Class: Redcar::Application

Inherits:
Object show all
Includes:
Model, Observable
Defined in:
plugins/application/lib/application.rb,
plugins/application/lib/application/dialog.rb,
plugins/application/lib/application/updates.rb,
plugins/application/lib/application/event_spewer.rb,
plugins/application/lib/application/global_state.rb,
plugins/application/lib/application/commands/tab_commands.rb,
plugins/application/lib/application/commands/window_commands.rb,
plugins/application/lib/application/commands/notebook_commands.rb,
plugins/application/lib/application/commands/treebook_commands.rb,
plugins/application/lib/application/commands/application_commands.rb

Overview

A Redcar process contains one Application instance. The application instance (the app) contains:

* an array of {Redcar::Window} objects and handles creating new Windows.
* a {Redcar::Clipboard}

  * a Command::History

A lot of events in Redcar bubble up through the app, which gives plugins one place to hook into Redcar events.

Defined Under Namespace

Classes: CloseAll, CloseNotebookCommand, CloseOthers, CloseTabCommand, CloseTreeCommand, CloseWindowCommand, DecreaseTreebookWidthCommand, Dialog, EnlargeNotebookCommand, EventSpewer, FocusWindowCommand, GlobalState, IncreaseTreebookWidthCommand, MoveTabDownCommand, MoveTabToOtherNotebookCommand, MoveTabUpCommand, OpenNewNotebookCommand, OpenNewWindowCommand, OpenTreeFinderCommand, OpenUpdateCommand, QuitCommand, ResetNotebookWidthsCommand, RotateNotebooksCommand, SwitchNotebookCommand, SwitchTabDownCommand, SwitchTabUpCommand, SwitchTreeDownCommand, SwitchTreeUpCommand, ToggleCheckForUpdatesCommand, ToggleFullscreen, ToggleToolbar, ToggleTreesCommand, TreebookWidthCommand, Updates

Constant Summary

NAME =
"Redcar"

Constants included from Observable

Observable::ASPECTS

Instance Attribute Summary (collapse)

Attributes included from Model

#controller

Class Method Summary (collapse)

Instance Method Summary (collapse)

Methods included from Observable

#add_listener, #notify_listeners, #remove_listener

Methods included from ReentryHelpers

#ignore, #ignore_changes

Constructor Details

- (Application) initialize

Create an application instance with a Redcar::Clipboard and a Redcar::History.



121
122
123
124
125
126
127
128
129
130
# File 'plugins/application/lib/application.rb', line 121

def initialize
  @windows = []
  @window_handlers = Hash.new {|h,k| h[k] = []}
  create_clipboard
  create_history
  @navigation_history = NavigationHistory.new
  @event_spewer = EventSpewer.new
  @task_queue   = TaskQueue.new
  @show_toolbar = !!Application.storage['show_toolbar']
end

Instance Attribute Details

- (Object) clipboard (readonly)

Returns the value of attribute clipboard



118
119
120
# File 'plugins/application/lib/application.rb', line 118

def clipboard
  @clipboard
end

- (Object) history (readonly)

Returns the value of attribute history



118
119
120
# File 'plugins/application/lib/application.rb', line 118

def history
  @history
end

- (Object) keymap (readonly)

Returns the value of attribute keymap



118
119
120
# File 'plugins/application/lib/application.rb', line 118

def keymap
  @keymap
end

Returns the value of attribute menu



118
119
120
# File 'plugins/application/lib/application.rb', line 118

def menu
  @menu
end

Returns the value of attribute navigation_history



118
119
120
# File 'plugins/application/lib/application.rb', line 118

def navigation_history
  @navigation_history
end

- (Object) show_toolbar

Returns the value of attribute show_toolbar



118
119
120
# File 'plugins/application/lib/application.rb', line 118

def show_toolbar
  @show_toolbar
end

- (Object) task_queue (readonly)

Returns the value of attribute task_queue



118
119
120
# File 'plugins/application/lib/application.rb', line 118

def task_queue
  @task_queue
end

- (Object) toolbar (readonly)

Returns the value of attribute toolbar



118
119
120
# File 'plugins/application/lib/application.rb', line 118

def toolbar
  @toolbar
end

Class Method Details

+ (Object) instance_id



132
133
134
# File 'plugins/application/lib/application.rb', line 132

def self.instance_id
  Application.storage["instance_id"]
end

+ (Object) sensitivities



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'plugins/application/lib/application.rb', line 70

def self.sensitivities
  [
    Sensitivity.new(:open_tab, Redcar.app, false, [:focussed_window, :tab_focussed]) do |tab|
      if win = Redcar.app.focussed_window
        win.focussed_notebook.focussed_tab
      end
    end,
    Sensitivity.new(:open_htmltab, Redcar.app, false, [:focussed_window, :tab_focussed]) do |tab|
      if win = Redcar.app.focussed_window and
        tab = win.focussed_notebook.focussed_tab
        tab.is_a?(HtmlTab)
      end
    end,
    Sensitivity.new(:open_trees, Redcar.app, false, [:focussed_window, :tree_added, :tree_removed]) do |tree|
      if win = Redcar.app.focussed_window
        trees = win.treebook.trees
        trees and trees.length > 0
      end
    end,
    Sensitivity.new(:focussed_committed_mirror, Redcar.app, false,
      [:focussed_window, :notebook_change, :mirror_committed, :tab_focussed]) do
      if win = Redcar.app.focussed_window and tab = win.focussed_notebook.focussed_tab
        begin;tab.edit_view.document.mirror.path;rescue;false;end
      end
    end,
    Sensitivity.new(:single_notebook, Redcar.app, true, [:focussed_window, :notebook_change]) do
      if win = Redcar.app.focussed_window
        win.notebooks.length == 1
      end
    end,
    Sensitivity.new(:multiple_notebooks, Redcar.app, false, [:focussed_window, :notebook_change]) do
      if win = Redcar.app.focussed_window
        win.notebooks.length > 1
      end
    end,
    Sensitivity.new(:other_notebook_has_tab, Redcar.app, false,
                    [:focussed_window, :focussed_notebook, :notebook_change, :tab_closed]) do
      if win = Redcar.app.focussed_window and notebook = win.nonfocussed_notebook
        notebook.tabs.any?
      end
    end,
    Sensitivity.new(:always_disabled, Redcar.app, false, []) { false },
    Sensitivity.new(:update_available, Redcar.app, false, [:update_available]) do
      Application::Updates.update_available?
    end
  ]
end

+ (Object) start_with_app



63
64
65
66
67
68
# File 'plugins/application/lib/application.rb', line 63

def self.start_with_app
  Redcar.app = Application.new
  Redcar.plugin_manager.objects_implementing(:app_started).each do |object|
    object.app_started
  end
end

+ (Object) storage



197
198
199
200
201
202
203
204
205
206
# File 'plugins/application/lib/application.rb', line 197

def self.storage
  @storage ||= begin
    storage = Plugin::Storage.new('application_plugin')
    storage.set_default('stay_resident_after_last_window_closed', false)
    storage.set_default('show_toolbar', Redcar.platform != :osx)
    storage.set_default('instance_id', java.util.UUID.randomUUID.to_s)
    storage.set_default('should_check_for_updates', true)
    storage
  end
end

Instance Method Details

- (Object) all_notebooks

All Redcar::Notebooks in all Windows.



209
210
211
# File 'plugins/application/lib/application.rb', line 209

def all_notebooks
  windows.inject([]) { |arr, window| arr << window.notebooks }.flatten
end

- (Object) all_tabs

All Redcar::Tabs in all Notebooks in all Windows.



214
215
216
# File 'plugins/application/lib/application.rb', line 214

def all_tabs
  all_notebooks.inject([]) { |arr, notebook| arr << notebook.tabs }.flatten
end

- (Object) apply_user_keybindings(keymap)



325
326
327
328
329
330
# File 'plugins/application/lib/application.rb', line 325

def apply_user_keybindings(keymap)
  Redcar.plugin_manager.objects_implementing(:user_keybindings).each do |object|
    keymap.map.merge!(object.user_keybindings)
  end
  keymap
end

- (Object) call_on_plugins(method_name, *args)

For every plugin that implements it, call the method with the given arguments and pass the result to the block.

Parameters:

  • method_name (Symbol)


265
266
267
268
269
270
271
# File 'plugins/application/lib/application.rb', line 265

def call_on_plugins(method_name, *args)
  Redcar.plugin_manager.objects_implementing(method_name).each do |object|
    result = object.send(method_name, *args)
    yield result if block_given?
  end
  nil
end

- (Object) events



136
137
138
# File 'plugins/application/lib/application.rb', line 136

def events
  @event_spewer
end

- (Object) focussed_notebook_tab

The focussed Redcar::Tab in the focussed notebook in the focussed window.



224
225
226
# File 'plugins/application/lib/application.rb', line 224

def focussed_notebook_tab
  focussed_window_notebook.focussed_tab if focussed_window_notebook
end

- (Object) focussed_window

The focussed Redcar::Window.



229
230
231
# File 'plugins/application/lib/application.rb', line 229

def focussed_window
  @focussed_window
end

- (Object) focussed_window=(window)

Set which window the app thinks is focussed. Should not be called by plugins, use Window#focus instead.



235
236
237
238
# File 'plugins/application/lib/application.rb', line 235

def focussed_window=(window)
  set_focussed_window(window)
  notify_listeners(:focussed_window, window)
end

- (Object) focussed_window_notebook

The focussed Redcar::Notebook in the focussed window, or nil.



219
220
221
# File 'plugins/application/lib/application.rb', line 219

def focussed_window_notebook
  focussed_window.focussed_notebook if focussed_window
end

- (Object) gained_application_focus

Called by the Gui to tell the Application that it has gained focus.



349
350
351
352
353
354
355
356
357
358
359
360
361
362
# File 'plugins/application/lib/application.rb', line 349

def gained_application_focus
  if @application_focus == false
    @application_focus = true
    notify_listeners(:focussed, self)
  end
  Thread.new do
    Application::Updates.check_for_new_version
    if Application::Updates.update_available?
      Redcar.update_gui do
        notify_listeners(:update_available, self)
      end
    end
  end
end

- (Boolean) has_focus?

Returns:

  • (Boolean)


364
365
366
# File 'plugins/application/lib/application.rb', line 364

def has_focus?
  @application_focus
end

- (Object) load_sensitivities

Loads sensitivities from all plugins.



333
334
335
336
337
# File 'plugins/application/lib/application.rb', line 333

def load_sensitivities
  Redcar.plugin_manager.objects_implementing(:sensitivities).each do |object|
    object.sensitivities
  end
end

- (Object) lost_application_focus

Called by the Gui to tell the Application that it has lost focus.



341
342
343
344
345
# File 'plugins/application/lib/application.rb', line 341

def lost_application_focus
  return if @protect_application_focus
  @application_focus = false
  notify_listeners(:lost_focus, self)
end

- (Redcar::Keymap) main_keymap

Generate the main keymap by merging the keymaps from all plugins.

Returns:



307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
# File 'plugins/application/lib/application.rb', line 307

def main_keymap
  @main_keymap ||= begin
    keymap = Keymap.new("main", Redcar.platform)
    Redcar.plugin_manager.objects_implementing(:keymaps).each do |object|
      maps = object.keymaps
      unless maps
        Redcar.log.warn("#{object.inspect} implements :keymaps but :keymaps returns nil")
        maps = []
      end
      keymaps = maps.select do |map|
        map.name == "main" and map.platforms.include?(Redcar.platform)
      end
      keymap = keymaps.inject(keymap) {|k, nk| k.merge(nk) }
    end
    apply_user_keybindings(keymap)
  end
end

Generate the main menu by combining menus from all plugins.

Returns:



276
277
278
279
280
281
282
283
284
285
286
287
288
289
# File 'plugins/application/lib/application.rb', line 276

def main_menu(window=nil)
  @main_menu ||= begin
    menu = Menu.new
    Redcar.plugin_manager.objects_implementing(:menus).each do |object|
      case object.method(:menus).arity
      when 1
        menu.merge(object.menus(window))
      else
        menu.merge(object.menus)
      end
    end
    menu
  end
end

- (Redcar::ToolBar) main_toolbar

Generate the toolbar combining toolbars from all plugins.

