forked from openlp/openlp
Head
This commit is contained in:
commit
220e40c306
@ -554,4 +554,4 @@ class MediaManagerItem(QtGui.QWidget):
|
||||
item_id = remoteItem
|
||||
else:
|
||||
item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0]
|
||||
return item_id
|
||||
return item_id
|
||||
|
@ -222,13 +222,13 @@ class Renderer(object):
|
||||
# Songs and Custom
|
||||
if item.is_capable(ItemCapabilities.AllowsVirtualSplit):
|
||||
# Do not forget the line breaks !
|
||||
slides = text.split(u'\n[---]\n')
|
||||
slides = text.split(u'[---]')
|
||||
pages = []
|
||||
for slide in slides:
|
||||
lines = self._lines(slide)
|
||||
lines = slide.strip(u'\n').split(u'\n')
|
||||
new_pages = self._paginate_slide(lines, line_break,
|
||||
self.force_page)
|
||||
pages.extend([page for page in new_pages])
|
||||
pages.extend(new_pages)
|
||||
# Bibles
|
||||
elif item.is_capable(ItemCapabilities.AllowsWordSplit):
|
||||
pages = self._paginate_slide_words(text, line_break)
|
||||
@ -341,12 +341,14 @@ class Renderer(object):
|
||||
if force_page and line_count > 0:
|
||||
Receiver.send_message(u'theme_line_count', line_count)
|
||||
line_count = -1
|
||||
html_text = html_text.rstrip(u'<br>')
|
||||
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
|
||||
html_text = html_text.rstrip(u'<br>')
|
||||
while html_text.endswith(u'<br>'):
|
||||
html_text = html_text[:-4]
|
||||
formatted.append(html_text)
|
||||
log.debug(u'_paginate_slide - End')
|
||||
return formatted
|
||||
@ -371,7 +373,7 @@ class Renderer(object):
|
||||
formatted = []
|
||||
previous_html = u''
|
||||
previous_raw = u''
|
||||
lines = self._lines(text)
|
||||
lines = text.split(u'\n')
|
||||
for line in lines:
|
||||
styled_line = expand_tags(line)
|
||||
html = self.page_shell + previous_html + styled_line + HTML_END
|
||||
@ -385,7 +387,8 @@ class Renderer(object):
|
||||
self.web.setHtml(html)
|
||||
if self.web_frame.contentsSize().height() <= \
|
||||
self.page_height:
|
||||
previous_raw = previous_raw.rstrip(u'<br>')
|
||||
while previous_raw.endswith(u'<br>'):
|
||||
previous_raw = previous_raw[:-4]
|
||||
formatted.append(previous_raw)
|
||||
previous_html = u''
|
||||
previous_raw = u''
|
||||
@ -408,7 +411,8 @@ class Renderer(object):
|
||||
# Text too long so go to next page
|
||||
if self.web_frame.contentsSize().height() > \
|
||||
self.page_height:
|
||||
previous_raw = previous_raw.rstrip(u'<br>')
|
||||
while previous_raw.endswith(u'<br>'):
|
||||
previous_raw = previous_raw[:-4]
|
||||
formatted.append(previous_raw)
|
||||
previous_html = u''
|
||||
previous_raw = u''
|
||||
@ -419,36 +423,20 @@ class Renderer(object):
|
||||
else:
|
||||
previous_html += styled_line + line_end
|
||||
previous_raw += line + line_end
|
||||
previous_raw = previous_raw.rstrip(u'<br>')
|
||||
while previous_raw.endswith(u'<br>'):
|
||||
previous_raw = previous_raw[:-4]
|
||||
formatted.append(previous_raw)
|
||||
log.debug(u'_paginate_slide_words - End')
|
||||
return formatted
|
||||
|
||||
def _lines(self, text):
|
||||
"""
|
||||
Split the slide up by physical line
|
||||
"""
|
||||
# this parse we do not want to use this so remove it
|
||||
verses_text = text.split(u'\n')
|
||||
text = []
|
||||
for verse in verses_text:
|
||||
lines = verse.split(u'\n')
|
||||
text.extend([line for line in lines])
|
||||
|
||||
return text
|
||||
|
||||
def _words_split(self, line):
|
||||
"""
|
||||
Split the slide up by word so can wrap better
|
||||
"""
|
||||
# this parse we are to be wordy
|
||||
line = line.replace(u'\n', u' ')
|
||||
verses_text = line.split(u' ')
|
||||
text = []
|
||||
for verse in verses_text:
|
||||
lines = verse.split(u' ')
|
||||
text.extend([line + u' ' for line in lines])
|
||||
return text
|
||||
words = line.split(u' ')
|
||||
return [word + u' ' for word in words]
|
||||
|
||||
def _lines_split(self, text):
|
||||
"""
|
||||
@ -457,9 +445,4 @@ class Renderer(object):
|
||||
# this parse we do not want to use this so remove it
|
||||
text = text.replace(u'\n[---]', u'')
|
||||
lines = text.split(u'\n')
|
||||
real_lines = []
|
||||
for line in lines:
|
||||
line = line.replace(u'[---]', u'')
|
||||
sub_lines = line.split(u'\n')
|
||||
real_lines.extend([sub_line for sub_line in sub_lines])
|
||||
return real_lines
|
||||
return [line.replace(u'[---]', u'') for line in lines]
|
||||
|
@ -122,12 +122,17 @@ class Ui_MainWindow(object):
|
||||
self.HelpMenu = QtGui.QMenu(self.MenuBar)
|
||||
self.HelpMenu.setObjectName(u'HelpMenu')
|
||||
mainWindow.setMenuBar(self.MenuBar)
|
||||
self.StatusBar = QtGui.QStatusBar(mainWindow)
|
||||
self.StatusBar.setObjectName(u'StatusBar')
|
||||
mainWindow.setStatusBar(self.StatusBar)
|
||||
self.DefaultThemeLabel = QtGui.QLabel(self.StatusBar)
|
||||
self.DefaultThemeLabel.setObjectName(u'DefaultThemeLabel')
|
||||
self.StatusBar.addPermanentWidget(self.DefaultThemeLabel)
|
||||
self.statusBar = QtGui.QStatusBar(mainWindow)
|
||||
self.statusBar.setObjectName(u'statusBar')
|
||||
mainWindow.setStatusBar(self.statusBar)
|
||||
self.loadProgressBar = QtGui.QProgressBar(self.statusBar)
|
||||
self.loadProgressBar.setObjectName(u'loadProgressBar')
|
||||
self.statusBar.addPermanentWidget(self.loadProgressBar)
|
||||
self.loadProgressBar.hide()
|
||||
self.loadProgressBar.setValue(0)
|
||||
self.defaultThemeLabel = QtGui.QLabel(self.statusBar)
|
||||
self.defaultThemeLabel.setObjectName(u'defaultThemeLabel')
|
||||
self.statusBar.addPermanentWidget(self.defaultThemeLabel)
|
||||
# Create the MediaManager
|
||||
self.mediaManagerDock = OpenLPDockWidget(mainWindow,
|
||||
u'mediaManagerDock', u':/system/system_mediamanager.png')
|
||||
@ -880,10 +885,10 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
||||
self.setWindowTitle(title)
|
||||
|
||||
def showStatusMessage(self, message):
|
||||
self.StatusBar.showMessage(message)
|
||||
self.statusBar.showMessage(message)
|
||||
|
||||
def defaultThemeChanged(self, theme):
|
||||
self.DefaultThemeLabel.setText(
|
||||
self.defaultThemeLabel.setText(
|
||||
unicode(translate('OpenLP.MainWindow', 'Default Theme: %s')) %
|
||||
theme)
|
||||
|
||||
@ -979,7 +984,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
||||
for fileId, filename in enumerate(recentFilesToDisplay):
|
||||
log.debug('Recent file name: %s', filename)
|
||||
action = base_action(self, u'')
|
||||
action.setText(u'&%d %s' %
|
||||
action.setText(u'&%d %s' %
|
||||
(fileId + 1, QtCore.QFileInfo(filename).fileName()))
|
||||
action.setData(QtCore.QVariant(filename))
|
||||
self.connect(action, QtCore.SIGNAL(u'triggered()'),
|
||||
@ -1008,3 +1013,34 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
|
||||
while self.recentFiles.count() > maxRecentFiles:
|
||||
# Don't care what API says takeLast works, removeLast doesn't!
|
||||
self.recentFiles.takeLast()
|
||||
|
||||
def displayProgressBar(self, size):
|
||||
"""
|
||||
Make Progress bar visible and set size
|
||||
"""
|
||||
self.loadProgressBar.show()
|
||||
self.loadProgressBar.setMaximum(size)
|
||||
self.loadProgressBar.setValue(0)
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
|
||||
def incrementProgressBar(self):
|
||||
"""
|
||||
Increase the Progress Bar value by 1
|
||||
"""
|
||||
self.loadProgressBar.setValue(self.loadProgressBar.value() + 1)
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
|
||||
def finishedProgressBar(self):
|
||||
"""
|
||||
Trigger it's removal after 2.5 second
|
||||
"""
|
||||
self.timer_id = self.startTimer(2500)
|
||||
|
||||
def timerEvent(self, event):
|
||||
"""
|
||||
Remove the Progress bar from view.
|
||||
"""
|
||||
if event.timerId() == self.timer_id:
|
||||
self.timer_id = 0
|
||||
self.loadProgressBar.hide()
|
||||
Receiver.send_message(u'openlp_process_events')
|
||||
|
@ -460,7 +460,11 @@ class ServiceManager(QtGui.QWidget):
|
||||
service = []
|
||||
write_list = []
|
||||
total_size = 0
|
||||
Receiver.send_message(u'cursor_busy')
|
||||
# Number of items + 1 to zip it
|
||||
self.mainwindow.displayProgressBar(len(self.serviceItems) + 1)
|
||||
for item in self.serviceItems:
|
||||
self.mainwindow.incrementProgressBar()
|
||||
service.append({u'serviceitem':
|
||||
item[u'service_item'].get_service_repr()})
|
||||
if not item[u'service_item'].uses_file():
|
||||
@ -501,6 +505,7 @@ class ServiceManager(QtGui.QWidget):
|
||||
log.debug(u'ServiceManager.saveFile - allowZip64 is %s' % allow_zip_64)
|
||||
zip = None
|
||||
success = True
|
||||
self.mainwindow.incrementProgressBar()
|
||||
try:
|
||||
zip = zipfile.ZipFile(path_file_name, 'w', zipfile.ZIP_STORED,
|
||||
allow_zip_64)
|
||||
@ -516,6 +521,8 @@ class ServiceManager(QtGui.QWidget):
|
||||
finally:
|
||||
if zip:
|
||||
zip.close()
|
||||
self.mainwindow.finishedProgressBar()
|
||||
Receiver.send_message(u'cursor_normal')
|
||||
if success:
|
||||
self.mainwindow.addRecentFile(path_file_name)
|
||||
self.setModified(False)
|
||||
@ -576,13 +583,15 @@ class ServiceManager(QtGui.QWidget):
|
||||
items = cPickle.load(fileTo)
|
||||
fileTo.close()
|
||||
self.newFile()
|
||||
self.mainwindow.displayProgressBar(len(items))
|
||||
for item in items:
|
||||
self.mainwindow.incrementProgressBar()
|
||||
serviceItem = ServiceItem()
|
||||
serviceItem.from_service = True
|
||||
serviceItem.renderer = self.mainwindow.renderer
|
||||
serviceItem.set_from_service(item, self.servicePath)
|
||||
self.validateItem(serviceItem)
|
||||
self.addServiceItem(serviceItem)
|
||||
self.addServiceItem(serviceItem, repaint=False)
|
||||
if serviceItem.is_capable(ItemCapabilities.OnLoadUpdate):
|
||||
Receiver.send_message(u'%s_service_load' %
|
||||
serviceItem.name.lower(), serviceItem)
|
||||
@ -592,7 +601,6 @@ class ServiceManager(QtGui.QWidget):
|
||||
self.setModified(False)
|
||||
QtCore.QSettings().setValue(
|
||||
'service/last file', QtCore.QVariant(fileName))
|
||||
Receiver.send_message(u'cursor_normal')
|
||||
else:
|
||||
critical_error_message_box(
|
||||
message=translate('OpenLP.ServiceManager',
|
||||
@ -623,6 +631,9 @@ class ServiceManager(QtGui.QWidget):
|
||||
fileTo.close()
|
||||
if zip:
|
||||
zip.close()
|
||||
self.mainwindow.finishedProgressBar()
|
||||
Receiver.send_message(u'cursor_normal')
|
||||
self.repaintServiceList(-1, -1)
|
||||
|
||||
def loadLastFile(self):
|
||||
"""
|
||||
@ -1056,7 +1067,8 @@ class ServiceManager(QtGui.QWidget):
|
||||
newItem)
|
||||
self.setModified()
|
||||
|
||||
def addServiceItem(self, item, rebuild=False, expand=None, replace=False):
|
||||
def addServiceItem(self, item, rebuild=False, expand=None, replace=False,
|
||||
repaint=True):
|
||||
"""
|
||||
Add a Service item to the list
|
||||
|
||||
@ -1089,7 +1101,8 @@ class ServiceManager(QtGui.QWidget):
|
||||
self.serviceItems.append({u'service_item': item,
|
||||
u'order': len(self.serviceItems) + 1,
|
||||
u'expanded': expand})
|
||||
self.repaintServiceList(len(self.serviceItems) - 1, -1)
|
||||
if repaint:
|
||||
self.repaintServiceList(len(self.serviceItems) - 1, -1)
|
||||
else:
|
||||
self.serviceItems.insert(self.dropPosition,
|
||||
{u'service_item': item, u'order': self.dropPosition,
|
||||
|
@ -77,7 +77,7 @@ class ImageMediaItem(MediaManagerItem):
|
||||
u'thumbnails')
|
||||
check_directory_exists(self.servicePath)
|
||||
self.loadList(SettingsManager.load_list(
|
||||
self.settingsSection, self.settingsSection))
|
||||
self.settingsSection, self.settingsSection), True)
|
||||
|
||||
def addListViewToToolBar(self):
|
||||
MediaManagerItem.addListViewToToolBar(self)
|
||||
@ -107,8 +107,13 @@ class ImageMediaItem(MediaManagerItem):
|
||||
SettingsManager.set_list(self.settingsSection,
|
||||
self.settingsSection, self.getFileList())
|
||||
|
||||
def loadList(self, list):
|
||||
def loadList(self, list, initialLoad=False):
|
||||
Receiver.send_message(u'cursor_busy')
|
||||
if not initialLoad:
|
||||
self.parent.formparent.displayProgressBar(len(list))
|
||||
for imageFile in list:
|
||||
if not initialLoad:
|
||||
self.parent.formparent.incrementProgressBar()
|
||||
filename = os.path.split(unicode(imageFile))[1]
|
||||
thumb = os.path.join(self.servicePath, filename)
|
||||
if os.path.exists(thumb):
|
||||
@ -122,6 +127,9 @@ class ImageMediaItem(MediaManagerItem):
|
||||
item_name.setIcon(icon)
|
||||
item_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(imageFile))
|
||||
self.listView.addItem(item_name)
|
||||
Receiver.send_message(u'cursor_normal')
|
||||
if not initialLoad:
|
||||
self.parent.formparent.finishedProgressBar()
|
||||
|
||||
def generateSlideData(self, service_item, item=None, xmlVersion=False):
|
||||
items = self.listView.selectedIndexes()
|
||||
@ -201,4 +209,4 @@ class ImageMediaItem(MediaManagerItem):
|
||||
critical_error_message_box(UiStrings().LiveBGError,
|
||||
unicode(translate('ImagePlugin.MediaItem',
|
||||
'There was a problem replacing your background, '
|
||||
'the image file "%s" no longer exists.')) % filename)
|
||||
'the image file "%s" no longer exists.')) % filename)
|
||||
|
@ -158,7 +158,12 @@ class PresentationMediaItem(MediaManagerItem):
|
||||
titles = []
|
||||
for file in currlist:
|
||||
titles.append(os.path.split(file)[1])
|
||||
Receiver.send_message(u'cursor_busy')
|
||||
if not initialLoad:
|
||||
self.parent.formparent.displayProgressBar(len(list))
|
||||
for file in list:
|
||||
if not initialLoad:
|
||||
self.parent.formparent.incrementProgressBar()
|
||||
if currlist.count(file) > 0:
|
||||
continue
|
||||
filename = os.path.split(unicode(file))[1]
|
||||
@ -198,6 +203,9 @@ class PresentationMediaItem(MediaManagerItem):
|
||||
item_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(file))
|
||||
item_name.setIcon(icon)
|
||||
self.listView.addItem(item_name)
|
||||
Receiver.send_message(u'cursor_normal')
|
||||
if not initialLoad:
|
||||
self.parent.formparent.finishedProgressBar()
|
||||
|
||||
def onDeleteClick(self):
|
||||
"""
|
||||
@ -296,4 +304,4 @@ class PresentationMediaItem(MediaManagerItem):
|
||||
if self.controllers[controller].enabled():
|
||||
if filetype in self.controllers[controller].alsosupports:
|
||||
return controller
|
||||
return None
|
||||
return None
|
||||
|
@ -293,7 +293,10 @@ def clean_song(manager, song):
|
||||
song.lyrics = unicode(sxml.extract_xml(), u'utf-8')
|
||||
# Rebuild the verse order, to convert translated verse tags, which might
|
||||
# have been added prior to 1.9.5.
|
||||
order = song.verse_order.strip().split()
|
||||
if song.verse_order:
|
||||
order = song.verse_order.strip().split()
|
||||
else:
|
||||
order = []
|
||||
new_order = []
|
||||
for verse_def in order:
|
||||
verse_type = VerseType.Tags[VerseType.from_loose_input(verse_def[0])]
|
||||
|
@ -32,7 +32,7 @@ The basic XML for storing the lyrics in the song database looks like this::
|
||||
<song version="1.0">
|
||||
<lyrics>
|
||||
<verse type="c" label="1" lang="en">
|
||||
<![CDATA[ ... ]]>
|
||||
<![CDATA[Chorus virtual slide 1[---]Chorus virtual slide 2]]>
|
||||
</verse>
|
||||
</lyrics>
|
||||
</song>
|
||||
@ -129,18 +129,31 @@ class SongXML(object):
|
||||
|
||||
The returned list has the following format::
|
||||
|
||||
[[{'lang': 'en', 'type': 'v', 'label': '1'}, u"English verse"],
|
||||
[[{'type': 'v', 'label': '1'},
|
||||
u"virtual slide 1[---]virtual slide 2"],
|
||||
[{'lang': 'en', 'type': 'c', 'label': '1'}, u"English chorus"]]
|
||||
"""
|
||||
self.song_xml = None
|
||||
if xml[:5] == u'<?xml':
|
||||
verse_list = []
|
||||
if not xml.startswith(u'<?xml') and not xml.startswith(u'<song'):
|
||||
# This is an old style song, without XML. Let's handle it correctly
|
||||
# by iterating through the verses, and then recreating the internal
|
||||
# xml object as well.
|
||||
self.song_xml = objectify.fromstring(u'<song version="1.0" />')
|
||||
self.lyrics = etree.SubElement(self.song_xml, u'lyrics')
|
||||
verses = xml.split(u'\n\n')
|
||||
for count, verse in enumerate(verses):
|
||||
verse_list.append([{u'type': u'v', u'label': unicode(count)},
|
||||
unicode(verse)])
|
||||
self.add_verse_to_lyrics(u'v', unicode(count), verse)
|
||||
return verse_list
|
||||
elif xml.startswith(u'<?xml'):
|
||||
xml = xml[38:]
|
||||
try:
|
||||
self.song_xml = objectify.fromstring(xml)
|
||||
except etree.XMLSyntaxError:
|
||||
log.exception(u'Invalid xml %s', xml)
|
||||
xml_iter = self.song_xml.getiterator()
|
||||
verse_list = []
|
||||
for element in xml_iter:
|
||||
if element.tag == u'verse':
|
||||
if element.text is None:
|
||||
@ -226,7 +239,6 @@ class OpenLyrics(object):
|
||||
Convert the song to OpenLyrics Format.
|
||||
"""
|
||||
sxml = SongXML()
|
||||
verse_list = sxml.get_verses(song.lyrics)
|
||||
song_xml = objectify.fromstring(u'<song/>')
|
||||
# Append the necessary meta data to the song.
|
||||
song_xml.set(u'xmlns', u'http://openlyrics.info/namespace/2009/song')
|
||||
@ -268,17 +280,26 @@ class OpenLyrics(object):
|
||||
themes = etree.SubElement(properties, u'themes')
|
||||
for topic in song.topics:
|
||||
self._add_text_to_element(u'theme', themes, topic.name)
|
||||
# Process the song's lyrics.
|
||||
lyrics = etree.SubElement(song_xml, u'lyrics')
|
||||
verse_list = sxml.get_verses(song.lyrics)
|
||||
for verse in verse_list:
|
||||
verse_tag = u'%s%s' % (
|
||||
verse[0][u'type'][0].lower(), verse[0][u'label'])
|
||||
element = \
|
||||
self._add_text_to_element(u'verse', lyrics, None, verse_tag)
|
||||
if verse[0].has_key(u'lang'):
|
||||
element.set(u'lang', verse[0][u'lang'])
|
||||
element = self._add_text_to_element(u'lines', element)
|
||||
for line in unicode(verse[1]).split(u'\n'):
|
||||
self._add_text_to_element(u'line', element, line)
|
||||
verse_tag = verse[0][u'type'][0].lower()
|
||||
verse_number = verse[0][u'label']
|
||||
# Create a list with all "virtual" verses.
|
||||
virtual_verses = verse[1].split(u'[---]')
|
||||
for index, virtual_verse in enumerate(virtual_verses):
|
||||
verse_def = verse_tag + verse_number
|
||||
# We need "v1a" because we have more than one virtual verse.
|
||||
if len(virtual_verses) > 1:
|
||||
verse_def += list(u'abcdefghijklmnopqrstuvwxyz')[index]
|
||||
element = \
|
||||
self._add_text_to_element(u'verse', lyrics, None, verse_def)
|
||||
if verse[0].has_key(u'lang'):
|
||||
element.set(u'lang', verse[0][u'lang'])
|
||||
element = self._add_text_to_element(u'lines', element)
|
||||
for line in virtual_verse.strip(u'\n').split(u'\n'):
|
||||
self._add_text_to_element(u'line', element, line)
|
||||
return self._extract_xml(song_xml)
|
||||
|
||||
def xml_to_song(self, xml):
|
||||
@ -446,6 +467,8 @@ class OpenLyrics(object):
|
||||
The song object.
|
||||
"""
|
||||
sxml = SongXML()
|
||||
verses = {}
|
||||
verse_def_list = []
|
||||
for verse in lyrics.verse:
|
||||
text = u''
|
||||
for lines in verse.lines:
|
||||
@ -465,7 +488,15 @@ class OpenLyrics(object):
|
||||
lang = None
|
||||
if self._get(verse, u'lang'):
|
||||
lang = self._get(verse, u'lang')
|
||||
sxml.add_verse_to_lyrics(verse_tag, verse_number, text, lang)
|
||||
if verses.has_key((verse_tag, verse_number, lang)):
|
||||
verses[(verse_tag, verse_number, lang)] += u'\n[---]\n' + text
|
||||
else:
|
||||
verses[(verse_tag, verse_number, lang)] = text
|
||||
verse_def_list.append((verse_tag, verse_number, lang))
|
||||
# We have to use a list to keep the order, as dicts are not sorted.
|
||||
for verse in verse_def_list:
|
||||
sxml.add_verse_to_lyrics(
|
||||
verse[0], verse[1], verses[verse], verse[2])
|
||||
song.lyrics = unicode(sxml.extract_xml(), u'utf-8')
|
||||
# Process verse order
|
||||
if hasattr(properties, u'verseOrder'):
|
||||
|
Loading…
Reference in New Issue
Block a user