Skip to content
Merged
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
16 changes: 13 additions & 3 deletions src/configuration/configuration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -487,11 +487,22 @@ NODISCARD static uint16_t sanitizeUint16(const int input, const uint16_t default
} while (false)

void Configuration::read()
{
SETTINGS(conf);
readFrom(conf);
}

void Configuration::write() const
{
SETTINGS(conf);
writeTo(conf);
}

void Configuration::readFrom(QSettings &conf)
{
// reset to defaults before reading colors that might override them
colorSettings.resetToDefaults();

SETTINGS(conf);
FOREACH_CONFIG_GROUP(read);

// This logic only runs once on a MMapper fresh install (or factory reset)
Expand All @@ -514,9 +525,8 @@ void Configuration::read()
&& !colorSettings.BACKGROUND.getColor().isTransparent());
}

void Configuration::write() const
void Configuration::writeTo(QSettings &conf) const
{
SETTINGS(conf);
FOREACH_CONFIG_GROUP(write);
}

Expand Down
3 changes: 3 additions & 0 deletions src/configuration/configuration.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ class NODISCARD Configuration final
void write() const;
void reset();

void readFrom(QSettings &conf);
void writeTo(QSettings &conf) const;

public:
struct NODISCARD GeneralSettings final
{
Expand Down
11 changes: 0 additions & 11 deletions src/parser/AbstractParser-Commands.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ const Abbrev cmdConfig{"config", 4};
const Abbrev cmdConnect{"connect", 4};
const Abbrev cmdDirections{"dirs", 3};
const Abbrev cmdDisconnect{"disconnect", 4};
const Abbrev cmdDoorHelp{"doorhelp", 5};
const Abbrev cmdGenerateBaseMap{"generate-base-map"};
const Abbrev cmdGroup{"group", 2};
const Abbrev cmdHelp{"help", 2};
Expand Down Expand Up @@ -921,16 +920,6 @@ void AbstractParser::initSpecialCommandMap()
},
// TODO: create a parse tree, and show all of the help topics.
makeSimpleHelp("Provides help."));
add(
cmdDoorHelp,
[this](const std::vector<StringView> & /*s*/, StringView rest) {
if (!rest.isEmpty()) {
return false;
}
this->showDoorCommandHelp();
return true;
},
makeSimpleHelp("Help for door console commands."));

// door actions
for (const DoorActionEnum x : ALL_DOOR_ACTION_TYPES) {
Expand Down
87 changes: 87 additions & 0 deletions src/parser/AbstractParser-Config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "../global/Consts.h"
#include "../global/NamedColors.h"
#include "../global/PrintUtils.h"
#include "../mpi/remoteeditwidget.h"
#include "../proxy/proxy.h"
#include "../syntax/SyntaxArgs.h"
#include "../syntax/TreeParser.h"
Expand All @@ -19,6 +20,11 @@
#include <ostream>

#include <QColor>
#include <QDir>
#include <QFile>
#include <QPointer>
#include <QSettings>
#include <QTemporaryFile>

class NODISCARD ArgNamedColor final : public syntax::IArgument
{
Expand Down Expand Up @@ -344,6 +350,87 @@ void AbstractParser::doConfig(const StringView cmd)
send_ok(os);
},
"read config file")),
syn("edit",
Accept(
[this](User &user, auto) {
auto &os = user.getOstream();
if (isConnected()) {
os << "You must disconnect before you can edit the saved configuration.\n";
return;
}
os << "Opening configuration editor...\n";

QString content;
QString fileName;
{
QTemporaryFile temp(QDir::tempPath() + "/mmapper_XXXXXX.ini");
temp.setAutoRemove(false);
if (!temp.open()) {
os << "Failed to create temporary file.\n";
return;
}
fileName = temp.fileName();
temp.close();

{
QSettings settings(fileName, QSettings::IniFormat);
getConfig().writeTo(settings);
settings.sync();
}

QFile file(fileName);
if (file.open(QIODevice::ReadOnly)) {
content = QString::fromUtf8(file.readAll());
file.close();
}
QFile::remove(fileName);
}

if (content.isEmpty()) {
os << "Configuration is empty or failed to export.\n";
return;
}

// REVISIT: Ideally we support external editor as well
auto *editor = new RemoteEditWidget(true,
"MMapper Client Configuration",
content,
nullptr);
QObject::connect(editor,
&RemoteEditWidget::sig_save,
[weakParser = QPointer<AbstractParser>(this)](
const QString &edited) {
if (weakParser.isNull()) {
return;
}

QTemporaryFile tempRead(QDir::tempPath()
+ "/mmapper_XXXXXX.ini");
tempRead.setAutoRemove(true);
if (tempRead.open()) {
QString name = tempRead.fileName();
tempRead.write(edited.toUtf8());
tempRead.close();

{
auto &cfg = setConfig();
QSettings settings(name, QSettings::IniFormat);
cfg.readFrom(settings);
cfg.write();
}

weakParser->sendToUser(
SendToUserSourceEnum::FromMMapper,
"\nConfiguration imported and persisted.\n");
weakParser->sendOkToUser();
}
});

editor->setAttribute(Qt::WA_DeleteOnClose);
editor->show();
editor->activateWindow();
},
"edit client configuration")),
syn("factory",
"reset",
TokenMatcher::alloc<ArgStringExact>("Yes, I'm sure!"),
Expand Down
1 change: 0 additions & 1 deletion src/parser/abstractparser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -653,7 +653,6 @@ void AbstractParser::showHelp()
"Help commands:\n"
" %1help - this help text\n"
" %1help ?? - full syntax help for the help command\n"
" %1doorhelp - help for door console commands\n"
"\n"
"Other commands:\n"
" %1dirs [-options] pattern - directions to matching rooms\n"
Expand Down
5 changes: 1 addition & 4 deletions src/preferences/configdialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,7 @@ ConfigDialog::ConfigDialog(QWidget *const parent)
&ConfigDialog::slot_changePage);
connect(ui->closeButton, &QAbstractButton::clicked, this, &QWidget::close);

