vimmate 0.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. data/.autotest +10 -0
  2. data/CHANGELOG +108 -0
  3. data/COPYING +20 -0
  4. data/README +221 -0
  5. data/Rakefile +31 -0
  6. data/TODO +21 -0
  7. data/bin/vimmate +105 -0
  8. data/config/environment.rb +35 -0
  9. data/controllers/file_filter_controller.rb +101 -0
  10. data/controllers/file_popup_menu_controller.rb +40 -0
  11. data/controllers/vim_controller.rb +28 -0
  12. data/controllers/vim_mate_controller.rb +76 -0
  13. data/images/file.png +0 -0
  14. data/images/file_green.png +0 -0
  15. data/images/file_orange.png +0 -0
  16. data/images/file_red.png +0 -0
  17. data/images/folder.png +0 -0
  18. data/images/folder_green.png +0 -0
  19. data/images/folder_orange.png +0 -0
  20. data/images/folder_red.png +0 -0
  21. data/images/processing.png +0 -0
  22. data/images/svn_added.png +0 -0
  23. data/images/svn_conflict.png +0 -0
  24. data/images/svn_deleted.png +0 -0
  25. data/images/svn_locked.png +0 -0
  26. data/images/svn_modified.png +0 -0
  27. data/images/svn_normal.png +0 -0
  28. data/images/svn_readonly.png +0 -0
  29. data/images/vimmate16.png +0 -0
  30. data/images/vimmate32.png +0 -0
  31. data/images/vimmate48.png +0 -0
  32. data/lib/active_window/active_column.rb +218 -0
  33. data/lib/active_window/active_tree_store/columns.rb +88 -0
  34. data/lib/active_window/active_tree_store/extentions.rb +81 -0
  35. data/lib/active_window/active_tree_store/index.rb +53 -0
  36. data/lib/active_window/active_tree_store.rb +26 -0
  37. data/lib/active_window/application.rb +137 -0
  38. data/lib/active_window/controller.rb +58 -0
  39. data/lib/active_window/dot_file.rb +29 -0
  40. data/lib/active_window/filtered_active_tree_store.rb +113 -0
  41. data/lib/active_window/listed_item.rb +127 -0
  42. data/lib/active_window/signal.rb +46 -0
  43. data/lib/active_window.rb +8 -0
  44. data/lib/config_window.rb +90 -0
  45. data/lib/file_tree_store.rb +74 -0
  46. data/lib/filtered_file_tree_store.rb +34 -0
  47. data/lib/gtk_thread_helper.rb +73 -0
  48. data/lib/listed_directory.rb +45 -0
  49. data/lib/listed_file.rb +67 -0
  50. data/lib/try.rb +9 -0
  51. data/lib/vim/buffers.rb +18 -0
  52. data/lib/vim/integration.rb +38 -0
  53. data/lib/vim/netbeans.rb +154 -0
  54. data/lib/vim/source.vim +18 -0
  55. data/lib/vim_mate/config.rb +132 -0
  56. data/lib/vim_mate/dummy_window.rb +14 -0
  57. data/lib/vim_mate/files_menu.rb +110 -0
  58. data/lib/vim_mate/icons.rb +156 -0
  59. data/lib/vim_mate/nice_singleton.rb +53 -0
  60. data/lib/vim_mate/plugins/inotify/init.rb +4 -0
  61. data/lib/vim_mate/plugins/inotify/lib/INotify.rb +208 -0
  62. data/lib/vim_mate/plugins/inotify/lib/directory.rb +58 -0
  63. data/lib/vim_mate/plugins/subversion/init.rb +7 -0
  64. data/lib/vim_mate/plugins/subversion/lib/file.rb +59 -0
  65. data/lib/vim_mate/plugins/subversion/lib/menu.rb +96 -0
  66. data/lib/vim_mate/plugins/subversion/lib/subversion.rb +157 -0
  67. data/lib/vim_mate/plugins.rb +6 -0
  68. data/lib/vim_mate/requirer.rb +68 -0
  69. data/lib/vim_mate/search_window.rb +227 -0
  70. data/lib/vim_mate/tags_window.rb +167 -0
  71. data/lib/vim_mate/terminals_window.rb +163 -0
  72. data/lib/vim_mate/version.rb +29 -0
  73. data/lib/vim_mate/vim_widget.rb +143 -0
  74. data/spec/active_window/active_column_spec.rb +41 -0
  75. data/spec/active_window/active_tree_store_spec.rb +312 -0
  76. data/spec/active_window/controller_spec.rb +6 -0
  77. data/spec/lib/file_tree_store_spec.rb +40 -0
  78. data/spec/lib/listed_directory_spec.rb +26 -0
  79. data/spec/lib/listed_file_spec.rb +53 -0
  80. data/spec/nice_singleton_spec.rb +23 -0
  81. data/spec/spec.opts +6 -0
  82. data/spec/spec_helper.rb +10 -0
  83. data/views/vim_mate.glade +500 -0
  84. data/vimmate.gemspec +138 -0
  85. metadata +146 -0
