wmclockmon: fix assignment
[dockapps.git] / wmclockmon / wmclockmon-cal / mainwindow.c
blob2246daa3530603bce4f94f2ce291e08cdc80be5e
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 GtkWidget *application;
31 /* Calendar part */
32 static GtkWidget *calendar;
33 static GtkWidget *closewindow;
35 /* Editor part */
36 static GtkWidget *text_buttons;
37 static GtkWidget *label_u;
38 static GtkWidget *label_y;
39 static GtkWidget *label_m;
40 static GtkWidget *button_u = NULL;
41 static GtkWidget *button_y = NULL;
42 static GtkWidget *button_m = NULL;
43 static GtkWidget *edit;
44 static GtkWidget *save;
45 static GtkWidget *delete;
46 static GtkWidget *cancel;
47 static int shown = 1;
48 static int dateb = 0;
49 static char daystr[MAXSTRLEN + 1];
52 static void show_editor() {
53 gtk_widget_hide(calendar);
54 gtk_widget_hide(closewindow);
55 gtk_widget_grab_default(GTK_WIDGET(cancel));
56 gtk_widget_grab_focus(GTK_WIDGET(edit));
57 gtk_widget_show(text_buttons);
58 gtk_widget_show(edit);
59 gtk_widget_show(save);
60 gtk_widget_show(delete);
61 gtk_widget_show(cancel);
65 static void hide_editor() {
66 gtk_widget_hide(text_buttons);
67 gtk_widget_hide(edit);
68 gtk_widget_hide(save);
69 gtk_widget_hide(delete);
70 gtk_widget_hide(cancel);
71 gtk_widget_show(calendar);
72 gtk_widget_grab_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 GtkTextIter iter;
97 GtkTextBuffer *buf;
99 buf = GTK_TEXT_BUFFER(gtk_text_view_get_buffer(GTK_TEXT_VIEW(edit)));
100 gtk_text_buffer_get_end_iter(GTK_TEXT_BUFFER(gtk_text_view_get_buffer(GTK_TEXT_VIEW(edit))), &iter);
101 gtk_text_buffer_place_cursor(GTK_TEXT_BUFFER(gtk_text_view_get_buffer(GTK_TEXT_VIEW(edit))), &iter);
103 if ((file = fopen(filename, "r")) != NULL) {
104 while (! feof(file)) {
105 char line[MAXSTRLEN + 1];
106 bzero(line, MAXSTRLEN + 1);
107 fgets(line, MAXSTRLEN, file);
108 if (line[0] != 0)
109 gtk_text_buffer_insert(buf, &iter, line, -1);
111 fclose(file);
113 FREE(filename);
117 static void toggle_button(GtkWidget *button) {
118 int is_active = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button));
120 if (is_active)
121 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), FALSE);
122 else
123 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
127 static void toggle_buttons(int button) {
128 switch (button) {
129 case UNIQUE: toggle_button(button_u); break;
130 case YEAR: toggle_button(button_y); break;
131 case MONTH: toggle_button(button_m); break;
132 default: break;
137 static void to_button(int button) {
138 if (dateb == 0)
139 dateb = button;
140 if (button != dateb) {
141 int b = dateb;
142 dateb = button;
143 toggle_buttons(b);
148 static void set_buttons_text() {
149 int year, month, day;
150 char datestr[MAXSTRLEN + 1];
152 bzero(datestr, MAXSTRLEN + 1);
153 gtk_calendar_get_date(GTK_CALENDAR(calendar), &year, &month, &day);
154 month++;
155 snprintf(datestr, MAXSTRLEN, UNIQSTR"%02d", year, month, day);
156 gtk_label_set_text(GTK_LABEL(label_u), datestr);
157 snprintf(datestr, MAXSTRLEN, YEARSTR"%02d", month, day);
158 gtk_label_set_text(GTK_LABEL(label_y), datestr);
159 snprintf(datestr, MAXSTRLEN, MONTSTR"%02d", day);
160 gtk_label_set_text(GTK_LABEL(label_m), datestr);
164 static void editor_flush() {
165 gtk_text_buffer_set_text(GTK_TEXT_BUFFER(gtk_text_view_get_buffer(GTK_TEXT_VIEW(edit))), "", 0);
169 static void editor_fill(int which) {
170 char *filename, *dstr;
171 GtkWidget *label;
172 GtkTextIter iter;
174 switch (which) {
175 case UNIQUE: label = label_u; break;
176 case YEAR: label = label_y; break;
177 case MONTH: label = label_m; break;
179 gtk_label_get(GTK_LABEL(label), &dstr);
180 strcpy(daystr, dstr);
181 to_button(which);
182 editor_flush();
183 load_file(daystr);
184 gtk_text_buffer_get_end_iter(GTK_TEXT_BUFFER(gtk_text_view_get_buffer(GTK_TEXT_VIEW(edit))), &iter);
185 gtk_text_buffer_place_cursor(GTK_TEXT_BUFFER(gtk_text_view_get_buffer(GTK_TEXT_VIEW(edit))), &iter);
189 static void check_button(int bnum, GtkWidget *button) {
190 int is_active = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button));
192 if (!(button_u && button_y && button_m)) return;
193 if (!is_active && (dateb == bnum))
194 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
195 if (is_active && (dateb != bnum)) editor_fill(bnum);
199 static void cal_click() {
200 set_buttons_text();
201 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button_u), TRUE);
202 editor_fill(UNIQUE);
206 static void set_text_u() {
207 check_button(UNIQUE, button_u);
211 static void set_text_y() {
212 check_button(YEAR, button_y);
216 static void set_text_m() {
217 check_button(MONTH, button_m);
221 static void save_datas() {
222 char *filename = get_file(daystr);
223 int len = strlen(robust_home()) + strlen(DEFAULT_CONFIGDIR);
224 char *dirname = xmalloc(len + 2);
225 struct stat stat_buf;
227 GtkTextIter ts, te;
228 gchar *tbuf;
229 int tlen;
231 tlen = gtk_text_buffer_get_char_count(GTK_TEXT_BUFFER(gtk_text_view_get_buffer(GTK_TEXT_VIEW(edit))));
232 gtk_text_buffer_get_bounds(GTK_TEXT_BUFFER(gtk_text_view_get_buffer(GTK_TEXT_VIEW(edit))), &ts, &te);
234 sprintf(dirname, "%s/%s", robust_home(), DEFAULT_CONFIGDIR);
235 if (tlen > 0) {
236 if (! ((stat(dirname, &stat_buf) == 0) && S_ISDIR(stat_buf.st_mode)))
237 mkdir(dirname, 0755);
239 if ((stat(dirname, &stat_buf) == 0) && S_ISDIR(stat_buf.st_mode)) {
240 FILE *file = fopen(filename, "w");
241 int year, month, day;
243 if (file) {
244 tbuf = gtk_text_buffer_get_text(GTK_TEXT_BUFFER(gtk_text_view_get_buffer(GTK_TEXT_VIEW(edit))), &ts, &te, TRUE);
245 fprintf(file, "%s", tbuf);
246 g_free(tbuf);
247 fflush(file);
248 fclose(file);
250 gtk_calendar_get_date(GTK_CALENDAR(calendar), &year, &month, &day);
251 gtk_calendar_mark_day(GTK_CALENDAR(calendar), day);
254 FREE(filename);
258 static void delete_file() {
259 char *filename = get_file(daystr);
260 int year, month, day;
262 unlink(filename);
263 gtk_calendar_get_date(GTK_CALENDAR(calendar), &year, &month, &day);
264 gtk_calendar_unmark_day(GTK_CALENDAR(calendar), day);
265 FREE(filename);
266 editor_flush();
270 static int check_day(const char *filename, const char *startstr) {
271 int day = -1;
273 if (strncmp(filename, startstr, strlen(startstr)) == 0) {
274 char format[12];
275 sprintf(format, "%s%%d", startstr);
276 sscanf(filename, format, &day);
279 return day;
283 static void mark_days() {
284 char *Home = robust_home();
285 DIR *dir;
286 struct dirent *dir_ent;
287 char *dirname = xmalloc(
288 strlen(Home) +
289 strlen(DEFAULT_CONFIGDIR) +
292 gtk_calendar_clear_marks(GTK_CALENDAR(calendar));
293 sprintf(dirname, "%s/%s", Home, DEFAULT_CONFIGDIR);
294 if ((dir = opendir(dirname)) != NULL) {
295 char startstr_u[9]; /* unique (full date) */
296 char startstr_y[9]; /* yearly date */
297 char startstr_m[9]; /* monthly date */
298 int year, month, day;
300 gtk_calendar_get_date(GTK_CALENDAR(calendar), &year, &month, &day);
301 month++;
302 sprintf(startstr_u, UNIQSTR, year, month);
303 sprintf(startstr_y, YEARSTR, month);
304 sprintf(startstr_m, MONTSTR);
305 while ((dir_ent = readdir(dir)) != NULL) {
306 int day_u = check_day(dir_ent->d_name, startstr_u);
307 int day_y = check_day(dir_ent->d_name, startstr_y);
308 int day_m = check_day(dir_ent->d_name, startstr_m);
309 if (day_u != -1)
310 gtk_calendar_mark_day(GTK_CALENDAR(calendar), day_u);
311 if (day_y != -1)
312 gtk_calendar_mark_day(GTK_CALENDAR(calendar), day_y);
313 if (day_m != -1)
314 gtk_calendar_mark_day(GTK_CALENDAR(calendar), day_m);
316 closedir(dir);
318 FREE(dirname);
322 void create_mainwindow() {
323 GtkWidget *main_vbox;
324 GtkWidget *buttons_hbox;
326 /*** FENÊTRE PRINCIPALE ***/
327 application = gtk_window_new(GTK_WINDOW_TOPLEVEL);
328 gtk_window_set_title(GTK_WINDOW(application), PACKAGE" Calendar");
329 /*-- Connexion aux signaux --*/
330 gtk_signal_connect(GTK_OBJECT(application), "delete_event",
331 GTK_SIGNAL_FUNC(quit_app), NULL);
332 gtk_signal_connect(GTK_OBJECT(application), "destroy",
333 GTK_SIGNAL_FUNC(quit_app), "WM destroy");
334 /*-- Taille de la fenêtre --*/
335 gtk_widget_set_usize(GTK_WIDGET(application), WIN_WIDTH, WIN_HEIGHT);
336 gtk_widget_realize(application);
338 /*** Zone principale de placement des widgets***/
339 main_vbox = gtk_vbox_new(FALSE, 1);
340 gtk_container_border_width(GTK_CONTAINER(main_vbox), 1);
341 gtk_container_add(GTK_CONTAINER(application), main_vbox);
342 gtk_widget_show(main_vbox);
344 calendar = gtk_calendar_new();
345 gtk_calendar_display_options(GTK_CALENDAR(calendar),
346 GTK_CALENDAR_SHOW_HEADING |
347 GTK_CALENDAR_SHOW_DAY_NAMES |
348 GTK_CALENDAR_WEEK_START_MONDAY);
349 gtk_calendar_select_month(GTK_CALENDAR(calendar),
350 timeinfos->tm_mon, timeinfos->tm_year + 1900);
351 gtk_calendar_select_day(GTK_CALENDAR(calendar), timeinfos->tm_mday);
352 mark_days();
353 gtk_box_pack_start(GTK_BOX(main_vbox), calendar, TRUE, TRUE, 1);
354 gtk_signal_connect(GTK_OBJECT(calendar), "day-selected-double-click",
355 GTK_SIGNAL_FUNC(cal_click), NULL);
356 gtk_signal_connect(GTK_OBJECT(calendar), "day-selected-double-click",
357 GTK_SIGNAL_FUNC(toggle_displ), NULL);
358 gtk_signal_connect(GTK_OBJECT(calendar), "month-changed",
359 GTK_SIGNAL_FUNC(mark_days), NULL);
360 gtk_widget_show(calendar);
362 edit = gtk_text_view_new();
363 gtk_text_view_set_editable(GTK_TEXT_VIEW(edit), TRUE);
364 gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(edit), GTK_WRAP_WORD_CHAR);
366 gtk_box_pack_start(GTK_BOX(main_vbox), edit, TRUE, TRUE, 1);
369 /*** BOUTONS DE CHANGEMENT DE TEXTE ***/
370 text_buttons = gtk_hbox_new(FALSE, 1);
371 gtk_box_pack_start(GTK_BOX(main_vbox), text_buttons, FALSE, TRUE, 1);
374 button_u = gtk_toggle_button_new();
375 gtk_signal_connect(GTK_OBJECT(button_u), "clicked",
376 GTK_SIGNAL_FUNC(set_text_u), NULL);
377 gtk_box_pack_start(GTK_BOX(text_buttons), button_u, TRUE, TRUE, 0);
378 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button_u), TRUE);
379 gtk_widget_show(button_u);
380 label_u = gtk_label_new(" Unique ");
381 gtk_widget_show(label_u);
382 gtk_container_add(GTK_CONTAINER(button_u), label_u);
385 button_y = gtk_toggle_button_new();
386 gtk_signal_connect(GTK_OBJECT(button_y), "clicked",
387 GTK_SIGNAL_FUNC(set_text_y), NULL);
388 gtk_box_pack_start(GTK_BOX(text_buttons), button_y, TRUE, TRUE, 0);
389 gtk_widget_show(button_y);
390 label_y = gtk_label_new(" Yearly ");
391 gtk_widget_show(label_y);
392 gtk_container_add(GTK_CONTAINER(button_y), label_y);
395 button_m = gtk_toggle_button_new();
396 gtk_signal_connect(GTK_OBJECT(button_m), "clicked",
397 GTK_SIGNAL_FUNC(set_text_m), NULL);
398 gtk_box_pack_start(GTK_BOX(text_buttons), button_m, TRUE, TRUE, 0);
399 gtk_widget_show(button_m);
400 label_m = gtk_label_new(" Monthly ");
401 gtk_widget_show(label_m);
402 gtk_container_add(GTK_CONTAINER(button_m), label_m);
406 /*** BOUTONS DE SAUVEGARDE ET ANNULATION ***/
407 buttons_hbox = gtk_hbox_new(FALSE, 1);
408 gtk_box_pack_start(GTK_BOX(main_vbox), buttons_hbox, FALSE, TRUE, 1);
409 gtk_widget_show(buttons_hbox);
412 closewindow = gtk_button_new_with_label(" Close ");
413 gtk_signal_connect(GTK_OBJECT(closewindow), "clicked",
414 GTK_SIGNAL_FUNC(quit_app), NULL);
415 gtk_box_pack_start(GTK_BOX(buttons_hbox), closewindow, TRUE, TRUE, 0);
416 GTK_WIDGET_SET_FLAGS(GTK_WIDGET(closewindow), GTK_CAN_DEFAULT);
417 gtk_widget_grab_default(GTK_WIDGET(closewindow));
418 gtk_widget_show(closewindow);
421 save = gtk_button_new_with_label(" Save ");
422 gtk_signal_connect(GTK_OBJECT(save), "clicked",
423 GTK_SIGNAL_FUNC(save_datas), NULL);
424 gtk_box_pack_start(GTK_BOX(buttons_hbox), save, TRUE, TRUE, 0);
425 GTK_WIDGET_SET_FLAGS(GTK_WIDGET(save), GTK_CAN_DEFAULT);
428 delete = gtk_button_new_with_label(" Delete ");
429 gtk_signal_connect(GTK_OBJECT(delete), "clicked",
430 GTK_SIGNAL_FUNC(delete_file), NULL);
431 gtk_box_pack_start(GTK_BOX(buttons_hbox), delete, TRUE, TRUE, 0);
432 GTK_WIDGET_SET_FLAGS(GTK_WIDGET(delete), GTK_CAN_DEFAULT);
435 cancel = gtk_button_new_with_label(" Close ");
436 gtk_signal_connect(GTK_OBJECT(cancel), "clicked",
437 GTK_SIGNAL_FUNC(toggle_displ), NULL);
438 gtk_box_pack_start(GTK_BOX(buttons_hbox), cancel, TRUE, TRUE, 0);
439 GTK_WIDGET_SET_FLAGS(GTK_WIDGET(cancel), GTK_CAN_DEFAULT);
442 /*** AFFICHAGE DE LA FENÊTRE ***/
443 gtk_widget_show(application);