ruber 0.0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (166) hide show
  1. data/COPYING +339 -0
  2. data/INSTALL +137 -0
  3. data/LICENSE +8 -0
  4. data/bin/ruber +65 -0
  5. data/data/share/apps/ruber/core_components.yaml +31 -0
  6. data/data/share/apps/ruber/ruberui.rc +109 -0
  7. data/data/share/icons/ruber.png +0 -0
  8. data/data/share/pixmaps/ruby.png +0 -0
  9. data/icons/ruber-16.png +0 -0
  10. data/icons/ruber-32.png +0 -0
  11. data/icons/ruber-48.png +0 -0
  12. data/icons/ruber-8.png +0 -0
  13. data/lib/ruber/application/application.rb +288 -0
  14. data/lib/ruber/application/plugin.yaml +11 -0
  15. data/lib/ruber/component_manager.rb +899 -0
  16. data/lib/ruber/config/config.rb +82 -0
  17. data/lib/ruber/config/plugin.yaml +3 -0
  18. data/lib/ruber/document_project.rb +209 -0
  19. data/lib/ruber/documents/document_list.rb +416 -0
  20. data/lib/ruber/documents/plugin.yaml +4 -0
  21. data/lib/ruber/editor/document.rb +506 -0
  22. data/lib/ruber/editor/editor_view.rb +167 -0
  23. data/lib/ruber/editor/ktexteditor_wrapper.rb +202 -0
  24. data/lib/ruber/exception_widgets.rb +245 -0
  25. data/lib/ruber/external_program_plugin.rb +397 -0
  26. data/lib/ruber/filtered_output_widget.rb +342 -0
  27. data/lib/ruber/gui_states_handler.rb +231 -0
  28. data/lib/ruber/kde_config_option_backend.rb +167 -0
  29. data/lib/ruber/kde_sugar.rb +249 -0
  30. data/lib/ruber/main_window/choose_plugins_dlg.rb +353 -0
  31. data/lib/ruber/main_window/main_window.rb +524 -0
  32. data/lib/ruber/main_window/main_window_actions.rb +537 -0
  33. data/lib/ruber/main_window/main_window_internal.rb +239 -0
  34. data/lib/ruber/main_window/open_file_in_project_dlg.rb +212 -0
  35. data/lib/ruber/main_window/output_color_widget.rb +35 -0
  36. data/lib/ruber/main_window/plugin.yaml +58 -0
  37. data/lib/ruber/main_window/save_modified_files_dlg.rb +89 -0
  38. data/lib/ruber/main_window/status_bar.rb +156 -0
  39. data/lib/ruber/main_window/ui/choose_plugins_widget.rb +90 -0
  40. data/lib/ruber/main_window/ui/choose_plugins_widget.ui +77 -0
  41. data/lib/ruber/main_window/ui/main_window_settings_widget.rb +108 -0
  42. data/lib/ruber/main_window/ui/main_window_settings_widget.ui +89 -0
  43. data/lib/ruber/main_window/ui/new_project_widget.rb +119 -0
  44. data/lib/ruber/main_window/ui/new_project_widget.ui +178 -0
  45. data/lib/ruber/main_window/ui/open_file_in_project_dlg.rb +109 -0
  46. data/lib/ruber/main_window/ui/open_file_in_project_dlg.ui +168 -0
  47. data/lib/ruber/main_window/ui/output_color_widget.rb +241 -0
  48. data/lib/ruber/main_window/ui/output_color_widget.ui +204 -0
  49. data/lib/ruber/main_window/workspace.rb +442 -0
  50. data/lib/ruber/output_widget.rb +1093 -0
  51. data/lib/ruber/plugin.rb +264 -0
  52. data/lib/ruber/plugin_like.rb +589 -0
  53. data/lib/ruber/plugin_specification.rb +106 -0
  54. data/lib/ruber/plugin_specification_reader.rb +451 -0
  55. data/lib/ruber/project.rb +493 -0
  56. data/lib/ruber/project_backend.rb +105 -0
  57. data/lib/ruber/projects/plugin.yaml +11 -0
  58. data/lib/ruber/projects/project_files_list.rb +314 -0
  59. data/lib/ruber/projects/project_files_widget.rb +301 -0
  60. data/lib/ruber/projects/project_list.rb +314 -0
  61. data/lib/ruber/projects/ui/project_files_rule_chooser_widget.rb +74 -0
  62. data/lib/ruber/projects/ui/project_files_rule_chooser_widget.ui +61 -0
  63. data/lib/ruber/projects/ui/project_files_widget.rb +117 -0
  64. data/lib/ruber/projects/ui/project_files_widget.ui +123 -0
  65. data/lib/ruber/qt_sugar.rb +673 -0
  66. data/lib/ruber/settings_container.rb +515 -0
  67. data/lib/ruber/settings_dialog.rb +244 -0
  68. data/lib/ruber/settings_dialog_manager.rb +503 -0
  69. data/lib/ruber/utils.rb +414 -0
  70. data/lib/ruber/yaml_option_backend.rb +159 -0
  71. data/outsider_files +15 -0
  72. data/plugins/autosave/autosave.rb +404 -0
  73. data/plugins/autosave/plugin.yaml +16 -0
  74. data/plugins/autosave/ui/autosave_config_widget.rb +83 -0
  75. data/plugins/autosave/ui/autosave_config_widget.ui +68 -0
  76. data/plugins/command/command.png +0 -0
  77. data/plugins/command/command.rb +74 -0
  78. data/plugins/command/plugin.yaml +11 -0
  79. data/plugins/find_in_files/find_in_files.rb +337 -0
  80. data/plugins/find_in_files/find_in_files_dlg.rb +411 -0
  81. data/plugins/find_in_files/find_in_files_ui.rc +11 -0
  82. data/plugins/find_in_files/find_in_files_widgets.rb +485 -0
  83. data/plugins/find_in_files/plugin.yaml +23 -0
  84. data/plugins/find_in_files/ui/config_widget.rb +58 -0
  85. data/plugins/find_in_files/ui/config_widget.ui +41 -0
  86. data/plugins/find_in_files/ui/find_in_files_widget.rb +260 -0
  87. data/plugins/find_in_files/ui/find_in_files_widget.ui +324 -0
  88. data/plugins/project_browser/plugin.yaml +10 -0
  89. data/plugins/project_browser/project_browser.rb +245 -0
  90. data/plugins/rake/plugin.yaml +39 -0
  91. data/plugins/rake/rake.png +0 -0
  92. data/plugins/rake/rake.rb +567 -0
  93. data/plugins/rake/rake_extension.rb +153 -0
  94. data/plugins/rake/rake_widgets.rb +615 -0
  95. data/plugins/rake/rakeui.rc +27 -0
  96. data/plugins/rake/ui/add_quick_task_widget.rb +71 -0
  97. data/plugins/rake/ui/add_quick_task_widget.ui +59 -0
  98. data/plugins/rake/ui/choose_task_widget.rb +77 -0
  99. data/plugins/rake/ui/choose_task_widget.ui +72 -0
  100. data/plugins/rake/ui/config_widget.rb +127 -0
  101. data/plugins/rake/ui/config_widget.ui +123 -0
  102. data/plugins/rake/ui/project_widget.rb +217 -0
  103. data/plugins/rake/ui/project_widget.ui +246 -0
  104. data/plugins/rspec/plugin.yaml +30 -0
  105. data/plugins/rspec/rspec.png +0 -0
  106. data/plugins/rspec/rspec.rb +945 -0
  107. data/plugins/rspec/rspec.svg +90 -0
  108. data/plugins/rspec/rspecui.rc +20 -0
  109. data/plugins/rspec/ruber_rspec_formatter.rb +312 -0
  110. data/plugins/rspec/ui/rspec_project_widget.rb +170 -0
  111. data/plugins/rspec/ui/rspec_project_widget.ui +193 -0
  112. data/plugins/ruby_development/plugin.yaml +27 -0
  113. data/plugins/ruby_development/ruby_development.png +0 -0
  114. data/plugins/ruby_development/ruby_development.rb +453 -0
  115. data/plugins/ruby_development/ruby_developmentui.rc +19 -0
  116. data/plugins/ruby_development/ui/project_widget.rb +112 -0
  117. data/plugins/ruby_development/ui/project_widget.ui +108 -0
  118. data/plugins/ruby_runner/config_widget.rb +116 -0
  119. data/plugins/ruby_runner/plugin.yaml +26 -0
  120. data/plugins/ruby_runner/project_widget.rb +62 -0
  121. data/plugins/ruby_runner/ruby.png +0 -0
  122. data/plugins/ruby_runner/ruby_interpretersui.rc +26 -0
  123. data/plugins/ruby_runner/ruby_runner.rb +411 -0
  124. data/plugins/ruby_runner/ui/config_widget.rb +92 -0
  125. data/plugins/ruby_runner/ui/config_widget.ui +91 -0
  126. data/plugins/ruby_runner/ui/project_widget.rb +60 -0
  127. data/plugins/ruby_runner/ui/project_widget.ui +48 -0
  128. data/plugins/ruby_runner/ui/ruby_runnner_plugin_option_widget.rb +59 -0
  129. data/plugins/ruby_runner/ui/ruby_runnner_plugin_option_widget.ui +44 -0
  130. data/plugins/state/plugin.yaml +28 -0
  131. data/plugins/state/state.rb +520 -0
  132. data/plugins/state/ui/config_widget.rb +92 -0
  133. data/plugins/state/ui/config_widget.ui +89 -0
  134. data/plugins/syntax_checker/plugin.yaml +18 -0
  135. data/plugins/syntax_checker/syntax_checker.rb +662 -0
  136. data/ruber.desktop +10 -0
  137. data/spec/annotation_model_spec.rb +174 -0
  138. data/spec/common.rb +119 -0
  139. data/spec/component_manager_spec.rb +1259 -0
  140. data/spec/document_list_spec.rb +626 -0
  141. data/spec/document_project_spec.rb +373 -0
  142. data/spec/document_spec.rb +779 -0
  143. data/spec/editor_view_spec.rb +167 -0
  144. data/spec/external_program_plugin_spec.rb +676 -0
  145. data/spec/filtered_output_widget_spec.rb +642 -0
  146. data/spec/gui_states_handler_spec.rb +304 -0
  147. data/spec/kde_config_option_backend_spec.rb +214 -0
  148. data/spec/kde_sugar_spec.rb +101 -0
  149. data/spec/ktexteditor_wrapper_spec.rb +305 -0
  150. data/spec/output_widget_spec.rb +1703 -0
  151. data/spec/plugin_spec.rb +1393 -0
  152. data/spec/plugin_specification_reader_spec.rb +1765 -0
  153. data/spec/plugin_specification_spec.rb +401 -0
  154. data/spec/project_backend_spec.rb +172 -0
  155. data/spec/project_files_list_spec.rb +401 -0
  156. data/spec/project_list_spec.rb +511 -0
  157. data/spec/project_spec.rb +990 -0
  158. data/spec/qt_sugar_spec.rb +328 -0
  159. data/spec/settings_container_spec.rb +617 -0
  160. data/spec/settings_dialog_manager_spec.rb +773 -0
  161. data/spec/settings_dialog_spec.rb +419 -0
  162. data/spec/state_spec.rb +991 -0
  163. data/spec/utils_spec.rb +406 -0
  164. data/spec/workspace_spec.rb +869 -0
  165. data/spec/yaml_option_backend_spec.rb +246 -0
  166. metadata +284 -0
@@ -0,0 +1,204 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <ui version="4.0">
3
+ <class>OutputColorWidget</class>
4
+ <widget class="QWidget" name="OutputColorWidget">
5
+ <property name="geometry">
6
+ <rect>
7
+ <x>0</x>
8
+ <y>0</y>
9
+ <width>392</width>
10
+ <height>189</height>
11
+ </rect>
12
+ </property>
13
+ <property name="windowTitle">
14
+ <string>Form</string>
15
+ </property>
16
+ <layout class="QVBoxLayout" name="verticalLayout">
17
+ <item>
18
+ <layout class="QGridLayout" name="gridLayout">
19
+ <item row="0" column="1">
20
+ <widget class="QLabel" name="label_9">
21
+ <property name="text">
22
+ <string>Default</string>
23
+ </property>
24
+ <property name="alignment">
25
+ <set>Qt::AlignCenter</set>
26
+ </property>
27
+ </widget>
28
+ </item>
29
+ <item row="0" column="2">
30
+ <widget class="QLabel" name="label_8">
31
+ <property name="text">
32
+ <string>Good</string>
33
+ </property>
34
+ <property name="alignment">
35
+ <set>Qt::AlignCenter</set>
36
+ </property>
37
+ </widget>
38
+ </item>
39
+ <item row="1" column="0">
40
+ <widget class="QLabel" name="label_7">
41
+ <property name="text">
42
+ <string>Message</string>
43
+ </property>
44
+ </widget>
45
+ </item>
46
+ <item row="1" column="1">
47
+ <widget class="KColorButton" name="_output_colors__message"/>
48
+ </item>
49
+ <item row="1" column="2">
50
+ <widget class="KColorButton" name="_output_colors__message_good"/>
51
+ </item>
52
+ <item row="1" column="3">
53
+ <widget class="KColorButton" name="_output_colors__message_bad"/>
54
+ </item>
55
+ <item row="0" column="3">
56
+ <widget class="QLabel" name="label_10">
57
+ <property name="text">
58
+ <string>Bad</string>
59
+ </property>
60
+ <property name="alignment">
61
+ <set>Qt::AlignCenter</set>
62
+ </property>
63
+ </widget>
64
+ </item>
65
+ </layout>
66
+ </item>
67
+ <item>
68
+ <widget class="Line" name="line">
69
+ <property name="orientation">
70
+ <enum>Qt::Horizontal</enum>
71
+ </property>
72
+ </widget>
73
+ </item>
74
+ <item>
75
+ <layout class="QGridLayout" name="gridLayout_2">
76
+ <item row="0" column="1">
77
+ <widget class="QLabel" name="label">
78
+ <property name="text">
79
+ <string>Default</string>
80
+ </property>
81
+ <property name="alignment">
82
+ <set>Qt::AlignCenter</set>
83
+ </property>
84
+ </widget>
85
+ </item>
86
+ <item row="0" column="2">
87
+ <widget class="QLabel" name="label_2">
88
+ <property name="text">
89
+ <string>Variant 1</string>
90
+ </property>
91
+ <property name="alignment">
92
+ <set>Qt::AlignCenter</set>
93
+ </property>
94
+ </widget>
95
+ </item>
96
+ <item row="0" column="3">
97
+ <widget class="QLabel" name="label_3">
98
+ <property name="text">
99
+ <string>Variant 2</string>
100
+ </property>
101
+ <property name="alignment">
102
+ <set>Qt::AlignCenter</set>
103
+ </property>
104
+ </widget>
105
+ </item>
106
+ <item row="1" column="0">
107
+ <widget class="QLabel" name="label_5">
108
+ <property name="text">
109
+ <string>Output</string>
110
+ </property>
111
+ </widget>
112
+ </item>
113
+ <item row="1" column="1">
114
+ <widget class="KColorButton" name="_output_colors__output"/>
115
+ </item>
116
+ <item row="1" column="2">
117
+ <widget class="KColorButton" name="_output_colors__output1"/>
118
+ </item>
119
+ <item row="1" column="3">
120
+ <widget class="KColorButton" name="_output_colors__output2"/>
121
+ </item>
122
+ <item row="2" column="0">
123
+ <widget class="QLabel" name="label_6">
124
+ <property name="text">
125
+ <string>Error</string>
126
+ </property>
127
+ </widget>
128
+ </item>
129
+ <item row="2" column="1">
130
+ <widget class="KColorButton" name="_output_colors__error"/>
131
+ </item>
132
+ <item row="2" column="2">
133
+ <widget class="KColorButton" name="_output_colors__error1"/>
134
+ </item>
135
+ <item row="2" column="3">
136
+ <widget class="KColorButton" name="_output_colors__error2"/>
137
+ </item>
138
+ <item row="3" column="0">
139
+ <widget class="QLabel" name="label_4">
140
+ <property name="text">
141
+ <string>Warning</string>
142
+ </property>
143
+ </widget>
144
+ </item>
145
+ <item row="3" column="1">
146
+ <widget class="KColorButton" name="_output_colors__warning"/>
147
+ </item>
148
+ <item row="3" column="2">
149
+ <widget class="KColorButton" name="_output_colors__warning1"/>
150
+ </item>
151
+ <item row="3" column="3">
152
+ <widget class="KColorButton" name="_output_colors__warning2"/>
153
+ </item>
154
+ </layout>
155
+ </item>
156
+ <item>
157
+ <spacer name="verticalSpacer">
158
+ <property name="orientation">
159
+ <enum>Qt::Vertical</enum>
160
+ </property>
161
+ <property name="sizeHint" stdset="0">
162
+ <size>
163
+ <width>20</width>
164
+ <height>40</height>
165
+ </size>
166
+ </property>
167
+ </spacer>
168
+ </item>
169
+ </layout>
170
+ <zorder>label</zorder>
171
+ <zorder>label_2</zorder>
172
+ <zorder>label_3</zorder>
173
+ <zorder>label_5</zorder>
174
+ <zorder>_output_colors__output</zorder>
175
+ <zorder>_output_colors__output1</zorder>
176
+ <zorder>_output_colors__output2</zorder>
177
+ <zorder>label_6</zorder>
178
+ <zorder>_output_colors__error</zorder>
179
+ <zorder>_output_colors__error1</zorder>
180
+ <zorder>_output_colors__error2</zorder>
181
+ <zorder>_output_colors__warning2</zorder>
182
+ <zorder>label_4</zorder>
183
+ <zorder>_output_colors__warning1</zorder>
184
+ <zorder>_output_colors__warning</zorder>
185
+ <zorder>line</zorder>
186
+ <zorder>_output_colors__message</zorder>
187
+ <zorder>_output_colors__message_bad</zorder>
188
+ <zorder>label_7</zorder>
189
+ <zorder>label_8</zorder>
190
+ <zorder>label_9</zorder>
191
+ <zorder>label_10</zorder>
192
+ <zorder>_output_colors__message_good</zorder>
193
+ <zorder>label_10</zorder>
194
+ </widget>
195
+ <customwidgets>
196
+ <customwidget>
197
+ <class>KColorButton</class>
198
+ <extends>QPushButton</extends>
199
+ <header>kcolorbutton.h</header>
200
+ </customwidget>
201
+ </customwidgets>
202
+ <resources/>
203
+ <connections/>
204
+ </ui>
@@ -0,0 +1,442 @@
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 'facets/enumerable/sum'
22
+
23
+ module Ruber
24
+
25
+ =begin rdoc
26
+ Widget representing the main area of Ruber's main window, containing the tool
27
+ widgets, together with their tab bars, and the tab widget containing the views.
28
+
29
+ ===Tool Widgets
30
+ The workspace provides three <i>tool widgets containers</i>, on all sides of the
31
+ editor views except above them. The container on each side is indipendent from the
32
+ others.
33
+
34
+ A tool widget can be
35
+ * +raised+ or +lowered+: a raised tool widget is the only one which can bee seen
36
+ and interact with the user. There can be only one raised tool widget for side.
37
+ All other tool widgets are said to be lowered.
38
+ * +visible+ or +hidden+: while a lowered tool widget is can never be seen, the
39
+ opposite is not necessarily true. A raised tool widget will be visible only if
40
+ its container is visible, otherwise it will be hidden, too
41
+ * +active+ or +inactive+: a tool widget is active only if it has focus, otherwise
42
+ it's inactive. Obviously, only visible tool widgets can be active and there can
43
+ be at most one active tool widget in all the workspace.
44
+ =end
45
+ class Workspace < Qt::Widget
46
+
47
+ =begin rdoc
48
+ Class used by +ToolManager+ to display the currently selected widget. It's a
49
+ <tt>Qt::WidgetStack</tt> which handles the +keyPressEvent+ when the key is either
50
+ Esc or Shift+Esc. In the former case, the tool widget is hidden; in the latter
51
+ the focus is given back to the editor.
52
+
53
+ ===TODO
54
+ See whether this can somehow managed using shortcuts
55
+ =end
56
+ class StackedWidget < Qt::StackedWidget
57
+
58
+ protected
59
+
60
+ =begin rdoc
61
+ Handles the key press event. First, it calls the method of the parent class,
62
+ then if the event hasn't been accepted, activates the editor if the key was
63
+ <tt>Shift + Esc</tt> or hides the current tool (thus activating the editor) if
64
+ the key was +Esc+ with no modifiers.
65
+ =====Arguments
66
+ _e_:: the event (<tt>Qt::KeyEvent</tt>)
67
+ =end
68
+ def keyPressEvent e
69
+ super e
70
+ return if e.accepted?
71
+ if e.key == Qt::Key_Q and e.modifiers == Qt::ShiftModifier.to_i
72
+ Ruber[:main_window].activate_editor
73
+ elsif e.key == Qt::Key_Q and e.modifiers == Qt::NoModifier.to_i
74
+ Ruber[:main_window].hide_tool current_widget
75
+ else e.ignore
76
+ end
77
+ end
78
+
79
+ end
80
+
81
+ =begin rdoc
82
+ Internal class used to store information about the position of a tool widget
83
+ =end
84
+ ToolData = Struct.new(:side, :id)
85
+
86
+ ##
87
+ # :method: tool_raised(tool)
88
+ #
89
+ # <b>Signal</b>
90
+ #
91
+ # <b>Signature:</b> <tt>tool_raised(QWidget*)</tt>
92
+ #
93
+ # Signal emitted when a tool widget is raised. _tool_ is the widget which
94
+ # has been raised
95
+ signals 'tool_raised(QWidget*)'
96
+
97
+ ##
98
+ # :method: removing_tool(tool)
99
+ #
100
+ # *Signal*
101
+ #
102
+ # <b>Signature:</b> <tt>removing_tool(QWidget*)</tt>
103
+ #
104
+ # Signal emitted just before the tool widget _tool_ is removed
105
+ signals 'removing_tool(QWidget*)'
106
+
107
+ ##
108
+ # :method: tool_shown
109
+ # <b>Signal: <tt>tool_shown(QWidget*)</tt></b>
110
+ #
111
+ # Signal emitted when a tool widget is shown programmaticaly.
112
+ signals 'tool_shown(QWidget*)'
113
+
114
+ slots 'toggle_tool(int)'
115
+
116
+ =begin rdoc
117
+ The tab widget containing the editor views
118
+ =end
119
+ # attr_reader :views
120
+
121
+ =begin rdoc
122
+ Creates a new Workspace. _parent_ is the workspace's parent widget
123
+ =end
124
+ def initialize parent = nil
125
+ super
126
+ @button_bars = {}
127
+ @splitters = {}
128
+ @stacks = {}
129
+ @widgets = {}
130
+ @next_id = 0
131
+ @tool_sizes = {}
132
+ @sizes = Ruber[:config][:workspace, :tools_sizes].dup
133
+ create_skeleton
134
+ end
135
+
136
+ =begin rdoc
137
+ Adds a tool widget to the workspace. _side_ is the side where the widget should
138
+ be put. It can be <tt>:left</tt>, <tt>:right</tt> or <tt>:bottom</tt>. _widget_
139
+ is the widget to add; _icon_ is the <tt>Qt::Pixmap</tt> containing the icon to
140
+ put on the tab bar and _caption_ is the text to display on the same caption.
141
+
142
+ If _widget_ had already been added as a tool widget (either on the same side or
143
+ another side, then ArgumentError is raised).
144
+ =end
145
+ def add_tool_widget side, widget, icon, caption
146
+ if @stacks.values.include? widget.parent
147
+ Kernel.raise ArgumentError, "This widget has already been added as tool widget"
148
+ end
149
+ bar = @button_bars[side]
150
+ id = @next_id
151
+ bar.append_tab icon, id, caption
152
+ @widgets[widget] = ToolData.new side, id
153
+ @stacks[side].add_widget widget
154
+ connect bar.tab(id), SIGNAL('clicked(int)'), self, SLOT('toggle_tool(int)')
155
+ @next_id += 1
156
+ end
157
+
158
+ =begin rdoc
159
+ Removes a tool widget. _arg_ can be either the widget itself or its <tt>object_name</tt>,
160
+ either as a string or as a symbol. If the widget isn't a tool widget, nothing
161
+ happens.
162
+ =end
163
+ def remove_tool_widget arg
164
+ widget, data = if arg.is_a? String or arg.is_a? Symbol
165
+ @widgets.find{|k, v| k.object_name == arg.to_s}
166
+ else [arg, @widgets[arg]]
167
+ end
168
+ return unless widget and data
169
+ emit removing_tool(widget)
170
+ stack = @stacks[data.side]
171
+ raised = stack.current_widget.equal?(widget)
172
+ stack.remove_widget widget
173
+ if stack.empty? then stack.hide
174
+ else raise_tool stack.current_widget
175
+ end
176
+ @button_bars[data.side].remove_tab data.id
177
+ end
178
+
179
+ =begin rdoc
180
+ Raises the tool widget _tool_, which can be either the tool widget itself or its
181
+ <tt>object_name</tt>, either as a string or symbol. If _tool_ is not a tool widget
182
+ (or if no tool widget with that <tt>object_name</tt> exists), nothing is done. If
183
+ _tool_ is a string or symbol and more than one tool widget exist with that <tt>object_name</tt>,
184
+ which one is raised is undefined.
185
+
186
+ <b>Note:</b> this method doesn't make the container of _tool_ visible if it's hidden
187
+ =end
188
+ def raise_tool tool
189
+ tool, data = tool_and_data tool
190
+ return unless tool
191
+ bar = @button_bars[data.side]
192
+ stack = @stacks[data.side]
193
+ old = stack.current_widget
194
+ if old and old.visible?
195
+ store_tool_size old
196
+ old_data = @widgets[old]
197
+ bar.set_tab old_data.id, false
198
+ end
199
+ bar.set_tab data.id, true
200
+ if old != tool
201
+ stack.current_widget = tool
202
+ emit tool_raised(tool)
203
+ emit tool_shown(tool) if stack.visible?
204
+ end
205
+ resize_tool tool
206
+ end
207
+
208
+ =begin rdoc
209
+ Shows the tool widget _tool_. This means that _tool_ will become the current widget
210
+ in its stack and that the stack will become visible (if it's not already visible).
211
+ _tool_ won't receive focus, unless the previously current widget of its stack had
212
+ focus.
213
+
214
+ _tool_ can be either the tool widget itself or its <tt>object_name</tt>, either as
215
+ string or as symbol. In the latter cases, it there's more than one tool widget with
216
+ the same <tt>object_name</tt>, it's undefined which one will be shown.
217
+
218
+ If _tool_ isn't a tool widget, nothing happens.
219
+ =end
220
+ def show_tool tool
221
+ tool, data = tool_and_data tool
222
+ return unless tool
223
+ data = @widgets[tool]
224
+ stack = @stacks[data.side]
225
+ visible = tool.visible?
226
+ give_focus = stack.find_children(Qt::Widget).any?{|w| w.has_focus}
227
+ raise_tool tool
228
+ stack.show unless stack.visible?
229
+ emit tool_shown(tool) unless visible
230
+ tool.set_focus if give_focus
231
+ end
232
+
233
+ =begin rdoc
234
+ Gives focus to the tool widget _tool_ (raising and showing it if necessary). _tool_
235
+ can be either the tool widget itself or its <tt>object_name</tt> (as either a string
236
+ or symbol). If _tool_ doesn't represent a valid tool widget, nothing happens. If
237
+ _tool_ is a string or symbol and more than one tool widget with the same name exists,
238
+ which one will obtain focus is undefined.
239
+ =end
240
+ def activate_tool tool
241
+ tool, data = tool_and_data tool
242
+ return unless tool
243
+ show_tool tool unless tool.visible?
244
+ tool.set_focus
245
+ end
246
+
247
+ =begin rdoc
248
+ <b>Slot</b>
249
+
250
+ Activates the tool _tool_ if it's not visibile and hides its stack if instead it's
251
+ visible.
252
+
253
+ _tool_ can be either the tool widget itself or its <tt>object_name</tt> (as either a string
254
+ or symbol) or the id of the tab associated with the tool widget. If _tool_ doesn't
255
+ represent a valid tool widget, nothing happens. If
256
+ _tool_ is a string or symbol and more than one tool widget with the same name exists,
257
+ which one will obtain focus is undefined.
258
+
259
+ <b>Note:</b> the use of the id of the tab as argument is only for internal use.
260
+ =end
261
+ def toggle_tool tool
262
+ tool, data = tool_and_data tool
263
+ return unless tool
264
+ if !tool.visible? then activate_tool tool
265
+ else hide_tool tool
266
+ end
267
+ end
268
+
269
+ =begin rdoc
270
+ Hides the stack containing the tool widget _tool_, giving focus to the active editor,
271
+ if _tool_ is raised (that is, if it is the current widget of its stack).
272
+
273
+ _tool_ can be either the tool widget itself or its <tt>object_name</tt> (as
274
+ either a string or symbol). If _tool_ doesn't represent a valid tool widget,
275
+ nothing happens. If _tool_ is a string or symbol and more than one tool widget
276
+ with the same name exists, which one will be used is undefined.
277
+ =end
278
+ def hide_tool tool
279
+ tool, data = tool_and_data tool
280
+ return unless tool
281
+ store_tool_size tool if tool.visible?
282
+ stack = tool.parent
283
+ if stack.current_widget == tool
284
+ @button_bars[data.side].set_tab data.id, false
285
+ if stack.visible?
286
+ stack.hide
287
+ Ruber[:main_window].focus_on_editor
288
+ end
289
+ end
290
+ end
291
+
292
+
293
+ =begin rdoc
294
+ Stores the tool widgets size in the configuration manager. It reads the sizes of
295
+ the splitters for the tool widgets which are visible and uses the values stored
296
+ previously for the others.
297
+ =end
298
+ def store_sizes
299
+ @stacks.each_value do |s|
300
+ w = s.current_widget
301
+ next unless w
302
+ store_tool_size w if w.visible?
303
+ end
304
+ Ruber[:config][:workspace, :tools_sizes] = @sizes
305
+ end
306
+
307
+ =begin rdoc
308
+ Returns a hash having all the tool widgets as keys and the side each of them is
309
+ (<tt>:left</tt>, <tt>:right</tt>, <tt>:bottom</tt>) as values.
310
+ =end
311
+ def tool_widgets
312
+ res = {}
313
+ @widgets.each_pair{|w, data| res[w] = data.side}
314
+ res
315
+ end
316
+
317
+ def current_widget side
318
+ @stacks[side].current_widget
319
+ end
320
+
321
+ =begin
322
+ Returns the active tool widget, or *nil* if there's no active tool widget.
323
+ =end
324
+ def active_tool
325
+ fw = KDE::Application.focus_widget
326
+ if @widgets.include? fw then fw
327
+ else @widgets.keys.find{|w| w.find_children(Qt::Widget).include? fw}
328
+ end
329
+ end
330
+
331
+ private
332
+
333
+ =begin rdoc
334
+ Helper method which creates the structure of the workspace (layout, button bars,
335
+ splitters and tab view)
336
+ =end
337
+ def create_skeleton
338
+ self.layout = Qt::GridLayout.new self
339
+ layout.set_contents_margins 0,0,0,0
340
+ layout.vertical_spacing = 0
341
+ %w[left right bottom].each do |side|
342
+ @button_bars[side.to_sym] =
343
+ KDE::MultiTabBar.new(KDE::MultiTabBar.const_get(side.capitalize), self)
344
+ end
345
+ layout.add_widget @button_bars[:left], 0, 0
346
+ layout.add_widget @button_bars[:right], 0, 2
347
+ layout.add_widget @button_bars[:bottom], 1, 0, 1, -1
348
+ v = Qt::Splitter.new Qt::Vertical, self
349
+ h = Qt::Splitter.new Qt::Horizontal, v
350
+ layout.add_widget v, 0,1
351
+ @splitters[:vertical] = v
352
+ @splitters[:horizontal] = h
353
+ [:left, :right, :bottom].each do |s|
354
+ stack = StackedWidget.new{|w| w.hide}
355
+ @stacks[s] = stack
356
+ end
357
+ v.add_widget h
358
+ v.add_widget @stacks[:bottom]
359
+ h.add_widget @stacks[:left]
360
+ @views = KDE::TabWidget.new(h){self.document_mode = true}
361
+ h.add_widget @views
362
+ h.add_widget @stacks[:right]
363
+ end
364
+
365
+ =begin rdoc
366
+ Resizes the splitter where the tool widget _tool_ is so that the size of _tool_
367
+ matches that of the last time it was used. The space needed to do so is taken
368
+ from the editor.
369
+
370
+ If no size is recorded for _tool_, nothing is done.
371
+ =end
372
+ def resize_tool tool
373
+ data = @widgets[tool]
374
+ side = data.side
375
+ caption = @button_bars[side].tab(data.id).text
376
+ size = @sizes[caption] #|| 150
377
+ return unless size
378
+ case side
379
+ when :bottom
380
+ splitter = @splitters[:vertical]
381
+ total = splitter.sizes.sum
382
+ new_sizes = [[total - size, 0].max, size]
383
+ splitter.sizes = new_sizes
384
+ when :left
385
+ splitter = @splitters[:horizontal]
386
+ old_sizes = splitter.sizes
387
+ total = old_sizes[0..1].sum
388
+ new_sizes = [size, [total - size, 0].max, old_sizes[-1]]
389
+ splitter.sizes = new_sizes
390
+ when :right
391
+ splitter = @splitters[:horizontal]
392
+ old_sizes = splitter.sizes
393
+ total = old_sizes[1..-1].sum
394
+ new_sizes = [old_sizes[0], [total - size, 0].max, size]
395
+ splitter.sizes = new_sizes
396
+ end
397
+ end
398
+
399
+ =begin rdoc
400
+ Stores the size of the splitter slot where the tool widget _tool_ is in the
401
+ <tt>@sizes</tt> instance variable.
402
+ =end
403
+ def store_tool_size tool
404
+ data = @widgets[tool]
405
+ side = data.side
406
+ caption = @button_bars[side].tab(data.id).text
407
+ splitter, pos = case side
408
+ when :bottom then [@splitters[:vertical], 1]
409
+ when :left then [@splitters[:horizontal], 0]
410
+ when :right then [@splitters[:horizontal], 2]
411
+ end
412
+ @sizes[caption] = splitter.sizes[pos]
413
+ end
414
+
415
+ =begin rdoc
416
+ Returns an array containing the tool widget corresponding to _arg_ and its data
417
+ (that is, the entry in the <tt>@widgets</tt> hash corresponding to the tool widget).
418
+ _arg_ can be:
419
+ * the tool widget itself
420
+ * a string or symbol containing the <tt>object_name</tt> of the widget
421
+ * an +Integer+ containing the id of the tab associated with the tool widget.
422
+ If a suitable tool widget can't be found (or if _arg_ is of another class), *nil*
423
+ is returned.
424
+ =end
425
+ def tool_and_data arg
426
+ case arg
427
+ when String, Symbol
428
+ name = arg.to_s
429
+ @widgets.find{|w, data| w.object_name == name}
430
+ when Integer
431
+ @widgets.find{|w, data| data.id == arg}
432
+ else
433
+ if arg.is_a? Qt::Widget
434
+ data = @widgets[arg]
435
+ [arg, data] if data
436
+ end
437
+ end
438
+ end
439
+
440
+ end
441
+
442
+ end