Blame src/nautilus-canvas-view-container.c

Packit a189e0
/* fm-icon-container.h - the container widget for file manager icons
Packit a189e0
 *
Packit a189e0
 *  Copyright (C) 2002 Sun Microsystems, Inc.
Packit a189e0
 *
Packit a189e0
 *  The Gnome Library is free software; you can redistribute it and/or
Packit a189e0
 *  modify it under the terms of the GNU Library General Public License as
Packit a189e0
 *  published by the Free Software Foundation; either version 2 of the
Packit a189e0
 *  License, or (at your option) any later version.
Packit a189e0
 *
Packit a189e0
 *  The Gnome Library is distributed in the hope that it will be useful,
Packit a189e0
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit a189e0
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit a189e0
 *  Library General Public License for more details.
Packit a189e0
 *
Packit a189e0
 *  You should have received a copy of the GNU Library General Public
Packit a189e0
 *  License along with the Gnome Library; see the file COPYING.LIB.  If not,
Packit a189e0
 *  see <http://www.gnu.org/licenses/>.
Packit a189e0
 *
Packit a189e0
 *  Author: Michael Meeks <michael@ximian.com>
Packit a189e0
 */
Packit a189e0
#include <config.h>
Packit a189e0
Packit a189e0
#include "nautilus-canvas-view-container.h"
Packit a189e0
Packit a189e0
#include <string.h>
Packit a189e0
#include <glib/gi18n.h>
Packit a189e0
#include <gio/gio.h>
Packit a189e0
#include <eel/eel-glib-extensions.h>
Packit a189e0
#include "nautilus-global-preferences.h"
Packit a189e0
#include "nautilus-file-attributes.h"
Packit a189e0
#include "nautilus-thumbnails.h"
Packit a189e0
Packit a189e0
G_DEFINE_TYPE (NautilusCanvasViewContainer, nautilus_canvas_view_container, NAUTILUS_TYPE_CANVAS_CONTAINER);
Packit a189e0
Packit a189e0
static GQuark attribute_none_q;
Packit a189e0
Packit a189e0
static NautilusCanvasView *
Packit a189e0
get_canvas_view (NautilusCanvasContainer *container)
Packit a189e0
{
Packit a189e0
    /* Type unsafe comparison for performance */
Packit a189e0
    return ((NautilusCanvasViewContainer *) container)->view;
Packit a189e0
}
Packit a189e0
Packit a189e0
static NautilusIconInfo *
Packit a189e0
nautilus_canvas_view_container_get_icon_images (NautilusCanvasContainer *container,
Packit a189e0
                                                NautilusCanvasIconData  *data,
Packit a189e0
                                                int                      size,
Packit a189e0
                                                gboolean                 for_drag_accept)
Packit a189e0
{
Packit a189e0
    NautilusCanvasView *canvas_view;
Packit a189e0
    NautilusFile *file;
Packit a189e0
    NautilusFileIconFlags flags;
Packit a189e0
    NautilusIconInfo *icon_info;
Packit a189e0
    gint scale;
Packit a189e0
Packit a189e0
    file = (NautilusFile *) data;
Packit a189e0
Packit a189e0
    g_assert (NAUTILUS_IS_FILE (file));
Packit a189e0
    canvas_view = get_canvas_view (container);
Packit a189e0
    g_return_val_if_fail (canvas_view != NULL, NULL);
Packit a189e0
Packit a189e0
    flags = NAUTILUS_FILE_ICON_FLAGS_USE_EMBLEMS |
Packit a189e0
            NAUTILUS_FILE_ICON_FLAGS_USE_THUMBNAILS;
Packit a189e0
Packit a189e0
    if (for_drag_accept)
Packit a189e0
    {
Packit a189e0
        flags |= NAUTILUS_FILE_ICON_FLAGS_FOR_DRAG_ACCEPT;
Packit a189e0
    }
Packit a189e0
Packit a189e0
    scale = gtk_widget_get_scale_factor (GTK_WIDGET (canvas_view));
Packit a189e0
    icon_info = nautilus_file_get_icon (file, size, scale, flags);
Packit a189e0
Packit a189e0
    return icon_info;
Packit a189e0
}
Packit a189e0
Packit a189e0
static char *
Packit a189e0
nautilus_canvas_view_container_get_icon_description (NautilusCanvasContainer *container,
Packit a189e0
                                                     NautilusCanvasIconData  *data)
