home *** CD-ROM | disk | FTP | other *** search
/ PC Welt 2006 November (DVD) / PCWELT_11_2006.ISO / casper / filesystem.squashfs / usr / lib / gedit-2 / plugins / snippets / SnippetComplete.py < prev    next >
Encoding:
Python Source  |  2006-08-27  |  7.6 KB  |  307 lines

  1. #    Gedit snippets plugin
  2. #    Copyright (C) 2005-2006  Jesse van den Kieboom <jesse@icecrew.nl>
  3. #
  4. #    This program is free software; you can redistribute it and/or modify
  5. #    it under the terms of the GNU General Public License as published by
  6. #    the Free Software Foundation; either version 2 of the License, or
  7. #    (at your option) any later version.
  8. #
  9. #    This program is distributed in the hope that it will be useful,
  10. #    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. #    GNU General Public License for more details.
  13. #
  14. #    You should have received a copy of the GNU General Public License
  15. #    along with this program; if not, write to the Free Software
  16. #    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  17.  
  18. import gtk
  19. import gobject
  20. from Snippet import Snippet
  21. from gtk import gdk
  22. import gedit
  23. from functions import *
  24.  
  25. class CompleteModel(gtk.GenericTreeModel):
  26.     column_types = (str, object)
  27.     column_names = ['Description', 'Node']
  28.  
  29.     def __init__(self, nodes, prefix = None, description_only = False):
  30.         gtk.GenericTreeModel.__init__(self)
  31.         
  32.         self.nodes = self.create_list(nodes, prefix)
  33.         
  34.         # Sort the nodes
  35.         if not prefix:
  36.             if description_only:
  37.                 self.display_snippet = self.display_snippet_description
  38.             else:
  39.                 self.display_snippet = self.display_snippet_default
  40.  
  41.             self.do_filter = self.filter_snippet_default
  42.             
  43.             self.nodes.sort(lambda a, b: cmp(a['description'].lower(), \
  44.                     b['description'].lower()))
  45.         else:
  46.             self.display_snippet = self.display_snippet_prefix
  47.             self.do_filter = self.filter_snippet_prefix
  48.             self.nodes.sort(self.sort_prefix)
  49.             
  50.         self.visible_nodes = list(self.nodes)        
  51.  
  52.     def display_snippet_description(self, snippet):
  53.         return markup_escape(snippet['description'])
  54.     
  55.     def display_snippet_default(self, snippet):
  56.         return snippet.display()
  57.     
  58.     def display_snippet_prefix(self, snippet):
  59.         return '<b>' + markup_escape(snippet['tag']) + '</b>: ' + \
  60.                 markup_escape(snippet['description'])
  61.  
  62.     def sort_prefix(self, a, b):
  63.         return cmp(a['tag'] + ': ' + a['description'], b['tag'] + ': ' + \
  64.                 b['description'])
  65.  
  66.     def create_list(self, nodes, prefix):
  67.         if prefix:
  68.             prelen = len(prefix)
  69.             
  70.         result = []
  71.  
  72.         for node in nodes:
  73.             s = Snippet(node)
  74.             
  75.             if not prefix or \
  76.                     prefix.lower() == s['tag'][0:prelen].lower():
  77.                 result.append(s)
  78.                 
  79.         return result
  80.  
  81.     def filter_snippet_process(self, new):        
  82.         # Update all nodes
  83.         old = self.visible_nodes
  84.         oldlen = len(old)
  85.         
  86.         self.visible_nodes = new
  87.         newlen = len(new)
  88.  
  89.         for index in range(0, min(newlen, oldlen)):
  90.             path = (index,)
  91.             self.row_changed(path, self.get_iter(path))
  92.         
  93.         if oldlen > newlen:
  94.             for index in range(oldlen - 1, newlen - 1, -1):
  95.                 self.row_deleted((index,))
  96.  
  97.         elif newlen > oldlen:
  98.             for index in range(oldlen, newlen):
  99.                 path = (index,)
  100.                 self.row_inserted(path, self.get_iter(path))
  101.  
  102.     def filter_snippet_prefix(self, s):
  103.         new = []
  104.         s = s.lower()
  105.         
  106.         for node in self.nodes:
  107.             if s in node['tag'].lower():
  108.                 new.append(node)
  109.         
  110.         self.filter_snippet_process(new)
  111.     
  112.     def filter_snippet_default(self, s):
  113.         new = []
  114.         s = s.lower()
  115.         
  116.         for node in self.nodes:
  117.             if s in node['description'].lower():
  118.                 new.append(node)
  119.         
  120.         self.filter_snippet_process(new)
  121.  
  122.     def get_snippet(self, path):
  123.         try:
  124.             return self.visible_nodes[path[0]]
  125.         except IndexError:
  126.             return None
  127.  
  128.     def on_get_flags(self):
  129.         return gtk.TREE_MODEL_LIST_ONLY
  130.     
  131.     def on_get_n_columns(self):
  132.         len(self.column_types)
  133.  
  134.     def on_get_column_type(self, index):
  135.         return self.column_types[index]
  136.  
  137.     def on_get_iter(self, path):
  138.         try:
  139.             return self.visible_nodes[path[0]]
  140.         except IndexError:
  141.             return None
  142.  
  143.     def on_get_path(self, rowref):
  144.         return self.visible_nodes.index(rowref)
  145.         
  146.     def on_get_value(self, rowref, column):
  147.         if column == 0:
  148.             return self.display_snippet(rowref)
  149.         elif column == 1:
  150.             return rowref
  151.         
  152.     def on_iter_next(self, rowref):
  153.         try:
  154.             next = self.visible_nodes.index(rowref) + 1
  155.         except ValueError:
  156.             next = 0
  157.         
  158.         try:
  159.             return self.visible_nodes[next]
  160.         except IndexError:
  161.             return None
  162.         
  163.     def on_iter_children(self, parent):
  164.         if parent:
  165.             return None
  166.         else:
  167.             return self.visible_nodes[0]
  168.  
  169.     def on_iter_has_child(self, rowref):
  170.         return False
  171.  
  172.     def on_iter_n_children(self, rowref):
  173.         if rowref:
  174.             return 0
  175.         return len(self.visible_nodes)
  176.  
  177.     def on_iter_nth_child(self, parent, n):
  178.         if parent:
  179.             return None
  180.  
  181.         try:
  182.             return self.visible_nodes[n]
  183.         except IndexError:
  184.             return None
  185.  
  186.     def on_iter_parent(self, child):
  187.         return None
  188.  
  189. class SnippetComplete(gtk.Window):
  190.     def __init__(self, nodes, prefix = None, description_only = False):
  191.         gtk.Window.__init__(self, gtk.WINDOW_TOPLEVEL)
  192.         self.set_keep_above(True)
  193.         self.set_decorated(False)
  194.         self.set_skip_taskbar_hint(True)
  195.         self.set_skip_pager_hint(True)
  196.         
  197.         window = gedit.app_get_default().get_active_window()
  198.         window.get_group().add_window(self)
  199.         
  200.         self.set_transient_for(window)
  201.         self.set_size_request(200, 300)
  202.         self.entry_changed_id = 0
  203.         self.model = CompleteModel(nodes, prefix, description_only)
  204.         self.build()
  205.  
  206.         if prefix:
  207.             self.entry.set_text(prefix)
  208.  
  209.         self.connect('delete-event', lambda x, y: x.destroy())
  210.         self.connect('focus-out-event', self.on_focus_out)
  211.  
  212.     def run(self):
  213.         if not self.model.nodes:
  214.             self.destroy()
  215.             return False
  216.         
  217.         self.show_all()
  218.         self.entry.grab_focus()
  219.         self.entry.set_position(-1)
  220.         return True
  221.  
  222.     def build_tree(self):
  223.         self.tree_view = gtk.TreeView(self.model)
  224.         self.tree_view.set_headers_visible(False)
  225.  
  226.         column = gtk.TreeViewColumn(None)
  227.         renderer = gtk.CellRendererText()
  228.         column.pack_start(renderer, False)
  229.         column.set_attributes(renderer, markup=0)
  230.         
  231.         self.tree_view.append_column(column)
  232.     
  233.         self.tree_view.connect('row-activated', self.on_tree_view_row_activated)
  234.  
  235.     def build(self):
  236.         vbox = gtk.VBox(False, 3)
  237.         frame = gtk.Frame()
  238.  
  239.         frame.set_shadow_type(gtk.SHADOW_ETCHED_IN)
  240.  
  241.         self.entry = gtk.Entry()
  242.         vbox.pack_start(self.entry, False, False, 0)
  243.         
  244.         self.build_tree()
  245.         sw = gtk.ScrolledWindow()
  246.         sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
  247.         sw.add(self.tree_view)
  248.         sw.set_shadow_type(gtk.SHADOW_OUT)
  249.         
  250.         vbox.pack_start(sw, True, True, 0)
  251.         
  252.         frame.add(vbox)
  253.         self.add(frame)
  254.         
  255.         self.entry.connect('changed', self.on_entry_changed)
  256.         self.entry.connect('activate', self.on_entry_activate)
  257.         self.entry.connect('key-press-event', self.on_entry_key_press)
  258.     
  259.     def snippet_activated(self, snippet):
  260.         self.emit('snippet-activated', snippet)
  261.         self.destroy()
  262.  
  263.     def idle_filter(self, text):
  264.         self.entry_changed_id = 0
  265.         self.model.do_filter(text)
  266.         
  267.         piter = self.model.get_iter_first()
  268.         
  269.         if piter:
  270.             self.tree_view.get_selection().select_iter(piter)
  271.  
  272.         return False
  273.     
  274.     def on_focus_out(self, wnd, event):
  275.         self.destroy()
  276.         return False
  277.         
  278.     def on_entry_changed(self, entry):
  279.         if self.entry_changed_id:
  280.             gobject.source_remove(self.entry_changed_id)
  281.         
  282.         self.entry_changed_id = gobject.idle_add(self.idle_filter, 
  283.                 entry.get_text())
  284.     
  285.     def on_entry_key_press(self, entry, event):
  286.         if event.keyval == gdk.keyval_from_name('Escape'):
  287.             self.destroy()
  288.             return True
  289.         
  290.         return False
  291.     
  292.     def on_tree_view_row_activated(self, view, path, column):
  293.         snippet = self.model.get_snippet(path)
  294.  
  295.         self.snippet_activated(snippet)
  296.  
  297.     def on_entry_activate(self, entry):
  298.         (model, piter) = self.tree_view.get_selection().get_selected()
  299.         
  300.         if piter:
  301.             snippet = self.model.get_snippet(self.model.get_path(piter))
  302.             self.snippet_activated(snippet)
  303.  
  304. gobject.signal_new('snippet-activated', SnippetComplete, \
  305.         gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, \
  306.         (gobject.TYPE_PYOBJECT,))
  307.