Class: MetaRuby::GUI::ModelHierarchy

Inherits:
Qt::StandardItemModel
  • Object
show all
Defined in:
lib/metaruby/gui/model_hierarchy.rb

Defined Under Namespace

Classes: Metadata, Resolver, RootModel

Instance Method Summary collapse

Constructor Details

#initializeModelHierarchy

Returns a new instance of ModelHierarchy.



49
50
51
52
# File 'lib/metaruby/gui/model_hierarchy.rb', line 49

def initialize
    super()
    @root_models = Array.new
end

Instance Method Details

#add_root(root_model, priority, categories: [], resolver: Resolver.new(root_model)) ⇒ Object



71
72
73
# File 'lib/metaruby/gui/model_hierarchy.rb', line 71

def add_root(root_model, priority, categories: [], resolver: Resolver.new(root_model))
    @root_models << RootModel.new(root_model, priority, categories, resolver)
end

#compute_and_store_metadata(item) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Compute each item’s metadata and stores it in UserRole. The metadata is stored as “Category0|Category1;name/with/slashes/between/parts”. This is meant to be used in a seach/filter function.



127
128
129
130
131
132
133
134
135
136
# File 'lib/metaruby/gui/model_hierarchy.rb', line 127

def (item)
    current = @items_metadata[item]

    item.rowCount.times do |row|
        current.merge (item.child(row))
    end

    item.set_data(Qt::Variant.new(current.to_user_role), Qt::UserRole)
    current
end

#discover_model_hierarchy(root_model, categories, resolver, seen) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Register a model and its whole submodels hierarchy



208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
# File 'lib/metaruby/gui/model_hierarchy.rb', line 208

def discover_model_hierarchy(root_model, categories, resolver, seen)
    discovered = Array.new
    queue = [root_model]
    categories = categories.to_set

    while !queue.empty?
        m = queue.shift
        next if seen.include?(m)
        seen << m
        discovered << m

        register_model(m, categories, resolver)
        resolver.each_submodel(m) do |model, excluded|
            raise if model.kind_of?(String)
            if excluded
                seen << model
            else
                queue << model
            end
        end
    end
    discovered
end

#find_index_by_model(model) ⇒ Object

Returns the QModelIndex object that represents the given model



199
200
201
202
203
# File 'lib/metaruby/gui/model_hierarchy.rb', line 199

def find_index_by_model(model)
    if item = find_item_by_model(model)
        item.index
    end
end

#find_index_by_path(*path) ⇒ Qt::ModelIndex?

Returns the ModelIndex object that sits at the given path

Returns:

  • (Qt::ModelIndex, nil)


187
188
189
190
191
# File 'lib/metaruby/gui/model_hierarchy.rb', line 187

def find_index_by_path(*path)
    if item = find_item_by_path(*path)
        item.index
    end
end

#find_item_by_model(model) ⇒ Object

Returns the QStandardItem object that represents the given model



194
195
196
# File 'lib/metaruby/gui/model_hierarchy.rb', line 194

def find_item_by_model(model)
    @models_to_items[model]
end

#find_item_by_path(*path) ⇒ Qt::StandardItem?

Returns the QStandardItem object that sits at the given path

Returns:

  • (Qt::StandardItem, nil)


175
176
177
178
179
180
181
182
# File 'lib/metaruby/gui/model_hierarchy.rb', line 175

def find_item_by_path(*path)
    path.inject(self) do |parent_item, name|
        return if !name
        if names = @names_to_item[parent_item]
            names[name]
        end
    end
end

#find_item_child_by_name(item, name) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



166
167
168
169
170
# File 'lib/metaruby/gui/model_hierarchy.rb', line 166

def find_item_child_by_name(item, name)
    if context = @names_to_item[item]
        context[name]
    end
end

#find_model_from_index(index) ⇒ Object?

Returns the model that matches the QModelIndex

Returns:

  • (Object, nil)


116
117
118
119
# File 'lib/metaruby/gui/model_hierarchy.rb', line 116

def find_model_from_index(index)
    @items_to_models[
        item_from_index(index)]