Returns:



294
295
296
297
298
299
300
301
302
# File 'plugins/application/lib/application.rb', line 294

def main_toolbar
  @main_toolbar ||= begin
    toolbar = ToolBar.new
    Redcar.plugin_manager.objects_implementing(:toolbars).each do |object|
      toolbar.merge(object.toolbars)
    end
    toolbar
  end
end

- (Object) make_sure_at_least_one_window_open



171
172
173
174
175
# File 'plugins/application/lib/application.rb', line 171

def make_sure_at_least_one_window_open
  if windows.length == 0
    new_window
  end
end

- (Object) make_sure_at_least_one_window_there



177
178
179
180
181
182
183
# File 'plugins/application/lib/application.rb', line 177

def make_sure_at_least_one_window_there
  if windows.length == 0
    win = new_window(false)
    set_focussed_window(win)
    win
  end
end

- (Object) new_window(show = true)

Create a new Application::Window, and the controller for it.



155
156
157
158
159
160
161
162
163
164
# File 'plugins/application/lib/application.rb', line 155

def new_window(show=true)
  new_window = Window.new
  windows << new_window
  notify_listeners(:new_window, new_window)
  attach_window_listeners(new_window)
  new_window.refresh_menu
  new_window.refresh_toolbar
  show_window(new_window) if show
  new_window
end

- (Object) protect_application_focus



368
369
370
371
372
373
# File 'plugins/application/lib/application.rb', line 368

def protect_application_focus
  @protect_application_focus = true
  r = yield
  @protect_application_focus = false
  r
end

- (Object) quit

Immediately stop the gui event loop. (You should probably be running QuitCommand instead.)



142
143
144
145
# File 'plugins/application/lib/application.rb', line 142

def quit
  @task_queue.stop
  Redcar.gui.stop
end

- (Object) refresh_menu!

Redraw the main menu, reloading all the Menus and Keymaps from the plugins.



247
248
249
250
251
252
# File 'plugins/application/lib/application.rb', line 247

def refresh_menu!
  @main_menu = nil
  @main_keymap = nil
  windows.each {|window| window.refresh_menu }
  notify_listeners(:refresh_menu)
end

- (Object) refresh_toolbar!

Redraw the main toolbar, reloading all the ToolBars and Keymaps from the plugins.



255
256
257
258
259
# File 'plugins/application/lib/application.rb', line 255

def refresh_toolbar!
  @main_toolbar = nil
  windows.each {|window| window.refresh_toolbar }
  controller.refresh_toolbar
end

- (Object) repeat_event(type)



375
376
377
# File 'plugins/application/lib/application.rb', line 375

def repeat_event(type)
  notify_listeners(type)
end

- (Object) set_focussed_window(window)

Set which window the app thinks is focussed. Should not be called by plugins, use Window#focus instead.



242
243
244
# File 'plugins/application/lib/application.rb', line 242

def set_focussed_window(window)
  @focussed_window = window
end

- (Boolean) show_toolbar?

Returns:

  • (Boolean)


431
432
433
# File 'plugins/application/lib/application.rb', line 431

def show_toolbar?
  @show_toolbar
end

- (Object) show_window(window)



166
167
168
169
# File 'plugins/application/lib/application.rb', line 166

def show_window(window)
  window.show
  set_focussed_window(window)
end

- (Object) toggle_show_toolbar



439
440
441
# File 'plugins/application/lib/application.rb', line 439

def toggle_show_toolbar
  Application.storage['show_toolbar'] = @show_toolbar = !Application.storage['show_toolbar']
end

- (Object) window_closed(window)

Removes a window from this Application. Should not be called by plugins, use Window#close instead.



187
188
189
190
191
192
193
194
195
# File 'plugins/application/lib/application.rb', line 187

def window_closed(window)
  windows.delete(window)
  if focussed_window == window
    self.focussed_window = windows.first
  end
  @window_handlers[window].each {|h| window.remove_listener(h) }

  @window_handlers.delete(window)
end

- (Array<Redcar::Window>) windows

All open windows

Returns:



150
151
152
# File 'plugins/application/lib/application.rb', line 150

def windows
  @windows
end