# HG changeset patch # User William Ehlhardt # Date 1183868822 0 # Node ID 2e064085b7df5c54bce990481d5fdd3b1468d405 # Parent 45865fb3f4f93c9a6214c8e27eea70c5405a92f5# Parent d4065b26dcac8bd2f0df79ba21d93e512b0d20cb propagate from branch 'im.pidgin.pidgin' (head 1ede3f4c61fab6e6979e40b2169494d27af5f528) to branch 'im.pidgin.soc.2007.certmgr' (head 27afef9aea7ea6baa4c0bcc8ddc0dcb3282d747e) diff -r d4065b26dcac -r 2e064085b7df ChangeLog --- a/ChangeLog Sun Jul 08 04:23:55 2007 +0000 +++ b/ChangeLog Sun Jul 08 04:27:02 2007 +0000 @@ -22,6 +22,7 @@ * A new status area has been added to the top of conversations to provide additional detail about the buddy, including buddy icon, protocol and status message. + * Show idle times in the buddy list as days, hours, seconds Finch: * There's support for workspaces now (details in the manpage) @@ -29,6 +30,7 @@ * Some improvements for tab-completion, tooltip and the password entries * Some bugs regarding search results fixed * A new DBus-script to create a docklet for finch + * Support for showing empty groups in the buddy list (Eric Polino) version 2.0.2 (06/14/2007): Pidgin: diff -r d4065b26dcac -r 2e064085b7df finch/gntaccount.c --- a/finch/gntaccount.c Sun Jul 08 04:23:55 2007 +0000 +++ b/finch/gntaccount.c Sun Jul 08 04:27:02 2007 +0000 @@ -472,6 +472,14 @@ } } + list = purple_plugins_get_protocols(); + if (list == NULL) { + purple_notify_error(NULL, _("Error"), + _("There's no protocol plugins installed."), + _("(You probably forgot to 'make install'.)")); + return; + } + dialog = g_new0(AccountEditDialog, 1); accountdialogs = g_list_prepend(accountdialogs, dialog); @@ -489,7 +497,6 @@ gnt_box_add_widget(GNT_BOX(window), hbox); dialog->protocol = combo = gnt_combo_box_new(); - list = purple_plugins_get_protocols(); for (iter = list; iter; iter = iter->next) { gnt_combo_box_add_data(GNT_COMBO_BOX(combo), iter->data, diff -r d4065b26dcac -r 2e064085b7df finch/gntblist.c --- a/finch/gntblist.c Sun Jul 08 04:23:55 2007 +0000 +++ b/finch/gntblist.c Sun Jul 08 04:27:02 2007 +0000 @@ -195,8 +195,8 @@ node_update(list, (PurpleBlistNode*)contact); } else if (!PURPLE_BLIST_NODE_IS_GROUP(node)) { PurpleGroup *group = (PurpleGroup*)node->parent; - if ((!purple_prefs_get_bool(PREF_ROOT "/showoffline") && !is_group_online(group)) || - group->currentsize < 1) + if ((group->currentsize < 1 && !purple_prefs_get_bool(PREF_ROOT "/emptygroups")) || + (!purple_prefs_get_bool(PREF_ROOT "/showoffline") && !is_group_online(group))) node_remove(list, node->parent); for (node = node->child; node; node = node->next) node->ui_data = NULL; @@ -253,8 +253,9 @@ } } else if (PURPLE_BLIST_NODE_IS_GROUP(node)) { PurpleGroup *group = (PurpleGroup*)node; - if ((!purple_prefs_get_bool(PREF_ROOT "/showoffline") && !is_group_online(group)) || - group->currentsize < 1) + if (!purple_prefs_get_bool(PREF_ROOT "/emptygroups") && + ((!purple_prefs_get_bool(PREF_ROOT "/showoffline") && !is_group_online(group)) || + group->currentsize < 1)) node_remove(list, node); else add_node(node, list->ui_data); @@ -507,21 +508,24 @@ gboolean ascii = gnt_ascii_only(); presence = purple_buddy_get_presence(buddy); - now = purple_presence_get_active_status(presence); + if (purple_presence_is_status_primitive_active(presence, PURPLE_STATUS_MOBILE)) + strncpy(status, ascii ? ":" : "☎", sizeof(status) - 1); + else { + now = purple_presence_get_active_status(presence); - prim = purple_status_type_get_primitive(purple_status_get_type(now)); + prim = purple_status_type_get_primitive(purple_status_get_type(now)); - switch(prim) - { - case PURPLE_STATUS_OFFLINE: - strncpy(status, ascii ? "x" : "⊗", sizeof(status) - 1); - break; - case PURPLE_STATUS_AVAILABLE: - strncpy(status, ascii ? "o" : "◯", sizeof(status) - 1); - break; - default: - strncpy(status, ascii ? "." : "⊖", sizeof(status) - 1); - break; + switch(prim) { + case PURPLE_STATUS_OFFLINE: + strncpy(status, ascii ? "x" : "⊗", sizeof(status) - 1); + break; + case PURPLE_STATUS_AVAILABLE: + strncpy(status, ascii ? "o" : "◯", sizeof(status) - 1); + break; + default: + strncpy(status, ascii ? "." : "⊖", sizeof(status) - 1); + break; + } } name = purple_buddy_get_alias(buddy); } @@ -590,6 +594,9 @@ if (node->ui_data) return; + if (!purple_account_is_connected(buddy->account)) + return; + contact = (PurpleContact*)node->parent; if (!contact) /* When a new buddy is added and show-offline is set */ return; @@ -1266,12 +1273,14 @@ PurplePluginProtocolInfo *prpl_info; PurpleAccount *account; PurpleNotifyUserInfo *user_info; + PurplePresence *presence; const char *alias = purple_buddy_get_alias(buddy); char *tmp, *strip; user_info = purple_notify_user_info_new(); account = purple_buddy_get_account(buddy); + presence = purple_buddy_get_presence(buddy); if (!full || g_utf8_collate(purple_buddy_get_name(buddy), alias)) purple_notify_user_info_add_pair(user_info, _("Nickname"), alias); @@ -1305,6 +1314,10 @@ strip = purple_markup_strip_html(tmp); g_string_append(str, strip); + + if (purple_presence_is_status_primitive_active(presence, PURPLE_STATUS_MOBILE)) + g_string_append(str, _("On Mobile")); + g_free(strip); g_free(tmp); } @@ -1714,9 +1727,12 @@ purple_prefs_add_int(PREF_ROOT "/position/y", 0); purple_prefs_add_bool(PREF_ROOT "/idletime", TRUE); purple_prefs_add_bool(PREF_ROOT "/showoffline", FALSE); + purple_prefs_add_bool(PREF_ROOT "/emptygroups", FALSE); purple_prefs_add_string(PREF_ROOT "/sort_type", "text"); purple_prefs_connect_callback(finch_blist_get_handle(), + PREF_ROOT "/emptygroups", redraw_blist, NULL); + purple_prefs_connect_callback(finch_blist_get_handle(), PREF_ROOT "/showoffline", redraw_blist, NULL); purple_prefs_connect_callback(finch_blist_get_handle(), PREF_ROOT "/sort_type", redraw_blist, NULL); @@ -2124,10 +2140,9 @@ } } -static void show_offline_cb(GntMenuItem *item, gpointer n) +static void toggle_pref_cb(GntMenuItem *item, gpointer n) { - purple_prefs_set_bool(PREF_ROOT "/showoffline", - !purple_prefs_get_bool(PREF_ROOT "/showoffline")); + purple_prefs_set_bool(n, !purple_prefs_get_bool(n)); } static void sort_blist_change_cb(GntMenuItem *item, gpointer n) @@ -2135,7 +2150,7 @@ purple_prefs_set_string(PREF_ROOT "/sort_type", n); } -/* XXX: send_im_select* -- Xerox */ +/* send_im_select* -- Xerox */ static void send_im_select_cb(gpointer data, PurpleRequestFields *fields) { @@ -2208,11 +2223,17 @@ gnt_menu_add_item(GNT_MENU(sub), item); gnt_menuitem_set_callback(GNT_MENU_ITEM(item), send_im_select, NULL); + item = gnt_menuitem_check_new(_("Show empty groups")); + gnt_menuitem_check_set_checked(GNT_MENU_ITEM_CHECK(item), + purple_prefs_get_bool(PREF_ROOT "/emptygroups")); + gnt_menu_add_item(GNT_MENU(sub), item); + gnt_menuitem_set_callback(GNT_MENU_ITEM(item), toggle_pref_cb, PREF_ROOT "/emptygroups"); + item = gnt_menuitem_check_new(_("Show offline buddies")); gnt_menuitem_check_set_checked(GNT_MENU_ITEM_CHECK(item), purple_prefs_get_bool(PREF_ROOT "/showoffline")); gnt_menu_add_item(GNT_MENU(sub), item); - gnt_menuitem_set_callback(GNT_MENU_ITEM(item), show_offline_cb, NULL); + gnt_menuitem_set_callback(GNT_MENU_ITEM(item), toggle_pref_cb, PREF_ROOT "/showoffline"); item = gnt_menuitem_new(_("Sort by status")); gnt_menu_add_item(GNT_MENU(sub), item); diff -r d4065b26dcac -r 2e064085b7df finch/gntconv.c --- a/finch/gntconv.c Sun Jul 08 04:23:55 2007 +0000 +++ b/finch/gntconv.c Sun Jul 08 04:27:02 2007 +0000 @@ -541,6 +541,8 @@ gnt_entry_set_always_suggest(GNT_ENTRY(ggc->entry), FALSE); gnt_text_view_attach_scroll_widget(GNT_TEXT_VIEW(ggc->tv), ggc->entry); + gnt_text_view_attach_pager_widget(GNT_TEXT_VIEW(ggc->tv), ggc->entry); + g_signal_connect_after(G_OBJECT(ggc->entry), "key_pressed", G_CALLBACK(entry_key_pressed), ggc); g_signal_connect(G_OBJECT(ggc->entry), "completion", G_CALLBACK(completion_cb), NULL); g_signal_connect(G_OBJECT(ggc->window), "destroy", G_CALLBACK(closing_window), ggc); diff -r d4065b26dcac -r 2e064085b7df finch/gntdebug.c --- a/finch/gntdebug.c Sun Jul 08 04:23:55 2007 +0000 +++ b/finch/gntdebug.c Sun Jul 08 04:27:02 2007 +0000 @@ -274,6 +274,7 @@ g_signal_connect(G_OBJECT(debug.window), "destroy", G_CALLBACK(reset_debug_win), NULL); gnt_text_view_attach_scroll_widget(GNT_TEXT_VIEW(debug.tview), debug.window); + gnt_text_view_attach_pager_widget(GNT_TEXT_VIEW(debug.tview), debug.window); gnt_widget_show(debug.window); } diff -r d4065b26dcac -r 2e064085b7df finch/libgnt/gnt.h --- a/finch/libgnt/gnt.h Sun Jul 08 04:23:55 2007 +0000 +++ b/finch/libgnt/gnt.h Sun Jul 08 04:27:02 2007 +0000 @@ -112,7 +112,7 @@ /** * * @param label - * @param callback)() + * @param callback */ void gnt_register_action(const char *label, void (*callback)()); @@ -149,3 +149,11 @@ */ void gnt_set_clipboard_string(gchar *string); +/** + * Spawn a different application that will consume the console. + */ +gboolean gnt_giveup_console(const char *wd, char **argv, char **envp, + gint *stin, gint *stout, gint *sterr); + +gboolean gnt_is_refugee(void); + diff -r d4065b26dcac -r 2e064085b7df finch/libgnt/gntcombobox.c --- a/finch/libgnt/gntcombobox.c Sun Jul 08 04:23:55 2007 +0000 +++ b/finch/libgnt/gntcombobox.c Sun Jul 08 04:27:02 2007 +0000 @@ -107,7 +107,7 @@ GntWidget *dd = GNT_COMBO_BOX(widget)->dropdown; gnt_widget_size_request(dd); widget->priv.height = 3; /* For now, a combobox will have border */ - widget->priv.width = MAX(10, dd->priv.width + 4); + widget->priv.width = MAX(10, dd->priv.width + 2); } } diff -r d4065b26dcac -r 2e064085b7df finch/libgnt/gntfilesel.c --- a/finch/libgnt/gntfilesel.c Sun Jul 08 04:23:55 2007 +0000 +++ b/finch/libgnt/gntfilesel.c Sun Jul 08 04:27:02 2007 +0000 @@ -448,6 +448,9 @@ GntFileSel *sel = GNT_FILE_SEL(widget); GntWidget *hbox, *vbox; + if (sel->current == NULL) + gnt_file_sel_set_current_location(sel, g_get_home_dir()); + vbox = gnt_vbox_new(FALSE); gnt_box_set_pad(GNT_BOX(vbox), 0); gnt_box_set_alignment(GNT_BOX(vbox), GNT_ALIGN_MID); @@ -584,7 +587,7 @@ G_STRUCT_OFFSET(GntFileSelClass, file_selected), NULL, NULL, gnt_closure_marshal_VOID__STRING_STRING, - G_TYPE_NONE, 0); + G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_STRING); gnt_bindable_class_register_action(bindable, "toggle-tag", toggle_tag_selection, "t", NULL); gnt_bindable_class_register_action(bindable, "clear-tags", clear_tags, "c", NULL); @@ -631,6 +634,16 @@ return type; } +static void +select_activated_cb(GntWidget *button, GntFileSel *sel) +{ + char *path = gnt_file_sel_get_selected_file(sel); + char *file = g_path_get_basename(path); + g_signal_emit(sel, signals[SIG_FILE_SELECTED], 0, path, file); + g_free(file); + g_free(path); +} + GntWidget *gnt_file_sel_new(void) { GntWidget *widget = g_object_new(GNT_TYPE_FILE_SEL, NULL); @@ -650,6 +663,7 @@ gnt_tree_set_show_title(GNT_TREE(sel->files), TRUE); gnt_tree_set_col_width(GNT_TREE(sel->files), 0, 25); gnt_tree_set_col_width(GNT_TREE(sel->files), 1, 10); + gnt_tree_set_column_is_right_aligned(GNT_TREE(sel->files), 1, TRUE); g_signal_connect(G_OBJECT(sel->files), "selection_changed", G_CALLBACK(file_sel_changed), sel); /* The location entry */ @@ -659,6 +673,8 @@ sel->cancel = gnt_button_new("Cancel"); sel->select = gnt_button_new("Select"); + g_signal_connect(G_OBJECT(sel->select), "activate", G_CALLBACK(select_activated_cb), sel); + return widget; } diff -r d4065b26dcac -r 2e064085b7df finch/libgnt/gntkeys.c --- a/finch/libgnt/gntkeys.c Sun Jul 08 04:23:55 2007 +0000 +++ b/finch/libgnt/gntkeys.c Sun Jul 08 04:27:02 2007 +0000 @@ -154,7 +154,7 @@ const char *gnt_key_translate(const char *name) { - return g_hash_table_lookup(specials, name); + return name ? g_hash_table_lookup(specials, name) : NULL; } typedef struct { diff -r d4065b26dcac -r 2e064085b7df finch/libgnt/gntmain.c --- a/finch/libgnt/gntmain.c Sun Jul 08 04:23:55 2007 +0000 +++ b/finch/libgnt/gntmain.c Sun Jul 08 04:27:02 2007 +0000 @@ -65,6 +65,7 @@ */ static GIOChannel *channel = NULL; +static int channel_read_callback; static gboolean ascii_only; static gboolean mouse_enabled; @@ -220,8 +221,13 @@ io_invoke(GIOChannel *source, GIOCondition cond, gpointer null) { char keys[256]; - int rd = read(STDIN_FILENO, keys + HOLDING_ESCAPE, sizeof(keys) - 1 - HOLDING_ESCAPE); + int rd; char *k; + + if (wm->mode == GNT_KP_MODE_WAIT_ON_CHILD) + return FALSE; + + rd = read(STDIN_FILENO, keys + HOLDING_ESCAPE, sizeof(keys) - 1 - HOLDING_ESCAPE); if (rd < 0) { int ch = getch(); /* This should return ERR, but let's see what it really returns */ @@ -288,7 +294,7 @@ g_io_channel_set_flags(channel, G_IO_FLAG_NONBLOCK, NULL ); #endif - result = g_io_add_watch_full(channel, G_PRIORITY_HIGH, + channel_read_callback = result = g_io_add_watch_full(channel, G_PRIORITY_HIGH, (G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_PRI), io_invoke, NULL, NULL); @@ -346,6 +352,14 @@ static GntWidget *win = NULL; GntWidget *bbox, *button; + if (wm->menu) { + do { + gnt_widget_hide(GNT_WIDGET(wm->menu)); + if (wm->menu) + wm->menu = wm->menu->parentmenu; + } while (wm->menu); + } + if (win) goto raise; @@ -622,7 +636,51 @@ { return clipboard; } + gchar *gnt_get_clipboard_string() { return gnt_clipboard_get_string(clipboard); } + +#if GLIB_CHECK_VERSION(2,4,0) +static void +reap_child(GPid pid, gint status, gpointer data) +{ + wm->mode = GNT_KP_MODE_NORMAL; + clear(); + setup_io(); + refresh_screen(); +} +#endif + +gboolean gnt_giveup_console(const char *wd, char **argv, char **envp, + gint *stin, gint *stout, gint *sterr) +{ +#if GLIB_CHECK_VERSION(2,4,0) + GPid pid = 0; + + if (!g_spawn_async_with_pipes(wd, argv, envp, + G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD, + (GSpawnChildSetupFunc)endwin, NULL, + &pid, stin, stout, sterr, NULL)) + return FALSE; + + g_source_remove(channel_read_callback); + wm->mode = GNT_KP_MODE_WAIT_ON_CHILD; + g_child_watch_add(pid, reap_child, NULL); + + return TRUE; +#else + return FALSE; +#endif +} + +gboolean gnt_is_refugee() +{ +#if GLIB_CHECK_VERSION(2,4,0) + return (wm && wm->mode == GNT_KP_MODE_WAIT_ON_CHILD); +#else + return FALSE; +#endif +} + diff -r d4065b26dcac -r 2e064085b7df finch/libgnt/gntmenu.c --- a/finch/libgnt/gntmenu.c Sun Jul 08 04:23:55 2007 +0000 +++ b/finch/libgnt/gntmenu.c Sun Jul 08 04:27:02 2007 +0000 @@ -23,6 +23,7 @@ #include "gntmenu.h" #include "gntmenuitemcheck.h" +#include #include enum @@ -30,11 +31,20 @@ SIGS = 1, }; +enum +{ + ITEM_TEXT = 0, + ITEM_TRIGGER, + ITEM_SUBMENU, + NUM_COLUMNS +}; + static GntTreeClass *parent_class = NULL; static void (*org_draw)(GntWidget *wid); static void (*org_destroy)(GntWidget *wid); static void (*org_map)(GntWidget *wid); +static void (*org_size_request)(GntWidget *wid); static gboolean (*org_key_pressed)(GntWidget *w, const char *t); static void @@ -75,21 +85,26 @@ widget->priv.height = 1; widget->priv.width = getmaxx(stdscr); } else { + org_size_request(widget); widget->priv.height = g_list_length(menu->list) + 2; - widget->priv.width = 25; /* XXX: */ } } static void menu_tree_add(GntMenu *menu, GntMenuItem *item, GntMenuItem *parent) { + char trigger[4] = "\0 )\0"; + + if ((trigger[1] = gnt_menuitem_get_trigger(item)) && trigger[1] != ' ') + trigger[0] = '('; + if (GNT_IS_MENU_ITEM_CHECK(item)) { gnt_tree_add_choice(GNT_TREE(menu), item, - gnt_tree_create_row(GNT_TREE(menu), item->text, " "), parent, NULL); + gnt_tree_create_row(GNT_TREE(menu), item->text, trigger, " "), parent, NULL); gnt_tree_set_choice(GNT_TREE(menu), item, gnt_menuitem_check_get_checked(GNT_MENU_ITEM_CHECK(item))); } else gnt_tree_add_row_last(GNT_TREE(menu), item, - gnt_tree_create_row(GNT_TREE(menu), item->text, item->submenu ? ">" : " "), parent); + gnt_tree_create_row(GNT_TREE(menu), item->text, trigger, item->submenu ? ">" : " "), parent); if (0 && item->submenu) { GntMenu *sub = GNT_MENU(item->submenu); @@ -101,6 +116,45 @@ } } +#define GET_VAL(ch) ((ch >= '0' && ch <= '9') ? (ch - '0') : (ch >= 'a' && ch <= 'z') ? (10 + ch - 'a') : 36) + +static void +assign_triggers(GntMenu *menu) +{ + GList *iter; + gboolean bools[37]; + + memset(bools, 0, sizeof(bools)); + bools[36] = 1; + + for (iter = menu->list; iter; iter = iter->next) { + GntMenuItem *item = iter->data; + char trigger = tolower(gnt_menuitem_get_trigger(item)); + if (trigger == '\0' || trigger == ' ') + continue; + bools[(int)GET_VAL(trigger)] = 1; + } + + for (iter = menu->list; iter; iter = iter->next) { + GntMenuItem *item = iter->data; + char trigger = gnt_menuitem_get_trigger(item); + const char *text = item->text; + if (trigger != '\0') + continue; + while (*text) { + char ch = tolower(*text++); + if (ch == ' ' || bools[(int)GET_VAL(ch)]) + continue; + trigger = ch; + break; + } + if (trigger == 0) + trigger = item->text[0]; + gnt_menuitem_set_trigger(item, trigger); + bools[(int)GET_VAL(trigger)] = 1; + } +} + static void gnt_menu_map(GntWidget *widget) { @@ -112,6 +166,8 @@ /* Populate the tree */ GList *iter; gnt_tree_remove_all(GNT_TREE(widget)); + /* Try to assign some trigger for the items */ + assign_triggers(menu); for (iter = menu->list; iter; iter = iter->next) { GntMenuItem *item = GNT_MENU_ITEM(iter->data); menu_tree_add(menu, item, NULL); @@ -149,6 +205,41 @@ } } +static GList* +find_item_with_trigger(GList *start, GList *end, char trigger) +{ + GList *iter; + for (iter = start; iter != (end ? end : NULL); iter = iter->next) { + if (gnt_menuitem_get_trigger(iter->data) == trigger) + return iter; + } + return NULL; +} + +static gboolean +check_for_trigger(GntMenu *menu, char trigger) +{ + /* check for a trigger key */ + GList *iter; + GList *nth = g_list_find(menu->list, gnt_tree_get_selection_data(GNT_TREE(menu))); + GList *find = find_item_with_trigger(nth->next, NULL, trigger); + if (!find) + find = find_item_with_trigger(menu->list, nth->next, trigger); + if (!find) + return FALSE; + if (find != nth) { + gnt_tree_set_selected(GNT_TREE(menu), find->data); + iter = find_item_with_trigger(find->next, NULL, trigger); + if (iter != NULL && iter != find) + return TRUE; + iter = find_item_with_trigger(menu->list, nth, trigger); + if (iter != NULL && iter != find) + return TRUE; + } + gnt_widget_activate(GNT_WIDGET(menu)); + return TRUE; +} + static gboolean gnt_menu_key_pressed(GntWidget *widget, const char *text) { @@ -189,6 +280,10 @@ return TRUE; } } else { + if (text[1] == '\0') { + if (check_for_trigger(menu, text[0])) + return TRUE; + } return org_key_pressed(widget, text); } @@ -260,6 +355,7 @@ org_map = wid_class->map; org_draw = wid_class->draw; org_key_pressed = wid_class->key_pressed; + org_size_request = wid_class->size_request; wid_class->destroy = gnt_menu_destroy; wid_class->draw = gnt_menu_draw; @@ -327,9 +423,11 @@ widget->priv.y = 0; } else { GNT_TREE(widget)->show_separator = FALSE; - _gnt_tree_init_internals(GNT_TREE(widget), 2); - gnt_tree_set_col_width(GNT_TREE(widget), 1, 1); /* The second column is to indicate that it has a submenu */ - gnt_tree_set_column_resizable(GNT_TREE(widget), 1, FALSE); + _gnt_tree_init_internals(GNT_TREE(widget), NUM_COLUMNS); + gnt_tree_set_col_width(GNT_TREE(widget), ITEM_TRIGGER, 3); + gnt_tree_set_column_resizable(GNT_TREE(widget), ITEM_TRIGGER, FALSE); + gnt_tree_set_col_width(GNT_TREE(widget), ITEM_SUBMENU, 1); + gnt_tree_set_column_resizable(GNT_TREE(widget), ITEM_SUBMENU, FALSE); GNT_WIDGET_UNSET_FLAGS(widget, GNT_WIDGET_NO_BORDER); } diff -r d4065b26dcac -r 2e064085b7df finch/libgnt/gntmenuitem.c --- a/finch/libgnt/gntmenuitem.c Sun Jul 08 04:23:55 2007 +0000 +++ b/finch/libgnt/gntmenuitem.c Sun Jul 08 04:27:02 2007 +0000 @@ -104,3 +104,13 @@ item->submenu = menu; } +void gnt_menuitem_set_trigger(GntMenuItem *item, char trigger) +{ + item->priv.trigger = trigger; +} + +char gnt_menuitem_get_trigger(GntMenuItem *item) +{ + return item->priv.trigger; +} + diff -r d4065b26dcac -r 2e064085b7df finch/libgnt/gntmenuitem.h --- a/finch/libgnt/gntmenuitem.h Sun Jul 08 04:23:55 2007 +0000 +++ b/finch/libgnt/gntmenuitem.h Sun Jul 08 04:27:02 2007 +0000 @@ -52,6 +52,7 @@ /* These will be used to determine the position of the submenu */ int x; int y; + char trigger; }; typedef void (*GntMenuItemCallback)(GntMenuItem *item, gpointer data); @@ -114,6 +115,25 @@ */ void gnt_menuitem_set_submenu(GntMenuItem *item, GntMenu *menu); +/** + * Set a trigger key for the item. + * + * @param item The menuitem + * @param trigger The key that will trigger the item when the parent manu is visible + */ +void gnt_menuitem_set_trigger(GntMenuItem *item, char trigger); + +/** + * Get the trigger key for a menuitem. + * + * @param item The menuitem + * + * @return The trigger key for the menuitem. + * + * @see gnt_menuitem_set_trigger + */ +char gnt_menuitem_get_trigger(GntMenuItem *item); + G_END_DECLS #endif /* GNT_MENUITEM_H */ diff -r d4065b26dcac -r 2e064085b7df finch/libgnt/gnttextview.c --- a/finch/libgnt/gnttextview.c Sun Jul 08 04:23:55 2007 +0000 +++ b/finch/libgnt/gnttextview.c Sun Jul 08 04:27:02 2007 +0000 @@ -20,9 +20,11 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include "gntstyle.h" #include "gnttextview.h" #include "gntutils.h" +#include #include enum @@ -793,3 +795,43 @@ view->flags |= flag; } +static gboolean +check_for_pager_cb(GntWidget *widget, const char *key, GntTextView *view) +{ + static const char *combin = NULL; + char *argv[] = {NULL, NULL, NULL}; + static char path[1024]; + static int len = -1; + FILE *file; + + if (combin == NULL) { + combin = gnt_key_translate(gnt_style_get_from_name("pager", "key")); + if (combin == NULL) + combin = "\033" "v"; + len = g_snprintf(path, sizeof(path), "%s" G_DIR_SEPARATOR_S "gnt", g_get_tmp_dir()); + } else { + g_snprintf(path + len, sizeof(path) - len, "XXXXXX"); + } + + if (strcmp(key, combin)) { + return FALSE; + } + + file = fdopen(g_mkstemp(path), "wb"); + if (!file) + return FALSE; + + fprintf(file, "%s", view->string->str); + fclose(file); + argv[0] = gnt_style_get_from_name("pager", "path"); + argv[0] = argv[0] ? argv[0] : getenv("PAGER"); + argv[0] = argv[0] ? argv[0] : "less"; + argv[1] = path; + return gnt_giveup_console(NULL, argv, NULL, NULL, NULL, NULL); +} + +void gnt_text_view_attach_pager_widget(GntTextView *view, GntWidget *pager) +{ + g_signal_connect(pager, "key_pressed", G_CALLBACK(check_for_pager_cb), view); +} + diff -r d4065b26dcac -r 2e064085b7df finch/libgnt/gnttextview.h --- a/finch/libgnt/gnttextview.h Sun Jul 08 04:23:55 2007 +0000 +++ b/finch/libgnt/gnttextview.h Sun Jul 08 04:27:02 2007 +0000 @@ -184,6 +184,13 @@ void gnt_text_view_attach_scroll_widget(GntTextView *view, GntWidget *widget); /** + * + * @param view + * @param widget + */ +void gnt_text_view_attach_pager_widget(GntTextView *view, GntWidget *pager); + +/** * Set a GntTextViewFlag for the textview widget. * * @param view The textview widget diff -r d4065b26dcac -r 2e064085b7df finch/libgnt/gnttree.c --- a/finch/libgnt/gnttree.c Sun Jul 08 04:23:55 2007 +0000 +++ b/finch/libgnt/gnttree.c Sun Jul 08 04:27:02 2007 +0000 @@ -32,6 +32,8 @@ #define SEARCHING(tree) (tree->search && tree->search->len > 0) #define COLUMN_INVISIBLE(tree, index) (tree->columns[index].flags & GNT_TREE_COLUMN_INVISIBLE) +#define BINARY_DATA(tree, index) (tree->columns[index].flags & GNT_TREE_COLUMN_BINARY_DATA) +#define RIGHT_ALIGNED(tree, index) (tree->columns[index].flags & GNT_TREE_COLUMN_RIGHT_ALIGNED) enum { @@ -69,6 +71,7 @@ struct _GntTreeCol { char *text; + gboolean isbinary; int span; /* How many columns does it span? */ }; @@ -84,13 +87,15 @@ int width; #define WIDTH(i) (tree->columns[i].width_ratio ? tree->columns[i].width_ratio : tree->columns[i].width) gnt_widget_get_size(GNT_WIDGET(tree), &width, NULL); + if (!GNT_WIDGET_IS_FLAG_SET(GNT_WIDGET(tree), GNT_WIDGET_NO_BORDER)) + width -= 2; for (i = 0, total = 0; i < tree->ncol ; i++) { if (tree->columns[i].flags & GNT_TREE_COLUMN_INVISIBLE) continue; if (tree->columns[i].flags & GNT_TREE_COLUMN_FIXED_SIZE) - width -= WIDTH(i); + width -= WIDTH(i) + 1; else - total += WIDTH(i); + total += WIDTH(i) + 1; } if (total == 0) @@ -136,6 +141,8 @@ { GntTree *t = row->tree; if (t->search && t->search->len > 0) { + /* XXX: Allow setting the search column. And make sure the search column + * doesn't contain binary data. */ char *one = g_utf8_casefold(((GntTreeCol*)row->columns->data)->text, -1); char *two = g_utf8_casefold(t->search->str, -1); char *z = strstr(one, two); @@ -279,27 +286,28 @@ GList *iter; int i; gboolean notfirst = FALSE; - int lastvisible = tree->ncol; - - while (lastvisible && COLUMN_INVISIBLE(tree, lastvisible)) - lastvisible--; for (i = 0, iter = row->columns; i < tree->ncol && iter; i++, iter = iter->next) { GntTreeCol *col = iter->data; const char *text; - int len = gnt_util_onscreen_width(col->text, NULL); + int len; int fl = 0; gboolean cut = FALSE; int width; + const char *display; if (COLUMN_INVISIBLE(tree, i)) continue; - if (i == lastvisible) - width = GNT_WIDGET(tree)->priv.width - gnt_util_onscreen_width(string->str, NULL); + if (BINARY_DATA(tree, i)) + display = ""; else - width = tree->columns[i].width; + display = col->text; + + len = gnt_util_onscreen_width(display, NULL); + + width = tree->columns[i].width; if (i == 0) { @@ -327,8 +335,7 @@ g_string_append_printf(string, "%*s", fl, ""); } len += fl; - } - else if (notfirst) + } else if (notfirst && tree->show_separator) g_string_append_c(string, '|'); else g_string_append_c(string, ' '); @@ -339,8 +346,13 @@ len = width - 1; cut = TRUE; } - text = gnt_util_onscreen_width_to_pointer(col->text, len - fl, NULL); - string = g_string_append_len(string, col->text, text - col->text); + + if (RIGHT_ALIGNED(tree, i) && len < tree->columns[i].width) { + g_string_append_printf(string, "%*s", width - len, ""); + } + + text = gnt_util_onscreen_width_to_pointer(display, len - fl, NULL); + string = g_string_append_len(string, display, text - display); if (cut) { /* ellipsis */ if (gnt_ascii_only()) g_string_append_c(string, '~'); @@ -349,7 +361,7 @@ len++; } - if (len < tree->columns[i].width && iter->next) + if (!RIGHT_ALIGNED(tree, i) && len < tree->columns[i].width && iter->next) g_string_append_printf(string, "%*s", width - len, ""); } return g_string_free(string, FALSE); @@ -586,9 +598,13 @@ { GntTree *tree = GNT_TREE(widget); int i, width = 0; + width = 1 + 2 * (!GNT_WIDGET_IS_FLAG_SET(GNT_WIDGET(tree), GNT_WIDGET_NO_BORDER)); for (i = 0; i < tree->ncol; i++) - if (!COLUMN_INVISIBLE(tree, i)) - width += tree->columns[i].width + 1; + if (!COLUMN_INVISIBLE(tree, i)) { + width = width + tree->columns[i].width; + if (tree->lastvisible != i) + width++; + } widget->priv.width = width; } } @@ -1003,8 +1019,8 @@ free_tree_col(gpointer data) { GntTreeCol *col = data; - - g_free(col->text); + if (col->isbinary) + g_free(col->text); g_free(col); } @@ -1390,8 +1406,12 @@ if (row) { col = g_list_nth_data(row->columns, colno); - g_free(col->text); - col->text = g_strdup(text ? text : ""); + if (BINARY_DATA(tree, colno)) { + col->text = (gpointer)text; + } else { + g_free(col->text); + col->text = g_strdup(text ? text : ""); + } if (get_distance(tree->top, row) >= 0 && get_distance(row, tree->bottom) >= 0) redraw_tree(tree); @@ -1486,6 +1506,7 @@ tree->ncol = col; tree->hash = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, free_tree_row); tree->columns = g_new0(struct _GntTreeColInfo, col); + tree->lastvisible = col - 1; while (col--) { tree->columns[col].width = 15; @@ -1517,7 +1538,13 @@ { GntTreeCol *col = g_new0(GntTreeCol, 1); col->span = 1; - col->text = g_strdup(iter->data ? iter->data : ""); + if (BINARY_DATA(tree, i)) { + col->text = iter->data; + col->isbinary = TRUE; + } else { + col->text = g_strdup(iter->data ? iter->data : ""); + col->isbinary = FALSE; + } row->columns = g_list_append(row->columns, col); } @@ -1625,9 +1652,14 @@ twidth = 1 + 2 * (!GNT_WIDGET_IS_FLAG_SET(GNT_WIDGET(tree), GNT_WIDGET_NO_BORDER)); for (i = 0; i < tree->ncol; i++) { + if (tree->columns[i].flags & GNT_TREE_COLUMN_FIXED_SIZE) + widths[i] = tree->columns[i].width; gnt_tree_set_col_width(tree, i, widths[i]); - if (!COLUMN_INVISIBLE(tree, i)) - twidth += widths[i] + (tree->show_separator ? 1 : 0) + 1; + if (!COLUMN_INVISIBLE(tree, i)) { + twidth = twidth + widths[i]; + if (tree->lastvisible != i) + twidth += 1; + } } g_free(widths); @@ -1654,6 +1686,18 @@ { g_return_if_fail(col < tree->ncol); set_column_flag(tree, col, GNT_TREE_COLUMN_INVISIBLE, !vis); + if (vis) { + /* the column is visible */ + if (tree->lastvisible < col) + tree->lastvisible = col; + } else { + if (tree->lastvisible == col) + while (tree->lastvisible) { + tree->lastvisible--; + if (!COLUMN_INVISIBLE(tree, tree->lastvisible)) + break; + } + } } void gnt_tree_set_column_resizable(GntTree *tree, int col, gboolean res) @@ -1662,6 +1706,18 @@ set_column_flag(tree, col, GNT_TREE_COLUMN_FIXED_SIZE, !res); } +void gnt_tree_set_column_is_binary(GntTree *tree, int col, gboolean bin) +{ + g_return_if_fail(col < tree->ncol); + set_column_flag(tree, col, GNT_TREE_COLUMN_FIXED_SIZE, bin); +} + +void gnt_tree_set_column_is_right_aligned(GntTree *tree, int col, gboolean right) +{ + g_return_if_fail(col < tree->ncol); + set_column_flag(tree, col, GNT_TREE_COLUMN_RIGHT_ALIGNED, right); +} + void gnt_tree_set_column_width_ratio(GntTree *tree, int cols[]) { int i; diff -r d4065b26dcac -r 2e064085b7df finch/libgnt/gnttree.h --- a/finch/libgnt/gnttree.h Sun Jul 08 04:23:55 2007 +0000 +++ b/finch/libgnt/gnttree.h Sun Jul 08 04:27:02 2007 +0000 @@ -50,6 +50,8 @@ typedef enum { GNT_TREE_COLUMN_INVISIBLE = 1 << 0, GNT_TREE_COLUMN_FIXED_SIZE = 1 << 1, + GNT_TREE_COLUMN_BINARY_DATA = 1 << 2, + GNT_TREE_COLUMN_RIGHT_ALIGNED = 1 << 3, } GntTreeColumnFlag; struct _GntTree @@ -85,6 +87,7 @@ int search_timeout; GCompareFunc compare; + int lastvisible; }; struct _GntTreeClass @@ -103,203 +106,253 @@ G_BEGIN_DECLS /** - * - * - * @return + * @return The GType for GntTree */ GType gnt_tree_get_gtype(void); /** - * + * Create a tree with one column. * - * @return + * @return The newly created tree + * + * @see gnt_tree_new_with_columns */ GntWidget * gnt_tree_new(void); - /* A tree with just one column */ - /** - * - * @param columns + * Create a tree with a specified number of columns. + * + * @param columns Number of columns * - * @return + * @return The newly created tree + * + * @see gnt_tree_new */ GntWidget * gnt_tree_new_with_columns(int columns); /** - * - * @param tree - * @param rows + * The number of rows the tree should display at a time. + * + * @param tree The tree + * @param rows The number of rows */ void gnt_tree_set_visible_rows(GntTree *tree, int rows); /** - * - * @param tree + * Get the number visible rows. * - * @return + * @param tree The tree + * + * @return The number of visible rows */ int gnt_tree_get_visible_rows(GntTree *tree); /** - * - * @param tree - * @param count + * Scroll the contents of the tree. + * + * @param tree The tree + * @param count If positive, the tree will be scrolled down by count rows, + * otherwise, it will be scrolled up by count rows. */ void gnt_tree_scroll(GntTree *tree, int count); /** - * - * @param tree - * @param key - * @param row - * @param parent - * @param bigbro + * Insert a row in the tree. * - * @return + * @param tree The tree + * @param key The key for the row + * @param row The row to insert + * @param parent The key for the parent row + * @param bigbro The key for the row to insert the new row after. + * + * @return The inserted row + * + * @see gnt_tree_create_row + * @see gnt_tree_add_row_last + * @see gnt_tree_add_choice */ GntTreeRow * gnt_tree_add_row_after(GntTree *tree, void *key, GntTreeRow *row, void *parent, void *bigbro); /** - * - * @param tree - * @param key - * @param row - * @param parent + * Insert a row at the end of the tree. * - * @return + * @param tree The tree + * @param key The key for the row + * @param row The row to insert + * @param parent The key for the parent row + * + * @return The inserted row + * + * @see gnt_tree_create_row + * @see gnt_tree_add_row_after + * @see gnt_tree_add_choice */ GntTreeRow * gnt_tree_add_row_last(GntTree *tree, void *key, GntTreeRow *row, void *parent); /** - * - * @param tree + * Get the key for the selected row. * - * @return + * @param tree The tree + * + * @return The key for the selected row */ gpointer gnt_tree_get_selection_data(GntTree *tree); -/* Returned string needs to be freed */ /** - * - * @param tree + * Get the text displayed for the selected row. * - * @return + * @param tree The tree + * + * @return The text, which needs to be freed by the caller */ char * gnt_tree_get_selection_text(GntTree *tree); /** - * - * @param tree + * Get a list of text of the current row. * - * @return + * @param tree The tree + * + * @return A list of texts of the currently selected row. The list + * and its data should be freed by the caller. */ GList * gnt_tree_get_selection_text_list(GntTree *tree); /** + * Returns the list of rows in the tree. * - * @param tree + * @param tree The tree * - * @constreturn + * @return The list of the rows. The list should not be modified by the caller. */ GList *gnt_tree_get_rows(GntTree *tree); /** - * - * @param tree - * @param key + * Remove a row from the tree. + * + * @param tree The tree + * @param key The key for the row to remove */ void gnt_tree_remove(GntTree *tree, gpointer key); /** - * - * @param tree + * Remove all the item from the tree. + * + * @param tree The tree */ void gnt_tree_remove_all(GntTree *tree); -/* Returns the visible line number of the selected row */ /** - * - * @param tree + * Get the visible line number of the selected row. * - * @return + * @param tree The tree + * + * @return The line number of the currently selected row */ int gnt_tree_get_selection_visible_line(GntTree *tree); /** - * - * @param tree - * @param key - * @param colno - * @param text + * Change the text of a column in a row. + * + * @param tree The tree + * @param key The key for the row + * @param colno The index of the column + * @param text The new text */ void gnt_tree_change_text(GntTree *tree, gpointer key, int colno, const char *text); /** - * - * @param tree - * @param key - * @param row - * @param parent - * @param bigbro + * Add a checkable item in the tree. * - * @return + * @param tree The tree + * @param key The key for the row + * @param row The row to add + * @param parent The parent of the row, or @c NULL + * @param bigbro The row to insert after, or @c NULL + * + * @return The row inserted. + * + * @see gnt_tree_create_row + * @see gnt_tree_create_row_from_list + * @see gnt_tree_add_row_last + * @see gnt_tree_add_row_after */ GntTreeRow * gnt_tree_add_choice(GntTree *tree, void *key, GntTreeRow *row, void *parent, void *bigbro); /** - * - * @param tree - * @param key - * @param set + * Set whether a checkable item is checked or not. + * + * @param tree The tree + * @param key The key for the row + * @param set @c TRUE if the item should be checked, @c FALSE if not */ void gnt_tree_set_choice(GntTree *tree, void *key, gboolean set); /** - * - * @param tree - * @param key + * Return whether a row is selected or not, where the row is a checkable item. * - * @return + * @param tree The tree + * @param key The key for the row + * + * @return @c TRUE if the row is checked, @c FALSE otherwise. */ gboolean gnt_tree_get_choice(GntTree *tree, void *key); /** - * - * @param tree - * @param key - * @param flags + * Set flags for the text in a row in the tree. + * + * @param tree The tree + * @param key The key for the row + * @param flags The flags to set */ void gnt_tree_set_row_flags(GntTree *tree, void *key, GntTextFormatFlags flags); /** - * - * @param key + * Select a row. + * + * @param tree The tree + * @param key The key of the row to select */ void gnt_tree_set_selected(GntTree *tree , void *key); /** - * - * @param tree + * Create a row to insert in the tree. + * + * @param tree The tree + * @param ... A string for each column in the tree * - * @return + * @return The row + * + * @see gnt_tree_create_row_from_list + * @see gnt_tree_add_row_after + * @see gnt_tree_add_row_last + * @see gnt_tree_add_choice */ GntTreeRow * gnt_tree_create_row(GntTree *tree, ...); /** - * - * @param tree - * @param list + * Create a row from a list of text. + * + * @param tree The tree + * @param list The list containing the text for each column * - * @return + * @return The row + * + * @see gnt_tree_create_row + * @see gnt_tree_add_row_after + * @see gnt_tree_add_row_last + * @see gnt_tree_add_choice */ GntTreeRow * gnt_tree_create_row_from_list(GntTree *tree, GList *list); /** - * - * @param tree - * @param col - * @param width + * Set the width of a column in the tree. + * + * @param tree The tree + * @param col The index of the column + * @param width The width for the column + * + * @see gnt_tree_set_column_width_ratio + * @see gnt_tree_set_column_resizable */ void gnt_tree_set_col_width(GntTree *tree, int col, int width); @@ -309,64 +362,87 @@ * @param tree The tree * @param index The index of the column * @param title The title for the column + * + * @see gnt_tree_set_column_titles + * @see gnt_tree_set_show_title */ void gnt_tree_set_column_title(GntTree *tree, int index, const char *title); /** - * - * @param tree + * Set the titles of the columns + * + * @param tree The tree + * @param ... One title for each column in the tree + * + * @see gnt_tree_set_column_title + * @see gnt_tree_set_show_title */ void gnt_tree_set_column_titles(GntTree *tree, ...); /** - * - * @param tree - * @param set + * Set whether to display the title of the columns. + * + * @param tree The tree + * @param set If @c TRUE, the column titles are displayed + * + * @see gnt_tree_set_column_title + * @see gnt_tree_set_column_titles */ void gnt_tree_set_show_title(GntTree *tree, gboolean set); /** - * - * @param tree - * @param func + * Set the compare function for sorting the data. + * + * @param tree The tree + * @param func The comparison function, which is used to compare + * the keys + * + * @see gnt_tree_sort_row */ void gnt_tree_set_compare_func(GntTree *tree, GCompareFunc func); /** - * - * @param tree - * @param key - * @param expanded + * Set whether a row, which has child rows, should be expanded. + * + * @param tree The tree + * @param key The key of the row + * @param expanded Whether to expand the child rows */ void gnt_tree_set_expanded(GntTree *tree, void *key, gboolean expanded); /** - * - * @param tree - * @param set + * Set whether to show column separators. + * + * @param tree The tree + * @param set If @c TRUE, the column separators are displayed */ void gnt_tree_set_show_separator(GntTree *tree, gboolean set); /** - * - * @param tree - * @param row + * Sort a row in the tree. + * + * @param tree The tree + * @param row The row to sort + * + * @see gnt_tree_set_compare_func */ void gnt_tree_sort_row(GntTree *tree, void *row); -/* This will try to automatically adjust the width of the columns in the tree */ /** - * - * @param tree + * Automatically adjust the width of the columns in the tree. + * + * @param tree The tree */ void gnt_tree_adjust_columns(GntTree *tree); /** - * - * @param tree - * @param hash - * @param eq - * @param kd + * Set the hash functions to use to hash, compare and free the keys. + * + * @param tree The tree + * @param hash The hashing function + * @param eq The function to compare keys + * @param kd The function to use to free the keys when a row is removed + * from the tree */ void gnt_tree_set_hash_fns(GntTree *tree, gpointer hash, gpointer eq, gpointer kd); @@ -389,10 +465,32 @@ * @param col The index of the column * @param res If @c FALSE, the column will not be resized when the * tree is resized + * + * @see gnt_tree_set_col_width + * @see gnt_tree_set_column_width_ratio */ void gnt_tree_set_column_resizable(GntTree *tree, int col, gboolean res); /** + * Set whether data in a column should be considered as binary data, and + * not as strings. A column containing binary data will be display empty text. + * + * @param tree The tree + * @param col The index of the column + * @param bin @c TRUE if the data for the column is binary + */ +void gnt_tree_set_column_is_binary(GntTree *tree, int col, gboolean bin); + +/** + * Set whether text in a column should be right-aligned. + * + * @param tree The tree + * @param col The index of the column + * @param right @c TRUE if the text in the column should be right aligned + */ +void gnt_tree_set_column_is_right_aligned(GntTree *tree, int col, gboolean right); + +/** * Set column widths to use when calculating column widths after a tree * is resized. * @@ -400,6 +498,9 @@ * @param cols Array of widths. The width must have the same number * of entries as the number of columns in the tree, or * end with a negative value for a column-width. + * + * @see gnt_tree_set_col_width + * @see gnt_tree_set_column_resizable */ void gnt_tree_set_column_width_ratio(GntTree *tree, int cols[]); @@ -408,11 +509,6 @@ /* The following functions should NOT be used by applications. */ /* This should be called by the subclasses of GntTree's in their _new function */ -/** - * - * @param tree - * @param col - */ void _gnt_tree_init_internals(GntTree *tree, int col); #endif /* GNT_TREE_H */ diff -r d4065b26dcac -r 2e064085b7df finch/libgnt/gntwm.c --- a/finch/libgnt/gntwm.c Sun Jul 08 04:23:55 2007 +0000 +++ b/finch/libgnt/gntwm.c Sun Jul 08 04:27:02 2007 +0000 @@ -204,6 +204,9 @@ static gboolean update_screen(GntWM *wm) { + if (wm->mode == GNT_KP_MODE_WAIT_ON_CHILD) + return TRUE; + if (wm->menu) { GntMenu *top = wm->menu; while (top) { @@ -377,13 +380,7 @@ else if (pos >= 0) wid = g_list_nth_data(wm->cws->list, pos); - wm->cws->ordered = g_list_bring_to_front(wm->cws->ordered, wid); - - gnt_wm_raise_window(wm, wm->cws->ordered->data); - - if (w != wid) { - gnt_widget_set_focus(w, FALSE); - } + gnt_wm_raise_window(wm, wid); } static gboolean @@ -406,7 +403,6 @@ switch_window_n(GntBindable *bind, GList *list) { GntWM *wm = GNT_WM(bind); - GntWidget *w = NULL; GList *l; int n; @@ -418,17 +414,11 @@ else n = 0; - w = wm->cws->ordered->data; - if ((l = g_list_nth(wm->cws->list, n)) != NULL) { gnt_wm_raise_window(wm, l->data); } - if (l && w != l->data) - { - gnt_widget_set_focus(w, FALSE); - } return TRUE; } @@ -1038,7 +1028,7 @@ gnt_ws_draw_taskbar(wm->cws, TRUE); curs_set(0); /* endwin resets the cursor to normal */ - return FALSE; + return TRUE; } static gboolean @@ -1362,7 +1352,6 @@ gnt_ws_draw_taskbar(wm->cws, TRUE); update_screen(wm); if (wm->cws->ordered) { - gnt_widget_set_focus(wm->cws->ordered->data, TRUE); gnt_wm_raise_window(wm, wm->cws->ordered->data); } @@ -1573,29 +1562,16 @@ if (!transient) { GntWS *ws = wm->cws; if (node->me != wm->_list.window) { - GntWidget *w = NULL; - if (GNT_IS_BOX(widget)) { ws = new_widget_find_workspace(wm, widget); } - - if (ws->ordered) - w = ws->ordered->data; - node->ws = ws; ws->list = g_list_append(ws->list, widget); - - if (wm->event_stack) - ws->ordered = g_list_prepend(ws->ordered, widget); - else - ws->ordered = g_list_append(ws->ordered, widget); - - gnt_widget_set_focus(widget, TRUE); - if (w) - gnt_widget_set_focus(w, FALSE); + ws->ordered = g_list_append(ws->ordered, widget); } - if (wm->event_stack || node->me == wm->_list.window) { + if (wm->event_stack || node->me == wm->_list.window || + node->me == ws->ordered->data) { gnt_wm_raise_window(wm, node->me); } else { bottom_panel(node->panel); /* New windows should not grab focus */ @@ -1976,6 +1952,14 @@ GntWS *ws = gnt_wm_widget_find_workspace(wm, widget); if (wm->cws != ws) gnt_wm_switch_workspace(wm, g_list_index(wm->workspaces, ws)); + if (widget != wm->cws->ordered->data) { + GntWidget *wid = wm->cws->ordered->data; + wm->cws->ordered = g_list_bring_to_front(wm->cws->ordered, widget); + gnt_widget_set_focus(wid, FALSE); + gnt_widget_draw(wid); + } + gnt_widget_set_focus(widget, TRUE); + gnt_widget_draw(widget); g_signal_emit(wm, signals[SIG_GIVE_FOCUS], 0, widget); } diff -r d4065b26dcac -r 2e064085b7df finch/libgnt/gntwm.h --- a/finch/libgnt/gntwm.h Sun Jul 08 04:23:55 2007 +0000 +++ b/finch/libgnt/gntwm.h Sun Jul 08 04:27:02 2007 +0000 @@ -46,6 +46,7 @@ GNT_KP_MODE_NORMAL, GNT_KP_MODE_RESIZE, GNT_KP_MODE_MOVE, + GNT_KP_MODE_WAIT_ON_CHILD } GntKeyPressMode; typedef struct diff -r d4065b26dcac -r 2e064085b7df finch/libgnt/gntws.c --- a/finch/libgnt/gntws.c Sun Jul 08 04:23:55 2007 +0000 +++ b/finch/libgnt/gntws.c Sun Jul 08 04:27:02 2007 +0000 @@ -35,6 +35,9 @@ int n, width = 0; int i; + if (gnt_is_refugee()) + return; + if (taskbar == NULL) { taskbar = newwin(1, getmaxx(stdscr), getmaxy(stdscr) - 1, 0); } else if (reposition) { @@ -114,11 +117,13 @@ g_list_foreach(ws->ordered, widget_hide, nodes); } -void gnt_ws_widget_hide(GntWidget *widget, GHashTable *nodes) { +void gnt_ws_widget_hide(GntWidget *widget, GHashTable *nodes) +{ widget_hide(widget, nodes); } -void gnt_ws_widget_show(GntWidget *widget, GHashTable *nodes) { +void gnt_ws_widget_show(GntWidget *widget, GHashTable *nodes) +{ widget_show(widget, nodes); } diff -r d4065b26dcac -r 2e064085b7df finch/libgnt/wms/irssi.c --- a/finch/libgnt/wms/irssi.c Sun Jul 08 04:23:55 2007 +0000 +++ b/finch/libgnt/wms/irssi.c Sun Jul 08 04:27:02 2007 +0000 @@ -181,8 +181,10 @@ GNT_BOX(node->me)->title); wbkgdset(node->window, '\0' | COLOR_PAIR(gnt_widget_has_focus(node->me) ? GNT_COLOR_TITLE : GNT_COLOR_TITLE_D)); mvwaddstr(node->window, 0, 0, title); - update_panels(); - doupdate(); + if (!gnt_is_refugee()) { + update_panels(); + doupdate(); + } return FALSE; } diff -r d4065b26dcac -r 2e064085b7df libpurple/account.c --- a/libpurple/account.c Sun Jul 08 04:23:55 2007 +0000 +++ b/libpurple/account.c Sun Jul 08 04:27:02 2007 +0000 @@ -2183,6 +2183,7 @@ purple_accounts_delete(PurpleAccount *account) { PurpleBlistNode *gnode, *cnode, *bnode; + GList *iter; g_return_if_fail(account != NULL); @@ -2231,6 +2232,14 @@ } } + /* Remove any open conversation for this account */ + for (iter = purple_get_conversations(); iter; ) { + PurpleConversation *conv = iter->data; + iter = iter->next; + if (purple_conversation_get_account(conv) == account) + purple_conversation_destroy(conv); + } + /* Remove this account's pounces */ purple_pounce_destroy_all_by_account(account); diff -r d4065b26dcac -r 2e064085b7df libpurple/dbus-useful.c diff -r d4065b26dcac -r 2e064085b7df libpurple/debug.c diff -r d4065b26dcac -r 2e064085b7df libpurple/internal.h --- a/libpurple/internal.h Sun Jul 08 04:23:55 2007 +0000 +++ b/libpurple/internal.h Sun Jul 08 04:27:02 2007 +0000 @@ -93,8 +93,9 @@ #include #endif +#include + #ifdef PURPLE_PLUGINS -# include # ifndef _WIN32 # include # endif diff -r d4065b26dcac -r 2e064085b7df libpurple/plugins/autoaccept.c --- a/libpurple/plugins/autoaccept.c Sun Jul 08 04:23:55 2007 +0000 +++ b/libpurple/plugins/autoaccept.c Sun Jul 08 04:27:02 2007 +0000 @@ -178,7 +178,8 @@ { PurpleMenuAction *action; - if (!PURPLE_BLIST_NODE_IS_BUDDY(node) && !PURPLE_BLIST_NODE_IS_CONTACT(node)) + if (!PURPLE_BLIST_NODE_IS_BUDDY(node) && !PURPLE_BLIST_NODE_IS_CONTACT(node) && + !(purple_blist_node_get_flags(node) & PURPLE_BLIST_NODE_FLAG_NO_SAVE)) return; action = purple_menu_action_new(_("Autoaccept File Transfers..."), diff -r d4065b26dcac -r 2e064085b7df libpurple/plugins/perl/common/Connection.xs diff -r d4065b26dcac -r 2e064085b7df libpurple/plugins/perl/common/Makefile.mingw --- a/libpurple/plugins/perl/common/Makefile.mingw Sun Jul 08 04:23:55 2007 +0000 +++ b/libpurple/plugins/perl/common/Makefile.mingw Sun Jul 08 04:27:02 2007 +0000 @@ -20,6 +20,7 @@ INCLUDE_PATHS += -I. \ -I$(PIDGIN_TREE_TOP) \ -I$(PURPLE_TOP) \ + -I$(PURPLE_TOP)/win32 \ -I$(GTK_TOP)/include \ -I$(GTK_TOP)/include/glib-2.0 \ -I$(GTK_TOP)/lib/glib-2.0/include \ diff -r d4065b26dcac -r 2e064085b7df libpurple/plugins/perl/perl-common.h --- a/libpurple/plugins/perl/perl-common.h Sun Jul 08 04:23:55 2007 +0000 +++ b/libpurple/plugins/perl/perl-common.h Sun Jul 08 04:27:02 2007 +0000 @@ -11,7 +11,14 @@ /* XXX: perl defines it's own _ but I think it's safe to undef it */ #undef _ +/* Dirty hack to prevent the win32 libc compat stuff from interfering with the Perl internal stuff */ +#ifdef _WIN32 +#define _WIN32DEP_H_ +#endif #include "internal.h" +#ifdef _WIN32 +#undef _WIN32DEP_H_ +#endif #include "plugin.h" #include "value.h" diff -r d4065b26dcac -r 2e064085b7df libpurple/protocols/gg/gg.c --- a/libpurple/protocols/gg/gg.c Sun Jul 08 04:23:55 2007 +0000 +++ b/libpurple/protocols/gg/gg.c Sun Jul 08 04:27:02 2007 +0000 @@ -1074,9 +1074,7 @@ } } - val = ggp_buddy_get_name(gc, ggp_str_to_uin(who)); - purple_notify_userinfo(gc, val, user_info, ggp_sr_close_cb, form); - g_free(val); + purple_notify_userinfo(gc, who, user_info, ggp_sr_close_cb, form); g_free(who); purple_notify_user_info_destroy(user_info); } diff -r d4065b26dcac -r 2e064085b7df libpurple/protocols/gg/lib/http.c diff -r d4065b26dcac -r 2e064085b7df libpurple/protocols/gg/lib/pubdir50.c diff -r d4065b26dcac -r 2e064085b7df libpurple/protocols/jabber/jutil.c diff -r d4065b26dcac -r 2e064085b7df libpurple/protocols/msn/directconn.c --- a/libpurple/protocols/msn/directconn.c Sun Jul 08 04:23:55 2007 +0000 +++ b/libpurple/protocols/msn/directconn.c Sun Jul 08 04:27:02 2007 +0000 @@ -370,7 +370,7 @@ else { struct sockaddr_in client_addr; - unsigned int client; + socklen_t client; fd = accept (source, (struct sockaddr *)&client_addr, &client); } diff -r d4065b26dcac -r 2e064085b7df libpurple/protocols/yahoo/yahoochat.h diff -r d4065b26dcac -r 2e064085b7df libpurple/win32/win32dep.c --- a/libpurple/win32/win32dep.c Sun Jul 08 04:23:55 2007 +0000 +++ b/libpurple/win32/win32dep.c Sun Jul 08 04:27:02 2007 +0000 @@ -43,8 +43,6 @@ /* * DEFINES & MACROS */ -#define _(x) gettext(x) - #define WIN32_PROXY_REGKEY "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings" /* For shfolder.dll */ diff -r d4065b26dcac -r 2e064085b7df pidgin/gtkblist.c --- a/pidgin/gtkblist.c Sun Jul 08 04:23:55 2007 +0000 +++ b/pidgin/gtkblist.c Sun Jul 08 04:27:02 2007 +0000 @@ -3417,13 +3417,16 @@ time_t idle_secs = purple_presence_get_idle_time(presence); if (idle_secs > 0) { - int ihrs, imin; + int iday, ihrs, imin; time(&t); - ihrs = (t - idle_secs) / 3600; + iday = (t - idle_secs) / (24 * 60 * 60); + ihrs = ((t - idle_secs) / 60 / 60) % 24; imin = ((t - idle_secs) / 60) % 60; - if (ihrs) + if (iday) + idletime = g_strdup_printf(_("Idle %dd %dh %02dm"), iday, ihrs, imin); + else if (ihrs) idletime = g_strdup_printf(_("Idle %dh %02dm"), ihrs, imin); else idletime = g_strdup_printf(_("Idle %dm"), imin); diff -r d4065b26dcac -r 2e064085b7df pidgin/gtkconv.c --- a/pidgin/gtkconv.c Sun Jul 08 04:23:55 2007 +0000 +++ b/pidgin/gtkconv.c Sun Jul 08 04:27:02 2007 +0000 @@ -4857,8 +4857,14 @@ gtkconv->convs = g_list_remove(gtkconv->convs, conv); /* Don't destroy ourselves until all our convos are gone */ - if (gtkconv->convs) + if (gtkconv->convs) { + /* Make sure the destroyed conversation is not the active one */ + if (gtkconv->active_conv == conv) { + gtkconv->active_conv = gtkconv->convs->data; + purple_conversation_update(gtkconv->active_conv, PURPLE_CONV_UPDATE_FEATURES); + } return; + } pidgin_conv_window_remove_gtkconv(gtkconv->win, gtkconv); diff -r d4065b26dcac -r 2e064085b7df pidgin/gtkdocklet.c diff -r d4065b26dcac -r 2e064085b7df pidgin/gtkimhtml.c --- a/pidgin/gtkimhtml.c Sun Jul 08 04:23:55 2007 +0000 +++ b/pidgin/gtkimhtml.c Sun Jul 08 04:27:02 2007 +0000 @@ -28,8 +28,8 @@ #include #endif +#include "internal.h" #include "pidgin.h" -#include "internal.h" #include "debug.h" #include "util.h" diff -r d4065b26dcac -r 2e064085b7df pidgin/gtklog.c diff -r d4065b26dcac -r 2e064085b7df pidgin/plugins/gestures/gestures.c diff -r d4065b26dcac -r 2e064085b7df pidgin/plugins/notify.c diff -r d4065b26dcac -r 2e064085b7df pidgin/plugins/perl/common/Makefile.mingw --- a/pidgin/plugins/perl/common/Makefile.mingw Sun Jul 08 04:23:55 2007 +0000 +++ b/pidgin/plugins/perl/common/Makefile.mingw Sun Jul 08 04:27:02 2007 +0000 @@ -18,6 +18,7 @@ INCLUDE_PATHS = -I. \ -I$(PIDGIN_TREE_TOP) \ -I$(PURPLE_TOP) \ + -I$(PURPLE_TOP)/win32 \ -I$(PIDGIN_TOP) \ -I$(PIDGIN_TOP)/win32 \ -I$(GTK_TOP)/include \ diff -r d4065b26dcac -r 2e064085b7df pidgin/plugins/timestamp.c diff -r d4065b26dcac -r 2e064085b7df pidgin/win32/gtkwin32dep.c --- a/pidgin/win32/gtkwin32dep.c Sun Jul 08 04:23:55 2007 +0000 +++ b/pidgin/win32/gtkwin32dep.c Sun Jul 08 04:27:02 2007 +0000 @@ -36,6 +36,8 @@ #include #include +#include "internal.h" + #include "debug.h" #include "notify.h" diff -r d4065b26dcac -r 2e064085b7df pidgin/win32/gtkwin32dep.h --- a/pidgin/win32/gtkwin32dep.h Sun Jul 08 04:23:55 2007 +0000 +++ b/pidgin/win32/gtkwin32dep.h Sun Jul 08 04:27:02 2007 +0000 @@ -45,5 +45,5 @@ void winpidgin_post_init(void); void winpidgin_cleanup(void); -#endif /* _WIN32DEP_H_ */ +#endif /* _GTKWIN32DEP_H_ */