33import logging
44import tempfile
55import ctags
6- from gi .repository import GObject , GdkPixbuf , Gedit , Gtk
6+ from gi .repository import GObject , GdkPixbuf , Gedit , Gtk , PeasGtk , Gio
77
88logging .basicConfig ()
99LOG_LEVEL = logging .WARN
10-
10+ SETTINGS_SCHEMA = "org.gnome.gedit.plugins.sourcecodebrowser"
1111DATA_DIR = os .path .join (os .path .dirname (__file__ ), 'data' )
1212ICON_DIR = os .path .join (DATA_DIR , 'icons' , '16x16' )
1313
@@ -21,6 +21,22 @@ class SourceTree(Gtk.VBox):
2121 __gsignals__ = {
2222 "tag-activated" : (GObject .SIGNAL_RUN_FIRST , GObject .TYPE_NONE , (GObject .TYPE_PYOBJECT ,)),
2323 }
24+
25+ def __init__ (self ):
26+ Gtk .VBox .__init__ (self )
27+ self ._log = logging .getLogger (self .__class__ .__name__ )
28+ self ._log .setLevel (LOG_LEVEL )
29+ self ._pixbufs = {}
30+ self .expanded_rows = {}
31+
32+ # preferences (should be set by plugin)
33+ self .show_line_numbers = True
34+ self .ctags_executable = 'ctags'
35+ self .expand_rows = True
36+
37+ self .create_ui ()
38+ self .show_all ()
39+
2440 def get_pixbuf (self , icon_name ):
2541 """
2642 Get the pixbuf for a specific icon name fron an internal dictionary of
@@ -35,23 +51,10 @@ def get_pixbuf(self, icon_name):
3551 self ._log .warn ("Could not load pixbuf for icon '%s': %s" ,
3652 icon_name ,
3753 str (e ))
54+ self ._pixbufs [icon_name ] = GdkPixbuf .Pixbuf .new_from_file (
55+ os .path .join (ICON_DIR , "missing-image.png" ))
3856 return self ._pixbufs [icon_name ]
39-
40- def __init__ (self ):
41- Gtk .VBox .__init__ (self )
42- self ._log = logging .getLogger (self .__class__ .__name__ )
43- self ._log .setLevel (LOG_LEVEL )
44- self ._pixbufs = {}
45- self .expanded_rows = {}
46-
47- # preferences (should be set by plugin)
48- self .show_line_numbers = True
49- self .ctags_executable = 'ctags'
50- self .expand_rows = True
51-
52- self .create_ui ()
53- self .show_all ()
54-
57+
5558 def clear (self ):
5659 """ Clear the tree view so that new data can be loaded. """
5760 self ._store .clear ()
@@ -228,7 +231,7 @@ def parse_file(self, path, uri):
228231 filename to pass to ctags, and the uri is the actual URI as known by
229232 Gedit. They would be different for remote files.
230233 """
231- command = "ctags -n --fields=fiKlmnsSzt -f - %s " % path
234+ command = "ctags -n --fields=fiKlmnsSzt -f - '%s' " % path
232235 #self._log.debug(command)
233236 try :
234237 parser = ctags .Parser ()
@@ -238,8 +241,57 @@ def parse_file(self, path, uri):
238241 str (e ),
239242 self .ctags_executable )
240243 self .load (parser .kinds , parser .tags , uri )
244+
245+ class Config (object ):
246+ def __init__ (self ):
247+ self ._log = logging .getLogger (self .__class__ .__name__ )
248+ self ._log .setLevel (LOG_LEVEL )
249+
250+ def get_widget (self , has_schema ):
251+ filename = os .path .join (DATA_DIR , 'configure_dialog.ui' )
252+ builder = Gtk .Builder ()
253+ try :
254+ count = builder .add_objects_from_file (filename , ["configure_widget" ])
255+ assert (count > 0 )
256+ except Exception as e :
257+ self ._log .error ("Failed to load %s: %s." % (filename , str (e )))
258+ return None
259+ widget = builder .get_object ("configure_widget" )
260+ widget .set_border_width (12 )
241261
242- class SourceCodeBrowserPlugin (GObject .Object , Gedit .WindowActivatable ):
262+ if not has_schema :
263+ widget .set_sensitive (False )
264+ else :
265+ self ._settings = Gio .Settings .new (SETTINGS_SCHEMA )
266+ builder .get_object ("show_line_numbers" ).set_active (
267+ self ._settings .get_boolean ('show-line-numbers' )
268+ )
269+ builder .get_object ("expand_rows" ).set_active (
270+ self ._settings .get_boolean ('expand-rows' )
271+ )
272+ builder .get_object ("load_remote_files" ).set_active (
273+ self ._settings .get_boolean ('load-remote-files' )
274+ )
275+ builder .get_object ("ctags_executable" ).set_text (
276+ self ._settings .get_string ('ctags-executable' )
277+ )
278+ builder .connect_signals (self )
279+ return widget
280+
281+ def on_show_line_numbers_toggled (self , button , data = None ):
282+ self ._settings .set_boolean ('show-line-numbers' , button .get_active ())
283+
284+ def on_expand_rows_toggled (self , button , data = None ):
285+ self ._settings .set_boolean ('expand-rows' , button .get_active ())
286+
287+ def on_load_remote_files_toggled (self , button , data = None ):
288+ self ._settings .set_boolean ('load-remote-files' , button .get_active ())
289+
290+ def on_ctags_executable_changed (self , editable , data = None ):
291+ self ._settings .set_string ('ctags-executable' , editable .get_text ())
292+
293+
294+ class SourceCodeBrowserPlugin (GObject .Object , Gedit .WindowActivatable , PeasGtk .Configurable ):
243295 """
244296 Source Code Browser Plugin for Gedit 3.x
245297
@@ -250,26 +302,23 @@ class SourceCodeBrowserPlugin(GObject.Object, Gedit.WindowActivatable):
250302 """
251303 __gtype_name__ = "SourceCodeBrowserPlugin"
252304 window = GObject .property (type = Gedit .Window )
253-
305+
254306 def __init__ (self ):
255307 GObject .Object .__init__ (self )
256308 self ._log = logging .getLogger (self .__class__ .__name__ )
257309 self ._log .setLevel (LOG_LEVEL )
258310 self ._ctags_version = None
259-
260- # preferences
261- # TODO: Put preferences into the config dialog
262- self .load_remote_files = True
263- self .ctags_executable = 'ctags'
264- self .show_line_numbers = False
265- self .expand_rows = True
266-
311+
267312 filename = os .path .join (ICON_DIR , "source-code-browser.png" )
268313 self .icon = Gtk .Image .new_from_file (filename )
269-
314+
315+ def do_create_configure_widget (self ):
316+ return Config ().get_widget (self ._has_settings_schema ())
317+
270318 def do_activate (self ):
271319 """ Activate plugin """
272320 self ._log .debug ("Activating plugin" )
321+ self ._init_settings ()
273322 self ._version_check ()
274323 self ._sourcetree = SourceTree ()
275324 self ._sourcetree .ctags_executable = self .ctags_executable
@@ -292,9 +341,34 @@ def do_deactivate(self):
292341 pane = self .window .get_side_panel ()
293342 pane .remove_item (self ._sourcetree )
294343
295- def do_update_state (self ):
296- pass
297-
344+ def _has_settings_schema (self ):
345+ schemas = Gio .Settings .list_schemas ()
346+ if not SETTINGS_SCHEMA in schemas :
347+ return False
348+ else :
349+ return True
350+
351+ def _init_settings (self ):
352+ """ Initialize GSettings if available. """
353+ if self ._has_settings_schema ():
354+ settings = Gio .Settings .new (SETTINGS_SCHEMA )
355+ self .load_remote_files = settings .get_boolean ("load-remote-files" )
356+ self .show_line_numbers = settings .get_boolean ("show-line-numbers" )
357+ self .expand_rows = settings .get_boolean ("expand-rows" )
358+ self .ctags_executable = settings .get_string ("ctags-executable" )
359+ settings .connect ("changed::load-remote-files" , self .on_setting_changed )
360+ settings .connect ("changed::show-line-numbers" , self .on_setting_changed )
361+ settings .connect ("changed::expand-rows" , self .on_setting_changed )
362+ settings .connect ("changed::ctags-executable" , self .on_setting_changed )
363+ self ._settings = settings
364+ else :
365+ self ._log .warn ("Settings schema not installed. Plugin will not be configurable." )
366+ self ._settings = None
367+ self .load_remote_files = True
368+ self .show_line_numbers = False
369+ self .expand_rows = True
370+ self .ctags_executable = 'ctags'
371+
298372 def _load_active_document_symbols (self ):
299373 """ Load the symbols for the given URI. """
300374 self ._sourcetree .clear ()
@@ -329,6 +403,28 @@ def on_active_tab_changed(self, window, tab, data=None):
329403 self ._log .debug ("active-tab-changed" )
330404 self ._load_active_document_symbols ()
331405
406+ def on_setting_changed (self , settings , key , data = None ):
407+ """
408+ self.load_remote_files = True
409+ self.show_line_numbers = False
410+ self.expand_rows = True
411+ self.ctags_executable = 'ctags'
412+ """
413+ if key == 'load-remote-files' :
414+ self .load_remote_files = self ._settings .get_boolean (key )
415+ elif key == 'show-line-numbers' :
416+ self .show_line_numbers = self ._settings .get_boolean (key )
417+ elif key == 'expand-rows' :
418+ self .expand_rows = self ._settings .get_boolean (key )
419+ elif key == 'ctags-executable' :
420+ self .ctags_executable = self ._settings .get_string (key )
421+
422+ if self ._sourcetree is not None :
423+ self ._sourcetree .ctags_executable = self .ctags_executable
424+ self ._sourcetree .show_line_numbers = self .show_line_numbers
425+ self ._sourcetree .expand_rows = self .expand_rows
426+ self ._load_active_document_symbols ()
427+
332428 def on_tab_state_changed (self , window , data = None ):
333429 self ._log .debug ("tab-state-changed" )
334430 self ._load_active_document_symbols ()
0 commit comments