Commit 2848dcd3 authored by Ragnar Thomsen's avatar Ragnar Thomsen

Redesign of CreateDialog

CreateDialog was completely redesigned. The KFileWidget is gone and replaced by
a KUrlRequester for the destination folder and a QLineEdit for the filename.
The encryption options are moved to a KCollapsibleGroupBox and further options
can be added in future KCollapsibleGroupBox's.

AddDialog is also gone and CreateDialog is now used directly instead.
parent 0b6215d7
......@@ -295,18 +295,15 @@ void MainWindow::newArchive()
QPointer<Kerfuffle::CreateDialog> dialog = new Kerfuffle::CreateDialog(
Q_NULLPTR, // parent
i18n("Create a new Archive"), // caption
i18n("Create New Archive"), // caption
QUrl()); // startDir
dialog.data()->show();
dialog.data()->restoreWindowSize();
if (dialog.data()->exec()) {
const QUrl saveFileUrl = dialog.data()->selectedUrls().first();
const QUrl saveFileUrl = dialog.data()->selectedUrl();
const QString password = dialog.data()->password();
qCDebug(ARK) << "CreateDialog returned URL:" << saveFileUrl.toString();
qCDebug(ARK) << "CreateDialog returned mime:" << dialog.data()->currentFilterMimeType().name();
qCDebug(ARK) << "CreateDialog returned mime:" << dialog.data()->currentMimeType().name();
m_openArgs.metaData()[QStringLiteral("createNewArchive")] = QStringLiteral("true");
m_openArgs.metaData()[QStringLiteral("encryptionPassword")] = password;
......
......@@ -26,7 +26,11 @@
#include "createdialog.h"
#include "mimetypes.h"
#include <KCollapsibleGroupBox>
#include <QCheckBox>
#include <QComboBox>
#include <QLineEdit>
#include <QMimeDatabase>
#include <QTest>
......@@ -37,12 +41,75 @@ class CreateDialogTest : public QObject
Q_OBJECT
private Q_SLOTS:
void testBasicWidgets_data();
void testBasicWidgets();
void testEncryption_data();
void testEncryption();
void testHeaderEncryptionTooltip();
};
void CreateDialogTest::testBasicWidgets_data()
{
QTest::addColumn<QString>("mimeType");
QTest::newRow("tar") << QStringLiteral("application/x-tar");
QTest::newRow("targzip") << QStringLiteral("application/x-compressed-tar");
QTest::newRow("tarbzip") << QStringLiteral("application/x-bzip-compressed-tar");
QTest::newRow("tarZ") << QStringLiteral("application/x-tarz");
QTest::newRow("tarxz") << QStringLiteral("application/x-xz-compressed-tar");
QTest::newRow("tarlzma") << QStringLiteral("application/x-lzma-compressed-tar");
QTest::newRow("tarlzop") << QStringLiteral("application/x-tzo");
QTest::newRow("tarlzip") << QStringLiteral("application/x-lzip-compressed-tar");
const auto writeMimeTypes = supportedWriteMimeTypes();
if (writeMimeTypes.contains(QStringLiteral("application/zip"))) {
QTest::newRow("zip") << QStringLiteral("application/zip");
} else {
qDebug() << "zip format not available in CreateDialog, skipping test.";
}
if (writeMimeTypes.contains(QStringLiteral("application/x-7z-compressed"))) {
QTest::newRow("7z") << QStringLiteral("application/x-7z-compressed");
} else {
qDebug() << "7z format not available in CreateDialog, skipping test.";
}
if (writeMimeTypes.contains(QStringLiteral("application/x-rar"))) {
QTest::newRow("rar") << QStringLiteral("application/x-rar");
} else {
qDebug() << "rar format not available in CreateDialog, skipping test.";
}
if (writeMimeTypes.contains(QStringLiteral("application/x-lrzip-compressed-tar"))) {
QTest::newRow("tarlrzip") << QStringLiteral("application/x-lrzip-compressed-tar");
} else {
qDebug() << "tar.lrzip format not available in CreateDialog, skipping test.";
}
}
void CreateDialogTest::testBasicWidgets()
{
CreateDialog *dialog = new CreateDialog(Q_NULLPTR, QString(), QUrl());
auto fileNameLineEdit = dialog->findChild<QLineEdit*>(QStringLiteral("filenameLineEdit"));
auto archiveTypeComboBox = dialog->findChild<QComboBox*>(QStringLiteral("mimeComboBox"));
QVERIFY(fileNameLineEdit);
QVERIFY(archiveTypeComboBox);
QFETCH(QString, mimeType);
const QMimeType mime = QMimeDatabase().mimeTypeForName(mimeType);
// Test if combobox is updated when user enters a filename with suffix.
fileNameLineEdit->setText(QStringLiteral("basename.%1").arg(mime.preferredSuffix()));
QCOMPARE(archiveTypeComboBox->currentText(), mime.comment());
// Test if suffix is added correctly when the user selects an archive type in combobox.
fileNameLineEdit->setText(QStringLiteral("basename"));
archiveTypeComboBox->setCurrentText(mime.comment());
QCOMPARE(QFileInfo(dialog->selectedUrl().toLocalFile()).fileName(), QStringLiteral("basename.%1").arg(mime.preferredSuffix()));
}
void CreateDialogTest::testEncryption_data()
{
QTest::addColumn<QString>("filter");
......@@ -78,12 +145,12 @@ void CreateDialogTest::testEncryption()
QFETCH(bool, isEncryptionAvailable);
QFETCH(bool, isHeaderEncryptionAvailable);
auto encryptCheckBox = dialog->findChild<QCheckBox*>(QStringLiteral("encryptCheckBox"));
auto collapsibleEncryption = dialog->findChild<KCollapsibleGroupBox*>(QStringLiteral("collapsibleEncryption"));
auto encryptHeaderCheckBox = dialog->findChild<QCheckBox*>(QStringLiteral("encryptHeaderCheckBox"));
QVERIFY(encryptCheckBox);
QVERIFY(collapsibleEncryption);
QVERIFY(encryptHeaderCheckBox);
dialog->setCurrentFilterFromMimeType(filter);
QVERIFY(dialog->setMimeType(filter));
// Encryption is initially not enabled.
QVERIFY(!dialog->isEncryptionEnabled());
......@@ -92,7 +159,7 @@ void CreateDialogTest::testEncryption()
if (isEncryptionAvailable) {
QVERIFY(dialog->isEncryptionAvailable());
encryptCheckBox->setChecked(true);
collapsibleEncryption->setExpanded(true);
QVERIFY(dialog->isEncryptionEnabled());
if (isHeaderEncryptionAvailable) {
......@@ -106,7 +173,7 @@ void CreateDialogTest::testEncryption()
QVERIFY(!dialog->isHeaderEncryptionAvailable());
}
encryptCheckBox->setChecked(false);
collapsibleEncryption->setExpanded(false);
QVERIFY(!dialog->isEncryptionEnabled());
QVERIFY(!dialog->isHeaderEncryptionEnabled());
} else {
......@@ -125,18 +192,18 @@ void CreateDialogTest::testHeaderEncryptionTooltip()
CreateDialog *dialog = new CreateDialog(Q_NULLPTR, QString(), QUrl());
auto encryptCheckBox = dialog->findChild<QCheckBox*>(QStringLiteral("encryptCheckBox"));
auto collapsibleEncryption = dialog->findChild<KCollapsibleGroupBox*>(QStringLiteral("collapsibleEncryption"));
auto encryptHeaderCheckBox = dialog->findChild<QCheckBox*>(QStringLiteral("encryptHeaderCheckBox"));
QVERIFY(encryptCheckBox);
QVERIFY(collapsibleEncryption);
QVERIFY(encryptHeaderCheckBox);
encryptCheckBox->setChecked(true);
collapsibleEncryption->setExpanded(true);
dialog->setCurrentFilterFromMimeType(QStringLiteral("application/zip"));
QVERIFY(dialog->setMimeType(QStringLiteral("application/zip")));
QVERIFY(!encryptHeaderCheckBox->toolTip().isEmpty());
// If we set a tar filter after the zip one, ensure that the old zip's tooltip is not shown anymore.
dialog->setCurrentFilterFromMimeType(QStringLiteral("application/x-compressed-tar"));
QVERIFY(dialog->setMimeType(QStringLiteral("application/x-compressed-tar")));
QVERIFY(encryptHeaderCheckBox->toolTip().isEmpty());
}
......
......@@ -9,7 +9,6 @@ set(kerfuffle_SRCS
jobs.cpp
createdialog.cpp
extractiondialog.cpp
adddialog.cpp
propertiesdialog.cpp
queries.cpp
addtoarchive.cpp
......@@ -20,7 +19,6 @@ set(kerfuffle_SRCS
kconfig_add_kcfg_files(kerfuffle_SRCS settings.kcfgc)
ki18n_wrap_ui(kerfuffle_SRCS
adddialog.ui
createdialog.ui
extractiondialog.ui
extractionsettings.ui
......@@ -42,11 +40,11 @@ PUBLIC
KF5::Pty
KF5::Service
KF5::I18n
KF5::WidgetsAddons
PRIVATE
KF5::KIOCore
KF5::KIOWidgets
KF5::KIOFileWidgets
KF5::WidgetsAddons
)
......
/*
* ark -- archiver for the KDE project
*
* Copyright (C) 2008 Harald Hvaal <haraldhv@stud.ntnu.no>
* Copyright (C) 2009,2011 Raphael Kubo da Costa <rakuco@FreeBSD.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ( INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "adddialog.h"
#include "ark_debug.h"
#include "ui_adddialog.h"
#include "kerfuffle/archive_kerfuffle.h"
#include <KFilePlacesModel>
#include <KFileWidget>
#include <QDir>
#include <QFileInfo>
#include <QMimeDatabase>
#include <QStandardItemModel>
namespace Kerfuffle
{
class AddDialogUI: public QWidget, public Ui::AddDialog
{
public:
AddDialogUI(QWidget *parent = 0)
: QWidget(parent) {
setupUi(this);
}
};
AddDialog::AddDialog(QWidget *parent,
const QString &caption,
const QUrl &startDir,
const QStringList &itemsToAdd)
: CreateDialog(parent, caption, startDir)
{
qCDebug(ARK) << "AddDialog loaded";
m_ui = new AddDialogUI(this);
m_vlayout->addWidget(m_ui);
setupIconList(itemsToAdd);
// Set up a default name if there's only one file to compress
if (itemsToAdd.size() == 1) {
const QFileInfo fileInfo(itemsToAdd.first());
const QString fileName =
fileInfo.isDir() ? fileInfo.dir().dirName() : fileInfo.baseName();
m_fileWidget->setSelection(fileName);
}
}
void AddDialog::setupIconList(const QStringList& itemsToAdd)
{
QStandardItemModel* listModel = new QStandardItemModel(this);
QStringList sortedList(itemsToAdd);
sortedList.sort();
Q_FOREACH(const QString& urlString, sortedList) {
QUrl url(urlString);
QStandardItem* item = new QStandardItem;
item->setText(url.fileName());
QMimeDatabase db;
QString iconName = db.mimeTypeForUrl(url).iconName();
item->setIcon(QIcon::fromTheme(iconName));
item->setData(QVariant(url), KFilePlacesModel::UrlRole);
listModel->appendRow(item);
}
m_ui->compressList->setModel(listModel);
}
}
/*
* ark -- archiver for the KDE project
*
* Copyright (C) 2008 Harald Hvaal <haraldhv@stud.ntnu.no>
* Copyright (C) 2009 Raphael Kubo da Costa <rakuco@FreeBSD.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ( INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef ADDDIALOG_H
#define ADDDIALOG_H
#include "createdialog.h"
#include "kerfuffle_export.h"
namespace Kerfuffle
{
class KERFUFFLE_EXPORT AddDialog : public CreateDialog
{
Q_OBJECT
public:
AddDialog(QWidget *parent,
const QString &caption,
const QUrl &startDir,
const QStringList &itemsToAdd);
private:
class AddDialogUI *m_ui;
void setupIconList(const QStringList& itemsToAdd);
};
}
#endif
......@@ -28,8 +28,8 @@
#include "addtoarchive.h"
#include "ark_debug.h"
#include "adddialog.h"
#include "archive_kerfuffle.h"
#include "createdialog.h"
#include "jobs.h"
#include <KConfig>
......@@ -89,21 +89,18 @@ bool AddToArchive::showAddDialog()
{
qCDebug(ARK) << "Opening add dialog";
QPointer<Kerfuffle::AddDialog> dialog = new Kerfuffle::AddDialog(
QPointer<Kerfuffle::CreateDialog> dialog = new Kerfuffle::CreateDialog(
Q_NULLPTR, // parent
i18n("Compress to Archive"), // caption
QUrl::fromLocalFile(m_firstPath), // startDir
m_inputs); // itemsToAdd
QUrl::fromLocalFile(m_firstPath)); // startDir
dialog.data()->show();
dialog.data()->restoreWindowSize();
bool ret = dialog.data()->exec();
if (ret) {
qCDebug(ARK) << "AddDialog returned URL:" << dialog.data()->selectedUrls().at(0).toString();
qCDebug(ARK) << "AddDialog returned mime:" << dialog.data()->currentFilterMimeType().name();
setFilename(dialog.data()->selectedUrls().at(0));
setMimeType(dialog.data()->currentFilterMimeType().name());
qCDebug(ARK) << "CreateDialog returned URL:" << dialog.data()->selectedUrl().toString();
qCDebug(ARK) << "CreateDialog returned mime:" << dialog.data()->currentMimeType().name();
setFilename(dialog.data()->selectedUrl());
setMimeType(dialog.data()->currentMimeType().name());
setPassword(dialog.data()->password());
setHeaderEncryptionEnabled(dialog.data()->isHeaderEncryptionEnabled());
}
......
This diff is collapsed.
......@@ -4,6 +4,7 @@
* Copyright (C) 2008 Harald Hvaal <haraldhv@stud.ntnu.no>
* Copyright (C) 2009 Raphael Kubo da Costa <rakuco@FreeBSD.org>
* Copyright (C) 2015 Elvis Angelaccio <elvis.angelaccio@kdemail.net>
* Copyright (C) 2016 Ragnar Thomsen <rthomsen6@gmail.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
......@@ -37,35 +38,12 @@
#include <QDialog>
#include <QMimeType>
class KFileWidget;
class QUrl;
class QVBoxLayout;
namespace Kerfuffle
{
class KERFUFFLE_EXPORT ArchiveTypeFilter
{
public:
explicit ArchiveTypeFilter(const QMimeType &newMimeType,
const QStringList &newGlobPatterns = QStringList(),
const QString &newComment = QStringLiteral(""));
QMimeType mimeType;
QStringList globPatterns;
QString comment;
// Enables sorting.
bool operator<(const ArchiveTypeFilter& right) const
{
return (comment < right.comment);
}
// Enables comparison.
bool operator==(const ArchiveTypeFilter& right) const
{
return (mimeType == right.mimeType);
}
};
class KERFUFFLE_EXPORT CreateDialog : public QDialog
{
Q_OBJECT
......@@ -74,12 +52,10 @@ public:
explicit CreateDialog(QWidget *parent,
const QString &caption,
const QUrl &startDir);
QSize sizeHint() const Q_DECL_OVERRIDE;
QList<QUrl> selectedUrls() const;
QUrl selectedUrl() const;
QString password() const;
QMimeType currentFilterMimeType() const;
void setCurrentFilterFromMimeType(const QString &mimeType);
QMimeType currentMimeType() const;
bool setMimeType(const QString &mimeTypeName);
/**
* @return Whether the user can encrypt the new archive.
......@@ -103,27 +79,21 @@ public:
public slots:
virtual void accept() Q_DECL_OVERRIDE;
void restoreWindowSize();
protected slots:
void slotSaveWindowSize();
void slotOkButtonClicked();
void slotEncryptionToggled(bool checked);
void slotFilterChanged(int index);
void slotUpdateDefaultMimeType();
private:
void loadConfiguration();
protected:
class CreateDialogUI *m_ui;
QVBoxLayout *m_vlayout;
KConfigGroup m_config;
KFileWidget *m_fileWidget;
void loadConfiguration();
QStringList m_supportedMimeTypes;
private:
QString filterFromMimeTypes(const QSet<QString> &mimeTypes);
QList<ArchiveTypeFilter> m_filterList;
private slots:
void slotFileNameEdited(const QString &text);
void slotUpdateWidgets(int index);
void slotEncryptionToggled();
void slotUpdateDefaultMimeType();
void slotUpdateFilenameExtension(int index);
};
}
......
......@@ -6,50 +6,119 @@
<rect>
<x>0</x>
<y>0</y>
<width>799</width>
<height>496</height>
<width>502</width>
<height>228</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<width>400</width>
<height>0</height>
</size>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<item>
<widget class="QCheckBox" name="encryptCheckBox">
<property name="text">
<string>Protect the archive with a password</string>
<layout class="QFormLayout" name="formLayout">
<property name="sizeConstraint">
<enum>QLayout::SetFixedSize</enum>
</property>
</widget>
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Folder:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="KUrlRequester" name="destFolderUrlRequester">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Filename:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="filenameLineEdit">
<property name="placeholderText">
<string>Type archive name...</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Type:</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QComboBox" name="mimeComboBox">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QCheckBox" name="chkAddExtension">
<property name="text">
<string notr="true">Automatically add filename extension (extension)</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Extension:</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QGroupBox" name="groupEncryptionOptions">
<widget class="KCollapsibleGroupBox" name="collapsibleEncryption">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="layoutDirection">
<enum>Qt::LeftToRight</enum>
</property>
<property name="title">
<string>Password options</string>
<string>Password Protection</string>
</property>
<property name="expanded">
<bool>false</bool>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="KNewPasswordWidget" name="pwdWidget" native="true"/>
<widget class="KNewPasswordWidget" name="pwdWidget" native="true">
<property name="enabled">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="encryptHeaderCheckBox">
<property name="enabled">
<bool>false</bool>
</property>
<property name="layoutDirection">
<enum>Qt::LeftToRight</enum>
</property>
......@@ -61,25 +130,37 @@
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>