File indexing completed on 2024-04-28 05:47:34

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