4 Copyright (C) 1999-2001 Timo Sirainen
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.
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.
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
25 #include "special-vars.h"
28 #include "gui-entry.h"
29 #include "gui-windows.h"
30 #include "gui-printtext.h"
32 static int window_create_override;
34 static char *prompt, *prompt_window;
36 static GUI_WINDOW_REC *gui_window_init(WINDOW_REC *window,
37 MAIN_WINDOW_REC *parent)
41 window->width = parent->width;
42 window->height = parent->height;
44 gui = g_new0(GUI_WINDOW_REC, 1);
46 gui->view = textbuffer_view_create(textbuffer_create(),
47 window->width, window->height,
48 settings_get_int("indent"),
49 settings_get_bool("indent_always"));
53 static void gui_window_deinit(GUI_WINDOW_REC *gui)
55 textbuffer_view_destroy(gui->view);
59 static void sig_window_create_override(gpointer tab)
61 window_create_override = GPOINTER_TO_INT(tab);
64 static void gui_window_created(WINDOW_REC *window)
66 MAIN_WINDOW_REC *parent;
68 g_return_if_fail(window != NULL);
70 parent = window_create_override != 0 &&
71 active_win != NULL && WINDOW_GUI(active_win) != NULL ?
72 WINDOW_GUI(active_win)->parent : mainwindow_create();
74 /* not enough space for new window, but we really can't
75 abort creation of the window anymore, so create hidden
77 parent = WINDOW_GUI(active_win)->parent;
79 window_create_override = -1;
81 if (settings_get_bool("autostick_split_windows") &&
82 (parent->sticky_windows != NULL ||
83 (mainwindows->next != NULL && parent->active == NULL))) {
84 /* set the window sticky */
85 parent->sticky_windows =
86 g_slist_append(parent->sticky_windows, window);
89 if (parent->active == NULL) parent->active = window;
90 window->gui_data = gui_window_init(window, parent);
91 signal_emit("gui window created", 1, window);
94 static void gui_window_destroyed(WINDOW_REC *window)
96 MAIN_WINDOW_REC *parent;
99 g_return_if_fail(window != NULL);
101 gui = WINDOW_GUI(window);
102 parent = gui->parent;
104 signal_emit("gui window destroyed", 1, window);
106 gui_window_deinit(gui);
107 window->gui_data = NULL;
109 if (parent->active == window && mainwindows->next != NULL)
110 mainwindow_destroy(parent);
113 void gui_window_resize(WINDOW_REC *window, int width, int height)
117 gui = WINDOW_GUI(window);
119 window->width = width;
120 window->height = height;
121 textbuffer_view_resize(gui->view, width, height);
124 void gui_window_scroll(WINDOW_REC *window, int lines)
126 g_return_if_fail(window != NULL);
128 textbuffer_view_scroll(WINDOW_GUI(window)->view, lines);
129 signal_emit("gui page scrolled", 1, window);
132 void gui_window_scroll_line(WINDOW_REC *window, LINE_REC *line)
134 g_return_if_fail(window != NULL);
135 g_return_if_fail(line != NULL);
137 textbuffer_view_scroll_line(WINDOW_GUI(window)->view, line);
138 signal_emit("gui page scrolled", 1, window);
141 void window_update_prompt(void)
147 special = settings_get_str(active_win->active != NULL ?
148 "prompt" : "prompt_window");
149 if (*special == '\0') {
150 gui_entry_set_prompt("");
154 prompt = parse_special_string(special, active_win->active_server,
155 active_win->active, "", &var_used,
156 PARSE_FLAG_ISSET_ANY |
157 PARSE_FLAG_ESCAPE_VARS);
158 if (!var_used && strchr(special, '$') != NULL) {
159 /* none of the $vars had non-empty values, use empty prompt */
164 text = show_lowascii(prompt);
165 gui_entry_set_prompt(text);
171 static void window_update_prompt_server(SERVER_REC *server)
173 if (server == active_win->active_server)
174 window_update_prompt();
177 static void window_update_prompt_window(WINDOW_REC *window)
179 if (window == active_win)
180 window_update_prompt();
183 static void window_update_prompt_window_item(WI_ITEM_REC *item)
185 if (item == active_win->active)
186 window_update_prompt();
189 void gui_window_reparent(WINDOW_REC *window, MAIN_WINDOW_REC *parent)
191 MAIN_WINDOW_REC *oldparent;
193 oldparent = WINDOW_GUI(window)->parent;
194 if (oldparent == parent)
197 textbuffer_view_set_window(WINDOW_GUI(window)->view, NULL);
199 WINDOW_GUI(window)->parent = parent;
200 if (parent->height != oldparent->height ||
201 parent->width != oldparent->width)
202 gui_window_resize(window, parent->width, parent->height);
205 static MAIN_WINDOW_REC *mainwindow_find_unsticky(void)
209 for (tmp = mainwindows; tmp != NULL; tmp = tmp->next) {
210 MAIN_WINDOW_REC *rec = tmp->data;
212 if (rec->sticky_windows == NULL)
216 /* all windows are sticky, fallback to active window */
217 return active_mainwin;
220 static void signal_window_changed(WINDOW_REC *window, WINDOW_REC *old_window)
222 MAIN_WINDOW_REC *parent;
224 g_return_if_fail(window != NULL);
226 if (quitting) return;
228 parent = WINDOW_GUI(window)->parent;
229 if (is_window_visible(window)) {
230 /* already visible */
231 active_mainwin = parent;
232 } else if (active_mainwin == NULL) {
233 /* no main window set yet */
234 active_mainwin = parent;
235 } else if (g_slist_find(parent->sticky_windows, window) != NULL) {
236 /* window is sticky, switch to correct main window */
237 if (parent != active_mainwin)
238 active_mainwin = parent;
240 /* move window to active main window */
241 if (active_mainwin->sticky_windows != NULL) {
242 /* active mainwindow is sticky, we'll need to
243 set the window active somewhere else */
244 active_mainwin = mainwindow_find_unsticky();
246 gui_window_reparent(window, active_mainwin);
248 active_mainwin->active = window;
250 if (old_window != NULL && !is_window_visible(old_window))
251 textbuffer_view_set_window(WINDOW_GUI(old_window)->view, NULL);
253 textbuffer_view_set_window(WINDOW_GUI(window)->view,
256 window_update_prompt();
259 static void sig_check_window_update(WINDOW_REC *window)
261 if (window == active_win)
262 window_update_prompt();
265 static void read_settings(void)
269 SIGNAL_FUNC funcs[] = {
270 (SIGNAL_FUNC) window_update_prompt,
271 (SIGNAL_FUNC) window_update_prompt_server,
272 (SIGNAL_FUNC) window_update_prompt_window,
273 (SIGNAL_FUNC) window_update_prompt_window_item
276 if (prompt != NULL) {
277 special_vars_remove_signals(prompt, 4, funcs);
278 special_vars_remove_signals(prompt_window, 4, funcs);
280 g_free(prompt_window);
282 prompt = g_strdup(settings_get_str("prompt"));
283 prompt_window = g_strdup(settings_get_str("prompt_window"));
285 for (tmp = windows; tmp != NULL; tmp = tmp->next) {
286 WINDOW_REC *rec = tmp->data;
288 textbuffer_view_set_default_indent(WINDOW_GUI(rec)->view,
289 settings_get_int("indent"),
290 settings_get_bool("indent_always"));
293 special_vars_add_signals(prompt, 4, funcs);
294 special_vars_add_signals(prompt_window, 4, funcs);
296 if (active_win != NULL) window_update_prompt();
299 void gui_windows_init(void)
301 settings_add_bool("lookandfeel", "autostick_split_windows", TRUE);
302 settings_add_int("lookandfeel", "indent", 10);
303 settings_add_bool("lookandfeel", "indent_always", FALSE);
304 settings_add_str("lookandfeel", "prompt", "[$[.15]T] ");
305 settings_add_str("lookandfeel", "prompt_window", "[$winname] ");
307 prompt = NULL; prompt_window = NULL;
308 window_create_override = -1;
311 signal_add("gui window create override", (SIGNAL_FUNC) sig_window_create_override);
312 signal_add("window created", (SIGNAL_FUNC) gui_window_created);
313 signal_add("window destroyed", (SIGNAL_FUNC) gui_window_destroyed);
314 signal_add_first("window changed", (SIGNAL_FUNC) signal_window_changed);
315 signal_add("window item remove", (SIGNAL_FUNC) sig_check_window_update);
316 signal_add("setup changed", (SIGNAL_FUNC) read_settings);
319 void gui_windows_deinit(void)
321 g_free_not_null(prompt);
322 g_free_not_null(prompt_window);
324 while (windows != NULL)
325 window_destroy(windows->data);
327 signal_remove("gui window create override", (SIGNAL_FUNC) sig_window_create_override);
328 signal_remove("window created", (SIGNAL_FUNC) gui_window_created);
329 signal_remove("window destroyed", (SIGNAL_FUNC) gui_window_destroyed);
330 signal_remove("window changed", (SIGNAL_FUNC) signal_window_changed);
331 signal_remove("window item remove", (SIGNAL_FUNC) sig_check_window_update);
332 signal_remove("setup changed", (SIGNAL_FUNC) read_settings);