1 /*
2  * Copyright © 2009-2010 freedcpp, http://code.google.com/p/freedcpp
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17  *
18  * In addition, as a special exception, compiling, linking, and/or
19  * using OpenSSL with this program is allowed.
20  */
21 
22 #include "favoriteusers.hh"
23 #include <dcpp/ClientManager.h>
24 #include "settingsmanager.hh"
25 #include "wulformanager.hh"
26 #include "WulforUtil.hh"
27 #include "message.hh"
28 
29 using namespace std;
30 using namespace dcpp;
31 
FavoriteUsers()32 FavoriteUsers::FavoriteUsers():
33     BookEntry(Entry::FAVORITE_USERS, _("Favorite Users"), "favoriteusers.ui")
34 {
35 #if !GTK_CHECK_VERSION(3,0,0)
36     gtk_statusbar_set_has_resize_grip (GTK_STATUSBAR(getWidget("status")),FALSE);
37 #endif
38 
39     // Configure the dialog
40     gtk_dialog_set_alternative_button_order(GTK_DIALOG(getWidget("DescriptionDialog")), GTK_RESPONSE_OK, GTK_RESPONSE_CANCEL, -1);
41 
42     // menu
43     g_object_ref_sink(getWidget("menu"));
44 
45     // Initialize favorite users list treeview
46     favoriteUserView.setView(GTK_TREE_VIEW(getWidget("favoriteUserView")), TRUE, "favoriteusers");
47     favoriteUserView.insertColumn(_("Auto grant slot"), G_TYPE_BOOLEAN, TreeView::BOOL, 100);
48     favoriteUserView.insertColumn(_("Nick"), G_TYPE_STRING, TreeView::ICON_STRING, 100, "Icon");
49     favoriteUserView.insertColumn(_("Hub (last seen in, if offline)"), G_TYPE_STRING, TreeView::STRING, 200);
50     favoriteUserView.insertColumn(_("Time last seen"), G_TYPE_STRING, TreeView::STRING, 120);
51     favoriteUserView.insertColumn(_("Description"), G_TYPE_STRING, TreeView::STRING, 100);
52     favoriteUserView.insertColumn(_("CID"), G_TYPE_STRING, TreeView::STRING, 350);
53     favoriteUserView.insertHiddenColumn("URL", G_TYPE_STRING);
54     favoriteUserView.insertHiddenColumn("Icon", G_TYPE_STRING);
55     favoriteUserView.finalize();
56 
57     favoriteUserStore = gtk_list_store_newv(favoriteUserView.getColCount(), favoriteUserView.getGTypes());
58     gtk_tree_view_set_model(favoriteUserView.get(), GTK_TREE_MODEL(favoriteUserStore));
59     g_object_unref(favoriteUserStore);
60 
61     favoriteUserSelection = gtk_tree_view_get_selection(favoriteUserView.get());
62     gtk_tree_selection_set_mode(favoriteUserSelection, GTK_SELECTION_MULTIPLE);
63     gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(favoriteUserStore), favoriteUserView.col(_("Nick")), GTK_SORT_ASCENDING);
64     gtk_tree_view_column_set_sort_indicator(gtk_tree_view_get_column(favoriteUserView.get(), favoriteUserView.col(_("Nick"))), TRUE);
65     gtk_tree_view_set_fixed_height_mode(favoriteUserView.get(), TRUE);
66 
67     GList *list = gtk_cell_layout_get_cells(GTK_CELL_LAYOUT(gtk_tree_view_get_column(favoriteUserView.get(),
68         favoriteUserView.col(_("Auto grant slot")))));
69     GObject *renderer = (GObject *)g_list_nth_data(list, 0);
70     g_signal_connect(renderer, "toggled", G_CALLBACK(onAutoGrantSlotToggled_gui), (gpointer)this);
71     g_list_free(list);
72 
73     g_signal_connect(getWidget("browseItem"), "activate", G_CALLBACK(onBrowseItemClicked_gui), (gpointer)this);
74     g_signal_connect(getWidget("matchQueueItem"), "activate", G_CALLBACK(onMatchQueueItemClicked_gui), (gpointer)this);
75     g_signal_connect(getWidget("sendPMItem"), "activate", G_CALLBACK(onSendPMItemClicked_gui), (gpointer)this);
76     g_signal_connect(getWidget("grantSlotItem"), "activate", G_CALLBACK(onGrantSlotItemClicked_gui), (gpointer)this);
77     g_signal_connect(getWidget("connectItem"), "activate", G_CALLBACK(onConnectItemClicked_gui), (gpointer)this);
78     g_signal_connect(getWidget("removeFromQueueItem"), "activate", G_CALLBACK(onRemoveFromQueueItemClicked_gui), (gpointer)this);
79     g_signal_connect(getWidget("descriptionItem"), "activate", G_CALLBACK(onDescriptionItemClicked_gui), (gpointer)this);
80     g_signal_connect(getWidget("removeItem"), "activate", G_CALLBACK(onRemoveItemClicked_gui), (gpointer)this);
81     g_signal_connect(favoriteUserView.get(), "button-press-event", G_CALLBACK(onButtonPressed_gui), (gpointer)this);
82     g_signal_connect(favoriteUserView.get(), "button-release-event", G_CALLBACK(onButtonReleased_gui), (gpointer)this);
83     g_signal_connect(favoriteUserView.get(), "key-release-event", G_CALLBACK(onKeyReleased_gui), (gpointer)this);
84 }
85 
~FavoriteUsers()86 FavoriteUsers::~FavoriteUsers()
87 {
88     FavoriteManager::getInstance()->removeListener(this);
89 
90     gtk_widget_destroy(getWidget("DescriptionDialog"));
91     g_object_unref(getWidget("menu"));
92 }
93 
show()94 void FavoriteUsers::show()
95 {
96     // Initialize favorite users list
97     FavoriteManager::FavoriteMap map = FavoriteManager::getInstance()->getFavoriteUsers();
98     FavoriteManager::FavoriteMap::const_iterator it;
99 
100     for (it = map.begin(); it != map.end(); ++it)
101     {
102         GtkTreeIter iter;
103         const FavoriteUser &user = it->second;
104         bool online = user.getUser()->isOnline();
105         string hub = online ? WulforUtil::getHubNames(user.getUser(), user.getUrl()) : user.getUrl();
106         string seen = online ? _("Online") : Util::formatTime("%Y-%m-%d %H:%M", user.getLastSeen());
107         string cid = user.getUser()->getCID().toBase32();
108 
109         gtk_list_store_append(favoriteUserStore, &iter);
110         gtk_list_store_set(favoriteUserStore, &iter,
111             favoriteUserView.col(_("Auto grant slot")), user.isSet(FavoriteUser::FLAG_GRANTSLOT) ? TRUE : FALSE,
112             favoriteUserView.col(_("Nick")), user.getNick().c_str(),
113             favoriteUserView.col(_("Hub (last seen in, if offline)")), hub.c_str(),
114             favoriteUserView.col(_("Time last seen")), seen.c_str(),
115             favoriteUserView.col(_("Description")), user.getDescription().c_str(),
116             favoriteUserView.col(_("CID")), cid.c_str(),
117             favoriteUserView.col("URL"), user.getUrl().c_str(),
118             favoriteUserView.col("Icon"), "eiskaltdcpp-normal",
119             -1);
120 
121         userIters.insert(UserIters::value_type(cid, iter));
122     }
123     FavoriteManager::getInstance()->addListener(this);
124 }
125 
onKeyReleased_gui(GtkWidget * widget,GdkEventKey * event,gpointer data)126 gboolean FavoriteUsers::onKeyReleased_gui(GtkWidget *widget, GdkEventKey *event, gpointer data)
127 {
128     FavoriteUsers *fu = (FavoriteUsers *)data;
129 
130     if (gtk_tree_selection_count_selected_rows(fu->favoriteUserSelection) > 0)
131     {
132         if (event->keyval == GDK_Delete || event->keyval == GDK_BackSpace)
133         {
134             fu->onRemoveItemClicked_gui(NULL, data);
135         }
136         else if (event->keyval == GDK_Menu || (event->keyval == GDK_F10 && event->state & GDK_SHIFT_MASK))
137         {
138             gtk_menu_popup(GTK_MENU(fu->getWidget("menu")), NULL, NULL, NULL, NULL, 0, gtk_get_current_event_time());
139         }
140     }
141 
142     return FALSE;
143 }
144 
onButtonPressed_gui(GtkWidget * widget,GdkEventButton * event,gpointer data)145 gboolean FavoriteUsers::onButtonPressed_gui(GtkWidget *widget, GdkEventButton *event, gpointer data)
146 {
147     FavoriteUsers *fu = (FavoriteUsers *)data;
148     fu->previous = event->type;
149 
150     if (event->button == 3)
151     {
152         GtkTreePath *path;
153 
154         if (gtk_tree_view_get_path_at_pos(fu->favoriteUserView.get(), (gint)event->x, (gint)event->y, &path, NULL, NULL, NULL))
155         {
156             bool selected = gtk_tree_selection_path_is_selected(fu->favoriteUserSelection, path);
157             gtk_tree_path_free(path);
158 
159             if (selected)
160                 return TRUE;
161         }
162     }
163     return FALSE;
164 }
165 
onButtonReleased_gui(GtkWidget * widget,GdkEventButton * event,gpointer data)166 gboolean FavoriteUsers::onButtonReleased_gui(GtkWidget *widget, GdkEventButton *event, gpointer data)
167 {
168     FavoriteUsers *fu = (FavoriteUsers *)data;
169 
170     if (gtk_tree_selection_count_selected_rows(fu->favoriteUserSelection) > 0)
171     {
172         if (event->button == 1 && fu->previous == GDK_2BUTTON_PRESS)
173         {
174             if (WGETB("pm"))
175 
176                 fu->onSendPMItemClicked_gui(NULL, data);
177             else
178                 fu->onBrowseItemClicked_gui(NULL, data);
179         }
180         else if (event->button == 2 && event->type == GDK_BUTTON_RELEASE)
181         {
182             if (WGETB("pm"))
183 
184                 fu->onBrowseItemClicked_gui(NULL, data);
185             else
186                 fu->onSendPMItemClicked_gui(NULL, data);
187         }
188         else if (event->button == 3 && event->type == GDK_BUTTON_RELEASE)
189         {
190             gtk_menu_popup(GTK_MENU(fu->getWidget("menu")), NULL, NULL, NULL, NULL, 0, gtk_get_current_event_time());
191         }
192     }
193 
194     return FALSE;
195 }
196 
onBrowseItemClicked_gui(GtkMenuItem * item,gpointer data)197 void FavoriteUsers::onBrowseItemClicked_gui(GtkMenuItem *item, gpointer data)
198 {
199     FavoriteUsers *fu = (FavoriteUsers *)data;
200 
201     if (gtk_tree_selection_count_selected_rows(fu->favoriteUserSelection) > 0)
202     {
203         GtkTreeIter iter;
204         GtkTreePath *path;
205         GList *list = gtk_tree_selection_get_selected_rows(fu->favoriteUserSelection, NULL);
206         typedef Func3<FavoriteUsers, string, string, bool> F3;
207 
208         for (GList *i = list; i; i = i->next)
209         {
210             path = (GtkTreePath *)i->data;
211 
212             if (gtk_tree_model_get_iter(GTK_TREE_MODEL(fu->favoriteUserStore), &iter, path))
213             {
214                 F3 *func = new F3(fu, &FavoriteUsers::getFileList_client,
215                     fu->favoriteUserView.getString(&iter, _("CID")),
216                     fu->favoriteUserView.getString(&iter, "URL"),
217                     FALSE);
218                 WulforManager::get()->dispatchClientFunc(func);
219             }
220             gtk_tree_path_free(path);
221         }
222         g_list_free(list);
223     }
224 }
225 
onMatchQueueItemClicked_gui(GtkMenuItem * item,gpointer data)226 void FavoriteUsers::onMatchQueueItemClicked_gui(GtkMenuItem *item, gpointer data)
227 {
228     FavoriteUsers *fu = (FavoriteUsers *)data;
229 
230     if (gtk_tree_selection_count_selected_rows(fu->favoriteUserSelection) > 0)
231     {
232         GtkTreeIter iter;
233         GtkTreePath *path;
234         GList *list = gtk_tree_selection_get_selected_rows(fu->favoriteUserSelection, NULL);
235         typedef Func3<FavoriteUsers, string, string, bool> F3;
236 
237         for (GList *i = list; i; i = i->next)
238         {
239             path = (GtkTreePath *)i->data;
240 
241             if (gtk_tree_model_get_iter(GTK_TREE_MODEL(fu->favoriteUserStore), &iter, path))
242             {
243                 F3 *func = new F3(fu, &FavoriteUsers::getFileList_client,
244                     fu->favoriteUserView.getString(&iter, _("CID")),
245                     fu->favoriteUserView.getString(&iter, "URL"),
246                     TRUE);
247                 WulforManager::get()->dispatchClientFunc(func);
248             }
249             gtk_tree_path_free(path);
250         }
251         g_list_free(list);
252     }
253 }
254 
onSendPMItemClicked_gui(GtkMenuItem * item,gpointer data)255 void FavoriteUsers::onSendPMItemClicked_gui(GtkMenuItem *item, gpointer data)
256 {
257     FavoriteUsers *fu = (FavoriteUsers *)data;
258 
259     if (gtk_tree_selection_count_selected_rows(fu->favoriteUserSelection) > 0)
260     {
261         GtkTreeIter iter;
262         GtkTreePath *path;
263         GList *list = gtk_tree_selection_get_selected_rows(fu->favoriteUserSelection, NULL);
264 
265         for (GList *i = list; i; i = i->next)
266         {
267             path = (GtkTreePath *)i->data;
268 
269             if (gtk_tree_model_get_iter(GTK_TREE_MODEL(fu->favoriteUserStore), &iter, path))
270             {
271                 WulforManager::get()->getMainWindow()->addPrivateMessage_gui(Msg::UNKNOWN,
272                     fu->favoriteUserView.getString(&iter, _("CID")),
273                     fu->favoriteUserView.getString(&iter, "URL"));
274             }
275             gtk_tree_path_free(path);
276         }
277         g_list_free(list);
278     }
279 }
280 
onGrantSlotItemClicked_gui(GtkMenuItem * item,gpointer data)281 void FavoriteUsers::onGrantSlotItemClicked_gui(GtkMenuItem *item, gpointer data)
282 {
283     FavoriteUsers *fu = (FavoriteUsers *)data;
284 
285     if (gtk_tree_selection_count_selected_rows(fu->favoriteUserSelection) > 0)
286     {
287         GtkTreeIter iter;
288         GtkTreePath *path;
289         GList *list = gtk_tree_selection_get_selected_rows(fu->favoriteUserSelection, NULL);
290         typedef Func2<FavoriteUsers, string, string> F2;
291 
292         for (GList *i = list; i; i = i->next)
293         {
294             path = (GtkTreePath *)i->data;
295 
296             if (gtk_tree_model_get_iter(GTK_TREE_MODEL(fu->favoriteUserStore), &iter, path))
297             {
298                 F2 *func = new F2(fu, &FavoriteUsers::grantSlot_client,
299                     fu->favoriteUserView.getString(&iter, _("CID")),
300                     fu->favoriteUserView.getString(&iter, "URL"));
301                 WulforManager::get()->dispatchClientFunc(func);
302             }
303             gtk_tree_path_free(path);
304         }
305         g_list_free(list);
306     }
307 }
308 
onConnectItemClicked_gui(GtkMenuItem * item,gpointer data)309 void FavoriteUsers::onConnectItemClicked_gui(GtkMenuItem *item, gpointer data)
310 {
311     FavoriteUsers *fu = (FavoriteUsers *)data;
312 
313     if (gtk_tree_selection_count_selected_rows(fu->favoriteUserSelection) > 0)
314     {
315         GtkTreeIter iter;
316         GtkTreePath *path;
317         GList *list = gtk_tree_selection_get_selected_rows(fu->favoriteUserSelection, NULL);
318 
319         for (GList *i = list; i; i = i->next)
320         {
321             path = (GtkTreePath *)i->data;
322 
323             if (gtk_tree_model_get_iter(GTK_TREE_MODEL(fu->favoriteUserStore), &iter, path))
324             {
325                 WulforManager::get()->getMainWindow()->showHub_gui(fu->favoriteUserView.getString(&iter, "URL"));
326             }
327             gtk_tree_path_free(path);
328         }
329         g_list_free(list);
330     }
331 }
332 
onRemoveFromQueueItemClicked_gui(GtkMenuItem * item,gpointer data)333 void FavoriteUsers::onRemoveFromQueueItemClicked_gui(GtkMenuItem *item, gpointer data)
334 {
335     FavoriteUsers *fu = (FavoriteUsers *)data;
336 
337     if (gtk_tree_selection_count_selected_rows(fu->favoriteUserSelection) > 0)
338     {
339         GtkTreeIter iter;
340         GtkTreePath *path;
341         GList *list = gtk_tree_selection_get_selected_rows(fu->favoriteUserSelection, NULL);
342         typedef Func1<FavoriteUsers, string> F1;
343 
344         for (GList *i = list; i; i = i->next)
345         {
346             path = (GtkTreePath *)i->data;
347 
348             if (gtk_tree_model_get_iter(GTK_TREE_MODEL(fu->favoriteUserStore), &iter, path))
349             {
350                 F1 *func = new F1(fu, &FavoriteUsers::removeUserFromQueue_client, fu->favoriteUserView.getString(&iter, _("CID")));
351                 WulforManager::get()->dispatchClientFunc(func);
352             }
353             gtk_tree_path_free(path);
354         }
355         g_list_free(list);
356     }
357 }
358 
onDescriptionItemClicked_gui(GtkMenuItem * item,gpointer data)359 void FavoriteUsers::onDescriptionItemClicked_gui(GtkMenuItem *item, gpointer data)
360 {
361     FavoriteUsers *fu = (FavoriteUsers *)data;
362 
363     if (gtk_tree_selection_count_selected_rows(fu->favoriteUserSelection) == 1)
364     {
365         GList *list = gtk_tree_selection_get_selected_rows(fu->favoriteUserSelection, NULL);
366 
367         if (list)
368         {
369             GtkTreeIter iter;
370             GtkTreePath *path = (GtkTreePath *) list->data;
371             string description, nick, cid;
372 
373             if (gtk_tree_model_get_iter(GTK_TREE_MODEL(fu->favoriteUserStore), &iter, path))
374             {
375                 description = fu->favoriteUserView.getString(&iter, _("Description"));
376                 nick = fu->favoriteUserView.getString(&iter, _("Nick"));
377                 cid = fu->favoriteUserView.getString(&iter, _("CID"));
378             }
379             gtk_tree_path_free(path);
380             g_list_free(list);
381 
382             gtk_window_set_title(GTK_WINDOW(fu->getWidget("DescriptionDialog")), nick.c_str());
383             gtk_entry_set_text(GTK_ENTRY(fu->getWidget("descriptionEntry")), description.c_str());
384             gint response = gtk_dialog_run(GTK_DIALOG(fu->getWidget("DescriptionDialog")));
385 
386             // Fix crash, if the dialog gets programmatically destroyed.
387             if (response == GTK_RESPONSE_NONE)
388             {
389                 return;
390             }
391 
392             gtk_widget_hide(fu->getWidget("DescriptionDialog"));
393 
394             if (response != GTK_RESPONSE_OK)
395                 return;
396 
397             if (fu->findUser_gui(cid, &iter))
398             {
399                 description = gtk_entry_get_text(GTK_ENTRY(fu->getWidget("descriptionEntry")));
400                 gtk_list_store_set(fu->favoriteUserStore, &iter, fu->favoriteUserView.col(_("Description")), description.c_str(), -1);
401 
402                 typedef Func2<FavoriteUsers, string, string> F2;
403                 F2 *func = new F2(fu, &FavoriteUsers::setUserDescription_client, cid, description);
404                 WulforManager::get()->dispatchClientFunc(func);
405             }
406         }
407     }
408 }
409 
onRemoveItemClicked_gui(GtkMenuItem * item,gpointer data)410 void FavoriteUsers::onRemoveItemClicked_gui(GtkMenuItem *item, gpointer data)
411 {
412     FavoriteUsers *fu = (FavoriteUsers *)data;
413 
414     if (gtk_tree_selection_count_selected_rows(fu->favoriteUserSelection) > 0)
415     {
416         ParamMap params;
417         GtkTreeIter iter;
418         GtkTreePath *path;
419         typedef Func1<FavoriteUsers, string> F1;
420         GList *list = gtk_tree_selection_get_selected_rows(fu->favoriteUserSelection, NULL);
421 
422         for (GList *i = list; i; i = i->next)
423         {
424             path = (GtkTreePath *)i->data;
425 
426             if (gtk_tree_model_get_iter(GTK_TREE_MODEL(fu->favoriteUserStore), &iter, path))
427             {
428                 params.insert(ParamMap::value_type(fu->favoriteUserView.getString(&iter, _("CID")),
429                                             fu->favoriteUserView.getString(&iter, _("Nick"))));
430             }
431             gtk_tree_path_free(path);
432         }
433         g_list_free(list);
434 
435         if (WGETB("confirm-user-removal"))
436         {
437             GtkWidget* dialog = gtk_message_dialog_new(GTK_WINDOW(WulforManager::get()->getMainWindow()->getContainer()),
438                 GTK_DIALOG_DESTROY_WITH_PARENT,
439                 GTK_MESSAGE_QUESTION,
440                 GTK_BUTTONS_NONE,
441                 _("Are you sure you want to delete favorite user(s)?"));
442             gtk_dialog_add_buttons(GTK_DIALOG(dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_REMOVE,
443                 GTK_RESPONSE_YES, NULL);
444             gtk_dialog_set_alternative_button_order(GTK_DIALOG(dialog), GTK_RESPONSE_YES, GTK_RESPONSE_CANCEL, -1);
445             gint response = gtk_dialog_run(GTK_DIALOG(dialog));
446 
447             // Widget failed if the dialog gets programmatically destroyed.
448             if (response == GTK_RESPONSE_NONE)
449                 return;
450 
451             gtk_widget_hide(dialog);
452 
453             if (response != GTK_RESPONSE_YES)
454                 return;
455         }
456 
457         for (auto it = params.begin(); it != params.end(); ++it)
458         {
459             F1 *func = new F1(fu, &FavoriteUsers::removeFavoriteUser_client, it->first);
460             WulforManager::get()->dispatchClientFunc(func);
461         }
462     }
463 }
464 
onAutoGrantSlotToggled_gui(GtkCellRendererToggle * cell,gchar * path,gpointer data)465 void FavoriteUsers::onAutoGrantSlotToggled_gui(GtkCellRendererToggle *cell, gchar *path, gpointer data)
466 {
467     FavoriteUsers *fu = (FavoriteUsers *)data;
468     GtkTreeIter iter;
469 
470     if (gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(fu->favoriteUserStore), &iter, path))
471     {
472         string cid = fu->favoriteUserView.getString(&iter, _("CID"));
473         gboolean grant = fu->favoriteUserView.getValue<gboolean>(&iter, _("Auto grant slot"));
474         grant = !grant;
475         gtk_list_store_set(fu->favoriteUserStore, &iter, fu->favoriteUserView.col(_("Auto grant slot")), grant, -1);
476 
477         typedef Func2<FavoriteUsers, string, bool> F2;
478         F2 *func = new F2(fu, &FavoriteUsers::setAutoGrantSlot_client, cid, grant);
479         WulforManager::get()->dispatchClientFunc(func);
480     }
481 }
482 
getFileList_client(const string cid,const string hubUrl,bool match)483 void FavoriteUsers::getFileList_client(const string cid, const string hubUrl, bool match)
484 {
485     try
486     {
487         UserPtr user = ClientManager::getInstance()->findUser(CID(cid));
488 
489         if (user)
490         {
491             const HintedUser hintedUser(user, hubUrl);
492             if (match)
493                 QueueManager::getInstance()->addList(hintedUser, QueueItem::FLAG_MATCH_QUEUE);
494             else
495                 QueueManager::getInstance()->addList(hintedUser, QueueItem::FLAG_CLIENT_VIEW);
496         }
497     }
498     catch (const Exception& e)
499     {
500         typedef Func1<FavoriteUsers, string> F1;
501         F1 *func = new F1(this, &FavoriteUsers::setStatus_gui, e.getError());
502         WulforManager::get()->dispatchGuiFunc(func);
503     }
504 }
505 
grantSlot_client(const string cid,const string hubUrl)506 void FavoriteUsers::grantSlot_client(const string cid, const string hubUrl)
507 {
508     UserPtr user = ClientManager::getInstance()->findUser(CID(cid));
509     if (user)
510     {
511         UploadManager::getInstance()->reserveSlot(HintedUser(user, hubUrl));
512         typedef Func1<FavoriteUsers, string> F1;
513         F1 *func = new F1(this, &FavoriteUsers::setStatus_gui, _("Slot granted to ") + WulforUtil::getNicks(user, hubUrl));
514         WulforManager::get()->dispatchGuiFunc(func);
515     }
516 }
517 
removeUserFromQueue_client(const string cid)518 void FavoriteUsers::removeUserFromQueue_client(const string cid)
519 {
520     if (!cid.empty())
521     {
522         UserPtr user = ClientManager::getInstance()->findUser(CID(cid));
523         if (user)
524             QueueManager::getInstance()->removeSource(user, QueueItem::Source::FLAG_REMOVED);
525     }
526 }
527 
setAutoGrantSlot_client(const string cid,bool grant)528 void FavoriteUsers::setAutoGrantSlot_client(const string cid, bool grant)
529 {
530     UserPtr user = ClientManager::getInstance()->findUser(CID(cid));
531 
532     if (user)
533     {
534         FavoriteManager::getInstance()->setAutoGrant(user, grant);
535     }
536 }
537 
removeFavoriteUser_client(const string cid)538 void FavoriteUsers::removeFavoriteUser_client(const string cid)
539 {
540     UserPtr user = ClientManager::getInstance()->findUser(CID(cid));
541 
542     if (user)
543     {
544         FavoriteManager::getInstance()->removeFavoriteUser(user);
545     }
546 }
547 
setUserDescription_client(const string cid,const string description)548 void FavoriteUsers::setUserDescription_client(const string cid, const string description)
549 {
550     UserPtr user = ClientManager::getInstance()->findUser(CID(cid));
551 
552     if (user)
553     {
554         FavoriteManager::getInstance()->setUserDescription(user, description);
555     }
556 }
557 
findUser_gui(const string & cid,GtkTreeIter * iter)558 bool FavoriteUsers::findUser_gui(const string &cid, GtkTreeIter *iter)
559 {
560     auto it = userIters.find(cid);
561 
562     if (it != userIters.end())
563     {
564         if (iter)
565             *iter = it->second;
566 
567         return TRUE;
568     }
569 
570     return FALSE;
571 }
572 
updateFavoriteUser_gui(ParamMap params)573 void FavoriteUsers::updateFavoriteUser_gui(ParamMap params)
574 {
575     const string &cid = params["CID"];
576     GtkTreeIter iter;
577 
578     if (findUser_gui(cid, &iter))
579     {
580         gtk_list_store_set(favoriteUserStore, &iter, favoriteUserView.col(_("Time last seen")), params["Time"].c_str(), -1);
581     }
582     else
583     {
584         gtk_list_store_append(favoriteUserStore, &iter);
585         gtk_list_store_set(favoriteUserStore, &iter,
586             favoriteUserView.col(_("Nick")), params["Nick"].c_str(),
587             favoriteUserView.col(_("Hub (last seen in, if offline)")), params["Hub"].c_str(),
588             favoriteUserView.col(_("Time last seen")), params["Time"].c_str(),
589             favoriteUserView.col(_("Description")), params["Description"].c_str(),
590             favoriteUserView.col(_("CID")), cid.c_str(),
591             favoriteUserView.col("URL"), params["URL"].c_str(),
592             favoriteUserView.col("Icon"), "eiskaltdcpp-normal",
593             -1);
594 
595         userIters.insert(UserIters::value_type(cid, iter));
596     }
597 }
598 
removeFavoriteUser_gui(const string cid)599 void FavoriteUsers::removeFavoriteUser_gui(const string cid)
600 {
601     GtkTreeIter iter;
602 
603     if (findUser_gui(cid, &iter))
604     {
605         gtk_list_store_remove(favoriteUserStore, &iter);
606         userIters.erase(cid);
607     }
608 }
609 
setStatus_gui(const string text)610 void FavoriteUsers::setStatus_gui(const string text)
611 {
612     if (!text.empty())
613     {
614         gtk_statusbar_pop(GTK_STATUSBAR(getWidget("status")), 0);
615         gtk_statusbar_push(GTK_STATUSBAR(getWidget("status")), 0, ("[" + Util::getShortTimeString() + "] " + text).c_str());
616     }
617 }
618 
on(FavoriteManagerListener::UserAdded,const FavoriteUser & user)619 void FavoriteUsers::on(FavoriteManagerListener::UserAdded, const FavoriteUser &user) noexcept
620 {
621     ParamMap params;
622     bool online = user.getUser()->isOnline();
623     params.insert(ParamMap::value_type("Nick", user.getNick()));
624     params.insert(ParamMap::value_type("Hub", online ? WulforUtil::getHubNames(user.getUser(), user.getUrl()) : user.getUrl()));
625     params.insert(ParamMap::value_type("Time", online ? _("Online") : Util::formatTime("%Y-%m-%d %H:%M", user.getLastSeen())));
626     params.insert(ParamMap::value_type("Description", user.getDescription()));
627     params.insert(ParamMap::value_type("CID", user.getUser()->getCID().toBase32()));
628     params.insert(ParamMap::value_type("URL", user.getUrl()));
629 
630     Func1<FavoriteUsers, ParamMap> *func = new Func1<FavoriteUsers, ParamMap>(this, &FavoriteUsers::updateFavoriteUser_gui, params);
631     WulforManager::get()->dispatchGuiFunc(func);
632 }
633 
on(FavoriteManagerListener::UserRemoved,const FavoriteUser & user)634 void FavoriteUsers::on(FavoriteManagerListener::UserRemoved, const FavoriteUser &user) noexcept
635 {
636     Func1<FavoriteUsers, string> *func = new Func1<FavoriteUsers, string>(this, &FavoriteUsers::removeFavoriteUser_gui,
637         user.getUser()->getCID().toBase32());
638     WulforManager::get()->dispatchGuiFunc(func);
639 }
640 
on(FavoriteManagerListener::StatusChanged,const FavoriteUser & user)641 void FavoriteUsers::on(FavoriteManagerListener::StatusChanged, const FavoriteUser &user) noexcept
642 {
643     ParamMap params;
644     string seen = user.getUser()->isOnline() ? _("Online") : Util::formatTime("%Y-%m-%d %H:%M", user.getLastSeen());
645     params.insert(ParamMap::value_type("Time", seen));
646     params.insert(ParamMap::value_type("CID", user.getUser()->getCID().toBase32()));
647 
648     Func1<FavoriteUsers, ParamMap> *func = new Func1<FavoriteUsers, ParamMap>(this, &FavoriteUsers::updateFavoriteUser_gui, params);
649     WulforManager::get()->dispatchGuiFunc(func);
650 }
651