? patch-modified.diff
? patch-modified1.diff
? help/ru/.xml2po.mo
? help/ru/gedit.xml
? help/ru/legal.xml
? help/sv/.xml2po.mo
? help/sv/gedit.xml
? help/sv/legal.xml
Index: gedit/gedit-document.c
===================================================================
RCS file: /cvs/gnome/gedit/gedit/gedit-document.c,v
retrieving revision 1.135
diff -u -r1.135 gedit-document.c
--- gedit/gedit-document.c	24 Aug 2006 13:17:13 -0000	1.135
+++ gedit/gedit-document.c	26 Nov 2006 19:40:05 -0000
@@ -888,6 +888,28 @@
 	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);
+	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)
 {
@@ -1202,7 +1224,6 @@
 
 	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 -r1.47 gedit-document.h
--- gedit/gedit-document.h	7 Aug 2006 18:04:07 -0000	1.47
+++ gedit/gedit-document.h	26 Nov 2006 19:40:06 -0000
@@ -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);
 
Index: gedit/gedit-tab.c
===================================================================
RCS file: /cvs/gnome/gedit/gedit/gedit-tab.c,v
retrieving revision 1.17
diff -u -r1.17 gedit-tab.c
--- gedit/gedit-tab.c	25 Aug 2006 13:59:41 -0000	1.17
+++ gedit/gedit-tab.c	26 Nov 2006 19:40:10 -0000
@@ -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,6 +455,153 @@
 				   (gpointer *)&tab->priv->message_area);
 }
 
+static void 
+file_modified_on_disk_message_area_response (GeditMessageArea *message_area,
+						gint              response_id,
+						GeditTab         *tab)
+{
+	GeditView *view;
+	GeditDocument *doc;
+
+	doc = gedit_tab_get_document (tab);
+	g_return_if_fail (GEDIT_IS_DOCUMENT (doc));
+
+	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 gboolean
+view_focused_in (GtkWidget     *widget,
+              GdkEventFocus *event,
+              GeditTab    *tab)
+{
+	GeditDocument *doc;
+	gchar *uri;
+	
+	g_assert (GEDIT_IS_TAB (tab));
+        
+	if ((tab->priv->state == GEDIT_TAB_STATE_FILE_CHANGED) ||
+		(tab->priv->state == GEDIT_TAB_STATE_LOADING) ||
+		(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;
+	}
+	gboolean 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);
+
+	const gchar *primary_text = "The file changed on disk";
+	const gchar *secondary_text = "Which version do you want to edit?";
+
+	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 ();
+
+	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);
+	
+	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);
+
+	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);
+			  
+	return FALSE;
+}
+
 static void
 remove_tab (GeditTab *tab)
 {
@@ -1039,6 +1191,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:
@@ -1358,6 +1516,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);
 	}
@@ -1378,6 +1542,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);
@@ -1437,6 +1603,11 @@
 			  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 -r1.4 gedit-tab.h
--- gedit/gedit-tab.h	19 Feb 2006 18:01:09 -0000	1.4
+++ gedit/gedit-tab.h	26 Nov 2006 19:40:11 -0000
@@ -54,6 +54,7 @@
 	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;
 
