forked from openlp/openlp
r1715
This commit is contained in:
commit
d1e9a1a32e
@ -20,3 +20,4 @@ _eric4project
|
||||
openlp/core/resources.py.old
|
||||
*.qm
|
||||
resources/windows/warnOpenLP.txt
|
||||
openlp.cfg
|
||||
|
18
openlp.pyw
18
openlp.pyw
@ -79,6 +79,8 @@ class OpenLP(QtGui.QApplication):
|
||||
class in order to provide the core of the application.
|
||||
"""
|
||||
|
||||
args = []
|
||||
|
||||
def exec_(self):
|
||||
"""
|
||||
Override exec method to allow the shared memory to be released on exit
|
||||
@ -92,7 +94,7 @@ class OpenLP(QtGui.QApplication):
|
||||
"""
|
||||
# On Windows, the args passed into the constructor are
|
||||
# ignored. Not very handy, so set the ones we want to use.
|
||||
self.args = args
|
||||
self.args.extend(args)
|
||||
# provide a listener for widgets to reqest a screen update.
|
||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||
QtCore.SIGNAL(u'openlp_process_events'), self.processEvents)
|
||||
@ -125,6 +127,8 @@ class OpenLP(QtGui.QApplication):
|
||||
# now kill the splashscreen
|
||||
self.splash.finish(self.mainWindow)
|
||||
log.debug(u'Splashscreen closed')
|
||||
# make sure Qt really display the splash screen
|
||||
self.processEvents()
|
||||
self.mainWindow.repaint()
|
||||
self.processEvents()
|
||||
if not has_run_wizard:
|
||||
@ -180,6 +184,18 @@ class OpenLP(QtGui.QApplication):
|
||||
"""
|
||||
self.restoreOverrideCursor()
|
||||
|
||||
def event(self, event):
|
||||
"""
|
||||
Enables direct file opening on OS X
|
||||
"""
|
||||
if event.type() == QtCore.QEvent.FileOpen:
|
||||
file_name = event.file()
|
||||
log.debug(u'Got open file event for %s!', file_name)
|
||||
self.args.insert(0, unicode(file_name))
|
||||
return True
|
||||
else:
|
||||
return QtGui.QApplication.event(self, event)
|
||||
|
||||
def main():
|
||||
"""
|
||||
The main function which parses command line options and then runs
|
||||
|
@ -205,7 +205,7 @@ def clean_tags(text):
|
||||
text = text.replace(u'<br>', u'\n')
|
||||
text = text.replace(u'{br}', u'\n')
|
||||
text = text.replace(u' ', u' ')
|
||||
for tag in DisplayTags.get_html_tags():
|
||||
for tag in FormattingTags.get_html_tags():
|
||||
text = text.replace(tag[u'start tag'], u'')
|
||||
text = text.replace(tag[u'end tag'], u'')
|
||||
return text
|
||||
@ -214,7 +214,7 @@ def expand_tags(text):
|
||||
"""
|
||||
Expand tags HTML for display
|
||||
"""
|
||||
for tag in DisplayTags.get_html_tags():
|
||||
for tag in FormattingTags.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
|
||||
@ -233,9 +233,9 @@ def check_directory_exists(dir):
|
||||
except IOError:
|
||||
pass
|
||||
|
||||
from listwidgetwithdnd import ListWidgetWithDnD
|
||||
from displaytags import DisplayTags
|
||||
from eventreceiver import Receiver
|
||||
from listwidgetwithdnd import ListWidgetWithDnD
|
||||
from formattingtags import FormattingTags
|
||||
from spelltextedit import SpellTextEdit
|
||||
from settingsmanager import SettingsManager
|
||||
from plugin import PluginStatus, StringContent, Plugin
|
||||
|
@ -25,12 +25,12 @@
|
||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
||||
"""
|
||||
Provide Html Tag management and Display Tag access class
|
||||
Provide HTML Tag management and Formatting Tag access class
|
||||
"""
|
||||
|
||||
from openlp.core.lib import translate
|
||||
|
||||
class DisplayTags(object):
|
||||
class FormattingTags(object):
|
||||
"""
|
||||
Static Class to HTML Tags to be access around the code the list is managed
|
||||
by the Options Tab.
|
||||
@ -42,89 +42,93 @@ class DisplayTags(object):
|
||||
"""
|
||||
Provide access to the html_expands list.
|
||||
"""
|
||||
return DisplayTags.html_expands
|
||||
return FormattingTags.html_expands
|
||||
|
||||
@staticmethod
|
||||
def reset_html_tags():
|
||||
"""
|
||||
Resets the html_expands list.
|
||||
"""
|
||||
DisplayTags.html_expands = []
|
||||
FormattingTags.html_expands = []
|
||||
base_tags = []
|
||||
# Append the base tags.
|
||||
# Hex Color tags from http://www.w3schools.com/html/html_colornames.asp
|
||||
base_tags.append({u'desc': translate('OpenLP.DisplayTags', 'Red'),
|
||||
base_tags.append({u'desc': translate('OpenLP.FormattingTags', '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': True})
|
||||
base_tags.append({u'desc': translate('OpenLP.DisplayTags', 'Black'),
|
||||
base_tags.append({u'desc': translate('OpenLP.FormattingTags', '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': True})
|
||||
base_tags.append({u'desc': translate('OpenLP.DisplayTags', 'Blue'),
|
||||
base_tags.append({u'desc': translate('OpenLP.FormattingTags', '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': True})
|
||||
base_tags.append({u'desc': translate('OpenLP.DisplayTags', 'Yellow'),
|
||||
base_tags.append({u'desc': translate('OpenLP.FormattingTags', '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': True})
|
||||
base_tags.append({u'desc': translate('OpenLP.DisplayTags', 'Green'),
|
||||
base_tags.append({u'desc': translate('OpenLP.FormattingTags', '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': True})
|
||||
base_tags.append({u'desc': translate('OpenLP.DisplayTags', 'Pink'),
|
||||
base_tags.append({u'desc': translate('OpenLP.FormattingTags', 'Pink'),
|
||||
u'start tag': u'{pk}',
|
||||
u'start html': u'<span style="-webkit-text-fill-color:#FFC0CB">',
|
||||
u'end tag': u'{/pk}', u'end html': u'</span>', u'protected': True})
|
||||
base_tags.append({u'desc': translate('OpenLP.DisplayTags', 'Orange'),
|
||||
base_tags.append({u'desc': translate('OpenLP.FormattingTags', 'Orange'),
|
||||
u'start tag': u'{o}',
|
||||
u'start html': u'<span style="-webkit-text-fill-color:#FFA500">',
|
||||
u'end tag': u'{/o}', u'end html': u'</span>', u'protected': True})
|
||||
base_tags.append({u'desc': translate('OpenLP.DisplayTags', 'Purple'),
|
||||
base_tags.append({u'desc': translate('OpenLP.FormattingTags', 'Purple'),
|
||||
u'start tag': u'{pp}',
|
||||
u'start html': u'<span style="-webkit-text-fill-color:#800080">',
|
||||
u'end tag': u'{/pp}', u'end html': u'</span>', u'protected': True})
|
||||
base_tags.append({u'desc': translate('OpenLP.DisplayTags', 'White'),
|
||||
base_tags.append({u'desc': translate('OpenLP.FormattingTags', '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': True})
|
||||
base_tags.append({
|
||||
u'desc': translate('OpenLP.DisplayTags', 'Superscript'),
|
||||
u'desc': translate('OpenLP.FormattingTags', 'Superscript'),
|
||||
u'start tag': u'{su}', u'start html': u'<sup>',
|
||||
u'end tag': u'{/su}', u'end html': u'</sup>', u'protected': True})
|
||||
base_tags.append({u'desc': translate('OpenLP.DisplayTags', 'Subscript'),
|
||||
base_tags.append({
|
||||
u'desc': translate('OpenLP.FormattingTags', 'Subscript'),
|
||||
u'start tag': u'{sb}', u'start html': u'<sub>',
|
||||
u'end tag': u'{/sb}', u'end html': u'</sub>', u'protected': True})
|
||||
base_tags.append({u'desc': translate('OpenLP.DisplayTags', 'Paragraph'),
|
||||
base_tags.append({
|
||||
u'desc': translate('OpenLP.FormattingTags', 'Paragraph'),
|
||||
u'start tag': u'{p}', u'start html': u'<p>', u'end tag': u'{/p}',
|
||||
u'end html': u'</p>', u'protected': True})
|
||||
base_tags.append({u'desc': translate('OpenLP.DisplayTags', 'Bold'),
|
||||
base_tags.append({u'desc': translate('OpenLP.FormattingTags', 'Bold'),
|
||||
u'start tag': u'{st}', u'start html': u'<strong>',
|
||||
u'end tag': u'{/st}', u'end html': u'</strong>',
|
||||
u'protected': True})
|
||||
base_tags.append({u'desc': translate('OpenLP.DisplayTags', 'Italics'),
|
||||
base_tags.append({
|
||||
u'desc': translate('OpenLP.FormattingTags', 'Italics'),
|
||||
u'start tag': u'{it}', u'start html': u'<em>', u'end tag': u'{/it}',
|
||||
u'end html': u'</em>', u'protected': True})
|
||||
base_tags.append({u'desc': translate('OpenLP.DisplayTags', 'Underline'),
|
||||
base_tags.append({
|
||||
u'desc': translate('OpenLP.FormattingTags', '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})
|
||||
base_tags.append({u'desc': translate('OpenLP.DisplayTags', 'Break'),
|
||||
base_tags.append({u'desc': translate('OpenLP.FormattingTags', 'Break'),
|
||||
u'start tag': u'{br}', u'start html': u'<br>', u'end tag': u'',
|
||||
u'end html': u'', u'protected': True})
|
||||
DisplayTags.add_html_tags(base_tags)
|
||||
FormattingTags.add_html_tags(base_tags)
|
||||
|
||||
@staticmethod
|
||||
def add_html_tags(tags):
|
||||
"""
|
||||
Add a list of tags to the list
|
||||
"""
|
||||
DisplayTags.html_expands.extend(tags)
|
||||
FormattingTags.html_expands.extend(tags)
|
||||
|
||||
@staticmethod
|
||||
def remove_html_tag(tag_id):
|
||||
"""
|
||||
Removes an individual html_expands tag.
|
||||
"""
|
||||
DisplayTags.html_expands.pop(tag_id)
|
||||
FormattingTags.html_expands.pop(tag_id)
|
@ -27,8 +27,12 @@
|
||||
"""
|
||||
Extend QListWidget to handle drag and drop functionality
|
||||
"""
|
||||
import os.path
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import Receiver
|
||||
|
||||
class ListWidgetWithDnD(QtGui.QListWidget):
|
||||
"""
|
||||
Provide a list widget to store objects and handle drag and drop events
|
||||
@ -41,6 +45,16 @@ class ListWidgetWithDnD(QtGui.QListWidget):
|
||||
self.mimeDataText = name
|
||||
assert(self.mimeDataText)
|
||||
|
||||
def activateDnD(self):
|
||||
"""
|
||||
Activate DnD of widget
|
||||
"""
|
||||
self.setAcceptDrops(True)
|
||||
self.setDragDropMode(QtGui.QAbstractItemView.DragDrop)
|
||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||
QtCore.SIGNAL(u'%s_dnd' % self.mimeDataText),
|
||||
self.parent().loadFile)
|
||||
|
||||
def mouseMoveEvent(self, event):
|
||||
"""
|
||||
Drag and drop event does not care what data is selected
|
||||
@ -58,3 +72,39 @@ class ListWidgetWithDnD(QtGui.QListWidget):
|
||||
drag.setMimeData(mimeData)
|
||||
mimeData.setText(self.mimeDataText)
|
||||
drag.start(QtCore.Qt.CopyAction)
|
||||
|
||||
def dragEnterEvent(self, event):
|
||||
if event.mimeData().hasUrls():
|
||||
event.accept()
|
||||
else:
|
||||
event.ignore()
|
||||
|
||||
def dragMoveEvent(self, event):
|
||||
if event.mimeData().hasUrls():
|
||||
event.setDropAction(QtCore.Qt.CopyAction)
|
||||
event.accept()
|
||||
else:
|
||||
event.ignore()
|
||||
|
||||
def dropEvent(self, event):
|
||||
"""
|
||||
Receive drop event check if it is a file and process it if it is.
|
||||
|
||||
``event``
|
||||
Handle of the event pint passed
|
||||
"""
|
||||
if event.mimeData().hasUrls():
|
||||
event.setDropAction(QtCore.Qt.CopyAction)
|
||||
event.accept()
|
||||
files = []
|
||||
for url in event.mimeData().urls():
|
||||
localFile = unicode(url.toLocalFile())
|
||||
if os.path.isfile(localFile):
|
||||
files.append(localFile)
|
||||
elif os.path.isdir(localFile):
|
||||
listing = os.listdir(localFile)
|
||||
for file in listing:
|
||||
files.append(os.path.join(localFile,file))
|
||||
Receiver.send_message(u'%s_dnd' % self.mimeDataText,files)
|
||||
else:
|
||||
event.ignore()
|
||||
|
@ -252,7 +252,6 @@ class MediaManagerItem(QtGui.QWidget):
|
||||
self.listView.setSelectionMode(
|
||||
QtGui.QAbstractItemView.ExtendedSelection)
|
||||
self.listView.setAlternatingRowColors(True)
|
||||
self.listView.setDragEnabled(True)
|
||||
self.listView.setObjectName(u'%sListView' % self.plugin.name)
|
||||
# Add to pageLayout
|
||||
self.pageLayout.addWidget(self.listView)
|
||||
@ -339,26 +338,65 @@ class MediaManagerItem(QtGui.QWidget):
|
||||
log.info(u'New files(s) %s', unicode(files))
|
||||
if files:
|
||||
Receiver.send_message(u'cursor_busy')
|
||||
names = []
|
||||
for count in range(0, self.listView.count()):
|
||||
names.append(self.listView.item(count).text())
|
||||
newFiles = []
|
||||
for file in files:
|
||||
filename = os.path.split(unicode(file))[1]
|
||||
if filename in names:
|
||||
self.validateAndLoad(files)
|
||||
Receiver.send_message(u'cursor_normal')
|
||||
|
||||
def loadFile(self, files):
|
||||
"""
|
||||
Turn file from Drag and Drop into an array so the Validate code
|
||||
can run it.
|
||||
|
||||
``files``
|
||||
The list of files to be loaded
|
||||
"""
|
||||
newFiles = []
|
||||
errorShown = False
|
||||
for file in files:
|
||||
type = file.split(u'.')[-1]
|
||||
if type.lower() not in self.onNewFileMasks:
|
||||
if not errorShown:
|
||||
critical_error_message_box(
|
||||
UiStrings().Duplicate,
|
||||
translate('OpenLP.MediaManagerItem',
|
||||
'Invalid File Type'),
|
||||
unicode(translate('OpenLP.MediaManagerItem',
|
||||
'Duplicate filename %s.\nThis filename is already in '
|
||||
'the list')) % filename)
|
||||
else:
|
||||
newFiles.append(file)
|
||||
'Invalid File %s.\nSuffix not supported'))
|
||||
% file)
|
||||
errorShown = True
|
||||
else:
|
||||
newFiles.append(file)
|
||||
if file:
|
||||
self.validateAndLoad(newFiles)
|
||||
|
||||
def validateAndLoad(self, files):
|
||||
"""
|
||||
Process a list for files either from the File Dialog or from Drag and
|
||||
Drop
|
||||
|
||||
``files``
|
||||
The files to be loaded
|
||||
"""
|
||||
names = []
|
||||
for count in range(0, self.listView.count()):
|
||||
names.append(self.listView.item(count).text())
|
||||
newFiles = []
|
||||
duplicatesFound = False
|
||||
for file in files:
|
||||
filename = os.path.split(unicode(file))[1]
|
||||
if filename in names:
|
||||
duplicatesFound = True
|
||||
else:
|
||||
newFiles.append(file)
|
||||
if newFiles:
|
||||
self.loadList(newFiles)
|
||||
lastDir = os.path.split(unicode(files[0]))[0]
|
||||
SettingsManager.set_last_dir(self.settingsSection, lastDir)
|
||||
SettingsManager.set_list(self.settingsSection,
|
||||
self.settingsSection, self.getFileList())
|
||||
Receiver.send_message(u'cursor_normal')
|
||||
if duplicatesFound:
|
||||
critical_error_message_box(
|
||||
UiStrings().Duplicate,
|
||||
unicode(translate('OpenLP.MediaManagerItem',
|
||||
'Duplicate files found on import and ignored.')))
|
||||
|
||||
def contextMenu(self, point):
|
||||
item = self.listView.itemAt(point)
|
||||
|
@ -46,8 +46,6 @@ VERSE = u'The Lord said to {r}Noah{/r}: \n' \
|
||||
'r{/pk}{o}e{/o}{pp}n{/pp} of the Lord\n'
|
||||
FOOTER = [u'Arky Arky (Unknown)', u'Public Domain', u'CCLI 123456']
|
||||
|
||||
HTML_END = u'</div></body></html>'
|
||||
|
||||
class Renderer(object):
|
||||
"""
|
||||
Class to pull all Renderer interactions into one place. The plugins will
|
||||
@ -85,7 +83,7 @@ class Renderer(object):
|
||||
Updates the render manager's information about the current screen.
|
||||
"""
|
||||
log.debug(u'Update Display')
|
||||
self._calculate_default(self.screens.current[u'size'])
|
||||
self._calculate_default()
|
||||
if self.display:
|
||||
self.display.close()
|
||||
self.display = MainDisplay(None, self.imageManager, False)
|
||||
@ -163,7 +161,7 @@ class Renderer(object):
|
||||
self.theme_data = override_theme
|
||||
else:
|
||||
self.theme_data = self.themeManager.getThemeData(theme)
|
||||
self._calculate_default(self.screens.current[u'size'])
|
||||
self._calculate_default()
|
||||
self._build_text_rectangle(self.theme_data)
|
||||
# if No file do not update cache
|
||||
if self.theme_data.background_filename:
|
||||
@ -185,7 +183,7 @@ class Renderer(object):
|
||||
# save value for use in format_slide
|
||||
self.force_page = force_page
|
||||
# set the default image size for previews
|
||||
self._calculate_default(self.screens.preview[u'size'])
|
||||
self._calculate_default()
|
||||
# build a service item to generate preview
|
||||
serviceItem = ServiceItem()
|
||||
serviceItem.theme = theme_data
|
||||
@ -203,7 +201,7 @@ class Renderer(object):
|
||||
raw_html = serviceItem.get_rendered_frame(0)
|
||||
preview = self.display.text(raw_html)
|
||||
# Reset the real screen size for subsequent render requests
|
||||
self._calculate_default(self.screens.current[u'size'])
|
||||
self._calculate_default()
|
||||
return preview
|
||||
self.force_page = False
|
||||
|
||||
@ -224,7 +222,7 @@ class Renderer(object):
|
||||
line_end = u' '
|
||||
# Bibles
|
||||
if item.is_capable(ItemCapabilities.AllowsWordSplit):
|
||||
pages = self._paginate_slide_words(text, line_end)
|
||||
pages = self._paginate_slide_words(text.split(u'\n'), line_end)
|
||||
else:
|
||||
# Clean up line endings.
|
||||
lines = self._lines_split(text)
|
||||
@ -245,19 +243,16 @@ class Renderer(object):
|
||||
new_pages.append(page)
|
||||
return new_pages
|
||||
|
||||
def _calculate_default(self, screen):
|
||||
def _calculate_default(self):
|
||||
"""
|
||||
Calculate the default dimentions of the screen.
|
||||
|
||||
``screen``
|
||||
The screen to calculate the default of.
|
||||
"""
|
||||
log.debug(u'_calculate default %s', screen)
|
||||
self.width = screen.width()
|
||||
self.height = screen.height()
|
||||
screen_size = self.screens.current[u'size']
|
||||
self.width = screen_size.width()
|
||||
self.height = screen_size.height()
|
||||
self.screen_ratio = float(self.height) / float(self.width)
|
||||
log.debug(u'calculate default %d, %d, %f',
|
||||
self.width, self.height, self.screen_ratio)
|
||||
log.debug(u'_calculate default %s, %f' % (screen_size,
|
||||
self.screen_ratio))
|
||||
# 90% is start of footer
|
||||
self.footer_start = int(self.height * 0.90)
|
||||
|
||||
@ -310,17 +305,28 @@ class Renderer(object):
|
||||
self.web.resize(self.page_width, self.page_height)
|
||||
self.web_frame = self.web.page().mainFrame()
|
||||
# Adjust width and height to account for shadow. outline done in css
|
||||
self.page_shell = u'<!DOCTYPE html><html><head><style>' \
|
||||
u'*{margin:0; padding:0; border:0;} '\
|
||||
u'#main {position:absolute; top:0px; %s %s}</style></head><body>' \
|
||||
u'<div id="main">' % \
|
||||
html = u"""<!DOCTYPE html><html><head><script>
|
||||
function show_text(newtext) {
|
||||
var main = document.getElementById('main');
|
||||
main.innerHTML = newtext;
|
||||
// We need to be sure that the page is loaded, that is why we
|
||||
// return the element's height (even though we do not use the
|
||||
// returned value).
|
||||
return main.offsetHeight;
|
||||
}
|
||||
</script><style>*{margin: 0; padding: 0; border: 0;}
|
||||
#main {position: absolute; top: 0px; %s %s}</style></head><body>
|
||||
<div id="main"></div></body></html>""" % \
|
||||
(build_lyrics_format_css(self.theme_data, self.page_width,
|
||||
self.page_height), build_lyrics_outline_css(self.theme_data))
|
||||
self.web.setHtml(html)
|
||||
|
||||
def _paginate_slide(self, lines, line_end):
|
||||
"""
|
||||
Figure out how much text can appear on a slide, using the current
|
||||
theme settings.
|
||||
**Note:** The smallest possible "unit" of text for a slide is one line.
|
||||
If the line is too long it will be cut off when displayed.
|
||||
|
||||
``lines``
|
||||
The text to be fitted on the slide split into lines.
|
||||
@ -334,10 +340,8 @@ class Renderer(object):
|
||||
previous_raw = u''
|
||||
separator = u'<br>'
|
||||
html_lines = map(expand_tags, lines)
|
||||
html = self.page_shell + separator.join(html_lines) + HTML_END
|
||||
self.web.setHtml(html)
|
||||
# Text too long so go to next page.
|
||||
if self.web_frame.contentsSize().height() > self.page_height:
|
||||
if self._text_fits_on_slide(separator.join(html_lines)):
|
||||
html_text, previous_raw = self._binary_chop(formatted,
|
||||
previous_html, previous_raw, html_lines, lines, separator, u'')
|
||||
else:
|
||||
@ -347,48 +351,41 @@ class Renderer(object):
|
||||
log.debug(u'_paginate_slide - End')
|
||||
return formatted
|
||||
|
||||
def _paginate_slide_words(self, text, line_end):
|
||||
def _paginate_slide_words(self, lines, line_end):
|
||||
"""
|
||||
Figure out how much text can appear on a slide, using the current
|
||||
theme settings. This version is to handle text which needs to be split
|
||||
into words to get it to fit.
|
||||
theme settings.
|
||||
**Note:** The smallest possible "unit" of text for a slide is one word.
|
||||
If one line is too long it will be processed word by word. This is
|
||||
sometimes need for **bible** verses.
|
||||
|
||||
``text``
|
||||
The words to be fitted on the slide split into lines.
|
||||
``lines``
|
||||
The text to be fitted on the slide split into lines.
|
||||
|
||||
``line_end``
|
||||
The text added after each line. Either ``u' '`` or ``u'<br>``.
|
||||
This is needed for bibles.
|
||||
This is needed for **bibles**.
|
||||
"""
|
||||
log.debug(u'_paginate_slide_words - Start')
|
||||
formatted = []
|
||||
previous_html = u''
|
||||
previous_raw = u''
|
||||
lines = text.split(u'\n')
|
||||
for line in lines:
|
||||
line = line.strip()
|
||||
html_line = expand_tags(line)
|
||||
html = self.page_shell + previous_html + html_line + HTML_END
|
||||
self.web.setHtml(html)
|
||||
# Text too long so go to next page.
|
||||
if self.web_frame.contentsSize().height() > self.page_height:
|
||||
if self._text_fits_on_slide(previous_html + html_line):
|
||||
# Check if there was a verse before the current one and append
|
||||
# it, when it fits on the page.
|
||||
if previous_html:
|
||||
html = self.page_shell + previous_html + HTML_END
|
||||
self.web.setHtml(html)
|
||||
if self.web_frame.contentsSize().height() <= \
|
||||
self.page_height:
|
||||
if not self._text_fits_on_slide(previous_html):
|
||||
formatted.append(previous_raw)
|
||||
previous_html = u''
|
||||
previous_raw = u''
|
||||
html = self.page_shell + html_line + HTML_END
|
||||
self.web.setHtml(html)
|
||||
# Now check if the current verse will fit, if it does
|
||||
# not we have to start to process the verse word by
|
||||
# word.
|
||||
if self.web_frame.contentsSize().height() <= \
|
||||
self.page_height:
|
||||
if not self._text_fits_on_slide(html_line):
|
||||
previous_html = html_line + line_end
|
||||
previous_raw = line + line_end
|
||||
continue
|
||||
@ -422,7 +419,7 @@ class Renderer(object):
|
||||
to the list of slides. (unicode string)
|
||||
|
||||
``previous_raw``
|
||||
The raw text (with display tags) which is know to fit on a slide,
|
||||
The raw text (with formatting tags) which is know to fit on a slide,
|
||||
but is not yet added to the list of slides. (unicode string)
|
||||
|
||||
``html_list``
|
||||
@ -431,7 +428,7 @@ class Renderer(object):
|
||||
|
||||
``raw_list``
|
||||
The elements which do not fit on a slide and needs to be processed
|
||||
using the binary chop. The elements can contain display tags.
|
||||
using the binary chop. The elements can contain formatting tags.
|
||||
|
||||
``separator``
|
||||
The separator for the elements. For lines this is ``u'<br>'`` and
|
||||
@ -445,10 +442,8 @@ class Renderer(object):
|
||||
highest_index = len(html_list) - 1
|
||||
index = int(highest_index / 2)
|
||||
while True:
|
||||
html = self.page_shell + previous_html + \
|
||||
separator.join(html_list[:index + 1]).strip() + HTML_END
|
||||
self.web.setHtml(html)
|
||||
if self.web_frame.contentsSize().height() > self.page_height:
|
||||
if self._text_fits_on_slide(
|
||||
previous_html + separator.join(html_list[:index + 1]).strip()):
|
||||
# We know that it does not fit, so change/calculate the
|
||||
# new index and highest_index accordingly.
|
||||
highest_index = index
|
||||
@ -470,10 +465,8 @@ class Renderer(object):
|
||||
else:
|
||||
continue
|
||||
# Check if the remaining elements fit on the slide.
|
||||
html = self.page_shell + \
|
||||
separator.join(html_list[index + 1:]).strip() + HTML_END
|
||||
self.web.setHtml(html)
|
||||
if self.web_frame.contentsSize().height() <= self.page_height:
|
||||
if not self._text_fits_on_slide(
|
||||
separator.join(html_list[index + 1:]).strip()):
|
||||
previous_html = separator.join(
|
||||
html_list[index + 1:]).strip() + line_end
|
||||
previous_raw = separator.join(
|
||||
@ -489,6 +482,18 @@ class Renderer(object):
|
||||
index = int(highest_index / 2)
|
||||
return previous_html, previous_raw
|
||||
|
||||
def _text_fits_on_slide(self, text):
|
||||
"""
|
||||
Checks if the given ``text`` fits on a slide. If it does ``True`` is
|
||||
returned, otherwise ``False``.
|
||||
|
||||
``text``
|
||||
The text to check. It can contain HTML tags.
|
||||
"""
|
||||
self.web_frame.evaluateJavaScript(u'show_text("%s")' %
|
||||
text.replace(u'\\', u'\\\\').replace(u'\"', u'\\\"'))
|
||||
return self.web_frame.contentsSize().height() > self.page_height
|
||||
|
||||
def _words_split(self, line):
|
||||
"""
|
||||
Split the slide up by word so can wrap better
|
||||
|
@ -39,7 +39,7 @@ except ImportError:
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import translate, DisplayTags
|
||||
from openlp.core.lib import translate, FormattingTags
|
||||
from openlp.core.lib.ui import checkable_action
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
@ -48,9 +48,10 @@ class SpellTextEdit(QtGui.QPlainTextEdit):
|
||||
"""
|
||||
Spell checking widget based on QPlanTextEdit.
|
||||
"""
|
||||
def __init__(self, *args):
|
||||
def __init__(self, parent=None, formattingTagsAllowed=True):
|
||||
global ENCHANT_AVAILABLE
|
||||
QtGui.QPlainTextEdit.__init__(self, *args)
|
||||
QtGui.QPlainTextEdit.__init__(self, parent)
|
||||
self.formattingTagsAllowed = formattingTagsAllowed
|
||||
# Default dictionary based on the current locale.
|
||||
if ENCHANT_AVAILABLE:
|
||||
try:
|
||||
@ -110,16 +111,17 @@ class SpellTextEdit(QtGui.QPlainTextEdit):
|
||||
spell_menu.addAction(action)
|
||||
# Only add the spelling suggests to the menu if there are
|
||||
# suggestions.
|
||||
if len(spell_menu.actions()):
|
||||
if spell_menu.actions():
|
||||
popupMenu.insertMenu(popupMenu.actions()[0], spell_menu)
|
||||
tagMenu = QtGui.QMenu(translate('OpenLP.SpellTextEdit',
|
||||
'Formatting Tags'))
|
||||
for html in DisplayTags.get_html_tags():
|
||||
action = SpellAction(html[u'desc'], tagMenu)
|
||||
action.correct.connect(self.htmlTag)
|
||||
tagMenu.addAction(action)
|
||||
popupMenu.insertSeparator(popupMenu.actions()[0])
|
||||
popupMenu.insertMenu(popupMenu.actions()[0], tagMenu)
|
||||
if self.formattingTagsAllowed:
|
||||
for html in FormattingTags.get_html_tags():
|
||||
action = SpellAction(html[u'desc'], tagMenu)
|
||||
action.correct.connect(self.htmlTag)
|
||||
tagMenu.addAction(action)
|
||||
popupMenu.insertSeparator(popupMenu.actions()[0])
|
||||
popupMenu.insertMenu(popupMenu.actions()[0], tagMenu)
|
||||
popupMenu.exec_(event.globalPos())
|
||||
|
||||
def setLanguage(self, action):
|
||||
@ -148,7 +150,7 @@ class SpellTextEdit(QtGui.QPlainTextEdit):
|
||||
"""
|
||||
Replaces the selected text with word.
|
||||
"""
|
||||
for html in DisplayTags.get_html_tags():
|
||||
for html in FormattingTags.get_html_tags():
|
||||
if tag == html[u'desc']:
|
||||
cursor = self.textCursor()
|
||||
if self.textCursor().hasSelection():
|
||||
|
@ -69,7 +69,7 @@ from advancedtab import AdvancedTab
|
||||
from aboutform import AboutForm
|
||||
from pluginform import PluginForm
|
||||
from settingsform import SettingsForm
|
||||
from displaytagform import DisplayTagForm
|
||||
from formattingtagform import FormattingTagForm
|
||||
from shortcutlistform import ShortcutListForm
|
||||
from mediadockmanager import MediaDockManager
|
||||
from servicemanager import ServiceManager
|
||||
|
@ -129,6 +129,7 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard):
|
||||
os.path.join(gettempdir(), u'openlp', screenshot)))
|
||||
item.setCheckState(QtCore.Qt.Unchecked)
|
||||
item.setFlags(item.flags() | QtCore.Qt.ItemIsUserCheckable)
|
||||
Receiver.send_message(u'cursor_normal')
|
||||
|
||||
def nextId(self):
|
||||
"""
|
||||
@ -156,10 +157,27 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard):
|
||||
item = self.themesListWidget.item(iter)
|
||||
if item.checkState() == QtCore.Qt.Checked:
|
||||
self.themeComboBox.addItem(item.text())
|
||||
# Check if this is a re-run of the wizard.
|
||||
self.has_run_wizard = QtCore.QSettings().value(
|
||||
u'general/has run wizard', QtCore.QVariant(False)).toBool()
|
||||
if self.has_run_wizard:
|
||||
# Add any existing themes to list.
|
||||
for theme in self.parent().themeManagerContents.getThemes():
|
||||
index = self.themeComboBox.findText(theme)
|
||||
if index == -1:
|
||||
self.themeComboBox.addItem(theme)
|
||||
default_theme = unicode(QtCore.QSettings().value(
|
||||
u'themes/global theme',
|
||||
QtCore.QVariant(u'')).toString())
|
||||
# Pre-select the current default theme.
|
||||
index = self.themeComboBox.findText(default_theme)
|
||||
self.themeComboBox.setCurrentIndex(index)
|
||||
elif pageId == FirstTimePage.Progress:
|
||||
Receiver.send_message(u'cursor_busy')
|
||||
self._preWizard()
|
||||
self._performWizard()
|
||||
self._postWizard()
|
||||
Receiver.send_message(u'cursor_normal')
|
||||
|
||||
def updateScreenListCombo(self):
|
||||
"""
|
||||
@ -248,11 +266,21 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard):
|
||||
"""
|
||||
if self.max_progress:
|
||||
self.progressBar.setValue(self.progressBar.maximum())
|
||||
self.progressLabel.setText(translate('OpenLP.FirstTimeWizard',
|
||||
'Download complete. Click the finish button to start OpenLP.'))
|
||||
if self.has_run_wizard:
|
||||
self.progressLabel.setText(translate('OpenLP.FirstTimeWizard',
|
||||
'Download complete.'
|
||||
' Click the finish button to return to OpenLP.'))
|
||||
else:
|
||||
self.progressLabel.setText(translate('OpenLP.FirstTimeWizard',
|
||||
'Download complete.'
|
||||
' Click the finish button to start OpenLP.'))
|
||||
else:
|
||||
self.progressLabel.setText(translate('OpenLP.FirstTimeWizard',
|
||||
'Click the finish button to start OpenLP.'))
|
||||
if self.has_run_wizard:
|
||||
self.progressLabel.setText(translate('OpenLP.FirstTimeWizard',
|
||||
'Click the finish button to return to OpenLP.'))
|
||||
else:
|
||||
self.progressLabel.setText(translate('OpenLP.FirstTimeWizard',
|
||||
'Click the finish button to start OpenLP.'))
|
||||
self.finishButton.setVisible(True)
|
||||
self.finishButton.setEnabled(True)
|
||||
self.cancelButton.setVisible(False)
|
||||
|
@ -30,15 +30,15 @@ from PyQt4 import QtCore, QtGui
|
||||
from openlp.core.lib import translate
|
||||
from openlp.core.lib.ui import UiStrings
|
||||
|
||||
class Ui_DisplayTagDialog(object):
|
||||
class Ui_FormattingTagDialog(object):
|
||||
|
||||
def setupUi(self, displayTagDialog):
|
||||
displayTagDialog.setObjectName(u'displayTagDialog')
|
||||
displayTagDialog.resize(725, 548)
|
||||
self.listdataGridLayout = QtGui.QGridLayout(displayTagDialog)
|
||||
def setupUi(self, formattingTagDialog):
|
||||
formattingTagDialog.setObjectName(u'formattingTagDialog')
|
||||
formattingTagDialog.resize(725, 548)
|
||||
self.listdataGridLayout = QtGui.QGridLayout(formattingTagDialog)
|
||||
self.listdataGridLayout.setMargin(8)
|
||||
self.listdataGridLayout.setObjectName(u'listdataGridLayout')
|
||||
self.tagTableWidget = QtGui.QTableWidget(displayTagDialog)
|
||||
self.tagTableWidget = QtGui.QTableWidget(formattingTagDialog)
|
||||
self.tagTableWidget.setHorizontalScrollBarPolicy(
|
||||
QtCore.Qt.ScrollBarAlwaysOff)
|
||||
self.tagTableWidget.setEditTriggers(
|
||||
@ -67,11 +67,11 @@ class Ui_DisplayTagDialog(object):
|
||||
spacerItem = QtGui.QSpacerItem(40, 20,
|
||||
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
|
||||
self.horizontalLayout.addItem(spacerItem)
|
||||
self.deletePushButton = QtGui.QPushButton(displayTagDialog)
|
||||
self.deletePushButton = QtGui.QPushButton(formattingTagDialog)
|
||||
self.deletePushButton.setObjectName(u'deletePushButton')
|
||||
self.horizontalLayout.addWidget(self.deletePushButton)
|
||||
self.listdataGridLayout.addLayout(self.horizontalLayout, 1, 0, 1, 1)
|
||||
self.editGroupBox = QtGui.QGroupBox(displayTagDialog)
|
||||
self.editGroupBox = QtGui.QGroupBox(formattingTagDialog)
|
||||
self.editGroupBox.setObjectName(u'editGroupBox')
|
||||
self.dataGridLayout = QtGui.QGridLayout(self.editGroupBox)
|
||||
self.dataGridLayout.setObjectName(u'dataGridLayout')
|
||||
@ -112,38 +112,38 @@ class Ui_DisplayTagDialog(object):
|
||||
self.savePushButton.setObjectName(u'savePushButton')
|
||||
self.dataGridLayout.addWidget(self.savePushButton, 4, 2, 1, 1)
|
||||
self.listdataGridLayout.addWidget(self.editGroupBox, 2, 0, 1, 1)
|
||||
self.buttonBox = QtGui.QDialogButtonBox(displayTagDialog)
|
||||
self.buttonBox.setObjectName('displayTagDialogButtonBox')
|
||||
self.buttonBox = QtGui.QDialogButtonBox(formattingTagDialog)
|
||||
self.buttonBox.setObjectName('formattingTagDialogButtonBox')
|
||||
self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Close)
|
||||
self.listdataGridLayout.addWidget(self.buttonBox, 3, 0, 1, 1)
|
||||
|
||||
self.retranslateUi(displayTagDialog)
|
||||
QtCore.QMetaObject.connectSlotsByName(displayTagDialog)
|
||||
self.retranslateUi(formattingTagDialog)
|
||||
QtCore.QMetaObject.connectSlotsByName(formattingTagDialog)
|
||||
|
||||
def retranslateUi(self, displayTagDialog):
|
||||
displayTagDialog.setWindowTitle(translate('OpenLP.displayTagDialog',
|
||||
'Configure Display Tags'))
|
||||
def retranslateUi(self, formattingTagDialog):
|
||||
formattingTagDialog.setWindowTitle(translate(
|
||||
'OpenLP.FormattingTagDialog', 'Configure Formatting Tags'))
|
||||
self.editGroupBox.setTitle(
|
||||
translate('OpenLP.DisplayTagDialog', 'Edit Selection'))
|
||||
translate('OpenLP.FormattingTagDialog', 'Edit Selection'))
|
||||
self.savePushButton.setText(
|
||||
translate('OpenLP.DisplayTagDialog', 'Save'))
|
||||
translate('OpenLP.FormattingTagDialog', 'Save'))
|
||||
self.descriptionLabel.setText(
|
||||
translate('OpenLP.DisplayTagDialog', 'Description'))
|
||||
self.tagLabel.setText(translate('OpenLP.DisplayTagDialog', 'Tag'))
|
||||
translate('OpenLP.FormattingTagDialog', 'Description'))
|
||||
self.tagLabel.setText(translate('OpenLP.FormattingTagDialog', 'Tag'))
|
||||
self.startTagLabel.setText(
|
||||
translate('OpenLP.DisplayTagDialog', 'Start tag'))
|
||||
translate('OpenLP.FormattingTagDialog', 'Start tag'))
|
||||
self.endTagLabel.setText(
|
||||
translate('OpenLP.DisplayTagDialog', 'End tag'))
|
||||
translate('OpenLP.FormattingTagDialog', 'End tag'))
|
||||
self.deletePushButton.setText(UiStrings().Delete)
|
||||
self.newPushButton.setText(UiStrings().New)
|
||||
self.tagTableWidget.horizontalHeaderItem(0).setText(
|
||||
translate('OpenLP.DisplayTagDialog', 'Description'))
|
||||
translate('OpenLP.FormattingTagDialog', 'Description'))
|
||||
self.tagTableWidget.horizontalHeaderItem(1).setText(
|
||||
translate('OpenLP.DisplayTagDialog', 'Tag Id'))
|
||||
translate('OpenLP.FormattingTagDialog', 'Tag Id'))
|
||||
self.tagTableWidget.horizontalHeaderItem(2).setText(
|
||||
translate('OpenLP.DisplayTagDialog', 'Start HTML'))
|
||||
translate('OpenLP.FormattingTagDialog', 'Start HTML'))
|
||||
self.tagTableWidget.horizontalHeaderItem(3).setText(
|
||||
translate('OpenLP.DisplayTagDialog', 'End HTML'))
|
||||
translate('OpenLP.FormattingTagDialog', 'End HTML'))
|
||||
self.tagTableWidget.setColumnWidth(0, 120)
|
||||
self.tagTableWidget.setColumnWidth(1, 80)
|
||||
self.tagTableWidget.setColumnWidth(2, 330)
|
@ -25,22 +25,22 @@
|
||||
# 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
|
||||
The :mod:`formattingtagform` 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 translate, DisplayTags
|
||||
from openlp.core.lib import translate, FormattingTags
|
||||
from openlp.core.lib.ui import critical_error_message_box
|
||||
from openlp.core.ui.displaytagdialog import Ui_DisplayTagDialog
|
||||
from openlp.core.ui.formattingtagdialog import Ui_FormattingTagDialog
|
||||
|
||||
class DisplayTagForm(QtGui.QDialog, Ui_DisplayTagDialog):
|
||||
class FormattingTagForm(QtGui.QDialog, Ui_FormattingTagDialog):
|
||||
"""
|
||||
The :class:`DisplayTagTab` manages the settings tab .
|
||||
The :class:`FormattingTagForm` manages the settings tab .
|
||||
"""
|
||||
def __init__(self, parent):
|
||||
"""
|
||||
@ -48,7 +48,7 @@ class DisplayTagForm(QtGui.QDialog, Ui_DisplayTagDialog):
|
||||
"""
|
||||
QtGui.QDialog.__init__(self, parent)
|
||||
self.setupUi(self)
|
||||
self._loadDisplayTags()
|
||||
self._loadFormattingTags()
|
||||
QtCore.QObject.connect(self.tagTableWidget,
|
||||
QtCore.SIGNAL(u'clicked(QModelIndex)'), self.onRowSelected)
|
||||
QtCore.QObject.connect(self.newPushButton,
|
||||
@ -65,19 +65,20 @@ class DisplayTagForm(QtGui.QDialog, Ui_DisplayTagDialog):
|
||||
Load Display and set field state.
|
||||
"""
|
||||
# Create initial copy from master
|
||||
self._loadDisplayTags()
|
||||
self._loadFormattingTags()
|
||||
self._resetTable()
|
||||
self.selected = -1
|
||||
return QtGui.QDialog.exec_(self)
|
||||
|
||||
def _loadDisplayTags(self):
|
||||
def _loadFormattingTags(self):
|
||||
"""
|
||||
Load the Tags from store so can be used in the system or used to
|
||||
update the display. If Cancel was selected this is needed to reset the
|
||||
dsiplay to the correct version.
|
||||
"""
|
||||
# Initial Load of the Tags
|
||||
DisplayTags.reset_html_tags()
|
||||
FormattingTags.reset_html_tags()
|
||||
# Formatting Tags were also known as display tags.
|
||||
user_expands = QtCore.QSettings().value(u'displayTags/html_tags',
|
||||
QtCore.QVariant(u'')).toString()
|
||||
# cPickle only accepts str not unicode strings
|
||||
@ -85,14 +86,14 @@ class DisplayTagForm(QtGui.QDialog, Ui_DisplayTagDialog):
|
||||
if user_expands_string:
|
||||
user_tags = cPickle.loads(user_expands_string)
|
||||
# If we have some user ones added them as well
|
||||
DisplayTags.add_html_tags(user_tags)
|
||||
FormattingTags.add_html_tags(user_tags)
|
||||
|
||||
def onRowSelected(self):
|
||||
"""
|
||||
Table Row selected so display items and set field state.
|
||||
"""
|
||||
row = self.tagTableWidget.currentRow()
|
||||
html = DisplayTags.get_html_tags()[row]
|
||||
html = FormattingTags.get_html_tags()[row]
|
||||
self.selected = row
|
||||
self.descriptionLineEdit.setText(html[u'desc'])
|
||||
self.tagLineEdit.setText(self._strip(html[u'start tag']))
|
||||
@ -117,23 +118,23 @@ class DisplayTagForm(QtGui.QDialog, Ui_DisplayTagDialog):
|
||||
"""
|
||||
Add a new tag to list only if it is not a duplicate.
|
||||
"""
|
||||
for html in DisplayTags.get_html_tags():
|
||||
for html in FormattingTags.get_html_tags():
|
||||
if self._strip(html[u'start tag']) == u'n':
|
||||
critical_error_message_box(
|
||||
translate('OpenLP.DisplayTagTab', 'Update Error'),
|
||||
translate('OpenLP.DisplayTagTab',
|
||||
translate('OpenLP.FormattingTagForm', 'Update Error'),
|
||||
translate('OpenLP.FormattingTagForm',
|
||||
'Tag "n" already defined.'))
|
||||
return
|
||||
# Add new tag to list
|
||||
tag = {
|
||||
u'desc': translate('OpenLP.DisplayTagTab', 'New Tag'),
|
||||
u'desc': translate('OpenLP.FormattingTagForm', 'New Tag'),
|
||||
u'start tag': u'{n}',
|
||||
u'start html': translate('OpenLP.DisplayTagTab', '<HTML here>'),
|
||||
u'start html': translate('OpenLP.FormattingTagForm', '<HTML here>'),
|
||||
u'end tag': u'{/n}',
|
||||
u'end html': translate('OpenLP.DisplayTagTab', '</and here>'),
|
||||
u'end html': translate('OpenLP.FormattingTagForm', '</and here>'),
|
||||
u'protected': False
|
||||
}
|
||||
DisplayTags.add_html_tags([tag])
|
||||
FormattingTags.add_html_tags([tag])
|
||||
self._resetTable()
|
||||
# Highlight new row
|
||||
self.tagTableWidget.selectRow(self.tagTableWidget.rowCount() - 1)
|
||||
@ -145,7 +146,7 @@ class DisplayTagForm(QtGui.QDialog, Ui_DisplayTagDialog):
|
||||
Delete selected custom tag.
|
||||
"""
|
||||
if self.selected != -1:
|
||||
DisplayTags.remove_html_tag(self.selected)
|
||||
FormattingTags.remove_html_tag(self.selected)
|
||||
self.selected = -1
|
||||
self._resetTable()
|
||||
self._saveTable()
|
||||
@ -154,7 +155,7 @@ class DisplayTagForm(QtGui.QDialog, Ui_DisplayTagDialog):
|
||||
"""
|
||||
Update Custom Tag details if not duplicate and save the data.
|
||||
"""
|
||||
html_expands = DisplayTags.get_html_tags()
|
||||
html_expands = FormattingTags.get_html_tags()
|
||||
if self.selected != -1:
|
||||
html = html_expands[self.selected]
|
||||
tag = unicode(self.tagLineEdit.text())
|
||||
@ -162,8 +163,8 @@ class DisplayTagForm(QtGui.QDialog, Ui_DisplayTagDialog):
|
||||
if self._strip(html1[u'start tag']) == tag and \
|
||||
linenumber != self.selected:
|
||||
critical_error_message_box(
|
||||
translate('OpenLP.DisplayTagTab', 'Update Error'),
|
||||
unicode(translate('OpenLP.DisplayTagTab',
|
||||
translate('OpenLP.FormattingTagForm', 'Update Error'),
|
||||
unicode(translate('OpenLP.FormattingTagForm',
|
||||
'Tag %s already defined.')) % tag)
|
||||
return
|
||||
html[u'desc'] = unicode(self.descriptionLineEdit.text())
|
||||
@ -177,18 +178,15 @@ class DisplayTagForm(QtGui.QDialog, Ui_DisplayTagDialog):
|
||||
|
||||
def _saveTable(self):
|
||||
"""
|
||||
Saves all display tags except protected ones.
|
||||
Saves all formatting tags except protected ones.
|
||||
"""
|
||||
tags = []
|
||||
for tag in DisplayTags.get_html_tags():
|
||||
for tag in FormattingTags.get_html_tags():
|
||||
if not tag[u'protected']:
|
||||
tags.append(tag)
|
||||
if tags:
|
||||
QtCore.QSettings().setValue(u'displayTags/html_tags',
|
||||
QtCore.QVariant(cPickle.dumps(tags)))
|
||||
else:
|
||||
QtCore.QSettings().setValue(u'displayTags/html_tags',
|
||||
QtCore.QVariant(u''))
|
||||
# Formatting Tags were also known as display tags.
|
||||
QtCore.QSettings().setValue(u'displayTags/html_tags',
|
||||
QtCore.QVariant(cPickle.dumps(tags) if tags else u''))
|
||||
|
||||
def _resetTable(self):
|
||||
"""
|
||||
@ -199,7 +197,7 @@ class DisplayTagForm(QtGui.QDialog, Ui_DisplayTagDialog):
|
||||
self.newPushButton.setEnabled(True)
|
||||
self.savePushButton.setEnabled(False)
|
||||
self.deletePushButton.setEnabled(False)
|
||||
for linenumber, html in enumerate(DisplayTags.get_html_tags()):
|
||||
for linenumber, html in enumerate(FormattingTags.get_html_tags()):
|
||||
self.tagTableWidget.setRowCount(
|
||||
self.tagTableWidget.rowCount() + 1)
|
||||
self.tagTableWidget.setItem(linenumber, 0,
|
@ -188,7 +188,7 @@ class MainDisplay(QtGui.QGraphicsView):
|
||||
while not self.webLoaded:
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
self.setGeometry(self.screen[u'size'])
|
||||
self.frame.evaluateJavaScript(u'show_text("%s")' % \
|
||||
self.frame.evaluateJavaScript(u'show_text("%s")' %
|
||||
slide.replace(u'\\', u'\\\\').replace(u'\"', u'\\\"'))
|
||||
return self.preview()
|
||||
|
||||
|
@ -28,20 +28,23 @@
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
import shutil
|
||||
from tempfile import gettempdir
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import Renderer, build_icon, OpenLPDockWidget, \
|
||||
PluginManager, Receiver, translate, ImageManager
|
||||
PluginManager, Receiver, translate, ImageManager, PluginStatus
|
||||
from openlp.core.lib.ui import UiStrings, base_action, checkable_action, \
|
||||
icon_action, shortcut_action
|
||||
from openlp.core.ui import AboutForm, SettingsForm, ServiceManager, \
|
||||
ThemeManager, SlideController, PluginForm, MediaDockManager, \
|
||||
ShortcutListForm, DisplayTagForm
|
||||
ShortcutListForm, FormattingTagForm
|
||||
from openlp.core.utils import AppLocation, add_actions, LanguageManager, \
|
||||
get_application_version, delete_file
|
||||
from openlp.core.utils.actions import ActionList, CategoryOrder
|
||||
from openlp.core.ui.firsttimeform import FirstTimeForm
|
||||
from openlp.core.ui import ScreenList
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
@ -107,6 +110,8 @@ class Ui_MainWindow(object):
|
||||
self.menuBar.setObjectName(u'menuBar')
|
||||
self.fileMenu = QtGui.QMenu(self.menuBar)
|
||||
self.fileMenu.setObjectName(u'fileMenu')
|
||||
self.recentFilesMenu = QtGui.QMenu(self.fileMenu)
|
||||
self.recentFilesMenu.setObjectName(u'recentFilesMenu')
|
||||
self.fileImportMenu = QtGui.QMenu(self.fileMenu)
|
||||
self.fileImportMenu.setObjectName(u'fileImportMenu')
|
||||
self.fileExportMenu = QtGui.QMenu(self.fileMenu)
|
||||
@ -244,6 +249,9 @@ class Ui_MainWindow(object):
|
||||
self.toolsOpenDataFolder = icon_action(mainWindow,
|
||||
u'toolsOpenDataFolder', u':/general/general_open.png',
|
||||
category=UiStrings().Tools)
|
||||
self.toolsFirstTimeWizard = icon_action(mainWindow,
|
||||
u'toolsFirstTimeWizard', u':/general/general_revert.png',
|
||||
category=UiStrings().Tools)
|
||||
self.updateThemeImages = base_action(mainWindow,
|
||||
u'updateThemeImages', category=UiStrings().Tools)
|
||||
action_list.add_category(UiStrings().Settings,
|
||||
@ -269,7 +277,8 @@ class Ui_MainWindow(object):
|
||||
u'settingsShortcutsItem',
|
||||
u':/system/system_configure_shortcuts.png',
|
||||
category=UiStrings().Settings)
|
||||
self.displayTagItem = icon_action(mainWindow,
|
||||
# Formatting Tags were also known as display tags.
|
||||
self.formattingTagItem = icon_action(mainWindow,
|
||||
u'displayTagItem', u':/system/tag_editor.png',
|
||||
category=UiStrings().Settings)
|
||||
self.settingsConfigureItem = icon_action(mainWindow,
|
||||
@ -296,10 +305,11 @@ class Ui_MainWindow(object):
|
||||
(self.importThemeItem, self.importLanguageItem))
|
||||
add_actions(self.fileExportMenu,
|
||||
(self.exportThemeItem, self.exportLanguageItem))
|
||||
self.fileMenuActions = (self.fileNewItem, self.fileOpenItem,
|
||||
self.fileSaveItem, self.fileSaveAsItem, None,
|
||||
self.printServiceOrderItem, None, self.fileImportMenu.menuAction(),
|
||||
self.fileExportMenu.menuAction(), self.fileExitItem)
|
||||
add_actions(self.fileMenu, (self.fileNewItem, self.fileOpenItem,
|
||||
self.fileSaveItem, self.fileSaveAsItem,
|
||||
self.recentFilesMenu.menuAction(), None,
|
||||
self.fileImportMenu.menuAction(), self.fileExportMenu.menuAction(),
|
||||
None, self.printServiceOrderItem, self.fileExitItem))
|
||||
add_actions(self.viewModeMenu, (self.modeDefaultItem,
|
||||
self.modeSetupItem, self.modeLiveItem))
|
||||
add_actions(self.viewMenu, (self.viewModeMenu.menuAction(),
|
||||
@ -315,14 +325,15 @@ class Ui_MainWindow(object):
|
||||
add_actions(self.settingsMenu, (self.settingsPluginListItem,
|
||||
self.settingsLanguageMenu.menuAction(), None,
|
||||
self.settingsConfigureItem, self.settingsShortcutsItem,
|
||||
self.displayTagItem))
|
||||
self.formattingTagItem))
|
||||
else:
|
||||
add_actions(self.settingsMenu, (self.settingsPluginListItem,
|
||||
self.settingsLanguageMenu.menuAction(), None,
|
||||
self.displayTagItem, self.settingsShortcutsItem,
|
||||
self.formattingTagItem, self.settingsShortcutsItem,
|
||||
self.settingsConfigureItem))
|
||||
add_actions(self.toolsMenu, (self.toolsAddToolItem, None))
|
||||
add_actions(self.toolsMenu, (self.toolsOpenDataFolder, None))
|
||||
add_actions(self.toolsMenu, (self.toolsFirstTimeWizard, None))
|
||||
add_actions(self.toolsMenu, [self.updateThemeImages])
|
||||
if os.name == u'nt':
|
||||
add_actions(self.helpMenu, (self.offlineHelpItem,
|
||||
@ -339,7 +350,7 @@ class Ui_MainWindow(object):
|
||||
self.mediaToolBox.setCurrentIndex(0)
|
||||
# Connect up some signals and slots
|
||||
QtCore.QObject.connect(self.fileMenu,
|
||||
QtCore.SIGNAL(u'aboutToShow()'), self.updateFileMenu)
|
||||
QtCore.SIGNAL(u'aboutToShow()'), self.updateRecentFilesMenu)
|
||||
QtCore.QMetaObject.connectSlotsByName(mainWindow)
|
||||
# Hide the entry, as it does not have any functionality yet.
|
||||
self.toolsAddToolItem.setVisible(False)
|
||||
@ -356,6 +367,8 @@ class Ui_MainWindow(object):
|
||||
self.fileMenu.setTitle(translate('OpenLP.MainWindow', '&File'))
|
||||
self.fileImportMenu.setTitle(translate('OpenLP.MainWindow', '&Import'))
|
||||
self.fileExportMenu.setTitle(translate('OpenLP.MainWindow', '&Export'))
|
||||
self.recentFilesMenu.setTitle(
|
||||
translate('OpenLP.MainWindow', '&Recent Files'))
|
||||
self.viewMenu.setTitle(translate('OpenLP.MainWindow', '&View'))
|
||||
self.viewModeMenu.setTitle(translate('OpenLP.MainWindow', 'M&ode'))
|
||||
self.toolsMenu.setTitle(translate('OpenLP.MainWindow', '&Tools'))
|
||||
@ -403,8 +416,8 @@ class Ui_MainWindow(object):
|
||||
translate('OpenLP.MainWindow', '&Language'))
|
||||
self.settingsShortcutsItem.setText(
|
||||
translate('OpenLP.MainWindow', 'Configure &Shortcuts...'))
|
||||
self.displayTagItem.setText(
|
||||
translate('OpenLP.MainWindow', '&Configure Display Tags'))
|
||||
self.formattingTagItem.setText(
|
||||
translate('OpenLP.MainWindow', '&Configure Formatting Tags...'))
|
||||
self.settingsConfigureItem.setText(
|
||||
translate('OpenLP.MainWindow', '&Configure OpenLP...'))
|
||||
self.viewMediaManagerItem.setText(
|
||||
@ -471,6 +484,10 @@ class Ui_MainWindow(object):
|
||||
translate('OpenLP.MainWindow', 'Open &Data Folder...'))
|
||||
self.toolsOpenDataFolder.setStatusTip(translate('OpenLP.MainWindow',
|
||||
'Open the folder where songs, bibles and other data resides.'))
|
||||
self.toolsFirstTimeWizard.setText(
|
||||
translate('OpenLP.MainWindow', 'Re-run First Time Wizard'))
|
||||
self.toolsFirstTimeWizard.setStatusTip(translate('OpenLP.MainWindow',
|
||||
'Re-run the First Time Wizard, importing songs, Bibles and themes.'))
|
||||
self.updateThemeImages.setText(
|
||||
translate('OpenLP.MainWindow', 'Update Theme Images'))
|
||||
self.updateThemeImages.setStatusTip(
|
||||
@ -511,7 +528,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
||||
self.serviceNotSaved = False
|
||||
self.aboutForm = AboutForm(self)
|
||||
self.settingsForm = SettingsForm(self, self)
|
||||
self.displayTagForm = DisplayTagForm(self)
|
||||
self.formattingTagForm = FormattingTagForm(self)
|
||||
self.shortcutForm = ShortcutListForm(self)
|
||||
self.recentFiles = QtCore.QStringList()
|
||||
# Set up the path with plugins
|
||||
@ -523,8 +540,8 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
||||
self.setupUi(self)
|
||||
# Load settings after setupUi so default UI sizes are overwritten
|
||||
self.loadSettings()
|
||||
# Once settings are loaded update FileMenu with recentFiles
|
||||
self.updateFileMenu()
|
||||
# Once settings are loaded update the menu with the recent files.
|
||||
self.updateRecentFilesMenu()
|
||||
self.pluginForm = PluginForm(self)
|
||||
# Set up signals and slots
|
||||
QtCore.QObject.connect(self.importThemeItem,
|
||||
@ -546,10 +563,12 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
||||
QtCore.SIGNAL(u'triggered()'), self.onHelpWebSiteClicked)
|
||||
QtCore.QObject.connect(self.toolsOpenDataFolder,
|
||||
QtCore.SIGNAL(u'triggered()'), self.onToolsOpenDataFolderClicked)
|
||||
QtCore.QObject.connect(self.toolsFirstTimeWizard,
|
||||
QtCore.SIGNAL(u'triggered()'), self.onFirstTimeWizardClicked)
|
||||
QtCore.QObject.connect(self.updateThemeImages,
|
||||
QtCore.SIGNAL(u'triggered()'), self.onUpdateThemeImages)
|
||||
QtCore.QObject.connect(self.displayTagItem,
|
||||
QtCore.SIGNAL(u'triggered()'), self.onDisplayTagItemClicked)
|
||||
QtCore.QObject.connect(self.formattingTagItem,
|
||||
QtCore.SIGNAL(u'triggered()'), self.onFormattingTagItemClicked)
|
||||
QtCore.QObject.connect(self.settingsConfigureItem,
|
||||
QtCore.SIGNAL(u'triggered()'), self.onSettingsConfigureItemClicked)
|
||||
QtCore.QObject.connect(self.settingsShortcutsItem,
|
||||
@ -708,11 +727,46 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
||||
plugin.firstTime()
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
temp_dir = os.path.join(unicode(gettempdir()), u'openlp')
|
||||
if not os.path.exists(temp_dir):
|
||||
shutil.rmtree(temp_dir, True)
|
||||
|
||||
def onFirstTimeWizardClicked(self):
|
||||
"""
|
||||
Re-run the first time wizard. Prompts the user for run confirmation
|
||||
If wizard is run, songs, bibles and themes are imported. The default
|
||||
theme is changed (if necessary). The plugins in pluginmanager are
|
||||
set active/in-active to match the selection in the wizard.
|
||||
"""
|
||||
answer = QtGui.QMessageBox.warning(self,
|
||||
translate('OpenLP.MainWindow', 'Re-run First Time Wizard?'),
|
||||
translate('OpenLP.MainWindow',
|
||||
'Are you sure you want to re-run the First Time Wizard?\n\n'
|
||||
'Re-running this wizard may make changes to your current '
|
||||
'OpenLP configuration and possibly add songs to your '
|
||||
'existing songs list and change your default theme.'),
|
||||
QtGui.QMessageBox.StandardButtons(
|
||||
QtGui.QMessageBox.Yes |
|
||||
QtGui.QMessageBox.No),
|
||||
QtGui.QMessageBox.No)
|
||||
if answer == QtGui.QMessageBox.No:
|
||||
return
|
||||
for filename in os.listdir(temp_dir):
|
||||
delete_file(os.path.join(temp_dir, filename))
|
||||
os.removedirs(temp_dir)
|
||||
Receiver.send_message(u'cursor_busy')
|
||||
screens = ScreenList.get_instance()
|
||||
if FirstTimeForm(screens, self).exec_() == QtGui.QDialog.Accepted:
|
||||
self.firstTime()
|
||||
for plugin in self.pluginManager.plugins:
|
||||
self.activePlugin = plugin
|
||||
oldStatus = self.activePlugin.status
|
||||
self.activePlugin.setStatus()
|
||||
if oldStatus != self.activePlugin.status:
|
||||
if self.activePlugin.status == PluginStatus.Active:
|
||||
self.activePlugin.toggleStatus(PluginStatus.Active)
|
||||
self.activePlugin.appStartup()
|
||||
else:
|
||||
self.activePlugin.toggleStatus(PluginStatus.Inactive)
|
||||
self.themeManagerContents.configUpdated()
|
||||
self.themeManagerContents.loadThemes(True)
|
||||
Receiver.send_message(u'theme_update_global',
|
||||
self.themeManagerContents.global_theme)
|
||||
|
||||
def blankCheck(self):
|
||||
"""
|
||||
@ -788,11 +842,11 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
||||
"""
|
||||
self.themeManagerContents.updatePreviewImages()
|
||||
|
||||
def onDisplayTagItemClicked(self):
|
||||
def onFormattingTagItemClicked(self):
|
||||
"""
|
||||
Show the Settings dialog
|
||||
"""
|
||||
self.displayTagForm.exec_()
|
||||
self.formattingTagForm.exec_()
|
||||
|
||||
def onSettingsConfigureItemClicked(self):
|
||||
"""
|
||||
@ -1085,30 +1139,36 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
||||
QtCore.QVariant(self.controlSplitter.saveState()))
|
||||
settings.endGroup()
|
||||
|
||||
def updateFileMenu(self):
|
||||
def updateRecentFilesMenu(self):
|
||||
"""
|
||||
Updates the file menu with the latest list of service files accessed.
|
||||
Updates the recent file menu with the latest list of service files
|
||||
accessed.
|
||||
"""
|
||||
recentFileCount = QtCore.QSettings().value(
|
||||
u'advanced/recent file count', QtCore.QVariant(4)).toInt()[0]
|
||||
self.fileMenu.clear()
|
||||
add_actions(self.fileMenu, self.fileMenuActions[:-1])
|
||||
existingRecentFiles = [recentFile for recentFile in self.recentFiles
|
||||
if QtCore.QFile.exists(recentFile)]
|
||||
recentFilesToDisplay = existingRecentFiles[0:recentFileCount]
|
||||
if recentFilesToDisplay:
|
||||
self.fileMenu.addSeparator()
|
||||
for fileId, filename in enumerate(recentFilesToDisplay):
|
||||
log.debug('Recent file name: %s', filename)
|
||||
action = base_action(self, u'')
|
||||
action.setText(u'&%d %s' %
|
||||
(fileId + 1, QtCore.QFileInfo(filename).fileName()))
|
||||
action.setData(QtCore.QVariant(filename))
|
||||
self.connect(action, QtCore.SIGNAL(u'triggered()'),
|
||||
self.serviceManagerContents.onRecentServiceClicked)
|
||||
self.fileMenu.addAction(action)
|
||||
self.fileMenu.addSeparator()
|
||||
self.fileMenu.addAction(self.fileMenuActions[-1])
|
||||
self.recentFilesMenu.clear()
|
||||
for fileId, filename in enumerate(recentFilesToDisplay):
|
||||
log.debug('Recent file name: %s', filename)
|
||||
action = base_action(self, u'')
|
||||
action.setText(u'&%d %s' %
|
||||
(fileId + 1, QtCore.QFileInfo(filename).fileName()))
|
||||
action.setData(QtCore.QVariant(filename))
|
||||
self.connect(action, QtCore.SIGNAL(u'triggered()'),
|
||||
self.serviceManagerContents.onRecentServiceClicked)
|
||||
self.recentFilesMenu.addAction(action)
|
||||
clearRecentFilesAction = base_action(self, u'')
|
||||
clearRecentFilesAction.setText(
|
||||
translate('OpenLP.MainWindow', 'Clear List',
|
||||
'Clear List of recent files'))
|
||||
clearRecentFilesAction.setStatusTip(
|
||||
translate('OpenLP.MainWindow', 'Clear the list of recent files.'))
|
||||
add_actions(self.recentFilesMenu, (None, clearRecentFilesAction))
|
||||
self.connect(clearRecentFilesAction, QtCore.SIGNAL(u'triggered()'),
|
||||
self.recentFiles.clear)
|
||||
clearRecentFilesAction.setEnabled(not self.recentFiles.isEmpty())
|
||||
|
||||
def addRecentFile(self, filename):
|
||||
"""
|
||||
|
@ -108,7 +108,7 @@ class Ui_PrintServiceDialog(object):
|
||||
self.footerLabel = QtGui.QLabel(self.optionsWidget)
|
||||
self.footerLabel.setObjectName(u'footerLabel')
|
||||
self.optionsLayout.addWidget(self.footerLabel)
|
||||
self.footerTextEdit = SpellTextEdit(self.optionsWidget)
|
||||
self.footerTextEdit = SpellTextEdit(self.optionsWidget, False)
|
||||
self.footerTextEdit.setObjectName(u'footerTextEdit')
|
||||
self.optionsLayout.addWidget(self.footerTextEdit)
|
||||
self.optionsGroupBox = QtGui.QGroupBox()
|
||||
|
@ -24,6 +24,7 @@
|
||||
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
||||
import cgi
|
||||
import datetime
|
||||
import os
|
||||
|
||||
@ -183,7 +184,7 @@ class PrintServiceForm(QtGui.QDialog, Ui_PrintServiceDialog):
|
||||
self._addElement(u'style', custom_css, html_data.head,
|
||||
attribute=(u'type', u'text/css'))
|
||||
self._addElement(u'body', parent=html_data)
|
||||
self._addElement(u'h1', unicode(self.titleLineEdit.text()),
|
||||
self._addElement(u'h1', cgi.escape(unicode(self.titleLineEdit.text())),
|
||||
html_data.body, classId=u'serviceTitle')
|
||||
for index, item in enumerate(self.serviceManager.serviceItems):
|
||||
self._addPreviewItem(html_data.body, item[u'service_item'], index)
|
||||
@ -193,8 +194,9 @@ class PrintServiceForm(QtGui.QDialog, Ui_PrintServiceDialog):
|
||||
classId=u'customNotes')
|
||||
self._addElement(u'span', translate('OpenLP.ServiceManager',
|
||||
'Custom Service Notes: '), div, classId=u'customNotesTitle')
|
||||
self._addElement(u'span', self.footerTextEdit.toPlainText(), div,
|
||||
classId=u'customNotesText')
|
||||
self._addElement(u'span',
|
||||
cgi.escape(self.footerTextEdit.toPlainText()),
|
||||
div, classId=u'customNotesText')
|
||||
self.document.setHtml(html.tostring(html_data))
|
||||
self.previewWidget.updatePreview()
|
||||
|
||||
@ -204,8 +206,8 @@ class PrintServiceForm(QtGui.QDialog, Ui_PrintServiceDialog):
|
||||
item_title = self._addElement(u'h2', parent=div, classId=u'itemTitle')
|
||||
self._addElement(u'img', parent=item_title,
|
||||
attribute=(u'src', item.icon))
|
||||
self._addElement(u'span', u' ' + item.get_display_title(),
|
||||
item_title)
|
||||
self._addElement(u'span',
|
||||
u' ' + cgi.escape(item.get_display_title()), item_title)
|
||||
if self.slideTextCheckBox.isChecked():
|
||||
# Add the text of the service item.
|
||||
if item.is_text():
|
||||
@ -230,8 +232,9 @@ class PrintServiceForm(QtGui.QDialog, Ui_PrintServiceDialog):
|
||||
foot_text = item.foot_text
|
||||
foot_text = foot_text.partition(u'<br>')[2]
|
||||
if foot_text:
|
||||
foot = self._addElement(u'div', foot_text, parent=div,
|
||||
classId=u'itemFooter')
|
||||
foot_text = cgi.escape(foot_text.replace(u'<br>', u'\n'))
|
||||
self._addElement(u'div', foot_text.replace(u'\n', u'<br>'),
|
||||
parent=div, classId=u'itemFooter')
|
||||
# Add service items' notes.
|
||||
if self.notesCheckBox.isChecked():
|
||||
if item.notes:
|
||||
@ -239,8 +242,8 @@ class PrintServiceForm(QtGui.QDialog, Ui_PrintServiceDialog):
|
||||
self._addElement(u'span',
|
||||
translate('OpenLP.ServiceManager', 'Notes: '), p,
|
||||
classId=u'itemNotesTitle')
|
||||
notes = self._addElement(u'span',
|
||||
item.notes.replace(u'\n', u'<br>'), p,
|
||||
self._addElement(u'span',
|
||||
cgi.escape(unicode(item.notes)).replace(u'\n', u'<br>'), p,
|
||||
classId=u'itemNotesText')
|
||||
# Add play length of media files.
|
||||
if item.is_media() and self.metaDataCheckBox.isChecked():
|
||||
|
@ -79,7 +79,7 @@ class ServiceItemEditForm(QtGui.QDialog, Ui_ServiceItemEditDialog):
|
||||
if not item:
|
||||
return
|
||||
row = self.listWidget.row(item)
|
||||
self.itemList.remove(self.itemList[row])
|
||||
self.itemList.pop(row)
|
||||
self.loadData()
|
||||
if row == self.listWidget.count():
|
||||
self.listWidget.setCurrentRow(row - 1)
|
||||
@ -109,7 +109,7 @@ class ServiceItemEditForm(QtGui.QDialog, Ui_ServiceItemEditDialog):
|
||||
return
|
||||
row = self.listWidget.row(item)
|
||||
temp = self.itemList[row]
|
||||
self.itemList.remove(self.itemList[row])
|
||||
self.itemList.pop(row)
|
||||
if direction == u'up':
|
||||
row -= 1
|
||||
else:
|
||||
|
@ -24,6 +24,7 @@
|
||||
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||
###############################################################################
|
||||
import cgi
|
||||
import cPickle
|
||||
import logging
|
||||
import os
|
||||
@ -408,20 +409,33 @@ class ServiceManager(QtGui.QWidget):
|
||||
return False
|
||||
self.newFile()
|
||||
|
||||
def onLoadServiceClicked(self):
|
||||
def onLoadServiceClicked(self, loadFile=None):
|
||||
"""
|
||||
Loads the service file and saves the existing one it there is one
|
||||
unchanged
|
||||
|
||||
``loadFile``
|
||||
The service file to the loaded. Will be None is from menu so
|
||||
selection will be required.
|
||||
"""
|
||||
if self.isModified():
|
||||
result = self.saveModifiedService()
|
||||
if result == QtGui.QMessageBox.Cancel:
|
||||
return False
|
||||
elif result == QtGui.QMessageBox.Save:
|
||||
self.saveFile()
|
||||
fileName = unicode(QtGui.QFileDialog.getOpenFileName(self.mainwindow,
|
||||
translate('OpenLP.ServiceManager', 'Open File'),
|
||||
SettingsManager.get_last_dir(
|
||||
self.mainwindow.serviceSettingsSection),
|
||||
translate('OpenLP.ServiceManager', 'OpenLP Service Files (*.osz)')))
|
||||
if not fileName:
|
||||
return False
|
||||
if not loadFile:
|
||||
fileName = unicode(QtGui.QFileDialog.getOpenFileName(
|
||||
self.mainwindow,
|
||||
translate('OpenLP.ServiceManager', 'Open File'),
|
||||
SettingsManager.get_last_dir(
|
||||
self.mainwindow.serviceSettingsSection),
|
||||
translate('OpenLP.ServiceManager',
|
||||
'OpenLP Service Files (*.osz)')))
|
||||
if not fileName:
|
||||
return False
|
||||
else:
|
||||
fileName = loadFile
|
||||
SettingsManager.set_last_dir(self.mainwindow.serviceSettingsSection,
|
||||
split_filename(fileName)[0])
|
||||
self.loadFile(fileName)
|
||||
@ -474,6 +488,7 @@ class ServiceManager(QtGui.QWidget):
|
||||
item[u'service_item'].get_service_repr()})
|
||||
if not item[u'service_item'].uses_file():
|
||||
continue
|
||||
skipMissing = False
|
||||
for frame in item[u'service_item'].get_frames():
|
||||
if item[u'service_item'].is_image():
|
||||
path_from = frame[u'path']
|
||||
@ -482,25 +497,29 @@ class ServiceManager(QtGui.QWidget):
|
||||
# Only write a file once
|
||||
if path_from in write_list:
|
||||
continue
|
||||
file_size = os.path.getsize(path_from)
|
||||
size_limit = 52428800 # 50MiB
|
||||
#if file_size > size_limit:
|
||||
# # File exeeds size_limit bytes, ask user
|
||||
# message = unicode(translate('OpenLP.ServiceManager',
|
||||
# 'Do you want to include \n%.1f MB file "%s"\n'
|
||||
# 'into the service file?\nThis may take some time.\n\n'
|
||||
# 'Please note that you need to\ntake care of that file'
|
||||
# ' yourself,\nif you leave it out.')) % \
|
||||
# (file_size/1048576, os.path.split(path_from)[1])
|
||||
# ans = QtGui.QMessageBox.question(self.mainwindow,
|
||||
# translate('OpenLP.ServiceManager', 'Including Large '
|
||||
# 'File'), message, QtGui.QMessageBox.StandardButtons(
|
||||
# QtGui.QMessageBox.Ok|QtGui.QMessageBox.Cancel),
|
||||
# QtGui.QMessageBox.Ok)
|
||||
# if ans == QtGui.QMessageBox.Cancel:
|
||||
# continue
|
||||
write_list.append(path_from)
|
||||
total_size += file_size
|
||||
if not os.path.exists(path_from):
|
||||
if not skipMissing:
|
||||
Receiver.send_message(u'cursor_normal')
|
||||
title = unicode(translate('OpenLP.ServiceManager',
|
||||
'Service File Missing'))
|
||||
message = unicode(translate('OpenLP.ServiceManager',
|
||||
'File missing from service\n\n %s \n\n'
|
||||
'Continue saving?' % path_from ))
|
||||
answer = QtGui.QMessageBox.critical(self, title,
|
||||
message,
|
||||
QtGui.QMessageBox.StandardButtons(
|
||||
QtGui.QMessageBox.Yes | QtGui.QMessageBox.No |
|
||||
QtGui.QMessageBox.YesToAll))
|
||||
if answer == QtGui.QMessageBox.No:
|
||||
self.mainwindow.finishedProgressBar()
|
||||
return False
|
||||
if answer == QtGui.QMessageBox.YesToAll:
|
||||
skipMissing = True
|
||||
Receiver.send_message(u'cursor_busy')
|
||||
else:
|
||||
file_size = os.path.getsize(path_from)
|
||||
write_list.append(path_from)
|
||||
total_size += file_size
|
||||
log.debug(u'ServiceManager.saveFile - ZIP contents size is %i bytes' %
|
||||
total_size)
|
||||
service_content = cPickle.dumps(service)
|
||||
@ -701,6 +720,9 @@ class ServiceManager(QtGui.QWidget):
|
||||
self.setModified()
|
||||
|
||||
def onStartTimeForm(self):
|
||||
"""
|
||||
Opens a dialog to type in service item notes.
|
||||
"""
|
||||
item = self.findServiceItem()[0]
|
||||
self.startTimeForm.item = self.serviceItems[item]
|
||||
if self.startTimeForm.exec_():
|
||||
@ -939,7 +961,7 @@ class ServiceManager(QtGui.QWidget):
|
||||
if serviceitem.notes:
|
||||
tips.append(u'<strong>%s: </strong> %s' %
|
||||
(unicode(translate('OpenLP.ServiceManager', 'Notes')),
|
||||
unicode(serviceitem.notes)))
|
||||
cgi.escape(unicode(serviceitem.notes))))
|
||||
if item[u'service_item'] \
|
||||
.is_capable(ItemCapabilities.AllowsVariableStartTime):
|
||||
tips.append(item[u'service_item'].get_media_time())
|
||||
@ -1239,7 +1261,14 @@ class ServiceManager(QtGui.QWidget):
|
||||
Handle of the event pint passed
|
||||
"""
|
||||
link = event.mimeData()
|
||||
if link.hasText():
|
||||
if event.mimeData().hasUrls():
|
||||
event.setDropAction(QtCore.Qt.CopyAction)
|
||||
event.accept()
|
||||
for url in event.mimeData().urls():
|
||||
filename = unicode(url.toLocalFile())
|
||||
if filename.endswith(u'.osz'):
|
||||
self.onLoadServiceClicked(filename)
|
||||
elif event.mimeData().hasText():
|
||||
plugin = unicode(event.mimeData().text())
|
||||
item = self.serviceManagerList.itemAt(event.pos())
|
||||
# ServiceManager started the drag and drop
|
||||
|
@ -27,7 +27,7 @@
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import translate
|
||||
from openlp.core.lib import translate, SpellTextEdit
|
||||
from openlp.core.lib.ui import create_accept_reject_button_box
|
||||
|
||||
class ServiceNoteForm(QtGui.QDialog):
|
||||
@ -52,7 +52,7 @@ class ServiceNoteForm(QtGui.QDialog):
|
||||
self.dialogLayout.setContentsMargins(8, 8, 8, 8)
|
||||
self.dialogLayout.setSpacing(8)
|
||||
self.dialogLayout.setObjectName(u'verticalLayout')
|
||||
self.textEdit = QtGui.QTextEdit(self)
|
||||
self.textEdit = SpellTextEdit(self, False)
|
||||
self.textEdit.setObjectName(u'textEdit')
|
||||
self.dialogLayout.addWidget(self.textEdit)
|
||||
self.dialogLayout.addWidget(create_accept_reject_button_box(self))
|
||||
|
@ -123,7 +123,7 @@ class Ui_ShortcutListDialog(object):
|
||||
|
||||
def retranslateUi(self, shortcutListDialog):
|
||||
shortcutListDialog.setWindowTitle(
|
||||
translate('OpenLP.ShortcutListDialog', 'Customize Shortcuts'))
|
||||
translate('OpenLP.ShortcutListDialog', 'Configure Shortcuts'))
|
||||
self.descriptionLabel.setText(translate('OpenLP.ShortcutListDialog',
|
||||
'Select an action and click one of the buttons below to start '
|
||||
'capturing a new primary or alternate shortcut, respectively.'))
|
||||
|
@ -386,6 +386,17 @@ def split_filename(path):
|
||||
else:
|
||||
return os.path.split(path)
|
||||
|
||||
def clean_filename(filename):
|
||||
"""
|
||||
Removes invalid characters from the given ``filename``.
|
||||
|
||||
``filename``
|
||||
The "dirty" file name to clean.
|
||||
"""
|
||||
if not isinstance(filename, unicode):
|
||||
filename = unicode(filename, u'utf-8')
|
||||
return re.sub(r'[/\\?*|<>\[\]":<>+%]+', u'_', filename).strip(u'_')
|
||||
|
||||
def delete_file(file_path_name):
|
||||
"""
|
||||
Deletes a file from the system.
|
||||
@ -492,4 +503,4 @@ from actions import ActionList
|
||||
__all__ = [u'AppLocation', u'get_application_version', u'check_latest_version',
|
||||
u'add_actions', u'get_filesystem_encoding', u'LanguageManager',
|
||||
u'ActionList', u'get_web_page', u'file_is_unicode', u'get_uno_command',
|
||||
u'get_uno_instance', u'delete_file']
|
||||
u'get_uno_instance', u'delete_file', u'clean_filename']
|
||||
|
@ -44,85 +44,85 @@ class AlertsTab(SettingsTab):
|
||||
self.fontGroupBox.setObjectName(u'fontGroupBox')
|
||||
self.fontLayout = QtGui.QFormLayout(self.fontGroupBox)
|
||||
self.fontLayout.setObjectName(u'fontLayout')
|
||||
self.FontLabel = QtGui.QLabel(self.fontGroupBox)
|
||||
self.FontLabel.setObjectName(u'FontLabel')
|
||||
self.FontComboBox = QtGui.QFontComboBox(self.fontGroupBox)
|
||||
self.FontComboBox.setObjectName(u'FontComboBox')
|
||||
self.fontLayout.addRow(self.FontLabel, self.FontComboBox)
|
||||
self.FontColorLabel = QtGui.QLabel(self.fontGroupBox)
|
||||
self.FontColorLabel.setObjectName(u'FontColorLabel')
|
||||
self.ColorLayout = QtGui.QHBoxLayout()
|
||||
self.ColorLayout.setObjectName(u'ColorLayout')
|
||||
self.FontColorButton = QtGui.QPushButton(self.fontGroupBox)
|
||||
self.FontColorButton.setObjectName(u'FontColorButton')
|
||||
self.ColorLayout.addWidget(self.FontColorButton)
|
||||
self.ColorLayout.addSpacing(20)
|
||||
self.BackgroundColorLabel = QtGui.QLabel(self.fontGroupBox)
|
||||
self.BackgroundColorLabel.setObjectName(u'BackgroundColorLabel')
|
||||
self.ColorLayout.addWidget(self.BackgroundColorLabel)
|
||||
self.BackgroundColorButton = QtGui.QPushButton(self.fontGroupBox)
|
||||
self.BackgroundColorButton.setObjectName(u'BackgroundColorButton')
|
||||
self.ColorLayout.addWidget(self.BackgroundColorButton)
|
||||
self.fontLayout.addRow(self.FontColorLabel, self.ColorLayout)
|
||||
self.FontSizeLabel = QtGui.QLabel(self.fontGroupBox)
|
||||
self.FontSizeLabel.setObjectName(u'FontSizeLabel')
|
||||
self.FontSizeSpinBox = QtGui.QSpinBox(self.fontGroupBox)
|
||||
self.FontSizeSpinBox.setObjectName(u'FontSizeSpinBox')
|
||||
self.fontLayout.addRow(self.FontSizeLabel, self.FontSizeSpinBox)
|
||||
self.TimeoutLabel = QtGui.QLabel(self.fontGroupBox)
|
||||
self.TimeoutLabel.setObjectName(u'TimeoutLabel')
|
||||
self.TimeoutSpinBox = QtGui.QSpinBox(self.fontGroupBox)
|
||||
self.TimeoutSpinBox.setMaximum(180)
|
||||
self.TimeoutSpinBox.setObjectName(u'TimeoutSpinBox')
|
||||
self.fontLayout.addRow(self.TimeoutLabel, self.TimeoutSpinBox)
|
||||
self.fontLabel = QtGui.QLabel(self.fontGroupBox)
|
||||
self.fontLabel.setObjectName(u'fontLabel')
|
||||
self.fontComboBox = QtGui.QFontComboBox(self.fontGroupBox)
|
||||
self.fontComboBox.setObjectName(u'fontComboBox')
|
||||
self.fontLayout.addRow(self.fontLabel, self.fontComboBox)
|
||||
self.fontColorLabel = QtGui.QLabel(self.fontGroupBox)
|
||||
self.fontColorLabel.setObjectName(u'fontColorLabel')
|
||||
self.colorLayout = QtGui.QHBoxLayout()
|
||||
self.colorLayout.setObjectName(u'colorLayout')
|
||||
self.fontColorButton = QtGui.QPushButton(self.fontGroupBox)
|
||||
self.fontColorButton.setObjectName(u'fontColorButton')
|
||||
self.colorLayout.addWidget(self.fontColorButton)
|
||||
self.colorLayout.addSpacing(20)
|
||||
self.backgroundColorLabel = QtGui.QLabel(self.fontGroupBox)
|
||||
self.backgroundColorLabel.setObjectName(u'backgroundColorLabel')
|
||||
self.colorLayout.addWidget(self.backgroundColorLabel)
|
||||
self.backgroundColorButton = QtGui.QPushButton(self.fontGroupBox)
|
||||
self.backgroundColorButton.setObjectName(u'backgroundColorButton')
|
||||
self.colorLayout.addWidget(self.backgroundColorButton)
|
||||
self.fontLayout.addRow(self.fontColorLabel, self.colorLayout)
|
||||
self.fontSizeLabel = QtGui.QLabel(self.fontGroupBox)
|
||||
self.fontSizeLabel.setObjectName(u'fontSizeLabel')
|
||||
self.fontSizeSpinBox = QtGui.QSpinBox(self.fontGroupBox)
|
||||
self.fontSizeSpinBox.setObjectName(u'fontSizeSpinBox')
|
||||
self.fontLayout.addRow(self.fontSizeLabel, self.fontSizeSpinBox)
|
||||
self.timeoutLabel = QtGui.QLabel(self.fontGroupBox)
|
||||
self.timeoutLabel.setObjectName(u'timeoutLabel')
|
||||
self.timeoutSpinBox = QtGui.QSpinBox(self.fontGroupBox)
|
||||
self.timeoutSpinBox.setMaximum(180)
|
||||
self.timeoutSpinBox.setObjectName(u'timeoutSpinBox')
|
||||
self.fontLayout.addRow(self.timeoutLabel, self.timeoutSpinBox)
|
||||
create_valign_combo(self, self.fontGroupBox, self.fontLayout)
|
||||
self.leftLayout.addWidget(self.fontGroupBox)
|
||||
self.leftLayout.addStretch()
|
||||
self.PreviewGroupBox = QtGui.QGroupBox(self.rightColumn)
|
||||
self.PreviewGroupBox.setObjectName(u'PreviewGroupBox')
|
||||
self.PreviewLayout = QtGui.QVBoxLayout(self.PreviewGroupBox)
|
||||
self.PreviewLayout.setObjectName(u'PreviewLayout')
|
||||
self.FontPreview = QtGui.QLineEdit(self.PreviewGroupBox)
|
||||
self.FontPreview.setObjectName(u'FontPreview')
|
||||
self.PreviewLayout.addWidget(self.FontPreview)
|
||||
self.rightLayout.addWidget(self.PreviewGroupBox)
|
||||
self.previewGroupBox = QtGui.QGroupBox(self.rightColumn)
|
||||
self.previewGroupBox.setObjectName(u'previewGroupBox')
|
||||
self.previewLayout = QtGui.QVBoxLayout(self.previewGroupBox)
|
||||
self.previewLayout.setObjectName(u'previewLayout')
|
||||
self.fontPreview = QtGui.QLineEdit(self.previewGroupBox)
|
||||
self.fontPreview.setObjectName(u'fontPreview')
|
||||
self.previewLayout.addWidget(self.fontPreview)
|
||||
self.rightLayout.addWidget(self.previewGroupBox)
|
||||
self.rightLayout.addStretch()
|
||||
# Signals and slots
|
||||
QtCore.QObject.connect(self.BackgroundColorButton,
|
||||
QtCore.QObject.connect(self.backgroundColorButton,
|
||||
QtCore.SIGNAL(u'pressed()'), self.onBackgroundColorButtonClicked)
|
||||
QtCore.QObject.connect(self.FontColorButton,
|
||||
QtCore.QObject.connect(self.fontColorButton,
|
||||
QtCore.SIGNAL(u'pressed()'), self.onFontColorButtonClicked)
|
||||
QtCore.QObject.connect(self.FontComboBox,
|
||||
QtCore.QObject.connect(self.fontComboBox,
|
||||
QtCore.SIGNAL(u'activated(int)'), self.onFontComboBoxClicked)
|
||||
QtCore.QObject.connect(self.TimeoutSpinBox,
|
||||
QtCore.QObject.connect(self.timeoutSpinBox,
|
||||
QtCore.SIGNAL(u'valueChanged(int)'), self.onTimeoutSpinBoxChanged)
|
||||
QtCore.QObject.connect(self.FontSizeSpinBox,
|
||||
QtCore.QObject.connect(self.fontSizeSpinBox,
|
||||
QtCore.SIGNAL(u'valueChanged(int)'), self.onFontSizeSpinBoxChanged)
|
||||
|
||||
def retranslateUi(self):
|
||||
self.fontGroupBox.setTitle(
|
||||
translate('AlertsPlugin.AlertsTab', 'Font'))
|
||||
self.FontLabel.setText(
|
||||
self.fontLabel.setText(
|
||||
translate('AlertsPlugin.AlertsTab', 'Font name:'))
|
||||
self.FontColorLabel.setText(
|
||||
self.fontColorLabel.setText(
|
||||
translate('AlertsPlugin.AlertsTab', 'Font color:'))
|
||||
self.BackgroundColorLabel.setText(
|
||||
self.backgroundColorLabel.setText(
|
||||
translate('AlertsPlugin.AlertsTab', 'Background color:'))
|
||||
self.FontSizeLabel.setText(
|
||||
self.fontSizeLabel.setText(
|
||||
translate('AlertsPlugin.AlertsTab', 'Font size:'))
|
||||
self.FontSizeSpinBox.setSuffix(UiStrings().FontSizePtUnit)
|
||||
self.TimeoutLabel.setText(
|
||||
self.fontSizeSpinBox.setSuffix(UiStrings().FontSizePtUnit)
|
||||
self.timeoutLabel.setText(
|
||||
translate('AlertsPlugin.AlertsTab', 'Alert timeout:'))
|
||||
self.TimeoutSpinBox.setSuffix(UiStrings().Seconds)
|
||||
self.PreviewGroupBox.setTitle(UiStrings().Preview)
|
||||
self.FontPreview.setText(UiStrings().OLPV2)
|
||||
self.timeoutSpinBox.setSuffix(UiStrings().Seconds)
|
||||
self.previewGroupBox.setTitle(UiStrings().Preview)
|
||||
self.fontPreview.setText(UiStrings().OLPV2)
|
||||
|
||||
def onBackgroundColorButtonClicked(self):
|
||||
new_color = QtGui.QColorDialog.getColor(
|
||||
QtGui.QColor(self.bg_color), self)
|
||||
if new_color.isValid():
|
||||
self.bg_color = new_color.name()
|
||||
self.BackgroundColorButton.setStyleSheet(
|
||||
self.backgroundColorButton.setStyleSheet(
|
||||
u'background-color: %s' % self.bg_color)
|
||||
self.updateDisplay()
|
||||
|
||||
@ -134,15 +134,15 @@ class AlertsTab(SettingsTab):
|
||||
QtGui.QColor(self.font_color), self)
|
||||
if new_color.isValid():
|
||||
self.font_color = new_color.name()
|
||||
self.FontColorButton.setStyleSheet(
|
||||
self.fontColorButton.setStyleSheet(
|
||||
u'background-color: %s' % self.font_color)
|
||||
self.updateDisplay()
|
||||
|
||||
def onTimeoutSpinBoxChanged(self):
|
||||
self.timeout = self.TimeoutSpinBox.value()
|
||||
self.timeout = self.timeoutSpinBox.value()
|
||||
|
||||
def onFontSizeSpinBoxChanged(self):
|
||||
self.font_size = self.FontSizeSpinBox.value()
|
||||
self.font_size = self.fontSizeSpinBox.value()
|
||||
self.updateDisplay()
|
||||
|
||||
def load(self):
|
||||
@ -160,16 +160,16 @@ class AlertsTab(SettingsTab):
|
||||
self.location = settings.value(
|
||||
u'location', QtCore.QVariant(1)).toInt()[0]
|
||||
settings.endGroup()
|
||||
self.FontSizeSpinBox.setValue(self.font_size)
|
||||
self.TimeoutSpinBox.setValue(self.timeout)
|
||||
self.FontColorButton.setStyleSheet(
|
||||
self.fontSizeSpinBox.setValue(self.font_size)
|
||||
self.timeoutSpinBox.setValue(self.timeout)
|
||||
self.fontColorButton.setStyleSheet(
|
||||
u'background-color: %s' % self.font_color)
|
||||
self.BackgroundColorButton.setStyleSheet(
|
||||
self.backgroundColorButton.setStyleSheet(
|
||||
u'background-color: %s' % self.bg_color)
|
||||
self.verticalComboBox.setCurrentIndex(self.location)
|
||||
font = QtGui.QFont()
|
||||
font.setFamily(self.font_face)
|
||||
self.FontComboBox.setCurrentFont(font)
|
||||
self.fontComboBox.setCurrentFont(font)
|
||||
self.updateDisplay()
|
||||
|
||||
def save(self):
|
||||
@ -178,7 +178,7 @@ class AlertsTab(SettingsTab):
|
||||
settings.setValue(u'background color', QtCore.QVariant(self.bg_color))
|
||||
settings.setValue(u'font color', QtCore.QVariant(self.font_color))
|
||||
settings.setValue(u'font size', QtCore.QVariant(self.font_size))
|
||||
self.font_face = self.FontComboBox.currentFont().family()
|
||||
self.font_face = self.fontComboBox.currentFont().family()
|
||||
settings.setValue(u'font face', QtCore.QVariant(self.font_face))
|
||||
settings.setValue(u'timeout', QtCore.QVariant(self.timeout))
|
||||
self.location = self.verticalComboBox.currentIndex()
|
||||
@ -187,10 +187,10 @@ class AlertsTab(SettingsTab):
|
||||
|
||||
def updateDisplay(self):
|
||||
font = QtGui.QFont()
|
||||
font.setFamily(self.FontComboBox.currentFont().family())
|
||||
font.setFamily(self.fontComboBox.currentFont().family())
|
||||
font.setBold(True)
|
||||
font.setPointSize(self.font_size)
|
||||
self.FontPreview.setFont(font)
|
||||
self.FontPreview.setStyleSheet(u'background-color: %s; color: %s' %
|
||||
self.fontPreview.setFont(font)
|
||||
self.fontPreview.setStyleSheet(u'background-color: %s; color: %s' %
|
||||
(self.bg_color, self.font_color))
|
||||
|
||||
|
@ -29,17 +29,17 @@ The bible import functions for OpenLP
|
||||
import logging
|
||||
import os
|
||||
import shutil
|
||||
from tempfile import gettempdir
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
from openlp.core.lib import Receiver, SettingsManager, translate, \
|
||||
check_directory_exists
|
||||
from openlp.core.lib.db import delete_database
|
||||
from openlp.core.lib.ui import UiStrings, critical_error_message_box
|
||||
from openlp.core.ui.wizard import OpenLPWizard, WizardStrings
|
||||
from openlp.core.utils import AppLocation, delete_file
|
||||
from openlp.plugins.bibles.lib.db import BibleDB, BibleMeta, OldBibleDB, \
|
||||
BiblesResourcesDB, clean_filename
|
||||
BiblesResourcesDB
|
||||
from openlp.plugins.bibles.lib.http import BSExtract, BGExtract, CWExtract
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
@ -70,6 +70,7 @@ class BibleUpgradeForm(OpenLPWizard):
|
||||
self.suffix = u'.sqlite'
|
||||
self.settingsSection = u'bibles'
|
||||
self.path = AppLocation.get_section_data_path(self.settingsSection)
|
||||
self.temp_dir = os.path.join(gettempdir(), u'openlp')
|
||||
self.files = self.manager.old_bible_databases
|
||||
self.success = {}
|
||||
self.newbibles = {}
|
||||
@ -91,20 +92,6 @@ class BibleUpgradeForm(OpenLPWizard):
|
||||
log.debug(u'Stopping import')
|
||||
self.stop_import_flag = True
|
||||
|
||||
def onCheckBoxIndexChanged(self, index):
|
||||
"""
|
||||
Show/Hide warnings if CheckBox state has changed
|
||||
"""
|
||||
for number, filename in enumerate(self.files):
|
||||
if not self.checkBox[number].checkState() == QtCore.Qt.Checked:
|
||||
self.verticalWidget[number].hide()
|
||||
self.formWidget[number].hide()
|
||||
else:
|
||||
version_name = unicode(self.versionNameEdit[number].text())
|
||||
if self.manager.exists(version_name):
|
||||
self.verticalWidget[number].show()
|
||||
self.formWidget[number].show()
|
||||
|
||||
def reject(self):
|
||||
"""
|
||||
Stop the wizard on cancel button, close button or ESC key.
|
||||
@ -113,8 +100,6 @@ class BibleUpgradeForm(OpenLPWizard):
|
||||
self.stop_import_flag = True
|
||||
if not self.currentPage() == self.progressPage:
|
||||
self.done(QtGui.QDialog.Rejected)
|
||||
else:
|
||||
self.postWizard()
|
||||
|
||||
def onCurrentIdChanged(self, pageId):
|
||||
"""
|
||||
@ -124,7 +109,7 @@ class BibleUpgradeForm(OpenLPWizard):
|
||||
self.preWizard()
|
||||
self.performWizard()
|
||||
self.postWizard()
|
||||
elif self.page(pageId) == self.selectPage and self.maxBibles == 0:
|
||||
elif self.page(pageId) == self.selectPage and not self.files:
|
||||
self.next()
|
||||
|
||||
def onBackupBrowseButtonClicked(self):
|
||||
@ -243,78 +228,13 @@ class BibleUpgradeForm(OpenLPWizard):
|
||||
Add the content to the scrollArea.
|
||||
"""
|
||||
self.checkBox = {}
|
||||
self.versionNameEdit = {}
|
||||
self.versionNameLabel = {}
|
||||
self.versionInfoLabel = {}
|
||||
self.versionInfoPixmap = {}
|
||||
self.verticalWidget = {}
|
||||
self.horizontalLayout = {}
|
||||
self.formWidget = {}
|
||||
self.formLayoutAttention = {}
|
||||
for number, filename in enumerate(self.files):
|
||||
bible = OldBibleDB(self.mediaItem, path=self.path, file=filename[0])
|
||||
self.checkBox[number] = QtGui.QCheckBox(self.scrollAreaContents)
|
||||
checkBoxName = u'checkBox[%d]' % number
|
||||
self.checkBox[number].setObjectName(checkBoxName)
|
||||
self.checkBox[number].setObjectName(u'checkBox[%d]' % number)
|
||||
self.checkBox[number].setText(bible.get_name())
|
||||
self.checkBox[number].setCheckState(QtCore.Qt.Checked)
|
||||
self.formLayout.addWidget(self.checkBox[number])
|
||||
self.verticalWidget[number] = QtGui.QWidget(self.scrollAreaContents)
|
||||
verticalWidgetName = u'verticalWidget[%d]' % number
|
||||
self.verticalWidget[number].setObjectName(verticalWidgetName)
|
||||
self.horizontalLayout[number] = QtGui.QHBoxLayout(
|
||||
self.verticalWidget[number])
|
||||
self.horizontalLayout[number].setContentsMargins(25, 0, 0, 0)
|
||||
horizontalLayoutName = u'horizontalLayout[%d]' % number
|
||||
self.horizontalLayout[number].setObjectName(horizontalLayoutName)
|
||||
self.versionInfoPixmap[number] = QtGui.QLabel(
|
||||
self.verticalWidget[number])
|
||||
versionInfoPixmapName = u'versionInfoPixmap[%d]' % number
|
||||
self.versionInfoPixmap[number].setObjectName(versionInfoPixmapName)
|
||||
self.versionInfoPixmap[number].setPixmap(QtGui.QPixmap(
|
||||
u':/bibles/bibles_upgrade_alert.png'))
|
||||
self.versionInfoPixmap[number].setAlignment(QtCore.Qt.AlignRight)
|
||||
self.horizontalLayout[number].addWidget(
|
||||
self.versionInfoPixmap[number])
|
||||
self.versionInfoLabel[number] = QtGui.QLabel(
|
||||
self.verticalWidget[number])
|
||||
versionInfoLabelName = u'versionInfoLabel[%d]' % number
|
||||
self.versionInfoLabel[number].setObjectName(versionInfoLabelName)
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding,
|
||||
QtGui.QSizePolicy.Preferred)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(
|
||||
self.versionInfoLabel[number].sizePolicy().hasHeightForWidth())
|
||||
self.versionInfoLabel[number].setSizePolicy(sizePolicy)
|
||||
self.horizontalLayout[number].addWidget(
|
||||
self.versionInfoLabel[number])
|
||||
self.formLayout.addWidget(self.verticalWidget[number])
|
||||
self.formWidget[number] = QtGui.QWidget(self.scrollAreaContents)
|
||||
formWidgetName = u'formWidget[%d]' % number
|
||||
self.formWidget[number].setObjectName(formWidgetName)
|
||||
self.formLayoutAttention[number] = QtGui.QFormLayout(
|
||||
self.formWidget[number])
|
||||
self.formLayoutAttention[number].setContentsMargins(25, 0, 0, 5)
|
||||
formLayoutAttentionName = u'formLayoutAttention[%d]' % number
|
||||
self.formLayoutAttention[number].setObjectName(
|
||||
formLayoutAttentionName)
|
||||
self.versionNameLabel[number] = QtGui.QLabel(
|
||||
self.formWidget[number])
|
||||
self.versionNameLabel[number].setObjectName(u'VersionNameLabel')
|
||||
self.formLayoutAttention[number].setWidget(0,
|
||||
QtGui.QFormLayout.LabelRole, self.versionNameLabel[number])
|
||||
self.versionNameEdit[number] = QtGui.QLineEdit(
|
||||
self.formWidget[number])
|
||||
self.versionNameEdit[number].setObjectName(u'VersionNameEdit')
|
||||
self.formLayoutAttention[number].setWidget(0,
|
||||
QtGui.QFormLayout.FieldRole, self.versionNameEdit[number])
|
||||
self.versionNameEdit[number].setText(bible.get_name())
|
||||
self.formLayout.addWidget(self.formWidget[number])
|
||||
# Set up the Signal for the checkbox.
|
||||
QtCore.QObject.connect(self.checkBox[number],
|
||||
QtCore.SIGNAL(u'stateChanged(int)'),
|
||||
self.onCheckBoxIndexChanged)
|
||||
self.spacerItem = QtGui.QSpacerItem(20, 5, QtGui.QSizePolicy.Minimum,
|
||||
QtGui.QSizePolicy.Expanding)
|
||||
self.formLayout.addItem(self.spacerItem)
|
||||
@ -327,23 +247,6 @@ class BibleUpgradeForm(OpenLPWizard):
|
||||
for number, filename in enumerate(self.files):
|
||||
self.formLayout.removeWidget(self.checkBox[number])
|
||||
self.checkBox[number].setParent(None)
|
||||
self.horizontalLayout[number].removeWidget(
|
||||
self.versionInfoPixmap[number])
|
||||
self.versionInfoPixmap[number].setParent(None)
|
||||
self.horizontalLayout[number].removeWidget(
|
||||
self.versionInfoLabel[number])
|
||||
self.versionInfoLabel[number].setParent(None)
|
||||
self.formLayout.removeWidget(self.verticalWidget[number])
|
||||
self.verticalWidget[number].setParent(None)
|
||||
self.formLayoutAttention[number].removeWidget(
|
||||
self.versionNameLabel[number])
|
||||
self.versionNameLabel[number].setParent(None)
|
||||
self.formLayoutAttention[number].removeWidget(
|
||||
self.versionNameEdit[number])
|
||||
self.formLayoutAttention[number].deleteLater()
|
||||
self.versionNameEdit[number].setParent(None)
|
||||
self.formLayout.removeWidget(self.formWidget[number])
|
||||
self.formWidget[number].setParent(None)
|
||||
self.formLayout.removeItem(self.spacerItem)
|
||||
|
||||
def retranslateUi(self):
|
||||
@ -385,12 +288,6 @@ class BibleUpgradeForm(OpenLPWizard):
|
||||
self.selectPage.setSubTitle(
|
||||
translate('BiblesPlugin.UpgradeWizardForm',
|
||||
'Please select the Bibles to upgrade'))
|
||||
for number, bible in enumerate(self.files):
|
||||
self.versionNameLabel[number].setText(
|
||||
translate('BiblesPlugin.UpgradeWizardForm', 'Version name:'))
|
||||
self.versionInfoLabel[number].setText(
|
||||
translate('BiblesPlugin.UpgradeWizardForm', 'This '
|
||||
'Bible still exists. Please change the name or uncheck it.'))
|
||||
self.progressPage.setTitle(translate('BiblesPlugin.UpgradeWizardForm',
|
||||
'Upgrading'))
|
||||
self.progressPage.setSubTitle(
|
||||
@ -425,58 +322,16 @@ class BibleUpgradeForm(OpenLPWizard):
|
||||
return False
|
||||
return True
|
||||
elif self.currentPage() == self.selectPage:
|
||||
check_directory_exists(self.temp_dir)
|
||||
for number, filename in enumerate(self.files):
|
||||
if not self.checkBox[number].checkState() == QtCore.Qt.Checked:
|
||||
continue
|
||||
version_name = unicode(self.versionNameEdit[number].text())
|
||||
if not version_name:
|
||||
critical_error_message_box(UiStrings().EmptyField,
|
||||
translate('BiblesPlugin.UpgradeWizardForm',
|
||||
'You need to specify a version name for your Bible.'))
|
||||
self.versionNameEdit[number].setFocus()
|
||||
return False
|
||||
elif self.manager.exists(version_name):
|
||||
critical_error_message_box(
|
||||
translate('BiblesPlugin.UpgradeWizardForm',
|
||||
'Bible Exists'),
|
||||
translate('BiblesPlugin.UpgradeWizardForm',
|
||||
'This Bible already exists. Please upgrade '
|
||||
'a different Bible, delete the existing one or '
|
||||
'uncheck.'))
|
||||
self.versionNameEdit[number].setFocus()
|
||||
return False
|
||||
elif os.path.exists(os.path.join(self.path, clean_filename(
|
||||
version_name))) and version_name == filename[1]:
|
||||
newfilename = u'old_database_%s' % filename[0]
|
||||
if not os.path.exists(os.path.join(self.path,
|
||||
newfilename)):
|
||||
os.rename(os.path.join(self.path, filename[0]),
|
||||
os.path.join(self.path, newfilename))
|
||||
self.files[number] = [newfilename, filename[1]]
|
||||
continue
|
||||
else:
|
||||
critical_error_message_box(
|
||||
translate('BiblesPlugin.UpgradeWizardForm',
|
||||
'Bible Exists'),
|
||||
translate('BiblesPlugin.UpgradeWizardForm',
|
||||
'This Bible already exists. Please upgrade '
|
||||
'a different Bible, delete the existing one or '
|
||||
'uncheck.'))
|
||||
self.verticalWidget[number].show()
|
||||
self.formWidget[number].show()
|
||||
self.versionNameEdit[number].setFocus()
|
||||
return False
|
||||
elif os.path.exists(os.path.join(self.path,
|
||||
clean_filename(version_name))):
|
||||
critical_error_message_box(
|
||||
translate('BiblesPlugin.UpgradeWizardForm',
|
||||
'Bible Exists'),
|
||||
translate('BiblesPlugin.UpgradeWizardForm',
|
||||
'This Bible already exists. Please upgrade '
|
||||
'a different Bible, delete the existing one or '
|
||||
'uncheck.'))
|
||||
self.versionNameEdit[number].setFocus()
|
||||
return False
|
||||
# Move bibles to temp dir.
|
||||
if not os.path.exists(os.path.join(self.temp_dir, filename[0])):
|
||||
shutil.move(
|
||||
os.path.join(self.path, filename[0]), self.temp_dir)
|
||||
else:
|
||||
delete_file(os.path.join(self.path, filename[0]))
|
||||
return True
|
||||
if self.currentPage() == self.progressPage:
|
||||
return True
|
||||
@ -495,16 +350,8 @@ class BibleUpgradeForm(OpenLPWizard):
|
||||
self.files = self.manager.old_bible_databases
|
||||
self.addScrollArea()
|
||||
self.retranslateUi()
|
||||
self.maxBibles = len(self.files)
|
||||
for number, filename in enumerate(self.files):
|
||||
self.checkBox[number].setCheckState(QtCore.Qt.Checked)
|
||||
oldname = filename[1]
|
||||
if self.manager.exists(oldname):
|
||||
self.verticalWidget[number].show()
|
||||
self.formWidget[number].show()
|
||||
else:
|
||||
self.verticalWidget[number].hide()
|
||||
self.formWidget[number].hide()
|
||||
self.progressBar.show()
|
||||
self.restart()
|
||||
self.finishButton.setVisible(False)
|
||||
@ -516,9 +363,8 @@ class BibleUpgradeForm(OpenLPWizard):
|
||||
Prepare the UI for the upgrade.
|
||||
"""
|
||||
OpenLPWizard.preWizard(self)
|
||||
self.progressLabel.setText(translate(
|
||||
'BiblesPlugin.UpgradeWizardForm',
|
||||
'Starting upgrade...'))
|
||||
self.progressLabel.setText(
|
||||
translate('BiblesPlugin.UpgradeWizardForm', 'Starting upgrade...'))
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
|
||||
def performWizard(self):
|
||||
@ -527,48 +373,42 @@ class BibleUpgradeForm(OpenLPWizard):
|
||||
"""
|
||||
self.include_webbible = False
|
||||
proxy_server = None
|
||||
if self.maxBibles == 0:
|
||||
if not self.files:
|
||||
self.progressLabel.setText(
|
||||
translate('BiblesPlugin.UpgradeWizardForm', 'There are no '
|
||||
'Bibles that need to be upgraded.'))
|
||||
self.progressBar.hide()
|
||||
return
|
||||
self.maxBibles = 0
|
||||
max_bibles = 0
|
||||
for number, file in enumerate(self.files):
|
||||
if self.checkBox[number].checkState() == QtCore.Qt.Checked:
|
||||
self.maxBibles += 1
|
||||
number = 0
|
||||
for biblenumber, filename in enumerate(self.files):
|
||||
max_bibles += 1
|
||||
oldBible = None
|
||||
for number, filename in enumerate(self.files):
|
||||
# Close the previous bible's connection.
|
||||
if oldBible is not None:
|
||||
oldBible.close_connection()
|
||||
# Set to None to make obvious that we have already closed the
|
||||
# database.
|
||||
oldBible = None
|
||||
if self.stop_import_flag:
|
||||
bible_failed = True
|
||||
self.success[number] = False
|
||||
break
|
||||
bible_failed = False
|
||||
self.success[biblenumber] = False
|
||||
if not self.checkBox[biblenumber].checkState() == QtCore.Qt.Checked:
|
||||
if not self.checkBox[number].checkState() == QtCore.Qt.Checked:
|
||||
self.success[number] = False
|
||||
continue
|
||||
self.progressBar.reset()
|
||||
oldbible = OldBibleDB(self.mediaItem, path=self.path,
|
||||
oldBible = OldBibleDB(self.mediaItem, path=self.temp_dir,
|
||||
file=filename[0])
|
||||
name = filename[1]
|
||||
if name is None:
|
||||
delete_file(os.path.join(self.path, filename[0]))
|
||||
self.incrementProgressBar(unicode(translate(
|
||||
'BiblesPlugin.UpgradeWizardForm',
|
||||
'Upgrading Bible %s of %s: "%s"\nFailed')) %
|
||||
(number + 1, self.maxBibles, name),
|
||||
self.progressBar.maximum() - self.progressBar.value())
|
||||
number += 1
|
||||
continue
|
||||
self.progressLabel.setText(unicode(translate(
|
||||
'BiblesPlugin.UpgradeWizardForm',
|
||||
'Upgrading Bible %s of %s: "%s"\nUpgrading ...')) %
|
||||
(number + 1, self.maxBibles, name))
|
||||
if os.path.exists(os.path.join(self.path, filename[0])):
|
||||
name = unicode(self.versionNameEdit[biblenumber].text())
|
||||
(number + 1, max_bibles, name))
|
||||
self.newbibles[number] = BibleDB(self.mediaItem, path=self.path,
|
||||
name=name)
|
||||
name=name, file=filename[0])
|
||||
self.newbibles[number].register(self.plugin.upgrade_wizard)
|
||||
metadata = oldbible.get_metadata()
|
||||
metadata = oldBible.get_metadata()
|
||||
webbible = False
|
||||
meta_data = {}
|
||||
for meta in metadata:
|
||||
@ -595,7 +435,7 @@ class BibleUpgradeForm(OpenLPWizard):
|
||||
u'name: "%s" failed' % (
|
||||
meta_data[u'download source'],
|
||||
meta_data[u'download name']))
|
||||
delete_database(self.path, clean_filename(name))
|
||||
self.newbibles[number].session.close()
|
||||
del self.newbibles[number]
|
||||
critical_error_message_box(
|
||||
translate('BiblesPlugin.UpgradeWizardForm',
|
||||
@ -606,9 +446,9 @@ class BibleUpgradeForm(OpenLPWizard):
|
||||
self.incrementProgressBar(unicode(translate(
|
||||
'BiblesPlugin.UpgradeWizardForm',
|
||||
'Upgrading Bible %s of %s: "%s"\nFailed')) %
|
||||
(number + 1, self.maxBibles, name),
|
||||
(number + 1, max_bibles, name),
|
||||
self.progressBar.maximum() - self.progressBar.value())
|
||||
number += 1
|
||||
self.success[number] = False
|
||||
continue
|
||||
bible = BiblesResourcesDB.get_webbible(
|
||||
meta_data[u'download name'],
|
||||
@ -621,25 +461,25 @@ class BibleUpgradeForm(OpenLPWizard):
|
||||
language_id = self.newbibles[number].get_language(name)
|
||||
if not language_id:
|
||||
log.warn(u'Upgrading from "%s" failed' % filename[0])
|
||||
delete_database(self.path, clean_filename(name))
|
||||
self.newbibles[number].session.close()
|
||||
del self.newbibles[number]
|
||||
self.incrementProgressBar(unicode(translate(
|
||||
'BiblesPlugin.UpgradeWizardForm',
|
||||
'Upgrading Bible %s of %s: "%s"\nFailed')) %
|
||||
(number + 1, self.maxBibles, name),
|
||||
(number + 1, max_bibles, name),
|
||||
self.progressBar.maximum() - self.progressBar.value())
|
||||
number += 1
|
||||
self.success[number] = False
|
||||
continue
|
||||
self.progressBar.setMaximum(len(books))
|
||||
for book in books:
|
||||
if self.stop_import_flag:
|
||||
bible_failed = True
|
||||
self.success[number] = False
|
||||
break
|
||||
self.incrementProgressBar(unicode(translate(
|
||||
'BiblesPlugin.UpgradeWizardForm',
|
||||
'Upgrading Bible %s of %s: "%s"\n'
|
||||
'Upgrading %s ...')) %
|
||||
(number + 1, self.maxBibles, name, book))
|
||||
(number + 1, max_bibles, name, book))
|
||||
book_ref_id = self.newbibles[number].\
|
||||
get_book_ref_id_by_name(book, len(books), language_id)
|
||||
if not book_ref_id:
|
||||
@ -647,24 +487,24 @@ class BibleUpgradeForm(OpenLPWizard):
|
||||
u'name: "%s" aborted by user' % (
|
||||
meta_data[u'download source'],
|
||||
meta_data[u'download name']))
|
||||
delete_database(self.path, clean_filename(name))
|
||||
self.newbibles[number].session.close()
|
||||
del self.newbibles[number]
|
||||
bible_failed = True
|
||||
self.success[number] = False
|
||||
break
|
||||
book_details = BiblesResourcesDB.get_book_by_id(book_ref_id)
|
||||
db_book = self.newbibles[number].create_book(book,
|
||||
book_ref_id, book_details[u'testament_id'])
|
||||
# Try to import still downloaded verses
|
||||
oldbook = oldbible.get_book(book)
|
||||
# Try to import already downloaded verses.
|
||||
oldbook = oldBible.get_book(book)
|
||||
if oldbook:
|
||||
verses = oldbible.get_verses(oldbook[u'id'])
|
||||
verses = oldBible.get_verses(oldbook[u'id'])
|
||||
if not verses:
|
||||
log.warn(u'No verses found to import for book '
|
||||
u'"%s"', book)
|
||||
continue
|
||||
for verse in verses:
|
||||
if self.stop_import_flag:
|
||||
bible_failed = True
|
||||
self.success[number] = False
|
||||
break
|
||||
self.newbibles[number].create_verse(db_book.id,
|
||||
int(verse[u'chapter']),
|
||||
@ -678,40 +518,40 @@ class BibleUpgradeForm(OpenLPWizard):
|
||||
language_id = self.newbibles[number].get_language(name)
|
||||
if not language_id:
|
||||
log.warn(u'Upgrading books from "%s" failed' % name)
|
||||
delete_database(self.path, clean_filename(name))
|
||||
self.newbibles[number].session.close()
|
||||
del self.newbibles[number]
|
||||
self.incrementProgressBar(unicode(translate(
|
||||
'BiblesPlugin.UpgradeWizardForm',
|
||||
'Upgrading Bible %s of %s: "%s"\nFailed')) %
|
||||
(number + 1, self.maxBibles, name),
|
||||
(number + 1, max_bibles, name),
|
||||
self.progressBar.maximum() - self.progressBar.value())
|
||||
number += 1
|
||||
self.success[number] = False
|
||||
continue
|
||||
books = oldbible.get_books()
|
||||
books = oldBible.get_books()
|
||||
self.progressBar.setMaximum(len(books))
|
||||
for book in books:
|
||||
if self.stop_import_flag:
|
||||
bible_failed = True
|
||||
self.success[number] = False
|
||||
break
|
||||
self.incrementProgressBar(unicode(translate(
|
||||
'BiblesPlugin.UpgradeWizardForm',
|
||||
'Upgrading Bible %s of %s: "%s"\n'
|
||||
'Upgrading %s ...')) %
|
||||
(number + 1, self.maxBibles, name, book[u'name']))
|
||||
(number + 1, max_bibles, name, book[u'name']))
|
||||
book_ref_id = self.newbibles[number].\
|
||||
get_book_ref_id_by_name(book[u'name'], len(books),
|
||||
language_id)
|
||||
if not book_ref_id:
|
||||
log.warn(u'Upgrading books from %s " '\
|
||||
'failed - aborted by user' % name)
|
||||
delete_database(self.path, clean_filename(name))
|
||||
self.newbibles[number].session.close()
|
||||
del self.newbibles[number]
|
||||
bible_failed = True
|
||||
self.success[number] = False
|
||||
break
|
||||
book_details = BiblesResourcesDB.get_book_by_id(book_ref_id)
|
||||
db_book = self.newbibles[number].create_book(book[u'name'],
|
||||
book_ref_id, book_details[u'testament_id'])
|
||||
verses = oldbible.get_verses(book[u'id'])
|
||||
verses = oldBible.get_verses(book[u'id'])
|
||||
if not verses:
|
||||
log.warn(u'No verses found to import for book '
|
||||
u'"%s"', book[u'name'])
|
||||
@ -719,31 +559,32 @@ class BibleUpgradeForm(OpenLPWizard):
|
||||
continue
|
||||
for verse in verses:
|
||||
if self.stop_import_flag:
|
||||
bible_failed = True
|
||||
self.success[number] = False
|
||||
break
|
||||
self.newbibles[number].create_verse(db_book.id,
|
||||
int(verse[u'chapter']),
|
||||
int(verse[u'verse']), unicode(verse[u'text']))
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
self.newbibles[number].session.commit()
|
||||
if not bible_failed:
|
||||
if self.success.has_key(number) and not self.success[number]:
|
||||
self.incrementProgressBar(unicode(translate(
|
||||
'BiblesPlugin.UpgradeWizardForm',
|
||||
'Upgrading Bible %s of %s: "%s"\nFailed')) %
|
||||
(number + 1, max_bibles, name),
|
||||
self.progressBar.maximum() - self.progressBar.value())
|
||||
else:
|
||||
self.success[number] = True
|
||||
self.newbibles[number].create_meta(u'Version', name)
|
||||
oldbible.close_connection()
|
||||
delete_file(os.path.join(self.path, filename[0]))
|
||||
self.incrementProgressBar(unicode(translate(
|
||||
'BiblesPlugin.UpgradeWizardForm',
|
||||
'Upgrading Bible %s of %s: "%s"\n'
|
||||
'Complete')) %
|
||||
(number + 1, self.maxBibles, name))
|
||||
self.success[biblenumber] = True
|
||||
else:
|
||||
self.incrementProgressBar(unicode(translate(
|
||||
'BiblesPlugin.UpgradeWizardForm',
|
||||
'Upgrading Bible %s of %s: "%s"\nFailed')) %
|
||||
(number + 1, self.maxBibles, name),
|
||||
self.progressBar.maximum() - self.progressBar.value())
|
||||
delete_database(self.path, clean_filename(name))
|
||||
number += 1
|
||||
(number + 1, max_bibles, name))
|
||||
if self.newbibles.has_key(number):
|
||||
self.newbibles[number].session.close()
|
||||
# Close the last bible's connection if possible.
|
||||
if oldBible is not None:
|
||||
oldBible.close_connection()
|
||||
|
||||
def postWizard(self):
|
||||
"""
|
||||
@ -752,10 +593,14 @@ class BibleUpgradeForm(OpenLPWizard):
|
||||
successful_import = 0
|
||||
failed_import = 0
|
||||
for number, filename in enumerate(self.files):
|
||||
if number in self.success and self.success[number] == True:
|
||||
if self.success.has_key(number) and self.success[number]:
|
||||
successful_import += 1
|
||||
elif self.checkBox[number].checkState() == QtCore.Qt.Checked:
|
||||
failed_import += 1
|
||||
# Delete upgraded (but not complete, corrupted, ...) bible.
|
||||
delete_file(os.path.join(self.path, filename[0]))
|
||||
# Copy not upgraded bible back.
|
||||
shutil.move(os.path.join(self.temp_dir, filename[0]), self.path)
|
||||
if failed_import > 0:
|
||||
failed_import_text = unicode(translate(
|
||||
'BiblesPlugin.UpgradeWizardForm',
|
||||
@ -776,7 +621,8 @@ class BibleUpgradeForm(OpenLPWizard):
|
||||
'Bible(s): %s successful%s')) % (successful_import,
|
||||
failed_import_text))
|
||||
else:
|
||||
self.progressLabel.setText(
|
||||
translate('BiblesPlugin.UpgradeWizardForm', 'Upgrade '
|
||||
'failed.'))
|
||||
self.progressLabel.setText(translate(
|
||||
'BiblesPlugin.UpgradeWizardForm', 'Upgrade failed.'))
|
||||
# Remove temp directory.
|
||||
shutil.rmtree(self.temp_dir, True)
|
||||
OpenLPWizard.postWizard(self)
|
||||
|
@ -45,7 +45,7 @@ class LanguageForm(QDialog, Ui_LanguageDialog):
|
||||
"""
|
||||
log.info(u'LanguageForm loaded')
|
||||
|
||||
def __init__(self, parent = None):
|
||||
def __init__(self, parent=None):
|
||||
"""
|
||||
Constructor
|
||||
"""
|
||||
@ -57,12 +57,11 @@ class LanguageForm(QDialog, Ui_LanguageDialog):
|
||||
if bible_name:
|
||||
self.bibleLabel.setText(unicode(bible_name))
|
||||
items = BiblesResourcesDB.get_languages()
|
||||
for item in items:
|
||||
self.languageComboBox.addItem(item[u'name'])
|
||||
self.languageComboBox.addItems([item[u'name'] for item in items])
|
||||
return QDialog.exec_(self)
|
||||
|
||||
def accept(self):
|
||||
if self.languageComboBox.currentText() == u'':
|
||||
if not self.languageComboBox.currentText():
|
||||
critical_error_message_box(
|
||||
message=translate('BiblesPlugin.LanguageForm',
|
||||
'You need to choose a language.'))
|
||||
|
@ -39,7 +39,7 @@ from sqlalchemy.orm.exc import UnmappedClassError
|
||||
from openlp.core.lib import Receiver, translate
|
||||
from openlp.core.lib.db import BaseModel, init_db, Manager
|
||||
from openlp.core.lib.ui import critical_error_message_box
|
||||
from openlp.core.utils import AppLocation
|
||||
from openlp.core.utils import AppLocation, clean_filename
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
@ -63,19 +63,6 @@ class Verse(BaseModel):
|
||||
"""
|
||||
pass
|
||||
|
||||
def clean_filename(filename):
|
||||
"""
|
||||
Clean up the version name of the Bible and convert it into a valid
|
||||
file name.
|
||||
|
||||
``filename``
|
||||
The "dirty" file name or version name.
|
||||
"""
|
||||
if not isinstance(filename, unicode):
|
||||
filename = unicode(filename, u'utf-8')
|
||||
filename = re.sub(r'[^\w]+', u'_', filename).strip(u'_')
|
||||
return filename + u'.sqlite'
|
||||
|
||||
def init_schema(url):
|
||||
"""
|
||||
Setup a bible database connection and initialise the database schema.
|
||||
@ -158,7 +145,7 @@ class BibleDB(QtCore.QObject, Manager):
|
||||
self.name = kwargs[u'name']
|
||||
if not isinstance(self.name, unicode):
|
||||
self.name = unicode(self.name, u'utf-8')
|
||||
self.file = clean_filename(self.name)
|
||||
self.file = clean_filename(self.name) + u'.sqlite'
|
||||
if u'file' in kwargs:
|
||||
self.file = kwargs[u'file']
|
||||
Manager.__init__(self, u'bibles', init_schema, self.file)
|
||||
|
@ -151,9 +151,10 @@ class BibleManager(object):
|
||||
name = bible.get_name()
|
||||
# Remove corrupted files.
|
||||
if name is None:
|
||||
bible.session.close()
|
||||
delete_file(os.path.join(self.path, filename))
|
||||
continue
|
||||
# Find old database versions
|
||||
# Find old database versions.
|
||||
if bible.is_old_database():
|
||||
self.old_bible_databases.append([filename, name])
|
||||
bible.session.close()
|
||||
|
@ -395,6 +395,7 @@ class BibleMediaItem(MediaManagerItem):
|
||||
log.debug(u'Reloading Bibles')
|
||||
self.plugin.manager.reload_bibles()
|
||||
self.loadBibles()
|
||||
self.updateAutoCompleter()
|
||||
|
||||
def initialiseAdvancedBible(self, bible):
|
||||
"""
|
||||
@ -612,7 +613,7 @@ class BibleMediaItem(MediaManagerItem):
|
||||
if restore:
|
||||
old_text = unicode(combo.currentText())
|
||||
combo.clear()
|
||||
combo.addItems([unicode(i) for i in range(range_from, range_to + 1)])
|
||||
combo.addItems(map(unicode, range(range_from, range_to + 1)))
|
||||
if restore and combo.findText(old_text) != -1:
|
||||
combo.setCurrentIndex(combo.findText(old_text))
|
||||
|
||||
|
Binary file not shown.
@ -52,6 +52,8 @@ class ImageMediaItem(MediaManagerItem):
|
||||
self.hasSearch = True
|
||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||
QtCore.SIGNAL(u'live_theme_changed'), self.liveThemeChanged)
|
||||
# Allow DnD from the desktop
|
||||
self.listView.activateDnD()
|
||||
|
||||
def retranslateUi(self):
|
||||
self.onNewPrompt = translate('ImagePlugin.MediaItem',
|
||||
@ -131,6 +133,7 @@ class ImageMediaItem(MediaManagerItem):
|
||||
icon = self.iconFromFile(imageFile, thumb)
|
||||
item_name = QtGui.QListWidgetItem(filename)
|
||||
item_name.setIcon(icon)
|
||||
item_name.setToolTip(imageFile)
|
||||
item_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(imageFile))
|
||||
self.listView.addItem(item_name)
|
||||
if not initialLoad:
|
||||
|
@ -39,6 +39,8 @@ from PyQt4.phonon import Phonon
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
CLAPPERBOARD = QtGui.QPixmap(u':/media/media_video.png').toImage()
|
||||
|
||||
class MediaMediaItem(MediaManagerItem):
|
||||
"""
|
||||
This is the custom media manager item for Media Slides.
|
||||
@ -48,8 +50,7 @@ class MediaMediaItem(MediaManagerItem):
|
||||
def __init__(self, parent, plugin, icon):
|
||||
self.IconPath = u'images/image'
|
||||
self.background = False
|
||||
self.PreviewFunction = QtGui.QPixmap(
|
||||
u':/media/media_video.png').toImage()
|
||||
self.PreviewFunction = CLAPPERBOARD
|
||||
MediaManagerItem.__init__(self, parent, plugin, icon)
|
||||
self.singleServiceItem = False
|
||||
self.hasSearch = True
|
||||
@ -60,6 +61,8 @@ class MediaMediaItem(MediaManagerItem):
|
||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||
QtCore.SIGNAL(u'openlp_phonon_creation'),
|
||||
self.createPhonon)
|
||||
# Allow DnD from the desktop
|
||||
self.listView.activateDnD()
|
||||
|
||||
def retranslateUi(self):
|
||||
self.onNewPrompt = translate('MediaPlugin.MediaItem', 'Select Media')
|
||||
@ -201,17 +204,17 @@ class MediaMediaItem(MediaManagerItem):
|
||||
SettingsManager.set_list(self.settingsSection,
|
||||
u'media', self.getFileList())
|
||||
|
||||
def loadList(self, files):
|
||||
def loadList(self, media):
|
||||
# Sort the themes by its filename considering language specific
|
||||
# characters. lower() is needed for windows!
|
||||
files.sort(cmp=locale.strcoll,
|
||||
media.sort(cmp=locale.strcoll,
|
||||
key=lambda filename: os.path.split(unicode(filename))[1].lower())
|
||||
for file in files:
|
||||
filename = os.path.split(unicode(file))[1]
|
||||
for track in media:
|
||||
filename = os.path.split(unicode(track))[1]
|
||||
item_name = QtGui.QListWidgetItem(filename)
|
||||
img = QtGui.QPixmap(u':/media/media_video.png').toImage()
|
||||
item_name.setIcon(build_icon(img))
|
||||
item_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(file))
|
||||
item_name.setIcon(build_icon(CLAPPERBOARD))
|
||||
item_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(track))
|
||||
item_name.setToolTip(track)
|
||||
self.listView.addItem(item_name)
|
||||
|
||||
def createPhonon(self):
|
||||
|
@ -58,6 +58,8 @@ class PresentationMediaItem(MediaManagerItem):
|
||||
self.hasSearch = True
|
||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||
QtCore.SIGNAL(u'mediaitem_presentation_rebuild'), self.rebuild)
|
||||
# Allow DnD from the desktop
|
||||
self.listView.activateDnD()
|
||||
|
||||
def retranslateUi(self):
|
||||
"""
|
||||
@ -205,6 +207,7 @@ class PresentationMediaItem(MediaManagerItem):
|
||||
item_name = QtGui.QListWidgetItem(filename)
|
||||
item_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(file))
|
||||
item_name.setIcon(icon)
|
||||
item_name.setToolTip(file)
|
||||
self.listView.addItem(item_name)
|
||||
Receiver.send_message(u'cursor_normal')
|
||||
if not initialLoad:
|
||||
|
@ -28,6 +28,7 @@
|
||||
The :mod:`songexportform` module provides the wizard for exporting songs to the
|
||||
OpenLyrics format.
|
||||
"""
|
||||
import locale
|
||||
import logging
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
@ -249,6 +250,7 @@ class SongExportForm(OpenLPWizard):
|
||||
# Load the list of songs.
|
||||
Receiver.send_message(u'cursor_busy')
|
||||
songs = self.plugin.manager.get_all_objects(Song)
|
||||
songs.sort(cmp=locale.strcoll, key=lambda song: song.title.lower())
|
||||
for song in songs:
|
||||
authors = u', '.join([author.display_name
|
||||
for author in song.authors])
|
||||
|
@ -699,7 +699,8 @@ class SongImportForm(OpenLPWizard):
|
||||
elif source_format == SongFormat.OpenLP1:
|
||||
# Import an openlp.org database
|
||||
importer = self.plugin.importSongs(SongFormat.OpenLP1,
|
||||
filename=unicode(self.openLP1FilenameEdit.text())
|
||||
filename=unicode(self.openLP1FilenameEdit.text()),
|
||||
plugin=self.plugin
|
||||
)
|
||||
elif source_format == SongFormat.OpenLyrics:
|
||||
# Import OpenLyrics songs
|
||||
|
@ -57,6 +57,8 @@ class OpenLP1SongImport(SongImport):
|
||||
The database providing the data to import.
|
||||
"""
|
||||
SongImport.__init__(self, manager, **kwargs)
|
||||
self.available_themes = \
|
||||
kwargs[u'plugin'].formparent.themeManagerContents.getThemes()
|
||||
|
||||
def do_import(self):
|
||||
"""
|
||||
@ -70,27 +72,34 @@ class OpenLP1SongImport(SongImport):
|
||||
encoding = self.get_encoding()
|
||||
if not encoding:
|
||||
return
|
||||
# Connect to the database
|
||||
# Connect to the database.
|
||||
connection = sqlite.connect(self.import_source, mode=0444,
|
||||
encoding=(encoding, 'replace'))
|
||||
cursor = connection.cursor()
|
||||
# Determine if we're using a new or an old DB
|
||||
# Determine if we're using a new or an old DB.
|
||||
cursor.execute(u'SELECT name FROM sqlite_master '
|
||||
u'WHERE type = \'table\' AND name = \'tracks\'')
|
||||
new_db = len(cursor.fetchall()) > 0
|
||||
# "cache" our list of authors
|
||||
# "cache" our list of authors.
|
||||
cursor.execute(u'-- types int, unicode')
|
||||
cursor.execute(u'SELECT authorid, authorname FROM authors')
|
||||
authors = cursor.fetchall()
|
||||
if new_db:
|
||||
# "cache" our list of tracks
|
||||
# "cache" our list of tracks.
|
||||
cursor.execute(u'-- types int, unicode')
|
||||
cursor.execute(u'SELECT trackid, fulltrackname FROM tracks')
|
||||
tracks = cursor.fetchall()
|
||||
# Import the songs
|
||||
cursor.execute(u'-- types int, unicode, unicode, unicode')
|
||||
# "cache" our list of themes.
|
||||
cursor.execute(u'-- types int, unicode')
|
||||
cursor.execute(u'SELECT settingsid, settingsname FROM settings')
|
||||
themes = {}
|
||||
for theme_id, theme_name in cursor.fetchall():
|
||||
if theme_name in self.available_themes:
|
||||
themes[theme_id] = theme_name
|
||||
# Import the songs.
|
||||
cursor.execute(u'-- types int, unicode, unicode, unicode, int')
|
||||
cursor.execute(u'SELECT songid, songtitle, lyrics || \'\' AS lyrics, '
|
||||
u'copyrightinfo FROM songs')
|
||||
u'copyrightinfo, settingsid FROM songs')
|
||||
songs = cursor.fetchall()
|
||||
self.import_wizard.progressBar.setMaximum(len(songs))
|
||||
for song in songs:
|
||||
@ -101,8 +110,12 @@ class OpenLP1SongImport(SongImport):
|
||||
self.title = song[1]
|
||||
lyrics = song[2].replace(u'\r\n', u'\n')
|
||||
self.add_copyright(song[3])
|
||||
if themes.has_key(song[4]):
|
||||
self.theme_name = themes[song[4]]
|
||||
verses = lyrics.split(u'\n\n')
|
||||
[self.add_verse(verse.strip()) for verse in verses if verse.strip()]
|
||||
for verse in verses:
|
||||
if verse.strip():
|
||||
self.add_verse(verse.strip())
|
||||
cursor.execute(u'-- types int')
|
||||
cursor.execute(u'SELECT authorid FROM songauthors '
|
||||
u'WHERE songid = %s' % song_id)
|
||||
@ -137,12 +150,12 @@ class OpenLP1SongImport(SongImport):
|
||||
"""
|
||||
Detect character encoding of an openlp.org 1.x song database.
|
||||
"""
|
||||
# Connect to the database
|
||||
# Connect to the database.
|
||||
connection = sqlite.connect(self.import_source, mode=0444)
|
||||
cursor = connection.cursor()
|
||||
|
||||
detector = UniversalDetector()
|
||||
# detect charset by authors
|
||||
# Detect charset by authors.
|
||||
cursor.execute(u'SELECT authorname FROM authors')
|
||||
authors = cursor.fetchall()
|
||||
for author in authors:
|
||||
@ -150,7 +163,7 @@ class OpenLP1SongImport(SongImport):
|
||||
if detector.done:
|
||||
detector.close()
|
||||
return detector.result[u'encoding']
|
||||
# detect charset by songs
|
||||
# Detect charset by songs.
|
||||
cursor.execute(u'SELECT songtitle, copyrightinfo, '
|
||||
u'lyrics || \'\' AS lyrics FROM songs')
|
||||
songs = cursor.fetchall()
|
||||
@ -160,7 +173,7 @@ class OpenLP1SongImport(SongImport):
|
||||
if detector.done:
|
||||
detector.close()
|
||||
return detector.result[u'encoding']
|
||||
# detect charset by songs
|
||||
# Detect charset by songs.
|
||||
cursor.execute(u'SELECT name FROM sqlite_master '
|
||||
u'WHERE type = \'table\' AND name = \'tracks\'')
|
||||
if len(cursor.fetchall()) > 0:
|
||||
|
@ -35,6 +35,7 @@ import re
|
||||
from lxml import etree
|
||||
|
||||
from openlp.core.lib import check_directory_exists, Receiver, translate
|
||||
from openlp.core.utils import clean_filename
|
||||
from openlp.plugins.songs.lib import OpenLyrics
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
@ -72,8 +73,7 @@ class OpenLyricsExport(object):
|
||||
tree = etree.ElementTree(etree.fromstring(xml))
|
||||
filename = u'%s (%s)' % (song.title,
|
||||
u', '.join([author.display_name for author in song.authors]))
|
||||
filename = re.sub(
|
||||
r'[/\\?*|<>\[\]":<>+%]+', u'_', filename).strip(u'_')
|
||||
filename = clean_filename(filename)
|
||||
# Ensure the filename isn't too long for some filesystems
|
||||
filename = u'%s.xml' % filename[0:250 - len(self.save_path)]
|
||||
# Pass a file object, because lxml does not cope with some special
|
||||
|
@ -102,7 +102,6 @@ class SongShowPlusImport(SongImport):
|
||||
if not isinstance(self.import_source, list):
|
||||
return
|
||||
self.import_wizard.progressBar.setMaximum(len(self.import_source))
|
||||
|
||||
for file in self.import_source:
|
||||
self.sspVerseOrderList = []
|
||||
otherCount = 0
|
||||
@ -111,7 +110,6 @@ class SongShowPlusImport(SongImport):
|
||||
self.import_wizard.incrementProgressBar(
|
||||
WizardStrings.ImportingType % file_name, 0)
|
||||
songData = open(file, 'rb')
|
||||
|
||||
while True:
|
||||
blockKey, = struct.unpack("I", songData.read(4))
|
||||
# The file ends with 4 NUL's
|
||||
@ -126,8 +124,9 @@ class SongShowPlusImport(SongImport):
|
||||
songData.read(2))
|
||||
verseName = songData.read(verseNameLength)
|
||||
lengthDescriptorSize, = struct.unpack("B", songData.read(1))
|
||||
log.debug(lengthDescriptorSize)
|
||||
# Detect if/how long the length descriptor is
|
||||
if lengthDescriptorSize == 12:
|
||||
if lengthDescriptorSize == 12 or lengthDescriptorSize == 20:
|
||||
lengthDescriptor, = struct.unpack("I", songData.read(4))
|
||||
elif lengthDescriptorSize == 2:
|
||||
lengthDescriptor = 1
|
||||
@ -135,6 +134,7 @@ class SongShowPlusImport(SongImport):
|
||||
lengthDescriptor = 0
|
||||
else:
|
||||
lengthDescriptor, = struct.unpack("B", songData.read(1))
|
||||
log.debug(lengthDescriptorSize)
|
||||
data = songData.read(lengthDescriptor)
|
||||
if blockKey == TITLE:
|
||||
self.title = unicode(data, u'cp1252')
|
||||
|
@ -246,8 +246,9 @@ class OpenLyrics(object):
|
||||
# Append the necessary meta data to the song.
|
||||
song_xml.set(u'xmlns', u'http://openlyrics.info/namespace/2009/song')
|
||||
song_xml.set(u'version', OpenLyrics.IMPLEMENTED_VERSION)
|
||||
song_xml.set(u'createdIn', get_application_version()[u'version'])
|
||||
song_xml.set(u'modifiedIn', get_application_version()[u'version'])
|
||||
application_name = u'OpenLP ' + get_application_version()[u'version']
|
||||
song_xml.set(u'createdIn', application_name)
|
||||
song_xml.set(u'modifiedIn', application_name)
|
||||
song_xml.set(u'modifiedDate',
|
||||
datetime.datetime.now().strftime(u'%Y-%m-%dT%H:%M:%S'))
|
||||
properties = etree.SubElement(song_xml, u'properties')
|
||||
|
@ -91,8 +91,8 @@ class SongUsagePlugin(Plugin):
|
||||
self.toolsMenu.addAction(self.songUsageMenu.menuAction())
|
||||
self.songUsageMenu.addAction(self.songUsageStatus)
|
||||
self.songUsageMenu.addSeparator()
|
||||
self.songUsageMenu.addAction(self.songUsageDelete)
|
||||
self.songUsageMenu.addAction(self.songUsageReport)
|
||||
self.songUsageMenu.addAction(self.songUsageDelete)
|
||||
self.songUsageActiveButton = QtGui.QToolButton(
|
||||
self.formparent.statusBar)
|
||||
self.songUsageActiveButton.setCheckable(True)
|
||||
|
@ -2,6 +2,99 @@
|
||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
|
||||
<key>CFBundleDocumentTypes</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>CFBundleTypeExtension</key>
|
||||
<array>
|
||||
<string>osz</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFiles</key>
|
||||
<array>
|
||||
<string>openlp-logo-with-text.icns</string>
|
||||
</array>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>OpenLP Service</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Viewer</string>
|
||||
<key>LSHandlerRank</key>
|
||||
<string>Owner</string>
|
||||
<key>LSItemContentTypes</key>
|
||||
<array>
|
||||
<string>org.openlp.osz</string>
|
||||
</array>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeExtension</key>
|
||||
<array>
|
||||
<string>otz</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFiles</key>
|
||||
<array>
|
||||
<string>openlp-logo-with-text.icns</string>
|
||||
</array>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>OpenLP Theme</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Viewer</string>
|
||||
<key>LSHandlerRank</key>
|
||||
<string>Owner</string>
|
||||
<key>LSItemContentTypes</key>
|
||||
<array>
|
||||
<string>org.openlp.otz</string>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
|
||||
<key>UTExportedTypeDeclarations</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>UTTypeIdentifier</key>
|
||||
<string>org.openlp.osz</string>
|
||||
<key>UTTypeDescription</key>
|
||||
<string>OpenLP Service</string>
|
||||
<key>UTTypeConformsTo</key>
|
||||
<array>
|
||||
<string>public.data</string>
|
||||
<string>public.content</string>
|
||||
</array>
|
||||
<key>UTTypeTagSpecification</key>
|
||||
<dict>
|
||||
<key>public.filename-extension</key>
|
||||
<array>
|
||||
<string>osz</string>
|
||||
</array>
|
||||
<key>public.mime-type</key>
|
||||
<array>
|
||||
<string>application/x-openlp-service</string>
|
||||
</array>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>UTTypeIdentifier</key>
|
||||
<string>org.openlp.otz</string>
|
||||
<key>UTTypeDescription</key>
|
||||
<string>OpenLP Theme</string>
|
||||
<key>UTTypeConformsTo</key>
|
||||
<array>
|
||||
<string>public.data</string>
|
||||
<string>public.content</string>
|
||||
</array>
|
||||
<key>UTTypeTagSpecification</key>
|
||||
<dict>
|
||||
<key>public.filename-extension</key>
|
||||
<array>
|
||||
<string>otz</string>
|
||||
</array>
|
||||
<key>public.mime-type</key>
|
||||
<array>
|
||||
<string>application/x-openlp-theme</string>
|
||||
</array>
|
||||
</dict>
|
||||
</dict>
|
||||
</array>
|
||||
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>org.openlp</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
|
@ -48,7 +48,7 @@ on run
|
||||
set theViewOptions to the icon view options of container window
|
||||
set arrangement of theViewOptions to not arranged
|
||||
set icon size of theViewOptions to 128
|
||||
set background picture of theViewOptions to file ".installer-background.png"
|
||||
set background picture of theViewOptions to file ".background:installer-background.png"
|
||||
if not exists file "Applications" then
|
||||
make new alias file at container window to POSIX file "/Applications" with properties {name:"Applications"}
|
||||
end if
|
||||
|
@ -49,15 +49,19 @@ on run
|
||||
set theViewOptions to the icon view options of container window
|
||||
set arrangement of theViewOptions to not arranged
|
||||
set icon size of theViewOptions to 128
|
||||
set background picture of theViewOptions to file ".installer-background.png"
|
||||
make new alias file at container window to POSIX file "/Applications" with properties {name:"Applications"}
|
||||
delay 5
|
||||
set background picture of theViewOptions to file ".background:installer-background.png"
|
||||
if not exists file "Applications" then
|
||||
make new alias file at container window to POSIX file "/Applications" with properties {name:"Applications"}
|
||||
end if
|
||||
delay 1
|
||||
set position of item "%s" of container window to {160, 200}
|
||||
set position of item ".Trashes" of container window to {100, 500}
|
||||
set position of item ".installer-background.png" of container window to {200, 500}
|
||||
set position of item ".background" of container window to {200, 500}
|
||||
set position of item ".DS_Store" of container window to {400, 500}
|
||||
set position of item "Applications" of container window to {550, 200}
|
||||
set position of item ".VolumeIcon.icns" of container window to {500, 500}
|
||||
if exists file ".VolumeIcon.icns" then
|
||||
set position of item ".VolumeIcon.icns" of container window to {500, 500}
|
||||
end if
|
||||
set position of item ".fseventsd" of container window to {300, 500}
|
||||
if exists POSIX file ".SymAVx86QSFile" then
|
||||
set position of item ".SymAVx86QSFile" of container window to {600, 500}
|
||||
|
@ -93,8 +93,12 @@ script_name = "build"
|
||||
def build_application(settings, app_name_lower, app_dir):
|
||||
logging.info('[%s] now building the app with pyinstaller at "%s"...',
|
||||
script_name, settings['pyinstaller_basedir'])
|
||||
result = os.system('python %s/pyinstaller.py openlp.spec' \
|
||||
% settings['pyinstaller_basedir'])
|
||||
full_python_dir = os.path.join('/opt/local/Library/Frameworks',
|
||||
'Python.framework/Versions/2.6/Resources/',
|
||||
'Python.app/Contents/MacOS/Python')
|
||||
result = os.system('arch -i386 %s %s/pyinstaller.py openlp.spec' \
|
||||
% ( full_python_dir,
|
||||
settings['pyinstaller_basedir']) )
|
||||
if (result != 0):
|
||||
logging.error('[%s] The pyinstaller build reported an error, cannot \
|
||||
continue!', script_name)
|
||||
@ -219,10 +223,10 @@ def create_dmg(settings):
|
||||
sys.exit(1)
|
||||
|
||||
logging.info('[%s] copying the background image...', script_name)
|
||||
# os.mkdir(volume_basedir + '/.background')
|
||||
os.mkdir(volume_basedir + '/.background')
|
||||
result = os.system('CpMac %s %s'
|
||||
% (settings['installer_backgroundimage_file'],
|
||||
volume_basedir + '/.installer-background.png'))
|
||||
volume_basedir + '/.background/installer-background.png'))
|
||||
if (result != 0):
|
||||
logging.error('[%s] could not copy the background image, dmg creation\
|
||||
failed!', script_name)
|
||||
|
0
resources/osx/openlp-logo-with-text.icns
Executable file → Normal file
0
resources/osx/openlp-logo-with-text.icns
Executable file → Normal file
@ -1,8 +1,8 @@
|
||||
[openlp]
|
||||
openlp_appname = OpenLP
|
||||
openlp_dmgname = OpenLP-1.9.4-bzrXXXX
|
||||
openlp_dmgname = OpenLP-1.9.6-bzrXXXX
|
||||
openlp_version = XXXX
|
||||
openlp_basedir = /Users/openlp/trunk
|
||||
openlp_basedir = /Users/openlp/repo/trunk
|
||||
openlp_icon_file = openlp-logo-with-text.icns
|
||||
openlp_dmg_icon_file = openlp-logo-420x420.png
|
||||
installer_backgroundimage_file = installation-background.png
|
@ -1,5 +1,5 @@
|
||||
# -*- mode: python -*-
|
||||
a = Analysis([os.path.join(HOMEPATH,'support/_mountzlib.py'), os.path.join(HOMEPATH,'support/useUnicode.py'), '%(openlp_basedir)s/openlp.pyw'],
|
||||
a = Analysis([os.path.join(HOMEPATH,'support/_mountzlib.py'), os.path.join(CONFIGDIR,'support/useUnicode.py'), '%(openlp_basedir)s/openlp.pyw'],
|
||||
pathex=['%(pyinstaller_basedir)s'], hookspath=['%(openlp_basedir)s/resources/pyinstaller'])
|
||||
pyz = PYZ(a.pure)
|
||||
exe = EXE(pyz,
|
||||
|
Loading…
Reference in New Issue
Block a user