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

Revision 18142, 7.1 KB checked in by ghudson, 22 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r18141, 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#include "e-dialog-utils.h"
26
27#include "widgets/misc/e-bonobo-widget.h"
28
29#include <gdk/gdkx.h>
30#include <gdk/gdkprivate.h>
31#include <gdk/gdk.h>
32
33#include <gtk/gtkmain.h>
34#include <gtk/gtksignal.h>
35#include <gtk/gtkfilesel.h>
36
37#include <libgnome/gnome-defs.h>
38#include <libgnome/gnome-i18n.h>
39#include <libgnome/gnome-util.h>
40#include <libgnomeui/gnome-dialog-util.h>
41#include <libgnomeui/gnome-uidefs.h>
42
43#include <bonobo/bonobo-control.h>
44#include <bonobo/bonobo-property-bag.h>
45
46
47#define TRANSIENT_DATA_ID "e-dialog:transient"
48
49
50static void
51transient_realize_callback (GtkWidget *widget)
52{
53        GdkWindow *window;
54
55        window = gtk_object_get_data (GTK_OBJECT (widget), TRANSIENT_DATA_ID);
56        g_assert (window != NULL);
57
58        gdk_window_set_transient_for (GTK_WIDGET (widget)->window, window);
59}
60
61static void
62transient_unrealize_callback (GtkWidget *widget)
63{
64        GdkWindow *window;
65
66        window = gtk_object_get_data (GTK_OBJECT (widget), TRANSIENT_DATA_ID);
67        g_assert (window != NULL);
68
69        gdk_property_delete (window, gdk_atom_intern ("WM_TRANSIENT_FOR", FALSE));
70}
71
72static void
73transient_destroy_callback (GtkWidget *widget)
74{
75        GdkWindow *window;
76       
77        window = gtk_object_get_data (GTK_OBJECT (widget), "transient");
78        if (window != NULL)
79                gdk_window_unref (window);
80}
81
82static void       
83set_transient_for_gdk (GtkWindow *window,
84                       GdkWindow *parent)
85{
86        g_return_if_fail (window != NULL);
87        g_return_if_fail (gtk_object_get_data (GTK_OBJECT (window), TRANSIENT_DATA_ID) == NULL);
88
89        /* if the parent window doesn't exist anymore,
90         * something is probably about to go very wrong,
91         * but at least let's not segfault here. */
92
93        if (parent == NULL) {
94                g_warning ("set_transient_for_gdk: uhoh, parent of window %p is NULL", window);
95                return;
96        }
97
98        gdk_window_ref (parent); /* FIXME? */
99
100        gtk_object_set_data (GTK_OBJECT (window), TRANSIENT_DATA_ID, parent);
101
102        if (GTK_WIDGET_REALIZED (window))
103                gdk_window_set_transient_for (GTK_WIDGET (window)->window, parent);
104
105        gtk_signal_connect (GTK_OBJECT (window), "realize",
106                            GTK_SIGNAL_FUNC (transient_realize_callback), NULL);
107
108        gtk_signal_connect (GTK_OBJECT (window), "unrealize",
109                            GTK_SIGNAL_FUNC (transient_unrealize_callback), NULL);
110       
111        gtk_signal_connect (GTK_OBJECT (window), "destroy",
112                            GTK_SIGNAL_FUNC (transient_destroy_callback), NULL);
113}
114
115
116/**
117 * e_set_dialog_parent:
118 * @dialog:
119 * @parent_widget:
120 *
121 * This sets the parent for @dialog to be @parent_widget.  Unlike
122 * gtk_window_set_parent(), this doesn't need @parent_widget to be the actual
123 * toplevel, and also works if @parent_widget is been embedded as a Bonobo
124 * control by an out-of-process container.
125 **/
126void
127e_set_dialog_parent (GtkWindow *dialog,
128                     GtkWidget *parent_widget)
129{
130        Bonobo_PropertyBag property_bag;
131        GtkWidget *toplevel;
132        GdkWindow *gdk_window;
133        CORBA_char *id;
134        guint32 xid;
135
136        g_return_if_fail (dialog != NULL);
137        g_return_if_fail (GTK_IS_WINDOW (dialog));
138        g_return_if_fail (parent_widget != NULL);
139        g_return_if_fail (GTK_IS_WIDGET (parent_widget));
140
141        toplevel = gtk_widget_get_toplevel (parent_widget);
142        if (toplevel == NULL)
143                return;
144
145        if (! BONOBO_IS_CONTROL (toplevel)) {
146                if (GTK_IS_WINDOW (toplevel))
147                        gtk_window_set_transient_for (dialog, GTK_WINDOW (toplevel));
148                return;
149        }
150
151        property_bag = bonobo_control_get_ambient_properties (BONOBO_CONTROL (toplevel), NULL);
152        if (property_bag == CORBA_OBJECT_NIL)
153                return;
154
155        id = bonobo_property_bag_client_get_value_string (property_bag, E_BONOBO_WIDGET_TOPLEVEL_PROPERTY_ID, NULL);
156        if (id == NULL)
157                return;
158
159        xid = strtol (id, NULL, 10);
160
161        gdk_window = gdk_window_foreign_new (xid);
162        set_transient_for_gdk (dialog, gdk_window);
163}
164
165/**
166 * e_set_dialog_parent_from_xid:
167 * @dialog:
168 * @xid:
169 *
170 * Like %e_set_dialog_parent_from_xid, but use an XID to specify the parent
171 * window.
172 **/
173void
174e_set_dialog_parent_from_xid (GtkWindow *dialog,
175                              Window xid)
176{
177        g_return_if_fail (dialog != NULL);
178        g_return_if_fail (GTK_IS_WINDOW (dialog));
179
180        set_transient_for_gdk (dialog, gdk_window_foreign_new (xid));
181}
182
183static void
184e_gnome_dialog_parent_destroyed (GtkWidget *parent, GtkWidget *dialog)
185{
186        gnome_dialog_close (GNOME_DIALOG (dialog));
187}
188
189void
190e_gnome_dialog_set_parent (GnomeDialog *dialog, GtkWindow *parent)
191{
192        gnome_dialog_set_parent (dialog, parent);
193        gtk_signal_connect_while_alive (GTK_OBJECT (parent), "destroy",
194                                        e_gnome_dialog_parent_destroyed,
195                                        dialog, GTK_OBJECT (dialog));
196}
197
198GtkWidget *
199e_gnome_warning_dialog_parented (const char *warning, GtkWindow *parent)
200{
201        GtkWidget *dialog;
202       
203        dialog = gnome_warning_dialog_parented (warning, parent);
204        gtk_signal_connect_while_alive (GTK_OBJECT (parent), "destroy",
205                                        e_gnome_dialog_parent_destroyed, dialog, GTK_OBJECT(dialog));
206       
207        return dialog;
208}
209
210GtkWidget *
211e_gnome_ok_cancel_dialog_parented (const char *message, GnomeReplyCallback callback,
212                                   gpointer data, GtkWindow *parent)
213{
214        GtkWidget *dialog;
215       
216        dialog = gnome_ok_cancel_dialog_parented (message, callback, data, parent);
217        gtk_signal_connect_while_alive (GTK_OBJECT (parent), "destroy",
218                                        e_gnome_dialog_parent_destroyed, dialog, GTK_OBJECT(dialog));
219       
220        return dialog;
221}
222
223static void
224save_ok (GtkWidget *widget, gpointer data)
225{
226        GtkWidget *fs;
227        char **filename = data;
228        char *path;
229        int btn = GNOME_YES;
230
231        fs = gtk_widget_get_toplevel (widget);
232        path = gtk_file_selection_get_filename (GTK_FILE_SELECTION (fs));
233
234        if (g_file_test (path, G_FILE_TEST_ISFILE)) {
235                GtkWidget *dlg;
236
237                dlg = gnome_question_dialog_modal (_("A file by that name already exists.\n"
238                                                     "Overwrite it?"), NULL, NULL);
239                btn = gnome_dialog_run_and_close (GNOME_DIALOG (dlg));
240        }
241
242        if (btn == GNOME_YES)
243                *filename = g_strdup (path);
244
245        gtk_main_quit ();
246}
247
248char *
249e_file_dialog_save (const char *title)
250{
251        GtkFileSelection *fs;
252        char *path, *filename = NULL;
253
254        fs = GTK_FILE_SELECTION (gtk_file_selection_new (title));
255        path = g_strdup_printf ("%s/", g_get_home_dir ());
256        gtk_file_selection_set_filename (fs, path);
257        g_free (path);
258       
259        gtk_signal_connect (GTK_OBJECT (fs->ok_button), "clicked",
260                            GTK_SIGNAL_FUNC (save_ok), &filename);
261        gtk_signal_connect (GTK_OBJECT (fs->cancel_button), "clicked",
262                            GTK_SIGNAL_FUNC (gtk_main_quit), NULL);
263       
264        gtk_widget_show (GTK_WIDGET (fs));
265        gtk_grab_add (GTK_WIDGET (fs));
266        gtk_main ();
267       
268        gtk_widget_destroy (GTK_WIDGET (fs));
269
270        return filename;
271}
272
273
Note: See TracBrowser for help on using the repository browser.