end

#find_model_from_item(item) ⇒ Object?

Returns the model that matches the QStandardItem

Returns:

  • (Object, nil)


109
110
111
# File 'lib/metaruby/gui/model_hierarchy.rb', line 109

def find_model_from_item(item)
    @items_to_models[item]
end

#find_path_from_model(model) ⇒ Object

Returns the path to the given model or nil if it is not registered



63
64
65
66
67
# File 'lib/metaruby/gui/model_hierarchy.rb', line 63

def find_path_from_model(model)
    if resolver = find_resolver_from_model(model)
        resolver.split_name(model)
    end
end

#find_resolver_from_model(model) ⇒ Object?

Find the resolver object that has been responsible for a given object’s discovery

Returns:

  • (Object, nil)


58
59
60
# File 'lib/metaruby/gui/model_hierarchy.rb', line 58

def find_resolver_from_model(model)
    @resolver_from_model[model]
end

#register_model(model, model_categories, resolver) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Register a model in the hierarchy



141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
# File 'lib/metaruby/gui/model_hierarchy.rb', line 141

def register_model(model, model_categories, resolver)
    name = resolver.split_name(model)
    if !name || name.empty?
        #raise ArgumentError, "cannot resolve #{model.name}"
        puts "Cannot resolve #{model}"
        return
    end

    context = name[0..-2].inject(self) do |item, name|
        resolve_namespace(item, name)
    end
    if !(item = find_item_child_by_name(context, name.last))
        item = Qt::StandardItem.new(name.last)
        context.append_row(item)
        (@names_to_item[context] ||= Hash.new)[name.last] = item
    end

    item.flags = Qt::ItemIsEnabled

    @items_metadata[item] = Metadata.new(name, name.map { |n| [n] }, model_categories)
    @items_to_models[item] = model
    @models_to_items[model] = item
end

#reloadObject

Refresh the model to match the current hierarchy that starts with this object’s root model



77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/metaruby/gui/model_hierarchy.rb', line 77

def reload
    begin_reset_model
    clear

    @items_to_models = Hash.new
    @models_to_items = Hash.new
    @names_to_item = Hash.new
    @items_metadata = Hash[self => Metadata.new([], [], Set.new)]
    @resolver_from_model = Hash.new

    seen = Set.new
    sorted_roots = @root_models.
        sort_by(&:priority).reverse
    
    sorted_roots.each do |root_model|
        models = discover_model_hierarchy(root_model.model, root_model.categories, root_model.resolver, seen)
        models.each do |m|
            @resolver_from_model[m] = root_model.resolver
        end
    end
    
    rowCount.times do |row|
        (item(row))
    end
    self.horizontal_header_labels = [""]
ensure
    end_reset_model
end

#resolve_namespace(parent_item, name) ⇒ Qt::StandardItem

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Find or create the StandardItem that represents a namespace in the hierarchy

Parameters:

  • parent_item (Qt::StandardItem)

    the parent item

  • name (String)

    the name of the namespace

Returns:

  • (Qt::StandardItem)


251
252
253
254
255
256
257
258
259
260
261
262
263
# File 'lib/metaruby/gui/model_hierarchy.rb', line 251

def resolve_namespace(parent_item, name)
    if item = find_item_child_by_name(parent_item, name)
        item
    else
        item = Qt::StandardItem.new(name)
        item.flags = 0

        parent_name = @items_metadata[parent_item].name
        @items_metadata[item] = Metadata.new(parent_name + [name], [], Set.new)
        parent_item.append_row item
        (@names_to_item[parent_item] ||= Hash.new)[name] = item
    end
end

#resolve_root_namespace(name) ⇒ Qt::StandardItem

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Find or create the StandardItem that represents a root in the hierarchy

Parameters:

  • name (String)

    the name of the namespace

Returns:

  • (Qt::StandardItem)


239
240
241
# File 'lib/metaruby/gui/model_hierarchy.rb', line 239

def resolve_root_namespace(name)
    resolve_namespace(self, name)
end