forked from openlp/openlp
Add option to add a split to a song
This will split the verse when added to the service but keep the verse together for editing. Useful for the 10 line hymn verses which need 2 slides to display. Fix some iffy spelling lp:~trb143/openlp/splitter (revision 2738) [SUCCESS] https://ci.openlp.io/job/Branch-01-Pull/2182/ [SUCCESS] https://ci.openlp.io/job/Branch-02-Functional-Tests/2085/ [SUCCESS] https://ci.openlp.io/job/Branch-03-Interface-Tests/1972/ [SUCCESS] https://ci.openlp.io/job/Branch... bzr-revno: 2777
This commit is contained in:
commit
df39497cc1
@ -147,7 +147,7 @@ class UiStrings(object):
|
|||||||
self.SaveService = translate('OpenLP.Ui', 'Save Service')
|
self.SaveService = translate('OpenLP.Ui', 'Save Service')
|
||||||
self.Service = translate('OpenLP.Ui', 'Service')
|
self.Service = translate('OpenLP.Ui', 'Service')
|
||||||
self.ShortResults = translate('OpenLP.Ui', 'Please type more text to use \'Search As You Type\'')
|
self.ShortResults = translate('OpenLP.Ui', 'Please type more text to use \'Search As You Type\'')
|
||||||
self.Split = translate('OpenLP.Ui', 'Optional &Split')
|
self.Split = translate('OpenLP.Ui', 'Overflow &Split')
|
||||||
self.SplitToolTip = translate('OpenLP.Ui',
|
self.SplitToolTip = translate('OpenLP.Ui',
|
||||||
'Split a slide into two only if it does not fit on the screen as one slide.')
|
'Split a slide into two only if it does not fit on the screen as one slide.')
|
||||||
self.StartingImport = translate('OpenLP.Ui', 'Starting import...')
|
self.StartingImport = translate('OpenLP.Ui', 'Starting import...')
|
||||||
|
@ -243,6 +243,9 @@ class Renderer(OpenLPMixin, RegistryMixin, RegistryProperties):
|
|||||||
elif item.is_capable(ItemCapabilities.CanSoftBreak):
|
elif item.is_capable(ItemCapabilities.CanSoftBreak):
|
||||||
pages = []
|
pages = []
|
||||||
if '[---]' in text:
|
if '[---]' in text:
|
||||||
|
# Remove Overflow split if at start of the text
|
||||||
|
if text.startswith('[---]'):
|
||||||
|
text = text[5:]
|
||||||
# Remove two or more option slide breaks next to each other (causing infinite loop).
|
# Remove two or more option slide breaks next to each other (causing infinite loop).
|
||||||
while '\n[---]\n[---]\n' in text:
|
while '\n[---]\n[---]\n' in text:
|
||||||
text = text.replace('\n[---]\n[---]\n', '\n[---]\n')
|
text = text.replace('\n[---]\n[---]\n', '\n[---]\n')
|
||||||
|
@ -209,21 +209,21 @@ class ListPreviewWidget(QtWidgets.QTableWidget, RegistryProperties):
|
|||||||
Switches to the given row.
|
Switches to the given row.
|
||||||
"""
|
"""
|
||||||
# Retrieve setting
|
# Retrieve setting
|
||||||
autoscrolling = Settings().value('advanced/autoscrolling')
|
auto_scrolling = Settings().value('advanced/autoscrolling')
|
||||||
# Check if auto-scroll disabled (None) and validate value as dict containing 'dist' and 'pos'
|
# Check if auto-scroll disabled (None) and validate value as dict containing 'dist' and 'pos'
|
||||||
# 'dist' represents the slide to scroll to relative to the new slide (-1 = previous, 0 = current, 1 = next)
|
# 'dist' represents the slide to scroll to relative to the new slide (-1 = previous, 0 = current, 1 = next)
|
||||||
# 'pos' represents the vert position of of the slide (0 = in view, 1 = top, 2 = middle, 3 = bottom)
|
# 'pos' represents the vert position of of the slide (0 = in view, 1 = top, 2 = middle, 3 = bottom)
|
||||||
if not (isinstance(autoscrolling, dict) and 'dist' in autoscrolling and 'pos' in autoscrolling and
|
if not (isinstance(auto_scrolling, dict) and 'dist' in auto_scrolling and 'pos' in auto_scrolling and
|
||||||
isinstance(autoscrolling['dist'], int) and isinstance(autoscrolling['pos'], int)):
|
isinstance(auto_scrolling['dist'], int) and isinstance(auto_scrolling['pos'], int)):
|
||||||
return
|
return
|
||||||
# prevent scrolling past list bounds
|
# prevent scrolling past list bounds
|
||||||
scroll_to_slide = slide + autoscrolling['dist']
|
scroll_to_slide = slide + auto_scrolling['dist']
|
||||||
if scroll_to_slide < 0:
|
if scroll_to_slide < 0:
|
||||||
scroll_to_slide = 0
|
scroll_to_slide = 0
|
||||||
if scroll_to_slide >= self.slide_count():
|
if scroll_to_slide >= self.slide_count():
|
||||||
scroll_to_slide = self.slide_count() - 1
|
scroll_to_slide = self.slide_count() - 1
|
||||||
# Scroll to item if possible.
|
# Scroll to item if possible.
|
||||||
self.scrollToItem(self.item(scroll_to_slide, 0), autoscrolling['pos'])
|
self.scrollToItem(self.item(scroll_to_slide, 0), auto_scrolling['pos'])
|
||||||
self.selectRow(slide)
|
self.selectRow(slide)
|
||||||
|
|
||||||
def current_slide_number(self):
|
def current_slide_number(self):
|
||||||
|
@ -25,14 +25,13 @@ The duplicate song removal logic for OpenLP.
|
|||||||
|
|
||||||
import logging
|
import logging
|
||||||
import multiprocessing
|
import multiprocessing
|
||||||
import os
|
|
||||||
|
|
||||||
from PyQt5 import QtCore, QtWidgets
|
from PyQt5 import QtCore, QtWidgets
|
||||||
|
|
||||||
from openlp.core.common import Registry, RegistryProperties, translate
|
from openlp.core.common import Registry, RegistryProperties, translate
|
||||||
from openlp.core.ui.lib.wizard import OpenLPWizard, WizardStrings
|
from openlp.core.ui.lib.wizard import OpenLPWizard, WizardStrings
|
||||||
from openlp.plugins.songs.lib import delete_song
|
from openlp.plugins.songs.lib import delete_song
|
||||||
from openlp.plugins.songs.lib.db import Song, MediaFile
|
from openlp.plugins.songs.lib.db import Song
|
||||||
from openlp.plugins.songs.forms.songreviewwidget import SongReviewWidget
|
from openlp.plugins.songs.forms.songreviewwidget import SongReviewWidget
|
||||||
from openlp.plugins.songs.lib.songcompare import songs_probably_equal
|
from openlp.plugins.songs.lib.songcompare import songs_probably_equal
|
||||||
|
|
||||||
|
@ -42,10 +42,14 @@ class Ui_EditVerseDialog(object):
|
|||||||
self.dialog_layout.addWidget(self.verse_text_edit)
|
self.dialog_layout.addWidget(self.verse_text_edit)
|
||||||
self.verse_type_layout = QtWidgets.QHBoxLayout()
|
self.verse_type_layout = QtWidgets.QHBoxLayout()
|
||||||
self.verse_type_layout.setObjectName('verse_type_layout')
|
self.verse_type_layout.setObjectName('verse_type_layout')
|
||||||
self.split_button = QtWidgets.QPushButton(edit_verse_dialog)
|
self.forced_split_button = QtWidgets.QPushButton(edit_verse_dialog)
|
||||||
self.split_button.setIcon(build_icon(':/general/general_add.png'))
|
self.forced_split_button.setIcon(build_icon(':/general/general_add.png'))
|
||||||
self.split_button.setObjectName('split_button')
|
self.forced_split_button.setObjectName('forced_split_button')
|
||||||
self.verse_type_layout.addWidget(self.split_button)
|
self.verse_type_layout.addWidget(self.forced_split_button)
|
||||||
|
self.overflow_split_button = QtWidgets.QPushButton(edit_verse_dialog)
|
||||||
|
self.overflow_split_button.setIcon(build_icon(':/general/general_add.png'))
|
||||||
|
self.overflow_split_button.setObjectName('overflow_split_button')
|
||||||
|
self.verse_type_layout.addWidget(self.overflow_split_button)
|
||||||
self.verse_type_label = QtWidgets.QLabel(edit_verse_dialog)
|
self.verse_type_label = QtWidgets.QLabel(edit_verse_dialog)
|
||||||
self.verse_type_label.setObjectName('verse_type_label')
|
self.verse_type_label.setObjectName('verse_type_label')
|
||||||
self.verse_type_layout.addWidget(self.verse_type_label)
|
self.verse_type_layout.addWidget(self.verse_type_label)
|
||||||
@ -93,8 +97,11 @@ class Ui_EditVerseDialog(object):
|
|||||||
self.verse_type_combo_box.setItemText(VerseType.Intro, VerseType.translated_names[VerseType.Intro])
|
self.verse_type_combo_box.setItemText(VerseType.Intro, VerseType.translated_names[VerseType.Intro])
|
||||||
self.verse_type_combo_box.setItemText(VerseType.Ending, VerseType.translated_names[VerseType.Ending])
|
self.verse_type_combo_box.setItemText(VerseType.Ending, VerseType.translated_names[VerseType.Ending])
|
||||||
self.verse_type_combo_box.setItemText(VerseType.Other, VerseType.translated_names[VerseType.Other])
|
self.verse_type_combo_box.setItemText(VerseType.Other, VerseType.translated_names[VerseType.Other])
|
||||||
self.split_button.setText(UiStrings().Split)
|
self.overflow_split_button.setText(UiStrings().Split)
|
||||||
self.split_button.setToolTip(UiStrings().SplitToolTip)
|
self.overflow_split_button.setToolTip(UiStrings().SplitToolTip)
|
||||||
|
self.forced_split_button.setText(translate('SongsPlugin.EditVerseForm', '&Forced Split'))
|
||||||
|
self.forced_split_button.setToolTip(translate('SongsPlugin.EditVerseForm', 'Split the verse when displayed '
|
||||||
|
'regardless of the screen size.'))
|
||||||
self.insert_button.setText(translate('SongsPlugin.EditVerseForm', '&Insert'))
|
self.insert_button.setText(translate('SongsPlugin.EditVerseForm', '&Insert'))
|
||||||
self.insert_button.setToolTip(translate('SongsPlugin.EditVerseForm',
|
self.insert_button.setToolTip(translate('SongsPlugin.EditVerseForm',
|
||||||
'Split a slide into two by inserting a verse splitter.'))
|
'Split a slide into two by inserting a verse splitter.'))
|
||||||
|
@ -48,12 +48,13 @@ class EditVerseForm(QtWidgets.QDialog, Ui_EditVerseDialog):
|
|||||||
self.setupUi(self)
|
self.setupUi(self)
|
||||||
self.has_single_verse = False
|
self.has_single_verse = False
|
||||||
self.insert_button.clicked.connect(self.on_insert_button_clicked)
|
self.insert_button.clicked.connect(self.on_insert_button_clicked)
|
||||||
self.split_button.clicked.connect(self.on_split_button_clicked)
|
self.overflow_split_button.clicked.connect(self.on_overflow_split_button_clicked)
|
||||||
self.verse_text_edit.cursorPositionChanged.connect(self.on_cursor_position_changed)
|
self.verse_text_edit.cursorPositionChanged.connect(self.on_cursor_position_changed)
|
||||||
self.verse_type_combo_box.currentIndexChanged.connect(self.on_verse_type_combo_box_changed)
|
self.verse_type_combo_box.currentIndexChanged.connect(self.on_verse_type_combo_box_changed)
|
||||||
|
self.forced_split_button.clicked.connect(self.on_forced_split_button_clicked)
|
||||||
if Settings().value('songs/enable chords'):
|
if Settings().value('songs/enable chords'):
|
||||||
self.transpose_down_button.clicked.connect(self.on_transepose_down_button_clicked)
|
self.transpose_down_button.clicked.connect(self.on_transpose_down_button_clicked)
|
||||||
self.transpose_up_button.clicked.connect(self.on_transepose_up_button_clicked)
|
self.transpose_up_button.clicked.connect(self.on_transpose_up_button_clicked)
|
||||||
|
|
||||||
def insert_verse(self, verse_tag, verse_num=1):
|
def insert_verse(self, verse_tag, verse_num=1):
|
||||||
"""
|
"""
|
||||||
@ -68,13 +69,27 @@ class EditVerseForm(QtWidgets.QDialog, Ui_EditVerseDialog):
|
|||||||
self.verse_text_edit.insertPlainText('---[{tag}:{number}]---\n'.format(tag=verse_tag, number=verse_num))
|
self.verse_text_edit.insertPlainText('---[{tag}:{number}]---\n'.format(tag=verse_tag, number=verse_num))
|
||||||
self.verse_text_edit.setFocus()
|
self.verse_text_edit.setFocus()
|
||||||
|
|
||||||
def on_split_button_clicked(self):
|
def on_overflow_split_button_clicked(self):
|
||||||
"""
|
"""
|
||||||
The split button has been pressed
|
The optional split button has been pressed so we need add the split
|
||||||
|
"""
|
||||||
|
self._add_splitter_to_text('[---]')
|
||||||
|
|
||||||
|
def on_forced_split_button_clicked(self):
|
||||||
|
"""
|
||||||
|
The force split button has been pressed so we need add the split
|
||||||
|
"""
|
||||||
|
self._add_splitter_to_text('[--}{--]')
|
||||||
|
|
||||||
|
def _add_splitter_to_text(self, insert_string):
|
||||||
|
"""
|
||||||
|
Add a custom splitter to the song text
|
||||||
|
|
||||||
|
:param insert_string: The string to insert
|
||||||
|
:return:
|
||||||
"""
|
"""
|
||||||
text = self.verse_text_edit.toPlainText()
|
text = self.verse_text_edit.toPlainText()
|
||||||
position = self.verse_text_edit.textCursor().position()
|
position = self.verse_text_edit.textCursor().position()
|
||||||
insert_string = '[---]'
|
|
||||||
if position and text[position - 1] != '\n':
|
if position and text[position - 1] != '\n':
|
||||||
insert_string = '\n' + insert_string
|
insert_string = '\n' + insert_string
|
||||||
if position == len(text) or text[position] != '\n':
|
if position == len(text) or text[position] != '\n':
|
||||||
@ -101,7 +116,7 @@ class EditVerseForm(QtWidgets.QDialog, Ui_EditVerseDialog):
|
|||||||
"""
|
"""
|
||||||
self.update_suggested_verse_number()
|
self.update_suggested_verse_number()
|
||||||
|
|
||||||
def on_transepose_up_button_clicked(self):
|
def on_transpose_up_button_clicked(self):
|
||||||
"""
|
"""
|
||||||
The transpose up button clicked
|
The transpose up button clicked
|
||||||
"""
|
"""
|
||||||
@ -118,7 +133,7 @@ class EditVerseForm(QtWidgets.QDialog, Ui_EditVerseDialog):
|
|||||||
self.verse_text_edit.setFocus()
|
self.verse_text_edit.setFocus()
|
||||||
self.verse_text_edit.moveCursor(QtGui.QTextCursor.End)
|
self.verse_text_edit.moveCursor(QtGui.QTextCursor.End)
|
||||||
|
|
||||||
def on_transepose_down_button_clicked(self):
|
def on_transpose_down_button_clicked(self):
|
||||||
"""
|
"""
|
||||||
The transpose down button clicked
|
The transpose down button clicked
|
||||||
"""
|
"""
|
||||||
|
@ -546,12 +546,12 @@ def delete_song(song_id, song_plugin):
|
|||||||
song_plugin.manager.delete_object(Song, song_id)
|
song_plugin.manager.delete_object(Song, song_id)
|
||||||
|
|
||||||
|
|
||||||
def transpose_lyrics(lyrics, transepose_value):
|
def transpose_lyrics(lyrics, transpose_value):
|
||||||
"""
|
"""
|
||||||
Transepose lyrics
|
Transpose lyrics
|
||||||
|
|
||||||
:param lyrcs: The lyrics to be transposed
|
:param lyrics: The lyrics to be transposed
|
||||||
:param transepose_value: The value to transpose the lyrics with
|
:param transpose_value: The value to transpose the lyrics with
|
||||||
:return: The transposed lyrics
|
:return: The transposed lyrics
|
||||||
"""
|
"""
|
||||||
# Split text by verse delimiter - both normal and optional
|
# Split text by verse delimiter - both normal and optional
|
||||||
@ -562,16 +562,17 @@ def transpose_lyrics(lyrics, transepose_value):
|
|||||||
if verse.startswith('---[') or verse == '[---]':
|
if verse.startswith('---[') or verse == '[---]':
|
||||||
transposed_lyrics += verse
|
transposed_lyrics += verse
|
||||||
else:
|
else:
|
||||||
transposed_lyrics += transpose_verse(verse, transepose_value, notation)
|
transposed_lyrics += transpose_verse(verse, transpose_value, notation)
|
||||||
return transposed_lyrics
|
return transposed_lyrics
|
||||||
|
|
||||||
|
|
||||||
def transpose_verse(verse_text, transepose_value, notation):
|
def transpose_verse(verse_text, transpose_value, notation):
|
||||||
"""
|
"""
|
||||||
Transepose lyrics
|
Transpose Verse
|
||||||
|
|
||||||
:param lyrcs: The lyrics to be transposed
|
:param verse_text: The lyrics to be transposed
|
||||||
:param transepose_value: The value to transpose the lyrics with
|
:param transpose_value: The value to transpose the lyrics with
|
||||||
|
:param notation: which notation to use
|
||||||
:return: The transposed lyrics
|
:return: The transposed lyrics
|
||||||
"""
|
"""
|
||||||
if '[' not in verse_text:
|
if '[' not in verse_text:
|
||||||
@ -589,11 +590,11 @@ def transpose_verse(verse_text, transepose_value, notation):
|
|||||||
if word == ']':
|
if word == ']':
|
||||||
in_tag = False
|
in_tag = False
|
||||||
transposed_lyrics += word
|
transposed_lyrics += word
|
||||||
elif word == '/':
|
elif word == '/' or word == '--}{--':
|
||||||
transposed_lyrics += word
|
transposed_lyrics += word
|
||||||
else:
|
else:
|
||||||
# This MUST be a chord
|
# This MUST be a chord
|
||||||
transposed_lyrics += transpose_chord(word, transepose_value, notation)
|
transposed_lyrics += transpose_chord(word, transpose_value, notation)
|
||||||
# If still inside a chord tag something is wrong!
|
# If still inside a chord tag something is wrong!
|
||||||
if in_tag:
|
if in_tag:
|
||||||
return verse_text
|
return verse_text
|
||||||
@ -629,36 +630,36 @@ def transpose_chord(chord, transpose_value, notation):
|
|||||||
for i in range(0, len(chord_split)):
|
for i in range(0, len(chord_split)):
|
||||||
if i > 0:
|
if i > 0:
|
||||||
transposed_chord += '/'
|
transposed_chord += '/'
|
||||||
currentchord = chord_split[i]
|
current_chord = chord_split[i]
|
||||||
if currentchord and currentchord[0] == '(':
|
if current_chord and current_chord[0] == '(':
|
||||||
transposed_chord += '('
|
transposed_chord += '('
|
||||||
if len(currentchord) > 1:
|
if len(current_chord) > 1:
|
||||||
currentchord = currentchord[1:]
|
current_chord = current_chord[1:]
|
||||||
else:
|
else:
|
||||||
currentchord = ''
|
current_chord = ''
|
||||||
if len(currentchord) > 0:
|
if len(current_chord) > 0:
|
||||||
if len(currentchord) > 1:
|
if len(current_chord) > 1:
|
||||||
if '#b'.find(currentchord[1]) == -1:
|
if '#b'.find(current_chord[1]) == -1:
|
||||||
note = currentchord[0:1]
|
note = current_chord[0:1]
|
||||||
rest = currentchord[1:]
|
rest = current_chord[1:]
|
||||||
else:
|
else:
|
||||||
note = currentchord[0:2]
|
note = current_chord[0:2]
|
||||||
rest = currentchord[2:]
|
rest = current_chord[2:]
|
||||||
else:
|
else:
|
||||||
note = currentchord
|
note = current_chord
|
||||||
rest = ''
|
rest = ''
|
||||||
notenumber = notes_flat.index(note) if note not in notes_sharp else notes_sharp.index(note)
|
note_number = notes_flat.index(note) if note not in notes_sharp else notes_sharp.index(note)
|
||||||
notenumber += transpose_value
|
note_number += transpose_value
|
||||||
while notenumber > 11:
|
while note_number > 11:
|
||||||
notenumber -= 12
|
note_number -= 12
|
||||||
while notenumber < 0:
|
while note_number < 0:
|
||||||
notenumber += 12
|
note_number += 12
|
||||||
if i == 0:
|
if i == 0:
|
||||||
current_chord = notes_sharp[notenumber] if notes_preferred[notenumber] == '#' else notes_flat[
|
current_chord = notes_sharp[note_number] if notes_preferred[note_number] == '#' else notes_flat[
|
||||||
notenumber]
|
note_number]
|
||||||
last_chord = current_chord
|
last_chord = current_chord
|
||||||
else:
|
else:
|
||||||
current_chord = notes_flat[notenumber] if last_chord not in notes_sharp else notes_sharp[notenumber]
|
current_chord = notes_flat[note_number] if last_chord not in notes_sharp else notes_sharp[note_number]
|
||||||
if not (note not in notes_flat and note not in notes_sharp):
|
if not (note not in notes_flat and note not in notes_sharp):
|
||||||
transposed_chord += current_chord + rest
|
transposed_chord += current_chord + rest
|
||||||
else:
|
else:
|
||||||
|
@ -577,7 +577,7 @@ class SongMediaItem(MediaManagerItem):
|
|||||||
if not song.verse_order.strip():
|
if not song.verse_order.strip():
|
||||||
for verse in verse_list:
|
for verse in verse_list:
|
||||||
# We cannot use from_loose_input() here, because database is supposed to contain English lowercase
|
# We cannot use from_loose_input() here, because database is supposed to contain English lowercase
|
||||||
# singlechar tags.
|
# single char tags.
|
||||||
verse_tag = verse[0]['type']
|
verse_tag = verse[0]['type']
|
||||||
verse_index = None
|
verse_index = None
|
||||||
if len(verse_tag) > 1:
|
if len(verse_tag) > 1:
|
||||||
@ -588,7 +588,9 @@ class SongMediaItem(MediaManagerItem):
|
|||||||
verse_index = VerseType.from_tag(verse_tag)
|
verse_index = VerseType.from_tag(verse_tag)
|
||||||
verse_tag = VerseType.translated_tags[verse_index].upper()
|
verse_tag = VerseType.translated_tags[verse_index].upper()
|
||||||
verse_def = '{tag}{label}'.format(tag=verse_tag, label=verse[0]['label'])
|
verse_def = '{tag}{label}'.format(tag=verse_tag, label=verse[0]['label'])
|
||||||
service_item.add_from_text(str(verse[1]), verse_def)
|
force_verse = verse[1].split('[--}{--]\n')
|
||||||
|
for split_verse in force_verse:
|
||||||
|
service_item.add_from_text(split_verse, verse_def)
|
||||||
else:
|
else:
|
||||||
# Loop through the verse list and expand the song accordingly.
|
# Loop through the verse list and expand the song accordingly.
|
||||||
for order in song.verse_order.lower().split():
|
for order in song.verse_order.lower().split():
|
||||||
@ -603,7 +605,9 @@ class SongMediaItem(MediaManagerItem):
|
|||||||
verse_index = VerseType.from_tag(verse[0]['type'])
|
verse_index = VerseType.from_tag(verse[0]['type'])
|
||||||
verse_tag = VerseType.translated_tags[verse_index]
|
verse_tag = VerseType.translated_tags[verse_index]
|
||||||
verse_def = '{tag}{label}'.format(tag=verse_tag, label=verse[0]['label'])
|
verse_def = '{tag}{label}'.format(tag=verse_tag, label=verse[0]['label'])
|
||||||
service_item.add_from_text(verse[1], verse_def)
|
force_verse = verse[1].split('[--}{--]\n')
|
||||||
|
for split_verse in force_verse:
|
||||||
|
service_item.add_from_text(split_verse, verse_def)
|
||||||
service_item.title = song.title
|
service_item.title = song.title
|
||||||
author_list = self.generate_footer(service_item, song)
|
author_list = self.generate_footer(service_item, song)
|
||||||
service_item.data_string = {'title': song.search_title, 'authors': ', '.join(author_list)}
|
service_item.data_string = {'title': song.search_title, 'authors': ', '.join(author_list)}
|
||||||
|
@ -71,6 +71,7 @@ log = logging.getLogger(__name__)
|
|||||||
|
|
||||||
NAMESPACE = 'http://openlyrics.info/namespace/2009/song'
|
NAMESPACE = 'http://openlyrics.info/namespace/2009/song'
|
||||||
NSMAP = '{{' + NAMESPACE + '}}{tag}'
|
NSMAP = '{{' + NAMESPACE + '}}{tag}'
|
||||||
|
NEWPAGETAG = '<p style="page-break-after: always;"/>'
|
||||||
|
|
||||||
|
|
||||||
class SongXML(object):
|
class SongXML(object):
|
||||||
@ -281,7 +282,7 @@ class OpenLyrics(object):
|
|||||||
tags_element = None
|
tags_element = None
|
||||||
match = re.search('\{/?\w+\}', song.lyrics, re.UNICODE)
|
match = re.search('\{/?\w+\}', song.lyrics, re.UNICODE)
|
||||||
if match:
|
if match:
|
||||||
# Named 'format_' - 'format' is built-in fuction in Python.
|
# Named 'format_' - 'format' is built-in function in Python.
|
||||||
format_ = etree.SubElement(song_xml, 'format')
|
format_ = etree.SubElement(song_xml, 'format')
|
||||||
tags_element = etree.SubElement(format_, 'tags')
|
tags_element = etree.SubElement(format_, 'tags')
|
||||||
tags_element.set('application', 'OpenLP')
|
tags_element.set('application', 'OpenLP')
|
||||||
@ -472,6 +473,7 @@ class OpenLyrics(object):
|
|||||||
text = text.replace('{{/{tag}}}'.format(tag=tag), '</tag>')
|
text = text.replace('{{/{tag}}}'.format(tag=tag), '</tag>')
|
||||||
# Replace \n with <br/>.
|
# Replace \n with <br/>.
|
||||||
text = text.replace('\n', '<br/>')
|
text = text.replace('\n', '<br/>')
|
||||||
|
text = text.replace('[--}{--]', NEWPAGETAG)
|
||||||
element = etree.XML('<lines>{text}</lines>'.format(text=text))
|
element = etree.XML('<lines>{text}</lines>'.format(text=text))
|
||||||
verse_element.append(element)
|
verse_element.append(element)
|
||||||
return element
|
return element
|
||||||
@ -634,6 +636,9 @@ class OpenLyrics(object):
|
|||||||
if element.tail:
|
if element.tail:
|
||||||
text += element.tail
|
text += element.tail
|
||||||
return text
|
return text
|
||||||
|
elif newlines and element.tag == NSMAP.format(tag='p') and 'page-break-after' in str(element.attrib):
|
||||||
|
text += '[--}{--]'
|
||||||
|
return text
|
||||||
# Start formatting tag.
|
# Start formatting tag.
|
||||||
if element.tag == NSMAP.format(tag='tag'):
|
if element.tag == NSMAP.format(tag='tag'):
|
||||||
text += '{{{name}}}'.format(name=element.get('name'))
|
text += '{{{name}}}'.format(name=element.get('name'))
|
||||||
|
@ -72,3 +72,31 @@ class TestEditVerseForm(TestCase, TestMixin):
|
|||||||
|
|
||||||
# THEN the verse number must not be changed
|
# THEN the verse number must not be changed
|
||||||
self.assertEqual(3, self.edit_verse_form.verse_number_box.value(), 'The verse number should be 3')
|
self.assertEqual(3, self.edit_verse_form.verse_number_box.value(), 'The verse number should be 3')
|
||||||
|
|
||||||
|
def test_on_divide_split_button_clicked(self):
|
||||||
|
"""
|
||||||
|
Test that divide adds text at the correct position
|
||||||
|
"""
|
||||||
|
# GIVEN some input values
|
||||||
|
self.edit_verse_form.verse_type_combo_box.currentIndex = MagicMock(return_value=4)
|
||||||
|
self.edit_verse_form.verse_text_edit.setPlainText('Text\n')
|
||||||
|
|
||||||
|
# WHEN the method is called
|
||||||
|
self.edit_verse_form.on_forced_split_button_clicked()
|
||||||
|
# THEN the verse number must not be changed
|
||||||
|
self.assertEqual('[--}{--]\nText\n', self.edit_verse_form.verse_text_edit.toPlainText(),
|
||||||
|
'The verse number should be [--}{--]\nText\n')
|
||||||
|
|
||||||
|
def test_on_split_button_clicked(self):
|
||||||
|
"""
|
||||||
|
Test that divide adds text at the correct position
|
||||||
|
"""
|
||||||
|
# GIVEN some input values
|
||||||
|
self.edit_verse_form.verse_type_combo_box.currentIndex = MagicMock(return_value=4)
|
||||||
|
self.edit_verse_form.verse_text_edit.setPlainText('Text\n')
|
||||||
|
|
||||||
|
# WHEN the method is called
|
||||||
|
self.edit_verse_form.on_overflow_split_button_clicked()
|
||||||
|
# THEN the verse number must not be changed
|
||||||
|
self.assertEqual('[---]\nText\n', self.edit_verse_form.verse_text_edit.toPlainText(),
|
||||||
|
'The verse number should be [---]\nText\n')
|
||||||
|
Loading…
Reference in New Issue
Block a user