plugin: add qalculator

For launcher >calc instead of qalc proc
This commit is contained in:
2 * r + 2 * t 2025-09-04 15:40:31 +10:00
parent bcba9f6d73
commit 050ddf7c3e
5 changed files with 77 additions and 41 deletions

View file

@ -1,8 +1,8 @@
import qs.components import qs.components
import qs.services import qs.services
import qs.config import qs.config
import Caelestia
import Quickshell import Quickshell
import Quickshell.Io
import QtQuick import QtQuick
import QtQuick.Layouts import QtQuick.Layouts
@ -13,7 +13,7 @@ Item {
readonly property string math: list.search.text.slice(`${Config.launcher.actionPrefix}calc `.length) readonly property string math: list.search.text.slice(`${Config.launcher.actionPrefix}calc `.length)
function onClicked(): void { 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; root.list.visibilities.launcher = false;
} }
@ -22,13 +22,6 @@ Item {
anchors.left: parent?.left anchors.left: parent?.left
anchors.right: parent?.right anchors.right: parent?.right
onMathChanged: {
if (math) {
qalcProc.command = ["qalc", "-m", "100", math];
qalcProc.running = true;
}
}
StateLayer { StateLayer {
radius: Appearance.rounding.full 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 { RowLayout {
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
@ -71,28 +48,18 @@ Item {
id: result id: result
color: { color: {
if (metrics.text.includes("error: ")) if (text.includes("error: ") || text.includes("warning: "))
return Colours.palette.m3error; return Colours.palette.m3error;
if (!root.math) if (!root.math)
return Colours.palette.m3onSurfaceVariant; return Colours.palette.m3onSurfaceVariant;
return Colours.palette.m3onSurface; return Colours.palette.m3onSurface;
} }
text: metrics.elidedText text: root.math.length > 0 ? Qalculator.eval(root.math) : qsTr("Type an expression to calculate")
font.pointSize: Appearance.font.size.normal elide: Text.ElideLeft
Layout.fillWidth: true Layout.fillWidth: true
Layout.alignment: Qt.AlignVCenter 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 { StyledRect {

View file

@ -95,8 +95,8 @@
fileset = lib.fileset.union ./../CMakeLists.txt ./../plugin; fileset = lib.fileset.union ./../CMakeLists.txt ./../plugin;
}; };
nativeBuildInputs = [cmake ninja]; nativeBuildInputs = [cmake ninja pkg-config];
buildInputs = [qt6.qtbase qt6.qtdeclarative]; buildInputs = [qt6.qtbase qt6.qtdeclarative libqalculate];
dontWrapQtApps = true; dontWrapQtApps = true;
cmakeFlags = cmakeFlags =

View file

@ -1,3 +1,6 @@
find_package(PkgConfig REQUIRED)
pkg_check_modules(QALCULATE REQUIRED libqalculate)
qt_add_qml_module(caelestia qt_add_qml_module(caelestia
URI Caelestia URI Caelestia
VERSION 0.1 VERSION 0.1
@ -5,6 +8,7 @@ qt_add_qml_module(caelestia
cutils.hpp cutils.cpp cutils.hpp cutils.cpp
cachingimagemanager.hpp cachingimagemanager.cpp cachingimagemanager.hpp cachingimagemanager.cpp
filesystemmodel.hpp filesystemmodel.cpp filesystemmodel.hpp filesystemmodel.cpp
qalculator.hpp qalculator.cpp
) )
qt_query_qml_module(caelestia 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_qmldir}" DESTINATION "${module_dir}")
install(FILES "${module_typeinfo}" 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})

View file

@ -0,0 +1,49 @@
#include "qalculator.hpp"
#include <QObject>
#include <libqalculate/qalculate.h>
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);
}

View file

@ -0,0 +1,15 @@
#pragma once
#include <QObject>
#include <qqmlintegration.h>
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;
};