[anjuta] libanjuta: Add AnjutaCellRendererDiff
- From: James Liggett <jrliggett src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [anjuta] libanjuta: Add AnjutaCellRendererDiff
- Date: Sun, 18 Aug 2013 06:50:50 +0000 (UTC)
commit dae9d988b851c172c706ffe7f4afd27b3c9ebff5
Author: James Liggett <jrliggett cox net>
Date: Wed Aug 14 16:08:24 2013 -0700
libanjuta: Add AnjutaCellRendererDiff
This custom cell renderer highlights unified diffs with the cgit color scheme
(i.e. adds are green, removes are red, and hunks are blue.)
libanjuta/Makefile.am | 4 +-
libanjuta/anjuta-cell-renderer-diff.c | 234 +++++++++++++++++++++++++++
libanjuta/anjuta-cell-renderer-diff.h | 61 +++++++
libanjuta/tests/Makefile.am | 7 +-
libanjuta/tests/anjuta-diff-renderer-test.c | 124 ++++++++++++++
5 files changed, 428 insertions(+), 2 deletions(-)
---
diff --git a/libanjuta/Makefile.am b/libanjuta/Makefile.am
index 4ac227e..d47c978 100644
--- a/libanjuta/Makefile.am
+++ b/libanjuta/Makefile.am
@@ -138,7 +138,9 @@ libanjuta_3_la_SOURCES= \
anjuta-close-button.c \
anjuta-close-button.h \
anjuta-modeline.c \
- anjuta-modeline.h
+ anjuta-modeline.h \
+ anjuta-cell-renderer-diff.c \
+ anjuta-cell-renderer-diff.h
# Glade module
if ENABLE_GLADE_CATALOG
diff --git a/libanjuta/anjuta-cell-renderer-diff.c b/libanjuta/anjuta-cell-renderer-diff.c
new file mode 100644
index 0000000..e52729b
--- /dev/null
+++ b/libanjuta/anjuta-cell-renderer-diff.c
@@ -0,0 +1,234 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * anjuta-cell-renderer-diff.c
+ * Copyright (C) 2013 James Liggett <jrliggett cox net>
+ *
+ * anjuta is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * anjuta is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "anjuta-cell-renderer-diff.h"
+
+struct _AnjutaCellRendererDiffPrivate
+{
+ GtkCellRenderer *text_cell;
+};
+
+
+enum
+{
+ PROP_0,
+
+ PROP_DIFF
+};
+
+
+
+G_DEFINE_TYPE (AnjutaCellRendererDiff, anjuta_cell_renderer_diff, GTK_TYPE_CELL_RENDERER);
+
+static void
+anjuta_cell_renderer_diff_init (AnjutaCellRendererDiff *self)
+{
+ self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, ANJUTA_TYPE_CELL_RENDERER_DIFF,
+ AnjutaCellRendererDiffPrivate);
+
+ self->priv->text_cell = gtk_cell_renderer_text_new ();
+}
+
+static void
+anjuta_cell_renderer_diff_finalize (GObject *object)
+{
+ AnjutaCellRendererDiff *self;
+
+ self = ANJUTA_CELL_RENDERER_DIFF (object);
+
+ g_object_unref (self->priv->text_cell);
+
+ G_OBJECT_CLASS (anjuta_cell_renderer_diff_parent_class)->finalize (object);
+}
+
+static void
+anjuta_cell_renderer_diff_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec
*pspec)
+{
+ g_return_if_fail (ANJUTA_IS_CELL_RENDERER_DIFF (object));
+
+ switch (prop_id)
+ {
+ case PROP_DIFF:
+ anjuta_cell_renderer_diff_set_diff (ANJUTA_CELL_RENDERER_DIFF (object),
+ g_value_get_string (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+anjuta_cell_renderer_diff_render (GtkCellRenderer *cell,
+ cairo_t *cr,
+ GtkWidget *widget,
+ const GdkRectangle *background_area,
+ const GdkRectangle *cell_area,
+ GtkCellRendererState flags)
+{
+ AnjutaCellRendererDiff *self;
+
+ self = ANJUTA_CELL_RENDERER_DIFF (cell);
+
+ gtk_cell_renderer_render (self->priv->text_cell, cr, widget,
+ background_area, cell_area, flags);
+}
+
+static void
+anjuta_cell_renderer_diff_get_preferred_width (GtkCellRenderer *cell,
+ GtkWidget *widget,
+ gint *minimum,
+ gint *natural)
+{
+ AnjutaCellRendererDiff *self;
+
+ self = ANJUTA_CELL_RENDERER_DIFF (cell);
+
+ gtk_cell_renderer_get_preferred_width (self->priv->text_cell, widget,
+ minimum, natural);
+}
+
+static void
+anjuta_cell_renderer_diff_get_preferred_height (GtkCellRenderer *cell,
+ GtkWidget *widget,
+ gint *minimum,
+ gint *natural)
+{
+ AnjutaCellRendererDiff *self;
+
+ self = ANJUTA_CELL_RENDERER_DIFF (cell);
+
+ gtk_cell_renderer_get_preferred_height (self->priv->text_cell, widget,
+ minimum, natural);
+}
+
+static void
+anjuta_cell_renderer_diff_class_init (AnjutaCellRendererDiffClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GtkCellRendererClass *parent_class = GTK_CELL_RENDERER_CLASS (klass);
+
+ g_type_class_add_private (klass, sizeof (AnjutaCellRendererDiffPrivate));
+
+ object_class->finalize = anjuta_cell_renderer_diff_finalize;
+ object_class->set_property = anjuta_cell_renderer_diff_set_property;
+ parent_class->render = anjuta_cell_renderer_diff_render;
+ parent_class->get_preferred_width = anjuta_cell_renderer_diff_get_preferred_width;;
+ parent_class->get_preferred_height = anjuta_cell_renderer_diff_get_preferred_height;
+
+ g_object_class_install_property (object_class,
+ PROP_DIFF,
+ g_param_spec_string ("diff",
+ "diff",
+ "Diff to render",
+ "",
+ G_PARAM_WRITABLE));
+}
+
+
+static PangoAttrList *
+create_attribute_list (const gchar *diff)
+{
+ PangoAttrList *list;
+ const gchar *line_begin, *line_end;
+ guint begin_index, end_index;
+ gboolean found_hunk = FALSE;
+ PangoAttribute *attribute;
+
+ list = pango_attr_list_new ();
+
+ /* Make all of the text monospace */
+ pango_attr_list_insert (list, pango_attr_family_new ("Monospace"));
+
+ line_begin = diff;
+
+ while (line_begin && *line_begin)
+ {
+ line_end = strchr (line_begin, '\n');
+
+ if (!line_end)
+ line_end = diff + strlen (line_begin);
+
+ begin_index = line_begin - diff;
+ end_index = line_end - diff;
+ attribute = NULL;
+
+ if (line_begin[0] == '@' && line_begin[1] == '@')
+ {
+ /* Dark blue */
+ attribute = pango_attr_foreground_new (0, 0, 0x8000);
+
+ /* Don't decorate diff headers */
+ found_hunk = TRUE;
+ }
+ else if (found_hunk)
+ {
+ if (line_begin[0] == '+')
+ {
+ /* Dark green */
+ attribute = pango_attr_foreground_new (0, 0x8000, 0);
+ }
+ else if (line_begin[0] == '-')
+ {
+ /* Red */
+ attribute = pango_attr_foreground_new (0xffff, 0, 0);
+ }
+ }
+
+ if (attribute)
+ {
+ attribute->start_index = begin_index;
+ attribute->end_index = end_index;
+
+ pango_attr_list_insert (list, attribute);
+ }
+
+ if (*line_end)
+ line_begin = line_end + 1;
+ else
+ line_begin = NULL;
+
+ }
+
+ return list;
+}
+
+void
+anjuta_cell_renderer_diff_set_diff (AnjutaCellRendererDiff *self,
+ const gchar *diff)
+{
+ PangoAttrList *attributes = NULL;
+
+ if (diff)
+ attributes = create_attribute_list (diff);
+
+ g_object_set (G_OBJECT (self->priv->text_cell),
+ "attributes", attributes,
+ "text", diff,
+ NULL);
+
+ pango_attr_list_unref (attributes);
+}
+
+GtkCellRenderer *
+anjuta_cell_renderer_diff_new (void)
+{
+ return g_object_new (ANJUTA_TYPE_CELL_RENDERER_DIFF, NULL);
+}
+
diff --git a/libanjuta/anjuta-cell-renderer-diff.h b/libanjuta/anjuta-cell-renderer-diff.h
new file mode 100644
index 0000000..345f1f7
--- /dev/null
+++ b/libanjuta/anjuta-cell-renderer-diff.h
@@ -0,0 +1,61 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * anjuta-cell-renderer-diff.h
+ * Copyright (C) 2013 James Liggett <jrliggett cox net>
+ *
+ * anjuta is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * anjuta is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _ANJUTA_CELL_RENDERER_DIFF_H_
+#define _ANJUTA_CELL_RENDERER_DIFF_H_
+
+#include <glib-object.h>
+#include <gtk/gtk.h>
+#include <string.h>
+
+G_BEGIN_DECLS
+
+#define ANJUTA_TYPE_CELL_RENDERER_DIFF (anjuta_cell_renderer_diff_get_type ())
+#define ANJUTA_CELL_RENDERER_DIFF(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj),
ANJUTA_TYPE_CELL_RENDERER_DIFF, AnjutaCellRendererDiff))
+#define ANJUTA_CELL_RENDERER_DIFF_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass),
ANJUTA_TYPE_CELL_RENDERER_DIFF, AnjutaCellRendererDiffClass))
+#define ANJUTA_IS_CELL_RENDERER_DIFF(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj),
ANJUTA_TYPE_CELL_RENDERER_DIFF))
+#define ANJUTA_IS_CELL_RENDERER_DIFF_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),
ANJUTA_TYPE_CELL_RENDERER_DIFF))
+#define ANJUTA_CELL_RENDERER_DIFF_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj),
ANJUTA_TYPE_CELL_RENDERER_DIFF, AnjutaCellRendererDiffClass))
+
+typedef struct _AnjutaCellRendererDiffClass AnjutaCellRendererDiffClass;
+typedef struct _AnjutaCellRendererDiff AnjutaCellRendererDiff;
+typedef struct _AnjutaCellRendererDiffPrivate AnjutaCellRendererDiffPrivate;
+
+
+struct _AnjutaCellRendererDiffClass
+{
+ GtkCellRendererClass parent_class;
+};
+
+struct _AnjutaCellRendererDiff
+{
+ GtkCellRenderer parent_instance;
+
+ AnjutaCellRendererDiffPrivate *priv;
+};
+
+GType anjuta_cell_renderer_diff_get_type (void) G_GNUC_CONST;
+void anjuta_cell_renderer_diff_set_diff (AnjutaCellRendererDiff *self,
+ const gchar *diff);
+GtkCellRenderer *anjuta_cell_renderer_diff_new (void);
+
+G_END_DECLS
+
+#endif /* _ANJUTA_CELL_RENDERER_DIFF_H_ */
+
diff --git a/libanjuta/tests/Makefile.am b/libanjuta/tests/Makefile.am
index 72d8dde..676b1d6 100644
--- a/libanjuta/tests/Makefile.am
+++ b/libanjuta/tests/Makefile.am
@@ -1,7 +1,8 @@
noinst_PROGRAMS = \
anjuta-completion-test \
anjuta-tabber-test \
- anjuta-token-test
+ anjuta-token-test \
+ anjuta-diff-renderer-test
# Include paths
AM_CPPFLAGS = \
@@ -26,6 +27,10 @@ anjuta_token_test_LDADD = $(ANJUTA_LIBS)
anjuta_token_test_SOURCES = anjuta-token-test.c \
../anjuta-token.c
+anjuta_diff_renderer_test_CFLAGS = $(LIBANJUTA_CFLAGS)
+anjuta_diff_renderer_test_LDADD = $(LIBANJUTA_LIBS) $(ANJUTA_LIBS)
+anjuta_diff_renderer_test_SOURCES = anjuta-diff-renderer-test.c
+
CLEANFILES = anjuta_token_test-anjuta-token.gcno \
anjuta_token_test-anjuta-token-test.gcno \
anjuta_token_test-anjuta-debug.gcno
diff --git a/libanjuta/tests/anjuta-diff-renderer-test.c b/libanjuta/tests/anjuta-diff-renderer-test.c
new file mode 100644
index 0000000..78dc01c
--- /dev/null
+++ b/libanjuta/tests/anjuta-diff-renderer-test.c
@@ -0,0 +1,124 @@
+/*
+ * anjuta-diff-renderer-test.c
+ *
+ * Copyright (C) 2013 - James Liggett
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <libanjuta/anjuta-cell-renderer-diff.h>
+
+enum
+{
+ COL_DIFF,
+
+ NUM_COLS
+};
+
+static void
+on_window_destroy (GtkWidget *window, gpointer user_data)
+{
+ gtk_main_quit ();
+}
+
+int
+main (int argc, char **argv)
+{
+ GtkWidget *window;
+ GtkWidget *scrolled_window;
+ GtkWidget *tree_view;
+ GtkTreeViewColumn *column;
+ GtkCellRenderer *renderer;
+ GtkListStore *list_store;
+ GtkTreeIter iter;
+ const gchar diff[] =
+ "diff --git a/libanjuta/Makefile.am b/libanjuta/Makefile.am\n"
+ "index 4ac227e..d47c978 100644\n"
+ "--- a/libanjuta/Makefile.am\n"
+ "+++ b/libanjuta/Makefile.am\n"
+ "@@ -138,7 +138,9 @@ libanjuta_3_la_SOURCES= \\\n"
+ " anjuta-close-button.c \\\n"
+ " anjuta-close-button.h \\\n"
+ " anjuta-modeline.c \\\n"
+ "- anjuta-modeline.h\n"
+ "+ anjuta-modeline.h \\\n"
+ "+ anjuta-cell-renderer-diff.c \\\n"
+ "+ anjuta-cell-renderer-diff.h\n"
+ "\n"
+ "# Glade module\n"
+ "if ENABLE_GLADE_CATALOG\n";
+
+ const gchar non_diff[] = "non-diff text";
+ const gchar hunk_line[] = "@@";
+ const gchar broken_hunk[] = "@";
+
+ gtk_init (&argc, &argv);
+
+
+ window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ gtk_window_set_title (GTK_WINDOW (window), "Diff renderer test");
+
+ scrolled_window = gtk_scrolled_window_new (NULL, NULL);
+ tree_view = gtk_tree_view_new ();
+
+ gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (tree_view), FALSE);
+
+ renderer = anjuta_cell_renderer_diff_new ();
+ column = gtk_tree_view_column_new ();
+
+ gtk_tree_view_column_pack_start (column, renderer, TRUE);
+ gtk_tree_view_column_add_attribute (column, renderer, "diff", COL_DIFF);
+ gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), column);
+
+ gtk_container_add (GTK_CONTAINER (scrolled_window), tree_view);
+ gtk_container_add (GTK_CONTAINER (window), scrolled_window);
+
+ list_store = gtk_list_store_new (NUM_COLS, G_TYPE_STRING);
+
+ /* Test general diffs */
+ gtk_list_store_append (list_store, &iter);
+ gtk_list_store_set (list_store, &iter, COL_DIFF, diff, -1);
+
+ /* Test non-diff text */
+ gtk_list_store_append (list_store, &iter);
+ gtk_list_store_set (list_store, &iter, COL_DIFF, non_diff, -1);
+
+ /* Test hunk line detection */
+ gtk_list_store_append (list_store, &iter);
+ gtk_list_store_set (list_store, &iter, COL_DIFF, hunk_line, -1);
+
+ gtk_list_store_append (list_store, &iter);
+ gtk_list_store_set (list_store, &iter, COL_DIFF, broken_hunk, -1);
+
+ /* Test empty and NULL strings */
+ gtk_list_store_append (list_store, &iter);
+ gtk_list_store_set (list_store, &iter, COL_DIFF, "", -1);
+
+ gtk_list_store_append (list_store, &iter);
+ gtk_list_store_set (list_store, &iter, COL_DIFF, NULL, -1);
+
+ gtk_tree_view_set_model (GTK_TREE_VIEW (tree_view),
+ GTK_TREE_MODEL (list_store));
+
+ g_signal_connect (G_OBJECT (window), "destroy",
+ G_CALLBACK (on_window_destroy),
+ NULL);
+
+ gtk_widget_set_size_request (window, 650, 400);
+
+ gtk_widget_show_all (window);
+ gtk_main();
+
+ return 0;
+}
\ No newline at end of file
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]