Added SILC Thread Queue API
[crypto.git] / apps / irssi / src / fe-common / core / fe-queries.c
index 1924464ac6e087302afcdbffd57ccefa0ca9f081..f1763814103ea11576770e23172623ab19df8872 100644 (file)
 #include "settings.h"
 
 #include "chat-protocols.h"
+#include "servers.h"
 #include "queries.h"
 
+#include "fe-core-commands.h"
 #include "fe-windows.h"
 #include "window-items.h"
 #include "printtext.h"
@@ -45,7 +47,8 @@ QUERY_REC *privmsg_get_query(SERVER_REC *server, const char *nick,
         g_return_val_if_fail(nick != NULL, NULL);
 
        query = query_find(server, nick);
-       if (query == NULL && (querycreate_level & level) != 0 &&
+       if (query == NULL && !command_hide_output &&
+           (querycreate_level & level) != 0 &&
            (!own || settings_get_bool("autocreate_own_query"))) {
                query = CHAT_PROTOCOL(server)->
                        query_create(server->tag, nick, TRUE);
@@ -56,14 +59,19 @@ QUERY_REC *privmsg_get_query(SERVER_REC *server, const char *nick,
 
 static void signal_query_created(QUERY_REC *query, gpointer automatic)
 {
+        TEXT_DEST_REC dest;
+
        g_return_if_fail(IS_QUERY(query));
 
        if (window_item_window(query) == NULL) {
                window_item_create((WI_ITEM_REC *) query,
                                   GPOINTER_TO_INT(automatic));
-               printformat(query->server, query->name, MSGLEVEL_CLIENTNOTICE,
-                           TXT_QUERY_STARTED, query->name);
        }
+
+       format_create_dest_tag(&dest, query->server, query->server_tag,
+                              query->name, MSGLEVEL_CLIENTNOTICE, NULL);
+       printformat_dest(&dest, TXT_QUERY_START,
+                        query->name, query->server_tag);
 }
 
 static void signal_query_created_curwin(QUERY_REC *query)
@@ -76,15 +84,25 @@ static void signal_query_created_curwin(QUERY_REC *query)
 static void signal_query_destroyed(QUERY_REC *query)
 {
        WINDOW_REC *window;
+        TEXT_DEST_REC dest;
 
        g_return_if_fail(IS_QUERY(query));
 
        window = window_item_window((WI_ITEM_REC *) query);
-       if (window != NULL) {
-               window_item_destroy((WI_ITEM_REC *) query);
+       if (window == NULL)
+               return;
 
-               if (!query->unwanted)
-                       window_auto_destroy(window);
+       format_create_dest_tag(&dest, query->server, query->server_tag,
+                              query->name, MSGLEVEL_CLIENTNOTICE, NULL);
+       printformat_dest(&dest, TXT_QUERY_STOP, query->name);
+
+       window_item_destroy((WI_ITEM_REC *) query);
+
+       if (!query->unwanted)
+               window_auto_destroy(window);
+       else {
+               /* eg. connection lost to dcc chat */
+               window_bind_add(window, query->server_tag, query->name);
        }
 }
 
@@ -101,8 +119,20 @@ static void signal_query_server_changed(QUERY_REC *query)
 
 static void signal_query_nick_changed(QUERY_REC *query, const char *oldnick)
 {
+        TEXT_DEST_REC dest;
+
        g_return_if_fail(query != NULL);
 
+       format_create_dest_tag(&dest, query->server, query->server_tag,
+                              query->name, MSGLEVEL_CLIENTNOTICE, NULL);
+
+       /* don't print the nick change message if only the case was changed */
+       if (g_strcasecmp(query->name, oldnick) != 0) {
+               printformat_dest(&dest,  TXT_NICK_CHANGED, oldnick,
+                                query->name, query->name,
+                                query->address == NULL ? "" : query->address);
+       }
+
        signal_emit("window item changed", 2,
                    window_item_window((WI_ITEM_REC *) query), query);
 }
@@ -117,16 +147,6 @@ static void signal_window_item_server_changed(WINDOW_REC *window,
        }
 }
 
-static void signal_window_item_destroy(WINDOW_REC *window, WI_ITEM_REC *item)
-{
-       QUERY_REC *query;
-
-       g_return_if_fail(window != NULL);
-
-       query = QUERY(item);
-       if (query != NULL) query_destroy(query);
-}
-
 static void sig_server_connected(SERVER_REC *server)
 {
        GSList *tmp;
@@ -151,6 +171,7 @@ static void cmd_window_server(const char *data)
 {
        SERVER_REC *server;
         QUERY_REC *query;
+        TEXT_DEST_REC dest;
 
        g_return_if_fail(data != NULL);
 
@@ -160,10 +181,12 @@ static void cmd_window_server(const char *data)
                return;
 
        /* /WINDOW SERVER used in a query window */
+       format_create_dest_tag(&dest, query->server, query->server_tag,
+                              query->name, MSGLEVEL_CLIENTNOTICE, NULL);
+       printformat_dest(&dest, TXT_QUERY_SERVER_CHANGED,
+                        query->name, server->tag);
+
        query_change_server(query, server);
-       printformat(NULL, NULL, MSGLEVEL_CLIENTNOTICE,
-                   TXT_QUERY_SERVER_CHANGED,
-                   query->name, server->tag);
        signal_stop();
 }
 
@@ -171,23 +194,29 @@ static void cmd_window_server(const char *data)
 static void cmd_unquery(const char *data, SERVER_REC *server, WI_ITEM_REC *item)
 {
        QUERY_REC *query;
+       char *nick;
+       void *free_arg;
 
        g_return_if_fail(data != NULL);
 
-       if (*data == '\0') {
+       if (!cmd_get_params(data, &free_arg, 1, &nick))
+               return;
+
+       if (*nick == '\0') {
                /* remove current query */
                query = QUERY(item);
-               if (query == NULL) return;
        } else {
-               query = query_find(server, data);
+               query = query_find(server, nick);
                if (query == NULL) {
                        printformat(server, NULL, MSGLEVEL_CLIENTERROR,
-                                   TXT_NO_QUERY, data);
-                       return;
+                                   TXT_NO_QUERY, nick);
                }
        }
 
-       query_destroy(query);
+       if (query != NULL)
+               query_destroy(query);
+
+       cmd_params_free(free_arg);
 }
 
 /* SYNTAX: QUERY [-window] [-<server tag>] <nick> [<message>] */
@@ -200,17 +229,17 @@ static void cmd_query(const char *data, SERVER_REC *server, WI_ITEM_REC *item)
 
        g_return_if_fail(data != NULL);
 
-       if (*data == '\0') {
-               /* remove current query */
-               cmd_unquery("", server, item);
-               return;
-       }
-
        if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_GETREST |
                            PARAM_FLAG_OPTIONS | PARAM_FLAG_UNKNOWN_OPTIONS,
                            "query", &optlist, &nick, &msg))
                return;
-       if (*nick == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS);
+
+       if (*nick == '\0') {
+               /* remove current query */
+               cmd_unquery("", server, item);
+               cmd_params_free(free_arg);
+                return;
+       }
 
        server = cmd_options_get_server("query", optlist, server);
        if (server == NULL) {
@@ -228,24 +257,15 @@ static void cmd_query(const char *data, SERVER_REC *server, WI_ITEM_REC *item)
 
        query = query_find(server, nick);
        if (query == NULL)
-               CHAT_PROTOCOL(server)->query_create(server->tag, nick, FALSE);
+               query = CHAT_PROTOCOL(server)->
+                       query_create(server->tag, nick, FALSE);
        else {
-               /* query already exists */
+               /* query already exists, set it active */
                WINDOW_REC *window = window_item_window(query);
 
-               if (window == active_win) {
-                        /* query is in active window, set it active */
-                       window_item_set_active(active_win,
-                                              (WI_ITEM_REC *) query);
-               } else {
-                       /* notify user how to move the query to active
-                          window. this was used to be done automatically
-                          but it just confused everyone who did it
-                          accidentally */
-                       printformat_window(active_win, MSGLEVEL_CLIENTNOTICE,
-                                          TXT_QUERY_MOVE_NOTIFY, query->name,
-                                          window->refnum);
-               }
+               if (window != active_win)
+                       window_set_active(window);
+               window_item_set_active(active_win, (WI_ITEM_REC *) query);
        }
 
        if (g_hash_table_lookup(optlist, "window") != NULL) {
@@ -254,44 +274,36 @@ static void cmd_query(const char *data, SERVER_REC *server, WI_ITEM_REC *item)
        }
 
        if (*msg != '\0') {
-               /* FIXME: we'll need some function that does both
-                  of these. and separate the , and . target handling
-                  from own_private messagge.. */
-               server->send_message(server, nick, msg);
-
-               signal_emit("message own_private", 4,
-                           server, msg, nick, nick);
+                msg = g_strdup_printf("-nick %s %s", nick, msg);
+               signal_emit("command msg", 3, msg, server, query);
+                g_free(msg);
        }
 
        cmd_params_free(free_arg);
 }
 
-static int window_has_query(WINDOW_REC *window)
+static void window_reset_query_timestamps(WINDOW_REC *window)
 {
        GSList *tmp;
 
-       g_return_val_if_fail(window != NULL, FALSE);
+       if (window == NULL)
+                return;
 
        for (tmp = window->items; tmp != NULL; tmp = tmp->next) {
-               if (IS_QUERY(tmp->data))
-                       return TRUE;
-       }
+               QUERY_REC *query = QUERY(tmp->data);
 
-       return FALSE;
+               if (query != NULL)
+                        query->last_unread_msg = time(NULL);
+       }
 }
 
 static void sig_window_changed(WINDOW_REC *window, WINDOW_REC *old_window)
 {
-       if (query_auto_close <= 0)
-               return;
-
-       /* reset the window's last_line timestamp so that query doesn't get
-          closed immediately after switched to the window, or after changed
-          to some other window from it */
-       if (window != NULL && window_has_query(window))
-               window->last_line = time(NULL);
-       if (old_window != NULL && window_has_query(old_window))
-               old_window->last_line = time(NULL);
+       /* reset the queries last_unread_msg so query doesn't get closed
+          immediately after switched to the window, or after changed to
+          some other window from it */
+        window_reset_query_timestamps(window);
+        window_reset_query_timestamps(old_window);
 }
 
 static int sig_query_autoclose(void)
@@ -306,24 +318,30 @@ static int sig_query_autoclose(void)
 
                next = tmp->next;
                window = window_item_window((WI_ITEM_REC *) rec);
-               if (window != active_win && rec->data_level == 0 &&
-                   now-window->last_line > query_auto_close)
+               if (window != active_win && rec->data_level < DATA_LEVEL_MSG &&
+                   now-rec->last_unread_msg > query_auto_close)
                        query_destroy(rec);
        }
-        return 1;
+     return 1;
 }
 
 static void sig_message_private(SERVER_REC *server, const char *msg,
                                const char *nick, const char *address)
 {
+       QUERY_REC *query;
+
        /* create query window if needed */
-       privmsg_get_query(server, nick, FALSE, MSGLEVEL_MSGS);
+       query = privmsg_get_query(server, nick, FALSE, MSGLEVEL_MSGS);
+
+       /* reset the query's last_unread_msg timestamp */
+        if (query != NULL)
+               query->last_unread_msg = time(NULL);
 }
 
 static void read_settings(void)
 {
-       querycreate_level = level2bits(settings_get_str("autocreate_query_level"));
-       query_auto_close = settings_get_int("autoclose_query");
+       querycreate_level = settings_get_level("autocreate_query_level");
+       query_auto_close = settings_get_time("autoclose_query")/1000;
        if (query_auto_close > 0 && queryclose_tag == -1)
                queryclose_tag = g_timeout_add(5000, (GSourceFunc) sig_query_autoclose, NULL);
        else if (query_auto_close <= 0 && queryclose_tag != -1) {
@@ -334,9 +352,9 @@ static void read_settings(void)
 
 void fe_queries_init(void)
 {
-       settings_add_str("lookandfeel", "autocreate_query_level", "MSGS DCCMSGS");
+       settings_add_level("lookandfeel", "autocreate_query_level", "MSGS DCCMSGS");
        settings_add_bool("lookandfeel", "autocreate_own_query", TRUE);
-       settings_add_int("lookandfeel", "autoclose_query", 0);
+       settings_add_time("lookandfeel", "autoclose_query", "0");
 
        queryclose_tag = -1;
        read_settings();
@@ -346,7 +364,6 @@ void fe_queries_init(void)
        signal_add("query server changed", (SIGNAL_FUNC) signal_query_server_changed);
        signal_add("query nick changed", (SIGNAL_FUNC) signal_query_nick_changed);
         signal_add("window item server changed", (SIGNAL_FUNC) signal_window_item_server_changed);
-       signal_add_last("window item destroy", (SIGNAL_FUNC) signal_window_item_destroy);
        signal_add("server connected", (SIGNAL_FUNC) sig_server_connected);
        signal_add("window changed", (SIGNAL_FUNC) sig_window_changed);
        signal_add_first("message private", (SIGNAL_FUNC) sig_message_private);
@@ -368,7 +385,6 @@ void fe_queries_deinit(void)
        signal_remove("query server changed", (SIGNAL_FUNC) signal_query_server_changed);
        signal_remove("query nick changed", (SIGNAL_FUNC) signal_query_nick_changed);
         signal_remove("window item server changed", (SIGNAL_FUNC) signal_window_item_server_changed);
-       signal_remove("window item destroy", (SIGNAL_FUNC) signal_window_item_destroy);
        signal_remove("server connected", (SIGNAL_FUNC) sig_server_connected);
        signal_remove("window changed", (SIGNAL_FUNC) sig_window_changed);
        signal_remove("message private", (SIGNAL_FUNC) sig_message_private);