📄 file.c
字号:
/* -*- 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 + -