""" Multi-edit - Gedit plugin Copyright (C) 2009 Jonathan Walsh 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 3 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, see . """ import csv import gtk import gedit import gconf import me_window import me_config """ Version: 1.0 Changes for 0.9.1 -> 1.0: Added: Support for unicode (removed ascii check) Added: Support for non-US keyboards Added: Configurable shortcuts Added: Auto-indent support Added: Level marks option Changed: Auto-increment function redone Changed: Improved tab(character) support Fixed: Document not scrolling with cursor (during text modifications) Fixed: Ctrl+A not exiting multi-edit mode Fixed: Shortcut detection (caps lock problem) Fixed: Multi-edit mode vertical nav (tab support) """ class MultiEditPlugin(gedit.Plugin): """ Plugin instance (Multi-edit) """ # ============================================================ Gedit expected functions def __init__(self): gedit.Plugin.__init__(self) self._windows = {} self._gconf_key_base = '/apps/gedit-2/plugins/multi_edit/' # Note: safe keys are keys that cannot modify the textbuffer (e.g. caps lock) self._keyvals = { 'arrows': {'up':65362, 'down':65364, 'left':65361, 'right':65363}, 'tab': (65289, 65056), 'backspace': 65288, 'delete': 65535, 'enter': 65293, 'v': 118, 'a': 97, '0': 48, 'safe_keys': (65505, 65506, 65507, 65508, 65513, 65514, 65509, 65407), } # Shortcut defaults self._sc_add_mark_def = 'e' self._sc_level_marks_def = 'E' self._sc_auto_incr_def = '\n'.join(( '- abc:a', '_ abc:A', '= abc:z', '+ abc:Z', '0 num:0,1', ') num:1,1', )) # Shortcuts self._sc_add_mark_str = self._get_config_str('add_mark', self._sc_add_mark_def) self._sc_level_marks_str = self._get_config_str('level_marks', self._sc_level_marks_def) self._sc_auto_incr_str = self._get_config_str('auto_incr', self._sc_auto_incr_def) # Shortcut strings to keyvals self._set_shortcut_keyvals() def activate(self, window): """ Create a Multi-edit instance for a window. """ self._windows[window] = me_window.WindowInstance(self, window) def deactivate(self, window): """ Deactivate Multi-edit for a window. """ self._windows[window].deactivate() del self._windows[window] def update_ui(self, window): pass def is_configurable(self): return True def create_configure_dialog(self): """ Show the plugin settings window. """ self._config_instance = me_config.ConfigDialog(self) return self._config_instance._dialog # ============================================================ Shortcuts def _get_keyval(self, string): """ Get a GTK keyval from a single character or a keyval name. """ if len(string) == 1: return gtk.gdk.unicode_to_keyval(ord(unicode(string))) if len(string) > 1: return gtk.gdk.keyval_from_name(string) else: return 0 def _set_shortcut_keyvals(self): """ Convert the shortcut strings to GTK readable keyvals. """ self._sc_add_mark = self._get_keyval(self._sc_add_mark_str) self._sc_level_marks = self._get_keyval(self._sc_level_marks_str) self._sc_auto_incr = self._parse_sc_auto_incr(self._sc_auto_incr_str) def _parse_sc_auto_incr(self, string): """ Parse the multi-line string and return a dictionary of auto-incr shortcuts. """ lines = string.splitlines() result = {} for line in lines: (command, sep, values) = line.partition(':') if sep != ':': continue (key, sep, command) = command.partition(' ') if sep != ' ': continue keyval = self._get_keyval(key) if keyval == 0: continue values = csv.reader([values]).next() result[keyval] = [command] result[keyval].extend(values) return result # ============================================================ gconf def _get_config_str(self, key, default=''): """ Retrieve a gconf key, or its default if not set. """ key = self._gconf_key_base + key value = gconf.client_get_default().get(key) if value is not None and value.type == gconf.VALUE_STRING: return value.get_string() else: return default def _set_config_str(self, key, string): """ Save a value to a gconf key. """ key = self._gconf_key_base + key value = gconf.Value(gconf.VALUE_STRING) value.set_string(string) gconf.client_get_default().set(key, value) def _save_settings(self): """ Wrapper for saving the current settings to gconf. """ self._set_config_str('add_mark', self._sc_add_mark_str) self._set_config_str('level_marks', self._sc_level_marks_str) self._set_config_str('auto_incr', self._sc_auto_incr_str)