ruber 0.0.8 → 0.0.9

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 (81) hide show
  1. data/CHANGES +21 -0
  2. data/data/share/apps/ruber/ruberui.rc +3 -1
  3. data/lib/ruber/application/application.rb +22 -23
  4. data/lib/ruber/application/plugin.yaml +7 -2
  5. data/lib/ruber/{projects → application}/project_files_list.rb +0 -0
  6. data/lib/ruber/{projects → application}/project_files_widget.rb +0 -0
  7. data/lib/ruber/application/ui/project_files_rule_chooser_widget.rb +74 -0
  8. data/lib/ruber/{projects → application}/ui/project_files_rule_chooser_widget.ui +0 -0
  9. data/lib/ruber/application/ui/project_files_widget.rb +117 -0
  10. data/lib/ruber/{projects → application}/ui/project_files_widget.ui +0 -0
  11. data/lib/ruber/component_manager.rb +14 -9
  12. data/lib/ruber/editor/document.rb +35 -5
  13. data/lib/ruber/kde_sugar.rb +16 -0
  14. data/lib/ruber/main_window/choose_plugins_dlg.rb +7 -4
  15. data/lib/ruber/main_window/main_window.rb +131 -193
  16. data/lib/ruber/main_window/main_window_actions.rb +157 -58
  17. data/lib/ruber/main_window/main_window_internal.rb +145 -54
  18. data/lib/ruber/main_window/open_file_in_project_dlg.rb +4 -4
  19. data/lib/ruber/main_window/plugin.yaml +3 -6
  20. data/lib/ruber/main_window/ui/workspace_settings_widget.rb +2 -2
  21. data/lib/ruber/main_window/workspace.rb +62 -32
  22. data/lib/ruber/output_widget.rb +20 -16
  23. data/lib/ruber/pane.rb +11 -5
  24. data/lib/ruber/project.rb +27 -12
  25. data/lib/ruber/projects/ui/project_files_rule_chooser_widget.rb +2 -2
  26. data/lib/ruber/projects/ui/project_files_widget.rb +2 -2
  27. data/lib/ruber/utils.rb +37 -4
  28. data/lib/ruber/version.rb +1 -1
  29. data/lib/ruber/world/document_factory.rb +121 -0
  30. data/lib/ruber/world/document_list.rb +396 -0
  31. data/lib/ruber/world/environment.rb +470 -0
  32. data/lib/ruber/{main_window → world}/hint_solver.rb +1 -1
  33. data/lib/ruber/world/plugin.yaml +11 -0
  34. data/lib/ruber/world/project_factory.rb +131 -0
  35. data/lib/ruber/world/project_list.rb +265 -0
  36. data/lib/ruber/world/ui/workspace_settings_widget.rb +51 -0
  37. data/lib/ruber/{main_window → world}/ui/workspace_settings_widget.ui +0 -0
  38. data/lib/ruber/world/world.rb +307 -0
  39. data/plugins/auto_end/auto_end.rb +135 -9
  40. data/plugins/autosave/autosave.rb +4 -4
  41. data/plugins/find_in_files/find_in_files.rb +5 -5
  42. data/plugins/find_in_files/find_in_files_widgets.rb +1 -1
  43. data/plugins/project_browser/project_browser.rb +4 -4
  44. data/plugins/rake/rake.rb +4 -4
  45. data/plugins/rake/rake_extension.rb +1 -1
  46. data/plugins/rspec/rspec.rb +4 -4
  47. data/plugins/rspec/ruber_rspec_formatter.rb +2 -2
  48. data/plugins/ruby_development/ruby_development.rb +3 -3
  49. data/plugins/ruby_runner/ruby_runner.rb +2 -2
  50. data/plugins/state/plugin.yaml +6 -8
  51. data/plugins/state/state.rb +201 -391
  52. data/plugins/state/ui/config_widget.rb +5 -5
  53. data/plugins/state/ui/config_widget.ui +3 -3
  54. data/plugins/syntax_checker/syntax_checker.rb +4 -0
  55. data/spec/annotation_model_spec.rb +1 -1
  56. data/spec/auto_end_spec.rb +98 -47
  57. data/spec/component_manager_spec.rb +80 -21
  58. data/spec/document_factory_spec.rb +115 -0
  59. data/spec/document_list_spec.rb +560 -450
  60. data/spec/document_spec.rb +143 -55
  61. data/spec/editor_view_spec.rb +2 -2
  62. data/spec/environment_spec.rb +1900 -0
  63. data/spec/hint_solver_spec.rb +5 -5
  64. data/spec/kde_sugar_spec.rb +16 -0
  65. data/spec/output_widget_spec.rb +177 -51
  66. data/spec/pane_spec.rb +29 -5
  67. data/spec/plugin_spec.rb +1 -1
  68. data/spec/project_factory_spec.rb +104 -0
  69. data/spec/project_list_spec.rb +352 -447
  70. data/spec/project_spec.rb +34 -33
  71. data/spec/qt_sugar_spec.rb +2 -2
  72. data/spec/state_spec.rb +508 -811
  73. data/spec/utils_spec.rb +149 -98
  74. data/spec/workspace_spec.rb +120 -9
  75. data/spec/world_spec.rb +1219 -0
  76. metadata +23 -14
  77. data/lib/ruber/documents/document_list.rb +0 -412
  78. data/lib/ruber/documents/plugin.yaml +0 -4
  79. data/lib/ruber/main_window/view_manager.rb +0 -431
  80. data/lib/ruber/projects/plugin.yaml +0 -11
  81. data/lib/ruber/projects/project_list.rb +0 -314
