1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
3 * anjuta-cell-renderer-diff.c
4 * Copyright (C) 2013 James Liggett <jrliggett@cox.net>
6 * anjuta is free software: you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * anjuta is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 * See the GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include "anjuta-cell-renderer-diff.h"
22 struct _AnjutaCellRendererDiffPrivate
24 GtkCellRenderer
*text_cell
;
40 LINE_TYPE_HUNK_HEADER
,
46 G_DEFINE_TYPE (AnjutaCellRendererDiff
, anjuta_cell_renderer_diff
, GTK_TYPE_CELL_RENDERER
);
49 anjuta_cell_renderer_diff_init (AnjutaCellRendererDiff
*self
)
51 self
->priv
= G_TYPE_INSTANCE_GET_PRIVATE (self
, ANJUTA_TYPE_CELL_RENDERER_DIFF
,
52 AnjutaCellRendererDiffPrivate
);
54 self
->priv
->text_cell
= gtk_cell_renderer_text_new ();
58 anjuta_cell_renderer_diff_finalize (GObject
*object
)
60 AnjutaCellRendererDiff
*self
;
62 self
= ANJUTA_CELL_RENDERER_DIFF (object
);
64 g_object_unref (self
->priv
->text_cell
);
66 G_OBJECT_CLASS (anjuta_cell_renderer_diff_parent_class
)->finalize (object
);
70 anjuta_cell_renderer_diff_set_property (GObject
*object
, guint prop_id
, const GValue
*value
, GParamSpec
*pspec
)
72 g_return_if_fail (ANJUTA_IS_CELL_RENDERER_DIFF (object
));
77 anjuta_cell_renderer_diff_set_diff (ANJUTA_CELL_RENDERER_DIFF (object
),
78 g_value_get_string (value
));
81 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, prop_id
, pspec
);
87 anjuta_cell_renderer_diff_render (GtkCellRenderer
*cell
,
90 const GdkRectangle
*background_area
,
91 const GdkRectangle
*cell_area
,
92 GtkCellRendererState flags
)
94 AnjutaCellRendererDiff
*self
;
96 self
= ANJUTA_CELL_RENDERER_DIFF (cell
);
98 gtk_cell_renderer_render (self
->priv
->text_cell
, cr
, widget
,
99 background_area
, cell_area
, flags
);
103 anjuta_cell_renderer_diff_get_preferred_width (GtkCellRenderer
*cell
,
108 AnjutaCellRendererDiff
*self
;
110 self
= ANJUTA_CELL_RENDERER_DIFF (cell
);
112 gtk_cell_renderer_get_preferred_width (self
->priv
->text_cell
, widget
,
117 anjuta_cell_renderer_diff_get_preferred_height (GtkCellRenderer
*cell
,
122 AnjutaCellRendererDiff
*self
;
124 self
= ANJUTA_CELL_RENDERER_DIFF (cell
);
126 gtk_cell_renderer_get_preferred_height (self
->priv
->text_cell
, widget
,
131 anjuta_cell_renderer_diff_class_init (AnjutaCellRendererDiffClass
*klass
)
133 GObjectClass
*object_class
= G_OBJECT_CLASS (klass
);
134 GtkCellRendererClass
*parent_class
= GTK_CELL_RENDERER_CLASS (klass
);
136 g_type_class_add_private (klass
, sizeof (AnjutaCellRendererDiffPrivate
));
138 object_class
->finalize
= anjuta_cell_renderer_diff_finalize
;
139 object_class
->set_property
= anjuta_cell_renderer_diff_set_property
;
140 parent_class
->render
= anjuta_cell_renderer_diff_render
;
141 parent_class
->get_preferred_width
= anjuta_cell_renderer_diff_get_preferred_width
;;
142 parent_class
->get_preferred_height
= anjuta_cell_renderer_diff_get_preferred_height
;
144 g_object_class_install_property (object_class
,
146 g_param_spec_string ("diff",
154 static PangoAttrList
*
155 create_attribute_list (const gchar
*diff
)
160 list
= pango_attr_list_new ();
162 /* Make all of the text monospace */
163 pango_attr_list_insert (list
, pango_attr_family_new ("Monospace"));
165 /* Assume that diff points to one line of a unified diff */
166 type
= LINE_TYPE_CONTEXT
;
172 if (diff
[0] == '@' && diff
[1] == '@')
173 type
= LINE_TYPE_HUNK_HEADER
;
174 else if (diff
[0] == '+')
176 if (g_str_has_prefix (diff
, "+++ "))
177 type
= LINE_TYPE_HEADER
;
179 type
= LINE_TYPE_ADD
;
181 else if (diff
[0] == '-')
183 if (g_str_has_prefix (diff
, "--- "))
184 type
= LINE_TYPE_HEADER
;
186 type
= LINE_TYPE_DELETE
;
189 type
= LINE_TYPE_HEADER
;
195 case LINE_TYPE_HEADER
:
196 /* Make file headers easier to see by making them bold */
197 pango_attr_list_insert (list
,
198 pango_attr_weight_new (PANGO_WEIGHT_BOLD
));
200 case LINE_TYPE_HUNK_HEADER
:
202 pango_attr_list_insert (list
,
203 pango_attr_foreground_new (0, 0, 0x8000));
207 pango_attr_list_insert (list
,
208 pango_attr_foreground_new (0, 0x8000, 0));
210 case LINE_TYPE_DELETE
:
212 pango_attr_list_insert (list
,
213 pango_attr_foreground_new (0xffff, 0, 0));
223 anjuta_cell_renderer_diff_set_diff (AnjutaCellRendererDiff
*self
,
226 PangoAttrList
*attributes
= NULL
;
228 gchar
*diff_without_newline
= NULL
;
232 newline
= strchr (diff
, '\n');
236 diff_without_newline
= g_strndup (diff
, newline
- diff
);
237 g_object_set (G_OBJECT (self
->priv
->text_cell
),
238 "text", diff_without_newline
,
240 g_free (diff_without_newline
);
244 g_object_set (G_OBJECT (self
->priv
->text_cell
),
249 attributes
= create_attribute_list (diff
);
251 g_object_set (G_OBJECT (self
->priv
->text_cell
),
252 "attributes", attributes
,
255 pango_attr_list_unref (attributes
);
259 g_object_set (G_OBJECT (self
->priv
->text_cell
),
265 anjuta_cell_renderer_diff_new (void)
267 return g_object_new (ANJUTA_TYPE_CELL_RENDERER_DIFF
, NULL
);