Packit a189e0
{
Packit a189e0
    NautilusFile *file;
Packit a189e0
    char *mime_type;
Packit a189e0
    const char *description;
Packit a189e0
Packit a189e0
    file = NAUTILUS_FILE (data);
Packit a189e0
    g_assert (NAUTILUS_IS_FILE (file));
Packit a189e0
Packit a189e0
    mime_type = nautilus_file_get_mime_type (file);
Packit a189e0
    description = g_content_type_get_description (mime_type);
Packit a189e0
    g_free (mime_type);
Packit a189e0
    return g_strdup (description);
Packit a189e0
}
Packit a189e0
Packit a189e0
static void
Packit a189e0
nautilus_canvas_view_container_prioritize_thumbnailing (NautilusCanvasContainer *container,
Packit a189e0
                                                        NautilusCanvasIconData  *data)
Packit a189e0
{
Packit a189e0
    NautilusFile *file;
Packit a189e0
    char *uri;
Packit a189e0
Packit a189e0
    file = (NautilusFile *) data;
Packit a189e0
Packit a189e0
    g_assert (NAUTILUS_IS_FILE (file));
Packit a189e0
Packit a189e0
    if (nautilus_file_is_thumbnailing (file))
Packit a189e0
    {
Packit a189e0
        uri = nautilus_file_get_uri (file);
Packit a189e0
        nautilus_thumbnail_prioritize (uri);
Packit a189e0
        g_free (uri);
Packit a189e0
    }
Packit a189e0
}
Packit a189e0
Packit a189e0
static GQuark *
Packit a189e0
get_quark_from_strv (gchar **value)
Packit a189e0
{
Packit a189e0
    GQuark *quark;
Packit a189e0
    int i;
Packit a189e0
Packit a189e0
    quark = g_new0 (GQuark, g_strv_length (value) + 1);
Packit a189e0
    for (i = 0; value[i] != NULL; ++i)
Packit a189e0
    {
Packit a189e0
        quark[i] = g_quark_from_string (value[i]);
Packit a189e0
    }
Packit a189e0
Packit a189e0
    return quark;
Packit a189e0
}
Packit a189e0
Packit a189e0
/*
Packit a189e0
 * Get the preference for which caption text should appear
Packit a189e0
 * beneath icons.
Packit a189e0
 */
