arcadia 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,92 @@
1
+ name=editor
2
+ label=Editor
3
+ frame=0.1
4
+ active=yes
5
+ require=ext/ae-editor/ae-editor
6
+ class=AgMultiEditor
7
+
8
+ tab-chars=0.5c
9
+ tab-replace-width-space=2
10
+ find.frame=0.0
11
+ #tabs
12
+ tabs.font=courier 9
13
+ i386-freebsd6:tabs.font=courier 12
14
+ i386-mswin32:tabs.font={Courier New} 9
15
+ #tabs.side=bottom
16
+ tabs.side=top
17
+ # editor
18
+ font=courier 9
19
+ font.bold=courier 9 bold
20
+ i386-freebsd6:font=courier 12
21
+ i386-freebsd6:font.bold=courier 12 bold
22
+ i386-mswin32:font={Courier New} 9
23
+ i386-mswin32:font.bold={Courier New} 9 bold
24
+ #+--------------------------------------------------
25
+ #color.background=#000040
26
+ #color.foreground=white
27
+ #color.insertbackground=#ff8000
28
+ #hightlight.keyword.color.foreground=#800000
29
+ #hightlight.variable.color.foreground=#f9c6f8
30
+ #hightlight.comment.color.foreground=#4aff4a
31
+ #hightlight.string.color.foreground=#8080ff
32
+ #hightlight.number.color.foreground=red
33
+ #hightlight.capitalize.color.foreground=#ffff00
34
+ #hightlight.select.color.foreground=yellow
35
+ #hightlight.select.color.background=blue
36
+ #hightlight.goto.color.foreground=blue
37
+ #hightlight.goto.color.background=yellow
38
+ #+--------------------------------------------------
39
+ #+--------------------------------------------------
40
+ color.background=#FFFFFF
41
+ color.foreground=#7F7F7F
42
+ color.insertbackground=#ff8000
43
+ hightlight.keyword.color.foreground=#00007F
44
+ hightlight.keyword.style=bold
45
+ hightlight.method_name.color.foreground=#007F7F
46
+ hightlight.method_name.style=bold
47
+ hightlight.class_name.color.foreground=#0000FF
48
+ hightlight.class_name.style=bold
49
+ hightlight.module_name.color.foreground=#0000FF
50
+ hightlight.module_name.style=bold
51
+ hightlight.instance_variable.color.foreground=#7F7F7F
52
+ hightlight.instance_variable.style=bold
53
+ hightlight.comment.color.foreground=#007F00
54
+ hightlight.string.color.foreground=#7F007F
55
+ hightlight.number.color.foreground=#007F7F
56
+ #hightlight.capitalize.color.foreground=#0000FF
57
+ hightlight.operator.color.foreground=#000000
58
+ hightlight.operator.style=bold
59
+ #hightlight.sel.color.foreground=yellow
60
+ hightlight.sel.color.background=#cccccc
61
+ hightlight.sel.borderwidth=1
62
+ hightlight.sel.relief=raised
63
+ #hightlight.goto.color.foreground=blue
64
+ hightlight.selected.color.background=yellow
65
+ #+--------------------------------------------------
66
+
67
+
68
+ # line number
69
+ #line_number_panel.color.background=#6e6e6e
70
+ #line_number_panel.color.foreground=white
71
+
72
+ line_number_panel.color.background=#e1e1e1
73
+ line_number_panel.color.foreground=#333333
74
+
75
+
76
+ # tree explorer
77
+ explorer_panel.tree.color.background=#ffffff
78
+ explorer_panel.tree.color.foreground=white
79
+ explorer_panel.tree.font=courier 9
80
+ i386-freebsd6:explorer_panel.tree.font=courier 12
81
+ i386-mswin32:explorer_panel.tree.font={Courier New} 9
82
+ explorer_panel.tree.class.color.foreground=#a42019
83
+ explorer_panel.tree.class.font=times 10 bold
84
+ i386-mswin32:explorer_panel.tree.class.font=times 10 bold
85
+ explorer_panel.tree.def.color.foreground=blue
86
+ explorer_panel.tree.def.font=times 10
87
+ i386-mswin32:explorer_panel.tree.def.font=times 10
88
+ explorer_panel.tree.module.color.foreground=#1b691e
89
+ explorer_panel.tree.module.font=times 8 bold
90
+ i386-mswin32:explorer_panel.tree.module.font={Courier New} 9 bold
91
+
92
+ #:::::::::::::::: Editor group ::::::::::::::::::::::<end>
@@ -0,0 +1,1744 @@
1
+ #
2
+ # ae-editor.rb - Arcadia Ruby ide
3
+ # by Antonio Galeone <antonio-galeone@rubyforge.org>
4
+ #
5
+
6
+ require 'tk'
7
+ require 'tktext'
8
+ require 'base/a-utils'
9
+
10
+
11
+ class TreeNode
12
+ attr_reader :sons
13
+ attr_reader :parent
14
+ attr_reader :kind
15
+ attr_reader :rif, :label, :helptext
16
+ attr_writer :rif, :label, :helptext
17
+ def initialize(parent=nil, kind='KClass')
18
+ @sons = Array.new
19
+ @parent = parent
20
+ @kind = kind
21
+ if @parent !=nil
22
+ @parent.sons << self
23
+ end
24
+ yield(self) if block_given?
25
+ end
26
+
27
+ def <=> (other)
28
+ self.label.strip <=> other.label.strip
29
+ end
30
+ end
31
+
32
+ class AgEditor
33
+ attr_reader :file
34
+ attr_reader :page_frame
35
+ attr_reader :text, :root
36
+ def initialize(_controller, _page_frame)
37
+ @controller = _controller
38
+ @page_frame = _page_frame
39
+ @set_mod = false
40
+ # @fm = AGTkVSplittedFrames.new(@page_frame,150)
41
+ # @fm1 = AGTkVSplittedFrames.new(@fm.right_frame,60)
42
+ @font = @controller.conf('font')
43
+ @font_bold = @controller.conf('font.bold')
44
+ @font_metrics = TkFont.new(@font).metrics
45
+ @font_metrics_bold = TkFont.new(@font_bold).metrics
46
+ # initialize_text
47
+ # initialize_text_binding
48
+ # initialize_highlight
49
+ # initialize_line_number
50
+ # initialize_tree
51
+ @highlighting = false
52
+ @classbrowsing = false
53
+ @find = @controller.get_find
54
+ end
55
+
56
+ def initialize_tree(_frame)
57
+ @classbrowsing = true
58
+ @nb = Tk::BWidget::NoteBook.new(_frame){
59
+ tabbevelsize 0
60
+ internalborderwidth 0
61
+ activeforeground 'red'
62
+ activebackground 'yellow'
63
+ borderwidth 1
64
+ side $arcadia['conf']['editor.tabs.side']
65
+ font $arcadia['conf']['editor.tabs.font']
66
+ pack('fill'=>'both', :padx=>0, :pady=>0, :expand => 'yes')
67
+ }
68
+ @nb_tab_exp = @nb.insert('end','exp' ,'text'=>'Class Tree' )
69
+ @nb.raise('exp')
70
+ _tree_goto = proc{|_self|
71
+ _line = _self.selection_get[0]
72
+ _index =_line.to_s+'.0'
73
+ _hinner_text = @tree_exp.itemcget(_line,'text').strip
74
+ _editor_line = @text.get(_index, _index+ ' lineend')
75
+ if !_editor_line.include?(_hinner_text)
76
+ MsgContract.instance.out_simple(self, "... rebuild tree \n")
77
+ if @tree_thread && @tree_thread.alive?
78
+ @tree_thread.exit
79
+ end
80
+ @tree_thread = Thread.new{
81
+ build_tree(_line)
82
+ Tk.update
83
+ }
84
+ _line = _self.selection_get[0]
85
+ _index =_line.to_s+'.0'
86
+ end
87
+ @text.see(_index)
88
+ @text.tag_remove('selected','1.0','end')
89
+ @text.tag_add('selected',_line.to_s+'.0',(_line+1).to_s+'.0')
90
+ }
91
+ @tree_exp = Tk::BWidget::Tree.new(@nb_tab_exp){
92
+ background '#FFFFFF'
93
+ relief 'flat'
94
+ showlines false
95
+ deltay 18
96
+ dragenabled true
97
+ selectcommand proc{ _tree_goto.call(self) }
98
+ place('relwidth' => 1,'relx' => 0,'x' => '0','y' => '0','relheight' => '1','rely' => 0,'height' => 1,'bordermode' => 'inside','width' => '50')
99
+ }
100
+ @nodes = Array.new
101
+ _c_explo = proc{|*args| @tree_exp.yview(*args)}
102
+ _s_explo = TkScrollbar.new(@nb_tab_exp){|s|
103
+ width 8
104
+ command _c_explo
105
+ }.pack('side'=>'right', 'fill'=>'y')
106
+ @tree_exp.yscrollcommand proc{|first,last| _s_explo.set first,last}
107
+
108
+ end
109
+
110
+ def initialize_text(_frame)
111
+ @v_scroll = TkScrollbar.new(_frame,
112
+ 'orient'=>'vertical',
113
+ 'relief'=>'flat'
114
+ ).pack('side' => 'right', 'fill' => 'y')
115
+ @text = TkText.new(@fm1.right_frame){|j|
116
+ wrap 'none'
117
+ relief 'flat'
118
+ undo true
119
+ insertofftime 200
120
+ insertontime 200
121
+ insertbackground $arcadia['conf']['editor.color.insertbackground']
122
+ background $arcadia['conf']['editor.color.background']
123
+ foreground $arcadia['conf']['editor.color.foreground']
124
+ insertwidth 3
125
+ exportselection true
126
+ autoseparators true
127
+ padx 0
128
+ tabs $arcadia['conf']['editor.tab-chars']
129
+ place(
130
+ 'x'=>0,
131
+ 'y'=>0,
132
+ 'width' => -15,
133
+ 'relheight'=>1,
134
+ 'relwidth'=>1,
135
+ 'bordermode'=>'outside'
136
+ )
137
+ }
138
+ @text.configure('font', @font);
139
+
140
+ @text.tag_configure('eval','foreground' => 'yellow', 'background' =>'red','borderwidth'=>1, 'relief'=>'raised')
141
+ @text.tag_configure('errline','borderwidth'=>1, 'relief'=>'groove')
142
+ @text.tag_configure('debug', 'background' =>'#b9c6d9', 'borderwidth'=>1 ,'relief'=>'raise')
143
+ @buffer = text_value
144
+ pop_up_menu
145
+ end
146
+
147
+ def initialize_text_binding
148
+ @v_scroll.command(proc{|*args|
149
+ @text.yview *args
150
+ })
151
+ @text.yscrollcommand(proc{|first,last| @v_scroll.set(first,last)
152
+ self.do_line_update()
153
+ })
154
+ @text.tag_bind('selected', 'Enter', proc{@text.tag_remove('selected','1.0','end')})
155
+
156
+ @text.bind("Enter", proc{check_file_last_access_time})
157
+ @text.bind("ButtonPress-1", proc{
158
+ _code = $arcadia['palette'].give_me_code
159
+ @text.insert('insert', _code) if _code
160
+ })
161
+
162
+ @text.bind("Control-KeyPress"){|e|
163
+ case e.keysym
164
+ when 'z'
165
+ _b = @text.index('insert').split('.')[0].to_i
166
+ @text.edit_undo
167
+ _e = @text.index('insert').split('.')[0].to_i
168
+ if @highlighting
169
+ for j in _b..._e
170
+ rehighlightline(j)
171
+ end
172
+ end
173
+ break
174
+ when 'c'
175
+ @text.text_copy
176
+ break
177
+ when 'x'
178
+ @text.text_cut
179
+ break
180
+ when 'v'
181
+ _b = @text.index('insert').split('.')[0].to_i
182
+ @text.text_paste
183
+ _e = @text.index('insert').split('.')[0].to_i
184
+ if @highlighting
185
+ for j in _b..._e
186
+ rehighlightline(j)
187
+ end
188
+ end
189
+ break
190
+ end
191
+ case e.keysym
192
+ when 's'
193
+ save
194
+ when 'f'
195
+ _r = @text.tag_ranges('sel')
196
+ if _r.length>0
197
+ _text=@text.get(_r[0][0],_r[0][1])
198
+ if _text.length > 0
199
+ @find.e_what.text(_text)
200
+ end
201
+ else
202
+ end
203
+ @find.use(self)
204
+ @find.e_what.focus
205
+ when 'egrave'
206
+ @text.insert('insert',"{")
207
+ when 'plus'
208
+ @text.insert('insert',"}")
209
+ end
210
+ }
211
+
212
+ @text.bind("Control-Shift-KeyPress"){|e|
213
+ case e.keysym
214
+ when 'I'
215
+ _r = @text.tag_ranges('sel')
216
+ _row_begin = _r[0][0].split('.')[0].to_i
217
+ _row_end = _r[_r.length - 1][1].split('.')[0].to_i
218
+
219
+ for _row in _row_begin..._row_end
220
+ @text.insert(_row.to_s+'.0',"\s\s")
221
+ end
222
+ when 'U'
223
+ _r = @text.tag_ranges('sel')
224
+ _row_begin = _r[0][0].split('.')[0].to_i
225
+ _row_end = _r[_r.length - 1][1].split('.')[0].to_i
226
+
227
+ for _row in _row_begin..._row_end
228
+ if @text.get(_row.to_s+'.0',_row.to_s+'.2') == "\s\s"
229
+ @text.delete(_row.to_s+'.0',_row.to_s+'.2')
230
+ end
231
+ end
232
+ when 'C'
233
+ _r = @text.tag_ranges('sel')
234
+ _row_begin = _r[0][0].split('.')[0].to_i
235
+ _row_end = _r[_r.length - 1][1].split('.')[0].to_i
236
+
237
+ for _row in _row_begin..._row_end
238
+ if @text.get(_row.to_s+'.0',_row.to_s+'.1') == "#"
239
+ @text.delete(_row.to_s+'.0',_row.to_s+'.1')
240
+ else
241
+ @text.insert(_row.to_s+'.0',"#")
242
+ end
243
+ rehighlightline(_row) if @highlighting
244
+ end
245
+
246
+ end
247
+ }
248
+ @text.bind("KeyPress"){|e|
249
+ case e.keysym
250
+ when 'BackSpace'
251
+ _index = @text.index('insert')
252
+ _row, _col = _index.split('.')
253
+ rehighlightline(_row.to_i) if @highlighting
254
+ when 'Delete'
255
+ _index = @text.index('insert')
256
+ _row, _col = _index.split('.')
257
+ rehighlightline(_row.to_i) if @highlighting
258
+ when 'F5'
259
+ save
260
+ $arcadia['shell'].run(@file.to_s)
261
+ when 'F3'
262
+ @find.do_find_next
263
+ when 'Tab'
264
+ _r = @text.tag_ranges('sel')
265
+ if _r && _r[0]
266
+ _row_begin = _r[0][0].split('.')[0].to_i
267
+ _row_end = _r[_r.length - 1][1].split('.')[0].to_i
268
+ n_space = $arcadia['conf']['editor.tab-replace-width-space'].to_i
269
+ if n_space > 0
270
+ suf = "\s"*n_space
271
+ else
272
+ suf = "\t"
273
+ end
274
+ for _row in _row_begin..._row_end
275
+ @text.insert(_row.to_s+'.0', suf)
276
+ end
277
+ break
278
+ end
279
+ end
280
+ }
281
+
282
+ @text.bind("Shift-KeyPress"){|e|
283
+ case e.keysym
284
+ when 'Tab'
285
+ _r = @text.tag_ranges('sel')
286
+ if _r && _r[0]
287
+ _row_begin = _r[0][0].split('.')[0].to_i
288
+ _row_end = _r[_r.length - 1][1].split('.')[0].to_i
289
+
290
+ n_space = $arcadia['conf']['editor.tab-replace-width-space'].to_i
291
+ if n_space > 0
292
+ suf = "\s"*n_space
293
+ else
294
+ suf = "\t"
295
+ n_space = 1
296
+ end
297
+ for _row in _row_begin..._row_end
298
+ if @text.get(_row.to_s+'.0',_row.to_s+'.'+n_space.to_s) == suf
299
+ @text.delete(_row.to_s+'.0',_row.to_s+'.'+n_space.to_s)
300
+ end
301
+ end
302
+ break
303
+ end
304
+ end
305
+ }
306
+
307
+ @text.bind("KeyRelease"){|e|
308
+ case e.keysym
309
+ when 'Control_L','Return', 'Control_V', 'BackSpace', 'Delete'
310
+ if modified?
311
+ set_modify
312
+ else
313
+ reset_modify
314
+ end
315
+ do_line_update
316
+ when 'Right','Left','Down', 'Up'
317
+ # do nil
318
+ else
319
+ if modified?
320
+ if !@set_mod
321
+ set_modify
322
+ end
323
+ else
324
+ reset_modify
325
+ end
326
+ end
327
+ case e.keysym
328
+ when 'Return'
329
+ _index = @text.index('insert')
330
+ _row, _col = _index.split('.')
331
+ _txt = @text.get((_row.to_i-1).to_s+'.0',_index)
332
+ if _txt.length > 0
333
+ m = /\s*/.match(_txt)
334
+ if m
335
+ if (m[0] != "\n")
336
+ _sm = m[0]
337
+ _sm = _sm.sub(/\n/,"")
338
+ @text.insert('insert',_sm)
339
+ end
340
+ end
341
+ end
342
+ if _row.to_i + 1 == @text.index('end').split('.')[0].to_i
343
+ do_line_update
344
+ end
345
+ else
346
+ if @highlighting && /\w/.match(e.keysym)
347
+ rehighlightline(@text.index('insert').split('.')[0].to_i)
348
+ end
349
+ end
350
+ }
351
+
352
+
353
+ end
354
+
355
+ def initialize_line_number(_frame)
356
+ @text_line_num = TkText.new(_frame){
357
+ wrap 'none'
358
+ relief 'flat'
359
+ undo false
360
+ takefocus 0
361
+ insertofftime 0
362
+ exportselection true
363
+ autoseparators true
364
+ background $arcadia['conf']['editor.line_number_panel.color.background']
365
+ foreground $arcadia['conf']['editor.line_number_panel.color.foreground']
366
+ place(
367
+ 'x'=>0,
368
+ 'y'=>0,
369
+ 'relheight'=>1,
370
+ 'relwidth'=>1,
371
+ 'bordermode'=>'outside'
372
+ )
373
+ }
374
+ delta = @font_metrics_bold[2][1]-@font_metrics[2][1]
375
+ @text_line_num.tag_configure('bold_case', 'spacing1'=>delta)
376
+ @text_line_num.tag_configure('breakpoint', 'background'=>'red','borderwidth'=>1, 'relief'=>'raised')
377
+ @text_line_num.bind("Double-ButtonPress-1", proc{
378
+ _index = @text_line_num.index('insert')
379
+ _line = @text_line_num.get(_index+' linestart',_index+' lineend').strip
380
+ if @controller.breakpoint_lines_on_file(@file).include?(_line)
381
+ @text_line_num.tag_remove('breakpoint',_index+' linestart',_index+' lineend')
382
+ @controller.breakpoint_del(@file, _line)
383
+ else
384
+ @text_line_num.tag_add('breakpoint',_index+' linestart',_index+' linestart + 1 chars')
385
+ @controller.breakpoint_add(@file, _line)
386
+ end
387
+ })
388
+ @text_line_num.configure('font', @font);
389
+ @text_line_num.tag_configure('line_num',
390
+ 'foreground' => '#FFFFFF',
391
+ 'background' =>'#0000a0',
392
+ 'borderwidth'=>2,
393
+ 'relief'=>'raised'
394
+ )
395
+ end
396
+
397
+ def initialize_highlight
398
+ @highlighting = true
399
+ @highlight_zone = Hash.new;
400
+ # @highlight_zone_length = 45;
401
+ @highlight_zone_length = 8;
402
+ @last_line_begin = 0
403
+ @last_line_end = 0
404
+ @last_zone_begin=0;
405
+ @last_zone_end=0;
406
+ @is_line_bold = Hash.new
407
+ @is_tag_bold = Hash.new
408
+
409
+ @keyword = ['__FILE__', 'and', 'def', 'end', 'in', 'or', 'self', 'unless',
410
+ '__LINE__', 'begin', 'defined?', 'ensure', 'module', 'redo', 'super', 'until',
411
+ 'BEGIN', 'break', 'do', 'false', 'next', 'rescue', 'then', 'when',
412
+ 'END', 'case', 'else', 'for', 'nil', 'retry', 'true', 'while',
413
+ 'alias', 'class', 'elsif', 'if', 'not', 'return', 'undef', 'yield','require']
414
+ _re_string = ''
415
+ @keyword.each{|word|
416
+ if _re_string.length > 0
417
+ _re_string << '|'
418
+ end
419
+ if ['class','module','def'].include?(word)
420
+ _re_string << '([\s]*'+word+'[\s])'
421
+ else
422
+ _re_string << '\b('+word+')([.,+\(\s])'
423
+ end
424
+ }
425
+ @re_keyword = Regexp::new(_re_string)
426
+ @re_instance_variable = /([\s]*@)[A-Za-z0-9_]*/
427
+ @re_string = /'([\/A-Za-z0-9_@+\-!?=<>\[\]\{\}\(\).\s]*)'|"([\/A-Za-z0-9_@+\-!?=<>\[\]\{\}\(\).\s]*)"/
428
+ @re_number = /\d/
429
+ @re_operator = /[\(\)\[\]\(\)\{\}.:;,=><|]/
430
+ @re_method_name = /(def[\s][\s]*)[A-Za-z0-9_]*/
431
+ @re_class_name = /(class[\s][\s]*)[A-Za-z0-9_]*/
432
+ @re_module_name = /(module[\s][\s]*)[A-Za-z0-9_]*/
433
+ do_tag_configure('keyword')
434
+ do_tag_configure('method_name')
435
+ do_tag_configure('instance_variable')
436
+ do_tag_configure('class_name')
437
+ do_tag_configure('module_name')
438
+ do_tag_configure('comment')
439
+ do_tag_configure('string')
440
+ do_tag_configure('number')
441
+ do_tag_configure('sel')
442
+ do_tag_configure('selected')
443
+ do_tag_configure('operator')
444
+
445
+ end
446
+
447
+ def do_tag_configure(_name)
448
+ h = Hash.new
449
+ if $arcadia['conf']['editor.hightlight.'+_name+'.color.foreground']
450
+ h['foreground']=$arcadia['conf']['editor.hightlight.'+_name+'.color.foreground']
451
+ end
452
+ if $arcadia['conf']['editor.hightlight.'+_name+'.color.background']
453
+ h['background']=$arcadia['conf']['editor.hightlight.'+_name+'.color.background']
454
+ end
455
+ if $arcadia['conf']['editor.hightlight.'+_name+'.style']== 'bold'
456
+ h['font']=@font_bold
457
+ @is_tag_bold[_name]= true
458
+ end
459
+ if $arcadia['conf']['editor.hightlight.'+_name+'.relief']
460
+ h['relief']=$arcadia['conf']['editor.hightlight.'+_name+'.relief']
461
+ end
462
+ if $arcadia['conf']['editor.hightlight.'+_name+'.borderwidth']
463
+ h['borderwidth']=$arcadia['conf']['editor.hightlight.'+_name+'.borderwidth']
464
+ end
465
+ @text.tag_configure(_name, h)
466
+ end
467
+
468
+ def pop_up_menu
469
+ @pop_up = TkMenu.new(
470
+ :parent=>@text,
471
+ :tearoff=>1,
472
+ :title => 'Menu'
473
+ )
474
+ @pop_up.insert('end',
475
+ :command,
476
+ :label=>'Save as',
477
+ :hidemargin => false,
478
+ :command=> proc{save_as}
479
+ )
480
+ @pop_up.insert('end',
481
+ :command,
482
+ :label=>'Save',
483
+ :hidemargin => false,
484
+ :command=> proc{save}
485
+ )
486
+ # @pop_up.insert('end',
487
+ # :command,
488
+ # :label=>'New',
489
+ # :hidemargin => false,
490
+ # :command=> proc{@controller.open_buffer()}
491
+ # )
492
+ # @pop_up.insert('end',
493
+ # :command,
494
+ # :label=>'Open',
495
+ # :hidemargin => false,
496
+ # :command=> proc{ @controller.open_file(Tk.getOpenFile)}
497
+ # )
498
+ # @pop_up.insert('end',
499
+ # :command,
500
+ # :label=>'Close',
501
+ # :hidemargin => false,
502
+ # :command=> proc{
503
+ # @controller.close_editor(self)
504
+ # }
505
+ # )
506
+
507
+ @pop_up.insert('end',
508
+ :command,
509
+ :label=>'Color',
510
+ :hidemargin => false,
511
+ :command=> proc{
512
+ @text.insert('insert',Tk.chooseColor)
513
+ }
514
+ )
515
+ @pop_up.insert('end',
516
+ :command,
517
+ :label=>'Font',
518
+ :hidemargin => false,
519
+ :command=> proc{
520
+ @text.insert('insert', $arcadia['action.get.font'].call)
521
+ }
522
+ )
523
+ # @pop_up.insert('end',
524
+ # :command,
525
+ # :label=>'Eval Toplevel',
526
+ # :hidemargin => false,
527
+ # :command=> proc{
528
+ # _r = @text.tag_ranges('sel')
529
+ # _ibegin = _r[_r.length - 1][0]
530
+ # _iend = _r[_r.length - 1][1]
531
+ # _cod = @text.get(_ibegin, _iend)
532
+ # Revparsel.new(_cod, @file)
533
+ # @text.tag_add('eval',_ibegin, _iend)
534
+ # _reset = proc{
535
+ # _message = 'Replace code with new '+$arcadia['objic'].active.agobj_start.i_name+'?'
536
+ # _r = TkDialog2.new('message'=>_message, 'buttons'=>['Yes','No','Cancel']).show()
537
+ # if _r == '0'
538
+ # @text.tag_remove('eval',_ibegin, _iend)
539
+ # @text.delete(_ibegin, _iend)
540
+ # text_insert(_ibegin,$arcadia['objic'].active.objects2code.to_s){_edit_reset=false}
541
+ # @text.tag_remove('sel','1.0', 'end')
542
+ # $arcadia['objic'].del($arcadia['objic'].active)
543
+ # end
544
+ # }
545
+ # @text.tag_bind('eval',"Double-ButtonPress-1",_reset)
546
+ # }
547
+ # )
548
+ @text.bind("Button-3",
549
+ proc{|x,y|
550
+ _x = TkWinfo.pointerx(@text)
551
+ _y = TkWinfo.pointery(@text)
552
+ @pop_up.popup(_x,_y)
553
+ },
554
+ "%x %y")
555
+ end
556
+
557
+ def unmark_debug(_index)
558
+ @text.tag_remove('debug',_index+' linestart', _index+' lineend')
559
+ end
560
+
561
+ def mark_debug(_index)
562
+ #@text.tag_add('debug',_index +' linestart', _index +' +1 lines linestart')
563
+ @text.tag_add('debug',_index +' linestart', _index +' lineend')
564
+ end
565
+
566
+ def mark_selected(_index)
567
+ @text.tag_remove('selected','1.0', 'end')
568
+ @text.tag_add('selected',_index +' linestart', _index +' +1 lines linestart')
569
+ end
570
+
571
+
572
+ def build_tree_from_source(_source)
573
+ _row = 1
574
+ _liv = 0
575
+ _livs = Array.new
576
+ root = TreeNode.new(nil, 'KRoot'){|_node|
577
+ _node.rif= 'root'
578
+ _node.label=''
579
+ }
580
+ _livs[_liv]=root
581
+ _source.each_line{|line|
582
+ line = "\s"+line.split("#")[0]+"\s"
583
+ m = /[\s\n\t\;]+(module|class|def|if|unless|begin|case|for|while|do)[\s\n\t\;]+/.match(line)
584
+ if m
585
+ index = m.post_match.strip.length - 1
586
+ if m.post_match.strip[index,index]=='{'
587
+ _row = _row +1
588
+ next
589
+ end
590
+ _liv>=0? _liv = _liv + 1:_liv=1
591
+ _pliv = _liv
592
+ _parent = nil
593
+ while (_parent == nil && _pliv>=0)
594
+ _pliv = _pliv -1
595
+ _parent = _livs[_pliv]
596
+ end
597
+ if _parent
598
+ _helptext = m.post_match.strip
599
+ _label = _helptext.split('<')[0]
600
+ if _label == nil || _label.strip.length==0
601
+ _label = _helptext
602
+ end
603
+ if (m[0].strip[0..4] == "class" && m.pre_match.strip.length==0)
604
+ _kind = 'KClass'
605
+ elsif (m[0].strip[0..4] == "class" && m.pre_match.strip.length>0)
606
+ _row = _row +1
607
+ _liv = _liv - 1
608
+ next
609
+ elsif (m[0].strip[0..5] == "module" && m.pre_match.strip.length==0)
610
+ _kind = 'KModule'
611
+ elsif (m[0].strip[0..5] == "module" && m.pre_match.strip.length>0)
612
+ _row = _row +1
613
+ _liv = _liv - 1
614
+ next
615
+ elsif ((m[0].strip[0..4] == "begin")||(m[0].strip[0..3] == "case") ||(m[0].strip[0..4] == "while") || (m[0].strip[0..2] == "for") || (m[0].strip[0..1] == "do") || ((m[0].strip[0..1] == "if" || m[0].strip[0..5] == "unless") && m.pre_match.strip.length==0))
616
+ _row = _row +1
617
+ next
618
+ elsif ((m[0].strip[0..1] == "if" || m[0].strip[0..5] == "unless") && m.pre_match.strip.length>0)
619
+ _row = _row +1
620
+ _liv = _liv - 1
621
+ next
622
+ elsif (m[0].strip[0..2] == "def" && m.pre_match.strip.length==0)
623
+ _kind = 'KDef'
624
+ if _label.include?(_parent.label + '.')
625
+ _kind = 'KDefClass'
626
+ end
627
+ # elsif (m[0].strip[0..10] == "attr_reader" && m.pre_match.strip.length==0)
628
+ # _kind = 'KAttr_reader'
629
+ # _liv = _liv - 1
630
+ # _row = _row +1
631
+ end
632
+
633
+ @nodes << _row.to_s
634
+ TreeNode.new(_parent, _kind){|_node|
635
+ _node.label = _label
636
+ _node.helptext = _helptext
637
+ _node.rif = _row.to_s
638
+ _livs[_pliv + 1]=_node
639
+ }
640
+ else
641
+ _row = _row +1
642
+ _liv = _liv - 1
643
+ next
644
+ end
645
+ end
646
+ m_end = /[\s\n\t\;]+end[\s\n\t\;]+/.match(line)
647
+ if m_end
648
+ _liv = _liv - 1
649
+ end
650
+ _row = _row +1
651
+ }
652
+ return root
653
+ end
654
+
655
+ def build_tree_from_node(_node, _label_match=nil)
656
+ _sorted_sons = _node.sons.sort
657
+ for inode in 0.._sorted_sons.length - 1
658
+ _son = _sorted_sons[inode]
659
+ if _son.kind == 'KClass'
660
+ _window = TkLabel.new(@tree_exp){
661
+ image TkPhotoImage.new('dat' => TREE_NODE_CLASS_GIF)
662
+ background($arcadia['conf']['editor.explorer_panel.tree.color.background'])
663
+ }
664
+ elsif _son.kind == 'KModule'
665
+ _window = TkLabel.new(@tree_exp){
666
+ image TkPhotoImage.new('dat' => TREE_NODE_MODULE_GIF)
667
+ background($arcadia['conf']['editor.explorer_panel.tree.color.background'])
668
+ }
669
+ elsif _son.kind == 'KDef'
670
+ _window = TkLabel.new(@tree_exp){
671
+ image TkPhotoImage.new('dat' => TREE_NODE_DEF_GIF)
672
+ background($arcadia['conf']['editor.explorer_panel.tree.color.background'])
673
+ }
674
+ elsif _son.kind == 'KDefClass'
675
+ _window = TkLabel.new(@tree_exp){
676
+ image TkPhotoImage.new('dat' => TREE_NODE_DEFCLASS_GIF)
677
+ background($arcadia['conf']['editor.explorer_panel.tree.color.background'])
678
+ }
679
+ end
680
+ @tree_exp.insert('end', _son.parent.rif ,_son.rif, {
681
+ 'text' => _son.label ,
682
+ 'helptext' => _son.helptext,
683
+ 'font'=>$arcadia['conf']['editor.explorer_panel.tree.font'],
684
+ 'window'=> _window
685
+ }
686
+ )
687
+ @nodes << _son.rif
688
+ if (_label_match) && (_label_match.strip == _son.label.strip)
689
+ @selected = _son
690
+ end
691
+ build_tree_from_node(_son, _label_match)
692
+ end
693
+ end
694
+
695
+ def build_tree(_sel=nil)
696
+ if _sel
697
+ _label_sel = @tree_exp.itemcget(_sel,'text')
698
+ end
699
+ #clear tree
700
+ @tree_exp.delete(@nodes)
701
+ @nodes.clear
702
+ #(re)build tree
703
+ _txt = @text.get('1.0','end')
704
+ @root = build_tree_from_source(_txt)
705
+ @selected = nil
706
+ build_tree_from_node(@root, _label_sel)
707
+ if @selected
708
+ @tree_exp.selection_add(@selected.rif)
709
+ end
710
+ end
711
+
712
+ def insert_popup_menu_item(_where, *args)
713
+ @pop_up.insert(_where,*args)
714
+ end
715
+
716
+ def text_value
717
+ return @text.value
718
+ end
719
+
720
+ # vertical scrollbar : ON/OFF
721
+ def vscroll(mode)
722
+ st = TkGrid.info(@v_scroll)
723
+ if mode && st == [] then
724
+ @v_scroll.grid('row'=>0, 'column'=>1, 'sticky'=>'ns')
725
+ elsif !mode && st != [] then
726
+ @v_scroll.ungrid
727
+ end
728
+ self
729
+ end
730
+
731
+ # horizontal scrollbar : ON/OFF
732
+ def hscroll(mode, wrap_mode="char")
733
+ st = TkGrid.info(@h_scroll)
734
+ if mode && st == [] then
735
+ @h_scroll.grid('row'=>1, 'column'=>0, 'sticky'=>'ew')
736
+ @text.configure('wrap'=> 'none')
737
+ elsif !mode && st != [] then
738
+ @h_scroll.ungrid
739
+ @text.configure('wrap'=> wrap_mode)
740
+ end
741
+ self
742
+ end
743
+
744
+ def rowcol(_index, _gap_row = nil, _gap_col = nil)
745
+ _riga, _colonna = _index.split('.')
746
+ if _gap_row == nil
747
+ _riga = '1'
748
+ _gap_row = 0
749
+ end
750
+ if _gap_col == nil
751
+ _colonna = '0'
752
+ _gap_col = 0
753
+ end
754
+ return (_riga.to_i + _gap_row).to_s + '.'+ (_colonna.to_i + _gap_col).to_s
755
+ end
756
+
757
+ def find_and_set_tag(_re, _row, _txt, _tag, _tag_rem = nil)
758
+ m = _re.match(_txt)
759
+ _end = 0
760
+ if m && @is_tag_bold[_tag]
761
+ @is_line_bold[_row]=true
762
+ end
763
+ while m
764
+ _txt = m.post_match
765
+ _ibegin = _row.to_s+'.'+(m.begin(0)+_end).to_s
766
+ _end = m.end(0) + _end
767
+ _iend = _row.to_s+'.'+(_end.to_s)
768
+ if _tag_rem
769
+ _tag_rem.each {|value|
770
+ @text.tag_remove(value,_ibegin, _iend)
771
+ }
772
+ end
773
+ @text.tag_add(_tag,_ibegin, _iend)
774
+ m = _re.match(_txt)
775
+ end
776
+ end
777
+
778
+ # def find_next_and_set_tag(_re, _row, _col, _txt, _tag)
779
+ # m = _re.match(_txt)
780
+ # if m
781
+ # _txt = m.post_match
782
+ # _ibegin = _row.to_s+'.'+(m.begin(0)+_end).to_s
783
+ # _col = m.end(0)+ _col
784
+ # _iend = _row.to_s+'.'+(_col.to_s)
785
+ # @text.tag_add(_tag,_ibegin, _iend)
786
+ # end
787
+ # end
788
+
789
+ def modified?
790
+ return !(@buffer === text_value)
791
+ end
792
+
793
+ def set_modify
794
+ if !@set_mod
795
+ @set_mod = true
796
+ @controller.change_tab_set_modify(@page_frame)
797
+ end
798
+ end
799
+
800
+ def reset_modify
801
+ @controller.change_tab_reset_modify(@page_frame)
802
+ @set_mod = false
803
+ @file_last_access_time = File.mtime(@file) if @file
804
+ end
805
+
806
+ def highlightline(_row, _line, _check_mod = false)
807
+ if _check_mod && modified?
808
+ set_modify
809
+ end
810
+ _txt = _line
811
+ _end = 0
812
+
813
+ #if line is a comment
814
+ m_c = /#/.match(_txt)
815
+ if m_c then
816
+ _ibegin = _row.to_s+'.'+(m_c.begin(0)).to_s
817
+ _iend = _row.to_s+'.'+(_line.length - 1).to_s
818
+ @text.tag_add('comment',_ibegin, _iend)
819
+ _txt = m_c.pre_match
820
+ end
821
+ arem = Array.new
822
+ if _txt.strip.length > 0
823
+ find_and_set_tag(@re_number, _row, _txt, 'number')
824
+ arem << 'number'
825
+ find_and_set_tag(@re_method_name, _row, _txt, 'method_name',arem)
826
+ arem << 'method_name'
827
+ find_and_set_tag(@re_class_name, _row, _txt, 'class_name',arem)
828
+ arem << 'class_name'
829
+ find_and_set_tag(@re_module_name, _row, _txt, 'module_name',arem)
830
+ arem << 'module_name'
831
+ find_and_set_tag(@re_keyword, _row, _txt, 'keyword',arem)
832
+ arem << 'keyword'
833
+ find_and_set_tag(@re_instance_variable, _row, _txt, 'instance_variable',arem)
834
+ arem << 'instance_variable'
835
+ find_and_set_tag(@re_operator, _row, _txt, 'operator')
836
+ arem << 'operator'
837
+ find_and_set_tag(@re_string, _row, _txt, 'string', arem)
838
+ end
839
+ end
840
+
841
+ def rehighlightline(_row)
842
+ _ibegin = _row.to_s+'.0'
843
+ _iend = (_row+1).to_s+'.0'
844
+ @text.tag_remove('keyword',_ibegin, _iend)
845
+ @text.tag_remove('comment',_ibegin, _iend)
846
+ @text.tag_remove('string',_ibegin, _iend)
847
+ @text.tag_remove('number',_ibegin, _iend)
848
+ @text.tag_remove('operator',_ibegin, _iend)
849
+ @text.tag_remove('capitalize',_ibegin, _iend)
850
+ _line = @text.get(_ibegin, _iend)
851
+ highlightline(_row, _line)
852
+ end
853
+
854
+ def row(_index='insert')
855
+ _row = @text.index(_index).split('.')[0].to_i
856
+ print "def row(_index='insert')",_row.to_s,"\n"
857
+ return _row
858
+ end
859
+
860
+ def do_line_update
861
+ #renum in @text_line_num the portion of visibled screen of @text
862
+ if @text_line_num
863
+ incr = 1 + (@font_metrics[2][1]+@font_metrics_bold[2][1]) / 4
864
+ line_begin = @text.index('@0,0').split('.')[0].to_i
865
+ line_end = @text.index('@0,'+TkWinfo.height(@text).to_s).split('.')[0].to_i + 1
866
+ # breakpoint
867
+ b = @controller.breakpoint_lines_on_file(@file)
868
+ @text_line_num.delete('1.0','end')
869
+ for j in line_begin...line_end
870
+ nline = j.to_s.rjust(6)
871
+ _index = @text_line_num.index('end')
872
+ if @hightliting && @is_line_bold[j]
873
+ @text_line_num.insert('end', nline+"\n",'bold_case')
874
+ else
875
+ @text_line_num.insert('end', nline+"\n")
876
+ end
877
+ if b.include?(j.to_s)
878
+ @text_line_num.tag_add('breakpoint',_index+' -1 lines',_index+' -1 lines + 1 chars')
879
+ end
880
+ end
881
+
882
+ if @highlighting
883
+ _zone_begin = ((line_begin) / @highlight_zone_length).to_i + 1
884
+ _zone_end = ((line_end) / @highlight_zone_length).to_i + 1
885
+
886
+ (_zone_begin >=@last_zone_begin)?_zone_begin.upto(_zone_end+1){|_zone|
887
+ highlight_zone(_zone)
888
+ }:_zone_end.downto(_zone_begin-1){|_zone|
889
+ highlight_zone(_zone)
890
+ }
891
+ @last_line_begin = line_begin
892
+ @last_line_end = line_end
893
+ @last_zone_begin = _zone_begin
894
+ @last_zone_end = _zone_end
895
+ end
896
+ end
897
+ end
898
+
899
+ def highlight_zone(_zone)
900
+ if !@highlight_zone[_zone]
901
+ _b = @highlight_zone_length*(_zone - 1)
902
+ _e = @highlight_zone_length*(_zone) + 1
903
+ for j in _b..._e
904
+ rehighlightline(j)
905
+ end
906
+ @highlight_zone[_zone] = true
907
+ end
908
+ end
909
+
910
+ def text_see(_index=nil)
911
+ if _index
912
+ @text.see(_index)
913
+ end
914
+ end
915
+
916
+ def text_insert_index
917
+ @text.index('insert')
918
+ end
919
+
920
+ def text_insert(index, chars, *tags, &b)
921
+ if block_given?
922
+ instance_eval(&b)
923
+ end
924
+ _index = @text.index(index)
925
+ _row, _col = _index.split('.')
926
+ _row = (_row.to_i - 1).to_s
927
+ chars.each_line {|line|
928
+ @text.insert(_row+'.0', line, *tags)
929
+ if !defined?(m_begin)||(m_begin == nil)
930
+ m_begin = /=begin/.match(line)
931
+ end
932
+ if @highlighting
933
+ if m_begin &&(m_begin.begin(0)==0)
934
+ _ibegin = _row+'.0'
935
+ _iend = _row+'.'+(line.length - 1).to_s
936
+ @text.tag_add('comment',_ibegin, _iend)
937
+ else
938
+ highlightline(_row.to_i, line, false)
939
+ end
940
+ end
941
+ _row = (_row.to_i + 1).to_s
942
+ }
943
+ if defined?(_edit_reset)
944
+ if _edit_reset
945
+ @text.edit_reset
946
+ end
947
+ else
948
+ @text.edit_reset
949
+ end
950
+ end
951
+
952
+ def save
953
+ if !@file
954
+ save_as
955
+ else
956
+ f = File.new(@file, "w")
957
+ begin
958
+ if f
959
+ f.syswrite(text_value)
960
+ @buffer = text_value
961
+ reset_modify
962
+ end
963
+ ensure
964
+ f.close unless f.nil?
965
+ end
966
+ end
967
+ end
968
+
969
+ def save_as
970
+ @file = Tk.getSaveFile
971
+ if @file
972
+ save
973
+ @controller.change_file_name(@page_frame, @file)
974
+ end
975
+ end
976
+
977
+
978
+ def check_file_last_access_time
979
+ if @file && @file_last_access_time
980
+
981
+ ftime = File.mtime(@file)
982
+ if @file_last_access_time != ftime
983
+ msg = 'File "'+@file+'" is changed! Reload?'
984
+ if Tk.messageBox('icon' => 'error', 'type' => 'yesno',
985
+ 'title' => '(Arcadia) Libs', 'parent' => @text,
986
+ 'message' => msg) == 'yes'
987
+ @text.delete('1.0','end')
988
+ load_file(@file)
989
+ else
990
+ @file_last_access_time = ftime
991
+ end
992
+ end
993
+ end
994
+ end
995
+
996
+ def init_editing(_ext='rb')
997
+ case _ext
998
+ when 'rb'
999
+ @fm = AGTkVSplittedFrames.new(@page_frame,150)
1000
+ @fm1 = AGTkVSplittedFrames.new(@fm.right_frame,60)
1001
+ initialize_text(@fm1.right_frame)
1002
+ initialize_text_binding
1003
+ initialize_highlight
1004
+ initialize_line_number(@fm1.left_frame)
1005
+ initialize_tree(@fm.left_frame)
1006
+ else
1007
+ @fm1 = AGTkVSplittedFrames.new(@page_frame,60)
1008
+ initialize_text(@fm1.right_frame)
1009
+ initialize_text_binding
1010
+ initialize_line_number(@fm1.left_frame)
1011
+ end
1012
+ end
1013
+
1014
+ def file_extension(_filename=nil)
1015
+ if _filename
1016
+ _m = /(.*\.)(.*$)/.match(File.basename(_filename))
1017
+ return _m[2] if _m && _m.length > 1
1018
+ end
1019
+ end
1020
+
1021
+ def load_file(_filename = nil)
1022
+ #if filename is nil then open a new tab
1023
+ @file = _filename
1024
+ if _filename
1025
+ #init_editing(file_extension(_filename))
1026
+ File::open(_filename,'r'){ |file|
1027
+ @text.insert('end',file.readlines.collect!{| line | line.chomp+"\n" }.to_s)
1028
+ }
1029
+ end
1030
+ @buffer = text_value
1031
+ reset_modify
1032
+ @text.edit_reset
1033
+ build_tree if @classbrowsing
1034
+ end
1035
+ end
1036
+
1037
+ class AgMultiEditorView
1038
+ attr_reader :enb
1039
+ def initialize(parent=nil)
1040
+ @enb = Tk::BWidget::NoteBook.new(parent){
1041
+ tabbevelsize 0
1042
+ internalborderwidth 2
1043
+ activeforeground 'red'
1044
+ activebackground 'yellow'
1045
+ #background 'black'
1046
+ borderwidth 1
1047
+ side $arcadia['conf']['editor.tabs.side']
1048
+ font $arcadia['conf']['editor.tabs.font']
1049
+ pack('fill'=>'both', :padx=>0, :pady=>0, :expand => 'yes')
1050
+ }
1051
+ end
1052
+
1053
+ end
1054
+
1055
+ class AgMultiEditor < ArcadiaExt
1056
+ attr_reader :breakpoints
1057
+ attr_reader :splitted_frame
1058
+ def before_build
1059
+ ArcadiaContractListener.new(self, DebugContract, :do_debug_event)
1060
+ ArcadiaContractListener.new(self, EditorContract, :do_editor_event)
1061
+ end
1062
+
1063
+ def build
1064
+ if @arcadia.layout.headed?
1065
+ title_frame = @arcadia.layout.domain(conf('frame'))['root']
1066
+ #@close_button = title_frame.add_button(nil,nil,TAB_CLOSE_GIF,'left')
1067
+ end
1068
+
1069
+ @splitted_frame = AGTkOSplittedFrames.new(self.frame,20)
1070
+ @main_frame = AgMultiEditorView.new(@splitted_frame.bottom_frame)
1071
+ #@close_button.bind('1',proc{close_raised})
1072
+ @tabs_file =Hash.new
1073
+ @tabs_editor =Hash.new
1074
+ @breakpoints =Array.new
1075
+ create_find
1076
+ pop_up_menu
1077
+ end
1078
+
1079
+ def after_build
1080
+ self.open_last_files
1081
+ end
1082
+
1083
+ def pop_up_menu
1084
+ @pop_up = TkMenu.new(
1085
+ :parent=>@main_frame.enb,
1086
+ :tearoff=>0,
1087
+ :title => 'Menu'
1088
+ )
1089
+ @pop_up.insert('end',
1090
+ :command,
1091
+ :label=>'...',
1092
+ :state=>'disabled',
1093
+ :background=>'yellow',
1094
+ :activebackground=>'yellow',
1095
+ :hidemargin => true
1096
+ )
1097
+ @c = @pop_up.insert('end',
1098
+ :command,
1099
+ :label=>'Close',
1100
+ :hidemargin => false,
1101
+ :command=> proc{
1102
+ if @selected_tab_name_from_popup != nil
1103
+ _e = @tabs_editor[@selected_tab_name_from_popup]
1104
+ self.close_editor(_e)
1105
+ end
1106
+ }
1107
+ )
1108
+ @c = @pop_up.insert('end',
1109
+ :command,
1110
+ :label=>'Close others',
1111
+ :hidemargin => false,
1112
+ :command=> proc{
1113
+ if @selected_tab_name_from_popup != nil
1114
+ _e = @tabs_editor[@selected_tab_name_from_popup]
1115
+ self.close_others_editor(_e)
1116
+ end
1117
+ }
1118
+ )
1119
+
1120
+ @main_frame.enb.tabbind("Button-3",
1121
+ proc{|x|
1122
+ #p x
1123
+ _x = TkWinfo.pointerx(@main_frame.enb)
1124
+ _y = TkWinfo.pointery(@main_frame.enb)
1125
+ @selected_tab_name_from_popup = 'ff'+x[0].split(':')[0]
1126
+ _file = @main_frame.enb.itemcget(@selected_tab_name_from_popup, 'text')
1127
+ @pop_up.entryconfigure(0, 'label'=>_file)
1128
+ @pop_up.popup(_x,_y)
1129
+ })
1130
+ end
1131
+
1132
+
1133
+ def do_debug_event(_event)
1134
+ #@arcadia.outln('_sender ----> '+_sender.to_s)
1135
+ #@arcadia.outln('_event.signature ----> '+_event.signature)
1136
+ case _event.signature
1137
+ when DebugContract::DEBUG_BEGIN
1138
+ self.debug_begin
1139
+ when DebugContract::DEBUG_END
1140
+ self.debug_end
1141
+ when DebugContract::DEBUG_STEP
1142
+ if _event.context.file
1143
+ self.open_file_in_debug(_event.context.file, _event.context.line)
1144
+ end
1145
+ end
1146
+ end
1147
+
1148
+ def do_editor_event(_event)
1149
+ case _event.signature
1150
+ when EditorContract::OPEN_FILE
1151
+ if _event.context.file
1152
+ if _event.context.line
1153
+ _index = _event.context.line.to_s+'.0'
1154
+ end
1155
+ self.open_file(_event.context.file, _index)
1156
+ _event.handled(self)
1157
+ end
1158
+ when EditorContract::OPEN_TEXT
1159
+ if _event.context.title
1160
+ self.open_buffer(_event.context.title)
1161
+ _e = @tabs_editor[_event.context.title]
1162
+ _e.text_insert('end',_event.context.text) if _event.context.text
1163
+ add_reverse_item(_e)
1164
+ _event.handled(self)
1165
+ end
1166
+ when EditorContract::CLOSE_FILE
1167
+ if _event.context.file
1168
+ self.close_file(_event.context.file)
1169
+ _event.handled(self)
1170
+ end
1171
+ end
1172
+ end
1173
+
1174
+ def add_reverse_item(_editor)
1175
+ code2form = proc{
1176
+ Revparsel.new(_editor.text_value)
1177
+ self.close_editor(_editor, false)
1178
+ # $arcadia['objic'].active.select_last
1179
+ }
1180
+ _editor.insert_popup_menu_item('end',
1181
+ :command,
1182
+ :label=>'View as form',
1183
+ :hidemargin => false,
1184
+ :command=> code2form
1185
+ )
1186
+
1187
+ end
1188
+
1189
+ # def editor_state
1190
+ # r = EditorContract::SObj.new
1191
+ # r.raised_file = self.raised.file
1192
+ # r.breakpoints = @breakpoints
1193
+ # return r
1194
+ # end
1195
+
1196
+ def get_find
1197
+ @find
1198
+ end
1199
+
1200
+ def create_find
1201
+ #find_frame = @arcadia.layout.register_panel(conf('find.frame'),'Find', 'Find')
1202
+ @find = Find.new(@splitted_frame.top_frame, self)
1203
+ end
1204
+
1205
+ def finalize
1206
+ _files =''
1207
+ @tabs_editor.each_value{|editor|
1208
+ _files=_files+'|'+ editor.file if editor.file != nil
1209
+ close_editor(editor)
1210
+ }
1211
+ @arcadia['pers']['editor.files.open']=_files
1212
+ end
1213
+
1214
+ def raised
1215
+ _page = @main_frame.enb.raise
1216
+ return @tabs_editor[_page]
1217
+ end
1218
+
1219
+ def close_raised
1220
+ close_editor(@tabs_editor[@main_frame.enb.raise])
1221
+
1222
+ #_page = @main_frame.enb.raise
1223
+ #_editor = @tabs_editor[_page]
1224
+ #_row = _editor.text_insert_index.split('.')[0].strip.to_i
1225
+ #close_editor(_editor)
1226
+ end
1227
+
1228
+ def breakpoint_add(_file,_line)
1229
+ _tobj = EditorContract::TEditorObj.new(self)
1230
+ _tobj.file = _file
1231
+ _tobj.line = _line
1232
+ EditorContract.instance.breakpoint_created(_tobj)
1233
+ @breakpoints << {:file=>_file,:line=>_line}
1234
+ end
1235
+
1236
+ def breakpoint_del(_file,_line)
1237
+ _tobj = EditorContract::TEditorObj.new(self)
1238
+ _tobj.file = _file
1239
+ _tobj.line = _line
1240
+ EditorContract.instance.breakpoint_deleted(_tobj)
1241
+ @breakpoints.delete_if{|b| (b[:file]==_file && b[:line]==_line)}
1242
+ end
1243
+
1244
+ def breakpoint_lines_on_file(_file)
1245
+ result = Array.new
1246
+ @breakpoints.each{|value|
1247
+ if value[:file]==_file
1248
+ result << value[:line]
1249
+ end
1250
+ }
1251
+ return result
1252
+ end
1253
+
1254
+ def open_last_files
1255
+ if $arcadia['pers']['editor.files.open']
1256
+ _files_index =$arcadia['pers']['editor.files.open'].split("|")
1257
+ _files_index.each{|value|
1258
+ _file,_index = value.split(';')
1259
+ if _file
1260
+ open_file(_file,_index)
1261
+ end
1262
+ }
1263
+ end
1264
+ self
1265
+ end
1266
+
1267
+ def bookmark_add(_file, _index)
1268
+ if @bookmarks == nil
1269
+ @bookmarks = Array.new
1270
+ @bookmarks_index = - 1
1271
+ else
1272
+ _cur_file, _cur_index = @bookmarks[@bookmarks_index]
1273
+ if _cur_file == _file && _cur_index == _index
1274
+ #@arcadia.outln('uguale ----> '+_file+':'+_index)
1275
+ return
1276
+ end
1277
+ @bookmarks = @bookmarks[0..@bookmarks_index]
1278
+ end
1279
+ @bookmarks << [_file, _index]
1280
+ @bookmarks_index = @bookmarks.length - 1
1281
+ #@arcadia.outln('add ----> '+_file+':'+_index)
1282
+ end
1283
+
1284
+ def bookmark_clear
1285
+ @bookmarks.clear
1286
+ @bookmarks_index = - 1
1287
+ end
1288
+
1289
+ def bookmark_next
1290
+ return if @bookmarks == nil || @bookmarks_index >= @bookmarks.length - 1
1291
+ bookmark_move(+1)
1292
+ end
1293
+
1294
+ def bookmark_move(_n=0)
1295
+ @bookmarks_index = @bookmarks_index + _n
1296
+ #Tk.messageBox('message'=>@bookmarks_index.to_s)
1297
+ _file, _index = @bookmarks[@bookmarks_index]
1298
+ _line, _col = _index.split('.') if _index
1299
+ open_file(_file, _index)
1300
+ #openfile(@bookmarks[@bookmarks_index])
1301
+ end
1302
+
1303
+
1304
+ def bookmark_prev
1305
+ return if @bookmarks == nil || @bookmarks_index <= 0
1306
+ bookmark_move(-1)
1307
+ end
1308
+
1309
+
1310
+ def get_tab_from_name(_name=nil)
1311
+ return @main_frame.enb.get_frame(_name)
1312
+ # if _name
1313
+ # @tabs_name.each{
1314
+ # |key,value|
1315
+ # if value.to_s==_name.to_s
1316
+ # return key
1317
+ # end
1318
+ # }
1319
+ # return nil
1320
+ # end
1321
+ end
1322
+
1323
+ def change_tab_set_modify(_tab)
1324
+ _new_name = '(...)'+@main_frame.enb.itemcget(page_name(_tab), 'text')
1325
+ change_tab_title(_tab, _new_name)
1326
+ end
1327
+
1328
+ def page_name(_page_frame)
1329
+ TkWinfo.appname(_page_frame).sub('f','')
1330
+ end
1331
+
1332
+ def change_tab_reset_modify(_tab)
1333
+ #_new_name = @main_frame.enb.itemcget(@tabs_name[_tab], 'text').gsub!("(...)",'')
1334
+ _new_name = @main_frame.enb.itemcget(page_name(_tab), 'text').gsub!("(...)",'')
1335
+ if _new_name
1336
+ change_tab_title(_tab, _new_name)
1337
+ end
1338
+ end
1339
+
1340
+ def change_tab_title(_tab, _new_text)
1341
+ @main_frame.enb.itemconfigure(page_name(_tab), 'text'=> _new_text)
1342
+ end
1343
+
1344
+ def change_file_name(_tab, _new_file)
1345
+ _new_label = File.basename(_new_file)
1346
+ change_tab_title(_tab, _new_label)
1347
+ @tabs_file[page_name(_tab)] = _new_file
1348
+ end
1349
+
1350
+ def debug_begin
1351
+ if @editors_in_debug != nil
1352
+ @editors_in_debug.clear
1353
+ else
1354
+ @editors_in_debug = Array.new
1355
+ end
1356
+ end
1357
+
1358
+ def debug_end
1359
+ debug_reset
1360
+ @editors_in_debug.each{|e|
1361
+ close_editor(e)
1362
+ }
1363
+ end
1364
+
1365
+ def debug_reset
1366
+ if @last_index && @last_e
1367
+ @last_e.unmark_debug(@last_index)
1368
+ end
1369
+ end
1370
+
1371
+ def open_file_in_debug(_filename=nil, _line=nil)
1372
+ debug_reset
1373
+ if _filename && _line
1374
+
1375
+ @last_index = _line.to_s+'.0'
1376
+ _editor_exist = editor_exist?(_filename)
1377
+ @last_e = open_file(_filename, @last_index)
1378
+ if !_editor_exist
1379
+ @editors_in_debug << @last_e
1380
+ end
1381
+ @last_e.mark_debug(@last_index) if @last_e
1382
+
1383
+ end
1384
+ end
1385
+
1386
+ def do_buffer_raise(_name, _title='...')
1387
+ _index = @main_frame.enb.index(_name)
1388
+ _new_caption = '...'
1389
+ if _index != -1
1390
+ #_name = @main_frame.enb.pages(_index)
1391
+ #_tab = get_tab_from_name(_name)
1392
+ #@main_frame.enb.raise(_name)
1393
+ _e = @tabs_editor[_name]
1394
+ if _e && _e.file != nil
1395
+ _new_caption = _e.file
1396
+ @find.use(_e)
1397
+ _e.check_file_last_access_time
1398
+ else
1399
+ _new_caption = _title
1400
+ end
1401
+ end
1402
+ if @arcadia.layout.headed?
1403
+ @arcadia.layout.domain(@arcadia['conf'][@name+'.frame'])['root'].top_text(_new_caption)
1404
+ end
1405
+ _title = @tabs_file[_name] != nil ? File.basename(@tabs_file[_name]) :_name
1406
+ EditorContract.instance.buffer_raised(EditorContract::TEditorObj.new(self, 'title'=>_title, 'file'=>@tabs_file[_name]))
1407
+ end
1408
+
1409
+ def editor_exist?(_filename)
1410
+ _basefilename = File.basename(_filename)
1411
+ #_basename = _basefilename.split('.')[0]+'_'+_basefilename.split('.')[1]
1412
+
1413
+
1414
+ _index = @main_frame.enb.index(self.tab_name(_filename))
1415
+ return _index != -1
1416
+ end
1417
+
1418
+ def tab_name(_filename="")
1419
+ 'ff'+File.expand_path(_filename).gsub("/","_").gsub(".","_")
1420
+ end
1421
+
1422
+ def open_file(_filename = nil, _text_index='1.0')
1423
+ return if _filename == nil || !File.exist?(_filename)
1424
+ _basefilename = File.basename(_filename)
1425
+ _tab_name = self.tab_name(_filename)
1426
+ _index = @main_frame.enb.index(_tab_name)
1427
+ _exist_buffer = _index != -1
1428
+
1429
+ if _exist_buffer
1430
+ open_buffer(_tab_name)
1431
+ else
1432
+ open_buffer(_tab_name, _basefilename)
1433
+ # _basefilename.include?('.rb')?_image = RUBY_DOCUMENT_GIF: _image = DOCUMENT_OPEN_GIF
1434
+ # @main_frame.enb.itemconfigure(_tab_name,
1435
+ # 'image'=> TkPhotoImage.new('data' =>_image )
1436
+ # )
1437
+ @tabs_file[_tab_name]= _filename
1438
+ @tabs_editor[_tab_name].load_file(_filename)
1439
+ #do_buffer_raise(_tab_name)
1440
+ _tobj =EditorContract::TEditorObj.new(self)
1441
+ _tobj.file= _filename
1442
+ EditorContract.instance.file_opened(_tobj)
1443
+ end
1444
+
1445
+ if _text_index != nil && _text_index != '1.0'
1446
+ @tabs_editor[_tab_name].text_see(_text_index)
1447
+ #@tabs_editor[_tab_name].mark_selected(_text_index)
1448
+ end
1449
+
1450
+ return @tabs_editor[_tab_name]
1451
+ end
1452
+
1453
+
1454
+ def open_buffer(_buffer_name = nil, _title = nil)
1455
+ _index = @main_frame.enb.index(_buffer_name)
1456
+ _buffer_name = 'new' if _buffer_name == nil
1457
+ if _index != -1
1458
+ _tab = @main_frame.enb.get_frame(_buffer_name)
1459
+ @main_frame.enb.raise(_buffer_name)
1460
+ else
1461
+ _n = 1
1462
+ while @main_frame.enb.index(_buffer_name) != -1
1463
+ _buffer_name = 'new'+_n.to_s
1464
+ _n =_n+1
1465
+ end
1466
+ if _title == nil
1467
+ _title = '*'+_buffer_name
1468
+ end
1469
+ _tab = @main_frame.enb.insert('end', _buffer_name ,
1470
+ 'text'=> _title,
1471
+ 'raisecmd'=>proc{do_buffer_raise(_buffer_name, _title)}
1472
+ )
1473
+ _e = AgEditor.new(self, _tab)
1474
+ _e.init_editing(_e.file_extension(_title))
1475
+ @tabs_file[_buffer_name]= nil
1476
+ @tabs_editor[_buffer_name]=_e
1477
+ end
1478
+ @main_frame.enb.move(_buffer_name, 1)
1479
+ @main_frame.enb.raise(_buffer_name)
1480
+ @main_frame.enb.see(_buffer_name)
1481
+ return _tab
1482
+ end
1483
+
1484
+ def close_others_editor(_editor, _mod=true)
1485
+ @tabs_editor.values.each do |_e|
1486
+ close_editor(_e) if _e != _editor
1487
+ end
1488
+ end
1489
+
1490
+
1491
+ def close_editor(_editor, _mod=true)
1492
+ if ((_mod)&&(_editor.modified?))
1493
+ _message = @main_frame.enb.itemcget(page_name(_editor.page_frame), 'text')+"\n modified. Save?"
1494
+ _r = TkDialog2.new('message'=>_message, 'buttons'=>['Ok','No','Cancel']).show()
1495
+ if _r == 0
1496
+ _editor.save
1497
+ elsif _r == 1
1498
+ close_tab(_editor.page_frame)
1499
+ elsif _r == 2
1500
+ return
1501
+ end
1502
+ else
1503
+ close_tab(_editor.page_frame)
1504
+ end
1505
+ _tobj = EditorContract::TEditorObj.new(self)
1506
+ _tobj.file = _editor.file
1507
+ EditorContract.instance.file_closed(_tobj)
1508
+ end
1509
+
1510
+ def close_tab(_page_frame)
1511
+ _name = page_name(_page_frame)
1512
+ @tabs_editor.delete(_name)
1513
+ _index = @main_frame.enb.index(_name)
1514
+ @main_frame.enb.delete(_name)
1515
+ if !@main_frame.enb.pages.empty?
1516
+ @main_frame.enb.raise(@main_frame.enb.pages[_index-1])
1517
+ end
1518
+ end
1519
+
1520
+ def close_file(_filename)
1521
+ close_editor(@tabs_editor[tab_name(_filename)])
1522
+ end
1523
+ end
1524
+
1525
+ class Findview < TkFrame
1526
+ def initialize(_parent)
1527
+ super(_parent)
1528
+ @cb_reg = TkCheckButton.new(self){|_cb_reg|
1529
+ text 'regexp'
1530
+ justify 'left'
1531
+ relief 'flat'
1532
+ pack('side'=>'left', 'anchor'=>'e')
1533
+ #place('relwidth' => 0,'x' => 8,'y' => 14,'relheight' => 0,'rely' => 0,'height' => 22,'bordermode' => 'inside','width' => 62)
1534
+ }
1535
+ # @e_kind = Tk::BWidget::ComboBox.new(self){
1536
+ # editable true
1537
+ # justify 'left'
1538
+ # relief 'groove'
1539
+ # autocomplete 'true'
1540
+ # insertbackground '#FFFFFF'
1541
+ # expand 'tab'
1542
+ # values 'forwards backwards page'
1543
+ # takefocus 'true'
1544
+ # pack('side'=>'left', 'anchor'=>'e')
1545
+ # }
1546
+ @rb = TkRadioButton.new(self){
1547
+ value 'forwards'
1548
+ text 'forwards'
1549
+ select
1550
+ pack('side'=>'left', 'anchor'=>'e')
1551
+ #place('relx' => 0,'x' => 8,'y' => 64,'relheight' => 0,'rely' => 0,'height' => 23,'bordermode' => 'inside')
1552
+ }
1553
+ TkRadioButton.new(self){
1554
+ value 'backwards'
1555
+ text 'backwards'
1556
+ pack('side'=>'left', 'anchor'=>'e')
1557
+ #place('relx' => 0,'x' => 8,'y' => 84,'relheight' => 0,'rely' => 0,'height' => 23,'bordermode' => 'inside')
1558
+ }
1559
+ TkRadioButton.new(self){
1560
+ value 'line'
1561
+ text 'line'
1562
+ pack('side'=>'left', 'anchor'=>'e')
1563
+ #place('relx' => 0,'x' => 8,'y' => 104,'relheight' => 0,'rely' => 0,'height' => 23,'bordermode' => 'inside')
1564
+ }
1565
+ # TkLabel.new(self){
1566
+ # text 'what'
1567
+ # pack('side'=>'left', 'anchor'=>'e')
1568
+ # }
1569
+ @b_go = TkButton.new(self){|_b_go|
1570
+ compound 'none'
1571
+ default 'disabled'
1572
+ text 'Find'
1573
+ #background '#ffffff'
1574
+ image TkPhotoImage.new('dat' => FIND_GIF)
1575
+ overrelief 'raised'
1576
+ justify 'center'
1577
+ relief 'ridge'
1578
+ width 20
1579
+ pack('side'=>'right','ipadx'=>20)
1580
+ #place('width' => 50,'x' => 0,'y' => 130,'height' => 23,'bordermode' => 'inside')
1581
+ }
1582
+ @e_what = Tk::BWidget::ComboBox.new(self){
1583
+ editable true
1584
+ justify 'left'
1585
+ relief 'ridge'
1586
+ autocomplete 'true'
1587
+ #insertbackground '#FFFFFF'
1588
+ entrybg '#FFFFFF'
1589
+ expand 'tab'
1590
+ takefocus 'true'
1591
+ pack('padx'=>10, 'fill'=>'x')
1592
+ #place('relwidth' => 1, 'x' => 0,'y' => 41,'height' => 19)
1593
+ }
1594
+ place('x'=>0,'y'=>0,'relheight'=> 1,'relwidth'=> 1)
1595
+
1596
+ end
1597
+ end
1598
+
1599
+ class Find < Findview
1600
+ attr_reader :e_what
1601
+ def initialize(_frame, _controller)
1602
+ super(_frame)
1603
+ #@l_file.configure('text'=>_title)
1604
+ #Tk.tk_call('wm', 'title', self, _title )
1605
+ @controller = _controller
1606
+ @forwards = true
1607
+ @find_action = proc{
1608
+ _radio = @rb.get_value
1609
+ if _radio == 'line'
1610
+ go_line
1611
+ else
1612
+ @forwards = _radio == 'forwards'
1613
+ do_find_next
1614
+ end
1615
+ }
1616
+ @b_go.bind('1', @find_action)
1617
+ e = TkWinfo.children(@e_what)[0]
1618
+ e.bind_append('KeyPress'){|e|
1619
+ case e.keysym
1620
+ when 'Return'
1621
+ @find_action.call
1622
+ break
1623
+ end
1624
+ }
1625
+ @last_index='insert'
1626
+ end
1627
+
1628
+ def editor
1629
+ if @editor_caller == nil
1630
+ @editor_caller = @controller.raised
1631
+ end
1632
+ return @editor_caller
1633
+ end
1634
+
1635
+
1636
+ def go_line
1637
+ if @e_what.value.length > 0
1638
+ _row = @e_what.value
1639
+ _index = _row+'.1'
1640
+ self.editor.text.see(_index)
1641
+ self.editor.text.tag_add('sel', _index,_index+' lineend')
1642
+ self.editor.text.set_insert(_index)
1643
+ @controller.bookmark_add(self.editor.file, _index)
1644
+ end
1645
+ #self.hide()
1646
+ end
1647
+
1648
+ def use(_editor)
1649
+ if (_editor != @editor_caller)
1650
+ @last_index='insert'
1651
+ @editor_caller = _editor
1652
+ end
1653
+ end
1654
+
1655
+ def update_combo(_txt)
1656
+ values = @e_what.cget('values')
1657
+ if (values != nil && !values.include?(_txt))
1658
+ @e_what.insert('end', @e_what.value)
1659
+ end
1660
+ end
1661
+
1662
+ def do_find(_istart=nil)
1663
+ if @e_what.text.length > 0
1664
+ update_combo(@e_what.text)
1665
+ if !_istart && self.editor.text.index('insert')!=nil
1666
+ _istart ='insert'
1667
+ elsif defined?(@last_index)
1668
+ _istart = @last_index
1669
+ else
1670
+ _istart = '1.0'
1671
+ end
1672
+ if @forwards
1673
+ if @cb_reg.cget('onvalue')=='1'
1674
+ _index = self.editor.text.rsearch(@e_what.text,_istart)
1675
+ else
1676
+ _index = self.editor.text.search(@e_what.text,_istart)
1677
+ end
1678
+ else
1679
+
1680
+ if @cb_reg.cget('onvalue')=='1'
1681
+ _index = self.editor.text.tkrsearch(['backwards'],@e_what.text,_istart)
1682
+ else
1683
+ _index = self.editor.text.tksearch(['backwards'],@e_what.text,_istart)
1684
+ end
1685
+ end
1686
+ if _index && _index.length>0
1687
+ self.editor.text.see(_index)
1688
+ _row, _col = _index.split('.')
1689
+ _index_sel_end = _row.to_i.to_s+'.'+(_col.to_i+@e_what.text.length).to_i.to_s
1690
+ if @forwards
1691
+ @last_index= _index_sel_end
1692
+ else
1693
+ @last_index= _row.to_i.to_s+'.'+(_col.to_i-1).to_i.to_s
1694
+ end
1695
+ self.editor.text.tag_add('sel', _index,_index_sel_end)
1696
+ self.editor.text.set_insert(_index)
1697
+ @controller.bookmark_add(self.editor.file, _index)
1698
+ else
1699
+ _message = '"'+@e_what.value+'" not found'
1700
+ TkDialog2.new('message'=>_message, 'buttons'=>['Ok']).show()
1701
+ end
1702
+
1703
+ else
1704
+ self.show()
1705
+ end
1706
+ end
1707
+
1708
+ def do_find_next
1709
+ do_find(@last_index)
1710
+ end
1711
+ end
1712
+
1713
+
1714
+ class KeyTestView < TkToplevel
1715
+ attr_reader :ttest
1716
+ def initialize
1717
+ super
1718
+
1719
+ Tk.tk_call('wm', 'title', self, '...hello' )
1720
+ Tk.tk_call('wm', 'geometry', self, '638x117+200+257' )
1721
+
1722
+ @ttest = TkText.new(self){
1723
+ background '#FFF454'
1724
+ place('relwidth' => '1','relx' => 0,'x' => '0','y' => '0','relheight' => '1','rely' => 0,'height' => '0','bordermode' => 'inside','width' => '0')
1725
+ }
1726
+
1727
+ end
1728
+ end
1729
+
1730
+ class KetTest
1731
+ def initialize
1732
+ kt = KeyTestView.new
1733
+ kt.ttest.bind("KeyPress"){|e|
1734
+ kt.ttest.insert('end'," [ "+e.keysym+" ] ")
1735
+ break
1736
+ }
1737
+ end
1738
+ end
1739
+
1740
+ class AgTkEditor < AgEditor
1741
+ end
1742
+
1743
+ class AgTkMultiEditor < AgMultiEditor
1744
+ end