1
0
mirror of https://github.com/profanity-im/profanity.git synced 2024-09-08 19:34:14 -04:00

Merge branch 'master' into otr

This commit is contained in:
James Booth 2013-08-30 00:58:06 +01:00
commit 6b1c7da11f
14 changed files with 1702 additions and 931 deletions

View File

@ -14,6 +14,7 @@ profanity_SOURCES = \
src/ui/ui.h src/ui/window.c src/ui/window.h src/ui/core.c \
src/ui/titlebar.c src/ui/statusbar.c src/ui/inputwin.c \
src/ui/console.c src/ui/notifier.c src/ui/notifier.h \
src/ui/windows.c src/ui/windows.h \
src/command/command.h src/command/command.c src/command/history.c \
src/command/history.h src/tools/parser.c \
src/tools/parser.h \
@ -42,6 +43,7 @@ tests_testsuite_SOURCES = \
src/ui/ui.h src/ui/window.c src/ui/window.h src/ui/core.c \
src/ui/titlebar.c src/ui/statusbar.c src/ui/inputwin.c \
src/ui/console.c src/ui/notifier.c src/ui/notifier.h \
src/ui/windows.c src/ui/windows.h \
src/command/command.h src/command/command.c src/command/history.c \
src/command/history.h src/tools/parser.c \
src/tools/parser.h \

View File

