1 /***************************************************************************
2 *                                                                         *
3 *   This program is free software; you can redistribute it and/or modify  *
4 *   it under the terms of the GNU General Public License as published by  *
5 *   the Free Software Foundation; either version 3 of the License, or     *
6 *   (at your option) any later version.                                   *
7 *                                                                         *
8 ***************************************************************************/
9 
10 #include "TransferView.h"
11 #include "TransferViewModel.h"
12 #include "WulforUtil.h"
13 #include "WulforSettings.h"
14 #include "HubFrame.h"
15 #include "HubManager.h"
16 #include "Notification.h"
17 #include "SearchFrame.h"
18 #include "DownloadQueue.h"
19 #include "IPFilter.h"
20 #include "ArenaWidgetFactory.h"
21 
22 #include "dcpp/Util.h"
23 #include "dcpp/User.h"
24 #include "dcpp/CID.h"
25 #include "dcpp/Transfer.h"
26 #include "dcpp/Download.h"
27 #include "dcpp/QueueItem.h"
28 #include "dcpp/Upload.h"
29 #include "dcpp/ClientManager.h"
30 #include "dcpp/QueueManager.h"
31 #include "dcpp/FavoriteManager.h"
32 #include "dcpp/HashManager.h"
33 
34 #include <QItemSelectionModel>
35 #include <QModelIndex>
36 #include <QClipboard>
37 #include <QMessageBox>
38 #include <QFileInfo>
39 #include <QDir>
40 
Menu()41 TransferView::Menu::Menu():
42         menu(NULL),
43         selectedColumn(0)
44 {
45     WulforUtil *WU = WulforUtil::getInstance();
46     menu = new QMenu();
47 
48     QAction *browse     = new QAction(tr("Browse files"), menu);
49     browse->setIcon(WU->getPixmap(WulforUtil::eiFOLDER_BLUE));
50 
51     QAction *search     = new QAction(tr("Search Alternates"), menu);
52     search->setIcon(WU->getPixmap(WulforUtil::eiFIND));
53 
54     QAction *match      = new QAction(tr("Match Queue"), menu);
55     match->setIcon(WU->getPixmap(WulforUtil::eiDOWN));
56 
57     QAction *send_pm    = new QAction(tr("Send Private Message"), menu);
58     send_pm->setIcon(WU->getPixmap(WulforUtil::eiMESSAGE));
59 
60     QAction *add_to_fav = new QAction(tr("Add to favorites"), menu);
61     add_to_fav->setIcon(WU->getPixmap(WulforUtil::eiBOOKMARK_ADD));
62 
63     QAction *grant      = new QAction(tr("Grant extra slot"), menu);
64     grant->setIcon(WU->getPixmap(WulforUtil::eiEDITADD));
65 
66     copy_column = new QMenu(tr("Copy"), menu);
67     copy_column->setIcon(WU->getPixmap(WulforUtil::eiEDITCOPY));
68 
69     copy_column->addAction(tr("Users"));
70     copy_column->addAction(tr("Speed"));
71     copy_column->addAction(tr("Status"));
72     copy_column->addAction(tr("Flags"));
73     copy_column->addAction(tr("Size"));
74     copy_column->addAction(tr("Time left"));
75     copy_column->addAction(tr("Filename"));
76     copy_column->addAction(tr("Hub"));
77     copy_column->addAction(tr("IP"));
78     copy_column->addAction(tr("Encryption"));
79     copy_column->addAction(tr("Magnet"));
80 
81     QAction *sep1        = new QAction(menu);
82     sep1->setSeparator(true);
83 
84     QAction *rem_queue  = new QAction(tr("Remove Source"), menu);
85     rem_queue->setIcon(WU->getPixmap(WulforUtil::eiEDITDELETE));
86 
87     QAction *sep3       = new QAction(menu);
88     sep3->setSeparator(true);
89 
90     QAction *force    = new QAction(tr("Force attempt"), menu);
91     force->setIcon(WU->getPixmap(WulforUtil::eiCONNECT));
92 
93     QAction *close = new QAction(tr("Close connection(s)"), menu);
94     close->setIcon(WU->getPixmap(WulforUtil::eiCONNECT_NO));
95 
96     actions.insert(browse, Browse);
97     actions.insert(match, MatchQueue);
98     actions.insert(send_pm, SendPM);
99     actions.insert(add_to_fav, AddToFav);
100     actions.insert(grant, GrantExtraSlot);
101     actions.insert(rem_queue, RemoveFromQueue);
102     actions.insert(force, Force);
103     actions.insert(close, Close);
104     actions.insert(search, SearchAlternates);
105 
106     menu->addActions(QList<QAction*>() << browse
107                                        << search
108                                        << match
109                                        << send_pm
110                                        << add_to_fav
111                                        << grant);
112     menu->addMenu(copy_column);
113     menu->addActions(QList<QAction*>() << sep1
114                                        << rem_queue
115                                        << sep3
116                                        << force
117                                        << close
118                                        );
119 }
120 
~Menu()121 TransferView::Menu::~Menu(){
122     menu->deleteLater();
123     copy_column->deleteLater();
124 }
125 
exec()126 TransferView::Menu::Action TransferView::Menu::exec(){
127     QAction *ret = menu->exec(QCursor::pos());
128 
129     if (actions.contains(ret))
130         return actions.value(ret);
131     else if (ret){
132         selectedColumn = copy_column->actions().indexOf(ret);
133 
134         return Copy;
135     }
136 
137     return None;
138 }
139 
TransferView(QWidget * parent)140 TransferView::TransferView(QWidget *parent):
141         QWidget(parent),
142         model(NULL)
143 {
144     setupUi(this);
145 
146     init();
147 
148     QueueManager::getInstance()->addListener(this);
149     DownloadManager::getInstance()->addListener(this);
150     UploadManager::getInstance()->addListener(this);
151     ConnectionManager::getInstance()->addListener(this);
152 }
153 
~TransferView()154 TransferView::~TransferView(){
155     QueueManager::getInstance()->removeListener(this);
156     DownloadManager::getInstance()->removeListener(this);
157     UploadManager::getInstance()->removeListener(this);
158     ConnectionManager::getInstance()->removeListener(this);
159 
160     delete model;
161 }
162 
closeEvent(QCloseEvent * e)163 void TransferView::closeEvent(QCloseEvent *e){
164     save();
165 
166     e->accept();
167 }
168 
resizeEvent(QResizeEvent * e)169 void TransferView::resizeEvent(QResizeEvent *e){
170     e->accept();
171 
172     if (isVisible())
173         WISET(WI_TRANSFER_HEIGHT, height());
174 }
175 
hideEvent(QHideEvent * e)176 void TransferView::hideEvent(QHideEvent *e){
177     save();
178 
179     WISET(WI_TRANSFER_HEIGHT, height());
180 
181     e->accept();
182 }
183 
save()184 void TransferView::save(){
185     WSSET(WS_TRANSFERS_STATE, treeView_TRANSFERS->header()->saveState().toBase64());
186 }
187 
load()188 void TransferView::load(){
189     int h = WIGET(WI_TRANSFER_HEIGHT);
190 
191     if (h >= 0)
192         resize(this->width(), h);
193 
194     treeView_TRANSFERS->header()->restoreState(QByteArray::fromBase64(WSGET(WS_TRANSFERS_STATE).toUtf8()));
195 }
196 
sizeHint() const197 QSize TransferView::sizeHint() const{
198     int h = WIGET(WI_TRANSFER_HEIGHT);
199 
200     if (h > 0)
201         return QSize(300, h);
202 
203     return QSize(300, 250);
204 }
205 
init()206 void TransferView::init(){
207     setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
208 
209     model = new TransferViewModel();
210 
211     treeView_TRANSFERS->setModel(model);
212     treeView_TRANSFERS->setItemDelegate(new TransferViewDelegate(this));
213     treeView_TRANSFERS->setContextMenuPolicy(Qt::CustomContextMenu);
214     treeView_TRANSFERS->header()->setContextMenuPolicy(Qt::CustomContextMenu);
215 
216     connect(treeView_TRANSFERS, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(slotContextMenu(QPoint)));
217     connect(treeView_TRANSFERS->header(), SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(slotHeaderMenu(QPoint)));
218 
219     connect(this, SIGNAL(coreDMRequesting(VarMap)),     model, SLOT(initTransfer(VarMap)), Qt::QueuedConnection);
220     connect(this, SIGNAL(coreDMStarting(VarMap)),       model, SLOT(updateTransfer(VarMap)), Qt::QueuedConnection);
221     connect(this, SIGNAL(coreDMTick(VarMap)),           model, SLOT(updateTransfer(VarMap)), Qt::QueuedConnection);
222     connect(this, SIGNAL(coreUpdateParents()),          model, SLOT(updateParents()), Qt::QueuedConnection);
223     connect(this, SIGNAL(coreUpdateParents()),          model, SLOT(sort()), Qt::QueuedConnection);
224     connect(this, SIGNAL(coreDMComplete(VarMap)),       model, SLOT(updateTransfer(VarMap)), Qt::QueuedConnection);
225     connect(this, SIGNAL(coreUpdateTransferPosition(VarMap,qint64)), model, SLOT(updateTransferPos(VarMap,qint64)), Qt::QueuedConnection);
226     connect(this, SIGNAL(coreDMFailed(VarMap)),         model, SLOT(updateTransfer(VarMap)), Qt::QueuedConnection);
227     connect(this, SIGNAL(coreCMAdded(VarMap)),          model, SLOT(addConnection(VarMap)));
228     connect(this, SIGNAL(coreCMConnected(VarMap)),      model, SLOT(updateTransfer(VarMap)), Qt::QueuedConnection);
229     connect(this, SIGNAL(coreCMRemoved(VarMap)),        model, SLOT(removeTransfer(VarMap)), Qt::QueuedConnection);
230     connect(this, SIGNAL(coreCMFailed(VarMap)),         model, SLOT(updateTransfer(VarMap)), Qt::QueuedConnection);
231     connect(this, SIGNAL(coreCMStatusChanged(VarMap)),  model, SLOT(updateTransfer(VarMap)), Qt::QueuedConnection);
232     connect(this, SIGNAL(coreQMFinished(VarMap)),       model, SLOT(finishParent(VarMap)), Qt::QueuedConnection);
233     connect(this, SIGNAL(coreQMRemoved(VarMap)),        model, SLOT(finishParent(VarMap)), Qt::QueuedConnection);
234     connect(this, SIGNAL(coreDownloadComplete(QString)), this, SLOT(downloadComplete(QString)), Qt::QueuedConnection);
235     connect(this, SIGNAL(coreUMStarting(VarMap)),       model, SLOT(updateTransfer(VarMap)), Qt::QueuedConnection);
236     connect(this, SIGNAL(coreUMTick(VarMap)),           model, SLOT(updateTransfer(VarMap)), Qt::QueuedConnection);
237     connect(this, SIGNAL(coreUMComplete(VarMap)),       model, SLOT(updateTransfer(VarMap)), Qt::QueuedConnection);
238     connect(this, SIGNAL(coreUMFailed(VarMap)),         model, SLOT(updateTransfer(VarMap)), Qt::QueuedConnection);
239 
240     load();
241 }
242 
getFileList(const QString & cid,const QString & host)243 void TransferView::getFileList(const QString &cid, const QString &host){
244     if (cid.isEmpty() || host.isEmpty())
245         return;
246 
247     try{
248         dcpp::UserPtr user = ClientManager::getInstance()->getUser(CID(_tq(cid)));
249 
250         if (user)
251             QueueManager::getInstance()->addList(HintedUser(user, _tq(host)), QueueItem::FLAG_CLIENT_VIEW, "");
252     }
253     catch (const Exception&){}
254 }
255 
matchQueue(const QString & cid,const QString & host)256 void TransferView::matchQueue(const QString &cid, const QString &host){
257     if (cid.isEmpty() || host.isEmpty())
258         return;
259 
260     try{
261         dcpp::UserPtr user = ClientManager::getInstance()->getUser(CID(_tq(cid)));
262 
263         if (user)
264             QueueManager::getInstance()->addList(HintedUser(user, _tq(host)), QueueItem::FLAG_MATCH_QUEUE, "");
265     }
266     catch (const Exception&){}
267 }
268 
addFavorite(const QString & cid)269 void TransferView::addFavorite(const QString &cid){
270     if (cid.isEmpty())
271         return;
272 
273     try{
274         dcpp::UserPtr user = ClientManager::getInstance()->getUser(CID(_tq(cid)));
275 
276         if (user)
277             FavoriteManager::getInstance()->addFavoriteUser(user);
278     }
279     catch (const Exception&){}
280 }
281 
grantSlot(const QString & cid,const QString & host)282 void TransferView::grantSlot(const QString &cid, const QString &host){
283     if (cid.isEmpty() || host.isEmpty())
284         return;
285 
286     try{
287         dcpp::UserPtr user = ClientManager::getInstance()->getUser(CID(_tq(cid)));
288 
289         if (user)
290             UploadManager::getInstance()->reserveSlot(HintedUser(user, _tq(host)));
291     }
292     catch (const Exception&){}
293 }
294 
removeFromQueue(const QString & cid)295 void TransferView::removeFromQueue(const QString &cid){
296     if (cid.isEmpty())
297         return;
298 
299     try{
300         dcpp::UserPtr user = ClientManager::getInstance()->getUser(CID(_tq(cid)));
301 
302         if (user)
303             QueueManager::getInstance()->removeSource(user, QueueItem::Source::FLAG_REMOVED);
304     }
305     catch (const Exception&){}
306 }
307 
forceAttempt(const QString & cid)308 void TransferView::forceAttempt(const QString &cid){
309     if (cid.isEmpty())
310         return;
311 
312     try{
313         dcpp::UserPtr user = ClientManager::getInstance()->getUser(CID(_tq(cid)));
314 
315         if (user)
316             ConnectionManager::getInstance()->force(user);
317     }
318     catch (const Exception&){}
319 }
320 
closeConection(const QString & cid,bool download)321 void TransferView::closeConection(const QString &cid, bool download){
322     if (cid.isEmpty())
323         return;
324 
325     try{
326         dcpp::UserPtr user = ClientManager::getInstance()->getUser(CID(_tq(cid)));
327 
328         if (user)
329             ConnectionManager::getInstance()->disconnect(user, download);
330     }
331     catch (const Exception&){}
332 }
333 
searchAlternates(const QString & tth)334 void TransferView::searchAlternates(const QString &tth){
335     if (tth.isEmpty())
336         return;
337 
338     SearchFrame *sfr = ArenaWidgetFactory().create<SearchFrame>();
339     sfr->searchAlternates(tth);
340 }
341 
downloadComplete(QString target)342 void TransferView::downloadComplete(QString target){
343     Notification::getInstance()->showMessage(Notification::TRANSFER, tr("Download complete"), target);
344 }
345 
getTTHFromItem(const TransferViewItem * item)346 QString TransferView::getTTHFromItem(const TransferViewItem *item){
347     QString tth_str = "";
348 
349     if (item->download)
350         tth_str = item->tth;
351     else {
352         const TTHValue *tth = dcpp::HashManager::getInstance()->getFileTTHif(_tq(item->target));
353 
354         if (tth)
355             tth_str = _q(tth->toBase32());
356     }
357 
358     return tth_str;
359 }
360 
getParams(TransferView::VarMap & params,const dcpp::ConnectionQueueItem * item)361 void TransferView::getParams(TransferView::VarMap &params, const dcpp::ConnectionQueueItem *item){
362     const dcpp::UserPtr &user = item->getUser();
363     WulforUtil *WU = WulforUtil::getInstance();
364 
365     params["CID"]   = _q(user->getCID().toBase32());
366     params["USER"]  = WU->getNicks(user->getCID());
367     params["HUB"]   = WU->getHubNames(user);
368     params["FAIL"]  = false;
369     params["HOST"]  = _q(item->getUser().hint);
370     params["DOWN"]  = item->getDownload();
371 }
372 
getParams(TransferView::VarMap & params,const dcpp::Transfer * trf)373 void TransferView::getParams(TransferView::VarMap &params, const dcpp::Transfer *trf){
374     const UserPtr& user = trf->getUser();
375     WulforUtil *WU = WulforUtil::getInstance();
376     double percent = 0.0;
377 
378     params["CID"]   = _q(user->getCID().toBase32());
379 
380     if (trf->getType() == Transfer::TYPE_PARTIAL_LIST || trf->getType() == Transfer::TYPE_FULL_LIST)
381         params["FNAME"] = tr("File list");
382     else if (trf->getType() == Transfer::TYPE_TREE)
383         params["FNAME"] = tr("TTH: ") + _q(Util::getFileName(trf->getPath()));
384     else
385         params["FNAME"] = _q(Util::getFileName(trf->getPath()));
386 
387     QString nick = WU->getNicks(user->getCID());
388 
389     if (!nick.isEmpty())//Do not update user nick if user is offline
390         params["USER"]  = nick;
391 
392     params["HUB"]   = WU->getHubNames(user);
393     params["PATH"]  = _q(Util::getFilePath(trf->getPath()));
394     params["ESIZE"] = (qlonglong)trf->getSize();
395     params["DPOS"]  = (qlonglong)trf->getPos();
396     params["SPEED"] = trf->getAverageSpeed();
397 
398     if (trf->getSize() > 0)
399         percent = static_cast<double>(trf->getPos() * 100.0)/ trf->getSize();
400 
401     params["IP"]    = _q(trf->getUserConnection().getRemoteIp());
402     params["TLEFT"] = qlonglong(trf->getSecondsLeft() > 0 ? trf->getSecondsLeft() : -1);
403     params["TARGET"]= _q(trf->getPath());
404     params["HOST"]  = _q(trf->getUserConnection().getHubUrl());
405     params["PERC"]  = percent;
406     params["DOWN"]  = true;
407     params["TTH"] = _q(trf->getTTH().toBase32());
408     if (trf->getUserConnection().isSecure())
409     {
410         params["ENCRYPTION"] = _q(trf->getUserConnection().getCipherName());
411     }
412     else
413     {
414         params["ENCRYPTION"] = _q("Plain");
415     }
416 }
417 
slotContextMenu(const QPoint &)418 void TransferView::slotContextMenu(const QPoint &){
419     QItemSelectionModel *selection_model = treeView_TRANSFERS->selectionModel();
420     QModelIndexList list = selection_model->selectedRows(0);
421 
422     if (list.size() < 1)
423         return;
424 
425     Menu::Action act;
426     Menu m;
427 
428     act = m.exec();
429 
430 
431     list = selection_model->selectedRows(0);
432 
433     if (list.size() < 1)
434         return;
435 
436     QList<TransferViewItem*> items;
437 
438     for (const auto &index : list){
439         TransferViewItem *i = reinterpret_cast<TransferViewItem*>(index.internalPointer());
440 
441         if (i->childCount() > 0){
442             for (const auto &child : i->childItems)
443                 items.append(child);
444         }
445         else if (!items.contains(i))
446             items.append(i);
447     }
448 
449     if (items.size() < 1)
450         return;
451 
452     switch (act){
453 
454     case Menu::None:
455     {
456         break;
457     }
458     case Menu::Browse:
459     {
460         for (const auto &i : items)
461             getFileList(i->cid, vstr(i->data(COLUMN_TRANSFER_HOST)));
462 
463         break;
464     }
465     case Menu::SearchAlternates:
466     {
467         QStringList tths;
468         QString tth_str = "";
469         for (const auto &item : items) {
470             tth_str = getTTHFromItem(item);
471             if (!tth_str.isEmpty() && !tths.contains(tth_str)){
472                 tths.push_back(tth_str);
473                 searchAlternates(tth_str);
474             }
475         }
476 
477         break;
478     }
479     case Menu::MatchQueue:
480     {
481         for (const auto &i : items)
482             matchQueue(i->cid, vstr(i->data(COLUMN_TRANSFER_HOST)));
483 
484         break;
485     }
486     case Menu::AddToFav:
487     {
488         for (const auto &i : items)
489             addFavorite(i->cid);
490 
491         break;
492     }
493     case Menu::GrantExtraSlot:
494     {
495         for (const auto &i : items)
496             grantSlot(i->cid, vstr(i->data(COLUMN_TRANSFER_HOST)));
497 
498         break;
499     }
500     case Menu::Copy:
501     {
502         int col = m.copyColumn();
503         QString data = "";
504 
505         if (col <= (model->columnCount()-1)){
506             for (const auto &i : items)
507                 data += i->data(col).toString() + "\n";
508         }
509         else {
510             QString tth_str = "";
511             for (const auto &i : items){
512                 QFileInfo fi(i->target);
513                 tth_str = getTTHFromItem(i);
514 
515                 if (tth_str.isEmpty()) {
516                     QString str = QDir::toNativeSeparators(fi.canonicalFilePath() ); // try to follow symlinks
517                     const TTHValue *tth = HashManager::getInstance()->getFileTTHif(str.toStdString());
518 
519                     if (tth)
520                         tth_str = _q(tth->toBase32());
521                 }
522 
523                 if (!tth_str.isEmpty())
524                     data += WulforUtil::getInstance()->makeMagnet(fi.fileName(), fi.size(), tth_str) + "\n";
525             }
526         }
527 
528         if (!data.isEmpty())
529             qApp->clipboard()->setText(data, QClipboard::Clipboard);
530 
531         break;
532     }
533     case Menu::RemoveFromQueue:
534     {
535         for (const auto &i : items)
536             removeFromQueue(i->cid);
537 
538         break;
539     }
540     case Menu::Force:
541     {
542         for (const auto &i : items)
543             forceAttempt(i->cid);
544 
545         break;
546     }
547     case Menu::Close:
548     {
549         for (const auto &i : items)
550             closeConection(i->cid, i->download);
551 
552         break;
553     }
554     case Menu::SendPM:
555     {
556         HubFrame *fr = NULL;
557 
558         for (const auto &i : items){
559             dcpp::CID cid(_tq(i->cid));
560             QString hubUrl = i->data(COLUMN_TRANSFER_HOST).toString();
561 
562             fr = qobject_cast<HubFrame*>(HubManager::getInstance()->getHub(hubUrl));
563 
564             if (fr)
565                 fr->createPMWindow(cid);
566         }
567 
568         break;
569     }
570     default:
571         break;
572     }
573 }
574 
slotHeaderMenu(const QPoint &)575 void TransferView::slotHeaderMenu(const QPoint &){
576     WulforUtil::headerMenu(treeView_TRANSFERS);
577 }
578 
on(dcpp::DownloadManagerListener::Requesting,dcpp::Download * dl)579 void TransferView::on(dcpp::DownloadManagerListener::Requesting, dcpp::Download* dl) noexcept{
580     VarMap params;
581 
582     getParams(params, dl);
583 
584     if (IPFilter::getInstance()){
585         if (!IPFilter::getInstance()->OK(vstr(params["IP"]), eDIRECTION_IN)){
586             closeConection(vstr(params["CID"]), true);
587             return;
588         }
589     }
590 
591     params["ESIZE"] = (qlonglong)QueueManager::getInstance()->getSize(dl->getPath());
592     params["FPOS"]  = (qlonglong)QueueManager::getInstance()->getPos(dl->getPath());
593     params["STAT"]  = tr("Requesting");
594     params["FAIL"]  = false;
595 
596     emit coreDMRequesting(params);
597 }
598 
on(dcpp::DownloadManagerListener::Starting,dcpp::Download * dl)599 void TransferView::on(dcpp::DownloadManagerListener::Starting, dcpp::Download* dl) noexcept{
600     VarMap params;
601 
602     getParams(params, dl);
603 
604     params["STAT"] = tr("Download starting...");
605     params["FPOS"]  = (qlonglong)QueueManager::getInstance()->getPos(dl->getPath());
606 
607     emit coreDMStarting(params);
608 }
609 
on(dcpp::DownloadManagerListener::Tick,const dcpp::DownloadList & dls)610 void TransferView::on(dcpp::DownloadManagerListener::Tick, const dcpp::DownloadList& dls) noexcept{
611     for (const auto &it : dls){
612         Download* dl = it;
613         VarMap params;
614         QString str;
615 
616         getParams(params, dl);
617         params["FPOS"]  = (qlonglong)QueueManager::getInstance()->getPos(dl->getPath());
618 
619         if (dl->getUserConnection().isSecure())
620         {
621             if (dl->getUserConnection().isTrusted())
622                str += tr("[S]");
623             else
624                str += tr("[U]");
625         }
626 
627         if (dl->isSet(Download::FLAG_TTH_CHECK))
628             str += tr("[T]");
629         if (dl->isSet(Download::FLAG_ZDOWNLOAD))
630             str += tr("[Z]");
631 
632         params["FLAGS"] = str;
633 
634         str = QString(tr("Downloaded %1")).arg(WulforUtil::formatBytes(dl->getPos()))
635             + QString(tr(" (%1%)")).arg(vdbl(params["PERC"]), 0, 'f', 1);
636 
637         params["STAT"] = str;
638 
639         emit coreDMTick(params);
640     }
641 
642     emit coreUpdateParents();
643 }
644 
on(dcpp::DownloadManagerListener::Complete,dcpp::Download * dl)645 void TransferView::on(dcpp::DownloadManagerListener::Complete, dcpp::Download* dl) noexcept{
646     VarMap params;
647 
648     getParams(params, dl);
649 
650     params["STAT"]  = tr("Download complete");
651     params["SPEED"] = 0;
652 
653     qint64 pos = QueueManager::getInstance()->getPos(dl->getPath()) + dl->getPos();
654 
655     emit coreDMComplete(params);
656     emit coreUpdateTransferPosition(params, pos);
657 }
658 
on(dcpp::DownloadManagerListener::Failed,dcpp::Download * dl,const std::string & reason)659 void TransferView::on(dcpp::DownloadManagerListener::Failed, dcpp::Download* dl, const std::string& reason) noexcept {
660     onFailed(dl, reason);
661 }
662 
on(dcpp::QueueManagerListener::CRCFailed,dcpp::Download * dl,const std::string & reason)663 void TransferView::on(dcpp::QueueManagerListener::CRCFailed, dcpp::Download* dl, const std::string& reason) noexcept {
664     onFailed(dl, reason);
665 }
666 
onFailed(dcpp::Download * dl,const std::string & reason)667 void TransferView::onFailed(dcpp::Download* dl, const std::string& reason) {
668     VarMap params;
669 
670     getParams(params, dl);
671 
672     params["STAT"]  = _q(reason);
673     params["SPEED"] = 0;
674     params["FAIL"]  = true;
675     params["TLEFT"] = -1;
676 
677     qint64 pos = QueueManager::getInstance()->getPos(dl->getPath()) + dl->getPos();
678 
679     emit coreDMFailed(params);
680     emit coreUpdateTransferPosition(params, pos);
681 }
682 
on(dcpp::ConnectionManagerListener::Added,dcpp::ConnectionQueueItem * cqi)683 void TransferView::on(dcpp::ConnectionManagerListener::Added, dcpp::ConnectionQueueItem* cqi) noexcept{
684     VarMap params;
685 
686     getParams(params, cqi);
687 
688     params["FNAME"] = "";
689     params["STAT"] = tr("Connecting...");
690 
691     if(cqi->getDownload()) {
692         string aTarget; int64_t aSize; int aFlags = 0;
693         if(QueueManager::getInstance()->getQueueInfo(cqi->getUser(), aTarget, aSize, aFlags)) {
694             params["TARGET"] = _q(aTarget);
695             params["ESIZE"] = (qlonglong)aSize;
696 
697             if (!aFlags)
698                 params["FNAME"] = _q(Util::getFileName(aTarget));
699 
700             params["BGROUP"] = !aFlags;
701         }
702     }
703 
704     emit coreCMAdded(params);
705 }
706 
on(dcpp::ConnectionManagerListener::Connected,dcpp::ConnectionQueueItem * cqi)707 void TransferView::on(dcpp::ConnectionManagerListener::Connected, dcpp::ConnectionQueueItem* cqi) noexcept{
708 
709     VarMap params;
710 
711     getParams(params, cqi);
712 
713     params["STAT"] = tr("Connected");
714 
715     emit coreCMConnected(params);
716 }
717 
on(dcpp::ConnectionManagerListener::Removed,dcpp::ConnectionQueueItem * cqi)718 void TransferView::on(dcpp::ConnectionManagerListener::Removed, dcpp::ConnectionQueueItem* cqi) noexcept{
719     VarMap params;
720 
721     getParams(params, cqi);
722 
723     emit coreCMRemoved(params);
724 }
725 
on(dcpp::ConnectionManagerListener::Failed,dcpp::ConnectionQueueItem * cqi,const std::string & reason)726 void TransferView::on(dcpp::ConnectionManagerListener::Failed, dcpp::ConnectionQueueItem* cqi, const std::string &reason) noexcept{
727     VarMap params;
728 
729     getParams(params, cqi);
730 
731     params["STAT"] = _q(reason);
732     params["FAIL"] = true;
733     params["SPEED"] = (qlonglong)0;
734     params["TLEFT"] = -1;
735 
736     emit coreCMFailed(params);
737 }
738 
on(dcpp::ConnectionManagerListener::StatusChanged,dcpp::ConnectionQueueItem * cqi)739 void TransferView::on(dcpp::ConnectionManagerListener::StatusChanged, dcpp::ConnectionQueueItem* cqi) noexcept{
740     VarMap params;
741     getParams(params, cqi);
742 
743     if (cqi->getState() == ConnectionQueueItem::CONNECTING)
744         params["STAT"] = tr("Connecting");
745     else if (cqi->getState() == ConnectionQueueItem::NO_DOWNLOAD_SLOTS)
746         params["STAT"] = tr("No download slots");
747     else
748         params["STAT"] = tr("Waiting to retry");
749 
750     emit coreCMStatusChanged(params);
751 }
752 
on(dcpp::QueueManagerListener::Finished,dcpp::QueueItem * qi,const std::string &,int64_t)753 void TransferView::on(dcpp::QueueManagerListener::Finished, dcpp::QueueItem* qi, const std::string&, int64_t) noexcept{
754     VarMap params;
755     params["TARGET"] = _q(qi->getTarget());
756 
757     emit coreQMFinished(params);
758 
759     if (!qi->isSet(QueueItem::FLAG_USER_LIST))//Do not show notify for filelists
760         emit coreDownloadComplete(_q(qi->getTarget()).split(QDir::separator()).last());
761 }
762 
on(dcpp::QueueManagerListener::Removed,dcpp::QueueItem * qi)763 void TransferView::on(dcpp::QueueManagerListener::Removed, dcpp::QueueItem* qi) noexcept{
764     VarMap params;
765     params["TARGET"] = _q(qi->getTarget());
766 
767     emit coreQMRemoved(params);
768 }
769 
on(dcpp::UploadManagerListener::Starting,dcpp::Upload * ul)770 void TransferView::on(dcpp::UploadManagerListener::Starting, dcpp::Upload* ul) noexcept{
771     VarMap params;
772 
773     getParams(params, ul);
774 
775     if (IPFilter::getInstance()){
776         if (!IPFilter::getInstance()->OK(vstr(params["IP"]), eDIRECTION_OUT)){
777             closeConection(vstr(params["CID"]), false);
778             return;
779         }
780     }
781 
782     params["STAT"] = tr("Upload starting...");
783     params["DOWN"] = false;
784     params["FAIL"] = false;
785 
786     emit coreUMStarting(params);
787 }
788 
on(dcpp::UploadManagerListener::Tick,const dcpp::UploadList & uls)789 void TransferView::on(dcpp::UploadManagerListener::Tick, const dcpp::UploadList& uls) noexcept{
790     for (const auto &it : uls){
791         Upload* ul = it;
792         VarMap params;
793         QString stat = "";
794 
795         getParams(params, ul);
796 
797         if (ul->getUserConnection().isSecure())
798         {
799             if (ul->getUserConnection().isTrusted())
800                 stat += tr("[S]");
801             else
802                 stat += tr("[U]");
803         }
804         if (ul->isSet(Upload::FLAG_ZUPLOAD))
805             stat += tr("[Z]");
806 
807         params["FLAGS"] = stat;
808 
809         stat = QString(tr("Uploaded %1 (%2%) ")).arg(WulforUtil::formatBytes(ul->getPos())).arg(vdbl(params["PERC"]), 0, 'f', 1);
810 
811         params["STAT"] = stat;
812         params["DOWN"] = false;
813         params["FAIL"] = false;
814 
815         emit coreUMTick(params);
816     }
817 
818     emit coreUpdateParents();
819 }
820 
on(dcpp::UploadManagerListener::Complete,dcpp::Upload * ul)821 void TransferView::on(dcpp::UploadManagerListener::Complete, dcpp::Upload* ul) noexcept{
822     VarMap params;
823 
824     getParams(params, ul);
825 
826     params["STAT"] = tr("Upload complete");
827     params["DOWN"] = false;
828     params["FAIL"] = false;
829 
830     emit coreUMComplete(params);
831 }
832 
on(dcpp::UploadManagerListener::Failed,dcpp::Upload * ul,const std::string & reason)833 void TransferView::on(dcpp::UploadManagerListener::Failed, dcpp::Upload* ul, const std::string& reason) noexcept{
834     VarMap params;
835 
836     getParams(params, ul);
837 
838     params["STAT"] = tr("Upload failed");
839     params["DOWN"] = false;
840     params["FAIL"] = false;
841 
842     emit coreUMFailed(params);
843 }
844