Commit 06c6a4c8 authored by Stephan Arts's avatar Stephan Arts

Conflicts:

	src/image_viewer.c
	src/main_window.c
parent 9a29ded8
Stephan Arts - <stephan@xfce.org>
The ristretto-icon is drawn by Simon Steinbeiss and is released under the
same license as the ristretto application.
......@@ -81,11 +81,8 @@ po/Makefile.in
src/Makefile
icons/Makefile
icons/16x16/Makefile
icons/22x22/Makefile
icons/24x24/Makefile
icons/32x32/Makefile
icons/36x36/Makefile
icons/48x48/Makefile
icons/128x128/Makefile
icons/scalable/Makefile
])
......
icons/16x16/ristretto.png

825 Bytes | W: | H:

icons/16x16/ristretto.png

797 Bytes | W: | H:

icons/16x16/ristretto.png
icons/16x16/ristretto.png
icons/16x16/ristretto.png
icons/16x16/ristretto.png
  • 2-up
  • Swipe
  • Onion skin
icons/48x48/ristretto.png

3.39 KB | W: | H:

icons/48x48/ristretto.png

3.36 KB | W: | H:

icons/48x48/ristretto.png
icons/48x48/ristretto.png
icons/48x48/ristretto.png
icons/48x48/ristretto.png
  • 2-up
  • Swipe
  • Onion skin
