? src/.gedit-commands.c.swp
? src/\
? src/blah
Index: src/ChangeLog
===================================================================
RCS file: /cvs/gnome/gedit/src/ChangeLog,v
retrieving revision 1.448
diff -u -5 -t -r1.448 ChangeLog
--- src/ChangeLog	10 Jul 2002 16:10:12 -0000	1.448
+++ src/ChangeLog	15 Jul 2002 00:42:44 -0000
@@ -1,5 +1,16 @@
+2002-07-14  James Willcox  <jwillcox@cs.indiana.edu>
+
+        * gedit-document.[ch]:  Use gnome-vfs monitoring to watch the file
+        for changes (including being deleted).  Added two signals "deleted",
+        and "changed_external".
+
+        * gedit-mdi-child.[ch]:  Added the two new signals
+
+        * gedit-mdi.c:  Prompt for action when the file is either deleted
+        or changed.
+
 2002-07-10  Paolo Maggi  <maggi@athena.polito.it>
 
         * gedit-utils.[ch] (gedit_utils_uri_exists): new functions
 
         * gedit-mdi.c (gedit_mdi_remove_child_handler):  Check to see if
Index: src/gedit-document.c
===================================================================
RCS file: /cvs/gnome/gedit/src/gedit-document.c,v
retrieving revision 1.43
diff -u -5 -t -r1.43 gedit-document.c
--- src/gedit-document.c	10 Jul 2002 14:41:43 -0000	1.43
+++ src/gedit-document.c	15 Jul 2002 00:42:50 -0000
@@ -78,20 +78,24 @@
         guint            auto_save_timeout;
         gboolean         last_save_was_manually; 
         
         gboolean         readonly;
 
+        GnomeVFSMonitorHandle *monitor;
+
         GeditUndoManager *undo_manager;
 };
 
 enum {
         NAME_CHANGED,
         SAVED,
         LOADED,
         READONLY_CHANGED,
         CAN_UNDO,
         CAN_REDO,
+        DELETED,
+        CHANGED_EXTERNAL,
         LAST_SIGNAL
 };
 
 static void gedit_document_base_init            (GeditDocumentClass     *klass);
 static void gedit_document_base_finalize        (GeditDocumentClass     *klass);
@@ -293,10 +297,30 @@
                               gedit_marshal_VOID__BOOLEAN,
                               G_TYPE_NONE,
                               1,
                               G_TYPE_BOOLEAN);
 
+        document_signals[DELETED] =
+                g_signal_new ("deleted",
+                              G_OBJECT_CLASS_TYPE (object_class),
+                              G_SIGNAL_RUN_LAST,
+                              G_STRUCT_OFFSET (GeditDocumentClass, deleted),
+                              NULL, NULL,
+                              gedit_marshal_VOID__VOID,
+                              G_TYPE_NONE,
+                              0);
+
+        document_signals[CHANGED_EXTERNAL] =
+                g_signal_new ("changed_external",
+                              G_OBJECT_CLASS_TYPE (object_class),
+                              G_SIGNAL_RUN_LAST,
+                              G_STRUCT_OFFSET (GeditDocumentClass, changed_external),
+                              NULL, NULL,
+                              gedit_marshal_VOID__VOID,
+                              G_TYPE_NONE,
+                              0);
+
 }
 
 static void
 gedit_document_init (GeditDocument *document)
 {
@@ -371,10 +395,14 @@
                 g_free (document->priv->last_searched_text);
 
         if (document->priv->last_replace_text)
                 g_free (document->priv->last_replace_text);
 
+        if (document->priv->monitor) {
+                gedit_debug (DEBUG_DOCUMENT, "cancelling monitor");
+                gnome_vfs_monitor_cancel (document->priv->monitor);
+        }
 
         g_object_unref (G_OBJECT (document->priv->undo_manager));
         
         g_free (document->priv);
         
@@ -933,10 +961,62 @@
 
         return (doc->priv->uri == NULL) && 
                 (!gtk_text_buffer_get_modified (GTK_TEXT_BUFFER (doc)));
 }
 
+
+static gboolean
+gedit_document_monitor_delete_verify (GeditDocument *doc)
+{
+        GnomeVFSURI *uri = gnome_vfs_uri_new (doc->priv->uri);
+
+        if (gnome_vfs_uri_exists (uri)) {
+                /* Liar!!  It's still there! */
+                                
+                /* what probably happened is, another editor
+                 * backed up the existing file by moving it,
+                 * which is what triggered this.  We will
+                 * simply emit a "changed" signal, since this
+                 * is essentially what happened
+                 */
+
+                g_signal_emit (G_OBJECT (doc),
+                       document_signals[CHANGED_EXTERNAL], 0);
+        } else
+                g_signal_emit (G_OBJECT (doc),
+                       document_signals[DELETED], 0);
+
+        
+        
+        return FALSE;
+}
+
+static void
+gedit_document_monitor_handler (GnomeVFSMonitorHandle *handle,
+                           const gchar *monitor_uri,
+                           const gchar *info_uri,
+                           GnomeVFSMonitorEventType event_type,
+                           gpointer user_data)
+{
+        GeditDocument *doc = GEDIT_DOCUMENT (user_data);
+
+
+        switch (event_type) {
+                case GNOME_VFS_MONITOR_EVENT_DELETED:
+                        g_timeout_add (500,
+                                       (GSourceFunc)gedit_document_monitor_delete_verify,
+                                       doc);
+                break;
+                case GNOME_VFS_MONITOR_EVENT_CHANGED:
+                        g_signal_emit (G_OBJECT (doc),
+                                       document_signals[CHANGED_EXTERNAL], 0);
+                break;
+                default:
+                break;
+        }
+}
+
 static void
 gedit_document_set_uri (GeditDocument* doc, const gchar* uri)
 {
         gedit_debug (DEBUG_DOCUMENT, "");
 
@@ -954,20 +1034,30 @@
         if (doc->priv->untitled_number > 0)
         {
                 gedit_document_release_untitled_number (doc->priv->untitled_number);
                 doc->priv->untitled_number = 0;
         }
+
+        if (doc->priv->monitor != NULL) {
+                gnome_vfs_monitor_cancel (doc->priv->monitor);
+                doc->priv->monitor = NULL;
+        }
+
+        gnome_vfs_monitor_add (&doc->priv->monitor,
+                               uri,
+                               GNOME_VFS_MONITOR_FILE,
+                               gedit_document_monitor_handler,
+                               doc);
         
         g_signal_emit (G_OBJECT (doc), document_signals[NAME_CHANGED], 0);
 }
         
 gboolean 
 gedit_document_save (GeditDocument* doc, GError **error)
 {       
         gboolean auto_save;
         gboolean create_backup_copy;
-
         gboolean ret;
 
         gedit_debug (DEBUG_DOCUMENT, "");
 
         g_return_val_if_fail (doc != NULL, FALSE);
@@ -985,18 +1075,30 @@
                         g_source_remove (doc->priv->auto_save_timeout);
                         doc->priv->auto_save_timeout = 0;
                 }
         }
         
+        if (doc->priv->monitor) {
+                gnome_vfs_monitor_cancel (doc->priv->monitor);
+                doc->priv->monitor = NULL;
+        }
+        
         ret = gedit_document_save_as_real (doc, 
                                            doc->priv->uri, 
                                            create_backup_copy, 
                                            error);
 
-        if (ret)
+        gnome_vfs_monitor_add (&doc->priv->monitor,
+                               doc->priv->uri,
+                               GNOME_VFS_MONITOR_FILE,
+                               gedit_document_monitor_handler,
+                               doc);
+        
+        if (ret) {
                 doc->priv->last_save_was_manually = TRUE;
-
+        }
+                
         if (auto_save && (doc->priv->auto_save_timeout <= 0)) 
         {
                 gint auto_save_interval = 
                         gedit_prefs_manager_get_auto_save_interval ();
 
Index: src/gedit-document.h
===================================================================
RCS file: /cvs/gnome/gedit/src/gedit-document.h,v
retrieving revision 1.16
diff -u -5 -t -r1.16 gedit-document.h
--- src/gedit-document.h	14 May 2002 09:46:38 -0000	1.16
+++ src/gedit-document.h	15 Jul 2002 00:42:50 -0000
@@ -77,10 +77,16 @@
         void (* can_undo)               (GeditDocument *document,
                                          gboolean can_undo);
         void (* can_redo)               (GeditDocument *document,
                                          gboolean can_redo);
 
+        /* Document was deleted from the file system */
+        void (* deleted)                (GeditDocument *document);
+
+        /* Document was changed by another process */
+        void (* changed_external)       (GeditDocument *document);
+
 };
 #define GEDIT_ERROR_INVALID_UTF8_DATA   1024
 #define GEDIT_ERROR_UNTITLED            1025    
 #define GEDIT_DOCUMENT_IO_ERROR gedit_document_io_error_quark ()
 GQuark          gedit_document_io_error_quark (void);
Index: src/gedit-mdi-child.c
===================================================================
RCS file: /cvs/gnome/gedit/src/gedit-mdi-child.c,v
retrieving revision 1.6
diff -u -5 -t -r1.6 gedit-mdi-child.c
--- src/gedit-mdi-child.c	14 May 2002 09:46:38 -0000	1.6
+++ src/gedit-mdi-child.c	15 Jul 2002 00:42:51 -0000
@@ -39,10 +39,12 @@
 };
 
 enum {
         STATE_CHANGED,
         UNDO_REDO_STATE_CHANGED,
+        DELETED,
+        CHANGED_EXTERNAL,
         LAST_SIGNAL
 };
 
 static void gedit_mdi_child_class_init  (GeditMDIChildClass     *klass);
 static void gedit_mdi_child_init        (GeditMDIChild          *mdi);
@@ -124,10 +126,30 @@
                               G_STRUCT_OFFSET (GeditMDIChildClass, undo_redo_state_changed),
                               NULL, NULL,
                               gedit_marshal_VOID__VOID,
                               G_TYPE_NONE, 
                               0);
+
+        mdi_child_signals [DELETED] =
+                g_signal_new ("deleted",
+                              G_OBJECT_CLASS_TYPE (gobject_class),
+                              G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+                              G_STRUCT_OFFSET (GeditMDIChildClass, deleted),
+                              NULL, NULL,
+                              gedit_marshal_VOID__VOID,
+                              G_TYPE_NONE, 
+                              0);
+
+        mdi_child_signals [CHANGED_EXTERNAL] =
+                g_signal_new ("changed_external",
+                              G_OBJECT_CLASS_TYPE (gobject_class),
+                              G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+                              G_STRUCT_OFFSET (GeditMDIChildClass, changed_external),
+                              NULL, NULL,
+                              gedit_marshal_VOID__VOID,
+                              G_TYPE_NONE, 
+                              0);
                     
         BONOBO_MDI_CHILD_CLASS (klass)->create_view = 
                 (BonoboMDIChildViewCreator)(gedit_mdi_child_create_view);
 
         BONOBO_MDI_CHILD_CLASS (klass)->get_config_string = 
@@ -236,10 +258,29 @@
         g_return_if_fail (child->document == document);
 
         g_signal_emit (G_OBJECT (child), mdi_child_signals [UNDO_REDO_STATE_CHANGED], 0);
 }
 
+static void
+gedit_mdi_child_deleted_handler (GeditDocument *document, GeditMDIChild *child)
+{
+        gedit_debug (DEBUG_MDI, "");
+
+        g_return_if_fail (child->document == document);
+
+        g_signal_emit (G_OBJECT (child), mdi_child_signals [DELETED], 0);
+}
+
+static void
+gedit_mdi_child_changed_external_handler (GeditDocument *document, GeditMDIChild *child)
+{
+        gedit_debug (DEBUG_MDI, "");
+
+        g_return_if_fail (child->document == document);
+
+        g_signal_emit (G_OBJECT (child), mdi_child_signals [CHANGED_EXTERNAL], 0);
+}
 
 static void
 gedit_mdi_child_connect_signals (GeditMDIChild *child)
 {
         g_signal_connect (G_OBJECT (child->document), "name_changed",
@@ -255,10 +296,18 @@
                           G_CALLBACK (gedit_mdi_child_document_can_undo_redo_handler), 
                           child);
         g_signal_connect (G_OBJECT (child->document), "can_redo",
                           G_CALLBACK (gedit_mdi_child_document_can_undo_redo_handler), 
                           child);
+
+        g_signal_connect (GEDIT_MDI_CHILD (child)->document, "deleted",
+                          G_CALLBACK (gedit_mdi_child_deleted_handler),
+                          child);
+
+        g_signal_connect (GEDIT_MDI_CHILD (child)->document, "changed_external",
+                          G_CALLBACK (gedit_mdi_child_changed_external_handler),
+                          child);
 }
 
 /**
  * gedit_mdi_child_new:
  * 
@@ -331,10 +380,11 @@
 
         g_return_val_if_fail (child != NULL, NULL);
         g_return_val_if_fail (GEDIT_IS_MDI_CHILD (child), NULL);
 
         new_view = gedit_view_new (GEDIT_MDI_CHILD (child)->document);
+
 
         gtk_widget_show_all (GTK_WIDGET (new_view));
 
         return GTK_WIDGET (new_view);
 }
Index: src/gedit-mdi-child.h
===================================================================
RCS file: /cvs/gnome/gedit/src/gedit-mdi-child.h,v
retrieving revision 1.1
diff -u -5 -t -r1.1 gedit-mdi-child.h
--- src/gedit-mdi-child.h	16 Nov 2001 19:33:05 -0000	1.1
+++ src/gedit-mdi-child.h	15 Jul 2002 00:42:51 -0000
@@ -63,10 +63,13 @@
 
         /* MDI child state changed */
         void (*state_changed)           (GeditMDIChild *child);
 
         void (*undo_redo_state_changed) (GeditMDIChild *child);
+
+        void (*deleted) (GeditMDIChild *child);
+        void (*changed_external) (GeditMDIChild *child);
 };
 
 
 GtkType         gedit_mdi_child_get_type        (void) G_GNUC_CONST;
 
Index: src/gedit-mdi.c
===================================================================
RCS file: /cvs/gnome/gedit/src/gedit-mdi.c,v
retrieving revision 1.48
diff -u -5 -t -r1.48 gedit-mdi.c
--- src/gedit-mdi.c	10 Jul 2002 16:10:12 -0000	1.48
+++ src/gedit-mdi.c	15 Jul 2002 00:42:54 -0000
@@ -749,20 +749,131 @@
                 return;
         
         gedit_mdi_set_active_window_undo_redo_verbs_sensitivity (BONOBO_MDI (gedit_mdi));
 }
 
