24
24
# TODO: recode the whole pango code
28
28
from gtk import glade
35
import xml.sax,xml.sax.handler
36
from cStringIO import StringIO
36
38
class textbox_tag(interface.widget_interface):
37
39
desc_to_attr_table = {
38
'family':[pango.AttrFamily,""],
40
# 'family':[pango.AttrFamily,""],
39
41
'style':[pango.AttrStyle,pango.STYLE_NORMAL],
40
42
'variant':[pango.AttrVariant,pango.VARIANT_NORMAL],
41
43
'weight':[pango.AttrWeight,pango.WEIGHT_NORMAL],
72
74
pango.STYLE_OBLIQUE:'oblique',
73
75
pango.STYLE_ITALIC:'italic',
75
'stikethrough':{1:'true',
77
'strikethrough':{1:'true',
83
85
gtk.JUSTIFY_RIGHT : 'RIGHT',
84
86
gtk.JUSTIFY_LEFT : 'LEFT'
89
'underline':{'single':'u'},
91
'strikethrough':{'true':'strike'},
92
'style':{'italic':'i'},
93
'color':{'color':True},
87
97
def __init__(self,window, parent, model, attrs={}):
88
98
interface.widget_interface.__init__(self, window, parent, model, attrs)
99
109
self.buf.connect_after('insert-text', self.sig_insert_text)
100
110
self.buf.connect('mark-set', self.sig_mark_set)
102
112
# self.sizeButton = self.win_gl.get_widget('font_size')
103
113
# self.colorButton =self.win_gl.get_widget('font_color')
104
114
self.boldButton = self.win_gl.get_widget('toggle_bold')
105
115
self.italicButton = self.win_gl.get_widget('toggle_italic')
106
116
self.underlineButton = self.win_gl.get_widget('toggle_underline')
117
self.strikethroughButton=self.win_gl.get_widget('toggle_strikethrough')
109
120
self.internal_toggle = False
111
122
self.win_gl.signal_connect('on_toggle_bold_toggled', self._toggle, [self.bold])
112
123
self.win_gl.signal_connect('on_toggle_italic_toggled', self._toggle, [self.italic])
113
124
self.win_gl.signal_connect('on_toggle_underline_toggled', self._toggle, [self.underline])
125
self.win_gl.signal_connect('on_toggle_strike_toggled', self._toggle, [self.strikethrough])
114
126
# self.win_gl.signal_connect('on_font_size_changed',self._font_changed)
115
127
# self.win_gl.signal_connect('on_color_changed',self._color_changed)
128
self.win_gl.signal_connect('on_font_button_clicked',self._font_changed)
129
self.win_gl.signal_connect('on_color_button_clicked',self._color_changed)
117
132
self.justify = gtk.JUSTIFY_LEFT
119
134
self.leading = 14+7
120
135
self.win_gl.signal_connect('on_radiofill_toggled',self._toggle_justify, gtk.JUSTIFY_FILL)
121
136
self.win_gl.signal_connect('on_radiocenter_toggled',self._toggle_justify, gtk.JUSTIFY_CENTER)
135
150
for key, value in self.tagdict[tag].items():
136
151
if key == 'font_desc' and tag.get_priority() > (is_set.has_key(key) and is_set[key]) or 0:
137
152
# self.sizeButton.set_value(int(value[-2:]))
138
# is_set[key] = tag.get_priority()
153
# is_set[key] = tag.get_priority()
140
155
elif key == 'foreground' and tag.get_priority() > (is_set.has_key(key) and is_set[key]) or 0:
141
156
# self.colorButton.set_color(gtk.gdk.color_parse(value))
142
# is_set[key] = tag.get_priority()
157
# is_set[key] = tag.get_priority()
143
158
# color_priority = tag.get_priority()
145
160
elif key == 'weight' and tag.get_priority() > (is_set.has_key(key) and is_set[key]) or 0:
146
161
self.boldButton.set_active(True)
147
is_set[key] = tag.get_priority()
162
is_set[key] = tag.get_priority()
148
163
elif key == 'style' and value == 'italic' and tag.get_priority() > (is_set.has_key(key) and is_set[key]) or 0:
149
164
self.italicButton.set_active(True)
150
is_set[key] = tag.get_priority()
165
is_set[key] = tag.get_priority()
151
166
elif key == 'underline' and tag.get_priority() > (is_set.has_key(key) and is_set[key]) or 0:
152
167
self.underlineButton.set_active(True)
153
is_set[key] = tag.get_priority()
168
is_set[key] = tag.get_priority()
169
elif key == 'strikethrough' and tag.get_priority() > (is_set.has_key(key) and is_set[key]) or 0:
170
self.strikethroughButton.set_active(True)
171
is_set[key] = tag.get_priority()
154
172
#if no color defined, set to defalt (black)
155
173
if not is_set.has_key('foreground'):
156
174
# self.colorButton.set_color(gtk.gdk.color_parse('#000000'))
162
180
def _font_changed(self, widget, event=None):
163
font_desc = pango.FontDescription('Normal '+str(widget.get_value()))
164
self.leading = int(widget.get_value()*1.6)
181
font_desc = pango.FontDescription(str(widget.get_font_name()))
182
# self.leading = int(widget.get_value()*1.6)
165
183
self.apply_font_and_attrs(font_desc, [])
173
191
def get_tags_from_attrs (self, font,lang,attrs):
176
font,fontattrs = self.fontdesc_to_attrs(font)
177
fontdesc = font.to_string()
194
font1,fontattrs = self.fontdesc_to_attrs(font)
195
fontdesc = font1.to_string()
179
197
attrs.extend(fontattrs)
180
198
if fontdesc and fontdesc!='Normal':
181
if not self.tags.has_key(font.to_string()):
199
if not self.tags.has_key(font1.to_string()):
182
200
tag=self.buf.create_tag()
183
tag.set_property('font-desc',font)
201
tag.set_property('font-desc',font1)
184
202
if not self.tagdict.has_key(tag): self.tagdict[tag]={}
185
self.tagdict[tag]['font_desc']=font.to_string()
186
self.tags[font.to_string()]=tag
187
tags.append(self.tags[font.to_string()])
203
self.tagdict[tag]['face']=str(font.get_family())
204
self.tags[font1.to_string()]=tag
205
tags.append(self.tags[font1.to_string()])
189
207
if not self.tags.has_key(lang):
190
208
tag = self.buf.create_tag()
200
219
self.tags[key]=self.buf.create_tag()
201
220
self.tags[key].set_property('foreground-gdk',gdkcolor)
202
221
self.tagdict[self.tags[key]]={}
203
self.tagdict[self.tags[key]]['foreground']="#%s"%self.color_to_hex(gdkcolor)
222
self.tagdict[self.tags[key]]['color']="#%s"%self.color_to_hex(gdkcolor)
204
223
tags.append(self.tags[key])
205
224
if a.type == pango.ATTR_BACKGROUND:
206
225
gdkcolor = self.pango_color_to_gdk(a.color)
234
253
def get_tags (self, at_pos=None):
237
256
for pos in range(self.buf.get_char_count()):
238
257
iter=self.buf.get_iter_at_offset(pos)
239
258
for tag in iter.get_tags():
283
302
for tag in cuts[c]:
285
304
outbuff += txt[last_pos:]
286
outbuff = '<span alignment="' + self.alignment_markup[self.justify] \
287
+ '" leading="' + str(self.leading) + '">' + outbuff + '</span>'
305
outbuff = '<pre><p align="' + self.alignment_markup[self.justify] \
306
+ '" leading="' + str(self.leading) + '">' + outbuff + '</p></pre>'
290
310
def tag_to_markup (self, tag):
292
312
for k,v in self.tagdict[tag].items():
293
stag += ' %s="%s"'%(k,v)
295
return stag,"</span>"
313
if self.html_tags.has_key(k) and (self.html_tags[k].has_key(k) or self.html_tags[k].has_key(v)):
314
if k in ['color','face']:
315
stag='<font %s="%s">'%(k,v)
318
stag="<"+self.html_tags[k][v]+">"
319
etag="</"+self.html_tags[k][v]+">"
321
stag += ' %s="%s"'%(k,v)
322
if stag.startswith('<span'):
297
328
def fontdesc_to_attrs (self,font):
298
329
nicks = font.get_set_fields().value_nicks
329
360
self.italic = self.get_tags_from_attrs(None,None,[pango.AttrStyle('italic')])[0]
330
361
self.bold = self.get_tags_from_attrs(None,None,[pango.AttrWeight('bold')])[0]
331
362
self.underline = self.get_tags_from_attrs(None,None,[pango.AttrUnderline('single')])[0]
363
self.strikethrough = self.get_tags_from_attrs(None,None,[pango.AttrStrikethrough(1)])[0]
333
365
def get_selection (self):
334
366
bounds = self.buf.get_selection_bounds()
348
380
def apply_tag (self, tag):
349
381
insert_iter = self.buf.get_iter_at_mark(self.buf.get_insert())
350
382
selection = self.get_selection()
352
383
self.tags_dic[tag] = True
354
385
self.buf.apply_tag(tag, *selection)
372
403
def set_text (self, txt):
373
404
buf = self.tv.get_buffer()
374
txt = re.sub('<span alignment[^>]*>', '<span>', txt)
405
# txt = re.sub('<p align[^>]*>', '<p>', txt)
376
407
parsed, txt, separator = pango.parse_markup(txt, u'0')
379
attrIter = parsed.get_iterator()
411
attrIter = parsed.get_iterator()
413
# common.warning("Either the Message contains HTML tags or the selected Fonts are not supported!",'User Error')
380
416
buf.delete(buf.get_start_iter(), buf.get_end_iter())
382
418
range=attrIter.range()
433
470
self.internal_toggle=False
435
472
def display(self, model, model_field):
473
self.remove_all_tags()
436
474
super(textbox_tag, self).display(model, model_field)
437
475
value = model_field and model_field.get(model)
477
self.value=value or ''
478
self.set_text(self.value)
442
480
def set_value(self, model, model_field):
443
481
model_field.set_client(model, self.get_text() or False)