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.
Files changed (83) hide show
  1. data/CHANGES +25 -0
  2. data/bin/ruber +0 -0
  3. data/data/share/apps/ruber/ruberui.rc +15 -1
  4. data/data/share/icons/{ruber.png → ruber-old.pgn} +0 -0
  5. data/lib/ruber/application/application.rb +216 -73
  6. data/lib/ruber/application/plugin.yaml +2 -2
  7. data/lib/ruber/document_project.rb +25 -5
  8. data/lib/ruber/documents/document_list.rb +11 -15
  9. data/lib/ruber/editor/document.rb +106 -50
  10. data/lib/ruber/editor/editor_view.rb +4 -2
  11. data/lib/ruber/external_program_plugin.rb +8 -0
  12. data/lib/ruber/kde_config_option_backend.rb +12 -4
  13. data/lib/ruber/kde_sugar.rb +35 -1
  14. data/lib/ruber/main_window/choose_plugins_dlg.rb +10 -10
  15. data/lib/ruber/main_window/hint_solver.rb +263 -0
  16. data/lib/ruber/main_window/main_window.rb +462 -206
  17. data/lib/ruber/main_window/main_window_actions.rb +228 -62
  18. data/lib/ruber/main_window/main_window_internal.rb +169 -115
  19. data/lib/ruber/main_window/plugin.yaml +13 -3
  20. data/lib/ruber/main_window/save_modified_files_dlg.rb +1 -1
  21. data/lib/ruber/main_window/ui/choose_plugins_widget.rb +1 -1
  22. data/lib/ruber/main_window/ui/main_window_settings_widget.rb +1 -1
  23. data/lib/ruber/main_window/ui/new_project_widget.rb +1 -1
  24. data/lib/ruber/main_window/ui/open_file_in_project_dlg.rb +1 -1
  25. data/lib/ruber/main_window/ui/output_color_widget.rb +1 -1
  26. data/lib/ruber/main_window/ui/workspace_settings_widget.rb +51 -0
  27. data/lib/ruber/main_window/ui/workspace_settings_widget.ui +28 -0
  28. data/lib/ruber/main_window/view_manager.rb +418 -0
  29. data/lib/ruber/main_window/workspace.png +0 -0
  30. data/lib/ruber/output_widget.rb +43 -37
  31. data/lib/ruber/pane.rb +621 -0
  32. data/lib/ruber/plugin_specification_reader.rb +8 -1
  33. data/lib/ruber/projects/project_files_list.rb +6 -0
  34. data/lib/ruber/projects/ui/project_files_rule_chooser_widget.rb +1 -1
  35. data/lib/ruber/projects/ui/project_files_widget.rb +1 -1
  36. data/lib/ruber/qt_sugar.rb +94 -4
  37. data/lib/ruber/utils.rb +16 -7
  38. data/lib/ruber/version.rb +2 -2
  39. data/plugins/autosave/autosave.rb +62 -1
  40. data/plugins/autosave/plugin.yaml +1 -0
  41. data/plugins/autosave/ui/autosave_config_widget.rb +37 -14
  42. data/plugins/autosave/ui/autosave_config_widget.ui +62 -12
  43. data/plugins/find_in_files/find_in_files_widgets.rb +1 -3
  44. data/plugins/find_in_files/ui/config_widget.rb +1 -1
  45. data/plugins/find_in_files/ui/find_in_files_widget.rb +1 -1
  46. data/plugins/rake/plugin.yaml +1 -1
  47. data/plugins/rake/ui/add_quick_task_widget.rb +1 -1
  48. data/plugins/rake/ui/choose_task_widget.rb +1 -1
  49. data/plugins/rake/ui/config_widget.rb +1 -1
  50. data/plugins/rake/ui/project_widget.rb +1 -1
  51. data/plugins/rspec/rspec.rb +14 -22
  52. data/plugins/rspec/ruber_rspec_formatter.rb +4 -1
  53. data/plugins/rspec/ui/rspec_project_widget.rb +1 -1
  54. data/plugins/ruby_development/plugin.yaml +7 -2
  55. data/plugins/ruby_development/ruby_development.rb +134 -13
  56. data/plugins/ruby_development/ui/config_widget.rb +66 -0
  57. data/plugins/ruby_development/ui/config_widget.ui +58 -0
  58. data/plugins/ruby_development/ui/project_widget.rb +1 -1
  59. data/plugins/ruby_runner/plugin.yaml +2 -2
  60. data/plugins/ruby_runner/ruby_runner.rb +15 -3
  61. data/plugins/ruby_runner/ui/config_widget.rb +1 -1
  62. data/plugins/ruby_runner/ui/project_widget.rb +1 -1
  63. data/plugins/ruby_runner/ui/ruby_runnner_plugin_option_widget.rb +1 -1
  64. data/plugins/state/plugin.yaml +6 -2
  65. data/plugins/state/state.rb +305 -81
  66. data/plugins/state/ui/config_widget.rb +1 -1
  67. data/spec/common.rb +11 -3
  68. data/spec/document_list_spec.rb +8 -8
  69. data/spec/document_project_spec.rb +98 -25
  70. data/spec/document_spec.rb +178 -152
  71. data/spec/editor_view_spec.rb +26 -5
  72. data/spec/framework.rb +5 -0
  73. data/spec/hint_solver_spec.rb +450 -0
  74. data/spec/kde_sugar_spec.rb +73 -6
  75. data/spec/output_widget_spec.rb +172 -156
  76. data/spec/pane_spec.rb +1165 -0
  77. data/spec/plugin_specification_reader_spec.rb +37 -1
  78. data/spec/project_files_list_spec.rb +30 -20
  79. data/spec/qt_sugar_spec.rb +269 -0
  80. data/spec/state_spec.rb +566 -353
  81. data/spec/utils_spec.rb +1 -1
  82. data/spec/view_manager_spec.rb +71 -0
  83. metadata +16 -4
