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

📄 gtk.c

📁 一个曾经热门的网络游戏RO查看GRF工具的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
		g_static_mutex_unlock (&extractProgressM);		if (stop) goto end;	}	end:	if (timer)		g_timer_destroy (timer);	g_list_free (files);	g_list_free (indices);	g_static_mutex_lock (&extractProgressM);	extractProgress.failed = failed;	extractProgress.status = STATUS_DONE;	g_static_mutex_unlock (&extractProgressM);	return NULL;}static gbooleanwatch_extract_thread (gpointer user_data){	ExtractProgress ep;	g_static_mutex_lock (&extractProgressM);	memcpy (&ep, &extractProgress, sizeof (ExtractProgress));	g_static_mutex_unlock (&extractProgressM);	if (ep.status != lastKnownProgress.status) {		switch (ep.status) {		case STATUS_INIT:			break;		case STATUS_MKDIR:			gtk_progress_bar_set_text (GTK_PROGRESS_BAR (W(progress)),				_("Creating folders..."));			break;		case STATUS_EXTRACT:			gtk_progress_bar_set_text (GTK_PROGRESS_BAR (W(progress)),				_("0%"));			break;		case STATUS_DONE:			break;		default:			break;		};	}	if (ep.current != lastKnownProgress.current || ep.max != lastKnownProgress.max) {		if (ep.max == 0)			gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (W(progress)), 0.0);		else			gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (W(progress)),				(gdouble) ep.current / (gdouble) ep.max);		if (ep.status == STATUS_EXTRACT && ep.file) {			char *tmp, *basename;			basename = g_path_get_basename (ep.file);			tmp = str_to_utf8 (basename, NULL);			g_free (basename);			basename = g_strdup_printf ("%.1f%%: %s",				((gdouble) ep.current / (gdouble) ep.max) * 100, tmp);			g_free (tmp);			gtk_progress_bar_set_text (GTK_PROGRESS_BAR (W(progress)),				basename);			g_free (basename);		}	}	memcpy (&lastKnownProgress, &ep, sizeof (ExtractProgress));	return TRUE;}static gbooleanwatch_extract_thread_stop (gpointer user_data){	guint watcher;	gboolean result = TRUE;	g_static_mutex_lock (&extractProgressM);	if (extractProgress.status == STATUS_DONE) {		char *msg;		watcher = GPOINTER_TO_INT (user_data);		gtk_timeout_remove (watcher);		result = FALSE;		if (extractProgress.failed == 0)			msg = g_strdup_printf (_("%ld files extracted."), extractProgress.current);		else			msg = g_strdup_printf (_("%ld files extracted (%ld failed)."),				extractProgress.current, extractProgress.failed);		set_status (msg);		g_free (msg);		gtk_widget_hide (W(progressBox));		gtk_widget_set_sensitive (W(open), TRUE);		gtk_widget_set_sensitive (W(extract), TRUE);	}	g_static_mutex_unlock (&extractProgressM);	if (!result) {		g_thread_join (extractProgress.thread);		memset (&lastKnownProgress, 0, sizeof (ExtractProgress));	}	return result;}static voidextract_files (const char *savedir, GList *files, GList *indices){	GError *err = NULL;	GList *args;	guint watcher;	/* Run extraction as background thread */	args = g_list_append (NULL, (gpointer) savedir);	args = g_list_append (args, files);	args = g_list_append (args, indices);	memset (&extractProgress, 0, sizeof (ExtractProgress));	memset (&lastKnownProgress, 0, sizeof (ExtractProgress));	extractProgress.thread = g_thread_create (extract_thread,		args, TRUE, &err);	if (!extractProgress.thread) {		show_error (_("A system error occured while extracting (unable to create thread).\n%s"),			err->message);		g_error_free (err);		g_list_free (args);		memset (&extractProgress, 0, sizeof (ExtractProgress));		return;	}	/* Update GUI in main thread */	set_status (_("Extracting files..."));	gtk_widget_set_sensitive (W(open), FALSE);	gtk_widget_set_sensitive (W(extract), FALSE);	gtk_widget_set_sensitive (W(stop), TRUE);	gtk_widget_show (W(progressBox));	watcher = gtk_timeout_add (100, watch_extract_thread, NULL);	gtk_timeout_add (10, watch_extract_thread_stop, GINT_TO_POINTER (watcher));	return;}static voidsort_by_anything (GtkTreeViewColumn *column, gint sort_column, GtkSortType default_sort){	GtkTreeView *view = GTK_TREE_VIEW (W(filelist));	GtkTreeModel *model = gtk_tree_view_get_model (view);	GList *list, *cols = gtk_tree_view_get_columns (view);	gint sort_id;	GtkSortType sort_type;	for (list = cols; list; list = list->next) {		GtkTreeViewColumn *col = (GtkTreeViewColumn *) list->data;		gtk_tree_view_column_set_sort_indicator (col, FALSE);	}	g_list_free (cols);	gtk_tree_view_column_set_sort_indicator (column, TRUE);	gtk_tree_sortable_get_sort_column_id (GTK_TREE_SORTABLE (model), &sort_id, &sort_type);	if (sort_id == sort_column) {		sort_type = (sort_type == GTK_SORT_ASCENDING) ? GTK_SORT_DESCENDING : GTK_SORT_ASCENDING;		gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (model), sort_column, sort_type);		gtk_tree_view_column_set_sort_order (column, sort_type);	} else {		gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (model), sort_column, default_sort);		gtk_tree_view_column_set_sort_order (column, default_sort);	}}static voidsort_by_column (GtkTreeViewColumn *col, gpointer column){	sort_by_anything (col, GPOINTER_TO_INT (column), GTK_SORT_ASCENDING);}/*********************** * Callbacks ***********************/voidopen_cb (){	const char *fname = NULL;	gtk_file_selection_show_fileop_buttons (GTK_FILE_SELECTION (opensel));	if (gtk_dialog_run (GTK_DIALOG (opensel)) == GTK_RESPONSE_OK)		fname = gtk_file_selection_get_filename (GTK_FILE_SELECTION (opensel));	gtk_widget_hide (opensel);	if (fname)		open_grf_file (fname);}voidextract_cb (){	GtkTreeSelection *selection;	GList *list, *l;	GtkTreePath *path;	GtkTreeIter iter;	char *fname, *display;	unsigned long size, index;	void *data;	if (!grf) return;	if (!savesel) {		gchar *tmp, *dir;		/* We want the extract file selector to have		   the same working directory as the open one */		savesel = gtk_file_selection_new (_("Extract & save file"));		dirsel = gtk_file_selection_new (_("Extract & save to folder"));		gtk_widget_set_sensitive (GTK_FILE_SELECTION (dirsel)->file_list,			FALSE);		tmp = g_path_get_dirname (filename->str);		dir = g_strdup_printf ("%s%c", tmp, G_DIR_SEPARATOR);		gtk_file_selection_complete (GTK_FILE_SELECTION (savesel), dir);		gtk_file_selection_complete (GTK_FILE_SELECTION (dirsel), dir);		g_free (dir);		g_free (tmp);	}	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (W(filelist)));	list = gtk_tree_selection_get_selected_rows (selection, NULL);	if (list && !list->next) {		/* 1 file selected */		GtkTreePath *path;		const gchar *savename = NULL;		gchar *basename;		GrfError err;		/* Get file information */		path = (GtkTreePath *) list->data;		gtk_tree_model_get_iter (filelist, &iter, path);		gtk_tree_model_get (filelist, &iter,			INDEX_COL, &index,			DISPLAY_COL, &display,			-1);		/* Setup save dialog */		basename = strrchr (display, '\\');		if (basename)			gtk_file_selection_set_filename (GTK_FILE_SELECTION (savesel),				basename + 1);		if (gtk_dialog_run (GTK_DIALOG (savesel)) == GTK_RESPONSE_OK)			savename = gtk_file_selection_get_filename (GTK_FILE_SELECTION (savesel));		gtk_widget_hide (savesel);		if (!savename) {			g_free (display);			goto end;		}		/* Extract */		if (grf_index_extract (grf, index, savename, &err)) {			char *msg;			msg = g_strdup_printf (_("%s saved"), basename + 1);			set_status (msg);			g_free (msg);		} else {			show_error (_("Unable to extract %s:\n%s"),				basename + 1,				grf_strerror (err));		}		g_free (display);	} else {		/* More than 1 file selected, or nothing selected */		const gchar *savedir = NULL;		GList *files = NULL, *indices = NULL;		if (gtk_dialog_run (GTK_DIALOG (dirsel)) == GTK_RESPONSE_OK)			savedir = gtk_file_selection_get_filename (GTK_FILE_SELECTION (dirsel));		gtk_widget_hide (dirsel);		if (!savedir)			goto end;		if (!g_file_test (savedir, G_FILE_TEST_IS_DIR)) {			if (mkdir (savedir, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) != 0) {				show_error (_("Unable to create a new folder: %s"),					g_strerror (errno));				goto end;			}		}		if (list) {			/* More than 1 file is selected */			for (l = list; l; l = l->next) {				path = (GtkTreePath *) l->data;				gtk_tree_model_get_iter (filelist, &iter, path);				gtk_tree_model_get (filelist, &iter,					INDEX_COL, &index,					-1);				files = g_list_prepend (files, grf->files[index].name);				indices = g_list_prepend (indices, GINT_TO_POINTER (index));			}			list = g_list_reverse (list);		} else if (gtk_tree_model_get_iter_first (filelist, &iter)) {			/* Nothing is selected */			do {				gtk_tree_model_get (filelist, &iter,					INDEX_COL, &index,					-1);				files = g_list_prepend (files, grf->files[index].name);				indices = g_list_prepend (indices, GINT_TO_POINTER (index));			} while (gtk_tree_model_iter_next (filelist, &iter));			list = g_list_reverse (list);		}		extract_files (savedir, files, indices);	}	end:	g_list_foreach (list, (GFunc) gtk_tree_path_free, NULL);	g_list_free (list);}voidpreview_toggled_cb (){	gboolean active;	active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (W(preview_toggle)));	if (active)		gtk_widget_show (W(preview_pane));	else		gtk_widget_hide (W(preview_pane));}voidfilelist_activated_cb (GtkTreeView *tree, GtkTreePath *path){	extract_cb ();}voidfill_filelist_cb (){	gchar *msg;	unsigned long i;	if (!grf) return;	set_status (_("Searching..."));	while (gtk_events_pending ()) gtk_main_iteration ();	i = fill_filelist ();	msg = g_strdup_printf (_("%ld files found"), i);	set_status (msg);	g_free (msg);}static voidfilelist_selection_changed_cb (GtkTreeSelection *selection, GtkTreeView *tree){	GList *list, *l;	char *title, *tmp;	GtkTreeIter iter;	GtkTreePath *this;	unsigned long index;	guint len;	if (!grf || filling) return;	list = gtk_tree_selection_get_selected_rows (selection, NULL);	len = g_list_length (list);	if (list && !list->next) { /* 1 file selected */		char *fname, *display;		this = (GtkTreePath *) list->data;		if (current_selection) {			if (gtk_tree_path_compare (current_selection, this) == 0)				/* The user selected an already selected row; don't do anything */				goto end;			gtk_tree_path_free (current_selection);		}		current_selection = gtk_tree_path_copy (this);		gtk_tree_model_get_iter (filelist, &iter, this);		gtk_tree_model_get (filelist, &iter,			INDEX_COL, &index,			DISPLAY_COL, &display,			-1);		tmp = g_path_get_basename (filename->str);		title = g_strdup_printf (_("%s: %ld files - file #%ld selected"),			tmp, grf->nfiles, index + 1);		set_status (title);		g_free (tmp);		g_free (title);		preview_file (display, grf->files[index].name);		g_free (display);	} else if (!list) { /* no files selected */		tmp = g_path_get_basename (filename->str);		title = g_strdup_printf (_("%s: %ld files"), tmp, grf->nfiles);		set_status (title);		g_free (tmp);		g_free (title);	} else { /* >1 files selected */		char *sizestr;		unsigned long size = 0;		for (l = list; l; l = l->next) {			this = (GtkTreePath *) list->data;			gtk_tree_model_get_iter (filelist, &iter, this);			gtk_tree_model_get (filelist, &iter,				INDEX_COL, &index,				-1);			size += grf->files[index].real_len;		}		sizestr = friendly_size_name (size);		tmp = g_path_get_basename (filename->str);		title = g_strdup_printf (_("%s: %ld files - %d files selected (%s)"),			tmp, grf->nfiles, len, sizestr);		set_status (title);		g_free (tmp);		g_free (title);		g_free (sizestr);	}	end:	g_list_foreach (list, (GFunc) gtk_tree_path_free, NULL);	g_list_free (list);}voidstop_cb (){	g_static_mutex_lock (&extractProgressM);	if (extractProgress.thread)		extractProgress.stop = TRUE;	g_static_mutex_unlock (&extractProgressM);	gtk_widget_set_sensitive (W(stop), FALSE);}intmain (int argc, char *argv[]){	GtkTreeView *tree;	GtkTreeViewColumn *column;	GtkTreeSelection *selection;	GtkTooltips *tips;	g_thread_init (NULL);	gtk_init (&argc, &argv);	memset (&extractProgress, 0, sizeof (ExtractProgress));	g_static_mutex_init (&extractProgressM);	xml = load_glade ("grftool.glade");	opensel = gtk_file_selection_new (_("Open GRF archive"));	filename = g_string_new ("");	/* Manually set tooltips (libglade bug??) */	tips = gtk_tooltips_new ();	gtk_tooltips_set_tip (tips, W(open),		_("Open GRF file"), NULL);	gtk_tooltips_set_tip (tips, W(extract),		_("Extract all files or selected files"), NULL);	gtk_tooltips_set_tip (tips, W(preview_toggle),		_("Enable/disable preview of files"), NULL);	/* Setup the file list model and widget */	filelist = GTK_TREE_MODEL (gtk_list_store_new (N_COLS,		G_TYPE_ULONG,	/* index */		G_TYPE_STRING,	/* display name (filename converted to UTF-8) */		G_TYPE_STRING,	/* type */		G_TYPE_ULONG,	/* decompressed file size */		G_TYPE_STRING	/* file size string */	));	tree = GTK_TREE_VIEW (W(filelist));	g_object_set (tree,		"model", filelist,		"rules-hint", TRUE,		NULL);	selection = gtk_tree_view_get_selection (tree);	gtk_tree_selection_set_mode (selection, GTK_SELECTION_MULTIPLE);	g_signal_connect (G_OBJECT (selection), "changed",		G_CALLBACK (filelist_selection_changed_cb), tree);	gtk_tree_sortable_set_default_sort_func (GTK_TREE_SORTABLE (filelist),		(GtkTreeIterCompareFunc) gtk_false, NULL, NULL);	column = gtk_tree_view_column_new_with_attributes (		_("Filename"),		gtk_cell_renderer_text_new (),		"text", DISPLAY_COL,		NULL);	g_object_set (column,		"reorderable", TRUE,		"resizable", TRUE,		"clickable", TRUE,		NULL);	gtk_tree_view_append_column (tree, column);	g_signal_connect (G_OBJECT (column), "clicked",		G_CALLBACK (sort_by_column), GINT_TO_POINTER (DISPLAY_COL));	column = gtk_tree_view_column_new_with_attributes (		_("Type"),		gtk_cell_renderer_text_new (),		"text", TYPE_COL,		NULL);	g_object_set (column,		"reorderable", TRUE,		"resizable", TRUE,		"clickable", TRUE,		NULL);	gtk_tree_view_append_column (tree, column);	g_signal_connect (G_OBJECT (column), "clicked",		G_CALLBACK (sort_by_column), GINT_TO_POINTER (TYPE_COL));	column = gtk_tree_view_column_new_with_attributes (		_("Size"),		gtk_cell_renderer_text_new (),		"text", SIZE_DISPLAY_COL,		NULL);	g_object_set (column,		"reorderable", TRUE,		"resizable", TRUE,		"clickable", TRUE,		NULL);	gtk_tree_view_append_column (tree, column);	g_signal_connect (G_OBJECT (column), "clicked",		G_CALLBACK (sort_by_column), GINT_TO_POINTER (SIZE_COL));	gtk_tree_view_set_headers_visible (tree, TRUE);	gtk_widget_modify_bg (W(viewport1), GTK_STATE_NORMAL,		&(gtk_widget_get_style (W(viewport1))->white));	/* Show the GUI */	set_status (_("Click Open to open a GRF archive."));	busy_cursor = gdk_cursor_new (GDK_WATCH);	if (argv[1])		gtk_idle_add (idle_open, argv[1]);	gtk_widget_realize (W(main));	gtk_widget_show (W(main));	gtk_main ();	return 0;}

⌨️ 快捷键说明

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