+
+
+#define GEDIT_RESPONSE_SAVE 1
+#define GEDIT_RESPONSE_IGNORE 2
+
+static void
+gedit_mdi_child_deleted_handler (GeditMDIChild *child)
+{
+        GtkWidget *dialog;
+        gint response;
+        gchar *uri;
+        gchar *message;
+
+        uri = gedit_document_get_uri (child->document);
+        message = g_strdup_printf (_("The file '%s' has been deleted from the filesystem."), uri);
+
+        dialog = gtk_message_dialog_new (
+                        GTK_WINDOW (bonobo_mdi_get_active_window (BONOBO_MDI (gedit_mdi))),
+                        GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
+                        GTK_MESSAGE_QUESTION,
+                        GTK_BUTTONS_NONE,
+                        message);
+        g_free (message);
+        
+        gedit_dialog_add_button (GTK_DIALOG (dialog),
+                                _("_Ignore"), GTK_STOCK_OK,
+                                GEDIT_RESPONSE_IGNORE);
+        gedit_dialog_add_button (GTK_DIALOG (dialog),
+                                _("_Save now"), GTK_STOCK_SAVE,
+                                GEDIT_RESPONSE_SAVE);
+
+        gtk_dialog_set_default_response (GTK_DIALOG (dialog), GEDIT_RESPONSE_SAVE);
+        gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
+        response = gtk_dialog_run (GTK_DIALOG (dialog));
+        gtk_widget_destroy (dialog);
+
+        switch (response) {
+                case GEDIT_RESPONSE_SAVE:
+                        gedit_file_save (GEDIT_MDI_CHILD (child));
+                break;
+                default:
+                break;
+        }
+
+        g_free (uri);
+}
+
+
+#define GEDIT_RESPONSE_RELOAD 3
+
+static void
+gedit_mdi_child_changed_external_handler (GeditMDIChild *child)
+{
+        GtkWidget *dialog;
+        gint response;
+        gchar *uri;
+        gchar *message;
+
+        uri = gedit_document_get_uri (child->document);
+
+        message = g_strdup_printf (_("The file '%s' has been changed by another process."), uri);
+        dialog = gtk_message_dialog_new (
+                        GTK_WINDOW (bonobo_mdi_get_active_window (BONOBO_MDI (gedit_mdi))),
+                        GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
+                        GTK_MESSAGE_QUESTION,
+                        GTK_BUTTONS_NONE,
+                        message);
+        g_free (message);
+        
+        gedit_dialog_add_button (GTK_DIALOG (dialog),
+                                _("_Ignore"), GTK_STOCK_OK,
+                                GEDIT_RESPONSE_IGNORE);
+        
+        gedit_dialog_add_button (GTK_DIALOG (dialog),
+                                _("_Save now"), GTK_STOCK_SAVE,
+                                GEDIT_RESPONSE_SAVE);
+
+        gedit_dialog_add_button (GTK_DIALOG (dialog),
+                                _("_Reload"), GTK_STOCK_OPEN,
+                                GEDIT_RESPONSE_RELOAD);
+
+        gtk_dialog_set_default_response (GTK_DIALOG (dialog), GEDIT_RESPONSE_IGNORE);
+        gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
+        response = gtk_dialog_run (GTK_DIALOG (dialog));
+        gtk_widget_destroy (dialog);
+
+        switch (response) {
+                case GEDIT_RESPONSE_SAVE:
+                        gedit_file_save (GEDIT_MDI_CHILD (child));
+                break;
+                case GEDIT_RESPONSE_RELOAD:
+                        uri = gedit_document_get_uri (child->document);
+                        gedit_document_load (child->document, uri, NULL);
+                break;
+                default:
+                break;
+        }
+
+        g_free (uri);
+}
+
+#undef GEDIT_RESPONSE_RELOAD
+#undef GEDIT_RESPONSE_SAVE
+#undef GEDIT_RESPONSE_IGNORE
+
 static gint 
 gedit_mdi_add_child_handler (BonoboMDI *mdi, BonoboMDIChild *child)
 {
         gedit_debug (DEBUG_MDI, "");
 
         g_signal_connect (G_OBJECT (child), "state_changed",
                           G_CALLBACK (gedit_mdi_child_state_changed_handler), 
                           NULL);
         g_signal_connect (G_OBJECT (child), "undo_redo_state_changed",
                           G_CALLBACK (gedit_mdi_child_undo_redo_state_changed_handler), 
+                          NULL);
+        g_signal_connect (G_OBJECT (child), "deleted",
+                          G_CALLBACK (gedit_mdi_child_deleted_handler),
+                          NULL);
+        g_signal_connect (G_OBJECT (child), "changed_external",
+                          G_CALLBACK (gedit_mdi_child_changed_external_handler),
                           NULL);
 
         return TRUE;
 }
 
Index: src/gedit-view.c
===================================================================
RCS file: /cvs/gnome/gedit/src/gedit-view.c,v
retrieving revision 1.28
diff -u -5 -t -r1.28 gedit-view.c
--- src/gedit-view.c	4 Jul 2002 17:26:21 -0000	1.28
+++ src/gedit-view.c	15 Jul 2002 00:42:56 -0000
@@ -35,10 +35,11 @@
 #include <libgnome/gnome-i18n.h>
 #include "gedit-view.h"
 #include "gedit-debug.h"
 #include "gedit-menus.h"
 #include "gedit-prefs-manager.h"
+#include "gedit-utils.h"
 
 #define MIN_NUMBER_WINDOW_WIDTH 20
 
 struct _GeditViewPrivate
 {
@@ -129,11 +130,10 @@
 
         g_return_if_fail (GEDIT_IS_VIEW (view));
 
         gtk_text_view_set_editable (view->priv->text_view, !readonly);  
 }
-
 
 static void
 gedit_view_class_init (GeditViewClass *klass)
 {
         GObjectClass *object_class = G_OBJECT_CLASS (klass);
