# HG changeset patch # User Lachlan Andrew # Date 1454109214 -39600 # Node ID 65827e9cccb87e602491d97bfa425214edc93285 # Parent 94fc5f13d51bf05bc4b361d41f9ce7d600523d5a Gui support for enhancement of dbstop. * octave-qscintilla.cc (contextMenuEvent): Capture right-click in the left margins to show a context menu for "dbstop if...". * octave-qscintilla.{cc,h} (contextmenu_break_condition): new function * file-editor-interface.h: pass condition to handle_update_breakpoint_marker_request * file-editor-tab.{cc,h}: (file_editor_tab, bp_info, handle_request_add_breakpoint, next_breakpoint, previous_breakpoint, do_breakpoint_marker, add_breakpoint_callback): Allow conditional breakpoint markers * file-editor-tab.cc (handle_context_menu_break_condition): new function * file-editor.{cc,h} (request_open_file, add_file_editor_tab, handle_delete_debugger_pointer_request): pass bp conditions. * marker.{cc,h} (marker, construct, handle_report_editor_linenr): pass breakpoint conditions * main-window.{cc,h} (handle_update_breakpoint_marker_request): pass breakpoint condition. * octave-link.h (update_breakpoint): pass breakpoint condition. * octave-qt-link.{cc,h} (do_update_breakpoint): pass breakpoint condition. diff -r 94fc5f13d51b -r 65827e9cccb8 libgui/src/m-editor/file-editor-interface.h --- a/libgui/src/m-editor/file-editor-interface.h Sun Jan 24 11:02:30 2016 +1100 +++ b/libgui/src/m-editor/file-editor-interface.h Sat Jan 30 10:13:34 2016 +1100 @@ -56,7 +56,7 @@ virtual void handle_update_breakpoint_marker_request (bool insert, const QString& file, - int line) = 0; + int line, const QString& cond) = 0; virtual void handle_edit_file_request (const QString& file) = 0; @@ -76,7 +76,8 @@ int line = -1, bool debug_pointer = false, bool breakpoint_marker = false, - bool insert = true) = 0; + bool insert = true, + const QString& cond = "") = 0; //signals: //protected: diff -r 94fc5f13d51b -r 65827e9cccb8 libgui/src/m-editor/file-editor-tab.cc --- a/libgui/src/m-editor/file-editor-tab.cc Sun Jan 24 11:02:30 2016 +1100 +++ b/libgui/src/m-editor/file-editor-tab.cc Sat Jan 30 10:13:34 2016 +1100 @@ -74,6 +74,7 @@ #include "version.h" #include "utils.h" #include "defaults.h" +#include "unwind-prot.h" #include bool file_editor_tab::_cancelled = false; @@ -103,7 +104,8 @@ _line = 0; _col = 0; - _bp_list.clear (); // start with an empty list of breakpoints + _bp_lines.clear (); // start with empty lists of breakpoints + _bp_conditions.clear (); connect (_edit_area, SIGNAL (cursorPositionChanged (int, int)), this, SLOT (handle_cursor_moved (int,int))); @@ -155,6 +157,8 @@ _edit_area->setMarkerBackgroundColor (QColor (0,0,232), marker::bookmark); _edit_area->markerDefine (QsciScintilla::Circle, marker::breakpoint); _edit_area->setMarkerBackgroundColor (QColor (192,0,0), marker::breakpoint); + _edit_area->markerDefine (QsciScintilla::Circle, marker::cond_break); + _edit_area->setMarkerBackgroundColor (QColor (255,127,0), marker::cond_break); _edit_area->markerDefine (QsciScintilla::RightTriangle, marker::debugger_position); _edit_area->setMarkerBackgroundColor (QColor (255,255,0), marker::debugger_position); _edit_area->markerDefine (QsciScintilla::RightTriangle, @@ -166,6 +170,9 @@ this, SLOT (handle_margin_clicked (int, int, Qt::KeyboardModifiers))); + connect (_edit_area, SIGNAL (context_menu_break_condition_signal (int)), + this, SLOT (handle_context_menu_break_condition (int))); + // line numbers _edit_area->setMarginsForegroundColor (QColor (96, 96, 96)); _edit_area->setMarginsBackgroundColor (QColor (232, 232, 220)); @@ -316,6 +323,83 @@ emit edit_mfile_request (word_at_cursor, _file_name, _ced, -1); } +// If "dbstop if ..." selected from context menu, create a conditional +// breakpoint. The default condition is (a) the existing condition if there +// is already a breakpoint (b) any selected text, or (c) empty +void +file_editor_tab::handle_context_menu_break_condition (int linenr) +{ + QString cond; + bp_info info (_file_name, linenr); // Get function name & dir from filename. + + // Ensure editor line numbers match Octave core's line numbers. + // Give users the option to save modifications if necessary. + if (! unchanged_or_saved () + || !(_main_win->get_octave_qt_link ()->file_in_path (info.file, info.dir))) + return; + + // Search for previous condition. FIXME -- is there a more direct way? + if (_edit_area->markersAtLine (linenr) & (1 << marker::cond_break)) + { + emit report_marker_linenr (_bp_lines, _bp_conditions); + for (int i = 0; i < _bp_lines.length (); i++) + if (_bp_lines.value (i) == linenr) + { + cond = _bp_conditions.value (i); + break; + } + _bp_lines.clear (); + } + + // If text selected by the mouse, default to that instead + // If both present, use the OR of them, to avoid accidental overwriting + // FIXME If both are present, show old condition unselected and + // the selection (in edit area) selected (in the dialog). + if (_edit_area->hasSelectedText ()) + { + if (cond == "") + cond = _edit_area->selectedText (); + else + cond = "(" + cond + ") || (" + _edit_area->selectedText () + ")"; + } + + bool valid = false; + std::string prompt = "dbstop if"; + while (!valid) + { + bool ok; + QString new_condition + = QInputDialog::getText (this, tr ("Breakpoint condition"), + tr (prompt.c_str ()), QLineEdit::Normal, cond, + &ok); + if (ok) // If cancel, don't change breakpoint condition. + { + bp_table::intmap line; + line[0] = linenr + 1; + + try + { + // Suppress error messages on the console. + unwind_protect frame; + frame.protect_var (buffer_error_messages); + buffer_error_messages++; + + bp_table::add_breakpoint (info.function_name, line, + new_condition.toStdString ()); + valid = true; + } + catch (const octave_interrupt_exception&) { valid = true; } + catch (const index_exception& e) { } + catch (const octave_execution_exception& e) { } + + // In case we repeat, set new prompt. + prompt = "ERROR: " + last_error_message () + "\n\ndbstop if"; + cond = new_condition; + } + else + valid = true; + } +} void file_editor_tab::set_file_name (const QString& fileName) @@ -398,12 +482,13 @@ } else { - if (markers_mask & (1 << marker::breakpoint)) + if (markers_mask & ((1 << marker::breakpoint) + | (1 << marker::cond_break))) handle_request_remove_breakpoint (editor_linenr + 1); else { if (unchanged_or_saved ()) - handle_request_add_breakpoint (editor_linenr + 1); + handle_request_add_breakpoint (editor_linenr + 1, ""); } } } @@ -845,7 +930,7 @@ line_info[0] = info.line; if (_main_win->get_octave_qt_link ()->file_in_path (info.file, info.dir)) - bp_table::add_breakpoint (info.function_name, line_info); + bp_table::add_breakpoint (info.function_name, line_info, info.condition); } void @@ -865,8 +950,9 @@ bp_table::remove_all_breakpoints_in_file (info.function_name, true); } -file_editor_tab::bp_info::bp_info (const QString& fname, int l) - : line (l), file (fname.toStdString ()) +file_editor_tab::bp_info::bp_info (const QString& fname, int l, + const QString& cond) + : line (l), file (fname.toStdString ()), condition (cond.toStdString ()) { QFileInfo file_info (fname); @@ -896,9 +982,10 @@ } void -file_editor_tab::handle_request_add_breakpoint (int line) +file_editor_tab::handle_request_add_breakpoint (int line, + const QString& condition) { - bp_info info (_file_name, line); + bp_info info (_file_name, line, condition); octave_link::post_event (this, &file_editor_tab::add_breakpoint_callback, info); @@ -927,11 +1014,11 @@ else { if (unchanged_or_saved ()) - handle_request_add_breakpoint (editor_linenr + 1); + handle_request_add_breakpoint (editor_linenr + 1, ""); } } -// Move the text cursor to the closest breakpoint +// Move the text cursor to the closest breakpoint (conditional or unconditional) // after the current line. void file_editor_tab::next_breakpoint (const QWidget *ID) @@ -945,11 +1032,16 @@ line++; // Find breakpoint strictly after the current line. int nextline = _edit_area->markerFindNext (line, (1 << marker::breakpoint)); + int nextcond = _edit_area->markerFindNext (line, (1 << marker::cond_break)); + + // Check if the next conditional breakpoint is before next unconditional one. + if (nextcond != -1 && (nextcond < nextline || nextline == -1)) + nextline = nextcond; _edit_area->setCursorPosition (nextline, 0); } -// Move the text cursor to the closest breakpoint +// Move the text cursor to the closest breakpoint (conditional or unconditional) // before the current line. void file_editor_tab::previous_breakpoint (const QWidget *ID) @@ -957,12 +1049,17 @@ if (ID != this) return; - int line, cur, prevline; + int line, cur, prevline, prevcond; _edit_area->getCursorPosition (&line, &cur); line--; // Find breakpoint strictly before the current line. prevline = _edit_area->markerFindPrevious (line, (1 << marker::breakpoint)); + prevcond = _edit_area->markerFindPrevious (line, (1 << marker::cond_break)); + + // Check if the prev conditional breakpoint is closer than the unconditional. + if (prevcond != -1 && prevcond > prevline) + prevline = prevcond; _edit_area->setCursorPosition (prevline, 0); } @@ -1405,18 +1502,19 @@ void file_editor_tab::check_restore_breakpoints () { - if (! _bp_list.isEmpty ()) + if (! _bp_lines.isEmpty ()) { // At least one breakpoint is present. // Get rid of breakpoints at old (now possibly invalid) linenumbers remove_all_breakpoints (this); // and set breakpoints at the new linenumbers - for (int i = 0; i < _bp_list.length (); i++) - handle_request_add_breakpoint (_bp_list.value (i) + 1); + for (int i = 0; i < _bp_lines.length (); i++) + handle_request_add_breakpoint (_bp_lines.value (i) + 1, + _bp_conditions.value (i)); // reset the list of breakpoints - _bp_list.clear (); + _bp_lines.clear (); } } @@ -1613,7 +1711,7 @@ QFile file (file_to_save); // Get a list of all the breakpoint line numbers. - emit report_editor_linenr (_bp_list); + emit report_marker_linenr (_bp_lines, _bp_conditions); // stop watching file QStringList trackedFiles = _file_system_watcher.files (); @@ -2225,7 +2323,8 @@ // isn't certain whether the original line number and current line // number match. int editor_linenr = -1; - emit find_translated_line_number (line, editor_linenr); + marker *dummy; + emit find_translated_line_number (line, editor_linenr, dummy); if (editor_linenr != -1) { // Match with an existing breakpoint. @@ -2277,7 +2376,8 @@ } void -file_editor_tab::do_breakpoint_marker (bool insert, const QWidget *ID, int line) +file_editor_tab::do_breakpoint_marker (bool insert, const QWidget *ID, int line, + const QString& cond) { if (ID != this || ID == 0) return; @@ -2287,30 +2387,48 @@ if (insert) { int editor_linenr = -1; - - // If comes back indicating a modified editor line number - // then there is already a breakpoint marker associated - // with this debugger line. - emit find_translated_line_number (line, editor_linenr); - - if (editor_linenr == -1) + marker *bp = 0; + + // If comes back indicating a non-zero breakpoint marker, + // reuse it if possible + emit find_translated_line_number (line, editor_linenr, bp); + if (bp != 0) { - marker *bp = new marker (_edit_area, line, marker::breakpoint); - connect (this, SIGNAL (remove_breakpoint_via_debugger_linenr (int)), - bp, SLOT (handle_remove_via_original_linenr (int))); - connect (this, SIGNAL (request_remove_breakpoint_via_editor_linenr (int)), - bp, SLOT (handle_request_remove_via_editor_linenr (int))); - connect (this, SIGNAL (remove_all_breakpoints (void)), - bp, SLOT (handle_remove (void))); - connect (this, SIGNAL (find_translated_line_number (int, int&)), - bp, SLOT (handle_find_translation (int, int&))); - connect (this, SIGNAL (find_linenr_just_before (int, int&, int&)), - bp, SLOT (handle_find_just_before (int, int&, int&))); - connect (this, SIGNAL (report_editor_linenr (QIntList&)), - bp, SLOT (handle_report_editor_linenr (QIntList&))); - connect (bp, SIGNAL (request_remove (int)), - this, SLOT (handle_request_remove_breakpoint (int))); + if ((cond == "") != (bp->get_cond () == "")) + { // can only reuse conditional bp as conditional + emit remove_breakpoint_via_debugger_linenr (line); + bp = 0; + } + else + bp->set_cond (cond); } + + if (bp == 0) + bp = new marker (_edit_area, line, + cond == "" ? marker::breakpoint + : marker::cond_break, cond); + + connect (this, SIGNAL (remove_breakpoint_via_debugger_linenr + (int)), + bp, SLOT (handle_remove_via_original_linenr (int))); + connect (this, SIGNAL (request_remove_breakpoint_via_editor_linenr + (int)), + bp, SLOT (handle_request_remove_via_editor_linenr + (int))); + connect (this, SIGNAL (remove_all_breakpoints (void)), + bp, SLOT (handle_remove (void))); + connect (this, SIGNAL (find_translated_line_number (int, int&, + marker*&)), + bp, SLOT (handle_find_translation (int, int&, + marker*&))); + connect (this, SIGNAL (find_linenr_just_before (int, int&, int&)), + bp, SLOT (handle_find_just_before (int, int&, int&))); + connect (this, SIGNAL (report_marker_linenr (QIntList&, + QStringList&)), + bp, SLOT (handle_report_editor_linenr (QIntList&, + QStringList&))); + connect (bp, SIGNAL (request_remove (int)), + this, SLOT (handle_request_remove_breakpoint (int))); } else emit remove_breakpoint_via_debugger_linenr (line); diff -r 94fc5f13d51b -r 65827e9cccb8 libgui/src/m-editor/file-editor-tab.h --- a/libgui/src/m-editor/file-editor-tab.h Sun Jan 24 11:02:30 2016 +1100 +++ b/libgui/src/m-editor/file-editor-tab.h Sat Jan 30 10:13:34 2016 +1100 @@ -128,7 +128,8 @@ void insert_debugger_pointer (const QWidget *ID, int line = -1); void delete_debugger_pointer (const QWidget *ID, int line = -1); - void do_breakpoint_marker (bool insert, const QWidget *ID, int line = -1); + void do_breakpoint_marker (bool insert, const QWidget *ID, int line = -1, + const QString& cond = ""); void recover_from_exit (void); void set_modified (bool modified = true); @@ -142,8 +143,9 @@ void file_has_changed (const QString& fileName); void handle_context_menu_edit (const QString&); + void handle_context_menu_break_condition (int linenr); - void handle_request_add_breakpoint (int line); + void handle_request_add_breakpoint (int line, const QString& cond); void handle_request_remove_breakpoint (int line); void handle_octave_result (QObject *requester, QString& command, octave_value_list &result); @@ -165,9 +167,9 @@ void remove_breakpoint_via_debugger_linenr (int debugger_linenr); void request_remove_breakpoint_via_editor_linenr (int editor_linenr); void remove_all_breakpoints (void); - void find_translated_line_number (int original_linenr, int& translated_linenr); + void find_translated_line_number (int original_linenr, int& translated_linenr, marker*&); void find_linenr_just_before (int linenr, int& original_linenr, int& editor_linenr); - void report_editor_linenr (QIntList& int_list); + void report_marker_linenr (QIntList& lines, QStringList& conditions); void remove_position_via_debugger_linenr (int debugger_linenr); void remove_all_positions (void); // TODO: The following is similar to "process_octave_code" signal. However, @@ -215,12 +217,13 @@ struct bp_info { - bp_info (const QString& fname, int l = 0); + bp_info (const QString& fname, int l = 0, const QString& cond = ""); int line; std::string file; std::string dir; std::string function_name; + std::string condition; }; bool valid_file_name (const QString& file=QString ()); @@ -279,7 +282,8 @@ QFileSystemWatcher _file_system_watcher; - QIntList _bp_list; + QIntList _bp_lines; + QStringList _bp_conditions; find_dialog *_find_dialog; bool _find_dialog_is_visible; diff -r 94fc5f13d51b -r 65827e9cccb8 libgui/src/m-editor/file-editor.cc --- a/libgui/src/m-editor/file-editor.cc Sun Jan 24 11:02:30 2016 +1100 +++ b/libgui/src/m-editor/file-editor.cc Sat Jan 30 10:13:34 2016 +1100 @@ -404,11 +404,14 @@ request_open_file (open_file_names.at (i), _file_encoding); } +// Open a file, if not already open, and mark the current execution location +// and/or a breakpoint with condition cond. void file_editor::request_open_file (const QString& openFileName, const QString& encoding, int line, bool debug_pointer, - bool breakpoint_marker, bool insert) + bool breakpoint_marker, bool insert, + const QString& cond) { if (call_custom_editor (openFileName, line)) return; // custom editor called @@ -440,7 +443,7 @@ emit fetab_insert_debugger_pointer (tab, line); if (breakpoint_marker) - emit fetab_do_breakpoint_marker (insert, tab, line); + emit fetab_do_breakpoint_marker (insert, tab, line, cond); } if (! ((breakpoint_marker || debug_pointer) && is_editor_console_tabbed ())) @@ -476,7 +479,7 @@ line); if (breakpoint_marker) emit fetab_do_breakpoint_marker (insert, fileEditorTab, - line); + line, cond); } } else @@ -758,9 +761,10 @@ void file_editor::handle_update_breakpoint_marker_request (bool insert, const QString& file, - int line) + int line, + const QString& cond) { - request_open_file (file, QString (), line, false, true, insert); + request_open_file (file, QString (), line, false, true, insert, cond); } void @@ -887,6 +891,7 @@ emit fetab_remove_bookmark (_tab_widget->currentWidget ()); } +// FIXME What should this do with conditional breakpoints? void file_editor::request_toggle_breakpoint (bool) { @@ -1858,9 +1863,6 @@ connect (_tab_widget, SIGNAL (currentChanged (int)), this, SLOT (active_tab_changed (int))); - connect (this, SIGNAL (execute_command_in_terminal_signal (const QString&)), - main_win (), SLOT (execute_command_in_terminal (const QString&))); - resize (500, 400); setWindowIcon (QIcon (":/actions/icons/logo.png")); set_title (tr ("Editor")); @@ -1981,6 +1983,9 @@ connect (this, SIGNAL (fetab_check_modified_file (void)), f, SLOT (check_modified_file (void))); + connect (f, SIGNAL (execute_command_in_terminal_signal (const QString&)), + main_win (), SLOT (execute_command_in_terminal (const QString&))); + // Signals from the file_editor trivial operations connect (this, SIGNAL (fetab_recover_from_exit (void)), f, SLOT (recover_from_exit (void))); @@ -2080,8 +2085,9 @@ f, SLOT (delete_debugger_pointer (const QWidget*, int))); connect (this, SIGNAL (fetab_do_breakpoint_marker (bool, const QWidget*, - int)), - f, SLOT (do_breakpoint_marker (bool, const QWidget*, int))); + int, const QString&)), + f, SLOT (do_breakpoint_marker (bool, const QWidget*, int, + const QString&))); _tab_widget->setCurrentWidget (f); diff -r 94fc5f13d51b -r 65827e9cccb8 libgui/src/m-editor/file-editor.h --- a/libgui/src/m-editor/file-editor.h Sun Jan 24 11:02:30 2016 +1100 +++ b/libgui/src/m-editor/file-editor.h Sat Jan 30 10:13:34 2016 +1100 @@ -143,7 +143,7 @@ void fetab_insert_debugger_pointer (const QWidget* ID, int line = -1); void fetab_delete_debugger_pointer (const QWidget* ID, int line = -1); void fetab_do_breakpoint_marker (bool insert, const QWidget* ID, - int line = -1); + int line = -1, const QString& = ""); void fetab_set_focus (const QWidget* ID); void fetab_scintilla_command (const QWidget* ID, unsigned int sci_msg); @@ -235,7 +235,8 @@ void handle_insert_debugger_pointer_request (const QString& file, int line); void handle_delete_debugger_pointer_request (const QString& file, int line); void handle_update_breakpoint_marker_request (bool insert, - const QString& file, int line); + const QString& file, int line, + const QString& cond); void handle_edit_mfile_request (const QString& name, const QString& file, const QString& curr_dir, int line); @@ -262,7 +263,8 @@ 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); + bool breakpoint_marker = false, bool insert = true, + const QString& cond = ""); void request_preferences (bool); void request_styles_preferences (bool); void restore_create_file_setting (); diff -r 94fc5f13d51b -r 65827e9cccb8 libgui/src/m-editor/marker.cc --- a/libgui/src/m-editor/marker.cc Sun Jan 24 11:02:30 2016 +1100 +++ b/libgui/src/m-editor/marker.cc Sat Jan 30 10:13:34 2016 +1100 @@ -32,16 +32,16 @@ marker::marker (QsciScintilla *area, int original_linenr, editor_markers type, - int editor_linenr) : QObject () + int editor_linenr, const QString& condition) : QObject () { - construct (area, original_linenr, type, editor_linenr); + construct (area, original_linenr, type, editor_linenr, condition); } marker::marker (QsciScintilla *area, int original_linenr, - editor_markers type) : QObject () + editor_markers type, const QString& condition) : QObject () { - construct (area, original_linenr, type, original_linenr - 1); + construct (area, original_linenr, type, original_linenr - 1, condition); } @@ -52,12 +52,14 @@ void marker::construct (QsciScintilla *area, int original_linenr, - editor_markers type, int editor_linenr) + editor_markers type, int editor_linenr, + const QString& condition) { _edit_area = area; _original_linenr = original_linenr; _marker_type = type; _mhandle = _edit_area->markerAdd (editor_linenr, _marker_type); + _condition = condition; } @@ -96,10 +98,14 @@ void -marker::handle_find_translation (int linenr, int& translation_linenr) +marker::handle_find_translation (int linenr, int& translation_linenr, + marker *& bp) { if (_original_linenr == linenr) - translation_linenr = _edit_area->markerLine (_mhandle); + { + translation_linenr = _edit_area->markerLine (_mhandle); + bp = this; + } } @@ -126,9 +132,10 @@ void -marker::handle_report_editor_linenr (QIntList& list) +marker::handle_report_editor_linenr (QIntList& lines, QStringList& conditions) { - list << _edit_area->markerLine (_mhandle); + lines << _edit_area->markerLine (_mhandle); + conditions << _condition; } diff -r 94fc5f13d51b -r 65827e9cccb8 libgui/src/m-editor/marker.h --- a/libgui/src/m-editor/marker.h Sun Jan 24 11:02:30 2016 +1100 +++ b/libgui/src/m-editor/marker.h Sat Jan 30 10:13:34 2016 +1100 @@ -46,40 +46,49 @@ { bookmark, breakpoint, + cond_break, unsure_breakpoint, debugger_position, unsure_debugger_position }; marker (QsciScintilla *edit_area, int original_linenr, - editor_markers marker_type); + editor_markers marker_type, const QString& condition = ""); marker (QsciScintilla *edit_area, int original_linenr, - editor_markers marker_type, int editor_linenr); + editor_markers marker_type, int editor_linenr, + const QString& condition = ""); ~marker (void); + const QString& get_cond (void) const { return _condition; } + + void set_cond (const QString& cond) { _condition = cond; } + public slots: void handle_remove_via_original_linenr (int original_linenr); void handle_request_remove_via_editor_linenr (int editor_linenr); void handle_remove (void); - void handle_find_translation (int original_linenr, int& editor_linenr); + void handle_find_translation (int original_linenr, int& editor_linenr, + marker*& bp); void handle_find_just_before (int linenr, int& original_linenr, int& editor_linenr); void handle_find_just_after (int linenr, int& original_linenr, int& editor_linenr); /* void handle_lines_changed (void);*/ void handle_marker_line_deleted (int mhandle); void handle_marker_line_undeleted (int mhandle); - void handle_report_editor_linenr (QIntList& int_list); + void handle_report_editor_linenr (QIntList& lines, QStringList& conditions); signals: void request_remove (int original_linenr); private: void construct (QsciScintilla *edit_area, int original_linenr, - editor_markers marker_type, int editor_linenr); + editor_markers marker_type, int editor_linenr, + const QString& condition); QsciScintilla * _edit_area; int _original_linenr; editor_markers _marker_type; int _mhandle; + QString _condition; }; #endif // MARKER_H diff -r 94fc5f13d51b -r 65827e9cccb8 libgui/src/m-editor/octave-qscintilla.cc --- a/libgui/src/m-editor/octave-qscintilla.cc Sun Jan 24 11:02:30 2016 +1100 +++ b/libgui/src/m-editor/octave-qscintilla.cc Sat Jan 30 10:13:34 2016 +1100 @@ -194,8 +194,7 @@ QPoint global_pos, local_pos; // the menu's position QMenu *context_menu = createStandardContextMenu (); // standard menu - // fill context menu with editor's standard actions - emit create_context_menu_signal (context_menu); + bool in_left_margin = false; // determine position depending on mouse or keyboard event if (e->reason () == QContextMenuEvent::Mouse) @@ -203,6 +202,8 @@ // context menu by mouse global_pos = e->globalPos (); // global mouse position local_pos = e->pos (); // local mouse position + if (e->x () < marginWidth (1) + marginWidth (2)) + in_left_margin = true; } else { @@ -215,26 +216,45 @@ global_pos = editor_rect.topLeft (); // yes, take top left corner } - // additional custom entries of the context menu - context_menu->addSeparator (); // separator before custom entries - - // help menu: get the position of the mouse or the text cursor - // (only for octave files) - QString lexer_name = lexer ()->lexer (); - if (lexer_name == "octave" || lexer_name == "matlab") + if (! in_left_margin) { - _word_at_cursor = wordAtPoint (local_pos); - if (! _word_at_cursor.isEmpty ()) + // fill context menu with editor's standard actions + emit create_context_menu_signal (context_menu); + + // additional custom entries of the context menu + context_menu->addSeparator (); // separator before custom entries + + // help menu: get the position of the mouse or the text cursor + // (only for octave files) + QString lexer_name = lexer ()->lexer (); + if (lexer_name == "octave" || lexer_name == "matlab") { - context_menu->addAction (tr ("Help on") + " " + _word_at_cursor, - this, SLOT (contextmenu_help (bool))); - context_menu->addAction (tr ("Documentation on") - + " " + _word_at_cursor, - this, SLOT (contextmenu_doc (bool))); - context_menu->addAction (tr ("Edit") + " " + _word_at_cursor, - this, SLOT (contextmenu_edit (bool))); + _word_at_cursor = wordAtPoint (local_pos); + if (! _word_at_cursor.isEmpty ()) + { + context_menu->addAction (tr ("Help on") + " " + _word_at_cursor, + this, SLOT (contextmenu_help (bool))); + context_menu->addAction (tr ("Documentation on") + + " " + _word_at_cursor, + this, SLOT (contextmenu_doc (bool))); + context_menu->addAction (tr ("Edit") + " " + _word_at_cursor, + this, SLOT (contextmenu_edit (bool))); + } } - } + } + else + { + // remove all standard actions from scintilla + QList all_actions = context_menu->actions (); + QAction* a; + + foreach (a, all_actions) + context_menu->removeAction (a); + + a = context_menu->addAction (tr ("dbstop if ..."), this, + SLOT (contextmenu_break_condition (bool))); + a->setData (local_pos); + } // finaly show the menu context_menu->exec (global_pos); @@ -279,6 +299,38 @@ emit execute_command_in_terminal_signal (commands.at (i)); } +// wrappers for dbstop related context menu items + +#ifdef HAVE_QSCI_VERSION_2_6_0 +// FIXME Why can't the data be sent as the argument to the function??? +void +octave_qscintilla::contextmenu_break_condition (bool) +{ + QAction *action = qobject_cast(sender()); + QPoint local_pos = action->data ().value (); + + // pick point just right of margins, so lineAt doesn't give -1 + int margins = marginWidth (1) + marginWidth (2) + marginWidth (3); + local_pos = QPoint (margins + 1, local_pos.y ()); + + emit context_menu_break_condition_signal (lineAt (local_pos)); +} + +void +octave_qscintilla::contextmenu_break_once (const QPoint& local_pos) +{ + emit context_menu_break_once (lineAt (local_pos)); +} + +/* +void +octave_qscintilla::contextmenu_break_if_caught (bool) +{ + emit context_menu_break_if_caught +} +*/ +#endif // HAVE_QSCI_VERSION_2_6_0 + void octave_qscintilla::text_changed () { diff -r 94fc5f13d51b -r 65827e9cccb8 libgui/src/m-editor/octave-qscintilla.h --- a/libgui/src/m-editor/octave-qscintilla.h Sun Jan 24 11:02:30 2016 +1100 +++ b/libgui/src/m-editor/octave-qscintilla.h Sat Jan 30 10:13:34 2016 +1100 @@ -54,6 +54,8 @@ void qsci_has_focus_signal (bool); void status_update (bool,bool); void show_doc_signal (const QString&); + void context_menu_break_condition_signal (int); + void context_menu_break_once (int); private slots: @@ -63,6 +65,9 @@ void contextmenu_edit (bool); void contextmenu_run (bool); + void contextmenu_break_condition (bool); + void contextmenu_break_once (const QPoint&); + void text_changed (void); protected: diff -r 94fc5f13d51b -r 65827e9cccb8 libgui/src/main-window.cc --- a/libgui/src/main-window.cc Sun Jan 24 11:02:30 2016 +1100 +++ b/libgui/src/main-window.cc Sat Jan 30 10:13:34 2016 +1100 @@ -1000,11 +1000,12 @@ void main_window::handle_update_breakpoint_marker_request (bool insert, const QString& file, - int line) + int line, + const QString& cond) { bool cmd_focus = command_window_has_focus (); - emit update_breakpoint_marker_signal (insert, file, line); + emit update_breakpoint_marker_signal (insert, file, line, cond); if (cmd_focus) focus_command_window (); @@ -1414,11 +1415,13 @@ SLOT (handle_delete_debugger_pointer_request (const QString&, int))); connect (this, - SIGNAL (update_breakpoint_marker_signal (bool, const QString&, int)), + SIGNAL (update_breakpoint_marker_signal (bool, const QString&, + int, const QString&)), editor_window, SLOT (handle_update_breakpoint_marker_request (bool, const QString&, - int))); + int, + const QString&))); #endif octave_link::post_event (this, &main_window::resize_command_window_callback); @@ -1558,10 +1561,13 @@ SLOT (handle_delete_debugger_pointer_request (const QString&, int))); connect (_octave_qt_link, - SIGNAL (update_breakpoint_marker_signal (bool, const QString&, int)), + SIGNAL (update_breakpoint_marker_signal (bool, const QString&, + int, const QString&)), this, - SLOT (handle_update_breakpoint_marker_request (bool, const QString&, - int))); + SLOT (handle_update_breakpoint_marker_request (bool, + const QString&, + int, + const QString&))); connect (_octave_qt_link, SIGNAL (show_doc_signal (const QString &)), diff -r 94fc5f13d51b -r 65827e9cccb8 libgui/src/main-window.h --- a/libgui/src/main-window.h Sun Jan 24 11:02:30 2016 +1100 +++ b/libgui/src/main-window.h Sat Jan 30 10:13:34 2016 +1100 @@ -100,7 +100,7 @@ void insert_debugger_pointer_signal (const QString& file, int line); void delete_debugger_pointer_signal (const QString& file, int line); void update_breakpoint_marker_signal (bool insert, const QString& file, - int line); + int line, const QString& cond); void copyClipboard_signal (void); void pasteClipboard_signal (void); @@ -169,7 +169,8 @@ void handle_insert_debugger_pointer_request (const QString& file, int line); void handle_delete_debugger_pointer_request (const QString& file, int line); void handle_update_breakpoint_marker_request (bool insert, - const QString& file, int line); + const QString& file, int line, + const QString& cond); void read_settings (void); void init_terminal_size (void); diff -r 94fc5f13d51b -r 65827e9cccb8 libgui/src/octave-qt-link.cc --- a/libgui/src/octave-qt-link.cc Sun Jan 24 11:02:30 2016 +1100 +++ b/libgui/src/octave-qt-link.cc Sat Jan 30 10:13:34 2016 +1100 @@ -29,6 +29,7 @@ #include #include #include +#include #include "str-vec.h" #include "dialog.h" @@ -372,6 +373,11 @@ return retval; } +// Prompt to allow file to be run by setting cwd (or if addpath_option==true, +// alternatively setting the path). +// This uses a QMessageBox unlike other functions in this file, +// because uiwidget_creator.waitcondition.wait hangs when called from +// file_editor_tab::handle_context_menu_break_condition(). (FIXME -- why hang?) int octave_qt_link::do_debug_cd_or_addpath_error (const std::string& file, const std::string& dir, @@ -382,46 +388,30 @@ QString qdir = QString::fromStdString (dir); QString qfile = QString::fromStdString (file); - QString msg - = (addpath_option - ? tr ("The file %1 does not exist in the load path. To run or debug the function you are editing, you must either change to the directory %2 or add that directory to the load path.").arg (qfile).arg (qdir) - : tr ("The file %1 is shadowed by a file with the same name in the load path. To run or debug the function you are editing, change to the directory %2.").arg (qfile).arg (qdir)); - - QString title = tr ("Change Directory or Add Directory to Load Path"); + QMessageBox msgBox; - QString cd_txt = tr ("Change Directory"); - QString addpath_txt = tr ("Add Directory to Load Path"); - QString cancel_txt = tr ("Cancel"); + msgBox.setText ("File not in load path"); + QPushButton *cd_btn = msgBox.addButton (tr ("Change Directory"), + QMessageBox::YesRole); - QStringList btn; - QStringList role; - btn << cd_txt; - role << "YesRole"; + QPushButton *addpath_btn = 0; if (addpath_option) { - btn << addpath_txt; - role << "AcceptRole"; + msgBox.setInformativeText (tr ("The file %1 does not exist in the load path. To run or debug the function you are editing, you must either change to the directory %2 or add that directory to the load path.").arg (qfile).arg (qdir)); + addpath_btn = msgBox.addButton (tr ("Add Directory to Load Path"), + QMessageBox::AcceptRole); } - btn << cancel_txt; - role << "RejectRole"; - - // Lock mutex before signaling. - uiwidget_creator.mutex.lock (); - - uiwidget_creator.signal_dialog (msg, title, "quest", btn, cancel_txt, role); + else + { + msgBox.setInformativeText (tr ("The file %1 is shadowed by a file with the same name in the load path. To run or debug the function you are editing, change to the directory %2.").arg (qfile).arg (qdir)); + } + msgBox.setStandardButtons (QMessageBox::Cancel); - // Wait while the user is responding to message box. - uiwidget_creator.waitcondition.wait (&uiwidget_creator.mutex); - - // The GUI has sent a signal and the thread has been awakened. + msgBox.exec (); - QString result = uiwidget_creator.get_dialog_button (); - - uiwidget_creator.mutex.unlock (); - - if (result == cd_txt) + if (msgBox.clickedButton () == cd_btn) retval = 1; - else if (result == addpath_txt) + else if (msgBox.clickedButton () == addpath_btn) retval = 2; return retval; @@ -538,12 +528,15 @@ emit exit_debugger_signal (); } +// Display (if @insert true) or remove the appropriate symbol for a breakpoint +// in @file at @line with condition @cond. void octave_qt_link::do_update_breakpoint (bool insert, - const std::string& file, int line) + const std::string& file, int line, + const std::string& cond) { emit update_breakpoint_marker_signal (insert, QString::fromStdString (file), - line); + line, QString::fromStdString (cond)); } void diff -r 94fc5f13d51b -r 65827e9cccb8 libgui/src/octave-qt-link.h --- a/libgui/src/octave-qt-link.h Sun Jan 24 11:02:30 2016 +1100 +++ b/libgui/src/octave-qt-link.h Sat Jan 30 10:13:34 2016 +1100 @@ -124,7 +124,8 @@ void do_execute_in_debugger_event (const std::string& file, int line); void do_exit_debugger_event (void); - void do_update_breakpoint (bool insert, const std::string& file, int line); + void do_update_breakpoint (bool insert, const std::string& file, int line, + const std::string& cond); void do_set_default_prompts (std::string& ps1, std::string& ps2, std::string& ps4); @@ -191,7 +192,7 @@ void exit_debugger_signal (void); void update_breakpoint_marker_signal (bool insert, const QString& file, - int line); + int line, const QString& cond); void insert_debugger_pointer_signal (const QString&, int); void delete_debugger_pointer_signal (const QString&, int); diff -r 94fc5f13d51b -r 65827e9cccb8 libinterp/corefcn/octave-link.h --- a/libinterp/corefcn/octave-link.h Sun Jan 24 11:02:30 2016 +1100 +++ b/libinterp/corefcn/octave-link.h Sat Jan 30 10:13:34 2016 +1100 @@ -307,7 +307,7 @@ const std::string& cond = "") { if (enabled ()) - instance->do_update_breakpoint (insert, file, line); + instance->do_update_breakpoint (insert, file, line, cond); } static void connect_link (octave_link *); @@ -467,7 +467,8 @@ virtual void do_exit_debugger_event (void) = 0; virtual void do_update_breakpoint (bool insert, - const std::string& file, int line) = 0; + const std::string& file, int line, + const std::string& cond) = 0; virtual void do_set_default_prompts (std::string& ps1, std::string& ps2, std::string& ps4) = 0;