GNU Octave 7.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
file-editor.cc
Go to the documentation of this file.
1////////////////////////////////////////////////////////////////////////
2//
3// Copyright (C) 2011-2022 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#if defined (HAVE_QSCINTILLA)
31
32#include <algorithm>
33
34#include <QApplication>
35#include <QClipboard>
36#include <QFile>
37#include <QFileDialog>
38#include <QFont>
39#include <QMessageBox>
40#include <QMimeData>
41#include <QProcess>
42#include <QPushButton>
43#include <QStyle>
44#include <QTabBar>
45#include <QTextStream>
46#include <QVBoxLayout>
47#include <Qsci/qscicommandset.h>
48
49#include "file-editor.h"
50#include "gui-preferences-ed.h"
51#include "gui-preferences-sc.h"
53#include "main-window.h"
54#include "octave-qobject.h"
55#include "octave-qtutils.h"
56#include "shortcut-manager.h"
57
58#include "oct-env.h"
59
60#include "event-manager.h"
61#include "interpreter.h"
62#include "oct-map.h"
63#include "pt-eval.h"
64#include "utils.h"
65
66namespace octave
67{
68 // Functions of the the reimplemented tab widget
69
71 : QTabWidget (p)
72 {
73 tab_bar *bar = new tab_bar (this);
74
77
78 this->setTabBar (bar);
79
80 setTabsClosable (true);
81 setUsesScrollButtons (true);
82 setMovable (true);
83 }
84
86 {
87 return qobject_cast<tab_bar *> (tabBar ());
88 }
89
90 std::list<file_editor_tab *>
92 {
93 std::list<file_editor_tab *> retval;
94 for (int i = 0; i < count (); i++)
95 retval.push_back (static_cast<file_editor_tab *> (widget (i)));
96 return retval;
97 }
98
99
100 // File editor
101
103 : file_editor_interface (p, oct_qobj)
104 {
105 // Set current editing directory before construction because loaded
106 // files will change ced accordingly.
107 m_ced = QDir::currentPath ();
108
109 // Set actions that are later added by the main window to null,
110 // preventing access to them when they are still undefined.
111 m_undo_action = nullptr;
112 m_copy_action = nullptr;
113 m_paste_action = nullptr;
114 m_selectall_action = nullptr;
115
116 m_find_dialog = nullptr;
117
118 m_closed = false;
119 m_no_focus = false;
120 m_editor_ready = false;
121
122 m_copy_action_enabled = false;
123 m_undo_action_enabled = false;
125
126 construct ();
127
128 setVisible (false);
129 setAcceptDrops (true);
130 setFocusPolicy (Qt::StrongFocus);
131 }
132
133 void file_editor::focusInEvent (QFocusEvent *e)
134 {
135 // The focus is transferred to the active tab and its edit
136 // area in this focus in event handler. This is to avoid
137 // using focus proxies with conflicts in the proxy change
138 // presumably introduced by bug
139 // https://bugreports.qt.io/browse/QTBUG-61092
140 reset_focus (); // Make sure editor tab with edit area get focus
141
142 QDockWidget::focusInEvent (e);
143 }
144
145 // insert global actions, that should also be displayed in the editor window,
146 // into the editor's menu and/or toolbar
148 {
149 // actions/menus that have to be added to the toolbar or the menu
150 QAction *open_action = shared_actions.at (OPEN_ACTION);
151 QAction *new_action = shared_actions.at (NEW_SCRIPT_ACTION);
152 QAction *new_fcn_action = shared_actions.at (NEW_FUNCTION_ACTION);
153 m_fileMenu->insertAction (m_mru_file_menu->menuAction (), open_action);
154 m_fileMenu->insertAction (open_action, new_fcn_action);
155 m_fileMenu->insertAction (new_fcn_action, new_action);
156 m_tool_bar->insertAction (m_popdown_mru_action, open_action);
157 m_tool_bar->insertAction (open_action, new_action);
158
159 // actions that are additionally enabled/disabled later by the editor
160 // undo
161 m_undo_action = shared_actions.at (UNDO_ACTION);
162 m_tool_bar->insertAction (m_redo_action, m_undo_action);
163 m_edit_menu->insertAction (m_redo_action, m_undo_action);
164 // select all
165 m_selectall_action = shared_actions.at (SELECTALL_ACTION);
167 m_edit_menu->insertSeparator (m_find_action);
168 // paste
169 m_paste_action = shared_actions.at (PASTE_ACTION);
170 m_tool_bar->insertAction (m_find_action, m_paste_action);
172 m_edit_menu->insertSeparator (m_selectall_action);
173 // copy
174 m_copy_action = shared_actions.at (COPY_ACTION);
175 m_tool_bar->insertAction (m_paste_action, m_copy_action);
177 // find files
178 m_find_files_action = shared_actions.at (FIND_FILES_ACTION);
180 }
181
183 {
186 QString sc_run = settings->sc_value (sc_edit_run_run_file);
187 QString sc_cont = settings->sc_value (sc_main_debug_continue);
188
189 if (sc_run == sc_cont)
190 m_run_action->setShortcut (QKeySequence ()); // prevent ambiguous shortcuts
191
192 m_run_action->setToolTip (tr ("Continue")); // update tool tip
193
195 }
196
198 {
201 m_run_action->setToolTip (tr ("Save File and Run")); // update tool tip
202
204 }
205
207 {
208 // Do not include shared actions not only related to the editor
209 bool have_tabs = m_tab_widget->count () > 0;
210
211 m_edit_cmd_menu->setEnabled (have_tabs);
212 m_edit_fmt_menu->setEnabled (have_tabs);
213 m_edit_nav_menu->setEnabled (have_tabs);
214
215 m_comment_selection_action->setEnabled (have_tabs);
216 m_uncomment_selection_action->setEnabled (have_tabs);
217 m_comment_var_selection_action->setEnabled (have_tabs);
218 m_indent_selection_action->setEnabled (have_tabs);
219 m_unindent_selection_action->setEnabled (have_tabs);
220 m_smart_indent_line_or_selection_action->setEnabled (have_tabs);
221
222 m_context_help_action->setEnabled (have_tabs);
223 m_context_doc_action->setEnabled (have_tabs);
224
225 m_view_editor_menu->setEnabled (have_tabs);
226 m_zoom_in_action->setEnabled (have_tabs);
227 m_zoom_out_action->setEnabled (have_tabs);
228 m_zoom_normal_action->setEnabled (have_tabs);
229
230 m_find_action->setEnabled (have_tabs);
231 m_find_next_action->setEnabled (have_tabs);
232 m_find_previous_action->setEnabled (have_tabs);
233 m_print_action->setEnabled (have_tabs);
234
235 m_run_action->setEnabled (have_tabs && m_is_octave_file);
236
237 m_toggle_breakpoint_action->setEnabled (have_tabs && m_is_octave_file);
238 m_next_breakpoint_action->setEnabled (have_tabs && m_is_octave_file);
239 m_previous_breakpoint_action->setEnabled (have_tabs && m_is_octave_file);
240 m_remove_all_breakpoints_action->setEnabled (have_tabs && m_is_octave_file);
241
242 m_edit_function_action->setEnabled (have_tabs);
243 m_save_action->setEnabled (have_tabs && m_current_tab_modified);
244 m_save_as_action->setEnabled (have_tabs);
245 m_close_action->setEnabled (have_tabs);
246 m_close_all_action->setEnabled (have_tabs);
247 m_close_others_action->setEnabled (have_tabs && m_tab_widget->count () > 1);
248 m_sort_tabs_action->setEnabled (have_tabs && m_tab_widget->count () > 1);
249
251 }
252
253 // empty_script determines whether we have to create an empty script
254 // 1. At startup, when the editor has to be (really) visible
255 // (Here we can not use the visibility changed signal)
256 // 2. When the editor becomes visible when octave is running
257 void file_editor::empty_script (bool startup, bool visible)
258 {
259
260 if (startup)
261 m_editor_ready = true;
262 else
263 {
264 if (! m_editor_ready)
265 return; // not yet ready but got visibility changed signals
266 }
267
271 global_use_custom_editor.def).toBool ())
272 return; // do not open an empty script in the external editor
273
274 bool real_visible;
275
276 if (startup)
277 real_visible = isVisible ();
278 else
279 real_visible = visible;
280
281 if (! real_visible || m_tab_widget->count () > 0)
282 return;
283
284 if (startup && ! isFloating ())
285 {
286 // check if editor is really visible or hidden between tabbed widgets
287 QWidget *parent = parentWidget ();
288
289 if (parent)
290 {
291 QList<QTabBar *> tab_list = parent->findChildren<QTabBar *>();
292
293 bool in_tab = false;
294 int i = 0;
295 while ((i < tab_list.count ()) && (! in_tab))
296 {
297 QTabBar *tab = tab_list.at (i);
298 i++;
299
300 int j = 0;
301 while ((j < tab->count ()) && (! in_tab))
302 {
303 // check all tabs for the editor
304 if (tab->tabText (j) == windowTitle ())
305 {
306 // editor is in this tab widget
307 in_tab = true;
308 int top = tab->currentIndex ();
309 if (! (top > -1 && tab->tabText (top) == windowTitle ()))
310 return; // not current tab -> not visible
311 }
312 j++;
313 }
314 }
315 }
316 }
317
318 request_new_file ("");
319 }
320
322 {
323 //restore previous session
324 if (! settings->value (ed_restore_session).toBool ())
325 return;
326
327 // get the data from the settings file
328 QStringList sessionFileNames
329 = settings->value (ed_session_names).toStringList ();
330
331 QStringList session_encodings
332 = settings->value (ed_session_enc).toStringList ();
333
334 QStringList session_index
335 = settings->value (ed_session_ind).toStringList ();
336
337 QStringList session_lines
338 = settings->value (ed_session_lines).toStringList ();
339
340 // fill a list of the struct and sort it (depending on index)
341 QList<session_data> s_data;
342
343 bool do_encoding = (session_encodings.count () == sessionFileNames.count ());
344 bool do_index = (session_index.count () == sessionFileNames.count ());
345 bool do_lines = (session_lines.count () == sessionFileNames.count ());
346
347 for (int n = 0; n < sessionFileNames.count (); ++n)
348 {
349 QFileInfo file = QFileInfo (sessionFileNames.at (n));
350 if (! file.exists ())
351 continue;
352
353 session_data item = { 0, -1, sessionFileNames.at (n),
354 QString (), QString ()};
355 if (do_lines)
356 item.line = session_lines.at (n).toInt ();
357 if (do_index)
358 item.index = session_index.at (n).toInt ();
359 if (do_encoding)
360 item.encoding = session_encodings.at (n);
361
362 s_data << item;
363 }
364
365 std::sort (s_data.begin (), s_data.end ());
366
367 // finally open the files with the desired encoding in the desired order
368 for (int n = 0; n < s_data.count (); ++n)
369 request_open_file (s_data.at (n).file_name, s_data.at (n).encoding,
370 s_data.at (n).line);
371 }
372
374 {
375 if (m_no_focus)
376 return; // No focus for the editor if external open/close request
377
379
380 // set focus to current tab
381 reset_focus ();
382 }
383
385 {
386 setFocus ();
387
388 // set focus to desired tab
389 if (fet)
390 m_tab_widget->setCurrentWidget (fet);
391 }
392
393 // function enabling/disabling the menu accelerators depending on the
394 // focus of the editor
396 {
397 // Hide or show the find dialog together with the focus of the
398 // editor widget depending on the overall visibility of the find dialog.
399 // Do not change internal visibility state.
400 if (m_find_dialog)
401 m_find_dialog->set_visible (enable);
402
403 // Take care of the shortcuts
404 QHash<QMenu *, QStringList>::const_iterator i = m_hash_menu_text.constBegin ();
405
406 while (i != m_hash_menu_text.constEnd ())
407 {
408 i.key ()->setTitle (i.value ().at (! enable));
409 ++i;
410 }
411
412 // when editor loses focus, enable the actions, which are always active
413 // in the main window due to missing info on selected text and undo actions
415 {
416 if (enable)
417 {
420 }
421 else
422 {
423 m_copy_action_enabled = m_copy_action->isEnabled ();
424 m_undo_action_enabled = m_undo_action->isEnabled ();
425 m_copy_action->setEnabled (true);
426 m_undo_action->setEnabled (true);
427 }
428 }
429 }
430
431 // Save open files for restoring in next session
432 // (even if last session will not be restored next time)
433 // together with encoding and the tab index
435 {
438
439 QStringList fetFileNames;
440 QStringList fet_encodings;
441 QStringList fet_index;
442 QStringList fet_lines;
443
444 std::list<file_editor_tab *> editor_tab_lst = m_tab_widget->tab_list ();
445
446 for (auto editor_tab : editor_tab_lst)
447 {
448 QString file_name = editor_tab->file_name ();
449
450 // Don't append unnamed files.
451
452 if (! file_name.isEmpty ())
453 {
454 fetFileNames.append (file_name);
455 fet_encodings.append (editor_tab->encoding ());
456
457 QString index;
458 fet_index.append (index.setNum (m_tab_widget->indexOf (editor_tab)));
459
460 int l, c;
461 editor_tab->qsci_edit_area ()->getCursorPosition (&l, &c);
462 fet_lines.append (index.setNum (l + 1));
463 }
464 }
465
466 settings->setValue (ed_session_names.key, fetFileNames);
467 settings->setValue (ed_session_enc.key, fet_encodings);
468 settings->setValue (ed_session_ind.key, fet_index);
469 settings->setValue (ed_session_lines.key, fet_lines);
470 settings->sync ();
471 }
472
474 {
475 // When the application or the editor is closing and the user wants to
476 // close all files, in the latter case all editor tabs are checked whether
477 // they need to be saved. During these checks tabs are not closed since
478 // the user might cancel closing Octave during one of these saving dialogs.
479 // Therefore, saving the session for restoring at next start is not done
480 // before the application is definitely closing.
481
482 // Save the session. Even is closing is cancelled, this would be
483 // overwritten by the next attempt to close the editor
484 save_session ();
485
486 std::list<file_editor_tab *> fe_tab_lst = m_tab_widget->tab_list ();
487 m_number_of_tabs = fe_tab_lst.size ();
488
489 for (auto fe_tab : fe_tab_lst)
490 {
491 // Wait for all editor tabs to have saved their files if required
492
493 connect (fe_tab, &file_editor_tab::tab_ready_to_close,
495 Qt::UniqueConnection);
496 }
497
498 m_closing_canceled = false;
499
500 for (auto fe_tab : fe_tab_lst)
501 {
502 // If there was a cancellation, make the already saved/discarded tabs
503 // recover from the exit by removing the read-only state and by
504 // recovering the debugger breakpoints. Finally return false in order
505 // to cancel closing the application or the editor.
506
507 if (fe_tab->check_file_modified (false) == QMessageBox::Cancel)
508 {
510
511 m_closing_canceled = true;
512
513 for (auto fet : fe_tab_lst)
514 disconnect (fet, &file_editor_tab::tab_ready_to_close, 0, 0);
515
516 return false;
517 }
518 }
519
520 return true;
521 }
522
524 {
526 return;
527
528 // FIXME: Why count down to zero here before doing anything? Why
529 // not remove and delete each tab that is ready to be closed, one
530 // per invocation?
531
533
534 if (m_number_of_tabs > 0)
535 return;
536
537 // Here, the application or the editor will be closed -> store the session
538
539 // Take care of the find dialog
540 if (m_find_dialog)
541 m_find_dialog->close ();
542
543 // Finally close all the tabs and return indication that we can exit
544 // the application or close the editor.
545 // Closing and deleting the tabs makes the editor visible. In case it was
546 // hidden before, this state has to be restored afterwards.
547 bool vis = isVisible ();
548
549 std::list<file_editor_tab *> editor_tab_lst = m_tab_widget->tab_list ();
550 for (auto editor_tab : editor_tab_lst)
551 editor_tab->deleteLater ();
552
553 m_tab_widget->clear ();
554
555 setVisible (vis);
556 }
557
558 void file_editor::request_new_file (const QString& commands)
559 {
560 // Custom editor? If yes, we can only call the editor without passing
561 // some initial contents and even without being sure a new file is opened
562 if (call_custom_editor ())
563 return;
564
565 // New file isn't a file_editor_tab function since the file
566 // editor tab has yet to be created and there is no object to
567 // pass a signal to. Hence, functionality is here.
568
569 file_editor_tab *fileEditorTab = make_file_editor_tab (m_ced);
570 add_file_editor_tab (fileEditorTab, ""); // new tab with empty title
571 fileEditorTab->new_file (commands); // title is updated here
572 activate (); // focus editor and new tab
573 }
574
576 {
577 file_editor_tab *editor_tab
578 = static_cast<file_editor_tab *> (m_tab_widget->currentWidget ());
579 editor_tab->conditional_close ();
580 }
581
583 {
584 file_editor_tab *editor_tab;
585
586 // loop over all tabs starting from last one otherwise deletion changes index
587 for (int index = m_tab_widget->count ()-1; index >= 0; index--)
588 {
589 editor_tab = static_cast<file_editor_tab *> (m_tab_widget->widget (index));
590 editor_tab->conditional_close ();
591 }
592 }
593
595 {
596 file_editor_tab *editor_tab;
597 QWidget *tabID = m_tab_widget->currentWidget ();
598
599 // loop over all tabs starting from last one otherwise deletion changes index
600 for (int index = m_tab_widget->count ()-1; index >= 0; index--)
601 {
602 if (tabID != m_tab_widget->widget (index))
603 {
604 editor_tab
605 = static_cast<file_editor_tab *> (m_tab_widget->widget (index));
606 editor_tab->conditional_close ();
607 }
608 }
609 }
610
612 {
613 file_editor_tab *editor_tab
614 = static_cast<file_editor_tab *> (m_tab_widget->currentWidget ());
615
616 if (editor_tab)
617 QGuiApplication::clipboard ()->setText (editor_tab->file_name ());
618 }
619
620 // open a file from the mru list
622 {
623 if (action)
624 {
625 request_open_file (action->data ().toStringList ().at (0),
626 action->data ().toStringList ().at (1));
627 }
628 }
629
631 {
632 emit fetab_print_file (m_tab_widget->currentWidget ());
633 }
634
636 {
637 emit fetab_scintilla_command (m_tab_widget->currentWidget (),
638 QsciScintillaBase::SCI_REDO);
639 }
640
642 {
643 emit fetab_scintilla_command (m_tab_widget->currentWidget (),
644 QsciScintillaBase::SCI_CUT);
645 }
646
648 {
649 emit fetab_context_help (m_tab_widget->currentWidget (), false);
650 }
651
653 {
654 emit fetab_context_help (m_tab_widget->currentWidget (), true);
655 }
656
658 {
659 emit fetab_context_edit (m_tab_widget->currentWidget ());
660 }
661
663 {
664 emit fetab_save_file (m_tab_widget->currentWidget ());
665 }
666
668 {
669 emit fetab_save_file_as (m_tab_widget->currentWidget ());
670 }
671
673 {
675 ([=] (interpreter& interp)
676 {
677 // INTERPRETER THREAD
678
679 tree_evaluator& tw = interp.get_evaluator ();
680
681 if (tw.in_debug_repl ())
682 emit request_dbcont_signal ();
683 else
684 emit fetab_run_file (m_tab_widget->currentWidget ());
685 });
686 }
687
689 {
690 emit fetab_run_file (m_tab_widget->currentWidget (), true);
691 }
692
694 {
695 emit fetab_context_run (m_tab_widget->currentWidget ());
696 }
697
699 {
700 emit fetab_toggle_bookmark (m_tab_widget->currentWidget ());
701 }
702
704 {
705 emit fetab_next_bookmark (m_tab_widget->currentWidget ());
706 }
707
709 {
710 emit fetab_previous_bookmark (m_tab_widget->currentWidget ());
711 }
712
714 {
715 emit fetab_remove_bookmark (m_tab_widget->currentWidget ());
716 }
717
719 {
720 emit fetab_move_match_brace (m_tab_widget->currentWidget (), false);
721 }
722
724 {
725 emit fetab_move_match_brace (m_tab_widget->currentWidget (), true);
726 }
727
728 // FIXME: What should this do with conditional breakpoints?
730 {
731 emit fetab_toggle_breakpoint (m_tab_widget->currentWidget ());
732 }
733
735 {
736 emit fetab_next_breakpoint (m_tab_widget->currentWidget ());
737 }
738
740 {
741 emit fetab_previous_breakpoint (m_tab_widget->currentWidget ());
742 }
743
745 {
746 emit fetab_remove_all_breakpoints (m_tab_widget->currentWidget ());
747 }
748
749 // slots for Edit->Commands actions
751 {
752 emit fetab_scintilla_command (m_tab_widget->currentWidget (),
753 QsciScintillaBase::SCI_DELWORDLEFT);
754 }
755
757 {
758 emit fetab_scintilla_command (m_tab_widget->currentWidget (),
759 QsciScintillaBase::SCI_DELWORDRIGHT);
760 }
761
763 {
764 emit fetab_scintilla_command (m_tab_widget->currentWidget (),
765 QsciScintillaBase::SCI_DELLINELEFT);
766 }
767
769 {
770 emit fetab_scintilla_command (m_tab_widget->currentWidget (),
771 QsciScintillaBase::SCI_DELLINERIGHT);
772 }
773
775 {
776 emit fetab_scintilla_command (m_tab_widget->currentWidget (),
777 QsciScintillaBase::SCI_LINEDELETE);
778 }
779
781 {
782 emit fetab_scintilla_command (m_tab_widget->currentWidget (),
783 QsciScintillaBase::SCI_LINECOPY);
784 }
785
787 {
788 emit fetab_scintilla_command (m_tab_widget->currentWidget (),
789 QsciScintillaBase::SCI_LINECUT);
790 }
791
793 {
794 emit fetab_scintilla_command (m_tab_widget->currentWidget (),
795 QsciScintillaBase::SCI_SELECTIONDUPLICATE);
796 }
797
799 {
800 emit fetab_scintilla_command (m_tab_widget->currentWidget (),
801 QsciScintillaBase::SCI_LINETRANSPOSE);
802 }
803
805 {
806 emit fetab_comment_selected_text (m_tab_widget->currentWidget (), false);
807 }
808
810 {
811 emit fetab_uncomment_selected_text (m_tab_widget->currentWidget ());
812 }
813
815 {
816 emit fetab_comment_selected_text (m_tab_widget->currentWidget (), true);
817 }
818
819 // slots for Edit->Format actions
821 {
822 emit fetab_scintilla_command (m_tab_widget->currentWidget (),
823 QsciScintillaBase::SCI_UPPERCASE);
824 }
825
827 {
828 emit fetab_scintilla_command (m_tab_widget->currentWidget (),
829 QsciScintillaBase::SCI_LOWERCASE);
830 }
831
833 {
834 emit fetab_indent_selected_text (m_tab_widget->currentWidget ());
835 }
836
838 {
839 emit fetab_unindent_selected_text (m_tab_widget->currentWidget ());
840 }
841
843 {
845 }
846
848 {
849 emit fetab_convert_eol (m_tab_widget->currentWidget (),
850 QsciScintilla::EolWindows);
851 }
852 void
854 {
855 emit fetab_convert_eol (m_tab_widget->currentWidget (),
856 QsciScintilla::EolUnix);
857 }
858
860 {
861 emit fetab_convert_eol (m_tab_widget->currentWidget (),
862 QsciScintilla::EolMac);
863 }
864
865 // Slot for initially creating and showing the find dialog
867 {
868 // Create the dialog
869 find_create ();
870
871 // Since find_create shows the dialog without activating the widget
872 // (which is reuqired in other cases) do this manually here
873 m_find_dialog->activateWindow ();
874
875 // Initiate search text from possible selection and save the initial
876 // data from the dialog on the defined structure
877 m_find_dialog->init_search_text ();
878 }
879
880 // This method creates the find dialog.
881
883 {
884 if (m_find_dialog)
885 m_find_dialog->close ();
886
887 if (isFloating ())
888 m_find_dialog = new find_dialog (m_octave_qobj, this, this);
889 else
890 m_find_dialog = new find_dialog (m_octave_qobj, this, parentWidget ());
891
892 // Add required actions
895
896 // Update edit area
897 file_editor_tab *fet
898 = static_cast<file_editor_tab *> (m_tab_widget->currentWidget ());
899 m_find_dialog->update_edit_area (fet->qsci_edit_area ());
900
901 // Icon is the same as the editor
902 m_find_dialog->setWindowIcon (windowIcon ());
903
904 // Position: lower right of editor's position
905 int xp = x () + frameGeometry ().width ();
906 int yp = y () + frameGeometry ().height ();
907
908 if (! isFloating ())
909 {
910 // Fix position if editor is docked
911
912 QWidget *parent = parentWidget ();
913
914 if (parent)
915 {
916 xp = xp + parent->x ();
917 yp = yp + parent->y ();
918 }
919 }
920
921 if (yp < 0)
922 yp = 0;
923
924 // The size of the find dialog is considered in restore_settings
925 // since its size might change depending on the options
926 m_find_dialog->restore_settings (QPoint (xp, yp));
927
928 // Set visible
929 m_find_dialog->set_visible (true);
930 }
931
933 {
934 if (m_find_dialog)
935 m_find_dialog->find_next ();
936 }
937
939 {
940 if (m_find_dialog)
941 m_find_dialog->find_prev ();
942 }
943
945 {
946 emit fetab_goto_line (m_tab_widget->currentWidget ());
947 }
948
950 {
951 emit fetab_completion (m_tab_widget->currentWidget ());
952 }
953
954 void file_editor::handle_file_name_changed (const QString& fname,
955 const QString& tip,
956 bool modified)
957 {
958 QObject *fileEditorTab = sender ();
959 if (fileEditorTab)
960 {
962
963 for (int i = 0; i < m_tab_widget->count (); i++)
964 {
965 if (m_tab_widget->widget (i) == fileEditorTab)
966 {
967 m_tab_widget->setTabText (i, fname);
968 m_tab_widget->setTabToolTip (i, tip);
969
970 m_save_action->setEnabled (modified);
971 m_current_tab_modified = modified;
972
973 if (modified)
974 m_tab_widget->setTabIcon (i, rmgr.icon ("document-save"));
975 else
976 m_tab_widget->setTabIcon (i, QIcon ());
977 }
978 }
979 }
980 }
981
983 {
984 file_editor_tab *editor_tab
985 = static_cast<file_editor_tab *> (m_tab_widget->widget (index));
986 editor_tab->conditional_close ();
987 }
988
989 void
991 {
992 QObject *fileEditorTab = sender ();
993 if (fileEditorTab)
994 {
995 for (int i = 0; i < m_tab_widget->count (); i++)
996 {
997 if (m_tab_widget->widget (i) == fileEditorTab)
998 {
999 m_tab_widget->removeTab (i);
1000
1001 // Deleting the sender (even with deleteLater) seems a
1002 // bit strange. Is there a better way?
1003 fileEditorTab->deleteLater ();
1004 break;
1005 }
1006 }
1007 }
1008 check_actions ();
1009
1010 activate (); // focus stays in editor when tab is closed
1011
1012 }
1013
1014 // context menu of edit area
1016 {
1017 emit fetab_change_request (m_tab_widget->widget (index));
1018 activate ();
1019 }
1020
1022 bool is_octave_file,
1023 bool is_modified)
1024 {
1025 // In case there is some scenario where traffic could be coming from
1026 // all the file editor tabs, just process info from the current active tab.
1027 if (sender () == m_tab_widget->currentWidget ())
1028 {
1029 m_save_action->setEnabled (is_modified);
1030 m_current_tab_modified = is_modified;
1031
1032 if (m_copy_action)
1033 m_copy_action->setEnabled (copy_available);
1034
1035 m_cut_action->setEnabled (copy_available);
1036
1037 m_run_selection_action->setEnabled (copy_available);
1038 m_run_action->setEnabled (is_octave_file);
1039 m_is_octave_file = is_octave_file;
1040
1042 }
1043
1044 m_copy_action_enabled = m_copy_action->isEnabled ();
1045 m_undo_action_enabled = m_undo_action->isEnabled ();
1046 }
1047
1048 void file_editor::handle_mru_add_file (const QString& file_name,
1049 const QString& encoding)
1050 {
1051 int index;
1052 while ((index = m_mru_files.indexOf (file_name)) >= 0)
1053 {
1054 m_mru_files.removeAt (index);
1055 m_mru_files_encodings.removeAt (index);
1056 }
1057
1058 m_mru_files.prepend (file_name);
1059 m_mru_files_encodings.prepend (encoding);
1060
1061 mru_menu_update ();
1062 }
1063
1064 void file_editor::check_conflict_save (const QString& saveFileName,
1065 bool remove_on_success)
1066 {
1067 // Check whether this file is already open in the editor.
1068 file_editor_tab *tab = find_tab_widget (saveFileName);
1069
1070 if (tab)
1071 {
1072 // Note: to overwrite the contents of some other file editor tab
1073 // with the same name requires identifying which file editor tab
1074 // that is (not too difficult) then closing that tab. Of course,
1075 // that could trigger another dialog box if the file editor tab
1076 // with the same name has modifications in it. This could become
1077 // somewhat confusing to the user. For now, opt to do nothing.
1078
1079 // Create a NonModal message about error.
1080 QMessageBox *msgBox
1081 = new QMessageBox (QMessageBox::Critical, tr ("Octave Editor"),
1082 tr ("File not saved! A file with the selected name\n%1\n"
1083 "is already open in the editor").
1084 arg (saveFileName),
1085 QMessageBox::Ok, nullptr);
1086
1087 msgBox->setWindowModality (Qt::NonModal);
1088 msgBox->setAttribute (Qt::WA_DeleteOnClose);
1089 msgBox->show ();
1090
1091 return;
1092 }
1093
1094 QObject *saveFileObject = sender ();
1095 QWidget *saveFileWidget = nullptr;
1096
1097 for (int i = 0; i < m_tab_widget->count (); i++)
1098 {
1099 if (m_tab_widget->widget (i) == saveFileObject)
1100 {
1101 saveFileWidget = m_tab_widget->widget (i);
1102 break;
1103 }
1104 }
1105 if (! saveFileWidget)
1106 {
1107 // Create a NonModal message about error.
1108 QMessageBox *msgBox
1109 = new QMessageBox (QMessageBox::Critical, tr ("Octave Editor"),
1110 tr ("The associated file editor tab has disappeared."),
1111 QMessageBox::Ok, nullptr);
1112
1113 msgBox->setWindowModality (Qt::NonModal);
1114 msgBox->setAttribute (Qt::WA_DeleteOnClose);
1115 msgBox->show ();
1116
1117 return;
1118 }
1119
1120 // Can save without conflict, have the file editor tab do so.
1121 emit fetab_save_file (saveFileWidget, saveFileName, remove_on_success);
1122 }
1123
1125 int line)
1126 {
1127 request_open_file (file, QString (), line, true); // default encoding
1128 }
1129
1131 int line)
1132 {
1133 if (! file.isEmpty ())
1134 {
1135 // Check whether this file is already open in the editor.
1136 file_editor_tab *tab = find_tab_widget (file);
1137
1138 if (tab)
1139 {
1140 m_tab_widget->setCurrentWidget (tab);
1141
1142 if (line > 0)
1143 emit fetab_delete_debugger_pointer (tab, line);
1144
1145 emit fetab_set_focus (tab);
1146 }
1147 }
1148 }
1149
1151 const QString& file,
1152 int line,
1153 const QString& cond)
1154 {
1155 request_open_file (file, QString (), line, false, true, insert, cond);
1156 }
1157
1158 void file_editor::handle_edit_file_request (const QString& file)
1159 {
1160 request_open_file (file);
1161 }
1162
1163 // Slot used for signals indicating that a file was changed/renamed or
1164 // is going to be deleted/renamed
1165 void file_editor::handle_file_remove (const QString& old_name,
1166 const QString& new_name)
1167 {
1168 // Clear old list of file data and declare a structure for file data
1169 m_tmp_closed_files.clear ();
1170 session_data f_data;
1171
1172 // Preprocessing old name(s)
1173 QString old_name_clean = old_name.trimmed ();
1174 int s = old_name_clean.size ();
1175
1176 if (s > 1 && old_name_clean.at (0) == QChar ('\"')
1177 && old_name_clean.at (s - 1) == QChar ('\"'))
1178 old_name_clean = old_name_clean.mid (1, s - 2);
1179
1180 QStringList old_names = old_name_clean.split ("\" \"");
1181
1182 // Check if new name is a file or directory
1183 QFileInfo newf (new_name);
1184 bool new_is_dir = newf.isDir ();
1185
1186 // Now loop over all old files/dirs (several files by movefile ())
1187 for (int i = 0; i < old_names.count (); i++)
1188 {
1189 // Check if old name is a file or directory
1190 QFileInfo old (old_names.at (i));
1191
1192 if (old.isDir ())
1193 {
1194 // Call the function which handles directories and return
1195 handle_dir_remove (old_names.at (i), new_name);
1196 }
1197 else
1198 {
1199 // It is a single file. Is it open?
1200 file_editor_tab *editor_tab = find_tab_widget (old_names.at (i));
1201
1202 if (editor_tab)
1203 {
1204 // Get index and line.
1205
1206 f_data.encoding = editor_tab->encoding ();
1207 f_data.index = m_tab_widget->indexOf (editor_tab);
1208 int l, c;
1209 editor_tab->qsci_edit_area ()->getCursorPosition (&l, &c);
1210 f_data.line = l + 1;
1211
1212 // Close it silently
1213 m_no_focus = true; // Remember for not focussing editor
1214 editor_tab->file_has_changed (QString (), true); // Close the tab
1215 m_no_focus = false; // Back to normal
1216
1217 // For reloading old file if error while removing
1218 f_data.file_name = old_names.at (i);
1219 // For reloading new file (if new_file is not empty)
1220 if (new_is_dir)
1221 {
1222 std::string ndir = new_name.toStdString ();
1223 std::string ofile = old.fileName ().toStdString ();
1224 f_data.new_file_name
1226 }
1227 else
1228 f_data.new_file_name = new_name;
1229
1230 // Add file data to list
1231 m_tmp_closed_files << f_data;
1232 }
1233 }
1234 }
1235 }
1236
1237 // Slot for signal indicating that a file was renamed
1239 {
1240 m_no_focus = true; // Remember for not focussing editor
1241
1242 // Loop over all files that have to be reloaded. Start at the end of the
1243 // list, otherwise the stored indexes are not correct.
1244 for (int i = m_tmp_closed_files.count () - 1; i >= 0; i--)
1245 {
1246 // Load old or new file
1247 if (load_new)
1248 {
1249 if (! m_tmp_closed_files.at (i).new_file_name.isEmpty ())
1250 request_open_file (m_tmp_closed_files.at (i).new_file_name,
1251 m_tmp_closed_files.at (i).encoding,
1252 m_tmp_closed_files.at (i).line,
1253 false, false, true, "",
1254 m_tmp_closed_files.at (i).index);
1255 }
1256 else
1257 {
1258 request_open_file (m_tmp_closed_files.at (i).file_name,
1259 m_tmp_closed_files.at (i).encoding,
1260 m_tmp_closed_files.at (i).line,
1261 false, false, true, "",
1262 m_tmp_closed_files.at (i).index);
1263 }
1264
1265 }
1266
1267 m_no_focus = false; // Back to normal focus
1268
1269 // Clear the list of file data
1270 m_tmp_closed_files.clear ();
1271 }
1272
1274 {
1275 int size_idx = settings->value (global_icon_size).toInt ();
1276 size_idx = (size_idx > 0) - (size_idx < 0) + 1; // Make valid index from 0 to 2
1277
1278 QStyle *st = style ();
1279 int icon_size = st->pixelMetric (global_icon_sizes[size_idx]);
1280 m_tool_bar->setIconSize (QSize (icon_size, icon_size));
1281
1282 // Tab position and rotation
1283 QTabWidget::TabPosition pos
1284 = static_cast<QTabWidget::TabPosition> (settings->value (ed_tab_position).toInt ());
1285 bool rotated = settings->value (ed_tabs_rotated).toBool ();
1286
1287 m_tab_widget->setTabPosition (pos);
1288
1289 if (rotated)
1290 m_tab_widget->setTabsClosable (false); // No close buttons
1291 // FIXME: close buttons can not be correctly placed in rotated tabs
1292
1293 // Get the tab bar and set the rotation
1294 int rotation = rotated;
1295 if (pos == QTabWidget::West)
1296 rotation = -rotation;
1297
1298 tab_bar *bar = m_tab_widget->get_tab_bar ();
1299 bar->set_rotated (rotation);
1300
1301 // Get suitable height of a tab related to font and icon size
1302 int height = 1.5*QFontMetrics (m_tab_widget->font ()).height ();
1303 int is = 1.5*m_tab_widget->iconSize ().height ();
1304 if (is > height)
1305 height = is;
1306
1307 // Calculate possibly limited width and set the elide mode
1308 int chars = settings->value (ed_tabs_max_width).toInt ();
1309 int width = 9999;
1310 if (chars > 0)
1311 width = chars * QFontMetrics (m_tab_widget->font ()).averageCharWidth ();
1312
1313 // Get tab bar size properties for style sheet depending on rotation
1314 QString width_str ("width");
1315 QString height_str ("height");
1316 if ((pos == QTabWidget::West) || (pos == QTabWidget::East))
1317 {
1318 width_str = QString ("height");
1319 height_str = QString ("width");
1320 }
1321
1322 QString style_sheet
1323 = QString ("QTabBar::tab {max-" + height_str + ": %1px;\n"
1324 "max-" + width_str + ": %2px; }")
1325 .arg (height).arg (width);
1326
1327#if defined (Q_OS_MAC)
1328 // FIXME: This is a workaround for missing tab close buttons on MacOS
1329 // in several Qt versions (https://bugreports.qt.io/browse/QTBUG-61092)
1330 if (! rotated)
1331 {
1332 QString close_button_css_mac (
1333 "QTabBar::close-button"
1334 " { width: 6px; image: url(:/actions/icons/widget-close.png);"
1335 " subcontrol-position: button; }\n"
1336 "QTabBar::close-button:hover"
1337 " { background-color: #cccccc; }");
1338
1339 style_sheet = style_sheet + close_button_css_mac;
1340 }
1341#endif
1342
1343 m_tab_widget->setStyleSheet (style_sheet);
1344
1345 bool show_it;
1346 show_it = settings->value (ed_show_line_numbers).toBool ();
1347 m_show_linenum_action->setChecked (show_it);
1348 show_it = settings->value (ed_show_white_space).toBool ();
1349 m_show_whitespace_action->setChecked (show_it);
1350 show_it = settings->value (ed_show_eol_chars).toBool ();
1351 m_show_eol_action->setChecked (show_it);
1352 show_it = settings->value (ed_show_indent_guides).toBool ();
1353 m_show_indguide_action->setChecked (show_it);
1354 show_it = settings->value (ed_long_line_marker).toBool ();
1355 m_show_longline_action->setChecked (show_it);
1356
1357 show_it = settings->value (ed_show_toolbar).toBool ();
1358 m_show_toolbar_action->setChecked (show_it);
1359 m_tool_bar->setVisible (show_it);
1360 show_it = settings->value (ed_show_edit_status_bar).toBool ();
1361 m_show_statusbar_action->setChecked (show_it);
1362 show_it = settings->value (ed_show_hscroll_bar).toBool ();
1363 m_show_hscrollbar_action->setChecked (show_it);
1364
1365 set_shortcuts ();
1366
1367 // Find dialog with the same icon as the editor
1368 if (m_find_dialog)
1369 m_find_dialog->setWindowIcon (windowIcon ());
1370
1371 // Relay signal to file editor tabs.
1373 }
1374
1376 {
1377 // Shortcuts also available in the main window, as well as the related
1378 // shortcuts, are defined in main_window and added to the editor
1379
1381
1382 // File menu
1390
1391 // Edit menu
1397
1410
1426
1430
1431 // View menu
1444
1445 // Debug menu
1450
1451 // Run menu
1454
1455 // Help menu
1458
1459 // Tab navigation without menu entries
1464
1465 }
1466
1467 // This slot is a reimplementation of the virtual slot in octave_dock_widget.
1468 // We need this for creating an empty script when the editor has no open
1469 // files and is made visible.
1471 {
1473
1474 if (! m_editor_ready)
1475 return;
1476
1477 if (m_closed && visible)
1478 {
1479 m_closed = false;
1483 }
1484
1485 empty_script (false, visible);
1486 }
1487
1488 // This slot is a reimplementation of the virtual slot in octave_dock_widget.
1489 // We need this for updating the parent of the find dialog
1491 {
1492 if (m_find_dialog)
1493 {
1494 // close current dialog
1495 m_find_dialog->close ();
1496
1497 // re-create dialog with the new parent (editor or main-win)
1498 find_create ();
1499 m_find_dialog->activateWindow ();
1500 }
1501 }
1502
1504 {
1505 m_ced = dir;
1506 emit fetab_set_directory (m_ced); // for save dialog
1507 }
1508
1510 {
1511 if (editor_tab_has_focus ())
1512 emit fetab_scintilla_command (m_tab_widget->currentWidget (),
1513 QsciScintillaBase::SCI_COPY);
1514 }
1515
1517 {
1518 if (editor_tab_has_focus ())
1519 emit fetab_scintilla_command (m_tab_widget->currentWidget (),
1520 QsciScintillaBase::SCI_PASTE);
1521 }
1522
1524 {
1525 if (editor_tab_has_focus ())
1526 emit fetab_scintilla_command (m_tab_widget->currentWidget (),
1527 QsciScintillaBase::SCI_SELECTALL);
1528 }
1529
1531 {
1532 if (editor_tab_has_focus ())
1533 emit fetab_scintilla_command (m_tab_widget->currentWidget (),
1534 QsciScintillaBase::SCI_UNDO);
1535 }
1536
1537 // Open a file, if not already open, and mark the current execution location
1538 // and/or a breakpoint with condition cond.
1539 void file_editor::request_open_file (const QString& openFileName,
1540 const QString& encoding,
1541 int line, bool debug_pointer,
1542 bool breakpoint_marker, bool insert,
1543 const QString& cond, int index)
1544 {
1547
1548 if (settings->value (global_use_custom_editor).toBool ())
1549 {
1550 // Custom editor
1551 if (debug_pointer || breakpoint_marker)
1552 return; // Do not call custom editor during debugging
1553
1554 if (call_custom_editor (openFileName, line))
1555 return; // Custom editor called
1556 }
1557
1558 bool show_dbg_file
1559 = settings->value (ed_show_dbg_file).toBool ();
1560
1561 if (openFileName.isEmpty ())
1562 {
1563 // This happens if edit is called without an argument
1564 // Open editor with empty edit area instead (as new file would do)
1565 request_new_file ("");
1566 }
1567 else
1568 {
1569 // Check whether this file is already open in the editor.
1570 file_editor_tab *tab = find_tab_widget (openFileName);
1571
1572 if (tab)
1573 {
1574 m_tab_widget->setCurrentWidget (tab);
1575
1576 if (line > 0)
1577 {
1578 if (insert)
1579 emit fetab_goto_line (tab, line);
1580
1581 if (debug_pointer)
1582 emit fetab_insert_debugger_pointer (tab, line);
1583
1584 if (breakpoint_marker)
1585 emit fetab_do_breakpoint_marker (insert, tab, line, cond);
1586 }
1587
1588 if (show_dbg_file && ! ((breakpoint_marker || debug_pointer)
1590 {
1591 emit fetab_set_focus (tab);
1592 activate ();
1593 }
1594 }
1595 else
1596 {
1597 if (! show_dbg_file && (breakpoint_marker || debug_pointer))
1598 return; // Do not open a file for showing dbg markers
1599
1600 if (breakpoint_marker && ! insert)
1601 return; // Never open a file when removing breakpoints
1602
1603 file_editor_tab *fileEditorTab = nullptr;
1604 // Reuse <unnamed> tab if it hasn't yet been modified.
1605 bool reusing = false;
1606 tab = find_tab_widget ("");
1607 if (tab)
1608 {
1609 fileEditorTab = tab;
1610 if (fileEditorTab->qsci_edit_area ()->isModified ())
1611 fileEditorTab = nullptr;
1612 else
1613 reusing = true;
1614 }
1615
1616 // If <unnamed> was absent or modified, create a new tab.
1617 if (! fileEditorTab)
1618 fileEditorTab = make_file_editor_tab ();
1619
1620 fileEditorTab->set_encoding (encoding);
1621 QString result = fileEditorTab->load_file (openFileName);
1622 if (result == "")
1623 {
1624 // Supply empty title then have the file_editor_tab update
1625 // with full or short name.
1626 if (! reusing)
1627 add_file_editor_tab (fileEditorTab, "", index);
1628 fileEditorTab->update_window_title (false);
1629 // file already loaded, add file to mru list here
1630 QFileInfo file_info = QFileInfo (openFileName);
1631 handle_mru_add_file (file_info.canonicalFilePath (),
1632 encoding);
1633
1634 if (line > 0)
1635 {
1636 if (insert)
1637 emit fetab_goto_line (fileEditorTab, line);
1638
1639 if (debug_pointer)
1640 emit fetab_insert_debugger_pointer (fileEditorTab,
1641 line);
1642 if (breakpoint_marker)
1643 emit fetab_do_breakpoint_marker (insert, fileEditorTab,
1644 line, cond);
1645 }
1646 }
1647 else
1648 {
1649 delete fileEditorTab;
1650 fileEditorTab = nullptr;
1651
1652 if (QFile::exists (openFileName))
1653 {
1654 // File not readable:
1655 // create a NonModal message about error.
1656 QMessageBox *msgBox
1657 = new QMessageBox (QMessageBox::Critical,
1658 tr ("Octave Editor"),
1659 tr ("Could not open file\n%1\nfor read: %2.").
1660 arg (openFileName).arg (result),
1661 QMessageBox::Ok, this);
1662
1663 msgBox->setWindowModality (Qt::NonModal);
1664 msgBox->setAttribute (Qt::WA_DeleteOnClose);
1665 msgBox->show ();
1666 }
1667 else
1668 {
1669 // File does not exist, should it be created?
1670 bool create_file = true;
1671 QMessageBox *msgBox;
1672
1673 if (! settings->value (ed_create_new_file).toBool ())
1674 {
1675 msgBox = new QMessageBox (QMessageBox::Question,
1676 tr ("Octave Editor"),
1677 tr ("File\n%1\ndoes not exist. "
1678 "Do you want to create it?").arg (openFileName),
1679 QMessageBox::NoButton, nullptr);
1680 QPushButton *create_button =
1681 msgBox->addButton (tr ("Create"), QMessageBox::YesRole);
1682 msgBox->addButton (tr ("Cancel"), QMessageBox::RejectRole);
1683 msgBox->setDefaultButton (create_button);
1684 msgBox->exec ();
1685
1686 QAbstractButton *clicked_button = msgBox->clickedButton ();
1687 if (clicked_button != create_button)
1688 create_file = false;
1689
1690 delete msgBox;
1691 }
1692
1693 if (create_file)
1694 {
1695 // create the file and call the editor again
1696 QFile file (openFileName);
1697 if (! file.open (QIODevice::WriteOnly))
1698 {
1699 // error opening the file
1700 msgBox = new QMessageBox (QMessageBox::Critical,
1701 tr ("Octave Editor"),
1702 tr ("Could not open file\n%1\nfor write: %2.").
1703 arg (openFileName).arg (file.errorString ()),
1704 QMessageBox::Ok, this);
1705
1706 msgBox->setWindowModality (Qt::NonModal);
1707 msgBox->setAttribute (Qt::WA_DeleteOnClose);
1708 msgBox->show ();
1709 }
1710 else
1711 {
1712 file.close ();
1713 request_open_file (openFileName);
1714 }
1715 }
1716 }
1717 }
1718
1719 if (! ((breakpoint_marker || debug_pointer) && is_editor_console_tabbed ()))
1720 {
1721 // update breakpoint pointers, really show editor
1722 // and the current editor tab
1723 if (fileEditorTab)
1724 fileEditorTab->update_breakpoints ();
1725 activate ();
1726 emit file_loaded_signal ();
1727 }
1728 }
1729 }
1730 }
1731
1733 {
1734 emit request_settings_dialog ("editor");
1735 }
1736
1738 {
1739 emit request_settings_dialog ("editor_styles");
1740 }
1741
1743 {
1745 }
1746
1748 {
1750 }
1751
1753 {
1755 }
1756
1758 {
1760 }
1761
1763 {
1765 }
1766
1768 {
1770 }
1771
1773 {
1775 }
1776
1778 {
1780 }
1781
1783 {
1784 emit fetab_zoom_in (m_tab_widget->currentWidget ());
1785 }
1786
1788 {
1789 emit fetab_zoom_out (m_tab_widget->currentWidget ());
1790 }
1791
1793 {
1794 emit fetab_zoom_normal (m_tab_widget->currentWidget ());
1795 }
1796
1798 {
1799 // remove all standard actions from scintilla
1800 QList<QAction *> all_actions = menu->actions ();
1801
1802 for (auto *a : all_actions)
1803 menu->removeAction (a);
1804
1805 // add editor's actions with icons and customized shortcuts
1806 menu->addAction (m_cut_action);
1807 menu->addAction (m_copy_action);
1808 menu->addAction (m_paste_action);
1809 menu->addSeparator ();
1810 menu->addAction (m_selectall_action);
1811 menu->addSeparator ();
1812 menu->addAction (m_find_files_action);
1813 menu->addAction (m_find_action);
1814 menu->addAction (m_find_next_action);
1815 menu->addAction (m_find_previous_action);
1816 menu->addSeparator ();
1817 menu->addMenu (m_edit_cmd_menu);
1818 menu->addMenu (m_edit_fmt_menu);
1819 menu->addMenu (m_edit_nav_menu);
1820 menu->addSeparator ();
1821 menu->addAction (m_run_selection_action);
1822 }
1823
1824 void file_editor::edit_status_update (bool undo, bool redo)
1825 {
1826 if (m_undo_action)
1827 m_undo_action->setEnabled (undo);
1828 m_redo_action->setEnabled (redo);
1829 }
1830
1831 // handler for the close event
1832 void file_editor::closeEvent (QCloseEvent *e)
1833 {
1836 if (settings->value (ed_hiding_closes_files).toBool ())
1837 {
1838 if (check_closing ())
1839 {
1840 // All tabs are closed without cancelling,
1841 // store closing state for restoring session when shown again.
1842 // Editor is closing when session data is stored in preferences
1843 m_closed = true;
1844 e->ignore ();
1845 }
1846 else
1847 {
1848 e->ignore ();
1849 return;
1850 }
1851 }
1852 else
1853 e->accept ();
1854
1856 }
1857
1858 void file_editor::dragEnterEvent (QDragEnterEvent *e)
1859 {
1860 if (e->mimeData ()->hasUrls ())
1861 {
1862 e->acceptProposedAction ();
1863 }
1864 }
1865
1866 void file_editor::dropEvent (QDropEvent *e)
1867 {
1868 if (e->mimeData ()->hasUrls ())
1869 {
1870 for (const auto& url : e->mimeData ()->urls ())
1871 request_open_file (url.toLocalFile ());
1872 }
1873 }
1874
1876 {
1877 // FIXME: is there a way to do this job that doesn't require casting
1878 // the parent to a main_window object?
1879
1880 main_window *w = dynamic_cast<main_window *> (parentWidget ());
1881
1882 if (w)
1883 {
1884 QList<QDockWidget *> w_list = w->tabifiedDockWidgets (this);
1885 QDockWidget *console =
1886 static_cast<QDockWidget *> (w->get_dock_widget_list ().at (0));
1887
1888 for (int i = 0; i < w_list.count (); i++)
1889 {
1890 if (w_list.at (i) == console)
1891 return true;
1892 }
1893 }
1894
1895 return false;
1896 }
1897
1899 {
1900 QWidget *editor_widget = new QWidget (this);
1901
1902 // FIXME: what was the intended purpose of this unused variable?
1903 // QStyle *editor_style = QApplication::style ();
1904
1905 // Menu bar: do not set it native, required in macOS and Ubuntu Unity (Qt5)
1906 // for a visible menu bar in the editor widget. This property is ignored
1907 // on other platforms.
1908 m_menu_bar = new QMenuBar (editor_widget);
1909 m_menu_bar->setNativeMenuBar (false);
1910
1911 m_tool_bar = new QToolBar (editor_widget);
1912 m_tool_bar->setMovable (true);
1913
1914 m_tab_widget = new file_editor_tab_widget (editor_widget, this);
1915
1917
1918 // the mru-list and an empty array of actions
1920 m_mru_files = settings->value (ed_mru_file_list).toStringList ();
1922 .toStringList ();
1923
1924 if (m_mru_files_encodings.count () != m_mru_files.count ())
1925 {
1926 // encodings don't have the same count -> do not use them!
1927 m_mru_files_encodings = QStringList ();
1928 for (int i = 0; i < m_mru_files.count (); i++)
1929 m_mru_files_encodings << QString ();
1930 }
1931
1932 for (int i = 0; i < MaxMRUFiles; ++i)
1933 {
1934 m_mru_file_actions[i] = new QAction (this);
1935 m_mru_file_actions[i]->setVisible (false);
1936 }
1937
1938 // menu bar
1939
1940 // file menu
1941
1942 m_fileMenu = add_menu (m_menu_bar, tr ("&File"));
1943
1944 // new and open menus are inserted later by the main window
1945 m_mru_file_menu = new QMenu (tr ("&Recent Editor Files"), m_fileMenu);
1946 for (int i = 0; i < MaxMRUFiles; ++i)
1947 m_mru_file_menu->addAction (m_mru_file_actions[i]);
1948 m_fileMenu->addMenu (m_mru_file_menu);
1949
1950 m_fileMenu->addSeparator ();
1951
1954 tr ("&Edit Function"),
1955 SLOT (request_context_edit (bool)));
1956
1957 m_fileMenu->addSeparator ();
1958
1960 = add_action (m_fileMenu, rmgr.icon ("document-save"),
1961 tr ("&Save File"), SLOT (request_save_file (bool)));
1962
1964 = add_action (m_fileMenu, rmgr.icon ("document-save-as"),
1965 tr ("Save File &As..."),
1966 SLOT (request_save_file_as (bool)));
1967
1968 m_fileMenu->addSeparator ();
1969
1971 = add_action (m_fileMenu, rmgr.icon ("window-close", false),
1972 tr ("&Close"), SLOT (request_close_file (bool)));
1973
1975 = add_action (m_fileMenu, rmgr.icon ("window-close", false),
1976 tr ("Close All"), SLOT (request_close_all_files (bool)));
1977
1979 = add_action (m_fileMenu, rmgr.icon ("window-close", false),
1980 tr ("Close Other Files"),
1981 SLOT (request_close_other_files (bool)));
1982
1983 m_fileMenu->addSeparator ();
1984
1986 = add_action (m_fileMenu, rmgr.icon ("document-print"),
1987 tr ("Print..."), SLOT (request_print_file (bool)));
1988
1989 // edit menu (undo, copy, paste and select all later via main window)
1990
1991 m_edit_menu = add_menu (m_menu_bar, tr ("&Edit"));
1992
1994 = add_action (m_edit_menu, rmgr.icon ("edit-redo"),
1995 tr ("&Redo"), SLOT (request_redo (bool)));
1996 m_redo_action->setEnabled (false);
1997
1998 m_edit_menu->addSeparator ();
1999
2001 = add_action (m_edit_menu, rmgr.icon ("edit-cut"),
2002 tr ("Cu&t"), SLOT (request_cut (bool)));
2003 m_cut_action->setEnabled (false);
2004
2006 = add_action (m_edit_menu, rmgr.icon ("edit-find-replace"),
2007 tr ("&Find and Replace..."), SLOT (request_find (bool)));
2008
2010 = add_action (m_edit_menu, tr ("Find &Next..."),
2011 SLOT (request_find_next (bool)));
2012
2014 = add_action (m_edit_menu, tr ("Find &Previous..."),
2015 SLOT (request_find_previous (bool)));
2016
2017 m_edit_menu->addSeparator ();
2018
2019 m_edit_cmd_menu = m_edit_menu->addMenu (tr ("&Commands"));
2020
2022 = add_action (m_edit_cmd_menu, tr ("Delete Line"),
2023 SLOT (request_delete_line (bool)));
2024
2026 = add_action (m_edit_cmd_menu, tr ("Copy Line"),
2027 SLOT (request_copy_line (bool)));
2028
2030 = add_action (m_edit_cmd_menu, tr ("Cut Line"),
2031 SLOT (request_cut_line (bool)));
2032
2033 m_edit_cmd_menu->addSeparator ();
2034
2036 = add_action (m_edit_cmd_menu, tr ("Delete to Start of Word"),
2037 SLOT (request_delete_start_word (bool)));
2038
2040 = add_action (m_edit_cmd_menu, tr ("Delete to End of Word"),
2041 SLOT (request_delete_end_word (bool)));
2042
2044 = add_action (m_edit_cmd_menu, tr ("Delete to Start of Line"),
2045 SLOT (request_delete_start_line (bool)));
2046
2048 = add_action (m_edit_cmd_menu, tr ("Delete to End of Line"),
2049 SLOT (request_delete_end_line (bool)));
2050
2051 m_edit_cmd_menu->addSeparator ();
2052
2054 = add_action (m_edit_cmd_menu, tr ("Duplicate Selection/Line"),
2055 SLOT (request_duplicate_selection (bool)));
2056
2058 = add_action (m_edit_cmd_menu, tr ("Transpose Line"),
2059 SLOT (request_transpose_line (bool)));
2060
2061 m_edit_cmd_menu->addSeparator ();
2062
2064 = add_action (m_edit_cmd_menu, tr ("&Show Completion List"),
2065 SLOT (request_completion (bool)));
2066
2067 m_edit_fmt_menu = m_edit_menu->addMenu (tr ("&Format"));
2068
2070 = add_action (m_edit_fmt_menu, tr ("&Uppercase Selection"),
2071 SLOT (request_upper_case (bool)));
2072
2074 = add_action (m_edit_fmt_menu, tr ("&Lowercase Selection"),
2075 SLOT (request_lower_case (bool)));
2076
2077 m_edit_fmt_menu->addSeparator ();
2078
2080 = add_action (m_edit_fmt_menu, tr ("&Comment"),
2081 SLOT (request_comment_selected_text (bool)));
2082
2084 = add_action (m_edit_fmt_menu, tr ("&Uncomment"),
2085 SLOT (request_uncomment_selected_text (bool)));
2086
2088 = add_action (m_edit_fmt_menu, tr ("Comment (Choosing String)"),
2089 SLOT (request_comment_var_selected_text (bool)));
2090
2091 m_edit_fmt_menu->addSeparator ();
2092
2094 = add_action (m_edit_fmt_menu, tr ("&Indent Selection Rigidly"),
2095 SLOT (request_indent_selected_text (bool)));
2096
2098 = add_action (m_edit_fmt_menu, tr ("&Unindent Selection Rigidly"),
2099 SLOT (request_unindent_selected_text (bool)));
2100
2102 = add_action (m_edit_fmt_menu, tr ("Indent Code"),
2104
2105 m_edit_fmt_menu->addSeparator ();
2106
2109 tr ("Convert Line Endings to &Windows (CRLF)"),
2110 SLOT (request_conv_eol_windows (bool)));
2111
2113 = add_action (m_edit_fmt_menu, tr ("Convert Line Endings to &Unix (LF)"),
2114 SLOT (request_conv_eol_unix (bool)));
2115
2118 tr ("Convert Line Endings to Legacy &Mac (CR)"),
2119 SLOT (request_conv_eol_mac (bool)));
2120
2121 m_edit_nav_menu = m_edit_menu->addMenu (tr ("Navi&gation"));
2122
2124 = add_action (m_edit_nav_menu, tr ("Go &to Line..."),
2125 SLOT (request_goto_line (bool)));
2126
2127 m_edit_cmd_menu->addSeparator ();
2128
2130 = add_action (m_edit_nav_menu, tr ("Move to Matching Brace"),
2131 SLOT (request_move_match_brace (bool)));
2132
2134 = add_action (m_edit_nav_menu, tr ("Select to Matching Brace"),
2135 SLOT (request_sel_match_brace (bool)));
2136
2137 m_edit_nav_menu->addSeparator ();
2138
2140 = add_action (m_edit_nav_menu, tr ("&Next Bookmark"),
2141 SLOT (request_next_bookmark (bool)));
2142
2144 = add_action (m_edit_nav_menu, tr ("Pre&vious Bookmark"),
2145 SLOT (request_previous_bookmark (bool)));
2146
2148 = add_action (m_edit_nav_menu, tr ("Toggle &Bookmark"),
2149 SLOT (request_toggle_bookmark (bool)));
2150
2152 = add_action (m_edit_nav_menu, tr ("&Remove All Bookmarks"),
2153 SLOT (request_remove_bookmark (bool)));
2154
2155 m_edit_menu->addSeparator ();
2156
2158 = add_action (m_edit_menu, rmgr.icon ("preferences-system"),
2159 tr ("&Preferences..."),
2160 SLOT (request_preferences (bool)));
2161
2163 = add_action (m_edit_menu, rmgr.icon ("preferences-system"),
2164 tr ("&Styles Preferences..."),
2165 SLOT (request_styles_preferences (bool)));
2166
2167 // view menu
2168
2169 QMenu *view_menu = add_menu (m_menu_bar, tr ("&View"));
2170
2171 m_view_editor_menu = view_menu->addMenu (tr ("&Editor"));
2172
2174 = add_action (m_view_editor_menu, tr ("Show &Line Numbers"),
2175 SLOT (show_line_numbers (bool)));
2176 m_show_linenum_action->setCheckable (true);
2177
2179 = add_action (m_view_editor_menu, tr ("Show &Whitespace Characters"),
2180 SLOT (show_white_space (bool)));
2181 m_show_whitespace_action->setCheckable (true);
2182
2184 = add_action (m_view_editor_menu, tr ("Show Line &Endings"),
2185 SLOT (show_eol_chars (bool)));
2186 m_show_eol_action->setCheckable (true);
2187
2189 = add_action (m_view_editor_menu, tr ("Show &Indentation Guides"),
2190 SLOT (show_indent_guides (bool)));
2191 m_show_indguide_action->setCheckable (true);
2192
2194 = add_action (m_view_editor_menu, tr ("Show Long Line &Marker"),
2195 SLOT (show_long_line (bool)));
2196 m_show_longline_action->setCheckable (true);
2197
2198 m_view_editor_menu->addSeparator ();
2199
2201 = add_action (m_view_editor_menu, tr ("Show &Toolbar"),
2202 SLOT (show_toolbar (bool)));
2203 m_show_toolbar_action->setCheckable (true);
2204
2206 = add_action (m_view_editor_menu, tr ("Show &Statusbar"),
2207 SLOT (show_statusbar (bool)));
2208 m_show_statusbar_action->setCheckable (true);
2209
2211 = add_action (m_view_editor_menu, tr ("Show &Horizontal Scrollbar"),
2212 SLOT (show_hscrollbar (bool)));
2213 m_show_hscrollbar_action->setCheckable (true);
2214
2215 view_menu->addSeparator ();
2216
2218 = add_action (view_menu, rmgr.icon ("zoom-in"), tr ("Zoom &In"),
2219 SLOT (zoom_in (bool)));
2220
2222 = add_action (view_menu, rmgr.icon ("zoom-out"), tr ("Zoom &Out"),
2223 SLOT (zoom_out (bool)));
2224
2226 = add_action (view_menu, tr ("&Normal Size"), SLOT (zoom_normal (bool)));
2227
2228 view_menu->addSeparator ();
2229
2231 = add_action (view_menu, tr ("&Sort Tabs Alphabetically"),
2232 SLOT (sort_tabs_alph (void)),
2234
2235 m_menu_bar->addMenu (view_menu);
2236
2237 // debug menu
2238
2239 m_debug_menu = add_menu (m_menu_bar, tr ("&Debug"));
2240
2242 = add_action (m_debug_menu, rmgr.icon ("bp-toggle"),
2243 tr ("Toggle &Breakpoint"),
2244 SLOT (request_toggle_breakpoint (bool)));
2245
2247 = add_action (m_debug_menu, rmgr.icon ("bp-next"),
2248 tr ("&Next Breakpoint"),
2249 SLOT (request_next_breakpoint (bool)));
2250
2252 = add_action (m_debug_menu, rmgr.icon ("bp-prev"),
2253 tr ("Pre&vious Breakpoint"),
2254 SLOT (request_previous_breakpoint (bool)));
2255
2257 = add_action (m_debug_menu, rmgr.icon ("bp-rm-all"),
2258 tr ("&Remove All Breakpoints"),
2259 SLOT (request_remove_breakpoint (bool)));
2260
2261 m_debug_menu->addSeparator ();
2262
2263 // The other debug actions will be added by the main window.
2264
2265 // run menu
2266
2267 QMenu *_run_menu = add_menu (m_menu_bar, tr ("&Run"));
2268
2270 = add_action (_run_menu,
2271 rmgr.icon ("system-run"),
2272 tr ("Save File and Run / Continue"),
2273 SLOT (request_run_file (bool)));
2274
2276 = add_action (_run_menu,
2277 tr ("Run &Selection"),
2278 SLOT (request_context_run (bool)));
2279 m_run_selection_action->setEnabled (false);
2280
2281 // help menu
2282
2283 QMenu *_help_menu = add_menu (m_menu_bar, tr ("&Help"));
2284
2286 = add_action (_help_menu,
2287 tr ("&Help on Keyword"),
2288 SLOT (request_context_help (bool)));
2289
2291 = add_action (_help_menu,
2292 tr ("&Documentation on Keyword"),
2293 SLOT (request_context_doc (bool)));
2294
2295 // tab navigation (no menu, only actions; slots in tab_bar)
2296
2298 = add_action (nullptr, "", SLOT (switch_left_tab (void)),
2300
2302 = add_action (nullptr, "", SLOT (switch_right_tab (void)),
2304
2306 = add_action (nullptr, "", SLOT (move_tab_left (void)),
2308
2310 = add_action (nullptr, "", SLOT (move_tab_right (void)),
2312
2313 // toolbar
2314
2315 // popdown menu with mru files
2316 QToolButton *popdown_button = new QToolButton ();
2317 popdown_button->setToolTip (tr ("Recent Files"));
2318 popdown_button->setMenu (m_mru_file_menu);
2319 popdown_button->setPopupMode (QToolButton::InstantPopup);
2320 popdown_button->setArrowType (Qt::DownArrow);
2321 popdown_button->setToolButtonStyle (Qt::ToolButtonTextOnly);
2322
2323 // new and open actions are inserted later from main window
2324 m_popdown_mru_action = m_tool_bar->addWidget (popdown_button);
2325 m_tool_bar->addAction (m_save_action);
2326 m_tool_bar->addAction (m_save_as_action);
2327 m_tool_bar->addAction (m_print_action);
2328 m_tool_bar->addSeparator ();
2329 // m_undo_action: later via main window
2330 m_tool_bar->addAction (m_redo_action);
2331 m_tool_bar->addSeparator ();
2332 m_tool_bar->addAction (m_cut_action);
2333 // m_copy_action: later via the main window
2334 // m_paste_action: later via the main window
2335 m_tool_bar->addAction (m_find_action);
2336 //m_tool_bar->addAction (m_find_next_action);
2337 //m_tool_bar->addAction (m_find_previous_action);
2338 m_tool_bar->addSeparator ();
2339 m_tool_bar->addAction (m_run_action);
2340 m_tool_bar->addSeparator ();
2345
2346 // layout
2347 QVBoxLayout *vbox_layout = new QVBoxLayout ();
2348 vbox_layout->addWidget (m_menu_bar);
2349 vbox_layout->addWidget (m_tool_bar);
2350 vbox_layout->addWidget (m_tab_widget);
2351 vbox_layout->setMargin (0);
2352 vbox_layout->setSpacing (0);
2353 editor_widget->setLayout (vbox_layout);
2354 setWidget (editor_widget);
2355
2356 // Create the basic context menu of the tab bar with editor actions.
2357 // Actions for selecting an tab are added when the menu is activated.
2358 tab_bar *bar = m_tab_widget->get_tab_bar ();
2359 QMenu *ctx_men = bar->get_context_menu ();
2360 ctx_men->addSeparator ();
2361 ctx_men->addAction (m_close_action);
2362 ctx_men->addAction (m_close_all_action);
2363 ctx_men->addAction (m_close_others_action);
2364 ctx_men->addSeparator ();
2365 ctx_men->addAction (m_sort_tabs_action);
2366 add_action (ctx_men, tr ("Copy Full File &Path"),
2367 SLOT (copy_full_file_path (bool)), this);
2368
2369 // signals
2370 connect (m_mru_file_menu, &QMenu::triggered,
2372
2373 mru_menu_update ();
2374
2375 connect (m_tab_widget, &file_editor_tab_widget::tabCloseRequested,
2377
2378 connect (m_tab_widget, &file_editor_tab_widget::currentChanged,
2380
2381 resize (500, 400);
2382 setWindowIcon (QIcon (":/actions/icons/logo.png"));
2383 set_title (tr ("Editor"));
2384
2385 check_actions ();
2386 }
2387
2388 // Slot when autocompletion list was cancelled
2390 {
2391 // List was cancelled but somehow still active and blocking the
2392 // edit area from accepting shortcuts. Only after another keypress
2393 // shortcuts and lists are working againnas expected. This is
2394 // probably caused by qt bug https://bugreports.qt.io/browse/QTBUG-83720
2395 // Hack: Accept the list, which is hidden but still active
2396 // and undo the text insertion, if any
2397
2399 octave_qscintilla *qsci = f->qsci_edit_area ();
2400
2401 int line, col;
2402 qsci->getCursorPosition (&line, &col);
2403 int l1 = qsci->lineLength (line); // Current line length
2404
2405 // Accept autocompletion
2406 qsci->SendScintilla (QsciScintillaBase::SCI_AUTOCCOMPLETE);
2407
2408 // Was text inserted? If yes, undo
2409 if (qsci->text (line).length () - l1)
2410 qsci->undo ();
2411 }
2412
2414 {
2415 // Reset the focus of the tab and the related edit area
2417 = static_cast<file_editor_tab *> (m_tab_widget->currentWidget ());
2418 emit fetab_set_focus (f);
2419 return f;
2420 }
2421
2423 file_editor::make_file_editor_tab (const QString& directory)
2424 {
2425 file_editor_tab *f = new file_editor_tab (m_octave_qobj, directory);
2426
2427 // signals from the qscintilla edit area
2428 connect (f->qsci_edit_area (), &octave_qscintilla::status_update,
2430
2431 connect (f->qsci_edit_area (), &octave_qscintilla::create_context_menu_signal,
2433
2434 connect (f->qsci_edit_area (),
2435 SIGNAL (SCN_AUTOCCOMPLETED (const char *, int, int, int)),
2436 this, SLOT (reset_focus (void)));
2437
2438 connect (f->qsci_edit_area (), SIGNAL (SCN_AUTOCCANCELLED (void)),
2439 this, SLOT (handle_autoc_cancelled (void)));
2440
2441 // signals from the qscintilla edit area
2443 f->qsci_edit_area (), &octave_qscintilla::handle_enter_debug_mode);
2444
2446 f->qsci_edit_area (), &octave_qscintilla::handle_exit_debug_mode);
2447
2448 // Signals from the file editor_tab
2451
2454
2457
2460
2463
2466
2468 this, [=] (const QString& fname, const QString& encoding) { request_open_file (fname, encoding); });
2469
2472
2474 this, &file_editor::set_focus);
2475
2476 // Signals from the file_editor or main-win non-trivial operations
2478 f, [=] (const gui_settings *settings) { f->notice_settings (settings); });
2479
2480 connect (this, &file_editor::fetab_change_request,
2482
2485
2486 // Signals from the file_editor trivial operations
2489
2490 connect (this, &file_editor::fetab_set_directory,
2492
2493 connect (this, &file_editor::fetab_zoom_in,
2495 connect (this, &file_editor::fetab_zoom_out,
2497 connect (this, &file_editor::fetab_zoom_normal,
2499
2500 connect (this, &file_editor::fetab_context_help,
2502
2503 connect (this, &file_editor::fetab_context_edit,
2505
2508
2509 connect (this, &file_editor::fetab_save_file_as,
2511
2512 connect (this, &file_editor::fetab_print_file,
2514
2515 connect (this, &file_editor::fetab_run_file,
2517
2518 connect (this, &file_editor::fetab_context_run,
2520
2521 connect (this, &file_editor::fetab_toggle_bookmark,
2523
2524 connect (this, &file_editor::fetab_next_bookmark,
2526
2529
2530 connect (this, &file_editor::fetab_remove_bookmark,
2532
2535
2536 connect (this, &file_editor::fetab_next_breakpoint,
2538
2541
2544
2547
2550
2553
2556
2559
2562
2563 connect (this, &file_editor::fetab_convert_eol,
2565
2566 connect (this, &file_editor::fetab_goto_line,
2568
2571
2572 connect (this, &file_editor::fetab_completion,
2574
2575 connect (this, &file_editor::fetab_set_focus,
2577
2580
2583
2586
2589
2590 // Convert other signals from the edit area and tab to editor signals.
2591
2592 connect (f->qsci_edit_area (), &octave_qscintilla::execute_command_in_terminal_signal,
2594
2595 connect (f->qsci_edit_area (), &octave_qscintilla::focus_console_after_command_signal,
2597
2600
2603
2606
2607 // Any interpreter_event signal from a file_editor_tab_widget is
2608 // handled the same as for the parent main_window object.
2609
2612
2615
2616 return f;
2617 }
2618
2620 int index)
2621 {
2622 if (index == -1)
2623 m_tab_widget->addTab (f, fn);
2624 else
2625 m_tab_widget->insertTab (index, f, fn);
2626
2627 m_tab_widget->setCurrentWidget (f);
2628
2629 check_actions ();
2630 }
2631
2633 {
2634 int num_files = qMin (m_mru_files.size (), int (MaxMRUFiles));
2635
2636 // configure and show active actions of mru-menu
2637 for (int i = 0; i < num_files; ++i)
2638 {
2639 QString text = QString ("&%1 %2").
2640 arg ((i+1) % int (MaxMRUFiles)).arg (m_mru_files.at (i));
2641 m_mru_file_actions[i]->setText (text);
2642
2643 QStringList action_data;
2644 action_data << m_mru_files.at (i) << m_mru_files_encodings.at (i);
2645 m_mru_file_actions[i]->setData (action_data);
2646
2647 m_mru_file_actions[i]->setVisible (true);
2648 }
2649
2650 // hide unused mru-menu entries
2651 for (int j = num_files; j < MaxMRUFiles; ++j)
2652 m_mru_file_actions[j]->setVisible (false);
2653
2654 // delete entries in string-list beyond MaxMRUFiles
2655 while (m_mru_files.size () > MaxMRUFiles)
2656 {
2657 m_mru_files.removeLast ();
2658 m_mru_files_encodings.removeLast ();
2659 }
2660
2661 // save actual mru-list in settings
2664
2667 settings->sync ();
2668 }
2669
2670 bool file_editor::call_custom_editor (const QString& file_name, int line)
2671 {
2672 // Check if the user wants to use a custom file editor.
2675
2677 global_use_custom_editor.def).toBool ())
2678 {
2679 // use the external editor interface for handling the call
2680 emit request_open_file_external (file_name, line);
2681
2682 if (line < 0 && ! file_name.isEmpty ())
2683 handle_mru_add_file (QFileInfo (file_name).canonicalFilePath (),
2684 QString ());
2685
2686 return true;
2687 }
2688
2689 return false;
2690 }
2691
2693 {
2696
2697 bool old = settings->value (preference).toBool ();
2698 settings->setValue (preference.key, ! old);
2700 }
2701
2702 // Function for closing the files in a removed directory
2703 void file_editor::handle_dir_remove (const QString& old_name,
2704 const QString& new_name)
2705 {
2706 QDir old_dir (old_name);
2707 session_data f_data;
2708
2709 std::list<file_editor_tab *> editor_tab_lst = m_tab_widget->tab_list ();
2710
2711 for (auto editor_tab : editor_tab_lst)
2712 {
2713 QString file_name = editor_tab->file_name ();
2714
2715 if (file_name.isEmpty ())
2716 continue; // Nothing to do, no valid file name
2717
2718 // Get abs. file path and its path relative to the removed directory
2719 QString rel_path_to_file = old_dir.relativeFilePath (file_name);
2720 QString abs_path_to_file = old_dir.absoluteFilePath (file_name);
2721
2722 // Test whether the file is located within the directory that will
2723 // be removed. For this, two conditions must be met:
2724 // 1. The path of the file rel. to the dir is not equal to the
2725 // its absolute one.
2726 // If both are equal, then there is no relative path and removed
2727 // directory and file are on different drives (e.g. on windows)
2728 // 2. The (real) relative path does not start with "../", i.e.,
2729 // the file can be reached from the directory by descending only
2730 if ((rel_path_to_file != abs_path_to_file)
2731 && (rel_path_to_file.left (3) != QString ("../")))
2732 {
2733 // The currently considered file is included in the
2734 // removed/renamed diectory: Delete it.
2735 m_no_focus = true; // Remember for not focussing editor
2736
2737 if (editor_tab)
2738 {
2739 // Get index and line
2740 int l, c;
2741 editor_tab->qsci_edit_area ()->getCursorPosition (&l, &c);
2742 f_data.line = l + 1;
2743 f_data.index = m_tab_widget->indexOf (editor_tab);
2744 // Close
2745 editor_tab->file_has_changed (QString (), true);
2746 }
2747 m_no_focus = false; // Back to normal
2748
2749 // Store file for possible later reload
2750 f_data.file_name = file_name;
2751
2752 // Add the new file path and the encoding for later reloading
2753 // if new_name is given
2754 if (! new_name.isEmpty ())
2755 {
2756 QDir new_dir (new_name);
2757 QString append_to_new_dir;
2758 if (new_dir.exists ())
2759 {
2760 // The new directory already exists (movefile was used).
2761 // This means, we have to add the name (not the path)
2762 // of the old dir and the relative path to the file
2763 // to new dir.
2764 append_to_new_dir
2765 = old_dir.dirName () + "/" + rel_path_to_file;
2766 }
2767 else
2768 append_to_new_dir = rel_path_to_file;
2769
2770 f_data.new_file_name
2771 = new_dir.absoluteFilePath (append_to_new_dir);
2772 }
2773 else
2774 f_data.new_file_name = ""; // no new name, just removing this file
2775
2776 f_data.encoding = editor_tab->encoding (); // store the encoding
2777
2778 // Store data in list for later reloading
2779 m_tmp_closed_files << f_data;
2780 }
2781 }
2782 }
2783
2785 {
2786 QWidget *foc_w = focusWidget ();
2787 if (foc_w && foc_w->inherits ("octave::octave_qscintilla"))
2788 return true;
2789 return false;
2790 }
2791
2792 // Check whether this file is already open in the editor.
2794 {
2795 std::string std_file = file.toStdString ();
2796
2797 std::list<file_editor_tab *> fe_tab_lst = m_tab_widget->tab_list ();
2798
2799 for (auto fe_tab : fe_tab_lst)
2800 {
2801 QString tab_file = fe_tab->file_name ();
2802
2803 // We check file == tab_file because
2804 //
2805 // same_file ("", "")
2806 //
2807 // is false
2808
2809 if (same_file (std_file, tab_file.toStdString ()) || file == tab_file)
2810 return fe_tab;
2811 }
2812
2813 return nullptr;
2814 }
2815
2816 QAction * file_editor::add_action (QMenu *menu, const QString& text,
2817 const char *member,
2818 QWidget *receiver)
2819 {
2820 return add_action (menu, QIcon (), text, member, receiver);
2821 }
2822
2823 QAction * file_editor::add_action (QMenu *menu, const QIcon& icon,
2824 const QString& text, const char *member,
2825 QWidget *receiver)
2826 {
2827 QAction *a;
2828 QWidget *r = this;
2829
2830 if (receiver != nullptr)
2831 r = receiver;
2832
2833 if (menu)
2834 a = menu->addAction (icon, text, r, member);
2835 else
2836 {
2837 a = new QAction (this);
2838 connect (a, SIGNAL (triggered ()), r, member);
2839 }
2840
2841 addAction (a); // important for shortcut context
2842 a->setShortcutContext (Qt::WidgetWithChildrenShortcut);
2843
2844 return a;
2845 }
2846
2848 {
2849 QMenu *menu = p->addMenu (name);
2850
2851 QString base_name = name; // get a copy
2852 // replace intended '&' ("&&") by a temp. string
2853 base_name.replace ("&&", "___octave_amp_replacement___");
2854 // remove single '&' (shortcut)
2855 base_name.remove ("&");
2856 // restore intended '&'
2857 base_name.replace ("___octave_amp_replacement___", "&&");
2858
2859 // remember names with and without shortcut
2860 m_hash_menu_text[menu] = QStringList () << name << base_name;
2861
2862 return menu;
2863 }
2864}
2865
2866#endif
tree_evaluator & get_evaluator(void)
Base class for Octave interfaces that use Qt.
shortcut_manager & get_shortcut_manager(void)
resource_manager & get_resource_manager(void)
void interpreter_event(const fcn_callback &fcn)
file_editor_tab_widget(QWidget *p, file_editor *fe)
Definition: file-editor.cc:70
tab_bar * get_tab_bar(void) const
Definition: file-editor.cc:85
std::list< file_editor_tab * > tab_list(void) const
Definition: file-editor.cc:91
void set_encoding(const QString &new_encoding)
void goto_line(const QWidget *ID, int line=-1)
void toggle_breakpoint(const QWidget *ID)
void zoom_out(const QWidget *ID)
void delete_debugger_pointer(const QWidget *ID, int line=-1)
void run_file(const QWidget *ID, bool step_into=false)
void save_file_as(const QWidget *ID)
void tab_ready_to_close(void)
void set_current_directory(const QString &dir)
void zoom_normal(const QWidget *ID)
void set_focus_editor_signal(QWidget *)
void editor_check_conflict_save(const QString &saveFileName, bool remove_on_success)
void interpreter_event(const fcn_callback &fcn)
QString load_file(const QString &fileName)
void next_bookmark(const QWidget *ID)
void previous_breakpoint(const QWidget *ID)
void update_lexer_settings(bool update_apis_only=false)
void convert_eol(const QWidget *ID, QsciScintilla::EolMode)
void save_file(const QWidget *ID)
void toggle_bookmark(const QWidget *ID)
octave_qscintilla * qsci_edit_area(void)
void set_focus(const QWidget *ID)
void unindent_selected_text(const QWidget *ID)
void update_window_title(bool modified)
void do_breakpoint_marker(bool insert, const QWidget *ID, int line=-1, const QString &cond="")
void insert_debugger_pointer(const QWidget *ID, int line=-1)
void move_match_brace(const QWidget *ID, bool select)
void next_breakpoint(const QWidget *ID)
void edit_mfile_request(const QString &, const QString &, const QString &, int)
void previous_bookmark(const QWidget *ID)
void editor_state_changed(bool copy_available, bool is_octave_file, bool is_modified)
void print_file(const QWidget *ID)
void run_file_signal(const QFileInfo &info)
void indent_selected_text(const QWidget *ID)
void file_name_changed(const QString &fileName, const QString &toolTip, bool modified)
void smart_indent_line_or_selected_text(const QWidget *ID)
void context_edit(const QWidget *ID)
void uncomment_selected_text(const QWidget *ID)
void tab_remove_request(void)
void context_help(const QWidget *ID, bool)
void remove_bookmark(const QWidget *ID)
void remove_all_breakpoints(const QWidget *ID)
void debug_quit_signal(void)
void context_run(const QWidget *ID)
void scintilla_command(const QWidget *, unsigned int)
void comment_selected_text(const QWidget *ID, bool input_str)
void change_editor_state(const QWidget *ID)
void edit_area_changed(octave_qscintilla *edit_area)
void zoom_in(const QWidget *ID)
void file_has_changed(const QString &path, bool do_close=false)
QString encoding(void) const
void mru_add_file(const QString &file_name, const QString &encoding)
void request_open_file(const QString &, const QString &=QString())
QString file_name(void) const
void new_file(const QString &commands=QString())
void show_auto_completion(const QWidget *ID)
QAction * m_delete_start_word_action
Definition: file-editor.h:407
void request_find_previous(bool)
Definition: file-editor.cc:938
QAction * m_move_tab_left_action
Definition: file-editor.h:451
void request_close_other_files(bool)
Definition: file-editor.cc:594
void fetab_next_bookmark(const QWidget *ID)
void focus_console_after_command_signal(void)
QAction * m_upper_case_action
Definition: file-editor.h:376
QAction * m_previous_breakpoint_action
Definition: file-editor.h:457
void zoom_normal(bool)
void empty_script(bool startup, bool visible)
Definition: file-editor.cc:257
QAction * m_conv_eol_windows_action
Definition: file-editor.h:384
QAction * m_sel_to_matching_brace
Definition: file-editor.h:425
QAction * m_show_indguide_action
Definition: file-editor.h:398
void handle_update_breakpoint_marker_request(bool insert, const QString &file, int line, const QString &cond)
bool check_closing(void)
Definition: file-editor.cc:473
void fetab_zoom_out(const QWidget *ID)
void request_find_next(bool)
Definition: file-editor.cc:932
void handle_tab_close_request(int index)
Definition: file-editor.cc:982
QAction * m_close_action
Definition: file-editor.h:439
QAction * m_switch_right_tab_action
Definition: file-editor.h:450
void fetab_previous_bookmark(const QWidget *ID)
void request_styles_preferences(bool)
QAction * m_transpose_line_action
Definition: file-editor.h:415
void request_step_into_file()
Definition: file-editor.cc:688
QAction * m_indent_selection_action
Definition: file-editor.h:381
QAction * m_completion_action
Definition: file-editor.h:422
void request_mru_open_file(QAction *action)
Definition: file-editor.cc:621
void fetab_zoom_in(const QWidget *ID)
QAction * m_close_others_action
Definition: file-editor.h:441
QAction * m_smart_indent_line_or_selection_action
Definition: file-editor.h:383
QPointer< find_dialog > m_find_dialog
Definition: file-editor.h:487
void request_open_file(const QString &fileName, const QString &encoding=QString(), int line=-1, bool debug_pointer=false, bool breakpoint_marker=false, bool insert=true, const QString &cond="", int index=-1)
QAction * m_save_action
Definition: file-editor.h:437
QAction * m_run_action
Definition: file-editor.h:432
QAction * m_lower_case_action
Definition: file-editor.h:377
QAction * m_paste_action
Definition: file-editor.h:390
QAction * m_print_action
Definition: file-editor.h:431
QAction * m_conv_eol_mac_action
Definition: file-editor.h:386
file_editor(QWidget *p, base_qobject &oct_qobj)
Definition: file-editor.cc:102
void fetab_remove_bookmark(const QWidget *ID)
void request_close_file(bool)
Definition: file-editor.cc:575
void request_delete_end_line(bool)
Definition: file-editor.cc:768
void handle_file_remove(const QString &, const QString &)
void request_move_match_brace(bool)
Definition: file-editor.cc:718
QAction * m_context_doc_action
Definition: file-editor.h:393
QList< session_data > m_tmp_closed_files
Definition: file-editor.h:490
void toggle_preference(const gui_pref &preference)
void fetab_set_directory(const QString &dir)
QAction * m_preferences_action
Definition: file-editor.h:446
file_editor_tab_widget * m_tab_widget
Definition: file-editor.h:472
void request_next_breakpoint(bool)
Definition: file-editor.cc:734
void fetab_context_help(const QWidget *ID, bool)
QAction * m_remove_all_breakpoints_action
Definition: file-editor.h:458
void enable_menu_shortcuts(bool)
Definition: file-editor.cc:395
void find_create(void)
Definition: file-editor.cc:882
void edit_area_changed(octave_qscintilla *edit_area)
void edit_mfile_request(const QString &, const QString &, const QString &, int)
void exit_debug_mode_signal(void)
void request_conv_eol_unix(bool)
Definition: file-editor.cc:853
QAction * m_move_to_matching_brace
Definition: file-editor.h:424
QAction * m_unindent_selection_action
Definition: file-editor.h:382
void request_open_file_external(const QString &file_name, int line)
QAction * m_selectall_action
Definition: file-editor.h:391
void fetab_context_run(const QWidget *ID)
QAction * m_cut_line_action
Definition: file-editor.h:413
void request_upper_case(bool)
Definition: file-editor.cc:820
bool call_custom_editor(const QString &file_name=QString(), int line=-1)
QAction * m_next_breakpoint_action
Definition: file-editor.h:456
void handle_exit_debug_mode(void)
Definition: file-editor.cc:197
QAction * m_show_statusbar_action
Definition: file-editor.h:401
QAction * m_edit_function_action
Definition: file-editor.h:435
void fetab_delete_debugger_pointer(const QWidget *ID, int line=-1)
void show_hscrollbar(bool)
void request_next_bookmark(bool)
Definition: file-editor.cc:703
void insert_global_actions(QList< QAction * >)
Definition: file-editor.cc:147
void fetab_previous_breakpoint(const QWidget *ID)
void closeEvent(QCloseEvent *event)
void request_delete_start_line(bool)
Definition: file-editor.cc:762
void handle_delete_debugger_pointer_request(const QString &file, int line)
QAction * m_run_selection_action
Definition: file-editor.h:433
QAction * m_undo_action
Definition: file-editor.h:444
void fetab_unindent_selected_text(const QWidget *ID)
bool is_editor_console_tabbed(void)
void request_new_file(const QString &commands)
Definition: file-editor.cc:558
void copy_full_file_path(bool)
Definition: file-editor.cc:611
void handle_file_renamed(bool load_new=true)
QMenu * add_menu(QMenuBar *p, QString text)
void request_remove_breakpoint(bool)
Definition: file-editor.cc:744
void set_focus(QWidget *fet)
Definition: file-editor.cc:384
QAction * m_delete_end_line_action
Definition: file-editor.h:410
QAction * m_uncomment_selection_action
Definition: file-editor.h:380
QAction * m_find_files_action
Definition: file-editor.h:420
QAction * m_duplicate_selection_action
Definition: file-editor.h:414
void request_find(bool)
Definition: file-editor.cc:866
void request_unindent_selected_text(bool)
Definition: file-editor.cc:837
QAction * m_delete_end_word_action
Definition: file-editor.h:408
void execute_command_in_terminal_signal(const QString &)
void request_lower_case(bool)
Definition: file-editor.cc:826
void request_context_run(bool)
Definition: file-editor.cc:693
void request_save_file_as(bool)
Definition: file-editor.cc:667
bool editor_tab_has_focus(void)
void fetab_context_edit(const QWidget *ID)
QAction * m_remove_bookmark_action
Definition: file-editor.h:429
QAction * m_copy_line_action
Definition: file-editor.h:412
void show_eol_chars(bool)
void handle_insert_debugger_pointer_request(const QString &file, int line)
void active_tab_changed(int index)
void fetab_scintilla_command(const QWidget *ID, unsigned int sci_msg)
QAction * m_find_next_action
Definition: file-editor.h:418
QAction * m_conv_eol_unix_action
Definition: file-editor.h:385
void edit_status_update(bool, bool)
void update_octave_directory(const QString &dir)
void set_shortcuts(void)
void dropEvent(QDropEvent *event)
void enter_debug_mode_signal(void)
QAction * m_copy_action
Definition: file-editor.h:388
void fetab_do_breakpoint_marker(bool insert, const QWidget *ID, int line=-1, const QString &="")
QAction * m_show_longline_action
Definition: file-editor.h:399
void show_long_line(bool)
QAction * m_next_bookmark_action
Definition: file-editor.h:426
void request_previous_breakpoint(bool)
Definition: file-editor.cc:739
void editor_tabs_changed_signal(bool, bool)
QAction * add_action(QMenu *menu, const QString &text, const char *member, QWidget *receiver=nullptr)
void request_toggle_breakpoint(bool)
Definition: file-editor.cc:729
QAction * m_comment_selection_action
Definition: file-editor.h:378
void check_actions(void)
Definition: file-editor.cc:206
QAction * m_popdown_mru_action
Definition: file-editor.h:436
void update_gui_lexer_signal(bool)
void request_delete_end_word(bool)
Definition: file-editor.cc:756
QAction * m_previous_bookmark_action
Definition: file-editor.h:427
void request_conv_eol_windows(bool)
Definition: file-editor.cc:847
QAction * m_move_tab_right_action
Definition: file-editor.h:452
void request_dbcont_signal(void)
void fetab_move_match_brace(const QWidget *ID, bool select)
void show_toolbar(bool)
void request_settings_dialog(const QString &)
void request_conv_eol_mac(bool)
Definition: file-editor.cc:859
void request_cut_line(bool)
Definition: file-editor.cc:786
void fetab_smart_indent_line_or_selected_text(const QWidget *ID)
void handle_tab_ready_to_close(void)
Definition: file-editor.cc:523
void request_save_file(bool)
Definition: file-editor.cc:662
void request_comment_selected_text(bool)
Definition: file-editor.cc:804
void fetab_toggle_bookmark(const QWidget *ID)
void run_file_signal(const QFileInfo &)
QAction * m_mru_file_actions[MaxMRUFiles]
Definition: file-editor.h:483
void fetab_insert_debugger_pointer(const QWidget *ID, int line=-1)
void create_context_menu(QMenu *)
QAction * m_find_action
Definition: file-editor.h:417
void add_file_editor_tab(file_editor_tab *f, const QString &fn, int index=-1)
void dragEnterEvent(QDragEnterEvent *event)
void fetab_save_file(const QWidget *ID, const QString &fileName, bool remove_on_success)
QAction * m_switch_left_tab_action
Definition: file-editor.h:449
void request_delete_start_word(bool)
Definition: file-editor.cc:750
void request_run_file(bool)
Definition: file-editor.cc:672
void debug_quit_signal(void)
void request_redo(bool)
Definition: file-editor.cc:635
QStringList m_mru_files_encodings
Definition: file-editor.h:485
void request_close_all_files(bool)
Definition: file-editor.cc:582
void show_indent_guides(bool)
void request_context_doc(bool)
Definition: file-editor.cc:652
QAction * m_redo_action
Definition: file-editor.h:443
QAction * m_delete_start_line_action
Definition: file-editor.h:409
void handle_mru_add_file(const QString &file_name, const QString &encoding)
void fetab_uncomment_selected_text(const QWidget *ID)
void request_comment_var_selected_text(bool)
Definition: file-editor.cc:814
void fetab_goto_line(const QWidget *ID, int line=-1)
void request_cut(bool)
Definition: file-editor.cc:641
QAction * m_goto_line_action
Definition: file-editor.h:421
void request_completion(bool)
Definition: file-editor.cc:949
void handle_dir_remove(const QString &old_name, const QString &new_name)
void request_delete_line(bool)
Definition: file-editor.cc:774
void show_statusbar(bool)
void request_toggle_bookmark(bool)
Definition: file-editor.cc:698
QAction * m_save_as_action
Definition: file-editor.h:438
QMenuBar * m_menu_bar
Definition: file-editor.h:368
void file_loaded_signal(void)
void check_conflict_save(const QString &fileName, bool remove_on_success)
void fetab_zoom_normal(const QWidget *ID)
void fetab_settings_changed(const gui_settings *settings)
void mru_menu_update(void)
void restore_session(gui_settings *settings)
Definition: file-editor.cc:321
void handle_autoc_cancelled(void)
QAction * m_cut_action
Definition: file-editor.h:389
QAction * m_show_whitespace_action
Definition: file-editor.h:396
void handle_edit_file_request(const QString &file)
QAction * m_show_hscrollbar_action
Definition: file-editor.h:402
file_editor_tab * make_file_editor_tab(const QString &directory="")
QHash< QMenu *, QStringList > m_hash_menu_text
Definition: file-editor.h:364
void request_context_edit(bool)
Definition: file-editor.cc:657
QAction * m_show_toolbar_action
Definition: file-editor.h:400
QAction * m_context_help_action
Definition: file-editor.h:392
void fetab_save_file_as(const QWidget *ID)
void focusInEvent(QFocusEvent *e)
Definition: file-editor.cc:133
void notice_settings(const gui_settings *settings)
void fetab_print_file(const QWidget *ID)
QToolBar * m_tool_bar
Definition: file-editor.h:369
void pasteClipboard(void)
void request_duplicate_selection(bool)
Definition: file-editor.cc:792
QAction * m_close_all_action
Definition: file-editor.h:440
void show_white_space(bool)
void fetab_convert_eol(const QWidget *ID, QsciScintilla::EolMode eol_mode)
QAction * m_zoom_in_action
Definition: file-editor.h:403
void copyClipboard(void)
void request_sel_match_brace(bool)
Definition: file-editor.cc:723
QAction * m_zoom_out_action
Definition: file-editor.h:404
void handle_visibility(bool visible)
void request_smart_indent_line_or_selected_text(void)
Definition: file-editor.cc:842
QAction * m_zoom_normal_action
Definition: file-editor.h:405
void fetab_next_breakpoint(const QWidget *ID)
void request_transpose_line(bool)
Definition: file-editor.cc:798
QAction * m_find_previous_action
Definition: file-editor.h:419
void fetab_run_file(const QWidget *ID, bool step_into=false)
QAction * m_toggle_breakpoint_action
Definition: file-editor.h:455
QAction * m_toggle_bookmark_action
Definition: file-editor.h:428
void request_context_help(bool)
Definition: file-editor.cc:647
void handle_editor_state_changed(bool enableCopy, bool is_octave_file, bool is_modified)
void request_copy_line(bool)
Definition: file-editor.cc:780
void request_remove_bookmark(bool)
Definition: file-editor.cc:713
file_editor_tab * reset_focus(void)
void show_line_numbers(bool)
QAction * m_delete_line_action
Definition: file-editor.h:411
void request_preferences(bool)
QAction * m_show_eol_action
Definition: file-editor.h:397
QAction * m_show_linenum_action
Definition: file-editor.h:395
void fetab_completion(const QWidget *)
void fetab_change_request(const QWidget *ID)
void fetab_recover_from_exit(void)
void fetab_remove_all_breakpoints(const QWidget *ID)
void fetab_comment_selected_text(const QWidget *ID, bool)
QAction * m_sort_tabs_action
Definition: file-editor.h:453
void request_indent_selected_text(bool)
Definition: file-editor.cc:832
void fetab_set_focus(const QWidget *ID)
void handle_file_name_changed(const QString &fileName, const QString &toolTip, bool modified)
Definition: file-editor.cc:954
QAction * m_comment_var_selection_action
Definition: file-editor.h:379
void request_print_file(bool)
Definition: file-editor.cc:630
file_editor_tab * find_tab_widget(const QString &openFileName)
QAction * m_styles_preferences_action
Definition: file-editor.h:447
QStringList m_mru_files
Definition: file-editor.h:484
void request_previous_bookmark(bool)
Definition: file-editor.cc:708
void request_uncomment_selected_text(bool)
Definition: file-editor.cc:809
void handle_tab_remove_request(void)
Definition: file-editor.cc:990
void handle_enter_debug_mode(void)
Definition: file-editor.cc:182
QMenu * m_view_editor_menu
Definition: file-editor.h:470
void fetab_toggle_breakpoint(const QWidget *ID)
void toplevel_change(bool toplevel)
void fetab_indent_selected_text(const QWidget *ID)
void request_goto_line(bool)
Definition: file-editor.cc:944
void save_session(void)
Definition: file-editor.cc:434
void set_title(const QString &)
Represents the main window.
Definition: main-window.h:73
virtual void closeEvent(QCloseEvent *e)
virtual void handle_visibility(bool visible)
void focus_console_after_command_signal(void)
void status_update(bool, bool)
void create_context_menu_signal(QMenu *)
void execute_command_in_terminal_signal(const QString &)
gui_settings * get_settings(void) const
QIcon icon(const QString &icon_name, bool fallback=true)
void set_shortcut(QAction *action, const sc_pref &scpref, bool enable=true)
static std::string make_absolute(const std::string &s, const std::string &dot_path=get_current_directory())
Definition: oct-env.cc:131
void close_current_tab_signal(bool)
void set_rotated(int rotated)
Definition: tab-bar.cc:45
QMenu * get_context_menu(void)
Definition: tab-bar.h:55
bool in_debug_repl(void) const
Definition: pt-eval.cc:4843
QString name
const gui_pref ed_tabs_rotated("editor/tabs_rotated", QVariant(false))
const gui_pref ed_show_hscroll_bar("editor/show_hscroll_bar", QVariant(true))
const gui_pref ed_show_toolbar("editor/show_toolbar", QVariant(true))
const gui_pref ed_show_white_space("editor/show_white_space", QVariant(false))
const gui_pref ed_create_new_file("editor/create_new_file", QVariant(false))
const gui_pref ed_mru_file_encodings("editor/mru_file_encodings", QVariant())
const gui_pref ed_session_names("editor/savedSessionTabs", QVariant(QStringList()))
const gui_pref ed_tabs_max_width("editor/tabs_max_width", QVariant(0))
const gui_pref ed_long_line_marker("editor/long_line_marker", QVariant(true))
const gui_pref ed_tab_position("editor/tab_position", QVariant(QTabWidget::North))
const gui_pref ed_show_edit_status_bar("editor/show_edit_status_bar", QVariant(true))
const gui_pref ed_restore_session("editor/restoreSession", QVariant(true))
const gui_pref ed_mru_file_list("editor/mru_file_list", QVariant())
const gui_pref ed_show_dbg_file("editor/show_dbg_file", QVariant(true))
const gui_pref ed_session_ind("editor/saved_session_tab_index", QVariant(QStringList()))
const gui_pref ed_show_line_numbers("editor/showLineNumbers", QVariant(true))
const gui_pref ed_show_eol_chars("editor/show_eol_chars", QVariant(false))
const gui_pref ed_session_lines("editor/saved_session_lines", QVariant(QStringList()))
const gui_pref ed_show_indent_guides("editor/show_indent_guides", QVariant(false))
const gui_pref ed_hiding_closes_files("editor/hiding_closes_files", QVariant(false))
const gui_pref ed_session_enc("editor/saved_session_encodings", QVariant(QStringList()))
const QStyle::PixelMetric global_icon_sizes[3]
const gui_pref global_use_custom_editor("useCustomFileEditor", QVariant(false))
const gui_pref global_icon_size("toolbar_icon_size", QVariant(0))
const sc_pref sc_edit_view_show_long_line(sc_edit_view+":show_long_line", QKeySequence::UnknownKey)
const sc_pref sc_edit_file_close(sc_edit_file_cl, QKeySequence::Close)
const sc_pref sc_edit_edit_completion_list(sc_edit_edit+":completion_list", CTRL+Qt::Key_Space)
const sc_pref sc_edit_debug_next_breakpoint(sc_edit_debug+":next_breakpoint", QKeySequence::UnknownKey)
const sc_pref sc_edit_debug_previous_breakpoint(sc_edit_debug+":previous_breakpoint", QKeySequence::UnknownKey)
const sc_pref sc_edit_edit_delete_line(sc_edit_edit+":delete_line", CTRL_SHIFT+Qt::Key_L)
const sc_pref sc_edit_edit_move_to_brace(sc_edit_edit+":move_to_brace", CTRL+Qt::Key_M)
const sc_pref sc_edit_edit_toggle_bookmark(sc_edit_edit+":toggle_bookmark", PRE+Qt::Key_F7)
const sc_pref sc_edit_edit_delete_start_line(sc_edit_edit+":delete_start_line", CTRL_SHIFT+Qt::Key_Backspace)
const sc_pref sc_edit_edit_uncomment_selection(sc_edit_edit+":uncomment_selection", CTRL_SHIFT+Qt::Key_R)
const sc_pref sc_edit_edit_cut_line(sc_edit_edit+":cut_line", CTRL_SHIFT+Qt::Key_X)
const sc_pref sc_edit_view_show_hscrollbar(sc_edit_view+":show_hscrollbar", QKeySequence::UnknownKey)
const sc_pref sc_edit_edit_remove_bookmark(sc_edit_edit+":remove_bookmark", QKeySequence::UnknownKey)
const sc_pref sc_edit_edit_upper_case(sc_edit_edit+":upper_case", CTRL+Qt::Key_U)
const sc_pref sc_edit_file_save(sc_edit_file+":save", QKeySequence::Save)
const sc_pref sc_edit_edit_styles_preferences(sc_edit_edit+":styles_preferences", QKeySequence::UnknownKey)
const sc_pref sc_edit_file_print(sc_edit_file+":print", QKeySequence::Print)
const sc_pref sc_edit_edit_goto_line(sc_edit_edit+":goto_line", CTRL+Qt::Key_L)
const sc_pref sc_edit_edit_smart_indent_line_or_selection(sc_edit_edit+":smart_indent_line_or_selection", QKeySequence::UnknownKey)
const sc_pref sc_main_debug_continue(sc_main_debug+":continue", PRE+Qt::Key_F5)
const sc_pref sc_edit_view_show_statusbar(sc_edit_view+":show_statusbar", QKeySequence::UnknownKey)
const sc_pref sc_edit_view_show_eol_chars(sc_edit_view+":show_eol_chars", QKeySequence::UnknownKey)
const sc_pref sc_edit_file_edit_function(sc_edit_file+":edit_function", CTRL+Qt::Key_E)
const sc_pref sc_edit_edit_comment_selection(sc_edit_edit+":comment_selection", CTRL+Qt::Key_R)
const sc_pref sc_edit_edit_comment_var_selection(sc_edit_edit+":comment_var_selection", CTRL_ALT+Qt::Key_R)
const sc_pref sc_edit_run_run_file(sc_edit_run+":run_file", PRE+Qt::Key_F5)
const sc_pref sc_edit_file_save_as(sc_edit_file+":save_as", QKeySequence::SaveAs)
const sc_pref sc_edit_view_zoom_normal(sc_edit_view_zoom+"_normal", CTRL+Qt::Key_Period)
const sc_pref sc_edit_edit_find_replace(sc_edit_edit_find+"_replace", QKeySequence::Find)
const sc_pref sc_edit_view_show_ind_guides(sc_edit_view+":show_ind_guides", QKeySequence::UnknownKey)
const sc_pref sc_edit_file_close_other(sc_edit_file_cl+"_other", QKeySequence::UnknownKey)
const sc_pref sc_edit_edit_copy_line(sc_edit_edit+":copy_line", CTRL_SHIFT+Qt::Key_C)
const sc_pref sc_edit_edit_transpose_line(sc_edit_edit+":transpose_line", CTRL+Qt::Key_T)
const sc_pref sc_edit_edit_find_next(sc_edit_edit_find+"_next", QKeySequence::FindNext)
const sc_pref sc_edit_help_help_keyword(sc_edit_help+":help_keyword", QKeySequence::HelpContents)
const sc_pref sc_edit_edit_duplicate_selection(sc_edit_edit+":duplicate_selection", CTRL+Qt::Key_D)
const sc_pref sc_edit_view_show_toolbar(sc_edit_view+":show_toolbar", QKeySequence::UnknownKey)
const sc_pref sc_edit_help_doc_keyword(sc_edit_help+":doc_keyword", Qt::SHIFT+Qt::Key_F1)
const sc_pref sc_edit_edit_delete_end_line(sc_edit_edit+":delete_end_line", CTRL_SHIFT+Qt::Key_Delete)
const sc_pref sc_edit_tabs_move_tab_right(sc_edit_tabs+":move_tab_right", Qt::AltModifier+Qt::Key_PageDown)
const sc_pref sc_edit_edit_cut(sc_edit_edit+":cut", QKeySequence::Cut)
const sc_pref sc_edit_debug_remove_breakpoints(sc_edit_debug+":remove_breakpoints", QKeySequence::UnknownKey)
const sc_pref sc_edit_edit_unindent_selection(sc_edit_edit+":unindent_selection", CTRL_SHIFT+Qt::Key_Tab)
const sc_pref sc_edit_edit_next_bookmark(sc_edit_edit+":next_bookmark", PRE+Qt::Key_F2)
const sc_pref sc_edit_run_run_selection(sc_edit_run+":run_selection", PRE+Qt::Key_F9)
const sc_pref sc_edit_edit_find_previous(sc_edit_edit_find+"_previous", QKeySequence::FindPrevious)
const sc_pref sc_edit_view_show_white_spaces(sc_edit_view+":show_white_spaces", QKeySequence::UnknownKey)
const sc_pref sc_edit_file_close_all(sc_edit_file_cl+"_all", QKeySequence::UnknownKey)
const sc_pref sc_edit_edit_select_to_brace(sc_edit_edit+":select_to_brace", CTRL_SHIFT+Qt::Key_M)
const sc_pref sc_edit_debug_toggle_breakpoint(sc_edit_debug+":toggle_breakpoint", QKeySequence::UnknownKey)
const sc_pref sc_edit_edit_lower_case(sc_edit_edit+":lower_case", CTRL_ALT+Qt::Key_U)
const sc_pref sc_edit_edit_indent_selection(sc_edit_edit+":indent_selection", CTRL+Qt::Key_Tab)
const sc_pref sc_edit_view_zoom_in(sc_edit_view_zoom+"_in", QKeySequence::ZoomIn)
const sc_pref sc_edit_tabs_move_tab_left(sc_edit_tabs+":move_tab_left", Qt::AltModifier+Qt::Key_PageUp)
const sc_pref sc_edit_edit_delete_end_word(sc_edit_edit+":delete_end_word", QKeySequence::DeleteEndOfWord)
const sc_pref sc_edit_edit_preferences(sc_edit_edit+":preferences", QKeySequence::UnknownKey)
const sc_pref sc_edit_tabs_switch_right_tab(sc_edit_tabs+":switch_right_tab", CTRL+Qt::Key_PageDown)
const sc_pref sc_edit_edit_redo(sc_edit_edit+":redo", QKeySequence::Redo)
const sc_pref sc_edit_edit_conv_eol_unix(sc_edit_edit+":conv_eol_unix", QKeySequence::UnknownKey)
const sc_pref sc_edit_view_sort_tabs(sc_edit_view+":sort_tabs", QKeySequence::UnknownKey)
const sc_pref sc_edit_tabs_switch_left_tab(sc_edit_tabs+":switch_left_tab", CTRL+Qt::Key_PageUp)
const sc_pref sc_edit_view_show_line_numbers(sc_edit_view+":show_line_numbers", QKeySequence::UnknownKey)
const sc_pref sc_edit_view_zoom_out(sc_edit_view_zoom+"_out", QKeySequence::ZoomOut)
const sc_pref sc_edit_edit_conv_eol_mac(sc_edit_edit+":conv_eol_mac", QKeySequence::UnknownKey)
const sc_pref sc_edit_edit_conv_eol_winows(sc_edit_edit+":conv_eol_winows", QKeySequence::UnknownKey)
const sc_pref sc_edit_edit_previous_bookmark(sc_edit_edit+":previous_bookmark", PRE+Qt::SHIFT+Qt::Key_F2)
const sc_pref sc_edit_edit_delete_start_word(sc_edit_edit+":delete_start_word", QKeySequence::DeleteStartOfWord)
F77_RET_T const F77_DBLE * x
std::complex< double > w(std::complex< double > z, double relerr=0)
QString fromStdString(const std::string &s)
static double f(double k, double l_nu, double c_pm)
Definition: randpoisson.cc:118
static double fe[256]
Definition: randmtzig.cc:465
const QString key
const QVariant def
bool same_file(const std::string &f, const std::string &g)
Definition: utils.cc:293