@@ -44,29 +44,33 @@ Slot connected to the 'New File' action
44
44
 
45
45
  It creates and activates a new, empty file
46
46
 
47
- @return [nil]
47
+ @return [EditorView] the editor used to display the new file
48
48
  =end
49
49
  def new_file
50
50
  display_doc Ruber[:docs].new_document
51
- nil
52
51
  end
53
52
 
54
53
  =begin rdoc
55
54
  Slot connected to the 'Open File' action.
56
55
 
57
- It opens in an editor and activates a document associated with a file chosen by the
58
- user with an OpenFile dialog (the document is created if needed). It also adds
59
- the file to the list of recently opened files.
56
+ It asks the user for the file(s) or URL(s) to open, then creates a document and
57
+ and editor for each of them. If a document for some of the files already exists,
58
+ it will be used. If an editor for one of the files already exists, it will be
59
+ used.
60
60
 
61
- @return [nil]
61
+ After calling this method, the editor associated with the last file chosen by the
62
+ user will become active
63
+
64
+ @return [Array<EditorView>] a list of the editors used for the files
62
65
  =end
63
66
  def open_file
64
67
  dir = KDE::Url.from_path(Ruber.current_project.project_directory) rescue KDE::Url.new
65
68
  filenames = KDE::FileDialog.get_open_urls(dir, OPEN_DLG_FILTERS.join("\n") , self)
69
+ editors = []
66
70
  without_activating do
67
- filenames.each{|f| gui_open_file f}
71
+ filenames.each{|f| editors << gui_open_file(f)}
68
72
  end
69
- nil
73
+ editors
70
74
  end
71
75
 
72
76
  =begin rdoc
@@ -75,77 +79,116 @@ Slot connected to the 'Open Recent File' action
75
79
  It opens the file associated with the specified URL in an editor and gives it focus
76
80
 
77
81
  @param [KDE::Url] the url of the file to open
78
- @return [nil]
82
+ @return [EditorView] the editor used to display the URL
79
83
  =end
80
84
  def open_recent_file url
81
85
  gui_open_file url.path
82
- nil
83
86
  end
84
87
 
85
88
  =begin rdoc
86
89
  Slot connected to the 'Close Current' action
87
90
 
88
- It closes the current editor, if any. If the documents is modified,
89
- it allows the user to choose what to do via a dialog. If the user chooses to abort
90
- closing, nothing is done
91
+ It closes the current editor, if any. If this is the last editor associated with
92
+ its document and the document is modified, the user is asked to choose whether to
93
+ save it, discard changes or not close the view.
91
94
 
92
- @return [nil]
95
+ @return [Boolean] *true* if the editor was closed and *false* otherwise
93
96
  =end
94
97
  def close_current_editor
95
98
  close_editor active_editor if active_editor
96
- nil
97
99
  end
98
100
 
101
+ =begin rdoc
102
+ Slot connected to the Close Current Tab action
103
+
104
+ Closes all the editors in a given tab. If the tab contains the only view for a document,
105
+ the document is closed, too. If some of these documents are modified, the user
106
+ is asked what to do. If the user cancels the dialog, nothing is done.
107
+ @param [Integer,nil] idx the index of the tab to close. If *nil*, the current tab
108
+ is closed
109
+ @return [Boolean] *true* if the tab was closed successfully (or the tab widget was
110
+ empty) and *false* if the user canceled the save dialog
111
+ =end
112
+ def close_tab idx = nil
113
+ tab = idx ? @tabs.widget(idx) : @tabs.current_widget
114
+ return true unless tab
115
+ docs = tab.map(&:document).select{|d| d.views.size == 1}.uniq
116
+ return false unless save_documents docs
117
+ views = tab.to_a
118
+ without_activating do
119
+ views.each{|v| close_editor v, false}
120
+ end
121
+ true
122
+ end
123
+ slots :close_tab
124
+ slots 'close_tab(int)'
125
+
99
126
  =begin rdoc
100
127
  Slot connected to the 'Close All Other' action
101
128
 
102
- It closes all the editors except the current one. If some documents are modified,
103
- it allows the user to choose what to do via a dialog. If the user chooses to abort
104
- closing, nothing is done.
129
+ It closes all the editors except the current one. All documents with an open editor,
130
+ except for the one associated with the current editor, will be closed. If any document
131
+ is modified, the user will be ask whether to save them, discard the changes or
132
+ don't close the views. In the latter case, nothing will be done
105
133
 
106
- @return [nil]
134
+ @return [Boolean] *true* if the editors where successfully closed and *false*
135
+ otherwise
107
136
  =end
108
137
  def close_other_views
109
- to_close = @views.select{|w| w != @views.current_widget}.map{|w| w.document}
110
- if save_documents to_close
138
+ to_close = @tabs.inject([]) do |res, pn|
139
+ res += pn.each_view.to_a
140
+ res
141
+ end
142
+ to_close.delete active_editor
143
+ if save_documents to_close.map{|v| v.document}.uniq
111
144
  without_activating do
112
- to_close.dup.each{|d| d.close_view d.view, false}
145
+ to_close.each{|v| close_editor v, false}
113
146
  end
147
+ true
148
+ else false
114
149
  end
115
- nil
116
150
  end
117
151
 
118
152
  =begin rdoc
119
153
  Slot connected with the 'Close All' action
120
154
 
121
- It closes all the editors. If some documents are modified,
122
- it allows the user to choose what to do via a dialog. If the user chooses to abort
123
- closing, nothing is done.
155
+ It closes all the editors and documents associated with them. If any document
156
+ is modified and _ask_ is *true*, the user will be ask whether to save them,
157
+ discard the changes or don't close the views. In the latter case, nothing will be
158
+ done. If _ask_ is *false*, the documents will be closed even if they're modified,
159
+ without asking the user.
124
160
 
125
- @return [nil]
161
+ @param [Boolean] ask whether or not to ask the user how to proceed if any document
162
+ is modified. Please, set this to *false* only if you've already asked the user
163
+ whether he wants to save the documents or not
164
+ @return [Boolean] *true* if the editors where successfully closed and *false*
165
+ otherwise
126
166
  =end
127
167
  def close_all_views ask = true
128
- return if ask and !save_documents @views.map{|v| v.document}
168
+ docs = Ruber[:documents].select{|d| d.has_view?}
169
+ return false if ask and !save_documents docs
129
170
  without_activating do
130
- @views.to_a.each do |w|
131
- close_editor w, false
171
+ @tabs.to_a.each do |w|
172
+ w.to_a.each{|v| close_editor v, false}
132
173
  end
133
174
  end
134
- nil
175
+ true
135
176
  end
136
177
 
137
178
  =begin rdoc
138
179
  Slot connected to the 'Open Recent Projet' action
139
180
 
140
- It opens a project and activates a project
181
+ It opens and activates the project associated with the file described by the
182
+ given URL
141
183
 
142
184
  @param [KDE::Url] the url of the project file to open
143
- @return [nil]
185
+ @return [Project,nil] the open project or *nil* if an error occurs
144
186
  =end
145
187
  def open_recent_project url
146
- return unless safe_open_project url.path
188
+ prj = safe_open_project url.path
189
+ return unless prj
147
190
  action_collection.action('project-open_recent').add_url url, url.file_name
148
- nil
191
+ prj
149
192
  end
150
193
 
151
194
  =begin rdoc
@@ -153,7 +196,8 @@ Slot connected to the 'Open Project' action
153
196
 
154
197
  It opens the project chosen by the user using an open dialog
155
198
 
156
- @return [nil]
199
+ @return [Project,nil] the project chosen by the user or *nil* if either the user
200
+ cancels the dialog or an error occurs while loading the project
157
201
  =end
158
202
  def open_project
159
203
  filename = KDE::FileDialog.get_open_file_name KDE::Url.from_path(
@@ -163,16 +207,21 @@ It opens the project chosen by the user using an open dialog
163
207
  prj = safe_open_project filename
164
208
  url = KDE::Url.new prj.project_file
165
209
  action_collection.action('project-open_recent').add_url url, url.file_name
166
- nil
210
+ prj
167
211
  end
168
212
 
169
213
  =begin rdoc
170
214
  Slot connectedto the 'Close Current Project' action
215
+
216
+ It closes the current project, if any, warning the user if, for any reason, the
217
+ project couldn't be saved
218
+ @return [nil]
171
219
  =end
172
220
  def close_current_project
173
221
  unless Ruber[:projects].current_project.close
174
222
  KDE::MessageBox.sorry self, "The project couldn't be saved"
175
223
  end
224
+ nil
176
225
  end
177
226
 
178
227
  =begin rdoc
@@ -180,15 +229,15 @@ Slot connected to the 'Quick Open File' action
180
229
 
181
230
  It opens the file chosen by the user in a quick open file dialog
182
231
 
183
- @retrun [nil]
232
+ @return [EditorView,nil] the editor where the document has been displayed
184
233
  =end
185
234
  def open_file_in_project
186
235
  dlg = OpenFileInProjectDlg.new self
187
236
  if dlg.exec == Qt::Dialog::Accepted
188
- display_doc dlg.chosen_file
237
+ editor = display_doc dlg.chosen_file
189
238
  action_collection.action( 'file_open_recent').add_url( KDE::Url.new(dlg.chosen_file) )
239
+ editor
190
240
  end
191
- nil
192
241
  end
193
242
 
194
243
  =begin rdoc
@@ -269,30 +318,30 @@ it's closed
269
318
  =begin rdoc
270
319
  Slot connected with the 'Next Document' action
271
320
 
272
- Makes the editor to the right of the current one active. If there's no editor to
273
- the right, the first editor becomes active
321
+ Activates the tab to the right of the current one. If the current tab is the last
322
+ one, it returns to the first
274
323
 
275
- @return [nil]
324
+ @return [EditorView,nil] the active editor
276
325
  =end
277
326
  def next_document
278
- idx = @views.current_index
279
- new_idx = idx + 1 < @views.count ? idx + 1 : 0
280
- activate_editor new_idx
281
- nil
327
+ idx = @tabs.current_index
328
+ new_idx = idx + 1 < @tabs.count ? idx + 1 : 0
329
+ @tabs.current_index = new_idx
330
+ active_editor
282
331
  end
283
332
 
284
333
  =begin rdoc
285
334
  Slot connected with the 'Previous Document' action
286
335
 
287
- Makes the editor to the left of the current one active. If there's no editor to
288
- the left, the last editor becomes active
336
+ Activates the tab to the left of the current one. If the current tab is the first
337
+ one, it jumps to the last
289
338
 
290
- @return [nil]
339
+ @return [EditorView,nil] the active editor
291
340
  =end
292
341
  def previous_document
293
- idx = @views.current_index
294
- new_idx = idx > 0 ? idx - 1 : @views.count - 1
295
- activate_editor new_idx
342
+ idx = @tabs.current_index
343
+ new_idx = idx > 0 ? idx - 1 : @tabs.count - 1
344
+ @tabs.current_index = new_idx
296
345
  nil
297
346
  end
298
347
 
@@ -328,11 +377,10 @@ determined from the triggered action
328
377
  =begin rdoc
329
378
  Creates an About entry for a component in the "about plugins list" of the Help menu
330
379
 
331
- *Notes:*
332
- # this method doesn't check whether the action already exists for the given
380
+ @note this method doesn't check whether the action already exists for the given
333
381
  plugin. Since it's usually called in response to the {ComponentManager#component_loaded component_loaded}
334
382
  signal of the component manager, there shouldn't be problems with this
335
- # this method does nothing for core components
383
+ @note this method does nothing for core components
336
384
 
337
385
  @param [Plugin] comp the plugin object of the plugin to create the action for
338
386
  @return [nil]
@@ -355,11 +403,11 @@ Creates an About entry for a component in the "about plugins list" of the Help m
355
403
  =begin rdoc
356
404
  Removes the About entry for the given menu from the "about plugins list" of the Help menu
357
405
 
358
- *Notes:*
359
- # this method doesn't check whether the action for the given
360
- plugin actually exists. Since it's usually called in response to the {ComponentManager#unloading_component unloading_component}
361
- signal of the component manager, there shouldn't be problems with this
362
- # this method does nothing for core components
406
+ @note this method doesn't check whether the action for the given
407
+ plugin actually exists. Since it's usually called in response to the
408
+ {ComponentManager#unloading_component unloading_component} signal of the
409
+ component manager, there shouldn't be problems with this
410
+ @note this method does nothing for core components
363
411
 
364
412
  @param [Plugin] comp the plugin object of the plugin to remove the action for
365
413
  @return [nil]
@@ -387,7 +435,7 @@ Displays the configuration dialog for the current document, if it exists
387
435
  end
388
436
 
389
437
  =begin rdoc
390
- Slot associated with the Toggle * Tool Widget
438
+ Slot associated with the Toggle * Tool Widget action
391
439
 
392
440
  It identifies the tool widget to toggle basing on the name of the triggered action
393
441
 
@@ -401,6 +449,124 @@ It identifies the tool widget to toggle basing on the name of the triggered acti
401
449
  nil
402
450
  end
403
451
 
452
+ =begin rdoc
453
+ Slot associated with the Split Horizontally action
454
+
455
+ It splits the active view horizontally, so that a new copy of the view is created.
456
+ @note@ this method can only be called when there's an active view.
457
+
458
+ @return [EditorView] the newly created editor
459
+ =end
460
+ def split_horizontally
461
+ ed = active_editor
462
+ display_document ed.document, nil, nil, :existing => :never, :new => ed, :split => :horizontal
463
+ end
464
+ slots :split_horizontally
465
+
466
+ =begin rdoc
467
+ Slot associated with the Split Vertically action
468
+
469
+ It splits the active view vertically, so that a new copy of the view is created.
470
+ @note@ this method can only be called when there's an active view.
471
+
472
+ @return [EditorView] the newly created editor
473
+ =end
474
+ def split_vertically
475
+ ed = active_editor
476
+ new_ed = display_document ed.document, nil, nil, :existing => :never, :new => ed, :split => :vertical
477
+ end
478
+ slots :split_vertically
479
+
480
+ =begin rdoc
481
+ Slot associated with the Switch to New Document action
482
+
483
+ It creates a new empty document, replaces the current editor with an editor
484
+ associated to it and gives focus to it.
485
+ @note@ this method can only be called when there's an active view
486
+
487
+ @return [EditorView] the newly created editor
488
+ =end
489
+ def switch_to_new_document
490
+ old = active_editor
491
+ ed = replace_editor old, Ruber[:documents].new_document
492
+ focus_on_editor ed if ed
493
+ end
494
+ slots :switch_to_new_document
495
+
496
+ =begin rdoc
497
+ Slot associated with the Switch to File action
498
+
499
+ It allows the user to choose a file, then creates a document for that file, replaces
500
+ the active editor with a new one associated with the document and gives focus to it.
501
+ @note@ this method can only be called when there's an active view
502
+
503
+ @return [EditorView] the newly created editor
504
+ =end
505
+ def switch_to_file
506
+ dir = KDE::Url.from_path(Ruber.current_project.project_directory) rescue KDE::Url.new
507
+ filename = KDE::FileDialog.get_open_url(dir, OPEN_DLG_FILTERS.join("\n") , self)
508
+ return unless filename.valid?
509
+ Ruber::Application.process_events
510
+ ed = replace_editor active_editor, filename
511
+ focus_on_editor ed if ed
512
+ end
513
+ slots :switch_to_file
514
+
515
+ =begin rdoc
516
+ Slot which updates the @window-switch_to_open_document_list@ action list
517
+
518
+ This method is called whenever a document is created or deleted. It updates the
519
+ action list so that it contains an action for each of the open documents
520
+ =end
521
+ def update_switch_to_list
522
+ unplug_action_list 'window-switch_to_open_document_list'
523
+ @switch_to_actions.each{|a| a.delete_later}
524
+ @switch_to_actions = Ruber[:documents].map do |doc|
525
+ a = action_collection.add_action "switch_to_#{doc.document_name}", self, SLOT(:switch_to_document)
526
+ a.text = KDE.i18n("Switch to %s") % [doc.document_name]
527
+ a.object_name = doc.document_name
528
+ a
529
+ end
530
+ @switch_to_actions = @switch_to_actions.sort_by{|a| a.object_name}
531
+ plug_action_list 'window-switch_to_open_document_list', @switch_to_actions
532
+ end
533
+ slots :update_switch_to_list
534
+
535
+ =begin rdoc
536
+ Slot associated with the actions in the Switch to Document submenu
537
+
538
+ It creates a new editor for an already-existing document and replaces the active
539
+ editor with it, giving focus to it. The document to use is determined from the
540
+ @object_name@ of the action.
541
+ @note this method can only be called when there's an active view
542
+ @note this method uses @sender@ to find out the action which emitted the signal,
543
+ so it shouldn't be called directly
544
+ @return [EditorView] the newly created editor
545
+ =end
546
+ def switch_to_document
547
+ doc = Ruber[:documents].document_with_name sender.object_name
548
+ ed = replace_editor active_editor, doc
549
+ focus_on_editor ed if ed
550
+ end
551
+ slots :switch_to_document
552
+
553
+ =begin rdoc
554
+ Slot associated with Switch to Recent File action
555
+
556
+ It creates a new document for the given URL (if needed), creates a new editor
557
+ for it, replaces the active editor with it and gives focus to it.
558
+
559
+ @note@ this method can only be called when there's an active view
560
+ @param [KDE::Url] url the URL associated with the editor
561
+ @return [EditorView] the newly created editor
562
+
563
+ =end
564
+ def switch_to_recent_file url
565
+ ed = replace_editor active_editor, url
566
+ focus_on_editor ed if ed
567
+ end
568
+ slots 'switch_to_recent_file(KUrl)'
569
+
404
570
  end
405
571
 
406
572
  =begin rdoc
@@ -23,7 +23,7 @@ require 'facets/enumerable/sum'
23
23
  module Ruber
24
24
 
25
25
  class MainWindow < KParts::MainWindow
26
-
26
+
27
27
  =begin rdoc
28
28
  A list of strings to be used to create the filter for open file dialogs
29
29
  =end
@@ -38,202 +38,256 @@ A list of strings to be used to create the filter for open file dialogs
38
38
  'store_splitter_sizes(QString)', 'update_document_icon(QObject*)',
39
39
  'remove_plugin_ui_actions(QObject*)', 'close_project_files(QObject*)'
40
40
 
41
- private
41
+ protected
42
42
 
43
43
  =begin rdoc
44
- Checks whether an editor view for the given document exists and creates it if it
45
- doesn't. In both cases, An editor view for the document is returned. _doc_ is the
46
- Document for which the editor should be created.
47
-
48
- <b>Note:</b> this also creates a new tab with the new view, if it needs to create
49
- one
50
- =end
51
- def create_editor_if_needed doc
52
- if doc.view then doc.view
53
- else
54
- view = doc.create_view
55
- @editors_mapper.set_mapping view, view
56
- connect view, SIGNAL(:closing), @editors_mapper, SLOT(:map)
57
- connect view.document, SIGNAL('modified_changed(bool, QObject*)'), self, SLOT('document_modified_changed(bool)')
58
- connect view.document, SIGNAL('modified_on_disk(QObject*, bool, KTextEditor::ModificationInterface::ModifiedOnDiskReason)'), self, SLOT('update_document_icon(QObject*)')
59
- connect view.document, SIGNAL('document_url_changed(QObject*)'), self, SLOT(:document_url_changed)
60
- @views.add_tab view, doc.icon, doc.document_name
61
- view
62
- end
44
+ Override of @KParts::MainWindow#queryClose@
45
+
46
+ It calls which calls the {ComponentManager#query_close query_close} method of the
47
+ component manager.
48
+ @return [Boolean] what the {ComponentManager#query_close query_close} method of
49
+ the component manager returns
50
+ =end
51
+ def queryClose
52
+ Ruber[:components].query_close
63
53
  end
64
-
54
+
65
55
  =begin rdoc
66
- Changes the icon in the tab corresponding to the Document _doc_ so that it reflects
67
- its current status
56
+ Override of @KParts::MainWindow#queryExit@
57
+
58
+ It calls the {Application#quit_ruber quit_ruber} method of the application
59
+ @return [TrueClass] *true*
68
60
  =end
69
- def update_document_icon doc
70
- ed = editor_for doc
71
- return unless ed
72
- idx = @views.index_of ed
73
- return unless idx
74
- @views.set_tab_icon idx, doc.icon
61
+ def queryExit
62
+ Ruber[:app].quit_ruber
63
+ true
75
64
  end
76
65
 
77
66
  =begin rdoc
78
- Opens a file, creating a document and an editor for it, activates and gives focus
79
- to the editor and adds the file to the list of recent files. _file_ is the absolute
80
- path of the file to open
67
+ Saves the properties for session management
68
+
69
+ @return [nil]
81
70
  =end
82
- def gui_open_file file
83
- editor = editor_for! file
84
- return unless editor
85
- focus_on_editor editor
86
- url = KDE::Url.new file
87
- action_collection.action('file_open_recent').add_url url, url.file_name
71
+ def saveProperties conf
72
+ data = YAML.dump @session_data
73
+ conf.write_entry 'Ruber', data
74
+ nil
88
75
  end
89
76
 
90
77
  =begin rdoc
91
- If _ed_ is the active editor, it deactivates it and removes it from the gui. If
92
- _ed_ is not the active editor (or if it's *nil*), nothing is done.
93
-
94
- <b>Note:</b> this doesn't change the status bar associated with the view.
78
+ Reads the properties from the config object for session management
79
+
80
+ @return [nil]
95
81
  =end
96
- def deactivate_editor ed
97
- return unless ed and ed == @active_editor
98
- @active_editor.document.deactivate
99
- gui_factory.remove_client ed.send( :internal)
82
+ def readProperties conf
83
+ @last_session_data = YAML.load conf.read_entry('Ruber', '{}')
84
+ nil
100
85
  end
86
+
87
+
88
+ private
101
89
 
102
90
  =begin rdoc
103
- Remove the editor _ed_ from the tab widget, deactivating it before (if needed).
104
- If automatical activation of editors is on, it also activates another editor,
105
- if any
106
- =end
107
- def remove_view ed
108
- status_bar.view = nil if ed == @active_editor
109
- deactivate_editor ed
110
- idx = @views.index_of ed
111
- @views.remove_tab idx
112
- #This assumes that only one editor can exist for each document
113
- ed.document.disconnect SIGNAL('modified_changed(bool, QObject*)'), self
114
- ed.document.disconnect SIGNAL('document_url_changed(QObject*)'), self
115
- if @views.current_widget and @auto_activate_editors
116
- activate_editor @views.current_widget
117
- @views.current_widget.set_focus
118
- end
91
+ Slot called whenever a new document is created
92
+
93
+ It adds the document to the part manager and makes several signal-slot connections
94
+ @param [Document] doc the created document
95
+ @return [nil]
96
+ =end
97
+ def document_created doc
98
+ @view_manager.part_manager.add_part doc.send(:internal)
99
+ connect doc, SIGNAL('modified_changed(bool, QObject*)'), self, SLOT('document_modified_changed(bool)')
100
+ connect doc, SIGNAL('modified_on_disk(QObject*, bool, KTextEditor::ModificationInterface::ModifiedOnDiskReason)'), self, SLOT('update_document_icon(QObject*)')
101
+ connect doc, SIGNAL('document_url_changed(QObject*)'), self, SLOT(:document_url_changed)
102
+ connect doc, SIGNAL(:completed), self, SLOT(:document_url_changed)
103
+ connect doc, SIGNAL('closing(QObject*)'), self, SLOT('remove_document_from_part_manager(QObject*)')
104
+ update_switch_to_list
119
105
  end
106
+ slots 'document_created(QObject*)'
120
107
 
121
- protected
108
+ def remove_document_from_part_manager doc
109
+ @view_manager.part_manager.remove_part doc.send(:internal)
110
+ end
111
+ slots 'remove_document_from_part_manager(QObject*)'
122
112
 
123
113
  =begin rdoc
124
- Override of <tt>KParts::MainWindow#queryClose</tt> which calls the <tt>query_close</tt>
125
- method of the component manager. This means that the latter method will be called
126
- everytime the application is closed.
114
+ Slot called whenever the active editor changes
115
+
116
+ It emits the {#current_document_changed} and {#active_editor_changed} signals
117
+ and updates the title and the statusbar
118
+ @param [EditorView,nil] the new active editor, or *nil* if there's no active
119
+ editor
120
+ @return [nil]
127
121
  =end
128
- def queryClose
129
- Ruber[:components].query_close
122
+ def slot_active_editor_changed view
123
+ status_bar.view = view
124
+ emit current_document_changed view ? view.document : nil
125
+ emit active_editor_changed view
126
+ change_title
127
+ set_state 'current_document', !view.nil?
128
+ nil
130
129
  end
131
-
130
+ slots 'slot_active_editor_changed(QWidget*)'
131
+
132
132
  =begin rdoc
133
- Override of <tt>KParts::MainWindow#queryExit</tt> which calls the +shutdown+ method
134
- of the component
133
+ Changes the icon in the tab corresponding to a document so that it reflects its
134
+ current status
135
+
136
+ @param [Document] doc the document to update the icon for
137
+ @return [nil]
135
138
  =end
136
- def queryExit
137
- Ruber[:app].quit_ruber
138
- true
139
+ def update_document_icon doc
140
+ views = doc.views
141
+ views.each do |v|
142
+ tab = @view_manager.tab v
143
+ next unless tab
144
+ if v.is_ancestor_of tab.focus_widget
145
+ idx = @tabs.index_of tab
146
+ @tabs.set_tab_icon idx, doc.icon
147
+ end
148
+ end
149
+ nil
139
150
  end
140
151
 
141
152
  =begin rdoc
142
- Saves the properties for session management.
143
- TODO: currently, session management doesn't work at all. So, either remove the
144
- method or make it work
145
- =end
146
- def saveProperties conf
147
- data = YAML.dump @session_data
148
- conf.write_entry 'Ruber', data
149
- end
153
+ Opens a file in an editor, gives focus to it and adds it to the list of recent
154
+ files
150
155
 
151
- =begin rdoc
152
- Reads the properties from the config object for session management
156
+ If needed, a document is created for the file.
157
+
158
+ If the file can't be opened, nothing is done.
159
+
160
+ See {#editor_for!} for the values which can be included in _hints_
161
+ @param [String, KDE::Url] the absolute path of the file to open.
162
+ @param hints (see #editor_for!)
163
+ @return [EditorView,nil] the editor displaying the file or *nil* if the file
164
+ couldn't be opened
153
165
  =end
154
- def readProperties conf
155
- @last_session_data = YAML.load conf.read_entry('Ruber', '{}')
166
+ def gui_open_file file, hints = DEFAULT_HINTS
167
+ editor = editor_for! file, hints
168
+ return unless editor
169
+ focus_on_editor editor
170
+ url = KDE::Url.new file
171
+ action_collection.action('file_open_recent').add_url url, url.file_name
172
+ action_collection.action('window-switch_to_recent_file').add_url url, url.file_name
173
+ editor
156
174
  end
157
-
175
+
158
176
  =begin rdoc
159
- Creates a suitable title for the main window.
177
+ Changes the title
178
+
179
+ The title is created basing on the open project, the current document and its
180
+ modified status
181
+
182
+ @return [nil]
160
183
  =end
161
- def make_title
184
+ def change_title
162
185
  title = ''
163
186
  prj = Ruber[:projects].current_project
164
187
  if prj
165
188
  title << (prj.project_name ? prj.project_name :
166
189
  File.basename(prj.project_file, '.ruprj'))
167
190
  end
168
- if @active_editor and @active_editor.document.path.empty?
169
- title << ' - ' << @active_editor.document.document_name
170
- elsif @active_editor
171
- title << ' - ' << @active_editor.document.path
191
+ doc = current_document
192
+ if doc and doc.path.empty?
193
+ title << ' - ' << doc.document_name
194
+ elsif doc
195
+ title << ' - ' << doc.path
172
196
  end
173
197
  title.sub!(/\A\s+-/, '')
174
- mod = current_document.modified? rescue false
198
+ mod = doc.modified? rescue false
175
199
  set_caption title, mod
200
+ nil
176
201
  end
177
202
 
178
203
  =begin rdoc
179
- :call-seq: document_modified_changed(mod) [SLOT]
204
+ Slot called whenever the modified status of a document changes
205
+
206
+ It updates the icon on the tab of the document's editor and (if the document is active)
207
+ the window title accordingly.
180
208
 
181
- Slot called whenever the modified status of a document changes. It updates the
182
- icon on the tab of the document's editor and the window title (if the document
183
- was the active one) accordingly.
209
+ Nothing is done if the document isn't associated with a view
210
+ @return [nil]
211
+ @note this method uses @Qt::Object#sender@ to determine the document which emitted
212
+ the signal, so it can only be called as a slot
184
213
  =end
185
214
  def document_modified_changed mod
186
215
  doc = self.sender
187
- make_title
188
- #This assumes that only one editor exists for each document
216
+ change_title
189
217
  update_document_icon doc
218
+ nil
190
219
  end
191
220
 
192
221
  =begin rdoc
193
- Slot called whenever the document url changes (usually because the document has
194
- been saved). It changes the title and icon of the tab and changes the title of the
195
- window is the document is active.
222
+ Slot called whenever the document url changes
223
+
224
+ It changes the title and icon of the tab and changes the title of the window is
225
+ the document is active.
226
+
227
+ Nothing is done if the document isn't associated with a view
228
+
229
+ @return [nil]
196
230
  =end
197
231
  def document_url_changed
198
232
  doc = self.sender
199
- make_title
200
- idx = @views.index_of doc.view
201
- @views.set_tab_text idx, doc.document_name
233
+ return unless doc.has_view?
234
+ change_title
235
+ doc.views.each do |v|
236
+ v.parent.label = @view_manager.label_for_editor v
237
+ tab = @view_manager.tab v
238
+ if @view_manager.focus_editor? v, tab
239
+ idx = @tabs.index_of tab
240
+ @tabs.set_tab_text idx, doc.document_name
241
+ end
242
+ end
202
243
  update_document_icon doc
203
-
204
244
  unless doc.path.empty?
205
245
  action_collection.action('file_open_recent').add_url KDE::Url.new(doc.path)
206
246
  end
247
+ nil
207
248
  end
208
249
 
209
250
  =begin rdoc
210
- Removes the action handlers for all the actions belonging to the plugin _plug_
251
+ Removes the gui action handlers for all the actions belonging to the given plugin
211
252
  from the list of handlers
253
+
254
+ @param [Plugin] plug the plugin whose action handlers should be removed
255
+ @return [nil]
212
256
  =end
213
257
  def remove_plugin_ui_actions plug
214
258
  @actions_state_handlers.delete_if do |state, hs|
215
259
  hs.delete_if{|h| h.plugin == plug}
216
260
  hs.empty?
217
261
  end
262
+ nil
218
263
  end
219
264
 
220
265
  =begin
221
- Sets the UI states defined by the main window to their initial values.
266
+ Gives the UI states their initial values
267
+ @return [nil]
222
268
  =end
223
269
  def setup_initial_states
224
270
  change_state 'active_project_exists', false
225
271
  change_state 'current_document', false
272
+ nil
226
273
  end
227
274
 
275
+ =begin rdoc
276
+ Closes the documents associated with the given project
277
+
278
+ If any document is modified, the user has the possiblity of choosing whether to
279
+ save them, discard the changes or not to close the documents
280
+ @param [Project] prj the project whose documents should be closed
281
+ @return [Boolean] *true* if the documents were correctly closed and *false* otherwise
282
+ =end
228
283
  def close_project_files prj
229
- to_close = @views.select do |v|
230
- prj.project_files.file_in_project? v.document.path
284
+ to_close = Ruber[:documents].documents_with_file.select do |d|
285
+ prj.project_files.file_in_project? d.url.url
231
286
  end
232
- save_documents to_close.map &:document
233
- to_close.each{|v| v.document.close}
287
+ save_documents to_close
288
+ without_activating{to_close.each{|d| d.close}}
234
289
  end
235
290
 
236
-
237
291
  end
238
292
 
239
293
  end