connect(generalPage, &GeneralPage::sig_factoryReset, this, [this]() {
qDebug() << "Reloading config due to factory reset";
emit sig_loadConfig();
});
connect(generalPage, &GeneralPage::sig_reloadConfig, this, [this]() { emit sig_loadConfig(); });
connect(this, &ConfigDialog::sig_loadConfig, generalPage, &GeneralPage::slot_loadConfig);
connect(this, &ConfigDialog::sig_loadConfig, graphicsPage, &GraphicsPage::slot_loadConfig);
connect(this, &ConfigDialog::sig_loadConfig, parserPage, &ParserPage::slot_loadConfig);
Expand Down
60 changes: 59 additions & 1 deletion src/preferences/generalpage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,10 +108,68 @@ GeneralPage::GeneralPage(QWidget *parent)
QMessageBox::Yes | QMessageBox::No);
if (reply == QMessageBox::Yes) {
setConfig().reset();
emit sig_factoryReset();
emit sig_reloadConfig();
}
});

connect(ui->configurationExportButton, &QAbstractButton::clicked, this, []() {
QTemporaryFile temp(QDir::tempPath() + "/mmapper_XXXXXX.ini");
temp.setAutoRemove(false);
if (!temp.open()) {
qWarning() << "Failed to create temporary file for export";
return;
}
const QString fileName = temp.fileName();
temp.close();

{
QSettings settings(fileName, QSettings::IniFormat);
getConfig().writeTo(settings);
settings.sync();
}

QFile file(fileName);
if (file.open(QIODevice::ReadOnly)) {
const QByteArray content = file.readAll();
file.close();
QFileDialog::saveFileContent(content, "mmapper.ini");
}

QFile::remove(fileName);
});

connect(ui->configurationImportButton, &QAbstractButton::clicked, this, [this]() {
auto importFile = [this](const QString &fileName,
const std::optional<QByteArray> &fileContent) {
Comment on lines +142 to +143
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (bug_risk): Import callback signature using std::optional may not match QFileDialog::getOpenFileContent expectations.

QFileDialog::getOpenFileContent expects a callback void(const QString &, const QByteArray &). A lambda taking const std::optional<QByteArray> & will not match this signature and will fail to compile (no implicit conversion from QByteArray to std::optional<QByteArray>). If you need to represent “no content”, keep the Qt signature and use content.isEmpty() instead of std::optional.

if (fileName.isEmpty() || !fileContent.has_value()) {
return;
}

const QByteArray &content = fileContent.value();
if (content.isEmpty()) {
return;
}

QTemporaryFile temp(QDir::tempPath() + "/mmapper_import_XXXXXX.ini");
temp.setAutoRemove(true);
if (temp.open()) {
temp.write(content);
temp.close();

{
auto &cfg = setConfig();
QSettings settings(temp.fileName(), QSettings::IniFormat);
cfg.readFrom(settings);
cfg.write();
}
emit sig_reloadConfig();
}
};

const auto nameFilter = QStringLiteral("Configuration (*.ini);;All files (*)");
QFileDialog::getOpenFileContent(nameFilter, importFile);
});

connect(ui->autoLogin, &QCheckBox::stateChanged, this, [this]() {
setConfig().account.rememberLogin = ui->autoLogin->isChecked();
});
Expand Down
2 changes: 1 addition & 1 deletion src/preferences/generalpage.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class NODISCARD_QOBJECT GeneralPage final : public QWidget
~GeneralPage() final;

signals:
void sig_factoryReset();
void sig_reloadConfig();

public slots:
void slot_loadConfig();
Expand Down
47 changes: 30 additions & 17 deletions src/preferences/generalpage.ui
Original file line number Diff line number Diff line change
Expand Up @@ -397,23 +397,10 @@
<string>Advanced</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="2" column="1">
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="2" column="0">
<widget class="QPushButton" name="configurationResetButton">
<item row="3" column="1">
<widget class="QPushButton" name="configurationImportButton">
<property name="text">
<string>Reset to Default Settings</string>
<string>Import Settings...</string>
</property>
</widget>
</item>
Expand All @@ -427,6 +414,13 @@
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QPushButton" name="configurationExportButton">
<property name="text">
<string>Export Settings...</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QCheckBox" name="proxyListensOnAnyInterfaceCheckBox">
<property name="toolTip">
Expand All @@ -437,6 +431,26 @@
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QPushButton" name="configurationResetButton">
<property name="text">
<string>Reset to Default Settings</string>
</property>
</widget>
</item>
<item row="4" column="1">
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
Expand Down Expand Up @@ -477,7 +491,6 @@
<tabstop>showNotesCheckBox</tabstop>
<tabstop>proxyListensOnAnyInterfaceCheckBox</tabstop>
<tabstop>proxyConnectionStatusCheckBox</tabstop>
<tabstop>configurationResetButton</tabstop>
</tabstops>
<resources/>
<connections/>
Expand Down
2 changes: 2 additions & 0 deletions src/proxy/mumesocket.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,8 @@ void MumeFallbackSocket::onSocketError(const QString &errorString)
m_outputs.onSocketStatus("Attempting insecure plain text...");
break;
case SocketTypeEnum::SSL:
m_outputs.onSocketError("Unable to connect to MUME.");
return;
default:
assert(false);
};
Expand Down
Loading