ruber 0.0.8 → 0.0.9

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