class MetaRuby::GUI::ModelBrowser

Widget that allows to browse the currently available models and display information about them

It contains a model selection widget, which lists all available models and allows to select them, and a visualization pane in which the corresponding model visualizations are rendered as HTML

The object display itself is delegated to rendering objects. These objects must respond to:

#enable: enable this renderer. This is called so that the rendering
  object listens to relevant Qt signals if it has e.g. the ability to
  interact with the user through HTML buttons
#disable: disables this renderer. This is called so that the rendering
  object can stop listening to relevant Qt signals if it has e.g. the ability to
  interact with the user through HTML buttons
#clear: clear existing data
#render(model): render the given model

Attributes

central_splitter[R]

@return [Qt::Splitter] the horizontal splitter between the model browser and

the model view
display[R]

@return [Qt::WebView] the HTML view widget

exception_view[R]

@return [ExceptionView] view that allows to display errors to the

user
history_index[R]

@return [Integer] the index of the current link in the history

main_layout[R]

@return [Qt::BoxLayout] the main layout

manager[R]

@return [RenderingManager] the object that manages all the

rendering objects available
model_selector[R]

@return [ModelSelector] the widget that lists available models and

allows to select them
page[R]

@return [Page] the page object that handles compositing the

results of different rendering objects, as well as the ability
to e.g. handle buttons
registered_exceptions[R]

@return [Array<Exception>] set of exceptions raised during the

last rendering step
vertical_splitter[R]

@return [Qt::Splitter] the toplevel splitter (between model

browser and exception view)

Public Class Methods

new(main = nil, exception_view: nil) click to toggle source
Calls superclass method
# File lib/metaruby/gui/model_browser.rb, line 77
def initialize(main = nil, exception_view: nil)
    super(main)

    @available_renderers = Hash.new
    @registered_exceptions = Array.new

    @history = Array.new
    @history_index = -1

    @manager = RenderingManager.new

    @main_layout = Qt::VBoxLayout.new(self)
    @vertical_splitter = Qt::Splitter.new(Qt::Vertical, self)
    main_layout.add_widget(vertical_splitter)

    @central_splitter = Qt::Splitter.new(vertical_splitter)
    @exception_view = (exception_view ||= ExceptionView.new)
    exception_view.parent = vertical_splitter
    connect(exception_view, SIGNAL('fileOpenClicked(const QUrl&)'), self, SLOT('fileOpenClicked(const QUrl&)'))
    add_central_widgets(central_splitter)

    vertical_splitter.add_widget(central_splitter)
    vertical_splitter.add_widget(exception_view)
    setTabOrder(model_selector, display)

    update_exceptions
end

Public Instance Methods

add_central_widgets(splitter) click to toggle source

Sets up the widgets that form the central part of the browser

# File lib/metaruby/gui/model_browser.rb, line 167
def add_central_widgets(splitter)
    @model_selector = ModelSelector.new
    splitter.add_widget(model_selector)

    # Create a central stacked layout
    display = @display = Qt::WebView.new
    browser = self
    display.singleton_class.class_eval do
        define_method :contextMenuEvent do |event|
            menu = Qt::Menu.new(self)
            act = page.action(Qt::WebPage::Back)
            act.enabled = true
            menu.add_action act
            connect(act, SIGNAL(:triggered), browser, SLOT(:back))
            act = page.action(Qt::WebPage::Forward)
            act.enabled = true
            connect(act, SIGNAL(:triggered), browser, SLOT(:forward))
            menu.add_action act
            menu.popup(event.globalPos)
            event.accept
        end
    end
    splitter.add_widget(display)
    splitter.set_stretch_factor(1, 2)
    self.page = Page.new(@model_selector, display.page)

    model_selector.connect(SIGNAL('model_selected(QVariant)')) do |mod|
        mod = mod.to_ruby
        push_to_history(mod)
        render_model(mod)
    end
end
back() click to toggle source

Go back in the browsing history

# File lib/metaruby/gui/model_browser.rb, line 295
def back
    return if history_index <= 0
    @history_index -= 1
    select_by_history_element(history[history_index])
end
current_selection() click to toggle source