@ -144,6 +144,7 @@ static gboolean _cmd_tiny(gchar **args, struct cmd_help_t help);
static gboolean _cmd_titlebar(gchar **args, struct cmd_help_t help);
static gboolean _cmd_vercheck(gchar **args, struct cmd_help_t help);
static gboolean _cmd_who(gchar **args, struct cmd_help_t help);
static gboolean _cmd_win(gchar **args, struct cmd_help_t help);
static gboolean _cmd_wins(gchar **args, struct cmd_help_t help);
static gboolean _cmd_xa(gchar **args, struct cmd_help_t help);
@ -410,6 +411,14 @@ static struct cmd_t command_defs[] =
"Example : /nick bob",
NULL } } },
{ "/win",
_cmd_win, parse_args, 1, 1, NULL,
{ "/win num", "View a window.",
{ "/win num",
"------------------",
"Show the contents of a specific window in the main window area.",
NULL } } },
{ "/wins",
_cmd_wins, parse_args, 0, 1, NULL,
{ "/wins [tidy|prune]", "List or tidy active windows.",
@ -1196,8 +1205,6 @@ cmd_execute_default(const char * const inp)
break;
}
free(recipient);
return TRUE;
}
@ -1226,7 +1233,6 @@ _cmd_complete_parameters(char *input, int *size)
if (ui_current_win_type() == WIN_MUC) {
char *recipient = ui_current_recipient();
Autocomplete nick_ac = muc_get_roster_ac(recipient);
free(recipient);
if (nick_ac != NULL) {
gchar *nick_choices[] = { "/msg", "/info", "/caps", "/status", "/software" } ;
@ -1559,7 +1565,7 @@ _cmd_sub(gchar **args, struct cmd_help_t help)
return TRUE;
}
char *subcmd, *jid, *bare_jid;
char *subcmd, *jid;
subcmd = args[0];
jid = args[1];
@ -1583,49 +1589,47 @@ _cmd_sub(gchar **args, struct cmd_help_t help)
return TRUE;
}
if (jid != NULL) {
jid = strdup(jid);
} else {
if (jid == NULL) {
jid = ui_current_recipient();
}
bare_jid = strtok(jid, "/");
Jid *jidp = jid_create(jid);
if (strcmp(subcmd, "allow") == 0) {
presence_subscription(bare_jid, PRESENCE_SUBSCRIBED);
cons_show("Accepted subscription for %s", bare_jid);
log_info("Accepted subscription for %s", bare_jid);
presence_subscription(jidp->barejid, PRESENCE_SUBSCRIBED);
cons_show("Accepted subscription for %s", jidp->barejid);
log_info("Accepted subscription for %s", jidp->barejid);
} else if (strcmp(subcmd, "deny") == 0) {
presence_subscription(bare_jid, PRESENCE_UNSUBSCRIBED);
cons_show("Deleted/denied subscription for %s", bare_jid);
log_info("Deleted/denied subscription for %s", bare_jid);
presence_subscription(jidp->barejid, PRESENCE_UNSUBSCRIBED);
cons_show("Deleted/denied subscription for %s", jidp->barejid);
log_info("Deleted/denied subscription for %s", jidp->barejid);
} else if (strcmp(subcmd, "request") == 0) {
presence_subscription(bare_jid, PRESENCE_SUBSCRIBE);
cons_show("Sent subscription request to %s.", bare_jid);
log_info("Sent subscription request to %s.", bare_jid);
presence_subscription(jidp->barejid, PRESENCE_SUBSCRIBE);
cons_show("Sent subscription request to %s.", jidp->barejid);
log_info("Sent subscription request to %s.", jidp->barejid);
} else if (strcmp(subcmd, "show") == 0) {
PContact contact = roster_get_contact(bare_jid);
PContact contact = roster_get_contact(jidp->barejid);
if ((contact == NULL) || (p_contact_subscription(contact) == NULL)) {
if (win_type == WIN_CHAT) {
ui_current_print_line("No subscription information for %s.", bare_jid);
ui_current_print_line("No subscription information for %s.", jidp->barejid);
} else {
cons_show("No subscription information for %s.", bare_jid);
cons_show("No subscription information for %s.", jidp->barejid);
}
} else {
if (win_type == WIN_CHAT) {
if (p_contact_pending_out(contact)) {
ui_current_print_line("%s subscription status: %s, request pending.",
bare_jid, p_contact_subscription(contact));
jidp->barejid, p_contact_subscription(contact));
} else {
ui_current_print_line("%s subscription status: %s.", bare_jid,
ui_current_print_line("%s subscription status: %s.", jidp->barejid,
p_contact_subscription(contact));
}
} else {
if (p_contact_pending_out(contact)) {
cons_show("%s subscription status: %s, request pending.",
bare_jid, p_contact_subscription(contact));
jidp->barejid, p_contact_subscription(contact));
} else {
cons_show("%s subscription status: %s.", bare_jid,
cons_show("%s subscription status: %s.", jidp->barejid,
p_contact_subscription(contact));
}
}
@ -1634,7 +1638,8 @@ _cmd_sub(gchar **args, struct cmd_help_t help)
cons_show("Usage: %s", help.usage);
}
free(jid);
jid_destroy(jidp);
return TRUE;
}
@ -1673,6 +1678,19 @@ _cmd_wins(gchar **args, struct cmd_help_t help)
return TRUE;
}
static gboolean
_cmd_win(gchar **args, struct cmd_help_t help)
{
int num = atoi(args[0]);
if (ui_win_exists(num)) {
ui_switch_win(num);
} else {
cons_show("Window %d does not exist.", num);
}
return TRUE;
}
static
gint _compare_commands(Command *a, Command *b)
{
@ -1833,7 +1851,7 @@ _cmd_about(gchar **args, struct cmd_help_t help)
cons_show("");
cons_about();
if (ui_current_win_type() != WIN_CONSOLE) {
status_bar_new(0);
status_bar_new(1);
}
return TRUE;
}
@ -2016,8 +2034,6 @@ _cmd_who(gchar **args, struct cmd_help_t help)
ui_room_roster(room, filtered, presence);
}
free(room);
// not in groupchat window
} else {
cons_show("");
@ -2137,7 +2153,7 @@ _cmd_who(gchar **args, struct cmd_help_t help)
}
if (win_type != WIN_CONSOLE && win_type != WIN_MUC) {
status_bar_new(0);
status_bar_new(1);
}
return TRUE;
@ -2157,11 +2173,6 @@ _cmd_msg(gchar **args, struct cmd_help_t help)
return TRUE;
}
if (ui_windows_full()) {
cons_show_error("Windows all used, close a window and try again.");
return TRUE;
}
if (win_type == WIN_MUC) {
char *room_name = ui_current_recipient();
if (muc_nick_in_roster(room_name, usr)) {
@ -2182,8 +2193,6 @@ _cmd_msg(gchar **args, struct cmd_help_t help)
ui_current_print_line("No such participant \"%s\" in room.", usr);
}
free(room_name);
return TRUE;
} else {
@ -2421,11 +2430,6 @@ _cmd_duck(gchar **args, struct cmd_help_t help)
return TRUE;
}
if (ui_windows_full()) {
cons_show_error("Windows all used, close a window and try again.");
return TRUE;
}
// if no duck win open, create it and send a help command
if (!ui_duck_exists()) {
ui_create_duck_win();
@ -2581,8 +2585,6 @@ _cmd_info(gchar **args, struct cmd_help_t help)
break;
}
free(recipient);
return TRUE;
}
@ -2611,7 +2613,6 @@ _cmd_caps(gchar **args, struct cmd_help_t help)
} else {
cons_show("No such participant \"%s\" in room.", args[0]);
}
free(recipient);
} else {
cons_show("No nickname supplied to /caps in chat room.");
}
@ -2652,7 +2653,6 @@ _cmd_caps(gchar **args, struct cmd_help_t help)
cons_show_caps(jid->resourcepart, resource);
jid_destroy(jid);
}
free(recipient);
}
break;
default:
@ -2689,7 +2689,6 @@ _cmd_software(gchar **args, struct cmd_help_t help)
} else {
cons_show("No such participant \"%s\" in room.", args[0]);
}
free(recipient);
} else {
cons_show("No nickname supplied to /software in chat room.");
}
@ -2715,7 +2714,6 @@ _cmd_software(gchar **args, struct cmd_help_t help)
} else {
recipient = ui_current_recipient();
iq_send_software_version(recipient);
free(recipient);
}
break;
default:
@ -2735,11 +2733,6 @@ _cmd_join(gchar **args, struct cmd_help_t help)
return TRUE;
}
if (ui_windows_full()) {
cons_show_error("Windows all used, close a window and try again.");
return TRUE;
}
Jid *room_arg = jid_create(args[0]);
if (room_arg == NULL) {
cons_show_error("Specified room has incorrect format");
@ -2887,7 +2880,6 @@ _cmd_bookmark(gchar **args, struct cmd_help_t help)
cons_show_bookmarks(bookmark_get_list());
} else {
gboolean autojoin = FALSE;
gboolean jid_release = FALSE;
gchar *jid = NULL;
gchar *nick = NULL;
int idx = 1;
@ -2913,7 +2905,6 @@ _cmd_bookmark(gchar **args, struct cmd_help_t help)
if (win_type == WIN_MUC) {
jid = ui_current_recipient();
jid_release = TRUE;
nick = muc_get_room_nick(jid);
} else {
cons_show("Usage: %s", help.usage);
@ -2928,10 +2919,6 @@ _cmd_bookmark(gchar **args, struct cmd_help_t help)
} else {
cons_show("Usage: %s", help.usage);
}
if (jid_release) {
free(jid);
}
}
return TRUE;
@ -3024,16 +3011,13 @@ _cmd_tiny(gchar **args, struct cmd_help_t help)
}
ui_outgoing_msg("me", recipient, tiny);
free(recipient);
} else if (win_type == WIN_PRIVATE) {
char *recipient = ui_current_recipient();
message_send(tiny, recipient);
ui_outgoing_msg("me", recipient, tiny);
free(recipient);
} else { // groupchat
char *recipient = ui_current_recipient();
message_send_groupchat(tiny, recipient);
free(recipient);
}
free(tiny);
} else {
@ -3058,21 +3042,12 @@ _cmd_close(gchar **args, struct cmd_help_t help)
{
jabber_conn_status_t conn_status = jabber_get_connection_status();
int index = 0;
int curr = 0;
int count = 0;
if (args[0] == NULL) {
index = ui_current_win_index();
} else if (strcmp(args[0], "all") == 0) {
for (curr = 1; curr <= 9; curr++) {
if (ui_win_exists(curr)) {
if (conn_status == JABBER_CONNECTED) {
ui_close_connected_win(curr);
}
ui_close_win(curr);
count++;
}
}
count = ui_close_all_wins();
if (count == 0) {
cons_show("No windows to close.");
} else if (count == 1) {
@ -3082,15 +3057,7 @@ _cmd_close(gchar **args, struct cmd_help_t help)
}
return TRUE;
} else if (strcmp(args[0], "read") == 0) {
for (curr = 1; curr <= 9; curr++) {
if (ui_win_exists(curr) && (ui_win_unread(curr) == 0)) {
if (conn_status == JABBER_CONNECTED) {
ui_close_connected_win(curr);
}
ui_close_win(curr);
count++;
}
}
count = ui_close_read_wins();
if (count == 0) {
cons_show("No windows to close.");
} else if (count == 1) {
@ -3101,21 +3068,20 @@ _cmd_close(gchar **args, struct cmd_help_t help)
return TRUE;
} else {
index = atoi(args[0]);
if (index == 0) {
index = 9;
} else if (index != 10) {
index--;
}
}
if (index == 0) {
if (index < 0 || index == 10) {
cons_show("No such window exists.");
return TRUE;
}
if (index == 1) {
cons_show("Cannot close console window.");
return TRUE;
}
if (index > 9 || index < 0) {
cons_show("No such window exists.");
return TRUE;
if (index == 0) {
index = 10;
}
if (!ui_win_exists(index)) {
@ -3123,7 +3089,6 @@ _cmd_close(gchar **args, struct cmd_help_t help)
return TRUE;
}
// handle leaving rooms, or chat
if (conn_status == JABBER_CONNECTED) {
ui_close_connected_win(index);
@ -3131,11 +3096,7 @@ _cmd_close(gchar **args, struct cmd_help_t help)
// close the window
ui_close_win(index);
int ui_index = index + 1;
if (ui_index == 10) {
ui_index = 0;
}
cons_show("Closed window %d", ui_index);
cons_show("Closed window %d", index);
return TRUE;
}

View File

@ -399,6 +399,69 @@ get_unique_id(void)
return result;
}
int
cmp_win_num(gconstpointer a, gconstpointer b)
{
int real_a = GPOINTER_TO_INT(a);
int real_b = GPOINTER_TO_INT(b);
if (real_a == 0) {
real_a = 10;
}
if (real_b == 0) {
real_b = 10;
}
if (real_a < real_b) {
return -1;
} else if (real_a == real_b) {
return 0;
} else {
return 1;
}
}
int
get_next_available_win_num(GList *used)
{
int result = 0;
used = g_list_sort(used, cmp_win_num);
// only console used
if (g_list_length(used) == 1) {
return 2;
} else {
int last_num = 1;
GList *curr = used;
// skip console
curr = g_list_next(curr);
while (curr != NULL) {
int curr_num = GPOINTER_TO_INT(curr->data);
if (((last_num != 9) && ((last_num + 1) != curr_num)) ||
((last_num == 9) && (curr_num != 0))) {
result = last_num + 1;
if (result == 10) {
result = 0;
}
return (result);
} else {
last_num = curr_num;
if (last_num == 0) {
last_num = 10;
}
}
curr = g_list_next(curr);
}
result = last_num + 1;
if (result == 10) {
result = 0;
}
return result;
}
}
static size_t
_data_callback(void *ptr, size_t size, size_t nmemb, void *data)
{

View File

@ -91,4 +91,7 @@ contact_presence_t contact_presence_from_resource_presence(resource_presence_t r
char * get_unique_id(void);
int cmp_win_num(gconstpointer a, gconstpointer b);
int get_next_available_win_num(GList *used);
#endif

View File

@ -35,42 +35,34 @@
#include "config/theme.h"
#include "ui/notifier.h"
#include "ui/window.h"
#include "ui/windows.h"
#include "ui/ui.h"
#include "xmpp/xmpp.h"
#include "xmpp/bookmark.h"
#define CONS_WIN_TITLE "_cons"
static ProfWin* console;
static void _cons_splash_logo(void);
void _show_roster_contacts(GSList *list, gboolean show_groups);
ProfWin *
cons_create(void)
{
int cols = getmaxx(stdscr);
console = win_create(CONS_WIN_TITLE, cols, WIN_CONSOLE);
return console;
}
void
cons_show_time(void)
{
ProfWin *console = wins_get_console();
win_print_time(console, '-');
ui_console_dirty();
wins_refresh_console();
}
void
cons_show_word(const char * const word)
{
ProfWin *console = wins_get_console();
wprintw(console->win, "%s", word);
ui_console_dirty();
wins_refresh_console();
}
void
cons_debug(const char * const msg, ...)
{
ProfWin *console = wins_get_console();
if (strcmp(PACKAGE_STATUS, "development") == 0) {
va_list arg;
va_start(arg, msg);
@ -81,7 +73,7 @@ cons_debug(const char * const msg, ...)
g_string_free(fmt_msg, TRUE);
va_end(arg);
ui_console_dirty();
wins_refresh_console();
cons_alert();
ui_current_page_off();
@ -92,6 +84,7 @@ cons_debug(const char * const msg, ...)
void
cons_show(const char * const msg, ...)
{
ProfWin *console = wins_get_console();
va_list arg;
va_start(arg, msg);
GString *fmt_msg = g_string_new(NULL);
@ -100,12 +93,13 @@ cons_show(const char * const msg, ...)
wprintw(console->win, "%s\n", fmt_msg->str);
g_string_free(fmt_msg, TRUE);
va_end(arg);
ui_console_dirty();
wins_refresh_console();
}
void
cons_show_error(const char * const msg, ...)
{
ProfWin *console = wins_get_console();
va_list arg;
va_start(arg, msg);
GString *fmt_msg = g_string_new(NULL);
@ -117,13 +111,14 @@ cons_show_error(const char * const msg, ...)
g_string_free(fmt_msg, TRUE);
va_end(arg);
ui_console_dirty();
wins_refresh_console();
cons_alert();
}
void
cons_show_typing(const char * const barejid)
{
ProfWin *console = wins_get_console();
PContact contact = roster_get_contact(barejid);
const char * display_usr = NULL;
if (p_contact_name(contact) != NULL) {
@ -137,14 +132,16 @@ cons_show_typing(const char * const barejid)
wprintw(console->win, "!! %s is typing a message...\n", display_usr);
wattroff(console->win, COLOUR_TYPING);
ui_console_dirty();
wins_refresh_console();
cons_alert();
}
void
cons_show_incoming_message(const char * const short_from, const int win_index)
{
int ui_index = win_index + 1;
ProfWin *console = wins_get_console();
int ui_index = win_index;
if (ui_index == 10) {
ui_index = 0;
}
@ -153,13 +150,14 @@ cons_show_incoming_message(const char * const short_from, const int win_index)
wprintw(console->win, "<< incoming from %s (%d)\n", short_from, ui_index);
wattroff(console->win, COLOUR_INCOMING);
ui_console_dirty();
wins_refresh_console();
cons_alert();
}
void
cons_about(void)
{
ProfWin *console = wins_get_console();
int rows, cols;
getmaxyx(stdscr, rows, cols);
@ -198,13 +196,14 @@ cons_about(void)
prefresh(console->win, 0, 0, 1, 0, rows-3, cols-1);
ui_console_dirty();
wins_refresh_console();
cons_alert();
}
void
cons_check_version(gboolean not_available_msg)
{
ProfWin *console = wins_get_console();
char *latest_release = release_get_latest();
if (latest_release != NULL) {
@ -226,7 +225,7 @@ cons_check_version(gboolean not_available_msg)
}
}
ui_console_dirty();
wins_refresh_console();
cons_alert();
}
}
@ -235,6 +234,7 @@ cons_check_version(gboolean not_available_msg)
void
cons_show_login_success(ProfAccount *account)
{
ProfWin *console = wins_get_console();
win_print_time(console, '-');
wprintw(console->win, "%s logged in successfully, ", account->jid);
@ -247,91 +247,28 @@ cons_show_login_success(ProfAccount *account)
wprintw(console->win, " (priority %d)",
accounts_get_priority_for_presence_type(account->name, presence));
wprintw(console->win, ".\n");
ui_console_dirty();
wins_refresh_console();
cons_alert();
}
void
cons_show_wins(void)
{
int i = 0;
int count = 0;
int ui_index = 0;
ProfWin *console = wins_get_console();
cons_show("");
cons_show("Active windows:");
win_print_time(console, '-');
wprintw(console->win, "1: Console\n");
GSList *window_strings = wins_create_summary();
for (i = 1; i < NUM_WINS; i++) {
if (windows[i] != NULL) {
count++;
}
}
if (count != 0) {
for (i = 1; i < NUM_WINS; i++) {
if (windows[i] != NULL) {
ProfWin *window = windows[i];
win_print_time(console, '-');
ui_index = i + 1;
if (ui_index == 10) {
ui_index = 0;
}
switch (window->type)
{
case WIN_CHAT:
wprintw(console->win, "%d: Chat %s", ui_index, window->from);
PContact contact = roster_get_contact(window->from);
if (contact != NULL) {
if (p_contact_name(contact) != NULL) {
wprintw(console->win, " (%s)", p_contact_name(contact));
}
wprintw(console->win, " - %s", p_contact_presence(contact));
}
if (window->unread > 0) {
wprintw(console->win, ", %d unread", window->unread);
}
break;
case WIN_PRIVATE:
wprintw(console->win, "%d: Private %s", ui_index, window->from);
if (window->unread > 0) {
wprintw(console->win, ", %d unread", window->unread);
}
break;
case WIN_MUC:
wprintw(console->win, "%d: Room %s", ui_index, window->from);
if (window->unread > 0) {
wprintw(console->win, ", %d unread", window->unread);
}
break;
case WIN_DUCK:
wprintw(console->win, "%d: DuckDuckGo search", ui_index);
break;
default:
break;
}
wprintw(console->win, "\n");
}
}
GSList *curr = window_strings;
while (curr != NULL) {
win_print_time(console, '-');
wprintw(console->win, curr->data);
wprintw(console->win, "\n");
curr = g_slist_next(curr);
}
cons_show("");
ui_console_dirty();
wins_refresh_console();
cons_alert();
}
@ -349,13 +286,14 @@ cons_show_room_invites(GSList *invites)
}
}
ui_console_dirty();
wins_refresh_console();
cons_alert();
}
void
cons_show_info(PContact pcontact)
{
ProfWin *console = wins_get_console();
const char *barejid = p_contact_barejid(pcontact);
const char *name = p_contact_name(pcontact);
const char *presence = p_contact_presence(pcontact);
@ -481,13 +419,14 @@ cons_show_info(PContact pcontact)
ordered_resources = g_list_next(ordered_resources);
}
ui_console_dirty();
wins_refresh_console();
cons_alert();
}
void
cons_show_caps(const char * const contact, Resource *resource)
{
ProfWin *console = wins_get_console();
WINDOW *win = console->win;
cons_show("");
const char *resource_presence = string_from_resource_presence(resource->presence);
@ -555,7 +494,7 @@ cons_show_caps(const char * const contact, Resource *resource)
}
}
ui_console_dirty();
wins_refresh_console();
cons_alert();
}
@ -563,6 +502,7 @@ void
cons_show_software_version(const char * const jid, const char * const presence,
const char * const name, const char * const version, const char * const os)
{
ProfWin *console = wins_get_console();
if ((name != NULL) || (version != NULL) || (os != NULL)) {
cons_show("");
win_print_time(console, '-');
@ -581,7 +521,7 @@ cons_show_software_version(const char * const jid, const char * const presence,
cons_show("OS : %s", os);
}
ui_console_dirty();
wins_refresh_console();
cons_alert();
}
@ -600,6 +540,9 @@ cons_show_received_subs(void)
}
g_slist_free_full(received, g_free);
}
wins_refresh_console();
cons_alert();
}
void
@ -619,11 +562,15 @@ cons_show_sent_subs(void)
} else {
cons_show("No pending requests sent.");
}
wins_refresh_console();
cons_alert();
}
void
cons_show_room_list(GSList *rooms, const char * const conference_node)
{
ProfWin *console = wins_get_console();
if ((rooms != NULL) && (g_slist_length(rooms) > 0)) {
cons_show("Chat rooms at %s:", conference_node);
while (rooms != NULL) {
@ -640,7 +587,7 @@ cons_show_room_list(GSList *rooms, const char * const conference_node)
cons_show("No chat rooms at %s", conference_node);
}
ui_console_dirty();
wins_refresh_console();
cons_alert();
}
@ -656,6 +603,8 @@ cons_show_bookmarks(const GList *list)
while (list != NULL) {
item = list->data;
ProfWin *console = wins_get_console();
win_print_time(console, '-');
wprintw(console->win, " %s", item->jid);
if (item->nick != NULL) {
@ -668,7 +617,7 @@ cons_show_bookmarks(const GList *list)
list = g_list_next(list);
}
ui_console_dirty();
wins_refresh_console();
cons_alert();
}
@ -710,7 +659,7 @@ cons_show_disco_info(const char *jid, GSList *identities, GSList *features)
features = g_slist_next(features);
}
ui_console_dirty();
wins_refresh_console();
cons_alert();
}
}
@ -718,6 +667,7 @@ cons_show_disco_info(const char *jid, GSList *identities, GSList *features)
void
cons_show_disco_items(GSList *items, const char * const jid)
{
ProfWin *console = wins_get_console();
if ((items != NULL) && (g_slist_length(items) > 0)) {
cons_show("");
cons_show("Service discovery items for %s:", jid);
@ -735,13 +685,14 @@ cons_show_disco_items(GSList *items, const char * const jid)
cons_show("");
cons_show("No service discovery items for %s", jid);
}
ui_console_dirty();
wins_refresh_console();
cons_alert();
}
void
cons_show_status(const char * const barejid)
{
ProfWin *console = wins_get_console();
PContact pcontact = roster_get_contact(barejid);
if (pcontact != NULL) {
@ -749,7 +700,7 @@ cons_show_status(const char * const barejid)
} else {
cons_show("No such contact \"%s\" in roster.", barejid);
}
ui_console_dirty();
wins_refresh_console();
cons_alert();
}
@ -786,13 +737,14 @@ cons_show_room_invite(const char * const invitor, const char * const room,
free(display_from);
ui_console_dirty();
wins_refresh_console();
cons_alert();
}
void
cons_show_account_list(gchar **accounts)
{
ProfWin *console = wins_get_console();
int size = g_strv_length(accounts);
if (size > 0) {
cons_show("Accounts:");
@ -815,13 +767,14 @@ cons_show_account_list(gchar **accounts)
cons_show("");
}
ui_console_dirty();
wins_refresh_console();
cons_alert();
}
void
cons_show_account(ProfAccount *account)
{
ProfWin *console = wins_get_console();
cons_show("");
cons_show("Account %s:", account->name);
if (account->enabled) {
@ -928,7 +881,7 @@ cons_show_account(ProfAccount *account)
}
}
ui_console_dirty();
wins_refresh_console();
cons_alert();
}
@ -1021,7 +974,7 @@ cons_show_ui_prefs(void)
cons_statuses_setting();
cons_titlebar_setting();
ui_console_dirty();
wins_refresh_console();
cons_alert();
}
@ -1065,7 +1018,7 @@ cons_show_desktop_prefs(void)
cons_show("");
cons_notify_setting();
ui_console_dirty();
wins_refresh_console();
cons_alert();
}
@ -1129,7 +1082,7 @@ cons_show_chat_prefs(void)
cons_gone_setting();
cons_history_setting();
ui_console_dirty();
wins_refresh_console();
cons_alert();
}
@ -1166,7 +1119,7 @@ cons_show_log_prefs(void)
cons_chlog_setting();
cons_grlog_setting();
ui_console_dirty();
wins_refresh_console();
cons_alert();
}
@ -1202,7 +1155,7 @@ cons_show_presence_prefs(void)
cons_show("");
cons_autoaway_setting();
ui_console_dirty();
wins_refresh_console();
cons_alert();
}
@ -1247,7 +1200,7 @@ cons_show_connection_prefs(void)
cons_reconnect_setting();
cons_autoping_setting();
ui_console_dirty();
wins_refresh_console();
cons_alert();
}
@ -1266,7 +1219,7 @@ cons_show_themes(GSList *themes)
}
}
ui_console_dirty();
wins_refresh_console();
cons_alert();
}
@ -1287,7 +1240,7 @@ cons_prefs(void)
cons_show_connection_prefs();
cons_show("");
ui_console_dirty();
wins_refresh_console();
cons_alert();
}
@ -1310,7 +1263,7 @@ cons_help(void)
cons_show("/help [command] - Detailed help on a specific command.");
cons_show("");
ui_console_dirty();
wins_refresh_console();
cons_alert();
}
@ -1332,13 +1285,120 @@ cons_navigation_help(void)
cons_show("PAGE UP, PAGE DOWN : Page the main window.");
cons_show("");
ui_console_dirty();
wins_refresh_console();
cons_alert();
}
void
cons_show_roster_group(const char * const group, GSList *list)
{
cons_show("");
if (list != NULL) {
cons_show("%s:", group);
} else {
cons_show("No group named %s exists.", group);
}
_show_roster_contacts(list, FALSE);
wins_refresh_console();
cons_alert();
}
void
cons_show_roster(GSList *list)
{
cons_show("");
cons_show("Roster:");
_show_roster_contacts(list, TRUE);
wins_refresh_console();
cons_alert();
}
void
cons_show_contacts(GSList *list)
{
ProfWin *console = wins_get_console();
GSList *curr = list;
while(curr) {
PContact contact = curr->data;
if ((strcmp(p_contact_subscription(contact), "to") == 0) ||
(strcmp(p_contact_subscription(contact), "both") == 0)) {
win_show_contact(console, contact);
}
curr = g_slist_next(curr);
}
wins_refresh_console();
cons_alert();
}
void
cons_alert(void)
{
if (ui_current_win_type() != WIN_CONSOLE) {
status_bar_new(1);
}
}
static void
_cons_splash_logo(void)
{
ProfWin *console = wins_get_console();
win_print_time(console, '-');
wprintw(console->win, "Welcome to\n");
win_print_time(console, '-');
wattron(console->win, COLOUR_SPLASH);
wprintw(console->win, " ___ _ \n");
wattroff(console->win, COLOUR_SPLASH);
win_print_time(console, '-');
wattron(console->win, COLOUR_SPLASH);
wprintw(console->win, " / __) (_)_ \n");
wattroff(console->win, COLOUR_SPLASH);
win_print_time(console, '-');
wattron(console->win, COLOUR_SPLASH);
wprintw(console->win, " ____ ____ ___ | |__ ____ ____ _| |_ _ _ \n");
wattroff(console->win, COLOUR_SPLASH);
win_print_time(console, '-');
wattron(console->win, COLOUR_SPLASH);
wprintw(console->win, "| _ \\ / ___) _ \\| __) _ | _ \\| | _) | | |\n");
wattroff(console->win, COLOUR_SPLASH);
win_print_time(console, '-');
wattron(console->win, COLOUR_SPLASH);
wprintw(console->win, "| | | | | | |_| | | ( ( | | | | | | |_| |_| |\n");
wattroff(console->win, COLOUR_SPLASH);
win_print_time(console, '-');
wattron(console->win, COLOUR_SPLASH);
wprintw(console->win, "| ||_/|_| \\___/|_| \\_||_|_| |_|_|\\___)__ |\n");
wattroff(console->win, COLOUR_SPLASH);
win_print_time(console, '-');
wattron(console->win, COLOUR_SPLASH);
wprintw(console->win, "|_| (____/ \n");
wattroff(console->win, COLOUR_SPLASH);
win_print_time(console, '-');
wprintw(console->win, "\n");
win_print_time(console, '-');
if (strcmp(PACKAGE_STATUS, "development") == 0) {
wprintw(console->win, "Version %sdev\n", PACKAGE_VERSION);
} else {
wprintw(console->win, "Version %s\n", PACKAGE_VERSION);
}
}
void
_show_roster_contacts(GSList *list, gboolean show_groups)
{
ProfWin *console = wins_get_console();
GSList *curr = list;
while(curr) {
@ -1410,107 +1470,3 @@ _show_roster_contacts(GSList *list, gboolean show_groups)
}
}
void
cons_show_roster_group(const char * const group, GSList *list)
{
cons_show("");
if (list != NULL) {
cons_show("%s:", group);
} else {
cons_show("No group named %s exists.", group);
}
_show_roster_contacts(list, FALSE);
ui_console_dirty();
cons_alert();
}
void
cons_show_roster(GSList *list)
{
cons_show("");
cons_show("Roster:");
_show_roster_contacts(list, TRUE);
ui_console_dirty();
cons_alert();
}
void
cons_show_contacts(GSList *list)
{
GSList *curr = list;
while(curr) {
PContact contact = curr->data;
if ((strcmp(p_contact_subscription(contact), "to") == 0) ||
(strcmp(p_contact_subscription(contact), "both") == 0)) {
win_show_contact(console, contact);
}
curr = g_slist_next(curr);
}
ui_console_dirty();
cons_alert();
}
void
cons_alert(void)
{
if (ui_current_win_type() != WIN_CONSOLE) {
status_bar_new(0);
}
}
static void
_cons_splash_logo(void)
{
win_print_time(console, '-');
wprintw(console->win, "Welcome to\n");
win_print_time(console, '-');
wattron(console->win, COLOUR_SPLASH);
wprintw(console->win, " ___ _ \n");
wattroff(console->win, COLOUR_SPLASH);
win_print_time(console, '-');
wattron(console->win, COLOUR_SPLASH);
wprintw(console->win, " / __) (_)_ \n");
wattroff(console->win, COLOUR_SPLASH);
win_print_time(console, '-');
wattron(console->win, COLOUR_SPLASH);
wprintw(console->win, " ____ ____ ___ | |__ ____ ____ _| |_ _ _ \n");
wattroff(console->win, COLOUR_SPLASH);
win_print_time(console, '-');
wattron(console->win, COLOUR_SPLASH);
wprintw(console->win, "| _ \\ / ___) _ \\| __) _ | _ \\| | _) | | |\n");
wattroff(console->win, COLOUR_SPLASH);
win_print_time(console, '-');
wattron(console->win, COLOUR_SPLASH);
wprintw(console->win, "| | | | | | |_| | | ( ( | | | | | | |_| |_| |\n");
wattroff(console->win, COLOUR_SPLASH);
win_print_time(console, '-');
wattron(console->win, COLOUR_SPLASH);
wprintw(console->win, "| ||_/|_| \\___/|_| \\_||_|_| |_|_|\\___)__ |\n");
wattroff(console->win, COLOUR_SPLASH);
win_print_time(console, '-');
wattron(console->win, COLOUR_SPLASH);
wprintw(console->win, "|_| (____/ \n");
wattroff(console->win, COLOUR_SPLASH);
win_print_time(console, '-');
wprintw(console->win, "\n");
win_print_time(console, '-');
if (strcmp(PACKAGE_STATUS, "development") == 0) {
wprintw(console->win, "Version %sdev\n", PACKAGE_VERSION);
} else {
wprintw(console->win, "Version %s\n", PACKAGE_VERSION);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -526,35 +526,35 @@ _handle_alt_key(char *input, int *size, int key)
switch (key)
{
case '1':
ui_switch_win(0);
break;
case '2':
ui_switch_win(1);
break;
case '3':
case '2':
ui_switch_win(2);
break;
case '4':
case '3':
ui_switch_win(3);
break;
case '5':
case '4':
ui_switch_win(4);
break;
case '6':
case '5':
ui_switch_win(5);
break;
case '7':
case '6':
ui_switch_win(6);
break;
case '8':
case '7':
ui_switch_win(7);
break;
case '9':
case '8':
ui_switch_win(8);
break;
case '0':
case '9':
ui_switch_win(9);
break;
case '0':
ui_switch_win(0);
break;
case 263:
case 127:
input[*size] = '\0';

View File

@ -37,13 +37,20 @@
static WINDOW *status_bar;
static char *message = NULL;
static char _active[31] = "[ ][ ][ ][ ][ ][ ][ ][ ][ ][ ]";
static int is_active[10];
static int is_new[10];
// 1 2 3 4 5 6 7 8 9 0 >
static char _active[34] = "[ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ]";
static int is_active[12];
static GHashTable *remaining_active;
static int is_new[12];
static GHashTable *remaining_new;
static int dirty;
static GDateTime *last_time;
static void _status_bar_update_time(void);
static void _update_win_statuses(void);
static void _mark_new(int num);
static void _mark_active(int num);
static void _mark_inactive(int num);
void
create_status_bar(void)
@ -51,17 +58,19 @@ create_status_bar(void)
int rows, cols, i;
getmaxyx(stdscr, rows, cols);
is_active[0] = TRUE;
is_new[0] = FALSE;
for (i = 1; i < 10; i++) {
is_active[1] = TRUE;
is_new[1] = FALSE;
for (i = 2; i < 12; i++) {
is_active[i] = FALSE;
is_new[i] = FALSE;
}
remaining_active = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, NULL);
remaining_new = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, NULL);
status_bar = newwin(1, cols, rows-2, 0);
wbkgd(status_bar, COLOUR_STATUS_TEXT);
wattron(status_bar, COLOUR_STATUS_BRACKET);
mvwprintw(status_bar, 0, cols - 31, _active);
mvwprintw(status_bar, 0, cols - 34, _active);
wattroff(status_bar, COLOUR_STATUS_BRACKET);
if (last_time != NULL)
@ -86,6 +95,7 @@ status_bar_refresh(void)
if (dirty) {
_status_bar_update_time();
_update_win_statuses();
wrefresh(status_bar);
inp_put_back();
dirty = FALSE;
@ -97,7 +107,7 @@ status_bar_refresh(void)
void
status_bar_resize(void)
{
int rows, cols, i;
int rows, cols;
getmaxyx(stdscr, rows, cols);
mvwin(status_bar, rows-2, 0);
@ -105,15 +115,10 @@ status_bar_resize(void)
wbkgd(status_bar, COLOUR_STATUS_TEXT);
werase(status_bar);
wattron(status_bar, COLOUR_STATUS_BRACKET);
mvwprintw(status_bar, 0, cols - 31, _active);
mvwprintw(status_bar, 0, cols - 34, _active);
wattroff(status_bar, COLOUR_STATUS_BRACKET);
for(i = 0; i < 10; i++) {
if (is_new[i])
status_bar_new(i);
else if (is_active[i])
status_bar_active(i);
}
_update_win_statuses();
if (message != NULL)
mvwprintw(status_bar, 0, 10, message);
@ -124,61 +129,115 @@ status_bar_resize(void)
dirty = TRUE;
}
void
status_bar_set_all_inactive(void)
{
int i = 0;
for (i = 0; i < 12; i++) {
is_active[i] = FALSE;
is_new[i] = FALSE;
_mark_inactive(i);
}
g_hash_table_remove_all(remaining_active);
g_hash_table_remove_all(remaining_new);
}
void
status_bar_inactive(const int win)
{
is_active[win] = FALSE;
is_new[win] = FALSE;
int true_win = win;
if (true_win == 0) {
true_win = 10;
}
int active_pos = 1 + (win * 3);
// extra windows
if (true_win > 10) {
g_hash_table_remove(remaining_active, GINT_TO_POINTER(true_win));
g_hash_table_remove(remaining_new, GINT_TO_POINTER(true_win));
int cols = getmaxx(stdscr);
// still have new windows
if (g_hash_table_size(remaining_new) != 0) {
is_active[11] = TRUE;
is_new[11] = TRUE;
_mark_new(11);
mvwaddch(status_bar, 0, cols - 31 + active_pos, ' ');
// still have active winsows
} else if (g_hash_table_size(remaining_active) != 0) {
is_active[11] = TRUE;
is_new[11] = FALSE;
_mark_active(11);
dirty = TRUE;
// no active or new windows
} else {
is_active[11] = FALSE;
is_new[11] = FALSE;
_mark_inactive(11);
}
// visible window indicators
} else {
is_active[true_win] = FALSE;
is_new[true_win] = FALSE;
_mark_inactive(true_win);
}
}
void
status_bar_active(const int win)
{
is_active[win] = TRUE;
is_new[win] = FALSE;
int true_win = win;
if (true_win == 0) {
true_win = 10;
}
int active_pos = 1 + (win * 3);
// extra windows
if (true_win > 10) {
g_hash_table_add(remaining_active, GINT_TO_POINTER(true_win));
g_hash_table_remove(remaining_new, GINT_TO_POINTER(true_win));
int cols = getmaxx(stdscr);
// still have new windows
if (g_hash_table_size(remaining_new) != 0) {
is_active[11] = TRUE;
is_new[11] = TRUE;
_mark_new(11);
wattron(status_bar, COLOUR_STATUS_ACTIVE);
if (win+1 < 10)
mvwprintw(status_bar, 0, cols - 31 + active_pos, "%d", win+1);
else
mvwprintw(status_bar, 0, cols - 31 + active_pos, "0");
wattroff(status_bar, COLOUR_STATUS_ACTIVE);
// only active windows
} else {
is_active[11] = TRUE;
is_new[11] = FALSE;
_mark_active(11);
}
dirty = TRUE;
// visible winsow indicators
} else {
is_active[true_win] = TRUE;
is_new[true_win] = FALSE;
_mark_active(true_win);
}
}
void
status_bar_new(const int win)
{
is_active[win] = TRUE;
is_new[win] = TRUE;
int true_win = win;
if (true_win == 0) {
true_win = 10;
}
int active_pos = 1 + (win * 3);
if (true_win > 10) {
g_hash_table_add(remaining_active, GINT_TO_POINTER(true_win));
g_hash_table_add(remaining_new, GINT_TO_POINTER(true_win));
int cols = getmaxx(stdscr);
is_active[11] = TRUE;
is_new[11] = TRUE;
_mark_new(11);
wattron(status_bar, COLOUR_STATUS_NEW);
wattron(status_bar, A_BLINK);
if (win+1 < 10)
mvwprintw(status_bar, 0, cols - 31 + active_pos, "%d", win+1);
else
mvwprintw(status_bar, 0, cols - 31 + active_pos, "0");
wattroff(status_bar, COLOUR_STATUS_NEW);
wattroff(status_bar, A_BLINK);
dirty = TRUE;
} else {
is_active[true_win] = TRUE;
is_new[true_win] = TRUE;
_mark_new(true_win);
}
}
void
@ -203,17 +262,10 @@ status_bar_print_message(const char * const msg)
int cols = getmaxx(stdscr);
wattron(status_bar, COLOUR_STATUS_BRACKET);
mvwprintw(status_bar, 0, cols - 31, _active);
mvwprintw(status_bar, 0, cols - 34, _active);
wattroff(status_bar, COLOUR_STATUS_BRACKET);
int i;
for(i = 0; i < 10; i++) {
if (is_new[i])
status_bar_new(i);
else if (is_active[i])
status_bar_active(i);
}
_update_win_statuses();
dirty = TRUE;
}
@ -226,9 +278,9 @@ status_bar_clear(void)
}
int i;
is_active[0] = TRUE;
is_new[0] = FALSE;
for (i = 1; i < 10; i++) {
is_active[1] = TRUE;
is_new[1] = FALSE;
for (i = 2; i < 12; i++) {
is_active[i] = FALSE;
is_new[i] = FALSE;
}
@ -238,7 +290,7 @@ status_bar_clear(void)
int cols = getmaxx(stdscr);
wattron(status_bar, COLOUR_STATUS_BRACKET);
mvwprintw(status_bar, 0, cols - 31, _active);
mvwprintw(status_bar, 0, cols - 34, _active);
wattroff(status_bar, COLOUR_STATUS_BRACKET);
dirty = TRUE;
@ -257,17 +309,10 @@ status_bar_clear_message(void)
int cols = getmaxx(stdscr);
wattron(status_bar, COLOUR_STATUS_BRACKET);
mvwprintw(status_bar, 0, cols - 31, _active);
mvwprintw(status_bar, 0, cols - 34, _active);
wattroff(status_bar, COLOUR_STATUS_BRACKET);
int i;
for(i = 0; i < 10; i++) {
if (is_new[i])
status_bar_new(i);
else if (is_active[i])
status_bar_active(i);
}
_update_win_statuses();
dirty = TRUE;
}
@ -289,3 +334,65 @@ _status_bar_update_time(void)
dirty = TRUE;
}
static void
_update_win_statuses(void)
{
int i;
for(i = 1; i < 12; i++) {
if (is_new[i]) {
_mark_new(i);
}
else if (is_active[i]) {
_mark_active(i);
}
else {
_mark_inactive(i);
}
}
}
static void
_mark_new(int num)
{
int active_pos = 1 + ((num-1) * 3);
int cols = getmaxx(stdscr);
wattron(status_bar, COLOUR_STATUS_NEW);
wattron(status_bar, A_BLINK);
if (num == 10) {
mvwprintw(status_bar, 0, cols - 34 + active_pos, "0");
} else if (num > 10) {
mvwprintw(status_bar, 0, cols - 34 + active_pos, ">");
} else {
mvwprintw(status_bar, 0, cols - 34 + active_pos, "%d", num);
}
wattroff(status_bar, COLOUR_STATUS_NEW);
wattroff(status_bar, A_BLINK);
dirty = TRUE;
}
static void
_mark_active(int num)
{
int active_pos = 1 + ((num-1) * 3);
int cols = getmaxx(stdscr);
wattron(status_bar, COLOUR_STATUS_ACTIVE);
if (num == 10) {
mvwprintw(status_bar, 0, cols - 34 + active_pos, "0");
} else if (num > 10) {
mvwprintw(status_bar, 0, cols - 34 + active_pos, ">");
} else {
mvwprintw(status_bar, 0, cols - 34 + active_pos, "%d", num);
}
wattroff(status_bar, COLOUR_STATUS_ACTIVE);
dirty = TRUE;
}
static void
_mark_inactive(int num)
{
int active_pos = 1 + ((num-1) * 3);
int cols = getmaxx(stdscr);
mvwaddch(status_bar, 0, cols - 34 + active_pos, ' ');
dirty = TRUE;
}

