File indexing completed on 2024-05-12 09:53:37

0001 /*
0002     SPDX-FileCopyrightText: 2007 Henrique Pinto <henrique.pinto@kdemail.net>
0003     SPDX-FileCopyrightText: 2008-2009 Harald Hvaal <haraldhv@stud.ntnu.no>
0004     SPDX-FileCopyrightText: 2015-2017 Ragnar Thomsen <rthomsen6@gmail.com>
0005 
0006     SPDX-License-Identifier: GPL-2.0-or-later
0007 */
0008 
0009 #include "addtoarchive.h"
0010 #include "ark_debug.h"
0011 #include "ark_version.h"
0012 #include "batchextract.h"
0013 #include "mainwindow.h"
0014 #include "pluginmanager.h"
0015 
0016 #include <QApplication>
0017 #include <QCommandLineParser>
0018 #include <QDir>
0019 #include <QFileInfo>
0020 #include <QFileOpenEvent>
0021 
0022 #include <KAboutData>
0023 #include <KCrash>
0024 #include <KDBusService>
0025 #include <KLocalizedString>
0026 
0027 #include <iostream>
0028 
0029 using Kerfuffle::AddToArchive;
0030 
0031 class OpenFileEventHandler : public QObject
0032 {
0033     Q_OBJECT
0034 public:
0035     OpenFileEventHandler(QApplication *parent, MainWindow *w)
0036         : QObject(parent)
0037         , m_window(w)
0038     {
0039         parent->installEventFilter(this);
0040     }
0041 
0042     bool eventFilter(QObject *obj, QEvent *event) override
0043     {
0044         if (event->type() == QEvent::FileOpen) {
0045             QFileOpenEvent *openEvent = static_cast<QFileOpenEvent *>(event);
0046             qCDebug(ARK) << "File open event:" << openEvent->url() << "for window" << m_window;
0047             m_window->openUrl(openEvent->url());
0048             return true;
0049         }
0050         return QObject::eventFilter(obj, event);
0051     }
0052 
0053 private:
0054     MainWindow *m_window;
0055 };
0056 
0057 int main(int argc, char **argv)
0058 {
0059     QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts); // Required for the webengine part.
0060     QApplication application(argc, argv);
0061 
0062     KCrash::initialize();
0063 
0064     // Debug output can be turned on here:
0065     // QLoggingCategory::setFilterRules(QStringLiteral("ark.debug = true"));
0066 
0067     KLocalizedString::setApplicationDomain(QByteArrayLiteral("ark"));
0068 
0069     KAboutData aboutData(QStringLiteral("ark"),
0070                          i18n("Ark"),
0071                          QStringLiteral(ARK_VERSION_STRING),
0072                          i18n("KDE Archiving tool"),
0073                          KAboutLicense::GPL,
0074                          i18n("(c) 1997-2019, The Ark Developers"),
0075                          QString(),
0076                          QStringLiteral("https://apps.kde.org/ark"));
0077 
0078     aboutData.setProgramLogo(QIcon::fromTheme(QStringLiteral(":/ark/ark.svgz")));
0079 
0080     aboutData.addAuthor(i18n("Elvis Angelaccio"), i18n("Maintainer"), QStringLiteral("elvis.angelaccio@kde.org"));
0081     aboutData.addAuthor(i18n("Ragnar Thomsen"), i18n("Maintainer, KF5 port"), QStringLiteral("rthomsen6@gmail.com"));
0082     aboutData.addAuthor(i18n("Raphael Kubo da Costa"), i18n("Former Maintainer"), QStringLiteral("rakuco@FreeBSD.org"));
0083     aboutData.addAuthor(i18n("Harald Hvaal"), i18n("Former Maintainer"), QStringLiteral("haraldhv@stud.ntnu.no"));
0084     aboutData.addAuthor(i18n("Henrique Pinto"), i18n("Former Maintainer"), QStringLiteral("henrique.pinto@kdemail.net"));
0085     aboutData.addAuthor(i18n("Helio Chissini de Castro"), i18n("Former maintainer"), QStringLiteral("helio@kde.org"));
0086     aboutData.addAuthor(i18n("Georg Robbers"), QString(), QStringLiteral("Georg.Robbers@urz.uni-hd.de"));
0087     aboutData.addAuthor(i18n("Roberto Selbach Teixeira"), QString(), QStringLiteral("maragato@kde.org"));
0088     aboutData.addAuthor(i18n("Francois-Xavier Duranceau"), QString(), QStringLiteral("duranceau@kde.org"));
0089     aboutData.addAuthor(i18n("Emily Ezust (Corel Corporation)"), QString(), QStringLiteral("emilye@corel.com"));
0090     aboutData.addAuthor(i18n("Michael Jarrett (Corel Corporation)"), QString(), QStringLiteral("michaelj@corel.com"));
0091     aboutData.addAuthor(i18n("Robert Palmbos"), QString(), QStringLiteral("palm9744@kettering.edu"));
0092 
0093     aboutData.addCredit(i18n("Vladyslav Batyrenko"),
0094                         i18n("Advanced editing functionalities"),
0095                         QString(),
0096                         QStringLiteral("https://mvlabat.github.io/ark-gsoc-2016/"));
0097     aboutData.addCredit(i18n("Bryce Corkins"), i18n("Icons"), QStringLiteral("dbryce@attglobal.net"));
0098     aboutData.addCredit(i18n("Liam Smit"), i18n("Ideas, help with the icons"), QStringLiteral("smitty@absamail.co.za"));
0099     aboutData.addCredit(i18n("Andrew Smith"), i18n("bkisofs code"), QString(), QStringLiteral("http://littlesvr.ca/misc/contactandrew.php"));
0100 
0101     KAboutData::setApplicationData(aboutData);
0102     application.setWindowIcon(QIcon::fromTheme(QStringLiteral("ark"), application.windowIcon()));
0103 
0104     QCommandLineParser parser;
0105 
0106     // Url to open.
0107     parser.addPositionalArgument(QStringLiteral("[urls]"), i18n("URLs to open."));
0108 
0109     parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("d") << QStringLiteral("dialog"),
0110                                         i18n("Show a dialog for specifying the options for the operation (extract/add)")));
0111 
0112     parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("o") << QStringLiteral("destination"),
0113                                         i18n("Destination folder to extract to. Defaults to current path if not specified."),
0114                                         QStringLiteral("directory")));
0115 
0116     parser.addOption(
0117         QCommandLineOption(QStringList() << QStringLiteral("O") << QStringLiteral("opendestination"), i18n("Open destination folder after extraction.")));
0118 
0119     parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("c") << QStringLiteral("add"),
0120                                         i18n("Query the user for an archive filename and add specified files to it. Quit when finished.")));
0121 
0122     parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("t") << QStringLiteral("add-to"),
0123                                         i18n("Add the specified files to 'filename'. Create archive if it does not exist. Quit when finished."),
0124                                         QStringLiteral("filename")));
0125 
0126     parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("p") << QStringLiteral("changetofirstpath"),
0127                                         i18n("Change the current dir to the first entry and add all other entries relative to this one.")));
0128 
0129     parser.addOption(
0130         QCommandLineOption(QStringList() << QStringLiteral("f") << QStringLiteral("autofilename"),
0131                            i18n("Automatically choose a filename, with the selected suffix (for example rar, tar.gz, zip or any other supported types)"),
0132                            QStringLiteral("suffix")));
0133 
0134     parser.addOption(
0135         QCommandLineOption(QStringList() << QStringLiteral("b") << QStringLiteral("batch"),
0136                            i18n("Use the batch interface instead of the usual dialog. This option is implied if more than one url is specified.")));
0137 
0138     parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("e") << QStringLiteral("autodestination"),
0139                                         i18n("The destination argument will be set to the path of the first file supplied.")));
0140 
0141     parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("a") << QStringLiteral("autosubfolder"),
0142                                         i18n("Archive contents will be read, and if detected to not be a single folder or a single file archive, a subfolder "
0143                                              "with the name of the archive will be created.")));
0144 
0145     parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("m") << QStringLiteral("mimetypes"), i18n("List supported MIME types.")));
0146 
0147     aboutData.setupCommandLine(&parser);
0148 
0149     // Do the command line parsing.
0150     parser.process(application);
0151 
0152     // Handle standard options.
0153     aboutData.processCommandLine(&parser);
0154 
0155     // This is needed to prevent Dolphin from freezing when opening an archive.
0156     KDBusService dbusService(KDBusService::Multiple | KDBusService::NoExitOnFailure);
0157 
0158     // Session restoring.
0159     if (application.isSessionRestored()) {
0160         if (!KMainWindow::canBeRestored(1)) {
0161             return -1;
0162         }
0163 
0164         MainWindow *window = new MainWindow;
0165         window->restore(1);
0166         if (!window->loadPart()) {
0167             delete window;
0168             return -1;
0169         }
0170     } else { // New ark window (no restored session).
0171 
0172         // Open any given URLs.
0173         const QStringList urls = parser.positionalArguments();
0174 
0175         if (parser.isSet(QStringLiteral("add")) || parser.isSet(QStringLiteral("add-to"))) {
0176             if (urls.isEmpty()) {
0177                 std::cout << "Missing arguments: urls." << std::endl;
0178                 parser.showHelp(-1);
0179             }
0180 
0181             AddToArchive *addToArchiveJob = new AddToArchive(&application);
0182             application.setQuitOnLastWindowClosed(false);
0183             QObject::connect(addToArchiveJob, &KJob::result, &application, &QCoreApplication::quit, Qt::QueuedConnection);
0184 
0185             if (parser.isSet(QStringLiteral("changetofirstpath"))) {
0186                 qCDebug(ARK) << "Setting changetofirstpath";
0187                 addToArchiveJob->setChangeToFirstPath(true);
0188             }
0189 
0190             if (parser.isSet(QStringLiteral("add-to"))) {
0191                 qCDebug(ARK) << "Setting filename to" << parser.value(QStringLiteral("add-to"));
0192                 addToArchiveJob->setFilename(QUrl::fromUserInput(parser.value(QStringLiteral("add-to")), QDir::currentPath(), QUrl::AssumeLocalFile));
0193             }
0194 
0195             if (parser.isSet(QStringLiteral("autofilename"))) {
0196                 qCDebug(ARK) << "Setting autofilename to" << parser.value(QStringLiteral("autofilename"));
0197                 addToArchiveJob->setAutoFilenameSuffix(parser.value(QStringLiteral("autofilename")));
0198             }
0199 
0200             for (int i = 0; i < urls.count(); ++i) {
0201                 // TODO: use the returned value here?
0202                 qCDebug(ARK) << "Adding url" << QUrl::fromUserInput(urls.at(i), QDir::currentPath(), QUrl::AssumeLocalFile);
0203                 addToArchiveJob->addInput(QUrl::fromUserInput(urls.at(i), QDir::currentPath(), QUrl::AssumeLocalFile));
0204             }
0205 
0206             if (parser.isSet(QStringLiteral("dialog"))) {
0207                 qCDebug(ARK) << "Using kerfuffle to open add dialog";
0208                 if (!addToArchiveJob->showAddDialog(nullptr)) {
0209                     return 0;
0210                 }
0211             }
0212 
0213             addToArchiveJob->start();
0214 
0215         } else if (parser.isSet(QStringLiteral("batch"))) {
0216             if (urls.isEmpty()) {
0217                 qCDebug(ARK) << "No urls to be extracted were provided.";
0218                 parser.showHelp(-1);
0219             }
0220 
0221             BatchExtract *batchJob = new BatchExtract(&application);
0222             application.setQuitOnLastWindowClosed(false);
0223             QObject::connect(batchJob, &KJob::result, &application, &QCoreApplication::quit, Qt::QueuedConnection);
0224 
0225             for (int i = 0; i < urls.count(); ++i) {
0226                 qCDebug(ARK) << "Adding url" << QUrl::fromUserInput(urls.at(i), QDir::currentPath(), QUrl::AssumeLocalFile);
0227                 batchJob->addInput(QUrl::fromUserInput(urls.at(i), QDir::currentPath(), QUrl::AssumeLocalFile));
0228             }
0229 
0230             if (parser.isSet(QStringLiteral("autosubfolder"))) {
0231                 qCDebug(ARK) << "Setting autosubfolder";
0232                 batchJob->setAutoSubfolder(true);
0233             }
0234 
0235             if (parser.isSet(QStringLiteral("autodestination"))) {
0236                 QString autopath = QFileInfo(QUrl::fromUserInput(urls.at(0), QDir::currentPath(), QUrl::AssumeLocalFile).path()).path();
0237                 qCDebug(ARK) << "By autodestination, setting path to " << autopath;
0238                 batchJob->setDestinationFolder(autopath);
0239             }
0240 
0241             if (parser.isSet(QStringLiteral("destination"))) {
0242                 qCDebug(ARK) << "Setting destination to " << parser.value(QStringLiteral("destination"));
0243                 batchJob->setDestinationFolder(parser.value(QStringLiteral("destination")));
0244             }
0245 
0246             if (parser.isSet(QStringLiteral("opendestination"))) {
0247                 qCDebug(ARK) << "Setting opendestination";
0248                 batchJob->setOpenDestinationAfterExtraction(true);
0249             }
0250 
0251             if (parser.isSet(QStringLiteral("dialog"))) {
0252                 qCDebug(ARK) << "Opening extraction dialog";
0253                 if (!batchJob->showExtractDialog()) {
0254                     return 0;
0255                 }
0256             }
0257 
0258             batchJob->start();
0259 
0260         } else if (parser.isSet(QStringLiteral("mimetypes"))) {
0261             Kerfuffle::PluginManager pluginManager;
0262             const auto mimeTypes = pluginManager.supportedMimeTypes();
0263             QTextStream cout(stdout);
0264             for (const auto &mimeType : mimeTypes) {
0265                 cout << mimeType << '\n';
0266             }
0267             return 0;
0268 
0269         } else {
0270             MainWindow *window = new MainWindow;
0271             if (!window->loadPart()) { // if loading the part fails
0272                 delete window;
0273                 return -1;
0274             }
0275 
0276             if (!urls.isEmpty()) {
0277                 qCDebug(ARK) << "Trying to open" << QUrl::fromUserInput(urls.at(0), QDir::currentPath(), QUrl::AssumeLocalFile);
0278 
0279                 if (parser.isSet(QStringLiteral("dialog"))) {
0280                     window->setShowExtractDialog(true);
0281                 }
0282                 window->openUrl(QUrl::fromUserInput(urls.at(0), QDir::currentPath(), QUrl::AssumeLocalFile));
0283             }
0284             new OpenFileEventHandler(&application, window);
0285             window->show();
0286         }
0287     }
0288 
0289     qCDebug(ARK) << "Entering application loop";
0290     return application.exec();
0291 }
0292 
0293 #include "main.moc"