File indexing completed on 2024-04-21 04:57:18

0001 /* This file is part of the KDE project
0002 
0003    Copyright (C) 2007 by Lukas Appelhans <l.appelhans@gmx.de>
0004 
0005    This program is free software; you can redistribute it and/or
0006    modify it under the terms of the GNU General Public
0007    License as published by the Free Software Foundation; either
0008    version 2 of the License, or (at your option) any later version.
0009 */
0010 
0011 #include "transferhistory.h"
0012 #include "core/job.h"
0013 #include "core/transferhistorystore.h"
0014 #include "settings.h"
0015 #include "ui/history/rangetreewidget.h"
0016 #include "ui/history/transferhistorycategorizeddelegate.h"
0017 #include "ui/history/transferhistorycategorizedview.h"
0018 #include "ui/newtransferdialog.h"
0019 
0020 #include "kget_debug.h"
0021 
0022 #include <QDateTime>
0023 #include <QDebug>
0024 #include <QDialogButtonBox>
0025 #include <QFile>
0026 #include <QFileSystemWatcher>
0027 #include <QFontDatabase>
0028 #include <QFontMetrics>
0029 #include <QIcon>
0030 #include <QMenu>
0031 #include <QModelIndex>
0032 #include <QProgressBar>
0033 #include <QPushButton>
0034 #include <QStandardItem>
0035 #include <QStandardPaths>
0036 #include <QVariant>
0037 
0038 #include <KIO/JobUiDelegateFactory>
0039 #include <KIO/OpenUrlJob>
0040 #include <KLocalizedString>
0041 #include <KTreeWidgetSearchLine>
0042 #include <kio/global.h>
0043 
0044 TransferHistory::TransferHistory(QWidget *parent)
0045     : KGetSaveSizeDialog("TransferHistory", parent)
0046     , m_rangeType(TransferHistory::Date)
0047     , m_progressBar(new QProgressBar(this))
0048     , m_iconModeEnabled(true)
0049 {
0050     setAttribute(Qt::WA_DeleteOnClose);
0051     setWindowTitle(i18n("Transfer History"));
0052     // Setup Ui-Parts from Designer
0053     auto *mainWidget = new QWidget(this);
0054 
0055     setupUi(mainWidget);
0056 
0057     m_view = new TransferHistoryCategorizedView(this);
0058 
0059     // list icon view
0060     auto &iconView = bt_iconview;
0061     auto &listView = bt_listview;
0062 
0063     listView->setIcon(QIcon::fromTheme("view-list-details"));
0064     iconView->setIcon(QIcon::fromTheme("view-list-icons"));
0065 
0066     connect(listView, &QAbstractButton::clicked, this, &TransferHistory::slotSetListMode);
0067     connect(iconView, &QAbstractButton::clicked, this, &TransferHistory::slotSetIconMode);
0068 
0069     clearButton->setIcon(QIcon::fromTheme("edit-clear-history"));
0070     actionDelete_Selected->setIcon(QIcon::fromTheme("edit-delete"));
0071     actionDownload->setIcon(QIcon::fromTheme("document-new"));
0072     m_openFile = new QAction(QIcon::fromTheme("document-open"), i18n("&Open File"), this);
0073 
0074     m_progressBar->setFormat(i18nc("Progress bar percent value", "%p%"));
0075 
0076     vboxLayout->addWidget(m_view);
0077     vboxLayout->addWidget(m_progressBar);
0078 
0079     auto *buttonBox = new QDialogButtonBox(mainWidget);
0080     buttonBox->clear();
0081     buttonBox->addButton(QDialogButtonBox::Close);
0082     vboxLayout->addWidget(buttonBox);
0083 
0084     setLayout(vboxLayout);
0085 
0086     watcher = new QFileSystemWatcher();
0087     watcher->addPath(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + QLatin1Char('/') + QString());
0088     qCDebug(KGET_DEBUG) << watcher->directories();
0089 
0090     m_store = TransferHistoryStore::getStore();
0091 
0092     connect(actionDelete_Selected, SIGNAL(triggered()), this, SLOT(slotDeleteTransfer()));
0093     connect(actionDownload, &QAction::triggered, this, &TransferHistory::slotDownload);
0094     connect(m_openFile, SIGNAL(triggered()), this, SLOT(slotOpenFile()));
0095     connect(clearButton, &QAbstractButton::clicked, this, &TransferHistory::slotClear);
0096     connect(rangeType, SIGNAL(activated(int)), this, SLOT(slotLoadRangeType(int)));
0097     connect(m_view, SIGNAL(deletedTransfer(QString, QModelIndex)), SLOT(slotDeleteTransfer(QString, QModelIndex)));
0098     connect(m_view, SIGNAL(doubleClicked(QModelIndex)), SLOT(slotOpenFile(QModelIndex)));
0099     connect(m_store, &TransferHistoryStore::loadFinished, this, &TransferHistory::slotLoadFinished);
0100     connect(m_store, &TransferHistoryStore::elementLoaded, this, &TransferHistory::slotElementLoaded);
0101     connect(searchBar, SIGNAL(textChanged(QString)), m_view, SLOT(setFilterRegExp(QString)));
0102     connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
0103     connect(buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
0104     slotAddTransfers();
0105 }
0106 
0107 TransferHistory::~TransferHistory()
0108 {
0109     delete m_store;
0110 }
0111 
0112 QSize TransferHistory::sizeHint() const
0113 {
0114     QSize sh(800, 600);
0115     return sh;
0116 }
0117 
0118 void TransferHistory::slotDeleteTransfer()
0119 {
0120     if (!m_iconModeEnabled) {
0121         auto *range_view = qobject_cast<RangeTreeWidget *>(m_view);
0122 
0123         slotDeleteTransfer(range_view->currentItem(0)->text());
0124 
0125         slotLoadRangeType(m_rangeType);
0126     }
0127 }
0128 
0129 void TransferHistory::slotDeleteTransfer(const QString &transferName, const QModelIndex &index)
0130 {
0131     Q_UNUSED(index)
0132 
0133     TransferHistoryItem item;
0134     item.setSource(transferName);
0135     m_store->deleteItem(item);
0136 
0137     slotLoadRangeType(m_rangeType);
0138 }
0139 
0140 void TransferHistory::slotAddTransfers()
0141 {
0142     m_progressBar->show();
0143     m_store->load();
0144 }
0145 
0146 void TransferHistory::slotClear()
0147 {
0148     m_store->clear();
0149 
0150     slotLoadRangeType(m_rangeType);
0151 }
0152 
0153 void TransferHistory::slotWriteDefault()
0154 {
0155     // not neded ??
0156 }
0157 
0158 void TransferHistory::slotDownload()
0159 {
0160     if (!m_iconModeEnabled) {
0161         NewTransferDialogHandler::showNewTransferDialog(QUrl(((RangeTreeWidget *)m_view)->currentItem(0)->text()));
0162     }
0163 }
0164 
0165 void TransferHistory::contextMenuEvent(QContextMenuEvent *event)
0166 {
0167     Q_UNUSED(event)
0168 
0169     if (!m_iconModeEnabled) {
0170         auto *range_view = qobject_cast<RangeTreeWidget *>(m_view);
0171         if (range_view->currentIndex().parent().isValid()) {
0172             auto *contextMenu = new QMenu(this);
0173             contextMenu->addAction(actionDownload);
0174             contextMenu->addAction(actionDelete_Selected);
0175 
0176             if (range_view->currentItem(4)->data().toInt() == Job::Finished)
0177                 contextMenu->addAction(m_openFile);
0178             contextMenu->exec(QCursor::pos());
0179         }
0180     }
0181 }
0182 
0183 void TransferHistory::slotOpenFile(const QModelIndex &index)
0184 {
0185     QString file;
0186 
0187     if (!m_iconModeEnabled) {
0188         auto *range_view = qobject_cast<RangeTreeWidget *>(m_view);
0189         file = range_view->currentItem(1)->text();
0190     } else {
0191         auto *categorized_view = qobject_cast<TransferHistoryCategorizedView *>(m_view);
0192         file = categorized_view->data(index, TransferHistoryCategorizedDelegate::RoleDest).toString();
0193     }
0194 
0195     // qDebug() << "Try to open the file : " << file;
0196     if (!file.isEmpty()) {
0197         auto job = new KIO::OpenUrlJob(QUrl::fromLocalFile(file), this);
0198         job->setUiDelegate(KIO::createDefaultJobUiDelegate(KJobUiDelegate::AutoHandlingEnabled, this));
0199         job->start();
0200     }
0201 }
0202 
0203 void TransferHistory::hideEvent(QHideEvent *event)
0204 {
0205     Q_UNUSED(event)
0206     disconnect(watcher, &QFileSystemWatcher::directoryChanged, this, &TransferHistory::slotAddTransfers); // Prevent reloading of TransferHistory when saving
0207     deleteLater();
0208 }
0209 
0210 QString TransferHistory::statusText(int status) const
0211 {
0212     switch (status) {
0213     case Job::Running:
0214         return i18nc("The transfer is running", "Running");
0215     case Job::Stopped:
0216         return i18nc("The transfer is stopped", "Stopped");
0217     case Job::Aborted:
0218         return i18nc("The transfer is aborted", "Aborted");
0219     case Job::Finished:
0220         return i18nc("The transfer is finished", "Finished");
0221     default:
0222         return QString();
0223     }
0224 }
0225 
0226 void TransferHistory::slotLoadRangeType(int type)
0227 {
0228     m_rangeType = type;
0229     if (m_iconModeEnabled) {
0230         auto *cat_view = qobject_cast<TransferHistoryCategorizedView *>(m_view);
0231         cat_view->clear();
0232         switch (type) {
0233         case TransferHistory::Size:
0234             cat_view->setCategorizedDelegate(new SizeCategorizedDelegate());
0235             break;
0236         case TransferHistory::Date:
0237             cat_view->setCategorizedDelegate(new DateCategorizedDelegate());
0238             break;
0239         default:
0240             cat_view->setCategorizedDelegate(new HostCategorizedDelegate());
0241         }
0242     } else {
0243         auto *range_view = qobject_cast<RangeTreeWidget *>(m_view);
0244         auto *font = new QFontMetrics(QFontDatabase::systemFont(QFontDatabase::GeneralFont));
0245         range_view->clear();
0246 
0247         range_view->setLabels(QStringList() << i18n("Source File") << i18n("Destination") << i18n("Time") << i18n("File Size") << i18n("Status"));
0248         range_view->setRangeDelegate(nullptr);
0249 
0250         switch (m_rangeType) {
0251         case TransferHistory::Host:
0252             range_view->setRangeDelegate(new HostRangeDelegate(this));
0253             break;
0254         case TransferHistory::Size:
0255             range_view->addRange(QVariant(0), QVariant(1024 * 1024), i18n("Less than 1MiB"));
0256             range_view->addRange(QVariant(1024 * 1024), QVariant(1024 * 1024 * 10), i18n("Between 1MiB-10MiB"));
0257             range_view->addRange(QVariant(1024 * 1024 * 10), QVariant(1024 * 1024 * 100), i18n("Between 10MiB-100MiB"));
0258             range_view->addRange(QVariant(1024 * 1024 * 100), QVariant(1024 * 1024 * 1024), i18n("Between 100MiB-1GiB"));
0259             range_view->addRange(QVariant((double)1024 * 1024 * 1024), QVariant((double)1024 * 1024 * 1024 * 10), i18n("More than 1GiB"));
0260             break;
0261         default:
0262             range_view->addRange(QVariant(0), QVariant(1), i18n("Today"));
0263             range_view->addRange(QVariant(1), QVariant(7), i18n("Last week"));
0264             range_view->addRange(QVariant(7), QVariant(30), i18n("Last month"));
0265             range_view->addRange(QVariant(30), QVariant(-1), i18n("A long time ago"));
0266         }
0267 
0268         QList<int> list = Settings::historyColumnWidths();
0269 
0270         if (!list.isEmpty()) {
0271             int j = 0;
0272             foreach (int i, list) {
0273                 range_view->setColumnWidth(j, i);
0274                 j++;
0275             }
0276         } else {
0277             range_view->setColumnWidth(0, 200);
0278             range_view->setColumnWidth(1, 250);
0279             range_view->setColumnWidth(2, font->horizontalAdvance(QDate::currentDate().toString()));
0280             range_view->setColumnWidth(3, font->horizontalAdvance("1500000 KiB"));
0281             range_view->setColumnWidth(4, font->horizontalAdvance(i18nc("the transfer has been finished", "Finished")));
0282         }
0283     }
0284 
0285     slotAddTransfers();
0286 }
0287 
0288 void TransferHistory::slotSetListMode()
0289 {
0290     m_iconModeEnabled = false;
0291     delete m_view;
0292     m_view = new RangeTreeWidget(this);
0293     vboxLayout->insertWidget(1, m_view);
0294     slotLoadRangeType(m_rangeType);
0295 
0296     connect(searchBar, SIGNAL(textChanged(QString)), m_view, SLOT(setFilterRegExp(QString)));
0297     // we connect the doubleClicked signal over an item to the open file action
0298     connect(m_view, SIGNAL(doubleClicked(QModelIndex)), SLOT(slotOpenFile(QModelIndex)));
0299 }
0300 
0301 void TransferHistory::slotSetIconMode()
0302 {
0303     m_iconModeEnabled = true;
0304     delete m_view;
0305     m_view = new TransferHistoryCategorizedView(this);
0306     vboxLayout->insertWidget(1, m_view);
0307     slotLoadRangeType(m_rangeType);
0308 
0309     connect(searchBar, SIGNAL(textChanged(QString)), m_view, SLOT(setFilterRegExp(QString)));
0310     connect(m_view, SIGNAL(deletedTransfer(QString, QModelIndex)), SLOT(slotDeleteTransfer(QString, QModelIndex)));
0311     connect(m_view, SIGNAL(doubleClicked(QModelIndex)), SLOT(slotOpenFile(QModelIndex)));
0312 }
0313 
0314 void TransferHistory::slotElementLoaded(int number, int total, const TransferHistoryItem &item)
0315 {
0316     m_progressBar->setValue(number * 100 / total);
0317 
0318     if (m_iconModeEnabled) {
0319         ((TransferHistoryCategorizedView *)m_view)->addData(item.dateTime().date(), item.source(), item.dest(), item.size());
0320     } else {
0321         QVariantList attributeList;
0322         attributeList.append(item.source());
0323         attributeList.append(item.dest());
0324         attributeList.append(item.dateTime().date().toString());
0325         attributeList.append(KIO::convertSize(item.size()));
0326         attributeList.append(statusText(item.state()));
0327 
0328         QVariant data;
0329         if (m_rangeType == TransferHistory::Date) {
0330             QDate date = item.dateTime().date();
0331             data = QVariant(date.daysTo(QDate::currentDate()));
0332         } else if (m_rangeType == TransferHistory::Host) {
0333             data = QVariant(item.source());
0334         } else {
0335             data = QVariant(item.size());
0336         }
0337         ((RangeTreeWidget *)m_view)->add(data, attributeList);
0338     }
0339 }
0340 
0341 void TransferHistory::slotLoadFinished()
0342 {
0343     m_progressBar->hide();
0344 }
0345 
0346 #include "moc_transferhistory.cpp"