aboutsummaryrefslogtreecommitdiffstats
path: root/e-util/e-dialog-utils.c
diff options
context:
space:
mode:
Diffstat (limited to 'e-util/e-dialog-utils.c')
-rw-r--r--e-util/e-dialog-utils.c337
1 files changed, 165 insertions, 172 deletions
diff --git a/e-util/e-dialog-utils.c b/e-util/e-dialog-utils.c
index a37519297e..bf51a63914 100644
--- a/e-util/e-dialog-utils.c
+++ b/e-util/e-dialog-utils.c
@@ -22,239 +22,230 @@
* Ettore Perazzoli <ettore@ximian.com>
*/
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
#include "e-dialog-utils.h"
+#include "widgets/misc/e-bonobo-widget.h"
+
#include <gdk/gdkx.h>
+#include <gdk/gdkprivate.h>
+#include <gdk/gdk.h>
-#include <gtk/gtkfilesel.h>
#include <gtk/gtkmain.h>
-#include <gtk/gtkplug.h>
+#include <gtk/gtksignal.h>
+#include <gtk/gtkfilesel.h>
+#include <libgnome/gnome-defs.h>
#include <libgnome/gnome-i18n.h>
#include <libgnome/gnome-util.h>
+#include <libgnomeui/gnome-dialog-util.h>
+#include <libgnomeui/gnome-uidefs.h>
+
+#include <bonobo/bonobo-control.h>
+#include <bonobo/bonobo-property-bag.h>
-/**
- * e_notice:
- * @parent: the dialog's parent window, or %NULL
- * @type: the type of dialog (%GTK_MESSAGE_INFO, %GTK_MESSAGE_WARNING,
- * or %GTK_MESSAGE_ERROR)
- * @format: printf-style format string, followed by arguments
- *
- * Convenience function to show a dialog with a message and an "OK"
- * button.
- **/
-void
-e_notice (gpointer parent, GtkMessageType type, const char *format, ...)
+#define TRANSIENT_DATA_ID "e-dialog:transient"
+
+
+static void
+transient_realize_callback (GtkWidget *widget)
{
- GtkWidget *dialog;
- va_list args;
- char *str;
-
- va_start (args, format);
- str = g_strdup_vprintf (format, args);
- dialog = gtk_message_dialog_new (NULL,
- GTK_DIALOG_DESTROY_WITH_PARENT,
- type,
- GTK_BUTTONS_OK,
- "%s",
- str);
- va_end (args);
- g_free (str);
-
- if (parent)
- e_dialog_set_transient_for (GTK_WINDOW (dialog), parent);
- gtk_dialog_run (GTK_DIALOG (dialog));
- gtk_widget_destroy (dialog);
+ GdkWindow *window;
+
+ window = gtk_object_get_data (GTK_OBJECT (widget), TRANSIENT_DATA_ID);
+ g_assert (window != NULL);
+
+ gdk_window_set_transient_for (GTK_WIDGET (widget)->window, window);
}
-/**
- * e_notice_with_xid:
- * @parent: the dialog's parent window, or %NULL
- * @type: the type of dialog (%GTK_MESSAGE_INFO, %GTK_MESSAGE_WARNING,
- * or %GTK_MESSAGE_ERROR)
- * @format: printf-style format string, followed by arguments
- *
- * Like e_notice(), but takes a GdkNativeWindow for the parent
- * window argument.
- **/
-void
-e_notice_with_xid (GdkNativeWindow parent, GtkMessageType type, const char *format, ...)
+static void
+transient_unrealize_callback (GtkWidget *widget)
{
- GtkWidget *dialog;
- va_list args;
- char *str;
-
- va_start (args, format);
- str = g_strdup_vprintf (format, args);
- dialog = gtk_message_dialog_new (NULL,
- GTK_DIALOG_DESTROY_WITH_PARENT,
- type,
- GTK_BUTTONS_OK,
- "%s",
- str);
- va_end (args);
- g_free (str);
+ GdkWindow *window;
+
+ window = gtk_object_get_data (GTK_OBJECT (widget), TRANSIENT_DATA_ID);
+ g_assert (window != NULL);
+
+ gdk_property_delete (window, gdk_atom_intern ("WM_TRANSIENT_FOR", FALSE));
+}
+
+static void
+transient_destroy_callback (GtkWidget *widget)
+{
+ GdkWindow *window;
- if (parent)
- e_dialog_set_transient_for_xid (GTK_WINDOW (dialog), parent);
- gtk_dialog_run (GTK_DIALOG (dialog));
- gtk_widget_destroy (dialog);
+ window = gtk_object_get_data (GTK_OBJECT (widget), "transient");
+ if (window != NULL)
+ gdk_window_unref (window);
}
-
-/* Tests whether or not an X Window is being managed by the
- * window manager.
- */
-static gboolean
-window_is_wm_toplevel (Display *display, Window window)
+static void
+set_transient_for_gdk (GtkWindow *window,
+ GdkWindow *parent)
{
- static Atom WM_STATE = None;
- unsigned long nitems, after;
- unsigned char *data = NULL;
- Atom type = None;
- int format;
-
- if (!WM_STATE)
- WM_STATE = XInternAtom (display, "WM_STATE", False);
-
- if (XGetWindowProperty (display, window, WM_STATE, 0, 0, False,
- AnyPropertyType, &type, &format,
- &nitems, &after, &data) == Success) {
- if (data)
- XFree((char*)data);
- if (type)
- return TRUE;
+ g_return_if_fail (window != NULL);
+ g_return_if_fail (gtk_object_get_data (GTK_OBJECT (window), TRANSIENT_DATA_ID) == NULL);
+
+ /* if the parent window doesn't exist anymore,
+ * something is probably about to go very wrong,
+ * but at least let's not segfault here. */
+
+ if (parent == NULL) {
+ g_warning ("set_transient_for_gdk: uhoh, parent of window %p is NULL", window);
+ return;
}
- return FALSE;
+
+ gdk_window_ref (parent); /* FIXME? */
+
+ gtk_object_set_data (GTK_OBJECT (window), TRANSIENT_DATA_ID, parent);
+
+ if (GTK_WIDGET_REALIZED (window))
+ gdk_window_set_transient_for (GTK_WIDGET (window)->window, parent);
+
+ gtk_signal_connect (GTK_OBJECT (window), "realize",
+ GTK_SIGNAL_FUNC (transient_realize_callback), NULL);
+
+ gtk_signal_connect (GTK_OBJECT (window), "unrealize",
+ GTK_SIGNAL_FUNC (transient_unrealize_callback), NULL);
+
+ gtk_signal_connect (GTK_OBJECT (window), "destroy",
+ GTK_SIGNAL_FUNC (transient_destroy_callback), NULL);
}
+
/**
- * e_dialog_set_transient_for:
- * @dialog: a dialog window
- * @parent_widget: the parent for @dialog
+ * e_set_dialog_parent:
+ * @dialog:
+ * @parent_widget:
*
- * This sets the parent for @dialog to be @parent_widget. Unlike
- * gtk_window_set_transient_for(), this doesn't need @parent_widget to
- * be the actual toplevel, and also works if @parent_widget is
- * embedded as a Bonobo control by an out-of-process container.
- * @parent_widget must already be realized before calling this
- * function, but @dialog does not need to be.
+ * This sets the parent for @dialog to be @parent_widget. Unlike
+ * gtk_window_set_parent(), this doesn't need @parent_widget to be the actual
+ * toplevel, and also works if @parent_widget is been embedded as a Bonobo
+ * control by an out-of-process container.
**/
void
-e_dialog_set_transient_for (GtkWindow *dialog,
- GtkWidget *parent_widget)
+e_set_dialog_parent (GtkWindow *dialog,
+ GtkWidget *parent_widget)
{
+ Bonobo_PropertyBag property_bag;
GtkWidget *toplevel;
- Window parent, root_ret, *children;
- unsigned int numchildren;
- Display *display;
- Status status;
+ GdkWindow *gdk_window;
+ CORBA_char *id;
+ guint32 xid;
+ g_return_if_fail (dialog != NULL);
g_return_if_fail (GTK_IS_WINDOW (dialog));
+ g_return_if_fail (parent_widget != NULL);
g_return_if_fail (GTK_IS_WIDGET (parent_widget));
toplevel = gtk_widget_get_toplevel (parent_widget);
if (toplevel == NULL)
return;
- if (!GTK_IS_PLUG (toplevel)) {
- gtk_window_set_transient_for (GTK_WINDOW (dialog),
- GTK_WINDOW (toplevel));
+ if (! BONOBO_IS_CONTROL (toplevel)) {
+ if (GTK_IS_WINDOW (toplevel))
+ gtk_window_set_transient_for (dialog, GTK_WINDOW (toplevel));
return;
}
- /* Find the top-level windowmanager-managed X Window */
- display = GDK_WINDOW_XDISPLAY (parent_widget->window);
- parent = GDK_WINDOW_XID (parent_widget->window);
+ property_bag = bonobo_control_get_ambient_properties (BONOBO_CONTROL (toplevel), NULL);
+ if (property_bag == CORBA_OBJECT_NIL)
+ return;
- while (parent && !window_is_wm_toplevel (display, parent)) {
- status = XQueryTree (display, parent, &root_ret,
- &parent, &children, &numchildren);
- if (status != 0)
- XFree (children);
- }
+ id = bonobo_property_bag_client_get_value_string (property_bag, E_BONOBO_WIDGET_TOPLEVEL_PROPERTY_ID, NULL);
+ if (id == NULL)
+ return;
- e_dialog_set_transient_for_xid (dialog, parent);
-}
+ xid = strtol (id, NULL, 10);
-static void
-dialog_realized (GtkWindow *dialog, gpointer xid)
-{
- e_dialog_set_transient_for_xid (dialog, (GdkNativeWindow)xid);
+ gdk_window = gdk_window_foreign_new (xid);
+ set_transient_for_gdk (dialog, gdk_window);
}
/**
- * e_dialog_set_transient_for_xid:
- * @dialog: a dialog window
- * @xid: the X Window parent
+ * e_set_dialog_parent_from_xid:
+ * @dialog:
+ * @xid:
*
- * Like e_dialog_set_transient_for(), but use an XID to specify the
- * parent window.
+ * Like %e_set_dialog_parent_from_xid, but use an XID to specify the parent
+ * window.
**/
void
-e_dialog_set_transient_for_xid (GtkWindow *dialog,
- GdkNativeWindow xid)
+e_set_dialog_parent_from_xid (GtkWindow *dialog,
+ Window xid)
{
-#ifdef GDK_MULTIHEAD_SAFE
- GdkDisplay *display;
-#endif
- GdkWindow *parent;
-
+ g_return_if_fail (dialog != NULL);
g_return_if_fail (GTK_IS_WINDOW (dialog));
- if (!GTK_WIDGET_REALIZED (dialog)) {
- g_signal_connect (dialog, "realize",
- G_CALLBACK (dialog_realized),
- (gpointer) xid);
- return;
- }
+ set_transient_for_gdk (dialog, gdk_window_foreign_new (xid));
+}
-#ifdef GDK_MULTIHEAD_SAFE
- display = gdk_drawable_get_display (GDK_DRAWABLE (GTK_WIDGET (dialog)->window));
- parent = gdk_window_lookup_for_display (display, xid);
- if (!parent)
- parent = gdk_window_foreign_new_for_display (display, xid);
-#else
- parent = gdk_window_lookup (xid);
- if (!parent)
- parent = gdk_window_foreign_new (xid);
-#endif
- g_return_if_fail (parent != NULL);
+static void
+e_gnome_dialog_parent_destroyed (GtkWidget *parent, GtkWidget *dialog)
+{
+ gnome_dialog_close (GNOME_DIALOG (dialog));
+}
- gdk_window_set_transient_for (GTK_WIDGET (dialog)->window, parent);
+void
+e_gnome_dialog_set_parent (GnomeDialog *dialog, GtkWindow *parent)
+{
+ gnome_dialog_set_parent (dialog, parent);
+ gtk_signal_connect_while_alive (GTK_OBJECT (parent), "destroy",
+ e_gnome_dialog_parent_destroyed,
+ dialog, GTK_OBJECT (dialog));
}
+GtkWidget *
+e_gnome_warning_dialog_parented (const char *warning, GtkWindow *parent)
+{
+ GtkWidget *dialog;
+
+ dialog = gnome_warning_dialog_parented (warning, parent);
+ gtk_signal_connect_while_alive (GTK_OBJECT (parent), "destroy",
+ e_gnome_dialog_parent_destroyed, dialog, GTK_OBJECT(dialog));
+
+ return dialog;
+}
+
+GtkWidget *
+e_gnome_ok_cancel_dialog_parented (const char *message, GnomeReplyCallback callback,
+ gpointer data, GtkWindow *parent)
+{
+ GtkWidget *dialog;
+
+ dialog = gnome_ok_cancel_dialog_parented (message, callback, data, parent);
+ gtk_signal_connect_while_alive (GTK_OBJECT (parent), "destroy",
+ e_gnome_dialog_parent_destroyed, dialog, GTK_OBJECT(dialog));
+
+ return dialog;
+}
-
static void
save_ok (GtkWidget *widget, gpointer data)
{
GtkWidget *fs;
char **filename = data;
- const char *path;
- int btn = GTK_RESPONSE_YES;
-
+ char *path;
+ int btn = GNOME_YES;
+
fs = gtk_widget_get_toplevel (widget);
path = gtk_file_selection_get_filename (GTK_FILE_SELECTION (fs));
-
- if (g_file_test (path, G_FILE_TEST_IS_REGULAR)) {
+
+ if (g_file_test (path, G_FILE_TEST_ISFILE)) {
GtkWidget *dlg;
-
- dlg = gtk_message_dialog_new (GTK_WINDOW (fs), 0,
- GTK_MESSAGE_QUESTION,
- GTK_BUTTONS_YES_NO,
- _("A file by that name already exists.\n"
- "Overwrite it?"));
- gtk_window_set_title (GTK_WINDOW (dlg), _("Overwrite file?"));
-
- btn = gtk_dialog_run (GTK_DIALOG (dlg));
- gtk_widget_destroy (dlg);
+
+ dlg = gnome_question_dialog_modal (_("A file by that name already exists.\n"
+ "Overwrite it?"), NULL, NULL);
+ btn = gnome_dialog_run_and_close (GNOME_DIALOG (dlg));
}
-
- if (btn == GTK_RESPONSE_YES)
+
+ if (btn == GNOME_YES)
*filename = g_strdup (path);
-
+
gtk_main_quit ();
}
@@ -263,21 +254,23 @@ e_file_dialog_save (const char *title)
{
GtkFileSelection *fs;
char *path, *filename = NULL;
-
+
fs = GTK_FILE_SELECTION (gtk_file_selection_new (title));
path = g_strdup_printf ("%s/", g_get_home_dir ());
gtk_file_selection_set_filename (fs, path);
g_free (path);
- g_signal_connect (fs->ok_button, "clicked", G_CALLBACK (save_ok), &filename);
- g_signal_connect (fs->cancel_button, "clicked", G_CALLBACK (gtk_main_quit), NULL);
+ gtk_signal_connect (GTK_OBJECT (fs->ok_button), "clicked",
+ GTK_SIGNAL_FUNC (save_ok), &filename);
+ gtk_signal_connect (GTK_OBJECT (fs->cancel_button), "clicked",
+ GTK_SIGNAL_FUNC (gtk_main_quit), NULL);
gtk_widget_show (GTK_WIDGET (fs));
gtk_grab_add (GTK_WIDGET (fs));
gtk_main ();
gtk_widget_destroy (GTK_WIDGET (fs));
-
+
return filename;
}