Fix clang compile errors
[geeqie.git] / src / cellrenderericon.c
index 14f12f1..5f42e1c 100644 (file)
@@ -1,35 +1,38 @@
-/* cellrenderericon.c, based on:
+/*
+ * Copyright (C) 2000 Red Hat, Inc., Jonathan Blandford <jrb@redhat.com>
+ * Copyright (C) 2008 - 2016 The Geeqie Team
  *
- * gtkcellrendererpixbuf.c
- * Copyright (C) 2000  Red Hat, Inc.,  Jonathan Blandford <jrb@redhat.com>
+ * 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 library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
+ * 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
- * Library General Public License for more details.
+ * 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 Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
 #include <stdlib.h>
+#include <gtk/gtk.h> /* To define GTK_CHECK_VERSION */
 #include "cellrenderericon.h"
 #include "intl.h"
 
 
 #define FIXED_ICON_SIZE_MAX 512
 
+#define TOGGLE_WIDTH 13
+#define TOGGLE_SPACING 18
+
+
 static void gqv_cell_renderer_icon_get_property(GObject                *object,
-                                               guint           param_id,
-                                               GValue          *value,
-                                               GParamSpec      *pspec);
+                                               guint           param_id,
+                                               GValue          *value,
+                                               GParamSpec      *pspec);
 static void gqv_cell_renderer_icon_set_property(GObject                *object,
                                                guint           param_id,
                                                const GValue    *value,
@@ -37,13 +40,31 @@ static void gqv_cell_renderer_icon_set_property(GObject             *object,
 static void gqv_cell_renderer_icon_init(GQvCellRendererIcon *celltext);
 static void gqv_cell_renderer_icon_class_init(GQvCellRendererIconClass *class);
 static void gqv_cell_renderer_icon_finalize(GObject *object);
-static void gqv_cell_renderer_icon_get_size(GtkCellRenderer    *cell,
-                                           GtkWidget           *widget,
-                                           GdkRectangle        *rectangle,
-                                           gint                *x_offset,
-                                           gint                *y_offset,
-                                           gint                *width,
-                                           gint                *height);
+#if GTK_CHECK_VERSION(3,0,0)
+static void gqv_cell_renderer_icon_get_size(GtkCellRenderer    *cell,
+                                           GtkWidget          *widget,
+                                           const GdkRectangle *rectangle,
+                                           gint               *x_offset,
+                                           gint               *y_offset,
+                                           gint               *width,
+                                           gint               *height);
+#else
+static void gqv_cell_renderer_icon_get_size(GtkCellRenderer    *cell,
+                                           GtkWidget          *widget,
+                                           GdkRectangle       *rectangle,
+                                           gint               *x_offset,
+                                           gint               *y_offset,
+                                           gint               *width,
+                                           gint               *height);
+#endif
+#if GTK_CHECK_VERSION(3,0,0)
+static void gqv_cell_renderer_icon_render(GtkCellRenderer *cell,
+                                          cairo_t *cr,
+                                          GtkWidget *widget,
+                                          const GdkRectangle *background_area,
+                                          const GdkRectangle *cell_area,
+                                          GtkCellRendererState flags);
+#else
 static void gqv_cell_renderer_icon_render(GtkCellRenderer      *cell,
                                           GdkWindow            *window,
                                           GtkWidget            *widget,
@@ -51,7 +72,31 @@ static void gqv_cell_renderer_icon_render(GtkCellRenderer    *cell,
                                           GdkRectangle         *cell_area,
                                           GdkRectangle         *expose_area,
                                           GtkCellRendererState flags);
+#endif
+
+
+#if GTK_CHECK_VERSION(3,0,0)
+static gboolean gqv_cell_renderer_icon_activate(GtkCellRenderer      *cell,
+                                               GdkEvent             *event,
+                                               GtkWidget            *widget,
+                                               const gchar          *path,
+                                               const GdkRectangle   *background_area,
+                                               const GdkRectangle   *cell_area,
+                                               GtkCellRendererState  flags);
+#else
+static gboolean gqv_cell_renderer_icon_activate(GtkCellRenderer      *cell,
+                                               GdkEvent             *event,
+                                               GtkWidget            *widget,
+                                               const gchar          *path,
+                                               GdkRectangle         *background_area,
+                                               GdkRectangle         *cell_area,
+                                               GtkCellRendererState  flags);
+#endif
 
+enum {
+  TOGGLED,
+  LAST_SIGNAL
+};
 
 enum {
        PROP_ZERO,
@@ -65,13 +110,19 @@ enum {
 
        PROP_BACKGROUND_SET,
        PROP_FOREGROUND_SET,
-       PROP_SHOW_TEXT
+       PROP_SHOW_TEXT,
+       PROP_SHOW_MARKS,
+       PROP_NUM_MARKS,
+       PROP_MARKS,
+       PROP_TOGGLED
 };
 
+static guint toggle_cell_signals[LAST_SIGNAL] = { 0 };
+
 static gpointer parent_class;
 
 GType
-gqv_cell_renderer_icon_get_type (void)
+gqv_cell_renderer_icon_get_type(void)
 {
        static GType cell_icon_type = 0;
 
@@ -79,39 +130,40 @@ gqv_cell_renderer_icon_get_type (void)
                {
                static const GTypeInfo cell_icon_info =
                        {
-                       sizeof (GQvCellRendererIconClass),
+                       sizeof(GQvCellRendererIconClass), /* class_size */
                        NULL,           /* base_init */
                        NULL,           /* base_finalize */
-                       (GClassInitFunc) gqv_cell_renderer_icon_class_init,
+                       (GClassInitFunc) gqv_cell_renderer_icon_class_init, /* class_init */
                        NULL,           /* class_finalize */
                        NULL,           /* class_data */
-                       sizeof (GQvCellRendererIcon),
+                       sizeof(GQvCellRendererIcon), /* instance_size */
                        0,              /* n_preallocs */
-               (GInstanceInitFunc) gqv_cell_renderer_icon_init,
-               };
+                       (GInstanceInitFunc) gqv_cell_renderer_icon_init, /* instance_init */
+                       NULL,           /* value_table */
+                       };
 
-       cell_icon_type = g_type_register_static(GTK_TYPE_CELL_RENDERER,
-                                               "GQvCellRendererIcon",
-                                               &cell_icon_info, 0);
-       }
+               cell_icon_type = g_type_register_static(GTK_TYPE_CELL_RENDERER,
+                                                       "GQvCellRendererIcon",
+                                                       &cell_icon_info, 0);
+               }
 
        return cell_icon_type;
 }
 
 static void
-gqv_cell_renderer_icon_init (GQvCellRendererIcon *cellicon)
+gqv_cell_renderer_icon_init(GQvCellRendererIcon *cellicon)
 {
-       GTK_CELL_RENDERER(cellicon)->xpad = 2;
-       GTK_CELL_RENDERER(cellicon)->ypad = 2;
+       g_object_set(G_OBJECT(cellicon), "mode", GTK_CELL_RENDERER_MODE_ACTIVATABLE, NULL);
+       gtk_cell_renderer_set_padding(GTK_CELL_RENDERER(cellicon), 2, 2);
 }
 
 static void
-gqv_cell_renderer_icon_class_init (GQvCellRendererIconClass *class)
+gqv_cell_renderer_icon_class_init(GQvCellRendererIconClass *class)
 {
-       GObjectClass *object_class = G_OBJECT_CLASS (class);
-       GtkCellRendererClass *cell_class = GTK_CELL_RENDERER_CLASS (class);
+       GObjectClass *object_class = G_OBJECT_CLASS(class);
+       GtkCellRendererClass *cell_class = GTK_CELL_RENDERER_CLASS(class);
 
-       parent_class = g_type_class_peek_parent (class);
+       parent_class = g_type_class_peek_parent(class);
 
        object_class->finalize = gqv_cell_renderer_icon_finalize;
 
@@ -120,52 +172,53 @@ gqv_cell_renderer_icon_class_init (GQvCellRendererIconClass *class)
 
        cell_class->get_size = gqv_cell_renderer_icon_get_size;
        cell_class->render = gqv_cell_renderer_icon_render;
+       cell_class->activate = gqv_cell_renderer_icon_activate;
 
        g_object_class_install_property(object_class,
                                        PROP_PIXBUF,
                                        g_param_spec_object("pixbuf",
-                                                       _("Pixbuf Object"),
-                                                       _("The pixbuf to render"),
+                                                       "Pixbuf Object",
+                                                       "The pixbuf to render",
                                                        GDK_TYPE_PIXBUF,
                                                        G_PARAM_READWRITE));
 
        g_object_class_install_property(object_class,
                                        PROP_TEXT,
                                        g_param_spec_string("text",
-                                                       _("Text"),
-                                                       _("Text to render"),
+                                                       "Text",
+                                                       "Text to render",
                                                        NULL,
                                                        G_PARAM_READWRITE));
 
        g_object_class_install_property(object_class,
                                        PROP_BACKGROUND_GDK,
                                        g_param_spec_boxed("background_gdk",
-                                                       _("Background color"),
-                                                       _("Background color as a GdkColor"),
+                                                       "Background color",
+                                                       "Background color as a GdkColor",
                                                        GDK_TYPE_COLOR,
                                                        G_PARAM_READWRITE));
 
        g_object_class_install_property(object_class,
                                        PROP_FOREGROUND_GDK,
                                        g_param_spec_boxed("foreground_gdk",
-                                                       _("Foreground color"),
-                                                       _("Foreground color as a GdkColor"),
+                                                       "Foreground color",
+                                                       "Foreground color as a GdkColor",
                                                        GDK_TYPE_COLOR,
                                                        G_PARAM_READWRITE));
 
        g_object_class_install_property(object_class,
                                        PROP_FOCUSED,
-                                       g_param_spec_boolean ("has_focus",
-                                                       _("Focus"),
-                                                       _("Draw focus indicator"),
+                                       g_param_spec_boolean("has_focus",
+                                                       "Focus",
+                                                       "Draw focus indicator",
                                                        FALSE,
                                                        G_PARAM_READWRITE));
 
        g_object_class_install_property(object_class,
                                        PROP_FIXED_WIDTH,
                                        g_param_spec_int("fixed_width",
-                                                       _("Fixed width"),
-                                                       _("Width of cell"),
+                                                       "Fixed width",
+                                                       "Width of cell",
                                                        -1, FIXED_ICON_SIZE_MAX,
                                                        -1,
                                                        G_PARAM_READWRITE));
@@ -173,8 +226,8 @@ gqv_cell_renderer_icon_class_init (GQvCellRendererIconClass *class)
        g_object_class_install_property(object_class,
                                        PROP_FIXED_HEIGHT,
                                        g_param_spec_int("fixed_height",
-                                                       _("Fixed height"),
-                                                       _("Height of icon excluding text"),
+                                                       "Fixed height",
+                                                       "Height of icon excluding text",
                                                        -1, FIXED_ICON_SIZE_MAX,
                                                        -1,
                                                        G_PARAM_READWRITE));
@@ -182,38 +235,83 @@ gqv_cell_renderer_icon_class_init (GQvCellRendererIconClass *class)
        g_object_class_install_property(object_class,
                                        PROP_BACKGROUND_SET,
                                        g_param_spec_boolean("background_set",
-                                                       _("Background set"),
-                                                       _("Whether this tag affects the background color"),
+                                                       "Background set",
+                                                       "Whether this tag affects the background color",
                                                        FALSE,
                                                        G_PARAM_READWRITE));
 
        g_object_class_install_property(object_class,
                                        PROP_FOREGROUND_SET,
-                                       g_param_spec_boolean ("foreground_set",
-                                                       _("Foreground set"),
-                                                       _("Whether this tag affects the foreground color"),
+                                       g_param_spec_boolean("foreground_set",
+                                                       "Foreground set",
+                                                       "Whether this tag affects the foreground color",
                                                        FALSE,
                                                        G_PARAM_READWRITE));
 
        g_object_class_install_property(object_class,
                                        PROP_SHOW_TEXT,
                                        g_param_spec_boolean("show_text",
-                                                       _("Show text"),
-                                                       _("Whether the text is displayed"),
+                                                       "Show text",
+                                                       "Whether the text is displayed",
                                                        TRUE,
                                                        G_PARAM_READWRITE));
+
+       g_object_class_install_property(object_class,
+                                       PROP_SHOW_MARKS,
+                                       g_param_spec_boolean("show_marks",
+                                                       "Show marks",
+                                                       "Whether the marks are displayed",
+                                                       TRUE,
+                                                       G_PARAM_READWRITE));
+
+       g_object_class_install_property(object_class,
+                                       PROP_NUM_MARKS,
+                                       g_param_spec_int("num_marks",
+                                                       "Number of marks",
+                                                       "Number of marks",
+                                                       0, 32,
+                                                       6,
+                                                       G_PARAM_READWRITE));
+
+       g_object_class_install_property(object_class,
+                                       PROP_MARKS,
+                                       g_param_spec_uint("marks",
+                                                       "Marks",
+                                                       "Marks bit array",
+                                                       0, 0xffffffff,
+                                                       0,
+                                                       G_PARAM_READWRITE));
+
+       g_object_class_install_property(object_class,
+                                       PROP_TOGGLED,
+                                       g_param_spec_uint("toggled_mark",
+                                                       "Toggled mark",
+                                                       "Toggled mark",
+                                                       0, 32,
+                                                       0,
+                                                       G_PARAM_READWRITE));
+       toggle_cell_signals[TOGGLED] =
+               g_signal_new("toggled",
+               G_OBJECT_CLASS_TYPE (object_class),
+               G_SIGNAL_RUN_LAST,
+               G_STRUCT_OFFSET (GQvCellRendererIconClass, toggled),
+               NULL, NULL,
+               g_cclosure_marshal_VOID__STRING,
+               G_TYPE_NONE, 1,
+               G_TYPE_STRING);
+
 }
 
 static void
-gqv_cell_renderer_icon_finalize (GObject *object)
+gqv_cell_renderer_icon_finalize(GObject *object)
 {
-       GQvCellRendererIcon *cellicon = GQV_CELL_RENDERER_ICON (object);
+       GQvCellRendererIcon *cellicon = GQV_CELL_RENDERER_ICON(object);
 
-       if (cellicon->pixbuf) g_object_unref (cellicon->pixbuf);
+       if (cellicon->pixbuf) g_object_unref(cellicon->pixbuf);
 
        g_free(cellicon->text);
 
-       (* G_OBJECT_CLASS (parent_class)->finalize) (object);
+       (*(G_OBJECT_CLASS(parent_class))->finalize)(object);
 }
 
 static void
@@ -222,16 +320,15 @@ gqv_cell_renderer_icon_get_property(GObject       *object,
                                    GValue      *value,
                                    GParamSpec  *pspec)
 {
-       GQvCellRendererIcon *cellicon = GQV_CELL_RENDERER_ICON (object);
-  
+       GQvCellRendererIcon *cellicon = GQV_CELL_RENDERER_ICON(object);
+
        switch (param_id)
-               {
-               case PROP_PIXBUF:
-               g_value_set_object(value,
-                                  cellicon->pixbuf ? G_OBJECT (cellicon->pixbuf) : NULL);
+       {
+       case PROP_PIXBUF:
+               g_value_set_object(value, cellicon->pixbuf ? G_OBJECT(cellicon->pixbuf) : NULL);
                break;
        case PROP_TEXT:
-               g_value_set_string (value, cellicon->text);
+               g_value_set_string(value, cellicon->text);
                break;
        case PROP_BACKGROUND_GDK:
                {
@@ -241,7 +338,7 @@ gqv_cell_renderer_icon_get_property(GObject *object,
                color.green = cellicon->background.green;
                color.blue = cellicon->background.blue;
 
-               g_value_set_boxed (value, &color);
+               g_value_set_boxed(value, &color);
                }
                break;
        case PROP_FOREGROUND_GDK:
@@ -252,11 +349,11 @@ gqv_cell_renderer_icon_get_property(GObject       *object,
                color.green = cellicon->foreground.green;
                color.blue = cellicon->foreground.blue;
 
-               g_value_set_boxed (value, &color);
+               g_value_set_boxed(value, &color);
                }
                break;
        case PROP_FOCUSED:
-               g_value_set_boolean (value, cellicon->focused);
+               g_value_set_boolean(value, cellicon->focused);
                break;
        case PROP_FIXED_WIDTH:
                g_value_set_int(value, cellicon->fixed_width);
@@ -273,15 +370,27 @@ gqv_cell_renderer_icon_get_property(GObject       *object,
        case PROP_SHOW_TEXT:
                g_value_set_boolean(value, cellicon->show_text);
                break;
+       case PROP_SHOW_MARKS:
+               g_value_set_boolean(value, cellicon->show_marks);
+               break;
+       case PROP_NUM_MARKS:
+               g_value_set_int(value, cellicon->num_marks);
+               break;
+       case PROP_MARKS:
+               g_value_set_uint(value, cellicon->marks);
+               break;
+       case PROP_TOGGLED:
+               g_value_set_uint(value, cellicon->toggled_mark);
+               break;
        default:
-               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+               G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
                break;
        }
 }
 
 static void
-set_bg_color (GQvCellRendererIcon *cellicon,
-             GdkColor            *color)
+set_bg_color(GQvCellRendererIcon *cellicon,
+            GdkColor             *color)
 {
        if (color)
                {
@@ -305,8 +414,8 @@ set_bg_color (GQvCellRendererIcon *cellicon,
                }
 }
 
-static void set_fg_color (GQvCellRendererIcon *cellicon,
-                         GdkColor            *color)
+static void set_fg_color(GQvCellRendererIcon *cellicon,
+                        GdkColor             *color)
 {
        if (color)
                {
@@ -336,19 +445,19 @@ gqv_cell_renderer_icon_set_property(GObject               *object,
                                    const GValue        *value,
                                    GParamSpec          *pspec)
 {
-       GQvCellRendererIcon *cellicon = GQV_CELL_RENDERER_ICON (object);
-  
+       GQvCellRendererIcon *cellicon = GQV_CELL_RENDERER_ICON(object);
+
        switch (param_id)
+       {
+       case PROP_PIXBUF:
                {
-               case PROP_PIXBUF:
-                       {
-                       GdkPixbuf *pixbuf;
+               GdkPixbuf *pixbuf;
 
-                       pixbuf = (GdkPixbuf*) g_value_get_object (value);
-                       if (pixbuf) g_object_ref (pixbuf);
-                       if (cellicon->pixbuf) g_object_unref (cellicon->pixbuf);
-                       cellicon->pixbuf = pixbuf;
-                       }
+               pixbuf = (GdkPixbuf *) g_value_get_object(value);
+               if (pixbuf) g_object_ref(pixbuf);
+               if (cellicon->pixbuf) g_object_unref(cellicon->pixbuf);
+               cellicon->pixbuf = pixbuf;
+               }
                break;
        case PROP_TEXT:
                {
@@ -385,10 +494,19 @@ gqv_cell_renderer_icon_set_property(GObject               *object,
        case PROP_SHOW_TEXT:
                cellicon->show_text = g_value_get_boolean(value);
                break;
+       case PROP_SHOW_MARKS:
+               cellicon->show_marks = g_value_get_boolean(value);
+               break;
+       case PROP_NUM_MARKS:
+               cellicon->num_marks = g_value_get_int(value);
+               break;
+       case PROP_MARKS:
+               cellicon->marks = g_value_get_uint(value);
+               break;
        default:
-               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+               G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
                break;
-    }
+       }
 }
 
 static PangoLayout *
@@ -433,7 +551,7 @@ gqv_cell_renderer_icon_get_layout(GQvCellRendererIcon *cellicon, GtkWidget *widg
 
 /**
  * gqv_cell_renderer_icon_new:
- * 
+ *
  * Creates a new #GQvCellRendererIcon. Adjust rendering
  * parameters using object properties. Object properties can be set
  * globally (with g_object_set()). Also, with #GtkTreeViewColumn, you
@@ -441,27 +559,41 @@ gqv_cell_renderer_icon_get_layout(GQvCellRendererIcon *cellicon, GtkWidget *widg
  * can bind the "pixbuf" property on the cell renderer to a pixbuf value
  * in the model, thus rendering a different image in each row of the
  * #GtkTreeView.
- * 
+ *
  * Return value: the new cell renderer
  **/
 GtkCellRenderer *
 gqv_cell_renderer_icon_new(void)
 {
-       return g_object_new (GQV_TYPE_CELL_RENDERER_ICON, NULL);
+       return g_object_new(GQV_TYPE_CELL_RENDERER_ICON, NULL);
 }
 
-static void
-gqv_cell_renderer_icon_get_size(GtkCellRenderer *cell,
-                               GtkWidget       *widget,
-                               GdkRectangle    *cell_area,
-                               gint            *x_offset,
-                               gint            *y_offset,
-                               gint            *width,
-                               gint            *height)
+#if GTK_CHECK_VERSION(3,0,0)
+static void gqv_cell_renderer_icon_get_size(GtkCellRenderer    *cell,
+                                           GtkWidget          *widget,
+                                           const GdkRectangle *cell_area,
+                                           gint               *x_offset,
+                                           gint               *y_offset,
+                                           gint               *width,
+                                           gint               *height)
+#else
+static void gqv_cell_renderer_icon_get_size(GtkCellRenderer    *cell,
+                                           GtkWidget          *widget,
+                                           GdkRectangle       *cell_area,
+                                           gint               *x_offset,
+                                           gint               *y_offset,
+                                           gint               *width,
+                                           gint               *height)
+#endif
 {
        GQvCellRendererIcon *cellicon = (GQvCellRendererIcon *) cell;
        gint calc_width;
        gint calc_height;
+       gint xpad, ypad;
+       gfloat xalign, yalign;
+
+       gtk_cell_renderer_get_padding(cell, &xpad, &ypad);
+       gtk_cell_renderer_get_alignment(cell, &xalign, &yalign);
 
        if (cellicon->fixed_width > 0)
                {
@@ -494,8 +626,14 @@ gqv_cell_renderer_icon_get_size(GtkCellRenderer *cell,
                calc_height += rect.height;
                }
 
-       calc_width += (gint)cell->xpad * 2;
-       calc_height += (gint)cell->ypad * 2;
+       if (cellicon->show_marks)
+               {
+               calc_height += TOGGLE_SPACING;
+               calc_width = MAX(calc_width, TOGGLE_SPACING * cellicon->num_marks);
+               }
+
+       calc_width += xpad * 2;
+       calc_height += ypad * 2;
 
        if (x_offset) *x_offset = 0;
        if (y_offset) *y_offset = 0;
@@ -504,13 +642,13 @@ gqv_cell_renderer_icon_get_size(GtkCellRenderer *cell,
                {
                if (x_offset)
                        {
-                       *x_offset = (cell->xalign * (cell_area->width - calc_width - 2 * cell->xpad));
-                       *x_offset = MAX (*x_offset, 0) + cell->xpad;
+                       *x_offset = (xalign * (cell_area->width - calc_width - 2 * xpad));
+                       *x_offset = MAX(*x_offset, 0) + xpad;
                        }
                if (y_offset)
                        {
-                       *y_offset = (cell->yalign * (cell_area->height - calc_height - 2 * cell->ypad));
-                       *y_offset = MAX (*y_offset, 0) + cell->ypad;
+                       *y_offset = (yalign * (cell_area->height - calc_height - 2 * ypad));
+                       *y_offset = MAX(*y_offset, 0) + ypad;
                        }
                }
 
@@ -518,6 +656,17 @@ gqv_cell_renderer_icon_get_size(GtkCellRenderer *cell,
        if (height) *height = calc_height;
 }
 
+#if GTK_CHECK_VERSION(3,0,0)
+static void gqv_cell_renderer_icon_render(GtkCellRenderer *cell,
+                                          cairo_t *cr,
+                                          GtkWidget *widget,
+                                          const GdkRectangle *background_area,
+                                          const GdkRectangle *cell_area,
+                                          GtkCellRendererState flags)
+
+{
+       GtkStyleContext *context = gtk_widget_get_style_context(widget);
+#else
 static void
 gqv_cell_renderer_icon_render(GtkCellRenderer          *cell,
                              GdkWindow                 *window,
@@ -528,41 +677,73 @@ gqv_cell_renderer_icon_render(GtkCellRenderer             *cell,
                              GtkCellRendererState      flags)
 
 {
+       cairo_t *cr = gdk_cairo_create(window);
+#endif
        GQvCellRendererIcon *cellicon = (GQvCellRendererIcon *) cell;
        GdkPixbuf *pixbuf;
        const gchar *text;
        GdkRectangle cell_rect;
+#if GTK_CHECK_VERSION(3,0,0)
+       GtkStateFlags state;
+#else
        GtkStateType state;
+#endif
+       gint xpad, ypad;
+
 
        pixbuf = cellicon->pixbuf;
        text = cellicon->text;
 
-       if (!pixbuf && !text) return;
+       if (!pixbuf && !text)
+               {
+#if !GTK_CHECK_VERSION(3,0,0)
+               cairo_destroy(cr);
+#endif
+               return;
+               }
+
+       gtk_cell_renderer_get_padding(cell, &xpad, &ypad);
 
        gqv_cell_renderer_icon_get_size(cell, widget, cell_area,
                                        &cell_rect.x, &cell_rect.y,
                                        &cell_rect.width, &cell_rect.height);
 
-       cell_rect.x += cell->xpad;
-       cell_rect.y += cell->ypad;
-       cell_rect.width -= cell->xpad * 2;
-       cell_rect.height -= cell->ypad * 2;
+       cell_rect.x += xpad;
+       cell_rect.y += ypad;
+       cell_rect.width -= xpad * 2;
+       cell_rect.height -= ypad * 2;
 
        if ((flags & GTK_CELL_RENDERER_SELECTED) == GTK_CELL_RENDERER_SELECTED)
                {
-               if (GTK_WIDGET_HAS_FOCUS(widget))
+               if (gtk_widget_has_focus(widget))
+#if GTK_CHECK_VERSION(3,0,0)
+                       state = GTK_STATE_FLAG_SELECTED;
+               else
+                       state = GTK_STATE_FLAG_ACTIVE;
+#else
                        state = GTK_STATE_SELECTED;
                else
                        state = GTK_STATE_ACTIVE;
+#endif
                }
        else
                {
-               if (GTK_WIDGET_STATE(widget) == GTK_STATE_INSENSITIVE)
+               if (gtk_widget_get_state(widget) == GTK_STATE_INSENSITIVE)
+#if GTK_CHECK_VERSION(3,0,0)
+                       state = GTK_STATE_FLAG_INSENSITIVE;
+               else
+                       state = GTK_STATE_FLAG_NORMAL;
+#else
                        state = GTK_STATE_INSENSITIVE;
                else
                        state = GTK_STATE_NORMAL;
+#endif
                }
 
+#if GTK_CHECK_VERSION(3,0,0)
+       gtk_style_context_set_state(context, state);
+#endif
+
        if (pixbuf)
                {
                GdkRectangle pix_rect;
@@ -575,28 +756,27 @@ gqv_cell_renderer_icon_render(GtkCellRenderer             *cell,
 
                if (cellicon->fixed_height > 0)
                        {
-                       pix_rect.y = cell_area->y + cell->ypad + (cellicon->fixed_height - pix_rect.height) / 2;
+                       pix_rect.y = cell_area->y + ypad + (cellicon->fixed_height - pix_rect.height) / 2;
                        }
                else
                        {
                        pix_rect.y = cell_area->y + cell_rect.y;
                        }
 
-               if (gdk_rectangle_intersect(cell_area, &pix_rect, &draw_rect) &&
-                   gdk_rectangle_intersect(expose_area, &draw_rect, &draw_rect))
+               if (gdk_rectangle_intersect(cell_area, &pix_rect, &draw_rect)
+#if !GTK_CHECK_VERSION(3,0,0)
+                   && gdk_rectangle_intersect(expose_area, &draw_rect, &draw_rect)
+#endif
+                  )
                        {
-                       gdk_draw_pixbuf(window,
-                                       widget->style->black_gc,
-                                       pixbuf,
-                                       /* pixbuf 0, 0 is at pix_rect.x, pix_rect.y */
-                                       draw_rect.x - pix_rect.x,
-                                       draw_rect.y - pix_rect.y,
+                       gdk_cairo_set_source_pixbuf(cr, pixbuf, pix_rect.x, pix_rect.y);
+                       cairo_rectangle (cr,
                                        draw_rect.x,
                                        draw_rect.y,
                                        draw_rect.width,
-                                       draw_rect.height,
-                                       GDK_RGB_DITHER_NORMAL,
-                                       0, 0);
+                                       draw_rect.height);
+
+                       cairo_fill (cr);
                        }
                }
 
@@ -605,39 +785,201 @@ gqv_cell_renderer_icon_render(GtkCellRenderer            *cell,
                PangoLayout *layout;
                PangoRectangle text_rect;
                GdkRectangle pix_rect;
-                GdkRectangle draw_rect;
-
+               GdkRectangle draw_rect;
                layout = gqv_cell_renderer_icon_get_layout(cellicon, widget, TRUE);
                pango_layout_get_pixel_extents(layout, NULL, &text_rect);
 
                pix_rect.width = text_rect.width;
                pix_rect.height = text_rect.height;
-               pix_rect.x = cell_area->x + cell->xpad + (cell_rect.width - text_rect.width + 1) / 2;
-               pix_rect.y = cell_area->y + cell->ypad + (cell_rect.height - text_rect.height);
+               pix_rect.x = cell_area->x + xpad + (cell_rect.width - text_rect.width + 1) / 2;
+               pix_rect.y = cell_area->y + ypad + (cell_rect.height - text_rect.height);
+
+               if (cellicon->show_marks)
+                       {
+                       pix_rect.y -= TOGGLE_SPACING;
+                       }
 
-               if (gdk_rectangle_intersect(cell_area, &pix_rect, &draw_rect) &&
-                   gdk_rectangle_intersect(expose_area, &draw_rect, &draw_rect))
+               if (gdk_rectangle_intersect(cell_area, &pix_rect, &draw_rect)
+#if !GTK_CHECK_VERSION(3,0,0)
+                   && gdk_rectangle_intersect(expose_area, &draw_rect, &draw_rect)
+#endif
+                   )
                        {
-                       gtk_paint_layout(widget->style, window,
+#if GTK_CHECK_VERSION(3,0,0)
+                       gtk_render_layout(context, cr, pix_rect.x - text_rect.x, pix_rect.y, layout);
+#else
+
+                       gtk_paint_layout(gtk_widget_get_style(widget), window,
                                         state, TRUE,
                                         cell_area, widget,
                                         "cellrenderertext",
                                         pix_rect.x - text_rect.x, pix_rect.y,
                                         layout);
+#endif
                        }
-
                g_object_unref(layout);
                }
 
-       if (cellicon->focused &&
-           GTK_WIDGET_HAS_FOCUS(widget))
+       if (cellicon->show_marks)
                {
-               gtk_paint_focus(widget->style, window,
+               GdkRectangle pix_rect;
+               GdkRectangle draw_rect;
+               gint i;
+
+               pix_rect.width = TOGGLE_SPACING * cellicon->num_marks;
+               pix_rect.height = TOGGLE_SPACING;
+               pix_rect.x = cell_area->x + xpad + (cell_rect.width - pix_rect.width + 1) / 2 + (TOGGLE_SPACING - TOGGLE_WIDTH) / 2;
+               pix_rect.y = cell_area->y + ypad + (cell_rect.height - pix_rect.height) + (TOGGLE_SPACING - TOGGLE_WIDTH) / 2;
+
+               if (gdk_rectangle_intersect(cell_area, &pix_rect, &draw_rect)
+#if !GTK_CHECK_VERSION(3,0,0)
+                   && gdk_rectangle_intersect(expose_area, &draw_rect, &draw_rect)
+#endif
+                   )
+                       {
+                       for (i = 0; i < cellicon->num_marks; i++)
+                               {
+#if GTK_CHECK_VERSION(3,0,0)
+#if GTK_CHECK_VERSION(3,14,0)
+                               state &= ~(GTK_STATE_FLAG_CHECKED);
+
+                               if ((cellicon->marks & (1 << i)))
+                                       state |= GTK_STATE_FLAG_CHECKED;
+#else
+                               state &= ~(GTK_STATE_FLAG_ACTIVE);
+
+                               if ((cellicon->marks & (1 << i)))
+                                       state |= GTK_STATE_FLAG_ACTIVE;
+#endif
+                               cairo_save (cr);
+
+                               cairo_rectangle(cr,
+                                               pix_rect.x + i * TOGGLE_SPACING + (TOGGLE_WIDTH - TOGGLE_SPACING) / 2,
+                                               pix_rect.y,
+                                               TOGGLE_WIDTH, TOGGLE_WIDTH);
+                               cairo_clip (cr);
+
+                               gtk_style_context_save(context);
+                               gtk_style_context_set_state(context, state);
+
+                               gtk_style_context_add_class(context, GTK_STYLE_CLASS_CHECK);
+
+                               gtk_style_context_add_class(context, "marks");
+                               GtkStyleProvider *provider;
+                               provider = (GtkStyleProvider *)gtk_css_provider_new();
+                               gtk_css_provider_load_from_data(GTK_CSS_PROVIDER(provider),
+                                               ".marks {\n"
+                                               "border-color: #808080;\n"
+                                               "border-style: solid;\n"
+                                               "border-width: 1px;\n"
+                                               "border-radius: 0px;\n"
+                                               "}\n"
+                                               ,-1, NULL);
+                               gtk_style_context_add_provider(context, provider,
+                                                       GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
+
+                               gtk_render_check(context, cr,
+                                        pix_rect.x + i * TOGGLE_SPACING + (TOGGLE_WIDTH - TOGGLE_SPACING) / 2,
+                                        pix_rect.y,
+                                        TOGGLE_WIDTH, TOGGLE_WIDTH);
+                               gtk_render_frame(context, cr,
+                                        pix_rect.x + i * TOGGLE_SPACING + (TOGGLE_WIDTH - TOGGLE_SPACING) / 2,
+                                        pix_rect.y,
+                                        TOGGLE_WIDTH, TOGGLE_WIDTH);
+
+                               if (cellicon->focused && gtk_widget_has_focus(widget))
+                                       {
+                                       gtk_render_focus(context, cr,
+                                               pix_rect.x + i * TOGGLE_SPACING + (TOGGLE_WIDTH - TOGGLE_SPACING) / 2,
+                                               pix_rect.y, TOGGLE_WIDTH, TOGGLE_WIDTH);
+                                       }
+                               gtk_style_context_restore(context);
+                               cairo_restore(cr);
+
+#else
+                               gtk_paint_check(gtk_widget_get_style(widget), window,
+                                        state, (cellicon->marks & (1 << i)) ? GTK_SHADOW_IN : GTK_SHADOW_OUT,
+                                        cell_area, widget, "cellcheck",
+                                        pix_rect.x + i * TOGGLE_SPACING + (TOGGLE_WIDTH - TOGGLE_SPACING) / 2,
+                                        pix_rect.y,
+                                        TOGGLE_WIDTH, TOGGLE_WIDTH);
+#endif
+                               }
+                       }
+               }
+
+#if !GTK_CHECK_VERSION(3,0,0)
+       if (cellicon->focused && gtk_widget_has_focus(widget))
+               {
+               gtk_paint_focus(gtk_widget_get_style(widget), window,
                                state,
                                cell_area, widget,
                                "cellrendererfocus",
                                cell_area->x, cell_area->y,
                                cell_area->width, cell_area->height);
                }
+       cairo_destroy(cr);
+#endif
 }
 
+#if GTK_CHECK_VERSION(3,0,0)
+static gboolean gqv_cell_renderer_icon_activate(GtkCellRenderer      *cell,
+                                               GdkEvent             *event,
+                                               GtkWidget            *widget,
+                                               const gchar          *path,
+                                               const GdkRectangle   *background_area,
+                                               const GdkRectangle   *cell_area,
+                                               GtkCellRendererState  flags)
+#else
+static gboolean gqv_cell_renderer_icon_activate(GtkCellRenderer      *cell,
+                                               GdkEvent             *event,
+                                               GtkWidget            *widget,
+                                               const gchar          *path,
+                                               GdkRectangle         *background_area,
+                                               GdkRectangle         *cell_area,
+                                               GtkCellRendererState  flags)
+#endif
+{
+       GQvCellRendererIcon *cellicon = (GQvCellRendererIcon *) cell;
+       GdkEventButton *bevent = &event->button;
+
+       if (cellicon->show_marks &&
+           event->type == GDK_BUTTON_PRESS &&
+            !(bevent->state & GDK_SHIFT_MASK ) &&
+            !(bevent->state & GDK_CONTROL_MASK ))
+               {
+               GdkRectangle rect;
+               GdkRectangle cell_rect;
+               gint i;
+               gint xpad, ypad;
+
+               gtk_cell_renderer_get_padding(cell, &xpad, &ypad);
+
+               gqv_cell_renderer_icon_get_size(cell, widget, cell_area,
+                                               &cell_rect.x, &cell_rect.y,
+                                               &cell_rect.width, &cell_rect.height);
+
+               cell_rect.x += xpad;
+               cell_rect.y += ypad;
+               cell_rect.width -= xpad * 2;
+               cell_rect.height -= ypad * 2;
+
+               rect.width = TOGGLE_WIDTH;
+               rect.height = TOGGLE_WIDTH;
+               rect.y = cell_area->y + ypad + (cell_rect.height - TOGGLE_SPACING) + (TOGGLE_SPACING - TOGGLE_WIDTH) / 2;
+               for (i = 0; i < cellicon->num_marks; i++)
+                       {
+                       rect.x = cell_area->x + xpad + (cell_rect.width - TOGGLE_SPACING * cellicon->num_marks + 1) / 2 + i * TOGGLE_SPACING;
+
+                       if (bevent->x >= rect.x && bevent->x < rect.x + rect.width &&
+                           bevent->y >= rect.y && bevent->y < rect.y + rect.height)
+                               {
+                               cellicon->toggled_mark = i;
+                               g_signal_emit(cell, toggle_cell_signals[TOGGLED], 0, path);
+                               break;
+                               }
+                       }
+               }
+       return FALSE;
+}
+/* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */