Commit b8c5f332 authored by Harald Sitter's avatar Harald Sitter 🏳️‍🌈
Browse files

port config dialog to qml

exact replicate of the qwidget variant
parent 9c73be82
Pipeline #276193 passed with stage
in 9 minutes and 16 seconds
......@@ -32,13 +32,11 @@ target_sources(filelight PRIVATE
radialMap/radialMap.cpp
scan.cpp
Config.cpp
settingsDialog.cpp
localLister.cpp
remoteLister.cpp
historyAction.cpp
mainContext.cpp
main.cpp
settingsDialog.h
fileTree.h
radialMap/map.h
radialMap/radialMap.h
......@@ -65,7 +63,6 @@ set(filelight_ICONS
)
ecm_add_app_icon(filelight ICONS
${filelight_ICONS})
ki18n_wrap_ui(filelight dialog.ui)
target_link_libraries(filelight
KF5::I18n
......
/***********************************************************************
* SPDX-FileCopyrightText: 2003-2004 Max Howell <max.howell@methylblue.com>
* SPDX-FileCopyrightText: 2008-2009 Martin Sandsmark <martin.sandsmark@kde.org>
* SPDX-FileCopyrightText: 2022 Harald Sitter <sitter@kde.org>
*
* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
***********************************************************************/
......@@ -9,20 +10,15 @@
#include <KConfig>
#include <KConfigGroup>
#include <KLocalizedString>
#include <KMessageBox>
#include <KSharedConfig>
#include <QDebug>
#include <QFileDialog>
#include <QFont>
bool Config::scanAcrossMounts;
bool Config::scanRemoteMounts;
bool Config::showSmallFiles;
uint Config::contrast;
uint Config::defaultRingDepth;
Filelight::MapScheme Config::scheme;
QStringList Config::skipList;
const QSet<QByteArray> Config::remoteFsTypes = {"smbfs", "nfs", "afs"};
void Filelight::Config::read()
void Config::read()
{
const KConfigGroup config = KSharedConfig::openConfig()->group("filelight_part");
......@@ -30,13 +26,13 @@ void Filelight::Config::read()
scanRemoteMounts = config.readEntry("scanRemoteMounts", false);
showSmallFiles = config.readEntry("showSmallFiles", false);
contrast = config.readEntry("contrast", 75);
scheme = (MapScheme)config.readEntry("scheme", 0);
scheme = (Filelight::MapScheme)config.readEntry("scheme", 0);
skipList = config.readEntry("skipList", QStringList());
defaultRingDepth = 4;
Q_EMIT changed();
}
void Filelight::Config::write()
void Config::write() const
{
KConfigGroup config = KSharedConfig::openConfig()->group("filelight_part");
......@@ -47,4 +43,39 @@ void Filelight::Config::write()
config.writeEntry("scheme", (int)scheme); // TODO: make the enum belong to a qwidget,
// and use magic macros to make it save this properly
config.writePathEntry("skipList", skipList);
config.sync();
}
Config *Config::instance()
{
static Config self;
return &self;
}
void Config::addFolder()
{
const QString urlString = QFileDialog::getExistingDirectory(nullptr, i18n("Select path to ignore"), QDir::rootPath());
const QUrl url = QUrl::fromLocalFile(urlString);
// TODO error handling!
// TODO wrong protocol handling!
if (!url.isEmpty()) {
const QString path = url.toLocalFile();
if (!skipList.contains(path)) {
skipList.append(path);
Q_EMIT changed();
} else {
KMessageBox::information(nullptr, i18n("That folder is already set to be excluded from scans."), i18n("Folder already ignored"));
}
}
}
void Config::removeFolder(const QString &url)
{
qDebug() << url;
skipList.removeAll(url);
Q_EMIT changed();
}
......@@ -12,35 +12,50 @@
#include <QSet>
#include <QStringList>
namespace Filelight
{
Q_NAMESPACE
enum class Dirty {
Layout = 1,
Colors = 3,
};
Q_DECLARE_METATYPE(Dirty);
Q_ENUM_NS(Dirty);
namespace Filelight
{
enum MapScheme { Rainbow, KDE, HighContrast };
Q_ENUM_NS(MapScheme)
} // namespace Filelight
class Config
Q_DECLARE_METATYPE(Filelight::Dirty);
class Config : public QObject
{
Q_OBJECT
Q_PROPERTY(bool scanAcrossMounts MEMBER scanAcrossMounts NOTIFY changed)
Q_PROPERTY(bool scanRemoteMounts MEMBER scanRemoteMounts NOTIFY changed)
Q_PROPERTY(bool showSmallFiles MEMBER showSmallFiles NOTIFY changed)
Q_PROPERTY(uint contrast MEMBER contrast NOTIFY changed)
Q_PROPERTY(uint defaultRingDepth MEMBER defaultRingDepth NOTIFY changed)
Q_PROPERTY(Filelight::MapScheme scheme MEMBER scheme NOTIFY changed)
Q_PROPERTY(QStringList skipList MEMBER skipList NOTIFY changed)
public:
static void read();
static void write();
static Config *instance();
void read();
Q_INVOKABLE void write() const;
Q_SIGNAL void changed();
Q_INVOKABLE void addFolder();
Q_INVOKABLE void removeFolder(const QString &url);
// keep everything positive, avoid using DON'T, NOT or NO
static bool scanAcrossMounts;
static bool scanRemoteMounts;
static bool showSmallFiles;
static uint contrast;
static uint defaultRingDepth;
bool scanAcrossMounts;
bool scanRemoteMounts;
bool showSmallFiles;
uint contrast;
uint defaultRingDepth = 4;
static MapScheme scheme;
static QStringList skipList;
Filelight::MapScheme scheme;
QStringList skipList;
static const QSet<QByteArray> remoteFsTypes;
const QSet<QByteArray> remoteFsTypes = {"smbfs", "nfs", "afs"};
};
} // namespace Filelight
using Filelight::Config;
......@@ -39,9 +39,9 @@ void ContextMenuContext::doNotScan(RadialMap::Segment *segment)
void ContextMenuContext::doNotScan(const QUrl &url)
{
if (!Config::skipList.contains(url.toLocalFile())) {
Config::skipList.append(url.toLocalFile());
Config::write();
if (!Config::instance()->skipList.contains(url.toLocalFile())) {
Config::instance()->skipList.append(url.toLocalFile());
Config::instance()->write();
}
}
......
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Dialog</class>
<widget class="QWidget" name="Dialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>556</width>
<height>405</height>
</rect>
</property>
<property name="windowTitle">
<string>Settings - Filelight</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QTabWidget" name="tabWidget">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="acceptDrops">
<bool>false</bool>
</property>
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="Widget2">
<attribute name="title">
<string>Scannin&amp;g</string>
</attribute>
<layout class="QVBoxLayout">
<item>
<widget class="QLabel" name="textLabel1">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Do &amp;not scan these folders:</string>
</property>
<property name="textFormat">
<enum>Qt::PlainText</enum>
</property>
<property name="wordWrap">
<bool>false</bool>
</property>
<property name="buddy">
<cstring>m_listBox</cstring>
</property>
</widget>
</item>
<item>
<widget class="QListWidget" name="m_listBox"/>
</item>
<item>
<layout class="QHBoxLayout">
<item>
<spacer name="m_removeAddSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>180</width>
<height>21</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="m_removeButton">
<property name="enabled">
<bool>true</bool>
</property>
<property name="text">
<string>R&amp;emove</string>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="m_addButton">
<property name="text">
<string>&amp;Add...</string>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
<property name="default">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="Line" name="m_scanningSeparatorLine">
<property name="minimumSize">
<size>
<width>0</width>
<height>15</height>
</size>
</property>
<property name="frameShape">
<enum>QFrame::HLine</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Sunken</enum>
</property>
<property name="lineWidth">
<number>1</number>
</property>
<property name="midLineWidth">
<number>1</number>
</property>
</widget>
</item>
<item>
<layout class="QGridLayout">
<item row="1" column="0" rowspan="2">
<spacer name="m_excludeCheckBoxSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>16</width>
<height>50</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="dontScanRemoteMounts">
<property name="enabled">
<bool>false</bool>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>32767</width>
<height>32767</height>
</size>
</property>
<property name="acceptDrops">
<bool>false</bool>
</property>
<property name="toolTip">
<string/>
</property>
<property name="whatsThis">
<string>Prevents scanning of filesystems that are not on this computer, e.g. NFS or Samba mounts.</string>
</property>
<property name="text">
<string>Exclude remote files&amp;ystems</string>
</property>
</widget>
</item>
<item row="0" column="0" colspan="2">
<widget class="QCheckBox" name="scanAcrossMounts">
<property name="whatsThis">
<string>Allows scans to enter directories that are part of other filesystems. For example, when unchecked, this will usually prevent the contents of &lt;b&gt;/mnt&lt;/b&gt; from being scanned if you scan &lt;b&gt;/&lt;/b&gt;.</string>
</property>
<property name="text">
<string>Scan across filesystem &amp;boundaries</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<widget class="QWidget" name="Widget3">
<attribute name="title">
<string>&amp;Appearance</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QGroupBox" name="groupBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Color scheme</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QVBoxLayout" name="colorSchemeLayout"/>
</item>
<item>
<layout class="QHBoxLayout">
<property name="spacing">
<number>0</number>
</property>
<property name="sizeConstraint">
<enum>QLayout::SetNoConstraint</enum>
</property>
<property name="topMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="textLabel3">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Co&amp;ntrast</string>
</property>
<property name="textFormat">
<enum>Qt::PlainText</enum>
</property>
<property name="wordWrap">
<bool>false</bool>
</property>
<property name="buddy">
<cstring>contrastSlider</cstring>
</property>
</widget>
</item>
<item>
<widget class="QSlider" name="contrastSlider">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="whatsThis">
<string>Here you can vary the contrast of the filemap in realtime.</string>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>100</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QCheckBox" name="showSmallFiles">
<property name="whatsThis">
<string>Some files are too small to be rendered on the filemap. Selecting this option makes these files visible by merging them all into a single &quot;multi-segment&quot;.</string>
</property>
<property name="text">
<string>Show small files</string>
</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>
</widget>
</widget>
</item>
</layout>
</widget>
<layoutdefault spacing="6" margin="11"/>
<tabstops>
<tabstop>tabWidget</tabstop>
<tabstop>m_removeButton</tabstop>
<tabstop>m_addButton</tabstop>
<tabstop>scanAcrossMounts</tabstop>
<tabstop>dontScanRemoteMounts</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>
......@@ -34,11 +34,11 @@ LocalLister::LocalLister(const QString &path, QList<std::shared_ptr<Folder>> *ca
// add empty directories for any mount points that are in the path
// TODO empty directories is not ideal as adds to fileCount incorrectly
QStringList list(Config::skipList);
if (!Config::scanAcrossMounts) {
QStringList list(Config::instance()->skipList);
if (!Config::instance()->scanAcrossMounts) {
list += s_localMounts;
}
if (!Config::scanRemoteMounts) {
if (!Config::instance()->scanRemoteMounts) {
list += s_remoteMounts;
}
......@@ -164,7 +164,7 @@ void LocalLister::readMounts()
path += QLatin1Char('/');
}
if (Config::remoteFsTypes.contains(storage.fileSystemType()) && !s_remoteMounts.contains(path)) {
if (Config::instance()->remoteFsTypes.contains(storage.fileSystemType()) && !s_remoteMounts.contains(path)) {
s_remoteMounts.append(path);
} else if (!s_localMounts.contains(path)) {
s_localMounts.append(path);
......
......@@ -28,7 +28,6 @@
#include "radialMap/map.h"
#include "radialMap/radialMap.h"
#include "scan.h"
#include "settingsDialog.h"
namespace Filelight
{
......@@ -51,7 +50,7 @@ MainContext::MainContext(QObject *parent)
, m_histories(nullptr)
, m_manager(new ScanManager(this))
{
Config::read();
Config::instance()->read();
auto engine = new QQmlApplicationEngine(this);
......@@ -62,6 +61,8 @@ MainContext::MainContext(QObject *parent)
l10nContext->setTranslationDomain(QStringLiteral(TRANSLATION_DOMAIN));
engine->rootContext()->setContextObject(l10nContext);
qmlRegisterUncreatableMetaObject(Filelight::staticMetaObject, "org.kde.filelight", 1, 0, "Filelight", QStringLiteral("Access to enums & flags only"));
auto about = new About(this);
qRegisterMetaType<size_t>("size_t");
qmlRegisterType<DropperItem>("org.kde.filelight", 1, 0, "DropperItem");
......@@ -83,6 +84,12 @@ MainContext::MainContext(QObject *parent)
QQmlEngine::setObjectOwnership(RadialMap::Map::instance(), QQmlEngine::CppOwnership);
return RadialMap::Map::instance();
});
qmlRegisterSingletonType<Config>("org.kde.filelight", 1, 0, "Config", [](QQmlEngine *engine, QJSEngine *scriptEngine) -> QObject * {
Q_UNUSED(engine)
Q_UNUSED(scriptEngine)
QQmlEngine::setObjectOwnership(Config::instance(), QQmlEngine::CppOwnership);
return Config::instance();
});
connect(m_manager, &ScanManager::completed, RadialMap::Map::instance(), [](const auto &tree) {
if (tree) {
......@@ -276,16 +283,6 @@ void MainContext::setUrl(const QUrl &url)
Q_EMIT urlChanged();
}
void MainContext::configFilelight() const
{
auto dialog = new SettingsDialog(nullptr);
connect(dialog, &SettingsDialog::canvasIsDirty, this, &MainContext::canvasIsDirty);
connect(dialog, &SettingsDialog::mapIsInvalid, m_manager, &ScanManager::emptyCache);
dialog->show(); // deletes itself
}
bool MainContext::start(const QUrl &url) const
{
if (m_manager->running()) {
......
......@@ -47,7 +47,7 @@ public:
Q_SIGNALS:
void canceled(const QString &);
void canvasIsDirty(Dirty filth);
void canvasIsDirty(Filelight::Dirty filth);
public Q_SLOTS:
void slotUp();
......@@ -60,7 +60,6 @@ public Q_SLOTS:
void urlAboutToChange() const;
bool openUrl(const QUrl &);
void configFilelight() const;
void updateURL(const QUrl &);
void rescanSingleDir(const QUrl &) const;
......
// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
// SPDX-FileCopyrightText: 2022 Harald Sitter <sitter@kde.org>
import QtQuick 2.15
import QtQuick.Layouts 1.15
import QtQuick.Controls 2.15 as QQC2
import org.kde.kirigami 2.19 as Kirigami
import QtQuick.Window 2.15
import org.kde.filelight 1.0
ColumnLayout {
id: layout
readonly property var window: Window.window
QQC2.TabBar {
id: bar
QQC2.TabButton {
text: i18nc("@title", "Scanning")
}
QQC2.TabButton {
text: i18nc("@title", "Appearance")
}
}