Viewing file: test-widget.py (15.89 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
#!/usr/bin/env python # -*- coding: UTF-8 -*-
# This script shows the use of pygtksourceview module, the python wrapper # of gtksourceview C library. # It has been directly translated from test-widget.c # # Copyright (C) 2004 - IƱigo Serna <inigoserna@telefonica.net> # # 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
import os, os.path import sys import pygtk pygtk.require ('2.0')
import gtk if gtk.pygtk_version < (2,3,93): print "PyGtk 2.3.93 or later required for this example" raise SystemExit
import gtksourceview import gnome.vfs import pango import gnomeprint.ui
###################################################################### ##### global vars windows = [] # this list contains all view windows MARKER_TYPE_1 = 'one' MARKER_TYPE_2 = 'two' DATADIR = '/usr/share'
###################################################################### ##### error dialog def error_dialog(parent, msg): dialog = gtk.MessageDialog(parent, gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, msg) dialog.run() dialog.destroy()
###################################################################### ##### remove all markers def remove_all_markers(buffer): begin, end = buffer.get_bounds() markers = buffer.get_markers_in_region(begin, end) map(buffer.delete_marker, markers)
###################################################################### ##### load file def load_file(buffer, uri): buffer.begin_not_undoable_action() # TODO: use g_io_channel when pygtk supports it try: txt = open(uri.path).read() except: return False buffer.set_text(txt) buffer.set_data('filename', uri.path) buffer.end_not_undoable_action()
buffer.set_modified(False) buffer.place_cursor(buffer.get_start_iter()) return True
###################################################################### ##### buffer creation def open_file(buffer, filename): # get the new language for the file mimetype manager = buffer.get_data('languages-manager')
if os.path.isabs(filename): path = filename else: path = os.path.abspath(filename) uri = gnome.vfs.URI(path)
mime_type = gnome.vfs.get_mime_type(path) # needs ASCII filename, not URI if mime_type: language = manager.get_language_from_mime_type(mime_type) if language: buffer.set_highlight(True) buffer.set_language(language) else: print 'No language found for mime type "%s"' % mime_type buffer.set_highlight(False) else: print 'Couldn\'t get mime type for file "%s"' % filename buffer.set_highlight(False)
remove_all_markers(buffer) load_file(buffer, uri) # TODO: check return return True
###################################################################### ##### Printing callbacks def page_cb(job, *args): percent = 100 * job.get_page() / job.get_page_count() print 'Printing %.2f%% \r' % percent,
def finished_cb(job, *args): print gjob = job.get_print_job() preview = gnomeprint.ui.JobPreview(gjob, 'PyGtkSourceView Demo Print Preview') preview.show()
###################################################################### ##### Action callbacks def numbers_toggled_cb(action, sourceview): sourceview.set_show_line_numbers(action.get_active())
def markers_toggled_cb(action, sourceview): sourceview.set_show_line_markers(action.get_active())
def margin_toggled_cb(action, sourceview): sourceview.set_show_margin(action.get_active())
def auto_indent_toggled_cb(action, sourceview): sourceview.set_auto_indent(action.get_active())
def insert_spaces_toggled_cb(action, sourceview): sourceview.set_insert_spaces_instead_of_tabs(action.get_active())
def tabs_toggled_cb(action, action2, sourceview): sourceview.set_tabs_width(action.get_current_value())
def new_view_cb(action, sourceview): window = create_view_window(sourceview.get_buffer(), sourceview) window.set_default_size(400, 400) window.show()
def print_preview_cb(action, sourceview): buffer = sourceview.get_buffer() job = gtksourceview.SourcePrintJob() job.setup_from_view(sourceview) job.set_wrap_mode(gtk.WRAP_CHAR) job.set_highlight(True) job.set_print_numbers(5) job.set_header_format('Printed on %A', None, '%F', False) filename = buffer.get_data('filename') job.set_footer_format('%T', filename, 'Page %N/%Q', True) job.set_print_header(True) job.set_print_footer(True) start, end = buffer.get_bounds() if job.print_range_async(start, end): job.connect('begin_page', page_cb) job.connect('finished', finished_cb) else: print 'Async print failed'
###################################################################### ##### Buffer action callbacks def open_file_cb(action, buffer): chooser = gtk.FileChooserDialog('Open file...', None, gtk.FILE_CHOOSER_ACTION_OPEN, (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OPEN, gtk.RESPONSE_OK)) response = chooser.run() if response == gtk.RESPONSE_OK: filename = chooser.get_filename() if filename: open_file(buffer, filename) chooser.destroy()
def update_cursor_position(buffer, view): tabwidth = view.get_tabs_width() pos_label = view.get_data('pos_label') iter = buffer.get_iter_at_mark(buffer.get_insert()) nchars = iter.get_offset() row = iter.get_line() + 1 start = iter start.set_line_offset(0) col = 0 while not start.equal(iter): if start.get_char == '\t': col += (tabwidth - (col % tabwidth)) else: col += 1 start = start.forward_char() pos_label.set_text('char: %d, line: %d, column: %d' % (nchars, row, col))
def move_cursor_cb (buffer, cursoriter, mark, view): update_cursor_position(buffer, view)
def window_deleted_cb(widget, ev, view): if windows[0] == widget: gtk.main_quit() else: # remove window from list windows.remove(widget) # we return False since we want the window destroyed return False return True
def button_press_cb(view, ev): buffer = view.get_buffer() if not view.get_show_line_markers(): return False # check that the click was on the left gutter if ev.window == view.get_window(gtk.TEXT_WINDOW_LEFT): if ev.button == 1: marker_type = MARKER_TYPE_1 else: marker_type = MARKER_TYPE_2 x_buf, y_buf = view.window_to_buffer_coords(gtk.TEXT_WINDOW_LEFT, int(ev.x), int(ev.y)) # get line bounds line_start = view.get_line_at_y(y_buf)[0] line_end = line_start.copy() line_end.forward_to_line_end()
# get the markers already in the line marker_list = buffer.get_markers_in_region(line_start, line_end) # search for the marker corresponding to the button pressed for m in marker_list: if m.get_marker_type() == marker_type: marker = m break else: marker = None
if marker: # a marker was found, so delete it buffer.delete_marker(marker) else: # no marker found, create one marker = buffer.create_marker(None, marker_type, line_start) return False
###################################################################### ##### Actions & UI definition buffer_actions = [ ('Open', gtk.STOCK_OPEN, '_Open', '<control>O', 'Open a file', open_file_cb), ('Quit', gtk.STOCK_QUIT, '_Quit', '<control>Q', 'Exit the application', gtk.main_quit) ]
view_actions = [ ('FileMenu', None, '_File'), ('ViewMenu', None, '_View'), ('PrintPreview', gtk.STOCK_PRINT, '_Print Preview', '<control>P', 'Preview printing of the file', print_preview_cb), ('NewView', gtk.STOCK_NEW, '_New View', None, 'Create a new view of the file', new_view_cb), ('TabsWidth', None, '_Tabs Width') ]
toggle_actions = [ ('ShowNumbers', None, 'Show _Line Numbers', None, 'Toggle visibility of line numbers in the left margin', numbers_toggled_cb, False), ('ShowMarkers', None, 'Show _Markers', None, 'Toggle visibility of markers in the left margin', markers_toggled_cb, False), ('ShowMargin', None, 'Show M_argin', None, 'Toggle visibility of right margin indicator', margin_toggled_cb, False), ('AutoIndent', None, 'Enable _Auto Indent', None, 'Toggle automatic auto indentation of text', auto_indent_toggled_cb, False), ('InsertSpaces', None, 'Insert _Spaces Instead of Tabs', None, 'Whether to insert space characters when inserting tabulations', insert_spaces_toggled_cb, False) ]
radio_actions = [ ('TabsWidth4', None, '4', None, 'Set tabulation width to 4 spaces', 4), ('TabsWidth6', None, '6', None, 'Set tabulation width to 6 spaces', 6), ('TabsWidth8', None, '8', None, 'Set tabulation width to 8 spaces', 8), ('TabsWidth10', None, '10', None, 'Set tabulation width to 10 spaces', 10), ('TabsWidth12', None, '12', None, 'Set tabulation width to 12 spaces', 12) ]
view_ui_description = """ <ui> <menubar name='MainMenu'> <menu action='FileMenu'> <menuitem action='PrintPreview'/> </menu> <menu action='ViewMenu'> <menuitem action='NewView'/> <separator/> <menuitem action='ShowNumbers'/> <menuitem action='ShowMarkers'/> <menuitem action='ShowMargin'/> <separator/> <menuitem action='AutoIndent'/> <menuitem action='InsertSpaces'/> <separator/> <menu action='TabsWidth'> <menuitem action='TabsWidth4'/> <menuitem action='TabsWidth6'/> <menuitem action='TabsWidth8'/> <menuitem action='TabsWidth10'/> <menuitem action='TabsWidth12'/> </menu> </menu> </menubar> </ui> """
buffer_ui_description = """ <ui> <menubar name='MainMenu'> <menu action='FileMenu'> <menuitem action='Open'/> <separator/> <menuitem action='Quit'/> </menu> <menu action='ViewMenu'> </menu> </menubar> </ui> """
###################################################################### ##### create view window def create_view_window(buffer, sourceview = None): # window window = gtk.Window(gtk.WINDOW_TOPLEVEL) window.set_border_width(0) window.set_title('PyGtkSourceView Demo') windows.append(window) # this list contains all view windows
# view view = gtksourceview.SourceView(buffer) buffer.connect('mark_set', move_cursor_cb, view) buffer.connect('changed', update_cursor_position, view) view.connect('button-press-event', button_press_cb) window.connect('delete-event', window_deleted_cb, view)
# action group and UI manager action_group = gtk.ActionGroup('ViewActions') action_group.add_actions(view_actions, view) action_group.add_toggle_actions(toggle_actions, view) action_group.add_radio_actions(radio_actions, -1, tabs_toggled_cb, view)
ui_manager = gtk.UIManager() ui_manager.insert_action_group(action_group, 0) # save a reference to the ui manager in the window for later use window.set_data('ui_manager', ui_manager) accel_group = ui_manager.get_accel_group() window.add_accel_group(accel_group) ui_manager.add_ui_from_string(view_ui_description)
# misc widgets vbox = gtk.VBox(0, False) sw = gtk.ScrolledWindow() sw.set_shadow_type(gtk.SHADOW_IN) pos_label = gtk.Label('Position') view.set_data('pos_label', pos_label) menu = ui_manager.get_widget('/MainMenu')
# layout widgets window.add(vbox) vbox.pack_start(menu, False, False, 0) vbox.pack_start(sw, True, True, 0) sw.add(view) vbox.pack_start(pos_label, False, False, 0)
# setup view font_desc = pango.FontDescription('monospace 10') if font_desc: view.modify_font(font_desc)
# change view attributes to match those of sourceview if sourceview: action = action_group.get_action('ShowNumbers') action.set_active(sourceview.get_show_line_numbers()) action = action_group.get_action('ShowMarkers') action.set_active(sourceview.get_show_line_markers()) action = action_group.get_action('ShowMargin') action.set_active(sourceview.get_margin()) action = action_group.get_action('AutoIndent') action.set_active(sourceview.get_auto_indent()) action = action_group.get_action('InsertSpaces') action.set_active(sourceview.get_insert_spaces_instead_of_tabs()) action = action_group.get_action('TabsWidth%d' % sourceview.get_tabs_width()) if action: action.set_active(True)
# add marker pixbufs pixbuf = gtk.gdk.pixbuf_new_from_file(os.path.join(DATADIR, 'pixmaps/apple-green.png')) if pixbuf: view.set_marker_pixbuf(MARKER_TYPE_1, pixbuf) else: print 'could not load marker 1 image. Spurious messages might get triggered' pixbuf = gtk.gdk.pixbuf_new_from_file(os.path.join(DATADIR, 'pixmaps/apple-red.png')) if pixbuf: view.set_marker_pixbuf(MARKER_TYPE_2, pixbuf) else: print 'could not load marker 2 image. Spurious messages might get triggered'
vbox.show_all()
return window ###################################################################### ##### create main window def create_main_window(buffer): window = create_view_window(buffer) ui_manager = window.get_data('ui_manager') # buffer action group action_group = gtk.ActionGroup('BufferActions') action_group.add_actions(buffer_actions, buffer) ui_manager.insert_action_group(action_group, 1) # merge buffer ui ui_manager.add_ui_from_string(buffer_ui_description)
# preselect menu checkitems groups = ui_manager.get_action_groups() # retrieve the view action group at position 0 in the list action_group = groups[0] action = action_group.get_action('ShowNumbers') action.set_active(True) action = action_group.get_action('ShowMarkers') action.set_active(True) action = action_group.get_action('ShowMargin') action.set_active(True) action = action_group.get_action('AutoIndent') action.set_active(True) action = action_group.get_action('InsertSpaces') action.set_active(True) action = action_group.get_action('TabsWidth8') action.set_active(True)
return window
###################################################################### ##### main def main(args = []): # create buffer lm = gtksourceview.SourceLanguagesManager() buffer = gtksourceview.SourceBuffer() buffer.set_data('languages-manager', lm)
# parse arguments if len(args) > 2: open_file(buffer, args[1]) else: open_file(buffer, args[0]) # create first window window = create_main_window(buffer) window.set_default_size(500, 500) window.show()
# main loop gtk.main()
if __name__ == '__main__': if '--debug' in sys.argv: import pdb pdb.run('main(sys.argv)') else: main(sys.argv)
|