@@ -236,8 +236,8 @@ into account the enabled option and always attempt to save the documents.
236
236
  @return [Boolean] see {#autosave}
237
237
  =end
238
238
  def save_project_files opts, blk
239
- docs = Ruber[:docs].documents_with_file
240
- prj_files = Ruber[:projects].current.project_files.abs
239
+ docs = Ruber[:world].active_environment.documents.documents_with_file
240
+ prj_files = Ruber[:world].active_project.project_files.abs
241
241
  docs = docs.select{|d| prj_files.include? d.path}
242
242
  save_files docs, opts, blk
243
243
  end
@@ -253,7 +253,7 @@ into account the enabled option and always attempt to save the documents.
253
253
  @return [Boolean] see {#autosave}
254
254
  =end
255
255
  def save_open_documents opts, blk
256
- save_files Ruber[:docs].documents, opts, blk
256
+ save_files Ruber[:world].documents, opts, blk
257
257
  end
258
258
 
259
259
  =begin rdoc
@@ -267,7 +267,7 @@ into account the enabled option and always attempt to save the documents.
267
267
  @return [Boolean] see {#autosave}
268
268
  =end
269
269
  def save_documents_with_file opts, blk
270
- save_files Ruber[:docs].documents_with_file, opts, blk
270
+ save_files Ruber[:world].documents.documents_with_file, opts, blk
271
271
  end
272
272
 
273
273
  =begin rdoc
@@ -153,7 +153,7 @@ Replace button
153
153
  =end
154
154
  def find_replace
155
155
  @dlg.clear
156
- @dlg.allow_project = Ruber[:projects].current
156
+ @dlg.allow_project = Ruber[:world].active_project
157
157
  @dlg.exec
158
158
  case @dlg.action
159
159
  when :find then find @dlg.find_text, options_from_dialog
@@ -225,7 +225,7 @@ are saved.
225
225
  @return [Boolean] as {Autosave::AutosavePlugin#autosave AutosavePlugin#autosave}
226
226
  =end
227
227
  def do_autosave places
228
- docs = Ruber[:docs].documents_with_file
228
+ docs = Ruber[:world].documents.documents_with_file
229
229
  if places.is_a? String then docs = docs.select{|d| d.path.start_with? places}
230
230
  else docs = docs.select{|d| places.include? d.path}
231
231
  end
@@ -279,9 +279,9 @@ the following entries:
279
279
  opts[:whole_words] = @dlg.whole_words?
280
280
  places = case @dlg.places
281
281
  when :custom_dir then @dlg.directory
282
- when :project_dir then Ruber[:projects].current.project_directory
283
- when :project_files then Ruber[:projects].current.project_files.abs.to_a
284
- when :open_files then Ruber[:docs].documents_with_file.map{|d| d.path}
282
+ when :project_dir then Ruber[:world].active_project.project_directory
283
+ when :project_files then Ruber[:world].active_project.project_files.abs.to_a
284
+ when :open_files then Ruber[:world].documents.documents_with_file.map{|d| d.path}
285
285
  end
286
286
  opts[:places] = Array(places)
287
287
  opts[:all_files] = @dlg.all_files?
@@ -359,7 +359,7 @@ Items corresponding to successful replacements are removed from the view.
359
359
  def replace
360
360
  failed = {}
361
361
  success = []
362
- docs = Ruber[:docs].documents_with_file.map{|d| [d.path, d]}.to_h
362
+ docs = Ruber[:world].documents.documents_with_file.map{|d| [d.path, d]}.to_h
363
363
  model.each_row.each_with_index do |r, i|
364
364
  if r[0].checked?
365
365
  res = replace_file r[0], docs[r[0].text]
@@ -1,5 +1,5 @@
1
1
  =begin
2
- Copyright (C) 2010 by Stefano Crocco
2
+ Copyright (C) 2010, 2011 by Stefano Crocco
3
3
  stefano.crocco@alice.it
4
4
 
5
5
  This program is free software; you can redistribute it andor modify
@@ -54,7 +54,7 @@ something can be done about it
54
54
  =end
55
55
  def initialize parent = nil
56
56
  super
57
- @project = Ruber[:projects].current
57
+ @project = nil
58
58
  @do_filtering = true
59
59
  self.dynamic_sort_filter = true
60
60
  end
@@ -155,7 +155,7 @@ project, if any
155
155
  =end
156
156
  def initialize parent = nil
157
157
  super
158
- connect Ruber[:projects], SIGNAL('current_project_changed(QObject*)'), self, SLOT('current_project_changed(QObject*)')
158
+ connect Ruber[:world], SIGNAL('active_project_changed(QObject*)'), self, SLOT('current_project_changed(QObject*)')
159
159
  self.layout = Qt::VBoxLayout.new self
160
160
  @view = View.new self
161
161
  @model = KDE::DirModel.new @view
@@ -168,7 +168,7 @@ project, if any
168
168
  @view.header_hidden = true
169
169
  layout.add_widget @view
170
170
  @project = nil
171
- current_project_changed Ruber[:projects].current
171
+ current_project_changed Ruber[:world].active_project
172
172
  @view.connect(SIGNAL('only_project_files_triggered(bool)')){|val| @filter.do_filtering = val}
173
173
  connect @view, SIGNAL('activated(QModelIndex)'), self, SLOT('open_file_in_editor(QModelIndex)')
174
174
  end
@@ -142,8 +142,8 @@ Signal emitted when the rake program started with {#run_rake} has exited
142
142
  Ruber[:main_window].change_state 'rake_running', false
143
143
  end
144
144
  self.connect(SIGNAL(:process_failed_to_start)){Ruber[:main_window].change_state 'rake_running', false}
145
- connect Ruber[:projects], SIGNAL('current_project_changed(QObject*)'), self, SLOT(:set_current_target)
146
- connect Ruber[:main_window], SIGNAL('current_document_changed(QObject*)'), self, SLOT(:set_current_target)
145
+ connect Ruber[:world], SIGNAL('active_project_changed(QObject*)'), self, SLOT(:set_current_target)
146
+ connect Ruber[:world], SIGNAL('active_document_changed(QObject*)'), self, SLOT(:set_current_target)
147
147
  connect self, SIGNAL('process_finished(int, QString)'), self, SIGNAL(:rake_finished)
148
148
  connect self, SIGNAL('extension_added(QString, QObject*)'), self, SLOT(:set_current_target)
149
149
  connect self, SIGNAL('extension_removed(QString, QObject*)'), self, SLOT(:set_current_target)
@@ -437,9 +437,9 @@ it isn't a rakefile
437
437
  and there's no open project
438
438
  =end
439
439
  def find_current_target
440
- target = Ruber[:main_window].current_document.project rescue nil
440
+ target = Ruber[:world].active_document.project rescue nil
441
441
  if target.nil? or !target.has_extension? :rake
442
- prj = Ruber[:projects].current
442
+ prj = Ruber[:world].active_project
443
443
  target = if prj and prj.has_extension? :rake then prj
444
444
  else nil
445
445
  end
@@ -81,7 +81,7 @@ default task
81
81
  def run_rake task
82
82
  params = gather_parameters
83
83
  files = @project.files
84
- docs= Ruber[:documents].documents_with_file.select{|d| files.include? d.path}
84
+ docs= Ruber[:world].documents.documents_with_file.select{|d| files.include? d.path}
85
85
  return unless Ruber[:autosave].autosave Ruber[:rake], docs, :on_failure => :ask
86
86
  ruby, *ruby_opts = Ruber[:rake].ruby_command_for @project, params[:dir]
87
87
  params[:ruby_options] = ruby_opts
@@ -144,7 +144,7 @@ to find out whether the file is a spec file or not.
144
144
  @return [Boolean,nil] wheter or not _file_ is a spec file for the given project
145
145
  or *nil* if no project was specified and there's no open project
146
146
  =end
147
- def spec_file? file, prj = Ruber[:projects].current
147
+ def spec_file? file, prj = Ruber[:world].active_project
148
148
  return nil unless prj
149
149
  dir = prj[:rspec, :spec_directory, :absolute]
150
150
  return false unless file.start_with? dir
@@ -306,7 +306,7 @@ Runs all the specs for the project.
306
306
  @return [nil]
307
307
  =end
308
308
  def run_all
309
- prj = Ruber[:projects].current_project
309
+ prj = Ruber[:world].active_project
310
310
  unless prj
311
311
  KDE::MessageBox.error nil, "You must have an open project to choose this entry.\nYOU SHOULD NEVER SEE THIS MESSAGE"
312
312
  return
@@ -337,7 +337,7 @@ which, most likely, will cause it to fail.
337
337
  (including the case when the process was already running or autosaving failed)
338
338
  =end
339
339
  def run_current what = :all
340
- prj = Ruber[:projects].current_project
340
+ prj = Ruber[:world].active_project
341
341
  unless prj
342
342
  KDE::MessageBox.error nil, "You must have an open project to choose this entry.\nYOU SHOULD NEVER SEE THIS MESSAGE"
343
343
  return
@@ -451,7 +451,7 @@ It does nothing if the file corresponding to the current document isn't found
451
451
  =end
452
452
  def switch
453
453
  file = Ruber[:main_window].current_document.path
454
- prj = Ruber[:projects].current_project
454
+ prj = Ruber[:world].active_project
455
455
  if spec_file? file, prj then switch_to = file_for_spec prj, file
456
456
  else switch_to = specs_for_file(options(prj), file)[0]
457
457
  end
@@ -301,8 +301,8 @@ example
301
301
  hash = {}
302
302
  hash[:type] = :pending
303
303
  hash[:description] = ex.metadata[:full_description]
304
- hash[:message] = ex.metadata[:execution_result][:exception_encountered].message
305
- hash[:location] = ex[:metadata][:location]
304
+ hash[:message] = ex.metadata[:execution_result][:pending_message]
305
+ hash[:location] = ex.metadata[:location]
306
306
  write_data hash
307
307
  end
308
308
 
@@ -156,7 +156,7 @@ started correctly or not.
156
156
  @see #run_file
157
157
  =end
158
158
  def run
159
- if Ruber[:projects].current then run_project
159
+ if Ruber[:world].active_project then run_project
160
160
  elsif (doc = Ruber[:main_window].current_document) then run_document doc
161
161
  else run_file
162
162
  end
@@ -178,7 +178,7 @@ started successfully.
178
178
  @see #run_ruby_for
179
179
  =end
180
180
  def run_project
181
- prj = Ruber.current_project
181
+ prj = Ruber[:world].active_project
182
182
  data = prj[:ruby]
183
183
  prog = Pathname.new(data[:main_program, :abs])
184
184
  wdir = Pathname.new(data[:working_dir, :abs]||prj.project_dir)
@@ -259,7 +259,7 @@ was started. If the user pressed the Cancel button of the dialog, *nil* is retur
259
259
  file = url.to_encoded.to_s
260
260
  end
261
261
 
262
- if doc = Ruber[:docs].document_for_url(url)
262
+ if doc = Ruber[:world].documents.document_for_url(url)
263
263
  return run_document doc
264
264
  end
265
265
 
@@ -355,8 +355,8 @@ to it
355
355
  when Document
356
356
  cont << (ignore_project ? (target.own_project) : target.project)
357
357
  when String
358
- if !ignore_project and Ruber[:projects].project_for_file target
359
- cont << Ruber[:projects].current
358
+ if !ignore_project and Ruber[:world].projects.project_for_file target
359
+ cont << Ruber[:world].active_project
360
360
  end
361
361
  end
362
362
  cont << Ruber[:config]
@@ -9,17 +9,15 @@ class: Ruber::State::Plugin
9
9
  require: state
10
10
  config_options:
11
11
  state:
12
- open_documents: {default: []}
13
- open_projects: {default: []}
14
12
  restore_cursor_position: {default: true}
15
- restore_project_files: {default: true}
16
- startup_behaviour: {default: :restore_all}
17
- tabs: {default: []}
18
- active_view: {default: nil}
19
- cursor_positions: {default: []}
13
+ restore_projects: {default: true}
14
+ startup_behaviour: {default: [:default_environment, :projects]}
15
+ last_state: {default: []}
16
+ default_environment_tabs: {default: []}
17
+ default_environment_active_view: {default: nil}
18
+ default_environment_cursor_positions: {default: []}
20
19
  project_options:
21
20
  state:
22
- open_documents: {default: [], type: session, scope: global}
23
21
  tabs: {default: [], scope: global, type: session}
24
22
  cursor_positions: {default: [], type: session, scope: global }
25
23
  active_view: {default: ~, type: session, scope: global}
@@ -51,205 +51,67 @@ user preferences) when the application starts up.
51
51
  =end
52
52
  module State
53
53
 
54
- =begin rdoc
55
- Plugin object for the State plugin
56
-
57
- @api_method #with
58
- @api_method #restore
59
- @api_method #restore_document
60
- @api_method #restore_project
61
- =end
62
- class Plugin < Ruber::Plugin
54
+ module EnvironmentState
63
55
 
64
56
  =begin rdoc
65
- @param [Ruber::PluginSpecification] psf the plugin specification object associated
66
- with the plugin
67
- =end
68
- def initialize psf
69
- super
70
- @force_restore_project_files = nil
71
- @force_restore_cursor_position = nil
72
- end
73
-
74
- =begin rdoc
75
- Override of {PluginLike#delayed_initialize}
76
-
77
- If the application is starting and there's no open project and a single, pristine
78
- document, it uses the {#restore_last_state} method to restore the last state Ruber
79
- was according to the user preferences.
80
-
81
- @return [nil]
82
- =end
83
- def delayed_initialize
84
- return unless Ruber[:app].starting?
85
- if Ruber[:projects].to_a.empty? and Ruber[:docs].to_a.size == 1 and
86
- Ruber[:docs][0].pristine?
87
- restore_last_state
88
- end
89
- nil
90
- end
91
-
92
- =begin rdoc
93
- Tells whether or not the cursor position should be restored.
94
-
95
- This takes into account user settings and eventual requests made by the programmer
96
- using the {#with} method
97
- @return [Boolean] *true* if the cursor position should be restored and *false*
98
- otherwise
99
- =end
100
- def restore_cursor_position?
101
- if @force_restore_cursor_position.nil?
102
- Ruber[:config][:state, :restore_cursor_position]
103
- else @force_restore_cursor_position
104
- end
105
- end
106
-
107
- =begin rdoc
108
- Tells whether or not the open files in the project should be restored.
57
+ The open tabs configuration in a form suitable to be written to a configuration object
109
58
 
110
- This takes into account user settings and eventual requests made by the programmer
111
- using the {#with} method
112
- @return [Boolean] *true* if the open files in the project should be restored and *false*
113
- otherwise
114
- =end
115
- def restore_project_files?
116
- if @force_restore_project_files.nil?
117
- Ruber[:config][:state, :restore_project_files]
118
- else @force_restore_project_files
119
- end
120
- end
121
-
122
- =begin rdoc
123
- Executes a block temporarily overriding the user's settings about what should be
124
- restored and what shouldn't.
125
-
126
- Nested calls to this method are allowed. By default, the outer call wins over the
127
- inner, meaning that a value set by the inner call are only used if the outer
128
- call didn't set that value. You can change this behaviour by passing the @:force@
129
- option.
130
- @param [Hash] hash the settings to change. All settings not specified here will
131
- remain as chosen by the user
132
- @option hash [Boolean] :force (false) if *true*, in case of a nested call to this
133
- method, the values specified by the inner call will override values set by the
134
- outer call.
135
- @option hash [Boolean] :restore_cursor_position (false) whether or not the cursor position
136
- in documents should be restored, regardless of what the user chose
137
- @option hash [Boolean] :restore_project_files (false) whether or not the open
138
- files in projects should be restored, regardless of what the user chose
139
- @return [Object] the value returned by the block
59
+ @return [Hash] A hash containing the following keys:
60
+ * @:tabs@: an array of arrays, with each inner array representing one tab, with
61
+ the format described in {#restore_pane}. This value is the one to write under
62
+ the @state/tabs@ entry in a project or configuration object
63
+ * @:cursor_positions@:an array of arrays. Each inner array corresponds to a tab
64
+ and contains the cursor position of each view. Each cursor position is represented
65
+ as an array with two elements: the first is the line, the second is the column.
66
+ The order the views are is the same used by {Pane#each_view}. This value is the one to write under
67
+ the @state/cursor_positions@ entry in a project or configuration object
68
+ * @:active_view@: the active view. It is represented by a size 2 array, with the
69
+ first element being the index of the tab of the active view and the second being
70
+ the index of the view in the corresponding pane (according to the order used by
71
+ {Pane#each_view}). If there's no active view, this entry is *nil*. This is the value to write under
72
+ the @state/active_view@ entry in a project or configuration object
140
73
  =end
141
- def with hash
142
- old_doc = @force_restore_cursor_position
143
- old_projects = @force_restore_project_files
144
- if hash.has_key? :restore_cursor_position
145
- if @force_restore_cursor_position.nil? or hash[:force]
146
- @force_restore_cursor_position = hash[:restore_cursor_position] || false
74
+ def tabs_state env
75
+ res = {}
76
+ doc_map = {}
77
+ doc_idx = 0
78
+ env.documents.each do |doc|
79
+ if !doc.has_file?
80
+ doc_map[doc] = doc_idx
81
+ doc_idx += 1
147
82
  end
148
83
  end
149
- if hash.has_key? :restore_project_files
150
- if @force_restore_project_files.nil? or hash[:force]
151
- @force_restore_project_files = hash[:restore_project_files] || false
84
+ tabs = env.tabs
85
+ tabs_tree = []
86
+ cursor_positions = []
87
+ tabs.each do |t|
88
+ tabs_tree << tab_to_tree(t, doc_map)
89
+ cursor_positions << t.map do |v|
90
+ pos = v.cursor_position
91
+ [pos.line, pos.column]
152
92
  end
153
93
  end
154
- begin yield
155
- ensure
156
- @force_restore_cursor_position = old_doc
157
- @force_restore_project_files = old_projects
94
+ res[:tabs] = tabs_tree
95
+ res[:cursor_positions] = cursor_positions
96
+ active = env.views[0]
97
+ if active
98
+ active_tab = env.tab(active)
99
+ res[:active_view] = [tabs.index(active_tab), active_tab.to_a.index(active)]
158
100
  end
101
+ res
159
102
  end
160
103
 
161
- =begin rdoc
162
- Restores the given document
163
-
164
- @see DocumentExtension#restore DocumentExtension#restore for more information
165
-
166
- @param [Ruber::Document] doc the document to restore
167
- @return [nil]
168
- =end
169
- def restore_document doc
170
- doc.extension(:state).restore
171
- end
172
-
173
- =begin rdoc
174
- Restores the given global project
175
-
176
- @see ProjectExtension#restore ProjectExtension#restore for more information
177
-
178
- @param [Ruber::Project] prj the document to restore
179
- @return [nil]
180
- =end
181
- def restore_project prj
182
- prj.extension(:state).restore
183
- end
184
-
185
- =begin rdoc
186
- Restores the open projects according to a given configuration object
187
-
188
- Restoring the project means closing all the open projects and opening the projects
189
- and setting the active project according to the information in _conf_
190
-
191
- This method is called both when the session is restored and when ruber starts
192
- up (if the user chose so).
193
-
194
- @param [#[Symbol, Symbol]] conf the object from which to read the state. See {#restore}
195
- for more information
196
- @return [nil]
197
- =end
198
- def restore_projects conf = Ruber[:config]
199
- projects = Ruber[:projects]
200
- projects.to_a.each{|pr| projects.close_project pr}
201
- file = conf[:state, :open_projects][0]
202
- if file
203
- prj = Ruber[:main_window].safe_open_project file
204
- Ruber[:projects].current_project = prj if prj
205
- end
206
- nil
207
- end
208
-
209
- =begin rdoc
210
- Restores the open documents according to a given configuration object
211
-
212
- Restoring the open documents means:
213
- * closing all the open documents. If any of thess is modified, the user is asked
214
- how to proceed. If the choses to abort, nothing else is done
215
- * opening the documents according to the @state/open_documents@ entry of _conf_
216
- * recreating the tabs and the editors according to the @state/tabs@ entry of _conf_
217
- * activating the editor contained in the @state/active_editor@ entry of _conf_
218
-
219
- This method is called both when the session is restored and when ruber starts
220
- up (if the user chose so).
221
-
222
- @param [#[Symbol, Symbol]] conf the object from which to read the state. See {#restore}
223
- for more information
224
- @return [nil]
225
- =end
226
- def restore_documents config = Ruber[:config]
227
- return unless Ruber[:documents].close_all
228
- docs = config[:state, :open_documents]
104
+ def restore_environment env, data
229
105
  unnamed_docs = []
230
- docs = docs.map do |i|
231
- if i.is_a?(String) then Ruber[:documents].document(i)
232
- else
233
- doc = Ruber[:documents].new_document
234
- unnamed_docs << doc
235
- doc
236
- end
106
+ env.close_editors env.views, false
107
+ data[:tabs].each_with_index do |t, i|
108
+ restore_tab env, t, data[:cursor_positions][i] || [], unnamed_docs
237
109
  end
238
- return if docs.empty?
239
- tabs = config[:state, :tabs]
240
- mw = Ruber[:main_window]
241
- positions = config[:state, :cursor_positions]
242
- tabs.each_with_index do |t, i|
243
- pn = restore_pane t, unnamed_docs
244
- views = pn.to_a
245
- views.each_with_index do |v, j|
246
- cursor = KTextEditor::Cursor.new(*(positions[i][j] rescue [0,0]))
247
- v.cursor_position = cursor
248
- end
249
- end
250
- active_editor = config[:state, :active_view]
110
+ active_editor = data[:active_view]
251
111
  if active_editor
252
- mw.focus_on_editor mw.tabs[active_editor[0]].to_a[active_editor[1]]
112
+ editor = env.tabs[active_editor[0]].to_a[active_editor[1]]
113
+ env.activate_editor editor
114
+ editor.set_focus if editor
253
115
  end
254
116
  end
255
117
 
@@ -279,8 +141,8 @@ format:
279
141
  _n_ in _docs_
280
142
  @return [Pane] the new pane
281
143
  =end
282
- def restore_pane data, docs
283
- mw = Ruber[:main_window]
144
+ def restore_tab env, tab, cursor_positions, unnamed_docs
145
+ world = Ruber[:world]
284
146
  find_first_view = lambda do |array|
285
147
  if array.size == 1 then array[0]
286
148
  elsif array[1].is_a? Array then find_first_view.call array[1]
@@ -295,97 +157,181 @@ format:
295
157
  #the first view, which is already contained in the pane
296
158
  next if i < 2
297
159
  view = e.is_a?(Array) ? find_first_view.call(e) : e
298
- view = mw.editor_for! view.is_a?(String) ? view: docs[view],
299
- :existing => :never, :show => false
160
+ if view.is_a?(String)
161
+ doc = world.document(KDE::Url.new(view)) || world.new_document
162
+ else doc = unnamed_docs[view] ||= world.new_document
163
+ end
164
+ view = doc.create_view
300
165
  pn.split last_view, view, orientation
301
166
  last_view = view
302
167
  recreate_pane.call view.parent, e if e.is_a? Array
303
168
  end
304
169
  recreate_pane.call pn.splitter.widget(0), array[1] if array[1].is_a?(Array)
305
170
  end
306
- view = find_first_view.call data
307
- view = mw.editor_for! view.is_a?(String) ? view : docs[view],
308
- :existing => :never, :new => :new_tab
171
+ view = find_first_view.call tab
172
+ if view.is_a?(String)
173
+ doc = world.document(KDE::Url.new(view))
174
+ else doc = unnamed_docs[view] ||= Ruber[:world].new_document
175
+ end
176
+ view = env.editor_for! doc, :existing => :never, :new => :new_tab
309
177
  pane = view.parent
310
- recreate_pane.call pane, data
178
+ recreate_pane.call pane, tab
179
+ pane.views.each_with_index do |v, i|
180
+ pos = cursor_positions[i]
181
+ v.go_to *pos if pos
182
+ end
311
183
  pane
312
184
  end
313
185
 
186
+ private
187
+
314
188
  =begin rdoc
315
- Restores ruber state according to the user settings and the data stored in the given object
316
-
317
- The argument can be any object which has a @[]@ method which takes two arguments
318
- and behaves as the hash returned by {#gather_settings}.
189
+ A representation of a pane's configuration suitable to be written to a configuration
190
+ object
319
191
 
320
- @param [#[Symbol, Symbol]] conf the object from which to read the state
321
- @return [nil]
192
+ @param [Pane] pane the pane to return the representation for
193
+ @param [Hash{Document=>Integer}] docs a map between documents not associated
194
+ with files and the number to represent them
195
+ @return [Array<Array,Integer,String>] an array as described in {#restore_pane}
322
196
  =end
323
- def restore cfg = Ruber[:config]
324
- if !cfg[:state, :open_projects].empty? then restore_projects cfg
325
- else restore_documents cfg
197
+ def tab_to_tree pane, docs
198
+ if pane.single_view?
199
+ doc = pane.view.document
200
+ return [doc.has_file? ? doc.url.url : docs[doc]]
326
201
  end
327
- nil
202
+ panes = {}
203
+ tab_to_tree_prc = lambda do |pn|
204
+ if pn.single_view?
205
+ doc = pn.view.document
206
+ panes[pn.parent_pane] << (doc.has_file? ? doc.url.url : docs[doc])
207
+ else
208
+ data = [pn.orientation]
209
+ panes[pn] = data
210
+ panes[pn.parent_pane] << data if pn.parent_pane
211
+ end
212
+ end
213
+ tab_to_tree_prc.call pane
214
+ pane.each_pane :recursive, &tab_to_tree_prc
215
+ panes[pane]
328
216
  end
329
-
217
+
218
+ end
219
+
330
220
  =begin rdoc
331
- Restores Ruber's state according to the user settings so that it matches the state
332
- it was when it was last shut down
221
+ Plugin object for the State plugin
222
+ =end
223
+ class Plugin < Ruber::Plugin
224
+
225
+ include EnvironmentState
226
+
227
+ =begin rdoc
228
+ @param [Ruber::PluginSpecification] psf the plugin specification object associated
229
+ with the plugin
230
+ =end
231
+ def initialize psf
232
+ super
233
+ @force_restore_project_files = nil
234
+ @force_restore_cursor_position = nil
235
+ end
236
+
237
+ =begin rdoc
238
+ Override of {PluginLike#delayed_initialize}
333
239
 
334
- The state information is read from the global configuration object.
240
+ If the application is starting and there's no open project and a single, pristine
241
+ document, it uses the {#restore_last_state} method to restore the last state Ruber
242
+ was according to the user preferences.
335
243
 
336
244
  @return [nil]
337
245
  =end
338
- def restore_last_state
339
- case Ruber[:config][:state, :startup_behaviour]
340
- when :restore_all then restore
341
- when :restore_projects_only
342
- with(:restore_project_files => false){restore_projects}
343
- when :restore_documents_only then restore_documents
246
+ def delayed_initialize
247
+ return unless Ruber[:app].starting?
248
+ docs = Ruber[:world].documents
249
+ if Ruber[:world].projects.empty? and docs.size == 1 and docs[0].pristine?
250
+ Ruber[:app].sessionRestored? ? restore_last_state(:force) : restore_last_state
344
251
  end
252
+ connect Ruber[:world], SIGNAL('project_created(QObject*)'), self, SLOT('restore_project(QObject*)')
253
+ nil
345
254
  end
346
-
255
+
256
+ def restore_project prj
257
+ prx = prj[:state]
258
+ data = {
259
+ :tabs => prx[:tabs],
260
+ :cursor_positions => prx[:cursor_positions],
261
+ :active_view => prx[:active_view]
262
+ }
263
+ env = Ruber[:world].environment(prj)
264
+ if Ruber[:config][:state, :restore_projects] and env.tabs.count == 0
265
+ restore_environment env, data
266
+ end
267
+ end
268
+ slots 'restore_project(QObject*)'
269
+
347
270
  =begin rdoc
348
- Restores Ruber's state as it was in last session
271
+ Restores Ruber's state according to the user settings so that it matches the state
272
+ it was when it was last shut down
349
273
 
350
- Since this method deals with session management, it ignores the user settings
274
+ The state information is read from the global configuration object.
351
275
 
352
276
  @return [nil]
353
277
  =end
354
- def restore_session data
355
- hash = data['State'] || {:open_projects => [], :open_documents => [], :active_view => nil, :tabs => []}
356
- hash = hash.map_hash{|k, v| [[:state, k], v]}
357
- def hash.[] k, v
358
- super [k, v]
278
+ def restore_last_state mode = nil
279
+ force = mode == :force
280
+ cfg = Ruber[:config][:state]
281
+ if force or cfg[:startup_behaviour].include? :default_environment
282
+ default_env_data = {
283
+ :tabs => cfg[:default_environment_tabs],
284
+ :active_view => cfg[:default_environment_active_view],
285
+ :cursor_positions => cfg[:default_environment_cursor_positions]
286
+ }
287
+ restore_environment Ruber[:world].default_environment, default_env_data
359
288
  end
360
- with(:restore_project_files => true, :restore_cursor_position => true, :force => true) do
361
- restore hash
289
+ active_prj = nil
290
+ if force || cfg[:startup_behaviour].include?(:projects)
291
+ cfg[:last_state].each_with_index do |f, i|
292
+ next if f.nil?
293
+ begin prj = Ruber[:world].project f
294
+ rescue Ruber::AbstractProject::InvalidProjectFile
295
+ next
296
+ end
297
+ active_prj = prj if i == 0
298
+ data = {
299
+ :tabs => prj[:state, :tabs],
300
+ :cursor_positions => prj[:state, :cursor_positions],
301
+ :active_view => prj[:state, :active_view]
302
+ }
303
+ restore_environment Ruber[:world].environment(prj), data
304
+ end
305
+ Ruber[:world].active_project = active_prj
362
306
  end
363
- nil
364
307
  end
365
-
308
+
366
309
  =begin rdoc
367
310
  Saves Ruber's state to the global config object
368
311
 
369
312
  @return [nil]
370
313
  =end
371
314
  def save_settings
372
- h = gather_settings
373
- cfg = Ruber[:config]
374
- h.each_pair do |k, v|
375
- cfg[:state, k] = v
315
+ files = Ruber[:world].environments.map do |e|
316
+ prj = e.project
317
+ prj ? prj.project_file : nil
376
318
  end
319
+ active_env = Ruber[:world].active_environment
320
+ if active_env and active_env.project
321
+ active_project = active_env.project.project_file
322
+ else active_project = nil
323
+ end
324
+ files.unshift files.delete(active_project)
325
+ Ruber[:config][:state, :last_state] = files
326
+ default_env_state = tabs_state Ruber[:world].default_environment
327
+ Ruber[:config][:state, :default_environment_tabs] = default_env_state[:tabs]
328
+ Ruber[:config][:state, :default_environment_active_view] =
329
+ default_env_state[:active_view]
330
+ Ruber[:config][:state, :default_environment_cursor_positions] =
331
+ default_env_state[:cursor_positions]
377
332
  nil
378
333
  end
379
334
 
380
- =begin rdoc
381
- Override of {PluginLike#session_data}
382
-
383
- @return [Hash] a hash containing the session information under the @State@ key
384
- =end
385
- def session_data
386
- {'State' => gather_settings}
387
- end
388
-
389
335
  =begin rdoc
390
336
  The open projects in a form suitable to be written to a configuration object
391
337
 
@@ -395,129 +341,13 @@ The open projects in a form suitable to be written to a configuration object
395
341
  object
396
342
  =end
397
343
  def projects_state
398
- projects = Ruber[:projects].projects.map{|pr| pr.project_file}
344
+ projects = Ruber[:world].projects.map{|pr| pr.project_file}
399
345
  unless projects.empty?
400
- active_prj = Ruber[:projects].current
346
+ active_prj = Ruber[:world].active_document
401
347
  projects.unshift projects.delete(active_prj.project_file) if active_prj
402
348
  end
403
349
  projects
404
350
  end
405
-
406
- =begin rdoc
407
- The open documents in a form suitable to be written to a configuration object
408
-
409
- @return [Array<String,nil>] an array containing the names of the URLs associated with
410
- the currently open documents. Documents not associated with files are represented
411
- by *nil*s in the array. This value is the one to write under the @state/open_documents@
412
- entry in a project or configuration object
413
- =end
414
- def documents_state
415
- docs = Ruber[:documents].documents
416
- docs.map{ |doc| doc.has_file? ? doc.url.to_encoded.to_s : nil}
417
- end
418
-
419
- =begin rdoc
420
- The open tabs configuration in a form suitable to be written to a configuration object
421
-
422
- @return [Hash] A hash containing the following keys:
423
- * @:tabs@: an array of arrays, with each inner array representing one tab, with
424
- the format described in {#restore_pane}. This value is the one to write under
425
- the @state/tabs@ entry in a project or configuration object
426
- * @:cursor_positions@:an array of arrays. Each inner array corresponds to a tab
427
- and contains the cursor position of each view. Each cursor position is represented
428
- as an array with two elements: the first is the line, the second is the column.
429
- The order the views are is the same used by {Pane#each_view}. This value is the one to write under
430
- the @state/cursor_positions@ entry in a project or configuration object
431
- * @:active_view@: the active view. It is represented by a size 2 array, with the
432
- first element being the index of the tab of the active view and the second being
433
- the index of the view in the corresponding pane (according to the order used by
434
- {Pane#each_view}). If there's no active view, this entry is *nil*. This is the value to write under
435
- the @state/active_view@ entry in a project or configuration object
436
- =end
437
- def tabs_state
438
- res = {}
439
- doc_map = {}
440
- doc_idx = 0
441
- Ruber[:documents].each do |doc|
442
- if !doc.has_file?
443
- doc_map[doc] = doc_idx
444
- doc_idx += 1
445
- end
446
- end
447
- tabs = Ruber[:main_window].tabs
448
- tabs_tree = []
449
- cursor_positions = []
450
- tabs.each do |t|
451
- tabs_tree << tab_to_tree(t, doc_map)
452
- cursor_positions << t.map do |v|
453
- pos = v.cursor_position
454
- [pos.line, pos.column]
455
- end
456
- end
457
- res[:tabs] = tabs_tree
458
- res[:cursor_positions] = cursor_positions
459
- active = Ruber[:main_window].active_editor
460
- if active
461
- active_tab = Ruber[:main_window].tab(active)
462
- res[:active_view] = [tabs.index(active_tab), active_tab.to_a.index(active)]
463
- end
464
- res
465
- end
466
-
467
- private
468
-
469
- =begin rdoc
470
- Creates a hash with all the data needed to restore Ruber's state
471
-
472
- @return [Hash] a hash with the following keys:
473
- * @:open_projects@: an array containing the project file of each open project.
474
- the first entry is the active project
475
- * @:open_documents@: an array with the name of the file corresponding to each
476
- open document (documents without an associated file can't be restored and aren't
477
- included). The order is that of opening
478
- * @:visible_documents@: an array with the name of the files corresponding to the
479
- documents associated with a file and having a view
480
- * @:active_document@: the name of the file associated with the active document or
481
- *nil* if there's no open document
482
- =end
483
- def gather_settings
484
- res = {
485
- :open_projects => projects_state,
486
- :open_documents => documents_state
487
- }
488
- res.merge! tabs_state
489
- res
490
- end
491
-
492
- =begin rdoc
493
- A representation of a pane's configuration suitable to be written to a configuration
494
- object
495
-
496
- @param [Pane] pane the pane to return the representation for
497
- @param [Hash{Document=>Integer}] docs a map between documents not associated
498
- with files and the number to represent them
499
- @return [Array<Array,Integer,String>] an array as described in {#restore_pane}
500
- =end
501
- def tab_to_tree pane, docs
502
- if pane.single_view?
503
- doc = pane.view.document
504
- return [doc.has_file? ? doc.url.url : docs[doc]]
505
- end
506
- panes = {}
507
- tab_to_tree_prc = lambda do |pn|
508
- if pn.single_view?
509
- doc = pn.view.document
510
- panes[pn.parent_pane] << (doc.has_file? ? doc.url.url : docs[doc])
511
- else
512
- data = [pn.orientation]
513
- panes[pn] = data
514
- panes[pn.parent_pane] << data if pn.parent_pane
515
- end
516
- end
517
- tab_to_tree_prc.call pane
518
- pane.each_pane :recursive, &tab_to_tree_prc
519
- panes[pane]
520
- end
521
351
 
522
352
  end
523
353
 
@@ -594,7 +424,7 @@ is created
594
424
  @return [nil]
595
425
  =end
596
426
  def auto_restore view
597
- restore view if Ruber[:state].restore_cursor_position?
427
+ restore view if Ruber[:config][:state, :restore_cursor_position] #.restore_cursor_position?
598
428
  connect view, SIGNAL('focus_in(QWidget*)'), self, SLOT('view_received_focus(QWidget*)')
599
429
  nil
600
430
  end
@@ -641,6 +471,8 @@ when the project was last closed
641
471
 
642
472
  include Extension
643
473
 
474
+ include EnvironmentState
475
+
644
476
  slots :auto_restore, :save_settings
645
477
 
646
478
  =begin rdoc
@@ -649,21 +481,8 @@ when the project was last closed
649
481
  def initialize prj
650
482
  super
651
483
  @project = prj
652
- connect @project, SIGNAL(:activated), self, SLOT(:auto_restore)
653
- connect @project, SIGNAL(:deactivated), self, SLOT(:save_settings)
654
- end
655
-
656
- =begin rdoc
657
- Restore Ruber's state as it was when the project was last closed
658
-
659
- See {Plugin#restore_documents} for more information
660
-
661
- @return [nil]
662
- =end
663
-
664
- def restore
665
- Ruber[:state].restore_documents @project
666
- nil
484
+ # connect @project, SIGNAL(:activated), self, SLOT(:auto_restore)
485
+ # connect @project, SIGNAL(:deactivated), self, SLOT(:save_settings)
667
486
  end
668
487
 
669
488
  =begin rdoc
@@ -675,27 +494,13 @@ in the views and the active view
675
494
  @return [nil]
676
495
  =end
677
496
  def save_settings
678
- @project[:state, :open_documents] = Ruber[:state].documents_state
679
- tabs_state = Ruber[:state].tabs_state
680
- [:tabs, :cursor_positions, :active_view].each do |e|
681
- @project[:state, e] = tabs_state[e]
682
- end
497
+ state = tabs_state Ruber[:world].environment @project
498
+ @project[:state, :tabs] = state[:tabs]
499
+ @project[:state, :active_view] = state[:active_view]
500
+ @project[:state, :cursor_positions] = state[:cursor_positions]
683
501
  nil
684
502
  end
685
503
 
686
- private
687
-
688
- =begin rdoc
689
- Restores the project's state when a new project is activated
690
-
691
- It does nothing if the user choosed not to restore the projects's state.
692
- @return [nil]
693
- =end
694
- def auto_restore
695
- @project.disconnect SIGNAL(:activated), self, SLOT(:auto_restore)
696
- restore if Ruber[:state].restore_project_files?
697
- end
698
-
699
504
  end
700
505
 
701
506
  =begin rdoc
@@ -706,7 +511,12 @@ Configuration widget for the State plugin
706
511
  =begin rdoc
707
512
  A list of different behaviour the plugin can have at startup
708
513
  =end
709
- STARTUP_BEHAVIOURS = [:restore_all, :restore_documents_only, :restore_projects_only, :restore_nothing]
514
+ STARTUP_BEHAVIOURS = [
515
+ [:default_environment, :projects],
516
+ [:projects],
517
+ [:default_environment],
518
+ []
519
+ ]
710
520
 
711
521
  =begin rdoc
712
522
  @param [Qt::Widget, nil] parent the parent widget