ruber 0.0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (166) hide show
  1. data/COPYING +339 -0
  2. data/INSTALL +137 -0
  3. data/LICENSE +8 -0
  4. data/bin/ruber +65 -0
  5. data/data/share/apps/ruber/core_components.yaml +31 -0
  6. data/data/share/apps/ruber/ruberui.rc +109 -0
  7. data/data/share/icons/ruber.png +0 -0
  8. data/data/share/pixmaps/ruby.png +0 -0
  9. data/icons/ruber-16.png +0 -0
  10. data/icons/ruber-32.png +0 -0
  11. data/icons/ruber-48.png +0 -0
  12. data/icons/ruber-8.png +0 -0
  13. data/lib/ruber/application/application.rb +288 -0
  14. data/lib/ruber/application/plugin.yaml +11 -0
  15. data/lib/ruber/component_manager.rb +899 -0
  16. data/lib/ruber/config/config.rb +82 -0
  17. data/lib/ruber/config/plugin.yaml +3 -0
  18. data/lib/ruber/document_project.rb +209 -0
  19. data/lib/ruber/documents/document_list.rb +416 -0
  20. data/lib/ruber/documents/plugin.yaml +4 -0
  21. data/lib/ruber/editor/document.rb +506 -0
  22. data/lib/ruber/editor/editor_view.rb +167 -0
  23. data/lib/ruber/editor/ktexteditor_wrapper.rb +202 -0
  24. data/lib/ruber/exception_widgets.rb +245 -0
  25. data/lib/ruber/external_program_plugin.rb +397 -0
  26. data/lib/ruber/filtered_output_widget.rb +342 -0
  27. data/lib/ruber/gui_states_handler.rb +231 -0
  28. data/lib/ruber/kde_config_option_backend.rb +167 -0
  29. data/lib/ruber/kde_sugar.rb +249 -0
  30. data/lib/ruber/main_window/choose_plugins_dlg.rb +353 -0
  31. data/lib/ruber/main_window/main_window.rb +524 -0
  32. data/lib/ruber/main_window/main_window_actions.rb +537 -0
  33. data/lib/ruber/main_window/main_window_internal.rb +239 -0
  34. data/lib/ruber/main_window/open_file_in_project_dlg.rb +212 -0
  35. data/lib/ruber/main_window/output_color_widget.rb +35 -0
  36. data/lib/ruber/main_window/plugin.yaml +58 -0
  37. data/lib/ruber/main_window/save_modified_files_dlg.rb +89 -0
  38. data/lib/ruber/main_window/status_bar.rb +156 -0
  39. data/lib/ruber/main_window/ui/choose_plugins_widget.rb +90 -0
  40. data/lib/ruber/main_window/ui/choose_plugins_widget.ui +77 -0
  41. data/lib/ruber/main_window/ui/main_window_settings_widget.rb +108 -0
  42. data/lib/ruber/main_window/ui/main_window_settings_widget.ui +89 -0
  43. data/lib/ruber/main_window/ui/new_project_widget.rb +119 -0
  44. data/lib/ruber/main_window/ui/new_project_widget.ui +178 -0
  45. data/lib/ruber/main_window/ui/open_file_in_project_dlg.rb +109 -0
  46. data/lib/ruber/main_window/ui/open_file_in_project_dlg.ui +168 -0
  47. data/lib/ruber/main_window/ui/output_color_widget.rb +241 -0
  48. data/lib/ruber/main_window/ui/output_color_widget.ui +204 -0
  49. data/lib/ruber/main_window/workspace.rb +442 -0
  50. data/lib/ruber/output_widget.rb +1093 -0
  51. data/lib/ruber/plugin.rb +264 -0
  52. data/lib/ruber/plugin_like.rb +589 -0
  53. data/lib/ruber/plugin_specification.rb +106 -0
  54. data/lib/ruber/plugin_specification_reader.rb +451 -0
  55. data/lib/ruber/project.rb +493 -0
  56. data/lib/ruber/project_backend.rb +105 -0
  57. data/lib/ruber/projects/plugin.yaml +11 -0
  58. data/lib/ruber/projects/project_files_list.rb +314 -0
  59. data/lib/ruber/projects/project_files_widget.rb +301 -0
  60. data/lib/ruber/projects/project_list.rb +314 -0
  61. data/lib/ruber/projects/ui/project_files_rule_chooser_widget.rb +74 -0
  62. data/lib/ruber/projects/ui/project_files_rule_chooser_widget.ui +61 -0
  63. data/lib/ruber/projects/ui/project_files_widget.rb +117 -0
  64. data/lib/ruber/projects/ui/project_files_widget.ui +123 -0
  65. data/lib/ruber/qt_sugar.rb +673 -0
  66. data/lib/ruber/settings_container.rb +515 -0
  67. data/lib/ruber/settings_dialog.rb +244 -0
  68. data/lib/ruber/settings_dialog_manager.rb +503 -0
  69. data/lib/ruber/utils.rb +414 -0
  70. data/lib/ruber/yaml_option_backend.rb +159 -0
  71. data/outsider_files +15 -0
  72. data/plugins/autosave/autosave.rb +404 -0
  73. data/plugins/autosave/plugin.yaml +16 -0
  74. data/plugins/autosave/ui/autosave_config_widget.rb +83 -0
  75. data/plugins/autosave/ui/autosave_config_widget.ui +68 -0
  76. data/plugins/command/command.png +0 -0
  77. data/plugins/command/command.rb +74 -0
  78. data/plugins/command/plugin.yaml +11 -0
  79. data/plugins/find_in_files/find_in_files.rb +337 -0
  80. data/plugins/find_in_files/find_in_files_dlg.rb +411 -0
  81. data/plugins/find_in_files/find_in_files_ui.rc +11 -0
  82. data/plugins/find_in_files/find_in_files_widgets.rb +485 -0
  83. data/plugins/find_in_files/plugin.yaml +23 -0
  84. data/plugins/find_in_files/ui/config_widget.rb +58 -0
  85. data/plugins/find_in_files/ui/config_widget.ui +41 -0
  86. data/plugins/find_in_files/ui/find_in_files_widget.rb +260 -0
  87. data/plugins/find_in_files/ui/find_in_files_widget.ui +324 -0
  88. data/plugins/project_browser/plugin.yaml +10 -0
  89. data/plugins/project_browser/project_browser.rb +245 -0
  90. data/plugins/rake/plugin.yaml +39 -0
  91. data/plugins/rake/rake.png +0 -0
  92. data/plugins/rake/rake.rb +567 -0
  93. data/plugins/rake/rake_extension.rb +153 -0
  94. data/plugins/rake/rake_widgets.rb +615 -0
  95. data/plugins/rake/rakeui.rc +27 -0
  96. data/plugins/rake/ui/add_quick_task_widget.rb +71 -0
  97. data/plugins/rake/ui/add_quick_task_widget.ui +59 -0
  98. data/plugins/rake/ui/choose_task_widget.rb +77 -0
  99. data/plugins/rake/ui/choose_task_widget.ui +72 -0
  100. data/plugins/rake/ui/config_widget.rb +127 -0
  101. data/plugins/rake/ui/config_widget.ui +123 -0
  102. data/plugins/rake/ui/project_widget.rb +217 -0
  103. data/plugins/rake/ui/project_widget.ui +246 -0
  104. data/plugins/rspec/plugin.yaml +30 -0
  105. data/plugins/rspec/rspec.png +0 -0
  106. data/plugins/rspec/rspec.rb +945 -0
  107. data/plugins/rspec/rspec.svg +90 -0
  108. data/plugins/rspec/rspecui.rc +20 -0
  109. data/plugins/rspec/ruber_rspec_formatter.rb +312 -0
  110. data/plugins/rspec/ui/rspec_project_widget.rb +170 -0
  111. data/plugins/rspec/ui/rspec_project_widget.ui +193 -0
  112. data/plugins/ruby_development/plugin.yaml +27 -0
  113. data/plugins/ruby_development/ruby_development.png +0 -0
  114. data/plugins/ruby_development/ruby_development.rb +453 -0
  115. data/plugins/ruby_development/ruby_developmentui.rc +19 -0
  116. data/plugins/ruby_development/ui/project_widget.rb +112 -0
  117. data/plugins/ruby_development/ui/project_widget.ui +108 -0
  118. data/plugins/ruby_runner/config_widget.rb +116 -0
  119. data/plugins/ruby_runner/plugin.yaml +26 -0
  120. data/plugins/ruby_runner/project_widget.rb +62 -0
  121. data/plugins/ruby_runner/ruby.png +0 -0
  122. data/plugins/ruby_runner/ruby_interpretersui.rc +26 -0
  123. data/plugins/ruby_runner/ruby_runner.rb +411 -0
  124. data/plugins/ruby_runner/ui/config_widget.rb +92 -0
  125. data/plugins/ruby_runner/ui/config_widget.ui +91 -0
  126. data/plugins/ruby_runner/ui/project_widget.rb +60 -0
  127. data/plugins/ruby_runner/ui/project_widget.ui +48 -0
  128. data/plugins/ruby_runner/ui/ruby_runnner_plugin_option_widget.rb +59 -0
  129. data/plugins/ruby_runner/ui/ruby_runnner_plugin_option_widget.ui +44 -0
  130. data/plugins/state/plugin.yaml +28 -0
  131. data/plugins/state/state.rb +520 -0
  132. data/plugins/state/ui/config_widget.rb +92 -0
  133. data/plugins/state/ui/config_widget.ui +89 -0
  134. data/plugins/syntax_checker/plugin.yaml +18 -0
  135. data/plugins/syntax_checker/syntax_checker.rb +662 -0
  136. data/ruber.desktop +10 -0
  137. data/spec/annotation_model_spec.rb +174 -0
  138. data/spec/common.rb +119 -0
  139. data/spec/component_manager_spec.rb +1259 -0
  140. data/spec/document_list_spec.rb +626 -0
  141. data/spec/document_project_spec.rb +373 -0
  142. data/spec/document_spec.rb +779 -0
  143. data/spec/editor_view_spec.rb +167 -0
  144. data/spec/external_program_plugin_spec.rb +676 -0
  145. data/spec/filtered_output_widget_spec.rb +642 -0
  146. data/spec/gui_states_handler_spec.rb +304 -0
  147. data/spec/kde_config_option_backend_spec.rb +214 -0
  148. data/spec/kde_sugar_spec.rb +101 -0
  149. data/spec/ktexteditor_wrapper_spec.rb +305 -0
  150. data/spec/output_widget_spec.rb +1703 -0
  151. data/spec/plugin_spec.rb +1393 -0
  152. data/spec/plugin_specification_reader_spec.rb +1765 -0
  153. data/spec/plugin_specification_spec.rb +401 -0
  154. data/spec/project_backend_spec.rb +172 -0
  155. data/spec/project_files_list_spec.rb +401 -0
  156. data/spec/project_list_spec.rb +511 -0
  157. data/spec/project_spec.rb +990 -0
  158. data/spec/qt_sugar_spec.rb +328 -0
  159. data/spec/settings_container_spec.rb +617 -0
  160. data/spec/settings_dialog_manager_spec.rb +773 -0
  161. data/spec/settings_dialog_spec.rb +419 -0
  162. data/spec/state_spec.rb +991 -0
  163. data/spec/utils_spec.rb +406 -0
  164. data/spec/workspace_spec.rb +869 -0
  165. data/spec/yaml_option_backend_spec.rb +246 -0
  166. metadata +284 -0
