about summary refs log tree commit diff stats
path: root/src/ui/window.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ui/window.c')
-rw-r--r--src/ui/window.c216
1 files changed, 168 insertions, 48 deletions
diff --git a/src/ui/window.c b/src/ui/window.c
index 53dc9d02..c1624a50 100644
--- a/src/ui/window.c
+++ b/src/ui/window.c
@@ -1,7 +1,7 @@
 /*
  * window.c
  *
- * Copyright (C) 2012 - 2016 James Booth <boothj5@gmail.com>
+ * Copyright (C) 2012 - 2019 James Booth <boothj5@gmail.com>
  *
  * This file is part of Profanity.
  *
@@ -143,9 +143,13 @@ win_create_chat(const char *const barejid)
     new_win->otr_is_trusted = FALSE;
     new_win->pgp_recv = FALSE;
     new_win->pgp_send = FALSE;
+    new_win->is_omemo = FALSE;
     new_win->history_shown = FALSE;
     new_win->unread = 0;
     new_win->state = chat_state_new();
+    new_win->enctext = NULL;
+    new_win->incoming_char = NULL;
+    new_win->outgoing_char = NULL;
 
     new_win->memcheck = PROFCHATWIN_MEMCHECK;
 
@@ -159,7 +163,7 @@ win_create_muc(const char *const roomjid)
     int cols = getmaxx(stdscr);
 
     new_win->window.type = WIN_MUC;
-
+    new_win->window.layout = _win_create_simple_layout();
     ProfLayoutSplit *layout = malloc(sizeof(ProfLayoutSplit));
     layout->base.type = LAYOUT_SPLIT;
 
@@ -191,6 +195,10 @@ win_create_muc(const char *const roomjid)
     } else {
         new_win->showjid = FALSE;
     }
+    new_win->enctext = NULL;
+    new_win->message_char = NULL;
+    new_win->is_omemo = FALSE;
+    new_win->sent_messages = g_hash_table_new_full(g_str_hash, g_str_equal, free, NULL);
 
     new_win->memcheck = PROFMUCWIN_MEMCHECK;
 
@@ -198,14 +206,16 @@ win_create_muc(const char *const roomjid)
 }
 
 ProfWin*
-win_create_muc_config(const char *const roomjid, DataForm *form)
+win_create_config(const char *const roomjid, DataForm *form, ProfConfWinCallback submit, ProfConfWinCallback cancel, const void *userdata)
 {
-    ProfMucConfWin *new_win = malloc(sizeof(ProfMucConfWin));
-    new_win->window.type = WIN_MUC_CONFIG;
+    ProfConfWin *new_win = malloc(sizeof(ProfConfWin));
+    new_win->window.type = WIN_CONFIG;
     new_win->window.layout = _win_create_simple_layout();
-
     new_win->roomjid = strdup(roomjid);
     new_win->form = form;
+    new_win->submit = submit;
+    new_win->cancel = cancel;
+    new_win->userdata = userdata;
 
     new_win->memcheck = PROFCONFWIN_MEMCHECK;
 
@@ -218,7 +228,6 @@ win_create_private(const char *const fulljid)
     ProfPrivateWin *new_win = malloc(sizeof(ProfPrivateWin));
     new_win->window.type = WIN_PRIVATE;
     new_win->window.layout = _win_create_simple_layout();
-
     new_win->fulljid = strdup(fulljid);
     new_win->unread = 0;
     new_win->occupant_offline = FALSE;
@@ -245,15 +254,15 @@ ProfWin*
 win_create_plugin(const char *const plugin_name, const char *const tag)
 {
     ProfPluginWin *new_win = malloc(sizeof(ProfPluginWin));
-    new_win->super.type = WIN_PLUGIN;
-    new_win->super.layout = _win_create_simple_layout();
+    new_win->window.type = WIN_PLUGIN;
+    new_win->window.layout = _win_create_simple_layout();
 
     new_win->tag = strdup(tag);
     new_win->plugin_name = strdup(plugin_name);
 
     new_win->memcheck = PROFPLUGINWIN_MEMCHECK;
 
-    return &new_win->super;
+    return &new_win->window;
 }
 
 char*
@@ -286,8 +295,8 @@ win_get_title(ProfWin *window)
         assert(mucwin->memcheck == PROFMUCWIN_MEMCHECK);
         return strdup(mucwin->roomjid);
     }
-    if (window->type == WIN_MUC_CONFIG) {
-        ProfMucConfWin *confwin = (ProfMucConfWin*) window;
+    if (window->type == WIN_CONFIG) {
+        ProfConfWin *confwin = (ProfConfWin*) window;
         assert(confwin->memcheck == PROFCONFWIN_MEMCHECK);
         GString *title = g_string_new(confwin->roomjid);
         g_string_append(title, " config");
@@ -316,6 +325,50 @@ win_get_title(ProfWin *window)
 }
 
 char*
+win_get_tab_identifier(ProfWin *window)
+{
+    assert(window != NULL);
+
+    switch (window->type) {
+        case WIN_CONSOLE:
+        {
+            return strdup("console");
+        }
+        case WIN_CHAT:
+        {
+            ProfChatWin *chatwin = (ProfChatWin*)window;
+            return strdup(chatwin->barejid);
+        }
+        case WIN_MUC:
+        {
+            ProfMucWin *mucwin = (ProfMucWin*)window;
+            return strdup(mucwin->roomjid);
+        }
+        case WIN_CONFIG:
+        {
+            ProfConfWin *confwin = (ProfConfWin*)window;
+            return strdup(confwin->roomjid);
+        }
+        case WIN_PRIVATE:
+        {
+            ProfPrivateWin *privwin = (ProfPrivateWin*)window;
+            return strdup(privwin->fulljid);
+        }
+        case WIN_PLUGIN:
+        {
+            ProfPluginWin *pluginwin = (ProfPluginWin*)window;
+            return strdup(pluginwin->tag);
+        }
+        case WIN_XML:
+        {
+            return strdup("xmlconsole");
+        }
+        default:
+            return strdup("UNKNOWN");
+    }
+}
+
+char*
 win_to_string(ProfWin *window)
 {
     assert(window != NULL);
@@ -336,10 +389,10 @@ win_to_string(ProfWin *window)
             ProfMucWin *mucwin = (ProfMucWin*)window;
             return mucwin_get_string(mucwin);
         }
-        case WIN_MUC_CONFIG:
+        case WIN_CONFIG:
         {
-            ProfMucConfWin *mucconfwin = (ProfMucConfWin*)window;
-            return mucconfwin_get_string(mucconfwin);
+            ProfConfWin *confwin = (ProfConfWin*)window;
+            return confwin_get_string(confwin);
         }
         case WIN_PRIVATE:
         {
@@ -430,6 +483,9 @@ win_free(ProfWin* window)
         ProfChatWin *chatwin = (ProfChatWin*)window;
         free(chatwin->barejid);
         free(chatwin->resource_override);
+        free(chatwin->enctext);
+        free(chatwin->incoming_char);
+        free(chatwin->outgoing_char);
         chat_state_free(chatwin->state);
         break;
     }
@@ -437,13 +493,15 @@ win_free(ProfWin* window)
     {
         ProfMucWin *mucwin = (ProfMucWin*)window;
         free(mucwin->roomjid);
+        free(mucwin->enctext);
+        free(mucwin->message_char);
         break;
     }
-    case WIN_MUC_CONFIG:
+    case WIN_CONFIG:
     {
-        ProfMucConfWin *mucconf = (ProfMucConfWin*)window;
-        free(mucconf->roomjid);
-        form_destroy(mucconf->form);
+        ProfConfWin *conf = (ProfConfWin*)window;
+        free(conf->roomjid);
+        form_destroy(conf->form);
         break;
     }
     case WIN_PRIVATE:
@@ -994,23 +1052,34 @@ win_show_status_string(ProfWin *window, const char *const from,
 }
 
 void
-win_print_incoming(ProfWin *window, GDateTime *timestamp,
-    const char *const from, const char *const message, prof_enc_t enc_mode)
+win_print_incoming(ProfWin *window, const char *const from, ProfMessage *message)
 {
     char enc_char = '-';
+    int flags = NO_ME;
+
+    if (!message->trusted) {
+        flags |= UNTRUSTED;
+    }
 
     switch (window->type)
     {
         case WIN_CHAT:
-            if (enc_mode == PROF_MSG_OTR) {
+        {
+            ProfChatWin *chatwin = (ProfChatWin*)window;
+            if (chatwin->incoming_char) {
+                enc_char = chatwin->incoming_char[0];
+            } else if (message->enc == PROF_MSG_ENC_OTR) {
                 enc_char = prefs_get_otr_char();
-            } else if (enc_mode == PROF_MSG_PGP) {
+            } else if (message->enc == PROF_MSG_ENC_PGP) {
                 enc_char = prefs_get_pgp_char();
+            } else if (message->enc == PROF_MSG_ENC_OMEMO) {
+                enc_char = prefs_get_omemo_char();
             }
-            _win_printf(window, enc_char, 0, timestamp, NO_ME, THEME_TEXT_THEM, from, "%s", message);
+            _win_printf(window, enc_char, 0, message->timestamp, flags, THEME_TEXT_THEM, from, "%s", message->plain);
             break;
+        }
         case WIN_PRIVATE:
-            _win_printf(window, '-', 0, timestamp, NO_ME, THEME_TEXT_THEM, from, "%s", message);
+            _win_printf(window, '-', 0, message->timestamp, flags, THEME_TEXT_THEM, from, "%s", message->plain);
             break;
         default:
             assert(FALSE);
@@ -1019,13 +1088,13 @@ win_print_incoming(ProfWin *window, GDateTime *timestamp,
 }
 
 void
-win_print_them(ProfWin *window, theme_item_t theme_item, const char *const them)
+win_print_them(ProfWin *window, theme_item_t theme_item, char ch, int flags, const char *const them)
 {
-    _win_printf(window, '-', 0, NULL, NO_ME | NO_EOL, theme_item, them, "");
+    _win_printf(window, ch, 0, NULL, flags | NO_ME | NO_EOL, theme_item, them, "");
 }
 
 void
-win_println_them_message(ProfWin *window, const char *const them, const char *const message, ...)
+win_println_them_message(ProfWin *window, char ch, int flags, const char *const them, const char *const message, ...)
 {
     GDateTime *timestamp = g_date_time_new_now_local();
 
@@ -1034,9 +1103,9 @@ win_println_them_message(ProfWin *window, const char *const them, const char *co
     GString *fmt_msg = g_string_new(NULL);
     g_string_vprintf(fmt_msg, message, arg);
 
-    buffer_append(window->layout->buffer, '-', 0, timestamp, NO_ME, THEME_TEXT_THEM, them, fmt_msg->str, NULL);
+    buffer_append(window->layout->buffer, ch, 0, timestamp, flags | NO_ME, THEME_TEXT_THEM, them, fmt_msg->str, NULL);
 
-    _win_print(window, '-', 0, timestamp, NO_ME, THEME_TEXT_THEM, them, fmt_msg->str, NULL);
+    _win_print(window, ch, 0, timestamp, flags | NO_ME, THEME_TEXT_THEM, them, fmt_msg->str, NULL);
     inp_nonblocking(TRUE);
     g_date_time_unref(timestamp);
 
@@ -1045,7 +1114,7 @@ win_println_them_message(ProfWin *window, const char *const them, const char *co
 }
 
 void
-win_println_me_message(ProfWin *window, const char *const me, const char *const message, ...)
+win_println_me_message(ProfWin *window, char ch, const char *const me, const char *const message, ...)
 {
     GDateTime *timestamp = g_date_time_new_now_local();
 
@@ -1054,9 +1123,9 @@ win_println_me_message(ProfWin *window, const char *const me, const char *const
     GString *fmt_msg = g_string_new(NULL);
     g_string_vprintf(fmt_msg, message, arg);
 
-    buffer_append(window->layout->buffer, '-', 0, timestamp, 0, THEME_TEXT_ME, me, fmt_msg->str, NULL);
+    buffer_append(window->layout->buffer, ch, 0, timestamp, 0, THEME_TEXT_ME, me, fmt_msg->str, NULL);
 
-    _win_print(window, '-', 0, timestamp, 0, THEME_TEXT_ME, me, fmt_msg->str, NULL);
+    _win_print(window, ch, 0, timestamp, 0, THEME_TEXT_ME, me, fmt_msg->str, NULL);
     inp_nonblocking(TRUE);
     g_date_time_unref(timestamp);
 
@@ -1094,9 +1163,9 @@ win_print_history(ProfWin *window, GDateTime *timestamp, const char *const messa
     GString *fmt_msg = g_string_new(NULL);
     g_string_vprintf(fmt_msg, message, arg);
 
-    buffer_append(window->layout->buffer, '-', 0, timestamp, NO_COLOUR_DATE, THEME_DEFAULT, "", fmt_msg->str, NULL);
+    buffer_append(window->layout->buffer, '-', 0, timestamp, 0, THEME_TEXT_HISTORY, "", fmt_msg->str, NULL);
+    _win_print(window, '-', 0, timestamp, 0, THEME_TEXT_HISTORY, "", fmt_msg->str, NULL);
 
-    _win_print(window, '-', 0, timestamp, NO_COLOUR_DATE, THEME_DEFAULT, "", fmt_msg->str, NULL);
     inp_nonblocking(TRUE);
     g_date_time_unref(timestamp);
 
@@ -1288,16 +1357,6 @@ win_update_entry_message(ProfWin *window, const char *const id, const char *cons
 }
 
 void
-win_update_entry_theme(ProfWin *window, const char *const id, theme_item_t theme_item)
-{
-    ProfBuffEntry *entry = buffer_get_entry_by_id(window->layout->buffer, id);
-    if (entry) {
-        entry->theme_item = theme_item;
-        win_redraw(window);
-    }
-}
-
-void
 win_newline(ProfWin *window)
 {
     win_appendln(window, THEME_DEFAULT, "");
@@ -1337,6 +1396,7 @@ _win_print(ProfWin *window, const char show_char, int pad_indent, GDateTime *tim
     //         3rd bit =  0/1 - eol/no eol
     //         4th bit =  0/1 - color from/no color from
     //         5th bit =  0/1 - color date/no date
+    //         6th bit =  0/1 - trusted/untrusted
     gboolean me_message = FALSE;
     int offset = 0;
     int colour = theme_attrs(THEME_ME);
@@ -1350,8 +1410,8 @@ _win_print(ProfWin *window, const char show_char, int pad_indent, GDateTime *tim
         case WIN_MUC:
             time_pref = prefs_get_string(PREF_TIME_MUC);
             break;
-        case WIN_MUC_CONFIG:
-            time_pref = prefs_get_string(PREF_TIME_MUCCONFIG);
+        case WIN_CONFIG:
+            time_pref = prefs_get_string(PREF_TIME_CONFIG);
             break;
         case WIN_PRIVATE:
             time_pref = prefs_get_string(PREF_TIME_PRIVATE);
@@ -1419,6 +1479,9 @@ _win_print(ProfWin *window, const char show_char, int pad_indent, GDateTime *tim
         if (receipt && !receipt->received) {
             wbkgdset(window->layout->win, theme_attrs(THEME_RECEIPT_SENT));
             wattron(window->layout->win, theme_attrs(THEME_RECEIPT_SENT));
+        } else if (flags & UNTRUSTED) {
+            wbkgdset(window->layout->win, theme_attrs(THEME_UNTRUSTED));
+            wattron(window->layout->win, theme_attrs(THEME_UNTRUSTED));
         } else {
             wbkgdset(window->layout->win, theme_attrs(theme_item));
             wattron(window->layout->win, theme_attrs(theme_item));
@@ -1502,7 +1565,7 @@ _win_print_wrapped(WINDOW *win, const char *const message, size_t indent, int pa
             wordlen = utf8_display_len(word);
 
             int curx = getcurx(win);
-            int cury = getcury(win);
+            int cury;
             int maxx = getmaxx(win);
 
             // wrap required
@@ -1685,3 +1748,60 @@ win_sub_newline_lazy(WINDOW *win)
         wmove(win, cury+1, 0);
     }
 }
+
+void
+win_command_list_error(ProfWin *window, const char *const error)
+{
+    assert(window != NULL);
+
+    win_println(window, THEME_ERROR, '!', "Error retrieving command list: %s", error);
+}
+
+void
+win_command_exec_error(ProfWin *window, const char *const command, const char *const error, ...)
+{
+    assert(window != NULL);
+    va_list arg;
+    va_start(arg, error);
+    GString *msg = g_string_new(NULL);
+    g_string_vprintf(msg, error, arg);
+
+    win_println(window, THEME_ERROR, '!', "Error executing command %s: %s", command, msg->str);
+
+    g_string_free(msg, TRUE);
+    va_end(arg);
+}
+
+void
+win_handle_command_list(ProfWin *window, GSList *cmds)
+{
+    assert(window != NULL);
+
+    if (cmds) {
+        win_println(window, THEME_DEFAULT, '!', "Ad hoc commands:");
+        GSList *curr_cmd = cmds;
+        while (curr_cmd) {
+            const char *cmd = curr_cmd->data;
+            win_println(window, THEME_DEFAULT, '!', "  %s", cmd);
+            curr_cmd = g_slist_next(curr_cmd);
+        }
+        win_println(window, THEME_DEFAULT, '!', "");
+    } else {
+        win_println(window, THEME_DEFAULT, '!', "No commands found");
+        win_println(window, THEME_DEFAULT, '!', "");
+    }
+}
+
+void
+win_handle_command_exec_status(ProfWin *window, const char *const command, const char *const value)
+{
+    assert(window != NULL);
+    win_println(window, THEME_DEFAULT, '!', "%s %s", command, value);
+}
+
+void
+win_handle_command_exec_result_note(ProfWin *window, const char *const type, const char *const value)
+{
+    assert(window != NULL);
+    win_println(window, THEME_DEFAULT, '!', value);
+}