ruber 0.0.5 → 0.0.7
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 +25 -0
- data/bin/ruber +0 -0
- data/data/share/apps/ruber/ruberui.rc +15 -1
- data/data/share/icons/{ruber.png → ruber-old.pgn} +0 -0
- data/lib/ruber/application/application.rb +216 -73
- data/lib/ruber/application/plugin.yaml +2 -2
- data/lib/ruber/document_project.rb +25 -5
- data/lib/ruber/documents/document_list.rb +11 -15
- data/lib/ruber/editor/document.rb +106 -50
- data/lib/ruber/editor/editor_view.rb +4 -2
- data/lib/ruber/external_program_plugin.rb +8 -0
- data/lib/ruber/kde_config_option_backend.rb +12 -4
- data/lib/ruber/kde_sugar.rb +35 -1
- data/lib/ruber/main_window/choose_plugins_dlg.rb +10 -10
- data/lib/ruber/main_window/hint_solver.rb +263 -0
- data/lib/ruber/main_window/main_window.rb +462 -206
- data/lib/ruber/main_window/main_window_actions.rb +228 -62
- data/lib/ruber/main_window/main_window_internal.rb +169 -115
- data/lib/ruber/main_window/plugin.yaml +13 -3
- data/lib/ruber/main_window/save_modified_files_dlg.rb +1 -1
- data/lib/ruber/main_window/ui/choose_plugins_widget.rb +1 -1
- data/lib/ruber/main_window/ui/main_window_settings_widget.rb +1 -1
- data/lib/ruber/main_window/ui/new_project_widget.rb +1 -1
- data/lib/ruber/main_window/ui/open_file_in_project_dlg.rb +1 -1
- data/lib/ruber/main_window/ui/output_color_widget.rb +1 -1
- data/lib/ruber/main_window/ui/workspace_settings_widget.rb +51 -0
- data/lib/ruber/main_window/ui/workspace_settings_widget.ui +28 -0
- data/lib/ruber/main_window/view_manager.rb +418 -0
- data/lib/ruber/main_window/workspace.png +0 -0
- data/lib/ruber/output_widget.rb +43 -37
- data/lib/ruber/pane.rb +621 -0
- data/lib/ruber/plugin_specification_reader.rb +8 -1
- data/lib/ruber/projects/project_files_list.rb +6 -0
- data/lib/ruber/projects/ui/project_files_rule_chooser_widget.rb +1 -1
- data/lib/ruber/projects/ui/project_files_widget.rb +1 -1
- data/lib/ruber/qt_sugar.rb +94 -4
- data/lib/ruber/utils.rb +16 -7
- data/lib/ruber/version.rb +2 -2
- data/plugins/autosave/autosave.rb +62 -1
- data/plugins/autosave/plugin.yaml +1 -0
- data/plugins/autosave/ui/autosave_config_widget.rb +37 -14
- data/plugins/autosave/ui/autosave_config_widget.ui +62 -12
- data/plugins/find_in_files/find_in_files_widgets.rb +1 -3
- data/plugins/find_in_files/ui/config_widget.rb +1 -1
- data/plugins/find_in_files/ui/find_in_files_widget.rb +1 -1
- data/plugins/rake/plugin.yaml +1 -1
- data/plugins/rake/ui/add_quick_task_widget.rb +1 -1
- data/plugins/rake/ui/choose_task_widget.rb +1 -1
- data/plugins/rake/ui/config_widget.rb +1 -1
- data/plugins/rake/ui/project_widget.rb +1 -1
- data/plugins/rspec/rspec.rb +14 -22
- data/plugins/rspec/ruber_rspec_formatter.rb +4 -1
- data/plugins/rspec/ui/rspec_project_widget.rb +1 -1
- data/plugins/ruby_development/plugin.yaml +7 -2
- data/plugins/ruby_development/ruby_development.rb +134 -13
- data/plugins/ruby_development/ui/config_widget.rb +66 -0
- data/plugins/ruby_development/ui/config_widget.ui +58 -0
- data/plugins/ruby_development/ui/project_widget.rb +1 -1
- data/plugins/ruby_runner/plugin.yaml +2 -2
- data/plugins/ruby_runner/ruby_runner.rb +15 -3
- data/plugins/ruby_runner/ui/config_widget.rb +1 -1
- data/plugins/ruby_runner/ui/project_widget.rb +1 -1
- data/plugins/ruby_runner/ui/ruby_runnner_plugin_option_widget.rb +1 -1
- data/plugins/state/plugin.yaml +6 -2
- data/plugins/state/state.rb +305 -81
- data/plugins/state/ui/config_widget.rb +1 -1
- data/spec/common.rb +11 -3
- data/spec/document_list_spec.rb +8 -8
- data/spec/document_project_spec.rb +98 -25
- data/spec/document_spec.rb +178 -152
- data/spec/editor_view_spec.rb +26 -5
- data/spec/framework.rb +5 -0
- data/spec/hint_solver_spec.rb +450 -0
- data/spec/kde_sugar_spec.rb +73 -6
- data/spec/output_widget_spec.rb +172 -156
- data/spec/pane_spec.rb +1165 -0
- data/spec/plugin_specification_reader_spec.rb +37 -1
- data/spec/project_files_list_spec.rb +30 -20
- data/spec/qt_sugar_spec.rb +269 -0
- data/spec/state_spec.rb +566 -353
- data/spec/utils_spec.rb +1 -1
- data/spec/view_manager_spec.rb +71 -0
- metadata +16 -4
|
@@ -28,17 +28,20 @@ config_options:
|
|
|
28
28
|
v_splitter: {key: Vertical splitter, type: string list, default: "['80', '20']"}
|
|
29
29
|
workspace:
|
|
30
30
|
tools_sizes: {default: {}}
|
|
31
|
+
close_buttons: {default: 'true', type: bool}
|
|
31
32
|
config_widgets:
|
|
32
33
|
- {caption: General, pixmap: configure, class: Ruber::MainWindowSettingsWidget}
|
|
33
34
|
- {caption: Colors, pixmap: fill-color, class: Ruber::OutputColorWidget}
|
|
35
|
+
- {caption: Workspace, pixmap: workspace.png, class: Ruber::MainWindow::WorkspaceSettingsWidget}
|
|
34
36
|
actions:
|
|
35
37
|
file_new: {standard_action: open_new, slot: new_file()}
|
|
36
38
|
file_open: {standard_action: open, slot: open_file()}
|
|
37
39
|
file_open_recent: {standard_action: open_recent, signal: urlSelected(KUrl), slot: open_recent_file(KUrl)}
|
|
38
40
|
file-save_all: {text: Save &All, icon: document-save-all, slot: save_all()}
|
|
39
41
|
file_close: {standard_action: close, slot: close_current_editor()}
|
|
40
|
-
file-
|
|
41
|
-
file-
|
|
42
|
+
file-close_tab: {text: Close Current &Tab, slot: close_tab(), state: current_document}
|
|
43
|
+
file-close_all: {text: Clos&e All, slot: close_all_views(), state: current_document}
|
|
44
|
+
file-close_other: {text: Close All O&ther, slot: close_other_views(), state: current_document}
|
|
42
45
|
file_quit: {standard_action: quit, receiver: 'Ruber[:app]', slot: closeAllWindows()}
|
|
43
46
|
go_back: {standard_action: back, slot: previous_document(), shortcut: Alt+Left}
|
|
44
47
|
go_forward: {standard_action: forward, slot: next_document(), shortcut: Alt+Right}
|
|
@@ -55,4 +58,11 @@ actions:
|
|
|
55
58
|
options-choose_plugins: {text: C&hoose Plugins..., icon: preferences-plugin, slot: choose_plugins()}
|
|
56
59
|
options_configure: {standard_action: preferences, slot: preferences()}
|
|
57
60
|
configure_document: {text: Configure &Document, icon: configure, slot: configure_document(), state: current_document}
|
|
58
|
-
help_user_manual: {text: Ruber User &Manual, icon: help-contents, slot: show_user_manual()}
|
|
61
|
+
help_user_manual: {text: Ruber User &Manual, icon: help-contents, slot: show_user_manual()}
|
|
62
|
+
window-split_horizontally: {text: Split Horizontally, slot: split_horizontally(), shortcut: Ctrl+Shift+T, state: current_document}
|
|
63
|
+
window-split_vertically: {text: Split Vertically, slot: split_vertically(), shortcut: Ctrl+Shift+L, state: current_document}
|
|
64
|
+
window-switch_to_new_document: {text: Switch to New File, slot: switch_to_new_document(), state: current_document}
|
|
65
|
+
window-switch_to_file: {text: Switch to Open File, slot: switch_to_file(), state: current_document}
|
|
66
|
+
window-switch_to_recent_file: {signal: urlSelected(KUrl), slot: switch_to_recent_file(KUrl), class: KDE::RecentFilesAction, text: Switch to Recent File, state: current_document}
|
|
67
|
+
extensions:
|
|
68
|
+
ruber_default_document: {class: Ruber::Application::DefaultDocumentExtension, scope: document, place: all}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
=begin
|
|
2
2
|
** Form generated from reading ui file 'choose_plugins_widget.ui'
|
|
3
3
|
**
|
|
4
|
-
** Created:
|
|
4
|
+
** Created: mar nov 16 11:52:49 2010
|
|
5
5
|
** by: Qt User Interface Compiler version 4.7.0
|
|
6
6
|
**
|
|
7
7
|
** WARNING! All changes made in this file will be lost when recompiling ui file!
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
=begin
|
|
2
2
|
** Form generated from reading ui file 'main_window_settings_widget.ui'
|
|
3
3
|
**
|
|
4
|
-
** Created:
|
|
4
|
+
** Created: mar nov 16 11:52:49 2010
|
|
5
5
|
** by: Qt User Interface Compiler version 4.7.0
|
|
6
6
|
**
|
|
7
7
|
** WARNING! All changes made in this file will be lost when recompiling ui file!
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
=begin
|
|
2
2
|
** Form generated from reading ui file 'new_project_widget.ui'
|
|
3
3
|
**
|
|
4
|
-
** Created:
|
|
4
|
+
** Created: mar nov 16 11:52:48 2010
|
|
5
5
|
** by: Qt User Interface Compiler version 4.7.0
|
|
6
6
|
**
|
|
7
7
|
** WARNING! All changes made in this file will be lost when recompiling ui file!
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
=begin
|
|
2
2
|
** Form generated from reading ui file 'open_file_in_project_dlg.ui'
|
|
3
3
|
**
|
|
4
|
-
** Created:
|
|
4
|
+
** Created: mar nov 16 11:52:49 2010
|
|
5
5
|
** by: Qt User Interface Compiler version 4.7.0
|
|
6
6
|
**
|
|
7
7
|
** WARNING! All changes made in this file will be lost when recompiling ui file!
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
=begin
|
|
2
2
|
** Form generated from reading ui file 'output_color_widget.ui'
|
|
3
3
|
**
|
|
4
|
-
** Created:
|
|
4
|
+
** Created: mar nov 16 11:52:49 2010
|
|
5
5
|
** by: Qt User Interface Compiler version 4.7.0
|
|
6
6
|
**
|
|
7
7
|
** WARNING! All changes made in this file will be lost when recompiling ui file!
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
=begin
|
|
2
|
+
** Form generated from reading ui file 'workspace_settings_widget.ui'
|
|
3
|
+
**
|
|
4
|
+
** Created: mar gen 11 14:57:22 2011
|
|
5
|
+
** by: Qt User Interface Compiler version 4.7.1
|
|
6
|
+
**
|
|
7
|
+
** WARNING! All changes made in this file will be lost when recompiling ui file!
|
|
8
|
+
=end
|
|
9
|
+
|
|
10
|
+
class Ui_WorkspaceSettingsWidgetBase
|
|
11
|
+
attr_reader :verticalLayout
|
|
12
|
+
attr_reader :_workspace__close_buttons
|
|
13
|
+
|
|
14
|
+
def setupUi(workspaceSettingsWidgetBase)
|
|
15
|
+
if workspaceSettingsWidgetBase.objectName.nil?
|
|
16
|
+
workspaceSettingsWidgetBase.objectName = "workspaceSettingsWidgetBase"
|
|
17
|
+
end
|
|
18
|
+
workspaceSettingsWidgetBase.resize(400, 35)
|
|
19
|
+
@verticalLayout = Qt::VBoxLayout.new(workspaceSettingsWidgetBase)
|
|
20
|
+
@verticalLayout.objectName = "verticalLayout"
|
|
21
|
+
@_workspace__close_buttons = Qt::CheckBox.new(workspaceSettingsWidgetBase)
|
|
22
|
+
@_workspace__close_buttons.objectName = "_workspace__close_buttons"
|
|
23
|
+
|
|
24
|
+
@verticalLayout.addWidget(@_workspace__close_buttons)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
retranslateUi(workspaceSettingsWidgetBase)
|
|
28
|
+
|
|
29
|
+
Qt::MetaObject.connectSlotsByName(workspaceSettingsWidgetBase)
|
|
30
|
+
end # setupUi
|
|
31
|
+
|
|
32
|
+
def setup_ui(workspaceSettingsWidgetBase)
|
|
33
|
+
setupUi(workspaceSettingsWidgetBase)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def retranslateUi(workspaceSettingsWidgetBase)
|
|
37
|
+
workspaceSettingsWidgetBase.windowTitle = Qt::Application.translate("WorkspaceSettingsWidgetBase", "Form", nil, Qt::Application::UnicodeUTF8)
|
|
38
|
+
@_workspace__close_buttons.text = Qt::Application.translate("WorkspaceSettingsWidgetBase", "&Display close buttons on tabs", nil, Qt::Application::UnicodeUTF8)
|
|
39
|
+
end # retranslateUi
|
|
40
|
+
|
|
41
|
+
def retranslate_ui(workspaceSettingsWidgetBase)
|
|
42
|
+
retranslateUi(workspaceSettingsWidgetBase)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
module Ui
|
|
48
|
+
class WorkspaceSettingsWidgetBase < Ui_WorkspaceSettingsWidgetBase
|
|
49
|
+
end
|
|
50
|
+
end # module Ui
|
|
51
|
+
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<ui version="4.0">
|
|
3
|
+
<class>WorkspaceSettingsWidgetBase</class>
|
|
4
|
+
<widget class="QWidget" name="WorkspaceSettingsWidgetBase">
|
|
5
|
+
<property name="geometry">
|
|
6
|
+
<rect>
|
|
7
|
+
<x>0</x>
|
|
8
|
+
<y>0</y>
|
|
9
|
+
<width>400</width>
|
|
10
|
+
<height>35</height>
|
|
11
|
+
</rect>
|
|
12
|
+
</property>
|
|
13
|
+
<property name="windowTitle">
|
|
14
|
+
<string>Form</string>
|
|
15
|
+
</property>
|
|
16
|
+
<layout class="QVBoxLayout" name="verticalLayout">
|
|
17
|
+
<item>
|
|
18
|
+
<widget class="QCheckBox" name="_workspace__close_buttons">
|
|
19
|
+
<property name="text">
|
|
20
|
+
<string>&Display close buttons on tabs</string>
|
|
21
|
+
</property>
|
|
22
|
+
</widget>
|
|
23
|
+
</item>
|
|
24
|
+
</layout>
|
|
25
|
+
</widget>
|
|
26
|
+
<resources/>
|
|
27
|
+
<connections/>
|
|
28
|
+
</ui>
|
|
@@ -0,0 +1,418 @@
|
|
|
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
|
+
view.parent.split view, editor, dir
|
|
117
|
+
else
|
|
118
|
+
if hints[:close_starting_document]
|
|
119
|
+
if @tabs.count == 1 and @tabs.widget(0).single_view?
|
|
120
|
+
doc_to_close = @tabs.widget(0).view.document
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
add_tab editor, doc.icon, doc.document_name
|
|
124
|
+
doc_to_close.close if doc_to_close
|
|
125
|
+
end
|
|
126
|
+
editor.parent.label = label_for_editor editor
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
editor
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
=begin rdoc
|
|
133
|
+
Makes the given editor active
|
|
134
|
+
|
|
135
|
+
Besides merging the editor's GUI with the main window's, this method also deactivates
|
|
136
|
+
the previously active editor, updates the activation order, activates the document
|
|
137
|
+
associated with the new active editor, updates the tab where the new editor is
|
|
138
|
+
and emits the {#active_editor_changed} signal.
|
|
139
|
+
|
|
140
|
+
Nothing is done if the given editor was already active
|
|
141
|
+
@param [EditorView] editor the editor to activate
|
|
142
|
+
@return [EditorView] the new active editor
|
|
143
|
+
=end
|
|
144
|
+
def make_editor_active editor
|
|
145
|
+
return if editor and @active_editor == editor
|
|
146
|
+
deactivate_editor @active_editor
|
|
147
|
+
@active_editor = editor
|
|
148
|
+
if editor
|
|
149
|
+
parent.gui_factory.add_client editor.send(:internal)
|
|
150
|
+
@activation_order.delete editor
|
|
151
|
+
@activation_order.insert 0, editor
|
|
152
|
+
editor_tab = tab(editor)
|
|
153
|
+
tab_idx = @tabs.index_of editor_tab
|
|
154
|
+
@focus_editors[tab_idx] = editor
|
|
155
|
+
update_tab editor_tab
|
|
156
|
+
editor.document.activate
|
|
157
|
+
end
|
|
158
|
+
emit active_editor_changed @active_editor
|
|
159
|
+
@active_editor
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
=begin rdoc
|
|
163
|
+
Deactivates the given editor
|
|
164
|
+
|
|
165
|
+
To deactivate the editor, its GUI is removed from the main window's and the corresponding
|
|
166
|
+
document is deactivated.
|
|
167
|
+
|
|
168
|
+
If the given editor wasn't the active one, nothing is done
|
|
169
|
+
@param [EditorView] view the editor to deactivate
|
|
170
|
+
@return [nil]
|
|
171
|
+
=end
|
|
172
|
+
def deactivate_editor view
|
|
173
|
+
return unless @active_editor and view == @active_editor
|
|
174
|
+
@active_editor.document.deactivate
|
|
175
|
+
parent.gui_factory.remove_client view.send(:internal)
|
|
176
|
+
@active_editor = nil
|
|
177
|
+
nil
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
=begin rdoc
|
|
181
|
+
Executes a block without automatically activating editors
|
|
182
|
+
|
|
183
|
+
Usually, whenever a tab becomes active, one of the editors it contains becomes
|
|
184
|
+
active. Sometimes, you don't want this to happen (for example, when opening multiple
|
|
185
|
+
documents in sequence). To do so, do what you need from a block passed to this method.
|
|
186
|
+
|
|
187
|
+
After the block has been executed, the last activated method in the current tab
|
|
188
|
+
becomes active.
|
|
189
|
+
|
|
190
|
+
@yield the block to call without automatically activating editors
|
|
191
|
+
@return [Object] the value returned by the block
|
|
192
|
+
=end
|
|
193
|
+
def without_activating
|
|
194
|
+
begin
|
|
195
|
+
@auto_activate_editors = false
|
|
196
|
+
yield
|
|
197
|
+
ensure
|
|
198
|
+
@auto_activate_editors = true
|
|
199
|
+
if @tabs.current_index < 0 then make_editor_active nil
|
|
200
|
+
else make_editor_active @focus_editors[@tabs.current_index]
|
|
201
|
+
end
|
|
202
|
+
end
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
=begin rdoc
|
|
206
|
+
The toplevel pane corresponding to the given index or widget
|
|
207
|
+
|
|
208
|
+
@overload tab idx
|
|
209
|
+
@param [Integer] idx the index of the tab
|
|
210
|
+
@return [Pane] the toplevel pane in the tab number _idx_
|
|
211
|
+
@overload tab editor
|
|
212
|
+
@param [EditorView] editor the editor to retrieve the pane for
|
|
213
|
+
@return [Pane,nil] the toplevel pane containing the given editor or *nil* if the
|
|
214
|
+
view isn't contained in a pane
|
|
215
|
+
@overload tab pane
|
|
216
|
+
@param [Pane] pane the pane to retrieve the toplevel pane for
|
|
217
|
+
@return [Pane, nil] the toplevel pane containing the given pane or *nil* if the
|
|
218
|
+
pane isn't contained in another pane
|
|
219
|
+
=end
|
|
220
|
+
def tab arg
|
|
221
|
+
if arg.is_a? Integer then @tabs.widget arg
|
|
222
|
+
else
|
|
223
|
+
pane = arg.is_a?(Pane) ? arg : arg.parent
|
|
224
|
+
return unless pane
|
|
225
|
+
pane = pane.parent_pane while pane.parent_pane
|
|
226
|
+
pane
|
|
227
|
+
end
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
=begin rdoc
|
|
231
|
+
Whether the given view is a focus editor
|
|
232
|
+
|
|
233
|
+
@overload focus_editor? editor
|
|
234
|
+
Whether the given view is the focus editor for any tab
|
|
235
|
+
@param [EditorView] editor the view to test
|
|
236
|
+
@return [Boolean] *true* if there's a tab which has _editor_ as focus editor and
|
|
237
|
+
*false* otherwise
|
|
238
|
+
@overload focus_editor? editor, tab
|
|
239
|
+
Whether the given view is the focus editor for the given tab
|
|
240
|
+
@param [EditorView] editor the view to test
|
|
241
|
+
@param [Pane,Integer] tab the tab the view must be focus editor for. If a {Pane}
|
|
242
|
+
it must be the toplevel pane of the tab; if an @Integer@, it must be the index
|
|
243
|
+
of the pane to test
|
|
244
|
+
@note this method doesn't test whether _tab_ actually is a toplevel pane
|
|
245
|
+
@return [Boolean] *true* if _editor_ is the focus widget for _tab_ and
|
|
246
|
+
*false* otherwise
|
|
247
|
+
=end
|
|
248
|
+
def focus_editor? editor, tab = nil
|
|
249
|
+
if tab
|
|
250
|
+
tab = @tabs.index_of(tab) unless tab.is_a? Integer
|
|
251
|
+
@focus_editors[tab] == editor
|
|
252
|
+
else @focus_editors.any?{|k, v| v == editor}
|
|
253
|
+
end
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
=begin rdoc
|
|
257
|
+
The label to use for an editor
|
|
258
|
+
|
|
259
|
+
@param [EditorView] ed the editor to return the label for
|
|
260
|
+
@return [String] the text to show below the given editor
|
|
261
|
+
=end
|
|
262
|
+
def label_for_editor ed
|
|
263
|
+
url = ed.document.url
|
|
264
|
+
if url.valid? then url.local_file? ? url.path : url.pretty_url
|
|
265
|
+
else ed.document.document_name
|
|
266
|
+
end
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
private
|
|
270
|
+
|
|
271
|
+
=begin rdoc
|
|
272
|
+
Creates an editor for a document
|
|
273
|
+
|
|
274
|
+
@param [Document] doc the document to create the editor for
|
|
275
|
+
@return [EditorView] the new editor for the document
|
|
276
|
+
=end
|
|
277
|
+
def create_editor doc
|
|
278
|
+
editor = doc.create_view
|
|
279
|
+
connect editor, SIGNAL('focus_in(QWidget*)'), self, SLOT('focus_in_view(QWidget*)')
|
|
280
|
+
connect editor, SIGNAL('closing(QWidget*)'), self, SLOT('view_closing(QWidget*)')
|
|
281
|
+
editor
|
|
282
|
+
end
|
|
283
|
+
|
|
284
|
+
=begin rdoc
|
|
285
|
+
Adds a new tab to the tab widget
|
|
286
|
+
|
|
287
|
+
The tab is created with a view inserted in it and is assigned an icon an a label
|
|
288
|
+
@param [EditorView] view the view to insert in the new pane
|
|
289
|
+
@param [Qt::Icon] icon the icon to associate with the new tab
|
|
290
|
+
@param [String] label the label to use for the new tab
|
|
291
|
+
@return [Pane] the pane corresponding to the new tab
|
|
292
|
+
=end
|
|
293
|
+
def add_tab view, icon, label
|
|
294
|
+
new_tab = Pane.new(view)
|
|
295
|
+
idx = @tabs.add_tab new_tab, icon, label
|
|
296
|
+
@focus_editors[idx] = view
|
|
297
|
+
connect new_tab, SIGNAL('closing_last_view(QWidget*)'), self, SLOT('remove_tab(QWidget*)')
|
|
298
|
+
connect new_tab, SIGNAL('pane_split(QWidget*, QWidget*, QWidget*)'), self, SLOT('update_tab(QWidget*)')
|
|
299
|
+
connect new_tab, SIGNAL('removing_view(QWidget*, QWidget*)'), self, SLOT('update_tab(QWidget*)')
|
|
300
|
+
connect new_tab, SIGNAL('view_replaced(QWidget*, QWidget*, QWidget*)'), self, SLOT('update_tab(QWidget*)')
|
|
301
|
+
new_tab
|
|
302
|
+
end
|
|
303
|
+
|
|
304
|
+
=begin rdoc
|
|
305
|
+
Removes the tab corresponding to the given toplevel pane
|
|
306
|
+
|
|
307
|
+
@param [Pane] pane the toplevel pane whose tab should be removed
|
|
308
|
+
@return [nil]
|
|
309
|
+
=end
|
|
310
|
+
def remove_tab pane
|
|
311
|
+
idx = @tabs.index_of pane
|
|
312
|
+
if idx
|
|
313
|
+
@focus_editors.delete_at idx
|
|
314
|
+
@tabs.remove_tab idx
|
|
315
|
+
end
|
|
316
|
+
nil
|
|
317
|
+
end
|
|
318
|
+
slots 'remove_tab(QWidget*)'
|
|
319
|
+
|
|
320
|
+
=begin rdoc
|
|
321
|
+
Slot called whenever a view receives focus
|
|
322
|
+
|
|
323
|
+
The views is activated, unless it was already active
|
|
324
|
+
@param [EditorView] view the view which received focus
|
|
325
|
+
@return [nil]
|
|
326
|
+
=end
|
|
327
|
+
def focus_in_view view
|
|
328
|
+
if view != @active_editor
|
|
329
|
+
make_editor_active view
|
|
330
|
+
end
|
|
331
|
+
nil
|
|
332
|
+
end
|
|
333
|
+
slots 'focus_in_view(QWidget*)'
|
|
334
|
+
|
|
335
|
+
=begin rdoc
|
|
336
|
+
Slot called whenever a view is closed
|
|
337
|
+
|
|
338
|
+
It deactivates the view (if it was active) and preforms some cleanup.
|
|
339
|
+
@param [EditorView] view the view which is being closed
|
|
340
|
+
@return [nil]
|
|
341
|
+
=end
|
|
342
|
+
def view_closing view
|
|
343
|
+
@activation_order.delete view
|
|
344
|
+
disconnect view, SIGNAL('focus_in(QWidget*)'), self, SLOT('focus_in_view(QWidget*)')
|
|
345
|
+
deactivate_editor view
|
|
346
|
+
nil
|
|
347
|
+
end
|
|
348
|
+
slots 'view_closing(QWidget*)'
|
|
349
|
+
|
|
350
|
+
=begin rdoc
|
|
351
|
+
Slot called whenever the current tab changes
|
|
352
|
+
|
|
353
|
+
Unless called from within a {#without_activating} block, it activates and gives focus
|
|
354
|
+
to the view in the new current tab which last got focus.
|
|
355
|
+
|
|
356
|
+
If called from within a {#without_activating} block, or if there's no current tab,
|
|
357
|
+
all editors are deactivated
|
|
358
|
+
@param [Integer] idx the index of the current tab
|
|
359
|
+
@return [nil]
|
|
360
|
+
=end
|
|
361
|
+
def current_tab_changed idx
|
|
362
|
+
if idx > -1
|
|
363
|
+
@focus_editors[idx] ||= @tabs.widget(idx).to_a[0]
|
|
364
|
+
ed = @focus_editors[idx]
|
|
365
|
+
if @auto_activate_editors then ed.set_focus
|
|
366
|
+
else make_editor_active nil
|
|
367
|
+
end
|
|
368
|
+
else
|
|
369
|
+
make_editor_active nil
|
|
370
|
+
end
|
|
371
|
+
nil
|
|
372
|
+
end
|
|
373
|
+
slots 'current_tab_changed(int)'
|
|
374
|
+
|
|
375
|
+
=begin rdoc
|
|
376
|
+
Updates the tab containing the given toplevel pane
|
|
377
|
+
|
|
378
|
+
Updating the tab means changing its icon, its label, its tooltip and the label
|
|
379
|
+
associated with each of the editors it contains
|
|
380
|
+
@param [Pane] pane the toplevel pane contained in the pane to update
|
|
381
|
+
@return [nil]
|
|
382
|
+
=end
|
|
383
|
+
def update_tab pane
|
|
384
|
+
idx = @tabs.index_of tab(pane)
|
|
385
|
+
return if idx < 0
|
|
386
|
+
doc = @focus_editors[idx].document
|
|
387
|
+
@tabs.set_tab_text idx, doc.document_name
|
|
388
|
+
@tabs.set_tab_icon idx, doc.icon
|
|
389
|
+
pane.each_pane{|pn| pn.label = label_for_editor(pn.view) if pn.single_view?}
|
|
390
|
+
update_tool_tip idx
|
|
391
|
+
nil
|
|
392
|
+
end
|
|
393
|
+
slots 'update_tab(QWidget*)'
|
|
394
|
+
|
|
395
|
+
=begin rdoc
|
|
396
|
+
Updates the tooltip for the given tab
|
|
397
|
+
|
|
398
|
+
A pane's tooltip contains the list of the documents associated with the views in
|
|
399
|
+
the tab, separated by newlines.
|
|
400
|
+
|
|
401
|
+
@param [Integer] idx the index of the tab whose tooltip should be updated
|
|
402
|
+
@param [Array<EditorView>] ignore a list of views which shouldn't be considered
|
|
403
|
+
when creating the tool tip. This is necessary because, when a view is closed,
|
|
404
|
+
this method is called _before_ the view is removed from the pane, so the document
|
|
405
|
+
associated with it would be included in the tooltip if it weren't specified here
|
|
406
|
+
@return [nil]
|
|
407
|
+
=end
|
|
408
|
+
def update_tool_tip idx, *ignore
|
|
409
|
+
docs = @tabs.widget(idx).reject{|v| ignore.include? v}.map{|v| v.document.document_name}.uniq
|
|
410
|
+
@tabs.set_tab_tool_tip idx, docs.join("\n")
|
|
411
|
+
nil
|
|
412
|
+
end
|
|
413
|
+
|
|
414
|
+
end
|
|
415
|
+
|
|
416
|
+
end
|
|
417
|
+
|
|
418
|
+
end
|