Технічне, про месенджер
May. 31st, 2013 08:13 pmДля онлайн-спілкування я вже без малого 10 років використовую Pidgin мультипротокольний відкритий клієнт. Влаштовує він мене цілковито, але, як відомо, у досконалості немає меж. Конкретно кажучи, знайшлась незручність, пов'язана з опцією «показувати офлайн-контакти». Ця опція може виставлятись глобально (на весь список контактів), на один контакт або на групу контактів. Так от, при виставленні або відключенні цієї опції для групи контактів збиваються її налаштування для всіх контактів цієї групи. Тобто якщо у мене, скажімо, в групі є два контакти, яким я часто пишу і у яких, відповідно, стоїть відмітка «Показувати, коли не в мережі», і мені раптом треба написати комусь іншому з цієї групи, хто на даний момент офлайн, то у мене є два варіанти:
1. Виставити глобальну опцію «показувати офлайн-контакти» і прокручувати довжелезний список.
2. Виставити цю опцію на групу і змиритись з тим, що для двох контактів ця опція пропаде, і її доведеться знову виставляти або з застосуванням глобальної опції, або виловлюючи їх в той момент, коли вони в мережі.
Я вирішив, що опенсоурс на те і опенсоурс, щоб такі речі виправляти самому. Ось результат:
diff -aur pidgin-2.10.7/finch/gntblist.c pidgin-2.10.7-group_offline/finch/gntblist.c
--- pidgin-2.10.7/finch/gntblist.c 2013-02-11 11:16:51.000000000 +0200
+++ pidgin-2.10.7-group_offline/finch/gntblist.c 2013-05-31 19:08:29.000000000 +0300
@@ -170,6 +170,8 @@
if (PURPLE_BLIST_NODE_IS_BUDDY(node)) {
PurpleBuddy *buddy = (PurpleBuddy*)node;
FinchBlistNode *fnode = FINCH_GET_DATA(node);
+ PurpleBlistNode *contact = purple_blist_node_get_parent(buddy);
+ PurpleBlistNode *group = purple_blist_node_get_parent(contact);
if (!purple_buddy_get_contact(buddy))
return FALSE; /* When a new buddy is added and show-offline is set */
if (PURPLE_BUDDY_IS_ONLINE(buddy))
@@ -180,6 +182,8 @@
return TRUE; /* We want to see offline buddies too */
if (fnode && fnode->signed_timer)
return TRUE; /* Show if the buddy just signed off */
+ if (group && purple_blist_node_get_bool(group, "show_offline"))
+ return TRUE;
if (purple_blist_node_get_bool(node, "show_offline"))
return TRUE;
} else if (PURPLE_BLIST_NODE_IS_CONTACT(node)) {
diff -aur pidgin-2.10.7/libpurple/blist.c pidgin-2.10.7-group_offline/libpurple/blist.c
--- pidgin-2.10.7/libpurple/blist.c 2013-02-11 11:16:51.000000000 +0200
+++ pidgin-2.10.7-group_offline/libpurple/blist.c 2013-05-31 19:08:29.000000000 +0300
@@ -2690,7 +2690,8 @@
}
}
if (recompute ||
- purple_blist_node_get_bool(cnode, "show_offline")) {
+ purple_blist_node_get_bool(cnode, "show_offline") ||
+ purple_blist_node_get_bool(gnode, "show_offline")) {
purple_contact_invalidate_priority_buddy((PurpleContact*)cnode);
ops->update(purplebuddylist, cnode);
}
diff -aur pidgin-2.10.7/pidgin/gtkblist.c pidgin-2.10.7-group_offline/pidgin/gtkblist.c
--- pidgin-2.10.7/pidgin/gtkblist.c 2013-02-11 11:16:53.000000000 +0200
+++ pidgin-2.10.7-group_offline/pidgin/gtkblist.c 2013-05-31 19:12:37.000000000 +0300
@@ -809,12 +809,10 @@
cnode != NULL;
cnode = purple_blist_node_get_sibling_next(cnode))
{
- purple_blist_node_set_bool(cnode, "show_offline", setting);
for (bnode = purple_blist_node_get_first_child(cnode);
bnode != NULL;
bnode = purple_blist_node_get_sibling_next(bnode))
{
- purple_blist_node_set_bool(bnode, "show_offline", setting);
pidgin_blist_update(purple_get_blist(), bnode);
}
}
@@ -1808,6 +1806,12 @@
GtkWidget *menuitem;
gboolean show_offline = purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_offline_buddies");
+ PurpleBlistNode *contact = purple_blist_node_get_parent(node);
+ PurpleBlistNode *group = purple_blist_node_get_parent(contact);
+
+ if (group)
+ show_offline |= purple_blist_node_get_bool(group, "show_offline");
+
menu = gtk_menu_new();
pidgin_blist_make_buddy_menu(menu, b, FALSE);
@@ -3197,16 +3201,24 @@
static gboolean buddy_is_displayable(PurpleBuddy *buddy)
{
struct _pidgin_blist_node *gtknode;
+ PurpleBlistNode *contact, *group;
if(!buddy)
return FALSE;
+ contact = purple_blist_node_get_parent((PurpleBlistNode*)buddy);
+ group = purple_blist_node_get_parent(contact);
+
+ gboolean parent_show_offline =
+ (group) ? purple_blist_node_get_bool(group, "show_offline") : FALSE;
+
gtknode = ((PurpleBlistNode*)buddy)->ui_data;
return (purple_account_is_connected(buddy->account) &&
(purple_presence_is_online(buddy->presence) ||
(gtknode && gtknode->recent_signonoff) ||
purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_offline_buddies") ||
+ parent_show_offline ||
purple_blist_node_get_bool((PurpleBlistNode*)buddy, "show_offline")));
}
@@ -6354,7 +6366,8 @@
group = (PurpleGroup*)gnode;
- show_offline = purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_offline_buddies");
+ show_offline = purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/blist/show_offline_buddies") ||
+ purple_blist_node_get_bool(gnode, "show_offline");
if(show_offline)
count = purple_blist_get_group_size(group, FALSE);