Class: Ruber::World::Environment

Inherits:
Qt::Object
  • Object
show all
Includes:
Activable, Extension
Defined in:
lib/ruber/world/environment.rb

Defined Under Namespace

Classes: ViewList

Constant Summary

DEFAULT_HINTS =

The default hints used by methods like #editor_for and #editor_for!

{
  :exisiting => :always, 
  :strategy => [:current, :current_tab, :first],
  :new => :new_tab,
  :split => :horizontal,
  :show => true,
  :create_if_needed => true
}.freeze

Instance Attribute Summary (collapse)

Attributes included from Extension

plugin

Instance Method Summary (collapse)

Methods included from Extension

#save_settings, #shutdown

Methods included from Activable

#activate, #active=, #active?, #deactivate

Signal Summary

Constructor Details

- (Environment) initialize(prj, parent = nil)

A new instance of Environment



109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/ruber/world/environment.rb', line 109

def initialize prj, parent = nil
  super parent
  @project = prj
  @tab_widget = KDE::TabWidget.new{self.document_mode = true}
  @tab_widget.tabs_closable = true if Ruber[:config][:workspace, :close_buttons]
  connect @tab_widget, SIGNAL('currentChanged(int)'), self, SLOT('current_tab_changed(int)')
  connect @tab_widget, SIGNAL('tabCloseRequested(int)'), self, SLOT('close_tab(int)')
  @views = ViewList.new
  @hint_solver = HintSolver.new @tab_widget, nil, @views.by_activation
  @documents = MutableDocumentList.new
  @active_editor = nil
  @active = false
  @focus_on_editors = true
  unless prj
    @default_document = Ruber[:world].new_document
    @default_document.object_name = 'default_document'
    @default_document.connect(SIGNAL('closing(QObject*)')){@default_document = nil}
    editor_for! @default_document
  end
end

Instance Attribute Details

- (EditorView?) active_editor (readonly)

The active editor or nil if no active editor exists

Returns:

  • (EditorView, nil)

    the active editor or nil if no active editor exists



107
108
109
# File 'lib/ruber/world/environment.rb', line 107

def active_editor
  @active_editor
end

- (Project?) project (readonly)

The project associated with the environment or nil if the environment is not associated with a project

Returns:

  • (Project, nil)

    the project associated with the environment or nil if the environment is not associated with a project



96
97
98
# File 'lib/ruber/world/environment.rb', line 96

def project
  @project
end

- (KDE::TabWidget) tab_widget (readonly)

The tab widget containing the views contained in the environment

Returns:

  • (KDE::TabWidget)

    the tab widget containing the views contained in the environment



102
103
104
# File 'lib/ruber/world/environment.rb', line 102

def tab_widget
  @tab_widget
end

Instance Method Details

- (Object) activate_editor(view)



173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
# File 'lib/ruber/world/environment.rb', line 173

def activate_editor view
  return view if @active_editor == view
  deactivate_editor @active_editor
  if view
    if active?
      Ruber[:main_window].gui_factory.add_client view.send(:internal)
      @active_editor = view
    end
    @views.move_to_front view
    view_tab = tab(view)
    idx = @tab_widget.index_of view_tab
    @tab_widget.set_tab_text idx, view.document.document_name
    @tab_widget.set_tab_icon idx, view.document.icon
    @tab_widget.current_index = idx
  end
  if active?
    emit active_editor_changed(view) 
    view.document.activate if view
  end
  view.set_focus if view and focus_on_editors?
  view
end

Slot Signature:

activate_editor(QWidget*)

- (Object) active_document



197
198
199
# File 'lib/ruber/world/environment.rb', line 197

def active_document
  @active_editor ? @active_editor.document : nil
end

- (Object) add_editor(editor, pane) (private)



301
302
303
304
305
306
307
308
309
310
311
312
313
314
# File 'lib/ruber/world/environment.rb', line 301

def add_editor editor, pane
  maybe_close_default_document editor.document
  @views.add_view editor, pane
  doc = editor.document
  editor.parent.label = label_for_document doc
  unless @documents.include? doc
    @documents.add doc
    connect doc, SIGNAL('document_url_changed(QObject*)'), self, SLOT('document_url_changed(QObject*)')
  end
  connect editor, SIGNAL('focus_in(QWidget*)'), self, SLOT('editor_got_focus(QWidget*)')
  connect doc, SIGNAL('modified_changed(bool, QObject*)'), self, SLOT('document_modified_status_changed(bool, QObject*)')
  connect editor, SIGNAL('focus_out(QWidget*)'), self, SLOT('editor_lost_focus(QWidget*)')
  update_pane pane
