Module: Ruber::SettingsContainer
- Included in:
- AbstractProject, ConfigManager
- Defined in:
- lib/ruber/settings_container.rb
Overview
Change all names referring to “option” to use the word “setting” instead
Replace instance variables used by classes mixing-in this (for example, @dialog_class)
Module which allows including classes to store and retrieve settings and provides an interface (but not the implentation, which is a backend’s job) to write the settings to a file. It’s a part of the Ruber Settings Framework
Settings are divided into groups, and each settings has a name, so any of them
can be accessed using the [group, name]
pair. Each group can contain multiple
settings, obviously all with different names (of course, you can have settings
with the same name in different groups).
To read or write a setting, you must first add it, using the #add_setting method. This method takes what we call a settings object, that is an object describing a setting. Among other things, a setting object provides information about the name of the setting, the group it belongs to and the default value, that is the value to use for the setting if the user hasn’t changed it.
The user can change the value of the settings added to a container using the dialog
returned by the #dialog method. This dialog is a sublcass of KDE::PageDialog
,
to which plugins can add the widgets needed to change their settings (see #add_widget).
The dialog is only created when the #dialog method is called and is destroyed
every time a widget is added or removed to it.
This module knows nothing about the way the data is stored to file, so it needs a backend to do the reading/writing. Refer to the ruber settings framework documentation for the interface a backend class must provide.
Notes:
- classes mixing-in this module must call #setup_container before using the
functionality it provides. Usually, this can be done from the class’s
initialize
method - the values of the options in the backend aren’t updated when they are changed using the []= method, but only when the #write method is called.
- if you want to store a value of a custom class in a settings file, make sure
you require the file the class is defined in before creating the instance of
SettingsContainer
associated with the configuration file (not before accessing it). This is because some backends (for example the YAML backend) create all the objects stored in it on creation
Instance variables
There are some instance variables which classes mixing-in this module may set to tune the behaviour of the module. They are:
@base_dir
: this variable can be set to a path to use as base for settings representing a relative path. For example, if this variable is set to/home/myhome/
, a setting with value/home/myhome/somefile
will be stored simply assomefile
@dialog_class
: the class to instantiate to create the dialog. It must be a subclass of SettingsDialog. If this variable isn’t set, SettingsDialog will be used.
with method calls which may be overridden
Defined Under Namespace
Classes: Proxy
Instance Attribute Summary (collapse)
-
- (String) dialog_title
private
The title which will be used for the dialog.
Instance Method Summary (collapse)
-
- (Object) [](*args)
Returns the value of a setting been added, except in the case of one argument, where the Proxy object is always returned.
-
- (Object) []=(group, name, value)
Changes the value of a setting.
-
- (nil) add_setting(opt)
(also: #add_option)
Adds a setting to the container.
-
- (nil) add_widget(w)
Instructs the container to add a widget to the associated dialog.
-
- (Hash) collect_options
private
The known settings and their values.
-
- (Object) default(group, name)
The default value for a given setting.
-
- (Object) delete_dialog
private
Deletes the dialog.
-
- (Qt::Dialog) dialog
The dialog associated with the container.
-
- (Boolean) has_setting?(group, name)
(also: #has_option?)
Whether a given setting has been added to the container.
-
- (Boolean) relative_path?(group, name)
Whether a setting should be considered a relative path or not.
-
- (Object) remove_setting(*args)
(also: #remove_option)
Removes a setting.
-
- (nil) remove_widget(w)
Removes a widget from the dialog.
-
- (nil) setup_container(backend, base_dir = nil)
private
Initializes instance variables needed by this module.
-
- (nil) write
Writes the settings to file.
Instance Attribute Details
- (String) dialog_title (private)
The title which will be used for the dialog
438 439 440 |
# File 'lib/ruber/settings_container.rb', line 438 def dialog_title @dialog_title end |
Instance Method Details
- (SettingsContainer::Proxy) [](group) - (Object) [](group, name) - (Object) [](group, name, mode)
Returns the value of a setting been added, except in the case of one argument, where the Proxy object is always returned
283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 |
# File 'lib/ruber/settings_container.rb', line 283 def [](*args) group, name, path_opt = args return Proxy.new self, group unless name res = @options.fetch([group, name]) do raise IndexError, "An option called #{name} belonging to group #{group} doesn't exist" end if @base_directory and (path_opt == :abs or path_opt == :absolute) # The call to File.expand_path is used to avoid returning names as /base/dir/. # if the value of the options were . if res.is_a? String res = File.(File.join(@base_directory, res)) elsif res.is_a? Pathname res = (Pathname.new(@base_directory) + res).cleanpath end end res end |
- (Object) []=(group, name, value)
Changes the value of a setting
If the new value is a string containing an absolute path, the corresponding
setting object has a relative_path
method which returns true and the base directory
is not nil, the string will be trasformed into a path relative to the base directory
before being stored.
to the object
316 317 318 319 320 321 322 323 324 325 326 327 |
# File 'lib/ruber/settings_container.rb', line 316 def []=(group, name, value) full_name = [group, name] opt = @known_options.fetch(full_name) do raise IndexError, "No option called #{name} and belonging to group #{group} exists" end if value.is_a? String and (opt.relative_path rescue false) and @base_directory path = Pathname.new value dir = Pathname.new @base_directory value = path.relative_path_from( dir).to_s rescue value end @options[full_name] = value end |
- (nil) add_setting(opt) Also known as: add_option
Adds a setting to the container
Note: this method also deletes the configuration dialog, so a new one will be created the next time it’s needed
following methods:
name
: takes no arguments and returns a symbol corresponding to the name of the settinggroup
: takes no arguments and returns a symbol corresponding to the group the setting belongs todefault
: takes one argument of classBinding
and returns the default value to use for the setting
If the object also has a relative_path
method and that method returns true,
then the setting will be treated a a path relative to the base directory
already exists
208 209 210 211 212 213 214 215 216 217 |
# File 'lib/ruber/settings_container.rb', line 208 def add_setting opt full_name = [opt.group, opt.name] if @known_options[full_name] raise ArgumentError, "An option with name #{opt.name} belonging to group #{opt.group} already exists" end @known_options[full_name] = opt @options[full_name] = @backend[opt] delete_dialog nil end |
- (nil) add_widget(w)
Instructs the container to add a widget to the associated dialog
The widget won’t be immediately added to the dialog. This method only gives the container information about the widget to insert in the dialog. The widget itself will only be created and inserted in the dialog when it will first be shown.
This method resets the dialog.
below
383 384 385 386 387 |
# File 'lib/ruber/settings_container.rb', line 383 def w @widgets << w delete_dialog nil end |
- (Hash) collect_options (private)
The known settings and their values
and the corresponding values as values
507 508 509 510 511 |
# File 'lib/ruber/settings_container.rb', line 507 def data = {} @known_options.each_value{|v| data[v] = @options[[v.group, v.name]]} data end |
- (Object) default(group, name)
The default value for a given setting
the value returned by the relative_path
method of the setting object
(if it exists)
339 340 341 342 343 344 |
# File 'lib/ruber/settings_container.rb', line 339 def default group, name opt = @known_options.fetch([group, name]) do raise IndexError, "No option called #{name} and belonging to group #{group} exists" end opt.default end |
- (Object) delete_dialog (private)
Deletes the dialog
After calling this method, a call to #dialog will cause a new dialog to be craeated. This is used, for example, when adding a new widget to the dialog or removing an existing one.
If the dialog hadn’t already been crated, nothing is done.
494 495 496 497 498 499 |
# File 'lib/ruber/settings_container.rb', line 494 def delete_dialog if @dialog @dialog.delete_later @dialog = nil end end |
- (Qt::Dialog) dialog
The dialog associated with the container
If a dialog has already been created, it will be returned. Otherwise, another dialog will be created and filled with the widgets added to the container
The dialog will be an instance of the class stored in the @dialog_class
instance
variable.
415 416 417 |
# File 'lib/ruber/settings_container.rb', line 415 def dialog @dialog ||= @dialog_class.new self, @known_options.values, @widgets, @dialog_title end |
- (Boolean) has_setting?(group, name) Also known as: has_option?
Whether a given setting has been added to the container
251 252 253 |
# File 'lib/ruber/settings_container.rb', line 251 def has_setting? group, name !@known_options[[group, name]].nil? end |
- (Boolean) relative_path?(group, name)
Whether a setting should be considered a relative path or not
name has a relative_path
method and it returns true and false otherwise
354 355 356 |
# File 'lib/ruber/settings_container.rb', line 354 def relative_path? group, name @known_options[[group, name]].relative_path.to_bool rescue false end |
- (nil) remove_setting(group, name) - (nil) remove_setting(obj) Also known as: remove_option
Removes a setting
Note: this method also deletes the configuration dialog, so a new one will be created the next time it’s needed
235 236 237 238 239 240 241 242 |
# File 'lib/ruber/settings_container.rb', line 235 def remove_setting *args group, name = if args.size == 1 then [args[0].group, args[0].name] else args end @known_options.delete [group, name] @options.delete [group, name] delete_dialog end |
- (nil) remove_widget(w)
Removes a widget from the dialog
If the dialog doesn’t contain the widget, nothing is done. Otherwise, the dialog will be deleted
398 399 400 401 |
# File 'lib/ruber/settings_container.rb', line 398 def w deleted = @widgets.delete w delete_dialog if deleted end |
- (nil) setup_container(backend, base_dir = nil) (private)
Initializes instance variables needed by this module
This method must be called before any of the instance method provided by the module may be used. Usually it’s called from the constructor of the including class.
for documentation about backends
to. If nil, then settings containing absolute paths will be stored as such
path (that is, it doesn’t start with a /
)
455 456 457 458 459 460 461 462 463 464 465 466 467 468 |
# File 'lib/ruber/settings_container.rb', line 455 def setup_container backend, base_dir = nil @known_options = {} @options = {} @backend = backend @dialog = nil @dialog_title = nil @widgets = [] @dialog_class = SettingsDialog if base_dir and !base_dir.match(%r{\A/}) raise ArgumentError, "The second argument to setup_container should be either an absolute path or nil" end @base_directory = base_dir nil end |
- (nil) write
Writes the settings to file
If you need to modify the content of an option before writing (for example because it contains a value which can only be read if a specific plugin has been loaded), override this method and change the value of the option, then return the hash.
428 429 430 431 |
# File 'lib/ruber/settings_container.rb', line 428 def write @backend.write nil end |