summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlexander Kavon <me+git@alexkavon.com>2025-11-06 01:30:43 -0500
committerAlexander Kavon <me+git@alexkavon.com>2025-11-06 01:30:43 -0500
commit360c9e2d623be8c8a7479d3e170114fe75dcc4c7 (patch)
tree8d7497ae50fb47ac041257ae83eed8fdd112bd4c /src
kue a kanban todo app for kde plasmaHEADtrunk
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt57
-rw-r--r--src/kueapplication.cpp73
-rw-r--r--src/kueapplication.h37
-rw-r--r--src/kueconfig.kcfg16
-rw-r--r--src/kueconfig.kcfgc10
-rw-r--r--src/main.cpp74
-rw-r--r--src/qml/Main.qml168
-rw-r--r--src/settings/CMakeLists.txt11
-rw-r--r--src/settings/GeneralPage.qml27
-rw-r--r--src/settings/KueConfigurationView.qml20
10 files changed, 493 insertions, 0 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
new file mode 100644
index 0000000..e28db18
--- /dev/null
+++ b/src/CMakeLists.txt
@@ -0,0 +1,57 @@
+# SPDX-License-Identifier: BSD-2-Clause
+# SPDX-FileCopyrightText: 2024 Alexander Kavon <me+kue@alexkavon.com>
+
+add_subdirectory(settings)
+
+qt_add_library(kue_static STATIC)
+ecm_add_qml_module(kue_static
+ URI org.kde.kue
+ GENERATE_PLUGIN_SOURCE
+ VERSION 1.0
+ QML_FILES
+ qml/Main.qml
+ DEPENDENCIES
+ org.kde.kirigamiaddons.statefulapp
+ org.kde.kirigami
+ org.kde.kue.settings
+)
+
+target_sources(kue_static PUBLIC
+ kueapplication.cpp
+ kueapplication.h
+)
+
+target_link_libraries(kue_static PUBLIC
+ Qt6::Core
+ Qt6::Gui
+ Qt6::Qml
+ Qt6::Quick
+ Qt6::QuickControls2
+ Qt6::Svg
+ KF6::I18n
+ KF6::CoreAddons
+ KF6::ConfigCore
+ KF6::ConfigGui
+ KirigamiAddonsStatefulApp
+ KPim6::AkonadiCore
+ KPim6::AkonadiAgentBase
+ KPim6::AkonadiWidgets
+ KPim6::AkonadiXml
+ KPim6::AkonadiMime
+ KPim6::Mime
+ KPim6::MailCommon
+)
+target_include_directories(kue_static PUBLIC ${CMAKE_BINARY_DIR} /home/hawk/kde/usr/include)
+
+target_link_libraries(kue_static PUBLIC Qt::Widgets)
+
+kconfig_add_kcfg_files(kue_static GENERATE_MOC kueconfig.kcfgc)
+
+add_executable(kue main.cpp)
+target_link_libraries(kue PUBLIC
+ kue_static
+ kue_staticplugin
+ kue_settings
+ kue_settingsplugin
+)
+install(TARGETS kue ${KDE_INSTALL_TARGETS_DEFAULT_ARGS})
diff --git a/src/kueapplication.cpp b/src/kueapplication.cpp
new file mode 100644
index 0000000..b459acf
--- /dev/null
+++ b/src/kueapplication.cpp
@@ -0,0 +1,73 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+// SPDX-FileCopyrightText: 2024 Alexander Kavon <me+kue@alexkavon.com>
+
+#include "kueapplication.h"
+#include <KAuthorized>
+#include <KLocalizedString>
+#include <KDescendantsProxyModel>
+#include <Akonadi/ServerManager>
+#include <Akonadi/Session>
+#include <Akonadi/Monitor>
+#include <Akonadi/EntityTreeModel>
+#include <Akonadi/CollectionFilterProxyModel>
+#include <KMime/Message>
+#include <QApplication>
+#include <QDebug>
+
+using namespace Qt::StringLiterals;
+
+KueApplication::KueApplication(QObject *parent)
+ : AbstractKirigamiApplication(parent)
+ , m_loading(true)
+{
+ m_session = new Akonadi::Session(QByteArrayLiteral("Kue Kernel"), this);
+
+ auto monitor = new Akonadi::Monitor(this);
+
+ auto treeModel = new Akonadi::EntityTreeModel(monitor, this);
+ treeModel->setItemPopulationStrategy(Akonadi::EntityTreeModel::LazyPopulation);
+
+ auto entityTreeModel = new Akonadi::CollectionFilterProxyModel(this);
+ entityTreeModel->setSourceModel(treeModel);
+ entityTreeModel->addMimeTypeFilter(KMime::Message::mimeType());
+
+ m_descendantsProxyModel = new KDescendantsProxyModel(this);
+ m_descendantsProxyModel->setSourceModel(entityTreeModel);
+ qDebug() << m_descendantsProxyModel->rowCount();
+
+ if (Akonadi::ServerManager::isRunning()) {
+ m_loading = false;
+ } else {
+ connect(Akonadi::ServerManager::self(), &Akonadi::ServerManager::stateChanged, this, [this](Akonadi::ServerManager::State state) {
+ if (state == Akonadi::ServerManager::Broken) {
+ qDebug() << "ServerManager Broken";
+ qApp->exit(-1);
+ return;
+ }
+ bool loading = state != Akonadi::ServerManager::State::Running;
+ if (loading == m_loading) {
+ return;
+ }
+ m_loading = loading;
+ Q_EMIT loadingChanged();
+ disconnect(Akonadi::ServerManager::self(), &Akonadi::ServerManager::stateChanged, this, nullptr);
+ });
+ }
+}
+
+bool KueApplication::loading() const
+{
+ return m_loading;
+}
+
+KDescendantsProxyModel *KueApplication::descendantsProxyModel() const
+{
+ return m_descendantsProxyModel;
+}
+
+Akonadi::Session *KueApplication::session() const
+{
+ return m_session;
+}
+
+#include "moc_kueapplication.cpp"
diff --git a/src/kueapplication.h b/src/kueapplication.h
new file mode 100644
index 0000000..888c592
--- /dev/null
+++ b/src/kueapplication.h
@@ -0,0 +1,37 @@
+// SPDX-FileCopyrightText: 2024 Alexander Kavon <me+kue@alexkavon.com>
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include <QQmlEngine>
+#include <AbstractKirigamiApplication>
+#include <KDescendantsProxyModel>
+
+using namespace Qt::StringLiterals;
+
+namespace Akonadi {
+ class Session;
+}
+
+class KueApplication : public AbstractKirigamiApplication
+{
+ Q_OBJECT
+ QML_ELEMENT
+ Q_PROPERTY(bool loading READ loading NOTIFY loadingChanged)
+ Q_PROPERTY(KDescendantsProxyModel *descendantsProxyModel READ descendantsProxyModel CONSTANT)
+
+ bool loading() const;
+ Akonadi::Session *session() const;
+
+public:
+ explicit KueApplication(QObject *parent = nullptr);
+ KDescendantsProxyModel *descendantsProxyModel() const;
+
+Q_SIGNALS:
+ void loadingChanged();
+
+private:
+ bool m_loading;
+ Akonadi::Session *m_session;
+ KDescendantsProxyModel *m_descendantsProxyModel;
+};
diff --git a/src/kueconfig.kcfg b/src/kueconfig.kcfg
new file mode 100644
index 0000000..1ad1fd2
--- /dev/null
+++ b/src/kueconfig.kcfg
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<kcfg xmlns="http://www.kde.org/standards/kcfg/1.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.kde.org/standards/kcfg/1.0
+ http://www.kde.org/standards/kcfg/1.0/kcfg.xsd" >
+<!--
+SPDX-FileCopyrightText: 2024 Alexander Kavon <me+kue@alexkavon.com>
+SPDX-License-Identifier: LGPL-2.0-or-later
+-->
+ <group name="General">
+ <entry name="someSetting" type="Bool">
+ <label>Some setting description</label>
+ <default>true</default>
+ </entry>
+ </group>
+</kcfg>
diff --git a/src/kueconfig.kcfgc b/src/kueconfig.kcfgc
new file mode 100644
index 0000000..0a02a78
--- /dev/null
+++ b/src/kueconfig.kcfgc
@@ -0,0 +1,10 @@
+# SPDX-FileCopyrightText: 2024 Alexander Kavon <me+kue@alexkavon.com>
+# SPDX-License-Identifier: LGPL-2.0-or-later
+
+File=kueconfig.kcfg
+ClassName=KueConfig
+Mutators=true
+DefaultValueGetters=true
+GenerateProperties=true
+ParentInConstructor=true
+Singleton=true
diff --git a/src/main.cpp b/src/main.cpp
new file mode 100644
index 0000000..41f7fef
--- /dev/null
+++ b/src/main.cpp
@@ -0,0 +1,74 @@
+/*
+ SPDX-License-Identifier: GPL-2.0-or-later
+ SPDX-FileCopyrightText: 2024 Alexander Kavon <me+kue@alexkavon.com>
+*/
+
+#include <QtGlobal>
+#include <QApplication>
+
+#include <QIcon>
+#include <QQmlApplicationEngine>
+#include <QQmlContext>
+#include <QQuickStyle>
+#include <QUrl>
+#include <QDebug>
+#include <KDescendantsProxyModel>
+
+#include "version-kue.h"
+#include <KAboutData>
+#include <KLocalizedContext>
+#include <KLocalizedString>
+
+#include "kueconfig.h"
+
+using namespace Qt::Literals::StringLiterals;
+
+int main(int argc, char *argv[])
+{
+ QApplication app(argc, argv);
+
+ // Default to org.kde.desktop style unless the user forces another style
+ if (qEnvironmentVariableIsEmpty("QT_QUICK_CONTROLS_STYLE")) {
+ QQuickStyle::setStyle(u"org.kde.desktop"_s);
+ }
+
+ KLocalizedString::setApplicationDomain("kue");
+ QCoreApplication::setOrganizationName(u"KDE"_s);
+
+ KAboutData aboutData(
+ // The program name used internally.
+ u"kue"_s,
+ // A displayable program name string.
+ i18nc("@title", "Kue"),
+ // The program version string.
+ QStringLiteral(KUE_VERSION_STRING),
+ // Short description of what the app does.
+ i18n("Application Description"),
+ // The license this code is released under.
+ KAboutLicense::GPL,
+ // Copyright Statement.
+ i18n("(c) 2024"));
+ aboutData.addAuthor(i18nc("@info:credit", "Alexander Kavon"),
+ i18nc("@info:credit", "Maintainer"),
+ u"me+kue@alexkavon.com"_s,
+ u"https://yourwebsite.com"_s);
+ aboutData.setTranslator(i18nc("NAME OF TRANSLATORS", "Your names"), i18nc("EMAIL OF TRANSLATORS", "Your emails"));
+ KAboutData::setApplicationData(aboutData);
+ QGuiApplication::setWindowIcon(QIcon::fromTheme(u"org.kde.kue"_s));
+
+ QQmlApplicationEngine engine;
+
+ auto config = KueConfig::self();
+
+ qRegisterMetaType<KDescendantsProxyModel*>("KDescendantsProxyModel*");
+ qmlRegisterSingletonInstance("org.kde.kue.private", 1, 0, "Kue", config);
+
+ engine.rootContext()->setContextObject(new KLocalizedContext(&engine));
+ engine.loadFromModule("org.kde.kue", u"Main"_s);
+
+ if (engine.rootObjects().isEmpty()) {
+ return -1;
+ }
+
+ return app.exec();
+}
diff --git a/src/qml/Main.qml b/src/qml/Main.qml
new file mode 100644
index 0000000..cef37e9
--- /dev/null
+++ b/src/qml/Main.qml
@@ -0,0 +1,168 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+// SPDX-FileCopyrightText: 2024 Alexander Kavon <me+kue@alexkavon.com>
+
+import QtQuick
+import QtQuick.Controls as QQC2
+import QtQuick.Layouts
+
+import org.kde.kirigami as Kirigami
+import org.kde.kirigamiaddons.statefulapp as StatefulApp
+
+import org.kde.kue
+import org.kde.kue.settings as Settings
+
+StatefulApp.StatefulWindow {
+ id: root
+
+ property int counter: 0
+
+ title: i18nc("@title:window", "Kue")
+
+ windowName: "Kue"
+
+ minimumWidth: Kirigami.Units.gridUnit * 20
+ minimumHeight: Kirigami.Units.gridUnit * 20
+
+ application: KueApplication {
+ configurationView: Settings.KueConfigurationView {}
+ }
+
+ // Connections {
+ // target: root.application
+
+ // function onIncrementCounter(): void {
+ // root.counter += 1;
+ // }
+ // }
+
+ // globalDrawer: Kirigami.GlobalDrawer {
+ // // isMenu: !Kirigami.Settings.isMobile
+ // actions: [
+ // Kirigami.Action {
+ // id: incrementCounterAction
+ // fromQAction: root.application.action("increment_counter")
+ // },
+ // Kirigami.Action {
+ // separator: true
+ // },
+ // Kirigami.Action {
+ // fromQAction: root.application.action("options_configure")
+ // },
+ // Kirigami.Action {
+ // fromQAction: root.application.action("options_configure_keybinding")
+ // },
+ // Kirigami.Action {
+ // separator: true
+ // },
+ // Kirigami.Action {
+ // id: aboutAction
+ // fromQAction: root.application.action("open_about_page")
+ // },
+ // Kirigami.Action {
+ // fromQAction: root.application.action("open_about_kde_page")
+ // },
+ // Kirigami.Action {
+ // fromQAction: root.application.action("file_quit")
+ // }
+ // ]
+ // }
+
+ pageStack.initialPage: KueApplication.loading ? loadingPage : mainPage
+
+ Component {
+ id: loadingPage
+ Kirigami.Page {
+ Kirigami.PlaceholderMessage {
+ anchors.centerIn: parent
+ text: i18n("Loading, please wait...")
+ }
+ }
+ }
+
+ Kirigami.ScrollablePage {
+ id: mainPage
+
+ title: i18nc("@title", "Kue")
+
+ supportsRefreshing: true
+
+ ListView {
+ model: KueApplication.descendantsProxyModel
+ highlight: Rectangle {
+ width: parent.width
+ color: "blue"
+ }
+ delegate: Kirigami.SwipeListItem {
+ id: task
+
+ required property bool completed
+
+ contentItem: RowLayout {
+ QQC2.CheckBox {
+ id: control
+ checked: task.completed
+ onCheckedChanged: {
+ if (control.checked != task.completed) {
+ task.completed = control.checked;
+ }
+ }
+ indicator: Rectangle {
+ implicitWidth: 30
+ implicitHeight: 30
+ x: control.leftPadding
+ y: parent.height / 2 - height / 2
+ border.color: control.down ? "darkblue" : "gray"
+ border.width: 2
+ Rectangle {
+ visible: control.checked
+ color: "red"
+ radius: 1
+ width: 15
+ height: 15
+ anchors.margins: 5
+ anchors.fill: parent
+ }
+ }
+ }
+
+ QQC2.TextField {
+ id: taskEdit
+ Layout.fillWidth: true
+ height: Math.max(implicitHeight, Kirigami.Units.iconSizes.smallMedium)
+ placeholderText: "Task Info..."
+ text: model.display + " : " + task.completed
+ wrapMode: TextInput.Wrap
+ background: Rectangle {
+ id: taskEditBg
+ border.color: "transparent"
+ color: "transparent"
+ Rectangle {
+ visible: taskEdit.activeFocus
+ anchors.bottom: taskEditBg.bottom
+ height: 2
+ width: parent.width
+ color: "green"
+ }
+ }
+ }
+
+ Kirigami.Icon {
+ source: "view-list-details"
+ visible: taskEdit.activeFocus
+ implicitHeight: 20
+ implicitWidth: 20
+ }
+ }
+ }
+ section {
+ property: "section"
+ delegate: Kirigami.ListSectionHeader {
+ required property string section
+
+ text: qsTr("Section %1").arg(parseInt(section) + 1)
+ width: ListView.view.width - ListView.view.leftMargin - ListView.view.rightMargin
+ }
+ }
+ }
+ }
+}
diff --git a/src/settings/CMakeLists.txt b/src/settings/CMakeLists.txt
new file mode 100644
index 0000000..d4847a6
--- /dev/null
+++ b/src/settings/CMakeLists.txt
@@ -0,0 +1,11 @@
+# SPDX-FileCopyrightText: 2024 Alexander Kavon <me+kue@alexkavon.com>
+# SPDX-License-Identifier: BSD-2-Clause
+
+qt_add_library(kue_settings STATIC)
+ecm_add_qml_module(kue_settings
+ GENERATE_PLUGIN_SOURCE
+ URI org.kde.kue.settings
+ QML_FILES
+ KueConfigurationView.qml
+ GeneralPage.qml
+)
diff --git a/src/settings/GeneralPage.qml b/src/settings/GeneralPage.qml
new file mode 100644
index 0000000..3324c95
--- /dev/null
+++ b/src/settings/GeneralPage.qml
@@ -0,0 +1,27 @@
+// SPDX-FileCopyrightText: 2024 Alexander Kavon <me+kue@alexkavon.com>
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+pragma ComponentBehavior: Bound
+
+import QtQuick
+import org.kde.kirigamiaddons.formcard as FormCard
+
+FormCard.FormCardPage {
+ id: root
+
+ title: i18nc("@title", "General")
+
+ FormCard.FormHeader {
+ title: i18nc("@title:group", "My Group")
+ }
+
+ FormCard.FormHeader {
+ title: i18nc("@title:group", "My Group:")
+ }
+
+ FormCard.FormCard {
+ FormCard.FormTextFieldDelegate {
+ label: i18nc("@label:textbox", "My Label:")
+ }
+ }
+}
diff --git a/src/settings/KueConfigurationView.qml b/src/settings/KueConfigurationView.qml
new file mode 100644
index 0000000..c93ec52
--- /dev/null
+++ b/src/settings/KueConfigurationView.qml
@@ -0,0 +1,20 @@
+// SPDX-FileCopyrightText: 2024 Alexander Kavon <me+kue@alexkavon.com>
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+pragma ComponentBehavior: Bound
+
+import QtQuick
+import org.kde.kirigamiaddons.settings as KirigamiSettings
+
+KirigamiSettings.ConfigurationView {
+ id: root
+
+ modules: [
+ KirigamiSettings.ConfigurationModule {
+ moduleId: "general"
+ text: i18nc("@action:button", "General")
+ icon.name: "preferences-system-symbolic"
+ page: () => Qt.createComponent("org.kde.kue.settings", "GeneralPage")
+ }
+ ]
+}