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();
}