? depcomp
? stamp-h1
? gnome-session/session-properties.desktop.in
Index: gnome-session/session-properties-capplet.c
===================================================================
RCS file: /cvs/gnome/gnome-session/gnome-session/session-properties-capplet.c,v
retrieving revision 1.34
diff -u -r1.34 session-properties-capplet.c
--- gnome-session/session-properties-capplet.c	22 Dec 2004 16:19:24 -0000	1.34
+++ gnome-session/session-properties-capplet.c	15 Jan 2005 07:28:00 -0000
@@ -36,6 +36,7 @@
 
 /* Indicates whether we have to ask for save on close */
 static gboolean state_dirty = FALSE;
+static GTimeVal dirty_start_time;
 /* Apply button (for toggling sensitivity) */
 extern GtkWidget *apply_button;
 
@@ -180,41 +181,135 @@
 	}
 }
 
-static gboolean
-show_message_dialog ()
+static gchar *
+get_save_secondary_label (glong seconds)
+{
+	gchar *secondary_msg;
+
+	if (seconds < 55)	
+	{
+		secondary_msg = g_strdup_printf (
+					ngettext ("If you don't save, changes from the last %ld second will be discarded.",
+						  "If you don't save, changes from the last %ld seconds will be discarded.",
+						  seconds),
+					seconds);
+	}
+	else if (seconds < 75) /* 55 <= seconds < 75 */
+	{
+		secondary_msg = g_strdup (_("If you don't save, changes from the last minute will be discarded."));
+	}
+	else if (seconds < 110) /* 75 <= seconds < 110 */
+	{
+		secondary_msg = g_strdup_printf (
+					ngettext ("If you don't save, changes from the last minute and %ld second will be discarded.",
+						  "If you don't save, changes from the last minute and %ld seconds will be discarded.",
+						  seconds - 60 ),
+					seconds - 60);
+	}
+	else if (seconds < 3600)
+	{
+		secondary_msg = g_strdup_printf (
+					ngettext ("If you don't save, changes from the last %ld minute will be discarded.",
+						  "If you don't save, changes from the last %ld minutes will be discarded.",
+						  seconds / 60),
+					seconds / 60);
+	}
+	else if (seconds < 7200)
+	{
+		gint minutes;
+		seconds -= 3600;
+
+		minutes = seconds / 60;
+		if (minutes < 5)
+		{
+			secondary_msg = g_strdup (_("If you don't save, changes from the last hour will be discarded."));
+		}
+		else
+		{
+			secondary_msg = g_strdup_printf (
+					ngettext ("If you don't save, changes from the last hour and %d minute will be discarded.",
+						  "If you don't save, changes from the last hour and %d minutes will be discarded.",
+						  minutes),
+					minutes);
+		}
+	}
+	else
+	{
+		gint hours;
+
+		hours = seconds / 3600;
+
+		secondary_msg = g_strdup_printf (
+					ngettext ("If you don't save, changes from the last %d hour will be discarded.",
+						  "If you don't save, changes from the last %d hours will be discarded.",
+						  hours),
+					hours);
+	}
+
+	return secondary_msg;
+}
+
+/* Returns 1 if we should save before closing,
+   3 if we shouldn't, and
+   2 if we should cancel the operation 
+   (or -4 if dialog was deleted) */
+static gint
+show_message_dialog (GtkWidget *capplet)
 {
 	GtkWidget *dlg;
+	gchar *secondary_msg;
 	gint response;
+	GTimeVal current_time;
+
+	dlg = gtk_message_dialog_new (GTK_WINDOW (capplet),
+			GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
+			GTK_MESSAGE_WARNING,
+			GTK_BUTTONS_NONE,
+			_("Save changes to the current session before closing?"));
+
+	g_get_current_time (&current_time);
+	secondary_msg = get_save_secondary_label (current_time.tv_sec - dirty_start_time.tv_sec);
+	gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dlg), "%s", secondary_msg);
+	g_free (secondary_msg);
+
+	gtk_dialog_add_buttons (GTK_DIALOG (dlg), 
+			_("_Close without Saving"), 3,
+			GTK_STOCK_CANCEL, 2,
+			GTK_STOCK_SAVE, 1,
+			NULL);
+	gtk_dialog_set_default_response (GTK_DIALOG (dlg), 1);
+	gtk_window_set_title (GTK_WINDOW (dlg), "");
 
-	dlg = gtk_message_dialog_new (NULL, 0, GTK_MESSAGE_QUESTION, GTK_BUTTONS_OK_CANCEL,
-				      _("Some changes are not saved.\nIs it still OK to exit?"));
 	response = gtk_dialog_run (GTK_DIALOG (dlg));
 	gtk_widget_destroy (dlg);
-	if (response != GTK_RESPONSE_OK) 
-		return TRUE;
-	else
-		return FALSE;
+	return response;
 }
 
 static gboolean
-spc_delete (void)
+spc_delete (GtkWidget *capplet)
 {
-	gint ret = FALSE;
+	gint ret = 3;
 	if (state_dirty)
-		ret = show_message_dialog ();
+		ret = show_message_dialog (capplet);
 
-	if (ret == TRUE) 
-		return TRUE;
-	else {
+	switch (ret)
+	{
+	case 1:
+		apply ();
+		/* fall through */
+	case 3:
 		gtk_main_quit ();
 		return FALSE;
+	default: /* safest possible action on unclear delete-dialog response from user */
+	case 2:
+		return TRUE;
 	}
 }
 
 static void
-spc_close (void)
+spc_close (GtkWidget *capplet)
 {
-	spc_delete ();
+	spc_delete (capplet);
 }
 
 static GtkWidget *
@@ -245,8 +340,8 @@
   g_signal_connect (G_OBJECT (help_button), "clicked", help_cb, NULL);
   b = gtk_dialog_add_button (GTK_DIALOG (dlg), GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE);
   gtk_dialog_set_default_response (GTK_DIALOG (dlg), GTK_RESPONSE_CLOSE);
-  g_signal_connect (G_OBJECT (b), "clicked", spc_close, NULL);
-  g_signal_connect (dlg, "delete-event", G_CALLBACK(spc_delete), NULL);
+  g_signal_connect_swapped (G_OBJECT (b), "clicked", G_CALLBACK (spc_close), dlg);
+  g_signal_connect_swapped (dlg, "delete-event", G_CALLBACK (spc_delete), dlg);
 
   /* FIXME: Get rid of global capplet variable, or use only it, not both (Lauris) */
   capplet = dlg;
@@ -526,8 +621,12 @@
 void
 mark_dirty (void)
 {
-  state_dirty = TRUE;
-  gtk_widget_set_sensitive (apply_button, TRUE);
+  if (!state_dirty)
+  {
+    state_dirty = TRUE;
+    g_get_current_time (&dirty_start_time);
+    gtk_widget_set_sensitive (apply_button, TRUE);
+  }
 }
 
 /* Add a startup program to the list */
