1 /* GabeditTextEdit.c */
2 /**********************************************************************************************************
3 Copyright (c) 2002-2013 Abdul-Rahman Allouche. All rights reserved
4 
5 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
6 documentation files (the Gabedit), to deal in the Software without restriction, including without limitation
7 the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
8 and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9 
10   The above copyright notice and this permission notice shall be included in all copies or substantial portions
11   of the Software.
12 
13 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
14 TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
15 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
16 CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
17 DEALINGS IN THE SOFTWARE.
18 ************************************************************************************************************/
19 
20 #include "../../Config.h"
21 #include <gtk/gtk.h>
22 #include "../Common/GabeditType.h"
23 
24 /************************************************************************************************************/
gabedit_text_new()25 GtkWidget* gabedit_text_new()
26 {
27 	GtkWidget* text = gtk_text_view_new();
28 	GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text));
29 	/* GtkTextTag *found_text_tag = gtk_text_buffer_create_tag (buffer, NULL, "foreground", "red", NULL);*/
30 	GtkTextTag *found_text_tag = gtk_text_buffer_create_tag (buffer, NULL, "background", "red", NULL);
31 	g_object_set_data(G_OBJECT(text),"FoundTextTag",found_text_tag);
32 	return text;
33 }
34 /************************************************************************************************************/
gabedit_text_insert(GtkWidget * text,GdkFont * font,GdkColor * colorFore,GdkColor * colorBack,const gchar * str,gint l)35 void gabedit_text_insert(GtkWidget* text, GdkFont* font, GdkColor* colorFore, GdkColor* colorBack, const gchar* str, gint l)
36 {
37 		GtkTextBuffer *buffer;
38 		GtkTextIter match_start;
39 		GtkTextIter match_end;
40 		gint char_offset  = 0;
41 		if(!GTK_IS_TEXT_VIEW (text)) return;
42 		buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text));
43 		gtk_text_buffer_get_iter_at_mark (buffer, &match_start, gtk_text_buffer_get_mark (buffer,"insert"));
44 		char_offset = gtk_text_iter_get_offset(&match_start);
45 		gtk_text_buffer_insert_at_cursor (buffer, str, l);
46 		gtk_text_buffer_get_iter_at_mark (buffer, &match_end, gtk_text_buffer_get_mark (buffer,"insert"));
47 		gtk_text_buffer_get_iter_at_mark (buffer, &match_start, gtk_text_buffer_get_mark (buffer,"insert"));
48 		gtk_text_iter_set_offset(&match_start, char_offset );
49 
50 		if(colorFore)
51 		{
52 			GtkTextTag *tag = gtk_text_buffer_create_tag (buffer, NULL, "foreground_gdk", colorFore, NULL);
53 			gtk_text_buffer_apply_tag (buffer, tag, &match_start, &match_end);
54 			/* gtk_text_buffer_remove_tag (buffer,  tag, &match_start, &match_end);*/
55 		}
56 		if(colorBack)
57 		{
58 			GtkTextTag *tag = gtk_text_buffer_create_tag (buffer, NULL, "background_gdk", colorBack, NULL);
59 			gtk_text_buffer_apply_tag (buffer, tag, &match_start, &match_end);
60 			/* gtk_text_buffer_remove_tag (buffer,  tag, &match_start, &match_end);*/
61 		}
62 }
63 /************************************************************************************************************/
gabedit_text_get_length(GtkWidget * text)64 gint gabedit_text_get_length(GtkWidget* text)
65 {
66 		GtkTextBuffer *buffer;
67 		if(!GTK_IS_TEXT_VIEW (text)) return 0;
68 		buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text));
69 		return gtk_text_buffer_get_char_count  (buffer);
70 }
71 /************************************************************************************************************/
gabedit_text_get_chars(GtkWidget * text,gint b,gint e)72 gchar* gabedit_text_get_chars(GtkWidget* text, gint b, gint e)
73 {
74 		GtkTextBuffer *buffer;
75 		GtkTextIter start;
76 		GtkTextIter end;
77 		GtkTextIter iterStart;
78 		GtkTextIter iterEnd;
79 
80 		if(!GTK_IS_TEXT_VIEW (text)) return NULL;
81 
82 		buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text));
83 		gtk_text_buffer_get_bounds (buffer, &start, &end);
84 
85 		if(b>=0) gtk_text_buffer_get_iter_at_offset(buffer,&iterStart,b);
86 		else iterStart = start;
87 
88 		if(e>=0) gtk_text_buffer_get_iter_at_offset(buffer,&iterEnd,e);
89 		else iterEnd = end;
90 
91 		return gtk_text_iter_get_text(&iterStart, &iterEnd);
92 }
93 /************************************************************************************************************/
gabedit_text_set_point(GtkWidget * text,gint char_offset)94 void gabedit_text_set_point(GtkWidget* text, gint char_offset)
95 {
96 	GtkTextBuffer *buffer;
97 	GtkTextIter start;
98 	GtkTextIter end;
99 	GtkTextIter iter;
100 
101 	if(!GTK_IS_TEXT_VIEW (text)) return;
102 	buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text));
103 	if(!buffer) return;
104 	gtk_text_buffer_get_bounds (buffer, &start, &end);
105 	if(char_offset>=0) gtk_text_buffer_get_iter_at_offset(buffer,&iter,char_offset);
106 	else iter = end;
107 
108 	gtk_text_buffer_place_cursor(buffer, &iter);
109 }
110 /************************************************************************************************************/
gabedit_text_get_point(GtkWidget * text)111 gint gabedit_text_get_point(GtkWidget* text)
112 {
113 
114 	return 0;
115 }
116 /************************************************************************************************************/
gabedit_text_forward_delete(GtkWidget * text,gint char_offset)117 void gabedit_text_forward_delete(GtkWidget* text, gint char_offset)
118 {
119 	GtkTextBuffer *buffer;
120 	GtkTextIter start;
121 	GtkTextIter end;
122 	GtkTextIter iterBegin;
123 	GtkTextIter iterEnd;
124 
125 	if(!GTK_IS_TEXT_VIEW (text)) return;
126 	buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text));
127 	if(!buffer) return;
128 	gtk_text_buffer_get_bounds (buffer, &start, &end);
129 	gtk_text_buffer_get_iter_at_mark (buffer, &iterBegin, gtk_text_buffer_get_mark (buffer,"insert"));
130 	if(char_offset>=0)
131 	{
132 		gint char_offset_begin = gtk_text_iter_get_offset(&iterBegin);
133 		gint char_offset_end = char_offset_begin + char_offset;
134 		iterEnd = end;
135 		gtk_text_iter_set_offset(&iterEnd, char_offset_end );
136 	}
137 	else
138 	iterEnd = end;
139 
140 	gtk_text_buffer_delete(buffer, &iterBegin,&iterEnd);
141 }
142 /************************************************************************************************************/
gabedit_text_set_editable(GtkWidget * text,gboolean editable)143 void gabedit_text_set_editable(GtkWidget* text, gboolean editable)
144 {
145 	if(!GTK_IS_TEXT_VIEW (text)) return;
146 	gtk_text_view_set_editable((GtkTextView *)text, editable);
147 }
148 /************************************************************************************************************/
gabedit_text_search(GtkWidget * text,G_CONST_RETURN gchar * str,GtkTextIter * iter,gboolean forward)149 gint gabedit_text_search(GtkWidget *text, G_CONST_RETURN gchar *str, GtkTextIter* iter, gboolean forward)
150 {
151 	GtkTextTag *found_text_tag;
152 	GtkTextIter start;
153 	GtkTextIter end;
154 	GtkTextBuffer *buffer;
155 	GtkTextIter match_start;
156 	GtkTextIter match_end;
157 
158 	if(!str) return -1;
159 	if(*str == '\0') return -1;
160 
161 	if(!GTK_IS_TEXT_VIEW (text)) return -1;
162 
163 	found_text_tag = (GtkTextTag *)g_object_get_data(G_OBJECT(text),"FoundTextTag");
164 	buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text));
165 	gtk_text_buffer_get_bounds (buffer, &start, &end);
166 	gtk_text_buffer_remove_tag (buffer,  found_text_tag, &start, &end);
167 
168 	if(!gtk_text_iter_in_range(iter, &start, &end)) return -1;
169 
170 	if(forward)
171 	{
172 		gint i = 0;
173 		GtkTextIter posBegin;
174 		GtkTextIter posEnd;
175 		while(gtk_text_iter_forward_search (iter, str, GTK_TEXT_SEARCH_VISIBLE_ONLY | GTK_TEXT_SEARCH_TEXT_ONLY, &match_start, &match_end, NULL))
176 		{
177 			gtk_text_buffer_apply_tag (buffer, found_text_tag, &match_start, &match_end);
178 			if(i==0)
179 			{
180 			       	posBegin = match_start;
181 			       	posEnd = match_end;
182 			}
183 			i++;
184 			iter = &match_end;
185 		}
186 		if(i>0)
187 		{
188 			gtk_text_view_scroll_to_iter(GTK_TEXT_VIEW (text), &posBegin, 0.05, FALSE, 0.5, 0.5);
189 			gtk_text_buffer_place_cursor(buffer, &posEnd);
190 		}
191 
192 		return i;
193 	}
194 	else
195 	{
196 		gint i = 0;
197 		GtkTextIter posBegin;
198 		GtkTextIter posEnd;
199 		while(gtk_text_iter_backward_search (iter, str, GTK_TEXT_SEARCH_VISIBLE_ONLY | GTK_TEXT_SEARCH_TEXT_ONLY, &match_start, &match_end, NULL))
200 		{
201 			gtk_text_buffer_apply_tag (buffer, found_text_tag, &match_start, &match_end);
202 			if(i==0)
203 			{
204 			       	posBegin = match_start;
205 			       	posEnd = match_end;
206 			}
207 			i++;
208 			iter = &match_start;
209 		}
210 		if(i>0)
211 		{
212 			gtk_text_view_scroll_to_iter(GTK_TEXT_VIEW (text), &posBegin, 0.05, FALSE, 0.5, 0.5);
213 			gtk_text_buffer_place_cursor(buffer, &posBegin);
214 		}
215 		return i;
216 	}
217 	return -1;
218 
219 }
220 /************************************************************************************************************/
gabedit_text_search_all(GtkWidget * text,G_CONST_RETURN gchar * str)221 gint gabedit_text_search_all(GtkWidget *text, G_CONST_RETURN gchar *str)
222 {
223 	GtkTextIter start;
224 	GtkTextIter end;
225 	GtkTextBuffer *buffer;
226 
227 	if(!GTK_IS_TEXT_VIEW (text)) return -1;
228 	buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text));
229 	gtk_text_buffer_get_bounds (buffer, &start, &end);
230 	return gabedit_text_search(text, str, &start, TRUE);
231 }
232 /************************************************************************************************************/
gabedit_text_search_forward(GtkWidget * text,G_CONST_RETURN gchar * str)233 gint gabedit_text_search_forward(GtkWidget *text, G_CONST_RETURN gchar *str)
234 {
235 	GtkTextIter iter;
236 	GtkTextBuffer *buffer;
237 
238 	if(!GTK_IS_TEXT_VIEW (text)) return -1;
239 	buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text));
240 	gtk_text_buffer_get_iter_at_mark (buffer, &iter, gtk_text_buffer_get_mark (buffer,"insert"));
241 	return gabedit_text_search(text, str, &iter, TRUE);
242 }
243 /************************************************************************************************************/
gabedit_text_search_backward(GtkWidget * text,G_CONST_RETURN gchar * str)244 gint gabedit_text_search_backward(GtkWidget *text, G_CONST_RETURN gchar *str)
245 {
246 	GtkTextIter iter;
247 	GtkTextBuffer *buffer;
248 
249 	if(!GTK_IS_TEXT_VIEW (text)) return -1;
250 	buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text));
251 	gtk_text_buffer_get_iter_at_mark (buffer, &iter, gtk_text_buffer_get_mark (buffer,"insert"));
252 	return gabedit_text_search(text, str, &iter, FALSE);
253 }
254 /************************************************************************************************************/
gabedit_text_goto_end(GtkWidget * text)255 void gabedit_text_goto_end(GtkWidget *text)
256 {
257 
258 	GtkTextIter start;
259 	GtkTextIter end;
260 	GtkTextBuffer *buffer;
261 
262 	if(!GTK_IS_TEXT_VIEW (text)) return;
263 	buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text));
264 	gtk_text_buffer_get_bounds (buffer, &start, &end);
265 
266 	gtk_text_buffer_place_cursor(buffer, &end);
267 	gtk_text_view_scroll_mark_onscreen (GTK_TEXT_VIEW(text),gtk_text_buffer_get_insert(buffer));
268 
269 }
270 /************************************************************************************************************/
gabedit_text_goto_line(GtkWidget * text,gint line)271 void gabedit_text_goto_line(GtkWidget *text, gint line)
272 {
273 	GtkTextIter iter;
274 	GtkTextBuffer *buffer;
275 
276 	if(!GTK_IS_TEXT_VIEW (text)) return;
277 	buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text));
278 	gtk_text_buffer_get_iter_at_line(buffer, &iter, (gint)line);
279 	gtk_text_buffer_place_cursor(buffer, &iter);
280 	gtk_text_view_scroll_mark_onscreen (GTK_TEXT_VIEW(text),gtk_text_buffer_get_insert(buffer));
281 }
282 /************************************************************************************************************/
gabedit_text_select_all(GtkWidget * text)283 void gabedit_text_select_all(GtkWidget* text)
284 {
285 	GtkTextBuffer *buffer;
286 	GtkTextIter start_iter;
287 	GtkTextIter end_iter;
288 
289 	if(!GTK_IS_TEXT_VIEW (text)) return;
290 	buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text));
291 	gtk_text_buffer_get_bounds (buffer, &start_iter, &end_iter);
292 	gtk_text_buffer_select_range (buffer, &start_iter, &end_iter);
293 }
294 /************************************************************************************************************/
gabedit_text_cut_clipboard(GtkWidget * text)295 void gabedit_text_cut_clipboard (GtkWidget* text)
296 {
297 	GtkTextBuffer *buffer;
298 	if(!GTK_IS_TEXT_VIEW (text)) return;
299 	buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text));
300 	GtkClipboard *clipboard = gtk_widget_get_clipboard (GTK_WIDGET (text), GDK_SELECTION_CLIPBOARD);
301 
302 	gtk_text_buffer_cut_clipboard (buffer, clipboard, GTK_TEXT_VIEW(text)->editable);
303 	gtk_text_view_scroll_mark_onscreen (GTK_TEXT_VIEW(text), gtk_text_buffer_get_mark (buffer, "insert"));
304 }
305 /************************************************************************************************************/
gabedit_text_copy_clipboard(GtkWidget * text)306 void gabedit_text_copy_clipboard (GtkWidget* text)
307 {
308 	GtkTextBuffer *buffer;
309 	if(!GTK_IS_TEXT_VIEW (text)) return;
310 	buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text));
311 	GtkClipboard *clipboard = gtk_widget_get_clipboard (GTK_WIDGET (text), GDK_SELECTION_CLIPBOARD);
312 
313 	gtk_text_buffer_copy_clipboard (buffer, clipboard);
314 	gtk_text_view_scroll_mark_onscreen (GTK_TEXT_VIEW(text), gtk_text_buffer_get_mark (buffer, "insert"));
315 }
316 
317 /************************************************************************************************************/
gabedit_text_paste_clipboard(GtkWidget * text)318 void gabedit_text_paste_clipboard (GtkWidget* text)
319 {
320 	GtkTextBuffer *buffer;
321 	if(!GTK_IS_TEXT_VIEW (text)) return;
322 	buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text));
323 	GtkClipboard *clipboard = gtk_widget_get_clipboard (GTK_WIDGET (text), GDK_SELECTION_CLIPBOARD);
324 
325 	gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, GTK_TEXT_VIEW(text)->editable);
326 	gtk_text_view_scroll_mark_onscreen (GTK_TEXT_VIEW(text), gtk_text_buffer_get_mark (buffer, "insert"));
327 }
328