111
113
static void cancel_clicked(GtkButton *button, gpointer user_data);
112
114
GList *find_loadable(const gchar *path, gboolean load_8bit, gboolean load_recursive);
113
115
void load_loadable(RSStore *store, GList *loadable, RS_PROGRESS *rsp);
116
void cairo_draw_thumbnail(cairo_t *cr, GdkPixbuf *pixbuf, gint x, gint y, gint width, gint height, gdouble alphas);
117
GdkPixbuf * store_group_update_pixbufs(GdkPixbuf *pixbuf, GdkPixbuf *pixbuf_clean);
114
118
void store_group_select_n(GtkListStore *store, GtkTreeIter iter, guint n);
115
119
gboolean store_iter_is_group(GtkListStore *store, GtkTreeIter *iter);
116
120
void store_save_groups(GtkListStore *store);
117
121
void store_load_groups(GtkListStore *store);
118
122
void store_group_photos_by_iters(GtkListStore *store, GList *members);
119
123
void store_group_photos_by_filenames(GtkListStore *store, GList *members);
124
static GList *store_iter_list_to_filename_list(GtkListStore *store, GList *iters);
125
void store_group_select_name(GtkListStore *store, const gchar *filename);
126
void store_group_find_name(GtkListStore *store, const gchar *name, GtkTreeIter *iter, gint *n);
127
void store_get_members(GtkListStore *store, GtkTreeIter *iter, GList **members);
128
void store_get_type(GtkListStore *store, GtkTreeIter *iter, gint *type);
129
void store_get_fullname(GtkListStore *store, GtkTreeIter *iter, gchar **fullname);
130
void store_set_members(GtkListStore *store, GtkTreeIter *iter, GList *members);
122
133
* Class initializer
371
392
selection_changed(GtkIconView *iconview, gpointer data)
394
RSStore *store = RS_STORE(data);
395
GtkTreeModel *model = GTK_TREE_MODEL(store->store);
399
GList *group_member_list;
400
GList *filename_list;
373
401
GList *selected = NULL;
374
402
gint num_selected;
376
404
/* Get list of selected icons */
377
gtk_icon_view_selected_foreach(iconview, icon_get_selected_names, &selected);
405
selected = rs_store_get_selected_iters(store);
379
406
num_selected = g_list_length(selected);
381
408
/* Emit signal if only one thumbnail is selected */
382
409
if (num_selected == 1)
383
g_signal_emit (G_OBJECT (data), signals[THUMB_ACTIVATED_SIGNAL], 0, g_list_nth_data(selected, 0));
411
iter = * (GtkTreeIter *) g_list_nth_data(selected, 0);
412
/* Get type of row */
413
gtk_tree_model_get(model, &iter, TYPE_COLUMN, &type, -1);
416
case RS_STORE_TYPE_GROUP:
417
gtk_tree_model_get(model, &iter, GROUP_LIST_COLUMN, &group_member_list, -1);
418
filename_list = store_iter_list_to_filename_list(store->store, group_member_list);
419
g_signal_emit(G_OBJECT(data), signals[GROUP_ACTIVATED_SIGNAL], 0, filename_list);
420
g_list_free(filename_list);
423
gtk_tree_model_get(GTK_TREE_MODEL(store->store), &iter, FULLNAME_COLUMN, &name, -1);
424
g_signal_emit(G_OBJECT(data), signals[THUMB_ACTIVATED_SIGNAL], 0, name);
429
g_list_foreach(selected, (GFunc)g_free, NULL);
385
430
g_list_free(selected);
387
432
predict_preload(data, FALSE);
1403
1446
return gtk_notebook_get_current_page(store->notebook);
1450
cairo_draw_thumbnail(cairo_t *cr, GdkPixbuf *pixbuf, gint x, gint y, gint width, gint height, gdouble alpha)
1452
gdouble greyvalue = 1.0;
1454
cairo_set_source_rgba(cr, greyvalue, greyvalue, greyvalue, 0.5);
1455
cairo_rectangle(cr, x, y, width, height);
1458
gint pixbuf_height = gdk_pixbuf_get_height(pixbuf);
1459
gint pixbuf_width = gdk_pixbuf_get_width(pixbuf);
1461
GdkPixbuf *pixbuf_scaled = gdk_pixbuf_scale_simple(pixbuf, (pixbuf_width-4), (pixbuf_height-4), GDK_INTERP_HYPER);
1462
gdk_cairo_set_source_pixbuf(cr, pixbuf_scaled, (x+2), (y+2));
1463
g_object_unref(pixbuf_scaled);
1466
cairo_set_source_rgba(cr, 0.5, 0.5, 0.5, alpha);
1467
cairo_rectangle(cr, x+1, y+1, width-2, height-2);
1474
calc_rotated_coordinats(gdouble a, gdouble b, gdouble R, gdouble *a2, gdouble *b2)
1407
1485
store_group_update_pixbufs(GdkPixbuf *pixbuf, GdkPixbuf *pixbuf_clean)
1409
gint width, height, new_width, new_height;
1413
GdkPixbuf *new_pixbuf, *pixbuf_scaled;
1488
GdkPixbuf *new_pixbuf;
1415
1490
width = gdk_pixbuf_get_width(pixbuf_clean);
1416
1491
height = gdk_pixbuf_get_height(pixbuf_clean);
1418
1493
new_pixbuf = gdk_pixbuf_new(gdk_pixbuf_get_colorspace(pixbuf_clean),
1420
1495
gdk_pixbuf_get_bits_per_sample(pixbuf_clean),
1499
#if GTK_CHECK_VERSION(2,8,0) && defined(EXPERIMENTAL)
1501
gdouble a2, b2, scale, bb_x1, bb_x2, bb_y1, bb_y2, bb_height, bb_width, xoffset, yoffset, border = 1;
1503
/* We have a bit more room with landscape-mode photos than with portrait-mode*/
1509
/* upper left of left rotation - we need a2 */
1510
calc_rotated_coordinats((0-(width/2)), 128, -0.1, &a2, &b2);
1513
/* upper left of right rotation - we need b2 */
1514
calc_rotated_coordinats((0-(width/2)), 128, 0.2, &a2, &b2);
1517
/* upper right of right rotation - we need b2 */
1518
calc_rotated_coordinats((width/2), 128, 0.2, &a2, &b2);
1521
/* lower right of right rotation - we need b2 */
1522
calc_rotated_coordinats((width/2),(128-height), 0.2, &a2, &b2);
1525
/* Calculate the magic numbers - it will work from scale 0.7 and up */
1526
bb_height = ((bb_y1-bb_y2)+border*2)*scale;
1527
bb_width = ((bb_x1*-1+bb_x2+10)+border*2)*scale;
1528
xoffset = (bb_x2+bb_x1)/2/scale*-1;
1529
yoffset = (128-(bb_y1-(128)))/scale*-1;
1531
cairo_surface_t *surface;
1534
surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, bb_width, bb_height);
1536
cr = cairo_create(surface);
1538
cairo_translate(cr, (bb_width/2), 128);
1539
cairo_scale(cr, scale, scale);
1541
cairo_rotate(cr, -0.1);
1542
cairo_draw_thumbnail(cr, pixbuf_clean, (width/-2)+xoffset, yoffset, width, height, 0.7);
1543
cairo_rotate(cr, 0.2);
1544
cairo_draw_thumbnail(cr, pixbuf_clean, (width/-2)+xoffset, yoffset, width, height, 0.7);
1545
cairo_rotate(cr, 0.1);
1546
cairo_draw_thumbnail(cr, pixbuf_clean, (width/-2)+xoffset, yoffset, width, height, 0.7);
1547
cairo_rotate(cr, -0.2);
1548
cairo_draw_thumbnail(cr, pixbuf_clean, (width/-2)+xoffset, yoffset, width, height, 0.0);
1551
new_pixbuf = cairo_convert_to_pixbuf(surface);
1557
gint new_width, new_height;
1558
GdkPixbuf *pixbuf_scaled;
1654
1788
if (store_iter_is_group(store, &iter))
1790
gchar *selected = NULL;
1791
GList *members, *filenames;
1659
1793
xmlTextWriterStartElement(writer, BAD_CAST "group");
1661
1795
// Find selected member and place this first in XML
1662
gtk_tree_model_get(GTK_TREE_MODEL(store), &iter,
1663
FULLNAME_COLUMN, &selected,
1796
store_get_fullname(store, &iter, &selected);
1665
1798
xmlTextWriterWriteFormatElement(writer, BAD_CAST "member", "%s", selected);
1667
gtk_tree_model_get(GTK_TREE_MODEL(store), &iter,
1668
GROUP_LIST_COLUMN, &members,
1800
store_get_members(store, &iter, &members);
1671
for( m = 0; m < g_list_length(members); m++)
1803
filenames = store_iter_list_to_filename_list(store, members);
1805
for( m = 0; m < g_list_length(filenames); m++)
1673
GtkTreeIter *child_iter = (GtkTreeIter *) g_list_nth_data(members, m);
1674
gtk_tree_model_get (GTK_TREE_MODEL(store), child_iter, FULLNAME_COLUMN, &filename, -1);
1807
filename = g_list_nth_data(filenames, m);
1675
1808
if (!g_str_equal(selected, filename))
1676
1809
xmlTextWriterWriteFormatElement(writer, BAD_CAST "member", "%s", filename);
1796
1934
return g_list_sort(selected, (GCompareFunc) g_utf8_collate);
1938
rs_store_auto_group(RSStore *store)
1940
RS_FILETYPE *filetype = NULL;
1941
gchar *filename = NULL;
1942
gint timestamp = 0, timestamp_old = 0;
1945
GList *filenames = NULL;
1948
// TODO: remove all existing groups in iconview.
1950
gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store->store), &iter);
1953
store_get_fullname(GTK_LIST_STORE(store->store), &iter, &filename);
1954
filetype = rs_filetype_get(filename, TRUE);
1957
if(filetype->load_meta)
1959
meta = rs_metadata_new();
1960
filetype->load_meta(filename, meta);
1962
if (!meta->timestamp)
1965
timestamp = meta->timestamp;
1966
exposure = (1/meta->shutterspeed);
1968
if (timestamp > timestamp_old + 1)
1970
if (g_list_length(filenames) > 1)
1971
store_group_photos_by_filenames(store->store, filenames);
1972
g_list_free(filenames);
1975
timestamp_old = timestamp + exposure;
1979
filenames = g_list_append(filenames, filename);
1980
} while (gtk_tree_model_iter_next(GTK_TREE_MODEL(store->store), &iter));
1982
store_group_photos_by_filenames(store->store, filenames);
1983
g_list_free(filenames);
1988
store_iter_list_to_filename_list(GtkListStore *store, GList *iters)
1991
gchar *filename = NULL;
1992
GList *filenames = NULL;
1994
for (n=0; n<g_list_length(iters); n++)
1996
GtkTreeIter *iter = (GtkTreeIter *) g_list_nth_data(iters, n);
1997
store_get_fullname(store, iter, &filename);
1998
filenames = g_list_append(filenames, filename);
2005
store_group_select_name(GtkListStore *store, const gchar *filename)
2010
store_group_find_name(store, filename, &iter, &n);
2011
store_group_select_n(store, iter, n);
2015
store_group_find_name(GtkListStore *store, const gchar *name, GtkTreeIter *iter, gint *n)
2019
GList *members = NULL;
2020
GList *filenames = NULL;
2022
gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), iter);
2025
store_get_type(store, iter, &type);
2027
if (type == RS_STORE_TYPE_GROUP)
2029
store_get_members(store, iter, &members);
2030
filenames = store_iter_list_to_filename_list(store, members);
2032
for(i = 0; i < g_list_length(filenames); i++)
2034
if (g_str_equal(g_list_nth_data(filenames, i), name))
2040
g_list_free(filenames);
2042
} while (gtk_tree_model_iter_next(GTK_TREE_MODEL(store), iter));
2049
rs_store_group_select_name(RSStore *store, const gchar *filename)
2051
store_group_select_name(store->store, filename);
2055
store_group_ungroup_name(GtkListStore *store, const gchar *name)
2057
GtkTreeIter iter, *child_iter;
2061
store_group_find_name(store, name, &iter, &n);
2063
gtk_tree_model_get (GTK_TREE_MODEL(store), &iter,
2064
GROUP_LIST_COLUMN, &members,
2067
child_iter = (GtkTreeIter *) g_list_nth_data(members, n);
2068
gtk_list_store_set(store, child_iter,
2069
TYPE_COLUMN, RS_STORE_TYPE_FILE,
2072
members = g_list_remove(members, g_list_nth_data(members,n));
2074
/* If group now only has one member, we destroy the group */
2075
if (g_list_length(members) == 1)
2077
child_iter = (GtkTreeIter *) g_list_nth_data(members, 0);
2078
gtk_list_store_set(store, child_iter,
2079
TYPE_COLUMN, RS_STORE_TYPE_FILE,
2081
gtk_list_store_remove (store, &iter);
2083
store_set_members(store, &iter, members);
2084
store_save_groups(store);
2088
rs_store_group_ungroup_name(RSStore *store, const gchar *filename)
2090
store_group_ungroup_name(store->store, filename);
2094
store_get_members(GtkListStore *store, GtkTreeIter *iter, GList **members)
2096
gtk_tree_model_get (GTK_TREE_MODEL(store), iter,
2097
GROUP_LIST_COLUMN, members,
2102
store_get_type(GtkListStore *store, GtkTreeIter *iter, gint *type)
2104
gtk_tree_model_get (GTK_TREE_MODEL(store), iter,
2110
store_get_fullname(GtkListStore *store, GtkTreeIter *iter, gchar **fullname)
2112
gtk_tree_model_get (GTK_TREE_MODEL(store), iter,
2113
FULLNAME_COLUMN, fullname,
2118
store_set_members(GtkListStore *store, GtkTreeIter *iter, GList *members)
2120
gtk_list_store_set (store, iter,
2121
GROUP_LIST_COLUMN, members,