📄 search.c
字号:
/* clear it here, so that the FileData in list is not freed */ gtk_list_store_clear(GTK_LIST_STORE(store)); return g_list_reverse(list);}static gboolean search_result_free_node(GtkTreeModel *store, GtkTreePath *tpath, GtkTreeIter *iter, gpointer data){ FileData *fd; gtk_tree_model_get(store, iter, SEARCH_COLUMN_POINTER, &fd, -1); file_data_free(fd); return FALSE;}static void search_result_clear(SearchData *sd){ GtkListStore *store; store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(sd->result_view))); gtk_tree_model_foreach(GTK_TREE_MODEL(store), search_result_free_node, sd); gtk_list_store_clear(store); sd->click_fd = NULL; thumb_loader_free(sd->thumb_loader); sd->thumb_loader = NULL; sd->thumb_fd = NULL; search_status_update(sd);}static void search_result_remove_item(SearchData *sd, FileData *fd, GtkTreeIter *iter){ GtkTreeModel *store; if (!fd || !iter) return; store = gtk_tree_view_get_model(GTK_TREE_VIEW(sd->result_view)); tree_view_move_cursor_away(GTK_TREE_VIEW(sd->result_view), iter, TRUE); gtk_list_store_remove(GTK_LIST_STORE(store), iter); if (sd->click_fd == fd) sd->click_fd = NULL; if (sd->thumb_fd == fd) sd->thumb_fd = NULL; file_data_free(fd);}static void search_result_remove(SearchData *sd, FileData *fd){ GtkTreeModel *store; GtkTreeIter iter; gint valid; store = gtk_tree_view_get_model(GTK_TREE_VIEW(sd->result_view)); valid = gtk_tree_model_get_iter_first(store, &iter); while (valid) { FileData *fd_n; gtk_tree_model_get(store, &iter, SEARCH_COLUMN_POINTER, &fd_n, -1); if (fd_n == fd) { search_result_remove_item(sd, fd_n, &iter); return; } valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(store), &iter); }}static void search_result_remove_selection(SearchData *sd){ GtkTreeSelection *selection; GtkTreeModel *store; GList *slist; GList *flist = NULL; GList *work; selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(sd->result_view)); slist = gtk_tree_selection_get_selected_rows(selection, &store); work = slist; while (work) { GtkTreePath *tpath = work->data; GtkTreeIter iter; FileData *fd; gtk_tree_model_get_iter(store, &iter, tpath); gtk_tree_model_get(store, &iter, SEARCH_COLUMN_POINTER, &fd, -1); flist = g_list_prepend(flist, fd); work = work->next; } g_list_foreach(slist, (GFunc)gtk_tree_path_free, NULL); g_list_free(slist); work = flist; while (work) { FileData *fd = work->data; work = work->next; search_result_remove(sd, fd); } g_list_free(flist); search_status_update(sd);}static void search_result_edit_selected(SearchData *sd, gint n){ GList *list; list = search_result_selection_list(sd); start_editor_from_path_list(n, list); path_list_free(list);}static void search_result_collection_from_selection(SearchData *sd){ CollectWindow *w; GList *list; list = search_result_selection_list(sd); w = collection_window_new(NULL); collection_table_add_path_list(w->table, list); path_list_free(list);}static gint search_result_update_idle_cb(gpointer data){ SearchData *sd = data; search_status_update(sd); sd->update_idle_id = -1; return FALSE;}static void search_result_update_idle_cancel(SearchData *sd){ if (sd->update_idle_id != -1) g_source_remove(sd->update_idle_id); sd->update_idle_id = -1;}static gboolean search_result_select_cb(GtkTreeSelection *selection, GtkTreeModel *store, GtkTreePath *tpath, gboolean selected, gpointer data){ SearchData *sd = data; if (sd->update_idle_id == -1) { sd->update_idle_id = g_idle_add(search_result_update_idle_cb, sd); } return TRUE;}/* *------------------------------------------------------------------- * result list thumbs *------------------------------------------------------------------- */static void search_result_thumb_step(SearchData *sd);static void search_result_thumb_set(SearchData *sd, FileData *fd, GtkTreeIter *iter){ GtkListStore *store; GtkTreeIter iter_n; store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(sd->result_view))); if (!iter) { if (search_result_find_row(sd, fd, &iter_n) >= 0) iter = &iter_n; } if (iter) gtk_list_store_set(store, iter, SEARCH_COLUMN_THUMB, fd->pixbuf, -1);}static void search_result_thumb_do(SearchData *sd){ FileData *fd; if (!sd->thumb_loader || !sd->thumb_fd) return; fd = sd->thumb_fd; if (fd->pixbuf) g_object_unref(fd->pixbuf); fd->pixbuf = thumb_loader_get_pixbuf(sd->thumb_loader, TRUE); search_result_thumb_set(sd, fd, NULL);}static void search_result_thumb_done_cb(ThumbLoader *tl, gpointer data){ SearchData *sd = data; search_result_thumb_do(sd); search_result_thumb_step(sd);}static void search_result_thumb_step(SearchData *sd){ GtkTreeModel *store; GtkTreeIter iter; FileData *fd = NULL; gint valid; gint row = 0; gint length = 0; if (!sd->thumb_enable) return; store = gtk_tree_view_get_model(GTK_TREE_VIEW(sd->result_view)); valid = gtk_tree_model_get_iter_first(store, &iter); while (!fd && valid) { GdkPixbuf *pixbuf; length++; gtk_tree_model_get(store, &iter, SEARCH_COLUMN_POINTER, &fd, SEARCH_COLUMN_THUMB, &pixbuf, -1); if (pixbuf || fd->pixbuf) { if (!pixbuf) gtk_list_store_set(GTK_LIST_STORE(store), &iter, SEARCH_COLUMN_THUMB, fd->pixbuf, -1); row++; fd = NULL; } valid = gtk_tree_model_iter_next(store, &iter); } if (valid) { while (gtk_tree_model_iter_next(store, &iter)) length++; } if (!fd) { sd->thumb_fd = NULL; thumb_loader_free(sd->thumb_loader); sd->thumb_loader = NULL; search_progress_update(sd, TRUE, -1.0); return; } search_progress_update(sd, FALSE, (gdouble)row/length); sd->thumb_fd = fd; thumb_loader_free(sd->thumb_loader); sd->thumb_loader = thumb_loader_new(thumb_max_width, thumb_max_height); thumb_loader_set_callbacks(sd->thumb_loader, search_result_thumb_done_cb, search_result_thumb_done_cb, NULL, sd); if (!thumb_loader_start(sd->thumb_loader, fd->path)) { search_result_thumb_do(sd); search_result_thumb_step(sd); }}static void search_result_thumb_height(SearchData *sd){ GtkTreeViewColumn *column; GtkCellRenderer *cell; GList *list; column = gtk_tree_view_get_column(GTK_TREE_VIEW(sd->result_view), SEARCH_COLUMN_THUMB - 1); if (!column) return; gtk_tree_view_column_set_fixed_width(column, (sd->thumb_enable) ? thumb_max_width : 4); list = gtk_tree_view_column_get_cell_renderers(column); if (!list) return; cell = list->data; g_list_free(list); g_object_set(G_OBJECT(cell), "height", (sd->thumb_enable) ? thumb_max_height : -1, NULL); gtk_tree_view_columns_autosize(GTK_TREE_VIEW(sd->result_view));}static void search_result_thumb_enable(SearchData *sd, gint enable){ if (sd->thumb_enable == enable) return; if (sd->thumb_enable) { GtkTreeModel *store; GtkTreeIter iter; gint valid; thumb_loader_free(sd->thumb_loader); sd->thumb_loader = NULL; store = gtk_tree_view_get_model(GTK_TREE_VIEW(sd->result_view)); valid = gtk_tree_model_get_iter_first(store, &iter); while (valid) { gtk_list_store_set(GTK_LIST_STORE(store), &iter, SEARCH_COLUMN_THUMB, NULL, -1); valid = gtk_tree_model_iter_next(store, &iter); } search_progress_update(sd, TRUE, -1.0); } sd->thumb_enable = enable; search_result_thumb_height(sd); if (!sd->search_folder_list && !sd->search_file_list) search_result_thumb_step(sd);}/* *------------------------------------------------------------------- * result list menu *------------------------------------------------------------------- */static void sr_menu_view_cb(GtkWidget *widget, gpointer data){ SearchData *sd = data; if (sd->click_fd) layout_image_set_path(NULL, sd->click_fd->path);}static void sr_menu_viewnew_cb(GtkWidget *widget, gpointer data){ SearchData *sd = data; GList *list; list = search_result_selection_list(sd); view_window_new_from_list(list); path_list_free(list);}static void sr_menu_select_all_cb(GtkWidget *widget, gpointer data){ SearchData *sd = data; GtkTreeSelection *selection; selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(sd->result_view)); gtk_tree_selection_select_all(selection);}static void sr_menu_select_none_cb(GtkWidget *widget, gpointer data){ SearchData *sd = data; GtkTreeSelection *selection; selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(sd->result_view)); gtk_tree_selection_unselect_all(selection);}static void sr_menu_edit_cb(GtkWidget *widget, gpointer data){ SearchData *sd; gint n; sd = submenu_item_get_data(widget); n = GPOINTER_TO_INT(data); if (!sd) return; search_result_edit_selected(sd, n);}static void sr_menu_info_cb(GtkWidget *widget, gpointer data){ SearchData *sd = data; info_window_new(NULL, search_result_selection_list(sd));}static void sr_menu_collection_cb(GtkWidget *widget, gpointer data){ SearchData *sd = data; search_result_collection_from_selection(sd);}static void sr_menu_print_cb(GtkWidget *widget, gpointer data){ SearchData *sd = data; const gchar *path; path = (sd->click_fd) ? sd->click_fd->path : NULL; print_window_new(path, search_result_selection_list(sd), search_result_get_path_list(sd), sd->window);}static void sr_menu_copy_cb(GtkWidget *widget, gpointer data){ SearchData *sd = data; file_util_copy(NULL, search_result_selection_list(sd), NULL, sd->window);}static void sr_menu_move_cb(GtkWidget *widget, gpointer data){ SearchData *sd = data; file_util_move(NULL, search_result_selection_list(sd), NULL, sd->window);}static void sr_menu_rename_cb(GtkWidget *widget, gpointer data){ SearchData *sd = data; file_util_rename(NULL, search_result_selection_list(sd), sd->window);}static void sr_menu_delete_cb(GtkWidget *widget, gpointer data){ SearchData *sd = data; file_util_delete(NULL, search_result_selection_list(sd), sd->window);}static void sr_menu_remove_cb(GtkWidget *widget, gpointer data){ SearchData *sd = data; search_result_remove_selection(sd);}static void sr_menu_clear_cb(GtkWidget *widget, gpointer data){ SearchData *sd = data; search_result_clear(sd);}static GtkWidget *search_result_menu(SearchData *sd, gint on_row, gint empty){ GtkWidget *menu; GtkWidget *item; menu = popup_menu_short_lived(); menu_item_add_sensitive(menu, _("_View"), on_row, G_CALLBACK(sr_menu_view_cb), sd); menu_item_add_stock_sensitive(menu, _("View in _new window"), GTK_STOCK_NEW, on_row, G_CALLBACK(sr_menu_viewnew_cb), sd); menu_item_add_divider(menu); menu_item_add_sensitive(menu, _("Select all"), !empty, G_CALLBACK(sr_menu_select_all_cb), sd); menu_item_add_sensitive(menu, _("Select none"), !empty, G_CALLBACK(sr_menu_select_none_cb), sd); menu_item_add_divider(menu); submenu_add_edit(menu, &item, G_CALLBACK(sr_menu_edit_cb), sd); if (!on_row) gtk_widget_set_sensitive(item, FALSE); menu_item_add_stock_sensitive(menu, _("_Properties"), GTK_STOCK_PROPERTIES, on_row, G_CALLBACK(sr_menu_info_cb), sd); menu_item_add_stock_sensitive(menu, _("Add to new collection"), GTK_STOCK_INDEX, on_row, G_CALLBACK(sr_menu_collection_cb), sd); menu_item_add_stock_sensitive(menu, _("Print..."), GTK_STOCK_PRINT, on_row, G_CALLBACK(sr_menu_print_cb), sd); menu_item_add_divider(menu); menu_item_add_stock_sensitive(menu, _("_Copy..."), GTK_STOCK_COPY, on_row, G_CALLBACK(sr_menu_copy_cb), sd); menu_item_add_sensitive(menu, _("_Move..."), on_row, G_CALLBACK(sr_menu_move_cb), sd); menu_item_add_sensitive(menu, _("_Rename..."), on_row, G_CALLBACK(sr_menu_rename_cb), sd); menu_item_add_stock_sensitive(menu, _("_Delete..."), GTK_STOCK_DELETE, on_row, G_CALLBACK(sr_menu_delete_cb), sd); menu_item_add_divider(menu); menu_item_add_stock_sensitive(menu, _("Rem_ove"), GTK_STOCK_REMOVE, on_row, G_CALLBACK(sr_menu_remove_cb), sd); menu_item_add_stock_sensitive(menu, _("C_lear"), GTK_STOCK_CLEAR, !empty, G_CALLBACK(sr_menu_clear_cb), sd); return menu;}static void search_result_menu_pos_cb(GtkMenu *menu, gint *x, gint *y, gboolean *push_in, gpointer data){ SearchData *sd = data; GtkTreePath *tpath; gint cx, cy, cw, ch; gtk_tree_view_get_cursor(GTK_TREE_VIEW(sd->result_view), &tpath, NULL); if (!tpath) return; tree_view_get_cell_clamped(GTK_TREE_VIEW(sd->result_view), tpath, SEARCH_COLUMN_NAME - 1, TRUE, &cx, &cy, &cw, &ch); gtk_tree_path_free(tpath); cy += ch; popup_menu_position_clamp(menu, &cx, &cy, 0); *x = cx; *y = cy;}/* *------------------------------------------------------------------- * result list input *------------------------------------------------------------------- */static gint search_result_press_cb(GtkWidget *widget, GdkEventButton *bevent, gpointer data){ SearchData *sd = data; GtkTreeModel *store; GtkTreePath *tpath; GtkTreeIter iter; FileData *fd = NULL; store = gtk_tree_view_get_model(GTK_TREE_VIEW(widget)); if (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); } sd->click_fd = fd; if (bevent->button == 3) { GtkWidget *menu; menu = search_result_menu(sd, (fd != NULL), (search_result_count(sd, NULL) == 0)); gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, bevent->button, bevent->time);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -