📄 search.c
字号:
} if (!fd) return FALSE; if (bevent->button == 1 && bevent->type == GDK_2BUTTON_PRESS) { layout_image_set_path(NULL, fd->path); } if (bevent->button == 2) return TRUE; if (bevent->button == 3) { if (!search_result_row_selected(sd, fd)) { GtkTreeSelection *selection; selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(widget)); gtk_tree_selection_unselect_all(selection); gtk_tree_selection_select_iter(selection, &iter); tpath = gtk_tree_model_get_path(store, &iter); gtk_tree_view_set_cursor(GTK_TREE_VIEW(widget), tpath, NULL, FALSE); gtk_tree_path_free(tpath); } return TRUE; } if (bevent->button == 1 && bevent->type == GDK_BUTTON_PRESS && !(bevent->state & GDK_SHIFT_MASK ) && !(bevent->state & GDK_CONTROL_MASK ) && search_result_row_selected(sd, fd)) { /* this selection handled on release_cb */ gtk_widget_grab_focus(widget); return TRUE; } return FALSE;}static gint search_result_release_cb(GtkWidget *widget, GdkEventButton *bevent, gpointer data){ SearchData *sd = data; GtkTreeModel *store; GtkTreePath *tpath; GtkTreeIter iter; FileData *fd = NULL; if (bevent->button != 1 && bevent->button != 2) return TRUE; store = gtk_tree_view_get_model(GTK_TREE_VIEW(widget)); if ((bevent->x != 0 || bevent->y != 0) && gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(widget), bevent->x, bevent->y, &tpath, NULL, NULL, NULL)) { gtk_tree_model_get_iter(store, &iter, tpath); gtk_tree_model_get(store, &iter, SEARCH_COLUMN_POINTER, &fd, -1); gtk_tree_path_free(tpath); } if (bevent->button == 2) { if (fd && sd->click_fd == fd) { GtkTreeSelection *selection; selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(widget)); if (search_result_row_selected(sd, fd)) { gtk_tree_selection_unselect_iter(selection, &iter); } else { gtk_tree_selection_select_iter(selection, &iter); } } return TRUE; } if (fd && sd->click_fd == fd && !(bevent->state & GDK_SHIFT_MASK ) && !(bevent->state & GDK_CONTROL_MASK ) && search_result_row_selected(sd, fd)) { GtkTreeSelection *selection; selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(widget)); gtk_tree_selection_unselect_all(selection); gtk_tree_selection_select_iter(selection, &iter); tpath = gtk_tree_model_get_path(store, &iter); gtk_tree_view_set_cursor(GTK_TREE_VIEW(widget), tpath, NULL, FALSE); gtk_tree_path_free(tpath); return TRUE; } return FALSE;}static gint search_result_keypress_cb(GtkWidget *widget, GdkEventKey *event, gpointer data){ SearchData *sd = data; gint stop_signal = FALSE; GtkTreeModel *store; GtkTreeSelection *selection; GList *slist; FileData *fd = NULL; selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(sd->result_view)); slist = gtk_tree_selection_get_selected_rows(selection, &store); if (slist) { GtkTreePath *tpath; GtkTreeIter iter; GList *last; last = g_list_last(slist); tpath = last->data; /* last is newest selected file */ gtk_tree_model_get_iter(store, &iter, tpath); gtk_tree_model_get(store, &iter, SEARCH_COLUMN_POINTER, &fd, -1); } g_list_foreach(slist, (GFunc)gtk_tree_path_free, NULL); g_list_free(slist); if (event->state & GDK_CONTROL_MASK) { gint edit_val = -1; switch (event->keyval) { case '1': edit_val = 0; break; case '2': edit_val = 1; break; case '3': edit_val = 2; break; case '4': edit_val = 3; break; case '5': edit_val = 4; break; case '6': edit_val = 5; break; case '7': edit_val = 6; break; case '8': edit_val = 7; break; case '9': edit_val = 8; break; case '0': edit_val = 9; break; case 'C': case 'c': stop_signal = TRUE; file_util_copy(NULL, search_result_selection_list(sd), NULL, widget); break; case 'M': case 'm': stop_signal = TRUE; file_util_move(NULL, search_result_selection_list(sd), NULL, widget); break; case 'R': case 'r': stop_signal = TRUE; file_util_rename(NULL, search_result_selection_list(sd), widget); break; case 'D': case 'd': stop_signal = TRUE; file_util_delete(NULL, search_result_selection_list(sd), widget); break; case 'P': case 'p': stop_signal = TRUE; info_window_new(NULL, search_result_selection_list(sd)); break; case 'A': case 'a': if (event->state & GDK_SHIFT_MASK) { gtk_tree_selection_unselect_all(selection); } else { gtk_tree_selection_select_all(selection); } stop_signal = TRUE; break; case GDK_Delete: case GDK_KP_Delete: search_result_clear(sd); stop_signal = TRUE; break; default: break; } if (edit_val >= 0) { search_result_edit_selected(sd, edit_val); stop_signal = TRUE; } } else { switch (event->keyval) { case GDK_Return: case GDK_KP_Enter: if (fd) layout_image_set_path(NULL, fd->path); stop_signal = TRUE; break; case 'V': case 'v': { GList *list; list = search_result_selection_list(sd); view_window_new_from_list(list); path_list_free(list); stop_signal = TRUE; } break; case GDK_Delete: case GDK_KP_Delete: search_result_remove_selection(sd); stop_signal = TRUE; break; case 'C': case 'c': search_result_collection_from_selection(sd); stop_signal = TRUE; break; case GDK_Menu: case GDK_F10: { GtkWidget *menu; sd->click_fd = fd; menu = search_result_menu(sd, (fd != NULL), (search_result_count(sd, NULL) > 0)); gtk_menu_popup(GTK_MENU(menu), NULL, NULL, search_result_menu_pos_cb, sd, 0, GDK_CURRENT_TIME); stop_signal = TRUE; } break; default: break; } } return stop_signal;}static gint search_window_keypress_cb(GtkWidget *widget, GdkEventKey *event, gpointer data){ SearchData *sd = data; gint stop_signal = FALSE; if (event->state & GDK_CONTROL_MASK) { switch (event->keyval) { case 'T': case 't': gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(sd->button_thumbs), !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(sd->button_thumbs))); stop_signal = TRUE; break; case 'W': case 'w': search_window_close(sd); stop_signal = TRUE; break; default: break; } } return stop_signal;}/* *------------------------------------------------------------------- * dnd *------------------------------------------------------------------- */static GtkTargetEntry result_drag_types[] = { { "text/uri-list", 0, TARGET_URI_LIST }, { "text/plain", 0, TARGET_TEXT_PLAIN }};static gint n_result_drag_types = 2;static void search_dnd_data_set(GtkWidget *widget, GdkDragContext *context, GtkSelectionData *selection_data, guint info, guint time, gpointer data){ SearchData *sd = data; gchar *uri_text; gint length; GList *list; switch (info) { case TARGET_URI_LIST: case TARGET_TEXT_PLAIN: list = search_result_selection_list(sd); if (!list) return; uri_text = uri_text_from_list(list, &length, (info == TARGET_TEXT_PLAIN)); path_list_free(list); break; default: uri_text = NULL; break; } if (uri_text) gtk_selection_data_set(selection_data, selection_data->target, 8, uri_text, length); g_free(uri_text);}static void search_dnd_begin(GtkWidget *widget, GdkDragContext *context, gpointer data){ SearchData *sd = data; if (sd->click_fd && !search_result_row_selected(sd, sd->click_fd)) { GtkListStore *store; GtkTreeIter iter; store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(widget))); if (search_result_find_row(sd, sd->click_fd, &iter) >= 0) { GtkTreeSelection *selection; GtkTreePath *tpath; selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(widget)); gtk_tree_selection_unselect_all(selection); gtk_tree_selection_select_iter(selection, &iter); tpath = gtk_tree_model_get_path(GTK_TREE_MODEL(store), &iter); gtk_tree_view_set_cursor(GTK_TREE_VIEW(widget), tpath, NULL, FALSE); gtk_tree_path_free(tpath); } } if (sd->thumb_enable && sd->click_fd && sd->click_fd->pixbuf) { dnd_set_drag_icon(widget, context, sd->click_fd->pixbuf, search_result_selection_count(sd, NULL)); }}static void search_dnd_init(SearchData *sd){ gtk_drag_source_set(sd->result_view, GDK_BUTTON1_MASK | GDK_BUTTON2_MASK, result_drag_types, n_result_drag_types, GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK); g_signal_connect(G_OBJECT(sd->result_view), "drag_data_get", G_CALLBACK(search_dnd_data_set), sd); g_signal_connect(G_OBJECT(sd->result_view), "drag_begin", G_CALLBACK(search_dnd_begin), sd);#if 0 g_signal_connect(G_OBJECT(sd->result_view), "drag_end", G_CALLBACK(search_dnd_end), sd);#endif }/* *------------------------------------------------------------------- * search core *------------------------------------------------------------------- */#define MATCH_IS_BETWEEN(val, a, b) (b > a ? (val >= a && val <= b) : (val >= b && val <= a))static gint search_step_cb(gpointer data);static void search_buffer_flush(SearchData *sd){ GList *work; work = g_list_last(sd->search_buffer_list); while (work) { MatchFileData *mfd = work->data; work = work->prev; search_result_append(sd, mfd); } g_list_free(sd->search_buffer_list); sd->search_buffer_list = NULL; sd->search_buffer_count = 0;}static void search_stop(SearchData *sd){ if (sd->search_idle_id != -1) { g_source_remove(sd->search_idle_id); sd->search_idle_id = -1; } image_loader_free(sd->img_loader); sd->img_loader = NULL; cache_sim_data_free(sd->img_cd); sd->img_cd = NULL; cache_sim_data_free(sd->search_similarity_cd); sd->search_similarity_cd = NULL; search_buffer_flush(sd); filelist_free(sd->search_folder_list); sd->search_folder_list = NULL; g_list_free(sd->search_done_list); sd->search_done_list = NULL; filelist_free(sd->search_file_list); sd->search_file_list = NULL; gtk_widget_set_sensitive(sd->box_search, TRUE); spinner_set_interval(sd->spinner, -1); gtk_widget_set_sensitive(sd->button_start, TRUE); gtk_widget_set_sensitive(sd->button_stop, FALSE); search_progress_update(sd, TRUE, -1.0); search_status_update(sd);}static void search_file_load_process(SearchData *sd, CacheData *cd){ GdkPixbuf *pixbuf; pixbuf = image_loader_get_pixbuf(sd->img_loader); if (cd && pixbuf) { if (!cd->dimensions) { cache_sim_data_set_dimensions(cd, gdk_pixbuf_get_width(pixbuf), gdk_pixbuf_get_height(pixbuf)); } if (sd->match_similarity_enable && !cd->similarity) { ImageSimilarityData *sim; sim = image_sim_new_from_pixbuf(pixbuf); cache_sim_data_set_similarity(cd, sim); image_sim_free(sim); } if (enable_thumb_caching && sd->img_loader && sd->img_loader->path) { gchar *base; const gchar *path; mode_t mode = 0755; path = sd->img_loader->path; base = cache_get_location(CACHE_TYPE_SIM, path, FALSE, &mode); if (cache_ensure_dir_exists(base, mode)) { g_free(cd->path); cd->path = cache_get_location(CACHE_TYPE_SIM, path, TRUE, NULL); if (cache_sim_data_save(cd)) { filetime_set(cd->path, filetime(sd->img_loader->path)); } } g_free(base); } } image_loader_free(sd->img_loader); sd->img_loader = NULL; sd->search_idle_id = g_idle_add(search_step_cb, sd);}static void search_file_load_done_cb(ImageLoader *il, gpointer data){ SearchData *sd = data; search_file_load_process(sd, sd->img_cd);}static gint search_file_do_extra(SearchData *sd, FileData *fd, gint *match, gint *width, gint *height, gint *simval){ gint new_data = FALSE; gint tmatch = TRUE; gint tested = FALSE; if (!sd->img_cd) { gchar *cd_path; new_data = TRUE; cd_path = cache_find_location(CACHE_TYPE_SIM, fd->path); if (cd_path && filetime(fd->path) == filetime(cd_path)) { sd->img_cd = cache_sim_data_load(cd_path); } g_free(cd_path); } if (!sd->img_cd) { sd->img_cd = cache_sim_data_new(); } if (new_data) { if ((sd->match_dimensions_enable && !sd->img_cd->dimensions) || (sd->match_similarity_enable && !sd->img_cd->similarity)) { sd->img_loader = image_loader_new(fd->path); image_loader_set_error_func(sd->img_loader, search_file_load_done_cb, sd); if (image_loader_start(sd->img_loader, search_file_load_done_cb, sd)) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -