arcadia 0.1.2.1 → 0.1.3

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.
@@ -1,101 +1,105 @@
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
- tabs=0.5c left
9
- # to use tab key set tab-replace-width-space=0
10
- tab-replace-width-space=2
11
-
12
- #tabs
13
- tabs.font=courier 12
14
- freebsd::tabs.font=courier 12
15
- win::tabs.font={Courier New} 9
16
- #tabs.side=bottom
17
- tabs.side=top
18
- # editor
19
- font=courier 12
20
- font.bold=courier 12 bold
21
- freebsd::font=courier 12
22
- freebsd::font.bold=courier 12 bold
23
- win::font={Courier New} 9
24
- win::font.bold={Courier New} 9 bold
25
- #+--------------------------------------------------
26
- #color.background=#000040
27
- #color.foreground=white
28
- #color.insertbackground=#ff8000
29
- #hightlight.keyword.color.foreground=#800000
30
- #hightlight.variable.color.foreground=#f9c6f8
31
- #hightlight.comment.color.foreground=#4aff4a
32
- #hightlight.string.color.foreground=#8080ff
33
- #hightlight.number.color.foreground=red
34
- #hightlight.capitalize.color.foreground=#ffff00
35
- #hightlight.select.color.foreground=yellow
36
- #hightlight.select.color.background=blue
37
- #hightlight.goto.color.foreground=blue
38
- #hightlight.goto.color.background=yellow
39
- #+--------------------------------------------------
40
- #+--------------------------------------------------
41
- color.background=#FFFFFF
42
- color.foreground=#7F7F7F
43
- color.insertbackground=#ff8000
44
- hightlight.keyword.color.foreground=#00007F
45
- hightlight.keyword.style=bold
46
- hightlight.method_name.color.foreground=#007F7F
47
- hightlight.method_name.style=bold
48
- hightlight.class_name.color.foreground=#0000FF
49
- hightlight.class_name.style=bold
50
- hightlight.module_name.color.foreground=#0000FF
51
- hightlight.module_name.style=bold
52
- hightlight.instance_variable.color.foreground=#7F7F7F
53
- hightlight.instance_variable.style=bold
54
- hightlight.comment.color.foreground=#007F00
55
- hightlight.string.color.foreground=#7F007F
56
- hightlight.number.color.foreground=#007F7F
57
- #hightlight.capitalize.color.foreground=#0000FF
58
- hightlight.operator.color.foreground=#000000
59
- hightlight.operator.style=bold
60
- hightlight.sel.color.foreground=black
61
- hightlight.sel.color.background=#68f914
62
- hightlight.sel.borderwidth=1
63
- hightlight.sel.relief=raised
64
- #hightlight.goto.color.foreground=blue
65
- hightlight.selected.color.background=yellow
66
- hightlight.tabs.color.foreground=black
67
- hightlight.tabs.color.background=#b1cfba
68
- hightlight.tabs.borderwidth=1
69
- hightlight.tabs.relief=raised
70
- hightlight.spaces.color.foreground=black
71
- hightlight.spaces.color.background=#d9f42b
72
- hightlight.spaces.borderwidth=1
73
- hightlight.spaces.relief=raised
74
- #+--------------------------------------------------
75
-
76
-
77
- # line number
78
- #line_number_panel.color.background=#6e6e6e
79
- #line_number_panel.color.foreground=white
80
-
81
- line_number_panel.color.background=#e1e1e1
82
- line_number_panel.color.foreground=#333333
83
-
84
-
85
- # tree explorer
86
- explorer_panel.tree.color.background=#ffffff
87
- explorer_panel.tree.color.foreground=white
88
- explorer_panel.tree.font=courier 12
89
- freebsd::explorer_panel.tree.font=courier 12
90
- win::explorer_panel.tree.font={Courier New} 9
91
- explorer_panel.tree.class.color.foreground=#a42019
92
- explorer_panel.tree.class.font=times 10 bold
93
- win::explorer_panel.tree.class.font=times 10 bold
94
- explorer_panel.tree.def.color.foreground=blue
95
- explorer_panel.tree.def.font=times 10
96
- win::explorer_panel.tree.def.font=times 10
97
- explorer_panel.tree.module.color.foreground=#1b691e
98
- explorer_panel.tree.module.font=times 8 bold
99
- win::explorer_panel.tree.module.font={Courier New} 9 bold
100
-
101
- #:::::::::::::::: Editor group ::::::::::::::::::::::<end>
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
+ tabs=0.5c left
9
+ # to use tab key set tab-replace-width-space=0
10
+ tab-replace-width-space=2
11
+
12
+ #tabs
13
+ tabs.font=courier 12
14
+ freebsd::tabs.font=courier 12
15
+ win::tabs.font={Courier New} 9
16
+ #tabs.side=bottom
17
+ tabs.side=top
18
+
19
+ # editor
20
+ font=courier 12
21
+ font.bold=courier 12 bold
22
+ freebsd::font=courier 12
23
+ freebsd::font.bold=courier 12 bold
24
+ win::font={Courier New} 9
25
+ win::font.bold={Courier New} 9 bold
26
+ #+--------------------------------------------------
27
+ #color.background=#000040
28
+ #color.foreground=white
29
+ #color.insertbackground=#ff8000
30
+ #hightlight.keyword.color.foreground=#800000
31
+ #hightlight.variable.color.foreground=#f9c6f8
32
+ #hightlight.comment.color.foreground=#4aff4a
33
+ #hightlight.string.color.foreground=#8080ff
34
+ #hightlight.number.color.foreground=red
35
+ #hightlight.capitalize.color.foreground=#ffff00
36
+ #hightlight.select.color.foreground=yellow
37
+ #hightlight.select.color.background=blue
38
+ #hightlight.goto.color.foreground=blue
39
+ #hightlight.goto.color.background=yellow
40
+ #+--------------------------------------------------
41
+ #+--------------------------------------------------
42
+ color.background=#FFFFFF
43
+ color.foreground=#7F7F7F
44
+ color.insertbackground=#ff8000
45
+ hightlight.keyword.color.foreground=#00007F
46
+ hightlight.keyword.style=bold
47
+ hightlight.method_name.color.foreground=#007F7F
48
+ hightlight.method_name.style=bold
49
+ hightlight.class_name.color.foreground=#0000FF
50
+ hightlight.class_name.style=bold
51
+ hightlight.module_name.color.foreground=#0000FF
52
+ hightlight.module_name.style=bold
53
+ hightlight.instance_variable.color.foreground=#7F7F7F
54
+ hightlight.instance_variable.style=bold
55
+ hightlight.comment.color.foreground=#007F00
56
+ hightlight.string.color.foreground=#7F007F
57
+ hightlight.number.color.foreground=#007F7F
58
+ #hightlight.capitalize.color.foreground=#0000FF
59
+ hightlight.operator.color.foreground=#000000
60
+ hightlight.operator.style=bold
61
+ hightlight.sel.color.foreground=black
62
+ hightlight.sel.color.background=#68f914
63
+ hightlight.sel.borderwidth=1
64
+ hightlight.sel.relief=raised
65
+ #hightlight.goto.color.foreground=blue
66
+ hightlight.selected.color.background=yellow
67
+ hightlight.tabs.color.foreground=black
68
+ hightlight.tabs.color.background=#b1cfba
69
+ hightlight.tabs.borderwidth=1
70
+ hightlight.tabs.relief=raised
71
+ hightlight.spaces.color.foreground=black
72
+ hightlight.spaces.color.background=#d9f42b
73
+ hightlight.spaces.borderwidth=1
74
+ hightlight.spaces.relief=raised
75
+ #+--------------------------------------------------
76
+
77
+
78
+ # line number
79
+ #line_number_panel.color.background=#6e6e6e
80
+ #line_number_panel.color.foreground=white
81
+
82
+ line_number_panel.color.background=#e1e1e1
83
+ line_number_panel.color.foreground=#333333
84
+
85
+
86
+ # tree explorer
87
+ explorer_panel.tree.color.background=#ffffff
88
+ explorer_panel.tree.color.foreground=white
89
+ #explorer_panel.tabs.side=bottom
90
+ explorer_panel.tabs.side=top
91
+
92
+ explorer_panel.tree.font=courier 12
93
+ freebsd::explorer_panel.tree.font=courier 12
94
+ win::explorer_panel.tree.font={Courier New} 9
95
+ explorer_panel.tree.class.color.foreground=#a42019
96
+ explorer_panel.tree.class.font=times 10 bold
97
+ win::explorer_panel.tree.class.font=times 10 bold
98
+ explorer_panel.tree.def.color.foreground=blue
99
+ explorer_panel.tree.def.font=times 10
100
+ win::explorer_panel.tree.def.font=times 10
101
+ explorer_panel.tree.module.color.foreground=#1b691e
102
+ explorer_panel.tree.module.font=times 8 bold
103
+ win::explorer_panel.tree.module.font={Courier New} 9 bold
104
+
105
+ #:::::::::::::::: Editor group ::::::::::::::::::::::<end>
@@ -1,2229 +1,2287 @@
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
- @font = @controller.conf('font')
41
- @font_bold = @controller.conf('font.bold')
42
- @font_metrics = TkFont.new(@font).metrics
43
- @font_metrics_bold = TkFont.new(@font_bold).metrics
44
- @highlighting = false
45
- @classbrowsing = false
46
- @find = @controller.get_find
47
- end
48
-
49
- def initialize_tree(_frame)
50
- @classbrowsing = true
51
- @nb = Tk::BWidget::NoteBook.new(_frame){
52
- tabbevelsize 0
53
- internalborderwidth 0
54
- activeforeground 'red'
55
- activebackground 'yellow'
56
- borderwidth 1
57
- side $arcadia['conf']['editor.tabs.side']
58
- font $arcadia['conf']['editor.tabs.font']
59
- pack('fill'=>'both', :padx=>0, :pady=>0, :expand => 'yes')
60
- }
61
- @nb_tab_exp = @nb.insert('end','exp' ,'text'=>'Source Tree' )
62
- @nb.raise('exp')
63
- _tree_goto = proc{|_self|
64
- _line = _self.selection_get[0]
65
- _index =_line.to_s+'.0'
66
- _hinner_text = @tree_exp.itemcget(_line,'text').strip
67
- _editor_line = @text.get(_index, _index+ ' lineend')
68
- if !_editor_line.include?(_hinner_text)
69
- MsgContract.instance.out_simple(self, "... rebuild tree \n")
70
- if @tree_thread && @tree_thread.alive?
71
- @tree_thread.exit
72
- end
73
- @tree_thread = Thread.new{
74
- build_tree(_line)
75
- Tk.update
76
- }
77
- _line = _self.selection_get[0]
78
- _index =_line.to_s+'.0'
79
- end
80
- @text.see(_index)
81
- @text.tag_remove('selected','1.0','end')
82
- @text.tag_add('selected',_line.to_s+'.0',(_line+1).to_s+'.0')
83
- }
84
- @tree_exp = Tk::BWidget::Tree.new(@nb_tab_exp){
85
- background '#FFFFFF'
86
- relief 'flat'
87
- showlines false
88
- deltay 18
89
- dragenabled true
90
- selectcommand proc{ _tree_goto.call(self) }
91
- place('relwidth' => 1,'relx' => 0,'x' => '0','y' => '0','relheight' => '1','rely' => 0,'height' => 1,'bordermode' => 'inside','width' => '50')
92
- }
93
-
94
- _c_explo = proc{|*args| @tree_exp.yview(*args)}
95
- _s_explo = TkScrollbar.new(@nb_tab_exp){|s|
96
- width 8
97
- command _c_explo
98
- }.pack('side'=>'right', 'fill'=>'y')
99
- @tree_exp.yscrollcommand proc{|first,last| _s_explo.set first,last}
100
- pop_up_menu_tree
101
- end
102
-
103
- def pop_up_menu_tree
104
- @pop_up_tree = TkMenu.new(
105
- :parent=>@tree_exp,
106
- :title => 'Menu tree'
107
- )
108
- @pop_up_tree.insert('end',
109
- :command,
110
- :label=>'Rebuild',
111
- :hidemargin => false,
112
- :command=> proc{build_tree}
113
- )
114
- @tree_exp.bind_append("Button-3",
115
- proc{|x,y|
116
- _x = TkWinfo.pointerx(@tree_exp)
117
- _y = TkWinfo.pointery(@tree_exp)
118
- @pop_up_tree.popup(_x,_y)
119
- },
120
- "%x %y")
121
- end
122
-
123
-
124
- def initialize_text(_frame)
125
- @v_scroll = TkScrollbar.new(_frame,
126
- 'orient'=>'vertical',
127
- 'relief'=>'flat'
128
- ).pack('side' => 'right', 'fill' => 'y')
129
- @text = TkText.new(@fm1.right_frame){|j|
130
- wrap 'none'
131
- relief 'flat'
132
- undo true
133
- insertofftime 200
134
- insertontime 200
135
- insertbackground $arcadia['conf']['editor.color.insertbackground']
136
- background $arcadia['conf']['editor.color.background']
137
- foreground $arcadia['conf']['editor.color.foreground']
138
- insertwidth 3
139
- exportselection true
140
- autoseparators true
141
- padx 0
142
- tabs $arcadia['conf']['editor.tabs']
143
- place(
144
- 'x'=>0,
145
- 'y'=>0,
146
- 'width' => -15,
147
- 'relheight'=>1,
148
- 'relwidth'=>1,
149
- 'bordermode'=>'outside'
150
- )
151
- }
152
- @text.configure('font', @font);
153
-
154
- @text.tag_configure('eval','foreground' => 'yellow', 'background' =>'red','borderwidth'=>1, 'relief'=>'raised')
155
- @text.tag_configure('errline','borderwidth'=>1, 'relief'=>'groove')
156
- @text.tag_configure('debug', 'background' =>'#b9c6d9', 'borderwidth'=>1 ,'relief'=>'raise')
157
- @buffer = text_value
158
- pop_up_menu
159
- end
160
-
161
- def create_temp_file
162
- _file = @file+'~~'
163
- f = File.new(@file+'~~', "w")
164
- begin
165
- if f
166
- f.syswrite(text_value)
167
- end
168
- ensure
169
- f.close unless f.nil?
170
- end
171
- _file
172
- end
173
-
174
- def initialize_text_binding
175
- @v_scroll.command(proc{|*args|
176
- @text.yview *args
177
- })
178
- @text.yscrollcommand(proc{|first,last| @v_scroll.set(first,last)
179
- self.do_line_update()
180
- })
181
- @text.tag_bind('selected', 'Enter', proc{@text.tag_remove('selected','1.0','end')})
182
-
183
- @text.bind("Enter", proc{check_file_last_access_time})
184
- @text.bind("ButtonPress-1", proc{
185
- _code = $arcadia['palette'].give_me_code
186
- @text.insert('insert', _code) if _code
187
- })
188
-
189
- @text.bind("Control-KeyPress"){|e|
190
- case e.keysym
191
- when 'space'
192
- line, col = @text.index('insert').split('.')
193
- _file = create_temp_file
194
- EditorContract.instance.complete_code(self, 'file'=>_file, 'line'=>line.to_s, 'col'=>col.to_s)
195
- when 'z'
196
- _b = @text.index('insert').split('.')[0].to_i
197
- @text.edit_undo
198
- _e = @text.index('insert').split('.')[0].to_i
199
- if @highlighting
200
- for j in _b..._e
201
- rehighlightline(j)
202
- end
203
- end
204
- break
205
- when 'c'
206
- @text.text_copy
207
- break
208
- when 'x'
209
- @text.text_cut
210
- break
211
- when 'v'
212
- _b = @text.index('insert').split('.')[0].to_i
213
- @text.text_paste
214
- _e = @text.index('insert').split('.')[0].to_i
215
- if @highlighting
216
- for j in _b..._e
217
- rehighlightline(j)
218
- end
219
- end
220
- break
221
- end
222
- case e.keysym
223
- when 's'
224
- save
225
- when 'f'
226
- _r = @text.tag_ranges('sel')
227
- if _r.length>0
228
- _text=@text.get(_r[0][0],_r[0][1])
229
- if _text.length > 0
230
- @find.e_what.text(_text)
231
- end
232
- else
233
- end
234
- @find.use(self)
235
- @find.e_what.focus
236
- @find.show
237
- when 'egrave'
238
- @text.insert('insert',"{")
239
- when 'plus'
240
- @text.insert('insert',"}")
241
- end
242
- }
243
-
244
- @text.bind("Control-Shift-KeyPress"){|e|
245
- case e.keysym
246
- when 'I'
247
- _r = @text.tag_ranges('sel')
248
- _row_begin = _r[0][0].split('.')[0].to_i
249
- _row_end = _r[_r.length - 1][1].split('.')[0].to_i
250
- n_space = $arcadia['conf']['editor.tab-replace-width-space'].to_i
251
- if n_space > 0
252
- suf = "\s"*n_space
253
- else
254
- suf = "\t"
255
- end
256
-
257
- for _row in _row_begin..._row_end
258
- @text.insert(_row.to_s+'.0',suf)
259
- end
260
- when 'U'
261
- _r = @text.tag_ranges('sel')
262
- _row_begin = _r[0][0].split('.')[0].to_i
263
- _row_end = _r[_r.length - 1][1].split('.')[0].to_i
264
- n_space = $arcadia['conf']['editor.tab-replace-width-space'].to_i
265
- if n_space > 0
266
- suf = "\s"*n_space
267
- else
268
- suf = "\t"
269
- end
270
- _l_suf = suf.length.to_s
271
- for _row in _row_begin..._row_end
272
- if @text.get(_row.to_s+'.0',_row.to_s+'.'+_l_suf) == suf
273
- @text.delete(_row.to_s+'.0',_row.to_s+'.'+_l_suf)
274
- end
275
- end
276
- when 'C'
277
- _r = @text.tag_ranges('sel')
278
- _row_begin = _r[0][0].split('.')[0].to_i
279
- _row_end = _r[_r.length - 1][1].split('.')[0].to_i
280
-
281
- for _row in _row_begin..._row_end
282
- if @text.get(_row.to_s+'.0',_row.to_s+'.1') == "#"
283
- @text.delete(_row.to_s+'.0',_row.to_s+'.1')
284
- else
285
- @text.insert(_row.to_s+'.0',"#")
286
- end
287
- rehighlightline(_row) if @highlighting
288
- end
289
-
290
- end
291
- }
292
-
293
- @text.bind("KeyPress"){|e|
294
- case e.keysym
295
- when 'Return'
296
- when 'BackSpace'
297
- _index = @text.index('insert')
298
- _row, _col = _index.split('.')
299
- rehighlightline(_row.to_i) if @highlighting
300
- when 'Delete'
301
- _index = @text.index('insert')
302
- _row, _col = _index.split('.')
303
- rehighlightline(_row.to_i) if @highlighting
304
- when 'F5'
305
- save
306
- $arcadia['shell'].run(@file.to_s)
307
- when 'F3'
308
- @find.do_find_next
309
- when 'F1'
310
- line, col = @text.index('insert').split('.')
311
- _file = create_temp_file
312
- _x, _y = @controller.xy_insert
313
- EditorContract.instance.doc_code(@controller, 'file'=>_file, 'line'=>line.to_s, 'col'=>col.to_s, 'xdoc'=>_x, 'ydoc'=>_y)
314
- when 'Tab'
315
- n_space = $arcadia['conf']['editor.tab-replace-width-space'].to_i
316
- _r = @text.tag_ranges('sel')
317
- if _r && _r[0]
318
- _row_begin = _r[0][0].split('.')[0].to_i
319
- _row_end = _r[_r.length - 1][1].split('.')[0].to_i
320
- if n_space > 0
321
- suf = "\s"*n_space
322
- else
323
- suf = "\t"
324
- end
325
- for _row in _row_begin..._row_end
326
- @text.insert(_row.to_s+'.0', suf)
327
- end
328
- break
329
- elsif n_space > 0
330
- @text.insert('insert', "\s"*n_space)
331
- break
332
- end
333
- end
334
- }
335
-
336
- @text.bind("Shift-KeyPress"){|e|
337
- case e.keysym
338
- when 'Tab'
339
- _r = @text.tag_ranges('sel')
340
- if _r && _r[0]
341
- _row_begin = _r[0][0].split('.')[0].to_i
342
- _row_end = _r[_r.length - 1][1].split('.')[0].to_i
343
-
344
- n_space = $arcadia['conf']['editor.tab-replace-width-space'].to_i
345
- if n_space > 0
346
- suf = "\s"*n_space
347
- else
348
- suf = "\t"
349
- n_space = 1
350
- end
351
- for _row in _row_begin..._row_end
352
- if @text.get(_row.to_s+'.0',_row.to_s+'.'+n_space.to_s) == suf
353
- @text.delete(_row.to_s+'.0',_row.to_s+'.'+n_space.to_s)
354
- end
355
- end
356
- break
357
- end
358
- end
359
- }
360
-
361
- @text.bind("KeyRelease"){|e|
362
- case e.keysym
363
- when 'Control_L','Return', 'Control_V', 'BackSpace', 'Delete'
364
- if modified?
365
- set_modify
366
- else
367
- reset_modify
368
- end
369
- do_line_update
370
- when 'Right','Left','Down', 'Up'
371
- # do nil
372
- else
373
- check_modify
374
- end
375
- case e.keysym
376
- when 'Return'
377
- _index = @text.index('insert')
378
- _row, _col = _index.split('.')
379
- _txt = @text.get((_row.to_i-1).to_s+'.0',_index)
380
- if _txt.length > 0
381
- m = /\s*/.match(_txt)
382
- if m
383
- if (m[0] != "\n")
384
- _sm = m[0]
385
- _sm = _sm.sub(/\n/,"")
386
- @text.insert('insert',_sm)
387
- end
388
- end
389
- end
390
- if _row.to_i + 1 == @text.index('end').split('.')[0].to_i
391
- do_line_update
392
- end
393
- else
394
- if @highlighting && /\w/.match(e.keysym)
395
- rehighlightline(@text.index('insert').split('.')[0].to_i)
396
- end
397
- end
398
- }
399
- end
400
-
401
- def initialize_line_number(_frame)
402
- @text_line_num = TkText.new(_frame){
403
- wrap 'none'
404
- relief 'flat'
405
- undo false
406
- takefocus 0
407
- insertofftime 0
408
- exportselection true
409
- autoseparators true
410
- background $arcadia['conf']['editor.line_number_panel.color.background']
411
- foreground $arcadia['conf']['editor.line_number_panel.color.foreground']
412
- place(
413
- 'x'=>0,
414
- 'y'=>0,
415
- 'relheight'=>1,
416
- 'relwidth'=>1,
417
- 'bordermode'=>'outside'
418
- )
419
- }
420
- delta = @font_metrics_bold[2][1]-@font_metrics[2][1]
421
- @text_line_num.tag_configure('bold_case', 'spacing1'=>delta)
422
- @text_line_num.tag_configure('breakpoint', 'background'=>'red','borderwidth'=>1, 'relief'=>'raised')
423
- @text_line_num.bind("Double-ButtonPress-1", proc{
424
- _index = @text_line_num.index('insert')
425
- _line = @text_line_num.get(_index+' linestart',_index+' lineend').strip
426
- if @controller.breakpoint_lines_on_file(@file).include?(_line)
427
- @text_line_num.tag_remove('breakpoint',_index+' linestart',_index+' lineend')
428
- @controller.breakpoint_del(@file, _line)
429
- else
430
- @text_line_num.tag_add('breakpoint',_index+' linestart',_index+' linestart + 1 chars')
431
- @controller.breakpoint_add(@file, _line)
432
- end
433
- })
434
- @text_line_num.configure('font', @font);
435
- @text_line_num.tag_configure('line_num',
436
- 'foreground' => '#FFFFFF',
437
- 'background' =>'#0000a0',
438
- 'borderwidth'=>2,
439
- 'relief'=>'raised'
440
- )
441
- end
442
-
443
- def initialize_highlight
444
- @highlighting = true
445
- @highlight_zone = Hash.new;
446
- # @highlight_zone_length = 45;
447
- @highlight_zone_length = 8;
448
- @last_line_begin = 0
449
- @last_line_end = 0
450
- @last_zone_begin=0;
451
- @last_zone_end=0;
452
- @is_line_bold = Hash.new
453
- @is_tag_bold = Hash.new
454
-
455
- @keyword = ['__FILE__', 'and', 'def', 'end', 'in', 'or', 'self', 'unless',
456
- '__LINE__', 'begin', 'defined?', 'ensure', 'module', 'redo', 'super', 'until',
457
- 'BEGIN', 'break', 'do', 'false', 'next', 'rescue', 'then', 'when',
458
- 'END', 'case', 'else', 'for', 'nil', 'retry', 'true', 'while',
459
- 'alias', 'class', 'elsif', 'if', 'not', 'return', 'undef', 'yield','require','include']
460
- _re_string = ''
461
- @keyword.each{|word|
462
- if _re_string.length > 0
463
- _re_string << '|'
464
- end
465
- if ['class','module','def'].include?(word)
466
- _re_string << '([\s]*'+word+'[\s])'
467
- else
468
- _re_string << '\b('+word+')([.,+\(\s])'
469
- end
470
- }
471
- @re_keyword = Regexp::new(_re_string)
472
- @re_instance_variable = /([\s]*@)[A-Za-z0-9_]*/
473
- @re_string = /'([\/A-Za-z0-9_@+\-!?=<>\[\]\{\}\(\).\s]*)'|"([\/A-Za-z0-9_@+\-!?=<>\[\]\{\}\(\).\s]*)"/
474
- @re_number = /\d/
475
- @re_operator = /[\(\)\[\]\(\)\{\}.:;,=><|]/
476
- @re_method_name = /(def[\s][\s]*)[A-Za-z0-9_]*/
477
- @re_class_name = /(class[\s][\s]*)[A-Za-z0-9_]*/
478
- @re_module_name = /(module[\s][\s]*)[A-Za-z0-9_]*/
479
- do_tag_configure('keyword')
480
- do_tag_configure('method_name')
481
- do_tag_configure('instance_variable')
482
- do_tag_configure('class_name')
483
- do_tag_configure('module_name')
484
- do_tag_configure('comment')
485
- do_tag_configure('string')
486
- do_tag_configure('number')
487
- do_tag_configure('sel')
488
- do_tag_configure('selected')
489
- do_tag_configure('operator')
490
- do_tag_configure('tabs')
491
- do_tag_configure('spaces')
492
- end
493
-
494
- def do_tag_configure(_name)
495
- h = Hash.new
496
- if $arcadia['conf']['editor.hightlight.'+_name+'.color.foreground']
497
- h['foreground']=$arcadia['conf']['editor.hightlight.'+_name+'.color.foreground']
498
- end
499
- if $arcadia['conf']['editor.hightlight.'+_name+'.color.background']
500
- h['background']=$arcadia['conf']['editor.hightlight.'+_name+'.color.background']
501
- end
502
- if $arcadia['conf']['editor.hightlight.'+_name+'.style']== 'bold'
503
- h['font']=@font_bold
504
- @is_tag_bold[_name]= true
505
- end
506
- if $arcadia['conf']['editor.hightlight.'+_name+'.relief']
507
- h['relief']=$arcadia['conf']['editor.hightlight.'+_name+'.relief']
508
- end
509
- if $arcadia['conf']['editor.hightlight.'+_name+'.borderwidth']
510
- h['borderwidth']=$arcadia['conf']['editor.hightlight.'+_name+'.borderwidth']
511
- end
512
- @text.tag_configure(_name, h)
513
- end
514
-
515
- def pop_up_menu
516
- @pop_up = TkMenu.new(
517
- :parent=>@text,
518
- :tearoff=>1,
519
- :title => 'Menu'
520
- )
521
- @pop_up.insert('end',
522
- :command,
523
- :label=>'Save as',
524
- :hidemargin => false,
525
- :command=> proc{save_as}
526
- )
527
- @pop_up.insert('end',
528
- :command,
529
- :label=>'Save',
530
- :hidemargin => false,
531
- :command=> proc{save}
532
- )
533
-
534
- @pop_up.insert('end',
535
- :command,
536
- :label=>'Close',
537
- :hidemargin => false,
538
- :command=> proc{@controller.close_editor(self)}
539
- )
540
-
541
- @pop_up.insert('end',
542
- :command,
543
- :label=>'Close others',
544
- :hidemargin => false,
545
- :command=> proc{@controller.close_others_editor(self)}
546
- )
547
-
548
- @pop_up.insert('end',
549
- :command,
550
- :label=>'Close all',
551
- :hidemargin => false,
552
- :command=> proc{@controller.close_all_editor(self)}
553
- )
554
-
555
-
556
- @pop_up.insert('end', :separator)
557
-
558
- @pop_up.insert('end',
559
- :command,
560
- :label=>'Color',
561
- :hidemargin => false,
562
- :command=> proc{
563
- @text.insert('insert',Tk.chooseColor)
564
- }
565
- )
566
- @pop_up.insert('end',
567
- :command,
568
- :label=>'Font',
569
- :hidemargin => false,
570
- :command=> proc{
571
- @text.insert('insert', $arcadia['action.get.font'].call)
572
- }
573
- )
574
-
575
- @pop_up.insert('end', :separator)
576
-
577
- @pop_up.insert('end',
578
- :command,
579
- :label=>'Show tabs',
580
- :hidemargin => false,
581
- :command=> proc{show_tabs}
582
- )
583
-
584
-
585
- @pop_up.insert('end',
586
- :command,
587
- :label=>'Hide tabs',
588
- :hidemargin => false,
589
- :command=> proc{hide_tabs}
590
- )
591
-
592
- @pop_up.insert('end',
593
- :command,
594
- :label=>'Show spaces',
595
- :hidemargin => false,
596
- :command=> proc{show_spaces}
597
- )
598
-
599
-
600
- @pop_up.insert('end',
601
- :command,
602
- :label=>'Hide spaces',
603
- :hidemargin => false,
604
- :command=> proc{hide_spaces}
605
- )
606
-
607
-
608
- @pop_up.insert('end',
609
- :command,
610
- :label=>'Space to tabs indentation',
611
- :hidemargin => false,
612
- :command=> proc{indentation_space_2_tabs}
613
- )
614
-
615
- @pop_up.insert('end',
616
- :command,
617
- :label=>'Tabs to space indentation',
618
- :hidemargin => false,
619
- :command=> proc{indentation_tabs_2_space}
620
- )
621
-
622
-
623
- @text.bind("Button-3",
624
- proc{|x,y|
625
- _x = TkWinfo.pointerx(@text)
626
- _y = TkWinfo.pointery(@text)
627
- @pop_up.popup(_x,_y)
628
- },
629
- "%x %y")
630
- end
631
-
632
- def unmark_debug(_index)
633
- @text.tag_remove('debug',_index+' linestart', _index+' lineend')
634
- end
635
-
636
- def mark_debug(_index)
637
- #@text.tag_add('debug',_index +' linestart', _index +' +1 lines linestart')
638
- @text.tag_add('debug',_index +' linestart', _index +' lineend')
639
- end
640
-
641
- def mark_selected(_index)
642
- @text.tag_remove('selected','1.0', 'end')
643
- @text.tag_add('selected',_index +' linestart', _index +' +1 lines linestart')
644
- end
645
-
646
-
647
- def build_tree_from_source(_source)
648
- _row = 1
649
- _liv = 0
650
- _livs = Array.new
651
- root = TreeNode.new(nil, 'KRoot'){|_node|
652
- _node.rif= 'root'
653
- _node.label=''
654
- }
655
- _livs[_liv]=root
656
- _source.each_line{|line|
657
- line = "\s"+line.split("#")[0]+"\s"
658
- m = /[\s\n\t\;]+(module|class|def|if|unless|begin|case|for|while|do)[\s\n\t\;]+/.match(line)
659
- if m
660
- index = m.post_match.strip.length - 1
661
- if m.post_match.strip[index,index]=='{'
662
- _row = _row +1
663
- next
664
- end
665
- _liv>=0? _liv = _liv + 1:_liv=1
666
- _pliv = _liv
667
- _parent = nil
668
- while (_parent == nil && _pliv>=0)
669
- _pliv = _pliv -1
670
- _parent = _livs[_pliv]
671
- end
672
- if _parent
673
- _helptext = m.post_match.strip
674
- _label = _helptext.split('<')[0]
675
- if _label == nil || _label.strip.length==0
676
- _label = _helptext
677
- end
678
- if (m[0].strip[0..4] == "class" && m.pre_match.strip.length==0)
679
- _kind = 'KClass'
680
- elsif (m[0].strip[0..4] == "class" && m.pre_match.strip.length>0)
681
- _row = _row +1
682
- _liv = _liv - 1
683
- next
684
- elsif (m[0].strip[0..5] == "module" && m.pre_match.strip.length==0)
685
- _kind = 'KModule'
686
- elsif (m[0].strip[0..5] == "module" && m.pre_match.strip.length>0)
687
- _row = _row +1
688
- _liv = _liv - 1
689
- next
690
- 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))
691
- _row = _row +1
692
- next
693
- elsif ((m[0].strip[0..1] == "if" || m[0].strip[0..5] == "unless") && m.pre_match.strip.length>0)
694
- _row = _row +1
695
- _liv = _liv - 1
696
- next
697
- elsif (m[0].strip[0..2] == "def" && m.pre_match.strip.length==0)
698
- _kind = 'KDef'
699
- if _label.include?(_parent.label + '.')
700
- _kind = 'KDefClass'
701
- end
702
- # elsif (m[0].strip[0..10] == "attr_reader" && m.pre_match.strip.length==0)
703
- # _kind = 'KAttr_reader'
704
- # _liv = _liv - 1
705
- # _row = _row +1
706
- end
707
-
708
- TreeNode.new(_parent, _kind){|_node|
709
- _node.label = _label
710
- _node.helptext = _helptext
711
- _node.rif = _row.to_s
712
- _livs[_pliv + 1]=_node
713
- }
714
- else
715
- _row = _row +1
716
- _liv = _liv - 1
717
- next
718
- end
719
- end
720
- m_end = /[\s\n\t\;]+end[\s\n\t\;]+/.match(line)
721
- if m_end
722
- _liv = _liv - 1
723
- end
724
- _row = _row +1
725
- }
726
- return root
727
- end
728
-
729
- def build_tree_from_node(_node, _label_match=nil)
730
-
731
- @image_kclass = TkPhotoImage.new('dat' => TREE_NODE_CLASS_GIF)
732
- @image_kmodule = TkPhotoImage.new('dat' => TREE_NODE_MODULE_GIF)
733
- @image_kdef = TkPhotoImage.new('dat' => TREE_NODE_DEF_GIF)
734
- @image_kdefclass = TkPhotoImage.new('dat' => TREE_NODE_DEFCLASS_GIF)
735
-
736
- _sorted_sons = _node.sons.sort
737
- for inode in 0.._sorted_sons.length - 1
738
- _son = _sorted_sons[inode]
739
- if _son.kind == 'KClass'
740
- _image = @image_kclass
741
- elsif _son.kind == 'KModule'
742
- _image = @image_kmodule
743
- elsif _son.kind == 'KDef'
744
- _image = @image_kdef
745
- elsif _son.kind == 'KDefClass'
746
- _image = @image_kdefclass
747
- end
748
- @tree_exp.insert('end', _son.parent.rif ,_son.rif, {
749
- 'text' => _son.label ,
750
- 'helptext' => _son.helptext,
751
- 'font'=>$arcadia['conf']['editor.explorer_panel.tree.font'],
752
- 'image'=> _image
753
- }
754
- )
755
- if (_label_match) && (_label_match.strip == _son.label.strip)
756
- @selected = _son
757
- end
758
- build_tree_from_node(_son, _label_match)
759
- end
760
- end
761
-
762
- def build_tree(_sel=nil)
763
- if _sel
764
- _label_sel = @tree_exp.itemcget(_sel,'text')
765
- end
766
-
767
- #clear tree
768
- begin
769
- @tree_exp.delete(@tree_exp.nodes('root'))
770
- rescue Exception
771
- # workaround on windows
772
- @tree_exp.delete(@tree_exp.nodes('root'))
773
- end
774
-
775
-
776
- #(re)build tree
777
- _txt = @text.get('1.0','end')
778
- @root = build_tree_from_source(_txt)
779
- @selected = nil
780
- build_tree_from_node(@root, _label_sel)
781
- if @selected
782
- @tree_exp.selection_add(@selected.rif)
783
- @tree_exp.open_tree(@selected.parent.rif)
784
- @tree_exp.see(@selected.rif)
785
- end
786
- end
787
-
788
- def insert_popup_menu_item(_where, *args)
789
- @pop_up.insert(_where,*args)
790
- end
791
-
792
- def text_value
793
- return @text.value
794
- end
795
-
796
- # vertical scrollbar : ON/OFF
797
- def vscroll(mode)
798
- st = TkGrid.info(@v_scroll)
799
- if mode && st == [] then
800
- @v_scroll.grid('row'=>0, 'column'=>1, 'sticky'=>'ns')
801
- elsif !mode && st != [] then
802
- @v_scroll.ungrid
803
- end
804
- self
805
- end
806
-
807
- # horizontal scrollbar : ON/OFF
808
- def hscroll(mode, wrap_mode="char")
809
- st = TkGrid.info(@h_scroll)
810
- if mode && st == [] then
811
- @h_scroll.grid('row'=>1, 'column'=>0, 'sticky'=>'ew')
812
- @text.configure('wrap'=> 'none')
813
- elsif !mode && st != [] then
814
- @h_scroll.ungrid
815
- @text.configure('wrap'=> wrap_mode)
816
- end
817
- self
818
- end
819
-
820
- def rowcol(_index, _gap_row = nil, _gap_col = nil)
821
- _riga, _colonna = _index.split('.')
822
- if _gap_row == nil
823
- _riga = '1'
824
- _gap_row = 0
825
- end
826
- if _gap_col == nil
827
- _colonna = '0'
828
- _gap_col = 0
829
- end
830
- return (_riga.to_i + _gap_row).to_s + '.'+ (_colonna.to_i + _gap_col).to_s
831
- end
832
-
833
- def find_and_set_tag(_re, _row, _txt, _tag, _tag_rem = nil)
834
- m = _re.match(_txt)
835
- _end = 0
836
- if m && @is_tag_bold[_tag]
837
- @is_line_bold[_row]=true
838
- end
839
- while m
840
- _txt = m.post_match
841
- _ibegin = _row.to_s+'.'+(m.begin(0)+_end).to_s
842
- _end = m.end(0) + _end
843
- _iend = _row.to_s+'.'+(_end.to_s)
844
- if _tag_rem
845
- _tag_rem.each {|value|
846
- @text.tag_remove(value,_ibegin, _iend)
847
- }
848
- end
849
- @text.tag_add(_tag,_ibegin, _iend)
850
- m = _re.match(_txt)
851
- end
852
- end
853
-
854
- def show_spaces
855
- @spaces_show = true
856
- _row = 1
857
- @text.value.each{|_line|
858
- show_chars_line(_row, _line, /[ ^\t]\s*/, 'spaces')
859
- _row = _row+1
860
- }
861
- end
862
-
863
-
864
- def show_tabs
865
- @tabs_show = true
866
- _row = 1
867
- @text.value.each{|_line|
868
- show_chars_line(_row, _line, /\t/, 'tabs')
869
- _row = _row+1
870
- }
871
- end
872
-
873
-
874
- def show_chars_line(_row, _line, _re, _tag)
875
- m = _re.match(_line)
876
- _end = 0
877
- while m
878
- _txt = m.post_match
879
- _ibegin = _row.to_s+'.'+(m.begin(0)+_end).to_s
880
- _end = m.end(0) + _end
881
- _iend = _row.to_s+'.'+(_end.to_s)
882
- @text.tag_add(_tag,_ibegin, _iend)
883
- m = _re.match(_txt)
884
- end
885
- end
886
-
887
- def indentation_space_2_tabs(_n_space=2)
888
- _row = 1
889
- @text.value.each{|_line|
890
- m = /\s*/.match(_line)
891
- _end = 0
892
- if m && m.begin(0)==0
893
- _s = m[0]
894
- if !_s.include?("\n") && !_s.include?("\t")
895
- _ibegin = _row.to_s+'.0'
896
- _iend = _row.to_s+'.'+m.end(0).to_s
897
- _n_tab = (_s.length / _n_space).round
898
- @text.delete(_ibegin, _iend)
899
- @text.insert(_ibegin,"\t"*_n_tab )
900
- end
901
- end
902
- _row = _row+1
903
- }
904
- check_modify
905
- end
906
-
907
- def indentation_tabs_2_space(_n_space=2)
908
- _row = 1
909
- @text.value.each{|_line|
910
- m = /\t*/.match(_line)
911
- _end = 0
912
- if m && m.begin(0)==0
913
- _s = m[0]
914
- if !_s.include?("\n")
915
- _ibegin = _row.to_s+'.0'
916
- _iend = _row.to_s+'.'+m.end(0).to_s
917
- @text.delete(_ibegin, _iend)
918
- @text.insert(_ibegin,"\s"*_s.length*_n_space )
919
- end
920
- end
921
- _row = _row+1
922
- }
923
- check_modify
924
- end
925
-
926
-
927
- def hide_tabs
928
- @text.tag_remove('tabs','1.0', 'end')
929
- @tabs_show = false
930
- end
931
-
932
- def hide_spaces
933
- @text.tag_remove('spaces','1.0', 'end')
934
- @spaces_show = false
935
- end
936
-
937
-
938
- def modified?
939
- return !(@buffer === text_value)
940
- end
941
-
942
- def set_modify
943
- if !@set_mod
944
- @set_mod = true
945
- @controller.change_tab_set_modify(@page_frame)
946
- end
947
- end
948
-
949
- def reset_modify
950
- @controller.change_tab_reset_modify(@page_frame)
951
- @set_mod = false
952
- @file_last_access_time = File.mtime(@file) if @file
953
- end
954
-
955
- def highlightline(_row, _line, _check_mod = false)
956
- if _check_mod
957
- check_modify
958
- end
959
- _txt = _line
960
- _end = 0
961
-
962
- #if line is a comment
963
- m_c = /#/.match(_txt)
964
- if m_c then
965
- _ibegin = _row.to_s+'.'+(m_c.begin(0)).to_s
966
- _iend = _row.to_s+'.'+(_line.length - 1).to_s
967
- @text.tag_add('comment',_ibegin, _iend)
968
- _txt = m_c.pre_match
969
- end
970
- arem = Array.new
971
- if _txt.strip.length > 0
972
- find_and_set_tag(@re_number, _row, _txt, 'number')
973
- arem << 'number'
974
- find_and_set_tag(@re_method_name, _row, _txt, 'method_name',arem)
975
- arem << 'method_name'
976
- find_and_set_tag(@re_class_name, _row, _txt, 'class_name',arem)
977
- arem << 'class_name'
978
- find_and_set_tag(@re_module_name, _row, _txt, 'module_name',arem)
979
- arem << 'module_name'
980
- find_and_set_tag(@re_keyword, _row, _txt, 'keyword',arem)
981
- arem << 'keyword'
982
- find_and_set_tag(@re_instance_variable, _row, _txt, 'instance_variable',arem)
983
- arem << 'instance_variable'
984
- find_and_set_tag(@re_operator, _row, _txt, 'operator')
985
- arem << 'operator'
986
- find_and_set_tag(@re_string, _row, _txt, 'string', arem)
987
- end
988
- find_and_set_tag(/\t/, _row, _txt, 'tabs', arem) if @tabs_show
989
- find_and_set_tag(/[ ^\t]\s*/, _row, _txt, 'spaces', arem) if @spaces_show
990
- end
991
-
992
- def rehighlightline(_row)
993
- _ibegin = _row.to_s+'.0'
994
- _iend = (_row+1).to_s+'.0'
995
- @text.tag_remove('keyword',_ibegin, _iend)
996
- @text.tag_remove('comment',_ibegin, _iend)
997
- @text.tag_remove('string',_ibegin, _iend)
998
- @text.tag_remove('number',_ibegin, _iend)
999
- @text.tag_remove('operator',_ibegin, _iend)
1000
- @text.tag_remove('capitalize',_ibegin, _iend)
1001
- _line = @text.get(_ibegin, _iend)
1002
- highlightline(_row, _line)
1003
- end
1004
-
1005
- def row(_index='insert')
1006
- _row = @text.index(_index).split('.')[0].to_i
1007
- print "def row(_index='insert')",_row.to_s,"\n"
1008
- return _row
1009
- end
1010
-
1011
- def do_line_update
1012
- #renum in @text_line_num the portion of visibled screen of @text
1013
- if @text_line_num
1014
- incr = 1 + (@font_metrics[2][1]+@font_metrics_bold[2][1]) / 4
1015
- line_begin = @text.index('@0,0').split('.')[0].to_i
1016
- line_end = @text.index('@0,'+TkWinfo.height(@text).to_s).split('.')[0].to_i + 1
1017
- # breakpoint
1018
- b = @controller.breakpoint_lines_on_file(@file)
1019
- @text_line_num.delete('1.0','end')
1020
- for j in line_begin...line_end
1021
- nline = j.to_s.rjust(6)
1022
- _index = @text_line_num.index('end')
1023
- if @hightliting && @is_line_bold[j]
1024
- @text_line_num.insert('end', nline+"\n",'bold_case')
1025
- else
1026
- @text_line_num.insert('end', nline+"\n")
1027
- end
1028
- if b.include?(j.to_s)
1029
- @text_line_num.tag_add('breakpoint',_index+' -1 lines',_index+' -1 lines + 1 chars')
1030
- end
1031
- end
1032
-
1033
- if @highlighting
1034
- _zone_begin = ((line_begin) / @highlight_zone_length).to_i + 1
1035
- _zone_end = ((line_end) / @highlight_zone_length).to_i + 1
1036
-
1037
- (_zone_begin >=@last_zone_begin)?_zone_begin.upto(_zone_end+1){|_zone|
1038
- highlight_zone(_zone)
1039
- }:_zone_end.downto(_zone_begin-1){|_zone|
1040
- highlight_zone(_zone)
1041
- }
1042
- @last_line_begin = line_begin
1043
- @last_line_end = line_end
1044
- @last_zone_begin = _zone_begin
1045
- @last_zone_end = _zone_end
1046
- end
1047
- end
1048
- end
1049
-
1050
- def highlight_zone(_zone)
1051
- if !@highlight_zone[_zone]
1052
- _b = @highlight_zone_length*(_zone - 1)
1053
- _e = @highlight_zone_length*(_zone) + 1
1054
- for j in _b..._e
1055
- rehighlightline(j)
1056
- end
1057
- @highlight_zone[_zone] = true
1058
- end
1059
- end
1060
-
1061
- def text_see(_index=nil)
1062
- if _index
1063
- @text.see(_index)
1064
- end
1065
- end
1066
-
1067
- def text_insert_index
1068
- @text.index('insert')
1069
- end
1070
-
1071
- def text_insert(index, chars, *tags, &b)
1072
- if block_given?
1073
- instance_eval(&b)
1074
- end
1075
- _index = @text.index(index)
1076
- _row, _col = _index.split('.')
1077
- _row = (_row.to_i - 1).to_s
1078
- chars.each_line {|line|
1079
- @text.insert(_row+'.0', line, *tags)
1080
- if !defined?(m_begin)||(m_begin == nil)
1081
- m_begin = /=begin/.match(line)
1082
- end
1083
- if @highlighting
1084
- if m_begin &&(m_begin.begin(0)==0)
1085
- _ibegin = _row+'.0'
1086
- _iend = _row+'.'+(line.length - 1).to_s
1087
- @text.tag_add('comment',_ibegin, _iend)
1088
- else
1089
- highlightline(_row.to_i, line, false)
1090
- end
1091
- end
1092
- _row = (_row.to_i + 1).to_s
1093
- }
1094
- if defined?(_edit_reset)
1095
- if _edit_reset
1096
- @text.edit_reset
1097
- end
1098
- else
1099
- @text.edit_reset
1100
- end
1101
- end
1102
-
1103
- def save
1104
- if !@file
1105
- save_as
1106
- else
1107
- f = File.new(@file, "w")
1108
- begin
1109
- if f
1110
- f.syswrite(text_value)
1111
- @buffer = text_value
1112
- reset_modify
1113
- end
1114
- ensure
1115
- f.close unless f.nil?
1116
- end
1117
- EditorContract.instance.file_saved(self,'file' =>@file)
1118
- end
1119
- end
1120
-
1121
- def save_as
1122
- @file = Tk.getSaveFile("filetypes"=>[["Ruby Files", [".rb", ".rbw"]]])
1123
- @file = nil if @file == "" # cancelled
1124
- if @file
1125
- save
1126
- @controller.change_file_name(@page_frame, @file)
1127
- EditorContract.instance.file_created(self, 'file'=>@file)
1128
- end
1129
- end
1130
-
1131
- def check_modify
1132
- if modified? && !@set_mod
1133
- set_modify
1134
- else
1135
- reset_modify
1136
- end
1137
- end
1138
-
1139
- def check_file_last_access_time
1140
- if @file && @file_last_access_time
1141
-
1142
- ftime = File.mtime(@file)
1143
- if @file_last_access_time != ftime
1144
- msg = 'File "'+@file+'" is changed! Reload?'
1145
- if Tk.messageBox('icon' => 'error', 'type' => 'yesno',
1146
- 'title' => '(Arcadia) Libs', 'parent' => @text,
1147
- 'message' => msg) == 'yes'
1148
- @text.delete('1.0','end')
1149
- load_file(@file)
1150
- else
1151
- @file_last_access_time = ftime
1152
- end
1153
- end
1154
- end
1155
- end
1156
-
1157
- def init_editing(_ext='rb')
1158
- case _ext
1159
- when 'rb'
1160
- @fm = AGTkVSplittedFrames.new(@page_frame,150)
1161
- @fm1 = AGTkVSplittedFrames.new(@fm.right_frame,60)
1162
- initialize_text(@fm1.right_frame)
1163
- initialize_text_binding
1164
- initialize_highlight
1165
- initialize_line_number(@fm1.left_frame)
1166
- initialize_tree(@fm.left_frame)
1167
- when nil
1168
- @fm1 = AGTkVSplittedFrames.new(@page_frame,60)
1169
- initialize_text(@fm1.right_frame)
1170
- initialize_text_binding
1171
- initialize_highlight
1172
- initialize_line_number(@fm1.left_frame)
1173
- else
1174
- @fm1 = AGTkVSplittedFrames.new(@page_frame,60)
1175
- initialize_text(@fm1.right_frame)
1176
- initialize_text_binding
1177
- initialize_line_number(@fm1.left_frame)
1178
- end
1179
- end
1180
-
1181
- def file_extension(_filename=nil)
1182
- if _filename
1183
- _m = /(.*\.)(.*$)/.match(File.basename(_filename))
1184
- end
1185
- _ret = (_m && _m.length > 1)?_m[2]: nil
1186
- end
1187
-
1188
- def load_file(_filename = nil)
1189
- #if filename is nil then open a new tab
1190
- @file = _filename
1191
- if _filename
1192
- #init_editing(file_extension(_filename))
1193
- File::open(_filename,'r'){ |file|
1194
- @text.insert('end',file.readlines.collect!{| line | line.chomp+"\n" }.to_s)
1195
- }
1196
- end
1197
- reset
1198
- refresh
1199
- end
1200
-
1201
- def reset
1202
- @buffer = text_value
1203
- reset_modify
1204
- @text.edit_reset
1205
- end
1206
-
1207
- def refresh
1208
- build_tree if @classbrowsing
1209
- end
1210
- end
1211
-
1212
- class AgMultiEditorView
1213
- attr_reader :enb
1214
- def initialize(parent=nil)
1215
- @enb = Tk::BWidget::NoteBook.new(parent){
1216
- tabbevelsize 0
1217
- internalborderwidth 2
1218
- activeforeground 'red'
1219
- activebackground 'yellow'
1220
- #background 'black'
1221
- borderwidth 1
1222
- side $arcadia['conf']['editor.tabs.side']
1223
- font $arcadia['conf']['editor.tabs.font']
1224
- pack('fill'=>'both', :padx=>0, :pady=>0, :expand => 'yes')
1225
- }
1226
- end
1227
-
1228
- end
1229
-
1230
- class AgMultiEditor < ArcadiaExt
1231
- attr_reader :breakpoints
1232
- attr_reader :splitted_frame
1233
- def before_build
1234
- ArcadiaContractListener.new(self, DebugContract, :do_debug_event)
1235
- ArcadiaContractListener.new(self, EditorContract, :do_editor_event)
1236
- ArcadiaContractListener.new(self, MainContract, :do_main_event)
1237
- end
1238
-
1239
- def build
1240
- if @arcadia.layout.headed?
1241
- title_frame = @arcadia.layout.domain(conf('frame'))['root']
1242
- #@close_button = title_frame.add_button(nil,nil,TAB_CLOSE_GIF,'left')
1243
- end
1244
-
1245
- #@splitted_frame = AGTkOSplittedFrames.new(self.frame,20)
1246
- #@main_frame = AgMultiEditorView.new(@splitted_frame.bottom_frame)
1247
- @main_frame = AgMultiEditorView.new(self.frame)
1248
- #@close_button.bind('1',proc{close_raised})
1249
- @tabs_file =Hash.new
1250
- @tabs_editor =Hash.new
1251
- @breakpoints =Array.new
1252
- create_find
1253
- pop_up_menu
1254
- end
1255
-
1256
- def after_build
1257
- self.open_last_files
1258
- end
1259
-
1260
- def pop_up_menu
1261
- @pop_up = TkMenu.new(
1262
- :parent=>@main_frame.enb,
1263
- :tearoff=>0,
1264
- :title => 'Menu'
1265
- )
1266
- @pop_up.insert('end',
1267
- :command,
1268
- :label=>'...',
1269
- :state=>'disabled',
1270
- :background=>'blue',
1271
- :font => conf('font.bold'),
1272
- :hidemargin => true
1273
- )
1274
- @c = @pop_up.insert('end',
1275
- :command,
1276
- :label=>'Close',
1277
- :font => conf('font'),
1278
- :hidemargin => false,
1279
- :command=> proc{
1280
- if @selected_tab_name_from_popup != nil
1281
- _e = @tabs_editor[@selected_tab_name_from_popup]
1282
- self.close_editor(_e)
1283
- end
1284
- }
1285
- )
1286
- @c = @pop_up.insert('end',
1287
- :command,
1288
- :label=>'Close others',
1289
- :font => conf('font'),
1290
- :hidemargin => false,
1291
- :command=> proc{
1292
- if @selected_tab_name_from_popup != nil
1293
- _e = @tabs_editor[@selected_tab_name_from_popup]
1294
- self.close_others_editor(_e)
1295
- end
1296
- }
1297
- )
1298
- @c = @pop_up.insert('end',
1299
- :command,
1300
- :label=>'Close all',
1301
- :font => conf('font'),
1302
- :hidemargin => false,
1303
- :command=> proc{
1304
- if @selected_tab_name_from_popup != nil
1305
- _e = @tabs_editor[@selected_tab_name_from_popup]
1306
- self.close_all_editor(_e)
1307
- end
1308
- }
1309
- )
1310
-
1311
- @main_frame.enb.tabbind("Button-3",
1312
- proc{|*x|
1313
- _x = TkWinfo.pointerx(@main_frame.enb)
1314
- _y = TkWinfo.pointery(@main_frame.enb)
1315
- @selected_tab_name_from_popup = x[0].split(':')[0]
1316
- _index = @main_frame.enb.index(@selected_tab_name_from_popup)
1317
- if _index == -1
1318
- @selected_tab_name_from_popup = 'ff'+@selected_tab_name_from_popup
1319
- _index = @main_frame.enb.index(@selected_tab_name_from_popup)
1320
- end
1321
- if _index != -1
1322
- _file = @main_frame.enb.itemcget(@selected_tab_name_from_popup, 'text')
1323
- @pop_up.entryconfigure(0, 'label'=>_file)
1324
- @pop_up.popup(_x,_y)
1325
- end
1326
- })
1327
- end
1328
-
1329
-
1330
- def do_debug_event(_event)
1331
- #@arcadia.outln('_sender ----> '+_sender.to_s)
1332
- #@arcadia.outln('_event.signature ----> '+_event.signature)
1333
- case _event.signature
1334
- when DebugContract::DEBUG_BEGIN
1335
- self.debug_begin
1336
- when DebugContract::DEBUG_END
1337
- self.debug_end
1338
- when DebugContract::DEBUG_STEP
1339
- if _event.context.file
1340
- self.open_file_in_debug(_event.context.file, _event.context.line)
1341
- end
1342
- end
1343
- end
1344
-
1345
- def do_editor_event(_event)
1346
- case _event.signature
1347
- when EditorContract::OPEN_FILE
1348
- if _event.context.file
1349
- if _event.context.line
1350
- _index = _event.context.line.to_s+'.0'
1351
- end
1352
- self.open_file(_event.context.file, _index)
1353
- _event.handled(self)
1354
- end
1355
- when EditorContract::CLOSE_FILE
1356
- if _event.context.file
1357
- self.close_file(_event.context.file)
1358
- _event.handled(self)
1359
- end
1360
- when EditorContract::SAVE_FILE_RAISED
1361
- self.raised.save
1362
- _event.handled(self)
1363
- when EditorContract::SAVE_FILE
1364
- if _event.context.file
1365
- self.save_file(_event.context.file)
1366
- _event.handled(self)
1367
- end
1368
- when EditorContract::SAVE_AS_FILE_RAISED
1369
- self.raised.save_as
1370
- _event.handled(self)
1371
- when EditorContract::SAVE_AS_FILE
1372
- if _event.context.file
1373
- self.save_as_file(_event.context.file)
1374
- _event.handled(self)
1375
- end
1376
- when EditorContract::OPEN_TEXT
1377
- if _event.context.title
1378
- _tab_name = self.tab_name(_event.context.title)
1379
- self.open_buffer(_tab_name, _event.context.title)
1380
- _e = @tabs_editor[_tab_name]
1381
- _e.text_insert('end',_event.context.text) if _event.context.text
1382
- _e.reset
1383
- _e.refresh
1384
- add_reverse_item(_e)
1385
- _event.handled(self)
1386
- end
1387
- when EditorContract::SHOW_SEARCH_DIALOG
1388
- @find.show
1389
- when EditorContract::SHOW_GOTO_LINE_DIALOG
1390
- @find.show_go_to_line_dialog
1391
- end
1392
- end
1393
-
1394
- def xy_insert
1395
- _text = self.raised.text
1396
- _index_now = _text.index('insert')
1397
- _rx, _ry, _widht, _heigth = _text.bbox(_index_now);
1398
- _x = _rx + TkWinfo.rootx(_text)
1399
- _y = _ry + TkWinfo.rooty(_text) + TkFont.new(conf('font')).metrics[2][1]
1400
- _xroot = _x - TkWinfo.rootx(@arcadia.layout.root)
1401
- _yroot = _y - TkWinfo.rooty(@arcadia.layout.root)
1402
- return _xroot, _yroot
1403
- end
1404
-
1405
-
1406
-
1407
- def raise_complete_code(_context)
1408
- # delete the file used for completion
1409
- if File.exist?(_context.file) && _context.file.include?('~~')
1410
- File.delete(_context.file)
1411
- end
1412
- @raised_listbox.destroy if @raised_listbox != nil
1413
-
1414
- _text = self.raised.text
1415
- _index_call = _context.line+'.'+_context.col
1416
- _index_now = _text.index('insert')
1417
- if _index_call == _index_now
1418
- _target = _text.get('insert - 1 chars wordstart','insert')
1419
- if _target.length > 0 && _target != '.'
1420
- extra_len = _target.length.+@
1421
- _begin_index = _index_now<<' - '<<extra_len.to_s<<' chars'
1422
- _text.tag_add('sel', _begin_index, _index_now)
1423
- else
1424
- _begin_index = _index_now
1425
- extra_len = 0
1426
- end
1427
- if _context.candidates.length > 1
1428
- _rx, _ry, _widht, heigth = _text.bbox(_begin_index);
1429
- _x = _rx + TkWinfo.rootx(_text)
1430
- _y = _ry + TkWinfo.rooty(_text) + TkFont.new(conf('font')).metrics[2][1]
1431
-
1432
- _xroot = _x - TkWinfo.rootx(@arcadia.layout.root)
1433
- _yroot = _y - TkWinfo.rooty(@arcadia.layout.root)
1434
-
1435
- _max_height = TkWinfo.screenheight(@arcadia.layout.root) - _y - 5
1436
-
1437
- @raised_listbox = TkListbox.new(@arcadia.layout.root,
1438
- 'takefocus'=>true,
1439
- :background=>conf('color.background'),
1440
- :foreground=>conf('color.foreground'),
1441
- :selectbackground=>'yellow',
1442
- :selectforeground=>'red',
1443
- :activestyle=>'none',
1444
- :font => conf('font'),
1445
- :borderwidth=>1
1446
- )
1447
- _font = TkFont.new(conf('font'))
1448
- _char_height = _font.metrics[2][1]
1449
- _width = 0
1450
- _docs_entries = Hash.new
1451
- _context.candidates.each{|value|
1452
- _key, _doc = value.split
1453
- _docs_entries[_key]= _doc
1454
- @raised_listbox.insert('end', _key)
1455
- _temp_width = _font.measure(_key) + _font.measure('X')
1456
- _width = _temp_width if _temp_width > _width
1457
- }
1458
- _height = (_context.candidates.length+1)*_char_height
1459
- _height = _max_height if _height > _max_height
1460
- @raised_listbox.place('x'=>_xroot,'y'=>_yroot, 'width'=>_width, 'height'=>_height)
1461
-
1462
- @raised_listbox.focus
1463
- @raised_listbox.bind_append('KeyPress'){|e|
1464
- case e.keysym
1465
- when 'Escape'
1466
- @raised_listbox.destroy
1467
- #_menu.destroy
1468
- Tk.callback_break
1469
- when 'Return'
1470
- _value = @raised_listbox.get('active')
1471
- _text.delete(_begin_index,'insert')
1472
- _text.insert('insert',_value)
1473
- @raised_listbox.destroy
1474
- #_menu.destroy
1475
- Tk.callback_break
1476
- when 'F1'
1477
- _key = @raised_listbox.get('active')
1478
- _x, _y = xy_insert
1479
- EditorContract.instance.doc_code(self, 'doc_entry'=>_docs_entries[_key], 'xdoc'=>_x, 'ydoc'=>_y)
1480
- end
1481
- }
1482
- elsif _context.candidates.length == 1 && _context.candidates[0].length>0
1483
- _text.delete(_begin_index,'insert');
1484
- _text.insert('insert',_context.candidates[0].split[0])
1485
- end
1486
- end
1487
- end
1488
-
1489
- def do_main_event(_event)
1490
- case _event.signature
1491
- when MainContract::EVENT_HANDLED
1492
- _cause = _event.context.caused_by
1493
- if _cause.signature == EditorContract::COMPLETE_CODE &&
1494
- _cause.context.sender == self.raised
1495
- raise_complete_code(_cause.context)
1496
- elsif _cause.signature == EditorContract::DOC_CODE && _cause.context.file != nil
1497
- # delete the file used for completion
1498
- if File.exist?(_cause.context.file) && _cause.context.file.include?('~~')
1499
- File.delete(_cause.context.file)
1500
- end
1501
- end
1502
- end
1503
- end
1504
-
1505
- def add_reverse_item(_editor)
1506
- code2form = proc{
1507
- Revparsel.new(_editor.text_value)
1508
- self.close_editor(_editor, false)
1509
- InspectorContract.instance.raise_last_widget(self)
1510
- }
1511
- _editor.insert_popup_menu_item('end',
1512
- :command,
1513
- :label=>'View as form',
1514
- :hidemargin => false,
1515
- :command=> code2form
1516
- )
1517
-
1518
- end
1519
-
1520
- # def editor_state
1521
- # r = EditorContract::SObj.new
1522
- # r.raised_file = self.raised.file
1523
- # r.breakpoints = @breakpoints
1524
- # return r
1525
- # end
1526
-
1527
- def get_find
1528
- @find
1529
- end
1530
-
1531
- def create_find
1532
- #find_frame = @arcadia.layout.register_panel(conf('find.frame'),'Find', 'Find')
1533
- # @find = Find.new(@splitted_frame.top_frame, self)
1534
- @find = Find.new(@arcadia.layout.root, self)
1535
- @find.on_close=proc{@find.hide}
1536
- @find.hide
1537
- end
1538
-
1539
- def finalize
1540
- _files =''
1541
- @tabs_editor.each_value{|editor|
1542
- _files=_files+'|'+ editor.file if editor.file != nil
1543
- close_editor(editor)
1544
- }
1545
- @arcadia['pers']['editor.files.open']=_files
1546
- end
1547
-
1548
- def raised
1549
- _page = @main_frame.enb.raise
1550
- return @tabs_editor[_page]
1551
- end
1552
-
1553
- def close_raised
1554
- close_editor(@tabs_editor[@main_frame.enb.raise])
1555
-
1556
- #_page = @main_frame.enb.raise
1557
- #_editor = @tabs_editor[_page]
1558
- #_row = _editor.text_insert_index.split('.')[0].strip.to_i
1559
- #close_editor(_editor)
1560
- end
1561
-
1562
- def breakpoint_add(_file,_line)
1563
- EditorContract.instance.breakpoint_created(self, 'file'=>_file, 'line'=>_line)
1564
- @breakpoints << {:file=>_file,:line=>_line}
1565
- end
1566
-
1567
- def breakpoint_del(_file,_line)
1568
- EditorContract.instance.breakpoint_deleted(self, 'file'=>_file, 'line'=>_line)
1569
- @breakpoints.delete_if{|b| (b[:file]==_file && b[:line]==_line)}
1570
- end
1571
-
1572
- def breakpoint_lines_on_file(_file)
1573
- result = Array.new
1574
- @breakpoints.each{|value|
1575
- if value[:file]==_file
1576
- result << value[:line]
1577
- end
1578
- }
1579
- return result
1580
- end
1581
-
1582
- def open_last_files
1583
- if $arcadia['pers']['editor.files.open']
1584
- _files_index =$arcadia['pers']['editor.files.open'].split("|")
1585
- _files_index.each{|value|
1586
- _file,_index = value.split(';')
1587
- if _file
1588
- open_file(_file,_index)
1589
- end
1590
- }
1591
- end
1592
- self
1593
- end
1594
-
1595
- def bookmark_add(_file, _index)
1596
- if @bookmarks == nil
1597
- @bookmarks = Array.new
1598
- @bookmarks_index = - 1
1599
- else
1600
- _cur_file, _cur_index = @bookmarks[@bookmarks_index]
1601
- if _cur_file == _file && _cur_index == _index
1602
- #@arcadia.outln('uguale ----> '+_file+':'+_index)
1603
- return
1604
- end
1605
- @bookmarks = @bookmarks[0..@bookmarks_index]
1606
- end
1607
- @bookmarks << [_file, _index]
1608
- @bookmarks_index = @bookmarks.length - 1
1609
- #@arcadia.outln('add ----> '+_file+':'+_index)
1610
- end
1611
-
1612
- def bookmark_clear
1613
- @bookmarks.clear
1614
- @bookmarks_index = - 1
1615
- end
1616
-
1617
- def bookmark_next
1618
- return if @bookmarks == nil || @bookmarks_index >= @bookmarks.length - 1
1619
- bookmark_move(+1)
1620
- end
1621
-
1622
- def bookmark_move(_n=0)
1623
- @bookmarks_index = @bookmarks_index + _n
1624
- #Tk.messageBox('message'=>@bookmarks_index.to_s)
1625
- _file, _index = @bookmarks[@bookmarks_index]
1626
- _line, _col = _index.split('.') if _index
1627
- open_file(_file, _index)
1628
- #openfile(@bookmarks[@bookmarks_index])
1629
- end
1630
-
1631
-
1632
- def bookmark_prev
1633
- return if @bookmarks == nil || @bookmarks_index <= 0
1634
- bookmark_move(-1)
1635
- end
1636
-
1637
-
1638
- def get_tab_from_name(_name=nil)
1639
- return @main_frame.enb.get_frame(_name)
1640
- # if _name
1641
- # @tabs_name.each{
1642
- # |key,value|
1643
- # if value.to_s==_name.to_s
1644
- # return key
1645
- # end
1646
- # }
1647
- # return nil
1648
- # end
1649
- end
1650
-
1651
- def change_tab_set_modify(_tab)
1652
- _new_name = '(...)'+@main_frame.enb.itemcget(page_name(_tab), 'text')
1653
- change_tab_title(_tab, _new_name)
1654
- end
1655
-
1656
- def page_name(_page_frame)
1657
- TkWinfo.appname(_page_frame).sub('f','')
1658
- end
1659
-
1660
- def change_tab_reset_modify(_tab)
1661
- #_new_name = @main_frame.enb.itemcget(@tabs_name[_tab], 'text').gsub!("(...)",'')
1662
- _new_name = @main_frame.enb.itemcget(page_name(_tab), 'text').gsub!("(...)",'')
1663
- if _new_name
1664
- change_tab_title(_tab, _new_name)
1665
- end
1666
- end
1667
-
1668
- def change_tab_title(_tab, _new_text)
1669
- @main_frame.enb.itemconfigure(page_name(_tab), 'text'=> _new_text)
1670
- end
1671
-
1672
- def change_file_name(_tab, _new_file)
1673
- _new_label = File.basename(_new_file)
1674
- change_tab_title(_tab, _new_label)
1675
- @tabs_file[page_name(_tab)] = _new_file
1676
- end
1677
-
1678
- def debug_begin
1679
- if @editors_in_debug != nil
1680
- @editors_in_debug.clear
1681
- else
1682
- @editors_in_debug = Array.new
1683
- end
1684
- end
1685
-
1686
- def debug_end
1687
- debug_reset
1688
- @editors_in_debug.each{|e|
1689
- close_editor(e)
1690
- }
1691
- end
1692
-
1693
- def debug_reset
1694
- if @last_index && @last_e
1695
- @last_e.unmark_debug(@last_index)
1696
- end
1697
- end
1698
-
1699
- def open_file_in_debug(_filename=nil, _line=nil)
1700
- debug_reset
1701
- if _filename && _line
1702
-
1703
- @last_index = _line.to_s+'.0'
1704
- _editor_exist = editor_exist?(_filename)
1705
- @last_e = open_file(_filename, @last_index)
1706
- if !_editor_exist
1707
- @editors_in_debug << @last_e
1708
- end
1709
- @last_e.mark_debug(@last_index) if @last_e
1710
-
1711
- end
1712
- end
1713
-
1714
- def do_buffer_raise(_name, _title='...')
1715
- _index = @main_frame.enb.index(_name)
1716
- _new_caption = '...'
1717
- if _index != -1
1718
- #_name = @main_frame.enb.pages(_index)
1719
- #_tab = get_tab_from_name(_name)
1720
- #@main_frame.enb.raise(_name)
1721
- _e = @tabs_editor[_name]
1722
- if _e && _e.file != nil
1723
- _new_caption = _e.file
1724
- @find.use(_e)
1725
- _e.check_file_last_access_time
1726
- else
1727
- _new_caption = _title
1728
- end
1729
- end
1730
- if @arcadia.layout.headed?
1731
- @arcadia.layout.domain(@arcadia['conf'][@name+'.frame'])['root'].top_text(_new_caption)
1732
- end
1733
- _title = @tabs_file[_name] != nil ? File.basename(@tabs_file[_name]) :_name
1734
- EditorContract.instance.buffer_raised(self, 'title'=>_title, 'file'=>@tabs_file[_name])
1735
- end
1736
-
1737
- def editor_exist?(_filename)
1738
- _basefilename = File.basename(_filename)
1739
- #_basename = _basefilename.split('.')[0]+'_'+_basefilename.split('.')[1]
1740
-
1741
-
1742
- _index = @main_frame.enb.index(self.tab_name(_filename))
1743
- return _index != -1
1744
- end
1745
-
1746
- def tab_name(_str="")
1747
- 'ff'+_str.gsub("/","_").gsub(".","_").gsub(":","_").gsub("\\","_")
1748
- end
1749
-
1750
- def tab_file_name(_filename="")
1751
- _fstr = File.expand_path(_filename)
1752
- _fstr = _filename if _fstr == nil
1753
- tab_name(_fstr)
1754
- end
1755
-
1756
- def open_file(_filename = nil, _text_index='1.0')
1757
- return if _filename == nil || !File.exist?(_filename)
1758
- _basefilename = File.basename(_filename)
1759
- _tab_name = self.tab_file_name(_filename)
1760
- _index = @main_frame.enb.index(_tab_name)
1761
- _exist_buffer = _index != -1
1762
-
1763
- if _exist_buffer
1764
- open_buffer(_tab_name)
1765
- else
1766
- open_buffer(_tab_name, _basefilename)
1767
- # _basefilename.include?('.rb')?_image = RUBY_DOCUMENT_GIF: _image = DOCUMENT_OPEN_GIF
1768
- # @main_frame.enb.itemconfigure(_tab_name,
1769
- # 'image'=> TkPhotoImage.new('data' =>_image )
1770
- # )
1771
- @tabs_file[_tab_name]= _filename
1772
- @tabs_editor[_tab_name].load_file(_filename)
1773
- #do_buffer_raise(_tab_name)
1774
- EditorContract.instance.file_opened(self, 'file'=>_filename)
1775
- end
1776
-
1777
- if _text_index != nil && _text_index != '1.0'
1778
- @tabs_editor[_tab_name].text_see(_text_index)
1779
- @tabs_editor[_tab_name].mark_selected(_text_index)
1780
- end
1781
-
1782
- return @tabs_editor[_tab_name]
1783
- end
1784
-
1785
-
1786
- def open_buffer(_buffer_name = nil, _title = nil)
1787
- _index = @main_frame.enb.index(_buffer_name)
1788
- if _buffer_name == nil
1789
- _buffer_name = tab_name('new')
1790
- _title_new = '*new'
1791
- end
1792
-
1793
- if _index != -1
1794
- _tab = @main_frame.enb.get_frame(_buffer_name)
1795
- @main_frame.enb.raise(_buffer_name)
1796
- else
1797
- _n = 1
1798
- while @main_frame.enb.index(_buffer_name) != -1
1799
- _title_new = '*new'+_n.to_s
1800
- _buffer_name = tab_name('new')+_n.to_s
1801
- _n =_n+1
1802
- end
1803
- if _title == nil
1804
- _title = _title_new
1805
- end
1806
- _tab = @main_frame.enb.insert('end', _buffer_name ,
1807
- 'text'=> _title,
1808
- 'raisecmd'=>proc{do_buffer_raise(_buffer_name, _title)}
1809
- )
1810
- _e = AgEditor.new(self, _tab)
1811
- _e.init_editing(_e.file_extension(_title))
1812
- @tabs_file[_buffer_name]= nil
1813
- @tabs_editor[_buffer_name]=_e
1814
- end
1815
- @main_frame.enb.move(_buffer_name, 1)
1816
- @main_frame.enb.raise(_buffer_name)
1817
- @main_frame.enb.see(_buffer_name)
1818
- return _tab
1819
- end
1820
-
1821
- def close_others_editor(_editor, _mod=true)
1822
- @tabs_editor.values.each do |_e|
1823
- close_editor(_e) if _e != _editor
1824
- end
1825
- end
1826
-
1827
- def close_all_editor(_editor, _mod=true)
1828
- @tabs_editor.values.each do |_e|
1829
- close_editor(_e)
1830
- end
1831
- end
1832
-
1833
- def close_editor(_editor, _mod=true)
1834
- if ((_mod)&&(_editor.modified?))
1835
- _message = @main_frame.enb.itemcget(page_name(_editor.page_frame), 'text')+"\n modified. Save?"
1836
- _r = TkDialog2.new('message'=>_message, 'buttons'=>['Ok','No','Cancel']).show()
1837
- if _r == 0
1838
- _editor.save
1839
- elsif _r == 1
1840
- close_tab(_editor.page_frame)
1841
- elsif _r == 2
1842
- return
1843
- end
1844
- else
1845
- close_tab(_editor.page_frame)
1846
- end
1847
- EditorContract.instance.file_closed(self, 'file'=>_editor.file)
1848
- end
1849
-
1850
- def close_tab(_page_frame)
1851
- _name = page_name(_page_frame)
1852
- @tabs_editor.delete(_name)
1853
- _index = @main_frame.enb.index(_name)
1854
- @main_frame.enb.delete(_name)
1855
- if !@main_frame.enb.pages.empty?
1856
- @main_frame.enb.raise(@main_frame.enb.pages[_index-1])
1857
- end
1858
- end
1859
-
1860
- def close_file(_filename)
1861
- close_editor(@tabs_editor[tab_name(_filename)])
1862
- end
1863
-
1864
- def save_file(_filename)
1865
- @tabs_editor[tab_name(_filename)].save
1866
- end
1867
-
1868
- def save_as_file(_filename)
1869
- @tabs_editor[tab_name(_filename)].save_as
1870
- end
1871
-
1872
- end
1873
-
1874
- class Findview < TkFloatTitledFrame
1875
- def initialize(_parent)
1876
- super(_parent)
1877
- #stop_resizing
1878
- y0 = 10
1879
- d = 23
1880
- TkLabel.new(self.frame){
1881
- text 'Find what:'
1882
- place('x' => 8,'y' => y0,'height' => 19)
1883
- }
1884
- y0 = y0 + d
1885
- @e_what = Tk::BWidget::ComboBox.new(self.frame){
1886
- editable true
1887
- justify 'left'
1888
- relief 'ridge'
1889
- autocomplete 'true'
1890
- #insertbackground '#FFFFFF'
1891
- entrybg '#FFFFFF'
1892
- expand 'tab'
1893
- takefocus 'true'
1894
- #pack('padx'=>10, 'fill'=>'x')
1895
- place('relwidth' => 1, 'width'=>-16,'x' => 8,'y' => y0,'height' => 19)
1896
- }
1897
- y0 = y0 + d
1898
- TkLabel.new(self.frame){
1899
- text 'Replace with:'
1900
- place('x' => 8,'y' => y0,'height' => 19)
1901
- }
1902
- y0 = y0 + d
1903
-
1904
- @e_with = Tk::BWidget::ComboBox.new(self.frame){
1905
- editable true
1906
- justify 'left'
1907
- relief 'ridge'
1908
- autocomplete 'true'
1909
- #insertbackground '#FFFFFF'
1910
- entrybg '#FFFFFF'
1911
- expand 'tab'
1912
- takefocus 'true'
1913
- #pack('padx'=>10, 'fill'=>'x')
1914
- place('relwidth' => 1, 'width'=>-16,'x' => 8,'y' => y0,'height' => 19)
1915
- }
1916
-
1917
- y0 = y0 + d
1918
- @cb_reg = TkCheckButton.new(self.frame){|_cb_reg|
1919
- text 'Use Regular Expression'
1920
- justify 'left'
1921
- relief 'flat'
1922
- #pack('side'=>'left', 'anchor'=>'e')
1923
- place('x' => 8,'y' => y0,'height' => 22)
1924
- }
1925
- y0 = y0 + d
1926
- @cb_back = TkCheckButton.new(self.frame){|_cb_reg|
1927
- text 'Search backwards'
1928
- justify 'left'
1929
- relief 'flat'
1930
- #pack('side'=>'left', 'anchor'=>'e')
1931
- place('x' => 8,'y' => y0,'height' => 22)
1932
- }
1933
-
1934
- y0 = y0 + d
1935
- y0 = y0 + d
1936
- @buttons_frame = TkFrame.new(self.frame).pack('fill'=>'x', 'side'=>'bottom')
1937
-
1938
- @b_replace_all = TkButton.new(@buttons_frame){|_b_go|
1939
- state 'disabled'
1940
- default 'disabled'
1941
- text 'Replace All'
1942
- overrelief 'raised'
1943
- justify 'center'
1944
- #width 15
1945
- pack('side'=>'right','ipadx'=>5, 'padx'=>5)
1946
- #place('width' => 50,'x' => 0,'y' => y0,'height' => 23,'bordermode' => 'inside')
1947
- }
1948
-
1949
-
1950
- @b_replace = TkButton.new(@buttons_frame){|_b_go|
1951
- state 'disabled'
1952
- default 'disabled'
1953
- text 'Replace'
1954
- overrelief 'raised'
1955
- justify 'center'
1956
- #width 15
1957
- pack('side'=>'right','ipadx'=>5, 'padx'=>5)
1958
- #place('width' => 50,'x' => 0,'y' => y0,'height' => 23,'bordermode' => 'inside')
1959
- }
1960
-
1961
-
1962
- @b_go = TkButton.new(@buttons_frame){|_b_go|
1963
- compound 'none'
1964
- default 'disabled'
1965
- text 'Find Next'
1966
- #background '#ffffff'
1967
- #image TkPhotoImage.new('dat' => FIND_GIF)
1968
- overrelief 'raised'
1969
- justify 'center'
1970
- #relief 'ridge'
1971
- #width 15
1972
- pack('side'=>'right','ipadx'=>5, 'padx'=>5)
1973
- #place('width' => 50,'x' => 0,'y' => y0,'height' => 23,'bordermode' => 'inside')
1974
- }
1975
- #place('x'=>0,'y'=>0,'relheight'=> 1,'relwidth'=> 1)
1976
- place('x'=>100,'y'=>100,'height'=> 220,'width'=> 300)
1977
-
1978
- end
1979
- end
1980
-
1981
- class Find < Findview
1982
- attr_reader :e_what
1983
- def initialize(_frame, _controller)
1984
- super(_frame)
1985
- #@l_file.configure('text'=>_title)
1986
- #Tk.tk_call('wm', 'title', self, _title )
1987
- @controller = _controller
1988
- @forwards = true
1989
- @find_action = proc{
1990
- #_radio = @rb.get_value
1991
-
1992
- #if _radio == 'line'
1993
- # go_line
1994
- #else
1995
- do_find_next
1996
- #end
1997
- }
1998
- @b_go.bind('1', @find_action)
1999
-
2000
- @b_replace.bind('1', proc{do_replace})
2001
-
2002
- @b_replace_all.bind('1', proc{do_replace_all})
2003
-
2004
- e = TkWinfo.children(@e_what)[0]
2005
- e.bind_append('KeyPress'){|e|
2006
- case e.keysym
2007
- when 'Return'
2008
- @find_action.call
2009
- hide
2010
- @editor_caller.text.focus
2011
- Tk.callback_break
2012
- else
2013
- widget_state
2014
- end
2015
- }
2016
- e2 = TkWinfo.children(@e_with)[0]
2017
- e2.bind_append('KeyPress'){|e|
2018
- widget_state
2019
- }
2020
- @last_index='insert'
2021
-
2022
- @goto_line_dialog = GoToLine.new(_frame).hide
2023
- @goto_line_dialog.on_close=proc{@goto_line_dialog.hide}
2024
-
2025
- @goto_line_dialog.b_go.bind('1',proc{go_line})
2026
- end
2027
-
2028
- def do_replace
2029
- if do_find_next
2030
- _message = 'Replace "'+@e_what.value+'" with "'+@e_with.value+'" ?'
2031
- if TkDialog2.new('message'=>_message, 'buttons'=>['Yes','No']).show() == 0
2032
- self.editor.text.delete(@idx1,@idx2)
2033
- self.editor.text.insert(@idx1,@e_with.value)
2034
- self.editor.check_modify
2035
- end
2036
- end
2037
- end
2038
-
2039
- def do_replace_all
2040
- while do_find_next
2041
- _message = 'Replace "'+@e_what.value+'" with "'+@e_with.value+'" ?'
2042
- _rc = TkDialog2.new('message'=>_message, 'buttons'=>['Yes','No','Annulla']).show()
2043
- if _rc == 0
2044
- self.editor.text.delete(@idx1,@idx2)
2045
- self.editor.text.insert(@idx1,@e_with.value)
2046
- self.editor.check_modify
2047
- elsif _rc == 2
2048
- break
2049
- end
2050
- end
2051
- end
2052
-
2053
- def widget_state
2054
- if (@e_what.value.length > 0) && (@e_with.value.length > 0)
2055
- @b_replace.configure('state'=>'active')
2056
- @b_replace_all.configure('state'=>'active')
2057
- else
2058
- @b_replace.configure('state'=>'disabled')
2059
- @b_replace_all.configure('state'=>'disabled')
2060
- end
2061
- end
2062
-
2063
-
2064
- def editor
2065
- if @editor_caller == nil
2066
- @editor_caller = @controller.raised
2067
- end
2068
- return @editor_caller
2069
- end
2070
-
2071
- def show_go_to_line_dialog
2072
- @goto_line_dialog.show
2073
- end
2074
-
2075
- def go_line
2076
- if @goto_line_dialog.e_line.value.length > 0
2077
- _row = @goto_line_dialog.e_line.value
2078
- _index = _row+'.1'
2079
- self.editor.text.see(_index)
2080
- self.editor.text.tag_add('sel', _index,_index+' lineend')
2081
- self.editor.text.set_insert(_index)
2082
- @controller.bookmark_add(self.editor.file, _index)
2083
- @goto_line_dialog.hide
2084
- end
2085
- #self.hide()
2086
- end
2087
-
2088
- def use(_editor)
2089
- if (_editor != @editor_caller)
2090
- @last_index='insert'
2091
- @editor_caller = _editor
2092
- title(_editor.file)
2093
- end
2094
- end
2095
-
2096
- def update_combo(_txt)
2097
- values = @e_what.cget('values')
2098
- if (values != nil && !values.include?(_txt))
2099
- @e_what.insert('end', @e_what.value)
2100
- end
2101
- end
2102
-
2103
- def do_find(_istart=nil)
2104
- @forwards = @cb_back.cget('onvalue') != @cb_back.cget('variable').value.to_i
2105
- _found = false
2106
- @idx1 = nil
2107
- @idx2 = nil
2108
- if @e_what.text.length > 0
2109
- update_combo(@e_what.text)
2110
- if !_istart && self.editor.text.index('insert')!=nil
2111
- _istart ='insert'
2112
- elsif defined?(@last_index)
2113
- _istart = @last_index
2114
- else
2115
- _istart = '1.0'
2116
- end
2117
- if @forwards
2118
- if @cb_reg.cget('onvalue')==@cb_reg.cget('variable').value.to_i
2119
- _index = self.editor.text.tksearch(['regexp'],@e_what.text,_istart)
2120
- else
2121
- _index = self.editor.text.search(@e_what.text,_istart)
2122
- end
2123
- else
2124
-
2125
- if @cb_reg.cget('onvalue')==@cb_reg.cget('variable').value.to_i
2126
- _index = self.editor.text.tksearch(['regexp','backwards'],@e_what.text,_istart)
2127
- else
2128
- _index = self.editor.text.tksearch(['backwards'],@e_what.text,_istart)
2129
- end
2130
- end
2131
- if _index && _index.length>0
2132
- self.editor.text.see(_index)
2133
- _row, _col = _index.split('.')
2134
- _index_sel_end = _row.to_i.to_s+'.'+(_col.to_i+@e_what.text.length).to_i.to_s
2135
- if @forwards
2136
- @last_index= _index_sel_end
2137
- else
2138
- @last_index= _row.to_i.to_s+'.'+(_col.to_i-1).to_i.to_s
2139
- end
2140
- self.editor.text.tag_add('sel', _index,_index_sel_end)
2141
- self.editor.text.set_insert(_index)
2142
- @idx1 =_index
2143
- @idx2 =_index_sel_end
2144
- _found = true
2145
- @controller.bookmark_add(self.editor.file, _index)
2146
- else
2147
- _message = '"'+@e_what.value+'" not found'
2148
- TkDialog2.new('message'=>_message, 'buttons'=>['Ok']).show()
2149
- end
2150
-
2151
- else
2152
- self.show()
2153
- end
2154
- return _found
2155
- end
2156
-
2157
- def do_find_next
2158
- if @idx1 != nil
2159
- self.editor.text.tag_remove('sel',@idx1,@idx2)
2160
- end
2161
- do_find(@last_index)
2162
- end
2163
- end
2164
-
2165
-
2166
- class KeyTestView < TkToplevel
2167
- attr_reader :ttest
2168
- def initialize
2169
- super
2170
-
2171
- Tk.tk_call('wm', 'title', self, '...hello' )
2172
- Tk.tk_call('wm', 'geometry', self, '638x117+200+257' )
2173
-
2174
- @ttest = TkText.new(self){
2175
- background '#FFF454'
2176
- place('relwidth' => '1','relx' => 0,'x' => '0','y' => '0','relheight' => '1','rely' => 0,'height' => '0','bordermode' => 'inside','width' => '0')
2177
- }
2178
-
2179
- end
2180
- end
2181
-
2182
- class KetTest
2183
- def initialize
2184
- kt = KeyTestView.new
2185
- kt.ttest.bind("KeyPress"){|e|
2186
- kt.ttest.insert('end'," [ "+e.keysym+" ] ")
2187
- break
2188
- }
2189
- end
2190
- end
2191
-
2192
- class CodeInsight
2193
- end
2194
-
2195
- class GoToLine < TkFloatTitledFrame
2196
- attr_reader :e_line
2197
- attr_reader :b_go
2198
- def initialize(_parent)
2199
- super(_parent)
2200
- #stop_resizing
2201
- y0 = 10
2202
- d = 23
2203
- TkLabel.new(self.frame){
2204
- text 'Go to line:'
2205
- place('x' => 8,'y' => y0,'height' => 19)
2206
- }
2207
- y0 = y0 + d
2208
- @e_line = TkEntry.new(self.frame){
2209
- justify 'left'
2210
- relief 'ridge'
2211
- place('relwidth' => 1, 'width'=>-16,'x' => 8,'y' => y0,'height' => 19)
2212
- }
2213
-
2214
- y0 = y0 + d
2215
- y0 = y0 + d
2216
- @buttons_frame = TkFrame.new(self.frame).pack('fill'=>'x', 'side'=>'bottom')
2217
-
2218
- @b_go = TkButton.new(@buttons_frame){|_b_go|
2219
- compound 'none'
2220
- default 'disabled'
2221
- text 'Go'
2222
- overrelief 'raised'
2223
- justify 'center'
2224
- pack('side'=>'right','ipadx'=>5, 'padx'=>5)
2225
- }
2226
- place('x'=>150,'y'=>150,'height'=> 120,'width'=> 100)
2227
-
2228
- end
2229
- end
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
+ @font = @controller.conf('font')
41
+ @font_bold = @controller.conf('font.bold')
42
+ @font_metrics = TkFont.new(@font).metrics
43
+ @font_metrics_bold = TkFont.new(@font_bold).metrics
44
+ @highlighting = false
45
+ @classbrowsing = false
46
+ @find = @controller.get_find
47
+ end
48
+
49
+ def initialize_tree(_frame)
50
+ @classbrowsing = true
51
+ @nb = Tk::BWidget::NoteBook.new(_frame){
52
+ tabbevelsize 0
53
+ internalborderwidth 0
54
+ activeforeground 'red'
55
+ activebackground 'yellow'
56
+ borderwidth 1
57
+ side $arcadia['conf']['editor.explorer_panel.tabs.side']
58
+ font $arcadia['conf']['editor.tabs.font']
59
+ pack('fill'=>'both', :padx=>0, :pady=>0, :expand => 'yes')
60
+ }
61
+ @nb_tab_exp = @nb.insert('end','exp' ,'text'=>'Source Tree' )
62
+ @nb.raise('exp')
63
+ _tree_goto = proc{|_self|
64
+ _line = _self.selection_get[0]
65
+ _index =_line.to_s+'.0'
66
+ _hinner_text = @tree_exp.itemcget(_line,'text').strip
67
+ _editor_line = @text.get(_index, _index+ ' lineend')
68
+ if !_editor_line.include?(_hinner_text)
69
+ MsgContract.instance.out_simple(self, "... rebuild tree \n")
70
+ if @tree_thread && @tree_thread.alive?
71
+ @tree_thread.exit
72
+ end
73
+ @tree_thread = Thread.new{
74
+ build_tree(_line)
75
+ Tk.update
76
+ }
77
+ _line = _self.selection_get[0]
78
+ _index =_line.to_s+'.0'
79
+ end
80
+ @text.see(_index)
81
+ @text.tag_remove('selected','1.0','end')
82
+ @text.tag_add('selected',_line.to_s+'.0',(_line+1).to_s+'.0')
83
+ }
84
+ @tree_exp = Tk::BWidget::Tree.new(@nb_tab_exp){
85
+ background '#FFFFFF'
86
+ relief 'flat'
87
+ showlines false
88
+ deltay 18
89
+ dragenabled true
90
+ selectcommand proc{ _tree_goto.call(self) }
91
+ place('relwidth' => 1,'relx' => 0,'x' => '0','y' => '0','relheight' => '1','rely' => 0,'height' => 1,'bordermode' => 'inside','width' => '50')
92
+ }
93
+
94
+ _c_explo = proc{|*args| @tree_exp.yview(*args)}
95
+ _s_explo = TkScrollbar.new(@nb_tab_exp){|s|
96
+ width 8
97
+ command _c_explo
98
+ }.pack('side'=>'right', 'fill'=>'y')
99
+ @tree_exp.yscrollcommand proc{|first,last| _s_explo.set first,last}
100
+ pop_up_menu_tree
101
+ end
102
+
103
+ def pop_up_menu_tree
104
+ @pop_up_tree = TkMenu.new(
105
+ :parent=>@tree_exp,
106
+ :title => 'Menu tree'
107
+ )
108
+ @pop_up_tree.insert('end',
109
+ :command,
110
+ :label=>'Rebuild',
111
+ :hidemargin => false,
112
+ :command=> proc{build_tree}
113
+ )
114
+ @tree_exp.bind_append("Button-3",
115
+ proc{|x,y|
116
+ _x = TkWinfo.pointerx(@tree_exp)
117
+ _y = TkWinfo.pointery(@tree_exp)
118
+ @pop_up_tree.popup(_x,_y)
119
+ },
120
+ "%x %y")
121
+ end
122
+
123
+
124
+ def initialize_text(_frame)
125
+ @v_scroll = TkScrollbar.new(_frame,
126
+ 'orient'=>'vertical',
127
+ 'relief'=>'flat'
128
+ ).pack('side' => 'right', 'fill' => 'y')
129
+ @text = TkText.new(@fm1.right_frame){|j|
130
+ wrap 'none'
131
+ relief 'flat'
132
+ undo true
133
+ insertofftime 200
134
+ insertontime 200
135
+ insertbackground $arcadia['conf']['editor.color.insertbackground']
136
+ background $arcadia['conf']['editor.color.background']
137
+ foreground $arcadia['conf']['editor.color.foreground']
138
+ insertwidth 3
139
+ exportselection true
140
+ autoseparators true
141
+ padx 0
142
+ tabs $arcadia['conf']['editor.tabs']
143
+ place(
144
+ 'x'=>0,
145
+ 'y'=>0,
146
+ 'width' => -15,
147
+ 'relheight'=>1,
148
+ 'relwidth'=>1,
149
+ 'bordermode'=>'outside'
150
+ )
151
+ }
152
+ @text.configure('font', @font);
153
+
154
+ @text.tag_configure('eval','foreground' => 'yellow', 'background' =>'red','borderwidth'=>1, 'relief'=>'raised')
155
+ @text.tag_configure('errline','borderwidth'=>1, 'relief'=>'groove')
156
+ @text.tag_configure('debug', 'background' =>'#b9c6d9', 'borderwidth'=>1 ,'relief'=>'raise')
157
+ #@text.tag_configure('debug', 'background' =>'#ffd2ff', 'borderwidth'=>1 ,'relief'=>'raise')
158
+ @buffer = text_value
159
+ pop_up_menu
160
+ end
161
+
162
+ def create_temp_file
163
+ _file = @file+'~~'
164
+ f = File.new(@file+'~~', "w")
165
+ begin
166
+ if f
167
+ f.syswrite(text_value)
168
+ end
169
+ ensure
170
+ f.close unless f.nil?
171
+ end
172
+ _file
173
+ end
174
+
175
+ def initialize_text_binding
176
+ @v_scroll.command(proc{|*args|
177
+ @text.yview *args
178
+ })
179
+ @text.yscrollcommand(proc{|first,last| @v_scroll.set(first,last)
180
+ self.do_line_update()
181
+ })
182
+ @text.tag_bind('selected', 'Enter', proc{@text.tag_remove('selected','1.0','end')})
183
+
184
+ @text.bind("Enter", proc{check_file_last_access_time})
185
+ @text.bind("ButtonPress-1", proc{
186
+ _code = $arcadia['palette'].give_me_code
187
+ @text.insert('insert', _code) if _code
188
+ })
189
+
190
+ @text.bind("Control-KeyPress"){|e|
191
+ case e.keysym
192
+ when 'space'
193
+ line, col = @text.index('insert').split('.')
194
+ _file = create_temp_file
195
+ EditorContract.instance.complete_code(self, 'file'=>_file, 'line'=>line.to_s, 'col'=>col.to_s)
196
+ when 'z'
197
+ _b = @text.index('insert').split('.')[0].to_i
198
+ @text.edit_undo
199
+ _e = @text.index('insert').split('.')[0].to_i
200
+ if @highlighting
201
+ for j in _b..._e
202
+ rehighlightline(j)
203
+ end
204
+ end
205
+ break
206
+ when 'c'
207
+ @text.text_copy
208
+ break
209
+ when 'x'
210
+ @text.text_cut
211
+ break
212
+ when 'v'
213
+ _b = @text.index('insert').split('.')[0].to_i
214
+ @text.text_paste
215
+ _e = @text.index('insert').split('.')[0].to_i
216
+ if @highlighting
217
+ for j in _b..._e
218
+ rehighlightline(j)
219
+ end
220
+ end
221
+ break
222
+ end
223
+ case e.keysym
224
+ when 's'
225
+ save
226
+ when 'f'
227
+ _r = @text.tag_ranges('sel')
228
+ if _r.length>0
229
+ _text=@text.get(_r[0][0],_r[0][1])
230
+ if _text.length > 0
231
+ @find.e_what.text(_text)
232
+ end
233
+ else
234
+ end
235
+ @find.use(self)
236
+ @find.e_what.focus
237
+ @find.show
238
+ when 'egrave'
239
+ @text.insert('insert',"{")
240
+ when 'plus'
241
+ @text.insert('insert',"}")
242
+ end
243
+ }
244
+
245
+ @text.bind("Control-Shift-KeyPress"){|e|
246
+ case e.keysym
247
+ when 'I'
248
+ _r = @text.tag_ranges('sel')
249
+ _row_begin = _r[0][0].split('.')[0].to_i
250
+ _row_end = _r[_r.length - 1][1].split('.')[0].to_i
251
+ n_space = $arcadia['conf']['editor.tab-replace-width-space'].to_i
252
+ if n_space > 0
253
+ suf = "\s"*n_space
254
+ else
255
+ suf = "\t"
256
+ end
257
+
258
+ for _row in _row_begin..._row_end
259
+ @text.insert(_row.to_s+'.0',suf)
260
+ end
261
+ when 'U'
262
+ _r = @text.tag_ranges('sel')
263
+ _row_begin = _r[0][0].split('.')[0].to_i
264
+ _row_end = _r[_r.length - 1][1].split('.')[0].to_i
265
+ n_space = $arcadia['conf']['editor.tab-replace-width-space'].to_i
266
+ if n_space > 0
267
+ suf = "\s"*n_space
268
+ else
269
+ suf = "\t"
270
+ end
271
+ _l_suf = suf.length.to_s
272
+ for _row in _row_begin..._row_end
273
+ if @text.get(_row.to_s+'.0',_row.to_s+'.'+_l_suf) == suf
274
+ @text.delete(_row.to_s+'.0',_row.to_s+'.'+_l_suf)
275
+ end
276
+ end
277
+ when 'C'
278
+ _r = @text.tag_ranges('sel')
279
+ _row_begin = _r[0][0].split('.')[0].to_i
280
+ _row_end = _r[_r.length - 1][1].split('.')[0].to_i
281
+
282
+ for _row in _row_begin..._row_end
283
+ if @text.get(_row.to_s+'.0',_row.to_s+'.1') == "#"
284
+ @text.delete(_row.to_s+'.0',_row.to_s+'.1')
285
+ else
286
+ @text.insert(_row.to_s+'.0',"#")
287
+ end
288
+ rehighlightline(_row) if @highlighting
289
+ end
290
+
291
+ end
292
+ }
293
+
294
+ @text.bind("KeyPress"){|e|
295
+ case e.keysym
296
+ #when 'Return'
297
+ when 'BackSpace'
298
+ _index = @text.index('insert')
299
+ _row, _col = _index.split('.')
300
+ rehighlightline(_row.to_i) if @highlighting
301
+ when 'Delete'
302
+ _index = @text.index('insert')
303
+ _row, _col = _index.split('.')
304
+ rehighlightline(_row.to_i) if @highlighting
305
+ when 'F5'
306
+ save
307
+ $arcadia['shell'].run(@file.to_s)
308
+ when 'F3'
309
+ @find.do_find_next
310
+ when 'F1'
311
+ line, col = @text.index('insert').split('.')
312
+ _file = create_temp_file
313
+ _x, _y = @controller.xy_insert
314
+ EditorContract.instance.doc_code(@controller, 'file'=>_file, 'line'=>line.to_s, 'col'=>col.to_s, 'xdoc'=>_x, 'ydoc'=>_y)
315
+ when 'Tab'
316
+ n_space = $arcadia['conf']['editor.tab-replace-width-space'].to_i
317
+ _r = @text.tag_ranges('sel')
318
+ if _r && _r[0]
319
+ _row_begin = _r[0][0].split('.')[0].to_i
320
+ _row_end = _r[_r.length - 1][1].split('.')[0].to_i
321
+ if n_space > 0
322
+ suf = "\s"*n_space
323
+ else
324
+ suf = "\t"
325
+ end
326
+ for _row in _row_begin..._row_end
327
+ @text.insert(_row.to_s+'.0', suf)
328
+ end
329
+ break
330
+ elsif n_space > 0
331
+ @text.insert('insert', "\s"*n_space)
332
+ break
333
+ end
334
+ end
335
+ }
336
+
337
+ @text.bind("KeyRelease"){|e|
338
+ case e.keysym
339
+ when 'Control_L','Return', 'Control_V', 'BackSpace', 'Delete'
340
+ if modified?
341
+ set_modify
342
+ else
343
+ reset_modify
344
+ end
345
+ do_line_update
346
+ when 'Right','Left','Down', 'Up'
347
+ # do nil
348
+ else
349
+ check_modify
350
+ end
351
+
352
+ case e.keysym
353
+ when 'Return'
354
+ _index = @text.index('insert')
355
+ _row, _col = _index.split('.')
356
+ _txt = @text.get((_row.to_i-1).to_s+'.0',_index)
357
+ if _txt.length > 0
358
+ m = /\s*/.match(_txt)
359
+ if m
360
+ if (m[0] != "\n")
361
+ _sm = m[0]
362
+ _sm = _sm.sub(/\n/,"")
363
+ @text.insert('insert',_sm)
364
+ end
365
+ end
366
+ end
367
+ if _row.to_i + 1 == @text.index('end').split('.')[0].to_i
368
+ do_line_update
369
+ end
370
+ else
371
+ if @highlighting && /\w/.match(e.keysym)
372
+ rehighlightline(@text.index('insert').split('.')[0].to_i)
373
+ end
374
+ end
375
+ }
376
+
377
+
378
+ @text.bind("Shift-KeyPress"){|e|
379
+ case e.keysym
380
+ when 'Tab'
381
+ _r = @text.tag_ranges('sel')
382
+ if _r && _r[0]
383
+ _row_begin = _r[0][0].split('.')[0].to_i
384
+ _row_end = _r[_r.length - 1][1].split('.')[0].to_i
385
+
386
+ n_space = $arcadia['conf']['editor.tab-replace-width-space'].to_i
387
+ if n_space > 0
388
+ suf = "\s"*n_space
389
+ else
390
+ suf = "\t"
391
+ n_space = 1
392
+ end
393
+ for _row in _row_begin..._row_end
394
+ if @text.get(_row.to_s+'.0',_row.to_s+'.'+n_space.to_s) == suf
395
+ @text.delete(_row.to_s+'.0',_row.to_s+'.'+n_space.to_s)
396
+ end
397
+ end
398
+ break
399
+ end
400
+ end
401
+ }
402
+
403
+ end
404
+
405
+ def initialize_line_number(_frame)
406
+ @text_line_num = TkText.new(_frame){
407
+ wrap 'none'
408
+ relief 'flat'
409
+ undo false
410
+ takefocus 0
411
+ insertofftime 0
412
+ exportselection true
413
+ autoseparators true
414
+ cursor nil
415
+ insertwidth 0
416
+ background $arcadia['conf']['editor.line_number_panel.color.background']
417
+ foreground $arcadia['conf']['editor.line_number_panel.color.foreground']
418
+ place(
419
+ 'x'=>0,
420
+ 'y'=>0,
421
+ 'relheight'=>1,
422
+ 'relwidth'=>1,
423
+ 'bordermode'=>'outside'
424
+ )
425
+ }
426
+ delta = @font_metrics_bold[2][1]-@font_metrics[2][1]
427
+ @text_line_num.tag_configure('bold_case', 'spacing1'=>delta)
428
+ @text_line_num.tag_configure('breakpoint', 'background'=>'red','foreground'=>'yellow','borderwidth'=>1, 'relief'=>'raised')
429
+ @text_line_num.tag_configure('sel',
430
+ 'background'=>$arcadia['conf']['editor.line_number_panel.color.background'],
431
+ 'foreground'=>$arcadia['conf']['editor.line_number_panel.color.foreground'])
432
+ @text_line_num.bind("Double-ButtonPress-1", proc{|x,y|
433
+ _index = @text_line_num.index("@#{x},#{y}")
434
+ _line = @text_line_num.get(_index+' linestart',_index+' lineend').strip
435
+ if @controller.breakpoint_lines_on_file(@file).include?(_line)
436
+ @text_line_num.tag_remove('breakpoint',_index+' linestart',_index+' lineend')
437
+ @controller.breakpoint_del(@file, _line)
438
+ else
439
+ @text_line_num.tag_add('breakpoint',_index+' linestart',_index+' lineend')
440
+ # @text_line_num.tag_add('breakpoint',_index+' linestart',_index+' linestart + 1 chars')
441
+ @controller.breakpoint_add(@file, _line)
442
+ end
443
+ },
444
+ "%x %y")
445
+
446
+ @text_line_num.configure('font', @font);
447
+ @text_line_num.tag_configure('line_num',
448
+ 'foreground' => '#FFFFFF',
449
+ 'background' =>'#0000a0',
450
+ 'borderwidth'=>2,
451
+ 'relief'=>'raised'
452
+ )
453
+ end
454
+
455
+ def initialize_highlight
456
+ @highlighting = true
457
+ @highlight_zone = Hash.new;
458
+ # @highlight_zone_length = 45;
459
+ @highlight_zone_length = 8;
460
+ @last_line_begin = 0
461
+ @last_line_end = 0
462
+ @last_zone_begin=0;
463
+ @last_zone_end=0;
464
+ @is_line_bold = Hash.new
465
+ @is_tag_bold = Hash.new
466
+
467
+ @keyword = ['__FILE__', 'and', 'def', 'end', 'in', 'or', 'self', 'unless',
468
+ '__LINE__', 'begin', 'defined?', 'ensure', 'module', 'redo', 'super', 'until',
469
+ 'BEGIN', 'break', 'do', 'false', 'next', 'rescue', 'then', 'when',
470
+ 'END', 'case', 'else', 'for', 'nil', 'retry', 'true', 'while',
471
+ 'alias', 'class', 'elsif', 'if', 'not', 'return', 'undef', 'yield','require','include']
472
+ _re_string = ''
473
+ @keyword.each{|word|
474
+ if _re_string.length > 0
475
+ _re_string << '|'
476
+ end
477
+ if ['class','module','def'].include?(word)
478
+ _re_string << '([\s]*'+word+'[\s])'
479
+ else
480
+ _re_string << '\b('+word+')([.,+\(\s])'
481
+ end
482
+ }
483
+ @re_keyword = Regexp::new(_re_string)
484
+ @re_instance_variable = /([\s]*@)[A-Za-z0-9_]*/
485
+ @re_string = /'([\/A-Za-z0-9_@+\-!?=<>\[\]\{\}\(\).\s]*)'|"([\/A-Za-z0-9_@+\-!?=<>\[\]\{\}\(\).\s]*)"/
486
+ @re_number = /\d/
487
+ @re_operator = /[\(\)\[\]\(\)\{\}.:;,=><|]/
488
+ @re_method_name = /(def[\s][\s]*)[A-Za-z0-9_]*/
489
+ @re_class_name = /(class[\s][\s]*)[A-Za-z0-9_]*/
490
+ @re_module_name = /(module[\s][\s]*)[A-Za-z0-9_]*/
491
+ do_tag_configure('keyword')
492
+ do_tag_configure('method_name')
493
+ do_tag_configure('instance_variable')
494
+ do_tag_configure('class_name')
495
+ do_tag_configure('module_name')
496
+ do_tag_configure('comment')
497
+ do_tag_configure('string')
498
+ do_tag_configure('number')
499
+ do_tag_configure('sel')
500
+ do_tag_configure('selected')
501
+ do_tag_configure('operator')
502
+ do_tag_configure('tabs')
503
+ do_tag_configure('spaces')
504
+ end
505
+
506
+ def do_tag_configure(_name)
507
+ h = Hash.new
508
+ if $arcadia['conf']['editor.hightlight.'+_name+'.color.foreground']
509
+ h['foreground']=$arcadia['conf']['editor.hightlight.'+_name+'.color.foreground']
510
+ end
511
+ if $arcadia['conf']['editor.hightlight.'+_name+'.color.background']
512
+ h['background']=$arcadia['conf']['editor.hightlight.'+_name+'.color.background']
513
+ end
514
+ if $arcadia['conf']['editor.hightlight.'+_name+'.style']== 'bold'
515
+ h['font']=@font_bold
516
+ @is_tag_bold[_name]= true
517
+ end
518
+ if $arcadia['conf']['editor.hightlight.'+_name+'.relief']
519
+ h['relief']=$arcadia['conf']['editor.hightlight.'+_name+'.relief']
520
+ end
521
+ if $arcadia['conf']['editor.hightlight.'+_name+'.borderwidth']
522
+ h['borderwidth']=$arcadia['conf']['editor.hightlight.'+_name+'.borderwidth']
523
+ end
524
+ @text.tag_configure(_name, h)
525
+ end
526
+
527
+ def pop_up_menu
528
+ @pop_up = TkMenu.new(
529
+ :parent=>@text,
530
+ :tearoff=>1,
531
+ :title => 'Menu'
532
+ )
533
+ @pop_up.insert('end',
534
+ :command,
535
+ :label=>'Save as',
536
+ :hidemargin => false,
537
+ :command=> proc{save_as}
538
+ )
539
+ @pop_up.insert('end',
540
+ :command,
541
+ :label=>'Save',
542
+ :hidemargin => false,
543
+ :command=> proc{save}
544
+ )
545
+
546
+ @pop_up.insert('end',
547
+ :command,
548
+ :label=>'Close',
549
+ :hidemargin => false,
550
+ :command=> proc{@controller.close_editor(self)}
551
+ )
552
+
553
+ @pop_up.insert('end',
554
+ :command,
555
+ :label=>'Close others',
556
+ :hidemargin => false,
557
+ :command=> proc{@controller.close_others_editor(self)}
558
+ )
559
+
560
+ @pop_up.insert('end',
561
+ :command,
562
+ :label=>'Close all',
563
+ :hidemargin => false,
564
+ :command=> proc{@controller.close_all_editor(self)}
565
+ )
566
+
567
+
568
+ @pop_up.insert('end', :separator)
569
+
570
+ @pop_up.insert('end',
571
+ :command,
572
+ :label=>'Color',
573
+ :hidemargin => false,
574
+ :command=> proc{
575
+ @text.insert('insert',Tk.chooseColor)
576
+ }
577
+ )
578
+ @pop_up.insert('end',
579
+ :command,
580
+ :label=>'Font',
581
+ :hidemargin => false,
582
+ :command=> proc{
583
+ @text.insert('insert', $arcadia['action.get.font'].call)
584
+ }
585
+ )
586
+
587
+
588
+ @pop_up.insert('end', :separator)
589
+
590
+ #---- debug menu
591
+ _sub_debug = TkMenu.new(
592
+ :parent=>@pop_up,
593
+ :tearoff=>0,
594
+ :title => 'Debug'
595
+ )
596
+
597
+ _sub_debug.insert('end',
598
+ :command,
599
+ :label=>'Eval selected',
600
+ :hidemargin => false,
601
+ :command=> proc{
602
+ _r = @text.tag_ranges('sel')
603
+ if _r.length>0
604
+ _text=@text.get(_r[0][0],_r[0][1])
605
+ if _text.length > 0
606
+ EditorContract.instance.eval_expression(self, 'text'=>_text)
607
+ end
608
+ end
609
+ }
610
+ )
611
+
612
+ @pop_up.insert('end',
613
+ :cascade,
614
+ :label=>'Debug',
615
+ :menu=>_sub_debug,
616
+ :hidemargin => false
617
+ )
618
+
619
+
620
+ #---- code menu
621
+ _sub_code = TkMenu.new(
622
+ :parent=>@pop_up,
623
+ :tearoff=>0,
624
+ :title => 'Code'
625
+ )
626
+
627
+ _sub_code.insert('end',
628
+ :command,
629
+ :label=>'Show tabs',
630
+ :hidemargin => false,
631
+ :command=> proc{show_tabs}
632
+ )
633
+
634
+
635
+ _sub_code.insert('end',
636
+ :command,
637
+ :label=>'Hide tabs',
638
+ :hidemargin => false,
639
+ :command=> proc{hide_tabs}
640
+ )
641
+
642
+ _sub_code.insert('end',
643
+ :command,
644
+ :label=>'Show spaces',
645
+ :hidemargin => false,
646
+ :command=> proc{show_spaces}
647
+ )
648
+
649
+
650
+ _sub_code.insert('end',
651
+ :command,
652
+ :label=>'Hide spaces',
653
+ :hidemargin => false,
654
+ :command=> proc{hide_spaces}
655
+ )
656
+
657
+
658
+ _sub_code.insert('end',
659
+ :command,
660
+ :label=>'Space to tabs indentation',
661
+ :hidemargin => false,
662
+ :command=> proc{indentation_space_2_tabs}
663
+ )
664
+
665
+ _sub_code.insert('end',
666
+ :command,
667
+ :label=>'Tabs to space indentation',
668
+ :hidemargin => false,
669
+ :command=> proc{indentation_tabs_2_space}
670
+ )
671
+
672
+
673
+ @pop_up.insert('end',
674
+ :cascade,
675
+ :label=>'Code',
676
+ :menu=>_sub_code,
677
+ :hidemargin => false
678
+ )
679
+
680
+
681
+
682
+
683
+ @text.bind("Button-3",
684
+ proc{|x,y|
685
+ _x = TkWinfo.pointerx(@text)
686
+ _y = TkWinfo.pointery(@text)
687
+ @pop_up.popup(_x,_y)
688
+ },
689
+ "%x %y")
690
+ end
691
+
692
+ def unmark_debug(_index)
693
+ @text.tag_remove('debug',_index +' linestart', _index +' +1 lines linestart')
694
+ #@text.tag_remove('debug',_index+' linestart', _index+' lineend')
695
+ end
696
+
697
+ def mark_debug(_index)
698
+ @text.tag_add('debug',_index +' linestart', _index +' +1 lines linestart')
699
+ #@text.tag_add('debug',_index +' linestart', _index +' lineend')
700
+ end
701
+
702
+ def mark_selected(_index)
703
+ @text.tag_remove('selected','1.0', 'end')
704
+ @text.tag_add('selected',_index +' linestart', _index +' +1 lines linestart')
705
+ end
706
+
707
+
708
+ def build_tree_from_source(_source)
709
+ _row = 1
710
+ _liv = 0
711
+ _livs = Array.new
712
+ root = TreeNode.new(nil, 'KRoot'){|_node|
713
+ _node.rif= 'root'
714
+ _node.label=''
715
+ }
716
+ _livs[_liv]=root
717
+ _source.each_line{|line|
718
+ line = "\s"+line.split("#")[0]+"\s"
719
+ m = /[\s\n\t\;]+(module|class|def|if|unless|begin|case|for|while|do)[\s\n\t\;]+/.match(line)
720
+ if m
721
+ index = m.post_match.strip.length - 1
722
+ if m.post_match.strip[index,index]=='{'
723
+ _row = _row +1
724
+ next
725
+ end
726
+ _liv>=0? _liv = _liv + 1:_liv=1
727
+ _pliv = _liv
728
+ _parent = nil
729
+ while (_parent == nil && _pliv>=0)
730
+ _pliv = _pliv -1
731
+ _parent = _livs[_pliv]
732
+ end
733
+ if _parent
734
+ _helptext = m.post_match.strip
735
+ _label = _helptext.split('<')[0]
736
+ if _label == nil || _label.strip.length==0
737
+ _label = _helptext
738
+ end
739
+ if (m[0].strip[0..4] == "class" && m.pre_match.strip.length==0)
740
+ _kind = 'KClass'
741
+ elsif (m[0].strip[0..4] == "class" && m.pre_match.strip.length>0)
742
+ _row = _row +1
743
+ _liv = _liv - 1
744
+ next
745
+ elsif (m[0].strip[0..5] == "module" && m.pre_match.strip.length==0)
746
+ _kind = 'KModule'
747
+ elsif (m[0].strip[0..5] == "module" && m.pre_match.strip.length>0)
748
+ _row = _row +1
749
+ _liv = _liv - 1
750
+ next
751
+ 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))
752
+ _row = _row +1
753
+ next
754
+ elsif ((m[0].strip[0..1] == "if" || m[0].strip[0..5] == "unless") && m.pre_match.strip.length>0)
755
+ _row = _row +1
756
+ _liv = _liv - 1
757
+ next
758
+ elsif (m[0].strip[0..2] == "def" && m.pre_match.strip.length==0)
759
+ _kind = 'KDef'
760
+ if _label.include?(_parent.label + '.')
761
+ _kind = 'KDefClass'
762
+ end
763
+ # elsif (m[0].strip[0..10] == "attr_reader" && m.pre_match.strip.length==0)
764
+ # _kind = 'KAttr_reader'
765
+ # _liv = _liv - 1
766
+ # _row = _row +1
767
+ end
768
+
769
+ TreeNode.new(_parent, _kind){|_node|
770
+ _node.label = _label
771
+ _node.helptext = _helptext
772
+ _node.rif = _row.to_s
773
+ _livs[_pliv + 1]=_node
774
+ }
775
+ else
776
+ _row = _row +1
777
+ _liv = _liv - 1
778
+ next
779
+ end
780
+ end
781
+ m_end = /[\s\n\t\;]+end[\s\n\t\;]+/.match(line)
782
+ if m_end
783
+ _liv = _liv - 1
784
+ end
785
+ _row = _row +1
786
+ }
787
+ return root
788
+ end
789
+
790
+ def build_tree_from_node(_node, _label_match=nil)
791
+
792
+ @image_kclass = TkPhotoImage.new('dat' => TREE_NODE_CLASS_GIF)
793
+ @image_kmodule = TkPhotoImage.new('dat' => TREE_NODE_MODULE_GIF)
794
+ @image_kdef = TkPhotoImage.new('dat' => TREE_NODE_DEF_GIF)
795
+ @image_kdefclass = TkPhotoImage.new('dat' => TREE_NODE_DEFCLASS_GIF)
796
+
797
+ _sorted_sons = _node.sons.sort
798
+ for inode in 0.._sorted_sons.length - 1
799
+ _son = _sorted_sons[inode]
800
+ if _son.kind == 'KClass'
801
+ _image = @image_kclass
802
+ elsif _son.kind == 'KModule'
803
+ _image = @image_kmodule
804
+ elsif _son.kind == 'KDef'
805
+ _image = @image_kdef
806
+ elsif _son.kind == 'KDefClass'
807
+ _image = @image_kdefclass
808
+ end
809
+ @tree_exp.insert('end', _son.parent.rif ,_son.rif, {
810
+ 'text' => _son.label ,
811
+ 'helptext' => _son.helptext,
812
+ 'font'=>$arcadia['conf']['editor.explorer_panel.tree.font'],
813
+ 'image'=> _image
814
+ }
815
+ )
816
+ if (_label_match) && (_label_match.strip == _son.label.strip)
817
+ @selected = _son
818
+ end
819
+ build_tree_from_node(_son, _label_match)
820
+ end
821
+ end
822
+
823
+ def build_tree(_sel=nil)
824
+ if _sel
825
+ _label_sel = @tree_exp.itemcget(_sel,'text')
826
+ end
827
+
828
+ #clear tree
829
+ begin
830
+ @tree_exp.delete(@tree_exp.nodes('root'))
831
+ rescue Exception
832
+ # workaround on windows
833
+ @tree_exp.delete(@tree_exp.nodes('root'))
834
+ end
835
+
836
+
837
+ #(re)build tree
838
+ _txt = @text.get('1.0','end')
839
+ @root = build_tree_from_source(_txt)
840
+ @selected = nil
841
+ build_tree_from_node(@root, _label_sel)
842
+ if @selected
843
+ @tree_exp.selection_add(@selected.rif)
844
+ @tree_exp.open_tree(@selected.parent.rif)
845
+ @tree_exp.see(@selected.rif)
846
+ end
847
+ end
848
+
849
+ def insert_popup_menu_item(_where, *args)
850
+ @pop_up.insert(_where,*args)
851
+ end
852
+
853
+ def text_value
854
+ return @text.value
855
+ end
856
+
857
+ # vertical scrollbar : ON/OFF
858
+ def vscroll(mode)
859
+ st = TkGrid.info(@v_scroll)
860
+ if mode && st == [] then
861
+ @v_scroll.grid('row'=>0, 'column'=>1, 'sticky'=>'ns')
862
+ elsif !mode && st != [] then
863
+ @v_scroll.ungrid
864
+ end
865
+ self
866
+ end
867
+
868
+ # horizontal scrollbar : ON/OFF
869
+ def hscroll(mode, wrap_mode="char")
870
+ st = TkGrid.info(@h_scroll)
871
+ if mode && st == [] then
872
+ @h_scroll.grid('row'=>1, 'column'=>0, 'sticky'=>'ew')
873
+ @text.configure('wrap'=> 'none')
874
+ elsif !mode && st != [] then
875
+ @h_scroll.ungrid
876
+ @text.configure('wrap'=> wrap_mode)
877
+ end
878
+ self
879
+ end
880
+
881
+ def rowcol(_index, _gap_row = nil, _gap_col = nil)
882
+ _riga, _colonna = _index.split('.')
883
+ if _gap_row == nil
884
+ _riga = '1'
885
+ _gap_row = 0
886
+ end
887
+ if _gap_col == nil
888
+ _colonna = '0'
889
+ _gap_col = 0
890
+ end
891
+ return (_riga.to_i + _gap_row).to_s + '.'+ (_colonna.to_i + _gap_col).to_s
892
+ end
893
+
894
+ def find_and_set_tag(_re, _row, _txt, _tag, _tag_rem = nil)
895
+ m = _re.match(_txt)
896
+ _end = 0
897
+ if m && @is_tag_bold[_tag]
898
+ @is_line_bold[_row]=true
899
+ end
900
+ while m
901
+ _txt = m.post_match
902
+ _ibegin = _row.to_s+'.'+(m.begin(0)+_end).to_s
903
+ _end = m.end(0) + _end
904
+ _iend = _row.to_s+'.'+(_end.to_s)
905
+ if _tag_rem
906
+ _tag_rem.each {|value|
907
+ @text.tag_remove(value,_ibegin, _iend)
908
+ }
909
+ end
910
+ @text.tag_add(_tag,_ibegin, _iend)
911
+ m = _re.match(_txt)
912
+ end
913
+ end
914
+
915
+ def show_spaces
916
+ @spaces_show = true
917
+ _row = 1
918
+ @text.value.each{|_line|
919
+ show_chars_line(_row, _line, /[ ^\t]\s*/, 'spaces')
920
+ _row = _row+1
921
+ }
922
+ end
923
+
924
+
925
+ def show_tabs
926
+ @tabs_show = true
927
+ _row = 1
928
+ @text.value.each{|_line|
929
+ show_chars_line(_row, _line, /\t/, 'tabs')
930
+ _row = _row+1
931
+ }
932
+ end
933
+
934
+
935
+ def show_chars_line(_row, _line, _re, _tag)
936
+ m = _re.match(_line)
937
+ _end = 0
938
+ while m
939
+ _txt = m.post_match
940
+ _ibegin = _row.to_s+'.'+(m.begin(0)+_end).to_s
941
+ _end = m.end(0) + _end
942
+ _iend = _row.to_s+'.'+(_end.to_s)
943
+ @text.tag_add(_tag,_ibegin, _iend)
944
+ m = _re.match(_txt)
945
+ end
946
+ end
947
+
948
+ def indentation_space_2_tabs(_n_space=2)
949
+ _row = 1
950
+ @text.value.each{|_line|
951
+ m = /\s*/.match(_line)
952
+ _end = 0
953
+ if m && m.begin(0)==0
954
+ _s = m[0]
955
+ if !_s.include?("\n") && !_s.include?("\t")
956
+ _ibegin = _row.to_s+'.0'
957
+ _iend = _row.to_s+'.'+m.end(0).to_s
958
+ _n_tab = (_s.length / _n_space).round
959
+ @text.delete(_ibegin, _iend)
960
+ @text.insert(_ibegin,"\t"*_n_tab )
961
+ end
962
+ end
963
+ _row = _row+1
964
+ }
965
+ check_modify
966
+ end
967
+
968
+ def indentation_tabs_2_space(_n_space=2)
969
+ _row = 1
970
+ @text.value.each{|_line|
971
+ m = /\t*/.match(_line)
972
+ _end = 0
973
+ if m && m.begin(0)==0
974
+ _s = m[0]
975
+ if !_s.include?("\n")
976
+ _ibegin = _row.to_s+'.0'
977
+ _iend = _row.to_s+'.'+m.end(0).to_s
978
+ @text.delete(_ibegin, _iend)
979
+ @text.insert(_ibegin,"\s"*_s.length*_n_space )
980
+ end
981
+ end
982
+ _row = _row+1
983
+ }
984
+ check_modify
985
+ end
986
+
987
+
988
+ def hide_tabs
989
+ @text.tag_remove('tabs','1.0', 'end')
990
+ @tabs_show = false
991
+ end
992
+
993
+ def hide_spaces
994
+ @text.tag_remove('spaces','1.0', 'end')
995
+ @spaces_show = false
996
+ end
997
+
998
+
999
+ def modified?
1000
+ return !(@buffer === text_value)
1001
+ end
1002
+
1003
+ def set_modify
1004
+ if !@set_mod
1005
+ @set_mod = true
1006
+ @controller.change_tab_set_modify(@page_frame)
1007
+ end
1008
+ end
1009
+
1010
+ def reset_modify
1011
+ @controller.change_tab_reset_modify(@page_frame)
1012
+ @set_mod = false
1013
+ @file_last_access_time = File.mtime(@file) if @file
1014
+ end
1015
+
1016
+ def highlightline(_row, _line, _check_mod = false)
1017
+ if _check_mod
1018
+ check_modify
1019
+ end
1020
+ _txt = _line
1021
+ _end = 0
1022
+
1023
+ #if line is a comment
1024
+ m_c = /#/.match(_txt)
1025
+ if m_c then
1026
+ _ibegin = _row.to_s+'.'+(m_c.begin(0)).to_s
1027
+ _iend = _row.to_s+'.'+(_line.length - 1).to_s
1028
+ @text.tag_add('comment',_ibegin, _iend)
1029
+ _txt = m_c.pre_match
1030
+ end
1031
+ arem = Array.new
1032
+ if _txt.strip.length > 0
1033
+ find_and_set_tag(@re_number, _row, _txt, 'number')
1034
+ arem << 'number'
1035
+ find_and_set_tag(@re_method_name, _row, _txt, 'method_name',arem)
1036
+ arem << 'method_name'
1037
+ find_and_set_tag(@re_class_name, _row, _txt, 'class_name',arem)
1038
+ arem << 'class_name'
1039
+ find_and_set_tag(@re_module_name, _row, _txt, 'module_name',arem)
1040
+ arem << 'module_name'
1041
+ find_and_set_tag(@re_keyword, _row, _txt, 'keyword',arem)
1042
+ arem << 'keyword'
1043
+ find_and_set_tag(@re_instance_variable, _row, _txt, 'instance_variable',arem)
1044
+ arem << 'instance_variable'
1045
+ find_and_set_tag(@re_operator, _row, _txt, 'operator')
1046
+ arem << 'operator'
1047
+ find_and_set_tag(@re_string, _row, _txt, 'string', arem)
1048
+ end
1049
+ find_and_set_tag(/\t/, _row, _txt, 'tabs', arem) if @tabs_show
1050
+ find_and_set_tag(/[ ^\t]\s*/, _row, _txt, 'spaces', arem) if @spaces_show
1051
+ end
1052
+
1053
+ def rehighlightline(_row)
1054
+ _ibegin = _row.to_s+'.0'
1055
+ _iend = (_row+1).to_s+'.0'
1056
+ @text.tag_remove('keyword',_ibegin, _iend)
1057
+ @text.tag_remove('comment',_ibegin, _iend)
1058
+ @text.tag_remove('string',_ibegin, _iend)
1059
+ @text.tag_remove('number',_ibegin, _iend)
1060
+ @text.tag_remove('operator',_ibegin, _iend)
1061
+ @text.tag_remove('capitalize',_ibegin, _iend)
1062
+ _line = @text.get(_ibegin, _iend)
1063
+ highlightline(_row, _line)
1064
+ end
1065
+
1066
+ def row(_index='insert')
1067
+ _row = @text.index(_index).split('.')[0].to_i
1068
+ print "def row(_index='insert')",_row.to_s,"\n"
1069
+ return _row
1070
+ end
1071
+
1072
+ def do_line_update
1073
+ #renum in @text_line_num the portion of visibled screen of @text
1074
+ if @text_line_num
1075
+ #p '@is_line_bold='+@is_line_bold.to_s
1076
+ #incr = 1 + (@font_metrics[2][1]+@font_metrics_bold[2][1]) / 4
1077
+ line_begin = @text.index('@0,0').split('.')[0].to_i
1078
+ line_end = @text.index('@0,'+TkWinfo.height(@text).to_s).split('.')[0].to_i + 1
1079
+ # breakpoint
1080
+ b = @controller.breakpoint_lines_on_file(@file)
1081
+ @text_line_num.delete('1.0','end')
1082
+ for j in line_begin...line_end
1083
+ nline = j.to_s.rjust(6)
1084
+ _index = @text_line_num.index('end')
1085
+ if @highlighting && @is_line_bold[j]
1086
+ @text_line_num.insert('end', nline+"\n",'bold_case')
1087
+ else
1088
+ @text_line_num.insert('end', nline+"\n")
1089
+ end
1090
+ if b.include?(j.to_s)
1091
+ @text_line_num.tag_add('breakpoint',_index+' -1 lines',_index+' -1 lines lineend')
1092
+ # @text_line_num.tag_add('breakpoint',_index+' -1 lines',_index+' -1 lines + 1 chars')
1093
+ end
1094
+ end
1095
+
1096
+ if @highlighting
1097
+ _zone_begin = ((line_begin) / @highlight_zone_length).to_i + 1
1098
+ _zone_end = ((line_end) / @highlight_zone_length).to_i + 1
1099
+
1100
+ (_zone_begin >=@last_zone_begin)?_zone_begin.upto(_zone_end+1){|_zone|
1101
+ highlight_zone(_zone)
1102
+ }:_zone_end.downto(_zone_begin-1){|_zone|
1103
+ highlight_zone(_zone)
1104
+ }
1105
+ @last_line_begin = line_begin
1106
+ @last_line_end = line_end
1107
+ @last_zone_begin = _zone_begin
1108
+ @last_zone_end = _zone_end
1109
+ end
1110
+ end
1111
+ end
1112
+
1113
+ def highlight_zone(_zone)
1114
+ if !@highlight_zone[_zone]
1115
+ _b = @highlight_zone_length*(_zone - 1)
1116
+ _e = @highlight_zone_length*(_zone) + 1
1117
+ for j in _b..._e
1118
+ rehighlightline(j)
1119
+ end
1120
+ @highlight_zone[_zone] = true
1121
+ end
1122
+ end
1123
+
1124
+ def text_see(_index=nil)
1125
+ if _index
1126
+ @text.see(_index)
1127
+ end
1128
+ end
1129
+
1130
+ def text_insert_index
1131
+ @text.index('insert')
1132
+ end
1133
+
1134
+ def text_insert(index, chars, *tags, &b)
1135
+ if block_given?
1136
+ instance_eval(&b)
1137
+ end
1138
+ _index = @text.index(index)
1139
+ _row, _col = _index.split('.')
1140
+ _row = (_row.to_i - 1).to_s
1141
+ chars.each_line {|line|
1142
+ @text.insert(_row+'.0', line, *tags)
1143
+ if !defined?(m_begin)||(m_begin == nil)
1144
+ m_begin = /=begin/.match(line)
1145
+ end
1146
+ if @highlighting
1147
+ if m_begin &&(m_begin.begin(0)==0)
1148
+ _ibegin = _row+'.0'
1149
+ _iend = _row+'.'+(line.length - 1).to_s
1150
+ @text.tag_add('comment',_ibegin, _iend)
1151
+ else
1152
+ highlightline(_row.to_i, line, false)
1153
+ end
1154
+ end
1155
+ _row = (_row.to_i + 1).to_s
1156
+ }
1157
+ if defined?(_edit_reset)
1158
+ if _edit_reset
1159
+ @text.edit_reset
1160
+ end
1161
+ else
1162
+ @text.edit_reset
1163
+ end
1164
+ end
1165
+
1166
+ def save
1167
+ if !@file
1168
+ save_as
1169
+ else
1170
+ f = File.new(@file, "w")
1171
+ begin
1172
+ if f
1173
+ f.syswrite(text_value)
1174
+ @buffer = text_value
1175
+ reset_modify
1176
+ end
1177
+ ensure
1178
+ f.close unless f.nil?
1179
+ end
1180
+ EditorContract.instance.file_saved(self,'file' =>@file)
1181
+ end
1182
+ end
1183
+
1184
+ def save_as
1185
+ @file = Tk.getSaveFile("filetypes"=>[["Ruby Files", [".rb", ".rbw"]]])
1186
+ @file = nil if @file == "" # cancelled
1187
+ if @file
1188
+ save
1189
+ @controller.change_file_name(@page_frame, @file)
1190
+ EditorContract.instance.file_created(self, 'file'=>@file)
1191
+ end
1192
+ end
1193
+
1194
+ def check_modify
1195
+ if modified?
1196
+ set_modify if !@set_mod
1197
+ else
1198
+ reset_modify
1199
+ end
1200
+ end
1201
+
1202
+ def check_file_last_access_time
1203
+ if @file && @file_last_access_time
1204
+
1205
+ ftime = File.mtime(@file)
1206
+ if @file_last_access_time != ftime
1207
+ msg = 'File "'+@file+'" is changed! Reload?'
1208
+ if Tk.messageBox('icon' => 'error', 'type' => 'yesno',
1209
+ 'title' => '(Arcadia) Libs', 'parent' => @text,
1210
+ 'message' => msg) == 'yes'
1211
+ @text.delete('1.0','end')
1212
+ load_file(@file)
1213
+ else
1214
+ @file_last_access_time = ftime
1215
+ end
1216
+ end
1217
+ end
1218
+ end
1219
+
1220
+ def init_editing(_ext='rb')
1221
+ case _ext
1222
+ when 'rb'
1223
+ @fm = AGTkVSplittedFrames.new(@page_frame,150)
1224
+ @fm1 = AGTkVSplittedFrames.new(@fm.right_frame,60)
1225
+ initialize_text(@fm1.right_frame)
1226
+ initialize_text_binding
1227
+ initialize_highlight
1228
+ initialize_line_number(@fm1.left_frame)
1229
+ initialize_tree(@fm.left_frame)
1230
+ when nil
1231
+ @fm1 = AGTkVSplittedFrames.new(@page_frame,60)
1232
+ initialize_text(@fm1.right_frame)
1233
+ initialize_text_binding
1234
+ initialize_highlight
1235
+ initialize_line_number(@fm1.left_frame)
1236
+ else
1237
+ @fm1 = AGTkVSplittedFrames.new(@page_frame,60)
1238
+ initialize_text(@fm1.right_frame)
1239
+ initialize_text_binding
1240
+ initialize_line_number(@fm1.left_frame)
1241
+ end
1242
+ end
1243
+
1244
+ def file_extension(_filename=nil)
1245
+ if _filename
1246
+ _m = /(.*\.)(.*$)/.match(File.basename(_filename))
1247
+ end
1248
+ _ret = (_m && _m.length > 1)?_m[2]: nil
1249
+ end
1250
+
1251
+ def load_file(_filename = nil)
1252
+ #if filename is nil then open a new tab
1253
+ @file = _filename
1254
+ if _filename
1255
+ #init_editing(file_extension(_filename))
1256
+ File::open(_filename,'r'){ |file|
1257
+ @text.insert('end',file.readlines.collect!{| line | line.chomp+"\n" }.to_s)
1258
+ }
1259
+ end
1260
+ reset
1261
+ refresh
1262
+ end
1263
+
1264
+ def reset
1265
+ @buffer = text_value
1266
+ reset_modify
1267
+ @text.edit_reset
1268
+ end
1269
+
1270
+ def refresh
1271
+ build_tree if @classbrowsing
1272
+ end
1273
+ end
1274
+
1275
+ class AgMultiEditorView
1276
+ attr_reader :enb
1277
+ def initialize(parent=nil)
1278
+ @enb = Tk::BWidget::NoteBook.new(parent){
1279
+ tabbevelsize 0
1280
+ internalborderwidth 2
1281
+ activeforeground 'red'
1282
+ activebackground 'yellow'
1283
+ #background 'black'
1284
+ borderwidth 1
1285
+ side $arcadia['conf']['editor.tabs.side']
1286
+ font $arcadia['conf']['editor.tabs.font']
1287
+ pack('fill'=>'both', :padx=>0, :pady=>0, :expand => 'yes')
1288
+ }
1289
+ end
1290
+
1291
+ end
1292
+
1293
+ class AgMultiEditor < ArcadiaExt
1294
+ attr_reader :breakpoints
1295
+ attr_reader :splitted_frame
1296
+ def before_build
1297
+ ArcadiaContractListener.new(self, DebugContract, :do_debug_event)
1298
+ ArcadiaContractListener.new(self, EditorContract, :do_editor_event)
1299
+ ArcadiaContractListener.new(self, MainContract, :do_main_event)
1300
+ end
1301
+
1302
+ def build
1303
+ if @arcadia.layout.headed?
1304
+ title_frame = @arcadia.layout.domain(conf('frame'))['root']
1305
+ #@close_button = title_frame.add_button(nil,nil,TAB_CLOSE_GIF,'left')
1306
+ end
1307
+
1308
+ #@splitted_frame = AGTkOSplittedFrames.new(self.frame,20)
1309
+ #@main_frame = AgMultiEditorView.new(@splitted_frame.bottom_frame)
1310
+ @main_frame = AgMultiEditorView.new(self.frame)
1311
+ #@close_button.bind('1',proc{close_raised})
1312
+ @tabs_file =Hash.new
1313
+ @tabs_editor =Hash.new
1314
+ @breakpoints =Array.new
1315
+ create_find
1316
+ pop_up_menu
1317
+ end
1318
+
1319
+ def after_build
1320
+ self.open_last_files
1321
+ end
1322
+
1323
+ def pop_up_menu
1324
+ @pop_up = TkMenu.new(
1325
+ :parent=>@main_frame.enb,
1326
+ :tearoff=>0,
1327
+ :title => 'Menu'
1328
+ )
1329
+ @pop_up.insert('end',
1330
+ :command,
1331
+ :label=>'...',
1332
+ :state=>'disabled',
1333
+ :background=>'blue',
1334
+ :font => conf('font.bold'),
1335
+ :hidemargin => true
1336
+ )
1337
+ @c = @pop_up.insert('end',
1338
+ :command,
1339
+ :label=>'Close',
1340
+ :font => conf('font'),
1341
+ :hidemargin => false,
1342
+ :command=> proc{
1343
+ if @selected_tab_name_from_popup != nil
1344
+ _e = @tabs_editor[@selected_tab_name_from_popup]
1345
+ self.close_editor(_e)
1346
+ end
1347
+ }
1348
+ )
1349
+ @c = @pop_up.insert('end',
1350
+ :command,
1351
+ :label=>'Close others',
1352
+ :font => conf('font'),
1353
+ :hidemargin => false,
1354
+ :command=> proc{
1355
+ if @selected_tab_name_from_popup != nil
1356
+ _e = @tabs_editor[@selected_tab_name_from_popup]
1357
+ self.close_others_editor(_e)
1358
+ end
1359
+ }
1360
+ )
1361
+ @c = @pop_up.insert('end',
1362
+ :command,
1363
+ :label=>'Close all',
1364
+ :font => conf('font'),
1365
+ :hidemargin => false,
1366
+ :command=> proc{
1367
+ if @selected_tab_name_from_popup != nil
1368
+ _e = @tabs_editor[@selected_tab_name_from_popup]
1369
+ self.close_all_editor(_e)
1370
+ end
1371
+ }
1372
+ )
1373
+
1374
+ @main_frame.enb.tabbind("Button-3",
1375
+ proc{|*x|
1376
+ _x = TkWinfo.pointerx(@main_frame.enb)
1377
+ _y = TkWinfo.pointery(@main_frame.enb)
1378
+ @selected_tab_name_from_popup = x[0].split(':')[0]
1379
+ _index = @main_frame.enb.index(@selected_tab_name_from_popup)
1380
+ if _index == -1
1381
+ @selected_tab_name_from_popup = 'ff'+@selected_tab_name_from_popup
1382
+ _index = @main_frame.enb.index(@selected_tab_name_from_popup)
1383
+ end
1384
+ if _index != -1
1385
+ _file = @main_frame.enb.itemcget(@selected_tab_name_from_popup, 'text')
1386
+ @pop_up.entryconfigure(0, 'label'=>_file)
1387
+ @pop_up.popup(_x,_y)
1388
+ end
1389
+ })
1390
+ end
1391
+
1392
+
1393
+ def do_debug_event(_event)
1394
+ #@arcadia.outln('_sender ----> '+_sender.to_s)
1395
+ #@arcadia.outln('_event.signature ----> '+_event.signature)
1396
+ case _event.signature
1397
+ when DebugContract::DEBUG_BEGIN
1398
+ self.debug_begin
1399
+ when DebugContract::DEBUG_END
1400
+ self.debug_end
1401
+ when DebugContract::DEBUG_STEP
1402
+ if _event.context.file
1403
+ self.open_file_in_debug(_event.context.file, _event.context.line)
1404
+ end
1405
+ end
1406
+ end
1407
+
1408
+ def do_editor_event(_event)
1409
+ case _event.signature
1410
+ when EditorContract::OPEN_FILE
1411
+ if _event.context.file
1412
+ if _event.context.line
1413
+ _index = _event.context.line.to_s+'.0'
1414
+ end
1415
+ self.open_file(_event.context.file, _index)
1416
+ _event.handled(self)
1417
+ end
1418
+ when EditorContract::CLOSE_FILE
1419
+ if _event.context.file
1420
+ self.close_file(_event.context.file)
1421
+ _event.handled(self)
1422
+ end
1423
+ when EditorContract::SAVE_FILE_RAISED
1424
+ self.raised.save
1425
+ _event.handled(self)
1426
+ when EditorContract::SAVE_FILE
1427
+ if _event.context.file
1428
+ self.save_file(_event.context.file)
1429
+ _event.handled(self)
1430
+ end
1431
+ when EditorContract::SAVE_AS_FILE_RAISED
1432
+ self.raised.save_as
1433
+ _event.handled(self)
1434
+ when EditorContract::SAVE_AS_FILE
1435
+ if _event.context.file
1436
+ self.save_as_file(_event.context.file)
1437
+ _event.handled(self)
1438
+ end
1439
+ when EditorContract::OPEN_TEXT
1440
+ if _event.context.title
1441
+ _tab_name = self.tab_name(_event.context.title)
1442
+ self.open_buffer(_tab_name, _event.context.title)
1443
+ _e = @tabs_editor[_tab_name]
1444
+ _e.text_insert('end',_event.context.text) if _event.context.text
1445
+ _e.reset
1446
+ _e.refresh
1447
+ add_reverse_item(_e)
1448
+ _event.handled(self)
1449
+ end
1450
+ when EditorContract::SHOW_SEARCH_DIALOG
1451
+ @find.show
1452
+ when EditorContract::SHOW_GOTO_LINE_DIALOG
1453
+ @find.show_go_to_line_dialog
1454
+ end
1455
+ end
1456
+
1457
+ def xy_insert
1458
+ _text = self.raised.text
1459
+ _index_now = _text.index('insert')
1460
+ _rx, _ry, _widht, _heigth = _text.bbox(_index_now);
1461
+ _x = _rx + TkWinfo.rootx(_text)
1462
+ _y = _ry + TkWinfo.rooty(_text) + TkFont.new(conf('font')).metrics[2][1]
1463
+ _xroot = _x - TkWinfo.rootx(@arcadia.layout.root)
1464
+ _yroot = _y - TkWinfo.rooty(@arcadia.layout.root)
1465
+ return _xroot, _yroot
1466
+ end
1467
+
1468
+
1469
+
1470
+ def raise_complete_code(_context)
1471
+ # delete the file used for completion
1472
+ if File.exist?(_context.file) && _context.file.include?('~~')
1473
+ File.delete(_context.file)
1474
+ end
1475
+ @raised_listbox.destroy if @raised_listbox != nil
1476
+
1477
+ _text = self.raised.text
1478
+ _index_call = _context.line+'.'+_context.col
1479
+ _index_now = _text.index('insert')
1480
+ if _index_call == _index_now
1481
+ _target = _text.get('insert - 1 chars wordstart','insert')
1482
+ if _target.length > 0 && _target != '.'
1483
+ extra_len = _target.length.+@
1484
+ _begin_index = _index_now<<' - '<<extra_len.to_s<<' chars'
1485
+ _text.tag_add('sel', _begin_index, _index_now)
1486
+ else
1487
+ _begin_index = _index_now
1488
+ extra_len = 0
1489
+ end
1490
+ if _context.candidates.length > 1
1491
+ _rx, _ry, _widht, heigth = _text.bbox(_begin_index);
1492
+ _x = _rx + TkWinfo.rootx(_text)
1493
+ _y = _ry + TkWinfo.rooty(_text) + TkFont.new(conf('font')).metrics[2][1]
1494
+
1495
+ _xroot = _x - TkWinfo.rootx(@arcadia.layout.root)
1496
+ _yroot = _y - TkWinfo.rooty(@arcadia.layout.root)
1497
+
1498
+ _max_height = TkWinfo.screenheight(@arcadia.layout.root) - _y - 5
1499
+
1500
+ @raised_listbox = TkListbox.new(@arcadia.layout.root,
1501
+ 'takefocus'=>true,
1502
+ :background=>conf('color.background'),
1503
+ :foreground=>conf('color.foreground'),
1504
+ :selectbackground=>'yellow',
1505
+ :selectforeground=>'red',
1506
+ :activestyle=>'none',
1507
+ :font => conf('font'),
1508
+ :borderwidth=>1
1509
+ )
1510
+ _font = TkFont.new(conf('font'))
1511
+ _char_height = _font.metrics[2][1]
1512
+ _width = 0
1513
+ _docs_entries = Hash.new
1514
+ _context.candidates.each{|value|
1515
+ _key, _doc = value.split
1516
+ _docs_entries[_key]= _doc
1517
+ @raised_listbox.insert('end', _key)
1518
+ _temp_width = _font.measure(_key) + _font.measure('X')
1519
+ _width = _temp_width if _temp_width > _width
1520
+ }
1521
+ _height = (_context.candidates.length+1)*_char_height
1522
+ _height = _max_height if _height > _max_height
1523
+ @raised_listbox.place('x'=>_xroot,'y'=>_yroot, 'width'=>_width, 'height'=>_height)
1524
+
1525
+ @raised_listbox.focus
1526
+ @raised_listbox.bind_append('KeyPress'){|e|
1527
+ case e.keysym
1528
+ when 'Escape'
1529
+ @raised_listbox.destroy
1530
+ #_menu.destroy
1531
+ Tk.callback_break
1532
+ when 'Return'
1533
+ _value = @raised_listbox.get('active')
1534
+ _text.delete(_begin_index,'insert')
1535
+ _text.insert('insert',_value)
1536
+ @raised_listbox.destroy
1537
+ #_menu.destroy
1538
+ Tk.callback_break
1539
+ when 'F1'
1540
+ _key = @raised_listbox.get('active')
1541
+ _x, _y = xy_insert
1542
+ EditorContract.instance.doc_code(self, 'doc_entry'=>_docs_entries[_key], 'xdoc'=>_x, 'ydoc'=>_y)
1543
+ end
1544
+ }
1545
+ elsif _context.candidates.length == 1 && _context.candidates[0].length>0
1546
+ _text.delete(_begin_index,'insert');
1547
+ _text.insert('insert',_context.candidates[0].split[0])
1548
+ end
1549
+ end
1550
+ end
1551
+
1552
+ def do_main_event(_event)
1553
+ case _event.signature
1554
+ when MainContract::EVENT_HANDLED
1555
+ _cause = _event.context.caused_by
1556
+ if _cause.signature == EditorContract::COMPLETE_CODE &&
1557
+ _cause.context.sender == self.raised
1558
+ raise_complete_code(_cause.context)
1559
+ elsif _cause.signature == EditorContract::DOC_CODE && _cause.context.file != nil
1560
+ # delete the file used for completion
1561
+ if File.exist?(_cause.context.file) && _cause.context.file.include?('~~')
1562
+ File.delete(_cause.context.file)
1563
+ end
1564
+ end
1565
+ end
1566
+ end
1567
+
1568
+ def add_reverse_item(_editor)
1569
+ code2form = proc{
1570
+ Revparsel.new(_editor.text_value)
1571
+ self.close_editor(_editor, false)
1572
+ InspectorContract.instance.raise_last_widget(self)
1573
+ }
1574
+ _editor.insert_popup_menu_item('end',
1575
+ :command,
1576
+ :label=>'View as form',
1577
+ :hidemargin => false,
1578
+ :command=> code2form
1579
+ )
1580
+
1581
+ end
1582
+
1583
+ # def editor_state
1584
+ # r = EditorContract::SObj.new
1585
+ # r.raised_file = self.raised.file
1586
+ # r.breakpoints = @breakpoints
1587
+ # return r
1588
+ # end
1589
+
1590
+ def get_find
1591
+ @find
1592
+ end
1593
+
1594
+ def create_find
1595
+ #find_frame = @arcadia.layout.register_panel(conf('find.frame'),'Find', 'Find')
1596
+ # @find = Find.new(@splitted_frame.top_frame, self)
1597
+ @find = Find.new(@arcadia.layout.root, self)
1598
+ @find.on_close=proc{@find.hide}
1599
+ @find.hide
1600
+ end
1601
+
1602
+ def finalize
1603
+ _files =''
1604
+ @tabs_editor.each_value{|editor|
1605
+ _files=_files+'|'+ editor.file if editor.file != nil
1606
+ close_editor(editor)
1607
+ }
1608
+ @arcadia['pers']['editor.files.open']=_files
1609
+ end
1610
+
1611
+ def raised
1612
+ _page = @main_frame.enb.raise
1613
+ return @tabs_editor[_page]
1614
+ end
1615
+
1616
+ def close_raised
1617
+ close_editor(@tabs_editor[@main_frame.enb.raise])
1618
+
1619
+ #_page = @main_frame.enb.raise
1620
+ #_editor = @tabs_editor[_page]
1621
+ #_row = _editor.text_insert_index.split('.')[0].strip.to_i
1622
+ #close_editor(_editor)
1623
+ end
1624
+
1625
+ def breakpoint_add(_file,_line)
1626
+ EditorContract.instance.breakpoint_created(self, 'file'=>_file, 'line'=>_line)
1627
+ @breakpoints << {:file=>_file,:line=>_line}
1628
+ end
1629
+
1630
+ def breakpoint_del(_file,_line)
1631
+ EditorContract.instance.breakpoint_deleted(self, 'file'=>_file, 'line'=>_line)
1632
+ @breakpoints.delete_if{|b| (b[:file]==_file && b[:line]==_line)}
1633
+ end
1634
+
1635
+ def breakpoint_lines_on_file(_file)
1636
+ result = Array.new
1637
+ @breakpoints.each{|value|
1638
+ if value[:file]==_file
1639
+ result << value[:line]
1640
+ end
1641
+ }
1642
+ return result
1643
+ end
1644
+
1645
+ def open_last_files
1646
+ if $arcadia['pers']['editor.files.open']
1647
+ _files_index =$arcadia['pers']['editor.files.open'].split("|")
1648
+ _files_index.each{|value|
1649
+ _file,_index = value.split(';')
1650
+ if _file
1651
+ open_file(_file,_index)
1652
+ end
1653
+ }
1654
+ end
1655
+ self
1656
+ end
1657
+
1658
+ def bookmark_add(_file, _index)
1659
+ if @bookmarks == nil
1660
+ @bookmarks = Array.new
1661
+ @bookmarks_index = - 1
1662
+ else
1663
+ _cur_file, _cur_index = @bookmarks[@bookmarks_index]
1664
+ if _cur_file == _file && _cur_index == _index
1665
+ #@arcadia.outln('uguale ----> '+_file+':'+_index)
1666
+ return
1667
+ end
1668
+ @bookmarks = @bookmarks[0..@bookmarks_index]
1669
+ end
1670
+ @bookmarks << [_file, _index]
1671
+ @bookmarks_index = @bookmarks.length - 1
1672
+ #@arcadia.outln('add ----> '+_file+':'+_index)
1673
+ end
1674
+
1675
+ def bookmark_clear
1676
+ @bookmarks.clear
1677
+ @bookmarks_index = - 1
1678
+ end
1679
+
1680
+ def bookmark_next
1681
+ return if @bookmarks == nil || @bookmarks_index >= @bookmarks.length - 1
1682
+ bookmark_move(+1)
1683
+ end
1684
+
1685
+ def bookmark_move(_n=0)
1686
+ @bookmarks_index = @bookmarks_index + _n
1687
+ #Tk.messageBox('message'=>@bookmarks_index.to_s)
1688
+ _file, _index = @bookmarks[@bookmarks_index]
1689
+ _line, _col = _index.split('.') if _index
1690
+ open_file(_file, _index)
1691
+ #openfile(@bookmarks[@bookmarks_index])
1692
+ end
1693
+
1694
+
1695
+ def bookmark_prev
1696
+ return if @bookmarks == nil || @bookmarks_index <= 0
1697
+ bookmark_move(-1)
1698
+ end
1699
+
1700
+
1701
+ def get_tab_from_name(_name=nil)
1702
+ return @main_frame.enb.get_frame(_name)
1703
+ # if _name
1704
+ # @tabs_name.each{
1705
+ # |key,value|
1706
+ # if value.to_s==_name.to_s
1707
+ # return key
1708
+ # end
1709
+ # }
1710
+ # return nil
1711
+ # end
1712
+ end
1713
+
1714
+ def change_tab_set_modify(_tab)
1715
+ _new_name = '(...)'+@main_frame.enb.itemcget(page_name(_tab), 'text')
1716
+ change_tab_title(_tab, _new_name)
1717
+ end
1718
+
1719
+ def page_name(_page_frame)
1720
+ TkWinfo.appname(_page_frame).sub('f','')
1721
+ end
1722
+
1723
+ def change_tab_reset_modify(_tab)
1724
+ #_new_name = @main_frame.enb.itemcget(@tabs_name[_tab], 'text').gsub!("(...)",'')
1725
+ _new_name = @main_frame.enb.itemcget(page_name(_tab), 'text').gsub!("(...)",'')
1726
+ if _new_name
1727
+ change_tab_title(_tab, _new_name)
1728
+ end
1729
+ end
1730
+
1731
+ def change_tab_title(_tab, _new_text)
1732
+ @main_frame.enb.itemconfigure(page_name(_tab), 'text'=> _new_text)
1733
+ end
1734
+
1735
+ def change_file_name(_tab, _new_file)
1736
+ _new_label = File.basename(_new_file)
1737
+ change_tab_title(_tab, _new_label)
1738
+ @tabs_file[page_name(_tab)] = _new_file
1739
+ end
1740
+
1741
+ def debug_begin
1742
+ if @editors_in_debug != nil
1743
+ @editors_in_debug.clear
1744
+ else
1745
+ @editors_in_debug = Array.new
1746
+ end
1747
+ end
1748
+
1749
+ def debug_end
1750
+ debug_reset
1751
+ @editors_in_debug.each{|e|
1752
+ close_editor(e)
1753
+ }
1754
+ end
1755
+
1756
+ def debug_reset
1757
+ if @last_index && @last_e
1758
+ @last_e.unmark_debug(@last_index)
1759
+ end
1760
+ end
1761
+
1762
+ def open_file_in_debug(_filename=nil, _line=nil)
1763
+ debug_reset
1764
+ if _filename && _line
1765
+
1766
+ @last_index = _line.to_s+'.0'
1767
+ _editor_exist = editor_exist?(_filename)
1768
+ @last_e = open_file(_filename, @last_index, false)
1769
+ if !_editor_exist
1770
+ @editors_in_debug << @last_e
1771
+ end
1772
+ @last_e.mark_debug(@last_index) if @last_e
1773
+
1774
+ end
1775
+ end
1776
+
1777
+ def do_buffer_raise(_name, _title='...')
1778
+ _index = @main_frame.enb.index(_name)
1779
+ _new_caption = '...'
1780
+ if _index != -1
1781
+ #_name = @main_frame.enb.pages(_index)
1782
+ #_tab = get_tab_from_name(_name)
1783
+ #@main_frame.enb.raise(_name)
1784
+ _e = @tabs_editor[_name]
1785
+ if _e && _e.file != nil
1786
+ _new_caption = _e.file
1787
+ @find.use(_e)
1788
+ _e.check_file_last_access_time
1789
+ else
1790
+ _new_caption = _title
1791
+ end
1792
+ end
1793
+ if @arcadia.layout.headed?
1794
+ @arcadia.layout.domain(@arcadia['conf'][@name+'.frame'])['root'].top_text(_new_caption)
1795
+ end
1796
+ _title = @tabs_file[_name] != nil ? File.basename(@tabs_file[_name]) :_name
1797
+ EditorContract.instance.buffer_raised(self, 'title'=>_title, 'file'=>@tabs_file[_name])
1798
+ end
1799
+
1800
+ def editor_exist?(_filename)
1801
+ _basefilename = File.basename(_filename)
1802
+ #_basename = _basefilename.split('.')[0]+'_'+_basefilename.split('.')[1]
1803
+
1804
+
1805
+ _index = @main_frame.enb.index(self.tab_name(_filename))
1806
+ return _index != -1
1807
+ end
1808
+
1809
+ def tab_name(_str="")
1810
+ 'ff'+_str.gsub("/","_").gsub(".","_").gsub(":","_").gsub("\\","_")
1811
+ end
1812
+
1813
+ def tab_file_name(_filename="")
1814
+ _fstr = File.expand_path(_filename)
1815
+ _fstr = _filename if _fstr == nil
1816
+ tab_name(_fstr)
1817
+ end
1818
+
1819
+ def open_file(_filename = nil, _text_index='1.0', _mark_selected=true)
1820
+ return if _filename == nil || !File.exist?(_filename)
1821
+ _basefilename = File.basename(_filename)
1822
+ _tab_name = self.tab_file_name(_filename)
1823
+ _index = @main_frame.enb.index(_tab_name)
1824
+ _exist_buffer = _index != -1
1825
+
1826
+ if _exist_buffer
1827
+ open_buffer(_tab_name)
1828
+ else
1829
+ open_buffer(_tab_name, _basefilename)
1830
+ @tabs_file[_tab_name]= _filename
1831
+ @tabs_editor[_tab_name].load_file(_filename)
1832
+ EditorContract.instance.file_opened(self, 'file'=>_filename)
1833
+ end
1834
+
1835
+ if _text_index != nil && _text_index != '1.0'
1836
+ @tabs_editor[_tab_name].text_see(_text_index)
1837
+ @tabs_editor[_tab_name].mark_selected(_text_index) if _mark_selected
1838
+ end
1839
+
1840
+ return @tabs_editor[_tab_name]
1841
+ end
1842
+
1843
+
1844
+ def open_buffer(_buffer_name = nil, _title = nil)
1845
+ _index = @main_frame.enb.index(_buffer_name)
1846
+ if _buffer_name == nil
1847
+ _buffer_name = tab_name('new')
1848
+ _title_new = '*new'
1849
+ end
1850
+
1851
+ if _index != -1
1852
+ _tab = @main_frame.enb.get_frame(_buffer_name)
1853
+ @main_frame.enb.raise(_buffer_name)
1854
+ else
1855
+ _n = 1
1856
+ while @main_frame.enb.index(_buffer_name) != -1
1857
+ _title_new = '*new'+_n.to_s
1858
+ _buffer_name = tab_name('new')+_n.to_s
1859
+ _n =_n+1
1860
+ end
1861
+ if _title == nil
1862
+ _title = _title_new
1863
+ end
1864
+ _tab = @main_frame.enb.insert('end', _buffer_name ,
1865
+ 'text'=> _title,
1866
+ 'raisecmd'=>proc{do_buffer_raise(_buffer_name, _title)}
1867
+ )
1868
+ _e = AgEditor.new(self, _tab)
1869
+ _e.init_editing(_e.file_extension(_title))
1870
+ @tabs_file[_buffer_name]= nil
1871
+ @tabs_editor[_buffer_name]=_e
1872
+ end
1873
+ @main_frame.enb.move(_buffer_name, 1)
1874
+ @main_frame.enb.raise(_buffer_name)
1875
+ @main_frame.enb.see(_buffer_name)
1876
+ return _tab
1877
+ end
1878
+
1879
+ def close_others_editor(_editor, _mod=true)
1880
+ @tabs_editor.values.each do |_e|
1881
+ close_editor(_e) if _e != _editor
1882
+ end
1883
+ end
1884
+
1885
+ def close_all_editor(_editor, _mod=true)
1886
+ @tabs_editor.values.each do |_e|
1887
+ close_editor(_e)
1888
+ end
1889
+ end
1890
+
1891
+ def close_editor(_editor, _mod=true)
1892
+ if ((_mod)&&(_editor.modified?))
1893
+ _message = @main_frame.enb.itemcget(page_name(_editor.page_frame), 'text')+"\n modified. Save?"
1894
+ _r = TkDialog2.new('message'=>_message, 'buttons'=>['Ok','No','Cancel']).show()
1895
+ if _r == 0
1896
+ _editor.save
1897
+ elsif _r == 1
1898
+ close_tab(_editor.page_frame)
1899
+ elsif _r == 2
1900
+ return
1901
+ end
1902
+ else
1903
+ close_tab(_editor.page_frame)
1904
+ end
1905
+ EditorContract.instance.file_closed(self, 'file'=>_editor.file)
1906
+ end
1907
+
1908
+ def close_tab(_page_frame)
1909
+ _name = page_name(_page_frame)
1910
+ @tabs_editor.delete(_name)
1911
+ _index = @main_frame.enb.index(_name)
1912
+ @main_frame.enb.delete(_name)
1913
+ if !@main_frame.enb.pages.empty?
1914
+ @main_frame.enb.raise(@main_frame.enb.pages[_index-1])
1915
+ end
1916
+ end
1917
+
1918
+ def close_file(_filename)
1919
+ close_editor(@tabs_editor[tab_name(_filename)])
1920
+ end
1921
+
1922
+ def save_file(_filename)
1923
+ @tabs_editor[tab_name(_filename)].save
1924
+ end
1925
+
1926
+ def save_as_file(_filename)
1927
+ @tabs_editor[tab_name(_filename)].save_as
1928
+ end
1929
+
1930
+ end
1931
+
1932
+ class Findview < TkFloatTitledFrame
1933
+ def initialize(_parent)
1934
+ super(_parent)
1935
+ #stop_resizing
1936
+ y0 = 10
1937
+ d = 23
1938
+ TkLabel.new(self.frame){
1939
+ text 'Find what:'
1940
+ place('x' => 8,'y' => y0,'height' => 19)
1941
+ }
1942
+ y0 = y0 + d
1943
+ @e_what = Tk::BWidget::ComboBox.new(self.frame){
1944
+ editable true
1945
+ justify 'left'
1946
+ relief 'ridge'
1947
+ autocomplete 'true'
1948
+ #insertbackground '#FFFFFF'
1949
+ entrybg '#FFFFFF'
1950
+ expand 'tab'
1951
+ takefocus 'true'
1952
+ #pack('padx'=>10, 'fill'=>'x')
1953
+ place('relwidth' => 1, 'width'=>-16,'x' => 8,'y' => y0,'height' => 19)
1954
+ }
1955
+ y0 = y0 + d
1956
+ TkLabel.new(self.frame){
1957
+ text 'Replace with:'
1958
+ place('x' => 8,'y' => y0,'height' => 19)
1959
+ }
1960
+ y0 = y0 + d
1961
+
1962
+ @e_with = Tk::BWidget::ComboBox.new(self.frame){
1963
+ editable true
1964
+ justify 'left'
1965
+ relief 'ridge'
1966
+ autocomplete 'true'
1967
+ #insertbackground '#FFFFFF'
1968
+ entrybg '#FFFFFF'
1969
+ expand 'tab'
1970
+ takefocus 'true'
1971
+ #pack('padx'=>10, 'fill'=>'x')
1972
+ place('relwidth' => 1, 'width'=>-16,'x' => 8,'y' => y0,'height' => 19)
1973
+ }
1974
+
1975
+ y0 = y0 + d
1976
+ @cb_reg = TkCheckButton.new(self.frame){|_cb_reg|
1977
+ text 'Use Regular Expression'
1978
+ justify 'left'
1979
+ relief 'flat'
1980
+ #pack('side'=>'left', 'anchor'=>'e')
1981
+ place('x' => 8,'y' => y0,'height' => 22)
1982
+ }
1983
+ y0 = y0 + d
1984
+ @cb_back = TkCheckButton.new(self.frame){|_cb_reg|
1985
+ text 'Search backwards'
1986
+ justify 'left'
1987
+ relief 'flat'
1988
+ #pack('side'=>'left', 'anchor'=>'e')
1989
+ place('x' => 8,'y' => y0,'height' => 22)
1990
+ }
1991
+
1992
+ y0 = y0 + d
1993
+ y0 = y0 + d
1994
+ @buttons_frame = TkFrame.new(self.frame).pack('fill'=>'x', 'side'=>'bottom')
1995
+
1996
+ @b_replace_all = TkButton.new(@buttons_frame){|_b_go|
1997
+ state 'disabled'
1998
+ default 'disabled'
1999
+ text 'Replace All'
2000
+ overrelief 'raised'
2001
+ justify 'center'
2002
+ #width 15
2003
+ pack('side'=>'right','ipadx'=>5, 'padx'=>5)
2004
+ #place('width' => 50,'x' => 0,'y' => y0,'height' => 23,'bordermode' => 'inside')
2005
+ }
2006
+
2007
+
2008
+ @b_replace = TkButton.new(@buttons_frame){|_b_go|
2009
+ state 'disabled'
2010
+ default 'disabled'
2011
+ text 'Replace'
2012
+ overrelief 'raised'
2013
+ justify 'center'
2014
+ #width 15
2015
+ pack('side'=>'right','ipadx'=>5, 'padx'=>5)
2016
+ #place('width' => 50,'x' => 0,'y' => y0,'height' => 23,'bordermode' => 'inside')
2017
+ }
2018
+
2019
+
2020
+ @b_go = TkButton.new(@buttons_frame){|_b_go|
2021
+ compound 'none'
2022
+ default 'disabled'
2023
+ text 'Find Next'
2024
+ #background '#ffffff'
2025
+ #image TkPhotoImage.new('dat' => FIND_GIF)
2026
+ overrelief 'raised'
2027
+ justify 'center'
2028
+ #relief 'ridge'
2029
+ #width 15
2030
+ pack('side'=>'right','ipadx'=>5, 'padx'=>5)
2031
+ #place('width' => 50,'x' => 0,'y' => y0,'height' => 23,'bordermode' => 'inside')
2032
+ }
2033
+ #place('x'=>0,'y'=>0,'relheight'=> 1,'relwidth'=> 1)
2034
+ place('x'=>100,'y'=>100,'height'=> 220,'width'=> 300)
2035
+
2036
+ end
2037
+ end
2038
+
2039
+ class Find < Findview
2040
+ attr_reader :e_what
2041
+ def initialize(_frame, _controller)
2042
+ super(_frame)
2043
+ #@l_file.configure('text'=>_title)
2044
+ #Tk.tk_call('wm', 'title', self, _title )
2045
+ @controller = _controller
2046
+ @forwards = true
2047
+ @find_action = proc{
2048
+ #_radio = @rb.get_value
2049
+
2050
+ #if _radio == 'line'
2051
+ # go_line
2052
+ #else
2053
+ do_find_next
2054
+ #end
2055
+ }
2056
+ @b_go.bind('1', @find_action)
2057
+
2058
+ @b_replace.bind('1', proc{do_replace})
2059
+
2060
+ @b_replace_all.bind('1', proc{do_replace_all})
2061
+
2062
+ e = TkWinfo.children(@e_what)[0]
2063
+ e.bind_append('KeyPress'){|e|
2064
+ case e.keysym
2065
+ when 'Return'
2066
+ @find_action.call
2067
+ hide
2068
+ @editor_caller.text.focus
2069
+ Tk.callback_break
2070
+ else
2071
+ widget_state
2072
+ end
2073
+ }
2074
+ e2 = TkWinfo.children(@e_with)[0]
2075
+ e2.bind_append('KeyPress'){|e|
2076
+ widget_state
2077
+ }
2078
+ @last_index='insert'
2079
+
2080
+ @goto_line_dialog = GoToLine.new(_frame).hide
2081
+ @goto_line_dialog.on_close=proc{@goto_line_dialog.hide}
2082
+
2083
+ @goto_line_dialog.b_go.bind('1',proc{go_line})
2084
+ end
2085
+
2086
+ def do_replace
2087
+ if do_find_next
2088
+ _message = 'Replace "'+@e_what.value+'" with "'+@e_with.value+'" ?'
2089
+ if TkDialog2.new('message'=>_message, 'buttons'=>['Yes','No']).show() == 0
2090
+ self.editor.text.delete(@idx1,@idx2)
2091
+ self.editor.text.insert(@idx1,@e_with.value)
2092
+ self.editor.check_modify
2093
+ end
2094
+ end
2095
+ end
2096
+
2097
+ def do_replace_all
2098
+ while do_find_next
2099
+ _message = 'Replace "'+@e_what.value+'" with "'+@e_with.value+'" ?'
2100
+ _rc = TkDialog2.new('message'=>_message, 'buttons'=>['Yes','No','Annulla']).show()
2101
+ if _rc == 0
2102
+ self.editor.text.delete(@idx1,@idx2)
2103
+ self.editor.text.insert(@idx1,@e_with.value)
2104
+ self.editor.check_modify
2105
+ elsif _rc == 2
2106
+ break
2107
+ end
2108
+ end
2109
+ end
2110
+
2111
+ def widget_state
2112
+ if (@e_what.value.length > 0) && (@e_with.value.length > 0)
2113
+ @b_replace.configure('state'=>'active')
2114
+ @b_replace_all.configure('state'=>'active')
2115
+ else
2116
+ @b_replace.configure('state'=>'disabled')
2117
+ @b_replace_all.configure('state'=>'disabled')
2118
+ end
2119
+ end
2120
+
2121
+
2122
+ def editor
2123
+ if @editor_caller == nil
2124
+ @editor_caller = @controller.raised
2125
+ end
2126
+ return @editor_caller
2127
+ end
2128
+
2129
+ def show_go_to_line_dialog
2130
+ @goto_line_dialog.show
2131
+ end
2132
+
2133
+ def go_line
2134
+ if @goto_line_dialog.e_line.value.length > 0
2135
+ _row = @goto_line_dialog.e_line.value
2136
+ _index = _row+'.1'
2137
+ self.editor.text.see(_index)
2138
+ self.editor.text.tag_add('sel', _index,_index+' lineend')
2139
+ self.editor.text.set_insert(_index)
2140
+ @controller.bookmark_add(self.editor.file, _index)
2141
+ @goto_line_dialog.hide
2142
+ end
2143
+ #self.hide()
2144
+ end
2145
+
2146
+ def use(_editor)
2147
+ if (_editor != @editor_caller)
2148
+ @last_index='insert'
2149
+ @editor_caller = _editor
2150
+ title(_editor.file)
2151
+ end
2152
+ end
2153
+
2154
+ def update_combo(_txt)
2155
+ values = @e_what.cget('values')
2156
+ if (values != nil && !values.include?(_txt))
2157
+ @e_what.insert('end', @e_what.value)
2158
+ end
2159
+ end
2160
+
2161
+ def do_find(_istart=nil)
2162
+ @forwards = @cb_back.cget('onvalue') != @cb_back.cget('variable').value.to_i
2163
+ _found = false
2164
+ @idx1 = nil
2165
+ @idx2 = nil
2166
+ if @e_what.text.length > 0
2167
+ update_combo(@e_what.text)
2168
+ if !_istart && self.editor.text.index('insert')!=nil
2169
+ _istart ='insert'
2170
+ elsif defined?(@last_index)
2171
+ _istart = @last_index
2172
+ else
2173
+ _istart = '1.0'
2174
+ end
2175
+ if @forwards
2176
+ if @cb_reg.cget('onvalue')==@cb_reg.cget('variable').value.to_i
2177
+ _index = self.editor.text.tksearch(['regexp'],@e_what.text,_istart)
2178
+ else
2179
+ _index = self.editor.text.search(@e_what.text,_istart)
2180
+ end
2181
+ else
2182
+
2183
+ if @cb_reg.cget('onvalue')==@cb_reg.cget('variable').value.to_i
2184
+ _index = self.editor.text.tksearch(['regexp','backwards'],@e_what.text,_istart)
2185
+ else
2186
+ _index = self.editor.text.tksearch(['backwards'],@e_what.text,_istart)
2187
+ end
2188
+ end
2189
+ if _index && _index.length>0
2190
+ self.editor.text.see(_index)
2191
+ _row, _col = _index.split('.')
2192
+ _index_sel_end = _row.to_i.to_s+'.'+(_col.to_i+@e_what.text.length).to_i.to_s
2193
+ if @forwards
2194
+ @last_index= _index_sel_end
2195
+ else
2196
+ @last_index= _row.to_i.to_s+'.'+(_col.to_i-1).to_i.to_s
2197
+ end
2198
+ self.editor.text.tag_add('sel', _index,_index_sel_end)
2199
+ self.editor.text.set_insert(_index)
2200
+ @idx1 =_index
2201
+ @idx2 =_index_sel_end
2202
+ _found = true
2203
+ @controller.bookmark_add(self.editor.file, _index)
2204
+ else
2205
+ _message = '"'+@e_what.value+'" not found'
2206
+ TkDialog2.new('message'=>_message, 'buttons'=>['Ok']).show()
2207
+ end
2208
+
2209
+ else
2210
+ self.show()
2211
+ end
2212
+ return _found
2213
+ end
2214
+
2215
+ def do_find_next
2216
+ if @idx1 != nil
2217
+ self.editor.text.tag_remove('sel',@idx1,@idx2)
2218
+ end
2219
+ do_find(@last_index)
2220
+ end
2221
+ end
2222
+
2223
+
2224
+ class KeyTestView < TkToplevel
2225
+ attr_reader :ttest
2226
+ def initialize
2227
+ super
2228
+
2229
+ Tk.tk_call('wm', 'title', self, '...hello' )
2230
+ Tk.tk_call('wm', 'geometry', self, '638x117+200+257' )
2231
+
2232
+ @ttest = TkText.new(self){
2233
+ background '#FFF454'
2234
+ place('relwidth' => '1','relx' => 0,'x' => '0','y' => '0','relheight' => '1','rely' => 0,'height' => '0','bordermode' => 'inside','width' => '0')
2235
+ }
2236
+
2237
+ end
2238
+ end
2239
+
2240
+ class KetTest
2241
+ def initialize
2242
+ kt = KeyTestView.new
2243
+ kt.ttest.bind("KeyPress"){|e|
2244
+ kt.ttest.insert('end'," [ "+e.keysym+" ] ")
2245
+ break
2246
+ }
2247
+ end
2248
+ end
2249
+
2250
+ class CodeInsight
2251
+ end
2252
+
2253
+ class GoToLine < TkFloatTitledFrame
2254
+ attr_reader :e_line
2255
+ attr_reader :b_go
2256
+ def initialize(_parent)
2257
+ super(_parent)
2258
+ #stop_resizing
2259
+ y0 = 10
2260
+ d = 23
2261
+ TkLabel.new(self.frame){
2262
+ text 'Go to line:'
2263
+ place('x' => 8,'y' => y0,'height' => 19)
2264
+ }
2265
+ y0 = y0 + d
2266
+ @e_line = TkEntry.new(self.frame){
2267
+ justify 'left'
2268
+ relief 'ridge'
2269
+ place('relwidth' => 1, 'width'=>-16,'x' => 8,'y' => y0,'height' => 19)
2270
+ }
2271
+
2272
+ y0 = y0 + d
2273
+ y0 = y0 + d
2274
+ @buttons_frame = TkFrame.new(self.frame).pack('fill'=>'x', 'side'=>'bottom')
2275
+
2276
+ @b_go = TkButton.new(@buttons_frame){|_b_go|
2277
+ compound 'none'
2278
+ default 'disabled'
2279
+ text 'Go'
2280
+ overrelief 'raised'
2281
+ justify 'center'
2282
+ pack('side'=>'right','ipadx'=>5, 'padx'=>5)
2283
+ }
2284
+ place('x'=>150,'y'=>150,'height'=> 120,'width'=> 100)
2285
+
2286
+ end
2287
+ end