imported irssi.
[silc.git] / apps / irssi / src / fe-text / mainwindows-save.c
1 /*
2  mainwindows-save.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 "misc.h"
24 #include "lib-config/iconfig.h"
25 #include "settings.h"
26
27 #include "mainwindows.h"
28 #include "gui-windows.h"
29
30 static void main_window_save(MAIN_WINDOW_REC *window, CONFIG_NODE *node)
31 {
32         GSList *tmp;
33         GString *str;
34         char num[MAX_INT_STRLEN];
35
36         ltoa(num, window->active->refnum);
37         node = config_node_section(node, num, NODE_TYPE_BLOCK);
38
39         iconfig_node_set_int(node, "first_line", window->first_line);
40         iconfig_node_set_int(node, "lines", window->height);
41
42         str = g_string_new(NULL);
43         for (tmp = window->sticky_windows; tmp != NULL; tmp = tmp->next) {
44                 WINDOW_REC *rec = tmp->data;
45                 g_string_sprintfa(str, "%d ", rec->refnum);
46         }
47         if (str->len > 1) {
48                 g_string_truncate(str, str->len-1);
49                 iconfig_node_set_str(node, "sticky", str->str);
50         }
51         g_string_free(str, TRUE);
52 }
53
54 static void sig_windows_saved(void)
55 {
56         CONFIG_NODE *node;
57
58         iconfig_set_str(NULL, "mainwindows", NULL);
59         node = iconfig_node_traverse("mainwindows", TRUE);
60
61         g_slist_foreach(mainwindows, (GFunc) main_window_save, node);
62 }
63
64 static int window_node_cmp(CONFIG_NODE *n1, CONFIG_NODE *n2)
65 {
66         return config_node_get_int(n1, "first_line", 0) <
67                 config_node_get_int(n2, "first_line", 0) ? -1 : 1;
68 }
69
70 static GSList *read_sorted_windows(CONFIG_NODE *node)
71 {
72         GSList *tmp, *output;
73
74         output = NULL;
75         for (tmp = node->value; tmp != NULL; tmp = tmp->next) {
76                 output = g_slist_insert_sorted(output, tmp->data,
77                                                (GCompareFunc) window_node_cmp);
78         }
79
80         return output;
81 }
82
83 static void restore_sticky_windows(CONFIG_NODE *node,
84                                    MAIN_WINDOW_REC *mainwindow)
85 {
86         WINDOW_REC *window;
87         char **sticky_list, **sticky;
88
89         sticky_list = g_strsplit(config_node_get_str(node, "sticky", ""), " ", -1);
90         for (sticky = sticky_list; *sticky != NULL; sticky++) {
91                 window = window_find_refnum(atoi(*sticky));
92                 if (window != NULL) {
93                         mainwindow->sticky_windows =
94                                 g_slist_append(mainwindow->sticky_windows,
95                                                window);
96                 }
97         }
98         g_strfreev(sticky_list);
99 }
100
101 static WINDOW_REC *window_find_hidden(void)
102 {
103         GSList *tmp;
104
105         for (tmp = windows; tmp != NULL; tmp = tmp->next) {
106                 WINDOW_REC *rec = tmp->data;
107
108                 if (!is_window_visible(rec))
109                         return rec;
110         }
111
112         return NULL;
113 }
114
115 static void sig_windows_restored(void)
116 {
117         MAIN_WINDOW_REC *mainwindow, *lowerwin;
118         WINDOW_REC *window;
119         CONFIG_NODE *node;
120         GSList *tmp, *tmp2, *sorted_windows, *sorted_config;
121         int count, newsize;
122
123         node = iconfig_node_traverse("mainwindows", FALSE);
124         if (node == NULL) return;
125
126         /* create all windows, shrink the lower windows to minimum size */
127         lowerwin = mainwindows->data;
128         count = g_slist_length(node->value);
129         while (count > 1) {
130                 window = window_find_hidden();
131                 if (window == NULL)
132                         break;
133
134                 mainwindow = mainwindow_create();
135                 if (mainwindow == NULL)
136                         break;
137
138                 mainwindow->active = window;
139                 WINDOW_GUI(window)->parent = mainwindow;
140
141                 active_mainwin = NULL;
142                 window_set_active(window);
143
144                 if (lowerwin->height > WINDOW_MIN_SIZE)
145                         mainwindow_set_size(lowerwin, WINDOW_MIN_SIZE);
146                 count--;
147
148                 lowerwin = mainwindow;
149         }
150
151         sorted_config = read_sorted_windows(node);
152         sorted_windows = mainwindows_get_sorted(FALSE);
153         for (tmp = sorted_windows, tmp2 = sorted_config;
154              tmp != NULL && tmp2 != NULL;
155              tmp = tmp->next, tmp2 = tmp2->next) {
156                 MAIN_WINDOW_REC *mainwindow = tmp->data;
157                 CONFIG_NODE *node = tmp2->data;
158
159                 window = window_find_refnum(atoi(node->key));
160                 if (window == NULL) {
161                         mainwindow_destroy(mainwindow);
162                         continue;
163                 }
164
165                 if (is_window_visible(window)) {
166                         active_mainwin = WINDOW_GUI(window)->parent;
167                         window_set_active(window_find_hidden());
168                 }
169
170                 active_mainwin = mainwindow;
171                 window_set_active(window);
172
173                 restore_sticky_windows(node, mainwindow);
174
175                 newsize = config_node_get_int(node, "lines", 0);
176                 if (newsize > 0)
177                         mainwindow_set_size(mainwindow, newsize);
178         }
179         g_slist_free(sorted_windows);
180         g_slist_free(sorted_config);
181
182         irssi_redraw();
183 }
184
185 void mainwindows_save_init(void)
186 {
187         signal_add("windows saved", (SIGNAL_FUNC) sig_windows_saved);
188         signal_add("windows restored", (SIGNAL_FUNC) sig_windows_restored);
189 }
190
191 void mainwindows_save_deinit(void)
192 {
193         signal_remove("windows saved", (SIGNAL_FUNC) sig_windows_saved);
194         signal_remove("windows restored", (SIGNAL_FUNC) sig_windows_restored);
195 }