chore: split cmake into multiple files and fix settings searching regex + add enabled option to llm
C++ / fmt (pull_request) Successful in 4s
JS/TS / fmt (pull_request) Failing after 17s
JS/TS / lint (pull_request) Successful in 19s
Python / static (pull_request) Successful in 1m11s
Rust / fmt (pull_request) Successful in 1m3s
Rust / build (pull_request) Successful in 2m26s
Rust / clippy (pull_request) Failing after 16m40s
Python / verify (pull_request) Failing after 17m52s
C++ / clang-tidy (pull_request) Failing after 18m0s
C++ / build (pull_request) Failing after 18m2s

This commit is contained in:
2026-09-01 14:30:04 +02:00
parent 2150859847
commit ef2fb95fab
20 changed files with 855 additions and 641 deletions
+23
View File
@@ -1 +1,24 @@
find_package(Qt6 REQUIRED COMPONENTS ShaderTools Core Qml Gui Quick Concurrent Sql Network DBus CanvasPainter)
find_package(PkgConfig REQUIRED)
pkg_check_modules(Qalculate IMPORTED_TARGET libqalculate REQUIRED)
pkg_check_modules(Pipewire IMPORTED_TARGET libpipewire-0.3 REQUIRED)
pkg_check_modules(Aubio IMPORTED_TARGET aubio REQUIRED)
pkg_check_modules(Cava IMPORTED_TARGET libcava QUIET)
pkg_check_modules(GLIB REQUIRED glib-2.0 gobject-2.0 gio-2.0)
if(NOT Cava_FOUND)
pkg_check_modules(Cava IMPORTED_TARGET cava REQUIRED)
endif()
include(cmake/sensorslib.cmake)
set(QT_QML_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/qml")
qt_standard_project_setup(REQUIRES 6.9)
include(cmake/pch.cmake)
include(cmake/qml-module.cmake)
add_library(zshell-util INTERFACE)
target_include_directories(zshell-util INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/include")
add_subdirectory(ZShell)
+5 -55
View File
@@ -1,55 +1,3 @@
find_package(Qt6 REQUIRED COMPONENTS ShaderTools Core Qml Gui Quick Concurrent Sql Network DBus CanvasPainter)
find_package(PkgConfig REQUIRED)
find_library(SENSORS_LIBRARY NAMES sensors REQUIRED)
find_path(SENSORS_INCLUDE_DIR NAMES sensors/sensors.h REQUIRED)
pkg_check_modules(Qalculate IMPORTED_TARGET libqalculate REQUIRED)
pkg_check_modules(Pipewire IMPORTED_TARGET libpipewire-0.3 REQUIRED)
pkg_check_modules(Aubio IMPORTED_TARGET aubio REQUIRED)
pkg_check_modules(Cava IMPORTED_TARGET libcava QUIET)
pkg_check_modules(GLIB REQUIRED glib-2.0 gobject-2.0 gio-2.0)
if(NOT Cava_FOUND)
pkg_check_modules(Cava IMPORTED_TARGET cava REQUIRED)
endif()
if(NOT TARGET Sensors::Sensors)
add_library(Sensors::Sensors UNKNOWN IMPORTED)
set_target_properties(Sensors::Sensors PROPERTIES
IMPORTED_LOCATION "${SENSORS_LIBRARY}"
INTERFACE_INCLUDE_DIRECTORIES "${SENSORS_INCLUDE_DIR}"
)
endif()
set(QT_QML_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/qml")
qt_standard_project_setup(REQUIRES 6.9)
function(qml_module arg_TARGET)
cmake_parse_arguments(PARSE_ARGV 1 arg "" "URI" "SOURCES;LIBRARIES;RESOURCES")
qt_add_qml_module(${arg_TARGET}
URI ${arg_URI}
VERSION 1.0
SOURCES ${arg_SOURCES}
RESOURCES ${arg_RESOURCES}
)
qt_query_qml_module(${arg_TARGET}
URI module_uri
VERSION module_version
PLUGIN_TARGET module_plugin_target
TARGET_PATH module_target_path
QMLDIR module_qmldir
TYPEINFO module_typeinfo
)
set(module_dir "${INSTALL_QMLDIR}/${module_target_path}")
install(TARGETS ${arg_TARGET} LIBRARY DESTINATION "${module_dir}" RUNTIME DESTINATION "${module_dir}")
install(TARGETS "${module_plugin_target}" LIBRARY DESTINATION "${module_dir}" RUNTIME DESTINATION "${module_dir}")
install(FILES "${module_qmldir}" DESTINATION "${module_dir}")
install(FILES "${module_typeinfo}" DESTINATION "${module_dir}")
target_link_libraries(${arg_TARGET} PRIVATE Qt::Core Qt::Qml ${arg_LIBRARIES})
endfunction()
set_source_files_properties("${SETTINGS_INDEX_JSON}" PROPERTIES QT_RESOURCE_ALIAS "settings-index.json")
qml_module(ZShell
URI ZShell
SOURCES
@@ -60,8 +8,6 @@ qml_module(ZShell
toaster.hpp toaster.cpp
qalculator.hpp qalculator.cpp
zutils.hpp zutils.cpp
RESOURCES
"${SETTINGS_INDEX_JSON}"
LIBRARIES
Qt::Gui
Qt::Quick
@@ -69,9 +15,13 @@ qml_module(ZShell
Qt::Sql
Qt::DBus
PkgConfig::Qalculate
zshell-util
)
target_compile_definitions(ZShell PRIVATE ZSHELL_VERSION="${VERSION}")
target_compile_definitions(ZShell PRIVATE
ZSHELL_VERSION="${VERSION}"
GIT_REVISION="${GIT_REVISION}"
)
add_subdirectory(Models)
add_subdirectory(Internal)
+1
View File
@@ -24,6 +24,7 @@ class Llm : public ConfigObject {
CFG_PROPERTY(QString, model, "")
CFG_PROPERTY(double, temperature, 0.7)
CFG_PROPERTY(bool, tools, true)
CFG_PROPERTY(bool, enabled, true)
CONFIG_SUBOBJECT(LlmAppearance, appearance)
public:
+82 -6
View File
@@ -5,6 +5,7 @@
#include <QtQuick/qquickwindow.h>
#include <qcontainerfwd.h>
#include <qdir.h>
#include <qdiriterator.h>
#include <qfileinfo.h>
#include <qfuturewatcher.h>
#include <qjsprimitivevalue.h>
@@ -12,6 +13,8 @@
#include <qqmlengine.h>
#include <qfile.h>
#include "util/metaenum.hpp"
Q_LOGGING_CATEGORY(lcZUtils, "ZShell.cutils", QtInfoMsg)
namespace ZShell {
@@ -171,13 +174,44 @@ qreal ZUtils::clamp(qreal value, qreal min, qreal max) {
return qBound(min, value, max);
}
QString ZUtils::settingsIndex() {
QFile file(QStringLiteral(":/qt/qml/ZShell/settings-index.json"));
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
qCWarning(lcZUtils) << "Failed to open embedded settings index";
return QString();
QString ZUtils::enumToString(
QObject* target, const QString& property, const QVariant& value) {
if (!target) {
qCWarning(lcZUtils) << "enumToString: a target is required";
return {};
}
return QString::fromUtf8(file.readAll());
const auto* meta = target->metaObject();
const auto index = meta->indexOfProperty(property.toUtf8().constData());
if (index < 0) {
qCWarning(lcZUtils)
<< "enumToString:" << target << "has no property" << property;
return {};
}
const auto prop = meta->property(index);
const auto metaEnum = prop.isEnumType()
? prop.enumerator()
: util::metaEnumFor(prop.metaType());
if (!metaEnum.isValid() || metaEnum.is64Bit()) {
qCWarning(lcZUtils) << "enumToString: property" << property << "of"
<< target << "is not a supported enum";
return {};
}
const auto val = value.isValid() ? value : prop.read(target);
const auto* key = util::enumKeyFor(metaEnum, val);
if (!key) {
qCWarning(
lcZUtils,
"enumToString: no enumerator of %s::%s has the value %lld",
metaEnum.scope(),
metaEnum.name(),
val.toLongLong());
return {};
}
return QString::fromUtf8(key);
}
#ifndef ZSHELL_VERSION
@@ -192,4 +226,46 @@ QString ZUtils::qtVersion() const {
return QStringLiteral(QT_VERSION_STR);
}
QString ZUtils::gitRevision() {
#ifdef GIT_REVISION
return QStringLiteral(GIT_REVISION);
#else
return QString();
#endif
}
QString ZUtils::readTextFile(const QString& path) {
QFile file(path);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
return QString();
}
return QString::fromUtf8(file.readAll());
}
bool ZUtils::writeTextFile(const QString& path, const QString& text) {
const QFileInfo info(path);
if (!QDir().mkpath(info.absolutePath())) {
qCWarning(lcZUtils) << "Failed to create directory for" << path;
return false;
}
QFile file(path);
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
qCWarning(lcZUtils) << "Failed to open" << path << "for writing";
return false;
}
return file.write(text.toUtf8()) >= 0;
}
QStringList ZUtils::listFiles(const QString& dir, const QString& suffix) {
QStringList out;
QDirIterator it(dir, QDirIterator::Subdirectories);
while (it.hasNext()) {
const QString path = it.next();
if (it.fileInfo().isFile() && path.endsWith(suffix)) {
out.append(path);
}
}
return out;
}
} // namespace ZShell
+20 -1
View File
@@ -4,6 +4,8 @@
#include <qcontainerfwd.h>
#include <qobject.h>
#include <qqmlintegration.h>
#include <qtmetamacros.h>
#include <qvariant.h>
namespace ZShell {
@@ -32,7 +34,24 @@ class ZUtils : public QObject {
Q_INVOKABLE static qreal clamp(qreal value, qreal min, qreal max);
Q_INVOKABLE static QString settingsIndex();
Q_INVOKABLE static QString enumToString(
QObject* target,
const QString& property,
const QVariant& value = QVariant());
Q_INVOKABLE static QString gitRevision();
Q_INVOKABLE static QString readTextFile(const QString& path);
Q_INVOKABLE static bool writeTextFile(
const QString& path, const QString& text);
Q_INVOKABLE static QStringList listFiles(
const QString& dir, const QString& suffix);
Q_INVOKABLE static QQuickItem* findChild(
QQuickItem* root, const QString& name);
Q_INVOKABLE static QList<QQuickItem*> findChildren(
QQuickItem* root, const QString& name);
Q_INVOKABLE static QList<QQuickItem*> findChildrenMatching(
QQuickItem* root, const QString& pattern);
[[nodiscard]] QString version() const;
[[nodiscard]] QString qtVersion() const;
+14
View File
@@ -0,0 +1,14 @@
add_library(zshell-pch INTERFACE)
target_precompile_headers(zshell-pch INTERFACE
<qobject.h>
<qqmlintegration.h>
<qstring.h>
<qqmlengine.h>
<qloggingcategory.h>
<qvariant.h>
<qtimer.h>
<qdir.h>
<qlist.h>
<qstringlist.h>
<qpointer.h>
)
+45
View File
@@ -0,0 +1,45 @@
message(STATUS "QML install dir: ${CMAKE_INSTALL_PREFIX}/${INSTALL_QMLDIR}")
function(qml_module arg_TARGET)
cmake_parse_arguments(PARSE_ARGV 1 arg "" "URI" "SOURCES;QML_FILES;QML_SINGLETONS;DEPENDENCIES;IMPORTS;OPTIONAL_IMPORTS;DEFAULT_IMPORTS;LIBRARIES")
qt_add_qml_module(${arg_TARGET}
URI ${arg_URI}
SOURCES ${arg_SOURCES}
QML_FILES ${arg_QML_FILES} ${arg_QML_SINGLETONS}
DEPENDENCIES ${arg_DEPENDENCIES}
IMPORTS ${arg_IMPORTS}
OPTIONAL_IMPORTS ${arg_OPTIONAL_IMPORTS}
DEFAULT_IMPORTS ${arg_DEFAULT_IMPORTS}
)
qt_query_qml_module(${arg_TARGET}
URI module_uri
PLUGIN_TARGET module_plugin_target
TARGET_PATH module_target_path
QMLDIR module_qmldir
TYPEINFO module_typeinfo
)
message(STATUS "Created QML module: ${module_uri}")
string(REPLACE "/" ";" uri_parts "${module_target_path}")
list(GET uri_parts 0 top_level)
set(backing_lib_dir "${INSTALL_QMLDIR}/${top_level}/lib")
set(module_dir "${INSTALL_QMLDIR}/${module_target_path}")
install(TARGETS ${arg_TARGET}
LIBRARY DESTINATION "${backing_lib_dir}"
RUNTIME DESTINATION "${backing_lib_dir}"
)
install(TARGETS "${module_plugin_target}"
LIBRARY DESTINATION "${module_dir}"
RUNTIME DESTINATION "${module_dir}"
)
install(FILES "${module_qmldir}" DESTINATION "${module_dir}")
install(FILES "${module_typeinfo}" DESTINATION "${module_dir}")
target_link_libraries(${arg_TARGET} PRIVATE Qt::Core Qt::Qml ${arg_LIBRARIES})
file(RELATIVE_PATH plugin_to_lib "/${module_target_path}" "/${top_level}/lib")
set_property(TARGET ${module_plugin_target} APPEND PROPERTY INSTALL_RPATH "$ORIGIN/${plugin_to_lib}")
endfunction()
+10
View File
@@ -0,0 +1,10 @@
find_library(SENSORS_LIBRARY NAMES sensors REQUIRED)
find_path(SENSORS_INCLUDE_DIR NAMES sensors/sensors.h REQUIRED)
if(NOT TARGET Sensors::Sensors)
add_library(Sensors::Sensors UNKNOWN IMPORTED)
set_target_properties(Sensors::Sensors PROPERTIES
IMPORTED_LOCATION "${SENSORS_LIBRARY}"
INTERFACE_INCLUDE_DIRECTORIES "${SENSORS_INCLUDE_DIR}"
)
endif()
+31
View File
@@ -0,0 +1,31 @@
#pragma once
#include <qmetaobject.h>
#include <qmetatype.h>
#include <qvariant.h>
namespace util {
inline QMetaEnum metaEnumFor(const QMetaType& type) {
const auto* meta = type.metaObject();
if (!meta) return {};
auto name = QByteArray(type.name());
if (const auto scope = name.lastIndexOf("::"); scope >= 0)
name = name.mid(scope + 2);
return meta->enumerator(meta->indexOfEnumerator(name.constData()));
}
inline bool isSupportedEnum(const QMetaType& type) {
if (!type.flags().testFlag(QMetaType::IsEnumeration)) return false;
const auto metaEnum = metaEnumFor(type);
return metaEnum.isValid() && !metaEnum.is64Bit();
}
inline const char* enumKeyFor(const QMetaEnum& metaEnum, const QVariant& value) {
return metaEnum.valueToKey(static_cast<quint64>(value.toLongLong()));
}
} // namespace util