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 &parameters, 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 &parameters, 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 &parameters) 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