# 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