Packit a189e0
static GQuark *
Packit a189e0
nautilus_canvas_view_container_get_icon_text_attributes_from_preferences (void)
Packit a189e0
{
Packit a189e0
    GQuark *attributes;
Packit a189e0
    gchar **value;
Packit a189e0
Packit a189e0
    value = g_settings_get_strv (nautilus_icon_view_preferences,
Packit a189e0
                                 NAUTILUS_PREFERENCES_ICON_VIEW_CAPTIONS);
Packit a189e0
    attributes = get_quark_from_strv (value);
Packit a189e0
    g_strfreev (value);
Packit a189e0
Packit a189e0
    /* We don't need to sanity check the attributes list even though it came
Packit a189e0
     * from preferences.
Packit a189e0
     *
Packit a189e0
     * There are 2 ways that the values in the list could be bad.
Packit a189e0
     *
Packit a189e0
     * 1) The user picks "bad" values.  "bad" values are those that result in
Packit a189e0
     *    there being duplicate attributes in the list.
Packit a189e0
     *
Packit a189e0
     * 2) Value stored in GConf are tampered with.  Its possible physically do
Packit a189e0
     *    this by pulling the rug underneath GConf and manually editing its
Packit a189e0
     *    config files.  Its also possible to use a third party GConf key
Packit a189e0
     *    editor and store garbage for the keys in question.
Packit a189e0
     *
Packit a189e0
     * Thankfully, the Nautilus preferences machinery deals with both of
Packit a189e0
     * these cases.
Packit a189e0
     *
Packit a189e0
     * In the first case, the preferences dialog widgetry prevents
Packit a189e0
     * duplicate attributes by making "bad" choices insensitive.
Packit a189e0
     *
Packit a189e0
     * In the second case, the preferences getter (and also the auto storage) for
Packit a189e0
     * string_array values are always valid members of the enumeration associated
Packit a189e0
     * with the preference.
Packit a189e0
     *
Packit a189e0
     * So, no more error checking on attributes is needed here and we can return
Packit a189e0
     * a the auto stored value.
Packit a189e0
     */
Packit a189e0
    return attributes;
Packit a189e0
}
Packit a189e0
Packit a189e0
static int
Packit a189e0
quarkv_length (GQuark *attributes)
Packit a189e0
{
Packit a189e0
    int i;
Packit a189e0
    i = 0;
Packit a189e0
    while (attributes[i] != 0)
Packit a189e0
    {
Packit a189e0
        i++;
Packit a189e0
    }
Packit a189e0
    return i;
Packit a189e0
}
Packit a189e0
Packit a189e0
/**
Packit a189e0
 * nautilus_canvas_view_get_icon_text_attribute_names:
Packit a189e0
 *
Packit a189e0
 * Get a list representing which text attributes should be displayed
Packit a189e0
 * beneath an icon. The result is dependent on zoom level and possibly
Packit a189e0
 * user configuration. Don't free the result.
Packit a189e0
 * @view: NautilusCanvasView to query.
Packit a189e0
 *
Packit a189e0
 **/
Packit a189e0
static GQuark *
Packit a189e0
nautilus_canvas_view_container_get_icon_text_attribute_names (NautilusCanvasContainer *container,
Packit a189e0
                                                              int                     *len)
Packit a189e0
{
Packit a189e0
    GQuark *attributes;
Packit a189e0
    int piece_count;
Packit a189e0
Packit a189e0
    const int pieces_by_level[] =
Packit a189e0
    {
Packit a189e0
        1,              /* NAUTILUS_ZOOM_LEVEL_SMALL */
Packit a189e0
        2,              /* NAUTILUS_ZOOM_LEVEL_STANDARD */
Packit a189e0
        3,              /* NAUTILUS_ZOOM_LEVEL_LARGE */
Packit a189e0
        3,              /* NAUTILUS_ZOOM_LEVEL_LARGER */
Packit a189e0
    };
Packit a189e0
Packit a189e0
    piece_count = pieces_by_level[nautilus_canvas_container_get_zoom_level (container)];
Packit a189e0
Packit a189e0
    attributes = nautilus_canvas_view_container_get_icon_text_attributes_from_preferences ();
Packit a189e0
Packit a189e0
    *len = MIN (piece_count, quarkv_length (attributes));
Packit a189e0
Packit a189e0
    return attributes;
Packit a189e0
}
Packit a189e0
Packit a189e0
/* This callback returns the text, both the editable part, and the
Packit a189e0
 * part below that is not editable.
Packit a189e0
 */
Packit a189e0
static void
Packit a189e0
nautilus_canvas_view_container_get_icon_text (NautilusCanvasContainer  *container,
Packit a189e0
                                              NautilusCanvasIconData   *data,
Packit a189e0
                                              char                    **editable_text,
Packit a189e0
                                              char                    **additional_text,
Packit a189e0
                                              gboolean                  include_invisible)
