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