end

- (Object) close(mode = :save)



208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
# File 'lib/ruber/world/environment.rb', line 208

def close mode = :save
  if @project then @project.close mode == :save
  else 
    docs_to_close = @views.by_document.to_a.select{|d, v| (d.views - v).empty?}
    docs_to_close.map!{|d| d[0]}
    if mode == :save
      return false unless Ruber[:main_window].save_documents docs_to_close
    end
    emit closing(self)
    self.active = false
    docs_to_close.each{|d| d.close false}
    @views.by_activation.dup.each{|v| v.close}
    delete_later
    true
  end
end

Slot Signature:

close()

- (Object) close_editor(editor, ask = true)



201
202
203
204
205
206
# File 'lib/ruber/world/environment.rb', line 201

def close_editor editor, ask = true
  doc = editor.document
  if doc.views.count > 1 then editor.close
  else doc.close ask
  end
end

- (Object) close_editors(editors, ask = true)



254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
# File 'lib/ruber/world/environment.rb', line 254

def close_editors editors, ask = true
  editors_by_doc = editors.group_by &:document
  docs = editors_by_doc.keys
  to_close = docs.select{|doc| (doc.views - editors_by_doc[doc]).empty?}
  if ask
    return unless Ruber[:main_window].save_documents to_close 
  end
  to_close.each do |doc| 
    doc.close false
    editors_by_doc.delete doc
  end
  editors_by_doc.each_value do |a|
    a.each &:close
  end
end

- (Object) close_tab(idx) (private)



338
339
340
341
# File 'lib/ruber/world/environment.rb', line 338

def close_tab idx
  views = @tab_widget.widget(idx).views
  close_editors views
end

Slot Signature:

close_tab(int)

- (Object) create_tab(view) (private)



405
406
407
408
409
410
411
412
# File 'lib/ruber/world/environment.rb', line 405

def create_tab view
  pane = Pane.new view
  pane.label = label_for_document view.document
  connect pane, SIGNAL('removing_view(QWidget*, QWidget*)'), self, SLOT('remove_editor(QWidget*, QWidget*)')
  connect pane, SIGNAL('pane_split(QWidget*, QWidget*, QWidget*)'), self, SLOT('pane_split(QWidget*, QWidget*, QWidget*)')
  connect pane, SIGNAL('view_replaced(QWidget*, QWidget*, QWidget*)'), self, SLOT('view_replaced(QWidget*, QWidget*, QWidget*)')
  pane
end

- (Object) current_tab_changed(idx) (private)



434
435
436
437
438
439
# File 'lib/ruber/world/environment.rb', line 434

def current_tab_changed idx
  current_tab = @tab_widget.widget idx
  view = idx >= 0 ? @views.by_tab[current_tab][0] : nil
  activate_editor view
  view
end

Slot Signature:

current_tab_changed(int)

- (Object) deactivate_editor(view) (private)



387
388
389
390
391
392
393
# File 'lib/ruber/world/environment.rb', line 387

def deactivate_editor view
  if view and @active_editor == view
    view.document.deactivate
    Ruber[:main_window].gui_factory.remove_client view.send(:internal)
    @active_editor = nil
  end
end

- (Object) display_document(doc, hints = {})



246
247
248
249
250
251
252
# File 'lib/ruber/world/environment.rb', line 246

def display_document doc, hints = {}
  ed = editor_for! doc, hints
  activate_editor ed
  line = hints[:line]
  ed.go_to line, hints[:column] || 0 if hints[:line]
  ed
end

- (Object) do_activation (private)



375
376
377
378
379
380
381
382
383
384
# File 'lib/ruber/world/environment.rb', line 375

def do_activation
  #showing the tab widget may make some editors all receive focus, but we
  #want that setting to be kept until the environment becomes active again,
  #so we store the original value in a temp variable and restore it afterwards
#         old_focus_on_editors = @focus_on_editors
#         @tab_widget.show
#         @focus_on_editors = old_focus_on_editors
  activate_editor @views.by_activation[0]
  super
end

- (Object) do_deactivation (private)



364
365
366
367
368
369
370
371
372
373
# File 'lib/ruber/world/environment.rb', line 364

def do_deactivation
  #hiding the tab widget would make the editors all loose focus, but we
  #want that setting to be kept until the environment becomes active again,
  #so we store the original value in a temp variable and restore it afterwards
  old_focus_on_editors = @focus_on_editors
#         @tab_widget.hide
  deactivate_editor @active_editor
  @focus_on_editors = old_focus_on_editors
  super
end

