📄 dupe.c
字号:
static gint dupe_item_remove_by_path(DupeWindow *dw, const gchar *path){ DupeItem *di; di = dupe_item_find_path(dw, path); if (!di) return FALSE; dupe_item_remove(dw, di); return TRUE;}static void dupe_files_add(DupeWindow *dw, CollectionData *collection, CollectInfo *info, const gchar *path, gint recurse){ DupeItem *di = NULL; if (info) { di = dupe_item_new(info->path, info->size, info->date); } else if (path) { if (isfile(path)) { di = dupe_item_new(path, filesize(path), filetime(path)); } else if (isdir(path) && recurse) { GList *f, *d; if (path_list(path, &f, &d)) { GList *work; f = path_list_filter(f, FALSE); d = path_list_filter(d, TRUE); work = f; while(work) { dupe_files_add(dw, NULL, NULL, (gchar *)work->data, TRUE); work = work->next; } path_list_free(f); work = d; while(work) { dupe_files_add(dw, NULL, NULL, (gchar *)work->data, TRUE); work = work->next; } path_list_free(d); } } } if (!di) return; if (dw->second_drop) { dupe_second_add(dw, di); } else { dw->list = g_list_prepend(dw->list, di); }}void dupe_window_add_collection(DupeWindow *dw, CollectionData *collection){ CollectInfo *info; info = collection_get_first(collection); while(info) { dupe_files_add(dw, collection, info, NULL, FALSE); info = collection_next_by_info(collection, info); } dupe_check_start(dw);}void dupe_window_add_files(DupeWindow *dw, GList *list, gint recurse){ GList *work; work = list; while(work) { gchar *path = work->data; work = work->next; dupe_files_add(dw, NULL, NULL, path, recurse); } dupe_check_start(dw);}static gint dupe_item_set_path(DupeWindow *dw, const gchar *source, const gchar *dest){ DupeItem *di; di = dupe_item_find_path(dw, source); if (!di) return FALSE; if ( (dw->match_mask & DUPE_MATCH_NAME) || (dw->match_mask & DUPE_MATCH_PATH) ) { /* only effects matches on name or path */ gint second; second = di->second; dupe_item_remove(dw, di); dw->second_drop = second; dupe_files_add(dw, NULL, NULL, dest, FALSE); dw->second_drop = FALSE; dupe_check_start(dw); } else { GtkListStore *store; GtkTreeIter iter; gint row; g_free(di->path); di->path = g_strdup(dest); di->name = filename_from_path(di->path); /* update the listview(s) */ store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(dw->listview))); row = dupe_listview_find_item(store, di, &iter); if (row >= 0) { gtk_list_store_set(store, &iter, DUPE_COLUMN_NAME, di->name, DUPE_COLUMN_PATH, di->path, -1); } if (dw->second_listview) { store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(dw->second_listview))); row = dupe_listview_find_item(store, di, &iter); if (row >= 0) { gtk_list_store_set(store, &iter, 1, di->path, -1); } } } return TRUE;}/* * ------------------------------------------------------------------ * Misc. * ------------------------------------------------------------------ */static GtkWidget *dupe_display_label(GtkWidget *vbox, const gchar *description, const gchar *text){ GtkWidget *hbox; GtkWidget *label; hbox = gtk_hbox_new(FALSE, 10); label = gtk_label_new(description); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); gtk_widget_show(label); label = gtk_label_new(text); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); gtk_widget_show(label); gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); gtk_widget_show(hbox); return label;}static void dupe_display_stats(DupeWindow *dw, DupeItem *di){ GenericDialog *gd; gchar *buf; if (!di) return; gd = file_util_gen_dlg("Image thumbprint debug info", "GQview", "thumbprint", dw->window, TRUE, NULL, NULL); generic_dialog_add_button(gd, GTK_STOCK_CLOSE, NULL, NULL, TRUE); dupe_display_label(gd->vbox, "name:", di->name); buf = text_from_size(di->size); dupe_display_label(gd->vbox, "size:", buf); g_free(buf); dupe_display_label(gd->vbox, "date:", text_from_time(di->date)); buf = g_strdup_printf("%d x %d", di->width, di->height); dupe_display_label(gd->vbox, "dimensions:", buf); g_free(buf); dupe_display_label(gd->vbox, "md5sum:", (di->md5sum) ? di->md5sum : "not generated"); dupe_display_label(gd->vbox, "thumbprint:", (di->simd) ? "" : "not generated"); if (di->simd) { GtkWidget *image; GdkPixbuf *pixbuf; gint x, y; guchar *d_pix; guchar *dp; gint rs; gint sp; pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, 32, 32); rs = gdk_pixbuf_get_rowstride(pixbuf); d_pix = gdk_pixbuf_get_pixels(pixbuf); for (y = 0; y < 32; y++) { dp = d_pix + (y * rs); sp = y * 32; for (x = 0; x < 32; x++) { *(dp++) = di->simd->avg_r[sp + x]; *(dp++) = di->simd->avg_g[sp + x]; *(dp++) = di->simd->avg_b[sp + x]; } } image = gtk_image_new_from_pixbuf(pixbuf); gtk_box_pack_start(GTK_BOX(gd->vbox), image, FALSE, FALSE, 0); gtk_widget_show(image); gdk_pixbuf_unref(pixbuf); } gtk_widget_show(gd->dialog);}static void dupe_window_recompare(DupeWindow *dw){ GtkListStore *store; dupe_check_stop(dw); store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(dw->listview))); gtk_list_store_clear(store); g_list_free(dw->dupes); dw->dupes = NULL; dupe_match_reset_list(dw->list); dupe_match_reset_list(dw->second_list); dupe_check_start(dw);}static void dupe_menu_view(DupeWindow *dw, DupeItem *di, GtkWidget *listview, gint new_window){ if (!di) return; if (di->collection && collection_info_valid(di->collection, di->info)) { if (new_window) { view_window_new_from_collection(di->collection, di->info); } else { layout_image_set_collection(NULL, di->collection, di->info); } } else { if (new_window) { GList *list; list = dupe_listview_get_selection(dw, listview); view_window_new_from_list(list); path_list_free(list); } else { layout_image_set_path(NULL, di->path); } }}static void dupe_window_remove_selection(DupeWindow *dw, GtkWidget *listview){ GtkTreeSelection *selection; GtkTreeModel *store; GtkTreeIter iter; GList *slist; GList *list = NULL; GList *work; selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(listview)); slist = gtk_tree_selection_get_selected_rows(selection, &store); work = slist; while (work) { GtkTreePath *tpath = work->data; DupeItem *di = NULL; gtk_tree_model_get_iter(store, &iter, tpath); gtk_tree_model_get(store, &iter, DUPE_COLUMN_POINTER, &di, -1); if (di) list = g_list_prepend(list, di); work = work->next; } g_list_foreach(slist, (GFunc)gtk_tree_path_free, NULL); g_list_free(slist); dw->color_frozen = TRUE; work = list; while (work) { DupeItem *di; di = work->data; work = work->next; dupe_item_remove(dw, di); } dw->color_frozen = FALSE; g_list_free(list); dupe_listview_realign_colors(dw);}static void dupe_window_edit_selected(DupeWindow *dw, gint n){ GList *list; list = dupe_listview_get_selection(dw, dw->listview); start_editor_from_path_list(n, list); path_list_free(list);}static void dupe_window_collection_from_selection(DupeWindow *dw){ CollectWindow *w; GList *list; list = dupe_listview_get_selection(dw, dw->listview); w = collection_window_new(NULL); collection_table_add_path_list(w->table, list); path_list_free(list);}static void dupe_window_append_file_list(DupeWindow *dw, gint on_second){ GList *list; dw->second_drop = (dw->second_set && on_second); list = layout_list(NULL); dupe_window_add_files(dw, list, FALSE); path_list_free(list);}/* *------------------------------------------------------------------- * main pop-up menu callbacks *------------------------------------------------------------------- */static void dupe_menu_view_cb(GtkWidget *widget, gpointer data){ DupeWindow *dw = data; if (dw->click_item) dupe_menu_view(dw, dw->click_item, dw->listview, FALSE);}static void dupe_menu_viewnew_cb(GtkWidget *widget, gpointer data){ DupeWindow *dw = data; if (dw->click_item) dupe_menu_view(dw, dw->click_item, dw->listview, TRUE);}static void dupe_menu_select_all_cb(GtkWidget *widget, gpointer data){ DupeWindow *dw = data; GtkTreeSelection *selection; selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(dw->listview)); gtk_tree_selection_select_all(selection);}static void dupe_menu_select_none_cb(GtkWidget *widget, gpointer data){ DupeWindow *dw = data; GtkTreeSelection *selection; selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(dw->listview)); gtk_tree_selection_unselect_all(selection);}static void dupe_menu_select_dupes_set1_cb(GtkWidget *widget, gpointer data){ DupeWindow *dw = data; dupe_listview_select_dupes(dw, TRUE);}static void dupe_menu_select_dupes_set2_cb(GtkWidget *widget, gpointer data){ DupeWindow *dw = data; dupe_listview_select_dupes(dw, FALSE);}static void dupe_menu_edit_cb(GtkWidget *widget, gpointer data){ DupeWindow *dw; gint n; dw = submenu_item_get_data(widget); n = GPOINTER_TO_INT(data); if (!dw) return; dupe_window_edit_selected(dw, n);}static void dupe_menu_info_cb(GtkWidget *widget, gpointer data){ DupeWindow *dw = data; info_window_new(NULL, dupe_listview_get_selection(dw, dw->listview));}static void dupe_menu_collection_cb(GtkWidget *widget, gpointer data){ DupeWindow *dw = data; dupe_window_collection_from_selection(dw);}static void dupe_menu_print_cb(GtkWidget *widget, gpointer data){ DupeWindow *dw = data; const gchar *path; path = (dw->click_item) ? dw->click_item->path : NULL; print_window_new(path, dupe_listview_get_selection(dw, dw->listview), dupe_listview_get_path_list(dw, dw->listview), dw->window);}static void dupe_menu_copy_cb(GtkWidget *widget, gpointer data){ DupeWindow *dw = data; file_util_copy(NULL, dupe_listview_get_selection(dw, dw->listview), NULL, dw->window);}static void dupe_menu_move_cb(GtkWidget *widget, gpointer data){ DupeWindow *dw = data; file_util_move(NULL, dupe_listview_get_selection(dw, dw->listview), NULL, dw->window);}static void dupe_menu_rename_cb(GtkWidget *widget, gpointer data){ DupeWindow *dw = data; file_util_rename(NULL, dupe_listview_get_selection(dw, dw->listview), dw->window);}static void dupe_menu_delete_cb(GtkWidget *widget, gpointer data){ DupeWindow *dw = data; file_util_delete(NULL, dupe_listview_get_selection(dw, dw->listview), dw->window);}static void dupe_menu_remove_cb(GtkWidget *widget, gpointer data){ DupeWindow *dw = data; dupe_window_remove_selection(dw, dw->listview);}static void dupe_menu_clear_cb(GtkWidget *widget, gpointer data){ DupeWindow *dw = data; dupe_window_clear(dw);}static void dupe_menu_close_cb(GtkWidget *widget, gpointer data){ DupeWindow *dw = data; dupe_window_close(dw);}static GtkWidget *dupe_menu_popup_main(DupeWindow *dw, DupeItem *di){ GtkWidget *menu; GtkWidget *item; gint on_row; on_row = (di != NULL); menu = popup_menu_short_lived(); menu_item_add_sensitive(menu, _("_View"), on_row, G_CALLBACK(dupe_menu_view_cb), dw); menu_item_add_stock_sensitive(menu, _("View in _new window"), GTK_STOCK_NEW, on_row, G_CALLBACK(dupe_menu_viewnew_cb), dw); menu_item_add_divider(menu); menu_item_add_sensitive(menu, _("Select all"), (dw->dupes != NULL), G_CALLBACK(dupe_menu_select_all_cb), dw); menu_item_add_sensitive(menu, _("Select none"), (dw->dupes != NULL), G_CALLBACK(dupe_menu_select_none_cb), dw); menu_item_add_sensitive(menu, _("Select group _1 duplicates"), (dw->dupes != NULL), G_CALLBACK(dupe_menu_select_dupes_set1_cb), dw); 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); submenu_add_edit(menu, &item, G_CALLBACK(dupe_menu_edit_cb), dw); if (!on_row) gtk_widget_set_sensitive(item, FALSE); menu_item_add_stock_sensitive(menu, _("_Properties"), GTK_STOCK_PROPERTIES, on_row, G_CALLBACK(dupe_menu_info_cb), dw); menu_item_add_stock_sensitive(menu, _("Add to new collection"), GTK_STOCK_INDEX, on_row, G_CALLBACK(dupe_menu_collection_cb), dw); menu_item_add_stock_sensitive(menu, _("Print..."), GTK_STOCK_PRINT, on_row, G_CALLBACK(dupe_menu_print_cb), dw); menu_item_add_divider(menu); menu_item_add_stock_sensitive(menu, _("_Copy..."), GTK_STOCK_COPY, on_row, G_CALLBACK(dupe_menu_copy_cb), dw); menu_item_add_sensitive(menu, _("_Move..."), on_row, G_CALLBACK(dupe_menu_move_cb), dw); menu_item_add_sensitive(menu, _("_Rename..."), on_row, G_CALLBACK(dupe_menu_rename_cb), dw); menu_item_add_stock_sensitive(menu, _("_Delete..."), GTK_STOCK_DELETE, on_row, G_CALLBACK(dupe_menu_delete_cb), dw); menu_item_add_divider(menu); menu_item_add_stock_sensitive(menu, _("Rem_ove"), GTK_STOCK_REMOVE, on_row, G_CALLBACK(dupe_menu_remove_cb), dw); menu_item_add_stock_sensitive(menu, _("C_lear"), GTK_STOCK_CLEAR, (dw->list != NULL), G_CALLBACK(dupe_menu_clear_cb), dw); menu_item_add_divider(menu); menu_item_add_stock(menu, _("Close _window"), GTK_STOCK_CLOSE, G_CALLBACK(dupe_menu_close_cb), dw); return menu;}static gint dupe_listview_press_cb(GtkWidget *widget, GdkEventButton *bevent, gpointer data){ DupeWindow *dw = data;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -