1 ////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (C) 2016-2021 The Octave Project Developers
4 //
5 // See the file COPYRIGHT.md in the top-level directory of this
6 // distribution or <https://octave.org/copyright/>.
7 //
8 // This file is part of Octave.
9 //
10 // Octave is free software: you can redistribute it and/or modify it
11 // under the terms of the GNU General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // Octave is distributed in the hope that it will be useful, but
16 // WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 // GNU General Public License for more details.
19 //
20 // You should have received a copy of the GNU General Public License
21 // along with Octave; see the file COPYING.  If not, see
22 // <https://www.gnu.org/licenses/>.
23 //
24 ////////////////////////////////////////////////////////////////////////
25 
26 #if defined (HAVE_CONFIG_H)
27 #  include "config.h"
28 #endif
29 
30 #if defined (HAVE_QSCINTILLA)
31 
32 #include "marker.h"
33 
34 namespace octave
35 {
marker(QsciScintilla * area,int original_linenr,editor_markers type,int editor_linenr,const QString & condition)36   marker::marker (QsciScintilla *area, int original_linenr,
37                   editor_markers type, int editor_linenr,
38                   const QString& condition)
39     : QObject ()
40   {
41     construct (area, original_linenr, type, editor_linenr, condition);
42   }
43 
marker(QsciScintilla * area,int original_linenr,editor_markers type,const QString & condition)44   marker::marker (QsciScintilla *area, int original_linenr,
45                   editor_markers type, const QString& condition)
46     : QObject ()
47   {
48     construct (area, original_linenr, type, original_linenr - 1, condition);
49   }
50 
construct(QsciScintilla * area,int original_linenr,editor_markers type,int editor_linenr,const QString & condition)51   void marker::construct (QsciScintilla *area, int original_linenr,
52                           editor_markers type, int editor_linenr,
53                           const QString& condition)
54   {
55     m_edit_area = area;
56     m_original_linenr = original_linenr;
57     m_marker_type = type;
58     m_mhandle = m_edit_area->markerAdd (editor_linenr, m_marker_type);
59     m_condition = condition;
60   }
61 
handle_remove_via_original_linenr(int linenr)62   void marker::handle_remove_via_original_linenr (int linenr)
63   {
64     if (m_original_linenr == linenr)
65       {
66         m_edit_area->markerDeleteHandle (m_mhandle);
67         delete this;
68       }
69   }
70 
handle_request_remove_via_editor_linenr(int linenr)71   void marker::handle_request_remove_via_editor_linenr (int linenr)
72   {
73     // Get line number from the edit area and if it matches
74     // the requested line number, remove.
75     if (m_edit_area->markerLine (m_mhandle) == linenr)
76       {
77         // Rather than delete editor marker directly, issue command
78         // to Octave core.  Octave core should signal back to remove
79         // this breakpoint via debugger line number.
80         emit request_remove (m_original_linenr);
81       }
82   }
83 
handle_remove(void)84   void marker::handle_remove (void)
85   {
86     m_edit_area->markerDeleteHandle (m_mhandle);
87     delete this;
88   }
89 
handle_find_translation(int linenr,int & translation_linenr,marker * & bp)90   void marker::handle_find_translation (int linenr, int& translation_linenr,
91                                         marker *& bp)
92   {
93     if (m_original_linenr == linenr)
94       {
95         translation_linenr = m_edit_area->markerLine (m_mhandle);
96         bp = this;
97       }
98   }
99 
handle_find_just_before(int linenr,int & original_linenr,int & editor_linenr)100   void marker::handle_find_just_before (int linenr, int& original_linenr,
101                                         int& editor_linenr)
102   {
103     if (m_original_linenr < linenr && m_original_linenr >= original_linenr)
104       {
105         original_linenr = m_original_linenr;
106         editor_linenr = m_edit_area->markerLine (m_mhandle);
107       }
108   }
109 
handle_find_just_after(int linenr,int & original_linenr,int & editor_linenr)110   void marker::handle_find_just_after (int linenr, int& original_linenr,
111                                        int& editor_linenr)
112   {
113     if (m_original_linenr > linenr && m_original_linenr <= original_linenr)
114       {
115         original_linenr = m_original_linenr;
116         editor_linenr = m_edit_area->markerLine (m_mhandle);
117       }
118   }
119 
handle_report_editor_linenr(QIntList & lines,QStringList & conditions)120   void marker::handle_report_editor_linenr (QIntList& lines,
121                                             QStringList& conditions)
122   {
123     lines << m_edit_area->markerLine (m_mhandle);
124     conditions << m_condition;
125   }
126 
handle_marker_line_deleted(int mhandle)127   void marker::handle_marker_line_deleted (int mhandle)
128   {
129     // FUTURE SUPPORT: There really should be a signal in QsciScintilla
130     // called markerLineDeleted (int mhandle) because there is no way
131     // of knowing this.  QsciScintilla will place the marker at a
132     // different line rather than remove it from the margin.  I (DJS) will
133     // lobby for such a signal.
134     if (m_mhandle == mhandle)
135       {
136         if (m_marker_type == breakpoint || m_marker_type == debugger_position)
137           {
138             int editor_linenr = m_edit_area->markerLine (m_mhandle);
139             m_edit_area->markerDeleteHandle (m_mhandle);
140             m_marker_type = (m_marker_type == breakpoint
141                              ? unsure_breakpoint : unsure_debugger_position);
142             m_mhandle = m_edit_area->markerAdd (editor_linenr, m_marker_type);
143           }
144       }
145   }
146 
handle_marker_line_undeleted(int mhandle)147   void marker::handle_marker_line_undeleted (int mhandle)
148   {
149     // FUTURE SUPPORT: There really should be a signal in QsciScintilla
150     // called markerLineUndeleted (int mhandle) because there is no way
151     // of knowing this.  QsciScintilla will place the marker at a
152     // different line rather than remove it from the margin.  I (DJS) will
153     // lobby for such a signal.
154     if (m_mhandle == mhandle)
155       {
156         if (m_marker_type == unsure_breakpoint
157             || m_marker_type == unsure_debugger_position)
158           {
159             int editor_linenr = m_edit_area->markerLine (m_mhandle);
160             m_edit_area->markerDeleteHandle (m_mhandle);
161             m_marker_type = (m_marker_type == unsure_breakpoint
162                              ? breakpoint : debugger_position);
163             m_mhandle = m_edit_area->markerAdd (editor_linenr, m_marker_type);
164           }
165       }
166   }
167 }
168 #endif
169