Mercurial > octave-nkf
view libgui/src/main-window.cc @ 19895:19755f4fc851
maint: Cleanup C++ code to follow Octave coding conventions.
Try to wrap long lines to < 80 characters.
Use GNU style and don't indent first brace of function definition.
"case" statement is aligned flush left with brace of switch stmt.
Remove trailing '\' line continuation from the end of #define macros.
Use 2 spaces for indent.
* files-dock-widget.cc, history-dock-widget.cc, main-window.cc, octave-cmd.cc,
octave-dock-widget.cc, octave-gui.cc, resource-manager.cc, settings-dialog.cc,
shortcut-manager.cc, welcome-wizard.cc, workspace-view.cc, cellfun.cc, data.cc,
debug.cc, debug.h, dirfns.cc, error.h, file-io.cc, gl-render.cc, gl-render.h,
gl2ps-renderer.h, graphics.cc, graphics.in.h, help.cc, input.cc, load-path.cc,
load-path.h, lookup.cc, lu.cc, oct-stream.cc, octave-default-image.h,
ordschur.cc, pr-output.cc, qz.cc, strfns.cc, symtab.cc, symtab.h, sysdep.cc,
variables.cc, zfstream.h, __fltk_uigetfile__.cc, __init_fltk__.cc,
__magick_read__.cc, __osmesa_print__.cc, audiodevinfo.cc, ov-classdef.cc,
ov-classdef.h, ov-fcn.h, ov-float.cc, ov-flt-complex.cc, ov-java.cc,
ov-range.cc, ov-re-mat.cc, ov-usr-fcn.h, ov.cc, op-int.h, options-usage.h,
pt-eval.cc, Array-C.cc, Array-fC.cc, Array.cc, Array.h, PermMatrix.cc,
Sparse.cc, chMatrix.h, dSparse.cc, dim-vector.h, bsxfun-decl.h, bsxfun-defs.cc,
oct-norm.cc, Sparse-op-defs.h, oct-inttypes.cc, oct-inttypes.h, main.in.cc,
mkoctfile.in.cc: Cleanup C++ code to follow Octave coding conventions.
author | Rik <rik@octave.org> |
---|---|
date | Wed, 25 Feb 2015 11:55:49 -0800 |
parents | a59c5a16c9ab |
children | c7c50030e76c |
line wrap: on
line source
/* Copyright (C) 2013-2015 John W. Eaton Copyright (C) 2011-2015 Jacob Dawid This file is part of Octave. Octave is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. Octave is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Octave; see the file COPYING. If not, see <http://www.gnu.org/licenses/>. */ #ifdef HAVE_CONFIG_H #include <config.h> #endif #include <QKeySequence> #include <QApplication> #include <QLabel> #include <QMenuBar> #include <QMenu> #include <QAction> #include <QSettings> #include <QStyle> #include <QToolBar> #include <QDesktopServices> #include <QDesktopWidget> #include <QFileDialog> #include <QMessageBox> #include <QIcon> #include <QTextStream> #include <QThread> #include <QDateTime> #include <QDebug> #include <utility> #ifdef HAVE_QSCINTILLA #include "file-editor.h" #endif #include "main-window.h" #include "settings-dialog.h" #include "shortcut-manager.h" #include "__init_qt__.h" #include "Array.h" #include "cmd-edit.h" #include "url-transfer.h" #include "builtin-defun-decls.h" #include "defaults.h" #include "symtab.h" #include "version.h" #include "utils.h" static file_editor_interface * create_default_editor (QWidget *p) { #ifdef HAVE_QSCINTILLA return new file_editor (p); #else return 0; #endif } main_window::main_window (QWidget *p) : QMainWindow (p), _workspace_model (new workspace_model ()), status_bar (new QStatusBar ()), command_window (new terminal_dock_widget (this)), history_window (new history_dock_widget (this)), file_browser_window (new files_dock_widget (this)), doc_browser_window (new documentation_dock_widget (this)), editor_window (create_default_editor (this)), workspace_window (new workspace_view (this)), _settings_dlg (0), find_files_dlg (0), release_notes_window (0), community_news_window (0), _octave_qt_link (0), _clipboard (QApplication::clipboard ()), _cmd_queue (QList<octave_cmd *> ()), // no command pending _cmd_processing (1), _cmd_queue_mutex (), _dbg_queue (new QStringList ()), // no debug pending _dbg_processing (1), _dbg_queue_mutex (), _prevent_readline_conflicts (true) { QSettings *settings = resource_manager::get_settings (); bool connect_to_web = true; QDateTime last_checked; int serial = 0; _active_dock = 0; if (settings) { connect_to_web = settings->value ("news/allow_web_connection", true).toBool (); last_checked = settings->value ("news/last_time_checked", QDateTime ()).toDateTime (); serial = settings->value ("news/last_news_item", 0).toInt (); } QDateTime current = QDateTime::currentDateTime (); QDateTime one_day_ago = current.addDays (-1); if (connect_to_web && (! last_checked.isValid () || one_day_ago > last_checked)) load_and_display_community_news (serial); // We have to set up all our windows, before we finally launch octave. construct (); } main_window::~main_window (void) { // Destroy the terminal first so that STDERR stream is redirected back // to its original pipe to capture error messages at exit. delete editor_window; // first one for dialogs of modified editor-tabs delete command_window; delete workspace_window; delete doc_browser_window; delete file_browser_window; delete history_window; delete status_bar; delete _workspace_model; if (find_files_dlg) { delete find_files_dlg; find_files_dlg = 0; } if (release_notes_window) { delete release_notes_window; release_notes_window = 0; } if (_settings_dlg) { delete _settings_dlg; _settings_dlg = 0; } if (community_news_window) { delete community_news_window; community_news_window = 0; } delete _octave_qt_link; } // catch focus changes and determine the active dock widget void main_window::focus_changed (QWidget *, QWidget *new_widget) { octave_dock_widget* dock = 0; QWidget *w_new = new_widget; // get a copy of new focus widget QWidget *start = w_new; // Save it as start of our search int count = 0; // fallback to prevent endless loop while (w_new && w_new != _main_tool_bar && count < 100) { dock = qobject_cast <octave_dock_widget *> (w_new); if (dock) break; // it is a QDockWidget ==> exit loop #ifdef HAVE_QSCINTILLA if (qobject_cast <octave_qscintilla *> (w_new)) { dock = static_cast<octave_dock_widget *> (editor_window); break; // it is the editor window ==> exit loop } #endif w_new = qobject_cast <QWidget *> (w_new->previousInFocusChain ()); if (w_new == start) break; // we have arrived where we began ==> exit loop count++; } // editor needs extra handling octave_dock_widget *edit_dock_widget = static_cast<octave_dock_widget *> (editor_window); // if new dock has focus, emit signal and store active focus // except editor changes to a dialog (dock=0) if ((dock || _active_dock != edit_dock_widget) && (dock != _active_dock)) { // signal to all dock widgets for updating the style emit active_dock_changed (_active_dock, dock); if (edit_dock_widget == dock) emit editor_focus_changed (true); else if (edit_dock_widget == _active_dock) emit editor_focus_changed (false); _active_dock = dock; } } bool main_window::command_window_has_focus (void) const { return command_window->has_focus (); } void main_window::focus_command_window (void) { command_window->focus (); } void main_window::new_file (const QString& commands) { emit new_file_signal (commands); } void main_window::open_file (const QString& file_name) { emit open_file_signal (file_name); } void main_window::report_status_message (const QString& statusMessage) { status_bar->showMessage (statusMessage, 1000); } void main_window::handle_save_workspace_request (void) { QString file = QFileDialog::getSaveFileName (this, tr ("Save Workspace As"), ".", 0, 0, QFileDialog::DontUseNativeDialog); if (! file.isEmpty ()) octave_link::post_event (this, &main_window::save_workspace_callback, file.toStdString ()); } void main_window::handle_load_workspace_request (const QString& file_arg) { QString file = file_arg; if (file.isEmpty ()) file = QFileDialog::getOpenFileName (this, tr ("Load Workspace"), ".", 0, 0, QFileDialog::DontUseNativeDialog); if (! file.isEmpty ()) octave_link::post_event (this, &main_window::load_workspace_callback, file.toStdString ()); } void main_window::handle_clear_workspace_request (void) { octave_link::post_event (this, &main_window::clear_workspace_callback); } void main_window::handle_rename_variable_request (const QString& old_name, const QString& new_name) { name_pair names (old_name.toStdString (), new_name.toStdString ()); octave_link::post_event (this, &main_window::rename_variable_callback, names); } void main_window::handle_undo_request (void) { octave_link::post_event (this, &main_window::command_window_undo_callback); } void main_window::handle_clear_command_window_request (void) { octave_link::post_event (this, &main_window::clear_command_window_callback); } void main_window::handle_clear_history_request (void) { octave_link::post_event (this, &main_window::clear_history_callback); } bool main_window::focus_console_after_command () { QSettings *settings = resource_manager::get_settings (); return settings->value ("terminal/focus_after_command",false).toBool (); } void main_window::execute_command_in_terminal (const QString& command) { octave_cmd_exec *cmd = new octave_cmd_exec (command); queue_command (cmd); if (focus_console_after_command ()) focus_command_window (); } void main_window::run_file_in_terminal (const QFileInfo& info) { octave_link::post_event (this, &main_window::run_file_callback, info); if (focus_console_after_command ()) focus_command_window (); } void main_window::run_file_callback (const QFileInfo& info) { octave_cmd_eval *cmd = new octave_cmd_eval (info); queue_command (cmd); } void main_window::queue_command (octave_cmd* cmd) { _cmd_queue_mutex.lock (); _cmd_queue.append (cmd); // queue command and type _cmd_queue_mutex.unlock (); if (_cmd_processing.tryAcquire ()) // if callback not processing, post event octave_link::post_event (this, &main_window::execute_command_callback); } void main_window::handle_new_figure_request (void) { octave_link::post_event (this, &main_window::new_figure_callback); } void main_window::open_online_documentation_page (void) { QDesktopServices::openUrl (QUrl ("http://octave.org/doc/interpreter")); } void main_window::display_release_notes (void) { if (! release_notes_window) { std::string news_file = Voct_etc_dir + "/NEWS"; QString news; QFile *file = new QFile (QString::fromStdString (news_file)); if (file->open (QFile::ReadOnly)) { QTextStream *stream = new QTextStream (file); news = stream->readAll (); if (! news.isEmpty ()) { news.prepend ("<pre>"); news.append ("</pre>"); } else news = (tr ("The release notes file '%1' is empty.") . arg (QString::fromStdString (news_file))); } else news = (tr ("The release notes file '%1' cannot be read.") . arg (QString::fromStdString (news_file))); release_notes_window = new QWidget; QTextBrowser *browser = new QTextBrowser (release_notes_window); browser->setText (news); QVBoxLayout *vlayout = new QVBoxLayout; vlayout->addWidget (browser); release_notes_window->setLayout (vlayout); release_notes_window->setWindowTitle (tr ("Octave Release Notes")); browser->document()->adjustSize (); // center the window on the screen where octave is running QDesktopWidget *m_desktop = QApplication::desktop (); int screen = m_desktop->screenNumber (this); // screen of the main window QRect screen_geo = m_desktop->availableGeometry (screen); int win_x = screen_geo.width (); // width of the screen int win_y = screen_geo.height (); // height of the screen int reln_x = std::min (480, win_x-80); // desired width of release notes int reln_y = std::min (640, win_y-80); // desired height of release notes release_notes_window->resize (reln_x, reln_y); // set size release_notes_window->move (20, 0); // move to the top left corner } if (! release_notes_window->isVisible ()) release_notes_window->show (); else if (release_notes_window->isMinimized ()) release_notes_window->showNormal (); release_notes_window->setWindowIcon (QIcon (_release_notes_icon)); release_notes_window->raise (); release_notes_window->activateWindow (); } void news_reader::process (void) { QString html_text; if (connect_to_web) { // Run this part in a separate thread so Octave can continue to // run while we wait for the page to load. Then emit the signal // to display it when we have the page contents. QString url = base_url + "/" + page; std::ostringstream buf; url_transfer octave_dot_org (url.toStdString (), buf); if (octave_dot_org.is_valid ()) { Array<std::string> param; octave_dot_org.http_get (param); if (octave_dot_org.good ()) html_text = QString::fromStdString (buf.str ()); } if (html_text.contains ("this-is-the-gnu-octave-community-news-page")) { if (serial >= 0) { QSettings *settings = resource_manager::get_settings (); if (settings) { settings->setValue ("news/last_time_checked", QDateTime::currentDateTime ()); settings->sync (); } QString tag ("community-news-page-serial="); int b = html_text.indexOf (tag); if (b) { b += tag.length (); int e = html_text.indexOf ("\n", b); QString tmp = html_text.mid (b, e-b); int curr_page_serial = tmp.toInt (); if (curr_page_serial > serial) { if (settings) { settings->setValue ("news/last_news_item", curr_page_serial); settings->sync (); } } else return; } else return; } } else html_text = QString (tr ("<html>\n" "<body>\n" "<p>\n" "Octave's community news source seems to be unavailable.\n" "</p>\n" "<p>\n" "For the latest news, please check\n" "<a href=\"http://octave.org/community-news.html\">http://octave.org/community-news.html</a>\n" "when you have a connection to the web (link opens in an external browser).\n" "</p>\n" "<p>\n" "<small><em>— The Octave Developers, ") + OCTAVE_RELEASE_DATE + "</em></small>\n" "</p>\n" "</body>\n" "</html>\n"); } else html_text = QString (tr ("<html>\n" "<body>\n" "<p>\n" "Connecting to the web to display the latest Octave Community news has been disabled.\n" "</p>\n" "<p>\n" "For the latest news, please check\n" "<a href=\"http://octave.org/community-news.html\">http://octave.org/community-news.html</a>\n" "when you have a connection to the web (link opens in an external browser)\n" "or enable web connections for news in Octave's network settings dialog.\n" "</p>\n" "<p>\n" "<small><em>— The Octave Developers, ") + OCTAVE_RELEASE_DATE + "</em></small>\n" "</p>\n" "</body>\n" "</html>\n"); emit display_news_signal (html_text); emit finished (); } void main_window::load_and_display_community_news (int serial) { QSettings *settings = resource_manager::get_settings (); bool connect_to_web = (settings ? settings->value ("news/allow_web_connection", true).toBool () : true); QString base_url = "http://octave.org"; QString page = "community-news.html"; QThread *worker_thread = new QThread; news_reader *reader = new news_reader (base_url, page, serial, connect_to_web); reader->moveToThread (worker_thread); connect (reader, SIGNAL (display_news_signal (const QString&)), this, SLOT (display_community_news (const QString&))); connect (worker_thread, SIGNAL (started (void)), reader, SLOT (process ())); connect (reader, SIGNAL (finished (void)), worker_thread, SLOT (quit ())); connect (reader, SIGNAL (finished (void)), reader, SLOT (deleteLater ())); connect (worker_thread, SIGNAL (finished (void)), worker_thread, SLOT (deleteLater ())); worker_thread->start (); } void main_window::display_community_news (const QString& news) { if (! community_news_window) { community_news_window = new QWidget; QTextBrowser *browser = new QTextBrowser (community_news_window); browser->setHtml (news); browser->setObjectName ("OctaveNews"); browser->setOpenExternalLinks (true); QVBoxLayout *vlayout = new QVBoxLayout; vlayout->addWidget (browser); community_news_window->setLayout (vlayout); community_news_window->setWindowTitle (tr ("Octave Community News")); // center the window on the screen where octave is running QDesktopWidget *m_desktop = QApplication::desktop (); int screen = m_desktop->screenNumber (this); // screen of the main window QRect screen_geo = m_desktop->availableGeometry (screen); int win_x = screen_geo.width (); // width of the screen int win_y = screen_geo.height (); // height of the screen int news_x = std::min (640, win_x-80); // desired width of news window int news_y = std::min (480, win_y-80); // desired height of news window community_news_window->resize (news_x, news_y); // set size and center community_news_window->move ((win_x - community_news_window->width ())/2, (win_y - community_news_window->height ())/2); } if (! community_news_window->isVisible ()) community_news_window->show (); else if (community_news_window->isMinimized ()) community_news_window->showNormal (); // same icon as release notes community_news_window->setWindowIcon (QIcon (_release_notes_icon)); community_news_window->raise (); community_news_window->activateWindow (); } void main_window::open_bug_tracker_page (void) { QDesktopServices::openUrl (QUrl ("http://octave.org/bugs.html")); } void main_window::open_octave_packages_page (void) { QDesktopServices::openUrl (QUrl ("http://octave.org/packages.html")); } void main_window::open_agora_page (void) { QDesktopServices::openUrl (QUrl ("http://agora.octave.org")); } void main_window::open_contribute_page (void) { QDesktopServices::openUrl (QUrl ("http://octave.org/donate.html")); } void main_window::open_developer_page (void) { QDesktopServices::openUrl (QUrl ("http://octave.org/get-involved.html")); } void main_window::process_settings_dialog_request (const QString& desired_tab) { if (_settings_dlg) // _settings_dlg is a guarded pointer! { // here the dialog is still open and called once again if (! desired_tab.isEmpty ()) _settings_dlg->show_tab (desired_tab); return; } _settings_dlg = new settings_dialog (this, desired_tab); connect (_settings_dlg, SIGNAL (apply_new_settings ()), this, SLOT (request_reload_settings ())); _settings_dlg->setModal (false); _settings_dlg->setAttribute (Qt::WA_DeleteOnClose); _settings_dlg->show (); } void main_window::request_reload_settings () { QSettings *settings = resource_manager::get_settings (); if (settings) emit settings_changed (settings); } void main_window::notice_settings (const QSettings *settings) { // QSettings pointer is checked before emitting. // the widget's icons (when floating) QString icon_set = settings->value ("DockWidgets/widget_icon_set", "NONE").toString (); static struct { QString name; QString path; } widget_icon_data[] = { // array of possible icon sets (name, path (complete for NONE)) // the first entry here is the default! {"NONE", ":/actions/icons/logo.png"}, {"GRAPHIC", ":/actions/icons/graphic_logo_"}, {"LETTER", ":/actions/icons/letter_logo_"}, {"", ""} // end marker has empty name }; int count = 0; int icon_set_found = 0; // default while (!widget_icon_data[count].name.isEmpty ()) { // while not end of data if (widget_icon_data[count].name == icon_set) { // data of desired icon set found icon_set_found = count; break; } count++; } QString icon; foreach (octave_dock_widget *widget, dock_widget_list ()) { QString name = widget->objectName (); if (! name.isEmpty ()) { // if children has a name icon = widget_icon_data[icon_set_found].path; // prefix or octave-logo if (widget_icon_data[icon_set_found].name != "NONE") icon = icon + name + ".png"; // add widget name and ext. widget->setWindowIcon (QIcon (icon)); } } if (widget_icon_data[icon_set_found].name != "NONE") _release_notes_icon = widget_icon_data[icon_set_found].path + "ReleaseWidget.png"; else _release_notes_icon = ":/actions/icons/logo.png"; int icon_size_settings = settings->value ("toolbar_icon_size",0).toInt (); QStyle *st = style (); int icon_size = st->pixelMetric (QStyle::PM_ToolBarIconSize); if (icon_size_settings == 1) icon_size = st->pixelMetric (QStyle::PM_LargeIconSize); else if (icon_size_settings == -1) icon_size = st->pixelMetric (QStyle::PM_SmallIconSize); _main_tool_bar->setIconSize (QSize (icon_size,icon_size)); if (settings->value ("show_status_bar",true).toBool ()) status_bar->show (); else status_bar->hide (); _prevent_readline_conflicts = settings->value ("shortcuts/prevent_readline_conflicts", true).toBool (); configure_shortcuts (); set_global_shortcuts (command_window_has_focus ()); _suppress_dbg_location = ! settings->value ("terminal/print_debug_location", false).toBool (); resource_manager::update_network_settings (); } void main_window::confirm_shutdown_octave (void) { bool closenow = true; QSettings *settings = resource_manager::get_settings (); if (settings->value ("prompt_to_exit", false).toBool ()) { int ans = QMessageBox::question (this, tr ("Octave"), tr ("Are you sure you want to exit Octave?"), QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Ok); if (ans != QMessageBox::Ok) closenow = false; } #ifdef HAVE_QSCINTILLA if (closenow) closenow = editor_window->check_closing (); #endif _octave_qt_link->shutdown_confirmation (closenow); // Awake the worker thread so that it continues shutting down (or not). _octave_qt_link->waitcondition.wakeAll (); } void main_window::prepare_to_exit (void) { write_settings (); } void main_window::exit_app (int status) { qApp->exit (status); } void main_window::reset_windows (void) { QSettings *settings = resource_manager::get_default_settings (); set_window_layout (settings); showNormal (); // make sure main window is not minimized } void main_window::change_directory (const QString& dir) { // Remove existing entry, if any, then add new directory at top and // mark it as the current directory. Finally, update the file list // widget. int index = _current_directory_combo_box->findText (dir); if (index >= 0) _current_directory_combo_box->removeItem (index); _current_directory_combo_box->insertItem (0, dir); _current_directory_combo_box->setCurrentIndex (0); } void main_window::browse_for_directory (void) { QString dir = QFileDialog::getExistingDirectory (this, tr ("Browse directories"), 0, QFileDialog::ShowDirsOnly | QFileDialog::DontUseNativeDialog); set_current_working_directory (dir); // FIXME: on Windows systems, the command window freezes after the // previous actions. Forcing the focus appears to unstick it. focus_command_window (); } void main_window::set_current_working_directory (const QString& dir) { // Change to dir if it is an existing directory. QString xdir = dir.isEmpty () ? "." : dir; QFileInfo fileInfo (xdir); if (fileInfo.exists () && fileInfo.isDir ()) octave_link::post_event (this, &main_window::change_directory_callback, xdir.toStdString ()); } void main_window::change_directory_up (void) { set_current_working_directory (".."); } // Slot that is called if return is pressed in the line edit of the // combobox to change to a new directory or a directory that is already // in the drop down list. void main_window::accept_directory_line_edit (void) { // Get new directory name, and change to it if it is new. Otherwise, // the combo box will triggers the "activated" signal to change to the // directory. QString dir = _current_directory_combo_box->currentText (); int index = _current_directory_combo_box->findText (dir); if (index < 0) set_current_working_directory (dir); } void main_window::handle_enter_debugger (void) { setWindowTitle ("Octave (Debugging)"); _debug_continue->setEnabled (true); _debug_step_into->setEnabled (true); _debug_step_over->setEnabled (true); _debug_step_out->setEnabled (true); _debug_quit->setEnabled (true); #ifdef HAVE_QSCINTILLA editor_window->handle_enter_debug_mode (); #endif } void main_window::handle_exit_debugger (void) { setWindowTitle ("Octave"); _debug_continue->setEnabled (false); _debug_step_into->setEnabled (false); _debug_step_over->setEnabled (false); _debug_step_out->setEnabled (false); _debug_quit->setEnabled (false); #ifdef HAVE_QSCINTILLA editor_window->handle_exit_debug_mode (); #endif } void main_window::debug_continue (void) { queue_debug ("cont"); } void main_window::debug_step_into (void) { queue_debug ("in"); } void main_window::debug_step_over (void) { queue_debug ("step"); } void main_window::debug_step_out (void) { queue_debug ("out"); } void main_window::debug_quit (void) { queue_debug ("quit"); } void main_window::handle_insert_debugger_pointer_request (const QString& file, int line) { bool cmd_focus = command_window_has_focus (); emit insert_debugger_pointer_signal (file, line); if (cmd_focus) focus_command_window (); } void main_window::handle_delete_debugger_pointer_request (const QString& file, int line) { bool cmd_focus = command_window_has_focus (); emit delete_debugger_pointer_signal (file, line); if (cmd_focus) focus_command_window (); } void main_window::handle_update_breakpoint_marker_request (bool insert, const QString& file, int line) { bool cmd_focus = command_window_has_focus (); emit update_breakpoint_marker_signal (insert, file, line); if (cmd_focus) focus_command_window (); } void main_window::show_about_octave (void) { std::string message = octave_name_version_copyright_copying_warranty_and_bugs (true); QMessageBox::about (this, tr ("About Octave"), QString::fromStdString (message)); } void main_window::closeEvent (QCloseEvent *e) { e->ignore (); octave_cmd_exec *cmd = new octave_cmd_exec ("exit"); queue_command (cmd); } void main_window::read_settings (void) { QSettings *settings = resource_manager::get_settings (); if (!settings) { qDebug ("Error: QSettings pointer from resource manager is NULL."); return; } set_window_layout (settings); // restore the list of the last directories QStringList curr_dirs = settings->value ("MainWindow/current_directory_list").toStringList (); for (int i=0; i < curr_dirs.size (); i++) { _current_directory_combo_box->addItem (curr_dirs.at (i)); } emit settings_changed (settings); } void main_window::init_terminal_size (void) { emit init_terminal_size_signal (); } void main_window::set_window_layout (QSettings *settings) { #if ! defined (Q_OS_WIN32) restoreState (settings->value ("MainWindow/windowState").toByteArray ()); restoreGeometry (settings->value ("MainWindow/geometry").toByteArray ()); #endif // Restore the geometry of all dock-widgets foreach (octave_dock_widget *widget, dock_widget_list ()) { QString name = widget->objectName (); if (! name.isEmpty ()) { bool floating = settings->value ("DockWidgets/" + name + "Floating", false).toBool (); bool visible = settings->value ("DockWidgets/" + name + "Visible", true).toBool (); // If floating, make window from widget. if (floating) widget->make_window (); else if (! widget->parent ()) // should not be floating but is widget->make_widget (false); // no docking, just reparent #if ! defined (Q_OS_WIN32) // restore geometry QVariant val = settings->value ("DockWidgets/" + name); widget->restoreGeometry (val.toByteArray ()); #endif // make widget visible if desired if (floating && visible) // floating and visible { if (settings->value ("DockWidgets/" + widget->objectName () + "_minimized").toBool ()) widget->showMinimized (); else widget->setVisible (true); } else { widget->make_widget (); widget->setVisible (visible); // not floating -> show } } } #if defined (Q_OS_WIN32) restoreState (settings->value ("MainWindow/windowState").toByteArray ()); restoreGeometry (settings->value ("MainWindow/geometry").toByteArray ()); #endif show (); } void main_window::write_settings (void) { QSettings *settings = resource_manager::get_settings (); if (!settings) { qDebug ("Error: QSettings pointer from resource manager is NULL."); return; } settings->setValue ("MainWindow/geometry", saveGeometry ()); settings->setValue ("MainWindow/windowState", saveState ()); // write the list of recent used directories QStringList curr_dirs; for (int i=0; i<_current_directory_combo_box->count (); i++) { curr_dirs.append (_current_directory_combo_box->itemText (i)); } settings->setValue ("MainWindow/current_directory_list", curr_dirs); settings->sync (); } // Connecting the signals emitted when the visibility of a widget changes. // This has to be done after the window is shown (see octave-gui.cc) void main_window::connect_visibility_changed (void) { foreach (octave_dock_widget *widget, dock_widget_list ()) widget->connect_visibility_changed (); #ifdef HAVE_QSCINTILLA editor_window->enable_menu_shortcuts (false); #endif } void main_window::copyClipboard (void) { if (_current_directory_combo_box->hasFocus ()) { QLineEdit * edit = _current_directory_combo_box->lineEdit (); if (edit && edit->hasSelectedText ()) { QClipboard *clipboard = QApplication::clipboard (); clipboard->setText (edit->selectedText ()); } } else emit copyClipboard_signal (); } void main_window::pasteClipboard (void) { if (_current_directory_combo_box->hasFocus ()) { QLineEdit * edit = _current_directory_combo_box->lineEdit (); QClipboard *clipboard = QApplication::clipboard (); QString str = clipboard->text (); if (edit && str.length () > 0) { edit->insert (str); } } else emit pasteClipboard_signal (); } void main_window::selectAll (void) { if (_current_directory_combo_box->hasFocus ()) { QLineEdit * edit = _current_directory_combo_box->lineEdit (); if (edit) { edit->selectAll (); } } else emit selectAll_signal (); } // Connect the signals emitted when the Octave thread wants to create // a dialog box of some sort. Perhaps a better place for this would be // as part of the QUIWidgetCreator class. However, mainWindow currently // is not a global variable and not accessible for connecting. void main_window::connect_uiwidget_links () { connect (&uiwidget_creator, SIGNAL (create_dialog (const QString&, const QString&, const QString&, const QStringList&, const QString&, const QStringList&)), this, SLOT (handle_create_dialog (const QString&, const QString&, const QString&, const QStringList&, const QString&, const QStringList&))); // Register QIntList so that list of ints may be part of a signal. qRegisterMetaType<QIntList> ("QIntList"); connect (&uiwidget_creator, SIGNAL (create_listview (const QStringList&, const QString&, int, int, const QIntList&, const QString&, const QStringList&, const QString&, const QString&)), this, SLOT (handle_create_listview (const QStringList&, const QString&, int, int, const QIntList&, const QString&, const QStringList&, const QString&, const QString&))); // Register QFloatList so that list of floats may be part of a signal. qRegisterMetaType<QFloatList> ("QFloatList"); connect (&uiwidget_creator, SIGNAL (create_inputlayout (const QStringList&, const QString&, const QFloatList&, const QFloatList&, const QStringList&)), this, SLOT (handle_create_inputlayout (const QStringList&, const QString&, const QFloatList&, const QFloatList&, const QStringList&))); connect (&uiwidget_creator, SIGNAL (create_filedialog (const QStringList &,const QString&, const QString&, const QString&, const QString&)), this, SLOT (handle_create_filedialog (const QStringList &, const QString&, const QString&, const QString&, const QString&))); } // Create a message dialog with specified string, buttons and decorative // text. void main_window::handle_create_dialog (const QString& message, const QString& title, const QString& icon, const QStringList& button, const QString& defbutton, const QStringList& role) { MessageDialog *message_dialog = new MessageDialog (message, title, icon, button, defbutton, role); message_dialog->setAttribute (Qt::WA_DeleteOnClose); message_dialog->show (); } // Create a list dialog with specified list, initially selected, mode, // view size and decorative text. void main_window::handle_create_listview (const QStringList& list, const QString& mode, int wd, int ht, const QIntList& initial, const QString& name, const QStringList& prompt, const QString& ok_string, const QString& cancel_string) { ListDialog *list_dialog = new ListDialog (list, mode, wd, ht, initial, name, prompt, ok_string, cancel_string); list_dialog->setAttribute (Qt::WA_DeleteOnClose); list_dialog->show (); } // Create an input dialog with specified prompts and defaults, title and // row/column size specifications. void main_window::handle_create_inputlayout (const QStringList& prompt, const QString& title, const QFloatList& nr, const QFloatList& nc, const QStringList& defaults) { InputDialog *input_dialog = new InputDialog (prompt, title, nr, nc, defaults); input_dialog->setAttribute (Qt::WA_DeleteOnClose); input_dialog->show (); } void main_window::handle_create_filedialog (const QStringList& filters, const QString& title, const QString& filename, const QString& dirname, const QString& multimode) { FileDialog *file_dialog = new FileDialog (filters, title, filename, dirname, multimode); file_dialog->setAttribute (Qt::WA_DeleteOnClose); file_dialog->show (); } // Main subroutine of the constructor void main_window::construct (void) { _closing = false; // flag for editor files when closed setWindowIcon (QIcon (":/actions/icons/logo.png")); workspace_window->setModel (_workspace_model); connect (_workspace_model, SIGNAL (model_changed (void)), workspace_window, SLOT (handle_model_changed (void))); // Create and set the central widget. QMainWindow takes ownership of // the widget (pointer) so there is no need to delete the object upon // destroying this main_window. QWidget *dummyWidget = new QWidget (); dummyWidget->setObjectName ("CentralDummyWidget"); dummyWidget->resize (10, 10); dummyWidget->setSizePolicy (QSizePolicy::Minimum, QSizePolicy::Minimum); dummyWidget->hide (); setCentralWidget (dummyWidget); construct_menu_bar (); construct_tool_bar (); connect (qApp, SIGNAL (aboutToQuit ()), this, SLOT (prepare_to_exit ())); connect (qApp, SIGNAL (focusChanged (QWidget*, QWidget*)), this, SLOT(focus_changed (QWidget*, QWidget*))); connect (this, SIGNAL (settings_changed (const QSettings *)), this, SLOT (notice_settings (const QSettings *))); connect (this, SIGNAL (editor_focus_changed (bool)), this, SLOT (set_global_edit_shortcuts (bool))); connect (this, SIGNAL (editor_focus_changed (bool)), editor_window, SLOT (enable_menu_shortcuts (bool))); connect (file_browser_window, SIGNAL (load_file_signal (const QString&)), this, SLOT (handle_load_workspace_request (const QString&))); connect (file_browser_window, SIGNAL (find_files_signal (const QString&)), this, SLOT (find_files (const QString&))); connect_uiwidget_links (); setWindowTitle ("Octave"); setDockOptions (QMainWindow::AnimatedDocks | QMainWindow::AllowNestedDocks | QMainWindow::AllowTabbedDocks); addDockWidget (Qt::RightDockWidgetArea, command_window); addDockWidget (Qt::RightDockWidgetArea, doc_browser_window); tabifyDockWidget (command_window, doc_browser_window); #ifdef HAVE_QSCINTILLA addDockWidget (Qt::RightDockWidgetArea, editor_window); tabifyDockWidget (command_window, editor_window); #endif addDockWidget (Qt::LeftDockWidgetArea, file_browser_window); addDockWidget (Qt::LeftDockWidgetArea, workspace_window); addDockWidget (Qt::LeftDockWidgetArea, history_window); int win_x = QApplication::desktop ()->width (); int win_y = QApplication::desktop ()->height (); if (win_x > 960) win_x = 960; if (win_y > 720) win_y = 720; setGeometry (0, 0, win_x, win_y); setStatusBar (status_bar); construct_octave_qt_link (); #ifdef HAVE_QSCINTILLA connect (this, SIGNAL (insert_debugger_pointer_signal (const QString&, int)), editor_window, SLOT (handle_insert_debugger_pointer_request (const QString&, int))); connect (this, SIGNAL (delete_debugger_pointer_signal (const QString&, int)), editor_window, SLOT (handle_delete_debugger_pointer_request (const QString&, int))); connect (this, SIGNAL (update_breakpoint_marker_signal (bool, const QString&, int)), editor_window, SLOT (handle_update_breakpoint_marker_request (bool, const QString&, int))); #endif octave_link::post_event (this, &main_window::resize_command_window_callback); install___init_qt___functions (); Fregister_graphics_toolkit (ovl ("qt")); configure_shortcuts (); } void main_window::handle_octave_ready () { // actions after the startup files are executed QSettings *settings = resource_manager::get_settings (); QDir startup_dir = QDir (); // current octave dir after startup if (settings->value ("restore_octave_dir").toBool ()) { // restore last dir from previous session QStringList curr_dirs = settings->value ("MainWindow/current_directory_list").toStringList (); startup_dir = QDir (curr_dirs.at (0)); // last dir in previous session } else if (! settings->value ("octave_startup_dir").toString ().isEmpty ()) { // do not restore but there is a startup dir configured startup_dir = QDir (settings->value ("octave_startup_dir").toString ()); } if (! startup_dir.exists ()) { // the configured startup dir does not exist, take actual one startup_dir = QDir (); } set_current_working_directory (startup_dir.absolutePath ()); #ifdef HAVE_QSCINTILLA // Octave ready, determine whether to create an empty script. // This can not be done when the editor is created because all functions // must be known for the lexer's auto completion informations editor_window->empty_script (true, false); #endif focus_command_window (); // make sure that the command window has focus } void main_window::construct_octave_qt_link (void) { _octave_qt_link = new octave_qt_link (this); connect (_octave_qt_link, SIGNAL (confirm_shutdown_signal ()), this, SLOT (confirm_shutdown_octave ())); connect (_octave_qt_link, SIGNAL (exit_app_signal (int)), this, SLOT (exit_app (int))); connect (_octave_qt_link, SIGNAL (set_workspace_signal (bool, const QString&, const QStringList&, const QStringList&, const QStringList&, const QStringList&, const QIntList&)), _workspace_model, SLOT (set_workspace (bool, const QString&, const QStringList&, const QStringList&, const QStringList&, const QStringList&, const QIntList&))); connect (_octave_qt_link, SIGNAL (clear_workspace_signal ()), _workspace_model, SLOT (clear_workspace ())); connect (_octave_qt_link, SIGNAL (change_directory_signal (QString)), this, SLOT (change_directory (QString))); connect (_octave_qt_link, SIGNAL (change_directory_signal (QString)), file_browser_window, SLOT (update_octave_directory (QString))); connect (_octave_qt_link, SIGNAL (change_directory_signal (QString)), editor_window, SLOT (update_octave_directory (QString))); connect (_octave_qt_link, SIGNAL (execute_command_in_terminal_signal (QString)), this, SLOT (execute_command_in_terminal (QString))); connect (_octave_qt_link, SIGNAL (set_history_signal (const QStringList&)), history_window, SLOT (set_history (const QStringList&))); connect (_octave_qt_link, SIGNAL (append_history_signal (const QString&)), history_window, SLOT (append_history (const QString&))); connect (_octave_qt_link, SIGNAL (clear_history_signal (void)), history_window, SLOT (clear_history (void))); connect (_octave_qt_link, SIGNAL (enter_debugger_signal ()), this, SLOT (handle_enter_debugger ())); connect (_octave_qt_link, SIGNAL (exit_debugger_signal ()), this, SLOT (handle_exit_debugger ())); connect (_octave_qt_link, SIGNAL (show_preferences_signal (void)), this, SLOT (process_settings_dialog_request ())); #ifdef HAVE_QSCINTILLA connect (_octave_qt_link, SIGNAL (edit_file_signal (const QString&)), editor_window, SLOT (handle_edit_file_request (const QString&))); #endif connect (_octave_qt_link, SIGNAL (insert_debugger_pointer_signal (const QString&, int)), this, SLOT (handle_insert_debugger_pointer_request (const QString&, int))); connect (_octave_qt_link, SIGNAL (delete_debugger_pointer_signal (const QString&, int)), this, SLOT (handle_delete_debugger_pointer_request (const QString&, int))); connect (_octave_qt_link, SIGNAL (update_breakpoint_marker_signal (bool, const QString&, int)), this, SLOT (handle_update_breakpoint_marker_request (bool, const QString&, int))); connect (_octave_qt_link, SIGNAL (show_doc_signal (const QString &)), this, SLOT (handle_show_doc (const QString &))); connect (_workspace_model, SIGNAL (rename_variable (const QString&, const QString&)), this, SLOT (handle_rename_variable_request (const QString&, const QString&))); connect (command_window, SIGNAL (interrupt_signal (void)), _octave_qt_link, SLOT (terminal_interrupt (void))); _octave_qt_link->execute_interpreter (); octave_link::connect_link (_octave_qt_link); } void main_window::construct_menu_bar (void) { QMenuBar *menu_bar = menuBar (); construct_file_menu (menu_bar); construct_edit_menu (menu_bar); construct_debug_menu (menu_bar); construct_window_menu (menu_bar); construct_help_menu (menu_bar); construct_news_menu (menu_bar); } QAction* main_window::add_action (QMenu *menu, const QIcon &icon, const QString &text, const char *member, const QWidget *receiver) { QAction *a; if (receiver) a = menu->addAction (icon, text, receiver, member); else a = menu->addAction (icon, text, this, member); addAction (a); // important for shortcut context a->setShortcutContext (Qt::ApplicationShortcut); return a; } void main_window::enable_menu_shortcuts (bool enable) { QHash<QMenu*, QStringList>::const_iterator i = _hash_menu_text.constBegin(); while (i != _hash_menu_text.constEnd()) { i.key ()->setTitle (i.value ().at (! enable)); ++i; } } QMenu* main_window::m_add_menu (QMenuBar *p, QString name) { QMenu *menu = p->addMenu (name); QString base_name = name; // get a copy // replace intended '&' ("&&") by a temp. string base_name.replace ("&&","___octave_amp_replacement___"); // remove single '&' (shortcut) base_name.remove ("&"); // restore intended '&' base_name.replace ("___octave_amp_replacement___","&&"); // remember names with and without shortcut _hash_menu_text[menu] = QStringList () << name << base_name; return menu; } void main_window::construct_file_menu (QMenuBar *p) { QMenu *file_menu = m_add_menu (p, tr ("&File")); construct_new_menu (file_menu); _open_action = file_menu->addAction (QIcon (":/actions/icons/folder_documents.png"), tr ("Open...")); _open_action->setShortcutContext (Qt::ApplicationShortcut); _open_action->setToolTip (tr ("Open an existing file in editor")); #ifdef HAVE_QSCINTILLA editor_window->insert_new_open_actions (_new_script_action, _new_function_action, _open_action); file_menu->addMenu (editor_window->get_mru_menu ()); #endif file_menu->addSeparator (); _load_workspace_action = file_menu->addAction (tr ("Load Workspace...")); _save_workspace_action = file_menu->addAction (tr ("Save Workspace As...")); file_menu->addSeparator (); _preferences_action = file_menu->addAction (QIcon (":/actions/icons/configure.png"), tr ("Preferences...")); file_menu->addSeparator (); _exit_action = file_menu->addAction (tr ("Exit")); _exit_action->setShortcutContext (Qt::ApplicationShortcut); connect (_preferences_action, SIGNAL (triggered ()), this, SLOT (process_settings_dialog_request ())); #ifdef HAVE_QSCINTILLA connect (_open_action, SIGNAL (triggered ()), editor_window, SLOT (request_open_file ())); #endif connect (_load_workspace_action, SIGNAL (triggered ()), this, SLOT (handle_load_workspace_request ())); connect (_save_workspace_action, SIGNAL (triggered ()), this, SLOT (handle_save_workspace_request ())); connect (_exit_action, SIGNAL (triggered ()), this, SLOT (close ())); } void main_window::construct_new_menu (QMenu *p) { QMenu *new_menu = p->addMenu (tr ("New")); _new_script_action = new_menu->addAction (QIcon (":/actions/icons/filenew.png"), tr ("New Script")); _new_script_action->setShortcutContext (Qt::ApplicationShortcut); _new_function_action = new_menu->addAction (tr ("New Function...")); _new_function_action->setEnabled (true); _new_function_action->setShortcutContext (Qt::ApplicationShortcut); _new_figure_action = new_menu->addAction (tr ("New Figure")); _new_figure_action->setEnabled (true); #ifdef HAVE_QSCINTILLA connect (_new_script_action, SIGNAL (triggered ()), editor_window, SLOT (request_new_script ())); connect (_new_function_action, SIGNAL (triggered ()), editor_window, SLOT (request_new_function ())); #endif connect (_new_figure_action, SIGNAL (triggered ()), this, SLOT (handle_new_figure_request ())); } void main_window::construct_edit_menu (QMenuBar *p) { QMenu *edit_menu = m_add_menu (p, tr ("&Edit")); QKeySequence ctrl_shift = Qt::ControlModifier + Qt::ShiftModifier; _undo_action = edit_menu->addAction (QIcon (":/actions/icons/undo.png"), tr ("Undo")); edit_menu->addSeparator (); _copy_action = edit_menu->addAction (QIcon (":/actions/icons/editcopy.png"), tr ("Copy"), this, SLOT (copyClipboard ())); _paste_action = edit_menu->addAction (QIcon (":/actions/icons/editpaste.png"), tr ("Paste"), this, SLOT (pasteClipboard ())); _select_all_action = edit_menu->addAction (tr ("Select All"), this, SLOT (selectAll ())); _clear_clipboard_action = edit_menu->addAction (tr ("Clear Clipboard"), this, SLOT (clear_clipboard ())); edit_menu->addSeparator (); _find_files_action = edit_menu->addAction (tr ("Find Files...")); edit_menu->addSeparator (); _clear_command_window_action = edit_menu->addAction (tr ("Clear Command Window")); _clear_command_history_action = edit_menu->addAction (tr ("Clear Command History")); _clear_workspace_action = edit_menu->addAction (tr ("Clear Workspace")); connect (_find_files_action, SIGNAL (triggered ()), this, SLOT (find_files ())); connect (_clear_command_window_action, SIGNAL (triggered ()), this, SLOT (handle_clear_command_window_request ())); connect (_clear_command_history_action, SIGNAL (triggered ()), this, SLOT (handle_clear_history_request ())); connect (_clear_workspace_action, SIGNAL (triggered ()), this, SLOT (handle_clear_workspace_request ())); connect (_clipboard, SIGNAL (changed (QClipboard::Mode)), this, SLOT (clipboard_has_changed (QClipboard::Mode))); clipboard_has_changed (QClipboard::Clipboard); } QAction * main_window::construct_debug_menu_item (const char *icon, const QString& item, const char *member) { QAction *action = add_action (_debug_menu, QIcon (icon), item, member); action->setEnabled (false); #ifdef HAVE_QSCINTILLA editor_window->debug_menu ()->addAction (action); editor_window->toolbar ()->addAction (action); #endif return action; } void main_window::construct_debug_menu (QMenuBar *p) { _debug_menu = m_add_menu (p, tr ("De&bug")); _debug_step_over = construct_debug_menu_item (":/actions/icons/db_step.png", tr ("Step"), SLOT (debug_step_over ())); _debug_step_into = construct_debug_menu_item (":/actions/icons/db_step_in.png", tr ("Step In"), SLOT (debug_step_into ())); _debug_step_out = construct_debug_menu_item (":/actions/icons/db_step_out.png", tr ("Step Out"), SLOT (debug_step_out ())); _debug_continue = construct_debug_menu_item (":/actions/icons/db_cont.png", tr ("Continue"), SLOT (debug_continue ())); _debug_menu->addSeparator (); #ifdef HAVE_QSCINTILLA editor_window->debug_menu ()->addSeparator (); #endif _debug_quit = construct_debug_menu_item (":/actions/icons/db_stop.png", tr ("Quit Debug Mode"), SLOT (debug_quit ())); } QAction * main_window::construct_window_menu_item (QMenu *p, const QString& item, bool checkable, QWidget *widget) { QAction *action = p->addAction (QIcon (), item); addAction (action); // important for shortcut context action->setCheckable (checkable); action->setShortcutContext (Qt::ApplicationShortcut); if (widget) // might be zero for editor_window { if (checkable) { // action for visibilty of dock widget connect (action, SIGNAL (toggled (bool)), widget, SLOT (setVisible (bool))); connect (widget, SIGNAL (active_changed (bool)), action, SLOT (setChecked (bool))); } else { // action for focus of dock widget connect (action, SIGNAL (triggered ()), widget, SLOT (focus ())); } } return action; } void main_window::construct_window_menu (QMenuBar *p) { QMenu *window_menu = m_add_menu (p, tr ("&Window")); _show_command_window_action = construct_window_menu_item (window_menu, tr ("Show Command Window"), true, command_window); _show_history_action = construct_window_menu_item (window_menu, tr ("Show Command History"), true, history_window); _show_file_browser_action = construct_window_menu_item (window_menu, tr ("Show File Browser"), true, file_browser_window); _show_workspace_action = construct_window_menu_item (window_menu, tr ("Show Workspace"), true, workspace_window); _show_editor_action = construct_window_menu_item (window_menu, tr ("Show Editor"), true, editor_window); _show_documentation_action = construct_window_menu_item (window_menu, tr ("Show Documentation"), true, doc_browser_window); window_menu->addSeparator (); _command_window_action = construct_window_menu_item (window_menu, tr ("Command Window"), false, command_window); _history_action = construct_window_menu_item (window_menu, tr ("Command History"), false, history_window); _file_browser_action = construct_window_menu_item (window_menu, tr ("File Browser"), false, file_browser_window); _workspace_action = construct_window_menu_item (window_menu, tr ("Workspace"), false, workspace_window); _editor_action = construct_window_menu_item (window_menu, tr ("Editor"), false, editor_window); _documentation_action = construct_window_menu_item (window_menu, tr ("Documentation"), false, doc_browser_window); window_menu->addSeparator (); _reset_windows_action = add_action (window_menu, QIcon (), tr ("Reset Default Window Layout"), SLOT (reset_windows ())); } void main_window::construct_help_menu (QMenuBar *p) { QMenu *help_menu = m_add_menu (p, tr ("&Help")); construct_documentation_menu (help_menu); help_menu->addSeparator (); _report_bug_action = add_action (help_menu, QIcon (), tr ("Report Bug"), SLOT (open_bug_tracker_page ())); _octave_packages_action = add_action (help_menu, QIcon (), tr ("Octave Packages"), SLOT (open_octave_packages_page ())); _agora_action = add_action (help_menu, QIcon (), tr ("Share Code"), SLOT (open_agora_page ())); _contribute_action = add_action (help_menu, QIcon (), tr ("Contribute to Octave"), SLOT (open_contribute_page ())); _developer_action = add_action (help_menu, QIcon (), tr ("Octave Developer Resources"), SLOT (open_developer_page ())); help_menu->addSeparator (); _about_octave_action = add_action (help_menu, QIcon (), tr ("About Octave"), SLOT (show_about_octave ())); } void main_window::construct_documentation_menu (QMenu *p) { QMenu *doc_menu = p->addMenu (tr ("Documentation")); _ondisk_doc_action = add_action (doc_menu, QIcon (), tr ("On Disk"), SLOT (focus ()), doc_browser_window); _online_doc_action = add_action (doc_menu, QIcon (), tr ("Online"), SLOT (open_online_documentation_page ())); } void main_window::construct_news_menu (QMenuBar *p) { QMenu *news_menu = m_add_menu (p, tr ("&News")); _release_notes_action = add_action (news_menu, QIcon (), tr ("Release Notes"), SLOT (display_release_notes ())); _current_news_action = add_action (news_menu, QIcon (), tr ("Community News"), SLOT (load_and_display_community_news ())); } void main_window::construct_tool_bar (void) { _main_tool_bar = addToolBar ("Main"); _main_tool_bar->setObjectName ("MainToolBar"); _main_tool_bar->addAction (_new_script_action); _main_tool_bar->addAction (_open_action); _main_tool_bar->addSeparator (); _main_tool_bar->addAction (_copy_action); _main_tool_bar->addAction (_paste_action); _main_tool_bar->addAction (_undo_action); _main_tool_bar->addSeparator (); _current_directory_combo_box = new QComboBox (this); QFontMetrics fm = _current_directory_combo_box->fontMetrics (); _current_directory_combo_box->setFixedWidth (48*fm.averageCharWidth ()); _current_directory_combo_box->setEditable (true); _current_directory_combo_box->setInsertPolicy (QComboBox::NoInsert); _current_directory_combo_box->setToolTip (tr ("Enter directory name")); _current_directory_combo_box->setMaxVisibleItems ( current_directory_max_visible); _current_directory_combo_box->setMaxCount (current_directory_max_count); QSizePolicy sizePol (QSizePolicy::Preferred, QSizePolicy::Preferred); _current_directory_combo_box->setSizePolicy (sizePol); // addWidget takes ownership of the objects so there is no // need to delete these upon destroying this main_window. _main_tool_bar->addWidget (new QLabel (tr ("Current Directory: "))); _main_tool_bar->addWidget (_current_directory_combo_box); QAction *current_dir_up = _main_tool_bar->addAction ( QIcon (":/actions/icons/up.png"), tr ("One directory up")); QAction *current_dir_search = _main_tool_bar->addAction ( QIcon (":/actions/icons/folder.png"), tr ("Browse directories")); connect (_current_directory_combo_box, SIGNAL (activated (QString)), this, SLOT (set_current_working_directory (QString))); connect (_current_directory_combo_box->lineEdit (), SIGNAL (returnPressed ()), this, SLOT (accept_directory_line_edit ())); connect (current_dir_search, SIGNAL (triggered ()), this, SLOT (browse_for_directory ())); connect (current_dir_up, SIGNAL (triggered ()), this, SLOT (change_directory_up ())); connect (_undo_action, SIGNAL (triggered ()), this, SLOT (handle_undo_request ())); } void main_window::save_workspace_callback (const std::string& file) { Fsave (ovl (file)); } void main_window::load_workspace_callback (const std::string& file) { Fload (ovl (file)); octave_link::set_workspace (true, symbol_table::workspace_info ()); } void main_window::clear_workspace_callback (void) { Fclear (); } void main_window::rename_variable_callback (const main_window::name_pair& names) { /* bool status = */ symbol_table::rename (names.first, names.second); // if (status) octave_link::set_workspace (true, symbol_table::workspace_info ()); // else // ; // we need an octave_link action that runs a GUI error option. } void main_window::command_window_undo_callback (void) { command_editor::undo (); command_editor::redisplay (); } void main_window::clear_command_window_callback (void) { command_editor::kill_full_line (); command_editor::clear_screen (); } void main_window::resize_command_window_callback (void) { command_editor::resize_terminal (); } void main_window::set_screen_size_callback (const int_pair& sz) { command_editor::set_screen_size (sz.first, sz.second); } void main_window::clear_history_callback (void) { Fhistory (ovl ("-c")); } void main_window::execute_command_callback () { bool repost = false; // flag for reposting event for this callback if (! _cmd_queue.isEmpty ()) // list can not be empty here, just to make sure { _cmd_queue_mutex.lock (); // critical path octave_cmd *cmd = _cmd_queue.takeFirst (); if (_cmd_queue.isEmpty ()) _cmd_processing.release (); // cmd queue empty, processing will stop else repost = true; // not empty, repost at end _cmd_queue_mutex.unlock (); cmd->execute (); delete cmd; } if (repost) // queue not empty, so repost event for further processing octave_link::post_event (this, &main_window::execute_command_callback); } void main_window::new_figure_callback (void) { Fbuiltin (ovl ("figure")); Fdrawnow (); } void main_window::change_directory_callback (const std::string& directory) { Fcd (ovl (directory)); } // The next callbacks are invoked by GUI buttons. Those buttons // should only be active when we are doing debugging, which means that // Octave is waiting for input in get_debug_input. Calling // command_editor::interrupt will force readline to return even if it // has not read any input, and then get_debug_input will return, // allowing the evaluator to continue and execute the next statement. void main_window::queue_debug (QString debug_cmd) { _dbg_queue_mutex.lock (); _dbg_queue->append (debug_cmd); // queue command _dbg_queue_mutex.unlock (); if (_dbg_processing.tryAcquire ()) // if callback not processing, post event octave_link::post_event (this, &main_window::execute_debug_callback); } void main_window::execute_debug_callback () { bool repost = false; // flag for reposting event for this callback if (!_dbg_queue->isEmpty ()) // list can not be empty here, just to make sure { _dbg_queue_mutex.lock (); // critical path QString debug = _dbg_queue->takeFirst (); if (_dbg_queue->isEmpty ()) _dbg_processing.release (); // cmd queue empty, processing will stop else repost = true; // not empty, repost at end _dbg_queue_mutex.unlock (); if (debug == "step") { F__db_next_breakpoint_quiet__ (ovl (_suppress_dbg_location)); Fdbstep (); } else if (debug == "cont") { F__db_next_breakpoint_quiet__ (ovl (_suppress_dbg_location)); Fdbcont (); } else if (debug == "quit") Fdbquit (); else { F__db_next_breakpoint_quiet__ (ovl (_suppress_dbg_location)); Fdbstep (ovl (debug.toStdString ())); } command_editor::interrupt (true); } if (repost) // queue not empty, so repost event for further processing octave_link::post_event (this, &main_window::execute_debug_callback); } void main_window::find_files (const QString &start_dir) { if (! find_files_dlg) { find_files_dlg = new find_files_dialog (this); connect (find_files_dlg, SIGNAL (finished (int)), this, SLOT (find_files_finished (int))); connect (find_files_dlg, SIGNAL (dir_selected (const QString &)), file_browser_window, SLOT (set_current_directory (const QString&))); connect (find_files_dlg, SIGNAL (file_selected (const QString &)), this, SLOT (open_file (const QString &))); find_files_dlg->setWindowModality (Qt::NonModal); } if (! find_files_dlg->isVisible ()) { find_files_dlg->show (); } find_files_dlg->set_search_dir (start_dir); find_files_dlg->activateWindow (); } void main_window::find_files_finished (int) { } void main_window::set_global_edit_shortcuts (bool editor_has_focus) { // this slot is called when editor gets/loses focus if (editor_has_focus) { // disable shortcuts that are also provided by the editor itself QKeySequence no_key = QKeySequence (); _copy_action->setShortcut (no_key); _paste_action->setShortcut (no_key); _undo_action->setShortcut (no_key); _select_all_action->setShortcut (no_key); } else { // editor loses focus, set the global shortcuts shortcut_manager::set_shortcut (_copy_action, "main_edit:copy"); shortcut_manager::set_shortcut (_paste_action, "main_edit:paste"); shortcut_manager::set_shortcut (_undo_action, "main_edit:undo"); shortcut_manager::set_shortcut (_select_all_action, "main_edit:select_all"); } // dis-/enable global menu depending on editor's focus enable_menu_shortcuts (! editor_has_focus); } void main_window::configure_shortcuts () { // file menu shortcut_manager::set_shortcut (_open_action, "main_file:open_file"); shortcut_manager::set_shortcut (_new_script_action, "main_file:new_file"); shortcut_manager::set_shortcut (_new_function_action, "main_file:new_function"); shortcut_manager::set_shortcut (_new_function_action, "main_file:new_figure"); shortcut_manager::set_shortcut (_load_workspace_action, "main_file:load_workspace"); shortcut_manager::set_shortcut (_save_workspace_action, "main_file:save_workspace"); shortcut_manager::set_shortcut (_preferences_action, "main_file:preferences"); shortcut_manager::set_shortcut (_exit_action,"main_file:exit"); // edit menu shortcut_manager::set_shortcut (_copy_action, "main_edit:copy"); shortcut_manager::set_shortcut (_paste_action, "main_edit:paste"); shortcut_manager::set_shortcut (_undo_action, "main_edit:undo"); shortcut_manager::set_shortcut (_select_all_action, "main_edit:select_all"); shortcut_manager::set_shortcut (_clear_clipboard_action, "main_edit:clear_clipboard"); shortcut_manager::set_shortcut (_find_files_action, "main_edit:find_in_files"); shortcut_manager::set_shortcut (_clear_command_history_action, "main_edit:clear_history"); shortcut_manager::set_shortcut (_clear_command_window_action, "main_edit:clear_command_window"); shortcut_manager::set_shortcut (_clear_workspace_action, "main_edit:clear_workspace"); // debug menu shortcut_manager::set_shortcut (_debug_step_over, "main_debug:step_over"); shortcut_manager::set_shortcut (_debug_step_into, "main_debug:step_into"); shortcut_manager::set_shortcut (_debug_step_out, "main_debug:step_out"); shortcut_manager::set_shortcut (_debug_continue, "main_debug:continue"); shortcut_manager::set_shortcut (_debug_quit, "main_debug:quit"); // window menu shortcut_manager::set_shortcut (_show_command_window_action, "main_window:show_command"); shortcut_manager::set_shortcut (_show_history_action, "main_window:show_history"); shortcut_manager::set_shortcut (_show_workspace_action, "main_window:show_workspace"); shortcut_manager::set_shortcut (_show_file_browser_action, "main_window:show_file_browser"); shortcut_manager::set_shortcut (_show_editor_action, "main_window:show_editor"); shortcut_manager::set_shortcut (_show_documentation_action, "main_window:show_doc"); shortcut_manager::set_shortcut (_command_window_action, "main_window:command"); shortcut_manager::set_shortcut (_history_action, "main_window:history"); shortcut_manager::set_shortcut (_workspace_action, "main_window:workspace"); shortcut_manager::set_shortcut (_file_browser_action, "main_window:file_browser"); shortcut_manager::set_shortcut (_editor_action, "main_window:editor"); shortcut_manager::set_shortcut (_documentation_action, "main_window:doc"); shortcut_manager::set_shortcut (_reset_windows_action, "main_window:reset"); // help menu shortcut_manager::set_shortcut (_ondisk_doc_action, "main_help:ondisk_doc"); shortcut_manager::set_shortcut (_online_doc_action, "main_help:online_doc"); shortcut_manager::set_shortcut (_report_bug_action, "main_help:report_bug"); shortcut_manager::set_shortcut (_octave_packages_action, "main_help:packages"); shortcut_manager::set_shortcut (_agora_action, "main_help:agora"); shortcut_manager::set_shortcut (_contribute_action, "main_help:contribute"); shortcut_manager::set_shortcut (_developer_action, "main_help:developer"); shortcut_manager::set_shortcut (_about_octave_action, "main_help:about"); // news menu shortcut_manager::set_shortcut (_release_notes_action, "main_news:release_notes"); shortcut_manager::set_shortcut (_current_news_action, "main_news:community_news"); } void main_window::set_global_shortcuts (bool set_shortcuts) { // this slot is called when the terminal gets/loses focus // return if the user don't want to use readline shortcuts if (! _prevent_readline_conflicts) return; if (set_shortcuts) { // terminal loses focus: set the global shortcuts configure_shortcuts (); } else { // terminal gets focus: disable some shortcuts QKeySequence no_key = QKeySequence (); // file menu _open_action->setShortcut (no_key); _new_script_action->setShortcut (no_key); _new_function_action->setShortcut (no_key); _new_function_action->setShortcut (no_key); _load_workspace_action->setShortcut (no_key); _save_workspace_action->setShortcut (no_key); _preferences_action->setShortcut (no_key); _exit_action->setShortcut (no_key); // edit menu _select_all_action->setShortcut (no_key); _clear_clipboard_action->setShortcut (no_key); _find_files_action->setShortcut (no_key); _clear_command_history_action->setShortcut (no_key); _clear_command_window_action->setShortcut (no_key); _clear_workspace_action->setShortcut (no_key); // window menu _reset_windows_action->setShortcut (no_key); // help menu _ondisk_doc_action->setShortcut (no_key); _online_doc_action->setShortcut (no_key); _report_bug_action->setShortcut (no_key); _octave_packages_action->setShortcut (no_key); _agora_action->setShortcut (no_key); _contribute_action->setShortcut (no_key); _developer_action->setShortcut (no_key); _about_octave_action->setShortcut (no_key); // news menu _release_notes_action->setShortcut (no_key); _current_news_action->setShortcut (no_key); } } void main_window::set_screen_size (int ht, int wd) { octave_link::post_event (this, &main_window::set_screen_size_callback, int_pair (ht, wd)); } void main_window::handle_show_doc (const QString& file) { doc_browser_window->setVisible (true); emit show_doc_signal (file); } void main_window::clipboard_has_changed (QClipboard::Mode cp_mode) { if (cp_mode == QClipboard::Clipboard) { if (_clipboard->text ().isEmpty ()) { _paste_action->setEnabled (false); _clear_clipboard_action->setEnabled (false); } else { _paste_action->setEnabled (true); _clear_clipboard_action->setEnabled (true); } } } void main_window::clear_clipboard () { _clipboard->clear (QClipboard::Clipboard); }