class Vizkit::UiLoader

because of the shadowed method load we have to use DelegateClass

Attributes

current_file_path[RW]
current_loader_instance[RW]
plugin_specs[RW]

Public Class Methods

deprecate_plugin_spec(spec,message=nil,&block) click to toggle source
# File lib/vizkit/uiloader.rb, line 103
def deprecate_plugin_spec(spec,message=nil,&block)
    current_loader_instance.deprecate_plugin_spec(spec,message,&block)
end
extend_cplusplus_widget_class(class_name,&block) click to toggle source
# File lib/vizkit/uiloader.rb, line 50
def extend_cplusplus_widget_class(class_name,&block)
    spec = current_loader_instance.register_plugin(class_name,:cplusplus_widget) do |parent|
        widget = current_loader_instance.create_widget(class_name,parent,true,true)
        raise RuntimeError, "There is no widget called #{class_name} available. Check spelling" unless widget
        UiLoader.redefine_widget_class_name(widget,class_name)
        widget
    end
    spec.extension(VizkitCXXExtension)
    spec.extension(block)
    spec.cplusplus_name(class_name)
    spec.on_create do |plugin|
        plugin.initialize_vizkit_extension
    end
end
new(parent = nil) click to toggle source
Calls superclass method
# File lib/vizkit/uiloader.rb, line 108
def initialize(parent = nil)
    super(Qt::UiLoader.new(parent))
    # This should NOT be here. If that is required, then one that wants
    # to use Vizkit should be required to load/initialize it FIRST
    #
    # Keep it there for backward compatibility though :(
    if !Orocos.loaded?
        Vizkit.warn "one must call Orocos.load before using Vizkit.default_loader"
        Orocos.load
    end
    @plugin_specs = Hash.new

    load_extensions(File.join(File.dirname(__FILE__),"cplusplus_extensions"))
    load_extensions(File.join(File.dirname(__FILE__),"widgets"))

    paths = plugin_paths().uniq
    paths.each do|path|
        if File.directory?(path)
            Vizkit.info "Load extension from #{path}"
            load_extensions(path)
        else
            Vizkit.info "No Directory! Cannot load extensions from #{path}."
        end
    end
end
redefine_widget_class_name(widget,class_name) click to toggle source

redefines the widget class name of a widget this is needed because the qt loader does not set it right after the widget was loaded

# File lib/vizkit/uiloader.rb, line 91
def redefine_widget_class_name(widget,class_name)
    if class_name && (widget.class_name == "Qt::Widget" || widget.class_name == "Qt::MainWindow")
        widget.instance_variable_set(:@real_class_name,class_name)
        def widget.class_name;@real_class_name;end
        def widget.className;@real_class_name;end
    end
end
register_3d_plugin(ruby_name,lib_name=nil,plugin_name=nil) click to toggle source
# File lib/vizkit/uiloader.rb, line 37
def register_3d_plugin(ruby_name,lib_name=nil,plugin_name=nil)
    lib_name = lib_name || ruby_name
    plugin_name = plugin_name || ruby_name
    spec = current_loader_instance.register_plugin(ruby_name,:vizkit3d_plugin) do |parent|
        widget = Vizkit.vizkit3d_widget
        widget.show # if widget.hidden?
        if !widget.respond_to? :createPlugin
            raise "Extension for Vizkit3d widget was not loaded. Cannot create any Vizkit3dPlugin"
        end
        widget.createPlugin(lib_name,plugin_name,spec)
    end
    spec.cplusplus_name(plugin_name).lib_name(lib_name)
end
register_3d_plugin_for(widget_name,type_name,display_method = nil,&block) click to toggle source
# File lib/vizkit/uiloader.rb, line 84
def register_3d_plugin_for(widget_name,type_name,display_method = nil,&block)
    register_plugin_for(widget_name,type_name,:display,nil,display_method,&block)
end
register_control_for(widget_name,value,callback_fct=nil,&block) click to toggle source
# File lib/vizkit/uiloader.rb, line 75
def register_control_for(widget_name,value,callback_fct=nil,&block)
    register_plugin_for(widget_name,value,:control,nil,callback_fct,&block)
end
register_default_3d_plugin_for(widget_name,type_name,display_method = nil,&block) click to toggle source
# File lib/vizkit/uiloader.rb, line 81
def register_default_3d_plugin_for(widget_name,type_name,display_method = nil,&block)
    register_plugin_for(widget_name,type_name,:display,true,display_method,&block)
end
register_default_control_for(widget_name,value,callback_fct=nil,&block) click to toggle source
# File lib/vizkit/uiloader.rb, line 78
def register_default_control_for(widget_name,value,callback_fct=nil,&block)
    register_plugin_for(widget_name,value,:control,true,callback_fct,&block)
end
register_default_widget_for(widget_name,value,callback_fct=nil,&block) click to toggle source
# File lib/vizkit/uiloader.rb, line 72
def register_default_widget_for(widget_name,value,callback_fct=nil,&block)
    register_plugin_for(widget_name,value,:display,true,callback_fct,&block)
end
register_deprecate_plugin_clone(clone_name,name,message="[Depricated Plugin Name] click to toggle source
# File lib/vizkit/uiloader.rb, line 99
def register_deprecate_plugin_clone(clone_name,name,message="[Depricated Plugin Name] #{clone_name}. Use #{name}",&block)
    current_loader_instance.register_deprecate_plugin_clone(clone_name,name,message,&block)
end
register_plugin_for(plugin_name,value,callback_type,default=nil,callback_fct=nil,&block) click to toggle source

interface for ruby extensions

# File lib/vizkit/uiloader.rb, line 66
def register_plugin_for(plugin_name,value,callback_type,default=nil,callback_fct=nil,&block)
    current_loader_instance.register_plugin_for(plugin_name,value,callback_type,default,callback_fct,&block)
end
register_ruby_widget(widget_name,create_method=nil,&block) click to toggle source
# File lib/vizkit/uiloader.rb, line 33
def register_ruby_widget(widget_name,create_method=nil,&block)
    current_loader_instance.register_plugin(widget_name,:ruby_plugin,create_method,&block)
end
register_widget_for(widget_name,value,callback_fct=nil,&block) click to toggle source
# File lib/vizkit/uiloader.rb, line 69
def register_widget_for(widget_name,value,callback_fct=nil,&block)
    register_plugin_for(widget_name,value,:display,nil,callback_fct,&block)
end

Public Instance Methods

addPluginPath(path)
Alias for: add_plugin_path
add_plugin_path(path) click to toggle source
Calls superclass method
# File lib/vizkit/uiloader.rb, line 134
def add_plugin_path(path)
    return if plugin_paths.include? path
    super
    load_extensions(path)
end
Also aliased as: addPluginPath
all_plugin_specs() click to toggle source

Return all plugin specs

# File lib/vizkit/uiloader.rb, line 398
def all_plugin_specs
    @plugin_specs.values
end
create_plugin(class_name,parent=nil,reuse=false,raise_=true) click to toggle source
# File lib/vizkit/uiloader.rb, line 331
def create_plugin(class_name,parent=nil,reuse=false,raise_=true)
    spec = find_plugin_spec!({:plugin_name => class_name})
    return unless spec
    #check if there is already a widget of the same type
    #which can handle multiple values
    if reuse
        spec.created_plugins.each do |plugin| 
            return plugin if(plugin.respond_to?(:multi_value?) && plugin.multi_value?)
        end
    end
    plugin = spec.create_plugin(parent)
    plugin.setObjectName class_name if plugin.is_a?(Qt::Object) && !plugin.objectName
    plugin
end
create_plugin_for(value,callback_type,parent=nil,reuse=false) click to toggle source

creates a plugin which can handle the given type if reuse is set to ture it will first try to return a plugin which is already created and can handle multiple values of the the given value

# File lib/vizkit/uiloader.rb, line 360
def create_plugin_for(value,callback_type,parent=nil,reuse=false)
    name = find_plugin_name!(:argument => value,:callback_type => callback_type)
    create_plugin(name,parent,reuse) if name 
end
create_widget(name,parent=nil,reuse=true,internal=false) click to toggle source

compatibility method

Calls superclass method
# File lib/vizkit/uiloader.rb, line 347
def create_widget(name,parent=nil,reuse=true,internal=false)
    unless internal
        Vizkit.warn "[DEPRECATATION] 'create_widget' is deprecated use 'create_plugin' instead."
        create_plugin(name,parent,reuse)
    else
        super(name,parent)
    end
end
deprecate_plugin_spec(spec,message=nil,&block) click to toggle source
# File lib/vizkit/uiloader.rb, line 187
def deprecate_plugin_spec(spec,message=nil,&block)
    if(block||message)
        spec.instance_eval do 
            alias :old_create_plugin :create_plugin
        end
        spec.instance_variable_set :@__deprecate_message,message
        spec.instance_variable_set :@__deprecate_block,block
        def spec.create_plugin(parent=nil)
            Vizkit.warn @__deprecate_message if @__deprecate_message
            @__deprecate_block.call if @__deprecate_block
            old_create_plugin(parent)
        end
        #set all callbacks to false
        spec.callback_specs.each do|calls|
            calls.default(false)
        end
        #add deprecate flag
        spec.flags(spec.flags.merge({:deprecated => true}))
        add_plugin_spec spec
    end
    spec
end
extend_widgets(widget,mapping,children=true) click to toggle source

extends the widget and all its children this is needed for cases where the widget was loaded via an ui file

# File lib/vizkit/uiloader.rb, line 302
def extend_widgets(widget,mapping,children=true)
    class_name = mapping[widget.objectName]
    if class_name
        UiLoader.redefine_widget_class_name widget,class_name
        spec = find_plugin_spec!({:plugin_name => class_name})
        spec.extend_plugin(widget) if spec
    end
    return widget unless children

    #extend childs and add accessor for QObject
    #find will find children recursive
    #objectNames are unique for widgets if the ui file was
    #generated with the qt designer therefore we can put them to the toplevel
    #warning: ruby objects have the wrong parent
    children = widget.findChildren(Qt::Object)
    children.each do |child|
        if child.objectName && child.objectName.size > 0
            extend_widgets child, mapping,false
            (class << widget; self;end).send(:define_method,child.objectName){child}
        end
    end
    widget
end
find_all_plugin_names(*pattern) click to toggle source

returns the plugin names which can handle the given value

# File lib/vizkit/uiloader.rb, line 430
def find_all_plugin_names(*pattern)
    find_all_plugin_specs(*pattern).map do |spec|
        spec.plugin_name
    end
end
find_all_plugin_specs(*pattern) click to toggle source

returns an array of plugin specs matching the given pattern

if registered is set to false the mehtod will search for not registered cplusplus widgets if no spec can be found and automatically register this widget if one can be found

:plugin_name :cplusplus_name :value if given callback_type must be given as well :callback_type if given value must be given as well :default if given value and callback_type must be given as well :registered if set to true the method will not search for

not registered c++ widgets and automatically register them
# File lib/vizkit/uiloader.rb, line 379
def find_all_plugin_specs(*pattern)
    return Array.new if pattern.empty?
    pattern = pattern.first
    if pattern.size == 1 && pattern[:plugin_name]
        spec = @plugin_specs[pattern[:plugin_name]]
        return Array(spec) if spec 
        #try to find a cplusplus widget which is not registered
        #and register it
        if widget?(pattern[:plugin_name])
            result = Array(UiLoader.extend_cplusplus_widget_class(pattern[:plugin_name]))
            return result
        end
    end
    @plugin_specs.values.find_all do |spec|
        spec.match?(pattern)
    end
end
find_plugin_name!(*pattern) click to toggle source
# File lib/vizkit/uiloader.rb, line 436
def find_plugin_name!(*pattern)
    spec = find_plugin_spec!(*pattern)
    spec.plugin_name if spec
end
find_plugin_spec!(*pattern) click to toggle source
# File lib/vizkit/uiloader.rb, line 402
def find_plugin_spec!(*pattern)
    return if pattern.empty?
    pattern = pattern.first
    if pattern.size == 1 && pattern[:plugin_name]
        return find_all_plugin_specs(pattern).first
    end

    names = PluginHelper.normalize_obj(pattern[:argument])
    names << nil if names.empty?
    pattern = pattern.dup
    pattern[:exact] = true
    pattern[:default] = true if !pattern.has_key?(:default)
    specs = Array.new
    names.each do |name|
        pattern[:argument] = name
        result = find_all_plugin_specs(pattern)
        if !result.empty?
            specs = result
            break
        end
    end
    if specs.size > 1
        raise ArgumentError.new "Found more than on PluginSpec for the given pattern"
    end
    specs.first
end
load(ui_file,parent=nil) click to toggle source

creates a widget and all its children from an ui file

# File lib/vizkit/uiloader.rb, line 260
def load(ui_file,parent=nil)
    if parent and not parent.is_a? Qt::Widget
        Kernel.raise("You can only set a QWidget as parent. You tried: #{parent}")
    end
    
    file = Qt::File.new(ui_file)
    file.open(Qt::File::ReadOnly)

    form = nil
    Dir.chdir File.dirname(ui_file) do 
        form = __getobj__.load(file,parent)
    end
    return unless form 

    mapping = map_objectName_className(ui_file)
    extend_widgets form, mapping

    #check that all widgets are available
    mapping.each_key do |k|
        if !form.respond_to?(k.to_s) && form.objectName != k
            Vizkit.warn "Widgte #{k} of class #{mapping[k]} could not be loaded! Is this Qt Designer Widget installed?"
        end
    end
    form
end
load_extensions(*paths) click to toggle source
# File lib/vizkit/uiloader.rb, line 140
def load_extensions(*paths)
    paths.flatten!
    paths.each do |path|
        if ::File.file?(path) 
            UiLoader.current_loader_instance = self
            UiLoader.current_file_path = path
            begin 
                Kernel.load path if !path.match(/.ui.rb$/) && ::File.extname(path) ==".rb"
            rescue Interrupt
                raise
            rescue Exception => e
                Vizkit.warn "Cannot load vizkit extension #{path}"
                Vizkit.warn e.message
                e.backtrace.each do |line|
                    Vizkit.warn line
                end
            end
        elsif ::File.directory?(path)
            load_extensions ::Dir.glob(::File.join(path,"**","*.rb"))
        else
            # Check if we can find the file in $LOAD_PATH and by adding .rb
            paths.each do |file|
                $LOAD_PATH.each do |path|
                    if File.file?(full_path = File.join(path, file))
                        load_extensions(full_path)
                        return
                    elsif File.file?(full_path = "#{full_path}.rb")
                        load_extensions(full_path)
                        return
                    end
                end
            end
            warn "Qt designer plugin file or directory does not exist: #{path.inspect}!"
        end
    end
end
map_objectName_className(ui_file) click to toggle source

work around metaObject.className is always QWidget for qt4-ruby1.8 4.4.5 therefore we have to pass the ui file to get the mapping this error disappears on newer versions

# File lib/vizkit/uiloader.rb, line 290
def map_objectName_className(ui_file)
    doc = REXML::Document.new File.new ui_file
    mapping = Hash.new
    REXML::XPath.each( doc, "//widget")do |ele|
        mapping[ele.attributes["name"]] = ele.attributes["class"]
    end
    mapping
end
method_missing(*args, &block) click to toggle source

Ruby 1.9.3's Delegate has a different behaviour than 1.8 and 1.9.2. This is breaking the class definition, as some method calls gets undefined.

Backward compatibility fix.

# File lib/vizkit/uiloader.rb, line 445
def method_missing(*args, &block)
    #check if we can find a cplusplus widget matching the name
    if widget? args[0].to_s
        spec = find_all_plugin_specs(:plugin_name => args[0].to_s).first
        return spec.create_plugin(*args[1..-1]) if spec
    end
    begin
        __getobj__.send(*args, &block)
    rescue  NoMethodError => e
        Vizkit.error "#{args.first} is not plugin of the ui loader"
        Vizkit.error "The following plugins are registered:"
        names = available_plugins.sort
        Vizkit.error names.join(", ")
        Kernel.raise e 
    end
end
register_deprecate_plugin_clone(clone_name,name,message=nil,&block) click to toggle source
# File lib/vizkit/uiloader.rb, line 210
def register_deprecate_plugin_clone(clone_name,name,message=nil,&block)
    spec = find_plugin_spec!({:plugin_name => name})
    if !spec
        raise "Cannot register deprecate plugin clone #{clone_name} for #{name}. #{name} is not a registered plugin."
    end
    if find_plugin_spec!({:plugin_name => clone_name})
        raise "Cannot register deprecate plugin clone #{clone_name} for #{name}. #{clone_name} is already registered."
    end
    clone_spec = spec.clone
    clone_spec.instance_variable_set(:@plugin_name, clone_name)
    clone_spec.flags(clone_spec.flags.merge({:clone_of => name}))
    deprecate_plugin_spec(clone_spec,message,&block)
    add_plugin_spec clone_spec
end
register_plugin(plugin_name,plugin_type,creation_method=nil,&block) click to toggle source
# File lib/vizkit/uiloader.rb, line 177
def register_plugin(plugin_name,plugin_type,creation_method=nil,&block)
    if @plugin_specs[plugin_name] 
        raise "Plugin #{plugin_name} is already registered!"
    end
    spec = PluginSpec.new(plugin_name).creation_method(creation_method,&block).plugin_type(plugin_type)
    spec.extension(PluginConnections)
    raise "Cannot register plugin. Plugin name is nil" unless spec.plugin_name
    add_plugin_spec(spec)
end
register_plugin_for(plugin_name,values,callback_type,default=nil,callback_fct=nil,&block) click to toggle source
# File lib/vizkit/uiloader.rb, line 225
def register_plugin_for(plugin_name,values,callback_type,default=nil,callback_fct=nil,&block)
    if !callback_fct && !block
        raise ArgumentError, "#register_plugin_for(#{plugin_name}, #{values}, #{callback_type}) with neither a callback method name nor a block"
    end

    spec = find_plugin_spec!({:plugin_name => plugin_name})
    if !spec
        raise "Cannot register #{callback_fct||block} for #{plugin_name}. #{plugin_name} is not a registered plugin."
    end
    
    values = Array(values)
    specs = Array.new
    values.each do |value|
        spec2 = find_plugin_spec!(:callback_type => callback_type,:argument => value)
        #delete old default
        if spec2 
            spec2 = spec2.find_callback_spec!(:callback_type => callback_type,:argument=> value)
            if default
                spec2.default(false)
            else
                # check if the argument of the found spec is for a parent class type
                if spec2.argument != PluginHelper.normalize_obj(value,false).first
                    default = true
                end
            end
        else
            default = true
        end
        spec.callback_spec(value,callback_type,default,callback_fct,&block).file_name(UiLoader.current_file_path)
        specs << spec.callback_specs.last
    end
    values.size == 1 ? specs.first : specs
end
widget?(name) click to toggle source
# File lib/vizkit/uiloader.rb, line 326
def widget?(name)
    return unless name
    availableWidgets.include? name
end