Home | History | Annotate | Download | only in gio
      1 /* GIO - GLib Input, Output and Streaming Library
      2  *
      3  * Copyright (C) 2008 Clemens N. Buss <cebuzz (at) gmail.com>
      4  *
      5  * This library is free software; you can redistribute it and/or
      6  * modify it under the terms of the GNU Lesser General Public
      7  * License as published by the Free Software Foundation; either
      8  * version 2 of the License, or (at your option) any later version.
      9  *
     10  * This library is distributed in the hope that it will be useful,
     11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     13  * Lesser General Public License for more details.
     14  *
     15  * You should have received a copy of the GNU Lesser General
     16  * Public License along with this library; if not, write to the
     17  * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
     18  * Boston, MA 02111-1307, USA.
     19  *
     20  */
     21 
     22 #include <config.h>
     23 
     24 #include "gicon.h"
     25 #include "gemblem.h"
     26 #include "glibintl.h"
     27 #include "gioenums.h"
     28 #include "gioenumtypes.h"
     29 #include "gioerror.h"
     30 #include <stdlib.h>
     31 #include <string.h>
     32 
     33 #include "gioalias.h"
     34 
     35 /**
     36  * SECTION:gemblem
     37  * @short_description: An object for emblems
     38  * @include: gio/gio.h
     39  * @see_also: #GIcon, #GEmblemedIcon, #GLoadableIcon, #GThemedIcon
     40  *
     41  * #GEmblem is an implementation of #GIcon that supports
     42  * having an emblem, which is an icon with additional properties.
     43  * It can than be added to a #GEmblemedIcon.
     44  *
     45  * Currently, only metainformation about the emblem's origin is
     46  * supported. More may be added in the future.
     47  **/
     48 
     49 static void g_emblem_iface_init (GIconIface *iface);
     50 
     51 struct _GEmblem
     52 {
     53   GObject parent_instance;
     54 
     55   GIcon *icon;
     56   GEmblemOrigin origin;
     57 };
     58 
     59 struct _GEmblemClass
     60 {
     61   GObjectClass parent_class;
     62 };
     63 
     64 enum
     65 {
     66   PROP_0_GEMBLEM,
     67   PROP_ICON,
     68   PROP_ORIGIN
     69 };
     70 
     71 G_DEFINE_TYPE_WITH_CODE (GEmblem, g_emblem, G_TYPE_OBJECT,
     72                          G_IMPLEMENT_INTERFACE (G_TYPE_ICON, g_emblem_iface_init))
     73 
     74 static void
     75 g_emblem_get_property (GObject    *object,
     76                        guint       prop_id,
     77                        GValue     *value,
     78                        GParamSpec *pspec)
     79 {
     80   GEmblem *emblem = G_EMBLEM (object);
     81 
     82   switch (prop_id)
     83     {
     84       case PROP_ICON:
     85         g_value_set_object (value, emblem->icon);
     86 
     87       case PROP_ORIGIN:
     88         g_value_set_enum (value, emblem->origin);
     89         break;
     90 
     91       default:
     92         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
     93         break;
     94   }
     95 }
     96 
     97 static void
     98 g_emblem_set_property (GObject      *object,
     99                        guint         prop_id,
    100                        const GValue *value,
    101                        GParamSpec   *pspec)
    102 {
    103   GEmblem *emblem = G_EMBLEM (object);
    104 
    105   switch (prop_id)
    106     {
    107       case PROP_ICON:
    108         emblem->icon = g_value_get_object (value);
    109         break;
    110 
    111       case PROP_ORIGIN:
    112         emblem->origin = g_value_get_enum (value);
    113         break;
    114 
    115       default:
    116         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
    117         break;
    118     }
    119 }
    120 
    121 static void
    122 g_emblem_finalize (GObject *object)
    123 {
    124   GEmblem *emblem = G_EMBLEM (object);
    125 
    126   g_object_unref (emblem->icon);
    127 
    128   (*G_OBJECT_CLASS (g_emblem_parent_class)->finalize) (object);
    129 }
    130 
    131 static void
    132 g_emblem_class_init (GEmblemClass *klass)
    133 {
    134   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
    135 
    136   gobject_class->finalize = g_emblem_finalize;
    137   gobject_class->set_property = g_emblem_set_property;
    138   gobject_class->get_property = g_emblem_get_property;
    139 
    140   g_object_class_install_property (gobject_class,
    141                                    PROP_ORIGIN,
    142                                    g_param_spec_enum ("origin",
    143                                                       P_("GEmblem's origin"),
    144                                                       P_("Tells which origin the emblem is derived from"),
    145                                                       G_TYPE_EMBLEM_ORIGIN,
    146                                                       G_EMBLEM_ORIGIN_UNKNOWN,
    147                                                       G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_BLURB | G_PARAM_STATIC_NICK));
    148 
    149   g_object_class_install_property (gobject_class,
    150                                    PROP_ICON,
    151                                    g_param_spec_object ("icon",
    152                                                       P_("The icon of the emblem"),
    153                                                       P_("The actual icon of the emblem"),
    154                                                       G_TYPE_OBJECT,
    155                                                       G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_BLURB | G_PARAM_STATIC_NICK));
    156 
    157 }
    158 
    159 static void
    160 g_emblem_init (GEmblem *emblem)
    161 {
    162 }
    163 
    164 /**
    165  * g_emblem_new:
    166  * @icon: a GIcon containing the icon.
    167  *
    168  * Creates a new emblem for @icon.
    169  *
    170  * Returns: a new #GEmblem.
    171  *
    172  * Since: 2.18
    173  **/
    174 GEmblem *
    175 g_emblem_new (GIcon *icon)
    176 {
    177   GEmblem* emblem;
    178 
    179   g_return_val_if_fail (icon != NULL, NULL);
    180   g_return_val_if_fail (G_IS_ICON (icon), NULL);
    181   g_return_val_if_fail (!G_IS_EMBLEM (icon), NULL);
    182 
    183   emblem = g_object_new (G_TYPE_EMBLEM, NULL);
    184   emblem->icon = g_object_ref (icon);
    185   emblem->origin = G_EMBLEM_ORIGIN_UNKNOWN;
    186 
    187   return emblem;
    188 }
    189 
    190 /**
    191  * g_emblem_new_with_origin:
    192  * @icon: a GIcon containing the icon.
    193  * @origin: a GEmblemOrigin enum defining the emblem's origin
    194  *
    195  * Creates a new emblem for @icon.
    196  *
    197  * Returns: a new #GEmblem.
    198  *
    199  * Since: 2.18
    200  **/
    201 GEmblem *
    202 g_emblem_new_with_origin (GIcon         *icon,
    203                           GEmblemOrigin  origin)
    204 {
    205   GEmblem* emblem;
    206 
    207   g_return_val_if_fail (icon != NULL, NULL);
    208   g_return_val_if_fail (G_IS_ICON (icon), NULL);
    209   g_return_val_if_fail (!G_IS_EMBLEM (icon), NULL);
    210 
    211   emblem = g_object_new (G_TYPE_EMBLEM, NULL);
    212   emblem->icon = g_object_ref (icon);
    213   emblem->origin = origin;
    214 
    215   return emblem;
    216 }
    217 
    218 /**
    219  * g_emblem_get_icon:
    220  * @emblem: a #GEmblem from which the icon should be extracted.
    221  *
    222  * Gives back the icon from @emblem.
    223  *
    224  * Returns: a #GIcon. The returned object belongs to the emblem
    225  *    and should not be modified or freed.
    226  *
    227  * Since: 2.18
    228  **/
    229 GIcon *
    230 g_emblem_get_icon (GEmblem *emblem)
    231 {
    232   g_return_val_if_fail (G_IS_EMBLEM (emblem), NULL);
    233 
    234   return emblem->icon;
    235 }
    236 
    237 
    238 /**
    239  * g_emblem_get_origin:
    240  * @emblem: a #GEmblem
    241  *
    242  * Gets the origin of the emblem.
    243  *
    244  * Returns: the origin of the emblem
    245  *
    246  * Since: 2.18
    247  **/
    248 GEmblemOrigin
    249 g_emblem_get_origin (GEmblem *emblem)
    250 {
    251   g_return_val_if_fail (G_IS_EMBLEM (emblem), G_EMBLEM_ORIGIN_UNKNOWN);
    252 
    253   return emblem->origin;
    254 }
    255 
    256 static guint
    257 g_emblem_hash (GIcon *icon)
    258 {
    259   GEmblem *emblem = G_EMBLEM (icon);
    260   guint hash;
    261 
    262   hash  = g_icon_hash (g_emblem_get_icon (emblem));
    263   hash ^= emblem->origin;
    264 
    265   return hash;
    266 }
    267 
    268 static gboolean
    269 g_emblem_equal (GIcon *icon1,
    270                 GIcon *icon2)
    271 {
    272   GEmblem *emblem1 = G_EMBLEM (icon1);
    273   GEmblem *emblem2 = G_EMBLEM (icon2);
    274 
    275   return emblem1->origin == emblem2->origin &&
    276          g_icon_equal (emblem1->icon, emblem2->icon);
    277 }
    278 
    279 static gboolean
    280 g_emblem_to_tokens (GIcon *icon,
    281 		    GPtrArray *tokens,
    282 		    gint  *out_version)
    283 {
    284   GEmblem *emblem = G_EMBLEM (icon);
    285   char *s;
    286 
    287   /* GEmblem are encoded as
    288    *
    289    * <origin> <icon>
    290    */
    291 
    292   g_return_val_if_fail (out_version != NULL, FALSE);
    293 
    294   *out_version = 0;
    295 
    296   s = g_icon_to_string (emblem->icon);
    297   if (s == NULL)
    298     return FALSE;
    299 
    300   g_ptr_array_add (tokens, s);
    301 
    302   s = g_strdup_printf ("%d", emblem->origin);
    303   g_ptr_array_add (tokens, s);
    304 
    305   return TRUE;
    306 }
    307 
    308 static GIcon *
    309 g_emblem_from_tokens (gchar  **tokens,
    310 		      gint     num_tokens,
    311 		      gint     version,
    312 		      GError **error)
    313 {
    314   GEmblem *emblem;
    315   GIcon *icon;
    316   GEmblemOrigin origin;
    317 
    318   emblem = NULL;
    319 
    320   if (version != 0)
    321     {
    322       g_set_error (error,
    323                    G_IO_ERROR,
    324                    G_IO_ERROR_INVALID_ARGUMENT,
    325                    _("Can't handle version %d of GEmblem encoding"),
    326                    version);
    327       return NULL;
    328     }
    329 
    330   if (num_tokens != 2)
    331     {
    332       g_set_error (error,
    333                    G_IO_ERROR,
    334                    G_IO_ERROR_INVALID_ARGUMENT,
    335                    _("Malformed number of tokens (%d) in GEmblem encoding"),
    336                    num_tokens);
    337       return NULL;
    338     }
    339 
    340   icon = g_icon_new_for_string (tokens[0], error);
    341 
    342   if (icon == NULL)
    343     return NULL;
    344 
    345   origin = atoi (tokens[1]);
    346 
    347   emblem = g_emblem_new_with_origin (icon, origin);
    348   g_object_unref (icon);
    349 
    350   return G_ICON (emblem);
    351 }
    352 
    353 static void
    354 g_emblem_iface_init (GIconIface *iface)
    355 {
    356   iface->hash  = g_emblem_hash;
    357   iface->equal = g_emblem_equal;
    358   iface->to_tokens = g_emblem_to_tokens;
    359   iface->from_tokens = g_emblem_from_tokens;
    360 }
    361 
    362 #define __G_EMBLEM_C__
    363 #include "gioaliasdef.c"
    364