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

📄 search.c

📁 Gqview,Linux下基于GTK+库写成的轻量级而能丰富的图像浏览程序。
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * GQview * (C) 2005 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 "search.h"#include "bar_info.h"#include "cache.h"#include "collect.h"#include "collect-table.h"#include "dnd.h"#include "dupe.h"#include "image-load.h"#include "info.h"#include "editors.h"#include "img-view.h"#include "filelist.h"#include "layout_image.h"#include "menu.h"#include "print.h"#include "thumb.h"#include "utilops.h"#include "ui_bookmark.h"#include "ui_fileops.h"#include "ui_menu.h"#include "ui_misc.h"#include "ui_spinner.h"#include "ui_tabcomp.h"#include "ui_tree_edit.h"#include <gdk/gdkkeysyms.h> /* for keyboard values */#define DEF_SEARCH_WIDTH  700#define DEF_SEARCH_HEIGHT 450#define SEARCH_BUFFER_MATCH_LOAD 20#define SEARCH_BUFFER_MATCH_HIT  5#define SEARCH_BUFFER_MATCH_MISS 1#define SEARCH_BUFFER_FLUSH_SIZE 99typedef enum {	SEARCH_MATCH_NONE,	SEARCH_MATCH_EQUAL,	SEARCH_MATCH_CONTAINS,	SEARCH_MATCH_UNDER,	SEARCH_MATCH_OVER,	SEARCH_MATCH_BETWEEN,	SEARCH_MATCH_ALL,	SEARCH_MATCH_ANY} MatchType;enum {	SEARCH_COLUMN_POINTER = 0,	SEARCH_COLUMN_RANK,	SEARCH_COLUMN_THUMB,	SEARCH_COLUMN_NAME,	SEARCH_COLUMN_SIZE,	SEARCH_COLUMN_DATE,	SEARCH_COLUMN_DIMENSIONS,	SEARCH_COLUMN_PATH,	SEARCH_COLUMN_COUNT	/* total columns */};typedef struct _SearchData SearchData;struct _SearchData{	GtkWidget *window;	GtkWidget *button_thumbs;	GtkWidget *label_status;	GtkWidget *label_progress;	GtkWidget *button_start;	GtkWidget *button_stop;	GtkWidget *spinner;	GtkWidget *box_search;	GtkWidget *menu_path;	GtkWidget *path_entry;	GtkWidget *check_recurse;	GtkWidget *result_view;	GtkWidget *check_name;	GtkWidget *menu_name;	GtkWidget *entry_name;	GtkWidget *check_name_match_case;	GtkWidget *check_size;	GtkWidget *menu_size;	GtkWidget *spin_size;	GtkWidget *spin_size_end;	GtkWidget *check_date;	GtkWidget *menu_date;	GtkWidget *date_sel;	GtkWidget *date_sel_end;	GtkWidget *check_dimensions;	GtkWidget *menu_dimensions;	GtkWidget *spin_width;	GtkWidget *spin_height;	GtkWidget *spin_width_end;	GtkWidget *spin_height_end;	GtkWidget *check_similarity;	GtkWidget *spin_similarity;	GtkWidget *entry_similarity;	GtkWidget *check_keywords;	GtkWidget *menu_keywords;	GtkWidget *entry_keywords;	gchar *search_path;	gint   search_path_recurse;	gchar *search_name;	gint   search_name_match_case;	gint64 search_size;	gint64 search_size_end;	gint   search_date_y;	gint   search_date_m;	gint   search_date_d;	gint   search_date_end_y;	gint   search_date_end_m;	gint   search_date_end_d;	gint   search_width;	gint   search_height;	gint   search_width_end;	gint   search_height_end;	gint   search_similarity;	gchar *search_similarity_path;	CacheData *search_similarity_cd;	GList *search_keyword_list;	MatchType search_type;	MatchType match_name;	MatchType match_size;	MatchType match_date;	MatchType match_dimensions;	MatchType match_keywords;	gboolean match_name_enable;	gboolean match_size_enable;	gboolean match_date_enable;	gboolean match_dimensions_enable;	gboolean match_similarity_enable;	gboolean match_keywords_enable;	GList *search_folder_list;	GList *search_done_list;	GList *search_file_list;	GList *search_buffer_list;	gint search_count;	gint search_total;	gint search_buffer_count;	gint search_idle_id;	gint update_idle_id;	ImageLoader *img_loader;	CacheData   *img_cd;	FileData *click_fd;	ThumbLoader *thumb_loader;	gint thumb_enable;	FileData *thumb_fd;};typedef struct _MatchFileData MatchFileData;struct _MatchFileData{	FileData fd;	gint width;	gint height;	gint rank;};typedef struct _MatchList MatchList;struct _MatchList{	const gchar *text;	const MatchType type;};static const MatchList text_search_menu_path[] = {	{ N_("folder"),		SEARCH_MATCH_NONE },	{ N_("comments"),	SEARCH_MATCH_ALL },	{ N_("results"),	SEARCH_MATCH_CONTAINS }};static const MatchList text_search_menu_name[] = {	{ N_("contains"),	SEARCH_MATCH_CONTAINS },	{ N_("is"),		SEARCH_MATCH_EQUAL }};static const MatchList text_search_menu_size[] = {	{ N_("equal to"),	SEARCH_MATCH_EQUAL },	{ N_("less than"),	SEARCH_MATCH_UNDER },	{ N_("greater than"),	SEARCH_MATCH_OVER },	{ N_("between"),	SEARCH_MATCH_BETWEEN }};static const MatchList text_search_menu_date[] = {	{ N_("equal to"),	SEARCH_MATCH_EQUAL },	{ N_("before"),		SEARCH_MATCH_UNDER },	{ N_("after"),		SEARCH_MATCH_OVER },	{ N_("between"),	SEARCH_MATCH_BETWEEN }};static const MatchList text_search_menu_keyword[] = {	{ N_("match all"),	SEARCH_MATCH_ALL },	{ N_("match any"),	SEARCH_MATCH_ANY },	{ N_("exclude"),	SEARCH_MATCH_NONE }};static GList *search_window_list = NULL;static gint search_result_selection_count(SearchData *sd, gint64 *bytes);static gint search_result_count(SearchData *sd, gint64 *bytes);static void search_window_close(SearchData *sd);/* *------------------------------------------------------------------- * utils *------------------------------------------------------------------- */static time_t convert_dmy_to_time(gint day, gint month, gint year){	struct tm lt;	lt.tm_sec = 0;	lt.tm_min = 0;	lt.tm_hour = 0;	lt.tm_mday = day;	lt.tm_mon = month - 1;	lt.tm_year = year - 1900;	lt.tm_isdst = 0;	return mktime(&lt);}static void search_status_update(SearchData *sd){	gchar *buf;	gint t;	gint s;	gint64 t_bytes;	gint64 s_bytes;	gchar *tt;	gchar *ts;	t = search_result_count(sd, &t_bytes);	s = search_result_selection_count(sd, &s_bytes);	if (s > 0)		{		tt = text_from_size_abrev(t_bytes);		ts = text_from_size_abrev(s_bytes);		buf = g_strdup_printf(_("%s, %d files (%s, %d)"), tt, t, ts, s);		g_free(tt);		g_free(ts);		}	else		{		tt = text_from_size_abrev(t_bytes);		buf = g_strdup_printf(_("%s, %d files"), tt, t);		g_free(tt);		}	gtk_label_set_text(GTK_LABEL(sd->label_status), buf);	g_free(buf);}static void search_progress_update(SearchData *sd, gint search, gdouble thumbs){	if (search || thumbs >= 0.0)		{		gchar *buf;		const gchar *message;		if (search && (sd->search_folder_list || sd->search_file_list))			message = _("Searching...");		else if (thumbs >= 0.0)			message = _("Loading thumbs...");		else			message = "";		buf = g_strdup_printf("%s(%d / %d)", message, sd->search_count, sd->search_total);		gtk_progress_bar_set_text(GTK_PROGRESS_BAR(sd->label_progress), buf);		gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(sd->label_progress),					      (thumbs >= 0.0) ? thumbs : 0.0);		g_free(buf);		}	else		{		gtk_progress_bar_set_text(GTK_PROGRESS_BAR(sd->label_progress), "");		gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(sd->label_progress), 0.0);		}}/* *------------------------------------------------------------------- * result list *------------------------------------------------------------------- */static gint search_result_find_row(SearchData *sd, FileData *fd, GtkTreeIter *iter){	GtkTreeModel *store;	gint valid;	gint n = 0;	store = gtk_tree_view_get_model(GTK_TREE_VIEW(sd->result_view));	valid = gtk_tree_model_get_iter_first(store, iter);	while (valid)		{		FileData *fd_n;		n++;		gtk_tree_model_get(store, iter, SEARCH_COLUMN_POINTER, &fd_n, -1);		if (fd_n == fd) return n;		valid = gtk_tree_model_iter_next(store, iter);		}	return -1;}static gint search_result_row_selected(SearchData *sd, FileData *fd){	GtkTreeModel *store;	GtkTreeSelection *selection;	GList *slist;	GList *work;	gint found = FALSE;	selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(sd->result_view));	slist = gtk_tree_selection_get_selected_rows(selection, &store);	work = slist;	while (!found && work)		{		GtkTreePath *tpath = work->data;		FileData *fd_n;		GtkTreeIter iter;		gtk_tree_model_get_iter(store, &iter, tpath);		gtk_tree_model_get(store, &iter, SEARCH_COLUMN_POINTER, &fd_n, -1);		if (fd_n == fd) found = TRUE;		work = work->next;		}	g_list_foreach(slist, (GFunc)gtk_tree_path_free, NULL);	g_list_free(slist);	return found;}static gint search_result_selection_util(SearchData *sd, gint64 *bytes, GList **list){	GtkTreeModel *store;	GtkTreeSelection *selection;	GList *slist;	GList *work;	gint n = 0;	gint64 total = 0;	GList *plist = NULL;	store = gtk_tree_view_get_model(GTK_TREE_VIEW(sd->result_view));	selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(sd->result_view));	slist = gtk_tree_selection_get_selected_rows(selection, &store);	work = slist;	while (work)		{		n++;		if (bytes || list)			{			GtkTreePath *tpath = work->data;			FileData *fd;			GtkTreeIter iter;			gtk_tree_model_get_iter(store, &iter, tpath);			gtk_tree_model_get(store, &iter, SEARCH_COLUMN_POINTER, &fd, -1);			total += fd->size;			if (list) plist = g_list_prepend(plist, g_strdup(fd->path));			}					work = work->next;		}	g_list_foreach(slist, (GFunc)gtk_tree_path_free, NULL);	g_list_free(slist);	if (bytes) *bytes = total;	if (list) *list = g_list_reverse(plist);	return n;}static GList *search_result_selection_list(SearchData *sd){	GList *list;	search_result_selection_util(sd, NULL, &list);	return list;}static gint search_result_selection_count(SearchData *sd, gint64 *bytes){	return search_result_selection_util(sd, bytes, NULL);}static gint search_result_util(SearchData *sd, gint64 *bytes, GList **list){	GtkTreeModel *store;	GtkTreeIter iter;	gint valid;	gint n = 0;	gint64 total = 0;	GList *plist = NULL;	store = gtk_tree_view_get_model(GTK_TREE_VIEW(sd->result_view));	valid = gtk_tree_model_get_iter_first(store, &iter);	while (valid)		{		n++;		if (bytes || list)			{			FileData *fd;			gtk_tree_model_get(store, &iter, SEARCH_COLUMN_POINTER, &fd, -1);			total += fd->size;			if (list) plist = g_list_prepend(plist, g_strdup(fd->path));			}		valid = gtk_tree_model_iter_next(store, &iter);		}	if (bytes) *bytes = total;	if (list) *list = g_list_reverse(plist);	return n;}static GList *search_result_get_path_list(SearchData *sd){	GList *list = NULL;	search_result_util(sd, NULL, &list);	return list;}static gint search_result_count(SearchData *sd, gint64 *bytes){	return search_result_util(sd, bytes, NULL);}static void search_result_append(SearchData *sd, MatchFileData *mfd){	FileData *fd;	GtkListStore *store;	GtkTreeIter iter;	gchar *text_size;	gchar *text_dim = NULL;	fd = (FileData *)mfd;	if (!fd) return;	text_size = text_from_size(fd->size);	if (mfd->width > 0 && mfd->height > 0) text_dim = g_strdup_printf("%d x %d", mfd->width, mfd->height);	store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(sd->result_view)));	gtk_list_store_append(store, &iter);	gtk_list_store_set(store, &iter,				SEARCH_COLUMN_POINTER, fd,				SEARCH_COLUMN_RANK, mfd->rank,				SEARCH_COLUMN_THUMB, fd->pixbuf,				SEARCH_COLUMN_NAME, fd->name,				SEARCH_COLUMN_SIZE, text_size,				SEARCH_COLUMN_DATE, text_from_time(fd->date),				SEARCH_COLUMN_DIMENSIONS, text_dim,				SEARCH_COLUMN_PATH, fd->path,				-1);	g_free(text_size);	g_free(text_dim);}static GList *search_result_refine_list(SearchData *sd){	GList *list = NULL;	GtkTreeModel *store;	GtkTreeIter iter;	gint valid;	store = gtk_tree_view_get_model(GTK_TREE_VIEW(sd->result_view));	valid = gtk_tree_model_get_iter_first(store, &iter);	while (valid)		{		FileData *fd;		gtk_tree_model_get(store, &iter, SEARCH_COLUMN_POINTER, &fd, -1);		list = g_list_prepend(list, fd);		valid = gtk_tree_model_iter_next(store, &iter);		}

⌨️ 快捷键说明

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