Merged Irssi 0.8.2 from irssi.org cvs.
[silc.git] / apps / irssi / src / fe-common / core / fe-windows.c
index 3c48261a6aa25df6037cfc05f853b36ff7cf3e0e..fe76427b466e42d12ca455ba51be5e52b20ad294 100644 (file)
@@ -70,6 +70,7 @@ WINDOW_REC *window_create(WI_ITEM_REC *item, int automatic)
 
        rec = g_new0(WINDOW_REC, 1);
        rec->refnum = window_get_new_refnum();
+       rec->level = level2bits(settings_get_str("window_default_level"));
 
        windows = g_slist_prepend(windows, rec);
        signal_emit("window created", 2, rec, GINT_TO_POINTER(automatic));
@@ -134,7 +135,8 @@ void window_destroy(WINDOW_REC *window)
 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);
 }
 
@@ -194,6 +196,21 @@ void window_set_name(WINDOW_REC *window, const char *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);
@@ -202,6 +219,14 @@ void window_set_level(WINDOW_REC *window, int level)
         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)
 {
@@ -213,36 +238,42 @@ char *window_get_active_name(WINDOW_REC *window)
        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;
 
-       match = NULL;
+        /* prefer active window if possible */
+       if (WINDOW_LEVEL_MATCH(active_win, server, level))
+                return active_win;
+
        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)
-                               return rec;
-                       match = rec;
-               }
+               if (WINDOW_LEVEL_MATCH(rec, server, level))
+                        return rec;
        }
 
-       return match;
+       return NULL;
 }
 
 WINDOW_REC *window_find_closest(void *server, const char *name, int level)
 {
-       WINDOW_REC *window;
+       WINDOW_REC *window,*namewindow=NULL;
        WI_ITEM_REC *item;
 
        /* 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")))
+                 return namewindow;
+       }
 
        /* match by level */
        if (level != MSGLEVEL_HILIGHT)
@@ -254,6 +285,9 @@ WINDOW_REC *window_find_closest(void *server, const char *name, int level)
        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;
 }
@@ -375,7 +409,7 @@ int windows_refnum_last(void)
        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;
 }
@@ -395,6 +429,7 @@ GSList *windows_get_sorted(void)
         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)
 {
@@ -402,7 +437,11 @@ WINDOW_BIND_REC *window_bind_add(WINDOW_REC *window, const char *servertag,
 
         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);
@@ -494,18 +533,31 @@ static void sig_server_disconnected(SERVER_REC *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;
 
@@ -513,11 +565,8 @@ static void sig_print_text(void)
        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)
@@ -563,6 +612,8 @@ void windows_init(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_str("lookandfeel", "window_default_level", "NONE");
 
        read_settings();
        signal_add("server looking", (SIGNAL_FUNC) sig_server_looking);