File indexing completed on 2024-04-28 04:57:35

0001 /* This file is part of the KDE project
0002 
0003    Based in the kcategorizeditemsviewdelegate from kdebase/workspace/libs/plasma/appletbrowser by Ivan Cukic
0004    Copyright (C) 2008 Javier Goday <jgoday@gmail.com>
0005 
0006    This program is free software; you can redistribute it and/or
0007    modify it under the terms of the GNU General Public
0008    License as published by the Free Software Foundation; either
0009    version 2 of the License, or (at your option) any later version.
0010 */
0011 
0012 #include "transferhistoryitemdelegate.h"
0013 #include "ui/history/transferhistorycategorizeddelegate.h"
0014 #include "ui/history/transferhistorycategorizedview.h"
0015 #include "ui/newtransferdialog.h"
0016 
0017 #include <QAbstractItemModel>
0018 #include <QAction>
0019 #include <QApplication>
0020 #include <QDate>
0021 #include <QDebug>
0022 #include <QIcon>
0023 #include <QMenu>
0024 #include <QModelIndex>
0025 #include <QMouseEvent>
0026 #include <QPainter>
0027 #include <QPainterPath>
0028 
0029 #include <KIO/JobUiDelegateFactory>
0030 #include <KIO/OpenUrlJob>
0031 #include <KLocalizedString>
0032 
0033 TransferHistoryItemDelegate::TransferHistoryItemDelegate(QWidget *parent)
0034     : QStyledItemDelegate()
0035     , m_selectedIndex()
0036 {
0037     m_view = parent;
0038 
0039     // Actions
0040     m_actionDownload = new QAction(this);
0041     m_actionDownload->setText(i18n("Download again"));
0042     m_actionDownload->setIcon(QIcon::fromTheme("document-new"));
0043     connect(m_actionDownload, &QAction::triggered, this, &TransferHistoryItemDelegate::slotDownload);
0044 
0045     m_actionDelete_Selected = new QAction(this);
0046     m_actionDelete_Selected->setText(i18nc("Delete selected history-item", "Delete selected"));
0047     m_actionDelete_Selected->setIcon(QIcon::fromTheme("edit-delete"));
0048     connect(m_actionDelete_Selected, &QAction::triggered, this, &TransferHistoryItemDelegate::slotDeleteTransfer);
0049 
0050     m_openFile = new QAction(this);
0051     m_openFile->setText(i18n("Open file"));
0052     m_openFile->setIcon(QIcon::fromTheme("document-open"));
0053     connect(m_openFile, &QAction::triggered, this, &TransferHistoryItemDelegate::slotOpenFile);
0054 }
0055 
0056 TransferHistoryItemDelegate::~TransferHistoryItemDelegate()
0057 {
0058 }
0059 
0060 void TransferHistoryItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
0061 {
0062     if (!option.state.testFlag(QStyle::State_Selected) && !option.state.testFlag(QStyle::State_MouseOver)) {
0063         // draw a separator
0064         painter->save();
0065 
0066         QRect roundRect(option.rect.left() + 1, option.rect.top() + 1, option.rect.width() - 2, option.rect.height() - 2);
0067 
0068         QPainterPath path;
0069         path.addRoundedRect(roundRect, 2, 2, Qt::RelativeSize);
0070         QLinearGradient gradient(roundRect.left(), roundRect.top(), roundRect.left(), roundRect.bottom());
0071         gradient.setColorAt(0, Qt::transparent);
0072         gradient.setColorAt(0.95, option.palette.color(QPalette::AlternateBase).darker(130));
0073         QBrush brush(gradient);
0074 
0075         painter->fillPath(path, brush);
0076 
0077         painter->setPen(option.palette.color(QPalette::AlternateBase).darker(190));
0078         painter->drawRoundedRect(roundRect, 2, 2, Qt::RelativeSize);
0079         painter->restore();
0080     }
0081 
0082     QStyleOptionViewItem opt(option);
0083     QStyle *style = opt.widget ? opt.widget->style() : QApplication::style();
0084     style->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, painter, opt.widget);
0085 
0086     const auto *model = static_cast<const QAbstractItemModel *>(index.model());
0087     QUrl url(model->data(index, TransferHistoryCategorizedDelegate::RoleUrl).toString());
0088     QString name = url.path().mid(url.path().lastIndexOf("/") + 1);
0089     const QString iconName = KIO::iconNameForUrl(QUrl::fromLocalFile(model->data(index, TransferHistoryCategorizedDelegate::RoleDest).toString()));
0090     QIcon icon = QIcon::fromTheme(iconName, QIcon::fromTheme("application-octet-stream"));
0091     QString size = KIO::convertSize(model->data(index, TransferHistoryCategorizedDelegate::RoleSize).toInt());
0092     QString date = model->data(index, TransferHistoryCategorizedDelegate::RoleDate).toDate().toString("dd.MM.yyyy");
0093     QString host = url.host();
0094 
0095     // draw the host
0096     painter->save();
0097     painter->setPen(option.palette.color(QPalette::Link));
0098     // draw the host
0099     painter->drawText(option.rect.left() + PADDING, option.rect.top() + PADDING, option.rect.width() - PADDING * 2, 15, Qt::AlignTop | Qt::AlignLeft, host);
0100     painter->restore();
0101 
0102     // draw the transfer icon
0103     icon.paint(painter,
0104                option.rect.left() + option.rect.width() / 2 - ICON_SIZE / 2,
0105                option.rect.top() + option.rect.height() / 2 - ICON_SIZE / 2 - PADDING * 2,
0106                ICON_SIZE,
0107                ICON_SIZE,
0108                Qt::AlignCenter,
0109                QIcon::Active);
0110 
0111     painter->save();
0112     QColor subcolor = (option.state.testFlag(QStyle::State_Selected) || (option.state.testFlag(QStyle::State_MouseOver)))
0113         ? option.palette.color(QPalette::Text)
0114         : option.palette.color(QPalette::BrightText);
0115 
0116     // draw a separator line between the file name and his size and date
0117     painter->setPen(option.palette.color(QPalette::AlternateBase).darker(190));
0118     painter->drawLine(option.rect.left() + 2, option.rect.bottom() + PADDING - 27, option.rect.right() - 2, option.rect.bottom() + PADDING - 27);
0119     painter->setPen(subcolor);
0120     // draw the size
0121     painter->drawText(option.rect.right() - PADDING - 100, option.rect.bottom() + PADDING - 25, 100 - PADDING * 2, 25, Qt::AlignTop | Qt::AlignRight, size);
0122 
0123     // draw the date
0124     painter->drawText(option.rect.left() + PADDING, option.rect.bottom() + PADDING - 25, 100 - PADDING * 2, 25, Qt::AlignTop | Qt::AlignLeft, date);
0125 
0126     painter->restore();
0127 
0128     // draw the filenamne
0129     painter->save();
0130     QColor foregroundColor =
0131         (option.state.testFlag(QStyle::State_Selected)) ? option.palette.color(QPalette::HighlightedText) : option.palette.color(QPalette::Text);
0132     painter->setPen(foregroundColor);
0133     painter->setFont(option.font);
0134     painter->drawText(option.rect.left() + PADDING, option.rect.bottom() - PADDING - 35, 200 - PADDING * 2, 15, Qt::AlignBottom | Qt::AlignCenter, name);
0135     painter->restore();
0136 }
0137 
0138 QSize TransferHistoryItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
0139 {
0140     Q_UNUSED(option)
0141     Q_UNUSED(index)
0142 
0143     return QSize(200, 110);
0144 }
0145 
0146 bool TransferHistoryItemDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index)
0147 {
0148     Q_UNUSED(option)
0149     Q_UNUSED(model)
0150 
0151     auto *mouseEvent = dynamic_cast<QMouseEvent *>(event);
0152 
0153     if (mouseEvent && index.isValid()) {
0154         if (mouseEvent->button() == Qt::RightButton) {
0155             m_selectedIndex = index;
0156 
0157             auto *contextMenu = new QMenu();
0158             contextMenu->addAction(m_actionDownload);
0159             contextMenu->addAction(m_actionDelete_Selected);
0160             contextMenu->addAction(m_openFile);
0161 
0162             contextMenu->exec(QCursor::pos());
0163         }
0164     }
0165 
0166     return false;
0167 }
0168 
0169 void TransferHistoryItemDelegate::slotOpenFile()
0170 {
0171     const auto *model = static_cast<const QAbstractItemModel *>(m_selectedIndex.model());
0172 
0173     auto job = new KIO::OpenUrlJob(QUrl::fromLocalFile(model->data(m_selectedIndex, TransferHistoryCategorizedDelegate::RoleDest).toString()), m_view);
0174     job->setUiDelegate(KIO::createDefaultJobUiDelegate(KJobUiDelegate::AutoHandlingEnabled, m_view));
0175     job->start();
0176 }
0177 
0178 void TransferHistoryItemDelegate::slotDownload()
0179 {
0180     const auto *model = static_cast<const QAbstractItemModel *>(m_selectedIndex.model());
0181 
0182     NewTransferDialogHandler::showNewTransferDialog(QUrl(model->data(m_selectedIndex, TransferHistoryCategorizedDelegate::RoleUrl).toString()));
0183 }
0184 
0185 void TransferHistoryItemDelegate::slotDeleteTransfer()
0186 {
0187     const auto *model = static_cast<const QAbstractItemModel *>(m_selectedIndex.model());
0188 
0189     Q_EMIT deletedTransfer(model->data(m_selectedIndex, TransferHistoryCategorizedDelegate::RoleUrl).toString(), m_selectedIndex);
0190 }
0191 
0192 #include "moc_transferhistoryitemdelegate.cpp"