Module: Ruber::PluginLike

Included in:
Application, ConfigManager, MainWindow, Plugin, World::World
Defined in:
lib/ruber/plugin_like.rb

Overview

Module providing basic functionality common to both plugin and core components.

This mainly is an helper module, used to avoid code duplication among the Plugin class and the various core components (Application, MainWindow and so on which can’t inherit from Plugin). From a logical point of view, all of the functionality provided by this module should be in the Plugin class, instead.

Note: this module MUST only be included in classes which descend from Qt::Object, otherwise it will produce crashes

Instance Attribute Summary (collapse)

Instance Method Summary (collapse)

Instance Attribute Details

- (PluginSpecification) plugin_description (readonly)

The plugins specification object for the plugin

Returns:



40
41
42
# File 'lib/ruber/plugin_like.rb', line 40

def plugin_description
  @plugin_description
end

Instance Method Details

- (nil) add_extensions_to_project(prj, forbid_existing = true)

Adds the project extensions provided by the plugin to a project

Only the extensions matching the project will be added.

If the project already has one of the extensions this method wouold add, it can either raise an exception or ignore the exception. The first behaviour is desirable the first time the plugin’s extensions are added to the project, while the second is useful if this method has already been called for the project. In the first case, the existing extension most likely belongs to another plugin, which may lead to conflict. In the second case, instead, the extension will belong to this plugin, so there’s no risk.

an extension already exists in the project. one of the extension which this method would add

Parameters:

  • prj (Ruber::AbstractProject)

    the project to add the extensions to

  • forbid_existing (Boolean) (defaults to: true)

    whether to raise an exception or do nothing if

Returns:

  • (nil)

Raises:

  • ArgumentError if forbid_existing is true and the project already has

See Also:



287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
# File 'lib/ruber/plugin_like.rb', line 287

def add_extensions_to_project prj, forbid_existing = true
  @plugin_description.extensions.each_pair do |name, o|
    unless forbid_existing
      next if prj.extension name
    end
    ext = nil
    if o.is_a? Array
      o = o.find{|i| prj.match_rule? i}
      next unless o
      ext = o.class_obj.new prj
    elsif prj.match_rule? o
      ext = o.class_obj.new prj
    end
    if ext
      ext.plugin = self
      prj.add_extension name, ext
      emit extension_added(name.to_s, prj) rescue nil
    end
  end
end

- (nil) add_options_to_project(prj, forbid_existing = true)

Adds the project options provided by the plugin to a project

Only the options whose rules match the project are added.

If one of the options provided by the plugin (and whose rules matches the project) has already been inserted in the project, this method can either raise an exception or ignore the option. The first behaviour is desirable the first time the plugin’s options are added to the project, while the second is useful if this method has already been called for the project. In the first case, the existing option most likely belongs to another plugin, which may lead to conflict. In the second case, instead, the option will belong to this plugin, so there’s no risk.

an option already exists in the project. by the plugin already exists

Parameters:

  • prj (Ruber::AbstractProject)

    the project to add the options to

  • forbid_existing (Boolean) (defaults to: true)

    whether to raise an exception or do nothing if

Returns:

  • (nil)

Raises:

  • ArgumentError if forbid_existing is true and one of the options provided

See Also:



196
197
198
199
200
201
202
203
204
205
# File 'lib/ruber/plugin_like.rb', line 196

def add_options_to_project prj, forbid_existing = true
  @plugin_description.project_options.values.sort_by{|i| i.order || 0}.each do |o|
    o = o.to_os(prj.obj_binding)
    begin prj.add_option o if prj.match_rule?(o)
    rescue ArgumentError
      raise if forbid_existing
    end
  end
  nil
end

- (nil) add_widgets_to_project(prj)

Adds the project widgets provided by the plugin to a project

Only the widgets matching the project will be added.

Parameters:

Returns:

  • (nil)


246
247
248
249
250
251
# File 'lib/ruber/plugin_like.rb', line 246

def add_widgets_to_project prj
  @plugin_description.project_widgets.each do |w| 
    prj.add_widget w if prj.match_rule? w
  end
  nil
end

- (nil) create_tool_widget(data) (private)

Creates a tool widget and inserts it in the main window

It uses the data contained in the PSF to find out the characteristics of the tool widget. If the PSF contains a var_name entry for the tool widget, then an instance variable with that name will be created and set to the tool widget. If the PSF contains a name entry for the tool widget, its object_name will be set to that value.

If the tool widget object has a load_settings method, it’ll be connected with the configuration manager’s settings_changed signal

plugin’s context, returns the tool widget. At least one between this entry and the class_obj entry must be not nil the code entry is not *nil*At least one between this entry and the code entry must be not nil the tool widget. It’s mandatory tool widget. The values :left, :right and :bottom are valid

Parameters:

  • data (OpenStruct)

    the data from the PSF corresponding to the tool widget

Options Hash (data):

  • code (String) — default: nil

    a string of code which, when evaluated in the

  • :class_obj (Class) — default: nil

    the class of the tool widget. Ignored if

  • pixmap (String)

    the name of the file containing the icon to use for

  • caption (String)

    the caption for the tool widget. Mandatory

  • position (Symbol) — default: :left

    the side of the screen where to put the

Returns:

  • (nil)


518
519
520
521
522
523
524
525
526
527
# File 'lib/ruber/plugin_like.rb', line 518

def create_tool_widget data
  w = data.code ? eval(w, binding) : data.class_obj.new
  w.object_name = data.name if data.name
  Ruber[:main_window].add_tool data.position, w, Qt::Pixmap.new(data.pixmap), data.caption
  instance_variable_set("@#{data.var_name}", w) if data.var_name
  if w.respond_to? :load_settings and Ruber[:config]
    connect Ruber[:config], SIGNAL("settings_changed()"), w, SLOT("load_settings()")
    w.load_settings
  end
end

- (nil) delayed_initialize (private)

Performs delayed initialization

This method is called by the component manager after the plugin object has been stored in the component manager (and thus made availlable through Ruber.[]). Plugins only need to override this method (the base class version does nothing) if something which should happen during initialization requires to access the plugin using Ruber.[]

Returns:

  • (nil)


170
171
# File 'lib/ruber/plugin_like.rb', line 170

def delayed_initialize
end

- (PluginLike) initialize_plugin(pdf) (private)

Initializes the plugin

If this were a class rather than a module, this would be its initialize method. Since this is a module, it can’t have an initialize method in the sense classes do, therefore it’s up to classes including this module to call this method from their initialize, before using any functionality provided by this module.

The most important things done here are (in order):

  • adding the plugin to the component manager, so that it can be accessed using Ruber.[]
  • connects the #load_settings method with the configuration manager’s settings_changed signal
  • adds the options provided by the plugin to the configuration manager and loads the settings
  • creates the tool widgets provided by the plugin

Note: everything regarding the configuration manager is ignored if it doesn’t exist

Returns:



426
427
428
429
430
431
432
433
434
435
436
# File 'lib/ruber/plugin_like.rb', line 426

def initialize_plugin pdf
  @plugin_description = pdf
  Ruber[:components].add self
  if Ruber[:config]
    connect Ruber[:config], SIGNAL(:settings_changed), self, SLOT(:load_settings)
    register_options
    load_settings
  end
  @plugin_description.tool_widgets.each{|w| create_tool_widget w}
  self
end

- (nil) load_settings (private)

Applies the configuration settings

This method is called when the plugin is created and whenever the global settings change. The base class implementation does nothing. Plugins which need to react to changes in the global settings must reimplement it.

Note: this method must be a slot, so any class which directly includes this module should have a line like

slots :load_settings

Returns:

  • (nil)


471
472
# File 'lib/ruber/plugin_like.rb', line 471

def load_settings
end

- (Symbol) plugin_name Also known as: component_name

The internal name of the plugin

Returns:

  • (Symbol)

    the internal name of the plugin



45
46
47
# File 'lib/ruber/plugin_like.rb', line 45

def plugin_name
  @plugin_description.name
end

- (Boolean) query_close

Whether or not the plugin allows the application to shut down

If this method returns false for any plugin, the application won’t be closed.

maybe depending on the status of the plugin itself. As an example, the Document List component checks whether there are unsaved documents and asks the user what to do. If the user decides not to close the appplication, the method will return false.

Returns:

  • (Boolean)

    true. Plugins may override this method and return something else,



108
109
110
# File 'lib/ruber/plugin_like.rb', line 108

def query_close
  true
end

- (nil) register_options (private)

Adds the global options and configuration widgets provided by the plugin to the configuration manager

It does nothing if the configuration manager hasn’t as yet been created

Returns:

  • (nil)


481
482
483
484
485
486
487
488
489
# File 'lib/ruber/plugin_like.rb', line 481

def register_options
  config = Ruber[:config]
  return unless config
  @plugin_description.config_options.values.sort_by{|o| o.order || 0}.each do |o| 
    config.add_option o.to_os(binding)
  end
  @plugin_description.config_widgets.each{|w| config.add_widget w}
  nil
end

- (nil) register_with_project(prj)

Informs a project of the existance of the plugin

The base class implemenetation adds all the known project options, poject widgets and project extensions to the project. If a plugin needs to do something fancy with projects, it can override this method and do it from here, after calling the base class implementation.

Parameters:

Returns:

  • (nil)


359
360
361
362
363
# File 'lib/ruber/plugin_like.rb', line 359

def register_with_project prj
  add_options_to_project prj, true
  add_widgets_to_project prj
  add_extensions_to_project prj, true
end

- (nil) remove_extensions_from_project(prj, all = true)

Remove the extensions provided by the pluging from a project

Depending on the value of all, all the extensions provided by the plugin or only the ones which dont’ match the project are removed. In this case, a multi-class extension will only be removed if the class of the extension object is the same as the one specified in one of the entries which don’t match the project.

Note: to decide whether an extension belongs to the plugin or not, this method checks whether the object returned by the exension’s plugin method is the same as self.

only those which don’t match the project

Parameters:

  • prj (Ruber::AbstractProject)

    the project to remove the extensions from

  • all (Boolean) (defaults to: true)

    whether to remove all extensions provided by the plugin or

Returns:

  • (nil)

See Also:



326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
# File 'lib/ruber/plugin_like.rb', line 326

def remove_extensions_from_project prj, all = true
  if all
    prj.each_extension.select{|_, v| v.plugin.same? self}.each do |k, _|
      emit removing_extension k.to_s, prj rescue nil
      prj.remove_extension k
      emit extension_removed k.to_s, prj rescue nil
    end
  else
    exts = @plugin_description.extensions
    prj.each_extension.select{|_, v| v.plugin.same? self}.each do |k, o|
      data = exts[k]
      data = data.find{|i| i.class_obj == o.class} if data.is_a? Array
      if !prj.match_rule? data
        emit removing_extension k.to_s, prj rescue nil
        prj.remove_extension k
        emit extension_removed k.to_s, prj rescue nil
      end
    end
  end
  nil
end

- (nil) remove_from_project(prj)

Removes all traces of the plugin from a project

This method is called when the plugin is unloaded or when the project is closed and takes care of removeing all project options, project widgets and project extensions belonging to the plugin from the project.

If a plugin needs to do some other cleanup when removed from a project, it can override this method and do what it needs here (usually before calling super)

Parameters:

Returns:

  • (nil)


377
378
379
380
381
# File 'lib/ruber/plugin_like.rb', line 377

def remove_from_project prj
  remove_options_from_project prj, true
  remove_widgets_from_project prj
  remove_extensions_from_project prj, true
end

- (nil) remove_options_from_project(prj, matching = true)

Removes the project options provided by the plugin from a project

This method can operate in two ways: it can remove from the project all the options it provides whose rules match or don’t match the project. The first behaviour is meant to be used when the plugin is unloaded or the project is closed; the second when the project characteristics change, to remove those options which used to match the project but don’t anymore.

Parameters:

  • prj (Ruber::AbstractProject)

    the project to remove options from

  • matching (Boolean) (defaults to: true)

    whether to remove only

Returns:

  • (nil)

See Also:



221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
# File 'lib/ruber/plugin_like.rb', line 221

def remove_options_from_project prj, matching = true
  if matching
    @plugin_description.project_options.each_pair do |_, o|
      o = o.to_os(prj.obj_binding)
      prj.remove_option o.group, o.name if prj.match_rule? o
    end
  else
    @plugin_description.project_options.each_pair do |_, o|
      o = o.to_os(prj.obj_binding)
      if prj.has_option?(o.group, o.name) and !prj.match_rule? o
        prj.remove_option o.group, o.name
      end
    end
  end
  nil
end

- (nil) remove_widgets_from_project(prj)

Removes the project widgets provided by the plugin from a project

Parameters:

Returns:

  • (nil)


259
260
261
262
263
264
# File 'lib/ruber/plugin_like.rb', line 259

def remove_widgets_from_project prj
  @plugin_description.project_widgets.each do |w| 
    prj.remove_widget w
  end
  nil
end

- (Object) restore_session(cfg)

Restores the state of the plugin from session management

This method is called by the component manager when a session needs to be restored. Plugins need to override it if they have some state which needs to be restored (there’s no need to call super when overriding, since the base class method does nothing)

Parameters:

  • cfg (Hash)

    a hash containing the keys stored in the hash returned by #session_data

See Also:



157
158
# File 'lib/ruber/plugin_like.rb', line 157

def restore_session cfg
end

- (nil) save_settings

Method called at application shutdown to allow plugins to save their settings

Plugins which need to save some settings need to override this method, as the base class implementation does nothing.

Note: the plugin system calls this method for all plugins before starting unloading them. This means that it’s absolutely safe to access other plugins’ methods, objects, options,… from here

Returns:

  • (nil)


123
124
125
# File 'lib/ruber/plugin_like.rb', line 123

def save_settings
  nil
end

- (Hash) session_data

The data the plugin wants to store when the application is shut down by session management

session manager. The hash returned by this method is empty, so plugin which need to store some information need to override it. Note that the hashes returned by this method from various plugins are merged. To avoid name clashes, you should use unique names for the keys in the hashes. The best way to do this is to return a hash with a single key, named after the plugin, and corresponding to an inner hash containing the information you actually need to store

Returns:

  • (Hash)

    a hash containing the information which should be stored by the

See Also:



141
142
143
# File 'lib/ruber/plugin_like.rb', line 141

def session_data
  {}
end

- (KDE::Action) setup_action(data, coll) (private)

Creates one of the actions described in the PSF

Besides creating the action and adddint it to the specified KDE::ActionCollection, it registers a state handler for the action in the main window, if the PSF entry for the action includes a state entry (the plugin iself is used as extra_id for the handler), and creates a signal-slot connection between the action and the receiver specified in the receiver PSF entry for the action, provided that the slot entry isn’t nil.

action to KDE::StandardAction method to call to create the action. If this entry isn’t given, the action won’t be a standard action to create the action for the action If missing, no signal-slot connection is made. signal to connect to. Ignored unless the slot entry is given context of the plugin, returns the object the action should be connected to on. Note that this method doesn’t register a state handler for multiple states

Parameters:

  • data (OpenStruct)

    the structure containing the data used to create the

  • cool (KDE::ActionCollection)

    the action collection the new action belongs

Options Hash (data):

  • standard_action (Symbol, String, nil) — default: nil

    if not nil, the name of the

  • action_class (Class) — default: KDE::Action

    the class object to instantiate

  • text (String) — default: ''

    the text for the action

  • help_text (String) — default: ''

    the help text for the action

  • shortcut (String) — default: ''

    a string representing the default shortcut

  • icon (String) — default: ''

    the filename of the icon to use for the action

  • slot (String) — default: nil

    the slot to connect a signal from the action to.

  • signal (String, Symbol) — default: 'triggered()'

    the signature of the action

  • receiver (String) — default: 'self'

    a string which, when evalued in the

  • state (String) — default: nil

    the name of a single GUI state the action depends

