GNU Octave  6.2.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
main-window.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (C) 2011-2021 The Octave Project Developers
4 //
5 // See the file COPYRIGHT.md in the top-level directory of this
6 // distribution or <https://octave.org/copyright/>.
7 //
8 // This file is part of Octave.
9 //
10 // Octave is free software: you can redistribute it and/or modify it
11 // under the terms of the GNU General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // Octave is distributed in the hope that it will be useful, but
16 // WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU General Public License for more details.
19 //
20 // You should have received a copy of the GNU General Public License
21 // along with Octave; see the file COPYING. If not, see
22 // <https://www.gnu.org/licenses/>.
23 //
24 ////////////////////////////////////////////////////////////////////////
25 
26 #if defined (HAVE_CONFIG_H)
27 # include "config.h"
28 #endif
29 
30 #include <utility>
31 
32 #include <QAction>
33 #include <QApplication>
34 #include <QClipboard>
35 #include <QDateTime>
36 #include <QDebug>
37 #include <QDesktopServices>
38 #include <QDesktopWidget>
39 #include <QFileDialog>
40 #include <QIcon>
41 #include <QInputDialog>
42 #include <QKeySequence>
43 #include <QLabel>
44 #include <QMenu>
45 #include <QMenuBar>
46 #include <QMessageBox>
47 #include <QStyle>
48 #include <QStyleFactory>
49 #include <QStyleFactory>
50 #include <QTextBrowser>
51 #include <QTextCodec>
52 #include <QTextStream>
53 #include <QThread>
54 #include <QTimer>
55 #include <QToolBar>
56 
57 #if defined (HAVE_QSCINTILLA)
58 # include "file-editor.h"
59 #endif
60 #include "gui-preferences-cs.h"
61 #include "gui-preferences-dw.h"
62 #include "gui-preferences-ed.h"
63 #include "gui-preferences-global.h"
64 #include "gui-preferences-mw.h"
65 #include "gui-preferences-nr.h"
66 #include "gui-preferences-sc.h"
67 #include "gui-settings.h"
68 #include "interpreter-qobject.h"
69 #include "main-window.h"
70 #include "news-reader.h"
71 #include "octave-qobject.h"
72 #include "settings-dialog.h"
73 #include "shortcut-manager.h"
74 #include "welcome-wizard.h"
75 
76 #include "Array.h"
77 #include "cmd-edit.h"
78 #include "oct-env.h"
79 #include "url-transfer.h"
80 
81 #include "builtin-defun-decls.h"
82 #include "defaults.h"
83 #include "defun.h"
84 #include "interpreter-private.h"
85 #include "interpreter.h"
86 #include "load-path.h"
87 #include "oct-map.h"
88 #include "octave.h"
89 #include "parse.h"
90 #include "syminfo.h"
91 #include "symscope.h"
92 #include "utils.h"
93 #include "version.h"
94 
95 namespace octave
96 {
97  static file_editor_interface *
99  {
100 #if defined (HAVE_QSCINTILLA)
101  return new file_editor (p, oct_qobj);
102 #else
103  octave_unused_parameter (p);
104  octave_unused_parameter (oct_qobj);
105 
106  return 0;
107 #endif
108  }
109 
111  : QMainWindow (), m_octave_qobj (oct_qobj),
112  m_workspace_model (nullptr),
113  m_status_bar (nullptr), m_command_window (nullptr),
114  m_history_window (nullptr), m_file_browser_window (nullptr),
115  m_doc_browser_window (nullptr), m_editor_window (nullptr),
116  m_workspace_window (nullptr), m_variable_editor_window (nullptr),
117  m_external_editor (new external_editor_interface (this, m_octave_qobj)),
118  m_active_editor (m_external_editor), m_settings_dlg (nullptr),
119  m_find_files_dlg (nullptr), m_set_path_dlg (nullptr),
120  m_release_notes_window (nullptr), m_community_news_window (nullptr),
121  m_clipboard (QApplication::clipboard ()),
122  m_prevent_readline_conflicts (true), m_suppress_dbg_location (true),
123  m_closing (false), m_file_encoding (QString ())
124  {
126 
127  if (rmgr.is_first_run ())
128  {
129  // Before wizard.
131 
132  welcome_wizard welcomeWizard (m_octave_qobj);
133 
134  if (welcomeWizard.exec () == QDialog::Rejected)
135  exit (1);
136 
137  // Install settings file.
138  rmgr.reload_settings ();
139  }
140  else
141  {
142  // Get settings file.
143  rmgr.reload_settings ();
144 
145  // After settings.
147  }
148 
149  rmgr.update_network_settings ();
150 
151  // We provide specific terminal capabilities, so ensure that
152  // TERM is always set appropriately.
153 
154 #if defined (OCTAVE_USE_WINDOWS_API)
155  sys::env::putenv ("TERM", "cygwin");
156 #else
157  sys::env::putenv ("TERM", "xterm");
158 #endif
159 
160  // FIXME: can we do this job when creating the shortcut manager?
161  // A quick look shows that it may require some coordination with the
162  // resource manager. Startup is complicated, but maybe we can make
163  // it simpler?
165  scmgr.init_data ();
166 
168 
170  m_status_bar = new QStatusBar ();
178 
180 
181  // Set active editor depending on editor window. If the latter is
182  // not initialized (qscintilla not present), use the external editor.
183  if (m_editor_window)
185  else
187 
188 #if defined (HAVE_QGUIAPPLICATION_SETDESKTOPFILENAME)
189  QGuiApplication::setDesktopFileName ("org.octave.Octave.desktop");
190 #endif
191 
193 
194  m_default_style = qapp->style ()->objectName ();
195 
197 
198  bool connect_to_web = true;
199  QDateTime last_checked;
200  int serial = 0;
201  m_active_dock = nullptr;
202 
203  if (settings)
204  {
205  connect_to_web
206  = settings->value (nr_allow_connection).toBool ();
207 
208  last_checked
209  = settings->value (nr_last_time).toDateTime ();
210 
211  serial = settings->value (nr_last_news).toInt ();
212  m_default_encoding = settings->value (ed_default_enc).toString ();
213  }
214 
215  QDateTime current = QDateTime::currentDateTime ();
216  QDateTime one_day_ago = current.addDays (-1);
217 
218  if (connect_to_web
219  && (! last_checked.isValid () || one_day_ago > last_checked))
221 
223 
224  // We have to set up all our windows, before we finally launch
225  // octave.
226 
227  construct ();
228 
229  read_settings ();
230 
232 
233  // Connect signals for changes in visibility now before window is
234  // shown.
235 
237 
239  }
240 
242  {
243  // Destroy the terminal first so that STDERR stream is redirected back
244  // to its original pipe to capture error messages at exit.
245 
246  delete m_editor_window; // first one for dialogs of modified editor-tabs
247  delete m_external_editor;
248  delete m_command_window;
249  delete m_workspace_window;
250  delete m_doc_browser_window;
251  delete m_file_browser_window;
252  delete m_history_window;
253  delete m_status_bar;
254  delete m_workspace_model;
256 
257  delete m_find_files_dlg;
258  delete m_release_notes_window;
260  }
261 
263  {
264  return m_command_window->has_focus ();
265  }
266 
268  {
270  }
271 
272  void main_window::focus_window (const QString& win_name)
273  {
274  if (win_name == "command")
276  else if (win_name == "history")
278  else if (win_name == "workspace")
280  else if (win_name == "filebrowser")
282  }
283 
285  {
286  bool closenow = true;
287 
290 
291  if (settings->value (global_prompt_to_exit.key,
292  global_prompt_to_exit.def).toBool ())
293  {
294  int ans = QMessageBox::question (this, tr ("Octave"),
295  tr ("Are you sure you want to exit Octave?"),
296  (QMessageBox::Ok
297  | QMessageBox::Cancel),
298  QMessageBox::Ok);
299 
300  if (ans != QMessageBox::Ok)
301  closenow = false;
302  }
303 
304 #if defined (HAVE_QSCINTILLA)
305  if (closenow)
306  closenow = m_editor_window->check_closing ();
307 #endif
308 
309  return closenow;
310  }
311 
312  // catch focus changes and determine the active dock widget
314  {
315  // If there is no new widget (e.g., when pressing <alt> and the global
316  // menu gets active), we can return immediately
317  if (! new_widget)
318  return;
319 
320  octave_dock_widget *dock = nullptr;
321  QWidget *w_new = new_widget; // get a copy of new focus widget
322  QWidget *start = w_new; // Save it as start of our search
323  int count = 0; // fallback to prevent endless loop
324 
326 
327  while (w_new && w_new != m_main_tool_bar && count < 100)
328  {
329  // Go through all dock widgets and check whether the current widget
330  // with focus is a child of one of them.
331  for (auto w : w_list)
332  {
333  if (w->isAncestorOf (w_new))
334  dock = w;
335  }
336 
337  if (dock)
338  break;
339 
340  // If not yet found (in case w_new is not a child of its dock widget),
341  // test next widget in the focus chain
342  w_new = qobject_cast<QWidget *> (w_new->previousInFocusChain ());
343 
344  // Measures preventing an endless loop
345  if (w_new == start)
346  break; // We have arrived where we began ==> exit loop
347  count++; // Limited number of trials
348  }
349 
350  // editor needs extra handling
351  octave_dock_widget *edit_dock_widget
352  = static_cast<octave_dock_widget *> (m_editor_window);
353  // if new dock has focus, emit signal and store active focus
354  // except editor changes to a dialog (dock=0)
355  if ((dock || m_active_dock != edit_dock_widget) && (dock != m_active_dock))
356  {
357  // signal to all dock widgets for updating the style
358  emit active_dock_changed (m_active_dock, dock);
359 
360  if (dock)
361  {
362  QList<QDockWidget *> tabbed = tabifiedDockWidgets (dock);
363  if (tabbed.contains (m_active_dock))
365  }
366 
367  if (edit_dock_widget == dock)
368  emit editor_focus_changed (true);
369  else if (edit_dock_widget == m_active_dock)
370  emit editor_focus_changed (false);
371 
372  if (m_active_dock)
374  m_active_dock = dock;
375  }
376  }
377 
379  {
382 
383  if (settings)
384  emit settings_changed (settings);
385  }
386 
387  void main_window::report_status_message (const QString& statusMessage)
388  {
389  m_status_bar->showMessage (statusMessage, 1000);
390  }
391 
393  {
394  // FIXME: Remove, if for all common KDE versions (bug #54607) is resolved.
395  int opts = 0; // No options by default.
398  if (! settings->value (global_use_native_dialogs).toBool ())
399  opts = QFileDialog::DontUseNativeDialog;
400 
401  QString file
402  = QFileDialog::getSaveFileName (this, tr ("Save Workspace As"), ".",
403  nullptr, nullptr, QFileDialog::Option (opts));
404 
405  if (! file.isEmpty ())
406  {
407  emit interpreter_event
408  ([file] (interpreter& interp)
409  {
410  // INTERPRETER THREAD
411 
412  Fsave (interp, ovl (file.toStdString ()));
413  });
414  }
415  }
416 
417  void main_window::handle_load_workspace_request (const QString& file_arg)
418  {
419  // FIXME: Remove, if for all common KDE versions (bug #54607) is resolved.
420  int opts = 0; // No options by default.
423  if (! settings->value (global_use_native_dialogs).toBool ())
424  opts = QFileDialog::DontUseNativeDialog;
425 
426  QString file = file_arg;
427 
428  if (file.isEmpty ())
429  file = QFileDialog::getOpenFileName (this, tr ("Load Workspace"), ".",
430  nullptr, nullptr, QFileDialog::Option (opts));
431 
432  if (! file.isEmpty ())
433  {
434  emit interpreter_event
435  ([file] (interpreter& interp)
436  {
437  // INTERPRETER THREAD
438 
439  Fload (interp, ovl (file.toStdString ()));
440 
441  tree_evaluator& tw = interp.get_evaluator ();
442 
443  event_manager& xevmgr = interp.get_event_manager ();
444 
445  xevmgr.set_workspace (true, tw.get_symbol_info ());
446  });
447  }
448  }
449 
450  void main_window::handle_open_any_request (const QString& file_arg)
451  {
452  if (! file_arg.isEmpty ())
453  {
454  std::string file = file_arg.toStdString ();
455 
456  emit interpreter_event
457  ([file] (interpreter& interp)
458  {
459  // INTERPRETER THREAD
460 
461  interp.feval ("open", ovl (file));
462 
463  // Update the workspace since open.m may have loaded new
464  // variables.
465  tree_evaluator& tw = interp.get_evaluator ();
466 
467  event_manager& xevmgr = interp.get_event_manager ();
468 
469  xevmgr.set_workspace (true, tw.get_symbol_info ());
470  });
471  }
472  }
473 
475  {
476  emit interpreter_event
477  ([] (interpreter& interp)
478  {
479  // INTERPRETER THREAD
480 
481  Fclear (interp);
482  });
483  }
484 
486  {
487  emit interpreter_event
488  ([] (void)
489  {
490  // INTERPRETER THREAD
491 
494  });
495  }
496 
498  {
499  emit interpreter_event
500  ([] (interpreter& interp)
501  {
502  // INTERPRETER THREAD
503 
504  history_system& history_sys = interp.get_history_system ();
505 
506  history_sys.do_history (ovl ("-c"));
507  });
508  }
509 
511  {
513  {
514  emit interpreter_event
515  ([] (void)
516  {
517  // INTERPRETER THREAD
518 
521  });
522  }
523  else
524  emit undo_signal ();
525  }
526 
527  void main_window::handle_rename_variable_request (const QString& old_name_arg,
528  const QString& new_name_arg)
529 
530  {
531  std::string old_name = old_name_arg.toStdString ();
532  std::string new_name = new_name_arg.toStdString ();
533 
534  emit interpreter_event
535  ([old_name, new_name] (interpreter& interp)
536  {
537  // INTERPRETER THREAD
538 
539  symbol_scope scope = interp.get_current_scope ();
540 
541  if (scope)
542  {
543  scope.rename (old_name, new_name);
544 
545  tree_evaluator& tw = interp.get_evaluator ();
546 
547  event_manager& xevmgr = interp.get_event_manager ();
548 
549  xevmgr.set_workspace (true, tw.get_symbol_info ());
550  }
551 
552  // FIXME: if this action fails, do we need a way to display that info
553  // in the GUI?
554  });
555  }
556 
558  bool rm, bool subdirs)
559  {
560  emit interpreter_event
561  ([dir_list, rm, subdirs, this] (interpreter& interp)
562  {
563  // INTERPRETER THREAD
564 
565  octave_value_list paths = ovl ();
566 
567  if (subdirs)
568  {
569  // Loop over all directories in order to get all subdirs
570  for (octave_idx_type i = 0; i < dir_list.length (); i++)
571  paths.append (Fgenpath (dir_list(i)));
572  }
573  else
574  paths = dir_list;
575 
576  if (rm)
577  Frmpath (interp, paths);
578  else
579  Faddpath (interp, paths);
580  });
581  }
582 
583  void main_window::new_file (const QString& commands)
584  {
585  emit new_file_signal (commands);
586  }
587 
588  void main_window::open_file (const QString& file_name, int line)
589  {
590  if (line < 0)
591  emit open_file_signal (file_name);
592  else
593  emit open_file_signal (file_name, QString (), line);
594  }
595 
596  void main_window::edit_mfile (const QString& name, int line)
597  {
598  handle_edit_mfile_request (name, QString (), QString (), line);
599  }
600 
601  void main_window::file_remove_proxy (const QString& o, const QString& n)
602  {
604 
605  qt_interpreter_events *qt_link = interp_qobj->qt_link ();
606 
607  // Wait for worker to suspend
608  qt_link->lock ();
609 
610  // Close the file if opened
611 #if defined (HAVE_QSCINTILLA)
613 #else
614  octave_unused_parameter (o);
615  octave_unused_parameter (n);
616 #endif
617 
618  // We are done: Unlock and wake the worker thread
619  qt_link->unlock ();
620  qt_link->wake_all ();
621  }
622 
624  {
625  QDesktopServices::openUrl
626  (QUrl ("https://octave.org/doc/interpreter/index.html"));
627  }
628 
630  {
632  {
633  std::string news_file = config::oct_etc_dir () + "/NEWS";
634 
635  QString news;
636 
637  QFile *file = new QFile (QString::fromStdString (news_file));
638  if (file->open (QFile::ReadOnly))
639  {
640  QTextStream *stream = new QTextStream (file);
641  news = stream->readAll ();
642  if (! news.isEmpty ())
643  {
644  // Convert '<', '>' which would be interpreted as HTML
645  news.replace ("<", "&lt;");
646  news.replace (">", "&gt;");
647  // Add HTML tags for pre-formatted text
648  news.prepend ("<pre>");
649  news.append ("</pre>");
650  }
651  else
652  news = (tr ("The release notes file '%1' is empty.")
653  . arg (QString::fromStdString (news_file)));
654  }
655  else
656  news = (tr ("The release notes file '%1' cannot be read.")
657  . arg (QString::fromStdString (news_file)));
658 
660 
662  browser->setText (news);
663 
664  QVBoxLayout *vlayout = new QVBoxLayout;
665  vlayout->addWidget (browser);
666 
667  m_release_notes_window->setLayout (vlayout);
668  m_release_notes_window->setWindowTitle (tr ("Octave Release Notes"));
669 
670  browser->document ()->adjustSize ();
671 
672  int win_x, win_y;
673  get_screen_geometry (&win_x, &win_y);
674 
675  m_release_notes_window->resize (win_x*2/5, win_y*2/3);
676  m_release_notes_window->move (20, 20); // move to the top left corner
677  }
678 
679  if (! m_release_notes_window->isVisible ())
680  m_release_notes_window->show ();
681  else if (m_release_notes_window->isMinimized ())
682  m_release_notes_window->showNormal ();
683 
684  m_release_notes_window->setWindowIcon (QIcon (m_release_notes_icon));
685 
686  m_release_notes_window->raise ();
687  m_release_notes_window->activateWindow ();
688  }
689 
691  {
694 
695  bool connect_to_web
696  = (settings
697  ? settings->value (nr_allow_connection).toBool ()
698  : true);
699 
700  QString base_url = "https://octave.org";
701  QString page = "community-news.html";
702 
703  QThread *worker_thread = new QThread;
704 
705  news_reader *reader = new news_reader (m_octave_qobj, base_url, page,
706  serial, connect_to_web);
707 
708  reader->moveToThread (worker_thread);
709 
710  connect (reader, SIGNAL (display_news_signal (const QString&)),
711  this, SLOT (display_community_news (const QString&)));
712 
713  connect (worker_thread, SIGNAL (started (void)),
714  reader, SLOT (process (void)));
715 
716  connect (reader, SIGNAL (finished (void)), worker_thread, SLOT (quit (void)));
717 
718  connect (reader, SIGNAL (finished (void)), reader, SLOT (deleteLater (void)));
719 
720  connect (worker_thread, SIGNAL (finished (void)),
721  worker_thread, SLOT (deleteLater (void)));
722 
723  worker_thread->start ();
724  }
725 
726  void main_window::display_community_news (const QString& news)
727  {
729  {
731 
733 
734  browser->setHtml (news);
735  browser->setObjectName ("OctaveNews");
736  browser->setOpenExternalLinks (true);
737 
738  QVBoxLayout *vlayout = new QVBoxLayout;
739 
740  vlayout->addWidget (browser);
741 
742  m_community_news_window->setLayout (vlayout);
743  m_community_news_window->setWindowTitle (tr ("Octave Community News"));
744 
745  int win_x, win_y;
746  get_screen_geometry (&win_x, &win_y);
747 
748  m_community_news_window->resize (win_x/2, win_y/2);
749  m_community_news_window->move ((win_x - m_community_news_window->width ())/2,
750  (win_y - m_community_news_window->height ())/2);
751  }
752  else
753  {
754  // Window already exists, just update the browser contents
755  QTextBrowser *browser
756 
757  = m_community_news_window->findChild<QTextBrowser *>("OctaveNews"
758 #if defined (QOBJECT_FINDCHILDREN_ACCEPTS_FINDCHILDOPTIONS)
759  , Qt::FindDirectChildrenOnly
760 #endif
761  );
762  if (browser)
763  browser->setHtml (news);
764  }
765 
766  if (! m_community_news_window->isVisible ())
767  m_community_news_window->show ();
768  else if (m_community_news_window->isMinimized ())
769  m_community_news_window->showNormal ();
770 
771  // same icon as release notes
772  m_community_news_window->setWindowIcon (QIcon (m_release_notes_icon));
773 
774  m_community_news_window->raise ();
775  m_community_news_window->activateWindow ();
776  }
777 
779  {
780  QDesktopServices::openUrl (QUrl ("https://octave.org/bugs.html"));
781  }
782 
784  {
785  QDesktopServices::openUrl (QUrl ("https://octave.org/packages.html"));
786  }
787 
789  {
790  QDesktopServices::openUrl (QUrl ("https://octave.org/contribute.html"));
791  }
792 
794  {
795  QDesktopServices::openUrl (QUrl ("https://octave.org/donate.html"));
796  }
797 
798  void main_window::process_settings_dialog_request (const QString& desired_tab)
799  {
800  if (m_settings_dlg) // m_settings_dlg is a guarded pointer!
801  {
802  // here the dialog is still open and called once again
803  if (! desired_tab.isEmpty ())
804  m_settings_dlg->show_tab (desired_tab);
805  return;
806  }
807 
808  m_settings_dlg = new settings_dialog (this, m_octave_qobj, desired_tab);
809 
810  connect (m_settings_dlg, SIGNAL (apply_new_settings (void)),
811  this, SLOT (request_reload_settings (void)));
812 
813  m_settings_dlg->setModal (false);
814  m_settings_dlg->setAttribute (Qt::WA_DeleteOnClose);
815  m_settings_dlg->show ();
816  }
817 
819  {
820  std::string message
822 
823  QMessageBox::about (this, tr ("About Octave"),
825  }
826 
828  bool update_by_worker)
829  {
830  if (! settings)
831  return;
832 
833  // Get desired style from preferences or take the default one if
834  // the desired one is not found
835  QString preferred_style = settings->value (global_style).toString ();
836 
837  if (preferred_style == global_style.def.toString ())
838  preferred_style = m_default_style;
839 
840  QStyle *new_style = QStyleFactory::create (preferred_style);
841  if (new_style)
842  {
844 
845  qapp->setStyle (new_style);
846  }
847 
848  // the widget's icons (when floating)
849  QString icon_set
850  = settings->value (dw_icon_set).toString ();
851 
852  int count = 0;
853  int icon_set_found = 0; // default
854 
855  while (! dw_icon_set_names[count].name.isEmpty ())
856  {
857  // while not end of data
858  if (dw_icon_set_names[count].name == icon_set)
859  {
860  // data of desired icon set found
861  icon_set_found = count;
862  break;
863  }
864  count++;
865  }
866 
867  QString icon;
868  for (auto *widget : dock_widget_list ())
869  {
870  QString name = widget->objectName ();
871  if (! name.isEmpty ())
872  {
873  // if child has a name
874  icon = dw_icon_set_names[icon_set_found].path; // prefix | octave-logo
875  if (dw_icon_set_names[icon_set_found].name != "NONE")
876  icon += name + ".png"; // add widget name and ext.
877  widget->setWindowIcon (QIcon (icon));
878  }
879  }
880  if (dw_icon_set_names[icon_set_found].name != "NONE")
881  m_release_notes_icon = dw_icon_set_names[icon_set_found].path
882  + "ReleaseWidget.png";
883  else
884  m_release_notes_icon = ":/actions/icons/logo.png";
885 
886  int size_idx = settings->value (global_icon_size).toInt ();
887  size_idx = (size_idx > 0) - (size_idx < 0) + 1; // Make valid index from 0 to 2
888 
889  QStyle *st = style ();
890  int icon_size = st->pixelMetric (global_icon_sizes[size_idx]);
891  m_main_tool_bar->setIconSize (QSize (icon_size,icon_size));
892 
893  if (settings->value (global_status_bar.key, global_status_bar.def).toBool ())
894  m_status_bar->show ();
895  else
896  m_status_bar->hide ();
897 
900  sc_prevent_rl_conflicts.def).toBool ();
901 
903  = ! settings->value (cs_dbg_location).toBool ();
904 
906  rmgr.update_network_settings ();
907 
908  emit active_dock_changed (nullptr, m_active_dock); // update dock widget styles
909 
913 
914  // Check whether some octave internal preferences have to be updated
915  QString new_default_encoding
916  = settings->value (ed_default_enc).toString ();
917  // Do not update internal pref only if a) this update was not initiated
918  // by the worker and b) the pref has really changes
919  if (! update_by_worker && (new_default_encoding != m_default_encoding))
920  update_default_encoding (new_default_encoding);
921 
922  // Set cursor blinking depending on the settings
923  // Cursor blinking: consider old terminal related setting if not yet set
924  // TODO: This pref. can be deprecated / removed if Qt adds support for
925  // getting the cursor blink preferences from all OS environments
926  bool cursor_blinking;
927 
928  if (settings->contains (global_cursor_blinking.key))
929  cursor_blinking = settings->value (global_cursor_blinking).toBool ();
930  else
931  cursor_blinking = settings->value (cs_cursor_blinking).toBool ();
932 
933  if (cursor_blinking)
934  QApplication::setCursorFlashTime (1000); // 1000 ms flash time
935  else
936  QApplication::setCursorFlashTime (0); // no flashing
937 
938  }
939 
941  {
942  // Find files dialog is constructed dynamically, not at time of main_window
943  // construction. Connecting it to qApp aboutToQuit signal would have
944  // caused it to run after gui_settings is deleted.
945  if (m_find_files_dlg)
947 
948  if (m_set_path_dlg)
949  m_set_path_dlg->save_settings ();
950 
951  write_settings ();
952  }
953 
955  {
957  }
958 
959  void main_window::update_octave_directory (const QString& dir)
960  {
961  // Remove existing entry, if any, then add new directory at top and
962  // mark it as the current directory. Finally, update the file list
963  // widget.
964 
965  int index = m_current_directory_combo_box->findText (dir);
966 
967  if (index >= 0)
968  m_current_directory_combo_box->removeItem (index);
969 
970  m_current_directory_combo_box->insertItem (0, dir);
971  m_current_directory_combo_box->setCurrentIndex (0);
972  }
973 
975  {
976  // FIXME: Remove, if for all common KDE versions (bug #54607) is resolved.
977  int opts = QFileDialog::ShowDirsOnly;
980  if (! settings->value (global_use_native_dialogs).toBool ())
981  opts = QFileDialog::DontUseNativeDialog;
982 
983  QString dir
984  = QFileDialog::getExistingDirectory (this, tr ("Browse directories"), nullptr,
985  QFileDialog::Option (opts));
986 
988 
989  // FIXME: on Windows systems, the command window freezes after the
990  // previous actions. Forcing the focus appears to unstick it.
991 
993  }
994 
996  {
997  // Change to dir if it is an existing directory.
998 
999  QString xdir = (dir.isEmpty () ? "." : dir);
1000 
1001  QFileInfo fileInfo (xdir);
1002 
1003  if (fileInfo.exists () && fileInfo.isDir ())
1004  {
1005  emit interpreter_event
1006  ([xdir] (interpreter& interp)
1007  {
1008  // INTERPRETER THREAD
1009 
1010  interp.chdir (xdir.toStdString ());
1011  });
1012  }
1013  }
1014 
1016  {
1018  }
1019 
1020  // Slot that is called if return is pressed in the line edit of the
1021  // combobox to change to a new directory or a directory that is already
1022  // in the drop down list.
1023 
1025  {
1026  // Get new directory name, and change to it if it is new. Otherwise,
1027  // the combo box will trigger the "activated" signal to change to the
1028  // directory.
1029 
1030  QString dir = m_current_directory_combo_box->currentText ();
1031 
1032  int index = m_current_directory_combo_box->findText (dir);
1033 
1034  if (index < 0)
1036  }
1037 
1038  void main_window::execute_command_in_terminal (const QString& command)
1039  {
1040  emit interpreter_event
1041  ([command] (void)
1042  {
1043  // INTERPRETER THREAD
1044 
1045  std::string pending_input = command_editor::get_current_line ();
1046 
1047  command_editor::set_initial_input (pending_input);
1048  command_editor::replace_line (command.toStdString ());
1052  });
1053 
1055  }
1056 
1057  void main_window::run_file_in_terminal (const QFileInfo& info)
1058  {
1059  emit interpreter_event
1060  ([info] (interpreter& interp)
1061  {
1062  // INTERPRETER THREAD
1063 
1064  QString function_name = info.fileName ();
1065  function_name.chop (info.suffix ().length () + 1);
1066  std::string file_path = info.absoluteFilePath ().toStdString ();
1067 
1068  std::string pending_input = command_editor::get_current_line ();
1069 
1070  if (valid_identifier (function_name.toStdString ()))
1071  {
1072  // Valid identifier: call as function with possibility to
1073  // debug.
1074 
1075  load_path& lp = interp.get_load_path ();
1076 
1077  std::string path = info.absolutePath ().toStdString ();
1078 
1079  if (lp.contains_file_in_dir (file_path, path))
1080  command_editor::replace_line (function_name.toStdString ());
1081  }
1082  else
1083  {
1084  // No valid identifier: use equivalent of Fsource (), no
1085  // debug possible.
1086 
1087  interp.source_file (file_path);
1088 
1089  command_editor::replace_line ("");
1090  }
1091 
1092  command_editor::set_initial_input (pending_input);
1096  });
1097 
1099  }
1100 
1102  {
1103  emit interpreter_event
1104  ([] (interpreter& interp)
1105  {
1106  // INTERPRETER THREAD
1107 
1108  Fbuiltin (interp, ovl ("figure"));
1109  Fdrawnow (interp);
1110  });
1111  }
1112 
1114  {
1115  setWindowTitle ("Octave (Debugging)");
1116 
1117  m_debug_continue->setEnabled (true);
1118  m_debug_step_into->setEnabled (true);
1119  m_debug_step_over->setEnabled (true);
1120  m_debug_step_out->setEnabled (true);
1121  m_debug_quit->setEnabled (true);
1122 
1123 #if defined (HAVE_QSCINTILLA)
1125 #endif
1126  }
1127 
1129  {
1130  setWindowTitle ("Octave");
1131 
1132  m_debug_continue->setEnabled (false);
1133  m_debug_step_into->setEnabled (false);
1134  m_debug_step_over->setEnabled (m_editor_has_tabs);
1135  m_debug_step_out->setEnabled (false);
1136  m_debug_quit->setEnabled (false);
1137 
1138 #if defined (HAVE_QSCINTILLA)
1140 #endif
1141  }
1142 
1144  {
1145  emit interpreter_event
1146  ([this] (interpreter& interp)
1147  {
1148  // INTERPRETER THREAD
1149 
1151  Fdbcont (interp);
1152 
1154  });
1155  }
1156 
1158  {
1159  emit interpreter_event
1160  ([this] (interpreter& interp)
1161  {
1162  // INTERPRETER THREAD
1163 
1165  Fdbstep (interp, ovl ("in"));
1166 
1168  });
1169  }
1170 
1172  {
1173  if (m_debug_quit->isEnabled ())
1174  {
1175  // We are in debug mode, just call dbstep.
1176 
1177  emit interpreter_event
1178  ([this] (interpreter& interp)
1179  {
1180  // INTERPRETER THREAD
1181 
1184  Fdbstep (interp);
1185 
1187  });
1188  }
1189  else
1190  {
1191  // Not in debug mode: "step into" the current editor file
1192  emit step_into_file_signal ();
1193  }
1194  }
1195 
1197  {
1198  emit interpreter_event
1199  ([this] (interpreter& interp)
1200  {
1201  // INTERPRETER THREAD
1202 
1204  Fdbstep (interp, ovl ("out"));
1205 
1207  });
1208  }
1209 
1211  {
1212  emit interpreter_event
1213  ([] (interpreter& interp)
1214  {
1215  // INTERPRETER THREAD
1216 
1217  Fdbquit (interp);
1218 
1220  });
1221  }
1222 
1223  //
1224  // Functions related to file editing
1225  //
1226  // These are moved from editor to here for also using them when octave
1227  // is built without qscintilla
1228  //
1230  {
1231  // Open file isn't a file_editor_tab or editor function since the file
1232  // might be opened in an external editor. Hence, functionality is here.
1233 
1235  gui_settings *settings = rmgr.get_settings ();
1236  bool is_internal = m_editor_window
1237  && ! settings->value (global_use_custom_editor.key,
1238  global_use_custom_editor.def).toBool ();
1239 
1240  // Create a NonModal message.
1241  QWidget *p = this;
1242  if (is_internal)
1243  p = m_editor_window;
1244  QFileDialog *fileDialog = new QFileDialog (p);
1245  fileDialog->setNameFilter (tr ("Octave Files (*.m);;All Files (*)"));
1246 
1247  fileDialog->setAcceptMode (QFileDialog::AcceptOpen);
1248  fileDialog->setViewMode (QFileDialog::Detail);
1249  fileDialog->setFileMode (QFileDialog::ExistingFiles);
1250  fileDialog->setDirectory (m_current_directory_combo_box->itemText (0));
1251 
1252  // FIXME: Remove, if for all common KDE versions (bug #54607) is resolved.
1253  if (! settings->value (global_use_native_dialogs).toBool ())
1254  fileDialog->setOption(QFileDialog::DontUseNativeDialog);
1255 
1256  connect (fileDialog, SIGNAL (filesSelected (const QStringList&)),
1257  this, SLOT (request_open_files (const QStringList&)));
1258 
1259  fileDialog->setWindowModality (Qt::NonModal);
1260  fileDialog->setAttribute (Qt::WA_DeleteOnClose);
1261  fileDialog->show ();
1262  }
1263 
1264  // Create a new script
1265  void main_window::request_new_script (const QString& commands)
1266  {
1267  emit new_file_signal (commands);
1268  }
1269 
1270  // Create a new function and open it
1272  {
1273  bool ok;
1274  // Get the name of the new function: Parent of the input dialog is the
1275  // editor window or the main window. The latter is chosen, if a custom
1276  // editor is used or qscintilla is not available
1277  QWidget *p = m_editor_window;
1279  gui_settings *settings = rmgr.get_settings ();
1280  if (! p || settings->value (global_use_custom_editor.key,
1281  global_use_custom_editor.def).toBool ())
1282  p = this;
1283  QString new_name = QInputDialog::getText (p, tr ("New Function"),
1284  tr ("New function name:\n"), QLineEdit::Normal, "", &ok);
1285 
1286  if (ok && new_name.length () > 0)
1287  {
1288  // append suffix if it does not already exist
1289  if (new_name.rightRef (2) != ".m")
1290  new_name.append (".m");
1291  // check whether new files are created without prompt
1292  if (! settings->value (ed_create_new_file).toBool ())
1293  {
1294  // no, so enable this settings and wait for end of new file loading
1295  settings->setValue (ed_create_new_file.key, true);
1296  connect (m_editor_window, SIGNAL (file_loaded_signal (void)),
1297  this, SLOT (restore_create_file_setting (void)));
1298  }
1299  // start the edit command
1300  execute_command_in_terminal ("edit " + new_name);
1301  }
1302  }
1303 
1304  void main_window::handle_edit_mfile_request (const QString& fname,
1305  const QString& ffile,
1306  const QString& curr_dir,
1307  int line)
1308  {
1309  emit interpreter_event
1310  ([this, fname, ffile, curr_dir, line] (interpreter& interp)
1311  {
1312  // INTERPRETER THREAD
1313 
1314  // Split possible subfunctions
1315  QStringList fcn_list = fname.split ('>');
1316  QString fcn_name = fcn_list.at (0) + ".m";
1317 
1318  // FIXME: could use symbol_exist directly, but we may also want
1319  // to fix that to be a member function in the interpreter
1320  // class?
1321 
1322  // Is it a regular function within the search path? (Call Fexist)
1323  octave_value_list fct = Fexist (interp, ovl (fname.toStdString ()),0);
1324  int type = fct (0).int_value ();
1325 
1326  QString message = QString ();
1327  QString filename = QString ();
1328 
1329  switch (type)
1330  {
1331  case 3:
1332  case 5:
1333  case 103:
1334  message = tr ("%1 is a built-in, compiled or inline\n"
1335  "function and can not be edited.");
1336  break;
1337 
1338  case 2:
1339  // FIXME: could use a load_path function directly.
1340  octave_value_list file_path
1341  = Ffile_in_loadpath (interp, ovl (fcn_name.toStdString ()), 0);
1342  if (file_path.length () > 0)
1343  filename = QString::fromStdString (file_path (0).string_value ());
1344  break;
1345  }
1346 
1347  if (filename.isEmpty () && message.isEmpty ())
1348  {
1349  // No error so far, but function still not known
1350  // -> try directory of edited file
1351  // get directory
1352  QDir dir;
1353  if (ffile.isEmpty ())
1354  {
1355  if (curr_dir.isEmpty ())
1356  dir = QDir (m_current_directory_combo_box->itemText (0));
1357  else
1358  dir = QDir (curr_dir);
1359  }
1360  else
1361  dir = QDir (QFileInfo (ffile).canonicalPath ());
1362 
1363  QFileInfo file = QFileInfo (dir, fcn_name);
1364  if (file.exists ())
1365  filename = file.canonicalFilePath (); // local file exists
1366  else
1367  {
1368  // local file does not exist -> try private directory
1369  file = QFileInfo (ffile);
1370  file = QFileInfo (QDir (file.canonicalPath () + "/private"),
1371  fcn_name);
1372  if (file.exists ())
1373  filename = file.canonicalFilePath (); // private function exists
1374  else
1375  message = tr ("Can not find function %1"); // no file found
1376 
1377  }
1378  }
1379 
1380  if (! message.isEmpty ())
1381  {
1382  emit warning_function_not_found_signal (message.arg (fname));
1383  return;
1384  }
1385 
1386  if (! filename.endsWith (".m"))
1387  filename.append (".m");
1388 
1389  // default encoding
1390  emit open_file_signal (filename, QString (), line);
1391  });
1392  }
1393 
1395  {
1396  QMessageBox *msgBox = new QMessageBox (QMessageBox::Critical,
1397  tr ("Octave Editor"),
1398  message, QMessageBox::Ok, this);
1399  msgBox->setWindowModality (Qt::NonModal);
1400  msgBox->setAttribute (Qt::WA_DeleteOnClose);
1401  msgBox->show ();
1402  }
1403 
1405  int line)
1406  {
1407  bool cmd_focus = command_window_has_focus ();
1408 
1409  emit insert_debugger_pointer_signal (file, line);
1410 
1411  if (cmd_focus)
1413  }
1414 
1416  int line)
1417  {
1418  bool cmd_focus = command_window_has_focus ();
1419 
1420  emit delete_debugger_pointer_signal (file, line);
1421 
1422  if (cmd_focus)
1424  }
1425 
1427  const QString& file,
1428  int line,
1429  const QString& cond)
1430  {
1431  bool cmd_focus = command_window_has_focus ();
1432 
1433  emit update_breakpoint_marker_signal (insert, file, line, cond);
1434 
1435  if (cmd_focus)
1437  }
1438 
1440  {
1442  gui_settings *settings = rmgr.get_settings ();
1443 
1444  if (! settings)
1445  {
1446  qDebug ("Error: gui_settings pointer from resource manager is NULL.");
1447  return;
1448  }
1449 
1451 
1452  // restore the list of the last directories
1453  QStringList curr_dirs = settings->value (mw_dir_list).toStringList ();
1454  for (int i=0; i < curr_dirs.size (); i++)
1455  {
1456  m_current_directory_combo_box->addItem (curr_dirs.at (i));
1457  }
1458  emit settings_changed (settings);
1459  }
1460 
1462  {
1463  emit init_terminal_size_signal ();
1464  }
1465 
1467  {
1468  // Restore main window state and geometry from settings file or, in case
1469  // of an error (no pref values yet), from the default layout.
1470  if (! restoreGeometry (settings->value (mw_geometry).toByteArray ()))
1471  {
1472  do_reset_windows (true);
1473  return;
1474  }
1475 
1476  if (isMaximized())
1477  {
1478  setGeometry( QApplication::desktop ()->availableGeometry (this));
1479  }
1480 
1481  if (! restoreState (settings->value (mw_state).toByteArray ()))
1482  {
1483  do_reset_windows (true);
1484  return;
1485  }
1486 
1487  // Restore the geometry of all dock-widgets
1488  for (auto *widget : dock_widget_list ())
1489  {
1490  QString name = widget->objectName ();
1491 
1492  if (! name.isEmpty ())
1493  {
1494  bool floating = false;
1495  bool visible = true;
1496 
1497  floating = settings->value
1498  (dw_is_floating.key.arg (name), dw_is_floating.def).toBool ();
1499  visible = settings->value
1500  (dw_is_visible.key.arg (name), dw_is_visible.def).toBool ();
1501 
1502  // If floating, make window from widget.
1503  if (floating)
1504  {
1505  widget->make_window ();
1506 
1507  if (visible)
1508  {
1509  if (settings->value (dw_is_minimized.key.arg (name),
1510  dw_is_minimized.def).toBool ())
1511  widget->showMinimized ();
1512  else
1513  widget->setVisible (true);
1514  }
1515  }
1516  else // not floating
1517  {
1518  if (! widget->parent ()) // should not be floating but is
1519  widget->make_widget (false); // no docking, just reparent
1520 
1521  widget->make_widget ();
1522  widget->setVisible (visible); // not floating -> show
1523  }
1524  }
1525  }
1526 
1527  show ();
1528  }
1529 
1531  {
1533  gui_settings *settings = rmgr.get_settings ();
1534  if (! settings)
1535  {
1536  qDebug ("Error: gui_settings pointer from resource manager is NULL.");
1537  return;
1538  }
1539 
1540  settings->setValue (mw_geometry.key, saveGeometry ());
1541  settings->setValue (mw_state.key, saveState ());
1542  // write the list of recently used directories
1543  QStringList curr_dirs;
1544  for (int i=0; i<m_current_directory_combo_box->count (); i++)
1545  {
1546  curr_dirs.append (m_current_directory_combo_box->itemText (i));
1547  }
1548  settings->setValue (mw_dir_list.key, curr_dirs);
1549  settings->sync ();
1550  }
1551 
1552  // Connecting the signals emitted when the visibility of a widget changes.
1553  // This has to be done after the window is shown (see octave-gui.cc)
1555  {
1556  for (auto *widget : dock_widget_list ())
1557  widget->connect_visibility_changed ();
1558 
1559 #if defined (HAVE_QSCINTILLA)
1561 #endif
1562  }
1563 
1565  {
1566  if (m_current_directory_combo_box->hasFocus ())
1567  {
1568  QLineEdit *edit = m_current_directory_combo_box->lineEdit ();
1569  if (edit && edit->hasSelectedText ())
1570  {
1571  QClipboard *clipboard = QApplication::clipboard ();
1572  clipboard->setText (edit->selectedText ());
1573  }
1574  }
1575  else
1576  emit copyClipboard_signal ();
1577  }
1578 
1580  {
1581  if (m_current_directory_combo_box->hasFocus ())
1582  {
1583  QLineEdit *edit = m_current_directory_combo_box->lineEdit ();
1584  QClipboard *clipboard = QApplication::clipboard ();
1585  QString str = clipboard->text ();
1586  if (edit && str.length () > 0)
1587  {
1588  edit->insert (str);
1589  }
1590  }
1591  else
1592  emit pasteClipboard_signal ();
1593  }
1594 
1596  {
1597  if (m_current_directory_combo_box->hasFocus ())
1598  {
1599  QLineEdit *edit = m_current_directory_combo_box->lineEdit ();
1600  if (edit)
1601  {
1602  edit->selectAll ();
1603  }
1604  }
1605  else
1606  emit selectAll_signal ();
1607  }
1608 
1609  void main_window::handle_show_doc (const QString& file)
1610  {
1611  m_doc_browser_window->setVisible (true);
1612  emit show_doc_signal (file);
1613  }
1614 
1615  void main_window::handle_register_doc (const QString& file)
1616  {
1617  emit register_doc_signal (file);
1618  }
1619 
1620  void main_window::handle_unregister_doc (const QString& file)
1621  {
1622  emit unregister_doc_signal (file);
1623  }
1624 
1626  {
1627  // actions after the startup files are executed
1629  gui_settings *settings = rmgr.get_settings ();
1630 
1631  QDir startup_dir = QDir (); // current octave dir after startup
1632 
1633  if (settings)
1634  {
1635  if (settings->value (global_restore_ov_dir.key,
1636  global_restore_ov_dir.def).toBool ())
1637  {
1638  // restore last dir from previous session
1639  QStringList curr_dirs
1640  = settings->value (mw_dir_list).toStringList ();
1641  startup_dir
1642  = QDir (curr_dirs.at (0)); // last dir in previous session
1643  }
1644  else if (! settings->value (global_ov_startup_dir.key,
1645  global_ov_startup_dir.def).toString ().isEmpty ())
1646  {
1647  // do not restore but there is a startup dir configured
1648  startup_dir
1649  = QDir (settings->value (global_ov_startup_dir.key,
1650  global_ov_startup_dir.def).toString ());
1651  }
1652 
1653  update_default_encoding (settings->value (ed_default_enc).toString ());
1654  }
1655 
1656  if (! startup_dir.exists ())
1657  {
1658  // the configured startup dir does not exist, take actual one
1659  startup_dir = QDir ();
1660  }
1661 
1662  set_current_working_directory (startup_dir.absolutePath ());
1663 
1664  if (m_editor_window)
1665  {
1666 #if defined (HAVE_QSCINTILLA)
1667  // Octave ready, determine whether to create an empty script.
1668  // This can not be done when the editor is created because all functions
1669  // must be known for the lexer's auto completion information
1670  m_editor_window->empty_script (true, false);
1672 #endif
1673  }
1674 
1675  focus_command_window (); // make sure that the command window has focus
1676  }
1677 
1679  {
1680  if (m_set_path_dlg) // m_set_path_dlg is a guarded pointer!
1681  return;
1682 
1684 
1685  m_set_path_dlg->setModal (false);
1686  m_set_path_dlg->setAttribute (Qt::WA_DeleteOnClose);
1687  m_set_path_dlg->show ();
1688 
1689  // Any interpreter_event signal from a set_path_dialog object is
1690  // handled the same as for the main_window object.
1691 
1692  connect (m_set_path_dlg, SIGNAL (interpreter_event (const fcn_callback&)),
1693  this, SIGNAL (interpreter_event (const fcn_callback&)));
1694 
1695  connect (m_set_path_dlg, SIGNAL (interpreter_event (const meth_callback&)),
1696  this, SIGNAL (interpreter_event (const meth_callback&)));
1697 
1698  connect (m_set_path_dlg,
1699  SIGNAL (modify_path_signal (const octave_value_list&, bool, bool)),
1700  this, SLOT (modify_path (const octave_value_list&, bool, bool)));
1701 
1703 
1704  qt_interpreter_events *qt_link = interp_qobj->qt_link ();
1705 
1706  connect (qt_link, SIGNAL (update_path_dialog_signal (void)),
1707  m_set_path_dlg, SLOT (update_model (void)));
1708 
1709  // Now that all the signal connections are in place for the dialog
1710  // we can set the initial value of the path in the model.
1711 
1712  m_set_path_dlg->update_model ();
1713  }
1714 
1715  void main_window::find_files (const QString& start_dir)
1716  {
1717 
1718  if (! m_find_files_dlg)
1719  {
1721 
1722  connect (m_find_files_dlg, SIGNAL (finished (int)),
1723  this, SLOT (find_files_finished (int)));
1724 
1725  connect (m_find_files_dlg, SIGNAL (dir_selected (const QString &)),
1727  SLOT (set_current_directory (const QString&)));
1728 
1729  connect (m_find_files_dlg, SIGNAL (file_selected (const QString &)),
1730  this, SLOT (open_file (const QString &)));
1731 
1732  m_find_files_dlg->setWindowModality (Qt::NonModal);
1733  }
1734 
1735  if (! m_find_files_dlg->isVisible ())
1736  {
1737  m_find_files_dlg->show ();
1738  }
1739 
1740  m_find_files_dlg->set_search_dir (start_dir);
1741 
1742  m_find_files_dlg->activateWindow ();
1743 
1744  }
1745 
1746  void main_window::set_global_shortcuts (bool set_shortcuts)
1747  {
1748  // this slot is called when the terminal gets/loses focus
1749 
1750  // return if the user doesn't want to use readline shortcuts
1752  return;
1753 
1754  if (set_shortcuts)
1755  {
1756  // terminal loses focus: set the global shortcuts
1758  }
1759  else
1760  {
1761  // terminal gets focus: disable some shortcuts
1762  QKeySequence no_key = QKeySequence ();
1763 
1764  // file menu
1765  m_open_action->setShortcut (no_key);
1766  m_new_script_action->setShortcut (no_key);
1767  m_new_function_action->setShortcut (no_key);
1768  m_new_figure_action->setShortcut (no_key);
1769  m_load_workspace_action->setShortcut (no_key);
1770  m_save_workspace_action->setShortcut (no_key);
1771  m_preferences_action->setShortcut (no_key);
1772  m_set_path_action->setShortcut (no_key);
1773  m_exit_action->setShortcut (no_key);
1774 
1775  // edit menu
1776  m_select_all_action->setShortcut (no_key);
1777  m_clear_clipboard_action->setShortcut (no_key);
1778  m_find_files_action->setShortcut (no_key);
1779  m_clear_command_history_action->setShortcut (no_key);
1780  m_clear_command_window_action->setShortcut (no_key);
1781  m_clear_workspace_action->setShortcut (no_key);
1782 
1783  // window menu
1784  m_reset_windows_action->setShortcut (no_key);
1785 
1786  // help menu
1787  m_ondisk_doc_action->setShortcut (no_key);
1788  m_online_doc_action->setShortcut (no_key);
1789  m_report_bug_action->setShortcut (no_key);
1790  m_octave_packages_action->setShortcut (no_key);
1791  m_contribute_action->setShortcut (no_key);
1792  m_developer_action->setShortcut (no_key);
1793  m_about_octave_action->setShortcut (no_key);
1794 
1795  // news menu
1796  m_release_notes_action->setShortcut (no_key);
1797  m_current_news_action->setShortcut (no_key);
1798  }
1799  }
1800 
1801  void main_window::set_screen_size (int ht, int wd)
1802  {
1803  emit interpreter_event
1804  ([ht, wd] (void)
1805  {
1806  // INTERPRETER THREAD
1807 
1809  });
1810  }
1811 
1813  {
1814  if (m_clipboard->text ().isEmpty ())
1815  {
1816  m_paste_action->setEnabled (false);
1817  m_clear_clipboard_action->setEnabled (false);
1818  }
1819  else
1820  {
1821  m_paste_action->setEnabled (true);
1822  m_clear_clipboard_action->setEnabled (true);
1823  }
1824  }
1825 
1827  {
1828  m_clipboard->clear (QClipboard::Clipboard);
1829  }
1830 
1832  {
1833  QHash<QMenu*, QStringList>::const_iterator i = m_hash_menu_text.constBegin ();
1834 
1835  while (i != m_hash_menu_text.constEnd ())
1836  {
1837  i.key ()->setTitle (i.value ().at (disable));
1838  ++i;
1839  }
1840  }
1841 
1843  {
1844  // restore the new files creation setting
1846  gui_settings *settings = rmgr.get_settings ();
1847  settings->setValue (ed_create_new_file.key, false);
1848  disconnect (m_editor_window, SIGNAL (file_loaded_signal (void)),
1849  this, SLOT (restore_create_file_setting (void)));
1850  }
1851 
1852  void main_window::set_file_encoding (const QString& new_encoding)
1853  {
1854  m_file_encoding = new_encoding;
1855  }
1856 
1857  // The following slot is called after files have been selected in the
1858  // open file dialog, possibly with a new selected encoding stored in
1859  // m_file_encoding
1860  void main_window::request_open_files (const QStringList& open_file_names)
1861  {
1862  for (int i = 0; i < open_file_names.count (); i++)
1863  emit open_file_signal (open_file_names.at (i), m_file_encoding, -1);
1864  }
1865 
1866  void main_window::edit_variable (const QString &expr, const octave_value& val)
1867  {
1869 
1870  if (! m_variable_editor_window->isVisible ())
1871  {
1872  m_variable_editor_window->show ();
1873  m_variable_editor_window->raise ();
1874  }
1875 
1876  }
1877 
1879  {
1881  }
1882 
1884  {
1885  // Called when the variable editor emits the updated signal. The size
1886  // of a variable may have changed, so we refresh the workspace in the
1887  // interpreter. That will eventually cause the workspace view in the
1888  // GUI to be updated.
1889 
1890  emit interpreter_event
1891  ([] (interpreter& interp)
1892  {
1893  // INTERPRETER THREAD
1894 
1895  tree_evaluator& tw = interp.get_evaluator ();
1896 
1897  event_manager& xevmgr = interp.get_event_manager ();
1898 
1899  xevmgr.set_workspace (true, tw.get_symbol_info (), false);
1900  });
1901  }
1902 
1903  void main_window::closeEvent (QCloseEvent *e)
1904  {
1905  if (confirm_shutdown ())
1906  {
1907  // FIXME: Instead of ignoring the event and posting an
1908  // interpreter event, should we just accept the event and
1909  // shutdown and clean up the interprter as part of closing the
1910  // GUI? Going that route might make it easier to close the GUI
1911  // without having to stop the interpreter, for example, if the
1912  // GUI is started from the interpreter command line.
1913 
1914  e->ignore ();
1915 
1916  emit interpreter_event
1917  ([] (interpreter& interp)
1918  {
1919  // INTERPRETER THREAD
1920 
1921  interp.quit (0, false, false);
1922  });
1923  }
1924  else
1925  e->ignore ();
1926  }
1927 
1929  {
1930  // Create and set the central widget. QMainWindow takes ownership of
1931  // the widget (pointer) so there is no need to delete the object upon
1932  // destroying this main_window.
1933 
1934  QWidget *dummyWidget = new QWidget ();
1935  dummyWidget->setObjectName ("CentralDummyWidget");
1936  dummyWidget->resize (10, 10);
1937  dummyWidget->setSizePolicy (QSizePolicy::Fixed, QSizePolicy::Fixed);
1938  dummyWidget->hide ();
1939  setCentralWidget (dummyWidget);
1940  }
1941 
1942 // Main subroutine of the constructor
1943 
1945  {
1946  setWindowIcon (QIcon (":/actions/icons/logo.png"));
1947 
1949 
1950  connect (m_workspace_model, SIGNAL (model_changed (void)),
1951  m_workspace_window, SLOT (handle_model_changed (void)));
1952 
1954 
1955  qt_interpreter_events *qt_link = interp_qobj->qt_link ();
1956 
1957  connect (qt_link,
1958  SIGNAL (edit_variable_signal (const QString&,
1959  const octave_value&)),
1960  this,
1961  SLOT (edit_variable (const QString&, const octave_value&)));
1962 
1963  connect (qt_link, SIGNAL (refresh_variable_editor_signal (void)),
1964  this, SLOT (refresh_variable_editor (void)));
1965 
1966  connect (m_workspace_window,
1967  SIGNAL (rename_variable_signal (const QString&, const QString&)),
1968  this,
1969  SLOT (handle_rename_variable_request (const QString&,
1970  const QString&)));
1971 
1972  connect (m_variable_editor_window, SIGNAL (updated (void)),
1973  this, SLOT (handle_variable_editor_update (void)));
1974 
1975  construct_menu_bar ();
1976 
1977  construct_tool_bar ();
1978 
1979  // Order is important. Deleting gui_settings must be last.
1980  connect (qApp, SIGNAL (aboutToQuit (void)),
1981  m_command_window, SLOT (save_settings (void)));
1982 
1983  connect (qApp, SIGNAL (aboutToQuit (void)),
1984  m_history_window, SLOT (save_settings (void)));
1985 
1986  connect (qApp, SIGNAL (aboutToQuit (void)),
1987  m_file_browser_window, SLOT (save_settings (void)));
1988 
1989  connect (qApp, SIGNAL (aboutToQuit (void)),
1990  m_doc_browser_window, SLOT (save_settings (void)));
1991 
1992  connect (qApp, SIGNAL (aboutToQuit (void)),
1993  m_workspace_window, SLOT (save_settings (void)));
1994 
1995  connect (qApp, SIGNAL (aboutToQuit (void)),
1996  m_editor_window, SLOT (save_settings (void)));
1997 
1998  connect (qApp, SIGNAL (aboutToQuit (void)),
1999  m_variable_editor_window, SLOT (save_settings (void)));
2000 
2001  connect (qApp, SIGNAL (aboutToQuit (void)),
2002  this, SLOT (prepare_to_exit (void)));
2003 
2004  connect (qApp, SIGNAL (focusChanged (QWidget*, QWidget*)),
2005  this, SLOT (focus_changed (QWidget*, QWidget*)));
2006 
2007  connect (this, SIGNAL (settings_changed (const gui_settings *)),
2008  this, SLOT (notice_settings (const gui_settings *)));
2009 
2010  connect (this, SIGNAL (editor_focus_changed (bool)),
2011  this, SLOT (disable_menu_shortcuts (bool)));
2012 
2013  connect (this, SIGNAL (editor_focus_changed (bool)),
2014  m_editor_window, SLOT (enable_menu_shortcuts (bool)));
2015 
2016  connect (this, SIGNAL (step_into_file_signal (void)),
2017  m_editor_window, SLOT (request_step_into_file (void)));
2018 
2019  connect (m_editor_window, SIGNAL (editor_tabs_changed_signal (bool)),
2020  this, SLOT (editor_tabs_changed (bool)));
2021 
2022  connect (m_editor_window,
2023  SIGNAL (request_open_file_external (const QString&, int)),
2025  SLOT (call_custom_editor (const QString&, int)));
2026 
2027  connect (m_external_editor,
2028  SIGNAL (request_settings_dialog (const QString&)),
2029  this, SLOT (process_settings_dialog_request (const QString&)));
2030 
2031  connect (m_file_browser_window, SIGNAL (load_file_signal (const QString&)),
2032  this, SLOT (handle_load_workspace_request (const QString&)));
2033 
2034  connect (m_file_browser_window, SIGNAL (open_any_signal (const QString&)),
2035  this, SLOT (handle_open_any_request (const QString&)));
2036 
2037  connect (m_file_browser_window, SIGNAL (find_files_signal (const QString&)),
2038  this, SLOT (find_files (const QString&)));
2039 
2040  // Connections for signals from the interpreter thread where the slot
2041  // should be executed by the gui thread
2042 
2043  connect (this, SIGNAL (warning_function_not_found_signal (const QString&)),
2044  this, SLOT (warning_function_not_found (const QString&)));
2045 
2046  setWindowTitle ("Octave");
2047 
2048  setStatusBar (m_status_bar);
2049 
2050 #if defined (HAVE_QSCINTILLA)
2051  connect (this,
2052  SIGNAL (insert_debugger_pointer_signal (const QString&, int)),
2054  SLOT (handle_insert_debugger_pointer_request (const QString&,
2055  int)));
2056 
2057  connect (this,
2058  SIGNAL (delete_debugger_pointer_signal (const QString&, int)),
2060  SLOT (handle_delete_debugger_pointer_request (const QString&,
2061  int)));
2062 
2063  connect (this,
2064  SIGNAL (update_breakpoint_marker_signal (bool, const QString&,
2065  int, const QString&)),
2068  const QString&,
2069  int,
2070  const QString&)));
2071 
2072  // Signals for removing/renaming files/dirs in the file browser
2073  connect (m_file_browser_window,
2074  SIGNAL (file_remove_signal (const QString&, const QString&)),
2076  SLOT (handle_file_remove (const QString&, const QString&)));
2077 
2078  connect (m_file_browser_window, SIGNAL (file_renamed_signal (bool)),
2079  m_editor_window, SLOT (handle_file_renamed (bool)));
2080 
2081  // Signals for removing/renaming files/dirs in the terminal window
2082  connect (qt_link, SIGNAL (file_renamed_signal (bool)),
2083  m_editor_window, SLOT (handle_file_renamed (bool)));
2084 #endif
2085 
2086  // Signals for removing/renaming files/dirs in the temrinal window
2087  connect (qt_link,
2088  SIGNAL (file_remove_signal (const QString&, const QString&)),
2089  this, SLOT (file_remove_proxy (const QString&, const QString&)));
2090 
2091  connect (this, SIGNAL (interpreter_event (const fcn_callback&)),
2092  &m_octave_qobj, SLOT (interpreter_event (const fcn_callback&)));
2093 
2094  connect (this, SIGNAL (interpreter_event (const meth_callback&)),
2095  &m_octave_qobj, SLOT (interpreter_event (const meth_callback&)));
2096 
2098  }
2099 
2101  {
2103 
2104  qt_interpreter_events *qt_link = interp_qobj->qt_link ();
2105 
2106  connect (qt_link, SIGNAL (settings_changed (const gui_settings *, bool)),
2107  this, SLOT (notice_settings (const gui_settings *, bool)));
2108 
2109  connect (qt_link, SIGNAL (apply_new_settings (void)),
2110  this, SLOT (request_reload_settings (void)));
2111 
2112  connect (qt_link,
2113  SIGNAL (set_workspace_signal (bool, bool, const symbol_info_list&)),
2115  SLOT (set_workspace (bool, bool, const symbol_info_list&)));
2116 
2117  connect (qt_link, SIGNAL (clear_workspace_signal (void)),
2118  m_workspace_model, SLOT (clear_workspace (void)));
2119 
2120  connect (qt_link, SIGNAL (directory_changed_signal (QString)),
2121  this, SLOT (update_octave_directory (QString)));
2122 
2123  connect (qt_link, SIGNAL (directory_changed_signal (QString)),
2125 
2126  connect (qt_link, SIGNAL (directory_changed_signal (QString)),
2127  m_editor_window, SLOT (update_octave_directory (QString)));
2128 
2129  connect (qt_link,
2130  SIGNAL (execute_command_in_terminal_signal (QString)),
2131  this, SLOT (execute_command_in_terminal (QString)));
2132 
2133  connect (qt_link,
2134  SIGNAL (set_history_signal (const QStringList&)),
2135  m_history_window, SLOT (set_history (const QStringList&)));
2136 
2137  connect (qt_link,
2138  SIGNAL (append_history_signal (const QString&)),
2139  m_history_window, SLOT (append_history (const QString&)));
2140 
2141  connect (qt_link,
2142  SIGNAL (clear_history_signal (void)),
2143  m_history_window, SLOT (clear_history (void)));
2144 
2145  connect (qt_link, SIGNAL (enter_debugger_signal (void)),
2146  this, SLOT (handle_enter_debugger (void)));
2147 
2148  connect (qt_link, SIGNAL (exit_debugger_signal (void)),
2149  this, SLOT (handle_exit_debugger (void)));
2150 
2151  connect (qt_link,
2152  SIGNAL (show_preferences_signal (void)),
2153  this, SLOT (process_settings_dialog_request (void)));
2154 
2155  connect (qt_link,
2156  SIGNAL (edit_file_signal (const QString&)),
2158  SLOT (handle_edit_file_request (const QString&)));
2159 
2160  connect (qt_link,
2161  SIGNAL (insert_debugger_pointer_signal (const QString&, int)),
2162  this,
2163  SLOT (handle_insert_debugger_pointer_request (const QString&,
2164  int)));
2165 
2166  connect (qt_link,
2167  SIGNAL (delete_debugger_pointer_signal (const QString&, int)),
2168  this,
2169  SLOT (handle_delete_debugger_pointer_request (const QString&,
2170  int)));
2171 
2172  connect (qt_link,
2173  SIGNAL (update_breakpoint_marker_signal (bool, const QString&,
2174  int, const QString&)),
2175  this,
2176  SLOT (handle_update_breakpoint_marker_request (bool, const QString&,
2177  int, const QString&)));
2178 
2179  connect (qt_link,
2180  SIGNAL (show_doc_signal (const QString &)),
2181  this, SLOT (handle_show_doc (const QString &)));
2182 
2183  connect (qt_link,
2184  SIGNAL (register_doc_signal (const QString &)),
2185  this, SLOT (handle_register_doc (const QString &)));
2186 
2187  connect (qt_link,
2188  SIGNAL (unregister_doc_signal (const QString &)),
2189  this, SLOT (handle_unregister_doc (const QString &)));
2190  }
2191 
2192  QAction* main_window::add_action (QMenu *menu, const QIcon& icon,
2193  const QString& text, const char *member,
2194  const QWidget *receiver)
2195  {
2196  QAction *a;
2197 
2198  if (receiver)
2199  a = menu->addAction (icon, text, receiver, member);
2200  else
2201  a = menu->addAction (icon, text, this, member);
2202 
2203  addAction (a); // important for shortcut context
2204  a->setShortcutContext (Qt::ApplicationShortcut);
2205  return a;
2206  }
2207 
2209  {
2210  QMenu *menu = p->addMenu (name);
2211 
2212  QString base_name = name; // get a copy
2213  // replace intended '&' ("&&") by a temp. string
2214  base_name.replace ("&&", "___octave_amp_replacement___");
2215  // remove single '&' (shortcut)
2216  base_name.remove ("&");
2217  // restore intended '&'
2218  base_name.replace ("___octave_amp_replacement___", "&&");
2219 
2220  // remember names with and without shortcut
2221  m_hash_menu_text[menu] = QStringList () << name << base_name;
2222 
2223  return menu;
2224  }
2225 
2227  {
2228  QMenuBar *menu_bar = menuBar ();
2229 
2230  construct_file_menu (menu_bar);
2231 
2232  construct_edit_menu (menu_bar);
2233 
2234  construct_debug_menu (menu_bar);
2235 
2236  construct_window_menu (menu_bar);
2237 
2238  construct_help_menu (menu_bar);
2239 
2240  construct_news_menu (menu_bar);
2241 
2242 #if defined (HAVE_QSCINTILLA)
2243  // call the editor to add actions which should also be available in the
2244  // editor's menu and tool bar
2245  QList<QAction*> shared_actions;
2246  shared_actions << m_new_script_action
2248  << m_open_action
2250  << m_undo_action
2251  << m_copy_action
2252  << m_paste_action
2254  m_editor_window->insert_global_actions (shared_actions);
2255 #endif
2256  }
2257 
2259  {
2260  QMenu *file_menu = m_add_menu (p, tr ("&File"));
2261 
2262  construct_new_menu (file_menu);
2263 
2266  = file_menu->addAction (rmgr.icon ("document-open"), tr ("Open..."));
2267  m_open_action->setShortcutContext (Qt::ApplicationShortcut);
2268  m_open_action->setToolTip (tr ("Open an existing file in editor"));
2269 
2270 #if defined (HAVE_QSCINTILLA)
2271  file_menu->addMenu (m_editor_window->get_mru_menu ());
2272 #endif
2273 
2274  file_menu->addSeparator ();
2275 
2277  = file_menu->addAction (tr ("Load Workspace..."));
2278 
2280  = file_menu->addAction (tr ("Save Workspace As..."));
2281 
2282  file_menu->addSeparator ();
2283 
2284  m_exit_action = file_menu->addAction (tr ("Exit"));
2285  m_exit_action->setMenuRole (QAction::QuitRole);
2286  m_exit_action->setShortcutContext (Qt::ApplicationShortcut);
2287 
2288  connect (m_open_action, SIGNAL (triggered (void)),
2289  this, SLOT (request_open_file (void)));
2290 
2291  connect (m_load_workspace_action, SIGNAL (triggered (void)),
2292  this, SLOT (handle_load_workspace_request (void)));
2293 
2294  connect (m_save_workspace_action, SIGNAL (triggered (void)),
2295  this, SLOT (handle_save_workspace_request (void)));
2296 
2297  connect (m_exit_action, SIGNAL (triggered (void)),
2298  this, SLOT (close (void)));
2299  }
2300 
2302  {
2303  QMenu *new_menu = p->addMenu (tr ("New"));
2304 
2307  = new_menu->addAction (rmgr.icon ("document-new"), tr ("New Script"));
2308  m_new_script_action->setShortcutContext (Qt::ApplicationShortcut);
2309 
2310  m_new_function_action = new_menu->addAction (tr ("New Function..."));
2311  m_new_function_action->setEnabled (true);
2312  m_new_function_action->setShortcutContext (Qt::ApplicationShortcut);
2313 
2314  m_new_figure_action = new_menu->addAction (tr ("New Figure"));
2315  m_new_figure_action->setEnabled (true);
2316 
2317  connect (m_new_script_action, SIGNAL (triggered (void)),
2318  this, SLOT (request_new_script (void)));
2319 
2320  connect (m_new_function_action, SIGNAL (triggered (void)),
2321  this, SLOT (request_new_function (void)));
2322 
2323  connect (this, SIGNAL (new_file_signal (const QString&)),
2324  m_active_editor, SLOT (request_new_file (const QString&)));
2325 
2326  connect (this, SIGNAL (open_file_signal (const QString&)),
2327  m_active_editor, SLOT (request_open_file (const QString&)));
2328 
2329  connect (this,
2330  SIGNAL (open_file_signal (const QString&, const QString&, int)),
2332  SLOT (request_open_file (const QString&, const QString&, int)));
2333 
2334  connect (m_new_figure_action, SIGNAL (triggered (void)),
2335  this, SLOT (handle_new_figure_request (void)));
2336  }
2337 
2339  {
2340  QMenu *edit_menu = m_add_menu (p, tr ("&Edit"));
2341 
2342  QKeySequence ctrl_shift = Qt::ControlModifier + Qt::ShiftModifier;
2343 
2346  = edit_menu->addAction (rmgr.icon ("edit-undo"), tr ("Undo"));
2347  m_undo_action->setShortcutContext (Qt::ApplicationShortcut);
2348 
2349  edit_menu->addSeparator ();
2350 
2352  = edit_menu->addAction (rmgr.icon ("edit-copy"), tr ("Copy"), this,
2353  SLOT (copyClipboard (void)));
2354  m_copy_action->setShortcutContext (Qt::ApplicationShortcut);
2355 
2357  = edit_menu->addAction (rmgr.icon ("edit-paste"), tr ("Paste"), this,
2358  SLOT (pasteClipboard (void)));
2359  m_paste_action->setShortcutContext (Qt::ApplicationShortcut);
2360 
2362  = edit_menu->addAction (tr ("Select All"), this, SLOT (selectAll (void)));
2363  m_select_all_action->setShortcutContext (Qt::ApplicationShortcut);
2364 
2366  = edit_menu->addAction (tr ("Clear Clipboard"), this,
2367  SLOT (clear_clipboard (void)));
2368 
2369  edit_menu->addSeparator ();
2370 
2372  = edit_menu->addAction (rmgr.icon ("edit-find"), tr ("Find Files..."));
2373 
2374  edit_menu->addSeparator ();
2375 
2377  = edit_menu->addAction (tr ("Clear Command Window"));
2378 
2380  = edit_menu->addAction (tr ("Clear Command History"));
2381 
2383  = edit_menu->addAction (tr ("Clear Workspace"));
2384 
2385  edit_menu->addSeparator ();
2386 
2388  = edit_menu->addAction (tr ("Set Path"));
2389 
2391  = edit_menu->addAction (rmgr.icon ("preferences-system"),
2392  tr ("Preferences..."));
2393 
2394  connect (m_find_files_action, SIGNAL (triggered (void)),
2395  this, SLOT (find_files (void)));
2396 
2397  connect (m_clear_command_window_action, SIGNAL (triggered (void)),
2398  this, SLOT (handle_clear_command_window_request (void)));
2399 
2400  connect (m_clear_command_history_action, SIGNAL (triggered (void)),
2401  this, SLOT (handle_clear_history_request (void)));
2402 
2403  connect (m_clear_workspace_action, SIGNAL (triggered (void)),
2404  this, SLOT (handle_clear_workspace_request (void)));
2405 
2406  connect (m_clipboard, SIGNAL (dataChanged (void)),
2407  this, SLOT (clipboard_has_changed (void)));
2409 #if defined (Q_OS_WIN32)
2410  // Always enable paste action (unreliable clipboard signals in windows)
2411  // FIXME: This has to be removed, when the clipboard signals in windows
2412  // are working again
2413  m_paste_action->setEnabled (true);
2414  m_clear_clipboard_action->setEnabled (true);
2415 #endif
2416 
2417  connect (m_preferences_action, SIGNAL (triggered (void)),
2418  this, SLOT (process_settings_dialog_request (void)));
2419 
2420  connect (m_set_path_action, SIGNAL (triggered (void)),
2421  this, SLOT (handle_set_path_dialog_request (void)));
2422 
2423  }
2424 
2425  QAction * main_window::construct_debug_menu_item (const char *icon,
2426  const QString& item,
2427  const char *member)
2428  {
2430  QAction *action = add_action (m_debug_menu, rmgr.icon (QString (icon)),
2431  item, member);
2432 
2433  action->setEnabled (false);
2434 
2435 #if defined (HAVE_QSCINTILLA)
2436  m_editor_window->debug_menu ()->addAction (action);
2437  m_editor_window->toolbar ()->addAction (action);
2438 #endif
2439 
2440  return action;
2441  }
2442 
2444  {
2445  m_debug_menu = m_add_menu (p, tr ("De&bug"));
2446 
2448  = construct_debug_menu_item ("db-step", tr ("Step"),
2449  SLOT (debug_step_over (void)));
2450 
2452  = construct_debug_menu_item ("db-step-in", tr ("Step In"),
2453  SLOT (debug_step_into (void)));
2454 
2456  = construct_debug_menu_item ("db-step-out", tr ("Step Out"),
2457  SLOT (debug_step_out (void)));
2458 
2460  = construct_debug_menu_item ("db-cont", tr ("Continue"),
2461  SLOT (debug_continue (void)));
2462 
2463  m_debug_menu->addSeparator ();
2464 #if defined (HAVE_QSCINTILLA)
2465  m_editor_window->debug_menu ()->addSeparator ();
2466 #endif
2467 
2468  m_debug_quit
2469  = construct_debug_menu_item ("db-stop", tr ("Quit Debug Mode"),
2470  SLOT (debug_quit (void)));
2471  }
2472 
2473  void main_window::editor_tabs_changed (bool have_tabs)
2474  {
2475  // Set state of actions which depend on the existence of editor tabs
2476  m_editor_has_tabs = have_tabs;
2477  m_debug_step_over->setEnabled (have_tabs);
2478  }
2479 
2481  const QString& item,
2482  bool checkable,
2483  QWidget *widget)
2484  {
2485  QAction *action = p->addAction (QIcon (), item);
2486 
2487  addAction (action); // important for shortcut context
2488  action->setCheckable (checkable);
2489  action->setShortcutContext (Qt::ApplicationShortcut);
2490 
2491  if (widget) // might be zero for m_editor_window
2492  {
2493  if (checkable)
2494  {
2495  // action for visibility of dock widget
2496  connect (action, SIGNAL (toggled (bool)),
2497  widget, SLOT (setVisible (bool)));
2498 
2499  connect (widget, SIGNAL (active_changed (bool)),
2500  action, SLOT (setChecked (bool)));
2501  }
2502  else
2503  {
2504  // action for focus of dock widget
2505  connect (action, SIGNAL (triggered (void)), widget, SLOT (activate (void)));
2506  }
2507  }
2508  else
2509  {
2510  action->setEnabled (false);
2511  }
2512 
2513  return action;
2514  }
2515 
2517  {
2518  QMenu *window_menu = m_add_menu (p, tr ("&Window"));
2519 
2521  (window_menu, tr ("Show Command Window"), true, m_command_window);
2522 
2524  (window_menu, tr ("Show Command History"), true, m_history_window);
2525 
2527  (window_menu, tr ("Show File Browser"), true, m_file_browser_window);
2528 
2530  (window_menu, tr ("Show Workspace"), true, m_workspace_window);
2531 
2533  (window_menu, tr ("Show Editor"), true, m_editor_window);
2534 
2536  (window_menu, tr ("Show Documentation"), true, m_doc_browser_window);
2537 
2539  (window_menu, tr ("Show Variable Editor"), true, m_variable_editor_window);
2540 
2541  window_menu->addSeparator ();
2542 
2544  (window_menu, tr ("Command Window"), false, m_command_window);
2545 
2547  (window_menu, tr ("Command History"), false, m_history_window);
2548 
2550  (window_menu, tr ("File Browser"), false, m_file_browser_window);
2551 
2553  (window_menu, tr ("Workspace"), false, m_workspace_window);
2554 
2556  (window_menu, tr ("Editor"), false, m_editor_window);
2557 
2559  (window_menu, tr ("Documentation"), false, m_doc_browser_window);
2560 
2562  (window_menu, tr ("Variable Editor"), false, m_variable_editor_window);
2563 
2564  window_menu->addSeparator ();
2565 
2566  m_previous_dock_action = add_action (window_menu, QIcon (),
2567  tr ("Previous Widget"), SLOT (go_to_previous_widget (void)));
2568 
2569  window_menu->addSeparator ();
2570 
2571  m_reset_windows_action = add_action (window_menu, QIcon (),
2572  tr ("Reset Default Window Layout"), SLOT (reset_windows (void)));
2573  }
2574 
2576  {
2577  QMenu *help_menu = m_add_menu (p, tr ("&Help"));
2578 
2579  construct_documentation_menu (help_menu);
2580 
2581  help_menu->addSeparator ();
2582 
2583  m_report_bug_action = add_action (help_menu, QIcon (),
2584  tr ("Report Bug"), SLOT (open_bug_tracker_page ()));
2585 
2586  m_octave_packages_action = add_action (help_menu, QIcon (),
2587  tr ("Octave Packages"), SLOT (open_octave_packages_page ()));
2588 
2589  m_contribute_action = add_action (help_menu, QIcon (),
2590  tr ("Contribute"), SLOT (open_contribute_page ()));
2591 
2592  m_developer_action = add_action (help_menu, QIcon (),
2593  tr ("Donate to Octave"), SLOT (open_donate_page ()));
2594 
2595  help_menu->addSeparator ();
2596 
2597  m_about_octave_action = add_action (help_menu, QIcon (),
2598  tr ("About Octave"), SLOT (show_about_octave ()));
2599  }
2600 
2602  {
2603  QMenu *doc_menu = p->addMenu (tr ("Documentation"));
2604 
2605  m_ondisk_doc_action = add_action (doc_menu, QIcon (),
2606  tr ("On Disk"), SLOT (activate ()), m_doc_browser_window);
2607 
2608  m_online_doc_action = add_action (doc_menu, QIcon (),
2609  tr ("Online"), SLOT (open_online_documentation_page ()));
2610  }
2611 
2613  {
2614  QMenu *news_menu = m_add_menu (p, tr ("&News"));
2615 
2616  m_release_notes_action = add_action (news_menu, QIcon (),
2617  tr ("Release Notes"), SLOT (display_release_notes ()));
2618 
2619  m_current_news_action = add_action (news_menu, QIcon (),
2620  tr ("Community News"), SLOT (load_and_display_community_news ()));
2621  }
2622 
2624  {
2625  m_main_tool_bar = addToolBar (tr ("Toolbar"));
2626  m_main_tool_bar->setStyleSheet (m_main_tool_bar->styleSheet ()
2628 
2629  m_main_tool_bar->setObjectName ("MainToolBar");
2630  m_main_tool_bar->addAction (m_new_script_action);
2631  m_main_tool_bar->addAction (m_open_action);
2632 
2633  m_main_tool_bar->addSeparator ();
2634 
2635  m_main_tool_bar->addAction (m_copy_action);
2636  m_main_tool_bar->addAction (m_paste_action);
2637  m_main_tool_bar->addAction (m_undo_action);
2638 
2639  m_main_tool_bar->addSeparator ();
2640 
2641  m_current_directory_combo_box = new QComboBox (this);
2642  QFontMetrics fm = m_current_directory_combo_box->fontMetrics ();
2643  m_current_directory_combo_box->setFixedWidth (48*fm.averageCharWidth ());
2644  m_current_directory_combo_box->setEditable (true);
2645  m_current_directory_combo_box->setInsertPolicy (QComboBox::NoInsert);
2646  m_current_directory_combo_box->setToolTip (tr ("Enter directory name"));
2649  QSizePolicy sizePol (QSizePolicy::Preferred, QSizePolicy::Preferred);
2650  m_current_directory_combo_box->setSizePolicy (sizePol);
2651 
2652  // addWidget takes ownership of the objects so there is no
2653  // need to delete these upon destroying this main_window.
2654  m_main_tool_bar->addWidget (new QLabel (tr ("Current Directory: ")));
2657  QAction *current_dir_up
2658  = m_main_tool_bar->addAction (rmgr.icon ("go-up"),
2659  tr ("One directory up"));
2660  QAction *current_dir_search
2661  = m_main_tool_bar->addAction (rmgr.icon ("folder"),
2662  tr ("Browse directories"));
2663 
2664  connect (m_current_directory_combo_box, SIGNAL (activated (QString)),
2665  this, SLOT (set_current_working_directory (QString)));
2666 
2667  connect (m_current_directory_combo_box->lineEdit (), SIGNAL (returnPressed (void)),
2668  this, SLOT (accept_directory_line_edit (void)));
2669 
2670  connect (current_dir_search, SIGNAL (triggered (void)),
2671  this, SLOT (browse_for_directory (void)));
2672 
2673  connect (current_dir_up, SIGNAL (triggered (void)),
2674  this, SLOT (change_directory_up (void)));
2675 
2676  connect (m_undo_action, SIGNAL (triggered (void)),
2677  this, SLOT (handle_undo_request (void)));
2678  }
2679 
2681  {
2683  gui_settings *settings = rmgr.get_settings ();
2684  if (settings->value (cs_focus_cmd).toBool ())
2686  }
2687 
2689  {
2691 
2692  // file menu
2700 
2701  // edit menu
2713 
2714  // debug menu
2720 
2721  // window menu
2738 
2739  // help menu
2747 
2748  // news menu
2751  }
2752 
2754  {
2756  list.append (static_cast<octave_dock_widget *> (m_command_window));
2757  list.append (static_cast<octave_dock_widget *> (m_history_window));
2758  list.append (static_cast<octave_dock_widget *> (m_file_browser_window));
2759  list.append (static_cast<octave_dock_widget *> (m_doc_browser_window));
2760 #if defined (HAVE_QSCINTILLA)
2761  list.append (static_cast<octave_dock_widget *> (m_editor_window));
2762 #endif
2763  list.append (static_cast<octave_dock_widget *> (m_workspace_window));
2764  list.append (static_cast<octave_dock_widget *> (m_variable_editor_window));
2765  return list;
2766  }
2767 
2768  void main_window::update_default_encoding (const QString& default_encoding)
2769  {
2770  m_default_encoding = default_encoding;
2771  std::string mfile_encoding = m_default_encoding.toStdString ();
2772  if (m_default_encoding.startsWith ("SYSTEM", Qt::CaseInsensitive))
2773  mfile_encoding = "SYSTEM";
2774 
2775  emit interpreter_event
2776  ([mfile_encoding] (interpreter& interp)
2777  {
2778  // INTERPRETER THREAD
2779 
2780  F__mfile_encoding__ (interp, ovl (mfile_encoding));
2781  });
2782  }
2783 
2784  // Get size of screen where the main window is located
2785  void main_window::get_screen_geometry (int *width, int *height)
2786  {
2787  QRect screen_geometry
2788  = QApplication::desktop ()->availableGeometry (this);
2789 
2790  *width = screen_geometry.width ();
2791  *height = screen_geometry.height ();
2792  }
2793 
2794  void main_window::resize_dock (QDockWidget *dw, int width, int height)
2795  {
2796 #if defined (HAVE_QMAINWINDOW_RESIZEDOCKS)
2797  // resizeDockWidget was added to Qt in Qt 5.6
2798  if (width >= 0)
2799  resizeDocks ({dw},{width},Qt::Horizontal);
2800  if (height >= 0)
2801  resizeDocks ({dw},{height},Qt::Vertical);
2802 #else
2803  // This replacement of resizeDockWidget is not very reliable.
2804  // But even if Qt4 is not yet
2805  QSize s = dw->widget ()->size ();
2806  if (width >= 0)
2807  s.setWidth (width);
2808  if (height >= 0)
2809  s.setHeight (height);
2810  dw->widget ()->resize (s);
2811  dw->adjustSize ();
2812 #endif
2813  }
2814 
2815  // The default main window size relative to the desktop size
2817  {
2818  int win_x, win_y;
2819  get_screen_geometry (&win_x, &win_y);
2820 
2821  move (0, 0);
2822  resize (2*win_x/3, 7*win_y/8);
2823  }
2824 
2826  {
2827  // Slot for resetting the window layout to the default one
2828  hide ();
2829  showNormal (); // Unmaximize
2830  do_reset_windows (false); // Add all widgets
2831  // Re-add after giving time: This seems to be a reliable way to
2832  // reset the main window's layout
2833  QTimer::singleShot (250, this, SLOT (do_reset_windows (void)));
2834  }
2835 
2836  // Create the default layout of the main window. Do not use
2837  // restoreState () and restoreGeometry () with default values since
2838  // this might lead to problems when the Qt version changes
2839  void main_window::do_reset_windows (bool show_it)
2840  {
2841  // Set main window default geometry and store its width for
2842  // later resizing the command window
2844  int win_x = geometry ().width ();
2845 
2846  // Resize command window, the important one in the default layout
2847  resize_dock (m_command_window, 7*win_x/8, -1);
2848 
2849  // See Octave bug #53409 and https://bugreports.qt.io/browse/QTBUG-55357
2850 #if (QT_VERSION < 0x050601) || (QT_VERSION >= 0x050701)
2851  setDockOptions (QMainWindow::AnimatedDocks
2852  | QMainWindow::AllowNestedDocks
2853  | QMainWindow::AllowTabbedDocks);
2854 #else
2855  setDockNestingEnabled (true);
2856 #endif
2857 
2858  // Add the dock widgets and show them
2859  addDockWidget (Qt::LeftDockWidgetArea, m_file_browser_window);
2860  addDockWidget (Qt::LeftDockWidgetArea, m_workspace_window);
2861  addDockWidget (Qt::LeftDockWidgetArea, m_history_window);
2862 
2863  addDockWidget (Qt::RightDockWidgetArea, m_command_window);
2864 
2865  addDockWidget (Qt::RightDockWidgetArea, m_doc_browser_window);
2866  tabifyDockWidget (m_command_window, m_doc_browser_window);
2867 
2868  addDockWidget (Qt::RightDockWidgetArea, m_variable_editor_window);
2869  tabifyDockWidget (m_command_window, m_variable_editor_window);
2870 
2871 #if defined (HAVE_QSCINTILLA)
2872  addDockWidget (Qt::RightDockWidgetArea, m_editor_window);
2873  tabifyDockWidget (m_command_window, m_editor_window);
2874 #endif
2875 
2876  // Resize command window, the important one in the default layout
2877  resize_dock (m_command_window, 2*win_x/3, -1);
2878 
2879  // Show main wibdow, save state and geometry of main window and
2880  // all dock widgets
2881  if (show_it)
2882  {
2883  // Show all dock widgets
2884  for (auto *widget : dock_widget_list ())
2885  widget->show ();
2886 
2887  // Show main window and store size and state
2888  showNormal ();
2889 
2891  gui_settings *settings = rmgr.get_settings ();
2892 
2893  settings->setValue (mw_geometry.key, saveGeometry ());
2894  settings->setValue (mw_state.key, saveState ());
2895 
2897  }
2898  }
2899 }
Base class for Octave interfaces that use Qt.
interpreter_qobject * interpreter_qobj(void)
resource_manager & get_resource_manager(void)
QApplication * qapplication(void)
shortcut_manager & get_shortcut_manager(void)
void config_translators(void)
static bool interrupt(bool=true)
Definition: cmd-edit.cc:1616
static void clear_screen(bool skip_redisplay=false)
Definition: cmd-edit.cc:1248
static void replace_line(const std::string &text, bool clear_undo=true)
Definition: cmd-edit.cc:1452
static bool undo(void)
Definition: cmd-edit.cc:1487
static void set_screen_size(int ht, int wd)
Definition: cmd-edit.cc:1262
static void set_initial_input(const std::string &text)
Definition: cmd-edit.cc:1104
static void kill_full_line(void)
Definition: cmd-edit.cc:1459
static std::string get_current_line(void)
Definition: cmd-edit.cc:1438
static void accept_line(void)
Definition: cmd-edit.cc:1480
static void interrupt_event_loop(bool flag=true)
Definition: cmd-edit.cc:1636
static void redisplay(void)
Definition: cmd-edit.cc:1229
Provides threadsafe access to octave.
virtual QMenu * debug_menu(void)=0
virtual bool check_closing(void)=0
virtual QToolBar * toolbar(void)=0
virtual void enable_menu_shortcuts(bool enable)=0
virtual void empty_script(bool, bool)=0
virtual void handle_enter_debug_mode(void)=0
virtual QMenu * get_mru_menu(void)=0
virtual void restore_session(gui_settings *)=0
virtual void handle_file_remove(const QString &o, const QString &n)=0
virtual void insert_global_actions(QList< QAction * >)=0
virtual void handle_exit_debug_mode(void)=0
Dock widget to display files in the current directory.
void set_search_dir(const QString &dir)
string_vector do_history(const octave_value_list &args=octave_value_list(), int nargout=0)
Definition: oct-hist.cc:325
qt_interpreter_events * qt_link(void)
octave_value_list feval(const char *name, const octave_value_list &args=octave_value_list(), int nargout=0)
Evaluate an Octave function (built-in or interpreted) and return the list of result values.
history_system & get_history_system(void)
Definition: interpreter.h:233
int chdir(const std::string &dir)
symbol_scope get_current_scope(void) const
void quit(int exit_status, bool force=false, bool confirm=true)
event_manager & get_event_manager(void)
Definition: interpreter.h:290
tree_evaluator & get_evaluator(void)
void debug_step_over(void)
QAction * m_reset_windows_action
Definition: main-window.h:382
bool command_window_has_focus(void) const
Definition: main-window.cc:262
void construct_edit_menu(QMenuBar *p)
void handle_update_breakpoint_marker_request(bool insert, const QString &file, int line, const QString &cond)
QAction * m_save_workspace_action
Definition: main-window.h:352
void construct_window_menu(QMenuBar *p)
void change_directory_up(void)
void warning_function_not_found(const QString &message)
QAction * m_new_function_action
Definition: main-window.h:348
void file_remove_proxy(const QString &o, const QString &n)
Definition: main-window.cc:601
octave_dock_widget * m_previous_dock
Definition: main-window.h:332
QAction * m_ondisk_doc_action
Definition: main-window.h:384
bool m_prevent_readline_conflicts
Some class global flags.
Definition: main-window.h:424
static const int current_directory_max_count
For Toolbars.
Definition: main-window.h:399
external_editor_interface * m_external_editor
Definition: main-window.h:329
QAction * m_release_notes_action
Definition: main-window.h:392
QAction * m_show_workspace_action
Definition: main-window.h:369
QAction * m_documentation_action
Definition: main-window.h:379
QAction * m_copy_action
Definition: main-window.h:357
void construct_help_menu(QMenuBar *p)
QAction * m_octave_packages_action
Definition: main-window.h:387
void handle_exit_debugger(void)
QAction * m_clear_clipboard_action
Definition: main-window.h:359
void report_status_message(const QString &statusMessage)
Definition: main-window.cc:387
QAction * m_show_variable_editor_action
Definition: main-window.h:373
void settings_changed(const gui_settings *)
QStatusBar * m_status_bar
Toolbar.
Definition: main-window.h:316
void notice_settings(const gui_settings *settings, bool update_by_worker=false)
Definition: main-window.cc:827
void undo_signal(void)
octave_dock_widget * m_active_dock
Definition: main-window.h:333
QAction * m_show_file_browser_action
Definition: main-window.h:370
void set_window_layout(gui_settings *settings)
QAction * m_about_octave_action
Definition: main-window.h:390
void do_reset_windows(bool show_it=true)
QPointer< set_path_dialog > m_set_path_dlg
Set path dialog.
Definition: main-window.h:412
void handle_clear_command_window_request(void)
Definition: main-window.cc:485
QAction * m_previous_dock_action
Definition: main-window.h:381
QPointer< settings_dialog > m_settings_dlg
Settings dialog as guarded pointer (set to 0 when deleted).
Definition: main-window.h:405
QAction * m_editor_action
Definition: main-window.h:378
void handle_save_workspace_request(void)
Definition: main-window.cc:392
void handle_clear_workspace_request(void)
Definition: main-window.cc:474
void set_current_working_directory(const QString &dir)
Definition: main-window.cc:995
QString m_release_notes_icon
Definition: main-window.h:335
bool m_suppress_dbg_location
Some class global flags.
Definition: main-window.h:425
find_files_dialog * m_find_files_dlg
Find files dialog.
Definition: main-window.h:409
history_dock_widget * m_history_window
Dock widgets.
Definition: main-window.h:321
void construct_tool_bar(void)
void find_files_finished(int)
Find files dialog.
Definition: main-window.h:221
void construct_documentation_menu(QMenu *p)
void new_file(const QString &commands=QString())
Definition: main-window.cc:583
void handle_open_any_request(const QString &file=QString())
Definition: main-window.cc:450
QAction * m_history_action
Definition: main-window.h:375
void clear_clipboard()
Handling the clipboard.
void focus_command_window(void)
Definition: main-window.cc:267
QAction * m_developer_action
Definition: main-window.h:389
static const int current_directory_max_visible
For Toolbars.
Definition: main-window.h:398
QAction * m_select_all_action
Definition: main-window.h:365
QAction * m_command_window_action
Definition: main-window.h:374
void construct_debug_menu(QMenuBar *p)
void load_and_display_community_news(int serial=-1)
Definition: main-window.cc:690
void init_terminal_size(void)
void handle_clear_history_request(void)
Definition: main-window.cc:497
void show_doc_signal(const QString &)
void handle_show_doc(const QString &file)
QAction * m_preferences_action
Definition: main-window.h:354
workspace_model * m_workspace_model
Definition: main-window.h:306
void run_file_in_terminal(const QFileInfo &info)
void handle_rename_variable_request(const QString &old_name, const QString &new_name)
Definition: main-window.cc:527
void accept_directory_line_edit(void)
void handle_set_path_dialog_request(void)
void focus_console_after_command(void)
terminal_dock_widget * m_command_window
Dock widgets.
Definition: main-window.h:320
QAction * m_find_files_action
Definition: main-window.h:364
void modify_path(const octave_value_list &dir_list, bool rm, bool subdirs)
Definition: main-window.cc:557
QAction * m_debug_step_out
Definition: main-window.h:344
void focus_changed(QWidget *w_old, QWidget *w_new)
Definition: main-window.cc:313
void write_settings(void)
void construct_central_widget(void)
void request_open_file(void)
workspace_view * m_workspace_window
Dock widgets.
Definition: main-window.h:325
QClipboard * m_clipboard
Definition: main-window.h:420
void editor_focus_changed(bool)
QAction * m_undo_action
Definition: main-window.h:360
QToolBar * m_main_tool_bar
Definition: main-window.h:337
void interpreter_event(const fcn_callback &fcn)
void warning_function_not_found_signal(const QString &message)
void request_new_function(bool triggered=true)
documentation_dock_widget * m_doc_browser_window
Dock widgets.
Definition: main-window.h:323
QAction * m_show_documentation_action
Definition: main-window.h:372
QAction * m_open_action
Definition: main-window.h:349
void open_bug_tracker_page(void)
Definition: main-window.cc:778
void request_new_script(const QString &commands=QString())
QAction * m_clear_command_window_action
Definition: main-window.h:361
void new_file_signal(const QString &)
QAction * m_contribute_action
Definition: main-window.h:388
void set_default_geometry(void)
void disable_menu_shortcuts(bool disable)
void handle_edit_mfile_request(const QString &name, const QString &file, const QString &curr_dir, int line)
bool confirm_shutdown(void)
Definition: main-window.cc:284
QAction * m_paste_action
Definition: main-window.h:358
main_window(base_qobject &oct_qobj)
Definition: main-window.cc:110
QAction * m_show_history_action
Definition: main-window.h:368
QAction * m_show_command_window_action
Definition: main-window.h:367
void handle_insert_debugger_pointer_request(const QString &file, int line)
void handle_unregister_doc(const QString &file)
QComboBox * m_current_directory_combo_box
For Toolbars.
Definition: main-window.h:397
void refresh_variable_editor(void)
void display_release_notes(void)
Definition: main-window.cc:629
QAction * m_online_doc_action
Definition: main-window.h:385
void editor_tabs_changed(bool)
void active_dock_changed(octave_dock_widget *, octave_dock_widget *)
file_editor_interface * m_editor_window
Dock widgets.
Definition: main-window.h:324
QAction * construct_debug_menu_item(const char *icon, const QString &item, const char *member)
void handle_register_doc(const QString &file)
void browse_for_directory(void)
Definition: main-window.cc:974
void update_default_encoding(const QString &default_encoding)
QAction * m_variable_editor_action
Definition: main-window.h:380
QAction * m_clear_workspace_action
Definition: main-window.h:363
void read_settings(void)
QHash< QMenu *, QStringList > m_hash_menu_text
Definition: main-window.h:308
void handle_new_figure_request(void)
void construct_file_menu(QMenuBar *p)
void open_octave_packages_page(void)
Definition: main-window.cc:783
QAction * m_file_browser_action
Definition: main-window.h:377
void open_file(const QString &file_name=QString(), int line=-1)
Definition: main-window.cc:588
void open_contribute_page(void)
Definition: main-window.cc:788
void pasteClipboard(void)
void construct_news_menu(QMenuBar *p)
void focus_window(const QString &win_name)
Definition: main-window.cc:272
QAction * m_debug_step_over
Definition: main-window.h:343
void update_breakpoint_marker_signal(bool insert, const QString &file, int line, const QString &cond)
QList< octave_dock_widget * > dock_widget_list(void)
QAction * m_load_workspace_action
Definition: main-window.h:351
variable_editor * m_variable_editor_window
Dock widgets.
Definition: main-window.h:326
void debug_step_into(void)
void edit_mfile(const QString &, int)
Definition: main-window.cc:596
QString m_default_encoding
Definition: main-window.h:310
void step_into_file_signal(void)
QAction * m_clear_command_history_action
Definition: main-window.h:362
void handle_enter_debugger(void)
void register_doc_signal(const QString &)
void set_file_encoding(const QString &new_encoding)
QAction * m_new_figure_action
Definition: main-window.h:350
QAction * m_report_bug_action
Definition: main-window.h:386
QWidget * m_release_notes_window
Release notes window.
Definition: main-window.h:416
void construct_new_menu(QMenu *p)
void handle_variable_editor_update(void)
QAction * m_debug_continue
Definition: main-window.h:341
void configure_shortcuts(void)
void clipboard_has_changed(void)
Handling the clipboard.
void debug_continue(void)
QAction * m_exit_action
Definition: main-window.h:355
base_qobject & m_octave_qobj
Definition: main-window.h:304
void pasteClipboard_signal(void)
QAction * add_action(QMenu *menu, const QIcon &icon, const QString &text, const char *member, const QWidget *receiver=nullptr)
QAction * m_current_news_action
Definition: main-window.h:393
files_dock_widget * m_file_browser_window
Dock widgets.
Definition: main-window.h:322
QAction * m_set_path_action
Definition: main-window.h:353
void execute_command_in_terminal(const QString &dir)
void display_community_news(const QString &news)
Definition: main-window.cc:726
void handle_delete_debugger_pointer_request(const QString &file, int line)
void find_files(const QString &startdir=QDir::currentPath())
Find files dialog.
QAction * m_show_editor_action
Definition: main-window.h:371
void get_screen_geometry(int *width, int *height)
void resize_dock(QDockWidget *dw, int width, int height)
QWidget * m_active_editor
Definition: main-window.h:330
void reset_windows(void)
QWidget * m_community_news_window
Definition: main-window.h:418
void connect_visibility_changed(void)
void selectAll_signal(void)
QAction * m_new_script_action
Definition: main-window.h:347
void insert_debugger_pointer_signal(const QString &file, int line)
void show_about_octave(void)
Definition: main-window.cc:818
void copyClipboard(void)
void handle_load_workspace_request(const QString &file=QString())
Definition: main-window.cc:417
void request_reload_settings(void)
Definition: main-window.cc:378
void restore_create_file_setting(void)
void construct_octave_qt_link(void)
void open_donate_page(void)
Definition: main-window.cc:793
void update_octave_directory(const QString &dir)
Definition: main-window.cc:959
void handle_undo_request(void)
Definition: main-window.cc:510
bool m_editor_has_tabs
Some class global flags.
Definition: main-window.h:426
void request_open_files(const QStringList &open_file_names)
void closeEvent(QCloseEvent *closeEvent)
void set_screen_size(int ht, int wd)
void process_settings_dialog_request(const QString &desired_tab=QString())
Definition: main-window.cc:798
void open_online_documentation_page(void)
Definition: main-window.cc:623
void delete_debugger_pointer_signal(const QString &file, int line)
void copyClipboard_signal(void)
void debug_step_out(void)
void edit_variable(const QString &name, const octave_value &)
Opens the variable editor for name.
void unregister_doc_signal(const QString &)
void prepare_to_exit(void)
Definition: main-window.cc:940
void construct_menu_bar(void)
QAction * m_debug_quit
Definition: main-window.h:345
void go_to_previous_widget(void)
Definition: main-window.cc:954
void set_global_shortcuts(bool enable)
Setting global shortcuts.
void init_terminal_size_signal(void)
void open_file_signal(const QString &)
QAction * m_debug_step_into
Definition: main-window.h:342
QAction * m_workspace_action
Definition: main-window.h:376
QMenu * m_add_menu(QMenuBar *p, QString text)
QAction * construct_window_menu_item(QMenu *p, const QString &item, bool checkable, QWidget *)
void set_predecessor_widget(octave_dock_widget *prev_widget)
gui_settings * get_settings(void) const
bool is_first_run(void) const
QIcon icon(const QString &icon_name, bool fallback=true)
void set_shortcut(QAction *action, const sc_pref &scpref)
void rename(const std::string &old_name, const std::string &new_name)
Definition: symscope.h:498
static void putenv(const std::string &name, const std::string &value)
Definition: oct-env.cc:278
symbol_info_list get_symbol_info(void)
Definition: pt-eval.cc:3651
void edit_variable(const QString &name, const octave_value &val)
void setModel(workspace_model *model)
octave_value_list & append(const octave_value &val)
Definition: ovl.cc:98
octave_idx_type length(void) const
Definition: ovl.h:113
OCTAVE_EXPORT octave_value_list Fdbstep(octave::interpreter &interp, const octave_value_list &args, int)
Definition: debug.cc:1077
OCTAVE_EXPORT octave_value_list Fdbcont(octave::interpreter &interp, const octave_value_list &args, int)
Definition: debug.cc:1130
OCTAVE_EXPORT octave_value_list F__db_next_breakpoint_quiet__(octave::interpreter &interp, const octave_value_list &args, int)
Definition: debug.cc:1203
OCTAVE_EXPORT octave_value_list Fdbquit(octave::interpreter &interp, const octave_value_list &args, int)
Definition: debug.cc:1153
void message(const char *name, const char *fmt,...)
Definition: error.cc:936
OCTAVE_EXPORT octave_value_list Fdrawnow(octave::interpreter &interp, const octave_value_list &args, int)
Definition: graphics.cc:13698
const gui_pref cs_focus_cmd("terminal/focus_after_command", QVariant(false))
const gui_pref cs_dbg_location("terminal/print_debug_location", QVariant(false))
const gui_pref cs_cursor_blinking("terminal/cursorBlinking", QVariant(true))
const struct @24 dw_icon_set_names[]
const gui_pref dw_is_floating("DockWidgets/%1Floating", QVariant(false))
const gui_pref dw_is_visible("DockWidgets/%1Visible", QVariant(true))
const gui_pref dw_is_minimized("DockWidgets/%1_minimized", QVariant(false))
QString name
const gui_pref dw_icon_set("DockWidgets/widget_icon_set", QVariant("NONE"))
const gui_pref ed_create_new_file("editor/create_new_file", QVariant(false))
const gui_pref ed_default_enc("editor/default_encoding", QVariant(QString("SYSTEM (")+QString(octave_locale_charset_wrapper()).toUpper()+QString(")")))
const gui_pref global_restore_ov_dir("restore_octave_dir", QVariant(false))
const gui_pref global_status_bar("show_status_bar", QVariant(true))
const QStyle::PixelMetric global_icon_sizes[3]
const gui_pref global_prompt_to_exit("prompt_to_exit", QVariant(false))
const gui_pref global_use_native_dialogs("use_native_file_dialogs", QVariant(true))
const QString global_toolbar_style("QToolBar {" "spacing-top: 0px;" "spacing-bottom: 0px;" "margin-top: 0px;" "margin-bottom: 0px;" "padding-top: 0px;" "padding-bottom: 0px;" "border-top: 0px;" "border-bottom: 0px;" "}")
const gui_pref global_use_custom_editor("useCustomFileEditor", QVariant(false))
const gui_pref global_ov_startup_dir("octave_startup_dir", QVariant(QString()))
const gui_pref global_icon_size("toolbar_icon_size", QVariant(0))
const gui_pref global_cursor_blinking("cursor_blinking", QVariant(true))
const gui_pref global_style("style", QVariant("default"))
const gui_pref mw_dir_list("MainWindow/current_directory_list", QVariant(QStringList()))
const gui_pref mw_geometry("MainWindow/geometry", QVariant(QByteArray()))
const gui_pref mw_state("MainWindow/windowState", QVariant(QByteArray()))
const gui_pref nr_allow_connection("news/allow_web_connection", QVariant(false))
const gui_pref nr_last_news("news/last_news_item", QVariant(0))
const gui_pref nr_last_time("news/last_time_checked", QVariant(QDateTime()))
const sc_pref sc_main_help_online_doc(sc_main_help+":online_doc", QKeySequence::UnknownKey)
const sc_pref sc_main_file_exit(sc_main_file+":exit", QKeySequence::Quit)
const sc_pref sc_main_file_new_file(sc_main_file+":new_file", QKeySequence::New)
const sc_pref sc_main_news_release_notes(sc_main_news+":release_notes", QKeySequence::UnknownKey)
const sc_pref sc_main_window_workspace(sc_main_window+":workspace", PRE+CTRL+Qt::Key_3)
const sc_pref sc_main_file_new_figure(sc_main_file+":new_figure", QKeySequence::UnknownKey)
const sc_pref sc_main_window_doc(sc_main_window+":doc", PRE+CTRL+Qt::Key_5)
const sc_pref sc_main_debug_step_over(sc_main_debug+":step_over", PRE+Qt::Key_F10)
const sc_pref sc_main_window_show_editor(sc_main_window+":show_editor", PRE+CTRL_SHIFT+Qt::Key_4)
const sc_pref sc_main_edit_set_path(sc_main_edit+":set_path", QKeySequence::UnknownKey)
const gui_pref sc_prevent_rl_conflicts("shortcuts/prevent_readline_conflicts", QVariant(true))
const sc_pref sc_main_window_file_browser(sc_main_window+":file_browser", PRE+CTRL+Qt::Key_2)
const sc_pref sc_main_debug_continue(sc_main_debug+":continue", PRE+Qt::Key_F5)
const sc_pref sc_main_edit_clear_clipboard(sc_main_edit+":clear_clipboard", QKeySequence::UnknownKey)
const sc_pref sc_main_window_show_history(sc_main_window+":show_history", PRE+CTRL_SHIFT+Qt::Key_1)
const sc_pref sc_main_window_show_workspace(sc_main_window+":show_workspace", PRE+CTRL_SHIFT+Qt::Key_3)
const sc_pref sc_main_edit_clear_workspace(sc_main_edit+":clear_workspace", QKeySequence::UnknownKey)
const sc_pref sc_main_file_open_file(sc_main_file+":open_file", QKeySequence::Open)
const sc_pref sc_main_window_show_doc(sc_main_window+":show_doc", PRE+CTRL_SHIFT+Qt::Key_5)
const sc_pref sc_main_file_new_function(sc_main_file+":new_function", CTRL_SHIFT+Qt::Key_N)
const sc_pref sc_main_debug_step_into(sc_main_debug+":step_into", PRE+Qt::Key_F11)
const sc_pref sc_main_help_about(sc_main_help+":about", QKeySequence::UnknownKey)
const sc_pref sc_main_window_show_variable_editor(sc_main_window+":show_variable_editor", PRE+CTRL_SHIFT+Qt::Key_6)
const sc_pref sc_main_window_show_command(sc_main_window+":show_command", PRE+CTRL_SHIFT+Qt::Key_0)
const sc_pref sc_main_window_editor(sc_main_window+":editor", PRE+CTRL+Qt::Key_4)
const sc_pref sc_main_window_variable_editor(sc_main_window+":variable_editor", PRE+CTRL+Qt::Key_6)
const sc_pref sc_main_window_command(sc_main_window+":command", PRE+CTRL+Qt::Key_0)
const sc_pref sc_main_debug_quit(sc_main_debug+":quit", PRE+Qt::ShiftModifier+Qt::Key_F5)
const sc_pref sc_main_edit_copy(sc_main_edit+":copy", QKeySequence::Copy)
const sc_pref sc_main_help_ondisk_doc(sc_main_help+":ondisk_doc", QKeySequence::UnknownKey)
const sc_pref sc_main_help_developer(sc_main_help+":developer", QKeySequence::UnknownKey)
const sc_pref sc_main_edit_undo(sc_main_edit+":undo", QKeySequence::Undo)
const sc_pref sc_main_edit_clear_command_window(sc_main_edit+":clear_command_window", QKeySequence::UnknownKey)
const sc_pref sc_main_window_reset(sc_main_window+":reset", QKeySequence::UnknownKey)
const sc_pref sc_main_window_previous_dock(sc_main_window+":previous_widget", PRE+CTRL_ALT+Qt::Key_P)
const sc_pref sc_main_help_contribute(sc_main_help+":contribute", QKeySequence::UnknownKey)
const sc_pref sc_main_window_history(sc_main_window+":history", PRE+CTRL+Qt::Key_1)
const sc_pref sc_main_edit_preferences(sc_main_edit+":preferences", QKeySequence::UnknownKey)
const sc_pref sc_main_help_packages(sc_main_help+":packages", QKeySequence::UnknownKey)
const sc_pref sc_main_file_save_workspace(sc_main_file+":save_workspace", QKeySequence::UnknownKey)
const sc_pref sc_main_edit_paste(sc_main_edit+":paste", QKeySequence::Paste)
const sc_pref sc_main_edit_find_in_files(sc_main_edit+":find_in_files", CTRL_SHIFT+Qt::Key_F)
const sc_pref sc_main_edit_select_all(sc_main_edit+":select_all", QKeySequence::SelectAll)
const sc_pref sc_main_window_show_file_browser(sc_main_window+":show_file_browser", PRE+CTRL_SHIFT+Qt::Key_2)
const sc_pref sc_main_edit_clear_history(sc_main_edit+":clear_history", QKeySequence::UnknownKey)
const sc_pref sc_main_debug_step_out(sc_main_debug+":step_out", PRE+Qt::ShiftModifier+Qt::Key_F11)
const sc_pref sc_main_news_community_news(sc_main_news+":community_news", QKeySequence::UnknownKey)
const sc_pref sc_main_help_report_bug(sc_main_help+":report_bug", QKeySequence::UnknownKey)
const sc_pref sc_main_file_load_workspace(sc_main_file+":load_workspace", QKeySequence::UnknownKey)
OCTAVE_EXPORT octave_value_list Fgenpath(const octave_value_list &args, int)
Definition: load-path.cc:2340
OCTAVE_EXPORT octave_value_list Faddpath(octave::interpreter &interp, const octave_value_list &args, int nargout)
Definition: load-path.cc:2516
OCTAVE_EXPORT octave_value_list Frmpath(octave::interpreter &interp, const octave_value_list &args, int nargout)
Definition: load-path.cc:2643
OCTAVE_EXPORT octave_value_list Fsave(octave::interpreter &interp, const octave_value_list &args, int nargout)
Definition: load-save.cc:1808
OCTAVE_EXPORT octave_value_list Fload(octave::interpreter &interp, const octave_value_list &args, int nargout)
Definition: load-save.cc:1654
octave_idx_type n
Definition: mx-inlines.cc:753
std::complex< double > w(std::complex< double > z, double relerr=0)
QString fromStdString(const std::string &s)
std::string oct_etc_dir(void)
Definition: defaults.cc:339
bool valid_identifier(const char *s)
Definition: utils.cc:77
std::function< void(octave::interpreter &)> meth_callback
Definition: event-manager.h:47
std::function< void(void)> fcn_callback
Definition: event-manager.h:46
static file_editor_interface * create_default_editor(QWidget *p, base_qobject &oct_qobj)
Definition: main-window.cc:98
OCTAVE_EXPORT octave_value_list Fbuiltin(octave::interpreter &interp, const octave_value_list &args, int nargout)
Definition: oct-parse.cc:9690
octave_value_list ovl(const OV_Args &... args)
Construct an octave_value_list with less typing.
Definition: ovl.h:211
const QString key
const QVariant def
OCTAVE_EXPORT octave_value_list Ffile_in_loadpath(octave::interpreter &interp, const octave_value_list &args, int)
Definition: utils.cc:419
OCTAVE_EXPORT octave_value_list Fexist(octave::interpreter &interp, const octave_value_list &args, int)
Definition: variables.cc:465
OCTAVE_EXPORT octave_value_list Fclear(octave::interpreter &interp, const octave_value_list &args, int)
Definition: variables.cc:1257
std::string octave_name_version_copyright_copying_warranty_and_bugs(bool html, const std::string &extra_info)
Definition: version.cc:100