source: trunk/third/evolution/e-util/e-dialog-utils.c @ 19030

Revision 19030, 7.1 KB checked in by ghudson, 21 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r19029, which included commits to RCS files with non-trunk default branches.
Line 
1/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
2/* e-dialog-utils.h
3 *
4 * Copyright (C) 2001  Ximian, Inc.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of version 2 of the GNU General Public
8 * License as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public
16 * License along with this program; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA.
19 *
20 * Authors:
21 *   Michael Meeks <michael@ximian.com>
22 *   Ettore Perazzoli <ettore@ximian.com>
23 */
24
25#ifdef HAVE_CONFIG_H
26#include <config.h>
27#endif
28
29#include "e-dialog-utils.h"
30
31#include "widgets/misc/e-bonobo-widget.h"
32
33#include <gdk/gdkx.h>
34#include <gdk/gdkprivate.h>
35#include <gdk/gdk.h>
36
37#include <gtk/gtkmain.h>
38#include <gtk/gtksignal.h>
39#include <gtk/gtkfilesel.h>
40
41#include <libgnome/gnome-defs.h>
42#include <libgnome/gnome-i18n.h>
43#include <libgnome/gnome-util.h>
44#include <libgnomeui/gnome-dialog-util.h>
45#include <libgnomeui/gnome-uidefs.h>
46
47#include <bonobo/bonobo-control.h>
48#include <bonobo/bonobo-property-bag.h>
49
50
51#define TRANSIENT_DATA_ID "e-dialog:transient"
52
53
54static void
55transient_realize_callback (GtkWidget *widget)
56{
57        GdkWindow *window;
58
59        window = gtk_object_get_data (GTK_OBJECT (widget), TRANSIENT_DATA_ID);
60        g_assert (window != NULL);
61
62        gdk_window_set_transient_for (GTK_WIDGET (widget)->window, window);
63}
64
65static void
66transient_unrealize_callback (GtkWidget *widget)
67{
68        GdkWindow *window;
69
70        window = gtk_object_get_data (GTK_OBJECT (widget), TRANSIENT_DATA_ID);
71        g_assert (window != NULL);
72
73        gdk_property_delete (window, gdk_atom_intern ("WM_TRANSIENT_FOR", FALSE));
74}
75
76static void
77transient_destroy_callback (GtkWidget *widget)
78{
79        GdkWindow *window;
80       
81        window = gtk_object_get_data (GTK_OBJECT (widget), "transient");
82        if (window != NULL)
83                gdk_window_unref (window);
84}
85
86static void       
87set_transient_for_gdk (GtkWindow *window,
88                       GdkWindow *parent)
89{
90        g_return_if_fail (window != NULL);
91        g_return_if_fail (gtk_object_get_data (GTK_OBJECT (window), TRANSIENT_DATA_ID) == NULL);
92
93        /* if the parent window doesn't exist anymore,
94         * something is probably about to go very wrong,
95         * but at least let's not segfault here. */
96
97        if (parent == NULL) {
98                g_warning ("set_transient_for_gdk: uhoh, parent of window %p is NULL", window);
99                return;
100        }
101
102        gdk_window_ref (parent); /* FIXME? */
103
104        gtk_object_set_data (GTK_OBJECT (window), TRANSIENT_DATA_ID, parent);
105
106        if (GTK_WIDGET_REALIZED (window))
107                gdk_window_set_transient_for (GTK_WIDGET (window)->window, parent);
108
109        gtk_signal_connect (GTK_OBJECT (window), "realize",
110                            GTK_SIGNAL_FUNC (transient_realize_callback), NULL);
111
112        gtk_signal_connect (GTK_OBJECT (window), "unrealize",
113                            GTK_SIGNAL_FUNC (transient_unrealize_callback), NULL);
114       
115        gtk_signal_connect (GTK_OBJECT (window), "destroy",
116                            GTK_SIGNAL_FUNC (transient_destroy_callback), NULL);
117}
118
119
120/**
121 * e_set_dialog_parent:
122 * @dialog:
123 * @parent_widget:
124 *
125 * This sets the parent for @dialog to be @parent_widget.  Unlike
126 * gtk_window_set_parent(), this doesn't need @parent_widget to be the actual
127 * toplevel, and also works if @parent_widget is been embedded as a Bonobo
128 * control by an out-of-process container.
129 **/
130void
131e_set_dialog_parent (GtkWindow *dialog,
132                     GtkWidget *parent_widget)
133{
134        Bonobo_PropertyBag property_bag;
135        GtkWidget *toplevel;
136        GdkWindow *gdk_window;
137        CORBA_char *id;
138        guint32 xid;
139
140        g_return_if_fail (dialog != NULL);
141        g_return_if_fail (GTK_IS_WINDOW (dialog));
142        g_return_if_fail (parent_widget != NULL);
143        g_return_if_fail (GTK_IS_WIDGET (parent_widget));
144
145        toplevel = gtk_widget_get_toplevel (parent_widget);
146        if (toplevel == NULL)
147                return;
148
149        if (! BONOBO_IS_CONTROL (toplevel)) {
150                if (GTK_IS_WINDOW (toplevel))
151                        gtk_window_set_transient_for (dialog, GTK_WINDOW (toplevel));
152                return;
153        }
154
155        property_bag = bonobo_control_get_ambient_properties (BONOBO_CONTROL (toplevel), NULL);
156        if (property_bag == CORBA_OBJECT_NIL)
157                return;
158
159        id = bonobo_property_bag_client_get_value_string (property_bag, E_BONOBO_WIDGET_TOPLEVEL_PROPERTY_ID, NULL);
160        if (id == NULL)
161                return;
162
163        xid = strtol (id, NULL, 10);
164
165        gdk_window = gdk_window_foreign_new (xid);
166        set_transient_for_gdk (dialog, gdk_window);
167}
168
169/**
170 * e_set_dialog_parent_from_xid:
171 * @dialog:
172 * @xid:
173 *
174 * Like %e_set_dialog_parent_from_xid, but use an XID to specify the parent
175 * window.
176 **/
177void
178e_set_dialog_parent_from_xid (GtkWindow *dialog,
179                              Window xid)
180{
181        g_return_if_fail (dialog != NULL);
182        g_return_if_fail (GTK_IS_WINDOW (dialog));
183
184        set_transient_for_gdk (dialog, gdk_window_foreign_new (xid));
185}
186
187static void
188e_gnome_dialog_parent_destroyed (GtkWidget *parent, GtkWidget *dialog)
189{
190        gnome_dialog_close (GNOME_DIALOG (dialog));
191}
192
193void
194e_gnome_dialog_set_parent (GnomeDialog *dialog, GtkWindow *parent)
195{
196        gnome_dialog_set_parent (dialog, parent);
197        gtk_signal_connect_while_alive (GTK_OBJECT (parent), "destroy",
198                                        e_gnome_dialog_parent_destroyed,
199                                        dialog, GTK_OBJECT (dialog));
200}
201
202GtkWidget *
203e_gnome_warning_dialog_parented (const char *warning, GtkWindow *parent)
204{
205        GtkWidget *dialog;
206       
207        dialog = gnome_warning_dialog_parented (warning, parent);
208        gtk_signal_connect_while_alive (GTK_OBJECT (parent), "destroy",
209                                        e_gnome_dialog_parent_destroyed, dialog, GTK_OBJECT(dialog));
210       
211        return dialog;
212}
213
214GtkWidget *
215e_gnome_ok_cancel_dialog_parented (const char *message, GnomeReplyCallback callback,
216                                   gpointer data, GtkWindow *parent)
217{
218        GtkWidget *dialog;
219       
220        dialog = gnome_ok_cancel_dialog_parented (message, callback, data, parent);
221        gtk_signal_connect_while_alive (GTK_OBJECT (parent), "destroy",
222                                        e_gnome_dialog_parent_destroyed, dialog, GTK_OBJECT(dialog));
223       
224        return dialog;
225}
226
227static void
228save_ok (GtkWidget *widget, gpointer data)
229{
230        GtkWidget *fs;
231        char **filename = data;
232        char *path;
233        int btn = GNOME_YES;
234
235        fs = gtk_widget_get_toplevel (widget);
236        path = gtk_file_selection_get_filename (GTK_FILE_SELECTION (fs));
237
238        if (g_file_test (path, G_FILE_TEST_ISFILE)) {
239                GtkWidget *dlg;
240
241                dlg = gnome_question_dialog_modal (_("A file by that name already exists.\n"
242                                                     "Overwrite it?"), NULL, NULL);
243                btn = gnome_dialog_run_and_close (GNOME_DIALOG (dlg));
244        }
245
246        if (btn == GNOME_YES)
247                *filename = g_strdup (path);
248
249        gtk_main_quit ();
250}
251
252char *
253e_file_dialog_save (const char *title)
254{
255        GtkFileSelection *fs;
256        char *path, *filename = NULL;
257
258        fs = GTK_FILE_SELECTION (gtk_file_selection_new (title));
259        path = g_strdup_printf ("%s/", g_get_home_dir ());
260        gtk_file_selection_set_filename (fs, path);
261        g_free (path);
262       
263        gtk_signal_connect (GTK_OBJECT (fs->ok_button), "clicked",
264                            GTK_SIGNAL_FUNC (save_ok), &filename);
265        gtk_signal_connect (GTK_OBJECT (fs->cancel_button), "clicked",
266                            GTK_SIGNAL_FUNC (gtk_main_quit), NULL);
267       
268        gtk_widget_show (GTK_WIDGET (fs));
269        gtk_grab_add (GTK_WIDGET (fs));
270        gtk_main ();
271       
272        gtk_widget_destroy (GTK_WIDGET (fs));
273
274        return filename;
275}
276
277
Note: See TracBrowser for help on using the repository browser.