Returns:

  • (KDE::Action)

    the newly created action



563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
# File 'lib/ruber/plugin_like.rb', line 563

def setup_action data, coll
  action = if data.standard_action
    if data.standard_action.to_s == 'open'
      KDE::StandardAction.open nil, '', coll
    else KDE::StandardAction.send data.standard_action, nil, '', coll
    end
  else data.action_class.new coll
  end
  action.text = data.text unless data.text.empty?
  action.help_text = data.help unless data.help.empty?
  action.shortcut = data.shortcut if data.shortcut
  action.icon = Qt::Icon.new(data.icon) unless data.icon.empty?
  if data.slot
    rec = instance_eval(data.receiver)
    connect action, SIGNAL(data.signal), rec, SLOT(data.slot)
  end
  state = data.state
  if state
    Ruber[:main_window].register_action_handler action, state, :extra_id => self
  end
  action
end

- (nil) setup_actions(coll) (private)

Creates the actions provided by the plugin

Once created, the actions are stored in the KDE::ActionCollection given as argument. If any UI handler is provided for an action in the PSF, it’s registered with the main window. If the PSF entry for an acton contains a :slot, a :receiver and a :signal entry, a signal-slot connection is made using those parameters.

Parameters:

  • the (KDE::ActionCollection)

    action collection to add the new actions to

Returns:

  • (nil)

See Also:



450
451
452
453
454
455
456
# File 'lib/ruber/plugin_like.rb', line 450

def setup_actions coll
  @plugin_description.actions.each_value do |a|
      action = setup_action a, coll
      coll.add_action a.name, action
  end
  nil
end

- (nil) shutdown

Does the required cleanup before the application closes.

This method is also called when the plugin is unloaded when the application is running (for example because the user deselects it from the Choose Plugin dialog). This happens because usually the #unload method needs to do all #shutdown does and more. In the rare eventuality you need to do something before closing the application which shouldn’t be done when unloading the plugin, you can check Application#status and see whether it’s set to :running, which means the plugin is being unloaded, or to :quitting, which means the application is being closed.

The base class version of this method does nothing.

Returns:

  • (nil)


65
66
# File 'lib/ruber/plugin_like.rb', line 65

def shutdown
end

- (nil) unload

Method called before the plugin is unloaded. It is used to do any needed cleanup.

This method should be overridden by any plugin which needs to do custom cleanup, but it’s important that the base class’s version of the method is called as well (most likely after the custom part).

This basic implementation does the following:

  • calls #shutdown
  • disconnects the #load_settings slot from the config manager Config#settings_changed signal
  • removes all the options belonging to the plugin from the config manager
  • removes all tool widgets belonging to the plugin from the main window

Returns:

  • (nil)


83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/ruber/plugin_like.rb', line 83

def unload
  shutdown
  if Ruber[:config]
    disconnect Ruber[:config], SIGNAL('settings_changed()'), self, SLOT('load_settings()')
    @plugin_description.config_options.each_key do |g, n| 
      Ruber[:config].remove_option(g.to_sym, n)
    end
  end
  @plugin_description.tool_widgets.each do |w| 
    Ruber[:main_window].remove_tool w.name if w.name
  end
  nil
end

- (nil) update_project(prj)

Ensures that all the project options, widgets and extensions which are provided by the plugin and match the project have been added to it and that none which doesn’t match it have been added

This method is called when one of the characteristics of the project the rules take into account change, so that the plugin always add to the project all the pertinent content

Parameters:

Returns:

  • (nil)


394
395
396
397
398
399
400
401
# File 'lib/ruber/plugin_like.rb', line 394

def update_project prj
  remove_options_from_project prj, false
  add_options_to_project prj, false
  remove_widgets_from_project prj
  add_widgets_to_project prj
  remove_extensions_from_project prj, false
  add_extensions_to_project prj, false
end