📄 collect.c
字号:
return valid;}gint collection_add(CollectionData *cd, const gchar *path, gint sorted){ return collection_add_check(cd, path, sorted, TRUE);}gint collection_insert(CollectionData *cd, const gchar *path, CollectInfo *insert_ci, gint sorted){ struct stat st; if (!insert_ci) return collection_add(cd, path, sorted); if (stat_utf8(path, &st) >= 0 && !S_ISDIR(st.st_mode)) { CollectInfo *ci; ci = collection_info_new(path, &st, NULL); cd->list = collection_list_insert(cd->list, ci, insert_ci, sorted ? cd->sort_method : SORT_NONE); cd->changed = TRUE; collection_window_insert(collection_window_find(cd), ci); return TRUE; } return FALSE;}gint collection_remove(CollectionData *cd, const gchar *path){ CollectInfo *ci; ci = collection_list_find(cd->list, path); if (!ci) return FALSE; cd->list = g_list_remove(cd->list, ci); cd->changed = TRUE; collection_window_remove(collection_window_find(cd), ci); collection_info_free(ci); return TRUE;}static void collection_remove_by_info(CollectionData *cd, CollectInfo *info){ if (!info || !g_list_find(cd->list, info)) return; cd->list = g_list_remove(cd->list, info); cd->changed = (cd->list != NULL); collection_window_remove(collection_window_find(cd), info); collection_info_free(info);}void collection_remove_by_info_list(CollectionData *cd, GList *list){ GList *work; if (!list) return; if (!list->next) { /* more efficient (in collect-table) to remove a single item this way */ collection_remove_by_info(cd, (CollectInfo *)list->data); return; } work = list; while(work) { cd->list = collection_list_remove(cd->list, work->data); work = work->next; } cd->changed = (cd->list != NULL); collection_window_refresh(collection_window_find(cd));}gint collection_rename(CollectionData *cd, const gchar *source, const gchar *dest){ CollectInfo *ci; ci = collection_list_find(cd->list, source); if (!ci) return FALSE; g_free(ci->path); ci->path = g_strdup(dest); cd->changed = TRUE; collection_window_update(collection_window_find(cd), ci); return TRUE;}void collection_update_geometry(CollectionData *cd){ collection_window_get_geometry(collection_window_find(cd));}/* *------------------------------------------------------------------- * simple maintenance for renaming, deleting *------------------------------------------------------------------- */void collection_maint_removed(const gchar *path){ GList *work; work = collection_list; while(work) { CollectionData *cd = work->data; work = work->next; while(collection_remove(cd, path)); }#if 0 /* Do we really need to do this? removed files are * automatically ignored when loading a collection. */ collect_manager_moved(path, NULL);#endif}void collection_maint_renamed(const gchar *source, const gchar *dest){ GList *work; work = collection_list; while(work) { CollectionData *cd = work->data; work = work->next; while(collection_rename(cd, source, dest)); } collect_manager_moved(source, dest);}/* *------------------------------------------------------------------- * window key presses *------------------------------------------------------------------- */static gint collection_window_keypress(GtkWidget *widget, GdkEventKey *event, gpointer data){ CollectWindow *cw = data; gint stop_signal = FALSE; gint edit_val = -1; GList *list; if (event->state & GDK_CONTROL_MASK) { 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 'A': case 'a': if (event->state & GDK_SHIFT_MASK) { collection_table_unselect_all(cw->table); } else { collection_table_select_all(cw->table); } stop_signal = TRUE; break; case 'L': case 'l': list = layout_list(NULL); if (list) { collection_table_add_path_list(cw->table, list); path_list_free(list); } stop_signal = TRUE; break; case 'C': case 'c': file_util_copy(NULL, collection_table_selection_get_list(cw->table), NULL, cw->window); stop_signal = TRUE; break; case 'M': case 'm': file_util_move(NULL, collection_table_selection_get_list(cw->table), NULL, cw->window); stop_signal = TRUE; break; case 'R': case 'r': file_util_rename(NULL, collection_table_selection_get_list(cw->table), cw->window); stop_signal = TRUE; break; case 'D': case 'd': file_util_delete(NULL, collection_table_selection_get_list(cw->table), cw->window); stop_signal = TRUE; break; case 'P': case 'p': info_window_new(NULL, collection_table_selection_get_list(cw->table)); stop_signal = TRUE; break; case 'S': case 's': collection_dialog_save_as(NULL, cw->cd); stop_signal = TRUE; break; case 'W': case 'w': collection_window_close(cw); stop_signal = TRUE; break; default: break; } } else { switch (event->keyval) { case GDK_Return: case GDK_KP_Enter: layout_image_set_collection(NULL, cw->cd, collection_table_get_focus_info(cw->table)); stop_signal = TRUE; break; case 'V': case 'v': view_window_new_from_collection(cw->cd, collection_table_get_focus_info(cw->table)); stop_signal = TRUE; break; case 'S': case 's': if (!cw->cd->path) { collection_dialog_save_as(NULL, cw->cd); } else if (!collection_save(cw->cd, cw->cd->path)) { printf("failed saving to collection path: %s\n", cw->cd->path); } stop_signal = TRUE; break; case 'A': case 'a': if (!(event->state & GDK_CONTROL_MASK)) { collection_dialog_append(NULL, cw->cd); stop_signal = TRUE; } break; case 'N': case 'n': collection_set_sort_method(cw->cd, SORT_NAME); stop_signal = TRUE; break;#ifdef HAVE_STRVERSCMP case 'I': case 'i': collection_set_sort_method(cw->cd, SORT_NUMBER); stop_signal = TRUE; break;#endif case 'D': case 'd': collection_set_sort_method(cw->cd, SORT_TIME); stop_signal = TRUE; break; case 'B': case 'b': collection_set_sort_method(cw->cd, SORT_SIZE); stop_signal = TRUE; break; case 'P': case 'p': collection_set_sort_method(cw->cd, SORT_PATH); stop_signal = TRUE; break; case GDK_Delete: case GDK_KP_Delete: list = g_list_copy(cw->table->selection); if (list) { collection_remove_by_info_list(cw->cd, list); g_list_free(list); } else { collection_remove_by_info(cw->cd, collection_table_get_focus_info(cw->table)); } stop_signal = TRUE; break; default: break; } } if (edit_val != -1) { list = collection_table_selection_get_list(cw->table); start_editor_from_path_list(edit_val, list); path_list_free(list); stop_signal = TRUE; } return stop_signal;}/* *------------------------------------------------------------------- * window *------------------------------------------------------------------- */static void collection_window_get_geometry(CollectWindow *cw){ CollectionData *cd; if (!cw) return; cd = cw->cd; gdk_window_get_position (cw->window->window, &cd->window_x, &cd->window_y); gdk_drawable_get_size(cw->window->window, &cd->window_w, &cd->window_h); cd->window_read = TRUE;}static void collection_window_refresh(CollectWindow *cw){ if (!cw) return; collection_table_refresh(cw->table);}static void collection_window_update_title(CollectWindow *cw){ gchar *buf; if (!cw) return; buf = g_strdup_printf(_("%s - GQview Collection"), cw->cd->name); gtk_window_set_title(GTK_WINDOW(cw->window), buf); g_free(buf);}static void collection_window_update_info(CollectionData *cd, CollectInfo *ci, gpointer data){ CollectWindow *cw = data; collection_table_file_update(cw->table, ci);}static void collection_window_add(CollectWindow *cw, CollectInfo *ci){ if (!cw) return; if (!ci->pixbuf) collection_load_thumb_idle(cw->cd); collection_table_file_add(cw->table, ci);}static void collection_window_insert(CollectWindow *cw, CollectInfo *ci){ if (!cw) return; if (!ci->pixbuf) collection_load_thumb_idle(cw->cd); collection_table_file_insert(cw->table, ci); if (!cw) return;}#if 0static void collection_window_move(CollectWindow *cw, CollectInfo *ci){ if (!cw) return;}#endifstatic void collection_window_remove(CollectWindow *cw, CollectInfo *ci){ if (!cw) return; collection_table_file_remove(cw->table, ci);}static void collection_window_update(CollectWindow *cw, CollectInfo *ci){ if (!cw) return; collection_table_file_update(cw->table, ci); collection_table_file_update(cw->table, NULL);}static void collection_window_close_final(CollectWindow *cw){ if (cw->close_dialog) return; collection_window_list = g_list_remove(collection_window_list, cw); collection_window_get_geometry(cw); gtk_widget_destroy(cw->window); collection_set_update_info_func(cw->cd, NULL, NULL); collection_unref(cw->cd); g_free(cw);}static void collection_close_save_cb(GenericDialog *gd, gpointer data){ CollectWindow *cw = data; cw->close_dialog = NULL; generic_dialog_close(gd); if (!cw->cd->path) { collection_dialog_save_close(NULL, cw->cd); return; } else if (!collection_save(cw->cd, cw->cd->path)) { gchar *buf; buf = g_strdup_printf(_("Failed to save the collection:\n%s"), cw->cd->path); warning_dialog(_("Save Failed"), buf, GTK_STOCK_DIALOG_ERROR, cw->window); g_free(buf); return; } collection_window_close_final(cw);}static void collection_close_close_cb(GenericDialog *gd, gpointer data){ CollectWindow *cw = data; cw->close_dialog = NULL; generic_dialog_close(gd); collection_window_close_final(cw);}static void collection_close_cancel_cb(GenericDialog *gd, gpointer data){ CollectWindow *cw = data; cw->close_dialog = NULL; generic_dialog_close(gd);}static void collection_close_dlg_show(CollectWindow *cw){ GenericDialog *gd; if (cw->close_dialog) { gtk_window_present(GTK_WINDOW(cw->close_dialog)); return; } gd = generic_dialog_new(_("Close collection"), "GQview", "close_collection", cw->window, FALSE, collection_close_cancel_cb, cw); generic_dialog_add_message(gd, GTK_STOCK_DIALOG_QUESTION, _("Close collection"), _("Collection has been modified.\nSave first?")); generic_dialog_add_button(gd, GTK_STOCK_SAVE, NULL, collection_close_save_cb, TRUE); generic_dialog_add_button(gd, GTK_STOCK_DELETE, _("_Discard"), collection_close_close_cb, FALSE); cw->close_dialog = gd->dialog; gtk_widget_show(gd->dialog);}static void collection_window_close(CollectWindow *cw){ if (!cw->cd->changed && !cw->close_dialog) { collection_window_close_final(cw); return; } collection_close_dlg_show(cw);}void collection_window_close_by_collection(CollectionData *cd){ CollectWindow *cw; cw = collection_window_find(cd); if (cw) collection_window_close_final(cw);}gint collection_window_modified_exists(void){ GList *work; work = collection_window_list; while (work) { CollectWindow *cw = work->data; if (cw->cd->changed) return TRUE; work = work->next; } return FALSE;}static gint collection_window_delete(GtkWidget *widget, GdkEvent *event, gpointer data){ CollectWindow *cw = data; collection_window_close(cw); return TRUE;}CollectWindow *collection_window_new(const gchar *path){ CollectWindow *cw; GtkWidget *vbox; GtkWidget *frame; GtkWidget *status_label; GtkWidget *extra_label; GdkGeometry geometry; cw = g_new0(CollectWindow, 1); cw->close_dialog = NULL; collection_window_list = g_list_append(collection_window_list, cw); cw->cd = collection_new(path); cw->window = gtk_window_new(GTK_WINDOW_TOPLEVEL); window_set_icon(cw->window, (const gchar **)collect_xpm, NULL); geometry.min_width = 32; geometry.min_height = 32; geometry.base_width = COLLECT_DEF_WIDTH; geometry.base_height = COLLECT_DEF_HEIGHT; gtk_window_set_geometry_hints(GTK_WINDOW(cw->window), NULL, &geometry, GDK_HINT_MIN_SIZE | GDK_HINT_BASE_SIZE); if (save_window_positions && path && collection_load_only_geometry(cw->cd, path)) { /* FIXME: x, y is not implemented */ gtk_window_set_default_size(GTK_WINDOW(cw->window), cw->cd->window_w, cw->cd->window_h); } else { gtk_window_set_default_size(GTK_WINDOW(cw->window), COLLECT_DEF_WIDTH, COLLECT_DEF_HEIGHT); } gtk_window_set_resizable(GTK_WINDOW(cw->window), TRUE); collection_window_update_title(cw); gtk_window_set_wmclass(GTK_WINDOW(cw->window), "collection", "GQview"); gtk_container_set_border_width (GTK_CONTAINER (cw->window), 0); g_signal_connect(G_OBJECT(cw->window), "delete_event", G_CALLBACK(collection_window_delete), cw); g_signal_connect(G_OBJECT(cw->window),"key_press_event", G_CALLBACK(collection_window_keypress), cw); vbox = gtk_vbox_new(FALSE, 0); gtk_container_add(GTK_CONTAINER(cw->window), vbox); gtk_widget_show(vbox); cw->table = collection_table_new(cw->cd); gtk_box_pack_start(GTK_BOX(vbox), cw->table->scrolled, TRUE, TRUE, 0); gtk_widget_show(cw->table->scrolled); cw->status_box = gtk_hbox_new(TRUE, 0); gtk_box_pack_start(GTK_BOX(vbox), cw->status_box, FALSE, FALSE, 0); gtk_widget_show(cw->status_box); frame = gtk_frame_new(NULL); gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_IN); gtk_box_pack_start(GTK_BOX(cw->status_box), frame, TRUE, TRUE, 0); gtk_widget_show(frame); status_label = gtk_label_new(""); gtk_container_add(GTK_CONTAINER(frame), status_label); gtk_widget_show(status_label); extra_label = gtk_progress_bar_new(); gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(extra_label), 0.0); gtk_box_pack_start(GTK_BOX(cw->status_box), extra_label, TRUE, TRUE, 0); gtk_widget_show(extra_label); collection_table_set_labels(cw->table, status_label, extra_label); gtk_widget_show(cw->window); gtk_widget_grab_focus(cw->table->listview); collection_set_update_info_func(cw->cd, collection_window_update_info, cw); if (path && *path == '/') collection_load_begin(cw->cd, NULL, FALSE); return cw;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -