? plugins/externaltools/data/Makefile.in
Index: gedit/gedit-document.c
===================================================================
RCS file: /cvs/gnome/gedit/gedit/gedit-document.c,v
retrieving revision 1.136
diff -u -p -r1.136 gedit-document.c
--- gedit/gedit-document.c	8 Nov 2006 15:15:54 -0000	1.136
+++ gedit/gedit-document.c	5 Dec 2006 20:03:14 -0000
@@ -887,6 +887,29 @@ gedit_document_get_readonly (GeditDocume
 	return doc->priv->readonly;
 }
 
+gboolean
+_gedit_document_check_external_modification (GeditDocument *doc)
+{
+	GnomeVFSFileInfo *info;
+	GnomeVFSResult result;
+	gint file_mtime;
+
+	g_return_val_if_fail (GEDIT_IS_DOCUMENT (doc), FALSE);
+
+	info = gnome_vfs_file_info_new ();
+	result = gnome_vfs_get_file_info_uri (doc->priv->vfs_uri, info,
+						GNOME_VFS_FILE_INFO_DEFAULT|
+						GNOME_VFS_FILE_INFO_FOLLOW_LINKS);
+	if (result != GNOME_VFS_OK)
+	{
+		gnome_vfs_file_info_unref (info);
+		return FALSE;
+	}
+	file_mtime = info->mtime;
+	gnome_vfs_file_info_unref (info);
+	return (file_mtime > doc->priv->mtime);
+}
+
 static void
 reset_temp_loading_data (GeditDocument       *doc)
 {
@@ -1201,7 +1224,6 @@ gedit_document_is_untitled (GeditDocumen
 
 	return (doc->priv->uri == NULL);
 }
-
 
 gboolean
 gedit_document_get_deleted (GeditDocument *doc)
Index: gedit/gedit-document.h
===================================================================
RCS file: /cvs/gnome/gedit/gedit/gedit-document.h,v
retrieving revision 1.47
diff -u -p -r1.47 gedit-document.h
--- gedit/gedit-document.h	7 Aug 2006 18:04:07 -0000	1.47
+++ gedit/gedit-document.h	5 Dec 2006 20:03:14 -0000
@@ -184,6 +184,12 @@ gboolean	 gedit_document_get_externally_
 						(GeditDocument       *doc);
 */
 
+/* Has the file changed on disk compared to our version?
+ * NOTE: will also check for remote files!
+ */
+gboolean	_gedit_document_check_external_modification
+						(GeditDocument       *doc);
+
 gboolean	 gedit_document_goto_line 	(GeditDocument       *doc, 
 						 gint                 line);
 
Index: gedit/gedit-io-error-message-area.c
===================================================================
RCS file: /cvs/gnome/gedit/gedit/gedit-io-error-message-area.c,v
retrieving revision 1.8
diff -u -p -r1.8 gedit-io-error-message-area.c
--- gedit/gedit-io-error-message-area.c	7 Nov 2006 21:03:44 -0000	1.8
+++ gedit/gedit-io-error-message-area.c	5 Dec 2006 20:03:17 -0000
@@ -57,58 +57,16 @@ create_unrecoverable_error_message_area 
 					 const gchar *secondary_text)
 {
 	GtkWidget *message_area;
-	GtkWidget *hbox_content;
-	GtkWidget *image;
-	GtkWidget *vbox;
-	gchar *primary_markup;
-	gchar *secondary_markup;
-	GtkWidget *primary_label;
-	GtkWidget *secondary_label;
 	
 	message_area = gedit_message_area_new_with_buttons (
 					GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
 					NULL);
+	
+	gedit_message_area_add_message_and_icon (GEDIT_MESSAGE_AREA (message_area),
+						 "gtk-dialog-error",
+						 primary_text,
+						 secondary_text);
 
-	hbox_content = gtk_hbox_new (FALSE, 8);
-	gtk_widget_show (hbox_content);
-
-	image = gtk_image_new_from_stock ("gtk-dialog-error", GTK_ICON_SIZE_DIALOG);
-	gtk_widget_show (image);
-	gtk_box_pack_start (GTK_BOX (hbox_content), image, FALSE, FALSE, 0);
-	gtk_misc_set_alignment (GTK_MISC (image), 0.5, 0);
-  
-	vbox = gtk_vbox_new (FALSE, 6);
-	gtk_widget_show (vbox);
-	gtk_box_pack_start (GTK_BOX (hbox_content), vbox, TRUE, TRUE, 0);
-
-	primary_markup = g_strdup_printf ("<b>%s</b>", primary_text);
-	primary_label = gtk_label_new (primary_markup);
-	g_free (primary_markup);
-	gtk_widget_show (primary_label);
-	gtk_box_pack_start (GTK_BOX (vbox), primary_label, TRUE, TRUE, 0);
-	gtk_label_set_use_markup (GTK_LABEL (primary_label), TRUE);
-	gtk_label_set_line_wrap (GTK_LABEL (primary_label), TRUE);
-	gtk_misc_set_alignment (GTK_MISC (primary_label), 0, 0.5);
-	GTK_WIDGET_SET_FLAGS (primary_label, GTK_CAN_FOCUS);
-	gtk_label_set_selectable (GTK_LABEL (primary_label), TRUE);
-  
-  	if (secondary_text != NULL)
-  	{
-  		secondary_markup = g_strdup_printf ("<small>%s</small>",
-  						    secondary_text);
-		secondary_label = gtk_label_new (secondary_markup);
-		g_free (secondary_markup);
-		gtk_widget_show (secondary_label);
-		gtk_box_pack_start (GTK_BOX (vbox), secondary_label, TRUE, TRUE, 0);
-		GTK_WIDGET_SET_FLAGS (secondary_label, GTK_CAN_FOCUS);
-		gtk_label_set_use_markup (GTK_LABEL (secondary_label), TRUE);
-		gtk_label_set_line_wrap (GTK_LABEL (secondary_label), TRUE);
-		gtk_label_set_selectable (GTK_LABEL (secondary_label), TRUE);
-		gtk_misc_set_alignment (GTK_MISC (secondary_label), 0, 0.5);
-	}
-
-	gedit_message_area_set_contents (GEDIT_MESSAGE_AREA (message_area),
-					 hbox_content);
 	return message_area;
 }
 
Index: gedit/gedit-message-area.c
===================================================================
RCS file: /cvs/gnome/gedit/gedit/gedit-message-area.c,v
retrieving revision 1.4
diff -u -p -r1.4 gedit-message-area.c
--- gedit/gedit-message-area.c	9 Aug 2006 15:17:37 -0000	1.4
+++ gedit/gedit-message-area.c	5 Dec 2006 20:03:18 -0000
@@ -413,6 +413,62 @@ gedit_message_area_add_buttons (GeditMes
   
 	va_end (args);
 }
+
+void
+gedit_message_area_add_message_and_icon (GeditMessageArea *message_area,
+					 const gchar      *icon_stock_id,
+					 const gchar      *primary_text,
+					 const gchar      *secondary_text)
+{
+	GtkWidget *hbox_content;
+	GtkWidget *image;
+	GtkWidget *vbox;
+	gchar *primary_markup;
+	gchar *secondary_markup;
+	GtkWidget *primary_label;
+	GtkWidget *secondary_label;
+
+	hbox_content = gtk_hbox_new (FALSE, 8);
+	gtk_widget_show (hbox_content);
+	
+	image = gtk_image_new_from_stock (icon_stock_id, GTK_ICON_SIZE_DIALOG);
+	gtk_widget_show (image);
+	gtk_box_pack_start (GTK_BOX (hbox_content), image, FALSE, FALSE, 0);
+	gtk_misc_set_alignment (GTK_MISC (image), 0.5, 0);
+  
+	vbox = gtk_vbox_new (FALSE, 6);
+	gtk_widget_show (vbox);
+	gtk_box_pack_start (GTK_BOX (hbox_content), vbox, TRUE, TRUE, 0);
+	
+	primary_markup = g_strdup_printf ("<b>%s</b>", primary_text);
+	primary_label = gtk_label_new (primary_markup);
+	g_free (primary_markup);
+	gtk_widget_show (primary_label);
+	gtk_box_pack_start (GTK_BOX (vbox), primary_label, TRUE, TRUE, 0);
+	gtk_label_set_use_markup (GTK_LABEL (primary_label), TRUE);
+	gtk_label_set_line_wrap (GTK_LABEL (primary_label), TRUE);
+	gtk_misc_set_alignment (GTK_MISC (primary_label), 0, 0.5);
+	GTK_WIDGET_SET_FLAGS (primary_label, GTK_CAN_FOCUS);
+	gtk_label_set_selectable (GTK_LABEL (primary_label), TRUE);
+  
+  	if (secondary_text != NULL)
+  	{
+  		secondary_markup = g_strdup_printf ("<small>%s</small>",
+  						    secondary_text);
+		secondary_label = gtk_label_new (secondary_markup);
+		g_free (secondary_markup);
+		gtk_widget_show (secondary_label);
+		gtk_box_pack_start (GTK_BOX (vbox), secondary_label, TRUE, TRUE, 0);
+		GTK_WIDGET_SET_FLAGS (secondary_label, GTK_CAN_FOCUS);
+		gtk_label_set_use_markup (GTK_LABEL (secondary_label), TRUE);
+		gtk_label_set_line_wrap (GTK_LABEL (secondary_label), TRUE);
+		gtk_label_set_selectable (GTK_LABEL (secondary_label), TRUE);
+		gtk_misc_set_alignment (GTK_MISC (secondary_label), 0, 0.5);
+	}
+
+	gedit_message_area_set_contents (GEDIT_MESSAGE_AREA (message_area),
+					 hbox_content);
+}
 				 
 GtkWidget *
 gedit_message_area_new (void)
