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
data/spec/pane_spec.rb
ADDED
|
@@ -0,0 +1,1165 @@
|
|
|
1
|
+
require './spec/common'
|
|
2
|
+
require 'ruber/pane'
|
|
3
|
+
require 'ruber/editor/document'
|
|
4
|
+
|
|
5
|
+
describe Ruber::Pane do
|
|
6
|
+
|
|
7
|
+
class PaneSpecComponentManager < Qt::Object
|
|
8
|
+
extend Forwardable
|
|
9
|
+
signals 'component_loaded(QObject*)', 'unloading_component(QObject*)'
|
|
10
|
+
def_delegators :@data, :[], :<<
|
|
11
|
+
def_delegator :@data, :each, :each_component
|
|
12
|
+
|
|
13
|
+
def initialize parent = nil
|
|
14
|
+
super
|
|
15
|
+
@data = []
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
before do
|
|
21
|
+
@main_window = Qt::Widget.new
|
|
22
|
+
flexmock(Ruber).should_receive(:[]).with(:main_window).and_return(@main_window).by_default
|
|
23
|
+
flexmock(Ruber).should_receive(:[]).with(:components).and_return(PaneSpecComponentManager.new).by_default
|
|
24
|
+
@doc = Ruber::Document.new
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it 'is enumerable' do
|
|
28
|
+
Ruber::Pane.ancestors.should include(QtEnumerable)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
context 'when created with one view' do
|
|
32
|
+
|
|
33
|
+
it 'makes the view child of itself' do
|
|
34
|
+
view = @doc.create_view nil
|
|
35
|
+
pane = Ruber::Pane.new view
|
|
36
|
+
view.parent.should == pane
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
it 'inserts the view in the layout' do
|
|
40
|
+
view = @doc.create_view nil
|
|
41
|
+
pane = Ruber::Pane.new view
|
|
42
|
+
pane.layout.should include(view)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
it 'allows a parent to be specified' do
|
|
46
|
+
view = @doc.create_view nil
|
|
47
|
+
w = Qt::Widget.new
|
|
48
|
+
pane = Ruber::Pane.new view, w
|
|
49
|
+
pane.parent.should == w
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
context 'when created with two panes and an orientation' do
|
|
55
|
+
|
|
56
|
+
before do
|
|
57
|
+
@panes = 2.times.map{Ruber::Pane.new @doc.create_view(nil)}
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
it 'inserts the two panes in a splitter with the given orientation' do
|
|
61
|
+
pane = Ruber::Pane.new Qt::Horizontal, @panes[0], @panes[1]
|
|
62
|
+
splitter = pane.layout.find{|c| c.is_a? Qt::Splitter}
|
|
63
|
+
splitter.should_not be_nil
|
|
64
|
+
splitter.orientation.should == Qt::Horizontal
|
|
65
|
+
splitter.widget(0).should == @panes[0]
|
|
66
|
+
splitter.widget(1).should == @panes[1]
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
it 'makes the panes child of the splitter' do
|
|
70
|
+
pane = Ruber::Pane.new Qt::Horizontal, @panes[0], @panes[1]
|
|
71
|
+
splitter = pane.find_child(Qt::Splitter)
|
|
72
|
+
@panes.each{|p| p.parent.should == splitter}
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
it 'allows a parent to be specified' do
|
|
76
|
+
w = Qt::Widget.new
|
|
77
|
+
pane = Ruber::Pane.new Qt::Horizontal, @panes[0], @panes[1], w
|
|
78
|
+
pane.parent.should == w
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
describe '#single_view?' do
|
|
84
|
+
|
|
85
|
+
it 'returns true if the pane only contains one view' do
|
|
86
|
+
pane = Ruber::Pane.new @doc.create_view(nil)
|
|
87
|
+
pane.single_view?.should be_true
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
it 'returns false if the pane contains two views' do
|
|
91
|
+
views = 2.times.map{@doc.create_view(nil)}
|
|
92
|
+
pane = Ruber::Pane.new Qt::Vertical, views[0], views[1]
|
|
93
|
+
pane.single_view?.should be_false
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
describe '#orientation' do
|
|
99
|
+
|
|
100
|
+
it 'returns nil if the pane contains a single view' do
|
|
101
|
+
pane = Ruber::Pane.new @doc.create_view(nil)
|
|
102
|
+
pane.orientation.should be_nil
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
it 'returns the orientation of the splitter if the pain contains multiple panes' do
|
|
106
|
+
views = 2.times.map{@doc.create_view(nil)}
|
|
107
|
+
pane = Ruber::Pane.new Qt::Vertical, views[0], views[1]
|
|
108
|
+
pane.orientation.should == Qt::Vertical
|
|
109
|
+
pane = Ruber::Pane.new Qt::Horizontal, views[0], views[1]
|
|
110
|
+
pane.orientation.should == Qt::Horizontal
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
describe '#view' do
|
|
116
|
+
|
|
117
|
+
it 'returns the view if the pane contains a single view' do
|
|
118
|
+
view = @doc.create_view(nil)
|
|
119
|
+
pane = Ruber::Pane.new view
|
|
120
|
+
pane.view.should == view
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
it 'returns nil if the pane contains multiple panes' do
|
|
124
|
+
views = 2.times.map{@doc.create_view(nil)}
|
|
125
|
+
pane = Ruber::Pane.new Qt::Vertical, views[0], views[1]
|
|
126
|
+
pane.view.should be_nil
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
describe '#split' do
|
|
132
|
+
|
|
133
|
+
context 'if the pane contains a single view' do
|
|
134
|
+
|
|
135
|
+
before do
|
|
136
|
+
@view = @doc.create_view nil
|
|
137
|
+
@pane = Ruber::Pane.new @view
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
shared_examples_for '#split when the pane contains a single view' do
|
|
141
|
+
|
|
142
|
+
it 'inserts the pane containing each of the views in a splitter with the given orientation' do
|
|
143
|
+
view = @doc.create_view nil
|
|
144
|
+
@pane.split @view, view, Qt::Vertical, @pos
|
|
145
|
+
@pane.single_view?.should be_false
|
|
146
|
+
splitter = @pane.splitter
|
|
147
|
+
splitter.should be_a(Qt::Splitter)
|
|
148
|
+
splitter.orientation.should == Qt::Vertical
|
|
149
|
+
splitter.count.should == 2
|
|
150
|
+
splitter.each{|w| w.should be_a(Ruber::Pane)}
|
|
151
|
+
splitter.widget(@old_idx).view.should == @view
|
|
152
|
+
splitter.widget(@new_idx).view.should == view
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
it 'returns an array with the pane containing the old view as first element and the pane containing the new view as second element' do
|
|
156
|
+
view = @doc.create_view nil
|
|
157
|
+
res = @pane.split @view, view, Qt::Horizontal, @pos
|
|
158
|
+
res[0].should be_a(Ruber::Pane)
|
|
159
|
+
res[0].view.should == @view
|
|
160
|
+
res[1].should be_a(Ruber::Pane)
|
|
161
|
+
res[1].view.should == view
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
it 'hides the label' do
|
|
165
|
+
view = @doc.create_view nil
|
|
166
|
+
label = @pane.instance_variable_get(:@label)
|
|
167
|
+
flexmock(label).should_receive(:hide).once
|
|
168
|
+
@pane.split @view, view, Qt::Horizontal, @pos
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
it 'sets the label of the first pane to the text of the label and shows it' do
|
|
172
|
+
view = @doc.create_view nil
|
|
173
|
+
@pane.label = 'xyz'
|
|
174
|
+
views = [@pane.view, view]
|
|
175
|
+
panes = 2.times.map{|i| Ruber::Pane.new views[i], @pane.splitter}
|
|
176
|
+
flexmock(Ruber::Pane).should_receive(:new).with(views[0], Qt::Splitter).once.and_return panes[0]
|
|
177
|
+
flexmock(Ruber::Pane).should_receive(:new).with(views[1]).once.and_return panes[1]
|
|
178
|
+
label = panes[0].instance_variable_get(:@label)
|
|
179
|
+
flexmock(label).should_receive(:visible=).once.with(true)
|
|
180
|
+
pane = @pane.split(@view, view, Qt::Horizontal, @pos)
|
|
181
|
+
label.text.should == 'xyz'
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
it 'emits the split(QWidget*, QWidget*,QWidget*) signal passing self, the original and the new view as arguments' do
|
|
185
|
+
view = @doc.create_view nil
|
|
186
|
+
mk = flexmock{|m| m.should_receive(:pane_split).once.with(@pane, @view, view)}
|
|
187
|
+
@pane.connect(SIGNAL('pane_split(QWidget*,QWidget*,QWidget*)')){|pn, v1,v2| mk.pane_split pn, v1, v2}
|
|
188
|
+
@pane.split @view, view, Qt::Vertical, @pos
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
context 'and the last argument is :after or missing' do
|
|
194
|
+
before do
|
|
195
|
+
@old_idx = 0
|
|
196
|
+
@new_idx = 1
|
|
197
|
+
@pos = :after
|
|
198
|
+
end
|
|
199
|
+
it_behaves_like '#split when the pane contains a single view'
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
context 'and the last argument is :after or missing' do
|
|
203
|
+
before do
|
|
204
|
+
@old_idx = 1
|
|
205
|
+
@new_idx = 0
|
|
206
|
+
@pos = :before
|
|
207
|
+
end
|
|
208
|
+
it_behaves_like '#split when the pane contains a single view'
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
context 'if the pane already contains a splitter and it has the same orientation passed to the method' do
|
|
214
|
+
|
|
215
|
+
before do
|
|
216
|
+
@views = 2.times.map{@doc.create_view(nil)}
|
|
217
|
+
@panes = @views.map{|v| Ruber::Pane.new v}
|
|
218
|
+
@pane = Ruber::Pane.new Qt::Vertical, @panes[0], @panes[1]
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
shared_examples_for '#split when there\'s already a splitter with the same orientation' do
|
|
222
|
+
|
|
223
|
+
it 'puts the view in a new pane and adds the given view to the splitter after the one specified as second argument' do
|
|
224
|
+
view = @doc.create_view nil
|
|
225
|
+
@pane.split @views[0], view, Qt::Vertical, @pos
|
|
226
|
+
splitter = @pane.find_child(Qt::Splitter)
|
|
227
|
+
splitter.count.should == 3
|
|
228
|
+
pane = splitter.widget(@idx)
|
|
229
|
+
pane.should be_a(Ruber::Pane)
|
|
230
|
+
pane.find_child(Ruber::EditorView).should == view
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
it 'makes the new pane child of the splitter' do
|
|
234
|
+
view = @doc.create_view nil
|
|
235
|
+
@pane.split @views[0], view, Qt::Vertical, @pos
|
|
236
|
+
splitter = @pane.find_child(Qt::Splitter)
|
|
237
|
+
pane = splitter.widget(@idx)
|
|
238
|
+
pane.parent.should == splitter
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
it 'returns an array with the pane containing the old view as first element and the pane containing the new view as second element' do
|
|
242
|
+
view = @doc.create_view nil
|
|
243
|
+
res = @pane.split @views[0], view, Qt::Horizontal, @pos
|
|
244
|
+
res[0].should be_a(Ruber::Pane)
|
|
245
|
+
res[0].view.should == @views[0]
|
|
246
|
+
res[1].should be_a(Ruber::Pane)
|
|
247
|
+
res[1].view.should == view
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
it 'emits the split(QWidget*, QWidget*,QWidget*) signal passing self, the original and the new view as arguments' do
|
|
251
|
+
view = @doc.create_view nil
|
|
252
|
+
mk = flexmock{|m| m.should_receive(:pane_split).once.with(@pane, @views[0], view)}
|
|
253
|
+
@pane.connect(SIGNAL('pane_split(QWidget*,QWidget*,QWidget*)')){|pn, v1,v2| mk.pane_split pn, v1, v2}
|
|
254
|
+
@pane.split @views[0], view, Qt::Vertical, @pos
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
context 'and the last argument is :after or missing' do
|
|
261
|
+
before do
|
|
262
|
+
@idx = 1
|
|
263
|
+
@pos = :after
|
|
264
|
+
end
|
|
265
|
+
it_behaves_like '#split when there\'s already a splitter with the same orientation'
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
context 'and the last argument is :before' do
|
|
269
|
+
before do
|
|
270
|
+
@idx = 0
|
|
271
|
+
@pos = :before
|
|
272
|
+
end
|
|
273
|
+
it_behaves_like '#split when there\'s already a splitter with the same orientation'
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
end
|
|
277
|
+
|
|
278
|
+
context 'if the pane already contains a splitter but it has a different orientation' do
|
|
279
|
+
|
|
280
|
+
before do
|
|
281
|
+
@views = 2.times.map{@doc.create_view(nil)}
|
|
282
|
+
@panes = @views.map{|v| Ruber::Pane.new v}
|
|
283
|
+
@pane = Ruber::Pane.new Qt::Horizontal, @panes[0], @panes[1]
|
|
284
|
+
end
|
|
285
|
+
|
|
286
|
+
shared_examples_for '#split when there\'s already a splitter but it has a different orientation' do
|
|
287
|
+
|
|
288
|
+
it 'puts the two views in a new pane in the position of the existing view' do
|
|
289
|
+
view = @doc.create_view nil
|
|
290
|
+
old_splitter = @pane.find_child(Qt::Splitter)
|
|
291
|
+
@pane.split @views[0], view, Qt::Vertical, @pos
|
|
292
|
+
@pane.find_children(Ruber::Pane).select{|c| c.is_a? Ruber::Pane}.size.should == 4
|
|
293
|
+
old_splitter.count.should == 2
|
|
294
|
+
new_pane = old_splitter.widget 0
|
|
295
|
+
new_pane.should be_a(Ruber::Pane)
|
|
296
|
+
new_pane.should_not be_single_view
|
|
297
|
+
inner_splitter = new_pane.find_child(Qt::Splitter)
|
|
298
|
+
inner_splitter.orientation.should == Qt::Vertical
|
|
299
|
+
inner_splitter.widget(@old_idx).view.should == @views[0]
|
|
300
|
+
inner_splitter.widget(@new_idx).view.should == view
|
|
301
|
+
end
|
|
302
|
+
|
|
303
|
+
it 'returns an array with the pane containing the old view as first element and the pane containing the new view as second element' do
|
|
304
|
+
view = @doc.create_view nil
|
|
305
|
+
res = @pane.split @views[0], view, Qt::Horizontal, @pos
|
|
306
|
+
res[0].should be_a(Ruber::Pane)
|
|
307
|
+
res[0].view.should == @views[0]
|
|
308
|
+
res[1].should be_a(Ruber::Pane)
|
|
309
|
+
res[1].view.should == view
|
|
310
|
+
end
|
|
311
|
+
|
|
312
|
+
it 'emits the split(QWidget*, QWidget*,QWidget*) signal passing self, the original and the new view as arguments' do
|
|
313
|
+
view = @doc.create_view nil
|
|
314
|
+
mk = flexmock{|m| m.should_receive(:pane_split).once.with(@pane, @views[0], view)}
|
|
315
|
+
@pane.connect(SIGNAL('pane_split(QWidget*,QWidget*,QWidget*)')){|pn, v1,v2| mk.pane_split pn, v1, v2}
|
|
316
|
+
@pane.split @views[0], view, Qt::Vertical, @pos
|
|
317
|
+
end
|
|
318
|
+
|
|
319
|
+
|
|
320
|
+
end
|
|
321
|
+
|
|
322
|
+
context 'and the last argument is :after or missing' do
|
|
323
|
+
before do
|
|
324
|
+
@old_idx = 0
|
|
325
|
+
@new_idx = 1
|
|
326
|
+
@pos = :after
|
|
327
|
+
end
|
|
328
|
+
it_behaves_like '#split when there\'s already a splitter but it has a different orientation'
|
|
329
|
+
end
|
|
330
|
+
|
|
331
|
+
context 'and the last argument is :before' do
|
|
332
|
+
before do
|
|
333
|
+
@old_idx = 1
|
|
334
|
+
@new_idx = 0
|
|
335
|
+
@pos = :before
|
|
336
|
+
end
|
|
337
|
+
it_behaves_like '#split when there\'s already a splitter but it has a different orientation'
|
|
338
|
+
end
|
|
339
|
+
|
|
340
|
+
end
|
|
341
|
+
|
|
342
|
+
context 'if the given view is not directly contained in the pane' do
|
|
343
|
+
|
|
344
|
+
it 'does nothing and returns nil if the view isn\'t contained in any of the children panes' do
|
|
345
|
+
doc = Ruber::Document.new
|
|
346
|
+
views = 5.times.map{doc.create_view}
|
|
347
|
+
pane = Ruber::Pane.new(views[0])
|
|
348
|
+
pane.split views[0], views[1], Qt::Horizontal, :after
|
|
349
|
+
panes = pane.split views[0], views[2], Qt::Vertical, :after
|
|
350
|
+
pane.split(views[3], views[4], Qt::Horizontal, :after).should be_nil
|
|
351
|
+
pane.find_children(Ruber::EditorView).find{|v| v == views[4]}.should be_nil
|
|
352
|
+
end
|
|
353
|
+
|
|
354
|
+
it 'calls the same method of the pane containing the view' do
|
|
355
|
+
doc = Ruber::Document.new
|
|
356
|
+
views = 4.times.map{doc.create_view}
|
|
357
|
+
pane = Ruber::Pane.new(views[0])
|
|
358
|
+
pane.split views[0], views[1], Qt::Horizontal, :after
|
|
359
|
+
panes = pane.split views[0], views[2], Qt::Vertical, :after
|
|
360
|
+
flexmock(panes[1].parent.parent).should_receive(:split).with(views[2], views[3], Qt::Vertical, :after).once
|
|
361
|
+
pane.split views[2], views[3], Qt::Vertical, :after
|
|
362
|
+
end
|
|
363
|
+
|
|
364
|
+
it 'emits the split(QWidget*, QWidget*,QWidget*) signal passing the pane where the view was contained, the original and the new view as arguments' do
|
|
365
|
+
doc = Ruber::Document.new
|
|
366
|
+
views = 4.times.map{doc.create_view}
|
|
367
|
+
pane = Ruber::Pane.new(views[0])
|
|
368
|
+
pane.split views[0], views[1], Qt::Horizontal, :after
|
|
369
|
+
panes = pane.split views[0], views[2], Qt::Vertical, :after
|
|
370
|
+
mk = flexmock{|m| m.should_receive(:pane_split).once.with(panes[1].parent.parent, views[2], views[3])}
|
|
371
|
+
pane.connect(SIGNAL('pane_split(QWidget*,QWidget*,QWidget*)')){|pn, v1,v2| mk.pane_split pn, v1, v2}
|
|
372
|
+
pane.split views[2], views[3], Qt::Vertical, :after
|
|
373
|
+
end
|
|
374
|
+
|
|
375
|
+
end
|
|
376
|
+
|
|
377
|
+
end
|
|
378
|
+
|
|
379
|
+
context 'when a view contained in it emits the closing signal' do
|
|
380
|
+
|
|
381
|
+
context 'if the pane is in single view mode' do
|
|
382
|
+
|
|
383
|
+
it 'calls the remove_view method' do
|
|
384
|
+
doc = Ruber::Document.new
|
|
385
|
+
view = doc.create_view nil
|
|
386
|
+
pane = Ruber::Pane.new view
|
|
387
|
+
flexmock(pane).should_receive(:remove_view).once.with(view)
|
|
388
|
+
view.instance_eval{emit closing self}
|
|
389
|
+
end
|
|
390
|
+
|
|
391
|
+
it 'emits the removing_view(QWidget*,QWidget*) signal passing self and the view as arguments' do
|
|
392
|
+
doc = Ruber::Document.new
|
|
393
|
+
view = doc.create_view nil
|
|
394
|
+
pane = Ruber::Pane.new view
|
|
395
|
+
mk = flexmock{|m| m.should_receive(:removing_view).with(pane, view).once}
|
|
396
|
+
pane.connect(SIGNAL('removing_view(QWidget*,QWidget*)')){|pn, v| mk.removing_view pn, v}
|
|
397
|
+
view.instance_eval{emit closing self}
|
|
398
|
+
end
|
|
399
|
+
|
|
400
|
+
end
|
|
401
|
+
|
|
402
|
+
context 'if the pane is in multiple view mode' do
|
|
403
|
+
|
|
404
|
+
it 'does not attempt to remove the view' do
|
|
405
|
+
doc = Ruber::Document.new
|
|
406
|
+
views = 3.times.map{doc.create_view nil}
|
|
407
|
+
pane = Ruber::Pane.new views[0]
|
|
408
|
+
1.upto(2){|i| pane.split views[i-1], views[i], Qt::Vertical}
|
|
409
|
+
flexmock(pane).should_receive(:remove_view).never
|
|
410
|
+
views[0].instance_eval{emit closing self}
|
|
411
|
+
end
|
|
412
|
+
|
|
413
|
+
it 'emits the removing_view(QWidget*,QWidget*) signal passing the pane containing the view and the view itself as arguments' do
|
|
414
|
+
doc = Ruber::Document.new
|
|
415
|
+
views = 3.times.map{doc.create_view nil}
|
|
416
|
+
pane = Ruber::Pane.new views[0]
|
|
417
|
+
1.upto(2){|i| pane.split views[i-1], views[i], Qt::Vertical}
|
|
418
|
+
mk = flexmock{|m| m.should_receive(:removing_view).with(views[0].parent, views[0]).once}
|
|
419
|
+
pane.connect(SIGNAL('removing_view(QWidget*,QWidget*)')){|pn, v| mk.removing_view pn, v}
|
|
420
|
+
views[0].instance_eval{emit closing self}
|
|
421
|
+
end
|
|
422
|
+
|
|
423
|
+
end
|
|
424
|
+
|
|
425
|
+
end
|
|
426
|
+
|
|
427
|
+
describe '#remove_view' do
|
|
428
|
+
|
|
429
|
+
before do
|
|
430
|
+
@doc = Ruber::Document.new
|
|
431
|
+
@view = @doc.create_view nil
|
|
432
|
+
@pane = Ruber::Pane.new @view
|
|
433
|
+
flexmock(@pane).should_receive(:delete_later).by_default
|
|
434
|
+
end
|
|
435
|
+
|
|
436
|
+
it 'emits the closing_last_view signal passing self as argument' do
|
|
437
|
+
mk = flexmock{|m| m.should_receive(:closing_last_view).once.with(@pane)}
|
|
438
|
+
@pane.connect(SIGNAL('closing_last_view(QWidget*)')){|w| mk.closing_last_view w}
|
|
439
|
+
@pane.send :remove_view, @view
|
|
440
|
+
end
|
|
441
|
+
|
|
442
|
+
it 'sets the view\'s parent to nil' do
|
|
443
|
+
@pane.send :remove_view, @view
|
|
444
|
+
@view.parent.should be_nil
|
|
445
|
+
end
|
|
446
|
+
|
|
447
|
+
it 'deletes the pane' do
|
|
448
|
+
flexmock(@pane).should_receive(:delete_later).once
|
|
449
|
+
@pane.send :remove_view, @view
|
|
450
|
+
end
|
|
451
|
+
|
|
452
|
+
end
|
|
453
|
+
|
|
454
|
+
context 'when a child pane emits the closing_last_view signal' do
|
|
455
|
+
|
|
456
|
+
before do
|
|
457
|
+
@doc = Ruber::Document.new
|
|
458
|
+
@views = 3.times.map{@doc.create_view}
|
|
459
|
+
end
|
|
460
|
+
|
|
461
|
+
it 'does nothing if the pane isn\'t directly contained in the pane' do
|
|
462
|
+
@pane = Ruber::Pane.new Qt::Vertical, Ruber::Pane.new(@views[0]), Ruber::Pane.new(@views[1])
|
|
463
|
+
child_pane = @pane.split( @views[1], @views[2], Qt::Horizontal)[1]
|
|
464
|
+
flexmock(@pane).should_receive(:remove_pane).never
|
|
465
|
+
child_pane.instance_eval{emit closing_last_view(self)}
|
|
466
|
+
end
|
|
467
|
+
|
|
468
|
+
context 'when only one pane remains' do
|
|
469
|
+
|
|
470
|
+
context 'and that pane contains a single view' do
|
|
471
|
+
|
|
472
|
+
before do
|
|
473
|
+
@pane = Ruber::Pane.new @views[0]
|
|
474
|
+
@panes = @pane.split @views[0], @views[1], Qt::Vertical
|
|
475
|
+
end
|
|
476
|
+
|
|
477
|
+
it 'switches to single view mode containing the view of the remaining pane if the latter is in single view mode' do
|
|
478
|
+
@panes[0].instance_eval{emit closing_last_view(self)}
|
|
479
|
+
@pane.should be_single_view
|
|
480
|
+
@pane.view.should == @views[1]
|
|
481
|
+
end
|
|
482
|
+
|
|
483
|
+
it 'uses the label of the remaining pane as its own label' do
|
|
484
|
+
@panes[1].label = 'xyz'
|
|
485
|
+
@panes[0].instance_eval{emit closing_last_view(self)}
|
|
486
|
+
@pane.label.should == 'xyz'
|
|
487
|
+
end
|
|
488
|
+
|
|
489
|
+
it 'displays the label unless the pane is s top level' do
|
|
490
|
+
view = @doc.create_view
|
|
491
|
+
panes = @panes[0].split @views[0], view, Qt::Vertical
|
|
492
|
+
panes[1].label = 'xyz'
|
|
493
|
+
label = @panes[0].instance_variable_get(:@label)
|
|
494
|
+
flexmock(label).should_receive(:visible=).with(true).once
|
|
495
|
+
panes[0].instance_eval{emit closing_last_view(self)}
|
|
496
|
+
end
|
|
497
|
+
|
|
498
|
+
it 'hides the label if it\'s a top level pane' do
|
|
499
|
+
label = @pane.instance_variable_get(:@label)
|
|
500
|
+
flexmock(label).should_receive(:visible=).with(false).once
|
|
501
|
+
@panes[1].label = 'xyz'
|
|
502
|
+
@panes[0].instance_eval{emit closing_last_view(self)}
|
|
503
|
+
end
|
|
504
|
+
|
|
505
|
+
it 'hides the label if the text is empty' do
|
|
506
|
+
view = @doc.create_view
|
|
507
|
+
panes = @panes[0].split @views[0], view, Qt::Vertical
|
|
508
|
+
panes[1].label = ''
|
|
509
|
+
label = @panes[0].instance_variable_get(:@label)
|
|
510
|
+
flexmock(label).should_receive(:visible=).with(false).once
|
|
511
|
+
panes[0].instance_eval{emit closing_last_view(self)}
|
|
512
|
+
end
|
|
513
|
+
|
|
514
|
+
it 'calls the delete_later method of the remaining pane' do
|
|
515
|
+
flexmock(@panes[1]).should_receive(:delete_later).once
|
|
516
|
+
@panes[0].instance_eval{emit closing_last_view(self)}
|
|
517
|
+
end
|
|
518
|
+
|
|
519
|
+
end
|
|
520
|
+
|
|
521
|
+
context 'and that pane contains more than one view' do
|
|
522
|
+
|
|
523
|
+
before do
|
|
524
|
+
@views << @doc.create_view << @doc.create_view
|
|
525
|
+
@pane = Ruber::Pane.new @views[0]
|
|
526
|
+
@closing_pane, @remaining_pane = @pane.split @views[0], @views[1], Qt::Vertical
|
|
527
|
+
@remaining_pane.split @views[1], @views[2], Qt::Horizontal
|
|
528
|
+
@remaining_pane.split @views[2], @views[3], Qt::Horizontal
|
|
529
|
+
end
|
|
530
|
+
|
|
531
|
+
it 'removes the remaining pane from the splitter' do
|
|
532
|
+
@closing_pane.instance_eval{emit closing_last_view self}
|
|
533
|
+
@pane.splitter.children.select{|c| c.is_a?(Ruber::Pane)}.should_not include(@remaining_pane)
|
|
534
|
+
end
|
|
535
|
+
|
|
536
|
+
it 'makes all the children panes its own children' do
|
|
537
|
+
@closing_pane.instance_eval{emit closing_last_view self}
|
|
538
|
+
@pane.should_not be_single_view
|
|
539
|
+
@pane.splitter.count.should == 3
|
|
540
|
+
@pane.splitter.widget(0).view.should == @views[1]
|
|
541
|
+
@pane.splitter.widget(1).view.should == @views[2]
|
|
542
|
+
@pane.splitter.widget(2).view.should == @views[3]
|
|
543
|
+
end
|
|
544
|
+
|
|
545
|
+
it 'calls the delete_later method of the remaining pane' do
|
|
546
|
+
flexmock(@remaining_pane).should_receive(:delete_later).once
|
|
547
|
+
@closing_pane.instance_eval{emit closing_last_view(self)}
|
|
548
|
+
end
|
|
549
|
+
|
|
550
|
+
end
|
|
551
|
+
|
|
552
|
+
end
|
|
553
|
+
|
|
554
|
+
context 'when more than one pane remains' do
|
|
555
|
+
|
|
556
|
+
it 'removes the pane from the splitter' do
|
|
557
|
+
@pane = Ruber::Pane.new @views[0]
|
|
558
|
+
@pane.split @views[0], @views[1], Qt::Vertical
|
|
559
|
+
pane_to_delete = @pane.split( @views[1], @views[2], Qt::Vertical)[1]
|
|
560
|
+
pane_to_delete.instance_eval{emit closing_last_view(self)}
|
|
561
|
+
pane_to_delete.parent.should be_nil
|
|
562
|
+
end
|
|
563
|
+
|
|
564
|
+
it 'doesn\'t alter anything else' do
|
|
565
|
+
@pane = Ruber::Pane.new @views[0]
|
|
566
|
+
@pane.split @views[0], @views[1], Qt::Vertical
|
|
567
|
+
panes = @pane.split @views[1], @views[2], Qt::Vertical
|
|
568
|
+
panes[0].instance_eval{emit closing_last_view self}
|
|
569
|
+
@pane.splitter.count.should == 2
|
|
570
|
+
@pane.splitter.widget(0).view.should == @views[0]
|
|
571
|
+
@pane.splitter.widget(1).view.should == @views[2]
|
|
572
|
+
end
|
|
573
|
+
|
|
574
|
+
end
|
|
575
|
+
|
|
576
|
+
end
|
|
577
|
+
|
|
578
|
+
describe '#each_pane' do
|
|
579
|
+
|
|
580
|
+
before do
|
|
581
|
+
@doc = Ruber::Document.new
|
|
582
|
+
@views = 4.times.map{@doc.create_view}
|
|
583
|
+
@pane = Ruber::Pane.new @views[0]
|
|
584
|
+
end
|
|
585
|
+
|
|
586
|
+
context 'when called with no argument' do
|
|
587
|
+
|
|
588
|
+
it 'iterates on all panes which are direct child of the pane' do
|
|
589
|
+
panes = []
|
|
590
|
+
panes += @pane.split @views[0], @views[1], Qt::Vertical
|
|
591
|
+
panes += @pane.split @views[1], @views[2], Qt::Vertical
|
|
592
|
+
@pane.split @views[1], @views[3], Qt::Horizontal
|
|
593
|
+
panes.uniq!
|
|
594
|
+
res = []
|
|
595
|
+
@pane.each_pane{|i| res << i}
|
|
596
|
+
res.should == panes
|
|
597
|
+
end
|
|
598
|
+
|
|
599
|
+
it 'does nothing if the pane is in single view mode' do
|
|
600
|
+
res = []
|
|
601
|
+
@pane.each_pane{|w| res << w}
|
|
602
|
+
res.should be_empty
|
|
603
|
+
end
|
|
604
|
+
|
|
605
|
+
it 'returns self if called with a block' do
|
|
606
|
+
@pane.each_pane{|w| w}.should == @pane
|
|
607
|
+
@pane.split @views[0], @views[1], Qt::Vertical
|
|
608
|
+
@pane.each_pane{|w| w}.should == @pane
|
|
609
|
+
end
|
|
610
|
+
|
|
611
|
+
it 'returns an enumerable if called without a block' do
|
|
612
|
+
panes = @pane.split @views[0], @views[1], Qt::Vertical
|
|
613
|
+
res = []
|
|
614
|
+
en = @pane.each_pane
|
|
615
|
+
en.should be_an(Enumerator)
|
|
616
|
+
en.each{|w| res << w}
|
|
617
|
+
res.should == panes
|
|
618
|
+
end
|
|
619
|
+
|
|
620
|
+
end
|
|
621
|
+
|
|
622
|
+
context 'when called with the :recursive argument' do
|
|
623
|
+
|
|
624
|
+
it 'iterates on all panes, recursively' do
|
|
625
|
+
panes = []
|
|
626
|
+
panes += @pane.split @views[0], @views[1], Qt::Vertical
|
|
627
|
+
panes += @pane.split @views[1], @views[2], Qt::Vertical
|
|
628
|
+
panes.uniq!
|
|
629
|
+
temp = @pane.split @views[1], @views[3], Qt::Horizontal
|
|
630
|
+
panes.insert 2, temp[0]
|
|
631
|
+
panes.insert 3, temp[1]
|
|
632
|
+
panes.uniq!
|
|
633
|
+
res = []
|
|
634
|
+
@pane.each_pane(:recursive){|i| res << i}
|
|
635
|
+
res.should == panes
|
|
636
|
+
end
|
|
637
|
+
|
|
638
|
+
it 'does nothing if the pane is in single view mode' do
|
|
639
|
+
res = []
|
|
640
|
+
@pane.each_pane(:recursive){|w| res << w}
|
|
641
|
+
res.should be_empty
|
|
642
|
+
end
|
|
643
|
+
|
|
644
|
+
it 'returns self if called with a block' do
|
|
645
|
+
@pane.each_pane(:recursive){|w| w}.should == @pane
|
|
646
|
+
@pane.split @views[0], @views[1], Qt::Vertical
|
|
647
|
+
@pane.each_pane(:recursive){|w| w}.should == @pane
|
|
648
|
+
end
|
|
649
|
+
|
|
650
|
+
it 'returns an enumerator which iterates on all child panes recursively if called without a block' do
|
|
651
|
+
panes = []
|
|
652
|
+
panes += @pane.split @views[0], @views[1], Qt::Vertical
|
|
653
|
+
panes += @pane.split @views[1], @views[2], Qt::Vertical
|
|
654
|
+
panes.uniq!
|
|
655
|
+
temp = @pane.split @views[1], @views[3], Qt::Horizontal
|
|
656
|
+
panes.insert 2, temp[0]
|
|
657
|
+
panes.insert 3, temp[1]
|
|
658
|
+
panes.uniq!
|
|
659
|
+
res = []
|
|
660
|
+
en = @pane.each_pane(:recursive)
|
|
661
|
+
en.should be_an(Enumerator)
|
|
662
|
+
en.each{|i| res << i}
|
|
663
|
+
res.should == panes
|
|
664
|
+
end
|
|
665
|
+
|
|
666
|
+
end
|
|
667
|
+
|
|
668
|
+
end
|
|
669
|
+
|
|
670
|
+
describe '#each_view' do
|
|
671
|
+
|
|
672
|
+
before do
|
|
673
|
+
@doc = Ruber::Document.new
|
|
674
|
+
@views = 4.times.map{@doc.create_view}
|
|
675
|
+
@pane = Ruber::Pane.new @views[0]
|
|
676
|
+
end
|
|
677
|
+
|
|
678
|
+
it 'calls iterates over all views contained in the pane' do
|
|
679
|
+
@pane.split @views[0], @views[1], Qt::Vertical
|
|
680
|
+
@pane.split @views[1], @views[2], Qt::Vertical
|
|
681
|
+
@pane.split @views[1], @views[3], Qt::Horizontal
|
|
682
|
+
res = []
|
|
683
|
+
@pane.each_view{|v| res << v}
|
|
684
|
+
res.should == [@views[0], @views[1], @views[3], @views[2]]
|
|
685
|
+
end
|
|
686
|
+
|
|
687
|
+
it 'yields the single view contained in the pane if the pane is in single view mode' do
|
|
688
|
+
res = []
|
|
689
|
+
@pane.each_view{|v| res << v}
|
|
690
|
+
res.should == [@views[0]]
|
|
691
|
+
end
|
|
692
|
+
|
|
693
|
+
it 'returns self' do
|
|
694
|
+
@pane.each_view{}.should == @pane
|
|
695
|
+
@pane.split @views[0], @views[1], Qt::Vertical
|
|
696
|
+
@pane.split @views[1], @views[2], Qt::Vertical
|
|
697
|
+
@pane.split @views[1], @views[3], Qt::Horizontal
|
|
698
|
+
@pane.each_view{}.should == @pane
|
|
699
|
+
end
|
|
700
|
+
|
|
701
|
+
it 'returns an enumerator which iterates on all views if no block is given' do
|
|
702
|
+
en = @pane.each_view
|
|
703
|
+
en.should be_an(Enumerator)
|
|
704
|
+
res_single = []
|
|
705
|
+
en.each{|v| res_single << v}
|
|
706
|
+
@pane.split @views[0], @views[1], Qt::Vertical
|
|
707
|
+
@pane.split @views[1], @views[2], Qt::Vertical
|
|
708
|
+
@pane.split @views[1], @views[3], Qt::Horizontal
|
|
709
|
+
en = @pane.each_view
|
|
710
|
+
en.should be_an(Enumerator)
|
|
711
|
+
res_multi = []
|
|
712
|
+
en.each{|v| res_multi << v}
|
|
713
|
+
res_single.should == [@views[0]]
|
|
714
|
+
res_multi.should == [@views[0], @views[1], @views[3], @views[2]]
|
|
715
|
+
end
|
|
716
|
+
|
|
717
|
+
end
|
|
718
|
+
|
|
719
|
+
describe '#parent_pane' do
|
|
720
|
+
|
|
721
|
+
before do
|
|
722
|
+
@doc = Ruber::Document.new
|
|
723
|
+
@views = 4.times.map{@doc.create_view}
|
|
724
|
+
@pane = Ruber::Pane.new @views[0]
|
|
725
|
+
end
|
|
726
|
+
|
|
727
|
+
it 'returns nil if the pane is a toplevel widget' do
|
|
728
|
+
@pane.parent_pane.should be_nil
|
|
729
|
+
end
|
|
730
|
+
|
|
731
|
+
it 'returns nil if the pane\'s parent is not a Qt::Splitter' do
|
|
732
|
+
w = Qt::Widget.new
|
|
733
|
+
@pane.parent = w
|
|
734
|
+
@pane.parent_pane.should be_nil
|
|
735
|
+
end
|
|
736
|
+
|
|
737
|
+
it 'returns nil if the pane\'s gandparent is not a Pane' do
|
|
738
|
+
w = Qt::Widget.new
|
|
739
|
+
s = Qt::Splitter.new w
|
|
740
|
+
s.add_widget @pane
|
|
741
|
+
@pane.parent_pane.should be_nil
|
|
742
|
+
end
|
|
743
|
+
|
|
744
|
+
it 'returns the pane\'s grandparent if it\'s a Pane' do
|
|
745
|
+
panes = @pane.split @views[0], @views[1], Qt::Horizontal
|
|
746
|
+
panes[0].parent_pane.should == @pane
|
|
747
|
+
end
|
|
748
|
+
|
|
749
|
+
end
|
|
750
|
+
|
|
751
|
+
describe '#contains?' do
|
|
752
|
+
|
|
753
|
+
before do
|
|
754
|
+
@doc = Ruber::Document.new
|
|
755
|
+
@views = 4.times.map{@doc.create_view}
|
|
756
|
+
@pane = Ruber::Pane.new @views[0]
|
|
757
|
+
end
|
|
758
|
+
|
|
759
|
+
context 'when called with one argument' do
|
|
760
|
+
|
|
761
|
+
context 'and the argument is a pane' do
|
|
762
|
+
|
|
763
|
+
it 'returns true if this pane contains, directly or not, the one given as argument' do
|
|
764
|
+
panes = @pane.split @views[0], @views[1], Qt::Vertical
|
|
765
|
+
@pane.contain?(panes[0]).should be_true
|
|
766
|
+
panes = @pane.split @views[1], @views[2], Qt::Horizontal
|
|
767
|
+
@pane.contain?(panes[1]).should be_true
|
|
768
|
+
end
|
|
769
|
+
|
|
770
|
+
it 'returns false if this pane doesn\'t contain the one given as argument' do
|
|
771
|
+
pane = Ruber::Pane.new @views[2]
|
|
772
|
+
@pane.contain?(pane).should be_false
|
|
773
|
+
end
|
|
774
|
+
|
|
775
|
+
end
|
|
776
|
+
|
|
777
|
+
context 'and the argument is a view' do
|
|
778
|
+
|
|
779
|
+
it 'returns true if the pane contains, directly or not, the view' do
|
|
780
|
+
@pane.contain?(@views[0]).should be_true
|
|
781
|
+
@pane.split @views[0], @views[1], Qt::Vertical
|
|
782
|
+
@pane.split @views[1], @views[2], Qt::Horizontal
|
|
783
|
+
@pane.contain?(@views[2]).should be_true
|
|
784
|
+
end
|
|
785
|
+
|
|
786
|
+
it 'returns vale if this pane doesn\'t contain the view' do
|
|
787
|
+
@pane.contain?(@views[2]).should be_false
|
|
788
|
+
end
|
|
789
|
+
|
|
790
|
+
end
|
|
791
|
+
|
|
792
|
+
end
|
|
793
|
+
|
|
794
|
+
context 'when called with two arguments' do
|
|
795
|
+
|
|
796
|
+
context 'and the first argument is a pane' do
|
|
797
|
+
|
|
798
|
+
it 'returns true if this pane directly contains the one given as argument' do
|
|
799
|
+
panes = @pane.split @views[0], @views[1], Qt::Vertical
|
|
800
|
+
@pane.contain?(panes[0], :directly).should be_true
|
|
801
|
+
end
|
|
802
|
+
|
|
803
|
+
it 'returns false if this pane doesn\'t contain the one given as argument' do
|
|
804
|
+
pane = Ruber::Pane.new @views[2]
|
|
805
|
+
@pane.contain?(pane, :directly).should be_false
|
|
806
|
+
end
|
|
807
|
+
|
|
808
|
+
it 'returns false if this pane contains the one given as argument indirectly' do
|
|
809
|
+
panes = @pane.split @views[0], @views[1], Qt::Vertical
|
|
810
|
+
panes = @pane.split @views[1], @views[2], Qt::Horizontal
|
|
811
|
+
@pane.contain?(panes[1], :directly).should be_false
|
|
812
|
+
end
|
|
813
|
+
|
|
814
|
+
end
|
|
815
|
+
|
|
816
|
+
end
|
|
817
|
+
|
|
818
|
+
context 'and the second argument is a view' do
|
|
819
|
+
|
|
820
|
+
it 'returns true if this pane directly contains the view' do
|
|
821
|
+
@pane.contain?(@views[0], :directly).should be_true
|
|
822
|
+
end
|
|
823
|
+
|
|
824
|
+
it 'returns false if this pane doesn\'t contain the view' do
|
|
825
|
+
@pane.contain?(@views[1], :directly).should be_false
|
|
826
|
+
end
|
|
827
|
+
|
|
828
|
+
it 'returns false if this pane contains the one given as argument indirectly' do
|
|
829
|
+
panes = @pane.split @views[0], @views[1], Qt::Vertical
|
|
830
|
+
panes = @pane.split @views[1], @views[2], Qt::Horizontal
|
|
831
|
+
@pane.contain?(@views[2], :directly).should be_false
|
|
832
|
+
end
|
|
833
|
+
|
|
834
|
+
end
|
|
835
|
+
|
|
836
|
+
end
|
|
837
|
+
|
|
838
|
+
describe '#set_view_label' do
|
|
839
|
+
|
|
840
|
+
context 'when the pane is in single view mode' do
|
|
841
|
+
|
|
842
|
+
it 'displays a label containing the given text if the contained view matches the first argument' do
|
|
843
|
+
view1 = @doc.create_view
|
|
844
|
+
view2 = @doc.create_view
|
|
845
|
+
outer_pane = Ruber::Pane.new view1
|
|
846
|
+
pane = outer_pane.split(view1, view2, Qt::Horizontal)[0]
|
|
847
|
+
text = 'xyz'
|
|
848
|
+
flexmock(pane.instance_variable_get(:@label)).should_receive(:visible=).once.with true
|
|
849
|
+
pane.set_view_label view1, text
|
|
850
|
+
label = pane.layout.item_at(1).widget
|
|
851
|
+
label.should be_a(Qt::Label)
|
|
852
|
+
label.text.should == text
|
|
853
|
+
end
|
|
854
|
+
|
|
855
|
+
it 'hides the label if the text is empty and the view matches the first argument' do
|
|
856
|
+
view1 = @doc.create_view
|
|
857
|
+
view2 = @doc.create_view
|
|
858
|
+
outer_pane = Ruber::Pane.new view1
|
|
859
|
+
pane = outer_pane.split(view1, view2, Qt::Horizontal)[0]
|
|
860
|
+
label = pane.instance_variable_get(:@label)
|
|
861
|
+
label.text = 'xyz'
|
|
862
|
+
flexmock(pane.instance_variable_get(:@label)).should_receive(:visible=).once.with false
|
|
863
|
+
pane.set_view_label view1, ''
|
|
864
|
+
label.text.should == ''
|
|
865
|
+
end
|
|
866
|
+
|
|
867
|
+
it 'does nothing if the view argument isn\'t the same view contained in the pane' do
|
|
868
|
+
view1 = @doc.create_view
|
|
869
|
+
view2 = @doc.create_view
|
|
870
|
+
view3 = @doc.create_view
|
|
871
|
+
outer_pane = Ruber::Pane.new view1
|
|
872
|
+
pane = outer_pane.split(view1, view2, Qt::Horizontal)[0]
|
|
873
|
+
label = pane.instance_variable_get(:@label)
|
|
874
|
+
orig_text = 'abc'
|
|
875
|
+
label.text = orig_text
|
|
876
|
+
flexmock(label).should_receive(:visible=).never
|
|
877
|
+
text = 'xyz'
|
|
878
|
+
pane.set_view_label view3, text
|
|
879
|
+
label.text.should == orig_text
|
|
880
|
+
end
|
|
881
|
+
|
|
882
|
+
it 'changes the label text but doesn\'t display the label if the pane is a top-level pane' do
|
|
883
|
+
view = @doc.create_view
|
|
884
|
+
parent = Qt::Widget.new
|
|
885
|
+
pane = Ruber::Pane.new view, parent
|
|
886
|
+
pane.set_view_label view, 'text'
|
|
887
|
+
label = pane.instance_variable_get(:@label)
|
|
888
|
+
flexmock(label).should_receive(:visible=).never
|
|
889
|
+
text = 'xyz'
|
|
890
|
+
pane.set_view_label view, text
|
|
891
|
+
label.text.should == text
|
|
892
|
+
end
|
|
893
|
+
|
|
894
|
+
it 'returns true if the view argument is the same view contained in the pane' do
|
|
895
|
+
view1 = @doc.create_view
|
|
896
|
+
view2 = @doc.create_view
|
|
897
|
+
outer_pane = Ruber::Pane.new view1
|
|
898
|
+
pane = outer_pane.split(view1, view2, Qt::Horizontal)[0]
|
|
899
|
+
text = 'xyz'
|
|
900
|
+
pane.set_view_label( view1, text).should be_true
|
|
901
|
+
pane = Ruber::Pane.new view1
|
|
902
|
+
pane.set_view_label(view1, text).should be_true
|
|
903
|
+
end
|
|
904
|
+
|
|
905
|
+
it 'returns false if the view argument is different from the view contained in the pane' do
|
|
906
|
+
view1 = @doc.create_view
|
|
907
|
+
view2 = @doc.create_view
|
|
908
|
+
outer_pane = Ruber::Pane.new view1
|
|
909
|
+
pane = outer_pane.split(view1, view2, Qt::Horizontal)[0]
|
|
910
|
+
text = 'xyz'
|
|
911
|
+
pane.set_view_label( view2, text).should be_false
|
|
912
|
+
pane = Ruber::Pane.new view1
|
|
913
|
+
pane.set_view_label(view2, text).should be_false
|
|
914
|
+
end
|
|
915
|
+
|
|
916
|
+
end
|
|
917
|
+
|
|
918
|
+
context 'when the pane is in multiple view mode' do
|
|
919
|
+
|
|
920
|
+
it 'calls the same method on all child panes until one of them returns true' do
|
|
921
|
+
views = 3.times.map{@doc.create_view}
|
|
922
|
+
outer_pane = Ruber::Pane.new views[0]
|
|
923
|
+
panes = outer_pane.split(views[0], views[1], Qt::Horizontal)
|
|
924
|
+
panes << outer_pane.split(views[1], views[2], Qt::Horizontal)[1]
|
|
925
|
+
text = 'xyz'
|
|
926
|
+
flexmock(panes[0]).should_receive(:set_view_label).with(views[1], text).once.and_return false
|
|
927
|
+
flexmock(panes[1]).should_receive(:set_view_label).with(views[1], text).once.and_return true
|
|
928
|
+
flexmock(panes[2]).should_receive(:set_view_label).never
|
|
929
|
+
outer_pane.set_view_label views[1], text
|
|
930
|
+
end
|
|
931
|
+
|
|
932
|
+
it 'returns true if one of the child panels\' set_view_label methods returns true' do
|
|
933
|
+
views = 3.times.map{@doc.create_view}
|
|
934
|
+
outer_pane = Ruber::Pane.new views[0]
|
|
935
|
+
panes = outer_pane.split(views[0], views[1], Qt::Horizontal)
|
|
936
|
+
panes << outer_pane.split(views[1], views[2], Qt::Horizontal)[1]
|
|
937
|
+
text = 'xyz'
|
|
938
|
+
flexmock(panes[0]).should_receive(:set_view_label).with(views[1], text).once.and_return false
|
|
939
|
+
flexmock(panes[1]).should_receive(:set_view_label).with(views[1], text).once.and_return true
|
|
940
|
+
flexmock(panes[2]).should_receive(:set_view_label).never
|
|
941
|
+
outer_pane.set_view_label(views[1], text).should be_true
|
|
942
|
+
end
|
|
943
|
+
|
|
944
|
+
it 'returns false if all the child panels\'s set_view_label methods return false' do
|
|
945
|
+
views = 4.times.map{@doc.create_view}
|
|
946
|
+
outer_pane = Ruber::Pane.new views[0]
|
|
947
|
+
panes = outer_pane.split(views[0], views[1], Qt::Horizontal)
|
|
948
|
+
panes << outer_pane.split(views[1], views[2], Qt::Horizontal)[1]
|
|
949
|
+
text = 'xyz'
|
|
950
|
+
flexmock(panes[0]).should_receive(:set_view_label).with(views[3], text).once.and_return false
|
|
951
|
+
flexmock(panes[1]).should_receive(:set_view_label).with(views[3], text).once.and_return false
|
|
952
|
+
flexmock(panes[2]).should_receive(:set_view_label).with(views[3], text).once.and_return false
|
|
953
|
+
outer_pane.set_view_label(views[3], text).should be_false
|
|
954
|
+
end
|
|
955
|
+
|
|
956
|
+
end
|
|
957
|
+
|
|
958
|
+
end
|
|
959
|
+
|
|
960
|
+
describe '#label=' do
|
|
961
|
+
|
|
962
|
+
context 'when the pane is in single view mode' do
|
|
963
|
+
|
|
964
|
+
it 'sets the label to the given value' do
|
|
965
|
+
view = @doc.create_view
|
|
966
|
+
pane = Ruber::Pane.new view
|
|
967
|
+
text = 'xyz'
|
|
968
|
+
pane.label = text
|
|
969
|
+
pane.instance_variable_get(:@label).text.should == text
|
|
970
|
+
end
|
|
971
|
+
|
|
972
|
+
it 'shows the label if the text is not empty and the pane is not top level' do
|
|
973
|
+
views = 2.times.map{@doc.create_view}
|
|
974
|
+
outer_pane = Ruber::Pane.new views[0]
|
|
975
|
+
pane = outer_pane.split( views[0], views[1], Qt::Vertical)[0]
|
|
976
|
+
text = 'xyz'
|
|
977
|
+
label = pane.instance_variable_get(:@label)
|
|
978
|
+
flexmock(label).should_receive(:visible=).with(true).once
|
|
979
|
+
pane.label = text
|
|
980
|
+
label.text.should == text
|
|
981
|
+
end
|
|
982
|
+
|
|
983
|
+
it 'doesn\'t show the label if the pane is top-level' do
|
|
984
|
+
view = @doc.create_view
|
|
985
|
+
pane = Ruber::Pane.new view
|
|
986
|
+
text = 'xyz'
|
|
987
|
+
label = pane.instance_variable_get(:@label)
|
|
988
|
+
flexmock(label).should_receive(:visible=).never
|
|
989
|
+
pane.label = text
|
|
990
|
+
end
|
|
991
|
+
|
|
992
|
+
it 'hides the label if the text is empty' do
|
|
993
|
+
views = 2.times.map{@doc.create_view}
|
|
994
|
+
outer_pane = Ruber::Pane.new views[0]
|
|
995
|
+
pane = outer_pane.split( views[0], views[1], Qt::Vertical)[0]
|
|
996
|
+
label = pane.instance_variable_get(:@label)
|
|
997
|
+
label.text = 'xyz'
|
|
998
|
+
flexmock(label).should_receive(:visible=).with(false).once
|
|
999
|
+
pane.label = ''
|
|
1000
|
+
label.text.should == ''
|
|
1001
|
+
end
|
|
1002
|
+
|
|
1003
|
+
end
|
|
1004
|
+
|
|
1005
|
+
context 'when the pane is in multiple view mode' do
|
|
1006
|
+
|
|
1007
|
+
it 'does nothing' do
|
|
1008
|
+
views = 2.times.map{@doc.create_view}
|
|
1009
|
+
pane = Ruber::Pane.new views[0]
|
|
1010
|
+
pane.split( views[0], views[1], Qt::Vertical)[0]
|
|
1011
|
+
text = 'xyz'
|
|
1012
|
+
label = pane.instance_variable_get(:@label)
|
|
1013
|
+
flexmock(label).should_receive(:visible=).never
|
|
1014
|
+
flexmock(label).should_receive(:text=).never
|
|
1015
|
+
pane.label = text
|
|
1016
|
+
end
|
|
1017
|
+
|
|
1018
|
+
end
|
|
1019
|
+
|
|
1020
|
+
end
|
|
1021
|
+
|
|
1022
|
+
describe '#label' do
|
|
1023
|
+
|
|
1024
|
+
it 'returns the text of the label if the pane is in single view mode' do
|
|
1025
|
+
view = @doc.create_view
|
|
1026
|
+
pane = Ruber::Pane.new view
|
|
1027
|
+
pane.label = 'xyz'
|
|
1028
|
+
pane.label.should == 'xyz'
|
|
1029
|
+
end
|
|
1030
|
+
|
|
1031
|
+
it 'returns an empty string if the label hasn\'t been set' do
|
|
1032
|
+
view = @doc.create_view
|
|
1033
|
+
pane = Ruber::Pane.new view
|
|
1034
|
+
pane.label.should == ''
|
|
1035
|
+
end
|
|
1036
|
+
|
|
1037
|
+
it 'returns an empty string if the label has been set to an empty string' do
|
|
1038
|
+
view = @doc.create_view
|
|
1039
|
+
pane = Ruber::Pane.new view
|
|
1040
|
+
pane.label = ''
|
|
1041
|
+
pane.label.should == ''
|
|
1042
|
+
end
|
|
1043
|
+
|
|
1044
|
+
it 'returns nil if the pane is in multiple view mode' do
|
|
1045
|
+
views = 2.times.map{@doc.create_view}
|
|
1046
|
+
pane = Ruber::Pane.new views[0]
|
|
1047
|
+
pane.label = 'xyz'
|
|
1048
|
+
pane.split( views[0], views[1], Qt::Vertical)[0]
|
|
1049
|
+
pane.label.should be_nil
|
|
1050
|
+
end
|
|
1051
|
+
|
|
1052
|
+
end
|
|
1053
|
+
|
|
1054
|
+
describe '#replace_view' do
|
|
1055
|
+
|
|
1056
|
+
context 'if the pane is in single view mode' do
|
|
1057
|
+
|
|
1058
|
+
context 'and the view in the pane is the one given as first argument' do
|
|
1059
|
+
|
|
1060
|
+
it 'replaces the view contained in the pane with the one given as second argument' do
|
|
1061
|
+
views = 2.times.map{@doc.create_view}
|
|
1062
|
+
pane = Ruber::Pane.new views[0]
|
|
1063
|
+
pane.replace_view views[0], views[1]
|
|
1064
|
+
pane.view.should == views[1]
|
|
1065
|
+
pane.view.parent.should == pane
|
|
1066
|
+
pane.layout.should include(views[1])
|
|
1067
|
+
end
|
|
1068
|
+
|
|
1069
|
+
it 'makes the old view parentless and removes it from the layout' do
|
|
1070
|
+
views = 2.times.map{@doc.create_view}
|
|
1071
|
+
pane = Ruber::Pane.new views[0]
|
|
1072
|
+
pane.replace_view views[0], views[1]
|
|
1073
|
+
views[0].parent.should be_nil
|
|
1074
|
+
pane.layout.should_not include(views[0])
|
|
1075
|
+
end
|
|
1076
|
+
|
|
1077
|
+
it 'returns true' do
|
|
1078
|
+
views = 2.times.map{@doc.create_view}
|
|
1079
|
+
pane = Ruber::Pane.new views[0]
|
|
1080
|
+
pane.replace_view(views[0], views[1]).should be_true
|
|
1081
|
+
end
|
|
1082
|
+
|
|
1083
|
+
it 'emits the view_replaced(QWidget*,QWidget*,QWidget*) signal passing self, the original view and the replacement view as arguments' do
|
|
1084
|
+
views = 2.times.map{@doc.create_view}
|
|
1085
|
+
pane = Ruber::Pane.new views[0]
|
|
1086
|
+
mk = flexmock{|m| m.should_receive(:view_replaced).with(pane, views[0], views[1]).once}
|
|
1087
|
+
pane.connect(SIGNAL('view_replaced(QWidget*,QWidget*,QWidget*)')){|pn, v1, v2| mk.view_replaced pn, v1, v2}
|
|
1088
|
+
pane.replace_view(views[0], views[1])
|
|
1089
|
+
end
|
|
1090
|
+
|
|
1091
|
+
end
|
|
1092
|
+
|
|
1093
|
+
context 'and the view in the pane is not the one given as first argument' do
|
|
1094
|
+
|
|
1095
|
+
it 'does nothing' do
|
|
1096
|
+
views = 3.times.map{@doc.create_view}
|
|
1097
|
+
pane = Ruber::Pane.new views[0]
|
|
1098
|
+
pane.replace_view views[2], views[1]
|
|
1099
|
+
pane.view.should == views[0]
|
|
1100
|
+
views[0].parent.should == pane
|
|
1101
|
+
views[1].parent.should be_nil
|
|
1102
|
+
pane.layout.should include(views[0])
|
|
1103
|
+
pane.layout.should_not include(views[1])
|
|
1104
|
+
end
|
|
1105
|
+
|
|
1106
|
+
it 'returns false' do
|
|
1107
|
+
views = 3.times.map{@doc.create_view}
|
|
1108
|
+
pane = Ruber::Pane.new views[0]
|
|
1109
|
+
pane.replace_view(views[2], views[1]).should be_false
|
|
1110
|
+
end
|
|
1111
|
+
|
|
1112
|
+
end
|
|
1113
|
+
|
|
1114
|
+
end
|
|
1115
|
+
|
|
1116
|
+
context 'if the pane is in multiple view mode' do
|
|
1117
|
+
|
|
1118
|
+
it 'calls the same method on all child panes until one of them returns true' do
|
|
1119
|
+
views = 4.times.map{@doc.create_view}
|
|
1120
|
+
outer_pane = Ruber::Pane.new views[0]
|
|
1121
|
+
panes = outer_pane.split(views[0], views[1], Qt::Horizontal)
|
|
1122
|
+
panes << outer_pane.split(views[1], views[2], Qt::Horizontal)[1]
|
|
1123
|
+
flexmock(panes[0]).should_receive(:replace_view).with(views[1], views[3]).once.and_return false
|
|
1124
|
+
flexmock(panes[1]).should_receive(:replace_view).with(views[1], views[3]).once.and_return true
|
|
1125
|
+
flexmock(panes[2]).should_receive(:replace_view).never
|
|
1126
|
+
outer_pane.replace_view views[1], views[3]
|
|
1127
|
+
end
|
|
1128
|
+
|
|
1129
|
+
it 'returns true if one of the child panes\' replace_view methods returns true' do
|
|
1130
|
+
views = 4.times.map{@doc.create_view}
|
|
1131
|
+
outer_pane = Ruber::Pane.new views[0]
|
|
1132
|
+
panes = outer_pane.split(views[0], views[1], Qt::Horizontal)
|
|
1133
|
+
panes << outer_pane.split(views[1], views[2], Qt::Horizontal)[1]
|
|
1134
|
+
flexmock(panes[0]).should_receive(:replace_view).with(views[1], views[3]).once.and_return false
|
|
1135
|
+
flexmock(panes[1]).should_receive(:replace_view).with(views[1], views[3]).once.and_return true
|
|
1136
|
+
flexmock(panes[2]).should_receive(:replace_view).never
|
|
1137
|
+
outer_pane.replace_view(views[1], views[3]).should be_true
|
|
1138
|
+
end
|
|
1139
|
+
|
|
1140
|
+
it 'emits the view_replaced(QWidget*,QWidget*,QWidget*) signal passing the pane containing the view, the original view and the replacement view as arguments if one of the child panes\' replace_view methods returns true' do
|
|
1141
|
+
views = 4.times.map{@doc.create_view}
|
|
1142
|
+
outer_pane = Ruber::Pane.new views[0]
|
|
1143
|
+
panes = outer_pane.split(views[0], views[1], Qt::Horizontal)
|
|
1144
|
+
panes << outer_pane.split(views[1], views[2], Qt::Horizontal)[1]
|
|
1145
|
+
mk = flexmock{|m| m.should_receive(:view_replaced).with(views[1].parent, views[1], views[3]).once}
|
|
1146
|
+
outer_pane.connect(SIGNAL('view_replaced(QWidget*,QWidget*,QWidget*)')){|pn, v1, v2| mk.view_replaced pn, v1, v2}
|
|
1147
|
+
outer_pane.replace_view(views[1], views[3])
|
|
1148
|
+
end
|
|
1149
|
+
|
|
1150
|
+
it 'returns true if all of the child panes\' replace_view methods return false' do
|
|
1151
|
+
views = 5.times.map{@doc.create_view}
|
|
1152
|
+
outer_pane = Ruber::Pane.new views[0]
|
|
1153
|
+
panes = outer_pane.split(views[0], views[1], Qt::Horizontal)
|
|
1154
|
+
panes << outer_pane.split(views[1], views[2], Qt::Horizontal)[1]
|
|
1155
|
+
flexmock(panes[0]).should_receive(:replace_view).with(views[4], views[3]).once.and_return false
|
|
1156
|
+
flexmock(panes[1]).should_receive(:replace_view).with(views[4], views[3]).once.and_return false
|
|
1157
|
+
flexmock(panes[2]).should_receive(:replace_view).with(views[4], views[3]).once.and_return false
|
|
1158
|
+
outer_pane.replace_view(views[4], views[3]).should be_false
|
|
1159
|
+
end
|
|
1160
|
+
|
|
1161
|
+
end
|
|
1162
|
+
|
|
1163
|
+
end
|
|
1164
|
+
|
|
1165
|
+
end
|