Packit a189e0
{
Packit a189e0
    GQuark *attributes;
Packit a189e0
    char *text_array[4];
Packit a189e0
    int i, j, num_attributes;
Packit a189e0
    NautilusCanvasView *canvas_view;
Packit a189e0
    NautilusFile *file;
Packit a189e0
    gboolean use_additional;
Packit a189e0
Packit a189e0
    file = NAUTILUS_FILE (data);
Packit a189e0
Packit a189e0
    g_assert (NAUTILUS_IS_FILE (file));
Packit a189e0
    g_assert (editable_text != NULL);
Packit a189e0
    canvas_view = get_canvas_view (container);
Packit a189e0
    g_return_if_fail (canvas_view != NULL);
Packit a189e0
Packit a189e0
    use_additional = (additional_text != NULL);
Packit a189e0
Packit a189e0
    /* Strip the suffix for nautilus object xml files. */
Packit a189e0
    *editable_text = nautilus_file_get_display_name (file);
Packit a189e0
Packit a189e0
    if (!use_additional)
Packit a189e0
    {
Packit a189e0
        return;
Packit a189e0
    }
Packit a189e0
Packit a189e0
    if (nautilus_file_is_nautilus_link (file))
Packit a189e0
    {
Packit a189e0
        /* Don't show the normal extra information for desktop files,
Packit a189e0
         * it doesn't make sense. */
Packit a189e0
        *additional_text = NULL;
Packit a189e0
        return;
Packit a189e0
    }
Packit a189e0
Packit a189e0
    /* Find out what attributes go below each icon. */
Packit a189e0
    attributes = nautilus_canvas_view_container_get_icon_text_attribute_names (container,
Packit a189e0
                                                                               &num_attributes);
Packit a189e0
Packit a189e0
    /* Get the attributes. */
Packit a189e0
    j = 0;
Packit a189e0
    for (i = 0; i < num_attributes; ++i)
Packit a189e0
    {
Packit a189e0
        char *text;
Packit a189e0
        if (attributes[i] == attribute_none_q)
Packit a189e0
        {
Packit a189e0
            continue;
Packit a189e0
        }
Packit a189e0
        text = nautilus_file_get_string_attribute_q (file, attributes[i]);
Packit a189e0
        if (text == NULL)
Packit a189e0
        {
Packit a189e0
            continue;
Packit a189e0
        }
Packit a189e0
        text_array[j++] = text;
Packit a189e0
    }
Packit a189e0
    text_array[j] = NULL;
Packit a189e0
Packit a189e0
    /* Return them. */
Packit a189e0
    if (j == 0)
Packit a189e0
    {
Packit a189e0
        *additional_text = NULL;
Packit a189e0
    }
Packit a189e0
    else if (j == 1)
Packit a189e0
    {
Packit a189e0
        /* Only one item, avoid the strdup + free */
Packit a189e0
        *additional_text = text_array[0];
Packit a189e0
    }
Packit a189e0
    else
Packit a189e0
    {
Packit a189e0
        *additional_text = g_strjoinv ("\n", text_array);
Packit a189e0
Packit a189e0
        for (i = 0; i < j; i++)
Packit a189e0
        {
Packit a189e0
            g_free (text_array[i]);
Packit a189e0
        }
Packit a189e0
    }
Packit a189e0
Packit a189e0
    g_free (attributes);
Packit a189e0
}
Packit a189e0
Packit a189e0
static int
Packit a189e0
nautilus_canvas_view_container_compare_icons (NautilusCanvasContainer *container,
Packit a189e0
                                              NautilusCanvasIconData  *icon_a,
Packit a189e0
                                              NautilusCanvasIconData  *icon_b)
