278 |
|
|
279 |
gboolean catch_mult_line_indents (GtkWidget *widget, GdkEventKey *event, gpointer data) |
gboolean catch_mult_line_indents (GtkWidget *widget, GdkEventKey *event, gpointer data) |
280 |
{ |
{ |
281 |
|
gboolean rv = FALSE; |
282 |
|
|
283 |
if (event->keyval == GDK_Tab || event->keyval == GDK_ISO_Left_Tab) |
if (event->keyval == GDK_Tab || event->keyval == GDK_ISO_Left_Tab) |
284 |
{ |
{ |
285 |
gunichar ch; |
gunichar ch; |
287 |
GtkTextIter start, end; |
GtkTextIter start, end; |
288 |
gint page; |
gint page; |
289 |
|
|
290 |
|
START_FCN |
291 |
|
|
292 |
page = GPOINTER_TO_INT (data); |
page = GPOINTER_TO_INT (data); |
293 |
|
|
294 |
gtk_text_buffer_get_selection_bounds ( |
gtk_text_buffer_get_selection_bounds ( |
295 |
FPROPS (page, Buffer), &start, &end); |
FPROPS (page, Buffer), &start, &end); |
296 |
|
|
297 |
if (gtk_text_iter_get_line (&start) == |
if (gtk_text_iter_get_line (&start) != |
298 |
gtk_text_iter_get_line (&end)) |
gtk_text_iter_get_line (&end)) |
299 |
{ |
{ |
300 |
return FALSE; |
mark = gtk_text_buffer_create_mark (FPROPS (page, Buffer), |
301 |
} |
NULL, &end, FALSE); |
302 |
|
gtk_text_buffer_begin_user_action (FPROPS (page, Buffer)); |
303 |
mark = gtk_text_buffer_create_mark (FPROPS (page, Buffer), |
|
304 |
NULL, &end, FALSE); |
/* we don't want to consider the line if it isn't really |
305 |
gtk_text_buffer_begin_user_action (FPROPS (page, Buffer)); |
being selected */ |
306 |
|
if (gtk_text_iter_ends_line (&start)) |
|
/* we don't want to consider the line if it isn't really |
|
|
being selected */ |
|
|
if (gtk_text_iter_ends_line (&start)) |
|
|
{ |
|
|
gtk_text_iter_forward_char (&start); |
|
|
} |
|
|
|
|
|
gtk_text_iter_set_line_index (&start, 0); |
|
|
|
|
|
do |
|
|
{ |
|
|
if (event->keyval == GDK_Tab) /* indent */ |
|
307 |
{ |
{ |
308 |
gtk_text_buffer_insert (FPROPS (page, Buffer), |
gtk_text_iter_forward_char (&start); |
|
&start, "\t", -1); |
|
309 |
} |
} |
310 |
else |
|
311 |
|
gtk_text_iter_set_line_index (&start, 0); |
312 |
|
|
313 |
|
do |
314 |
{ |
{ |
315 |
/* find first tab and remove it */ |
if (event->keyval == GDK_Tab) /* indent */ |
|
do |
|
316 |
{ |
{ |
317 |
ch = gtk_text_iter_get_char (&start); |
gtk_text_buffer_insert (FPROPS (page, Buffer), |
318 |
|
&start, "\t", -1); |
319 |
if (ch == '\t') |
} |
320 |
|
else |
321 |
|
{ |
322 |
|
/* find first tab and remove it */ |
323 |
|
do |
324 |
{ |
{ |
325 |
GtkTextIter next = start; |
ch = gtk_text_iter_get_char (&start); |
326 |
|
|
327 |
gtk_text_iter_forward_char (&next); |
/* if first char is a tab, remove it */ |
328 |
gtk_text_buffer_delete (FPROPS (page, Buffer), |
if (ch == '\t') |
329 |
&start, &next); |
{ |
330 |
break; |
GtkTextIter next = start; |
331 |
} |
|
332 |
|
gtk_text_iter_forward_char (&next); |
333 |
} while (ch && ch != '\r' && ch != '\n' && |
gtk_text_buffer_delete (FPROPS (page, Buffer), |
334 |
g_unichar_isspace (ch)); |
&start, &next); |
335 |
} |
break; |
336 |
|
} |
337 |
if (!gtk_text_iter_forward_line (&start)) |
/* or, if we have spaces, let's remove up to a tab's |
338 |
{ |
length */ |
339 |
break; |
else if (ch == ' ') |
340 |
} |
{ |
341 |
|
GtkTextIter next = start; |
342 |
|
guint i, tab_size; |
343 |
|
|
344 |
|
tab_size = gtk_source_view_get_tabs_width ( |
345 |
|
GTK_SOURCE_VIEW (FPROPS (page, Text))); |
346 |
|
for (i = 0; i < tab_size && |
347 |
|
gtk_text_iter_get_char (&next) == ' '; i++) |
348 |
|
{ |
349 |
|
gtk_text_iter_forward_char (&next); |
350 |
|
} |
351 |
|
gtk_text_buffer_delete (FPROPS (page, Buffer), |
352 |
|
&start, &next); |
353 |
|
break; |
354 |
|
} |
355 |
|
else |
356 |
|
{ |
357 |
|
/* not a space or tab. keep going */ |
358 |
|
gtk_text_iter_forward_char (&start); |
359 |
|
} |
360 |
|
|
361 |
|
} while (ch && ch != '\r' && ch != '\n' && |
362 |
|
g_unichar_isspace (ch)); |
363 |
|
} |
364 |
|
|
365 |
|
if (!gtk_text_iter_forward_line (&start)) |
366 |
|
{ |
367 |
|
break; |
368 |
|
} |
369 |
|
|
370 |
|
gtk_text_buffer_get_iter_at_mark (FPROPS (page, Buffer), |
371 |
|
&end, mark); |
372 |
|
|
373 |
|
} while (gtk_text_iter_compare (&start, &end) < 0); |
374 |
|
|
375 |
gtk_text_buffer_get_iter_at_mark (FPROPS (page, Buffer), |
gtk_text_buffer_end_user_action (FPROPS (page, Buffer)); |
376 |
&end, mark); |
gtk_text_buffer_delete_mark (FPROPS (page, Buffer), mark); |
377 |
|
|
378 |
} while (gtk_text_iter_compare (&start, &end) < 0); |
rv = TRUE; |
|
|
|
|
gtk_text_buffer_end_user_action (FPROPS (page, Buffer)); |
|
|
gtk_text_buffer_delete_mark (FPROPS (page, Buffer), mark); |
|
|
|
|
|
return TRUE; |
|
|
} |
|
|
|
|
|
return FALSE; |
|
|
} |
|
|
|
|
|
|
|
|
#if 0 |
|
|
/* |
|
|
** This func produces a total refresh of the syhi of the widget |
|
|
** passed in argument |
|
|
** |
|
|
** Parameters : |
|
|
** Editor Pointer to the GtkWidget to refresh |
|
|
** tos Type Of Syhi, can be: |
|
|
** tos >= 0 manually selects the language |
|
|
** tos == SYHI_AUTODETECT autodetects the language |
|
|
** tos == SYHI_DISABLE syhi is disabled |
|
|
** |
|
|
** Return Values : |
|
|
** void |
|
|
*/ |
|
|
extern void refresh_editor(GtkWidget *Editor, gint tos) |
|
|
{ |
|
|
gint Lg; |
|
|
gint CurrentPage; |
|
|
GtkTextBuffer *Buffer; |
|
|
GtkTextIter start, end; |
|
|
|
|
|
#ifdef DEBUG_FCN |
|
|
g_print(__FILE__": %s(): Begin\n", __func__); |
|
|
#endif |
|
|
CurrentPage = gtk_notebook_get_current_page (GTK_NOTEBOOK(MainNotebook)); |
|
|
Buffer = FPROPS(CurrentPage, Buffer); |
|
|
/* Language detection */ |
|
|
if (tos >= 0) |
|
|
{ |
|
|
if (tos >= MAX_LANG) |
|
|
{ |
|
|
print_msg(_("*Bug!* Selected language number is not supported")); |
|
|
Lg = -1; |
|
|
} |
|
|
else if (!Prefs.L[tos].IsDefined) |
|
|
{ |
|
|
print_msg(_("*Bug!* Selected language not defined in the wordfile")); |
|
|
Lg = -1; |
|
|
} |
|
|
else |
|
|
Lg = tos; |
|
|
} |
|
|
else if (tos == SYHI_AUTODETECT) |
|
|
Lg = guess_lang(); /* Note: guess_lang() can return -1 */ |
|
|
else if (tos == SYHI_DISABLE) |
|
|
Lg = -1; |
|
|
else |
|
|
{ |
|
|
print_msg(_("*Bug!* Invalid type of syhi")); |
|
|
Lg = -1; |
|
|
} |
|
|
/* Save the language */ |
|
|
FPROPS(CurrentPage, WidgetInfo.Lg) = Lg; |
|
|
if (FPROPS (CurrentPage, WidgetInfo.markers)) |
|
|
{ |
|
|
g_list_foreach (FPROPS (CurrentPage, WidgetInfo.markers), (GFunc) g_free, NULL); |
|
|
g_list_free (FPROPS (CurrentPage, WidgetInfo.markers)); |
|
|
} |
|
|
/* Do the refesh */ |
|
|
gtk_text_buffer_get_bounds (Buffer, &start, &end); |
|
|
gtk_text_buffer_remove_all_tags (Buffer, &start, &end); |
|
|
gtk_widget_queue_draw (Editor); |
|
|
if (Lg == -1) |
|
|
{ |
|
|
gint i; |
|
|
|
|
|
gtk_text_buffer_get_bounds (Buffer, &start, &end); |
|
|
gtk_text_buffer_remove_all_tags (Buffer, &start, &end); |
|
|
FPROPS(CurrentPage, WidgetInfo.string0_tag) = NULL; |
|
|
FPROPS(CurrentPage, WidgetInfo.string1_tag) = NULL; |
|
|
FPROPS(CurrentPage, WidgetInfo.comment_tag) = NULL; |
|
|
FPROPS(CurrentPage, WidgetInfo.comment_alt_tag) = NULL; |
|
|
FPROPS(CurrentPage, WidgetInfo.number_tag) = NULL; |
|
|
|
|
|
for (i = 0; i < MAX_COL; i++) |
|
|
{ |
|
|
FPROPS(CurrentPage, WidgetInfo.keyword_tags[i]) = NULL; |
|
|
} |
|
|
|
|
|
FPROPS(CurrentPage, WidgetInfo.markers) = NULL; |
|
|
|
|
|
} |
|
|
else |
|
|
{ |
|
|
gint i; |
|
|
for (i = 0; i < MAX_COL; i++) |
|
|
{ |
|
|
FPROPS(CurrentPage, WidgetInfo.keyword_tags[i]) = gtk_text_buffer_create_tag (Buffer, |
|
|
NULL, "foreground-gdk", &Prefs.Colors.L[Lg].C[i], NULL); |
|
|
} |
|
|
|
|
|
FPROPS(CurrentPage, WidgetInfo.number_tag) = gtk_text_buffer_create_tag (Buffer, |
|
|
NULL, "foreground-gdk", &Prefs.Colors.L[Lg].Number, NULL); |
|
|
|
|
|
FPROPS(CurrentPage, WidgetInfo.string0_tag) = gtk_text_buffer_create_tag (Buffer, |
|
|
NULL, "foreground-gdk", &Prefs.Colors.L[Lg].String0, NULL); |
|
|
FPROPS(CurrentPage, WidgetInfo.string1_tag) = gtk_text_buffer_create_tag (Buffer, |
|
|
NULL, "foreground-gdk", &Prefs.Colors.L[Lg].String1, NULL); |
|
|
FPROPS(CurrentPage, WidgetInfo.comment_tag) = gtk_text_buffer_create_tag (Buffer, |
|
|
NULL, "foreground-gdk", &Prefs.Colors.L[Lg].Comment, NULL); |
|
|
FPROPS(CurrentPage, WidgetInfo.comment_alt_tag) = gtk_text_buffer_create_tag (Buffer, |
|
|
NULL, "foreground-gdk", &Prefs.Colors.L[Lg].CommentAlt, NULL); |
|
|
|
|
|
FPROPS(CurrentPage, WidgetInfo.markers) = NULL; |
|
|
refresh_syhi_all (GTK_TEXT_VIEW (Editor)); |
|
|
} |
|
|
#ifdef DEBUG_FCN |
|
|
g_print(__FILE__": %s(): End\n", __func__); |
|
|
#endif |
|
|
return ; |
|
|
} |
|
|
|
|
|
|
|
|
void auto_indent_on_insert (GtkTextBuffer *Buffer, GtkTextIter *iter, gchar *text, |
|
|
gint size, gpointer data) |
|
|
{ |
|
|
GtkTextIter start, end; |
|
|
gboolean ends_in_brace; |
|
|
gunichar ch = 0; |
|
|
gchar *indentation, *tmp; |
|
|
gchar *indent_str; |
|
|
gint CurrentPage; |
|
|
|
|
|
START_FCN |
|
|
|
|
|
CurrentPage = gtk_notebook_get_current_page (GTK_NOTEBOOK(MainNotebook)); |
|
|
|
|
|
if (!Settings.auto_indent || FPROPS(CurrentPage, WidgetInfo.Lg) == -1 || |
|
|
!Prefs.L[FPROPS(CurrentPage, WidgetInfo.Lg)].IndentString) |
|
|
{ |
|
|
return; |
|
|
} |
|
|
|
|
|
if (size != 1 || !(*text == '\n' || *text == '\r')) |
|
|
{ |
|
|
return; |
|
|
} |
|
|
|
|
|
indent_str = Prefs.L[FPROPS(CurrentPage, WidgetInfo.Lg)].IndentString; |
|
|
|
|
|
start = *iter; |
|
|
|
|
|
/* does this line end with an indent string? */ |
|
|
do |
|
|
{ |
|
|
if (gtk_text_iter_get_line_offset (&start) == 0) |
|
|
break; |
|
|
|
|
|
gtk_text_iter_backward_cursor_position (&start); |
|
|
} |
|
|
while (g_unichar_isspace ((ch = gtk_text_iter_get_char (&start)))); |
|
|
|
|
|
gtk_text_iter_forward_char (&start); |
|
|
end = start; |
|
|
gtk_text_iter_backward_chars (&start, strlen (indent_str)); |
|
|
|
|
|
tmp = gtk_text_iter_get_text (&start, &end); |
|
|
ends_in_brace = indent_str ? starts_string (tmp, 0, indent_str, NULL) : FALSE; |
|
|
g_free (tmp); |
|
|
|
|
|
/* ok, let's get indentation amount */ |
|
|
gtk_text_iter_set_line_offset (&start, 0); |
|
|
|
|
|
ch = gtk_text_iter_get_char (&start); |
|
|
if (ch == '\r' || ch == '\n') |
|
|
return; |
|
|
|
|
|
end = start; |
|
|
while (g_unichar_isspace ((ch = gtk_text_iter_get_char (&end)))) |
|
|
{ |
|
|
if (ch == '\r' || ch == '\n') |
|
|
break; |
|
|
|
|
|
gtk_text_iter_forward_cursor_position (&end); |
|
|
} |
|
|
|
|
|
tmp = gtk_text_iter_get_text (&start, &end); |
|
|
|
|
|
if (strcmp (tmp, "") == 0 && !ends_in_brace) |
|
|
{ |
|
|
g_free (tmp); |
|
|
return; |
|
|
} |
|
|
|
|
|
indentation = g_strdup_printf ("%s%s", text, tmp); |
|
|
g_free (tmp); |
|
|
|
|
|
if (ends_in_brace) |
|
|
{ |
|
|
tmp = indentation; |
|
|
indentation = g_strdup_printf ("%s%s", indentation, "\t"); |
|
|
g_free (tmp); |
|
|
} |
|
|
|
|
|
start = *iter; |
|
|
|
|
|
if (strcmp (indentation, "") != 0) |
|
|
{ |
|
|
g_signal_stop_emission_by_name (Buffer, "insert-text"); |
|
|
gtk_text_buffer_insert (Buffer, iter, indentation, -1); |
|
|
} |
|
|
|
|
|
g_free (indentation); |
|
|
|
|
|
END_FCN |
|
|
} |
|
|
|
|
|
void auto_unindent_on_insert (GtkTextBuffer *Buffer, GtkTextIter *iter, gchar *text, |
|
|
gint size, gpointer data) |
|
|
{ |
|
|
GtkTextIter start, origin; |
|
|
gchar *tmp; |
|
|
gchar *unindent_str; |
|
|
gint CurrentPage; |
|
|
|
|
|
START_FCN |
|
|
|
|
|
CurrentPage = gtk_notebook_get_current_page (GTK_NOTEBOOK(MainNotebook)); |
|
|
|
|
|
if (!Settings.auto_indent || FPROPS(CurrentPage, WidgetInfo.Lg) == -1 || |
|
|
!Prefs.L[FPROPS(CurrentPage, WidgetInfo.Lg)].UnindentString) |
|
|
{ |
|
|
return; |
|
|
} |
|
|
|
|
|
unindent_str = Prefs.L[FPROPS(CurrentPage, WidgetInfo.Lg)].UnindentString; |
|
|
|
|
|
if (strncmp (text, unindent_str, size)) |
|
|
return; |
|
|
|
|
|
origin = start = *iter; |
|
|
|
|
|
gtk_text_iter_backward_chars (&origin, size); |
|
|
gtk_text_iter_set_line_offset (&start, 0); |
|
|
|
|
|
tmp = gtk_text_iter_get_text (&start, &origin); |
|
|
|
|
|
g_strchug (tmp); |
|
|
/* we only want to unindent if this is the first char */ |
|
|
if (strcmp (tmp, "")) |
|
|
return; |
|
|
g_free (tmp); |
|
|
|
|
|
while (!gtk_text_iter_equal (&start, iter)) |
|
|
{ |
|
|
if (gtk_text_iter_get_char (&start) == '\t') |
|
|
{ |
|
|
GtkTextIter after = start; |
|
|
gtk_text_iter_forward_char (&after); |
|
379 |
|
|
380 |
g_signal_stop_emission_by_name (Buffer, "insert-text"); // cause we are deleting here |
END_FCN |
|
g_signal_handlers_block_by_func ( |
|
|
Buffer, G_CALLBACK (refresh_syhi_on_delete), NULL); |
|
|
gtk_text_buffer_delete_interactive (Buffer, &start, &after, TRUE); |
|
|
g_signal_handlers_unblock_by_func ( |
|
|
Buffer, G_CALLBACK (refresh_syhi_on_delete), NULL); |
|
|
break; |
|
381 |
} |
} |
|
|
|
|
gtk_text_iter_forward_cursor_position (&start); |
|
382 |
} |
} |
383 |
|
|
384 |
END_FCN |
return rv; |
385 |
} |
} |
|
#endif |
|