Index: gedit/gedit-tab.c
===================================================================
--- gedit/gedit-tab.c	(revision 5414)
+++ gedit/gedit-tab.c	(working copy)
@@ -65,6 +65,11 @@
 
 	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,7 +455,108 @@
 				   (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)
+{
+	GtkWidget *message_area;
+	GeditDocument *doc;
+	gchar *uri;
+	gboolean document_modified;
+	
+	doc = gedit_tab_get_document (tab);
+	g_return_if_fail (GEDIT_IS_DOCUMENT (doc));
+
+	/* uri cannot be NULL! we're here because
+	 * the file we're editing changed on disk */
+	uri = gedit_document_get_uri (doc);
+	document_modified = gtk_text_buffer_get_modified (GTK_TEXT_BUFFER(doc));
+	message_area = gedit_externally_modified_message_area_new (uri, document_modified);
+	g_free (uri);
+
+	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_NORMAL)
+	{
+		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_NOTIFY_FILE_CHANGED_ON_DISK);
+
+	display_message_area_file_changed (tab);
+
+	return FALSE;
+}
+
+
+static void
 remove_tab (GeditTab *tab)
 {
 	GeditNotebook *notebook;
@@ -1062,6 +1168,12 @@
 		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:
@@ -1381,6 +1493,12 @@
 			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);
 	}
@@ -1401,6 +1519,8 @@
 	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);
@@ -1459,8 +1579,13 @@
 			  "saved",
 			  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),
 			       tab);
@@ -1865,9 +1990,11 @@
 _gedit_tab_save (GeditTab *tab)
 {
 	GeditDocument *doc;
+	GeditDocumentSaveFlags save_flags;
 
 	g_return_if_fail (GEDIT_IS_TAB (tab));
 	g_return_if_fail ((tab->priv->state == GEDIT_TAB_STATE_NORMAL) ||
+			  (tab->priv->state == GEDIT_TAB_STATE_NOTIFY_FILE_CHANGED_ON_DISK) ||
 			  (tab->priv->state == GEDIT_TAB_STATE_SHOWING_PRINT_PREVIEW));
 	g_return_if_fail (tab->priv->tmp_save_uri == NULL);
 	g_return_if_fail (tab->priv->tmp_encoding == NULL);
@@ -1876,6 +2003,18 @@
 	g_return_if_fail (GEDIT_IS_DOCUMENT (doc));
 	g_return_if_fail (!gedit_document_is_untitled (doc));
 
+	if (tab->priv->state == GEDIT_TAB_STATE_NOTIFY_FILE_CHANGED_ON_DISK)
+	{
+		save_flags = tab->priv->save_flags | GEDIT_DOCUMENT_SAVE_IGNORE_MTIME;
+		/* hide the notify file changed on disk message area
+		   we'll use the message area for saving progress now. */
+		set_message_area (tab, NULL);
+	}
+	else
+	{
+		save_flags = tab->priv->save_flags;
+	}
+
 	gedit_tab_set_state (tab, GEDIT_TAB_STATE_SAVING);
 
 	/* uri used in error messages, will be freed in document_saved */
@@ -1885,7 +2024,7 @@
 	if (tab->priv->auto_save_timeout > 0)
 		remove_auto_save_timeout (tab);
 		
-	gedit_document_save (doc, tab->priv->save_flags);
+	gedit_document_save (doc, save_flags);
 }
 
 static gboolean
Index: gedit/gedit-tab.h
===================================================================
--- gedit/gedit-tab.h	(revision 5414)
+++ gedit/gedit-tab.h	(working copy)
@@ -54,6 +54,7 @@
 	GEDIT_TAB_STATE_SAVING_ERROR,
 	GEDIT_TAB_STATE_GENERIC_ERROR,
 	GEDIT_TAB_STATE_CLOSING,
+	GEDIT_TAB_STATE_NOTIFY_FILE_CHANGED_ON_DISK,
 	GEDIT_TAB_NUM_OF_STATES /* This is not a valid state */
 } GeditTabState;
 
Index: gedit/gedit-io-error-message-area.c
===================================================================
--- gedit/gedit-io-error-message-area.c	(revision 5414)
+++ gedit/gedit-io-error-message-area.c	(working copy)
@@ -1025,6 +1025,102 @@
 }
 
 GtkWidget *
