2007-03-13 Zsolt Foldvari <zfoldvar@users.sourceforge.net>
* src/RelLib/_Note.py: import const from MarkupText module * src/MarkupText.py: use actions instead of widgets on the interface; new helper functions * src/Editors/_EditNote.py: move widgets out to glade; implement new MarkupText buffer interface; use uimanager/toolbar for formatting * src/glade/gramps.glade: edit_note update svn: r8292
This commit is contained in:
parent
7593dbfe69
commit
63e344754f
@ -1,3 +1,11 @@
|
||||
2007-03-13 Zsolt Foldvari <zfoldvar@users.sourceforge.net>
|
||||
* src/RelLib/_Note.py: import const from MarkupText module
|
||||
* src/MarkupText.py: use actions instead of widgets on the interface;
|
||||
new helper functions
|
||||
* src/Editors/_EditNote.py: move widgets out to glade; implement new
|
||||
MarkupText buffer interface; use uimanager/toolbar for formatting
|
||||
* src/glade/gramps.glade: edit_note update
|
||||
|
||||
2007-03-11 Brian Matherly <brian@gramps-project.org>
|
||||
* src/ReportBase/_ReportDialog.py: don't catch all exceptions - we won't
|
||||
get a traceback.
|
||||
|
@ -69,10 +69,10 @@ class EditNote(EditPrimary):
|
||||
return RelLib.Note()
|
||||
|
||||
def get_menu_title(self):
|
||||
if self.obj.get_handle():
|
||||
title = _('Note') + ': %s' % self.obj.get_gramps_id()
|
||||
else:
|
||||
title = _('New Note')
|
||||
if self.obj.get_handle():
|
||||
title = _('Note') + ': %s' % self.obj.get_gramps_id()
|
||||
else:
|
||||
title = _('New Note')
|
||||
return title
|
||||
|
||||
def _local_init(self):
|
||||
@ -89,28 +89,25 @@ class EditNote(EditPrimary):
|
||||
height = Config.get(Config.NOTE_HEIGHT)
|
||||
self.window.set_default_size(width, height)
|
||||
|
||||
self.type = self.top.get_widget('type')
|
||||
self.format = self.top.get_widget('format')
|
||||
|
||||
container = self.top.get_widget('container')
|
||||
container.pack_start(self.build_interface())
|
||||
container.show_all()
|
||||
|
||||
self.build_interface()
|
||||
self.window.show_all()
|
||||
|
||||
def _setup_fields(self):
|
||||
|
||||
"""Get control widgets and attached them to Note's attributes."""
|
||||
self.type_selector = MonitoredDataType(
|
||||
self.top.get_widget("type"),
|
||||
self.top.get_widget('type'),
|
||||
self.obj.set_type,
|
||||
self.obj.get_type,
|
||||
self.db.readonly)
|
||||
|
||||
self.check = MonitoredCheckbox(
|
||||
self.obj,
|
||||
self.format,
|
||||
self.top.get_widget('format'),
|
||||
self.obj.set_format,
|
||||
self.obj.get_format,
|
||||
on_toggle = self.flow_changed,
|
||||
readonly = self.db.readonly)
|
||||
|
||||
|
||||
self.gid = MonitoredEntry(
|
||||
self.top.get_widget('id'),
|
||||
self.obj.set_gramps_id,
|
||||
@ -125,118 +122,102 @@ class EditNote(EditPrimary):
|
||||
self.db.get_marker_types())
|
||||
|
||||
def _connect_signals(self):
|
||||
"""
|
||||
Connects any signals that need to be connected. Called by the
|
||||
init routine of the base class (_EditPrimary).
|
||||
"""Connects any signals that need to be connected.
|
||||
|
||||
Called by the init routine of the base class (_EditPrimary).
|
||||
|
||||
"""
|
||||
self.define_ok_button(self.top.get_widget('ok'),self.save)
|
||||
self.define_cancel_button(self.top.get_widget('cancel'))
|
||||
|
||||
self.define_help_button(self.top.get_widget('help'), '')
|
||||
|
||||
def build_interface(self):
|
||||
BUTTON = [(_('Italic'),gtk.STOCK_ITALIC,'<i>i</i>','<Control>I'),
|
||||
(_('Bold'),gtk.STOCK_BOLD,'<b>b</b>','<Control>B'),
|
||||
(_('Underline'),gtk.STOCK_UNDERLINE,'<u>u</u>','<Control>U'),
|
||||
#('Separator', None, None, None),
|
||||
]
|
||||
FORMAT_TOOLBAR = '''
|
||||
<ui>
|
||||
<toolbar name="ToolBar">
|
||||
<toolitem action="italic"/>
|
||||
<toolitem action="bold"/>
|
||||
<toolitem action="underline"/>
|
||||
</toolbar>
|
||||
</ui>
|
||||
'''
|
||||
format_actions = [
|
||||
('<i>i</i>','<Control>I',
|
||||
('italic',_('Italic'),_('Italic'),gtk.STOCK_ITALIC)),
|
||||
('<b>b</b>','<Control>B',
|
||||
('bold',_('Bold'),_('Bold'),gtk.STOCK_BOLD)),
|
||||
('<u>u</u>','<Control>U',
|
||||
('underline',_('Underline'),_('Underline'),gtk.STOCK_UNDERLINE)),
|
||||
]
|
||||
|
||||
vbox = gtk.VBox()
|
||||
buffer = EditorBuffer()
|
||||
|
||||
self.text = gtk.TextView()
|
||||
self.text.set_accepts_tab(True)
|
||||
self.text = self.top.get_widget('text')
|
||||
self.text.set_editable(not self.dbstate.db.readonly)
|
||||
self.spellcheck = Spell.Spell(self.text)
|
||||
self.text.set_buffer(buffer)
|
||||
|
||||
if self.obj and self.obj.get_format():
|
||||
self.format.set_active(True)
|
||||
self.text.set_wrap_mode(gtk.WRAP_NONE)
|
||||
else:
|
||||
self.format.set_active(False)
|
||||
self.text.set_wrap_mode(gtk.WRAP_WORD)
|
||||
|
||||
scroll = gtk.ScrolledWindow()
|
||||
scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
|
||||
scroll.set_shadow_type(gtk.SHADOW_IN)
|
||||
scroll.add(self.text)
|
||||
|
||||
self.buf = EditorBuffer()
|
||||
self.text.set_buffer(self.buf)
|
||||
# create a formatting toolbar and pass the actions
|
||||
# together with the related markup tag to the buffer
|
||||
if not self.dbstate.db.readonly:
|
||||
uimanager = gtk.UIManager()
|
||||
accelgroup = uimanager.get_accel_group()
|
||||
self.window.add_accel_group(accelgroup)
|
||||
|
||||
action_group = gtk.ActionGroup('Format')
|
||||
for markup, accel, action_desc in format_actions:
|
||||
action = gtk.ToggleAction(*action_desc)
|
||||
action_group.add_action_with_accel(action, accel)
|
||||
# FIXME why are these needed?
|
||||
# Shouldn't uimanager do it automatically!?
|
||||
action.set_accel_group(accelgroup)
|
||||
action.connect_accelerator()
|
||||
#
|
||||
buffer.setup_action_from_xml(action, markup)
|
||||
|
||||
uimanager.insert_action_group(action_group, 0)
|
||||
uimanager.add_ui_from_string(FORMAT_TOOLBAR)
|
||||
uimanager.ensure_update()
|
||||
|
||||
toolbar = uimanager.get_widget('/ToolBar')
|
||||
toolbar.set_style(gtk.TOOLBAR_ICONS)
|
||||
vbox = self.top.get_widget('container')
|
||||
vbox.pack_start(toolbar, False)
|
||||
|
||||
# setup initial values for textview and buffer
|
||||
if self.obj:
|
||||
self.empty = False
|
||||
self.buf.set_text(self.obj.get(markup=True))
|
||||
self.flow_changed(self.obj.get_format())
|
||||
buffer.set_text(self.obj.get(markup=True))
|
||||
log.debug("Initial Note: %s" % buffer.get_text())
|
||||
else:
|
||||
self.empty = True
|
||||
|
||||
if not self.dbstate.db.readonly:
|
||||
self.accelerator = {}
|
||||
hbox = gtk.HBox()
|
||||
hbox.set_spacing(0)
|
||||
hbox.set_border_width(0)
|
||||
vbox.pack_start(hbox, False)
|
||||
# connection to buffer signals must be after the initial values are set
|
||||
buffer.connect('changed', self.update_note)
|
||||
buffer.connect_after('apply-tag', self.update_note)
|
||||
buffer.connect_after('remove-tag', self.update_note)
|
||||
|
||||
tooltips = gtk.Tooltips()
|
||||
for tip, stock, markup, accel in BUTTON:
|
||||
if markup:
|
||||
button = gtk.ToggleButton()
|
||||
image = gtk.Image()
|
||||
image.set_from_stock(stock, gtk.ICON_SIZE_MENU)
|
||||
button.set_image(image)
|
||||
button.set_relief(gtk.RELIEF_NONE)
|
||||
tooltips.set_tip(button, tip)
|
||||
self.buf.setup_widget_from_xml(button, markup)
|
||||
key, mod = gtk.accelerator_parse(accel)
|
||||
self.accelerator[(key, mod)] = button
|
||||
hbox.pack_start(button, False)
|
||||
else:
|
||||
hbox.pack_start(gtk.VSeparator(), False)
|
||||
|
||||
vbox.pack_start(scroll, True)
|
||||
vbox.set_spacing(6)
|
||||
vbox.set_border_width(6)
|
||||
|
||||
if self.dbstate.db.readonly:
|
||||
self.text.set_editable(False)
|
||||
return vbox
|
||||
|
||||
# Accelerator dictionary used for formatting shortcuts
|
||||
# key: tuple(key, modifier)
|
||||
# value: widget, to emit 'activate' signal on
|
||||
self.text.connect('key-press-event', self._on_key_press_event)
|
||||
|
||||
self.spellcheck = Spell.Spell(self.text)
|
||||
|
||||
self.format.connect('toggled', self.flow_changed)
|
||||
|
||||
self.buf.connect('changed', self.update)
|
||||
self.buf.connect_after('apply-tag', self.update)
|
||||
self.buf.connect_after('remove-tag', self.update)
|
||||
#self.rebuild()
|
||||
return vbox
|
||||
|
||||
def _on_key_press_event(self, widget, event):
|
||||
#log.debug("Key %s (%d) was pressed on %s" %
|
||||
#(gtk.gdk.keyval_name(event.keyval), event.keyval, widget))
|
||||
key = event.keyval
|
||||
mod = event.state
|
||||
if self.accelerator.has_key((key, mod)):
|
||||
self.accelerator[(key, mod)].emit('activate')
|
||||
return True
|
||||
|
||||
def update(self, obj, *args):
|
||||
def update_note(self, buffer, *args):
|
||||
"""Update the Note object with current value.
|
||||
|
||||
This happens after each change in the text or the formatting.
|
||||
|
||||
"""
|
||||
if self.obj:
|
||||
start = self.buf.get_start_iter()
|
||||
stop = self.buf.get_end_iter()
|
||||
text = self.buf.get_text(start, stop)
|
||||
start = buffer.get_start_iter()
|
||||
stop = buffer.get_end_iter()
|
||||
text = buffer.get_text(start, stop)
|
||||
self.obj.set(text)
|
||||
else:
|
||||
print "NOTE OBJ DOES NOT EXIST"
|
||||
log.debug("NOTE OBJ DOES NOT EXIST")
|
||||
return False
|
||||
|
||||
def flow_changed(self, obj):
|
||||
if obj.get_active():
|
||||
def flow_changed(self, active):
|
||||
if active:
|
||||
self.text.set_wrap_mode(gtk.WRAP_NONE)
|
||||
self.obj.set_format(True)
|
||||
else:
|
||||
self.text.set_wrap_mode(gtk.WRAP_WORD)
|
||||
self.obj.set_format(False)
|
||||
|
||||
def save(self, *obj):
|
||||
"""
|
||||
|
@ -53,12 +53,29 @@ log = logging.getLogger(".MarkupText")
|
||||
#-------------------------------------------------------------------------
|
||||
import gtk
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Constants
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
ROOT_ELEMENT = 'gramps'
|
||||
ROOT_START_TAG = '<' + ROOT_ELEMENT + '>'
|
||||
ROOT_END_TAG = '</' + ROOT_ELEMENT + '>'
|
||||
LEN_ROOT_START_TAG = len(ROOT_START_TAG)
|
||||
LEN_ROOT_END_TAG = len(ROOT_END_TAG)
|
||||
|
||||
def is_gramps_markup(text):
|
||||
return (text[:LEN_ROOT_START_TAG] == ROOT_START_TAG and
|
||||
text[-LEN_ROOT_END_TAG:] == ROOT_END_TAG)
|
||||
|
||||
def clear_root_tags(text):
|
||||
return text[LEN_ROOT_START_TAG:len(text)-LEN_ROOT_END_TAG]
|
||||
|
||||
class MarkupParser(ContentHandler):
|
||||
"""A simple ContentHandler class to parse Gramps markup'ed text.
|
||||
|
||||
Use it with xml.sax.parse() or xml.sax.parseString(). A root tag, 'gramps',
|
||||
is required. Parsing result can be obtained via the public attributes of
|
||||
Use it with xml.sax.parse() or xml.sax.parseString(). A root tag is
|
||||
required. Parsing result can be obtained via the public attributes of
|
||||
the class:
|
||||
@attr content: clean text
|
||||
@attr type: str
|
||||
@ -77,7 +94,7 @@ class MarkupParser(ContentHandler):
|
||||
|
||||
def startElement(self, name, attrs):
|
||||
if not self._open_document:
|
||||
if name == 'gramps':
|
||||
if name == ROOT_ELEMENT:
|
||||
self._open_document = True
|
||||
else:
|
||||
raise SAXParseException('Root element missing')
|
||||
@ -89,7 +106,7 @@ class MarkupParser(ContentHandler):
|
||||
|
||||
def endElement(self, name):
|
||||
# skip root element
|
||||
if name == 'gramps':
|
||||
if name == ROOT_ELEMENT:
|
||||
return
|
||||
|
||||
for e in self._open_elements:
|
||||
@ -221,7 +238,7 @@ class MarkupWriter:
|
||||
def generate(self, text, elements):
|
||||
# reset output and start root element
|
||||
self._output.truncate(0)
|
||||
self._writer.startElement('gramps', self._attrs)
|
||||
self._writer.startElement(ROOT_ELEMENT, self._attrs)
|
||||
|
||||
# split the elements to events
|
||||
events = self._elements_to_events(elements)
|
||||
@ -241,7 +258,7 @@ class MarkupWriter:
|
||||
self._writer.characters(text[last_pos:])
|
||||
|
||||
# close root element and end doc
|
||||
self._writer.endElement('gramps')
|
||||
self._writer.endElement(ROOT_ELEMENT)
|
||||
self._writer.endDocument()
|
||||
|
||||
# copy result
|
||||
@ -444,6 +461,7 @@ class EditorBuffer(MarkupBuffer):
|
||||
if normal_button:
|
||||
normal_button.connect('clicked',lambda *args: self.remove_all_tags())
|
||||
self.tag_widgets = {}
|
||||
self.tag_actions = {}
|
||||
self.internal_toggle = False
|
||||
self.insert = self.get_insert()
|
||||
for widg, name in toggle_widget_alist:
|
||||
@ -462,7 +480,8 @@ class EditorBuffer(MarkupBuffer):
|
||||
if old_itr != insert_itr:
|
||||
# Use the state of our widgets to determine what
|
||||
# properties to apply...
|
||||
for tag, w in self.tag_widgets.items():
|
||||
for tag, w in self.tag_actions.items():
|
||||
##for tag, w in self.tag_widgets.items():
|
||||
if w.get_active():
|
||||
self.apply_tag(tag, old_itr, insert_itr)
|
||||
|
||||
@ -474,7 +493,8 @@ class EditorBuffer(MarkupBuffer):
|
||||
|
||||
self._in_mark_set = True
|
||||
if mark.get_name() == 'insert':
|
||||
for tag,widg in self.tag_widgets.items():
|
||||
##for tag,widg in self.tag_widgets.items():
|
||||
for tag,widg in self.tag_actions.items():
|
||||
active = True
|
||||
if not iter.has_tag(tag):
|
||||
active = False
|
||||
@ -503,10 +523,12 @@ class EditorBuffer(MarkupBuffer):
|
||||
def setup_widget_from_xml(self, widg, xmlstring):
|
||||
"""Setup widget from an xml markup string."""
|
||||
try:
|
||||
parseString("<gramps>%s</gramps>" % xmlstring, self.parser)
|
||||
parseString((ROOT_START_TAG + '%s' + ROOT_END_TAG) % xmlstring,
|
||||
self.parser)
|
||||
except:
|
||||
log.error('"%s" is not a valid Gramps XML format.' % xmlstring)
|
||||
|
||||
# whatever is included we'll use only the first element
|
||||
(start, end), name, attrs = self.parser.elements[0]
|
||||
|
||||
return self.setup_widget(widg, name)
|
||||
@ -517,92 +539,24 @@ class EditorBuffer(MarkupBuffer):
|
||||
self.tag_widgets[tag] = widg
|
||||
return widg.connect('toggled', self._toggle, tag)
|
||||
|
||||
def setup_action_from_xml(self, action, xmlstring):
|
||||
"""Setup action from an xml markup string."""
|
||||
try:
|
||||
parseString((ROOT_START_TAG + '%s' + ROOT_END_TAG) % xmlstring,
|
||||
self.parser)
|
||||
except:
|
||||
log.error('"%s" is not a valid Gramps XML format.' % xmlstring)
|
||||
|
||||
# whatever is included we'll use only the first element
|
||||
(start, end), name, attrs = self.parser.elements[0]
|
||||
|
||||
return self.setup_action(action, name)
|
||||
|
||||
def setup_action(self, action, name):
|
||||
"""Setup action from Gramps tag name."""
|
||||
tag = self.get_tag_from_element(name)
|
||||
self.tag_actions[tag] = action
|
||||
return action.connect('activate', self._toggle, tag)
|
||||
|
||||
if gtk.pygtk_version < (2,8,0):
|
||||
gobject.type_register(EditorBuffer)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import sys
|
||||
|
||||
def main(args):
|
||||
win = gtk.Window()
|
||||
win.set_title('MarkupBuffer test window')
|
||||
win.set_position(gtk.WIN_POS_CENTER)
|
||||
def cb(window, event):
|
||||
gtk.main_quit()
|
||||
win.connect('delete-event', cb)
|
||||
|
||||
accel_group = gtk.AccelGroup()
|
||||
win.add_accel_group(accel_group)
|
||||
|
||||
vbox = gtk.VBox()
|
||||
win.add(vbox)
|
||||
|
||||
text = gtk.TextView()
|
||||
text.set_accepts_tab(True)
|
||||
|
||||
flowed = gtk.RadioButton(None, 'Flowed')
|
||||
format = gtk.RadioButton(flowed, 'Formatted')
|
||||
|
||||
#if self.note_obj and self.note_obj.get_format():
|
||||
#self.format.set_active(True)
|
||||
#self.text.set_wrap_mode(gtk.WRAP_NONE)
|
||||
#else:
|
||||
#self.flowed.set_active(True)
|
||||
#self.text.set_wrap_mode(gtk.WRAP_WORD)
|
||||
#self.spellcheck = Spell.Spell(self.text)
|
||||
|
||||
#flowed.connect('toggled', flow_changed)
|
||||
|
||||
scroll = gtk.ScrolledWindow()
|
||||
scroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
|
||||
scroll.add(text)
|
||||
|
||||
vbox.pack_start(scroll, True)
|
||||
vbox.set_spacing(6)
|
||||
vbox.set_border_width(6)
|
||||
|
||||
hbox = gtk.HBox()
|
||||
hbox.set_spacing(12)
|
||||
hbox.set_border_width(6)
|
||||
hbox.pack_start(flowed, False)
|
||||
hbox.pack_start(format, False)
|
||||
|
||||
vbox.pack_start(hbox, False)
|
||||
|
||||
#self.pack_start(vbox, True)
|
||||
buf = EditorBuffer()
|
||||
text.set_buffer(buf)
|
||||
tooltips = gtk.Tooltips()
|
||||
for tip,stock,font,accel in [('Italic',gtk.STOCK_ITALIC,'<i>i</i>','<Control>I'),
|
||||
('Bold',gtk.STOCK_BOLD,'<b>b</b>','<Control>B'),
|
||||
('Underline',gtk.STOCK_UNDERLINE,'<u>u</u>','<Control>U'),
|
||||
]:
|
||||
button = gtk.ToggleButton()
|
||||
image = gtk.Image()
|
||||
image.set_from_stock(stock, gtk.ICON_SIZE_MENU)
|
||||
button.set_image(image)
|
||||
tooltips.set_tip(button, tip)
|
||||
button.set_relief(gtk.RELIEF_NONE)
|
||||
buf.setup_widget_from_xml(button,font)
|
||||
key, mod = gtk.accelerator_parse(accel)
|
||||
button.add_accelerator('activate', accel_group,
|
||||
key, mod, gtk.ACCEL_VISIBLE)
|
||||
hbox.pack_start(button, False)
|
||||
|
||||
buf.set_text('<gramps>'
|
||||
'<b>Bold</b>. <i>Italic</i>. <u>Underline</u>.'
|
||||
'</gramps>')
|
||||
|
||||
win.show_all()
|
||||
gtk.main()
|
||||
|
||||
|
||||
stderrh = logging.StreamHandler(sys.stderr)
|
||||
stderrh.setLevel(logging.DEBUG)
|
||||
|
||||
log = logging.getLogger()
|
||||
log.setLevel(logging.DEBUG)
|
||||
log.addHandler(stderrh)
|
||||
|
||||
sys.exit(main(sys.argv))
|
||||
|
@ -40,6 +40,7 @@ import re
|
||||
#-------------------------------------------------------------------------
|
||||
from _BasicPrimaryObject import BasicPrimaryObject
|
||||
from _NoteType import NoteType
|
||||
from MarkupText import ROOT_START_TAG, LEN_ROOT_START_TAG
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
@ -114,7 +115,7 @@ class Note(BasicPrimaryObject):
|
||||
"""
|
||||
text = self.text
|
||||
|
||||
if not markup and text[0:8] == '<gramps>':
|
||||
if not markup and text[0:LEN_ROOT_START_TAG] == ROOT_START_TAG:
|
||||
text = self.delete_tags(text)
|
||||
|
||||
return text
|
||||
|
@ -14983,7 +14983,6 @@ Very High</property>
|
||||
</widget>
|
||||
|
||||
<widget class="GtkDialog" id="edit_note">
|
||||
<property name="visible">True</property>
|
||||
<property name="title" translatable="yes"></property>
|
||||
<property name="type">GTK_WINDOW_TOPLEVEL</property>
|
||||
<property name="window_position">GTK_WIN_POS_NONE</property>
|
||||
@ -15008,7 +15007,7 @@ Very High</property>
|
||||
<property name="spacing">0</property>
|
||||
|
||||
<child internal-child="action_area">
|
||||
<widget class="GtkHButtonBox" id="dialog-action_area25">
|
||||
<widget class="GtkHButtonBox" id="action_area">
|
||||
<property name="visible">True</property>
|
||||
<property name="layout_style">GTK_BUTTONBOX_END</property>
|
||||
|
||||
@ -15037,6 +15036,19 @@ Very High</property>
|
||||
<property name="response_id">-5</property>
|
||||
</widget>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkButton" id="help">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label">gtk-help</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||
<property name="focus_on_click">True</property>
|
||||
<property name="response_id">-11</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
@ -15054,12 +15066,46 @@ Very High</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkVBox" id="container">
|
||||
<property name="border_width">6</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="spacing">0</property>
|
||||
<property name="spacing">6</property>
|
||||
|
||||
<child>
|
||||
<placeholder/>
|
||||
<widget class="GtkScrolledWindow" id="scroll">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
|
||||
<property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
|
||||
<property name="shadow_type">GTK_SHADOW_IN</property>
|
||||
<property name="window_placement">GTK_CORNER_TOP_LEFT</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkTextView" id="text">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="editable">True</property>
|
||||
<property name="overwrite">False</property>
|
||||
<property name="accepts_tab">True</property>
|
||||
<property name="justification">GTK_JUSTIFY_LEFT</property>
|
||||
<property name="wrap_mode">GTK_WRAP_NONE</property>
|
||||
<property name="cursor_visible">True</property>
|
||||
<property name="pixels_above_lines">0</property>
|
||||
<property name="pixels_below_lines">0</property>
|
||||
<property name="pixels_inside_wrap">0</property>
|
||||
<property name="left_margin">0</property>
|
||||
<property name="right_margin">0</property>
|
||||
<property name="indent">0</property>
|
||||
<property name="text" translatable="yes"></property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="pack_type">GTK_PACK_END</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
|
Loading…
Reference in New Issue
Block a user