wmclockmon: import version 0.8.1
[dockapps.git] / wmclockmon / wmclockmon-cal / mainwindow.c
blobb815d85f7b5c0a1fab9a38319879fffe3b2008cf
1 /*
2 * Create the main window.
3 */
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <sys/types.h>
8 #include <sys/stat.h>
9 #include <dirent.h>
10 #include <gtk/gtk.h>
11 #include <string.h>
12 #include <unistd.h>
13 #include "../config.h"
14 #include "defines.h"
15 #include "mainwindow.h"
16 #include "main.h"
17 #include "tools.h"
20 #define UNIQUE 1
21 #define YEAR 2
22 #define MONTH 3
24 #define UNIQSTR "%04d-%02d-"
25 #define YEARSTR "XXXX-%02d-"
26 #define MONTSTR "XXXX-XX-"
29 /* Calendar part */
30 static GtkWidget *calendar;
31 static GtkWidget *closewindow;
33 /* Editor part */
34 static GtkWidget *text_buttons;
35 static GtkWidget *label_u;
36 static GtkWidget *label_y;
37 static GtkWidget *label_m;
38 static GtkWidget *button_u = NULL;
39 static GtkWidget *button_y = NULL;
40 static GtkWidget *button_m = NULL;
41 static GtkWidget *edit;
42 static GtkWidget *save;
43 static GtkWidget *delete;
44 static GtkWidget *cancel;
45 static int shown = 1;
46 static int dateb = 0;
47 static char daystr[MAXSTRLEN + 1];
50 static void show_editor() {
51 gtk_widget_hide(calendar);
52 gtk_widget_hide(closewindow);
53 gtk_widget_grab_default(GTK_WIDGET(cancel));
54 gtk_widget_draw_default(GTK_WIDGET(cancel));
55 gtk_widget_grab_focus(GTK_WIDGET(edit));
56 gtk_widget_show(text_buttons);
57 gtk_widget_show(edit);
58 gtk_widget_show(save);
59 gtk_widget_show(delete);
60 gtk_widget_show(cancel);
64 static void hide_editor() {
65 gtk_widget_hide(text_buttons);
66 gtk_widget_hide(edit);
67 gtk_widget_hide(save);
68 gtk_widget_hide(delete);
69 gtk_widget_hide(cancel);
70 gtk_widget_show(calendar);
71 gtk_widget_grab_default(GTK_WIDGET(closewindow));
72 gtk_widget_draw_default(GTK_WIDGET(closewindow));
73 gtk_widget_grab_focus(GTK_WIDGET(closewindow));
74 gtk_widget_show(closewindow);
78 static void toggle_displ(GtkWidget *widget, void *data) {
79 switch (shown) {
80 case 1:
81 show_editor();
82 shown = 2;
83 break;
84 case 2:
85 hide_editor();
86 shown = 1;
87 break;
92 static void load_file(const char *datestr) {
93 FILE *file;
94 char *filename = get_file(datestr);
96 if ((file = fopen(filename, "r")) != NULL) {
97 while (! feof(file)) {
98 char line[MAXSTRLEN + 1];
99 bzero(line, MAXSTRLEN + 1);
100 fgets(line, MAXSTRLEN, file);
101 if (line[0] != 0)
102 gtk_text_insert(GTK_TEXT(edit), NULL, NULL, NULL, line, -1);
104 fclose(file);
106 FREE(filename);
110 static void toggle_button(GtkWidget *button) {
111 int is_active = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button));
113 if (is_active)
114 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), FALSE);
115 else
116 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
120 static void toggle_buttons(int button) {
121 switch (button) {
122 case UNIQUE: toggle_button(button_u); break;
123 case YEAR: toggle_button(button_y); break;
124 case MONTH: toggle_button(button_m); break;
125 default: break;
130 static void to_button(int button) {
131 if (dateb == 0) dateb == button;
132 if (button != dateb) {
133 int b = dateb;
134 dateb = button;
135 toggle_buttons(b);
140 static void set_buttons_text() {
141 int year, month, day;
142 char datestr[MAXSTRLEN + 1];
144 bzero(datestr, MAXSTRLEN + 1);
145 gtk_calendar_get_date(GTK_CALENDAR(calendar), &year, &month, &day);
146 month++;
147 snprintf(datestr, MAXSTRLEN, UNIQSTR"%02d", year, month, day);
148 gtk_label_set_text(GTK_LABEL(label_u), datestr);
149 snprintf(datestr, MAXSTRLEN, YEARSTR"%02d", month, day);
150 gtk_label_set_text(GTK_LABEL(label_y), datestr);
151 snprintf(datestr, MAXSTRLEN, MONTSTR"%02d", day);
152 gtk_label_set_text(GTK_LABEL(label_m), datestr);
156 static void editor_flush() {
157 int cont = TRUE;
159 while (cont) {
160 cont = gtk_text_backward_delete(GTK_TEXT(edit), 1);
162 cont = TRUE;
163 while (cont) {
164 cont = gtk_text_forward_delete(GTK_TEXT(edit), 1);
169 static void editor_fill(int which) {
170 char *filename, *dstr;
171 GtkWidget *label;
173 switch (which) {
174 case UNIQUE: label = label_u; break;
175 case YEAR: label = label_y; break;
176 case MONTH: label = label_m; break;
177 default: break;
179 gtk_label_get(GTK_LABEL(label), &dstr);
180 strcpy(daystr, dstr);
181 to_button(which);
182 gtk_text_freeze(GTK_TEXT(edit));
183 editor_flush();
184 load_file(daystr);
185 gtk_text_set_point(GTK_TEXT(edit), gtk_text_get_length(GTK_TEXT(edit)));
186 gtk_text_thaw(GTK_TEXT(edit));
190 static void check_button(int bnum, GtkWidget *button) {
191 int is_active = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button));
193 if (!(button_u && button_y && button_m)) return;
194 if (!is_active && (dateb == bnum))
195 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
196 if (is_active && (dateb != bnum)) editor_fill(bnum);
200 static void cal_click() {
201 set_buttons_text();
202 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button_u), TRUE);
203 editor_fill(UNIQUE);
207 static void set_text_u() {
208 check_button(UNIQUE, button_u);
212 static void set_text_y() {
213 check_button(YEAR, button_y);
217 static void set_text_m() {
218 check_button(MONTH, button_m);
222 static void save_datas() {
223 char *filename = get_file(daystr);
224 int len = strlen(robust_home()) + strlen(DEFAULT_CONFIGDIR);
225 char *dirname = xmalloc(len + 2);
226 struct stat stat_buf;
228 sprintf(dirname, "%s/%s", robust_home(), DEFAULT_CONFIGDIR);
229 if (gtk_text_get_length(GTK_TEXT(edit)) > 0) {
230 if (! ((stat(dirname, &stat_buf) == 0) && S_ISDIR(stat_buf.st_mode)))
231 mkdir(dirname, 0755);
233 if ((stat(dirname, &stat_buf) == 0) && S_ISDIR(stat_buf.st_mode)) {
234 FILE *file = fopen(filename, "w");
235 int year, month, day;
237 if (file) {
238 int i;
239 for (i = 0 ; i < gtk_text_get_length(GTK_TEXT(edit)) ; i++) {
240 char t = GTK_TEXT_INDEX(GTK_TEXT(edit), i);
241 fprintf(file, "%c", t);
243 fflush(file);
244 fclose(file);
246 gtk_calendar_get_date(GTK_CALENDAR(calendar), &year, &month, &day);
247 gtk_calendar_mark_day(GTK_CALENDAR(calendar), day);
250 FREE(filename);
254 static void delete_file() {
255 char *filename = get_file(daystr);
256 int year, month, day;
258 unlink(filename);
259 gtk_calendar_get_date(GTK_CALENDAR(calendar), &year, &month, &day);
260 gtk_calendar_unmark_day(GTK_CALENDAR(calendar), day);
261 FREE(filename);
262 gtk_text_freeze(GTK_TEXT(edit));
263 editor_flush();
264 gtk_text_thaw(GTK_TEXT(edit));
268 static int check_day(const char *filename, const char *startstr) {
269 int day = -1;
271 if (strncmp(filename, startstr, strlen(startstr)) == 0) {
272 char format[12];
273 sprintf(format, "%s%%d", startstr);
274 sscanf(filename, format, &day);
277 return day;
281 static void mark_days() {
282 char *Home = robust_home();
283 DIR *dir;
284 struct dirent *dir_ent;
285 char *dirname = xmalloc(
286 strlen(Home) +
287 strlen(DEFAULT_CONFIGDIR) +
290 gtk_calendar_clear_marks(GTK_CALENDAR(calendar));
291 sprintf(dirname, "%s/%s", Home, DEFAULT_CONFIGDIR);
292 if ((dir = opendir(dirname)) != NULL) {
293 char startstr_u[9]; /* unique (full date) */
294 char startstr_y[9]; /* yearly date */
295 char startstr_m[9]; /* monthly date */
296 int year, month, day;
298 gtk_calendar_get_date(GTK_CALENDAR(calendar), &year, &month, &day);
299 month++;
300 sprintf(startstr_u, UNIQSTR, year, month);
301 sprintf(startstr_y, YEARSTR, month);
302 sprintf(startstr_m, MONTSTR);
303 while ((dir_ent = readdir(dir)) != NULL) {
304 int day_u = check_day(dir_ent->d_name, startstr_u);
305 int day_y = check_day(dir_ent->d_name, startstr_y);
306 int day_m = check_day(dir_ent->d_name, startstr_m);
307 if (day_u != -1)
308 gtk_calendar_mark_day(GTK_CALENDAR(calendar), day_u);
309 if (day_y != -1)
310 gtk_calendar_mark_day(GTK_CALENDAR(calendar), day_y);
311 if (day_m != -1)
312 gtk_calendar_mark_day(GTK_CALENDAR(calendar), day_m);
314 closedir(dir);
316 FREE(dirname);
320 void create_mainwindow() {
321 GtkWidget *main_vbox;
322 GtkWidget *buttons_hbox;
324 /*** FENÊTRE PRINCIPALE ***/
325 application = gtk_window_new(GTK_WINDOW_TOPLEVEL);
326 gtk_window_set_title(GTK_WINDOW(application), PACKAGE" Calendar");
327 /*-- Connexion aux signaux --*/
328 gtk_signal_connect(GTK_OBJECT(application), "delete_event",
329 GTK_SIGNAL_FUNC(quit_app), NULL);
330 gtk_signal_connect(GTK_OBJECT(application), "destroy",
331 GTK_SIGNAL_FUNC(quit_app), "WM destroy");
332 /*-- Taille de la fenêtre --*/
333 gtk_widget_set_usize(GTK_WIDGET(application), WIN_WIDTH, WIN_HEIGHT);
334 gtk_widget_realize(application);
336 /*** Zone principale de placement des widgets***/
337 main_vbox = gtk_vbox_new(FALSE, 1);
338 gtk_container_border_width(GTK_CONTAINER(main_vbox), 1);
339 gtk_container_add(GTK_CONTAINER(application), main_vbox);
340 gtk_widget_show(main_vbox);
342 calendar = gtk_calendar_new();
343 gtk_calendar_display_options(GTK_CALENDAR(calendar),
344 GTK_CALENDAR_SHOW_HEADING |
345 GTK_CALENDAR_SHOW_DAY_NAMES |
346 GTK_CALENDAR_WEEK_START_MONDAY);
347 gtk_calendar_select_month(GTK_CALENDAR(calendar),
348 timeinfos->tm_mon, timeinfos->tm_year + 1900);
349 gtk_calendar_select_day(GTK_CALENDAR(calendar), timeinfos->tm_mday);
350 mark_days();
351 gtk_box_pack_start(GTK_BOX(main_vbox), calendar, TRUE, TRUE, 1);
352 gtk_signal_connect(GTK_OBJECT(calendar), "day-selected-double-click",
353 GTK_SIGNAL_FUNC(cal_click), NULL);
354 gtk_signal_connect(GTK_OBJECT(calendar), "day-selected-double-click",
355 GTK_SIGNAL_FUNC(toggle_displ), NULL);
356 gtk_signal_connect(GTK_OBJECT(calendar), "month-changed",
357 GTK_SIGNAL_FUNC(mark_days), NULL);
358 gtk_widget_show(calendar);
360 edit = gtk_text_new(NULL, NULL);
361 gtk_text_set_editable(GTK_TEXT(edit), TRUE);
362 gtk_text_set_word_wrap(GTK_TEXT(edit), TRUE);
363 gtk_text_set_line_wrap(GTK_TEXT(edit), TRUE);
364 gtk_box_pack_start(GTK_BOX(main_vbox), edit, TRUE, TRUE, 1);
367 /*** BOUTONS DE CHANGEMENT DE TEXTE ***/
368 text_buttons = gtk_hbox_new(FALSE, 1);
369 gtk_box_pack_start(GTK_BOX(main_vbox), text_buttons, FALSE, TRUE, 1);
372 button_u = gtk_toggle_button_new();
373 gtk_signal_connect(GTK_OBJECT(button_u), "clicked",
374 GTK_SIGNAL_FUNC(set_text_u), NULL);
375 gtk_box_pack_start(GTK_BOX(text_buttons), button_u, TRUE, TRUE, 0);
376 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button_u), TRUE);
377 gtk_widget_show(button_u);
378 label_u = gtk_label_new(" Unique ");
379 gtk_widget_show(label_u);
380 gtk_container_add(GTK_CONTAINER(button_u), label_u);
383 button_y = gtk_toggle_button_new();
384 gtk_signal_connect(GTK_OBJECT(button_y), "clicked",
385 GTK_SIGNAL_FUNC(set_text_y), NULL);
386 gtk_box_pack_start(GTK_BOX(text_buttons), button_y, TRUE, TRUE, 0);
387 gtk_widget_show(button_y);
388 label_y = gtk_label_new(" Yearly ");
389 gtk_widget_show(label_y);
390 gtk_container_add(GTK_CONTAINER(button_y), label_y);
393 button_m = gtk_toggle_button_new();
394 gtk_signal_connect(GTK_OBJECT(button_m), "clicked",
395 GTK_SIGNAL_FUNC(set_text_m), NULL);
396 gtk_box_pack_start(GTK_BOX(text_buttons), button_m, TRUE, TRUE, 0);
397 gtk_widget_show(button_m);
398 label_m = gtk_label_new(" Monthly ");
399 gtk_widget_show(label_m);
400 gtk_container_add(GTK_CONTAINER(button_m), label_m);
404 /*** BOUTONS DE SAUVEGARDE ET ANNULATION ***/
405 buttons_hbox = gtk_hbox_new(FALSE, 1);
406 gtk_box_pack_start(GTK_BOX(main_vbox), buttons_hbox, FALSE, TRUE, 1);
407 gtk_widget_show(buttons_hbox);
410 closewindow = gtk_button_new_with_label(" Close ");
411 gtk_signal_connect(GTK_OBJECT(closewindow), "clicked",
412 GTK_SIGNAL_FUNC(quit_app), NULL);
413 gtk_box_pack_start(GTK_BOX(buttons_hbox), closewindow, TRUE, TRUE, 0);
414 GTK_WIDGET_SET_FLAGS(GTK_WIDGET(closewindow), GTK_CAN_DEFAULT);
415 gtk_widget_grab_default(GTK_WIDGET(closewindow));
416 gtk_widget_draw_default(GTK_WIDGET(closewindow));
417 gtk_widget_show(closewindow);
420 save = gtk_button_new_with_label(" Save ");
421 gtk_signal_connect(GTK_OBJECT(save), "clicked",
422 GTK_SIGNAL_FUNC(save_datas), NULL);
423 gtk_box_pack_start(GTK_BOX(buttons_hbox), save, TRUE, TRUE, 0);
424 GTK_WIDGET_SET_FLAGS(GTK_WIDGET(save), GTK_CAN_DEFAULT);
427 delete = gtk_button_new_with_label(" Delete ");
428 gtk_signal_connect(GTK_OBJECT(delete), "clicked",
429 GTK_SIGNAL_FUNC(delete_file), NULL);
430 gtk_box_pack_start(GTK_BOX(buttons_hbox), delete, TRUE, TRUE, 0);
431 GTK_WIDGET_SET_FLAGS(GTK_WIDGET(delete), GTK_CAN_DEFAULT);
434 cancel = gtk_button_new_with_label(" Close ");
435 gtk_signal_connect(GTK_OBJECT(cancel), "clicked",
436 GTK_SIGNAL_FUNC(toggle_displ), NULL);
437 gtk_box_pack_start(GTK_BOX(buttons_hbox), cancel, TRUE, TRUE, 0);
438 GTK_WIDGET_SET_FLAGS(GTK_WIDGET(cancel), GTK_CAN_DEFAULT);
441 /*** AFFICHAGE DE LA FENÊTRE ***/
442 gtk_widget_show(application);