fxri 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/fxri +292 -0
- data/fxri.gemspec +24 -0
- data/lib/Empty_Text_Field_Handler.rb +63 -0
- data/lib/FoxDisplayer.rb +148 -0
- data/lib/FoxTextFormatter.rb +265 -0
- data/lib/Globals.rb +42 -0
- data/lib/Icon_Loader.rb +35 -0
- data/lib/Packet_Item.rb +179 -0
- data/lib/Packet_List.rb +192 -0
- data/lib/Recursive_Open_Struct.rb +233 -0
- data/lib/RiManager.rb +155 -0
- data/lib/Search_Engine.rb +165 -0
- data/lib/fxirb.rb +339 -0
- data/lib/icons/class.png +0 -0
- data/lib/icons/method.png +0 -0
- data/lib/icons/module.png +0 -0
- metadata +65 -0
data/fxri
ADDED
@@ -0,0 +1,292 @@
|
|
1
|
+
#!/bin/env ruby
|
2
|
+
|
3
|
+
# Load FXRuby: try gem, then Fox 1.2, then Fox 1.0
|
4
|
+
begin
|
5
|
+
# try fxruby gem
|
6
|
+
require 'rubygems'
|
7
|
+
require_gem 'fxruby', '>= 1.1.0'
|
8
|
+
require 'fox12'
|
9
|
+
require 'fox12/colors'
|
10
|
+
FOXVERSION="1.2"
|
11
|
+
include Fox
|
12
|
+
rescue LoadError
|
13
|
+
# no gem? try fox12 direct.
|
14
|
+
begin
|
15
|
+
require "fox12"
|
16
|
+
require "fox12/colors"
|
17
|
+
FOXVERSION="1.2"
|
18
|
+
include Fox
|
19
|
+
rescue LoadError
|
20
|
+
# no gem, no fox12? try fox 1.0
|
21
|
+
require "fox"
|
22
|
+
require "fox/colors"
|
23
|
+
# grep for FOXVERSION to find all code that depends on this
|
24
|
+
FOXVERSION="1.0"
|
25
|
+
include Fox
|
26
|
+
FXMenuBar = FXMenubar
|
27
|
+
FXToolTip = FXTooltip
|
28
|
+
FXStatusBar = FXStatusbar
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
require 'thread'
|
33
|
+
|
34
|
+
require 'lib/RiManager'
|
35
|
+
require 'lib/Recursive_Open_Struct'
|
36
|
+
require 'lib/Globals'
|
37
|
+
require 'lib/Packet_List'
|
38
|
+
require 'lib/Packet_Item'
|
39
|
+
require 'lib/Empty_Text_Field_Handler'
|
40
|
+
require 'lib/Icon_Loader'
|
41
|
+
require 'lib/Search_Engine'
|
42
|
+
require 'lib/FoxDisplayer'
|
43
|
+
require 'lib/FoxTextFormatter'
|
44
|
+
require 'lib/fxirb'
|
45
|
+
|
46
|
+
# Responsible for application initialization
|
47
|
+
class Main_Window < FXMainWindow
|
48
|
+
|
49
|
+
# Initializes the XDCC-application.
|
50
|
+
def initialize(app)
|
51
|
+
super(app, $cfg.app.name, nil, nil, DECOR_ALL, 0, 0, $cfg.app.width, $cfg.app.height)
|
52
|
+
set_default_font
|
53
|
+
# load icons
|
54
|
+
icon_loader = Icon_Loader.new(FXApp::instance)
|
55
|
+
icon_loader.cfg_to_icons($cfg.icons)
|
56
|
+
|
57
|
+
@gui = Recursive_Open_Struct.new
|
58
|
+
@gui.main = self
|
59
|
+
@data = Recursive_Open_Struct.new
|
60
|
+
@data.gui_mutex = Mutex.new
|
61
|
+
|
62
|
+
build(self)
|
63
|
+
FXToolTip.new(FXApp::instance, TOOLTIP_NORMAL)
|
64
|
+
|
65
|
+
@gui.close
|
66
|
+
create_data
|
67
|
+
|
68
|
+
@data.close
|
69
|
+
|
70
|
+
@search_engine = Search_Engine.new(@gui, @data)
|
71
|
+
|
72
|
+
# show init message
|
73
|
+
@data.displayer.display_information($cfg.text.help)
|
74
|
+
end
|
75
|
+
|
76
|
+
# Automatically called when the Fox application is created
|
77
|
+
def create
|
78
|
+
super
|
79
|
+
show(PLACEMENT_SCREEN)
|
80
|
+
# load items
|
81
|
+
load_items
|
82
|
+
@search_engine.update_search_status_text
|
83
|
+
end
|
84
|
+
|
85
|
+
def create_data
|
86
|
+
@data.displayer = FoxDisplayer.new(@gui.text)
|
87
|
+
@data.ri_manager = RiManager.new(@data.displayer)
|
88
|
+
@data.items = Array.new
|
89
|
+
@desc = nil
|
90
|
+
end
|
91
|
+
|
92
|
+
|
93
|
+
# Set the default font to the first font of $cfg.app.font.name that is available on this system.
|
94
|
+
def set_default_font
|
95
|
+
@font = load_font($cfg.app.font.name)
|
96
|
+
FXApp::instance.normalFont = @font if @font
|
97
|
+
end
|
98
|
+
|
99
|
+
# Returns the first font of the given array of font names that can be loaded, or nil.
|
100
|
+
def load_font(font_array)
|
101
|
+
# load default font
|
102
|
+
font = nil
|
103
|
+
font_array.detect do |name|
|
104
|
+
next if FXFont.listFonts(name).empty?
|
105
|
+
font = FXFont.new(FXApp::instance, name, $cfg.app.font.size)
|
106
|
+
end
|
107
|
+
font
|
108
|
+
end
|
109
|
+
|
110
|
+
# build gui
|
111
|
+
def build(parent)
|
112
|
+
FXSplitter.new(parent, SPLITTER_TRACKING|LAYOUT_FILL_X|LAYOUT_FILL_Y) do |base|
|
113
|
+
FXVerticalFrame.new(base, LAYOUT_FILL_X|LAYOUT_FILL_Y, 0,0,$cfg.packet_list_width,0, DEFAULT_SPACING, 0) do |search_frame|
|
114
|
+
|
115
|
+
@gui.search_field = FXTextField.new(search_frame, 1, nil, 0, TEXTFIELD_NORMAL|LAYOUT_FILL_X|FRAME_SUNKEN)
|
116
|
+
Empty_Text_Field_Handler.new(@gui.search_field, $cfg.text.search_field)
|
117
|
+
@gui.search_field.connect(SEL_CHANGED) do |*args|
|
118
|
+
on_search
|
119
|
+
end
|
120
|
+
|
121
|
+
|
122
|
+
FXVerticalFrame.new(search_frame, FRAME_SUNKEN|LAYOUT_FILL_X|LAYOUT_FILL_Y, 0,0,0,0, 0,0,0,0,0,0) do |list_frame|
|
123
|
+
@gui.packet_list = Packet_List.new(@data, list_frame, nil, 0, HSCROLLER_NEVER|VSCROLLER_ALWAYS|TREELIST_BROWSESELECT|LAYOUT_FILL_X|LAYOUT_FILL_Y) do |packet_list|
|
124
|
+
packet_list.add_header($cfg.text.method_name, $cfg.packet_list_width) { |x| make_sortable(x) }
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
@gui.search_label = FXLabel.new(search_frame, "", nil, LAYOUT_FILL_X|LABEL_NORMAL|JUSTIFY_RIGHT, 0,0,0,0, 0,0,0,0)
|
129
|
+
|
130
|
+
@gui.packet_list.connect(SEL_SELECTED) do |sender, sel, data|
|
131
|
+
item = sender.getItem(data).packet_item
|
132
|
+
show_info(item.data)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
|
137
|
+
FXSplitter.new(base, SPLITTER_TRACKING|LAYOUT_FILL_X|LAYOUT_FILL_Y|SPLITTER_VERTICAL) do |split|
|
138
|
+
FXHorizontalFrame.new(split, FRAME_SUNKEN|LAYOUT_FILL_X|LAYOUT_FILL_Y, 0,0,0,0, 0,0,0,0,0,0) do |right|
|
139
|
+
@gui.text = FXText.new(right, nil, 0, TEXT_READONLY|TEXT_WORDWRAP|LAYOUT_FILL_X|LAYOUT_FILL_Y)
|
140
|
+
end
|
141
|
+
|
142
|
+
FXHorizontalFrame.new(split, FRAME_SUNKEN|LAYOUT_FILL_X|LAYOUT_FILL_Y, 0,0,0,0, 0,0,0,0,0,0) do |irb_frame|
|
143
|
+
@irb_frame = irb_frame
|
144
|
+
@gui.irb = FXIrb.init(irb_frame, nil, 0, LAYOUT_FILL_X|LAYOUT_FILL_Y|TEXT_WORDWRAP|TEXT_SHOWACTIVE)
|
145
|
+
@gui.irb.setFont(@font) if @font
|
146
|
+
end
|
147
|
+
split.setSplit(0, $cfg.irb_height)
|
148
|
+
end
|
149
|
+
font = load_font($cfg.ri_font)
|
150
|
+
@gui.text.font = font if font
|
151
|
+
font.create
|
152
|
+
@gui.text_width = font.fontWidth
|
153
|
+
|
154
|
+
@gui.text.connect(SEL_CONFIGURE) do
|
155
|
+
on_show if @desc
|
156
|
+
end
|
157
|
+
|
158
|
+
# construct hilite styles
|
159
|
+
@gui.text.styled = true
|
160
|
+
@gui.text.hiliteStyles = create_styles
|
161
|
+
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
def create_empty_style
|
166
|
+
hs = FXHiliteStyle.new
|
167
|
+
hs.activeBackColor = FXColor::White
|
168
|
+
hs.hiliteBackColor = FXColor::DarkBlue
|
169
|
+
hs.normalBackColor = FXColor::White
|
170
|
+
hs.normalForeColor = FXColor::Black
|
171
|
+
hs.selectBackColor = FXColor::DarkBlue
|
172
|
+
hs.selectForeColor = FXColor::White
|
173
|
+
hs.style = 0
|
174
|
+
hs
|
175
|
+
end
|
176
|
+
|
177
|
+
def create_styles
|
178
|
+
styles = Array.new
|
179
|
+
|
180
|
+
#normal
|
181
|
+
styles.push create_empty_style
|
182
|
+
|
183
|
+
# bold
|
184
|
+
hs = create_empty_style
|
185
|
+
hs.style = FXText::STYLE_BOLD
|
186
|
+
styles.push hs
|
187
|
+
|
188
|
+
# H1
|
189
|
+
hs = create_empty_style
|
190
|
+
hs.style = FXText::STYLE_UNDERLINE|FXText::STYLE_BOLD
|
191
|
+
hs.normalForeColor = FXColor::ForestGreen
|
192
|
+
styles.push hs
|
193
|
+
|
194
|
+
# H2
|
195
|
+
hs = create_empty_style
|
196
|
+
hs.style = FXText::STYLE_UNDERLINE
|
197
|
+
hs.normalForeColor = FXColor::ForestGreen
|
198
|
+
styles.push hs
|
199
|
+
|
200
|
+
# H3
|
201
|
+
hs = create_empty_style
|
202
|
+
hs.normalForeColor = FXColor::ForestGreen
|
203
|
+
styles.push hs
|
204
|
+
|
205
|
+
# teletype
|
206
|
+
hs = create_empty_style
|
207
|
+
hs.normalForeColor = FXColor::DarkCyan
|
208
|
+
styles.push hs
|
209
|
+
|
210
|
+
# code
|
211
|
+
hs = create_empty_style
|
212
|
+
hs.activeBackColor = FXColor::LightGrey
|
213
|
+
hs.normalForeColor = FXColor::DarkGreen
|
214
|
+
hs.style = FXText::STYLE_UNDERLINE|FXText::STYLE_BOLD
|
215
|
+
styles.push hs
|
216
|
+
|
217
|
+
# emphasis
|
218
|
+
hs = create_empty_style
|
219
|
+
hs.normalForeColor = FXColor::DarkCyan
|
220
|
+
styles.push hs
|
221
|
+
|
222
|
+
# class
|
223
|
+
hs = create_empty_style
|
224
|
+
hs.style = FXText::STYLE_BOLD
|
225
|
+
hs.normalForeColor = FXColor::Blue
|
226
|
+
styles.push hs
|
227
|
+
|
228
|
+
styles
|
229
|
+
end
|
230
|
+
|
231
|
+
|
232
|
+
# loads all ri items
|
233
|
+
def load_items
|
234
|
+
@data.ri_manager.all_names.each do |name|
|
235
|
+
icon = case name.type
|
236
|
+
when NameDescriptor::CLASS
|
237
|
+
$cfg.icons.klass
|
238
|
+
when NameDescriptor::INSTANCE_METHOD
|
239
|
+
$cfg.icons.instance_method
|
240
|
+
when NameDescriptor::CLASS_METHOD
|
241
|
+
$cfg.icons.class_method
|
242
|
+
end
|
243
|
+
item = Packet_Item.new(@gui.packet_list, icon, name.to_s)
|
244
|
+
item.data = name
|
245
|
+
@data.items.push item
|
246
|
+
end
|
247
|
+
# quick hack to sort in right order :-)
|
248
|
+
@gui.packet_list.on_cmd_header(0)
|
249
|
+
@gui.packet_list.on_cmd_header(0)
|
250
|
+
@gui.packet_list.update_header_width
|
251
|
+
recalc
|
252
|
+
end
|
253
|
+
|
254
|
+
def on_search
|
255
|
+
@search_engine.on_search
|
256
|
+
end
|
257
|
+
|
258
|
+
def on_show
|
259
|
+
begin
|
260
|
+
w = @gui.text.width / @gui.text_width - 3
|
261
|
+
w = [w, $cfg.minimum_letters_per_line].max
|
262
|
+
@data.ri_manager.show(@desc, w)
|
263
|
+
rescue RiError => e
|
264
|
+
#puts desc
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
268
|
+
def show_info(desc)
|
269
|
+
@desc = desc
|
270
|
+
on_show
|
271
|
+
end
|
272
|
+
|
273
|
+
|
274
|
+
# x beeing the name of the ri doc, like "Set#delete"
|
275
|
+
# This creates a sortable representation. First class, then class methods, then instance.
|
276
|
+
def make_sortable(x)
|
277
|
+
[ x.downcase.gsub("::", " 1 ").gsub("#", " 2 "),
|
278
|
+
x.downcase,
|
279
|
+
x]
|
280
|
+
end
|
281
|
+
|
282
|
+
end
|
283
|
+
|
284
|
+
Thread.abort_on_exception= true
|
285
|
+
|
286
|
+
# move to directory of this file, so that icons can load correctly.
|
287
|
+
Dir.chdir(File.dirname(File.expand_path(__FILE__)))
|
288
|
+
|
289
|
+
$app = FXApp.new($cfg.app.name, $cfg.app.name)
|
290
|
+
$main_window = Main_Window.new($app)
|
291
|
+
$app.create
|
292
|
+
$app.run
|
data/fxri.gemspec
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
#!/bin/env ruby
|
2
|
+
require 'rubygems'
|
3
|
+
|
4
|
+
spec = Gem::Specification.new do |s|
|
5
|
+
s.name = "fxri"
|
6
|
+
s.add_dependency('fxruby', '>= 1.2.0')
|
7
|
+
s.version = "0.1.0"
|
8
|
+
s.date = "2005-02-20"
|
9
|
+
s.summary = "Graphical interface to the RI documentation, with search engine."
|
10
|
+
s.require_paths = ["lib"]
|
11
|
+
s.email = "martin.ankerl@gmail.com"
|
12
|
+
s.homepage = "http://fxri.rubyforge.org/"
|
13
|
+
s.rubyforge_project = "fxri"
|
14
|
+
s.description = "FxRi is an FXRuby interface to the RI documentation, with a search engine that allows for search-on-typing."
|
15
|
+
s.has_rdoc = false
|
16
|
+
s.files = Dir.glob("**/*")
|
17
|
+
s.bindir = "."
|
18
|
+
s.executables = ["fxri"]
|
19
|
+
end
|
20
|
+
|
21
|
+
if __FILE__ == $0
|
22
|
+
Gem.manage_gems
|
23
|
+
Gem::Builder.new(spec).build
|
24
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# Copyright (c) 2004, 2005 Martin Ankerl
|
2
|
+
# Shows a grey text in an FXTextField if the user did not enter any input. This is a nice way to
|
3
|
+
# give the user more information about what to enter into a text field, without the need of additional
|
4
|
+
# space in the GUI.
|
5
|
+
class Empty_Text_Field_Handler
|
6
|
+
|
7
|
+
# Create a new handler for the specified textfield, with the given text. From now on you have to use the
|
8
|
+
# created object to get and set text, not the textfield or this handler would come out of sync
|
9
|
+
def initialize(textField, myText)
|
10
|
+
@textField = textField
|
11
|
+
@myText = myText
|
12
|
+
@isEmpty = true
|
13
|
+
onTextFieldFocusOut
|
14
|
+
# create connections
|
15
|
+
@textField.connect(SEL_FOCUSIN, method(:onTextFieldFocusIn))
|
16
|
+
@textField.connect(SEL_FOCUSOUT, method(:onTextFieldFocusOut))
|
17
|
+
end
|
18
|
+
|
19
|
+
# Check if textfield is empty (no user input).
|
20
|
+
def empty?
|
21
|
+
@isEmpty
|
22
|
+
end
|
23
|
+
|
24
|
+
# Set new text for the textfield
|
25
|
+
def text=(newText)
|
26
|
+
onTextFieldFocusIn
|
27
|
+
@textField.text = newText.to_s
|
28
|
+
onTextFieldFocusOut
|
29
|
+
end
|
30
|
+
|
31
|
+
# Get the textfield's text, if the user has entered something.
|
32
|
+
def text
|
33
|
+
if empty? && !@inside
|
34
|
+
""
|
35
|
+
else
|
36
|
+
@textField.text
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# Set focus to the textfield.
|
41
|
+
def setFocus
|
42
|
+
@textField.setFocus
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def onTextFieldFocusIn(*args)
|
48
|
+
@inside = true
|
49
|
+
return if !@isEmpty
|
50
|
+
@textField.textColor = FXColor::Black
|
51
|
+
@textField.text = ""
|
52
|
+
end
|
53
|
+
|
54
|
+
def onTextFieldFocusOut(*args)
|
55
|
+
@inside = false
|
56
|
+
@textField.killSelection
|
57
|
+
@isEmpty = @textField.text == ""
|
58
|
+
return if !@isEmpty
|
59
|
+
@textField.textColor = FXColor::DarkGrey
|
60
|
+
@textField.text = @myText
|
61
|
+
@isEmpty = true
|
62
|
+
end
|
63
|
+
end
|
data/lib/FoxDisplayer.rb
ADDED
@@ -0,0 +1,148 @@
|
|
1
|
+
class FoxDisplayer
|
2
|
+
attr_accessor :reader
|
3
|
+
|
4
|
+
def initialize(text_field)
|
5
|
+
@text_field = text_field
|
6
|
+
@formatter = FoxTextFormatter.new(70, "") do |arg, style|
|
7
|
+
startpos = @str.size
|
8
|
+
@str << arg
|
9
|
+
@formats.push [startpos, arg.size, style]
|
10
|
+
end
|
11
|
+
@reader = nil
|
12
|
+
end
|
13
|
+
|
14
|
+
def width=(newWidth)
|
15
|
+
@formatter.width = newWidth
|
16
|
+
end
|
17
|
+
|
18
|
+
def no_info_available
|
19
|
+
@text_field.text="nothing here, move on!"
|
20
|
+
end
|
21
|
+
|
22
|
+
def init_text
|
23
|
+
@str = ""
|
24
|
+
@formats = Array.new
|
25
|
+
end
|
26
|
+
|
27
|
+
# Sets a new text, and all styles
|
28
|
+
def set_text
|
29
|
+
@text_field.text = @str
|
30
|
+
@formats.each do |start, n, style|
|
31
|
+
case style
|
32
|
+
when FoxTextFormatter::STYLE_BOLD
|
33
|
+
@text_field.changeStyle(start, n, 2)
|
34
|
+
when FoxTextFormatter::STYLE_H1
|
35
|
+
@text_field.changeStyle(start, n, 3)
|
36
|
+
when FoxTextFormatter::STYLE_H2
|
37
|
+
@text_field.changeStyle(start, n, 4)
|
38
|
+
when FoxTextFormatter::STYLE_H3
|
39
|
+
@text_field.changeStyle(start, n, 5)
|
40
|
+
when FoxTextFormatter::STYLE_TELETYPE
|
41
|
+
@text_field.changeStyle(start, n, 6)
|
42
|
+
when FoxTextFormatter::STYLE_CODE
|
43
|
+
@text_field.changeStyle(start, n, 7)
|
44
|
+
when FoxTextFormatter::STYLE_EMPHASIS
|
45
|
+
@text_field.changeStyle(start, n, 8)
|
46
|
+
when FoxTextFormatter::STYLE_CLASS
|
47
|
+
@text_field.changeStyle(start, n, 9)
|
48
|
+
else
|
49
|
+
@text_field.changeStyle(start, n, 1)
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# Display method information
|
56
|
+
def display_method_info(method)
|
57
|
+
init_text
|
58
|
+
@formatter.draw_line(method.full_name)
|
59
|
+
@formatter.display_params(method)
|
60
|
+
@formatter.draw_line
|
61
|
+
display_flow(method.comment)
|
62
|
+
|
63
|
+
if method.aliases && !method.aliases.empty?
|
64
|
+
@formatter.blankline
|
65
|
+
aka = "(also known as "
|
66
|
+
aka << method.aliases.map {|a| a.name }.join(", ")
|
67
|
+
aka << ")"
|
68
|
+
@formatter.wrap(aka)
|
69
|
+
end
|
70
|
+
set_text
|
71
|
+
end
|
72
|
+
|
73
|
+
def display_information(message)
|
74
|
+
init_text
|
75
|
+
display_flow(message)
|
76
|
+
set_text
|
77
|
+
end
|
78
|
+
|
79
|
+
def display_class_info(klass)
|
80
|
+
init_text
|
81
|
+
superclass = klass.superclass_string
|
82
|
+
if superclass
|
83
|
+
superclass = " < " + superclass
|
84
|
+
else
|
85
|
+
superclass = ""
|
86
|
+
end
|
87
|
+
@formatter.draw_line(klass.display_name + ": " + klass.full_name + superclass)
|
88
|
+
display_flow(klass.comment)
|
89
|
+
@formatter.draw_line
|
90
|
+
|
91
|
+
unless klass.includes.empty?
|
92
|
+
@formatter.blankline
|
93
|
+
@formatter.display_heading("Includes:", 2, "")
|
94
|
+
incs = []
|
95
|
+
klass.includes.each do |inc|
|
96
|
+
inc_desc = @reader.find_class_by_name(inc.name)
|
97
|
+
if inc_desc
|
98
|
+
str = inc.name + "("
|
99
|
+
str << inc_desc.instance_methods.map{|m| m.name}.join(", ")
|
100
|
+
str << ")"
|
101
|
+
incs << str
|
102
|
+
else
|
103
|
+
incs << inc.name
|
104
|
+
end
|
105
|
+
end
|
106
|
+
@formatter.wrap(incs.sort.join(', '))
|
107
|
+
end
|
108
|
+
|
109
|
+
unless klass.constants.empty?
|
110
|
+
@formatter.blankline
|
111
|
+
@formatter.display_heading("Constants:", 2, "")
|
112
|
+
len = 0
|
113
|
+
klass.constants.each { |c| len = c.name.length if c.name.length > len }
|
114
|
+
len += 2
|
115
|
+
klass.constants.each do |c|
|
116
|
+
@formatter.wrap(c.value, @formatter.indent+((c.name+":").ljust(len)))
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
unless klass.class_methods.empty?
|
121
|
+
@formatter.blankline
|
122
|
+
@formatter.display_heading("Class methods:", 2, "")
|
123
|
+
@formatter.wrap(klass.class_methods.map{|m| m.name}.sort.join(', '))
|
124
|
+
end
|
125
|
+
|
126
|
+
unless klass.instance_methods.empty?
|
127
|
+
@formatter.blankline
|
128
|
+
@formatter.display_heading("Instance methods:", 2, "")
|
129
|
+
@formatter.wrap(klass.instance_methods.map{|m| m.name}.sort.join(', '))
|
130
|
+
end
|
131
|
+
|
132
|
+
unless klass.attributes.empty?
|
133
|
+
@formatter.blankline
|
134
|
+
@formatter.wrap("Attributes:", "")
|
135
|
+
@formatter.wrap(klass.attributes.map{|a| a.name}.sort.join(', '))
|
136
|
+
end
|
137
|
+
|
138
|
+
set_text
|
139
|
+
end
|
140
|
+
|
141
|
+
def display_flow(flow)
|
142
|
+
if !flow || flow.empty?
|
143
|
+
@formatter.wrap("(no description...)\n")
|
144
|
+
else
|
145
|
+
@formatter.display_flow(flow)
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|