1 /**************************************************************************
2 * Otter Browser: Web browser controlled by the user, not vice-versa.
3 * Copyright (C) 2013 - 2018 Michal Dutkiewicz aka Emdek <michal@emdek.pl>
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 **************************************************************************/
19
20 #include "TransfersContentsWidget.h"
21 #include "../../../core/ThemesManager.h"
22 #include "../../../core/TransfersManager.h"
23 #include "../../../core/Utils.h"
24 #include "../../../ui/Menu.h"
25 #include "../../../ui/ProgressBarWidget.h"
26
27 #include "ui_TransfersContentsWidget.h"
28
29 #include <QtCore/QDir>
30 #include <QtCore/QFileInfo>
31 #include <QtCore/QtMath>
32 #include <QtGui/QClipboard>
33 #include <QtGui/QKeyEvent>
34 #include <QtWidgets/QApplication>
35 #include <QtWidgets/QMessageBox>
36
37 namespace Otter
38 {
39
ProgressBarDelegate(QObject * parent)40 ProgressBarDelegate::ProgressBarDelegate(QObject *parent) : ItemDelegate(parent)
41 {
42 }
43
setEditorData(QWidget * editor,const QModelIndex & index) const44 void ProgressBarDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
45 {
46 ProgressBarWidget *progressBar(qobject_cast<ProgressBarWidget*>(editor));
47
48 if (progressBar)
49 {
50 const Transfer::TransferState state(static_cast<Transfer::TransferState>(index.data(TransfersContentsWidget::StateRole).toInt()));
51 const bool isIndeterminate(index.data(TransfersContentsWidget::BytesTotalRole).toLongLong() <= 0);
52 const bool hasError(state == Transfer::UnknownState || state == Transfer::ErrorState);
53
54 progressBar->setHasError(hasError);
55 progressBar->setRange(0, ((isIndeterminate && !hasError) ? 0 : 100));
56 progressBar->setValue(isIndeterminate ? (hasError ? 0 : -1) : index.data(TransfersContentsWidget::ProgressRole).toInt());
57 progressBar->setFormat(isIndeterminate ? tr("Unknown") : QLatin1String("%p%"));
58 }
59 }
60
createEditor(QWidget * parent,const QStyleOptionViewItem & option,const QModelIndex & index) const61 QWidget* ProgressBarDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
62 {
63 Q_UNUSED(option)
64
65 ProgressBarWidget *editor(new ProgressBarWidget(parent));
66 editor->setAlignment(Qt::AlignCenter);
67
68 setEditorData(editor, index);
69
70 return editor;
71 }
72
TransfersContentsWidget(const QVariantMap & parameters,Window * window,QWidget * parent)73 TransfersContentsWidget::TransfersContentsWidget(const QVariantMap ¶meters, Window *window, QWidget *parent) : ContentsWidget(parameters, window, parent),
74 m_model(new QStandardItemModel(this)),
75 m_isLoading(false),
76 m_ui(new Ui::TransfersContentsWidget)
77 {
78 m_ui->setupUi(this);
79
80 m_model->setHorizontalHeaderLabels({tr("Status"), tr("Filename"), tr("Size"), tr("Progress"), tr("Time"), tr("Speed"), tr("Started"), tr("Finished")});
81 m_model->setHeaderData(0, Qt::Horizontal, 28, HeaderViewWidget::WidthRole);
82 m_model->setHeaderData(1, Qt::Horizontal, 500, HeaderViewWidget::WidthRole);
83 m_model->setHeaderData(2, Qt::Horizontal, 150, HeaderViewWidget::WidthRole);
84 m_model->setHeaderData(3, Qt::Horizontal, 250, HeaderViewWidget::WidthRole);
85 m_model->setHeaderData(4, Qt::Horizontal, 150, HeaderViewWidget::WidthRole);
86 m_model->setHeaderData(5, Qt::Horizontal, 150, HeaderViewWidget::WidthRole);
87
88 m_ui->transfersViewWidget->setModel(m_model);
89 m_ui->transfersViewWidget->setItemDelegateForColumn(3, new ProgressBarDelegate(this));
90 m_ui->transfersViewWidget->setSortRoleMapping({{0, StateRole}, {2, BytesTotalRole}, {3, ProgressRole}, {6, TimeStartedRole}, {7, TimeFinishedRole}});
91 m_ui->transfersViewWidget->installEventFilter(this);
92 m_ui->stopResumeButton->setIcon(ThemesManager::createIcon(QLatin1String("task-reject")));
93 m_ui->redownloadButton->setIcon(ThemesManager::createIcon(QLatin1String("view-refresh")));
94 m_ui->downloadLineEditWidget->installEventFilter(this);
95
96 const QVector<Transfer*> transfers(TransfersManager::getTransfers());
97
98 for (int i = 0; i < transfers.count(); ++i)
99 {
100 handleTransferAdded(transfers.at(i));
101 }
102
103 if (isSidebarPanel())
104 {
105 m_ui->detailsWidget->hide();
106 }
107
108 connect(TransfersManager::getInstance(), &TransfersManager::transferStarted, this, &TransfersContentsWidget::handleTransferAdded);
109 connect(TransfersManager::getInstance(), &TransfersManager::transferRemoved, this, &TransfersContentsWidget::handleTransferRemoved);
110 connect(TransfersManager::getInstance(), &TransfersManager::transferChanged, this, &TransfersContentsWidget::handleTransferChanged);
111 connect(m_model, &QStandardItemModel::modelReset, this, &TransfersContentsWidget::updateActions);
112 connect(m_ui->transfersViewWidget, &ItemViewWidget::doubleClicked, this, &TransfersContentsWidget::openTransfer);
113 connect(m_ui->transfersViewWidget, &ItemViewWidget::customContextMenuRequested, this, &TransfersContentsWidget::showContextMenu);
114 connect(m_ui->transfersViewWidget, &ItemViewWidget::needsActionsUpdate, this, &TransfersContentsWidget::updateActions);
115 connect(m_ui->downloadLineEditWidget, &LineEditWidget::returnPressed, this, &TransfersContentsWidget::startQuickTransfer);
116 connect(m_ui->stopResumeButton, &QPushButton::clicked, this, &TransfersContentsWidget::stopResumeTransfer);
117 connect(m_ui->redownloadButton, &QPushButton::clicked, this, &TransfersContentsWidget::redownloadTransfer);
118 }
119
~TransfersContentsWidget()120 TransfersContentsWidget::~TransfersContentsWidget()
121 {
122 delete m_ui;
123 }
124
changeEvent(QEvent * event)125 void TransfersContentsWidget::changeEvent(QEvent *event)
126 {
127 ContentsWidget::changeEvent(event);
128
129 if (event->type() == QEvent::LanguageChange)
130 {
131 m_ui->retranslateUi(this);
132
133 m_model->setHorizontalHeaderLabels({tr("Status"), tr("Filename"), tr("Size"), tr("Progress"), tr("Time"), tr("Speed"), tr("Started"), tr("Finished")});
134
135 updateActions();
136 }
137 }
138
removeTransfer()139 void TransfersContentsWidget::removeTransfer()
140 {
141 Transfer *transfer(getTransfer(m_ui->transfersViewWidget->currentIndex()));
142
143 if (transfer)
144 {
145 if (transfer->getState() == Transfer::RunningState && QMessageBox::warning(this, tr("Warning"), tr("This file is still being downloaded.\nDo you really want to remove it?"), (QMessageBox::Yes | QMessageBox::Cancel)) == QMessageBox::Cancel)
146 {
147 return;
148 }
149
150 m_model->removeRow(m_ui->transfersViewWidget->currentIndex().row());
151
152 TransfersManager::removeTransfer(transfer);
153 }
154 }
155
openTransfer()156 void TransfersContentsWidget::openTransfer()
157 {
158 const Transfer *transfer(getTransfer(m_ui->transfersViewWidget->currentIndex()));
159
160 if (transfer)
161 {
162 transfer->openTarget();
163 }
164 }
165
openTransferFolder()166 void TransfersContentsWidget::openTransferFolder()
167 {
168 const Transfer *transfer(getTransfer(m_ui->transfersViewWidget->currentIndex()));
169
170 if (transfer)
171 {
172 Utils::runApplication({}, QUrl::fromLocalFile(QFileInfo(transfer->getTarget()).dir().canonicalPath()));
173 }
174 }
175
copyTransferInformation()176 void TransfersContentsWidget::copyTransferInformation()
177 {
178 const QModelIndex index(m_ui->transfersViewWidget->currentIndex());
179
180 if (index.isValid() && index.data(Qt::ToolTipRole).isValid())
181 {
182 QApplication::clipboard()->setText(index.data(Qt::ToolTipRole).toString().remove(QRegularExpression(QLatin1String("<[^>]*>"))));
183 }
184 }
185
stopResumeTransfer()186 void TransfersContentsWidget::stopResumeTransfer()
187 {
188 Transfer *transfer(getTransfer(m_ui->transfersViewWidget->getCurrentIndex()));
189
190 if (transfer)
191 {
192 if (transfer->getState() == Transfer::RunningState)
193 {
194 transfer->stop();
195 }
196 else if (transfer->getState() == Transfer::ErrorState)
197 {
198 transfer->resume();
199 }
200
201 updateActions();
202 }
203 }
204
redownloadTransfer()205 void TransfersContentsWidget::redownloadTransfer()
206 {
207 Transfer *transfer(getTransfer(m_ui->transfersViewWidget->getCurrentIndex()));
208
209 if (transfer)
210 {
211 transfer->restart();
212 }
213 }
214
startQuickTransfer()215 void TransfersContentsWidget::startQuickTransfer()
216 {
217 TransfersManager::startTransfer(m_ui->downloadLineEditWidget->text(), {}, (Transfer::CanNotifyOption | Transfer::IsQuickTransferOption | (SessionsManager::isPrivate() ? Transfer::IsPrivateOption : Transfer::NoOption)));
218
219 m_ui->downloadLineEditWidget->clear();
220 }
221
clearFinishedTransfers()222 void TransfersContentsWidget::clearFinishedTransfers()
223 {
224 TransfersManager::clearTransfers();
225 }
226
handleTransferAdded(Transfer * transfer)227 void TransfersContentsWidget::handleTransferAdded(Transfer *transfer)
228 {
229 QList<QStandardItem*> items({new QStandardItem(), new QStandardItem(QFileInfo(transfer->getTarget()).fileName())});
230 items[0]->setData(qVariantFromValue(static_cast<void*>(transfer)), InstanceRole);
231 items[0]->setFlags(items[0]->flags() | Qt::ItemNeverHasChildren);
232 items[1]->setFlags(items[1]->flags() | Qt::ItemNeverHasChildren);
233
234 for (int i = 2; i < m_model->columnCount(); ++i)
235 {
236 QStandardItem *item(new QStandardItem());
237 item->setFlags(item->flags() | Qt::ItemNeverHasChildren);
238
239 items.append(item);
240 }
241
242 m_model->appendRow(items);
243
244 m_ui->transfersViewWidget->openPersistentEditor(items[3]->index());
245
246 handleTransferChanged(transfer);
247 }
248
handleTransferChanged(Transfer * transfer)249 void TransfersContentsWidget::handleTransferChanged(Transfer *transfer)
250 {
251 const int row(findTransfer(transfer));
252
253 if (row < 0)
254 {
255 return;
256 }
257
258 QIcon icon;
259 const bool isIndeterminate(transfer->getBytesTotal() <= 0);
260
261 switch (transfer->getState())
262 {
263 case Transfer::RunningState:
264 icon = ThemesManager::createIcon(QLatin1String("task-ongoing"));
265
266 break;
267 case Transfer::FinishedState:
268 icon = ThemesManager::createIcon(QLatin1String("task-complete"));
269
270 break;
271 default:
272 icon = ThemesManager::createIcon(QLatin1String("task-reject"));
273
274 break;
275 }
276
277 const QString toolTip(tr("<div style=\"white-space:pre;\">Source: %1\nTarget: %2\nSize: %3\nDownloaded: %4\nProgress: %5</div>").arg(transfer->getSource().toDisplayString().toHtmlEscaped()).arg(transfer->getTarget().toHtmlEscaped()).arg(isIndeterminate ? tr("Unknown") : Utils::formatUnit(transfer->getBytesTotal(), false, 1, true)).arg(Utils::formatUnit(transfer->getBytesReceived(), false, 1, true)).arg(isIndeterminate ? tr("Unknown") : QStringLiteral("%1%").arg(Utils::calculatePercent(transfer->getBytesReceived(), transfer->getBytesTotal()), 0, 'f', 1)));
278
279 for (int i = 0; i < m_model->columnCount(); ++i)
280 {
281 const QModelIndex &index(m_model->index(row, i));
282
283 m_model->setData(index, toolTip, Qt::ToolTipRole);
284
285 switch (i)
286 {
287 case 0:
288 m_model->setData(index, icon, Qt::DecorationRole);
289 m_model->setData(index, transfer->getState(), StateRole);
290
291 break;
292 case 1:
293 m_model->setData(index, QFileInfo(transfer->getTarget()).fileName(), Qt::DisplayRole);
294
295 break;
296 case 2:
297 m_model->setData(index, Utils::formatUnit(transfer->getBytesTotal(), false, 1), Qt::DisplayRole);
298 m_model->setData(index, transfer->getBytesTotal(), BytesTotalRole);
299
300 break;
301 case 3:
302 m_model->setData(index, transfer->getBytesReceived(), BytesReceivedRole);
303 m_model->setData(index, transfer->getBytesTotal(), BytesTotalRole);
304 m_model->setData(index, ((transfer->getBytesTotal() > 0) ? qFloor(Utils::calculatePercent(transfer->getBytesReceived(), transfer->getBytesTotal())) : -1), ProgressRole);
305 m_model->setData(index, transfer->getState(), StateRole);
306
307 break;
308 case 4:
309 m_model->setData(index, ((isIndeterminate || transfer->getRemainingTime() <= 0) ? QString() : Utils::formatElapsedTime(transfer->getRemainingTime())), Qt::DisplayRole);
310
311 break;
312 case 5:
313 m_model->setData(index, ((transfer->getState() == Transfer::RunningState) ? Utils::formatUnit(transfer->getSpeed(), true, 1) : QString()), Qt::DisplayRole);
314
315 break;
316 case 6:
317 m_model->setData(index, Utils::formatDateTime(transfer->getTimeStarted()), Qt::DisplayRole);
318 m_model->setData(index, transfer->getTimeStarted(), TimeStartedRole);
319
320 break;
321 case 7:
322 m_model->setData(index, Utils::formatDateTime(transfer->getTimeFinished()), Qt::DisplayRole);
323 m_model->setData(index, transfer->getTimeFinished(), TimeFinishedRole);
324
325 break;
326 default:
327 break;
328 }
329 }
330
331 if (m_ui->transfersViewWidget->selectionModel()->hasSelection())
332 {
333 updateActions();
334 }
335
336 const bool isRunning(transfer && transfer->getState() == Transfer::RunningState);
337
338 if (isRunning != m_isLoading)
339 {
340 if (isRunning)
341 {
342 m_isLoading = true;
343
344 emit loadingStateChanged(WebWidget::OngoingLoadingState);
345 }
346 else
347 {
348 const QVector<Transfer*> transfers(TransfersManager::getTransfers());
349 bool hasRunning(false);
350
351 for (int i = 0; i < transfers.count(); ++i)
352 {
353 if (transfers.at(i) && transfers.at(i)->getState() == Transfer::RunningState)
354 {
355 hasRunning = true;
356
357 break;
358 }
359 }
360
361 if (!hasRunning)
362 {
363 m_isLoading = false;
364
365 emit loadingStateChanged(WebWidget::FinishedLoadingState);
366 }
367 }
368 }
369 }
370
handleTransferRemoved(Transfer * transfer)371 void TransfersContentsWidget::handleTransferRemoved(Transfer *transfer)
372 {
373 const int row(findTransfer(transfer));
374
375 if (row >= 0)
376 {
377 m_model->removeRow(row);
378 }
379 }
380
showContextMenu(const QPoint & position)381 void TransfersContentsWidget::showContextMenu(const QPoint &position)
382 {
383 const Transfer *transfer(getTransfer(m_ui->transfersViewWidget->indexAt(position)));
384 QMenu menu(this);
385
386 if (transfer)
387 {
388 const bool canOpen(QFile::exists(transfer->getTarget()));
389
390 menu.addAction(QCoreApplication::translate("actions", "Open"), this, &TransfersContentsWidget::openTransfer)->setEnabled(canOpen);
391
392 Menu *openWithMenu(new Menu(Menu::OpenInApplicationMenu, this));
393 openWithMenu->setEnabled(canOpen);
394 openWithMenu->setExecutor(ActionExecutor::Object(this, this));
395 openWithMenu->setActionParameters({{QLatin1String("url"), transfer->getTarget()}});
396 openWithMenu->setMenuOptions({{QLatin1String("mimeType"), transfer->getMimeType().name()}});
397
398 menu.addMenu(openWithMenu);
399 menu.addAction(tr("Open Folder"), this, &TransfersContentsWidget::openTransferFolder)->setEnabled(canOpen || QFileInfo(transfer->getTarget()).dir().exists());
400 menu.addSeparator();
401 menu.addAction(((transfer->getState() == Transfer::ErrorState) ? tr("Resume") : tr("Stop")), this, &TransfersContentsWidget::stopResumeTransfer)->setEnabled(transfer->getState() == Transfer::RunningState || transfer->getState() == Transfer::ErrorState);
402 menu.addAction(tr("Redownload"), this, &TransfersContentsWidget::redownloadTransfer);
403 menu.addSeparator();
404 menu.addAction(tr("Copy Transfer Information"), this, &TransfersContentsWidget::copyTransferInformation);
405 menu.addSeparator();
406 menu.addAction(tr("Remove"), this, &TransfersContentsWidget::removeTransfer);
407 }
408
409 const QVector<Transfer*> transfers(TransfersManager::getTransfers());
410 int finishedTransfers(0);
411
412 for (int i = 0; i < transfers.count(); ++i)
413 {
414 if (transfers.at(i)->getState() == Transfer::FinishedState)
415 {
416 ++finishedTransfers;
417 }
418 }
419
420 menu.addAction(tr("Clear Finished Transfers"), this, &TransfersContentsWidget::clearFinishedTransfers)->setEnabled(finishedTransfers > 0);
421 menu.exec(m_ui->transfersViewWidget->mapToGlobal(position));
422 }
423
updateActions()424 void TransfersContentsWidget::updateActions()
425 {
426 const Transfer *transfer(getTransfer(m_ui->transfersViewWidget->getCurrentIndex()));
427
428 if (transfer && transfer->getState() == Transfer::ErrorState)
429 {
430 m_ui->stopResumeButton->setText(tr("Resume"));
431 m_ui->stopResumeButton->setIcon(ThemesManager::createIcon(QLatin1String("task-ongoing")));
432 }
433 else
434 {
435 m_ui->stopResumeButton->setText(tr("Stop"));
436 m_ui->stopResumeButton->setIcon(ThemesManager::createIcon(QLatin1String("task-reject")));
437 }
438
439 m_ui->stopResumeButton->setEnabled(transfer && (transfer->getState() == Transfer::RunningState || transfer->getState() == Transfer::ErrorState));
440 m_ui->redownloadButton->setEnabled(transfer);
441
442 if (transfer)
443 {
444 const bool isIndeterminate(transfer->getBytesTotal() <= 0);
445
446 m_ui->sourceLabelWidget->setText(transfer->getSource().toDisplayString());
447 m_ui->sourceLabelWidget->setUrl(transfer->getSource());
448 m_ui->targetLabelWidget->setText(transfer->getTarget());
449 m_ui->targetLabelWidget->setUrl(QUrl(transfer->getTarget()));
450 m_ui->sizeLabelWidget->setText(isIndeterminate ? tr("Unknown") : Utils::formatUnit(transfer->getBytesTotal(), false, 1, true));
451 m_ui->downloadedLabelWidget->setText(Utils::formatUnit(transfer->getBytesReceived(), false, 1, true));
452 m_ui->progressLabelWidget->setText(isIndeterminate ? tr("Unknown") : QStringLiteral("%1%").arg(Utils::calculatePercent(transfer->getBytesReceived(), transfer->getBytesTotal()), 0, 'f', 1));
453 }
454 else
455 {
456 m_ui->sourceLabelWidget->clear();
457 m_ui->targetLabelWidget->clear();
458 m_ui->sizeLabelWidget->clear();
459 m_ui->downloadedLabelWidget->clear();
460 m_ui->progressLabelWidget->clear();
461 }
462
463 emit categorizedActionsStateChanged({ActionsManager::ActionDefinition::EditingCategory});
464 }
465
print(QPrinter * printer)466 void TransfersContentsWidget::print(QPrinter *printer)
467 {
468 m_ui->transfersViewWidget->render(printer);
469 }
470
triggerAction(int identifier,const QVariantMap & parameters,ActionsManager::TriggerType trigger)471 void TransfersContentsWidget::triggerAction(int identifier, const QVariantMap ¶meters, ActionsManager::TriggerType trigger)
472 {
473 switch (identifier)
474 {
475 case ActionsManager::CopyAction:
476 if (m_ui->transfersViewWidget->hasFocus() && m_ui->transfersViewWidget->currentIndex().isValid())
477 {
478 copyTransferInformation();
479 }
480 else
481 {
482 const QWidget *widget(focusWidget());
483
484 if (widget->metaObject()->className() == QLatin1String("Otter::TextLabelWidget"))
485 {
486 const TextLabelWidget *label(qobject_cast<const TextLabelWidget*>(widget));
487
488 if (label)
489 {
490 label->copy();
491 }
492 }
493 }
494
495 break;
496 case ActionsManager::DeleteAction:
497 removeTransfer();
498
499 break;
500 case ActionsManager::FindAction:
501 case ActionsManager::QuickFindAction:
502 m_ui->downloadLineEditWidget->setFocus();
503 m_ui->downloadLineEditWidget->selectAll();
504
505 break;
506 case ActionsManager::ActivateContentAction:
507 m_ui->transfersViewWidget->setFocus();
508
509 break;
510 default:
511 ContentsWidget::triggerAction(identifier, parameters, trigger);
512
513 break;
514 }
515 }
516
getTransfer(const QModelIndex & index) const517 Transfer* TransfersContentsWidget::getTransfer(const QModelIndex &index) const
518 {
519 if (index.isValid())
520 {
521 return static_cast<Transfer*>(index.sibling(index.row(), 0).data(InstanceRole).value<void*>());
522 }
523
524 return nullptr;
525 }
526
getTitle() const527 QString TransfersContentsWidget::getTitle() const
528 {
529 return tr("Downloads");
530 }
531
getType() const532 QLatin1String TransfersContentsWidget::getType() const
533 {
534 return QLatin1String("transfers");
535 }
536
getUrl() const537 QUrl TransfersContentsWidget::getUrl() const
538 {
539 return QUrl(QLatin1String("about:transfers"));
540 }
541
getIcon() const542 QIcon TransfersContentsWidget::getIcon() const
543 {
544 return ThemesManager::createIcon(QLatin1String("transfers"), false);
545 }
546
getActionState(int identifier,const QVariantMap & parameters) const547 ActionsManager::ActionDefinition::State TransfersContentsWidget::getActionState(int identifier, const QVariantMap ¶meters) const
548 {
549 switch (identifier)
550 {
551 case ActionsManager::CopyAction:
552 case ActionsManager::DeleteAction:
553 {
554 ActionsManager::ActionDefinition::State state(ActionsManager::getActionDefinition(identifier).getDefaultState());
555 state.isEnabled = (getTransfer(m_ui->transfersViewWidget->getCurrentIndex()) != nullptr);
556
557 return state;
558 }
559
560 break;
561 default:
562 break;
563 }
564
565 return ContentsWidget::getActionState(identifier, parameters);
566 }
567
getLoadingState() const568 WebWidget::LoadingState TransfersContentsWidget::getLoadingState() const
569 {
570 return (m_isLoading ? WebWidget::OngoingLoadingState : WebWidget::FinishedLoadingState);
571 }
572
findTransfer(Transfer * transfer) const573 int TransfersContentsWidget::findTransfer(Transfer *transfer) const
574 {
575 if (!transfer)
576 {
577 return -1;
578 }
579
580 for (int i = 0; i < m_model->rowCount(); ++i)
581 {
582 if (transfer == getTransfer(m_model->index(i, 0)))
583 {
584 return i;
585 }
586 }
587
588 return -1;
589 }
590
eventFilter(QObject * object,QEvent * event)591 bool TransfersContentsWidget::eventFilter(QObject *object, QEvent *event)
592 {
593 if (object == m_ui->transfersViewWidget && event->type() == QEvent::KeyPress)
594 {
595 switch (static_cast<QKeyEvent*>(event)->key())
596 {
597 case Qt::Key_Delete:
598 removeTransfer();
599
600 return true;
601 case Qt::Key_Enter:
602 case Qt::Key_Return:
603 openTransfer();
604
605 return true;
606 default:
607 break;
608 }
609 }
610 else if (object == m_ui->downloadLineEditWidget && event->type() == QEvent::KeyPress && static_cast<QKeyEvent*>(event)->key() == Qt::Key_Escape)
611 {
612 m_ui->downloadLineEditWidget->clear();
613 }
614
615 return ContentsWidget::eventFilter(object, event);
616 }
617
618 }
619