Class: Ruber::MainWindow
- Extended by:
- Forwardable
- Includes:
- GuiStatesHandler, PluginLike
- Defined in:
- lib/ruber/main_window/main_window.rb,
lib/ruber/main_window/main_window_actions.rb,
lib/ruber/main_window/main_window_internal.rb
Overview
The application’s main window. It is made of a menu bar, a tool bar, a workspace and a status bar. The workspace (see Workspace) is the main window’s central widget and where most of the user interaction happens. It contains the editors and the tool widgets.
Constant Summary collapse
- OPEN_DLG_FILTERS =
A list of strings to be used to create the filter for open file dialogs
[ '*.rb|Ruby source file (*.rb)', '*.yaml *.yml|YAML files (*.yaml, *.yml)', '*|All files' ]
Instance Attribute Summary collapse
-
#last_session_data ⇒ Object
readonly
A hash with the data stored in the session manager by plugins.
-
#workspace ⇒ Object
readonly
The widget which contains the tool widgets.
Attributes included from PluginLike
Instance Method Summary collapse
-
#activate_editor(arg) ⇒ Object
Activates an editor.
-
#active_editor ⇒ Object
Returns the active editor, or nil if there’s no active editor.
-
#close_editor(ed, ask = true) ⇒ Object
Closes the editor ed, deleting its tab and closing the corresponding document and activating the next tab if auto activating is on.
-
#current_document ⇒ Object
Returns the document associated with the active editor or nil if there’s no current editor.
-
#current_editor ⇒ Object
Returns the editor in the current tab, or nil if there’s no tab.
-
#display_doc(doc, line = nil, col = 0) ⇒ Object
(also: #display_document)
Similar to
editor_for!
but, after having retrieved/created the editor view, it activates and gives focus to it and moves the cursor to the line line and column col (both of them are 0-based indexes). -
#editor_for(doc) ⇒ Object
Similar to
editor_for!
but it doesn’t create the document or the editor if they don’t exist. -
#editor_for!(doc) ⇒ EditorView?
Returns the editor view for the given document, creating it if needed.
-
#execute_action(name, *args) ⇒ Object
Executes the action with name action contained in the main window’s action collection.
-
#focus_on_editor(ed = nil) ⇒ Object
Gives the focus to the current editor view.
-
#initialize(_manager, pdf) ⇒ MainWindow
constructor
Creates a new MainWindow.
-
#load_settings ⇒ Object
Loads the settings (in particular, the default script directory and the default project directory).
-
#projects_directory ⇒ Object
The directory where to create new projects by default.
-
#query_close ⇒ Object
Asks the user whether to save the modified documents and saves the chosen ones.
-
#safe_open_project(file, allow_reuse = false) ⇒ Object
Provides a standard interface to creating a project from a project file named file, automatically handling the possible exceptions.
-
#save_documents(docs = nil) ⇒ Object
This method is meant to be called in situation where the user may want to save a number of documents, for example when the application is quitting, as it avoids displaying a dialog box for each modified document.
-
#save_settings ⇒ Object
Saves recent files and projects, the position of the splitters and the size of the window.
-
#without_activating ⇒ Object
Executes the contents of the block with automatical editor activation disabled.
Methods included from GuiStatesHandler
#change_state, included, #register_action_handler, #remove_action_handler_for, #state
Methods included from PluginLike
#add_extensions_to_project, #add_options_to_project, #add_widgets_to_project, #plugin_name, #register_with_project, #remove_extensions_from_project, #remove_from_project, #remove_options_from_project, #remove_widgets_from_project, #restore_session, #session_data, #shutdown, #unload, #update_project
Constructor Details
#initialize(_manager, pdf) ⇒ MainWindow
Creates a new MainWindow. _manager is the component manager, while pdf is the plugin description for this object.
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 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
# File 'lib/ruber/main_window/main_window.rb', line 90 def initialize _manager, pdf super nil, 0 initialize_plugin pdf initialize_states_handler self. = Workspace.new self # We need the instance variable to use it with Forwardable @workspace = @views = .instance_variable_get :@views @current_view = nil @active_editor = nil @auto_activate_editors = true @editors_mapper = Qt::SignalMapper.new self @ui_states = {} @actions_state_handlers = Hash.new{|h, k| h[k] = []} @about_plugin_actions = [] @last_session_data = nil self. = StatusBar.new self self.connect(SIGNAL('current_document_changed(QObject*)')) do |doc| change_state 'current_document', !doc.nil_object? end connect Ruber[:components], SIGNAL('component_loaded(QObject*)'), self, SLOT('add_about_plugin_action(QObject*)') connect Ruber[:components], SIGNAL('unloading_component(QObject*)'), self, SLOT('remove_about_plugin_action(QObject*)') connect Ruber[:components], SIGNAL('unloading_component(QObject*)'), self, SLOT('remove_plugin_ui_actions(QObject*)') connect @editors_mapper, SIGNAL('mapped(QWidget*)'), self, SLOT('remove_view(QWidget*)') setup_actions action_collection @views.connect(SIGNAL('currentChanged(int)')) do |idx| if @auto_activate_editors then activate_editor idx else activate_editor nil end end Ruber[:projects].connect( SIGNAL('current_project_changed(QObject*)') ) do |prj| change_state "active_project_exists", !prj.nil? make_title end connect Ruber[:projects], SIGNAL('closing_project(QObject*)'), self, SLOT('close_project_files(QObject*)') setup_GUI create_shell_GUI true config_obj = Ruber[:config].kconfig apply_main_window_settings KDE::ConfigGroup.new( config_obj, 'MainWindow') recent_files = KDE::ConfigGroup.new config_obj, 'Recent files' action_collection.action("file_open_recent").load_entries recent_files recent_projects = KDE::ConfigGroup.new config_obj, 'Recent projects' action_collection.action("project-open_recent").load_entries recent_projects .show setup_initial_states end |
Instance Attribute Details
#last_session_data ⇒ Object (readonly)
A hash with the data stored in the session manager by plugins. The hash is only availlable after the restore
method has been called (which means that it will always be unavaillable if ruber wasn’t started by the session manager). If the hash isn’t availlable, nil is returned
NOTE: only for use by Application when restoring the session
84 85 86 |
# File 'lib/ruber/main_window/main_window.rb', line 84 def last_session_data @last_session_data end |
#workspace ⇒ Object (readonly)
The widget which contains the tool widgets.
The primary use of this method is to connect to the signals emitted from the workspace when a tool widget is raised, shown or hidden. All of its other methods are also provided by the MainWindow, so you shouldn’t need to access the workspace to use them.
74 75 76 |
# File 'lib/ruber/main_window/main_window.rb', line 74 def workspace @workspace end |
Instance Method Details
#activate_editor(arg) ⇒ Object
Activates an editor. arg can be either the index of a widget in the tab widget (for internal uses only) or the editor to activate, or nil. If the editor to activate is not in the current tab, the tab which contains it will become the current one. Activating an editor deactivates the previously active one.
Activating an editor means merging its GUI with the main window’s GUI, changing the title of the main window accordingly and telling the status bar to refer to that view. Also, the current_document_changed
and active_editor_changed
signals are emitted.
246 247 248 249 250 251 252 253 254 255 256 257 258 259 |
# File 'lib/ruber/main_window/main_window.rb', line 246 def activate_editor arg view = arg.is_a?(Integer) ? @views.( arg ) : arg @views. = view if view and @views. != view deactivate_editor @active_editor if @active_editor != view @active_editor = view if @active_editor gui_factory.add_client @active_editor.doc.view.send(:internal) @active_editor.document.activate end make_title .view = @active_editor emit current_document_changed @active_editor ? @active_editor.document : Qt::NilObject emit active_editor_changed @active_editor || Qt::NilObject end |
#active_editor ⇒ Object
Returns the active editor, or nil if there’s no active editor.
Note: strictly speaking, this is not the same as tab_widget.current_widget
. For an editor to be active, it’s not enough to be in the current tab, but it also need to having been its gui merged with the main window gui.
TODO: in all places this is called, change the name from current_view
to active_editor
.
223 224 225 |
# File 'lib/ruber/main_window/main_window.rb', line 223 def active_editor @active_editor end |
#close_editor(ed, ask = true) ⇒ Object
Closes the editor ed, deleting its tab and closing the corresponding document and activating the next tab if auto activating is on. If ask is true, the document will ask whether to save modifications, otherwise it won’t
324 325 326 |
# File 'lib/ruber/main_window/main_window.rb', line 324 def close_editor ed, ask = true ed.document.close_view ed, ask end |
#current_document ⇒ Object
Returns the document associated with the active editor or nil if there’s no
current editor.
It's almost the same as <tt>active_editor.doc</tt>, but already takes care of
the case when <tt>active_editor</tt> is *nil*.
268 269 270 271 |
# File 'lib/ruber/main_window/main_window.rb', line 268 def current_document view = @views. view ? view.doc : nil end |
#current_editor ⇒ Object
Returns the editor in the current tab, or nil if there’s no tab. Note that this may not be the active editor.
231 232 233 |
# File 'lib/ruber/main_window/main_window.rb', line 231 def current_editor @views. end |
#display_doc(doc, line = nil, col = 0) ⇒ Object Also known as: display_document
Similar to editor_for!
but, after having retrieved/created the editor view, it activates and gives focus to it and moves the cursor to the line line and column col (both of them are 0-based indexes).
278 279 280 281 282 283 284 |
# File 'lib/ruber/main_window/main_window.rb', line 278 def display_doc doc, line = nil, col = 0 ed = editor_for! doc return unless ed activate_editor ed ed.go_to line, col if line and col ed.set_focus end |
#editor_for(doc) ⇒ Object
Similar to editor_for!
but it doesn’t create the document or the editor if they don’t exist. If a Document for the string doc doesn’t exist, or if it doesn’t have an editor, returns nil.
207 208 209 210 211 |
# File 'lib/ruber/main_window/main_window.rb', line 207 def editor_for doc doc = Ruber[:documents][doc] if doc.is_a? String return unless doc doc.view end |
#editor_for!(doc) ⇒ EditorView?
Returns the editor view for the given document, creating it if needed
192 193 194 195 196 197 198 199 200 |
# File 'lib/ruber/main_window/main_window.rb', line 192 def editor_for! doc unless doc.is_a? Document if doc.is_a? KDE::Url or doc.start_with? '/' then doc = Ruber[:documents].document doc else doc = Ruber[:documents].document_with_name doc end end return unless doc create_editor_if_needed doc end |
#execute_action(name, *args) ⇒ Object
Executes the action with name action contained in the main window’s action collection.
See GuiPlugin#execute_action
for more details
504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 |
# File 'lib/ruber/main_window/main_window.rb', line 504 def execute_action name, *args data = plugin_description.actions[name.to_s] if data slot = data.slot.sub(/\(.*/, '') instance_eval(data.receiver).send slot, *args true elsif (action = action_collection.action(name)) if action.class == KDE::ToggleAction then KDE::ToggleAction action.instance_eval{emit toggled(*args)} elsif action.class == KDE::Action action.instance_eval{emit triggered()} else action.instance_eval{emit triggered(*args)} end true else false end end |
#focus_on_editor(ed = nil) ⇒ Object
Gives the focus to the current editor view. ed can be:
-
an EditorView
-
any argument acceptable by
editor_for!
-
nil
In the first two cases, the editor corresponding to ed is activated and given focus; in the last case the active editor is given focus.
477 478 479 480 481 482 483 |
# File 'lib/ruber/main_window/main_window.rb', line 477 def focus_on_editor ed = nil if ed ed = editor_for! ed unless ed.is_a? EditorView activate_editor ed if ed end @active_editor.set_focus if @active_editor end |
#load_settings ⇒ Object
Loads the settings (in particular, the default script directory and the default project directory)
463 464 465 466 467 |
# File 'lib/ruber/main_window/main_window.rb', line 463 def load_settings c = Ruber[:config][:general] @default_script_dir = KDE::Url.from_path c.default_script_directory @default_project_dir = KDE::Url.from_path c.default_project_directory end |
#projects_directory ⇒ Object
The directory where to create new projects by default
495 496 497 |
# File 'lib/ruber/main_window/main_window.rb', line 495 def projects_directory @default_project_dir end |
#query_close ⇒ Object
Asks the user whether to save the modified documents and saves the chosen ones. Returns true all the selected documents where saved and false if some of the document couldn’t be saved. MOVE: this should be moved to DocumentList, as there might be documents without a window
389 390 391 392 393 394 |
# File 'lib/ruber/main_window/main_window.rb', line 389 def query_close if Ruber[:app].session_saving @session_data = Ruber[:components].session_data end true end |
#safe_open_project(file, allow_reuse = false) ⇒ Object
Provides a standard interface to creating a project from a project file named file, automatically handling the possible exceptions. In particular, a message box will be displayed if the project file doesn’t exist or if it exists but it’s not a valid project file. A message box is also displayed if allow_reuse is false and the project list already contains a project corresponding to file. In all cases in which a message box is displayed nil is returned. Otherwise, the Project
object corresponding to file
is returned.
If a project was created from the project file, it will be made active and the old active project (if any) will be closed.
Note: file must be an absolute path.
410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 |
# File 'lib/ruber/main_window/main_window.rb', line 410 def safe_open_project file, allow_reuse = false prj = Ruber[:projects][file] if !allow_reuse and prj text = "A project corresponding to the file #{file} is already open. Please, close it before attempting to open it again" KDE::MessageBox.sorry self, KDE.i18n(text) return nil elsif prj then return prj end begin prj = Ruber[:projects].project file rescue Project::InvalidProjectFile => ex text = <<-EOS #{file} isn't a valid project file. The error reported was: #{ex.} EOS KDE::MessageBox.sorry self, KDE.i18n(text) return nil rescue LoadError KDE::MessageBox.sorry self, KDE.i18n(ex.) return nil end # The following two lines should be removed when we'll allow more than one project # open at the same time Ruber[:projects].current_project.close if Ruber[:projects].current_project Ruber[:projects].current_project = prj prj end |
#save_documents(docs = nil) ⇒ Object
This method is meant to be called in situation where the user may want to save
a number of documents, for example when the application is quitting, as it avoids
displaying a dialog box for each modified document.
_docs_ can be either an array containing the documents which can be saved (documents
in it which aren't modified will be ignored) or *nil*. In this case, all the
open documents (with or without an open editor) will be taken into account.
It displays a dialog where the user can choose, among the documents passed as
first argument, which ones he wants to save. The user has three choiches:
* save some (or all) the files, then proceed with the operation which has caused
the dialog to be shown (for example, quitting the application)
* don't save any file and go on with the operation
* abort the operation.
In the first case, this method attempts to perform save the selected files. If
any of them can't be saved, the dialog to choose the files to save will be
displayed again, with only those files which couldn't be saved (after informing
the user of the failure). The user can again chose which of those files this method
should attempt to save again, or whether to abort the operation or skip saving.
This will be repeated until all files have been saved or the user gives up
In the second and third cases, the method simply returns respectively +true+ or
*false*.
The value returned by this method is *false* if the user choose to abort the
operation and *true* otherwise. Calling methods should act appropriately (for
example, if this is called from a method which closes all documents and returns
*false*, the documents should't be closed. If it returns true, instead, they
should be closed, without asking again to save them).
<b>Note:</b> if _docs_ only contains non-modified documents, this method will
do nothing and immediately return *true*.
363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 |
# File 'lib/ruber/main_window/main_window.rb', line 363 def save_documents docs = nil docs ||= Ruber[:docs] to_save = docs.select{|d| d.modified?} until to_save.empty? dlg = SaveModifiedFilesDlg.new to_save, self case dlg.exec when KDE::Dialog::Yes to_save = Ruber[:docs].save_documents dlg.to_save unless to_save.empty? msg = "The following documents couldn't be saved: #{to_save.join "\n"}\nPlease, choose how to proceed" KDE::MessageBox.sorry nil, KDE.i18n(msg) end when KDE::Dialog::No then to_save.clear when Qt::Dialog::Rejected then return false end end true end |
#save_settings ⇒ Object
Saves recent files and projects, the position of the splitters and the size of the window.
TODO: since restoring window position seems to work correctly in Kate (even if there’s still an open bug, it seems to work, at least for me) see whether it’s still necessary to store the window size.
445 446 447 448 449 450 451 452 453 454 455 456 457 |
# File 'lib/ruber/main_window/main_window.rb', line 445 def save_settings @workspace.store_sizes # TODO use Ruber[:config] as soon as it works # config = Ruber[:config].kconfig config = KDE::Global.config recent_files = KDE::ConfigGroup.new config, 'Recent files' action_collection.action("file_open_recent").save_entries recent_files recent_projects = KDE::ConfigGroup.new config, 'Recent projects' action_collection.action("project-open_recent").save_entries recent_projects config.sync c = Ruber[:config][:main_window] c.window_size = rect.size end |
#without_activating ⇒ Object
Executes the contents of the block with automatical editor activation disabled. This should be used, for example, when more than one editor should be opened at once. Without this, every new editor would become (for a little time) the active one, with its gui merged with the main window and so on. This slows things down and should be avoided. To do so, you use this method:
Ruber[:main_window].without_activating do
ed = nil
files.each do |f|
ed = Ruber[:main_window].editor_for! f
end
Ruber[:main_window].activate_editor ed
end
After the block has been called, if there is no editor, or if the current widget in the tab widget is different from the active editor, the current widget will be activated. Note: automatical editor activation will be restored at the end of this method (even if exceptions occur).
306 307 308 309 310 311 312 313 314 315 316 317 |
# File 'lib/ruber/main_window/main_window.rb', line 306 def without_activating begin @auto_activate_editors = false yield ensure @auto_activate_editors = true if @views.current_index < 0 then activate_editor nil elsif @views. != @active_editor activate_editor @views. end end end |