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

📄 file.c

📁 一个简单的文本编辑器
💻 C
📖 第 1 页 / 共 3 页
字号:
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- *//* * gedit * * Copyright (C) 1998, 1999, 2000 Alex Roberts, Evan Lawrence, Jason Leach, Jose M Celorio * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. * * Authors: *   Chema Celorio  <chema@celorio.com> */#include <config.h>#include <gnome.h>#include <sys/stat.h> /* for stat() */#include <unistd.h>  /* for gedit_stdin_open () */#include <stdio.h>   /* for gedit_stdin_open () */#include <libgnomevfs/gnome-vfs.h>#include "commands.h"#include "document.h"#include "view.h" #include "prefs.h"#include "file.h"#include "utils.h"#include "recent.h"#include "window.h"#include "print.h"#include "undo.h"#include "search.h"#include "dialogs/dialogs.h"#define GEDIT_STDIN_BUFSIZE 1024#define PREALLOCATED_BUF_LEN 4096GtkWidget *save_file_selector = NULL;#if 0/* Don't use public variables */GtkWidget *open_file_selector = NULL;#endifvoid file_new_cb (GtkWidget *widget, gpointer cbdata);void file_open_cb (GtkWidget *widget, gpointer cbdata);gint file_save_document (GeditDocument *doc);void file_save_cb (GtkWidget *widget, gpointer cbdata);void file_save_as_cb (GtkWidget *widget, gpointer cbdata);void file_save_all_cb (GtkWidget *widget, gpointer cbdata);void file_close_cb(GtkWidget *widget, gpointer cbdata);void file_close_all_cb(GtkWidget *widget, gpointer cbdata);void file_revert_cb (GtkWidget *widget, gpointer cbdata);void file_quit_cb (GtkWidget *widget, gpointer cbdata);void uri_open_cb (GtkWidget *widget, gpointer cbdata);       gint gedit_file_create_popup (const gchar *title);#if 0/* don't add prototypes for public functions */static void gedit_file_open_ok_sel   (GtkWidget *widget, GtkFileSelection *files);#endifstatic void gedit_file_save_as_ok_sel (GtkWidget *w, gpointer cbdata);static gint delete_event_cb (GtkWidget *w, GdkEventAny *e);static void cancel_cb (GtkWidget *w, gpointer cbdata);/* Close all flag */       void gedit_close_all_flag_clear (void);static void gedit_close_all_flag_status (guchar *function);static void gedit_close_all_flag_verify (guchar *function);gchar * gedit_file_convert_to_full_pathname (const gchar * fname);static void  save_all_continue (GtkWidget *widget, gpointer cbdata);typedef enum {	SAVE_ALL_RUNNING,	SAVE_ALL_ENDED} GeditSaveAllFlagStates;;static gint save_all_flag = SAVE_ALL_ENDED;typedef struct {	GeditDocument *doc;	GeditView *view;	gchar *tmp_buf;} HackyStruct;static gboolean gedit_view_insert_if_mapped (HackyStruct *hack){	g_return_val_if_fail (GEDIT_IS_VIEW (hack->view), FALSE);	if (!GTK_WIDGET_REALIZED (hack->view->text)) {		g_print ("not mapped, returning\n");		return TRUE;	}		gtk_text_insert (GTK_TEXT (hack->view->text), NULL,			 NULL, NULL, hack->tmp_buf, strlen (hack->tmp_buf));	gedit_view_set_position (hack->view, 0);		g_free (hack->tmp_buf);	g_free (hack);	return FALSE;}static voidgedit_document_insert_text_when_mapped (GeditDocument *doc, const gchar * tmp_buf,					gint pos, gboolean something){	HackyStruct *hack;	gedit_debug (DEBUG_FILE, "");	hack = g_new (HackyStruct, 1);	hack->doc = doc;	hack->view = g_list_nth_data (doc->views, 0);	hack->tmp_buf = g_strdup (tmp_buf);	gtk_idle_add ((GtkFunction) gedit_view_insert_if_mapped,		      hack);		}	/* TODO: add flash on all operations ....Chema*//*        what happens when you open the same doc	  twice. I think we should add another view          of the same doc versus opening it twice. Chema*//** * gedit_file_open: * @doc: Document window to fill with text * @fname: Filename to open * * Open a file and read it into the text widget. * * Return value: 0 on success, 1 on error. */gintgedit_file_open (GeditDocument *doc, const gchar *fname){	GnomeVFSFileInfo *info;	GnomeVFSHandle *from_handle;	GnomeVFSResult  result;	GnomeVFSURI* uri;	const gchar* scheme;	GString *tmp_buf = NULL;			GeditView *view;				gedit_debug (DEBUG_FILE, "");	g_return_val_if_fail (fname != NULL, 1);		if (doc != NULL) 	{		g_return_val_if_fail (doc->filename != fname, -1);	}	gedit_flash_va ("%s %s", _(MSGBAR_LOADING_FILE), fname);		/* Update UI */	while (gtk_events_pending ())		  gtk_main_iteration ();	info = gnome_vfs_file_info_new ();	result = gnome_vfs_get_file_info (fname, 					  info,					  (GNOME_VFS_FILE_INFO_GET_MIME_TYPE					   | GNOME_VFS_FILE_INFO_FOLLOW_LINKS));	if ((result != GNOME_VFS_OK) || 	    !(info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_TYPE) ||	    (info->type != GNOME_VFS_FILE_TYPE_REGULAR))	{		gchar *errstr = g_strdup_printf (_("An error was encountered while opening the file \"%s\"."					"\nPlease make sure the file exists."), fname);		gnome_app_error (gedit_window_active_app(), errstr);		g_free (errstr);		if(result == GNOME_VFS_OK)			gnome_vfs_file_info_clear (info);		return 1;	}	if(info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_SIZE)	{		tmp_buf = g_string_sized_new (info->size + 1);	}	else	{		tmp_buf = g_string_sized_new (PREALLOCATED_BUF_LEN);	}	if (tmp_buf == NULL)	{		gchar *errstr = g_strdup_printf (_("An error was encountered while opening the file \"%s\"."						   "\nCould not allocate the required memory."), fname);		gnome_app_error (gedit_window_active_app(), errstr);		g_free (errstr);		gnome_vfs_file_info_clear (info);		return 1;		}	result = gnome_vfs_open (&from_handle, fname, GNOME_VFS_OPEN_READ);	if (result != GNOME_VFS_OK)	{		gchar *errstr = g_strdup_printf (_("An error was encountered while reading the file: \n\n%s\n\n"						   "Make sure that you have permissions for opening the file. "), 						   fname);		gnome_app_error (gedit_window_active_app(), errstr);		g_free (errstr);		g_string_free(tmp_buf, TRUE);		gnome_vfs_file_info_clear (info);		return 1;	}		while (1) 	{		GnomeVFSFileSize bytes_read;		guint8           data [1025];				result = gnome_vfs_read (from_handle, data, 1024, &bytes_read);				if ((result != GNOME_VFS_OK) && (result != GNOME_VFS_ERROR_EOF))		{			gchar *errstr = g_strdup_printf (_("An error was encountered while reading the file: \n\n%s"), 						   	fname);			gnome_app_error (gedit_window_active_app(), errstr);			g_free (errstr);			g_string_free(tmp_buf, TRUE);			gnome_vfs_file_info_clear (info);			return 1;		}		if (bytes_read == 0)		{			break;		}				if (bytes_read >  0 && bytes_read <= 1024)		{			data [bytes_read] = '\0';		}		else 		{			gchar *errstr = g_strdup_printf (_("Internal error reading the file: \n\n%s\n\n"							   "Please, report this error to submit@bugs.gnome.org."), fname);			gnome_app_error (gedit_window_active_app(), errstr);			g_free (errstr);			g_string_free(tmp_buf, TRUE);			gnome_vfs_file_info_clear (info);			return 1;		}				g_string_append(tmp_buf, data);	}	result = gnome_vfs_close (from_handle);		if (result != GNOME_VFS_OK)	{		gchar *errstr = g_strdup_printf (_("An error was encountered while closing the file: \n\n%s"), 						   fname);		gnome_app_error (gedit_window_active_app(), errstr);		g_free (errstr);		g_string_free(tmp_buf, TRUE);		gnome_vfs_file_info_clear (info);		return 1;	}	if (doc==NULL) 	{		doc = gedit_document_new ();		doc->filename = g_strdup (fname);		doc->untitled_number = 0;		gedit_document_insert_text_when_mapped (doc, tmp_buf->str, 0, FALSE);	} 	else 	{		if (doc->filename != NULL)			g_free (doc->filename);		doc->filename = g_strdup (fname);		doc->untitled_number = 0;		gedit_document_insert_text (doc, tmp_buf->str, 0, FALSE);		/* Set the cursor position to the start */		view = g_list_nth_data (doc->views, 0);		g_return_val_if_fail (view!=NULL, 1);		gedit_view_set_position (view, 0);	}		/* Conservatively set doc to readonly */	gedit_document_set_readonly (doc, TRUE);	uri = gnome_vfs_uri_new (fname);	if (uri != NULL)	{		scheme = gnome_vfs_uri_get_scheme(uri);		/* FIXME: all remote files are marked as readonly */		if ((scheme != NULL) && (strcmp (scheme, "file") == 0) && GNOME_VFS_FILE_INFO_LOCAL (info))		{			gchar* tmp_str;		        gchar* tmp_str2;															tmp_str = gnome_vfs_uri_to_string (uri, GNOME_VFS_URI_HIDE_TOPLEVEL_METHOD);							tmp_str2 = gnome_vfs_unescape_string_for_display (tmp_str);				if (tmp_str2 != NULL)			{				gedit_document_set_readonly (doc, access (tmp_str2, W_OK) ? TRUE : FALSE);			}						g_free (tmp_str2);			g_free (tmp_str);		}				gnome_vfs_uri_unref (uri);	}		g_string_free (tmp_buf, TRUE);	gnome_vfs_file_info_clear (info);	doc->changed = FALSE;	gedit_document_set_title (doc);	gedit_document_text_changed_signal_connect (doc);		gedit_flash_va ("%s %s", _(MSGBAR_FILE_OPENED), fname);	gedit_recent_add (fname);	gedit_recent_update_all_windows (mdi); 	return 0;}static gintgedit_file_selector_key_event (GtkFileSelection *fsel, GdkEventKey *event){	if (event->keyval == GDK_Escape) {		gtk_button_clicked (GTK_BUTTON (fsel->cancel_button));		return 1;	} else		return 0;}/** * gedit_file_save_as: * @doc:  *  * creates the save as dialog and connects the signals to * the button **/static voidgedit_file_save_as (GeditDocument *doc){	static gint ok_signal = 0;		gedit_debug (DEBUG_FILE, "");	if (doc == NULL)		doc = gedit_document_current();	if (doc == NULL)		return;				if (save_file_selector && GTK_WIDGET_VISIBLE (save_file_selector))		return;	if (save_file_selector == NULL)	{		save_file_selector = gtk_file_selection_new (NULL);				gtk_signal_connect(GTK_OBJECT(save_file_selector),				   "delete_event",				   GTK_SIGNAL_FUNC(delete_event_cb),				   save_file_selector);		gtk_signal_connect (GTK_OBJECT(GTK_FILE_SELECTION(save_file_selector)->cancel_button),				    "clicked",				    GTK_SIGNAL_FUNC(cancel_cb),				    save_file_selector);		gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION(save_file_selector)),				    "key_press_event",				    GTK_SIGNAL_FUNC (gedit_file_selector_key_event),				    NULL);		/* If this save as was the result of a close all, and the user cancels the		   save, clear the flag */		gtk_signal_connect(GTK_OBJECT(save_file_selector),				   "delete_event",				   GTK_SIGNAL_FUNC(gedit_close_all_flag_clear),				   NULL);		gtk_signal_connect (GTK_OBJECT(GTK_FILE_SELECTION(save_file_selector)->cancel_button),				    "clicked",				    GTK_SIGNAL_FUNC(gedit_close_all_flag_clear),				    NULL);		/* If this save as was the result of a save all, and the user cancels the		   save, clear the flag */		gtk_signal_connect(GTK_OBJECT(save_file_selector),				   "delete_event",				   GTK_SIGNAL_FUNC(save_all_continue),				   NULL);		gtk_signal_connect (GTK_OBJECT(GTK_FILE_SELECTION(save_file_selector)->cancel_button),				    "clicked",				    GTK_SIGNAL_FUNC(save_all_continue),				    NULL);		/*		g_print ("1. Doc->filename %s untitled #%i\n", doc->filename, doc->untitled_number);		*/		/* OK clicked */		ok_signal = gtk_signal_connect (GTK_OBJECT(GTK_FILE_SELECTION(save_file_selector)->ok_button),				    "clicked",				    GTK_SIGNAL_FUNC (gedit_file_save_as_ok_sel),				    doc);	}	gtk_signal_disconnect (GTK_OBJECT(GTK_FILE_SELECTION(save_file_selector)->ok_button), ok_signal);	/* OK clicked */	ok_signal = gtk_signal_connect (GTK_OBJECT(GTK_FILE_SELECTION(save_file_selector)->ok_button),			    "clicked",			    GTK_SIGNAL_FUNC (gedit_file_save_as_ok_sel),			    doc);	if (doc->filename == NULL)	{

⌨️ 快捷键说明

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