Updated Spanish translation
[anjuta-git-plugin.git] / plugins / sourceview / anjuta-view.c
blob23c92e5326f946ccbbce86caf094cd3d50f14553
1 /*
2 * anjuta-view.c
4 * Copyright (C) 1998, 1999 Alex Roberts, Evan Lawrence
5 * Copyright (C) 2000, 2002 Chema Celorio, Paolo Maggi
6 * Copyright (C) 2003-2005 Paolo Maggi
7 * Copyright (C) 2006 Johannes Schmid
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor,
22 * Boston, MA 02110-1301, USA.
26 * Modified by the anjuta Team, 1998-2005. See the AUTHORS file for a
27 * list of people on the anjuta Team.
28 * See the ChangeLog files for a list of changes.
30 * $Id$
33 #ifdef HAVE_CONFIG_H
34 #include <config.h>
35 #endif
37 #include <string.h>
38 #include <stdlib.h>
40 #include <gdk/gdkkeysyms.h>
42 #include <glib/gi18n.h>
43 #include <glib.h>
45 #include <libanjuta/anjuta-debug.h>
47 #include "anjuta-view.h"
48 #include "anjuta-encodings.h"
49 #include "sourceview.h"
50 #include "sourceview-private.h"
51 #include "anjuta-marshal.h"
53 #define ANJUTA_VIEW_SCROLL_MARGIN 0.02
55 #define ANJUTA_VIEW_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), ANJUTA_TYPE_VIEW, AnjutaViewPrivate))
57 enum {
58 CHAR_ADDED,
59 LAST_SIGNAL
62 static guint view_signals[LAST_SIGNAL] = { 0 };
64 enum
66 TAG = 0,
67 AUTOCOMPLETE,
68 SCOPE,
71 enum
73 ANJUTA_VIEW_POPUP = 1
76 struct _AnjutaViewPrivate
78 GtkTooltips *tooltips;
79 GtkWidget* popup;
80 guint scroll_idle;
81 Sourceview* sv;
84 static void anjuta_view_destroy (GtkObject *object);
85 static void anjuta_view_finalize (GObject *object);
86 static void anjuta_view_move_cursor (GtkTextView *text_view,
87 GtkMovementStep step,
88 gint count,
89 gboolean extend_selection);
90 static gint anjuta_view_focus_out (GtkWidget *widget,
91 GdkEventFocus *event);
93 static gint anjuta_view_expose (GtkWidget *widget,
94 GdkEventExpose *event);
96 static gboolean anjuta_view_key_press_event (GtkWidget *widget,
97 GdkEventKey *event);
98 static gboolean anjuta_view_button_press_event (GtkWidget *widget,
99 GdkEventButton *event);
101 G_DEFINE_TYPE(AnjutaView, anjuta_view, GTK_TYPE_SOURCE_VIEW)
103 static gboolean
104 scroll_to_cursor_real (AnjutaView *view)
106 GtkTextBuffer* buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
107 g_return_val_if_fail (buffer != NULL, FALSE);
109 gtk_text_view_scroll_to_mark (GTK_TEXT_VIEW (view),
110 gtk_text_buffer_get_insert (buffer),
111 0.25,
112 FALSE,
113 0.0,
114 0.0);
116 view->priv->scroll_idle = 0;
117 return FALSE;
120 static void
121 document_read_only_notify_handler (AnjutaDocument *document,
122 GParamSpec *pspec,
123 AnjutaView *view)
125 gtk_text_view_set_editable (GTK_TEXT_VIEW (view),
126 !anjuta_document_get_readonly (document));
129 static void
130 anjuta_view_set_property (GObject * object,
131 guint property_id,
132 const GValue * value, GParamSpec * pspec)
134 AnjutaView *self = ANJUTA_VIEW (object);
135 g_return_if_fail(value != NULL);
136 g_return_if_fail(pspec != NULL);
138 switch (property_id)
140 case ANJUTA_VIEW_POPUP:
142 GtkWidget* widget;
143 self->priv->popup = g_value_get_object (value);
144 widget = gtk_menu_get_attach_widget(GTK_MENU(self->priv->popup));
145 /* This is a very ugly hack, maybe somebody more familiar with gtk menus
146 can fix this */
147 if (widget != NULL)
148 gtk_menu_detach(GTK_MENU(self->priv->popup));
149 gtk_menu_attach_to_widget(GTK_MENU(self->priv->popup), GTK_WIDGET(self), NULL);
150 break;
152 default:
154 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
155 break;
160 static void
161 anjuta_view_get_property (GObject * object,
162 guint property_id,
163 GValue * value, GParamSpec * pspec)
165 AnjutaView *self = ANJUTA_VIEW (object);
167 g_return_if_fail(value != NULL);
168 g_return_if_fail(pspec != NULL);
170 switch (property_id)
172 case ANJUTA_VIEW_POPUP:
174 g_value_set_object (value, self->priv->popup);
175 break;
177 default:
179 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
180 break;
185 static void
186 anjuta_view_class_init (AnjutaViewClass *klass)
188 GObjectClass *object_class = G_OBJECT_CLASS (klass);
189 GtkObjectClass *gtkobject_class = GTK_OBJECT_CLASS (klass);
190 GtkTextViewClass *textview_class = GTK_TEXT_VIEW_CLASS (klass);
191 GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
192 GtkBindingSet *binding_set;
193 GParamSpec *anjuta_view_spec_popup;
195 gtkobject_class->destroy = anjuta_view_destroy;
196 object_class->finalize = anjuta_view_finalize;
197 object_class->set_property = anjuta_view_set_property;
198 object_class->get_property = anjuta_view_get_property;
200 widget_class->focus_out_event = anjuta_view_focus_out;
201 widget_class->expose_event = anjuta_view_expose;
202 widget_class->key_press_event = anjuta_view_key_press_event;
203 widget_class->button_press_event = anjuta_view_button_press_event;
205 textview_class->move_cursor = anjuta_view_move_cursor;
207 g_type_class_add_private (klass, sizeof (AnjutaViewPrivate));
209 anjuta_view_spec_popup = g_param_spec_object ("popup",
210 "Popup menu",
211 "The popup-menu to show",
212 GTK_TYPE_WIDGET,
213 G_PARAM_READWRITE);
214 g_object_class_install_property (object_class,
215 ANJUTA_VIEW_POPUP,
216 anjuta_view_spec_popup);
218 view_signals[CHAR_ADDED] =
219 g_signal_new ("char_added",
220 G_OBJECT_CLASS_TYPE (object_class),
221 G_SIGNAL_RUN_LAST,
222 G_STRUCT_OFFSET (AnjutaViewClass, char_added),
223 NULL, NULL,
224 anjuta_marshal_VOID__OBJECT_CHAR,
225 G_TYPE_NONE,
227 G_TYPE_INT,
228 G_TYPE_CHAR);
230 binding_set = gtk_binding_set_by_class (klass);
233 static void
234 move_cursor (GtkTextView *text_view,
235 const GtkTextIter *new_location,
236 gboolean extend_selection)
238 GtkTextBuffer *buffer = text_view->buffer;
240 if (extend_selection)
241 gtk_text_buffer_move_mark_by_name (buffer,
242 "insert",
243 new_location);
244 else
245 gtk_text_buffer_place_cursor (buffer, new_location);
247 gtk_text_view_scroll_to_mark (GTK_TEXT_VIEW (text_view),
248 gtk_text_buffer_get_insert (buffer),
249 ANJUTA_VIEW_SCROLL_MARGIN,
250 FALSE,
251 0.0,
252 0.0);
255 static void
256 anjuta_view_move_cursor (GtkTextView *text_view,
257 GtkMovementStep step,
258 gint count,
259 gboolean extend_selection)
261 GtkTextBuffer *buffer = text_view->buffer;
262 GtkTextMark *mark;
263 GtkTextIter cur, iter;
265 /* really make sure gtksourceview's home/end is disabled */
266 g_return_if_fail (!gtk_source_view_get_smart_home_end (
267 GTK_SOURCE_VIEW (text_view)));
269 mark = gtk_text_buffer_get_insert (buffer);
270 gtk_text_buffer_get_iter_at_mark (buffer, &cur, mark);
271 iter = cur;
273 if (step == GTK_MOVEMENT_DISPLAY_LINE_ENDS &&
274 (count == -1) && gtk_text_iter_starts_line (&iter))
276 /* Find the iter of the first character on the line. */
277 while (!gtk_text_iter_ends_line (&cur))
279 gunichar c;
281 c = gtk_text_iter_get_char (&cur);
282 if (g_unichar_isspace (c))
283 gtk_text_iter_forward_char (&cur);
284 else
285 break;
288 /* if we are clearing selection, we need to move_cursor even
289 * if we are at proper iter because selection_bound may need
290 * to be moved */
291 if (!gtk_text_iter_equal (&cur, &iter) || !extend_selection)
292 move_cursor (text_view, &cur, extend_selection);
294 else if (step == GTK_MOVEMENT_DISPLAY_LINE_ENDS &&
295 (count == 1) && gtk_text_iter_ends_line (&iter))
297 /* Find the iter of the last character on the line. */
298 while (!gtk_text_iter_starts_line (&cur))
300 gunichar c;
302 gtk_text_iter_backward_char (&cur);
303 c = gtk_text_iter_get_char (&cur);
304 if (!g_unichar_isspace (c))
306 /* We've gone one character too far. */
307 gtk_text_iter_forward_char (&cur);
308 break;
312 /* if we are clearing selection, we need to move_cursor even
313 * if we are at proper iter because selection_bound may need
314 * to be moved */
315 if (!gtk_text_iter_equal (&cur, &iter) || !extend_selection)
316 move_cursor (text_view, &cur, extend_selection);
318 else
320 /* note that we chain up to GtkTextView skipping GtkSourceView */
321 (* GTK_TEXT_VIEW_CLASS (anjuta_view_parent_class)->move_cursor) (text_view,
322 step,
323 count,
324 extend_selection);
328 static void
329 anjuta_view_init (AnjutaView *view)
331 view->priv = ANJUTA_VIEW_GET_PRIVATE (view);
334 * Set tab, fonts, wrap mode, colors, etc. according
335 * to preferences
338 g_object_set (G_OBJECT (view),
339 "wrap-mode", FALSE,
340 "show-line-numbers", TRUE,
341 "auto-indent", TRUE,
342 "tab-width", 4,
343 "insert-spaces-instead-of-tabs", FALSE,
344 "highlight-current-line", TRUE,
345 "indent-on-tab", TRUE, /* Fix #388727 */
346 "smart-home-end", FALSE, /* Never changes this */
347 NULL);
350 static void
351 anjuta_view_destroy (GtkObject *object)
353 AnjutaView *view;
355 view = ANJUTA_VIEW (object);
357 (* GTK_OBJECT_CLASS (anjuta_view_parent_class)->destroy) (object);
360 static void
361 anjuta_view_finalize (GObject *object)
363 AnjutaView *view;
365 view = ANJUTA_VIEW (object);
367 if (view->priv->tooltips != NULL)
368 g_object_unref (view->priv->tooltips);
370 if (view->priv->popup != NULL)
372 GtkWidget* widget = gtk_menu_get_attach_widget (GTK_MENU (view->priv->popup));
373 if (widget != NULL)
374 gtk_menu_detach (GTK_MENU (view->priv->popup));
377 (* G_OBJECT_CLASS (anjuta_view_parent_class)->finalize) (object);
380 static gint
381 anjuta_view_focus_out (GtkWidget *widget, GdkEventFocus *event)
383 AnjutaView *view = ANJUTA_VIEW (widget);
384 AssistWindow* assist_win = view->priv->sv->priv->assist_win;
385 AssistTip* assist_tip = view->priv->sv->priv->assist_tip;
387 if (assist_win)
388 gtk_widget_destroy(GTK_WIDGET(assist_win));
390 if (assist_tip)
391 gtk_widget_destroy(GTK_WIDGET(assist_tip));
393 gtk_widget_queue_draw (widget);
396 (* GTK_WIDGET_CLASS (anjuta_view_parent_class)->focus_out_event) (widget, event);
398 return FALSE;
403 * anjuta_view_new:
404 * @sv: a #Sourceview
406 * Creates a new #AnjutaView object displaying the @sv->priv->doc document.
407 * @doc cannot be NULL.
409 * Return value: a new #AnjutaView
411 GtkWidget *
412 anjuta_view_new (Sourceview *sv)
414 GtkWidget *view;
416 g_return_val_if_fail (ANJUTA_IS_DOCUMENT (sv->priv->document), NULL);
418 view = GTK_WIDGET (g_object_new (ANJUTA_TYPE_VIEW, NULL));
420 gtk_text_view_set_buffer (GTK_TEXT_VIEW (view),
421 GTK_TEXT_BUFFER (sv->priv->document));
423 g_signal_connect (sv->priv->document,
424 "notify::read-only",
425 G_CALLBACK (document_read_only_notify_handler),
426 view);
428 gtk_text_view_set_editable (GTK_TEXT_VIEW (view),
429 !anjuta_document_get_readonly (sv->priv->document));
431 gtk_widget_show_all (view);
433 ANJUTA_VIEW(view)->priv->sv = sv;
435 return view;
438 void
439 anjuta_view_cut_clipboard (AnjutaView *view)
441 GtkTextBuffer *buffer;
442 GtkClipboard *clipboard;
444 g_return_if_fail (ANJUTA_IS_VIEW (view));
446 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
447 g_return_if_fail (buffer != NULL);
449 clipboard = gtk_widget_get_clipboard (GTK_WIDGET (view),
450 GDK_SELECTION_CLIPBOARD);
452 /* FIXME: what is default editability of a buffer? */
453 gtk_text_buffer_cut_clipboard (buffer,
454 clipboard,
455 !anjuta_document_get_readonly (
456 ANJUTA_DOCUMENT (buffer)));
458 gtk_text_view_scroll_to_mark (GTK_TEXT_VIEW (view),
459 gtk_text_buffer_get_insert (buffer),
460 ANJUTA_VIEW_SCROLL_MARGIN,
461 FALSE,
462 0.0,
463 0.0);
466 void
467 anjuta_view_copy_clipboard (AnjutaView *view)
469 GtkTextBuffer *buffer;
470 GtkClipboard *clipboard;
472 g_return_if_fail (ANJUTA_IS_VIEW (view));
474 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
475 g_return_if_fail (buffer != NULL);
477 clipboard = gtk_widget_get_clipboard (GTK_WIDGET (view),
478 GDK_SELECTION_CLIPBOARD);
480 gtk_text_buffer_copy_clipboard (buffer, clipboard);
482 /* on copy do not scroll, we are already on screen */
485 void
486 anjuta_view_paste_clipboard (AnjutaView *view)
488 GtkTextBuffer *buffer;
489 GtkClipboard *clipboard;
491 g_return_if_fail (ANJUTA_IS_VIEW (view));
493 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
494 g_return_if_fail (buffer != NULL);
496 clipboard = gtk_widget_get_clipboard (GTK_WIDGET (view),
497 GDK_SELECTION_CLIPBOARD);
499 /* FIXME: what is default editability of a buffer? */
500 gtk_text_buffer_paste_clipboard (buffer,
501 clipboard,
502 NULL,
503 !anjuta_document_get_readonly (
504 ANJUTA_DOCUMENT (buffer)));
506 gtk_text_view_scroll_to_mark (GTK_TEXT_VIEW (view),
507 gtk_text_buffer_get_insert (buffer),
508 ANJUTA_VIEW_SCROLL_MARGIN,
509 FALSE,
510 0.0,
511 0.0);
514 void
515 anjuta_view_delete_selection (AnjutaView *view)
517 GtkTextBuffer *buffer = NULL;
519 g_return_if_fail (ANJUTA_IS_VIEW (view));
521 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
522 g_return_if_fail (buffer != NULL);
524 /* FIXME: what is default editability of a buffer? */
525 gtk_text_buffer_delete_selection (buffer,
526 TRUE,
527 !anjuta_document_get_readonly (
528 ANJUTA_DOCUMENT (buffer)));
530 gtk_text_view_scroll_to_mark (GTK_TEXT_VIEW (view),
531 gtk_text_buffer_get_insert (buffer),
532 ANJUTA_VIEW_SCROLL_MARGIN,
533 FALSE,
534 0.0,
535 0.0);
538 void
539 anjuta_view_select_all (AnjutaView *view)
541 GtkTextBuffer *buffer = NULL;
542 GtkTextIter start, end;
544 g_return_if_fail (ANJUTA_IS_VIEW (view));
546 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
547 g_return_if_fail (buffer != NULL);
549 gtk_text_buffer_get_bounds (buffer, &start, &end);
550 gtk_text_buffer_select_range (buffer, &start, &end);
553 void
554 anjuta_view_scroll_to_cursor (AnjutaView *view)
556 g_return_if_fail (ANJUTA_IS_VIEW (view));
558 view->priv->scroll_idle = g_idle_add ((GSourceFunc) scroll_to_cursor_real, view);
561 /* assign a unique name */
562 static G_CONST_RETURN gchar *
563 get_widget_name (GtkWidget *w)
565 const gchar *name;
567 name = gtk_widget_get_name (w);
568 g_return_val_if_fail (name != NULL, NULL);
570 if (strcmp (name, g_type_name (GTK_WIDGET_TYPE (w))) == 0)
572 static guint d = 0;
573 gchar *n;
575 n = g_strdup_printf ("%s_%u_%u", name, d, (guint) g_random_int);
576 d++;
578 gtk_widget_set_name (w, n);
579 g_free (n);
581 name = gtk_widget_get_name (w);
584 return name;
587 /* There is no clean way to set the cursor-color, so we are stuck
588 * with the following hack: set the name of each widget and parse
589 * a gtkrc string.
591 static void
592 modify_cursor_color (GtkWidget *textview,
593 GdkColor *color)
595 static const char cursor_color_rc[] =
596 "style \"svs-cc\"\n"
597 "{\n"
598 "GtkSourceView::cursor-color=\"#%04x%04x%04x\"\n"
599 "}\n"
600 "widget \"*.%s\" style : application \"svs-cc\"\n";
602 const gchar *name;
603 gchar *rc_temp;
605 name = get_widget_name (textview);
606 g_return_if_fail (name != NULL);
608 if (color != NULL)
610 rc_temp = g_strdup_printf (cursor_color_rc,
611 color->red,
612 color->green,
613 color->blue,
614 name);
616 else
618 GtkRcStyle *rc_style;
620 rc_style = gtk_widget_get_modifier_style (textview);
622 rc_temp = g_strdup_printf (cursor_color_rc,
623 rc_style->text [GTK_STATE_NORMAL].red,
624 rc_style->text [GTK_STATE_NORMAL].green,
625 rc_style->text [GTK_STATE_NORMAL].blue,
626 name);
629 gtk_rc_parse_string (rc_temp);
630 gtk_widget_reset_rc_styles (textview);
632 g_free (rc_temp);
635 void
636 anjuta_view_set_colors (AnjutaView *view,
637 gboolean def,
638 GdkColor *backgroud,
639 GdkColor *text,
640 GdkColor *selection,
641 GdkColor *sel_text)
644 g_return_if_fail (ANJUTA_IS_VIEW (view));
646 /* just a bit of paranoia */
647 gtk_widget_ensure_style (GTK_WIDGET (view));
649 if (!def)
651 if (backgroud != NULL)
652 gtk_widget_modify_base (GTK_WIDGET (view),
653 GTK_STATE_NORMAL, backgroud);
655 if (selection != NULL)
657 gtk_widget_modify_base (GTK_WIDGET (view),
658 GTK_STATE_SELECTED, selection);
659 gtk_widget_modify_base (GTK_WIDGET (view),
660 GTK_STATE_ACTIVE, selection);
663 if (sel_text != NULL)
665 gtk_widget_modify_text (GTK_WIDGET (view),
666 GTK_STATE_SELECTED, sel_text);
667 gtk_widget_modify_text (GTK_WIDGET (view),
668 GTK_STATE_ACTIVE, sel_text);
671 if (text != NULL)
673 gtk_widget_modify_text (GTK_WIDGET (view),
674 GTK_STATE_NORMAL, text);
675 modify_cursor_color (GTK_WIDGET (view), text);
678 else
680 GtkRcStyle *rc_style;
682 rc_style = gtk_widget_get_modifier_style (GTK_WIDGET (view));
684 rc_style->color_flags [GTK_STATE_NORMAL] = 0;
685 rc_style->color_flags [GTK_STATE_SELECTED] = 0;
686 rc_style->color_flags [GTK_STATE_ACTIVE] = 0;
688 gtk_widget_modify_style (GTK_WIDGET (view), rc_style);
692 void
693 anjuta_view_set_font (AnjutaView *view,
694 gboolean def,
695 const gchar *font_name)
698 g_return_if_fail (ANJUTA_IS_VIEW (view));
700 if (!def)
702 PangoFontDescription *font_desc = NULL;
704 g_return_if_fail (font_name != NULL);
706 font_desc = pango_font_description_from_string (font_name);
707 g_return_if_fail (font_desc != NULL);
709 gtk_widget_modify_font (GTK_WIDGET (view), font_desc);
711 pango_font_description_free (font_desc);
713 else
715 GtkRcStyle *rc_style;
717 rc_style = gtk_widget_get_modifier_style (GTK_WIDGET (view));
719 if (rc_style->font_desc)
720 pango_font_description_free (rc_style->font_desc);
722 rc_style->font_desc = NULL;
724 gtk_widget_modify_style (GTK_WIDGET (view), rc_style);
728 static gint
729 anjuta_view_expose (GtkWidget *widget,
730 GdkEventExpose *event)
732 GtkTextView *text_view;
733 AnjutaDocument *doc;
735 text_view = GTK_TEXT_VIEW (widget);
737 doc = ANJUTA_DOCUMENT (gtk_text_view_get_buffer (text_view));
739 if ((event->window == gtk_text_view_get_window (text_view, GTK_TEXT_WINDOW_TEXT)))
741 GdkRectangle visible_rect;
742 GtkTextIter iter1, iter2;
744 gtk_text_view_get_visible_rect (text_view, &visible_rect);
745 gtk_text_view_get_line_at_y (text_view, &iter1,
746 visible_rect.y, NULL);
747 gtk_text_view_get_line_at_y (text_view, &iter2,
748 visible_rect.y
749 + visible_rect.height, NULL);
750 gtk_text_iter_forward_line (&iter2);
753 return (* GTK_WIDGET_CLASS (anjuta_view_parent_class)->expose_event)(widget, event);
756 static gboolean
757 anjuta_view_key_press_event (GtkWidget *widget, GdkEventKey *event)
759 GtkTextBuffer *buffer;
760 AnjutaView* view = ANJUTA_VIEW(widget);
761 GtkTextIter iter;
762 AssistWindow* assist_win;
763 AssistTip* assist_tip;
764 SourceviewCell* cell;
766 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
768 assist_win = view->priv->sv->priv->assist_win;
769 assist_tip = view->priv->sv->priv->assist_tip;
770 if (assist_win)
772 if (assist_window_filter_keypress(assist_win, event->keyval))
774 DEBUG_PRINT("key filtered: %d", event->keyval);
775 return TRUE;
779 switch (event->keyval)
781 case GDK_Shift_L:
782 case GDK_Shift_R:
784 return TRUE;
786 default:
788 gboolean retval = (* GTK_WIDGET_CLASS (anjuta_view_parent_class)->key_press_event)(widget, event);
789 gtk_text_buffer_get_iter_at_mark(buffer, &iter,
790 gtk_text_buffer_get_insert(buffer));
791 /* Iter is at the position after the newly added character... */
792 gtk_text_iter_backward_char (&iter);
793 cell = sourceview_cell_new (&iter, GTK_TEXT_VIEW (view));
794 /* Handle char_added signal here */
795 if (event->keyval == GDK_Return)
797 g_signal_emit_by_name (G_OBJECT(view), "char_added",
798 cell, '\n');
800 else if (event->keyval == GDK_Tab)
802 g_signal_emit_by_name (G_OBJECT(view), "char_added",
803 cell, '\t');
805 else if (event->keyval == GDK_BackSpace)
807 g_signal_emit_by_name(G_OBJECT(view), "char_added",
808 cell, '\0');
810 else if (event->keyval == GDK_Escape ||
811 event->keyval == GDK_Up ||
812 event->keyval == GDK_Down)
814 if (assist_tip)
816 gtk_widget_destroy (GTK_WIDGET(assist_tip));
817 g_object_unref (cell);
818 return retval;
821 else if (event->keyval == GDK_Left || event->keyval == GDK_Right ||
822 event->keyval == GDK_Up || event->keyval == GDK_Down ||
823 event->keyval == GDK_Page_Up || event->keyval == GDK_Page_Down ||
824 event->keyval == GDK_Begin || event->keyval == GDK_End)
826 /* Ignore those for char_added */
827 g_object_unref (cell);
828 return retval;
830 else
832 gchar* unistring = g_new0(gchar, 6);
833 gunichar uc = gdk_keyval_to_unicode(event->keyval);
834 if (g_unichar_to_utf8(uc, unistring) >= 1)
836 guint read, written;
837 gchar* string = g_locale_from_utf8(unistring, 1, &read,
838 &written, NULL);
839 if (string != NULL && read == 1 && written == 1)
841 g_signal_emit_by_name (G_OBJECT(view), "char_added",
842 cell, string[0]);
844 else
846 g_object_unref (cell);
848 g_free(string);
850 g_free(unistring);
852 return retval;
857 static gboolean
858 anjuta_view_button_press_event (GtkWidget *widget, GdkEventButton *event)
860 AnjutaView* view = ANJUTA_VIEW(widget);
862 switch(event->button)
864 case 3: /* Right Button */
866 gtk_menu_popup (GTK_MENU (view->priv->popup), NULL, NULL, NULL, NULL,
867 event->button, event->time);
868 return TRUE;
870 default:
871 return (* GTK_WIDGET_CLASS (anjuta_view_parent_class)->button_press_event)(widget, event);