Packit a189e0
{
Packit a189e0
    NautilusCanvasView *canvas_view;
Packit a189e0
Packit a189e0
    canvas_view = get_canvas_view (container);
Packit a189e0
    g_return_val_if_fail (canvas_view != NULL, 0);
Packit a189e0
Packit a189e0
    /* Type unsafe comparisons for performance */
Packit a189e0
    return nautilus_canvas_view_compare_files (canvas_view,
Packit a189e0
                                               (NautilusFile *) icon_a,
Packit a189e0
                                               (NautilusFile *) icon_b);
Packit a189e0
}
Packit a189e0
Packit a189e0
static int
Packit a189e0
nautilus_canvas_view_container_compare_icons_by_name (NautilusCanvasContainer *container,
Packit a189e0
                                                      NautilusCanvasIconData  *icon_a,
Packit a189e0
                                                      NautilusCanvasIconData  *icon_b)
Packit a189e0
{
Packit a189e0
    return nautilus_file_compare_for_sort
Packit a189e0
               (NAUTILUS_FILE (icon_a),
Packit a189e0
               NAUTILUS_FILE (icon_b),
Packit a189e0
               NAUTILUS_FILE_SORT_BY_DISPLAY_NAME,
Packit a189e0
               FALSE, FALSE);
Packit a189e0
}
Packit a189e0
Packit a189e0
static void
Packit a189e0
nautilus_canvas_view_container_class_init (NautilusCanvasViewContainerClass *klass)
Packit a189e0
{
Packit a189e0
    NautilusCanvasContainerClass *ic_class;
Packit a189e0
Packit a189e0
    ic_class = &klass->parent_class;
Packit a189e0
Packit a189e0
    attribute_none_q = g_quark_from_static_string ("none");
Packit a189e0
Packit a189e0
    ic_class->get_icon_text = nautilus_canvas_view_container_get_icon_text;
Packit a189e0
    ic_class->get_icon_images = nautilus_canvas_view_container_get_icon_images;
Packit a189e0
    ic_class->get_icon_description = nautilus_canvas_view_container_get_icon_description;
Packit a189e0
    ic_class->prioritize_thumbnailing = nautilus_canvas_view_container_prioritize_thumbnailing;
Packit a189e0
Packit a189e0
    ic_class->compare_icons = nautilus_canvas_view_container_compare_icons;
Packit a189e0
    ic_class->compare_icons_by_name = nautilus_canvas_view_container_compare_icons_by_name;
Packit a189e0
}
Packit a189e0
Packit a189e0
static void
Packit a189e0
nautilus_canvas_view_container_init (NautilusCanvasViewContainer *canvas_container)
Packit a189e0
{
Packit a189e0
    gtk_style_context_add_class (gtk_widget_get_style_context (GTK_WIDGET (canvas_container)),
Packit a189e0
                                 GTK_STYLE_CLASS_VIEW);
Packit a189e0
}
Packit a189e0
Packit a189e0
NautilusCanvasContainer *
Packit a189e0
nautilus_canvas_view_container_construct (NautilusCanvasViewContainer *canvas_container,
Packit a189e0
                                          NautilusCanvasView          *view)
Packit a189e0
{
Packit a189e0
    AtkObject *atk_obj;
Packit a189e0
Packit a189e0
    g_return_val_if_fail (NAUTILUS_IS_CANVAS_VIEW (view), NULL);
Packit a189e0
Packit a189e0
    canvas_container->view = view;
Packit a189e0
    atk_obj = gtk_widget_get_accessible (GTK_WIDGET (canvas_container));
Packit a189e0
    atk_object_set_name (atk_obj, _("Icon View"));
Packit a189e0
Packit a189e0
    return NAUTILUS_CANVAS_CONTAINER (canvas_container);
Packit a189e0
}
Packit a189e0
Packit a189e0
NautilusCanvasContainer *
Packit a189e0
nautilus_canvas_view_container_new (NautilusCanvasView *view)
Packit a189e0
{
Packit a189e0
    return nautilus_canvas_view_container_construct
Packit a189e0
               (g_object_new (NAUTILUS_TYPE_CANVAS_VIEW_CONTAINER, NULL),
Packit a189e0
               view);
Packit a189e0
}