Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F85651326
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Award Token
Flag For Later
Size
27 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 992f82a..f387cfc 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1,344 +1,356 @@
function(kazv_add_qml_files)
set(options "")
set(oneValueArgs BASE_DIRECTORY)
set(multiValueArgs SOURCES)
cmake_parse_arguments(PARSE_ARGV 0 kazv_add_qml_files "${options}" "${oneValueArgs}" "${multiValueArgs}")
set(target "${kazv_add_qml_files_UNPARSED_ARGUMENTS}")
set(allSources)
foreach(source ${kazv_add_qml_files_SOURCES})
message(STATUS "Adding source: ${kazv_add_qml_files_BASE_DIRECTORY} / ${source}")
set_source_files_properties(
"${kazv_add_qml_files_BASE_DIRECTORY}/${source}"
PROPERTIES
QT_RESOURCE_ALIAS "${source}"
)
list(APPEND allSources "${kazv_add_qml_files_BASE_DIRECTORY}/${source}")
endforeach()
qt_target_qml_sources(
"${target}"
QML_FILES ${allSources}
)
endfunction()
if(WIN32)
set(KAZV_IS_WINDOWS 1)
else()
set(KAZV_IS_WINDOWS 0)
endif()
if(ANDROID)
set(KAZV_IS_ANDROID 1)
else()
set(KAZV_IS_ANDROID 0)
endif()
configure_file(kazv-version.cpp.in kazv-version.cpp)
configure_file(kazv-platform.hpp.in kazv-platform.hpp)
configure_file(kazv-defs.hpp.in kazv-defs.hpp)
set(kazvqmlmodule_SRCS
qt-job-handler.cpp
qt-job.cpp
${CMAKE_CURRENT_BINARY_DIR}/kazv-version.cpp
constants.cpp
matrix-sdk.cpp
matrix-session.cpp
matrix-session-controller.cpp
sso-login-process.cpp
kazv-session-lock-guard.cpp
matrix-room.cpp
matrix-room-list.cpp
matrix-room-timeline.cpp
matrix-room-pinned-events-timeline.cpp
matrix-room-member.cpp
matrix-room-member-list-model.cpp
matrix-room-state.cpp
matrix-event-reader.cpp
matrix-event-reader-list-model.cpp
matrix-event-reaction-list-model.cpp
matrix-event-reaction.cpp
matrix-event.cpp
matrix-event-list.cpp
matrix-link.cpp
meta-types.cpp
l10n-provider.cpp
qt-rand-adapter.cpp
helper.cpp
matrix-promise.cpp
kazv-util.cpp
matrix-sticker-pack.cpp
matrix-sticker.cpp
matrix-sticker-pack-list.cpp
matrix-sticker-pack-source.cpp
matrix-user-given-attrs-map.cpp
matrix-verification.cpp
matrix-verification-list.cpp
kazv-abstract-list-model.cpp
qt-promise-handler.cpp
device-mgmt/matrix-device.cpp
device-mgmt/matrix-device-list.cpp
kazv-config.cpp
kazv-path-config.cpp
kazv-io-manager.cpp
kazv-io-job.cpp
kazv-file.cpp
upload-job-model.cpp
kazv-markdown.cpp
kazv-clipboard.cpp
db-store.cpp
)
ecm_qt_declare_logging_category(kazvqmlmodule_SRCS
HEADER kazv-log.hpp
IDENTIFIER kazvLog
CATEGORY_NAME moe.kazv.mxc.kazv
)
qt_add_qml_module(kazvqmlmodule
STATIC
URI moe.kazv.mxc.kazv
VERSION 0.0
SOURCES ${kazvqmlmodule_SRCS}
)
+kconfig_target_kcfg_file(kazvqmlmodule
+ FILE kazv-settings.kcfg
+ CLASS_NAME KazvSettings
+ MUTATORS
+)
+kconfig_target_kcfg_file(kazvqmlmodule
+ FILE kazv-sessions-settings.kcfg
+ CLASS_NAME KazvSessionsSettings
+ MUTATORS
+)
+
target_link_libraries(kazvqmlmodule PUBLIC
libkazv::kazvall
Qt${QT_MAJOR_VERSION}::Core
Qt${QT_MAJOR_VERSION}::Network
Threads::Threads
Qt${QT_MAJOR_VERSION}::Gui
Qt${QT_MAJOR_VERSION}::Qml
Qt${QT_MAJOR_VERSION}::Quick
Qt${QT_MAJOR_VERSION}::QuickControls2
Qt${QT_MAJOR_VERSION}::Svg
Qt${QT_MAJOR_VERSION}::Concurrent
Qt${QT_MAJOR_VERSION}::Widgets
Qt${QT_MAJOR_VERSION}::Sql
Qt${QT_MAJOR_VERSION}::HttpServer
KF${KF_MAJOR_VERSION}::ConfigCore
+ KF${KF_MAJOR_VERSION}::ConfigGui
KF${KF_MAJOR_VERSION}::Notifications
KF${KF_MAJOR_VERSION}::CoreAddons
QCoro::Core
${CMARK_TARGET_NAME}
)
if(ANDROID)
target_link_libraries(kazvqmlmodule PUBLIC
KF${KF_MAJOR_VERSION}::Kirigami
OpenSSL::SSL
)
endif()
target_include_directories(kazvqmlmodule PUBLIC ${CMAKE_CURRENT_BINARY_DIR})
target_include_directories(kazvqmlmodule PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/device-mgmt)
qt_add_qml_module(kazvshortcutsqmlmodule
STATIC
URI moe.kazv.mxc.kazvshortcuts
VERSION 0.0
SOURCES
shortcuts/shortcut-util.cpp
)
target_link_libraries(kazvshortcutsqmlmodule PUBLIC
libkazv::kazvall
Qt${QT_MAJOR_VERSION}::Core
Qt${QT_MAJOR_VERSION}::Gui
Qt${QT_MAJOR_VERSION}::Qml
)
target_include_directories(kazvshortcutsqmlmodule
PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/shortcuts
)
add_library(kazvprivlib INTERFACE)
target_link_libraries(kazvprivlib
INTERFACE
kazvqmlmodule
kazvqmlmoduleplugin
kazvshortcutsqmlmodule
kazvshortcutsqmlmoduleplugin
)
qt_add_qml_module(kazvqmlqmlmodule
STATIC
URI moe.kazv.mxc.kazvqml
VERSION 0.0
)
kazv_add_qml_files(kazvqmlqmlmodule
BASE_DIRECTORY contents/ui
SOURCES
Main.qml
About.qml
PageManager.qml
LoginPage.qml
LoginFlows.qml
MainPage.qml
TabView.qml
Tab.qml
ClosableScrollablePage.qml
ClosableScrollableOverlay.qml
SelfDestroyableOverlaySheet.qml
FocusRingBackground.qml
RoomListView.qml
RoomListViewItemDelegate.qml
RoomPage.qml
RoomPinnedEventsPage.qml
RoomTimelineView.qml
SendMessageBox.qml
EventView.qml
EventViewWrapper.qml
EventViewCompact.qml
EventSourceView.qml
EventHistoryView.qml
EventReactions.qml
Bubble.qml
MediaFileMenu.qml
KazvIOMenu.qml
ConfirmUploadPopup.qml
StickerPicker.qml
AddStickerPopup.qml
StickerPackNameProvider.qml
ConfirmationOverlay.qml
AcceptRejectNoopOverlay.qml
VerificationsPage.qml
SasCodes.qml
event-types/Simple.qml
event-types/Text.qml
event-types/Emote.qml
event-types/Notice.qml
event-types/State.qml
event-types/TextTemplate.qml
event-types/Image.qml
event-types/File.qml
event-types/Video.qml
event-types/Audio.qml
event-types/MediaBubble.qml
event-types/Redacted.qml
event-types/Reaction.qml
event-types/Fallback.qml
TypingIndicator.qml
EventReadIndicator.qml
SelectableText.qml
ReactToEventPopup.qml
FileHandler.qml
media/PlayButton.qml
ActionSettingsPage.qml
CreateRoomPage.qml
JoinRoomPage.qml
RoomMemberListView.qml
RoomMemberListViewItemDelegate.qml
UserNameProvider.qml
RoomNameProvider.qml
Completion.qml
AsyncHandler.qml
UploadFileHelper.qml
SettingsPage.qml
settings/ProfileSettings.qml
settings/CacheSettings.qml
settings/SecuritySettings.qml
room-settings/RoomSettingsPage.qml
room-settings/RoomTagHandler.qml
room-settings/RoomMemberListPage.qml
room-settings/RoomInvitePage.qml
room-settings/RoomStickerPacksPage.qml
room-settings/RoomStickerPackItemDelegate.qml
room-settings/RoomStatePage.qml
device-mgmt/Device.qml
device-mgmt/DeviceList.qml
UserPage.qml
shortcuts/ActionCollection.qml
shortcuts/ActionItem.qml
shortcuts/ActionSettings.qml
shortcuts/ShortcutInput.qml
MessageNotification.qml
Notifier.qml
NotificationAction.qml
AvatarAdapter.qml
ImageAdapter.qml
FileDialogAdapter.qml
FolderDialogAdapter.qml
ScrollablePageAdapter.qml
emoji/Activities.qml
emoji/Flags.qml
emoji/Objects.qml
emoji/SmileysAndEmotion.qml
emoji/TravelAndPlaces.qml
emoji/AnimalsAndNature.qml
emoji/FoodAndDrink.qml
emoji/PeopleAndBody.qml
emoji/Symbols.qml
)
kazv_add_qml_files(kazvqmlqmlmodule
BASE_DIRECTORY js
SOURCES
l10n.js
global-this.js
matrix-helpers.js
sas-emoji-defs.js
)
kazv_add_qml_files(kazvqmlqmlmodule
BASE_DIRECTORY js/transformed-libs
SOURCES
fluent-bundle.js
fluent-sequence.js
fluent-langneg.js
bundled-deps.js
)
target_link_libraries(kazvqmlqmlmodule PUBLIC kazvprivlib)
set(kazv_SRCS
main.cpp
l10n/translations.qrc
)
add_executable(kazv ${kazv_SRCS})
target_link_libraries(kazv
PRIVATE
kazvqmlqmlmodule
kazvqmlqmlmoduleplugin
kazvprivlib
)
if(kazv_LINK_BREEZE_ICONS)
target_link_libraries(kazv PRIVATE KF${KF_MAJOR_VERSION}::BreezeIcons)
endif()
if(ANDROID)
message(STATUS "Collecting icons for apk deployment")
execute_process(
COMMAND
${PERL_EXECUTABLE} ${CMAKE_SOURCE_DIR}/tools/scan-icons
RESULT_VARIABLE KAZV_SCAN_ICONS_RESULT
OUTPUT_VARIABLE KAZV_FOUND_ICONS
COMMAND_ERROR_IS_FATAL ANY
)
kirigami_package_breeze_icons(ICONS ${KAZV_FOUND_ICONS})
endif()
set(kazv_INSTALL_ARGS ${KF_INSTALL_TARGETS_DEFAULT_ARGS})
if(NOT kazv_INSTALL_ARGS)
set(kazv_INSTALL_ARGS ${KF${KF_MAJOR_VERSION}_INSTALL_TARGETS_DEFAULT_ARGS})
endif()
install(TARGETS kazv ${kazv_INSTALL_ARGS})
if(ANDROID)
ecm_add_android_apk(kazv ANDROID_DIR ${CMAKE_CURRENT_SOURCE_DIR}/android)
endif()
if(kazv_BUILD_TESTS)
add_subdirectory(tests)
endif()
diff --git a/src/kazv-config.cpp b/src/kazv-config.cpp
index 655dce5..76f263f 100644
--- a/src/kazv-config.cpp
+++ b/src/kazv-config.cpp
@@ -1,63 +1,149 @@
/*
* This file is part of kazv.
* SPDX-FileCopyrightText: 2021-2024 tusooa <tusooa@kazv.moe>
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
#include <kazv-defs.hpp>
#include "kazv-config.hpp"
+#include "kazv-sessions-settings.h"
+#include "kazv-settings.h"
+
#include <KSharedConfig>
#include <KConfigGroup>
+#include <QFile>
+#include <QStandardPaths>
+
+#include <memory>
using namespace Qt::Literals::StringLiterals;
struct KazvConfigPrivate
{
- KSharedConfigPtr sessionrc{KSharedConfig::openConfig(u"kazvsessionrc"_s)};
- KConfigGroup sessionGroup{sessionrc, u"Sessions"_s};
+ KSharedConfigPtr appConfig{KSharedConfig::openConfig(
+ u"kazvrc"_s, KConfig::FullConfig, QStandardPaths::AppConfigLocation
+ )};
+
+ std::unique_ptr<KazvSessionsSettings> sessionsSettings{
+ std::make_unique<KazvSessionsSettings>(
+ KSharedConfig::openConfig(
+ u"kazvsessionrc"_s,
+ KConfig::FullConfig,
+ QStandardPaths::AppConfigLocation
+ )
+ )
+ };
- KSharedConfigPtr shortcutsrc{KSharedConfig::openConfig(u"kazv/shortcutsrc"_s)};
- KConfigGroup shortcutsGroup{shortcutsrc, u"Shortcuts"_s};
+ std::unique_ptr<KazvSettings> settings{
+ std::make_unique<KazvSettings>(appConfig)
+ };
- KSharedConfigPtr cacheDirectoryrc{KSharedConfig::openConfig(u"kazv/cacheDirectoryrc"_s)};
- KConfigGroup cacheDirectoryGroup{cacheDirectoryrc, u"CacheDirectory"_s};
+ // KConfigXT can't read/write groups directly;
+ // shortcutsGroup shares the same kazvrc instance as KazvSettings.
+ KConfigGroup shortcutsGroup{appConfig, u"Shortcuts"_s};
};
KazvConfig::KazvConfig(QObject *parent)
: QObject(parent)
, m_d(new KazvConfigPrivate)
{
+ migrateOldConfig();
+ m_d->sessionsSettings->load();
+ m_d->settings->load();
}
KazvConfig::~KazvConfig() = default;
QString KazvConfig::lastSession() const
{
- return m_d->sessionGroup.readEntry("lastSession", QString());
+ return m_d->sessionsSettings->lastSession();
}
void KazvConfig::setLastSession(QString session)
{
- m_d->sessionGroup.writeEntry("lastSession", session);
+ m_d->sessionsSettings->setLastSession(session);
+ m_d->sessionsSettings->save();
}
QStringList KazvConfig::shortcutForAction(QString actionName) const
{
return m_d->shortcutsGroup.readEntry(actionName, QStringList());
}
void KazvConfig::setShortcutForAction(QString actionName, QStringList shortcut)
{
m_d->shortcutsGroup.writeEntry(actionName, shortcut);
+ m_d->appConfig->sync();
}
QString KazvConfig::cacheDirectory() const
{
- return m_d->cacheDirectoryGroup.readEntry("cacheDirectory", QString());
+ return m_d->settings->cacheDirectory();
}
void KazvConfig::setCacheDirectory(QString cacheDirectory)
{
- m_d->cacheDirectoryGroup.writeEntry("cacheDirectory", cacheDirectory);
+ m_d->settings->setCacheDirectory(cacheDirectory);
+ m_d->settings->save();
+}
+
+void KazvConfig::migrateOldConfig()
+{
+ KSharedConfigPtr appConfig = m_d->appConfig;
+
+ const QString cacheDirectoryrcPath =
+ QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) +
+ u"/"_s + u"kazv/cacheDirectoryrc"_s;
+ if (QFile::exists(cacheDirectoryrcPath)) {
+ const auto oldConfig = KSharedConfig::openConfig(u"kazv/cacheDirectoryrc"_s);
+ const KConfigGroup oldGroup{oldConfig, u"CacheDirectory"_s};
+ KConfigGroup generalGroup = appConfig->group(u"General"_s);
+ const QString key = u"cacheDirectory"_s;
+ if (oldGroup.hasKey(key) && !generalGroup.hasKey(key)) {
+ generalGroup.writeEntry(key, oldGroup.readEntry(key, QString()));
+ }
+
+ if (appConfig->sync()) {
+ QFile::remove(cacheDirectoryrcPath);
+ }
+ }
+
+ const QString shortcutsrcPath =
+ QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) +
+ u"/"_s + u"kazv/shortcutsrc"_s;
+ if (QFile::exists(shortcutsrcPath)) {
+ const auto oldConfig = KSharedConfig::openConfig(u"kazv/shortcutsrc"_s);
+ const KConfigGroup oldGroup{oldConfig, u"Shortcuts"_s};
+ KConfigGroup newGroup = appConfig->group(u"Shortcuts"_s);
+ const QStringList keys = oldGroup.keyList();
+ for (const QString &key : keys) {
+ if (oldGroup.hasKey(key) && !newGroup.hasKey(key)) {
+ newGroup.writeEntry(key, oldGroup.readEntry(key, QStringList()));
+ }
+ }
+ if (appConfig->sync()) {
+ QFile::remove(shortcutsrcPath);
+ }
+ }
+
+ const QString sessionrcPath =
+ QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) +
+ u"/"_s + u"kazvsessionrc"_s;
+ if (QFile::exists(sessionrcPath)) {
+ const auto oldConfig = KSharedConfig::openConfig(u"kazvsessionrc"_s);
+ const KConfigGroup oldGroup{oldConfig, u"Sessions"_s};
+ const KSharedConfigPtr newSessionConfig = KSharedConfig::openConfig(
+ u"kazvsessionrc"_s, KConfig::FullConfig,
+ QStandardPaths::AppConfigLocation
+ );
+ KConfigGroup newGroup = newSessionConfig->group(u"Sessions"_s);
+ const QString key = u"lastSession"_s;
+ if (oldGroup.hasKey(key) && !newGroup.hasKey(key)) {
+ newGroup.writeEntry(key, oldGroup.readEntry(key, QString()));
+ }
+ if (newSessionConfig->sync()) {
+ QFile::remove(sessionrcPath);
+ }
+ }
}
diff --git a/src/kazv-config.hpp b/src/kazv-config.hpp
index fb567a0..a48fc4a 100644
--- a/src/kazv-config.hpp
+++ b/src/kazv-config.hpp
@@ -1,50 +1,53 @@
/*
* This file is part of kazv.
* SPDX-FileCopyrightText: 2021 Tusooa Zhu <tusooa@kazv.moe>
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
#pragma once
#include <kazv-defs.hpp>
#include <QObject>
#include <QQmlEngine>
#include <QString>
#include <QScopedPointer>
struct KazvConfigPrivate;
class KazvConfig : public QObject
{
Q_OBJECT
QML_ELEMENT
QScopedPointer<KazvConfigPrivate> m_d;
Q_PROPERTY(QString lastSession READ lastSession WRITE setLastSession)
Q_PROPERTY(QString cacheDirectory READ cacheDirectory WRITE setCacheDirectory)
public:
explicit KazvConfig(QObject *parent = 0);
~KazvConfig() override;
public Q_SLOTS:
QString lastSession() const;
void setLastSession(QString session);
QStringList shortcutForAction(QString actionName) const;
void setShortcutForAction(QString actionName, QStringList shortcut);
/**
* If Kazv calls setCacheDirectory() correctly, then this will always return a valid path
**/
QString cacheDirectory() const;
/**
* Where call this function should make sure that the cacheDirectory passed in is a valid path,
* otherwise the return value of cacheDirectory() will be an invalid path
**/
void setCacheDirectory(QString cacheDirectory);
+
+private:
+ void migrateOldConfig();
};
diff --git a/src/kazv-sessions-settings.kcfg b/src/kazv-sessions-settings.kcfg
new file mode 100644
index 0000000..44b18af
--- /dev/null
+++ b/src/kazv-sessions-settings.kcfg
@@ -0,0 +1,12 @@
+<?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" >
+ <kcfgfile arg="true" />
+ <group name="Sessions">
+ <entry name="lastSession" type="String">
+ <label>The last (most recent) session to load at startup.</label>
+ </entry>
+ </group>
+</kcfg>
diff --git a/src/kazv-settings.kcfg b/src/kazv-settings.kcfg
new file mode 100644
index 0000000..f4fe184
--- /dev/null
+++ b/src/kazv-settings.kcfg
@@ -0,0 +1,12 @@
+<?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" >
+ <kcfgfile arg="true" />
+ <group name="General">
+ <entry name="cacheDirectory" type="String">
+ <label>Directory for storing the cached files.</label>
+ </entry>
+ </group>
+</kcfg>
diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt
index 61bf8fe..ba70b0c 100644
--- a/src/tests/CMakeLists.txt
+++ b/src/tests/CMakeLists.txt
@@ -1,156 +1,157 @@
set(KAZV_TEST_TEMP_DIR ${CMAKE_CURRENT_BINARY_DIR}/test-temp)
configure_file(test-temp.hpp.in test-temp.hpp)
set(kazvtestlib_SRCS
test-model.cpp
)
add_library(kazvtestlib STATIC ${kazvtestlib_SRCS})
target_include_directories(kazvtestlib PUBLIC ${CMAKE_CURRENT_BINARY_DIR})
target_link_libraries(kazvtestlib PUBLIC kazvprivlib libkazv::kazvtestfixtures)
add_executable(matrix-sdk-session-loader matrix-sdk-session-loader.cpp matrix-sdk-sessions-test.cpp)
target_compile_definitions(matrix-sdk-session-loader PRIVATE MATRIX_SDK_SESSIONS_TEST_NO_MAIN)
target_link_libraries(matrix-sdk-session-loader Qt${QT_MAJOR_VERSION}::Test kazvtestlib)
ecm_add_tests(
qt-job-handler-test.cpp
qt-promise-handler-test.cpp
qt-json-test.cpp
device-mgmt-test.cpp
matrix-session-test.cpp
matrix-session-controller-test.cpp
matrix-sdk-sessions-test.cpp
matrix-promise-test.cpp
matrix-room-timeline-test.cpp
matrix-room-pinned-events-timeline-test.cpp
matrix-room-member-list-model-test.cpp
matrix-room-list-test.cpp
matrix-room-state-test.cpp
kazv-markdown-test.cpp
matrix-sticker-pack-test.cpp
matrix-link-test.cpp
matrix-user-given-attrs-map-test.cpp
kazv-abstract-list-model-test.cpp
matrix-event-list-test.cpp
matrix-event-test.cpp
kazv-file-test.cpp
db-store-test.cpp
sso-login-process-test.cpp
+ kazv-config-test.cpp
LINK_LIBRARIES Qt${QT_MAJOR_VERSION}::Test kazvtestlib
)
ecm_add_test(
kazv-io-job-test.cpp
LINK_LIBRARIES Qt${QT_MAJOR_VERSION}::Test Qt${QT_MAJOR_VERSION}::HttpServer kazvtestlib
)
ecm_add_test(
kazv-io-manager-test.cpp
LINK_LIBRARIES Qt${QT_MAJOR_VERSION}::Test Qt${QT_MAJOR_VERSION}::HttpServer kazvtestlib
)
add_executable(quicktest quick-test.cpp)
target_link_libraries(quicktest PRIVATE Qt${QT_MAJOR_VERSION}::QuickTest kazvtestlib)
if(KAZV_BUILD_BENCHMARKS)
ecm_add_test(
matrix-room-timeline-benchmark-test.cpp
LINK_LIBRARIES Qt${QT_MAJOR_VERSION}::Test kazvtestlib
)
endif()
set(quicktest_QMLS
tst_About.qml
tst_AddStickerPopup.qml
tst_AvatarImageAdapters.qml
tst_ConfirmUploadPopup.qml
tst_CreateRoomPage.qml
tst_DeviceList.qml
tst_DevicePopup.qml
tst_Device.qml
tst_EventHistoryView.qml
tst_EventReactions.qml
tst_EventReadIndicator.qml
tst_EventSourceView.qml
tst_EventView.qml
tst_EventViewRedacted.qml
tst_EventViewVideo.qml
tst_FileHandler.qml
tst_JoinRoomPage.qml
tst_KazvIOMenu.qml
tst_kazvshortcutsActionItem.qml
tst_LoginPage.qml
tst_MatrixHelpers.qml
tst_Notifications.qml
tst_PageManager.qml
tst_ReactToEventPopup.qml
tst_RoomInvitePage.qml
tst_RoomListViewItemDelegate.qml
tst_RoomMemberListPage.qml
tst_RoomNameProvider.qml
tst_RoomPage.qml
tst_RoomPinnedEventsPage.qml
tst_RoomSettingsPage.qml
tst_RoomStatePage.qml
tst_RoomStickerPackItemDelegate.qml
tst_RoomStickerPacksPage.qml
tst_RoomTimelineView.qml
tst_SendMessageBoxDrafts.qml
tst_SendMessageBox.qml
tst_StickerPackNameProvider.qml
tst_StickerPicker.qml
tst_TypingIndicator.qml
tst_UserNameProvider.qml
tst_UserPage.qml
)
foreach(testfilename ${quicktest_QMLS})
message(STATUS "Adding quick test ${testfilename}")
string(REPLACE .qml "" testname ${testfilename})
add_test(NAME ${testname} COMMAND quicktest -input ${CMAKE_CURRENT_SOURCE_DIR}/quick-tests/${testfilename})
set_property(TEST ${testname}
PROPERTY LABELS "quicktest")
endforeach()
if(kazv_ENABLE_APPIUM_TESTS)
qt_add_qml_module(kazvappiumcomponentqmlmodule
STATIC
URI moe.kazv.mxc.kazvappiumcomponent
VERSION 0.0
)
kazv_add_qml_files(kazvappiumcomponentqmlmodule
BASE_DIRECTORY run-appium-component-qml
SOURCES
Main.qml
)
add_executable(run-appium-component run-appium-component.cpp)
target_link_libraries(run-appium-component
PRIVATE
kazvappiumcomponentqmlmodule
kazvappiumcomponentqmlmoduleplugin
kazvtestlib
Qt::Quick
)
set(appium_tests_SOURCES
TestStickerPicker.py
TestEventViewUnavailable.py
TestRoomTimelineView.py
)
foreach(testfilename ${appium_tests_SOURCES})
message(STATUS "Adding appium test ${testfilename}")
string(REPLACE .py "" testname ${testfilename})
add_test(NAME ${testname}
COMMAND
${SELENIUM_WEBDRIVER_AT_SPI_RUN_PATH}
${CMAKE_CURRENT_SOURCE_DIR}/appium-tests/${testfilename}
)
set_property(TEST ${testname}
PROPERTY ENVIRONMENT "KAZV_APPIUM_TEST_BIN=$<TARGET_FILE:run-appium-component>;TEST_WITH_VIDEO_RECORDER=0")
set_property(TEST ${testname}
PROPERTY LABELS "appiumtest")
endforeach()
endif()
diff --git a/src/tests/kazv-config-test.cpp b/src/tests/kazv-config-test.cpp
new file mode 100644
index 0000000..c77d3df
--- /dev/null
+++ b/src/tests/kazv-config-test.cpp
@@ -0,0 +1,197 @@
+/*
+ * This file is part of kazv.
+ * SPDX-FileCopyrightText: 2026 nannanko <nannanko@kazv.moe>
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+#include <kazv-defs.hpp>
+
+#include "kazv-config.hpp"
+
+#include <KConfigGroup>
+#include <KSharedConfig>
+
+#include <QDir>
+#include <QFile>
+#include <QMap>
+#include <QObject>
+#include <QStandardPaths>
+#include <QStringList>
+#include <QTemporaryDir>
+#include <QVariant>
+#include <QtTest>
+
+using namespace Qt::Literals::StringLiterals;
+
+namespace
+{
+ QString configDir()
+ {
+ return QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation);
+ }
+
+ QString configFilePath(const QString &relativePath)
+ {
+ return configDir() + u"/"_s + relativePath;
+ }
+
+ // Creates a config file by the same way the old kazv code did
+ void writeOldConfig(const QString &configName,
+ const QString &groupName,
+ const QMap<QString, QVariant> &entries)
+ {
+ const KSharedConfigPtr config = KSharedConfig::openConfig(configName);
+ KConfigGroup group = config->group(groupName);
+ for (auto it = entries.cbegin(); it != entries.cend(); ++it) {
+ group.writeEntry(it.key(), it.value());
+ }
+ QVERIFY(config->sync());
+ }
+}
+
+class KazvConfigTest : public QObject
+{
+ Q_OBJECT
+
+private:
+ QTemporaryDir m_configHome;
+
+private Q_SLOTS:
+ void initTestCase();
+ void cleanup();
+ void testMigrateCacheDirectory();
+ void testMigrateShortcuts();
+ void testMigratePreservesExistingNewConfig();
+ void testMigrateShortcutsPreservesExistingNewConfig();
+ void testMigrateLastSession();
+ void testMigrateLastSessionPreservesExistingNewConfig();
+ void testNoOldConfig();
+};
+
+void KazvConfigTest::initTestCase()
+{
+ // Redirect all config locations to a temporary directory, so that
+ // the migration code never touches the user's real configuration.
+ QCoreApplication::setApplicationName(u"kazv"_s);
+ QVERIFY(m_configHome.isValid());
+ QVERIFY(qputenv("XDG_CONFIG_HOME", m_configHome.path().toUtf8()));
+ QCOMPARE(configDir(), m_configHome.path());
+}
+
+void KazvConfigTest::cleanup()
+{
+ const QStringList configFiles = {
+ u"kazv/kazvrc"_s,
+ u"kazv/kazvsessionrc"_s,
+ u"kazv/cacheDirectoryrc"_s,
+ u"kazv/shortcutsrc"_s,
+ u"kazvsessionrc"_s,
+ };
+ for (const QString &relativePath : configFiles) {
+ QFile::remove(configFilePath(relativePath));
+ }
+}
+
+void KazvConfigTest::testMigrateCacheDirectory()
+{
+ writeOldConfig(u"kazv/cacheDirectoryrc"_s, u"CacheDirectory"_s,
+ {{u"cacheDirectory"_s, u"/tmp/kazv-cache"_s}});
+
+ KazvConfig config;
+ QCOMPARE(config.cacheDirectory(), u"/tmp/kazv-cache"_s);
+
+ // The old config file should be removed after a successful migration.
+ QVERIFY(!QFile::exists(configFilePath(u"kazv/cacheDirectoryrc"_s)));
+}
+
+void KazvConfigTest::testMigrateShortcuts()
+{
+ writeOldConfig(u"kazv/shortcutsrc"_s, u"Shortcuts"_s,
+ {{u"switch-account"_s,
+ QVariant::fromValue(QStringList{u"Meta+Tab"_s, u"Alt+1"_s})},
+ {u"hard-logout"_s, QVariant::fromValue(QStringList{u"Ctrl+L"_s})}});
+
+ KazvConfig config;
+ QCOMPARE(config.shortcutForAction(u"switch-account"_s),
+ (QStringList{u"Meta+Tab"_s, u"Alt+1"_s}));
+ QCOMPARE(config.shortcutForAction(u"hard-logout"_s),
+ QStringList{u"Ctrl+L"_s});
+
+ QVERIFY(!QFile::exists(configFilePath(u"kazv/shortcutsrc"_s)));
+}
+
+void KazvConfigTest::testMigratePreservesExistingNewConfig()
+{
+ {
+ KazvConfig config;
+ config.setCacheDirectory(u"/new/cache"_s);
+ }
+
+ writeOldConfig(u"kazv/cacheDirectoryrc"_s, u"CacheDirectory"_s,
+ {{u"cacheDirectory"_s, u"/old/cache"_s}});
+
+ KazvConfig config;
+ QCOMPARE(config.cacheDirectory(), u"/new/cache"_s);
+
+ QVERIFY(!QFile::exists(configFilePath(u"kazv/cacheDirectoryrc"_s)));
+}
+
+void KazvConfigTest::testMigrateShortcutsPreservesExistingNewConfig()
+{
+ {
+ KazvConfig config;
+ config.setShortcutForAction(u"switch-account"_s, (QStringList{u"Ctrl+K"_s}));
+ }
+
+ writeOldConfig(u"kazv/shortcutsrc"_s, u"Shortcuts"_s,
+ {{u"switch-account"_s, QVariant::fromValue(QStringList{u"Ctrl+J"_s})},
+ {u"hard-logout"_s, QVariant::fromValue(QStringList{u"Ctrl+L"_s})}});
+
+ KazvConfig config;
+ QCOMPARE(config.shortcutForAction(u"switch-account"_s), (QStringList{u"Ctrl+K"_s}));
+ QCOMPARE(config.shortcutForAction(u"hard-logout"_s), (QStringList{u"Ctrl+L"_s}));
+
+ QVERIFY(!QFile::exists(configFilePath(u"kazv/shortcutsrc"_s)));
+}
+
+void KazvConfigTest::testMigrateLastSession()
+{
+ writeOldConfig(u"kazvsessionrc"_s, u"Sessions"_s,
+ {{u"lastSession"_s, u"session1"_s}});
+
+ KazvConfig config;
+ QCOMPARE(config.lastSession(), u"session1"_s);
+
+ QVERIFY(!QFile::exists(configFilePath(u"kazvsessionrc"_s)));
+}
+
+void KazvConfigTest::testMigrateLastSessionPreservesExistingNewConfig()
+{
+ {
+ const KSharedConfigPtr newConfig = KSharedConfig::openConfig(
+ u"kazvsessionrc"_s, KConfig::FullConfig,
+ QStandardPaths::AppConfigLocation);
+ KConfigGroup newGroup{newConfig, u"Sessions"_s};
+ newGroup.writeEntry(u"lastSession"_s, u"newsession"_s);
+ QVERIFY(newConfig->sync());
+ }
+ writeOldConfig(u"kazvsessionrc"_s, u"Sessions"_s,
+ {{u"lastSession"_s, u"oldsession"_s}});
+
+ KazvConfig config;
+ QCOMPARE(config.lastSession(), u"newsession"_s);
+
+ QVERIFY(!QFile::exists(configFilePath(u"kazvsessionrc"_s)));
+}
+
+void KazvConfigTest::testNoOldConfig()
+{
+ KazvConfig config;
+ QCOMPARE(config.cacheDirectory(), QString());
+ QCOMPARE(config.shortcutForAction(u"switch-account"_s), QStringList());
+ QCOMPARE(config.lastSession(), QString());
+}
+
+QTEST_MAIN(KazvConfigTest)
+
+#include "kazv-config-test.moc"
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sun, Aug 30, 5:53 PM (1 d, 12 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1738099
Default Alt Text
(27 KB)
Attached To
Mode
rK kazv
Attached
Detach File
Event Timeline
Log In to Comment