File indexing completed on 2024-04-28 04:18:54

0001 /*
0002 Gwenview: an image viewer
0003 Copyright 2007-2012 Aurélien Gâteau <agateau@kde.org>
0004 
0005 This program is free software; you can redistribute it and/or
0006 modify it under the terms of the GNU General Public License
0007 as published by the Free Software Foundation; either version 2
0008 of the License, or (at your option) any later version.
0009 
0010 This program is distributed in the hope that it will be useful,
0011 but WITHOUT ANY WARRANTY; without even the implied warranty of
0012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0013 GNU General Public License for more details.
0014 
0015 You should have received a copy of the GNU General Public License
0016 along with this program; if not, write to the Free Software
0017 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
0018 
0019 */
0020 // Qt
0021 #include <QAction>
0022 #include <QDebug>
0023 #include <QFileDialog>
0024 #include <QMenu>
0025 #include <QUrl>
0026 
0027 // KF
0028 #include <KActionCollection>
0029 #include <KIO/FileCopyJob>
0030 #include <KIO/JobUiDelegate>
0031 #include <KIO/StoredTransferJob>
0032 #include <KJobWidgets>
0033 #include <KLocalizedString>
0034 #include <KPluginFactory>
0035 #include <KPropertiesDialog>
0036 #include <KStandardAction>
0037 
0038 // Local
0039 #include "../lib/document/document.h"
0040 #include "../lib/document/documentfactory.h"
0041 #include "../lib/documentview/documentview.h"
0042 #include "../lib/documentview/documentviewcontainer.h"
0043 #include "../lib/documentview/documentviewcontroller.h"
0044 #include "../lib/urlutils.h"
0045 #include "gvbrowserextension.h"
0046 #include "gvpart.h"
0047 
0048 namespace Gwenview
0049 {
0050 K_PLUGIN_CLASS_WITH_JSON(GVPart, "gvpart.json")
0051 
0052 GVPart::GVPart(QWidget *parentWidget, QObject *parent, const KPluginMetaData &metaData, const QVariantList & /*args*/)
0053     : KParts::ReadOnlyPart(parent, metaData)
0054 {
0055     auto container = new DocumentViewContainer(parentWidget);
0056     setWidget(container);
0057     mDocumentView = container->createView();
0058 
0059     connect(mDocumentView, &DocumentView::captionUpdateRequested, this, &KParts::Part::setWindowCaption);
0060     connect(mDocumentView, &DocumentView::completed, this, QOverload<>::of(&KParts::ReadOnlyPart::completed));
0061 
0062     connect(mDocumentView, &DocumentView::contextMenuRequested, this, &GVPart::showContextMenu);
0063 
0064     // Necessary to have zoom actions
0065     auto documentViewController = new DocumentViewController(actionCollection(), this);
0066     documentViewController->setView(mDocumentView);
0067 
0068     auto action = new QAction(actionCollection());
0069     action->setText(i18nc("@action", "Properties"));
0070     action->setShortcut(QKeySequence(Qt::ALT | Qt::Key_Return));
0071     connect(action, &QAction::triggered, this, &GVPart::showProperties);
0072     actionCollection()->addAction(QStringLiteral("file_show_properties"), action);
0073 
0074     KStandardAction::saveAs(this, SLOT(saveAs()), actionCollection());
0075 
0076     new GVBrowserExtension(this);
0077 
0078     setXMLFile(QStringLiteral("gvpart.rc"), true);
0079 }
0080 
0081 void GVPart::showProperties()
0082 {
0083     KPropertiesDialog::showDialog(url(), widget());
0084 }
0085 
0086 bool GVPart::openUrl(const QUrl &url)
0087 {
0088     if (!url.isValid()) {
0089         return false;
0090     }
0091     setUrl(url);
0092     Document::Ptr doc = DocumentFactory::instance()->load(url);
0093     if (arguments().reload()) {
0094         doc->reload();
0095     }
0096     if (!UrlUtils::urlIsFastLocalFile(url)) {
0097         // Keep raw data of remote files to avoid downloading them again in
0098         // saveAs()
0099         doc->setKeepRawData(true);
0100     }
0101     DocumentView::Setup setup;
0102     setup.zoomToFit = true;
0103     mDocumentView->openUrl(url, setup);
0104     mDocumentView->setCurrent(true);
0105     return true;
0106 }
0107 
0108 inline void addActionToMenu(QMenu *menu, KActionCollection *actionCollection, const char *name)
0109 {
0110     QAction *action = actionCollection->action(name);
0111     if (action) {
0112         menu->addAction(action);
0113     }
0114 }
0115 
0116 void GVPart::showContextMenu()
0117 {
0118     QMenu menu(widget());
0119     addActionToMenu(&menu, actionCollection(), "file_save_as");
0120     menu.addSeparator();
0121     addActionToMenu(&menu, actionCollection(), "view_actual_size");
0122     addActionToMenu(&menu, actionCollection(), "view_zoom_to_fit");
0123     addActionToMenu(&menu, actionCollection(), "view_zoom_in");
0124     addActionToMenu(&menu, actionCollection(), "view_zoom_out");
0125     menu.addSeparator();
0126     addActionToMenu(&menu, actionCollection(), "file_show_properties");
0127     menu.exec(QCursor::pos());
0128 }
0129 
0130 void GVPart::saveAs()
0131 {
0132     const QUrl srcUrl = url();
0133     const QUrl dstUrl = QFileDialog::getSaveFileUrl(widget(), QString(), srcUrl);
0134     if (!dstUrl.isValid()) {
0135         return;
0136     }
0137 
0138     KIO::Job *job;
0139     Document::Ptr doc = DocumentFactory::instance()->load(srcUrl);
0140     const QByteArray rawData = doc->rawData();
0141     if (!rawData.isEmpty()) {
0142         job = KIO::storedPut(rawData, dstUrl, -1);
0143     } else {
0144         job = KIO::file_copy(srcUrl, dstUrl);
0145     }
0146     connect(job, &KJob::result, this, &GVPart::showJobError);
0147 }
0148 
0149 void GVPart::showJobError(KJob *job)
0150 {
0151     if (job->error() != 0) {
0152         KJobUiDelegate *ui = static_cast<KIO::Job *>(job)->uiDelegate();
0153         if (!ui) {
0154             qCritical() << "Saving failed. job->ui() is null.";
0155             return;
0156         }
0157         KJobWidgets::setWindow(job, widget());
0158         ui->showErrorMessage();
0159     }
0160 }
0161 
0162 } // namespace
0163 
0164 #include "gvpart.moc"
0165 
0166 #include "moc_gvpart.cpp"