metaruby 1.0.0.rc2 → 1.0.0.rc3
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.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.travis.yml +4 -0
- data/README.md +4 -4
- data/lib/metaruby.rb +8 -1
- data/lib/metaruby/class.rb +13 -9
- data/lib/metaruby/dsls.rb +6 -0
- data/lib/metaruby/gui.rb +16 -0
- data/lib/metaruby/gui/exception_rendering.rb +281 -0
- data/lib/metaruby/gui/exception_view.rb +32 -111
- data/lib/metaruby/gui/html.rb +7 -0
- data/lib/metaruby/gui/html/button.rb +54 -12
- data/lib/metaruby/gui/html/collection.rb +33 -9
- data/lib/metaruby/gui/html/exception_view.css +4 -6
- data/lib/metaruby/gui/html/list.rhtml +3 -3
- data/lib/metaruby/gui/html/page.rb +233 -53
- data/lib/metaruby/gui/html/page.rhtml +6 -5
- data/lib/metaruby/gui/model_browser.rb +15 -6
- data/lib/metaruby/gui/model_selector.rb +57 -11
- data/lib/metaruby/gui/rendering_manager.rb +36 -7
- data/lib/metaruby/gui/ruby_constants_item_model.rb +155 -42
- data/lib/metaruby/inherited_attribute.rb +59 -8
- data/lib/metaruby/module.rb +29 -12
- data/lib/metaruby/registration.rb +44 -12
- data/lib/metaruby/test.rb +6 -10
- data/lib/metaruby/version.rb +2 -1
- data/lib/yard-metaruby.rb +10 -3
- data/manifest.xml +1 -0
- data/metaruby.gemspec +1 -1
- metadata +5 -4
@@ -1,15 +1,16 @@
|
|
1
1
|
<% prefix = if ressource_dir[0, 1] == "/" then "file://"
|
2
2
|
end
|
3
3
|
%>
|
4
|
-
<
|
4
|
+
<head>
|
5
5
|
<link rel="stylesheet" href="<%= prefix %><%= File.join(ressource_dir, 'page.css') %>" type="text/css" />
|
6
6
|
<script type="text/javascript" src="<%= prefix %><%= File.join(ressource_dir, 'jquery.min.js') %>"></script>
|
7
7
|
<script type="text/javascript" src="<%= prefix %><%= File.join(ressource_dir, 'jquery.selectfilter.js') %>"></script>
|
8
|
-
|
9
|
-
|
10
|
-
<% end %>
|
8
|
+
<%= head.join("\n").gsub('${RESOURCE_DIR}', "#{prefix}#{ressource_dir}") %>
|
9
|
+
<% if page_name %>
|
11
10
|
<title><%= page_name %></title>
|
12
|
-
|
11
|
+
<% end %>
|
12
|
+
</head>
|
13
|
+
<%= scripts.join("\n").gsub('${RESOURCE_DIR}', "#{prefix}#{ressource_dir}") %>
|
13
14
|
<body>
|
14
15
|
<%= html_body(ressource_dir: ressource_dir) %>
|
15
16
|
</body>
|
@@ -54,9 +54,12 @@ module MetaRuby
|
|
54
54
|
# the model view
|
55
55
|
attr_reader :central_splitter
|
56
56
|
|
57
|
-
# A Page object
|
58
|
-
#
|
57
|
+
# A Page object tunes to create URIs for objects that are suitable
|
58
|
+
# for {#model_selector}
|
59
59
|
class Page < HTML::Page
|
60
|
+
# Overloaded from {HTML::Page} to resolve object paths (in the
|
61
|
+
# constant hierarchy, e.g. A::B::C) into the corresponding
|
62
|
+
# path expected by {#model_selector} (e.g. /A/B/C)
|
60
63
|
def uri_for(object)
|
61
64
|
if object.respond_to?(:name) && (obj_name = object.name) && (obj_name =~ /^[\w:]+$/)
|
62
65
|
path = obj_name.split("::")
|
@@ -66,7 +69,6 @@ module MetaRuby
|
|
66
69
|
end
|
67
70
|
end
|
68
71
|
|
69
|
-
|
70
72
|
def initialize(main = nil, exception_view: nil)
|
71
73
|
super(main)
|
72
74
|
|
@@ -95,6 +97,10 @@ module MetaRuby
|
|
95
97
|
update_exceptions
|
96
98
|
end
|
97
99
|
|
100
|
+
# Restore the state of this widget from settings previously saved
|
101
|
+
# with {#save_to_settings}
|
102
|
+
#
|
103
|
+
# @param [Qt::Settings] settings
|
98
104
|
def restore_from_settings(settings)
|
99
105
|
%w{central_splitter vertical_splitter}.each do |object_name|
|
100
106
|
sizes = settings.value(object_name)
|
@@ -107,6 +113,9 @@ module MetaRuby
|
|
107
113
|
end
|
108
114
|
end
|
109
115
|
|
116
|
+
# Save the current state of this widget in the given settings
|
117
|
+
#
|
118
|
+
# @param [Qt::Settings] settings
|
110
119
|
def save_to_settings(settings)
|
111
120
|
%w{central_splitter vertical_splitter}.each do |object_name|
|
112
121
|
sizes = send(object_name).sizes
|
@@ -115,7 +124,7 @@ module MetaRuby
|
|
115
124
|
end
|
116
125
|
end
|
117
126
|
|
118
|
-
# Update the model selector after {register_type} got called
|
127
|
+
# Update the model selector after {#register_type} got called
|
119
128
|
def update_model_selector
|
120
129
|
model_selector.update
|
121
130
|
end
|
@@ -126,7 +135,7 @@ module MetaRuby
|
|
126
135
|
# It registers the given type on the model browser so that it gets
|
127
136
|
# displayed there.
|
128
137
|
#
|
129
|
-
# You must call {update_model_selector} after this call for the
|
138
|
+
# You must call {#update_model_selector} after this call for the
|
130
139
|
# modification to have any effect (i.e. for the newly registered
|
131
140
|
# models to appear on the selector)
|
132
141
|
#
|
@@ -204,7 +213,7 @@ module MetaRuby
|
|
204
213
|
# Call to render the given model
|
205
214
|
#
|
206
215
|
# @param [Model] mod the model that should be rendered
|
207
|
-
# @
|
216
|
+
# @raise [ArgumentError] if there is no view available for the
|
208
217
|
# given model
|
209
218
|
def render_model(mod, options = Hash.new)
|
210
219
|
page.clear
|
@@ -1,20 +1,42 @@
|
|
1
1
|
module MetaRuby
|
2
2
|
module GUI
|
3
|
-
# A Qt widget
|
4
|
-
#
|
3
|
+
# A Qt widget based on {RubyConstantsItemModel} to browse a set of
|
4
|
+
# models, and display them when the user selects one
|
5
5
|
class ModelSelector < Qt::Widget
|
6
|
-
|
6
|
+
# A per-type matching of the type to the actio that allows to
|
7
|
+
# filter/unfilter on this type
|
8
|
+
#
|
9
|
+
# @return [Hash<Module,Qt::Action>]
|
7
10
|
attr_reader :type_filters
|
11
|
+
|
12
|
+
# The view that shows the object hierarchy
|
13
|
+
#
|
14
|
+
# @return [Qt::TreeView]
|
8
15
|
attr_reader :model_list
|
16
|
+
|
17
|
+
# Qt model filter
|
18
|
+
# @return [Qt::SortFilterProxyModel]
|
9
19
|
attr_reader :model_filter
|
20
|
+
|
21
|
+
# (see {RubyConstantsItemModel#type_info)
|
22
|
+
attr_reader :type_info
|
23
|
+
|
24
|
+
# The Qt item model that represents the object hierarchy
|
25
|
+
# @return [RubyConstantsItemModel]
|
26
|
+
attr_reader :browser_model
|
27
|
+
|
28
|
+
# @return [Qt::PushButton] a button allowing to filter models by
|
29
|
+
# type
|
30
|
+
attr_reader :btn_type_filter_menu
|
10
31
|
# @return [Qt::LineEdit] the line edit widget that allows to modify
|
11
32
|
# the tree view filter
|
12
33
|
attr_reader :filter_box
|
13
|
-
# @return [Qt::Completer] auto-completion for {filter_box}
|
34
|
+
# @return [Qt::Completer] auto-completion for {#filter_box}
|
14
35
|
attr_reader :filter_completer
|
15
|
-
attr_reader :type_info
|
16
|
-
attr_reader :browser_model
|
17
36
|
|
37
|
+
# Create a new widget with an optional parent
|
38
|
+
#
|
39
|
+
# @param [Qt::Widget,nil] parent
|
18
40
|
def initialize(parent = nil)
|
19
41
|
super
|
20
42
|
|
@@ -35,6 +57,14 @@ module MetaRuby
|
|
35
57
|
setTabOrder(filter_button, model_list)
|
36
58
|
end
|
37
59
|
|
60
|
+
# Register a new object type
|
61
|
+
#
|
62
|
+
# @param [Module] model_base a module or class whose all objects of
|
63
|
+
# this type have as superclass
|
64
|
+
# @param [String] name the string that should be used to represent
|
65
|
+
# objects of this type
|
66
|
+
# @param [Integer] priority if an object's ancestry matches multiple
|
67
|
+
# types, only the ones of the highest priority will be retained
|
38
68
|
def register_type(model_base, name, priority = 0)
|
39
69
|
type_info[model_base] = RubyConstantsItemModel::TypeInfo.new(name, priority)
|
40
70
|
action = Qt::Action.new(name, self)
|
@@ -47,11 +77,15 @@ module MetaRuby
|
|
47
77
|
end
|
48
78
|
end
|
49
79
|
|
80
|
+
# Update the view, reloading the underlying model
|
50
81
|
def update
|
51
82
|
update_model_filter
|
52
83
|
reload
|
53
84
|
end
|
54
85
|
|
86
|
+
# @api private
|
87
|
+
#
|
88
|
+
# Update {#model_filter} to match the current filter setup
|
55
89
|
def update_model_filter
|
56
90
|
type_rx = type_filters.map do |model_base, act|
|
57
91
|
if act.checked?
|
@@ -74,6 +108,10 @@ module MetaRuby
|
|
74
108
|
auto_open
|
75
109
|
end
|
76
110
|
|
111
|
+
# Auto-open in the current state
|
112
|
+
#
|
113
|
+
# @param [Integer] threshold the method opens items whose number of
|
114
|
+
# children is lower than this threshold
|
77
115
|
def auto_open(threshold = 5)
|
78
116
|
current_level = [Qt::ModelIndex.new]
|
79
117
|
while !current_level.empty?
|
@@ -97,6 +135,7 @@ module MetaRuby
|
|
97
135
|
end
|
98
136
|
end
|
99
137
|
|
138
|
+
# Tests if an object if a model
|
100
139
|
def model?(obj)
|
101
140
|
type_info.any? do |model_base, _|
|
102
141
|
obj.kind_of?(model_base) ||
|
@@ -113,6 +152,9 @@ module MetaRuby
|
|
113
152
|
end
|
114
153
|
end
|
115
154
|
|
155
|
+
# @api private
|
156
|
+
#
|
157
|
+
# Helper method for {#select_first_item}
|
116
158
|
def all_leaves(model, limit = nil, item = Qt::ModelIndex.new, result = [])
|
117
159
|
if !model.hasChildren(item)
|
118
160
|
result << item
|
@@ -131,12 +173,16 @@ module MetaRuby
|
|
131
173
|
return result
|
132
174
|
end
|
133
175
|
|
176
|
+
# Select the first displayed item
|
134
177
|
def select_first_item
|
135
178
|
if item = all_leaves(model_filter, 1).first
|
136
179
|
model_list.setCurrentIndex(item)
|
137
180
|
end
|
138
181
|
end
|
139
182
|
|
183
|
+
# @api private
|
184
|
+
#
|
185
|
+
# Create and setup {#model_list}
|
140
186
|
def setup_tree_view(layout)
|
141
187
|
@model_list = Qt::TreeView.new(self)
|
142
188
|
@model_filter = Qt::SortFilterProxyModel.new
|
@@ -169,6 +215,7 @@ module MetaRuby
|
|
169
215
|
end
|
170
216
|
signals 'model_selected(QVariant)'
|
171
217
|
|
218
|
+
# Reload the object model, keeping the current selection if possible
|
172
219
|
def reload
|
173
220
|
if current = current_selection
|
174
221
|
current_module = current.this
|
@@ -202,12 +249,11 @@ module MetaRuby
|
|
202
249
|
# control whether the filter should be reset if the index given as
|
203
250
|
# parameter is currently filtered out
|
204
251
|
#
|
205
|
-
# @param [Qt::ModelIndex] an index valid in {browser_model}
|
206
|
-
# @
|
252
|
+
# @param [Qt::ModelIndex] source_index an index valid in {#browser_model}
|
253
|
+
# @param [Boolean] reset_filter if true, the filter
|
207
254
|
# is reset if the requested index is currently filtered out
|
208
|
-
# @return [Qt::ModelIndex] an index filtered by {model_filter}
|
209
|
-
def map_index_from_source(source_index,
|
210
|
-
options = Kernel.validate_options options, :reset_filter => true
|
255
|
+
# @return [Qt::ModelIndex] an index filtered by {#model_filter}
|
256
|
+
def map_index_from_source(source_index, reset_filter: true)
|
211
257
|
index = model_filter.map_from_source(source_index)
|
212
258
|
if !index
|
213
259
|
return
|
@@ -1,5 +1,10 @@
|
|
1
1
|
module MetaRuby
|
2
2
|
module GUI
|
3
|
+
# Management of HTML rendering of objects of different types
|
4
|
+
#
|
5
|
+
# Objects of this class allow to register a set of renderers, dedicated
|
6
|
+
# to rendering objects of a certain type (defined as a superclass) and
|
7
|
+
# automatically switch between the rendering objects.
|
3
8
|
class RenderingManager < Qt::Object
|
4
9
|
# @return [#push] the page object on which we render
|
5
10
|
attr_reader :page
|
@@ -10,15 +15,19 @@ module MetaRuby
|
|
10
15
|
# matches will be used.
|
11
16
|
# Do not modify directly, use {#register_type} instead
|
12
17
|
attr_reader :available_renderers
|
13
|
-
# The
|
18
|
+
# The rendering object used last in {#render}
|
14
19
|
attr_reader :current_renderer
|
15
20
|
|
21
|
+
# Create a rendering manager that acts on a given page
|
16
22
|
def initialize(page = nil)
|
17
23
|
super()
|
18
24
|
@page = page
|
19
25
|
@available_renderers = Hash.new
|
20
26
|
end
|
21
27
|
|
28
|
+
# A list of exceptions that happened during rendering
|
29
|
+
#
|
30
|
+
# @return [Array<Exception>]
|
22
31
|
def registered_exceptions
|
23
32
|
if current_renderer.respond_to?(:registered_exceptions)
|
24
33
|
current_renderer.registered_exceptions
|
@@ -32,12 +41,15 @@ module MetaRuby
|
|
32
41
|
# It registers the given type on the model browser so that it gets
|
33
42
|
# displayed there.
|
34
43
|
#
|
35
|
-
# @param [Class] type
|
36
|
-
#
|
44
|
+
# @param [Class] type objects whose class or ancestry include 'type'
|
45
|
+
# will be rendered using the provided rendering class. If more tha
|
46
|
+
# none matches, the first one is used.
|
37
47
|
# @param [Class] rendering_class a class from which a relevant
|
38
48
|
# rendering object can be created. The generated instances must
|
39
49
|
# follow the rules described in the documentation of
|
40
50
|
# {ModelBrowser}
|
51
|
+
# @param [Hash] render_options a set of options that must be passed
|
52
|
+
# to the renderer's #render method
|
41
53
|
def register_type(type, rendering_class, render_options = Hash.new)
|
42
54
|
render = if rendering_class.kind_of?(Class)
|
43
55
|
rendering_class.new(page)
|
@@ -60,37 +72,54 @@ module MetaRuby
|
|
60
72
|
end
|
61
73
|
end
|
62
74
|
|
75
|
+
# @api private
|
76
|
+
#
|
77
|
+
# Find a rendering object for the given object
|
78
|
+
#
|
79
|
+
# @param [Object] mod the object we need to render
|
80
|
+
# @return [(Class,(#render,Hash)),nil] either the base class,
|
81
|
+
# rendering object and rendering options that should be used for
|
82
|
+
# the given object, or nil if there are no matching rendering
|
83
|
+
# objects
|
63
84
|
def find_renderer(mod)
|
64
85
|
available_renderers.find do |model, _|
|
65
86
|
mod.kind_of?(model) || (mod.kind_of?(Module) && model.kind_of?(Module) && mod <= model)
|
66
87
|
end
|
67
88
|
end
|
68
89
|
|
90
|
+
# Disable the current renderer
|
69
91
|
def disable
|
70
92
|
if current_renderer
|
71
93
|
current_renderer.disable
|
72
94
|
end
|
73
95
|
end
|
74
96
|
|
97
|
+
# Enable the current renderer
|
75
98
|
def enable
|
76
99
|
if current_renderer
|
77
100
|
current_renderer.enable
|
78
101
|
end
|
79
102
|
end
|
80
103
|
|
104
|
+
# Clear the current renderer
|
81
105
|
def clear
|
82
106
|
if current_renderer
|
83
107
|
current_renderer.clear
|
84
108
|
end
|
85
109
|
end
|
86
110
|
|
87
|
-
|
88
111
|
# Call to render the given model
|
89
112
|
#
|
90
|
-
#
|
91
|
-
#
|
113
|
+
# The renderer that has been used is made active (enabled) and
|
114
|
+
# stored in {#current_renderer}. The previous one is disabled and
|
115
|
+
# cleared.
|
116
|
+
#
|
117
|
+
# @param [Model] object the model that should be rendered
|
118
|
+
# @param [Hash] push_options options that should be passed to the
|
119
|
+
# object's renderer {#render} method
|
120
|
+
# @raise [ArgumentError] if there is no view available for the
|
92
121
|
# given model
|
93
|
-
def render(object, push_options
|
122
|
+
def render(object, **push_options)
|
94
123
|
_, (renderer, render_options) = find_renderer(object)
|
95
124
|
if renderer
|
96
125
|
if current_renderer
|
@@ -1,21 +1,69 @@
|
|
1
1
|
module MetaRuby
|
2
2
|
module GUI
|
3
|
-
# A Qt item model that
|
4
|
-
#
|
3
|
+
# A Qt item model that enumerates models stored in the Ruby constant
|
4
|
+
# hierarchy
|
5
|
+
#
|
6
|
+
# The model exposes all registered constants for which {#predicate}
|
7
|
+
# returns true in a hierarchy, allowing the user to interact with it.
|
8
|
+
#
|
9
|
+
# Discovery starts at Object
|
5
10
|
class RubyConstantsItemModel < Qt::AbstractItemModel
|
11
|
+
# Stored per-module information test
|
6
12
|
ModuleInfo = Struct.new :id, :name, :this, :parent, :children, :row, :types, :full_name, :keyword_string, :path
|
13
|
+
|
14
|
+
# Information about different model types
|
7
15
|
TypeInfo = Struct.new :name, :priority, :color
|
8
16
|
|
17
|
+
# Predicate that filters objects in addition to {#excludes}
|
18
|
+
#
|
19
|
+
# Only objects for which #call returns true and the constants that
|
20
|
+
# contain them are exposed by this model
|
21
|
+
#
|
22
|
+
# @return [#call]
|
9
23
|
attr_reader :predicate
|
24
|
+
|
25
|
+
# Explicitely excluded objects
|
26
|
+
#
|
27
|
+
# Set of objects that should be excluded from discovery, regardless
|
28
|
+
# of what {#predicate} would return from them.
|
29
|
+
#
|
30
|
+
# Note that such objects are not discovered at all, meaning that if
|
31
|
+
# they contain objects that should have been discovered, they won't
|
32
|
+
# be.
|
33
|
+
#
|
34
|
+
# @return [Set]
|
35
|
+
attr_reader :excludes
|
36
|
+
|
37
|
+
# A list of expected object types
|
38
|
+
#
|
39
|
+
# This is used to decide where a given object should be "attached"
|
40
|
+
# in the hierarchy. Matching types are stored in {ModuleInfo#types}.
|
41
|
+
#
|
42
|
+
# @return [{Class=>TypeInfo}]
|
43
|
+
attr_reader :type_info
|
44
|
+
|
45
|
+
# Mapping from module ID to a module object
|
46
|
+
#
|
47
|
+
# @return [{Integer=>ModuleInfo}]
|
10
48
|
attr_reader :id_to_module
|
49
|
+
|
50
|
+
# Set of objects that have been filtered out by {#predicate}
|
11
51
|
attr_reader :filtered_out_modules
|
12
|
-
|
52
|
+
|
53
|
+
# Name of the root item
|
54
|
+
#
|
55
|
+
# @return [String]
|
13
56
|
attr_accessor :title
|
57
|
+
|
58
|
+
# List of paths for each of the discovered objects
|
59
|
+
#
|
60
|
+
# @return [{Object=>String}]
|
14
61
|
attr_reader :object_paths
|
15
|
-
# @return [Set<Object>] a set of objects that should not be
|
16
|
-
# discovered
|
17
|
-
attr_reader :excludes
|
18
62
|
|
63
|
+
# Initialize this model for objects of the given type
|
64
|
+
#
|
65
|
+
# @param [Hash] type_info value for {#type_info}
|
66
|
+
# @param [#call] predicate the filter {#predicate}
|
19
67
|
def initialize(type_info = Hash.new, &predicate)
|
20
68
|
super()
|
21
69
|
@predicate = predicate || proc { true }
|
@@ -28,6 +76,7 @@ module MetaRuby
|
|
28
76
|
@object_paths = Hash.new
|
29
77
|
end
|
30
78
|
|
79
|
+
# Discovers or rediscovers the objects
|
31
80
|
def reload
|
32
81
|
begin_reset_model
|
33
82
|
@id_to_module = []
|
@@ -46,10 +95,19 @@ module MetaRuby
|
|
46
95
|
end_reset_model
|
47
96
|
end
|
48
97
|
|
98
|
+
# {ModuleInfo} for the root
|
49
99
|
def root_info
|
50
100
|
id_to_module.last
|
51
101
|
end
|
52
102
|
|
103
|
+
# @api private
|
104
|
+
#
|
105
|
+
# Generate the path information, i.e. per-object path string
|
106
|
+
#
|
107
|
+
# @param [Hash] paths the generated paths (matches {#object_paths})
|
108
|
+
# @param [ModuleInfo] info the object information for the object to
|
109
|
+
# be discovered
|
110
|
+
# @param [String] current the path of 'info'
|
53
111
|
def generate_paths(paths, info, current)
|
54
112
|
info.children.each do |child|
|
55
113
|
child_uri = current + '/' + child.name
|
@@ -58,6 +116,12 @@ module MetaRuby
|
|
58
116
|
end
|
59
117
|
end
|
60
118
|
|
119
|
+
# @api private
|
120
|
+
#
|
121
|
+
# Updates {ModuleInfo#types} so that it includes the type of its
|
122
|
+
# children
|
123
|
+
#
|
124
|
+
# @param [ModuleInfo] info the object info that should be updated
|
61
125
|
def update_module_type_info(info)
|
62
126
|
types = info.types.to_set
|
63
127
|
info.children.each do |child_info|
|
@@ -68,6 +132,13 @@ module MetaRuby
|
|
68
132
|
end.reverse
|
69
133
|
end
|
70
134
|
|
135
|
+
# @api private
|
136
|
+
#
|
137
|
+
# Discovers an object and its children
|
138
|
+
#
|
139
|
+
# @param [Object] mod an object that should be discovered
|
140
|
+
# @param [Array] stack the current stack (to avoid infinite recursions)
|
141
|
+
# @return [ModuleInfo]
|
71
142
|
def discover_module(mod, stack = Array.new)
|
72
143
|
return if excludes.include?(mod)
|
73
144
|
stack.push mod
|
@@ -143,13 +214,13 @@ module MetaRuby
|
|
143
214
|
ensure stack.pop
|
144
215
|
end
|
145
216
|
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
217
|
+
# @api private
|
218
|
+
#
|
219
|
+
# Lazily computes the full name of a discovered object. It updates
|
220
|
+
# {ModuleInfo#full_name}
|
221
|
+
#
|
222
|
+
# @param [ModuleInfo] info
|
223
|
+
# @return [String]
|
153
224
|
def compute_full_name(info)
|
154
225
|
if name = info.full_name
|
155
226
|
return name
|
@@ -164,6 +235,13 @@ module MetaRuby
|
|
164
235
|
end
|
165
236
|
end
|
166
237
|
|
238
|
+
# @api private
|
239
|
+
#
|
240
|
+
# Lazily compute the path of a discovered object. The result is
|
241
|
+
# stored in {ModuleInfo#path}
|
242
|
+
#
|
243
|
+
# @param [ModuleInfo] info
|
244
|
+
# @return [String]
|
167
245
|
def compute_path(info)
|
168
246
|
if path = info.path
|
169
247
|
return path
|
@@ -173,6 +251,57 @@ module MetaRuby
|
|
173
251
|
end
|
174
252
|
end
|
175
253
|
|
254
|
+
|
255
|
+
# Resolves a {ModuleInfo} from a Qt::ModelIndex
|
256
|
+
def info_from_index(index)
|
257
|
+
if !index.valid?
|
258
|
+
return id_to_module.last
|
259
|
+
else
|
260
|
+
id_to_module[index.internal_id >> 1]
|
261
|
+
end
|
262
|
+
end
|
263
|
+
|
264
|
+
# Return the Qt::ModelIndex that represents a given object
|
265
|
+
#
|
266
|
+
# @return [Qt::ModelIndex,nil] the index, or nil if the object is
|
267
|
+
# not included in this model
|
268
|
+
def find_index_by_model(model)
|
269
|
+
if info = id_to_module.find { |info| info.this == model }
|
270
|
+
return create_index(info.row, 0, info.id)
|
271
|
+
end
|
272
|
+
end
|
273
|
+
|
274
|
+
# Returns the Qt::ModelIndex that matches a given path
|
275
|
+
#
|
276
|
+
# @param [Array<String>] path path to the desired object
|
277
|
+
# @return [Qt::ModelIndex,nil] the index, or nil if the path does
|
278
|
+
# not resolve to an object included in this model
|
279
|
+
def find_index_by_path(*path)
|
280
|
+
current = id_to_module.last
|
281
|
+
if path.first == current.name
|
282
|
+
path.shift
|
283
|
+
end
|
284
|
+
|
285
|
+
path.each do |name|
|
286
|
+
current = id_to_module.find do |info|
|
287
|
+
info.name == name && info.parent == current
|
288
|
+
end
|
289
|
+
return if !current
|
290
|
+
end
|
291
|
+
create_index(current.row, 0, current.id)
|
292
|
+
end
|
293
|
+
|
294
|
+
# @api private
|
295
|
+
#
|
296
|
+
# Lazily compute a comma-separated string that can be used to search
|
297
|
+
# for the given node. The result is stored in
|
298
|
+
# {ModuleInfo#keyword_string}
|
299
|
+
#
|
300
|
+
# The returned string is of the form
|
301
|
+
# type0[,type1...]:name0[,name1...]
|
302
|
+
#
|
303
|
+
# @param [ModuleInfo] info
|
304
|
+
# @return [String]
|
176
305
|
def compute_keyword_string(info)
|
177
306
|
if keywords = info.keyword_string
|
178
307
|
return keywords
|
@@ -186,6 +315,15 @@ module MetaRuby
|
|
186
315
|
end
|
187
316
|
end
|
188
317
|
|
318
|
+
# Reimplemented for Qt model interface
|
319
|
+
def headerData(section, orientation, role)
|
320
|
+
if role == Qt::DisplayRole && section == 0
|
321
|
+
Qt::Variant.new(title)
|
322
|
+
else Qt::Variant.new
|
323
|
+
end
|
324
|
+
end
|
325
|
+
|
326
|
+
# Reimplemented for Qt model interface
|
189
327
|
def data(index, role)
|
190
328
|
if info = info_from_index(index)
|
191
329
|
if role == Qt::DisplayRole
|
@@ -199,6 +337,7 @@ module MetaRuby
|
|
199
337
|
return Qt::Variant.new
|
200
338
|
end
|
201
339
|
|
340
|
+
# Reimplemented for Qt model interface
|
202
341
|
def index(row, column, parent)
|
203
342
|
if info = info_from_index(parent)
|
204
343
|
if child_info = info.children[row]
|
@@ -208,6 +347,7 @@ module MetaRuby
|
|
208
347
|
Qt::ModelIndex.new
|
209
348
|
end
|
210
349
|
|
350
|
+
# Reimplemented for Qt model interface
|
211
351
|
def parent(child)
|
212
352
|
if info = info_from_index(child)
|
213
353
|
if info.parent && info.parent != root_info
|
@@ -217,6 +357,7 @@ module MetaRuby
|
|
217
357
|
Qt::ModelIndex.new
|
218
358
|
end
|
219
359
|
|
360
|
+
# Reimplemented for Qt model interface
|
220
361
|
def rowCount(parent)
|
221
362
|
if info = info_from_index(parent)
|
222
363
|
info.children.size
|
@@ -224,38 +365,10 @@ module MetaRuby
|
|
224
365
|
end
|
225
366
|
end
|
226
367
|
|
368
|
+
# Reimplemented for Qt model interface
|
227
369
|
def columnCount(parent)
|
228
370
|
return 1
|
229
371
|
end
|
230
|
-
|
231
|
-
def info_from_index(index)
|
232
|
-
if !index.valid?
|
233
|
-
return id_to_module.last
|
234
|
-
else
|
235
|
-
id_to_module[index.internal_id >> 1]
|
236
|
-
end
|
237
|
-
end
|
238
|
-
|
239
|
-
def find_index_by_model(model)
|
240
|
-
if info = id_to_module.find { |info| info.this == model }
|
241
|
-
return create_index(info.row, 0, info.id)
|
242
|
-
end
|
243
|
-
end
|
244
|
-
|
245
|
-
def find_index_by_path(*path)
|
246
|
-
current = id_to_module.last
|
247
|
-
if path.first == current.name
|
248
|
-
path.shift
|
249
|
-
end
|
250
|
-
|
251
|
-
path.each do |name|
|
252
|
-
current = id_to_module.find do |info|
|
253
|
-
info.name == name && info.parent == current
|
254
|
-
end
|
255
|
-
return if !current
|
256
|
-
end
|
257
|
-
create_index(current.row, 0, current.id)
|
258
|
-
end
|
259
372
|
end
|
260
373
|
end
|
261
374
|
end
|