Class: Ruber::World::HintSolver

Inherits:
Object
  • Object
show all
Defined in:
lib/ruber/world/hint_solver.rb

Overview

Helper class used by MainWindow#editor_for and friends to find out which editor should use or where the new editor should be placed according to the hints given them

Instance Method Summary (collapse)

Constructor Details

- (HintSolver) initialize(tabs, manager, view_order)

A new instance of HintSolver

Parameters:

  • tabs (KDE::TabWidget)

    the tab widget which contains the tabs

  • manager (KParts::PartManager)

    the part manager used by the main window

  • view_order (Array<EditorView>)

    an array specifying the order in which views were activated. Most recently activated views corresponds to lower indexes. It’s assumed that the main window will keep a reference to this array and update it whenever a view becomes activated



43
44
45
46
47
# File 'lib/ruber/world/hint_solver.rb', line 43

def initialize tabs, manager, view_order
  @tabs = tabs
  @part_manager = manager
  @view_order = view_order
end

Instance Method Details

- (EditorView?) choose_editor(doc, editors, hints) (private)

Chooses an editor according to the value of the :strategy hint

For each strategy specified in the hint, this method calls a method called choose_editor_*_strategy, where the * stands for the strategy name.

If there’s no editor satsifying the given strategy, then the :next strategy, which always gives a result, is used.

Parameters:

  • doc (Document)

    the document associated with the editor

  • editors (Array<EditorView>)

    a list of the editors to choose among. They should be ordered by tab and, within the same tab, from left to right and top to bottom

Returns:

  • (EditorView, nil)

    an editor view according to the :strategy hint or nil if editors is empty



117
118
119
120
121
122
123
124
125
126
127
128
129
# File 'lib/ruber/world/hint_solver.rb', line 117

def choose_editor doc, editors, hints
  case editors.size
  when 0 then nil
  when 1 then editors.first
  else
    editor = nil
    (Array(hints[:strategy]) + [:next]).each do |s|
      editor = send "choose_editor_#{s}_strategy", doc, editors, hints
      break if editor
    end
    editor
  end
end

- (EditorView?) choose_editor_current_strategy(doc, editors, hints) (private)

Chooses an editor according to the current strategy

Parameters:

  • doc (Document)

    the document associated with the editor

  • editors (Array<EditorView>)

    a list of the editors to choose among. They should be ordered by tab and, within the same tab, from left to right and top to bottom

Returns:

  • (EditorView, nil)

    the current editor if it is associated with doc and nil otherwise



150
151
152
153
154
155
# File 'lib/ruber/world/hint_solver.rb', line 150

def choose_editor_current_strategy doc, editors, hints
  current = @view_order[0]
  if current and current.document == doc then current
  else nil
  end
end

- (EditorView?) choose_editor_current_tab_strategy(doc, editors, hints) (private)

Chooses an editor according to the current_tab strategy

Parameters:

  • doc (Document)

    the document associated with the editor

  • editors (Array<EditorView>)

    a list of the editors to choose among. They should be ordered by tab and, within the same tab, from left to right and top to bottom

Returns:

  • (EditorView, nil)

    the first editor in the current tab associated with doc or nil if the current tab doesn’t contain any editor associated with doc



164
165
166
167
168
169
170
# File 'lib/ruber/world/hint_solver.rb', line 164

def choose_editor_current_tab_strategy doc, editors, hints
  tab = @tabs.current_widget
  views = tab.find_children(EditorView).select do |c| 
    c.is_a?(EditorView) and c.document == doc
  end
  (views & editors).first
end

- (EditorView) choose_editor_first_strategy(doc, editors, hints) (private)

Chooses an editor according to the first strategy

Parameters:

  • doc (Document)

    the document associated with the editor

  • editors (Array<EditorView>)

    a list of the editors to choose among. They should be ordered by tab and, within the same tab, from left to right and top to bottom

Returns:

  • (EditorView)

    the first editor associated with doc starting from the first tab



231
232
233
# File 'lib/ruber/world/hint_solver.rb', line 231

def choose_editor_first_strategy doc, editors, hints
  editors.first
end

- (EditorView?) choose_editor_last_current_tab_strategy(doc, editors, hints) (private)

Chooses an editor according to the last_current_tab strategy

Parameters:

  • doc (Document)

    the document associated with the editor

  • editors (Array<EditorView>)

    a list of the editors to choose among. They should be ordered by tab and, within the same tab, from left to right and top to bottom

Returns:

  • (EditorView, nil)

    the last editor in the current tab associated with doc or nil if the current tab doesn’t contain any editor associated with doc



180
181
182
183
184
185
186
# File 'lib/ruber/world/hint_solver.rb', line 180

def choose_editor_last_current_tab_strategy doc, editors, hints
  tab = @tabs.current_widget
  views = tab.find_children(EditorView).select do |c| 
    c.is_a?(EditorView) and c.document == doc
  end
  (views & editors).last
end

- (EditorView) choose_editor_last_strategy(doc, editors, hints) (private)

Chooses an editor according to the last strategy

Parameters:

  • doc (Document)

    the document associated with the editor

  • editors (Array<EditorView>)

    a list of the editors to choose among. They should be ordered by tab and, within the same tab, from left to right and top to bottom

