# HG changeset patch # User Sadrul Habib Chowdhury # Date 1153417089 0 # Node ID df8183b7fa2c5959a5f1b352a0228b88231cb17f # Parent 4a2e9c494beded91062ac38067f154d3e682e215 [gaim-migrate @ 16529] Make multi-column trees look nice. Show the list of users in a chat-room after you join. Add some commands (eg. /me, /help etc., all Xeroxed from gtkconv.c) committer: Tailor Script diff -r 4a2e9c494bed -r df8183b7fa2c console/gntconv.c --- a/console/gntconv.c Thu Jul 20 13:04:35 2006 +0000 +++ b/console/gntconv.c Thu Jul 20 17:38:09 2006 +0000 @@ -245,11 +245,12 @@ { if (flags & GAIM_MESSAGE_SEND) { - who = gaim_connection_get_display_name(conv->account->gc); + GaimAccount *account = gaim_conversation_get_account(conv); + who = gaim_connection_get_display_name(gaim_account_get_connection(account)); if (!who) - who = gaim_account_get_alias(conv->account); + who = gaim_account_get_alias(account); if (!who) - who = gaim_account_get_username(conv->account); + who = gaim_account_get_username(account); } else if (flags & GAIM_MESSAGE_RECV) who = gaim_conversation_get_name(conv); @@ -273,20 +274,48 @@ } static void -gg_chat_add_users(GaimConversation *conv, GList *users, GList *flags, GList *aliases, gboolean new_arrivals) -{} +gg_chat_add_users(GaimConversation *conv, GList *users, gboolean new_arrivals) +{ + if (!new_arrivals) + { + /* Print the list of users in the room */ + GString *string = g_string_new(_("List of users:\n")); + GList *iter; + + for (iter = users; iter; iter = iter->next) + { + GaimConvChatBuddy *cbuddy = iter->data; + char *str; + + if ((str = cbuddy->alias) == NULL) + str = cbuddy->name; + g_string_append_printf(string, "[ %s ]", str); + } + + gaim_conversation_write(conv, NULL, string->str, + GAIM_MESSAGE_SYSTEM, time(NULL)); + g_string_free(string, TRUE); + } + /* XXX: Add the names for string completion */ +} static void gg_chat_rename_user(GaimConversation *conv, const char *old, const char *new_n, const char *new_a) -{} +{ + /* XXX: Update the name for string completion */ +} static void gg_chat_remove_user(GaimConversation *conv, GList *list) -{} +{ + /* XXX: Remove the name from string completion */ +} static void gg_chat_update_user(GaimConversation *conv, const char *user) -{} +{ + /* XXX: This probably will not require updating the string completion */ +} static GaimConversationUiOps conv_ui_ops = { @@ -309,9 +338,9 @@ static void destroy_ggconv(gpointer data) { - GGConv *conv = data; - gnt_widget_destroy(conv->window); - g_free(conv); + GGConv *ggconv = data; + gnt_widget_destroy(ggconv->window); + g_free(ggconv); } GaimConversationUiOps *gg_conv_get_ui_ops() @@ -319,10 +348,132 @@ return &conv_ui_ops; } +/* Xerox */ +static GaimCmdRet +say_command_cb(GaimConversation *conv, + const char *cmd, char **args, char **error, void *data) +{ + if (gaim_conversation_get_type(conv) == GAIM_CONV_TYPE_IM) + gaim_conv_im_send(GAIM_CONV_IM(conv), args[0]); + else if (gaim_conversation_get_type(conv) == GAIM_CONV_TYPE_CHAT) + gaim_conv_chat_send(GAIM_CONV_CHAT(conv), args[0]); + + return GAIM_CMD_RET_OK; +} + +/* Xerox */ +static GaimCmdRet +me_command_cb(GaimConversation *conv, + const char *cmd, char **args, char **error, void *data) +{ + char *tmp; + + tmp = g_strdup_printf("/me %s", args[0]); + + if (gaim_conversation_get_type(conv) == GAIM_CONV_TYPE_IM) + gaim_conv_im_send(GAIM_CONV_IM(conv), tmp); + else if (gaim_conversation_get_type(conv) == GAIM_CONV_TYPE_CHAT) + gaim_conv_chat_send(GAIM_CONV_CHAT(conv), tmp); + + g_free(tmp); + return GAIM_CMD_RET_OK; +} + +/* Xerox */ +static GaimCmdRet +debug_command_cb(GaimConversation *conv, + const char *cmd, char **args, char **error, void *data) +{ + char *tmp, *markup; + GaimCmdStatus status; + + if (!g_ascii_strcasecmp(args[0], "version")) { + tmp = g_strdup_printf("me is using %s.", VERSION); + markup = g_markup_escape_text(tmp, -1); + + status = gaim_cmd_do_command(conv, tmp, markup, error); + + g_free(tmp); + g_free(markup); + return status; + } else { + gaim_conversation_write(conv, NULL, _("Supported debug options are: version"), + GAIM_MESSAGE_NO_LOG|GAIM_MESSAGE_ERROR, time(NULL)); + return GAIM_CMD_STATUS_OK; + } +} + +/* Xerox */ +static GaimCmdRet +clear_command_cb(GaimConversation *conv, + const char *cmd, char **args, char **error, void *data) +{ + GGConv *ggconv = conv->ui_data; + gnt_text_view_clear(GNT_TEXT_VIEW(ggconv->tv)); + return GAIM_CMD_STATUS_OK; +} + +/* Xerox */ +static GaimCmdRet +help_command_cb(GaimConversation *conv, + const char *cmd, char **args, char **error, void *data) +{ + GList *l, *text; + GString *s; + + if (args[0] != NULL) { + s = g_string_new(""); + text = gaim_cmd_help(conv, args[0]); + + if (text) { + for (l = text; l; l = l->next) + if (l->next) + g_string_append_printf(s, "%s\n", (char *)l->data); + else + g_string_append_printf(s, "%s", (char *)l->data); + } else { + g_string_append(s, _("No such command (in this context).")); + } + } else { + s = g_string_new(_("Use \"/help <command>\" for help on a specific command.\n" + "The following commands are available in this context:\n")); + + text = gaim_cmd_list(conv); + for (l = text; l; l = l->next) + if (l->next) + g_string_append_printf(s, "%s, ", (char *)l->data); + else + g_string_append_printf(s, "%s.", (char *)l->data); + g_list_free(text); + } + + gaim_conversation_write(conv, NULL, s->str, GAIM_MESSAGE_NO_LOG, time(NULL)); + g_string_free(s, TRUE); + + return GAIM_CMD_STATUS_OK; +} + void gg_conversation_init() { ggconvs = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, destroy_ggconv); + + /* Xerox */ + gaim_cmd_register("say", "S", GAIM_CMD_P_DEFAULT, + GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_IM, NULL, + say_command_cb, _("say <message>: Send a message normally as if you weren't using a command."), NULL); + gaim_cmd_register("me", "S", GAIM_CMD_P_DEFAULT, + GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_IM, NULL, + me_command_cb, _("me <action>: Send an IRC style action to a buddy or chat."), NULL); + gaim_cmd_register("debug", "w", GAIM_CMD_P_DEFAULT, + GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_IM, NULL, + debug_command_cb, _("debug <option>: Send various debug information to the current conversation."), NULL); + gaim_cmd_register("clear", "", GAIM_CMD_P_DEFAULT, + GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_IM, NULL, + clear_command_cb, _("clear: Clears the conversation scrollback."), NULL); + gaim_cmd_register("help", "w", GAIM_CMD_P_DEFAULT, + GAIM_CMD_FLAG_CHAT | GAIM_CMD_FLAG_IM | GAIM_CMD_FLAG_ALLOW_WRONG_ARGS, NULL, + help_command_cb, _("help <command>: Help on a specific command."), NULL); } void gg_conversation_uninit() diff -r 4a2e9c494bed -r df8183b7fa2c console/gntnotify.c --- a/console/gntnotify.c Thu Jul 20 13:04:35 2006 +0000 +++ b/console/gntnotify.c Thu Jul 20 17:38:09 2006 +0000 @@ -104,6 +104,8 @@ gnt_label_new_with_format(_("You have mail!"), GNT_TEXT_FLAG_BOLD)); emaildialog.tree = tree = gnt_tree_new_with_columns(3); + gnt_tree_set_column_titles(GNT_TREE(tree), _("Account"), _("From"), _("Subject")); + gnt_tree_set_show_title(GNT_TREE(tree), TRUE); gnt_tree_set_col_width(GNT_TREE(tree), 0, 15); gnt_tree_set_col_width(GNT_TREE(tree), 1, 25); gnt_tree_set_col_width(GNT_TREE(tree), 2, 25); @@ -141,7 +143,7 @@ gnt_tree_add_row_after(GNT_TREE(emaildialog.tree), GINT_TO_POINTER(time(NULL)), gnt_tree_create_row(GNT_TREE(emaildialog.tree), - tos ? *tos : gaim_account_get_username(account), + tos ? *tos : gaim_account_get_username(account), /* XXX: Perhaps add the prpl-name */ froms ? *froms : "[Unknown sender]", *subjects), NULL, NULL); diff -r 4a2e9c494bed -r df8183b7fa2c console/libgnt/gnttextview.c --- a/console/libgnt/gnttextview.c Thu Jul 20 13:04:35 2006 +0000 +++ b/console/libgnt/gnttextview.c Thu Jul 20 17:38:09 2006 +0000 @@ -271,3 +271,18 @@ return fl; } +void gnt_text_view_clear(GntTextView *view) +{ + GntTextLine *line; + + g_list_foreach(view->list, free_text_line, NULL); + g_list_free(view->list); + view->list = NULL; + + line = g_new0(GntTextLine, 1); + view->list = g_list_append(view->list, line); + + if (GNT_WIDGET(view)->window) + gnt_widget_draw(GNT_WIDGET(view)); +} + diff -r 4a2e9c494bed -r df8183b7fa2c console/libgnt/gnttextview.h --- a/console/libgnt/gnttextview.h Thu Jul 20 13:04:35 2006 +0000 +++ b/console/libgnt/gnttextview.h Thu Jul 20 17:38:09 2006 +0000 @@ -67,6 +67,8 @@ chtype gnt_text_format_flag_to_chtype(GntTextFormatFlags flags); +void gnt_text_view_clear(GntTextView *view); + G_END_DECLS #endif /* GNT_TEXT_VIEW_H */ diff -r 4a2e9c494bed -r df8183b7fa2c console/libgnt/gnttree.c --- a/console/libgnt/gnttree.c Thu Jul 20 13:04:35 2006 +0000 +++ b/console/libgnt/gnttree.c Thu Jul 20 17:38:09 2006 +0000 @@ -185,7 +185,6 @@ char *text; int len = g_utf8_strlen(col->text, -1); int fl = 0; - gboolean ell = FALSE; if (i == 0) { @@ -220,22 +219,31 @@ if (len > tree->columns[i].width) { len = tree->columns[i].width; - ell = TRUE; } - text = g_utf8_offset_to_pointer(col->text, len - fl - ell); + text = g_utf8_offset_to_pointer(col->text, len - fl); string = g_string_append_len(string, col->text, text - col->text); if (len < tree->columns[i].width) g_string_append_printf(string, "%*s", tree->columns[i].width - len, ""); - else if (ell) - { - g_string_append_unichar(string, (gunichar)2026); - } } return g_string_free(string, FALSE); } static void +tree_mark_columns(GntTree *tree, int pos, int y, chtype type) +{ + GntWidget *widget = GNT_WIDGET(tree); + int i; + int x = pos; + + for (i = 0; i < tree->ncol - 1; i++) + { + x += tree->columns[i].width; + mvwaddch(widget->window, y, x + i, type); + } +} + +static void redraw_tree(GntTree *tree) { int start; @@ -255,8 +263,29 @@ wbkgd(widget->window, COLOR_PAIR(GNT_COLOR_NORMAL)); + start = 0; + if (tree->show_title) + { + int i; + int x = pos; + + mvwhline(widget->window, pos + 1, pos, ACS_HLINE | COLOR_PAIR(GNT_COLOR_NORMAL), + widget->priv.width - pos - 1); + + for (i = 0; i < tree->ncol; i++) + { + mvwprintw(widget->window, pos, x + i, tree->columns[i].title); + x += tree->columns[i].width; + } + if (pos) + tree_mark_columns(tree, pos, 0, ACS_TTEE | COLOR_PAIR(GNT_COLOR_NORMAL)); + tree_mark_columns(tree, pos, pos + 1, ACS_PLUS | COLOR_PAIR(GNT_COLOR_NORMAL)); + tree_mark_columns(tree, pos, pos, ACS_VLINE | COLOR_PAIR(GNT_COLOR_NORMAL)); + start = 2; + } + row = tree->top; - for (start = pos; row && start < widget->priv.height - pos; + for (start = start + pos; row && start < widget->priv.height - pos; start++, row = get_next(row)) { char *str; @@ -303,6 +332,7 @@ whline(widget->window, ' ', widget->priv.width - pos * 2 - g_utf8_strlen(str, -1)); tree->bottom = row; g_free(str); + tree_mark_columns(tree, pos, start, ACS_VLINE | attr); } wbkgdset(widget->window, '\0' | COLOR_PAIR(GNT_COLOR_NORMAL)); @@ -310,6 +340,7 @@ { mvwhline(widget->window, start, pos, ' ', widget->priv.width - pos * 2); + tree_mark_columns(tree, pos, start, ACS_VLINE); start++; } @@ -424,9 +455,16 @@ gnt_tree_destroy(GntWidget *widget) { GntTree *tree = GNT_TREE(widget); + int i; g_hash_table_destroy(tree->hash); g_list_free(tree->list); + + for (i = 0; i < tree->ncol; i++) + { + g_free(tree->columns[i].title); + } + g_free(tree->columns); } static void @@ -813,6 +851,7 @@ { tree->columns[col].width = 15; } + tree->show_title = FALSE; GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_NO_SHADOW); gnt_widget_set_take_focus(widget, TRUE); @@ -836,6 +875,7 @@ row->columns = g_list_append(row->columns, col); } + va_end(args); return row; } @@ -847,3 +887,22 @@ tree->columns[col].width = width; } +void gnt_tree_set_column_titles(GntTree *tree, ...) +{ + int i; + va_list args; + + va_start(args, tree); + for (i = 0; i < tree->ncol; i++) + { + const char *title = va_arg(args, const char *); + tree->columns[i].title = g_strdup(title); + } + va_end(args); +} + +void gnt_tree_set_show_title(GntTree *tree, gboolean set) +{ + tree->show_title = set; +} + diff -r 4a2e9c494bed -r df8183b7fa2c console/libgnt/gnttree.h --- a/console/libgnt/gnttree.h Thu Jul 20 13:04:35 2006 +0000 +++ b/console/libgnt/gnttree.h Thu Jul 20 17:38:09 2006 +0000 @@ -37,14 +37,15 @@ GntTreeRow *root; /* The root of all evil */ GList *list; /* List of GntTreeRow s */ - GHashTable *hash; /* XXX: We may need this for quickly referencing the rows */ + GHashTable *hash; /* We need this for quickly referencing the rows */ int ncol; /* No. of columns */ struct _GntTreeColInfo { int width; - int *name; + char *title; } *columns; /* Would a GList be better? */ + gboolean show_title; }; struct _GnTreeClass @@ -100,6 +101,10 @@ void gnt_tree_set_col_width(GntTree *tree, int col, int width); +void gnt_tree_set_column_titles(GntTree *tree, ...); + +void gnt_tree_set_show_title(GntTree *tree, gboolean set); + G_END_DECLS #endif /* GNT_TREE_H */ diff -r 4a2e9c494bed -r df8183b7fa2c console/libgnt/test/multiwin.c --- a/console/libgnt/test/multiwin.c Thu Jul 20 13:04:35 2006 +0000 +++ b/console/libgnt/test/multiwin.c Thu Jul 20 17:38:09 2006 +0000 @@ -26,7 +26,9 @@ gnt_widget_set_name(hbox, "hbox"); gnt_widget_set_name(box2, "box2"); - tree = gnt_tree_new(); + tree = gnt_tree_new_with_columns(3); + gnt_tree_set_column_titles(GNT_TREE(tree), "12345678901234567890", "column 2", "column3"); + gnt_tree_set_show_title(GNT_TREE(tree), TRUE); gnt_widget_set_name(tree, "tree"); gnt_box_add_widget(GNT_BOX(hbox), tree); @@ -43,19 +45,21 @@ gnt_widget_set_position(box2, 35, 15); gnt_widget_show(box2); - gnt_tree_add_row_after(GNT_TREE(tree), "a", gnt_tree_create_row(GNT_TREE(tree), "a"), NULL, NULL); - gnt_tree_add_row_after(GNT_TREE(tree), "c", gnt_tree_create_row(GNT_TREE(tree), "c"), NULL, NULL); - gnt_tree_add_row_after(GNT_TREE(tree), "d", gnt_tree_create_row(GNT_TREE(tree), "d"), NULL, NULL); - gnt_tree_add_row_after(GNT_TREE(tree), "e", gnt_tree_create_row(GNT_TREE(tree), "e"), "a", NULL); - gnt_tree_add_row_after(GNT_TREE(tree), "b", gnt_tree_create_row(GNT_TREE(tree), "b"), "d", NULL); + gnt_tree_add_row_after(GNT_TREE(tree), "a", + gnt_tree_create_row(GNT_TREE(tree), "alaskdjfkashfashfah kfalkdhflsiafhlasf", " long text", "a2"), NULL, NULL); + gnt_tree_add_row_after(GNT_TREE(tree), "c", + gnt_tree_create_row(GNT_TREE(tree), "casdgertqhyeqgasfeytwfga fg arf agfwa ", " long text", "a2"), NULL, NULL); + gnt_tree_add_row_after(GNT_TREE(tree), "d", gnt_tree_create_row(GNT_TREE(tree), "d", " long text", "a2"), NULL, NULL); + gnt_tree_add_row_after(GNT_TREE(tree), "e", gnt_tree_create_row(GNT_TREE(tree), "e", " long text", "a2"), "a", NULL); + gnt_tree_add_row_after(GNT_TREE(tree), "b", gnt_tree_create_row(GNT_TREE(tree), "b", "this is", "a2"), "d", NULL); - gnt_tree_add_choice(GNT_TREE(tree), "1", gnt_tree_create_row(GNT_TREE(tree), "1"), NULL, NULL); - gnt_tree_add_row_after(GNT_TREE(tree), "2", gnt_tree_create_row(GNT_TREE(tree), "2"), NULL, NULL); - gnt_tree_add_row_after(GNT_TREE(tree), "3", gnt_tree_create_row(GNT_TREE(tree), "3"), NULL, NULL); - gnt_tree_add_row_after(GNT_TREE(tree), "4", gnt_tree_create_row(GNT_TREE(tree), "4"), "a", NULL); - gnt_tree_add_row_after(GNT_TREE(tree), "5", gnt_tree_create_row(GNT_TREE(tree), "5"), "d", NULL); + gnt_tree_add_choice(GNT_TREE(tree), "1", gnt_tree_create_row(GNT_TREE(tree), "1", " long text", "a2"), NULL, NULL); + gnt_tree_add_row_after(GNT_TREE(tree), "2", gnt_tree_create_row(GNT_TREE(tree), "2", " long text", "a2"), NULL, NULL); + gnt_tree_add_row_after(GNT_TREE(tree), "3", gnt_tree_create_row(GNT_TREE(tree), "3", " long text", "a2"), NULL, NULL); + gnt_tree_add_row_after(GNT_TREE(tree), "4", gnt_tree_create_row(GNT_TREE(tree), "4", " long text", "a2"), "a", NULL); + gnt_tree_add_row_after(GNT_TREE(tree), "5", gnt_tree_create_row(GNT_TREE(tree), "5", " long text", "a2"), "d", NULL); - gnt_tree_add_row_after(GNT_TREE(tree), "6", gnt_tree_create_row(GNT_TREE(tree), "6"), "4", NULL); + gnt_tree_add_row_after(GNT_TREE(tree), "6", gnt_tree_create_row(GNT_TREE(tree), "6", " long text", "a2"), "4", NULL); gnt_tree_set_row_flags(GNT_TREE(tree), "e", GNT_TEXT_FLAG_DIM);