1 /*
2  * Nautilus-Actions
3  * A Nautilus extension which offers configurable context menu actions.
4  *
5  * Copyright (C) 2005 The GNOME Foundation
6  * Copyright (C) 2006-2008 Frederic Ruaudel and others (see AUTHORS)
7  * Copyright (C) 2009-2014 Pierre Wieser and others (see AUTHORS)
8  *
9  * Nautilus-Actions is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License as
11  * published by the Free Software Foundation; either version 2 of
12  * the License, or (at your option) any later version.
13  *
14  * Nautilus-Actions is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with Nautilus-Actions; see the file COPYING. If not, see
21  * <http://www.gnu.org/licenses/>.
22  *
23  * Authors:
24  *   Frederic Ruaudel <grumz@grumz.net>
25  *   Rodrigo Moya <rodrigo@gnome-db.org>
26  *   Pierre Wieser <pwieser@trychlos.org>
27  *   ... and many others (see AUTHORS)
28  */
29 
30 #ifdef HAVE_CONFIG_H
31 #include <config.h>
32 #endif
33 
34 #include "base-dialog.h"
35 
36 /* private class data
37  */
38 struct _BaseDialogClassPrivate {
39 	void *empty;						/* so that gcc -pedantic is happy */
40 };
41 
42 /* private instance data
43  */
44 struct _BaseDialogPrivate {
45 	gboolean dispose_has_run;
46 };
47 
48 static BaseWindowClass *st_parent_class = NULL;
49 
50 static GType    register_type( void );
51 static void     class_init( BaseDialogClass *klass );
52 static void     instance_init( GTypeInstance *instance, gpointer klass );
53 static void     instance_dispose( GObject *application );
54 static void     instance_finalize( GObject *application );
55 
56 static int      do_run( BaseWindow *window );
57 static gboolean terminate_dialog( BaseDialog *window, GtkDialog *toplevel, int *code );
58 static void     dialog_cancel( BaseDialog *window );
59 static void     dialog_ok( BaseDialog *window );
60 
61 GType
base_dialog_get_type(void)62 base_dialog_get_type( void )
63 {
64 	static GType dialog_type = 0;
65 
66 	if( !dialog_type ){
67 		dialog_type = register_type();
68 	}
69 
70 	return( dialog_type );
71 }
72 
73 static GType
register_type(void)74 register_type( void )
75 {
76 	static const gchar *thisfn = "base_dialog_register_type";
77 	GType type;
78 
79 	static GTypeInfo info = {
80 		sizeof( BaseDialogClass ),
81 		( GBaseInitFunc ) NULL,
82 		( GBaseFinalizeFunc ) NULL,
83 		( GClassInitFunc ) class_init,
84 		NULL,
85 		NULL,
86 		sizeof( BaseDialog ),
87 		0,
88 		( GInstanceInitFunc ) instance_init
89 	};
90 
91 	g_debug( "%s", thisfn );
92 
93 	type = g_type_register_static( BASE_TYPE_WINDOW, "BaseDialog", &info, 0 );
94 
95 	return( type );
96 }
97 
98 static void
class_init(BaseDialogClass * klass)99 class_init( BaseDialogClass *klass )
100 {
101 	static const gchar *thisfn = "base_dialog_class_init";
102 	GObjectClass *object_class;
103 	BaseWindowClass *base_class;
104 
105 	g_debug( "%s: klass=%p", thisfn, ( void * ) klass );
106 
107 	st_parent_class = g_type_class_peek_parent( klass );
108 
109 	object_class = G_OBJECT_CLASS( klass );
110 	object_class->dispose = instance_dispose;
111 	object_class->finalize = instance_finalize;
112 
113 	base_class = BASE_WINDOW_CLASS( klass );
114 	base_class->run = do_run;
115 
116 	klass->private = g_new0( BaseDialogClassPrivate, 1 );
117 }
118 
119 static void
instance_init(GTypeInstance * instance,gpointer klass)120 instance_init( GTypeInstance *instance, gpointer klass )
121 {
122 	static const gchar *thisfn = "base_dialog_instance_init";
123 	BaseDialog *self;
124 
125 	g_return_if_fail( BASE_IS_DIALOG( instance ));
126 
127 	g_debug( "%s: instance=%p (%s), klass=%p",
128 			thisfn, ( void * ) instance, G_OBJECT_TYPE_NAME( instance ), ( void * ) klass );
129 
130 	self = BASE_DIALOG( instance );
131 
132 	self->private = g_new0( BaseDialogPrivate, 1 );
133 
134 	self->private->dispose_has_run = FALSE;
135 }
136 
137 static void
instance_dispose(GObject * window)138 instance_dispose( GObject *window )
139 {
140 	static const gchar *thisfn = "base_dialog_instance_dispose";
141 	BaseDialog *self;
142 
143 	g_return_if_fail( BASE_IS_DIALOG( window ));
144 
145 	self = BASE_DIALOG( window );
146 
147 	if( !self->private->dispose_has_run ){
148 
149 		g_debug( "%s: window=%p (%s)", thisfn, ( void * ) window, G_OBJECT_TYPE_NAME( window ));
150 
151 		self->private->dispose_has_run = TRUE;
152 
153 		/* chain up to the parent class */
154 		if( G_OBJECT_CLASS( st_parent_class )->dispose ){
155 			G_OBJECT_CLASS( st_parent_class )->dispose( window );
156 		}
157 	}
158 }
159 
160 static void
instance_finalize(GObject * window)161 instance_finalize( GObject *window )
162 {
163 	static const gchar *thisfn = "base_dialog_instance_finalize";
164 	BaseDialog *self;
165 
166 	g_return_if_fail( BASE_IS_DIALOG( window ));
167 
168 	g_debug( "%s: window=%p (%s)", thisfn, ( void * ) window, G_OBJECT_TYPE_NAME( window ));
169 
170 	self = BASE_DIALOG( window );
171 
172 	g_free( self->private );
173 
174 	/* chain call to parent class */
175 	if( G_OBJECT_CLASS( st_parent_class )->finalize ){
176 		G_OBJECT_CLASS( st_parent_class )->finalize( window );
177 	}
178 }
179 
180 /*
181  * returns the response ID of the dialog box
182  */
183 static int
do_run(BaseWindow * window)184 do_run( BaseWindow *window )
185 {
186 	static const gchar *thisfn = "base_dialog_do_run";
187 	int code;
188 	GtkWindow *toplevel;
189 
190 	g_return_val_if_fail( BASE_IS_DIALOG( window ), BASE_EXIT_CODE_PROGRAM );
191 
192 	code = BASE_EXIT_CODE_INIT_WINDOW;
193 
194 	if( !BASE_DIALOG( window )->private->dispose_has_run ){
195 
196 		g_debug( "%s: window=%p (%s), starting gtk_dialog_run",
197 				thisfn,
198 				( void * ) window, G_OBJECT_TYPE_NAME( window ));
199 
200 		toplevel = base_window_get_gtk_toplevel( window );
201 
202 		do {
203 			code = gtk_dialog_run( GTK_DIALOG( toplevel ));
204 		}
205 		while( !terminate_dialog( BASE_DIALOG( window ), GTK_DIALOG( toplevel ), &code ));
206 	}
207 
208 	return( code );
209 }
210 
211 /*
212  * returns %TRUE to quit the dialog loop
213  */
214 static gboolean
terminate_dialog(BaseDialog * window,GtkDialog * toplevel,int * code)215 terminate_dialog( BaseDialog *window, GtkDialog *toplevel, int *code )
216 {
217 	gboolean quit = FALSE;
218 
219 	switch( *code ){
220 		case GTK_RESPONSE_NONE:
221 		case GTK_RESPONSE_DELETE_EVENT:
222 		case GTK_RESPONSE_CLOSE:
223 		case GTK_RESPONSE_CANCEL:
224 			dialog_cancel( window );
225 			*code = GTK_RESPONSE_CANCEL;
226 			quit = TRUE;
227 			break;
228 
229 		case GTK_RESPONSE_OK:
230 			dialog_ok( window );
231 			quit = TRUE;
232 			break;
233 	}
234 
235 	return( quit );
236 }
237 
238 static void
dialog_cancel(BaseDialog * window)239 dialog_cancel( BaseDialog *window )
240 {
241 	if( BASE_DIALOG_GET_CLASS( window )->cancel ){
242 		BASE_DIALOG_GET_CLASS( window )->cancel( window );
243 	}
244 }
245 
246 static void
dialog_ok(BaseDialog * window)247 dialog_ok( BaseDialog *window )
248 {
249 	if( BASE_DIALOG_GET_CLASS( window )->ok ){
250 		BASE_DIALOG_GET_CLASS( window )->ok( window );
251 	}
252 }
253