- (Object) document_modified_status_changed(mod, doc) (private)



465
466
467
468
469
470
471
472
473
# File 'lib/ruber/world/environment.rb', line 465

def document_modified_status_changed mod, doc
  label = label_for_document doc
  @views.by_document[doc].each{|v| v.parent.label = label}
  @tab_widget.each_with_index do |w, i|
    if @views.by_tab[w][0].document == doc 
      @tab_widget.set_tab_icon i, doc.icon
    end
  end
end

Slot Signature:

document_modified_status_changed(bool, QObject*)

- (Object) document_url_changed(doc) (private)



452
453
454
455
456
457
458
459
460
461
462
# File 'lib/ruber/world/environment.rb', line 452

def document_url_changed doc
  @tab_widget.each{|t| update_pane t}
  label = label_for_document doc
  @views.by_document[doc].each{|v| v.parent.label = label}
  @tab_widget.each_with_index do |w, i|
    if @views.by_tab[w][0].document == doc 
      @tab_widget.set_tab_text i, doc.document_name 
      @tab_widget.set_tab_icon i, doc.icon
    end
  end
end

Slot Signature:

document_url_changed(QObject*)

- (Object) documents



150
151
152
# File 'lib/ruber/world/environment.rb', line 150

def documents
  DocumentList.new @documents
end

- (Object) editor_for!(doc, hints = DEFAULT_HINTS)



129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
# File 'lib/ruber/world/environment.rb', line 129

def editor_for! doc, hints = DEFAULT_HINTS
  doc = Ruber[:world].document doc unless doc.is_a? Document
  hints = DEFAULT_HINTS.merge hints
  editor = @hint_solver.find_editor doc, hints
  unless editor
    return nil unless hints[:create_if_needed]
    view_to_split = @hint_solver.place_editor hints
    editor = doc.create_view
    if view_to_split
      orientation = hints[:split] == :vertical ? Qt::Vertical : Qt::Horizontal
      view_to_split.parent.split view_to_split, editor, orientation
    else 
      new_pane = create_tab(editor)
      add_editor editor, new_pane
      @tab_widget.add_tab new_pane, doc.icon, doc.document_name
      new_pane.label = label_for_document doc
    end
  end
  editor
end

- (Object) editor_got_focus(editor) (private)



344
345
346
347
# File 'lib/ruber/world/environment.rb', line 344

def editor_got_focus editor
  @focus_on_editors = true
  activate_editor editor
end

Slot Signature:

editor_got_focus(QWidget*)

- (Object) editor_lost_focus(editor) (private)



350
351
352
353
354
355
356
357
358
359
360
361
# File 'lib/ruber/world/environment.rb', line 350

def editor_lost_focus editor
  #When an editor is closed, the editor's parent pane is made parentless before the removing_editor
  #signal is emitted by the pane, which means the editor is hidden (and thus
  #looses focus) before it is actually closed. We don't want @focus_on_editors
  #to be changed in that case (otherwise closing an editor which had focus
  #would cause focus not to be given to the next active editor). The only
  #check I can think of is whether the editor's parent pane has a parent
  #or not
  if editor.is_active_window and editor.parent.parent
    @focus_on_editors = false 
  end
end

Slot Signature:

editor_lost_focus(QWidget*)

- (Boolean) focus_on_editors?

Returns:

  • (Boolean)


270
271
272
# File 'lib/ruber/world/environment.rb', line 270

def focus_on_editors?
  @views.tabs.empty? || @focus_on_editors
end

- (Object) label_for_document(doc) (private)



395
396
397
398
399
400
401
402
403
# File 'lib/ruber/world/environment.rb', line 395

def label_for_document doc
  url = doc.url
  label = if url.local_file? then doc.path
  elsif url.valid? then url.pretty_url
  else doc.document_name
  end
  label << ' [modified]' if doc.modified?
  label
end

- (Object) maybe_close_default_document(doc) (private)



293
294
295
296
297
298
299
# File 'lib/ruber/world/environment.rb', line 293

def maybe_close_default_document doc
  return unless @default_document
  return if @default_document == doc
  return unless @default_document.pristine?
  return if @default_document.views.count != 1
  @default_document.close
end

- (Object) pane_split(pane, old, new) (private)



414
415
416
# File 'lib/ruber/world/environment.rb', line 414

def pane_split pane, old, new
  add_editor new, tab(pane)
end

Slot Signature:

pane_split(QWidget*, QWidget*, QWidget*)

- (Object) query_close



274
275
276
277
278
279
280
# File 'lib/ruber/world/environment.rb', line 274