# Inspired by Makefile.am from the Thunar file-manager
SUBDIRS = 16x16 22x22 24x24 32x32 36x36 48x48 scalable
SUBDIRS = 16x16 48x48 128x128 scalable
gtk_update_icon_cache = gtk-update-icon-cache -f -t $(datadir)/icons/hicolor
......
This diff is collapsed.
......@@ -6,9 +6,7 @@ src/privacy_dialog.c
src/preferences_dialog.c
src/properties_dialog.c
src/image_list.c
src/thumbnail.c
src/thumbnailer.c
src/thumbnail_bar.c
src/wallpaper_manager.c
src/xfce_wallpaper_manager.c
src/gnome_wallpaper_manager.c
......
......@@ -13,13 +13,12 @@ ristretto_SOURCES = \
xfce_wallpaper_manager.c xfce_wallpaper_manager.h \
gnome_wallpaper_manager.c gnome_wallpaper_manager.h \
app_menu_item.c app_menu_item.h \
thumbnail_bar.c thumbnail_bar.h \
thumbnail.c thumbnail.h \
thumbnailer.c thumbnailer.h \
marshal.c marshal.h \
file.c file.h \
privacy_dialog.h privacy_dialog.c \
util.c util.h \
icon_bar.c icon_bar.h \
main.c
ristretto_CFLAGS = \
......@@ -80,7 +79,7 @@ stamp-marshal.h: marshal.list Makefile
&& echo "#ifndef __RSTTO_MARSHAL_H__" > xgen-tmh \
&& echo "#define __RSTTO_MARSHAL_H__" >> xgen-tmh \
&& ( glib-genmarshal \
--prefix=rstto_marshal \
--prefix=_rstto_marshal \
--header marshal.list ) >> xgen-tmh \
&& echo "#endif /* !__RSTTO_MARSHAL_H__ */" >> xgen-tmh \
&& ( cmp -s xgen-tmh marshal.h || cp xgen-tmh marshal.h ) \
......@@ -93,7 +92,7 @@ marshal.c: marshal.list Makefile
cd $(srcdir) \
&& echo "#include \"marshal.h\"" > xgen-tmc \
&& ( glib-genmarshal \
--prefix=rstto_marshal \
--prefix=_rstto_marshal \
--body marshal.list ) >> xgen-tmc \
&& cp xgen-tmc marshal.c \
&& rm -f xgen-tmc \
......
......@@ -20,6 +20,7 @@
#include <glib.h>
#include <gio/gio.h>
#include <gtk/gtk.h>
#include <libexif/exif-data.h>
......@@ -100,6 +101,9 @@ struct _RsttoFilePriv
gchar *uri;
gchar *path;
gchar *thumbnail_path;
GdkPixbuf *thumbnails[THUMBNAIL_SIZE_COUNT];
ExifData *exif_data;
RsttoImageOrientation orientation;
};
......@@ -137,6 +141,7 @@ static void
rstto_file_dispose (GObject *object)
{
RsttoFile *file = RSTTO_FILE (object);
gint i = 0;
if (file->priv)
{
......@@ -160,12 +165,26 @@ rstto_file_dispose (GObject *object)
g_free (file->priv->path);
file->priv->path = NULL;
}
if (file->priv->thumbnail_path)
{
g_free (file->priv->thumbnail_path);
file->priv->thumbnail_path = NULL;
}
if (file->priv->uri)
{
g_free (file->priv->uri);
file->priv->uri = NULL;
}
for (i = 0; i < THUMBNAIL_SIZE_COUNT; ++i)
{
if (file->priv->thumbnails[i])
{
g_object_unref (file->priv->thumbnails[i]);
file->priv->thumbnails[i] = NULL;
}
}
g_free (file->priv);
file->priv = NULL;
......@@ -408,3 +427,45 @@ rstto_file_has_exif ( RsttoFile *file )
}
return TRUE;
}
const gchar *
rstto_file_get_thumbnail_path ( RsttoFile *file)
{
const gchar *uri;
gchar *checksum;
gchar *filename;
if (NULL == file->priv->thumbnail_path)
{
uri = rstto_file_get_uri (file);
checksum = g_compute_checksum_for_string (G_CHECKSUM_MD5, uri, strlen (uri));
filename = g_strconcat (checksum, ".png", NULL);
file->priv->thumbnail_path = g_build_path ("/", g_get_home_dir(), ".thumbnails", "normal", filename, NULL);
g_free (checksum);
g_free (filename);
}
return file->priv->thumbnail_path;
}
const GdkPixbuf *
rstto_file_get_thumbnail ( RsttoFile *file , RsttoThumbnailSize size)
{
const gchar *thumbnail_path;
if (file->priv->thumbnails[size])
return file->priv->thumbnails[size];
thumbnail_path = rstto_file_get_thumbnail_path (file);
file->priv->thumbnails[size] = gdk_pixbuf_new_from_file_at_scale (
thumbnail_path,
rstto_thumbnail_size[size],
rstto_thumbnail_size[size],
TRUE,
NULL);
return file->priv->thumbnails[size];
}
......@@ -83,6 +83,12 @@ rstto_file_get_uri ( RsttoFile * );
const gchar *
rstto_file_get_content_type ( RsttoFile * );
const gchar *
rstto_file_get_thumbnail_path ( RsttoFile *);
const GdkPixbuf *
rstto_file_get_thumbnail ( RsttoFile *, RsttoThumbnailSize );
guint64
rstto_file_get_modified_time ( RsttoFile *);
......
This diff is collapsed.
/*-
* Copyright (c) 2004 os-cillation e.K.
* Copyright (c) 2012 Stephan Arts <stephan@xfce.org>
*
* Written by Benedikt Meurer <benny@xfce.org>.
*
* 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,
* 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.
*
* 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.
*/
#ifndef __RSTTO_ICON_BAR_H__
#define __RSTTO_ICON_BAR_H__
#include <gtk/gtk.h>
G_BEGIN_DECLS
#define RSTTO_TYPE_ICON_BAR (rstto_icon_bar_get_type ())
#define RSTTO_ICON_BAR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RSTTO_TYPE_ICON_BAR, RsttoIconBar))
#define RSTTO_ICON_BAR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RSTTO_TYPE_ICON_BAR, RsttoIconBarClass))
#define RSTTO_IS_ICON_BAR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RSTTO_TYPE_ICON_BAR))
#define RSTTO_IS_ICON_BAR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), RSTTO_TYPE_ICON_BAR))
#define RSTTO_ICON_BAR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RSTTO_TYPE_ICON_BAR, RsttoIconBarClass))
typedef struct _RsttoIconBarPrivate RsttoIconBarPrivate;
typedef struct _RsttoIconBarClass RsttoIconBarClass;
typedef struct _RsttoIconBar RsttoIconBar;
/**
* RsttoIconBarClass:
* @set_scroll_adjustments : Used internally to make the RsttoIconBar scrollable.
* @selection_changed : This signal is emitted whenever the currently selected icon changes.
**/
struct _RsttoIconBarClass
{
GtkContainerClass __parent__;
/* signals */
void (*set_scroll_adjustments) (RsttoIconBar *icon_bar,
GtkAdjustment *hadjustment,
GtkAdjustment *vadjustment);
void (*selection_changed) (RsttoIconBar *icon_bar);
/*< private >*/
void (*reserved1) (void);
void (*reserved2) (void);
void (*reserved3) (void);
void (*reserved4) (void);
};
/**
* RsttoIconBar:
*
* The #RsttoIconBar struct contains only private fields and should not
* be directly accessed.
**/
struct _RsttoIconBar
{
GtkContainer __parent__;
/*< private >*/
RsttoIconBarPrivate *priv;
};
GType rstto_icon_bar_get_type (void) G_GNUC_CONST;
GtkWidget *rstto_icon_bar_new (void);
GtkWidget *rstto_icon_bar_new_with_model (GtkTreeModel *model);
GtkTreeModel *rstto_icon_bar_get_model (RsttoIconBar *icon_bar);
void rstto_icon_bar_set_model (RsttoIconBar *icon_bar,
GtkTreeModel *model);
gint rstto_icon_bar_get_file_column (RsttoIconBar *icon_bar);
void rstto_icon_bar_set_file_column (RsttoIconBar *icon_bar,
gint column);
GtkOrientation rstto_icon_bar_get_orientation (RsttoIconBar *icon_bar);
void rstto_icon_bar_set_orientation (RsttoIconBar *icon_bar,
GtkOrientation orientation);
gint rstto_icon_bar_get_active (RsttoIconBar *icon_bar);
void rstto_icon_bar_set_active (RsttoIconBar *icon_bar,
gint idx);
gboolean rstto_icon_bar_get_active_iter (RsttoIconBar *icon_bar,
GtkTreeIter *iter);
void rstto_icon_bar_set_active_iter (RsttoIconBar *icon_bar,
GtkTreeIter *iter);
gint rstto_icon_bar_get_item_width (RsttoIconBar *icon_bar);
void rstto_icon_bar_set_item_width (RsttoIconBar *icon_bar,
gint item_width);
gboolean rstto_icon_bar_get_show_text (RsttoIconBar *icon_bar);
void rstto_icon_bar_set_show_text (RsttoIconBar *icon_bar,
gboolean show_text);
gboolean rstto_icon_bar_show_active (RsttoIconBar *icon_bar);
G_END_DECLS
#endif /* !__RSTTO_ICON_BAR_H__ */
......@@ -15,7 +15,8 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Sorting-algorithm taken from the thunar filemanager.
* Sorting-algorithm taken from the thunar filemanager.
* Copyright (c) Benedict Meurer <benny@xfce.org>
*/
#include <config.h>
......@@ -33,6 +34,11 @@
#include "image_list.h"
#include "settings.h"
static void
rstto_image_list_tree_model_init (GtkTreeModelIface *iface);
static void
rstto_image_list_tree_sortable_init(GtkTreeSortableIface *iface);
static void
rstto_image_list_init(RsttoImageList *);
static void
......@@ -86,6 +92,77 @@ iter_set_position (
gint pos,
gboolean sticky);
/***************************************/
/* Begin TreeModelIface Functions */
/***************************************/
static GtkTreeModelFlags
image_list_model_get_flags ( GtkTreeModel *tree_model );
static gint
image_list_model_get_n_columns ( GtkTreeModel *tree_model );
static GType
image_list_model_get_column_type (
GtkTreeModel *tree_model,
gint index_ );
static gboolean
image_list_model_get_iter (
GtkTreeModel *tree_model,
GtkTreeIter *iter,
GtkTreePath *path );
static GtkTreePath *
image_list_model_get_path (
GtkTreeModel *tree_model,
GtkTreeIter *iter );
static void
image_list_model_get_value (
GtkTreeModel *tree_model,
GtkTreeIter *iter,
gint column,
GValue *value );
static gboolean
image_list_model_iter_children (
GtkTreeModel *tree_model,
GtkTreeIter *iter,
GtkTreeIter *parent );
static gboolean
image_list_model_iter_has_child (
GtkTreeModel *tree_model,
GtkTreeIter *iter );
static gboolean
image_list_model_iter_parent (
GtkTreeModel *tree_model,
GtkTreeIter *iter,
GtkTreeIter *child );
static gint
image_list_model_iter_n_children (
GtkTreeModel *tree_model,
GtkTreeIter *iter );
static gboolean
image_list_model_iter_nth_child (
GtkTreeModel *tree_model,
GtkTreeIter *iter,
GtkTreeIter *parent,
gint n );
static gboolean
image_list_model_iter_next (
GtkTreeModel *tree_model,
GtkTreeIter *iter );
/***************************************/
/* End TreeModelIface Functions */
/***************************************/
static RsttoImageListIter * rstto_image_list_iter_new ();
static gint
......@@ -98,8 +175,7 @@ static GObjectClass *iter_parent_class = NULL;
enum
{
RSTTO_IMAGE_LIST_SIGNAL_NEW_IMAGE = 0,
RSTTO_IMAGE_LIST_SIGNAL_REMOVE_IMAGE,
RSTTO_IMAGE_LIST_SIGNAL_REMOVE_IMAGE = 0,
RSTTO_IMAGE_LIST_SIGNAL_REMOVE_ALL,
RSTTO_IMAGE_LIST_SIGNAL_COUNT
};
......@@ -111,6 +187,11 @@ enum
RSTTO_IMAGE_LIST_ITER_SIGNAL_COUNT
};
/* Missing image thumbnail, should be re-generated every time
* the thumbnail-size changed.
*/
static GdkPixbuf *thumbnail_missing = NULL;
struct _RsttoImageListIterPriv
{
RsttoImageList *image_list;
......@@ -122,7 +203,8 @@ struct _RsttoImageListIterPriv
struct _RsttoImageListPriv
{
GFileMonitor *monitor;
gint stamp;
GFileMonitor *monitor;
RsttoSettings *settings;
GtkFileFilter *filter;
......@@ -141,6 +223,18 @@ static gint rstto_image_list_iter_signals[RSTTO_IMAGE_LIST_ITER_SIGNAL_COUNT];
GType
rstto_image_list_get_type (void)
{
static const GInterfaceInfo tree_model_info =
{
(GInterfaceInitFunc) rstto_image_list_tree_model_init,
NULL,
NULL
};
static const GInterfaceInfo tree_sort_info =
{
(GInterfaceInitFunc) rstto_image_list_tree_sortable_init,
NULL,
NULL
};
static GType rstto_image_list_type = 0;
if (!rstto_image_list_type)
......@@ -160,15 +254,51 @@ rstto_image_list_get_type (void)
};
rstto_image_list_type = g_type_register_static (G_TYPE_OBJECT, "RsttoImageList", &rstto_image_list_info, 0);
g_type_add_interface_static (rstto_image_list_type, GTK_TYPE_TREE_MODEL, &tree_model_info);
g_type_add_interface_static (rstto_image_list_type, GTK_TYPE_TREE_SORTABLE, &tree_sort_info);
}
return rstto_image_list_type;
}
static void
rstto_image_list_tree_model_init (GtkTreeModelIface *iface)
{
iface->get_flags = image_list_model_get_flags;
iface->get_n_columns = image_list_model_get_n_columns;
iface->get_column_type = image_list_model_get_column_type;
iface->get_iter = image_list_model_get_iter;
iface->get_path = image_list_model_get_path;
iface->get_value = image_list_model_get_value;
iface->iter_children = image_list_model_iter_children;
iface->iter_has_child = image_list_model_iter_has_child;
iface->iter_n_children = image_list_model_iter_n_children;
iface->iter_nth_child = image_list_model_iter_nth_child;
iface->iter_parent = image_list_model_iter_parent;
iface->iter_next = image_list_model_iter_next;
}
static void
rstto_image_list_tree_sortable_init(GtkTreeSortableIface *iface)
{
#if 0
iface->get_sort_column_id = sq_archive_store_get_sort_column_id;
iface->set_sort_column_id = sq_archive_store_set_sort_column_id;
iface->set_sort_func = sq_archive_store_set_sort_func; /*NOT SUPPORTED*/
iface->set_default_sort_func = sq_archive_store_set_default_sort_func; /*NOT SUPPORTED*/
iface->has_default_sort_func = sq_archive_store_has_default_sort_func;
#endif
}
static void
rstto_image_list_init(RsttoImageList *image_list)
{
image_list->priv = g_new0 (RsttoImageListPriv, 1);
image_list->priv->stamp = g_random_int();
image_list->priv->settings = rstto_settings_new ();
image_list->priv->filter = gtk_file_filter_new ();
g_object_ref_sink (image_list->priv->filter);
......@@ -197,18 +327,6 @@ rstto_image_list_class_init(RsttoImageListClass *nav_class)
object_class->dispose = rstto_image_list_dispose;
rstto_image_list_signals[RSTTO_IMAGE_LIST_SIGNAL_NEW_IMAGE] = g_signal_new("new-image",
G_TYPE_FROM_CLASS(nav_class),
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
0,
NULL,
NULL,
g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE,
1,
G_TYPE_OBJECT,
NULL);
rstto_image_list_signals[RSTTO_IMAGE_LIST_SIGNAL_REMOVE_IMAGE] = g_signal_new("remove-image",
G_TYPE_FROM_CLASS(nav_class),
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
......@@ -275,6 +393,9 @@ rstto_image_list_add_file (
GtkFileFilterInfo filter_info;
GList *image_iter = g_list_find (image_list->priv->images, file);
GSList *iter = image_list->priv->iterators;
gint i = 0;
GtkTreePath *path = NULL;
GtkTreeIter t_iter;
g_return_val_if_fail ( NULL != file , FALSE);
g_return_val_if_fail ( RSTTO_IS_FILE (file) , FALSE);
......@@ -294,8 +415,16 @@ rstto_image_list_add_file (
image_list->priv->images = g_list_insert_sorted (image_list->priv->images, file, rstto_image_list_get_compare_func (image_list));
image_list->priv->n_images++;
i = g_list_index (image_list->priv->images, file);
path = gtk_tree_path_new();
gtk_tree_path_append_index (path, i);
t_iter.stamp = image_list->priv->stamp;
t_iter.user_data = file;
t_iter.user_data3 = GINT_TO_POINTER(i);
gtk_tree_model_row_inserted(GTK_TREE_MODEL(image_list), path, &t_iter);
g_signal_emit (G_OBJECT (image_list), rstto_image_list_signals[RSTTO_IMAGE_LIST_SIGNAL_NEW_IMAGE], 0, file, NULL);
/** TODO: update all iterators */
while (iter)
{
......@@ -305,6 +434,7 @@ rstto_image_list_add_file (
}
iter = g_slist_next (iter);
}
return TRUE;
}
else
......@@ -315,8 +445,6 @@ rstto_image_list_add_file (
return FALSE;
}
g_signal_emit (G_OBJECT (image_list), rstto_image_list_signals[RSTTO_IMAGE_LIST_SIGNAL_NEW_IMAGE], 0, image_iter->data, NULL);
return TRUE;
}
......@@ -355,6 +483,7 @@ rstto_image_list_remove_file (RsttoImageList *image_list, RsttoFile *file)
{
GSList *iter = NULL;
RsttoFile *afile = NULL;
GtkTreePath *path_ = NULL;
if (g_list_find(image_list->priv->images, file))
{
......@@ -364,6 +493,12 @@ rstto_image_list_remove_file (RsttoImageList *image_list, RsttoFile *file)
{
if (rstto_file_equal(rstto_image_list_iter_get_file (iter->data), file))
{
path_ = gtk_tree_path_new();
gtk_tree_path_append_index(path_,rstto_image_list_iter_get_position (iter->data));
gtk_tree_model_row_deleted(GTK_TREE_MODEL(image_list), path_);
if (rstto_image_list_iter_get_position (iter->data) == rstto_image_list_get_n_images (image_list)-1)
{
iter_previous (iter->data, FALSE);
......@@ -409,6 +544,22 @@ static void
rstto_image_list_remove_all (RsttoImageList *image_list)
{
GSList *iter = NULL;
GList *image_iter = image_list->priv->images;
GtkTreePath *path_ = NULL;
gint i = g_list_length (image_iter);
while (image_iter)
{
i--;
path_ = gtk_tree_path_new();
gtk_tree_path_append_index(path_, i);
gtk_tree_model_row_deleted(GTK_TREE_MODEL(image_list), path_);
image_iter = g_list_next (image_iter);
}
g_list_foreach (image_list->priv->images, (GFunc)g_object_unref, NULL);
g_list_free (image_list->priv->images);
image_list->priv->images = NULL;
......@@ -1058,3 +1209,220 @@ cb_rstto_wrap_images_changed (
image_list->priv->wrap_images = g_value_get_boolean (&val_wrap_images);
}
/***************************************/
/* TreeModelIface Functions */
/***************************************/
static GtkTreeModelFlags
image_list_model_get_flags ( GtkTreeModel *tree_model )
{
g_return_val_if_fail(RSTTO_IS_IMAGE_LIST(tree_model), (GtkTreeModelFlags)0);
return (GTK_TREE_MODEL_LIST_ONLY | GTK_TREE_MODEL_ITERS_PERSIST);
}
static gint
image_list_model_get_n_columns ( GtkTreeModel *tree_model )
{
g_return_val_if_fail(RSTTO_IS_IMAGE_LIST(tree_model), 0);
return 2;
}
static GType
image_list_model_get_column_type (
GtkTreeModel *tree_model,
gint index_ )
{
g_return_val_if_fail(RSTTO_IS_IMAGE_LIST(tree_model), G_TYPE_INVALID);
switch (index_)
{
case 0: /* file */
return RSTTO_TYPE_FILE;
case 1:
return GDK_TYPE_PIXBUF;
break;
default:
return G_TYPE_INVALID;
break;
}
}
static gboolean
image_list_model_get_iter (
GtkTreeModel *tree_model,
GtkTreeIter *iter,
GtkTreePath *path )
{