2021-05-24 07:25:56 +00:00
|
|
|
/*
|
|
|
|
SPDX-FileCopyrightText: 2006 Albert Astals Cid <aacid@kde.org>
|
|
|
|
|
|
|
|
SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
*/
|
2006-05-28 16:54:54 +00:00
|
|
|
|
2007-04-19 18:30:20 +00:00
|
|
|
#include "embeddedfilesdialog.h"
|
|
|
|
|
2007-07-03 15:30:44 +00:00
|
|
|
#include <QAction>
|
|
|
|
#include <QCursor>
|
2006-05-28 16:54:54 +00:00
|
|
|
#include <QDateTime>
|
2016-03-23 00:58:38 +00:00
|
|
|
#include <QDir>
|
|
|
|
#include <QFileInfo>
|
2007-07-03 15:30:44 +00:00
|
|
|
#include <QMenu>
|
2016-03-23 00:58:38 +00:00
|
|
|
#include <QTemporaryFile>
|
2006-05-28 16:54:54 +00:00
|
|
|
#include <QTreeWidget>
|
|
|
|
|
2014-10-06 06:31:17 +00:00
|
|
|
#include <KConfigGroup>
|
2014-10-01 05:27:09 +00:00
|
|
|
#include <KFormat>
|
2015-01-29 20:48:47 +00:00
|
|
|
#include <KLocalizedString>
|
2014-09-11 13:18:05 +00:00
|
|
|
#include <KRun>
|
2020-07-08 11:54:37 +00:00
|
|
|
#include <KStandardGuiItem>
|
2014-10-19 13:28:32 +00:00
|
|
|
#include <QDialogButtonBox>
|
|
|
|
#include <QIcon>
|
2014-09-11 13:18:05 +00:00
|
|
|
#include <QMimeDatabase>
|
|
|
|
#include <QMimeType>
|
2014-10-19 13:28:32 +00:00
|
|
|
#include <QPushButton>
|
|
|
|
#include <QVBoxLayout>
|
2006-05-28 16:54:54 +00:00
|
|
|
|
|
|
|
#include "core/document.h"
|
2008-04-14 22:31:28 +00:00
|
|
|
#include "guiutils.h"
|
2006-05-28 16:54:54 +00:00
|
|
|
|
2008-02-10 02:02:58 +00:00
|
|
|
Q_DECLARE_METATYPE(Okular::EmbeddedFile *)
|
|
|
|
|
|
|
|
static const int EmbeddedFileRole = Qt::UserRole + 100;
|
|
|
|
|
2006-12-28 15:48:13 +00:00
|
|
|
static QString dateToString(const QDateTime &date)
|
|
|
|
{
|
2015-01-29 20:48:47 +00:00
|
|
|
return date.isValid() ? QLocale().toString(date, QLocale::LongFormat) : i18nc("Unknown date", "Unknown");
|
2006-12-28 15:48:13 +00:00
|
|
|
}
|
|
|
|
|
2014-10-19 13:28:32 +00:00
|
|
|
EmbeddedFilesDialog::EmbeddedFilesDialog(QWidget *parent, const Okular::Document *document)
|
|
|
|
: QDialog(parent)
|
2006-05-28 16:54:54 +00:00
|
|
|
{
|
2014-10-19 13:28:32 +00:00
|
|
|
setWindowTitle(i18nc("@title:window", "Embedded Files"));
|
|
|
|
QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Close);
|
|
|
|
QVBoxLayout *mainLayout = new QVBoxLayout;
|
|
|
|
setLayout(mainLayout);
|
|
|
|
mUser1Button = new QPushButton;
|
|
|
|
buttonBox->addButton(mUser1Button, QDialogButtonBox::ActionRole);
|
2015-10-29 12:37:11 +00:00
|
|
|
connect(buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
|
|
|
|
connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
|
2014-10-19 13:28:32 +00:00
|
|
|
buttonBox->button(QDialogButtonBox::Close)->setDefault(true);
|
|
|
|
KGuiItem::assign(mUser1Button, KStandardGuiItem::save());
|
|
|
|
mUser1Button->setEnabled(false);
|
2020-07-10 22:15:05 +00:00
|
|
|
|
2016-10-29 09:13:24 +00:00
|
|
|
mUser2Button = new QPushButton;
|
|
|
|
buttonBox->addButton(mUser2Button, QDialogButtonBox::ActionRole);
|
2019-04-25 21:10:48 +00:00
|
|
|
KGuiItem::assign(mUser2Button, KGuiItem(i18nc("@action:button", "View"), QStringLiteral("document-open")));
|
2016-10-29 09:26:52 +00:00
|
|
|
mUser2Button->setEnabled(false);
|
2020-07-10 22:15:05 +00:00
|
|
|
|
2006-05-28 16:54:54 +00:00
|
|
|
m_tw = new QTreeWidget(this);
|
2014-10-19 13:28:32 +00:00
|
|
|
mainLayout->addWidget(m_tw);
|
2016-10-29 09:13:24 +00:00
|
|
|
mainLayout->addWidget(buttonBox);
|
2020-07-10 22:15:05 +00:00
|
|
|
|
2006-05-28 16:54:54 +00:00
|
|
|
QStringList header;
|
2008-08-01 20:11:51 +00:00
|
|
|
header.append(i18nc("@title:column", "Name"));
|
|
|
|
header.append(i18nc("@title:column", "Description"));
|
|
|
|
header.append(i18nc("@title:column", "Size"));
|
|
|
|
header.append(i18nc("@title:column", "Created"));
|
|
|
|
header.append(i18nc("@title:column", "Modified"));
|
2006-05-28 16:54:54 +00:00
|
|
|
m_tw->setHeaderLabels(header);
|
|
|
|
m_tw->setRootIsDecorated(false);
|
2007-07-03 10:33:11 +00:00
|
|
|
m_tw->setSelectionMode(QAbstractItemView::ExtendedSelection);
|
2007-07-03 15:30:44 +00:00
|
|
|
m_tw->setContextMenuPolicy(Qt::CustomContextMenu);
|
2006-09-16 03:49:40 +00:00
|
|
|
|
2019-12-09 13:39:47 +00:00
|
|
|
// embeddedFiles() returns a const QList
|
|
|
|
for (Okular::EmbeddedFile *ef : *document->embeddedFiles()) {
|
2006-05-28 16:54:54 +00:00
|
|
|
QTreeWidgetItem *twi = new QTreeWidgetItem();
|
|
|
|
twi->setText(0, ef->name());
|
2016-10-29 09:13:24 +00:00
|
|
|
QMimeDatabase db;
|
|
|
|
QMimeType mime = db.mimeTypeForFile(ef->name(), QMimeDatabase::MatchExtension);
|
2014-09-11 13:18:05 +00:00
|
|
|
if (mime.isValid()) {
|
2016-10-29 09:13:24 +00:00
|
|
|
twi->setIcon(0, QIcon::fromTheme(mime.iconName()));
|
2006-06-17 10:22:24 +00:00
|
|
|
}
|
2006-05-28 16:54:54 +00:00
|
|
|
twi->setText(1, ef->description());
|
2014-10-01 05:27:09 +00:00
|
|
|
twi->setText(2, ef->size() <= 0 ? i18nc("Not available size", "N/A") : KFormat().formatByteSize(ef->size()));
|
2007-07-03 14:47:16 +00:00
|
|
|
twi->setText(3, dateToString(ef->creationDate()));
|
|
|
|
twi->setText(4, dateToString(ef->modificationDate()));
|
2019-09-18 11:41:19 +00:00
|
|
|
twi->setData(0, EmbeddedFileRole, QVariant::fromValue(ef));
|
2006-05-28 16:54:54 +00:00
|
|
|
m_tw->addTopLevelItem(twi);
|
|
|
|
}
|
2016-10-29 09:13:24 +00:00
|
|
|
// Having filled the columns, it is nice to resize them to be able to read the contents
|
|
|
|
for (int lv = 0; lv < m_tw->columnCount(); ++lv) {
|
|
|
|
m_tw->resizeColumnToContents(lv);
|
|
|
|
}
|
|
|
|
// This is a bit dubious, but I'm not seeing a nice way to say "expand to fit contents"
|
|
|
|
m_tw->setMinimumWidth(640);
|
|
|
|
m_tw->updateGeometry();
|
2020-07-10 22:15:05 +00:00
|
|
|
|
2020-02-20 14:48:08 +00:00
|
|
|
connect(mUser1Button, &QPushButton::clicked, this, &EmbeddedFilesDialog::saveFileFromButton);
|
|
|
|
connect(mUser2Button, &QPushButton::clicked, this, &EmbeddedFilesDialog::viewFileFromButton);
|
2015-10-29 12:37:11 +00:00
|
|
|
connect(m_tw, &QWidget::customContextMenuRequested, this, &EmbeddedFilesDialog::attachViewContextMenu);
|
|
|
|
connect(m_tw, &QTreeWidget::itemSelectionChanged, this, &EmbeddedFilesDialog::updateSaveButton);
|
2016-10-29 14:32:24 +00:00
|
|
|
connect(m_tw, &QTreeWidget::itemDoubleClicked, this, &EmbeddedFilesDialog::viewFileItem);
|
2010-03-03 16:46:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void EmbeddedFilesDialog::updateSaveButton()
|
|
|
|
{
|
|
|
|
bool enable = (m_tw->selectedItems().count() > 0);
|
2014-10-19 13:28:32 +00:00
|
|
|
mUser1Button->setEnabled(enable);
|
2016-10-29 09:13:24 +00:00
|
|
|
mUser2Button->setEnabled(enable);
|
2006-05-28 16:54:54 +00:00
|
|
|
}
|
|
|
|
|
2020-02-20 14:48:08 +00:00
|
|
|
void EmbeddedFilesDialog::saveFileFromButton()
|
2006-05-28 16:54:54 +00:00
|
|
|
{
|
2019-12-09 13:39:47 +00:00
|
|
|
const QList<QTreeWidgetItem *> selected = m_tw->selectedItems();
|
|
|
|
for (const QTreeWidgetItem *twi : selected) {
|
2008-02-10 02:02:58 +00:00
|
|
|
Okular::EmbeddedFile *ef = qvariant_cast<Okular::EmbeddedFile *>(twi->data(0, EmbeddedFileRole));
|
2007-07-03 15:30:44 +00:00
|
|
|
saveFile(ef);
|
2006-05-28 16:54:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-02-20 14:48:08 +00:00
|
|
|
void EmbeddedFilesDialog::viewFileFromButton()
|
2016-03-23 00:58:38 +00:00
|
|
|
{
|
2019-12-09 13:39:47 +00:00
|
|
|
const QList<QTreeWidgetItem *> selected = m_tw->selectedItems();
|
|
|
|
for (QTreeWidgetItem *twi : selected) {
|
2016-03-23 00:58:38 +00:00
|
|
|
Okular::EmbeddedFile *ef = qvariant_cast<Okular::EmbeddedFile *>(twi->data(0, EmbeddedFileRole));
|
|
|
|
viewFile(ef);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void EmbeddedFilesDialog::viewFileItem(QTreeWidgetItem *item, int /*column*/)
|
|
|
|
{
|
|
|
|
Okular::EmbeddedFile *ef = qvariant_cast<Okular::EmbeddedFile *>(item->data(0, EmbeddedFileRole));
|
|
|
|
viewFile(ef);
|
|
|
|
}
|
|
|
|
|
2020-02-20 17:45:46 +00:00
|
|
|
void EmbeddedFilesDialog::attachViewContextMenu()
|
2007-07-03 15:30:44 +00:00
|
|
|
{
|
|
|
|
QList<QTreeWidgetItem *> selected = m_tw->selectedItems();
|
|
|
|
if (selected.isEmpty())
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (selected.size() > 1)
|
|
|
|
return;
|
|
|
|
|
|
|
|
QMenu menu(this);
|
2015-10-29 12:37:11 +00:00
|
|
|
QAction *saveAsAct = menu.addAction(QIcon::fromTheme(QStringLiteral("document-save-as")), i18nc("@action:inmenu", "&Save As..."));
|
2016-10-29 09:13:24 +00:00
|
|
|
QAction *viewAct = menu.addAction(QIcon::fromTheme(QStringLiteral("document-open")), i18nc("@action:inmenu", "&View..."));
|
2007-07-03 15:30:44 +00:00
|
|
|
|
|
|
|
QAction *act = menu.exec(QCursor::pos());
|
|
|
|
if (!act)
|
|
|
|
return;
|
|
|
|
|
2016-03-23 01:02:45 +00:00
|
|
|
Okular::EmbeddedFile *ef = qvariant_cast<Okular::EmbeddedFile *>(selected.at(0)->data(0, EmbeddedFileRole));
|
2007-07-03 15:30:44 +00:00
|
|
|
if (act == saveAsAct) {
|
|
|
|
saveFile(ef);
|
2016-03-23 01:02:45 +00:00
|
|
|
} else if (act == viewAct) {
|
|
|
|
viewFile(ef);
|
|
|
|
}
|
2007-07-03 15:30:44 +00:00
|
|
|
}
|
|
|
|
|
2016-03-23 00:58:38 +00:00
|
|
|
void EmbeddedFilesDialog::viewFile(Okular::EmbeddedFile *ef)
|
|
|
|
{
|
|
|
|
// get name and extension
|
|
|
|
QFileInfo fileInfo(ef->name());
|
2020-07-10 22:15:05 +00:00
|
|
|
|
2016-03-23 00:58:38 +00:00
|
|
|
// save in temporary directory with a unique name resembling the attachment name,
|
|
|
|
// using QTemporaryFile's XXXXXX placeholder
|
2020-04-04 09:17:50 +00:00
|
|
|
QTemporaryFile *tmpFile = new QTemporaryFile(QDir::tempPath() + '/' + fileInfo.baseName() + ".XXXXXX" + (fileInfo.completeSuffix().isEmpty() ? QLatin1String("") : QString('.' + fileInfo.completeSuffix())));
|
2016-03-23 00:58:38 +00:00
|
|
|
GuiUtils::writeEmbeddedFile(ef, this, *tmpFile);
|
2020-07-10 22:15:05 +00:00
|
|
|
|
2016-03-23 00:58:38 +00:00
|
|
|
// set readonly to prevent the viewer application from modifying it
|
|
|
|
tmpFile->setPermissions(QFile::ReadOwner);
|
2020-07-10 22:15:05 +00:00
|
|
|
|
2016-03-23 00:58:38 +00:00
|
|
|
// keep temporary file alive while the dialog is open
|
|
|
|
m_openedFiles.push_back(QSharedPointer<QTemporaryFile>(tmpFile));
|
2020-07-10 22:15:05 +00:00
|
|
|
|
2016-03-23 00:58:38 +00:00
|
|
|
// view the temporary file with the default application
|
|
|
|
new KRun(QUrl("file://" + tmpFile->fileName()), this);
|
2007-07-03 15:30:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void EmbeddedFilesDialog::saveFile(Okular::EmbeddedFile *ef)
|
|
|
|
{
|
2008-04-14 22:31:28 +00:00
|
|
|
GuiUtils::saveEmbeddedFile(ef, this);
|
2007-07-03 15:30:44 +00:00
|
|
|
}
|
|
|
|
|
2014-08-08 22:00:07 +00:00
|
|
|
#include "moc_embeddedfilesdialog.cpp"
|