View File

@ -40,10 +40,6 @@
#include "xmpp/xmpp.h"
#define INP_WIN_MAX 1000
#define NUM_WINS 10
// holds console at index 0 and chat wins 1 through to 9
ProfWin* windows[NUM_WINS];
// ui startup and control
void ui_init(void);
@ -56,15 +52,15 @@ void ui_idle(void);
void ui_handle_special_keys(const wint_t * const ch, const char * const inp,
const int size);
void ui_switch_win(const int i);
gboolean ui_windows_full(void);
unsigned long ui_get_idle_time(void);
void ui_reset_idle_time(void);
void ui_new_chat_win(const char * const to);
void ui_print_error_from_recipient(const char * const from, const char *err_msg);
void ui_print_system_msg_from_recipient(const char * const from, const char *message);
gint ui_unread(void);
void ui_console_dirty(void);
void ui_close_connected_win(int index);
int ui_close_all_wins(void);
int ui_close_read_wins(void);
// current window actions
void ui_close_current(void);
@ -149,7 +145,6 @@ void title_bar_set_typing(gboolean is_typing);
void title_bar_draw(void);
// console window actions
ProfWin* cons_create(void);
void cons_show(const char * const msg, ...);
void cons_about(void);
void cons_help(void);
@ -230,6 +225,7 @@ void status_bar_inactive(const int win);
void status_bar_active(const int win);
void status_bar_new(const int win);
void status_bar_update_time(void);
void status_bar_set_all_inactive(void);
// input window actions
wint_t inp_get_char(char *input, int *size);