Returns:

  • (EditorView)

    the last editor associated with doc starting from the first tab



242
243
244
# File 'lib/ruber/world/hint_solver.rb', line 242

def choose_editor_last_strategy doc, editors, hints
  editors.last
end

- (EditorView) choose_editor_last_used_strategy(doc, editors, hints) (private)

Chooses an editor according to the last_used strategy

Parameters:

  • doc (Document)

    the document associated with the editor

  • editors (Array<EditorView>)

    a list of the editors to choose among. They should be ordered by tab and, within the same tab, from left to right and top to bottom

Returns:

  • (EditorView)

    the last activated editor associated with doc



252
253
254
255
256
257
# File 'lib/ruber/world/hint_solver.rb', line 252

def choose_editor_last_used_strategy doc, editors, hints
  # The || part is there in case there\'s a view in editors which doesn't
  # appears in the view order. In this case, it's given a fake index which
  # is greater than all the other possible
  editors.sort_by{|e| @view_order.index(e) || (@view_order.count + 1)}.first
end

- (EditorView) choose_editor_next_strategy(doc, editors, hints) (private)

Chooses an editor according to the next strategy

Parameters:

  • doc (Document)

    the document associated with the editor

  • editors (Array<EditorView>)

    a list of the editors to choose among. They should be ordered by tab and, within the same tab, from left to right and top to bottom

Returns:

  • (EditorView)

    the first editor associated with doc starting from the current tab



196
197
198
199
200
201
202
203
204
# File 'lib/ruber/world/hint_solver.rb', line 196

def choose_editor_next_strategy doc, editors, hints
  current_index = @tabs.current_index
  editor = editors.find do |e|
    pane = e.parent
    pane = pane.parent_pane while pane.parent_pane
    @tabs.index_of(pane) >= current_index
  end
  editor || editors.first
end

- (EditorView) choose_editor_previous_strategy(doc, editors, hints) (private)

Chooses an editor according to the previous strategy

Parameters:

  • doc (Document)

    the document associated with the editor

  • editors (Array<EditorView>)

    a list of the editors to choose among. They should be ordered by tab and, within the same tab, from left to right and top to bottom

Returns:

  • (EditorView)

    the first editor associated with doc starting from the current tab and going backwards



213
214
215
216
217
218
219
220
221
# File 'lib/ruber/world/hint_solver.rb', line 213

def choose_editor_previous_strategy doc, editors, hints
  current_index = @tabs.current_index
  editor = editors.reverse_each.find do |e|
    pane = e.parent
    pane = pane.parent_pane while pane.parent_pane
    @tabs.index_of(pane) < current_index
  end
  editor || editors.last
end

- (Array<EditorView>) editors_in_tab(doc, tab) (private)

A list of all the editors associated with the given document in a pane

Parameters:

  • doc (Document)

    the document

  • tab (Pane)

    the pane where to look for editors

Returns:

  • (Array<EditorView>)

    the editor views associated with doc in the pane pane, in order



139
140
141
# File 'lib/ruber/world/hint_solver.rb', line 139

def editors_in_tab doc, tab
  tab.select{|v| v.document == doc}
end

- (EditorView?) find_editor(doc, hints)

Finds the editor to use for a document according to the given hints

If no editor associated with the document and respecting the given hints exists, nil is returned. This always happens if the :existing hint is :never.

Parameters:

  • doc (Document)

    the document to retrieve the editor for

  • hints (see MainWindow#editor_for)

    . See Ruber::World::HintSolver#MainWindow#MainWindow#editor_for for the values it can contain. Only the :existing and :strategy entries are used

Returns:

  • (EditorView, nil)

    a view associated with the document which respects the hints or nil if such a view doesn’t exist



60
61
62
63
64
65
66
67
68
69
# File 'lib/ruber/world/hint_solver.rb', line 60

def find_editor doc, hints
  views = []
  case hints[:existing]
  when :never then return nil
  when :current_tab
    views = @tabs.current_widget.select{|v| v.document == doc}
  else @tabs.each{|t| views += t.select{|v| v.document == doc} }
  end
  choose_editor doc, views, hints
end

- (EditorView?) place_editor(hints)

Finds out where a new editor should respect the given hints

The return value tells where the new editor should be placed. If the return value is nil then the editor should be placed in a new tab; if it’s an EditorView then the editor should be placed in the pane containing the view, splitting it at the view values it can contain. Only the @:newand entry is used

Parameters:

  • hints (see MainWindow#editor_for)

    . See Ruber::World::HintSolver#MainWindow#MainWindow#editor_for for the

Returns:

  • (EditorView, nil)

    an EditorView if the new editor should be placed inside an existing pane. The returned view is the view where it’s parent should be split at. If nil is returned, the editor should be put in a new tab



84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/ruber/world/hint_solver.rb', line 84

def place_editor hints
  case hints[:new]
  when :new_tab then nil
  when :current then @view_order[0]
  when :current_tab
    current = @tabs.current_widget
    current.each_view.to_a[0] if current
  when Integer
    pane = @tabs.widget hints[:new]
    pane.each_view.to_a[0] if pane
  when EditorView then 
    view = hints[:new]
    view.parent.is_a?(Pane) ? view : nil
  end
end