* Wed Jan 28 2009 Levente Farkas <lfarkas@lfarkas.org> - 0.9.8j-1
[fedora-mingw.git] / gtk2 / test3.c
1 /* Calendar tutorial from
2  * http://library.gnome.org/devel/gtk-tutorial/stable/x1102.html
3  */
4
5 /*
6  * Copyright (C) 1998 Cesar Miquel, Shawn T. Amundson, Mattias Gr�nlund
7  * Copyright (C) 2000 Tony Gale
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program 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
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22  */
23
24 #include <stdio.h>
25 #include <string.h>
26 #include <gtk/gtk.h>
27
28 #define DEF_PAD 10
29 #define DEF_PAD_SMALL 5
30
31 #define TM_YEAR_BASE 1900
32
33 typedef struct _CalendarData {
34   GtkWidget *flag_checkboxes[5];
35   gboolean  settings[5];
36   GtkWidget *font_dialog;
37   GtkWidget *window;
38   GtkWidget *prev2_sig;
39   GtkWidget *prev_sig;
40   GtkWidget *last_sig;
41   GtkWidget *month;
42 } CalendarData;
43
44 enum {
45   calendar_show_header,
46   calendar_show_days,
47   calendar_month_change, 
48   calendar_show_week,
49   calendar_monday_first
50 };
51
52 /*
53  * GtkCalendar
54  */
55
56 static void calendar_date_to_string( CalendarData *data,
57                                      char         *buffer,
58                                      gint          buff_len )
59 {
60   GDate date;
61   guint year, month, day;
62
63   gtk_calendar_get_date (GTK_CALENDAR (data->window),
64                          &year, &month, &day);
65   g_date_set_dmy (&date, day, month + 1, year);
66   g_date_strftime (buffer, buff_len - 1, "%x", &date);
67
68 }
69
70 static void calendar_set_signal_strings( char         *sig_str,
71                                          CalendarData *data )
72 {
73   const gchar *prev_sig;
74
75   prev_sig = gtk_label_get_text (GTK_LABEL (data->prev_sig));
76   gtk_label_set_text (GTK_LABEL (data->prev2_sig), prev_sig);
77
78   prev_sig = gtk_label_get_text (GTK_LABEL (data->last_sig));
79   gtk_label_set_text (GTK_LABEL (data->prev_sig), prev_sig);
80   gtk_label_set_text (GTK_LABEL (data->last_sig), sig_str);
81 }
82
83 static void calendar_month_changed( GtkWidget    *widget,
84                                     CalendarData *data )
85 {
86   char buffer[256] = "month_changed: ";
87
88   calendar_date_to_string (data, buffer + 15, 256 - 15);
89   calendar_set_signal_strings (buffer, data);
90 }
91
92 static void calendar_day_selected( GtkWidget    *widget,
93                                    CalendarData *data )
94 {
95   char buffer[256] = "day_selected: ";
96
97   calendar_date_to_string (data, buffer + 14, 256 - 14);
98   calendar_set_signal_strings (buffer, data);
99 }
100
101 static void calendar_day_selected_double_click ( GtkWidget    *widget,
102                                                  CalendarData *data )
103 {
104   char buffer[256] = "day_selected_double_click: ";
105   guint day;
106
107   calendar_date_to_string (data, buffer + 27, 256 - 27);
108   calendar_set_signal_strings (buffer, data);
109
110   gtk_calendar_get_date (GTK_CALENDAR (data->window),
111                          NULL, NULL, &day);
112
113   if (GTK_CALENDAR (data->window)->marked_date[day-1] == 0) {
114     gtk_calendar_mark_day (GTK_CALENDAR (data->window), day);
115   } else { 
116     gtk_calendar_unmark_day (GTK_CALENDAR (data->window), day);
117   }
118 }
119
120 static void calendar_prev_month( GtkWidget    *widget,
121                                  CalendarData *data )
122 {
123   char buffer[256] = "prev_month: ";
124
125   calendar_date_to_string (data, buffer + 12, 256 - 12);
126   calendar_set_signal_strings (buffer, data);
127 }
128
129 static void calendar_next_month( GtkWidget    *widget,
130                                  CalendarData *data )
131 {
132   char buffer[256] = "next_month: ";
133
134   calendar_date_to_string (data, buffer + 12, 256 - 12);
135   calendar_set_signal_strings (buffer, data);
136 }
137
138 static void calendar_prev_year( GtkWidget    *widget,
139                                 CalendarData *data )
140 {
141   char buffer[256] = "prev_year: ";
142
143   calendar_date_to_string (data, buffer + 11, 256 - 11);
144   calendar_set_signal_strings (buffer, data);
145 }
146
147 static void calendar_next_year( GtkWidget    *widget,
148                                 CalendarData *data )
149 {
150   char buffer[256] = "next_year: ";
151
152   calendar_date_to_string (data, buffer + 11, 256 - 11);
153   calendar_set_signal_strings (buffer, data);
154 }
155
156
157 static void calendar_set_flags( CalendarData *calendar )
158 {
159   gint i;
160   gint options = 0;
161   for (i = 0;i < 5; i++) 
162     if (calendar->settings[i])
163       {
164         options = options + (1 << i);
165       }
166   if (calendar->window)
167     gtk_calendar_display_options (GTK_CALENDAR (calendar->window), options);
168 }
169
170 static void calendar_toggle_flag( GtkWidget    *toggle,
171                                   CalendarData *calendar)
172 {
173   gint i;
174   gint j;
175   j = 0;
176   for (i = 0; i < 5; i++)
177     if (calendar->flag_checkboxes[i] == toggle)
178       j = i;
179
180   calendar->settings[j] = !calendar->settings[j];
181   calendar_set_flags (calendar);
182   
183 }
184
185 static void calendar_font_selection_ok( GtkWidget    *button,
186                                         CalendarData *calendar )
187 {
188   GtkRcStyle *style;
189   char *font_name;
190
191   if (calendar->window)
192     {
193       font_name = gtk_font_selection_dialog_get_font_name (GTK_FONT_SELECTION_DIALOG (calendar->font_dialog));
194       if (font_name) 
195         {
196           style = gtk_rc_style_new ();
197           pango_font_description_free (style->font_desc);
198           style->font_desc = pango_font_description_from_string (font_name);
199           gtk_widget_modify_style (calendar->window, style);
200           g_free (font_name);
201         }
202     }
203
204   gtk_widget_destroy (calendar->font_dialog);
205 }
206
207 static void calendar_select_font( GtkWidget    *button,
208                                   CalendarData *calendar )
209 {
210   GtkWidget *window;
211
212   if (!calendar->font_dialog) {
213     window = gtk_font_selection_dialog_new ("Font Selection Dialog");
214     g_return_if_fail (GTK_IS_FONT_SELECTION_DIALOG (window));
215     calendar->font_dialog = window;
216     
217     gtk_window_set_position (GTK_WINDOW (window), GTK_WIN_POS_MOUSE);
218     
219     g_signal_connect (window, "destroy",
220                       G_CALLBACK (gtk_widget_destroyed),
221                       &calendar->font_dialog);
222     
223     g_signal_connect (GTK_FONT_SELECTION_DIALOG (window)->ok_button,
224                       "clicked", G_CALLBACK (calendar_font_selection_ok),
225                       calendar);
226     g_signal_connect_swapped (GTK_FONT_SELECTION_DIALOG (window)->cancel_button,
227                              "clicked", G_CALLBACK (gtk_widget_destroy), 
228                              calendar->font_dialog);
229   }
230   window = calendar->font_dialog;
231   if (!GTK_WIDGET_VISIBLE (window))
232     gtk_widget_show (window);
233   else
234     gtk_widget_destroy (window);
235
236 }
237
238 static void create_calendar( void )
239 {
240   GtkWidget *window;
241   GtkWidget *vbox, *vbox2, *vbox3;
242   GtkWidget *hbox;
243   GtkWidget *hbbox;
244   GtkWidget *calendar;
245   GtkWidget *toggle;
246   GtkWidget *button;
247   GtkWidget *frame;
248   GtkWidget *separator;
249   GtkWidget *label;
250   GtkWidget *bbox;
251   static CalendarData calendar_data;
252   gint i;
253   
254   struct {
255     char *label;
256   } flags[] =
257     {
258       { "Show Heading" },
259       { "Show Day Names" },
260       { "No Month Change" },
261       { "Show Week Numbers" },
262       { "Week Start Monday" }
263     };
264
265   
266   calendar_data.window = NULL;
267   calendar_data.font_dialog = NULL;
268
269   for (i = 0; i < 5; i++) {
270     calendar_data.settings[i] = 0;
271   }
272
273   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
274   gtk_window_set_title (GTK_WINDOW (window), "GtkCalendar Example");
275   gtk_container_set_border_width (GTK_CONTAINER (window), 5);
276   g_signal_connect (window, "destroy",
277                     G_CALLBACK (gtk_main_quit),
278                     NULL);
279   g_signal_connect (window, "delete-event",
280                     G_CALLBACK (gtk_false),
281                     NULL);
282   gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
283
284   vbox = gtk_vbox_new (FALSE, DEF_PAD);
285   gtk_container_add (GTK_CONTAINER (window), vbox);
286
287   /*
288    * The top part of the window, Calendar, flags and fontsel.
289    */
290
291   hbox = gtk_hbox_new (FALSE, DEF_PAD);
292   gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, DEF_PAD);
293   hbbox = gtk_hbutton_box_new ();
294   gtk_box_pack_start (GTK_BOX (hbox), hbbox, FALSE, FALSE, DEF_PAD);
295   gtk_button_box_set_layout (GTK_BUTTON_BOX (hbbox), GTK_BUTTONBOX_SPREAD);
296   gtk_box_set_spacing (GTK_BOX (hbbox), 5);
297
298   /* Calendar widget */
299   frame = gtk_frame_new ("Calendar");
300   gtk_box_pack_start(GTK_BOX (hbbox), frame, FALSE, TRUE, DEF_PAD);
301   calendar=gtk_calendar_new ();
302   calendar_data.window = calendar;
303   calendar_set_flags (&calendar_data);
304   gtk_calendar_mark_day (GTK_CALENDAR (calendar), 19);  
305   gtk_container_add (GTK_CONTAINER (frame), calendar);
306   g_signal_connect (calendar, "month_changed", 
307                     G_CALLBACK (calendar_month_changed),
308                     &calendar_data);
309   g_signal_connect (calendar, "day_selected", 
310                     G_CALLBACK (calendar_day_selected),
311                     &calendar_data);
312   g_signal_connect (calendar, "day_selected_double_click", 
313                     G_CALLBACK (calendar_day_selected_double_click),
314                     &calendar_data);
315   g_signal_connect (calendar, "prev_month", 
316                     G_CALLBACK (calendar_prev_month),
317                     &calendar_data);
318   g_signal_connect (calendar, "next_month", 
319                     G_CALLBACK (calendar_next_month),
320                     &calendar_data);
321   g_signal_connect (calendar, "prev_year", 
322                     G_CALLBACK (calendar_prev_year),
323                     &calendar_data);
324   g_signal_connect (calendar, "next_year", 
325                     G_CALLBACK (calendar_next_year),
326                     &calendar_data);
327
328
329   separator = gtk_vseparator_new ();
330   gtk_box_pack_start (GTK_BOX (hbox), separator, FALSE, TRUE, 0);
331
332   vbox2 = gtk_vbox_new (FALSE, DEF_PAD);
333   gtk_box_pack_start (GTK_BOX (hbox), vbox2, FALSE, FALSE, DEF_PAD);
334   
335   /* Build the Right frame with the flags in */ 
336
337   frame = gtk_frame_new ("Flags");
338   gtk_box_pack_start (GTK_BOX (vbox2), frame, TRUE, TRUE, DEF_PAD);
339   vbox3 = gtk_vbox_new (TRUE, DEF_PAD_SMALL);
340   gtk_container_add (GTK_CONTAINER (frame), vbox3);
341
342   for (i = 0; i < 5; i++)
343     {
344       toggle = gtk_check_button_new_with_label (flags[i].label);
345       g_signal_connect (toggle,
346                         "toggled",
347                         G_CALLBACK (calendar_toggle_flag),
348                         &calendar_data);
349       gtk_box_pack_start (GTK_BOX (vbox3), toggle, TRUE, TRUE, 0);
350       calendar_data.flag_checkboxes[i] = toggle;
351     }
352   /* Build the right font-button */ 
353   button = gtk_button_new_with_label ("Font...");
354   g_signal_connect (button,
355                     "clicked",
356                     G_CALLBACK (calendar_select_font),
357                     &calendar_data);
358   gtk_box_pack_start (GTK_BOX (vbox2), button, FALSE, FALSE, 0);
359
360   /*
361    *  Build the Signal-event part.
362    */
363
364   frame = gtk_frame_new ("Signal events");
365   gtk_box_pack_start (GTK_BOX (vbox), frame, TRUE, TRUE, DEF_PAD);
366
367   vbox2 = gtk_vbox_new (TRUE, DEF_PAD_SMALL);
368   gtk_container_add (GTK_CONTAINER (frame), vbox2);
369   
370   hbox = gtk_hbox_new (FALSE, 3);
371   gtk_box_pack_start (GTK_BOX (vbox2), hbox, FALSE, TRUE, 0);
372   label = gtk_label_new ("Signal:");
373   gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
374   calendar_data.last_sig = gtk_label_new ("");
375   gtk_box_pack_start (GTK_BOX (hbox), calendar_data.last_sig, FALSE, TRUE, 0);
376
377   hbox = gtk_hbox_new (FALSE, 3);
378   gtk_box_pack_start (GTK_BOX (vbox2), hbox, FALSE, TRUE, 0);
379   label = gtk_label_new ("Previous signal:");
380   gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
381   calendar_data.prev_sig = gtk_label_new ("");
382   gtk_box_pack_start (GTK_BOX (hbox), calendar_data.prev_sig, FALSE, TRUE, 0);
383
384   hbox = gtk_hbox_new (FALSE, 3);
385   gtk_box_pack_start (GTK_BOX (vbox2), hbox, FALSE, TRUE, 0);
386   label = gtk_label_new ("Second previous signal:");
387   gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
388   calendar_data.prev2_sig = gtk_label_new ("");
389   gtk_box_pack_start (GTK_BOX (hbox), calendar_data.prev2_sig, FALSE, TRUE, 0);
390
391   bbox = gtk_hbutton_box_new ();
392   gtk_box_pack_start (GTK_BOX (vbox), bbox, FALSE, FALSE, 0);
393   gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_END);
394
395   button = gtk_button_new_with_label ("Close");
396   g_signal_connect (button, "clicked", 
397                     G_CALLBACK (gtk_main_quit), 
398                     NULL);
399   gtk_container_add (GTK_CONTAINER (bbox), button);
400   GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
401   gtk_widget_grab_default (button);
402
403   gtk_widget_show_all (window);
404 }
405
406
407 int main (int   argc,
408           char *argv[])
409 {
410   gtk_init (&argc, &argv);
411
412   create_calendar ();
413
414   gtk_main ();
415
416   return 0;
417 }