rec = g_new0(WINDOW_REC, 1);
rec->refnum = window_get_new_refnum();
+ rec->level = settings_get_level("window_default_level");
windows = g_slist_prepend(windows, rec);
signal_emit("window created", 2, rec, GINT_TO_POINTER(automatic));
window->destroying = TRUE;
windows = g_slist_remove(windows, window);
- if (active_win == window && windows != NULL) {
- active_win = NULL; /* it's corrupted */
- window_set_active(windows->data);
+ if (active_win == window) {
+ active_win = NULL; /* it's corrupted */
+ if (windows != NULL)
+ window_set_active(windows->data);
}
while (window->items != NULL)
void window_auto_destroy(WINDOW_REC *window)
{
if (settings_get_bool("autoclose_windows") && windows->next != NULL &&
- window->items == NULL && window->level == 0)
+ window->items == NULL && window->bound_items == NULL &&
+ window->level == 0 && !window->immortal)
window_destroy(window);
}
void window_change_server(WINDOW_REC *window, void *server)
{
- window->active_server = server;
- signal_emit("window server changed", 2, window, server);
+ SERVER_REC *active, *connect;
+
+ if (server != NULL && SERVER(server)->disconnected)
+ return;
+
+ if (server == NULL) {
+ active = connect = NULL;
+ } else if (g_slist_find(servers, server) != NULL) {
+ active = server;
+ connect = NULL;
+ } else {
+ active = NULL;
+ connect = server;
+ }
+
+ if (window->connect_server != connect) {
+ window->connect_server = connect;
+ signal_emit("window connect changed", 2, window, connect);
+ }
+
+ if (window->active_server != active) {
+ window->active_server = active;
+ signal_emit("window server changed", 2, window, active);
+ }
}
void window_set_refnum(WINDOW_REC *window, int refnum)
void window_set_name(WINDOW_REC *window, const char *name)
{
g_free_not_null(window->name);
- window->name = g_strdup(name);
+ window->name = name == NULL || *name == '\0' ? NULL : g_strdup(name);
signal_emit("window name changed", 1, window);
}
+void window_set_history(WINDOW_REC *window, const char *name)
+{
+ char *oldname;
+ oldname = window->history_name;
+
+ if (name == NULL || *name == '\0')
+ window->history_name = NULL;
+ else
+ window->history_name = g_strdup(name);
+
+ signal_emit("window history changed", 1, window, oldname);
+
+ g_free_not_null(oldname);
+}
+
void window_set_level(WINDOW_REC *window, int level)
{
g_return_if_fail(window != NULL);
signal_emit("window level changed", 1, window);
}
+void window_set_immortal(WINDOW_REC *window, int immortal)
+{
+ g_return_if_fail(window != NULL);
+
+ window->immortal = immortal;
+ signal_emit("window immortal changed", 1, window);
+}
+
/* return active item's name, or if none is active, window's name */
-char *window_get_active_name(WINDOW_REC *window)
+const char *window_get_active_name(WINDOW_REC *window)
{
g_return_val_if_fail(window != NULL, NULL);
if (window->active != NULL)
- return window->active->name;
+ return window->active->visible_name;
return window->name;
}
+#define WINDOW_LEVEL_MATCH(window, server, level) \
+ (((window)->level & level) && \
+ (server == NULL || (window)->active_server == server))
+
WINDOW_REC *window_find_level(void *server, int level)
{
- WINDOW_REC *match;
GSList *tmp;
+ WINDOW_REC *match;
match = NULL;
for (tmp = windows; tmp != NULL; tmp = tmp->next) {
WINDOW_REC *rec = tmp->data;
- if ((server == NULL || rec->active_server == server) &&
- (rec->level & level)) {
- if (server == NULL || rec->active_server == server)
+ if (WINDOW_LEVEL_MATCH(rec, server, level)) {
+ /* prefer windows without any items */
+ if (rec->items == NULL)
return rec;
- match = rec;
+
+ if (match == NULL)
+ match = rec;
+ else if (active_win == rec) {
+ /* prefer active window over others */
+ match = rec;
+ }
}
}
WINDOW_REC *window_find_closest(void *server, const char *name, int level)
{
- WINDOW_REC *window;
+ WINDOW_REC *window,*namewindow=NULL;
WI_ITEM_REC *item;
+ int i;
/* match by name */
item = name == NULL ? NULL :
window_item_find(server, name);
- if (item != NULL)
- return window_item_window(item);
+ if (item != NULL) {
+ namewindow = window_item_window(item);
+ if (namewindow != NULL &&
+ ((namewindow->level & level) != 0 ||
+ !settings_get_bool("window_check_level_first"))) {
+ /* match, but if multiple windows have the same level
+ we could be choosing a bad one here, eg.
+ name=nick1 would get nick2's query instead of
+ generic msgs window.
+
+ And check for prefixed !channel name --Borys */
+ if (g_strcasecmp(name, item->visible_name) == 0 ||
+ g_strcasecmp(name, (char *) window_item_get_target((WI_ITEM_REC *) item)) == 0)
+ return namewindow;
+ }
+ }
- /* match by level */
- if (level != MSGLEVEL_HILIGHT)
- level &= ~(MSGLEVEL_HILIGHT | MSGLEVEL_NOHILIGHT);
- window = window_find_level(server, level);
- if (window != NULL) return window;
+ /* prefer windows without items */
+ for (i = 0; i < 2; i++) {
+ /* match by level */
+ if (level != MSGLEVEL_HILIGHT)
+ level &= ~(MSGLEVEL_HILIGHT | MSGLEVEL_NOHILIGHT);
+ window = window_find_level(server, level);
+ if (window != NULL && (i == 1 || window->items == NULL))
+ return window;
+
+ /* match by level - ignore server */
+ window = window_find_level(NULL, level);
+ if (window != NULL && (i == 1 || window->items == NULL))
+ return window;
+ }
- /* match by level - ignore server */
- window = window_find_level(NULL, level);
- if (window != NULL) return window;
+ /* still return item's window if we didnt find anything */
+ if (namewindow != NULL) return namewindow;
/* fallback to active */
return active_win;
item = server == NULL ? NULL :
window_item_find(server, name);
- if (item == NULL && server == NULL) {
+ if (item == NULL) {
/* not found from the active server - any server? */
item = window_item_find(NULL, name);
}
- if (item == NULL) {
- char *chan;
-
- /* still nothing? maybe user just left the # in front of
- channel, try again with it.. */
- chan = g_strdup_printf("#%s", name);
- item = server == NULL ? NULL :
- window_item_find(server, chan);
- if (item == NULL) item = window_item_find(NULL, chan);
- g_free(chan);
- }
-
if (item == NULL)
return 0;
return max;
}
-static int window_refnum_cmp(WINDOW_REC *w1, WINDOW_REC *w2)
+int window_refnum_cmp(WINDOW_REC *w1, WINDOW_REC *w2)
{
return w1->refnum < w2->refnum ? -1 : 1;
}
return sorted;
}
+/* Add a new bind to window - if duplicate is found it's returned */
WINDOW_BIND_REC *window_bind_add(WINDOW_REC *window, const char *servertag,
const char *name)
{
g_return_val_if_fail(window != NULL, NULL);
g_return_val_if_fail(servertag != NULL, NULL);
- g_return_val_if_fail(name != NULL, NULL);
+ g_return_val_if_fail(name != NULL, NULL);
+
+ rec = window_bind_find(window, servertag, name);
+ if (rec != NULL)
+ return rec;
rec = g_new0(WINDOW_BIND_REC, 1);
rec->name = g_strdup(name);
}
}
-static void sig_server_looking(SERVER_REC *server)
+static void sig_server_connected(SERVER_REC *server)
{
GSList *tmp;
for (tmp = windows; tmp != NULL; tmp = tmp->next) {
WINDOW_REC *rec = tmp->data;
- if (rec->active_server == server) {
+ if (rec->active_server == server ||
+ rec->connect_server == server) {
window_change_server(rec, rec->servertag != NULL ?
NULL : new_server);
}
}
}
+static void window_print_daychange(WINDOW_REC *window, struct tm *tm)
+{
+ THEME_REC *theme;
+ TEXT_DEST_REC dest;
+ char *format, str[256];
+
+ theme = active_win->theme != NULL ? active_win->theme : current_theme;
+ format_create_dest(&dest, NULL, NULL, MSGLEVEL_NEVER, window);
+ format = format_get_text_theme(theme, MODULE_NAME, &dest,
+ TXT_DAYCHANGE);
+ if (strftime(str, sizeof(str), format, tm) <= 0)
+ str[0] = '\0';
+ g_free(format);
+
+ printtext_string_window(window, MSGLEVEL_NEVER, str);
+}
+
static void sig_print_text(void)
{
GSList *tmp;
- char month[100];
time_t t;
struct tm *tm;
t = time(NULL);
tm = localtime(&t);
- if (strftime(month, sizeof(month), "%b", tm) <= 0)
- month[0] = '\0';
-
if (tm->tm_hour != 0 || tm->tm_min != 0)
return;
signal_remove("print text", (SIGNAL_FUNC) sig_print_text);
/* day changed, print notice about it to every window */
- for (tmp = windows; tmp != NULL; tmp = tmp->next) {
- printformat_window(tmp->data, MSGLEVEL_NEVER, TXT_DAYCHANGE,
- tm->tm_mday, tm->tm_mon+1,
- 1900+tm->tm_year, month);
- }
+ for (tmp = windows; tmp != NULL; tmp = tmp->next)
+ window_print_daychange(tmp->data, tm);
}
static int sig_check_daychange(void)
daycheck = 0; daytag = -1;
settings_add_bool("lookandfeel", "window_auto_change", FALSE);
settings_add_bool("lookandfeel", "windows_auto_renumber", TRUE);
+ settings_add_bool("lookandfeel", "window_check_level_first", FALSE);
+ settings_add_level("lookandfeel", "window_default_level", "NONE");
read_settings();
- signal_add("server looking", (SIGNAL_FUNC) sig_server_looking);
+ signal_add("server looking", (SIGNAL_FUNC) sig_server_connected);
+ signal_add("server connected", (SIGNAL_FUNC) sig_server_connected);
signal_add("server disconnected", (SIGNAL_FUNC) sig_server_disconnected);
signal_add("server connect failed", (SIGNAL_FUNC) sig_server_disconnected);
signal_add("setup changed", (SIGNAL_FUNC) read_settings);
if (daytag != -1) g_source_remove(daytag);
if (daycheck == 1) signal_remove("print text", (SIGNAL_FUNC) sig_print_text);
- signal_remove("server looking", (SIGNAL_FUNC) sig_server_looking);
+ signal_remove("server looking", (SIGNAL_FUNC) sig_server_connected);
+ signal_remove("server connected", (SIGNAL_FUNC) sig_server_connected);
signal_remove("server disconnected", (SIGNAL_FUNC) sig_server_disconnected);
signal_remove("server connect failed", (SIGNAL_FUNC) sig_server_disconnected);
signal_remove("setup changed", (SIGNAL_FUNC) read_settings);