View File

@ -35,8 +35,6 @@
#include "config/theme.h"
#include "ui/window.h"
#define CONS_WIN_TITLE "_cons"
ProfWin*
win_create(const char * const title, int cols, win_type_t type)
{
@ -59,8 +57,6 @@ win_free(ProfWin* window)
{
delwin(window->win);
free(window->from);
window->from = NULL;
window->win = NULL;
free(window);
window = NULL;
}

View File

@ -23,6 +23,14 @@
#ifndef WINDOW_H
#define WINDOW_H
#include "config.h"
#ifdef HAVE_NCURSESW_NCURSES_H
#include <ncursesw/ncurses.h>
#elif HAVE_NCURSES_H
#include <ncurses.h>
#endif
#include "contact.h"
#define PAD_SIZE 1000

475
src/ui/windows.c Normal file
View File

@ -0,0 +1,475 @@
/*
* windows.c
*
* Copyright (C) 2012, 2013 James Booth <boothj5@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#include "config.h"
#include <string.h>
#include <glib.h>
#ifdef HAVE_NCURSESW_NCURSES_H
#include <ncursesw/ncurses.h>
#elif HAVE_NCURSES_H
#include <ncurses.h>
#endif
#include "common.h"
#include "config/theme.h"
#include "ui/ui.h"
#include "ui/window.h"
#include "ui/windows.h"
#define CONS_WIN_TITLE "_cons"
static GHashTable *windows;
static int current;
static int max_cols;
void
wins_init(void)
{
windows = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL,
(GDestroyNotify)win_free);
max_cols = getmaxx(stdscr);
int cols = getmaxx(stdscr);
ProfWin *console = win_create(CONS_WIN_TITLE, cols, WIN_CONSOLE);
g_hash_table_insert(windows, GINT_TO_POINTER(1), console);
current = 1;
}
ProfWin *
wins_get_console(void)
{
return g_hash_table_lookup(windows, GINT_TO_POINTER(1));
}
ProfWin *
wins_get_current(void)
{
return g_hash_table_lookup(windows, GINT_TO_POINTER(current));
}
GList *
wins_get_nums(void)
{
return g_hash_table_get_keys(windows);
}
void
wins_set_current_by_num(int i)
{
if (g_hash_table_lookup(windows, GINT_TO_POINTER(i)) != NULL) {
current = i;
}
}
ProfWin *
wins_get_by_num(int i)
{
return g_hash_table_lookup(windows, GINT_TO_POINTER(i));
}
ProfWin *
wins_get_by_recipient(const char * const recipient)
{
GList *values = g_hash_table_get_values(windows);
GList *curr = values;
while (curr != NULL) {
ProfWin *window = curr->data;
if (g_strcmp0(window->from, recipient) == 0) {
return window;
}
curr = g_list_next(curr);
}
return NULL;
}
int
wins_get_num(ProfWin *window)
{
GList *keys = g_hash_table_get_keys(windows);
GList *curr = keys;
while (curr != NULL) {
gconstpointer num_p = curr->data;
ProfWin *curr_win = g_hash_table_lookup(windows, num_p);
if (g_strcmp0(curr_win->from, window->from) == 0) {
return GPOINTER_TO_INT(num_p);
}
curr = g_list_next(curr);
}
return -1;
}
int
wins_get_current_num(void)
{
return current;
}
void
wins_close_current(void)
{
wins_close_by_num(current);
}
void
wins_close_by_num(int i)
{
if (i != 1) {
if (i == current) {
current = 1;
wins_refresh_current();
}
g_hash_table_remove(windows, GINT_TO_POINTER(i));
status_bar_inactive(i);
}
}
void
wins_refresh_current(void)
{
ProfWin *window = wins_get_current();
int rows, cols;
getmaxyx(stdscr, rows, cols);
prefresh(window->win, window->y_pos, 0, 1, 0, rows-3, cols-1);
}
void
wins_clear_current(void)
{
ProfWin *window = wins_get_current();
werase(window->win);
wins_refresh_current();
}
gboolean
wins_is_current(ProfWin *window)
{
ProfWin *current_window = wins_get_current();
if (g_strcmp0(current_window->from, window->from) == 0) {
return TRUE;
} else {
return FALSE;
}
}
ProfWin *
wins_new(const char * const from, win_type_t type)
{
GList *keys = g_hash_table_get_keys(windows);
int result = get_next_available_win_num(keys);
int cols = getmaxx(stdscr);
ProfWin *new = win_create(from, cols, type);
g_hash_table_insert(windows, GINT_TO_POINTER(result), new);
return new;
}
int
wins_get_total_unread(void)
{
int result = 0;
GList *values = g_hash_table_get_values(windows);
GList *curr = values;
while (curr != NULL) {
ProfWin *window = curr->data;
result += window->unread;
curr = g_list_next(curr);
}
return result;
}
void
wins_resize_all(void)
{
int rows, cols;
getmaxyx(stdscr, rows, cols);
// only make the pads bigger, to avoid data loss on cropping
if (cols > max_cols) {
max_cols = cols;
GList *values = g_hash_table_get_values(windows);
GList *curr = values;
while (curr != NULL) {
ProfWin *window = curr->data;
wresize(window->win, PAD_SIZE, cols);
curr = g_list_next(curr);
}
}
ProfWin *current_win = wins_get_current();
prefresh(current_win->win, current_win->y_pos, 0, 1, 0, rows-3, cols-1);
}
void
wins_refresh_console(void)
{
if (current == 0) {
wins_refresh_current();
}
}
gboolean
wins_duck_exists(void)
{
GList *values = g_hash_table_get_values(windows);
GList *curr = values;
while (curr != NULL) {
ProfWin *window = curr->data;
if (window->type == WIN_DUCK)
return TRUE;
curr = g_list_next(curr);
}
return FALSE;
}
GSList *
wins_get_chat_recipients(void)
{
GSList *result = NULL;
GList *values = g_hash_table_get_values(windows);
GList *curr = values;
while (curr != NULL) {
ProfWin *window = curr->data;
if (window->type == WIN_CHAT) {
result = g_slist_append(result, window->from);
}
curr = g_list_next(curr);
}
return result;
}
GSList *
wins_get_prune_recipients(void)
{
GSList *result = NULL;
GList *values = g_hash_table_get_values(windows);
GList *curr = values;
while (curr != NULL) {
ProfWin *window = curr->data;
if (window->unread == 0 && window->type != WIN_MUC && window->type != WIN_CONSOLE) {
result = g_slist_append(result, window->from);
}
curr = g_list_next(curr);
}
return result;
}
void
wins_lost_connection(void)
{
GList *values = g_hash_table_get_values(windows);
GList *curr = values;
while (curr != NULL) {
ProfWin *window = curr->data;
if (window->type != WIN_CONSOLE) {
win_print_time(window, '-');
wattron(window->win, COLOUR_ERROR);
wprintw(window->win, "%s\n", "Lost connection.");
wattroff(window->win, COLOUR_ERROR);
// if current win, set current_win_dirty
if (wins_is_current(window)) {
wins_refresh_current();
}
}
curr = g_list_next(curr);
}
}
gboolean
wins_tidy(void)
{
gboolean tidy_required = FALSE;
// check for gaps
GList *keys = g_hash_table_get_keys(windows);
keys = g_list_sort(keys, cmp_win_num);
// get last used
GList *last = g_list_last(keys);
int last_num = GPOINTER_TO_INT(last->data);
// find first free num TODO - Will sort again
int next_available = get_next_available_win_num(keys);
// found gap (next available before last window)
if (cmp_win_num(GINT_TO_POINTER(next_available), GINT_TO_POINTER(last_num)) < 0) {
tidy_required = TRUE;
}
if (tidy_required) {
status_bar_set_all_inactive();
GHashTable *new_windows = g_hash_table_new_full(g_direct_hash,
g_direct_equal, NULL, (GDestroyNotify)win_free);
int num = 1;
GList *curr = keys;
while (curr != NULL) {
ProfWin *window = g_hash_table_lookup(windows, curr->data);
if (num == 10) {
g_hash_table_insert(new_windows, GINT_TO_POINTER(0), window);
if (window->unread > 0) {
status_bar_new(0);
} else {
status_bar_active(0);
}
} else {
g_hash_table_insert(new_windows, GINT_TO_POINTER(num), window);
if (window->unread > 0) {
status_bar_new(num);
} else {
status_bar_active(num);
}
}
num++;
curr = g_list_next(curr);
}
windows = new_windows;
return TRUE;
} else {
return FALSE;
}
}
GSList *
wins_create_summary(void)
{
GSList *result = NULL;
GList *keys = g_hash_table_get_keys(windows);
keys = g_list_sort(keys, cmp_win_num);
GList *curr = keys;
while (curr != NULL) {
ProfWin *window = g_hash_table_lookup(windows, curr->data);
int ui_index = GPOINTER_TO_INT(curr->data);
GString *chat_string;
GString *priv_string;
GString *muc_string;
GString *duck_string;
switch (window->type)
{
case WIN_CONSOLE:
result = g_slist_append(result, strdup("1: Console"));
break;
case WIN_CHAT:
chat_string = g_string_new("");
g_string_printf(chat_string, "%d: Chat %s", ui_index, window->from);
PContact contact = roster_get_contact(window->from);
if (contact != NULL) {
if (p_contact_name(contact) != NULL) {
GString *chat_name = g_string_new("");
g_string_printf(chat_name, " (%s)", p_contact_name(contact));
g_string_append(chat_string, chat_name->str);
g_string_free(chat_name, TRUE);
}
GString *chat_presence = g_string_new("");
g_string_printf(chat_presence, " - %s", p_contact_presence(contact));
g_string_append(chat_string, chat_presence->str);
g_string_free(chat_presence, TRUE);
}
if (window->unread > 0) {
GString *chat_unread = g_string_new("");
g_string_printf(chat_unread, ", %d unread", window->unread);
g_string_append(chat_string, chat_unread->str);
g_string_free(chat_unread, TRUE);
}
result = g_slist_append(result, strdup(chat_string->str));
g_string_free(chat_string, TRUE);
break;
case WIN_PRIVATE:
priv_string = g_string_new("");
g_string_printf(priv_string, "%d: Private %s", ui_index, window->from);
if (window->unread > 0) {
GString *priv_unread = g_string_new("");
g_string_printf(priv_unread, ", %d unread", window->unread);
g_string_append(priv_string, priv_unread->str);
g_string_free(priv_unread, TRUE);
}
result = g_slist_append(result, strdup(priv_string->str));
g_string_free(priv_string, TRUE);
break;
case WIN_MUC:
muc_string = g_string_new("");
g_string_printf(muc_string, "%d: Room %s", ui_index, window->from);
if (window->unread > 0) {
GString *muc_unread = g_string_new("");
g_string_printf(muc_unread, ", %d unread", window->unread);
g_string_append(muc_string, muc_unread->str);
g_string_free(muc_unread, TRUE);
}
result = g_slist_append(result, strdup(muc_string->str));
g_string_free(muc_string, TRUE);
break;
case WIN_DUCK:
duck_string = g_string_new("");
g_string_printf(duck_string, "%d: DuckDuckGo search", ui_index);
result = g_slist_append(result, strdup(duck_string->str));
g_string_free(duck_string, TRUE);
break;
default:
break;
}
curr = g_list_next(curr);
}
return result;
}
void
wins_destroy(void)
{
g_hash_table_destroy(windows);
}

52
src/ui/windows.h Normal file
View File

@ -0,0 +1,52 @@
/*
* windows.h
*
* Copyright (C) 2012, 2013 James Booth <boothj5@gmail.com>
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
#ifndef WINDOWS_H
#define WINDOWS_H
void wins_init(void);
ProfWin * wins_get_console(void);
ProfWin * wins_get_current(void);
void wins_set_current_by_num(int i);
ProfWin * wins_get_by_num(int i);
ProfWin * wins_get_by_recipient(const char * const recipient);
int wins_get_num(ProfWin *window);
int wins_get_current_num(void);
void wins_close_current(void);
void wins_close_by_num(int i);
void wins_refresh_current(void);
void wins_refresh_console(void);
void wins_clear_current(void);
gboolean wins_is_current(ProfWin *window);
ProfWin * wins_new(const char * const from, win_type_t type);
int wins_get_total_unread(void);
void wins_resize_all(void);
gboolean wins_duck_exists(void);
GSList * wins_get_chat_recipients(void);
GSList * wins_get_prune_recipients(void);
void wins_lost_connection(void);
gboolean wins_tidy(void);
GSList * wins_create_summary(void);
void wins_destroy(void);
GList * wins_get_nums(void);
#endif

View File

@ -146,6 +146,283 @@ void replace_when_new_null(void)
assert_string_equals("hello", result);
}
void compare_win_nums_less(void)
{
gconstpointer a = GINT_TO_POINTER(2);
gconstpointer b = GINT_TO_POINTER(3);
int result = cmp_win_num(a, b);
assert_true(result < 0);
}
void compare_win_nums_equal(void)
{
gconstpointer a = GINT_TO_POINTER(5);
gconstpointer b = GINT_TO_POINTER(5);
int result = cmp_win_num(a, b);
assert_true(result == 0);
}
void compare_win_nums_greater(void)
{
gconstpointer a = GINT_TO_POINTER(7);
gconstpointer b = GINT_TO_POINTER(6);
int result = cmp_win_num(a, b);
assert_true(result > 0);
}
void compare_0s_equal(void)
{
gconstpointer a = GINT_TO_POINTER(0);
gconstpointer b = GINT_TO_POINTER(0);
int result = cmp_win_num(a, b);
assert_true(result == 0);
}
void compare_0_greater_than_1(void)
{
gconstpointer a = GINT_TO_POINTER(0);
gconstpointer b = GINT_TO_POINTER(1);
int result = cmp_win_num(a, b);
assert_true(result > 0);
}
void compare_1_less_than_0(void)
{
gconstpointer a = GINT_TO_POINTER(1);
gconstpointer b = GINT_TO_POINTER(0);
int result = cmp_win_num(a, b);
assert_true(result < 0);
}
void compare_0_less_than_11(void)
{
gconstpointer a = GINT_TO_POINTER(0);
gconstpointer b = GINT_TO_POINTER(11);
int result = cmp_win_num(a, b);
assert_true(result < 0);
}
void compare_11_greater_than_0(void)
{
gconstpointer a = GINT_TO_POINTER(11);
gconstpointer b = GINT_TO_POINTER(0);
int result = cmp_win_num(a, b);
assert_true(result > 0);
}
void compare_0_greater_than_9(void)
{
gconstpointer a = GINT_TO_POINTER(0);
gconstpointer b = GINT_TO_POINTER(9);
int result = cmp_win_num(a, b);
assert_true(result > 0);
}
void compare_9_less_than_0(void)
{
gconstpointer a = GINT_TO_POINTER(9);
gconstpointer b = GINT_TO_POINTER(0);
int result = cmp_win_num(a, b);
assert_true(result < 0);
}
void next_available_when_only_console(void)
{
GList *used = NULL;
used = g_list_append(used, GINT_TO_POINTER(1));
int result = get_next_available_win_num(used);
assert_int_equals(2, result);
}
void next_available_3_at_end(void)
{
GList *used = NULL;
used = g_list_append(used, GINT_TO_POINTER(1));
used = g_list_append(used, GINT_TO_POINTER(2));
int result = get_next_available_win_num(used);
assert_int_equals(3, result);
}
void next_available_9_at_end(void)
{
GList *used = NULL;
used = g_list_append(used, GINT_TO_POINTER(1));
used = g_list_append(used, GINT_TO_POINTER(2));
used = g_list_append(used, GINT_TO_POINTER(3));
used = g_list_append(used, GINT_TO_POINTER(4));
used = g_list_append(used, GINT_TO_POINTER(5));
used = g_list_append(used, GINT_TO_POINTER(6));
used = g_list_append(used, GINT_TO_POINTER(7));
used = g_list_append(used, GINT_TO_POINTER(8));
int result = get_next_available_win_num(used);
assert_int_equals(9, result);
}
void next_available_0_at_end(void)
{
GList *used = NULL;
used = g_list_append(used, GINT_TO_POINTER(1));
used = g_list_append(used, GINT_TO_POINTER(2));
used = g_list_append(used, GINT_TO_POINTER(3));
used = g_list_append(used, GINT_TO_POINTER(4));
used = g_list_append(used, GINT_TO_POINTER(5));
used = g_list_append(used, GINT_TO_POINTER(6));
used = g_list_append(used, GINT_TO_POINTER(7));
used = g_list_append(used, GINT_TO_POINTER(8));
used = g_list_append(used, GINT_TO_POINTER(9));
int result = get_next_available_win_num(used);
assert_int_equals(0, result);
}
void next_available_2_in_first_gap(void)
{
GList *used = NULL;
used = g_list_append(used, GINT_TO_POINTER(1));
used = g_list_append(used, GINT_TO_POINTER(3));
used = g_list_append(used, GINT_TO_POINTER(4));
used = g_list_append(used, GINT_TO_POINTER(5));
used = g_list_append(used, GINT_TO_POINTER(9));
used = g_list_append(used, GINT_TO_POINTER(0));
int result = get_next_available_win_num(used);
assert_int_equals(2, result);
}
void next_available_9_in_first_gap(void)
{
GList *used = NULL;
used = g_list_append(used, GINT_TO_POINTER(1));
used = g_list_append(used, GINT_TO_POINTER(2));
used = g_list_append(used, GINT_TO_POINTER(3));
used = g_list_append(used, GINT_TO_POINTER(4));
used = g_list_append(used, GINT_TO_POINTER(5));
used = g_list_append(used, GINT_TO_POINTER(6));
used = g_list_append(used, GINT_TO_POINTER(7));
used = g_list_append(used, GINT_TO_POINTER(8));
used = g_list_append(used, GINT_TO_POINTER(0));
used = g_list_append(used, GINT_TO_POINTER(11));
used = g_list_append(used, GINT_TO_POINTER(12));
used = g_list_append(used, GINT_TO_POINTER(13));
used = g_list_append(used, GINT_TO_POINTER(20));
int result = get_next_available_win_num(used);
assert_int_equals(9, result);
}
void next_available_0_in_first_gap(void)
{
GList *used = NULL;
used = g_list_append(used, GINT_TO_POINTER(1));
used = g_list_append(used, GINT_TO_POINTER(2));
used = g_list_append(used, GINT_TO_POINTER(3));
used = g_list_append(used, GINT_TO_POINTER(4));
used = g_list_append(used, GINT_TO_POINTER(5));
used = g_list_append(used, GINT_TO_POINTER(6));
used = g_list_append(used, GINT_TO_POINTER(7));
used = g_list_append(used, GINT_TO_POINTER(8));
used = g_list_append(used, GINT_TO_POINTER(9));
used = g_list_append(used, GINT_TO_POINTER(11));
used = g_list_append(used, GINT_TO_POINTER(12));
used = g_list_append(used, GINT_TO_POINTER(13));
used = g_list_append(used, GINT_TO_POINTER(20));
int result = get_next_available_win_num(used);
assert_int_equals(0, result);
}
void next_available_11_in_first_gap(void)
{
GList *used = NULL;
used = g_list_append(used, GINT_TO_POINTER(1));
used = g_list_append(used, GINT_TO_POINTER(2));
used = g_list_append(used, GINT_TO_POINTER(3));
used = g_list_append(used, GINT_TO_POINTER(4));
used = g_list_append(used, GINT_TO_POINTER(5));
used = g_list_append(used, GINT_TO_POINTER(6));
used = g_list_append(used, GINT_TO_POINTER(7));
used = g_list_append(used, GINT_TO_POINTER(8));
used = g_list_append(used, GINT_TO_POINTER(9));
used = g_list_append(used, GINT_TO_POINTER(0));
used = g_list_append(used, GINT_TO_POINTER(12));
used = g_list_append(used, GINT_TO_POINTER(13));
used = g_list_append(used, GINT_TO_POINTER(20));
int result = get_next_available_win_num(used);
assert_int_equals(11, result);
}
void next_available_24_first_big_gap(void)
{
GList *used = NULL;
used = g_list_append(used, GINT_TO_POINTER(1));
used = g_list_append(used, GINT_TO_POINTER(2));
used = g_list_append(used, GINT_TO_POINTER(3));
used = g_list_append(used, GINT_TO_POINTER(4));
used = g_list_append(used, GINT_TO_POINTER(5));
used = g_list_append(used, GINT_TO_POINTER(6));
used = g_list_append(used, GINT_TO_POINTER(7));
used = g_list_append(used, GINT_TO_POINTER(8));
used = g_list_append(used, GINT_TO_POINTER(9));
used = g_list_append(used, GINT_TO_POINTER(0));
used = g_list_append(used, GINT_TO_POINTER(11));
used = g_list_append(used, GINT_TO_POINTER(12));
used = g_list_append(used, GINT_TO_POINTER(13));
used = g_list_append(used, GINT_TO_POINTER(14));
used = g_list_append(used, GINT_TO_POINTER(15));
used = g_list_append(used, GINT_TO_POINTER(16));
used = g_list_append(used, GINT_TO_POINTER(17));
used = g_list_append(used, GINT_TO_POINTER(18));
used = g_list_append(used, GINT_TO_POINTER(19));
used = g_list_append(used, GINT_TO_POINTER(20));
used = g_list_append(used, GINT_TO_POINTER(21));
used = g_list_append(used, GINT_TO_POINTER(22));
used = g_list_append(used, GINT_TO_POINTER(23));
used = g_list_append(used, GINT_TO_POINTER(51));
used = g_list_append(used, GINT_TO_POINTER(52));
used = g_list_append(used, GINT_TO_POINTER(53));
used = g_list_append(used, GINT_TO_POINTER(89));
used = g_list_append(used, GINT_TO_POINTER(90));
used = g_list_append(used, GINT_TO_POINTER(100));
used = g_list_append(used, GINT_TO_POINTER(101));
used = g_list_append(used, GINT_TO_POINTER(102));
int result = get_next_available_win_num(used);
assert_int_equals(24, result);
}
void register_common_tests(void)
{
TEST_MODULE("common tests");
@ -162,4 +439,23 @@ void register_common_tests(void)
TEST(replace_when_sub_null);
TEST(replace_when_new_empty);
TEST(replace_when_new_null);
TEST(compare_win_nums_less);
TEST(compare_win_nums_equal);
TEST(compare_win_nums_greater);
TEST(compare_0s_equal);
TEST(compare_0_greater_than_1);
TEST(compare_1_less_than_0);
TEST(compare_0_less_than_11);
TEST(compare_11_greater_than_0);
TEST(compare_0_greater_than_9);
TEST(compare_9_less_than_0);
TEST(next_available_when_only_console);
TEST(next_available_3_at_end);
TEST(next_available_9_at_end);
TEST(next_available_0_at_end);
TEST(next_available_2_in_first_gap);
TEST(next_available_9_in_first_gap);
TEST(next_available_0_in_first_gap);
TEST(next_available_11_in_first_gap);
TEST(next_available_24_first_big_gap);
}