📄 collect-table.c
字号:
/* * GQview * (C) 2004 John Ellis * * Author: John Ellis * * This software is released under the GNU General Public License (GNU GPL). * Please read the included file COPYING for more information. * This software comes with no warranty of any kind, use at your own risk! */#include "gqview.h"#include "collect-table.h"#include "cellrenderericon.h"#include "collect-dlg.h"#include "collect-io.h"#include "dnd.h"#include "dupe.h"#include "editors.h"#include "filelist.h"#include "img-view.h"#include "info.h"#include "layout.h"#include "layout_image.h"#include "menu.h"#include "print.h"#include "utilops.h"#include "ui_bookmark.h"#include "ui_fileops.h"#include "ui_menu.h"#include "ui_tree_edit.h"#include "icons/marker.xpm"#define MARKER_WIDTH 26#define MARKER_HEIGHT 32#include <gdk/gdkkeysyms.h> /* for keyboard values *//* between these, the icon width is increased by thumb_max_width / 2 */#define THUMB_MIN_ICON_WIDTH 128#define THUMB_MAX_ICON_WIDTH 150#define COLLECT_TABLE_MAX_COLUMNS 32#define THUMB_BORDER_PADDING 2#define COLLECT_TABLE_TIP_DELAY 500enum { CTABLE_COLUMN_POINTER = 0, CTABLE_COLUMN_COUNT};typedef enum { SELECTION_NONE = 0, SELECTION_SELECTED = 1 << 0, SELECTION_PRELIGHT = 1 << 1, SELECTION_FOCUS = 1 << 2} SelectionType;#define INFO_SELECTED(x) (x->flag_mask & SELECTION_SELECTED)static void collection_table_populate_at_new_size(CollectTable *ct, gint w, gint h, gint force);/* *------------------------------------------------------------------- * more misc *------------------------------------------------------------------- */static gint collection_table_find_position(CollectTable *ct, CollectInfo *info, gint *row, gint *col){ gint n; n = g_list_index(ct->cd->list, info); if (n < 0) return FALSE; *row = n / ct->columns; *col = n - (*row * ct->columns); return TRUE;}static gint collection_table_find_iter(CollectTable *ct, CollectInfo *info, GtkTreeIter *iter, gint *column){ GtkTreeModel *store; gint row, col; store = gtk_tree_view_get_model(GTK_TREE_VIEW(ct->listview)); if (!collection_table_find_position(ct, info, &row, &col)) return FALSE; if (!gtk_tree_model_iter_nth_child(store, iter, NULL, row)) return FALSE; if (column) *column = col; return TRUE;}static CollectInfo *collection_table_find_data(CollectTable *ct, gint row, gint col, GtkTreeIter *iter){ GtkTreeModel *store; GtkTreeIter p; if (row < 0 || col < 0) return NULL; store = gtk_tree_view_get_model(GTK_TREE_VIEW(ct->listview)); if (gtk_tree_model_iter_nth_child(store, &p, NULL, row)) { GList *list; gtk_tree_model_get(store, &p, CTABLE_COLUMN_POINTER, &list, -1); if (!list) return NULL; if (iter) *iter = p; return g_list_nth_data(list, col); } return NULL;}static CollectInfo *collection_table_find_data_by_coord(CollectTable *ct, gint x, gint y, GtkTreeIter *iter){ GtkTreePath *tpath; GtkTreeViewColumn *column; if (gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(ct->listview), x, y, &tpath, &column, NULL, NULL)) { GtkTreeModel *store; GtkTreeIter row; GList *list; gint n; store = gtk_tree_view_get_model(GTK_TREE_VIEW(ct->listview)); gtk_tree_model_get_iter(store, &row, tpath); gtk_tree_path_free(tpath); gtk_tree_model_get(store, &row, CTABLE_COLUMN_POINTER, &list, -1); n = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(column), "column_number")); if (list) { if (iter) *iter = row; return g_list_nth_data(list, n); } } return NULL;}static void collection_table_update_status(CollectTable *ct){ if (ct->status_label) { gchar *buf; if (!ct->cd->list) { buf = g_strdup(_("Empty")); } else if (ct->selection) { buf = g_strdup_printf(_("%d images (%d)"), g_list_length(ct->cd->list), g_list_length(ct->selection)); } else { buf = g_strdup_printf(_("%d images"), g_list_length(ct->cd->list)); } gtk_label_set_text(GTK_LABEL(ct->status_label), buf); g_free(buf); }}static void collection_table_update_extras(CollectTable *ct, gint loading, gdouble value){ if (ct->extra_label) { gchar *text; if (loading) text = _("Loading thumbs..."); else text = " "; gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(ct->extra_label), value); gtk_progress_bar_set_text(GTK_PROGRESS_BAR(ct->extra_label), text); }}static void collection_table_toggle_filenames(CollectTable *ct){ ct->show_text = !ct->show_text; show_icon_names = ct->show_text; collection_table_populate_at_new_size(ct, ct->listview->allocation.width, ct->listview->allocation.height, TRUE);}static gint collection_table_get_icon_width(CollectTable *ct){ gint width; if (!ct->show_text) return thumb_max_width; width = thumb_max_width + thumb_max_width / 2; if (width < THUMB_MIN_ICON_WIDTH) width = THUMB_MIN_ICON_WIDTH; if (width > THUMB_MAX_ICON_WIDTH) width = thumb_max_width; return width;}/* *------------------------------------------------------------------- * cell updates *------------------------------------------------------------------- */static void collection_table_selection_set(CollectTable *ct, CollectInfo *info, SelectionType value, GtkTreeIter *iter){ GtkTreeModel *store; GList *list; if (!info) return; if (info->flag_mask == value) return; info->flag_mask = value; store = gtk_tree_view_get_model(GTK_TREE_VIEW(ct->listview)); if (iter) { gtk_tree_model_get(store, iter, CTABLE_COLUMN_POINTER, &list, -1); if (list) gtk_list_store_set(GTK_LIST_STORE(store), iter, CTABLE_COLUMN_POINTER, list, -1); } else { GtkTreeIter row; if (collection_table_find_iter(ct, info, &row, NULL)) { gtk_tree_model_get(store, &row, CTABLE_COLUMN_POINTER, &list, -1); if (list) gtk_list_store_set(GTK_LIST_STORE(store), &row, CTABLE_COLUMN_POINTER, list, -1); } }}static void collection_table_selection_add(CollectTable *ct, CollectInfo *info, SelectionType mask, GtkTreeIter *iter){ if (!info) return; collection_table_selection_set(ct, info, info->flag_mask | mask, iter);}static void collection_table_selection_remove(CollectTable *ct, CollectInfo *info, SelectionType mask, GtkTreeIter *iter){ if (!info) return; collection_table_selection_set(ct, info, info->flag_mask & ~mask, iter);}/* *------------------------------------------------------------------- * selections *------------------------------------------------------------------- */static void collection_table_verify_selections(CollectTable *ct){ GList *work; work = ct->selection; while (work) { CollectInfo *info = work->data; work = work->next; if (!g_list_find(ct->cd->list, info)) { ct->selection = g_list_remove(ct->selection, info); } }}void collection_table_select_all(CollectTable *ct){ GList *work; g_list_free(ct->selection); ct->selection = NULL; work = ct->cd->list; while(work) { ct->selection = g_list_append(ct->selection, work->data); collection_table_selection_add(ct, work->data, SELECTION_SELECTED, NULL); work = work->next; } collection_table_update_status(ct);}void collection_table_unselect_all(CollectTable *ct){ GList *work; work = ct->selection; while (work) { collection_table_selection_remove(ct, work->data, SELECTION_SELECTED, NULL); work = work->next; } g_list_free(ct->selection); ct->selection = NULL; collection_table_update_status(ct);}static void collection_table_select(CollectTable *ct, CollectInfo *info){ ct->prev_selection = info; if (!info || INFO_SELECTED(info)) return; ct->selection = g_list_append(ct->selection, info); collection_table_selection_add(ct, info, SELECTION_SELECTED, NULL); collection_table_update_status(ct);}static void collection_table_unselect(CollectTable *ct, CollectInfo *info){ ct->prev_selection = info; if (!info || !INFO_SELECTED(info) ) return; ct->selection = g_list_remove(ct->selection, info); collection_table_selection_remove(ct, info, SELECTION_SELECTED, NULL); collection_table_update_status(ct);}static void collection_table_select_util(CollectTable *ct, CollectInfo *info, gint select){ if (select) { collection_table_select(ct, info); } else { collection_table_unselect(ct, info); }}static void collection_table_select_region_util(CollectTable *ct, CollectInfo *start, CollectInfo *end, gint select){ gint row1, col1; gint row2, col2; gint t; gint i, j; if (!collection_table_find_position(ct, start, &row1, &col1) || !collection_table_find_position(ct, end, &row2, &col2) ) return; ct->prev_selection = end; if (!collection_rectangular_selection) { GList *work; CollectInfo *info; if (g_list_index(ct->cd->list, start) > g_list_index(ct->cd->list, end)) { info = start; start = end; end = info; } work = g_list_find(ct->cd->list, start); while (work) { info = work->data; collection_table_select_util(ct, info, select); if (work->data != end) work = work->next; else work = NULL; } return; } if (row2 < row1) { t = row1; row1 = row2; row2 = t; } if (col2 < col1) { t = col1; col1 = col2; col2 = t; } if (debug) printf("table: %d x %d to %d x %d\n", row1, col1, row2, col2); for (i = row1; i <= row2; i++) { for (j = col1; j <= col2; j++) { CollectInfo *info = collection_table_find_data(ct, i, j, NULL); if (info) collection_table_select_util(ct, info, select); } }}GList *collection_table_selection_get_list(CollectTable *ct){ return collection_list_to_path_list(ct->selection);}static GList *collection_table_get_list(CollectTable *ct){ return collection_list_to_path_list(ct->cd->list);}/* *------------------------------------------------------------------- * tooltip type window *------------------------------------------------------------------- */static void tip_show(CollectTable *ct){ GtkWidget *label; gint x, y; if (ct->tip_window) return; gdk_window_get_pointer(ct->listview->window, &x, &y, NULL); ct->tip_info = collection_table_find_data_by_coord(ct, x, y, NULL); if (!ct->tip_info) return; ct->tip_window = gtk_window_new(GTK_WINDOW_POPUP); gtk_window_set_resizable(GTK_WINDOW(ct->tip_window), FALSE); gtk_container_set_border_width(GTK_CONTAINER(ct->tip_window), 2); label = gtk_label_new(filename_from_path(ct->tip_info->path)); g_object_set_data(G_OBJECT(ct->tip_window), "tip_label", label); gtk_container_add(GTK_CONTAINER(ct->tip_window), label); gtk_widget_show(label); gdk_window_get_pointer(NULL, &x, &y, NULL); if (!GTK_WIDGET_REALIZED(ct->tip_window)) gtk_widget_realize(ct->tip_window); gtk_window_move(GTK_WINDOW(ct->tip_window), x + 16, y + 16); gtk_widget_show(ct->tip_window);}static void tip_hide(CollectTable *ct){ if (ct->tip_window) gtk_widget_destroy(ct->tip_window); ct->tip_window = NULL;}static gint tip_schedule_cb(gpointer data){ CollectTable *ct = data; if (ct->tip_delay_id == -1) return FALSE; tip_show(ct); ct->tip_delay_id = -1; return FALSE;}static void tip_schedule(CollectTable *ct){ tip_hide(ct); if (ct->tip_delay_id != -1) { g_source_remove(ct->tip_delay_id); ct->tip_delay_id = -1; } if (!ct->show_text) { ct->tip_delay_id = g_timeout_add(COLLECT_TABLE_TIP_DELAY, tip_schedule_cb, ct); }}static void tip_unschedule(CollectTable *ct){ tip_hide(ct); if (ct->tip_delay_id != -1) g_source_remove(ct->tip_delay_id); ct->tip_delay_id = -1;}static void tip_update(CollectTable *ct, CollectInfo *info){ if (ct->tip_window) { gint x, y; gdk_window_get_pointer(NULL, &x, &y, NULL); gtk_window_move(GTK_WINDOW(ct->tip_window), x + 16, y + 16); if (info != ct->tip_info) { GtkWidget *label; ct->tip_info = info; if (!ct->tip_info) { tip_hide(ct); tip_schedule(ct); return; } label = g_object_get_data(G_OBJECT(ct->tip_window), "tip_label"); gtk_label_set_text(GTK_LABEL(label), filename_from_path(ct->tip_info->path)); } } else { tip_schedule(ct); }}/* *------------------------------------------------------------------- * popup menus *------------------------------------------------------------------- */static void collection_table_popup_save_as_cb(GtkWidget *widget, gpointer data){ CollectTable *ct = data; collection_dialog_save_as(NULL, ct->cd);}static void collection_table_popup_save_cb(GtkWidget *widget, gpointer data){ CollectTable *ct = data; if (!ct->cd->path) { collection_table_popup_save_as_cb(widget, data); return; } if (!collection_save(ct->cd, ct->cd->path)) { printf("failed saving to collection path: %s\n", ct->cd->path); }}static GList *collection_table_popup_file_list(CollectTable *ct){ if (!ct->click_info) return NULL; if (INFO_SELECTED(ct->click_info)) { return collection_table_selection_get_list(ct); } return g_list_append(NULL, g_strdup(ct->click_info->path));}static void collection_table_popup_edit_cb(GtkWidget *widget, gpointer data){ CollectTable *ct; gint n; GList *list; ct = submenu_item_get_data(widget); if (!ct) return; n = GPOINTER_TO_INT(data); list = collection_table_popup_file_list(ct); if (list) { start_editor_from_path_list(n, list); path_list_free(list); }}static void collection_table_popup_info_cb(GtkWidget *widget, gpointer data){ CollectTable *ct = data; info_window_new(NULL, collection_table_popup_file_list(ct));}static void collection_table_popup_copy_cb(GtkWidget *widget, gpointer data){ CollectTable *ct = data; file_util_copy(NULL, collection_table_popup_file_list(ct), NULL, ct->listview);}static void collection_table_popup_move_cb(GtkWidget *widget, gpointer data){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -