StyledText.join method fails if the joint_text has StyledText Tags (#457)
fixes #10192
This commit is contained in:
parent
fe45742c21
commit
af975e926f
@ -27,6 +27,7 @@
|
||||
# Gramps modules
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
from copy import copy
|
||||
from .styledtexttag import StyledTextTag
|
||||
from ..const import GRAMPS_LOCALE as glocale
|
||||
_ = glocale.translation.gettext
|
||||
@ -77,6 +78,8 @@ class StyledText:
|
||||
There could be a 'merge_tags' functionality in :py:meth:`__init__`,
|
||||
however :py:class:`StyledTextBuffer` will merge them automatically if
|
||||
the text is displayed.
|
||||
3. Warning: Some of these operations modify the source tag ranges in place
|
||||
so if you intend to use a source tag more than once, copy it for use.
|
||||
"""
|
||||
(POS_TEXT, POS_TAGS) = list(range(2))
|
||||
|
||||
@ -198,17 +201,27 @@ class StyledText:
|
||||
new_string = self._string.join([str(string) for string in seq])
|
||||
|
||||
offset = 0
|
||||
not_first = False
|
||||
new_tags = []
|
||||
self_len = len(self._string)
|
||||
|
||||
for text in seq:
|
||||
if not_first: # if not first time through...
|
||||
# put the joined element tag(s) into place
|
||||
for tag in self.tags:
|
||||
ntag = copy(tag)
|
||||
ntag.ranges = [(start + offset, end + offset)
|
||||
for (start, end) in tag.ranges]
|
||||
new_tags += [ntag]
|
||||
offset += self_len
|
||||
if isinstance(text, StyledText):
|
||||
for tag in text.tags:
|
||||
tag.ranges = [(start + offset, end + offset)
|
||||
for (start, end) in tag.ranges]
|
||||
new_tags += [tag]
|
||||
|
||||
offset = offset + len(str(text)) + self_len
|
||||
ntag = copy(tag)
|
||||
ntag.ranges = [(start + offset, end + offset)
|
||||
for (start, end) in tag.ranges]
|
||||
new_tags += [ntag]
|
||||
offset += len(str(text))
|
||||
not_first = True
|
||||
|
||||
return self.__class__(new_string, new_tags)
|
||||
|
||||
@ -366,6 +379,7 @@ if __name__ == '__main__':
|
||||
from .styledtexttagtype import StyledTextTagType
|
||||
T1 = StyledTextTag(StyledTextTagType(1), 'v1', [(0, 2), (2, 4), (4, 6)])
|
||||
T2 = StyledTextTag(StyledTextTagType(2), 'v2', [(1, 3), (3, 5), (0, 7)])
|
||||
T3 = StyledTextTag(StyledTextTagType(0), 'v3', [(0, 1)])
|
||||
|
||||
A = StyledText('123X456', [T1])
|
||||
B = StyledText("abcXdef", [T2])
|
||||
@ -376,7 +390,7 @@ if __name__ == '__main__':
|
||||
|
||||
C = C.join([A, S, B])
|
||||
L = C.split()
|
||||
C = C.replace('X', StyledText('_'))
|
||||
C = C.replace('X', StyledText('_', [T3]))
|
||||
A = A + B
|
||||
|
||||
print(A)
|
||||
|
82
gramps/gen/lib/test/styledtext_test.py
Normal file
82
gramps/gen/lib/test/styledtext_test.py
Normal file
@ -0,0 +1,82 @@
|
||||
#
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2017 Paul Culley
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
|
||||
""" unittest for styledtext """
|
||||
|
||||
import unittest
|
||||
from copy import deepcopy
|
||||
from ..styledtext import StyledText
|
||||
from ..styledtexttag import StyledTextTag
|
||||
from ..styledtexttagtype import StyledTextTagType
|
||||
|
||||
|
||||
class Test1(unittest.TestCase):
|
||||
T1 = StyledTextTag(StyledTextTagType(1), 'v1', [(0, 2), (2, 4), (4, 6)])
|
||||
T2 = StyledTextTag(StyledTextTagType(2), 'v2', [(1, 3), (3, 5), (0, 7)])
|
||||
T3 = StyledTextTag(StyledTextTagType(0), 'v3', [(0, 1)])
|
||||
T4 = StyledTextTag(StyledTextTagType(2), 'v2',
|
||||
[(8, 10), (10, 12), (7, 14)])
|
||||
T5 = StyledTextTag(StyledTextTagType(2), 'v2',
|
||||
[(19, 21), (21, 23), (18, 25)])
|
||||
|
||||
A = StyledText('123X456', [T1])
|
||||
B = StyledText("abcXdef", [T2])
|
||||
|
||||
C = StyledText('\n')
|
||||
|
||||
S = 'cleartext'
|
||||
|
||||
# some basic tests
|
||||
# because the StyledText.__eq__ method doesn't work very well (tags don't
|
||||
# compare when they are equivalent, but not equal) we have to use
|
||||
# serialize for comparisons.
|
||||
def test_join(self):
|
||||
C = self.C.join([self.A, self.S, deepcopy(self.B)])
|
||||
_C = StyledText('123X456\ncleartext\nabcXdef', [self.T1, self.T5])
|
||||
self.assertEqual(C.serialize(), _C.serialize())
|
||||
|
||||
def test_split(self):
|
||||
C = self.C.join([self.A, self.S, deepcopy(self.B)])
|
||||
L = C.split()
|
||||
_L = [self.A, self.S, self.B]
|
||||
self.assertEqual(L[0].serialize(), self.A.serialize())
|
||||
self.assertEqual(str(L[1]), self.S)
|
||||
self.assertEqual(L[2].serialize(), self.B.serialize())
|
||||
|
||||
def test_replace(self):
|
||||
C = self.C.join([self.A, self.S, deepcopy(self.B)])
|
||||
C = C.replace('X', StyledText('_', [self.T3]))
|
||||
_C = ('123_456\ncleartext\nabc_def',
|
||||
[((1, ''), 'v1', [(0, 2), (2, 3)]),
|
||||
((0, ''), 'v3', [(3, 4)]),
|
||||
((1, ''), 'v1', [(4, 6)]),
|
||||
((2, ''), 'v2', [(19, 21), (18, 21)]),
|
||||
((0, ''), 'v3', [(21, 22)]),
|
||||
((2, ''), 'v2', [(22, 23), (22, 25)])])
|
||||
self.assertEqual(C.serialize(), _C)
|
||||
|
||||
def test_add(self):
|
||||
A = deepcopy(self.A) + deepcopy(self.B)
|
||||
_A = StyledText('123X456abcXdef', [self.T1, self.T4])
|
||||
self.assertEqual(A.serialize(), _A.serialize())
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
Loading…
Reference in New Issue
Block a user