2006-10-08  Tom Tromey  <tromey@redhat.com>

	Bug #340766:
	* stickynotes.c (stickynotes_write_contents): New function.
	(stickynotes_save): Use it.

Index: stickynotes.c
===================================================================
RCS file: /cvs/gnome/gnome-applets/stickynotes/stickynotes.c,v
retrieving revision 1.74
diff -u -r1.74 stickynotes.c
--- stickynotes.c 5 Sep 2006 03:07:43 -0000 1.74
+++ stickynotes.c 8 Oct 2006 19:56:48 -0000
@@ -698,6 +698,33 @@
 	g_object_unref(glade);
 }
 
+/* Helper function to write the file.  On failure will ask the user
+   and may loop.  */
+static void
+stickynotes_write_contents (gchar *filename, const char *contents,
+			    int content_len)
+{
+	while (1) {
+		GError *err = NULL;
+		GtkWidget *msg;
+		int response;
+		if (g_file_set_contents(filename, contents, content_len, &err))
+			break;
+		msg = gtk_message_dialog_new(NULL,
+					     0,
+					     GTK_MESSAGE_ERROR,
+					     GTK_BUTTONS_YES_NO,
+					     _("Notes cannot be saved: %s.  Try to save again?"),
+					     err->message);
+		gtk_window_set_position (GTK_WINDOW (msg), GTK_WIN_POS_CENTER);
+		response = gtk_dialog_run (GTK_DIALOG (msg));
+		g_error_free(err);
+		gtk_widget_destroy(msg);
+		if (response == GTK_RESPONSE_NO)
+			break;
+	}
+}
+
 /* Save all sticky notes in an XML configuration file */
 void
 stickynotes_save (void)
@@ -798,10 +825,25 @@
 
 	/* The XML file is $HOME/.gnome2/stickynotes_applet, most probably */
 	{
-		gchar *file = g_strdup_printf("%s%s", g_get_home_dir(),
-				XML_PATH);
-		xmlSaveFormatFile(file, doc, 1);
-		g_free(file);
+		/* The XML file-writing APIs don't atomically write.
+		   This can cause problems if writing fails, so we use
+		   g_file_set_contents for safety.  */
+		xmlBufferPtr outbuf = xmlBufferCreate();
+		xmlOutputBufferPtr out = xmlOutputBufferCreateBuffer(outbuf,
+								     NULL);
+		if (xmlSaveFormatFileTo(out, doc, NULL, 1) == -1) {
+			/* Not sure what to do here...  */
+			g_warning("Could not create XML document.");
+		} else {
+			gchar *file = g_strdup_printf("%s%s", g_get_home_dir(),
+						      XML_PATH);
+			stickynotes_write_contents(file,
+						   xmlBufferContent(outbuf),
+						   xmlBufferLength(outbuf));
+			g_free(file);
+		}
+		/* Note that xmlSaveFormatFileTo closes 'out'.  */
+		xmlBufferFree(outbuf);
 	}
 	
 	xmlFreeDoc(doc);
