static void bar_pane_exif_update_entry(PaneExifData *ped, GtkWidget *entry, gboolean update_title) { gchar *text; ExifEntry *ee = g_object_get_data(G_OBJECT(entry), "entry_data"); if (!ee) return; text = metadata_read_string(ped->fd, ee->key, ee->editable ? METADATA_PLAIN : METADATA_FORMATTED); if (!ped->show_all && ee->if_set && !ee->editable && (!text || !*text)) { gtk_label_set_text(GTK_LABEL(ee->value_widget), NULL); gtk_widget_hide(entry); } else { if (ee->editable) { g_signal_handlers_block_by_func(ee->value_widget, bar_pane_exif_entry_changed, ee); gtk_entry_set_text(GTK_ENTRY(ee->value_widget), text ? text : ""); g_signal_handlers_unblock_by_func(ee->value_widget, bar_pane_exif_entry_changed, ee); gtk_widget_set_tooltip_text(ee->box, NULL); } else { gtk_label_set_text(GTK_LABEL(ee->value_widget), text); gtk_widget_set_tooltip_text(ee->box, text); } gtk_widget_show(entry); ped->all_hidden = FALSE; } g_free(text); if (update_title) bar_pane_exif_entry_update_title(ee); }
gdouble metadata_read_GPS_direction(FileData *fd, const gchar *key, gdouble fallback) { gchar *endptr; gdouble deg; gboolean ok = FALSE; gchar *string = metadata_read_string(fd, key, METADATA_PLAIN); if (!string) return fallback; DEBUG_3("GPS_direction: %s\n", string); deg = g_ascii_strtod(string, &endptr); /* Expected text string is of the format e.g.: * 18000/100 */ if (*endptr == '/') { deg = deg/100; ok = TRUE; } if (!ok) { deg = fallback; log_printf("unable to parse GPS direction '%s: %f'\n", string, deg); } g_free(string); return deg; }
guint64 metadata_read_int(FileData *fd, const gchar *key, guint64 fallback) { guint64 ret; gchar *endptr; gchar *string = metadata_read_string(fd, key, METADATA_PLAIN); if (!string) return fallback; ret = g_ascii_strtoull(string, &endptr, 10); if (string == endptr) ret = fallback; g_free(string); return ret; }
gboolean metadata_append_string(FileData *fd, const gchar *key, const char *value) { gchar *str = metadata_read_string(fd, key, METADATA_PLAIN); if (!str) { return metadata_write_string(fd, key, value); } else { gchar *new_string = g_strconcat(str, value, NULL); gboolean ret = metadata_write_string(fd, key, new_string); g_free(str); g_free(new_string); return ret; } }
static void bar_pane_comment_update(PaneCommentData *pcd) { gchar *comment = NULL; gchar *orig_comment = NULL; gchar *comment_not_null; GtkTextBuffer *comment_buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(pcd->comment_view)); orig_comment = text_widget_text_pull(pcd->comment_view); comment = metadata_read_string(pcd->fd, pcd->key, METADATA_PLAIN); comment_not_null = (comment) ? comment : ""; if (strcmp(orig_comment, comment_not_null) != 0) { g_signal_handlers_block_by_func(comment_buffer, bar_pane_comment_changed, pcd); gtk_text_buffer_set_text(comment_buffer, comment_not_null, -1); g_signal_handlers_unblock_by_func(comment_buffer, bar_pane_comment_changed, pcd); } g_free(comment); g_free(orig_comment); gtk_widget_set_sensitive(pcd->comment_view, (pcd->fd != NULL)); }
gdouble metadata_read_GPS_coord(FileData *fd, const gchar *key, gdouble fallback) { gdouble coord; gchar *endptr; gdouble deg, min, sec; gboolean ok = FALSE; gchar *string = metadata_read_string(fd, key, METADATA_PLAIN); if (!string) return fallback; deg = g_ascii_strtod(string, &endptr); if (*endptr == ',') { min = g_ascii_strtod(endptr + 1, &endptr); if (*endptr == ',') sec = g_ascii_strtod(endptr + 1, &endptr); else sec = 0.0; if (*endptr == 'S' || *endptr == 'W' || *endptr == 'N' || *endptr == 'E') { coord = deg + min /60.0 + sec / 3600.0; ok = TRUE; if (*endptr == 'S' || *endptr == 'W') coord = -coord; } } if (!ok) { coord = fallback; log_printf("unable to parse GPS coordinate '%s'\n", string); } g_free(string); return coord; }
static gboolean bar_pane_gps_marker_keypress_cb(GtkWidget *widget, ClutterButtonEvent *bevent, gpointer data) { //PaneGPSData *pgd = data; FileData *fd; ClutterActor *marker; ClutterColor marker_colour = { MARKER_COLOUR }; ClutterColor text_colour = { TEXT_COLOUR }; ClutterColor thumb_colour = { THUMB_COLOUR }; gchar *current_text; ClutterActor *actor; ClutterActor *current_image; GString *text; gint height, width, rotate; gchar *altitude = NULL; ThumbLoader *tl; if (bevent->button == MOUSE_BUTTON_LEFT) { marker = CLUTTER_ACTOR(widget); fd = g_object_get_data(G_OBJECT(marker), "file_fd"); /* If the marker is showing a thumbnail, delete it */ current_image = champlain_marker_get_image(CHAMPLAIN_MARKER(marker)); if (current_image != NULL) { clutter_actor_destroy(CLUTTER_ACTOR(current_image)); champlain_marker_set_image(CHAMPLAIN_MARKER(marker), NULL); } current_text = g_strdup(champlain_marker_get_text(CHAMPLAIN_MARKER(marker))); /* If the marker is showing only the text character, replace it with a * thumbnail and date and altitude */ if (g_strcmp0(current_text, "i") == 0) { /* If a thumbail has already been generated, use that. If not try the pixbuf of the full image. * If not, call the thumb_loader to generate a thumbnail and update the marker later in the * thumb_loader callback */ if (fd->thumb_pixbuf != NULL) { actor = clutter_texture_new(); gtk_clutter_texture_set_from_pixbuf(CLUTTER_TEXTURE(actor), fd->thumb_pixbuf, NULL); champlain_marker_set_image(CHAMPLAIN_MARKER(marker), actor); } else if (fd->pixbuf != NULL) { actor = clutter_texture_new(); width = gdk_pixbuf_get_width (fd->pixbuf); height = gdk_pixbuf_get_height (fd->pixbuf); switch (fd->exif_orientation) { case 8: rotate = GDK_PIXBUF_ROTATE_COUNTERCLOCKWISE; break; case 3: rotate = GDK_PIXBUF_ROTATE_UPSIDEDOWN; break; case 6: rotate = GDK_PIXBUF_ROTATE_CLOCKWISE; break; default: rotate = GDK_PIXBUF_ROTATE_NONE; } gtk_clutter_texture_set_from_pixbuf(CLUTTER_TEXTURE(actor), gdk_pixbuf_rotate_simple(gdk_pixbuf_scale_simple(fd->pixbuf, THUMB_SIZE, height * THUMB_SIZE / width, GDK_INTERP_NEAREST), rotate), NULL); champlain_marker_set_image(CHAMPLAIN_MARKER(marker), actor); } else { tl = thumb_loader_new(THUMB_SIZE, THUMB_SIZE); thumb_loader_set_callbacks(tl, bar_pane_gps_thumb_done_cb, bar_pane_gps_thumb_error_cb, NULL, marker); thumb_loader_start(tl, fd); } text = g_string_new(fd->name); g_string_append(text, "\n"); g_string_append(text, text_from_time(fd->date)); g_string_append(text, "\n"); altitude = metadata_read_string(fd, "formatted.GPSAltitude", METADATA_FORMATTED); if (altitude != NULL) { g_string_append(text, altitude); } champlain_marker_set_text(CHAMPLAIN_MARKER(marker), text->str); champlain_marker_set_color(CHAMPLAIN_MARKER(marker), &thumb_colour); champlain_marker_set_text_color(CHAMPLAIN_MARKER(marker), &text_colour); champlain_marker_set_font_name(CHAMPLAIN_MARKER(marker), "sans 8"); g_free(altitude); g_string_free(text, TRUE); } /* otherwise, revert to the hidden text marker */ else { champlain_marker_set_text(CHAMPLAIN_MARKER(marker), "i"); champlain_marker_set_color(CHAMPLAIN_MARKER(marker), &marker_colour); champlain_marker_set_text_color(CHAMPLAIN_MARKER(marker), &marker_colour); champlain_marker_set_font_name(CHAMPLAIN_MARKER(marker), "courier 5"); } g_free(current_text); return TRUE; } return TRUE; }
static gboolean cache_loader_process(CacheLoader *cl) { if (cl->todo_mask & CACHE_LOADER_SIMILARITY && !cl->cd->similarity) { GdkPixbuf *pixbuf; if (!cl->il && !cl->error) { cl->il = image_loader_new(cl->fd); g_signal_connect(G_OBJECT(cl->il), "error", (GCallback)cache_loader_error_cb, cl); g_signal_connect(G_OBJECT(cl->il), "done", (GCallback)cache_loader_done_cb, cl); if (image_loader_start(cl->il)) { return FALSE; } cl->error = TRUE; } pixbuf = image_loader_get_pixbuf(cl->il); if (pixbuf) { if (!cl->error) { ImageSimilarityData *sim; sim = image_sim_new_from_pixbuf(pixbuf); cache_sim_data_set_similarity(cl->cd, sim); image_sim_free(sim); cl->done_mask |= CACHE_LOADER_SIMILARITY; } /* we have the dimensions via pixbuf */ if (!cl->cd->dimensions) { cache_sim_data_set_dimensions(cl->cd, gdk_pixbuf_get_width(pixbuf), gdk_pixbuf_get_height(pixbuf)); if (cl->todo_mask & CACHE_LOADER_DIMENSIONS) { cl->todo_mask &= ~CACHE_LOADER_DIMENSIONS; cl->done_mask |= CACHE_LOADER_DIMENSIONS; } } } image_loader_free(cl->il); cl->il = NULL; cl->todo_mask &= ~CACHE_LOADER_SIMILARITY; } else if (cl->todo_mask & CACHE_LOADER_DIMENSIONS && !cl->cd->dimensions) { if (!cl->error && image_load_dimensions(cl->fd, &cl->cd->width, &cl->cd->height)) { cl->cd->dimensions = TRUE; cl->done_mask |= CACHE_LOADER_DIMENSIONS; } else { cl->error = TRUE; } cl->todo_mask &= ~CACHE_LOADER_DIMENSIONS; } else if (cl->todo_mask & CACHE_LOADER_MD5SUM && !cl->cd->have_md5sum) { if (md5_get_digest_from_file_utf8(cl->fd->path, cl->cd->md5sum)) { cl->cd->have_md5sum = TRUE; cl->done_mask |= CACHE_LOADER_MD5SUM; } else { cl->error = TRUE; } cl->todo_mask &= ~CACHE_LOADER_MD5SUM; } else if (cl->todo_mask & CACHE_LOADER_DATE && !cl->cd->have_date) { time_t date = -1; gchar *text; text = metadata_read_string(cl->fd, "formatted.DateTime", METADATA_FORMATTED); if (text) { struct tm t; memset(&t, 0, sizeof(t)); if (sscanf(text, "%d:%d:%d %d:%d:%d", &t.tm_year, &t.tm_mon, &t.tm_mday, &t.tm_hour, &t.tm_min, &t.tm_sec) == 6) { t.tm_year -= 1900; t.tm_mon -= 1; t.tm_isdst = -1; date = mktime(&t); } g_free(text); } cl->cd->date = date; cl->cd->have_date = TRUE; cl->done_mask |= CACHE_LOADER_DATE; cl->todo_mask &= ~CACHE_LOADER_DATE; } else { /* done, save then call done function */ if (options->thumbnails.enable_caching && cl->done_mask != CACHE_LOADER_NONE) { gchar *base; mode_t mode = 0755; base = cache_get_location(CACHE_TYPE_SIM, cl->fd->path, FALSE, &mode); if (recursive_mkdir_if_not_exists(base, mode)) { g_free(cl->cd->path); cl->cd->path = cache_get_location(CACHE_TYPE_SIM, cl->fd->path, TRUE, NULL); if (cache_sim_data_save(cl->cd)) { filetime_set(cl->cd->path, filetime(cl->fd->path)); } } g_free(base); } cl->idle_id = 0; if (cl->done_func) { cl->done_func(cl, cl->error, cl->done_data); } return FALSE; } return TRUE; }