(see ModelSelector#current_selection)

# File lib/metaruby/gui/model_browser.rb, line 272
def current_selection
    model_selector.current_selection
end
forward() click to toggle source

Go forward in the browsing history

# File lib/metaruby/gui/model_browser.rb, line 288
def forward
    return if history_index == history.size - 1
    @history_index += 1
    select_by_history_element(history[history_index])
end
linkClicked(url) click to toggle source
# File lib/metaruby/gui/model_browser.rb, line 217
def linkClicked(url)
    if url.scheme == "link"
        path = url.path
        path = path.split('/')[1..-1]
        select_by_path(*path)
    end
end
page=(page) click to toggle source

Sets the page object that should be used for rendering

@param [Page] page the new page object

# File lib/metaruby/gui/model_browser.rb, line 203
def page=(page)
    if @page
        disconnect(@page, SIGNAL('linkClicked(const QUrl&)'), self, SLOT('linkClicked(const QUrl&)'))
        disconnect(@page, SIGNAL('updated()'), self, SLOT('update_exceptions()'))
        disconnect(@page, SIGNAL('fileOpenClicked(const QUrl&)'), self, SLOT('fileOpenClicked(const QUrl&)'))
    end
    manager.page = page
    connect(page, SIGNAL('linkClicked(const QUrl&)'), self, SLOT('linkClicked(const QUrl&)'))
    connect(page, SIGNAL('updated()'), self, SLOT('update_exceptions()'))
    connect(page, SIGNAL('fileOpenClicked(const QUrl&)'), self, SLOT('fileOpenClicked(const QUrl&)'))
    connect(manager, SIGNAL('updated()'), self, SLOT('update_exceptions()'))
    @page = page
end
push_to_history(object) click to toggle source

Pushes one element in the history

If the history index is not at the end, the remainder is discarded

# File lib/metaruby/gui/model_browser.rb, line 279
def push_to_history(object)
    return if object == history[history_index]

    @history = history[0, history_index + 1]
    history << object
    @history_index = history.size - 1
end
register_type(root_model, rendering_class, name, priority = 0, categories: [], resolver: ModelHierarchy::Resolver.new) click to toggle source

Registers a certain kind of model as well as the information needed to display it

It registers the given type on the model browser so that it gets displayed there.

You must call {#update_model_selector} after this call for the modification to have any effect (i.e. for the newly registered models to appear on the selector)

@param [Model] type the base model class for the models that are

considered here

@param [Class] rendering_class a class from which a relevant

rendering object can be created. The generated instances must
follow the rules described in the documentation of
{ModelBrowser}

@param [String] name the name that should be used for this

category

@param [Integer] priority the priority of this category. Some

models might be submodels of various types at the same time (as
e.g. when both a model and its supermodel are registered here).
The one with the highest priority will be used.
# File lib/metaruby/gui/model_browser.rb, line 159
def register_type(root_model, rendering_class, name, priority = 0, categories: [], resolver: ModelHierarchy::Resolver.new)
    model_selector.register_type(
        root_model, name, priority,
        categories: categories, resolver: resolver)
    manager.register_type(root_model, rendering_class)
end
reload() click to toggle source

Update the model list

# File lib/metaruby/gui/model_browser.rb, line 312
def reload
    model_selector.reload
end
render_model(mod, options = Hash.new) click to toggle source

Call to render the given model

@param [Model] mod the model that should be rendered @raise [ArgumentError] if there is no view available for the

given model
# File lib/metaruby/gui/model_browser.rb, line 233
def render_model(mod, options = Hash.new)
    page.clear
    @registered_exceptions.clear
    reference_model, _ = manager.find_renderer(mod)
    if mod
        page.title = "#{mod.name} (#{reference_model.name})"
        begin
            manager.render(mod, options)
        rescue ::Exception => e
            @registered_exceptions << e
        end
    else
        @registered_exceptions << ArgumentError.new("no view available for #{mod} (#{mod.class})")
    end
    update_exceptions
end
restore_from_settings(settings) click to toggle source

Restore the state of this widget from settings previously saved with {#save_to_settings}

@param [Qt::Settings] settings

# File lib/metaruby/gui/model_browser.rb, line 109
def restore_from_settings(settings)
    %w{central_splitter vertical_splitter}.each do |object_name|
        sizes = settings.value(object_name)
        if !sizes.null?
            sizes = sizes.to_list.map do |obj|
                obj.to_int
            end
            send(object_name).sizes = sizes
        end
    end
end
save_to_settings(settings) click to toggle source

Save the current state of this widget in the given settings

@param [Qt::Settings] settings

# File lib/metaruby/gui/model_browser.rb, line 124
def save_to_settings(settings)
    %w{central_splitter vertical_splitter}.each do |object_name|
        sizes = send(object_name).sizes
        sizes = sizes.map { |o| Qt::Variant.new(o) }
        settings.set_value(object_name, Qt::Variant.new(sizes))
    end
end
select_by_history_element(h) click to toggle source

Selects a given model based on a value in the history

# File lib/metaruby/gui/model_browser.rb, line 304
def select_by_history_element(h)
    if h.respond_to?(:to_ary)
        select_by_path(*h)
    else select_by_model(h)
    end
end
select_by_model(model) click to toggle source

(see ModelSelector#select_by_model)

# File lib/metaruby/gui/model_browser.rb, line 265
def select_by_model(model)
    if model_selector.select_by_model(model)
        push_to_history(model)
    end
end
select_by_path(*path) click to toggle source

(see ModelSelector#select_by_model)

# File lib/metaruby/gui/model_browser.rb, line 258
def select_by_path(*path)
    if model_selector.select_by_path(*path)
        push_to_history(path)
    end
end
update_exceptions() click to toggle source

Updates {#exception_view} from the set of registered exceptions

# File lib/metaruby/gui/model_browser.rb, line 251
def update_exceptions
    exception_view.exceptions = registered_exceptions +
        manager.registered_exceptions
end
update_model_selector() click to toggle source

Update the model selector after {#register_type} got called

# File lib/metaruby/gui/model_browser.rb, line 133
def update_model_selector
    model_selector.update
end