kde-extraapps/ark/part/arkviewer.cpp
Ivailo Monev a91ec41cc6 generic: adjust to KRun changes
Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
2024-05-12 03:22:20 +03:00

238 lines
8.4 KiB
C++

/*
* ark: A program for modifying archives via a GUI.
*
* Copyright (C) 2004-2008 Henrique Pinto <henrique.pinto@kdemail.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#include "arkviewer.h"
#include <KLocale>
#include <KMimeTypeTrader>
#include <KMimeType>
#include <KDebug>
#include <KUrl>
#include <KGlobal>
#include <KIconLoader>
#include <KVBox>
#include <KMessageBox>
#include <KProgressDialog>
#include <KPushButton>
#include <KToolInvocation>
#include <KIO/NetAccess>
#include <KPixmapWidget>
#include <QHBoxLayout>
#include <QFile>
#include <QFrame>
#include <QLabel>
ArkViewer::ArkViewer(QWidget * parent, Qt::WFlags flags)
: KDialog(parent, flags)
{
setButtons(Close);
m_widget = new KVBox(this);
m_widget->layout()->setSpacing(10);
setMainWidget(m_widget);
connect(this, SIGNAL(finished()), SLOT(dialogClosed()));
}
ArkViewer::~ArkViewer()
{
}
void ArkViewer::dialogClosed()
{
KConfigGroup conf = KGlobal::config()->group("Viewer");
saveDialogSize(conf);
if (m_part) {
KProgressDialog progressDialog
(this, i18n("Closing preview"),
i18n("Please wait while the preview is being closed..."));
progressDialog.setMinimumDuration(500);
progressDialog.setModal(true);
progressDialog.setAllowCancel(false);
progressDialog.progressBar()->setRange(0, 0);
// #261785: this preview dialog is not modal, so we need to delete
// the previewed file ourselves when the dialog is closed;
// we used to remove it at the end of ArkViewer::view() when
// QDialog::exec() was called instead of QDialog::show().
const QString previewedFilePath(m_part.data()->url().pathOrUrl());
m_part.data()->closeUrl();
if (!previewedFilePath.isEmpty()) {
QFile::remove(previewedFilePath);
}
}
}
void ArkViewer::view(const QString& fileName, QWidget *parent)
{
KMimeType::Ptr mimeType = KMimeType::findByUrl(KUrl(fileName));
kDebug() << "MIME type" << mimeType->name();
KService::Ptr viewer = ArkViewer::getViewer(mimeType);
const bool needsExternalViewer = (!viewer.isNull() &&
!viewer->hasServiceType(QLatin1String("KParts/ReadOnlyPart")));
if (needsExternalViewer) {
// The last argument (temp) set to true means that the temporary
// file will be removed when the viewer application exits.
KToolInvocation::self()->startServiceByStorageId(viewer->entryPath(), QStringList() << fileName, parent, true);
return;
}
bool viewInInternalViewer = true;
if (viewer.isNull()) {
// No internal viewer available for the file. Ask the user if it
// should be previewed as text/plain.
int response;
if (!mimeType->isDefault()) {
// File has a defined MIME type, and not the default
// application/octet-stream. So it could be viewable as
// plain text, ask the user.
response = KMessageBox::warningContinueCancel(parent,
i18n("The internal viewer cannot preview this type of file<br/>(%1).<br/><br/>Do you want to try to view it as plain text?", mimeType->name()),
i18nc("@title:window", "Cannot Preview File"),
KGuiItem(i18nc("@action:button", "Preview as Text"), KIcon(QLatin1String("text-plain"))),
KStandardGuiItem::cancel(),
QString::fromLatin1("PreviewAsText_%1").arg(mimeType->name()));
} else {
// No defined MIME type, or the default application/octet-stream.
// There is still a possibility that it could be viewable as plain
// text, so ask the user. Not the same as the message/question
// above, because the wording and default are different.
response = KMessageBox::warningContinueCancel(parent,
i18n("The internal viewer cannot preview this unknown type of file.<br/><br/>Do you want to try to view it as plain text?"),
i18nc("@title:window", "Cannot Preview File"),
KGuiItem(i18nc("@action:button", "Preview as Text"), KIcon(QLatin1String("text-plain"))),
KStandardGuiItem::cancel(),
QString(),
KMessageBox::Dangerous);
}
if (response == KMessageBox::Cancel) {
viewInInternalViewer = false;
} else { // set for viewer later
mimeType = KMimeType::mimeType(QLatin1String("text/plain"));
}
}
if (viewInInternalViewer) {
ArkViewer *internalViewer = new ArkViewer(parent, Qt::Window);
if (internalViewer->viewInInternalViewer(fileName, mimeType)) {
internalViewer->show();
// The internal viewer is showing the file, and will
// remove the temporary file in dialogClosed(). So there
// is no more to do here.
return;
} else {
KMessageBox::sorry(parent, i18n("The internal viewer cannot preview this file."));
delete internalViewer;
}
}
// Only get here if there is no internal viewer available or could be
// used for the file, and no external viewer was opened. Nothing can be
// done with the temporary file, so remove it now.
QFile::remove(fileName);
}
void ArkViewer::keyPressEvent(QKeyEvent *event)
{
KPushButton *defButton = button(defaultButton());
// Only handle the event the usual way if the default button has focus
// Otherwise, pressing enter on KatePart still closes the dialog, for example.
if ((defButton) && (defButton->hasFocus())) {
KDialog::keyPressEvent(event);
}
event->accept();
}
// This sets the default size of the dialog. It will only take effect in the case
// where there is no saved size in the config file - it sets the default values
// for KDialog::restoreDialogSize().
QSize ArkViewer::sizeHint() const
{
return QSize(560, 400);
}
bool ArkViewer::viewInInternalViewer(const QString& fileName, const KMimeType::Ptr& mimeType)
{
const KUrl fileUrl(fileName);
setCaption(fileUrl.fileName());
restoreDialogSize(KGlobal::config()->group("Viewer"));
QFrame *header = new QFrame(m_widget);
QHBoxLayout *headerLayout = new QHBoxLayout(header);
KPixmapWidget *iconWidget = new KPixmapWidget(header);
headerLayout->addWidget(iconWidget);
iconWidget->setPixmap(KIconLoader::global()->loadMimeTypeIcon(mimeType->iconName(), KIconLoader::Desktop));
iconWidget->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum);
KVBox *headerRight = new KVBox(header);
headerLayout->addWidget(headerRight);
new QLabel(QString::fromLatin1( "<qt><b>%1</b></qt>" )
.arg(fileUrl.fileName()), headerRight
);
new QLabel(mimeType->comment(), headerRight);
header->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum);
m_part = KMimeTypeTrader::self()->createPartInstanceFromQuery<KParts::ReadOnlyPart>(mimeType->name(),
m_widget,
this);
if (!m_part.data()) {
return false;
}
m_part.data()->openUrl(fileUrl);
return true;
}
KService::Ptr ArkViewer::getViewer(const KMimeType::Ptr &mimeType)
{
// No point in even trying to find anything for application/octet-stream
if (mimeType->isDefault()) {
return KService::Ptr();
}
// Try to get a read-only kpart for the internal viewer
KService::Ptr offer = KMimeTypeTrader::self()->preferredService(mimeType->name(), QLatin1String("KParts/ReadOnlyPart"));
// If we can't find a kpart, try to get an external application
if (!offer) {
offer = KMimeTypeTrader::self()->preferredService(mimeType->name(), QLatin1String("Application"));
}
return offer;
}
#include "moc_arkviewer.cpp"