ruber 0.0.8 → 0.0.9
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES +21 -0
- data/data/share/apps/ruber/ruberui.rc +3 -1
- data/lib/ruber/application/application.rb +22 -23
- data/lib/ruber/application/plugin.yaml +7 -2
- data/lib/ruber/{projects → application}/project_files_list.rb +0 -0
- data/lib/ruber/{projects → application}/project_files_widget.rb +0 -0
- data/lib/ruber/application/ui/project_files_rule_chooser_widget.rb +74 -0
- data/lib/ruber/{projects → application}/ui/project_files_rule_chooser_widget.ui +0 -0
- data/lib/ruber/application/ui/project_files_widget.rb +117 -0
- data/lib/ruber/{projects → application}/ui/project_files_widget.ui +0 -0
- data/lib/ruber/component_manager.rb +14 -9
- data/lib/ruber/editor/document.rb +35 -5
- data/lib/ruber/kde_sugar.rb +16 -0
- data/lib/ruber/main_window/choose_plugins_dlg.rb +7 -4
- data/lib/ruber/main_window/main_window.rb +131 -193
- data/lib/ruber/main_window/main_window_actions.rb +157 -58
- data/lib/ruber/main_window/main_window_internal.rb +145 -54
- data/lib/ruber/main_window/open_file_in_project_dlg.rb +4 -4
- data/lib/ruber/main_window/plugin.yaml +3 -6
- data/lib/ruber/main_window/ui/workspace_settings_widget.rb +2 -2
- data/lib/ruber/main_window/workspace.rb +62 -32
- data/lib/ruber/output_widget.rb +20 -16
- data/lib/ruber/pane.rb +11 -5
- data/lib/ruber/project.rb +27 -12
- data/lib/ruber/projects/ui/project_files_rule_chooser_widget.rb +2 -2
- data/lib/ruber/projects/ui/project_files_widget.rb +2 -2
- data/lib/ruber/utils.rb +37 -4
- data/lib/ruber/version.rb +1 -1
- data/lib/ruber/world/document_factory.rb +121 -0
- data/lib/ruber/world/document_list.rb +396 -0
- data/lib/ruber/world/environment.rb +470 -0
- data/lib/ruber/{main_window → world}/hint_solver.rb +1 -1
- data/lib/ruber/world/plugin.yaml +11 -0
- data/lib/ruber/world/project_factory.rb +131 -0
- data/lib/ruber/world/project_list.rb +265 -0
- data/lib/ruber/world/ui/workspace_settings_widget.rb +51 -0
- data/lib/ruber/{main_window → world}/ui/workspace_settings_widget.ui +0 -0
- data/lib/ruber/world/world.rb +307 -0
- data/plugins/auto_end/auto_end.rb +135 -9
- data/plugins/autosave/autosave.rb +4 -4
- data/plugins/find_in_files/find_in_files.rb +5 -5
- data/plugins/find_in_files/find_in_files_widgets.rb +1 -1
- data/plugins/project_browser/project_browser.rb +4 -4
- data/plugins/rake/rake.rb +4 -4
- data/plugins/rake/rake_extension.rb +1 -1
- data/plugins/rspec/rspec.rb +4 -4
- data/plugins/rspec/ruber_rspec_formatter.rb +2 -2
- data/plugins/ruby_development/ruby_development.rb +3 -3
- data/plugins/ruby_runner/ruby_runner.rb +2 -2
- data/plugins/state/plugin.yaml +6 -8
- data/plugins/state/state.rb +201 -391
- data/plugins/state/ui/config_widget.rb +5 -5
- data/plugins/state/ui/config_widget.ui +3 -3
- data/plugins/syntax_checker/syntax_checker.rb +4 -0
- data/spec/annotation_model_spec.rb +1 -1
- data/spec/auto_end_spec.rb +98 -47
- data/spec/component_manager_spec.rb +80 -21
- data/spec/document_factory_spec.rb +115 -0
- data/spec/document_list_spec.rb +560 -450
- data/spec/document_spec.rb +143 -55
- data/spec/editor_view_spec.rb +2 -2
- data/spec/environment_spec.rb +1900 -0
- data/spec/hint_solver_spec.rb +5 -5
- data/spec/kde_sugar_spec.rb +16 -0
- data/spec/output_widget_spec.rb +177 -51
- data/spec/pane_spec.rb +29 -5
- data/spec/plugin_spec.rb +1 -1
- data/spec/project_factory_spec.rb +104 -0
- data/spec/project_list_spec.rb +352 -447
- data/spec/project_spec.rb +34 -33
- data/spec/qt_sugar_spec.rb +2 -2
- data/spec/state_spec.rb +508 -811
- data/spec/utils_spec.rb +149 -98
- data/spec/workspace_spec.rb +120 -9
- data/spec/world_spec.rb +1219 -0
- metadata +23 -14
- data/lib/ruber/documents/document_list.rb +0 -412
- data/lib/ruber/documents/plugin.yaml +0 -4
- data/lib/ruber/main_window/view_manager.rb +0 -431
- data/lib/ruber/projects/plugin.yaml +0 -11
- data/lib/ruber/projects/project_list.rb +0 -314
@@ -1,431 +0,0 @@
|
|
1
|
-
=begin
|
2
|
-
Copyright (C) 2010,2011 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 'ruber/main_window/hint_solver'
|
22
|
-
require 'ruber/pane'
|
23
|
-
|
24
|
-
module Ruber
|
25
|
-
|
26
|
-
class MainWindow
|
27
|
-
|
28
|
-
=begin rdoc
|
29
|
-
Class which manages the views in the tab widget
|
30
|
-
|
31
|
-
It takes care of activating a view when it gets focus, removing a tab when the
|
32
|
-
last view in it is closed, and so on.
|
33
|
-
|
34
|
-
@note this class is only for internal use by {MainWindow}. Its API is likely to
|
35
|
-
change and the whole class may disappear in the future. So, *do not* use it outside
|
36
|
-
of {MainWindow}
|
37
|
-
=end
|
38
|
-
class ViewManager < Qt::Object
|
39
|
-
|
40
|
-
=begin rdoc
|
41
|
-
@return [KDE::PartManager] the part manager which manages the document parts
|
42
|
-
=end
|
43
|
-
attr_reader :part_manager
|
44
|
-
|
45
|
-
=begin rdoc
|
46
|
-
@return [EditorView,nil] the active editor (that is, the editor whose GUI is merged
|
47
|
-
with the main window GUI) or *nil* if no main window exists
|
48
|
-
=end
|
49
|
-
attr_reader :active_editor
|
50
|
-
|
51
|
-
=begin rdoc
|
52
|
-
@return [Array<EditorView>] a list of all the editors in all tabs, in activation
|
53
|
-
order, from more recently activated to less recently activated
|
54
|
-
=end
|
55
|
-
attr_reader :activation_order
|
56
|
-
|
57
|
-
=begin rdoc
|
58
|
-
@return [Boolean] whether to automatically activate an editor when it is created
|
59
|
-
=end
|
60
|
-
attr_accessor :auto_activate_editors
|
61
|
-
|
62
|
-
=begin rdoc
|
63
|
-
Signal emitted whenever an editor is created
|
64
|
-
@param [EditorView] editor the newly created editor
|
65
|
-
=end
|
66
|
-
signals 'view_created(QWidget*)'
|
67
|
-
|
68
|
-
=begin rdoc
|
69
|
-
Signal emitted whenever the active editor changes
|
70
|
-
|
71
|
-
This signal is emitted _after_ the editor has become active
|
72
|
-
@param [EditorView,nil] editor the editor which become active or *nil* if no editor
|
73
|
-
become active
|
74
|
-
=end
|
75
|
-
signals 'active_editor_changed(QWidget*)'
|
76
|
-
|
77
|
-
=begin rdoc
|
78
|
-
@param [KDE::TabWidget] tabs the tab widget used by the main window
|
79
|
-
@param [Ruber::MainWindow] parent the main window
|
80
|
-
=end
|
81
|
-
def initialize tabs, parent
|
82
|
-
super parent
|
83
|
-
@tabs = tabs
|
84
|
-
@focus_editors = []
|
85
|
-
@part_manager = KParts::PartManager.new parent, self
|
86
|
-
@activation_order = []
|
87
|
-
@active_editor = nil
|
88
|
-
@solver = MainWindow::HintSolver.new @tabs, @part_manager, @activation_order
|
89
|
-
@auto_activate_editors = true
|
90
|
-
connect @tabs, SIGNAL('currentChanged(int)'), self, SLOT('current_tab_changed(int)')
|
91
|
-
end
|
92
|
-
|
93
|
-
=begin rdoc
|
94
|
-
Returns an editor associated with the given document, creating it if needed
|
95
|
-
|
96
|
-
It works as {MainWindow#editor_for!}.
|
97
|
-
|
98
|
-
_hints_ may contain the same values as in {MainWindow#editor_for!}. It may also
|
99
|
-
contain another value, @:close_starting_document@
|
100
|
-
@param [Document] doc the document to retrieve an editor for
|
101
|
-
@param hints (see MainWindow#editor_for!)
|
102
|
-
@option hints [Boolean] :close_starting_document (false) if given, specifies that
|
103
|
-
the default document created by ruber at startup exists and it's in the first
|
104
|
-
tab. If a new view is created in a new tab, this document is closed
|
105
|
-
@return [EditorView] the view to use for the document
|
106
|
-
=end
|
107
|
-
def editor_for doc, hints
|
108
|
-
editor = @solver.find_editor doc, hints
|
109
|
-
if !editor and hints[:create_if_needed]
|
110
|
-
editor = create_editor doc
|
111
|
-
if hints[:show]
|
112
|
-
@activation_order << editor
|
113
|
-
view = @solver.place_editor hints
|
114
|
-
if view
|
115
|
-
dir = Qt.const_get hints[:split].to_s.capitalize
|
116
|
-
# tab(view).split view, editor, dir
|
117
|
-
view.parent.split view, editor, dir
|
118
|
-
else
|
119
|
-
if hints[:close_starting_document]
|
120
|
-
if @tabs.count == 1 and @tabs.widget(0).single_view?
|
121
|
-
doc_to_close = @tabs.widget(0).view.document
|
122
|
-
end
|
123
|
-
end
|
124
|
-
add_tab editor, doc.icon, doc.document_name
|
125
|
-
doc_to_close.close if doc_to_close
|
126
|
-
end
|
127
|
-
editor.parent.label = label_for_editor editor
|
128
|
-
end
|
129
|
-
end
|
130
|
-
editor
|
131
|
-
end
|
132
|
-
|
133
|
-
=begin rdoc
|
134
|
-
Makes the given editor active
|
135
|
-
|
136
|
-
Besides merging the editor's GUI with the main window's, this method also deactivates
|
137
|
-
the previously active editor, updates the activation order, activates the document
|
138
|
-
associated with the new active editor, updates the tab where the new editor is
|
139
|
-
and emits the {#active_editor_changed} signal.
|
140
|
-
|
141
|
-
Nothing is done if the given editor was already active
|
142
|
-
@param [EditorView] editor the editor to activate
|
143
|
-
@return [EditorView] the new active editor
|
144
|
-
=end
|
145
|
-
def make_editor_active editor
|
146
|
-
return if editor and @active_editor == editor
|
147
|
-
deactivate_editor @active_editor
|
148
|
-
@active_editor = editor
|
149
|
-
if editor
|
150
|
-
parent.gui_factory.add_client editor.send(:internal)
|
151
|
-
@activation_order.delete editor
|
152
|
-
@activation_order.insert 0, editor
|
153
|
-
editor_tab = tab(editor)
|
154
|
-
tab_idx = @tabs.index_of editor_tab
|
155
|
-
@focus_editors[tab_idx] = editor
|
156
|
-
update_tab editor_tab
|
157
|
-
editor.document.activate
|
158
|
-
end
|
159
|
-
emit active_editor_changed @active_editor
|
160
|
-
@active_editor
|
161
|
-
end
|
162
|
-
|
163
|
-
=begin rdoc
|
164
|
-
Deactivates the given editor
|
165
|
-
|
166
|
-
To deactivate the editor, its GUI is removed from the main window's and the corresponding
|
167
|
-
document is deactivated.
|
168
|
-
|
169
|
-
If the given editor wasn't the active one, nothing is done
|
170
|
-
@param [EditorView] view the editor to deactivate
|
171
|
-
@return [nil]
|
172
|
-
=end
|
173
|
-
def deactivate_editor view
|
174
|
-
return unless @active_editor and view == @active_editor
|
175
|
-
@active_editor.document.deactivate
|
176
|
-
parent.gui_factory.remove_client view.send(:internal)
|
177
|
-
@active_editor = nil
|
178
|
-
nil
|
179
|
-
end
|
180
|
-
|
181
|
-
=begin rdoc
|
182
|
-
Executes a block without automatically activating editors
|
183
|
-
|
184
|
-
Usually, whenever a tab becomes active, one of the editors it contains becomes
|
185
|
-
active. Sometimes, you don't want this to happen (for example, when opening multiple
|
186
|
-
documents in sequence). To do so, do what you need from a block passed to this method.
|
187
|
-
|
188
|
-
After the block has been executed, the last activated method in the current tab
|
189
|
-
becomes active.
|
190
|
-
|
191
|
-
@yield the block to call without automatically activating editors
|
192
|
-
@return [Object] the value returned by the block
|
193
|
-
=end
|
194
|
-
def without_activating
|
195
|
-
begin
|
196
|
-
@auto_activate_editors = false
|
197
|
-
yield
|
198
|
-
ensure
|
199
|
-
@auto_activate_editors = true
|
200
|
-
if @tabs.current_index < 0 then make_editor_active nil
|
201
|
-
else make_editor_active @focus_editors[@tabs.current_index]
|
202
|
-
end
|
203
|
-
end
|
204
|
-
end
|
205
|
-
|
206
|
-
=begin rdoc
|
207
|
-
The toplevel pane corresponding to the given index or widget
|
208
|
-
|
209
|
-
@overload tab idx
|
210
|
-
@param [Integer] idx the index of the tab
|
211
|
-
@return [Pane] the toplevel pane in the tab number _idx_
|
212
|
-
@overload tab editor
|
213
|
-
@param [EditorView] editor the editor to retrieve the pane for
|
214
|
-
@return [Pane,nil] the toplevel pane containing the given editor or *nil* if the
|
215
|
-
view isn't contained in a pane
|
216
|
-
@overload tab pane
|
217
|
-
@param [Pane] pane the pane to retrieve the toplevel pane for
|
218
|
-
@return [Pane, nil] the toplevel pane containing the given pane or *nil* if the
|
219
|
-
pane isn't contained in another pane
|
220
|
-
=end
|
221
|
-
def tab arg
|
222
|
-
if arg.is_a? Integer then @tabs.widget arg
|
223
|
-
else
|
224
|
-
pane = arg.is_a?(Pane) ? arg : arg.parent
|
225
|
-
return unless pane
|
226
|
-
pane = pane.parent_pane while pane.parent_pane
|
227
|
-
pane
|
228
|
-
end
|
229
|
-
end
|
230
|
-
|
231
|
-
=begin rdoc
|
232
|
-
Whether the given view is a focus editor
|
233
|
-
|
234
|
-
@overload focus_editor? editor
|
235
|
-
Whether the given view is the focus editor for any tab
|
236
|
-
@param [EditorView] editor the view to test
|
237
|
-
@return [Boolean] *true* if there's a tab which has _editor_ as focus editor and
|
238
|
-
*false* otherwise
|
239
|
-
@overload focus_editor? editor, tab
|
240
|
-
Whether the given view is the focus editor for the given tab
|
241
|
-
@param [EditorView] editor the view to test
|
242
|
-
@param [Pane,Integer] tab the tab the view must be focus editor for. If a {Pane}
|
243
|
-
it must be the toplevel pane of the tab; if an @Integer@, it must be the index
|
244
|
-
of the pane to test
|
245
|
-
@note this method doesn't test whether _tab_ actually is a toplevel pane
|
246
|
-
@return [Boolean] *true* if _editor_ is the focus widget for _tab_ and
|
247
|
-
*false* otherwise
|
248
|
-
=end
|
249
|
-
def focus_editor? editor, tab = nil
|
250
|
-
if tab
|
251
|
-
tab = @tabs.index_of(tab) unless tab.is_a? Integer
|
252
|
-
@focus_editors[tab] == editor
|
253
|
-
else @focus_editors.any?{|k, v| v == editor}
|
254
|
-
end
|
255
|
-
end
|
256
|
-
|
257
|
-
=begin rdoc
|
258
|
-
The label to use for an editor
|
259
|
-
|
260
|
-
@param [EditorView] ed the editor to return the label for
|
261
|
-
@return [String] the text to show below the given editor
|
262
|
-
=end
|
263
|
-
def label_for_editor ed
|
264
|
-
url = ed.document.url
|
265
|
-
if url.valid? then url.local_file? ? url.path : url.pretty_url
|
266
|
-
else ed.document.document_name
|
267
|
-
end
|
268
|
-
end
|
269
|
-
|
270
|
-
private
|
271
|
-
|
272
|
-
=begin rdoc
|
273
|
-
Creates an editor for a document
|
274
|
-
|
275
|
-
@param [Document] doc the document to create the editor for
|
276
|
-
@return [EditorView] the new editor for the document
|
277
|
-
=end
|
278
|
-
def create_editor doc
|
279
|
-
editor = doc.create_view
|
280
|
-
connect editor, SIGNAL('focus_in(QWidget*)'), self, SLOT('focus_in_view(QWidget*)')
|
281
|
-
connect editor, SIGNAL('closing(QWidget*)'), self, SLOT('view_closing(QWidget*)')
|
282
|
-
editor
|
283
|
-
end
|
284
|
-
|
285
|
-
=begin rdoc
|
286
|
-
Adds a new tab to the tab widget
|
287
|
-
|
288
|
-
The tab is created with a view inserted in it and is assigned an icon an a label
|
289
|
-
@param [EditorView] view the view to insert in the new pane
|
290
|
-
@param [Qt::Icon] icon the icon to associate with the new tab
|
291
|
-
@param [String] label the label to use for the new tab
|
292
|
-
@return [Pane] the pane corresponding to the new tab
|
293
|
-
=end
|
294
|
-
def add_tab view, icon, label
|
295
|
-
new_tab = Pane.new(view)
|
296
|
-
idx = @tabs.add_tab new_tab, icon, label
|
297
|
-
@focus_editors[idx] = view
|
298
|
-
connect new_tab, SIGNAL('closing_last_view(QWidget*)'), self, SLOT('remove_tab(QWidget*)')
|
299
|
-
connect new_tab, SIGNAL('pane_split(QWidget*, QWidget*, QWidget*)'), self, SLOT('update_tab(QWidget*)')
|
300
|
-
connect new_tab, SIGNAL('removing_view(QWidget*, QWidget*)'), self, SLOT('update_tab(QWidget*)')
|
301
|
-
connect new_tab, SIGNAL('view_replaced(QWidget*, QWidget*, QWidget*)'), self, SLOT('update_tab(QWidget*)')
|
302
|
-
new_tab
|
303
|
-
end
|
304
|
-
|
305
|
-
=begin rdoc
|
306
|
-
Removes the tab corresponding to the given toplevel pane
|
307
|
-
|
308
|
-
@param [Pane] pane the toplevel pane whose tab should be removed
|
309
|
-
@return [nil]
|
310
|
-
=end
|
311
|
-
def remove_tab pane
|
312
|
-
idx = @tabs.index_of pane
|
313
|
-
if idx
|
314
|
-
@focus_editors.delete_at idx
|
315
|
-
@tabs.remove_tab idx
|
316
|
-
end
|
317
|
-
nil
|
318
|
-
end
|
319
|
-
slots 'remove_tab(QWidget*)'
|
320
|
-
|
321
|
-
=begin rdoc
|
322
|
-
Slot called whenever a view receives focus
|
323
|
-
|
324
|
-
The views is activated, unless it was already active
|
325
|
-
@param [EditorView] view the view which received focus
|
326
|
-
@return [nil]
|
327
|
-
=end
|
328
|
-
def focus_in_view view
|
329
|
-
if view != @active_editor
|
330
|
-
make_editor_active view
|
331
|
-
end
|
332
|
-
nil
|
333
|
-
end
|
334
|
-
slots 'focus_in_view(QWidget*)'
|
335
|
-
|
336
|
-
=begin rdoc
|
337
|
-
Slot called whenever a view is closed
|
338
|
-
|
339
|
-
It deactivates the view (if it was active), performs some cleanup and gives focus
|
340
|
-
to the editor which had focus before (if any).
|
341
|
-
@param [EditorView] view the view which is being closed
|
342
|
-
@return [nil]
|
343
|
-
=end
|
344
|
-
def view_closing view
|
345
|
-
view_tab = self.tab(view)
|
346
|
-
has_focus = view_tab.is_active_window if view_tab
|
347
|
-
if has_focus
|
348
|
-
views = view_tab.to_a
|
349
|
-
idx = views.index(view)
|
350
|
-
new_view = views[idx-1] || views[idx+1]
|
351
|
-
end
|
352
|
-
@activation_order.delete view
|
353
|
-
disconnect view, SIGNAL('focus_in(QWidget*)'), self, SLOT('focus_in_view(QWidget*)')
|
354
|
-
deactivate_editor view
|
355
|
-
if new_view
|
356
|
-
make_editor_active new_view
|
357
|
-
new_view.set_focus
|
358
|
-
end
|
359
|
-
nil
|
360
|
-
end
|
361
|
-
slots 'view_closing(QWidget*)'
|
362
|
-
|
363
|
-
=begin rdoc
|
364
|
-
Slot called whenever the current tab changes
|
365
|
-
|
366
|
-
Unless called from within a {#without_activating} block, it activates and gives focus
|
367
|
-
to the view in the new current tab which last got focus.
|
368
|
-
|
369
|
-
If called from within a {#without_activating} block, or if there's no current tab,
|
370
|
-
all editors are deactivated
|
371
|
-
@param [Integer] idx the index of the current tab
|
372
|
-
@return [nil]
|
373
|
-
=end
|
374
|
-
def current_tab_changed idx
|
375
|
-
if idx > -1
|
376
|
-
@focus_editors[idx] ||= @tabs.widget(idx).to_a[0]
|
377
|
-
ed = @focus_editors[idx]
|
378
|
-
if @auto_activate_editors then ed.set_focus
|
379
|
-
else make_editor_active nil
|
380
|
-
end
|
381
|
-
else
|
382
|
-
make_editor_active nil
|
383
|
-
end
|
384
|
-
nil
|
385
|
-
end
|
386
|
-
slots 'current_tab_changed(int)'
|
387
|
-
|
388
|
-
=begin rdoc
|
389
|
-
Updates the tab containing the given toplevel pane
|
390
|
-
|
391
|
-
Updating the tab means changing its icon, its label, its tooltip and the label
|
392
|
-
associated with each of the editors it contains
|
393
|
-
@param [Pane] pane the toplevel pane contained in the pane to update
|
394
|
-
@return [nil]
|
395
|
-
=end
|
396
|
-
def update_tab pane
|
397
|
-
idx = @tabs.index_of tab(pane)
|
398
|
-
return if idx < 0
|
399
|
-
doc = @focus_editors[idx].document
|
400
|
-
@tabs.set_tab_text idx, doc.document_name
|
401
|
-
@tabs.set_tab_icon idx, doc.icon
|
402
|
-
pane.each_pane{|pn| pn.label = label_for_editor(pn.view) if pn.single_view?}
|
403
|
-
update_tool_tip idx
|
404
|
-
nil
|
405
|
-
end
|
406
|
-
slots 'update_tab(QWidget*)'
|
407
|
-
|
408
|
-
=begin rdoc
|
409
|
-
Updates the tooltip for the given tab
|
410
|
-
|
411
|
-
A pane's tooltip contains the list of the documents associated with the views in
|
412
|
-
the tab, separated by newlines.
|
413
|
-
|
414
|
-
@param [Integer] idx the index of the tab whose tooltip should be updated
|
415
|
-
@param [Array<EditorView>] ignore a list of views which shouldn't be considered
|
416
|
-
when creating the tool tip. This is necessary because, when a view is closed,
|
417
|
-
this method is called _before_ the view is removed from the pane, so the document
|
418
|
-
associated with it would be included in the tooltip if it weren't specified here
|
419
|
-
@return [nil]
|
420
|
-
=end
|
421
|
-
def update_tool_tip idx, *ignore
|
422
|
-
docs = @tabs.widget(idx).reject{|v| ignore.include? v}.map{|v| v.document.document_name}.uniq
|
423
|
-
@tabs.set_tab_tool_tip idx, docs.join("\n")
|
424
|
-
nil
|
425
|
-
end
|
426
|
-
|
427
|
-
end
|
428
|
-
|
429
|
-
end
|
430
|
-
|
431
|
-
end
|
@@ -1,11 +0,0 @@
|
|
1
|
-
name: projects
|
2
|
-
require: [project_list, project_files_widget, project_files_list]
|
3
|
-
class: Ruber::ProjectList
|
4
|
-
project_options:
|
5
|
-
general:
|
6
|
-
project_files: {default: {:include: [], :exclude: [], :extensions: ["*.rb"]}}
|
7
|
-
open_documents: {default: [], type: session, scope: [global, document]}
|
8
|
-
project_widgets:
|
9
|
-
- {class: Ruber::ProjectFilesWidget, caption: 'General', pixmap: configure}
|
10
|
-
extensions:
|
11
|
-
project_files: {class: ProjectFilesList}
|
@@ -1,314 +0,0 @@
|
|
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 'ruber/project'
|
22
|
-
require 'ruber/plugin_like'
|
23
|
-
|
24
|
-
module Ruber
|
25
|
-
|
26
|
-
=begin rdoc
|
27
|
-
The current project
|
28
|
-
|
29
|
-
@return [Ruber::Project,nil] the current project or *nil* if no project is open
|
30
|
-
=end
|
31
|
-
def self.current_project
|
32
|
-
self[:projects].current_project
|
33
|
-
end
|
34
|
-
|
35
|
-
=begin rdoc
|
36
|
-
List of all open global projects
|
37
|
-
|
38
|
-
It allows to obtain a list of the open projects, to know when a project is
|
39
|
-
closed and keeps trace of which is the current project. The most common usage
|
40
|
-
is the following:
|
41
|
-
* use the {#project} method to retrieve an open project basing on the name of
|
42
|
-
its file, or to open it if it isn't already open, or to create a new project.
|
43
|
-
This will also cause the project to be added to the list of open projects,
|
44
|
-
if needed
|
45
|
-
* use {#current_project=} to set the current project
|
46
|
-
* use one of the methods to iterate or work with one of the projects
|
47
|
-
* close one of the projects with the project's {Project#close close} method, or use the
|
48
|
-
{#close_current_project} method to close the current project.
|
49
|
-
=end
|
50
|
-
class ProjectList < Qt::Object
|
51
|
-
|
52
|
-
include PluginLike
|
53
|
-
|
54
|
-
include Enumerable
|
55
|
-
|
56
|
-
=begin rdoc
|
57
|
-
Signal emitted when the current project changes
|
58
|
-
|
59
|
-
@param [Ruber::Project,nil] prj the new current project, or *nil* if there's no open
|
60
|
-
project
|
61
|
-
=end
|
62
|
-
signals 'current_project_changed(QObject*)'
|
63
|
-
|
64
|
-
=begin rdoc
|
65
|
-
Signal emitted just before a project is closed
|
66
|
-
|
67
|
-
@param [Ruber::Project] prj the project which is being closed
|
68
|
-
=end
|
69
|
-
signals 'closing_project(QObject*)'
|
70
|
-
|
71
|
-
=begin rdoc
|
72
|
-
Signal emitted whenever a project is added
|
73
|
-
|
74
|
-
@param [Ruber::Project] prj the newly added project
|
75
|
-
=end
|
76
|
-
signals 'project_added(QObject*)'
|
77
|
-
|
78
|
-
slots 'add_project(QObject*)', 'close_project(QObject*)', 'load_settings()'
|
79
|
-
|
80
|
-
=begin rdoc
|
81
|
-
@return [Ruber::Project,nil] the current project or *nil* if there's no open project
|
82
|
-
=end
|
83
|
-
attr_reader :current_project
|
84
|
-
alias_method :current, :current_project
|
85
|
-
|
86
|
-
=begin rdoc
|
87
|
-
@param [Ruber::ComponentManager] _manager (unused)
|
88
|
-
@param [Ruber::PluginSpecification] psf the plugin specification object describing
|
89
|
-
the component
|
90
|
-
=end
|
91
|
-
def initialize _manager, psf
|
92
|
-
super Ruber[:app]
|
93
|
-
initialize_plugin psf
|
94
|
-
@current_project = nil
|
95
|
-
@projects = {}
|
96
|
-
end
|
97
|
-
|
98
|
-
=begin rdoc
|
99
|
-
Iterates on all the projects
|
100
|
-
|
101
|
-
In both versions of the method, the order in which the projects are passed to the block is arbitrary
|
102
|
-
|
103
|
-
@overload each_project
|
104
|
-
Passes each open project to the block in turn
|
105
|
-
|
106
|
-
@yield [prj] one of the projects
|
107
|
-
@return [Ruber::ProjectList] *self*
|
108
|
-
@overload each_project
|
109
|
-
@return [Enumerator] an enumerator whose @each@ method yields all the projects
|
110
|
-
in turn
|
111
|
-
=end
|
112
|
-
def each_project &blk #:yields: project
|
113
|
-
res = @projects.each_value &blk
|
114
|
-
res.same?(@projects) ? self : res
|
115
|
-
end
|
116
|
-
alias each each_project
|
117
|
-
|
118
|
-
=begin rdoc
|
119
|
-
The existing projects
|
120
|
-
|
121
|
-
@return [Array<Ruber::Project>] the existing projects. Modifying the array
|
122
|
-
wont affect the @ProjectList@
|
123
|
-
=end
|
124
|
-
def projects
|
125
|
-
@projects.values
|
126
|
-
end
|
127
|
-
|
128
|
-
=begin rdoc
|
129
|
-
Returns the project associated with a project file, opening it if necessary
|
130
|
-
|
131
|
-
This is one of the core methods of this class. It searchs the list of open projects
|
132
|
-
and return the one corresponding to the given project file. If a project for that
|
133
|
-
file isn't open, it will be opened and added to the list of open projects.
|
134
|
-
|
135
|
-
If, for any reason, you create a project using @Project.new@ instead of
|
136
|
-
using this method, you'll need to add it to the project list yourself using
|
137
|
-
{#add_project}.
|
138
|
-
|
139
|
-
@param [String] file the absolute path of the project file
|
140
|
-
@return [Ruber::Project] the project corresponding to the project file _file_
|
141
|
-
@raise an error deriving from @SystemCallError@ if the project file doesn't exist
|
142
|
-
or can't be opened
|
143
|
-
@raise {Ruber::AbstractProject::InvalidProjectFile} if _file_ isn't a valid project file
|
144
|
-
=end
|
145
|
-
def project file
|
146
|
-
@projects[file] || add_project(Project.new(file))
|
147
|
-
end
|
148
|
-
|
149
|
-
=begin rdoc
|
150
|
-
Returns the project corresponding to a given file or with a given name
|
151
|
-
|
152
|
-
@overload [] name
|
153
|
-
Returns the project with the given name
|
154
|
-
@param [String] name the name of the project. It *must not* start with a slash (@/@)
|
155
|
-
@return [Ruber::Project,nil] the project with name _name_ or *nil* if no open
|
156
|
-
project with that name exists. If more than one project with that name exist,
|
157
|
-
which will be returned is arbitrary
|
158
|
-
@overload [] file
|
159
|
-
Returns the project corresponding to the given project file
|
160
|
-
@param [String] file the absolute path of the project file
|
161
|
-
@return [Ruber::Project,nil] the project corresponding to the project file _file_
|
162
|
-
or *nil* if no open projects correspond to that file. Note that, unlike {#project},
|
163
|
-
this method doesn't attempt to open the project corresponding to _file_ if it
|
164
|
-
isn't already open
|
165
|
-
=end
|
166
|
-
def [] arg
|
167
|
-
if arg[0,1] == '/' then @projects[arg]
|
168
|
-
else
|
169
|
-
find{|prj| prj.project_name == arg}
|
170
|
-
end
|
171
|
-
end
|
172
|
-
|
173
|
-
=begin rdoc
|
174
|
-
Creates a new empty project
|
175
|
-
|
176
|
-
After being created, the new project is added to the list. You almost always should
|
177
|
-
use this method, rather than calling {AbstractProject.new} to create a new empty
|
178
|
-
project.
|
179
|
-
|
180
|
-
@param [String] file the absolue path of the project file to associate with the
|
181
|
-
new project
|
182
|
-
@param [String] name the name of the new project
|
183
|
-
@return [Ruber::Project] the new project
|
184
|
-
@raise @RuntimeError@ if a file corresponding to the path _file_ already exists
|
185
|
-
=end
|
186
|
-
def new_project file, name
|
187
|
-
add_project Project.new( file, name )
|
188
|
-
end
|
189
|
-
|
190
|
-
=begin rdoc
|
191
|
-
Makes a project active
|
192
|
-
|
193
|
-
The previously active project is deactivated, while the new one (unless *nil*)
|
194
|
-
will be activated (calling respectively the the projects' @deactivate@ and @activate@
|
195
|
-
methods)
|
196
|
-
|
197
|
-
@param [Ruber::Project,nil] prj the project to make current. If *nil*, the current
|
198
|
-
project will be deactivated, but no other project will become current
|
199
|
-
@raise @ArgumentError@ if _prj_ is not included in the project list
|
200
|
-
=end
|
201
|
-
def current_project= prj
|
202
|
-
if prj and !@projects[prj.project_file]
|
203
|
-
raise ArgumentError, "Tried to set an unknown project as current project"
|
204
|
-
end
|
205
|
-
@current_project.deactivate if @current_project
|
206
|
-
@current_project = prj
|
207
|
-
emit current_project_changed prj
|
208
|
-
@current_project.activate if @current_project
|
209
|
-
end
|
210
|
-
|
211
|
-
=begin rdoc
|
212
|
-
Adds a project to the list
|
213
|
-
|
214
|
-
The {#project_added} signal is emitted after adding the project.
|
215
|
-
|
216
|
-
Since this method is automatically called by both {#project} and {#new_project},
|
217
|
-
you usually don't need to call it, unless you need to create the project using
|
218
|
-
@Project.new@ rather than using one of the above methods.
|
219
|
-
|
220
|
-
@param [Ruber::Project] prj the project to add
|
221
|
-
@return [Ruber::Project] the project itself
|
222
|
-
@raise @RuntimeError@ if a project corresponding to the same file as _prj_ is
|
223
|
-
already in the list
|
224
|
-
=end
|
225
|
-
def add_project prj
|
226
|
-
if @projects[prj.project_file]
|
227
|
-
raise "A project with project file #{prj.project_file} is already open"
|
228
|
-
end
|
229
|
-
@projects[prj.project_file] = prj
|
230
|
-
connect prj, SIGNAL('closing(QObject*)'), self, SLOT('close_project(QObject*)')
|
231
|
-
emit project_added(prj)
|
232
|
-
prj
|
233
|
-
end
|
234
|
-
|
235
|
-
=begin rdoc
|
236
|
-
Closes the current project
|
237
|
-
|
238
|
-
If there's not a current project, nothing is done. Otherwise, it simply calls the
|
239
|
-
{#close_project} method passing the current project as argument.
|
240
|
-
|
241
|
-
@return [nil]
|
242
|
-
=end
|
243
|
-
def close_current_project
|
244
|
-
@current_project.close if @current_project
|
245
|
-
nil
|
246
|
-
end
|
247
|
-
|
248
|
-
=begin rdoc
|
249
|
-
|
250
|
-
Closes a project
|
251
|
-
|
252
|
-
If the project is current, sets the current project to *nil* before closing it.
|
253
|
-
In all cases, emits the {#closing_project} signal before closing the project.
|
254
|
-
|
255
|
-
@param [Ruber::Project] the project to close
|
256
|
-
@return [nil]
|
257
|
-
=end
|
258
|
-
def close_project prj
|
259
|
-
self.current_project = nil if @current_project == prj
|
260
|
-
emit closing_project(prj)
|
261
|
-
@projects.delete prj.project_file
|
262
|
-
nil
|
263
|
-
end
|
264
|
-
|
265
|
-
|
266
|
-
=begin rdoc
|
267
|
-
Saves each open project
|
268
|
-
|
269
|
-
@return [nil]
|
270
|
-
=end
|
271
|
-
def save_settings
|
272
|
-
@projects.values.each{|pr| pr.save}
|
273
|
-
nil
|
274
|
-
end
|
275
|
-
|
276
|
-
=begin rdoc
|
277
|
-
Tells whether it's all right for the projects to close the application
|
278
|
-
|
279
|
-
It calls the @query_close@ method for each project, returning *false* if any of
|
280
|
-
them returns *false* and *true* if all return *true*
|
281
|
-
|
282
|
-
@return [Boolean] *true* if it's all right for the projects to close the application
|
283
|
-
and *false* if at least one of them say the application can't be closed
|
284
|
-
=end
|
285
|
-
def query_close
|
286
|
-
@projects.values.each{|pr| return false unless pr.query_close}
|
287
|
-
true
|
288
|
-
end
|
289
|
-
|
290
|
-
=begin rdoc
|
291
|
-
Returns the project associated with a given project file
|
292
|
-
|
293
|
-
@param [String] file the path of the project file
|
294
|
-
@param [Symbol] which if @:active_only@, the project corresponding to _file_ will
|
295
|
-
be returned only if it's active. If it is @:all@ then it will be returned even if
|
296
|
-
it's inactive. Any other value will cause this method to always return *nil*
|
297
|
-
@return [Ruber::Project,nil] the project associated with the file _file_ or *nil*
|
298
|
-
if the list doesn't contain any such file or if it doesn't respect the value of
|
299
|
-
_which_.
|
300
|
-
=end
|
301
|
-
def project_for_file file, which = :active_only
|
302
|
-
current_prj = current
|
303
|
-
return nil unless current_prj
|
304
|
-
if current_prj.project_files.file_in_project?(file) then current_prj
|
305
|
-
elsif which == :all
|
306
|
-
find{|prj| prj.project_files.file_in_project?(file)}
|
307
|
-
else nil
|
308
|
-
end
|
309
|
-
end
|
310
|
-
|
311
|
-
|
312
|
-
end
|
313
|
-
|
314
|
-
end
|