forked from openlp/openlp
head1711
This commit is contained in:
commit
365a0477d7
@ -20,3 +20,4 @@ _eric4project
|
|||||||
openlp/core/resources.py.old
|
openlp/core/resources.py.old
|
||||||
*.qm
|
*.qm
|
||||||
resources/windows/warnOpenLP.txt
|
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.
|
class in order to provide the core of the application.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
args = []
|
||||||
|
|
||||||
def exec_(self):
|
def exec_(self):
|
||||||
"""
|
"""
|
||||||
Override exec method to allow the shared memory to be released on exit
|
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
|
# On Windows, the args passed into the constructor are
|
||||||
# ignored. Not very handy, so set the ones we want to use.
|
# 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.
|
# provide a listener for widgets to reqest a screen update.
|
||||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||||
QtCore.SIGNAL(u'openlp_process_events'), self.processEvents)
|
QtCore.SIGNAL(u'openlp_process_events'), self.processEvents)
|
||||||
@ -125,6 +127,8 @@ class OpenLP(QtGui.QApplication):
|
|||||||
# now kill the splashscreen
|
# now kill the splashscreen
|
||||||
self.splash.finish(self.mainWindow)
|
self.splash.finish(self.mainWindow)
|
||||||
log.debug(u'Splashscreen closed')
|
log.debug(u'Splashscreen closed')
|
||||||
|
# make sure Qt really display the splash screen
|
||||||
|
self.processEvents()
|
||||||
self.mainWindow.repaint()
|
self.mainWindow.repaint()
|
||||||
self.processEvents()
|
self.processEvents()
|
||||||
if not has_run_wizard:
|
if not has_run_wizard:
|
||||||
@ -180,6 +184,18 @@ class OpenLP(QtGui.QApplication):
|
|||||||
"""
|
"""
|
||||||
self.restoreOverrideCursor()
|
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():
|
def main():
|
||||||
"""
|
"""
|
||||||
The main function which parses command line options and then runs
|
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'{br}', u'\n')
|
text = text.replace(u'{br}', u'\n')
|
||||||
text = text.replace(u' ', u' ')
|
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'start tag'], u'')
|
||||||
text = text.replace(tag[u'end tag'], u'')
|
text = text.replace(tag[u'end tag'], u'')
|
||||||
return text
|
return text
|
||||||
@ -214,7 +214,7 @@ def expand_tags(text):
|
|||||||
"""
|
"""
|
||||||
Expand tags HTML for display
|
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'start tag'], tag[u'start html'])
|
||||||
text = text.replace(tag[u'end tag'], tag[u'end html'])
|
text = text.replace(tag[u'end tag'], tag[u'end html'])
|
||||||
return text
|
return text
|
||||||
@ -233,9 +233,9 @@ def check_directory_exists(dir):
|
|||||||
except IOError:
|
except IOError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
from listwidgetwithdnd import ListWidgetWithDnD
|
|
||||||
from displaytags import DisplayTags
|
|
||||||
from eventreceiver import Receiver
|
from eventreceiver import Receiver
|
||||||
|
from listwidgetwithdnd import ListWidgetWithDnD
|
||||||
|
from formattingtags import FormattingTags
|
||||||
from spelltextedit import SpellTextEdit
|
from spelltextedit import SpellTextEdit
|
||||||
from settingsmanager import SettingsManager
|
from settingsmanager import SettingsManager
|
||||||
from plugin import PluginStatus, StringContent, Plugin
|
from plugin import PluginStatus, StringContent, Plugin
|
||||||
|
@ -25,12 +25,12 @@
|
|||||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
# 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
|
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
|
Static Class to HTML Tags to be access around the code the list is managed
|
||||||
by the Options Tab.
|
by the Options Tab.
|
||||||
@ -42,89 +42,93 @@ class DisplayTags(object):
|
|||||||
"""
|
"""
|
||||||
Provide access to the html_expands list.
|
Provide access to the html_expands list.
|
||||||
"""
|
"""
|
||||||
return DisplayTags.html_expands
|
return FormattingTags.html_expands
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def reset_html_tags():
|
def reset_html_tags():
|
||||||
"""
|
"""
|
||||||
Resets the html_expands list.
|
Resets the html_expands list.
|
||||||
"""
|
"""
|
||||||
DisplayTags.html_expands = []
|
FormattingTags.html_expands = []
|
||||||
base_tags = []
|
base_tags = []
|
||||||
# Append the base tags.
|
# Append the base tags.
|
||||||
# Hex Color tags from http://www.w3schools.com/html/html_colornames.asp
|
# 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 tag': u'{r}',
|
||||||
u'start html': u'<span style="-webkit-text-fill-color:red">',
|
u'start html': u'<span style="-webkit-text-fill-color:red">',
|
||||||
u'end tag': u'{/r}', u'end html': u'</span>', u'protected': True})
|
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 tag': u'{b}',
|
||||||
u'start html': u'<span style="-webkit-text-fill-color:black">',
|
u'start html': u'<span style="-webkit-text-fill-color:black">',
|
||||||
u'end tag': u'{/b}', u'end html': u'</span>', u'protected': True})
|
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 tag': u'{bl}',
|
||||||
u'start html': u'<span style="-webkit-text-fill-color:blue">',
|
u'start html': u'<span style="-webkit-text-fill-color:blue">',
|
||||||
u'end tag': u'{/bl}', u'end html': u'</span>', u'protected': True})
|
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 tag': u'{y}',
|
||||||
u'start html': u'<span style="-webkit-text-fill-color:yellow">',
|
u'start html': u'<span style="-webkit-text-fill-color:yellow">',
|
||||||
u'end tag': u'{/y}', u'end html': u'</span>', u'protected': True})
|
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 tag': u'{g}',
|
||||||
u'start html': u'<span style="-webkit-text-fill-color:green">',
|
u'start html': u'<span style="-webkit-text-fill-color:green">',
|
||||||
u'end tag': u'{/g}', u'end html': u'</span>', u'protected': True})
|
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 tag': u'{pk}',
|
||||||
u'start html': u'<span style="-webkit-text-fill-color:#FFC0CB">',
|
u'start html': u'<span style="-webkit-text-fill-color:#FFC0CB">',
|
||||||
u'end tag': u'{/pk}', u'end html': u'</span>', u'protected': True})
|
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 tag': u'{o}',
|
||||||
u'start html': u'<span style="-webkit-text-fill-color:#FFA500">',
|
u'start html': u'<span style="-webkit-text-fill-color:#FFA500">',
|
||||||
u'end tag': u'{/o}', u'end html': u'</span>', u'protected': True})
|
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 tag': u'{pp}',
|
||||||
u'start html': u'<span style="-webkit-text-fill-color:#800080">',
|
u'start html': u'<span style="-webkit-text-fill-color:#800080">',
|
||||||
u'end tag': u'{/pp}', u'end html': u'</span>', u'protected': True})
|
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 tag': u'{w}',
|
||||||
u'start html': u'<span style="-webkit-text-fill-color:white">',
|
u'start html': u'<span style="-webkit-text-fill-color:white">',
|
||||||
u'end tag': u'{/w}', u'end html': u'</span>', u'protected': True})
|
u'end tag': u'{/w}', u'end html': u'</span>', u'protected': True})
|
||||||
base_tags.append({
|
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'start tag': u'{su}', u'start html': u'<sup>',
|
||||||
u'end tag': u'{/su}', u'end html': u'</sup>', u'protected': True})
|
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'start tag': u'{sb}', u'start html': u'<sub>',
|
||||||
u'end tag': u'{/sb}', u'end html': u'</sub>', u'protected': True})
|
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'start tag': u'{p}', u'start html': u'<p>', u'end tag': u'{/p}',
|
||||||
u'end html': u'</p>', u'protected': True})
|
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'start tag': u'{st}', u'start html': u'<strong>',
|
||||||
u'end tag': u'{/st}', u'end html': u'</strong>',
|
u'end tag': u'{/st}', u'end html': u'</strong>',
|
||||||
u'protected': True})
|
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'start tag': u'{it}', u'start html': u'<em>', u'end tag': u'{/it}',
|
||||||
u'end html': u'</em>', u'protected': True})
|
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 tag': u'{u}',
|
||||||
u'start html': u'<span style="text-decoration: underline;">',
|
u'start html': u'<span style="text-decoration: underline;">',
|
||||||
u'end tag': u'{/u}', u'end html': u'</span>', u'protected': True})
|
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'start tag': u'{br}', u'start html': u'<br>', u'end tag': u'',
|
||||||
u'end html': u'', u'protected': True})
|
u'end html': u'', u'protected': True})
|
||||||
DisplayTags.add_html_tags(base_tags)
|
FormattingTags.add_html_tags(base_tags)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def add_html_tags(tags):
|
def add_html_tags(tags):
|
||||||
"""
|
"""
|
||||||
Add a list of tags to the list
|
Add a list of tags to the list
|
||||||
"""
|
"""
|
||||||
DisplayTags.html_expands.extend(tags)
|
FormattingTags.html_expands.extend(tags)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def remove_html_tag(tag_id):
|
def remove_html_tag(tag_id):
|
||||||
"""
|
"""
|
||||||
Removes an individual html_expands tag.
|
Removes an individual html_expands tag.
|
||||||
"""
|
"""
|
||||||
DisplayTags.html_expands.pop(tag_id)
|
FormattingTags.html_expands.pop(tag_id)
|
@ -34,6 +34,7 @@ from openlp.core.lib.theme import BackgroundType, BackgroundGradientType, \
|
|||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
# FIXME: Add html5 doctype. However, do not break theme gradients.
|
||||||
HTMLSRC = u"""
|
HTMLSRC = u"""
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
@ -56,44 +57,44 @@ body {
|
|||||||
height: %spx;
|
height: %spx;
|
||||||
}
|
}
|
||||||
#black {
|
#black {
|
||||||
z-index:8;
|
z-index: 8;
|
||||||
background-color: black;
|
background-color: black;
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
#bgimage {
|
#bgimage {
|
||||||
z-index:1;
|
z-index: 1;
|
||||||
}
|
}
|
||||||
#image {
|
#image {
|
||||||
z-index:2;
|
z-index: 2;
|
||||||
}
|
}
|
||||||
#video1 {
|
#video1 {
|
||||||
z-index:3;
|
z-index: 3;
|
||||||
}
|
}
|
||||||
#video2 {
|
#video2 {
|
||||||
z-index:3;
|
z-index: 3;
|
||||||
}
|
}
|
||||||
#alert {
|
#alert {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 0px;
|
left: 0px;
|
||||||
top: 0px;
|
top: 0px;
|
||||||
z-index:10;
|
z-index: 10;
|
||||||
%s
|
%s
|
||||||
}
|
}
|
||||||
#footer {
|
#footer {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index:6;
|
z-index: 6;
|
||||||
%s
|
%s
|
||||||
}
|
}
|
||||||
/* lyric css */
|
/* lyric css */
|
||||||
%s
|
%s
|
||||||
sup {
|
sup {
|
||||||
font-size:0.6em;
|
font-size: 0.6em;
|
||||||
vertical-align:top;
|
vertical-align: top;
|
||||||
position:relative;
|
position: relative;
|
||||||
top:-0.3em;
|
top: -0.3em;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<script language="javascript">
|
<script>
|
||||||
var timer = null;
|
var timer = null;
|
||||||
var video_timer = null;
|
var video_timer = null;
|
||||||
var current_video = '1';
|
var current_video = '1';
|
||||||
@ -317,10 +318,10 @@ sup {
|
|||||||
%s
|
%s
|
||||||
<div id="footer" class="footer"></div>
|
<div id="footer" class="footer"></div>
|
||||||
<div id="black" class="size"></div>
|
<div id="black" class="size"></div>
|
||||||
<div id="alert" style="visibility:hidden;"></div>
|
<div id="alert" style="visibility:hidden"></div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def build_html(item, screen, alert, islive, background, image=None):
|
def build_html(item, screen, alert, islive, background, image=None):
|
||||||
"""
|
"""
|
||||||
@ -446,15 +447,15 @@ def build_lyrics_css(item, webkitvers):
|
|||||||
The version of qtwebkit we're using
|
The version of qtwebkit we're using
|
||||||
|
|
||||||
"""
|
"""
|
||||||
style = """
|
style = u"""
|
||||||
.lyricstable {
|
.lyricstable {
|
||||||
z-index:5;
|
z-index: 5;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
display: table;
|
display: table;
|
||||||
%s
|
%s
|
||||||
}
|
}
|
||||||
.lyricscell {
|
.lyricscell {
|
||||||
display:table-cell;
|
display: table-cell;
|
||||||
word-wrap: break-word;
|
word-wrap: break-word;
|
||||||
%s
|
%s
|
||||||
}
|
}
|
||||||
@ -558,8 +559,8 @@ def build_lyrics_format_css(theme, width, height):
|
|||||||
left_margin = 0
|
left_margin = 0
|
||||||
lyrics = u'white-space:pre-wrap; word-wrap: break-word; ' \
|
lyrics = u'white-space:pre-wrap; word-wrap: break-word; ' \
|
||||||
'text-align: %s; vertical-align: %s; font-family: %s; ' \
|
'text-align: %s; vertical-align: %s; font-family: %s; ' \
|
||||||
'font-size: %spt; color: %s; line-height: %d%%; margin:0;' \
|
'font-size: %spt; color: %s; line-height: %d%%; margin: 0;' \
|
||||||
'padding:0; padding-left:%spx; width: %spx; height: %spx; ' % \
|
'padding: 0; padding-left: %spx; width: %spx; height: %spx; ' % \
|
||||||
(align, valign, theme.font_main_name, theme.font_main_size,
|
(align, valign, theme.font_main_name, theme.font_main_size,
|
||||||
theme.font_main_color, 100 + int(theme.font_main_line_adjustment),
|
theme.font_main_color, 100 + int(theme.font_main_line_adjustment),
|
||||||
left_margin, width, height)
|
left_margin, width, height)
|
||||||
@ -608,7 +609,7 @@ def build_footer_css(item, height):
|
|||||||
``item``
|
``item``
|
||||||
Service Item to be processed.
|
Service Item to be processed.
|
||||||
"""
|
"""
|
||||||
style = """
|
style = u"""
|
||||||
left: %spx;
|
left: %spx;
|
||||||
bottom: %spx;
|
bottom: %spx;
|
||||||
width: %spx;
|
width: %spx;
|
||||||
@ -616,7 +617,7 @@ def build_footer_css(item, height):
|
|||||||
font-size: %spt;
|
font-size: %spt;
|
||||||
color: %s;
|
color: %s;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
white-space:nowrap;
|
white-space: nowrap;
|
||||||
"""
|
"""
|
||||||
theme = item.themedata
|
theme = item.themedata
|
||||||
if not theme or not item.footer:
|
if not theme or not item.footer:
|
||||||
@ -634,7 +635,7 @@ def build_alert_css(alertTab, width):
|
|||||||
``alertTab``
|
``alertTab``
|
||||||
Details from the Alert tab for fonts etc
|
Details from the Alert tab for fonts etc
|
||||||
"""
|
"""
|
||||||
style = """
|
style = u"""
|
||||||
width: %spx;
|
width: %spx;
|
||||||
vertical-align: %s;
|
vertical-align: %s;
|
||||||
font-family: %s;
|
font-family: %s;
|
||||||
|
@ -27,8 +27,12 @@
|
|||||||
"""
|
"""
|
||||||
Extend QListWidget to handle drag and drop functionality
|
Extend QListWidget to handle drag and drop functionality
|
||||||
"""
|
"""
|
||||||
|
import os.path
|
||||||
|
|
||||||
from PyQt4 import QtCore, QtGui
|
from PyQt4 import QtCore, QtGui
|
||||||
|
|
||||||
|
from openlp.core.lib import Receiver
|
||||||
|
|
||||||
class ListWidgetWithDnD(QtGui.QListWidget):
|
class ListWidgetWithDnD(QtGui.QListWidget):
|
||||||
"""
|
"""
|
||||||
Provide a list widget to store objects and handle drag and drop events
|
Provide a list widget to store objects and handle drag and drop events
|
||||||
@ -41,6 +45,16 @@ class ListWidgetWithDnD(QtGui.QListWidget):
|
|||||||
self.mimeDataText = name
|
self.mimeDataText = name
|
||||||
assert(self.mimeDataText)
|
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):
|
def mouseMoveEvent(self, event):
|
||||||
"""
|
"""
|
||||||
Drag and drop event does not care what data is selected
|
Drag and drop event does not care what data is selected
|
||||||
@ -58,3 +72,39 @@ class ListWidgetWithDnD(QtGui.QListWidget):
|
|||||||
drag.setMimeData(mimeData)
|
drag.setMimeData(mimeData)
|
||||||
mimeData.setText(self.mimeDataText)
|
mimeData.setText(self.mimeDataText)
|
||||||
drag.start(QtCore.Qt.CopyAction)
|
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()
|
||||||
|
@ -96,7 +96,7 @@ class MediaManagerItem(QtGui.QWidget):
|
|||||||
self.plugin = plugin
|
self.plugin = plugin
|
||||||
visible_title = self.plugin.getString(StringContent.VisibleName)
|
visible_title = self.plugin.getString(StringContent.VisibleName)
|
||||||
self.title = unicode(visible_title[u'title'])
|
self.title = unicode(visible_title[u'title'])
|
||||||
self.settingsSection = self.plugin.name.lower()
|
self.settingsSection = self.plugin.name
|
||||||
self.icon = None
|
self.icon = None
|
||||||
if icon:
|
if icon:
|
||||||
self.icon = build_icon(icon)
|
self.icon = build_icon(icon)
|
||||||
@ -113,7 +113,7 @@ class MediaManagerItem(QtGui.QWidget):
|
|||||||
self.retranslateUi()
|
self.retranslateUi()
|
||||||
self.auto_select_id = -1
|
self.auto_select_id = -1
|
||||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||||
QtCore.SIGNAL(u'%s_service_load' % self.plugin.name.lower()),
|
QtCore.SIGNAL(u'%s_service_load' % self.plugin.name),
|
||||||
self.serviceLoad)
|
self.serviceLoad)
|
||||||
|
|
||||||
def requiredIcons(self):
|
def requiredIcons(self):
|
||||||
@ -252,7 +252,6 @@ class MediaManagerItem(QtGui.QWidget):
|
|||||||
self.listView.setSelectionMode(
|
self.listView.setSelectionMode(
|
||||||
QtGui.QAbstractItemView.ExtendedSelection)
|
QtGui.QAbstractItemView.ExtendedSelection)
|
||||||
self.listView.setAlternatingRowColors(True)
|
self.listView.setAlternatingRowColors(True)
|
||||||
self.listView.setDragEnabled(True)
|
|
||||||
self.listView.setObjectName(u'%sListView' % self.plugin.name)
|
self.listView.setObjectName(u'%sListView' % self.plugin.name)
|
||||||
# Add to pageLayout
|
# Add to pageLayout
|
||||||
self.pageLayout.addWidget(self.listView)
|
self.pageLayout.addWidget(self.listView)
|
||||||
@ -339,26 +338,65 @@ class MediaManagerItem(QtGui.QWidget):
|
|||||||
log.info(u'New files(s) %s', unicode(files))
|
log.info(u'New files(s) %s', unicode(files))
|
||||||
if files:
|
if files:
|
||||||
Receiver.send_message(u'cursor_busy')
|
Receiver.send_message(u'cursor_busy')
|
||||||
names = []
|
self.validateAndLoad(files)
|
||||||
for count in range(0, self.listView.count()):
|
Receiver.send_message(u'cursor_normal')
|
||||||
names.append(self.listView.item(count).text())
|
|
||||||
newFiles = []
|
def loadFile(self, files):
|
||||||
for file in files:
|
"""
|
||||||
filename = os.path.split(unicode(file))[1]
|
Turn file from Drag and Drop into an array so the Validate code
|
||||||
if filename in names:
|
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(
|
critical_error_message_box(
|
||||||
UiStrings().Duplicate,
|
translate('OpenLP.MediaManagerItem',
|
||||||
|
'Invalid File Type'),
|
||||||
unicode(translate('OpenLP.MediaManagerItem',
|
unicode(translate('OpenLP.MediaManagerItem',
|
||||||
'Duplicate filename %s.\nThis filename is already in '
|
'Invalid File %s.\nSuffix not supported'))
|
||||||
'the list')) % filename)
|
% file)
|
||||||
else:
|
errorShown = True
|
||||||
newFiles.append(file)
|
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)
|
self.loadList(newFiles)
|
||||||
lastDir = os.path.split(unicode(files[0]))[0]
|
lastDir = os.path.split(unicode(files[0]))[0]
|
||||||
SettingsManager.set_last_dir(self.settingsSection, lastDir)
|
SettingsManager.set_last_dir(self.settingsSection, lastDir)
|
||||||
SettingsManager.set_list(self.settingsSection,
|
SettingsManager.set_list(self.settingsSection,
|
||||||
self.settingsSection, self.getFileList())
|
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):
|
def contextMenu(self, point):
|
||||||
item = self.listView.itemAt(point)
|
item = self.listView.itemAt(point)
|
||||||
@ -558,7 +596,7 @@ class MediaManagerItem(QtGui.QWidget):
|
|||||||
QtGui.QMessageBox.information(self, UiStrings().NISs,
|
QtGui.QMessageBox.information(self, UiStrings().NISs,
|
||||||
translate('OpenLP.MediaManagerItem',
|
translate('OpenLP.MediaManagerItem',
|
||||||
'You must select an existing service item to add to.'))
|
'You must select an existing service item to add to.'))
|
||||||
elif self.plugin.name.lower() == serviceItem.name.lower():
|
elif self.plugin.name == serviceItem.name:
|
||||||
self.generateSlideData(serviceItem)
|
self.generateSlideData(serviceItem)
|
||||||
self.plugin.serviceManager.addServiceItem(serviceItem,
|
self.plugin.serviceManager.addServiceItem(serviceItem,
|
||||||
replace=True)
|
replace=True)
|
||||||
|
@ -152,7 +152,7 @@ class Plugin(QtCore.QObject):
|
|||||||
self.version = version
|
self.version = version
|
||||||
else:
|
else:
|
||||||
self.version = get_application_version()[u'version']
|
self.version = get_application_version()[u'version']
|
||||||
self.settingsSection = self.name.lower()
|
self.settingsSection = self.name
|
||||||
self.icon = None
|
self.icon = None
|
||||||
self.media_item_class = media_item_class
|
self.media_item_class = media_item_class
|
||||||
self.settings_tab_class = settings_tab_class
|
self.settings_tab_class = settings_tab_class
|
||||||
|
@ -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'
|
'r{/pk}{o}e{/o}{pp}n{/pp} of the Lord\n'
|
||||||
FOOTER = [u'Arky Arky (Unknown)', u'Public Domain', u'CCLI 123456']
|
FOOTER = [u'Arky Arky (Unknown)', u'Public Domain', u'CCLI 123456']
|
||||||
|
|
||||||
HTML_END = u'</div></body></html>'
|
|
||||||
|
|
||||||
class Renderer(object):
|
class Renderer(object):
|
||||||
"""
|
"""
|
||||||
Class to pull all Renderer interactions into one place. The plugins will
|
Class to pull all Renderer interactions into one place. The plugins will
|
||||||
@ -56,20 +54,20 @@ class Renderer(object):
|
|||||||
"""
|
"""
|
||||||
log.info(u'Renderer Loaded')
|
log.info(u'Renderer Loaded')
|
||||||
|
|
||||||
def __init__(self, image_manager, theme_manager):
|
def __init__(self, imageManager, themeManager):
|
||||||
"""
|
"""
|
||||||
Initialise the render manager.
|
Initialise the render manager.
|
||||||
|
|
||||||
``image_manager``
|
``imageManager``
|
||||||
A ImageManager instance which takes care of e. g. caching and resizing
|
A ImageManager instance which takes care of e. g. caching and resizing
|
||||||
images.
|
images.
|
||||||
|
|
||||||
``theme_manager``
|
``themeManager``
|
||||||
The ThemeManager instance, used to get the current theme details.
|
The ThemeManager instance, used to get the current theme details.
|
||||||
"""
|
"""
|
||||||
log.debug(u'Initialisation started')
|
log.debug(u'Initialisation started')
|
||||||
self.theme_manager = theme_manager
|
self.themeManager = themeManager
|
||||||
self.image_manager = image_manager
|
self.imageManager = imageManager
|
||||||
self.screens = ScreenList.get_instance()
|
self.screens = ScreenList.get_instance()
|
||||||
self.service_theme = u''
|
self.service_theme = u''
|
||||||
self.theme_level = u''
|
self.theme_level = u''
|
||||||
@ -77,7 +75,7 @@ class Renderer(object):
|
|||||||
self.theme_data = None
|
self.theme_data = None
|
||||||
self.bg_frame = None
|
self.bg_frame = None
|
||||||
self.force_page = False
|
self.force_page = False
|
||||||
self.display = MainDisplay(None, self.image_manager, False)
|
self.display = MainDisplay(None, self.imageManager, False)
|
||||||
self.display.setup()
|
self.display.setup()
|
||||||
|
|
||||||
def update_display(self):
|
def update_display(self):
|
||||||
@ -85,10 +83,10 @@ class Renderer(object):
|
|||||||
Updates the render manager's information about the current screen.
|
Updates the render manager's information about the current screen.
|
||||||
"""
|
"""
|
||||||
log.debug(u'Update Display')
|
log.debug(u'Update Display')
|
||||||
self._calculate_default(self.screens.current[u'size'])
|
self._calculate_default()
|
||||||
if self.display:
|
if self.display:
|
||||||
self.display.close()
|
self.display.close()
|
||||||
self.display = MainDisplay(None, self.image_manager, False)
|
self.display = MainDisplay(None, self.imageManager, False)
|
||||||
self.display.setup()
|
self.display.setup()
|
||||||
self.bg_frame = None
|
self.bg_frame = None
|
||||||
self.theme_data = None
|
self.theme_data = None
|
||||||
@ -101,14 +99,14 @@ class Renderer(object):
|
|||||||
The global-level theme to be set.
|
The global-level theme to be set.
|
||||||
|
|
||||||
``theme_level``
|
``theme_level``
|
||||||
Defaults to *``ThemeLevel.Global``*. The theme level, can be
|
Defaults to ``ThemeLevel.Global``. The theme level, can be
|
||||||
``ThemeLevel.Global``, ``ThemeLevel.Service`` or
|
``ThemeLevel.Global``, ``ThemeLevel.Service`` or
|
||||||
``ThemeLevel.Song``.
|
``ThemeLevel.Song``.
|
||||||
"""
|
"""
|
||||||
self.global_theme = global_theme
|
self.global_theme = global_theme
|
||||||
self.theme_level = theme_level
|
self.theme_level = theme_level
|
||||||
self.global_theme_data = \
|
self.global_theme_data = \
|
||||||
self.theme_manager.getThemeData(self.global_theme)
|
self.themeManager.getThemeData(self.global_theme)
|
||||||
self.theme_data = None
|
self.theme_data = None
|
||||||
|
|
||||||
def set_service_theme(self, service_theme):
|
def set_service_theme(self, service_theme):
|
||||||
@ -162,12 +160,12 @@ class Renderer(object):
|
|||||||
if override_levels:
|
if override_levels:
|
||||||
self.theme_data = override_theme
|
self.theme_data = override_theme
|
||||||
else:
|
else:
|
||||||
self.theme_data = self.theme_manager.getThemeData(theme)
|
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)
|
self._build_text_rectangle(self.theme_data)
|
||||||
# if No file do not update cache
|
# if No file do not update cache
|
||||||
if self.theme_data.background_filename:
|
if self.theme_data.background_filename:
|
||||||
self.image_manager.add_image(self.theme_data.theme_name,
|
self.imageManager.add_image(self.theme_data.theme_name,
|
||||||
self.theme_data.background_filename)
|
self.theme_data.background_filename)
|
||||||
return self._rect, self._rect_footer
|
return self._rect, self._rect_footer
|
||||||
|
|
||||||
@ -185,7 +183,7 @@ class Renderer(object):
|
|||||||
# save value for use in format_slide
|
# save value for use in format_slide
|
||||||
self.force_page = force_page
|
self.force_page = force_page
|
||||||
# set the default image size for previews
|
# 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
|
# build a service item to generate preview
|
||||||
serviceItem = ServiceItem()
|
serviceItem = ServiceItem()
|
||||||
serviceItem.theme = theme_data
|
serviceItem.theme = theme_data
|
||||||
@ -193,7 +191,7 @@ class Renderer(object):
|
|||||||
# make big page for theme edit dialog to get line count
|
# make big page for theme edit dialog to get line count
|
||||||
serviceItem.add_from_text(u'', VERSE + VERSE + VERSE)
|
serviceItem.add_from_text(u'', VERSE + VERSE + VERSE)
|
||||||
else:
|
else:
|
||||||
self.image_manager.del_image(theme_data.theme_name)
|
self.imageManager.del_image(theme_data.theme_name)
|
||||||
serviceItem.add_from_text(u'', VERSE)
|
serviceItem.add_from_text(u'', VERSE)
|
||||||
serviceItem.renderer = self
|
serviceItem.renderer = self
|
||||||
serviceItem.raw_footer = FOOTER
|
serviceItem.raw_footer = FOOTER
|
||||||
@ -203,52 +201,58 @@ class Renderer(object):
|
|||||||
raw_html = serviceItem.get_rendered_frame(0)
|
raw_html = serviceItem.get_rendered_frame(0)
|
||||||
preview = self.display.text(raw_html)
|
preview = self.display.text(raw_html)
|
||||||
# Reset the real screen size for subsequent render requests
|
# Reset the real screen size for subsequent render requests
|
||||||
self._calculate_default(self.screens.current[u'size'])
|
self._calculate_default()
|
||||||
return preview
|
return preview
|
||||||
|
self.force_page = False
|
||||||
|
|
||||||
def format_slide(self, text, line_break, item):
|
def format_slide(self, text, item):
|
||||||
"""
|
"""
|
||||||
Calculate how much text can fit on a slide.
|
Calculate how much text can fit on a slide.
|
||||||
|
|
||||||
``text``
|
``text``
|
||||||
The words to go on the slides.
|
The words to go on the slides.
|
||||||
|
|
||||||
``line_break``
|
``item``
|
||||||
Add line endings after each line of text used for bibles.
|
The :class:`~openlp.core.lib.serviceitem.ServiceItem` item object.
|
||||||
"""
|
"""
|
||||||
log.debug(u'format slide')
|
log.debug(u'format slide')
|
||||||
# clean up line endings
|
# Add line endings after each line of text used for bibles.
|
||||||
lines = self._lines_split(text)
|
line_end = u'<br>'
|
||||||
pages = self._paginate_slide(lines, line_break, self.force_page)
|
if item.is_capable(ItemCapabilities.NoLineBreaks):
|
||||||
if len(pages) > 1:
|
line_end = u' '
|
||||||
# Songs and Custom
|
# Bibles
|
||||||
if item.is_capable(ItemCapabilities.AllowsVirtualSplit):
|
if item.is_capable(ItemCapabilities.AllowsWordSplit):
|
||||||
# Do not forget the line breaks !
|
pages = self._paginate_slide_words(text.split(u'\n'), line_end)
|
||||||
slides = text.split(u'[---]')
|
else:
|
||||||
pages = []
|
# Clean up line endings.
|
||||||
for slide in slides:
|
lines = self._lines_split(text)
|
||||||
lines = slide.strip(u'\n').split(u'\n')
|
pages = self._paginate_slide(lines, line_end)
|
||||||
new_pages = self._paginate_slide(lines, line_break,
|
if len(pages) > 1:
|
||||||
self.force_page)
|
# Songs and Custom
|
||||||
pages.extend(new_pages)
|
if item.is_capable(ItemCapabilities.AllowsVirtualSplit):
|
||||||
# Bibles
|
# Do not forget the line breaks!
|
||||||
elif item.is_capable(ItemCapabilities.AllowsWordSplit):
|
slides = text.split(u'[---]')
|
||||||
pages = self._paginate_slide_words(text, line_break)
|
pages = []
|
||||||
return pages
|
for slide in slides:
|
||||||
|
lines = slide.strip(u'\n').split(u'\n')
|
||||||
|
pages.extend(self._paginate_slide(lines, line_end))
|
||||||
|
new_pages = []
|
||||||
|
for page in pages:
|
||||||
|
while page.endswith(u'<br>'):
|
||||||
|
page = page[:-4]
|
||||||
|
new_pages.append(page)
|
||||||
|
return new_pages
|
||||||
|
|
||||||
def _calculate_default(self, screen):
|
def _calculate_default(self):
|
||||||
"""
|
"""
|
||||||
Calculate the default dimentions of the screen.
|
Calculate the default dimentions of the screen.
|
||||||
|
|
||||||
``screen``
|
|
||||||
The QSize of the screen.
|
|
||||||
"""
|
"""
|
||||||
log.debug(u'_calculate default %s', screen)
|
screen_size = self.screens.current[u'size']
|
||||||
self.width = screen.width()
|
self.width = screen_size.width()
|
||||||
self.height = screen.height()
|
self.height = screen_size.height()
|
||||||
self.screen_ratio = float(self.height) / float(self.width)
|
self.screen_ratio = float(self.height) / float(self.width)
|
||||||
log.debug(u'calculate default %d, %d, %f',
|
log.debug(u'_calculate default %s, %f' % (screen_size,
|
||||||
self.width, self.height, self.screen_ratio)
|
self.screen_ratio))
|
||||||
# 90% is start of footer
|
# 90% is start of footer
|
||||||
self.footer_start = int(self.height * 0.90)
|
self.footer_start = int(self.height * 0.90)
|
||||||
|
|
||||||
@ -301,177 +305,202 @@ class Renderer(object):
|
|||||||
self.web.resize(self.page_width, self.page_height)
|
self.web.resize(self.page_width, self.page_height)
|
||||||
self.web_frame = self.web.page().mainFrame()
|
self.web_frame = self.web.page().mainFrame()
|
||||||
# Adjust width and height to account for shadow. outline done in css
|
# Adjust width and height to account for shadow. outline done in css
|
||||||
self.page_shell = u'<html><head><style>' \
|
html = u"""<!DOCTYPE html><html><head><script>
|
||||||
u'*{margin: 0; padding: 0; border: 0;} '\
|
function show_text(newtext) {
|
||||||
u'#main {position:absolute; top:0px; %s %s}</style></head><body>' \
|
var main = document.getElementById('main');
|
||||||
u'<div id="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,
|
(build_lyrics_format_css(self.theme_data, self.page_width,
|
||||||
self.page_height), build_lyrics_outline_css(self.theme_data))
|
self.page_height), build_lyrics_outline_css(self.theme_data))
|
||||||
|
self.web.setHtml(html)
|
||||||
|
|
||||||
def _paginate_slide(self, lines, line_break, force_page=False):
|
def _paginate_slide(self, lines, line_end):
|
||||||
"""
|
"""
|
||||||
Figure out how much text can appear on a slide, using the current
|
Figure out how much text can appear on a slide, using the current
|
||||||
theme settings.
|
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``
|
``lines``
|
||||||
The words to be fitted on the slide split into lines.
|
The text to be fitted on the slide split into lines.
|
||||||
|
|
||||||
``line_break``
|
|
||||||
Add line endings after each line of text (used for bibles).
|
|
||||||
|
|
||||||
``force_page``
|
|
||||||
Flag to tell message lines in page.
|
|
||||||
|
|
||||||
|
``line_end``
|
||||||
|
The text added after each line. Either ``u' '`` or ``u'<br>``.
|
||||||
"""
|
"""
|
||||||
log.debug(u'_paginate_slide - Start')
|
log.debug(u'_paginate_slide - Start')
|
||||||
line_end = u''
|
|
||||||
if line_break:
|
|
||||||
line_end = u'<br>'
|
|
||||||
formatted = []
|
|
||||||
html_text = u''
|
|
||||||
styled_text = u''
|
|
||||||
line_count = 0
|
|
||||||
for line in lines:
|
|
||||||
if line_count != -1:
|
|
||||||
line_count += 1
|
|
||||||
styled_line = expand_tags(line) + line_end
|
|
||||||
styled_text += styled_line
|
|
||||||
html = self.page_shell + styled_text + HTML_END
|
|
||||||
self.web.setHtml(html)
|
|
||||||
# Text too long so go to next page.
|
|
||||||
if self.web_frame.contentsSize().height() > self.page_height:
|
|
||||||
if force_page and line_count > 0:
|
|
||||||
Receiver.send_message(u'theme_line_count', line_count - 1)
|
|
||||||
line_count = -1
|
|
||||||
while html_text.endswith(u'<br>'):
|
|
||||||
html_text = html_text[:-4]
|
|
||||||
formatted.append(html_text)
|
|
||||||
html_text = u''
|
|
||||||
styled_text = styled_line
|
|
||||||
html_text += line + line_end
|
|
||||||
while html_text.endswith(u'<br>'):
|
|
||||||
html_text = html_text[:-4]
|
|
||||||
formatted.append(html_text)
|
|
||||||
log.debug(u'_paginate_slide - End')
|
|
||||||
return formatted
|
|
||||||
|
|
||||||
def _paginate_slide_words(self, text, line_break):
|
|
||||||
"""
|
|
||||||
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.
|
|
||||||
|
|
||||||
``text``
|
|
||||||
The words to be fitted on the slide split into lines.
|
|
||||||
|
|
||||||
``line_break``
|
|
||||||
Add line endings after each line of text used for bibles.
|
|
||||||
|
|
||||||
"""
|
|
||||||
log.debug(u'_paginate_slide_words - Start')
|
|
||||||
line_end = u' '
|
|
||||||
if line_break:
|
|
||||||
line_end = u'<br>'
|
|
||||||
formatted = []
|
formatted = []
|
||||||
previous_html = u''
|
previous_html = u''
|
||||||
previous_raw = u''
|
previous_raw = u''
|
||||||
lines = text.split(u'\n')
|
separator = u'<br>'
|
||||||
|
html_lines = map(expand_tags, lines)
|
||||||
|
# Text too long so go to next page.
|
||||||
|
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:
|
||||||
|
previous_raw = separator.join(lines)
|
||||||
|
if previous_raw:
|
||||||
|
formatted.append(previous_raw)
|
||||||
|
log.debug(u'_paginate_slide - End')
|
||||||
|
return formatted
|
||||||
|
|
||||||
|
def _paginate_slide_words(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 word.
|
||||||
|
If one line is too long it will be processed word by word. This is
|
||||||
|
sometimes need for **bible** verses.
|
||||||
|
|
||||||
|
``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**.
|
||||||
|
"""
|
||||||
|
log.debug(u'_paginate_slide_words - Start')
|
||||||
|
formatted = []
|
||||||
|
previous_html = u''
|
||||||
|
previous_raw = u''
|
||||||
for line in lines:
|
for line in lines:
|
||||||
line = line.strip()
|
line = line.strip()
|
||||||
styled_line = expand_tags(line)
|
html_line = expand_tags(line)
|
||||||
html = self.page_shell + previous_html + styled_line + HTML_END
|
|
||||||
self.web.setHtml(html)
|
|
||||||
# Text too long so go to next page.
|
# 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
|
# Check if there was a verse before the current one and append
|
||||||
# it, when it fits on the page.
|
# it, when it fits on the page.
|
||||||
if previous_html:
|
if previous_html:
|
||||||
html = self.page_shell + previous_html + HTML_END
|
if not self._text_fits_on_slide(previous_html):
|
||||||
self.web.setHtml(html)
|
|
||||||
if self.web_frame.contentsSize().height() <= \
|
|
||||||
self.page_height:
|
|
||||||
while previous_raw.endswith(u'<br>'):
|
|
||||||
previous_raw = previous_raw[:-4]
|
|
||||||
formatted.append(previous_raw)
|
formatted.append(previous_raw)
|
||||||
previous_html = u''
|
previous_html = u''
|
||||||
previous_raw = u''
|
previous_raw = u''
|
||||||
html = self.page_shell + styled_line + HTML_END
|
|
||||||
self.web.setHtml(html)
|
|
||||||
# Now check if the current verse will fit, if it does
|
# Now check if the current verse will fit, if it does
|
||||||
# not we have to start to process the verse word by
|
# not we have to start to process the verse word by
|
||||||
# word.
|
# word.
|
||||||
if self.web_frame.contentsSize().height() <= \
|
if not self._text_fits_on_slide(html_line):
|
||||||
self.page_height:
|
previous_html = html_line + line_end
|
||||||
previous_html = styled_line + line_end
|
|
||||||
previous_raw = line + line_end
|
previous_raw = line + line_end
|
||||||
continue
|
continue
|
||||||
# Figure out how many words of the line will fit on screen by
|
# Figure out how many words of the line will fit on screen as
|
||||||
# using the algorithm known as "binary chop".
|
# the line will not fit as a whole.
|
||||||
raw_words = self._words_split(line)
|
raw_words = self._words_split(line)
|
||||||
html_words = [expand_tags(word) for word in raw_words]
|
html_words = map(expand_tags, raw_words)
|
||||||
smallest_index = 0
|
previous_html, previous_raw = self._binary_chop(
|
||||||
highest_index = len(html_words) - 1
|
formatted, previous_html, previous_raw, html_words,
|
||||||
index = int(highest_index / 2)
|
raw_words, u' ', line_end)
|
||||||
while True:
|
|
||||||
html = self.page_shell + previous_html + \
|
|
||||||
u''.join(html_words[:index + 1]).strip() + HTML_END
|
|
||||||
self.web.setHtml(html)
|
|
||||||
if self.web_frame.contentsSize().height() > \
|
|
||||||
self.page_height:
|
|
||||||
# We know that it does not fit, so change/calculate the
|
|
||||||
# new index and highest_index accordingly.
|
|
||||||
highest_index = index
|
|
||||||
index = int(index - (index - smallest_index) / 2)
|
|
||||||
else:
|
|
||||||
smallest_index = index
|
|
||||||
index = int(index + (highest_index - index) / 2)
|
|
||||||
# We found the number of words which will fit.
|
|
||||||
if smallest_index == index or highest_index == index:
|
|
||||||
index = smallest_index
|
|
||||||
formatted.append(previous_raw.rstrip(u'<br>') +
|
|
||||||
u''.join(raw_words[:index + 1]))
|
|
||||||
previous_html = u''
|
|
||||||
previous_raw = u''
|
|
||||||
else:
|
|
||||||
continue
|
|
||||||
# Check if the rest of the line fits on the slide. If it
|
|
||||||
# does we do not have to do the much more intensive "word by
|
|
||||||
# word" checking.
|
|
||||||
html = self.page_shell + \
|
|
||||||
u''.join(html_words[index + 1:]).strip() + HTML_END
|
|
||||||
self.web.setHtml(html)
|
|
||||||
if self.web_frame.contentsSize().height() <= \
|
|
||||||
self.page_height:
|
|
||||||
previous_html = \
|
|
||||||
u''.join(html_words[index + 1:]).strip() + line_end
|
|
||||||
previous_raw = \
|
|
||||||
u''.join(raw_words[index + 1:]).strip() + line_end
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
# The other words do not fit, thus reset the indexes,
|
|
||||||
# create a new list and continue with "word by word".
|
|
||||||
raw_words = raw_words[index + 1:]
|
|
||||||
html_words = html_words[index + 1:]
|
|
||||||
smallest_index = 0
|
|
||||||
highest_index = len(html_words) - 1
|
|
||||||
index = int(highest_index / 2)
|
|
||||||
else:
|
else:
|
||||||
previous_html += styled_line + line_end
|
previous_html += html_line + line_end
|
||||||
previous_raw += line + line_end
|
previous_raw += line + line_end
|
||||||
while previous_raw.endswith(u'<br>'):
|
|
||||||
previous_raw = previous_raw[:-4]
|
|
||||||
formatted.append(previous_raw)
|
formatted.append(previous_raw)
|
||||||
log.debug(u'_paginate_slide_words - End')
|
log.debug(u'_paginate_slide_words - End')
|
||||||
return formatted
|
return formatted
|
||||||
|
|
||||||
|
def _binary_chop(self, formatted, previous_html, previous_raw, html_list,
|
||||||
|
raw_list, separator, line_end):
|
||||||
|
"""
|
||||||
|
This implements the binary chop algorithm for faster rendering. This
|
||||||
|
algorithm works line based (line by line) and word based (word by word).
|
||||||
|
It is assumed that this method is **only** called, when the lines/words
|
||||||
|
to be rendered do **not** fit as a whole.
|
||||||
|
|
||||||
|
``formatted``
|
||||||
|
The list to append any slides.
|
||||||
|
|
||||||
|
``previous_html``
|
||||||
|
The html text which is know to fit on a slide, but is not yet added
|
||||||
|
to the list of slides. (unicode string)
|
||||||
|
|
||||||
|
``previous_raw``
|
||||||
|
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``
|
||||||
|
The elements which do not fit on a slide and needs to be processed
|
||||||
|
using the binary chop. The text contains html.
|
||||||
|
|
||||||
|
``raw_list``
|
||||||
|
The elements which do not fit on a slide and needs to be processed
|
||||||
|
using the binary chop. The elements can contain formatting tags.
|
||||||
|
|
||||||
|
``separator``
|
||||||
|
The separator for the elements. For lines this is ``u'<br>'`` and
|
||||||
|
for words this is ``u' '``.
|
||||||
|
|
||||||
|
``line_end``
|
||||||
|
The text added after each "element line". Either ``u' '`` or
|
||||||
|
``u'<br>``. This is needed for bibles.
|
||||||
|
"""
|
||||||
|
smallest_index = 0
|
||||||
|
highest_index = len(html_list) - 1
|
||||||
|
index = int(highest_index / 2)
|
||||||
|
while True:
|
||||||
|
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
|
||||||
|
index = int(index - (index - smallest_index) / 2)
|
||||||
|
else:
|
||||||
|
smallest_index = index
|
||||||
|
index = int(index + (highest_index - index) / 2)
|
||||||
|
# We found the number of words which will fit.
|
||||||
|
if smallest_index == index or highest_index == index:
|
||||||
|
index = smallest_index
|
||||||
|
formatted.append(previous_raw.rstrip(u'<br>') +
|
||||||
|
separator.join(raw_list[:index + 1]))
|
||||||
|
previous_html = u''
|
||||||
|
previous_raw = u''
|
||||||
|
# Stop here as the theme line count was requested.
|
||||||
|
if self.force_page:
|
||||||
|
Receiver.send_message(u'theme_line_count', index + 1)
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
continue
|
||||||
|
# Check if the remaining elements fit on the slide.
|
||||||
|
if not self._text_fits_on_slide(
|
||||||
|
separator.join(html_list[index + 1:]).strip()):
|
||||||
|
previous_html = separator.join(
|
||||||
|
html_list[index + 1:]).strip() + line_end
|
||||||
|
previous_raw = separator.join(
|
||||||
|
raw_list[index + 1:]).strip() + line_end
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
# The remaining elements do not fit, thus reset the indexes,
|
||||||
|
# create a new list and continue.
|
||||||
|
raw_list = raw_list[index + 1:]
|
||||||
|
html_list = html_list[index + 1:]
|
||||||
|
smallest_index = 0
|
||||||
|
highest_index = len(html_list) - 1
|
||||||
|
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):
|
def _words_split(self, line):
|
||||||
"""
|
"""
|
||||||
Split the slide up by word so can wrap better
|
Split the slide up by word so can wrap better
|
||||||
"""
|
"""
|
||||||
# this parse we are to be wordy
|
# this parse we are to be wordy
|
||||||
line = line.replace(u'\n', u' ')
|
line = line.replace(u'\n', u' ')
|
||||||
words = line.split(u' ')
|
return line.split(u' ')
|
||||||
return [word + u' ' for word in words]
|
|
||||||
|
|
||||||
def _lines_split(self, text):
|
def _lines_split(self, text):
|
||||||
"""
|
"""
|
||||||
@ -479,5 +508,5 @@ class Renderer(object):
|
|||||||
"""
|
"""
|
||||||
# this parse we do not want to use this so remove it
|
# this parse we do not want to use this so remove it
|
||||||
text = text.replace(u'\n[---]', u'')
|
text = text.replace(u'\n[---]', u'')
|
||||||
lines = text.split(u'\n')
|
text = text.replace(u'[---]', u'')
|
||||||
return [line.replace(u'[---]', u'') for line in lines]
|
return text.split(u'\n')
|
||||||
|
@ -164,7 +164,6 @@ class ServiceItem(object):
|
|||||||
log.debug(u'Render called')
|
log.debug(u'Render called')
|
||||||
self._display_frames = []
|
self._display_frames = []
|
||||||
self.bg_image_bytes = None
|
self.bg_image_bytes = None
|
||||||
line_break = not self.is_capable(ItemCapabilities.NoLineBreaks)
|
|
||||||
theme = self.theme if self.theme else None
|
theme = self.theme if self.theme else None
|
||||||
self.main, self.footer = \
|
self.main, self.footer = \
|
||||||
self.renderer.set_override_theme(theme, use_override)
|
self.renderer.set_override_theme(theme, use_override)
|
||||||
@ -172,9 +171,8 @@ class ServiceItem(object):
|
|||||||
if self.service_item_type == ServiceItemType.Text:
|
if self.service_item_type == ServiceItemType.Text:
|
||||||
log.debug(u'Formatting slides')
|
log.debug(u'Formatting slides')
|
||||||
for slide in self._raw_frames:
|
for slide in self._raw_frames:
|
||||||
formatted = self.renderer \
|
pages = self.renderer.format_slide(slide[u'raw_slide'], self)
|
||||||
.format_slide(slide[u'raw_slide'], line_break, self)
|
for page in pages:
|
||||||
for page in formatted:
|
|
||||||
page = page.replace(u'<br>', u'{br}')
|
page = page.replace(u'<br>', u'{br}')
|
||||||
html = expand_tags(cgi.escape(page.rstrip()))
|
html = expand_tags(cgi.escape(page.rstrip()))
|
||||||
self._display_frames.append({
|
self._display_frames.append({
|
||||||
@ -209,7 +207,7 @@ class ServiceItem(object):
|
|||||||
"""
|
"""
|
||||||
self.service_item_type = ServiceItemType.Image
|
self.service_item_type = ServiceItemType.Image
|
||||||
self._raw_frames.append({u'title': title, u'path': path})
|
self._raw_frames.append({u'title': title, u'path': path})
|
||||||
self.renderer.image_manager.add_image(title, path)
|
self.renderer.imageManager.add_image(title, path)
|
||||||
self._new_item()
|
self._new_item()
|
||||||
|
|
||||||
def add_from_text(self, title, raw_slide, verse_tag=None):
|
def add_from_text(self, title, raw_slide, verse_tag=None):
|
||||||
@ -463,7 +461,7 @@ class ServiceItem(object):
|
|||||||
elif not start and end:
|
elif not start and end:
|
||||||
return end
|
return end
|
||||||
else:
|
else:
|
||||||
return u'%s <br />%s' % (start, end)
|
return u'%s <br>%s' % (start, end)
|
||||||
|
|
||||||
def update_theme(self, theme):
|
def update_theme(self, theme):
|
||||||
"""
|
"""
|
||||||
|
@ -39,7 +39,7 @@ except ImportError:
|
|||||||
|
|
||||||
from PyQt4 import QtCore, QtGui
|
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
|
from openlp.core.lib.ui import checkable_action
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
@ -48,9 +48,10 @@ class SpellTextEdit(QtGui.QPlainTextEdit):
|
|||||||
"""
|
"""
|
||||||
Spell checking widget based on QPlanTextEdit.
|
Spell checking widget based on QPlanTextEdit.
|
||||||
"""
|
"""
|
||||||
def __init__(self, *args):
|
def __init__(self, parent=None, formattingTagsAllowed=True):
|
||||||
global ENCHANT_AVAILABLE
|
global ENCHANT_AVAILABLE
|
||||||
QtGui.QPlainTextEdit.__init__(self, *args)
|
QtGui.QPlainTextEdit.__init__(self, parent)
|
||||||
|
self.formattingTagsAllowed = formattingTagsAllowed
|
||||||
# Default dictionary based on the current locale.
|
# Default dictionary based on the current locale.
|
||||||
if ENCHANT_AVAILABLE:
|
if ENCHANT_AVAILABLE:
|
||||||
try:
|
try:
|
||||||
@ -110,16 +111,17 @@ class SpellTextEdit(QtGui.QPlainTextEdit):
|
|||||||
spell_menu.addAction(action)
|
spell_menu.addAction(action)
|
||||||
# Only add the spelling suggests to the menu if there are
|
# Only add the spelling suggests to the menu if there are
|
||||||
# suggestions.
|
# suggestions.
|
||||||
if len(spell_menu.actions()):
|
if spell_menu.actions():
|
||||||
popupMenu.insertMenu(popupMenu.actions()[0], spell_menu)
|
popupMenu.insertMenu(popupMenu.actions()[0], spell_menu)
|
||||||
tagMenu = QtGui.QMenu(translate('OpenLP.SpellTextEdit',
|
tagMenu = QtGui.QMenu(translate('OpenLP.SpellTextEdit',
|
||||||
'Formatting Tags'))
|
'Formatting Tags'))
|
||||||
for html in DisplayTags.get_html_tags():
|
if self.formattingTagsAllowed:
|
||||||
action = SpellAction(html[u'desc'], tagMenu)
|
for html in FormattingTags.get_html_tags():
|
||||||
action.correct.connect(self.htmlTag)
|
action = SpellAction(html[u'desc'], tagMenu)
|
||||||
tagMenu.addAction(action)
|
action.correct.connect(self.htmlTag)
|
||||||
popupMenu.insertSeparator(popupMenu.actions()[0])
|
tagMenu.addAction(action)
|
||||||
popupMenu.insertMenu(popupMenu.actions()[0], tagMenu)
|
popupMenu.insertSeparator(popupMenu.actions()[0])
|
||||||
|
popupMenu.insertMenu(popupMenu.actions()[0], tagMenu)
|
||||||
popupMenu.exec_(event.globalPos())
|
popupMenu.exec_(event.globalPos())
|
||||||
|
|
||||||
def setLanguage(self, action):
|
def setLanguage(self, action):
|
||||||
@ -148,7 +150,7 @@ class SpellTextEdit(QtGui.QPlainTextEdit):
|
|||||||
"""
|
"""
|
||||||
Replaces the selected text with word.
|
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']:
|
if tag == html[u'desc']:
|
||||||
cursor = self.textCursor()
|
cursor = self.textCursor()
|
||||||
if self.textCursor().hasSelection():
|
if self.textCursor().hasSelection():
|
||||||
|
@ -69,7 +69,7 @@ from advancedtab import AdvancedTab
|
|||||||
from aboutform import AboutForm
|
from aboutform import AboutForm
|
||||||
from pluginform import PluginForm
|
from pluginform import PluginForm
|
||||||
from settingsform import SettingsForm
|
from settingsform import SettingsForm
|
||||||
from displaytagform import DisplayTagForm
|
from formattingtagform import FormattingTagForm
|
||||||
from shortcutlistform import ShortcutListForm
|
from shortcutlistform import ShortcutListForm
|
||||||
from mediadockmanager import MediaDockManager
|
from mediadockmanager import MediaDockManager
|
||||||
from servicemanager import ServiceManager
|
from servicemanager import ServiceManager
|
||||||
|
@ -61,6 +61,5 @@ class AboutForm(QtGui.QDialog, Ui_AboutDialog):
|
|||||||
Launch a web browser and go to the contribute page on the site.
|
Launch a web browser and go to the contribute page on the site.
|
||||||
"""
|
"""
|
||||||
import webbrowser
|
import webbrowser
|
||||||
url = u'http://www.openlp.org/en/documentation/introduction/' \
|
url = u'http://openlp.org/en/documentation/introduction/contributing'
|
||||||
+ u'contributing.html'
|
|
||||||
webbrowser.open_new(url)
|
webbrowser.open_new(url)
|
||||||
|
@ -129,6 +129,7 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard):
|
|||||||
os.path.join(gettempdir(), u'openlp', screenshot)))
|
os.path.join(gettempdir(), u'openlp', screenshot)))
|
||||||
item.setCheckState(QtCore.Qt.Unchecked)
|
item.setCheckState(QtCore.Qt.Unchecked)
|
||||||
item.setFlags(item.flags() | QtCore.Qt.ItemIsUserCheckable)
|
item.setFlags(item.flags() | QtCore.Qt.ItemIsUserCheckable)
|
||||||
|
Receiver.send_message(u'cursor_normal')
|
||||||
|
|
||||||
def nextId(self):
|
def nextId(self):
|
||||||
"""
|
"""
|
||||||
@ -156,10 +157,27 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard):
|
|||||||
item = self.themesListWidget.item(iter)
|
item = self.themesListWidget.item(iter)
|
||||||
if item.checkState() == QtCore.Qt.Checked:
|
if item.checkState() == QtCore.Qt.Checked:
|
||||||
self.themeComboBox.addItem(item.text())
|
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:
|
elif pageId == FirstTimePage.Progress:
|
||||||
|
Receiver.send_message(u'cursor_busy')
|
||||||
self._preWizard()
|
self._preWizard()
|
||||||
self._performWizard()
|
self._performWizard()
|
||||||
self._postWizard()
|
self._postWizard()
|
||||||
|
Receiver.send_message(u'cursor_normal')
|
||||||
|
|
||||||
def updateScreenListCombo(self):
|
def updateScreenListCombo(self):
|
||||||
"""
|
"""
|
||||||
@ -248,11 +266,21 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard):
|
|||||||
"""
|
"""
|
||||||
if self.max_progress:
|
if self.max_progress:
|
||||||
self.progressBar.setValue(self.progressBar.maximum())
|
self.progressBar.setValue(self.progressBar.maximum())
|
||||||
self.progressLabel.setText(translate('OpenLP.FirstTimeWizard',
|
if self.has_run_wizard:
|
||||||
'Download complete. Click the finish button to start OpenLP.'))
|
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:
|
else:
|
||||||
self.progressLabel.setText(translate('OpenLP.FirstTimeWizard',
|
if self.has_run_wizard:
|
||||||
'Click the finish button to start OpenLP.'))
|
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.setVisible(True)
|
||||||
self.finishButton.setEnabled(True)
|
self.finishButton.setEnabled(True)
|
||||||
self.cancelButton.setVisible(False)
|
self.cancelButton.setVisible(False)
|
||||||
|
@ -30,15 +30,15 @@ from PyQt4 import QtCore, QtGui
|
|||||||
from openlp.core.lib import translate
|
from openlp.core.lib import translate
|
||||||
from openlp.core.lib.ui import UiStrings
|
from openlp.core.lib.ui import UiStrings
|
||||||
|
|
||||||
class Ui_DisplayTagDialog(object):
|
class Ui_FormattingTagDialog(object):
|
||||||
|
|
||||||
def setupUi(self, displayTagDialog):
|
def setupUi(self, formattingTagDialog):
|
||||||
displayTagDialog.setObjectName(u'displayTagDialog')
|
formattingTagDialog.setObjectName(u'formattingTagDialog')
|
||||||
displayTagDialog.resize(725, 548)
|
formattingTagDialog.resize(725, 548)
|
||||||
self.listdataGridLayout = QtGui.QGridLayout(displayTagDialog)
|
self.listdataGridLayout = QtGui.QGridLayout(formattingTagDialog)
|
||||||
self.listdataGridLayout.setMargin(8)
|
self.listdataGridLayout.setMargin(8)
|
||||||
self.listdataGridLayout.setObjectName(u'listdataGridLayout')
|
self.listdataGridLayout.setObjectName(u'listdataGridLayout')
|
||||||
self.tagTableWidget = QtGui.QTableWidget(displayTagDialog)
|
self.tagTableWidget = QtGui.QTableWidget(formattingTagDialog)
|
||||||
self.tagTableWidget.setHorizontalScrollBarPolicy(
|
self.tagTableWidget.setHorizontalScrollBarPolicy(
|
||||||
QtCore.Qt.ScrollBarAlwaysOff)
|
QtCore.Qt.ScrollBarAlwaysOff)
|
||||||
self.tagTableWidget.setEditTriggers(
|
self.tagTableWidget.setEditTriggers(
|
||||||
@ -67,11 +67,11 @@ class Ui_DisplayTagDialog(object):
|
|||||||
spacerItem = QtGui.QSpacerItem(40, 20,
|
spacerItem = QtGui.QSpacerItem(40, 20,
|
||||||
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
|
QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
|
||||||
self.horizontalLayout.addItem(spacerItem)
|
self.horizontalLayout.addItem(spacerItem)
|
||||||
self.deletePushButton = QtGui.QPushButton(displayTagDialog)
|
self.deletePushButton = QtGui.QPushButton(formattingTagDialog)
|
||||||
self.deletePushButton.setObjectName(u'deletePushButton')
|
self.deletePushButton.setObjectName(u'deletePushButton')
|
||||||
self.horizontalLayout.addWidget(self.deletePushButton)
|
self.horizontalLayout.addWidget(self.deletePushButton)
|
||||||
self.listdataGridLayout.addLayout(self.horizontalLayout, 1, 0, 1, 1)
|
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.editGroupBox.setObjectName(u'editGroupBox')
|
||||||
self.dataGridLayout = QtGui.QGridLayout(self.editGroupBox)
|
self.dataGridLayout = QtGui.QGridLayout(self.editGroupBox)
|
||||||
self.dataGridLayout.setObjectName(u'dataGridLayout')
|
self.dataGridLayout.setObjectName(u'dataGridLayout')
|
||||||
@ -112,38 +112,38 @@ class Ui_DisplayTagDialog(object):
|
|||||||
self.savePushButton.setObjectName(u'savePushButton')
|
self.savePushButton.setObjectName(u'savePushButton')
|
||||||
self.dataGridLayout.addWidget(self.savePushButton, 4, 2, 1, 1)
|
self.dataGridLayout.addWidget(self.savePushButton, 4, 2, 1, 1)
|
||||||
self.listdataGridLayout.addWidget(self.editGroupBox, 2, 0, 1, 1)
|
self.listdataGridLayout.addWidget(self.editGroupBox, 2, 0, 1, 1)
|
||||||
self.buttonBox = QtGui.QDialogButtonBox(displayTagDialog)
|
self.buttonBox = QtGui.QDialogButtonBox(formattingTagDialog)
|
||||||
self.buttonBox.setObjectName('displayTagDialogButtonBox')
|
self.buttonBox.setObjectName('formattingTagDialogButtonBox')
|
||||||
self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Close)
|
self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Close)
|
||||||
self.listdataGridLayout.addWidget(self.buttonBox, 3, 0, 1, 1)
|
self.listdataGridLayout.addWidget(self.buttonBox, 3, 0, 1, 1)
|
||||||
|
|
||||||
self.retranslateUi(displayTagDialog)
|
self.retranslateUi(formattingTagDialog)
|
||||||
QtCore.QMetaObject.connectSlotsByName(displayTagDialog)
|
QtCore.QMetaObject.connectSlotsByName(formattingTagDialog)
|
||||||
|
|
||||||
def retranslateUi(self, displayTagDialog):
|
def retranslateUi(self, formattingTagDialog):
|
||||||
displayTagDialog.setWindowTitle(translate('OpenLP.displayTagDialog',
|
formattingTagDialog.setWindowTitle(translate(
|
||||||
'Configure Display Tags'))
|
'OpenLP.FormattingTagDialog', 'Configure Formatting Tags'))
|
||||||
self.editGroupBox.setTitle(
|
self.editGroupBox.setTitle(
|
||||||
translate('OpenLP.DisplayTagDialog', 'Edit Selection'))
|
translate('OpenLP.FormattingTagDialog', 'Edit Selection'))
|
||||||
self.savePushButton.setText(
|
self.savePushButton.setText(
|
||||||
translate('OpenLP.DisplayTagDialog', 'Save'))
|
translate('OpenLP.FormattingTagDialog', 'Save'))
|
||||||
self.descriptionLabel.setText(
|
self.descriptionLabel.setText(
|
||||||
translate('OpenLP.DisplayTagDialog', 'Description'))
|
translate('OpenLP.FormattingTagDialog', 'Description'))
|
||||||
self.tagLabel.setText(translate('OpenLP.DisplayTagDialog', 'Tag'))
|
self.tagLabel.setText(translate('OpenLP.FormattingTagDialog', 'Tag'))
|
||||||
self.startTagLabel.setText(
|
self.startTagLabel.setText(
|
||||||
translate('OpenLP.DisplayTagDialog', 'Start tag'))
|
translate('OpenLP.FormattingTagDialog', 'Start tag'))
|
||||||
self.endTagLabel.setText(
|
self.endTagLabel.setText(
|
||||||
translate('OpenLP.DisplayTagDialog', 'End tag'))
|
translate('OpenLP.FormattingTagDialog', 'End tag'))
|
||||||
self.deletePushButton.setText(UiStrings().Delete)
|
self.deletePushButton.setText(UiStrings().Delete)
|
||||||
self.newPushButton.setText(UiStrings().New)
|
self.newPushButton.setText(UiStrings().New)
|
||||||
self.tagTableWidget.horizontalHeaderItem(0).setText(
|
self.tagTableWidget.horizontalHeaderItem(0).setText(
|
||||||
translate('OpenLP.DisplayTagDialog', 'Description'))
|
translate('OpenLP.FormattingTagDialog', 'Description'))
|
||||||
self.tagTableWidget.horizontalHeaderItem(1).setText(
|
self.tagTableWidget.horizontalHeaderItem(1).setText(
|
||||||
translate('OpenLP.DisplayTagDialog', 'Tag Id'))
|
translate('OpenLP.FormattingTagDialog', 'Tag Id'))
|
||||||
self.tagTableWidget.horizontalHeaderItem(2).setText(
|
self.tagTableWidget.horizontalHeaderItem(2).setText(
|
||||||
translate('OpenLP.DisplayTagDialog', 'Start HTML'))
|
translate('OpenLP.FormattingTagDialog', 'Start HTML'))
|
||||||
self.tagTableWidget.horizontalHeaderItem(3).setText(
|
self.tagTableWidget.horizontalHeaderItem(3).setText(
|
||||||
translate('OpenLP.DisplayTagDialog', 'End HTML'))
|
translate('OpenLP.FormattingTagDialog', 'End HTML'))
|
||||||
self.tagTableWidget.setColumnWidth(0, 120)
|
self.tagTableWidget.setColumnWidth(0, 120)
|
||||||
self.tagTableWidget.setColumnWidth(1, 80)
|
self.tagTableWidget.setColumnWidth(1, 80)
|
||||||
self.tagTableWidget.setColumnWidth(2, 330)
|
self.tagTableWidget.setColumnWidth(2, 330)
|
@ -25,22 +25,22 @@
|
|||||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||||
###############################################################################
|
###############################################################################
|
||||||
"""
|
"""
|
||||||
The :mod:`DisplayTagTab` provides an Tag Edit facility. The Base set are
|
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.
|
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 Custom Tag arrays are saved in a pickle so QSettings works on them. Base
|
||||||
Tags cannot be changed.
|
Tags cannot be changed.
|
||||||
"""
|
"""
|
||||||
import cPickle
|
import cPickle
|
||||||
|
|
||||||
from PyQt4 import QtCore, QtGui
|
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.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):
|
def __init__(self, parent):
|
||||||
"""
|
"""
|
||||||
@ -48,7 +48,7 @@ class DisplayTagForm(QtGui.QDialog, Ui_DisplayTagDialog):
|
|||||||
"""
|
"""
|
||||||
QtGui.QDialog.__init__(self, parent)
|
QtGui.QDialog.__init__(self, parent)
|
||||||
self.setupUi(self)
|
self.setupUi(self)
|
||||||
self._loadDisplayTags()
|
self._loadFormattingTags()
|
||||||
QtCore.QObject.connect(self.tagTableWidget,
|
QtCore.QObject.connect(self.tagTableWidget,
|
||||||
QtCore.SIGNAL(u'clicked(QModelIndex)'), self.onRowSelected)
|
QtCore.SIGNAL(u'clicked(QModelIndex)'), self.onRowSelected)
|
||||||
QtCore.QObject.connect(self.newPushButton,
|
QtCore.QObject.connect(self.newPushButton,
|
||||||
@ -65,19 +65,20 @@ class DisplayTagForm(QtGui.QDialog, Ui_DisplayTagDialog):
|
|||||||
Load Display and set field state.
|
Load Display and set field state.
|
||||||
"""
|
"""
|
||||||
# Create initial copy from master
|
# Create initial copy from master
|
||||||
self._loadDisplayTags()
|
self._loadFormattingTags()
|
||||||
self._resetTable()
|
self._resetTable()
|
||||||
self.selected = -1
|
self.selected = -1
|
||||||
return QtGui.QDialog.exec_(self)
|
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
|
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
|
update the display. If Cancel was selected this is needed to reset the
|
||||||
dsiplay to the correct version.
|
dsiplay to the correct version.
|
||||||
"""
|
"""
|
||||||
# Initial Load of the Tags
|
# 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',
|
user_expands = QtCore.QSettings().value(u'displayTags/html_tags',
|
||||||
QtCore.QVariant(u'')).toString()
|
QtCore.QVariant(u'')).toString()
|
||||||
# cPickle only accepts str not unicode strings
|
# cPickle only accepts str not unicode strings
|
||||||
@ -85,14 +86,14 @@ class DisplayTagForm(QtGui.QDialog, Ui_DisplayTagDialog):
|
|||||||
if user_expands_string:
|
if user_expands_string:
|
||||||
user_tags = cPickle.loads(user_expands_string)
|
user_tags = cPickle.loads(user_expands_string)
|
||||||
# If we have some user ones added them as well
|
# 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):
|
def onRowSelected(self):
|
||||||
"""
|
"""
|
||||||
Table Row selected so display items and set field state.
|
Table Row selected so display items and set field state.
|
||||||
"""
|
"""
|
||||||
row = self.tagTableWidget.currentRow()
|
row = self.tagTableWidget.currentRow()
|
||||||
html = DisplayTags.get_html_tags()[row]
|
html = FormattingTags.get_html_tags()[row]
|
||||||
self.selected = row
|
self.selected = row
|
||||||
self.descriptionLineEdit.setText(html[u'desc'])
|
self.descriptionLineEdit.setText(html[u'desc'])
|
||||||
self.tagLineEdit.setText(self._strip(html[u'start tag']))
|
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.
|
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':
|
if self._strip(html[u'start tag']) == u'n':
|
||||||
critical_error_message_box(
|
critical_error_message_box(
|
||||||
translate('OpenLP.DisplayTagTab', 'Update Error'),
|
translate('OpenLP.FormattingTagForm', 'Update Error'),
|
||||||
translate('OpenLP.DisplayTagTab',
|
translate('OpenLP.FormattingTagForm',
|
||||||
'Tag "n" already defined.'))
|
'Tag "n" already defined.'))
|
||||||
return
|
return
|
||||||
# Add new tag to list
|
# Add new tag to list
|
||||||
tag = {
|
tag = {
|
||||||
u'desc': translate('OpenLP.DisplayTagTab', 'New Tag'),
|
u'desc': translate('OpenLP.FormattingTagForm', 'New Tag'),
|
||||||
u'start tag': u'{n}',
|
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 tag': u'{/n}',
|
||||||
u'end html': translate('OpenLP.DisplayTagTab', '</and here>'),
|
u'end html': translate('OpenLP.FormattingTagForm', '</and here>'),
|
||||||
u'protected': False
|
u'protected': False
|
||||||
}
|
}
|
||||||
DisplayTags.add_html_tags([tag])
|
FormattingTags.add_html_tags([tag])
|
||||||
self._resetTable()
|
self._resetTable()
|
||||||
# Highlight new row
|
# Highlight new row
|
||||||
self.tagTableWidget.selectRow(self.tagTableWidget.rowCount() - 1)
|
self.tagTableWidget.selectRow(self.tagTableWidget.rowCount() - 1)
|
||||||
@ -145,7 +146,7 @@ class DisplayTagForm(QtGui.QDialog, Ui_DisplayTagDialog):
|
|||||||
Delete selected custom tag.
|
Delete selected custom tag.
|
||||||
"""
|
"""
|
||||||
if self.selected != -1:
|
if self.selected != -1:
|
||||||
DisplayTags.remove_html_tag(self.selected)
|
FormattingTags.remove_html_tag(self.selected)
|
||||||
self.selected = -1
|
self.selected = -1
|
||||||
self._resetTable()
|
self._resetTable()
|
||||||
self._saveTable()
|
self._saveTable()
|
||||||
@ -154,7 +155,7 @@ class DisplayTagForm(QtGui.QDialog, Ui_DisplayTagDialog):
|
|||||||
"""
|
"""
|
||||||
Update Custom Tag details if not duplicate and save the data.
|
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:
|
if self.selected != -1:
|
||||||
html = html_expands[self.selected]
|
html = html_expands[self.selected]
|
||||||
tag = unicode(self.tagLineEdit.text())
|
tag = unicode(self.tagLineEdit.text())
|
||||||
@ -162,8 +163,8 @@ class DisplayTagForm(QtGui.QDialog, Ui_DisplayTagDialog):
|
|||||||
if self._strip(html1[u'start tag']) == tag and \
|
if self._strip(html1[u'start tag']) == tag and \
|
||||||
linenumber != self.selected:
|
linenumber != self.selected:
|
||||||
critical_error_message_box(
|
critical_error_message_box(
|
||||||
translate('OpenLP.DisplayTagTab', 'Update Error'),
|
translate('OpenLP.FormattingTagForm', 'Update Error'),
|
||||||
unicode(translate('OpenLP.DisplayTagTab',
|
unicode(translate('OpenLP.FormattingTagForm',
|
||||||
'Tag %s already defined.')) % tag)
|
'Tag %s already defined.')) % tag)
|
||||||
return
|
return
|
||||||
html[u'desc'] = unicode(self.descriptionLineEdit.text())
|
html[u'desc'] = unicode(self.descriptionLineEdit.text())
|
||||||
@ -177,18 +178,15 @@ class DisplayTagForm(QtGui.QDialog, Ui_DisplayTagDialog):
|
|||||||
|
|
||||||
def _saveTable(self):
|
def _saveTable(self):
|
||||||
"""
|
"""
|
||||||
Saves all display tags except protected ones.
|
Saves all formatting tags except protected ones.
|
||||||
"""
|
"""
|
||||||
tags = []
|
tags = []
|
||||||
for tag in DisplayTags.get_html_tags():
|
for tag in FormattingTags.get_html_tags():
|
||||||
if not tag[u'protected']:
|
if not tag[u'protected']:
|
||||||
tags.append(tag)
|
tags.append(tag)
|
||||||
if tags:
|
# Formatting Tags were also known as display tags.
|
||||||
QtCore.QSettings().setValue(u'displayTags/html_tags',
|
QtCore.QSettings().setValue(u'displayTags/html_tags',
|
||||||
QtCore.QVariant(cPickle.dumps(tags)))
|
QtCore.QVariant(cPickle.dumps(tags) if tags else u''))
|
||||||
else:
|
|
||||||
QtCore.QSettings().setValue(u'displayTags/html_tags',
|
|
||||||
QtCore.QVariant(u''))
|
|
||||||
|
|
||||||
def _resetTable(self):
|
def _resetTable(self):
|
||||||
"""
|
"""
|
||||||
@ -199,7 +197,7 @@ class DisplayTagForm(QtGui.QDialog, Ui_DisplayTagDialog):
|
|||||||
self.newPushButton.setEnabled(True)
|
self.newPushButton.setEnabled(True)
|
||||||
self.savePushButton.setEnabled(False)
|
self.savePushButton.setEnabled(False)
|
||||||
self.deletePushButton.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.setRowCount(
|
||||||
self.tagTableWidget.rowCount() + 1)
|
self.tagTableWidget.rowCount() + 1)
|
||||||
self.tagTableWidget.setItem(linenumber, 0,
|
self.tagTableWidget.setItem(linenumber, 0,
|
@ -48,13 +48,13 @@ class MainDisplay(QtGui.QGraphicsView):
|
|||||||
"""
|
"""
|
||||||
This is the display screen.
|
This is the display screen.
|
||||||
"""
|
"""
|
||||||
def __init__(self, parent, image_manager, live):
|
def __init__(self, parent, imageManager, live):
|
||||||
if live:
|
if live:
|
||||||
QtGui.QGraphicsView.__init__(self)
|
QtGui.QGraphicsView.__init__(self)
|
||||||
else:
|
else:
|
||||||
QtGui.QGraphicsView.__init__(self, parent)
|
QtGui.QGraphicsView.__init__(self, parent)
|
||||||
self.isLive = live
|
self.isLive = live
|
||||||
self.image_manager = image_manager
|
self.imageManager = imageManager
|
||||||
self.screens = ScreenList.get_instance()
|
self.screens = ScreenList.get_instance()
|
||||||
self.alertTab = None
|
self.alertTab = None
|
||||||
self.hideMode = None
|
self.hideMode = None
|
||||||
@ -188,7 +188,7 @@ class MainDisplay(QtGui.QGraphicsView):
|
|||||||
while not self.webLoaded:
|
while not self.webLoaded:
|
||||||
Receiver.send_message(u'openlp_process_events')
|
Receiver.send_message(u'openlp_process_events')
|
||||||
self.setGeometry(self.screen[u'size'])
|
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'\\\"'))
|
slide.replace(u'\\', u'\\\\').replace(u'\"', u'\\\"'))
|
||||||
return self.preview()
|
return self.preview()
|
||||||
|
|
||||||
@ -232,7 +232,7 @@ class MainDisplay(QtGui.QGraphicsView):
|
|||||||
"""
|
"""
|
||||||
API for replacement backgrounds so Images are added directly to cache
|
API for replacement backgrounds so Images are added directly to cache
|
||||||
"""
|
"""
|
||||||
self.image_manager.add_image(name, path)
|
self.imageManager.add_image(name, path)
|
||||||
if hasattr(self, u'serviceItem'):
|
if hasattr(self, u'serviceItem'):
|
||||||
self.override[u'image'] = name
|
self.override[u'image'] = name
|
||||||
self.override[u'theme'] = self.serviceItem.themedata.theme_name
|
self.override[u'theme'] = self.serviceItem.themedata.theme_name
|
||||||
@ -249,7 +249,7 @@ class MainDisplay(QtGui.QGraphicsView):
|
|||||||
The name of the image to be displayed
|
The name of the image to be displayed
|
||||||
"""
|
"""
|
||||||
log.debug(u'image to display')
|
log.debug(u'image to display')
|
||||||
image = self.image_manager.get_image_bytes(name)
|
image = self.imageManager.get_image_bytes(name)
|
||||||
self.resetVideo()
|
self.resetVideo()
|
||||||
self.displayImage(image)
|
self.displayImage(image)
|
||||||
return self.preview()
|
return self.preview()
|
||||||
@ -482,13 +482,13 @@ class MainDisplay(QtGui.QGraphicsView):
|
|||||||
self.override = {}
|
self.override = {}
|
||||||
else:
|
else:
|
||||||
# replace the background
|
# replace the background
|
||||||
background = self.image_manager. \
|
background = self.imageManager. \
|
||||||
get_image_bytes(self.override[u'image'])
|
get_image_bytes(self.override[u'image'])
|
||||||
if self.serviceItem.themedata.background_filename:
|
if self.serviceItem.themedata.background_filename:
|
||||||
self.serviceItem.bg_image_bytes = self.image_manager. \
|
self.serviceItem.bg_image_bytes = self.imageManager. \
|
||||||
get_image_bytes(self.serviceItem.themedata.theme_name)
|
get_image_bytes(self.serviceItem.themedata.theme_name)
|
||||||
if image:
|
if image:
|
||||||
image_bytes = self.image_manager.get_image_bytes(image)
|
image_bytes = self.imageManager.get_image_bytes(image)
|
||||||
else:
|
else:
|
||||||
image_bytes = None
|
image_bytes = None
|
||||||
html = build_html(self.serviceItem, self.screen, self.alertTab,
|
html = build_html(self.serviceItem, self.screen, self.alertTab,
|
||||||
|
@ -33,15 +33,17 @@ from tempfile import gettempdir
|
|||||||
from PyQt4 import QtCore, QtGui
|
from PyQt4 import QtCore, QtGui
|
||||||
|
|
||||||
from openlp.core.lib import Renderer, build_icon, OpenLPDockWidget, \
|
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, \
|
from openlp.core.lib.ui import UiStrings, base_action, checkable_action, \
|
||||||
icon_action, shortcut_action
|
icon_action, shortcut_action
|
||||||
from openlp.core.ui import AboutForm, SettingsForm, ServiceManager, \
|
from openlp.core.ui import AboutForm, SettingsForm, ServiceManager, \
|
||||||
ThemeManager, SlideController, PluginForm, MediaDockManager, \
|
ThemeManager, SlideController, PluginForm, MediaDockManager, \
|
||||||
ShortcutListForm, DisplayTagForm
|
ShortcutListForm, FormattingTagForm
|
||||||
from openlp.core.utils import AppLocation, add_actions, LanguageManager, \
|
from openlp.core.utils import AppLocation, add_actions, LanguageManager, \
|
||||||
get_application_version, delete_file
|
get_application_version, delete_file
|
||||||
from openlp.core.utils.actions import ActionList, CategoryOrder
|
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__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -107,6 +109,8 @@ class Ui_MainWindow(object):
|
|||||||
self.menuBar.setObjectName(u'menuBar')
|
self.menuBar.setObjectName(u'menuBar')
|
||||||
self.fileMenu = QtGui.QMenu(self.menuBar)
|
self.fileMenu = QtGui.QMenu(self.menuBar)
|
||||||
self.fileMenu.setObjectName(u'fileMenu')
|
self.fileMenu.setObjectName(u'fileMenu')
|
||||||
|
self.recentFilesMenu = QtGui.QMenu(self.fileMenu)
|
||||||
|
self.recentFilesMenu.setObjectName(u'recentFilesMenu')
|
||||||
self.fileImportMenu = QtGui.QMenu(self.fileMenu)
|
self.fileImportMenu = QtGui.QMenu(self.fileMenu)
|
||||||
self.fileImportMenu.setObjectName(u'fileImportMenu')
|
self.fileImportMenu.setObjectName(u'fileImportMenu')
|
||||||
self.fileExportMenu = QtGui.QMenu(self.fileMenu)
|
self.fileExportMenu = QtGui.QMenu(self.fileMenu)
|
||||||
@ -244,6 +248,9 @@ class Ui_MainWindow(object):
|
|||||||
self.toolsOpenDataFolder = icon_action(mainWindow,
|
self.toolsOpenDataFolder = icon_action(mainWindow,
|
||||||
u'toolsOpenDataFolder', u':/general/general_open.png',
|
u'toolsOpenDataFolder', u':/general/general_open.png',
|
||||||
category=UiStrings().Tools)
|
category=UiStrings().Tools)
|
||||||
|
self.toolsFirstTimeWizard = icon_action(mainWindow,
|
||||||
|
u'toolsFirstTimeWizard', u':/general/general_revert.png',
|
||||||
|
category=UiStrings().Tools)
|
||||||
self.updateThemeImages = base_action(mainWindow,
|
self.updateThemeImages = base_action(mainWindow,
|
||||||
u'updateThemeImages', category=UiStrings().Tools)
|
u'updateThemeImages', category=UiStrings().Tools)
|
||||||
action_list.add_category(UiStrings().Settings,
|
action_list.add_category(UiStrings().Settings,
|
||||||
@ -269,7 +276,8 @@ class Ui_MainWindow(object):
|
|||||||
u'settingsShortcutsItem',
|
u'settingsShortcutsItem',
|
||||||
u':/system/system_configure_shortcuts.png',
|
u':/system/system_configure_shortcuts.png',
|
||||||
category=UiStrings().Settings)
|
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',
|
u'displayTagItem', u':/system/tag_editor.png',
|
||||||
category=UiStrings().Settings)
|
category=UiStrings().Settings)
|
||||||
self.settingsConfigureItem = icon_action(mainWindow,
|
self.settingsConfigureItem = icon_action(mainWindow,
|
||||||
@ -296,10 +304,11 @@ class Ui_MainWindow(object):
|
|||||||
(self.importThemeItem, self.importLanguageItem))
|
(self.importThemeItem, self.importLanguageItem))
|
||||||
add_actions(self.fileExportMenu,
|
add_actions(self.fileExportMenu,
|
||||||
(self.exportThemeItem, self.exportLanguageItem))
|
(self.exportThemeItem, self.exportLanguageItem))
|
||||||
self.fileMenuActions = (self.fileNewItem, self.fileOpenItem,
|
add_actions(self.fileMenu, (self.fileNewItem, self.fileOpenItem,
|
||||||
self.fileSaveItem, self.fileSaveAsItem, None,
|
self.fileSaveItem, self.fileSaveAsItem,
|
||||||
self.printServiceOrderItem, None, self.fileImportMenu.menuAction(),
|
self.recentFilesMenu.menuAction(), None,
|
||||||
self.fileExportMenu.menuAction(), self.fileExitItem)
|
self.fileImportMenu.menuAction(), self.fileExportMenu.menuAction(),
|
||||||
|
None, self.printServiceOrderItem, self.fileExitItem))
|
||||||
add_actions(self.viewModeMenu, (self.modeDefaultItem,
|
add_actions(self.viewModeMenu, (self.modeDefaultItem,
|
||||||
self.modeSetupItem, self.modeLiveItem))
|
self.modeSetupItem, self.modeLiveItem))
|
||||||
add_actions(self.viewMenu, (self.viewModeMenu.menuAction(),
|
add_actions(self.viewMenu, (self.viewModeMenu.menuAction(),
|
||||||
@ -315,14 +324,15 @@ class Ui_MainWindow(object):
|
|||||||
add_actions(self.settingsMenu, (self.settingsPluginListItem,
|
add_actions(self.settingsMenu, (self.settingsPluginListItem,
|
||||||
self.settingsLanguageMenu.menuAction(), None,
|
self.settingsLanguageMenu.menuAction(), None,
|
||||||
self.settingsConfigureItem, self.settingsShortcutsItem,
|
self.settingsConfigureItem, self.settingsShortcutsItem,
|
||||||
self.displayTagItem))
|
self.formattingTagItem))
|
||||||
else:
|
else:
|
||||||
add_actions(self.settingsMenu, (self.settingsPluginListItem,
|
add_actions(self.settingsMenu, (self.settingsPluginListItem,
|
||||||
self.settingsLanguageMenu.menuAction(), None,
|
self.settingsLanguageMenu.menuAction(), None,
|
||||||
self.displayTagItem, self.settingsShortcutsItem,
|
self.formattingTagItem, self.settingsShortcutsItem,
|
||||||
self.settingsConfigureItem))
|
self.settingsConfigureItem))
|
||||||
add_actions(self.toolsMenu, (self.toolsAddToolItem, None))
|
add_actions(self.toolsMenu, (self.toolsAddToolItem, None))
|
||||||
add_actions(self.toolsMenu, (self.toolsOpenDataFolder, None))
|
add_actions(self.toolsMenu, (self.toolsOpenDataFolder, None))
|
||||||
|
add_actions(self.toolsMenu, (self.toolsFirstTimeWizard, None))
|
||||||
add_actions(self.toolsMenu, [self.updateThemeImages])
|
add_actions(self.toolsMenu, [self.updateThemeImages])
|
||||||
if os.name == u'nt':
|
if os.name == u'nt':
|
||||||
add_actions(self.helpMenu, (self.offlineHelpItem,
|
add_actions(self.helpMenu, (self.offlineHelpItem,
|
||||||
@ -339,7 +349,7 @@ class Ui_MainWindow(object):
|
|||||||
self.mediaToolBox.setCurrentIndex(0)
|
self.mediaToolBox.setCurrentIndex(0)
|
||||||
# Connect up some signals and slots
|
# Connect up some signals and slots
|
||||||
QtCore.QObject.connect(self.fileMenu,
|
QtCore.QObject.connect(self.fileMenu,
|
||||||
QtCore.SIGNAL(u'aboutToShow()'), self.updateFileMenu)
|
QtCore.SIGNAL(u'aboutToShow()'), self.updateRecentFilesMenu)
|
||||||
QtCore.QMetaObject.connectSlotsByName(mainWindow)
|
QtCore.QMetaObject.connectSlotsByName(mainWindow)
|
||||||
# Hide the entry, as it does not have any functionality yet.
|
# Hide the entry, as it does not have any functionality yet.
|
||||||
self.toolsAddToolItem.setVisible(False)
|
self.toolsAddToolItem.setVisible(False)
|
||||||
@ -356,6 +366,8 @@ class Ui_MainWindow(object):
|
|||||||
self.fileMenu.setTitle(translate('OpenLP.MainWindow', '&File'))
|
self.fileMenu.setTitle(translate('OpenLP.MainWindow', '&File'))
|
||||||
self.fileImportMenu.setTitle(translate('OpenLP.MainWindow', '&Import'))
|
self.fileImportMenu.setTitle(translate('OpenLP.MainWindow', '&Import'))
|
||||||
self.fileExportMenu.setTitle(translate('OpenLP.MainWindow', '&Export'))
|
self.fileExportMenu.setTitle(translate('OpenLP.MainWindow', '&Export'))
|
||||||
|
self.recentFilesMenu.setTitle(
|
||||||
|
translate('OpenLP.MainWindow', '&Recent Files'))
|
||||||
self.viewMenu.setTitle(translate('OpenLP.MainWindow', '&View'))
|
self.viewMenu.setTitle(translate('OpenLP.MainWindow', '&View'))
|
||||||
self.viewModeMenu.setTitle(translate('OpenLP.MainWindow', 'M&ode'))
|
self.viewModeMenu.setTitle(translate('OpenLP.MainWindow', 'M&ode'))
|
||||||
self.toolsMenu.setTitle(translate('OpenLP.MainWindow', '&Tools'))
|
self.toolsMenu.setTitle(translate('OpenLP.MainWindow', '&Tools'))
|
||||||
@ -403,8 +415,8 @@ class Ui_MainWindow(object):
|
|||||||
translate('OpenLP.MainWindow', '&Language'))
|
translate('OpenLP.MainWindow', '&Language'))
|
||||||
self.settingsShortcutsItem.setText(
|
self.settingsShortcutsItem.setText(
|
||||||
translate('OpenLP.MainWindow', 'Configure &Shortcuts...'))
|
translate('OpenLP.MainWindow', 'Configure &Shortcuts...'))
|
||||||
self.displayTagItem.setText(
|
self.formattingTagItem.setText(
|
||||||
translate('OpenLP.MainWindow', '&Configure Display Tags'))
|
translate('OpenLP.MainWindow', '&Configure Formatting Tags...'))
|
||||||
self.settingsConfigureItem.setText(
|
self.settingsConfigureItem.setText(
|
||||||
translate('OpenLP.MainWindow', '&Configure OpenLP...'))
|
translate('OpenLP.MainWindow', '&Configure OpenLP...'))
|
||||||
self.viewMediaManagerItem.setText(
|
self.viewMediaManagerItem.setText(
|
||||||
@ -471,6 +483,10 @@ class Ui_MainWindow(object):
|
|||||||
translate('OpenLP.MainWindow', 'Open &Data Folder...'))
|
translate('OpenLP.MainWindow', 'Open &Data Folder...'))
|
||||||
self.toolsOpenDataFolder.setStatusTip(translate('OpenLP.MainWindow',
|
self.toolsOpenDataFolder.setStatusTip(translate('OpenLP.MainWindow',
|
||||||
'Open the folder where songs, bibles and other data resides.'))
|
'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(
|
self.updateThemeImages.setText(
|
||||||
translate('OpenLP.MainWindow', 'Update Theme Images'))
|
translate('OpenLP.MainWindow', 'Update Theme Images'))
|
||||||
self.updateThemeImages.setStatusTip(
|
self.updateThemeImages.setStatusTip(
|
||||||
@ -511,7 +527,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
|||||||
self.serviceNotSaved = False
|
self.serviceNotSaved = False
|
||||||
self.aboutForm = AboutForm(self)
|
self.aboutForm = AboutForm(self)
|
||||||
self.settingsForm = SettingsForm(self, self)
|
self.settingsForm = SettingsForm(self, self)
|
||||||
self.displayTagForm = DisplayTagForm(self)
|
self.formattingTagForm = FormattingTagForm(self)
|
||||||
self.shortcutForm = ShortcutListForm(self)
|
self.shortcutForm = ShortcutListForm(self)
|
||||||
self.recentFiles = QtCore.QStringList()
|
self.recentFiles = QtCore.QStringList()
|
||||||
# Set up the path with plugins
|
# Set up the path with plugins
|
||||||
@ -523,8 +539,8 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
|||||||
self.setupUi(self)
|
self.setupUi(self)
|
||||||
# Load settings after setupUi so default UI sizes are overwritten
|
# Load settings after setupUi so default UI sizes are overwritten
|
||||||
self.loadSettings()
|
self.loadSettings()
|
||||||
# Once settings are loaded update FileMenu with recentFiles
|
# Once settings are loaded update the menu with the recent files.
|
||||||
self.updateFileMenu()
|
self.updateRecentFilesMenu()
|
||||||
self.pluginForm = PluginForm(self)
|
self.pluginForm = PluginForm(self)
|
||||||
# Set up signals and slots
|
# Set up signals and slots
|
||||||
QtCore.QObject.connect(self.importThemeItem,
|
QtCore.QObject.connect(self.importThemeItem,
|
||||||
@ -546,10 +562,12 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
|||||||
QtCore.SIGNAL(u'triggered()'), self.onHelpWebSiteClicked)
|
QtCore.SIGNAL(u'triggered()'), self.onHelpWebSiteClicked)
|
||||||
QtCore.QObject.connect(self.toolsOpenDataFolder,
|
QtCore.QObject.connect(self.toolsOpenDataFolder,
|
||||||
QtCore.SIGNAL(u'triggered()'), self.onToolsOpenDataFolderClicked)
|
QtCore.SIGNAL(u'triggered()'), self.onToolsOpenDataFolderClicked)
|
||||||
|
QtCore.QObject.connect(self.toolsFirstTimeWizard,
|
||||||
|
QtCore.SIGNAL(u'triggered()'), self.onFirstTimeWizardClicked)
|
||||||
QtCore.QObject.connect(self.updateThemeImages,
|
QtCore.QObject.connect(self.updateThemeImages,
|
||||||
QtCore.SIGNAL(u'triggered()'), self.onUpdateThemeImages)
|
QtCore.SIGNAL(u'triggered()'), self.onUpdateThemeImages)
|
||||||
QtCore.QObject.connect(self.displayTagItem,
|
QtCore.QObject.connect(self.formattingTagItem,
|
||||||
QtCore.SIGNAL(u'triggered()'), self.onDisplayTagItemClicked)
|
QtCore.SIGNAL(u'triggered()'), self.onFormattingTagItemClicked)
|
||||||
QtCore.QObject.connect(self.settingsConfigureItem,
|
QtCore.QObject.connect(self.settingsConfigureItem,
|
||||||
QtCore.SIGNAL(u'triggered()'), self.onSettingsConfigureItemClicked)
|
QtCore.SIGNAL(u'triggered()'), self.onSettingsConfigureItemClicked)
|
||||||
QtCore.QObject.connect(self.settingsShortcutsItem,
|
QtCore.QObject.connect(self.settingsShortcutsItem,
|
||||||
@ -714,6 +732,45 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
|||||||
delete_file(os.path.join(temp_dir, filename))
|
delete_file(os.path.join(temp_dir, filename))
|
||||||
os.removedirs(temp_dir)
|
os.removedirs(temp_dir)
|
||||||
|
|
||||||
|
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
|
||||||
|
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):
|
def blankCheck(self):
|
||||||
"""
|
"""
|
||||||
Check and display message if screen blank on setup.
|
Check and display message if screen blank on setup.
|
||||||
@ -788,11 +845,11 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
|||||||
"""
|
"""
|
||||||
self.themeManagerContents.updatePreviewImages()
|
self.themeManagerContents.updatePreviewImages()
|
||||||
|
|
||||||
def onDisplayTagItemClicked(self):
|
def onFormattingTagItemClicked(self):
|
||||||
"""
|
"""
|
||||||
Show the Settings dialog
|
Show the Settings dialog
|
||||||
"""
|
"""
|
||||||
self.displayTagForm.exec_()
|
self.formattingTagForm.exec_()
|
||||||
|
|
||||||
def onSettingsConfigureItemClicked(self):
|
def onSettingsConfigureItemClicked(self):
|
||||||
"""
|
"""
|
||||||
@ -1085,30 +1142,36 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
|||||||
QtCore.QVariant(self.controlSplitter.saveState()))
|
QtCore.QVariant(self.controlSplitter.saveState()))
|
||||||
settings.endGroup()
|
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(
|
recentFileCount = QtCore.QSettings().value(
|
||||||
u'advanced/recent file count', QtCore.QVariant(4)).toInt()[0]
|
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
|
existingRecentFiles = [recentFile for recentFile in self.recentFiles
|
||||||
if QtCore.QFile.exists(recentFile)]
|
if QtCore.QFile.exists(recentFile)]
|
||||||
recentFilesToDisplay = existingRecentFiles[0:recentFileCount]
|
recentFilesToDisplay = existingRecentFiles[0:recentFileCount]
|
||||||
if recentFilesToDisplay:
|
self.recentFilesMenu.clear()
|
||||||
self.fileMenu.addSeparator()
|
for fileId, filename in enumerate(recentFilesToDisplay):
|
||||||
for fileId, filename in enumerate(recentFilesToDisplay):
|
log.debug('Recent file name: %s', filename)
|
||||||
log.debug('Recent file name: %s', filename)
|
action = base_action(self, u'')
|
||||||
action = base_action(self, u'')
|
action.setText(u'&%d %s' %
|
||||||
action.setText(u'&%d %s' %
|
(fileId + 1, QtCore.QFileInfo(filename).fileName()))
|
||||||
(fileId + 1, QtCore.QFileInfo(filename).fileName()))
|
action.setData(QtCore.QVariant(filename))
|
||||||
action.setData(QtCore.QVariant(filename))
|
self.connect(action, QtCore.SIGNAL(u'triggered()'),
|
||||||
self.connect(action, QtCore.SIGNAL(u'triggered()'),
|
self.serviceManagerContents.onRecentServiceClicked)
|
||||||
self.serviceManagerContents.onRecentServiceClicked)
|
self.recentFilesMenu.addAction(action)
|
||||||
self.fileMenu.addAction(action)
|
clearRecentFilesAction = base_action(self, u'')
|
||||||
self.fileMenu.addSeparator()
|
clearRecentFilesAction.setText(
|
||||||
self.fileMenu.addAction(self.fileMenuActions[-1])
|
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):
|
def addRecentFile(self, filename):
|
||||||
"""
|
"""
|
||||||
|
@ -66,7 +66,7 @@ class MediaDockManager(object):
|
|||||||
match = False
|
match = False
|
||||||
for dock_index in range(0, self.media_dock.count()):
|
for dock_index in range(0, self.media_dock.count()):
|
||||||
if self.media_dock.widget(dock_index).settingsSection == \
|
if self.media_dock.widget(dock_index).settingsSection == \
|
||||||
media_item.plugin.name.lower():
|
media_item.plugin.name:
|
||||||
match = True
|
match = True
|
||||||
break
|
break
|
||||||
if not match:
|
if not match:
|
||||||
@ -84,6 +84,6 @@ class MediaDockManager(object):
|
|||||||
for dock_index in range(0, self.media_dock.count()):
|
for dock_index in range(0, self.media_dock.count()):
|
||||||
if self.media_dock.widget(dock_index):
|
if self.media_dock.widget(dock_index):
|
||||||
if self.media_dock.widget(dock_index).settingsSection == \
|
if self.media_dock.widget(dock_index).settingsSection == \
|
||||||
media_item.plugin.name.lower():
|
media_item.plugin.name:
|
||||||
self.media_dock.widget(dock_index).setVisible(False)
|
self.media_dock.widget(dock_index).setVisible(False)
|
||||||
self.media_dock.removeItem(dock_index)
|
self.media_dock.removeItem(dock_index)
|
||||||
|
@ -108,7 +108,7 @@ class Ui_PrintServiceDialog(object):
|
|||||||
self.footerLabel = QtGui.QLabel(self.optionsWidget)
|
self.footerLabel = QtGui.QLabel(self.optionsWidget)
|
||||||
self.footerLabel.setObjectName(u'footerLabel')
|
self.footerLabel.setObjectName(u'footerLabel')
|
||||||
self.optionsLayout.addWidget(self.footerLabel)
|
self.optionsLayout.addWidget(self.footerLabel)
|
||||||
self.footerTextEdit = SpellTextEdit(self.optionsWidget)
|
self.footerTextEdit = SpellTextEdit(self.optionsWidget, False)
|
||||||
self.footerTextEdit.setObjectName(u'footerTextEdit')
|
self.footerTextEdit.setObjectName(u'footerTextEdit')
|
||||||
self.optionsLayout.addWidget(self.footerTextEdit)
|
self.optionsLayout.addWidget(self.footerTextEdit)
|
||||||
self.optionsGroupBox = QtGui.QGroupBox()
|
self.optionsGroupBox = QtGui.QGroupBox()
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
import cgi
|
||||||
import datetime
|
import datetime
|
||||||
import os
|
import os
|
||||||
|
|
||||||
@ -183,7 +184,7 @@ class PrintServiceForm(QtGui.QDialog, Ui_PrintServiceDialog):
|
|||||||
self._addElement(u'style', custom_css, html_data.head,
|
self._addElement(u'style', custom_css, html_data.head,
|
||||||
attribute=(u'type', u'text/css'))
|
attribute=(u'type', u'text/css'))
|
||||||
self._addElement(u'body', parent=html_data)
|
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')
|
html_data.body, classId=u'serviceTitle')
|
||||||
for index, item in enumerate(self.serviceManager.serviceItems):
|
for index, item in enumerate(self.serviceManager.serviceItems):
|
||||||
self._addPreviewItem(html_data.body, item[u'service_item'], index)
|
self._addPreviewItem(html_data.body, item[u'service_item'], index)
|
||||||
@ -193,8 +194,9 @@ class PrintServiceForm(QtGui.QDialog, Ui_PrintServiceDialog):
|
|||||||
classId=u'customNotes')
|
classId=u'customNotes')
|
||||||
self._addElement(u'span', translate('OpenLP.ServiceManager',
|
self._addElement(u'span', translate('OpenLP.ServiceManager',
|
||||||
'Custom Service Notes: '), div, classId=u'customNotesTitle')
|
'Custom Service Notes: '), div, classId=u'customNotesTitle')
|
||||||
self._addElement(u'span', self.footerTextEdit.toPlainText(), div,
|
self._addElement(u'span',
|
||||||
classId=u'customNotesText')
|
cgi.escape(self.footerTextEdit.toPlainText()),
|
||||||
|
div, classId=u'customNotesText')
|
||||||
self.document.setHtml(html.tostring(html_data))
|
self.document.setHtml(html.tostring(html_data))
|
||||||
self.previewWidget.updatePreview()
|
self.previewWidget.updatePreview()
|
||||||
|
|
||||||
@ -204,8 +206,8 @@ class PrintServiceForm(QtGui.QDialog, Ui_PrintServiceDialog):
|
|||||||
item_title = self._addElement(u'h2', parent=div, classId=u'itemTitle')
|
item_title = self._addElement(u'h2', parent=div, classId=u'itemTitle')
|
||||||
self._addElement(u'img', parent=item_title,
|
self._addElement(u'img', parent=item_title,
|
||||||
attribute=(u'src', item.icon))
|
attribute=(u'src', item.icon))
|
||||||
self._addElement(u'span', u' ' + item.get_display_title(),
|
self._addElement(u'span',
|
||||||
item_title)
|
u' ' + cgi.escape(item.get_display_title()), item_title)
|
||||||
if self.slideTextCheckBox.isChecked():
|
if self.slideTextCheckBox.isChecked():
|
||||||
# Add the text of the service item.
|
# Add the text of the service item.
|
||||||
if item.is_text():
|
if item.is_text():
|
||||||
@ -230,8 +232,9 @@ class PrintServiceForm(QtGui.QDialog, Ui_PrintServiceDialog):
|
|||||||
foot_text = item.foot_text
|
foot_text = item.foot_text
|
||||||
foot_text = foot_text.partition(u'<br>')[2]
|
foot_text = foot_text.partition(u'<br>')[2]
|
||||||
if foot_text:
|
if foot_text:
|
||||||
foot = self._addElement(u'div', foot_text, parent=div,
|
foot_text = cgi.escape(foot_text.replace(u'<br>', u'\n'))
|
||||||
classId=u'itemFooter')
|
self._addElement(u'div', foot_text.replace(u'\n', u'<br>'),
|
||||||
|
parent=div, classId=u'itemFooter')
|
||||||
# Add service items' notes.
|
# Add service items' notes.
|
||||||
if self.notesCheckBox.isChecked():
|
if self.notesCheckBox.isChecked():
|
||||||
if item.notes:
|
if item.notes:
|
||||||
@ -239,8 +242,8 @@ class PrintServiceForm(QtGui.QDialog, Ui_PrintServiceDialog):
|
|||||||
self._addElement(u'span',
|
self._addElement(u'span',
|
||||||
translate('OpenLP.ServiceManager', 'Notes: '), p,
|
translate('OpenLP.ServiceManager', 'Notes: '), p,
|
||||||
classId=u'itemNotesTitle')
|
classId=u'itemNotesTitle')
|
||||||
notes = self._addElement(u'span',
|
self._addElement(u'span',
|
||||||
item.notes.replace(u'\n', u'<br />'), p,
|
cgi.escape(unicode(item.notes)).replace(u'\n', u'<br>'), p,
|
||||||
classId=u'itemNotesText')
|
classId=u'itemNotesText')
|
||||||
# Add play length of media files.
|
# Add play length of media files.
|
||||||
if item.is_media() and self.metaDataCheckBox.isChecked():
|
if item.is_media() and self.metaDataCheckBox.isChecked():
|
||||||
|
@ -79,7 +79,7 @@ class ServiceItemEditForm(QtGui.QDialog, Ui_ServiceItemEditDialog):
|
|||||||
if not item:
|
if not item:
|
||||||
return
|
return
|
||||||
row = self.listWidget.row(item)
|
row = self.listWidget.row(item)
|
||||||
self.itemList.remove(self.itemList[row])
|
self.itemList.pop(row)
|
||||||
self.loadData()
|
self.loadData()
|
||||||
if row == self.listWidget.count():
|
if row == self.listWidget.count():
|
||||||
self.listWidget.setCurrentRow(row - 1)
|
self.listWidget.setCurrentRow(row - 1)
|
||||||
@ -109,7 +109,7 @@ class ServiceItemEditForm(QtGui.QDialog, Ui_ServiceItemEditDialog):
|
|||||||
return
|
return
|
||||||
row = self.listWidget.row(item)
|
row = self.listWidget.row(item)
|
||||||
temp = self.itemList[row]
|
temp = self.itemList[row]
|
||||||
self.itemList.remove(self.itemList[row])
|
self.itemList.pop(row)
|
||||||
if direction == u'up':
|
if direction == u'up':
|
||||||
row -= 1
|
row -= 1
|
||||||
else:
|
else:
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
|
||||||
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
import cgi
|
||||||
import cPickle
|
import cPickle
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
@ -408,20 +409,33 @@ class ServiceManager(QtGui.QWidget):
|
|||||||
return False
|
return False
|
||||||
self.newFile()
|
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():
|
if self.isModified():
|
||||||
result = self.saveModifiedService()
|
result = self.saveModifiedService()
|
||||||
if result == QtGui.QMessageBox.Cancel:
|
if result == QtGui.QMessageBox.Cancel:
|
||||||
return False
|
return False
|
||||||
elif result == QtGui.QMessageBox.Save:
|
elif result == QtGui.QMessageBox.Save:
|
||||||
self.saveFile()
|
self.saveFile()
|
||||||
fileName = unicode(QtGui.QFileDialog.getOpenFileName(self.mainwindow,
|
if not loadFile:
|
||||||
translate('OpenLP.ServiceManager', 'Open File'),
|
fileName = unicode(QtGui.QFileDialog.getOpenFileName(
|
||||||
SettingsManager.get_last_dir(
|
self.mainwindow,
|
||||||
self.mainwindow.serviceSettingsSection),
|
translate('OpenLP.ServiceManager', 'Open File'),
|
||||||
translate('OpenLP.ServiceManager', 'OpenLP Service Files (*.osz)')))
|
SettingsManager.get_last_dir(
|
||||||
if not fileName:
|
self.mainwindow.serviceSettingsSection),
|
||||||
return False
|
translate('OpenLP.ServiceManager',
|
||||||
|
'OpenLP Service Files (*.osz)')))
|
||||||
|
if not fileName:
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
fileName = loadFile
|
||||||
SettingsManager.set_last_dir(self.mainwindow.serviceSettingsSection,
|
SettingsManager.set_last_dir(self.mainwindow.serviceSettingsSection,
|
||||||
split_filename(fileName)[0])
|
split_filename(fileName)[0])
|
||||||
self.loadFile(fileName)
|
self.loadFile(fileName)
|
||||||
@ -474,6 +488,7 @@ class ServiceManager(QtGui.QWidget):
|
|||||||
item[u'service_item'].get_service_repr()})
|
item[u'service_item'].get_service_repr()})
|
||||||
if not item[u'service_item'].uses_file():
|
if not item[u'service_item'].uses_file():
|
||||||
continue
|
continue
|
||||||
|
skipMissing = False
|
||||||
for frame in item[u'service_item'].get_frames():
|
for frame in item[u'service_item'].get_frames():
|
||||||
if item[u'service_item'].is_image():
|
if item[u'service_item'].is_image():
|
||||||
path_from = frame[u'path']
|
path_from = frame[u'path']
|
||||||
@ -482,25 +497,29 @@ class ServiceManager(QtGui.QWidget):
|
|||||||
# Only write a file once
|
# Only write a file once
|
||||||
if path_from in write_list:
|
if path_from in write_list:
|
||||||
continue
|
continue
|
||||||
file_size = os.path.getsize(path_from)
|
if not os.path.exists(path_from):
|
||||||
size_limit = 52428800 # 50MiB
|
if not skipMissing:
|
||||||
#if file_size > size_limit:
|
Receiver.send_message(u'cursor_normal')
|
||||||
# # File exeeds size_limit bytes, ask user
|
title = unicode(translate('OpenLP.ServiceManager',
|
||||||
# message = unicode(translate('OpenLP.ServiceManager',
|
'Service File Missing'))
|
||||||
# 'Do you want to include \n%.1f MB file "%s"\n'
|
message = unicode(translate('OpenLP.ServiceManager',
|
||||||
# 'into the service file?\nThis may take some time.\n\n'
|
'File missing from service\n\n %s \n\n'
|
||||||
# 'Please note that you need to\ntake care of that file'
|
'Continue saving?' % path_from ))
|
||||||
# ' yourself,\nif you leave it out.')) % \
|
answer = QtGui.QMessageBox.critical(self, title,
|
||||||
# (file_size/1048576, os.path.split(path_from)[1])
|
message,
|
||||||
# ans = QtGui.QMessageBox.question(self.mainwindow,
|
QtGui.QMessageBox.StandardButtons(
|
||||||
# translate('OpenLP.ServiceManager', 'Including Large '
|
QtGui.QMessageBox.Yes | QtGui.QMessageBox.No |
|
||||||
# 'File'), message, QtGui.QMessageBox.StandardButtons(
|
QtGui.QMessageBox.YesToAll))
|
||||||
# QtGui.QMessageBox.Ok|QtGui.QMessageBox.Cancel),
|
if answer == QtGui.QMessageBox.No:
|
||||||
# QtGui.QMessageBox.Ok)
|
self.mainwindow.finishedProgressBar()
|
||||||
# if ans == QtGui.QMessageBox.Cancel:
|
return False
|
||||||
# continue
|
if answer == QtGui.QMessageBox.YesToAll:
|
||||||
write_list.append(path_from)
|
skipMissing = True
|
||||||
total_size += file_size
|
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' %
|
log.debug(u'ServiceManager.saveFile - ZIP contents size is %i bytes' %
|
||||||
total_size)
|
total_size)
|
||||||
service_content = cPickle.dumps(service)
|
service_content = cPickle.dumps(service)
|
||||||
@ -701,6 +720,9 @@ class ServiceManager(QtGui.QWidget):
|
|||||||
self.setModified()
|
self.setModified()
|
||||||
|
|
||||||
def onStartTimeForm(self):
|
def onStartTimeForm(self):
|
||||||
|
"""
|
||||||
|
Opens a dialog to type in service item notes.
|
||||||
|
"""
|
||||||
item = self.findServiceItem()[0]
|
item = self.findServiceItem()[0]
|
||||||
self.startTimeForm.item = self.serviceItems[item]
|
self.startTimeForm.item = self.serviceItems[item]
|
||||||
if self.startTimeForm.exec_():
|
if self.startTimeForm.exec_():
|
||||||
@ -939,11 +961,11 @@ class ServiceManager(QtGui.QWidget):
|
|||||||
if serviceitem.notes:
|
if serviceitem.notes:
|
||||||
tips.append(u'<strong>%s: </strong> %s' %
|
tips.append(u'<strong>%s: </strong> %s' %
|
||||||
(unicode(translate('OpenLP.ServiceManager', 'Notes')),
|
(unicode(translate('OpenLP.ServiceManager', 'Notes')),
|
||||||
unicode(serviceitem.notes)))
|
cgi.escape(unicode(serviceitem.notes))))
|
||||||
if item[u'service_item'] \
|
if item[u'service_item'] \
|
||||||
.is_capable(ItemCapabilities.AllowsVariableStartTime):
|
.is_capable(ItemCapabilities.AllowsVariableStartTime):
|
||||||
tips.append(item[u'service_item'].get_media_time())
|
tips.append(item[u'service_item'].get_media_time())
|
||||||
treewidgetitem.setToolTip(0, u'<br />'.join(tips))
|
treewidgetitem.setToolTip(0, u'<br>'.join(tips))
|
||||||
treewidgetitem.setData(0, QtCore.Qt.UserRole,
|
treewidgetitem.setData(0, QtCore.Qt.UserRole,
|
||||||
QtCore.QVariant(item[u'order']))
|
QtCore.QVariant(item[u'order']))
|
||||||
treewidgetitem.setSelected(item[u'selected'])
|
treewidgetitem.setSelected(item[u'selected'])
|
||||||
@ -1239,7 +1261,14 @@ class ServiceManager(QtGui.QWidget):
|
|||||||
Handle of the event pint passed
|
Handle of the event pint passed
|
||||||
"""
|
"""
|
||||||
link = event.mimeData()
|
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())
|
plugin = unicode(event.mimeData().text())
|
||||||
item = self.serviceManagerList.itemAt(event.pos())
|
item = self.serviceManagerList.itemAt(event.pos())
|
||||||
# ServiceManager started the drag and drop
|
# ServiceManager started the drag and drop
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
from PyQt4 import QtCore, QtGui
|
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
|
from openlp.core.lib.ui import create_accept_reject_button_box
|
||||||
|
|
||||||
class ServiceNoteForm(QtGui.QDialog):
|
class ServiceNoteForm(QtGui.QDialog):
|
||||||
@ -52,7 +52,7 @@ class ServiceNoteForm(QtGui.QDialog):
|
|||||||
self.dialogLayout.setContentsMargins(8, 8, 8, 8)
|
self.dialogLayout.setContentsMargins(8, 8, 8, 8)
|
||||||
self.dialogLayout.setSpacing(8)
|
self.dialogLayout.setSpacing(8)
|
||||||
self.dialogLayout.setObjectName(u'verticalLayout')
|
self.dialogLayout.setObjectName(u'verticalLayout')
|
||||||
self.textEdit = QtGui.QTextEdit(self)
|
self.textEdit = SpellTextEdit(self, False)
|
||||||
self.textEdit.setObjectName(u'textEdit')
|
self.textEdit.setObjectName(u'textEdit')
|
||||||
self.dialogLayout.addWidget(self.textEdit)
|
self.dialogLayout.addWidget(self.textEdit)
|
||||||
self.dialogLayout.addWidget(create_accept_reject_button_box(self))
|
self.dialogLayout.addWidget(create_accept_reject_button_box(self))
|
||||||
|
@ -123,7 +123,7 @@ class Ui_ShortcutListDialog(object):
|
|||||||
|
|
||||||
def retranslateUi(self, shortcutListDialog):
|
def retranslateUi(self, shortcutListDialog):
|
||||||
shortcutListDialog.setWindowTitle(
|
shortcutListDialog.setWindowTitle(
|
||||||
translate('OpenLP.ShortcutListDialog', 'Customize Shortcuts'))
|
translate('OpenLP.ShortcutListDialog', 'Configure Shortcuts'))
|
||||||
self.descriptionLabel.setText(translate('OpenLP.ShortcutListDialog',
|
self.descriptionLabel.setText(translate('OpenLP.ShortcutListDialog',
|
||||||
'Select an action and click one of the buttons below to start '
|
'Select an action and click one of the buttons below to start '
|
||||||
'capturing a new primary or alternate shortcut, respectively.'))
|
'capturing a new primary or alternate shortcut, respectively.'))
|
||||||
|
@ -508,6 +508,11 @@ class SlideController(QtGui.QWidget):
|
|||||||
self.mediabar.setVisible(False)
|
self.mediabar.setVisible(False)
|
||||||
self.toolbar.makeWidgetsInvisible([u'Song Menu'])
|
self.toolbar.makeWidgetsInvisible([u'Song Menu'])
|
||||||
self.toolbar.makeWidgetsInvisible(self.loopList)
|
self.toolbar.makeWidgetsInvisible(self.loopList)
|
||||||
|
# Reset the button
|
||||||
|
self.playSlidesOnce.setChecked(False)
|
||||||
|
self.playSlidesOnce.setIcon(build_icon(u':/media/media_time.png'))
|
||||||
|
self.playSlidesLoop.setChecked(False)
|
||||||
|
self.playSlidesLoop.setIcon(build_icon(u':/media/media_time.png'))
|
||||||
if item.is_text():
|
if item.is_text():
|
||||||
if QtCore.QSettings().value(
|
if QtCore.QSettings().value(
|
||||||
self.parent().songsSettingsSection + u'/display songbar',
|
self.parent().songsSettingsSection + u'/display songbar',
|
||||||
|
@ -43,7 +43,7 @@ class AlertsPlugin(Plugin):
|
|||||||
log.info(u'Alerts Plugin loaded')
|
log.info(u'Alerts Plugin loaded')
|
||||||
|
|
||||||
def __init__(self, plugin_helpers):
|
def __init__(self, plugin_helpers):
|
||||||
Plugin.__init__(self, u'Alerts', plugin_helpers,
|
Plugin.__init__(self, u'alerts', plugin_helpers,
|
||||||
settings_tab_class=AlertsTab)
|
settings_tab_class=AlertsTab)
|
||||||
self.weight = -3
|
self.weight = -3
|
||||||
self.icon_path = u':/plugins/plugin_alerts.png'
|
self.icon_path = u':/plugins/plugin_alerts.png'
|
||||||
|
@ -41,7 +41,7 @@ class BiblePlugin(Plugin):
|
|||||||
log.info(u'Bible Plugin loaded')
|
log.info(u'Bible Plugin loaded')
|
||||||
|
|
||||||
def __init__(self, plugin_helpers):
|
def __init__(self, plugin_helpers):
|
||||||
Plugin.__init__(self, u'Bibles', plugin_helpers,
|
Plugin.__init__(self, u'bibles', plugin_helpers,
|
||||||
BibleMediaItem, BiblesTab)
|
BibleMediaItem, BiblesTab)
|
||||||
self.weight = -9
|
self.weight = -9
|
||||||
self.icon_path = u':/plugins/plugin_bibles.png'
|
self.icon_path = u':/plugins/plugin_bibles.png'
|
||||||
|
@ -395,6 +395,7 @@ class BibleMediaItem(MediaManagerItem):
|
|||||||
log.debug(u'Reloading Bibles')
|
log.debug(u'Reloading Bibles')
|
||||||
self.plugin.manager.reload_bibles()
|
self.plugin.manager.reload_bibles()
|
||||||
self.loadBibles()
|
self.loadBibles()
|
||||||
|
self.updateAutoCompleter()
|
||||||
|
|
||||||
def initialiseAdvancedBible(self, bible):
|
def initialiseAdvancedBible(self, bible):
|
||||||
"""
|
"""
|
||||||
|
@ -46,7 +46,7 @@ class CustomPlugin(Plugin):
|
|||||||
log.info(u'Custom Plugin loaded')
|
log.info(u'Custom Plugin loaded')
|
||||||
|
|
||||||
def __init__(self, plugin_helpers):
|
def __init__(self, plugin_helpers):
|
||||||
Plugin.__init__(self, u'Custom', plugin_helpers,
|
Plugin.__init__(self, u'custom', plugin_helpers,
|
||||||
CustomMediaItem, CustomTab)
|
CustomMediaItem, CustomTab)
|
||||||
self.weight = -5
|
self.weight = -5
|
||||||
self.manager = Manager(u'custom', init_schema)
|
self.manager = Manager(u'custom', init_schema)
|
||||||
|
@ -36,7 +36,7 @@ class ImagePlugin(Plugin):
|
|||||||
log.info(u'Image Plugin loaded')
|
log.info(u'Image Plugin loaded')
|
||||||
|
|
||||||
def __init__(self, plugin_helpers):
|
def __init__(self, plugin_helpers):
|
||||||
Plugin.__init__(self, u'Images', plugin_helpers, ImageMediaItem)
|
Plugin.__init__(self, u'images', plugin_helpers, ImageMediaItem)
|
||||||
self.weight = -7
|
self.weight = -7
|
||||||
self.icon_path = u':/plugins/plugin_images.png'
|
self.icon_path = u':/plugins/plugin_images.png'
|
||||||
self.icon = build_icon(self.icon_path)
|
self.icon = build_icon(self.icon_path)
|
||||||
|
@ -52,6 +52,8 @@ class ImageMediaItem(MediaManagerItem):
|
|||||||
self.hasSearch = True
|
self.hasSearch = True
|
||||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||||
QtCore.SIGNAL(u'live_theme_changed'), self.liveThemeChanged)
|
QtCore.SIGNAL(u'live_theme_changed'), self.liveThemeChanged)
|
||||||
|
# Allow DnD from the desktop
|
||||||
|
self.listView.activateDnD()
|
||||||
|
|
||||||
def retranslateUi(self):
|
def retranslateUi(self):
|
||||||
self.onNewPrompt = translate('ImagePlugin.MediaItem',
|
self.onNewPrompt = translate('ImagePlugin.MediaItem',
|
||||||
@ -131,6 +133,7 @@ class ImageMediaItem(MediaManagerItem):
|
|||||||
icon = self.iconFromFile(imageFile, thumb)
|
icon = self.iconFromFile(imageFile, thumb)
|
||||||
item_name = QtGui.QListWidgetItem(filename)
|
item_name = QtGui.QListWidgetItem(filename)
|
||||||
item_name.setIcon(icon)
|
item_name.setIcon(icon)
|
||||||
|
item_name.setToolTip(imageFile)
|
||||||
item_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(imageFile))
|
item_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(imageFile))
|
||||||
self.listView.addItem(item_name)
|
self.listView.addItem(item_name)
|
||||||
if not initialLoad:
|
if not initialLoad:
|
||||||
|
@ -39,6 +39,8 @@ from PyQt4.phonon import Phonon
|
|||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
CLAPPERBOARD = QtGui.QPixmap(u':/media/media_video.png').toImage()
|
||||||
|
|
||||||
class MediaMediaItem(MediaManagerItem):
|
class MediaMediaItem(MediaManagerItem):
|
||||||
"""
|
"""
|
||||||
This is the custom media manager item for Media Slides.
|
This is the custom media manager item for Media Slides.
|
||||||
@ -48,8 +50,7 @@ class MediaMediaItem(MediaManagerItem):
|
|||||||
def __init__(self, parent, plugin, icon):
|
def __init__(self, parent, plugin, icon):
|
||||||
self.IconPath = u'images/image'
|
self.IconPath = u'images/image'
|
||||||
self.background = False
|
self.background = False
|
||||||
self.PreviewFunction = QtGui.QPixmap(
|
self.PreviewFunction = CLAPPERBOARD
|
||||||
u':/media/media_video.png').toImage()
|
|
||||||
MediaManagerItem.__init__(self, parent, plugin, icon)
|
MediaManagerItem.__init__(self, parent, plugin, icon)
|
||||||
self.singleServiceItem = False
|
self.singleServiceItem = False
|
||||||
self.hasSearch = True
|
self.hasSearch = True
|
||||||
@ -60,6 +61,8 @@ class MediaMediaItem(MediaManagerItem):
|
|||||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||||
QtCore.SIGNAL(u'openlp_phonon_creation'),
|
QtCore.SIGNAL(u'openlp_phonon_creation'),
|
||||||
self.createPhonon)
|
self.createPhonon)
|
||||||
|
# Allow DnD from the desktop
|
||||||
|
self.listView.activateDnD()
|
||||||
|
|
||||||
def retranslateUi(self):
|
def retranslateUi(self):
|
||||||
self.onNewPrompt = translate('MediaPlugin.MediaItem', 'Select Media')
|
self.onNewPrompt = translate('MediaPlugin.MediaItem', 'Select Media')
|
||||||
@ -201,17 +204,17 @@ class MediaMediaItem(MediaManagerItem):
|
|||||||
SettingsManager.set_list(self.settingsSection,
|
SettingsManager.set_list(self.settingsSection,
|
||||||
u'media', self.getFileList())
|
u'media', self.getFileList())
|
||||||
|
|
||||||
def loadList(self, files):
|
def loadList(self, media):
|
||||||
# Sort the themes by its filename considering language specific
|
# Sort the themes by its filename considering language specific
|
||||||
# characters. lower() is needed for windows!
|
# 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())
|
key=lambda filename: os.path.split(unicode(filename))[1].lower())
|
||||||
for file in files:
|
for track in media:
|
||||||
filename = os.path.split(unicode(file))[1]
|
filename = os.path.split(unicode(track))[1]
|
||||||
item_name = QtGui.QListWidgetItem(filename)
|
item_name = QtGui.QListWidgetItem(filename)
|
||||||
img = QtGui.QPixmap(u':/media/media_video.png').toImage()
|
item_name.setIcon(build_icon(CLAPPERBOARD))
|
||||||
item_name.setIcon(build_icon(img))
|
item_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(track))
|
||||||
item_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(file))
|
item_name.setToolTip(track)
|
||||||
self.listView.addItem(item_name)
|
self.listView.addItem(item_name)
|
||||||
|
|
||||||
def createPhonon(self):
|
def createPhonon(self):
|
||||||
|
@ -39,7 +39,7 @@ class MediaPlugin(Plugin):
|
|||||||
log.info(u'%s MediaPlugin loaded', __name__)
|
log.info(u'%s MediaPlugin loaded', __name__)
|
||||||
|
|
||||||
def __init__(self, plugin_helpers):
|
def __init__(self, plugin_helpers):
|
||||||
Plugin.__init__(self, u'Media', plugin_helpers,
|
Plugin.__init__(self, u'media', plugin_helpers,
|
||||||
MediaMediaItem, MediaTab)
|
MediaMediaItem, MediaTab)
|
||||||
self.weight = -6
|
self.weight = -6
|
||||||
self.icon_path = u':/plugins/plugin_media.png'
|
self.icon_path = u':/plugins/plugin_media.png'
|
||||||
|
@ -58,6 +58,8 @@ class PresentationMediaItem(MediaManagerItem):
|
|||||||
self.hasSearch = True
|
self.hasSearch = True
|
||||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||||
QtCore.SIGNAL(u'mediaitem_presentation_rebuild'), self.rebuild)
|
QtCore.SIGNAL(u'mediaitem_presentation_rebuild'), self.rebuild)
|
||||||
|
# Allow DnD from the desktop
|
||||||
|
self.listView.activateDnD()
|
||||||
|
|
||||||
def retranslateUi(self):
|
def retranslateUi(self):
|
||||||
"""
|
"""
|
||||||
@ -205,6 +207,7 @@ class PresentationMediaItem(MediaManagerItem):
|
|||||||
item_name = QtGui.QListWidgetItem(filename)
|
item_name = QtGui.QListWidgetItem(filename)
|
||||||
item_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(file))
|
item_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(file))
|
||||||
item_name.setIcon(icon)
|
item_name.setIcon(icon)
|
||||||
|
item_name.setToolTip(file)
|
||||||
self.listView.addItem(item_name)
|
self.listView.addItem(item_name)
|
||||||
Receiver.send_message(u'cursor_normal')
|
Receiver.send_message(u'cursor_normal')
|
||||||
if not initialLoad:
|
if not initialLoad:
|
||||||
|
@ -52,7 +52,7 @@ class PresentationPlugin(Plugin):
|
|||||||
"""
|
"""
|
||||||
log.debug(u'Initialised')
|
log.debug(u'Initialised')
|
||||||
self.controllers = {}
|
self.controllers = {}
|
||||||
Plugin.__init__(self, u'Presentations', plugin_helpers)
|
Plugin.__init__(self, u'presentations', plugin_helpers)
|
||||||
self.weight = -8
|
self.weight = -8
|
||||||
self.icon_path = u':/plugins/plugin_presentations.png'
|
self.icon_path = u':/plugins/plugin_presentations.png'
|
||||||
self.icon = build_icon(self.icon_path)
|
self.icon = build_icon(self.icon_path)
|
||||||
|
@ -150,13 +150,11 @@ class HttpResponse(object):
|
|||||||
|
|
||||||
class HttpServer(object):
|
class HttpServer(object):
|
||||||
"""
|
"""
|
||||||
Ability to control OpenLP via a webbrowser
|
Ability to control OpenLP via a web browser.
|
||||||
e.g. http://localhost:4316/send/slidecontroller_live_next
|
|
||||||
http://localhost:4316/send/alerts_text?q=your%20alert%20text
|
|
||||||
"""
|
"""
|
||||||
def __init__(self, plugin):
|
def __init__(self, plugin):
|
||||||
"""
|
"""
|
||||||
Initialise the httpserver, and start the server
|
Initialise the httpserver, and start the server.
|
||||||
"""
|
"""
|
||||||
log.debug(u'Initialise httpserver')
|
log.debug(u'Initialise httpserver')
|
||||||
self.plugin = plugin
|
self.plugin = plugin
|
||||||
@ -170,9 +168,9 @@ class HttpServer(object):
|
|||||||
|
|
||||||
def start_tcp(self):
|
def start_tcp(self):
|
||||||
"""
|
"""
|
||||||
Start the http server, use the port in the settings default to 4316
|
Start the http server, use the port in the settings default to 4316.
|
||||||
Listen out for slide and song changes so they can be broadcast to
|
Listen out for slide and song changes so they can be broadcast to
|
||||||
clients. Listen out for socket connections
|
clients. Listen out for socket connections.
|
||||||
"""
|
"""
|
||||||
log.debug(u'Start TCP server')
|
log.debug(u'Start TCP server')
|
||||||
port = QtCore.QSettings().value(
|
port = QtCore.QSettings().value(
|
||||||
@ -195,20 +193,20 @@ class HttpServer(object):
|
|||||||
|
|
||||||
def slide_change(self, row):
|
def slide_change(self, row):
|
||||||
"""
|
"""
|
||||||
Slide change listener. Store the item and tell the clients
|
Slide change listener. Store the item and tell the clients.
|
||||||
"""
|
"""
|
||||||
self.current_slide = row
|
self.current_slide = row
|
||||||
|
|
||||||
def item_change(self, items):
|
def item_change(self, items):
|
||||||
"""
|
"""
|
||||||
Item (song) change listener. Store the slide and tell the clients
|
Item (song) change listener. Store the slide and tell the clients.
|
||||||
"""
|
"""
|
||||||
self.current_item = items[0]
|
self.current_item = items[0]
|
||||||
|
|
||||||
def new_connection(self):
|
def new_connection(self):
|
||||||
"""
|
"""
|
||||||
A new http connection has been made. Create a client object to handle
|
A new http connection has been made. Create a client object to handle
|
||||||
communication
|
communication.
|
||||||
"""
|
"""
|
||||||
log.debug(u'new http connection')
|
log.debug(u'new http connection')
|
||||||
socket = self.server.nextPendingConnection()
|
socket = self.server.nextPendingConnection()
|
||||||
@ -225,15 +223,16 @@ class HttpServer(object):
|
|||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
"""
|
"""
|
||||||
Close down the http server
|
Close down the http server.
|
||||||
"""
|
"""
|
||||||
log.debug(u'close http server')
|
log.debug(u'close http server')
|
||||||
self.server.close()
|
self.server.close()
|
||||||
|
|
||||||
|
|
||||||
class HttpConnection(object):
|
class HttpConnection(object):
|
||||||
"""
|
"""
|
||||||
A single connection, this handles communication between the server
|
A single connection, this handles communication between the server
|
||||||
and the client
|
and the client.
|
||||||
"""
|
"""
|
||||||
def __init__(self, parent, socket):
|
def __init__(self, parent, socket):
|
||||||
"""
|
"""
|
||||||
@ -287,9 +286,12 @@ class HttpConnection(object):
|
|||||||
"""
|
"""
|
||||||
self.template_vars = {
|
self.template_vars = {
|
||||||
'app_title': translate('RemotePlugin.Mobile', 'OpenLP 2.0 Remote'),
|
'app_title': translate('RemotePlugin.Mobile', 'OpenLP 2.0 Remote'),
|
||||||
'stage_title': translate('RemotePlugin.Mobile', 'OpenLP 2.0 Stage View'),
|
'stage_title': translate('RemotePlugin.Mobile',
|
||||||
'service_manager': translate('RemotePlugin.Mobile', 'Service Manager'),
|
'OpenLP 2.0 Stage View'),
|
||||||
'slide_controller': translate('RemotePlugin.Mobile', 'Slide Controller'),
|
'service_manager': translate('RemotePlugin.Mobile',
|
||||||
|
'Service Manager'),
|
||||||
|
'slide_controller': translate('RemotePlugin.Mobile',
|
||||||
|
'Slide Controller'),
|
||||||
'alerts': translate('RemotePlugin.Mobile', 'Alerts'),
|
'alerts': translate('RemotePlugin.Mobile', 'Alerts'),
|
||||||
'search': translate('RemotePlugin.Mobile', 'Search'),
|
'search': translate('RemotePlugin.Mobile', 'Search'),
|
||||||
'back': translate('RemotePlugin.Mobile', 'Back'),
|
'back': translate('RemotePlugin.Mobile', 'Back'),
|
||||||
@ -301,7 +303,8 @@ class HttpConnection(object):
|
|||||||
'text': translate('RemotePlugin.Mobile', 'Text'),
|
'text': translate('RemotePlugin.Mobile', 'Text'),
|
||||||
'show_alert': translate('RemotePlugin.Mobile', 'Show Alert'),
|
'show_alert': translate('RemotePlugin.Mobile', 'Show Alert'),
|
||||||
'go_live': translate('RemotePlugin.Mobile', 'Go Live'),
|
'go_live': translate('RemotePlugin.Mobile', 'Go Live'),
|
||||||
'add_to_service': translate('RemotePlugin.Mobile', 'Add To Service'),
|
'add_to_service': translate('RemotePlugin.Mobile',
|
||||||
|
'Add to Service'),
|
||||||
'no_results': translate('RemotePlugin.Mobile', 'No Results'),
|
'no_results': translate('RemotePlugin.Mobile', 'No Results'),
|
||||||
'options': translate('RemotePlugin.Mobile', 'Options')
|
'options': translate('RemotePlugin.Mobile', 'Options')
|
||||||
}
|
}
|
||||||
@ -397,7 +400,7 @@ class HttpConnection(object):
|
|||||||
if self.parent.current_item else u''
|
if self.parent.current_item else u''
|
||||||
}
|
}
|
||||||
return HttpResponse(json.dumps({u'results': result}),
|
return HttpResponse(json.dumps({u'results': result}),
|
||||||
{u'Content-Type': u'application/json'})
|
{u'Content-Type': u'application/json'})
|
||||||
|
|
||||||
def display(self, action):
|
def display(self, action):
|
||||||
"""
|
"""
|
||||||
@ -483,10 +486,11 @@ class HttpConnection(object):
|
|||||||
|
|
||||||
def pluginInfo(self, action):
|
def pluginInfo(self, action):
|
||||||
"""
|
"""
|
||||||
Return plugin related information, based on the action
|
Return plugin related information, based on the action.
|
||||||
|
|
||||||
``action`` - The action to perform
|
``action``
|
||||||
if 'search' return a list of plugin names which support search
|
The action to perform. If *search* return a list of plugin names
|
||||||
|
which support search.
|
||||||
"""
|
"""
|
||||||
if action == u'search':
|
if action == u'search':
|
||||||
searches = []
|
searches = []
|
||||||
@ -501,10 +505,10 @@ class HttpConnection(object):
|
|||||||
|
|
||||||
def search(self, type):
|
def search(self, type):
|
||||||
"""
|
"""
|
||||||
Return a list of items that match the search text
|
Return a list of items that match the search text.
|
||||||
|
|
||||||
``type``
|
``type``
|
||||||
The plugin name to search in.
|
The plugin name to search in.
|
||||||
"""
|
"""
|
||||||
text = json.loads(self.url_params[u'data'][0])[u'request'][u'text']
|
text = json.loads(self.url_params[u'data'][0])[u'request'][u'text']
|
||||||
plugin = self.parent.plugin.pluginManager.get_plugin_by_name(type)
|
plugin = self.parent.plugin.pluginManager.get_plugin_by_name(type)
|
||||||
@ -528,7 +532,7 @@ class HttpConnection(object):
|
|||||||
|
|
||||||
def add_to_service(self, type):
|
def add_to_service(self, type):
|
||||||
"""
|
"""
|
||||||
Add item of type ``type`` to the end of the service
|
Add item of type ``type`` to the end of the service.
|
||||||
"""
|
"""
|
||||||
id = json.loads(self.url_params[u'data'][0])[u'request'][u'id']
|
id = json.loads(self.url_params[u'data'][0])[u'request'][u'id']
|
||||||
plugin = self.parent.plugin.pluginManager.get_plugin_by_name(type)
|
plugin = self.parent.plugin.pluginManager.get_plugin_by_name(type)
|
||||||
|
@ -39,7 +39,7 @@ class RemotesPlugin(Plugin):
|
|||||||
"""
|
"""
|
||||||
remotes constructor
|
remotes constructor
|
||||||
"""
|
"""
|
||||||
Plugin.__init__(self, u'Remotes', plugin_helpers,
|
Plugin.__init__(self, u'remotes', plugin_helpers,
|
||||||
settings_tab_class=RemoteTab)
|
settings_tab_class=RemoteTab)
|
||||||
self.icon_path = u':/plugins/plugin_remote.png'
|
self.icon_path = u':/plugins/plugin_remote.png'
|
||||||
self.icon = build_icon(self.icon_path)
|
self.icon = build_icon(self.icon_path)
|
||||||
|
@ -90,7 +90,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
|||||||
self.onVerseListViewPressed)
|
self.onVerseListViewPressed)
|
||||||
QtCore.QObject.connect(self.themeAddButton,
|
QtCore.QObject.connect(self.themeAddButton,
|
||||||
QtCore.SIGNAL(u'clicked()'),
|
QtCore.SIGNAL(u'clicked()'),
|
||||||
self.mediaitem.plugin.renderer.theme_manager.onAddTheme)
|
self.mediaitem.plugin.renderer.themeManager.onAddTheme)
|
||||||
QtCore.QObject.connect(self.maintenanceButton,
|
QtCore.QObject.connect(self.maintenanceButton,
|
||||||
QtCore.SIGNAL(u'clicked()'), self.onMaintenanceButtonClicked)
|
QtCore.SIGNAL(u'clicked()'), self.onMaintenanceButtonClicked)
|
||||||
QtCore.QObject.connect(Receiver.get_receiver(),
|
QtCore.QObject.connect(Receiver.get_receiver(),
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
The :mod:`songexportform` module provides the wizard for exporting songs to the
|
The :mod:`songexportform` module provides the wizard for exporting songs to the
|
||||||
OpenLyrics format.
|
OpenLyrics format.
|
||||||
"""
|
"""
|
||||||
|
import locale
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from PyQt4 import QtCore, QtGui
|
from PyQt4 import QtCore, QtGui
|
||||||
@ -249,6 +250,7 @@ class SongExportForm(OpenLPWizard):
|
|||||||
# Load the list of songs.
|
# Load the list of songs.
|
||||||
Receiver.send_message(u'cursor_busy')
|
Receiver.send_message(u'cursor_busy')
|
||||||
songs = self.plugin.manager.get_all_objects(Song)
|
songs = self.plugin.manager.get_all_objects(Song)
|
||||||
|
songs.sort(cmp=locale.strcoll, key=lambda song: song.title.lower())
|
||||||
for song in songs:
|
for song in songs:
|
||||||
authors = u', '.join([author.display_name
|
authors = u', '.join([author.display_name
|
||||||
for author in song.authors])
|
for author in song.authors])
|
||||||
|
@ -699,7 +699,8 @@ class SongImportForm(OpenLPWizard):
|
|||||||
elif source_format == SongFormat.OpenLP1:
|
elif source_format == SongFormat.OpenLP1:
|
||||||
# Import an openlp.org database
|
# Import an openlp.org database
|
||||||
importer = self.plugin.importSongs(SongFormat.OpenLP1,
|
importer = self.plugin.importSongs(SongFormat.OpenLP1,
|
||||||
filename=unicode(self.openLP1FilenameEdit.text())
|
filename=unicode(self.openLP1FilenameEdit.text()),
|
||||||
|
plugin=self.plugin
|
||||||
)
|
)
|
||||||
elif source_format == SongFormat.OpenLyrics:
|
elif source_format == SongFormat.OpenLyrics:
|
||||||
# Import OpenLyrics songs
|
# Import OpenLyrics songs
|
||||||
|
@ -57,6 +57,8 @@ class OpenLP1SongImport(SongImport):
|
|||||||
The database providing the data to import.
|
The database providing the data to import.
|
||||||
"""
|
"""
|
||||||
SongImport.__init__(self, manager, **kwargs)
|
SongImport.__init__(self, manager, **kwargs)
|
||||||
|
self.available_themes = \
|
||||||
|
kwargs[u'plugin'].formparent.themeManagerContents.getThemes()
|
||||||
|
|
||||||
def do_import(self):
|
def do_import(self):
|
||||||
"""
|
"""
|
||||||
@ -70,27 +72,34 @@ class OpenLP1SongImport(SongImport):
|
|||||||
encoding = self.get_encoding()
|
encoding = self.get_encoding()
|
||||||
if not encoding:
|
if not encoding:
|
||||||
return
|
return
|
||||||
# Connect to the database
|
# Connect to the database.
|
||||||
connection = sqlite.connect(self.import_source, mode=0444,
|
connection = sqlite.connect(self.import_source, mode=0444,
|
||||||
encoding=(encoding, 'replace'))
|
encoding=(encoding, 'replace'))
|
||||||
cursor = connection.cursor()
|
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 '
|
cursor.execute(u'SELECT name FROM sqlite_master '
|
||||||
u'WHERE type = \'table\' AND name = \'tracks\'')
|
u'WHERE type = \'table\' AND name = \'tracks\'')
|
||||||
new_db = len(cursor.fetchall()) > 0
|
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'-- types int, unicode')
|
||||||
cursor.execute(u'SELECT authorid, authorname FROM authors')
|
cursor.execute(u'SELECT authorid, authorname FROM authors')
|
||||||
authors = cursor.fetchall()
|
authors = cursor.fetchall()
|
||||||
if new_db:
|
if new_db:
|
||||||
# "cache" our list of tracks
|
# "cache" our list of tracks.
|
||||||
cursor.execute(u'-- types int, unicode')
|
cursor.execute(u'-- types int, unicode')
|
||||||
cursor.execute(u'SELECT trackid, fulltrackname FROM tracks')
|
cursor.execute(u'SELECT trackid, fulltrackname FROM tracks')
|
||||||
tracks = cursor.fetchall()
|
tracks = cursor.fetchall()
|
||||||
# Import the songs
|
# "cache" our list of themes.
|
||||||
cursor.execute(u'-- types int, unicode, unicode, unicode')
|
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, '
|
cursor.execute(u'SELECT songid, songtitle, lyrics || \'\' AS lyrics, '
|
||||||
u'copyrightinfo FROM songs')
|
u'copyrightinfo, settingsid FROM songs')
|
||||||
songs = cursor.fetchall()
|
songs = cursor.fetchall()
|
||||||
self.import_wizard.progressBar.setMaximum(len(songs))
|
self.import_wizard.progressBar.setMaximum(len(songs))
|
||||||
for song in songs:
|
for song in songs:
|
||||||
@ -101,8 +110,12 @@ class OpenLP1SongImport(SongImport):
|
|||||||
self.title = song[1]
|
self.title = song[1]
|
||||||
lyrics = song[2].replace(u'\r\n', u'\n')
|
lyrics = song[2].replace(u'\r\n', u'\n')
|
||||||
self.add_copyright(song[3])
|
self.add_copyright(song[3])
|
||||||
|
if themes.has_key(song[4]):
|
||||||
|
self.theme_name = themes[song[4]]
|
||||||
verses = lyrics.split(u'\n\n')
|
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'-- types int')
|
||||||
cursor.execute(u'SELECT authorid FROM songauthors '
|
cursor.execute(u'SELECT authorid FROM songauthors '
|
||||||
u'WHERE songid = %s' % song_id)
|
u'WHERE songid = %s' % song_id)
|
||||||
@ -137,12 +150,12 @@ class OpenLP1SongImport(SongImport):
|
|||||||
"""
|
"""
|
||||||
Detect character encoding of an openlp.org 1.x song database.
|
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)
|
connection = sqlite.connect(self.import_source, mode=0444)
|
||||||
cursor = connection.cursor()
|
cursor = connection.cursor()
|
||||||
|
|
||||||
detector = UniversalDetector()
|
detector = UniversalDetector()
|
||||||
# detect charset by authors
|
# Detect charset by authors.
|
||||||
cursor.execute(u'SELECT authorname FROM authors')
|
cursor.execute(u'SELECT authorname FROM authors')
|
||||||
authors = cursor.fetchall()
|
authors = cursor.fetchall()
|
||||||
for author in authors:
|
for author in authors:
|
||||||
@ -150,7 +163,7 @@ class OpenLP1SongImport(SongImport):
|
|||||||
if detector.done:
|
if detector.done:
|
||||||
detector.close()
|
detector.close()
|
||||||
return detector.result[u'encoding']
|
return detector.result[u'encoding']
|
||||||
# detect charset by songs
|
# Detect charset by songs.
|
||||||
cursor.execute(u'SELECT songtitle, copyrightinfo, '
|
cursor.execute(u'SELECT songtitle, copyrightinfo, '
|
||||||
u'lyrics || \'\' AS lyrics FROM songs')
|
u'lyrics || \'\' AS lyrics FROM songs')
|
||||||
songs = cursor.fetchall()
|
songs = cursor.fetchall()
|
||||||
@ -160,7 +173,7 @@ class OpenLP1SongImport(SongImport):
|
|||||||
if detector.done:
|
if detector.done:
|
||||||
detector.close()
|
detector.close()
|
||||||
return detector.result[u'encoding']
|
return detector.result[u'encoding']
|
||||||
# detect charset by songs
|
# Detect charset by songs.
|
||||||
cursor.execute(u'SELECT name FROM sqlite_master '
|
cursor.execute(u'SELECT name FROM sqlite_master '
|
||||||
u'WHERE type = \'table\' AND name = \'tracks\'')
|
u'WHERE type = \'table\' AND name = \'tracks\'')
|
||||||
if len(cursor.fetchall()) > 0:
|
if len(cursor.fetchall()) > 0:
|
||||||
|
@ -102,7 +102,6 @@ class SongShowPlusImport(SongImport):
|
|||||||
if not isinstance(self.import_source, list):
|
if not isinstance(self.import_source, list):
|
||||||
return
|
return
|
||||||
self.import_wizard.progressBar.setMaximum(len(self.import_source))
|
self.import_wizard.progressBar.setMaximum(len(self.import_source))
|
||||||
|
|
||||||
for file in self.import_source:
|
for file in self.import_source:
|
||||||
self.sspVerseOrderList = []
|
self.sspVerseOrderList = []
|
||||||
otherCount = 0
|
otherCount = 0
|
||||||
@ -111,7 +110,6 @@ class SongShowPlusImport(SongImport):
|
|||||||
self.import_wizard.incrementProgressBar(
|
self.import_wizard.incrementProgressBar(
|
||||||
WizardStrings.ImportingType % file_name, 0)
|
WizardStrings.ImportingType % file_name, 0)
|
||||||
songData = open(file, 'rb')
|
songData = open(file, 'rb')
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
blockKey, = struct.unpack("I", songData.read(4))
|
blockKey, = struct.unpack("I", songData.read(4))
|
||||||
# The file ends with 4 NUL's
|
# The file ends with 4 NUL's
|
||||||
@ -126,8 +124,9 @@ class SongShowPlusImport(SongImport):
|
|||||||
songData.read(2))
|
songData.read(2))
|
||||||
verseName = songData.read(verseNameLength)
|
verseName = songData.read(verseNameLength)
|
||||||
lengthDescriptorSize, = struct.unpack("B", songData.read(1))
|
lengthDescriptorSize, = struct.unpack("B", songData.read(1))
|
||||||
|
log.debug(lengthDescriptorSize)
|
||||||
# Detect if/how long the length descriptor is
|
# Detect if/how long the length descriptor is
|
||||||
if lengthDescriptorSize == 12:
|
if lengthDescriptorSize == 12 or lengthDescriptorSize == 20:
|
||||||
lengthDescriptor, = struct.unpack("I", songData.read(4))
|
lengthDescriptor, = struct.unpack("I", songData.read(4))
|
||||||
elif lengthDescriptorSize == 2:
|
elif lengthDescriptorSize == 2:
|
||||||
lengthDescriptor = 1
|
lengthDescriptor = 1
|
||||||
@ -135,6 +134,7 @@ class SongShowPlusImport(SongImport):
|
|||||||
lengthDescriptor = 0
|
lengthDescriptor = 0
|
||||||
else:
|
else:
|
||||||
lengthDescriptor, = struct.unpack("B", songData.read(1))
|
lengthDescriptor, = struct.unpack("B", songData.read(1))
|
||||||
|
log.debug(lengthDescriptorSize)
|
||||||
data = songData.read(lengthDescriptor)
|
data = songData.read(lengthDescriptor)
|
||||||
if blockKey == TITLE:
|
if blockKey == TITLE:
|
||||||
self.title = unicode(data, u'cp1252')
|
self.title = unicode(data, u'cp1252')
|
||||||
|
@ -57,7 +57,7 @@ class SongsPlugin(Plugin):
|
|||||||
"""
|
"""
|
||||||
Create and set up the Songs plugin.
|
Create and set up the Songs plugin.
|
||||||
"""
|
"""
|
||||||
Plugin.__init__(self, u'Songs', plugin_helpers, SongMediaItem, SongsTab)
|
Plugin.__init__(self, u'songs', plugin_helpers, SongMediaItem, SongsTab)
|
||||||
self.weight = -10
|
self.weight = -10
|
||||||
self.manager = Manager(u'songs', init_schema)
|
self.manager = Manager(u'songs', init_schema)
|
||||||
self.icon_path = u':/plugins/plugin_songs.png'
|
self.icon_path = u':/plugins/plugin_songs.png'
|
||||||
|
@ -45,7 +45,7 @@ class SongUsagePlugin(Plugin):
|
|||||||
log.info(u'SongUsage Plugin loaded')
|
log.info(u'SongUsage Plugin loaded')
|
||||||
|
|
||||||
def __init__(self, plugin_helpers):
|
def __init__(self, plugin_helpers):
|
||||||
Plugin.__init__(self, u'SongUsage', plugin_helpers)
|
Plugin.__init__(self, u'songusage', plugin_helpers)
|
||||||
self.weight = -4
|
self.weight = -4
|
||||||
self.icon = build_icon(u':/plugins/plugin_songusage.png')
|
self.icon = build_icon(u':/plugins/plugin_songusage.png')
|
||||||
self.activeIcon = build_icon(u':/songusage/song_usage_active.png')
|
self.activeIcon = build_icon(u':/songusage/song_usage_active.png')
|
||||||
@ -91,8 +91,8 @@ class SongUsagePlugin(Plugin):
|
|||||||
self.toolsMenu.addAction(self.songUsageMenu.menuAction())
|
self.toolsMenu.addAction(self.songUsageMenu.menuAction())
|
||||||
self.songUsageMenu.addAction(self.songUsageStatus)
|
self.songUsageMenu.addAction(self.songUsageStatus)
|
||||||
self.songUsageMenu.addSeparator()
|
self.songUsageMenu.addSeparator()
|
||||||
self.songUsageMenu.addAction(self.songUsageDelete)
|
|
||||||
self.songUsageMenu.addAction(self.songUsageReport)
|
self.songUsageMenu.addAction(self.songUsageReport)
|
||||||
|
self.songUsageMenu.addAction(self.songUsageDelete)
|
||||||
self.songUsageActiveButton = QtGui.QToolButton(
|
self.songUsageActiveButton = QtGui.QToolButton(
|
||||||
self.formparent.statusBar)
|
self.formparent.statusBar)
|
||||||
self.songUsageActiveButton.setCheckable(True)
|
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">
|
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
<plist version="1.0">
|
<plist version="1.0">
|
||||||
<dict>
|
<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>
|
<key>CFBundleIdentifier</key>
|
||||||
<string>org.openlp</string>
|
<string>org.openlp</string>
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
|
@ -48,7 +48,7 @@ on run
|
|||||||
set theViewOptions to the icon view options of container window
|
set theViewOptions to the icon view options of container window
|
||||||
set arrangement of theViewOptions to not arranged
|
set arrangement of theViewOptions to not arranged
|
||||||
set icon size of theViewOptions to 128
|
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
|
if not exists file "Applications" then
|
||||||
make new alias file at container window to POSIX file "/Applications" with properties {name:"Applications"}
|
make new alias file at container window to POSIX file "/Applications" with properties {name:"Applications"}
|
||||||
end if
|
end if
|
||||||
|
@ -49,15 +49,19 @@ on run
|
|||||||
set theViewOptions to the icon view options of container window
|
set theViewOptions to the icon view options of container window
|
||||||
set arrangement of theViewOptions to not arranged
|
set arrangement of theViewOptions to not arranged
|
||||||
set icon size of theViewOptions to 128
|
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"
|
||||||
make new alias file at container window to POSIX file "/Applications" with properties {name:"Applications"}
|
if not exists file "Applications" then
|
||||||
delay 5
|
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 "%s" of container window to {160, 200}
|
||||||
set position of item ".Trashes" of container window to {100, 500}
|
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 ".DS_Store" of container window to {400, 500}
|
||||||
set position of item "Applications" of container window to {550, 200}
|
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}
|
set position of item ".fseventsd" of container window to {300, 500}
|
||||||
if exists POSIX file ".SymAVx86QSFile" then
|
if exists POSIX file ".SymAVx86QSFile" then
|
||||||
set position of item ".SymAVx86QSFile" of container window to {600, 500}
|
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):
|
def build_application(settings, app_name_lower, app_dir):
|
||||||
logging.info('[%s] now building the app with pyinstaller at "%s"...',
|
logging.info('[%s] now building the app with pyinstaller at "%s"...',
|
||||||
script_name, settings['pyinstaller_basedir'])
|
script_name, settings['pyinstaller_basedir'])
|
||||||
result = os.system('python %s/pyinstaller.py openlp.spec' \
|
full_python_dir = os.path.join('/opt/local/Library/Frameworks',
|
||||||
% settings['pyinstaller_basedir'])
|
'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):
|
if (result != 0):
|
||||||
logging.error('[%s] The pyinstaller build reported an error, cannot \
|
logging.error('[%s] The pyinstaller build reported an error, cannot \
|
||||||
continue!', script_name)
|
continue!', script_name)
|
||||||
@ -219,10 +223,10 @@ def create_dmg(settings):
|
|||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
logging.info('[%s] copying the background image...', script_name)
|
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'
|
result = os.system('CpMac %s %s'
|
||||||
% (settings['installer_backgroundimage_file'],
|
% (settings['installer_backgroundimage_file'],
|
||||||
volume_basedir + '/.installer-background.png'))
|
volume_basedir + '/.background/installer-background.png'))
|
||||||
if (result != 0):
|
if (result != 0):
|
||||||
logging.error('[%s] could not copy the background image, dmg creation\
|
logging.error('[%s] could not copy the background image, dmg creation\
|
||||||
failed!', script_name)
|
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]
|
||||||
openlp_appname = OpenLP
|
openlp_appname = OpenLP
|
||||||
openlp_dmgname = OpenLP-1.9.4-bzrXXXX
|
openlp_dmgname = OpenLP-1.9.6-bzrXXXX
|
||||||
openlp_version = XXXX
|
openlp_version = XXXX
|
||||||
openlp_basedir = /Users/openlp/trunk
|
openlp_basedir = /Users/openlp/repo/trunk
|
||||||
openlp_icon_file = openlp-logo-with-text.icns
|
openlp_icon_file = openlp-logo-with-text.icns
|
||||||
openlp_dmg_icon_file = openlp-logo-420x420.png
|
openlp_dmg_icon_file = openlp-logo-420x420.png
|
||||||
installer_backgroundimage_file = installation-background.png
|
installer_backgroundimage_file = installation-background.png
|
@ -1,5 +1,5 @@
|
|||||||
# -*- mode: python -*-
|
# -*- 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'])
|
pathex=['%(pyinstaller_basedir)s'], hookspath=['%(openlp_basedir)s/resources/pyinstaller'])
|
||||||
pyz = PYZ(a.pure)
|
pyz = PYZ(a.pure)
|
||||||
exe = EXE(pyz,
|
exe = EXE(pyz,
|
||||||
|
@ -46,12 +46,6 @@ PyEnchant
|
|||||||
Inno Setup 5
|
Inno Setup 5
|
||||||
Inno Setup should be installed into "C:\%PROGRAMFILES%\Inno Setup 5"
|
Inno Setup should be installed into "C:\%PROGRAMFILES%\Inno Setup 5"
|
||||||
|
|
||||||
UPX
|
|
||||||
This is used to compress DLLs and EXEs so that they take up less space, but
|
|
||||||
still function exactly the same. To install UPX, download it from
|
|
||||||
http://upx.sourceforge.net/, extract it into C:\%PROGRAMFILES%\UPX, and then
|
|
||||||
add that directory to your PATH environment variable.
|
|
||||||
|
|
||||||
Sphinx
|
Sphinx
|
||||||
This is used to build the documentation. The documentation trunk must be at
|
This is used to build the documentation. The documentation trunk must be at
|
||||||
the same directory level as Openlp trunk and named "documentation"
|
the same directory level as Openlp trunk and named "documentation"
|
||||||
@ -179,6 +173,7 @@ def run_pyinstaller():
|
|||||||
pyinstaller = Popen((python_exe, pyi_build,
|
pyinstaller = Popen((python_exe, pyi_build,
|
||||||
u'--noconfirm',
|
u'--noconfirm',
|
||||||
u'--windowed',
|
u'--windowed',
|
||||||
|
u'--noupx',
|
||||||
u'-o', branch_path,
|
u'-o', branch_path,
|
||||||
u'-i', win32_icon,
|
u'-i', win32_icon,
|
||||||
u'-p', branch_path,
|
u'-p', branch_path,
|
||||||
|
Loading…
Reference in New Issue
Block a user