Mercurial > hg > octave-nkf
view libgui/src/main-window.cc @ 20194:8f59e3cca4e7
remove undo-button from main toolbar and rename toolbar title
* main-window.cc (construct_tool_bar): rename toolbar;
(construct_tool_bar): no undo button
author | Torsten <ttl@justmail.de> |
---|---|
date | Wed, 25 Mar 2015 21:18:37 +0100 |
parents | 643de08e524c |
children | 3538c2824dd8 |
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 "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, bool start_gui) : QMainWindow (p), _workspace_model (start_gui ? new workspace_model () : 0), status_bar (start_gui ? new QStatusBar () : 0), command_window (start_gui ? new terminal_dock_widget (this) : 0), history_window (start_gui ? new history_dock_widget (this) : 0), file_browser_window (start_gui ? new files_dock_widget (this) : 0), doc_browser_window (start_gui ? new documentation_dock_widget (this) : 0), editor_window (start_gui ? create_default_editor (this) : 0), workspace_window (start_gui ? new workspace_view (this) : 0), _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), _suppress_dbg_location (true), _start_gui (start_gui) { 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 (start_gui && 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); QList<QDockWidget *> tabbed = tabifiedDockWidgets (dock); if (tabbed.contains (_active_dock)) dock->set_predecessor_widget (_active_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) { if (command_window_has_focus ()) octave_link::post_event (this, &main_window::command_window_undo_callback); else emit undo_signal (); } 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 (620, 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 (); _suppress_dbg_location = ! settings->value ("terminal/print_debug_location", false).toBool (); resource_manager::update_network_settings (); emit active_dock_changed (0, _active_dock); // update dock widget styles configure_shortcuts (); set_global_shortcuts (_active_dock == command_window); set_global_edit_shortcuts (_active_dock == editor_window); } void main_window::confirm_shutdown_octave (void) { bool closenow = true; if (_start_gui) { 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 (void) { 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 // 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); connect_uiwidget_links (); construct_octave_qt_link (); if (_start_gui) { 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))); 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&))); 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); #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); 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) { 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 ()); if (editor_window) { #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 } if (_start_gui) 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 (exit_app_signal (int)), this, SLOT (exit_app (int))); connect (_octave_qt_link, SIGNAL (confirm_shutdown_signal ()), this, SLOT (confirm_shutdown_octave ())); if (_start_gui) { connect (_octave_qt_link, SIGNAL (set_workspace_signal (bool, bool, const QString&, const QStringList&, const QStringList&, const QStringList&, const QStringList&, const QIntList&)), _workspace_model, SLOT (set_workspace (bool, 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 (resource_manager::icon ("document-open"), 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 (resource_manager::icon ("preferences-system"), 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 (resource_manager::icon ("document-new"), 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 (resource_manager::icon ("edit-undo"), tr ("Undo")); edit_menu->addSeparator (); _copy_action = edit_menu->addAction (resource_manager::icon ("edit-copy"), tr ("Copy"), this, SLOT (copyClipboard ())); _paste_action = edit_menu->addAction (resource_manager::icon ("edit-paste"), 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 (resource_manager::icon ("edit-find"), 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, resource_manager::icon (QString (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 ( "db-step", tr ("Step"), SLOT (debug_step_over ())); _debug_step_into = construct_debug_menu_item ( "db-step-in", tr ("Step In"), SLOT (debug_step_into ())); _debug_step_out = construct_debug_menu_item ( "db-step-out", tr ("Step Out"), SLOT (debug_step_out ())); _debug_continue = construct_debug_menu_item ( "db-cont", tr ("Continue"), SLOT (debug_continue ())); _debug_menu->addSeparator (); #ifdef HAVE_QSCINTILLA editor_window->debug_menu ()->addSeparator (); #endif _debug_quit = construct_debug_menu_item ( "db-stop", 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 (tr ("Toolbar")); _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->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 ( resource_manager::icon ("go-up"), tr ("One directory up")); QAction *current_dir_search = _main_tool_bar->addAction ( resource_manager::icon ("folder"), 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); }