info.c
来自「Gqview,Linux下基于GTK+库写成的轻量级而能丰富的图像浏览程序。」· C语言 代码 · 共 772 行 · 第 1/2 页
C
772 行
td->func_sync = info_tab_general_sync; td->func_image = info_tab_general_image; td->data = tab; return td;}/* *------------------------------------------------------------------- * tabs *------------------------------------------------------------------- */static void info_tabs_sync(InfoData *id, gint image){ GList *work; work = id->tab_list; while (work) { TabData *td = work->data; work = work->next; if (image) { if (td->func_image) td->func_image(id, td->data); } else { if (td->func_sync) td->func_sync(id, td->data); } }}static void info_tabs_free(InfoData *id){ GList *work; work = id->tab_list; while (work) { TabData *td = work->data; work = work->next; if (td->func_free) td->func_free(td->data); g_free(td); } g_list_free(id->tab_list); id->tab_list = NULL;}static void info_tabs_init(InfoData *id){ id->tab_list = g_list_append(id->tab_list, info_tab_general_new(id)); id->tab_list = g_list_append(id->tab_list, info_tab_meta_new(id)); id->tab_list = g_list_append(id->tab_list, info_tab_exif_new(id));}/* *------------------------------------------------------------------- * sync *------------------------------------------------------------------- */static void info_window_sync(InfoData *id, const gchar *path){ if (!path) return; gtk_entry_set_text(GTK_ENTRY(id->name_entry), filename_from_path(path)); if (id->label_count) { gchar *buf; buf = g_strdup_printf(_("Image %d of %d"), g_list_index(id->list, (gpointer)path) + 1, g_list_length(id->list)); gtk_label_set_text(GTK_LABEL(id->label_count), buf); g_free(buf); } info_tabs_sync(id, FALSE); id->updated = FALSE; image_change_path(id->image, path, 0.0);}/* *------------------------------------------------------------------- * drag n drop (dropping not supported!) *------------------------------------------------------------------- */static void info_window_dnd_data_set(GtkWidget *widget, GdkDragContext *context, GtkSelectionData *selection_data, guint info, guint time, gpointer data){ InfoData *id = data; const gchar *path; path = image_get_path(id->image); if (path) { gchar *text; gint len; GList *list; gint plain_text; switch (info) { case TARGET_URI_LIST: plain_text = FALSE; break; case TARGET_TEXT_PLAIN: default: plain_text = TRUE; break; } list = g_list_append(NULL, (gchar *)path); text = uri_text_from_list(list, &len, plain_text); g_list_free(list); gtk_selection_data_set(selection_data, selection_data->target, 8, text, len); g_free(text); }}static void info_window_dnd_init(InfoData *id){ ImageWindow *imd; imd = id->image; gtk_drag_source_set(imd->pr, GDK_BUTTON2_MASK, dnd_file_drag_types, dnd_file_drag_types_count, GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK); g_signal_connect(G_OBJECT(imd->pr), "drag_data_get", G_CALLBACK(info_window_dnd_data_set), id);#if 0 gtk_drag_dest_set(imd->pr, GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_DROP, dnd_file_drop_types, dnd_file_drop_types_count, GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK); g_signal_connect(G_OBJECT(imd->pr), "drag_data_received", G_CALLBACK(info_window_dnd_data_get), id);#endif}/* *------------------------------------------------------------------- * base window *------------------------------------------------------------------- */static gint info_window_last_width = DEF_PROPERTY_WIDTH;static gint info_window_last_height = DEF_PROPERTY_HEIGHT;static void info_window_image_update_cb(ImageWindow *imd, gpointer data){ InfoData *id = data; /* only do this once after when loading a new image, * for tabs that depend on image data (exif) * Subsequent updates are ignored, as the image * should not really changed if id->updated is TRUE. */ if (id->updated) return; if (imd->unknown) return; info_tabs_sync(id, TRUE); id->updated = TRUE;}static void info_window_back_cb(GtkWidget *widget, gpointer data){ InfoData *id = data; GList *work; work = g_list_find(id->list, (gpointer)id->path); if (!work || !work->prev) return; work = work->prev; id->path = work->data; info_window_sync(id, id->path); gtk_widget_set_sensitive(id->button_back, (work->prev != NULL)); gtk_widget_set_sensitive(id->button_next, TRUE);}static void info_window_next_cb(GtkWidget *widget, gpointer data){ InfoData *id = data; GList *work; work = g_list_find(id->list, (gpointer)id->path); if (!work || !work->next) return; work = work->next; id->path = work->data; info_window_sync(id, id->path); gtk_widget_set_sensitive(id->button_next, (work->next != NULL)); gtk_widget_set_sensitive(id->button_back, TRUE);}static void info_window_image_button_cb(ImageWindow *imd, gint button, guint32 time, gdouble x, gdouble y, guint state, gpointer data){ if (button == 1) { info_window_next_cb(NULL, data); } else if (button == 2 || button == 3) { info_window_back_cb(NULL, data); }}static void info_window_image_scroll_cb(ImageWindow *imd, GdkScrollDirection direction, guint32 time, gdouble x, gdouble y, guint state, gpointer data){ if (direction == GDK_SCROLL_UP) { info_window_back_cb(NULL, data); } else if (direction == GDK_SCROLL_DOWN) { info_window_next_cb(NULL, data); }}static void info_window_close(InfoData *id){ gdk_drawable_get_size(id->window->window, &info_window_last_width, &info_window_last_height); info_window_last_width = MAX(info_window_last_width, DEF_PROPERTY_WIDTH); info_window_last_height = MAX(info_window_last_height, DEF_PROPERTY_HEIGHT); gtk_widget_destroy(id->window);}static void info_window_close_cb(GtkWidget *widget, gpointer data){ InfoData *id = data; info_window_close(id);}static gint info_window_delete_cb(GtkWidget *widget, GdkEventAny *event, gpointer data){ InfoData *id = data; info_window_close(id); return TRUE;}static void info_window_destroy_cb(GtkWidget *widget, gpointer data){ InfoData *id = data; info_tabs_free(id); path_list_free(id->list); g_free(id);}void info_window_new(const gchar *path, GList *list){ InfoData *id; GtkWidget *main_vbox; GtkWidget *paned; GtkWidget *hbox; GtkWidget *button; GtkWidget *label; GdkGeometry geometry; if (!path && !list) return; if (!list) { list = g_list_append(NULL, g_strdup(path)); } id = g_new0(InfoData, 1); id->list = list; id->path = (gchar *)id->list->data; id->updated = FALSE; id->window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_type_hint(GTK_WINDOW(id->window), GDK_WINDOW_TYPE_HINT_DIALOG); window_set_icon(id->window, NULL, NULL); gtk_window_set_resizable(GTK_WINDOW(id->window), TRUE); gtk_window_set_title(GTK_WINDOW(id->window), _("Image properties - GQview")); gtk_window_set_wmclass(GTK_WINDOW(id->window), "properties", "GQview"); geometry.min_width = 32; geometry.min_height = 32; geometry.base_width = DEF_PROPERTY_WIDTH; geometry.base_height = DEF_PROPERTY_HEIGHT; gtk_window_set_geometry_hints(GTK_WINDOW(id->window), NULL, &geometry, GDK_HINT_MIN_SIZE | GDK_HINT_BASE_SIZE); gtk_window_set_default_size(GTK_WINDOW(id->window), info_window_last_width, info_window_last_height); gtk_container_set_border_width(GTK_CONTAINER(id->window), PREF_PAD_BORDER); g_signal_connect(G_OBJECT(id->window), "delete_event", G_CALLBACK(info_window_delete_cb), id); g_signal_connect(G_OBJECT(id->window), "destroy", G_CALLBACK(info_window_destroy_cb), id); paned = gtk_hpaned_new(); gtk_container_add(GTK_CONTAINER(id->window), paned); gtk_widget_show(paned); id->image = image_new(FALSE); image_set_update_func(id->image, info_window_image_update_cb, id); image_set_button_func(id->image, info_window_image_button_cb, id); image_set_scroll_func(id->image, info_window_image_scroll_cb, id); gtk_widget_set_size_request(id->image->widget, IMAGE_SIZE_W, IMAGE_SIZE_H); gtk_paned_pack1(GTK_PANED(paned), id->image->widget, FALSE, TRUE); gtk_widget_show(id->image->widget); main_vbox = gtk_vbox_new(FALSE, 0); gtk_paned_pack2(GTK_PANED(paned), main_vbox, TRUE, TRUE); gtk_widget_show(main_vbox); hbox = pref_box_new(main_vbox, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE); label = pref_label_new(hbox, _("Filename:")); pref_label_bold(label, TRUE, FALSE); id->name_entry = gtk_entry_new(); gtk_editable_set_editable(GTK_EDITABLE(id->name_entry), FALSE); gtk_box_pack_start(GTK_BOX(hbox), id->name_entry, TRUE, TRUE, 0); gtk_widget_show(id->name_entry); id->notebook = gtk_notebook_new(); gtk_notebook_set_tab_pos(GTK_NOTEBOOK(id->notebook), GTK_POS_TOP); gtk_box_pack_start(GTK_BOX(main_vbox), id->notebook, TRUE, TRUE, 5); gtk_widget_show(id->notebook); pref_spacer(main_vbox, PREF_PAD_GAP); hbox = pref_box_new(main_vbox, FALSE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_GAP); id->button_back = pref_button_new(hbox, GTK_STOCK_GO_BACK, NULL, TRUE, G_CALLBACK(info_window_back_cb), id); gtk_widget_set_sensitive(id->button_back, FALSE); id->button_next = pref_button_new(hbox, GTK_STOCK_GO_FORWARD, NULL, TRUE, G_CALLBACK(info_window_next_cb), id); gtk_widget_set_sensitive(id->button_next, (id->list->next != NULL)); if (id->list->next) { id->label_count = pref_label_new(hbox, ""); } button = pref_button_new(NULL, GTK_STOCK_CLOSE, NULL, FALSE, G_CALLBACK(info_window_close_cb), id); gtk_box_pack_end(GTK_BOX(hbox), button, FALSE, FALSE, 0); gtk_widget_show(button); /* set up tabs */ info_tabs_init(id); /* fill it */ info_window_sync(id, id->path); /* finish */ info_window_dnd_init(id); gtk_widget_show(id->window);}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?