From 050ddf7c3e4ea6aa7a18087d17aee2a43781d0af Mon Sep 17 00:00:00 2001 From: 2 * r + 2 * t <61896496+soramanew@users.noreply.github.com> Date: Thu, 4 Sep 2025 15:40:31 +1000 Subject: plugin: add qalculator For launcher >calc instead of qalc proc --- modules/launcher/items/CalcItem.qml | 43 ++++---------------------------- nix/default.nix | 4 +-- plugin/src/Caelestia/CMakeLists.txt | 7 +++++- plugin/src/Caelestia/qalculator.cpp | 49 +++++++++++++++++++++++++++++++++++++ plugin/src/Caelestia/qalculator.hpp | 15 ++++++++++++ 5 files changed, 77 insertions(+), 41 deletions(-) create mode 100644 plugin/src/Caelestia/qalculator.cpp create mode 100644 plugin/src/Caelestia/qalculator.hpp diff --git a/modules/launcher/items/CalcItem.qml b/modules/launcher/items/CalcItem.qml index 211ac61..120866f 100644 --- a/modules/launcher/items/CalcItem.qml +++ b/modules/launcher/items/CalcItem.qml @@ -1,8 +1,8 @@ import qs.components import qs.services import qs.config +import Caelestia import Quickshell -import Quickshell.Io import QtQuick import QtQuick.Layouts @@ -13,7 +13,7 @@ Item { readonly property string math: list.search.text.slice(`${Config.launcher.actionPrefix}calc `.length) function onClicked(): void { - Quickshell.execDetached(["sh", "-c", `qalc -t -m 100 '${root.math}' | wl-copy`]); + Quickshell.execDetached(["wl-copy", Qalculator.eval(math, false)]); root.list.visibilities.launcher = false; } @@ -22,13 +22,6 @@ Item { anchors.left: parent?.left anchors.right: parent?.right - onMathChanged: { - if (math) { - qalcProc.command = ["qalc", "-m", "100", math]; - qalcProc.running = true; - } - } - StateLayer { radius: Appearance.rounding.full @@ -37,22 +30,6 @@ Item { } } - Binding { - id: binding - - when: root.math.length > 0 - target: metrics - property: "text" - } - - Process { - id: qalcProc - - stdout: StdioCollector { - onStreamFinished: binding.value = text.trim() - } - } - RowLayout { anchors.left: parent.left anchors.right: parent.right @@ -71,28 +48,18 @@ Item { id: result color: { - if (metrics.text.includes("error: ")) + if (text.includes("error: ") || text.includes("warning: ")) return Colours.palette.m3error; if (!root.math) return Colours.palette.m3onSurfaceVariant; return Colours.palette.m3onSurface; } - text: metrics.elidedText - font.pointSize: Appearance.font.size.normal + text: root.math.length > 0 ? Qalculator.eval(root.math) : qsTr("Type an expression to calculate") + elide: Text.ElideLeft Layout.fillWidth: true Layout.alignment: Qt.AlignVCenter - - TextMetrics { - id: metrics - - text: qsTr("Type an expression to calculate") - font.family: result.font.family - font.pointSize: result.font.pointSize - elide: Text.ElideRight - elideWidth: result.width - } } StyledRect { diff --git a/nix/default.nix b/nix/default.nix index b97bc1b..acb6d8f 100644 --- a/nix/default.nix +++ b/nix/default.nix @@ -95,8 +95,8 @@ fileset = lib.fileset.union ./../CMakeLists.txt ./../plugin; }; - nativeBuildInputs = [cmake ninja]; - buildInputs = [qt6.qtbase qt6.qtdeclarative]; + nativeBuildInputs = [cmake ninja pkg-config]; + buildInputs = [qt6.qtbase qt6.qtdeclarative libqalculate]; dontWrapQtApps = true; cmakeFlags = diff --git a/plugin/src/Caelestia/CMakeLists.txt b/plugin/src/Caelestia/CMakeLists.txt index d00247e..6461027 100644 --- a/plugin/src/Caelestia/CMakeLists.txt +++ b/plugin/src/Caelestia/CMakeLists.txt @@ -1,3 +1,6 @@ +find_package(PkgConfig REQUIRED) +pkg_check_modules(QALCULATE REQUIRED libqalculate) + qt_add_qml_module(caelestia URI Caelestia VERSION 0.1 @@ -5,6 +8,7 @@ qt_add_qml_module(caelestia cutils.hpp cutils.cpp cachingimagemanager.hpp cachingimagemanager.cpp filesystemmodel.hpp filesystemmodel.cpp + qalculator.hpp qalculator.cpp ) qt_query_qml_module(caelestia @@ -24,4 +28,5 @@ install(TARGETS "${module_plugin_target}" LIBRARY DESTINATION "${module_dir}" RU install(FILES "${module_qmldir}" DESTINATION "${module_dir}") install(FILES "${module_typeinfo}" DESTINATION "${module_dir}") -target_link_libraries(caelestia PRIVATE Qt::Core Qt::Qml Qt::Gui Qt::Concurrent) +target_include_directories(caelestia SYSTEM PRIVATE ${QALCULATE_INCLUDE_DIRS}) +target_link_libraries(caelestia PRIVATE Qt::Core Qt::Qml Qt::Gui Qt::Concurrent ${QALCULATE_LIBRARIES}) diff --git a/plugin/src/Caelestia/qalculator.cpp b/plugin/src/Caelestia/qalculator.cpp new file mode 100644 index 0000000..2e18033 --- /dev/null +++ b/plugin/src/Caelestia/qalculator.cpp @@ -0,0 +1,49 @@ +#include "qalculator.hpp" + +#include +#include + +Qalculator::Qalculator(QObject* parent) + : QObject(parent) { + if (!CALCULATOR) { + new Calculator(); + CALCULATOR->loadExchangeRates(); + CALCULATOR->loadGlobalDefinitions(); + CALCULATOR->loadLocalDefinitions(); + } +} + +QString Qalculator::eval(const QString& expr, bool printExpr) const { + if (expr.isEmpty()) { + return QString(); + } + + EvaluationOptions eo; + PrintOptions po; + + std::string parsed; + std::string result = CALCULATOR->calculateAndPrint( + CALCULATOR->unlocalizeExpression(expr.toStdString(), eo.parse_options), 100, eo, po, &parsed); + + std::string error; + while (CALCULATOR->message()) { + if (!CALCULATOR->message()->message().empty()) { + if (CALCULATOR->message()->type() == MESSAGE_ERROR) { + error += "error: "; + } else if (CALCULATOR->message()->type() == MESSAGE_WARNING) { + error += "warning: "; + } + error += CALCULATOR->message()->message(); + } + CALCULATOR->nextMessage(); + } + if (!error.empty()) { + return QString::fromStdString(error); + } + + if (printExpr) { + return QString("%1 = %2").arg(parsed).arg(result); + } + + return QString::fromStdString(result); +} diff --git a/plugin/src/Caelestia/qalculator.hpp b/plugin/src/Caelestia/qalculator.hpp new file mode 100644 index 0000000..266699f --- /dev/null +++ b/plugin/src/Caelestia/qalculator.hpp @@ -0,0 +1,15 @@ +#pragma once + +#include +#include + +class Qalculator : public QObject { + Q_OBJECT + QML_ELEMENT + QML_SINGLETON + +public: + explicit Qalculator(QObject* parent = nullptr); + + Q_INVOKABLE QString eval(const QString& expr, bool printExpr = true) const; +}; -- cgit v1.2.3-freya