Merged 0.7.99 irssi.
[crypto.git] / apps / irssi / src / fe-text / statusbar-config.c
1 /*
2  statusbar-config.c : irssi
3
4     Copyright (C) 2001 Timo Sirainen
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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 */
20
21 #include "module.h"
22 #include "signals.h"
23 #include "settings.h"
24 #include "lib-config/iconfig.h"
25
26 #include "statusbar.h"
27
28 static void read_statusbar_config_from_node(CONFIG_NODE *node);
29
30 static STATUSBAR_CONFIG_REC *
31 statusbar_config_create(STATUSBAR_GROUP_REC *group, const char *name)
32 {
33         STATUSBAR_CONFIG_REC *bar;
34
35         g_return_val_if_fail(group != NULL, NULL);
36         g_return_val_if_fail(name != NULL, NULL);
37
38         bar = g_new0(STATUSBAR_CONFIG_REC, 1);
39         group->config_bars = g_slist_append(group->config_bars, bar);
40
41         bar->name = g_strdup(name);
42         return bar;
43 }
44
45 static SBAR_ITEM_CONFIG_REC *
46 statusbar_item_config_create(STATUSBAR_CONFIG_REC *bar, const char *name,
47                              int priority, int right_alignment)
48 {
49         SBAR_ITEM_CONFIG_REC *rec;
50
51         g_return_val_if_fail(bar != NULL, NULL);
52         g_return_val_if_fail(name != NULL, NULL);
53
54         rec = g_new0(SBAR_ITEM_CONFIG_REC, 1);
55         bar->items = g_slist_append(bar->items, rec);
56
57         rec->name = g_strdup(name);
58         rec->priority = priority;
59         rec->right_alignment = right_alignment;
60
61         return rec;
62 }
63
64 static void statusbar_config_item_destroy(STATUSBAR_CONFIG_REC *barconfig,
65                                           SBAR_ITEM_CONFIG_REC *itemconfig)
66 {
67         barconfig->items = g_slist_remove(barconfig->items, itemconfig);
68
69         g_free(itemconfig->name);
70         g_free(itemconfig);
71 }
72
73 void statusbar_config_destroy(STATUSBAR_GROUP_REC *group,
74                               STATUSBAR_CONFIG_REC *config)
75 {
76         group->config_bars = g_slist_remove(group->config_bars, config);
77
78         while (config->items != NULL)
79                 statusbar_config_item_destroy(config, config->items->data);
80
81         g_free(config->name);
82         g_free(config);
83 }
84
85 static STATUSBAR_CONFIG_REC *
86 statusbar_config_find(STATUSBAR_GROUP_REC *group, const char *name)
87 {
88         GSList *tmp;
89
90         for (tmp = group->config_bars; tmp != NULL; tmp = tmp->next) {
91                 STATUSBAR_CONFIG_REC *config = tmp->data;
92
93                 if (strcmp(config->name, name) == 0)
94                         return config;
95         }
96
97         return NULL;
98 }
99
100 static void statusbar_reset_defaults(void)
101 {
102         CONFIG_REC *config;
103         CONFIG_NODE *node;
104
105         while (statusbar_groups != NULL)
106                 statusbar_group_destroy(statusbar_groups->data);
107         active_statusbar_group = NULL;
108
109         /* read the default statusbar settings from internal config */
110         config = config_open(NULL, -1);
111         config_parse_data(config, default_config, "internal");
112         node = config_node_traverse(config, "statusbar", FALSE);
113         if (node != NULL)
114                 read_statusbar_config_from_node(node);
115         config_close(config);
116 }
117
118 static void statusbar_read_items(CONFIG_NODE *items)
119 {
120         GSList *tmp;
121
122         tmp = config_node_first(items->value);
123         for (; tmp != NULL; tmp = config_node_next(tmp)) {
124                 CONFIG_NODE *node = tmp->data;
125
126                 statusbar_item_register(node->key, node->value, NULL);
127         }
128 }
129
130 static void statusbar_read_item(STATUSBAR_CONFIG_REC *bar, CONFIG_NODE *node)
131 {
132         int priority, right_alignment;
133
134         priority = config_node_get_int(node, "priority", 0);
135         right_alignment = strcmp(config_node_get_str(node, "alignment", ""), "right") == 0;
136         statusbar_item_config_create(bar, node->key,
137                                      priority, right_alignment);
138 }
139
140 static void statusbar_read(STATUSBAR_GROUP_REC *group, CONFIG_NODE *node)
141 {
142         STATUSBAR_CONFIG_REC *bar;
143         GSList *tmp;
144         int visible;
145         const char *visible_str;
146
147         bar = statusbar_config_find(group, node->key);
148         visible = bar == NULL ? STATUSBAR_VISIBLE_ALWAYS : bar->visible;
149
150         /* first make sure we want to see this statusbar */
151         visible_str = config_node_get_str(node, "visible", "");
152         if (strcmp(visible_str, "active") == 0)
153                 visible = STATUSBAR_VISIBLE_ACTIVE;
154         else if (strcmp(visible_str, "inactive") == 0)
155                 visible = STATUSBAR_VISIBLE_INACTIVE;
156         else if (strcmp(visible_str, "never") == 0) {
157                 /* we don't want this statusbar -
158                    destroy it if it already exists */
159                 if (bar != NULL)
160                         statusbar_config_destroy(group, bar);
161                 return;
162         }
163
164         if (bar == NULL) {
165                 bar = statusbar_config_create(group, node->key);
166                 bar->type = STATUSBAR_TYPE_ROOT;
167                 bar->placement = STATUSBAR_BOTTOM;
168                 bar->position = 0;
169         }
170         bar->visible = visible;
171
172         if (strcmp(config_node_get_str(node, "type", ""), "window") == 0)
173                 bar->type = STATUSBAR_TYPE_WINDOW;
174         if (strcmp(config_node_get_str(node, "placement", ""), "top") == 0)
175                 bar->placement = STATUSBAR_TOP;
176         bar->position = config_node_get_int(node, "position", 0);
177
178         node = config_node_section(node, "items", -1);
179         if (node != NULL) {
180                 /* we're overriding the items - destroy the old */
181                 while (bar->items != NULL)
182                         statusbar_config_item_destroy(bar, bar->items->data);
183
184                 tmp = config_node_first(node->value);
185                 for (; tmp != NULL; tmp = config_node_next(tmp))
186                         statusbar_read_item(bar, tmp->data);
187         }
188 }
189
190 static void statusbar_read_group(CONFIG_NODE *node)
191 {
192         STATUSBAR_GROUP_REC *group;
193         GSList *tmp;
194
195         group = statusbar_group_find(node->key);
196         if (group == NULL) {
197                 group = statusbar_group_create(node->key);
198                 if (active_statusbar_group == NULL)
199                         active_statusbar_group = group;
200         }
201
202         tmp = config_node_first(node->value);
203         for (; tmp != NULL; tmp = config_node_next(tmp))
204                 statusbar_read(group, tmp->data);
205 }
206
207 static void create_root_statusbars(void)
208 {
209         STATUSBAR_REC *bar;
210         GSList *tmp;
211
212         tmp = active_statusbar_group->config_bars;
213         for (; tmp != NULL; tmp = tmp->next) {
214                 STATUSBAR_CONFIG_REC *rec = tmp->data;
215
216                 if (rec->type == STATUSBAR_TYPE_ROOT) {
217                         bar = statusbar_create(active_statusbar_group, rec, NULL);
218                         statusbar_redraw(bar, TRUE);
219                 }
220         }
221 }
222
223 static void read_statusbar_config_from_node(CONFIG_NODE *node)
224 {
225         CONFIG_NODE *items;
226         GSList *tmp;
227
228         items = config_node_section(node, "items", -1);
229         if (items != NULL)
230                 statusbar_read_items(items);
231
232         tmp = config_node_first(node->value);
233         for (; tmp != NULL; tmp = config_node_next(tmp)) {
234                 if (tmp->data != items)
235                         statusbar_read_group(tmp->data);
236         }
237 }
238
239 static void read_statusbar_config(void)
240 {
241         CONFIG_NODE *node;
242
243         statusbar_reset_defaults();
244
245         node = iconfig_node_traverse("statusbar", FALSE);
246         if (node != NULL)
247                 read_statusbar_config_from_node(node);
248
249         create_root_statusbars();
250 }
251
252 void statusbar_config_init(void)
253 {
254         read_statusbar_config();
255         signal_add("setup reread", (SIGNAL_FUNC) read_statusbar_config);
256 }
257
258 void statusbar_config_deinit(void)
259 {
260         signal_remove("setup reread", (SIGNAL_FUNC) read_statusbar_config);
261 }