Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 39 additions & 1 deletion src/ApplicationSettings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

#include "ApplicationSettings.h"

#include <QTemporaryFile>
#include <QApplication>
#include <QFont>

Expand All @@ -36,8 +37,45 @@ ApplicationSetting<type> name{#group "/" #name, default};\


ApplicationSettings::ApplicationSettings(QObject *parent)
: QSettings{parent}
: QSettings(parent)
{ }

ApplicationSettings::ApplicationSettings(QTemporaryFile *tempFile, QObject *parent)
: QSettings(tempFile->fileName(), QSettings::NativeFormat, parent)
{
tempFile->setParent(this);
}

void ApplicationSettings::fillFrom(ApplicationSettings *other)
{
if (!other) return;

const auto meta = metaObject();

for (auto i = meta->propertyOffset(); i < meta->propertyCount(); ++i)
{
const auto property = meta->property(i);

if (property.isWritable() && property.isReadable())
property.write(this, property.read(other));
}
}

bool ApplicationSettings::isEquals(ApplicationSettings *other) const
{
if (!other) return false;

const auto meta = metaObject();

for (auto i = meta->propertyOffset(); i < meta->propertyCount(); ++i)
{
const auto property = meta->property(i);

if (property.read(this) != property.read(other))
return false;
}

return true;
}

CREATE_SETTING(Gui, ShowMenuBar, showMenuBar, bool, true)
Expand Down
46 changes: 31 additions & 15 deletions src/ApplicationSettings.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include <QString>
#include <QMetaEnum>

class QTemporaryFile;

template<typename T>
class ApplicationSetting
Expand Down Expand Up @@ -53,39 +54,54 @@ class ApplicationSetting
};


#define DEFINE_SETTING(name, lname, type)\
public:\
type lname() const;\
public slots:\
void set##name(type lname);\
Q_SIGNAL\
void lname##Changed(type lname);\

#define DEFINE_SETTING(name, lname, type) \
Q_PROPERTY(type lname READ lname WRITE set##name NOTIFY lname##Changed FINAL) \
public: \
type lname() const; \
public slots: \
void set##name(type lname); \
Q_SIGNAL \
void lname##Changed(type lname);

class ApplicationSettings : public QSettings
{
Q_OBJECT

public:
explicit ApplicationSettings(QObject *parent = nullptr);

enum DefaultDirectoryBehaviorEnum {
enum DefaultDirectoryBehaviorEnum
{
FollowCurrentDocument,
RememberLastUsed,
HardCoded
};
Q_ENUM(DefaultDirectoryBehaviorEnum)

public:
explicit ApplicationSettings(QObject *parent = nullptr);

/**
* @brief Create temporary instance with default settings.
* @param tempFile Temporary file instance to be used.
* @warning Ensure tempFile->open() was called before passing it.
* @note The instance takes ownership of tempFile.
*/
ApplicationSettings(QTemporaryFile *tempFile, QObject *parent = nullptr);

inline void copyTo(ApplicationSettings *other) const {
other->fillFrom(const_cast<ApplicationSettings*>(this));
}
void fillFrom(ApplicationSettings *other);
bool isEquals(ApplicationSettings *other) const;

template <typename T>
T get(const char *key, const T &defaultValue) const
inline T get(const char *key, const T &defaultValue) const
{ return value(QLatin1String(key), defaultValue).template value<T>(); }

template <typename T>
T get(const ApplicationSetting<T> &setting) const
inline T get(const ApplicationSetting<T> &setting) const
{ return get(setting.key(), setting.getDefault()); }

template <typename T>
void set(const ApplicationSetting<T> &setting, const T &value)
inline void set(const ApplicationSetting<T> &setting, const T &value)
{ setValue(QLatin1String(setting.key()), value); }

DEFINE_SETTING(ShowMenuBar, showMenuBar, bool)
Expand Down
17 changes: 14 additions & 3 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,17 @@ qt_add_executable(NotepadNext
decorators/SurroundSelection.h
decorators/URLFinder.cpp
decorators/URLFinder.h
dialogs/Preferences/PreferencesCategoryListModel.cpp
dialogs/Preferences/PreferencesCategoryListModel.h
dialogs/Preferences/BehaviorCategoryItem.cpp
dialogs/Preferences/BehaviorCategoryItem.h
dialogs/Preferences/PreferencesViewUtils.h
dialogs/Preferences/PreferencesCategoryItem.h
dialogs/Preferences/PreferencesCategoryItemT.h
dialogs/Preferences/AppearanceCategoryItem.cpp
dialogs/Preferences/AppearanceCategoryItem.h
dialogs/PreferencesDialog.cpp
dialogs/PreferencesDialog.h
dialogs/ColumnEditorDialog.cpp
dialogs/ColumnEditorDialog.h
dialogs/ColumnEditorDialog.ui
Expand All @@ -143,9 +154,9 @@ qt_add_executable(NotepadNext
dialogs/MainWindow.cpp
dialogs/MainWindow.h
dialogs/MainWindow.ui
dialogs/PreferencesDialog.cpp
dialogs/PreferencesDialog.h
dialogs/PreferencesDialog.ui



docks/DebugLogDock.cpp
docks/DebugLogDock.h
docks/DebugLogDock.ui
Expand Down
5 changes: 4 additions & 1 deletion src/dialogs/MainWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -719,12 +719,15 @@ MainWindow::MainWindow(NotepadNextApplication *app) :
languageActionGroup->setExclusive(true);

connect(ui->actionPreferences, &QAction::triggered, this, [=] {
PreferencesDialog *pd = findChild<PreferencesDialog *>(QString(), Qt::FindDirectChildrenOnly);
auto pd = findChild<PreferencesDialog*>(QString(), Qt::FindDirectChildrenOnly);

if (pd == Q_NULLPTR) {
pd = new PreferencesDialog(app->getSettings(), this);
}

pd->resize(700, 400);
pd->setGeometry(QStyle::alignedRect(Qt::LeftToRight, Qt::AlignCenter, pd->size(), geometry()));

pd->show();
pd->raise();
pd->activateWindow();
Expand Down
146 changes: 146 additions & 0 deletions src/dialogs/Preferences/AppearanceCategoryItem.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
/*
* This file is part of Notepad Next.
* Copyright 2026 Justin Dailey
*
* Notepad Next 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 3 of the License, or
* (at your option) any later version.
*
* Notepad Next 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 Notepad Next. If not, see <https://www.gnu.org/licenses/>.
*/


#include <QFontComboBox>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QGroupBox>
#include <QComboBox>
#include <QLabel>

#include "AppearanceCategoryItem.h"
#include "PreferencesViewUtils.h"
#include "ApplicationSettings.h"

using namespace Preferences;

namespace
{
inline QGroupBox *WindowAppearanceView(ApplicationSettings *settings)
{
const auto group = new QGroupBox(QObject::tr("Main window"));

const auto layout = new QVBoxLayout(group);
layout->addWidget(CreateCheckBox(
QObject::tr("Show menu bar"),
settings,
PREFERENCES_BIND_PROPERTY(showMenuBar, ShowMenuBar)
));
layout->addWidget(CreateCheckBox(
QObject::tr("Show toolbar"),
settings,
PREFERENCES_BIND_PROPERTY(showToolBar, ShowToolBar)
));
layout->addWidget(CreateCheckBox(
QObject::tr("Show status bar"),
settings,
PREFERENCES_BIND_PROPERTY(showStatusBar, ShowStatusBar)
));
layout->setContentsMargins(MARGINS_6);
layout->setSpacing(SPACING_6);

return group;
}

inline QGroupBox *FontAppearanceView(ApplicationSettings *settings)
{
const auto group = new QGroupBox(QObject::tr("Font"));

const auto familyCombo = new QFontComboBox;
familyCombo->setMinimumWidth(120);

const auto sizeCombo = new QComboBox;
sizeCombo->addItems({
"4", "6", "8", "9", "10",
"11", "12", "14", "16", "18",
"20", "22", "24", "26", "28",
"36", "48", "72"
});
sizeCombo->setValidator(new QIntValidator(4, 200, sizeCombo));
sizeCombo->setEditable(true);

const auto wheelSuppressor = new WheelEventSuppressFilter(group);
wheelSuppressor->setupFor(familyCombo);
wheelSuppressor->setupFor(sizeCombo);

const auto layout = new QHBoxLayout(group);
layout->addWidget(new QLabel(QObject::tr("Family:")));
layout->addWidget(familyCombo, 1);
layout->addSpacing(3);
layout->addWidget(new QLabel(QObject::tr("Size:")));
layout->addWidget(sizeCombo);
layout->setContentsMargins(MARGINS_6);
layout->setSpacing(3);

familyCombo->setCurrentFont(QFont(settings->fontName()));
sizeCombo->setCurrentText(QString("%1").arg(settings->fontSize()));

QObject::connect(familyCombo, &QFontComboBox::currentFontChanged, settings, [settings](const QFont &font) {
settings->setFontName(font.family());
});
QObject::connect(settings, &ApplicationSettings::fontNameChanged, familyCombo, [familyCombo](const QString &fontName){
familyCombo->setCurrentFont(QFont(fontName));
});

QObject::connect(sizeCombo, &QComboBox::currentTextChanged, settings, [settings](const QString &value) {
settings->setFontSize(value.toInt());
});
QObject::connect(settings, &ApplicationSettings::fontSizeChanged, sizeCombo, [sizeCombo](int size) {
sizeCombo->setCurrentText(QString("%1").arg(size));
});

return group;
}

inline QGroupBox *EditorAppearanceView(ApplicationSettings *settings)
{
const auto group = new QGroupBox(QObject::tr("Editor"));

const auto layout = new QVBoxLayout(group);
layout->addWidget(FontAppearanceView(settings));
layout->addWidget(CreateCheckBox(
QObject::tr("Highlight URLs"),
settings,
PREFERENCES_BIND_PROPERTY(urlHighlighting, URLHighlighting)
));
layout->addWidget(CreateCheckBox(
QObject::tr("Show line numbers"),
settings,
PREFERENCES_BIND_PROPERTY(showLineNumbers, ShowLineNumbers)
));
layout->setContentsMargins(MARGINS_6);
layout->setSpacing(SPACING_6);

return group;
}
}

QWidget *AppearanceCategoryItem::contentView(ApplicationSettings *settings) const
{
const auto widget = new QWidget;
const auto layout = new QVBoxLayout(widget);

layout->addWidget(WindowAppearanceView(settings));
layout->addWidget(EditorAppearanceView(settings));
layout->addStretch(1);
layout->setContentsMargins(MARGINS_6);
layout->setSpacing(SPACING_6);

return widget;
}
36 changes: 36 additions & 0 deletions src/dialogs/Preferences/AppearanceCategoryItem.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* This file is part of Notepad Next.
* Copyright 2026 Justin Dailey
*
* Notepad Next 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 3 of the License, or
* (at your option) any later version.
*
* Notepad Next 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 Notepad Next. If not, see <https://www.gnu.org/licenses/>.
*/


#ifndef APPEARANCECATEGORYITEM_H
#define APPEARANCECATEGORYITEM_H

#include "PreferencesCategoryItem.h"

class AppearanceCategoryItem : public PreferencesCategoryItem
{
public:
AppearanceCategoryItem() = default;
virtual ~AppearanceCategoryItem() = default;

virtual QString title() const override { return QObject::tr("Appearance"); }
virtual QString iconPath() const override { return "://icons/paintbrush.svg"; }
virtual QWidget *contentView(ApplicationSettings *settings) const override;
};

#endif // APPEARANCECATEGORYITEM_H
Loading
Loading