Mercurial > geeqie
view src/pan-calendar.c @ 954:ed0fc0986928
do not free unallocated exif data
author | nadvornik |
---|---|
date | Mon, 28 Jul 2008 18:02:10 +0000 |
parents | d6a7fb4b8e7c |
children | 4fe8f9656107 |
line wrap: on
line source
/* * Geeqie * (C) 2006 John Ellis * Copyright (C) 2008 The Geeqie Team * * Author: John Ellis * * This software is released under the GNU General Public License (GNU GPL). * Please read the included file COPYING for more information. * This software comes with no warranty of any kind, use at your own risk! */ #include "main.h" #include "pan-types.h" #include <math.h> #define PAN_CAL_POPUP_COLOR 220, 220, 220 #define PAN_CAL_POPUP_ALPHA 255 #define PAN_CAL_POPUP_BORDER 1 #define PAN_CAL_POPUP_BORDER_COLOR 0, 0, 0 #define PAN_CAL_POPUP_TEXT_COLOR 0, 0, 0 #define PAN_CAL_DAY_WIDTH 100 #define PAN_CAL_DAY_HEIGHT 80 #define PAN_CAL_DAY_COLOR 255, 255, 255 #define PAN_CAL_DAY_ALPHA 220 #define PAN_CAL_DAY_BORDER 2 #define PAN_CAL_DAY_BORDER_COLOR 0, 0, 0 #define PAN_CAL_DAY_TEXT_COLOR 0, 0, 0 #define PAN_CAL_MONTH_COLOR 255, 255, 255 #define PAN_CAL_MONTH_ALPHA 200 #define PAN_CAL_MONTH_BORDER 4 #define PAN_CAL_MONTH_BORDER_COLOR 0, 0, 0 #define PAN_CAL_MONTH_TEXT_COLOR 0, 0, 0 #define PAN_CAL_DOT_SIZE 3 #define PAN_CAL_DOT_GAP 2 #define PAN_CAL_DOT_COLOR 128, 128, 128 #define PAN_CAL_DOT_ALPHA 128 /* *----------------------------------------------------------------------------- * calendar *----------------------------------------------------------------------------- */ void pan_calendar_update(PanWindow *pw, PanItem *pi_day) { PanItem *pbox; PanItem *pi; GList *list; GList *work; gint x1, y1, x2, y2, x3, y3; gint x, y, w, h; gint grid; gint column; while ((pi = pan_item_find_by_key(pw, PAN_ITEM_NONE, "day_bubble"))) pan_item_remove(pw, pi); if (!pi_day || pi_day->type != PAN_ITEM_BOX || !pi_day->key || strcmp(pi_day->key, "day") != 0) return; list = pan_layout_intersect(pw, pi_day->x, pi_day->y, pi_day->width, pi_day->height); work = list; while (work) { PanItem *dot; GList *node; dot = work->data; node = work; work = work->next; if (dot->type != PAN_ITEM_BOX || !dot->fd || !dot->key || strcmp(dot->key, "dot") != 0) { list = g_list_delete_link(list, node); } } #if 0 if (!list) return; #endif grid = (gint)(sqrt(g_list_length(list)) + 0.5); x = pi_day->x + pi_day->width + 4; y = pi_day->y; #if 0 if (y + grid * (PAN_THUMB_SIZE + PAN_THUMB_GAP) + PAN_BOX_BORDER * 4 > pw->pr->image_height) { y = pw->pr->image_height - (grid * (PAN_THUMB_SIZE + PAN_THUMB_GAP) + PAN_BOX_BORDER * 4); } #endif pbox = pan_item_box_new(pw, NULL, x, y, PAN_BOX_BORDER, PAN_BOX_BORDER, PAN_CAL_POPUP_BORDER, PAN_CAL_POPUP_COLOR, PAN_CAL_POPUP_ALPHA, PAN_CAL_POPUP_BORDER_COLOR, PAN_CAL_POPUP_ALPHA); pan_item_set_key(pbox, "day_bubble"); if (pi_day->fd) { PanItem *plabel; gchar *buf; buf = pan_date_value_string(pi_day->fd->date, PAN_DATE_LENGTH_WEEK); plabel = pan_item_text_new(pw, x, y, buf, PAN_TEXT_ATTR_BOLD | PAN_TEXT_ATTR_HEADING, PAN_TEXT_BORDER_SIZE, PAN_CAL_POPUP_TEXT_COLOR, 255); pan_item_set_key(plabel, "day_bubble"); g_free(buf); pan_item_size_by_item(pbox, plabel, 0); y += plabel->height; } if (list) { column = 0; x += PAN_BOX_BORDER; y += PAN_BOX_BORDER; work = list; while (work) { PanItem *dot; dot = work->data; work = work->next; if (dot->fd) { PanItem *pimg; pimg = pan_item_thumb_new(pw, file_data_ref(dot->fd), x, y); pan_item_set_key(pimg, "day_bubble"); pan_item_size_by_item(pbox, pimg, PAN_BOX_BORDER); column++; if (column < grid) { x += PAN_THUMB_SIZE + PAN_THUMB_GAP; } else { column = 0; x = pbox->x + PAN_BOX_BORDER; y += PAN_THUMB_SIZE + PAN_THUMB_GAP; } } } } x1 = pi_day->x + pi_day->width - 8; y1 = pi_day->y + 8; x2 = pbox->x + 1; y2 = pbox->y + MIN(42, pbox->height); x3 = pbox->x + 1; y3 = MAX(pbox->y, y2 - 30); util_clip_triangle(x1, y1, x2, y2, x3, y3, &x, &y, &w, &h); pi = pan_item_tri_new(pw, NULL, x, y, w, h, x1, y1, x2, y2, x3, y3, PAN_CAL_POPUP_COLOR, PAN_CAL_POPUP_ALPHA); pan_item_tri_border(pi, PAN_BORDER_1 | PAN_BORDER_3, PAN_CAL_POPUP_BORDER_COLOR, PAN_CAL_POPUP_ALPHA); pan_item_set_key(pi, "day_bubble"); pan_item_added(pw, pi); pan_item_box_shadow(pbox, PAN_SHADOW_OFFSET * 2, PAN_SHADOW_FADE * 2); pan_item_added(pw, pbox); pan_layout_resize(pw); } void pan_calendar_compute(PanWindow *pw, FileData *dir_fd, gint *width, gint *height) { GList *list; GList *work; gint x, y; time_t tc; gint count; gint day_max; gint day_width; gint day_height; gint grid; gint year = 0; gint month = 0; gint end_year = 0; gint end_month = 0; list = pan_list_tree(dir_fd, SORT_NONE, TRUE, pw->ignore_symlinks); if (pw->cache_list && pw->exif_date_enable) { pw->cache_list = pan_cache_sort(pw->cache_list, SORT_NAME, TRUE); list = filelist_sort(list, SORT_NAME, TRUE); pan_cache_sync_date(pw, list); } pw->cache_list = pan_cache_sort(pw->cache_list, SORT_TIME, TRUE); list = filelist_sort(list, SORT_TIME, TRUE); day_max = 0; count = 0; tc = 0; work = list; while (work) { FileData *fd; fd = work->data; work = work->next; if (!pan_date_compare(fd->date, tc, PAN_DATE_LENGTH_DAY)) { count = 0; tc = fd->date; } else { count++; if (day_max < count) day_max = count; } } DEBUG_1("biggest day contains %d images", day_max); grid = (gint)(sqrt((double)day_max) + 0.5) * (PAN_THUMB_SIZE + PAN_SHADOW_OFFSET * 2 + PAN_THUMB_GAP); day_width = MAX(PAN_CAL_DAY_WIDTH, grid); day_height = MAX(PAN_CAL_DAY_HEIGHT, grid); if (list) { FileData *fd = list->data; year = pan_date_value(fd->date, PAN_DATE_LENGTH_YEAR); month = pan_date_value(fd->date, PAN_DATE_LENGTH_MONTH); } work = g_list_last(list); if (work) { FileData *fd = work->data; end_year = pan_date_value(fd->date, PAN_DATE_LENGTH_YEAR); end_month = pan_date_value(fd->date, PAN_DATE_LENGTH_MONTH); } *width = PAN_BOX_BORDER * 2; *height = PAN_BOX_BORDER * 2; x = PAN_BOX_BORDER; y = PAN_BOX_BORDER; work = list; while (work && (year < end_year || (year == end_year && month <= end_month))) { PanItem *pi_month; PanItem *pi_text; gint day; gint days; gint col; gint row; time_t dt; gchar *buf; /* figure last second of this month */ dt = pan_date_to_time((month == 12) ? year + 1 : year, (month == 12) ? 1 : month + 1, 1); dt -= 60 * 60 * 24; /* anything to show this month? */ if (!pan_date_compare(((FileData *)(work->data))->date, dt, PAN_DATE_LENGTH_MONTH)) { month ++; if (month > 12) { year++; month = 1; } continue; } days = pan_date_value(dt, PAN_DATE_LENGTH_DAY); dt = pan_date_to_time(year, month, 1); col = pan_date_value(dt, PAN_DATE_LENGTH_WEEK); row = 1; x = PAN_BOX_BORDER; pi_month = pan_item_box_new(pw, NULL, x, y, PAN_CAL_DAY_WIDTH * 7, PAN_CAL_DAY_HEIGHT / 4, PAN_CAL_MONTH_BORDER, PAN_CAL_MONTH_COLOR, PAN_CAL_MONTH_ALPHA, PAN_CAL_MONTH_BORDER_COLOR, PAN_CAL_MONTH_ALPHA); buf = pan_date_value_string(dt, PAN_DATE_LENGTH_MONTH); pi_text = pan_item_text_new(pw, x, y, buf, PAN_TEXT_ATTR_BOLD | PAN_TEXT_ATTR_HEADING, PAN_TEXT_BORDER_SIZE, PAN_CAL_MONTH_TEXT_COLOR, 255); g_free(buf); pi_text->x = pi_month->x + (pi_month->width - pi_text->width) / 2; pi_month->height = pi_text->y + pi_text->height - pi_month->y; x = PAN_BOX_BORDER + col * PAN_CAL_DAY_WIDTH; y = pi_month->y + pi_month->height + PAN_BOX_BORDER; for (day = 1; day <= days; day++) { FileData *fd; PanItem *pi_day; gint dx, dy; gint n = 0; char fake_path[20]; dt = pan_date_to_time(year, month, day); /* * Create a FileData entry that represents the given day. * It does not correspond to any real file */ g_snprintf(fake_path, sizeof(fake_path), "//%04d-%02d-%02d", year, month, day); fd = file_data_new_simple(fake_path); fd->date = dt; pi_day = pan_item_box_new(pw, fd, x, y, PAN_CAL_DAY_WIDTH, PAN_CAL_DAY_HEIGHT, PAN_CAL_DAY_BORDER, PAN_CAL_DAY_COLOR, PAN_CAL_DAY_ALPHA, PAN_CAL_DAY_BORDER_COLOR, PAN_CAL_DAY_ALPHA); pan_item_set_key(pi_day, "day"); dx = x + PAN_CAL_DOT_GAP * 2; dy = y + PAN_CAL_DOT_GAP * 2; fd = (work) ? work->data : NULL; while (fd && pan_date_compare(fd->date, dt, PAN_DATE_LENGTH_DAY)) { PanItem *pi; pi = pan_item_box_new(pw, fd, dx, dy, PAN_CAL_DOT_SIZE, PAN_CAL_DOT_SIZE, 0, PAN_CAL_DOT_COLOR, PAN_CAL_DOT_ALPHA, 0, 0, 0, 0); pan_item_set_key(pi, "dot"); dx += PAN_CAL_DOT_SIZE + PAN_CAL_DOT_GAP; if (dx + PAN_CAL_DOT_SIZE > pi_day->x + pi_day->width - PAN_CAL_DOT_GAP * 2) { dx = x + PAN_CAL_DOT_GAP * 2; dy += PAN_CAL_DOT_SIZE + PAN_CAL_DOT_GAP; } if (dy + PAN_CAL_DOT_SIZE > pi_day->y + pi_day->height - PAN_CAL_DOT_GAP * 2) { /* must keep all dots within respective day even if it gets ugly */ dy = y + PAN_CAL_DOT_GAP * 2; } n++; work = work->next; fd = (work) ? work->data : NULL; } if (n > 0) { PanItem *pi; pi_day->color_r = MAX(pi_day->color_r - 61 - n * 3, 80); pi_day->color_g = pi_day->color_r; buf = g_strdup_printf("( %d )", n); pi = pan_item_text_new(pw, x, y, buf, PAN_TEXT_ATTR_NONE, PAN_TEXT_BORDER_SIZE, PAN_CAL_DAY_TEXT_COLOR, 255); g_free(buf); pi->x = pi_day->x + (pi_day->width - pi->width) / 2; pi->y = pi_day->y + (pi_day->height - pi->height) / 2; } buf = g_strdup_printf("%d", day); pan_item_text_new(pw, x + 4, y + 4, buf, PAN_TEXT_ATTR_BOLD | PAN_TEXT_ATTR_HEADING, PAN_TEXT_BORDER_SIZE, PAN_CAL_DAY_TEXT_COLOR, 255); g_free(buf); pan_item_size_coordinates(pi_day, PAN_BOX_BORDER, width, height); col++; if (col > 6) { col = 0; row++; x = PAN_BOX_BORDER; y += PAN_CAL_DAY_HEIGHT; } else { x += PAN_CAL_DAY_WIDTH; } } if (col > 0) y += PAN_CAL_DAY_HEIGHT; y += PAN_BOX_BORDER * 2; month ++; if (month > 12) { year++; month = 1; } } *width += grid; *height = MAX(*height, grid + PAN_BOX_BORDER * 2 * 2); g_list_free(list); }