ruber 0.0.8 → 0.0.9
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/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
|