📄 utilops.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 "utilops.h"#include "cache_maint.h"#include "collect.h"#include "dupe.h"#include "filelist.h"#include "image.h"#include "img-view.h"#include "layout.h"#include "search.h"#include "ui_bookmark.h"#include "ui_fileops.h"#include "ui_misc.h"#include "ui_tabcomp.h"/* *-------------------------------------------------------------------------- * call these when names change, files move, deleted, etc. * so that any open windows are also updated *-------------------------------------------------------------------------- */void file_maint_renamed(const gchar *source, const gchar *dest){ cache_maint_moved(source, dest); collection_maint_renamed(source, dest); layout_maint_renamed(source, dest); view_window_maint_moved(source, dest); dupe_maint_renamed(source, dest); search_maint_renamed(source, dest);}/* under most cases ignore_list should be NULL */void file_maint_removed(const gchar *path, GList *ignore_list){ layout_maint_removed(path, ignore_list); view_window_maint_removed(path, ignore_list); dupe_maint_removed(path); search_maint_removed(path); collection_maint_removed(path); cache_maint_removed(path);}/* special case for correct main window behavior */void file_maint_moved(const gchar *source, const gchar *dest, GList *ignore_list){ cache_maint_moved(source, dest); collection_maint_renamed(source, dest); layout_maint_moved(source, dest, ignore_list); view_window_maint_moved(source, dest); dupe_maint_renamed(source, dest); search_maint_renamed(source, dest);}void file_maint_copied(const gchar *source, const gchar *dest){ cache_maint_copied(source, dest);}/* *-------------------------------------------------------------------------- * The file manipulation dialogs *-------------------------------------------------------------------------- */enum { DIALOG_NEW_DIR, DIALOG_COPY, DIALOG_MOVE, DIALOG_DELETE, DIALOG_RENAME};typedef struct _FileDataMult FileDataMult;struct _FileDataMult{ gint confirm_all; gint confirmed; gint skip; GList *source_list; GList *source_next; gchar *dest_base; gchar *source; gchar *dest; gint copy; gint rename; gint rename_auto; gint rename_all; GtkWidget *rename_box; GtkWidget *rename_entry; GtkWidget *rename_auto_box; GtkWidget *yes_all_button;};typedef struct _FileDataSingle FileDataSingle;struct _FileDataSingle{ gint confirmed; gchar *source; gchar *dest; gint copy; gint rename; gint rename_auto; GtkWidget *rename_box; GtkWidget *rename_entry; GtkWidget *rename_auto_box;};/* *-------------------------------------------------------------------------- * Adds 1 or 2 images (if 2, side by side) to a GenericDialog *-------------------------------------------------------------------------- */#define DIALOG_DEF_IMAGE_DIM_X 200#define DIALOG_DEF_IMAGE_DIM_Y 150static void generic_dialog_add_image(GenericDialog *gd, const gchar *path1, const gchar *header1, const gchar *path2, const gchar *header2, gint show_filename){ ImageWindow *imd; GtkWidget *hbox = NULL; GtkWidget *vbox; GtkWidget *label = NULL; if (path2) { hbox = pref_box_new(gd->vbox, TRUE, GTK_ORIENTATION_HORIZONTAL, PREF_PAD_SPACE); } /* image 1 */ vbox = gtk_vbox_new(FALSE, PREF_PAD_GAP); if (hbox) { GtkWidget *sep; gtk_box_pack_start(GTK_BOX(hbox), vbox, TRUE, TRUE, 0); sep = gtk_vseparator_new(); gtk_box_pack_start(GTK_BOX(hbox), sep, FALSE, FALSE, 0); gtk_widget_show(sep); } else { gtk_box_pack_start(GTK_BOX(gd->vbox), vbox, TRUE, TRUE, PREF_PAD_GAP); } gtk_widget_show(vbox); if (header1) { GtkWidget *head; head = pref_label_new(vbox, header1); pref_label_bold(head, TRUE, FALSE); gtk_misc_set_alignment(GTK_MISC(head), 0.0, 0.5); } imd = image_new(FALSE); gtk_widget_set_size_request(imd->widget, DIALOG_DEF_IMAGE_DIM_X, DIALOG_DEF_IMAGE_DIM_Y); gtk_box_pack_start(GTK_BOX(vbox), imd->widget, TRUE, TRUE, 0); image_change_path(imd, path1, 0.0); gtk_widget_show(imd->widget); if (show_filename) { label = pref_label_new(vbox, (path1 == NULL) ? "" : filename_from_path(path1)); } /* only the first image is stored (for use in gd_image_set) */ g_object_set_data(G_OBJECT(gd->dialog), "img_image", imd); g_object_set_data(G_OBJECT(gd->dialog), "img_label", label); /* image 2 */ if (hbox && path2) { vbox = pref_box_new(hbox, TRUE, GTK_ORIENTATION_VERTICAL, PREF_PAD_GAP); if (header2) { GtkWidget *head; head = pref_label_new(vbox, header2); pref_label_bold(head, TRUE, FALSE); gtk_misc_set_alignment(GTK_MISC(head), 0.0, 0.5); } imd = image_new(FALSE); gtk_widget_set_size_request(imd->widget, DIALOG_DEF_IMAGE_DIM_X, DIALOG_DEF_IMAGE_DIM_Y); gtk_box_pack_start(GTK_BOX(vbox), imd->widget, TRUE, TRUE, 0); image_change_path(imd, path2, 0.0); gtk_widget_show(imd->widget); pref_label_new(vbox, filename_from_path(path2)); }}static void generic_dialog_image_set(GenericDialog *gd, const gchar *path){ ImageWindow *imd; GtkWidget *label; imd = g_object_get_data(G_OBJECT(gd->dialog), "img_image"); label = g_object_get_data(G_OBJECT(gd->dialog), "img_label"); if (!imd) return; image_change_path(imd, path, 0.0); if (label) gtk_label_set_text(GTK_LABEL(label), filename_from_path(path));}/* *-------------------------------------------------------------------------- * Wrappers to aid in setting additional dialog properties (unde mouse, etc.) *-------------------------------------------------------------------------- */GenericDialog *file_util_gen_dlg(const gchar *title, const gchar *wmclass, const gchar *wmsubclass, GtkWidget *parent, gint auto_close, void (*cancel_cb)(GenericDialog *, gpointer), gpointer data){ GenericDialog *gd; gd = generic_dialog_new(title, wmclass, wmsubclass, parent, auto_close, cancel_cb, data); if (place_dialogs_under_mouse) { gtk_window_set_position(GTK_WINDOW(gd->dialog), GTK_WIN_POS_MOUSE); } return gd;}FileDialog *file_util_file_dlg(const gchar *title, const gchar *wmclass, const gchar *wmsubclass, GtkWidget *parent, void (*cancel_cb)(FileDialog *, gpointer), gpointer data){ FileDialog *fd; fd = file_dialog_new(title, wmclass, wmsubclass, parent, cancel_cb, data); if (place_dialogs_under_mouse) { gtk_window_set_position(GTK_WINDOW(GENERIC_DIALOG(fd)->dialog), GTK_WIN_POS_MOUSE); } return fd;}/* this warning dialog is copied from SLIK's ui_utildg.c, * because it does not have a mouse center option, * and we must center it before show, implement it here. */static void file_util_warning_dialog_ok_cb(GenericDialog *gd, gpointer data){ /* no op */}GenericDialog *file_util_warning_dialog(const gchar *heading, const gchar *message, const gchar *icon_stock_id, GtkWidget *parent){ GenericDialog *gd; gd = file_util_gen_dlg(heading, "GQview", "warning", parent, TRUE, NULL, NULL); generic_dialog_add_message(gd, icon_stock_id, heading, message); generic_dialog_add_button(gd, GTK_STOCK_OK, NULL, file_util_warning_dialog_ok_cb, TRUE); if (place_dialogs_under_mouse) { gtk_window_set_position(GTK_WINDOW(gd->dialog), GTK_WIN_POS_MOUSE); } gtk_widget_show(gd->dialog); return gd;}static gint filename_base_length(const gchar *name){ gint n; if (!name) return 0; n = strlen(name); if (filter_name_exists(name)) { const gchar *ext; ext = extension_from_path(name); if (ext) n -= strlen(ext); } return n;}/* *-------------------------------------------------------------------------- * Move and Copy routines *-------------------------------------------------------------------------- *//* * Multi file move */static FileDataMult *file_data_multiple_new(GList *source_list, const gchar *dest, gint copy){ FileDataMult *fdm = g_new0(FileDataMult, 1); fdm->confirm_all = FALSE; fdm->confirmed = FALSE; fdm->skip = FALSE; fdm->source_list = source_list; fdm->source_next = fdm->source_list; fdm->dest_base = g_strdup(dest); fdm->source = NULL; fdm->dest = NULL; fdm->copy = copy; return fdm;}static void file_data_multiple_free(FileDataMult *fdm){ path_list_free(fdm->source_list); g_free(fdm->dest_base); g_free(fdm->dest); g_free(fdm);}static void file_util_move_multiple(FileDataMult *fdm);static void file_util_move_multiple_ok_cb(GenericDialog *gd, gpointer data){ FileDataMult *fdm = data; fdm->confirmed = TRUE; if (fdm->rename_auto) { gchar *buf; buf = unique_filename_simple(fdm->dest); if (buf) { g_free(fdm->dest); fdm->dest = buf; } else { /* unique failed? well, return to the overwrite prompt :( */ fdm->confirmed = FALSE; } } else if (fdm->rename) { const gchar *name; name = gtk_entry_get_text(GTK_ENTRY(fdm->rename_entry)); if (strlen(name) == 0 || strcmp(name, filename_from_path(fdm->source)) == 0) { fdm->confirmed = FALSE; } else { g_free(fdm->dest); fdm->dest = concat_dir_and_file(fdm->dest_base, name); fdm->confirmed = !isname(fdm->dest); } } file_util_move_multiple(fdm);}static void file_util_move_multiple_all_cb(GenericDialog *gd, gpointer data){ FileDataMult *fdm = data; fdm->confirm_all = TRUE; if (fdm->rename_auto) fdm->rename_all = TRUE; file_util_move_multiple(fdm);}static void file_util_move_multiple_skip_cb(GenericDialog *gd, gpointer data){ FileDataMult *fdm = data; fdm->skip = TRUE; fdm->confirmed = TRUE; file_util_move_multiple(fdm);}static void file_util_move_multiple_skip_all_cb(GenericDialog *gd, gpointer data){ FileDataMult *fdm = data; fdm->skip = TRUE; fdm->confirm_all = TRUE; file_util_move_multiple(fdm);}static void file_util_move_multiple_continue_cb(GenericDialog *gd, gpointer data){ FileDataMult *fdm = data; fdm->confirmed = TRUE; file_util_move_multiple(fdm);}static void file_util_move_multiple_cancel_cb(GenericDialog *gd, gpointer data){ FileDataMult *fdm = data; file_data_multiple_free(fdm);}/* rename option */static void file_util_move_multiple_rename_auto_cb(GtkWidget *widget, gpointer data){ GenericDialog *gd = data; FileDataMult *fdm; fdm = gd->data; fdm->rename_auto = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); gtk_widget_set_sensitive(fdm->rename_box, !fdm->rename_auto); gtk_widget_set_sensitive(fdm->rename_entry, (!fdm->rename_auto && fdm->rename)); if (fdm->rename_auto) { gchar *preview; preview = unique_filename_simple(fdm->dest); if (preview) gtk_entry_set_text(GTK_ENTRY(fdm->rename_entry), filename_from_path(preview)); g_free(preview); } gtk_widget_set_sensitive(fdm->yes_all_button, (fdm->rename_auto || !fdm->rename));}static void file_util_move_multiple_rename_cb(GtkWidget *widget, gpointer data){ GenericDialog *gd = data; FileDataMult *fdm; fdm = gd->data; fdm->rename = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); gtk_widget_set_sensitive(fdm->rename_entry, fdm->rename); gtk_widget_set_sensitive(fdm->yes_all_button, !fdm->rename); if (fdm->rename) { const gchar *name; gtk_widget_grab_focus(fdm->rename_entry); name = gtk_entry_get_text(GTK_ENTRY(fdm->rename_entry)); gtk_editable_select_region(GTK_EDITABLE(fdm->rename_entry), 0, filename_base_length(name)); }}static GenericDialog *file_util_move_multiple_confirm_dialog(FileDataMult *fdm){ GenericDialog *gd; GtkWidget *hbox; gd = file_util_gen_dlg(_("Overwrite file"), "GQview", "dlg_confirm", NULL, TRUE, file_util_move_multiple_cancel_cb, fdm);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -