1 /*
2  *		markers.c
3  *
4  *      Copyright 2010 Alexander Petukhov <devel(at)apetukhov.ru>
5  *
6  *      This program is free software; you can redistribute it and/or modify
7  *      it under the terms of the GNU General Public License as published by
8  *      the Free Software Foundation; either version 2 of the License, or
9  *      (at your option) any later version.
10  *
11  *      This program is distributed in the hope that it will be useful,
12  *      but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *      GNU General Public License for more details.
15  *
16  *      You should have received a copy of the GNU General Public License
17  *      along with this program; if not, write to the Free Software
18  *      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19  *      MA 02110-1301, USA.
20  */
21 
22 /*
23  * 		Contains functions for manipulating margin and background markers.
24  */
25 
26 #include <string.h>
27 
28 #include <geanyplugin.h>
29 extern GeanyData		*geany_data;
30 
31 #include "markers.h"
32 #include "breakpoints.h"
33 
34 #include "xpm/breakpoint.xpm"
35 #include "xpm/breakpoint_disabled.xpm"
36 #include "xpm/breakpoint_condition.xpm"
37 
38 #include "xpm/frame.xpm"
39 #include "xpm/frame_current.xpm"
40 
41 /* markers identifiers */
42 #define M_FIRST			12
43 enum
44 {
45 	M_BP_ENABLED		= M_FIRST,
46 	M_BP_DISABLED,
47 	M_BP_CONDITIONAL,
48 	M_FRAME,
49 	M_CI_BACKGROUND,
50 	M_CI_ARROW
51 };
52 
53 /* markers colors */
54 #define RGB(R,G,B)	(R | (G << 8) | (B << 16))
55 #define RED				RGB(255,0,0)
56 #define GREEN			RGB(0,255,0)
57 #define BLUE				RGB(0,0,255)
58 #define YELLOW			RGB(255,255,0)
59 #define BLACK			RGB(0,0,0)
60 #define WHITE			RGB(255,255,255)
61 #define PINK				RGB(255,192,203)
62 
63 #define BP_BACKGROUND	RGB(255,246,33)
64 
65 
66 #define LIGHT_YELLOW	RGB(200,200,0)
67 
68 /*
69  * sets markers for a scintilla document
70  */
markers_set_for_document(ScintillaObject * sci)71 void markers_set_for_document(ScintillaObject *sci)
72 {
73 	/* enabled breakpoint */
74 	scintilla_send_message(sci, SCI_MARKERDEFINEPIXMAP, M_BP_ENABLED, (long)breakpoint_xpm);
75 
76 	/* disabled breakpoint */
77 	scintilla_send_message(sci, SCI_MARKERDEFINEPIXMAP, M_BP_DISABLED, (long)breakpoint_disabled_xpm);
78 
79 	/* conditional breakpoint */
80 	scintilla_send_message(sci, SCI_MARKERDEFINEPIXMAP, M_BP_CONDITIONAL, (long)breakpoint_condition_xpm);
81 
82 	/* currect instruction background */
83 	scintilla_send_message(sci, SCI_MARKERDEFINE, M_CI_BACKGROUND, SC_MARK_BACKGROUND);
84 	scintilla_send_message(sci, SCI_MARKERSETBACK, M_CI_BACKGROUND, YELLOW);
85 	scintilla_send_message(sci, SCI_MARKERSETFORE, M_CI_BACKGROUND, YELLOW);
86 	scintilla_send_message(sci, SCI_MARKERSETALPHA, M_CI_BACKGROUND, 75);
87 
88 	/* currect instruction arrow */
89 	scintilla_send_message(sci, SCI_MARKERDEFINEPIXMAP, M_CI_ARROW, (long)frame_current_xpm);
90 
91 	/* frame marker current */
92 	scintilla_send_message(sci, SCI_MARKERDEFINEPIXMAP, M_FRAME, (long)frame_xpm);
93 }
94 
95 /*
96  * inits markers staff
97  */
markers_init(void)98 void markers_init(void)
99 {
100 	/* set markers in all currently opened documents */
101 	guint i;
102 	foreach_document(i)
103 		markers_set_for_document(document_index(i)->editor->sci);
104 }
105 
106 /*
107  * add breakpoint marker
108  * enabled or disabled, based on bp->enabled value
109  * arguments:
110  * 		bp - breakpoint to add marker for
111  */
markers_add_breakpoint(breakpoint * bp)112 void markers_add_breakpoint(breakpoint* bp)
113 {
114 	GeanyDocument *doc = document_find_by_filename(bp->file);
115 	if (doc)
116 	{
117 		if (!bp->enabled)
118 		{
119 			sci_set_marker_at_line(doc->editor->sci, bp->line - 1, M_BP_DISABLED);
120 		}
121 		else if (strlen(bp->condition) || bp->hitscount)
122 		{
123 				sci_set_marker_at_line(doc->editor->sci, bp->line - 1, M_BP_CONDITIONAL);
124 		}
125 		else
126 		{
127 				sci_set_marker_at_line(doc->editor->sci, bp->line - 1, M_BP_ENABLED);
128 		}
129 	}
130 }
131 
132 /*
133  * removes breakpoints marker
134  */
markers_remove_breakpoint(breakpoint * bp)135 void markers_remove_breakpoint(breakpoint *bp)
136 {
137 	static int breakpoint_markers[] = {
138 		M_BP_ENABLED,
139 		M_BP_DISABLED,
140 		M_BP_CONDITIONAL
141 	};
142 
143 	GeanyDocument *doc = document_find_by_filename(bp->file);
144 	if (doc)
145 	{
146 		int markers = scintilla_send_message(doc->editor->sci, SCI_MARKERGET, bp->line - 1, (long)NULL);
147 		int markers_count = sizeof(breakpoint_markers) / sizeof(breakpoint_markers[0]);
148 		int i = 0;
149 		for (; i < markers_count; i++)
150 		{
151 			int marker = breakpoint_markers[i];
152 			if (markers & (0x01 << marker))
153 			{
154 				sci_delete_marker_at_line(doc->editor->sci, bp->line - 1, marker);
155 			}
156 		}
157 	}
158 }
159 
160 /*
161  * adds current instruction marker
162  */
markers_add_current_instruction(char * file,int line)163 void markers_add_current_instruction(char* file, int line)
164 {
165 	GeanyDocument *doc = document_find_by_filename(file);
166 	if (doc)
167 	{
168 		sci_set_marker_at_line(doc->editor->sci, line - 1, M_CI_ARROW);
169 		sci_set_marker_at_line(doc->editor->sci, line - 1, M_CI_BACKGROUND);
170 	}
171 }
172 
173 /*
174  * removes current instruction marker
175  */
markers_remove_current_instruction(char * file,int line)176 void markers_remove_current_instruction(char* file, int line)
177 {
178 	GeanyDocument *doc = document_find_by_filename(file);
179 	if (doc)
180 	{
181 		sci_delete_marker_at_line(doc->editor->sci, line - 1, M_CI_ARROW);
182 		sci_delete_marker_at_line(doc->editor->sci, line - 1, M_CI_BACKGROUND);
183 		scintilla_send_message(doc->editor->sci, SCI_SETFOCUS, TRUE, 0);
184 	}
185 }
186 
187 /*
188  * adds frame marker
189  */
markers_add_frame(char * file,int line)190 void markers_add_frame(char* file, int line)
191 {
192 	GeanyDocument *doc = document_find_by_filename(file);
193 	if (doc)
194 	{
195 		sci_set_marker_at_line(doc->editor->sci, line - 1, M_FRAME);
196 	}
197 }
198 
199 /*
200  * removes frame marker
201  */
markers_remove_frame(char * file,int line)202 void markers_remove_frame(char* file, int line)
203 {
204 	GeanyDocument *doc = document_find_by_filename(file);
205 	if (doc)
206 	{
207 		sci_delete_marker_at_line(doc->editor->sci, line - 1, M_FRAME);
208 		scintilla_send_message(doc->editor->sci, SCI_SETFOCUS, TRUE, 0);
209 	}
210 }
211 
212 /*
213  * removes all markers from GeanyDocument
214  */
markers_remove_all(GeanyDocument * doc)215 void markers_remove_all(GeanyDocument *doc)
216 {
217 	static int markers[] = { M_BP_ENABLED, M_BP_DISABLED, M_BP_CONDITIONAL, M_CI_BACKGROUND, M_CI_ARROW, M_FRAME };
218 	int i = 0, size = sizeof(markers) / sizeof(int);
219 	for (; i < size; i++)
220 	{
221 		scintilla_send_message(doc->editor->sci, SCI_MARKERDELETEALL, markers[i], 0);
222 	}
223 }
224