Viewing file: SnippetsDialog.py (17.08 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
# Gedit snippets plugin # Copyright (C) 2005-2006 Jesse van den Kieboom <jesse@icecrew.nl> # # 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
import gtk from gtk import glade from gtk import gdk import pango import os import gedit import gtksourceview from Snippet import Snippet from functions import * from SnippetsLibrary import * import gobject
class SnippetsDialog: NAME_COLUMN = 0 SORT_COLUMN = 1 OBJ_COLUMN = 2
model = None def __init__(self): self.snippet = None self.dlg = None self.key_press_id = 0 self.tooltips = gtk.Tooltips() self.run()
def get_language_snippets(self, path, name = None): library = SnippetsLibrary() name = self.get_language(path) nodes = library.get_snippets(name)
return nodes
def add_new_snippet_node(self, parent): return self.model.append(parent, ('<i>' + _('Add a new snippet...') + \ '</i>', '', None))
def fill_language(self, piter): # Remove all children child = self.model.iter_children(piter) while child and self.model.remove(child): True path = self.model.get_path(piter) nodes = self.get_language_snippets(path) language = self.get_language(path) SnippetsLibrary().ref(language) if nodes: for node in nodes: self.add_snippet(piter, node) else: # Add node that tells there are no snippets currently self.add_new_snippet_node(piter)
self.tree_view.expand_row(path, False)
def build_model(self): window = gedit.app_get_default().get_active_window() if window: view = window.get_active_view()
if not view: current_lang = None else: current_lang = view.get_buffer().get_language() source_view = self['source_view_snippet'] source_view.set_auto_indent(view.get_auto_indent()) source_view.set_insert_spaces_instead_of_tabs( \ view.get_insert_spaces_instead_of_tabs()) source_view.set_smart_home_end(view.get_smart_home_end()) source_view.set_tabs_width(view.get_tabs_width())
else: current_lang = None
tree_view = self['tree_view_snippets'] expand = None if not self.model: self.model = gtk.TreeStore(str, str, object) self.model.set_sort_column_id(self.SORT_COLUMN, gtk.SORT_ASCENDING) manager = gtksourceview.SourceLanguagesManager() langs = manager.get_available_languages() piter = self.model.append(None, (_('Global'), '', None)) # Add dummy node self.model.append(piter, ('', '', None)) nm = None if current_lang: nm = current_lang.get_name() for lang in langs: name = lang.get_name() parent = self.model.append(None, (name, name, lang))
# Add dummy node self.model.append(parent, ('', '', None))
if (nm == name): expand = parent else: if current_lang: piter = self.model.get_iter_first() nm = current_lang.get_name() while piter: lang = self.model.get_value(piter, \ self.SORT_COLUMN) if lang == nm: expand = piter break; piter = self.model.iter_next(piter)
tree_view.set_model(self.model) if not expand: expand = self.model.get_iter_root() tree_view.expand_row(self.model.get_path(expand), False) self.select_iter(expand)
def get_cell_data_cb(self, column, cell, model, iter): s = model.get_value(iter, self.OBJ_COLUMN) snippet = isinstance(s, SnippetData) cell.set_property('editable', snippet) if snippet and not s.valid: cell.set_property('foreground-gdk', gdk.color_parse('red')) else: cell.set_property('foreground-set', False) cell.set_property('markup', model.get_value(iter, self.NAME_COLUMN))
def build_tree_view(self): self.tree_view = self['tree_view_snippets'] self.column = gtk.TreeViewColumn(None) self.renderer = gtk.CellRendererText() self.column.pack_start(self.renderer, False) self.column.set_cell_data_func(self.renderer, self.get_cell_data_cb) self.tree_view.append_column(self.column) self.renderer.connect('edited', self.on_cell_edited) self.renderer.connect('editing-started', self.on_cell_editing_started)
self.tree_view.get_selection().connect('changed', \ self.on_tree_view_selection_changed)
def custom_handler(self, xml, function_name, widget_name, str1, str2, \ int1 , int2): if function_name == 'create_source_view': buf = gtksourceview.SourceBuffer() buf.set_highlight(True) source_view = gtksourceview.SourceView(buf) source_view.set_auto_indent(True) source_view.set_insert_spaces_instead_of_tabs(False) source_view.set_smart_home_end(True) source_view.set_tabs_width(4) return source_view else: return None def build(self): glade.set_custom_handler(self.custom_handler) self.xml = glade.XML(os.path.dirname(__file__) + '/snippets.glade') handlers_dic = { 'on_dialog_snippets_response': \ self.on_dialog_snippets_response, \ 'on_button_new_snippet_clicked': \ self.on_button_new_snippet_clicked, \ 'on_button_remove_snippet_clicked': \ self.on_button_remove_snippet_clicked, \ 'on_entry_tab_trigger_focus_out': \ self.on_entry_tab_trigger_focus_out, \ 'on_entry_tab_trigger_changed': \ self.on_entry_tab_trigger_changed, \ 'on_entry_accelerator_focus_out': \ self.on_entry_accelerator_focus_out, \ 'on_entry_accelerator_focus_in': \ self.on_entry_accelerator_focus_in, \ 'on_entry_accelerator_key_press': \ self.on_entry_accelerator_key_press, \ 'on_source_view_snippet_focus_out': \ self.on_source_view_snippet_focus_out, \ 'on_tree_view_snippets_row_expanded': \ self.on_tree_view_snippets_row_expanded, \ 'on_tree_view_snippets_key_press': \ self.on_tree_view_snippets_key_press \ }
self.xml.signal_autoconnect(handlers_dic) self.build_tree_view() self.build_model()
button = self['button_remove_snippet'] button.set_use_stock(True) button.set_label(gtk.STOCK_REMOVE)
source_view = self['source_view_snippet'] source_view.modify_font(pango.FontDescription('Monospace 8'))
self.dlg = self['dialog_snippets'] def __getitem__(self, key): return self.xml.get_widget(key)
def is_filled(self, piter): if not self.model.iter_has_child(piter): return True child = self.model.iter_children(piter) nm = self.model.get_value(child, self.NAME_COLUMN) obj = self.model.get_value(child, self.OBJ_COLUMN) return (obj or nm)
def fill_if_needed(self, piter): if not self.is_filled(piter): self.fill_language(piter)
def find_iter(self, parent, snippet): self.fill_if_needed(parent) piter = self.model.iter_children(parent) while (piter): node = self.model.get_value(piter, self.OBJ_COLUMN)
if node == snippet.data: return piter piter = self.model.iter_next(piter) return None
def update_remove_button(self): button = self['button_remove_snippet'] if not self.snippet: button.set_sensitive(False) button.set_label(gtk.STOCK_REMOVE) else: if self.snippet.data.can_modify(): button.set_sensitive(True) if self.snippet.data.is_override(): button.set_label(gtk.STOCK_REVERT_TO_SAVED) else: button.set_label(gtk.STOCK_REMOVE) else: button.set_sensitive(False) button.set_label(gtk.STOCK_REMOVE)
def snippet_changed(self, piter = None): if piter: node = self.model.get_value(piter, self.OBJ_COLUMN) s = Snippet(node) else: s = self.snippet piter = self.find_iter(self.model.get_iter(self.language_path), s)
if piter: nm = s.display() self.model.set(piter, self.NAME_COLUMN, nm, self.SORT_COLUMN, nm) self.update_remove_button() self.entry_tab_trigger_update_valid()
return piter
def add_snippet(self, parent, snippet): piter = self.model.append(parent, ('', '', snippet)) return self.snippet_changed(piter)
def run(self): if not self.dlg: self.build() self.dlg.show_all() else: self.build_model() self.dlg.present() def selected_snippet(self): (model, piter) = self.tree_view.get_selection().get_selected() if piter: parent = model.iter_parent(piter) if parent: return parent, piter, \ model.get_value(piter, self.OBJ_COLUMN) else: return parent, piter, None else: return None, None, None
def selection_changed(self): if not self.snippet: sens = False
self['entry_tab_trigger'].set_text('') self['entry_accelerator'].set_text('') self['source_view_snippet'].get_buffer().set_text('')
self.tooltips.disable() else: sens = True
self['entry_tab_trigger'].set_text(self.snippet['tag']) self['entry_accelerator'].set_text( \ self.snippet.accelerator_display()) buf = self['source_view_snippet'].get_buffer() lang = self.model.get_value(self.model.get_iter( \ self.language_path), self.OBJ_COLUMN) buf.set_language(lang) buf.set_text(self.snippet['text']) self.tooltips.enable()
for name in ['source_view_snippet', 'label_tab_trigger', \ 'entry_tab_trigger', 'label_accelerator', 'entry_accelerator']: self[name].set_sensitive(sens) self.update_remove_button() def select_iter(self, piter): self.tree_view.get_selection().select_iter(piter) self.tree_view.scroll_to_cell(self.model.get_path(piter), None, \ True, 0.5, 0.5)
def get_language(self, path): if path[0] == 0: return None else: return self.model.get_value(self.model.get_iter( \ (path[0],)), self.OBJ_COLUMN).get_id()
def new_snippet(self, properties=None): if not self.language_path: return None
parent = self.model.get_iter(self.language_path) snippet = SnippetsLibrary().new_snippet(self.get_language( \ self.language_path), properties) return Snippet(snippet)
def get_dummy(self, parent): if not self.model.iter_n_children(parent) == 1: return None dummy = self.model.iter_children(parent) if not self.model.get_value(dummy, self.OBJ_COLUMN): return dummy return None def unref_languages(self): piter = self.model.get_iter_first() library = SnippetsLibrary() while piter: if self.is_filled(piter): language = self.get_language(self.model.get_path(piter)) library.save(language)
library.unref(language) piter = self.model.iter_next(piter)
# Callbacks def on_dialog_snippets_response(self, dlg, resp): if resp == gtk.RESPONSE_HELP: gedit.help_display(self.dlg, 'gedit.xml', 'gedit-snippets-plugin') return
self.unref_languages() self.snippet = None self.model = None self.dlg.destroy() self.dlg = None def on_cell_editing_started(self, renderer, editable, path): piter = self.model.get_iter(path) if not self.model.iter_parent(piter): renderer.stop_editing(True) editable.remove_widget() elif isinstance(editable, gtk.Entry): if self.snippet: editable.set_text(self.snippet['description']) else: # This is the `Add a new snippet...` item editable.set_text('') editable.grab_focus() def on_cell_edited(self, cell, path, new_text): if new_text != '': piter = self.model.get_iter(path) node = self.model.get_value(piter, self.OBJ_COLUMN) if node: if node == self.snippet.data: s = self.snippet else: s = Snippet(node) s['description'] = new_text self.snippet_changed(piter) self.select_iter(piter) else: # This is the `Add a new snippet...` item # We create a new snippet snippet = self.new_snippet({'description': new_text}) if snippet: self.model.set(piter, self.OBJ_COLUMN, snippet.data) self.snippet_changed(piter) self.snippet = snippet self.selection_changed() def on_entry_accelerator_focus_out(self, entry, event): if not self.snippet: return
entry.set_text(self.snippet.accelerator_display())
def entry_tab_trigger_update_valid(self): entry = self['entry_tab_trigger'] text = entry.get_text() if text and not SnippetsLibrary().valid_tab_trigger(text): entry.modify_base(gtk.STATE_NORMAL, gtk.gdk.Color(0xffff, 0x6666, \ 0x6666)) entry.modify_text(gtk.STATE_NORMAL, gtk.gdk.Color(0xffff, 0xffff, \ 0xffff))
self.tooltips.set_tip(entry, _('This is not a valid tab trigger. Triggers can either contain letters or a single, non alphanumeric, character like {, [, etcetera.')) else: entry.modify_base(gtk.STATE_NORMAL, None) entry.modify_text(gtk.STATE_NORMAL, None)
self.tooltips.set_tip(entry, None) return False
def on_entry_tab_trigger_focus_out(self, entry, event): if not self.snippet: return
text = entry.get_text()
# save tag self.snippet['tag'] = text self.snippet_changed() def on_entry_tab_trigger_changed(self, entry): self.entry_tab_trigger_update_valid() def on_source_view_snippet_focus_out(self, source_view, event): if not self.snippet: return
buf = source_view.get_buffer() text = buf.get_text(buf.get_start_iter(), \ buf.get_end_iter())
self.snippet['text'] = text self.snippet_changed() def on_button_new_snippet_clicked(self, button): snippet = self.new_snippet() if not snippet: return
parent = self.model.get_iter(self.language_path) path = self.model.get_path(parent) dummy = self.get_dummy(parent) if dummy: # Remove the dummy self.model.remove(dummy) # Add the snippet piter = self.add_snippet(parent, snippet.data) self.select_iter(piter)
if not self.tree_view.row_expanded(path): self.tree_view.expand_row(path, False) self.select_iter(piter)
self.tree_view.grab_focus()
path = self.model.get_path(piter) self.tree_view.set_cursor(path, self.column, True) def on_button_remove_snippet_clicked(self, button): parent, piter, node = self.selected_snippet()
if not self.snippet or not node.can_modify(): return if node.is_override(): SnippetsLibrary().revert_snippet(node) self.selection_changed() else: SnippetsLibrary().remove_snippet(node) self.snippet = None
path = self.model.get_path(piter) if self.model.remove(piter): self.select_iter(piter) elif path[-1] != 0: self.select_iter(self.model.get_iter((path[0], path[1] - 1))) else: dummy = self.add_new_snippet_node(parent) self.tree_view.expand_row(self.model.get_path(parent), False) self.select_iter(dummy) self.tree_view.grab_focus() def set_accelerator(self, keyval, mod): accelerator = gtk.accelerator_name(keyval, mod) self.snippet['accelerator'] = accelerator
return True def on_entry_accelerator_key_press(self, entry, event): source_view = self['source_view_snippet']
if event.keyval == gdk.keyval_from_name('Escape'): # Reset entry.set_text(self.snippet.accelerator_display()) self.tree_view.grab_focus() return True elif event.keyval == gdk.keyval_from_name('Delete') or \ event.keyval == gdk.keyval_from_name('BackSpace'): # Remove the accelerator entry.set_text('') self.snippet['accelerator'] = '' self.tree_view.grab_focus() self.snippet_changed() return True elif SnippetsLibrary().valid_accelerator(event.keyval, event.state): # New accelerator self.set_accelerator(event.keyval, \ event.state & gtk.accelerator_get_default_mod_mask()) entry.set_text(self.snippet.accelerator_display()) self.snippet_changed() self.tree_view.grab_focus()
else: return True def on_entry_accelerator_focus_in(self, entry, event): if self.snippet['accelerator']: entry.set_text(_('Type a new accelerator, or press Backspace to clear')) else: entry.set_text(_('Type a new accelerator')) def on_tree_view_selection_changed(self, selection): parent, piter, node = self.selected_snippet() if self.snippet: self.on_entry_tab_trigger_focus_out(self['entry_tab_trigger'], \ None) self.on_source_view_snippet_focus_out( \ self['source_view_snippet'], None) if parent: self.language_path = self.model.get_path(parent) elif piter: self.language_path = self.model.get_path(piter) else: self.language_path = None
if node: self.snippet = Snippet(node) else: self.snippet = None
self.selection_changed()
def iter_after(self, target, after): if not after: return True
tp = self.model.get_path(target) ap = self.model.get_path(after) if tp[0] > ap[0] or (tp[0] == ap[0] and (len(ap) == 1 or tp[1] > ap[1])): return True return False def on_tree_view_snippets_key_press(self, treeview, event): if self.snippet and event.keyval == gdk.keyval_from_name('Delete') \ and self.snippet: self.on_button_remove_snippet_clicked(None) return True
def on_tree_view_snippets_row_expanded(self, treeview, piter, path): # Check if it is already filled self.fill_if_needed(piter) self.select_iter(piter)
|