@@ -0,0 +1,137 @@
1
+ class ActiveWindow::Application
2
+ include ActiveSupport::Callbacks
3
+ define_callbacks :after_initialize
4
+
5
+ attr_accessor :controller, :database, :glade, :window
6
+
7
+ def widget(name)
8
+ glade[name]
9
+ end
10
+
11
+ def initialize(options = {})
12
+ @glade = GladeXML.new(find_glade, nil, options[:title] || 'application' )
13
+ @window = widget(options[:main_window] || 'main_window')
14
+ @window.signal_connect("destroy") { Gtk.main_quit }
15
+ @dot_file_prefs = DotFile.read
16
+ @database = options[:database]
17
+ define_widget_readers
18
+ run_callbacks :after_initialize
19
+ end
20
+
21
+ def start
22
+ setup
23
+ window.show
24
+ run
25
+ end
26
+
27
+ def run
28
+ Gtk.main
29
+ end
30
+
31
+ def default_database
32
+ @dot_file_prefs[:db]
33
+ end
34
+
35
+ def save_default_database(hash)
36
+ @dot_file_prefs[:db] = hash
37
+ @dot_file_prefs.save
38
+ end
39
+
40
+ # creates the controllers, connects the signals
41
+ # calls 'setup' on each controller
42
+ def setup
43
+ @controller = {}
44
+
45
+ Module.constants.grep(/.Controller$/).each do |klass|
46
+ ctrl = Kernel.const_get(klass).instance
47
+ ctrl.application = self
48
+ ctrl.setup
49
+ name = klass.to_s.sub('Controller','').underscore.to_sym # eg MyFirstController -> :my_first
50
+ controller[name] = ctrl
51
+ end
52
+
53
+ glade.signal_autoconnect_full do |source, target, signal, handler, data|
54
+ # for example:
55
+ # source : instance of Gtk::ImageMenuItem
56
+ # target : nil
57
+ # signal : activate, clicked, pressed, etc.
58
+ # handler : window.close, which would call WindowController.close()
59
+ # data : nil
60
+ #puts [source, target, signal, handler, data].inspect
61
+ source.signal_connect(signal) { |widget,event| self.dispatch(handler, :source => source, :target => target, :signal => signal, :handler => handler, :data => data, :widget => widget, :event => event) }
62
+ #source.signal_connect(signal) { self.(handler, data) }
63
+ end
64
+ post_setup
65
+ end
66
+
67
+ # calls post_setup on each controller
68
+ def post_setup
69
+ controller.each do |name,ctrl|
70
+ ctrl.post_setup
71
+ end
72
+ end
73
+
74
+ ##
75
+ ## dispatch a signal to the correct controller
76
+ ##
77
+ def dispatch(handler, event)
78
+ controller_name,action = handler.to_s.split('.')
79
+ unless controller_name and action
80
+ return(error "cannot parse handler '%s'" % handler)
81
+ end
82
+
83
+ name = controller_name.to_sym
84
+ ctrl = controller[name]
85
+ unless ctrl
86
+ puts controller.inspect
87
+ return(error "no controller '%s' defined" % controller_name.camelize)
88
+ end
89
+
90
+ unless ctrl.respond_to? action
91
+ return(error "controller '%s' does not have a method '%s'" % [ctrl.class, action])
92
+ end
93
+
94
+ method = ctrl.method(action)
95
+ #puts "calling %s.%s" % [controller_name.camelize, action]
96
+ if method.arity == 0
97
+ method.call
98
+ else
99
+ method.call(event)
100
+ end
101
+ end
102
+
103
+
104
+ private
105
+
106
+ def class_exists?(classname)
107
+ return (Kernel::const_get(classname) rescue NameError) != NameError
108
+ end
109
+
110
+ def error(msg)
111
+ puts msg
112
+ end
113
+
114
+ def find_glade
115
+ Dir.glob("#{views_directory}/*.glade") do |f|
116
+ return f
117
+ end
118
+ raise "could not find a .glade file in #{views_directory}"
119
+ end
120
+
121
+ def views_directory
122
+ File.join(APP_ROOT, 'views')
123
+ end
124
+
125
+ def define_widget_readers
126
+ glade.widget_names.each do |widget|
127
+ meth = widget.underscore
128
+ instance_eval <<-EOEVAL
129
+ @#{meth} = glade['#{widget}']
130
+ def #{meth}
131
+ @#{meth}
132
+ end
133
+ EOEVAL
134
+ end
135
+ end
136
+
137
+ end
@@ -0,0 +1,58 @@
1
+ # require 'libglade2'
2
+ # require 'gtk2'
3
+
4
+ class ActiveWindow::Controller
5
+ include Singleton
6
+
7
+ attr_accessor :application
8
+
9
+ def app
10
+ application
11
+ end
12
+
13
+ def widget(name)
14
+ application.widget(name)
15
+ end
16
+
17
+ def controller
18
+ application.controller
19
+ end
20
+
21
+ def window
22
+ application.window
23
+ end
24
+
25
+ def database
26
+ application.database
27
+ end
28
+
29
+ # called on startup
30
+ def setup
31
+ end
32
+
33
+ # called on startup, after setup has been called for all controllers
34
+ def post_setup
35
+ end
36
+
37
+ def pref_set(key,value)
38
+ Preference.delete_all ['pref = ?', key]
39
+ Preference.create(:pref => key, :value => value)
40
+ value
41
+ end
42
+
43
+ def pref_get(key)
44
+ pref = Preference.find_by_pref(key)
45
+ return pref.value if pref
46
+ return nil
47
+ end
48
+
49
+ def pref_get_or_set(key,value)
50
+ pref_get(key) || pref_set(key,value)
51
+ end
52
+
53
+ def method_missing(name, *args, &block)
54
+ application.send name, *args, &block
55
+ end
56
+
57
+ end
58
+
@@ -0,0 +1,29 @@
1
+ =begin
2
+
3
+ A simple class for reading and writing settings information
4
+ to a dot file (~/.appname.yml)
5
+
6
+ =end
7
+
8
+ module ActiveWindow
9
+ class DotFile < ::Hash
10
+ def self.read(fname=nil)
11
+ fname ||= filename
12
+ unless File.exists? fname
13
+ new.save(fname)
14
+ end
15
+ YAML.load_file( fname )
16
+ end
17
+
18
+ def save(fname=nil)
19
+ fname ||= self.class.filename
20
+ File.open( fname, 'w+' ) do |out|
21
+ YAML.dump( self, out )
22
+ end
23
+ end
24
+
25
+ def self.filename
26
+ File.join ENV['HOME'], ".#{PROGRAM_NAME}.yml"
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,113 @@
1
+ module ActiveWindow
2
+ # This creates a TreeModel which supports filtering. Please give a block that "returns" boolean
3
+ #
4
+ # filtered_model = ActiveTreeStoreFilter.new model do |filter_string, model, path, iter|
5
+ # !iter[23].index(filter_string).nil?
6
+ # end
7
+ class FilteredActiveTreeStore < Gtk::TreeModelFilter
8
+ include TreeStoreExtentions
9
+
10
+ attr_reader :filter_string, :found_count
11
+ attr_reader :unfiltered_store
12
+ define_callbacks :before_filter_applied, :after_filter_applied
13
+ define_callbacks :before_clear_filter, :after_clear_filter
14
+
15
+ def self.inherited(child_class)
16
+ unfiltered_class_name = child_class.name.sub(/^Filtered/,'')
17
+ unfiltered_class = unfiltered_class_name.constantize
18
+ child_class.columns = unfiltered_class.columns
19
+ child_class.column_id = unfiltered_class.column_id
20
+ child_class.setup_column_id_constants
21
+ unfiltered_class.class_eval <<-EOCODE
22
+ def add_with_filter_visibility(file, *args)
23
+ iter = add_without_filter_visibility(file, *args)
24
+ filtered_model.set_visibility_for(iter)
25
+ filtered_model.refilter unless initial_add_in_progress?
26
+ iter
27
+ end
28
+ alias_method_chain :add, :filter_visibility
29
+ attr_accessor :filtered_model
30
+ EOCODE
31
+ rescue NameError => e
32
+ if e.message =~ /uninitialized constant #{unfiltered_class}/
33
+ raise "there is no class named #{unfiltered_class} to filter from"
34
+ else
35
+ raise
36
+ end
37
+ end
38
+
39
+ def initialize(child_model)
40
+ super(child_model)
41
+ setup_filter
42
+ end
43
+
44
+ def filter_string=(new_filter_string)
45
+ if new_filter_string.empty?
46
+ clear_filter
47
+ else
48
+ @filter_string = new_filter_string
49
+ apply_filter
50
+ end
51
+ end
52
+
53
+ def clear_filter
54
+ run_callbacks :before_clear_filter
55
+ @filter_string = ''
56
+ @found_count = -1
57
+ refilter
58
+ run_callbacks :after_clear_filter
59
+ end
60
+
61
+ # implement this to oyur own needs
62
+ def iter_visible?(iter)
63
+ true
64
+ end
65
+
66
+ # Iterate over child model and set visible column according to #iter_visible?
67
+ def apply_filter
68
+ run_callbacks :before_filter_applied
69
+ @found_count = 0
70
+ child_model.each do |model,path,iter|
71
+ set_visibility_for(iter)
72
+ end
73
+ refilter
74
+ run_callbacks :after_filter_applied
75
+ end
76
+
77
+ def filtered?
78
+ !filter_string.blank?
79
+ end
80
+ alias_method :filter, :filter_string
81
+ alias_method :filter=, :filter_string=
82
+ alias_method :filtering?, :filtered?
83
+
84
+ def set_visibility_for(iter)
85
+ visid = self.class.column_id[:visible]
86
+ unless filtering?
87
+ iter[ visid ] = true
88
+ else
89
+ if iter_visible?(iter) # iter matches - mark it and all parents as visible
90
+ @found_count += 1
91
+ iter[ visid ] = true
92
+ i = iter
93
+ while i = i.parent
94
+ i[ visid ] = true
95
+ end
96
+ else
97
+ iter[ visid ] = false
98
+ end
99
+ end
100
+ end
101
+
102
+ private
103
+
104
+ def setup_filter
105
+ set_visible_func do |model, iter|
106
+ !filtered? || iter[ self.class.column_id[:visible] ]
107
+ end
108
+ child_model.filtered_model = self
109
+ clear_filter
110
+ end
111
+
112
+ end
113
+ end
@@ -0,0 +1,127 @@
1
+ module ActiveWindow
2
+ # The ListItem is created on the fly
3
+ # * to oo-abstract methods to its TreeIter
4
+ # * for iteration in TreeController
5
+ # * as object in ActiveTreeStore
6
+ class ListedItem
7
+
8
+ def initialize(opts = {})
9
+ @traversed = false
10
+ self
11
+ end
12
+
13
+ def sort
14
+ "item-#{iter}"
15
+ end
16
+
17
+ def icon_name
18
+ nil
19
+ end
20
+
21
+ def icon
22
+ VimMate::Icons.by_name icon_name
23
+ end
24
+
25
+ # New by Gtk::TreeRowReference
26
+ def self.new_by_reference(reference)
27
+ new(:iter => reference.iter)
28
+ end
29
+
30
+ # New by Gtk::TreeIter
31
+ def self.new_by_iter(iter)
32
+ new(:iter => iter)
33
+ end
34
+
35
+ def message?
36
+ referenced_type == 'VimMate::Message'
37
+ end
38
+
39
+ def separator?
40
+ referenced_type == 'VimMate::Separator'
41
+ end
42
+
43
+ def file?
44
+ false
45
+ end
46
+
47
+ def directory?
48
+ false
49
+ end
50
+
51
+ def file_or_directory?
52
+ false
53
+ end
54
+
55
+ def show!
56
+ self.visible = true
57
+ # TODO hide seperator
58
+ #if directory? and Config[:file_directory_separator]
59
+ # if iter.next!
60
+ # tree.row_for_iter(iter).show!
61
+ # end
62
+ #end
63
+ end
64
+ def hide!
65
+ self.visible = false
66
+ # TODO hide seperator
67
+ #if directory? and Config[:file_directory_separator]
68
+ # if iter.next!
69
+ # tree.row_for_iter(iter).hide!
70
+ # end
71
+ #end
72
+ end
73
+
74
+ def visible?
75
+ visible
76
+ end
77
+
78
+ def matches?(str)
79
+ name.index(str)
80
+ end
81
+
82
+ def refresh
83
+ end
84
+
85
+ def reference
86
+ @reference ||= Gtk::TreeRowReference.new(tree.store, iter.path)
87
+ end
88
+
89
+ def reference=(new_ref)
90
+ if new_ref
91
+ @reference = new_ref
92
+ @iter = tree.store.get_iter(new_ref.path)
93
+ end
94
+ end
95
+
96
+ def self.build(attrs)
97
+ if full_path = attrs[:full_path]
98
+ if ::File.directory? full_path
99
+ 'ListedDirectory'
100
+ elsif ::File.file? full_path
101
+ 'ListedFile'
102
+ else
103
+ self
104
+ end
105
+ elsif iter = attrs[:iter] and !iter[REFERENCED_TYPE].nil?
106
+ iter[REFERENCED_TYPE]
107
+ else
108
+ self
109
+ end.constantize.new attrs
110
+ end
111
+
112
+ def to_s
113
+ "#{self.class} [#{iter.path}]"
114
+ end
115
+
116
+ def self.modify_icon(scope, &block)
117
+ with = "icon_name_with_#{scope}"
118
+ without = "icon_name_without_#{scope}"
119
+ define_method with do
120
+ block.call(self)
121
+ end
122
+ alias_method without, :icon_name
123
+ alias_method :icon_name, with
124
+ end
125
+
126
+ end
127
+ end
@@ -0,0 +1,46 @@
1
+ module ActiveWindow
2
+ class Signal
3
+ class UnknownSignalError < StandardError ; end
4
+ @@signals = {}
5
+
6
+ def self.on(name, &block)
7
+ @@signals[name] ||= []
8
+ @@signals[name] << block
9
+ end
10
+
11
+ def self.emit(name, *args)
12
+ if @@signals[name].is_a?(Array)
13
+ @@signals[name].each do |block|
14
+ block.call(*args)
15
+ end
16
+ end
17
+ end
18
+
19
+ def self.signals
20
+ @@signals
21
+ end
22
+
23
+ def self.define name
24
+ class_eval <<-EOCODE
25
+ def self.emit_#{name}(*args)
26
+ self.emit(:#{name},*args)
27
+ end
28
+ def self.on_#{name}(&block)
29
+ self.on(:#{name}, &block)
30
+ end
31
+ EOCODE
32
+ end
33
+
34
+ def self.method_missing(meth,*args,&block)
35
+ case meth.to_s
36
+ when /^emit_(.*)$/
37
+ raise UnknownSignalError, "cannot emit unknown signal '#{$1}'"
38
+ when /^on_(.*)$/
39
+ raise UnknownSignalError, "cannot connect to unknown signal '#{$1}'"
40
+ else
41
+ raise NoMethodError, "unknown method: #{meth}"
42
+ end
43
+ end
44
+
45
+ end
46
+ end
@@ -0,0 +1,8 @@
1
+ module ActiveWindow
2
+
3
+ end
4
+ require_dependency 'active_window/signal'
5
+ require_dependency 'active_window/active_tree_store/columns'
6
+ require_dependency 'active_window/active_tree_store/index'
7
+ require_dependency 'active_window/active_tree_store/extentions'
8
+ require_dependency 'active_window/filtered_active_tree_store'
@@ -0,0 +1,90 @@
1
+ module VimMate
2
+ class ConfigWindow
3
+ attr_reader :container
4
+ def initialize(main_window=nil)
5
+ @gtk_main_window = Gtk::Dialog.new("Configuration", main_window, Gtk::Dialog::MODAL,
6
+ [ Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_REJECT ],
7
+ [ Gtk::Stock::OK, Gtk::Dialog::RESPONSE_ACCEPT ]
8
+ )
9
+ gtk_window.set_default_size(400,300)
10
+ gtk_window.signal_connect('response') do |win,resp|
11
+ case resp
12
+ when Gtk::Dialog::RESPONSE_ACCEPT
13
+ save_settings
14
+ win.close
15
+ when Gtk::Dialog::RESPONSE_REJECT
16
+ win.close
17
+ when Gtk::Dialog::RESPONSE_NONE
18
+ puts "closing"
19
+ end
20
+ end
21
+ @container = gtk_window.vbox
22
+ fill_container
23
+ gtk_window.show_all
24
+ end
25
+ # The "window" for this object
26
+ def gtk_window
27
+ @gtk_main_window
28
+ end
29
+
30
+ def fill_container
31
+ @fields = {}
32
+ Config::DEFAULT_CONFIG.keys.sort {|a,b| a.to_s <=> b.to_s}.each do |key|
33
+ val = Config[key]
34
+ box = Gtk::HBox.new(true,10)
35
+ label = Gtk::Label.new(key.to_s.humanize)
36
+ label.xalign = 1
37
+ box.pack_start label, true, true
38
+
39
+ field = field_for val
40
+ @fields[key] = field
41
+ box.pack_start field, true, false
42
+ container.pack_start box
43
+ end
44
+ end
45
+
46
+ def save_settings
47
+ Config::DEFAULT_CONFIG.keys.each do |key|
48
+ if new_val = val_of(key)
49
+ Config.config[key] = new_val
50
+ end
51
+ end
52
+ Config.write_config
53
+ end
54
+
55
+ def val_of(key)
56
+ field = @fields[key]
57
+ case Config::DEFAULT_CONFIG[key]
58
+ when String
59
+ field.text
60
+ when Fixnum
61
+ field.value.to_i
62
+ when Float
63
+ field.value.to_f
64
+ when FalseClass, TrueClass
65
+ field.active?
66
+ end
67
+ end
68
+
69
+ def field_for(val)
70
+ case val
71
+ when String
72
+ # TODO make "textarea" for more than 42 chars
73
+ e = Gtk::Entry.new
74
+ e.editable = true
75
+ e.text = val
76
+ e
77
+ when Fixnum, Float
78
+ Gtk::SpinButton.new(
79
+ Gtk::Adjustment.new(val,0,10000,1,10,1),
80
+ 1,0)
81
+ when FalseClass, TrueClass
82
+ e = Gtk::ToggleButton.new
83
+ e.active = val
84
+ e
85
+ else
86
+ Gtk::Label.new(val.to_s)
87
+ end
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,74 @@
1
+ class FileTreeStore < ActiveWindow::ActiveTreeStore
2
+ column :full_path, String, :visible => false
3
+ column :status, String, :visible => false
4
+ column :sort, String, :visible => false
5
+
6
+ composite_column 'Files' do |col|
7
+ col.add column(:icon, Gdk::Pixbuf), false
8
+ col.add column(:name, String)
9
+ end
10
+
11
+ index_by :full_path
12
+
13
+ attr_reader :excludes
14
+ def initialize
15
+ super
16
+ @excludes ||= []
17
+ set_sort_column_id self.class.column_id[:sort]
18
+ ActiveWindow::Signal.on_file_modified { |path| refresh_path(path) }
19
+ ActiveWindow::Signal.on_file_created { |path| add_path(path) }
20
+ ActiveWindow::Signal.on_file_deleted { |path| remove_path(path) }
21
+ end
22
+
23
+ def add_path(path, parent=nil)
24
+ unless excludes?(File.expand_path(path))
25
+ file = ListedFile.create(:full_path => path)
26
+ iter = add file, parent || find_by_full_path( File.dirname(path) )
27
+ if file.directory?
28
+ file.children_paths.each do |child|
29
+ add_path(child, iter)
30
+ end
31
+ end
32
+ end
33
+ rescue ArgumentError => e
34
+ STDERR.puts e.message
35
+ end
36
+
37
+ def refresh_path(path)
38
+ if iter = find_by_full_path(path)
39
+ update_iter_from_object(iter, iter[OBJECT])
40
+ if iter[OBJECT].directory?
41
+ each do |iter|
42
+ if iter[FULL_PATH].start_with?(path)
43
+ refresh_path iter[FULL_PATH]
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
49
+
50
+ def remove_path(file_path)
51
+ if has_full_path?(file_path)
52
+ to_remove = []
53
+ each do |model,path,iter|
54
+ if iter[FULL_PATH].starts_with?(file_path)
55
+ to_remove << reference_for(iter)
56
+ end
57
+ end
58
+ to_remove.each do |element|
59
+ i = get_iter(element.path)
60
+ remove(i) if i
61
+ end
62
+ end
63
+ end
64
+
65
+ # Path ends with a node name contained in the exclude list
66
+ def excludes?(path)
67
+ excludes.any? {|f| path[-(f.size+1)..-1] == "/#{f}" }
68
+ end
69
+
70
+ def exclude!(new_exclude)
71
+ excludes << new_exclude.chomp.strip
72
+ end
73
+
74
+ end