+gedit_externally_modified_message_area_new (
+						const gchar  *uri,
+						gboolean     document_modified)
+{
+	GtkWidget *message_area;
+	GtkWidget *hbox_content;
+	GtkWidget *image;
+	GtkWidget *vbox;
+	gchar *primary_markup;
+	gchar *secondary_markup;
+	GtkWidget *primary_label;
+	GtkWidget *secondary_label;
+	gchar *primary_text;
+	const gchar *secondary_text;
+	gchar *full_formatted_uri;
+	gchar *uri_for_display;
+	gchar *temp_uri_for_display;
+
+	g_return_val_if_fail (uri != NULL, NULL);
+
+	full_formatted_uri = gedit_utils_format_uri_for_display (uri);
+
+	/* Truncate the URI so it doesn't get insanely wide. Note that even
+	 * though the dialog uses wrapped text, if the URI doesn't contain
+	 * white space then the text-wrapping code is too stupid to wrap it.
+	 */
+	temp_uri_for_display = gedit_utils_str_middle_truncate (full_formatted_uri, 
+								MAX_URI_IN_DIALOG_LENGTH);								
+	g_free (full_formatted_uri);
+
+	uri_for_display = g_markup_printf_escaped ("<i>%s</i>", temp_uri_for_display);
+	g_free (temp_uri_for_display);
+
+	message_area = gedit_message_area_new ();
+	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);
+
+	hbox_content = gtk_hbox_new (FALSE, 8);
+	gtk_widget_show (hbox_content);				
+
+	image = gtk_image_new_from_stock ("gtk-dialog-warning", 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);
+
+	// FIXME: review this message, it's not clear since for the user the "modification"
+	// could be interpreted as the changes he made in the document. beside "reading" is
+	// not accurate (since last load/save)
+	primary_text = g_strdup_printf (_("The file %s changed on disk."),
+					uri_for_display);
+	g_free (uri_for_display);
+
+	primary_markup = g_strdup_printf ("<b>%s</b>", primary_text);
+	g_free (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 (document_modified)
+		secondary_text = _("Do you want to drop your changes and reload the file?");
+	else
+		secondary_text = _("Do you want to reload the file?");
+  	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;
+}
+
+GtkWidget *
 gedit_no_backup_saving_error_message_area_new (const gchar  *uri,
 					       const GError *error)
 {
Index: gedit/gedit-io-error-message-area.h
===================================================================
--- gedit/gedit-io-error-message-area.h	(revision 5414)
+++ gedit/gedit-io-error-message-area.h	(working copy)
@@ -57,6 +57,9 @@
 GtkWidget	*gedit_externally_modified_saving_error_message_area_new (const gchar         *uri,
 									  const GError        *error);
 
+GtkWidget	*gedit_externally_modified_message_area_new		 (const gchar         *uri,
+									  gboolean document_modified);
+
 GtkWidget	*gedit_no_backup_saving_error_message_area_new		 (const gchar         *uri,
 									  const GError        *error);
 
Index: gedit/gedit-window.c
===================================================================
--- gedit/gedit-window.c	(revision 5414)
+++ gedit/gedit-window.c	(working copy)
@@ -673,6 +673,7 @@
 					      "FileSave");
 	gtk_action_set_sensitive (action,
 				  (state_normal ||
+				   (state == GEDIT_TAB_STATE_NOTIFY_FILE_CHANGED_ON_DISK) ||
 				   (state == GEDIT_TAB_STATE_SHOWING_PRINT_PREVIEW)) &&
 				  !gedit_document_get_readonly (doc) &&
 				  !(lockdown & GEDIT_LOCKDOWN_SAVE_TO_DISK));
@@ -681,6 +682,7 @@
 					      "FileSaveAs");
 	gtk_action_set_sensitive (action,
 				  (state_normal ||
+				   (state == GEDIT_TAB_STATE_NOTIFY_FILE_CHANGED_ON_DISK) ||
 				  (state == GEDIT_TAB_STATE_SHOWING_PRINT_PREVIEW)) &&
 				  !(lockdown & GEDIT_LOCKDOWN_SAVE_TO_DISK));
 				  	
Index: gedit/gedit-document.c
===================================================================
--- gedit/gedit-document.c	(revision 5414)
+++ gedit/gedit-document.c	(working copy)
@@ -887,6 +887,29 @@
 	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)
 {
Index: gedit/gedit-document.h
===================================================================
--- gedit/gedit-document.h	(revision 5414)
+++ gedit/gedit-document.h	(working copy)
@@ -184,6 +184,12 @@
 						(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);
 
