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.
Files changed (49) hide show
  1. data/gem_bin/ratchet +23 -0
  2. data/lib/ratchet.rb +613 -0
  3. data/lib/ratchet/aliases.rb +106 -0
  4. data/lib/ratchet/bufferparser.rb +409 -0
  5. data/lib/ratchet/commandbuffer.rb +66 -0
  6. data/lib/ratchet/commandparser.rb +668 -0
  7. data/lib/ratchet/configuration.rb +278 -0
  8. data/lib/ratchet/connections.rb +403 -0
  9. data/lib/ratchet/constants.rb +111 -0
  10. data/lib/ratchet/contrib/instance_exec.rb +21 -0
  11. data/lib/ratchet/eventparser.rb +486 -0
  12. data/lib/ratchet/gtk/bufferlistview.rb +514 -0
  13. data/lib/ratchet/gtk/bufferview.rb +167 -0
  14. data/lib/ratchet/gtk/configwindow.rb +229 -0
  15. data/lib/ratchet/gtk/connectionwindow.rb +218 -0
  16. data/lib/ratchet/gtk/keybinding.rb +356 -0
  17. data/lib/ratchet/gtk/linkwindow.rb +137 -0
  18. data/lib/ratchet/gtk/mainwindow.rb +504 -0
  19. data/lib/ratchet/gtk/networkpresenceconf.rb +567 -0
  20. data/lib/ratchet/gtk/pluginconfig.rb +94 -0
  21. data/lib/ratchet/gtk/pluginwindow.rb +146 -0
  22. data/lib/ratchet/gtk/userlistview.rb +161 -0
  23. data/lib/ratchet/help.rb +64 -0
  24. data/lib/ratchet/items.rb +271 -0
  25. data/lib/ratchet/lines.rb +63 -0
  26. data/lib/ratchet/networks.rb +652 -0
  27. data/lib/ratchet/plugins.rb +616 -0
  28. data/lib/ratchet/queue.rb +47 -0
  29. data/lib/ratchet/ratchet-version.rb +21 -0
  30. data/lib/ratchet/replies.rb +134 -0
  31. data/lib/ratchet/replyparser.rb +441 -0
  32. data/lib/ratchet/tabcomplete.rb +98 -0
  33. data/lib/ratchet/users.rb +237 -0
  34. data/lib/ratchet/utils.rb +178 -0
  35. data/share/defaults.yaml +169 -0
  36. data/share/glade/config.glade +2634 -0
  37. data/share/glade/connect.glade +950 -0
  38. data/share/glade/keybindings.glade +109 -0
  39. data/share/glade/linkwindow.glade +188 -0
  40. data/share/glade/mainwindow.glade +335 -0
  41. data/share/glade/network-presences.glade +1373 -0
  42. data/share/glade/pluginconf.glade +97 -0
  43. data/share/glade/plugins.glade +360 -0
  44. data/share/plugins/colorewrite.rb +193 -0
  45. data/share/plugins/highlighter.rb +115 -0
  46. data/share/plugins/mpdplay.rb +123 -0
  47. data/share/plugins/numberswitcher.rb +30 -0
  48. data/share/plugins/sysinfo.rb +82 -0
  49. metadata +96 -0
@@ -0,0 +1,514 @@
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
+ #### bufferlistview ####
21
+ # Defines some Views for the BufferList
22
+ ####
23
+
24
+ #TODO: add a notebook style view, and an 'activity line' irssi0 style view
25
+
26
+ module Ratchet
27
+ #the base view class...
28
+ class BufferListView
29
+ attr_reader :model
30
+ def initialize(controller, model)
31
+ @controller = controller
32
+ @model = model
33
+ @filled = false
34
+ end
35
+
36
+ def filled?
37
+ @filled
38
+ end
39
+
40
+ def rightclickmenu(buffer, event)
41
+ puts buffer
42
+ menu = Gtk::Menu.new
43
+ if buffer.respond_to? :part
44
+ i = Gtk::MenuItem.new('Part')
45
+ i.signal_connect("activate"){buffer.part}
46
+ menu.append(i)
47
+ elsif buffer.respond_to? :disconnect
48
+ i = Gtk::MenuItem.new('Disconnect')
49
+ i.signal_connect("activate"){buffer.disconnect}
50
+ menu.append(i)
51
+ end
52
+ i = Gtk::MenuItem.new("Close")
53
+ i.signal_connect("activate"){@controller.close_buffer(buffer)}
54
+ menu.append(i)
55
+ menu.show_all
56
+ menu.popup(nil, nil, event.button, event.time)
57
+ end
58
+
59
+
60
+
61
+ def redraw
62
+ # puts 'redraw triggered'
63
+ clear
64
+ fill
65
+ set_active(@model.active)
66
+ end
67
+
68
+ def update_status(buffer)
69
+ recolor(buffer)
70
+ end
71
+
72
+ #stub for child classes to implement
73
+ def clear
74
+ end
75
+
76
+ #stub for child classes to implement
77
+ def fill
78
+ end
79
+
80
+ def recolor
81
+ end
82
+ end
83
+
84
+
85
+ class BoxBufferListView < BufferListView
86
+ def initialize(controller, model)
87
+ super
88
+ @buttons = {}
89
+ @config = @controller.config
90
+ @togglehandlers = {}
91
+ fill
92
+ # puts model.active
93
+ set_active(model.active)
94
+ @box.show_all
95
+ end
96
+
97
+ def widget
98
+ return @box
99
+ end
100
+
101
+ def fill
102
+ clear
103
+ @model.structure.each do |o|
104
+ if !@box.children.empty? and o.class == NetworkBuffer
105
+ add_separator
106
+ end
107
+ @box.pack_start(add_button(o), false)
108
+ end
109
+ @filled = true
110
+ end
111
+
112
+ def clear
113
+ @buttons = {}
114
+ @togglehandlers = {}
115
+ @box.children.each {|child| @box.remove(child)}
116
+ @filled = false
117
+ end
118
+
119
+ def insert(object, after)
120
+ index = nil
121
+ if after == nil or object == after
122
+ index = 0
123
+ else
124
+ @box.children.each_with_index do |c, i|
125
+ if @buttons.index(c) == after
126
+ index = i+1
127
+ end
128
+ end
129
+ end
130
+
131
+ if index
132
+ #inserting a network after 0, insert a separator before it
133
+ if object.class == NetworkBuffer and index > 0
134
+ s = add_separator
135
+ @box.reorder_child(s, index)
136
+ index +=1
137
+ end
138
+ button = add_button(object)
139
+ @box.pack_start(button, false)
140
+ @box.reorder_child(button, index)
141
+ #inserting a network at 0, add a separator after it...
142
+ if object.class == NetworkBuffer and index == 0 and @box.children.length > 1
143
+ s = add_separator
144
+ @box.reorder_child(s, index+1)
145
+ end
146
+ end
147
+ end
148
+
149
+ def remove(object)
150
+ if @buttons[object]
151
+ index = @box.children.index(@buttons[object])
152
+ @box.remove(@buttons[object])
153
+ @buttons.delete(object)
154
+ if @box.children[index-1].class.ancestors.include? Gtk::Separator
155
+ @box.remove(@box.children[index-1])
156
+ elsif @box.children[0].class.ancestors.include? Gtk::Separator
157
+ @box.remove(@box.children[0])
158
+ end
159
+ end
160
+ end
161
+
162
+ def renumber
163
+ @buttons.each do |buffer, button|
164
+ number = ''
165
+ #~ if $config['numbertabs'] and x = @model.tab2number(buffer)
166
+ #~ number = x.to_s+':'
167
+ #~ end
168
+
169
+ button.label = number+buffer.name
170
+ recolor(buffer)
171
+ end
172
+ end
173
+
174
+
175
+ def set_active(buffer)
176
+ return unless @buttons[buffer]
177
+ if @model.active and @buttons[@model.active]
178
+ @buttons[@model.active].signal_handler_block(@togglehandlers[@model.active])
179
+ @buttons[@model.active].active = false
180
+ @buttons[@model.active].signal_handler_unblock(@togglehandlers[@model.active])
181
+ end
182
+
183
+ @buttons[buffer].signal_handler_block(@togglehandlers[buffer])
184
+ @buttons[buffer].active = true
185
+ @buttons[buffer].signal_handler_unblock(@togglehandlers[buffer])
186
+ #@controller.set_active(buffer)
187
+ end
188
+
189
+ def recolor(buffer)
190
+ return unless @buttons[buffer]
191
+ label = @buttons[buffer].child
192
+ if buffer == @model.active
193
+ label.modify_fg(Gtk::STATE_NORMAL, Gdk::Color.new(*@config.getstatuscolor(0)))
194
+ label.modify_fg(Gtk::STATE_PRELIGHT, Gdk::Color.new(*@config.getstatuscolor(0)))
195
+ else
196
+ label.modify_fg(Gtk::STATE_NORMAL, Gdk::Color.new(*@config.getstatuscolor(buffer.status)))
197
+ label.modify_fg(Gtk::STATE_PRELIGHT, Gdk::Color.new(*@config.getstatuscolor(buffer.status)))
198
+ end
199
+ end
200
+
201
+ def add_button(buffer)
202
+ if !@buttons.include?(buffer)
203
+ number = ''
204
+ #~ if $config['numbertabs'] and x = @model.tab2number(buffer)
205
+ #~ number = x.to_s+':'
206
+ #~ end
207
+ button = Gtk::ToggleButton.new(number+buffer.name)
208
+
209
+ @togglehandlers[buffer] = button.signal_connect('toggled')do |w|
210
+ if buffer == @model.active
211
+ set_active(buffer)#force it active again
212
+ else
213
+ @controller.set_active(buffer)
214
+ end
215
+ end
216
+ button.signal_connect('button_press_event')do |w, event|
217
+ if event.button == 3
218
+ rightclickmenu(buffer, event)
219
+ end
220
+ end
221
+ @buttons[buffer] = button
222
+ button.show
223
+ end
224
+ return @buttons[buffer]
225
+ end
226
+
227
+ def add_separator
228
+ b = create_separator
229
+ @box.pack_start(b, false, false, 5)
230
+ b.show
231
+ return b
232
+ end
233
+ end
234
+
235
+ class VBoxBufferListView < BoxBufferListView
236
+ attr_reader :box
237
+ def initialize(controller, model)
238
+ @box = Gtk::VBox.new
239
+ super
240
+ end
241
+
242
+ def create_separator
243
+ b = Gtk::HSeparator.new
244
+ b.show
245
+ return b
246
+ end
247
+ end
248
+
249
+ class HBoxBufferListView < BoxBufferListView
250
+ attr_reader :box
251
+ def initialize(controller, model)
252
+ @box = Gtk::HBox.new
253
+ super
254
+ end
255
+
256
+ def create_separator
257
+ b = Gtk::VSeparator.new
258
+ b.show
259
+ return b
260
+ end
261
+ end
262
+
263
+ class TreeBufferListView < BufferListView
264
+ attr_reader :model, :view
265
+ def initialize(controller, model)
266
+ super
267
+ @store = Gtk::TreeStore.new(String, String)
268
+ @view = Gtk::TreeView.new(@store)
269
+ @selecthandler = @view.selection.signal_connect('changed') do |w|
270
+ @controller.set_active(iter2buffer(w.selected))
271
+ end
272
+ @iters = {}
273
+ @config = @controller.config
274
+ fill
275
+ renderer = Gtk::CellRendererText.new
276
+ col = Gtk::TreeViewColumn.new("", renderer, :text => 0)
277
+ @view.append_column(col)
278
+ col = Gtk::TreeViewColumn.new("", renderer, :markup => 1)
279
+ @view.append_column(col)
280
+ @view.set_expander_column(col)
281
+ @view.headers_visible=false
282
+ @view.enable_search = false
283
+ @view.expand_all
284
+ @frame = Gtk::Frame.new
285
+ @frame.shadow_type = Gtk::SHADOW_ETCHED_IN
286
+ @frame.add(@view)
287
+ @sw = Gtk::ScrolledWindow.new
288
+ @sw.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC)
289
+ @sw.add_with_viewport(@frame)
290
+ @sw.show_all
291
+ @view.signal_connect('focus_in_event') do |w, event|
292
+ set_active(@model.active)
293
+ end
294
+ @view.signal_connect('button_press_event') do |widget, event|
295
+ # if event.button == 3
296
+ # rightclickmenu(buffer, event)
297
+ # end
298
+ if event.button == 3
299
+ path, column, x, y = widget.get_path_at_pos(event.x, event.y)
300
+ if path
301
+ puts "path is #{path}"
302
+ # widget.set_cursor(path, nil, false)
303
+ foo = @iters.values.detect{|x| x.path.to_s == path.to_s}
304
+ puts "result #{foo}, #{@iters.index(foo)}"
305
+ buffer = @iters.index(foo)
306
+ rightclickmenu(buffer, event) if buffer
307
+ end
308
+ true
309
+ end
310
+ end
311
+ end
312
+
313
+ def widget
314
+ @sw
315
+ end
316
+
317
+ def fill
318
+ clear
319
+ @model.structure.each do |o|
320
+ if !o.respond_to? :network or o == o.network
321
+ add_iter(o)
322
+ else
323
+ add_iter(o, get_last_parent)
324
+ end
325
+ end
326
+ @filled = true
327
+ # parent = add_iter(@model.root)
328
+ # @model.tree[@model.root].each do |k, v|
329
+ # child = add_iter(k, parent)
330
+ # @view.expand_row(parent.path, false)
331
+ # recolor(k)
332
+ # if v.methods.include?('each')
333
+ # v.each do |z, c|
334
+ # child2 = add_iter(z, child)
335
+ # @view.expand_row(child.path, false)
336
+ # recolor(z)
337
+ # end
338
+ # else
339
+
340
+ # end
341
+ # end
342
+ # cleanup
343
+ end
344
+
345
+ def clear
346
+ @iters = {}
347
+ @store.clear
348
+ @filled = false
349
+ end
350
+
351
+ def insert(object, after)
352
+ # puts after
353
+ path = @iters[after].path
354
+ # puts path.depth
355
+ if !object.respond_to? :network or object == object.network
356
+ if path.depth == 1
357
+ iter = @store.insert_after(nil, @store.get_iter(path))
358
+ elsif
359
+ iter = @store.insert_after(nil, @store.get_iter(path.indices[0].to_s))
360
+ end
361
+ else
362
+ if path.depth == 1
363
+ iter = @store.insert_after(@store.get_iter(path), nil)
364
+ else
365
+ iter = @store.insert_after(@store.get_iter(path.indices[0].to_s), @store.get_iter(path))
366
+ end
367
+ end
368
+ iter[0] = ''
369
+ iter[1] = object.name
370
+ @iters[object] = Gtk::TreeRowReference.new(@store, iter.path)
371
+ # exit
372
+ end
373
+
374
+ #~ def add(item)
375
+ #~ i = 0
376
+ #~ @model.tree[@model.root].each do |k, v|
377
+ #~ path = '0:'+i.to_s
378
+ #~ this = @store.get_iter(path)
379
+ #~ if this and clean_tag(this[1]) != k.name
380
+ #~ new = @store.insert_before(@store.get_iter(@iters[@model.root].path), this)
381
+ #~ new[1] = k.name
382
+ #~ @iters[k] = Gtk::TreeRowReference.new(@store, new.path)
383
+ #~ @view.expand_row(@iters[@model.root].path, false)
384
+ #~ elsif !this
385
+ #~ new = @store.insert_before(@store.get_iter(@iters[@model.root].path), nil)
386
+ #~ new[1] = k.name
387
+ #~ @iters[k] = Gtk::TreeRowReference.new(@store, new.path)
388
+ #~ @view.expand_row(@iters[@model.root].path, false)
389
+ #~ end
390
+ #~ j = 0
391
+ #~ if v.methods.include?('each')
392
+ #~ v.each do |z, c|
393
+ #~ path2 = '0:'+i.to_s+':'+j.to_s
394
+ #~ this2 = @store.get_iter(path2)
395
+ #~ if this2 and clean_tag(this2[1]) != z.name
396
+ #~ #puts path2, z.name
397
+ #~ new = @store.insert_before(@store.get_iter(@iters[k].path), this2)
398
+ #~ new[1] = z.name
399
+ #~ @iters[z] = Gtk::TreeRowReference.new(@store, new.path)
400
+ #~ @view.expand_row(this.path, false)
401
+ #~ elsif !this2
402
+ #~ path2 = '0:'+i.to_s+':'+(j-1).to_s
403
+ #~ new = @store.insert_before(@store.get_iter(@iters[k].path), nil)
404
+ #~ new[1] = z.name
405
+ #~ @iters[z] = Gtk::TreeRowReference.new(@store, new.path)
406
+ #~ @view.expand_row(this.path, false)
407
+ #~ end
408
+ #~ j += 1
409
+ #~ end
410
+ #~ end
411
+ #~ i += 1
412
+ #~ end
413
+ #~ cleanup
414
+ #~ renumber
415
+ #~ end
416
+
417
+ #~ #ack, I wish I didn't need this
418
+ #~ def cleanup
419
+ #~ @store.each do |model, path, iter|
420
+ #~ if !iter2buffer(iter)
421
+ #~ @store.remove(iter)
422
+ #~ end
423
+ #~ end
424
+ #~ end
425
+
426
+ def remove(item)
427
+ if @iters[item] and @iters[item].valid?
428
+ @store.remove(@store.get_iter(@iters[item].path))
429
+ @iters.delete(item)
430
+ end
431
+ end
432
+
433
+ #~ def renumber
434
+ #~ @iters.each do |buffer, iter|
435
+ #~ y = @store.get_iter(iter.path)
436
+ #~ number = ''
437
+ #~ if $config['numbertabs'] and x = @model.tab2number(buffer)
438
+ #~ number = x.to_s
439
+ #~ end
440
+ #~ y[0] = number
441
+ #~ end
442
+ #~ end
443
+
444
+
445
+ def clean_tag(tag)
446
+ re = /^\<span .+\>(.+?)\<\/span\>$/i
447
+ md = re.match(tag)
448
+ if md
449
+ return md[1]
450
+ else
451
+ return tag
452
+ end
453
+ end
454
+
455
+ def add_iter(buffer, parent= nil)
456
+ iter = @store.append(parent)
457
+ number = ''
458
+ # if $config['numbertabs'] and x = @model.tab2number(buffer)
459
+ # number = x.to_s
460
+ # end
461
+ iter[0] = number
462
+ iter[1] = buffer.name
463
+ @iters[buffer] = Gtk::TreeRowReference.new(@store, iter.path)
464
+ return iter
465
+ end
466
+
467
+ def get_last_parent(pos=-1)
468
+ # @iters.values.sort_by.sort_by{|x| [x.split(':')[0].to_i*-1, x.path.length]}[0].path.split(':')[0]
469
+ puts @iters.values.inspect
470
+ root = @iters.values.map{|x| x.path.to_s.split(':')[0]}.sort[pos]
471
+ @store.get_iter(root)
472
+ end
473
+
474
+ def iter2buffer(iter)
475
+ return nil unless iter
476
+ @iters.each do |b, i|
477
+ if i.valid? and (i.path.to_s) == (iter.path.to_s)
478
+ return b
479
+ end
480
+ end
481
+ return nil
482
+ end
483
+
484
+ def set_active(buffer)
485
+ if buffer
486
+ if @active
487
+ oldactive = @active
488
+ end
489
+ # setstatus(buffer, ACTIVE)
490
+ @active = buffer
491
+ # setstatus(oldactive, INACTIVE) if oldactive
492
+
493
+ @view.selection.signal_handler_block(@selecthandler)
494
+ @view.selection.select_iter(@store.get_iter(@iters[buffer].path)) if @iters[buffer]
495
+ @view.selection.signal_handler_unblock(@selecthandler)
496
+ recolor(buffer)
497
+ # $main.window.switchchannel(buffer) if $main.window
498
+ end
499
+ end
500
+
501
+ def recolor(buffer)
502
+ if @iters[buffer] and @iters[buffer].valid?
503
+ iter = @store.get_iter(@iters[buffer].path)
504
+ if @model.active == buffer
505
+ iter[1] = clean_tag(iter[1])
506
+ else
507
+ color = @config.getstatuscolor(buffer.status).to_hex
508
+ iter[1] = '<span color="'+color+'">'+clean_tag(iter[1])+'</span>'
509
+ #puts 'recoloring '+buffer.name
510
+ end
511
+ end
512
+ end
513
+ end
514
+ end