scintilla: Update scintilla with changeset 3662:1d1c06df8a2f using gtk+3
[anjuta-extras.git] / plugins / scintilla / text_editor_cbs.c
blobf6ee56e45295a6485aac45e27ce6f6b443cbea56
1 /*
2 * text_editor_cbs.
3 * Copyright (C) 2000 Kh. Naba Kumar Singh
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 #ifdef HAVE_CONFIG_H
20 # include <config.h>
21 #endif
23 #include <gtk/gtk.h>
24 #include <gdk/gdk.h>
25 #include <gdk/gdkkeysyms.h>
26 #include <ctype.h>
28 #include <libanjuta/resources.h>
29 #include <libanjuta/anjuta-utils.h>
30 #include <libanjuta/anjuta-debug.h>
32 #include "text_editor.h"
33 #include "text_editor_cbs.h"
34 #include "text-editor-iterable.h"
36 #define GTK
37 #undef PLAT_GTK
38 #define PLAT_GTK 1
39 #include "Scintilla.h"
40 #include "SciLexer.h"
41 #include "ScintillaWidget.h"
43 gboolean
44 on_text_editor_scintilla_focus_in (GtkWidget* scintilla, GdkEvent *event,
45 TextEditor *te)
47 GList *node;
49 node = te->views;
50 while (node)
52 if (aneditor_get_widget (GPOINTER_TO_INT (node->data)) == scintilla)
54 DEBUG_PRINT ("%s", "Switching editor view ...");
55 te->editor_id = GPOINTER_TO_INT (node->data);
56 te->scintilla = aneditor_get_widget (te->editor_id);
57 break;
59 node = g_list_next (node);
61 return FALSE;
64 gboolean
65 on_text_editor_text_buttonpress_event (GtkWidget * widget,
66 GdkEventButton * event,
67 gpointer user_data)
69 TextEditor *te = user_data;
70 gtk_widget_grab_focus (GTK_WIDGET (te->scintilla));
71 return FALSE;
74 gboolean
75 on_text_editor_text_keyrelease_event (GtkWidget * widget,
76 GdkEventKey * event,
77 gpointer user_data)
79 if (event->keyval == GDK_KEY_BackSpace)
81 TextEditor *te = user_data;
82 g_signal_emit_by_name(G_OBJECT(te), "backspace");
84 return FALSE;
87 gboolean
88 on_text_editor_text_event (GtkWidget * widget,
89 GdkEvent * event, gpointer user_data)
91 TextEditor *te = TEXT_EDITOR (user_data);
92 GdkEventButton *bevent;
94 if (event->type != GDK_BUTTON_PRESS)
95 return FALSE;
96 if (((GdkEventButton *) event)->button != 3)
97 return FALSE;
98 if (!text_editor_has_selection (te))
100 /* Move cursor to set breakpoints at correct line (#530689) */
101 glong pos;
102 gint x = (gint)((GdkEventButton *) event)->x;
103 gint y = (gint)((GdkEventButton *) event)->y;
105 pos = scintilla_send_message (SCINTILLA (te->scintilla), SCI_POSITIONFROMPOINT, x, y);
106 if (pos >= 0)
108 scintilla_send_message (SCINTILLA (te->scintilla), SCI_GOTOPOS, pos, 0);
111 bevent = (GdkEventButton *) event;
112 bevent->button = 1;
113 gtk_menu_popup (GTK_MENU (te->popup_menu),
114 NULL, NULL, NULL, NULL,
115 bevent->button, bevent->time);
116 return TRUE;
119 static void
120 scintilla_uri_dropped (TextEditor *te, const char *uri)
122 GtkWidget *parent;
123 // FIXME: Not possible to create a selection data anymore
124 //GtkSelectionData tmp;
126 //tmp.data = (guchar *) uri;
128 parent = gtk_widget_get_toplevel (GTK_WIDGET (te));
129 //if (parent)
130 // g_signal_emit_by_name (G_OBJECT (parent), "drag_data_received",
131 // NULL, 0, 0, &tmp, 0, 0);
132 return;
135 gboolean timerclick = FALSE;
137 static gboolean
138 click_timeout (TextEditor *te)
140 gint line = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (te),
141 "marker_line"));
143 /* If not second clic after timeout : Single Click */
144 if (timerclick)
146 timerclick = FALSE;
147 /* Emit (single) clicked signal */
148 g_signal_emit_by_name (G_OBJECT (te), "marker_clicked", FALSE, line);
150 return FALSE;
153 void
154 on_text_editor_scintilla_notify (GtkWidget * sci, gint wParam, gpointer lParam,
155 gpointer data)
157 TextEditor *te;
158 struct SCNotification *nt;
159 gint line, position;
161 te = data;
162 if (te->freeze_count != 0)
163 return;
164 nt = lParam;
165 switch (nt->nmhdr.code)
167 case SCN_URIDROPPED:
168 scintilla_uri_dropped(te, nt->text);
169 break;
170 case SCN_SAVEPOINTREACHED:
171 g_signal_emit_by_name(G_OBJECT (te), "update_save_ui");
172 break;
173 case SCN_SAVEPOINTLEFT:
174 g_signal_emit_by_name(G_OBJECT (te), "update_save_ui");
175 //FIXME:
176 // anjuta_update_title ();
177 // update_main_menubar ();
178 text_editor_update_controls (te);
179 return;
180 case SCN_UPDATEUI:
181 te->current_line = text_editor_get_current_lineno (te);
182 g_signal_emit_by_name(G_OBJECT (te), "update_ui");
183 g_signal_emit_by_name(G_OBJECT (te), "cursor-moved");
184 return;
186 case SCN_CHARADDED:
188 position = text_editor_get_current_position (te) - 1;
189 TextEditorCell *position_iter = text_editor_cell_new (te, position);
190 te->current_line = text_editor_get_current_lineno (te);
191 g_signal_emit_by_name(G_OBJECT (te), "char-added", position_iter,
192 (gchar)nt->ch);
193 g_object_unref (position_iter);
195 text_editor_suggest_completion (te);
197 return;
198 case SCN_AUTOCCANCELLED:
199 text_editor_cancel_completion (te);
200 return;
201 case SCN_AUTOCCHARDELETED:
202 text_editor_suggest_completion (te);
203 return;
204 case SCN_AUTOCSELECTION:
205 case SCN_USERLISTSELECTION:
206 text_editor_select_completion (te);
207 return;
208 case SCN_MODIFIED:
209 if (nt->modificationType & (SC_MOD_INSERTTEXT | SC_MOD_DELETETEXT))
211 TextEditorCell *position_iter =
212 text_editor_cell_new (te, nt->position);
213 gboolean added = nt->modificationType & SC_MOD_INSERTTEXT;
214 g_signal_emit_by_name (G_OBJECT (te), "changed", position_iter,
215 added, nt->length, nt->linesAdded,
216 nt->text);
217 g_object_unref (position_iter);
219 return;
220 case SCN_MARGINCLICK:
221 line = text_editor_get_line_from_position (te, nt->position);
222 if (nt->margin == 1) /* Bookmarks and Breakpoints margin */
224 /* if second click before timeout : Double click */
225 if (timerclick)
227 timerclick = FALSE;
228 text_editor_goto_line (te, line, -1, TRUE);
229 aneditor_command (te->editor_id, ANE_BOOKMARK_TOGGLE, 0, 0);
230 /* Emit (double) clicked signal */
231 g_signal_emit_by_name (G_OBJECT (te), "marker_clicked",
232 TRUE, line);
234 else
236 timerclick = TRUE;
237 g_object_set_data (G_OBJECT (te), "marker_line",
238 GINT_TO_POINTER (line));
239 /* Timeout after 400ms */
240 /* If 2 clicks before the timeout ==> Single Click */
241 g_timeout_add (400, (void*) click_timeout, te);
244 return;
245 case SCN_DWELLSTART:
247 TextEditorCell* cell = nt->position < 0 ? NULL : text_editor_cell_new (te, nt->position);
248 g_signal_emit_by_name (te, "hover-over", cell);
249 if (cell) g_object_unref (cell);
250 return;
253 case SCN_DWELLEND:
255 TextEditorCell* cell = nt->position < 0 ? NULL : text_editor_cell_new (te, nt->position);
257 text_editor_hide_hover_tip (te);
258 g_signal_emit_by_name (te, "hover-leave", cell);
259 if (cell) g_object_unref (cell);
260 return;
263 /* case SCEN_SETFOCUS:
264 case SCEN_KILLFOCUS:
265 case SCN_STYLENEEDED:
266 case SCN_DOUBLECLICK:
267 case SCN_MODIFIED:
268 case SCN_NEEDSHOWN:
270 default:
271 return;
275 void
276 on_text_editor_scintilla_size_allocate (GtkWidget * widget,
277 GtkAllocation * allocation,
278 gpointer data)
280 TextEditor *te;
281 te = data;
282 g_return_if_fail (te != NULL);
284 if (te->first_time_expose == FALSE)
285 return;
287 te->first_time_expose = FALSE;
288 text_editor_goto_line (te, te->current_line, FALSE, FALSE);