def query_close
  if Ruber[:app].status != :asking_to_quit
    docs = @views.by_document.select{|d, v| (d.views - v).empty?}
    Ruber[:main_window].save_documents docs.map{|a| a[0]}
  else true
  end
end

- (Object) remove_editor(pane, editor) (private)



316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
# File 'lib/ruber/world/environment.rb', line 316

def remove_editor pane, editor
  editor_tab = @views.tabs[editor]
  if @active_editor == editor
    to_activate = @views.by_tab[editor_tab][1]
    activate_editor to_activate
    deactivate_editor editor
  end
  disconnect editor, SIGNAL('focus_in(QWidget*)'), self, SLOT('editor_got_focus(QWidget*)')
  disconnect editor, SIGNAL('focus_out(QWidget*)'), self, SLOT('editor_lost_focus(QWidget*)')
  @views.remove_view editor
  unless @views.by_tab[editor_tab]
    @tab_widget.remove_tab @tab_widget.index_of(editor_tab) 
  end
  doc = editor.document
  unless @views.by_document[doc]
    @documents.remove doc 
    disconnect doc, SIGNAL('document_url_changed(QObject*)'), self, SLOT('document_url_changed(QObject*)')
    disconnect doc, SIGNAL('modified_changed(bool, QObject*)'), self, SLOT('document_modified_status_changed(bool, QObject*)')
  end
end

Slot Signature:

remove_editor(QWidget*, QWidget*)

- (Object) remove_from_project



282
283
284
285
286
287
288
289
# File 'lib/ruber/world/environment.rb', line 282

def remove_from_project
  raise "environment not associated with a project" unless @project
  emit closing(self)
  self.active = false
  docs_to_close = @views.by_document.select{|d, v| (d.views - v).empty?}
  docs_to_close.each{|d| d[0].close false}
  @views.dup.by_activation.each{|v| v.close}
end

- (Object) remove_tab(pane) (private)



442
443
444
# File 'lib/ruber/world/environment.rb', line 442

def remove_tab pane
  @tab_widget.remove_tab @tab_widget.index_of(pane)
end

Slot Signature:

remove_tab(QWidget*)

- (Object) replace_editor(old, new)



250
251
252
253
254
255
256
257
258
259
260
261
262
263
# File 'lib/ruber/world/environment.rb', line 250

def replace_editor old, new
  if new.is_a? Document
    new = new.create_view
  elsif new.is_a? String or new.is_a? KDE::Url
    new = Ruber[:world].document(new).create_view
  end
  if old.document.views.count == 1
    return unless old.document.query_close
    close_doc = true
  end
  old.parent.replace_view old, new
  close_editor old, false
  new
end

- (Object) tab(arg)



162
163
164
165
166
167
168
169
170
171
# File 'lib/ruber/world/environment.rb', line 162

def tab arg
  if arg.is_a?(Pane)
    pane = arg
    while parent = pane.parent_pane
      pane = parent
    end
    @tab_widget.index_of(pane) > -1 ? pane : nil
  else @views.tabs[arg]
  end
end

- (Object) tabs



154
155
156
# File 'lib/ruber/world/environment.rb', line 154

def tabs
  @tab_widget.to_a
end

- (Object) update_pane(pane) (private)



427
428
429
430
431
# File 'lib/ruber/world/environment.rb', line 427

def update_pane pane
  docs = @views.by_tab[pane].map(&:document).uniq
  tool_tip = docs.map(&:document_name).join "\n"
  @tab_widget.set_tab_tool_tip @tab_widget.index_of(pane), tool_tip
end

Slot Signature:

update_pane(QWidget*)

- (Object) update_tabs_for_document(doc) (private)



447
448
449
# File 'lib/ruber/world/environment.rb', line 447

def update_tabs_for_document doc
  @tab_widget.each{|w| }
end

Slot Signature:

update_tabs_for_document(QObject*)

- (Object) view_replaced(pane, old, new) (private)



419
420
421
422
423
424
# File 'lib/ruber/world/environment.rb', line 419

def view_replaced pane, old, new
  toplevel_pane = tab(pane)
  add_editor new, toplevel_pane
  remove_editor toplevel_pane, old
  update_pane toplevel_pane
end

Slot Signature:

view_replaced(QWidget*, QWidget*, QWidget*)

- (Object) views(doc = nil)



158
159
160
# File 'lib/ruber/world/environment.rb', line 158

def views doc = nil
  doc ? @views.by_document[doc].dup : @views.by_activation.dup
end

Signal Details

- active_editor_changed(QWidget* arg1)

- deactivated

- activated

- closing(QObject* arg1)