ruber 0.0.5 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
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