El domingo recién pasado (09/02) me correspondió dar la charla en irc.gnome.org sobre el uso de GtkTextView, donde explique como realizar un editor de texto básico, que pudiera cortar/copiar/pegar y dar algunos atributos a los textos (negrita, color, tachado, subrayado). Es un ejemplo bastante sencillo, pero suficientemente claro como para descubrir la forma de trabajar y familiarizarse con este widget.
El editor al final de la charla luce como la siguiente captura:

El código final se muestra a continuación. Cabe notar, que no he puesto comentarios, puestos que en la charla expliqué el funcionamiento de cada parte.
/* Ejemplo de un editor simple para la charla de GtkTextView
en #gnome-hispano en irc.gnome.org el dom 09/02/2003
(c) 2003. German Poo Caaman~o
*/
#include <gtk/gtk.h>
GtkWidget *create_window ();
void create_tags (GtkTextBuffer * buffer);
void on_button_clear_clicked (GtkButton * button, gpointer user_data);
void on_button_cut_clicked (GtkButton * button, gpointer user_data);
void on_button_copy_clicked (GtkButton * button, gpointer user_data);
void on_button_paste_clicked (GtkButton * button, gpointer user_data);
void on_button_bold_clicked (GtkButton * button, gpointer user_data);
void on_button_underline_clicked (GtkButton * button, gpointer user_data);
void on_button_strike_clicked (GtkButton * button, gpointer user_data);
void on_button_color_clicked (GtkButton * button, gpointer user_data);
int
main (int argc, char *argv[])
{
GtkWidget *window;
gtk_init (&argc, &argv);
window = create_window ();
gtk_widget_show_all (window);
gtk_main ();
return 0;
}
GtkWidget *create_window ()
{
GtkWidget *window;
GtkWidget *vbox_main;
GtkWidget *handlebox;
GtkWidget *toolbar;
GtkWidget *button_clear;
GtkWidget *button_cut;
GtkWidget *button_copy;
GtkWidget *button_paste;
GtkWidget *button_bold;
GtkWidget *button_underline;
GtkWidget *button_strike;
GtkWidget *button_color;
GtkWidget *scrolledwindow;
GtkWidget *textview;
GtkTextBuffer *buffer;
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_title (GTK_WINDOW (window), "Mini editor de texto");
gtk_window_set_default_size (GTK_WINDOW (window), 400, 500);
vbox_main = gtk_vbox_new (FALSE, 0);
gtk_container_add (GTK_CONTAINER (window), vbox_main);
handlebox = gtk_handle_box_new ();
gtk_box_pack_start (GTK_BOX (vbox_main), handlebox, FALSE, FALSE, 0);
toolbar = gtk_toolbar_new ();
gtk_container_add (GTK_CONTAINER (handlebox), toolbar);
button_clear = gtk_toolbar_insert_stock (GTK_TOOLBAR (toolbar), "gtk-clear",
NULL,
NULL, NULL, NULL, -1);
button_cut = gtk_toolbar_insert_stock (GTK_TOOLBAR (toolbar),
"gtk-cut",
NULL, NULL, NULL, NULL, -1);
button_copy = gtk_toolbar_insert_stock (GTK_TOOLBAR (toolbar),
"gtk-copy",
NULL,
NULL, NULL, NULL, -1);
button_paste = gtk_toolbar_insert_stock (GTK_TOOLBAR (toolbar),
"gtk-paste",
NULL,
NULL, NULL, NULL, -1);
gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
button_bold = gtk_toolbar_insert_stock (GTK_TOOLBAR (toolbar),
"gtk-bold",
NULL,
NULL, NULL, NULL, -1);
button_underline = gtk_toolbar_insert_stock (GTK_TOOLBAR (toolbar),
"gtk-underline",
NULL,
NULL, NULL, NULL, -1);
button_strike = gtk_toolbar_insert_stock (GTK_TOOLBAR (toolbar),
"gtk-strikethrough",
NULL,
NULL, NULL, NULL, -1);
button_color = gtk_toolbar_insert_stock (GTK_TOOLBAR (toolbar),
"gtk-select-color",
NULL,
NULL, NULL, NULL, -1);
scrolledwindow = gtk_scrolled_window_new (NULL, NULL);
gtk_box_pack_start (GTK_BOX (vbox_main), scrolledwindow, TRUE,
TRUE, 0);
textview = gtk_text_view_new ();
gtk_container_add (GTK_CONTAINER (scrolledwindow), textview);
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (textview));
create_tags (buffer);
g_signal_connect ((gpointer) window, "delete_event",
G_CALLBACK (gtk_main_quit), NULL);
g_signal_connect ((gpointer) button_clear, "clicked",
G_CALLBACK (on_button_clear_clicked),
(gpointer) textview);
g_signal_connect ((gpointer) button_cut, "clicked",
G_CALLBACK (on_button_cut_clicked),
(gpointer) textview);
g_signal_connect ((gpointer) button_copy, "clicked",
G_CALLBACK (on_button_copy_clicked),
(gpointer) textview);
g_signal_connect ((gpointer) button_paste, "clicked",
G_CALLBACK (on_button_paste_clicked),
(gpointer) textview);
g_signal_connect ((gpointer) button_bold, "clicked",
G_CALLBACK (on_button_bold_clicked),
(gpointer) textview);
g_signal_connect ((gpointer) button_underline, "clicked",
G_CALLBACK (on_button_underline_clicked),
(gpointer) textview);
g_signal_connect ((gpointer) button_strike, "clicked",
G_CALLBACK (on_button_strike_clicked),
(gpointer) textview);
g_signal_connect ((gpointer) button_color, "clicked",
G_CALLBACK (on_button_color_clicked),
(gpointer) textview);
return window;
}
void
on_button_clear_clicked (GtkButton * button, gpointer user_data)
{
GtkTextBuffer *textbuffer = NULL;
g_assert (GTK_IS_TEXT_VIEW (user_data));
textbuffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (user_data));
gtk_text_buffer_delete_selection (textbuffer, TRUE, TRUE);
}
void
on_button_copy_clicked (GtkButton * button, gpointer user_data)
{
GtkTextBuffer *textbuffer = NULL;
g_assert (GTK_IS_TEXT_VIEW (user_data));
textbuffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (user_data));
gtk_text_buffer_copy_clipboard (textbuffer,
gtk_clipboard_get (GDK_NONE));
}
void
on_button_paste_clicked (GtkButton * button, gpointer user_data)
{
GtkTextBuffer *textbuffer = NULL;
g_assert (GTK_IS_TEXT_VIEW (user_data));
textbuffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (user_data));
gtk_text_buffer_paste_clipboard (textbuffer,
gtk_clipboard_get (GDK_NONE),
NULL, TRUE);
}
void
on_button_bold_clicked (GtkButton * button, gpointer user_data)
{
GtkTextBuffer *textbuffer = NULL;
GtkTextIter start, end;
g_assert (GTK_IS_TEXT_VIEW (user_data));
textbuffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (user_data));
gtk_text_buffer_get_selection_bounds (textbuffer, &start, &end);
gtk_text_buffer_apply_tag_by_name (textbuffer, "bold", &start,
&end);
}
void
on_button_underline_clicked (GtkButton * button, gpointer user_data)
{
GtkTextBuffer *textbuffer = NULL;
GtkTextIter start, end;
g_assert (GTK_IS_TEXT_VIEW (user_data));
textbuffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (user_data));
gtk_text_buffer_get_selection_bounds (textbuffer, &start, &end);
gtk_text_buffer_apply_tag_by_name (textbuffer, "underline", &start,
&end);
}
void
on_button_strike_clicked (GtkButton * button, gpointer user_data)
{
GtkTextBuffer *textbuffer = NULL;
GtkTextIter start, end;
g_assert (GTK_IS_TEXT_VIEW (user_data));
textbuffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (user_data));
gtk_text_buffer_get_selection_bounds (textbuffer, &start, &end);
gtk_text_buffer_apply_tag_by_name (textbuffer, "strike", &start,
&end);
}
void
on_button_color_clicked (GtkButton * button, gpointer user_data)
{
GtkTextBuffer *textbuffer = NULL;
GtkTextIter start, end;
g_assert (GTK_IS_TEXT_VIEW (user_data));
textbuffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (user_data));
gtk_text_buffer_get_selection_bounds (textbuffer, &start, &end);
gtk_text_buffer_apply_tag_by_name (textbuffer, "color", &start,
&end);
}
void
create_tags (GtkTextBuffer * buffer)
{
g_assert (GTK_IS_TEXT_BUFFER (buffer));
gtk_text_buffer_create_tag (buffer, "bold",
"weight", PANGO_WEIGHT_BOLD, NULL);
gtk_text_buffer_create_tag (buffer, "underline",
"underline", PANGO_UNDERLINE_SINGLE,
NULL);
gtk_text_buffer_create_tag (buffer, "strike", "strikethrough",
TRUE, NULL);
gtk_text_buffer_create_tag (buffer, "color", "foreground", "blue",
NULL);
}