forked from PsychoticNinja/irssi
git-svn-id: http://svn.irssi.org/repos/irssi/trunk@1523 dbcabf3a-b0e7-0310-adc4-f8d773084564
337 lines
9.3 KiB
C
337 lines
9.3 KiB
C
/*
|
|
gui-windows.c : irssi
|
|
|
|
Copyright (C) 1999-2001 Timo Sirainen
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*/
|
|
|
|
#include "module.h"
|
|
#include "signals.h"
|
|
#include "misc.h"
|
|
#include "settings.h"
|
|
#include "special-vars.h"
|
|
|
|
#include "screen.h"
|
|
#include "gui-entry.h"
|
|
#include "gui-windows.h"
|
|
#include "gui-printtext.h"
|
|
|
|
static int window_create_override;
|
|
|
|
static char *prompt, *prompt_window;
|
|
|
|
static GUI_WINDOW_REC *gui_window_init(WINDOW_REC *window,
|
|
MAIN_WINDOW_REC *parent)
|
|
{
|
|
GUI_WINDOW_REC *gui;
|
|
|
|
window->width = parent->width;
|
|
window->height = parent->height;
|
|
|
|
gui = g_new0(GUI_WINDOW_REC, 1);
|
|
gui->parent = parent;
|
|
gui->view = textbuffer_view_create(textbuffer_create(),
|
|
window->width, window->height,
|
|
settings_get_int("indent"),
|
|
settings_get_bool("indent_always"));
|
|
return gui;
|
|
}
|
|
|
|
static void gui_window_deinit(GUI_WINDOW_REC *gui)
|
|
{
|
|
textbuffer_view_destroy(gui->view);
|
|
g_free(gui);
|
|
}
|
|
|
|
static void sig_window_create_override(gpointer tab)
|
|
{
|
|
window_create_override = GPOINTER_TO_INT(tab);
|
|
}
|
|
|
|
static void gui_window_created(WINDOW_REC *window)
|
|
{
|
|
MAIN_WINDOW_REC *parent;
|
|
|
|
g_return_if_fail(window != NULL);
|
|
|
|
parent = window_create_override != 0 &&
|
|
active_win != NULL && WINDOW_GUI(active_win) != NULL ?
|
|
WINDOW_GUI(active_win)->parent : mainwindow_create();
|
|
if (parent == NULL) {
|
|
/* not enough space for new window, but we really can't
|
|
abort creation of the window anymore, so create hidden
|
|
window instead. */
|
|
parent = WINDOW_GUI(active_win)->parent;
|
|
}
|
|
window_create_override = -1;
|
|
|
|
if (settings_get_bool("autostick_split_windows") &&
|
|
(parent->sticky_windows != NULL ||
|
|
(mainwindows->next != NULL && parent->active == NULL))) {
|
|
/* set the window sticky */
|
|
parent->sticky_windows =
|
|
g_slist_append(parent->sticky_windows, window);
|
|
}
|
|
|
|
if (parent->active == NULL) parent->active = window;
|
|
window->gui_data = gui_window_init(window, parent);
|
|
signal_emit("gui window created", 1, window);
|
|
}
|
|
|
|
static void gui_window_destroyed(WINDOW_REC *window)
|
|
{
|
|
MAIN_WINDOW_REC *parent;
|
|
GUI_WINDOW_REC *gui;
|
|
|
|
g_return_if_fail(window != NULL);
|
|
|
|
gui = WINDOW_GUI(window);
|
|
parent = gui->parent;
|
|
|
|
signal_emit("gui window destroyed", 1, window);
|
|
|
|
gui_window_deinit(gui);
|
|
window->gui_data = NULL;
|
|
|
|
if (parent->active == window && mainwindows->next != NULL)
|
|
mainwindow_destroy(parent);
|
|
}
|
|
|
|
void gui_window_resize(WINDOW_REC *window, int width, int height)
|
|
{
|
|
GUI_WINDOW_REC *gui;
|
|
|
|
gui = WINDOW_GUI(window);
|
|
|
|
window->width = width;
|
|
window->height = height;
|
|
textbuffer_view_resize(gui->view, width, height);
|
|
}
|
|
|
|
void gui_window_scroll(WINDOW_REC *window, int lines)
|
|
{
|
|
g_return_if_fail(window != NULL);
|
|
|
|
textbuffer_view_scroll(WINDOW_GUI(window)->view, lines);
|
|
signal_emit("gui page scrolled", 1, window);
|
|
}
|
|
|
|
void gui_window_scroll_line(WINDOW_REC *window, LINE_REC *line)
|
|
{
|
|
g_return_if_fail(window != NULL);
|
|
g_return_if_fail(line != NULL);
|
|
|
|
textbuffer_view_scroll_line(WINDOW_GUI(window)->view, line);
|
|
signal_emit("gui page scrolled", 1, window);
|
|
}
|
|
|
|
void window_update_prompt(void)
|
|
{
|
|
const char *special;
|
|
char *prompt, *text;
|
|
int var_used;
|
|
|
|
special = settings_get_str(active_win->active != NULL ?
|
|
"prompt" : "prompt_window");
|
|
if (*special == '\0') {
|
|
gui_entry_set_prompt("");
|
|
return;
|
|
}
|
|
|
|
prompt = parse_special_string(special, active_win->active_server,
|
|
active_win->active, "", &var_used,
|
|
PARSE_FLAG_ISSET_ANY |
|
|
PARSE_FLAG_ESCAPE_VARS);
|
|
if (!var_used && strchr(special, '$') != NULL) {
|
|
/* none of the $vars had non-empty values, use empty prompt */
|
|
*prompt = '\0';
|
|
}
|
|
|
|
/* set prompt */
|
|
text = show_lowascii(prompt);
|
|
gui_entry_set_prompt(text);
|
|
g_free(text);
|
|
|
|
g_free(prompt);
|
|
}
|
|
|
|
static void window_update_prompt_server(SERVER_REC *server)
|
|
{
|
|
if (server == active_win->active_server)
|
|
window_update_prompt();
|
|
}
|
|
|
|
static void window_update_prompt_window(WINDOW_REC *window)
|
|
{
|
|
if (window == active_win)
|
|
window_update_prompt();
|
|
}
|
|
|
|
static void window_update_prompt_window_item(WI_ITEM_REC *item)
|
|
{
|
|
if (item == active_win->active)
|
|
window_update_prompt();
|
|
}
|
|
|
|
void gui_window_reparent(WINDOW_REC *window, MAIN_WINDOW_REC *parent)
|
|
{
|
|
MAIN_WINDOW_REC *oldparent;
|
|
|
|
oldparent = WINDOW_GUI(window)->parent;
|
|
if (oldparent == parent)
|
|
return;
|
|
|
|
textbuffer_view_set_window(WINDOW_GUI(window)->view, NULL);
|
|
|
|
WINDOW_GUI(window)->parent = parent;
|
|
if (parent->height != oldparent->height ||
|
|
parent->width != oldparent->width)
|
|
gui_window_resize(window, parent->width, parent->height);
|
|
}
|
|
|
|
static MAIN_WINDOW_REC *mainwindow_find_unsticky(void)
|
|
{
|
|
GSList *tmp;
|
|
|
|
for (tmp = mainwindows; tmp != NULL; tmp = tmp->next) {
|
|
MAIN_WINDOW_REC *rec = tmp->data;
|
|
|
|
if (rec->sticky_windows == NULL)
|
|
return rec;
|
|
}
|
|
|
|
/* all windows are sticky, fallback to active window */
|
|
return active_mainwin;
|
|
}
|
|
|
|
static void signal_window_changed(WINDOW_REC *window)
|
|
{
|
|
MAIN_WINDOW_REC *parent;
|
|
WINDOW_REC *old_window;
|
|
|
|
g_return_if_fail(window != NULL);
|
|
|
|
if (quitting) return;
|
|
|
|
parent = WINDOW_GUI(window)->parent;
|
|
if (is_window_visible(window)) {
|
|
/* already visible */
|
|
active_mainwin = parent;
|
|
} else if (active_mainwin == NULL) {
|
|
/* no main window set yet */
|
|
active_mainwin = parent;
|
|
} else if (g_slist_find(parent->sticky_windows, window) != NULL) {
|
|
/* window is sticky, switch to correct main window */
|
|
if (parent != active_mainwin)
|
|
active_mainwin = parent;
|
|
} else {
|
|
/* move window to active main window */
|
|
if (active_mainwin->sticky_windows != NULL) {
|
|
/* active mainwindow is sticky, we'll need to
|
|
set the window active somewhere else */
|
|
active_mainwin = mainwindow_find_unsticky();
|
|
}
|
|
gui_window_reparent(window, active_mainwin);
|
|
}
|
|
|
|
old_window = active_mainwin->active;
|
|
if (old_window != NULL)
|
|
textbuffer_view_set_window(WINDOW_GUI(old_window)->view, NULL);
|
|
|
|
active_mainwin->active = window;
|
|
|
|
textbuffer_view_set_window(WINDOW_GUI(window)->view,
|
|
parent->curses_win);
|
|
|
|
window_update_prompt();
|
|
}
|
|
|
|
static void sig_check_window_update(WINDOW_REC *window)
|
|
{
|
|
if (window == active_win)
|
|
window_update_prompt();
|
|
}
|
|
|
|
static void read_settings(void)
|
|
{
|
|
GSList *tmp;
|
|
|
|
SIGNAL_FUNC funcs[] = {
|
|
(SIGNAL_FUNC) window_update_prompt,
|
|
(SIGNAL_FUNC) window_update_prompt_server,
|
|
(SIGNAL_FUNC) window_update_prompt_window,
|
|
(SIGNAL_FUNC) window_update_prompt_window_item
|
|
};
|
|
|
|
if (prompt != NULL) {
|
|
special_vars_remove_signals(prompt, 4, funcs);
|
|
special_vars_remove_signals(prompt_window, 4, funcs);
|
|
g_free(prompt);
|
|
g_free(prompt_window);
|
|
}
|
|
prompt = g_strdup(settings_get_str("prompt"));
|
|
prompt_window = g_strdup(settings_get_str("prompt_window"));
|
|
|
|
for (tmp = windows; tmp != NULL; tmp = tmp->next) {
|
|
WINDOW_REC *rec = tmp->data;
|
|
|
|
textbuffer_view_set_default_indent(WINDOW_GUI(rec)->view,
|
|
settings_get_int("indent"),
|
|
settings_get_bool("indent_always"));
|
|
}
|
|
|
|
special_vars_add_signals(prompt, 4, funcs);
|
|
special_vars_add_signals(prompt_window, 4, funcs);
|
|
|
|
if (active_win != NULL) window_update_prompt();
|
|
}
|
|
|
|
void gui_windows_init(void)
|
|
{
|
|
settings_add_bool("lookandfeel", "autostick_split_windows", TRUE);
|
|
settings_add_int("lookandfeel", "indent", 10);
|
|
settings_add_bool("lookandfeel", "indent_always", FALSE);
|
|
settings_add_str("lookandfeel", "prompt", "[$[.15]T] ");
|
|
settings_add_str("lookandfeel", "prompt_window", "[$winname] ");
|
|
|
|
prompt = NULL; prompt_window = NULL;
|
|
window_create_override = -1;
|
|
|
|
read_settings();
|
|
signal_add("gui window create override", (SIGNAL_FUNC) sig_window_create_override);
|
|
signal_add("window created", (SIGNAL_FUNC) gui_window_created);
|
|
signal_add("window destroyed", (SIGNAL_FUNC) gui_window_destroyed);
|
|
signal_add_first("window changed", (SIGNAL_FUNC) signal_window_changed);
|
|
signal_add("window item remove", (SIGNAL_FUNC) sig_check_window_update);
|
|
signal_add("setup changed", (SIGNAL_FUNC) read_settings);
|
|
}
|
|
|
|
void gui_windows_deinit(void)
|
|
{
|
|
g_free_not_null(prompt);
|
|
g_free_not_null(prompt_window);
|
|
|
|
while (windows != NULL)
|
|
window_destroy(windows->data);
|
|
|
|
signal_remove("gui window create override", (SIGNAL_FUNC) sig_window_create_override);
|
|
signal_remove("window created", (SIGNAL_FUNC) gui_window_created);
|
|
signal_remove("window destroyed", (SIGNAL_FUNC) gui_window_destroyed);
|
|
signal_remove("window changed", (SIGNAL_FUNC) signal_window_changed);
|
|
signal_remove("window item remove", (SIGNAL_FUNC) sig_check_window_update);
|
|
signal_remove("setup changed", (SIGNAL_FUNC) read_settings);
|
|
}
|