ExifItem *item;
exif = exif_read_fd(ew->fd);
-
+
gtk_widget_set_sensitive(ew->scrolled, !!exif);
if (!exif) return;
-
+
exif_original = exif_get_original(exif);
store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(ew->listview)));
{
gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
}
-
+
gtk_tree_view_column_set_resizable(column, TRUE);
gtk_tree_view_column_set_sort_column_id(column, n);
advanced_exif_add_column(ew->listview, _("Tag"), EXIF_ADVCOL_TAG, FALSE);
advanced_exif_add_column(ew->listview, _("Format"), EXIF_ADVCOL_FORMAT, FALSE);
advanced_exif_add_column(ew->listview, _("Elements"), EXIF_ADVCOL_ELEMENTS, FALSE);
-
+
gtk_drag_source_set(ew->listview,
GDK_BUTTON1_MASK | GDK_BUTTON2_MASK,
if (!expander) return;
box = gtk_widget_get_ancestor(expander, GTK_TYPE_BOX);
if (!box) return;
-
+
gtk_container_child_get(GTK_CONTAINER(box), expander, "position", &pos, NULL);
-
+
if (single_step)
{
pos = up ? (pos - 1) : (pos + 1);
{
pos = up ? 0 : -1;
}
-
+
gtk_box_reorder_child(GTK_BOX(box), expander, pos);
}
const gchar *config;
if (!id) return;
-
+
while (pane->id)
{
if (strcmp(pane->id, id) == 0) break;
pane++;
}
if (!pane->id) return;
-
+
config = bar_pane_get_default_config(id);
if (config) load_config_from_buf(config, strlen(config), FALSE);
bar = gtk_widget_get_parent(bar);
if (!bar) return;
}
-
+
menu = popup_menu_short_lived();
if (expander)
g_object_set_data(G_OBJECT(item), "pane_add_id", pane->id);
pane++;
}
-
+
gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, bar, 0, GDK_CURRENT_TIME);
}
bd->fd = file_data_ref(fd);
gtk_container_foreach(GTK_CONTAINER(bd->vbox), bar_pane_set_fd_cb, fd);
-
+
gtk_label_set_text(GTK_LABEL(bd->label_file_name), (bd->fd) ? bd->fd->name : "");
}
BarData *bd;
GList *list, *work;
gboolean ret = FALSE;
-
+
bd = g_object_get_data(G_OBJECT(bar), "bar_data");
if (!bd) return FALSE;
list = gtk_container_get_children(GTK_CONTAINER(bd->vbox));
-
+
work = list;
while (work)
{
GtkWidget *widget = gtk_bin_get_child(GTK_BIN(work->data));
PaneData *pd = g_object_get_data(G_OBJECT(widget), "pane_data");
if (!pd) continue;
-
+
if (pd->pane_event && pd->pane_event(widget, event))
{
ret = TRUE;
BarData *bd;
GList *list, *work;
GtkWidget *ret = NULL;
-
+
if (!id || !id[0]) return NULL;
-
+
bd = g_object_get_data(G_OBJECT(bar), "bar_data");
if (!bd) return NULL;
list = gtk_container_get_children(GTK_CONTAINER(bd->vbox));
-
+
work = list;
while (work)
{
GtkWidget *widget = gtk_bin_get_child(GTK_BIN(work->data));
PaneData *pd = g_object_get_data(G_OBJECT(widget), "pane_data");
if (!pd) continue;
-
+
if (type == pd->type && strcmp(id, pd->id) == 0)
{
ret = widget;
{
BarData *bd;
GList *list, *work;
-
+
bd = g_object_get_data(G_OBJECT(bar), "bar_data");
if (!bd) return;
list = gtk_container_get_children(GTK_CONTAINER(bd->vbox));
-
+
work = list;
while (work)
{
GList *list, *work;
if (!bar) return;
-
+
bd = g_object_get_data(G_OBJECT(bar), "bar_data");
if (!bd) return;
write_bool_option(outstr, indent, "enabled", gtk_widget_get_visible(bar));
write_uint_option(outstr, indent, "width", bd->width);
WRITE_STRING(">");
-
+
indent++;
WRITE_NL(); WRITE_STRING("<clear/>");
{
PaneData *pd = g_object_get_data(G_OBJECT(pane), "pane_data");
GtkWidget *expander;
-
+
if (!pd) return;
expander = gtk_widget_get_parent(pane);
-
+
gtk_expander_set_expanded(GTK_EXPANDER(expander), pd->expanded);
}
GtkWidget *expander;
BarData *bd = g_object_get_data(G_OBJECT(bar), "bar_data");
PaneData *pd = g_object_get_data(G_OBJECT(pane), "pane_data");
-
+
if (!bd) return;
pd->lw = bd->lw;
pd->bar = bar;
-
+
expander = gtk_expander_new(NULL);
if (pd && pd->title)
{
gtk_expander_set_label_widget(GTK_EXPANDER(expander), pd->title);
gtk_widget_show(pd->title);
}
-
+
gtk_box_pack_start(GTK_BOX(bd->vbox), expander, FALSE, TRUE, 0);
-
+
g_signal_connect(expander, "button_release_event", G_CALLBACK(bar_menu_cb), bd);
-
+
gtk_container_add(GTK_CONTAINER(expander), pane);
-
+
gtk_expander_set_expanded(GTK_EXPANDER(expander), pd->expanded);
gtk_widget_show(expander);
{
const gchar *populate_id[] = {"histogram", "title", "keywords", "comment", "exif", NULL};
const gchar **id = populate_id;
-
+
while (*id)
{
const gchar *config = bar_pane_get_default_config(*id);
static void bar_size_allocate(GtkWidget *widget, GtkAllocation *allocation, gpointer data)
{
BarData *bd = data;
-
+
bd->width = allocation->width;
}
gint bar_get_width(GtkWidget *bar)
{
BarData *bd;
-
+
bd = g_object_get_data(G_OBJECT(bar), "bar_data");
if (!bd) return 0;
bd = g_new0(BarData, 1);
bd->lw = lw;
-
+
bd->widget = gtk_vbox_new(FALSE, PREF_PAD_GAP);
g_object_set_data(G_OBJECT(bd->widget), "bar_data", bd);
g_signal_connect(G_OBJECT(bd->widget), "destroy",
if (READ_BOOL_FULL("enabled", enabled)) continue;
if (READ_INT_FULL("width", width)) continue;
-
+
log_printf("unknown attribute %s = %s\n", option, value);
}
-
+
gtk_widget_set_size_request(bar, width, -1);
if (enabled)
{
gboolean bar_pane_translate_title(PaneType type, const gchar *id, gchar **title)
{
const KnownPanes *pane = known_panes;
-
+
if (!title) return FALSE;
while (pane->id)
{
pane++;
}
if (!pane->id) return FALSE;
-
+
if (*title && **title && strcmp(pane->title, *title) != 0) return FALSE;
-
+
g_free(*title);
*title = g_strdup(_(pane->title));
return TRUE;
const gchar *bar_pane_get_default_config(const gchar *id)
{
const KnownPanes *pane = known_panes;
-
+
while (pane->id)
{
if (strcmp(pane->id, id) == 0) break;
if (!pane->id) return NULL;
return pane->config;
}
-
+
/* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */
gboolean expanded;
gchar *id;
PaneType type;
-
+
/* filled in by bar */
GtkWidget *bar;
LayoutWindow *lw;
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);
list = layout_selection_list(pcd->pane.lw);
list = file_data_process_groups_in_selection(list, FALSE, NULL);
-
+
work = list;
while (work)
{
GtkTextBuffer *buffer;
pcd = g_new0(PaneCommentData, 1);
-
+
pcd->pane.pane_set_fd = bar_pane_comment_set_fd;
pcd->pane.pane_event = bar_pane_comment_event;
pcd->pane.pane_write_config = bar_pane_comment_write_config;
pcd->pane.type = PANE_COMMENT;
pcd->pane.expanded = expanded;
-
+
pcd->key = g_strdup(key);
pcd->height = height;
scrolled = gtk_scrolled_window_new(NULL, NULL);
-
+
pcd->widget = scrolled;
g_object_set_data(G_OBJECT(pcd->widget), "pane_data", pcd);
g_signal_connect(G_OBJECT(pcd->widget), "destroy",
G_CALLBACK(bar_pane_comment_destroy), pcd);
-
+
gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled), GTK_SHADOW_IN);
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled),
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
if (READ_BOOL_FULL("expanded", expanded)) continue;
if (READ_INT_FULL("height", height)) continue;
if (READ_CHAR_FULL("id", id)) continue;
-
+
log_printf("unknown attribute %s = %s\n", option, value);
}
-
+
bar_pane_translate_title(PANE_COMMENT, id, &title);
ret = bar_pane_comment_new(id, title, key, expanded, height);
g_free(title);
if (READ_BOOL_FULL("expanded", pcd->pane.expanded)) continue;
if (READ_INT_FULL("height", pcd->height)) continue;
if (READ_CHAR_FULL("id", pcd->pane.id)) continue;
-
+
log_printf("unknown attribute %s = %s\n", option, value);
}
PaneExifData *ped;
};
-
-
+
+
struct _PaneExifData
{
PaneData pane;
GtkSizeGroup *size_group;
gint min_height;
-
+
gboolean all_hidden;
gboolean show_all;
-
+
FileData *fd;
};
// gtk_widget_set_size_request(ee->value_widget, 100, -1);
gtk_misc_set_alignment(GTK_MISC(ee->value_widget), 0.0, 0.5);
}
-
+
gtk_box_pack_start(GTK_BOX(ee->box), ee->value_widget, TRUE, TRUE, 1);
gtk_widget_show(ee->value_widget);
}
static GtkWidget *bar_pane_exif_add_entry(PaneExifData *ped, const gchar *key, const gchar *title, gboolean if_set, gboolean editable)
{
ExifEntry *ee = g_new0(ExifEntry, 1);
-
+
ee->key = g_strdup(key);
if (title && title[0])
{
ee->title = exif_get_description_by_key(key);
ee->auto_title = TRUE;
}
-
+
ee->if_set = if_set;
ee->editable = editable;
-
+
ee->ped = ped;
-
+
ee->ebox = gtk_event_box_new();
g_object_set_data(G_OBJECT(ee->ebox), "entry_data", ee);
g_signal_connect_after(G_OBJECT(ee->ebox), "destroy",
G_CALLBACK(bar_pane_exif_entry_destroy), ee);
-
+
gtk_box_pack_start(GTK_BOX(ped->vbox), ee->ebox, FALSE, FALSE, 0);
bar_pane_exif_entry_dnd_init(ee->ebox);
g_signal_connect(ee->ebox, "button_release_event", G_CALLBACK(bar_pane_exif_menu_cb), ped);
-
+
bar_pane_exif_setup_entry_box(ped, ee);
-
+
bar_pane_exif_entry_update_title(ee);
bar_pane_exif_update(ped);
-
+
return ee->ebox;
}
PaneExifData *ped = g_object_get_data(G_OBJECT(pane), "pane_data");
PaneExifData *old_ped;
ExifEntry *ee = g_object_get_data(G_OBJECT(entry), "entry_data");
-
+
if (!ped || !ee) return;
-
+
old_ped = ee->ped;
-
+
g_object_ref(entry);
-
+
gtk_size_group_remove_widget(old_ped->size_group, ee->title_label);
gtk_container_remove(GTK_CONTAINER(old_ped->vbox), entry);
-
+
ee->ped = ped;
gtk_size_group_add_widget(ped->size_group, ee->title_label);
gtk_box_pack_start(GTK_BOX(ped->vbox), entry, FALSE, FALSE, 0);
{
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);
gtk_widget_show(entry);
ped->all_hidden = FALSE;
}
-
+
g_free(text);
-
+
if (update_title) bar_pane_exif_entry_update_title(ee);
}
{
GtkWidget *entry = work->data;
work = work->next;
-
+
bar_pane_exif_update_entry(ped, entry, FALSE);
}
g_list_free(list);
gtk_selection_data_set_text(selection_data, ee->key, -1);
break;
}
-
+
}
static void bar_pane_exif_dnd_receive(GtkWidget *pane, GdkDragContext *context,
GList *work, *list;
gint pos;
GtkWidget *new_entry = NULL;
-
+
ped = g_object_get_data(G_OBJECT(pane), "pane_data");
if (!ped) return;
{
case TARGET_APP_EXIF_ENTRY:
new_entry = *(gpointer *)gtk_selection_data_get_data(selection_data);
-
+
if (gtk_widget_get_parent(new_entry) && gtk_widget_get_parent(new_entry) != ped->vbox) bar_pane_exif_reparent_entry(new_entry, pane);
-
+
break;
default:
/* FIXME: this needs a check for valid exif keys */
GtkWidget *entry = work->data;
GtkAllocation allocation;
work = work->next;
-
+
if (entry == new_entry) continue;
-
+
gtk_widget_get_allocation(entry, &allocation);
-
+
if (gtk_widget_is_drawable(entry) &&
gtk_widget_translate_coordinates(pane, entry, x, y, &nx, &ny) &&
ny < allocation.height / 2) break;
static void bar_pane_exif_entry_dnd_begin(GtkWidget *entry, GdkDragContext *context, gpointer data)
{
ExifEntry *ee = g_object_get_data(G_OBJECT(entry), "entry_data");
-
+
if (!ee) return;
dnd_set_drag_label(entry, context, ee->key);
}
static void bar_pane_exif_edit_ok_cb(GenericDialog *gd, gpointer data)
{
ConfDialogData *cdd = data;
-
+
/* either one or the other */
PaneExifData *ped = g_object_get_data(G_OBJECT(cdd->widget), "pane_data");
ExifEntry *ee = g_object_get_data(G_OBJECT(cdd->widget), "entry_data");
{
const gchar *title;
GtkWidget *pane = gtk_widget_get_parent(cdd->widget);
-
+
while (pane)
{
ped = g_object_get_data(G_OBJECT(pane), "pane_data");
if (ped) break;
pane = gtk_widget_get_parent(pane);
}
-
+
if (!pane) return;
-
+
g_free(ee->key);
ee->key = g_strdup(gtk_entry_get_text(GTK_ENTRY(cdd->key_entry)));
title = gtk_entry_get_text(GTK_ENTRY(cdd->title_entry));
ee->title = g_strdup(title);
ee->auto_title = FALSE;
}
-
+
ee->if_set = cdd->if_set;
ee->editable = cdd->editable;
-
+
bar_pane_exif_setup_entry_box(ped, ee);
bar_pane_exif_entry_update_title(ee);
ExifEntry *ee = g_object_get_data(G_OBJECT(widget), "entry_data");
cdd = g_new0(ConfDialogData, 1);
-
+
cdd->widget = widget;
cdd->if_set = ee ? ee->if_set : TRUE;
cdd->editable = ee ? ee->editable : FALSE;
-
+
cdd->gd = gd = generic_dialog_new(ee ? _("Configure entry") : _("Add entry"), "exif_entry_edit",
widget, TRUE,
bar_pane_exif_edit_cancel_cb, cdd);
/* for the entry */
gchar *conf = g_strdup_printf(_("Configure \"%s\""), ee->title);
gchar *del = g_strdup_printf(_("Remove \"%s\""), ee->title);
-
+
menu_item_add_stock(menu, conf, GTK_STOCK_EDIT, G_CALLBACK(bar_pane_exif_conf_dialog_cb), widget);
menu_item_add_stock(menu, del, GTK_STOCK_DELETE, G_CALLBACK(bar_pane_exif_delete_entry_cb), widget);
menu_item_add_divider(menu);
-
+
g_free(conf);
g_free(del);
}
/* for the pane */
menu_item_add_stock(menu, _("Add entry"), GTK_STOCK_ADD, G_CALLBACK(bar_pane_exif_conf_dialog_cb), ped->widget);
menu_item_add_check(menu, _("Show hidden entries"), ped->show_all, G_CALLBACK(bar_pane_exif_toggle_show_all_cb), ped);
-
+
gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, 0, GDK_CURRENT_TIME);
}
{
PaneExifData *ped;
GList *work, *list;
-
+
ped = g_object_get_data(G_OBJECT(pane), "pane_data");
if (!ped) return;
WRITE_BOOL(ped->pane, expanded);
WRITE_STRING(">");
indent++;
-
+
list = gtk_container_get_children(GTK_CONTAINER(ped->vbox));
work = list;
while (work)
{
GtkWidget *entry = work->data;
work = work->next;
-
+
bar_pane_exif_entry_write_config(entry, outstr, indent);
}
g_list_free(list);
#endif
g_signal_connect(G_OBJECT(ped->widget), "size-allocate",
G_CALLBACK(bar_pane_exif_size_allocate), ped);
-
+
bar_pane_exif_dnd_init(ped->widget);
g_signal_connect(ped->widget, "button_release_event", G_CALLBACK(bar_pane_exif_menu_cb), ped);
log_printf("unknown attribute %s = %s\n", option, value);
}
-
+
bar_pane_translate_title(PANE_EXIF, id, &title);
ret = bar_pane_exif_new(id, title, expanded);
g_free(title);
if (READ_CHAR_FULL("title", title)) continue;
if (READ_BOOL_FULL("expanded", ped->pane.expanded)) continue;
if (READ_CHAR_FULL("id", ped->pane.id)) continue;
-
+
log_printf("unknown attribute %s = %s\n", option, value);
}
if (READ_CHAR_FULL("title", title)) continue;
if (READ_BOOL_FULL("if_set", if_set)) continue;
if (READ_BOOL_FULL("editable", editable)) continue;
-
+
log_printf("unknown attribute %s = %s\n", option, value);
}
-
+
if (key && key[0]) bar_pane_exif_add_entry(ped, key, title, if_set, editable);
}
clutter_actor_destroy(CLUTTER_ACTOR(current_image));
champlain_label_set_image(CHAMPLAIN_LABEL(marker), NULL);
}
-
+
current_text = g_strdup(champlain_label_get_text(CHAMPLAIN_LABEL(marker)));
/* If the marker is showing only the text character, replace it with a
default:
rotate = GDK_PIXBUF_ROTATE_NONE;
}
-
+
gtk_clutter_texture_set_from_pixbuf(GTK_CLUTTER_TEXTURE(actor),
gdk_pixbuf_rotate_simple(gdk_pixbuf_scale_simple(fd->pixbuf, THUMB_SIZE, height * THUMB_SIZE / width,
GDK_INTERP_NEAREST), rotate), 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_free(current_text);
-
+
return TRUE;
}
return TRUE;
gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(pgd->progress),
(gdouble)(pgd->selection_count - g_list_length(pgd->not_added)) /
(gdouble)pgd->selection_count);
-
+
message = g_string_new("");
g_string_printf(message, "%i/%i", (pgd->selection_count - g_list_length(pgd->not_added)),
pgd->selection_count);
gtk_progress_bar_set_text(GTK_PROGRESS_BAR(pgd->progress), message->str);
g_string_free(message, TRUE);
-
+
if(pgd->not_added)
{
fd = pgd->not_added->data;
if ((latitude != 1000) && (longitude != 1000))
{
pgd->num_added++;
-
+
marker = champlain_label_new_with_text("i","courier 5", &marker_colour, &marker_colour);
champlain_location_set_location(CHAMPLAIN_LOCATION(marker), latitude, longitude);
}
return TRUE;
}
-
+
if (pgd->centre_map_checked)
{
if (pgd->num_added == 1)
/* Delete any markers currently displayed
*/
-
+
champlain_marker_layer_remove_all(pgd->icon_layer);
if (!pgd->enable_markers_checked)
*/
filelist_free(pgd->selection_list);
if (pgd->bbox) champlain_bounding_box_free(pgd->bbox);
-
+
list = layout_selection_list(pgd->pane.lw);
list = file_data_process_groups_in_selection(list, FALSE, NULL);
{
gtk_label_set_text(GTK_LABEL(pgd->state), message->str);
}
-
+
gtk_widget_set_tooltip_text(GTK_WIDGET(pgd->slider), message->str);
gtk_scale_button_set_value(GTK_SCALE_BUTTON(pgd->slider), (gdouble)zoom);
static void bar_pane_gps_notify_cb(FileData *fd, NotifyType type, gpointer data)
{
PaneGPSData *pgd = data;
-
+
if ((type & (NOTIFY_REREAD | NOTIFY_CHANGE | NOTIFY_METADATA)) &&
g_list_find(pgd->selection_list, fd))
{
while (map_list)
{
map_desc = (ChamplainMapSourceDesc *)(map_list->data);
-
+
menu_item_add_radio(menu,
champlain_map_source_desc_get_name(map_desc),
(gpointer)champlain_map_source_desc_get_id(map_desc),
strcmp(champlain_map_source_desc_get_id(map_desc), current) == 0,
G_CALLBACK(bar_pane_gps_change_map_cb), pgd);
-
+
map_list = g_slist_next(map_list);
}
-
+
menu_item_add_divider(menu);
menu_item_add_check(menu, _("Enable markers"), pgd->enable_markers_checked,
G_CALLBACK(bar_pane_gps_enable_markers_checked_toggle_cb), pgd);
message = g_string_append(message, _("Move map centre to marker\n is enabled"));
pgd->centre_map_checked = TRUE;
}
-
+
dialog = gtk_message_dialog_new(NULL,
GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_INFO,
gtk_window_set_title(GTK_WINDOW(dialog), _("Map Centreing"));
gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_MOUSE);
gtk_dialog_run(GTK_DIALOG(dialog));
-
+
gtk_widget_destroy(dialog);
g_string_free(message, TRUE);
}
progress = gtk_progress_bar_new();
state = gtk_label_new("");
gtk_label_set_justify(GTK_LABEL(state), GTK_JUSTIFY_CENTER);
-
+
gtk_box_pack_start(GTK_BOX(status), GTK_WIDGET(slider), FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(status), GTK_WIDGET(state), FALSE, FALSE, 5);
gtk_box_pack_end(GTK_BOX(status), GTK_WIDGET(progress), FALSE, FALSE, 0);
gtk_box_pack_end(GTK_BOX(vbox),GTK_WIDGET(status), FALSE, FALSE, 0);
-
+
layer = champlain_marker_layer_new();
champlain_view_add_layer(view, CHAMPLAIN_LAYER(layer));
pgd->state = state;
bar_pane_gps_set_map_source(pgd, map_id);
-
+
g_object_set(G_OBJECT(view), "kinetic-mode", TRUE,
"zoom-level", zoom,
"keep-center-on-resize", TRUE,
pgd->create_markers_id = 0;
pgd->enable_markers_checked = TRUE;
pgd->centre_map_checked = TRUE;
-
+
return pgd->widget;
}
phd->idle_id = 0;
phd->need_update = FALSE;
-
+
gtk_widget_queue_draw_area(GTK_WIDGET(phd->drawing_area), 0, 0, phd->histogram_width, phd->histogram_height);
-
+
if (phd->fd == NULL) return FALSE;
histmap = histmap_get(phd->fd);
-
+
if (!histmap)
{
histmap_start_idle(phd->fd);
return FALSE;
}
-
+
phd->pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, phd->histogram_width, phd->histogram_height);
gdk_pixbuf_fill(phd->pixbuf, 0xffffffff);
histogram_draw(phd->histogram, histmap, phd->pixbuf, 0, 0, phd->histogram_width, phd->histogram_height);
{
PaneHistogramData *phd = data;
if (!phd) return TRUE;
-
+
if (phd->need_update)
{
bar_pane_histogram_update(phd);
}
-
+
if (!phd->pixbuf) return TRUE;
-
+
gdk_cairo_set_source_pixbuf(cr, phd->pixbuf, 0, 0);
cairo_paint (cr);
{
PaneHistogramData *phd = data;
if (!phd) return TRUE;
-
+
if (phd->need_update)
{
bar_pane_histogram_update(phd);
}
-
+
if (!phd->pixbuf) return TRUE;
-
+
cairo_t *cr = gdk_cairo_create(gtk_widget_get_window(widget));
gdk_cairo_set_source_pixbuf (cr, phd->pixbuf, 0, 0);
cairo_paint (cr);
static void bar_pane_histogram_destroy(GtkWidget *widget, gpointer data)
{
PaneHistogramData *phd = data;
-
+
if (phd->idle_id) g_source_remove(phd->idle_id);
file_data_unregister_notify_func(bar_pane_histogram_notify_cb, phd);
{
PaneHistogramData *phd = data;
gint logmode;
-
+
if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget))) return;
if (!phd) return;
menu_item_add_radio(menu, _("Histogram on _Blue"), GINT_TO_POINTER(HCHAN_B), (channel == HCHAN_B), G_CALLBACK(bar_pane_histogram_popup_channels_cb), phd);
menu_item_add_radio(menu, _("_Histogram on RGB"), GINT_TO_POINTER(HCHAN_RGB), (channel == HCHAN_RGB), G_CALLBACK(bar_pane_histogram_popup_channels_cb), phd);
menu_item_add_radio(menu, _("Histogram on _Value"), GINT_TO_POINTER(HCHAN_MAX), (channel == HCHAN_MAX), G_CALLBACK(bar_pane_histogram_popup_channels_cb), phd);
-
+
menu_item_add_divider(menu);
-
+
menu_item_add_radio(menu, _("Li_near Histogram"), GINT_TO_POINTER(0), (mode == 0), G_CALLBACK(bar_pane_histogram_popup_mode_cb), phd);
menu_item_add_radio(menu, _("L_og Histogram"), GINT_TO_POINTER(1), (mode == 1), G_CALLBACK(bar_pane_histogram_popup_mode_cb), phd);
PaneHistogramData *phd;
phd = g_new0(PaneHistogramData, 1);
-
+
phd->pane.pane_set_fd = bar_pane_histogram_set_fd;
phd->pane.pane_write_config = bar_pane_histogram_write_config;
phd->pane.title = bar_pane_expander_title(title);
phd->pane.type = PANE_HISTOGRAM;
phd->pane.expanded = expanded;
-
+
phd->histogram = histogram_new();
histogram_set_channel(phd->histogram, histogram_channel);
g_object_set_data(G_OBJECT(phd->widget), "pane_data", phd);
g_signal_connect(G_OBJECT(phd->widget), "destroy",
G_CALLBACK(bar_pane_histogram_destroy), phd);
-
+
gtk_widget_set_size_request(GTK_WIDGET(phd->widget), -1, height);
g_signal_connect(G_OBJECT(phd->drawing_area), "expose_event",
G_CALLBACK(bar_pane_histogram_expose_event_cb), phd);
#endif
-
+
gtk_box_pack_start(GTK_BOX(phd->widget), phd->drawing_area, TRUE, TRUE, 0);
gtk_widget_show(phd->drawing_area);
gtk_widget_add_events(phd->drawing_area, GDK_BUTTON_PRESS_MASK);
log_printf("unknown attribute %s = %s\n", option, value);
}
-
+
bar_pane_translate_title(PANE_HISTOGRAM, id, &title);
ret = bar_pane_histogram_new(id, title, height, expanded, histogram_channel, histogram_mode);
g_free(title);
if (READ_BOOL_FULL("expanded", phd->pane.expanded)) continue;
if (READ_INT_FULL("histogram_channel", histogram_channel)) continue;
if (READ_INT_FULL("histogram_mode", histogram_mode)) continue;
-
+
log_printf("unknown attribute %s = %s\n", option, value);
}
-
+
histogram_set_channel(phd->histogram, histogram_channel);
histogram_set_mode(phd->histogram, histogram_mode);
{
PaneKeywordsData *pkd;
GtkTreePath *click_tpath;
-
+
/* dialog parts */
GenericDialog *gd;
GtkWidget *edit_widget;
gboolean is_keyword;
-
+
gboolean edit_existing;
};
gboolean set;
gtk_tree_model_get(model, iter, FILTER_KEYWORD_COLUMN_TOGGLE, &set, -1);
-
+
if (set && !gtk_tree_view_row_expanded(GTK_TREE_VIEW(pkd->keyword_treeview), path))
{
gtk_tree_view_expand_to_path(GTK_TREE_VIEW(pkd->keyword_treeview), path);
gboolean set;
gtk_tree_model_get(model, iter, FILTER_KEYWORD_COLUMN_TOGGLE, &set, -1);
-
+
if (!set && gtk_tree_view_row_expanded(GTK_TREE_VIEW(pkd->keyword_treeview), path))
{
gtk_tree_view_collapse_row(GTK_TREE_VIEW(pkd->keyword_treeview), path);
/* compare the lists */
work1 = keywords;
work2 = orig_keywords;
-
+
while (work1 && work2)
{
if (strcmp(work1->data, work2->data) != 0) break;
work1 = work1->next;
work2 = work2->next;
}
-
+
if (work1 || work2) /* lists differs */
{
g_signal_handlers_block_by_func(keyword_buffer, bar_pane_keywords_changed, pkd);
GList *list;
GtkTreeIter child_iter;
GtkTreeModel *keyword_tree;
-
+
GtkTextBuffer *keyword_buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(pkd->keyword_view));
model = gtk_tree_view_get_model(GTK_TREE_VIEW(pkd->keyword_treeview));
keyword_tree_set(keyword_tree, &child_iter, &list);
else
keyword_tree_reset(keyword_tree, &child_iter, &list);
-
+
g_signal_handlers_block_by_func(keyword_buffer, bar_pane_keywords_changed, pkd);
keyword_list_push(pkd->keyword_view, list);
string_list_free(list);
GtkTreeIter child_iter;
gtk_tree_model_filter_convert_iter_to_child_iter(GTK_TREE_MODEL_FILTER(model), &child_iter, iter);
-
+
memset(value, 0, sizeof (GValue));
switch (column)
GList *keywords = keyword_list_pull(pkd->keyword_view);
gboolean set = keyword_tree_is_set(keyword_tree, &child_iter, keywords);
string_list_free(keywords);
-
+
g_value_init(value, G_TYPE_BOOLEAN);
g_value_set_boolean(value, set);
break;
gboolean bar_pane_keywords_filter_visible(GtkTreeModel *keyword_tree, GtkTreeIter *iter, gpointer data)
{
GtkTreeModel *filter = data;
-
+
return !keyword_is_hidden_in(keyword_tree, iter, filter);
}
list = layout_selection_list(pkd->pane.lw);
list = file_data_process_groups_in_selection(list, FALSE, NULL);
-
+
work = list;
while (work)
{
{
gchar *src_name;
GtkTreeIter parent;
-
+
if (dest_kw_iter && keyword_same_parent(keyword_tree, src_kw_iter, dest_kw_iter))
{
return TRUE; /* reordering of siblings is ok */
/* the keywords can't be added if the same name already exist */
return;
}
-
+
switch (pos)
{
case GTK_TREE_VIEW_DROP_INTO_OR_BEFORE:
break;
}
}
-
+
}
else
{
}
gtk_tree_store_append(GTK_TREE_STORE(keyword_tree), &new_kw_iter, NULL);
}
-
-
+
+
if (src_valid)
{
keyword_move_recursive(GTK_TREE_STORE(keyword_tree), &new_kw_iter, &src_kw_iter);
}
-
+
work = new_keywords;
while (work)
{
gtk_tree_model_get_iter(model, &dest_iter, tpath);
if (pos == GTK_TREE_VIEW_DROP_INTO_OR_BEFORE && gtk_tree_model_iter_has_child(model, &dest_iter))
pos = GTK_TREE_VIEW_DROP_BEFORE;
-
+
if (pos == GTK_TREE_VIEW_DROP_INTO_OR_AFTER && gtk_tree_model_iter_has_child(model, &dest_iter))
pos = GTK_TREE_VIEW_DROP_AFTER;
}
gtk_tree_view_set_drag_dest_row(GTK_TREE_VIEW(tree_view), tpath, pos);
gtk_tree_path_free(tpath);
-
+
if (tree_view == gtk_drag_get_source_widget(context))
gdk_drag_status(context, GDK_ACTION_MOVE, time);
else
gdk_drag_status(context, GDK_ACTION_COPY, time);
-
+
return TRUE;
}
GtkTreeModel *keyword_tree;
GtkTreeIter kw_iter;
-
+
gboolean have_dest = FALSE;
-
+
GList *keywords;
model = gtk_tree_view_get_model(GTK_TREE_VIEW(pkd->keyword_treeview));
keyword_tree = gtk_tree_model_filter_get_model(GTK_TREE_MODEL_FILTER(model));
-
+
if (cdd->click_tpath)
{
GtkTreeIter iter;
have_dest = TRUE;
}
}
-
+
if (cdd->edit_existing && !have_dest) return;
-
+
keywords = keyword_list_pull(cdd->edit_widget);
-
+
if (cdd->edit_existing)
{
if (keywords && keywords->data && /* there should be one keyword */
GtkWidget *table;
GtkWidget *group;
GtkWidget *button;
-
+
gchar *name = NULL;
gboolean is_keyword = TRUE;
-
+
if (edit_existing && pkd->click_tpath)
{
return;
}
}
-
+
if (edit_existing && !name) return;
-
+
cdd = g_new0(ConfDialogData, 1);
cdd->pkd =pkd;
model = gtk_tree_view_get_model(GTK_TREE_VIEW(pkd->keyword_treeview));
keyword_tree = gtk_tree_model_filter_get_model(GTK_TREE_MODEL_FILTER(model));
-
+
if (!pkd->click_tpath) return;
if (!gtk_tree_model_get_iter(model, &iter, pkd->click_tpath)) return;
if (!gtk_tree_model_get_iter(model, &iter, pkd->click_tpath)) return;
gtk_tree_model_filter_convert_iter_to_child_iter(GTK_TREE_MODEL_FILTER(model), &kw_iter, &iter);
-
+
keyword_delete(GTK_TREE_STORE(keyword_tree), &kw_iter);
}
if (!gtk_tree_model_get_iter(model, &iter, pkd->click_tpath)) return;
gtk_tree_model_filter_convert_iter_to_child_iter(GTK_TREE_MODEL_FILTER(model), &kw_iter, &iter);
-
+
keyword_hide_in(GTK_TREE_STORE(keyword_tree), &kw_iter, model);
}
keyword_tree = gtk_tree_model_filter_get_model(GTK_TREE_MODEL_FILTER(model));
keyword_show_all_in(GTK_TREE_STORE(keyword_tree), model);
-
+
if (!pkd->collapse_unchecked) gtk_tree_view_expand_all(GTK_TREE_VIEW(pkd->keyword_treeview));
bar_keyword_tree_sync(pkd);
}
GtkTreeModel *keyword_tree;
GList *keywords;
-
+
model = gtk_tree_view_get_model(GTK_TREE_VIEW(pkd->keyword_treeview));
keyword_tree = gtk_tree_model_filter_get_model(GTK_TREE_MODEL_FILTER(model));
GtkWidget *item;
GtkWidget *submenu;
GtkTreeViewDropPosition pos;
-
+
if (pkd->click_tpath) gtk_tree_path_free(pkd->click_tpath);
pkd->click_tpath = NULL;
gtk_tree_view_get_dest_row_at_pos(GTK_TREE_VIEW(pkd->keyword_treeview), x, y, &pkd->click_tpath, &pos);
menu = popup_menu_short_lived();
menu_item_add_stock(menu, _("Add keyword"), GTK_STOCK_EDIT, G_CALLBACK(bar_pane_keywords_add_dialog_cb), pkd);
-
+
menu_item_add_divider(menu);
menu_item_add(menu, _("Add keyword to all selected images"), G_CALLBACK(bar_pane_keywords_add_to_selected_cb), pkd);
gchar *text;
gchar *mark;
gint i;
-
+
GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(pkd->keyword_treeview));
-
+
GtkTreeIter iter;
gtk_tree_model_get_iter(model, &iter, pkd->click_tpath);
gchar *name;
-
+
gtk_tree_model_get(model, &iter, FILTER_KEYWORD_COLUMN_NAME, &name,
FILTER_KEYWORD_COLUMN_MARK, &mark, -1);
-
+
text = g_strdup_printf(_("Hide \"%s\""), name);
menu_item_add_stock(menu, text, GTK_STOCK_EDIT, G_CALLBACK(bar_pane_keywords_hide_cb), pkd);
g_free(text);
-
+
submenu = gtk_menu_new();
for (i = 0; i < FILEDATA_MARKS_SIZE; i++)
{
menu_item_add_stock(menu, text, GTK_STOCK_DELETE, G_CALLBACK(bar_pane_keywords_delete_cb), pkd);
g_free(text);
-
+
if (mark && mark[0])
{
text = g_strdup_printf(_("Disconnect \"%s\" from mark %s"), name, mark);
pkd = g_object_get_data(G_OBJECT(bar), "pane_data");
if (!pkd) return;
-
+
g_free(pkd->pane.id);
gtk_widget_destroy(pkd->widget);
}
pkd->pane.expanded = expanded;
pkd->key = g_strdup(key);
-
+
pkd->expand_checked = TRUE;
-
+
hbox = gtk_hbox_new(FALSE, PREF_PAD_GAP);
pkd->widget = hbox;
pkd->keyword_treeview = gtk_tree_view_new_with_model(store);
g_object_unref(store);
-
+
gtk_widget_set_size_request(pkd->keyword_treeview, -1, 400);
gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(pkd->keyword_treeview), FALSE);
GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_HIGHLIGHT | GTK_DEST_DEFAULT_DROP,
bar_pane_keywords_drop_types, n_keywords_drop_types,
GDK_ACTION_COPY | GDK_ACTION_MOVE);
-
+
g_signal_connect(G_OBJECT(pkd->keyword_treeview), "drag_data_received",
G_CALLBACK(bar_pane_keywords_dnd_receive), pkd);
g_signal_connect(G_OBJECT(pkd->keyword_treeview), "button_release_event",
G_CALLBACK(bar_pane_keywords_menu_cb), pkd);
-
+
gtk_container_add(GTK_CONTAINER(scrolled), pkd->keyword_treeview);
gtk_widget_show(pkd->keyword_treeview);
if (READ_CHAR_FULL("title", title)) continue;
if (READ_CHAR_FULL("key", key)) continue;
if (READ_BOOL_FULL("expanded", expanded)) continue;
-
+
log_printf("unknown attribute %s = %s\n", option, value);
}
-
+
bar_pane_translate_title(PANE_KEYWORDS, id, &title);
ret = bar_pane_keywords_new(id, title, key, expanded);
g_free(id);
if (READ_CHAR_FULL("key", pkd->key)) continue;
if (READ_BOOL_FULL("expanded", pkd->pane.expanded)) continue;
if (READ_CHAR_FULL("id", pkd->pane.id)) continue;
-
+
log_printf("unknown attribute %s = %s\n", option, value);
}
SortModeType mode;
SortActionType action;
gchar *filter_key;
-
+
SortSelectionType selection;
GtkWidget *folder_group;
sd->lw = lw;
sd->action = action;
-
+
if (sd->action == BAR_SORT_FILTER && (!filter_key || !filter_key[0]))
{
sd->action = BAR_SORT_COPY;
}
-
+
sd->selection = selection;
sd->undo_src = NULL;
sd->undo_dest = NULL;
gboolean select = FALSE;
work = work->next;
-
+
if (!editor_is_filter(editor->key)) continue;
-
+
key = g_strdup(editor->key);
if (sd->action == BAR_SORT_FILTER && strcmp(key, filter_key) == 0)
{
select = TRUE;
have_filter = TRUE;
}
-
+
button = pref_radiobutton_new(sd->folder_group, buttongrp,
editor->name, select,
G_CALLBACK(bar_sort_set_filter_cb), sd);
g_object_set_data_full(G_OBJECT(button), "filter_key", key, bar_sort_edit_button_free);
}
g_list_free(editors_list);
-
+
if (sd->action == BAR_SORT_FILTER && !have_filter) sd->action = BAR_SORT_COPY;
sd->collection_group = pref_box_new(sd->vbox, FALSE, GTK_ORIENTATION_VERTICAL, 0);
GtkWidget *bar_sort_new_from_config(LayoutWindow *lw, const gchar **attribute_names, const gchar **attribute_values)
{
GtkWidget *bar;
-
+
gboolean enabled = TRUE;
gint action = 0;
gint mode = 0;
guint8 *avg_g = &cd->sim->avg_g[s];
guint8 *avg_b = &cd->sim->avg_b[s];
guint n = 0;
-
+
for (x = 0; x < 32; x++)
{
buf[n++] = avg_r[x];
path = g_build_filename(base, cache_local, name, NULL);
g_free(name);
g_free(base);
-
+
return path;
}
void cache_notify_cb(FileData *fd, NotifyType type, gpointer data)
{
if (!(type & NOTIFY_CHANGE) || !fd->change) return;
-
+
DEBUG_1("Notify cache_maint: %s %04x", fd->path, type);
switch (fd->change->type)
{
label = pref_label_new(group, buf);
g_free(buf);
gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
-
+
return label;
}
gint calc_height;
gint xpad, ypad;
gfloat xalign, yalign;
-
+
gtk_cell_renderer_get_padding(cell, &xpad, &ypad);
gtk_cell_renderer_get_alignment(cell, &xalign, &yalign);
GdkRectangle cell_rect;
GtkStateType state;
gint xpad, ypad;
-
+
pixbuf = cellicon->pixbuf;
text = cellicon->text;
pix_rect.height = text_rect.height;
pix_rect.x = cell_area->x + xpad + (cell_rect.width - text_rect.width + 1) / 2;
pix_rect.y = cell_area->y + ypad + (cell_rect.height - text_rect.height);
-
+
if (cellicon->show_marks)
{
pix_rect.y -= TOGGLE_SPACING;
pix_rect.height = TOGGLE_SPACING;
pix_rect.x = cell_area->x + xpad + (cell_rect.width - pix_rect.width + 1) / 2 + (TOGGLE_SPACING - TOGGLE_WIDTH) / 2;
pix_rect.y = cell_area->y + ypad + (cell_rect.height - pix_rect.height) + (TOGGLE_SPACING - TOGGLE_WIDTH) / 2;
-
+
if (gdk_rectangle_intersect(cell_area, &pix_rect, &draw_rect)
#if !GTK_CHECK_VERSION(3,0,0)
&& gdk_rectangle_intersect(expose_area, &draw_rect, &draw_rect)
gint xpad, ypad;
gtk_cell_renderer_get_padding(cell, &xpad, &ypad);
-
+
gqv_cell_renderer_icon_get_size(cell, widget, cell_area,
&cell_rect.x, &cell_rect.y,
&cell_rect.width, &cell_rect.height);
for (i = 0; i < cellicon->num_marks; i++)
{
rect.x = cell_area->x + xpad + (cell_rect.width - TOGGLE_SPACING * cellicon->num_marks + 1) / 2 + i * TOGGLE_SPACING;
-
+
if (bevent->x >= rect.x && bevent->x < rect.x + rect.width &&
bevent->y >= rect.y && bevent->y < rect.y + rect.height)
{
gboolean background_set;
gint num_marks;
-
+
gboolean show_text;
gboolean show_marks;
-
+
guint marks;
guint toggled_mark;
-
+
};
struct _GQvCellRendererIconClass
static void collect_manager_process_actions(gint max)
{
if (collection_manager_action_list) DEBUG_1("collection manager processing actions");
-
+
while (collection_manager_action_list != NULL && max > 0)
{
CollectManagerAction *action;
void collect_manager_notify_cb(FileData *fd, NotifyType type, gpointer data)
{
if (!(type & NOTIFY_CHANGE) || !fd->change) return;
-
+
DEBUG_1("Notify collect_manager: %s %04x", fd->path, type);
switch (fd->change->type)
{
gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), submenu);
menu_item_add_divider(menu);
-
+
ct->editmenu_fd_list = collection_table_selection_get_list(ct);
submenu_add_edit(menu, &item,
G_CALLBACK(collection_table_popup_edit_cb), ct, ct->editmenu_fd_list);
gint i;
ct = g_new0(CollectTable, 1);
-
+
ct->cd = cd;
ct->show_text = options->show_icon_names;
collection_list = g_list_append(collection_list, cd);
-
+
return cd;
}
collection_load_stop(cd);
collection_list_free(cd->list);
-
+
file_data_unregister_notify_func(collection_notify_cb, cd);
collection_list = g_list_remove(collection_list, cd);
if (info_list) *info_list = NULL;
if (strncmp(data, "COLLECTION:", 11) != 0) return NULL;
-
+
ptr = data + 11;
-
+
collection_number = atoi(ptr);
cd = collection_from_number(collection_number);
if (!cd) return NULL;
if (!list && !info_list) return cd;
-
+
while (*ptr != '\0' && *ptr != '\n' ) ptr++;
if (*ptr == '\0') return cd;
ptr++;
{
guint item_number;
CollectInfo *info;
-
+
item_number = (guint) atoi(ptr);
while (*ptr != '\n' && *ptr != '\0') ptr++;
if (*ptr == '\0')
if (list) *list = g_list_append(*list, file_data_ref(info->fd));
if (info_list) *info_list = g_list_append(*info_list, info);
}
-
+
return cd;
}
work = work->next;
if (item_number < 0) continue;
-
+
text = g_strdup_printf("%d\n", item_number);
temp = g_list_prepend(temp, text);
*length += strlen(text);
if (!(type & NOTIFY_CHANGE) || !fd->change) return;
DEBUG_1("Notify collection: %s %04x", fd->path, type);
-
+
switch (fd->change->type)
{
case FILEDATA_CHANGE_MOVE:
GError *error = NULL;
gboolean ret = TRUE;
const gchar *name = gtk_entry_get_text(GTK_ENTRY(ew->entry));
-
+
if (!name || !name[0])
{
file_util_warning_dialog(_("Can't save"), _("Please specify file name."), GTK_STOCK_DIALOG_ERROR, NULL);
return FALSE;
}
-
+
gtk_text_buffer_get_bounds(ew->buffer, &start, &end);
text = gtk_text_buffer_get_text(ew->buffer, &start, &end, FALSE);
g_error_free(error);
ret = FALSE;
}
-
+
g_free(path);
g_free(dir);
g_free(text);
static void editor_window_text_modified_cb(GtkWidget *widget, gpointer data)
{
EditorWindow *ew = data;
-
+
if (gtk_text_buffer_get_modified(ew->buffer))
{
gtk_widget_set_sensitive(ew->save_button, TRUE);
{
modified = strcmp(ew->desktop_name, content);
}
-
+
gtk_widget_set_sensitive(ew->save_button, modified);
ew->modified = modified;
}
ewdl = g_new(EditorWindowDel_Data, 1);
ewdl->ewl = ewl;
ewdl->path = path;
-
+
if (ewl->gd)
{
GenericDialog *gd = ewl->gd;
gtk_tree_model_get(store, &iter,
DESKTOP_FILE_COLUMN_PATH, &path,
-1);
-
+
gtk_widget_set_sensitive(ewl->delete_button, access_file(path, W_OK));
gtk_widget_set_sensitive(ewl->edit_button, TRUE);
g_free(path);
}
-
+
}
static gint editor_list_window_sort_cb(GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer data)
g_free(s2);
}
break;
-
+
default:
g_return_val_if_reached(0);
}
EditorListWindow *ewl;
editor_list_window = ewl = g_new0(EditorListWindow, 1);
-
+
ewl->window = window_new(GTK_WINDOW_TOPLEVEL, "editors", PIXBUF_INLINE_ICON_CONFIG, NULL, _("Editors"));
gtk_window_set_type_hint(GTK_WINDOW(ewl->window), GDK_WINDOW_TYPE_HINT_DIALOG);
g_signal_connect(G_OBJECT(ewl->window), "delete_event",
menu_item_add_sensitive(menu, _("Select group _2 duplicates"), (dw->dupes != NULL),
G_CALLBACK(dupe_menu_select_dupes_set2_cb), dw);
menu_item_add_divider(menu);
-
+
editmenu_fd_list = dupe_window_get_fd_list(dw);
g_signal_connect(G_OBJECT(menu), "destroy",
G_CALLBACK(dupe_menu_popup_destroy_cb), editmenu_fd_list);
if (!(type & NOTIFY_CHANGE) || !fd->change) return;
DEBUG_1("Notify dupe: %s %04x", fd->path, type);
-
+
switch (fd->change->type)
{
case FILEDATA_CHANGE_MOVE:
void editor_description_free(EditorDescription *editor)
{
if (!editor) return;
-
+
g_free(editor->key);
g_free(editor->name);
g_free(editor->icon);
static GList *editor_mime_types_to_extensions(gchar **mime_types)
{
/* FIXME: this should be rewritten to use the shared mime database, as soon as we switch to gio */
-
+
static const gchar *conv_table[][2] = {
{"application/x-ufraw", ".ufraw"},
{"image/*", "*"},
{"image/x-x3f", ".x3f"},
{"application/x-ptoptimizer-script", ".pto"},
{NULL, NULL}};
-
+
gint i, j;
GList *list = NULL;
-
+
for (i = 0; mime_types[i]; i++)
for (j = 0; conv_table[j][0]; j++)
if (strcmp(mime_types[i], conv_table[j][0]) == 0)
list = g_list_concat(list, filter_to_list(conv_table[j][1]));
-
+
return list;
}
gboolean category_geeqie = FALSE;
if (g_hash_table_lookup(editors, key)) return FALSE; /* the file found earlier wins */
-
+
key_file = g_key_file_new();
if (!g_key_file_load_from_file(key_file, path, 0, NULL))
{
return FALSE;
}
g_free(type);
-
+
editor = g_new0(EditorDescription, 1);
-
+
editor->key = g_strdup(key);
editor->file = g_strdup(path);
if (found) editor->ignored = TRUE;
g_strfreev(not_show_in);
}
-
-
+
+
try_exec = g_key_file_get_string(key_file, DESKTOP_GROUP, "TryExec", NULL);
if (try_exec && !editor->hidden && !editor->ignored)
{
g_key_file_free(key_file);
return TRUE;
}
-
+
editor->name = g_key_file_get_locale_string(key_file, DESKTOP_GROUP, "Name", NULL, NULL);
editor->icon = g_key_file_get_string(key_file, DESKTOP_GROUP, "Icon", NULL);
-
+
/* Icon key can be either a full path (absolute with file name extension) or an icon name (without extension) */
if (editor->icon && !g_path_is_absolute(editor->icon))
{
gchar *ext = strrchr(editor->icon, '.');
-
+
if (ext && strlen(ext) == 4 &&
(!strcmp(ext, ".png") || !strcmp(ext, ".xpm") || !strcmp(ext, ".svg")))
{
log_printf(_("Desktop file '%s' should not include extension in Icon key: '%s'\n"),
editor->file, editor->icon);
-
+
// drop extension
*ext = '\0';
}
}
editor->exec = g_key_file_get_string(key_file, DESKTOP_GROUP, "Exec", NULL);
-
+
editor->menu_path = g_key_file_get_string(key_file, DESKTOP_GROUP, "X-Geeqie-Menu-Path", NULL);
if (!editor->menu_path) editor->menu_path = g_strdup("EditMenu/ExternalMenu");
-
+
editor->hotkey = g_key_file_get_string(key_file, DESKTOP_GROUP, "X-Geeqie-Hotkey", NULL);
editor->comment = g_key_file_get_string(key_file, DESKTOP_GROUP, "Comment", NULL);
if (!editor->ext_list) editor->hidden = TRUE;
}
}
-
+
if (g_key_file_get_boolean(key_file, DESKTOP_GROUP, "X-Geeqie-Keep-Fullscreen", NULL)) editor->flags |= EDITOR_KEEP_FS;
if (g_key_file_get_boolean(key_file, DESKTOP_GROUP, "X-Geeqie-Verbose", NULL)) editor->flags |= EDITOR_VERBOSE;
if (g_key_file_get_boolean(key_file, DESKTOP_GROUP, "X-Geeqie-Verbose-Multi", NULL)) editor->flags |= EDITOR_VERBOSE_MULTI;
if (g_key_file_get_boolean(key_file, DESKTOP_GROUP, "X-Geeqie-Filter", NULL)) editor->flags |= EDITOR_DEST;
if (g_key_file_get_boolean(key_file, DESKTOP_GROUP, "Terminal", NULL)) editor->flags |= EDITOR_TERMINAL;
-
+
editor->flags |= editor_command_parse(editor, NULL, FALSE, NULL);
if ((editor->flags & EDITOR_NO_PARAM) && !category_geeqie) editor->hidden = TRUE;
g_key_file_free(key_file);
if (editor->ignored) return TRUE;
-
+
gtk_list_store_append(desktop_file_list, &iter);
gtk_list_store_set(desktop_file_list, &iter,
DESKTOP_FILE_COLUMN_KEY, key,
DESKTOP_FILE_COLUMN_HIDDEN, editor->hidden ? _("yes") : _("no"),
DESKTOP_FILE_COLUMN_WRITABLE, access_file(path, W_OK),
DESKTOP_FILE_COLUMN_PATH, path, -1);
-
+
return TRUE;
}
while ((dir = readdir(dp)) != NULL)
{
gchar *namel = dir->d_name;
-
+
if (g_str_has_suffix(namel, ".desktop"))
{
gchar *name = path_to_utf8(namel);
gchar **split_dirs;
gint i;
GList *list = NULL;
-
+
xdg_data_dirs = getenv("XDG_DATA_DIRS");
if (xdg_data_dirs && xdg_data_dirs[0])
xdg_data_dirs = path_to_utf8(xdg_data_dirs);
else
xdg_data_dirs = g_strdup("/usr/share");
-
+
all_dirs = g_strconcat(get_rc_dir(), ":", GQ_APP_DIR, ":", xdg_data_home_get(), ":", xdg_data_dirs, NULL);
-
+
g_free(xdg_data_dirs);
split_dirs = g_strsplit(all_dirs, ":", 0);
-
+
g_free(all_dirs);
for (i = 0; split_dirs[i]; i++);
list = editor_add_desktop_dir(list, path);
g_free(path);
}
-
+
g_strfreev(split_dirs);
return list;
}
{
GList **listp = data;
EditorDescription *editor = value;
-
+
/* do not show the special commands in any list, they are called explicitly */
if (strcmp(editor->key, CMD_COPY) == 0 ||
strcmp(editor->key, CMD_MOVE) == 0 ||
const EditorDescription *ea = a;
const EditorDescription *eb = b;
gint ret;
-
+
ret = strcmp(ea->menu_path, eb->menu_path);
if (ret != 0) return ret;
-
+
return g_utf8_collate(ea->name, eb->name);
}
GList *editor_list_get(void)
{
GList *editors_list = NULL;
-
+
if (!editors_finished) return NULL;
-
+
g_hash_table_foreach(editors, editor_list_add_cb, &editors_list);
editors_list = g_list_sort(editors_list, editor_sort);
g_free(pathl);
pathl = NULL;
}
-
+
DEBUG_2("editor_command_path_parse: return %s", pathl);
return pathl;
}
static GString *append_quoted(GString *str, const char *s, gboolean single_quotes, gboolean double_quotes)
{
const char *p;
-
+
if (!single_quotes)
{
if (!double_quotes)
else
g_string_append_c(str, *p);
}
-
+
if (!single_quotes)
{
if (!double_quotes)
flags |= EDITOR_ERROR_EMPTY;
goto err;
}
-
+
p = editor->exec;
/* skip leading whitespaces if any */
while (g_ascii_isspace(*p)) p++;
/* just testing, check also the rest of the list (like with F and U)
any matching file is OK */
GList *work = list->next;
-
+
while (!pathl && work)
{
FileData *fd = work->data;
work = work->next;
}
}
-
+
if (!pathl)
{
flags |= EDITOR_ERROR_NO_FILE;
{
ok = (options->shell.path && *options->shell.path);
if (!ok) log_printf("ERROR: empty shell command\n");
-
+
if (ok)
{
ok = (access(options->shell.path, X_OK) == 0);
ed->vd ? &standard_output : NULL,
ed->vd ? &standard_error : NULL,
NULL);
-
+
g_free(working_directory);
if (!ok) ed->flags |= EDITOR_ERROR_CANT_EXEC;
if (!error)
return 0;
-
+
/* command was not started, call the finish immediately */
return editor_command_next_finish(ed, 0);
}
case EDITOR_CB_SKIP:
return editor_command_done(ed);
}
-
+
return editor_command_next_start(ed);
}
EditorFlags error;
EditorDescription *editor;
if (!key) return EDITOR_ERROR_EMPTY;
-
+
editor = g_hash_table_lookup(editors, key);
if (!editor) return EDITOR_ERROR_EMPTY;
if (EDITOR_ERRORS(error))
{
gchar *text = g_strdup_printf(_("%s\n\"%s\""), editor_get_error_str(error), editor->file);
-
+
file_util_warning_dialog(_("Invalid editor command"), text, GTK_STOCK_DIALOG_ERROR, NULL);
g_free(text);
}
{
EditorDescription *editor;
if (!key) return TRUE;
-
+
editor = g_hash_table_lookup(editors, key);
if (!editor) return TRUE;
{
EditorDescription *editor;
if (!key) return TRUE;
-
+
editor = g_hash_table_lookup(editors, key);
if (!editor) return TRUE;
{
EditorDescription *editor;
if (!key) return FALSE;
-
+
editor = g_hash_table_lookup(editors, key);
if (!editor) return FALSE;
{
EditorDescription *editor;
if (!key) return FALSE;
-
+
editor = g_hash_table_lookup(editors, key);
if (!editor) return FALSE;
saved, for editing unrelated files.
%f vs. %F seems to be a good heuristic to detect this kind of editors.
*/
-
+
return !(editor->flags & EDITOR_SINGLE_COMMAND);
}
{
gchar *str;
ExifItem *item;
-
+
if (!key) return NULL;
-
+
/* convert xmp key to exif key */
if (strcmp(key, "Xmp.tiff.Orientation") == 0) key = "Exif.Image.Orientation";
-
+
if (format == METADATA_FORMATTED)
{
gchar *text;
item = exif_get_item(exif, key);
if (!item) return NULL;
-
+
str = exif_item_get_data_as_text_full(item, format);
-
+
if (!str) return NULL;
-
+
return g_list_append(NULL, str);
}
guchar *map_data;
size_t map_len;
int fd;
-
+
if (!exif) return NULL;
path = exif->path;
fd = open(path, O_RDONLY);
-
-
+
+
if (fd == -1)
{
return 0;
ud->ptr = map_data + offset;
ud->map_data = map_data;
ud->map_len = map_len;
-
+
exif_unmap_list = g_list_prepend(exif_unmap_list, ud);
return ud->ptr;
}
void exif_free_preview(guchar *buf)
{
GList *work = exif_unmap_list;
-
+
while (work)
{
UnmapData *ud = (UnmapData *)work->data;
gboolean file_cache_get(FileCacheData *fc, FileData *fd)
{
GList *work;
-
+
g_assert(fc && fd);
work = fc->list;
DEBUG_2("cache move to front: fc=%p %s", fc, fd->path);
fc->list = g_list_remove_link(fc->list, work);
fc->list = g_list_concat(work, fc->list);
-
+
if (file_data_check_changed_files(fd)) {
/* file has been changed, cance entry is no longer valid */
file_cache_remove_fd(fc, fd);
prev = work->prev;
fc->list = g_list_delete_link(fc->list, work);
work = prev;
-
+
DEBUG_2("file changed - cache remove: fc=%p %s", fc, last_fe->fd->path);
fc->size -= last_fe->size;
fc->release(last_fe->fd);
FileCacheEntry *fe;
if (file_cache_get(fc, fd)) return;
-
+
DEBUG_2("cache add: fc=%p %s", fc, fd->path);
fe = g_new(FileCacheEntry, 1);
fe->fd = file_data_ref(fd);
fe->size = size;
fc->list = g_list_prepend(fc->list, fe);
fc->size += size;
-
+
file_cache_set_size(fc, fc->max_size);
}
if (fe->fd == fd)
{
fc->list = g_list_delete_link(fc->list, current);
-
+
DEBUG_1("cache remove: fc=%p %s", fc, fe->fd->path);
fc->size -= fe->size;
fc->release(fe->fd);
gulong n = 0;
DEBUG_1("cache dump: fc=%p max size:%ld size:%ld", fc, fc->max_size, fc->size);
-
+
while (work)
{
FileCacheEntry *fe = work->data;
{
gboolean ret = FALSE;
GList *work;
-
+
ret = file_data_check_changed_single_file(fd, st);
work = fd->sidecar_files;
{
gboolean ret = FALSE;
struct stat st;
-
+
if (fd->parent) fd = fd->parent;
if (!stat_utf8(fd->path, &st))
ret = TRUE;
fd->size = 0;
fd->date = 0;
-
+
/* file_data_disconnect_sidecar_file might delete the file,
we have to keep the reference to prevent this */
sidecars = filelist_copy(fd->sidecar_files);
{
sfd = work->data;
work = work->next;
-
+
file_data_disconnect_sidecar_file(fd, sfd);
}
file_data_check_sidecars(sidecars); /* this will group the sidecars back together */
fd->collate_key_name = g_utf8_collate_key(valid_name, -1);
fd->collate_key_name_nocase = g_utf8_collate_key(caseless_name, -1);
-
+
g_free(valid_name);
g_free(caseless_name);
}
{
fd->extension = fd->name + strlen(fd->name);
}
-
+
fd->sidecar_priority = sidecar_file_priority(fd->extension);
file_data_set_collate_keys(fd);
}
{
file_data_ref(fd);
}
-
+
if (!fd && file_data_planned_change_hash)
{
fd = g_hash_table_lookup(file_data_planned_change_hash, path_utf8);
file_data_apply_ci(fd);
}
}
-
+
if (fd)
{
gboolean changed;
-
+
if (disable_sidecars) file_data_disable_grouping(fd, TRUE);
-
-
+
+
changed = file_data_check_changed_single_file(fd, st);
DEBUG_2("file_data_pool hit: '%s' %s", fd->path, changed ? "(changed)" : "");
-
+
return fd;
}
fd = g_new0(FileData, 1);
-
+
fd->size = st->st_size;
fd->date = st->st_mtime;
fd->mode = st->st_mode;
fd->ref = 1;
fd->magick = FD_MAGICK;
-
+
if (disable_sidecars) fd->disable_grouping = TRUE;
file_data_set_path(fd, path_utf8); /* set path, name, collate_key_*, original_path */
DEBUG_1("%s set_exif_time_data: Already exists for %s", get_exec_time(), file->path);
return;
}
-
+
file->exif = exif_read_fd(file);
if (file->exif)
{
struct tm time_str;
uint year, month, day, hour, min, sec;
-
+
sscanf(tmp, "%4d:%2d:%2d %2d:%2d:%2d", &year, &month, &day, &hour, &min, &sec);
time_str.tm_year = year - 1900;
time_str.tm_mon = month - 1;
time_str.tm_min = min;
time_str.tm_sec = sec;
time_str.tm_isdst = 0;
-
+
file->exifdate = mktime(&time_str);
g_free(tmp);
}
void set_exif_time_data(GList *files)
{
DEBUG_1("%s set_exif_time_data: ...", get_exec_time());
-
+
while (files)
{
FileData *file = files->data;
-
+
read_exif_time_data(file);
files = files->next;
}
else
/* dir or non-existing yet */
g_assert(S_ISDIR(st.st_mode));
-
+
return file_data_new(path_utf8, &st, TRUE);
}
g_free(fd->collate_key_name_nocase);
if (fd->thumb_pixbuf) g_object_unref(fd->thumb_pixbuf);
histmap_free(fd->histmap);
-
+
g_assert(fd->sidecar_files == NULL); /* sidecar files must be freed before calling this */
file_data_change_info_free(NULL, fd);
DEBUG_0("fd magick mismatch fd=%p", fd);
#endif
g_assert(fd->magick == FD_MAGICK);
-
+
fd->ref--;
#ifdef DEBUG_FILEDATA
DEBUG_2("file_data_unref fd=%p (%d): '%s' @ %s:%d", fd, fd->ref, fd->path, file, line);
{
GList *work;
FileData *parent = fd->parent ? fd->parent : fd;
-
+
if (parent->ref > 0) return;
work = parent->sidecar_files;
{
const FileData *fda = a;
const FileData *fdb = b;
-
+
if (fda->sidecar_priority < fdb->sidecar_priority) return -1;
if (fda->sidecar_priority > fdb->sidecar_priority) return 1;
-
+
return strcmp(fdb->extension, fda->extension);
}
while (work) {
gchar *ext = work->data;
-
+
work = work->next;
if (g_ascii_strcasecmp(extension, ext) == 0) return i;
i++;
g_assert(sfd->magick == FD_MAGICK);
DEBUG_2(" sidecar: %p %s", sfd, sfd->name);
}
-
+
g_assert(fd->parent == NULL || fd->sidecar_files == NULL);
}
as sidecars of the first entry (parent_fd) */
work = basename_list->next;
s_work = parent_fd->sidecar_files;
-
+
while (work && s_work)
{
if (work->data != s_work->data) break;
work = work->next;
s_work = s_work->next;
}
-
+
if (!work && !s_work)
{
DEBUG_2("basename no change");
return; /* no change in grouping */
}
-
+
/* we have to regroup it */
-
+
/* first, disconnect everything and send notification*/
work = basename_list;
FileData *fd = work->data;
work = work->next;
g_assert(fd->parent == NULL || fd->sidecar_files == NULL);
-
+
if (fd->parent)
{
FileData *old_parent = fd->parent;
file_data_send_notification(old_parent, NOTIFY_REREAD);
file_data_unref(old_parent);
}
-
+
while (fd->sidecar_files)
{
FileData *sfd = fd->sidecar_files->data;
file_data_unref(sfd);
}
file_data_send_notification(fd, NOTIFY_GROUPING);
-
+
g_assert(fd->parent == NULL && fd->sidecar_files == NULL);
}
file_data_ref(sfd);
g_assert(sfd->parent == target);
-
+
file_data_increment_version(sfd); /* increments both sfd and target */
target->sidecar_files = g_list_remove(target->sidecar_files, sfd);
void file_data_disable_grouping(FileData *fd, gboolean disable)
{
if (!fd->disable_grouping == !disable) return;
-
+
fd->disable_grouping = !!disable;
-
+
if (disable)
{
if (fd->parent)
void file_data_disable_grouping_list(GList *fd_list, gboolean disable)
{
GList *work;
-
+
work = fd_list;
while (work)
{
FileData *fd = work->data;
-
+
file_data_disable_grouping(fd, disable);
work = work->next;
}
ret = strcmp(fa->collate_key_name_nocase, fb->collate_key_name_nocase);
if (ret != 0) return ret;
-
+
/* do not return 0 unless the files are really the same
file_data_pool ensures that original_path is unique
*/
gchar *basename = g_strndup(fd->path, fd->extension - fd->path);
list = g_hash_table_lookup(basename_hash, basename);
-
+
if (!g_list_find(list, fd))
{
list = g_list_insert_sorted(list, file_data_ref(fd), file_data_sort_by_ext);
while (work)
{
FileData *fd = work->data;
-
+
work = work->next;
if (fd->parent) /* remove fd's that are children */
file_data_unref(fd);
}
closedir(dp);
-
+
g_free(pathl);
if (dirs) *dirs = dlist;
if (S_ISDIR(st.st_mode))
return file_data_new(path_utf8, &st, TRUE);
-
+
dir = remove_level_from_path(path_utf8);
-
+
filelist_read_real(dir, &files, NULL, TRUE);
-
+
fd = g_hash_table_lookup(file_data_pool, path_utf8);
g_assert(fd);
file_data_ref(fd);
-
+
filelist_free(files);
g_free(dir);
return fd;
strcmp(name, GQ_CACHE_LOCAL_METADATA) == 0)) )
{
GList *link = work;
-
+
list = g_list_remove_link(list, link);
file_data_unref(fd);
g_list_free(link);
}
-
+
work = work->next;
}
{
gchar *sidecar_path = NULL;
GList *work;
-
+
if (!file_data_can_write_sidecar(fd)) return NULL;
-
+
work = fd->parent ? fd->parent->sidecar_files : fd->sidecar_files;
while (work)
{
break;
}
}
-
+
if (!existing_only && !sidecar_path)
{
gchar *base = g_strndup(fd->path, fd->extension - fd->path);
gboolean file_data_get_mark(FileData *fd, gint n)
{
gboolean valid = (fd->valid_marks & (1 << n));
-
+
if (file_data_get_mark_func[n] && !valid)
{
guint old = fd->marks;
gboolean value = (file_data_get_mark_func[n])(fd, n, file_data_mark_func_data[n]);
-
+
if (!value != !(fd->marks & (1 << n)))
{
fd->marks = fd->marks ^ (1 << n);
}
-
+
fd->valid_marks |= (1 << n);
if (old && !fd->marks) /* keep files with non-zero marks in memory */
{
{
guint old;
if (!value == !file_data_get_mark(fd, n)) return;
-
+
if (file_data_set_mark_func[n])
{
(file_data_set_mark_func[n])(fd, n, value, file_data_mark_func_data[n]);
}
-
+
old = fd->marks;
fd->marks = fd->marks ^ (1 << n);
-
+
if (old && !fd->marks) /* keep files with non-zero marks in memory */
{
file_data_unref(fd);
{
file_data_ref(fd);
}
-
+
file_data_increment_version(fd);
file_data_send_notification(fd, NOTIFY_MARKS);
}
gboolean file_data_register_mark_func(gint n, FileDataGetMarkFunc get_mark_func, FileDataSetMarkFunc set_mark_func, gpointer data, GDestroyNotify notify)
{
if (n < 0 || n >= FILEDATA_MARKS_SIZE) return FALSE;
-
+
if (file_data_destroy_mark_func[n]) (file_data_destroy_mark_func[n])(file_data_mark_func_data[n]);
-
+
file_data_get_mark_func[n] = get_mark_func;
file_data_set_mark_func[n] = set_mark_func;
file_data_mark_func_data[n] = data;
fdci->dest = g_strdup(dest);
fd->change = fdci;
-
+
return TRUE;
}
if (!fdci) return;
file_data_planned_change_remove(fd);
-
+
if (fdci->regroup_when_finished) file_data_disable_grouping(fd, FALSE);
g_free(fdci->source);
GList *work;
if (fd->parent) fd = fd->parent;
-
+
if (fd->change) return FALSE;
-
+
work = fd->sidecar_files;
while (work)
{
FileData *sfd = work->data;
-
+
if (sfd->change) return FALSE;
work = work->next;
}
file_data_add_ci(fd, type, NULL, NULL);
-
+
work = fd->sidecar_files;
while (work)
{
FileData *sfd = work->data;
-
+
file_data_add_ci(sfd, type, NULL, NULL);
work = work->next;
}
-
+
return TRUE;
}
static gboolean file_data_sc_check_ci(FileData *fd, FileDataChangeType type)
{
GList *work;
-
+
if (fd->parent) fd = fd->parent;
-
+
if (!fd->change || fd->change->type != type) return FALSE;
-
+
work = fd->sidecar_files;
while (work)
{
GList *work;
if (fd->parent) fd = fd->parent;
-
+
file_data_free_ci(fd);
-
+
work = fd->sidecar_files;
while (work)
{
FileData *sfd = work->data;
-
+
file_data_free_ci(sfd);
work = work->next;
}
while (work)
{
FileData *fd = work->data;
-
+
if (!file_data_sc_add_ci_delete(fd)) ret = FALSE;
work = work->next;
}
static void file_data_sc_revert_ci_list(GList *fd_list)
{
GList *work;
-
+
work = fd_list;
while (work)
{
FileData *fd = work->data;
-
+
file_data_sc_free_ci(fd);
work = work->prev;
}
static gboolean file_data_sc_add_ci_list_call_func(GList *fd_list, const gchar *dest, gboolean (*func)(FileData *, const gchar *))
{
GList *work;
-
+
work = fd_list;
while (work)
{
FileData *fd = work->data;
-
+
if (!func(fd, dest))
{
file_data_sc_revert_ci_list(work->prev);
}
work = work->next;
}
-
+
return TRUE;
}
while (work)
{
FileData *fd = work->data;
-
+
if (!file_data_add_ci_write_metadata(fd)) ret = FALSE;
work = work->next;
}
void file_data_free_ci_list(GList *fd_list)
{
GList *work;
-
+
work = fd_list;
while (work)
{
FileData *fd = work->data;
-
+
file_data_free_ci(fd);
work = work->next;
}
void file_data_sc_free_ci_list(GList *fd_list)
{
GList *work;
-
+
work = fd_list;
while (work)
{
FileData *fd = work->data;
-
+
file_data_sc_free_ci(fd);
work = work->next;
}
static void file_data_update_planned_change_hash(FileData *fd, const gchar *old_path, gchar *new_path)
{
FileDataChangeType type = fd->change->type;
-
+
if (type == FILEDATA_CHANGE_MOVE || type == FILEDATA_CHANGE_RENAME)
{
FileData *ofd;
-
+
if (!file_data_planned_change_hash)
file_data_planned_change_hash = g_hash_table_new(g_str_hash, g_str_equal);
-
+
if (old_path && g_hash_table_lookup(file_data_planned_change_hash, old_path) == fd)
{
DEBUG_1("planned change: removing %s -> %s", old_path, fd->path);
g_hash_table_remove(file_data_planned_change_hash, new_path);
file_data_unref(ofd);
}
-
+
DEBUG_1("planned change: inserting %s -> %s", new_path, fd->path);
file_data_ref(fd);
g_hash_table_insert(file_data_planned_change_hash, new_path, fd);
const gchar *extension = extension_from_path(fd->change->source);
gchar *base = remove_extension_from_path(dest_path);
gchar *old_path = fd->change->dest;
-
+
fd->change->dest = g_strconcat(base, extension, NULL);
file_data_update_planned_change_hash(fd, old_path, fd->change->dest);
-
+
g_free(old_path);
g_free(base);
}
{
GList *work;
gchar *dest_path_full = NULL;
-
+
if (fd->parent) fd = fd->parent;
-
+
if (!dest_path)
{
dest_path = fd->path;
else if (!strchr(dest_path, G_DIR_SEPARATOR)) /* we got only filename, not a full path */
{
gchar *dir = remove_level_from_path(fd->path);
-
+
dest_path_full = g_build_filename(dir, dest_path, NULL);
g_free(dir);
dest_path = dest_path_full;
dest_path_full = g_build_filename(dest_path, fd->name, NULL);
dest_path = dest_path_full;
}
-
+
file_data_update_ci_dest(fd, dest_path);
-
+
work = fd->sidecar_files;
while (work)
{
FileData *sfd = work->data;
-
+
file_data_update_ci_dest_preserve_ext(sfd, dest_path);
work = work->next;
}
-
+
g_free(dest_path_full);
}
{
return file_data_sc_check_update_ci(fd, dest_path, FILEDATA_CHANGE_COPY);
}
-
+
gboolean file_data_sc_update_ci_move(FileData *fd, const gchar *dest_path)
{
return file_data_sc_check_update_ci(fd, dest_path, FILEDATA_CHANGE_MOVE);
{
GList *work;
gboolean ret = TRUE;
-
+
work = fd_list;
while (work)
{
FileData *fd = work->data;
-
+
if (!func(fd, dest)) ret = FALSE;
work = work->next;
}
-
+
return ret;
}
{
gint ret = CHANGE_OK;
gchar *dir;
-
+
if (!fd->change)
{
DEBUG_1("Change checked: no change info: %s", fd->path);
DEBUG_1("Change checked: file does not exist: %s", fd->path);
return ret;
}
-
+
dir = remove_level_from_path(fd->path);
-
+
if (fd->change->type != FILEDATA_CHANGE_DELETE &&
fd->change->type != FILEDATA_CHANGE_MOVE && /* the unsaved metadata should survive move and rename operations */
fd->change->type != FILEDATA_CHANGE_RENAME &&
ret |= CHANGE_WARN_UNSAVED_META;
DEBUG_1("Change checked: unsaved metadata: %s", fd->path);
}
-
+
if (fd->change->type != FILEDATA_CHANGE_DELETE &&
fd->change->type != FILEDATA_CHANGE_WRITE_METADATA &&
!access_file(fd->path, R_OK))
/* determine destination file */
gboolean have_dest = FALSE;
gchar *dest_dir = NULL;
-
+
if (options->metadata.save_in_image_file)
{
if (file_data_can_write_directly(fd))
g_free(sidecar);
}
}
-
+
if (!have_dest)
{
/* write private metadata file under ~/.geeqie */
metadata_path = cache_find_location(CACHE_TYPE_XMP_METADATA, fd->path);
#endif
if (!metadata_path) metadata_path = cache_find_location(CACHE_TYPE_METADATA, fd->path);
-
+
if (metadata_path && !access_file(metadata_path, W_OK))
{
g_free(metadata_path);
if (recursive_mkdir_if_not_exists(dest_dir, mode))
{
gchar *filename = g_strconcat(fd->name, options->metadata.save_legacy_format ? GQ_CACHE_EXT_METADATA : GQ_CACHE_EXT_XMP_METADATA, NULL);
-
+
metadata_path = g_build_filename(dest_dir, filename, NULL);
g_free(filename);
}
}
g_free(dest_dir);
}
-
+
if (fd->change->dest && fd->change->type != FILEDATA_CHANGE_WRITE_METADATA)
{
gboolean same;
gchar *dest_dir;
-
+
same = (strcmp(fd->path, fd->change->dest) == 0);
if (!same)
g_free(dest_dir);
}
-
+
fd->change->error = ret;
if (ret == 0) DEBUG_1("Change checked: OK: %s", fd->path);
if (result->len > 0) g_string_append(result, ", ");
g_string_append(result, _("destination already exists and will be overwritten"));
}
-
+
if (error & CHANGE_WARN_SAME)
{
if (result->len > 0) g_string_append(result, ", ");
gint num;
gint *errors;
gint i;
-
+
if (!list) return 0;
-
+
num = g_list_length(list);
errors = g_new(int, num);
work = list;
fd = work->data;
work = work->next;
-
+
error = with_sidecars ? file_data_sc_verify_ci(fd) : file_data_verify_ci(fd);
all_errors |= error;
common_errors &= error;
-
+
errors[i] = error;
-
+
i++;
}
-
+
if (desc && all_errors)
{
GList *work;
GString *result = g_string_new("");
-
+
if (common_errors)
{
gchar *str = file_data_get_error_string(common_errors);
g_string_append(result, "\n");
g_free(str);
}
-
+
work = list;
i = 0;
while (work)
fd = work->data;
work = work->next;
-
+
error = errors[i] & ~common_errors;
-
+
if (error)
{
gchar *str = file_data_get_error_string(error);
GList *work;
gboolean ret = TRUE;
FileDataChangeType type = fd->change->type;
-
+
if (!file_data_sc_check_ci(fd, type)) return FALSE;
work = fd->sidecar_files;
while (work)
{
FileData *sfd = work->data;
-
+
if (!file_data_perform_ci(sfd)) ret = FALSE;
work = work->next;
}
-
+
if (!file_data_perform_ci(fd)) ret = FALSE;
-
+
return ret;
}
{
DEBUG_1("planned change: applying %s -> %s", fd->change->dest, fd->path);
file_data_planned_change_remove(fd);
-
+
if (g_hash_table_lookup(file_data_pool, fd->change->dest))
{
/* this change overwrites another file which is already known to other modules
}
file_data_increment_version(fd);
file_data_send_notification(fd, NOTIFY_CHANGE);
-
+
return TRUE;
}
{
GList *work;
FileDataChangeType type = fd->change->type;
-
+
if (!file_data_sc_check_ci(fd, type)) return FALSE;
work = fd->sidecar_files;
while (work)
{
FileData *sfd = work->data;
-
+
file_data_apply_ci(sfd);
work = work->next;
}
-
+
file_data_apply_ci(fd);
-
+
return TRUE;
}
GList *work;
if (fd->parent) fd = fd->parent;
if (!g_list_find(list, fd)) return FALSE;
-
+
work = fd->sidecar_files;
while (work)
{
{
FileData *fd = work->data;
work = work->next;
-
+
if (!file_data_list_contains_whole_group(list, fd))
{
file_data_disable_grouping(fd, TRUE);
}
}
}
-
+
/* remove sidecars from the list,
they can be still acessed via main_fd->sidecar_files */
work = list;
{
FileData *fd = work->data;
work = work->next;
-
+
if (!fd->parent ||
(!ungroup && !file_data_list_contains_whole_group(list, fd)))
{
out = g_list_prepend(out, file_data_ref(fd));
}
}
-
+
filelist_free(list);
out = g_list_reverse(out);
{
NotifyData *nd;
GList *work = notify_func_list;
-
+
while (work)
{
NotifyData *nd = (NotifyData *)work->data;
-
+
if (nd->func == func && nd->data == data)
{
g_warning("Notify func already registered");
}
work = work->next;
}
-
+
nd = g_new(NotifyData, 1);
nd->func = func;
nd->data = data;
notify_func_list = g_list_insert_sorted(notify_func_list, nd, file_data_notify_sort);
DEBUG_2("Notify func registered: %p", nd);
-
+
return TRUE;
}
gboolean file_data_unregister_notify_func(FileDataNotifyFunc func, gpointer data)
{
GList *work = notify_func_list;
-
+
while (work)
{
NotifyData *nd = (NotifyData *)work->data;
-
+
if (nd->func == func && nd->data == data)
{
notify_func_list = g_list_delete_link(notify_func_list, work);
while (work)
{
NotifyData *nd = (NotifyData *)work->data;
-
+
nd->func(nid->fd, nid->type, nd->data);
work = work->next;
}
FileData *fd = key;
file_data_check_changed_files(fd);
-
+
DEBUG_1("monitor %s", fd->path);
}
gboolean file_data_register_real_time_monitor(FileData *fd)
{
gint count;
-
+
file_data_ref(fd);
-
+
if (!file_data_monitor_pool)
file_data_monitor_pool = g_hash_table_new(g_direct_hash, g_direct_equal);
-
+
count = GPOINTER_TO_INT(g_hash_table_lookup(file_data_monitor_pool, fd));
DEBUG_1("Register realtime %d %s", count, fd->path);
-
+
count++;
g_hash_table_insert(file_data_monitor_pool, fd, GINT_TO_POINTER(count));
-
+
if (!realtime_monitor_id)
{
realtime_monitor_id = g_timeout_add(5000, realtime_monitor_cb, NULL);
}
-
+
return TRUE;
}
gint count;
g_assert(file_data_monitor_pool);
-
+
count = GPOINTER_TO_INT(g_hash_table_lookup(file_data_monitor_pool, fd));
-
+
DEBUG_1("Unregister realtime %d %s", count, fd->path);
-
+
g_assert(count > 0);
-
+
count--;
-
+
if (count == 0)
g_hash_table_remove(file_data_monitor_pool, fd);
else
g_hash_table_insert(file_data_monitor_pool, fd, GINT_TO_POINTER(count));
file_data_unref(fd);
-
+
if (g_hash_table_size(file_data_monitor_pool) == 0)
{
g_source_remove(realtime_monitor_id);
realtime_monitor_id = 0;
return FALSE;
}
-
+
return TRUE;
}
/* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */
{
if (fe->file_class == FORMAT_CLASS_UNKNOWN)
fe->file_class = file_class; /* for compatibility */
-
+
if (fe->writable && fe->allow_sidecar)
{
fe->writable = writable;
work = work->next;
name = gdk_pixbuf_format_get_name(format);
-
+
if (strcmp(name, "Digital camera RAW") == 0)
{
DEBUG_1("Skipped '%s' from loader", name);
g_free(name);
continue;
}
-
+
desc = gdk_pixbuf_format_get_description(format);
extensions = gdk_pixbuf_format_get_extensions(format);
filter_add_if_missing("ico", "Icon file", ".ico;.cur", FORMAT_CLASS_IMAGE, TRUE, FALSE, FALSE);
filter_add_if_missing("ras", "Raster", ".ras", FORMAT_CLASS_IMAGE, TRUE, FALSE, FALSE);
filter_add_if_missing("svg", "Scalable Vector Graphics", ".svg", FORMAT_CLASS_IMAGE, TRUE, FALSE, FALSE);
-
+
/* special formats for stereo */
filter_add_if_missing("jps", "Stereo side-by-side jpeg", ".jps", FORMAT_CLASS_IMAGE, TRUE, FALSE, TRUE);
filter_add_if_missing("mpo", "Stereo multi-image jpeg", ".mpo", FORMAT_CLASS_IMAGE, FALSE, TRUE, TRUE);
-
+
/* non-image files that might be desirable to show */
filter_add_if_missing("xmp", "XMP sidecar", ".xmp", FORMAT_CLASS_META, TRUE, FALSE, TRUE);
filter_add_if_missing("gqv", GQ_APPNAME " image collection", GQ_COLLECTION_EXT, FORMAT_CLASS_META, FALSE, FALSE, TRUE);
p++;
l++;
}
-
+
ext = g_strndup(b, l);
-
+
if (g_ascii_strcasecmp(ext, "%image") == 0) file_class = FORMAT_CLASS_IMAGE;
else if (g_ascii_strcasecmp(ext, "%raw") == 0) file_class = FORMAT_CLASS_RAWIMAGE;
else if (g_ascii_strcasecmp(ext, "%meta") == 0) file_class = FORMAT_CLASS_META;
else if (g_ascii_strcasecmp(ext, "%unknown") == 0) file_class = FORMAT_CLASS_UNKNOWN;
-
+
if (file_class == -1)
{
list = g_list_append(list, ext);
list = g_list_concat(list, string_list_copy(file_class_extension_list[file_class]));
g_free(ext);
}
-
+
if (*p == ';') p++;
}
{
gchar *sa = (gchar *)a;
gchar *sb = (gchar *)b;
-
+
gint len_a = strlen(sa);
gint len_b = strlen(sb);
-
+
if (len_a > len_b) return -1;
if (len_a < len_b) return 1;
return 0;
}
-
+
void filter_rebuild(void)
{
{
log_printf("WARNING: invalid file class %d\n", fe->file_class);
}
-
+
if (fe->writable)
{
ext = filter_to_list(fe->extensions);
ext = filter_to_list(fe->extensions);
if (ext) file_sidecar_list = g_list_concat(file_sidecar_list, ext);
}
-
+
}
}
log_printf("unknown attribute %s = %s\n", option, value);
}
if (fe.file_class >= FILE_FORMAT_CLASSES) fe.file_class = FORMAT_CLASS_UNKNOWN;
-
+
if (fe.key && fe.key[0] != 0)
{
old_fe = filter_get_by_key(fe.key);
else
{
GdkCursor *cursor;
-
+
cursor = gdk_cursor_new(GDK_BLANK_CURSOR);
gdk_window_set_cursor(window, cursor);
gdk_cursor_unref(cursor);
image_background_set_color_from_options(fs->imd, TRUE);
image_set_delay_flip(fs->imd, options->fullscreen.clean_flip);
image_auto_refresh_enable(fs->imd, fs->normal_imd->auto_refresh);
-
+
if (options->fullscreen.clean_flip)
{
image_set_update_func(fs->imd, fullscreen_image_update_cb, fs);
gulong g[HISTMAP_SIZE];
gulong b[HISTMAP_SIZE];
gulong max[HISTMAP_SIZE];
-
+
guint idle_id; /* event source id */
GdkPixbuf *pixbuf;
gint y;
const gchar *histogram_label(Histogram *histogram)
{
const gchar *t1 = "";
-
+
if (!histogram) return NULL;
if (histogram->histogram_mode)
gint w, h, i, j, srs, has_alpha, step, end_line;
guchar *s_pix;
GdkPixbuf *imgpixbuf = histmap->pixbuf;
-
+
w = gdk_pixbuf_get_width(imgpixbuf);
h = gdk_pixbuf_get_height(imgpixbuf);
srs = gdk_pixbuf_get_rowstride(imgpixbuf);
s_pix = gdk_pixbuf_get_pixels(imgpixbuf);
has_alpha = gdk_pixbuf_get_has_alpha(imgpixbuf);
-
+
if (whole)
{
end_line = h;
guint max = sp[0];
if (sp[1] > max) max = sp[1];
if (sp[2] > max) max = sp[2];
-
+
histmap->r[sp[0]]++;
histmap->g[sp[1]]++;
histmap->b[sp[2]]++;
const HistMap *histmap_get(FileData *fd)
{
if (fd->histmap && !fd->histmap->idle_id) return fd->histmap; /* histmap exists and is finished */
-
+
return NULL;
}
{
guint i;
float add;
-
+
if (histogram->vgrid == 0) return;
add = width / (float)histogram->vgrid;
{
guint i;
float add;
-
+
if (histogram->hgrid == 0) return;
add = height / (float)histogram->hgrid;
for (i = 1; i < histogram->hgrid; i++)
{
gint ypos = y + (int)(i * add + 0.5);
-
+
pixbuf_draw_line(pixbuf, x, y, width, height, x, ypos, x + width, ypos,
histogram->grid_color.R,
histogram->grid_color.G,
gdouble logmax;
gint combine = (HISTMAP_SIZE - 1) / width + 1;
gint ypos = y + height;
-
+
if (!histogram || !histmap) return FALSE;
-
+
/* Draw the grid */
histogram_vgrid(histogram, pixbuf, x, y, width, height);
histogram_hgrid(histogram, pixbuf, x, y, width, height);
v[2] += histmap->b[p];
v[3] += histmap->max[p];
}
-
+
for (j = 0; combine > 1 && j < 4; j++)
v[j] /= combine;
-
+
num_chan = (histogram->histogram_channel == HCHAN_RGB) ? 3 : 1;
for (j = 0; j < num_chan; j++)
{
{
chanmax = histogram->histogram_channel;
}
-
+
{
gulong pt;
gint r = rplus;
case HCHAN_B: r = 0; g = 0; break;
case HCHAN_MAX: r = 0; b = 0; g = 0; break;
}
-
+
if (v[chanmax] == 0)
pt = 0;
else if (histogram->histogram_mode)
{
DEBUG_2("pending signals detected");
}
-
+
while (il->area_param_list)
{
DEBUG_1("pending area_ready signals detected");
}
if (il->pixbuf) g_object_unref(il->pixbuf);
-
+
if (il->error) g_error_free(il->error);
file_data_unref(il->fd);
if (!fd) return NULL;
il = (ImageLoader *) g_object_new(TYPE_IMAGE_LOADER, NULL);
-
+
il->fd = file_data_ref(fd);
-
+
return il;
}
g_mutex_unlock(il->data_mutex);
g_signal_emit(il, signals[SIGNAL_AREA_READY], 0, x, y, w, h);
-
+
return FALSE;
}
return NULL;
}
}
-
+
ImageLoaderAreaParam *par = g_new0(ImageLoaderAreaParam, 1);
par->il = il;
par->x = x;
par->y = y;
par->w = w;
par->h = h;
-
+
*list = g_list_prepend(*list, par);
return par;
}
static void image_loader_emit_area_ready(ImageLoader *il, guint x, guint y, guint w, guint h)
{
ImageLoaderAreaParam *par = image_loader_queue_area_ready(il, &il->area_param_list, x, y, w, h);
-
+
if (par)
{
g_idle_add_full(G_PRIORITY_HIGH, image_loader_emit_area_ready_cb, par, NULL);
static void image_loader_sync_pixbuf(ImageLoader *il)
{
GdkPixbuf *pb;
-
+
g_mutex_lock(il->data_mutex);
-
+
if (!il->loader)
{
g_mutex_unlock(il->data_mutex);
image_loader_queue_delayed_area_ready(il, x, y, w, h);
else
image_loader_emit_area_ready(il, x, y, w, h);
-
+
if (il->stopping) il->backend.abort(il->loader);
g_mutex_unlock(il->data_mutex);
GdkPixbuf *pb;
guchar *pix;
size_t h, rs;
-
+
/* a workaround for
http://bugzilla.gnome.org/show_bug.cgi?id=547669
http://bugzilla.gnome.org/show_bug.cgi?id=589334
g_free(format);
return;
}
-
+
g_free(format);
pb = il->backend.get_pixbuf(loader);
-
+
h = gdk_pixbuf_get_height(pb);
rs = gdk_pixbuf_get_rowstride(pb);
pix = gdk_pixbuf_get_pixels(pb);
-
+
memset(pix, 0, rs * h); /*this should be faster than pixbuf_fill */
}
static gboolean image_loader_begin(ImageLoader *il)
{
gssize b;
-
+
if (il->pixbuf) return FALSE;
b = MIN(il->read_buffer_size, il->bytes_total - il->bytes_read);
if (b < 1) return FALSE;
image_loader_setup_loader(il);
-
+
g_assert(il->bytes_read == 0);
if (il->backend.load) {
b = il->bytes_total;
exif_free_fd(il->fd, exif);
}
-
+
if (!il->mapped_file)
{
/* normal file */
gint load_fd;
-
+
pathl = path_from_utf8(il->fd->path);
load_fd = open(pathl, O_RDONLY | O_NONBLOCK);
g_free(pathl);
close(load_fd);
return FALSE;
}
-
+
il->mapped_file = mmap(0, il->bytes_total, PROT_READ|PROT_WRITE, MAP_PRIVATE, load_fd, 0);
close(load_fd);
if (il->mapped_file == MAP_FAILED)
}
il->preview = FALSE;
}
-
+
return TRUE;
}
static void image_loader_stop_source(ImageLoader *il)
{
if (!il) return;
-
+
if (il->mapped_file)
{
if (il->preview)
g_source_remove(il->idle_id);
il->idle_id = 0;
}
-
+
if (il->thread)
{
/* stop loader in the other thread */
image_loader_stop_loader(il);
image_loader_stop_source(il);
-
+
}
void image_loader_delay_area_ready(ImageLoader *il, gboolean enable)
{
ImageLoaderAreaParam *par = work->data;
work = work->next;
-
+
g_signal_emit(il, signals[SIGNAL_AREA_READY], 0, par->x, par->y, par->w, par->h);
g_free(par);
}
{
ret = image_loader_continue(il);
}
-
+
if (!ret)
{
image_loader_stop_source(il);
}
-
+
return ret;
}
static gboolean image_loader_start_idle(ImageLoader *il)
{
gboolean ret;
-
+
if (!il) return FALSE;
if (!il->fd) return FALSE;
if (!image_loader_setup_source(il)) return FALSE;
-
+
ret = image_loader_begin(il);
if (ret && !il->done) il->idle_id = g_idle_add_full(il->idle_priority, image_loader_idle_cb, il, NULL);
ImageLoader *il = data;
gboolean cont;
gboolean err;
-
+
if (il->idle_priority > G_PRIORITY_DEFAULT_IDLE)
{
/* low prio, wait untill high prio tasks finishes */
/* high prio */
image_loader_thread_enter_high();
}
-
+
err = !image_loader_begin(il);
-
+
if (err)
{
/*
*/
image_loader_emit_error(il);
}
-
+
cont = !err;
-
+
while (cont && !image_loader_get_is_done(il) && !image_loader_get_stopping(il))
{
if (il->idle_priority > G_PRIORITY_DEFAULT_IDLE)
if (!il->fd) return FALSE;
il->thread = TRUE;
-
+
if (!image_loader_setup_source(il)) return FALSE;
if (!image_loader_thread_pool)
g_thread_pool_push(image_loader_thread_pool, il, NULL);
DEBUG_1("Thread pool num threads: %d", g_thread_pool_get_num_threads(image_loader_thread_pool));
-
+
return TRUE;
}
#endif /* HAVE_GTHREAD */
{
GdkPixbuf *ret;
if (!il) return NULL;
-
+
g_mutex_lock(il->data_mutex);
ret = il->pixbuf;
g_mutex_unlock(il->data_mutex);
{
gdouble ret;
if (!il) return 0.0;
-
+
g_mutex_lock(il->data_mutex);
if (il->bytes_total == 0)
{
struct _ImageLoader
{
GObject parent;
-
+
/*< private >*/
GdkPixbuf *pixbuf;
FileData *fd;
guint idle_done_id; /* event source id */
GList *area_param_list;
GList *area_param_delayed_list;
-
+
gboolean delay_area_ready;
-
+
GMutex *data_mutex;
gboolean stopping;
gboolean can_destroy;
struct _ImageLoaderClass {
GObjectClass parent;
-
+
/* class members */
void (*area_ready)(ImageLoader *, guint x, guint y, guint w, guint h, gpointer);
void (*error)(ImageLoader *, gpointer);
OsdShowFlags show;
gint ovl_info;
-
+
gint x;
gint y;
{
gchar *kw = work->data;
work = work->next;
-
+
if (!kw) continue;
if (!kwstr)
kwstr = g_string_new("");
else
g_string_append(kwstr, ", ");
-
+
g_string_append(kwstr, kw);
}
string_list_free(keywords);
if (extrapos)
extra = g_strndup(extrapos, end - extrapos);
-
+
name = g_strndup(start+1, (trunc ? trunc : end)-start-1);
pos = start - new->str;
data = NULL;
if (!data)
data = metadata_read_string(imd->image_fd, name, METADATA_FORMATTED);
}
-
+
if (data && *data && limit > 0 && strlen(data) > limit + 3)
{
gchar *new_data = g_strdup_printf("%-*.*s...", limit, limit, data);
g_free(data);
data = new_data;
}
-
+
if (data)
{
/* Since we use pango markup to display, we need to escape here */
gchar *right = extra;
gchar *p;
guint len = strlen(extra);
-
+
/* Search for left and right parts and unescape characters */
for (p = extra; *p; p++, len--)
if (p[0] == '\\')
t = 1;
n = 1;
}
-
+
if (n < 1) n = 1;
if (t < 1) t = 1;
-
+
osd_template_insert(vars, "collection", NULL, OSDT_NONE);
}
-
+
osd_template_insert(vars, "number", g_strdup_printf("%d", n), OSDT_NO_DUP);
osd_template_insert(vars, "total", g_strdup_printf("%d", t), OSDT_NO_DUP);
osd_template_insert(vars, "name", (gchar *) name, OSDT_NONE);
osd_template_insert(vars, "date", imd->image_fd ? ((gchar *) text_from_time(imd->image_fd->date)) : "", OSDT_NONE);
osd_template_insert(vars, "size", imd->image_fd ? (text_from_size_abrev(imd->image_fd->size)) : g_strdup(""), OSDT_FREE);
osd_template_insert(vars, "zoom", image_zoom_get_as_text(imd), OSDT_FREE);
-
+
if (!imd->unknown)
{
gint w, h;
{
image_get_image_size(imd, &w, &h);
}
-
-
+
+
osd_template_insert(vars, "width", g_strdup_printf("%d", w), OSDT_NO_DUP);
osd_template_insert(vars, "height", g_strdup_printf("%d", h), OSDT_NO_DUP);
osd_template_insert(vars, "res", g_strdup_printf("%d × %d", w, h), OSDT_FREE);
with_hist = FALSE;
}
}
-
-
+
+
{
gint active_marks = 0;
gint mark;
{
if (osd->changed_states & IMAGE_STATE_IMAGE)
image_osd_icons_reset_time(osd);
-
+
if (osd->changed_states & IMAGE_STATE_COLOR_ADJ)
{
osd->icon_time[IMAGE_OSD_COLOR] = IMAGE_OSD_DEFAULT_DURATION + 1;
osd->show = OSD_SHOW_NOTHING;
osd->x = options->image_overlay.x;
osd->y = options->image_overlay.y;
-
+
osd->histogram = histogram_new();
osd->destroy_id = g_signal_connect(G_OBJECT(imd->pr), "destroy",
{
Histogram *h_src, *h_dest;
image_osd_set(dest, image_osd_get(src));
-
+
h_src = image_osd_get_histogram(src);
h_dest = image_osd_get_histogram(dest);
-
+
h_dest->histogram_mode = h_src->histogram_mode;
h_dest->histogram_channel = h_src->histogram_channel;
-
+
}
/* duration:
imd->color_profile_input < COLOR_PROFILE_FILE + COLOR_PROFILE_INPUTS)
{
const gchar *file = options->color_profile.input_file[imd->color_profile_input - COLOR_PROFILE_FILE];
-
+
if (!is_readable_file(file)) return FALSE;
input_type = COLOR_PROFILE_FILE;
imd->color_profile_from_image = COLOR_PROFILE_NONE;
exif = exif_read_fd(imd->image_fd);
-
+
if (exif)
{
profile = exif_get_color_profile(exif, &profile_len);
exif_free_fd(imd->image_fd, exif);
}
-
+
if (profile)
{
}
image_update_util(imd);
-
+
if (screen_profile)
{
g_free(screen_profile);
screen_profile = NULL;
}
-
+
return !!cm;
}
DEBUG_1("%s read ahead started for :%s", get_exec_time(), imd->read_ahead_fd->path);
imd->read_ahead_il = image_loader_new(imd->read_ahead_fd);
-
+
image_loader_delay_area_ready(imd->read_ahead_il, TRUE); /* we will need the area_ready signals later */
g_signal_connect(G_OBJECT(imd->read_ahead_il), "error", (GCallback)image_read_ahead_error_cb, imd);
g_assert(imd->image_fd->pixbuf);
image_change_pixbuf(imd, imd->image_fd->pixbuf, image_zoom_get(imd), FALSE);
}
-
+
// file_cache_dump(image_get_cache());
return success;
}
if (is_readable_file(imd->image_fd->path))
{
PixbufRenderer *pr;
-
+
pr = PIXBUF_RENDERER(imd->pr);
pr->zoom = zoom; /* store the zoom, needed by the loader */
if (imd->unknown == TRUE)
{
GdkPixbuf *pixbuf;
-
+
pixbuf = pixbuf_inline(PIXBUF_INLINE_BROKEN);
image_change_pixbuf(imd, pixbuf, zoom, FALSE);
g_object_unref(pixbuf);
a notification that removes the pixbuf from cache and unrefs it. Therefore we must ref it
here before it is taken over by the renderer. */
if (pixbuf) g_object_ref(pixbuf);
-
+
if (imd->image_fd)
{
if (imd->image_fd->user_orientation)
{
ColorMan *cm;
if (!imd) return FALSE;
-
+
cm = imd->cm;
if (!cm) return FALSE;
return color_man_get_status(cm, image_profile, screen_profile);
void image_select(ImageWindow *imd, gboolean select)
{
if (!imd->has_frame) return;
-
+
if (select)
{
gtk_widget_set_state(imd->widget, GTK_STATE_SELECTED);
void image_set_selectable(ImageWindow *imd, gboolean selectable)
{
if (!imd->has_frame) return;
-
+
gtk_frame_set_shadow_type(GTK_FRAME(imd->frame), GTK_SHADOW_NONE);
gtk_container_set_border_width(GTK_CONTAINER(imd->frame), selectable ? 4 : 0);
}
NULL);
pixbuf_renderer_set_parent((PixbufRenderer *)imd->pr, (GtkWindow *)imd->top_window);
-
+
image_stereo_set(imd, options->stereo.mode);
pixbuf_renderer_stereo_fixed_set((PixbufRenderer *)imd->pr,
options->stereo.fixed_w, options->stereo.fixed_h,
g_object_unref(imd->pr);
gtk_widget_set_can_focus(imd->frame, TRUE);
gtk_widget_set_app_paintable(imd->frame, TRUE);
-
+
#if GTK_CHECK_VERSION(3,0,0)
g_signal_connect(G_OBJECT(imd->frame), "draw",
G_CALLBACK(selectable_frame_draw_cb), NULL);
static gpointer image_loader_gdk_new(ImageLoaderBackendCbAreaUpdated area_updated_cb, ImageLoaderBackendCbSize size_cb, ImageLoaderBackendCbAreaPrepared area_prepared_cb, gpointer data)
{
GdkPixbufLoader *loader = gdk_pixbuf_loader_new();
-
+
g_signal_connect(G_OBJECT(loader), "area_updated", G_CALLBACK(area_updated_cb), data);
g_signal_connect(G_OBJECT(loader), "size_prepared", G_CALLBACK(size_cb), data);
g_signal_connect(G_OBJECT(loader), "area_prepared", G_CALLBACK(area_prepared_cb), data);
funcs->close = (ImageLoaderBackendFuncClose) gdk_pixbuf_loader_close;
funcs->abort = image_loader_gdk_abort;
funcs->free = image_loader_gdk_free;
-
+
funcs->get_format_name = image_loader_gdk_get_format_name;
funcs->get_format_mime_types = image_loader_gdk_get_format_mime_types;
}
ImageLoaderBackendCbAreaUpdated area_updated_cb;
ImageLoaderBackendCbSize size_cb;
ImageLoaderBackendCbAreaPrepared area_prepared_cb;
-
+
gpointer data;
-
+
GdkPixbuf *pixbuf;
guint requested_width;
guint requested_height;
-
+
gboolean abort;
gboolean stereo;
-
+
};
/* error handler data */
w = cinfo->output_width;
for (i = cinfo->rec_outbuf_height - 1; i >= 0; i--) {
guchar *from, *to;
-
+
from = lines[i] + w - 1;
to = lines[i] + (w - 1) * 3;
for (j = w - 1; j >= 0; j--) {
for (i = cinfo->rec_outbuf_height - 1; i >= 0; i--) {
guchar *p;
-
+
p = lines[i];
for (j = 0; j < cinfo->output_width; j++) {
int c, m, y, k;
static gpointer image_loader_jpeg_new(ImageLoaderBackendCbAreaUpdated area_updated_cb, ImageLoaderBackendCbSize size_cb, ImageLoaderBackendCbAreaPrepared area_prepared_cb, gpointer data)
{
ImageLoaderJpeg *loader = g_new0(ImageLoaderJpeg, 1);
-
+
loader->area_updated_cb = area_updated_cb;
loader->size_cb = size_cb;
loader->area_prepared_cb = area_prepared_cb;
{
struct error_handler_data *errmgr;
char buffer[JMSG_LENGTH_MAX];
-
+
errmgr = (struct error_handler_data *) cinfo->err;
-
+
/* Create the message */
(* cinfo->err->format_message) (cinfo, buffer);
_("Error interpreting JPEG image file (%s)"),
buffer);
}
-
+
siglongjmp (errmgr->setjmp_buffer, 1);
g_assert_not_reached ();
guint stereo_length = 0;
struct error_handler_data jerr;
-
+
lj->stereo = FALSE;
MPOData *mpo = jpeg_get_mpo_data(buf, count);
guint i;
gint idx1 = -1, idx2 = -1;
guint num2 = 1;
-
+
for (i = 0; i < mpo->num_images; i++)
{
if (mpo->images[i].type_code == 0x20002)
}
}
}
-
+
if (idx1 >= 0 && idx2 >= 0)
{
lj->stereo = TRUE;
if (lj->stereo) jpeg_destroy_decompress(&cinfo2);
return FALSE;
}
-
+
jpeg_create_decompress(&cinfo);
set_mem_src(&cinfo, (unsigned char *)buf, count);
jpeg_read_header(&cinfo, TRUE);
-
+
if (lj->stereo)
{
jpeg_create_decompress(&cinfo2);
set_mem_src(&cinfo2, stereo_buf2, stereo_length);
jpeg_read_header(&cinfo2, TRUE);
-
+
if (cinfo.image_width != cinfo2.image_width ||
cinfo.image_height != cinfo2.image_height)
{
}
}
-
+
lj->requested_width = lj->stereo ? cinfo.image_width * 2: cinfo.image_width;
lj->requested_height = cinfo.image_height;
lj->size_cb(loader, lj->requested_width, lj->requested_height, lj->data);
-
+
cinfo.scale_num = 1;
for (cinfo.scale_denom = 2; cinfo.scale_denom <= 8; cinfo.scale_denom *= 2) {
jpeg_calc_output_dimensions(&cinfo);
jpeg_calc_output_dimensions(&cinfo2);
jpeg_start_decompress(&cinfo2);
}
-
+
jpeg_start_decompress(&cinfo);
-
+
if (lj->stereo)
{
lj->stereo = FALSE;
}
}
-
-
+
+
lj->pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB,
cinfo.out_color_components == 4 ? TRUE : FALSE,
8, lj->stereo ? cinfo.output_width * 2: cinfo.output_width, cinfo.output_height);
rowstride = gdk_pixbuf_get_rowstride(lj->pixbuf);
dptr = gdk_pixbuf_get_pixels(lj->pixbuf);
dptr2 = gdk_pixbuf_get_pixels(lj->pixbuf) + ((cinfo.out_color_components == 4) ? 4 * cinfo.output_width : 3 * cinfo.output_width);
-
+
while (cinfo.output_scanline < cinfo.output_height && !lj->abort)
{
funcs->close = image_loader_jpeg_close;
funcs->abort = image_loader_jpeg_abort;
funcs->free = image_loader_jpeg_free;
-
+
funcs->get_format_name = image_loader_jpeg_get_format_name;
funcs->get_format_mime_types = image_loader_jpeg_get_format_mime_types;
}
ImageLoaderBackendCbAreaUpdated area_updated_cb;
ImageLoaderBackendCbSize size_cb;
ImageLoaderBackendCbAreaPrepared area_prepared_cb;
-
+
gpointer data;
GdkPixbuf *pixbuf;
guint requested_width;
guint requested_height;
-
+
gboolean abort;
const guchar *buffer;
for (row = 0; row < height; row += rowsperstrip)
{
int rows_to_write, i_row;
-
+
if (lt->abort) {
break;
}
funcs->close = image_loader_tiff_close;
funcs->abort = image_loader_tiff_abort;
funcs->free = image_loader_tiff_free;
-
+
funcs->get_format_name = image_loader_tiff_get_format_name;
funcs->get_format_mime_types = image_loader_tiff_get_format_mime_types;
}
{
if (image_osd_get(vw->imd) & OSD_SHOW_INFO)
image_osd_set(vw->imd, image_osd_get(vw->fs->imd));
-
+
fullscreen_stop(vw->fs);
}
else
ImageWindow *imd;
imd = view_window_active_image(vw);
-
+
image_osd_toggle(imd);
}
{
ViewWindow *vw = work->data;
work = work->next;
-
+
image_background_set_color_from_options(vw->imd, !!vw->fs);
}
}
FileData *fd = image_get_fd(imd);
if (fd) list = g_list_append(NULL, file_data_ref(fd));
}
-
+
return list;
}
ViewWindow *vw = data;
if (!(type & NOTIFY_CHANGE) || !fd->change) return;
-
+
DEBUG_1("Notify view_window: %s %04x", fd->path, type);
switch (fd->change->type)
{
parse_entry(tiff, offset + i * TIFF_TIFD_SIZE, size, bo, data);
}
-
+
next = tiff_byte_get_int32(tiff + offset + count * TIFF_TIFD_SIZE, bo);
if (next_offset) *next_offset = next;
-
+
return 0;
}
{
return -1;
}
-
+
mpo->images = g_new0(MPOEntry, mpo->num_images);
-
+
for (i = 0; i < mpo->num_images; i++) {
guint image_attr = tiff_byte_get_int32(tiff + data_offset + i * 16, bo);
mpo->images[i].type_code = image_attr & 0xffffff;
mpo->images[i].offset = tiff_byte_get_int32(tiff + data_offset + i * 16 + 8, bo);
mpo->images[i].dep1 = tiff_byte_get_int16(tiff + data_offset + i * 16 + 12, bo);
mpo->images[i].dep2 = tiff_byte_get_int16(tiff + data_offset + i * 16 + 14, bo);
-
+
if (i == 0)
{
mpo->images[i].offset = 0;
{
mpo->images[i].offset += mpo->mpo_offset;
}
-
+
DEBUG_1(" image %x %x %x", image_attr, mpo->images[i].length, mpo->images[i].offset);
}
}
DEBUG_1("mpo signature found at %x", seg_offset);
seg_offset += 4;
seg_size -= 4;
-
+
if (!tiff_directory_offset(data + seg_offset, seg_size, &offset, &bo)) return NULL;
mpo = g_new0(MPOData, 1);
mpo->mpo_offset = seg_offset;
-
+
tiff_parse_IFD_table(data + seg_offset, offset , seg_size, bo, &next_offset, mpo_parse_Index_IFD_entry, (gpointer)mpo);
if (!mpo->images) mpo->num_images = 0;
-
-
+
+
for (i = 0; i < mpo->num_images; i++)
{
if (mpo->images[i].offset + mpo->images[i].length > size)
break;
}
}
-
+
for (i = 0; i < mpo->num_images; i++)
{
if (i == 0)
DEBUG_1("MPO image %d: MPO signature not found", i);
continue;
}
-
+
seg_offset += 4;
seg_size -= 4;
if (!tiff_directory_offset(data + mpo->images[i].offset + seg_offset, seg_size, &offset, &bo))
}
tiff_parse_IFD_table(data + mpo->images[i].offset + seg_offset, offset , seg_size, bo, NULL, mpo_parse_Attributes_IFD_entry, (gpointer)&mpo->images[i]);
}
-
+
return mpo;
}
return NULL;
GList *work;
if (!id || !id[0]) return NULL;
-
+
if (strcmp(id, LAYOUT_ID_CURRENT) == 0)
{
if (current_lw) return current_lw;
char id[10];
gint i;
if (lw->options.id && lw->options.id[0]) return; /* id is already set */
-
+
g_free(lw->options.id);
lw->options.id = NULL;
-
+
if (!layout_find_by_layout_id("main"))
{
lw->options.id = g_strdup("main");
return;
}
-
+
i = 1;
while (TRUE)
{
buf = g_strdup(path);
parse_out_relatives(buf);
-
+
if (isdir(buf))
{
if ((!lw->dir_fd || strcmp(lw->dir_fd->path, buf) != 0) && layout_set_path(lw, buf))
}
g_free(base);
}
-
+
g_free(buf);
}
{
guint n;
gint64 n_bytes = 0;
-
+
n = layout_list_count(lw, &n_bytes);
-
+
if (n)
{
guint s;
{
ss = "";
}
-
+
s = layout_selection_count(lw, &s_bytes);
-
+
layout_bars_new_selection(lw, s);
-
+
if (s > 0)
{
gchar *b = text_from_size_abrev(n_bytes);
{
buf = g_strdup_printf(_("%d files%s"), n, ss);
}
-
+
text = buf;
-
+
image_osd_update(lw->image);
}
else
text = "";
}
}
-
+
if (lw->info_status) gtk_label_set_text(GTK_LABEL(lw->info_status), text);
g_free(buf);
}
void layout_status_update_image(LayoutWindow *lw)
{
guint64 n;
-
+
if (!layout_valid(&lw) || !lw->image) return;
if (!lw->info_zoom || !lw->info_details) return; /*called from layout_style_set */
n = layout_list_count(lw, NULL);
-
+
if (!n)
{
gtk_label_set_text(GTK_LABEL(lw->info_zoom), "");
else
{
gint width, height;
-
+
image_get_image_size(lw->image, &width, &height);
text = g_strdup_printf(_("( %d x %d ) %s bytes"),
width, height, b);
}
g_signal_emit_by_name (lw->image->pr, "update-pixel");
-
+
g_free(b);
-
+
gtk_label_set_text(GTK_LABEL(lw->info_details), text);
g_free(text);
}
}
lw->info_details = layout_status_label(NULL, hbox, TRUE, 0, TRUE);
toolbar = layout_actions_toolbar(lw, TOOLBAR_STATUS);
-
+
toolbar_frame = gtk_frame_new(NULL);
gtk_frame_set_shadow_type(GTK_FRAME(toolbar_frame), GTK_SHADOW_IN);
gtk_container_add(GTK_CONTAINER(toolbar_frame), toolbar);
vf_set_thumb_status_func(lw->vf, layout_list_thumb_cb, lw);
vf_marks_set(lw->vf, lw->options.show_marks);
-
+
layout_list_sync_thumb(lw);
return lw->vf->widget;
gboolean ret;
if (!path) return FALSE;
-
+
fd = file_data_new_group(path);
ret = layout_set_fd(lw, fd);
file_data_unref(fd);
if (lw->path_entry) tab_completion_append_to_history(lw->path_entry, lw->dir_fd->path);
layout_sync_path(lw);
layout_list_sync_sort(lw);
-
+
if (have_file)
{
gint row;
{
GdkWindow *window;
if (!layout_valid(&lw)) return FALSE;
-
+
window = gtk_widget_get_window(lw->window);
gdk_window_get_root_origin(window, x, y);
*w = gdk_window_get_width(window);
{
GtkAllocation h_allocation;
GtkAllocation v_allocation;
-
+
if (!layout_valid(&lw)) return FALSE;
-
+
if (lw->h_pane)
{
GtkWidget *child = gtk_paned_get_child1(GTK_PANED(lw->h_pane));
image = layout_image_setup_split(lw, lw->split_mode);
image_sb = layout_bars_prepare(lw, image);
}
-
+
tools = layout_tools_new(lw);
files = layout_list_new(lw);
gint i;
LayoutWindow *lw = work->data;
work = work->next;
-
+
if (!lw->image) continue;
for (i = 0; i < MAX_SPLIT_IMAGES; i++)
if (!lw->split_images[i]) continue;
image_background_set_color_from_options(lw->split_images[i], !!lw->full_screen);
}
-
+
image_background_set_color_from_options(lw->image, !!lw->full_screen);
}
}
void layout_info_pixel_set(LayoutWindow *lw, gboolean show)
{
GtkWidget *frame;
-
+
if (!layout_valid(&lw)) return;
if (!lw->info_pixel) return;
{
gtk_widget_show(frame);
}
-
+
g_signal_emit_by_name (lw->image->pr, "update-pixel");
}
GtkWidget *configwindow;
GtkWidget *home_path_entry;
GtkWidget *layout_widget;
-
+
LayoutOptions options;
};
static void layout_config_close_cb(GtkWidget *widget, gpointer data)
{
LayoutConfig *lc = data;
-
+
gtk_widget_destroy(lc->configwindow);
free_layout_options_content(&lc->options);
g_free(lc);
static void layout_config_apply_cb(GtkWidget *widget, gpointer data)
{
LayoutConfig *lc = data;
-
+
g_free(lc->options.order);
lc->options.order = layout_config_get(lc->layout_widget, &lc->options.style);
}
frame = pref_frame_new(win_vbox, TRUE, NULL, GTK_ORIENTATION_VERTICAL, PREF_PAD_GAP);
-
+
vbox = gtk_vbox_new(FALSE, PREF_PAD_SPACE);
gtk_container_add(GTK_CONTAINER(frame), vbox);
gtk_widget_show(vbox);
lw->options.image_overlay.state = image_osd_get(lw->image);
histogram = image_osd_get_histogram(lw->image);
-
+
lw->options.image_overlay.histogram_channel = histogram->histogram_channel;
lw->options.image_overlay.histogram_mode = histogram->histogram_mode;
if (current_lw == lw) current_lw = NULL;
if (lw->exif_window) g_signal_handlers_disconnect_matched(G_OBJECT(lw->exif_window), G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, lw);
-
+
layout_bars_close(lw);
g_object_unref(lw->menu_bar);
if (lw->toolbar[i]) g_object_unref(lw->toolbar[i]);
string_list_free(lw->toolbar_actions[i]);
}
-
+
gtk_widget_destroy(lw->window);
-
+
if (lw->split_image_sizegroup) g_object_unref(lw->split_image_sizegroup);
file_data_unregister_notify_func(layout_image_notify_cb, lw);
GdkPixbuf *pixbuf;
pixbuf = pixbuf_inline(PIXBUF_INLINE_LOGO);
-
+
/* FIXME: the zoom value set here is the value, which is then copied again and again
in "Leave Zoom at previous setting" mode. This is not ideal. */
image_change_pixbuf(lw->image, pixbuf, 0.0, FALSE);
image_osd_set(lw->image, lw->options.image_overlay.state);
histogram = image_osd_get_histogram(lw->image);
-
+
histogram->histogram_channel = lw->options.image_overlay.histogram_channel;
histogram->histogram_mode = lw->options.image_overlay.histogram_mode;
bar_sort_write_config(lw->bar_sort, outstr, indent + 1);
bar_write_config(lw->bar, outstr, indent + 1);
-
+
layout_toolbar_write_config(lw, TOOLBAR_MAIN, outstr, indent + 1);
layout_toolbar_write_config(lw, TOOLBAR_STATUS, outstr, indent + 1);
void layout_load_attributes(LayoutOptions *layout, const gchar **attribute_names, const gchar **attribute_values)
{
gchar *id = NULL;
-
+
while (*attribute_names)
{
const gchar *option = *attribute_names++;
if (READ_INT(*layout, style)) continue;
if (READ_CHAR(*layout, order)) continue;
-
+
if (READ_UINT(*layout, dir_view_type)) continue;
if (READ_UINT(*layout, file_view_type)) continue;
if (READ_BOOL(*layout, show_marks)) continue;
if (READ_INT(*layout, float_window.w)) continue;
if (READ_INT(*layout, float_window.h)) continue;
if (READ_INT(*layout, float_window.vdivider_pos)) continue;
-
+
if (READ_INT(*layout, properties_window.w)) continue;
if (READ_INT(*layout, properties_window.h)) continue;
*path = g_strdup(command_line->path);
}
else layout_config_startup_path(lop, path);
-
+
if (command_line->tools_show)
{
lop->tools_float = FALSE;
LayoutOptions lop;
LayoutWindow *lw;
gchar *path = NULL;
-
+
init_layout_options(&lop);
if (attribute_names) layout_load_attributes(&lop, attribute_names, attribute_values);
-
+
if (use_commandline)
{
layout_config_commandline(&lop, &path);
void layout_update_from_config(LayoutWindow *lw, const gchar **attribute_names, const gchar **attribute_values)
{
LayoutOptions lop;
-
+
init_layout_options(&lop);
if (attribute_names) layout_load_attributes(&lop, attribute_names, attribute_values);
layout_apply_options(lw, &lop);
-
+
free_layout_options_content(&lop);
}
else
list = g_list_append(NULL, file_data_ref(fd));
}
-
+
return list;
}
if (!path) gtk_widget_set_sensitive(item, FALSE);
item = menu_item_add_stock(menu, _("_Delete..."), GTK_STOCK_DELETE, G_CALLBACK(li_pop_menu_delete_cb), lw);
if (!path) gtk_widget_set_sensitive(item, FALSE);
-
+
item = menu_item_add(menu, _("_Copy path"), G_CALLBACK(li_pop_menu_copy_path_cb), lw);
if (!path) gtk_widget_set_sensitive(item, FALSE);
image_get_image_size(lw->image, &width, &height);
dx = (gdouble) x / width;
dy = (gdouble) y / height;
-
+
for (i = 0; i < MAX_SPLIT_IMAGES; i++)
{
if (lw->split_images[i] && lw->split_images[i] != lw->image)
if (width < 1 || height < 1) return;
pixbuf_renderer_get_mouse_position(pr, &x_pixel, &y_pixel);
-
+
if(x_pixel >= 0 && y_pixel >= 0)
{
gint r_mouse, g_mouse, b_mouse;
-
+
pixbuf_renderer_get_pixel_colors(pr, x_pixel, y_pixel,
&r_mouse, &g_mouse, &b_mouse);
-
+
text = g_strdup_printf(_("[%*d,%*d]: RGB(%3d,%3d,%3d)"),
num_length(width - 1), x_pixel,
num_length(height - 1), y_pixel,
r_mouse, g_mouse, b_mouse);
-
+
}
else
{
layout_image_new(lw, i);
image_set_frame(lw->split_images[i], frame);
image_set_selectable(lw->split_images[i], (n > 1));
-
+
if (lw->image)
{
image_osd_copy_status(lw->image, lw->split_images[i]);
{
GList *work = g_list_last(layout_selection_list(lw));
gint j = 0;
-
+
if (work) work = work->prev;
while (work && j < i)
{
FileData *fd = work->data;
work = work->prev;
-
+
j++;
if (!fd || !*fd->path) continue;
img_fd = fd;
lw->split_images[i] = NULL;
}
}
-
+
if (!lw->image || lw->active_split_image < 0 || lw->active_split_image >= n)
{
layout_image_activate(lw, 0, TRUE);
GtkWidget *layout_image_setup_split_none(LayoutWindow *lw)
{
lw->split_mode = SPLIT_NONE;
-
+
layout_image_setup_split_common(lw, 1);
lw->split_image_widget = lw->split_images[0]->widget;
GtkWidget *layout_image_setup_split_hv(LayoutWindow *lw, gboolean horizontal)
{
GtkWidget *paned;
-
+
lw->split_mode = horizontal ? SPLIT_HOR : SPLIT_VERT;
layout_image_setup_split_common(lw, 2);
}
layout_image_set_fd(lw, NULL);
}
-
+
/* the image will be set to the next image from the list soon,
setting it to NULL here is not necessary*/
}
if (!(type & NOTIFY_CHANGE) || !fd->change) return;
DEBUG_1("Notify layout_image: %s %04x", fd->path, type);
-
+
switch (fd->change->type)
{
case FILEDATA_CHANGE_MOVE:
static void layout_menu_list_cb(GtkRadioAction *action, GtkRadioAction *current, gpointer data)
{
LayoutWindow *lw = data;
-
+
layout_exit_fullscreen(lw);
layout_views_set(lw, lw->options.dir_view_type, (FileViewType) gtk_radio_action_get_current_value(action));
}
static void layout_menu_overlay_cb(GtkToggleAction *action, gpointer data)
{
LayoutWindow *lw = data;
-
+
if (gtk_toggle_action_get_active(action))
{
OsdShowFlags flags = image_osd_get(lw->image);
-
+
if ((flags | OSD_SHOW_INFO | OSD_SHOW_STATUS) != flags)
image_osd_set(lw->image, flags | OSD_SHOW_INFO | OSD_SHOW_STATUS);
}
else
{
GtkToggleAction *histogram_action = GTK_TOGGLE_ACTION(gtk_action_group_get_action(lw->action_group, "ImageHistogram"));
-
+
image_osd_set(lw->image, OSD_SHOW_NOTHING);
gtk_toggle_action_set_active(histogram_action, FALSE); /* this calls layout_menu_histogram_cb */
}
GtkToggleAction *histogram_action = GTK_TOGGLE_ACTION(gtk_action_group_get_action(lw->action_group, "ImageHistogram"));
if (channel < 0 || channel >= HCHAN_COUNT) return;
-
+
gtk_toggle_action_set_active(histogram_action, TRUE); /* this calls layout_menu_histogram_cb */
image_osd_histogram_set_channel(lw->image, channel);
}
GtkToggleAction *histogram_action = GTK_TOGGLE_ACTION(gtk_action_group_get_action(lw->action_group, "ImageHistogram"));
if (mode < 0 || mode > 1) return;
-
+
gtk_toggle_action_set_active(histogram_action, TRUE); /* this calls layout_menu_histogram_cb */
image_osd_histogram_set_mode(lw->image, mode);
}
static void layout_menu_bar_exif_cb(GtkAction *action, gpointer data)
{
LayoutWindow *lw = data;
-
+
layout_exit_fullscreen(lw);
layout_exif_window_new(lw);
}
{
LayoutWindow *lw = data;
gint mode = layout_image_stereo_pixbuf_get(lw);
-
+
/* 0->1, 1->2, 2->3, 3->1 - disable auto, then cycle */
mode = mode % 3 + 1;
-
+
GtkAction *radio = gtk_action_group_get_action(lw->action_group, "StereoAuto");
gtk_radio_action_set_current_value(GTK_RADIO_ACTION(radio), mode);
-
+
/*
this is called via fallback in layout_menu_stereo_mode_cb
layout_image_stereo_pixbuf_set(lw, mode);
static void layout_menu_notes_cb(GtkAction *action, gpointer data)
{
LayoutWindow *lw = data;
-
+
layout_exit_fullscreen(lw);
help_window_show("release_notes");
}
}
if (!path) return;
-
+
/* Open previous path */
dir_fd = file_data_new_dir(path);
layout_set_fd(lw, dir_fd);
{
LayoutWindow *lw = data;
const gchar *path;
-
+
if (lw->options.home_path && *lw->options.home_path)
path = lw->options.home_path;
else
{
LayoutWindow *lw = data;
const gchar *key = gtk_action_get_name(action);
-
+
if (!editor_window_flag_set(key))
layout_exit_fullscreen(lw);
g_snprintf(name, sizeof(name), name_tmpl, mark);
g_snprintf(label, sizeof(label), label_tmpl, mark);
-
+
if (accel_tmpl)
g_snprintf(accel, sizeof(accel), accel_tmpl, mark % 10);
else
g_snprintf(tooltip, sizeof(tooltip), tooltip_tmpl, mark);
else
entry.tooltip = NULL;
-
+
gtk_action_group_add_actions(lw->action_group, &entry, 1, lw);
action = gtk_action_group_get_action(lw->action_group, name);
g_object_set_data(G_OBJECT(action), "mark_num", GINT_TO_POINTER(mark));
gchar **split = g_strsplit(editor->menu_path, "/", 0);
gint i = 0;
GList *ret = NULL;
-
+
if (split[0] == NULL)
{
g_strfreev(split);
return NULL;
}
-
+
while (split[i])
{
ret = g_list_prepend(ret, g_strdup(split[i]));
i++;
}
-
+
g_strfreev(split);
-
+
ret = g_list_prepend(ret, g_strdup(editor->key));
-
+
return g_list_reverse(ret);
}
}
to_open = g_list_length(path) - 1;
to_close = g_list_length(old_path) - 1;
-
+
if (to_close > 0)
{
old_path = g_list_last(old_path);
old_path = old_path->prev;
}
-
+
for (i = 0; i < to_close; i++)
{
gchar *name = old_path->data;
}
path = path->next;
}
-
+
if (path)
g_string_append_printf(desc, " <menuitem action='%s'/>", (gchar *)path->data);
}
GList *work;
GList *old_path;
GString *desc;
-
+
if (lw->ui_editors_id)
{
gtk_ui_manager_remove_ui(lw->ui_manager, lw->ui_editors_id);
" <menubar name='MainMenu'>");
editors_list = editor_list_get();
-
+
old_path = NULL;
work = editors_list;
while (work)
editor->hotkey,
editor->comment ? editor->comment : editor->name,
G_CALLBACK(layout_menu_edit_cb) };
-
+
if (editor->icon)
{
entry.stock_id = editor->key;
}
gtk_action_group_add_actions(lw->action_group_editors, &entry, 1, lw);
-
+
path = layout_actions_editor_menu_path(editor);
layout_actions_editor_add(desc, path, old_path);
-
+
string_list_free(old_path);
old_path = path;
work = work->next;
"</ui>" );
error = NULL;
-
+
lw->ui_editors_id = gtk_ui_manager_add_ui_from_string(lw->ui_manager, desc->str, -1, &error);
if (!lw->ui_editors_id)
{
g_error_free(error);
exit(EXIT_FAILURE);
}
-
+
DEBUG_1("%s layout_actions_setup: add toolbar", get_exec_time());
for (i = 0; i < TOOLBAR_COUNT; i++)
{
layout_toolbar_clear(lw, i);
layout_toolbar_add_default(lw, i);
}
-
+
DEBUG_1("%s layout_actions_setup: marks", get_exec_time());
layout_actions_setup_marks(lw);
DEBUG_1("%s layout_actions_setup: status_update_write", get_exec_time());
layout_util_status_update_write(lw);
-
+
DEBUG_1("%s layout_actions_setup: actions_add_window", get_exec_time());
layout_actions_add_window(lw, lw->window);
DEBUG_1("%s layout_actions_setup: end", get_exec_time());
layout_editors_desktop_files = editor_get_desktop_files();
return TRUE;
}
-
+
editor_read_desktop_file(layout_editors_desktop_files->data);
g_free(layout_editors_desktop_files->data);
layout_editors_desktop_files = g_list_delete_link(layout_editors_desktop_files, layout_editors_desktop_files);
-
-
+
+
if (!layout_editors_desktop_files)
{
GList *work;
}
DEBUG_1("%s layout_editors_reload_idle_cb: setup_editors done", get_exec_time());
-
+
layout_editors_reload_idle_id = -1;
return FALSE;
}
editor_table_clear();
layout_editors_reload_idle_id = g_idle_add(layout_editors_reload_idle_cb, NULL);
}
-
+
void layout_editors_reload_finish(void)
{
if (layout_editors_reload_idle_id != -1)
}
string_list_free(lw->toolbar_actions[type]);
lw->toolbar_actions[type] = NULL;
-
+
lw->toolbar_merge_id[type] = gtk_ui_manager_new_merge_id(lw->ui_manager);
}
-
+
void layout_toolbar_add(LayoutWindow *lw, ToolbarType type, const gchar *action)
{
const gchar *path = NULL;
if (!action || !lw->ui_manager) return;
-
+
if (g_list_find_custom(lw->toolbar_actions[type], action, (GCompareFunc)strcmp)) return;
switch (type)
default:
break;
}
-
-
+
+
if (g_str_has_suffix(action, ".desktop"))
{
/* this may be called before the external editors are read
create a dummy action for now */
-
+
if (!lw->action_group_editors)
{
lw->action_group_editors = gtk_action_group_new("MenuActionsExternal");
void layout_toolbar_add_from_config(LayoutWindow *lw, ToolbarType type, const gchar **attribute_names, const gchar **attribute_values)
{
gchar *action = NULL;
-
+
while (*attribute_names)
{
const gchar *option = *attribute_names++;
if (!lw->action_group) return;
if (!layout_image_color_profile_get(lw, &input, &use_image)) return;
-
+
use_color = layout_image_color_profile_get_use(lw);
action = gtk_action_group_get_action(lw->action_group, "UseColorProfiles");
{
sprintf(action_name, "ColorProfile%d", i);
action = gtk_action_group_get_action(lw->action_group, action_name);
-
+
if (i >= COLOR_PROFILE_FILE)
{
const gchar *name = options->color_profile.input_name[i - COLOR_PROFILE_FILE];
action = gtk_action_group_get_action(lw->action_group, "HideToolbar");
gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action), lw->options.toolbar_hidden);
-
+
action = gtk_action_group_get_action(lw->action_group, "ShowInfoPixel");
gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action), lw->options.show_info_pixel);
static void layout_bar_set_default(LayoutWindow *lw)
{
GtkWidget *bar;
-
+
if (!lw->utility_box) return;
bar = bar_new(lw);
-
+
layout_bar_set(lw, bar);
-
+
bar_populate_default(bar);
}
static void layout_bar_sort_set_default(LayoutWindow *lw)
{
GtkWidget *bar;
-
+
if (!lw->utility_box) return;
bar = bar_sort_new_default(lw);
-
+
layout_bar_sort_set(lw, bar);
}
gtk_paned_pack1(GTK_PANED(lw->utility_paned), image, TRUE, FALSE);
gtk_widget_show(lw->utility_paned);
-
+
gtk_widget_show(image);
g_object_ref(lw->utility_box);
void layout_exif_window_new(LayoutWindow *lw)
{
if (lw->exif_window) return;
-
+
lw->exif_window = advanced_exif_new();
if (!lw->exif_window) return;
g_signal_connect(G_OBJECT(lw->exif_window), "destroy",
gint ret;
gint x = 0;
gint y = 0;
-
+
/* LIRC code and corresponding geeqie command (and parameters)*/
gchar *code;
gchar *cmd;
ptr = cmd + 4;
while (g_ascii_isspace(*ptr)) ptr++;
i_parm = atoi(ptr);
-
+
if (i_parm <= 0) i_parm = 1;
x -= i_parm;
}
ptr = cmd + 5;
while (g_ascii_isspace(*ptr)) ptr++;
i_parm = atoi(ptr);
-
+
if (i_parm <= 0) i_parm = 1;
x += i_parm;
}
ptr = cmd + 2;
while (g_ascii_isspace(*ptr)) ptr++;
i_parm = atoi(ptr);
-
+
if (i_parm <= 0) i_parm = 1;
y -= i_parm;
}
ptr = cmd + 4;
while (g_ascii_isspace(*ptr)) ptr++;
i_parm = atoi(ptr);
-
+
if (i_parm <= 0) i_parm = 1;
y += i_parm;
}
ptr = cmd + 7;
while (g_ascii_isspace(*ptr)) ptr++;
fl_parm = atoi(ptr) / 10.0;
-
+
if (fl_parm <= 0.01) fl_parm = get_zoom_increment();
layout_image_zoom_adjust(lw, fl_parm, FALSE);
}
ptr = cmd + 8;
while (g_ascii_isspace(*ptr)) ptr++;
fl_parm = atoi(ptr) / 10.0;
-
+
if (fl_parm <= 0.01) fl_parm = get_zoom_increment();
layout_image_zoom_adjust(lw, -fl_parm, FALSE);
}
ptr = cmd + 8;
while (g_ascii_isspace(*ptr)) ptr++;
i_parm = atoi(ptr);
-
+
if (i_parm <= 0) i_parm = 1;
layout_image_zoom_set(lw, 1.0, FALSE);
}
ptr = cmd + 12;
while (g_ascii_isspace(*ptr)) ptr++;
i_parm = atoi(ptr);
-
+
if (i_parm <= 0) i_parm = 1;
layout_image_zoom_set(lw, -i_parm, FALSE);
}
void layout_image_lirc_init(LayoutWindow *lw)
{
gint flags;
-
+
DEBUG_1("Initializing LIRC...");
lirc_fd = lirc_init(GQ_APPNAME_LC, get_debug_level() > 0);
if (lirc_fd == -1)
GtkWidget *window;
GtkWidget *scrolledwin;
GtkWidget *text;
-
+
GdkColor colors[LOG_COUNT];
guint lines;
GtkTextView *text = GTK_TEXT_VIEW(logwin->text);
GtkTextBuffer *buffer;
GtkTextMark *mark;
-
+
g_assert(logwin != NULL);
buffer = gtk_text_view_get_buffer(text);
{
GList *work = g_list_last(memory);
LogMsg *oldest_msg = work->data;
-
+
g_free(oldest_msg->text);
memory = g_list_delete_link(memory, work);
}
{
GList *prev;
LogMsg *oldest_msg = work->data;
-
+
log_window_insert_text(buffer, &iter, oldest_msg->text, logdefs[oldest_msg->type].tag);
-
+
prev = work->prev;
memory = g_list_delete_link(memory, work);
work = prev;
if (gtk_widget_get_visible(GTK_WIDGET(text)))
{
GtkTextMark *mark;
-
+
mark = gtk_text_buffer_get_mark(buffer, "end");
gtk_text_view_scroll_mark_onscreen(text, mark);
}
path_parsed = g_strdup(dir);
parse_out_relatives(path_parsed);
dir_fd = file_data_new_dir(path_parsed);
-
+
if (filelist_read(dir_fd, &files, NULL))
{
GList *remote_errors = NULL;
gboolean remote_do = FALSE;
gchar *first_dir = NULL;
-
+
command_line = g_new0(CommandLine, 1);
-
+
command_line->argc = argc;
command_line->argv = argv;
if (remote_errors)
{
GList *work = remote_errors;
-
+
printf_term(_("Invalid or ignored remote options: "));
while (work)
{
gchar *opt = work->data;
-
+
printf_term("%s%s", (work == remote_errors) ? "" : ", ", opt);
work = work->next;
}
log_printf(_("error saving file: %s\n"), path);
return FALSE;
}
-
+
gstring = g_string_new("; ");
if (g_get_prgname())
g_string_append(gstring, g_get_prgname());
gdk_threads_enter();
#endif
-
+
/* init execution time counter (debug only) */
init_exec_time();
#endif
exif_init();
-
+
/* setup random seed for random slideshow */
srand(time(NULL));
file_data_register_notify_func(histogram_notify_cb, NULL, NOTIFY_PRIORITY_HIGH);
file_data_register_notify_func(collect_manager_notify_cb, NULL, NOTIFY_PRIORITY_LOW);
file_data_register_notify_func(metadata_notify_cb, NULL, NOTIFY_PRIORITY_LOW);
-
+
gtkrc_load();
buf = g_build_filename(get_rc_dir(), ".command", NULL);
remote_connection = remote_server_init(buf, cd);
g_free(buf);
-
+
DEBUG_1("%s main: gtk_main", get_exec_time());
gtk_main();
#ifdef HAVE_GTHREAD
g_signal_connect(G_OBJECT(item), "destroy", G_CALLBACK(edit_item_destroy_cb), key);
}
}
-
+
g_list_free(editors_list);
}
static void metadata_cache_update(FileData *fd, const gchar *key, const GList *values)
{
GList *work;
-
+
work = fd->cached_metadata;
while (work)
{
GList *entry = work->data;
gchar *entry_key = entry->data;
-
+
if (strcmp(entry_key, key) == 0)
{
/* key found - just replace values */
}
work = work->next;
}
-
+
/* key not found - prepend new entry */
fd->cached_metadata = g_list_prepend(fd->cached_metadata,
g_list_prepend(string_list_copy(values), g_strdup(key)));
static const GList *metadata_cache_get(FileData *fd, const gchar *key)
{
GList *work;
-
+
work = fd->cached_metadata;
while (work)
{
GList *entry = work->data;
gchar *entry_key = entry->data;
-
+
if (strcmp(entry_key, key) == 0)
{
/* key found */
static void metadata_cache_remove(FileData *fd, const gchar *key)
{
GList *work;
-
+
work = fd->cached_metadata;
while (work)
{
GList *entry = work->data;
gchar *entry_key = entry->data;
-
+
if (strcmp(entry_key, key) == 0)
{
/* key found */
{
GList *work;
if (fd->cached_metadata) DEBUG_1("freed %s\n", fd->path);
-
+
work = fd->cached_metadata;
while (work)
{
GList *entry = work->data;
string_list_free(entry);
-
+
work = work->next;
}
g_list_free(fd->cached_metadata);
{
metadata_write_queue = g_list_prepend(metadata_write_queue, fd);
file_data_ref(fd);
-
+
layout_util_status_update_write_all();
}
g_source_remove(metadata_write_idle_id);
metadata_write_idle_id = 0;
}
-
+
if (options->metadata.confirm_after_timeout)
{
metadata_write_idle_id = g_timeout_add(options->metadata.confirm_timeout * 1000, metadata_write_queue_idle_cb, NULL);
fd->modified_xmp = NULL;
metadata_write_queue = g_list_remove(metadata_write_queue, fd);
-
+
file_data_increment_version(fd);
file_data_send_notification(fd, NOTIFY_REREAD);
{
GList *work;
gboolean ret = TRUE;
-
+
work = list;
while (work)
{
if (type & (NOTIFY_REREAD | NOTIFY_CHANGE))
{
metadata_cache_free(fd);
-
+
if (g_list_find(metadata_write_queue, fd))
{
DEBUG_1("Notify metadata: %s %04x", fd->path, type);
{
GList *work;
GList *to_approve = NULL;
-
+
work = metadata_write_queue;
while (work)
{
FileData *fd = work->data;
work = work->next;
-
+
if (!isname(fd->path))
{
/* ignore deleted files */
metadata_write_queue_remove(fd);
continue;
}
-
+
if (fd->change) continue; /* another operation in progress, skip this file for now */
-
+
to_approve = g_list_prepend(to_approve, file_data_ref(fd));
}
file_util_write_metadata(NULL, to_approve, NULL, force_dialog, done_func, done_data);
-
+
return (metadata_write_queue != NULL);
}
{
gboolean success;
ExifData *exif;
-
+
g_assert(fd->change);
-
+
if (fd->change->dest &&
strcmp(extension_from_path(fd->change->dest), GQ_CACHE_EXT_METADATA) == 0)
{
FIXME: this does not catch new sidecars created by independent external programs
*/
file_data_unref(file_data_new_group(fd->change->dest));
-
+
if (success) metadata_legacy_delete(fd, fd->change->dest);
return success;
}
static gboolean metadata_check_key(const gchar *keys[], const gchar *key)
{
const gchar **k = keys;
-
+
while (*k)
{
if (strcmp(key, *k) == 0) return TRUE;
gboolean metadata_write_revert(FileData *fd, const gchar *key)
{
if (!fd->modified_xmp) return FALSE;
-
+
g_hash_table_remove(fd->modified_xmp, key);
-
+
if (g_hash_table_size(fd->modified_xmp) == 0)
{
metadata_write_queue_remove(fd);
fd->modified_xmp = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, (GDestroyNotify)string_list_free);
}
g_hash_table_insert(fd->modified_xmp, g_strdup(key), string_list_copy((GList *)values));
-
+
metadata_cache_remove(fd, key);
-
+
if (fd->exif)
{
exif_update_metadata(fd->exif, key, values);
if (options->metadata.sync_grouped_files && metadata_check_key(group_keys, key))
{
GList *work = fd->sidecar_files;
-
+
while (work)
{
FileData *sfd = work->data;
work = work->next;
-
+
if (filter_file_class(sfd->extension, FORMAT_CLASS_META)) continue;
metadata_write_list(sfd, key, values);
return TRUE;
}
-
+
gboolean metadata_write_string(FileData *fd, const gchar *key, const char *value)
{
GList *list = g_list_append(NULL, g_strdup(value));
gboolean metadata_write_int(FileData *fd, const gchar *key, guint64 value)
{
gchar string[50];
-
+
g_snprintf(string, sizeof(string), "%llu", (unsigned long long) value);
return metadata_write_string(fd, key, string);
}
have_keywords = g_hash_table_lookup_extended(fd->modified_xmp, KEYWORD_KEY, NULL, &keywords);
have_comment = g_hash_table_lookup_extended(fd->modified_xmp, COMMENT_KEY, NULL, &comment_l);
comment = (have_comment && comment_l) ? ((GList *)comment_l)->data : NULL;
-
+
if (!have_keywords || !have_comment) metadata_file_read(metadata_pathl, &orig_keywords, &orig_comment);
-
+
success = metadata_file_write(metadata_pathl,
have_keywords ? (GList *)keywords : orig_keywords,
have_comment ? comment : orig_comment);
g_free(metadata_pathl);
g_free(orig_comment);
string_list_free(orig_keywords);
-
+
return success;
}
if (*ptr == '[' && key != MK_COMMENT)
{
gchar *keystr = ++ptr;
-
+
key = MK_NONE;
while (*ptr != ']' && *ptr != '\n' && *ptr != '\0') ptr++;
-
+
if (*ptr == ']')
{
*ptr = '\0';
}
continue;
}
-
+
switch (key)
{
case MK_NONE:
break;
}
}
-
+
fclose(f);
if (keywords)
{
string_list_free(list);
}
-
+
if (comment_build)
{
if (comment)
gchar *metadata_path;
gchar *metadata_pathl;
gboolean success = FALSE;
-
+
if (!fd) return FALSE;
metadata_path = cache_find_location(CACHE_TYPE_METADATA, fd->path);
{
return g_list_append(NULL, metadata_file_info(fd, key, format));
}
-
+
exif = exif_read_fd(fd); /* this is cached, thus inexpensive */
if (!exif) return NULL;
list = exif_get_metadata(exif, key, format);
exif_free_fd(fd, exif);
-
+
if (format == METADATA_PLAIN && strcmp(key, KEYWORD_KEY) == 0)
{
metadata_cache_update(fd, key, list);
}
-
+
return list;
}
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);
gboolean ok = FALSE;
gchar *string = metadata_read_string(fd, key, METADATA_PLAIN);
if (!string) return fallback;
-
+
deg = g_ascii_strtod(string, &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;
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;
}
-
+
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);
gboolean metadata_append_list(FileData *fd, const gchar *key, const GList *values)
{
GList *list = metadata_read_list(fd, key, METADATA_PLAIN);
-
+
if (!list)
{
return metadata_write_list(fd, key, values);
gboolean ret;
list = g_list_concat(list, string_list_copy(values));
list = remove_duplicate_strings_from_list(list);
-
+
ret = metadata_write_list(fd, key, list);
string_list_free(list);
return ret;
/*
* keywords to marks
*/
-
+
gboolean meta_data_get_keyword_mark(FileData *fd, gint n, gpointer data)
{
GList *path = data;
GList *keywords = NULL;
GtkTreeIter iter;
-
+
if (!keyword_tree_get_iter(GTK_TREE_MODEL(keyword_tree), &iter, path)) return FALSE;
keywords = metadata_read_list(fd, KEYWORD_KEY, METADATA_PLAIN);
{
GtkTreeIter old_kw_iter;
GList *old_path = mark_func_data;
-
+
if (keyword_tree_get_iter(keyword_tree, &old_kw_iter, old_path) &&
(i == mark || /* release any previous connection of given mark */
keyword_compare(keyword_tree, &old_kw_iter, kw_iter) == 0)) /* or given keyword */
gchar *mark_str;
path = keyword_tree_get_path(keyword_tree, kw_iter);
file_data_register_mark_func(mark, meta_data_get_keyword_mark, meta_data_set_keyword_mark, path, (GDestroyNotify)string_list_free);
-
+
mark_str = g_strdup_printf("%d", mark + 1);
gtk_tree_store_set(GTK_TREE_STORE(keyword_tree), kw_iter, KEYWORD_COLUMN_MARK, mark_str, -1);
g_free(mark_str);
{
GtkTreeIter parent_a;
GtkTreeIter parent_b;
-
+
gboolean valid_pa = gtk_tree_model_iter_parent(keyword_tree, &parent_a, a);
gboolean valid_pb = gtk_tree_model_iter_parent(keyword_tree, &parent_b, b);
gboolean toplevel = FALSE;
gboolean ret;
gchar *casefold;
-
+
if (parent_ptr)
{
parent = *parent_ptr;
{
toplevel = TRUE;
}
-
+
if (!gtk_tree_model_iter_children(GTK_TREE_MODEL(keyword_tree), &iter, toplevel ? NULL : &parent)) return FALSE;
-
+
casefold = g_utf8_casefold(name, -1);
ret = FALSE;
-
+
while (TRUE)
{
if (!(exclude_sibling && sibling && keyword_compare(keyword_tree, &iter, sibling) == 0))
void keyword_copy_recursive(GtkTreeStore *keyword_tree, GtkTreeIter *to, GtkTreeIter *from)
{
GtkTreeIter from_child;
-
+
keyword_copy(keyword_tree, to, from);
-
+
if (!gtk_tree_model_iter_children(GTK_TREE_MODEL(keyword_tree), &from_child, from)) return;
-
+
while (TRUE)
{
GtkTreeIter to_child;
{
GList *path = NULL;
GtkTreeIter iter = *iter_ptr;
-
+
while (TRUE)
{
GtkTreeIter parent;
GtkTreeIter iter;
if (!gtk_tree_model_get_iter_first(keyword_tree, &iter)) return FALSE;
-
+
while (TRUE)
{
GtkTreeIter children;
*iter_ptr = iter;
return TRUE;
}
-
+
if (!gtk_tree_model_iter_children(keyword_tree, &children, &iter)) return FALSE;
iter = children;
}
if (!gtk_tree_model_iter_next(keyword_tree, &child)) return FALSE;
}
}
-
+
while (TRUE)
{
GtkTreeIter parent;
g_free(iter_casefold);
if (!found) return FALSE;
}
-
+
if (!gtk_tree_model_iter_parent(keyword_tree, &parent, &iter)) return TRUE;
iter = parent;
}
{
GtkTreeIter child;
keyword_tree_reset1(keyword_tree, iter, kw_list);
-
+
if (!gtk_tree_model_iter_children(keyword_tree, &child, iter)) return;
while (TRUE)
static gboolean keyword_tree_check_empty_children(GtkTreeModel *keyword_tree, GtkTreeIter *parent, GList *kw_list)
{
GtkTreeIter iter;
-
+
if (!gtk_tree_model_iter_children(keyword_tree, &iter, parent))
return TRUE; /* this should happen only on empty helpers */
if (!gtk_tree_model_iter_parent(keyword_tree, &parent, &iter)) return;
iter = parent;
-
+
while (keyword_tree_check_empty_children(keyword_tree, &iter, *kw_list))
{
GtkTreeIter parent;
{
keyword_delete(keyword_tree, &child);
}
-
+
meta_data_connect_mark_with_keyword(GTK_TREE_MODEL(keyword_tree), iter_ptr, -1);
gtk_tree_model_get(GTK_TREE_MODEL(keyword_tree), iter_ptr, KEYWORD_COLUMN_HIDE_IN, &list, -1);
g_list_free(list);
-
+
gtk_tree_store_remove(keyword_tree, iter_ptr);
}
void keyword_tree_new(void)
{
if (keyword_tree) return;
-
+
keyword_tree = gtk_tree_store_new(KEYWORD_COLUMN_COUNT, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_POINTER);
}
GtkTreeIter iter;
WRITE_NL(); WRITE_STRING("<keyword_tree>");
indent++;
-
+
if (keyword_tree && gtk_tree_model_get_iter_first(GTK_TREE_MODEL(keyword_tree), &iter))
{
keyword_tree_node_write_config(GTK_TREE_MODEL(keyword_tree), &iter, outstr, indent);
gint len;
if (!text) return NULL;
-
+
len = strlen(text);
if (!g_utf8_validate(text, len, NULL))
return g_convert(text, len, "UTF-8", "ISO-8859-1", NULL, NULL, NULL);
DEBUG_1("%s : %d\n", msg, retval);
}
-
+
return retval;
#endif
}
options->dnd_icon_size = 48;
options->duplicates_similarity_threshold = 99;
-
+
options->file_filter.disable = FALSE;
options->file_filter.show_dot_directory = FALSE;
options->file_filter.show_hidden_files = FALSE;
options->place_dialogs_under_mouse = FALSE;
options->progressive_key_scrolling = TRUE;
-
+
options->metadata.enable_metadata_dirs = FALSE;
options->metadata.save_in_image_file = FALSE;
options->metadata.save_legacy_IPTC = FALSE;
options->metadata.confirm_on_dir_change = TRUE;
options->metadata.keywords_case_sensitive = FALSE;
options->metadata.write_orientation = TRUE;
-
+
options->show_icon_names = TRUE;
options->slideshow.delay = 50;
options->tree_descend_subdirs = FALSE;
options->update_on_time_change = TRUE;
-
+
options->stereo.fixed_w = 1920;
options->stereo.fixed_h = 1080;
options->stereo.fixed_x1 = 0;
void copy_layout_options(LayoutOptions *dest, const LayoutOptions *src)
{
free_layout_options_content(dest);
-
+
*dest = *src;
dest->id = g_strdup(src->id);
dest->order = g_strdup(src->order);
DEBUG_1("Loading options from %s ... %s", rc_path, success ? "done" : "failed");
g_free(rc_path);
}
-
+
rc_path = g_build_filename(get_rc_dir(), RC_FILE_NAME, NULL);
success = load_config_from_file(rc_path, TRUE);
DEBUG_1("Loading options from %s ... %s", rc_path, success ? "done" : "failed");
struct {
gchar *ext;
} sidecar;
-
+
/* collections */
struct {
gboolean rectangular_selection;
gchar *path;
gchar *options;
} shell;
-
+
/* file sorting */
struct {
SortType method;
gboolean warn_on_write_problems;
gboolean save_legacy_format;
-
+
gboolean sync_grouped_files;
-
+
gboolean confirm_write;
gint confirm_timeout;
gboolean confirm_after_timeout;
gboolean keywords_case_sensitive;
gboolean write_orientation;
} metadata;
-
+
/* Stereo */
struct {
gint mode;;
PanItem *pi;
pi = g_new0(PanItem, 1);
-
+
pi->type = PAN_ITEM_THUMB;
pi->fd = fd;
pi->x = x;
pr = PIXBUF_RENDERER(pw->imd->pr);
fd = pan_menu_click_fd(pw);
-
+
imd_widget = gtk_container_get_focus_child(GTK_CONTAINER(pw->imd->widget));
focused = (pw->fs || (imd_widget && gtk_widget_has_focus(imd_widget)));
on_entry = (gtk_widget_has_focus(pw->path_entry) ||
{
GList *list = NULL;
FileData *fd = pan_menu_click_fd(pw);
-
+
if (fd) list = g_list_prepend(filelist_copy(fd->sidecar_files), file_data_ref(fd));
-
+
return list;
}
submenu_add_edit(menu, &item, G_CALLBACK(pan_edit_cb), pw, editmenu_fd_list);
gtk_widget_set_sensitive(item, active);
-
+
menu_item_add_stock_sensitive(menu, _("View in _new window"), GTK_STOCK_NEW, active,
G_CALLBACK(pan_new_window_cb), pw);
g_cclosure_marshal_VOID__BOXED,
G_TYPE_NONE, 1,
GDK_TYPE_EVENT);
-
+
signals[SIGNAL_UPDATE_PIXEL] =
g_signal_new("update-pixel",
G_OBJECT_CLASS_TYPE(gobject_class),
pr->scroller_id = 0;
pr->scroller_overlay = -1;
-
+
pr->x_mouse = -1;
pr->y_mouse = -1;
pr->norm_center_x = 0.5;
pr->norm_center_y = 0.5;
-
+
pr->stereo_mode = PR_STEREO_NONE;
-
+
pr->renderer = pr_backend_renderer_new(pr);
-
+
pr->renderer2 = NULL;
gtk_widget_set_double_buffered(box, FALSE);
src_x = pr->x_scroll + pr->vis_width / 2;
pr->norm_center_x = (gdouble)src_x / pr->width;
}
-
+
if (pr->height > pr->viewport_height)
{
src_y = pr->y_scroll + pr->vis_height / 2;
new_viewport_height = pr->stereo_fixed_height;
}
}
-
+
if (pr->window_width == new_width && pr->window_height == new_height &&
pr->viewport_width == new_viewport_width && pr->viewport_height == new_viewport_height) return;
pr->y_scroll += y;
pr_scroll_clamp(pr);
-
+
pixbuf_renderer_sync_scroll_center(pr);
-
+
if (pr->x_scroll == old_x && pr->y_scroll == old_y) return;
pr_scroll_notify_signal(pr);
x_off = pr->x_scroll - old_x;
y_off = pr->y_scroll - old_y;
-
+
pr->renderer->scroll(pr->renderer, x_off, y_off);
if (pr->renderer2) pr->renderer2->scroll(pr->renderer2, x_off, y_off);
}
pr->scroller_xpos = bevent->x;
pr->scroller_ypos = bevent->y;
}
-
+
pr->x_mouse = bevent->x;
pr->y_mouse = bevent->y;
pr_update_pixel_signal(pr);
-
+
if (!pr->in_drag || !gdk_pointer_is_grabbed()) return FALSE;
if (pr->drag_moved < PR_DRAG_SCROLL_THRESHHOLD)
}
}
}
-
+
void pr_create_anaglyph(guint mode, GdkPixbuf *pixbuf, GdkPixbuf *right, gint x, gint y, gint w, gint h)
{
if (mode & PR_STEREO_ANAGLYPH_RC)
pr->image_height /= 2;
pr->stereo_pixbuf_offset_left = pr->image_height;
}
-
+
break;
default:
pr->image_width = gdk_pixbuf_get_width(pr->pixbuf);
static void pr_stereo_set(PixbufRenderer *pr)
{
if (!pr->renderer) pr->renderer = pr_backend_renderer_new(pr);
-
+
pr->renderer->stereo_set(pr->renderer, pr->stereo_mode & ~PR_STEREO_MIRROR_RIGHT & ~PR_STEREO_FLIP_RIGHT);
-
+
if (pr->stereo_mode & (PR_STEREO_HORIZ | PR_STEREO_VERT | PR_STEREO_FIXED))
{
if (!pr->renderer2) pr->renderer2 = pr_backend_renderer_new(pr);
gboolean redraw = !(pr->stereo_mode == stereo_mode) || pr->stereo_temp_disable;
pr->stereo_mode = stereo_mode;
if ((stereo_mode & PR_STEREO_TEMP_DISABLE) && pr->stereo_temp_disable) return;
-
+
pr->stereo_temp_disable = FALSE;
-
+
pr_stereo_set(pr);
-
+
if (redraw)
{
pr_size_sync(pr, pr->window_width, pr->window_height); /* recalculate new viewport */
gint p_alpha, prs;
guchar *p_pix, *pp;
gint map_x, map_y, map_w, map_h;
-
+
g_return_val_if_fail(IS_PIXBUF_RENDERER(pr), FALSE);
g_return_val_if_fail(r_mouse != NULL && g_mouse != NULL && b_mouse != NULL, FALSE);
*b_mouse = -1;
return FALSE;
}
-
+
if (!pb) return FALSE;
pr_tile_region_map_orientation(pr->orientation,
if (map_x < 0 || map_x > gdk_pixbuf_get_width(pr->pixbuf) - 1) return FALSE;
if (map_y < 0 || map_y > gdk_pixbuf_get_height(pr->pixbuf) - 1) return FALSE;
-
+
p_alpha = gdk_pixbuf_get_has_alpha(pb);
prs = gdk_pixbuf_get_rowstride(pb);
p_pix = gdk_pixbuf_get_pixels(pb);
*g_mouse = *pp;
pp++;
*b_mouse = *pp;
-
+
return TRUE;
}
gboolean pixbuf_renderer_get_mouse_position(PixbufRenderer *pr, gint *x_pixel_return, gint *y_pixel_return)
{
gint x_pixel, y_pixel, x_pixel_clamped, y_pixel_clamped;
-
+
g_return_val_if_fail(IS_PIXBUF_RENDERER(pr), FALSE);
g_return_val_if_fail(x_pixel_return != NULL && y_pixel_return != NULL, FALSE);
*y_pixel_return = -1;
return FALSE;
}
-
+
x_pixel = floor((gdouble)(pr->x_mouse - pr->x_offset + pr->x_scroll) / pr->scale);
y_pixel = floor((gdouble)(pr->y_mouse - pr->y_offset + pr->y_scroll) / pr->scale / pr->aspect_ratio);
x_pixel_clamped = CLAMP(x_pixel, 0, pr->image_width - 1);
y_pixel_clamped = CLAMP(y_pixel, 0, pr->image_height - 1);
-
+
if(x_pixel != x_pixel_clamped || y_pixel != y_pixel_clamped)
{
/* mouse is not on pr */
*x_pixel_return = x_pixel;
*y_pixel_return = y_pixel;
-
+
return TRUE;
}
gint x_offset; /* offset of image start (non-zero when viewport < window) */
gint y_offset;
-
+
gint x_mouse; /* coordinates of the mouse taken from GtkEvent */
gint y_mouse;
gdouble norm_center_x; /* coordinates of viewport center in the image, in range 0.0 - 1.0 */
gdouble norm_center_y; /* these coordinates are used for PR_SCROLL_RESET_NOCHANGE and should be preserved over periods with NULL pixbuf */
-
+
gdouble subpixel_x_scroll; /* subpixel scroll alignment, used to prevent acumulation of rounding errors */
gdouble subpixel_y_scroll;
gint orientation;
gint stereo_mode;
-
+
StereoPixbufData stereo_data;
gboolean stereo_temp_disable;
gint stereo_fixed_width;
gint stereo_fixed_y_left;
gint stereo_fixed_x_right;
gint stereo_fixed_y_right;
-
+
RendererFuncs *renderer;
RendererFuncs *renderer2;
};
{
static GtkIconFactory *icon_factory = NULL;
GtkIconSet *icon_set;
-
+
if (!icon_factory)
{
icon_factory = gtk_icon_factory_new();
gtk_icon_factory_add_default(icon_factory);
}
-
+
icon_set = gtk_icon_set_new_from_pixbuf(pixbuf);
gtk_icon_factory_add(icon_factory, key, icon_set);
}
GError *error = NULL;
icon_theme = gtk_icon_theme_get_default();
-
+
if (gtk_icon_theme_has_icon(icon_theme, key)) return FALSE;
pixbuf = gtk_icon_theme_load_icon(icon_theme,
g_error_free(error);
error = NULL;
}
-
+
if (strchr(icon, '.'))
{
/* try again without extension */
}
if (!pixbuf) return FALSE;
-
+
register_stock_icon(key, pixbuf);
return TRUE;
}
GdkPixbuf *pixbuf_fallback(FileData *fd, gint requested_width, gint requested_height)
{
GdkPixbuf *pixbuf = pixbuf_inline(PIXBUF_INLINE_BROKEN); /* FIXME use different images according to FORMAT_CLASS */
-
+
if (requested_width && requested_height)
{
gint w = gdk_pixbuf_get_width(pixbuf);
{
GdkPixbuf *dest;
GdkPixbuf *tmp = NULL;
-
+
switch (orientation)
{
case EXIF_ORIENTATION_TOP_LEFT:
current = 6;
if (option & PR_STEREO_HALF) current = 7;
}
-
+
if (add_fixed)
{
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("Fixed position"));
pw->source = print_pref_int(PRINT_PREF_SOURCE, PRINT_SOURCE_SELECTION);
pw->layout = print_pref_int(PRINT_PREF_LAYOUT, PRINT_LAYOUT_IMAGE);
-
+
pw->image_scale = print_pref_double(PRINT_PREF_IMAGE_SCALE, 100.0);
-
+
pw->output = print_pref_int(PRINT_PREF_OUTPUT, PRINT_OUTPUT_PS_LPR);
pw->output_format = print_pref_int(PRINT_PREF_FORMAT, PRINT_FILE_JPG_NORMAL);
else
*n = 0;
}
-
+
return TRUE;
}
*n = l * subunits + r;
g_free(buf);
-
+
return TRUE;
}
GString *outstr;
gint indent = 0;
GList *work;
-
+
rc_pathl = path_from_utf8(utf8_path);
ssi = secure_open(rc_pathl);
g_free(rc_pathl);
WRITE_STRING("<gq>\n");
indent++;
-
+
WRITE_NL(); WRITE_STRING("<global\n");
indent++;
write_global_attributes(outstr, indent + 1);
{
const gchar *option = *attribute_names++;
const gchar *value = *attribute_values++;
-
+
if (strcmp(option, "id") == 0) return value;
}
{
bar_update_from_config(lw->bar, attribute_names, attribute_values);
}
-
+
options_parse_func_push(parser_data, options_parse_bar, NULL, lw->bar);
}
else if (g_ascii_strcasecmp(element_name, "bar_sort") == 0)
options_parse_func_push(parser_data, options_parse_global, options_parse_global_end, NULL);
return;
}
-
+
if (g_ascii_strcasecmp(element_name, "layout") == 0)
{
LayoutWindow *lw;
func_data->start_func = start_func;
func_data->end_func = end_func;
func_data->data = data;
-
+
parser_data->parse_func_stack = g_list_prepend(parser_data->parse_func_stack, func_data);
}
GQParserData *parser_data = user_data;
GQParserFuncData *func = parser_data->parse_func_stack->data;
DEBUG_2("start %s", element_name);
-
+
if (func->start_func)
func->start_func(parser_data, context, element_name, attribute_names, attribute_values, func->data, error);
}
GQParserData *parser_data;
parser_data = g_new0(GQParserData, 1);
-
+
parser_data->startup = startup;
options_parse_func_push(parser_data, options_parse_toplevel, NULL, NULL);
-
+
context = g_markup_parse_context_new(&parser, 0, parser_data, NULL);
if (g_markup_parse_context_parse(context, buf, size, NULL) == FALSE)
ret = FALSE;
DEBUG_1("Parse failed");
}
-
+
g_free(parser_data);
g_markup_parse_context_free(context);
g_free(buf);
return ret;
}
-
+
/* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */
DEBUG_1("HUP detected, closing client.");
DEBUG_1("client count %d", g_list_length(rc->clients));
-
+
g_source_remove(client->channel_id);
close(client->fd);
g_free(client);
}
rc = g_new0(RemoteConnection, 1);
-
+
rc->server = TRUE;
rc->fd = fd;
rc->path = g_strdup(path);
channel = g_io_channel_unix_new(rc->fd);
g_io_channel_set_flags(channel, G_IO_FLAG_NONBLOCK, NULL);
-
+
rc->channel_id = g_io_add_watch_full(channel, G_PRIORITY_DEFAULT, G_IO_IN,
remote_server_read_cb, rc, NULL);
g_io_channel_unref(channel);
ret = FALSE;
}
}
-
+
/* restore the original signal handler */
sigaction(SIGPIPE, &old_action, NULL);
{
gchar *filename = expand_tilde(text);
FileData *fd = file_data_new_group(filename);
-
+
GList *work;
if (fd->parent) fd = fd->parent;
{
gchar *filename = expand_tilde(text);
FileData *fd = file_data_new_group(filename);
-
+
if (fd->change && fd->change->dest)
{
g_io_channel_write_chars(channel, fd->change->dest, -1, NULL, NULL);
{
RemoteConnection *remote_connection = remote_server_open(path);
RemoteData *remote_data = g_new(RemoteData, 1);
-
+
remote_data->command_collection = command_collection;
remote_server_subscribe(remote_connection, remote_cb, remote_data);
RendererFuncs f;
PixbufRenderer *pr;
-
+
gint stereo_mode;
gint stereo_off_x;
gint stereo_off_y;
-
-
+
+
GList *pending_updates;
gint idle_update;
-
+
GList *overlay_list;
-
+
GtkWidget *widget; /* widget and stage may be shared with other renderers */
ClutterActor *stage;
ClutterActor *texture;
ClutterActor *group;
-
+
gboolean clut_updated;
gint64 last_pixbuf_change;
};
GdkPixbuf *tmp_pixbuf;
CoglHandle material;
CoglHandle tex3d;
-
+
DEBUG_0("%s clut start", get_exec_time());
for (r = 0; r < CLUT_SIZE; r++)
PixbufRenderer *pr = rc->pr;
gint anchor_x = 0;
gint anchor_y = 0;
-
+
clutter_actor_set_anchor_point(CLUTTER_ACTOR(rc->texture), 0, 0);
DEBUG_0("scale %d %d", rc->pr->width, rc->pr->height);
DEBUG_0("pos %d %d", rc->pr->x_offset, rc->pr->y_offset);
-
+
clutter_actor_set_scale(CLUTTER_ACTOR(rc->texture),
(gfloat)pr->width / pr->image_width,
(gfloat)pr->height / pr->image_height);
-
+
switch (pr->orientation)
{
case EXIF_ORIENTATION_TOP_LEFT:
/* The other values are out of range */
break;
}
-
+
clutter_actor_set_position(CLUTTER_ACTOR(rc->texture),
pr->x_offset - pr->x_scroll + anchor_x,
pr->y_offset - pr->y_scroll + anchor_y);
{
gfloat x2, y2;
gfloat clip_x, clip_y, clip_w, clip_h, clip_x2, clip_y2;
-
+
x2 = x + w;
y2 = y + h;
-
+
clutter_actor_get_clip(rc->texture, &clip_x, &clip_y, &clip_w, &clip_h);
-
+
clip_x2 = clip_x + clip_w;
clip_y2 = clip_y + clip_h;
-
+
if (clip_x > x) clip_x = x;
if (clip_x2 < x2) clip_x2 = x2;
if (clip_y > y) clip_y = y;
if (clip_y2 < y2) clip_y2 = y2;
-
+
clip_w = clip_x2 - clip_x;
clip_h = clip_y2 - clip_y;
-
+
clutter_actor_set_clip(rc->texture, clip_x, clip_y, clip_w, clip_h);
}
{
RendererClutter *rc = (RendererClutter *)data;
PixbufRenderer *pr = rc->pr;
-
+
RendererClutterAreaParam *par = rc->pending_updates->data;
-
+
gint h = MAX_REGION_AREA / par->w;
if (h == 0) h = 1;
if (h > par->h) h = par->h;
-
-
+
+
DEBUG_0("%s upload start", get_exec_time());
if (pr->pixbuf)
{
CoglHandle texture = clutter_texture_get_cogl_texture(CLUTTER_TEXTURE(rc->texture));
-
+
cogl_texture_set_region(texture,
par->x + GET_RIGHT_PIXBUF_OFFSET(rc),
par->y,
DEBUG_0("%s upload end", get_exec_time());
rc_area_clip_add(rc, par->x, par->y, par->w, h);
-
+
par->y += h;
par->h -= h;
-
+
if (par->h == 0)
{
rc->pending_updates = g_list_remove(rc->pending_updates, par);
gint width = gdk_pixbuf_get_width(pr->pixbuf);
gint height = gdk_pixbuf_get_height(pr->pixbuf);
-
+
if (pr->stereo_data == STEREO_PIXBUF_SBS || pr->stereo_data == STEREO_PIXBUF_CROSS)
{
width /= 2;
}
-
+
if (!pr_clip_region(src_x, src_y, src_w, src_h,
GET_RIGHT_PIXBUF_OFFSET(rc), 0, width, height,
&src_x, &src_y, &src_w, &src_h)) return;
-
+
par = g_new0(RendererClutterAreaParam, 1);
par->rc = rc;
par->x = src_x - GET_RIGHT_PIXBUF_OFFSET(rc);
{
RendererClutter *rc = (RendererClutter *)renderer;
PixbufRenderer *pr = rc->pr;
-
+
DEBUG_0("rc_update_pixbuf");
rc_remove_pending_updates(rc);
rc->last_pixbuf_change = g_get_monotonic_time();
DEBUG_0("%s change time reset", get_exec_time());
-
+
if (pr->pixbuf)
{
gint width = gdk_pixbuf_get_width(pr->pixbuf);
gint height = gdk_pixbuf_get_height(pr->pixbuf);
DEBUG_0("pixbuf size %d x %d (%d)", width, height, gdk_pixbuf_get_has_alpha(pr->pixbuf) ? 32 : 24);
-
+
gint prev_width, prev_height;
-
+
if (pr->stereo_data == STEREO_PIXBUF_SBS || pr->stereo_data == STEREO_PIXBUF_CROSS)
{
width /= 2;
}
-
+
clutter_texture_get_base_size(CLUTTER_TEXTURE(rc->texture), &prev_width, &prev_height);
-
+
if (width != prev_width || height != prev_height)
{
/* FIXME use CoglMaterial with multiple textures for background, color management, anaglyph, ... */
od->x = x;
od->y = y;
od->flags = flags;
-
+
od->actor = gtk_clutter_texture_new();
g_signal_connect (od->actor, "destroy", G_CALLBACK(rc_overlay_actor_destroy_cb), od);
-
+
gtk_clutter_texture_set_from_pixbuf(GTK_CLUTTER_TEXTURE (od->actor), pixbuf, NULL);
clutter_container_add_actor(CLUTTER_CONTAINER(rc->group), od->actor);
rc->stereo_off_x = 0;
rc->stereo_off_y = 0;
-
+
if (rc->stereo_mode & PR_STEREO_RIGHT)
{
if (rc->stereo_mode & PR_STEREO_HORIZ)
clutter_actor_set_size(rc->group, rc->pr->viewport_width, rc->pr->viewport_height);
clutter_actor_set_position(rc->group, rc->stereo_off_x, rc->stereo_off_y);
-
+
clutter_actor_set_rotation(CLUTTER_ACTOR(rc->group),
CLUTTER_Y_AXIS,
(rc->stereo_mode & PR_STEREO_MIRROR) ? 180 : 0,
rc_remove_pending_updates(rc);
rc_overlay_free_all(rc);
-
+
if (widget)
{
/* widget still exists */
RendererFuncs *renderer_clutter_new(PixbufRenderer *pr)
{
RendererClutter *rc = g_new0(RendererClutter, 1);
-
+
rc->pr = pr;
-
+
rc->f.area_changed = rc_area_changed;
rc->f.update_pixbuf = rc_update_pixbuf;
rc->f.free = rc_free;
rc->f.overlay_get = rc_overlay_get;
rc->f.stereo_set = rc_stereo_set;
-
-
+
+
rc->stereo_mode = 0;
rc->stereo_off_x = 0;
rc->stereo_off_y = 0;
rc->pending_updates = NULL;
rc->widget = gtk_bin_get_child(GTK_BIN(rc->pr));
-
+
if (rc->widget)
{
if (!GTK_CLUTTER_IS_EMBED(rc->widget))
rc->widget = gtk_clutter_embed_new();
gtk_container_add(GTK_CONTAINER(rc->pr), rc->widget);
}
-
+
gtk_event_box_set_above_child (GTK_EVENT_BOX(rc->pr), TRUE);
rc->stage = gtk_clutter_embed_get_stage (GTK_CLUTTER_EMBED (rc->widget));
-
+
rc->group = clutter_group_new();
clutter_container_add_actor(CLUTTER_CONTAINER(rc->stage), rc->group);
clutter_actor_set_clip_to_allocation(CLUTTER_ACTOR(rc->group), TRUE);
-
+
rc->texture = clutter_texture_new ();
clutter_container_add_actor(CLUTTER_CONTAINER(rc->group), rc->texture);
rc_set_shader(clutter_texture_get_cogl_material(CLUTTER_TEXTURE(rc->texture)));
g_object_ref(G_OBJECT(rc->widget));
-
+
gtk_widget_show(rc->widget);
return (RendererFuncs *) rc;
}
GList *overlay_list;
cairo_surface_t *overlay_buffer;
-
+
guint draw_idle_id; /* event source id */
GdkPixbuf *spare_tile;
-
+
gint stereo_mode;
gint stereo_off_x;
gint stereo_off_y;
-
+
gint x_scroll; /* allow local adjustment and mirroring */
gint y_scroll;
-
+
};
static void rt_sync_scroll(RendererTiles *rt)
{
PixbufRenderer *pr = rt->pr;
-
+
rt->x_scroll = (rt->stereo_mode & PR_STEREO_MIRROR) ?
pr->width - pr->vis_width - pr->x_scroll
: pr->x_scroll;
-
+
rt->y_scroll = (rt->stereo_mode & PR_STEREO_FLIP) ?
pr->height - pr->vis_height - pr->y_scroll
: pr->y_scroll;
work = work->next;
if (!od->window) rt_overlay_init_window(rt, od);
-
+
rt_overlay_get_position(rt, od, &px, &py, &pw, &ph);
if (pr_clip_region(x, y, w, h, px, py, pw, ph, &rx, &ry, &rw, &rh))
{
cairo_set_source_surface(cr, it->surface, (pr->x_offset + (it->x - rt->x_scroll)) - rx, (pr->y_offset + (it->y - rt->y_scroll)) - ry);
cairo_rectangle(cr, 0, 0, rw, rh);
cairo_fill_preserve(cr);
-
+
gdk_cairo_set_source_pixbuf(cr, od->pixbuf, px - rx, py - ry);
cairo_fill (cr);
cairo_destroy (cr);
-
+
cr = gdk_cairo_create(od->window);
cairo_set_source_surface(cr, rt->overlay_buffer, rx - px, ry - py);
cairo_rectangle (cr, rx - px, ry - py, rw, rh);
cairo_set_source_rgb(cr, 0, 0, 0);
cairo_rectangle(cr, 0, 0, sw, sh);
cairo_fill_preserve(cr);
-
+
gdk_cairo_set_source_pixbuf(cr, od->pixbuf, px - sx, py - sy);
cairo_fill (cr);
cairo_destroy (cr);
-
+
cr = gdk_cairo_create(od->window);
cairo_set_source_surface(cr, rt->overlay_buffer, sx - px, sy - py);
cairo_rectangle (cr, sx - px, sy - py, sw, sh);
gint x, y, w, h;
rt_overlay_get_position(rt, od, &x, &y, &w, &h);
-
+
/* add borders */
x -= x1;
y -= y1;
w += x1 + x2;
h += y1 + y2;
-
+
rt_queue(rt, rt->x_scroll - pr->x_offset + x,
rt->y_scroll - pr->y_offset + y,
w, h,
{
OverlayData *od = work->data;
work = work->next;
-
+
if (!od->window) rt_overlay_init_window(rt, od);
-
+
if (od->flags & OVL_RELATIVE)
{
gint x, y, w, h;
od->flags = flags;
rt_overlay_init_window(rt, od);
-
+
rt->overlay_list = g_list_append(rt->overlay_list, od);
rt_overlay_queue_draw(rt, od, 0, 0, 0, 0);
/* nothing to do */
break;
}
-
+
/* HACK: The pixbuf scalers get kinda buggy(crash) with extremely
* small sizes for anything but GDK_INTERP_NEAREST
*/
static gint rt_get_queued_area(GList *work)
{
gint area = 0;
-
+
while (work)
{
QueueData *qd = work->data;
PixbufRenderer *pr = rt->pr;
gfloat percent;
gint visible_area = pr->vis_width * pr->vis_height;
-
+
if (!pr->loading)
{
/* 2pass prio */
rt->draw_idle_id = g_idle_add_full(G_PRIORITY_DEFAULT_IDLE, rt_queue_draw_idle_cb, rt, NULL);
return FALSE;
}
-
+
if (visible_area == 0)
{
/* not known yet */
{
percent = 100.0 * rt_get_queued_area(rt->draw_queue) / visible_area;
}
-
+
if (percent > 10.0)
{
/* we have enough data for starting intensive redrawing */
rt->draw_idle_id = g_idle_add_full(GDK_PRIORITY_REDRAW, rt_queue_draw_idle_cb, rt, NULL);
return FALSE;
}
-
+
if (percent < 1.0 || force_set)
{
/* queue is (almost) empty, wait 50 ms*/
rt->draw_idle_id = g_timeout_add_full(G_PRIORITY_DEFAULT_IDLE, 50, rt_queue_draw_idle_cb, rt, NULL);
return FALSE;
}
-
+
/* keep the same priority as before */
DEBUG_2("redraw priority: no change %.2f %%", percent);
return TRUE;
}
-
+
static gboolean rt_queue_draw_idle_cb(gpointer data)
{
x -= rt->stereo_off_x;
y -= rt->stereo_off_y;
-
+
rt_border_draw(rt, x, y, w, h);
x = MAX(0, x - pr->x_offset + pr->x_scroll);
rt->stereo_off_x = 0;
rt->stereo_off_y = 0;
-
+
if (rt->stereo_mode & PR_STEREO_RIGHT)
{
if (rt->stereo_mode & PR_STEREO_HORIZ)
RendererFuncs *renderer_tiles_new(PixbufRenderer *pr)
{
RendererTiles *rt = g_new0(RendererTiles, 1);
-
+
rt->pr = pr;
-
+
rt->f.area_changed = renderer_area_changed;
rt->f.update_pixbuf = renderer_update_pixbuf;
rt->f.free = renderer_free;
rt->f.overlay_get = renderer_tiles_overlay_get;
rt->f.stereo_set = renderer_stereo_set;
-
+
rt->tile_width = PR_TILE_SIZE;
rt->tile_height = PR_TILE_SIZE;
rt->tile_cache_max = PR_CACHE_SIZE_DEFAULT;
rt->draw_idle_id = 0;
-
+
rt->stereo_mode = 0;
rt->stereo_off_x = 0;
rt->stereo_off_y = 0;
t = search_result_count(sd, &t_bytes);
s = search_result_selection_count(sd, &s_bytes);
-
+
tt = text_from_size_abrev(t_bytes);
if (s > 0)
sd->match_name_enable = TRUE;
sd->search_similarity = 95;
-
+
if (example_file)
{
sd->search_similarity_path = g_strdup(example_file->path);
if (!(type & NOTIFY_CHANGE) || !fd->change) return;
DEBUG_1("Notify search: %s %04x", fd->path, type);
-
+
switch (fd->change->type)
{
case FILEDATA_CHANGE_MOVE:
static void swap(GPtrArray *array, guint index1, guint index2)
{
gpointer temp = g_ptr_array_index(array, index1);
-
+
g_ptr_array_index(array, index1) = g_ptr_array_index(array, index2);
g_ptr_array_index(array, index2) = temp;
}
ptr_array_random_shuffle(src_array);
g_ptr_array_foreach(src_array, (GFunc) list_prepend, &list);
g_ptr_array_free(src_array, TRUE);
-
+
return list;
}
}
slideshow_list_init(ss, start_index);
-
+
if (ss->lw)
ss->slide_fd = file_data_ref(layout_image_get_fd(ss->lw));
else
{
tl->fd->exif_orientation = metadata_read_int(tl->fd, ORIENTATION_KEY, EXIF_ORIENTATION_TOP_LEFT);
}
-
+
if (tl->fd->exif_orientation != EXIF_ORIENTATION_TOP_LEFT)
{
rotated = pixbuf_apply_orientation(pixbuf, tl->fd->exif_orientation);
tl->cache_hit = FALSE;
thumb_loader_setup(tl, tl->fd);
-
+
g_signal_connect(G_OBJECT(tl->il), "done", (GCallback)thumb_loader_done_cb, tl);
if (!image_loader_start(tl->il))
w = (gdouble)h / ph * pw;
if (w < 1) w = 1;
}
-
+
if (tl->fd)
{
if (tl->fd->thumb_pixbuf) g_object_unref(tl->fd->thumb_pixbuf);
}
if (rotated) g_object_unref(rotated);
-
+
/* save it ? */
if (tl->cache_enable && save)
{
tl->il = NULL;
thumb_loader_set_fallback(tl);
-
+
if (tl->func_error) tl->func_error(tl, tl->data);
}
}
tl = g_new0(ThumbLoader, 1);
-
+
tl->cache_enable = options->thumbnails.enable_caching;
tl->percent_done = 0.0;
tl->max_w = width;
if (sscanf(buffer, "%d %d %d", &width, &height, &depth) == 3)
{
gsize size = width * height;
-
+
data = g_new(guchar, size);
if (data && fread(data, 1, size, file) == size)
{
path = path_from_utf8(thumb_filename);
directory = g_path_get_dirname(path);
name = g_path_get_basename(path);
-
+
thumb_name = g_build_filename(directory, ".xvpics", name, NULL);
-
+
g_free(name);
g_free(directory);
g_free(path);
{
tl->fd->exif_orientation = metadata_read_int(tl->fd, ORIENTATION_KEY, EXIF_ORIENTATION_TOP_LEFT);
}
-
+
if (tl->fd->exif_orientation != EXIF_ORIENTATION_TOP_LEFT)
{
rotated = pixbuf_apply_orientation(pixbuf, tl->fd->exif_orientation);
thumb_loader_std_done_cb(il, data);
return;
}
-
+
DEBUG_1("thumb image error: %s", tl->fd->path);
DEBUG_1(" from: %s", image_loader_get_fd(tl->il)->path);
if (thumb_loader_std_next_source(tl, TRUE)) return;
thumb_loader_std_set_fallback(tl);
-
+
if (tl->func_error) tl->func_error(tl, tl->data);
}
buf = g_strdup_printf(_("Safe delete: %s"), _("off"));
}
}
-
+
return buf;
}
/* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */
NOTIFY_PRIORITY_MEDIUM,
NOTIFY_PRIORITY_LOW
} NotifyPriority;
-
+
typedef enum {
NOTIFY_MARKS = 1 << 1, /* changed marks */
NOTIFY_PIXBUF = 1 << 2, /* image was read into fd->pixbuf */
time_t date;
mode_t mode; /* this is needed at least for notification in view_dir because it is preserved after the file/directory is deleted */
gint sidecar_priority;
-
+
guint marks; /* each bit represents one mark */
guint valid_marks; /* zero bit means that the corresponding mark needs to be reread */
GdkPixbuf *pixbuf; /* full-size image, only complete images, NULL during loading
all FileData with non-NULL pixbuf are referenced by image_cache */
-
+
HistMap *histmap;
gint ref;
gint user_orientation;
gint exif_orientation;
-
+
ExifData *exif;
time_t exifdate;
GHashTable *modified_xmp; // hash table which contains unwritten xmp metadata in format: key->list of string values
GtkWidget *info_details;
GtkWidget *info_zoom;
GtkWidget *info_pixel;
-
+
/* slide show */
SlideShowData *slideshow;
gboolean marks_enabled;
gint active_mark;
gint clicked_mark;
-
+
/* refresh */
guint refresh_idle_id; /* event source id */
time_t time_refresh_set; /* time when refresh_idle_id was set */
void (*stop_func)(FullScreenData *, gpointer);
gpointer stop_data;
-
+
gboolean same_region; /* the returned region will overlap the current location of widget. */
};
GdkModifierType mask;
gint x, y;
GtkAllocation allocation;
-
+
gtk_widget_get_allocation(button, &allocation);
#if GTK_CHECK_VERSION(3,0,0)
name = g_convert(path, -1, "UTF-8", "ISO-8859-1", NULL, NULL, NULL);
string = g_string_append(string, _("\nPreferred encoding appears to be UTF-8, however the file:\n"));
g_string_append_printf(string, "\"%s\"\n", (name) ? name : _("[name not displayable]"));
-
+
if (g_utf8_validate(path, -1, NULL))
g_string_append_printf(string, _("\"%s\" is encoded in valid UTF-8."), (name) ? name : _("[name not displayable]"));
else
if (!home)
home = path_to_utf8(getenv("HOME"));
-
+
if (!home)
home = path_to_utf8(g_get_home_dir());
{
return g_build_filename(homedir(), fallback, NULL);
}
-
+
return path_to_utf8(dir);
}
static const gchar *xdg_data_home = NULL;
if (xdg_data_home) return xdg_data_home;
-
+
xdg_data_home = xdg_dir_get("XDG_DATA_HOME", ".local/share");
return xdg_data_home;
static const gchar *xdg_config_home = NULL;
if (xdg_config_home) return xdg_config_home;
-
+
xdg_config_home = xdg_dir_get("XDG_CONFIG_HOME", ".config");
return xdg_config_home;
static const gchar *xdg_cache_home = NULL;
if (xdg_cache_home) return xdg_cache_home;
-
+
xdg_cache_home = xdg_dir_get("XDG_CACHE_HOME", ".cache");
return xdg_cache_home;
const gchar *get_rc_dir(void)
{
static gchar *rc_dir = NULL;
-
+
if (rc_dir) return rc_dir;
if (USE_XDG)
static gchar *trash_dir = NULL;
if (trash_dir) return trash_dir;
-
+
if (USE_XDG)
{
trash_dir = g_build_filename(xdg_data_home_get(), GQ_APPNAME_LC, GQ_TRASH_DIR, NULL);
fi = fopen(sl, "rb");
if (!fi) goto end;
-
+
/* First we write to a temporary file, then we rename it on success,
and attributes from original file are copied */
randname = g_strconcat(tl, ".tmp_XXXXXX", NULL);
if (!randname) goto end;
-
+
fd = g_mkstemp(randname);
if (fd == -1) goto end;
-
+
fo = fdopen(fd, "wb");
if (!fo) {
close(fd);
continue;
}
}
-
+
if (s != t) path[t] = path[s];
t++;
s++;
p[0] = '\0';
end = FALSE;
}
-
+
if (!isdir(npath))
{
DEBUG_1("creating sub dir:%s", npath);
return FALSE;
}
}
-
+
if (!end) p[0] = G_DIR_SEPARATOR;
}
}
GtkWidget *pref_toolbar_new(GtkWidget *parent_box, GtkToolbarStyle style)
{
GtkWidget *tbar;
-
+
tbar = gtk_toolbar_new();
gtk_toolbar_set_style(GTK_TOOLBAR(tbar), style);
gtk_widget_get_allocation(ds->button, &button_allocation);
gtk_widget_get_allocation(ds->window, &window_allocation);
-
+
x = wx + button_allocation.x + button_allocation.width - window_allocation.width;
y = wy + button_allocation.y + button_allocation.height;
new_directory = g_path_get_dirname(full_path);
else
new_directory = g_strdup(full_path);
-
+
gtk_entry_set_text(GTK_ENTRY(dd->entry), full_path);
dest_populate(dd, new_directory);
gpointer enter_data;
gpointer tab_data;
gpointer tab_append_data;
-
+
GtkWidget *combo;
gboolean has_history;
gchar *history_key;
const gchar *entry_text = gtk_entry_get_text(GTK_ENTRY(td->entry));
const gchar *prefix = filename_from_path(entry_text);
guint prefix_len = strlen(prefix);
-
+
if (strlen(text) < prefix_len || strncmp(text, prefix, prefix_len))
{
/* Hide menu items not matching */
buf[1] = '\0';
gtk_editable_insert_text(GTK_EDITABLE(td->entry), buf, 1, &p);
gtk_editable_set_position(GTK_EDITABLE(td->entry), -1);
-
+
/* Reduce the number of entries in the menu */
td->choices = 0;
gtk_container_foreach(GTK_CONTAINER(widget), tab_completion_iter_menu_items, (gpointer) td);
if (td->choices > 1) return TRUE; /* multiple choices */
if (td->choices > 0) tab_completion_do(td); /* one choice */
}
-
+
/* close the menu */
gtk_menu_popdown(GTK_MENU(widget));
/* doing this does not emit the "selection done" signal, unref it ourselves */
gtk_widget_get_requisition(td->entry, &requisition);
gtk_widget_get_allocation(td->entry, &allocation);
-
+
height = MIN(requisition.height, allocation.height);
if (req.height > monitor.y + monitor.height - *y - height &&
ptr = (gchar *)filename_from_path(entry_dir);
if (ptr > entry_dir) ptr--;
ptr[0] = '\0';
-
+
if (strlen(entry_dir) == 0)
{
g_free(entry_dir);
gchar *local_path = path_from_utf8(path);
uris[i] = g_filename_to_uri(local_path, NULL, NULL);
g_free(local_path);
-
+
i++;
work = work->next;
}
struct _UtilityData {
UtilityType type;
UtilityPhase phase;
-
+
FileData *dir_fd;
GList *content_list;
GList *flist;
-
+
FileData *sel_fd;
GtkWidget *parent;
GenericDialog *gd;
FileDialog *fdlg;
-
+
guint update_idle_id; /* event source id */
guint perform_idle_id; /* event source id */
gboolean with_sidecars; /* operate on grouped or single files; TRUE = use file_data_sc_, FALSE = use file_data_ functions */
-
+
/* alternative dialog parts */
GtkWidget *notebook;
/* data for the operation itself, internal or external */
gboolean external; /* TRUE for external command, FALSE for internal */
-
+
gchar *external_command;
gpointer resume_data;
-
+
FileUtilDoneFunc done_func;
void (*details_func)(UtilityData *ud, FileData *fd);
gboolean (*finalize_func)(FileData *fd);
UtilityData *ud;
ud = g_new0(UtilityData, 1);
-
+
ud->type = type;
ud->phase = UTILITY_PHASE_START;
-
+
return ud;
}
filelist_free(ud->flist);
if (ud->gd) generic_dialog_close(ud->gd);
-
+
g_free(ud->dest_path);
g_free(ud->external_command);
FileData *fd = list->data;
GtkTreeIter iter;
gchar *sidecars;
-
+
sidecars = with_sidecars ? file_data_sc_list_to_string(fd) : NULL;
GdkPixbuf *icon = file_util_get_error_icon(fd, view);
gtk_list_store_append(store, &iter);
gint ret = EDITOR_CB_CONTINUE;
ud->resume_data = resume_data;
-
+
if (EDITOR_ERRORS_BUT_SKIPPED(flags))
{
GString *msg = g_string_new(editor_get_error_str(flags));
else
file_data_apply_ci(fd);
}
-
+
ud->flist = g_list_remove(ud->flist, fd);
-
+
if (ud->finalize_func)
{
ud->finalize_func(fd);
file_data_free_ci(fd);
file_data_unref(fd);
}
-
+
if (!resume_data) /* end of the list */
{
ud->phase = UTILITY_PHASE_DONE;
file_util_dialog_run(ud);
}
-
+
return ret;
}
/* this function was called directly
just setup idle callback and wait until we are called again
*/
-
+
/* this is removed when ud is destroyed */
ud->perform_idle_id = g_idle_add(file_util_perform_ci_internal, ud);
return TRUE;
}
g_assert(ud->flist);
-
+
if (ud->flist)
{
gint ret;
-
+
/* take a single entry each time, this allows better control over the operation */
GList *single_entry = g_list_append(NULL, ud->flist->data);
gboolean last = !ud->flist->next;
EditorFlags status = EDITOR_ERROR_STATUS;
-
+
if (ud->with_sidecars ? file_data_sc_perform_ci(single_entry->data)
: file_data_perform_ci(single_entry->data))
status = 0; /* OK */
-
+
ret = file_util_perform_ci_cb(GINT_TO_POINTER(!last), status, single_entry, ud);
g_list_free(single_entry);
-
+
if (ret == EDITOR_CB_SUSPEND || last) return FALSE;
-
+
if (ret == EDITOR_CB_SKIP)
{
file_util_perform_ci_cb(NULL, EDITOR_ERROR_SKIPPED, ud->flist, ud);
return FALSE;
}
}
-
+
return TRUE;
}
fd = work->data;
work = work->next;
-
+
if (!fail)
{
if ((internal && file_data_sc_perform_ci(fd)) ||
fail = file_data_ref(ud->dir_fd);
}
}
-
+
if (fail)
{
gchar *text;
{
fail = file_data_ref(ud->dir_fd);
}
-
+
work = ud->content_list;
while (work)
fd = work->data;
work = work->next;
-
+
if (!fail)
{
file_data_sc_apply_ci(fd);
}
file_data_sc_free_ci(fd);
}
-
+
if (fail)
{
gchar *text;
(void) file_util_warning_dialog(ud->messages.fail, text, GTK_STOCK_DIALOG_ERROR, NULL);
g_free(text);
}
-
+
break;
}
default:
if (is_valid_editor_command(ud->external_command))
{
EditorFlags flags;
-
+
ud->external = TRUE;
-
+
if (ud->dir_fd)
{
flags = start_editor_from_file_full(ud->external_command, ud->dir_fd, file_util_perform_ci_dir_cb, ud);
static GdkPixbuf *pb_error;
static GdkPixbuf *pb_apply;
gint error;
-
+
if (!pb_warning)
{
pb_warning = gtk_widget_render_icon(widget, GTK_STOCK_DIALOG_WARNING, GTK_ICON_SIZE_MENU, NULL);
{
pb_apply = gtk_widget_render_icon(widget, GTK_STOCK_APPLY, GTK_ICON_SIZE_MENU, NULL);
}
-
+
error = file_data_sc_verify_ci(fd);
-
+
if (!error) return pb_apply;
if (error & CHANGE_ERROR_MASK)
{
gint error = CHANGE_OK;
gchar *desc = NULL;
-
+
if (ud->type != UTILITY_TYPE_CREATE_FOLDER &&
ud->type != UTILITY_TYPE_RENAME_FOLDER)
{
static void file_util_cancel_cb(GenericDialog *gd, gpointer data)
{
UtilityData *ud = data;
-
+
generic_dialog_close(gd);
ud->gd = NULL;
-
+
ud->phase = UTILITY_PHASE_CANCEL;
file_util_dialog_run(ud);
}
static void file_util_discard_cb(GenericDialog *gd, gpointer data)
{
UtilityData *ud = data;
-
+
generic_dialog_close(gd);
ud->gd = NULL;
-
+
ud->phase = UTILITY_PHASE_DISCARD;
file_util_dialog_run(ud);
}
static void file_util_ok_cb(GenericDialog *gd, gpointer data)
{
UtilityData *ud = data;
-
+
generic_dialog_close(gd);
-
+
ud->gd = NULL;
file_util_dialog_run(ud);
static void file_util_fdlg_cancel_cb(FileDialog *fdlg, gpointer data)
{
UtilityData *ud = data;
-
+
file_dialog_close(fdlg);
ud->fdlg = NULL;
-
+
ud->phase = UTILITY_PHASE_CANCEL;
file_util_dialog_run(ud);
}
{
g_free(ud->dest_path);
ud->dest_path = g_strdup(gtk_entry_get_text(GTK_ENTRY(ud->fdlg->entry)));
-
+
switch (ud->type)
{
case UTILITY_TYPE_COPY:
static void file_util_fdlg_ok_cb(FileDialog *fdlg, gpointer data)
{
UtilityData *ud = data;
-
+
file_util_dest_folder_update_path(ud);
if (isdir(ud->dest_path)) file_dialog_sync_history(fdlg, TRUE);
file_dialog_close(fdlg);
-
+
ud->fdlg = NULL;
file_util_dialog_run(ud);
{
FileData *fd;
const gchar *dest = gtk_entry_get_text(GTK_ENTRY(ud->rename_entry));
-
+
gtk_tree_model_get(store, &iter, UTILITY_COLUMN_FD, &fd, -1);
g_assert(ud->with_sidecars); /* sidecars must be renamed too, it would break the pairing otherwise */
file_data_sc_update_ci_rename(fd, dest);
gtk_tree_model_get(store, &iter, UTILITY_COLUMN_FD, &fd, -1);
generic_dialog_image_set(ud->gd, fd);
-
+
ud->sel_fd = fd;
-
+
if (ud->type == UTILITY_TYPE_RENAME)
{
const gchar *name = filename_from_path(fd->change->dest);
{
dir_msg = g_strdup("");
}
-
+
box = generic_dialog_add_message(ud->gd, GTK_STOCK_DIALOG_QUESTION,
ud->messages.question,
dir_msg);
g_free(dir_msg);
-
+
box = pref_group_new(box, TRUE, ud->messages.desc_flist, GTK_ORIENTATION_HORIZONTAL);
ud->listview = file_util_dialog_add_list(box, ud->flist, FALSE, ud->with_sidecars);
fdlg = file_util_file_dlg(ud->messages.title, "dlg_dest_folder", ud->parent,
file_util_fdlg_cancel_cb, ud);
-
+
ud->fdlg = fdlg;
-
+
generic_dialog_add_message(GENERIC_DIALOG(fdlg), NULL, ud->messages.question, NULL);
label = pref_label_new(GENERIC_DIALOG(fdlg)->vbox, _("Choose the destination folder."));
// gtk_tree_view_column_set_visible(column, FALSE);
gtk_tree_view_set_reorderable(GTK_TREE_VIEW(ud->listview), TRUE);
-
+
store = gtk_tree_view_get_model(GTK_TREE_VIEW(ud->listview));
g_signal_connect(G_OBJECT(store), "row_changed",
G_CALLBACK(file_util_rename_preview_order_cb), ud);
ud->notebook = gtk_notebook_new();
-
+
gtk_box_pack_start(GTK_BOX(ud->gd->vbox), ud->notebook, FALSE, FALSE, 0);
gtk_widget_show(ud->notebook);
-
+
page = gtk_vbox_new(FALSE, PREF_PAD_GAP);
gtk_notebook_append_page(GTK_NOTEBOOK(ud->notebook), page, gtk_label_new(_("Manual rename")));
gtk_widget_show(page);
-
+
table = pref_table_new(page, 2, 2, FALSE, FALSE);
pref_table_label(table, 0, 0, _("Original name:"), 1.0);
static void file_util_finalize_all(UtilityData *ud)
{
GList *work = ud->flist;
-
+
if (ud->phase == UTILITY_PHASE_CANCEL) return;
if (ud->phase == UTILITY_PHASE_DONE && !ud->finalize_func) return;
if (ud->phase == UTILITY_PHASE_DISCARD && !ud->discard_func) return;
-
+
while (work)
{
FileData *fd = work->data;
file_data_sc_free_ci(fd);
else
file_data_free_ci(fd);
-
+
file_data_unref(fd);
return TRUE;
}
case UTILITY_PHASE_ENTERING:
file_util_check_ci(ud);
break;
-
+
ud->phase = UTILITY_PHASE_CHECKED;
case UTILITY_PHASE_CHECKED:
file_util_perform_ci(ud);
case UTILITY_PHASE_DISCARD:
file_util_finalize_all(ud);
-
+
/* both DISCARD and DONE finishes the operation for good */
if (ud->done_func)
ud->done_func((ud->phase != UTILITY_PHASE_CANCEL), ud->dest_path, ud->done_data);
-
+
if (ud->with_sidecars)
file_data_sc_free_ci_list(ud->flist);
else
file_data_free_ci_list(ud->flist);
-
+
/* directory content is always handled including sidecars */
file_data_sc_free_ci_list(ud->content_list);
-
+
if (ud->dir_fd) file_data_free_ci(ud->dir_fd);
file_util_data_free(ud);
break;
{
UtilityData *ud = data;
FileData *fd = g_object_get_data(G_OBJECT(gd->dialog), "file_data");
-
+
if (!fd) return;
file_util_exclude_fd(ud, fd);
-
+
if (discard && ud->discard_func) ud->discard_func(fd);
-
+
/* all files were excluded, this has the same effect as pressing the cancel button in the confirmation dialog*/
if (!ud->flist)
{
GString *message = g_string_new("");
gint error;
g_string_append_printf(message, _("File: '%s'\n"), fd->path);
-
+
if (ud->with_sidecars && fd->sidecar_files)
{
GList *work = fd->sidecar_files;
g_string_append(message, _("with sidecar files:\n"));
-
+
while (work)
{
FileData *sfd = work->data;
g_string_append_printf(message, _(" '%s'\n"), sfd->path);
}
}
-
+
g_string_append(message, _("\nStatus: "));
-
+
error = ud->with_sidecars ? file_data_sc_verify_ci(fd) : file_data_verify_ci(fd);
if (error)
GtkWidget *box;
gchar *message;
const gchar *stock_id;
-
+
gd = file_util_gen_dlg(_("File details"), "details", ud->gd->dialog, TRUE, NULL, ud);
generic_dialog_add_button(gd, GTK_STOCK_CLOSE, NULL, file_util_details_dialog_ok_cb, TRUE);
generic_dialog_add_button(gd, GTK_STOCK_REMOVE, _("Exclude file"), file_util_details_dialog_exclude_cb, FALSE);
generic_dialog_add_image(gd, box, fd, NULL, NULL, NULL, FALSE);
gtk_widget_show(gd->dialog);
-
+
g_free(message);
}
gchar *message2;
gint i;
const gchar *stock_id;
-
+
if (fd && fd->modified_xmp)
{
keys = g_hash_table_get_keys(fd->modified_xmp);
}
-
+
g_assert(keys);
-
-
+
+
gd = file_util_gen_dlg(_("Overview of changed metadata"), "details", ud->gd->dialog, TRUE, NULL, ud);
generic_dialog_add_button(gd, GTK_STOCK_CLOSE, NULL, file_util_details_dialog_ok_cb, TRUE);
generic_dialog_add_button(gd, GTK_STOCK_REMOVE, _("Exclude file"), file_util_details_dialog_exclude_cb, FALSE);
gchar *title_f = g_strdup_printf("%s:", title);
gchar *value = metadata_read_string(fd, key, METADATA_FORMATTED);
work = work->next;
-
-
+
+
label = gtk_label_new(title_f);
gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.0);
pref_label_bold(label, TRUE, FALSE);
gtk_widget_show(label);
label = gtk_label_new(value);
-
+
gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.0);
gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
gtk_table_attach(GTK_TABLE(table), label,
gtk_widget_set_size_request(gd->dialog, DIALOG_WIDTH, -1);
gtk_widget_show(gd->dialog);
-
+
g_list_free(keys);
g_free(message1);
g_free(message2);
{
UtilityData *ud;
GList *ungrouped = NULL;
-
+
if (source_fd)
flist = g_list_append(flist, file_data_ref(source_fd));
if (!flist) return;
-
+
flist = file_data_process_groups_in_selection(flist, TRUE, &ungrouped);
-
+
if (!file_data_sc_add_ci_delete_list(flist))
{
file_util_warn_op_in_progress(_("File deletion failed"));
filelist_free(ungrouped);
return;
}
-
+
file_util_mark_ungrouped_files(ungrouped);
filelist_free(ungrouped);
ud = file_util_data_new(UTILITY_TYPE_DELETE);
-
+
ud->phase = phase;
-
+
ud->with_sidecars = TRUE;
ud->dir_fd = NULL;
ud->flist = flist;
ud->content_list = NULL;
ud->parent = parent;
-
+
ud->details_func = file_util_details_dialog;
ud->messages.title = _("Delete");
static void file_util_write_metadata_full(FileData *source_fd, GList *flist, GtkWidget *parent, UtilityPhase phase, FileUtilDoneFunc done_func, gpointer done_data)
{
UtilityData *ud;
-
+
if (source_fd)
flist = g_list_append(flist, file_data_ref(source_fd));
if (!flist) return;
-
+
if (!file_data_add_ci_write_metadata_list(flist))
{
file_util_warn_op_in_progress(_("Can't write metadata"));
}
ud = file_util_data_new(UTILITY_TYPE_WRITE_METADATA);
-
+
ud->phase = phase;
ud->with_sidecars = FALSE; /* operate on individual files, not groups */
ud->flist = flist;
ud->content_list = NULL;
ud->parent = parent;
-
+
ud->done_func = done_func;
ud->done_data = done_data;
-
+
ud->details_func = file_util_write_metadata_details_dialog;
ud->finalize_func = metadata_write_queue_remove;
ud->discard_func = metadata_write_queue_remove;
-
+
ud->messages.title = _("Write metadata");
ud->messages.question = _("Write metadata?");
ud->messages.desc_flist = _("This will write the changed metadata into the following files");
{
UtilityData *ud;
GList *ungrouped = NULL;
-
+
if (source_fd)
flist = g_list_append(flist, file_data_ref(source_fd));
filelist_free(ungrouped);
return;
}
-
+
file_util_mark_ungrouped_files(ungrouped);
filelist_free(ungrouped);
ud->parent = parent;
if (dest_path) ud->dest_path = g_strdup(dest_path);
-
+
ud->messages.title = _("Move");
ud->messages.question = _("Move files?");
ud->messages.desc_flist = _("This will move the following files");
{
UtilityData *ud;
GList *ungrouped = NULL;
-
+
if (source_fd)
flist = g_list_append(flist, file_data_ref(source_fd));
ud->parent = parent;
if (dest_path) ud->dest_path = g_strdup(dest_path);
-
+
ud->messages.title = _("Copy");
ud->messages.question = _("Copy files?");
ud->messages.desc_flist = _("This will copy the following files");
{
UtilityData *ud;
GList *ungrouped = NULL;
-
+
if (source_fd)
flist = g_list_append(flist, file_data_ref(source_fd));
ud->parent = parent;
ud->details_func = file_util_details_dialog;
-
+
ud->messages.title = _("Rename");
ud->messages.question = _("Rename files?");
ud->messages.desc_flist = _("This will rename the following files");
{
UtilityData *ud;
GList *ungrouped = NULL;
-
+
if (editor_no_param(key))
{
gchar *file_directory = NULL;
file_directory = remove_level_from_path(((FileData *)flist->data)->path);
working_directory = file_directory;
}
-
+
/* just start the editor, don't care about files */
start_editor(key, working_directory);
g_free(file_directory);
filelist_free(flist);
return;
}
-
-
+
+
if (source_fd)
{
/* flist is most probably NULL
}
if (!flist) return;
-
+
if (file_util_write_metadata_first(UTILITY_TYPE_FILTER, phase, flist, dest_path, key, parent))
return;
ud = file_util_data_new(UTILITY_TYPE_FILTER);
else
ud = file_util_data_new(UTILITY_TYPE_EDITOR);
-
-
+
+
/* ask for destination if we don't have it */
if (ud->type == UTILITY_TYPE_FILTER && dest_path == NULL) phase = UTILITY_PHASE_START;
-
+
ud->phase = phase;
ud->with_sidecars = TRUE;
-
+
ud->external_command = g_strdup(key);
ud->dir_fd = NULL;
ud->details_func = file_util_details_dialog;
if (dest_path) ud->dest_path = g_strdup(dest_path);
-
+
ud->messages.title = _("Editor");
ud->messages.question = _("Run editor?");
ud->messages.desc_flist = _("This will copy the following files");
GList *dlist;
GList *flist;
GList *work;
-
+
gboolean ok = TRUE;
DEBUG_1("deltree into: %s", fd->path);
{
ok = file_data_sc_add_ci_delete(ud->dir_fd);
}
-
+
if (!ok)
{
work = ud->content_list;
file_data_sc_free_ci(fd);
}
}
-
+
return ok;
}
ud->flist = NULL;
ud->parent = parent;
-
+
ud->messages.title = _("Delete folder");
ud->messages.question = _("Delete symbolic link?");
ud->messages.desc_flist = "";
ud->flist = flist = filelist_sort_path(flist);
ud->parent = parent;
-
+
ud->messages.title = _("Delete folder");
ud->messages.question = _("Delete folder?");
ud->messages.desc_flist = _("The folder contains these files:");
ud->messages.desc_source_fd = _("This will delete the folder.\n"
"The contents of this folder will also be deleted.");
ud->messages.fail = _("File deletion failed");
-
+
if (!file_util_delete_dir_prepare(ud, flist, dlist))
{
gchar *text;
GList *dlist;
GList *flist;
GList *work;
-
+
gboolean ok = TRUE;
if (!filelist_read_lstat(fd, &flist, &dlist))
gboolean ok;
GList *work;
gint orig_len = strlen(ud->dir_fd->path);
-
+
ok = file_util_rename_dir_scan(ud, ud->dir_fd);
-
+
work = ud->content_list;
-
+
while (ok && work)
{
gchar *np;
fd = work->data;
work = work->next;
-
+
g_assert(strncmp(fd->path, ud->dir_fd->path, orig_len) == 0);
-
+
np = g_strconcat(new_path, fd->path + orig_len, NULL);
-
+
ok = file_data_sc_add_ci_rename(fd, np);
-
+
DEBUG_1("Dir rename: %s -> %s", fd->path, np);
g_free(np);
}
-
+
if (ok)
{
ok = file_data_sc_add_ci_rename(ud->dir_fd, new_path);
}
-
+
if (!ok)
{
work = ud->content_list;
return ok;
}
-
+
static void file_util_rename_dir_full(FileData *fd, const gchar *new_path, GtkWidget *parent, UtilityPhase phase, FileUtilDoneFunc done_func, gpointer done_data)
{
ud->done_func = done_func;
ud->done_data = done_data;
ud->dest_path = g_strdup(new_path);
-
+
ud->messages.title = _("Rename");
ud->messages.question = _("Rename folder?");
ud->messages.desc_flist = _("The folder contains the following files");
ud->dest_path = unique_filename(buf, NULL, " ", FALSE);
g_free(buf);
}
-
+
ud->dir_fd = file_data_new_dir(ud->dest_path);
ud->done_func = done_func;
ud->done_data = done_data;
-
+
ud->messages.title = _("Create Folder");
ud->messages.question = _("Create folder?");
ud->messages.desc_flist = "";
static gboolean file_util_write_metadata_first_after_done(gpointer data)
{
UtilityDelayData *dd = data;
-
+
/* start the delayed operation with original arguments */
switch (dd->type)
{
dd->idle_id = g_idle_add(file_util_write_metadata_first_after_done, dd);
return;
}
-
+
/* the operation was cancelled */
filelist_free(dd->flist);
g_free(dd->dest_path);
{
GList *unsaved = NULL;
UtilityDelayData *dd;
-
+
GList *work;
-
+
work = flist;
while (work)
{
FileData *fd = work->data;
work = work->next;
-
+
if (fd->change)
{
filelist_free(unsaved);
return FALSE; /* another op. in progress, let the caller handle it */
}
-
+
if (fd->modified_xmp) /* has unsaved metadata */
{
unsaved = g_list_prepend(unsaved, file_data_ref(fd));
}
}
-
+
if (!unsaved) return FALSE;
-
+
/* save arguments of the original operation */
-
+
dd = g_new0(UtilityDelayData, 1);
-
+
dd->type = type;
dd->phase = phase;
dd->flist = flist;
dd->dest_path = g_strdup(dest_path);
dd->editor_key = g_strdup(editor_key);
dd->parent = parent;
-
+
file_util_write_metadata(NULL, unsaved, parent, FALSE, file_util_write_metadata_first_done, dd);
return TRUE;
}
GString *new;
clipboard = gtk_clipboard_get(GDK_SELECTION_PRIMARY);
-
+
new = g_string_new("");
work = list;
while (work) {
work = work->next;
if (!fd || !*fd->path) continue;
-
+
g_string_append(new, g_shell_quote(fd->path));
if (work) g_string_append_c(new, ' ');
}
-
+
gtk_clipboard_set_text(clipboard, new->str, new->len);
g_string_free(new, TRUE);
filelist_free(list);
static PixmapFolders *folder_icons_new(GtkWidget *widget)
{
PixmapFolders *pf = g_new0(PixmapFolders, 1);
-
+
#if 1
GtkIconSize size = GTK_ICON_SIZE_MENU;
g_free(base);
file_util_rename_dir(fd, new_path, vd->view, vd_rename_finished_cb, vd);
-
+
g_free(new_path);
return FALSE;
const gchar *path;
GList *list;
const gchar *key;
-
+
if (!vd->drop_fd) return;
-
+
key = g_object_get_data(G_OBJECT(widget), "filter_key");
path = vd->drop_fd->path;
const EditorDescription *editor = work->data;
gchar *key;
work = work->next;
-
+
if (!editor_is_filter(editor->key)) continue;
key = g_strdup(editor->key);
item = menu_item_add_sensitive(menu, editor->name, active, G_CALLBACK(vd_drop_menu_filter_cb), vd);
g_object_set_data_full(G_OBJECT(item), "filter_key", key, vd_drop_menu_edit_item_free);
}
-
+
g_list_free(editors_list);
menu_item_add_divider(menu);
g_free(source_base);
}
}
-
+
if (refresh) vd_refresh(vd);
}
GdkPixbuf *pixbuf;
const gchar *date = "";
gboolean done = FALSE;
-
+
fd = work->data;
if (access_file(fd->path, R_OK | X_OK) && fd->name)
if (match == 0) g_warning("multiple fd for the same path");
}
-
+
}
else
{
valid = gtk_list_store_remove(store, &iter);
}
-
+
vd->click_fd = NULL;
vd->drop_fd = NULL;
gtk_tree_view_get_cursor(GTK_TREE_VIEW(vd->view), &old_tpath, NULL);
tpath = gtk_tree_model_get_path(store, &iter);
-
+
if (!old_tpath || gtk_tree_path_compare(tpath, old_tpath) != 0)
{
/* setting the cursor scrolls the view; do not do that unless it is necessary */
gtk_tree_view_set_cursor(GTK_TREE_VIEW(vd->view), tpath, NULL, FALSE);
-
+
/* gtk_tree_view_set_cursor scrolls the window itself, but it sometimes
does not work (switch from dir_list to dir_tree) */
tree_view_row_make_visible(GTK_TREE_VIEW(vd->view), &iter, TRUE);
G_CALLBACK(vficon_pop_menu_show_names_cb), vf);
break;
}
-
+
menu_item_add_stock(menu, _("Re_fresh"), GTK_STOCK_REFRESH, G_CALLBACK(vf_pop_menu_refresh_cb), vf);
return menu;
case FILEVIEW_LIST: ret = vflist_set_fd(vf, dir_fd); break;
case FILEVIEW_ICON: ret = vficon_set_fd(vf, dir_fd); break;
}
-
+
return ret;
}
{
GtkWidget *frame = gtk_frame_new(NULL);
GtkWidget *hbox = gtk_hbox_new(FALSE, 0);
-
+
gint i;
-
+
for (i = 0; i < FILEDATA_MARKS_SIZE ; i++)
{
GtkWidget *check = gtk_check_button_new();
ViewFile *vf;
vf = g_new0(ViewFile, 1);
-
+
vf->type = type;
vf->sort_method = SORT_NAME;
vf->sort_ascend = TRUE;
gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(vf->scrolled), GTK_SHADOW_IN);
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(vf->scrolled),
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
-
+
vf->filter = vf_marks_filter_init(vf);
vf->widget = gtk_vbox_new(FALSE, 0);
gtk_box_pack_start(GTK_BOX(vf->widget), vf->filter, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(vf->widget), vf->scrolled, TRUE, TRUE, 0);
gtk_widget_show(vf->scrolled);
-
+
g_signal_connect(G_OBJECT(vf->widget), "destroy",
G_CALLBACK(vf_destroy_cb), vf);
{
gint count = 0;
gint done = 0;
-
+
switch (vf->type)
{
case FILEVIEW_LIST: vflist_thumb_progress_count(vf->list, &count, &done); break;
case FILEVIEW_ICON: vficon_thumb_progress_count(vf->list, &count, &done); break;
}
-
+
DEBUG_1("thumb progress: %d of %d", done, count);
return (gdouble)done / count;
}
void vf_thumb_update(ViewFile *vf)
{
vf_thumb_stop(vf);
-
+
if (vf->type == FILEVIEW_LIST && !VFLIST(vf)->thumbs_enabled) return;
vf_thumb_status(vf, 0.0, _("Loading thumbs..."));
guint ret = 0;
gint i;
if (!vf->marks_enabled) return 0;
-
+
for (i = 0; i < FILEDATA_MARKS_SIZE ; i++)
{
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(vf->filter_check[i])))
/* FIXME: NOTIFY_METADATA should be checked by the keyword-to-mark functions and converted to NOTIFY_MARKS only if there was a change */
if (!(type & interested) || vf->refresh_idle_id || !vf->dir_fd) return;
-
+
refresh = (fd == vf->dir_fd);
if (!refresh)
g_free(source_base);
}
}
-
+
if (refresh)
{
DEBUG_1("Notify vf: %s %04x", fd->path, type);
FileData *fd = id->fd;
gchar *str = (gchar *) gtk_selection_data_get_text(selection);
GList *kw_list = string_to_keywords_list(str);
-
+
metadata_append_list(fd, KEYWORD_KEY, kw_list);
string_list_free(kw_list);
g_free(str);
{
IconData *id = work->data;
work = work->next;
-
+
VFICON(vf)->selection = g_list_append(VFICON(vf)->selection, id);
vficon_selection_add(vf, id, SELECTION_SELECTED, NULL);
}
g_assert(fd->magick == FD_MAGICK);
list = g_list_prepend(list, file_data_ref(fd));
-
+
work2 = fd->sidecar_files;
while (work2)
{
{
GList *work;
IconData *id = NULL;
-
+
if (sel_fd->parent) sel_fd = sel_fd->parent;
work = vf->list;
-
+
while (work)
{
gint match;
FileData *fd;
-
+
id = work->data;
fd = id->fd;
work = work->next;
match = filelist_sort_compare_filedata_full(fd, sel_fd, vf->sort_method, vf->sort_ascend);
-
+
if (match >= 0) break;
}
-
+
if (id)
{
vficon_select(vf, id);
GList *list;
gtk_tree_model_get(store, iter, FILE_COLUMN_POINTER, &list, -1);
-
+
/* it seems that gtk_list_store_clear may call some callbacks
that use the column. Set the pointer to NULL to be safe. */
gtk_list_store_set(GTK_LIST_STORE(store), iter, FILE_COLUMN_POINTER, NULL, -1);
{
gint i;
gint thumb_width;
-
+
vficon_clear_store(vf);
thumb_width = vficon_get_icon_width(vf);
file_data_ref(first_selected);
g_list_free(VFICON(vf)->selection);
VFICON(vf)->selection = NULL;
-
+
}
FileData *fd = NULL;
FileData *new_fd = NULL;
gint match;
-
+
if (work && work_fd)
{
id = work->data;
fd = id->fd;
-
+
new_fd = work_fd->data;
-
+
if (fd == new_fd)
{
/* not changed, go to next */
}
continue;
}
-
+
match = filelist_sort_compare_filedata_full(fd, new_fd, vf->sort_method, vf->sort_ascend);
if (match == 0) g_warning("multiple fd for the same path");
}
new_fd = work_fd->data;
match = 1;
}
-
+
if (match < 0)
{
/* file no longer exists, delete from vf->list */
vf->list = g_list_insert_before(vf->list, work, id);
else
new_iconlist = g_list_prepend(new_iconlist, id); /* it is faster to append all new entries together later */
-
+
work_fd = work_fd->next;
}
{
vf->list = g_list_concat(vf->list, g_list_reverse(new_iconlist));
}
-
+
VFICON(vf)->selection = g_list_reverse(VFICON(vf)->selection);
filelist_free(new_filelist);
vficon_select_closest(vf, first_selected);
}
file_data_unref(first_selected);
-
+
/* attempt to keep focus on same icon when refreshing */
if (focus_id && g_list_find(vf->list, focus_id))
{
gtk_tree_model_get(tree_model, iter, FILE_COLUMN_POINTER, &list, -1);
id = g_list_nth_data(list, cd->number);
-
+
if (id)
{
GdkColor color_fg;
gchar *disabled_grouping = id->fd->disable_grouping ? _(" [NO GROUPING]") : "";
name_sidecars = g_strdup_printf("%s%s%s", link, id->fd->name, disabled_grouping);
}
-
+
style = gtk_widget_get_style(vf->listview);
if (id->selected & SELECTION_SELECTED)
{
state = GTK_STATE_SELECTED;
}
-
+
memcpy(&color_fg, &style->text[state], sizeof(color_fg));
memcpy(&color_bg, &style->base[state], sizeof(color_bg));
{
shift_color(&color_bg, -1, 0);
}
-
+
g_object_set(cell, "pixbuf", id->fd->thumb_pixbuf,
"text", name_sidecars,
"marks", file_data_get_marks(id->fd),
gtk_tree_view_column_set_cell_data_func(column, renderer, vficon_cell_data_cb, cd, g_free);
gtk_tree_view_append_column(GTK_TREE_VIEW(vf->listview), column);
-
+
g_signal_connect(G_OBJECT(renderer), "toggled", G_CALLBACK(vficon_mark_toggled_cb), vf);
}
ViewFile *vf = data;
vf_refresh_idle_cancel(vf);
-
+
file_data_unregister_notify_func(vf_notify_cb, vf);
tip_unschedule(vf);
/* Add keywords to file */
gchar *str = (gchar *) gtk_selection_data_get_text(selection);
GList *kw_list = string_to_keywords_list(str);
-
+
metadata_append_list(fd, KEYWORD_KEY, kw_list);
string_list_free(kw_list);
g_free(str);
/* check if the row is expanded */
GtkTreeModel *store;
GtkTreeIter iter;
-
+
store = gtk_tree_view_get_model(GTK_TREE_VIEW(vf->listview));
if (vflist_find_row(vf, fd, &iter) >= 0)
{
file_data_unref(fd);
g_free(old_path);
}
-
+
g_free(new_path);
return FALSE;
GtkTreeIter iter;
FileData *fd = NULL;
GtkTreeViewColumn *column;
-
+
vf->clicked_mark = 0;
if (gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(widget), bevent->x, bevent->y,
const gchar *disabled_grouping;
gchar *formatted;
gboolean expanded = FALSE;
-
+
if (fd->sidecar_files) /* expanded has no effect on files without sidecars */
{
gtk_tree_model_get(GTK_TREE_MODEL(store), iter, FILE_COLUMN_EXPANDED, &expanded, -1);
disabled_grouping = fd->disable_grouping ? _(" [NO GROUPING]") : "";
name = g_strdup_printf("%s%s%s", link, fd->name, disabled_grouping);
size = text_from_size(fd->size);
-
+
formatted = vflist_get_formatted(vf, name, sidecars, size, time, expanded);
-
+
gtk_tree_store_set(store, iter, FILE_COLUMN_POINTER, fd,
FILE_COLUMN_VERSION, fd->version,
FILE_COLUMN_THUMB, fd->thumb_pixbuf,
if (match == 0) g_warning("multiple fd for the same path");
}
-
+
}
else
{
vflist_setup_iter(vf, store, &new, file_data_ref(fd));
vflist_setup_iter_recursive(vf, store, &new, fd->sidecar_files, selected, force);
-
+
if (g_list_find(selected, fd))
{
/* renamed files - the same fd appears at different position - select it again*/
valid = gtk_tree_store_remove(store, &iter);
}
-
+
/* move the prepended entries to the correct position */
if (num_prepended)
{
gint i;
gint num_total = num_prepended + num_ordered;
gint *new_order = g_malloc(num_total * sizeof(gint));
-
+
for (i = 0; i < num_total; i++)
{
if (i < num_ordered)
work = work->next;
if (fd->thumb_pixbuf) (*done)++;
-
+
if (fd->sidecar_files)
{
vflist_thumb_progress_count(fd->sidecar_files, count, done);
GtkTreeModel *store;
GtkTreeIter iter;
gboolean valid = TRUE;
-
+
store = gtk_tree_view_get_model(GTK_TREE_VIEW(vf->listview));
gtk_tree_model_get_iter(store, &iter, tpath);
gtk_tree_path_free(tpath);
{
FileData *list_fd = work->data;
if (list_fd == fd) return p;
-
+
work2 = list_fd->sidecar_files;
while (work2)
{
if (sidecar_fd == fd) return p;
work2 = work2->next;
}
-
+
work = work->next;
p++;
}
gtk_tree_model_get(store, &iter, FILE_COLUMN_POINTER, &fd, -1);
list = g_list_prepend(list, file_data_ref(fd));
-
+
if (!fd->parent && !gtk_tree_view_row_expanded(GTK_TREE_VIEW(vf->listview), tpath))
{
/* unexpanded - add whole group */
while (TRUE)
{
GtkTreeIter next = *iter;
-
+
if (gtk_tree_model_iter_next(store, &next))
*iter = next;
else
break;
}
-
+
return TRUE;
}
gtk_tree_selection_unselect_iter(selection, &iter);
else
gtk_tree_selection_select_iter(selection, &iter);
-
+
valid = tree_model_iter_prev(store, &iter);
}
}
{
GList *work;
FileData *fd = NULL;
-
+
if (sel_fd->parent) sel_fd = sel_fd->parent;
work = vf->list;
-
+
while (work)
{
gint match;
work = work->next;
match = filelist_sort_compare_filedata_full(fd, sel_fd, vf->sort_method, vf->sort_ascend);
-
+
if (match >= 0) break;
}
case STM_MODE_TOGGLE: file_data_set_mark(fd, n, !file_data_get_mark(fd, n));
break;
}
-
+
if (!file_data_filter_marks(fd, vf_marks_get_filter(vf))) /* file no longer matches the filter -> remove it */
{
vf_refresh_idle(vf);
vflist_setup_iter_recursive(vf, GTK_TREE_STORE(store), &iter, fd->sidecar_files, NULL, FALSE);
}
-
+
file_data_register_notify_func(vf_notify_cb, vf, NOTIFY_PRIORITY_MEDIUM);
work = work->next;
vflist_listview_set_columns(vf->listview, VFLIST(vf)->thumbs_enabled, vflist_is_multiline(vf));
selected = vflist_selection_get_list(vf);
-
+
vflist_setup_iter_recursive(vf, store, NULL, vf->list, selected, force);
if (selected && vflist_selection_count(vf, NULL) == 0)
}
filelist_free(selected);
-
+
vf_send_update(vf);
vf_thumb_update(vf);
}
gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, FILE_COLUMN_POINTER, &fd, col_idx, &marked, -1);
marked = !marked;
-
+
/* the change has a very limited range and the standard notification would trigger
complete re-read of the directory - try to do only minimal update instead */
file_data_unregister_notify_func(vf_notify_cb, vf);
gint column;
vf->info = g_new0(ViewFileInfoList, 1);
-
+
flist_types[FILE_COLUMN_POINTER] = G_TYPE_POINTER;
flist_types[FILE_COLUMN_VERSION] = G_TYPE_INT;
flist_types[FILE_COLUMN_THUMB] = GDK_TYPE_PIXBUF;
vflist_listview_add_column(vf, FILE_COLUMN_THUMB, "", TRUE, FALSE, FALSE);
g_assert(column == FILE_VIEW_COLUMN_THUMB);
column++;
-
+
vflist_listview_add_column(vf, FILE_COLUMN_FORMATTED, _("Name"), FALSE, FALSE, TRUE);
g_assert(column == FILE_VIEW_COLUMN_FORMATTED);
column++;
if (VFLIST(vf)->thumbs_enabled == enable) return;
VFLIST(vf)->thumbs_enabled = enable;
-
+
/* vflist_populate_view is better than vf_refresh:
- no need to re-read the directory
- force update because the formatted string has changed
if (result)
{
int ret = help_browser_command(result, path);
-
+
if (ret == 0) break;
g_free(result);
result = NULL;