From 7453e8d61d1492725b1141e5ab94b063d7635c67 Mon Sep 17 00:00:00 2001 From: Johan Malm Date: Sun, 30 Nov 2025 19:00:50 +0000 Subject: [PATCH 1/4] Remove maindialog.ui and just code the list+stack --- CMakeLists.txt | 2 +- src/maindialog.cpp | 115 +++++++++++++++++++++++++---- src/maindialog.h | 17 +++-- src/maindialog.ui | 178 --------------------------------------------- 4 files changed, 112 insertions(+), 200 deletions(-) delete mode 100644 src/maindialog.ui diff --git a/CMakeLists.txt b/CMakeLists.txt index 62fe184..194627d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -37,7 +37,7 @@ find_package(LibXml2 REQUIRED) set(PROJECT_SOURCES src/main.cpp - src/maindialog.cpp src/maindialog.h src/maindialog.ui + src/maindialog.cpp src/maindialog.h src/layoutmodel.cpp src/layoutmodel.h diff --git a/src/maindialog.cpp b/src/maindialog.cpp index 3edf6e5..f5072d7 100644 --- a/src/maindialog.cpp +++ b/src/maindialog.cpp @@ -1,3 +1,17 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "appearance.h" +#include "behaviour.h" + #include #include #include @@ -11,41 +25,112 @@ #include "log.h" #include "macros.h" #include "maindialog.h" -#include "./ui_maindialog.h" #include "xml.h" -MainDialog::MainDialog(QWidget *parent) : QDialog(parent), ui(new Ui::MainDialog) +MainDialog::MainDialog(QWidget *parent) : QDialog(parent) { - ui->setupUi(this); - ui->list->setFixedWidth(ui->list->sizeHintForColumn(0) + 2 * ui->list->frameWidth()); - QObject::connect(ui->buttonBox, &QDialogButtonBox::clicked, [&](QAbstractButton *button) { - if (ui->buttonBox->standardButton(button) == QDialogButtonBox::Apply) { + resize(640, 480); + + QVBoxLayout *verticalLayout = new QVBoxLayout(this); + verticalLayout->setContentsMargins(6, 6, 6, 6); + + QWidget *widget = new QWidget(this); + + QHBoxLayout *horizontalLayout = new QHBoxLayout(widget); + horizontalLayout->setContentsMargins(6, 6, 6, 6); + + // List Widget on the Left + QListWidget *list = new QListWidget(widget); + + QListWidgetItem *item0 = new QListWidgetItem(list); + item0->setIcon(QIcon::fromTheme("applications-graphics")); + item0->setText(tr("Appearance")); + + QListWidgetItem *item1 = new QListWidgetItem(list); + item1->setIcon(QIcon::fromTheme("preferences-desktop")); + item1->setText(tr("Behaviour")); + + QListWidgetItem *item2 = new QListWidgetItem(list); + item2->setIcon(QIcon::fromTheme("input-mouse")); + item2->setText(tr("Mouse & Touchpad")); + + QListWidgetItem *item3 = new QListWidgetItem(list); + item3->setIcon(QIcon::fromTheme("preferences-desktop-locale")); + item3->setText(tr("Language & Region")); + + QSizePolicy sizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding); + sizePolicy.setHorizontalStretch(0); + sizePolicy.setVerticalStretch(0); + sizePolicy.setHeightForWidth(list->sizePolicy().hasHeightForWidth()); + list->setSizePolicy(sizePolicy); + list->setSizeAdjustPolicy(QAbstractScrollArea::SizeAdjustPolicy::AdjustToContents); + list->setCurrentRow(0); + list->setFixedWidth(list->sizeHintForColumn(0) + 2 * list->frameWidth()); + + horizontalLayout->addWidget(list); + + // The stack containing all the pages + QStackedWidget *stack = new QStackedWidget(widget); + + m_pageAppearance = new Appearance(); + stack->addWidget(m_pageAppearance); + + m_pageBehaviour = new Behaviour(); + stack->addWidget(m_pageBehaviour); + + m_pageMouse = new Mouse(); + stack->addWidget(m_pageMouse); + + m_pageLanguage = new Language(); + stack->addWidget(m_pageLanguage); + + horizontalLayout->addWidget(stack); + + verticalLayout->addWidget(widget); + + m_buttonBox = new QDialogButtonBox(this); + m_buttonBox->setOrientation(Qt::Orientation::Horizontal); + m_buttonBox->setStandardButtons(QDialogButtonBox::StandardButton::Apply + | QDialogButtonBox::StandardButton::Close); + m_buttonBox->setCenterButtons(false); + + verticalLayout->addWidget(m_buttonBox); + + // Change pages when list items are clicked + QObject::connect(list, SIGNAL(currentRowChanged(int)), stack, SLOT(setCurrentIndex(int))); + + // Close Button + QObject::connect(m_buttonBox, SIGNAL(rejected()), this, SLOT(reject())); + + // Apply Button + QObject::connect(m_buttonBox, &QDialogButtonBox::clicked, [&](QAbstractButton *button) { + if (m_buttonBox->standardButton(button) == QDialogButtonBox::Apply) { onApply(); } }); + activate(); } MainDialog::~MainDialog() { - delete ui; xml_finish(); } void MainDialog::activate() { - ui->pageAppearance->activate(); - ui->pageBehaviour->activate(); - ui->pageMouse->activate(); - ui->pageLanguage->activate(); + m_pageAppearance->activate(); + m_pageBehaviour->activate(); + m_pageMouse->activate(); + m_pageLanguage->activate(); } void MainDialog::onApply() { - ui->pageAppearance->onApply(); - ui->pageBehaviour->onApply(); - ui->pageMouse->onApply(); - ui->pageLanguage->onApply(); + m_pageAppearance->onApply(); + m_pageBehaviour->onApply(); + m_pageMouse->onApply(); + m_pageLanguage->onApply(); // TODO: Get filename in a more consistent way - share common code with main.cpp std::string config_home = std::getenv("HOME") + std::string("/.config/labwc"); diff --git a/src/maindialog.h b/src/maindialog.h index 471f24e..427eb43 100644 --- a/src/maindialog.h +++ b/src/maindialog.h @@ -1,13 +1,13 @@ #ifndef MAINDIALOG_H #define MAINDIALOG_H #include +#include #include "settings.h" -QT_BEGIN_NAMESPACE -namespace Ui { -class MainDialog; -} -QT_END_NAMESPACE +class Appearance; +class Behaviour; +class Mouse; +class Language; class MainDialog : public QDialog { @@ -20,6 +20,11 @@ class MainDialog : public QDialog private: void onApply(); - Ui::MainDialog *ui; + + QDialogButtonBox *m_buttonBox; + Appearance *m_pageAppearance; + Behaviour *m_pageBehaviour; + Mouse *m_pageMouse; + Language *m_pageLanguage; }; #endif // MAINDIALOG_H diff --git a/src/maindialog.ui b/src/maindialog.ui deleted file mode 100644 index a3a2625..0000000 --- a/src/maindialog.ui +++ /dev/null @@ -1,178 +0,0 @@ - - - MainDialog - - - - 0 - 0 - 640 - 480 - - - - - 6 - - - 6 - - - 6 - - - 6 - - - - - - 6 - - - 6 - - - 6 - - - 6 - - - - - - 0 - 0 - - - - QAbstractScrollArea::SizeAdjustPolicy::AdjustToContents - - - 0 - - - - Appearance - - - - - - - - Behaviour - - - - - - - - Mouse & Touchpad - - - - - - - - Language & Region - - - - - - - - - - - - - - - - - - - - - - Qt::Orientation::Horizontal - - - QDialogButtonBox::StandardButton::Apply|QDialogButtonBox::StandardButton::Close - - - false - - - - - - - - Appearance - QWidget -
appearance.h
-
- - Behaviour - QWidget -
behaviour.h
-
-
- - - - buttonBox - accepted() - MainDialog - accept() - - - 248 - 254 - - - 157 - 274 - - - - - buttonBox - rejected() - MainDialog - reject() - - - 316 - 260 - - - 286 - 274 - - - - - list - currentRowChanged(int) - stack - setCurrentIndex(int) - - - 145 - 248 - - - 459 - 248 - - - - -
From 00cacf793cd125e20a4a54b1ad644b16b5e31ccc Mon Sep 17 00:00:00 2001 From: Johan Malm Date: Sun, 30 Nov 2025 19:02:45 +0000 Subject: [PATCH 2/4] environment.cpp: use QString::toInt() instead of atoi() --- src/environment.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/environment.cpp b/src/environment.cpp index fb0d370..84d780e 100644 --- a/src/environment.cpp +++ b/src/environment.cpp @@ -50,8 +50,9 @@ int environmentGetInt(QString key) continue; } if (line->key == key) { - // TODO: Not ideal - return atoi(line->value.toStdString().c_str()); + bool success = false; + int ret = line->value.toInt(&success); + return success ? ret : -1; } } return -1; From db1125ec1974e68ce73112846973753df67c8d98 Mon Sep 17 00:00:00 2001 From: Johan Malm Date: Sun, 30 Nov 2025 19:06:44 +0000 Subject: [PATCH 3/4] settings.cpp: fix bug whereby initial int value of 0 in rc.xml is handled wrong --- src/settings.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/settings.cpp b/src/settings.cpp index 5842a07..1fc3812 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -64,7 +64,7 @@ Setting::Setting(QString name, enum settingFileType fileType, enum settingValueT } case LAB_VALUE_TYPE_INT: { int value = xml_get_int(m_name.toStdString().c_str()); - if (value && (value != std::get(m_value))) { + if (value != std::get(m_value)) { m_valueOrigin = LAB_VALUE_ORIGIN_USER_OVERRIDE; m_value = value; info("[user-override] {}: {}", m_name.toStdString(), value); @@ -147,7 +147,7 @@ QString getStr(QString name) return nullptr; } if (setting->valueType() != LAB_VALUE_TYPE_STRING) { - qDebug() << "getStr(): not valid int setting" << name; + qDebug() << "getStr(): not valid string setting" << name; } return std::get(setting->value()); } @@ -174,7 +174,7 @@ int getBool(QString name) return -1; } if (setting->valueType() != LAB_VALUE_TYPE_BOOL) { - qDebug() << "getBool(): not valid int setting" << name; + qDebug() << "getBool(): not valid bool setting" << name; } return std::get(setting->value()); } From ec85b913fe7f819fb3898aaa0aeeb138ceabbdcd Mon Sep 17 00:00:00 2001 From: Johan Malm Date: Sun, 30 Nov 2025 20:41:22 +0000 Subject: [PATCH 4/4] behaviour.cpp: translate values in Placement Policy QComboBox ...by providing both text (the translated stuff) and data (the value that we want to go into rc.xml) when calling addItem(). Fixes: #128 --- CMakeLists.txt | 1 + src/behaviour.cpp | 23 ++++++++++++++++++----- src/macros.h | 7 +++++++ src/pair.h | 21 +++++++++++++++++++++ 4 files changed, 47 insertions(+), 5 deletions(-) create mode 100644 src/pair.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 194627d..59e64ad 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -45,6 +45,7 @@ set(PROJECT_SOURCES src/settings.cpp src/settings.h src/xml.cpp src/xml.h src/find-themes.cpp src/find-themes.h + src/pair.h src/appearance.cpp src/appearance.h src/appearance.ui src/behaviour.cpp src/behaviour.h src/behaviour.ui diff --git a/src/behaviour.cpp b/src/behaviour.cpp index 6939961..f73133a 100644 --- a/src/behaviour.cpp +++ b/src/behaviour.cpp @@ -1,6 +1,8 @@ #include "behaviour.h" +#include #include "find-themes.h" #include "macros.h" +#include "pair.h" #include "settings.h" #include "./ui_behaviour.h" @@ -17,13 +19,24 @@ Behaviour::~Behaviour() void Behaviour::activate() { /* Placement Policy */ - QStringList policies = { "", "Automatic", "Cascade", "Center", "Cursor" }; - ui->placementPolicy->addItems(policies); - ui->placementPolicy->setCurrentIndex( - policies.indexOf(getStr("/labwc_config/placement/policy"))); + QVector> policies; + policies.append(QSharedPointer(new Pair("automatic", tr("Automatic")))); + policies.append(QSharedPointer(new Pair("cascade", tr("Cascade")))); + policies.append(QSharedPointer(new Pair("center", tr("Center")))); + policies.append(QSharedPointer(new Pair("cursor", tr("Cursor")))); + + QString current = getStr("/labwc_config/placement/policy"); + int index = -1; + foreach (auto policy, policies) { + ui->placementPolicy->addItem(policy.get()->description(), QVariant(policy.get()->value())); + ++index; + if (current == policy.get()->value()) { + ui->placementPolicy->setCurrentIndex(index); + } + } } void Behaviour::onApply() { - setStr("/labwc_config/placement/policy", TEXT(ui->placementPolicy)); + setStr("/labwc_config/placement/policy", DATA(ui->placementPolicy)); } diff --git a/src/macros.h b/src/macros.h index eff47ce..8df54f4 100644 --- a/src/macros.h +++ b/src/macros.h @@ -3,4 +3,11 @@ #define TEXT(widget) widget->currentText().toLatin1().data() +/* + * Typically used when a widget like a QComboBox contains translated text + * which obviously would not be very good to feed to rc.xml and we therefore + * need the QVariant userdata instead. + */ +#define DATA(widget) widget->currentData().toString().toLatin1().data() + #endif // MACROS_H diff --git a/src/pair.h b/src/pair.h new file mode 100644 index 0000000..239bf51 --- /dev/null +++ b/src/pair.h @@ -0,0 +1,21 @@ +#pragma once +#include + +class Pair +{ +public: + Pair(QString value, QString description) + { + m_value = value; + m_description = description; + }; + ~Pair() { }; + +private: + QString m_value; + QString m_description; + +public: + QString value() const { return m_value; } + QString description() const { return m_description; } +};