ratchet 0.3.0
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.
- data/gem_bin/ratchet +23 -0
- data/lib/ratchet.rb +613 -0
- data/lib/ratchet/aliases.rb +106 -0
- data/lib/ratchet/bufferparser.rb +409 -0
- data/lib/ratchet/commandbuffer.rb +66 -0
- data/lib/ratchet/commandparser.rb +668 -0
- data/lib/ratchet/configuration.rb +278 -0
- data/lib/ratchet/connections.rb +403 -0
- data/lib/ratchet/constants.rb +111 -0
- data/lib/ratchet/contrib/instance_exec.rb +21 -0
- data/lib/ratchet/eventparser.rb +486 -0
- data/lib/ratchet/gtk/bufferlistview.rb +514 -0
- data/lib/ratchet/gtk/bufferview.rb +167 -0
- data/lib/ratchet/gtk/configwindow.rb +229 -0
- data/lib/ratchet/gtk/connectionwindow.rb +218 -0
- data/lib/ratchet/gtk/keybinding.rb +356 -0
- data/lib/ratchet/gtk/linkwindow.rb +137 -0
- data/lib/ratchet/gtk/mainwindow.rb +504 -0
- data/lib/ratchet/gtk/networkpresenceconf.rb +567 -0
- data/lib/ratchet/gtk/pluginconfig.rb +94 -0
- data/lib/ratchet/gtk/pluginwindow.rb +146 -0
- data/lib/ratchet/gtk/userlistview.rb +161 -0
- data/lib/ratchet/help.rb +64 -0
- data/lib/ratchet/items.rb +271 -0
- data/lib/ratchet/lines.rb +63 -0
- data/lib/ratchet/networks.rb +652 -0
- data/lib/ratchet/plugins.rb +616 -0
- data/lib/ratchet/queue.rb +47 -0
- data/lib/ratchet/ratchet-version.rb +21 -0
- data/lib/ratchet/replies.rb +134 -0
- data/lib/ratchet/replyparser.rb +441 -0
- data/lib/ratchet/tabcomplete.rb +98 -0
- data/lib/ratchet/users.rb +237 -0
- data/lib/ratchet/utils.rb +178 -0
- data/share/defaults.yaml +169 -0
- data/share/glade/config.glade +2634 -0
- data/share/glade/connect.glade +950 -0
- data/share/glade/keybindings.glade +109 -0
- data/share/glade/linkwindow.glade +188 -0
- data/share/glade/mainwindow.glade +335 -0
- data/share/glade/network-presences.glade +1373 -0
- data/share/glade/pluginconf.glade +97 -0
- data/share/glade/plugins.glade +360 -0
- data/share/plugins/colorewrite.rb +193 -0
- data/share/plugins/highlighter.rb +115 -0
- data/share/plugins/mpdplay.rb +123 -0
- data/share/plugins/numberswitcher.rb +30 -0
- data/share/plugins/sysinfo.rb +82 -0
- metadata +96 -0
|
@@ -0,0 +1,616 @@
|
|
|
1
|
+
=begin
|
|
2
|
+
This file is part of the Ratchet project, a client for Icecap.
|
|
3
|
+
Copyright (C) 2005-6 Andrew Thompson
|
|
4
|
+
|
|
5
|
+
This program is free software; you can redistribute it and/or modify
|
|
6
|
+
it under the terms of the GNU General Public License as published by
|
|
7
|
+
the Free Software Foundation; either version 2 of the License, or
|
|
8
|
+
(at your option) any later version.
|
|
9
|
+
|
|
10
|
+
This program is distributed in the hope that it will be useful,
|
|
11
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
+
GNU General Public License for more details.
|
|
14
|
+
|
|
15
|
+
You should have received a copy of the GNU General Public License
|
|
16
|
+
along with this program; if not, write to the Free Software
|
|
17
|
+
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
18
|
+
=end
|
|
19
|
+
|
|
20
|
+
#### plugins.rb ####
|
|
21
|
+
# Provides a pluginAPI mixin for addding plugin support to classes
|
|
22
|
+
# provides a base plugin class which all other plugins must derive from
|
|
23
|
+
# provides some configuration automation for plugins
|
|
24
|
+
####
|
|
25
|
+
|
|
26
|
+
#include this in any classes where you want plugins
|
|
27
|
+
module Ratchet
|
|
28
|
+
module PluginAPI
|
|
29
|
+
@@cb_hash = {}
|
|
30
|
+
@@cb_hash_after = {}
|
|
31
|
+
#calls all the callback blocks associated with method, should exit if a block returns true
|
|
32
|
+
def callback(method, *args)
|
|
33
|
+
|
|
34
|
+
#lookup the hash
|
|
35
|
+
# cb_hash = self.class.cb_hashes
|
|
36
|
+
# cb_hash ||= resolve_cb_hashes
|
|
37
|
+
|
|
38
|
+
#return if we get nothing
|
|
39
|
+
# callbacks = self.class.find_callbacks(method.to_sym)
|
|
40
|
+
# unless cb_hash
|
|
41
|
+
# puts cb_hash
|
|
42
|
+
# puts 'empty callback hash for '+self.class.to_s
|
|
43
|
+
# return *args
|
|
44
|
+
# end
|
|
45
|
+
|
|
46
|
+
#check if the callback is in the hash
|
|
47
|
+
# if cb_hash.has_key?(method.to_sym)
|
|
48
|
+
#initialize the return value as nil
|
|
49
|
+
ret = nil
|
|
50
|
+
|
|
51
|
+
#loop through the callbacks
|
|
52
|
+
# cb_hash[method.to_sym].each do |callback|
|
|
53
|
+
self.class.find_callbacks(method.to_sym).each do |callback|
|
|
54
|
+
|
|
55
|
+
#call the block and get the return value
|
|
56
|
+
#what about instance_eval here?
|
|
57
|
+
ret = self.instance_exec(*args, &callback)
|
|
58
|
+
# ret = callback.call(self, *args)
|
|
59
|
+
|
|
60
|
+
#if return value is true, break off calling any more callbacks (like GTK's system)
|
|
61
|
+
if ret === true
|
|
62
|
+
break
|
|
63
|
+
#if its an array, store the results so they can be passed to sucessive callbacks
|
|
64
|
+
elsif ret.kind_of? Array
|
|
65
|
+
ret.each_with_index { |z, i| args[i]=z}
|
|
66
|
+
|
|
67
|
+
#if a single value, assume first argument is returned
|
|
68
|
+
elsif ret
|
|
69
|
+
args[0] = ret
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
#if it returned true, let the calling function know
|
|
74
|
+
if ret === true
|
|
75
|
+
puts "returned true, disabling further callbacks or functions for #{method}"
|
|
76
|
+
return true
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
#otherwise return the arguments, possibly modified by callbacks.
|
|
80
|
+
return args
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
#calls all the callback_after blocks associated with method, should exit if a block returns true
|
|
84
|
+
def callback_after(method, *args)
|
|
85
|
+
#lookup the hash
|
|
86
|
+
# cb_hash_after = self.class.cb_hashes_after
|
|
87
|
+
# cb_hash_after ||= resolve_cb_hashes_after
|
|
88
|
+
|
|
89
|
+
# #return if nothing
|
|
90
|
+
# unless cb_hash_after
|
|
91
|
+
# puts 'empty callback_after hash for '+self.class.to_s
|
|
92
|
+
# return *args
|
|
93
|
+
# end
|
|
94
|
+
|
|
95
|
+
#check if the callback is in the hash
|
|
96
|
+
# if cb_hash_after.has_key?(method.to_sym)
|
|
97
|
+
|
|
98
|
+
#init the return value to nil
|
|
99
|
+
ret = nil
|
|
100
|
+
|
|
101
|
+
#loop through the callbacks
|
|
102
|
+
# cb_hash_after[method.to_sym].each do |callback|
|
|
103
|
+
self.class.find_callbacks_after(method.to_sym).each do |callback|
|
|
104
|
+
#call the callback, and get the return stuff
|
|
105
|
+
ret = self.instance_exec(*args, &callback)
|
|
106
|
+
# ret = callback.call(self, *args)
|
|
107
|
+
|
|
108
|
+
#if callback returns true, break off calling any other callbacks like GTK's signals
|
|
109
|
+
if ret === true
|
|
110
|
+
break
|
|
111
|
+
|
|
112
|
+
#if its an array, update the original arguments (assume they're passed in order)
|
|
113
|
+
elsif ret.kind_of? Array
|
|
114
|
+
ret.each_with_index { |z, i| args[i]=z}
|
|
115
|
+
|
|
116
|
+
#if single return, assume first argument
|
|
117
|
+
elsif ret
|
|
118
|
+
args[0] = ret
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
#let the calling function know it returned true
|
|
123
|
+
if ret === true
|
|
124
|
+
puts 'returned true, disabling further callbacks or functions for '+method
|
|
125
|
+
return true
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
#otherwise, return the arguments, possibly modified by callbacks
|
|
129
|
+
return args
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
#resolves the method name of the current method (is this still needed?)
|
|
133
|
+
def get_method_name()
|
|
134
|
+
/\`([^\']+)\'/.match(caller(1).first)[1].to_sym # we need a ' to close the damn thing :)
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
#load a plugin
|
|
138
|
+
def plugin_load(name)
|
|
139
|
+
#expand the name
|
|
140
|
+
return unless file = Plugin.find_plugin(name)
|
|
141
|
+
@config['plugins'] = [] unless @config['plugins'].class == Array
|
|
142
|
+
@config['plugins'].push(name) unless @config['plugins'].include?(name)
|
|
143
|
+
|
|
144
|
+
#check if it exists, if so, load it
|
|
145
|
+
if File.exists?(file)
|
|
146
|
+
begin
|
|
147
|
+
load(file, true)
|
|
148
|
+
rescue Exception => details
|
|
149
|
+
puts 'Error loading plugin '+name+' : '+details.message
|
|
150
|
+
puts details.backtrace
|
|
151
|
+
@config['plugins'].delete(name)
|
|
152
|
+
return false
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
#no plugin found
|
|
156
|
+
else
|
|
157
|
+
puts 'plugin file '+file+' not found'
|
|
158
|
+
@config['plugins'].delete(name)
|
|
159
|
+
return false
|
|
160
|
+
end
|
|
161
|
+
Plugin[name]
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
#wrapper function for class method
|
|
165
|
+
# def resolve_cb_hash
|
|
166
|
+
# puts 'resolving cb_hash'
|
|
167
|
+
# return self.class.resolve_cb_hash
|
|
168
|
+
# end
|
|
169
|
+
|
|
170
|
+
# #wrapper function for class method
|
|
171
|
+
# def resolve_cb_hash_after
|
|
172
|
+
# puts 'resolving cb_hash_after'
|
|
173
|
+
# return self.class.resolve_cb_hash_after
|
|
174
|
+
# end
|
|
175
|
+
|
|
176
|
+
#hyperextend!, these methods are added as class methods
|
|
177
|
+
module Plugins
|
|
178
|
+
#define a callback
|
|
179
|
+
def add_callback(name, &block)
|
|
180
|
+
#initialize the hash if it doesn't exist
|
|
181
|
+
@cb_hash ||= Hash.new
|
|
182
|
+
|
|
183
|
+
#make sure there's a function to attach a callback to
|
|
184
|
+
if self.private_instance_methods.include?(name.to_s) or self.instance_methods.include?(name.to_s)
|
|
185
|
+
|
|
186
|
+
#make a new array for the callback if need be, this allows multiple callbacks per function, executed in the order they were added
|
|
187
|
+
@cb_hash[name.to_sym] ||= Array.new
|
|
188
|
+
if block_given?
|
|
189
|
+
|
|
190
|
+
#add the block to the array
|
|
191
|
+
@cb_hash[name.to_sym].push(block)
|
|
192
|
+
puts "added callback for #{name}"
|
|
193
|
+
puts @cb_hash.inspect
|
|
194
|
+
# ObjectSpace.each_object(self) do |klass|
|
|
195
|
+
#puts klass
|
|
196
|
+
# klass.class.resolve_cb_hash
|
|
197
|
+
# end
|
|
198
|
+
#return the name of the callback..?
|
|
199
|
+
return name
|
|
200
|
+
end
|
|
201
|
+
else
|
|
202
|
+
#no function to attach to...
|
|
203
|
+
puts "no event function called #{name}, not adding callback"
|
|
204
|
+
return nil
|
|
205
|
+
end
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
#add a callback to be executed after a function
|
|
209
|
+
def add_callback_after(name, &block)
|
|
210
|
+
#again, make the hash if it doesn't exist
|
|
211
|
+
@cb_hash_after ||= Hash.new
|
|
212
|
+
|
|
213
|
+
#check to see if there's a function to attach to
|
|
214
|
+
if self.private_instance_methods.include?(name.to_s) or self.instance_methods.include?(name.to_s)
|
|
215
|
+
#make an array for the callbacks if there isn't one
|
|
216
|
+
@cb_hash_after[name.to_sym] ||= Array.new
|
|
217
|
+
if block_given?
|
|
218
|
+
@cb_hash_after[name.to_sym].push(block)
|
|
219
|
+
puts "added callback_after for #{name}"
|
|
220
|
+
puts @cb_hash_after.inspect
|
|
221
|
+
# ObjectSpace.each_object(self) do |klass|
|
|
222
|
+
#puts klass.class
|
|
223
|
+
# klass.class.resolve_cb_hash_after
|
|
224
|
+
# end
|
|
225
|
+
#return the name, not sure why...
|
|
226
|
+
return name
|
|
227
|
+
end
|
|
228
|
+
else
|
|
229
|
+
#no function!
|
|
230
|
+
puts "no event function called #{name}, not adding callback"
|
|
231
|
+
return nil
|
|
232
|
+
end
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
#remove a callback
|
|
236
|
+
def del_callback(name)
|
|
237
|
+
#puts self.class
|
|
238
|
+
puts @cb_hash.delete(name.to_sym)
|
|
239
|
+
puts @cb_hash.inspect
|
|
240
|
+
# resolve_cb_hashes
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
#remove a callback_after
|
|
244
|
+
def del_callback_after(name)
|
|
245
|
+
@cb_hash_after.delete(name.to_sym)
|
|
246
|
+
puts @cb_hash_after.inspect
|
|
247
|
+
# resolve_cb_hashes_after
|
|
248
|
+
puts @cb_hashes_after.inspect
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
#remove a method
|
|
252
|
+
def del_method(name)
|
|
253
|
+
self.send(:remove_method, name.to_sym)
|
|
254
|
+
# puts self.methods.inspect
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
#add a new method
|
|
258
|
+
def add_method(name, &block)
|
|
259
|
+
#make sure its not already defined....
|
|
260
|
+
if self.private_instance_methods.include?(name.to_s) or self.instance_methods.include?(name.to_s)
|
|
261
|
+
puts 'method '+name+' already defined, not redefining'
|
|
262
|
+
return nil
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
#call define method and add it.
|
|
266
|
+
self.send(:define_method, name, &block)
|
|
267
|
+
#puts 'added '+name
|
|
268
|
+
return name
|
|
269
|
+
end
|
|
270
|
+
|
|
271
|
+
#reader for cb_hash...?
|
|
272
|
+
def cb_hash
|
|
273
|
+
@cb_hash ||= Hash.new
|
|
274
|
+
return @cb_hash
|
|
275
|
+
end
|
|
276
|
+
|
|
277
|
+
def cb_hashes
|
|
278
|
+
resolve_cb_hashes unless @cb_hashes
|
|
279
|
+
@cb_hashes
|
|
280
|
+
end
|
|
281
|
+
|
|
282
|
+
#lookup parent classes for callbacks
|
|
283
|
+
#TODO is there a way to do this less then once per callback call without messing up plugin unloading?
|
|
284
|
+
def resolve_cb_hashes
|
|
285
|
+
#a new hash to store the resulting callbacks
|
|
286
|
+
hashes = [cb_hash]
|
|
287
|
+
|
|
288
|
+
#loop through the parent classes, and build an array of them....
|
|
289
|
+
c = self
|
|
290
|
+
classes = Array.new
|
|
291
|
+
|
|
292
|
+
while c != Object || nil
|
|
293
|
+
classes.push(c)
|
|
294
|
+
c = c.superclass
|
|
295
|
+
end
|
|
296
|
+
|
|
297
|
+
#reverse the array of classes, so callbacks are overridden in child classes
|
|
298
|
+
classes.reverse!
|
|
299
|
+
|
|
300
|
+
#loop through, and add callbacks
|
|
301
|
+
classes.each do |klass|
|
|
302
|
+
if klass.respond_to? :cb_hash
|
|
303
|
+
hashes << klass.cb_hash# if klass.cb_hash
|
|
304
|
+
end
|
|
305
|
+
end
|
|
306
|
+
|
|
307
|
+
#return
|
|
308
|
+
#return temphash
|
|
309
|
+
@cb_hashes = hashes
|
|
310
|
+
end
|
|
311
|
+
|
|
312
|
+
def find_callbacks(method)
|
|
313
|
+
ret = []
|
|
314
|
+
x = cb_hashes.select{|x| x.has_key? method}
|
|
315
|
+
# puts x.inspect, @cb_hashes.inspect
|
|
316
|
+
x.each do |y|
|
|
317
|
+
ret += y[method]
|
|
318
|
+
end
|
|
319
|
+
# puts "found callbacks: #{ret.inspect}"
|
|
320
|
+
ret
|
|
321
|
+
end
|
|
322
|
+
|
|
323
|
+
def find_callbacks_after(method)
|
|
324
|
+
# puts method
|
|
325
|
+
ret = []
|
|
326
|
+
x = cb_hashes_after.select{|x| x.has_key? method}
|
|
327
|
+
# puts x.inspect, @cb_hashes_after.inspect
|
|
328
|
+
x.each do |y|
|
|
329
|
+
ret += y[method]
|
|
330
|
+
end
|
|
331
|
+
# puts "found callbacks after: #{ret.inspect}"
|
|
332
|
+
ret
|
|
333
|
+
end
|
|
334
|
+
|
|
335
|
+
#reader for cb_hash_after
|
|
336
|
+
def cb_hash_after
|
|
337
|
+
@cb_hash_after ||= Hash.new
|
|
338
|
+
return @cb_hash_after
|
|
339
|
+
end
|
|
340
|
+
|
|
341
|
+
def cb_hashes_after
|
|
342
|
+
resolve_cb_hashes_after unless @cb_hashes_after
|
|
343
|
+
@cb_hashes_after
|
|
344
|
+
end
|
|
345
|
+
|
|
346
|
+
#lookup parent classes for callback_after
|
|
347
|
+
def resolve_cb_hashes_after
|
|
348
|
+
|
|
349
|
+
#new hash to store results
|
|
350
|
+
hashes = [cb_hash_after]
|
|
351
|
+
|
|
352
|
+
#loop through parents and build an array
|
|
353
|
+
c = self
|
|
354
|
+
classes = Array.new
|
|
355
|
+
|
|
356
|
+
while c != Object || nil
|
|
357
|
+
classes.push(c)
|
|
358
|
+
c = c.superclass
|
|
359
|
+
end
|
|
360
|
+
|
|
361
|
+
#invert the array, so child callbacks override parents
|
|
362
|
+
classes.reverse!
|
|
363
|
+
|
|
364
|
+
#build hash of callback_after
|
|
365
|
+
classes.each do |klass|
|
|
366
|
+
# puts klass, klass.respond_to?(:cb_hash_after)
|
|
367
|
+
if klass.respond_to? :cb_hash_after
|
|
368
|
+
# puts "#{klass} has cb_hash_after"
|
|
369
|
+
# puts klass.cb_hash_after.inspect
|
|
370
|
+
hashes << klass.cb_hash_after# if klass.cb_hash_after
|
|
371
|
+
end
|
|
372
|
+
end
|
|
373
|
+
|
|
374
|
+
#return
|
|
375
|
+
#return temphash
|
|
376
|
+
# puts "resolved cb_hashes_after to: #{hashes.inspect} for class #{self}"
|
|
377
|
+
@cb_hashes_after = hashes
|
|
378
|
+
end
|
|
379
|
+
end
|
|
380
|
+
|
|
381
|
+
extend Plugins
|
|
382
|
+
|
|
383
|
+
def self.append_features(klass)
|
|
384
|
+
super
|
|
385
|
+
klass.extend(Plugins)
|
|
386
|
+
end
|
|
387
|
+
|
|
388
|
+
def method_missing(symbol, *args)
|
|
389
|
+
plugin = Plugin.find_plugin_method(symbol)
|
|
390
|
+
if plugin
|
|
391
|
+
plugin[0].send(symbol, *args)
|
|
392
|
+
else
|
|
393
|
+
puts "cannot find method #{symbol} in plugins"
|
|
394
|
+
nil
|
|
395
|
+
# raise NoMethodError
|
|
396
|
+
end
|
|
397
|
+
end
|
|
398
|
+
end
|
|
399
|
+
|
|
400
|
+
#the plugin class, all plugins are derivatives of this class
|
|
401
|
+
class Plugin
|
|
402
|
+
include PluginAPI
|
|
403
|
+
|
|
404
|
+
def self.main=(main)
|
|
405
|
+
@@main= main
|
|
406
|
+
# puts "set main to #{main}"
|
|
407
|
+
end
|
|
408
|
+
|
|
409
|
+
#register a plugin
|
|
410
|
+
def self.register(plugin)
|
|
411
|
+
# puts 'registeting'
|
|
412
|
+
if /([\w\-]+)\.rb/.match(caller[0])
|
|
413
|
+
unless find_plugin($1)
|
|
414
|
+
raise SystemCallError, 'No such file '+$1+' to load as plugin', caller
|
|
415
|
+
end
|
|
416
|
+
name = $1
|
|
417
|
+
else
|
|
418
|
+
raise SystemCallError, 'Plugin does not have a name', caller
|
|
419
|
+
end
|
|
420
|
+
|
|
421
|
+
#plugin must be a child of Plugin class..
|
|
422
|
+
unless plugin.class.superclass == Plugin
|
|
423
|
+
puts 'Plugin must be subclass of Plugin'
|
|
424
|
+
return
|
|
425
|
+
end
|
|
426
|
+
|
|
427
|
+
#make sure its not already defined
|
|
428
|
+
if self[name]
|
|
429
|
+
puts "a plugin called #{name} is already registered"
|
|
430
|
+
return
|
|
431
|
+
end
|
|
432
|
+
|
|
433
|
+
#init the plugin hash if it doesn't exist
|
|
434
|
+
@@plugins ||= {}
|
|
435
|
+
|
|
436
|
+
#stuff the data in it
|
|
437
|
+
@@plugins[plugin] = {:name => name, :callbacks => Array.new, :callbacks_after => Array.new, :methods => Array.new} if plugin and !@@plugins[plugin]
|
|
438
|
+
|
|
439
|
+
#call the plugins load() method
|
|
440
|
+
@@main.console.send_user_event({'msg' => 'Loading Plugin '+name}, EVENT_NOTICE)
|
|
441
|
+
plugin.load
|
|
442
|
+
# puts self, self.class
|
|
443
|
+
end
|
|
444
|
+
|
|
445
|
+
def help(a, b)
|
|
446
|
+
self.class.help(a, b)
|
|
447
|
+
end
|
|
448
|
+
|
|
449
|
+
#TODO - what if the function we lookup is shared between multiple plugins?
|
|
450
|
+
def self.find_plugin_method(method)
|
|
451
|
+
plugin = @@plugins.detect do |p, info|
|
|
452
|
+
p.respond_to? method
|
|
453
|
+
end
|
|
454
|
+
plugin
|
|
455
|
+
end
|
|
456
|
+
|
|
457
|
+
#unload a plugin and remove all methods/callbacks added by it...
|
|
458
|
+
def self.unregister(plugin)
|
|
459
|
+
|
|
460
|
+
#make sure the plugin is registered
|
|
461
|
+
return false unless @@plugins and @@plugins[plugin]
|
|
462
|
+
|
|
463
|
+
#remove all the callbacks
|
|
464
|
+
@@plugins[plugin][:callbacks].each do |c|
|
|
465
|
+
c[:class].del_callback(c[:callback])
|
|
466
|
+
puts "removed callback #{c[:callback]} for class #{c[:class]}"
|
|
467
|
+
end
|
|
468
|
+
|
|
469
|
+
#remove all the callback_afters
|
|
470
|
+
@@plugins[plugin][:callbacks_after].each do |c|
|
|
471
|
+
c[:class].del_callback_after(c[:callback])
|
|
472
|
+
puts "removed callback_after #{c[:callback]} for class #{c[:class]}"
|
|
473
|
+
end
|
|
474
|
+
|
|
475
|
+
#remove all the methods
|
|
476
|
+
@@plugins[plugin][:methods].each do |c|
|
|
477
|
+
c[:class].del_method(c[:method])
|
|
478
|
+
puts "removed method #{c[:method]} for class #{c[:class]}"
|
|
479
|
+
end
|
|
480
|
+
|
|
481
|
+
@@main.config['plugins'].delete(@@plugins[plugin][:name])
|
|
482
|
+
|
|
483
|
+
#delete the plugin from the hash
|
|
484
|
+
@@plugins.delete(plugin)
|
|
485
|
+
|
|
486
|
+
#call the unload function if the plugin wants to do any additional cleanup
|
|
487
|
+
plugin.unload
|
|
488
|
+
true
|
|
489
|
+
end
|
|
490
|
+
|
|
491
|
+
#list registered plugins.
|
|
492
|
+
def self.list
|
|
493
|
+
@@plugins ||= {}
|
|
494
|
+
return @@plugins
|
|
495
|
+
end
|
|
496
|
+
|
|
497
|
+
#lookup a string as a plugin name
|
|
498
|
+
def self.[](name)
|
|
499
|
+
# puts "looking up #{name}"
|
|
500
|
+
@@plugins ||= {}
|
|
501
|
+
x = @@plugins.detect{|p| p[1][:name] == name}
|
|
502
|
+
x = x[0] if x
|
|
503
|
+
return x
|
|
504
|
+
end
|
|
505
|
+
|
|
506
|
+
#wrapper function for adding a callback to a class
|
|
507
|
+
def add_callback(plugin, classname, name, &block)
|
|
508
|
+
|
|
509
|
+
#make sure the plugin is registered
|
|
510
|
+
if @@plugins[plugin]
|
|
511
|
+
#add the callback, make sure its not already defined for this plugin and then define it iof add is sucessful
|
|
512
|
+
if callback = classname.add_callback(name, &block) and !@@plugins[plugin][:callbacks].include?({:callback=>callback, :class=>classname})
|
|
513
|
+
@@plugins[plugin][:callbacks].push({:callback=>callback, :class=>classname})
|
|
514
|
+
end
|
|
515
|
+
|
|
516
|
+
#error
|
|
517
|
+
else
|
|
518
|
+
puts 'plugin not registered'
|
|
519
|
+
end
|
|
520
|
+
end
|
|
521
|
+
|
|
522
|
+
def add_callback_after(plugin, classname, name, &block)
|
|
523
|
+
|
|
524
|
+
#make sure the plugin is registered
|
|
525
|
+
if @@plugins[plugin]
|
|
526
|
+
#add the callback, make sure its not already defined for this plugin and then define it if add is sucessful
|
|
527
|
+
if callback = classname.add_callback_after(name, &block) and !@@plugins[plugin][:callbacks_after].include?({:callback=>callback, :class=>classname})
|
|
528
|
+
@@plugins[plugin][:callbacks_after].push({:callback=>callback, :class=>classname})
|
|
529
|
+
end
|
|
530
|
+
|
|
531
|
+
#error
|
|
532
|
+
else
|
|
533
|
+
puts 'plugin not registered'
|
|
534
|
+
end
|
|
535
|
+
end
|
|
536
|
+
|
|
537
|
+
def add_method(plugin, classname, name, &block)
|
|
538
|
+
#make sure the plugin is registered
|
|
539
|
+
if @@plugins[plugin]
|
|
540
|
+
#add the callback, make sure its not already defined for this plugin and then define it if add is sucessful
|
|
541
|
+
if method = classname.add_method(name, &block) and !@@plugins[plugin][:methods].include?({:method=>method, :class=>classname})
|
|
542
|
+
@@plugins[plugin][:methods].push({:method=>method, :class=>classname})
|
|
543
|
+
end
|
|
544
|
+
|
|
545
|
+
#error
|
|
546
|
+
else
|
|
547
|
+
puts 'plugin not registered'
|
|
548
|
+
end
|
|
549
|
+
end
|
|
550
|
+
|
|
551
|
+
def self.find_plugin(name)
|
|
552
|
+
return unless name
|
|
553
|
+
name += '.rb'
|
|
554
|
+
dir1 = File.join($ratchetfolder, 'plugins')
|
|
555
|
+
dir2 = "#{DATADIR}/plugins"
|
|
556
|
+
if File.directory?(dir1) and Dir.entries(dir1).include?(name)
|
|
557
|
+
return File.join(dir1, name)
|
|
558
|
+
elsif File.directory?(dir2) and Dir.entries(dir2).include?(name)
|
|
559
|
+
return File.join(dir2, name)
|
|
560
|
+
else
|
|
561
|
+
return false
|
|
562
|
+
end
|
|
563
|
+
end
|
|
564
|
+
|
|
565
|
+
#stub for unload function to allow plugins to do additional cleanup
|
|
566
|
+
def unload
|
|
567
|
+
end
|
|
568
|
+
|
|
569
|
+
#stub for configure function
|
|
570
|
+
# def configure
|
|
571
|
+
# []
|
|
572
|
+
# end
|
|
573
|
+
end
|
|
574
|
+
|
|
575
|
+
class PluginConfig
|
|
576
|
+
#The GTK specific part of this has been moved to gtk/pluginconfig.rb
|
|
577
|
+
|
|
578
|
+
def bool_changed(widget)
|
|
579
|
+
change_setting(widget, widget.active?)
|
|
580
|
+
end
|
|
581
|
+
|
|
582
|
+
def color_changed(widget)
|
|
583
|
+
change_setting(widget, Color.new(*widget.color.to_a))
|
|
584
|
+
end
|
|
585
|
+
|
|
586
|
+
def text_changed(widget)
|
|
587
|
+
change_setting(widget, widget.text)
|
|
588
|
+
end
|
|
589
|
+
|
|
590
|
+
def integer_changed(widget)
|
|
591
|
+
change_setting(widget, widget.text.to_i)
|
|
592
|
+
end
|
|
593
|
+
|
|
594
|
+
def array_changed(widget)
|
|
595
|
+
change_setting(widget, widget.text.split(',').uniq)
|
|
596
|
+
end
|
|
597
|
+
|
|
598
|
+
def change_setting(widget, setting)
|
|
599
|
+
#puts 'changed setting of '+widget.name+' to '+setting.to_s
|
|
600
|
+
@configarray[widget]['value'] = setting
|
|
601
|
+
end
|
|
602
|
+
|
|
603
|
+
def update_config
|
|
604
|
+
@configarray.each do |k, v|
|
|
605
|
+
#puts v['name']+' = '+v['value'].to_s
|
|
606
|
+
@config[v['name']] = v['value']
|
|
607
|
+
end
|
|
608
|
+
destroy
|
|
609
|
+
@main.send_command('sendconfig', @config.changes)
|
|
610
|
+
end
|
|
611
|
+
|
|
612
|
+
def destroy
|
|
613
|
+
@window.destroy
|
|
614
|
+
end
|
|
615
|
+
end
|
|
616
|
+
end
|