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.
- data/COPYING +339 -0
- data/INSTALL +137 -0
- data/LICENSE +8 -0
- data/bin/ruber +65 -0
- data/data/share/apps/ruber/core_components.yaml +31 -0
- data/data/share/apps/ruber/ruberui.rc +109 -0
- data/data/share/icons/ruber.png +0 -0
- data/data/share/pixmaps/ruby.png +0 -0
- data/icons/ruber-16.png +0 -0
- data/icons/ruber-32.png +0 -0
- data/icons/ruber-48.png +0 -0
- data/icons/ruber-8.png +0 -0
- data/lib/ruber/application/application.rb +288 -0
- data/lib/ruber/application/plugin.yaml +11 -0
- data/lib/ruber/component_manager.rb +899 -0
- data/lib/ruber/config/config.rb +82 -0
- data/lib/ruber/config/plugin.yaml +3 -0
- data/lib/ruber/document_project.rb +209 -0
- data/lib/ruber/documents/document_list.rb +416 -0
- data/lib/ruber/documents/plugin.yaml +4 -0
- data/lib/ruber/editor/document.rb +506 -0
- data/lib/ruber/editor/editor_view.rb +167 -0
- data/lib/ruber/editor/ktexteditor_wrapper.rb +202 -0
- data/lib/ruber/exception_widgets.rb +245 -0
- data/lib/ruber/external_program_plugin.rb +397 -0
- data/lib/ruber/filtered_output_widget.rb +342 -0
- data/lib/ruber/gui_states_handler.rb +231 -0
- data/lib/ruber/kde_config_option_backend.rb +167 -0
- data/lib/ruber/kde_sugar.rb +249 -0
- data/lib/ruber/main_window/choose_plugins_dlg.rb +353 -0
- data/lib/ruber/main_window/main_window.rb +524 -0
- data/lib/ruber/main_window/main_window_actions.rb +537 -0
- data/lib/ruber/main_window/main_window_internal.rb +239 -0
- data/lib/ruber/main_window/open_file_in_project_dlg.rb +212 -0
- data/lib/ruber/main_window/output_color_widget.rb +35 -0
- data/lib/ruber/main_window/plugin.yaml +58 -0
- data/lib/ruber/main_window/save_modified_files_dlg.rb +89 -0
- data/lib/ruber/main_window/status_bar.rb +156 -0
- data/lib/ruber/main_window/ui/choose_plugins_widget.rb +90 -0
- data/lib/ruber/main_window/ui/choose_plugins_widget.ui +77 -0
- data/lib/ruber/main_window/ui/main_window_settings_widget.rb +108 -0
- data/lib/ruber/main_window/ui/main_window_settings_widget.ui +89 -0
- data/lib/ruber/main_window/ui/new_project_widget.rb +119 -0
- data/lib/ruber/main_window/ui/new_project_widget.ui +178 -0
- data/lib/ruber/main_window/ui/open_file_in_project_dlg.rb +109 -0
- data/lib/ruber/main_window/ui/open_file_in_project_dlg.ui +168 -0
- data/lib/ruber/main_window/ui/output_color_widget.rb +241 -0
- data/lib/ruber/main_window/ui/output_color_widget.ui +204 -0
- data/lib/ruber/main_window/workspace.rb +442 -0
- data/lib/ruber/output_widget.rb +1093 -0
- data/lib/ruber/plugin.rb +264 -0
- data/lib/ruber/plugin_like.rb +589 -0
- data/lib/ruber/plugin_specification.rb +106 -0
- data/lib/ruber/plugin_specification_reader.rb +451 -0
- data/lib/ruber/project.rb +493 -0
- data/lib/ruber/project_backend.rb +105 -0
- data/lib/ruber/projects/plugin.yaml +11 -0
- data/lib/ruber/projects/project_files_list.rb +314 -0
- data/lib/ruber/projects/project_files_widget.rb +301 -0
- data/lib/ruber/projects/project_list.rb +314 -0
- data/lib/ruber/projects/ui/project_files_rule_chooser_widget.rb +74 -0
- data/lib/ruber/projects/ui/project_files_rule_chooser_widget.ui +61 -0
- data/lib/ruber/projects/ui/project_files_widget.rb +117 -0
- data/lib/ruber/projects/ui/project_files_widget.ui +123 -0
- data/lib/ruber/qt_sugar.rb +673 -0
- data/lib/ruber/settings_container.rb +515 -0
- data/lib/ruber/settings_dialog.rb +244 -0
- data/lib/ruber/settings_dialog_manager.rb +503 -0
- data/lib/ruber/utils.rb +414 -0
- data/lib/ruber/yaml_option_backend.rb +159 -0
- data/outsider_files +15 -0
- data/plugins/autosave/autosave.rb +404 -0
- data/plugins/autosave/plugin.yaml +16 -0
- data/plugins/autosave/ui/autosave_config_widget.rb +83 -0
- data/plugins/autosave/ui/autosave_config_widget.ui +68 -0
- data/plugins/command/command.png +0 -0
- data/plugins/command/command.rb +74 -0
- data/plugins/command/plugin.yaml +11 -0
- data/plugins/find_in_files/find_in_files.rb +337 -0
- data/plugins/find_in_files/find_in_files_dlg.rb +411 -0
- data/plugins/find_in_files/find_in_files_ui.rc +11 -0
- data/plugins/find_in_files/find_in_files_widgets.rb +485 -0
- data/plugins/find_in_files/plugin.yaml +23 -0
- data/plugins/find_in_files/ui/config_widget.rb +58 -0
- data/plugins/find_in_files/ui/config_widget.ui +41 -0
- data/plugins/find_in_files/ui/find_in_files_widget.rb +260 -0
- data/plugins/find_in_files/ui/find_in_files_widget.ui +324 -0
- data/plugins/project_browser/plugin.yaml +10 -0
- data/plugins/project_browser/project_browser.rb +245 -0
- data/plugins/rake/plugin.yaml +39 -0
- data/plugins/rake/rake.png +0 -0
- data/plugins/rake/rake.rb +567 -0
- data/plugins/rake/rake_extension.rb +153 -0
- data/plugins/rake/rake_widgets.rb +615 -0
- data/plugins/rake/rakeui.rc +27 -0
- data/plugins/rake/ui/add_quick_task_widget.rb +71 -0
- data/plugins/rake/ui/add_quick_task_widget.ui +59 -0
- data/plugins/rake/ui/choose_task_widget.rb +77 -0
- data/plugins/rake/ui/choose_task_widget.ui +72 -0
- data/plugins/rake/ui/config_widget.rb +127 -0
- data/plugins/rake/ui/config_widget.ui +123 -0
- data/plugins/rake/ui/project_widget.rb +217 -0
- data/plugins/rake/ui/project_widget.ui +246 -0
- data/plugins/rspec/plugin.yaml +30 -0
- data/plugins/rspec/rspec.png +0 -0
- data/plugins/rspec/rspec.rb +945 -0
- data/plugins/rspec/rspec.svg +90 -0
- data/plugins/rspec/rspecui.rc +20 -0
- data/plugins/rspec/ruber_rspec_formatter.rb +312 -0
- data/plugins/rspec/ui/rspec_project_widget.rb +170 -0
- data/plugins/rspec/ui/rspec_project_widget.ui +193 -0
- data/plugins/ruby_development/plugin.yaml +27 -0
- data/plugins/ruby_development/ruby_development.png +0 -0
- data/plugins/ruby_development/ruby_development.rb +453 -0
- data/plugins/ruby_development/ruby_developmentui.rc +19 -0
- data/plugins/ruby_development/ui/project_widget.rb +112 -0
- data/plugins/ruby_development/ui/project_widget.ui +108 -0
- data/plugins/ruby_runner/config_widget.rb +116 -0
- data/plugins/ruby_runner/plugin.yaml +26 -0
- data/plugins/ruby_runner/project_widget.rb +62 -0
- data/plugins/ruby_runner/ruby.png +0 -0
- data/plugins/ruby_runner/ruby_interpretersui.rc +26 -0
- data/plugins/ruby_runner/ruby_runner.rb +411 -0
- data/plugins/ruby_runner/ui/config_widget.rb +92 -0
- data/plugins/ruby_runner/ui/config_widget.ui +91 -0
- data/plugins/ruby_runner/ui/project_widget.rb +60 -0
- data/plugins/ruby_runner/ui/project_widget.ui +48 -0
- data/plugins/ruby_runner/ui/ruby_runnner_plugin_option_widget.rb +59 -0
- data/plugins/ruby_runner/ui/ruby_runnner_plugin_option_widget.ui +44 -0
- data/plugins/state/plugin.yaml +28 -0
- data/plugins/state/state.rb +520 -0
- data/plugins/state/ui/config_widget.rb +92 -0
- data/plugins/state/ui/config_widget.ui +89 -0
- data/plugins/syntax_checker/plugin.yaml +18 -0
- data/plugins/syntax_checker/syntax_checker.rb +662 -0
- data/ruber.desktop +10 -0
- data/spec/annotation_model_spec.rb +174 -0
- data/spec/common.rb +119 -0
- data/spec/component_manager_spec.rb +1259 -0
- data/spec/document_list_spec.rb +626 -0
- data/spec/document_project_spec.rb +373 -0
- data/spec/document_spec.rb +779 -0
- data/spec/editor_view_spec.rb +167 -0
- data/spec/external_program_plugin_spec.rb +676 -0
- data/spec/filtered_output_widget_spec.rb +642 -0
- data/spec/gui_states_handler_spec.rb +304 -0
- data/spec/kde_config_option_backend_spec.rb +214 -0
- data/spec/kde_sugar_spec.rb +101 -0
- data/spec/ktexteditor_wrapper_spec.rb +305 -0
- data/spec/output_widget_spec.rb +1703 -0
- data/spec/plugin_spec.rb +1393 -0
- data/spec/plugin_specification_reader_spec.rb +1765 -0
- data/spec/plugin_specification_spec.rb +401 -0
- data/spec/project_backend_spec.rb +172 -0
- data/spec/project_files_list_spec.rb +401 -0
- data/spec/project_list_spec.rb +511 -0
- data/spec/project_spec.rb +990 -0
- data/spec/qt_sugar_spec.rb +328 -0
- data/spec/settings_container_spec.rb +617 -0
- data/spec/settings_dialog_manager_spec.rb +773 -0
- data/spec/settings_dialog_spec.rb +419 -0
- data/spec/state_spec.rb +991 -0
- data/spec/utils_spec.rb +406 -0
- data/spec/workspace_spec.rb +869 -0
- data/spec/yaml_option_backend_spec.rb +246 -0
- metadata +284 -0
|
@@ -0,0 +1,493 @@
|
|
|
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 'yaml'
|
|
23
|
+
|
|
24
|
+
require 'ruber/plugin'
|
|
25
|
+
require 'ruber/settings_container'
|
|
26
|
+
require 'ruber/project_backend'
|
|
27
|
+
|
|
28
|
+
module Ruber
|
|
29
|
+
|
|
30
|
+
=begin rdoc
|
|
31
|
+
|
|
32
|
+
Base class for all projects. It must be sublcassed to be used.
|
|
33
|
+
|
|
34
|
+
It has two main functionalities
|
|
35
|
+
* store configuration options specific to each project (called <i>project options</i>),
|
|
36
|
+
and read/write them to file, allow access to them and provide a way to configure
|
|
37
|
+
them
|
|
38
|
+
* store the projects extensions relative to this projects and allow access to them.
|
|
39
|
+
|
|
40
|
+
Project option management is almost all done by the included SettingsContainer module. The
|
|
41
|
+
backend may be choose by subclasses, with the only restriction that it should provide
|
|
42
|
+
a +file+ method returning the name of the file associated with it.
|
|
43
|
+
|
|
44
|
+
Subclasses must reimplement the +:scope+ method, which should return <tt>:global</tt>
|
|
45
|
+
if the project is a global one (that is a project managed by the +ProjectList+)
|
|
46
|
+
component or <tt>:document</tt> if the project is associated with a single document.
|
|
47
|
+
|
|
48
|
+
A project can be in two states: _active_ and _inactive_, depending on whether the
|
|
49
|
+
user chose it as active project or not. Signals are emitted when the state changes.
|
|
50
|
+
<b>Note:</b> there can be at most one active project at any given time.
|
|
51
|
+
|
|
52
|
+
===Signals
|
|
53
|
+
=====<tt>option_changed(QString, QString)</tt>
|
|
54
|
+
Signal emitted when the value of an option changes. The two parameters are the
|
|
55
|
+
group and the name of the option, converted to strings. You'll have to convert
|
|
56
|
+
them back to symbols if you want to use them to access the option's value
|
|
57
|
+
|
|
58
|
+
=====<tt>closing(QObject*)</tt>
|
|
59
|
+
Signal emitted when the project is about to close The argument is the project itself.
|
|
60
|
+
This is mostly used by project
|
|
61
|
+
extensions which need to do some cleanup. They shouldn't use it to store settings
|
|
62
|
+
or similar, as there's the <tt>save_settings</tt> method for that.
|
|
63
|
+
|
|
64
|
+
=====<tt>saving()</tt>
|
|
65
|
+
Signal emitted just before the project is saved to file. This can be used by
|
|
66
|
+
extensions to write their options to the project.
|
|
67
|
+
=end
|
|
68
|
+
class AbstractProject < Qt::Object
|
|
69
|
+
|
|
70
|
+
=begin rdoc
|
|
71
|
+
Exception raised when a project file contains some errors
|
|
72
|
+
=end
|
|
73
|
+
class InvalidProjectFile < StandardError
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
include SettingsContainer
|
|
77
|
+
|
|
78
|
+
signals 'option_changed(QString, QString)', 'closing(QObject*)', :settings_changed,
|
|
79
|
+
:saving
|
|
80
|
+
|
|
81
|
+
=begin rdoc
|
|
82
|
+
A string containing the name of the project
|
|
83
|
+
=end
|
|
84
|
+
attr_reader :project_name
|
|
85
|
+
|
|
86
|
+
=begin rdoc
|
|
87
|
+
The absolute path of the project file
|
|
88
|
+
=end
|
|
89
|
+
attr_reader :project_file
|
|
90
|
+
|
|
91
|
+
=begin rdoc
|
|
92
|
+
Creates a new Project. _parent_ is the projects parent object (derived from <tt>Qt::Object</tt>);
|
|
93
|
+
_file_ is the name of the project file, which may already
|
|
94
|
+
exist or not, while _name_ is the name of the project. _name_ can only be specified
|
|
95
|
+
if the project file doesn't exist, otherwise +ArgumentError+ will be raised.
|
|
96
|
+
|
|
97
|
+
The project file, if existing, must follow the format described in the documentation for YamlSettingsBackend
|
|
98
|
+
and must contain a <tt>:project_name</tt> entry under the <tt>:general</tt> group,
|
|
99
|
+
otherwise it will be considered invalid. In this case, InvalidProjectFile will be
|
|
100
|
+
raised.
|
|
101
|
+
|
|
102
|
+
The new project asks each component to register itself with it, so that project
|
|
103
|
+
options, project widgets (widgets to be shown in the project's configuration dialog)
|
|
104
|
+
and project extensions are added. It also connects to the <tt>component_loaded</tt>
|
|
105
|
+
and <tt>unloading_component</tt> signals of the component manager. The first allow
|
|
106
|
+
each newly loaded plugin to register itself with the project, while the second allows
|
|
107
|
+
any unloading plugin to unregister itself.
|
|
108
|
+
|
|
109
|
+
When the project is created, it's not active.
|
|
110
|
+
=end
|
|
111
|
+
def initialize parent, backend, name = nil
|
|
112
|
+
super(parent)
|
|
113
|
+
@active = false
|
|
114
|
+
Ruber[:components].named_connect(SIGNAL('component_loaded(QObject*)'), "register_component_with_project #{object_id}"){|c| c.register_with_project self}
|
|
115
|
+
Ruber[:components].named_connect(SIGNAL('unloading_component(QObject*)'), "remove_component_from_project #{object_id}"){|c| c.remove_from_project self}
|
|
116
|
+
@project_file = backend.file
|
|
117
|
+
setup_container backend, project_dir
|
|
118
|
+
@dialog_class = ProjectDialog
|
|
119
|
+
self.dialog_title = 'Configure Project'
|
|
120
|
+
add_option OpenStruct.new(:group => :general, :name => :project_name, :default => nil)
|
|
121
|
+
@project_name = self[:general, :project_name]
|
|
122
|
+
if @project_name and name
|
|
123
|
+
raise ArgumentError, "You can't specify a file name for an already existing project"
|
|
124
|
+
elsif name
|
|
125
|
+
self[:general, :project_name] = name
|
|
126
|
+
@project_name = name
|
|
127
|
+
elsif !@project_name and File.exist? @project_file
|
|
128
|
+
raise InvalidProjectFile, "The project file #{@project_file} isn't invalid because it doesn't contain a project name entry"
|
|
129
|
+
elsif !name and !File.exist? @project_file
|
|
130
|
+
raise InvalidProjectFile, "You need to specify a project name for a new project"
|
|
131
|
+
end
|
|
132
|
+
@project_extensions = {}
|
|
133
|
+
Ruber[:components].each_component{|c| c.register_with_project self}
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
=begin rdoc
|
|
137
|
+
Returns the scope of the project (currently it must be either +:global+ or +document+).
|
|
138
|
+
|
|
139
|
+
This method must be overridden in derived classes, as it only raises +NoMethodError+
|
|
140
|
+
=end
|
|
141
|
+
def scope
|
|
142
|
+
raise NoMethodError, "Undefined method `scope' for #{self}:#{self.class}"
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
=begin rdoc
|
|
146
|
+
Tells whether the project matches the rule specified in the object _obj_. _obj_
|
|
147
|
+
is an object with at least the following methods:
|
|
148
|
+
* +scope+
|
|
149
|
+
* +mimetype+
|
|
150
|
+
* +file_extension+
|
|
151
|
+
|
|
152
|
+
This implementation returns *true* if <tt>obj.scope</tt> includes the value returned
|
|
153
|
+
by <tt>self.scope</tt> (using this method requires subclassing AbstractProject,
|
|
154
|
+
since <tt>AbstractProject#scope</tt> raises an exception). Subclasses may override
|
|
155
|
+
this method to introduce other conditions. However, they'll most likely always
|
|
156
|
+
want to call the base class implementation.
|
|
157
|
+
=end
|
|
158
|
+
def match_rule? obj
|
|
159
|
+
obj.scope.include? self.scope
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
=begin rdoc
|
|
163
|
+
Adds the project extension _ext_ to the project, under the name _name_. If an
|
|
164
|
+
extension is already stored under that name, +ArgumentError+ is raised.
|
|
165
|
+
=end
|
|
166
|
+
def add_extension name, ext
|
|
167
|
+
if @project_extensions[name]
|
|
168
|
+
raise ArgumentError, "An extension called '#{name}' already exists"
|
|
169
|
+
end
|
|
170
|
+
@project_extensions[name] = ext
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
=begin rdoc
|
|
174
|
+
Removes the project extension with name _name_. If an extension with that name
|
|
175
|
+
doesn't exist, nothing is done.
|
|
176
|
+
=end
|
|
177
|
+
def remove_extension name
|
|
178
|
+
ext = @project_extensions[name]
|
|
179
|
+
ext.remove_from_project if ext.respond_to? :remove_from_project
|
|
180
|
+
@project_extensions.delete name
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
=begin rdoc
|
|
184
|
+
Override of SettingsContainer#[]= which after changing the value of the option,
|
|
185
|
+
emits the <tt>option_changed(QString, QString)</tt> message if the value of
|
|
186
|
+
the option changed (according to eql?).
|
|
187
|
+
=end
|
|
188
|
+
def []= group, name, value
|
|
189
|
+
old = @options[[group, name]]
|
|
190
|
+
super
|
|
191
|
+
emit option_changed group.to_s, name.to_s unless old.eql? value
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
=begin rdoc
|
|
195
|
+
Returns the project extension with name _name_.
|
|
196
|
+
=end
|
|
197
|
+
def extension name
|
|
198
|
+
@project_extensions[name]
|
|
199
|
+
end
|
|
200
|
+
alias_method :project_extension, :extension
|
|
201
|
+
|
|
202
|
+
=begin rdoc
|
|
203
|
+
If called with a block, calls it for each extension passing the extension name
|
|
204
|
+
and the extension object itself as argument. If called without a block, returns
|
|
205
|
+
an +Enumerator+ whose +each+ method works as explained above
|
|
206
|
+
=end
|
|
207
|
+
def each_extension
|
|
208
|
+
if block_given?
|
|
209
|
+
@project_extensions.each_pair{|name, ext| yield name, ext}
|
|
210
|
+
else self.to_enum(:each_extension)
|
|
211
|
+
end
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
=begin rdoc
|
|
215
|
+
Returns a hash having the extension names as keys and the extension objects as
|
|
216
|
+
values.
|
|
217
|
+
|
|
218
|
+
<b>Note:</b> modifiying the hash doesn't change the internal list of extensions
|
|
219
|
+
=end
|
|
220
|
+
def extensions
|
|
221
|
+
@project_extensions.dup
|
|
222
|
+
end
|
|
223
|
+
alias_method :project_extensions, :extensions
|
|
224
|
+
|
|
225
|
+
=begin rdoc
|
|
226
|
+
Returns true if the project contains an extension corresponding to the name +:name+
|
|
227
|
+
and false otherwise
|
|
228
|
+
=end
|
|
229
|
+
def has_extension? name
|
|
230
|
+
@project_extensions.has_key? name
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
=begin rdoc
|
|
234
|
+
Returns the absolute path of project directory, that is the directory where the
|
|
235
|
+
project file lies.
|
|
236
|
+
=end
|
|
237
|
+
def project_directory
|
|
238
|
+
File.dirname(@project_file)
|
|
239
|
+
end
|
|
240
|
+
alias_method :project_dir, :project_directory
|
|
241
|
+
|
|
242
|
+
=begin rdoc
|
|
243
|
+
Returns an array containing the name of the files belonging to the project.
|
|
244
|
+
|
|
245
|
+
This method should be reimplemented in derived classes to return the actual list
|
|
246
|
+
of files. The base class's version always returns an empty array.
|
|
247
|
+
=end
|
|
248
|
+
def files
|
|
249
|
+
[]
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
=begin rdoc
|
|
253
|
+
Returns the project extension with name _name_. If a project extension with that
|
|
254
|
+
name doesn't exist, or if _args_ is not empty, +ArgumentError+ is raised.
|
|
255
|
+
=end
|
|
256
|
+
def method_missing name, *args, &blk
|
|
257
|
+
begin super
|
|
258
|
+
rescue NoMethodError, NameError, TypeError, ArgumentError => e
|
|
259
|
+
if e.is_a? ArgumentError
|
|
260
|
+
puts e.message
|
|
261
|
+
puts e.backtrace.join("\n")
|
|
262
|
+
puts "Method name: #{name}"
|
|
263
|
+
puts "Arguments: #{args.empty? ? '[]' : args.join( ', ')}"
|
|
264
|
+
end
|
|
265
|
+
raise ArgumentError, "wrong number of arguments (#{args.size} for 0)" unless args.empty?
|
|
266
|
+
@project_extensions.fetch(name){|k| raise ArgumentError, "No project extension with name #{k}"}
|
|
267
|
+
end
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
|
|
271
|
+
def save
|
|
272
|
+
emit saving
|
|
273
|
+
@project_extensions.each_value{|v| v.save_settings}
|
|
274
|
+
begin
|
|
275
|
+
write
|
|
276
|
+
true
|
|
277
|
+
rescue Exception
|
|
278
|
+
false
|
|
279
|
+
end
|
|
280
|
+
end
|
|
281
|
+
|
|
282
|
+
=begin rdoc
|
|
283
|
+
Override of <tt>SettingsContainer#write</tt> which emits the +settings_changed+ signal after
|
|
284
|
+
writing the settings to file
|
|
285
|
+
=end
|
|
286
|
+
def write
|
|
287
|
+
super
|
|
288
|
+
emit settings_changed
|
|
289
|
+
end
|
|
290
|
+
|
|
291
|
+
=begin rdoc
|
|
292
|
+
Closes the project. This means:
|
|
293
|
+
* calling the +save+ method if _save_ is *true*
|
|
294
|
+
* removing all the project extensions
|
|
295
|
+
* emitting the <tt>closing(QObject*)</tt> signal
|
|
296
|
+
|
|
297
|
+
If _save_ is *true*, returns *false* if an error occurred while saving
|
|
298
|
+
and *true* if no error occurred. If _save_ is *false*, it always
|
|
299
|
+
returns *true*
|
|
300
|
+
=end
|
|
301
|
+
def close save = true
|
|
302
|
+
if save
|
|
303
|
+
return false unless self.save
|
|
304
|
+
end
|
|
305
|
+
emit closing(self)
|
|
306
|
+
@project_extensions.each_key{|k| remove_extension k}
|
|
307
|
+
Ruber[:components].named_disconnect "remove_component_from_project #{object_id}"
|
|
308
|
+
Ruber[:components].named_disconnect "register_component_with_project #{object_id}"
|
|
309
|
+
true
|
|
310
|
+
end
|
|
311
|
+
|
|
312
|
+
def query_close
|
|
313
|
+
@project_extensions.each_value{|v| return false unless v.query_close}
|
|
314
|
+
true
|
|
315
|
+
end
|
|
316
|
+
|
|
317
|
+
end
|
|
318
|
+
|
|
319
|
+
=begin rdoc
|
|
320
|
+
Class representing a global project (one which should be managed by ProjectList).
|
|
321
|
+
|
|
322
|
+
It uses ProjectBackend as backend and includes the Activable module.
|
|
323
|
+
|
|
324
|
+
===Signals
|
|
325
|
+
=====<tt>activated()</tt>
|
|
326
|
+
Signal emitted when the project is activated
|
|
327
|
+
|
|
328
|
+
=====<tt>deactivated()</tt>
|
|
329
|
+
Signal emitted when the project is deactivated
|
|
330
|
+
|
|
331
|
+
===Slots
|
|
332
|
+
* <tt>activate()</tt>
|
|
333
|
+
* <tt>deactivate()</tt>
|
|
334
|
+
=end
|
|
335
|
+
class Project < AbstractProject
|
|
336
|
+
|
|
337
|
+
class InvalidProjectFileName < StandardError
|
|
338
|
+
end
|
|
339
|
+
|
|
340
|
+
include Activable
|
|
341
|
+
|
|
342
|
+
signals :activated, :deactivated
|
|
343
|
+
|
|
344
|
+
slots :activate, :deactivate
|
|
345
|
+
|
|
346
|
+
=begin rdoc
|
|
347
|
+
Creates a new Project. _file_ is the name of the project file, while _name_ is
|
|
348
|
+
the project name. You must specify both arguments if the file _file_ doesn't exist,
|
|
349
|
+
while you must not pass the _name_ parameter if the file _file_ already exists (in
|
|
350
|
+
this case, the project name is written in the project file and there's no need
|
|
351
|
+
to specify it). Note that this method takes care of creating the backend, so you
|
|
352
|
+
don't need to do that yourself (unlike with AbstractProject).
|
|
353
|
+
|
|
354
|
+
If _file_ is a relative path, it's considered relative to the current directory.
|
|
355
|
+
|
|
356
|
+
If the project file _file_ already exists but it's not a valid project file,
|
|
357
|
+
AbstractProject::InvalidProjectFile will be raised.
|
|
358
|
+
=end
|
|
359
|
+
def initialize file, name = nil
|
|
360
|
+
file = File.join(Dir.pwd, file) unless file.start_with? '/'
|
|
361
|
+
back = begin ProjectBackend.new file
|
|
362
|
+
rescue YamlSettingsBackend::InvalidSettingsFile => e
|
|
363
|
+
raise Ruber::AbstractProject::InvalidProjectFile, e.message
|
|
364
|
+
end
|
|
365
|
+
super Ruber[:projects], back, name
|
|
366
|
+
end
|
|
367
|
+
|
|
368
|
+
=begin rdoc
|
|
369
|
+
Override of <tt>AbstractProject#close</tt> which deactivates the project before closing it
|
|
370
|
+
and disposes of it after closing. Aside from this, it works as the base class version.
|
|
371
|
+
=end
|
|
372
|
+
def close save = true
|
|
373
|
+
deactivate
|
|
374
|
+
res = super
|
|
375
|
+
dispose
|
|
376
|
+
res
|
|
377
|
+
end
|
|
378
|
+
|
|
379
|
+
=begin rdoc
|
|
380
|
+
Reimplementation of <tt>AbstractProject#scope</tt> which returns +:global+
|
|
381
|
+
=end
|
|
382
|
+
def scope
|
|
383
|
+
:global
|
|
384
|
+
end
|
|
385
|
+
|
|
386
|
+
=begin rdoc
|
|
387
|
+
Override of <tt>SettingsContainer#add_option</tt> which sets the type of _opt_
|
|
388
|
+
to +:global+ if <tt>opt.type</tt> returns *nil*.
|
|
389
|
+
|
|
390
|
+
This is necessary because +AbstractProject.new+ adds the +:project_name+ option
|
|
391
|
+
without specifying its type.
|
|
392
|
+
=end
|
|
393
|
+
def add_option opt
|
|
394
|
+
opt.type ||= :global
|
|
395
|
+
super
|
|
396
|
+
end
|
|
397
|
+
|
|
398
|
+
=begin rdoc
|
|
399
|
+
Override of AbstractProject#files which actually returns the list of files belonging
|
|
400
|
+
to the project.
|
|
401
|
+
|
|
402
|
+
<b>Note:</b> this method uses the <tt>project_files</tt> extension
|
|
403
|
+
=end
|
|
404
|
+
def files
|
|
405
|
+
@project_extensions[:project_files].project_files
|
|
406
|
+
end
|
|
407
|
+
|
|
408
|
+
end
|
|
409
|
+
|
|
410
|
+
=begin rdoc
|
|
411
|
+
Subclass of SettingsDialog which differs from it only in that it overrides the
|
|
412
|
+
<tt>widget_from_class</tt> method.
|
|
413
|
+
|
|
414
|
+
<bb>Note:</bb> since the overridden <tt>widget_from_class</tt> method passes
|
|
415
|
+
the project as argument to the widget's class <tt>#new</tt> method, the widget's
|
|
416
|
+
constructor must explicitly pass *nil* to the superclass method as parent. To
|
|
417
|
+
avoid any issues, you can derive your widget from ProjectConfigWidget
|
|
418
|
+
rather than from <tt>Qt::Widget</tt>. If, for some reason, you can't do that (for
|
|
419
|
+
example because you need to derive from another specialized widget), your widget
|
|
420
|
+
constructor must do something like this (assuming that the base class's construcor
|
|
421
|
+
take the same argument as Qt::Widget's):
|
|
422
|
+
|
|
423
|
+
class MyWidget < SomeWidget
|
|
424
|
+
|
|
425
|
+
def initialize prj
|
|
426
|
+
super()
|
|
427
|
+
# do (if you want) something with prj
|
|
428
|
+
end
|
|
429
|
+
|
|
430
|
+
end
|
|
431
|
+
=end
|
|
432
|
+
class ProjectDialog < SettingsDialog
|
|
433
|
+
|
|
434
|
+
private
|
|
435
|
+
|
|
436
|
+
=begin rdoc
|
|
437
|
+
Override of SettingsDialog#widget_from_class which passes the project as argument
|
|
438
|
+
to the class's +#new+ method.
|
|
439
|
+
=end
|
|
440
|
+
def widget_from_class cls
|
|
441
|
+
cls.new @container
|
|
442
|
+
end
|
|
443
|
+
|
|
444
|
+
end
|
|
445
|
+
|
|
446
|
+
=begin rdoc
|
|
447
|
+
Small class which can be used instead of <tt>Qt::Widget</tt> for widgets to be
|
|
448
|
+
used in the configuration dialog.
|
|
449
|
+
|
|
450
|
+
The only difference between this class and <tt>Qt::Widget</tt> is in the arguments
|
|
451
|
+
taken by the constructor: instead of taking the parent (which is instead set to
|
|
452
|
+
*nil*), this class accepts the project the dialog refers to and stores it in
|
|
453
|
+
its +project+ attribute.
|
|
454
|
+
=end
|
|
455
|
+
class ProjectConfigWidget < Qt::Widget
|
|
456
|
+
|
|
457
|
+
=begin rdoc
|
|
458
|
+
The project associated with the dialog containing the widget
|
|
459
|
+
=end
|
|
460
|
+
attr_reader :project
|
|
461
|
+
|
|
462
|
+
=begin rdoc
|
|
463
|
+
Creates a new instance. _project_ is the Project associated with the dialog the
|
|
464
|
+
widget will be put into.
|
|
465
|
+
=end
|
|
466
|
+
def initialize project
|
|
467
|
+
super()
|
|
468
|
+
@project = project
|
|
469
|
+
end
|
|
470
|
+
|
|
471
|
+
end
|
|
472
|
+
|
|
473
|
+
|
|
474
|
+
module Extension
|
|
475
|
+
|
|
476
|
+
attr_accessor :plugin
|
|
477
|
+
|
|
478
|
+
def save_settings
|
|
479
|
+
end
|
|
480
|
+
|
|
481
|
+
def shutdown
|
|
482
|
+
end
|
|
483
|
+
|
|
484
|
+
def remove_from_project
|
|
485
|
+
end
|
|
486
|
+
|
|
487
|
+
def query_close
|
|
488
|
+
true
|
|
489
|
+
end
|
|
490
|
+
|
|
491
|
+
end
|
|
492
|
+
|
|
493
|
+
end
|