1 /*
2 * Copyright © 2004-2010 Jens Oknelid, paskharen@gmail.com
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 <sstream>
23 #include <iostream>
24 #include <iomanip>
25 #include <iterator>
26 #include "transfers.hh"
27 #include "WulforUtil.hh"
28 #include "wulformanager.hh"
29 #include "settingsmanager.hh"
30 #include "func.hh"
31 #include "previewmenu.hh"
32 #include "UserCommandMenu.hh"
33 #include <dcpp/Download.h>
34 #include <dcpp/Upload.h>
35 #include <dcpp/ClientManager.h>
36 #include <dcpp/TimerManager.h>
37 #include <dcpp/FavoriteManager.h>
38
39 using namespace std;
40 using namespace dcpp;
41
Transfers()42 Transfers::Transfers() :
43 Entry(Entry::TRANSFERS, "transfers.ui")
44 {
45 // menu
46 g_object_ref_sink(getWidget("transferMenu"));
47
48 // Initialize the user command menu
49 userCommandMenu = new UserCommandMenu(getWidget("userCommandMenu"), ::UserCommand::CONTEXT_USER);
50 addChild(userCommandMenu);
51
52 // Initialize the preview menu
53 appsPreviewMenu = new PreviewMenu(getWidget("appsPreviewMenu"));
54
55 // Initialize transfer treeview
56 transferView.setView(GTK_TREE_VIEW(getWidget("transfers")), TRUE, "transfers");
57 transferView.insertColumn(_("User"), G_TYPE_STRING, TreeView::ICON_STRING, 150, "Icon");
58 transferView.insertColumn(_("Hub Name"), G_TYPE_STRING, TreeView::STRING, 100);
59 transferView.insertColumn(_("Progress"), G_TYPE_STRING, TreeView::PROGRESS, 85, "Progress Hidden");
60 transferView.insertColumn(_("Status"), G_TYPE_STRING, TreeView::STRING, 250);
61 transferView.insertColumn(_("Time"), G_TYPE_STRING, TreeView::STRING, 85);
62 transferView.insertColumn(_("Time Left"), G_TYPE_INT64, TreeView::TIME_LEFT, 85);
63 transferView.insertColumn(_("Speed"), G_TYPE_INT64, TreeView::SPEED, 125);
64 transferView.insertColumn(_("Flags"), G_TYPE_STRING, TreeView::STRING, 85);
65 transferView.insertColumn(_("Transferred"), G_TYPE_STRING, TreeView::STRING, 85);
66 transferView.insertColumn(_("Filename"), G_TYPE_STRING, TreeView::STRING, 200);
67 transferView.insertColumn(_("Size"), G_TYPE_INT64, TreeView::SIZE, 125);
68 transferView.insertColumn(_("Path"), G_TYPE_STRING, TreeView::STRING, 200);
69 transferView.insertColumn(_("IP"), G_TYPE_STRING, TreeView::STRING, 175);
70 transferView.insertColumn(_("Encryption"), G_TYPE_STRING, TreeView::STRING, 175);
71 transferView.insertHiddenColumn("Icon", G_TYPE_STRING);
72 transferView.insertHiddenColumn("Progress Hidden", G_TYPE_INT);
73 transferView.insertHiddenColumn("Sort Order", G_TYPE_STRING);
74 transferView.insertHiddenColumn("CID", G_TYPE_STRING);
75 transferView.insertHiddenColumn("Download Position", G_TYPE_INT64); // For keeping track of and calculating parent pos
76 transferView.insertHiddenColumn("Failed", G_TYPE_BOOLEAN);
77 transferView.insertHiddenColumn("Target", G_TYPE_STRING);
78 transferView.insertHiddenColumn("tmpTarget", G_TYPE_STRING);
79 transferView.insertHiddenColumn("Download", G_TYPE_BOOLEAN);
80 transferView.insertHiddenColumn("Hub URL", G_TYPE_STRING);
81 transferView.finalize();
82
83 transferStore = gtk_tree_store_newv(transferView.getColCount(), transferView.getGTypes());
84 gtk_tree_view_set_model(transferView.get(), GTK_TREE_MODEL(transferStore));
85 g_object_unref(transferStore);
86 transferSelection = gtk_tree_view_get_selection(transferView.get());
87 gtk_tree_selection_set_mode(transferSelection, GTK_SELECTION_MULTIPLE);
88 transferView.setSortColumn_gui(_("User"), "Sort Order");
89 gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(transferStore), transferView.col("Sort Order"), GTK_SORT_ASCENDING);
90 gtk_tree_view_column_set_sort_indicator(gtk_tree_view_get_column(transferView.get(), transferView.col(_("User"))), TRUE);
91 gtk_tree_view_set_fixed_height_mode(transferView.get(), TRUE);
92
93 g_signal_connect(transferView.get(), "button-press-event", G_CALLBACK(onTransferButtonPressed_gui), (gpointer)this);
94 g_signal_connect(transferView.get(), "button-release-event", G_CALLBACK(onTransferButtonReleased_gui), (gpointer)this);
95 g_signal_connect(getWidget("getFileListItem"), "activate", G_CALLBACK(onGetFileListClicked_gui), (gpointer)this);
96 g_signal_connect(getWidget("matchQueueItem"), "activate", G_CALLBACK(onMatchQueueClicked_gui), (gpointer)this);
97 g_signal_connect(getWidget("sendPrivateMessageItem"), "activate", G_CALLBACK(onPrivateMessageClicked_gui), (gpointer)this);
98 g_signal_connect(getWidget("addToFavoritesItem"), "activate", G_CALLBACK(onAddFavoriteUserClicked_gui), (gpointer)this);
99 g_signal_connect(getWidget("grantExtraSlotItem"), "activate", G_CALLBACK(onGrantExtraSlotClicked_gui), (gpointer)this);
100 g_signal_connect(getWidget("removeUserItem"), "activate", G_CALLBACK(onRemoveUserFromQueueClicked_gui), (gpointer)this);
101 g_signal_connect(getWidget("forceAttemptItem"), "activate", G_CALLBACK(onForceAttemptClicked_gui), (gpointer)this);
102 g_signal_connect(getWidget("closeConnectionItem"), "activate", G_CALLBACK(onCloseConnectionClicked_gui), (gpointer)this);
103 }
104
~Transfers()105 Transfers::~Transfers()
106 {
107 QueueManager::getInstance()->removeListener(this);
108 DownloadManager::getInstance()->removeListener(this);
109 UploadManager::getInstance()->removeListener(this);
110 ConnectionManager::getInstance()->removeListener(this);
111
112 g_object_unref(getWidget("transferMenu"));
113 delete appsPreviewMenu;
114 }
115
show()116 void Transfers::show()
117 {
118 QueueManager::getInstance()->addListener(this);
119 DownloadManager::getInstance()->addListener(this);
120 UploadManager::getInstance()->addListener(this);
121 ConnectionManager::getInstance()->addListener(this);
122 }
123
popupTransferMenu_gui()124 void Transfers::popupTransferMenu_gui()
125 {
126 // Build user command menu
127 appsPreviewMenu->cleanMenu_gui();
128 userCommandMenu->cleanMenu_gui();
129
130 GtkTreePath *path;
131 GtkTreeIter iter;
132 GList *list = gtk_tree_selection_get_selected_rows(transferSelection, NULL);
133 string target = "";
134
135 for (GList *i = list; i; i = i->next)
136 {
137 path = (GtkTreePath *)i->data;
138 if (gtk_tree_model_get_iter(GTK_TREE_MODEL(transferStore), &iter, path))
139 {
140 bool parent = gtk_tree_model_iter_has_child(GTK_TREE_MODEL(transferStore), &iter);
141
142 do
143 {
144 if (target.empty())
145 target = transferView.getString(&iter, "tmpTarget");
146
147 string cid = transferView.getString(&iter, "CID");
148 string hubUrl = transferView.getString(&iter, "Hub URL");
149 userCommandMenu->addUser(cid);
150 userCommandMenu->addHub(WulforUtil::getHubAddress(CID(cid), hubUrl));
151 }
152 while (parent && WulforUtil::getNextIter_gui(GTK_TREE_MODEL(transferStore), &iter, TRUE, FALSE));
153 }
154 gtk_tree_path_free(path);
155 }
156 g_list_free(list);
157
158 userCommandMenu->buildMenu_gui();
159
160 if (appsPreviewMenu->buildMenu_gui(target))
161 gtk_widget_set_sensitive(getWidget("appsPreviewItem"), TRUE);
162 else gtk_widget_set_sensitive(getWidget("appsPreviewItem"), FALSE);
163
164 gtk_menu_popup(GTK_MENU(getWidget("transferMenu")), NULL, NULL, NULL, NULL, 0, gtk_get_current_event_time());
165 gtk_widget_show_all(getWidget("transferMenu"));
166 }
167
onGetFileListClicked_gui(GtkMenuItem * item,gpointer data)168 void Transfers::onGetFileListClicked_gui(GtkMenuItem *item, gpointer data)
169 {
170 Transfers *tr = (Transfers *)data;
171 GtkTreeIter iter;
172 GtkTreePath *path;
173 GList *list = gtk_tree_selection_get_selected_rows(tr->transferSelection, NULL);
174 typedef Func2<Transfers, string, string> F2;
175
176 for (GList *i = list; i; i = i->next)
177 {
178 path = (GtkTreePath *)i->data;
179 if (gtk_tree_model_get_iter(GTK_TREE_MODEL(tr->transferStore), &iter, path))
180 {
181 bool parent = gtk_tree_model_iter_has_child(GTK_TREE_MODEL(tr->transferStore), &iter);
182
183 do
184 {
185 string cid = tr->transferView.getString(&iter, "CID");
186 string hubUrl = tr->transferView.getString(&iter, "Hub URL");
187 if (!cid.empty())
188 {
189 F2 *func = new F2(tr, &Transfers::getFileList_client, cid, hubUrl);
190 WulforManager::get()->dispatchClientFunc(func);
191 }
192 }
193 while (parent && WulforUtil::getNextIter_gui(GTK_TREE_MODEL(tr->transferStore), &iter, TRUE, FALSE));
194 }
195 gtk_tree_path_free(path);
196 }
197 g_list_free(list);
198 }
199
onMatchQueueClicked_gui(GtkMenuItem * item,gpointer data)200 void Transfers::onMatchQueueClicked_gui(GtkMenuItem *item, gpointer data)
201 {
202 Transfers *tr = (Transfers *)data;
203 GtkTreeIter iter;
204 GtkTreePath *path;
205 GList *list = gtk_tree_selection_get_selected_rows(tr->transferSelection, NULL);
206 typedef Func2<Transfers, string, string> F2;
207
208 for (GList *i = list; i; i = i->next)
209 {
210 path = (GtkTreePath *)i->data;
211 if (gtk_tree_model_get_iter(GTK_TREE_MODEL(tr->transferStore), &iter, path))
212 {
213 bool parent = gtk_tree_model_iter_has_child(GTK_TREE_MODEL(tr->transferStore), &iter);
214
215 do
216 {
217 string cid = tr->transferView.getString(&iter, "CID");
218 string hubUrl = tr->transferView.getString(&iter, "Hub URL");
219 if (!cid.empty())
220 {
221 F2 *func = new F2(tr, &Transfers::matchQueue_client, cid, hubUrl);
222 WulforManager::get()->dispatchClientFunc(func);
223 }
224 }
225 while (parent && WulforUtil::getNextIter_gui(GTK_TREE_MODEL(tr->transferStore), &iter, TRUE, FALSE));
226 }
227 gtk_tree_path_free(path);
228 }
229 g_list_free(list);
230 }
231
onPrivateMessageClicked_gui(GtkMenuItem * item,gpointer data)232 void Transfers::onPrivateMessageClicked_gui(GtkMenuItem *item, gpointer data)
233 {
234 Transfers *tr = (Transfers *)data;
235 string cid;
236 GtkTreeIter iter;
237 GtkTreePath *path;
238 GList *list = gtk_tree_selection_get_selected_rows(tr->transferSelection, NULL);
239
240 for (GList *i = list; i; i = i->next)
241 {
242 path = (GtkTreePath *)i->data;
243 if (gtk_tree_model_get_iter(GTK_TREE_MODEL(tr->transferStore), &iter, path))
244 {
245 bool parent = gtk_tree_model_iter_has_child(GTK_TREE_MODEL(tr->transferStore), &iter);
246
247 do
248 {
249 cid = tr->transferView.getString(&iter, "CID");
250 if (!cid.empty())
251 WulforManager::get()->getMainWindow()->addPrivateMessage_gui(Msg::UNKNOWN, cid);
252 }
253 while (parent && WulforUtil::getNextIter_gui(GTK_TREE_MODEL(tr->transferStore), &iter, TRUE, FALSE));
254 }
255 gtk_tree_path_free(path);
256 }
257 g_list_free(list);
258 }
259
onAddFavoriteUserClicked_gui(GtkMenuItem * item,gpointer data)260 void Transfers::onAddFavoriteUserClicked_gui(GtkMenuItem *item, gpointer data)
261 {
262 Transfers *tr = (Transfers *)data;
263 string cid;
264 GtkTreeIter iter;
265 GtkTreePath *path;
266 GList *list = gtk_tree_selection_get_selected_rows(tr->transferSelection, NULL);
267 typedef Func1<Transfers, string > F1;
268 F1 *func;
269
270 for (GList *i = list; i; i = i->next)
271 {
272 path = (GtkTreePath *)i->data;
273 if (gtk_tree_model_get_iter(GTK_TREE_MODEL(tr->transferStore), &iter, path))
274 {
275 bool parent = gtk_tree_model_iter_has_child(GTK_TREE_MODEL(tr->transferStore), &iter);
276
277 do
278 {
279 cid = tr->transferView.getString(&iter, "CID");
280 if (!cid.empty())
281 {
282 func = new F1(tr, &Transfers::addFavoriteUser_client, cid);
283 WulforManager::get()->dispatchClientFunc(func);
284 }
285 }
286 while (parent && WulforUtil::getNextIter_gui(GTK_TREE_MODEL(tr->transferStore), &iter, TRUE, FALSE));
287 }
288 gtk_tree_path_free(path);
289 }
290 g_list_free(list);
291 }
292
onGrantExtraSlotClicked_gui(GtkMenuItem * item,gpointer data)293 void Transfers::onGrantExtraSlotClicked_gui(GtkMenuItem *item, gpointer data)
294 {
295 Transfers *tr = (Transfers *)data;
296 GtkTreeIter iter;
297 GtkTreePath *path;
298 GList *list = gtk_tree_selection_get_selected_rows(tr->transferSelection, NULL);
299 typedef Func2<Transfers, string, string> F2;
300
301 for (GList *i = list; i; i = i->next)
302 {
303 path = (GtkTreePath *)i->data;
304 if (gtk_tree_model_get_iter(GTK_TREE_MODEL(tr->transferStore), &iter, path))
305 {
306 bool parent = gtk_tree_model_iter_has_child(GTK_TREE_MODEL(tr->transferStore), &iter);
307
308 do
309 {
310 string cid = tr->transferView.getString(&iter, "CID");
311 string hubUrl = tr->transferView.getString(&iter, "Hub URL");
312 if (!cid.empty())
313 {
314 F2 *func = new F2(tr, &Transfers::grantExtraSlot_client, cid, hubUrl);
315 WulforManager::get()->dispatchClientFunc(func);
316 }
317 }
318 while (parent && WulforUtil::getNextIter_gui(GTK_TREE_MODEL(tr->transferStore), &iter, TRUE, FALSE));
319 }
320 gtk_tree_path_free(path);
321 }
322 g_list_free(list);
323 }
324
onRemoveUserFromQueueClicked_gui(GtkMenuItem * item,gpointer data)325 void Transfers::onRemoveUserFromQueueClicked_gui(GtkMenuItem *item, gpointer data)
326 {
327 Transfers *tr = (Transfers *)data;
328 string cid;
329 GtkTreeIter iter;
330 GtkTreePath *path;
331 GList *list = gtk_tree_selection_get_selected_rows(tr->transferSelection, NULL);
332 typedef Func1<Transfers, string > F1;
333 F1 *func;
334
335 for (GList *i = list; i; i = i->next)
336 {
337 path = (GtkTreePath *)i->data;
338 if (gtk_tree_model_get_iter(GTK_TREE_MODEL(tr->transferStore), &iter, path))
339 {
340 bool parent = gtk_tree_model_iter_has_child(GTK_TREE_MODEL(tr->transferStore), &iter);
341
342 do
343 {
344 cid = tr->transferView.getString(&iter, "CID");
345 if (!cid.empty())
346 {
347 func = new F1(tr, &Transfers::removeUserFromQueue_client, cid);
348 WulforManager::get()->dispatchClientFunc(func);
349 }
350 }
351 while (parent && WulforUtil::getNextIter_gui(GTK_TREE_MODEL(tr->transferStore), &iter, TRUE, FALSE));
352 }
353 gtk_tree_path_free(path);
354 }
355 g_list_free(list);
356 }
357
onForceAttemptClicked_gui(GtkMenuItem * menuItem,gpointer data)358 void Transfers::onForceAttemptClicked_gui(GtkMenuItem *menuItem, gpointer data)
359 {
360 Transfers *tr = (Transfers *)data;
361 string cid;
362 GtkTreeIter iter;
363 GtkTreePath *path;
364 GList *list = gtk_tree_selection_get_selected_rows(tr->transferSelection, NULL);
365 typedef Func1<Transfers, string> F1;
366 F1 *func;
367
368 for (GList *i = list; i; i = i->next)
369 {
370 path = (GtkTreePath *)i->data;
371 if (gtk_tree_model_get_iter(GTK_TREE_MODEL(tr->transferStore), &iter, path))
372 {
373 cid = tr->transferView.getString(&iter, "CID");
374 gtk_tree_store_set(tr->transferStore, &iter, tr->transferView.col(_("Status")), _("Connecting (forced)..."), -1);
375
376 func = new F1(tr, &Transfers::forceAttempt_client, cid);
377 WulforManager::get()->dispatchClientFunc(func);
378 }
379 gtk_tree_path_free(path);
380 }
381 g_list_free(list);
382 }
383
onCloseConnectionClicked_gui(GtkMenuItem * menuItem,gpointer data)384 void Transfers::onCloseConnectionClicked_gui(GtkMenuItem *menuItem, gpointer data)
385 {
386 Transfers *tr = (Transfers *)data;
387 string cid;
388 GtkTreeIter iter;
389 GtkTreePath *path;
390 bool download;
391 GList *list = gtk_tree_selection_get_selected_rows(tr->transferSelection, NULL);
392 typedef Func2<Transfers, string, bool> F2;
393 F2 *func;
394
395 for (GList *i = list; i; i = i->next)
396 {
397 path = (GtkTreePath *)i->data;
398 if (gtk_tree_model_get_iter(GTK_TREE_MODEL(tr->transferStore), &iter, path))
399 {
400 bool parent = gtk_tree_model_iter_has_child(GTK_TREE_MODEL(tr->transferStore), &iter);
401
402 do
403 {
404 cid = tr->transferView.getString(&iter, "CID");
405 if (!cid.empty())
406 {
407 gtk_tree_store_set(tr->transferStore, &iter, tr->transferView.col(_("Status")), _("Closing connection..."), -1);
408 download = tr->transferView.getValue<gboolean>(&iter, "Download");
409
410 func = new F2(tr, &Transfers::closeConnection_client, cid, download);
411 WulforManager::get()->dispatchClientFunc(func);
412 }
413 }
414 while (parent && WulforUtil::getNextIter_gui(GTK_TREE_MODEL(tr->transferStore), &iter, TRUE, FALSE));
415 }
416 gtk_tree_path_free(path);
417 }
418 g_list_free(list);
419 }
420
onTransferButtonPressed_gui(GtkWidget * widget,GdkEventButton * event,gpointer data)421 gboolean Transfers::onTransferButtonPressed_gui(GtkWidget *widget, GdkEventButton *event, gpointer data)
422 {
423 Transfers *tr = (Transfers *)data;
424
425 if (event->button == 3)
426 {
427 GtkTreePath *path;
428 if (gtk_tree_view_get_path_at_pos(tr->transferView.get(), (gint)event->x, (gint)event->y, &path, NULL, NULL, NULL))
429 {
430 bool selected = gtk_tree_selection_path_is_selected(tr->transferSelection, path);
431 gtk_tree_path_free(path);
432
433 if (selected)
434 return TRUE;
435 }
436 }
437
438 return FALSE;
439 }
440
onTransferButtonReleased_gui(GtkWidget * widget,GdkEventButton * event,gpointer data)441 gboolean Transfers::onTransferButtonReleased_gui(GtkWidget *widget, GdkEventButton *event, gpointer data)
442 {
443 Transfers *tr = (Transfers *)data;
444 int count = gtk_tree_selection_count_selected_rows(tr->transferSelection);
445
446 if (count > 0 && event->type == GDK_BUTTON_RELEASE && event->button == 3)
447 tr->popupTransferMenu_gui();
448
449 return FALSE;
450 }
451
findParent_gui(const string & target,GtkTreeIter * iter)452 bool Transfers::findParent_gui(const string& target, GtkTreeIter* iter)
453 {
454 dcassert(!target.empty());
455 GtkTreeModel *m = GTK_TREE_MODEL(transferStore);
456 bool valid = gtk_tree_model_get_iter_first(m, iter);
457
458 while (valid)
459 {
460 if (transferView.getValue<gboolean>(iter, "Download") &&
461 target == transferView.getString(iter, "Target") &&
462 transferView.getString(iter, "CID").empty())
463 return TRUE;
464
465 valid = WulforUtil::getNextIter_gui(m, iter, FALSE, FALSE);
466 }
467
468 return FALSE;
469 }
470
findTransfer_gui(const string & cid,bool download,GtkTreeIter * iter)471 bool Transfers::findTransfer_gui(const string& cid, bool download, GtkTreeIter* iter)
472 {
473 GtkTreeModel *m = GTK_TREE_MODEL(transferStore);
474 bool valid = gtk_tree_model_get_iter_first(m, iter);
475
476 while (valid)
477 {
478 if (cid == transferView.getString(iter, "CID") && !cid.empty())
479 {
480 if (download && transferView.getValue<gboolean>(iter, "Download"))
481 return TRUE;
482 if (!download && !transferView.getValue<gboolean>(iter, "Download"))
483 return TRUE;
484 }
485 valid = WulforUtil::getNextIter_gui(m, iter, TRUE, TRUE);
486 }
487
488 return FALSE;
489 }
490
addConnection_gui(StringMap params,bool download)491 void Transfers::addConnection_gui(StringMap params, bool download)
492 {
493 GtkTreeIter iter;
494 dcassert(params.find("CID") != params.end());
495 dcassert(findTransfer_gui(params["CID"], download, &iter) == FALSE); // shouldn't fail, if it's already there we've forgot to remove it or dcpp core sends more than one Connection::Added
496
497 gtk_tree_store_append(transferStore, &iter, NULL);
498 gtk_tree_store_set(transferStore, &iter,
499 transferView.col(_("User")), params["User"].c_str(),
500 transferView.col(_("Hub Name")), params["Hub Name"].c_str(),
501 transferView.col(_("Status")), params["Status"].c_str(),
502 transferView.col("CID"), params["CID"].c_str(),
503 transferView.col("Icon"), download ? "icon-download" : "icon-upload",
504 transferView.col("Download"), download,
505 transferView.col("Hub URL"), params["Hub URL"].c_str(),
506 -1);
507 }
508
removeConnection_gui(const string cid,bool download)509 void Transfers::removeConnection_gui(const string cid, bool download)
510 {
511 GtkTreeIter iter;
512 GtkTreeIter parent;
513 bool valid = findTransfer_gui(cid, download, &iter);
514
515 if (valid)
516 {
517 if (gtk_tree_model_iter_parent(GTK_TREE_MODEL(transferStore), &parent, &iter))
518 {
519 gtk_tree_store_remove(transferStore, &iter);
520
521 if (!gtk_tree_model_iter_has_child(GTK_TREE_MODEL(transferStore), &parent))
522 gtk_tree_store_remove(transferStore, &parent);
523 else
524 updateParent_gui(&parent);
525 }
526 else
527 {
528 gtk_tree_store_remove(transferStore, &iter);
529 }
530 }
531 }
532
updateParent_gui(GtkTreeIter * iter)533 void Transfers::updateParent_gui(GtkTreeIter* iter)
534 {
535 int active = 0;
536 GtkTreeIter child;
537 string sprogress, users, status;
538 set<string> hubs;
539 int64_t speed = 0;
540 int64_t position = 0;
541 int64_t totalSize = 0;
542 int64_t timeLeft = 0;
543 double progress = 0.0;
544 ostringstream susers;
545 ostringstream tmpHubs;
546
547 position = transferView.getValue<int64_t>(iter, "Download Position");
548 totalSize = transferView.getValue<int64_t>(iter, _("Size"));
549
550 // Get Totals
551 if (gtk_tree_model_iter_has_child(GTK_TREE_MODEL(transferStore), iter))
552 {
553 child = *iter;
554 bool valid = WulforUtil::getNextIter_gui(GTK_TREE_MODEL(transferStore), &child, TRUE, FALSE);
555 while (valid)
556 {
557 if (transferView.getValue<int>(&child, "Failed") == 0 &&
558 transferView.getString(&child, "Sort Order").substr(0,1) == "d")
559 {
560 active++;
561 speed += transferView.getValue<int64_t>(&child, _("Speed"));
562 position += transferView.getValue<int64_t>(&child, "Download Position");
563 }
564 users += transferView.getString(&child, _("User")) + string(", ");
565 hubs.insert(transferView.getString(&child, _("Hub Name")));
566 valid = WulforUtil::getNextIter_gui(GTK_TREE_MODEL(transferStore), &child, TRUE, FALSE);
567 }
568 }
569
570 if (totalSize > 0)
571 progress = (double)(position * 100.0) / totalSize;
572 if (speed > 0)
573 timeLeft = (totalSize - position) / speed;
574
575 susers << setiosflags(ios::fixed) << setprecision(1);
576 susers << active << "/" << gtk_tree_model_iter_n_children(GTK_TREE_MODEL(transferStore), iter);
577
578 if (transferView.getValue<gboolean>(iter, "Failed") == 0)
579 {
580 if (active)
581 status = _("Downloading");
582 else
583 status = _("Waiting for slot");
584 }
585 else
586 {
587 status = transferView.getString(iter, _("Status"));
588 }
589
590 sprogress = Util::toString(static_cast<int>(progress)) + "%";
591
592 std::copy(hubs.begin(), hubs.end(), std::ostream_iterator<string>(tmpHubs, ", "));
593
594 gtk_tree_store_set(transferStore, iter,
595 transferView.col(_("User")), susers.str().c_str(),
596 transferView.col(_("Hub Name")), tmpHubs.str().substr(0, tmpHubs.str().length()-2).c_str(),
597 transferView.col(_("Speed")), speed,
598 transferView.col(_("Transferred")), Util::formatBytes(position).c_str(),
599 transferView.col(_("Time Left")), timeLeft,
600 transferView.col(_("Progress")), sprogress.c_str(),
601 transferView.col(_("Status")), status.c_str(),
602 transferView.col("Progress Hidden"), static_cast<int>(progress),
603 transferView.col("Sort Order"), active ? (string("d").append(users)).c_str() : (string("w").append(users)).c_str(),
604 -1);
605 }
606
updateTransfer_gui(StringMap params,bool download,Sound::TypeSound sound)607 void Transfers::updateTransfer_gui(StringMap params, bool download, Sound::TypeSound sound)
608 {
609 dcassert(!params["CID"].empty());
610
611 GtkTreeIter iter, parent;
612 if (!findTransfer_gui(params["CID"], download, &iter))
613 {
614 dcdebug(_("Transfers::updateTransfer, CID not found %s\n"), params["CID"].c_str());
615 // Transfer not found. Usually this *shouldn't* happen, but I guess it's possible since tick updates are sent by TimerManager
616 // and removing is handled by dl manager.
617
618 return;
619 }
620
621 int failed = transferView.getValue<int>(&iter, "Failed");
622 if (failed && params.find("Failed") != params.end())
623 failed = Util::toInt(params["Failed"]);
624
625 if (failed) // Transfer had failed already. We won't update the transfer before the fail status changes.
626 return;
627 for (auto it = params.begin(); it != params.end(); ++it)
628 {
629 if (it->first == "Size" || it->first == "Speed" || it->first == "Download Position" || it->first == "Time Left")
630 gtk_tree_store_set(transferStore, &iter, transferView.col(_(it->first.c_str())), Util::toInt64(it->second), -1);
631 else if (it->first == "Progress Hidden" || it->first == "Failed")
632 gtk_tree_store_set(transferStore, &iter, transferView.col(it->first), Util::toInt(it->second), -1);
633 else if (!it->second.empty())
634 gtk_tree_store_set(transferStore, &iter, transferView.col(_(it->first.c_str())), it->second.c_str(), -1);
635 }
636 if (gtk_tree_model_iter_parent(GTK_TREE_MODEL(transferStore), &parent, &iter))
637 updateParent_gui(&parent);
638 playSound_gui(sound);
639 }
640
updateFilePosition_gui(const string cid,int64_t filePosition)641 void Transfers::updateFilePosition_gui(const string cid, int64_t filePosition)
642 {
643 GtkTreeIter iter;
644 GtkTreeIter parent;
645
646 if (!findTransfer_gui(cid, TRUE, &iter))
647 return;
648
649 if (gtk_tree_model_iter_parent(GTK_TREE_MODEL(transferStore), &parent, &iter))
650 {
651 gtk_tree_store_set(transferStore, &parent,
652 transferView.col("Download Position"), filePosition,
653 -1);
654 updateParent_gui(&parent);
655 }
656 }
657
initTransfer_gui(StringMap params)658 void Transfers::initTransfer_gui(StringMap params)
659 {
660 dcassert(!params["CID"].empty() && !params["Target"].empty());
661
662 bool oldParentValid = FALSE;
663 bool newParentValid = FALSE;
664 bool needParent;
665 GtkTreeIter iter;
666 GtkTreeIter oldParent;
667 GtkTreeIter newParent;
668 GtkTreeIter newIter;
669
670 // We could use && BOOLSETTING(SEGMENTED_DL) here to group only when segmented is enabled,
671 // but then the transfer should be worked out to display the whole size of the file. As
672 // it currently only shows the size of a transfer (and always starts from 0)
673 needParent = (params["Filename"] != string(_("File list"))) && BOOLSETTING(SEGMENTED_DL);
674
675 if (!findTransfer_gui(params["CID"], TRUE, &iter))
676 {
677 dcassert(0); // not really fatal only annoying as the dl can't be seen, can be ignored in release build
678 return;
679 }
680
681 oldParentValid = gtk_tree_model_iter_parent(GTK_TREE_MODEL(transferStore), &oldParent, &iter);
682 if (needParent)
683 {
684 newParentValid = findParent_gui(params["Target"], &newParent);
685
686 if (newParentValid)
687 {
688 string target = oldParentValid ? transferView.getString(&oldParent, "Target") : transferView.getString(&iter, "Target");
689 if (target != transferView.getString(&newParent, "Target")) // is the file changing
690 {
691 newIter = WulforUtil::copyRow_gui(transferStore, &iter, &newParent);
692 gtk_tree_store_remove(transferStore, &iter);
693 iter = newIter;
694 }
695 else
696 {
697 if (transferView.getValue<int>(&newParent, "Failed"))
698 {
699 gtk_tree_store_set(transferStore, &newParent,
700 transferView.col("Failed"), FALSE,
701 -1);
702 }
703
704 oldParentValid = FALSE; // Don't update the parentRow twice, since old and new are the same (and definately don't remove twice)
705 }
706 }
707 else
708 {
709 string filename = params["Filename"];
710 if (filename.find(_("TTH: ")) != string::npos)
711 filename = filename.substr((string(_("TTH: "))).length());
712 gtk_tree_store_append(transferStore, &newParent, NULL);
713 newParentValid = TRUE;
714 gtk_tree_store_set(transferStore, &newParent,
715 transferView.col(_("Filename")), filename.c_str(),
716 transferView.col(_("Path")), params["Path"].c_str(),
717 transferView.col(_("Size")), Util::toInt64(params["File Size"]),
718 transferView.col("Icon"), "icon-download",
719 transferView.col("Download"), TRUE,
720 transferView.col("Target"), params["Target"].c_str(),
721 -1);
722
723 newIter = WulforUtil::copyRow_gui(transferStore, &iter, &newParent);
724 gtk_tree_store_remove(transferStore, &iter);
725 iter = newIter;
726 }
727
728 gtk_tree_store_set(transferStore, &newParent,
729 transferView.col(_("Size")), Util::toInt64(params["File Size"]),
730 transferView.col("Download Position"), Util::toInt64(params["File Position"]),
731 -1);
732 }
733 else if (oldParentValid) // No need for parent, but we have one anyway => move row to top-level
734 {
735 newIter = WulforUtil::copyRow_gui(transferStore, &iter, NULL);
736 gtk_tree_store_remove(transferStore, &iter);
737 iter = newIter;
738 }
739
740 if (oldParentValid)
741 {
742 if (!gtk_tree_model_iter_n_children(GTK_TREE_MODEL(transferStore), &oldParent))
743 gtk_tree_store_remove(transferStore, &oldParent);
744 else
745 updateParent_gui(&oldParent);
746 }
747 if (newParentValid)
748 {
749 updateParent_gui(&newParent);
750 }
751 }
752
finishParent_gui(const string target,const string status,Sound::TypeSound sound)753 void Transfers::finishParent_gui(const string target, const string status, Sound::TypeSound sound)
754 {
755 GtkTreeIter iter;
756 if (findParent_gui(target, &iter))
757 {
758 if (!gtk_tree_model_iter_has_child(GTK_TREE_MODEL(transferStore), &iter))
759 return;
760
761 if (transferView.getValue<gboolean>(&iter, "Failed") == 0)
762 {
763 gtk_tree_store_set(transferStore, &iter,
764 transferView.col(_("Status")), status.c_str(),
765 transferView.col("Failed"), (gboolean)1,
766 transferView.col(_("Speed")), (uint64_t)-1,
767 -1);
768 }
769 }
770
771 playSound_gui(sound);
772 }
773
playSound_gui(Sound::TypeSound sound)774 void Transfers::playSound_gui(Sound::TypeSound sound)
775 {
776 if (sound != Sound::NONE)
777 Sound::get()->playSound(sound);
778 }
779
getFileList_client(string cid,string hubUrl)780 void Transfers::getFileList_client(string cid, string hubUrl)
781 {
782 try
783 {
784 if (!cid.empty() && !hubUrl.empty())
785 {
786 UserPtr user = ClientManager::getInstance()->getUser(CID(cid));
787 QueueManager::getInstance()->addList(HintedUser(user, hubUrl), QueueItem::FLAG_CLIENT_VIEW);
788 }
789 }
790 catch (const Exception&)
791 {
792 }
793 }
794
matchQueue_client(string cid,string hubUrl)795 void Transfers::matchQueue_client(string cid, string hubUrl)
796 {
797 try
798 {
799 if (!cid.empty() && !hubUrl.empty())
800 {
801 UserPtr user = ClientManager::getInstance()->getUser(CID(cid));
802 QueueManager::getInstance()->addList(HintedUser(user, hubUrl), QueueItem::FLAG_MATCH_QUEUE);
803 }
804 }
805 catch (const Exception&)
806 {
807 }
808 }
809
addFavoriteUser_client(string cid)810 void Transfers::addFavoriteUser_client(string cid)
811 {
812 if (!cid.empty())
813 {
814 UserPtr user = ClientManager::getInstance()->getUser(CID(cid));
815 FavoriteManager::getInstance()->addFavoriteUser(user);
816 }
817 }
818
grantExtraSlot_client(string cid,string hubUrl)819 void Transfers::grantExtraSlot_client(string cid, string hubUrl)
820 {
821 if (!cid.empty() && !hubUrl.empty())
822 {
823 UserPtr user = ClientManager::getInstance()->getUser(CID(cid));
824 UploadManager::getInstance()->reserveSlot(HintedUser(user, hubUrl));
825 }
826 }
827
removeUserFromQueue_client(string cid)828 void Transfers::removeUserFromQueue_client(string cid)
829 {
830 if (!cid.empty())
831 {
832 UserPtr user = ClientManager::getInstance()->getUser(CID(cid));
833 QueueManager::getInstance()->removeSource(user, QueueItem::Source::FLAG_REMOVED);
834 }
835 }
836
forceAttempt_client(string cid)837 void Transfers::forceAttempt_client(string cid)
838 {
839 if (!cid.empty())
840 {
841 UserPtr user = ClientManager::getInstance()->findUser(CID(cid));
842 ConnectionManager::getInstance()->force(user);
843 }
844 }
845
closeConnection_client(string cid,bool download)846 void Transfers::closeConnection_client(string cid, bool download)
847 {
848 if (!cid.empty())
849 {
850 UserPtr user = ClientManager::getInstance()->findUser(CID(cid));
851 ConnectionManager::getInstance()->disconnect(user, download);
852 }
853 }
854
getParams_client(StringMap & params,ConnectionQueueItem * cqi)855 void Transfers::getParams_client(StringMap& params, ConnectionQueueItem* cqi)
856 {
857 // NOTE: const HintedUser& getUser() const { return user; }
858 const HintedUser &user = cqi->getUser();
859
860 params["CID"] = user.user->getCID().toBase32();
861 params["User"] = WulforUtil::getNicks(user);
862 params["Hub Name"] = WulforUtil::getHubNames(user);
863 params["Failed"] = "0";
864 params["Hub URL"] = user.hint;
865 }
866
getParams_client(StringMap & params,Transfer * tr)867 void Transfers::getParams_client(StringMap& params, Transfer* tr)
868 {
869 // NOTE: const HintedUser getHintedUser() const;
870 const HintedUser user = tr->getHintedUser();
871 double percent = 0.0;
872
873 params["CID"] = user.user->getCID().toBase32();
874 if (tr->getType() == Transfer::TYPE_FULL_LIST || tr->getType() == Transfer::TYPE_PARTIAL_LIST)
875 params["Filename"] = _("File list");
876 else if (tr->getType() == Transfer::TYPE_TREE)
877 params["Filename"] = _("TTH: ") + Util::getFileName(tr->getPath());
878 else
879 params["Filename"] = Util::getFileName(tr->getPath());
880 params["User"] = WulforUtil::getNicks(user);
881 params["Hub Name"] = WulforUtil::getHubNames(user);
882 params["Path"] = Util::getFilePath(tr->getPath());
883 params["Size"] = Util::toString(tr->getSize());
884 params["Download Position"] = Util::toString(tr->getPos());
885 params["Speed"] = Util::toString(tr->getAverageSpeed());
886 if (tr->getSize() > 0)
887 percent = static_cast<double>(tr->getPos() * 100.0)/ tr->getSize();
888 params["Progress Hidden"] = Util::toString(static_cast<int>(percent));
889 params["IP"] = tr->getUserConnection().getRemoteIp();
890 params["Time Left"] = tr->getSecondsLeft() > 0 ? Util::toString(tr->getSecondsLeft()) : "-1";
891 params["Target"] = tr->getPath();
892 params["Hub URL"] = tr->getUserConnection().getHubUrl();
893 params["Encryption"] = tr->getUserConnection().isSecure() ? tr->getUserConnection().getCipherName() : _("Plain");
894 }
895
on(DownloadManagerListener::Requesting,Download * dl)896 void Transfers::on(DownloadManagerListener::Requesting, Download* dl) noexcept
897 {
898 StringMap params;
899
900 getParams_client(params, dl);
901
902 params["File Size"] = Util::toString(QueueManager::getInstance()->getSize(dl->getPath()));
903 params["File Position"] = Util::toString(QueueManager::getInstance()->getPos(dl->getPath()));
904 params["Sort Order"] = "w" + params["User"];
905 params["Status"] = _("Requesting");
906 params["Failed"] = "0";
907
908 typedef Func1<Transfers, StringMap> F1;
909 F1* f1 = new F1(this, &Transfers::initTransfer_gui, params);
910 WulforManager::get()->dispatchGuiFunc(f1);
911 }
912
on(DownloadManagerListener::Starting,Download * dl)913 void Transfers::on(DownloadManagerListener::Starting, Download* dl) noexcept
914 {
915 StringMap params;
916
917 getParams_client(params, dl);
918 params["Status"] = _("Download starting...");
919 params["Sort Order"] = "d" + params["User"];
920 params["Failed"] = "0";
921 params["tmpTarget"] = dl->getTempTarget();
922
923 typedef Func3<Transfers, StringMap, bool, Sound::TypeSound> F3;
924 F3* f3 = new F3(this, &Transfers::updateTransfer_gui, params, TRUE, Sound::NONE);
925 WulforManager::get()->dispatchGuiFunc(f3);
926 }
927
on(DownloadManagerListener::Tick,const DownloadList & dls)928 void Transfers::on(DownloadManagerListener::Tick, const DownloadList& dls) noexcept
929 {
930 for (auto it = dls.begin(); it != dls.end(); ++it)
931 {
932 Download* dl = *it;
933 StringMap params;
934 string flags;
935
936 getParams_client(params, *it);
937
938 if (dl->getUserConnection().isSecure())
939 {
940 if (dl->getUserConnection().isTrusted())
941 flags += _("[S]");
942 else
943 flags += _("[U]");
944 }
945 if (dl->isSet(Download::FLAG_TTH_CHECK))
946 flags += _("[T]");
947 if (dl->isSet(Download::FLAG_ZDOWNLOAD))
948 flags += _("[Z]");
949
950 params["Flags"] = flags;
951 params["Transferred"] = Util::formatBytes(dl->getPos());
952 params["Time"] = Util::formatSeconds((GET_TICK() - dl->getStart()) / 1000);
953 params["Progress"] = params["Progress Hidden"] + "%";
954 params["Status"] = _("Downloading");
955
956 typedef Func3<Transfers, StringMap, bool, Sound::TypeSound> F3;
957 F3* f3 = new F3(this, &Transfers::updateTransfer_gui, params, TRUE, Sound::NONE);
958 WulforManager::get()->dispatchGuiFunc(f3);
959 }
960 }
961
on(DownloadManagerListener::Complete,Download * dl)962 void Transfers::on(DownloadManagerListener::Complete, Download* dl) noexcept
963 {
964 StringMap params;
965
966 getParams_client(params, dl);
967 params["Status"] = _("Download complete...");
968 params["Progress Hidden"] = "100";
969 params["Progress"] = "100%";
970 params["Sort Order"] = "w" + params["User"];
971 params["Speed"] = "-1";
972
973 int64_t pos = QueueManager::getInstance()->getPos(dl->getPath()) + dl->getPos();
974
975 typedef Func3<Transfers, StringMap, bool, Sound::TypeSound> F3;
976 F3* f3 = new F3(this, &Transfers::updateTransfer_gui, params, TRUE, Sound::NONE);
977 WulforManager::get()->dispatchGuiFunc(f3);
978
979 typedef Func2<Transfers, const string, int64_t> F2b;
980 F2b* f2b = new F2b(this, &Transfers::updateFilePosition_gui, params["CID"], pos);
981 WulforManager::get()->dispatchGuiFunc(f2b);
982 }
983
on(DownloadManagerListener::Failed,Download * dl,const string & reason)984 void Transfers::on(DownloadManagerListener::Failed, Download* dl, const string& reason) noexcept
985 {
986 onFailed(dl, reason);
987 }
988
on(QueueManagerListener::CRCFailed,Download * dl,const string & reason)989 void Transfers::on(QueueManagerListener::CRCFailed, Download* dl, const string& reason) noexcept
990 {
991 onFailed(dl, reason);
992 }
993
onFailed(Download * dl,const string & reason)994 void Transfers::onFailed(Download* dl, const string& reason) {
995 StringMap params;
996 getParams_client(params, dl);
997 params["Status"] = reason;
998 params["Sort Order"] = "w" + params["User"];
999 params["Failed"] = "1";
1000 params["Speed"] = "-1";
1001 params["Time Left"] = "-1";
1002
1003 int64_t pos = QueueManager::getInstance()->getPos(dl->getPath()) + dl->getPos();
1004
1005 typedef Func3<Transfers, StringMap, bool, Sound::TypeSound> F3;
1006 F3* f3 = new F3(this, &Transfers::updateTransfer_gui, params, TRUE, Sound::NONE);
1007 WulforManager::get()->dispatchGuiFunc(f3);
1008
1009 typedef Func2<Transfers, const string, int64_t> F2b;
1010 F2b* f2b = new F2b(this, &Transfers::updateFilePosition_gui, params["CID"], pos);
1011 WulforManager::get()->dispatchGuiFunc(f2b);
1012 }
1013
on(ConnectionManagerListener::Added,ConnectionQueueItem * cqi)1014 void Transfers::on(ConnectionManagerListener::Added, ConnectionQueueItem* cqi) noexcept
1015 {
1016 StringMap params;
1017 getParams_client(params, cqi);
1018 params["Status"] = _("Connecting...");
1019
1020 typedef Func2<Transfers, StringMap, bool> F2;
1021 F2* f2 = new F2(this, &Transfers::addConnection_gui, params, cqi->getDownload());
1022 WulforManager::get()->dispatchGuiFunc(f2);
1023 }
1024
on(ConnectionManagerListener::Connected,ConnectionQueueItem * cqi)1025 void Transfers::on(ConnectionManagerListener::Connected, ConnectionQueueItem* cqi) noexcept
1026 {
1027 StringMap params;
1028 getParams_client(params, cqi);
1029 params["Status"] = _("Connected");
1030
1031 typedef Func3<Transfers, StringMap, bool, Sound::TypeSound> F3;
1032 F3* f3 = new F3(this, &Transfers::updateTransfer_gui, params, cqi->getDownload(), Sound::NONE);
1033 WulforManager::get()->dispatchGuiFunc(f3);
1034 }
1035
on(ConnectionManagerListener::Removed,ConnectionQueueItem * cqi)1036 void Transfers::on(ConnectionManagerListener::Removed, ConnectionQueueItem* cqi) noexcept
1037 {
1038 string cid = cqi->getUser().user->getCID().toBase32();
1039 typedef Func2<Transfers, const string, bool> F2;
1040 F2* f2 = new F2(this, &Transfers::removeConnection_gui, cid, cqi->getDownload());
1041 WulforManager::get()->dispatchGuiFunc(f2);
1042 }
1043
on(ConnectionManagerListener::Failed,ConnectionQueueItem * cqi,const string & reason)1044 void Transfers::on(ConnectionManagerListener::Failed, ConnectionQueueItem* cqi, const string& reason) noexcept
1045 {
1046 StringMap params;
1047 getParams_client(params, cqi);
1048 params["Status"] = reason;
1049 params["Failed"] = "1";
1050 params["Sort Order"] = "w" + params["User"];
1051 params["Speed"] = "-1";
1052 params["Time Left"] = "-1";
1053
1054 typedef Func3<Transfers, StringMap, bool, Sound::TypeSound> F3;
1055 F3* f3 = new F3(this, &Transfers::updateTransfer_gui, params, cqi->getDownload(), Sound::NONE);
1056 WulforManager::get()->dispatchGuiFunc(f3);
1057 }
1058
on(ConnectionManagerListener::StatusChanged,ConnectionQueueItem * cqi)1059 void Transfers::on(ConnectionManagerListener::StatusChanged, ConnectionQueueItem* cqi) noexcept
1060 {
1061 StringMap params;
1062 getParams_client(params, cqi);
1063
1064 if (cqi->getState() == ConnectionQueueItem::CONNECTING)
1065 params["Status"] = _("Connecting");
1066 else
1067 params["Status"] = _("Waiting to retry");
1068 params["Sort Order"] = "w" + params["User"];
1069
1070 typedef Func3<Transfers, StringMap, bool, Sound::TypeSound> F3;
1071 F3* f3 = new F3(this, &Transfers::updateTransfer_gui, params, cqi->getDownload(), Sound::NONE);
1072 WulforManager::get()->dispatchGuiFunc(f3);
1073 }
1074
on(QueueManagerListener::Finished,QueueItem * qi,const string & dir,int64_t size)1075 void Transfers::on(QueueManagerListener::Finished, QueueItem* qi, const string& dir, int64_t size) noexcept
1076 {
1077 string target = qi->getTarget();
1078 Sound::TypeSound sound = Sound::DOWNLOAD_FINISHED;
1079
1080 if (qi->isSet(QueueItem::FLAG_CLIENT_VIEW | QueueItem::FLAG_USER_LIST))
1081 {
1082 sound = Sound::DOWNLOAD_FINISHED_USER_LIST;
1083 }
1084 else if (qi->isSet(QueueItem::FLAG_XML_BZLIST))
1085 {
1086 sound = Sound::NONE;
1087 }
1088
1089 typedef Func3<Transfers, const string, const string, Sound::TypeSound> F3;
1090 F3* f3 = new F3(this, &Transfers::finishParent_gui, target, _("Download finished"), sound);
1091 WulforManager::get()->dispatchGuiFunc(f3);
1092 }
1093
on(QueueManagerListener::Removed,QueueItem * qi)1094 void Transfers::on(QueueManagerListener::Removed, QueueItem* qi) noexcept
1095 {
1096 string target = qi->getTarget();
1097
1098 typedef Func3<Transfers, const string, const string, Sound::TypeSound> F3;
1099 F3* f3 = new F3(this, &Transfers::finishParent_gui, target, _("Download removed"), Sound::NONE);
1100 WulforManager::get()->dispatchGuiFunc(f3);
1101 }
1102
on(UploadManagerListener::Starting,Upload * ul)1103 void Transfers::on(UploadManagerListener::Starting, Upload* ul) noexcept
1104 {
1105 StringMap params;
1106
1107 getParams_client(params, ul);
1108 params["Status"] = _("Upload starting...");
1109 params["Sort Order"] = "u" + params["User"];
1110 params["Failed"] = "0";
1111 params["tmpTarget"] = _("none"); //fix open 'tmp' file
1112
1113 typedef Func3<Transfers, StringMap, bool, Sound::TypeSound> F3;
1114 F3* f3 = new F3(this, &Transfers::updateTransfer_gui, params, FALSE, Sound::NONE);
1115 WulforManager::get()->dispatchGuiFunc(f3);
1116 }
1117
on(UploadManagerListener::Tick,const UploadList & uls)1118 void Transfers::on(UploadManagerListener::Tick, const UploadList& uls) noexcept
1119 {
1120 for (auto it = uls.begin(); it != uls.end(); ++it)
1121 {
1122 Upload* ul = *it;
1123 StringMap params;
1124 string flags;
1125
1126 getParams_client(params, ul);
1127
1128 if (ul->getUserConnection().isSecure())
1129 {
1130 if (ul->getUserConnection().isTrusted())
1131 flags += _("[S]");
1132 else
1133 flags += _("[U]");
1134 }
1135 if (ul->isSet(Upload::FLAG_ZUPLOAD))
1136 flags += _("[Z]");
1137
1138 params["Flags"] = flags;
1139 params["Transferred"] = Util::formatBytes(ul->getPos());
1140 params["Time"] = Util::formatSeconds((GET_TICK() - ul->getStart()) / 1000);
1141 params["Progress"] = params["Progress Hidden"] + "%";
1142 params["Status"] = _("Uploading");
1143
1144 typedef Func3<Transfers, StringMap, bool, Sound::TypeSound> F3;
1145 F3* f3 = new F3(this, &Transfers::updateTransfer_gui, params, FALSE, Sound::NONE);
1146 WulforManager::get()->dispatchGuiFunc(f3);
1147 }
1148 }
1149
on(UploadManagerListener::Complete,Upload * ul)1150 void Transfers::on(UploadManagerListener::Complete, Upload* ul) noexcept
1151 {
1152 StringMap params;
1153
1154 getParams_client(params, ul);
1155 params["Status"] = _("Upload complete...");
1156 params["Progress Hidden"] = "100";
1157 params["Progress"] = "100%";
1158 params["Sort Order"] = "w" + params["User"];
1159 params["Speed"] = "-1";
1160
1161 typedef Func3<Transfers, StringMap, bool, Sound::TypeSound> F3;
1162 F3* f3 = new F3(this, &Transfers::updateTransfer_gui, params, FALSE, Sound::UPLOAD_FINISHED);
1163 WulforManager::get()->dispatchGuiFunc(f3);
1164 }
1165
on(UploadManagerListener::Failed,Upload * ul,const string & reason)1166 void Transfers::on(UploadManagerListener::Failed, Upload* ul, const string& reason) noexcept
1167 {
1168 StringMap params;
1169 getParams_client(params, ul);
1170 params["Status"] = reason;
1171 params["Sort Order"] = "w" + params["User"];
1172 params["Failed"] = "1";
1173 params["Speed"] = "-1";
1174 params["Time Left"] = "-1";
1175
1176 typedef Func3<Transfers, StringMap, bool, Sound::TypeSound> F3;
1177 F3* f3 = new F3(this, &Transfers::updateTransfer_gui, params, FALSE, Sound::NONE);
1178 WulforManager::get()->dispatchGuiFunc(f3);
1179 }
1180