Index: gedit/gedit-message-area.h
===================================================================
RCS file: /cvs/gnome/gedit/gedit/gedit-message-area.h,v
retrieving revision 1.2
diff -u -p -r1.2 gedit-message-area.h
--- gedit/gedit-message-area.h	12 Dec 2005 17:27:55 -0000	1.2
+++ gedit/gedit-message-area.h	5 Dec 2006 20:03:18 -0000
@@ -111,7 +111,12 @@ GtkWidget	*gedit_message_area_add_stock_
 
 void       	 gedit_message_area_add_buttons 	(GeditMessageArea *message_area,
                                          		 const gchar      *first_button_text,
-                                         		 ...);
+							 ...);
+void		 gedit_message_area_add_message_and_icon
+							(GeditMessageArea *message_area,
+							 const gchar      *icon_stock_id,
+							 const gchar      *primary_text,
+							 const gchar      *secondary_text);
 
 void		 gedit_message_area_set_response_sensitive 
 							(GeditMessageArea *message_area,
Index: gedit/gedit-tab.c
===================================================================
RCS file: /cvs/gnome/gedit/gedit/gedit-tab.c,v
retrieving revision 1.17
diff -u -p -r1.17 gedit-tab.c
--- gedit/gedit-tab.c	25 Aug 2006 13:59:41 -0000	1.17
+++ gedit/gedit-tab.c	5 Dec 2006 20:03:23 -0000
@@ -65,6 +65,11 @@ struct _GeditTabPrivate
 
 	GeditPrintJob          *print_job;
 
+	/* did we already notify the user that the file on disk
+	 * is different than what is in gedit? if we notified
+	 * the user, we won't notify again since user already knows. */
+	gboolean	       user_notified_that_file_changed_on_disk;
+
 	/* tmp data for saving */
 	gchar		       *tmp_save_uri;
 
@@ -450,6 +455,115 @@ set_message_area (GeditTab  *tab,
 				   (gpointer *)&tab->priv->message_area);
 }
 
+static void 
+file_modified_on_disk_message_area_response (GeditMessageArea *message_area,
+						gint              response_id,
+						GeditTab         *tab)
+{
+	GeditView *view;
+
+	set_message_area (tab, NULL);
+	view = gedit_tab_get_view (tab);
+	gedit_tab_set_state (tab, GEDIT_TAB_STATE_NORMAL);
+
+	if (response_id == GTK_RESPONSE_OK)
+	{
+		_gedit_tab_revert (tab);
+	}
+	else
+	{
+		tab->priv->user_notified_that_file_changed_on_disk = TRUE;
+	}
+
+	gtk_widget_grab_focus (GTK_WIDGET (view));
+}
+
+static void
+display_message_area_file_changed (GeditTab    *tab)
+{
+	const gchar *primary_text = _("The file changed on disk");
+	const gchar *secondary_text = _("Which version do you want to edit?");
+
+	GtkWidget *message_area;
+	
+	message_area = gedit_message_area_new ();
+
+	gedit_message_area_add_message_and_icon (GEDIT_MESSAGE_AREA (message_area),
+							   "gtk-dialog-warning",
+							   primary_text,
+							   secondary_text);
+
+	gedit_message_area_add_stock_button_with_text (GEDIT_MESSAGE_AREA (message_area),
+						       _("_Refresh from disk"),
+						       GTK_STOCK_REFRESH,
+						       GTK_RESPONSE_OK);
+	gedit_message_area_add_button (GEDIT_MESSAGE_AREA (message_area),
+				       _("_Keep changes"),
+				       GTK_RESPONSE_CANCEL);
+				      
+
+	tab->priv->message_area = NULL;
+	set_message_area (tab, message_area);
+	gtk_widget_show (message_area);
+
+	g_signal_connect (message_area,
+			  "response",
+			  G_CALLBACK (file_modified_on_disk_message_area_response),
+			  tab);
+}
+
+static gboolean
+view_focused_in (GtkWidget     *widget,
+              GdkEventFocus *event,
+              GeditTab    *tab)
+{
+	GeditDocument *doc;
+	gchar *uri;
+	gboolean local_document;
+	
+	g_return_val_if_fail (GEDIT_IS_TAB (tab), FALSE);
+        
+	if ((tab->priv->state == GEDIT_TAB_STATE_FILE_CHANGED) ||
+		(tab->priv->state == GEDIT_TAB_STATE_LOADING) ||
+		(tab->priv->state == GEDIT_TAB_STATE_SAVING) ||
+		(tab->priv->state == GEDIT_TAB_STATE_REVERTING))
+	{
+		return FALSE;
+	}
+	
+	doc = gedit_tab_get_document (tab);
+	g_return_val_if_fail (GEDIT_IS_DOCUMENT (doc), FALSE);
+
+	uri = gedit_document_get_uri (doc);
+	if (uri == NULL)
+	{
+		/* file has no disk saving: nothing to do */
+		return FALSE;
+	}
+	local_document = gedit_utils_uri_has_file_scheme (uri);
+	g_free (uri);
+	if (!local_document)
+	{
+		/* file is not local: bailing out
+		   (checking remote files is too slow) */
+		return FALSE;
+	}
+
+	if ((!_gedit_document_check_external_modification (doc)) ||
+		tab->priv->user_notified_that_file_changed_on_disk)
+	{
+		/* document didn't change, or user already
+		   notified of the change: nothing to do */
+		return FALSE;
+	}
+
+	gedit_tab_set_state (tab, GEDIT_TAB_STATE_FILE_CHANGED);
+
+	display_message_area_file_changed (tab);
+
+	return FALSE;
+}
+
 static void
 remove_tab (GeditTab *tab)
 {
@@ -1039,6 +1153,12 @@ document_loaded (GeditDocument *document
 		gedit_tab_set_state (tab, GEDIT_TAB_STATE_NORMAL);
 		
 		install_auto_save_timeout_if_needed (tab);
+
+		/* the user synchronized the file with disk:
+		 * now the user assumes the file is the same
+		 * than on disk, must notify the user again
+		 * if it's not the case. */
+		tab->priv->user_notified_that_file_changed_on_disk = FALSE;
 	}
 
  end:
@@ -1358,6 +1478,12 @@ document_saved (GeditDocument *document,
 			gedit_tab_set_state (tab, GEDIT_TAB_STATE_SHOWING_PRINT_PREVIEW);
 		else
 			gedit_tab_set_state (tab, GEDIT_TAB_STATE_NORMAL);
+
+		/* the user synchronized the file with disk:
+		 * now the user assumes the file is the same
+		 * than on disk, must notify the user again
+		 * if it's not the case. */
+		tab->priv->user_notified_that_file_changed_on_disk = FALSE;
 			
 		end_saving (tab);
 	}
@@ -1378,6 +1504,8 @@ gedit_tab_init (GeditTab *tab)
 	tab->priv->not_editable = FALSE;
 
 	tab->priv->save_flags = 0;
+
+	tab->priv->user_notified_that_file_changed_on_disk = FALSE;
 	
 	/* Create the scrolled window */
 	sw = gtk_scrolled_window_new (NULL, NULL);
@@ -1437,6 +1565,11 @@ gedit_tab_init (GeditTab *tab)
 			  G_CALLBACK (document_saved),
 			  tab);
 			  
+	g_signal_connect_after(tab->priv->view,
+        		  "focus-in-event",
+		 	  G_CALLBACK (view_focused_in),
+ 			  tab);
+		  
 	g_signal_connect_after(tab->priv->view,
 			       "realize",
 			       G_CALLBACK (view_realized),
Index: gedit/gedit-tab.h
===================================================================
RCS file: /cvs/gnome/gedit/gedit/gedit-tab.h,v
retrieving revision 1.4
diff -u -p -r1.4 gedit-tab.h
--- gedit/gedit-tab.h	19 Feb 2006 18:01:09 -0000	1.4
+++ gedit/gedit-tab.h	5 Dec 2006 20:03:23 -0000
@@ -54,6 +54,7 @@ typedef enum
 	GEDIT_TAB_STATE_SAVING_ERROR,
 	GEDIT_TAB_STATE_GENERIC_ERROR,
 	GEDIT_TAB_STATE_CLOSING,
+	GEDIT_TAB_STATE_FILE_CHANGED,
 	GEDIT_TAB_NUM_OF_STATES /* This is not a valid state */
 } GeditTabState;
 
