1 /*
2  * GTimer
3  *
4  * Copyright:
5  *	(C) 1999 Craig Knudsen, cknudsen@cknudsen.com
6  *	See accompanying file "COPYING".
7  *
8  *	This program is free software; you can redistribute it and/or
9  *	modify it under the terms of the GNU General Public License
10  *	as published by the Free Software Foundation; either version 2
11  *	of the License, or (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
20  *	Free Software Foundation, Inc., 59 Temple Place,
21  *	Suite 330, Boston, MA  02111-1307, USA
22  *
23  * Description:
24  *	Helps you keep track of time spent on different tasks.
25  *
26  * Author:
27  *	Craig Knudsen, cknudsen@cknudsen.com, http://www.cknudsen.com
28  *
29  * Home Page:
30  *	http://www.cknudsen.com/gtimer/
31  *
32  * History:
33  *	09-Mar-2000	Added optional third button for confirm windows.
34  *	07-Mar-2000	Added create_confirm_toplevel ()
35  *	25-Mar-1999	Added use of gtk_window_set_transient_for() for
36  *			GTK 1.1 or later.
37  *	18-Mar-1998	Added calls to gtk_window_set_wmclass so the windows
38  *			behave better for window managers.
39  *	16-Mar-1998	Changed application/about icon.
40  *	03-Mar-1998	Created
41  *
42  ****************************************************************************/
43 
44 
45 #include <stdio.h>
46 #include <stdlib.h>
47 #if HAVE_UNISTD_H
48 #include <unistd.h>
49 #endif
50 #include <time.h>
51 #include <memory.h>
52 #include <ctype.h>
53 
54 #include <gtk/gtk.h>
55 
56 #include "project.h"
57 #include "task.h"
58 #include "gtimer.h"
59 
60 #ifdef GTIMER_MEMDEBUG
61 #include "memdebug/memdebug.h"
62 #endif
63 
64 /* icons */
65 #include "icons/error.xpm"
66 #include "icons/confirm.xpm"
67 #include "icons/about.xpm"
68 
69 extern GtkWidget *main_window;
70 
71 static GdkPixmap *error_icon = NULL, *confirm_icon = NULL,
72   *gtimer_icon = NULL;
73 static GdkBitmap *error_mask, *confirm_mask, *gtimer_mask;
74 
75 typedef struct {
76   char *callback_data;
77   GtkWidget *window;
78   void (*ok_callback)();
79   void (*cancel_callback)();
80   void (*third_callback)();
81 } ConfirmData;
82 
83 
confirm_ok_callback(widget,data)84 static void confirm_ok_callback ( widget, data )
85 GtkWidget *widget;
86 gpointer data;
87 {
88   ConfirmData *cd = (ConfirmData *) data;
89 
90   gtk_grab_remove ( cd->window );
91   if ( cd->ok_callback )
92     cd->ok_callback ( widget, (gpointer)cd->callback_data );
93   gtk_widget_destroy ( cd->window );
94   free ( cd );
95 }
96 
97 
confirm_cancel_callback(widget,data)98 static void confirm_cancel_callback ( widget, data )
99 GtkWidget *widget;
100 gpointer data;
101 {
102   ConfirmData *cd = (ConfirmData *) data;
103 
104   gtk_grab_remove ( cd->window );
105   if ( cd->cancel_callback )
106     cd->cancel_callback ( widget, (gpointer)cd->callback_data );
107   gtk_widget_destroy ( cd->window );
108   free ( cd );
109 }
110 
111 
confirm_third_callback(widget,data)112 static void confirm_third_callback ( widget, data )
113 GtkWidget *widget;
114 gpointer data;
115 {
116   ConfirmData *cd = (ConfirmData *) data;
117 
118   gtk_grab_remove ( cd->window );
119   if ( cd->third_callback )
120     cd->third_callback ( widget, (gpointer)cd->callback_data );
121   gtk_widget_destroy ( cd->window );
122   free ( cd );
123 }
124 
125 
126 
127 
128 
129 
130 
131 /*
132 ** Create the confirm window.
133 */
create_window(type,is_modal,title,text,ok_text,cancel_text,third_text,ok_callback,cancel_callback,third_callback,callback_data)134 static GtkWidget *create_window ( type, is_modal, title, text,
135   ok_text, cancel_text, third_text,
136   ok_callback, cancel_callback, third_callback,
137   callback_data )
138 enum_confirm_type type;
139 int is_modal;
140 char *title;
141 char *text;
142 char *ok_text, *cancel_text, *third_text;
143 void (*ok_callback)();
144 void (*cancel_callback)();
145 void (*third_callback)();
146 char *callback_data;
147 {
148   GtkWidget *window;
149   /*GtkWidget *vbox, *hbox, *table;*/
150   GtkWidget *table;
151   GtkWidget *pixmap, *label, *ok_button, *cancel_button, *third_button;
152   ConfirmData *cd;
153   GdkPixmap *icon = NULL, *mask = NULL;
154   char *title2;
155 
156   cd = (ConfirmData *) malloc ( sizeof ( ConfirmData ) );
157   cd->callback_data = callback_data;
158   cd->ok_callback = ok_callback;
159   cd->cancel_callback = cancel_callback;
160   cd->third_callback = third_callback;
161   cd->window = window = gtk_dialog_new ();
162   gtk_window_set_wmclass ( GTK_WINDOW ( cd->window ), "GTimer", "gtimer" );
163   title2 = (char *) malloc ( strlen ( title ) + 10 );
164   sprintf ( title2, "GTimer: %s", title );
165   gtk_window_set_title (GTK_WINDOW (window), title2 );
166   free ( title2 );
167   gtk_window_position ( GTK_WINDOW(window), GTK_WIN_POS_MOUSE );
168   gtk_grab_add ( window );
169   gtk_widget_realize ( window );
170 
171 #if OLD_GTK
172 #else
173   if ( is_modal )
174     gtk_window_set_transient_for ( GTK_WINDOW ( window ),
175       GTK_WINDOW ( main_window ) );
176 #endif
177 
178   table = gtk_table_new (1, 2, FALSE);
179   gtk_table_set_row_spacings (GTK_TABLE (table), 4);
180   gtk_table_set_col_spacings (GTK_TABLE (table), 8);
181   gtk_container_border_width (GTK_CONTAINER (table), 6);
182   gtk_box_pack_start ( GTK_BOX ( GTK_DIALOG (window)->vbox ),
183     table, TRUE, TRUE, 5 );
184 
185   /* Add pixmap */
186   switch ( type ) {
187     case CONFIRM_ABOUT:
188       if ( gtimer_icon == NULL )
189         gtimer_icon = gdk_pixmap_create_from_xpm_d (
190           GTK_WIDGET ( window )->window, &gtimer_mask,
191           &window->style->white, about_xpm );
192       icon = gtimer_icon;
193       mask = gtimer_mask;
194       break;
195     case CONFIRM_ERROR:
196     case CONFIRM_WARNING:
197       if ( error_icon == NULL )
198         error_icon = gdk_pixmap_create_from_xpm_d (
199           GTK_WIDGET ( window )->window, &error_mask,
200           &window->style->white, error_xpm );
201       icon = error_icon;
202       mask = error_mask;
203       break;
204     case CONFIRM_CONFIRM:
205       if ( confirm_icon == NULL )
206         confirm_icon = gdk_pixmap_create_from_xpm_d (
207           GTK_WIDGET ( window )->window, &confirm_mask,
208           &window->style->white, confirm_xpm );
209       icon = confirm_icon;
210       mask = confirm_mask;
211       break;
212     case CONFIRM_MESSAGE:
213       break;
214   }
215   if ( icon ) {
216     pixmap = gtk_pixmap_new ( icon, mask );
217     gtk_misc_set_alignment (GTK_MISC (pixmap), 0.0, 0.5);
218     gtk_table_attach (GTK_TABLE (table), pixmap, 0, 1, 0, 1,
219       GTK_FILL, GTK_FILL, 0, 0);
220     gtk_widget_show ( pixmap );
221   }
222 
223   /* Add message */
224   label = gtk_label_new ( text );
225   gtk_table_attach_defaults (GTK_TABLE (table), label, 1, 2, 0, 1);
226   gtk_widget_show ( label );
227 
228   gtk_widget_show ( table );
229 
230   /* add command buttons */
231 
232   if ( ok_text ) {
233     ok_button = gtk_button_new_with_label ( ok_text );
234     gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area),
235       ok_button, FALSE, FALSE, 10);
236     gtk_signal_connect (GTK_OBJECT (ok_button), "clicked",
237       GTK_SIGNAL_FUNC (confirm_ok_callback), cd);
238     GTK_WIDGET_SET_FLAGS ( ok_button, GTK_CAN_DEFAULT );
239     gtk_widget_grab_default ( ok_button );
240     gtk_widget_show (ok_button);
241   }
242 
243   if ( cancel_text ) {
244     cancel_button = gtk_button_new_with_label ( cancel_text );
245     gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area),
246       cancel_button, FALSE, FALSE, 10);
247     gtk_signal_connect (GTK_OBJECT (cancel_button), "clicked",
248       GTK_SIGNAL_FUNC (confirm_cancel_callback), cd);
249     if ( ! ok_text ) {
250       GTK_WIDGET_SET_FLAGS ( cancel_button, GTK_CAN_DEFAULT );
251       gtk_widget_grab_default ( cancel_button );
252     }
253     gtk_widget_show (cancel_button);
254   }
255 
256   if ( third_text ) {
257     third_button = gtk_button_new_with_label ( third_text );
258     gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area),
259       third_button, FALSE, FALSE, 10);
260     if ( confirm_third_callback != NULL )
261       gtk_signal_connect (GTK_OBJECT (third_button), "clicked",
262         GTK_SIGNAL_FUNC (confirm_third_callback), cd);
263     gtk_widget_show (third_button);
264   }
265 
266   gtk_widget_show (window);
267 
268   return ( window );
269 }
270 
271 
272 
273 
274 /*
275 ** Create a toplevel confirm window.
276 */
create_confirm_toplevel(type,title,text,ok_text,cancel_text,third_text,ok_callback,cancel_callback,third_callback,callback_data)277 GtkWidget *create_confirm_toplevel ( type, title, text,
278   ok_text, cancel_text, third_text,
279   ok_callback, cancel_callback, third_callback,
280   callback_data )
281 enum_confirm_type type;
282 char *title;
283 char *text;
284 char *ok_text, *cancel_text, *third_text;
285 void (*ok_callback)();
286 void (*cancel_callback)();
287 void (*third_callback)();
288 char *callback_data;
289 {
290   return create_window ( type, FALSE, title, text, ok_text,
291     cancel_text, third_text, ok_callback, cancel_callback, third_callback,
292     callback_data );
293 }
294 
295 /*
296 ** Create a modal confirm window.
297 */
create_confirm_window(type,title,text,ok_text,cancel_text,third_text,ok_callback,cancel_callback,third_callback,callback_data)298 GtkWidget *create_confirm_window ( type, title, text,
299   ok_text, cancel_text, third_text,
300   ok_callback, cancel_callback, third_callback,
301   callback_data )
302 enum_confirm_type type;
303 char *title;
304 char *text;
305 char *ok_text, *cancel_text, *third_text;
306 void (*ok_callback)();
307 void (*cancel_callback)();
308 void (*third_callback)();
309 char *callback_data;
310 {
311   return create_window ( type, TRUE, title, text,
312     ok_text, cancel_text, third_text,
313     ok_callback, cancel_callback, third_callback, callback_data );
314 }
315 
316