diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index 03e97359..bd3dab4d 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -1,84 +1,102 @@ add_subdirectory(icons) include_directories(${CMAKE_BINARY_DIR}) # for version.h generated by cmake include_directories(${CMAKE_SOURCE_DIR}/part) # for part's interface.h set(ark_SRCS batchextract.cpp main.cpp mainwindow.cpp ) ecm_qt_declare_logging_category(ark_SRCS HEADER ark_debug.h IDENTIFIER ARK CATEGORY_NAME ark.main) # For Mac and Windows. file(GLOB ICONS_SRCS "${CMAKE_CURRENT_SOURCE_DIR}/icons/*-apps-ark.png") include(ECMAddAppIcon) ecm_add_app_icon(ark_SRCS ICONS ${ICONS_SRCS}) add_executable( ark ${ark_SRCS} ) target_link_libraries(ark kerfuffle KF5::Crash KF5::DBusAddons KF5::KIOFileWidgets KF5::Parts) +# we provide our own Info.plist containing a simple "we open anything" instruction. +if(APPLE) + # own plist template + set_target_properties (ark PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/MacOSXBundleInfo.plist.in) + + # the MacOSX bundle display name property (CFBundleDisplayName) is not currently supported by cmake, + # so has to be set for all targets in this cmake file + set(MACOSX_BUNDLE_DISPLAY_NAME Ark) + set_target_properties(ark PROPERTIES MACOSX_BUNDLE_GUI_IDENTIFIER "org.kde.Ark") + set_target_properties(ark PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Ark") + set_target_properties(ark PROPERTIES MACOSX_BUNDLE_DISPLAY_NAME "Ark") + set_target_properties(ark PROPERTIES MACOSX_BUNDLE_INFO_STRING "Ark - KDE Archiving Tool") + set_target_properties(ark PROPERTIES MACOSX_BUNDLE_LONG_VERSION_STRING "Ark ${KDE_APPLICATIONS_VERSION}") + set_target_properties(ark PROPERTIES MACOSX_BUNDLE_SHORT_VERSION_STRING "${KDE_APPLICATIONS_VERSION}") + set_target_properties(ark PROPERTIES MACOSX_BUNDLE_BUNDLE_VERSION "${KDE_APPLICATIONS_VERSION}") + set_target_properties(ark PROPERTIES MACOSX_BUNDLE_COPYRIGHT "1997-2017, The Ark Developers") +endif() + # Remove duplicate mimetypes from list of supported formats. list(REMOVE_DUPLICATES SUPPORTED_ARK_MIMETYPES) configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/org.kde.ark.desktop.cmake ${CMAKE_CURRENT_BINARY_DIR}/org.kde.ark.desktop ) configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/ark_dndextract.desktop.cmake ${CMAKE_CURRENT_BINARY_DIR}/ark_dndextract.desktop ) install(TARGETS ark ${KDE_INSTALL_TARGETS_DEFAULT_ARGS}) install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/org.kde.ark.desktop DESTINATION ${KDE_INSTALL_APPDIR}) install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/org.kde.ark.appdata.xml DESTINATION ${KDE_INSTALL_METAINFODIR}) install(FILES arkui.rc DESTINATION ${KDE_INSTALL_KXMLGUI5DIR}/ark) ############ ark_extract_here plugin ############### set(extracthere_SRCS batchextract.cpp extractHereDndPlugin.cpp ark_debug.cpp) kcoreaddons_add_plugin(extracthere SOURCES ${extracthere_SRCS} INSTALL_NAMESPACE kf5/kio_dnd) kcoreaddons_desktop_to_json(extracthere ${CMAKE_CURRENT_BINARY_DIR}/ark_dndextract.desktop DEFAULT_SERVICE_TYPE) target_link_libraries(extracthere kerfuffle KF5::Parts KF5::KIOWidgets KF5::KIOFileWidgets) # compressfileitemaction plugin kcoreaddons_add_plugin(compressfileitemaction SOURCES compressfileitemaction.cpp JSON compressfileitemaction.json INSTALL_NAMESPACE "kf5/kfileitemaction") target_link_libraries(compressfileitemaction kerfuffle KF5::I18n KF5::KIOWidgets) # extractfileitemaction plugin kcoreaddons_add_plugin(extractfileitemaction SOURCES extractfileitemaction.cpp JSON extractfileitemaction.json INSTALL_NAMESPACE "kf5/kfileitemaction") target_link_libraries(extractfileitemaction kerfuffle KF5::I18n KF5::KIOWidgets) diff --git a/app/MacOSXBundleInfo.plist.in b/app/MacOSXBundleInfo.plist.in new file mode 100644 index 00000000..ab421eaf --- /dev/null +++ b/app/MacOSXBundleInfo.plist.in @@ -0,0 +1,55 @@ + + + + + NSPrincipalClass + NSApplication + NSHighResolutionCapable + True + CFBundleDevelopmentRegion + English + CFBundleExecutable + ${MACOSX_BUNDLE_EXECUTABLE_NAME} + CFBundleGetInfoString + ${MACOSX_BUNDLE_INFO_STRING} + CFBundleIconFile + ${MACOSX_BUNDLE_ICON_FILE} + CFBundleIdentifier + ${MACOSX_BUNDLE_GUI_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleLongVersionString + ${MACOSX_BUNDLE_LONG_VERSION_STRING} + CFBundleName + ${MACOSX_BUNDLE_BUNDLE_NAME} + CFBundlePackageType + APPL + CFBundleShortVersionString + ${MACOSX_BUNDLE_SHORT_VERSION_STRING} + CFBundleSignature + ???? + CFBundleVersion + ${MACOSX_BUNDLE_BUNDLE_VERSION} + CSResourcesFileMapped + + LSRequiresCarbon + + NSHumanReadableCopyright + ${MACOSX_BUNDLE_COPYRIGHT} + LSMultipleInstancesProhibited + + CFBundleDocumentTypes + + + CFBundleTypeExtensions + + * + + CFBundleTypeName + NSStringPboardType + CFBundleTypeRole + Editor + + + + diff --git a/app/main.cpp b/app/main.cpp index 02dafea8..03964006 100644 --- a/app/main.cpp +++ b/app/main.cpp @@ -1,302 +1,331 @@ /* * ark -- archiver for the KDE project * * Copyright (C) 2007 Henrique Pinto * Copyright (C) 2008-2009 Harald Hvaal * Copyright (C) 2015-2017 Ragnar Thomsen * * 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 "ark_version.h" #include "ark_debug.h" #include "mainwindow.h" #include "batchextract.h" #include "addtoarchive.h" #include #include #include #include +#include #include #include #include #include #include using Kerfuffle::AddToArchive; +class OpenFileEventHandler : public QObject +{ + Q_OBJECT +public: + OpenFileEventHandler(QApplication *parent, MainWindow *w) + : QObject(parent) + , m_window(w) + { + parent->installEventFilter(this); + } + + bool eventFilter(QObject *obj, QEvent *event) override + { + if (event->type() == QEvent::FileOpen) { + QFileOpenEvent *openEvent = static_cast(event); + qCDebug(ARK) << "File open event:" << openEvent->url() << "for window" << m_window; + m_window->openUrl(openEvent->url()); + return true; + } + return QObject::eventFilter(obj, event); + } +private: + MainWindow *m_window; +}; + int main(int argc, char **argv) { QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts); // Required for the webengine part. QApplication application(argc, argv); /** * enable high dpi support */ application.setAttribute(Qt::AA_UseHighDpiPixmaps, true); KCrash::initialize(); // Debug output can be turned on here: //QLoggingCategory::setFilterRules(QStringLiteral("ark.debug = true")); Kdelibs4ConfigMigrator migrate(QStringLiteral("ark")); migrate.setConfigFiles(QStringList() << QStringLiteral("arkrc")); migrate.setUiFiles(QStringList() << QStringLiteral("arkuirc")); migrate.migrate(); KLocalizedString::setApplicationDomain("ark"); KAboutData aboutData(QStringLiteral("ark"), i18n("Ark"), QStringLiteral(ARK_VERSION_STRING), i18n("KDE Archiving tool"), KAboutLicense::GPL, i18n("(c) 1997-2017, The Ark Developers"), QString(), QStringLiteral("http://utils.kde.org/projects/ark") ); aboutData.setOrganizationDomain("kde.org"); aboutData.addAuthor(i18n("Elvis Angelaccio"), i18n("Maintainer"), QStringLiteral("elvis.angelaccio@kde.org")); aboutData.addAuthor(i18n("Ragnar Thomsen"), i18n("Maintainer, KF5 port"), QStringLiteral("rthomsen6@gmail.com")); aboutData.addAuthor(i18n("Raphael Kubo da Costa"), i18n("Former Maintainer"), QStringLiteral("rakuco@FreeBSD.org")); aboutData.addAuthor(i18n("Harald Hvaal"), i18n("Former Maintainer"), QStringLiteral("haraldhv@stud.ntnu.no")); aboutData.addAuthor(i18n("Henrique Pinto"), i18n("Former Maintainer"), QStringLiteral("henrique.pinto@kdemail.net")); aboutData.addAuthor(i18n("Helio Chissini de Castro"), i18n("Former maintainer"), QStringLiteral("helio@kde.org")); aboutData.addAuthor(i18n("Georg Robbers"), QString(), QStringLiteral("Georg.Robbers@urz.uni-hd.de")); aboutData.addAuthor(i18n("Roberto Selbach Teixeira"), QString(), QStringLiteral("maragato@kde.org")); aboutData.addAuthor(i18n("Francois-Xavier Duranceau"), QString(), QStringLiteral("duranceau@kde.org")); aboutData.addAuthor(i18n("Emily Ezust (Corel Corporation)"), QString(), QStringLiteral("emilye@corel.com")); aboutData.addAuthor(i18n("Michael Jarrett (Corel Corporation)"), QString(), QStringLiteral("michaelj@corel.com")); aboutData.addAuthor(i18n("Robert Palmbos"), QString(), QStringLiteral("palm9744@kettering.edu")); aboutData.addCredit(i18n("Vladyslav Batyrenko"), i18n("Advanced editing functionalities"), QString(), QStringLiteral("http://mvlabat.github.io/ark-gsoc-2016/")); aboutData.addCredit(i18n("Bryce Corkins"), i18n("Icons"), QStringLiteral("dbryce@attglobal.net")); aboutData.addCredit(i18n("Liam Smit"), i18n("Ideas, help with the icons"), QStringLiteral("smitty@absamail.co.za")); aboutData.addCredit(i18n("Andrew Smith"), i18n("bkisofs code"), QString(), QStringLiteral("http://littlesvr.ca/misc/contactandrew.php")); KAboutData::setApplicationData(aboutData); - application.setWindowIcon(QIcon::fromTheme(QStringLiteral("ark"))); + application.setWindowIcon(QIcon::fromTheme(QStringLiteral("ark"), application.windowIcon())); QCommandLineParser parser; parser.addHelpOption(); parser.addVersionOption(); // Url to open. parser.addPositionalArgument(QStringLiteral("[urls]"), i18n("URLs to open.")); parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("d") << QStringLiteral("dialog"), i18n("Show a dialog for specifying the options for the operation (extract/add)"))); parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("o") << QStringLiteral("destination"), i18n("Destination folder to extract to. Defaults to current path if not specified."), QStringLiteral("directory"))); parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("O") << QStringLiteral("opendestination"), i18n("Open destination folder after extraction."))); parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("c") << QStringLiteral("add"), i18n("Query the user for an archive filename and add specified files to it. Quit when finished."))); parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("t") << QStringLiteral("add-to"), i18n("Add the specified files to 'filename'. Create archive if it does not exist. Quit when finished."), QStringLiteral("filename"))); parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("p") << QStringLiteral("changetofirstpath"), i18n("Change the current dir to the first entry and add all other entries relative to this one."))); parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("f") << QStringLiteral("autofilename"), i18n("Automatically choose a filename, with the selected suffix (for example rar, tar.gz, zip or any other supported types)"), QStringLiteral("suffix"))); parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("b") << QStringLiteral("batch"), i18n("Use the batch interface instead of the usual dialog. This option is implied if more than one url is specified."))); parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("e") << QStringLiteral("autodestination"), i18n("The destination argument will be set to the path of the first file supplied."))); parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("a") << QStringLiteral("autosubfolder"), i18n("Archive contents will be read, and if detected to not be a single folder archive, a subfolder with the name of the archive will be created."))); aboutData.setupCommandLine(&parser); // Do the command line parsing. parser.process(application); // Handle standard options. aboutData.processCommandLine(&parser); // This is needed to prevent Dolphin from freezing when opening an archive. KDBusService dbusService(KDBusService::Multiple | KDBusService::NoExitOnFailure); // Session restoring. if (application.isSessionRestored()) { if (!KMainWindow::canBeRestored(1)) { return -1; } MainWindow* window = new MainWindow; window->restore(1); if (!window->loadPart()) { delete window; return -1; } } else { // New ark window (no restored session). // Open any given URLs. const QStringList urls = parser.positionalArguments(); if (parser.isSet(QStringLiteral("add")) || parser.isSet(QStringLiteral("add-to"))) { AddToArchive *addToArchiveJob = new AddToArchive(&application); application.setQuitOnLastWindowClosed(false); QObject::connect(addToArchiveJob, &KJob::result, &application, &QCoreApplication::quit, Qt::QueuedConnection); if (parser.isSet(QStringLiteral("changetofirstpath"))) { qCDebug(ARK) << "Setting changetofirstpath"; addToArchiveJob->setChangeToFirstPath(true); } if (parser.isSet(QStringLiteral("add-to"))) { qCDebug(ARK) << "Setting filename to" << parser.value(QStringLiteral("add-to")); addToArchiveJob->setFilename(QUrl::fromUserInput(parser.value(QStringLiteral("add-to")), QString(), QUrl::AssumeLocalFile)); } if (parser.isSet(QStringLiteral("autofilename"))) { qCDebug(ARK) << "Setting autofilename to" << parser.value(QStringLiteral("autofilename")); addToArchiveJob->setAutoFilenameSuffix(parser.value(QStringLiteral("autofilename"))); } for (int i = 0; i < urls.count(); ++i) { //TODO: use the returned value here? qCDebug(ARK) << "Adding url" << QUrl::fromUserInput(urls.at(i), QString(), QUrl::AssumeLocalFile); addToArchiveJob->addInput(QUrl::fromUserInput(urls.at(i), QString(), QUrl::AssumeLocalFile)); } if (parser.isSet(QStringLiteral("dialog"))) { qCDebug(ARK) << "Using kerfuffle to open add dialog"; if (!addToArchiveJob->showAddDialog()) { return 0; } } addToArchiveJob->start(); } else if (parser.isSet(QStringLiteral("batch"))) { BatchExtract *batchJob = new BatchExtract(&application); application.setQuitOnLastWindowClosed(false); QObject::connect(batchJob, &KJob::result, &application, &QCoreApplication::quit, Qt::QueuedConnection); for (int i = 0; i < urls.count(); ++i) { qCDebug(ARK) << "Adding url" << QUrl::fromUserInput(urls.at(i), QString(), QUrl::AssumeLocalFile); batchJob->addInput(QUrl::fromUserInput(urls.at(i), QString(), QUrl::AssumeLocalFile)); } if (parser.isSet(QStringLiteral("autosubfolder"))) { qCDebug(ARK) << "Setting autosubfolder"; batchJob->setAutoSubfolder(true); } if (parser.isSet(QStringLiteral("autodestination"))) { QString autopath = QFileInfo(QUrl::fromUserInput(urls.at(0), QString(), QUrl::AssumeLocalFile).path()).path(); qCDebug(ARK) << "By autodestination, setting path to " << autopath; batchJob->setDestinationFolder(autopath); } if (parser.isSet(QStringLiteral("destination"))) { qCDebug(ARK) << "Setting destination to " << parser.value(QStringLiteral("destination")); batchJob->setDestinationFolder(parser.value(QStringLiteral("destination"))); } if (parser.isSet(QStringLiteral("opendestination"))) { qCDebug(ARK) << "Setting opendestination"; batchJob->setOpenDestinationAfterExtraction(true); } if (parser.isSet(QStringLiteral("dialog"))) { qCDebug(ARK) << "Opening extraction dialog"; if (!batchJob->showExtractDialog()) { return 0; } } batchJob->start(); } else { MainWindow *window = new MainWindow; if (!window->loadPart()) { // if loading the part fails delete window; return -1; } if (!urls.isEmpty()) { qCDebug(ARK) << "Trying to open" << QUrl::fromUserInput(urls.at(0), QString(), QUrl::AssumeLocalFile); if (parser.isSet(QStringLiteral("dialog"))) { window->setShowExtractDialog(true); } window->openUrl(QUrl::fromUserInput(urls.at(0), QString(), QUrl::AssumeLocalFile)); } + new OpenFileEventHandler(&application, window); window->show(); } } qCDebug(ARK) << "Entering application loop"; return application.exec(); } + +#include "main.moc" diff --git a/app/mainwindow.cpp b/app/mainwindow.cpp index 7b53458e..0a6b71e7 100644 --- a/app/mainwindow.cpp +++ b/app/mainwindow.cpp @@ -1,336 +1,338 @@ /* * ark -- archiver for the KDE project * * Copyright (C) 2002-2003: Georg Robbers * Copyright (C) 2003: Helio Chissini de Castro * Copyright (C) 2007 Henrique Pinto * Copyright (C) 2008 Harald Hvaal * * 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 "mainwindow.h" #include "ark_debug.h" #include "archive_kerfuffle.h" #include "createdialog.h" #include "settingsdialog.h" #include "settingspage.h" #include "pluginmanager.h" #include "interface.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include static bool isValidArchiveDrag(const QMimeData *data) { return ((data->hasUrls()) && (data->urls().count() == 1)); } MainWindow::MainWindow(QWidget *) : KParts::MainWindow() { setupActions(); setAcceptDrops(true); + // Ark doesn't provide a fullscreen mode; remove the corresponding window button + setWindowFlags(windowFlags() & ~Qt::WindowFullscreenButtonHint); } MainWindow::~MainWindow() { if (m_recentFilesAction) { m_recentFilesAction->saveEntries(KSharedConfig::openConfig()->group("Recent Files")); } guiFactory()->removeClient(m_part); delete m_part; m_part = nullptr; } void MainWindow::dragEnterEvent(QDragEnterEvent * event) { qCDebug(ARK) << "dragEnterEvent" << event; Interface *iface = qobject_cast(m_part); if (iface->isBusy()) { return; } if (!event->source() && isValidArchiveDrag(event->mimeData())) { event->acceptProposedAction(); } return; } void MainWindow::dropEvent(QDropEvent * event) { qCDebug(ARK) << "dropEvent" << event; Interface *iface = qobject_cast(m_part); if (iface->isBusy()) { return; } if ((event->source() == nullptr) && (isValidArchiveDrag(event->mimeData()))) { event->acceptProposedAction(); } //TODO: if this call provokes a message box the drag will still be going //while the box is onscreen. looks buggy, do something about it openUrl(event->mimeData()->urls().at(0)); } void MainWindow::dragMoveEvent(QDragMoveEvent * event) { qCDebug(ARK) << "dragMoveEvent" << event; Interface *iface = qobject_cast(m_part); if (iface->isBusy()) { return; } if ((event->source() == nullptr) && (isValidArchiveDrag(event->mimeData()))) { event->acceptProposedAction(); } } bool MainWindow::loadPart() { KPluginFactory *factory = nullptr; const auto plugins = KPluginLoader::findPlugins(QString(), [](const KPluginMetaData& metaData) { return metaData.pluginId() == QStringLiteral("arkpart") && metaData.serviceTypes().contains(QStringLiteral("KParts/ReadOnlyPart")) && metaData.serviceTypes().contains(QStringLiteral("Browser/View")); }); if (!plugins.isEmpty()) { factory = KPluginLoader(plugins.first().fileName()).factory(); } m_part = factory ? static_cast(factory->create(this)) : nullptr; if (!m_part) { KMessageBox::error(this, i18n("Unable to find Ark's KPart component, please check your installation.")); qCWarning(ARK) << "Error loading Ark KPart."; return false; } m_part->setObjectName(QStringLiteral("ArkPart")); setCentralWidget(m_part->widget()); setupGUI(ToolBar | Keys | Save, QStringLiteral("arkui.rc")); createGUI(m_part); statusBar()->hide(); connect(m_part, SIGNAL(ready()), this, SLOT(updateActions())); connect(m_part, SIGNAL(quit()), this, SLOT(quit())); // #365200: this will disable m_recentFilesAction, while openUrl() will enable it. // So updateActions() needs to be called after openUrl() returns. connect(m_part, SIGNAL(busy()), this, SLOT(updateActions()), Qt::QueuedConnection); return true; } void MainWindow::setupActions() { m_newAction = actionCollection()->addAction(KStandardAction::New, QStringLiteral("ark_file_new"), this, SLOT(newArchive())); m_openAction = actionCollection()->addAction(KStandardAction::Open, QStringLiteral("ark_file_open"), this, SLOT(openArchive())); actionCollection()->addAction(KStandardAction::Quit, QStringLiteral("ark_quit"), this, SLOT(quit())); m_recentFilesAction = KStandardAction::openRecent(this, SLOT(openUrl(QUrl)), nullptr); actionCollection()->addAction(QStringLiteral("ark_file_open_recent"), m_recentFilesAction); m_recentFilesAction->setToolBarMode(KRecentFilesAction::MenuMode); m_recentFilesAction->setToolButtonPopupMode(QToolButton::DelayedPopup); m_recentFilesAction->setIconText(i18nc("action, to open an archive", "Open")); m_recentFilesAction->setToolTip(i18n("Open an archive")); m_recentFilesAction->loadEntries(KSharedConfig::openConfig()->group("Recent Files")); KStandardAction::preferences(this, SLOT(showSettings()), actionCollection()); } void MainWindow::updateActions() { Interface *iface = qobject_cast(m_part); m_newAction->setEnabled(!iface->isBusy()); m_openAction->setEnabled(!iface->isBusy()); m_recentFilesAction->setEnabled(!iface->isBusy()); } void MainWindow::openArchive() { Interface *iface = qobject_cast(m_part); Q_ASSERT(iface); Q_UNUSED(iface); Kerfuffle::PluginManager pluginManager; auto dlg = new QFileDialog(this, i18nc("to open an archive", "Open Archive")); dlg->setMimeTypeFilters(pluginManager.supportedMimeTypes(Kerfuffle::PluginManager::SortByComment)); dlg->setFileMode(QFileDialog::ExistingFile); dlg->setAcceptMode(QFileDialog::AcceptOpen); connect(dlg, &QDialog::finished, this, [this, dlg](int result) { if (result == QDialog::Accepted) { openUrl(dlg->selectedUrls().at(0)); } dlg->deleteLater(); }); dlg->open(); } void MainWindow::openUrl(const QUrl& url) { if (!url.isEmpty()) { m_part->setArguments(m_openArgs); if (m_part->openUrl(url)) { m_recentFilesAction->addUrl(url); } else { m_recentFilesAction->removeUrl(url); } } } void MainWindow::setShowExtractDialog(bool option) { if (option) { m_openArgs.metaData()[QStringLiteral("showExtractDialog")] = QStringLiteral("true"); } else { m_openArgs.metaData().remove(QStringLiteral("showExtractDialog")); } } void MainWindow::closeEvent(QCloseEvent *event) { // Preview windows don't have a parent, so we need to manually close them. foreach (QWidget *widget, qApp->topLevelWidgets()) { if (widget->isVisible()) { widget->close(); } } KParts::MainWindow::closeEvent(event); } void MainWindow::quit() { close(); } void MainWindow::showSettings() { Interface *iface = qobject_cast(m_part); Q_ASSERT(iface); auto dialog = new Kerfuffle::SettingsDialog(this, QStringLiteral("settings"), iface->config()); foreach (Kerfuffle::SettingsPage *page, iface->settingsPages(this)) { dialog->addPage(page, page->name(), page->iconName()); connect(dialog, &KConfigDialog::settingsChanged, page, &Kerfuffle::SettingsPage::slotSettingsChanged); connect(dialog, &Kerfuffle::SettingsDialog::defaultsButtonClicked, page, &Kerfuffle::SettingsPage::slotDefaultsButtonClicked); } // Hide the icons list if only one page has been added. dialog->setFaceType(KPageDialog::Auto); connect(dialog, &KConfigDialog::settingsChanged, this, &MainWindow::writeSettings); dialog->show(); } void MainWindow::writeSettings() { Interface *iface = qobject_cast(m_part); Q_ASSERT(iface); iface->config()->save(); } void MainWindow::newArchive() { qCDebug(ARK) << "Creating new archive"; Interface *iface = qobject_cast(m_part); Q_ASSERT(iface); Q_UNUSED(iface); QPointer dialog = new Kerfuffle::CreateDialog( nullptr, // parent i18n("Create New Archive"), // caption QUrl()); // startDir if (dialog.data()->exec()) { const QUrl saveFileUrl = dialog.data()->selectedUrl(); const QString password = dialog.data()->password(); const QString fixedMimeType = dialog.data()->currentMimeType().name(); qCDebug(ARK) << "CreateDialog returned URL:" << saveFileUrl.toString(); qCDebug(ARK) << "CreateDialog returned mime:" << fixedMimeType; m_openArgs.metaData()[QStringLiteral("createNewArchive")] = QStringLiteral("true"); m_openArgs.metaData()[QStringLiteral("fixedMimeType")] = fixedMimeType; if (dialog.data()->compressionLevel() > -1) { m_openArgs.metaData()[QStringLiteral("compressionLevel")] = QString::number(dialog.data()->compressionLevel()); } if (dialog.data()->volumeSize() > 0) { qCDebug(ARK) << "Setting volume size:" << QString::number(dialog.data()->volumeSize()); m_openArgs.metaData()[QStringLiteral("volumeSize")] = QString::number(dialog.data()->volumeSize()); } if (!dialog.data()->compressionMethod().isEmpty()) { m_openArgs.metaData()[QStringLiteral("compressionMethod")] = dialog.data()->compressionMethod(); } if (!dialog.data()->encryptionMethod().isEmpty()) { m_openArgs.metaData()[QStringLiteral("encryptionMethod")] = dialog.data()->encryptionMethod(); } m_openArgs.metaData()[QStringLiteral("encryptionPassword")] = password; if (dialog.data()->isHeaderEncryptionEnabled()) { m_openArgs.metaData()[QStringLiteral("encryptHeader")] = QStringLiteral("true"); } openUrl(saveFileUrl); m_openArgs.metaData().remove(QStringLiteral("showExtractDialog")); m_openArgs.metaData().remove(QStringLiteral("createNewArchive")); m_openArgs.metaData().remove(QStringLiteral("fixedMimeType")); m_openArgs.metaData().remove(QStringLiteral("compressionLevel")); m_openArgs.metaData().remove(QStringLiteral("encryptionPassword")); m_openArgs.metaData().remove(QStringLiteral("encryptHeader")); } delete dialog.data(); }