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
|
# Gramps modules
|
||||||
#
|
#
|
||||||
#-------------------------------------------------------------------------
|
#-------------------------------------------------------------------------
|
||||||
|
from copy import copy
|
||||||
from .styledtexttag import StyledTextTag
|
from .styledtexttag import StyledTextTag
|
||||||
from ..const import GRAMPS_LOCALE as glocale
|
from ..const import GRAMPS_LOCALE as glocale
|
||||||
_ = glocale.translation.gettext
|
_ = glocale.translation.gettext
|
||||||
@ -77,6 +78,8 @@ class StyledText:
|
|||||||
There could be a 'merge_tags' functionality in :py:meth:`__init__`,
|
There could be a 'merge_tags' functionality in :py:meth:`__init__`,
|
||||||
however :py:class:`StyledTextBuffer` will merge them automatically if
|
however :py:class:`StyledTextBuffer` will merge them automatically if
|
||||||
the text is displayed.
|
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))
|
(POS_TEXT, POS_TAGS) = list(range(2))
|
||||||
|
|
||||||
@ -198,17 +201,27 @@ class StyledText:
|
|||||||
new_string = self._string.join([str(string) for string in seq])
|
new_string = self._string.join([str(string) for string in seq])
|
||||||
|
|
||||||
offset = 0
|
offset = 0
|
||||||
|
not_first = False
|
||||||
new_tags = []
|
new_tags = []
|
||||||
self_len = len(self._string)
|
self_len = len(self._string)
|
||||||
|
|
||||||
for text in seq:
|
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):
|
if isinstance(text, StyledText):
|
||||||
for tag in text.tags:
|
for tag in text.tags:
|
||||||
tag.ranges = [(start + offset, end + offset)
|
ntag = copy(tag)
|
||||||
for (start, end) in tag.ranges]
|
ntag.ranges = [(start + offset, end + offset)
|
||||||
new_tags += [tag]
|
for (start, end) in tag.ranges]
|
||||||
|
new_tags += [ntag]
|
||||||
offset = offset + len(str(text)) + self_len
|
offset += len(str(text))
|
||||||
|
not_first = True
|
||||||
|
|
||||||
return self.__class__(new_string, new_tags)
|
return self.__class__(new_string, new_tags)
|
||||||
|
|
||||||
@ -366,6 +379,7 @@ if __name__ == '__main__':
|
|||||||
from .styledtexttagtype import StyledTextTagType
|
from .styledtexttagtype import StyledTextTagType
|
||||||
T1 = StyledTextTag(StyledTextTagType(1), 'v1', [(0, 2), (2, 4), (4, 6)])
|
T1 = StyledTextTag(StyledTextTagType(1), 'v1', [(0, 2), (2, 4), (4, 6)])
|
||||||
T2 = StyledTextTag(StyledTextTagType(2), 'v2', [(1, 3), (3, 5), (0, 7)])
|
T2 = StyledTextTag(StyledTextTagType(2), 'v2', [(1, 3), (3, 5), (0, 7)])
|
||||||
|
T3 = StyledTextTag(StyledTextTagType(0), 'v3', [(0, 1)])
|
||||||
|
|
||||||
A = StyledText('123X456', [T1])
|
A = StyledText('123X456', [T1])
|
||||||
B = StyledText("abcXdef", [T2])
|
B = StyledText("abcXdef", [T2])
|
||||||
@ -376,7 +390,7 @@ if __name__ == '__main__':
|
|||||||
|
|
||||||
C = C.join([A, S, B])
|
C = C.join([A, S, B])
|
||||||
L = C.split()
|
L = C.split()
|
||||||
C = C.replace('X', StyledText('_'))
|
C = C.replace('X', StyledText('_', [T3]))
|
||||||
A = A + B
|
A = A + B
|
||||||
|
|
||||||
print(A)
|
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