diff options
Diffstat (limited to 'src/ui')
-rw-r--r-- | src/ui/console.c | 8 | ||||
-rw-r--r-- | src/ui/ui.h | 8 | ||||
-rw-r--r-- | src/ui/vcardwin.c | 75 | ||||
-rw-r--r-- | src/ui/win_types.h | 12 | ||||
-rw-r--r-- | src/ui/window.c | 189 | ||||
-rw-r--r-- | src/ui/window_list.c | 33 | ||||
-rw-r--r-- | src/ui/window_list.h | 2 |
7 files changed, 326 insertions, 1 deletions
diff --git a/src/ui/console.c b/src/ui/console.c index 822e6d3e..e7b656f5 100644 --- a/src/ui/console.c +++ b/src/ui/console.c @@ -1517,6 +1517,10 @@ cons_time_setting(void) char* pref_time_lastactivity = prefs_get_string(PREF_TIME_LASTACTIVITY); cons_show("Time last activity (/time) : %s", pref_time_lastactivity); g_free(pref_time_lastactivity); + + char* pref_time_vcard = prefs_get_string(PREF_TIME_VCARD); + cons_show("Time vCard (/time) : %s", pref_time_vcard); + g_free(pref_time_vcard); } void @@ -2262,6 +2266,10 @@ cons_executable_setting(void) gchar* editor = prefs_get_string(PREF_COMPOSE_EDITOR); cons_show("Default '/editor' command (/executable editor) : %s", editor); g_free(editor); + + gchar* vcard_cmd = prefs_get_string(PREF_VCARD_PHOTO_CMD); + cons_show("Default '/vcard photo open' command (/executable vcard_photo) : %s", vcard_cmd); + g_free(vcard_cmd); } void diff --git a/src/ui/ui.h b/src/ui/ui.h index a3377690..78632aa0 100644 --- a/src/ui/ui.h +++ b/src/ui/ui.h @@ -230,6 +230,11 @@ char* confwin_get_string(ProfConfWin* confwin); void xmlwin_show(ProfXMLWin* xmlwin, const char* const msg); char* xmlwin_get_string(ProfXMLWin* xmlwin); +// vCard window +void vcardwin_show_vcard_config(ProfVcardWin* vcardwin); +char* vcardwin_get_string(ProfVcardWin* vcardwin); +void vcardwin_update(void); + // Input window char* inp_readline(void); void inp_nonblocking(gboolean reset); @@ -371,6 +376,7 @@ ProfWin* win_create_muc(const char* const roomjid); ProfWin* win_create_config(const char* const title, DataForm* form, ProfConfWinCallback submit, ProfConfWinCallback cancel, const void* userdata); ProfWin* win_create_private(const char* const fulljid); ProfWin* win_create_plugin(const char* const plugin_name, const char* const tag); +ProfWin* win_create_vcard(vCard* vcard); void win_update_virtual(ProfWin* window); void win_free(ProfWin* window); gboolean win_notify_remind(ProfWin* window); @@ -396,6 +402,8 @@ void win_show_occupant(ProfWin* window, Occupant* occupant); void win_show_occupant_info(ProfWin* window, const char* const room, Occupant* occupant); void win_show_contact(ProfWin* window, PContact contact); void win_show_info(ProfWin* window, PContact contact); +void win_show_vcard(ProfWin* window, vCard* vcard); + void win_clear(ProfWin* window); char* win_get_tab_identifier(ProfWin* window); char* win_to_string(ProfWin* window); diff --git a/src/ui/vcardwin.c b/src/ui/vcardwin.c new file mode 100644 index 00000000..a49f240c --- /dev/null +++ b/src/ui/vcardwin.c @@ -0,0 +1,75 @@ +/* + * vcardwin.c + * vim: expandtab:ts=4:sts=4:sw=4 + * + * Copyright (C) 2022 Marouane L. <techmetx11@disroot.org> + * + * This file is part of Profanity. + * + * Profanity 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 3 of the License, or + * (at your option) any later version. + * + * Profanity 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 Profanity. If not, see <https://www.gnu.org/licenses/>. + * + * In addition, as a special exception, the copyright holders give permission to + * link the code of portions of this program with the OpenSSL library under + * certain conditions as described in each individual source file, and + * distribute linked combinations including the two. + * + * You must obey the GNU General Public License in all respects for all of the + * code used other than OpenSSL. If you modify file(s) with this exception, you + * may extend this exception to your version of the file(s), but you are not + * obligated to do so. If you do not wish to do so, delete this exception + * statement from your version. If you delete this exception statement from all + * source files in the program, then also delete it here. + * + */ + +#include "ui/ui.h" +#include "ui/window_list.h" +#include "xmpp/vcard.h" + +void +vcardwin_show_vcard_config(ProfVcardWin* vcardwin) +{ + ProfWin* window = &vcardwin->window; + + win_clear(window); + win_show_vcard(window, vcardwin->vcard); + + win_println(window, THEME_DEFAULT, "-", "Use '/vcard save' to save changes."); + win_println(window, THEME_DEFAULT, "-", "Use '/help vcard' for more information."); +} + +char* +vcardwin_get_string(ProfVcardWin* vcardwin) +{ + GString* string = g_string_new("vCard: "); + char* jid = connection_get_barejid(); + g_string_append(string, jid); + + if (vcardwin->vcard && vcardwin->vcard->modified) { + g_string_append(string, " (modified)"); + } + + free(jid); + return g_string_free(string, FALSE); +} + +void +vcardwin_update(void) +{ + ProfVcardWin* win = wins_get_vcard(); + + if (win) { + vcardwin_show_vcard_config(win); + } +} diff --git a/src/ui/win_types.h b/src/ui/win_types.h index 70d226b0..b7cd3519 100644 --- a/src/ui/win_types.h +++ b/src/ui/win_types.h @@ -52,6 +52,7 @@ #include "tools/autocomplete.h" #include "ui/buffer.h" #include "xmpp/chat_state.h" +#include "xmpp/vcard.h" #define LAYOUT_SPLIT_MEMCHECK 12345671 #define PROFCHATWIN_MEMCHECK 22374522 @@ -60,6 +61,7 @@ #define PROFCONFWIN_MEMCHECK 64334685 #define PROFXMLWIN_MEMCHECK 87333463 #define PROFPLUGINWIN_MEMCHECK 43434777 +#define PROFVCARDWIN_MEMCHECK 68947523 typedef enum { FIELD_HIDDEN, @@ -140,7 +142,8 @@ typedef enum { WIN_CONFIG, WIN_PRIVATE, WIN_XML, - WIN_PLUGIN + WIN_PLUGIN, + WIN_VCARD } win_type_t; typedef struct prof_win_t @@ -239,4 +242,11 @@ typedef struct prof_plugin_win_t unsigned long memcheck; } ProfPluginWin; +typedef struct prof_vcard_win_t +{ + ProfWin window; + vCard* vcard; + unsigned long memcheck; +} ProfVcardWin; + #endif diff --git a/src/ui/window.c b/src/ui/window.c index e25002d6..fbff3374 100644 --- a/src/ui/window.c +++ b/src/ui/window.c @@ -281,6 +281,19 @@ win_create_plugin(const char* const plugin_name, const char* const tag) return &new_win->window; } +ProfWin* +win_create_vcard(vCard* vcard) +{ + ProfVcardWin* new_win = malloc(sizeof(ProfVcardWin)); + new_win->window.type = WIN_VCARD; + new_win->window.layout = _win_create_simple_layout(); + + new_win->vcard = vcard; + new_win->memcheck = PROFVCARDWIN_MEMCHECK; + + return &new_win->window; +} + char* win_get_title(ProfWin* window) { @@ -351,7 +364,22 @@ win_get_title(ProfWin* window) assert(pluginwin->memcheck == PROFPLUGINWIN_MEMCHECK); return strdup(pluginwin->tag); } + if (window->type == WIN_VCARD) { + ProfVcardWin* vcardwin = (ProfVcardWin*)window; + assert(vcardwin->memcheck == PROFVCARDWIN_MEMCHECK); + + GString* title = g_string_new("vCard "); + char* jid = connection_get_barejid(); + + g_string_append(title, jid); + + if (vcardwin->vcard->modified) { + g_string_append(title, " *"); + } + free(jid); + return g_string_free(title, FALSE); + } return NULL; } @@ -474,6 +502,11 @@ win_to_string(ProfWin* window) g_string_free(gstring, FALSE); return res; } + case WIN_VCARD: + { + ProfVcardWin* vcardwin = (ProfVcardWin*)window; + return vcardwin_get_string(vcardwin); + } default: return NULL; } @@ -1083,6 +1116,162 @@ win_show_info(ProfWin* window, PContact contact) } void +win_show_vcard(ProfWin* window, vCard* vcard) +{ + GList* pointer; + int index = 0; + + if (vcard->fullname) { + win_println(window, THEME_DEFAULT, "!", "Full name: %s", vcard->fullname); + } + if (vcard->name.family || vcard->name.given || vcard->name.middle || vcard->name.prefix || vcard->name.suffix) { + win_println(window, THEME_DEFAULT, "!", "Name: "); + if (vcard->name.family) { + win_println(window, THEME_DEFAULT, "!", " Family: %s", vcard->name.family); + } + if (vcard->name.given) { + win_println(window, THEME_DEFAULT, "!", " Given: %s", vcard->name.given); + } + if (vcard->name.middle) { + win_println(window, THEME_DEFAULT, "!", " Middle: %s", vcard->name.middle); + } + if (vcard->name.prefix) { + win_println(window, THEME_DEFAULT, "!", " Prefix: %s", vcard->name.prefix); + } + if (vcard->name.suffix) { + win_println(window, THEME_DEFAULT, "!", " Suffix: %s", vcard->name.suffix); + } + } + index = 0; + for (pointer = g_queue_peek_head_link(vcard->elements); pointer != NULL; pointer = pointer->next, index++) { + assert(pointer->data != NULL); + vcard_element_t* element = (vcard_element_t*)pointer->data; + + switch (element->type) { + case VCARD_NICKNAME: + { + win_println(window, THEME_DEFAULT, "!", "[%d] Nickname: %s", index, element->nickname); + break; + } + case VCARD_PHOTO: + { + if (element->photo.external) { + win_println(window, THEME_DEFAULT, "!", "[%d] Photo, External value: %s", index, element->photo.extval); + } else { + win_println(window, THEME_DEFAULT, "!", "[%d] Photo (%s), size: %zu", index, element->photo.type, element->photo.length); + } + break; + } + case VCARD_BIRTHDAY: + { + char* date_format = prefs_get_string(PREF_TIME_VCARD); + gchar* date = g_date_time_format(element->birthday, date_format); + g_free(date_format); + + assert(date != NULL); + win_println(window, THEME_DEFAULT, "!", "[%d] Birthday: %s", index, date); + g_free(date); + break; + } + case VCARD_ADDRESS: + { + // Print the header with flags + win_println(window, THEME_DEFAULT, "!", "[%d] Address%s%s%s%s%s%s%s", index, + (element->address.options & VCARD_HOME) ? " [home]" : "", + (element->address.options & VCARD_WORK) == VCARD_WORK ? " [work]" : "", + (element->address.options & VCARD_POSTAL) == VCARD_POSTAL ? " [postal]" : "", + (element->address.options & VCARD_PARCEL) == VCARD_PARCEL ? " [parcel]" : "", + (element->address.options & VCARD_INTL) == VCARD_INTL ? " [international]" : "", + (element->address.options & VCARD_DOM) == VCARD_DOM ? " [domestic]" : "", + (element->address.options & VCARD_PREF) == VCARD_PREF ? " [preferred]" : ""); + + if (element->address.pobox) { + win_println(window, THEME_DEFAULT, "!", " P.O. Box: %s", element->address.pobox); + } + if (element->address.extaddr) { + win_println(window, THEME_DEFAULT, "!", " Extended address: %s", element->address.extaddr); + } + if (element->address.street) { + win_println(window, THEME_DEFAULT, "!", " Street: %s", element->address.street); + } + if (element->address.locality) { + win_println(window, THEME_DEFAULT, "!", " Locality: %s", element->address.locality); + } + if (element->address.region) { + win_println(window, THEME_DEFAULT, "!", " Region: %s", element->address.region); + } + if (element->address.pcode) { + win_println(window, THEME_DEFAULT, "!", " Postal code: %s", element->address.pcode); + } + if (element->address.country) { + win_println(window, THEME_DEFAULT, "!", " Country: %s", element->address.country); + } + break; + } + case VCARD_TELEPHONE: + { + // Print the header with flags + win_println(window, THEME_DEFAULT, "!", "[%d] Telephone%s%s%s%s%s%s%s%s%s%s%s%s%s", index, + (element->telephone.options & VCARD_HOME) ? " [home]" : "", + (element->telephone.options & VCARD_WORK) == VCARD_WORK ? " [work]" : "", + (element->telephone.options & VCARD_TEL_VOICE) == VCARD_TEL_VOICE ? " [voice]" : "", + (element->telephone.options & VCARD_TEL_FAX) == VCARD_TEL_FAX ? " [fax]" : "", + (element->telephone.options & VCARD_TEL_PAGER) == VCARD_TEL_PAGER ? " [pager]" : "", + (element->telephone.options & VCARD_TEL_MSG) == VCARD_TEL_MSG ? " [msg]" : "", + (element->telephone.options & VCARD_TEL_CELL) == VCARD_TEL_CELL ? " [cell]" : "", + (element->telephone.options & VCARD_TEL_VIDEO) == VCARD_TEL_VIDEO ? " [video]" : "", + (element->telephone.options & VCARD_TEL_BBS) == VCARD_TEL_BBS ? " [bbs]" : "", + (element->telephone.options & VCARD_TEL_MODEM) == VCARD_TEL_MODEM ? " [modem]" : "", + (element->telephone.options & VCARD_TEL_ISDN) == VCARD_TEL_ISDN ? " [isdn]" : "", + (element->telephone.options & VCARD_TEL_PCS) == VCARD_TEL_PCS ? " [pcs]" : "", + (element->telephone.options & VCARD_PREF) == VCARD_PREF ? " [preferred]" : ""); + if (element->telephone.number) { + win_println(window, THEME_DEFAULT, "!", " Number: %s", element->telephone.number); + } + break; + } + case VCARD_EMAIL: + { + // Print the header with flags + win_println(window, THEME_DEFAULT, "!", "[%d] E-mail%s%s%s%s%s", index, + (element->email.options & VCARD_HOME) ? " [home]" : "", + (element->email.options & VCARD_WORK) == VCARD_WORK ? " [work]" : "", + (element->email.options & VCARD_EMAIL_X400) == VCARD_EMAIL_X400 ? " [x400]" : "", + (element->email.options & VCARD_EMAIL_INTERNET) == VCARD_EMAIL_INTERNET ? " [internet]" : "", + (element->email.options & VCARD_PREF) == VCARD_PREF ? " [preferred]" : ""); + if (element->email.userid) { + win_println(window, THEME_DEFAULT, "!", " ID: %s", element->email.userid); + } + break; + } + case VCARD_JID: + { + win_println(window, THEME_DEFAULT, "!", "[%d] Jabber ID: %s", index, element->jid); + break; + } + case VCARD_TITLE: + { + win_println(window, THEME_DEFAULT, "!", "[%d] Title: %s", index, element->title); + break; + } + case VCARD_ROLE: + { + win_println(window, THEME_DEFAULT, "!", "[%d] Role: %s", index, element->role); + break; + } + case VCARD_NOTE: + { + win_println(window, THEME_DEFAULT, "!", "[%d] Note: %s", index, element->note); + break; + } + case VCARD_URL: + win_println(window, THEME_DEFAULT, "!", "[%d] URL: %s", index, element->url); + break; + } + } +} + +void win_show_status_string(ProfWin* window, const char* const from, const char* const show, const char* const status, GDateTime* last_activity, const char* const pre, diff --git a/src/ui/window_list.c b/src/ui/window_list.c index 56370bca..cdb87de4 100644 --- a/src/ui/window_list.c +++ b/src/ui/window_list.c @@ -711,6 +711,18 @@ wins_new_plugin(const char* const plugin_name, const char* const tag) return newwin; } +ProfWin* +wins_new_vcard(vCard* vcard) +{ + GList* keys = g_hash_table_get_keys(windows); + int result = _wins_get_next_available_num(keys); + g_list_free(keys); + ProfWin* newwin = win_create_vcard(vcard); + g_hash_table_insert(windows, GINT_TO_POINTER(result), newwin); + + return newwin; +} + gboolean wins_do_notify_remind(void) { @@ -805,6 +817,27 @@ wins_get_xmlconsole(void) return NULL; } +ProfVcardWin* +wins_get_vcard(void) +{ + GList* values = g_hash_table_get_values(windows); + GList* curr = values; + + while (curr) { + ProfWin* window = curr->data; + if (window->type == WIN_VCARD) { + ProfVcardWin* vcardwin = (ProfVcardWin*)window; + assert(vcardwin->memcheck == PROFVCARDWIN_MEMCHECK); + g_list_free(values); + return vcardwin; + } + curr = g_list_next(curr); + } + + g_list_free(values); + return NULL; +} + GSList* wins_get_chat_recipients(void) { diff --git a/src/ui/window_list.h b/src/ui/window_list.h index bcb18d14..788248b9 100644 --- a/src/ui/window_list.h +++ b/src/ui/window_list.h @@ -46,6 +46,7 @@ ProfWin* wins_new_muc(const char* const roomjid); ProfWin* wins_new_config(const char* const roomjid, DataForm* form, ProfConfWinCallback submit, ProfConfWinCallback cancel, const void* userdata); ProfWin* wins_new_private(const char* const fulljid); ProfWin* wins_new_plugin(const char* const plugin_name, const char* const tag); +ProfWin* wins_new_vcard(vCard* vcard); gboolean wins_chat_exists(const char* const barejid); GList* wins_get_private_chats(const char* const roomjid); @@ -61,6 +62,7 @@ ProfConfWin* wins_get_conf(const char* const roomjid); ProfPrivateWin* wins_get_private(const char* const fulljid); ProfPluginWin* wins_get_plugin(const char* const tag); ProfXMLWin* wins_get_xmlconsole(void); +ProfVcardWin* wins_get_vcard(void); void wins_close_plugin(char* tag); |