Add lots more aoview UI bits
[fw/altos] / aoview / aoview_log.c
1 /*
2  * Copyright © 2009 Keith Packard <keithp@keithp.com>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; version 2 of the License.
7  *
8  * This program is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11  * General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License along
14  * with this program; if not, write to the Free Software Foundation, Inc.,
15  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
16  */
17
18 #include "aoview.h"
19
20 #define LOG_DIR_PATH    "/apps/aoview/log_dir"
21 #define DEFAULT_LOG     "AltOS"
22
23 static char *aoview_log_dir;
24 static FILE *aoview_log_file;
25 static int aoview_log_serial;
26 static int aoview_log_sequence;
27 static GtkMessageDialog *log_fail_dialog;
28 static int aoview_log_failed;
29
30 static void
31 aoview_log_save_conf(void)
32 {
33         GConfClient     *gconf_client;
34
35         gconf_client = gconf_client_get_default();
36         if (gconf_client)
37         {
38                 gconf_client_set_string(gconf_client,
39                                         LOG_DIR_PATH,
40                                         aoview_log_dir,
41                                         NULL);
42                 g_object_unref(G_OBJECT(gconf_client));
43         }
44 }
45
46 static void
47 aoview_log_configure(GtkWidget *widget, gpointer data)
48 {
49         GtkFileChooser *chooser = data;
50         aoview_log_dir = gtk_file_chooser_get_filename(chooser);
51         aoview_log_save_conf();
52         gtk_widget_hide(GTK_WIDGET(chooser));
53 }
54
55 static void
56 aoview_log_new(void)
57 {
58         if (aoview_log_file) {
59                 fclose(aoview_log_file);
60                 aoview_log_file = NULL;
61         }
62         aoview_log_failed = 0;
63 }
64
65 static void
66 aoview_log_new_item(GtkWidget *widget, gpointer data)
67 {
68         aoview_log_new();
69 }
70
71 void
72 aoview_log_set_serial(int serial)
73 {
74         aoview_log_serial = serial;
75 }
76
77 int
78 aoview_log_get_serial(void)
79 {
80         return aoview_log_serial;
81 }
82
83 static void
84 aoview_log_open_failed(char *name)
85 {
86         char    *utf8_file;
87         utf8_file = g_filename_to_utf8(name, -1, NULL, NULL, NULL);
88         if (!utf8_file)
89                 utf8_file = name;
90         gtk_message_dialog_format_secondary_text(log_fail_dialog,
91                                                  "\"%s\"", utf8_file);
92         if (utf8_file != name)
93                 g_free(utf8_file);
94         gtk_widget_show(GTK_WIDGET(log_fail_dialog));
95         aoview_log_failed = 1;
96 }
97
98 static void
99 aoview_log_start(void)
100 {
101         if (!aoview_log_file) {
102                 char            base[50];
103                 struct tm       tm;
104                 time_t          now;
105                 char            *full;
106                 int             r;
107
108                 now = time(NULL);
109                 (void) localtime_r(&now, &tm);
110                 aoview_mkdir(aoview_log_dir);
111                 for (;;) {
112                         sprintf(base, "%04d-%02d-%02d-serial-%03d-flight-%03d.log",
113                                 tm.tm_year + 1900,
114                                 tm.tm_mon + 1,
115                                 tm.tm_mday,
116                                 aoview_log_serial,
117                                 aoview_log_sequence);
118                         full = aoview_fullname(aoview_log_dir, base);
119                         r = access(full, F_OK);
120                         if (r < 0) {
121                                 aoview_log_file = fopen(full, "w");
122                                 if (!aoview_log_file)
123                                         aoview_log_open_failed(full);
124                                 else
125                                         setlinebuf(aoview_log_file);
126                                 free(full);
127                                 break;
128                         }
129                         free (full);
130                         aoview_log_sequence++;
131                 }
132         }
133 }
134
135 void
136 aoview_log_printf(char *format, ...)
137 {
138         va_list ap;
139
140         if (aoview_log_failed)
141                 return;
142         aoview_log_start();
143         va_start(ap, format);
144         vfprintf(aoview_log_file, format, ap);
145         va_end(ap);
146 }
147
148 void
149 aoview_log_init(GladeXML *xml)
150 {
151         GConfClient     *gconf_client;
152         char            *log_dir = NULL;
153         GtkFileChooser  *log_chooser_dialog;
154         GtkWidget       *log_configure_ok;
155         GtkWidget       *log_new;
156
157         g_type_init();
158         gconf_client = gconf_client_get_default();
159         if (gconf_client)
160         {
161                 log_dir = gconf_client_get_string(gconf_client,
162                                                   LOG_DIR_PATH,
163                                                   NULL);
164                 g_object_unref(G_OBJECT(gconf_client));
165         }
166         if (!log_dir) {
167                 aoview_log_dir = aoview_fullname(getenv("HOME"), DEFAULT_LOG);
168                 aoview_log_save_conf();
169         } else {
170                 aoview_log_dir = strdup(log_dir);
171         }
172
173         log_chooser_dialog = GTK_FILE_CHOOSER(glade_xml_get_widget(xml, "log_chooser_dialog"));
174         assert(log_chooser_dialog);
175         gtk_file_chooser_set_filename(log_chooser_dialog, aoview_log_dir);
176
177         log_configure_ok = glade_xml_get_widget(xml, "log_configure_ok");
178         assert(log_configure_ok);
179
180         g_signal_connect(G_OBJECT(log_configure_ok), "clicked",
181                          G_CALLBACK(aoview_log_configure),
182                          log_chooser_dialog);
183
184         log_new = glade_xml_get_widget(xml, "ao_log_new");
185         assert(log_new);
186         g_signal_connect(G_OBJECT(log_new), "activate",
187                          G_CALLBACK(aoview_log_new_item),
188                          NULL);
189
190         log_fail_dialog = GTK_MESSAGE_DIALOG(glade_xml_get_widget(xml, "log_fail_dialog"));
191         assert(log_fail_dialog);
192 }