mirror of
https://github.com/QuasarApp/QuasarAppLib.git
synced 2025-04-26 09:44:38 +00:00
Compare commits
401 Commits
Author | SHA1 | Date | |
---|---|---|---|
6e494a13f1 | |||
703fff317c | |||
4eb85b8cbb | |||
0ce9053539 | |||
5d020006bb | |||
7e84073393 | |||
9c6c6d257c | |||
1e61c3578b | |||
ebdd860531 | |||
37a1f76ba1 | |||
961e6608d9 | |||
86c9036f13 | |||
6b8bb9f2cd | |||
945da5be9d | |||
8b710eaa67 | |||
580a4ce1bd | |||
5302846051 | |||
7f24b57b41 | |||
88414ce06f | |||
|
d61ef581ce | ||
|
5218f2094c | ||
|
06b71bd9aa | ||
|
f06e675631 | ||
65a467054a | |||
ccd47b8be3 | |||
e59bc728b3 | |||
97260fea2d | |||
a21c8d38ed | |||
f82a69db36 | |||
ee0f7fb2ee | |||
ad939ab45e | |||
f3fabf4f64 | |||
78ceff0f09 | |||
53c73c2913 | |||
c17c20e51f | |||
08c27ec560 | |||
10d0361ae1 | |||
b7b0f330c6 | |||
ad27b38b10 | |||
00b80d9454 | |||
0551a56944 | |||
0e8a402e9a | |||
8b5fce889f | |||
37fe8a069b | |||
5ab1c66525 | |||
3b797f9a78 | |||
334e209ff4 | |||
4d445ef7fc | |||
90a4284c56 | |||
a23bbe9268 | |||
d4a3e7dff2 | |||
53a67709ff | |||
fb8c76feb6 | |||
62c9d4e7c2 | |||
c427dd9349 | |||
21b07bfdb0 | |||
b3d577165d | |||
d2c1e7819c | |||
cb9dc9d3d2 | |||
11588289c0 | |||
f3519b341a | |||
c462f44e6b | |||
d7b9ccef40 | |||
c29c9edc52 | |||
7737b28258 | |||
7b4c10be77 | |||
9fcdeb42dd | |||
38e609e128 | |||
07943dfc37 | |||
edd7176e56 | |||
00c013beac | |||
f06e1e290a | |||
afb0ef5fd8 | |||
f1067da2d7 | |||
c492fa2fe8 | |||
5616b7e6fd | |||
a50d7a0348 | |||
7ff9620735 | |||
744ec83b7d | |||
cac23de957 | |||
3b54cebae8 | |||
8da7dd8759 | |||
7d2331b666 | |||
668aa59436 | |||
a825977705 | |||
1f708e971a | |||
80eb3fcca8 | |||
ff2a2dbed0 | |||
dcb12781be | |||
bc08092e1a | |||
5bf7366b6d | |||
00cdfae297 | |||
6f8308db6d | |||
ee6df818d0 | |||
246ea80b36 | |||
81316a23d3 | |||
2d2e1a9a5f | |||
2559e3d560 | |||
8e61cf5551 | |||
f5ca59a2e9 | |||
79d2a8ccb3 | |||
3cf69bb5a3 | |||
093ea662ee | |||
ea4f1cda31 | |||
99473b2167 | |||
96043e36e6 | |||
85185d2430 | |||
aa4e7971bb | |||
fcf2f50f2f | |||
97cbfebebf | |||
803870ea08 | |||
a4e3768dfb | |||
b9ad1c41b2 | |||
071a01a2d6 | |||
11947d4cde | |||
b26c9ea62d | |||
9e6e642f13 | |||
8b848650b8 | |||
76482dd08f | |||
4c596e3088 | |||
b0321a2c08 | |||
f466dd6437 | |||
b6d3b0f72e | |||
5426711796 | |||
ef5dc565bb | |||
c080361126 | |||
c3d94013c2 | |||
748fd9fd94 | |||
9cc9e77bab | |||
d6ee73aff1 | |||
a9d81a2eb5 | |||
b971e3dffb | |||
909bff8142 | |||
f7ee5cd272 | |||
61badc9ff0 | |||
2b0f879580 | |||
8f9a778baf | |||
4ed7f0880a | |||
461fcb6c82 | |||
d3c72639c4 | |||
f7355aad58 | |||
12582fc2eb | |||
10ed7648a1 | |||
fa66066021 | |||
fe224bdc99 | |||
04b73772d8 | |||
03e5ecb541 | |||
ddd0ef996b | |||
ccea0a2f17 | |||
b8c0663ca9 | |||
3ef2547ebd | |||
47b00c0152 | |||
50176cc974 | |||
953b1fb465 | |||
adaa01346d | |||
e3815b8029 | |||
2e6c010b14 | |||
d01a58570c | |||
6bdaa0e9ef | |||
302ee6d369 | |||
0d9b75268d | |||
6c4645899a | |||
bcff3c3619 | |||
e2f3fed163 | |||
3bf106665d | |||
eb18b6c969 | |||
8a93dd9062 | |||
2dca907f8b | |||
78facac89b | |||
2464bf55cf | |||
bf0283a8c2 | |||
4b0dd805ad | |||
eb7ba6cfcc | |||
bd6dd8ecca | |||
6d5f602b7b | |||
a1680f59cc | |||
e56482ab50 | |||
c27ca21445 | |||
d7e11e644c | |||
165e61a86d | |||
ed56d729ad | |||
dc54e2bbc3 | |||
|
53d5cd4ff2 | ||
|
0c04d41712 | ||
|
c309260b46 | ||
|
0a03a081c0 | ||
|
66aa7eca11 | ||
4573b7dfa1 | |||
|
049283c287 | ||
|
2709f1141a | ||
|
b62144cd4b | ||
|
26156be771 | ||
|
bbdf744514 | ||
|
3994904b0a | ||
|
bd14ed499f | ||
|
3e83214d34 | ||
4554cf393d | |||
0c25573875 | |||
698d5364cb | |||
500186ef52 | |||
45ff443288 | |||
72ec98c4cd | |||
421be4a1d8 | |||
88df62884a | |||
0ad790d7f6 | |||
20ceb9ba9d | |||
ae03daea64 | |||
7646d2a6db | |||
5f1ebf22e2 | |||
d69306c121 | |||
d37c6a1ff0 | |||
665eec418c | |||
cc87accb8b | |||
864fe83d42 | |||
cae874728f | |||
e021209f95 | |||
93839d1dc0 | |||
87e2fb4b99 | |||
d7244c7442 | |||
313f7f2cc5 | |||
fc80dba292 | |||
dee8b58fd8 | |||
a5cfed3688 | |||
9f997369d2 | |||
fea42f1ced | |||
12c20dc83f | |||
cd84e72484 | |||
ed3be09bde | |||
97b2580498 | |||
ed0145dd39 | |||
5cca105e57 | |||
7a2e525ac8 | |||
7c9308b3ff | |||
9182b1bf1e | |||
553e337e6a | |||
68e6b32bd5 | |||
a6a5c8f1b5 | |||
6f0754fa22 | |||
d66dbc7faa | |||
87a0d37a6e | |||
39d6d034b6 | |||
621fc4a5d0 | |||
438a6fe855 | |||
f9d81280c8 | |||
f5a8f4de82 | |||
da1df65ada | |||
461c5169bd | |||
ba39d68abb | |||
fc5dbe3702 | |||
2cb6709b3e | |||
c478359c60 | |||
75ad22b2df | |||
c7968c3f5f | |||
e51bf43b09 | |||
92f9c9c27a | |||
da3b928e63 | |||
8615e4162d | |||
c25ec6e68f | |||
95b8359efd | |||
271829781c | |||
ebfd0b0ff3 | |||
19a2437d0c | |||
db974c911e | |||
fe2ba8e5d3 | |||
680a42202c | |||
87eb1cdd12 | |||
ebf0c7894a | |||
d0d791e9e3 | |||
7ea6c9af26 | |||
aab6cca7f5 | |||
ec864de682 | |||
b3b8307172 | |||
51ab2bf3d3 | |||
f33f915887 | |||
401409a87f | |||
3f602cbfac | |||
73f51c2fff | |||
ef8774c134 | |||
693e0e9948 | |||
caabc17e2f | |||
|
8bdb0b38f1 | ||
5a2e19e5ab | |||
a7f5756f52 | |||
e2ae121a7c | |||
d978f47ea5 | |||
67eac71d91 | |||
e8e7721518 | |||
b643f5ec96 | |||
681dab9741 | |||
80661ff685 | |||
d011e2bada | |||
cf88bc8264 | |||
1130c1d2a6 | |||
37dc7a7c80 | |||
ca54815677 | |||
7af6efb0c6 | |||
d24908f7c8 | |||
30b3669ce4 | |||
34e0c6b502 | |||
e6751c86d5 | |||
fd2aad7890 | |||
81e0ed8a19 | |||
9c7aa9b8a3 | |||
e06d6d3634 | |||
a0676fbc84 | |||
681d2492db | |||
|
647055ec21 | ||
7b978a5561 | |||
9a1a870993 | |||
38068ec75f | |||
23b5f47a44 | |||
1fe4fa3b25 | |||
81e4ef9bb4 | |||
b5316127aa | |||
e520e9da41 | |||
d0971dbcb7 | |||
5042527ffb | |||
fcdda0b0af | |||
f4a720bd24 | |||
e1f0f13c8e | |||
7106ed22d9 | |||
2934cdc09f | |||
e634961b4a | |||
ffc95d077b | |||
a3e435823c | |||
f873269780 | |||
f84faab0dd | |||
9d22f8a219 | |||
c8a3dae894 | |||
68a0185c5a | |||
fec2b1d13b | |||
c4a1b14149 | |||
9c68064b48 | |||
b1fb180221 | |||
2d26f15603 | |||
05ac25e92a | |||
df333341ce | |||
68dc207db0 | |||
100b70b4d6 | |||
ad21d646d0 | |||
3ff083ab33 | |||
bdb77471ac | |||
80cae9f7ac | |||
3947277ce2 | |||
18226f2753 | |||
88a3632807 | |||
c65aba6329 | |||
a4734f877f | |||
05254ad0cd | |||
eff3a3055d | |||
44791d19c2 | |||
bb6ced3b79 | |||
537d7b0634 | |||
ec0622fa12 | |||
3b0c06626c | |||
1abd8f522a | |||
8afe9cdd87 | |||
e428da03a0 | |||
c138c75cb5 | |||
b3820d7b15 | |||
60f961375a | |||
9a9a5d6322 | |||
c76e611a9f | |||
4129ff8c1d | |||
7b413c0539 | |||
4e0c569c00 | |||
8d11470d99 | |||
ee268f348e | |||
cebdc74ab6 | |||
40846764a5 | |||
c5c74c393f | |||
4af60d539e | |||
f138989588 | |||
f5a6e542ea | |||
2343a11c7a | |||
762f421db4 | |||
7070d77012 | |||
d580ac1a20 | |||
273045d966 | |||
ad7b644573 | |||
a98ed022c8 | |||
eea36f0e62 | |||
0bc7d99080 | |||
b932e8c65e | |||
48cde49139 | |||
5b2e25567b | |||
b9e8a900c7 | |||
a3db249c8f | |||
32b5693872 | |||
0dda7b9189 | |||
40b9616ad6 | |||
76ec898818 | |||
99b6aa1474 | |||
5deea5073a | |||
9847582222 | |||
ee3f9d1d7a | |||
2df4876f7c | |||
a5aca0e487 | |||
105f019aa7 | |||
663c1571c7 | |||
5a971a5b21 |
1
.gitignore
vendored
1
.gitignore
vendored
@ -59,3 +59,4 @@ compile_commands.json
|
||||
CTestTestfile.cmake
|
||||
_deps
|
||||
*_autogen
|
||||
docs/html
|
||||
|
2
CMake
2
CMake
@ -1 +1 @@
|
||||
Subproject commit 682c00fca702776925f66511ae76b2fe88dece75
|
||||
Subproject commit 76d88f13235574890fa72e9a811c6ff524d6abaa
|
@ -1,34 +1,65 @@
|
||||
#
|
||||
# Copyright (C) 2018-2019 QuasarApp.
|
||||
# Copyright (C) 2018-2025 QuasarApp.
|
||||
# Distributed under the lgplv3 software license, see the accompanying
|
||||
# Everyone is permitted to copy and distribute verbatim copies
|
||||
# of this license document, but changing it is not allowed.
|
||||
#
|
||||
|
||||
if(DEFINED QUASARAPP_LIBRARY)
|
||||
return()
|
||||
else()
|
||||
set(QUASARAPP_LIBRARY 1)
|
||||
add_definitions(-DQUASARAPP_LIBRARY)
|
||||
endif()
|
||||
|
||||
project(QuasarApp)
|
||||
|
||||
if(TARGET ${PROJECT_NAME})
|
||||
message("The ${PROJECT_NAME} arledy included in main Project")
|
||||
return()
|
||||
endif()
|
||||
|
||||
cmake_minimum_required(VERSION 3.1)
|
||||
include(CMake/crossplatform/crossplatform.cmake)
|
||||
|
||||
project(QuasarApp LANGUAGES CXX)
|
||||
|
||||
include(CMake/ProjectOut.cmake)
|
||||
include(CMake/ccache.cmake)
|
||||
include(CMake/QuasarApp.cmake)
|
||||
include(CMake/Version.cmake)
|
||||
|
||||
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
set(CMAKE_AUTORCC ON)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
set(CMAKE_AUTORCC ON)
|
||||
option(BUILD_SHARED_LIBS "Enable or disable shared libraryes" OFF)
|
||||
|
||||
find_package(Qt5 COMPONENTS Core REQUIRED)
|
||||
if (NOT QT_VERSION_MAJOR)
|
||||
find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED)
|
||||
endif()
|
||||
|
||||
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core REQUIRED)
|
||||
|
||||
option(QA_ALLOW_NOT_SUPPORTED_OPTIONS "Enable for allow any command line options" ON)
|
||||
option(QA_DISABLE_LOG "Disabled all logs (force sets verbose to 0)" OFF)
|
||||
|
||||
if (QA_DISABLE_LOG)
|
||||
add_definitions(-DQA_DISABLE_LOG)
|
||||
endif()
|
||||
|
||||
if (QA_ALLOW_NOT_SUPPORTED_OPTIONS)
|
||||
add_definitions(-DQA_ALLOW_NOT_SUPPORTED_OPTIONS)
|
||||
endif()
|
||||
|
||||
file(GLOB SOURCE_CPP
|
||||
"*.cpp"
|
||||
"*.cpp" "*.h"
|
||||
)
|
||||
|
||||
add_library(${PROJECT_NAME} SHARED ${SOURCE_CPP})
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE Qt5::Core)
|
||||
add_library(${PROJECT_NAME} ${SOURCE_CPP})
|
||||
target_link_libraries(${PROJECT_NAME} PUBLIC Qt${QT_VERSION_MAJOR}::Core)
|
||||
target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
setVersion(1 2 0)
|
||||
setVersion(1 5 4)
|
||||
|
||||
initAll()
|
||||
make_directory("${CMAKE_CURRENT_SOURCE_DIR}/Distro")
|
||||
|
||||
addDoc(${PROJECT_NAME}Docs ${CMAKE_CURRENT_SOURCE_DIR}/doxygen.conf)
|
||||
|
@ -1,22 +0,0 @@
|
||||
#
|
||||
# Copyright (C) 2018-2020 QuasarApp.
|
||||
# Distributed under the lgplv3 software license, see the accompanying
|
||||
# Everyone is permitted to copy and distribute verbatim copies
|
||||
# of this license document, but changing it is not allowed.
|
||||
#
|
||||
|
||||
!isEmpty(CCACHE_INCLUDE):error("ccache.pri already included")
|
||||
CCACHE_INCLUDE = 1
|
||||
|
||||
contains(QMAKE_HOST.os, Linux):{
|
||||
BIN = $$system(which ccache)
|
||||
|
||||
|
||||
!isEmpty(BIN) {
|
||||
message(ccache detected in $$BIN)
|
||||
QMAKE_CXX='$$BIN $$QMAKE_CXX'
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,33 +0,0 @@
|
||||
#
|
||||
# Copyright (C) 2018-2019 QuasarApp.
|
||||
# Distributed under the lgplv3 software license, see the accompanying
|
||||
# Everyone is permitted to copy and distribute verbatim copies
|
||||
# of this license document, but changing it is not allowed.
|
||||
#
|
||||
|
||||
QT_DIR = $$dirname(QMAKE_QMAKE)
|
||||
LUPDATE = $$QT_DIR/lupdate
|
||||
LRELEASE = $$QT_DIR/lrelease
|
||||
|
||||
win32 {
|
||||
LUPDATE = $${LUPDATE}.exe
|
||||
LRELEASE = $${LRELEASE}.exe
|
||||
}
|
||||
|
||||
PRO_FILES = $$files(*.pro, true)
|
||||
|
||||
for(PRO, PRO_FILES) {
|
||||
commands += "$$LUPDATE $$PRO"
|
||||
}
|
||||
|
||||
|
||||
TS_FILES = $$files(*.ts, true)
|
||||
|
||||
for(TS, TS_FILES) {
|
||||
commands += "$$LRELEASE $$TS"
|
||||
}
|
||||
|
||||
for(command, commands) {
|
||||
system($$command)|error("Failed to run: $$command")
|
||||
}
|
||||
|
@ -1,442 +0,0 @@
|
||||
#!/bin/bash
|
||||
#################
|
||||
# Launcher init #
|
||||
#################
|
||||
|
||||
START=$(date +%s.%N)
|
||||
|
||||
# On Fedora $SNAP is under /var and there is some magic to map it to /snap.
|
||||
# # We need to handle that case and reset $SNAP
|
||||
SNAP=`echo $SNAP | sed -e "s|/var/lib/snapd||g"`
|
||||
|
||||
needs_update=true
|
||||
|
||||
. $SNAP_USER_DATA/.last_revision 2>/dev/null || true
|
||||
if [ "$SNAP_DESKTOP_LAST_REVISION" = "$SNAP_REVISION" ]; then
|
||||
needs_update=false
|
||||
fi
|
||||
|
||||
# Set $REALHOME to the users real home directory
|
||||
REALHOME=`getent passwd $UID | cut -d ':' -f 6`
|
||||
|
||||
# If the user has modified their user-dirs settings, force an update
|
||||
if [[ -f $HOME/.config/user-dirs.dirs.md5sum && -f $HOME/.config/user-dirs.locale.md5sum ]]; then
|
||||
if [[ "$(md5sum < $REALHOME/.config/user-dirs.dirs)" != "$(cat $HOME/.config/user-dirs.dirs.md5sum)" ||
|
||||
"$(md5sum < $REALHOME/.config/user-dirs.locale)" != "$(cat $HOME/.config/user-dirs.locale.md5sum)" ]]; then
|
||||
needs_update=true
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$SNAP_ARCH" == "amd64" ]; then
|
||||
ARCH="x86_64-linux-gnu"
|
||||
elif [ "$SNAP_ARCH" == "armhf" ]; then
|
||||
ARCH="arm-linux-gnueabihf"
|
||||
elif [ "$SNAP_ARCH" == "arm64" ]; then
|
||||
ARCH="aarch64-linux-gnu"
|
||||
else
|
||||
ARCH="$SNAP_ARCH-linux-gnu"
|
||||
fi
|
||||
|
||||
export SNAP_LAUNCHER_ARCH_TRIPLET=$ARCH
|
||||
|
||||
# Don't LD_PRELOAD bindtextdomain for classic snaps
|
||||
if ! grep -qs "^\s*confinement:\s*classic\s*" $SNAP/meta/snap.yaml; then
|
||||
if [ -f $SNAP/lib/bindtextdomain.so ]; then
|
||||
export LD_PRELOAD=$LD_PRELOAD:$SNAP/lib/bindtextdomain.so
|
||||
fi
|
||||
fi
|
||||
###############################################
|
||||
# Launcher common exports for any desktop app #
|
||||
###############################################
|
||||
|
||||
function prepend_dir() {
|
||||
local var="$1"
|
||||
local dir="$2"
|
||||
if [ -d "$dir" ]; then
|
||||
eval "export $var=\"\$dir\${$var:+:\$$var}\""
|
||||
fi
|
||||
}
|
||||
|
||||
function append_dir() {
|
||||
local var="$1"
|
||||
local dir="$2"
|
||||
if [ -d "$dir" ]; then
|
||||
eval "export $var=\"\${$var:+\$$var:}\$dir\""
|
||||
fi
|
||||
}
|
||||
|
||||
function can_open_file() {
|
||||
return `head -c0 "$1" &> /dev/null`;
|
||||
}
|
||||
|
||||
WITH_RUNTIME=no
|
||||
if [ -z "$RUNTIME" ]; then
|
||||
RUNTIME=$SNAP
|
||||
else
|
||||
# add general paths not added by snapcraft due to runtime snap
|
||||
append_dir LD_LIBRARY_PATH $RUNTIME/lib/$ARCH
|
||||
append_dir LD_LIBRARY_PATH $RUNTIME/usr/lib/$ARCH
|
||||
append_dir PATH $RUNTIME/usr/bin
|
||||
WITH_RUNTIME=yes
|
||||
fi
|
||||
|
||||
# XKB config
|
||||
export XKB_CONFIG_ROOT=$RUNTIME/usr/share/X11/xkb
|
||||
|
||||
# Give XOpenIM a chance to locate locale data.
|
||||
# This is required for text input to work in SDL2 games.
|
||||
export XLOCALEDIR=$RUNTIME/usr/share/X11/locale
|
||||
|
||||
# Set XCursors path
|
||||
export XCURSOR_PATH=$RUNTIME/usr/share/icons
|
||||
|
||||
# Mesa Libs for OpenGL support
|
||||
append_dir LD_LIBRARY_PATH $RUNTIME/usr/lib/$ARCH/mesa
|
||||
append_dir LD_LIBRARY_PATH $RUNTIME/usr/lib/$ARCH/mesa-egl
|
||||
|
||||
# Tell libGL where to find the drivers
|
||||
export LIBGL_DRIVERS_PATH=$RUNTIME/usr/lib/$ARCH/dri
|
||||
append_dir LD_LIBRARY_PATH $LIBGL_DRIVERS_PATH
|
||||
|
||||
# Workaround in snapd for proprietary nVidia drivers mounts the drivers in
|
||||
# /var/lib/snapd/lib/gl that needs to be in LD_LIBRARY_PATH
|
||||
# Without that OpenGL using apps do not work with the nVidia drivers.
|
||||
# Ref.: https://bugs.launchpad.net/snappy/+bug/1588192
|
||||
append_dir LD_LIBRARY_PATH /var/lib/snapd/lib/gl
|
||||
|
||||
# Unity7 export (workaround for https://launchpad.net/bugs/1638405)
|
||||
append_dir LD_LIBRARY_PATH $RUNTIME/usr/lib/$ARCH/libunity
|
||||
|
||||
# Pulseaudio export
|
||||
append_dir LD_LIBRARY_PATH $RUNTIME/usr/lib/$ARCH/pulseaudio
|
||||
|
||||
# EGL vendor files on glvnd enabled systems
|
||||
[ -d /var/lib/snapd/lib/glvnd/egl_vendor.d ] && \
|
||||
append_dir __EGL_VENDOR_LIBRARY_DIRS /var/lib/snapd/lib/glvnd/egl_vendor.d
|
||||
|
||||
# Tell GStreamer where to find its plugins
|
||||
export GST_PLUGIN_PATH=$SNAP/usr/lib/$ARCH/gstreamer-1.0
|
||||
export GST_PLUGIN_SYSTEM_PATH=$RUNTIME/usr/lib/$ARCH/gstreamer-1.0
|
||||
# gst plugin scanner doesn't install in the correct path: https://github.com/ubuntu/snapcraft-desktop-helpers/issues/43
|
||||
export GST_PLUGIN_SCANNER=$RUNTIME/usr/lib/$ARCH/gstreamer1.0/gstreamer-1.0/gst-plugin-scanner
|
||||
|
||||
# XDG Config
|
||||
[ "$WITH_RUNTIME" = yes ] && prepend_dir XDG_CONFIG_DIRS $RUNTIME/etc/xdg
|
||||
prepend_dir XDG_CONFIG_DIRS $SNAP/etc/xdg
|
||||
|
||||
# Define snaps' own data dir
|
||||
[ "$WITH_RUNTIME" = yes ] && prepend_dir XDG_DATA_DIRS $RUNTIME/usr/share
|
||||
prepend_dir XDG_DATA_DIRS $SNAP/usr/share
|
||||
prepend_dir XDG_DATA_DIRS $SNAP/share
|
||||
prepend_dir XDG_DATA_DIRS $SNAP/data-dir
|
||||
prepend_dir XDG_DATA_DIRS $SNAP_USER_DATA
|
||||
|
||||
# Set XDG_DATA_HOME to local path
|
||||
export XDG_DATA_HOME=$SNAP_USER_DATA/.local/share
|
||||
mkdir -p $XDG_DATA_HOME
|
||||
|
||||
# Workaround for GLib < 2.53.2 not searching for schemas in $XDG_DATA_HOME:
|
||||
# https://bugzilla.gnome.org/show_bug.cgi?id=741335
|
||||
prepend_dir XDG_DATA_DIRS $XDG_DATA_HOME
|
||||
|
||||
# Set cache folder to local path
|
||||
export XDG_CACHE_HOME=$SNAP_USER_COMMON/.cache
|
||||
if [[ -d $SNAP_USER_DATA/.cache && ! -e $XDG_CACHE_HOME ]]; then
|
||||
# the .cache directory used to be stored under $SNAP_USER_DATA, migrate it
|
||||
mv $SNAP_USER_DATA/.cache $SNAP_USER_COMMON/
|
||||
fi
|
||||
mkdir -p $XDG_CACHE_HOME
|
||||
|
||||
# Set config folder to local path
|
||||
export XDG_CONFIG_HOME=$SNAP_USER_DATA/.config
|
||||
mkdir -p $XDG_CONFIG_HOME
|
||||
|
||||
# Create $XDG_RUNTIME_DIR if not exists (to be removed when LP: #1656340 is fixed)
|
||||
[ -n "$XDG_RUNTIME_DIR" ] && mkdir -p $XDG_RUNTIME_DIR -m 700
|
||||
|
||||
# Ensure the app finds locale definitions (requires locales-all to be installed)
|
||||
append_dir LOCPATH $RUNTIME/usr/lib/locale
|
||||
|
||||
# If any, keep track of where XDG dirs were so we can potentially migrate the content later
|
||||
test -f ${XDG_CONFIG_HOME:-$HOME/.config}/user-dirs.dirs && . ${XDG_CONFIG_HOME:-$HOME/.config}/user-dirs.dirs
|
||||
for d in DOCUMENTS DESKTOP DOWNLOAD MUSIC PICTURES VIDEOS PUBLICSHARE TEMPLATES; do
|
||||
eval $(echo "OLD_XDG_${d}_DIR")=`eval "$(echo "echo \\$XDG_${d}_DIR")"`
|
||||
done
|
||||
|
||||
# Setup user-dirs.* or run xdg-user-dirs-update if needed
|
||||
needs_xdg_update=false
|
||||
needs_xdg_links=false
|
||||
if can_open_file "$REALHOME/.config/user-dirs.dirs" && can_open_file "$REALHOME/.config/user-dirs.locale"; then
|
||||
mkdir -p $HOME/.config -m 700
|
||||
sed /^#/!s#\$HOME#${REALHOME}#g $REALHOME/.config/user-dirs.dirs > $HOME/.config/user-dirs.dirs
|
||||
cp -a $REALHOME/.config/user-dirs.locale $HOME/.config/
|
||||
for f in user-dirs.dirs user-dirs.locale; do
|
||||
md5sum < $REALHOME/.config/$f > $HOME/.config/$f.md5sum
|
||||
done
|
||||
else
|
||||
needs_xdg_update=true
|
||||
needs_xdg_links=true
|
||||
fi
|
||||
|
||||
# Check if we can actually read the contents of each xdg dir
|
||||
test -f ${XDG_CONFIG_HOME:-$HOME/.config}/user-dirs.dirs && . ${XDG_CONFIG_HOME:-$HOME/.config}/user-dirs.dirs
|
||||
XDG_SPECIAL_DIRS=($XDG_DOCUMENTS_DIR $XDG_DESKTOP_DIR $XDG_DOWNLOAD_DIR $XDG_MUSIC_DIR $XDG_PICTURES_DIR $XDG_VIDEOS_DIR $XDG_PUBLIC_DIR $XDG_TEMPLATES_DIR)
|
||||
for d in ${XDG_SPECIAL_DIRS[@]}; do
|
||||
if ! can_open_file $d; then
|
||||
needs_xdg_update=true
|
||||
fi
|
||||
done
|
||||
|
||||
# If needs XDG update and xdg-user-dirs-update exists in $PATH, run it
|
||||
if [ $needs_xdg_update = true ] && command -v xdg-user-dirs-update >/dev/null; then
|
||||
xdg-user-dirs-update
|
||||
fi
|
||||
|
||||
# Create links for user-dirs.dirs
|
||||
if [ $needs_xdg_links = true ]; then
|
||||
test -f ${XDG_CONFIG_HOME:-$HOME/.config}/user-dirs.dirs && . ${XDG_CONFIG_HOME:-$HOME/.config}/user-dirs.dirs
|
||||
XDG_SPECIAL_DIRS=($XDG_DOCUMENTS_DIR $XDG_DESKTOP_DIR $XDG_DOWNLOAD_DIR $XDG_MUSIC_DIR $XDG_PICTURES_DIR $XDG_VIDEOS_DIR $XDG_PUBLIC_DIR $XDG_TEMPLATES_DIR)
|
||||
for d in ${XDG_SPECIAL_DIRS[@]}; do
|
||||
b=$(realpath "$d" --relative-to="$REALHOME")
|
||||
if [ -e $REALHOME/$b ] && [ ! -e $HOME/$b ]; then
|
||||
ln -s $REALHOME/$b $HOME/$b
|
||||
fi
|
||||
done
|
||||
else
|
||||
# If we aren't creating new links, check if we have content saved in old locations and move it
|
||||
for d in DOCUMENTS DESKTOP DOWNLOAD MUSIC PICTURES VIDEOS PUBLICSHARE TEMPLATES; do
|
||||
old=`eval "$(echo "echo \\$OLD_XDG_${d}_DIR")"`
|
||||
new=`eval "$(echo "echo \\$XDG_${d}_DIR")"`
|
||||
if [ -L "$old" ] && [ -d "$new" ] && [ `readlink "$old"` != "$new" ]; then
|
||||
mv "$old"/* "$new"/ 2>/dev/null
|
||||
elif [ -d "$old" ] && [ -d "$new" ] && [ "$old" != "$new" ]; then
|
||||
mv "$old"/* "$new"/ 2>/dev/null
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
# If detect wayland server socket, then set environment so applications prefer
|
||||
# wayland, and setup compat symlink (until we use user mounts. Remember,
|
||||
# XDG_RUNTIME_DIR is /run/user/<uid>/snap.$SNAP so look in the parent directory
|
||||
# for the socket. For details:
|
||||
# https://forum.snapcraft.io/t/wayland-dconf-and-xdg-runtime-dir/186/10
|
||||
# Applications that don't support wayland natively may define DISABLE_WAYLAND
|
||||
# (to any non-empty value) to skip that logic entirely.
|
||||
wayland_available=false
|
||||
if [[ -n "$XDG_RUNTIME_DIR" && -z "$DISABLE_WAYLAND" ]]; then
|
||||
wdisplay="wayland-0"
|
||||
if [ -n "$WAYLAND_DISPLAY" ]; then
|
||||
wdisplay="$WAYLAND_DISPLAY"
|
||||
fi
|
||||
wayland_sockpath="$XDG_RUNTIME_DIR/../$wdisplay"
|
||||
wayland_snappath="$XDG_RUNTIME_DIR/$wdisplay"
|
||||
if [ -S "$wayland_sockpath" ]; then
|
||||
# if running under wayland, use it
|
||||
#export WAYLAND_DEBUG=1
|
||||
wayland_available=true
|
||||
# create the compat symlink for now
|
||||
if [ ! -e "$wayland_snappath" ]; then
|
||||
ln -s "$wayland_sockpath" "$wayland_snappath"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# Make PulseAudio socket available inside the snap-specific $XDG_RUNTIME_DIR
|
||||
if [ -n "$XDG_RUNTIME_DIR" ]; then
|
||||
pulsenative="pulse/native"
|
||||
pulseaudio_sockpath="$XDG_RUNTIME_DIR/../$pulsenative"
|
||||
if [ -S "$pulseaudio_sockpath" ]; then
|
||||
export PULSE_SERVER="unix:${pulseaudio_sockpath}"
|
||||
fi
|
||||
fi
|
||||
|
||||
# GI repository
|
||||
[ "$WITH_RUNTIME" = yes ] && prepend_dir GI_TYPELIB_PATH $RUNTIME/usr/lib/$ARCH/girepository-1.0
|
||||
[ "$WITH_RUNTIME" = yes ] && prepend_dir GI_TYPELIB_PATH $RUNTIME/usr/lib/girepository-1.0
|
||||
prepend_dir GI_TYPELIB_PATH $SNAP/usr/lib/$ARCH/girepository-1.0
|
||||
prepend_dir GI_TYPELIB_PATH $SNAP/usr/lib/girepository-1.0
|
||||
prepend_dir GI_TYPELIB_PATH $SNAP/usr/lib/gjs/girepository-1.0
|
||||
|
||||
# Keep an array of data dirs, for looping through them
|
||||
IFS=':' read -r -a data_dirs_array <<< "$XDG_DATA_DIRS"
|
||||
|
||||
# Font Config and themes
|
||||
export FONTCONFIG_PATH=$RUNTIME/etc/fonts
|
||||
export FONTCONFIG_FILE=$RUNTIME/etc/fonts/fonts.conf
|
||||
|
||||
function make_user_fontconfig {
|
||||
echo "<fontconfig>"
|
||||
if [ -d $REALHOME/.local/share/fonts ]; then
|
||||
echo " <dir>$REALHOME/.local/share/fonts</dir>"
|
||||
fi
|
||||
if [ -d $REALHOME/.fonts ]; then
|
||||
echo " <dir>$REALHOME/.fonts</dir>"
|
||||
fi
|
||||
for d in "${data_dirs_array[@]}"; do
|
||||
if [ -d "$d/fonts" ]; then
|
||||
echo " <dir>$d/fonts</dir>"
|
||||
fi
|
||||
done
|
||||
echo ' <include ignore_missing="yes">conf.d</include>'
|
||||
# We need to include this default cachedir first so that caching
|
||||
# works: without it, fontconfig will try to write to the real user home
|
||||
# cachedir and be blocked by AppArmor.
|
||||
echo ' <cachedir prefix="xdg">fontconfig</cachedir>'
|
||||
if [ -d $REALHOME/.cache/fontconfig ]; then
|
||||
echo " <cachedir>$REALHOME/.cache/fontconfig</cachedir>"
|
||||
fi
|
||||
echo "</fontconfig>"
|
||||
}
|
||||
|
||||
if [ $needs_update = true ]; then
|
||||
rm -rf $XDG_DATA_HOME/{fontconfig,fonts,fonts-*,themes,.themes}
|
||||
|
||||
# This fontconfig fragment is installed in a location that is
|
||||
# included by the system fontconfig configuration: namely the
|
||||
# etc/fonts/conf.d/50-user.conf file.
|
||||
mkdir -p $XDG_CONFIG_HOME/fontconfig
|
||||
make_user_fontconfig > $XDG_CONFIG_HOME/fontconfig/fonts.conf
|
||||
|
||||
# the themes symlink are needed for GTK 3.18 when the prefix isn't changed
|
||||
# GTK 3.20 looks into XDG_DATA_DIR which has connected themes.
|
||||
ln -sf $RUNTIME/usr/share/themes $XDG_DATA_HOME
|
||||
ln -sfn $RUNTIME/usr/share/themes $SNAP_USER_DATA/.themes
|
||||
fi
|
||||
|
||||
# Build mime.cache
|
||||
# needed for gtk and qt icon
|
||||
if [ $needs_update = true ]; then
|
||||
rm -rf $XDG_DATA_HOME/mime
|
||||
if [ ! -f $RUNTIME/usr/share/mime/mime.cache ]; then
|
||||
if command -v update-mime-database >/dev/null; then
|
||||
cp --preserve=timestamps -dR $RUNTIME/usr/share/mime $XDG_DATA_HOME
|
||||
update-mime-database $XDG_DATA_HOME/mime
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# Gio modules and cache (including gsettings module)
|
||||
export GIO_MODULE_DIR=$XDG_CACHE_HOME/gio-modules
|
||||
function compile_giomodules {
|
||||
if [ -f $1/glib-2.0/gio-querymodules ]; then
|
||||
rm -rf $GIO_MODULE_DIR
|
||||
mkdir -p $GIO_MODULE_DIR
|
||||
ln -s $1/gio/modules/*.so $GIO_MODULE_DIR
|
||||
$1/glib-2.0/gio-querymodules $GIO_MODULE_DIR
|
||||
fi
|
||||
}
|
||||
if [ $needs_update = true ]; then
|
||||
compile_giomodules $RUNTIME/usr/lib/$ARCH
|
||||
fi
|
||||
|
||||
# Setup compiled gsettings schema
|
||||
GS_SCHEMA_DIR=$XDG_DATA_HOME/glib-2.0/schemas
|
||||
function compile_schemas {
|
||||
if [ -f "$1" ]; then
|
||||
rm -rf $GS_SCHEMA_DIR
|
||||
mkdir -p $GS_SCHEMA_DIR
|
||||
for d in "${data_dirs_array[@]}"; do
|
||||
schema_dir=$d/glib-2.0/schemas
|
||||
if [ -f "$schema_dir/gschemas.compiled" ]; then
|
||||
# This directory already has compiled schemas
|
||||
continue
|
||||
fi
|
||||
if [ -n "$(ls -A $schema_dir/*.xml 2>/dev/null)" ]; then
|
||||
ln -s $schema_dir/*.xml $GS_SCHEMA_DIR
|
||||
fi
|
||||
if [ -n "$(ls -A $schema_dir/*.override 2>/dev/null)" ]; then
|
||||
ln -s $schema_dir/*.override $GS_SCHEMA_DIR
|
||||
fi
|
||||
done
|
||||
# Only compile schemas if we copied anyting
|
||||
if [ -n "$(ls -A $GS_SCHEMA_DIR/*.xml $GS_SCHEMA_DIR/*.override 2>/dev/null)" ]; then
|
||||
"$1" $GS_SCHEMA_DIR
|
||||
fi
|
||||
fi
|
||||
}
|
||||
if [ $needs_update = true ]; then
|
||||
compile_schemas $RUNTIME/usr/lib/$ARCH/glib-2.0/glib-compile-schemas
|
||||
fi
|
||||
|
||||
# Enable gsettings user changes
|
||||
# symlink the dconf file if home plug is connected for read
|
||||
DCONF_DEST_USER_DIR=$SNAP_USER_DATA/.config/dconf
|
||||
if [ ! -f $DCONF_DEST_USER_DIR/user ]; then
|
||||
if [ -f $REALHOME/.config/dconf/user ]; then
|
||||
mkdir -p $DCONF_DEST_USER_DIR
|
||||
ln -s $REALHOME/.config/dconf/user $DCONF_DEST_USER_DIR
|
||||
fi
|
||||
fi
|
||||
|
||||
# Testability support
|
||||
append_dir LD_LIBRARY_PATH $SNAP/testability
|
||||
append_dir LD_LIBRARY_PATH $SNAP/testability/$ARCH
|
||||
append_dir LD_LIBRARY_PATH $SNAP/testability/$ARCH/mesa
|
||||
|
||||
# Gdk-pixbuf loaders
|
||||
export GDK_PIXBUF_MODULE_FILE=$XDG_CACHE_HOME/gdk-pixbuf-loaders.cache
|
||||
export GDK_PIXBUF_MODULEDIR=$RUNTIME/usr/lib/$ARCH/gdk-pixbuf-2.0/2.10.0/loaders
|
||||
if [ $needs_update = true ]; then
|
||||
rm -f $GDK_PIXBUF_MODULE_FILE
|
||||
if [ -f $RUNTIME/usr/lib/$ARCH/gdk-pixbuf-2.0/gdk-pixbuf-query-loaders ]; then
|
||||
$RUNTIME/usr/lib/$ARCH/gdk-pixbuf-2.0/gdk-pixbuf-query-loaders > $GDK_PIXBUF_MODULE_FILE
|
||||
fi
|
||||
fi
|
||||
|
||||
# Icon themes cache
|
||||
if [ $needs_update = true ]; then
|
||||
rm -rf $XDG_DATA_HOME/icons
|
||||
mkdir -p $XDG_DATA_HOME/icons
|
||||
for d in "${data_dirs_array[@]}"; do
|
||||
for i in $d/icons/*; do
|
||||
if [ -f "$i/index.theme" -a ! -f "$i/icon-theme.cache" ]; then
|
||||
theme_dir=$XDG_DATA_HOME/icons/$(basename "$i")
|
||||
if [ ! -d "$theme_dir" ]; then
|
||||
mkdir -p "$theme_dir"
|
||||
ln -s $i/* "$theme_dir"
|
||||
if [ -f $RUNTIME/usr/sbin/update-icon-caches ]; then
|
||||
$RUNTIME/usr/sbin/update-icon-caches "$theme_dir"
|
||||
elif [ -f $RUNTIME/usr/sbin/update-icon-cache.gtk2 ]; then
|
||||
$RUNTIME/usr/sbin/update-icon-cache.gtk2 "$theme_dir"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
done
|
||||
done
|
||||
fi
|
||||
|
||||
# GTK theme and behavior modifier
|
||||
# Those can impact the theme engine used by Qt as well
|
||||
gtk_configs=(.config/gtk-3.0/settings.ini .config/gtk-3.0/bookmarks .config/gtk-2.0/gtkfilechooser.ini)
|
||||
for f in ${gtk_configs[@]}; do
|
||||
dest="$SNAP_USER_DATA/$f"
|
||||
if [ ! -L "$dest" ]
|
||||
then
|
||||
mkdir -p `dirname $dest`
|
||||
ln -s $REALHOME/$f $dest
|
||||
fi
|
||||
done
|
||||
|
||||
# create symbolic link to ibus socket path for ibus to look up its socket files
|
||||
# (see comments #3 and #6 on https://launchpad.net/bugs/1580463)
|
||||
IBUS_CONFIG_PATH=$XDG_CONFIG_HOME/ibus
|
||||
mkdir -p $IBUS_CONFIG_PATH
|
||||
[ -d $IBUS_CONFIG_PATH/bus ] && rm -rf $IBUS_CONFIG_PATH/bus
|
||||
ln -sfn $REALHOME/.config/ibus/bus $IBUS_CONFIG_PATH
|
||||
|
||||
##############################
|
||||
# Glib minimum specific part #
|
||||
##############################
|
||||
|
||||
###############################
|
||||
# Mark update and exec binary #
|
||||
###############################
|
||||
|
||||
[ $needs_update = true ] && echo "SNAP_DESKTOP_LAST_REVISION=$SNAP_REVISION" > $SNAP_USER_DATA/.last_revision
|
||||
|
||||
if [ -n "$SNAP_DESKTOP_DEBUG" ]; then
|
||||
echo "desktop-launch elapsed time: " $(date +%s.%N --date="$START seconds ago")
|
||||
echo "Now running: exec $@"
|
||||
fi
|
||||
|
||||
exec "$@"
|
@ -1,61 +0,0 @@
|
||||
|
||||
#
|
||||
# Copyright (C) 2018-2020 QuasarApp.
|
||||
# Distributed under the lgplv3 software license, see the accompanying
|
||||
# Everyone is permitted to copy and distribute verbatim copies
|
||||
# of this license document, but changing it is not allowed.
|
||||
#
|
||||
|
||||
QT -= gui
|
||||
CONFIG += c++17
|
||||
|
||||
TARGET = QuasarApp
|
||||
TEMPLATE = lib
|
||||
|
||||
DEFINES += QUASARAAPP_LIBRARY
|
||||
|
||||
# The following define makes your compiler emit warnings if you use
|
||||
# any feature of Qt which has been marked as deprecated (the exact warnings
|
||||
# depend on your compiler). Please consult the documentation of the
|
||||
# deprecated API in order to know how to port your code away from it.
|
||||
DEFINES += QT_DEPRECATED_WARNINGS
|
||||
|
||||
# You can also make your code fail to compile if you use deprecated APIs.
|
||||
# In order to do so, uncomment the following line.
|
||||
# You can also select to disable deprecated APIs only up to a certain version of Qt.
|
||||
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
|
||||
|
||||
CONFIG(release, debug|release): {
|
||||
DESTDIR = $$PWD/build/release
|
||||
|
||||
} else {
|
||||
DESTDIR = $$PWD/build/debug
|
||||
}
|
||||
|
||||
SOURCES += \
|
||||
quasarapp.cpp \
|
||||
params.cpp \
|
||||
locales.cpp \
|
||||
settings.cpp \
|
||||
global.cpp
|
||||
|
||||
HEADERS += \
|
||||
quasarapp.h \
|
||||
quasarapp_global.h \
|
||||
params.h \
|
||||
locales.h \
|
||||
settings.h \
|
||||
global.h
|
||||
|
||||
DISTFILES += \
|
||||
QuasarLib.pri \
|
||||
qmakeEtalons/locales.pri
|
||||
|
||||
RESOURCES += \
|
||||
res.qrc
|
||||
|
||||
|
||||
include(Etalons/qmake/ccache.pri)
|
||||
|
||||
VERSION = 1.2.1
|
||||
|
@ -1,26 +0,0 @@
|
||||
#
|
||||
# Copyright (C) 2018-2020 QuasarApp.
|
||||
# Distributed under the lgplv3 software license, see the accompanying
|
||||
# Everyone is permitted to copy and distribute verbatim copies
|
||||
# of this license document, but changing it is not allowed.
|
||||
#
|
||||
|
||||
!isEmpty(QUASARAPP_LIB):error("QuasarLib.pri already included")
|
||||
QUASARAPP_LIB = 1
|
||||
|
||||
#DEPENDS
|
||||
CONFIG(release, debug|release): {
|
||||
QUASARAPP_LIB_OUTPUT_DIR="$$PWD/build/release"
|
||||
} else {
|
||||
QUASARAPP_LIB_OUTPUT_DIR="$$PWD/build/debug"
|
||||
}
|
||||
|
||||
unix:LIBS += -L$$QUASARAPP_LIB_OUTPUT_DIR -lQuasarApp
|
||||
|
||||
win32:LIBS += -L$$QUASARAPP_LIB_OUTPUT_DIR -lQuasarApp1
|
||||
|
||||
INCLUDEPATH += "$$PWD/"
|
||||
|
||||
include(Etalons/qmake/ccache.pri);
|
||||
|
||||
|
101
README.md
101
README.md
@ -1,63 +1,68 @@
|
||||
# QuasarAppLib
|
||||
Global function for quasar app.
|
||||
This lib include base functions for the all applications of QuasarApp group.
|
||||
All methods of the Quasar AppUtils is static
|
||||
Global functions used in applications QuasarApp.
|
||||
This lib include include next modules:
|
||||
|
||||
* parseParams - parase input data of started application
|
||||
* argc - count of arguments
|
||||
* argv - arrat of arguments
|
||||
* return true if all arguments read else false
|
||||
* Locales - This module use for parse local files. This module allows you to work with translations.
|
||||
* Params - This module use for parese app params and create log.
|
||||
* Settings - This is a module that allows you to work with application settings.
|
||||
* Global - This module contains other global functions.
|
||||
|
||||
------------------------
|
||||
* getStrArg - get string value of key
|
||||
* key
|
||||
* return string value of argument
|
||||
|
||||
------------------------
|
||||
* getArg - get string value of key
|
||||
* key
|
||||
* return string value of argument
|
||||
## Build
|
||||
|
||||
------------------------
|
||||
|
||||
* isEndable - check if enable argument of key
|
||||
* key
|
||||
* return true if argument enabled
|
||||
* git clone https://github.com/QuasarApp/QuasarAppLib.git
|
||||
* git submodule update --init --recursive
|
||||
* cd QuasarAppLib
|
||||
* cmake -DCMAKE_PREFIX_PATH=Yuor/Qt/Dir/Path .
|
||||
* make -j8
|
||||
* make test #(for testing)
|
||||
|
||||
------------------------
|
||||
* initLocale init translation of applictaion
|
||||
* locale - string value of locale. example (en)
|
||||
* app - app core of qt
|
||||
* translator - translator core of qt
|
||||
* return return true if locale funded
|
||||
|
||||
# QuasarAppLib
|
||||
Глобальная функция для приложений quasar.
|
||||
Эта библиотека включает базовые функции для всех приложений группы QuasarApp.
|
||||
Все методы Quasar AppUtils являются статическими
|
||||
### Available build options:
|
||||
|
||||
* parseParams - парсит входные данные запускаемого приложения
|
||||
* argc - количество аргументов
|
||||
* argv - аргумент аргументов
|
||||
* вернет true, если все аргументы прочитаны верно иначе false
|
||||
```cmake
|
||||
option(QA_ALLOW_NOT_SUPPORTED_OPTIONS "Enable for allow any command line options" ON)
|
||||
option(QA_DISABLE_LOG "Disabled all logs (force sets verbose to 0)" OFF)
|
||||
|
||||
------------------------
|
||||
* getStrArg - получить строковое значение ключа
|
||||
* возвращаемое строковое значение аргумента
|
||||
```
|
||||
|
||||
------------------------
|
||||
## Include
|
||||
|
||||
* getArg - получить строковое значение ключа
|
||||
* возвращаемое строковое значение аргумента
|
||||
#### The cmake build do not required Qt libraries.
|
||||
|
||||
* cd yourRepo
|
||||
* git submodule add https://github.com/QuasarApp/QuasarAppLib.git # add the repository of QtBigInt into your repo like submodule
|
||||
* git submodule update --init --recursive
|
||||
* Include in your CMakeLists.txt file the main CMakeLists.txt file of QuasarAppLib library
|
||||
>> add_subdirectory(QuasarAppLib)
|
||||
* Rebuild yuor project
|
||||
|
||||
------------------------
|
||||
```cmake
|
||||
add_subdirectory(QuasarAppLib)
|
||||
target_link_libraries(MyBinary PUBLIC QuasarApp)
|
||||
```
|
||||
|
||||
* isEndable - проверить, разрешен ли аргумент ключа
|
||||
* вернет true, если аргумент включен
|
||||
### Note
|
||||
|
||||
------------------------
|
||||
* initLocale инициализирует перевод приложения
|
||||
* locale - строковое значение locale. пример (en)
|
||||
* app - ядро приложения qt
|
||||
* translator - ядро переводчика qt
|
||||
* вернет true, если все аргументы прочитаны верно иначе false
|
||||
By Default QuasarAppLib makes as a static library. If you want to create a shared library just add the BUILD_SHARED_LIBS into your main CMakeLists.txt file.
|
||||
Example :
|
||||
|
||||
```cmake
|
||||
set(BUILD_SHARED_LIBS ON)
|
||||
add_subdirectory(QuasarAppLib)
|
||||
target_link_libraries(MyBinary PUBLIC QuasarApp)
|
||||
|
||||
```
|
||||
|
||||
# Usage
|
||||
|
||||
```cpp
|
||||
#include <quasarapp.h>
|
||||
|
||||
if (!QuasarAppUtils::Params::parseParams(argc, argv)) {
|
||||
QuasarAppUtils::Params::log("Warning message", QuasarAppUtils::Warning);
|
||||
QuasarAppUtils::Params::showHelp();
|
||||
exit(0);
|
||||
}
|
||||
```
|
||||
|
83
crc32constexper.h
Normal file
83
crc32constexper.h
Normal file
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright (C) 2025-2025 QuasarApp.
|
||||
* Distributed under the lgplv3 software license, see the accompanying
|
||||
* Everyone is permitted to copy and distribute verbatim copies
|
||||
* of this license document, but changing it is not allowed.
|
||||
*/
|
||||
|
||||
#ifndef CRC32CONSTEXPER_H
|
||||
#define CRC32CONSTEXPER_H
|
||||
|
||||
|
||||
#include <array>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
namespace QuasarAppUtils {
|
||||
|
||||
/**
|
||||
* @brief generateCrc32Table This method generate crc32 table for fast calculate crc32 hash.
|
||||
* @param polynomial This is polynomial for crc32 hash.
|
||||
* @return return table for fast calculate crc32 hash.
|
||||
* @note This method is constexpr and available in compile time.
|
||||
*/
|
||||
constexpr std::array<uint32_t, 256> generateCrc32Table(uint32_t polynomial = 0xEDB88320) {
|
||||
std::array<uint32_t, 256> table{};
|
||||
for (uint32_t i = 0; i < 256; ++i) {
|
||||
uint32_t crc = i;
|
||||
for (int j = 0; j < 8; ++j) {
|
||||
crc = (crc >> 1) ^ (-(crc & 1) & polynomial);
|
||||
}
|
||||
table[i] = crc;
|
||||
}
|
||||
return table;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief crc32Table This is crc32 table for fast calculate crc32 hash.
|
||||
* @note This table is used for fast calculate crc32 hash.
|
||||
*/
|
||||
constexpr std::array<uint32_t, 256> crc32Table = generateCrc32Table();
|
||||
|
||||
/**
|
||||
* @brief calculateCrc32 This method calculate crc32 hash for data.
|
||||
* @param data This is data for calculate crc32 hash.
|
||||
* @param size This is size of data.
|
||||
* @param initialCrc This is initial crc value.
|
||||
* @return return crc32 hash for data.
|
||||
* @note This method is constexpr and available in compile time.
|
||||
*/
|
||||
constexpr uint32_t calculateCrc32(const char* data, size_t size, uint32_t initialCrc = 0xFFFFFFFF) {
|
||||
uint32_t crc = initialCrc;
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
crc = crc32Table[(crc ^ data[i]) & 0xFF] ^ (crc >> 8);
|
||||
}
|
||||
return crc ^ 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief calculateCrc16 This method calculate crc16 hash for data.
|
||||
* @param data This is data for calculate crc16 hash.
|
||||
* @param size This is size of data.
|
||||
* @param initialCrc This is initial crc value.
|
||||
* @return return crc16 hash for data.
|
||||
* @note This method is constexpr and available in compile time.
|
||||
*/
|
||||
constexpr uint16_t calculateCrc16(const char* data, size_t size, uint32_t initialCrc = 0xFFFFFFFF) {
|
||||
return calculateCrc32(data, size, initialCrc) % 0xFFFF;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief calculateCrc8 This method calculate crc8 hash for data.
|
||||
* @param data This is data for calculate crc8 hash.
|
||||
* @param size This is size of data.
|
||||
* @param initialCrc This is initial crc value.
|
||||
* @return return crc8 hash for data.
|
||||
* @note This method is constexpr and available in compile time.
|
||||
*/
|
||||
constexpr uint16_t calculateCrc8(const char* data, size_t size, uint32_t initialCrc = 0xFFFFFFFF) {
|
||||
return calculateCrc32(data, size, initialCrc) % 0xFF;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // CRC32CONSTEXPER_H
|
2496
doxygen.conf
Normal file
2496
doxygen.conf
Normal file
File diff suppressed because it is too large
Load Diff
@ -1 +0,0 @@
|
||||
#include "global.h"
|
67
global.h
67
global.h
@ -1,67 +0,0 @@
|
||||
#ifndef GLOBAL_H
|
||||
#define GLOBAL_H
|
||||
|
||||
#include <cstdlib>
|
||||
#include <type_traits>
|
||||
|
||||
template <typename T>
|
||||
constexpr inline T operator | (T lhs, T rhs)
|
||||
{
|
||||
|
||||
static_assert(std::is_enum<T>::value,
|
||||
"template parameter is not an enum type");
|
||||
|
||||
return static_cast<T>(static_cast<int>(lhs) | static_cast<int>(rhs));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
constexpr inline T operator & (T lhs, T rhs)
|
||||
{
|
||||
|
||||
static_assert(std::is_enum<T>::value,
|
||||
"template parameter is not an enum type");
|
||||
|
||||
return static_cast<T>(static_cast<int>(lhs) & static_cast<int>(rhs));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
constexpr inline T operator >> (T lhs, T rhs)
|
||||
{
|
||||
|
||||
static_assert(std::is_enum<T>::value,
|
||||
"template parameter is not an enum type");
|
||||
|
||||
return static_cast<T>(static_cast<int>(lhs) >> static_cast<int>(rhs));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
constexpr inline T operator << (T lhs, T rhs)
|
||||
{
|
||||
|
||||
static_assert(std::is_enum<T>::value,
|
||||
"template parameter is not an enum type");
|
||||
|
||||
return static_cast<T>(static_cast<int>(lhs) << static_cast<int>(rhs));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
constexpr inline T operator ~ (T lhs)
|
||||
{
|
||||
|
||||
static_assert(std::is_enum<T>::value,
|
||||
"template parameter is not an enum type");
|
||||
|
||||
return static_cast<T>(~static_cast<int>(lhs));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
constexpr inline T operator ^ (T lhs, T rhs)
|
||||
{
|
||||
|
||||
static_assert(std::is_enum<T>::value,
|
||||
"template parameter is not an enum type");
|
||||
|
||||
return static_cast<T>(static_cast<int>(lhs) ^ static_cast<int>(rhs));
|
||||
}
|
||||
|
||||
#endif // GLOBAL_H
|
108
helpdata.cpp
Normal file
108
helpdata.cpp
Normal file
@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2025 QuasarApp.
|
||||
* Distributed under the lgplv3 software license, see the accompanying
|
||||
* Everyone is permitted to copy and distribute verbatim copies
|
||||
* of this license document, but changing it is not allowed.
|
||||
*/
|
||||
|
||||
#include "helpdata.h"
|
||||
#include <iostream>
|
||||
|
||||
#ifdef Q_OS_WIN32
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <sys/ioctl.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
namespace QuasarAppUtils {
|
||||
namespace Help {
|
||||
|
||||
static int MAX_LENGTH = -1;
|
||||
static int SectionMargin = 2;
|
||||
|
||||
#define EXPANDER(COUNT, ITEM) QString(COUNT, ITEM).toStdString()
|
||||
#define SPACES(X) EXPANDER(X, ' ')
|
||||
#define SECTION_MARGIN SPACES(SectionMargin)
|
||||
#define WIDTH ((MAX_LENGTH > 10)? MAX_LENGTH: width())
|
||||
|
||||
|
||||
/*
|
||||
* @brief print This method prints the one line of the help.
|
||||
* @param key This is Option name.
|
||||
* @param value This is Description of option.
|
||||
* @param keyLength This is length of the current line.
|
||||
* This is private method of the QuasarAppLibrary.
|
||||
*/
|
||||
void print(const QString& key, const QString& value, int keyLength) {
|
||||
|
||||
auto diffExpander = QString(keyLength - key.size(), ' ');
|
||||
std::cout << SECTION_MARGIN << key.toStdString() << diffExpander.toStdString() << ":";
|
||||
|
||||
QString expander(keyLength + SectionMargin, ' ');
|
||||
auto words = value.split(" ");
|
||||
|
||||
int currentLength = std::max(keyLength, static_cast<int>(key.size()));
|
||||
for (const auto& word : words) {
|
||||
if (currentLength + 2 + word.size() < WIDTH) {
|
||||
std::cout << " " << word.toStdString();
|
||||
currentLength += 2 + word.size();
|
||||
|
||||
} else {
|
||||
std::cout << std::endl << expander.toStdString() << ":";
|
||||
currentLength = keyLength;
|
||||
|
||||
std::cout << " " << word.toStdString();
|
||||
currentLength += 2 + word.size();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void print(const QuasarAppUtils::Help::Options &oprionsList) {
|
||||
int maxLength = 0;
|
||||
for (auto line = oprionsList.begin(); line != oprionsList.end(); ++line) {
|
||||
if (line.key().size() > maxLength)
|
||||
maxLength = line.key().size();
|
||||
}
|
||||
|
||||
maxLength = std::min(WIDTH / 3, maxLength);
|
||||
|
||||
for (auto line = oprionsList.begin(); line != oprionsList.end(); ++line) {
|
||||
print(line.key(), line.value(), maxLength + SectionMargin);
|
||||
std::cout << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void print(const Section &help) {
|
||||
for (auto line = help.begin(); line != help.end(); ++line) {
|
||||
QString expander(WIDTH, '-');
|
||||
|
||||
std::cout << line.key().toStdString() << std::endl;
|
||||
std::cout << expander.toStdString() << std::endl;
|
||||
print(line.value());
|
||||
std::cout << std::endl << expander.toStdString() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void setLineLength(int newLength) {
|
||||
MAX_LENGTH = newLength;
|
||||
}
|
||||
|
||||
int width() {
|
||||
|
||||
#ifdef Q_OS_WIN32
|
||||
CONSOLE_SCREEN_BUFFER_INFO csbi;
|
||||
|
||||
GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi);
|
||||
return csbi.srWindow.Right - csbi.srWindow.Left + 1;
|
||||
#else
|
||||
struct winsize w;
|
||||
ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
|
||||
return w.ws_col;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
80
helpdata.h
Normal file
80
helpdata.h
Normal file
@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2025 QuasarApp.
|
||||
* Distributed under the lgplv3 software license, see the accompanying
|
||||
* Everyone is permitted to copy and distribute verbatim copies
|
||||
* of this license document, but changing it is not allowed.
|
||||
*/
|
||||
|
||||
#ifndef HELPDATA_H
|
||||
#define HELPDATA_H
|
||||
|
||||
#include <QMap>
|
||||
#include "quasarapp_global.h"
|
||||
|
||||
namespace QuasarAppUtils{
|
||||
|
||||
/**
|
||||
* @brief Help namespace contains functions for printing help in to console. All Print fucntions automaticly calc width of the console and aligns the text to fit the window.
|
||||
*/
|
||||
namespace Help {
|
||||
/**
|
||||
* @brief Options this is list of **key-descriptions** pairs of help.
|
||||
* The **key** is name of the available argument and **description** is description of the available argument.
|
||||
*
|
||||
* **Example**:
|
||||
*
|
||||
* @code{cpp}
|
||||
* Options myOptionsList = {{"argument1", "This is test argumetn1 of my application."},
|
||||
* {"argument2", "This is test argumetn2 of my application."}};
|
||||
*
|
||||
* @endcode
|
||||
*/
|
||||
typedef QMultiMap<QString, QString> Options;
|
||||
|
||||
/**
|
||||
* @brief Section This is list of the help Sections. The one section it is Title of the section and Help::Options list.
|
||||
*
|
||||
* **Example:**
|
||||
* @code{cpp}
|
||||
* Options myOptionsList = {{"argument1", "This is test argumetn1 of my application."},
|
||||
* {"argument2", "This is test argumetn2 of my application."}};
|
||||
* Section mySections = {{"This Is main section of the help", myOptionsList}};
|
||||
* QuasarAppUtils::Help::print(mySections);
|
||||
* @endcode
|
||||
*/
|
||||
typedef QMultiMap<QString, Options> Section;
|
||||
|
||||
/**
|
||||
* @brief Charters is wraper of the Section type.
|
||||
* @warning This type is depricated. Use the Help:Section type.
|
||||
*/
|
||||
typedef Section Charters;
|
||||
|
||||
/**
|
||||
* @brief width This method return current width of the cosole window.
|
||||
* @return width in pxels of the cosole window.
|
||||
*/
|
||||
int width();
|
||||
|
||||
/**
|
||||
* @brief print This method print a one options list.
|
||||
* @param oprionsList This is options list.
|
||||
*/
|
||||
void QUASARAPPSHARED_EXPORT print(const Options& oprionsList);
|
||||
|
||||
/**
|
||||
* @brief print This method print all sections of the help.
|
||||
* @note This is main method for printing helps.
|
||||
* @param help This is sections list.
|
||||
*/
|
||||
void QUASARAPPSHARED_EXPORT print(const Section& help);
|
||||
|
||||
/**
|
||||
* @brief setLineLength sets new length of the help line (width of the console window). If you set this into -1 then the window width will be selected automatically.
|
||||
* @param newLength This is a new size of the console window.
|
||||
*/
|
||||
void QUASARAPPSHARED_EXPORT setLineLength(int newLength);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // HELPDATA_H
|
18
humanreadableobject.cpp
Normal file
18
humanreadableobject.cpp
Normal file
@ -0,0 +1,18 @@
|
||||
//#
|
||||
//# Copyright (C) 2022-2025 QuasarApp.
|
||||
//# Distributed under the GPLv3 software license, see the accompanying
|
||||
//# Everyone is permitted to copy and distribute verbatim copies
|
||||
//# of this license document, but changing it is not allowed.
|
||||
//#
|
||||
|
||||
|
||||
#include "humanreadableobject.h"
|
||||
|
||||
namespace QuasarAppUtils{
|
||||
|
||||
HumanReadableObject::HumanReadableObject()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
39
humanreadableobject.h
Normal file
39
humanreadableobject.h
Normal file
@ -0,0 +1,39 @@
|
||||
//#
|
||||
//# Copyright (C) 2022-2025 QuasarApp.
|
||||
//# Distributed under the GPLv3 software license, see the accompanying
|
||||
//# Everyone is permitted to copy and distribute verbatim copies
|
||||
//# of this license document, but changing it is not allowed.
|
||||
//#
|
||||
|
||||
#ifndef HUMANREADABLEOBJECT_H
|
||||
#define HUMANREADABLEOBJECT_H
|
||||
|
||||
#include <QString>
|
||||
#include "quasarapp_global.h"
|
||||
|
||||
namespace QuasarAppUtils {
|
||||
|
||||
/**
|
||||
* @brief The HumanReadableObject interface This is simple class that add one virtula method toString.
|
||||
* All childs object should be override this method.
|
||||
*/
|
||||
class QUASARAPPSHARED_EXPORT HumanReadableObject
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief toString This method convert this object to human readable string.
|
||||
* @return human readable string of this object.
|
||||
*/
|
||||
virtual QString toString() const = 0;
|
||||
|
||||
protected:
|
||||
HumanReadableObject();
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief iHRO This is short abriviature of the HumanReadableObject class.
|
||||
*/
|
||||
typedef HumanReadableObject iHRO;
|
||||
|
||||
}
|
||||
#endif // HUMANREADABLEOBJECT_H
|
128
isettings.cpp
Normal file
128
isettings.cpp
Normal file
@ -0,0 +1,128 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2025 QuasarApp.
|
||||
* Distributed under the lgplv3 software license, see the accompanying
|
||||
* Everyone is permitted to copy and distribute verbatim copies
|
||||
* of this license document, but changing it is not allowed.
|
||||
*/
|
||||
|
||||
#include "isettings.h"
|
||||
#include <QSettings>
|
||||
#include <QCoreApplication>
|
||||
#include "qaglobalutils.h"
|
||||
|
||||
namespace QuasarAppUtils {
|
||||
|
||||
ISettings::ISettings(SettingsSaveMode mode) {
|
||||
_mode = mode;
|
||||
}
|
||||
|
||||
ISettings::~ISettings() {
|
||||
if (_defaultConfig)
|
||||
delete _defaultConfig;
|
||||
}
|
||||
|
||||
void ISettings::clearCache() {
|
||||
_cache.clear();
|
||||
}
|
||||
|
||||
QHash<QString, QVariant> &ISettings::settingsMap() {
|
||||
if (!_defaultConfig)
|
||||
_defaultConfig = new QHash<QString, QVariant>(defaultSettings());
|
||||
|
||||
return *_defaultConfig;
|
||||
}
|
||||
|
||||
SettingsSaveMode ISettings::getMode() const {
|
||||
return _mode;
|
||||
}
|
||||
|
||||
void ISettings::setMode(const SettingsSaveMode &mode) {
|
||||
_mode = mode;
|
||||
}
|
||||
|
||||
ISettings *ISettings::instance() {
|
||||
return Service<ISettings>::instance();
|
||||
}
|
||||
|
||||
bool ISettings::initService(std::unique_ptr<ISettings> obj) {
|
||||
return Service<ISettings>::initService(std::move(obj));
|
||||
}
|
||||
|
||||
QVariant ISettings::getValue(const QString &key, const QVariant &def) {
|
||||
debug_assert(key.size(), "You can't use the empty key value!");
|
||||
|
||||
if (!_cache.contains(key)) {
|
||||
|
||||
QVariant defVal = def;
|
||||
if (defVal.isNull()) {
|
||||
defVal = settingsMap().value(key);
|
||||
}
|
||||
|
||||
_cache[key] = getValueImplementation(key, def);
|
||||
}
|
||||
|
||||
return _cache[key];
|
||||
}
|
||||
|
||||
QString ISettings::getStrValue(const QString &key, const QString &def) {
|
||||
if (def.isEmpty()) {
|
||||
return getValue(key).toString();
|
||||
|
||||
}
|
||||
|
||||
return getValue(key, QVariant(def)).toString();
|
||||
}
|
||||
|
||||
void ISettings::resetToDefault() {
|
||||
auto &defaultConfig = settingsMap();
|
||||
|
||||
for (auto it = defaultConfig.begin(); it != defaultConfig.end(); ++it) {
|
||||
if (!ignoreToRest(it.key()))
|
||||
setValue(it.key(), defaultConfig.value(it.key()));
|
||||
}
|
||||
}
|
||||
|
||||
bool ISettings::ignoreToRest(const QString &) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
void ISettings::sync() {
|
||||
for (auto it = _cache.begin(); it != _cache.end(); ++it) {
|
||||
setValueImplementation(it.key(), it.value());
|
||||
}
|
||||
|
||||
return syncImplementation();
|
||||
}
|
||||
|
||||
void ISettings::forceReloadCache() {
|
||||
auto &defaultConfig = settingsMap();
|
||||
|
||||
for (auto it = defaultConfig.begin(); it != defaultConfig.end(); ++it) {
|
||||
setValue(it.key(), getValueImplementation(it.key(), it.value()));
|
||||
}
|
||||
}
|
||||
|
||||
void ISettings::setValue(const QString &key, const QVariant &value) {
|
||||
|
||||
debug_assert(key.size(), "You can't use the empty key value!");
|
||||
|
||||
if (_cache.contains(key) && _cache.value(key) == value) {
|
||||
return;
|
||||
}
|
||||
|
||||
_cache[key] = value;
|
||||
|
||||
emit valueChanged(key, value);
|
||||
emit valueStrChanged(key, value.toString());
|
||||
|
||||
if (_mode == SettingsSaveMode::Auto) {
|
||||
setValueImplementation(key, value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ISettings::setStrValue(const QString &key, const QString &value) {
|
||||
setValue(key, value);
|
||||
}
|
||||
|
||||
}
|
230
isettings.h
Normal file
230
isettings.h
Normal file
@ -0,0 +1,230 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2025 QuasarApp.
|
||||
* Distributed under the lgplv3 software license, see the accompanying
|
||||
* Everyone is permitted to copy and distribute verbatim copies
|
||||
* of this license document, but changing it is not allowed.
|
||||
*/
|
||||
|
||||
#ifndef ISETTINGS_H
|
||||
#define ISETTINGS_H
|
||||
|
||||
#include "qaservice.h"
|
||||
#include "quasarapp_global.h"
|
||||
#include <QObject>
|
||||
#include <QVariant>
|
||||
|
||||
class QSettings;
|
||||
|
||||
namespace QuasarAppUtils {
|
||||
|
||||
/**
|
||||
* @brief The SettingsSaveMode enum
|
||||
*/
|
||||
enum class SettingsSaveMode: quint64 {
|
||||
/// a settings will be saved on hard disk when called the Settings::setValue method.
|
||||
Auto,
|
||||
/// a settings will be saved on hard disk when called the Settings::Sync method.
|
||||
Manual
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The Settings class base interface for implementation settings backends.
|
||||
* Available implementations:
|
||||
* Setting (based on QSettings backend)
|
||||
* @note This is singleton object.
|
||||
*
|
||||
* @note The all child classes should be initialized before used.
|
||||
*
|
||||
* @code{cpp}
|
||||
* auto settingsInstance = Setting::initService<Setting>();
|
||||
* @endcode
|
||||
*
|
||||
* @see ISettings::init method.
|
||||
*
|
||||
*/
|
||||
class QUASARAPPSHARED_EXPORT ISettings : public QObject, public Service<ISettings>
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
~ISettings() override;
|
||||
|
||||
/**
|
||||
* @brief getValue This method return the value of the settings.
|
||||
* @param key This is name of the required settings value.
|
||||
* @param def This is default value if a value is not finded. If this params will be skipped, then The Settngs model try find default value in the defaultSettings map.
|
||||
* @return value of a @a key
|
||||
* @see ISettings::defaultSettings
|
||||
*/
|
||||
Q_INVOKABLE QVariant getValue(const QString &key, const QVariant& def = {});
|
||||
|
||||
/**
|
||||
* @brief getStrValue some as getValue but convert result object to QString type.
|
||||
* @param key This is name of the required settings value.
|
||||
* @param def This is default value if a value is not finded. If this params will be skipped, then The Settngs model try find default value in the defaultSettings map.
|
||||
* @return value of a @a key
|
||||
* @see ISettings::defaultSettings
|
||||
* @warning If you set a def arguments to empty string then this method will return default value from the defaultSettings map.
|
||||
*/
|
||||
Q_INVOKABLE QString getStrValue(const QString &key, const QString& def = {});
|
||||
|
||||
/**
|
||||
* @brief resetToDefault This method reset all settings to default values.
|
||||
*/
|
||||
Q_INVOKABLE void resetToDefault();
|
||||
|
||||
/**
|
||||
* @brief ignoreToRest This method should be returns true if the @a key setting is not be reset on the resetToDefault method.
|
||||
* @param key This is keuy value.
|
||||
* @return true if the @a key option can't be reset to default.
|
||||
* The default implementaion alwayes return false.
|
||||
*/
|
||||
virtual bool ignoreToRest(const QString& key) const;
|
||||
|
||||
/**
|
||||
* @brief sync This method save all setings data on a hard disk;
|
||||
*/
|
||||
void sync();
|
||||
|
||||
/**
|
||||
* @brief forceReloadCache This method force reload settings data from disk.
|
||||
* @note Cache will be refreshed
|
||||
*/
|
||||
void forceReloadCache();
|
||||
|
||||
/**
|
||||
* @brief getMode This method return the current mode of the settings.
|
||||
* @return the current mode of the settings.
|
||||
*/
|
||||
SettingsSaveMode getMode() const;
|
||||
|
||||
/**
|
||||
* @brief setMode This method sets a new value of the settings mode.
|
||||
* @param mode This is a new value of the settings mode.
|
||||
*/
|
||||
void setMode(const SettingsSaveMode &mode);
|
||||
|
||||
/**
|
||||
* @brief instance This method returns pointer to current settings object.
|
||||
* @return pointer to current settings object.
|
||||
* @see Service::instance
|
||||
*/
|
||||
static ISettings* instance();
|
||||
|
||||
/**
|
||||
* @brief initService This method initialize the global settings object.
|
||||
* @param obj This is prepared settings object. You should create a your object monyaly, and add to initialization
|
||||
* @code{cpp}
|
||||
* bool result = initService(std::make_unique<MySettings>());
|
||||
* @endcode
|
||||
* @return true if initialization finished successful else false.
|
||||
* @see Service::initService
|
||||
*/
|
||||
static bool initService(std::unique_ptr<ISettings> obj);
|
||||
|
||||
public slots:
|
||||
/**
|
||||
* @brief setValue This slot sets new value for a @a key setting
|
||||
* @param key This is name of the changed setting.
|
||||
* @param value This is a new value of the setting
|
||||
*/
|
||||
void setValue(const QString &key, const QVariant& value);
|
||||
|
||||
/**
|
||||
* @brief setStrValue This is some as setValue but working with the QString type.
|
||||
* @param key This is name of the changed setting.
|
||||
* @param value This is a new value of the setting
|
||||
*/
|
||||
void setStrValue(const QString& key, const QString& value);
|
||||
|
||||
|
||||
signals:
|
||||
/**
|
||||
* @brief valueChanged This signal when value of the @a key settings changed
|
||||
* @param key This is name of change setting.
|
||||
* @param value This is a new value of @a key.
|
||||
*/
|
||||
void valueChanged(QString key, QVariant value);
|
||||
|
||||
/**
|
||||
* @brief valueStrChanged some as valueChanged(QString key, QVariant value) but value has ben converted to the QString type.
|
||||
* @param key This is name of change setting.
|
||||
* @param value This is a new value of @a key.
|
||||
*/
|
||||
void valueStrChanged(QString key, QString value);
|
||||
|
||||
protected:
|
||||
|
||||
explicit ISettings(SettingsSaveMode mode = SettingsSaveMode::Auto);
|
||||
|
||||
/**
|
||||
* @brief defaultSettings This method must be return default map of the settings and them values. If the default value argument in a getValue method will be skipped, then settings model try find a default value in this map.
|
||||
* @return The default settings map.
|
||||
* @see ISettings::getValue
|
||||
* **example:** example of implementation of this method:
|
||||
*
|
||||
* @code{cpp}
|
||||
*
|
||||
QHash<QString, QVariant> SettingsModel::defaultSettings() {
|
||||
QHash<QString, QVariant> settings;
|
||||
|
||||
settings["colorTheme"] = "#ff6b01";
|
||||
settings["shareName"] = true;
|
||||
settings["devSettingEnable"] = false;
|
||||
settings["host"] = "";
|
||||
settings["APIVersion"] = 2;
|
||||
|
||||
return settings;
|
||||
}
|
||||
* @endcode
|
||||
*/
|
||||
virtual QHash<QString, QVariant> defaultSettings() = 0;
|
||||
|
||||
/**
|
||||
* @brief syncImplementation This method should save all configuration data to the hard drive;
|
||||
*/
|
||||
virtual void syncImplementation() = 0;
|
||||
|
||||
/**
|
||||
* @brief getValueImplementation This method will return the value of the settings.
|
||||
* @param key This is name of the required settings value.
|
||||
* @param def This is default value if a value is not finded.
|
||||
* @return value of a @a key
|
||||
*/
|
||||
virtual QVariant getValueImplementation(const QString &key, const QVariant& def) = 0;
|
||||
|
||||
/**
|
||||
* @brief setValueImplementation This slot will set a new value for the @a key parameter.
|
||||
* @param key This is name of the changed setting.
|
||||
* @param value This is a new value of the setting
|
||||
*/
|
||||
virtual void setValueImplementation(const QString key, const QVariant& value) = 0;
|
||||
|
||||
/**
|
||||
* @brief clearCache This method clear all data from cache.
|
||||
*/
|
||||
void clearCache();
|
||||
|
||||
/**
|
||||
* @brief settingsMap This method returns initialized settings map.
|
||||
* Settings map contains pairs with settings key and default value.
|
||||
* @return initialized settings map.
|
||||
* @see ISettings::defaultSettings method
|
||||
*/
|
||||
QHash<QString, QVariant>& settingsMap();
|
||||
|
||||
private:
|
||||
|
||||
SettingsSaveMode _mode = SettingsSaveMode::Auto;
|
||||
|
||||
QHash<QString, QVariant> _cache;
|
||||
QHash<QString, QVariant> *_defaultConfig = nullptr;
|
||||
|
||||
friend class Service<ISettings>;
|
||||
};
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif // ISETTINGS_H
|
236
locales.cpp
236
locales.cpp
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2020 QuasarApp.
|
||||
* Copyright (C) 2018-2025 QuasarApp.
|
||||
* Distributed under the lgplv3 software license, see the accompanying
|
||||
* Everyone is permitted to copy and distribute verbatim copies
|
||||
* of this license document, but changing it is not allowed.
|
||||
@ -11,22 +11,234 @@
|
||||
#include <QCoreApplication>
|
||||
#include <QTranslator>
|
||||
#include <QLocale>
|
||||
#include <QLibraryInfo>
|
||||
#include <QRegularExpression>
|
||||
#include <QLocale>
|
||||
#include <QMap>
|
||||
|
||||
using namespace QuasarAppUtils;
|
||||
|
||||
bool QuasarAppUtils::Locales::findQmPrivate(const QString &prefix,
|
||||
QList<QTranslator*> &qmFiles) {
|
||||
|
||||
bool Locales::initLocale(const QString& prefix, const QString &locale, QCoreApplication *app, QTranslator *translator){
|
||||
for (const auto &location: std::as_const(_locations)) {
|
||||
|
||||
QString defaultLocale = QLocale::system().name();
|
||||
defaultLocale.truncate(defaultLocale.lastIndexOf('_'));
|
||||
const auto availableFiles = QDir(location).entryInfoList(
|
||||
{prefix + ".qm"}, QDir::Files);
|
||||
|
||||
if(!locale.isEmpty() && translator->load(QString("%0/%1").arg(prefix, locale))) {
|
||||
return app->installTranslator(translator);
|
||||
for (const auto &file : availableFiles) {
|
||||
auto qmFile = new QTranslator();
|
||||
|
||||
if(!qmFile->load(file.absoluteFilePath())) {
|
||||
qWarning() << "Failed to load translation file : "
|
||||
+ file.absoluteFilePath();
|
||||
delete qmFile;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (qmFile->isEmpty()) {
|
||||
qDebug() << "Translation file is Empty: " +
|
||||
file.absoluteFilePath();
|
||||
delete qmFile;
|
||||
continue;
|
||||
}
|
||||
|
||||
auto language = qmFile->language();
|
||||
if (language.size() && !language.contains(prefix, Qt::CaseInsensitive)) {
|
||||
auto message = QString("The target language (%0) and a choosed qm file (%1) "
|
||||
"is different, Loading will be skiped: ").
|
||||
arg(language, file.absoluteFilePath());
|
||||
qDebug() << message;
|
||||
|
||||
delete qmFile;
|
||||
continue;
|
||||
}
|
||||
|
||||
qmFiles += qmFile;
|
||||
}
|
||||
}
|
||||
|
||||
if(!translator->load(QString("%0/%1").arg(prefix, defaultLocale))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return app->installTranslator(translator);
|
||||
return qmFiles.size();
|
||||
}
|
||||
|
||||
bool QuasarAppUtils::Locales::findQm(QString localePrefix,
|
||||
QList<QTranslator *> &qmFiles) {
|
||||
|
||||
if (localePrefix.size() < 2) {
|
||||
if (localePrefix.compare('c', Qt::CaseInsensitive) == 0) {
|
||||
return findQmPrivate("en", qmFiles);
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
} else if (localePrefix.size() >= 4) {
|
||||
return findQmPrivate(localePrefix.replace('-', '_'), qmFiles);
|
||||
}
|
||||
|
||||
return findQmPrivate(localePrefix, qmFiles);
|
||||
}
|
||||
|
||||
void QuasarAppUtils::Locales::installTranslations( QList<QTranslator *> &qmFiles)
|
||||
{
|
||||
for (const auto & translator: std::as_const(qmFiles)) {
|
||||
if (!QCoreApplication::installTranslator(translator)) {
|
||||
|
||||
qWarning() << "Failed to install translation file : " + translator->filePath();
|
||||
delete translator;
|
||||
// we use a link of qmFiles so remove all invalid translations.
|
||||
qmFiles.removeAll(translator);
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QString Locales::translatePrivate(const char *source, const QLocale &locale) {
|
||||
auto translations = _translations.value(locale);
|
||||
|
||||
for (const auto& tr : translations) {
|
||||
auto result = tr->translate("QuasarAppUtils::Locales", source);
|
||||
if (result.size()) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return source;
|
||||
}
|
||||
|
||||
bool Locales::setLocalePrivate(const QLocale &locale, bool force, bool install) {
|
||||
if (force) {
|
||||
clearCache(locale);
|
||||
}
|
||||
|
||||
removeOldTranslation(_currentLocate);
|
||||
|
||||
// take a link to list of translations.
|
||||
QList<QTranslator *> &qmFiles = _translations[locale];
|
||||
|
||||
if (qmFiles.isEmpty()) {
|
||||
// fill list of translations
|
||||
const auto list = locale.uiLanguages();
|
||||
|
||||
auto it = list.rbegin();
|
||||
while (qmFiles.isEmpty() && it != list.rend() && !findQm(*it, qmFiles)) {
|
||||
it++;
|
||||
}
|
||||
|
||||
if (qmFiles.isEmpty())
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
if (install)
|
||||
installTranslations(qmFiles);
|
||||
|
||||
emit sigTranslationChanged();
|
||||
|
||||
_currentLocate = locale;
|
||||
|
||||
return _translations[locale].size();
|
||||
}
|
||||
|
||||
const QLocale &Locales::currentLocate() {
|
||||
auto obj = instance();
|
||||
return obj->currentLocatePrivate();
|
||||
}
|
||||
|
||||
QString Locales::tr(const char *source, const QLocale &locale) {
|
||||
auto obj = instance();
|
||||
return obj->translatePrivate(source, locale);
|
||||
}
|
||||
|
||||
bool Locales::setLocale(const QLocale &locale, bool force) {
|
||||
auto obj = instance();
|
||||
return obj->setLocalePrivate(locale, force);
|
||||
}
|
||||
|
||||
bool Locales::init(const QList<QLocale> &locales, const QSet<QString> &location) {
|
||||
auto obj = instance();
|
||||
return obj->initPrivate(locales, location);
|
||||
}
|
||||
|
||||
bool Locales::init(const QLocale &locale, const QSet<QString> & location) {
|
||||
auto obj = instance();
|
||||
return obj->initPrivate(locale, location);
|
||||
}
|
||||
|
||||
bool Locales::initPrivate(const QLocale &locale, const QSet<QString> & locations) {
|
||||
|
||||
#if QT_VERSION <= QT_VERSION_CHECK(6, 0, 0)
|
||||
auto defaultTr = QLibraryInfo::location(QLibraryInfo::TranslationsPath);
|
||||
#else
|
||||
auto defaultTr = QLibraryInfo::path(QLibraryInfo::TranslationsPath);
|
||||
#endif
|
||||
_locations = locations;
|
||||
if (!_locations.contains(defaultTr)) {
|
||||
_locations += defaultTr;
|
||||
}
|
||||
|
||||
return setLocalePrivate(locale);
|
||||
}
|
||||
|
||||
bool Locales::initPrivate(const QList<QLocale> &locales, const QSet<QString> &locations) {
|
||||
#if QT_VERSION <= QT_VERSION_CHECK(6, 0, 0)
|
||||
auto defaultTr = QLibraryInfo::location(QLibraryInfo::TranslationsPath);
|
||||
#else
|
||||
auto defaultTr = QLibraryInfo::path(QLibraryInfo::TranslationsPath);
|
||||
#endif
|
||||
_locations = locations;
|
||||
if (!_locations.contains(defaultTr)) {
|
||||
_locations += defaultTr;
|
||||
}
|
||||
|
||||
for (const auto& locale: locales) {
|
||||
if (!setLocalePrivate(locale, false, false)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Locales::clearCache(const QLocale &locale) {
|
||||
for (const auto & tr :std::as_const(_translations[locale])) {
|
||||
QCoreApplication::removeTranslator(tr);
|
||||
delete tr;
|
||||
}
|
||||
|
||||
_translations[locale].clear();
|
||||
}
|
||||
|
||||
void Locales::clearCache() {
|
||||
for (auto it = _translations.keyBegin(); it != _translations.keyEnd(); it = std::next(it)) {
|
||||
clearCache(*it);
|
||||
}
|
||||
_translations.clear();
|
||||
}
|
||||
|
||||
Locales *Locales::instance() {
|
||||
static auto instance = new Locales();
|
||||
return instance;
|
||||
}
|
||||
|
||||
void Locales::removeOldTranslation(const QLocale &locale) {
|
||||
for (const auto & tr :std::as_const(_translations[locale])) {
|
||||
QCoreApplication::removeTranslator(tr);
|
||||
}
|
||||
}
|
||||
|
||||
void Locales::addLocationPrivate(const QString &location) {
|
||||
_locations += location;
|
||||
}
|
||||
|
||||
const QLocale &Locales::currentLocatePrivate() const {
|
||||
return _currentLocate;
|
||||
|
||||
}
|
||||
void Locales::addLocation(const QString &location) {
|
||||
auto obj = instance();
|
||||
obj->addLocationPrivate(location);
|
||||
}
|
||||
|
||||
Locales::~Locales() {
|
||||
clearCache();
|
||||
}
|
||||
|
117
locales.h
117
locales.h
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2020 QuasarApp.
|
||||
* Copyright (C) 2018-2025 QuasarApp.
|
||||
* Distributed under the lgplv3 software license, see the accompanying
|
||||
* Everyone is permitted to copy and distribute verbatim copies
|
||||
* of this license document, but changing it is not allowed.
|
||||
@ -11,6 +11,11 @@
|
||||
|
||||
#include "quasarapp_global.h"
|
||||
|
||||
#include <QLocale>
|
||||
#include <QSet>
|
||||
#include <QString>
|
||||
#include <QDir>
|
||||
|
||||
class QCoreApplication;
|
||||
class QTranslator;
|
||||
|
||||
@ -18,21 +23,113 @@ namespace QuasarAppUtils {
|
||||
|
||||
/**
|
||||
* @brief The Locales class for parese local files
|
||||
* **Example :**
|
||||
* @code{cpp}
|
||||
* QuasarAppUtils::Locales::init();
|
||||
* @endcode
|
||||
*
|
||||
* @note If you want to add you own location of the qm files then add this into seccond arguments of the Locales::init method.
|
||||
*
|
||||
* @code{cpp}
|
||||
* QuasarAppUtils::Locales::init(QLocale::system(), "myPath");
|
||||
* @endcode
|
||||
*
|
||||
* @note All translations qm files should be named with lower case example : en.qm
|
||||
*/
|
||||
class QUASARAPPSHARED_EXPORT Locales
|
||||
class QUASARAPPSHARED_EXPORT Locales : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
Locales() = delete;
|
||||
|
||||
/**
|
||||
* @brief initLocale init translation of applictaion
|
||||
* @param prefix - path to folder with qm files. example (/home)
|
||||
* @param locale - string value of locale. example (en)
|
||||
* @param app - app core of qt
|
||||
* @param translator - translator core of qt
|
||||
* @return return true if locale funded
|
||||
* @brief setLocale This method sets locale for application and loaded all translations for this locale.
|
||||
* @param locale This is new locale.
|
||||
* @return true if the all ltranstations files loaded successful.
|
||||
*/
|
||||
static bool initLocale(const QString& prefix ,const QString &locale, QCoreApplication* app, QTranslator *translator);
|
||||
static bool setLocale(const QLocale &locale, bool force = false);
|
||||
|
||||
/**
|
||||
* @brief init This method initialize translations of applictaion.
|
||||
* @param locales This is list of locales that you want to locad to application cache. See info about QLocale.
|
||||
* @param location Path to folder with qm files. example (:/tr).
|
||||
* @return return true if locale set for application.
|
||||
*/
|
||||
static bool init(const QList<QLocale> & locales,
|
||||
const QSet<QString> & location = {});
|
||||
|
||||
/**
|
||||
* @brief init This method initialize translation of applictaion.
|
||||
* @param locale See info about QLocale.
|
||||
* @param location Path to folder with qm files. example (:/tr).
|
||||
* @return return true if locale set for application.
|
||||
*/
|
||||
static bool init(const QLocale &locale = QLocale::system(),
|
||||
const QSet<QString> & location = {});
|
||||
|
||||
/**
|
||||
* @brief addLocation This method add location for qm files. Use This method if you create a own library with translations supports.
|
||||
* @param location This is a new location of the qm files.
|
||||
*/
|
||||
static void addLocation(const QString& location);
|
||||
|
||||
/**
|
||||
* @brief instance This method return pointer to the Locales service.
|
||||
* @return return pointer to the Locales static object
|
||||
*/
|
||||
static Locales *instance();
|
||||
|
||||
/**
|
||||
* @brief currentLocate This method return current locate of applicatuon.
|
||||
* @return current or last sets locate of applciation.
|
||||
*/
|
||||
static const QLocale ¤tLocate();
|
||||
|
||||
/**
|
||||
* @brief tr This method will translate single string to choosed language.
|
||||
* @param source This is source string of translations.
|
||||
* @param locale This is choosed language.
|
||||
* @return translated string value.
|
||||
* @note use instant QOBject::tr, This method must be read by the lupdate utility
|
||||
*/
|
||||
static QString tr(const char *source, const QLocale& locale);
|
||||
|
||||
signals:
|
||||
/**
|
||||
* @brief sigTranslationChanged Emited when set new locale for application.
|
||||
*/
|
||||
void sigTranslationChanged();
|
||||
|
||||
private:
|
||||
Locales() = default;
|
||||
~Locales();
|
||||
|
||||
bool setLocalePrivate(const QLocale &locale = QLocale::system(), bool force = false, bool install = true);
|
||||
bool initPrivate(const QLocale &locale = QLocale::system(),
|
||||
const QSet<QString> &location = {});
|
||||
|
||||
bool initPrivate(const QList<QLocale> &locales,
|
||||
const QSet<QString> &location = {});
|
||||
|
||||
void clearCache(const QLocale& locale);
|
||||
void clearCache();
|
||||
|
||||
void removeOldTranslation(const QLocale& locale);
|
||||
|
||||
void addLocationPrivate(const QString& location);
|
||||
|
||||
const QLocale ¤tLocatePrivate() const;
|
||||
|
||||
bool findQm(QString localePrefix,
|
||||
QList<QTranslator *> &result);
|
||||
bool findQmPrivate(const QString &prefix,
|
||||
QList<QTranslator *> &qmFiles);
|
||||
void installTranslations(QList<QTranslator *> &qmFiles);
|
||||
QString translatePrivate(const char *source, const QLocale& locale);
|
||||
|
||||
|
||||
QLocale _currentLocate;
|
||||
QSet<QString> _locations;
|
||||
QHash<QLocale, QList<QTranslator *>> _translations;
|
||||
|
||||
};
|
||||
}
|
||||
|
90
optiondata.cpp
Normal file
90
optiondata.cpp
Normal file
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright (C) 2021-2025 QuasarApp.
|
||||
* Distributed under the lgplv3 software license, see the accompanying
|
||||
* Everyone is permitted to copy and distribute verbatim copies
|
||||
* of this license document, but changing it is not allowed.
|
||||
*/
|
||||
|
||||
|
||||
#include "optiondata.h"
|
||||
|
||||
namespace QuasarAppUtils{
|
||||
|
||||
OptionData::OptionData(const QStringList& name,
|
||||
const QString& arguments,
|
||||
const QString& description,
|
||||
const QString& example,
|
||||
const QString& depricatedMsg,
|
||||
bool removed) {
|
||||
|
||||
setNames(name);
|
||||
setArguments(arguments);
|
||||
setDescription(description);
|
||||
setExample(example);
|
||||
setDepricatedMsg(depricatedMsg);
|
||||
_removed = removed;
|
||||
}
|
||||
|
||||
const QStringList &OptionData::names() const {
|
||||
return _name;
|
||||
}
|
||||
|
||||
void OptionData::setNames(const QStringList &newName) {
|
||||
_name = newName;
|
||||
}
|
||||
|
||||
const QString &OptionData::description() const {
|
||||
return _description;
|
||||
}
|
||||
|
||||
void OptionData::setDescription(const QString &newDescription) {
|
||||
_description = newDescription;
|
||||
}
|
||||
|
||||
const QString &OptionData::example() const {
|
||||
return _example;
|
||||
}
|
||||
|
||||
void OptionData::setExample(const QString &newExample) {
|
||||
_example = newExample;
|
||||
}
|
||||
|
||||
const QString &OptionData::arguments() const {
|
||||
return _arguments;
|
||||
}
|
||||
|
||||
void OptionData::setArguments(const QString &newArguments) {
|
||||
_arguments = newArguments;
|
||||
}
|
||||
|
||||
const QString &OptionData::depricatedMsg() const {
|
||||
return _depricatedMsg;
|
||||
}
|
||||
|
||||
void OptionData::setDepricatedMsg(const QString &newDepricatedMsg) {
|
||||
_depricatedMsg = newDepricatedMsg;
|
||||
}
|
||||
|
||||
bool OptionData::isRemoved() const {
|
||||
return _removed;
|
||||
}
|
||||
|
||||
bool OptionData::isDepricated() const {
|
||||
return depricatedMsg().size();
|
||||
}
|
||||
|
||||
Help::Options OptionData::toHelp() const {
|
||||
QString left = names().join(" / ") + " " + arguments();
|
||||
|
||||
QString right = description();
|
||||
if (example().size()) {
|
||||
right += " Example: " + example();
|
||||
}
|
||||
|
||||
return {{left, {right}}};
|
||||
}
|
||||
|
||||
bool OptionData::isValid() const {
|
||||
return names().size();
|
||||
}
|
||||
}
|
152
optiondata.h
Normal file
152
optiondata.h
Normal file
@ -0,0 +1,152 @@
|
||||
/*
|
||||
* Copyright (C) 2021-2025 QuasarApp.
|
||||
* Distributed under the lgplv3 software license, see the accompanying
|
||||
* Everyone is permitted to copy and distribute verbatim copies
|
||||
* of this license document, but changing it is not allowed.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef OPTIONDATA_H
|
||||
#define OPTIONDATA_H
|
||||
|
||||
#include "quasarapp_global.h"
|
||||
#include "helpdata.h"
|
||||
|
||||
namespace QuasarAppUtils{
|
||||
|
||||
/**
|
||||
* @brief The OptionData class contains information about one option.
|
||||
*/
|
||||
class QUASARAPPSHARED_EXPORT OptionData
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* @brief OptionData This is main constructor
|
||||
* @param names This is names list of the option. It is a required argument and cannot be empty.
|
||||
* @param arguments This is input arguments of this option or help meesage about arguments.
|
||||
* @param description This is description message of this option.
|
||||
* @param example This is example of use string.
|
||||
* @param depricatedMsg This is a message that will be printed as a warning if user will use this option. If you set this argument to empty value then warning message will be ignored and option not be marked asa a depricated. An option will be marked as a depricated when this arguments will not equal empty string.
|
||||
* @param removed This option show depricatedMsg as a error and force the parseParams method return false. This option will be ignored if the depricatedMsg will be empty.
|
||||
*/
|
||||
OptionData(const QStringList& names,
|
||||
const QString& arguments = "",
|
||||
const QString& description = "",
|
||||
const QString& example = "",
|
||||
const QString& depricatedMsg = "",
|
||||
bool removed = false);
|
||||
|
||||
/**
|
||||
* @brief name This is name of the option. It is a required argument and cannot be empty.
|
||||
* @return return name of this option.
|
||||
*/
|
||||
const QStringList &names() const;
|
||||
|
||||
/**
|
||||
* @brief description This is description message of this option.
|
||||
* @return return description of this option.
|
||||
*/
|
||||
const QString &description() const;
|
||||
|
||||
/**
|
||||
* @brief example This is example of use string.
|
||||
* @return return example if use of this option.
|
||||
*/
|
||||
const QString &example() const;
|
||||
|
||||
/**
|
||||
* @brief arguments This is input arguments of this option or help meesage about arguments.
|
||||
* @return return arguments of this option.
|
||||
*/
|
||||
const QString &arguments() const;
|
||||
|
||||
/**
|
||||
* @brief depricatedWarning This is a message that will be printed as a warning if user will use this option. If you set this argument to empty value then warning message will be ignored and option not be marked asa a depricated. An option will be marked as a depricated when this arguments will not equal empty string.
|
||||
* @note if this value is empty the option are not depricated.
|
||||
* @return warning meessage of the depricated options.
|
||||
*/
|
||||
const QString &depricatedMsg() const;
|
||||
|
||||
/**
|
||||
* @brief toHelp This method convert this option into help line.
|
||||
* The help line have next structure :
|
||||
*
|
||||
* Key: {name [arguments]}
|
||||
* Value: {description examples}
|
||||
* @return The Help::Options set with one line.
|
||||
*/
|
||||
Help::Options toHelp() const;
|
||||
|
||||
/**
|
||||
* @brief isValid This method return true if the option is valid. If option do not contain a name then it is invalid.
|
||||
* @return true if the option valid else false.
|
||||
*/
|
||||
bool isValid() const;
|
||||
|
||||
/**
|
||||
* @brief isRemoved This method return true if the option is removed.
|
||||
* @return true if option is removed else false.
|
||||
*/
|
||||
bool isRemoved() const;
|
||||
|
||||
/**
|
||||
* @brief isDepricated This method return true if this option is depricated.
|
||||
* @return true if options is depricated else false
|
||||
*/
|
||||
bool isDepricated() const;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* @brief setNames This method sets new value of the option name.
|
||||
* @param newNames This is a new value of the options name.
|
||||
* @note see the OptionData::name method.
|
||||
*/
|
||||
void setNames(const QStringList &newNames);
|
||||
|
||||
/**
|
||||
* @brief setDescription This method sets new description of this options.
|
||||
* @param newDescription This is new value of optons description
|
||||
* @note See the OptionData::description method.
|
||||
|
||||
*/
|
||||
void setDescription(const QString &newDescription);
|
||||
|
||||
/**
|
||||
* @brief setExample This method sets a new example value of this option
|
||||
* @param newExample This is a new value of the options example.
|
||||
* @note See the OptionData::example method.
|
||||
|
||||
*/
|
||||
void setExample(const QString &newExample);
|
||||
|
||||
/**
|
||||
* @brief setArguments This method sets new value of the options arguments
|
||||
* @param newArguments new value of the options arguments
|
||||
* @note See the OptionData::arguments method.
|
||||
|
||||
*/
|
||||
void setArguments(const QString &newArguments);
|
||||
|
||||
/**
|
||||
* @brief setDepricatedMsg This method sets new value of the depricated warnning message of this option.
|
||||
* @param newDepricatedMsg This is new value of the depricated message.
|
||||
* @note See the OptionData::depricatedMsg method.
|
||||
*/
|
||||
void setDepricatedMsg(const QString &newDepricatedMsg);
|
||||
|
||||
private:
|
||||
QStringList _name;
|
||||
QString _description;
|
||||
QString _example;
|
||||
QString _arguments;
|
||||
QString _depricatedMsg;
|
||||
bool _removed;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief OptionsList is Hash map of the OptionData items. Where the key it is group name and value it is option data.
|
||||
*/
|
||||
typedef QMultiHash<QString, OptionData> OptionsDataList;
|
||||
}
|
||||
#endif // OPTIONDATA_H
|
423
params.cpp
423
params.cpp
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2020 QuasarApp.
|
||||
* Copyright (C) 2018-2025 QuasarApp.
|
||||
* Distributed under the lgplv3 software license, see the accompanying
|
||||
* Everyone is permitted to copy and distribute verbatim copies
|
||||
* of this license document, but changing it is not allowed.
|
||||
@ -9,188 +9,178 @@
|
||||
#include <QVariantMap>
|
||||
#include <QDebug>
|
||||
#include <QFileInfo>
|
||||
#include <iostream>
|
||||
#include <QDateTime>
|
||||
#include <QCoreApplication>
|
||||
#include "qaglobalutils.h"
|
||||
#include <QtLogging>
|
||||
|
||||
#ifdef Q_OS_DARWIN
|
||||
#include <mach-o/dyld.h>
|
||||
#endif
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
#include "windows.h"
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#include <limits.h>
|
||||
#endif
|
||||
|
||||
using namespace QuasarAppUtils;
|
||||
QMap<QString, QString> Params::params = QMap<QString, QString>();
|
||||
QString Params::appPath = "";
|
||||
QString Params::appName = "";
|
||||
Help::Section Params::userHelp = {};
|
||||
OptionsDataList Params::inputOptions = {};
|
||||
|
||||
static QVariantMap params = QVariantMap();
|
||||
|
||||
bool Params::isEndable(const QString& key) {
|
||||
return params.contains(key);
|
||||
}
|
||||
|
||||
void Params::verboseLog(const QString &log, VerboseLvl vLvl) {
|
||||
void Params::log(const QString &log, VerboseLvl vLvl) {
|
||||
|
||||
writeLoginFile(log, vLvl);
|
||||
auto lvl = getVerboseLvl();
|
||||
if (vLvl <= lvl) {
|
||||
|
||||
if (isEndable("verbose")) {
|
||||
switch (vLvl) {
|
||||
|
||||
auto lvl = static_cast<VerboseLvl>(getArg("verbose").toInt());
|
||||
case VerboseLvl::Error:
|
||||
qCritical().noquote() << log;
|
||||
break;
|
||||
|
||||
if (vLvl <= lvl) {
|
||||
case VerboseLvl::Warning: {
|
||||
qWarning().noquote() << log;
|
||||
break;
|
||||
}
|
||||
case VerboseLvl::Debug: {
|
||||
qDebug().noquote() << log;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (vLvl) {
|
||||
case VerboseLvl::Info:
|
||||
default: {
|
||||
qInfo().noquote() << log;
|
||||
break;
|
||||
}
|
||||
|
||||
case VerboseLvl::Error: {
|
||||
qCritical() << lvlToString(vLvl) + ": " + log;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
VerboseLvl Params::getVerboseLvl() {
|
||||
return static_cast<VerboseLvl>(getArg("verbose", DEFAULT_VERBOSE_LVL).toInt());
|
||||
}
|
||||
|
||||
bool Params::isDebug() {
|
||||
return getVerboseLvl() >= VerboseLvl::Debug;
|
||||
}
|
||||
|
||||
bool Params::isDebugBuild() {
|
||||
#ifdef QT_DEBUG
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
void Params::showHelp() {
|
||||
|
||||
if (inputOptions.size() > 1) {
|
||||
showHelpForInputOptions();
|
||||
} else {
|
||||
Help::print(userHelp);
|
||||
}
|
||||
}
|
||||
|
||||
void Params::showHelpForInputOptions() {
|
||||
Help::print(getHelpOfInputOptions());
|
||||
}
|
||||
|
||||
Help::Section Params::getHelpOfInputOptions() {
|
||||
|
||||
if (inputOptions.size() <= 1 ) {
|
||||
return {};
|
||||
}
|
||||
|
||||
Help::Options help;
|
||||
for (const auto &optionData: std::as_const(inputOptions) ) {
|
||||
help.unite(optionData.toHelp());
|
||||
}
|
||||
|
||||
return Help::Section{{"Information about using options", help}};
|
||||
}
|
||||
|
||||
const Help::Section &Params::getHelp() {
|
||||
return userHelp;
|
||||
}
|
||||
|
||||
const QMap<QString, QString>& Params::getUserParamsMap() {
|
||||
return params;
|
||||
}
|
||||
|
||||
void Params::clearParsedData() {
|
||||
params.clear();
|
||||
appPath = "";
|
||||
appName = "";
|
||||
}
|
||||
|
||||
QString Params::getCurrentExecutable() {
|
||||
return getCurrentExecutableDir() + "/" + appName;
|
||||
}
|
||||
|
||||
QString Params::getCurrentExecutableDir() {
|
||||
return appPath;
|
||||
}
|
||||
|
||||
OptionsDataList Params::availableArguments() {
|
||||
return OptionsDataList{
|
||||
{
|
||||
"Base Options",
|
||||
OptionData{
|
||||
{"-verbose"}, "(level 1 - 3)", "Shows debug log"
|
||||
}
|
||||
|
||||
case VerboseLvl::Warning: {
|
||||
qWarning() << lvlToString(vLvl) + ": " + log;
|
||||
break;
|
||||
}
|
||||
|
||||
case VerboseLvl::Info: {
|
||||
qInfo() << lvlToString(vLvl) + ": " + log;
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
qDebug() << lvlToString(vLvl) + ": " + log;
|
||||
break;
|
||||
}
|
||||
},
|
||||
{
|
||||
"Base Options",
|
||||
OptionData{
|
||||
{"-fileLog"}, "(path to file)", "Sets path of log file. Default it is path to executable file with suffix '.log'"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QStringList Params::getparamsHelp() {
|
||||
return
|
||||
{
|
||||
{""},
|
||||
{ " -verbose (level 1 - 3) : Shows debug log"},
|
||||
{ " -fileLog (path to file) : Sets path of log file"},
|
||||
{ " : Default it is path to executable file"},
|
||||
{ " : with suffix '.log' "},
|
||||
{ " noWriteInFileLog : Disables loging into file"},
|
||||
{ ""}
|
||||
};
|
||||
}
|
||||
|
||||
void Params::showHelp(const QStringList &help) {
|
||||
for (const QString& line : help) {
|
||||
std::cout << line.toStdString() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
int Params::size() {
|
||||
return params.size();
|
||||
}
|
||||
|
||||
int Params::customParamasSize() {
|
||||
return size() - 2;
|
||||
}
|
||||
bool Params::optionsForEach(const QStringList ¶msArray,
|
||||
const OptionsDataList& availableOptions) {
|
||||
|
||||
QString Params::timeString() {
|
||||
return QDateTime::currentDateTime().toString();
|
||||
}
|
||||
for (int i = 0 ; i < paramsArray.size(); ++i) {
|
||||
|
||||
QString Params::lvlToString(VerboseLvl vLvl) {
|
||||
switch (vLvl) {
|
||||
QStringList virtualOptionsList = paramsArray[i].split('=');
|
||||
|
||||
case VerboseLvl::Error: {
|
||||
return "Error";
|
||||
}
|
||||
|
||||
case VerboseLvl::Warning: {
|
||||
return "Warning";
|
||||
}
|
||||
|
||||
case VerboseLvl::Info: {
|
||||
return "Info";
|
||||
}
|
||||
|
||||
case VerboseLvl::Debug: {
|
||||
return "Verbose log";
|
||||
}
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
bool Params::writeLoginFile(const QString &log, VerboseLvl vLvl) {
|
||||
if (!isEndable("noWriteInFileLog")) {
|
||||
|
||||
QString path = getStrArg("appPath") + "/" + getStrArg("appName") + ".log";
|
||||
|
||||
if (isEndable("fileLog")) {
|
||||
QString path = getStrArg("fileLog");
|
||||
if (virtualOptionsList.size() > 1) {
|
||||
return optionsForEach(virtualOptionsList, availableOptions);
|
||||
}
|
||||
|
||||
QFile logFile(path);
|
||||
|
||||
if (logFile.open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Text)) {
|
||||
|
||||
QTextStream stream(&logFile);
|
||||
stream << timeString() <<"| " << lvlToString(vLvl) + ": " + log << endl;
|
||||
logFile.close();
|
||||
} else {
|
||||
auto optionData = availableOptions.value(paramsArray[i], {{}});
|
||||
if (!checkOption(optionData, paramsArray[i])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
inputOptions.insert(paramsArray[i], optionData);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Params::parseParams(int argc, const char *argv[]) {
|
||||
|
||||
QStringList params;
|
||||
for (int i = 1; i < argc; i++) {
|
||||
params.push_back(argv[i]);
|
||||
}
|
||||
|
||||
return parseParams(params);
|
||||
}
|
||||
|
||||
bool Params::parseParams(int argc, char *argv[]) {
|
||||
return parseParams(argc, const_cast<const char**>(argv));
|
||||
}
|
||||
|
||||
bool Params::parseParams(const QStringList ¶msArray) {
|
||||
params.clear();
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
char buffer[MAX_PATH];
|
||||
memset(buffer, 0, sizeof buffer);
|
||||
|
||||
GetModuleFileNameA(nullptr, buffer, MAX_PATH);
|
||||
params ["appPath"] = QFileInfo(buffer).absolutePath();
|
||||
params ["appName"] = QFileInfo(buffer).fileName();
|
||||
|
||||
#else
|
||||
char path[2048];
|
||||
memset(path, 0, sizeof path);
|
||||
|
||||
if (readlink("/proc/self/exe", path, 2048) < 0) {
|
||||
qWarning() << "parseParams can't get self path!" ;
|
||||
return false;
|
||||
}
|
||||
params ["appPath"] = QFileInfo(path).absolutePath();
|
||||
params ["appName"] = QFileInfo(path).fileName();
|
||||
|
||||
#endif
|
||||
|
||||
if (!getStrArg("appPath").size()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0 ; i < paramsArray.size(); ++i) {
|
||||
if (paramsArray[i][0] == '-') {
|
||||
|
||||
if (i < (paramsArray.size() - 1) && paramsArray[i + 1][0] != '-') {
|
||||
params[paramsArray[i].mid(1)] = paramsArray[i + 1];
|
||||
i++;
|
||||
} else {
|
||||
qWarning() << "Missing argument for " + paramsArray[i] ;
|
||||
qCritical() << "Missing argument for " + paramsArray[i];
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
params[paramsArray[i]] = "";
|
||||
@ -200,15 +190,166 @@ bool Params::parseParams(const QStringList ¶msArray) {
|
||||
return true;
|
||||
}
|
||||
|
||||
QString Params::getStrArg(const QString& key, const QString &def) {
|
||||
return params.value(key, def).toString();
|
||||
bool Params::parseParams(const int argc, const char *argv[], const OptionsDataList& options) {
|
||||
|
||||
QStringList params;
|
||||
for (int i = 1; i < argc; i++) {
|
||||
params.push_back(argv[i]);
|
||||
}
|
||||
|
||||
return parseParams(params, options);
|
||||
}
|
||||
|
||||
QVariant Params::getArg(const QString& key,const QVariant& def) {
|
||||
bool Params::parseParams(int argc, char *argv[], const OptionsDataList& options) {
|
||||
return parseParams(argc, const_cast<const char**>(argv), options);
|
||||
}
|
||||
|
||||
bool Params::parseParams(const QStringList ¶msArray, const OptionsDataList &options) {
|
||||
params.clear();
|
||||
OptionsDataList availableOptions;
|
||||
|
||||
parseAvailableOptions(OptionsDataList{}.unite(options).unite(availableArguments()),
|
||||
&availableOptions,
|
||||
&userHelp);
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
char buffer[MAX_PATH];
|
||||
memset(buffer, 0, sizeof buffer);
|
||||
|
||||
GetModuleFileNameA(nullptr, buffer, MAX_PATH);
|
||||
appPath = QFileInfo(buffer).absolutePath();
|
||||
appName = QFileInfo(buffer).fileName();
|
||||
#endif
|
||||
|
||||
#ifdef Q_OS_LINUX
|
||||
char path[2048];
|
||||
memset(path, 0, sizeof path);
|
||||
|
||||
if (readlink("/proc/self/exe", path, 2048) < 0) {
|
||||
qCritical() << "parseParams can't get self path!";
|
||||
return false;
|
||||
}
|
||||
appPath = QFileInfo(path).absolutePath();
|
||||
appName = QFileInfo(path).fileName();
|
||||
|
||||
#endif
|
||||
#ifdef Q_OS_DARWIN
|
||||
uint32_t size = 0;
|
||||
_NSGetExecutablePath(nullptr, &size); // request to buffer size
|
||||
std::vector<char> buffer(size);
|
||||
if (_NSGetExecutablePath(buffer.data(), &size) == 0) {
|
||||
appPath = QString::fromUtf8(buffer.data());
|
||||
} else {
|
||||
appPath = QString();
|
||||
}
|
||||
|
||||
appName = QCoreApplication::applicationName();
|
||||
#endif
|
||||
|
||||
if (!appPath.size()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!optionsForEach(paramsArray, availableOptions)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
printWorkingOptions();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Params::printWorkingOptions() {
|
||||
qDebug() << "--- Working options table start ---";
|
||||
|
||||
QMap<QString, QString>::const_iterator iter = params.constBegin();
|
||||
while (iter != params.constEnd()) {
|
||||
|
||||
QString row = QString{"Option[%0]"}.arg(iter.key());
|
||||
|
||||
QString value = iter.value();
|
||||
if (!value.isEmpty()) {
|
||||
row += QString{": %1"}.arg(value);
|
||||
}
|
||||
|
||||
qDebug() << row;
|
||||
|
||||
++iter;
|
||||
}
|
||||
|
||||
qDebug() << "--- Working options table end ---";
|
||||
}
|
||||
|
||||
bool Params::checkOption(const OptionData& optionData, const QString& rawOptionName) {
|
||||
|
||||
#ifndef QA_ALLOW_NOT_SUPPORTED_OPTIONS
|
||||
if (!optionData.isValid()) {
|
||||
|
||||
qCritical() << QString("The '%0' option not exists!"
|
||||
" You use wrong option name,"
|
||||
" please check the help before run your commnad.").
|
||||
arg(rawOptionName);
|
||||
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
Q_UNUSED(rawOptionName);
|
||||
#endif
|
||||
|
||||
if (optionData.isDepricated()) {
|
||||
|
||||
|
||||
|
||||
if (optionData.isRemoved()) {
|
||||
qCritical() << optionData.depricatedMsg();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
qWarning() << QString("The %0 option(s) marked as deprecated! "
|
||||
"And most likely will be removed in next release.").
|
||||
arg(optionData.names().join("/"));
|
||||
|
||||
qWarning() << QString("Option message: %0").arg(optionData.depricatedMsg());
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Params::parseAvailableOptions(const OptionsDataList &availableOptionsListIn,
|
||||
OptionsDataList *availableOptionsListOut,
|
||||
Help::Section *helpOut) {
|
||||
|
||||
if (!(availableOptionsListOut && helpOut))
|
||||
return;
|
||||
|
||||
helpOut->clear();
|
||||
|
||||
QHash<QString, Help::Options> options;
|
||||
for (auto it = availableOptionsListIn.begin(); it != availableOptionsListIn.end(); ++it) {
|
||||
|
||||
if (availableOptionsListOut) {
|
||||
for (const auto &name : std::as_const(it.value().names())) {
|
||||
availableOptionsListOut->insert(name, it.value());
|
||||
}
|
||||
}
|
||||
|
||||
if (helpOut) {
|
||||
options[it.key()].unite(it.value().toHelp());
|
||||
}
|
||||
}
|
||||
|
||||
for (auto it = options.begin(); it != options.end(); ++it) {
|
||||
helpOut->insert(it.key(), it.value());
|
||||
}
|
||||
}
|
||||
|
||||
QString Params::getArg(const QString& key,const QString& def) {
|
||||
return params.value(key, def);
|
||||
}
|
||||
|
||||
void Params::setArg(const QString &key, const QVariant &val) {
|
||||
void Params::setArg(const QString &key, const QString &val) {
|
||||
params.insert(key, val);
|
||||
}
|
||||
|
||||
|
252
params.h
252
params.h
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2020 QuasarApp.
|
||||
* Copyright (C) 2018-2025 QuasarApp.
|
||||
* Distributed under the lgplv3 software license, see the accompanying
|
||||
* Everyone is permitted to copy and distribute verbatim copies
|
||||
* of this license document, but changing it is not allowed.
|
||||
@ -8,113 +8,253 @@
|
||||
#ifndef PARAMS_H
|
||||
#define PARAMS_H
|
||||
|
||||
#include <QMap>
|
||||
#include <QVariant>
|
||||
#include "quasarapp_global.h"
|
||||
|
||||
#include "helpdata.h"
|
||||
#include "optiondata.h"
|
||||
|
||||
namespace QuasarAppUtils {
|
||||
|
||||
|
||||
/**
|
||||
* @brief The Params class for parese app params
|
||||
* @brief The VerboseLvl enum uses for sets log level.
|
||||
*/
|
||||
|
||||
enum VerboseLvl {
|
||||
Debug = 0x0,
|
||||
Error = 0x1,
|
||||
Warning = 0x2,
|
||||
Info = 0x3,
|
||||
};
|
||||
/// Error message. This logs will marked as a **Error** and printing if the verbose lvl >= 0
|
||||
Error = 0x0,
|
||||
/// Warning message. This logs will marked as a **Warning** and printing if the verbose lvl >= 1
|
||||
Warning = 0x1,
|
||||
/// General information. This logs will marked as a **Info** and and printing if the verbose lvl >= 2.
|
||||
Info = 0x2,
|
||||
/// Debug message. This logs will marked as a **Debug** and printing if the verbose lvl >= 3
|
||||
Debug = 0x3,
|
||||
|
||||
};
|
||||
#ifdef QA_DISABLE_LOG
|
||||
#define DEFAULT_VERBOSE_LVL "0"
|
||||
#else
|
||||
#ifdef QT_DEBUG
|
||||
#define DEFAULT_VERBOSE_LVL "3"
|
||||
#else
|
||||
#define DEFAULT_VERBOSE_LVL "2"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief The Params class Contains fonctions for working with input arguments and logs.
|
||||
* This Class support next comandline arguments.
|
||||
* * **-verbose** (level 1 - 3) Shows debug log
|
||||
* * **-fileLog** (path to file) Sets path of log file. Default it is path to executable file with suffix '.log'
|
||||
*
|
||||
* ### Usage
|
||||
*
|
||||
* ```cpp
|
||||
#include <quasarapp.h>
|
||||
|
||||
if (!QuasarAppUtils::Params::parseParams(argc, argv)) {
|
||||
QuasarAppUtils::Params::log("Warning message", QuasarAppUtils::Warning);
|
||||
QuasarAppUtils::Params::showHelp();
|
||||
exit(0);
|
||||
}
|
||||
```
|
||||
*/
|
||||
class QUASARAPPSHARED_EXPORT Params
|
||||
{
|
||||
private:
|
||||
static QString timeString();
|
||||
static QString lvlToString(VerboseLvl vLvl);
|
||||
static bool writeLoginFile(const QString& log, VerboseLvl vLvl = VerboseLvl::Debug);
|
||||
public:
|
||||
Params() = delete;
|
||||
|
||||
/**
|
||||
* @brief parseParams - parase input data of started application
|
||||
* @param argc - count of arguments
|
||||
* @param argv - arrat of arguments
|
||||
* @return true if all arguments read else false
|
||||
* @brief parseParams Parse input data of started application.
|
||||
* @param argc Count of arguments.
|
||||
* @param argv Array of arguments.
|
||||
* @param options This is list of the available options for parse. See the OptionData class for more inforamtion.
|
||||
* If you skip thi argument then QuasarAppLib will not check input options.
|
||||
* @return true if all arguments read successful else false.
|
||||
*/
|
||||
static bool parseParams(int argc, const char *argv[]);
|
||||
static bool parseParams(int argc, char *argv[]);
|
||||
static bool parseParams(const int argc, const char *argv[], const OptionsDataList& options = {});
|
||||
|
||||
/**
|
||||
* @brief parseParams - parase input data of started application
|
||||
* @param params - arguments
|
||||
* @return true if all arguments read else false
|
||||
* @brief parseParams Parse input data of started application.
|
||||
* @param argc Count of arguments.
|
||||
* @param argv Array of arguments.
|
||||
* @param options This is list of the available options for parse. See the OptionData class for more inforamtion.
|
||||
* If you skip thi argument then QuasarAppLib will not check input options.
|
||||
* @return true if all arguments read successful else false.
|
||||
*/
|
||||
static bool parseParams(const QStringList& paramsArray);
|
||||
static bool parseParams(int argc, char *argv[], const OptionsDataList& options = {});
|
||||
|
||||
/**
|
||||
* @brief getStrArg - get string value of key
|
||||
* @param key
|
||||
* @param def - default value
|
||||
* @return string value of argument
|
||||
* @brief parseParams Parse input data of started application.
|
||||
* @param paramsArray Arguments.
|
||||
* @param options This is list of the available options for parse. See the OptionData class for more inforamtion.
|
||||
* If you skip thi argument then QuasarAppLib will not check input options.
|
||||
* @return true if all arguments read successful else false.
|
||||
*/
|
||||
static QString getStrArg(const QString& key, const QString& def = "");
|
||||
static bool parseParams(const QStringList& paramsArray, const OptionsDataList& options = {});
|
||||
|
||||
/**
|
||||
* @brief getArg - get string value of key
|
||||
* @param key
|
||||
* @param def - default value
|
||||
* @return string value of argument
|
||||
* @brief getArg return string value of a @a key if key is exits else return a @a def value.
|
||||
* If a @a def value not defined retunr empty string.
|
||||
* @param key This is key of a console argument.
|
||||
* @param def This is Default value. If key not exits This function will return a default value.
|
||||
* @return a string value of argument.
|
||||
*/
|
||||
static QVariant getArg(const QString& key, const QVariant &def = {});
|
||||
static QString getArg(const QString& key, const QString &def = {});
|
||||
|
||||
/**
|
||||
* @brief setArg - set value of key
|
||||
* @param key
|
||||
* @brief setArg sets a new value of a @a key.
|
||||
* @param key This is a name of sets option.
|
||||
* @param val This is a new value of the @a key.
|
||||
*/
|
||||
static void setArg(const QString& key, const QVariant& val);
|
||||
static void setArg(const QString& key, const QString& val);
|
||||
|
||||
/**
|
||||
* @brief setArg - set boolean value of key
|
||||
* @param key
|
||||
* @param enable - new value of key
|
||||
* @brief setArg This method sets boolean value of key.
|
||||
* @param key This is name of the console option.
|
||||
* @param enable New value of key.
|
||||
* @note For check is enable @a key argument use the Params::isEndable method.
|
||||
*/
|
||||
static void setEnable(const QString& key, bool enable);
|
||||
|
||||
/**
|
||||
* @brief isEndable - check if enable argument of key
|
||||
* @param key
|
||||
* @return true if argument enabled
|
||||
* @brief isEndable This method check if enable a @a key argument.
|
||||
* @param key This is name of the validate arguments
|
||||
* @return true if argument enabled.
|
||||
*/
|
||||
static bool isEndable(const QString& key);
|
||||
|
||||
/**
|
||||
* @brief verboseLog - print text on console if the flag "vergose" is enabled
|
||||
* @param log - printed text
|
||||
* @brief log This method print @a log text on console.
|
||||
* @param log This is printed text message.
|
||||
* @param vLvl This is verbose level of message, for get more information see the QuasarAppUtils::VerboseLvl enum.
|
||||
* @note All messages will be printed according to the current verbose setting.
|
||||
* @note The verbose level sets by verbose option on console.
|
||||
*/
|
||||
static void verboseLog(const QString& log, VerboseLvl vLvl = VerboseLvl::Debug);
|
||||
[[deprecated("Use QALogger and qt debug functions(qDebug, qInfo, qError...)")]]
|
||||
static void log(const QString& log, VerboseLvl vLvl = VerboseLvl::Debug);
|
||||
|
||||
/**
|
||||
* @brief getparamsHelp
|
||||
* @return help string of default params
|
||||
* @brief getVerboseLvl This method return the verbose log level.
|
||||
* @return verbose log lvl.
|
||||
*/
|
||||
static QStringList getparamsHelp();
|
||||
static VerboseLvl getVerboseLvl();
|
||||
|
||||
/**
|
||||
* @brief showHelp - show all strings of help
|
||||
* @param help
|
||||
* @brief isDebug This method return true if the application verbose level >= VerboseLvl::Debug.
|
||||
* @return true if a verbose level >= VerboseLvl::Debug
|
||||
*/
|
||||
static void showHelp(const QStringList& help);
|
||||
static bool isDebug();
|
||||
|
||||
/**
|
||||
* @brief size
|
||||
* @return size of all params array
|
||||
* @brief isDebugBuild This method return true if the library buildet in debug mode.
|
||||
* @return true if this library buildet in debug mode.
|
||||
*/
|
||||
[[deprecated("Use Qt MACROSSSES")]]
|
||||
static bool isDebugBuild();
|
||||
|
||||
/**
|
||||
* @brief size This method return count of the all input arguments.
|
||||
* @return size of all params array.
|
||||
*/
|
||||
static int size();
|
||||
|
||||
/**
|
||||
* @brief customParamasSize
|
||||
* @return size of params entered in conosole
|
||||
* @brief showHelp This method shows all help message.
|
||||
*/
|
||||
static int customParamasSize();
|
||||
static void showHelp();
|
||||
|
||||
/**
|
||||
* @brief showHelpForInputOptions This method show help for each input option.
|
||||
* @note Befor using of this method invoke the parseParams method. This is needed for generate the help message.
|
||||
*
|
||||
* **Example:**
|
||||
*
|
||||
* ```bash
|
||||
* myTool help option1 -option2 argumets
|
||||
* ```
|
||||
*/
|
||||
static void showHelpForInputOptions();
|
||||
|
||||
/**
|
||||
* @brief getHelpOfInputOptions This method return help abut input options only. Exept help and h options.
|
||||
* @return help abut input options only. Exept help and h options.
|
||||
*/
|
||||
static Help::Section getHelpOfInputOptions();
|
||||
|
||||
/**
|
||||
* @brief getHelp This method return options help page.
|
||||
* @note Befor using of this method invoke the parseParams method. This is needed for generate the help message.
|
||||
* @return help of available options.
|
||||
*/
|
||||
static const Help::Section& getHelp();
|
||||
|
||||
/**
|
||||
* @brief getUserParamsMap This method return const reference to the parsed arguments map.
|
||||
* @return A map object with parsed arguments.
|
||||
*/
|
||||
static const QMap<QString, QString> &getUserParamsMap();
|
||||
|
||||
/**
|
||||
* @brief clearParsedData This method clear all parsed data.
|
||||
*/
|
||||
static void clearParsedData();
|
||||
|
||||
/**
|
||||
* @brief getCurrentExecutable This method return path to the current executable.
|
||||
* @return path to current executable.
|
||||
*/
|
||||
static QString getCurrentExecutable();
|
||||
|
||||
/**
|
||||
* @brief getCurrentExecutableDir This method return a path to a folder with the current executable.
|
||||
* @return path of the folder with current executable.
|
||||
*/
|
||||
static QString getCurrentExecutableDir();
|
||||
|
||||
/**
|
||||
* @brief availableArguments This method return list of the available arguments of QuasarAppLibrary
|
||||
* @return list of the available arguments
|
||||
*/
|
||||
static OptionsDataList availableArguments();
|
||||
|
||||
private:
|
||||
|
||||
static bool optionsForEach(const QStringList& paramsArray,
|
||||
const OptionsDataList &availableOptions);
|
||||
|
||||
/**
|
||||
* @brief Traverse @a params and output its content (all the working
|
||||
* options) to stdout in the form of option-value groups at the
|
||||
* debug verbose level (-verbose 3).
|
||||
*/
|
||||
static void printWorkingOptions();
|
||||
|
||||
/**
|
||||
* @brief checkOption return tru if the option is supported
|
||||
* @param option checked option
|
||||
* @return true if option is supported
|
||||
*/
|
||||
static bool checkOption(const OptionData &option, const QString &rawOptionName);
|
||||
|
||||
/**
|
||||
* @brief parseAvailableOptions This is private method for parsing availabel options.
|
||||
* @param availableOptionsListIn input data of the available options.
|
||||
* @param availableOptionsListOut hash of available options wher key it options name and value it is options data
|
||||
* @param helpOut This is help object that generated from the
|
||||
*/
|
||||
static void parseAvailableOptions(const OptionsDataList& availableOptionsListIn,
|
||||
OptionsDataList* availableOptionsListOut,
|
||||
Help::Section* helpOut);
|
||||
|
||||
|
||||
static QMap<QString, QString> params;
|
||||
static OptionsDataList inputOptions;
|
||||
|
||||
static Help::Section userHelp;
|
||||
static QString appPath;
|
||||
static QString appName;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
29
qaglobalutils.cpp
Normal file
29
qaglobalutils.cpp
Normal file
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2025 QuasarApp.
|
||||
* Distributed under the lgplv3 software license, see the accompanying
|
||||
* Everyone is permitted to copy and distribute verbatim copies
|
||||
* of this license document, but changing it is not allowed.
|
||||
*/
|
||||
|
||||
#include "qaglobalutils.h"
|
||||
#include <limits>
|
||||
|
||||
template<class NUM>
|
||||
void gen(int size, QByteArray &result) {
|
||||
for (; size > 0; size -= sizeof(NUM)) {
|
||||
NUM random = (rand() * rand()) % std::numeric_limits<NUM>::max();
|
||||
result.insert(0, reinterpret_cast<char*>(&random), sizeof(random));
|
||||
}
|
||||
}
|
||||
// to do. The random function should generate 4 bit numbers anywhere except last number
|
||||
void randomArray(int size, QByteArray &result) {
|
||||
if (size % sizeof(unsigned long long) == 0) {
|
||||
gen<unsigned long long>(size, result);
|
||||
} else if (size % sizeof(unsigned int) == 0) {
|
||||
gen<unsigned int>(size, result);
|
||||
} else if (size % sizeof(unsigned short) == 0) {
|
||||
gen<unsigned short>(size, result);
|
||||
} else {
|
||||
gen<unsigned char>(size, result);
|
||||
}
|
||||
}
|
159
qaglobalutils.h
Normal file
159
qaglobalutils.h
Normal file
@ -0,0 +1,159 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2025 QuasarApp.
|
||||
* Distributed under the lgplv3 software license, see the accompanying
|
||||
* Everyone is permitted to copy and distribute verbatim copies
|
||||
* of this license document, but changing it is not allowed.
|
||||
*/
|
||||
|
||||
#ifndef QU_GLOBAL_UTILS_H
|
||||
#define QU_GLOBAL_UTILS_H
|
||||
|
||||
#include <type_traits>
|
||||
#include <typeinfo>
|
||||
#include <QByteArray>
|
||||
#include "QtGlobal"
|
||||
#include "quasarapp_global.h"
|
||||
|
||||
template <typename T>
|
||||
constexpr inline T operator | (T lhs, T rhs)
|
||||
{
|
||||
|
||||
static_assert(std::is_enum<T>::value,
|
||||
"template parameter is not an enum type");
|
||||
|
||||
return static_cast<T>(static_cast<int>(lhs) | static_cast<int>(rhs));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
constexpr inline T operator & (T lhs, T rhs)
|
||||
{
|
||||
|
||||
static_assert(std::is_enum<T>::value,
|
||||
"template parameter is not an enum type");
|
||||
|
||||
return static_cast<T>(static_cast<int>(lhs) & static_cast<int>(rhs));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
constexpr inline T operator >> (T lhs, T rhs)
|
||||
{
|
||||
|
||||
static_assert(std::is_enum<T>::value,
|
||||
"template parameter is not an enum type");
|
||||
|
||||
return static_cast<T>(static_cast<int>(lhs) >> static_cast<int>(rhs));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
constexpr inline T operator << (T lhs, T rhs)
|
||||
{
|
||||
|
||||
static_assert(std::is_enum<T>::value,
|
||||
"template parameter is not an enum type");
|
||||
|
||||
return static_cast<T>(static_cast<int>(lhs) << static_cast<int>(rhs));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
constexpr inline T operator ~ (T lhs)
|
||||
{
|
||||
|
||||
static_assert(std::is_enum<T>::value,
|
||||
"template parameter is not an enum type");
|
||||
|
||||
return static_cast<T>(~static_cast<int>(lhs));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
constexpr inline T operator ^ (T lhs, T rhs)
|
||||
{
|
||||
|
||||
static_assert(std::is_enum<T>::value,
|
||||
"template parameter is not an enum type");
|
||||
|
||||
return static_cast<T>(static_cast<int>(lhs) ^ static_cast<int>(rhs));
|
||||
}
|
||||
|
||||
template<class T>
|
||||
/**
|
||||
* @brief static_type_hash_32 This function return hash code of the class T.
|
||||
* For get more information see the std [documentation](https://en.cppreference.com/w/cpp/types/type_info/hash_code).
|
||||
* @note This method will create a T object on stack, so if you have a alredy created object use the static_type_hash_32(const T&) function.
|
||||
* @return uint32_t hash code of the class T
|
||||
*/
|
||||
uint32_t static_type_hash_32() noexcept {
|
||||
return typeid (T).hash_code();
|
||||
};
|
||||
|
||||
template<class T>
|
||||
/**
|
||||
* @brief static_type_hash_16 This function return hash code of the class T.
|
||||
* For get more information see the std [documentation](https://en.cppreference.com/w/cpp/types/type_info/hash_code).
|
||||
* @note This method will create a T object on stack, so if you have a alredy created object use the static_type_hash_16(const T&) function.
|
||||
* @return uint16_t hash code of the class T
|
||||
*/
|
||||
uint16_t static_type_hash_16() noexcept {
|
||||
return typeid (T).hash_code() % 0xFFFF;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
/**
|
||||
* @brief static_type_hash_8 This function return hash code of the class T.
|
||||
* For get more information see the std [documentation](https://en.cppreference.com/w/cpp/types/type_info/hash_code).
|
||||
* @note This method will create a T object on stack, so if you have a alredy created object use the static_type_hash_8(const T&) function.
|
||||
* @return uint8_t hash code of the class T
|
||||
*/
|
||||
uint8_t static_type_hash_8() noexcept {
|
||||
return typeid (T).hash_code() % 0xFF;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
/**
|
||||
* @brief static_type_hash_32 This function return hash code of a T type using @a object.
|
||||
* @param object This is object of the T type using for generate hash.
|
||||
* @return uint32_t hash code of the class T
|
||||
*/
|
||||
uint32_t static_type_hash_32(T& object) noexcept {
|
||||
return typeid (object).hash_code();
|
||||
};
|
||||
|
||||
template<class T>
|
||||
/**
|
||||
* @brief static_type_hash_16 This function return hash code of a T type using @a object.
|
||||
* @param object This is object of the T type using for generate hash.
|
||||
* @return uint16_t hash code of the class T
|
||||
*/
|
||||
uint16_t static_type_hash_16(T& object) noexcept {
|
||||
return typeid (object).hash_code() % 0xFFFF;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
/**
|
||||
* @brief static_type_hash_8 This function return hash code of a T type using @a object.
|
||||
* @param object This is object of the T type using for generate hash.
|
||||
* @return uint8_t hash code of the class T
|
||||
*/
|
||||
uint8_t static_type_hash_8(T& object) noexcept {
|
||||
return typeid (object).hash_code() % 0xFF;
|
||||
};
|
||||
|
||||
/// @brief H_8 This is short wraper of the static_type_hash_8 fucntion.
|
||||
#define H_8 static_type_hash_8
|
||||
|
||||
/// @brief H_16 This is short wraper of the static_type_hash_16 fucntion.
|
||||
#define H_16 static_type_hash_16
|
||||
|
||||
/// @brief H_32 This is short wraper of the static_type_hash_32 fucntion.
|
||||
#define H_32 static_type_hash_32
|
||||
|
||||
|
||||
#define debug_assert(C, M) Q_ASSERT(C && M)
|
||||
|
||||
/**
|
||||
* @brief randomArray This function return random arrat with size @a size
|
||||
* @param size This is size of needed array.
|
||||
* @param result This is result value of generated array.
|
||||
*/
|
||||
void QUASARAPPSHARED_EXPORT randomArray(int size, QByteArray &result);
|
||||
|
||||
#endif // GLOBAL_H
|
114
qalogger.cpp
Normal file
114
qalogger.cpp
Normal file
@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright (C) 2024-2025 QuasarApp.
|
||||
* Distributed under the lgplv3 software license, see the accompanying
|
||||
* Everyone is permitted to copy and distribute verbatim copies
|
||||
* of this license document, but changing it is not allowed.
|
||||
*/
|
||||
|
||||
#include "qalogger.h"
|
||||
#include "params.h"
|
||||
#include <iostream>
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QStandardPaths>
|
||||
|
||||
namespace QuasarAppUtils {
|
||||
|
||||
Q_GLOBAL_STATIC(QString, _logFile)
|
||||
|
||||
static bool _toFile = false;
|
||||
static VerboseLvl _verboseLevel = Debug;
|
||||
|
||||
|
||||
#define MESSAGE_PATTERN \
|
||||
"[%{time MM-dd h:mm:ss.zzz} %{threadid} " \
|
||||
"%{if-debug}Debug%{endif}%{if-info}Info%{endif}%{if-warning}Warning%{endif}%{if-critical}Error%{endif}%{if-fatal}Fatal%{endif}] " \
|
||||
"%{message}"
|
||||
|
||||
|
||||
QALogger::QALogger() {
|
||||
}
|
||||
|
||||
QALogger::~QALogger() {
|
||||
}
|
||||
|
||||
|
||||
bool checkLogType(QtMsgType type, VerboseLvl lvl) {
|
||||
switch (type) {
|
||||
case QtDebugMsg: return lvl >= Debug;
|
||||
case QtInfoMsg: return lvl >= Info;
|
||||
case QtWarningMsg: return lvl >= Warning;
|
||||
|
||||
case QtCriticalMsg:
|
||||
case QtFatalMsg:
|
||||
return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
void messageHandler(QtMsgType type, const QMessageLogContext & context, const QString &msg) {
|
||||
|
||||
|
||||
|
||||
if (checkLogType(type, _verboseLevel)) {
|
||||
if (_toFile && _logFile->size()) {
|
||||
QFile logFile(*_logFile);
|
||||
if (logFile.open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Text)) {
|
||||
QTextStream stream(&logFile);
|
||||
stream << qFormatLogMessage(type, context, msg) << Qt::endl;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case QtMsgType::QtFatalMsg:
|
||||
case QtMsgType::QtCriticalMsg:
|
||||
case QtMsgType::QtWarningMsg: {
|
||||
std::cerr << qFormatLogMessage(type, context, msg).toStdString() << std::endl;
|
||||
break;
|
||||
}
|
||||
case QtMsgType::QtDebugMsg:
|
||||
case QtMsgType::QtInfoMsg:
|
||||
default: {
|
||||
std::cout << qFormatLogMessage(type, context, msg).toStdString() << std::endl;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void QALogger::init() {
|
||||
qSetMessagePattern(MESSAGE_PATTERN);
|
||||
qInstallMessageHandler(messageHandler);
|
||||
|
||||
|
||||
_verboseLevel = Params::getVerboseLvl();
|
||||
|
||||
if (Params::isEndable("fileLog")) {
|
||||
_toFile = true;
|
||||
QString path = QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation);
|
||||
QString filePath = path + "/" + QCoreApplication::applicationName() +
|
||||
" " + QDate::currentDate().toString(Qt::DateFormat::ISODate) + ".log";
|
||||
auto file = Params::getArg("fileLog");
|
||||
if (file.size()) {
|
||||
filePath = file;
|
||||
}
|
||||
|
||||
QDir().mkpath(path);
|
||||
|
||||
*_logFile = filePath;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
QString QALogger::getLogFilePath() {
|
||||
return *_logFile;
|
||||
}
|
||||
|
||||
}
|
66
qalogger.h
Normal file
66
qalogger.h
Normal file
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (C) 2024-2025 QuasarApp.
|
||||
* Distributed under the lgplv3 software license, see the accompanying
|
||||
* Everyone is permitted to copy and distribute verbatim copies
|
||||
* of this license document, but changing it is not allowed.
|
||||
*/
|
||||
|
||||
#ifndef QALOGGER_H
|
||||
#define QALOGGER_H
|
||||
|
||||
#include "quasarapp_global.h"
|
||||
|
||||
#include <QFile>
|
||||
#include <QList>
|
||||
|
||||
namespace QuasarAppUtils {
|
||||
|
||||
/**
|
||||
* @brief The QALogger class is logger handler for app.
|
||||
* This class allow to log all message from app to file.
|
||||
*
|
||||
* Example:
|
||||
* @code
|
||||
* #include <qalogger.h>
|
||||
*
|
||||
* QuasarAppUtils::QALogger logger;
|
||||
*
|
||||
* QuasarAppUtils::Params::setEnable("fileLog", true); //force enable file writing using efault file location - located in localApplication data.
|
||||
*
|
||||
* QuasarAppUtils::Params::parseParams(argc, argv);
|
||||
*
|
||||
* logger.init();
|
||||
* @endcode
|
||||
*
|
||||
*
|
||||
* Standart file log locations per platforms :
|
||||
* - Windows: %APPDATA%/OrganisationName/YourAppName/YourAppName.log
|
||||
* - Linux: $HOME/.config/OrganisationName/YourAppName/YourAppName.log
|
||||
* - Mac: $HOME/Library/Application Support/OrganisationName/YourAppName/YourAppName.log
|
||||
* - Android: /data/data/com.organisationName.yourAppName/files/YourAppName.log
|
||||
* - iOS: /var/mobile/Applications/Data/YourAppName/YourAppName.log
|
||||
*
|
||||
* you can overiwite this location by setting "fileLog" option in Params.
|
||||
*/
|
||||
class QUASARAPPSHARED_EXPORT QALogger
|
||||
{
|
||||
public:
|
||||
QALogger();
|
||||
~QALogger();
|
||||
|
||||
/**
|
||||
* @brief init This method initialize logging of all qt message into file.
|
||||
* @note This function should be invokae after parsing arguments.
|
||||
* if you invoke this before parsing arguments, verbose level of logs will not created correct.
|
||||
*/
|
||||
void init();
|
||||
|
||||
/**
|
||||
* @brief setVerboseLevel This method set verbose level of the logger.
|
||||
* @param lvl This is new verbose level.
|
||||
*/
|
||||
static QString getLogFilePath();
|
||||
|
||||
};
|
||||
}
|
||||
#endif // QALOGGER_H
|
53
qaplatformutils.h
Normal file
53
qaplatformutils.h
Normal file
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (C) 2024-2025 QuasarApp.
|
||||
* Distributed under the lgplv3 software license, see the accompanying
|
||||
* Everyone is permitted to copy and distribute verbatim copies
|
||||
* of this license document, but changing it is not allowed.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef PLATFORMUTILS_H
|
||||
#define PLATFORMUTILS_H
|
||||
|
||||
#include <QString>
|
||||
#include "quasarapp_global.h"
|
||||
|
||||
namespace QuasarAppUtils {
|
||||
|
||||
/**
|
||||
* @brief The iPlatformUtils class bas interface for get access platform dependet functions and constants.
|
||||
*/
|
||||
class QUASARAPPSHARED_EXPORT PlatformUtils
|
||||
{
|
||||
public:
|
||||
PlatformUtils();
|
||||
|
||||
/**
|
||||
* @brief isSnap This method check destribution type. true if the application packed as a snap.
|
||||
* @return true if the application packaged as a snap else false.
|
||||
*/
|
||||
static bool isSnap();
|
||||
|
||||
/**
|
||||
* @brief snapRootFS returns root file system of main OS (available read only)
|
||||
* @return path ro main os root.
|
||||
*/
|
||||
static QString snapRootFS();
|
||||
|
||||
/**
|
||||
* @brief transportPathToSnapRoot change path to snap avaialble.
|
||||
* @param path source path of main OS.
|
||||
* @return readable path location for snap pacakge.
|
||||
* @note this method is not a fast, so not invoke it too offten.
|
||||
*/
|
||||
static QString transportPathToSnapRoot(const QString &path);
|
||||
|
||||
/**
|
||||
* @brief checkSystemBakupSnapInterface This method check access to bakcup permision of snap pacakge.
|
||||
* This permision required to get access to rootfs of main OS.
|
||||
* @return true if the app have this accesss.
|
||||
*/
|
||||
static bool checkSystemBakupSnapInterface();
|
||||
};
|
||||
}
|
||||
#endif // IPLATFORMUTILS_H
|
99
qaplatformutils_linux.cpp
Normal file
99
qaplatformutils_linux.cpp
Normal file
@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright (C) 2024-2025 QuasarApp.
|
||||
* Distributed under the lgplv3 software license, see the accompanying
|
||||
* Everyone is permitted to copy and distribute verbatim copies
|
||||
* of this license document, but changing it is not allowed.
|
||||
*/
|
||||
|
||||
#include "qaplatformutils.h"
|
||||
|
||||
#if defined(Q_OS_LINUX)
|
||||
#include <QDir>
|
||||
#include <QFileInfo>
|
||||
#include <QProcessEnvironment>
|
||||
#elif defined(Q_OS_ANDROID)
|
||||
#elif defined(Q_OS_WIN32)
|
||||
#elif defined(Q_OS_MACOS)
|
||||
#elif defined(Q_OS_IOS)
|
||||
#endif
|
||||
|
||||
namespace QuasarAppUtils {
|
||||
|
||||
#if defined(Q_OS_LINUX)
|
||||
bool PlatformUtils::isSnap() {
|
||||
return QProcessEnvironment::systemEnvironment().value("SNAP").size();
|
||||
}
|
||||
|
||||
QString PlatformUtils::snapRootFS() {
|
||||
return "/var/lib/snapd/hostfs";
|
||||
}
|
||||
|
||||
QString PlatformUtils::transportPathToSnapRoot(const QString &path) {
|
||||
if (isSnap() && checkSystemBakupSnapInterface()) {
|
||||
|
||||
if(QFileInfo(path).isWritable()) {
|
||||
return path;
|
||||
}
|
||||
|
||||
if (path.size() && path[0] != QString("/")) {
|
||||
auto absalutPath = QProcessEnvironment::systemEnvironment().value("PWD") + "/" + path;
|
||||
if (!absalutPath.contains(snapRootFS())) {
|
||||
return snapRootFS() + "/" + absalutPath;
|
||||
}
|
||||
}
|
||||
|
||||
if (!path.contains(snapRootFS())) {
|
||||
return snapRootFS() + "/" + path;
|
||||
}
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
bool PlatformUtils::checkSystemBakupSnapInterface() {
|
||||
return QDir(snapRootFS()).entryList(QDir::AllEntries | QDir::NoDotAndDotDot).size();
|
||||
}
|
||||
|
||||
#elif defined(Q_OS_ANDROID)
|
||||
|
||||
bool PlatformUtils::isSnap() { return false;}
|
||||
|
||||
QString PlatformUtils::snapRootFS() { return "";}
|
||||
|
||||
QString PlatformUtils::transportPathToSnapRoot(const QString &path) { return path; }
|
||||
|
||||
bool PlatformUtils::checkSystemBakupSnapInterface() { return false; }
|
||||
|
||||
#elif defined(Q_OS_WIN32)
|
||||
|
||||
bool PlatformUtils::isSnap() { return false;}
|
||||
|
||||
QString PlatformUtils::snapRootFS() { return "";}
|
||||
|
||||
QString PlatformUtils::transportPathToSnapRoot(const QString &path) { return path; }
|
||||
|
||||
bool PlatformUtils::checkSystemBakupSnapInterface() { return false; }
|
||||
|
||||
#elif defined(Q_OS_MACOS)
|
||||
|
||||
bool PlatformUtils::isSnap() { return false;}
|
||||
|
||||
QString PlatformUtils::snapRootFS() { return "";}
|
||||
|
||||
QString PlatformUtils::transportPathToSnapRoot(const QString &path) { return path; }
|
||||
|
||||
bool PlatformUtils::checkSystemBakupSnapInterface() { return false; }
|
||||
|
||||
#elif defined(Q_OS_IOS)
|
||||
|
||||
bool PlatformUtils::isSnap() { return false;}
|
||||
|
||||
QString PlatformUtils::snapRootFS() { return "";}
|
||||
|
||||
QString PlatformUtils::transportPathToSnapRoot(const QString &path) { return path; }
|
||||
|
||||
bool PlatformUtils::checkSystemBakupSnapInterface() { return false; }
|
||||
|
||||
#endif
|
||||
|
||||
}
|
48
qasecretservice.cpp
Normal file
48
qasecretservice.cpp
Normal file
@ -0,0 +1,48 @@
|
||||
#include "qasecretservice.h"
|
||||
|
||||
#ifdef Q_OS_LINUX
|
||||
#include <QProcess>
|
||||
|
||||
QByteArray QuasarAppUtils::QASecretService::getByAlias(const QString &alias) {
|
||||
QProcess proc;
|
||||
proc.setProgram("qasecretservice");
|
||||
proc.setArguments(QStringList() << "get" << "-alias" << alias);
|
||||
|
||||
proc.start();
|
||||
|
||||
if (!proc.waitForFinished(2000)) {
|
||||
return "";
|
||||
}
|
||||
|
||||
if (proc.exitCode()) {
|
||||
return "";
|
||||
}
|
||||
|
||||
QByteArray result = proc.readAllStandardOutput();
|
||||
|
||||
// drop \n
|
||||
return result.left(result.size() - 1);
|
||||
}
|
||||
|
||||
QByteArray QuasarAppUtils::QASecretService::getByHash(const QByteArray &hash)
|
||||
{
|
||||
QProcess proc;
|
||||
proc.setProgram("qasecretservice");
|
||||
proc.setArguments(QStringList() << "get" << "-hash" << hash);
|
||||
|
||||
proc.start();
|
||||
|
||||
if (!proc.waitForFinished(2000)) {
|
||||
return "";
|
||||
}
|
||||
|
||||
if (proc.exitCode()) {
|
||||
return "";
|
||||
}
|
||||
|
||||
QByteArray result = proc.readAllStandardOutput();
|
||||
|
||||
// drop \n
|
||||
return result.left(result.size() - 1);
|
||||
}
|
||||
#endif
|
35
qasecretservice.h
Normal file
35
qasecretservice.h
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (C) 2024-2025 QuasarApp.
|
||||
* Distributed under the lgplv3 software license, see the accompanying
|
||||
* Everyone is permitted to copy and distribute verbatim copies
|
||||
* of this license document, but changing it is not allowed.
|
||||
*/
|
||||
|
||||
#ifndef QASECRETSERVICE_H
|
||||
#define QASECRETSERVICE_H
|
||||
|
||||
#include <QByteArray>
|
||||
|
||||
|
||||
namespace QuasarAppUtils {
|
||||
|
||||
/**
|
||||
* @brief The qasecretservice class This is a simeple provider of QASecretService tool
|
||||
* See https://github.com/QuasarApp/SecretService
|
||||
* @note Before use this class please install QASecretService to your runtime mashine.
|
||||
*
|
||||
*/
|
||||
class QASecretService
|
||||
{
|
||||
public:
|
||||
QASecretService();
|
||||
|
||||
#ifdef Q_OS_LINUX
|
||||
|
||||
static QByteArray getByAlias(const QString& alias);
|
||||
static QByteArray getByHash(const QByteArray& hash);
|
||||
#endif
|
||||
};
|
||||
|
||||
}
|
||||
#endif // QASECRETSERVICE_H
|
7
qaservice.cpp
Normal file
7
qaservice.cpp
Normal file
@ -0,0 +1,7 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2025 QuasarApp.
|
||||
* Distributed under the lgplv3 software license, see the accompanying
|
||||
* Everyone is permitted to copy and distribute verbatim copies
|
||||
* of this license document, but changing it is not allowed.
|
||||
*/
|
||||
|
159
qaservice.h
Normal file
159
qaservice.h
Normal file
@ -0,0 +1,159 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2025 QuasarApp.
|
||||
* Distributed under the lgplv3 software license, see the accompanying
|
||||
* Everyone is permitted to copy and distribute verbatim copies
|
||||
* of this license document, but changing it is not allowed.
|
||||
*/
|
||||
|
||||
#ifndef QASERVICE_H
|
||||
#define QASERVICE_H
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
namespace QuasarAppUtils {
|
||||
|
||||
/**
|
||||
* @brief The Service class is a template class for creating a singleton services objects.
|
||||
* This is manual control wrapper. You should be manually initializing your service object and manually deinitializing.
|
||||
* If you don't destroy your service, then service object will be automatically destroyed when application will be closed.
|
||||
* @warning If service was destroyed automatically, then destructor of your base class will be not invoked. Use The deinit method for this.
|
||||
* @todo Remove the template Base class. Instead, it needs to use a general inherit paradigm
|
||||
*
|
||||
* **Examples**
|
||||
*
|
||||
* **Create a service class**
|
||||
*
|
||||
* @code{cpp}
|
||||
*
|
||||
* #include <qaservice.h>
|
||||
*
|
||||
* class MyService: public QuasarAppUtils::Service<MyService> {\
|
||||
* // some implementation
|
||||
* };
|
||||
*
|
||||
* @endcode
|
||||
*
|
||||
* **Initialise a service object**
|
||||
*
|
||||
* @code{cpp}
|
||||
*
|
||||
* #include <MyService.h>
|
||||
*
|
||||
* // initialise service
|
||||
* MyService* serviceInstance = MyService::initService();
|
||||
*
|
||||
* // get service instance.
|
||||
* serviceInstance = MyService::instance();
|
||||
*
|
||||
* // remove service instance object.
|
||||
* MyService::deinitService();
|
||||
*
|
||||
* @endcode
|
||||
*
|
||||
*
|
||||
* Or you can use the autoInstance method for initialize instance object if not exists.
|
||||
* @note This method try initialize base instance object use default construct.
|
||||
*
|
||||
* @code{cpp}
|
||||
*
|
||||
* #include <MyService.h>
|
||||
*
|
||||
* // initialise service
|
||||
* MyService* serviceInstance = MyService::autoInstance();
|
||||
*
|
||||
* @endcode
|
||||
*/
|
||||
template<class Base>
|
||||
class Service
|
||||
{
|
||||
|
||||
public:
|
||||
Service() {};
|
||||
|
||||
/**
|
||||
* @brief initService This method initialize the @a Base object as a service.
|
||||
* @param args This is argumets of a constructo of the @a Base class.
|
||||
* @return instance pointer. If the service alredy initialized then return pointer to current service object.
|
||||
* @see instance
|
||||
* @see deinitService
|
||||
* @see autoInstance
|
||||
*/
|
||||
static inline std::unique_ptr<Base>& initService() {
|
||||
auto& val = instancePrivat();
|
||||
if(!val) {
|
||||
val.reset(new Base());
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief initService This is overrided static method of initialization cross libraryes object.
|
||||
* @note If you want to create your own implementation of the settings object - you need to use this method for initioalisation instant qaservice::initService - template method.
|
||||
* Becouse Some OS has every shared libraryes has itself isolation address space (for example Android).
|
||||
* If you initialize instance of your settings model on one libarary the this instance will be available only on your library or upper.
|
||||
* Bot not on the QuasarApp lib so SettingsListner will not work.
|
||||
* @param obj This is inited settings object.
|
||||
* @return true if the @a obj service was saved as a service object else false.
|
||||
*/
|
||||
static bool initService(std::unique_ptr<Base> obj) {
|
||||
auto& val = instancePrivat();
|
||||
if(!val) {
|
||||
val = std::move(obj);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief instance This method return pointerer to current service object.
|
||||
* @note If object was not initialized, then return false.
|
||||
* @return pointerer to current service object if service initialized else nullptr.
|
||||
* @see initService
|
||||
* @see deinitService
|
||||
* @see autoInstance
|
||||
*/
|
||||
static Base* instance() {
|
||||
return instancePrivat().get();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief autoInstance This method return pointerer to current service object and if it is not inited try to initialize it use default constructor.
|
||||
* @return pointerer to current service object if service initialized else nullptr.
|
||||
* @see instance
|
||||
*/
|
||||
static Base* autoInstance() {
|
||||
auto& val = instancePrivat();
|
||||
|
||||
if (!val) {
|
||||
initService();
|
||||
}
|
||||
|
||||
return val.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief deinitService This is distructor method for the service.
|
||||
* @note do nothink if this object alredy distroyed.
|
||||
* @see instance
|
||||
* @see initService
|
||||
* @see autoInstance
|
||||
*/
|
||||
static void deinitService() {
|
||||
auto& val = instancePrivat();
|
||||
|
||||
if(val) {
|
||||
val.release();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
static inline std::unique_ptr<Base>& instancePrivat() {
|
||||
static std::unique_ptr<Base> instance = nullptr;
|
||||
return instance;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
#endif // QASERVICE_H
|
@ -1,11 +1,10 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2020 QuasarApp.
|
||||
* Copyright (C) 2018-2025 QuasarApp.
|
||||
* Distributed under the lgplv3 software license, see the accompanying
|
||||
* Everyone is permitted to copy and distribute verbatim copies
|
||||
* of this license document, but changing it is not allowed.
|
||||
*/
|
||||
|
||||
#include "quasarapp.h"
|
||||
|
||||
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2020 QuasarApp.
|
||||
* Copyright (C) 2018-2025 QuasarApp.
|
||||
* Distributed under the lgplv3 software license, see the accompanying
|
||||
* Everyone is permitted to copy and distribute verbatim copies
|
||||
* of this license document, but changing it is not allowed.
|
||||
@ -11,12 +11,12 @@
|
||||
#include "params.h"
|
||||
#include "locales.h"
|
||||
#include "settings.h"
|
||||
#include "global.h"
|
||||
#include "qaplatformutils.h"
|
||||
|
||||
/**
|
||||
* @brief The QuasaraAppUtils class
|
||||
* this lib include base functions for the all applications of QuasarApp group.
|
||||
* all methods of the Quasar AppUtils is static
|
||||
* This lib include base functions for the all applications of QuasarApp group.
|
||||
* All methods of the Quasar AppUtils is static.
|
||||
*/
|
||||
namespace QuasarAppUtils{
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
#include <QtCore/qglobal.h>
|
||||
|
||||
#if defined(QUASARAAPP_LIBRARY)
|
||||
#if defined(QUASARAPP_LIBRARY)
|
||||
# define QUASARAPPSHARED_EXPORT Q_DECL_EXPORT
|
||||
#else
|
||||
# define QUASARAPPSHARED_EXPORT Q_DECL_IMPORT
|
||||
|
79
settings.cpp
79
settings.cpp
@ -1,17 +1,19 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2020 QuasarApp.
|
||||
* Copyright (C) 2021-2025 QuasarApp.
|
||||
* Distributed under the lgplv3 software license, see the accompanying
|
||||
* Everyone is permitted to copy and distribute verbatim copies
|
||||
* of this license document, but changing it is not allowed.
|
||||
*/
|
||||
|
||||
|
||||
#include "settings.h"
|
||||
#include <QSettings>
|
||||
#include <QCoreApplication>
|
||||
#include <QDebug>
|
||||
|
||||
using namespace QuasarAppUtils;
|
||||
namespace QuasarAppUtils {
|
||||
|
||||
Settings::Settings(SettingsSaveMode mode) {
|
||||
Settings::Settings() {
|
||||
auto name = QCoreApplication::applicationName();
|
||||
auto company = QCoreApplication::organizationName();
|
||||
if (name.isEmpty()) {
|
||||
@ -22,57 +24,58 @@ Settings::Settings(SettingsSaveMode mode) {
|
||||
company = "QuasarApp";
|
||||
}
|
||||
|
||||
_settings = new QSettings(QSettings::IniFormat, QSettings::Scope::UserScope, company, name);
|
||||
_mode = mode;
|
||||
_settings = new QSettings(QSettings::NativeFormat, QSettings::Scope::UserScope, company, name);
|
||||
}
|
||||
|
||||
SettingsSaveMode Settings::getMode() const
|
||||
{
|
||||
return _mode;
|
||||
void Settings::syncImplementation() {
|
||||
return _settings->sync();
|
||||
}
|
||||
|
||||
void Settings::setMode(const SettingsSaveMode &mode)
|
||||
{
|
||||
_mode = mode;
|
||||
}
|
||||
QVariant Settings::getValueImplementation(const QString &key, const QVariant &def) {
|
||||
if (isBool(key)) {
|
||||
return _settings->value(key, def).toBool();
|
||||
}
|
||||
|
||||
Settings *Settings::initSettings(SettingsSaveMode mode) {
|
||||
static Settings* res = new Settings(mode);
|
||||
return res;
|
||||
}
|
||||
|
||||
Settings *Settings::get() {
|
||||
return initSettings();
|
||||
}
|
||||
|
||||
const Settings *Settings::getConst() {
|
||||
return initSettings();
|
||||
}
|
||||
|
||||
QVariant Settings::getValue(const QString &key, const QVariant &def) {
|
||||
return _settings->value(key, def);
|
||||
}
|
||||
|
||||
QString Settings::getStrValue(const QString &key, const QString &def) {
|
||||
return getValue(key, QVariant(def)).toString();
|
||||
void Settings::setValueImplementation(const QString key, const QVariant &value) {
|
||||
return _settings->setValue(key, value);
|
||||
}
|
||||
|
||||
void Settings::sync() {
|
||||
_settings->sync();
|
||||
bool Settings::ignoreToRest(const QString &) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
void Settings::setValue(const QString key, const QVariant &value) {
|
||||
_settings->setValue(key, value);
|
||||
QHash<QString, QVariant> Settings::defaultSettings() {
|
||||
return {};
|
||||
}
|
||||
|
||||
emit valueChanged(key, value);
|
||||
emit valueStrChanged(key, value.toString());
|
||||
bool Settings::isBool(const QString &) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_mode == SettingsSaveMode::Auto) {
|
||||
sync();
|
||||
const QSet<QString> &Settings::boolOptions() const
|
||||
{
|
||||
return _boolOptions;
|
||||
}
|
||||
|
||||
void Settings::setBoolOptions(const QSet<QString> &newBoolOptions)
|
||||
{
|
||||
_boolOptions = newBoolOptions;
|
||||
}
|
||||
|
||||
bool Settings::initService() {
|
||||
return ISettings::initService(std::make_unique<Settings>());
|
||||
}
|
||||
|
||||
ISettings *Settings::autoInstance() {
|
||||
if (auto result = instance()) {
|
||||
return result;
|
||||
}
|
||||
|
||||
Settings::initService();
|
||||
return ISettings::instance();
|
||||
}
|
||||
|
||||
void Settings::setStrValue(const QString &key, const QString &value) {
|
||||
setValue(key, value);
|
||||
}
|
||||
|
143
settings.h
143
settings.h
@ -1,107 +1,106 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2020 QuasarApp.
|
||||
* Copyright (C) 2021-2025 QuasarApp.
|
||||
* Distributed under the lgplv3 software license, see the accompanying
|
||||
* Everyone is permitted to copy and distribute verbatim copies
|
||||
* of this license document, but changing it is not allowed.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef SETTINGS_H
|
||||
#define SETTINGS_H
|
||||
|
||||
#include "quasarapp_global.h"
|
||||
#include <QObject>
|
||||
#include <QVariant>
|
||||
|
||||
class QSettings;
|
||||
#include "isettings.h"
|
||||
#include <QSet>
|
||||
|
||||
namespace QuasarAppUtils {
|
||||
|
||||
/**
|
||||
* @brief The SettingsSaveMode enum
|
||||
* Auto - value save on hard disk when calling method "value"
|
||||
* manual - save all data on hard disk when calling method Settings::sync
|
||||
* @brief The Settings class This is wraper of the QSettings object.
|
||||
*
|
||||
* Example of initialisation :
|
||||
*
|
||||
* @code{cpp}
|
||||
* auto settingsInstance = QuasarAppUtils::Setting::initService();
|
||||
*
|
||||
* // on any another site you can use the instance method for get settings instance object.
|
||||
* auto settingsInstance = QuasarAppUtils::Setting::instance();
|
||||
*
|
||||
* // and you can destroy setting object if they are not needed anymore
|
||||
* QuasarAppUtils::Setting::deinitService();
|
||||
* @endcode
|
||||
*
|
||||
* **Or** you can use the Settings::autoInstance method.
|
||||
*
|
||||
* @code{cpp}
|
||||
* auto settingsInstance = QuasarAppUtils::Setting::autoInstance();
|
||||
* @endcode
|
||||
*
|
||||
* @see Settings::init
|
||||
*/
|
||||
enum class SettingsSaveMode: quint64 {
|
||||
Auto,
|
||||
Manual
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The Settings class - singleton for QSettings
|
||||
*/
|
||||
class QUASARAPPSHARED_EXPORT Settings : public QObject
|
||||
class QUASARAPPSHARED_EXPORT Settings: public ISettings
|
||||
{
|
||||
Q_OBJECT
|
||||
private:
|
||||
explicit Settings(SettingsSaveMode mode = SettingsSaveMode::Auto);
|
||||
QSettings *_settings = nullptr;
|
||||
SettingsSaveMode _mode = SettingsSaveMode::Auto;
|
||||
|
||||
static Settings* initSettings(SettingsSaveMode mode = SettingsSaveMode::Auto);
|
||||
public:
|
||||
Settings();
|
||||
|
||||
// ISettings interface
|
||||
/**
|
||||
* @brief boolOptions returns current map with keys that has a bool type.
|
||||
* @return current map with keys that has a bool type
|
||||
* @see Settings::setBoolOptions
|
||||
* @see Settings::isBool
|
||||
*/
|
||||
const QSet<QString> &boolOptions() const;
|
||||
|
||||
/**
|
||||
* @brief get
|
||||
* @return object of all settings app;
|
||||
* @brief setBoolOptions This method sets new map of the boolean options.
|
||||
* @param newBoolOptions This is new map of the boolean options.
|
||||
* @see Settings::boolOptions
|
||||
* @see Settings::isBool
|
||||
*/
|
||||
static Settings* get();
|
||||
void setBoolOptions(const QSet<QString> &newBoolOptions);
|
||||
|
||||
/**
|
||||
* @brief get
|
||||
* @return const object of all settings app;
|
||||
* @brief initService This method initialize default object of the QuasarAppUtils::Settings type.
|
||||
* @return true if initialization finished successfull else false.
|
||||
* @see ISettings::initService
|
||||
*/
|
||||
static const Settings* getConst();
|
||||
static bool initService();
|
||||
|
||||
/**
|
||||
* @brief getValue
|
||||
* @param key - key of value
|
||||
* @param def - default value if is value not finded
|
||||
* @return value of key
|
||||
* @brief deinitService This method destroy default object of the QuasarAppUtils::Settings type.
|
||||
* @see ISettings::deinitService
|
||||
*/
|
||||
Q_INVOKABLE QVariant getValue(const QString &key, const QVariant& def);
|
||||
static ISettings *autoInstance();
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
void syncImplementation() override;
|
||||
QVariant getValueImplementation(const QString &key, const QVariant &def) override;
|
||||
void setValueImplementation(const QString key, const QVariant &value) override;
|
||||
bool ignoreToRest(const QString &) const override;
|
||||
QHash<QString, QVariant> defaultSettings() override;
|
||||
|
||||
/**
|
||||
* @brief getStrValue some as getValue but work with QString
|
||||
* @brief isBool This method should be return true if the key's type is bool.
|
||||
* This is needed because QVariant will be converted alvays to true value in a qml code.
|
||||
* @param key This is key of checks setting.
|
||||
* @return true if the key is boolean variable.
|
||||
* The default implementation check key in the inner map.
|
||||
*
|
||||
* @see Settings::setBoolOptions
|
||||
* @see Settings::boolOptions
|
||||
*/
|
||||
Q_INVOKABLE QString getStrValue(const QString &key, const QString& def);
|
||||
|
||||
/**
|
||||
* @brief sync - save all data on hard disk;
|
||||
*/
|
||||
void sync();
|
||||
|
||||
/**
|
||||
* @brief getMode
|
||||
* @return
|
||||
*/
|
||||
SettingsSaveMode getMode() const;
|
||||
|
||||
/**
|
||||
* @brief setMode
|
||||
* @param mode
|
||||
*/
|
||||
void setMode(const SettingsSaveMode &mode);
|
||||
|
||||
public slots:
|
||||
/**
|
||||
* @brief setValue - set new value of key
|
||||
* @param key - key pf settings
|
||||
* @param value - new value
|
||||
*/
|
||||
void setValue(const QString key, const QVariant& value);
|
||||
|
||||
/**
|
||||
* @brief setStrValue - some as setValue< but use QString
|
||||
*/
|
||||
void setStrValue(const QString& key, const QString& value);
|
||||
|
||||
|
||||
signals:
|
||||
void valueChanged(QString key, QVariant value);
|
||||
void valueStrChanged(QString key, QString value);
|
||||
virtual bool isBool(const QString& key) const;
|
||||
void setGroup(const QString&);
|
||||
|
||||
private:
|
||||
QSettings *_settings = nullptr;
|
||||
QSet<QString> _boolOptions;
|
||||
};
|
||||
} ;
|
||||
|
||||
}
|
||||
|
||||
#endif // SETTINGS_H
|
||||
|
32
settingslistner.cpp
Normal file
32
settingslistner.cpp
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2025 QuasarApp.
|
||||
* Distributed under the lgplv3 software license, see the accompanying
|
||||
* Everyone is permitted to copy and distribute verbatim copies
|
||||
* of this license document, but changing it is not allowed.
|
||||
*/
|
||||
|
||||
#include "isettings.h"
|
||||
#include "settingslistner.h"
|
||||
|
||||
namespace QuasarAppUtils {
|
||||
|
||||
SettingsListner::SettingsListner() {
|
||||
|
||||
auto settings = ISettings::instance();
|
||||
if (settings) {
|
||||
|
||||
auto listner = [this](QString key, QVariant val){
|
||||
this->handleSettingsChanged(key, val);
|
||||
};
|
||||
|
||||
_listnerConnection = QObject::connect(settings,
|
||||
&ISettings::valueChanged,
|
||||
listner);
|
||||
}
|
||||
}
|
||||
|
||||
SettingsListner::~SettingsListner() {
|
||||
QObject::disconnect(_listnerConnection);
|
||||
}
|
||||
|
||||
}
|
59
settingslistner.h
Normal file
59
settingslistner.h
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2025 QuasarApp.
|
||||
* Distributed under the lgplv3 software license, see the accompanying
|
||||
* Everyone is permitted to copy and distribute verbatim copies
|
||||
* of this license document, but changing it is not allowed.
|
||||
*/
|
||||
|
||||
#ifndef SETTINGSLISTNER_H
|
||||
#define SETTINGSLISTNER_H
|
||||
|
||||
#include <QString>
|
||||
#include <QVariant>
|
||||
#include "quasarapp_global.h"
|
||||
|
||||
|
||||
namespace QuasarAppUtils {
|
||||
|
||||
/**
|
||||
* @brief The SettingsListner class is listner of the ISettings global object.
|
||||
* The SettingsListner class is abstrct class and contains only one method for hendling settings changes.
|
||||
*
|
||||
*
|
||||
* ### Example of use :
|
||||
*
|
||||
* @code{cpp}
|
||||
* class MyClass : protected QuasarAppUtils::SettingsListner {
|
||||
* protected:
|
||||
* void handleSettingsChanged(const QString& key, const QVariant& value) override {
|
||||
*
|
||||
* if (key == "shareName") {
|
||||
setSessinon(static_cast<long long >(rand()) * rand());
|
||||
}
|
||||
* }
|
||||
*
|
||||
* };
|
||||
* @endcode
|
||||
* @see ISettings
|
||||
*/
|
||||
class QUASARAPPSHARED_EXPORT SettingsListner
|
||||
{
|
||||
public:
|
||||
SettingsListner();
|
||||
virtual ~SettingsListner();
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* @brief handleSettingsChanged This method will be invoked when settings of application has bean changed.
|
||||
* @param key This is key of a changed settings.
|
||||
* @param value This is a new value of a changed settings.
|
||||
*/
|
||||
virtual void handleSettingsChanged(const QString& key,
|
||||
const QVariant& value) = 0;
|
||||
private:
|
||||
QMetaObject::Connection _listnerConnection;
|
||||
};
|
||||
|
||||
}
|
||||
#endif // SETTINGSLISTNER_H
|
18
validableobject.cpp
Normal file
18
validableobject.cpp
Normal file
@ -0,0 +1,18 @@
|
||||
//#
|
||||
//# Copyright (C) 2022-2025 QuasarApp.
|
||||
//# Distributed under the GPLv3 software license, see the accompanying
|
||||
//# Everyone is permitted to copy and distribute verbatim copies
|
||||
//# of this license document, but changing it is not allowed.
|
||||
//#
|
||||
|
||||
|
||||
|
||||
#include "validableobject.h"
|
||||
|
||||
namespace QuasarAppUtils{
|
||||
|
||||
ValidableObject::ValidableObject()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
35
validableobject.h
Normal file
35
validableobject.h
Normal file
@ -0,0 +1,35 @@
|
||||
//#
|
||||
//# Copyright (C) 2022-2025 QuasarApp.
|
||||
//# Distributed under the GPLv3 software license, see the accompanying
|
||||
//# Everyone is permitted to copy and distribute verbatim copies
|
||||
//# of this license document, but changing it is not allowed.
|
||||
//#
|
||||
|
||||
|
||||
#ifndef VALIDABLEOBJECT_H
|
||||
#define VALIDABLEOBJECT_H
|
||||
|
||||
namespace QuasarAppUtils{
|
||||
|
||||
/**
|
||||
* @brief The ValidableObject class is Base interface for all object that can be checked to valid.
|
||||
*/
|
||||
class ValidableObject
|
||||
{
|
||||
public:
|
||||
ValidableObject();
|
||||
|
||||
/**
|
||||
* @brief isValid This method return true if the object is valid else false.
|
||||
* @return true if the object is valid else false.
|
||||
*/
|
||||
virtual bool isValid() const = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief iVO This is short abriviature of the ValidableObject class.
|
||||
*/
|
||||
typedef ValidableObject iVO;
|
||||
|
||||
}
|
||||
#endif // VALIDABLEOBJECT_H
|
Loading…
x
Reference in New Issue
Block a user