@@ -0,0 +1,515 @@
1
+ =begin
2
+ Copyright (C) 2010 by Stefano Crocco
3
+ stefano.crocco@alice.it
4
+
5
+ This program is free software; you can redistribute it andor modify
6
+ it under the terms of the GNU General Public License as published by
7
+ the Free Software Foundation; either version 2 of the License, or
8
+ (at your option) any later version.
9
+
10
+ This program is distributed in the hope that it will be useful,
11
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ GNU General Public License for more details.
14
+
15
+ You should have received a copy of the GNU General Public License
16
+ along with this program; if not, write to the
17
+ Free Software Foundation, Inc.,
18
+ 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19
+ =end
20
+
21
+ require 'pathname'
22
+ require 'facets/basicobject'
23
+
24
+ require 'ruber/settings_dialog'
25
+
26
+ module Ruber
27
+
28
+ =begin rdoc
29
+ Module which allows including classes to store and retrieve settings and provides
30
+ an interface (but not the implentation, which is a backend's job) to write the
31
+ settings to a file. It's
32
+ a part of the <a href="../file.settings_framework.html">Ruber Settings Framework</a>
33
+
34
+ Settings are divided into groups, and each settings has a name, so any of them
35
+ can be accessed using the @[group, name]@ pair. Each group can contain multiple
36
+ settings, obviously all with different names (of course, you can have settings
37
+ with the same name in different groups).
38
+
39
+ To read or write a setting, you must first add it, using the {#add_setting} method.
40
+ This method takes what we call a _settings object_, that is an object describing
41
+ a setting. Among other things, a setting object provides information about the name
42
+ of the setting, the group it belongs to and the default value, that is the value
43
+ to use for the setting if the user hasn't changed it.
44
+
45
+ The user can change the value of the settings added to a container using the dialog
46
+ returned by the {#dialog} method. This dialog is a sublcass of @KDE::PageDialog@,
47
+ to which plugins can add the widgets needed to change their settings (see {#add_widget}).
48
+ The dialog is only created when the {#dialog} method is called and is destroyed
49
+ every time a widget is added or removed to it.
50
+
51
+ This module knows nothing about the way the data is stored to file, so it needs
52
+ a backend to do the reading/writing. Refer to
53
+ "the ruber settings framework documentation":../file.settings_framework.html#backends
54
+ for the interface a backend class must provide.
55
+
56
+ *Notes:*
57
+ * classes mixing-in this module *must* call {#setup_container} before using the
58
+ functionality it provides. Usually, this can be done from the class's @initialize@
59
+ method
60
+ * the values of the options in the backend aren't updated when they are changed
61
+ using the []= method, but only when the {#write} method is called.
62
+ * if you want to store a value of a custom class in a settings file, make sure
63
+ you require the file the class is defined in before _creating_ the instance of
64
+ @SettingsContainer@ associated with the configuration file (not before accessing
65
+ it). This is because some backends (for example the YAML backend) create all the
66
+ objects stored in it on creation
67
+
68
+
69
+ h3. Instance variables
70
+
71
+ There are some instance variables which classes mixing-in this module may set
72
+ to tune the behaviour of the module. They are:
73
+ * @@base_dir@: this variable can be set to a path to use as base for settings
74
+ representing a relative path. For example, if this variable is set to @/home/myhome/@,
75
+ a setting with value @/home/myhome/somefile@ will be stored simply as @somefile@
76
+ * @@dialog_class@: the class to instantiate to create the dialog. It must be a
77
+ subclass of {Ruber::SettingsDialog}. If this variable isn't set, {Ruber::SettingsDialog}
78
+ will be used.
79
+
80
+ @todo Change all names referring to "option" to use the word "setting" instead
81
+ @todo Replace instance variables used by classes mixing-in this (for example, @dialog_class)
82
+ with method calls which may be overridden
83
+ =end
84
+ module SettingsContainer
85
+
86
+ =begin rdoc
87
+ Utility class to be used to avoid having to repeat the group
88
+ when fetching options from a {SettingsContainer}. When created, it takes a {SettingsContainer}
89
+ and a group name as parameters. To access one option in that group, you can simply
90
+ call the {#[]} and {#[]=} methods specifying the option name (and, in the second case,
91
+ the value). Alternatively, you can use the option names as if they were method
92
+ names (appending an equal sign to store values)
93
+
94
+ Note that you don't usually need to create instances of this class, as {SettingsContainer#[]}
95
+ returns one when called with one argument.
96
+
97
+ @example Without using Proxy:
98
+
99
+ o1 = settings_container[:group1, :o1]
100
+ o2 = settings_container[:group1, :o2]
101
+ o3 = settings_container[:group1, :o3]
102
+ o4 = settings_container[:group1, :o4, :abs]
103
+ settings_container[:group1, :o1] = 1
104
+ settings_container[:group1, :o2] = 2
105
+ settings_container[:group1, :o3] = 3
106
+ settings_container[:group1, :o4] = 4
107
+
108
+ @example Using {Proxy#[]} and {Proxy#[]}:
109
+
110
+ proxy = settings_container[:group1]
111
+ o1 = proxy[:o1]
112
+ o2 = proxy[:o2]
113
+ o3 = proxy[:o3]
114
+ o4 = proxy[:o4, :abs]
115
+ proxy[:o1] = 1
116
+ proxy[:o2] = 2
117
+ proxy[:o3] = 3
118
+ proxy[:o4] = 4
119
+
120
+ @example Using Proxy via {#method_missing}
121
+
122
+ proxy = settings_container[:group1]
123
+ o1 = proxy.o1
124
+ o2 = proxy.o2
125
+ o3 = proxy.o3
126
+ o4 = proxy.o4 :abs
127
+ proxy.o1 = 1
128
+ proxy.o2 = 2
129
+ proxy.o3 = 3
130
+ proxy.o4 = 4
131
+
132
+ =end
133
+ class Proxy < BasicObject
134
+
135
+ =begin rdoc
136
+ @param [SettingsContainer] container the object to create the proxy for
137
+ @param [Symbol] group the group to create the proxy for
138
+ =end
139
+ def initialize container, group
140
+ @container = container
141
+ @group = group
142
+ end
143
+
144
+ =begin rdoc
145
+ Calls the {#[]} method of the associated container.
146
+
147
+ The group passed to the container's {SettingsContainer#[] #[]} method is the one
148
+ associated with the proxy.
149
+ @param [Symbol] option the second argument to {SettingsContainer#[]}
150
+ @param [Symbol,nil] option the third argument to {SettingsContainer#[]}
151
+ @return [Object] whatever {SettingsContainer#[]} returns
152
+ =end
153
+ def [](option, path_opt = nil)
154
+ @container[@group, option, path_opt]
155
+ end
156
+
157
+ =begin rdoc
158
+ Calls the {#[]=} method of the associated container.
159
+
160
+ The group passed to the container's {SettingsContainer#[]= #[]=} method is the one
161
+ associated with the proxy.
162
+ @param [Symbol] option the second argument to {SettingsContainer#[]}
163
+ @param [Object] value the third argument to {SettingsContainer#[]}
164
+ =end
165
+ def []=(option, value)
166
+ @container[@group, option] = value
167
+ end
168
+
169
+ =begin rdoc
170
+ Attempts to read or write an option with the same name as the method
171
+
172
+ If the method name ends with a @=@, it attempts to change the value of a setting
173
+ called as the method in the group associated with the proxy. If the method doesn't
174
+ end with an @=@, it attempts to read the setting
175
+
176
+ The contents of the _args_ array are passed to the called method
177
+ @param [Symbol] meth the name of the method
178
+ @param [Array] args the parameters to pass
179
+ =end
180
+ def method_missing meth, *args
181
+ name = meth.to_s
182
+ if name[-1,1] == '=' then @container.send :[]=, @group, name[0...-1].to_sym, *args
183
+ else @container[@group, meth, *args]
184
+ end
185
+ end
186
+
187
+ end
188
+
189
+ =begin rdoc
190
+ Adds a setting to the container
191
+
192
+ *Note:* this method also deletes the configuration dialog, so a new one will be
193
+ created the next time it's needed
194
+
195
+ @param [Object] the settings object describing the setting to add. It must have the three
196
+ following methods:
197
+ * @name@: takes no arguments and returns a symbol corresponding to the name of the setting
198
+ * @group@: takes no arguments and returns a symbol corresponding to the group the setting belongs to
199
+ * @default@: takes one argument of class @Binding@ and returns the default value
200
+ to use for the setting
201
+
202
+ If the object also has a @relative_path@ method and that method returns *true*,
203
+ then the setting will be treated a a path relative to the base directory
204
+ @raise ArgumentError if an option with the same name nad belonging to the same group
205
+ already exists
206
+ @return [nil]
207
+ =end
208
+ def add_setting opt
209
+ full_name = [opt.group, opt.name]
210
+ if @known_options[full_name]
211
+ raise ArgumentError, "An option with name #{opt.name} belonging to group #{opt.group} already exists"
212
+ end
213
+ @known_options[full_name] = opt
214
+ @options[full_name] = @backend[opt]
215
+ delete_dialog
216
+ nil
217
+ end
218
+ alias add_option add_setting
219
+
220
+ =begin rdoc
221
+ Removes a setting
222
+
223
+ *Note:* this method also deletes the configuration dialog, so a new one will be
224
+ created the next time it's needed
225
+
226
+ @overload remove_setting group, name
227
+ @param [Symbol] group the group the setting belongs to
228
+ @param [Symbol] name the name of the setting to remove
229
+ @return [nil]
230
+
231
+ @overload remove_setting obj
232
+ @param [Object] see {#add_setting}
233
+ @return [nil]
234
+ =end
235
+ def remove_setting *args
236
+ group, name = if args.size == 1 then [args[0].group, args[0].name]
237
+ else args
238
+ end
239
+ @known_options.delete [group, name]
240
+ @options.delete [group, name]
241
+ delete_dialog
242
+ end
243
+ alias remove_option remove_setting
244
+
245
+ =begin rdoc
246
+ Whether a given setting has been added to the container
247
+ @param [Symbol] group the name the setting belongs to
248
+ @param [Symbol] name the name of the setting
249
+ @return [Boolean] *true* if the setting had already been added and *false* otherwise
250
+ =end
251
+ def has_setting? group, name
252
+ !@known_options[[group, name]].nil?
253
+ end
254
+ alias has_option? has_setting?
255
+
256
+ =begin rdoc
257
+ Returns the value of a setting
258
+ @overload [] group
259
+ Returns a {Proxy} object associated with a group
260
+ @param [Symbol] group the name of the group
261
+ @return [SettingsContainer::Proxy]
262
+
263
+ @overload [] group, name
264
+ @param [Symbol] group the group the setting belongs to
265
+ @param [Symbol] name the name of the setting
266
+ @return [Object] the value of the setting. If it has never been set, the default
267
+ value is returned
268
+
269
+ @overload [] group, name, mode
270
+ @param [Symbol] group the group the setting belongs to
271
+ @param [Symbol] name the name of the setting
272
+ @param [Symbol] mode if either @:abs@ or @absolute@, and if the setting is a @string@
273
+ or a @Pathname@, it is considered as a path relative to the base directory. The
274
+ absolute path, obtained by joining the base directory with the value of the setting
275
+ is then returned
276
+ @return [Object] the value of the setting. If it has never been set, the default
277
+ value is returned
278
+
279
+ @raise IndexError if an option corresponding to the given group and name hasn't
280
+ been added, except in the case of one argument, where the {Proxy} object is always
281
+ returned
282
+ =end
283
+ def [](*args)
284
+ group, name, path_opt = args
285
+ return Proxy.new self, group unless name
286
+ res = @options.fetch([group, name]) do
287
+ raise IndexError, "An option called #{name} belonging to group #{group} doesn't exist"
288
+ end
289
+ if @base_directory and (path_opt == :abs or path_opt == :absolute)
290
+ # The call to File.expand_path is used to avoid returning names as /base/dir/.
291
+ # if the value of the options were .
292
+ if res.is_a? String
293
+ res = File.expand_path(File.join(@base_directory, res))
294
+ elsif res.is_a? Pathname
295
+ res = (Pathname.new(@base_directory) + res).cleanpath
296
+ end
297
+ end
298
+ res
299
+ end
300
+
301
+ =begin rdoc
302
+ Changes the value of a setting
303
+
304
+ If the new value is a string containing an absolute path, the corresponding
305
+ setting object has a @relative_path@ method which returns *true* and the base directory
306
+ is not *nil*, the string will be trasformed into a path relative to the base directory
307
+ before being stored.
308
+
309
+ @param [Symbol] group the group the setting belongs to
310
+ @param [Symbol] name the name of the setting
311
+ @param [Object] value the new value of the setting
312
+ @raise {IndexError} if a setting with the given name and group haven't been added
313
+ to the object
314
+ @return [Object] _value_
315
+ =end
316
+ def []=(group, name, value)
317
+ full_name = [group, name]
318
+ opt = @known_options.fetch(full_name) do
319
+ raise IndexError, "No option called #{name} and belonging to group #{group} exists"
320
+ end
321
+ if value.is_a? String and (opt.relative_path rescue false) and @base_directory
322
+ path = Pathname.new value
323
+ dir = Pathname.new @base_directory
324
+ value = path.relative_path_from( dir).to_s rescue value
325
+ end
326
+ @options[full_name] = value
327
+ end
328
+
329
+ =begin rdoc
330
+ The default value for a given setting
331
+
332
+ @param [Sybmol] group the group the setting belongs to
333
+ @param [String] the name of the setting
334
+ @return [Object] the default value for the setting, without taking into account
335
+ the value returned by the @relative_path@ method of the setting object
336
+ (if it exists)
337
+ @raise @IndexError@ if a setting with the given name and group hasn't been added
338
+ =end
339
+ def default group, name
340
+ opt = @known_options.fetch([group, name]) do
341
+ raise IndexError, "No option called #{name} and belonging to group #{group} exists"
342
+ end
343
+ opt.default
344
+ end
345
+
346
+ =begin rdoc
347
+ Whether a setting should be considered a relative path or not
348
+
349
+ @param [Sybmol] group the group the setting belongs to
350
+ @param [String] the name of the setting
351
+ @return [Boolean] *true* if the settings object corresponding to _group_ and
352
+ _name_ has a @relative_path@ method and it returns *true* and *false* otherwise
353
+ =end
354
+ def relative_path? group, name
355
+ @known_options[[group, name]].relative_path.to_bool rescue false
356
+ end
357
+
358
+ =begin rdoc
359
+ Instructs the container to add a widget to the associated dialog
360
+
361
+ The widget won't be immediately added to the dialog. This method only gives the
362
+ container information about the widget to insert in the dialog. The widget itself
363
+ will only be created and inserted in the dialog when it will first be shown.
364
+
365
+ This method resets the dialog.
366
+
367
+ @param [Object] w the object describing the widget. It must have the methods documented
368
+ below
369
+ @option w [String] caption the name of the page the widget should be put into. If
370
+ the page doesn't exist in the dialog, it will be added. Otherwise, the widget will
371
+ be added to the one already existing in the page
372
+ @option w [Class] class_obj (nil) the class of the widget to create. The class's
373
+ @initialize@ method must take no parameters. Either this method or the @code@
374
+ method must not be *nil*
375
+ @option w [String] code (nil) a piece of ruby code which, when executed in the
376
+ @TOPLEVEL_BINDING@, will return the widget to add to the dialog. Either this
377
+ method or the @class_obje@ method must not be *nil*. If both are not *nil*, this
378
+ method will have the precedence
379
+ @option w [String] pixmap ('') the path of the pixmap to associate to the page
380
+ @return [nil]
381
+ @see SettingsDialog#initialize
382
+ =end
383
+ def add_widget w
384
+ @widgets << w
385
+ delete_dialog
386
+ nil
387
+ end
388
+
389
+ =begin rdoc
390
+ Removes a widget from the dialog
391
+
392
+ If the dialog doesn't contain the widget, nothing is done. Otherwise, the dialog
393
+ will be deleted
394
+
395
+ @param [Qt::Widget] w the widget to remove
396
+ @return [nil]
397
+ =end
398
+ def remove_widget w
399
+ deleted = @widgets.delete w
400
+ delete_dialog if deleted
401
+ end
402
+
403
+ =begin rdoc
404
+ The dialog associated with the container
405
+
406
+ If a dialog has already been created, it will be returned. Otherwise, another dialog
407
+ will be created and filled with the widgets added to the container
408
+
409
+ The dialog will be an instance of the class stored in the @@dialog_class@ instance
410
+ variable.
411
+ @return [Qt::Dialog] the dialog associated with the container.
412
+ @see #add_widget
413
+ @see SettingsContainer
414
+ =end
415
+ def dialog
416
+ @dialog ||= @dialog_class.new self, @known_options.values, @widgets, @dialog_title
417
+ end
418
+
419
+ =begin rdoc
420
+ Writes the settings to file
421
+
422
+ If you need to modify the content of an option before writing (for example because
423
+ it contains a value which can only be read if a specific plugin has been loaded),
424
+ override this method and change the value of the option, then return the hash.
425
+
426
+ @return [nil]
427
+ =end
428
+ def write
429
+ @backend.write collect_options
430
+ nil
431
+ end
432
+
433
+ private
434
+
435
+ =begin
436
+ @return [String] the title which will be used for the dialog
437
+ =end
438
+ attr_reader :dialog_title
439
+
440
+ =begin rdoc
441
+ Initializes instance variables needed by this module
442
+
443
+ This method must be called
444
+ before any of the instance method provided by the module may be
445
+ used. Usually it's called from the constructor of the including class.
446
+
447
+ @param [Object] backend the backend to use. See "here":../file.settings_framework.html#backends
448
+ for documentation about backends
449
+ @param [String,nil] base_dir the directory all paths settings will be relative
450
+ to. If *nil*, then settings containing absolute paths will be stored as such
451
+ @raise [ArgumentError] if _base_dir_ is a string but doesn't represent a full
452
+ path (that is, it doesn't start with a @/@)
453
+ @return [nil]
454
+ =end
455
+ def setup_container backend, base_dir = nil
456
+ @known_options = {}
457
+ @options = {}
458
+ @backend = backend
459
+ @dialog = nil
460
+ @dialog_title = nil
461
+ @widgets = []
462
+ @dialog_class = SettingsDialog
463
+ if base_dir and !base_dir.match(%r{\A/})
464
+ raise ArgumentError, "The second argument to setup_container should be either an absolute path or nil"
465
+ end
466
+ @base_directory = base_dir
467
+ nil
468
+ end
469
+
470
+ =begin rdoc
471
+ Sets the title of the dialog
472
+
473
+ This method deletes the dialog
474
+
475
+ @param [String] title the new title to give the dialog
476
+ @return [nil]
477
+ =end
478
+ def dialog_title= title
479
+ @dialog_title = title
480
+ delete_dialog
481
+ nil
482
+ end
483
+
484
+ =begin rdoc
485
+ Deletes the dialog
486
+
487
+ After calling this method, a call to {#dialog} will cause a new dialog to be
488
+ craeated. This is used, for example, when adding a new widget to the dialog or
489
+ removing an existing one.
490
+
491
+ If the dialog hadn't already been crated, nothing is done.
492
+ @retrun [nil]
493
+ =end
494
+ def delete_dialog
495
+ if @dialog
496
+ @dialog.delete_later
497
+ @dialog = nil
498
+ end
499
+ end
500
+
501
+ =begin rdoc
502
+ The known settings and their values
503
+
504
+ @return [Hash] a hash having the settings objects added to the container as keys
505
+ and the corresponding values as values
506
+ =end
507
+ def collect_options
508
+ data = {}
509
+ @known_options.each_value{|v| data[v] = @options[[v.group, v.name]]}
510
+ data
511
+ end
512
+
513
+ end
514
+
515
+ end