⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ui_pathsel.c

📁 Gqview,Linux下基于GTK+库写成的轻量级而能丰富的图像浏览程序。
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * (SLIK) SimpLIstic sKin functions * (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! */#ifdef HAVE_CONFIG_H#  include "config.h"#endif#include "intl.h"#include <stdio.h>#include <stdlib.h>#include <string.h>#include <dirent.h>#include <fcntl.h>#include <unistd.h>#include <sys/types.h>#include <sys/stat.h>#include <gtk/gtk.h>#include <gdk/gdkkeysyms.h> /* for key values */#include "ui_pathsel.h"#include "ui_bookmark.h"#include "ui_fileops.h"#include "ui_menu.h"#include "ui_misc.h"#include "ui_utildlg.h"#include "ui_tabcomp.h"#include "ui_tree_edit.h"#define DEST_WIDTH 250#define DEST_HEIGHT 210#define RENAME_PRESS_DELAY 333	/* 1/3 second, to allow double clicks */#define PATH_SEL_USE_HEADINGS FALSEenum {	FILTER_COLUMN_NAME = 0,	FILTER_COLUMN_FILTER};typedef struct _Dest_Data Dest_Data;struct _Dest_Data{	GtkWidget *d_view;	GtkWidget *f_view;	GtkWidget *entry;	gchar *filter;	gchar *path;	GList *filter_list;	GList *filter_text_list;	GtkWidget *filter_combo;	gint show_hidden;	GtkWidget *hidden_button;	GtkWidget *bookmark_list;	GtkTreePath *right_click_path;	void (*select_func)(const gchar *path, gpointer data);	gpointer select_data;	GenericDialog *gd;	/* any open confirm dialogs ? */};typedef struct _DestDel_Data DestDel_Data;struct _DestDel_Data{	Dest_Data *dd;	gchar *path;};static void dest_view_delete_dlg_cancel(GenericDialog *gd, gpointer data);/* *----------------------------------------------------------------------------- * (private) *----------------------------------------------------------------------------- */ static void dest_free_data(GtkWidget *widget, gpointer data){	Dest_Data *dd = data;	if (dd->gd)		{		GenericDialog *gd = dd->gd;		dest_view_delete_dlg_cancel(dd->gd, dd->gd->data);		generic_dialog_close(gd);		}	if (dd->right_click_path) gtk_tree_path_free(dd->right_click_path);	g_free(dd->filter);	g_free(dd->path);	g_free(dd);}static gint dest_check_filter(const gchar *filter, const gchar *file){	const gchar *f_ptr = filter;	const gchar *strt_ptr;	gint i;	gint l;	l = strlen(file);	if (filter[0] == '*') return TRUE;	while (f_ptr < filter + strlen(filter))		{		strt_ptr = f_ptr;		i=0;		while (*f_ptr != ';' && *f_ptr != '\0')			{			f_ptr++;			i++;			}		if (*f_ptr != '\0' && f_ptr[1] == ' ') f_ptr++;	/* skip space immediately after separator */		f_ptr++;		if (l >= i && strncasecmp(file + l - i, strt_ptr, i) == 0) return TRUE;		}	return FALSE;}#ifndef CASE_SORT#define CASE_SORT strcmp#endifstatic gint dest_sort_cb(void *a, void *b){	return CASE_SORT((gchar *)a, (gchar *)b);}static gint is_hidden(const gchar *name){	if (name[0] != '.') return FALSE;	if (name[1] == '\0') return FALSE;	if (name[1] == '.' && name[2] == '\0') return FALSE;	return TRUE;}static void dest_populate(Dest_Data *dd, const gchar *path){	DIR *dp;	struct dirent *dir;	struct stat ent_sbuf;	GList *path_list = NULL;	GList *file_list = NULL;	GList *list;	GtkListStore *store;	gchar *pathl;	if (!path) return;	pathl = path_from_utf8(path);	dp = opendir(pathl);	if (!dp)		{		/* dir not found */		g_free(pathl);		return;		}	while ((dir = readdir(dp)) != NULL)		{		/* skips removed files */		if (dir->d_ino > 0 && (dd->show_hidden || !is_hidden(dir->d_name)) )			{			gchar *name = dir->d_name;			gchar *filepath = g_strconcat(pathl, "/", name, NULL);			if (stat(filepath, &ent_sbuf) >= 0 && S_ISDIR(ent_sbuf.st_mode))				{				path_list = g_list_prepend(path_list, path_to_utf8(name));				}			else if (dd->f_view)				{				if (!dd->filter || (dd->filter && dest_check_filter(dd->filter, name)))					file_list = g_list_prepend(file_list, path_to_utf8(name));				}			g_free(filepath);			}		}	closedir(dp);	g_free(pathl);	path_list = g_list_sort(path_list, (GCompareFunc) dest_sort_cb);	file_list = g_list_sort(file_list, (GCompareFunc) dest_sort_cb);	store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(dd->d_view)));	gtk_list_store_clear(store);	list = path_list;	while (list)		{		GtkTreeIter iter;		gchar *filepath;		if (strcmp(list->data, ".") == 0)			{			filepath = g_strdup(path);			}		else if (strcmp(list->data, "..") == 0)			{			gchar *p;			filepath = g_strdup(path);			p = (gchar *)filename_from_path(filepath);			if (p - 1 != filepath) p--;			p[0] = '\0';			}		else			{			filepath = concat_dir_and_file(path, list->data);			}				gtk_list_store_append(store, &iter);		gtk_list_store_set(store, &iter, 0, list->data, 1, filepath, -1);		g_free(filepath);		list = list->next;		}	path_list_free(path_list);	if (dd->f_view)		{		store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(dd->f_view)));		gtk_list_store_clear(store);		list = file_list;		while (list)        	        {			GtkTreeIter iter;			gchar *filepath;			const gchar *name = list->data;			filepath = concat_dir_and_file(path, name);					gtk_list_store_append(store, &iter);			gtk_list_store_set(store, &iter, 0, name, 1, filepath, -1);			g_free(filepath);			list = list->next;			}		path_list_free(file_list);		}	g_free(dd->path);	dd->path = g_strdup(path);}static void dest_change_dir(Dest_Data *dd, const gchar *path, gint retain_name){	gchar *old_name = NULL;	gint s = 0;	if (retain_name)		{		const gchar *buf = gtk_entry_get_text(GTK_ENTRY(dd->entry));		if (!isdir(buf))			{			if (path && strcmp(path, "/") == 0)				{				old_name = g_strdup(filename_from_path(buf));				}			else				{				old_name = g_strconcat("/", filename_from_path(buf), NULL);				s = 1;				}			}		}	gtk_entry_set_text(GTK_ENTRY(dd->entry), path);	dest_populate(dd, path);	/* remember filename */	if (old_name)		{		gint pos = -1;		gtk_editable_insert_text(GTK_EDITABLE(dd->entry), old_name, -1, &pos);		gtk_editable_select_region(GTK_EDITABLE(dd->entry), strlen(path) + s, strlen(path) + strlen(old_name));		g_free(old_name);		}}/* *----------------------------------------------------------------------------- * drag and drop *----------------------------------------------------------------------------- */enum {	TARGET_URI_LIST,	TARGET_TEXT_PLAIN};static GtkTargetEntry dest_drag_types[] = {	{ "text/uri-list", 0, TARGET_URI_LIST },	{ "text/plain",    0, TARGET_TEXT_PLAIN }};#define dest_drag_types_n 2static void dest_dnd_set_data(GtkWidget *view,			      GdkDragContext *context, GtkSelectionData *selection_data,			      guint info, guint time, gpointer data){	gchar *path = NULL;	gchar *uri_text = NULL;	GList *list = NULL;	gint length = 0;	GtkTreeModel *model;	GtkTreeSelection *selection;	GtkTreeIter iter;	selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(view));	if (!gtk_tree_selection_get_selected(selection, &model, &iter)) return;	gtk_tree_model_get(model, &iter, 1, &path, -1);	if (!path) return;	list = g_list_append(list, path);	switch (info)		{		case TARGET_URI_LIST:			uri_text = uri_text_from_list(list, &length, FALSE);			break;		case TARGET_TEXT_PLAIN:			uri_text = uri_text_from_list(list, &length, TRUE);			break;		}	path_list_free(list);	if (!uri_text) return;	gtk_selection_data_set(selection_data, selection_data->target,			       8, uri_text, length);	g_free(uri_text);}static void dest_dnd_init(Dest_Data *dd){	gtk_tree_view_enable_model_drag_source(GTK_TREE_VIEW(dd->d_view), GDK_BUTTON1_MASK,					       dest_drag_types, dest_drag_types_n,					       GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK | GDK_ACTION_ASK);	g_signal_connect(G_OBJECT(dd->d_view), "drag_data_get",			 G_CALLBACK(dest_dnd_set_data), dd);	if (dd->f_view)		{		gtk_tree_view_enable_model_drag_source(GTK_TREE_VIEW(dd->f_view), GDK_BUTTON1_MASK,						       dest_drag_types, dest_drag_types_n,						       GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK | GDK_ACTION_ASK);		g_signal_connect(G_OBJECT(dd->f_view), "drag_data_get",				 G_CALLBACK(dest_dnd_set_data), dd);		}}/* *----------------------------------------------------------------------------- * destination widget file management utils *----------------------------------------------------------------------------- */static void dest_view_store_selection(Dest_Data *dd, GtkTreeView *view){	GtkTreeModel *model;	GtkTreeSelection *selection;	GtkTreeIter iter;	if (dd->right_click_path) gtk_tree_path_free(dd->right_click_path);	dd->right_click_path = NULL;	selection = gtk_tree_view_get_selection(view);	if (!gtk_tree_selection_get_selected(selection, &model, &iter))		{		return;		}	dd->right_click_path = gtk_tree_model_get_path(model, &iter);}static gint dest_view_rename_cb(TreeEditData *ted, const gchar *old, const gchar *new, gpointer data){	Dest_Data *dd = data;	GtkTreeModel *model;	GtkTreeIter iter;	gchar *buf;	gchar *old_path;	gchar *new_path;	model = gtk_tree_view_get_model(GTK_TREE_VIEW(ted->tree));	gtk_tree_model_get_iter(model, &iter, dd->right_click_path);	gtk_tree_model_get(model, &iter, 1, &old_path, -1);	if (!old_path) return FALSE;	buf = remove_level_from_path(old_path);	new_path = concat_dir_and_file(buf, new);	g_free(buf);	if (isname(new_path))		{		buf = g_strdup_printf(_("A file with name %s already exists."), new);		warning_dialog("Rename failed", buf, GTK_STOCK_DIALOG_INFO, dd->entry);		g_free(buf);		}	else if (!rename_file(old_path, new_path))		{		buf = g_strdup_printf(_("Failed to rename %s to %s."), old, new);		warning_dialog("Rename failed", buf, GTK_STOCK_DIALOG_ERROR, dd->entry);		g_free(buf);		}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -