arcadia 0.1.3 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. data/README +69 -77
  2. data/arcadia.rb +1097 -770
  3. data/base/a-commons.rb +480 -0
  4. data/base/a-contracts.rb +207 -322
  5. data/base/{a-utils.rb → a-tkcommons.rb} +933 -993
  6. data/conf/arcadia.conf +130 -203
  7. data/conf/arcadia.res.rb +1332 -1325
  8. data/ext/ae-action-dispatcher/ae-action-dispatcher.conf +6 -0
  9. data/ext/ae-action-dispatcher/ae-action-dispatcher.rb +22 -0
  10. data/ext/ae-complete-code/ae-complete-code.conf +2 -2
  11. data/ext/ae-complete-code/ae-complete-code.rb +82 -80
  12. data/ext/ae-doc-code/ae-doc-code.conf +2 -2
  13. data/ext/ae-doc-code/ae-doc-code.rb +114 -111
  14. data/ext/ae-editor/ae-editor.conf +110 -105
  15. data/ext/ae-editor/ae-editor.rb +2501 -2287
  16. data/ext/ae-editor/langs/conf.lang +15 -0
  17. data/ext/ae-editor/langs/lang.lang.bind +1 -0
  18. data/ext/ae-editor/langs/rb.lang +67 -0
  19. data/ext/ae-editor/langs/rbw.lang.bind +1 -0
  20. data/ext/ae-event-log/ae-event-log.rb +45 -52
  21. data/ext/ae-file-history/ae-file-history.conf +4 -4
  22. data/ext/ae-file-history/ae-file-history.rb +298 -286
  23. data/ext/ae-flag/ae-flag.conf +6 -6
  24. data/ext/ae-flag/ae-flag.rb +12 -12
  25. data/ext/ae-inspector/ae-inspector.conf +3 -3
  26. data/ext/ae-inspector/ae-inspector.rb +2 -2
  27. data/ext/ae-output-event/ae-output-event.conf +15 -15
  28. data/ext/ae-output/ae-output.conf +5 -3
  29. data/ext/ae-output/ae-output.rb +62 -33
  30. data/ext/ae-palette/ae-palette.conf +3 -3
  31. data/ext/ae-palette/ae-palette.rb +265 -306
  32. data/ext/ae-rad/ae-rad-inspector.rb +1534 -0
  33. data/{base/a-libs.rb → ext/ae-rad/ae-rad-libs.rb} +1118 -846
  34. data/ext/ae-rad/ae-rad-palette.rb +273 -0
  35. data/ext/ae-rad/ae-rad.conf +71 -0
  36. data/ext/ae-rad/ae-rad.rb +56 -0
  37. data/{lib → ext/ae-rad/lib}/tk/al-tk.rb +21 -110
  38. data/{lib → ext/ae-rad/lib}/tk/al-tk.res.rb +0 -0
  39. data/{lib → ext/ae-rad/lib}/tk/al-tkarcadia.rb +26 -26
  40. data/{lib → ext/ae-rad/lib}/tk/al-tkcustom.rb +70 -70
  41. data/{lib → ext/ae-rad/lib}/tkext/al-bwidget.rb +194 -194
  42. data/{lib → ext/ae-rad/lib}/tkext/al-iwidgets.rb +25 -25
  43. data/{lib → ext/ae-rad/lib}/tkext/al-tile.rb +173 -173
  44. data/{lib → ext/ae-rad/lib}/tkext/al-tktable.rb +0 -0
  45. data/ext/ae-ruby-debug/ae-ruby-debug.conf +7 -4
  46. data/ext/ae-ruby-debug/ae-ruby-debug.rb +278 -142
  47. data/ext/ae-search-in-files/ae-search-in-files.conf +15 -0
  48. data/ext/ae-search-in-files/ae-search-in-files.rb +284 -0
  49. data/ext/ae-shell/ae-shell.rb +88 -8
  50. data/ext/ae-shell/sh.rb +7 -0
  51. metadata +93 -79
  52. data/base/a-contracts-work.rb +0 -219
  53. data/base/a-ext.rb +0 -280
  54. data/ext/ae-debug/ae-debug.conf +0 -7
  55. data/ext/ae-debug/ae-debug.rb +0 -601
  56. data/ext/ae-debug/debug1.57.rb +0 -998
data/README CHANGED
@@ -1,45 +1,42 @@
1
- Arcadia Ruby Ide
2
- version 0.1.3
1
+ = Arcadia Ruby Ide
2
+ version 0.2.0
3
3
 
4
4
  by Antonio Galeone
5
- on Jul 2, 2007
5
+ on Oct 25, 2007
6
6
 
7
7
 
8
- About
9
- =====
8
+ == About
9
+
10
10
  Arcadia is a Integrated Development Environment (IDE) for Ruby language
11
11
  written in Ruby using the classic tcl/tk GUI toolkit.
12
12
 
13
13
  Some of Arcadia ruby ide project features include:
14
- -Editor with source browsing, syntax highlighting, code completion
15
- -Debugging support
16
- -Contextual ruby documentation
17
- -Supporting RAD gui building
18
- -Generation of widget-wrapper-independent ruby code
19
- -Working on any platform where ruby and tcl-tk work.
20
- -Highly extensibility architecture.
21
-
22
- This release
23
- ============
24
- -added ruby-debug integration
25
-
26
- How to install
27
- ==============
14
+ * Editor with source browsing, syntax highlighting, code completion
15
+ * Debugging support
16
+ * Contextual ruby documentation
17
+ * Working on any platform where ruby and tcl-tk work.
18
+ * Highly extensibility architecture.
19
+
20
+ == In this release
21
+ * [mod] extension architecture changes
22
+ * [fix] bug-fixing
23
+ * [new] added "search in files" features (in Search menu item)
24
+
25
+ == How to install
28
26
  There are two way:
29
- 1)exec as root on command line "gem install arcadia"
30
- 2)a) untar (on unix) tar -xzf arcadia-<version>.tar.gz
31
- b) unzip (on windows) arcadia-<version>.zip
27
+ 1. exec as root on command line "gem install arcadia"
28
+ or as user "sudo gem install arcadia"
29
+ 2. using archive distribution
30
+ a. untar (on unix) (tar -xzf) arcadia-<version>.tar.gz
31
+ b. unzip (on windows) arcadia-<version>.zip
32
32
 
33
33
 
34
- How to run
35
- ==========
36
- exec on command line "ruby arcadia.rb"
34
+ == How to run
35
+ * exec on command line "ruby arcadia.rb"
37
36
 
38
37
 
39
- Short User guide
40
- ================
41
- I hope that you perceive Arcadia gui enough user frindly.
42
- As you can see the application is splitted in vertical
38
+ == Short User guide
39
+ As you can see the application layout is splitted in vertical
43
40
  and horizontal resizing frames. Clicking on vertical splitter
44
41
  appear two button for left or right one shot frame close.
45
42
  The horizontal splitter has two little button for the same reason
@@ -47,43 +44,44 @@ The horizontal splitter has two little button for the same reason
47
44
  Every frame has a title and a button to expand or resizing it.
48
45
  In this beta release there are very essential feature:
49
46
 
50
- < Toolbar >
47
+ ==== Main Toolbar
51
48
  The toolbar button are in order:
52
- -new, open, save
53
- (relatively to editor extension)
54
- -run current, run last
55
- (for execute the raised file in the editor or the last file executed)
56
- -debug current, debug last, quit debug panel
57
- (for the debug extension that is in very unstable state)
58
- -quit (to exit from arcadia)
59
-
60
- < Editor >
49
+ - new, open, save
50
+ (relatively to edit operation)
51
+ - run current, run last
52
+ (for execute the raised file in the editor or the last runned file)
53
+ - debug current, debug last, quit debug panel
54
+ (for debug need)
55
+ - show rad palette
56
+ (for tk rad need)
57
+ - quit (to exit from arcadia)
58
+
59
+ ==== Editor
61
60
  Editor use the notebook metaphor. Same command are on the popup menu
62
61
  that is raised on "Button-3" click event fundamentalally for closing the tab
63
62
  under the mouse pointer.
64
63
  These are same editor short-cut:
65
- Ctrl-c => copy selected text
66
- Ctrl-v => paste copied text
67
- Ctrl-x => cut selected text
68
- Ctrl-z => undo
69
- Ctrl-f => copy the selected text on input combobox of find dialog and moves focus
70
- Ctrl-s => save
71
- Ctrl-space => completion code
72
- Ctrl-shift-i => indent the selected block
73
- Ctrl-shift-u => unindent the selected block
74
- Ctrl-shift-c => comment/uncomment the selected code block
75
- F5 => execute the file
76
- F3 => find/ find next
77
- F1 => contextual ruby documentation (called from editor or from code completion item, if
78
- no corrispondation is founded a doc tree is build in left side)
79
-
80
- Double-Click on line number set or unset a debug breakpoint
81
-
82
- < File history >
64
+ - Ctrl-c => copy selected text
65
+ - Ctrl-v => paste copied text
66
+ - Ctrl-x => cut selected text
67
+ - Ctrl-z => undo
68
+ - Ctrl-f => copy the selected text on input combobox of find dialog and moves focus
69
+ - Ctrl-s => save
70
+ - Ctrl-space => completion code
71
+ - Ctrl-shift-i => indent the selected block
72
+ - Ctrl-shift-u => unindent the selected block
73
+ - Ctrl-shift-c => comment/uncomment the selected code block
74
+ - F5 => execute the file
75
+ - F3 => find/ find next
76
+ - F1 => contextual ruby documentation (called from editor or from code completion item)
77
+
78
+ - Double-Click on line number set or unset a debug breakpoint
79
+
80
+ ==== File history
83
81
  The last used files are organizing in tree so you can reopen them or there
84
82
  directory by clicking on the tree node.
85
83
 
86
- < Palette >
84
+ ==== Rad Palette
87
85
  It contain the wrapper components for the tk gui building.
88
86
  It is in very unstabled and incomplete state.
89
87
  The first component is a TkTopLevel wrapper, when you click on it a new form is created and a
@@ -95,48 +93,42 @@ On the palette there are also two button, one for deselect and other for copy fr
95
93
  created widget. The copy action copy also the code into the clipboard, so you can copy the
96
94
  code rapresenting the gui into the embedded editor or into external editor.
97
95
 
98
- < Object Inspector >
96
+ ==== Rad Object Inspector
99
97
  It is for modify the widget property at runtime
100
98
 
101
- < Debug >
99
+ ==== Debug
102
100
  It is created when a debug session init.
103
101
  The debug button are: Step Next, Step Into, Step Over, Resume and quit.
104
102
  The debug frame show the local, instance and global variables for each
105
103
  step.
106
104
 
107
- <Configuration>
105
+ ==== Configuration
108
106
  Same Arcadia properties are locally configurabled by editing the file arcadia.conf
109
107
  under ~/.arcadia directory. The format of property definition are:
110
108
  <OPERATING SYSTEM IDENTIFY::>PROPERTY_NAME=PROPERTY_VALUE
111
109
 
112
110
 
113
- Requirement
114
- ===========
111
+ == Requirement
115
112
  I include into distribution also the BWidget lib (under tcl directory) so
116
113
  are require realy only the standard tcl tk lib (tested on tcl tk 8.4).
117
114
  I have tested arcadia with ruby 1.8.4, 1.8.5, 1.8.6 on
118
- FreeBsd6.x,
119
- Vector linux 5.8,
120
- Windows 2000/XP,
121
- Cygwin (note: same page fault error on dll under cygwin may be solved in this way:
122
- by ash.exe exec "/bin/rebaseall").
115
+ * FreeBsd6.x,
116
+ * Vector linux 5.8,
117
+ * Windows 2000/XP,
118
+ * Cygwin (note: same page fault error on dll under cygwin may be solved in this way:
119
+ by ash.exe exec "/bin/rebaseall").
123
120
  If you will test arcadia on other operating system sends me an e-mail.
124
121
 
125
- Developers information
126
- =====================
122
+ ==Developers information
127
123
  Soon i will write samething about the arcadia software architecture (when it is more stable)
128
124
  in order to allow extensions writing and collaborations.
129
125
 
130
126
 
131
127
 
132
- License
133
- =======
128
+ == License
134
129
  Arcadia is released under the Ruby License
135
130
 
136
- Contacts
137
- ========
131
+ == Contacts
138
132
  For questions:
139
133
  antonio-galeone@rubyforge.org
140
- For bugs, support request, feature request https://rubyforge.org/projects/arcadia:
141
-
142
-
134
+ For bugs, support request, features request http://rubyforge.org/projects/arcadia
data/arcadia.rb CHANGED
@@ -1,770 +1,1097 @@
1
- #
2
- # arcadia.rb - Arcadia Ruby ide
3
- # by Antonio Galeone <antonio-galeone@rubyforge.org>
4
- #
5
-
6
- Dir.chdir(File.dirname(__FILE__))
7
- if FileTest.exist?('conf/arcadia.init.rb')
8
- require 'conf/arcadia.init'
9
- end
10
- require "conf/arcadia.res"
11
- require 'tkextlib/bwidget'
12
- require "base/a-utils"
13
- require "base/a-ext"
14
- require "base/a-contracts"
15
- require "observer"
16
-
17
- class Arcadia < TkApplication
18
- include Observable
19
- attr_reader :layout
20
- attr_reader :libs
21
- #attr_reader :main_contract
22
- def initialize
23
- super(
24
- ApplicationParams.new(
25
- 'arcadia',
26
- '0.1.3',
27
- 'conf/arcadia.conf',
28
- 'conf/arcadia.pers'
29
- )
30
- )
31
- self.load_local_config(false)
32
- ObjectSpace.define_finalizer($arcadia, self.class.method(:finalize).to_proc)
33
- publish('action.on_exit', proc{do_exit})
34
- _title = "Arcadia Ruby ide :: [Platform = "+RUBY_PLATFORM+'] [Ruby version = ' + RUBY_VERSION+']'
35
- @root = TkRoot.new{
36
- title _title
37
- withdraw
38
- protocol( "WM_DELETE_WINDOW", $arcadia['action.on_exit'])
39
- }
40
- @on_event = Hash.new
41
- @main_menu = TkMenubar.new.pack('fill'=>'x')
42
- @mf_root = Tk::BWidget::MainFrame.new(@root){
43
- menu @main_menu
44
- }.pack(
45
- 'anchor'=> 'center',
46
- 'fill'=> 'both',
47
- 'expand'=> 1
48
- )
49
-
50
- #.place('x'=>0,'y'=>0,'relwidth'=>1,'relheight'=>1)
51
- @mf_root.show_statusbar('none')
52
- @toolbar = @mf_root.add_toolbar
53
- @is_toolbar_show=self['conf']['toolbar_show']=='yes'
54
- @mf_root.show_toolbar(0,@is_toolbar_show)
55
- @splash = ArcadiaAboutSplash.new('... initialize')
56
- @splash.set_progress(50)
57
- @splash.deiconify
58
- Tk.update
59
- sleep(1)
60
- @splash.next_step('..prepare')
61
- prepare
62
- @splash.last_step('..load finish')
63
- geometry = (TkWinfo.screenwidth(@root)-4).to_s+'x'+
64
- (TkWinfo.screenheight(@root)-20).to_s+'+0+0'
65
- @root.deiconify
66
- @root.raise
67
- @root.focus(true)
68
- @root.geometry(geometry)
69
- Tk.update_idletasks
70
- sleep(1)
71
- @splash.destroy
72
- if @first_run
73
- EditorContract.instance.open_file(self, 'file'=>'README')
74
- end
75
- end
76
-
77
- def show_hide_toolbar
78
- if @is_toolbar_show
79
- @mf_root.show_toolbar(0,false)
80
- @is_toolbar_show = false
81
- else
82
- @mf_root.show_toolbar(0,true)
83
- Tk.update
84
- @is_toolbar_show = true
85
- end
86
-
87
- end
88
-
89
-
90
- def Arcadia.finalize(id)
91
- puts "\nArcadia #{id} dying at #{Time.new}"
92
- end
93
-
94
- def load_libs
95
- @libs = ArcadiaLibs.new(self)
96
- libs = self['conf']['libraries'].split(',')
97
- libs.each{|lib|
98
- if lib
99
- @splash.next_step('... loading library '+lib)
100
- begin
101
- require self['conf']['libraries.'+lib+'.source']
102
- @libs.add_lib(
103
- ArcadiaLibs::ArcadiaLibParams.new(
104
- self['conf']['libraries.'+lib+'.name'],
105
- self['conf']['libraries.'+lib+'.source'],
106
- self['conf']['libraries.'+lib+'.require'],
107
- eval(self['conf']['libraries.'+lib+'.collection.class']))
108
- )
109
- rescue Exception
110
- msg = "Loading lib "+'"'+lib+'"'+" ("+$!.class.to_s+") "+" : "+$! + " at : "+$@.to_s
111
- if Tk.messageBox('icon' => 'error', 'type' => 'okcancel',
112
- 'title' => '(Arcadia) Libs', 'parent' => @root,
113
- 'message' => msg) == 'cancel'
114
- raise
115
- exit
116
- else
117
- Tk.update
118
- end
119
- end
120
- end
121
- }
122
- end
123
-
124
- def load_toolbar_buttons
125
- suf = 'toolbar_buttons'
126
- @buttons = Hash.new
127
- toolbar_buttons = self['conf'][suf].split(',')
128
- toolbar_buttons.each{|groups|
129
- if groups
130
- suf1 = suf+'.'+groups
131
- @splash.next_step('... loading '+suf1)
132
- begin
133
- buttons = self['conf'][suf1].split(',')
134
- buttons.each{|button|
135
- suf2 = suf1+'.'+button
136
- name = self['conf'][suf2+'.name']
137
- text = self['conf'][suf2+'.text']
138
- image = self['conf'][suf2+'.image']
139
- font = self['conf'][suf2+'.font']
140
- background = self['conf'][suf2+'.background']
141
- foreground = self['conf'][suf2+'.foreground']
142
- hint = self['conf'][suf2+'.hint']
143
- action = self['conf'][suf2+'.action']
144
- actions = action.split('->') if action
145
- if actions && actions.length>1
146
- _command = proc{
147
- action_obj = $arcadia[actions[0]]
148
- 1.upto(actions.length-2) do |x|
149
- action_obj = action_obj.send(actions[x])
150
- end
151
- action_obj.send(actions[actions.length-1])
152
- }
153
- elsif action
154
- _command = proc{$arcadia[action].call}
155
- end
156
- @buttons[name] = Tk::BWidget::Button.new(@toolbar){
157
- image TkPhotoImage.new('data' => eval(image)) if image
158
- borderwidth 1
159
- font font if font
160
- background background if background
161
- foreground foreground if foreground
162
- command _command if action
163
- relief 'flat'
164
- helptext hint if hint
165
- text text if text
166
- pack('side' =>'left', :padx=>2, :pady=>2)
167
- }
168
- }
169
- rescue Exception
170
- msg = 'Loading '+groups+'" -> '+buttons.to_s+ '" (' + $!.class.to_s + ") : " + $!.to_s + " at : "+$@.to_s
171
- if Tk.messageBox('icon' => 'error', 'type' => 'okcancel',
172
- 'title' => '(Arcadia) Toolbar', 'parent' => @root,
173
- 'message' => msg) == 'cancel'
174
- raise
175
- exit
176
- else
177
- Tk.update
178
- end
179
- end
180
- end
181
- Tk::BWidget::Separator.new(@toolbar, :orient=>'vertical').pack('side' =>'left', :padx=>2, :pady=>2, :fill=>'y',:anchor=> 'w')
182
- }
183
- end
184
-
185
- def ext_active?(_name)
186
- return (self['conf'][_name+'.active'] != nil && self['conf'][_name+'.active']=='yes')||
187
- (self['conf'][_name+'.active'] == nil)
188
- end
189
-
190
- def load_exts_conf
191
- @exts = Array.new
192
- dirs = Array.new
193
- files = Dir['ext/*'].concat(Dir[ENV["HOME"]+'/.arcadia/ext/*'])
194
- files.each{|f|
195
- dirs << f if File.stat(f).directory? && FileTest.exist?(f+'/'+File.basename(f)+'.conf')
196
- }
197
- dirs.each{|ext_dir|
198
- conf_hash = self.config_file2hash(ext_dir+'/'+File.basename(ext_dir)+'.conf')
199
- conf_hash2 = Hash.new
200
- name = conf_hash['name']
201
- conf_hash.each{|key, value|
202
- var_plat = key.split(':')
203
- if var_plat.length > 1
204
- new_key = var_plat[0] + ':' + name + '.' + var_plat[1]
205
- else
206
- new_key = name+'.'+key
207
- end
208
- conf_hash2[new_key]= value
209
- }
210
- @exts << name
211
- self['conf'].update(conf_hash2)
212
- }
213
- end
214
-
215
- def load_exts
216
-
217
- # create extensions
218
- @exts.each{|extension|
219
- if extension && ext_active?(extension)
220
- @splash.next_step('... creating '+extension)
221
- ext_create(extension)
222
- end
223
- }
224
-
225
- # before_build extensions
226
- @exts.each{|extension|
227
- if extension && ext_active?(extension)
228
- @splash.next_step('... before building '+extension)
229
- ext_method(extension, :before_build)
230
- MainContract.instance.extension_before_build(self, 'obj'=>self[extension])
231
- end
232
- }
233
-
234
- # build extensions
235
- @exts.each{|extension|
236
- if extension && ext_active?(extension)
237
- @splash.next_step('... building '+extension)
238
- ext_method(extension, :build)
239
- MainContract.instance.extension_build(self, 'obj'=>self[extension])
240
- end
241
- }
242
-
243
- # after build extensions
244
- @exts.each{|extension|
245
- if extension && ext_active?(extension)
246
- @splash.next_step('... after building '+extension)
247
- ext_method(extension, :after_build)
248
- MainContract.instance.extension_after_build(self, 'obj'=>self[extension])
249
- end
250
- }
251
-
252
- end
253
-
254
- def ext_create(_extension)
255
- begin
256
- source = self['conf'][_extension+'.require']
257
- class_name = self['conf'][_extension+'.class']
258
- if source.strip.length > 0
259
- #p source
260
- eval('require ' + "'" + source + "'")
261
- end
262
- if class_name.strip.length > 0
263
- publish(_extension, eval(class_name).new(self, _extension))
264
- end
265
- rescue Exception
266
- raise
267
- msg = "Loading "+'"'+extension+'"'+" ("+$!.class.to_s+") "+" : "+$! + " at : "+$@.to_s
268
- ans = Tk.messageBox('icon' => 'error', 'type' => 'abortretryignore',
269
- 'title' => '(Arcadia) Extensions', 'parent' => @root,
270
- 'message' => msg)
271
- if ans == 'abort'
272
- raise
273
- exit
274
- elsif ans == 'retry'
275
- retry
276
- else
277
- Tk.update
278
- end
279
- end
280
- end
281
-
282
- def ext_method(_extension, _method)
283
- begin
284
- self[_extension].send(_method)
285
- rescue Exception
286
- msg = _method.to_s+' "'+_extension.to_s+'"'+" ("+$!.class.to_s+") "+" : "+$! + "\n at : "+$@.to_s
287
- ans = Tk.messageBox('icon' => 'warning', 'type' => 'abortretryignore',
288
- 'title' => '(Arcadia) Extensions', 'parent' => @root,
289
- 'message' => msg)
290
- if ans == 'abort'
291
- raise
292
- exit
293
- elsif ans == 'retry'
294
- retry
295
- else
296
- Tk.update
297
- end
298
- end
299
- end
300
-
301
-
302
- def prepare
303
- super
304
- @splash.next_step('...initialize')
305
- @layout = ArcadiaLayout.new(self, @mf_root.get_frame)
306
-
307
- @layout.add_cols(0,0,225)
308
- @layout.add_rows(0,0,180)
309
- # @layout.add_rows(0,1,500)
310
- @layout.add_rows_perc(0,1,70)
311
-
312
-
313
- @layout.add_headers
314
- @splash.next_step
315
- self.load_libs
316
- @splash.next_step
317
- @splash.next_step('... load extensions')
318
- self.load_exts_conf
319
- self.load_local_config
320
- self.load_exts
321
- publish('buffers.code.in_memory',Hash.new)
322
- publish('action.load_code_from_buffers', proc{TkBuffersChoise.new})
323
- publish('output.action.run_last', proc{$arcadia['output'].run_last})
324
- publish('main.action.open_file', proc{self['editor'].open_file(Tk.getOpenFile)})
325
- @splash.next_step('... load obj controller')
326
- @splash.next_step('... load editor')
327
- publish('main.action.new_file',proc{$arcadia['editor'].open_buffer()})
328
- publish('main.action.edit_cut',proc{$arcadia['editor'].raised.text.text_cut()})
329
- publish('main.action.edit_copy',proc{$arcadia['editor'].raised.text.text_copy()})
330
- publish('main.action.edit_paste',proc{$arcadia['editor'].raised.text.text_paste()})
331
- @splash.next_step('... load actions')
332
- publish('action.test.keys', proc{KetTest.new})
333
- publish('action.get.font', proc{Tk::BWidget::SelectFont::Dialog.new.create})
334
- @splash.next_step
335
- publish('action.show_about', proc{ArcadiaAboutSplash.new.deiconify})
336
- # publish('main.menu', @main_menu)
337
- publish('main.menu', AMainMenu.new(@main_menu))
338
- @splash.next_step
339
- publish('objic.action.raise_active_obj',
340
- proc{
341
- InspectorContract.instance.raise_active_toplevel(self)
342
- }
343
- )
344
- load_toolbar_buttons
345
- end
346
-
347
- def do_exit
348
- q1 = (Tk.messageBox('icon' => 'question', 'type' => 'yesno',
349
- 'title' => '(Arcadia) Exit', 'parent' => @root,
350
- 'message' => "Do you want exit?")=='yes')
351
- if q1 && can_exit?
352
- do_finalize
353
- @root.destroy
354
- end
355
- end
356
-
357
- def can_exit?
358
- _can_exit = true
359
- @exts.each{|extension|
360
- if ext_active?(extension) && !self[extension].can_exit_query
361
- _can_exit = false
362
- break
363
- end
364
- }
365
- return _can_exit
366
- end
367
-
368
- def do_finalize
369
- @exts.each{|extension|
370
- self[extension].finalize if ext_active?(extension)
371
- }
372
- self.write_persist
373
- end
374
- end
375
-
376
-
377
- class AMainMenu < TkMenubar
378
-
379
- def initialize(menu)
380
- # create main menu
381
- @menu = menu
382
- build
383
- menu.foreground('grey40')
384
- menu.activeforeground('red')
385
- menu.relief('groove')
386
- menu.borderwidth(0)
387
- menu.font($arcadia['conf']['main.mainmenu.font'])
388
- end
389
-
390
- def build
391
- menu_spec_file = [
392
- ['File', 0],
393
- ['Open', $arcadia['main.action.open_file'], 0],
394
- ['New', $arcadia['main.action.new_file'], 0],
395
- ['Save', proc{EditorContract.instance.save_file_raised(self)},0],
396
- ['Save as ...', proc{EditorContract.instance.save_as_file_raised(self)},0],
397
- '---',
398
- ['Quit', $arcadia['action.on_exit'], 0]]
399
- menu_spec_edit = [['Edit', 0],
400
- ['Cut', $arcadia['main.action.edit_cut'], 2],
401
- ['Copy', $arcadia['main.action.edit_copy'], 0],
402
- ['Paste', $arcadia['main.action.edit_paste'], 0]]
403
- menu_spec_search = [['Search', 0],
404
- ['Find ...', proc{EditorContract.instance.show_search_dialog(self)}, 2],
405
- ['Go to line ...', proc{EditorContract.instance.show_goto_line_dialog(self)}, 2]]
406
- menu_spec_view = [['View', 0],['Show/Hide Toolbar', proc{$arcadia.show_hide_toolbar}, 2]]
407
- menu_spec_tools = [['Tools', 0],
408
- ['Build ruby doc tree', proc{EditorContract.instance.build_doc_tree(self)}, 2],
409
- ['Keys-test', $arcadia['action.test.keys'], 2]
410
- ]
411
- menu_spec_help = [['Help', 0],
412
- ['About', $arcadia['action.show_about'], 2],]
413
- @menu.add_menu(menu_spec_file)
414
- @menu.add_menu(menu_spec_edit)
415
- @menu.add_menu(menu_spec_search)
416
- @menu.add_menu(menu_spec_view)
417
- @menu.add_menu(menu_spec_tools)
418
- @menu.add_menu(menu_spec_help)
419
- end
420
-
421
- end
422
-
423
-
424
- class ArcadiaAboutSplash < TkToplevel
425
- attr :progress
426
-
427
- def initialize(_txt=nil)
428
- #_bgcolor = '#B83333'
429
- _bgcolor = '#000000'
430
- super()
431
- relief 'flat'
432
- background _bgcolor
433
- highlightbackground _bgcolor
434
- highlightthickness 6
435
- borderwidth 1
436
- withdraw
437
- overrideredirect(true)
438
-
439
- @tkLabel3 = TkLabel.new(self){
440
- image TkPhotoImage.new('format'=>'GIF','data' =>A_LOGO_GIF)
441
- background _bgcolor
442
- place('x'=> 20,'y' => 20)
443
- }
444
- @tkLabel1 = TkLabel.new(self){
445
- text 'Arcadia'
446
- background _bgcolor
447
- foreground '#ffffff'
448
- font Arcadia.instance['conf']['splash.title.font']
449
- justify 'left'
450
- place('width' => '190','x' => 120,'y' => 10,'height' => 25)
451
- }
452
- @tkLabelRuby = TkLabel.new(self){
453
- image TkPhotoImage.new('data' =>RUBY_DOCUMENT_GIF)
454
- background _bgcolor
455
- place('x'=> 150,'y' => 40)
456
- }
457
- @tkLabel2 = TkLabel.new(self){
458
- text 'Ruby ide'
459
- background _bgcolor
460
- foreground '#ffffff'
461
- font Arcadia.instance['conf']['splash.subtitle.font']
462
- justify 'left'
463
- place('width' => '90','x' => 170,'y' => 40,'height' => 19)
464
- }
465
- @tkLabelVersion = TkLabel.new(self){
466
- text 'version: '+$arcadia['applicationParams'].version
467
- background _bgcolor
468
- foreground '#ffffff'
469
- font Arcadia.instance['conf']['splash.version.font']
470
- justify 'left'
471
- place('width' => '100','x' => 150,'y' => 60,'height' => 19)
472
- }
473
- @tkLabelStep = TkLabel.new(self){
474
- text _txt
475
- background _bgcolor
476
- foreground 'yellow'
477
- font Arcadia.instance['conf']['splash.banner.font']
478
- justify 'left'
479
- anchor 'w'
480
- place('width'=>-5,'relwidth' => 1,'x' => 5,'y' => 175,'height' => 19)
481
- }
482
- @tkLabel21 = TkLabel.new(self){
483
- text 'by Antonio Galeone - 2007'
484
- background _bgcolor
485
- foreground '#ffffff'
486
- font Arcadia.instance['conf']['splash.credits.font']
487
- justify 'left'
488
- place('width' => '190','x' => 130,'y' => 146,'height' => 19)
489
- }
490
- @progress = TkVariable.new
491
- reset
492
- _width = 340
493
- _height = 210
494
- #_width = 0;_height = 0
495
- _x = TkWinfo.screenwidth(self)/2 - _width / 2
496
- _y = TkWinfo.screenheight(self)/2 - _height / 2
497
- geometry = _width.to_s+'x'+_height.to_s+'+'+_x.to_s+'+'+_y.to_s
498
- Tk.tk_call('wm', 'geometry', self, geometry )
499
- bind("Double-Button-1", proc{self.destroy})
500
- end
501
-
502
- def set_progress(_max=10)
503
- @max = _max
504
- Tk::BWidget::ProgressBar.new(self, :width=>150, :height=>10,
505
- :background=>'black',
506
- :foreground=>'yellow',
507
- :variable=>@progress,
508
- :borderwidth=>0,
509
- :relief=>'flat',
510
- :maximum=>_max).place('width' => '150','x' => 145,'y' => 95,'height' => 15)
511
- end
512
-
513
- def reset
514
- @progress.value = -1
515
- end
516
-
517
- def next_step(_txt = nil)
518
- @progress.numeric += 1
519
- labelStep(_txt) if _txt
520
- end
521
-
522
- def labelStep(_txt)
523
- @tkLabelStep.text = _txt
524
- Tk.update
525
- end
526
-
527
- def last_step(_txt = nil)
528
- @progress.numeric = @max
529
- labelStep(_txt) if _txt
530
- end
531
-
532
- end
533
-
534
- class TkBuffersChoiseView < TkToplevel
535
-
536
- def initialize
537
- super
538
- Tk.tk_call('wm', 'title', self, '...hello' )
539
- Tk.tk_call('wm', 'geometry', self, '150x217+339+198' )
540
- @lb = TkListbox.new(self){
541
- background '#fedbd7'
542
- relief 'groove'
543
- place('relwidth' => '1','relx' => 0,'x' => '0','y' => '0','relheight' => '1','rely' => 0,'height' => '0','bordermode' => 'inside','width' => '0')
544
- }
545
- end
546
-
547
- end
548
-
549
- class TkBuffersChoise < TkBuffersChoiseView
550
-
551
- def initialize
552
- super
553
- @lb.value= $arcadia['buffers.code.in_memory'].keys
554
- @lb.bind("Double-ButtonPress-1",proc{
555
- _sel = @lb.get('active')
556
- Revparsel.new($arcadia['buffers.code.in_memory'][_sel])
557
- @lb.delete('active')
558
- $arcadia['buffers.code.in_memory'].delete(_sel)
559
- destroy
560
- })
561
- raise
562
- end
563
-
564
- end
565
-
566
- class ArcadiaLayout
567
- include Observable
568
- ArcadiaPanelInfo = Struct.new( "ArcadiaPanelInfo",
569
- :name,
570
- :title,
571
- :frame
572
- )
573
-
574
- def initialize(_arcadia, _frame, _autotab=true)
575
- @arcadia = _arcadia
576
- @frames = Array.new
577
- @frames[0] = Array.new
578
- @frames[0][0] = _frame
579
- @domains = Array.new
580
- @domains[0] = Array.new
581
- @domains[0][0] = '_domain_root_'
582
- @panels = Hash.new
583
- @panels['_domain_root_']= Hash.new
584
- @panels['_domain_root_']['root']= _frame
585
- @panels['_domain_root_']['sons'] = Hash.new
586
- @autotab = _autotab
587
- @headed = false
588
- ArcadiaContractListener.new(self, MainContract, :do_main_event)
589
- end
590
- def root
591
- @panels['_domain_root_']['root']
592
- end
593
- def do_main_event(_event)
594
- case _event.signature
595
- when MainContract::RAISE_EXTENSION
596
- p = @panels[_event.context.domain]
597
- if p && p['notebook'] != nil && _event.channel == '0'
598
- p['notebook'].raise(_event.context.extension)
599
- end
600
- end
601
- end
602
-
603
- def _prepare_rows(_row,_col, _height, _perc=false, _top_name=nil, _bottom_name=nil)
604
- if (@frames[_row][_col] != nil)
605
- _h = AGTkOSplittedFrames.new(@frames[_row][_col],_height, _perc)
606
- if @frames[_row + 1] == nil
607
- @frames[_row + 1] = Array.new
608
- @domains[_row + 1] = Array.new
609
- end
610
- @frames[_row][_col] = _h.top_frame
611
- @frames[_row + 1][_col] = _h.bottom_frame
612
-
613
- _top_name = _row.to_s+'.'+_col.to_s if _top_name == nil
614
- @panels[_top_name] = Hash.new
615
- @panels[_top_name]['root'] = @frames[_row][_col]
616
- @panels[_top_name]['sons'] = Hash.new
617
- @domains[_row][_col] = _top_name
618
-
619
- _bottom_name = (_row+1).to_s+'.'+_col.to_s if _bottom_name == nil
620
- @panels[_bottom_name] = Hash.new
621
- @panels[_bottom_name]['root'] = @frames[_row + 1][_col]
622
- @panels[_bottom_name]['sons'] = Hash.new
623
- @domains[_row + 1][_col] = _bottom_name
624
- end
625
- end
626
- private :_prepare_rows
627
-
628
- def add_rows(_row,_col, _height, _top_name=nil, _bottom_name=nil)
629
- _prepare_rows(_row,_col, _height, false, _top_name, _bottom_name)
630
- end
631
-
632
- def add_rows_perc(_row,_col, _height, _top_name=nil, _bottom_name=nil)
633
- _prepare_rows(_row,_col, _height, true, _top_name, _bottom_name)
634
- end
635
-
636
-
637
- def add_cols(_row,_col, _width, _left_name=nil, _right_name=nil)
638
- if (@frames[_row][_col] != nil)
639
- _w = AGTkVSplittedFrames.new(@frames[_row][_col],_width)
640
- @frames[_row][_col] = _w.left_frame
641
- @frames[_row][_col + 1] = _w.right_frame
642
-
643
- _left_name = _row.to_s+'.'+_col.to_s if _left_name == nil
644
- @panels[_left_name] = Hash.new
645
- @panels[_left_name]['root'] = @frames[_row][_col]
646
- @panels[_left_name]['sons'] = Hash.new
647
- @domains[_row][_col] = _left_name
648
-
649
- _right_name = _row.to_s+'.'+(_col+1).to_s if _right_name == nil
650
- @panels[_right_name] = Hash.new
651
- @panels[_right_name]['root'] = @frames[_row][_col + 1]
652
- @panels[_right_name]['sons'] = Hash.new
653
- @domains[_row][_col + 1] = _right_name
654
- end
655
- end
656
-
657
- def add_headers
658
- @domains.each{|row|
659
- row.each{|domain|
660
- @panels[domain]['root']= TkTitledFrame.new(@panels[domain]['root'], '...').place('x'=>0, 'y'=>0,'relheight'=>1, 'relwidth'=>1) if @panels[domain]
661
- }
662
- }
663
- @headed = true
664
- end
665
-
666
- def headed?
667
- @headed
668
- end
669
-
670
- def autotab?
671
- @autotab
672
- end
673
-
674
- def registed?(_domain_name, _name)
675
- @panels[_domain_name]['sons'][_name] != nil
676
- end
677
-
678
- def register_panel(_domain_name, _name, _title)
679
- p = @panels[_domain_name]
680
- if p!=nil
681
- num = p['sons'].length
682
- if @headed
683
- p['root'].title(_title)
684
- root_frame = p['root'].frame
685
- else
686
- root_frame = p['root']
687
- end
688
- if (num == 0 && @autotab)
689
- api = ArcadiaPanelInfo.new(_name,_title,nil)
690
- api.frame = TkFrame.new(root_frame).place('x'=>0, 'y'=>0, 'relwidth'=>1, 'relheight'=>1)
691
- p['sons'][_name] = api
692
- return api.frame
693
- else
694
- if num == 1 && @autotab && p['notebook'] == nil
695
- p['notebook'] = Tk::BWidget::NoteBook.new(root_frame){
696
- tabbevelsize 0
697
- internalborderwidth 0
698
- pack('fill'=>'both', :padx=>0, :pady=>0, :expand => 'yes')
699
- }
700
- api = p['sons'].values[0]
701
- api_tab_frame = p['notebook'].insert('end',
702
- api.name,
703
- 'text'=>api.title,
704
- 'raisecmd'=>proc{
705
- p['root'].title(api.title)
706
- p['root'].top_text('')
707
- changed
708
- notify_observers('RAISE', api.name)
709
- }
710
- )
711
- api.frame.place('in'=>api_tab_frame, 'x'=>0, 'y'=>0, 'relwidth'=>1, 'relheight'=>1)
712
- api.frame.raise
713
- elsif (num==0 && !@autotab)
714
- p['notebook'] = Tk::BWidget::NoteBook.new(root_frame){
715
- tabbevelsize 0
716
- internalborderwidth 0
717
- pack('fill'=>'both', :padx=>0, :pady=>0, :expand => 'yes')
718
- }
719
- end
720
- _panel = p['notebook'].insert('end',_name ,
721
- 'text'=>_title,
722
- #'background'=>_tab_bg,
723
- 'raisecmd'=>proc{
724
- p['root'].title(_title)
725
- changed
726
- notify_observers('RAISE', _name)
727
- }
728
- )
729
-
730
- # if _tab_bg
731
- # _panel = p['notebook'].insert('end',_name , 'text'=>_title, 'background'=>_tab_bg)
732
- # else
733
- # _panel = p['notebook'].insert('end',_name , 'text'=>_title)
734
- # end
735
- p['sons'][_name] = ArcadiaPanelInfo.new(_name,_title,_panel)
736
- p['notebook'].raise(_name)
737
- return _panel
738
- end
739
- end
740
- end
741
-
742
- def unregister_panel(_domain_name, _name)
743
- @panels[_domain_name]['sons'].delete(_name)
744
- @panels[_domain_name]['notebook'].delete(_name)
745
- new_raise_key = @panels[_domain_name]['sons'].keys[@panels[_domain_name]['sons'].length-1]
746
- @panels[_domain_name]['notebook'].raise(new_raise_key)
747
- end
748
-
749
- def raise_panel(_domain_name, _name)
750
- @panels[_domain_name]['notebook'].raise(_name) if @panels[_domain_name] && @panels[_domain_name]['notebook']
751
- end
752
-
753
- def [](_row, _col)
754
- @frames[_row][_col]
755
- end
756
-
757
- def frame(_domain_name, _name)
758
- @panels[_domain_name]['sons'][_name].frame
759
- end
760
-
761
- def domain(_domain_name)
762
- @panels[_domain_name]
763
- end
764
-
765
- def domain_root_frame(_domain_name)
766
- @panels[_domain_name]['root'].frame
767
- end
768
- end
769
-
770
- Arcadia.new.run
1
+ #
2
+ # arcadia.rb - Arcadia Ruby ide
3
+ # by Antonio Galeone <antonio-galeone@rubyforge.org>
4
+ #
5
+
6
+ Dir.chdir(File.dirname(__FILE__))
7
+ if FileTest.exist?('conf/arcadia.init.rb')
8
+ require 'conf/arcadia.init'
9
+ end
10
+ require "conf/arcadia.res"
11
+ require 'tkextlib/bwidget'
12
+ require "base/a-tkcommons"
13
+ require "base/a-contracts"
14
+ require "observer"
15
+
16
+ class Arcadia < TkApplication
17
+ include Observable
18
+ attr_reader :layout
19
+ attr_reader :main_menu
20
+ #attr_reader :libs
21
+ #attr_reader :root
22
+ def initialize
23
+ super(
24
+ ApplicationParams.new(
25
+ 'arcadia',
26
+ '0.2.0',
27
+ 'conf/arcadia.conf',
28
+ 'conf/arcadia.pers'
29
+ )
30
+ )
31
+ ArcadiaDialogManager.new(self)
32
+ self.load_local_config(false)
33
+ ObjectSpace.define_finalizer($arcadia, self.class.method(:finalize).to_proc)
34
+ publish('action.on_exit', proc{do_exit})
35
+ _title = "Arcadia Ruby ide :: [Platform = "+RUBY_PLATFORM+'] [Ruby version = ' + RUBY_VERSION+']'
36
+ @root = TkRoot.new{
37
+ title _title
38
+ withdraw
39
+ protocol( "WM_DELETE_WINDOW", $arcadia['action.on_exit'])
40
+ }
41
+ @on_event = Hash.new
42
+ @main_menu_bar = TkMenubar.new.pack('fill'=>'x')
43
+ @mf_root = Tk::BWidget::MainFrame.new(@root){
44
+ menu @main_menu_bar
45
+ }.pack(
46
+ 'anchor'=> 'center',
47
+ 'fill'=> 'both',
48
+ 'expand'=> 1
49
+ )
50
+
51
+ #.place('x'=>0,'y'=>0,'relwidth'=>1,'relheight'=>1)
52
+ @mf_root.show_statusbar('none')
53
+ #@toolbar = @mf_root.add_toolbar
54
+ @main_toolbar = ArcadiaMainToolbar.new(self, @mf_root.add_toolbar)
55
+ @is_toolbar_show=self['conf']['user_toolbar_show']=='yes'
56
+ @mf_root.show_toolbar(0,@is_toolbar_show)
57
+ @splash = ArcadiaAboutSplash.new('... initialize')
58
+ @splash.set_progress(50)
59
+ @splash.deiconify
60
+ Tk.update
61
+ #sleep(1)
62
+ @splash.next_step('..prepare')
63
+ prepare
64
+ @splash.last_step('..load finish')
65
+ geometry = (TkWinfo.screenwidth(@root)-4).to_s+'x'+
66
+ (TkWinfo.screenheight(@root)-20).to_s+'+0+0'
67
+ @root.deiconify
68
+ @root.raise
69
+ @root.focus(true)
70
+ @root.geometry(geometry)
71
+ Tk.update_idletasks
72
+ #sleep(1)
73
+ @splash.destroy
74
+ if @first_run
75
+ Arcadia.process_event(OpenBufferEvent.new(self,'file'=>'README'))
76
+ elsif ARGV.length > 0
77
+ ARGV.each{|_f|
78
+ Arcadia.process_event(OpenBufferEvent.new(self,'file'=>_f)) if File.exist?(_f)
79
+ }
80
+ end
81
+ Arcadia.add_listener(self, QuitEvent)
82
+ end
83
+
84
+ def on_quit(_event)
85
+ self.do_exit
86
+ end
87
+
88
+ def show_hide_toolbar
89
+ if @is_toolbar_show
90
+ @mf_root.show_toolbar(0,false)
91
+ @is_toolbar_show = false
92
+ else
93
+ @mf_root.show_toolbar(0,true)
94
+ Tk.update
95
+ @is_toolbar_show = true
96
+ end
97
+
98
+ end
99
+
100
+
101
+ def Arcadia.finalize(id)
102
+ puts "\nArcadia #{id} dying at #{Time.new}"
103
+ end
104
+
105
+ def ext_active?(_name)
106
+ return (self['conf'][_name+'.active'] != nil && self['conf'][_name+'.active']=='yes')||
107
+ (self['conf'][_name+'.active'] == nil)
108
+ end
109
+
110
+ def load_exts_conf
111
+ @exts = Array.new
112
+ dirs = Array.new
113
+ files = Dir['ext/*'].concat(Dir[ENV["HOME"]+'/.arcadia/ext/*']).sort
114
+ files.each{|f|
115
+ dirs << f if File.stat(f).directory? && FileTest.exist?(f+'/'+File.basename(f)+'.conf')
116
+ }
117
+ dirs.each{|ext_dir|
118
+ conf_hash = self.properties_file2hash(ext_dir+'/'+File.basename(ext_dir)+'.conf')
119
+ conf_hash2 = Hash.new
120
+ name = conf_hash['name']
121
+ conf_hash.each{|key, value|
122
+ var_plat = key.split(':')
123
+ if var_plat.length > 1
124
+ new_key = var_plat[0] + ':' + name + '.' + var_plat[1]
125
+ else
126
+ new_key = name+'.'+key
127
+ end
128
+ conf_hash2[new_key]= value
129
+ }
130
+ @exts << name
131
+ self['conf'].update(conf_hash2)
132
+ }
133
+ end
134
+
135
+ def do_build
136
+
137
+ # create extensions
138
+ @exts.each{|extension|
139
+ if extension && ext_active?(extension)
140
+ @splash.next_step('... creating '+extension)
141
+ ext_create(extension)
142
+ end
143
+ }
144
+ _build_event = Arcadia.process_event(BuildEvent.new(self))
145
+ end
146
+
147
+ def ext_create(_extension)
148
+ begin
149
+ source = self['conf'][_extension+'.require']
150
+ class_name = self['conf'][_extension+'.class']
151
+ if source.strip.length > 0
152
+ #p source
153
+ eval('require ' + "'" + source + "'")
154
+ end
155
+ if class_name.strip.length > 0
156
+ publish(_extension, eval(class_name).new(self, _extension))
157
+ end
158
+ rescue Exception
159
+ raise
160
+ msg = "Loading "+'"'+extension+'"'+" ("+$!.class.to_s+") "+" : "+$! + " at : "+$@.to_s
161
+ ans = Tk.messageBox('icon' => 'error', 'type' => 'abortretryignore',
162
+ 'title' => '(Arcadia) Extensions', 'parent' => @root,
163
+ 'message' => msg)
164
+ if ans == 'abort'
165
+ raise
166
+ exit
167
+ elsif ans == 'retry'
168
+ retry
169
+ else
170
+ Tk.update
171
+ end
172
+ end
173
+ end
174
+
175
+ def ext_method(_extension, _method)
176
+ begin
177
+ self[_extension].send(_method)
178
+ rescue Exception
179
+ msg = _method.to_s+' "'+_extension.to_s+'"'+" ("+$!.class.to_s+") "+" : "+$! + "\n at : "+$@.to_s
180
+ ans = Tk.messageBox('icon' => 'warning', 'type' => 'abortretryignore',
181
+ 'title' => '(Arcadia) Extensions', 'parent' => @root,
182
+ 'message' => msg)
183
+ if ans == 'abort'
184
+ raise
185
+ exit
186
+ elsif ans == 'retry'
187
+ retry
188
+ else
189
+ Tk.update
190
+ end
191
+ end
192
+ end
193
+
194
+
195
+ def prepare
196
+ super
197
+ @splash.next_step('...initialize')
198
+ @layout = ArcadiaLayout.new(self, @mf_root.get_frame)
199
+
200
+ @layout.add_cols(0,0,225)
201
+ #@layout.add_rows(0,0,180)
202
+ @layout.add_rows_perc(0,1,70)
203
+
204
+ # @layout.add_rows_perc(0,0,70)
205
+ # @layout.add_cols(0,0,225)
206
+ # @layout.add_rows(0,0,180)
207
+
208
+
209
+
210
+ @layout.add_headers
211
+ @splash.next_step
212
+ #self.load_libs
213
+ @splash.next_step
214
+ @splash.next_step('... load extensions')
215
+ self.load_exts_conf
216
+ self.load_local_config
217
+ self.do_build
218
+ publish('buffers.code.in_memory',Hash.new)
219
+ publish('action.load_code_from_buffers', proc{TkBuffersChoise.new})
220
+ publish('output.action.run_last', proc{$arcadia['output'].run_last})
221
+ publish('main.action.open_file', proc{self['editor'].open_file(Tk.getOpenFile)})
222
+ @splash.next_step('... load obj controller')
223
+ @splash.next_step('... load editor')
224
+ publish('main.action.new_file',proc{$arcadia['editor'].open_buffer()})
225
+ publish('main.action.edit_cut',proc{$arcadia['editor'].raised.text.text_cut()})
226
+ publish('main.action.edit_copy',proc{$arcadia['editor'].raised.text.text_copy()})
227
+ publish('main.action.edit_paste',proc{$arcadia['editor'].raised.text.text_paste()})
228
+ @splash.next_step('... load actions')
229
+ publish('action.test.keys', proc{KetTest.new})
230
+ publish('action.get.font', proc{Tk::BWidget::SelectFont::Dialog.new.create})
231
+ @splash.next_step
232
+ publish('action.show_about', proc{ArcadiaAboutSplash.new.deiconify})
233
+ # publish('main.menu', @main_menu)
234
+ @main_menu = ArcadiaMainMenu.new(@main_menu_bar)
235
+ #publish('main.menu', ArcadiaMainMenu.new(@main_menu))
236
+ @splash.next_step
237
+ publish('objic.action.raise_active_obj',
238
+ proc{
239
+ InspectorContract.instance.raise_active_toplevel(self)
240
+ }
241
+ )
242
+ @splash.next_step('... toolbar buttons ')
243
+ #@main_toolbar.load_toolbar_buttons
244
+
245
+ #load user controls
246
+ #Arcadia control
247
+ load_user_control(@main_menu)
248
+ load_user_control(@main_toolbar)
249
+ #Extension control
250
+ @exts.each{|ext|
251
+ @splash.next_step("... load #{ext} user controls ")
252
+ load_user_control(@main_menu, ext)
253
+ load_user_control(@main_toolbar, ext)
254
+ }
255
+ load_user_control(@main_menu,"","e")
256
+ load_user_control(@main_toolbar,"","e")
257
+ end
258
+
259
+ def load_user_control(_user_control, _ext='', _pre='')
260
+ return unless _ext && ext_active?(_ext)
261
+
262
+ if _ext.length > 0 && self[_ext]
263
+ _self_on_eval = self[_ext]
264
+ suf = "#{_ext}.#{_user_control.class::SUF}"
265
+ else
266
+ _self_on_eval = self
267
+ suf = "#{_user_control.class::SUF}"
268
+ end
269
+ if _pre.length > 0
270
+ suf = "#{_pre}.#{suf}"
271
+ end
272
+ contexts = self['conf']["#{suf}.contexts"]
273
+ return if contexts.nil?
274
+ groups = contexts.split(',')
275
+ groups.each{|group|
276
+ if group
277
+ suf1 = suf+'.'+group
278
+ begin
279
+ context_path = self['conf']["#{suf1}.context_path"]
280
+ property = proc{|_str, _suf| self['conf']["#{_suf}.#{_str}"]}
281
+ property_to_eval = proc{|_str, _suf|
282
+ p = self['conf']["#{_suf}.#{_str}"]
283
+ _self_on_eval.instance_eval(p) if p
284
+ }
285
+ items = self['conf'][suf1].split(',')
286
+ items.each{|item|
287
+ suf2 = suf1+'.'+item
288
+ disabled = !self['conf']["#{suf2}.disabled"].nil?
289
+ # property = proc{|_str| self['conf']["#{suf2}.#{_str}"]}
290
+ # property_to_eval = proc{|_str|
291
+ # p = self['conf']["#{suf2}.#{_str}"]
292
+ # _self_on_eval.instance_eval(p) if p
293
+ # }
294
+ name = property.call('name',suf2)
295
+ caption = property.call('caption',suf2)
296
+ hint = property.call('hint',suf2)
297
+ event_class = property_to_eval.call('event_class',suf2)
298
+
299
+ event_args = property_to_eval.call('event_args',suf2)
300
+ image_data = property_to_eval.call('image_data',suf2)
301
+ i = _user_control.new_item(self,
302
+ 'name'=>name,
303
+ 'caption'=>caption,
304
+ 'hint'=>hint,
305
+ 'event_class' =>event_class,
306
+ 'event_args' =>event_args,
307
+ 'image_data' =>image_data,
308
+ 'context'=>group,
309
+ 'context_path'=>context_path)
310
+ i.enable=false if disabled
311
+ }
312
+ rescue Exception
313
+ msg = "Loading #{groups} ->#{items} (#{$!.class.to_s} : #{$!.to_s} at : #{$@.to_s})"
314
+ if Arcadia.ok_cancel(self, 'title' => '(Arcadia) Toolbar', 'msg'=>msg)=='cancel'
315
+ raise
316
+ exit
317
+ else
318
+ Tk.update
319
+ end
320
+ end
321
+ end
322
+ }
323
+
324
+ end
325
+
326
+
327
+ def do_exit
328
+ q1 = (Arcadia.yes_no(self,
329
+ 'msg'=>"Do you want exit?",
330
+ 'title' => '(Arcadia) Exit',
331
+ 'level' => 'question')=='yes')
332
+ if q1 && can_exit?
333
+ do_finalize
334
+ @root.destroy
335
+ end
336
+ end
337
+
338
+ def can_exit?
339
+ _can_exit = true
340
+ _event = Arcadia.process_event(ExitQueryEvent.new(self, 'can_exit'=>true))
341
+ _can_exit = _event.can_exit
342
+ @exts.each{|extension|
343
+ if ext_active?(extension) && !self[extension].can_exit_query
344
+ _can_exit = false
345
+ break
346
+ end
347
+ }
348
+ return _can_exit
349
+ end
350
+
351
+ def do_finalize
352
+ _event = Arcadia.process_event(FinalizeEvent.new(self))
353
+
354
+ @exts.each{|extension|
355
+ self[extension].finalize if ext_active?(extension)
356
+ }
357
+ self.write_persist(self['applicationParams'].persistent_file)
358
+ end
359
+
360
+ def Arcadia.new_msg(_sender, _msg, _channel=nil)
361
+ process_event(MsgEvent.new(_sender, 'msg'=>_msg))
362
+ end
363
+
364
+ def Arcadia.new_debug_msg(_sender, _msg, _channel=nil)
365
+ process_event(DebugMsgEvent.new(_sender, 'msg'=>_msg))
366
+ end
367
+
368
+ def Arcadia.new_error_msg(_sender, _msg, _channel=nil)
369
+ process_event(ErrorMsgEvent.new(_sender, 'msg'=>_msg))
370
+ end
371
+
372
+ def Arcadia.dialog(_sender, _type, _msg, _title=nil, _level=nil)
373
+ case _level
374
+ when 'info', nil
375
+ _event = process_event(DialogEvent.new(_sender, 'msg'=>_msg, 'title'=>_title, 'type'=>_type))
376
+ when 'question'
377
+ _event = process_event(QuestionDialogEvent.new(_sender, 'msg'=>_msg, 'title'=>_title, 'type'=>_type))
378
+ when 'warning'
379
+ _event = process_event(WarningDialogEvent.new(_sender, 'msg'=>_msg, 'title'=>_title, 'type'=>_type))
380
+ when 'error'
381
+ _event = process_event(ErrorDialogEvent.new(_sender, 'msg'=>_msg, 'title'=>_title, 'type'=>_type))
382
+ end
383
+ return _event.results[0].value if _event
384
+ end
385
+
386
+ def Arcadia.ok(_sender, _args=nil)
387
+ Arcadia.dialog(_sender, 'ok', _args['msg'], _args['title'], _args['level']) if _args
388
+ end
389
+
390
+ def Arcadia.ok_cancel(_sender, _args=nil)
391
+ Arcadia.dialog(_sender, 'ok_cancel', _args['msg'], _args['title'], _args['level']) if _args
392
+ end
393
+
394
+ def Arcadia.yes_no(_sender, _args=nil)
395
+ Arcadia.dialog(_sender, 'yes_no', _args['msg'], _args['title'], _args['level']) if _args
396
+ end
397
+
398
+ def Arcadia.yes_no_cancel(_sender, _args=nil)
399
+ Arcadia.dialog(_sender, 'yes_no_cancel', _args['msg'], _args['title'], _args['level']) if _args
400
+ end
401
+
402
+ def Arcadia.abort_retry_ignore(_sender, _args=nil)
403
+ Arcadia.dialog(_sender, 'abort_retry_ignore', _args['msg'], _args['title'], _args['level']) if _args
404
+ end
405
+
406
+ end
407
+
408
+ class ArcadiaUserControl
409
+ SUF='user_control'
410
+ class UserItem
411
+ attr_accessor :name
412
+ attr_accessor :context
413
+ attr_accessor :caption
414
+ attr_accessor :hint
415
+ attr_accessor :event_class
416
+ attr_accessor :event_args
417
+ attr_accessor :image_data
418
+ def initialize(_sender, _args)
419
+ @sender = _sender
420
+ if _args
421
+ _args.each do |key, value|
422
+ self.send(key+'=', value)
423
+ end
424
+ end
425
+ #@item_obj = ?
426
+ end
427
+
428
+ def method_missing(m, *args)
429
+ if @item_obj && m.respond_to?(m)
430
+ @item_obj.send(m, *args)
431
+ end
432
+ end
433
+
434
+
435
+ def enable=(_value)
436
+ end
437
+
438
+ def background
439
+ end
440
+
441
+ def foreground
442
+ end
443
+
444
+ end
445
+ # def initialize
446
+ # @items = Hash.new
447
+ # end
448
+ def items
449
+ @items = Hash.new if @items.nil?
450
+ @items
451
+ end
452
+
453
+ def new_item(_sender, _args)
454
+ item = self.class::UserItem.new(_sender, _args)
455
+ items[_args['name']]= item if _args['name']
456
+ end
457
+
458
+ end
459
+
460
+
461
+ class ArcadiaMainToolbar < ArcadiaUserControl
462
+ SUF='user_toolbar'
463
+ class UserItem < UserItem
464
+ attr_accessor :frame
465
+ def initialize(_sender, _args)
466
+ super(_sender, _args)
467
+ _image = TkPhotoImage.new('data' => @image_data) if @image_data
468
+ _command = proc{Arcadia.process_event(@event_class.new(_sender, @event_args))} if @event_class
469
+ _hint = @hint
470
+ _font = @font
471
+ _foreground = @foreground
472
+ _background = @background
473
+ _caption = @caption
474
+ @item_obj = Tk::BWidget::Button.new(_args['frame']){
475
+ image _image if _image
476
+ borderwidth 1
477
+ font _font if _font
478
+ background _background if _background
479
+ foreground _foreground if _foreground
480
+ command _command if _command
481
+ relief 'flat'
482
+ #relief 'groove'
483
+ width 20
484
+ height 20
485
+ helptext _hint if _hint
486
+ text _caption if _caption
487
+ pack('side' =>'left', :padx=>2, :pady=>0)
488
+ }
489
+ #Tk::BWidget::Separator.new(@frame, :orient=>'vertical').pack('side' =>'left', :padx=>2, :pady=>2, :fill=>'y',:anchor=> 'w')
490
+ end
491
+
492
+ def enabled=(_value)
493
+ if _value
494
+ @item_obj.state='enable'
495
+ else
496
+ @item_obj.state='disable'
497
+ end
498
+ end
499
+ end
500
+
501
+
502
+ def initialize(_arcadia, _frame)
503
+ @arcadia = _arcadia
504
+ @frame = _frame
505
+ # @context_frames = Hash.new
506
+ @last_context = nil
507
+ end
508
+
509
+ def new_item(_sender, _args= nil)
510
+ _context = _args['context']
511
+ # if _context
512
+ # if @context_frames[_context]
513
+ # else
514
+ # @context_frames[_context] = TkLabelFrame.new(@frame){
515
+ # text ""
516
+ # relief 'groove'
517
+ # pack('side' =>'left', :padx=>0, :pady=>0)
518
+ # }
519
+ # end
520
+ # _args['frame']=@context_frames[_context]
521
+ # else
522
+ # _args['frame']=@frame
523
+ # end
524
+ if @last_context && _context != @last_context
525
+ new_separator
526
+ end
527
+ @last_context = _context
528
+ _args['frame']=@frame
529
+ super(_sender, _args)
530
+ end
531
+
532
+ def new_separator
533
+ Tk::BWidget::Separator.new(@frame, :orient=>'vertical').pack('side' =>'left', :padx=>2, :pady=>2, :fill=>'y',:anchor=> 'w')
534
+ end
535
+
536
+ # def load_toolbar_buttons
537
+ # suf = 'toolbar_buttons'
538
+ # return if @arcadia['conf'][suf].nil?
539
+ # @buttons = Hash.new
540
+ # toolbar_buttons = @arcadia['conf'][suf].split(',')
541
+ # toolbar_buttons.each{|groups|
542
+ # if groups
543
+ # suf1 = suf+'.'+groups
544
+ # begin
545
+ # buttons = @arcadia['conf'][suf1].split(',')
546
+ # buttons.each{|button|
547
+ # suf2 = suf1+'.'+button
548
+ # name = @arcadia['conf'][suf2+'.name']
549
+ # text = @arcadia['conf'][suf2+'.text']
550
+ # image = @arcadia['conf'][suf2+'.image']
551
+ # font = @arcadia['conf'][suf2+'.font']
552
+ # background = @arcadia['conf'][suf2+'.background']
553
+ # foreground = @arcadia['conf'][suf2+'.foreground']
554
+ # hint = @arcadia['conf'][suf2+'.hint']
555
+ # action = @arcadia['conf'][suf2+'.action']
556
+ # actions = action.split('->') if action
557
+ # if actions && actions.length>1
558
+ # _command = proc{
559
+ # action_obj = $arcadia[actions[0]]
560
+ # 1.upto(actions.length-2) do |x|
561
+ # action_obj = action_obj.send(actions[x])
562
+ # end
563
+ # action_obj.send(actions[actions.length-1])
564
+ # }
565
+ # elsif action
566
+ # _command = proc{$arcadia[action].call}
567
+ # end
568
+ # @buttons[name] = Tk::BWidget::Button.new(@frame){
569
+ # image TkPhotoImage.new('data' => eval(image)) if image
570
+ # borderwidth 1
571
+ # font font if font
572
+ # background background if background
573
+ # foreground foreground if foreground
574
+ # command _command if action
575
+ # relief 'flat'
576
+ # helptext hint if hint
577
+ # text text if text
578
+ # pack('side' =>'left', :padx=>2, :pady=>0)
579
+ # }
580
+ # }
581
+ # rescue Exception
582
+ # msg = 'Loading '+groups+'" -> '+buttons.to_s+ '" (' + $!.class.to_s + ") : " + $!.to_s + " at : "+$@.to_s
583
+ # if Tk.messageBox('icon' => 'error', 'type' => 'okcancel',
584
+ # 'title' => '(Arcadia) Toolbar', 'parent' => @frame,
585
+ # 'message' => msg) == 'cancel'
586
+ # raise
587
+ # exit
588
+ # else
589
+ # Tk.update
590
+ # end
591
+ # end
592
+ # end
593
+ # Tk::BWidget::Separator.new(@frame, :orient=>'vertical').pack('side' =>'left', :padx=>2, :pady=>2, :fill=>'y',:anchor=> 'w')
594
+ # }
595
+ # end
596
+
597
+
598
+ end
599
+
600
+ class ArcadiaMainMenu < ArcadiaUserControl
601
+ SUF='user_menu'
602
+ class UserItem < UserItem
603
+ attr_accessor :menu
604
+ def initialize(_sender, _args)
605
+ super(_sender, _args)
606
+ _image = TkPhotoImage.new('data' => @image_data) if @image_data
607
+ _command = proc{Arcadia.process_event(@event_class.new(_sender, @event_args))} if @event_class
608
+ #_menu = @menu[@parent]
609
+ @item_obj = @menu.insert('end', :command,
610
+ 'image'=>_image,
611
+ 'label'=>@caption,
612
+ 'compound'=>'left',
613
+ 'command'=>_command )
614
+ @index = @menu.index('last')
615
+ end
616
+
617
+ def enabled=(_value)
618
+ if _value
619
+ @item_obj.entryconfigure(@index, 'state'=>'enable')
620
+ else
621
+ @item_obj.entryconfigure(@index,'state'=>'disable')
622
+ end
623
+ end
624
+ end
625
+
626
+ def initialize(menu)
627
+ # create main menu
628
+ @menu = menu
629
+ build
630
+ menu.foreground('black')
631
+ menu.activeforeground('#6679f1')
632
+ menu.relief('flat')
633
+ menu.borderwidth(0)
634
+ menu.font($arcadia['conf']['main.mainmenu.font'])
635
+ end
636
+
637
+ def get_menu_context(_menubar, _context)
638
+ menubuttons = _menubar[0..-1]
639
+ # cerchiamo il context
640
+ m_i = -1
641
+ menubuttons.each_with_index{|mb, i|
642
+ _t = mb[0].cget('text')
643
+ if _t==_context
644
+ m_i = i
645
+ break
646
+ end
647
+ }
648
+ if m_i > -1
649
+ _menubar[m_i][1]
650
+ else
651
+ _menubar.add_menu([[_context],[]])[1].delete(0)
652
+ end
653
+ end
654
+
655
+ def get_sub_menu(menu_context, folder=nil)
656
+ if folder
657
+ s_i = -1
658
+ i_end = menu_context.index('end')
659
+ if i_end
660
+ 0.upto(i_end){|j|
661
+ l = menu_context.entrycget(j,'label')
662
+ if l == folder
663
+ s_i = j
664
+ break
665
+ end
666
+ }
667
+ end
668
+ end
669
+ if s_i > -1 && menu_context.menutype(s_i) == 'cascade'
670
+ sub = menu_context.entrycget(s_i, 'menu')
671
+ else
672
+ sub = TkMenu.new(
673
+ :parent=>@pop_up,
674
+ :tearoff=>0
675
+ )
676
+ menu_context.insert('end',
677
+ :cascade,
678
+ :label=>folder,
679
+ :menu=>sub,
680
+ :hidemargin => false
681
+ )
682
+ end
683
+ sub
684
+ end
685
+
686
+ def get_menu(_menubar, _context, context_path)
687
+ context_menu = get_menu_context(_menubar, _context)
688
+ folders = context_path.split('/')
689
+ sub = context_menu
690
+ folders.each{|folder|
691
+ sub = get_sub_menu(sub, folder)
692
+ }
693
+ sub
694
+ end
695
+
696
+
697
+ def new_item(_sender, _args= nil)
698
+ return if _args.nil?
699
+ _args['menu']=get_menu(@menu, _args['context'], _args['context_path'])
700
+ super(_sender, _args)
701
+ end
702
+
703
+
704
+ def build
705
+ menu_spec_file = [
706
+ ['File', 0],
707
+ ['Open', proc{Arcadia.process_event(OpenBufferEvent.new(self,'file'=>Tk.getOpenFile))}, 0],
708
+ ['New', $arcadia['main.action.new_file'], 0],
709
+ #['Save', proc{EditorContract.instance.save_file_raised(self)},0],
710
+ ['Save', proc{Arcadia.process_event(SaveBufferEvent.new(self))},0],
711
+ ['Save as ...', proc{Arcadia.process_event(SaveAsBufferEvent.new(self))},0],
712
+ '---',
713
+ ['Quit', $arcadia['action.on_exit'], 0]]
714
+ menu_spec_edit = [['Edit', 0],
715
+ ['Cut', $arcadia['main.action.edit_cut'], 2],
716
+ ['Copy', $arcadia['main.action.edit_copy'], 0],
717
+ ['Paste', $arcadia['main.action.edit_paste'], 0]]
718
+ menu_spec_search = [['Search', 0],
719
+ ['Find ...', proc{Arcadia.process_event(SearchBufferEvent.new(self))}, 2],
720
+ ['Find in files...', proc{Arcadia.process_event(SearchInFilesEvent.new(self))}, 2],
721
+ ['Go to line ...', proc{Arcadia.process_event(GoToLineBufferEvent.new(self))}, 2]]
722
+ menu_spec_view = [['View', 0],['Show/Hide Toolbar', proc{$arcadia.show_hide_toolbar}, 2]]
723
+ menu_spec_tools = [['Tools', 0],
724
+ ['Keys-test', $arcadia['action.test.keys'], 2]
725
+ ]
726
+ menu_spec_help = [['Help', 0],
727
+ ['About', $arcadia['action.show_about'], 2],]
728
+ @menu.add_menu(menu_spec_file)
729
+ @menu.add_menu(menu_spec_edit)
730
+ @menu.add_menu(menu_spec_search)
731
+ @menu.add_menu(menu_spec_view)
732
+ @menu.add_menu(menu_spec_tools)
733
+ @menu.add_menu(menu_spec_help)
734
+ end
735
+
736
+ end
737
+
738
+ class ArcadiaAboutSplash < TkToplevel
739
+ attr :progress
740
+ def initialize(_txt=nil)
741
+ #_bgcolor = '#B83333'
742
+ _bgcolor = '#000000'
743
+ super()
744
+ relief 'groove'
745
+ #relief 'flat'
746
+ background _bgcolor
747
+ highlightbackground _bgcolor
748
+ highlightthickness 1
749
+ borderwidth 2
750
+ withdraw
751
+ overrideredirect(true)
752
+
753
+ @tkLabel3 = TkLabel.new(self){
754
+ image TkPhotoImage.new('format'=>'GIF','data' =>A_LOGO_GIF)
755
+ background _bgcolor
756
+ place('x'=> 20,'y' => 20)
757
+ }
758
+ @tkLabel1 = TkLabel.new(self){
759
+ text 'Arcadia'
760
+ background _bgcolor
761
+ foreground '#ffffff'
762
+ font Arcadia.instance['conf']['splash.title.font']
763
+ justify 'left'
764
+ place('width' => '190','x' => 110,'y' => 10,'height' => 25)
765
+ }
766
+ @tkLabelRuby = TkLabel.new(self){
767
+ image TkPhotoImage.new('data' =>RUBY_DOCUMENT_GIF)
768
+ background _bgcolor
769
+ place('x'=> 150,'y' => 40)
770
+ }
771
+ @tkLabel2 = TkLabel.new(self){
772
+ text 'Ruby ide'
773
+ background _bgcolor
774
+ foreground '#ffffff'
775
+ font Arcadia.instance['conf']['splash.subtitle.font']
776
+ justify 'left'
777
+ place('width' => '90','x' => 170,'y' => 40,'height' => 19)
778
+ }
779
+ @tkLabelVersion = TkLabel.new(self){
780
+ text 'version: '+$arcadia['applicationParams'].version
781
+ background _bgcolor
782
+ foreground '#ffffff'
783
+ font Arcadia.instance['conf']['splash.version.font']
784
+ justify 'left'
785
+ place('width' => '100','x' => 150,'y' => 65,'height' => 19)
786
+ }
787
+ @tkLabelStep = TkLabel.new(self){
788
+ text _txt
789
+ background _bgcolor
790
+ foreground 'yellow'
791
+ font Arcadia.instance['conf']['splash.banner.font']
792
+ justify 'left'
793
+ anchor 'w'
794
+ place('width'=>-5,'relwidth' => 1,'x' => 5,'y' => 175,'height' => 19)
795
+ }
796
+ @tkLabel21 = TkLabel.new(self){
797
+ text 'by Antonio Galeone - 2007'
798
+ background _bgcolor
799
+ foreground '#ffffff'
800
+ font Arcadia.instance['conf']['splash.credits.font']
801
+ justify 'left'
802
+ place('width' => '190','x' => 130,'y' => 146,'height' => 19)
803
+ }
804
+ @progress = TkVariable.new
805
+ reset
806
+ _width = 340
807
+ _height = 210
808
+ #_width = 0;_height = 0
809
+ _x = TkWinfo.screenwidth(self)/2 - _width / 2
810
+ _y = TkWinfo.screenheight(self)/2 - _height / 2
811
+ geometry = _width.to_s+'x'+_height.to_s+'+'+_x.to_s+'+'+_y.to_s
812
+ Tk.tk_call('wm', 'geometry', self, geometry )
813
+ bind("Double-Button-1", proc{self.destroy})
814
+ end
815
+
816
+ def set_progress(_max=10)
817
+ @max = _max
818
+ Tk::BWidget::ProgressBar.new(self, :width=>150, :height=>10,
819
+ :background=>'black',
820
+ :foreground=>'yellow',
821
+ :variable=>@progress,
822
+ :borderwidth=>0,
823
+ :relief=>'flat',
824
+ :maximum=>_max).place('width' => '150','x' => 145,'y' => 95,'height' => 15)
825
+ end
826
+
827
+ def reset
828
+ @progress.value = -1
829
+ end
830
+
831
+ def next_step(_txt = nil)
832
+ @progress.numeric += 1
833
+ labelStep(_txt) if _txt
834
+ end
835
+
836
+ def labelStep(_txt)
837
+ @tkLabelStep.text = _txt
838
+ Tk.update
839
+ end
840
+
841
+ def last_step(_txt = nil)
842
+ @progress.numeric = @max
843
+ labelStep(_txt) if _txt
844
+ end
845
+
846
+ end
847
+
848
+ class ArcadiaDialogManager
849
+ def initialize(_arcadia)
850
+ @arcadia = _arcadia
851
+ Arcadia.add_listener(self, DialogEvent)
852
+ end
853
+ def on_dialog(_event)
854
+ type = _event.type
855
+ if !DialogEvent::TYPE_PATTERNS.include?(_event.type)
856
+ type = 'ok'
857
+ end
858
+ case _event
859
+ when QuestionDialogEvent
860
+ icon = 'question'
861
+ when InfoDialogEvent
862
+ icon = 'info'
863
+ when WarningDialogEvent
864
+ icon = 'warning'
865
+ when ErrorDialogEvent
866
+ icon = 'error'
867
+ else
868
+ icon = 'info'
869
+ end
870
+
871
+ tktype = type.gsub('_','').downcase
872
+
873
+ res = Tk.messageBox(
874
+ 'icon' => icon,
875
+ 'type' => tktype,
876
+ 'title' => _event.title,
877
+ 'message' => _event.msg)
878
+ _event.add_result(self, 'value'=>res)
879
+ end
880
+ end
881
+
882
+
883
+ class ArcadiaLayout
884
+ include Observable
885
+ ArcadiaPanelInfo = Struct.new( "ArcadiaPanelInfo",
886
+ :name,
887
+ :title,
888
+ :frame
889
+ )
890
+
891
+ def initialize(_arcadia, _frame, _autotab=true)
892
+ @arcadia = _arcadia
893
+ @frames = Array.new
894
+ @frames[0] = Array.new
895
+ @frames[0][0] = _frame
896
+ @domains = Array.new
897
+ @domains[0] = Array.new
898
+ @domains[0][0] = '_domain_root_'
899
+ @panels = Hash.new
900
+ @panels['_domain_root_']= Hash.new
901
+ @panels['_domain_root_']['root']= _frame
902
+ @panels['_domain_root_']['sons'] = Hash.new
903
+ @autotab = _autotab
904
+ @headed = false
905
+ #ArcadiaContractListener.new(self, MainContract, :do_main_event)
906
+ end
907
+
908
+ def root
909
+ @panels['_domain_root_']['root']
910
+ end
911
+
912
+ def raise_panel(_domain, _extension)
913
+ p = @panels[_domain]
914
+ if p && p['notebook'] != nil
915
+ p['notebook'].raise(_extension)
916
+ end
917
+ end
918
+
919
+ def _prepare_rows(_row,_col, _height, _perc=false, _top_name=nil, _bottom_name=nil)
920
+ if (@frames[_row][_col] != nil)
921
+ _h = AGTkOSplittedFrames.new(@frames[_row][_col],_height, _perc)
922
+ if @frames[_row + 1] == nil
923
+ @frames[_row + 1] = Array.new
924
+ @domains[_row + 1] = Array.new
925
+ end
926
+ @frames[_row][_col] = _h.top_frame
927
+ # TODO: bisogna schiftare di uno tutti i frame a partire da _row + 1
928
+ # if @frames[_row + 1][_col] != nil
929
+ # if @frames[_row + 2] == nil
930
+ # @frames[_row + 2] = Array.new
931
+ # @domains[_row + 2] = Array.new
932
+ # end
933
+ # @frames[_row + 2][_col]=@frames[_row + 1][_col]
934
+ # end
935
+ @frames[_row + 1][_col] = _h.bottom_frame
936
+
937
+ _top_name = _row.to_s+'.'+_col.to_s if _top_name == nil
938
+ @panels[_top_name] = Hash.new
939
+ @panels[_top_name]['root'] = @frames[_row][_col]
940
+ @panels[_top_name]['sons'] = Hash.new
941
+ @domains[_row][_col] = _top_name
942
+
943
+ _bottom_name = (_row+1).to_s+'.'+_col.to_s if _bottom_name == nil
944
+ @panels[_bottom_name] = Hash.new
945
+ @panels[_bottom_name]['root'] = @frames[_row + 1][_col]
946
+ @panels[_bottom_name]['sons'] = Hash.new
947
+ @domains[_row + 1][_col] = _bottom_name
948
+ end
949
+ end
950
+ private :_prepare_rows
951
+
952
+ def add_rows(_row,_col, _height, _top_name=nil, _bottom_name=nil)
953
+ _prepare_rows(_row,_col, _height, false, _top_name, _bottom_name)
954
+ end
955
+
956
+ def add_rows_perc(_row,_col, _height, _top_name=nil, _bottom_name=nil)
957
+ _prepare_rows(_row,_col, _height, true, _top_name, _bottom_name)
958
+ end
959
+
960
+
961
+ def add_cols(_row,_col, _width, _left_name=nil, _right_name=nil)
962
+ if (@frames[_row][_col] != nil)
963
+ _w = AGTkVSplittedFrames.new(@frames[_row][_col],_width)
964
+ @frames[_row][_col] = _w.left_frame
965
+ @frames[_row][_col + 1] = _w.right_frame
966
+
967
+ _left_name = _row.to_s+'.'+_col.to_s if _left_name == nil
968
+ @panels[_left_name] = Hash.new
969
+ @panels[_left_name]['root'] = @frames[_row][_col]
970
+ @panels[_left_name]['sons'] = Hash.new
971
+ @domains[_row][_col] = _left_name
972
+
973
+ _right_name = _row.to_s+'.'+(_col+1).to_s if _right_name == nil
974
+ @panels[_right_name] = Hash.new
975
+ @panels[_right_name]['root'] = @frames[_row][_col + 1]
976
+ @panels[_right_name]['sons'] = Hash.new
977
+ @domains[_row][_col + 1] = _right_name
978
+ end
979
+ end
980
+
981
+ def add_headers
982
+ @domains.each{|row|
983
+ row.each{|domain|
984
+ @panels[domain]['root']= TkTitledFrame.new(@panels[domain]['root'], '...').place('x'=>0, 'y'=>0,'relheight'=>1, 'relwidth'=>1) if @panels[domain]
985
+ }
986
+ }
987
+ @headed = true
988
+ end
989
+
990
+ def headed?
991
+ @headed
992
+ end
993
+
994
+ def autotab?
995
+ @autotab
996
+ end
997
+
998
+ def registed?(_domain_name, _name)
999
+ @panels[_domain_name]['sons'][_name] != nil
1000
+ end
1001
+
1002
+ def register_panel(_domain_name, _name, _title)
1003
+ p = @panels[_domain_name]
1004
+ if p!=nil
1005
+ num = p['sons'].length
1006
+ if @headed
1007
+ p['root'].title(_title)
1008
+ root_frame = p['root'].frame
1009
+ else
1010
+ root_frame = p['root']
1011
+ end
1012
+ if (num == 0 && @autotab)
1013
+ api = ArcadiaPanelInfo.new(_name,_title,nil)
1014
+ api.frame = TkFrame.new(root_frame).place('x'=>0, 'y'=>0, 'relwidth'=>1, 'relheight'=>1)
1015
+ p['sons'][_name] = api
1016
+ return api.frame
1017
+ else
1018
+ if num == 1 && @autotab && p['notebook'] == nil
1019
+ p['notebook'] = Tk::BWidget::NoteBook.new(root_frame){
1020
+ tabbevelsize 0
1021
+ internalborderwidth 0
1022
+ pack('fill'=>'both', :padx=>0, :pady=>0, :expand => 'yes')
1023
+ }
1024
+ api = p['sons'].values[0]
1025
+ api_tab_frame = p['notebook'].insert('end',
1026
+ api.name,
1027
+ 'text'=>api.title,
1028
+ 'raisecmd'=>proc{
1029
+ p['root'].title(api.title)
1030
+ p['root'].top_text('')
1031
+ changed
1032
+ notify_observers('RAISE', api.name)
1033
+ }
1034
+ )
1035
+ api.frame.place('in'=>api_tab_frame, 'x'=>0, 'y'=>0, 'relwidth'=>1, 'relheight'=>1)
1036
+ api.frame.raise
1037
+ elsif (num==0 && !@autotab)
1038
+ p['notebook'] = Tk::BWidget::NoteBook.new(root_frame){
1039
+ tabbevelsize 0
1040
+ internalborderwidth 0
1041
+ pack('fill'=>'both', :padx=>0, :pady=>0, :expand => 'yes')
1042
+ }
1043
+ end
1044
+ _panel = p['notebook'].insert('end',_name ,
1045
+ 'text'=>_title,
1046
+ #'background'=>_tab_bg,
1047
+ 'raisecmd'=>proc{
1048
+ p['root'].title(_title)
1049
+ changed
1050
+ notify_observers('RAISE', _name)
1051
+ }
1052
+ )
1053
+ p['sons'][_name] = ArcadiaPanelInfo.new(_name,_title,_panel)
1054
+ p['notebook'].raise(_name)
1055
+ return _panel
1056
+ end
1057
+ end
1058
+ end
1059
+
1060
+ def unregister_panel(_domain_name, _name)
1061
+ @panels[_domain_name]['sons'].delete(_name)
1062
+ @panels[_domain_name]['notebook'].delete(_name)
1063
+ new_raise_key = @panels[_domain_name]['sons'].keys[@panels[_domain_name]['sons'].length-1]
1064
+ @panels[_domain_name]['notebook'].raise(new_raise_key)
1065
+ end
1066
+
1067
+ def raise_panel(_domain_name, _name)
1068
+ @panels[_domain_name]['notebook'].raise(_name) if @panels[_domain_name] && @panels[_domain_name]['notebook']
1069
+ end
1070
+
1071
+ def [](_row, _col)
1072
+ @frames[_row][_col]
1073
+ end
1074
+
1075
+ def frame(_domain_name, _name)
1076
+ @panels[_domain_name]['sons'][_name].frame
1077
+ end
1078
+
1079
+ def domain(_domain_name)
1080
+ @panels[_domain_name]
1081
+ end
1082
+
1083
+ def domain_root_frame(_domain_name)
1084
+ @panels[_domain_name]['root'].frame
1085
+ end
1086
+
1087
+ def new_float_frame(_args=nil)
1088
+ if _args.nil?
1089
+ _args = {'x'=>0, 'y'=>0, 'width'=>100, 'height'=>100}
1090
+ end
1091
+ _frame = TkFloatTitledFrame.new(root)
1092
+ _frame.on_close=proc{_frame.hide}
1093
+ _frame.place(_args)
1094
+ return _frame
1095
+ end
1096
+ end
1097
+ Arcadia.new.run