# Copyright (C) 2007 - Nando Vieira # # 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, 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 gedit import gtk import gtk.gdk import gtk.glade import gconf import os import os.path from gettext import gettext as _ ui = """ """ DEBUG_NAME = 'TB_DEBUG' DEBUG_TITLE = 'tabulation' GLADE_FILE = os.path.join(os.path.dirname(__file__), "tabulation.glade") def debug(text, level=1): if os.environ.has_key(DEBUG_NAME): try: required_level = int(os.environ[DEBUG_NAME]) if required_level >= level: print "[%s] %s" % (DEBUG_TITLE, text) except: print "[%s] debug error" % DEBUG_TITLE class TabulationPlugin(gedit.Plugin): def __init__(self): gedit.Plugin.__init__(self) self.instances = {} def activate(self, window): debug('activating plugin') self.instances[window] = TabulationWindowHelper(self, window) def deactivate(self, window): debug('deactivating plugin') self.instances[window].deactivate() del self.instances[window] def update(self, window): debug('updating') self.instances[window].update() def update_ui(self, window): debug('updating ui') self.instances[window].update_ui() class TabulationWindowHelper: handlers = {} def __init__(self, plugin, window): self.window = window self.plugin = plugin self.statusbar = window.get_statusbar() self.context_id = self.statusbar.get_context_id('TabulationStatusbar') self.dialog = None # settings [spaces?, width] self.settings = { # mime type 'text/x-python': [True, 4], 'application/x-php': [True, 4], 'application/x-ruby': [True, 2], # extension 'py': [True, 4], 'php': [True, 4], 'rb': [True, 2], 'yml': [True, 2] } # status label self.status_label = gtk.Label('') self.status_label.set_alignment(0, 0) self.system_status = self.statusbar.get_children()[-2].get_children()[0].get_children()[0] self.statusbar.get_children()[-2].hide() # frame self.frame = gtk.Frame() self.frame.add(self.status_label) # frame status bar self.frame_statusbar = gtk.Statusbar() self.frame_statusbar.add(self.frame) self.frame_statusbar.show_all() self.frame_statusbar.set_has_resize_grip(False) # adding to editor status bar self.statusbar.add(self.frame_statusbar) self.update_status() # connecting event window.connect('tab_added', self.on_tab_added) actions = [ ('Tabulation', None, _('Tabulation'), 't', _("Change tabulation settings"), self.on_open) ] action_group = gtk.ActionGroup("TabulationActions") action_group.add_actions(actions, self.window) self.manager = self.window.get_ui_manager() self.manager.insert_action_group(action_group, -1) self.manager.add_ui_from_string(ui) def deactivate(self): debug('deactivate function called') self.window.disconnect_by_func(self.on_tab_added) self.window = None self.plugin = None def on_tab_added(self, window, tab): self.apply_tabulation() self.update_status() def update(self, text=None): self.update_status() def update_ui(self): self.apply_tabulation() def update_status(self): view = self.window.get_active_view() if not view: return tab = 'T' if view.get_insert_spaces_instead_of_tabs(): tab = 'S' self.set_status('%s, %d%s' % (self.system_status.get_text(), view.get_tabs_width(), tab)) def set_status(self, text=None): label = '' if text is not None: label = text self.status_label.set_text(text) def set_data(self, name, value, target=None): if not target: target = self.window.get_active_view() target.set_data(name, value) def get_data(self, name, target=None): if not target: target = self.window.get_active_view() return target.get_data(name) def apply_tabulation(self, *args): view = self.window.get_active_view() if view is None: return buffer = view.get_buffer() uri = buffer.get_uri() debug('current document uri: %s' % uri) if uri is None: key = None else: key = os.path.splitext(uri)[1][1:].lower() if buffer.get_data('TabulationSkip'): use_spaces = view.get_insert_spaces_instead_of_tabs() tab_size = view.get_tabs_width() elif key is not None and self.settings.has_key(key): tab_size = self.settings[key][1] use_spaces = self.settings[key][0] else: use_spaces = gconf_get_bool("/apps/gedit-2/preferences/editor/tabs/insert_spaces", False) tab_size = gconf_get_int("/apps/gedit-2/preferences/editor/tabs/tabs_size", 4) debug('use spaces: %s, width: %s' % (use_spaces, tab_size)) view.set_tabs_width(tab_size) view.set_insert_spaces_instead_of_tabs(use_spaces) self.update_status() def on_open(self, *args): glade_xml = gtk.glade.XML(GLADE_FILE) if self.dialog: self.dialog.set_focus(True) return self.dialog = glade_xml.get_widget('tabulation_dialog') self.dialog.connect('delete_event', self.on_close) self.dialog.show_all() self.dialog.set_transient_for(self.window) self.cancel_button = glade_xml.get_widget('cancel_button') self.cancel_button.connect('clicked', self.on_cancel) self.apply_button = glade_xml.get_widget('apply_button') self.apply_button.connect('clicked', self.on_apply) view = self.window.get_active_view() space = view.get_insert_spaces_instead_of_tabs() size = view.get_tabs_width() self.size_picker = glade_xml.get_widget('size_picker') self.size_picker.set_value(size) self.use_spaces_check = glade_xml.get_widget('use_spaces_check') self.use_spaces_check.set_active(space) def on_close(self, *args): self.close_dialog() def close_dialog(self): self.dialog.destroy() self.dialog = None self.size_picker = None self.use_spaces_check = None def on_cancel(self, *args): self.close_dialog() def on_apply(self, *args): view = self.window.get_active_view() buffer = view.get_buffer() buffer.set_data('TabulationSkip', True) size = self.size_picker.get_value_as_int() use_spaces = self.use_spaces_check.get_active() view.set_insert_spaces_instead_of_tabs(use_spaces) view.set_tabs_width(size) self.update_status() self.close_dialog() gconf_client = gconf.client_get_default() def gconf_get_bool(key, default = False): val = gconf_client.get(key) if val is not None and val.type == gconf.VALUE_BOOL: return val.get_bool() else: return default def gconf_get_str(key, default = ""): val = gconf_client.get(key) if val is not None and val.type == gconf.VALUE_STRING: return val.get_string() else: return default def gconf_get_int(key, default = 0): val = gconf_client.get(key) if val is not None and val.type == gconf.VALUE_INT: return val.get_int() else: return default