diff options
author | Simon Feltman <sfeltman@src.gnome.org> | 2013-04-27 21:58:28 -0700 |
---|---|---|
committer | Simon Feltman <sfeltman@src.gnome.org> | 2013-04-28 13:48:58 -0700 |
commit | ed41e260dcf5745fcc0656412be3c4a520ee20fc (patch) | |
tree | 7c0dff2a94caf7709014c9febfedbbcfb7c6a56d | |
parent | 150104db47ac5ba32758fba0c156adaecc0fbcc0 (diff) | |
download | pygobject-ed41e260dcf5745fcc0656412be3c4a520ee20fc.tar.gz |
gtk-demo: Use GtkSource.View for showing source code
Replace manual syntax highlighting of Gtk.TextView with usage of
GtkSource.View when available. Fall back to TextView with no
hightlighting when GtkSource is not available.
https://bugzilla.gnome.org/show_bug.cgi?id=698547
-rwxr-xr-x | demos/gtk-demo/gtk-demo.py | 170 |
1 files changed, 44 insertions, 126 deletions
diff --git a/demos/gtk-demo/gtk-demo.py b/demos/gtk-demo/gtk-demo.py index eeb05537..1025eafb 100755 --- a/demos/gtk-demo/gtk-demo.py +++ b/demos/gtk-demo/gtk-demo.py @@ -21,41 +21,23 @@ import codecs -import keyword import os -import tokenize import sys from gi.repository import GLib, GObject, Pango, GdkPixbuf, Gtk +try: + from gi.repository import GtkSource + GtkSource # PyFlakes +except ImportError: + GtkSource = None + DEMOROOTDIR = os.path.abspath(os.path.dirname(__file__)) DEMOCODEDIR = os.path.join(DEMOROOTDIR, 'demos') sys.path.insert(0, DEMOROOTDIR) -class InputStream(object): - """ - Simple Wrapper for File-like objects. [c]StringIO doesn't provide - a readline function for use with generate_tokens. - Using a iterator-like interface doesn't succeed, because the readline - function isn't used in such a context. (see <python-lib>/tokenize.py) - """ - def __init__(self, data): - self.__data = ['%s\n' % x for x in data.splitlines()] - self.__lcount = 0 - - def readline(self): - try: - line = self.__data[self.__lcount] - self.__lcount += 1 - except IndexError: - line = '' - self.__lcount = 0 - - return line - - class Demo(GObject.GObject): __gtype_name__ = 'GtkDemo' @@ -146,33 +128,15 @@ class GtkDemoWindow(Gtk.Window): notebook = Gtk.Notebook() hbox.pack_start(notebook, True, True, 0) - (text_widget, info_buffer) = self.create_text(False) + text_widget, info_buffer = self.create_text_view() notebook.append_page(text_widget, Gtk.Label.new_with_mnemonic('_Info')) self.info_buffer = info_buffer self.info_buffer.create_tag('title', font='Sans 18') - (text_widget, source_buffer) = self.create_text(True) + text_widget, self.source_buffer = self.create_source_view() notebook.append_page(text_widget, Gtk.Label.new_with_mnemonic('_Source')) - self.source_buffer = source_buffer - self.source_buffer.create_tag('bold', - weight=Pango.Weight.BOLD) - self.source_buffer.create_tag('italic', - style=Pango.Style.ITALIC) - self.source_buffer.create_tag('comment', - foreground='#c0c0c0') - self.source_buffer.create_tag('decorator', - foreground='#7d7d7d', - style=Pango.Style.ITALIC) - self.source_buffer.create_tag('keyword', - foreground='#0000ff') - self.source_buffer.create_tag('number', - foreground='#800000') - self.source_buffer.create_tag('string', - foreground='#00aa00', - style=Pango.Style.ITALIC) - self.show_all() self.selection_cb(self.tree_view.get_selection(), @@ -242,7 +206,6 @@ class GtkDemoWindow(Gtk.Window): start = self.source_buffer.get_iter_at_offset(0) end = start.copy() self.source_buffer.insert(end, code) - self.fontify() def row_activated_cb(self, view, path, col, store): iter = store.get_iter(path) @@ -295,13 +258,15 @@ class GtkDemoWindow(Gtk.Window): return box - def create_text(self, is_source): + def create_scrolled_window(self): scrolled_window = Gtk.ScrolledWindow(hadjustment=None, vadjustment=None) scrolled_window.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) scrolled_window.set_shadow_type(Gtk.ShadowType.IN) + return scrolled_window + def create_text_view(self): text_view = Gtk.TextView() buffer = Gtk.TextBuffer() @@ -309,100 +274,53 @@ class GtkDemoWindow(Gtk.Window): text_view.set_editable(False) text_view.set_cursor_visible(False) + scrolled_window = self.create_scrolled_window() scrolled_window.add(text_view) - if is_source: - font_desc = Pango.FontDescription('monospace') - text_view.modify_font(font_desc) - text_view.set_wrap_mode(Gtk.WrapMode.NONE) + text_view.set_wrap_mode(Gtk.WrapMode.WORD) + text_view.set_pixels_above_lines(2) + text_view.set_pixels_below_lines(2) + + return scrolled_window, buffer + + def create_source_view(self): + font_desc = Pango.FontDescription('monospace 11') + + if GtkSource: + lang_mgr = GtkSource.LanguageManager() + lang = lang_mgr.get_language('python') + + buffer = GtkSource.Buffer() + buffer.set_language(lang) + buffer.set_highlight_syntax(True) + + view = GtkSource.View() + view.set_buffer(buffer) + view.set_show_line_numbers(True) + + scrolled_window = self.create_scrolled_window() + scrolled_window.add(view) + else: - text_view.set_wrap_mode(Gtk.WrapMode.WORD) - text_view.set_pixels_above_lines(2) - text_view.set_pixels_below_lines(2) - - return(scrolled_window, buffer) - - def fontify(self): - start_iter = self.source_buffer.get_iter_at_offset(0) - end_iter = self.source_buffer.get_iter_at_offset(0) - data = self.source_buffer.get_text(self.source_buffer.get_start_iter(), - self.source_buffer.get_end_iter(), - False) - - if sys.version_info < (3, 0): - data = data.decode('utf-8') - - builtin_constants = ['None', 'True', 'False'] - is_decorator = False - is_func = False - - def prepare_iters(): - start_iter.set_line(srow - 1) - start_iter.set_line_offset(scol) - end_iter.set_line(erow - 1) - end_iter.set_line_offset(ecol) - - for x in tokenize.generate_tokens(InputStream(data).readline): - # x has 5-tuples - tok_type, tok_str = x[0], x[1] - srow, scol = x[2] - erow, ecol = x[3] - - if tok_type == tokenize.COMMENT: - prepare_iters() - self.source_buffer.apply_tag_by_name('comment', start_iter, end_iter) - elif tok_type == tokenize.NAME: - if tok_str in keyword.kwlist or tok_str in builtin_constants: - prepare_iters() - self.source_buffer.apply_tag_by_name('keyword', start_iter, end_iter) - - if tok_str == 'def' or tok_str == 'class': - # Next token is going to be a function/method/class name - is_func = True - continue - elif tok_str == 'self': - prepare_iters() - self.source_buffer.apply_tag_by_name('italic', start_iter, end_iter) - else: - if is_func: - prepare_iters() - self.source_buffer.apply_tag_by_name('bold', start_iter, end_iter) - elif is_decorator: - prepare_iters() - self.source_buffer.apply_tag_by_name('decorator', start_iter, end_iter) - elif tok_type == tokenize.STRING: - prepare_iters() - self.source_buffer.apply_tag_by_name('string', start_iter, end_iter) - elif tok_type == tokenize.NUMBER: - prepare_iters() - self.source_buffer.apply_tag_by_name('number', start_iter, end_iter) - elif tok_type == tokenize.OP: - if tok_str == '@': - prepare_iters() - self.source_buffer.apply_tag_by_name('decorator', start_iter, end_iter) - - # next token is going to be the decorator name - is_decorator = True - continue - - if is_func: - is_func = False - - if is_decorator: - is_decorator = False + scrolled_window, buffer = self.create_text_view() + view = scrolled_window.get_child() + + view.modify_font(font_desc) + view.set_wrap_mode(Gtk.WrapMode.NONE) + return scrolled_window, buffer def main(): mainloop = GLib.MainLoop() demowindow = GtkDemoWindow() - demowindow.connect('delete-event', quit, mainloop) + demowindow.connect('destroy', quit, mainloop) demowindow.show() mainloop.run() -def quit(widget, event, mainloop): +def quit(widget, mainloop): mainloop.quit() |