1 /*
2  *  dialog.c:		Info or warning dialog windows, option menu
3  *
4  *  Written by:		Ullrich Hafner
5  *
6  *  Copyright (C) 1998 Ullrich Hafner <hafner@bigfoot.de>
7  *
8  *  This program is free software; you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation; either version 2 of the License, or
11  *  (at your option) any later version.
12  *
13  *  This program is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *  GNU General Public License for more details.
17  *
18  *  You should have received a copy of the GNU General Public License
19  *  along with this program; if not, write to the Free Software
20  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
21  */
22 
23 /*
24  *  $Date: 1999/12/03 15:34:23 $
25  *  $Author: hafner $
26  *  $Revision: 1.25 $
27  *  $State: Exp $
28  */
29 
30 #include "config.h"
31 
32 #include <gtk/gtk.h>
33 #include "proplist_t.h"
34 
35 #include "dialog.h"
36 #include "misc.h"
37 #include "icons.h"
38 #include "dialog.h"
39 
40 #include "error.h"
41 
42 static void
43 vdialog (dialog_e type, const char *close_text, const char *ok_text,
44 	 void (*ok_function) (GtkWidget *, gpointer),
45 	 gpointer dataptr_ok_function, const char *format, va_list args);
46 
47 /*******************************************************************************
48 
49 				public code
50 
51 *******************************************************************************/
52 
53 void
dialog_popup(dialog_e type,void (* ok_function)(GtkWidget *,gpointer),gpointer dataptr_ok_function,const char * format,...)54 dialog_popup (dialog_e type, void (*ok_function) (GtkWidget *, gpointer),
55 	      gpointer dataptr_ok_function, const char *format, ...)
56 /*
57  *  Popup dialog to display an info, question, warning or error message
58  *  with printf style syntax of 'format'.
59  *  Message 'type' must be one of DIALOG_INFO, DIALOG_QUESTION,
60  *  DIALOG_WARNING, DIALOG_ERROR.
61  *  If 'ok_function' is not NULL then 'ok_function' is called in case
62  *    user activates 'OK' button (which is labeled by 'ok_text').
63  *    'dataptr_ok_function' argument is passed to 'ok_function'.
64  *    A 'Cancel' button (which is labeled by 'close_text') is also shown.
65  *  Otherwise only the 'Cancel' button is shown.
66  *
67  *  No return value.
68  */
69 {
70    va_list args;
71    va_start (args, format);
72 
73    if (ok_function)
74       vdialog (type, _("No"), _("Yes"), ok_function, dataptr_ok_function,
75 	       format, args);
76    else
77       vdialog (type, _("Close"), NULL, ok_function, dataptr_ok_function,
78 	       format, args);
79 
80    va_end (args);
81 }
82 
83 void
dialog(dialog_e type,const char * close_text,const char * ok_text,void (* ok_function)(GtkWidget *,gpointer),gpointer dataptr_ok_function,const char * format,...)84 dialog (dialog_e type, const char *close_text, const char *ok_text,
85 	void (*ok_function) (GtkWidget *, gpointer),
86 	gpointer dataptr_ok_function, const char *format, ...)
87 {
88    va_list args;
89 
90    va_start (args, format);
91 
92    vdialog (type, close_text, ok_text, ok_function, dataptr_ok_function,
93 	    format, args);
94 
95    va_end (args);
96 }
97 
98 static void
vdialog(dialog_e type,const char * close_text,const char * ok_text,void (* ok_function)(GtkWidget *,gpointer),gpointer dataptr_ok_function,const char * format,va_list args)99 vdialog (dialog_e type, const char *close_text, const char *ok_text,
100 	 void (*ok_function) (GtkWidget *, gpointer),
101 	 gpointer dataptr_ok_function, const char *format, va_list args)
102 /*
103  *  Popup dialog to display an info, question, warning or error message
104  *  with printf style syntax of 'format'.
105  *  Message 'type' must be one of DIALOG_INFO, DIALOG_QUESTION,
106  *  DIALOG_WARNING, DIALOG_ERROR.
107  *  If 'ok_function' is not NULL then 'ok_function' is called in case
108  *    user activates 'OK' button (which is labeled by 'ok_text').
109  *    'dataptr_ok_function' argument is passed to 'ok_function'.
110  *    A 'Cancel' button (which is labeled by 'close_text') is also shown.
111  *  Otherwise only the 'Cancel' button is shown.
112  *
113  *  No return value.
114  */
115 {
116    GtkWidget *hbox;
117    GtkWidget *window, *button;
118    char	     *window_title[] = {N_("Info"), N_("Question"),
119 				N_("Warning"), N_("Error")};
120    xpms_e    window_icon[] = {P_INFO, P_QUESTION, P_WARNING, P_ERROR};
121 
122    window = gtk_dialog_new ();
123    gtk_window_set_title (GTK_WINDOW (window), _(window_title [type]));
124    gtk_window_set_position (GTK_WINDOW (window), GTK_WIN_POS_MOUSE);
125    gtk_widget_realize (window);
126 
127    hbox = gtk_hbox_new (FALSE, 5);
128    gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->vbox), hbox,
129 		       FALSE, FALSE, 0);
130    gtk_container_set_border_width (GTK_CONTAINER (hbox), 10);
131 
132    gtk_box_pack_start (GTK_BOX (hbox),
133 		       gtk_pixmap_new (p_array [window_icon [type]].pixmap,
134 				       p_array [window_icon [type]].mask),
135 		       TRUE, FALSE, 5);
136 
137    {
138       char *tmp = g_strdup_vprintf (format, args);
139 
140       gtk_box_pack_start (GTK_BOX (hbox), gtk_label_new (tmp), TRUE, TRUE, 5);
141       Free (tmp);
142    }
143 
144    if (ok_function && ok_text)
145       button = gtk_button_new_with_label (ok_text);
146    else
147       button = gtk_button_new_with_label (close_text);
148 
149    gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), button,
150 		       TRUE, TRUE, 10);
151    GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
152    gtk_widget_grab_default (button);
153 
154    gtk_signal_connect (GTK_OBJECT (window), "delete_event",
155 		       GTK_SIGNAL_FUNC (delete_button), button);
156 
157    if (ok_function)
158    {
159       gtk_signal_connect (GTK_OBJECT (button), "clicked",
160 			  GTK_SIGNAL_FUNC (ok_function), dataptr_ok_function);
161       if (ok_text)
162       {
163 	 gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
164 				    (GtkSignalFunc) gtk_widget_destroy,
165 				    GTK_OBJECT (window));
166 	 button = gtk_button_new_with_label (close_text);
167 	 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), button,
168 			     TRUE, TRUE, 10);
169       }
170    }
171    gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
172 			      (GtkSignalFunc) gtk_widget_destroy,
173 			      GTK_OBJECT (window));
174 
175    gtk_widget_show_all (window);
176 }
177 
178 GtkWidget *
generate_option_menu(const char * description,GtkTooltips * tooltips,const char * info,const char ** entry,const char * current,proplist_t text,void (* callback)(GtkWidget *,gpointer),gpointer callback_data)179 generate_option_menu (const char *description,
180 		      GtkTooltips *tooltips, const char *info,
181 		      const char **entry, const char *current,
182 		      proplist_t text,
183 		      void (*callback) (GtkWidget *, gpointer),
184 		      gpointer callback_data)
185 /*
186  *  Generate an option menu of all available text strings given in NULL
187  *  terminated array 'entry'. Optional 'description' is prepended if not NULL.
188  *  'current' is the string of the default option.
189  *  'callback' function is called if user changes options,
190  *  'callback_data' argument is passed to 'callback'.
191  *
192  *  Return value:
193  *	container widget containing the option menu
194  */
195 {
196    GtkWidget	*hbox = NULL;
197    GtkWidget	*menu;
198    GtkWidget	*menu_item;
199    GtkWidget	*option_menu;
200    const char	**ptr;
201 
202    option_menu = gtk_option_menu_new ();
203    menu = gtk_menu_new ();
204 
205    if (description)
206    {
207       hbox = gtk_hbox_new (FALSE, 5);
208       gtk_box_pack_start (GTK_BOX (hbox), gtk_label_new (description),
209 			  FALSE, FALSE, 5);
210       gtk_widget_show_all (hbox);
211    }
212 
213    for (ptr = entry; *ptr; ptr++)
214    {
215       if (text && WMIsPLArray (text))
216       {
217 	 char *label = D_(WMGetFromPLString (WMGetFromPLArray (text, ptr - entry)));
218 	 menu_item = gtk_menu_item_new_with_label (label);
219       }
220       else
221 	 menu_item = gtk_menu_item_new_with_label (*ptr);
222       if (callback)
223 	 gtk_signal_connect (GTK_OBJECT (menu_item), "activate",
224 			     GTK_SIGNAL_FUNC (callback), callback_data);
225       gtk_object_set_user_data (GTK_OBJECT (menu_item), (gpointer) *ptr);
226       gtk_menu_append (GTK_MENU (menu), menu_item);
227       gtk_widget_show (menu_item);
228    }
229    gtk_option_menu_set_menu (GTK_OPTION_MENU (option_menu), menu);
230    set_option_menu_default (GTK_OPTION_MENU (option_menu), entry, current);
231 
232    gtk_widget_show (option_menu);
233    if (info)
234       gtk_tooltips_set_tip (tooltips, option_menu, info, NULL);
235 
236    if (description)
237    {
238       gtk_box_pack_start (GTK_BOX (hbox), option_menu, FALSE, FALSE, 5);
239       return hbox;
240    }
241    else
242       return option_menu;
243 }
244 
245 void
set_option_menu_default(GtkOptionMenu * menu,const char ** list,const char * value)246 set_option_menu_default (GtkOptionMenu *menu, const char **list,
247 			 const char *value)
248 {
249    const char **ptr;
250 
251    for (ptr = list; *ptr; ptr++)
252       if (strcaseeq (value, *ptr))
253       {
254 	 gtk_option_menu_set_history (GTK_OPTION_MENU (menu), ptr - list);
255 	 break;
256       }
257 }
258 
259 gint
progress_timer(gpointer data)260 progress_timer (gpointer data)
261 {
262   gfloat	new_val;
263   GtkAdjustment *adj;
264 
265   adj = GTK_PROGRESS (data)->adjustment;
266 
267   new_val = adj->value + 1;
268   if (new_val > adj->upper)
269     new_val = adj->lower;
270 
271   gtk_progress_set_value (GTK_PROGRESS (data), new_val);
272 
273   return TRUE;
274 }
275 
276 gint
delete_button(GtkWidget * widget,GdkEventAny * event,gpointer ptr)277 delete_button (GtkWidget *widget, GdkEventAny  *event, gpointer ptr)
278 {
279    gtk_signal_emit_by_name (GTK_OBJECT (ptr), "clicked");
280 
281    return TRUE;
282 }
283 
284