📄 view_file_icon.c
字号:
while (work) { FileData *fd = work->data; if (strcmp(path, fd->path) == 0) return p; work = work->next; p++; } return -1;}gint vficon_count(ViewFileIcon *vfi, gint64 *bytes){ if (bytes) { gint64 b = 0; GList *work; work = vfi->list; while (work) { FileData *fd = work->data; work = work->next; b += fd->size; } *bytes = b; } return g_list_length(vfi->list);}GList *vficon_get_list(ViewFileIcon *vfi){ GList *list = NULL; GList *work; work = vfi->list; while (work) { FileData *fd = work->data; work = work->next; list = g_list_prepend(list, g_strdup(fd->path)); } return g_list_reverse(list);}/* *----------------------------------------------------------------------------- * *----------------------------------------------------------------------------- */static gint vficon_refresh_real(ViewFileIcon *vfi, gint keep_position){ gint ret = TRUE; GList *old_list; GList *work; FileData *focus_fd; focus_fd = vfi->focus_fd; old_list = vfi->list; vfi->list = NULL; if (vfi->path) { ret = iconlist_read(vfi->path, &vfi->list); } /* check for same files from old_list */ work = old_list; while (work) { FileData *fd; GList *needle; fd = work->data; needle = vfi->list; while (needle) { FileData *fdn = needle->data; if (strcmp(fd->name, fdn->name) == 0) { /* swap, to retain old thumb, selection */ needle->data = fd; work->data = fdn; needle = NULL; if (fd->date != fdn->date || fd->size != fdn->size) { /* file changed, update */ fd->date = fdn->date; fd->size = fdn->size; vficon_set_thumb(vfi, fd, NULL); } } else { needle = needle->next; } } work = work->next; } vfi->list = filelist_sort(vfi->list, vfi->sort_method, vfi->sort_ascend); work = old_list; while (work) { FileData *fd = work->data; work = work->next; if (fd == vfi->prev_selection) vfi->prev_selection = NULL; if (fd == vfi->click_fd) vfi->click_fd = NULL; } vficon_populate(vfi, TRUE, keep_position); /* attempt to keep focus on same icon when refreshing */ if (focus_fd && g_list_find(vfi->list, focus_fd)) { vficon_set_focus(vfi, focus_fd); } iconlist_free(old_list); return ret;}gint vficon_refresh(ViewFileIcon *vfi){ return vficon_refresh_real(vfi, TRUE);}/* *----------------------------------------------------------------------------- * draw, etc. *----------------------------------------------------------------------------- */typedef struct _ColumnData ColumnData;struct _ColumnData{ ViewFileIcon *vfi; gint number;};static void vficon_cell_data_cb(GtkTreeViewColumn *tree_column, GtkCellRenderer *cell, GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer data){ ColumnData *cd = data; ViewFileIcon *vfi; GtkStyle *style; GList *list; FileData *fd; GdkColor color_fg; GdkColor color_bg; vfi = cd->vfi; gtk_tree_model_get(tree_model, iter, FILE_COLUMN_POINTER, &list, -1); fd = g_list_nth_data(list, cd->number); style = gtk_widget_get_style(vfi->listview); if (fd && ICON_DATA(fd)->selected & SELECTION_SELECTED) { memcpy(&color_fg, &style->text[GTK_STATE_SELECTED], sizeof(color_fg)); memcpy(&color_bg, &style->base[GTK_STATE_SELECTED], sizeof(color_bg)); } else { memcpy(&color_fg, &style->text[GTK_STATE_NORMAL], sizeof(color_fg)); memcpy(&color_bg, &style->base[GTK_STATE_NORMAL], sizeof(color_bg)); } if (fd && ICON_DATA(fd)->selected & SELECTION_PRELIGHT) {#if 0 shift_color(&color_fg, -1, 0);#endif shift_color(&color_bg, -1, 0); } if (GQV_IS_CELL_RENDERER_ICON(cell)) { if (fd) { g_object_set(cell, "pixbuf", fd->pixbuf, "text", fd->name, "cell-background-gdk", &color_bg, "cell-background-set", TRUE, "foreground-gdk", &color_fg, "foreground-set", TRUE, "has-focus", (vfi->focus_fd == fd), NULL); } else { g_object_set(cell, "pixbuf", NULL, "text", NULL, "cell-background-set", FALSE, "foreground-set", FALSE, "has-focus", FALSE, NULL); } }}static void vficon_append_column(ViewFileIcon *vfi, gint n){ ColumnData *cd; GtkTreeViewColumn *column; GtkCellRenderer *renderer; column = gtk_tree_view_column_new(); gtk_tree_view_column_set_min_width(column, 0); gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED); gtk_tree_view_column_set_alignment(column, 0.5); renderer = gqv_cell_renderer_icon_new(); gtk_tree_view_column_pack_start(column, renderer, FALSE); g_object_set(G_OBJECT(renderer), "xpad", THUMB_BORDER_PADDING * 2, "ypad", THUMB_BORDER_PADDING, "mode", GTK_CELL_RENDERER_MODE_ACTIVATABLE, NULL); g_object_set_data(G_OBJECT(column), "column_number", GINT_TO_POINTER(n)); cd = g_new0(ColumnData, 1); cd->vfi = vfi; cd->number = n; 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(vfi->listview), column);}/* *----------------------------------------------------------------------------- * base *----------------------------------------------------------------------------- */gint vficon_set_path(ViewFileIcon *vfi, const gchar *path){ gint ret; if (!path) return FALSE; if (vfi->path && strcmp(path, vfi->path) == 0) return TRUE; g_free(vfi->path); vfi->path = g_strdup(path); g_list_free(vfi->selection); vfi->selection = NULL; iconlist_free(vfi->list); vfi->list = NULL; /* NOTE: populate will clear the store for us */ ret = vficon_refresh_real(vfi, FALSE); vfi->focus_fd = NULL; vficon_move_focus(vfi, 0, 0, FALSE); return ret;}static void vficon_destroy_cb(GtkWidget *widget, gpointer data){ ViewFileIcon *vfi = data; if (vfi->popup) { g_signal_handlers_disconnect_matched(G_OBJECT(vfi->popup), G_SIGNAL_MATCH_DATA, 0, 0, 0, NULL, vfi); gtk_widget_destroy(vfi->popup); } if (vfi->sync_idle_id != -1) g_source_remove(vfi->sync_idle_id); tip_unschedule(vfi); vficon_thumb_cleanup(vfi); g_free(vfi->path); iconlist_free(vfi->list); g_list_free(vfi->selection); g_free(vfi);}ViewFileIcon *vficon_new(const gchar *path){ ViewFileIcon *vfi; GtkListStore *store; GtkTreeSelection *selection; gint i; vfi = g_new0(ViewFileIcon, 1); vfi->path = NULL; vfi->sort_method = SORT_NAME; vfi->sort_ascend = TRUE; vfi->selection = NULL; vfi->prev_selection = NULL; vfi->tip_window = NULL; vfi->tip_delay_id = -1; vfi->focus_row = 0; vfi->focus_column = 0; vfi->focus_fd = NULL; vfi->show_text = show_icon_names; vfi->sync_idle_id = -1; vfi->popup = NULL; vfi->widget = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(vfi->widget), GTK_SHADOW_IN); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(vfi->widget), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); g_signal_connect(G_OBJECT(vfi->widget), "destroy", G_CALLBACK(vficon_destroy_cb), vfi); store = gtk_list_store_new(1, G_TYPE_POINTER); vfi->listview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store)); g_object_unref(store); selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(vfi->listview)); gtk_tree_selection_set_mode(GTK_TREE_SELECTION(selection), GTK_SELECTION_NONE); gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(vfi->listview), FALSE); gtk_tree_view_set_enable_search(GTK_TREE_VIEW(vfi->listview), FALSE); for (i = 0; i < VFICON_MAX_COLUMNS; i++) { vficon_append_column(vfi, i); } /* zero width column to hide tree view focus, we draw it ourselves */ vficon_append_column(vfi, i); /* end column to fill white space */ vficon_append_column(vfi, i); g_signal_connect(G_OBJECT(vfi->listview), "size_allocate", G_CALLBACK(vficon_sized_cb), vfi); g_signal_connect(G_OBJECT(vfi->listview), "key_press_event", G_CALLBACK(vficon_press_key_cb), vfi); gtk_container_add(GTK_CONTAINER(vfi->widget), vfi->listview); gtk_widget_show(vfi->listview); vficon_dnd_init(vfi); gtk_widget_set_events(vfi->listview, GDK_POINTER_MOTION_MASK | GDK_BUTTON_RELEASE_MASK | GDK_BUTTON_PRESS_MASK | GDK_LEAVE_NOTIFY_MASK); g_signal_connect(G_OBJECT(vfi->listview), "button_press_event", G_CALLBACK(vficon_press_cb), vfi); g_signal_connect(G_OBJECT(vfi->listview), "button_release_event", G_CALLBACK(vficon_release_cb), vfi); g_signal_connect(G_OBJECT(vfi->listview),"motion_notify_event", G_CALLBACK(vficon_motion_cb), vfi); g_signal_connect(G_OBJECT(vfi->listview), "leave_notify_event", G_CALLBACK(vficon_leave_cb), vfi); /* force vfi->columns to be at least 1 (sane) - this will be corrected in the size_cb */ vficon_populate_at_new_size(vfi, 1, 1, FALSE); if (path) vficon_set_path(vfi, path); return vfi;}void vficon_set_status_func(ViewFileIcon *vfi, void (*func)(ViewFileIcon *vfi, gpointer data), gpointer data){ vfi->func_status = func; vfi->data_status = data;}void vficon_set_thumb_status_func(ViewFileIcon *vfi, void (*func)(ViewFileIcon *vfi, gdouble val, const gchar *text, gpointer data), gpointer data){ vfi->func_thumb_status = func; vfi->data_thumb_status = data;}void vficon_set_layout(ViewFileIcon *vfi, LayoutWindow *layout){ vfi->layout = layout;}/* *----------------------------------------------------------------------------- * maintenance (for rename, move, remove) *----------------------------------------------------------------------------- */static gint vficon_maint_find_closest(ViewFileIcon *vfi, gint row, gint count, GList *ignore_list){ GList *list = NULL; GList *work; gint rev = row - 1; row ++; work = ignore_list; while (work) { gint f = vficon_index_by_path(vfi, work->data); if (f >= 0) list = g_list_prepend(list, GINT_TO_POINTER(f)); work = work->next; } while (list) { gint c = TRUE; work = list; while (work && c) { gpointer p = work->data; work = work->next; if (row == GPOINTER_TO_INT(p)) { row++; c = FALSE; } if (rev == GPOINTER_TO_INT(p)) { rev--; c = FALSE; } if (!c) list = g_list_remove(list, p); } if (c && list) { g_list_free(list); list = NULL; } } if (row > count - 1) { if (rev < 0) return -1; else return rev; } else { return row; }}gint vficon_maint_renamed(ViewFileIcon *vfi, const gchar *source, const gchar *dest){ gint ret = FALSE; gint row; gchar *source_base; gchar *dest_base; GList *work; FileData *fd; row = vficon_index_by_path(vfi, source); if (row < 0) return FALSE; source_base = remove_level_from_path(source); dest_base = remove_level_from_path(dest); work = g_list_nth(vfi->list, row); fd = work->data; if (strcmp(source_base, dest_base) == 0) { vfi->list = g_list_remove(vfi->list, fd); g_free(fd->path); fd->path = g_strdup(dest); fd->name = filename_from_path(fd->path); vfi->list = filelist_insert_sort(vfi->list, fd, vfi->sort_method, vfi->sort_ascend); vficon_sync(vfi); ret = TRUE; } else { ret = vficon_maint_removed(vfi, source, NULL); } g_free(source_base); g_free(dest_base); return ret;}gint vficon_maint_removed(ViewFileIcon *vfi, const gchar *path, GList *ignore_list){ FileData *fd; gint row; gint new_row = -1; GtkTreeModel *store; GtkTreeIter iter; row = vficon_index_by_path(vfi, path); if (row < 0) return FALSE; fd = g_list_nth_data(vfi->list, row); if (!fd) return FALSE; if ((ICON_DATA(fd)->selected & SELECTION_SELECTED) && layout_image_get_collection(vfi->layout, NULL) == NULL) { vficon_unselect(vfi, fd); if (!vfi->selection) { gint n; n = vficon_count(vfi, NULL); if (ignore_list) { new_row = vficon_maint_find_closest(vfi, row, n, ignore_list); if (debug) printf("row = %d, closest is %d\n", row, new_row); } else { if (row + 1 < n) { new_row = row + 1; } else if (row > 0) { new_row = row - 1; } } } else if (ignore_list) { GList *work; work = vfi->selection; while (work) { FileData *ignore_fd; GList *tmp; gint match = FALSE; ignore_fd = work->data; work = work->next; tmp = ignore_list; while (tmp && !match) { const gchar *ignore_path; ignore_path = tmp->data; tmp = tmp->next; if (strcmp(ignore_fd->path, ignore_path) == 0) { match = TRUE; } } if (!match) { new_row = g_list_index(vfi->list, ignore_fd); work = NULL; } } if (new_row == -1) { /* selection all ignored, use closest */ new_row = vficon_maint_find_closest(vfi, row, vficon_count(vfi, NULL), ignore_list); } } else { new_row = g_list_index(vfi->list, vfi->selection->data); } if (new_row >= 0) { FileData *fdn; fdn = g_list_nth_data(vfi->list, new_row); vficon_select(vfi, fdn); vficon_send_layout_select(vfi, fdn); } } /* Thumb loader check */ if (fd == vfi->thumbs_fd) vfi->thumbs_fd = NULL; if (vfi->prev_selection == fd) vfi->prev_selection = NULL; if (vfi->click_fd == fd) vfi->click_fd = NULL; /* remove pointer to this fd from grid */ store = gtk_tree_view_get_model(GTK_TREE_VIEW(vfi->listview)); if (gtk_tree_model_iter_nth_child(store, &iter, NULL, row / vfi->columns)) { GList *list; gtk_tree_model_get(store, &iter, FILE_COLUMN_POINTER, &list, -1); list = g_list_find(list, fd); if (list) list->data = NULL; } vfi->list = g_list_remove(vfi->list, fd); file_data_free(fd); vficon_sync_idle(vfi); vficon_send_update(vfi); return TRUE;}gint vficon_maint_moved(ViewFileIcon *vfi, const gchar *source, const gchar *dest, GList *ignore_list){ gint ret = FALSE; gchar *buf; if (!source || !vfi->path) return FALSE; buf = remove_level_from_path(source); if (strcmp(buf, vfi->path) == 0) { ret = vficon_maint_removed(vfi, source, ignore_list); } g_free(buf); return ret;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -