Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

GTK3 port: Pango workarounds, revert when b646788 resolved

  • Loading branch information...
commit da815339e5ce3631b122a72158ba9ffcc9ee4372 1 parent da6ecb0
Matas Brazdeikis authored
Showing with 194 additions and 8 deletions.
  1. +89 −0 pitivi/utils/pygtkcompat.py
  2. +105 −8 pitivi/utils/text_buffer_markup.py
View
89 pitivi/utils/pygtkcompat.py
@@ -430,6 +430,95 @@ class Keysyms(object):
value = getattr(Gdk, name)
setattr(keysyms, target, value)
+ #Pango.AttrList
+ class AttrIterator():
+ def __init__ (self, attributes=[]):
+ self.attributes = attributes
+ self.attribute_stack = []
+ self.start_index = 0
+ self.end_index = 0
+ if not self.next():
+ self.end_index = 2**32 -1
+
+ def next(self):
+ if len(self.attributes) == 0 and len(self.attribute_stack) == 0:
+ return False
+ self.start_index = self.end_index
+ self.end_index = 2**32 - 1
+
+ to_remove = []
+ for attr in self.attribute_stack:
+ if attr.end_index == self.start_index:
+ to_remove.append(attr)
+ else:
+ self.end_index = min(self.end_index, attr.end_index)
+
+ while len(to_remove) > 0:
+ attr = to_remove[0]
+ self.attribute_stack.remove(to_remove[0])
+ try:
+ to_remove.remove(attr)
+ except:
+ pass
+
+ while len(self.attributes) != 0 and \
+ self.attributes[0].start_index == self.start_index:
+ if self.attributes[0].end_index > self.start_index:
+ self.attribute_stack.append(self.attributes[0])
+ self.end_index = min(self.end_index, self.attributes[0].end_index)
+ self.attributes = self.attributes[1:]
+ if len(self.attributes) > 0:
+ self.end_index = min(self.end_index, self.attributes[0].start_index)
+ return True
+
+ def range(self):
+ return (self.start_index, self.end_index)
+
+ def get_font(self):
+ tmp_list1 = self.attribute_stack
+ fontdesc = Pango.FontDescription()
+ for attr in self.attribute_stack:
+ if attr.klass.type == Pango.ATTR_FONT_DESC:
+ tmp_list1.remove(attr)
+ attr.__class__ = gi.repository.Pango.AttrFontDesc
+ fontdesc = attr.desc
+ return (fontdesc, None, self.attribute_stack)
+
+
+
+ def get_iterator(self):
+ tmplist = []
+ def fil(val, data):
+ tmplist.append(val)
+ return False
+ self.filter(fil, None)
+ return AttrIterator(tmplist)
+
+
+ setattr(Pango.AttrList, 'get_iterator', get_iterator)
+ class AttrFamily(Pango.Attribute):
+ pass
+ Pango.AttrFamily = AttrFamily
+
+ class AttrStyle(Pango.Attribute):
+ pass
+ Pango.AttrStyle = AttrStyle
+
+ class AttrVariant(Pango.Attribute):
+ pass
+ Pango.AttrVariant = AttrVariant
+
+ class AttrWeight(Pango.Attribute):
+ pass
+ Pango.AttrWeight = AttrWeight
+
+ class AttrVariant(Pango.Attribute):
+ pass
+ Pango.AttrVariant = AttrVariant
+
+ class AttrStretch(Pango.Attribute):
+ pass
+ Pango.AttrStretch = AttrStretch
def enable_vte():
gi.require_version('Vte', '0.0')
View
113 pitivi/utils/text_buffer_markup.py
@@ -21,6 +21,7 @@
import xml.sax.saxutils
+import gi
class PangoBuffer(gtk.TextBuffer):
desc_to_attr_table = {
'family': [pango.AttrFamily, ""],
@@ -41,6 +42,21 @@ class PangoBuffer(gtk.TextBuffer):
pango.ATTR_FAMILY: 'family',
pango.ATTR_STRIKETHROUGH: 'strikethrough',
pango.ATTR_RISE: 'rise'}
+ pango_type_table = {
+ pango.ATTR_SIZE: gi.repository.Pango.AttrInt,
+ pango.ATTR_WEIGHT: gi.repository.Pango.AttrInt,
+ pango.ATTR_UNDERLINE: gi.repository.Pango.AttrInt,
+ pango.ATTR_STRETCH: gi.repository.Pango.AttrInt,
+ pango.ATTR_VARIANT: gi.repository.Pango.AttrInt,
+ pango.ATTR_STYLE: gi.repository.Pango.AttrInt,
+ pango.ATTR_SCALE: gi.repository.Pango.AttrFloat,
+ pango.ATTR_FAMILY: gi.repository.Pango.AttrString,
+ pango.ATTR_FONT_DESC: gi.repository.Pango.AttrFontDesc,
+ pango.ATTR_STRIKETHROUGH: gi.repository.Pango.AttrInt,
+ pango.ATTR_BACKGROUND: gi.repository.Pango.AttrColor,
+ pango.ATTR_FOREGROUND: gi.repository.Pango.AttrColor,
+ pango.ATTR_RISE: gi.repository.Pango.AttrInt}
+
attval_to_markup = {
'underline': {pango.UNDERLINE_SINGLE: 'single',
pango.UNDERLINE_DOUBLE: 'double',
@@ -77,7 +93,9 @@ def set_text(self, txt):
gtk.TextBuffer.set_text(self, "")
suc, self.parsed, self.txt, self.separator = pango.parse_markup(txt, -1, u'\x00')
if not suc:
+ oldtxt = txt
txt = xml.sax.saxutils.escape(txt)
+ self.warn("Marked text is not correct. Escape %s to %s", oldtxt, txt)
suc, self.parsed, self.txt, self.separator = pango.parse_markup(txt, -1, u'\x00')
self.attrIter = self.parsed.get_iterator()
self.add_iter_to_buffer()
@@ -85,14 +103,14 @@ def set_text(self, txt):
self.add_iter_to_buffer()
def add_iter_to_buffer(self):
- range = self.attrIter.range()
+ it_range = self.attrIter.range()
font, lang, attrs = self.attrIter.get_font()
tags = self.get_tags_from_attrs(font, lang, attrs)
- text = self.txt[range[0]:range[1]]
+ text = self.txt[it_range[0]:it_range[1]]
if tags:
self.insert_with_tags(self.get_end_iter(), text, *tags)
else:
- self.insert(self.get_end_iter(), text)
+ self.insert_with_tags(self.get_end_iter(), text, *tags)
def get_tags_from_attrs(self, font, lang, attrs):
tags = []
@@ -109,6 +127,16 @@ def get_tags_from_attrs(self, font, lang, attrs):
tags.append(self.tags[lang])
if attrs:
for a in attrs:
+ #FIXME remove on pango fix
+ type_ = a.klass.type
+ klass = a.klass
+ start_index = a.start_index
+ end_index = a.end_index
+ a.__class__ = self.pango_type_table[type_]
+ a.type = type_
+ a.start_index = start_index
+ a.end_index = end_index
+ a.klass = klass
if a.type == pango.ATTR_FOREGROUND:
gdkcolor = self.pango_color_to_gdk(a.color)
key = 'foreground%s' % self.color_to_hex(gdkcolor)
@@ -158,6 +186,71 @@ def get_tags(self):
tagdict[tag] = [(pos, pos)]
return tagdict
+ def split(self, interval, split_interval):
+ #We want as less intervals as posible
+ # interval represented []
+ # split interval represented {}
+ if interval == split_interval:
+ #[{ }]
+ return [interval]
+ if interval[1] < split_interval[0] or split_interval[1] < interval[0]:
+ #[ ] { }
+ return [interval]
+
+ if interval[0] == split_interval[0]:
+ #{[
+ if interval[1] < split_interval[1]:
+ #{[ ] }
+ return [interval]
+ else:
+ #{[ } ] -> {[ ]}[ ]
+ return [(interval[0], split_interval[1]),
+ (split_interval[1] + 1, interval[1])]
+
+ if interval[0] < split_interval[0]:
+ #[ {
+ if interval[1] == split_interval[1]:
+ #[ { ]} - > [ ]{[ ]}
+ return [(interval[0], split_interval[0] - 1),
+ (split_interval[0], interval[1])]
+ elif interval[1] < split_interval[1]:
+ #[ { ] } -> [ ]{[ ] }
+ return [(interval[0], split_interval[0] - 1),
+ (split_interval[0], interval[1])]
+ else: #interval[1] > split_interval[1]
+ #[ { } ] -> [ ][{ }][ ]
+ return [(interval[0], split_interval[0] - 1),
+ (split_interval[0], split_interval[1]),
+ (split_interval[1] + 1, interval[1])]
+
+ if interval[0] > split_interval[0]:
+ #{ [
+ if interval[1] == split_interval[1]:
+ #{ [ ]}
+ return [interval]
+ elif interval[1] < split_interval[1]:
+ #{ [ ] }
+ return [interval]
+ else: #interval[1] > split_interval[1]
+ #{ [ } ] - > { [ ]}[ ]
+ return [(interval[0], split_interval[1]),
+ (split_interval[1] + 1, interval[1])]
+
+ def split_overlap(self, tagdict):
+ intervals = []
+ for k, v in tagdict.items():
+ #Split by exsiting intervals
+ tmpint = v
+ for i in intervals:
+ iterint = tmpint
+ tmpint = []
+ for st, e in iterint:
+ tmpint.extend(self.split((st,e), i))
+ tagdict[k] = tmpint
+ #Add new intervals
+ intervals.extend(tmpint)
+ return tagdict
+
def get_text(self, start=None, end=None, include_hidden_chars=True):
tagdict = self.get_tags()
if not start:
@@ -165,6 +258,8 @@ def get_text(self, start=None, end=None, include_hidden_chars=True):
if not end:
end = self.get_end_iter()
txt = unicode(gtk.TextBuffer.get_text(self, start, end, True))
+ #Important step, split that no tags overlap
+ tagdict = self.split_overlap(tagdict)
cuts = {}
for k, v in tagdict.items():
stag, etag = self.tag_to_markup(k)
@@ -237,11 +332,6 @@ def remove_font_and_attrs(self, font, attrs):
for t in tags:
self.remove_tag_from_selection(t)
- def setup_default_tags(self):
- self.italics = self.get_tags_from_attrs(None, None, [pango.AttrStyle('italic')])[0]
- self.bold = self.get_tags_from_attrs(None, None, [pango.AttrWeight('bold')])[0]
- self.underline = self.get_tags_from_attrs(None, None, [pango.AttrUnderline('single')])[0]
-
def get_selection(self):
bounds = self.get_selection_bounds()
if not bounds:
@@ -301,6 +391,13 @@ def __init__(self,
for w, tup in toggle_widget_alist:
self.setup_widget(w, *tup)
+ def set_text(self, txt):
+ self.disconnect_by_func(self._changed_cb)
+ self.disconnect_by_func(self._mark_set_cb)
+ PangoBuffer.set_text(self, txt)
+ self.connect('changed', self._changed_cb)
+ self.connect('mark-set', self._mark_set_cb)
+
def setup_widget_from_pango(self, widg, markupstring):
"""setup widget from a pango markup string"""
#font = pango.FontDescription(fontstring)
Please sign in to comment.
Something went wrong with that request. Please try again.