Compare commits
No commits in common. "b56425c671a08783084d46a7beaccfd01cd6454a" and "c40a4b3fe1257a17cb4d46e5fb7f7e9ab1df24a4" have entirely different histories.
b56425c671
...
c40a4b3fe1
45 changed files with 819 additions and 1711 deletions
|
@ -30,10 +30,7 @@ include(ECMPoQmTools)
|
||||||
|
|
||||||
kde_enable_exceptions()
|
kde_enable_exceptions()
|
||||||
|
|
||||||
set(CXXQT_QTCOMPONENTS Core Gui Qml QuickControls2 QuickTest Test)
|
find_package(Qt6 ${QT_MIN_VERSION} REQUIRED NO_MODULE COMPONENTS Core Core5Compat Quick Test Gui Qml QuickControls2 Widgets Sql QmlImportScanner WebEngineQuick)
|
||||||
set(CXXQT_QTCOMPONENTS ${CXXQT_QTCOMPONENTS} QmlImportScanner)
|
|
||||||
|
|
||||||
find_package(Qt6 ${QT_MIN_VERSION} REQUIRED NO_MODULE COMPONENTS Core Core5Compat Quick Test Gui Qml QuickControls2 Widgets Sql QmlImportScanner WebEngineQuick Multimedia)
|
|
||||||
find_package(KF6 ${KF_MIN_VERSION} REQUIRED COMPONENTS Kirigami CoreAddons I18n)
|
find_package(KF6 ${KF_MIN_VERSION} REQUIRED COMPONENTS Kirigami CoreAddons I18n)
|
||||||
|
|
||||||
# find_package(KF6FileMetaData ${KF6_MIN_VERSION})
|
# find_package(KF6FileMetaData ${KF6_MIN_VERSION})
|
||||||
|
@ -60,70 +57,45 @@ set_package_properties(Ytdlp PROPERTIES TYPE RUNTIME)
|
||||||
# execute_process(COMMAND ${XDG-DESKTOP-MENU_EXECUTABLE} install --novender librepresenter.desktop)
|
# execute_process(COMMAND ${XDG-DESKTOP-MENU_EXECUTABLE} install --novender librepresenter.desktop)
|
||||||
|
|
||||||
get_target_property(QMAKE Qt::qmake IMPORTED_LOCATION)
|
get_target_property(QMAKE Qt::qmake IMPORTED_LOCATION)
|
||||||
find_package(CxxQt QUIET)
|
find_package(Corrosion QUIET)
|
||||||
if(NOT CxxQt_FOUND)
|
if(NOT Corrosion_FOUND)
|
||||||
include(FetchContent)
|
include(FetchContent)
|
||||||
FetchContent_Declare(
|
FetchContent_Declare(
|
||||||
CxxQt
|
Corrosion
|
||||||
GIT_REPOSITORY https://github.com/kdab/cxx-qt-cmake.git
|
GIT_REPOSITORY https://github.com/corrosion-rs/corrosion.git
|
||||||
GIT_TAG v0.7.0
|
GIT_TAG v0.3.0
|
||||||
)
|
)
|
||||||
|
|
||||||
FetchContent_MakeAvailable(CxxQt)
|
FetchContent_MakeAvailable(Corrosion)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# find_package(Corrosion QUIET)
|
add_subdirectory(src)
|
||||||
# if(NOT Corrosion_FOUND)
|
|
||||||
# include(FetchContent)
|
|
||||||
# FetchContent_Declare(
|
|
||||||
# Corrosion
|
|
||||||
# GIT_REPOSITORY https://github.com/corrosion-rs/corrosion.git
|
|
||||||
# GIT_TAG v0.3.0
|
|
||||||
# )
|
|
||||||
|
|
||||||
# FetchContent_MakeAvailable(Corrosion)
|
|
||||||
# endif()
|
|
||||||
|
|
||||||
|
|
||||||
set(CRATE liblumina)
|
set(CRATE liblumina)
|
||||||
|
|
||||||
# CXX-Qt (using Corrosion) creates a CMake target with the same name as the crate.
|
|
||||||
cxx_qt_import_crate(
|
|
||||||
MANIFEST_PATH Cargo.toml
|
|
||||||
CRATES liblumina
|
|
||||||
QT_MODULES Qt::Core Qt::Gui Qt::Qml Qt::QuickControls2 Qt::WebEngineQuick)
|
|
||||||
|
|
||||||
cxx_qt_import_qml_module(liblumina_qml_module
|
|
||||||
URI "org.presenter"
|
|
||||||
SOURCE_CRATE liblumina)
|
|
||||||
|
|
||||||
|
|
||||||
# Corrosion creates a CMake target with the same name as the crate.
|
# Corrosion creates a CMake target with the same name as the crate.
|
||||||
# corrosion_import_crate(MANIFEST_PATH Cargo.toml CRATES ${CRATE})
|
corrosion_import_crate(MANIFEST_PATH Cargo.toml CRATES ${CRATE})
|
||||||
|
|
||||||
# The Rust library's build script needs to be told where to output the
|
# The Rust library's build script needs to be told where to output the
|
||||||
# generated headers so CMake can find them. To do this, tell Corrosion
|
# generated headers so CMake can find them. To do this, tell Corrosion
|
||||||
# to set the CXXQT_EXPORT_DIR environment variable when calling `cargo build`.
|
# to set the CXXQT_EXPORT_DIR environment variable when calling `cargo build`.
|
||||||
# Also, set the QMAKE environment variable to ensure the Rust library uses
|
# Also, set the QMAKE environment variable to ensure the Rust library uses
|
||||||
# the same installation of Qt as CMake.
|
# the same installation of Qt as CMake.
|
||||||
# set(CXXQT_EXPORT_DIR "${CMAKE_CURRENT_BINARY_DIR}/cxxqt")
|
set(CXXQT_EXPORT_DIR "${CMAKE_CURRENT_BINARY_DIR}/cxxqt")
|
||||||
# corrosion_set_env_vars(${CRATE}
|
corrosion_set_env_vars(${CRATE}
|
||||||
# "CXXQT_EXPORT_DIR=${CXXQT_EXPORT_DIR}"
|
"CXXQT_EXPORT_DIR=${CXXQT_EXPORT_DIR}"
|
||||||
# "QMAKE=${QMAKE}"
|
"QMAKE=${QMAKE}"
|
||||||
# )
|
)
|
||||||
|
|
||||||
add_subdirectory(src)
|
add_library(${APP_NAME}_lib INTERFACE)
|
||||||
# Include the headers generated by the Rust library's build script. Each
|
# Include the headers generated by the Rust library's build script. Each
|
||||||
# crate gets its own subdirectory under CXXQT_EXPORT_DIR. This allows you
|
# crate gets its own subdirectory under CXXQT_EXPORT_DIR. This allows you
|
||||||
# to include headers generated by multiple crates without risk of one crate
|
# to include headers generated by multiple crates without risk of one crate
|
||||||
# overwriting another's files.
|
# overwriting another's files.
|
||||||
target_include_directories(liblumina INTERFACE "${CXXQT_EXPORT_DIR}/${CRATE}")
|
target_include_directories(${APP_NAME}_lib INTERFACE "${CXXQT_EXPORT_DIR}/${CRATE}")
|
||||||
|
|
||||||
|
|
||||||
# Link the Rust INTERFACE library target to Qt. Do this on the library target
|
# Link the Rust INTERFACE library target to Qt. Do this on the library target
|
||||||
# rather than the main executable. This way, CMake targets besides the main
|
# rather than the main executable. This way, CMake targets besides the main
|
||||||
# executable which link the Rust library, for example tests, will also link Qt.
|
# executable which link the Rust library, for example tests, will also link Qt.
|
||||||
target_link_libraries(liblumina INTERFACE
|
target_link_libraries(${APP_NAME}_lib INTERFACE
|
||||||
"$<LINK_LIBRARY:WHOLE_ARCHIVE,${CRATE}-static>"
|
"$<LINK_LIBRARY:WHOLE_ARCHIVE,${CRATE}-static>"
|
||||||
Qt6::Quick
|
Qt6::Quick
|
||||||
Qt6::Qml
|
Qt6::Qml
|
||||||
|
@ -132,7 +104,6 @@ target_link_libraries(liblumina INTERFACE
|
||||||
Qt6::Widgets
|
Qt6::Widgets
|
||||||
Qt6::Sql
|
Qt6::Sql
|
||||||
Qt6::WebEngineQuick
|
Qt6::WebEngineQuick
|
||||||
Qt6::Multimedia
|
|
||||||
KF6::Kirigami
|
KF6::Kirigami
|
||||||
KF6::I18n
|
KF6::I18n
|
||||||
KF6::CoreAddons
|
KF6::CoreAddons
|
||||||
|
@ -143,9 +114,8 @@ target_link_libraries(liblumina INTERFACE
|
||||||
crypto
|
crypto
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
# Link to the Rust library
|
# Link to the Rust library
|
||||||
target_link_libraries(${APP_NAME} PRIVATE liblumina)
|
target_link_libraries(${APP_NAME} PRIVATE ${APP_NAME}_lib)
|
||||||
|
|
||||||
# If we are using a statically linked Qt then we need to import any qml plugins
|
# If we are using a statically linked Qt then we need to import any qml plugins
|
||||||
qt_import_qml_plugins(${APP_NAME})
|
qt_import_qml_plugins(${APP_NAME})
|
||||||
|
|
159
Cargo.lock
generated
159
Cargo.lock
generated
|
@ -1,6 +1,6 @@
|
||||||
# This file is automatically @generated by Cargo.
|
# This file is automatically @generated by Cargo.
|
||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
version = 4
|
version = 3
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "addr2line"
|
name = "addr2line"
|
||||||
|
@ -338,19 +338,6 @@ dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "blah"
|
|
||||||
version = "0.1.0"
|
|
||||||
dependencies = [
|
|
||||||
"cxx",
|
|
||||||
"cxx-qt",
|
|
||||||
"cxx-qt-build",
|
|
||||||
"cxx-qt-lib",
|
|
||||||
"cxx-qt-lib-extras",
|
|
||||||
"markdown",
|
|
||||||
"qt-build-utils",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "block"
|
name = "block"
|
||||||
version = "0.1.6"
|
version = "0.1.6"
|
||||||
|
@ -503,6 +490,32 @@ dependencies = [
|
||||||
"unicode-segmentation",
|
"unicode-segmentation",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "core"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"color-eyre",
|
||||||
|
"configparser",
|
||||||
|
"dirs",
|
||||||
|
"fastrand 2.1.1",
|
||||||
|
"obws",
|
||||||
|
"pretty_assertions",
|
||||||
|
"quote",
|
||||||
|
"reqwest",
|
||||||
|
"rfd",
|
||||||
|
"serde",
|
||||||
|
"serde_derive",
|
||||||
|
"serde_json",
|
||||||
|
"sqlx",
|
||||||
|
"tar",
|
||||||
|
"time",
|
||||||
|
"tokio",
|
||||||
|
"tracing",
|
||||||
|
"tracing-subscriber",
|
||||||
|
"youtube_dl",
|
||||||
|
"zstd",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "core-foundation"
|
name = "core-foundation"
|
||||||
version = "0.9.4"
|
version = "0.9.4"
|
||||||
|
@ -580,6 +593,21 @@ dependencies = [
|
||||||
"link-cplusplus",
|
"link-cplusplus",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cxx-build"
|
||||||
|
version = "1.0.128"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c77953e99f01508f89f55c494bfa867171ef3a6c8cea03d26975368f2121a5c1"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
"codespan-reporting",
|
||||||
|
"once_cell",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"scratch",
|
||||||
|
"syn 2.0.77",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cxx-gen"
|
name = "cxx-gen"
|
||||||
version = "0.7.128"
|
version = "0.7.128"
|
||||||
|
@ -594,41 +622,38 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cxx-qt"
|
name = "cxx-qt"
|
||||||
version = "0.7.1"
|
version = "0.6.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "208ad6c4feac92f221fde00796f317b049ba1892b97be0d60ca177d0d3469fc5"
|
checksum = "08aa6cda7588b6d17c563b0d2fadc060d4204d04908c0f359ae288857091218d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cxx",
|
"cxx",
|
||||||
"cxx-qt-build",
|
|
||||||
"cxx-qt-macro",
|
"cxx-qt-macro",
|
||||||
"qt-build-utils",
|
|
||||||
"static_assertions",
|
"static_assertions",
|
||||||
"thiserror",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cxx-qt-build"
|
name = "cxx-qt-build"
|
||||||
version = "0.7.1"
|
version = "0.6.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "15f80e109aa68795486c70c302f6c2d921f00028b3b62038a4601efb5c585c1c"
|
checksum = "9e097b99f49792922a72a8ca35d9391762e48e63363d6998255be1f2ca1edf69"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc",
|
"cc",
|
||||||
"codespan-reporting",
|
"codespan-reporting",
|
||||||
|
"convert_case",
|
||||||
"cxx-gen",
|
"cxx-gen",
|
||||||
"cxx-qt-gen",
|
"cxx-qt-gen",
|
||||||
|
"cxx-qt-lib-headers",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"qt-build-utils",
|
"qt-build-utils",
|
||||||
"quote",
|
"quote",
|
||||||
"serde",
|
|
||||||
"serde_json",
|
|
||||||
"version_check",
|
"version_check",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cxx-qt-gen"
|
name = "cxx-qt-gen"
|
||||||
version = "0.7.1"
|
version = "0.6.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dc17d95ca9cc60c2f91f804a4e0ba6a3e1b8ed338c207a1bd8d176133e2fd05d"
|
checksum = "ede7c73dbfbcc234d8826919e257830c1789db2cac586546a87d2a82e3cbe5d5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clang-format",
|
"clang-format",
|
||||||
"convert_case",
|
"convert_case",
|
||||||
|
@ -640,33 +665,27 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cxx-qt-lib"
|
name = "cxx-qt-lib"
|
||||||
version = "0.7.1"
|
version = "0.6.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f116c5d982bbf3be707acf97f566802c30454d52ca319c745ed39a04834e8bc6"
|
checksum = "002f1a6119bcb7dfec67eb7c0803a7b1d595dc54610559faeac35133f22a5880"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cxx",
|
"cxx",
|
||||||
"cxx-qt",
|
"cxx-build",
|
||||||
"cxx-qt-build",
|
"cxx-qt-lib-headers",
|
||||||
"qt-build-utils",
|
"qt-build-utils",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cxx-qt-lib-extras"
|
name = "cxx-qt-lib-headers"
|
||||||
version = "0.7.1"
|
version = "0.6.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bbe1aaed6391a224d746e314104f33b4031138291ebd368170a2109b6008ace2"
|
checksum = "9abdeab6b77cfc5a53b724f3f62a37bcb5ac1423cccc2dba4c134f4273440b8c"
|
||||||
dependencies = [
|
|
||||||
"cxx",
|
|
||||||
"cxx-qt",
|
|
||||||
"cxx-qt-build",
|
|
||||||
"cxx-qt-lib",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cxx-qt-macro"
|
name = "cxx-qt-macro"
|
||||||
version = "0.7.1"
|
version = "0.6.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "58a4fe02c0604eda28c605792f5ba0d0251b4947f8f0fc43e55b61c06b2b8ec6"
|
checksum = "699e8a668c03b03419b084960d72eed253632bb16349b33fd0a0c893b61b664c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cxx-qt-gen",
|
"cxx-qt-gen",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
|
@ -1413,9 +1432,9 @@ checksum = "187674a687eed5fe42285b40c6291f9a01517d415fad1c3cbc6a9f778af7fcd4"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "itertools"
|
name = "itertools"
|
||||||
version = "0.13.0"
|
version = "0.11.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186"
|
checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"either",
|
"either",
|
||||||
]
|
]
|
||||||
|
@ -1471,7 +1490,6 @@ dependencies = [
|
||||||
"cxx-qt-lib",
|
"cxx-qt-lib",
|
||||||
"dirs",
|
"dirs",
|
||||||
"fastrand 2.1.1",
|
"fastrand 2.1.1",
|
||||||
"lumina_core",
|
|
||||||
"obws",
|
"obws",
|
||||||
"qt-build-utils",
|
"qt-build-utils",
|
||||||
"quote",
|
"quote",
|
||||||
|
@ -1555,32 +1573,6 @@ version = "0.4.22"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
|
checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "lumina_core"
|
|
||||||
version = "0.1.0"
|
|
||||||
dependencies = [
|
|
||||||
"color-eyre",
|
|
||||||
"configparser",
|
|
||||||
"dirs",
|
|
||||||
"fastrand 2.1.1",
|
|
||||||
"obws",
|
|
||||||
"pretty_assertions",
|
|
||||||
"quote",
|
|
||||||
"reqwest",
|
|
||||||
"rfd",
|
|
||||||
"serde",
|
|
||||||
"serde_derive",
|
|
||||||
"serde_json",
|
|
||||||
"sqlx",
|
|
||||||
"tar",
|
|
||||||
"time",
|
|
||||||
"tokio",
|
|
||||||
"tracing",
|
|
||||||
"tracing-subscriber",
|
|
||||||
"youtube_dl",
|
|
||||||
"zstd",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "malloc_buf"
|
name = "malloc_buf"
|
||||||
version = "0.0.6"
|
version = "0.0.6"
|
||||||
|
@ -1590,15 +1582,6 @@ dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "markdown"
|
|
||||||
version = "1.0.0-alpha.17"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "21e27d6220ce21f80ce5c4201f23a37c6f1ad037c72c9d1ff215c2919605a5d6"
|
|
||||||
dependencies = [
|
|
||||||
"unicode-id",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "matchers"
|
name = "matchers"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
@ -2109,9 +2092,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "qt-build-utils"
|
name = "qt-build-utils"
|
||||||
version = "0.7.1"
|
version = "0.6.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "efb239fdd8c036fabb95364320041ef68197cd4ab971bb3b4ca3ea0b7b93d12c"
|
checksum = "d59c828fe2434dad34dd0c30a4ba037509b61dad92a55baf0dc42699e6aa2f10"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc",
|
"cc",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
|
@ -2381,6 +2364,12 @@ version = "1.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "scratch"
|
||||||
|
version = "1.0.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a3cf7c11c38cb994f3d40e8a8cde3bbd1f72a435e4c49e85d6553d8312306152"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "security-framework"
|
name = "security-framework"
|
||||||
version = "2.11.1"
|
version = "2.11.1"
|
||||||
|
@ -3223,12 +3212,6 @@ version = "0.3.15"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75"
|
checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "unicode-id"
|
|
||||||
version = "0.3.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "10103c57044730945224467c09f71a4db0071c123a0648cc3e818913bde6b561"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-ident"
|
name = "unicode-ident"
|
||||||
version = "1.0.12"
|
version = "1.0.12"
|
||||||
|
@ -3321,9 +3304,9 @@ checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "versions"
|
name = "versions"
|
||||||
version = "6.3.2"
|
version = "5.0.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f25d498b63d1fdb376b4250f39ab3a5ee8d103957346abacd911e2d8b612c139"
|
checksum = "c73a36bc44e3039f51fbee93e39f41225f6b17b380eb70cc2aab942df06b34dd"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"itertools",
|
"itertools",
|
||||||
"nom",
|
"nom",
|
||||||
|
|
11
Cargo.toml
11
Cargo.toml
|
@ -1,5 +1,5 @@
|
||||||
[workspace]
|
[workspace]
|
||||||
members = [ "smdview/blah","src/rust/core"]
|
members = ["src/rust/core"]
|
||||||
|
|
||||||
[package]
|
[package]
|
||||||
name = "liblumina"
|
name = "liblumina"
|
||||||
|
@ -21,14 +21,13 @@ path = "src/rust/lib.rs"
|
||||||
# path = "src/rust/main.rs"
|
# path = "src/rust/main.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
lumina_core = { path = "src/rust/core" }
|
|
||||||
configparser = "3.0.2"
|
configparser = "3.0.2"
|
||||||
serde = "1.0.152"
|
serde = "1.0.152"
|
||||||
serde_derive = "1.0.152"
|
serde_derive = "1.0.152"
|
||||||
quote = "1.0.27"
|
quote = "1.0.27"
|
||||||
cxx = "1.0.83"
|
cxx = "1.0.83"
|
||||||
cxx-qt = "0.7.1"
|
cxx-qt = "0.6.1"
|
||||||
cxx-qt-lib = { version = "0.7.1", features = [ "qt_full" ] }
|
cxx-qt-lib = "0.6.1"
|
||||||
# home = "0.5.4"
|
# home = "0.5.4"
|
||||||
dirs = "5.0.0"
|
dirs = "5.0.0"
|
||||||
# libsqlite3-sys = { version = ">=0.17.2", features = ["bundled"] }
|
# libsqlite3-sys = { version = ">=0.17.2", features = ["bundled"] }
|
||||||
|
@ -51,8 +50,8 @@ color-eyre = "0.6.3"
|
||||||
# cxx-qt-build generates C++ code from the `#[cxx_qt::bridge]` module
|
# cxx-qt-build generates C++ code from the `#[cxx_qt::bridge]` module
|
||||||
# and compiles it together with the Rust static library
|
# and compiles it together with the Rust static library
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
cxx-qt-build = { version = "0.7.1", features = [ "link_qt_object_files" ] }
|
cxx-qt-build = { version = "0.6.1", features = [ "link_qt_object_files" ] }
|
||||||
qt-build-utils = "0.7.1"
|
qt-build-utils = "0.6.1"
|
||||||
|
|
||||||
# [dependencies.confy]
|
# [dependencies.confy]
|
||||||
# features = ["yaml_conf"]
|
# features = ["yaml_conf"]
|
||||||
|
|
3
TODO.org
3
TODO.org
|
@ -4,8 +4,7 @@
|
||||||
:CATEGORY: dev
|
:CATEGORY: dev
|
||||||
:END:
|
:END:
|
||||||
|
|
||||||
* Tasks [63%] [55/87]
|
* Tasks [63%] [55/86]
|
||||||
** TODO [#A] REWRITE FOR ALL RUST AND BUILD WITH CARGO
|
|
||||||
** TODO [#A] Plugin architecture with steel or some scheme as an extension language
|
** TODO [#A] Plugin architecture with steel or some scheme as an extension language
|
||||||
** TODO [#A] Server client architecture
|
** TODO [#A] Server client architecture
|
||||||
** TODO [#A] Organize and layout structure of rust code :maintenance:
|
** TODO [#A] Organize and layout structure of rust code :maintenance:
|
||||||
|
|
88
build.rs
88
build.rs
|
@ -1,5 +1,3 @@
|
||||||
use std::{env, path::PathBuf};
|
|
||||||
|
|
||||||
use cxx_qt_build::{CxxQtBuilder, QmlModule};
|
use cxx_qt_build::{CxxQtBuilder, QmlModule};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
@ -19,37 +17,6 @@ fn main() {
|
||||||
.file("src/rust/obs.rs")
|
.file("src/rust/obs.rs")
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
// let mut kde_include_dir = String::from("/usr/include/");
|
|
||||||
// let mut kde_lib_dir = String::from("/usr/lib/x86_64-linux-gnu/");
|
|
||||||
|
|
||||||
// if let Ok(mut include_dir) = env::var("CMAKE_INCLUDE_PATH") {
|
|
||||||
// println!("{}", include_dir);
|
|
||||||
// if let Some(include_dir) =
|
|
||||||
// include_dir.split(":").find(|s| s.contains("ki18n"))
|
|
||||||
// {
|
|
||||||
// kde_include_dir = include_dir.to_owned();
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// println!(
|
|
||||||
// "cargo:warning=KDE_INCLUDEDIR is not defined, used default value: {}",
|
|
||||||
// kde_include_dir
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
// if let Ok(lib_dir) = env::var("KDE_LIBDIR") {
|
|
||||||
// kde_lib_dir = lib_dir;
|
|
||||||
// } else {
|
|
||||||
// println!(
|
|
||||||
// "cargo:warning=KDE_LIBDIR is not defined, used default value: {}",
|
|
||||||
// kde_lib_dir
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
|
|
||||||
// let ki18n_include_path = PathBuf::from(kde_include_dir)
|
|
||||||
// .canonicalize()
|
|
||||||
// .expect("Cannot get canonical path of KDE_INCLUDEDIR")
|
|
||||||
// .join("KF6")
|
|
||||||
// .join("KI18n");
|
|
||||||
|
|
||||||
// CxxQtBuilder::new()
|
// CxxQtBuilder::new()
|
||||||
// // Link Qt's Network library
|
// // Link Qt's Network library
|
||||||
// // - Qt Core is always linked
|
// // - Qt Core is always linked
|
||||||
|
@ -60,64 +27,13 @@ fn main() {
|
||||||
// // .qt_module("Kirigami")
|
// // .qt_module("Kirigami")
|
||||||
// // .qt_module("WebEngineQuick")
|
// // .qt_module("WebEngineQuick")
|
||||||
// .qt_module("Network")
|
// .qt_module("Network")
|
||||||
// // .qt_module("Quick")
|
|
||||||
// // .qt_module("Test")
|
|
||||||
// // .qt_module("WebEngineQuick")
|
|
||||||
// // .qt_module("I18n")
|
// // .qt_module("I18n")
|
||||||
// // .qt_module("CoreAddons")
|
// // .qt_module("CoreAddons")
|
||||||
// .qml_module(QmlModule {
|
// .qml_module(QmlModule {
|
||||||
// uri: "com.cochrun.xyz",
|
// uri: "com.cochrun.xyz",
|
||||||
// rust_files: &[
|
// rust_files: &["src/rust/settings.rs"],
|
||||||
// "src/rust/settings.rs",
|
// qml_files: &["src/qml/main.qml"],
|
||||||
// "src/rust/service_item_model.rs",
|
|
||||||
// "src/rust/file_helper.rs",
|
|
||||||
// "src/rust/slide_model.rs",
|
|
||||||
// "src/rust/slide_object.rs",
|
|
||||||
// "src/rust/ytdl.rs",
|
|
||||||
// "src/rust/utils.rs",
|
|
||||||
// "src/rust/obs.rs",
|
|
||||||
// "src/rust/video_model.rs",
|
|
||||||
// "src/rust/image_model.rs",
|
|
||||||
// "src/rust/presentation_model.rs",
|
|
||||||
// // "src/rust/songs/song_model.rs",
|
|
||||||
// // "src/rust/songs/song_editor.rs",
|
|
||||||
// ],
|
|
||||||
// qrc_files: &["src/resources.qrc"],
|
|
||||||
// qml_files: &[
|
|
||||||
// "src/qml/main.qml",
|
|
||||||
// "src/qml/presenter/LeftDock.qml",
|
|
||||||
// "src/qml/presenter/ServiceList.qml",
|
|
||||||
// "src/qml/presenter/MainWindow.qml",
|
|
||||||
// "src/qml/presenter/Library.qml",
|
|
||||||
// "src/qml/presenter/LibraryItem.qml",
|
|
||||||
// "src/qml/presenter/Header.qml",
|
|
||||||
// "src/qml/presenter/Actions.qml",
|
|
||||||
// "src/qml/presenter/PanelItem.qml",
|
|
||||||
// "src/qml/presenter/SongEditor.qml",
|
|
||||||
// "src/qml/presenter/VideoEditor.qml",
|
|
||||||
// "src/qml/presenter/ImageEditor.qml",
|
|
||||||
// "src/qml/presenter/PresentationEditor.qml",
|
|
||||||
// "src/qml/presenter/SlideEditor.qml",
|
|
||||||
// "src/qml/presenter/Slide.qml",
|
|
||||||
// "src/qml/presenter/SlidesListView.qml",
|
|
||||||
// "src/qml/presenter/SongEditorSlideList.qml",
|
|
||||||
// "src/qml/presenter/DragHandle.qml",
|
|
||||||
// "src/qml/presenter/Presentation.qml",
|
|
||||||
// "src/qml/presenter/PresentationWindow.qml",
|
|
||||||
// "src/qml/presenter/PreviewSlideListDelegate.qml",
|
|
||||||
// "src/qml/presenter/PreviewSlide.qml",
|
|
||||||
// "src/qml/presenter/Settings.qml",
|
|
||||||
// "src/qml/presenter/RangedSlider.qml",
|
|
||||||
// "src/qml/presenter/NewVideo.qml",
|
|
||||||
// "src/qml/presenter/TextBackground.qml",
|
|
||||||
// "src/qml/presenter/TextBox.qml",
|
|
||||||
// "src/qml/presenter/LoadingSpinner.qml",
|
|
||||||
// ],
|
|
||||||
// ..Default::default()
|
// ..Default::default()
|
||||||
// })
|
// })
|
||||||
// .cc_builder(|cc| {
|
|
||||||
// cc.include("cpp");
|
|
||||||
// cc.include(format!("{}", ki18n_include_path.display()));
|
|
||||||
// })
|
|
||||||
// .build();
|
// .build();
|
||||||
}
|
}
|
||||||
|
|
131
flake.lock
generated
131
flake.lock
generated
|
@ -1,56 +1,15 @@
|
||||||
{
|
{
|
||||||
"nodes": {
|
"nodes": {
|
||||||
"fenix": {
|
|
||||||
"inputs": {
|
|
||||||
"nixpkgs": "nixpkgs",
|
|
||||||
"rust-analyzer-src": "rust-analyzer-src"
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1753252982,
|
|
||||||
"narHash": "sha256-brrpvP+4GRXLHjvnDr1j1/yA4117hzs6t9IT60JuSI8=",
|
|
||||||
"owner": "nix-community",
|
|
||||||
"repo": "fenix",
|
|
||||||
"rev": "8546562a84feb5370ce57493277b6f2c3cbdc432",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "nix-community",
|
|
||||||
"repo": "fenix",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"fenix_2": {
|
|
||||||
"inputs": {
|
|
||||||
"nixpkgs": [
|
|
||||||
"naersk",
|
|
||||||
"nixpkgs"
|
|
||||||
],
|
|
||||||
"rust-analyzer-src": "rust-analyzer-src_2"
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1752475459,
|
|
||||||
"narHash": "sha256-z6QEu4ZFuHiqdOPbYss4/Q8B0BFhacR8ts6jO/F/aOU=",
|
|
||||||
"owner": "nix-community",
|
|
||||||
"repo": "fenix",
|
|
||||||
"rev": "bf0d6f70f4c9a9cf8845f992105652173f4b617f",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "nix-community",
|
|
||||||
"repo": "fenix",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"flake-utils": {
|
"flake-utils": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"systems": "systems"
|
"systems": "systems"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1731533236,
|
"lastModified": 1710146030,
|
||||||
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
|
"narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
|
||||||
"owner": "numtide",
|
"owner": "numtide",
|
||||||
"repo": "flake-utils",
|
"repo": "flake-utils",
|
||||||
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
|
"rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -61,15 +20,14 @@
|
||||||
},
|
},
|
||||||
"naersk": {
|
"naersk": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"fenix": "fenix_2",
|
"nixpkgs": "nixpkgs"
|
||||||
"nixpkgs": "nixpkgs_2"
|
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1752689277,
|
"lastModified": 1721727458,
|
||||||
"narHash": "sha256-uldUBFkZe/E7qbvxa3mH1ItrWZyT6w1dBKJQF/3ZSsc=",
|
"narHash": "sha256-r/xppY958gmZ4oTfLiHN0ZGuQ+RSTijDblVgVLFi1mw=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "naersk",
|
"repo": "naersk",
|
||||||
"rev": "0e72363d0938b0208d6c646d10649164c43f4d64",
|
"rev": "3fb418eaf352498f6b6c30592e3beb63df42ef11",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -80,43 +38,23 @@
|
||||||
},
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1752950548,
|
"lastModified": 0,
|
||||||
"narHash": "sha256-NS6BLD0lxOrnCiEOcvQCDVPXafX1/ek1dfJHX1nUIzc=",
|
"narHash": "sha256-+yj+xgsfZaErbfYM3T+QvEE2hU7UuE+Jf0fJCJ8uPS0=",
|
||||||
"owner": "nixos",
|
"path": "/nix/store/6inj491lsap4ia7mmvn2gbh53jb27zq0-source",
|
||||||
"repo": "nixpkgs",
|
"type": "path"
|
||||||
"rev": "c87b95e25065c028d31a94f06a62927d18763fdf",
|
|
||||||
"type": "github"
|
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"owner": "nixos",
|
"id": "nixpkgs",
|
||||||
"ref": "nixos-unstable",
|
"type": "indirect"
|
||||||
"repo": "nixpkgs",
|
|
||||||
"type": "github"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nixpkgs_2": {
|
"nixpkgs_2": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1752077645,
|
"lastModified": 1725634671,
|
||||||
"narHash": "sha256-HM791ZQtXV93xtCY+ZxG1REzhQenSQO020cu6rHtAPk=",
|
"narHash": "sha256-v3rIhsJBOMLR8e/RNWxr828tB+WywYIoajrZKFM+0Gg=",
|
||||||
"owner": "NixOS",
|
|
||||||
"repo": "nixpkgs",
|
|
||||||
"rev": "be9e214982e20b8310878ac2baa063a961c1bdf6",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "NixOS",
|
|
||||||
"ref": "nixpkgs-unstable",
|
|
||||||
"repo": "nixpkgs",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"nixpkgs_3": {
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1752950548,
|
|
||||||
"narHash": "sha256-NS6BLD0lxOrnCiEOcvQCDVPXafX1/ek1dfJHX1nUIzc=",
|
|
||||||
"owner": "nixos",
|
"owner": "nixos",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "c87b95e25065c028d31a94f06a62927d18763fdf",
|
"rev": "574d1eac1c200690e27b8eb4e24887f8df7ac27c",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
@ -128,44 +66,9 @@
|
||||||
},
|
},
|
||||||
"root": {
|
"root": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"fenix": "fenix",
|
|
||||||
"flake-utils": "flake-utils",
|
"flake-utils": "flake-utils",
|
||||||
"naersk": "naersk",
|
"naersk": "naersk",
|
||||||
"nixpkgs": "nixpkgs_3"
|
"nixpkgs": "nixpkgs_2"
|
||||||
}
|
|
||||||
},
|
|
||||||
"rust-analyzer-src": {
|
|
||||||
"flake": false,
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1753204114,
|
|
||||||
"narHash": "sha256-xH8EIod+Hwog4P9OwX9hdtk6Nqr54M0tzMI71yGNOYI=",
|
|
||||||
"owner": "rust-lang",
|
|
||||||
"repo": "rust-analyzer",
|
|
||||||
"rev": "b40fce3ccdc5f94453c6aca4da8b64174a03a5ad",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "rust-lang",
|
|
||||||
"ref": "nightly",
|
|
||||||
"repo": "rust-analyzer",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"rust-analyzer-src_2": {
|
|
||||||
"flake": false,
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1752428706,
|
|
||||||
"narHash": "sha256-EJcdxw3aXfP8Ex1Nm3s0awyH9egQvB2Gu+QEnJn2Sfg=",
|
|
||||||
"owner": "rust-lang",
|
|
||||||
"repo": "rust-analyzer",
|
|
||||||
"rev": "591e3b7624be97e4443ea7b5542c191311aa141d",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "rust-lang",
|
|
||||||
"ref": "nightly",
|
|
||||||
"repo": "rust-analyzer",
|
|
||||||
"type": "github"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"systems": {
|
"systems": {
|
||||||
|
|
180
flake.nix
180
flake.nix
|
@ -6,121 +6,77 @@
|
||||||
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
|
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
|
||||||
naersk.url = "github:nix-community/naersk";
|
naersk.url = "github:nix-community/naersk";
|
||||||
flake-utils.url = "github:numtide/flake-utils";
|
flake-utils.url = "github:numtide/flake-utils";
|
||||||
fenix.url = "github:nix-community/fenix";
|
|
||||||
# nixpkgs.follows = "cargo2nix/nixpkgs";
|
# nixpkgs.follows = "cargo2nix/nixpkgs";
|
||||||
};
|
};
|
||||||
|
|
||||||
outputs = inputs:
|
outputs = inputs: with inputs;
|
||||||
with inputs;
|
flake-utils.lib.eachDefaultSystem
|
||||||
flake-utils.lib.eachDefaultSystem (system:
|
(system:
|
||||||
let
|
let
|
||||||
pkgs = import nixpkgs {
|
pkgs = import nixpkgs {
|
||||||
inherit system;
|
inherit system;
|
||||||
overlays = [ fenix.overlays.default ];
|
# overlays = [cargo2nix.overlays.default];
|
||||||
# overlays = [cargo2nix.overlays.default];
|
};
|
||||||
};
|
naersk' = pkgs.callPackage naersk {};
|
||||||
naersk' = pkgs.callPackage naersk { };
|
# src = ./.;
|
||||||
|
# rustPkgs = pkgs.rustBuilder.makePackageSet {
|
||||||
|
# rustVersion = "1.61.0";
|
||||||
|
# packageFun = import ./Cargo.nix;
|
||||||
|
# };
|
||||||
|
# The workspace defines a development shell with all of the dependencies
|
||||||
|
# and environment settings necessary for a regular `cargo build`.
|
||||||
|
# Passes through all arguments to pkgs.mkShell for adding supplemental
|
||||||
|
# dependencies.
|
||||||
|
# workspaceShell = rustPkgs.workspaceShell {
|
||||||
|
# packages = with pkgs; [
|
||||||
|
# gcc
|
||||||
|
# stdenv
|
||||||
|
# bintools
|
||||||
|
# gnumake
|
||||||
|
# gdb
|
||||||
|
# qtcreator
|
||||||
|
# cmake
|
||||||
|
# extra-cmake-modules
|
||||||
|
# pkg-config
|
||||||
|
# libsForQt5.wrapQtAppsHook
|
||||||
|
# makeWrapper
|
||||||
|
|
||||||
nbi = with pkgs; [
|
# clang-tools
|
||||||
# ffmpeg
|
# clang
|
||||||
alejandra
|
# libclang
|
||||||
(pkgs.fenix.stable.withComponents [
|
# qt5.qtbase
|
||||||
"cargo"
|
# qt5.qttools
|
||||||
"clippy"
|
# qt5.qtquickcontrols2
|
||||||
"rust-src"
|
# qt5.qtx11extras
|
||||||
"rustc"
|
# qt5.qtmultimedia
|
||||||
"rustfmt"
|
# qt5.qtwayland
|
||||||
])
|
# qt5.qtwebengine
|
||||||
rust-analyzer
|
# libsForQt5.kirigami2
|
||||||
];
|
# libsForQt5.qqc2-desktop-style
|
||||||
|
# libsForQt5.karchive
|
||||||
|
# mpv
|
||||||
|
# ffmpeg_6-full
|
||||||
|
# # Rust tools
|
||||||
|
# clippy
|
||||||
|
# rustc
|
||||||
|
# cargo
|
||||||
|
# rustfmt
|
||||||
|
# rust-analyzer
|
||||||
|
# corrosion
|
||||||
|
# ];
|
||||||
|
# # shellHook = ''
|
||||||
|
# # export PS1="\033[0;31m☠dev-shell☠ $ \033[0m"
|
||||||
|
# # '';
|
||||||
|
# };
|
||||||
|
|
||||||
bi = with pkgs; [
|
in rec
|
||||||
gcc
|
{
|
||||||
stdenv
|
# packages = {
|
||||||
gnumake
|
# crate = (rustPkgs.workspace.libre-presenter { }).bin;
|
||||||
gdb
|
# default = packages.crate;
|
||||||
qtcreator
|
# };
|
||||||
cmake
|
devShell = import ./shell.nix { inherit pkgs; };
|
||||||
kdePackages.extra-cmake-modules
|
defaultPackage = pkgs.libsForQt5.callPackage ./default.nix { };
|
||||||
pkg-config
|
}
|
||||||
qt6.wrapQtAppsHook
|
);
|
||||||
makeWrapper
|
|
||||||
|
|
||||||
openssl.dev
|
|
||||||
openssl.out
|
|
||||||
|
|
||||||
clang-tools
|
|
||||||
clang
|
|
||||||
libclang
|
|
||||||
# libwebp
|
|
||||||
# clang-format
|
|
||||||
qt6.full
|
|
||||||
qt6.qttools
|
|
||||||
qt6.qtbase
|
|
||||||
# qt6.qtquickcontrols2
|
|
||||||
# qt6.qtx11extras
|
|
||||||
qt6.qtmultimedia
|
|
||||||
qt6.qtwayland
|
|
||||||
qt6.qtwebengine
|
|
||||||
qt6.qtimageformats
|
|
||||||
kdePackages.kirigami
|
|
||||||
# kdePackages.kfilemetadata
|
|
||||||
# libsForQt5.breeze-icons
|
|
||||||
# libsForQt5.breeze-qt5
|
|
||||||
kdePackages.qqc2-desktop-style
|
|
||||||
# libsForQt5.kirigami-addons
|
|
||||||
# libsForQt5.ki18n
|
|
||||||
kdePackages.kcoreaddons
|
|
||||||
# libsForQt5.kguiaddons
|
|
||||||
# libsForQt5.kconfig
|
|
||||||
|
|
||||||
# podofo
|
|
||||||
mpv
|
|
||||||
kdePackages.mpvqt
|
|
||||||
ffmpeg-full
|
|
||||||
# yt-dlp
|
|
||||||
|
|
||||||
# Rust tools
|
|
||||||
just
|
|
||||||
clippy
|
|
||||||
rustc
|
|
||||||
cargo
|
|
||||||
rustfmt
|
|
||||||
rust-analyzer
|
|
||||||
sqlx-cli
|
|
||||||
cargo-watch
|
|
||||||
corrosion
|
|
||||||
];
|
|
||||||
|
|
||||||
in rec {
|
|
||||||
# packages = {
|
|
||||||
# crate = (rustPkgs.workspace.libre-presenter { }).bin;
|
|
||||||
# default = packages.crate;
|
|
||||||
# };
|
|
||||||
devShell = pkgs.mkShell {
|
|
||||||
nativeBuildInputs = nbi;
|
|
||||||
buildInputs = bi;
|
|
||||||
|
|
||||||
RUST_BACKTRACE = "1";
|
|
||||||
LIBCLANG_PATH = "${pkgs.llvmPackages.libclang.lib}/lib";
|
|
||||||
CMAKE_C_COMPILER = "${pkgs.gcc}/bin/gcc";
|
|
||||||
CMAKE_CXX_COMPILER = "${pkgs.gcc}/bin/g++";
|
|
||||||
CARGO_PROFILE_RELEASE_BUILD_OVERRIDE_DEBUG = true;
|
|
||||||
# KDE_INCLUDEDIR = "${pkgs.kdePackages.kirigami.dev}/include";
|
|
||||||
# KDE_QMLDIR = "${pkgs.kdePackages.kirigami.dev}/lib/qt-6/qml/org/kde/kirigami/";
|
|
||||||
|
|
||||||
# This creates the proper qt env so that plugins are found right.
|
|
||||||
shellHook = ''
|
|
||||||
setQtEnvironment=$(mktemp --suffix .setQtEnvironment.sh)
|
|
||||||
echo "shellHook: setQtEnvironment = $setQtEnvironment"
|
|
||||||
makeQtWrapper "/bin/sh" "$setQtEnvironment" "''${qtWrapperArgs[@]}"
|
|
||||||
sed "/^exec/d" -i "$setQtEnvironment"
|
|
||||||
source "$setQtEnvironment"
|
|
||||||
'';
|
|
||||||
DATABASE_URL =
|
|
||||||
"sqlite:///home/chris/.local/share/lumina/library-db.sqlite3";
|
|
||||||
};
|
|
||||||
# devShell = import ./shell.nix { inherit pkgs; };
|
|
||||||
# defaultPackage = pkgs.libsForQt5.callPackage ./default.nix { };
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
2
justfile
2
justfile
|
@ -15,7 +15,7 @@ test:
|
||||||
RUST_LOG=debug cargo test --benches --tests --all-features -- --nocapture
|
RUST_LOG=debug cargo test --benches --tests --all-features -- --nocapture
|
||||||
|
|
||||||
testcore:
|
testcore:
|
||||||
RUST_LOG=debug cargo test -p lumina_core --benches --tests --all-features -- --nocapture
|
RUST_LOG=debug cargo test -p core --benches --tests --all-features -- --nocapture
|
||||||
|
|
||||||
alias b := build
|
alias b := build
|
||||||
alias r := run
|
alias r := run
|
||||||
|
|
|
@ -1,17 +0,0 @@
|
||||||
[package]
|
|
||||||
name = "blah"
|
|
||||||
version = "0.1.0"
|
|
||||||
edition = "2024"
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
cxx = "1.0.122"
|
|
||||||
cxx-qt = "0.7.1"
|
|
||||||
cxx-qt-lib = { version = "0.7.1", features = [ "qt_full" ] }
|
|
||||||
cxx-qt-lib-extras = "0.7.1"
|
|
||||||
markdown = "=1.0.0-alpha.17"
|
|
||||||
|
|
||||||
[build-dependencies]
|
|
||||||
# The link_qt_object_files feature is required for statically linking Qt 6.
|
|
||||||
cxx-qt-build = { version = "0.7.1", features = [ "link_qt_object_files" ] }
|
|
||||||
qt-build-utils = "0.7.1"
|
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
use cxx_qt_build::{CxxQtBuilder, QmlModule};
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
CxxQtBuilder::new()
|
|
||||||
.qml_module(QmlModule {
|
|
||||||
uri: "org.kde.simplemdviewer",
|
|
||||||
qml_files: &["src/qml/Main.qml"],
|
|
||||||
rust_files: &["src/main.rs"],
|
|
||||||
..Default::default()
|
|
||||||
})
|
|
||||||
.build();
|
|
||||||
}
|
|
|
@ -1,42 +0,0 @@
|
||||||
#[cxx_qt::bridge]
|
|
||||||
mod ffi {
|
|
||||||
extern "RustQt" {
|
|
||||||
#[qobject]
|
|
||||||
type DummyQObject = super::DummyRustStruct;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Default)]
|
|
||||||
pub struct DummyRustStruct;
|
|
||||||
|
|
||||||
use cxx_qt_lib::{
|
|
||||||
QGuiApplication, QQmlApplicationEngine, QQuickStyle, QString,
|
|
||||||
QUrl,
|
|
||||||
};
|
|
||||||
use cxx_qt_lib_extras::QApplication;
|
|
||||||
use std::env;
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let mut app = QApplication::new();
|
|
||||||
|
|
||||||
// To associate the executable to the installed desktop file
|
|
||||||
QGuiApplication::set_desktop_file_name(&QString::from(
|
|
||||||
"org.kde.simplemdviewer",
|
|
||||||
));
|
|
||||||
|
|
||||||
// To ensure the style is set correctly
|
|
||||||
if env::var("QT_QUICK_CONTROLS_STYLE").is_err() {
|
|
||||||
QQuickStyle::set_style(&QString::from("org.kde.desktop"));
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut engine = QQmlApplicationEngine::new();
|
|
||||||
if let Some(engine) = engine.as_mut() {
|
|
||||||
engine.load(&QUrl::from(
|
|
||||||
"qrc:/qt/qml/org/kde/simplemdviewer/src/qml/Main.qml",
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(app) = app.as_mut() {
|
|
||||||
app.exec();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,71 +0,0 @@
|
||||||
import QtQuick
|
|
||||||
import QtQuick.Layouts
|
|
||||||
import QtQuick.Controls as Controls
|
|
||||||
import org.kde.kirigami as Kirigami
|
|
||||||
|
|
||||||
Kirigami.ApplicationWindow {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
title: "Simple Markdown Viewer in Rust 🦀"
|
|
||||||
|
|
||||||
minimumWidth: Kirigami.Units.gridUnit * 20
|
|
||||||
minimumHeight: Kirigami.Units.gridUnit * 20
|
|
||||||
width: minimumWidth
|
|
||||||
height: minimumHeight
|
|
||||||
|
|
||||||
pageStack.initialPage: initPage
|
|
||||||
|
|
||||||
Component {
|
|
||||||
id: initPage
|
|
||||||
|
|
||||||
Kirigami.Page {
|
|
||||||
title: "Markdown Viewer"
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
anchors {
|
|
||||||
top: parent.top
|
|
||||||
left: parent.left
|
|
||||||
right: parent.right
|
|
||||||
}
|
|
||||||
Controls.TextArea {
|
|
||||||
id: sourceArea
|
|
||||||
|
|
||||||
placeholderText: "Write some Markdown code here"
|
|
||||||
wrapMode: Text.WrapAnywhere
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.minimumHeight: Kirigami.Units.gridUnit * 5
|
|
||||||
}
|
|
||||||
|
|
||||||
RowLayout {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
|
|
||||||
Controls.Button {
|
|
||||||
text: "Format"
|
|
||||||
|
|
||||||
onClicked: formattedText.text = sourceArea.text
|
|
||||||
}
|
|
||||||
|
|
||||||
Controls.Button {
|
|
||||||
text: "Clear"
|
|
||||||
|
|
||||||
onClicked: {
|
|
||||||
sourceArea.text = ""
|
|
||||||
formattedText.text = ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Controls.Label {
|
|
||||||
id: formattedText
|
|
||||||
|
|
||||||
textFormat: Text.RichText
|
|
||||||
wrapMode: Text.WordWrap
|
|
||||||
text: sourceArea.text
|
|
||||||
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.minimumHeight: Kirigami.Units.gridUnit * 5
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
101
src/main.cpp
101
src/main.cpp
|
@ -1,49 +1,49 @@
|
||||||
// #include <QApplication>
|
#include <QApplication>
|
||||||
#include <QtQml/QQmlApplicationEngine>
|
#include <QQmlApplicationEngine>
|
||||||
#include <QtCore/qstringliteral.h>
|
#include <QtCore/qstringliteral.h>
|
||||||
#include <QtQml/QtQml>
|
#include <QtQml>
|
||||||
#include <QtCore/QUrl>
|
#include <QUrl>
|
||||||
#include <QtCore/QDebug>
|
#include <QDebug>
|
||||||
// #include <K/KLocalizedContext>
|
#include <KLocalizedContext>
|
||||||
// #include <KLocalizedString>
|
#include <KLocalizedString>
|
||||||
// #include <KAboutData>
|
#include <KAboutData>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <QtQml/QQmlEngine>
|
#include <QQmlEngine>
|
||||||
#include <QtWebEngineQuick/QtWebEngineQuick>
|
#include <QtWebEngineQuick>
|
||||||
#include <QtCore/QObject>
|
#include <QObject>
|
||||||
#include <QtCore/QtGlobal>
|
#include <QtGlobal>
|
||||||
#include <QtGui/QOpenGLContext>
|
#include <QOpenGLContext>
|
||||||
#include <QtGui/QGuiApplication>
|
#include <QGuiApplication>
|
||||||
#include <QtQuickControls2/QQuickStyle>
|
#include <QQuickStyle>
|
||||||
// #include <QSurfaceFormat>
|
#include <QSurfaceFormat>
|
||||||
#include <QtQuick/QQuickWindow>
|
#include <QtQuick/QQuickWindow>
|
||||||
#include <QtQuick/QQuickView>
|
#include <QtQuick/QQuickView>
|
||||||
// #include <qapplication.h>
|
#include <qapplication.h>
|
||||||
#include <QtCore/qcoreapplication.h>
|
#include <qcoreapplication.h>
|
||||||
#include <QtCore/qdir.h>
|
#include <qdir.h>
|
||||||
#include <QtCore/qglobal.h>
|
#include <qglobal.h>
|
||||||
#include <QtGui/qguiapplication.h>
|
#include <qguiapplication.h>
|
||||||
#include <QtQml/qqml.h>
|
#include <qqml.h>
|
||||||
#include <QtQuickControls2/qquickstyle.h>
|
#include <qquickstyle.h>
|
||||||
#include <QtCore/qstringliteral.h>
|
#include <qstringliteral.h>
|
||||||
// #include <MpvAbstractItem>
|
// #include <MpvAbstractItem>
|
||||||
// #include "cpp/mpv/mpvitem.h"
|
// #include "cpp/mpv/mpvitem.h"
|
||||||
// #include "cpp/mpv/mpvproperties.h"
|
// #include "cpp/mpv/mpvproperties.h"
|
||||||
|
|
||||||
// RUST
|
// RUST
|
||||||
#include <liblumina/src/rust/file_helper.cxxqt.h>
|
#include "cxx-qt-gen/file_helper.cxxqt.h"
|
||||||
#include <liblumina/src/rust/slide_object.cxxqt.h>
|
#include "cxx-qt-gen/slide_object.cxxqt.h"
|
||||||
#include <liblumina/src/rust/slide_model.cxxqt.h>
|
#include "cxx-qt-gen/slide_model.cxxqt.h"
|
||||||
#include <liblumina/src/rust/service_item_model.cxxqt.h>
|
#include "cxx-qt-gen/service_item_model.cxxqt.h"
|
||||||
#include <liblumina/src/rust/settings.cxxqt.h>
|
#include "cxx-qt-gen/settings.cxxqt.h"
|
||||||
#include <liblumina/src/rust/ytdl.cxxqt.h>
|
#include "cxx-qt-gen/ytdl.cxxqt.h"
|
||||||
#include <liblumina/src/rust/presentation_model.cxxqt.h>
|
#include "cxx-qt-gen/presentation_model.cxxqt.h"
|
||||||
#include <liblumina/src/rust/songs/song_model.cxxqt.h>
|
#include "cxx-qt-gen/song_model.cxxqt.h"
|
||||||
#include <liblumina/src/rust/video_model.cxxqt.h>
|
#include "cxx-qt-gen/video_model.cxxqt.h"
|
||||||
#include <liblumina/src/rust/image_model.cxxqt.h>
|
#include "cxx-qt-gen/image_model.cxxqt.h"
|
||||||
#include <liblumina/src/rust/utils.cxxqt.h>
|
#include "cxx-qt-gen/utils.cxxqt.h"
|
||||||
#include <liblumina/src/rust/songs/song_editor.cxxqt.h>
|
#include "cxx-qt-gen/song_editor.cxxqt.h"
|
||||||
#include <liblumina/src/rust/obs.cxxqt.h>
|
#include "cxx-qt-gen/obs.cxxqt.h"
|
||||||
|
|
||||||
static QWindow *windowFromEngine(QQmlApplicationEngine *engine)
|
static QWindow *windowFromEngine(QQmlApplicationEngine *engine)
|
||||||
{
|
{
|
||||||
|
@ -60,22 +60,22 @@ int main(int argc, char *argv[])
|
||||||
QGuiApplication::setWindowIcon(QIcon::fromTheme(QStringLiteral("video-display")));
|
QGuiApplication::setWindowIcon(QIcon::fromTheme(QStringLiteral("video-display")));
|
||||||
QtWebEngineQuick::initialize();
|
QtWebEngineQuick::initialize();
|
||||||
QGuiApplication app(argc, argv);
|
QGuiApplication app(argc, argv);
|
||||||
// KLocalizedString::setApplicationDomain("lumina");
|
KLocalizedString::setApplicationDomain("lumina");
|
||||||
// KAboutData about;
|
KAboutData about;
|
||||||
// about.setComponentName(QStringLiteral("lumina"));
|
about.setComponentName(QStringLiteral("lumina"));
|
||||||
// about.setDisplayName(i18n("lumina"));
|
about.setDisplayName(i18n("lumina"));
|
||||||
// about.setVersion(QByteArray("0.1"));
|
about.setVersion(QByteArray("0.1"));
|
||||||
// about.setShortDescription(i18n("A churchpresentation app build with KDE tech."));
|
about.setShortDescription(i18n("A churchpresentation app build with KDE tech."));
|
||||||
// about.setLicense(KAboutLicense::GPL_V3);
|
about.setLicense(KAboutLicense::GPL_V3);
|
||||||
|
|
||||||
// overwrite default-generated values of organizationDomain & desktopFileName
|
// overwrite default-generated values of organizationDomain & desktopFileName
|
||||||
// about.setOrganizationDomain("tfcconnection.org");
|
about.setOrganizationDomain("tfcconnection.org");
|
||||||
// about.setDesktopFileName(QStringLiteral("org.tfcconneciton.lumina"));
|
about.setDesktopFileName(QStringLiteral("org.tfcconneciton.lumina"));
|
||||||
|
|
||||||
QQuickWindow::setGraphicsApi(QSGRendererInterface::OpenGL);
|
QQuickWindow::setGraphicsApi(QSGRendererInterface::OpenGL);
|
||||||
|
|
||||||
// set the application metadata
|
// set the application metadata
|
||||||
// KAboutData::setApplicationData(about);
|
KAboutData::setApplicationData(about);
|
||||||
QCoreApplication::setOrganizationName(QStringLiteral("lumina"));
|
QCoreApplication::setOrganizationName(QStringLiteral("lumina"));
|
||||||
QCoreApplication::setOrganizationDomain(QStringLiteral("tfcconnection.org"));
|
QCoreApplication::setOrganizationDomain(QStringLiteral("tfcconnection.org"));
|
||||||
QCoreApplication::setApplicationName(QStringLiteral("lumina"));
|
QCoreApplication::setApplicationName(QStringLiteral("lumina"));
|
||||||
|
@ -93,7 +93,7 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
// qDebug() << QQuickStyle::availableStyles();
|
// qDebug() << QQuickStyle::availableStyles();
|
||||||
qDebug() << QIcon::themeName();
|
qDebug() << QIcon::themeName();
|
||||||
// qDebug() << QApplication::platformName();
|
qDebug() << QApplication::platformName();
|
||||||
|
|
||||||
//Need to instantiate our slide
|
//Need to instantiate our slide
|
||||||
QScopedPointer<SlideModel> slideModel(new SlideModel);
|
QScopedPointer<SlideModel> slideModel(new SlideModel);
|
||||||
|
@ -108,7 +108,6 @@ int main(int argc, char *argv[])
|
||||||
settings->setup();
|
settings->setup();
|
||||||
|
|
||||||
QQuickView *PresWindow = new QQuickView;
|
QQuickView *PresWindow = new QQuickView;
|
||||||
PresWindow->setSource(QUrl(QStringLiteral("qrc:qml/presenter/PresentationWindow.qml")));
|
|
||||||
qDebug() << PresWindow;
|
qDebug() << PresWindow;
|
||||||
qDebug() << PresWindow->isVisible();
|
qDebug() << PresWindow->isVisible();
|
||||||
|
|
||||||
|
@ -170,9 +169,9 @@ int main(int argc, char *argv[])
|
||||||
qmlRegisterSingletonInstance("org.presenter", 1, 0, "SlideModel", slideModel.get());
|
qmlRegisterSingletonInstance("org.presenter", 1, 0, "SlideModel", slideModel.get());
|
||||||
qmlRegisterSingletonInstance("org.presenter", 1, 0, "Utils", utils);
|
qmlRegisterSingletonInstance("org.presenter", 1, 0, "Utils", utils);
|
||||||
qmlRegisterSingletonInstance("org.presenter", 1, 0, "SlideObject", slideobject.get());
|
qmlRegisterSingletonInstance("org.presenter", 1, 0, "SlideObject", slideobject.get());
|
||||||
|
qmlRegisterSingletonInstance("org.presenter", 1, 0, "PresWindow", PresWindow);
|
||||||
qmlRegisterSingletonInstance("org.presenter", 1, 0, "RSettings", settings);
|
qmlRegisterSingletonInstance("org.presenter", 1, 0, "RSettings", settings);
|
||||||
qmlRegisterSingletonInstance("org.presenter", 1, 0, "ObsModel", obsModel.get());
|
qmlRegisterSingletonInstance("org.presenter", 1, 0, "ObsModel", obsModel.get());
|
||||||
qmlRegisterSingletonInstance("org.presenter", 1, 0, "PresWindow", PresWindow);
|
|
||||||
|
|
||||||
// This is the same slideobject, however to enusre that the PresWindow can have it
|
// This is the same slideobject, however to enusre that the PresWindow can have it
|
||||||
// we need to set it as a separate context so that it can change it's slides too.
|
// we need to set it as a separate context so that it can change it's slides too.
|
||||||
|
@ -185,7 +184,7 @@ int main(int argc, char *argv[])
|
||||||
QQmlApplicationEngine engine;
|
QQmlApplicationEngine engine;
|
||||||
qDebug() << app.allWindows();
|
qDebug() << app.allWindows();
|
||||||
|
|
||||||
// engine.rootContext()->setContextObject(new KLocalizedContext(&engine));
|
engine.rootContext()->setContextObject(new KLocalizedContext(&engine));
|
||||||
engine.load(QUrl(QStringLiteral("qrc:qml/main.qml")));
|
engine.load(QUrl(QStringLiteral("qrc:qml/main.qml")));
|
||||||
qDebug() << "Engine loaded";
|
qDebug() << "Engine loaded";
|
||||||
|
|
||||||
|
|
|
@ -252,7 +252,6 @@ Item {
|
||||||
}
|
}
|
||||||
|
|
||||||
function isDragFile(item) {
|
function isDragFile(item) {
|
||||||
console.log(item);
|
|
||||||
console.log(item.toString());
|
console.log(item.toString());
|
||||||
var extension = item.toString().split('.').pop();
|
var extension = item.toString().split('.').pop();
|
||||||
var valid = false;
|
var valid = false;
|
||||||
|
|
|
@ -188,10 +188,6 @@ Controls.Page {
|
||||||
songModel: songModel
|
songModel: songModel
|
||||||
}
|
}
|
||||||
|
|
||||||
Presenter.PresentationWindow {
|
|
||||||
id: presWindow
|
|
||||||
}
|
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: ServiceItemModel
|
target: ServiceItemModel
|
||||||
function onSaveProgressChanged() {
|
function onSaveProgressChanged() {
|
||||||
|
@ -356,20 +352,19 @@ Controls.Page {
|
||||||
function present(present) {
|
function present(present) {
|
||||||
if (present)
|
if (present)
|
||||||
{
|
{
|
||||||
/* presWindow.slideObj = SlideObject; */
|
PresWindow.showFullScreen();
|
||||||
presWindow.showFullScreen();
|
PresWindow.setSource("qrc:qml/presenter/PresentationWindow.qml")
|
||||||
/* presWindow.setSource("qrc:qml/presenter/PresentationWindow.qml") */
|
console.log(PresWindow);
|
||||||
console.log(presWindow);
|
|
||||||
/* presWinLoader.active = true; */
|
/* presWinLoader.active = true; */
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
presWindow.close();
|
PresWindow.close();
|
||||||
|
|
||||||
/* presWinLoader.active = false; */
|
/* presWinLoader.active = false; */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function closeAll() { presWindow.close() }
|
function closeAll() { PresWindow.close() }
|
||||||
|
|
||||||
function changeVidPos(pos) {
|
function changeVidPos(pos) {
|
||||||
presentation.slide.seek(pos);
|
presentation.slide.seek(pos);
|
||||||
|
|
|
@ -479,11 +479,6 @@ FocusScope {
|
||||||
previewSlide.stopVideo()
|
previewSlide.stopVideo()
|
||||||
}
|
}
|
||||||
|
|
||||||
function playVideo() {
|
|
||||||
/* showPassiveNotification("Stopping Video") */
|
|
||||||
previewSlide.playVideo()
|
|
||||||
}
|
|
||||||
|
|
||||||
function nextSlideAction() {
|
function nextSlideAction() {
|
||||||
keyHandler.forceActiveFocus();
|
keyHandler.forceActiveFocus();
|
||||||
SlideModel.next()
|
SlideModel.next()
|
||||||
|
|
|
@ -6,13 +6,13 @@ import org.kde.kirigami 2.13 as Kirigami
|
||||||
import "./" as Presenter
|
import "./" as Presenter
|
||||||
import org.presenter 1.0
|
import org.presenter 1.0
|
||||||
|
|
||||||
Window {
|
Item {
|
||||||
id: presentationWindow
|
id: presentationWindow
|
||||||
|
|
||||||
property Item slide: presentationSlide
|
property Item slide: presentationSlide
|
||||||
/* property var SlideObject: SlideObject; */
|
/* property var slideObj */
|
||||||
property var pWin
|
property var pWin
|
||||||
/* anchors.fill: parent */
|
anchors.fill: parent
|
||||||
|
|
||||||
/* title: "presentation-window" */
|
/* title: "presentation-window" */
|
||||||
/* height: maximumHeight */
|
/* height: maximumHeight */
|
||||||
|
@ -25,7 +25,7 @@ Window {
|
||||||
|
|
||||||
/* onClosing: { */
|
/* onClosing: { */
|
||||||
/* presentationSlide.stopVideo(); */
|
/* presentationSlide.stopVideo(); */
|
||||||
/* SlideObject.pause(); */
|
/* SlideObj.pause(); */
|
||||||
/* presentationSlide.stopAudio(); */
|
/* presentationSlide.stopAudio(); */
|
||||||
/* presenting = false; */
|
/* presenting = false; */
|
||||||
/* } */
|
/* } */
|
||||||
|
@ -34,7 +34,7 @@ Window {
|
||||||
target: PresWindow
|
target: PresWindow
|
||||||
function onClosing() {
|
function onClosing() {
|
||||||
presentationSlide.stopVideo();
|
presentationSlide.stopVideo();
|
||||||
SlideObject.pause();
|
SlideObj.pause();
|
||||||
presentationSlide.stopAudio();
|
presentationSlide.stopAudio();
|
||||||
presenting = false;
|
presenting = false;
|
||||||
}
|
}
|
||||||
|
@ -48,25 +48,25 @@ Window {
|
||||||
Presenter.Slide {
|
Presenter.Slide {
|
||||||
id: presentationSlide
|
id: presentationSlide
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
imageSource: SlideObject.html ? "" : SlideObject.imageBackground
|
imageSource: SlideObj.html ? "" : SlideObj.imageBackground
|
||||||
webSource: SlideObject.html ? SlideObject.imageBackground : ""
|
webSource: SlideObj.html ? SlideObj.imageBackground : ""
|
||||||
htmlVisible: SlideObject.html
|
htmlVisible: SlideObj.html
|
||||||
videoSource: presentationWindow.visible ? SlideObject.videoBackground : ""
|
videoSource: presentationWindow.visible ? SlideObj.videoBackground : ""
|
||||||
audioSource: SlideObject.audio
|
audioSource: SlideObj.audio
|
||||||
text: SlideObject.text
|
text: SlideObj.text
|
||||||
chosenFont: SlideObject.font
|
chosenFont: SlideObj.font
|
||||||
textSize: SlideObject.fontSize
|
textSize: SlideObj.fontSize
|
||||||
pdfIndex: SlideObject.slideIndex
|
pdfIndex: SlideObj.slideIndex
|
||||||
itemType: SlideObject.ty
|
itemType: SlideObj.ty
|
||||||
vidLoop: SlideObject.looping
|
vidLoop: SlideObj.looping
|
||||||
vidStartTime: SlideObject.videoStartTime
|
vidStartTime: SlideObj.videoStartTime
|
||||||
vidEndTime: SlideObject.videoEndTime
|
vidEndTime: SlideObj.videoEndTime
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: SlideObject
|
target: SlideObj
|
||||||
function onVideoBackgroundChanged() {
|
function onVideoBackgroundChanged() {
|
||||||
if (SlideObject.videoBackground === "")
|
if (SlideObj.videoBackground === "")
|
||||||
stopVideo();
|
stopVideo();
|
||||||
else {
|
else {
|
||||||
loadVideo();
|
loadVideo();
|
||||||
|
@ -74,12 +74,12 @@ Window {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function onIsPlayingChanged() {
|
function onIsPlayingChanged() {
|
||||||
if(SlideObject.isPlaying)
|
if(SlideObj.isPlaying)
|
||||||
presentationSlide.playVideo();
|
presentationSlide.playVideo();
|
||||||
pauseVideo();
|
pauseVideo();
|
||||||
}
|
}
|
||||||
function onLoopingChanged() {
|
function onLoopingChanged() {
|
||||||
if(SlideObject.looping)
|
if(SlideObj.looping)
|
||||||
presentationSlide.loopVideo();
|
presentationSlide.loopVideo();
|
||||||
}
|
}
|
||||||
function onAudioChanged() {
|
function onAudioChanged() {
|
||||||
|
|
|
@ -21,7 +21,6 @@ Kirigami.OverlaySheet {
|
||||||
|
|
||||||
Kirigami.FormLayout {
|
Kirigami.FormLayout {
|
||||||
implicitHeight: Kirigami.Units.gridUnit * 30
|
implicitHeight: Kirigami.Units.gridUnit * 30
|
||||||
implicitWidth: Kirigami.Units.gridUnit * 30
|
|
||||||
Controls.ComboBox {
|
Controls.ComboBox {
|
||||||
id: screenSelectionField
|
id: screenSelectionField
|
||||||
Kirigami.FormData.label: i18nc("@label:textbox", "Presentation Screen:")
|
Kirigami.FormData.label: i18nc("@label:textbox", "Presentation Screen:")
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
[package]
|
[package]
|
||||||
name = "lumina_core"
|
name = "lumina-core"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
authors = [
|
authors = [
|
||||||
|
|
|
@ -1,133 +1,82 @@
|
||||||
use crate::{
|
|
||||||
images::{get_image_from_db, Image},
|
|
||||||
kinds::ServiceItemKind,
|
|
||||||
model::get_db,
|
|
||||||
presentations::{
|
|
||||||
get_presentation_from_db, PresKind, Presentation,
|
|
||||||
},
|
|
||||||
service_items::ServiceItem,
|
|
||||||
slides::Background,
|
|
||||||
songs::{get_song_from_db, Song},
|
|
||||||
videos::{get_video_from_db, Video},
|
|
||||||
};
|
|
||||||
use color_eyre::eyre::{eyre, Context, Result};
|
|
||||||
use serde_json::Value;
|
|
||||||
use sqlx::{query, query_as, FromRow, SqliteConnection};
|
|
||||||
use std::{
|
|
||||||
fs::{self, File},
|
|
||||||
iter,
|
|
||||||
path::{Path, PathBuf},
|
|
||||||
};
|
|
||||||
use tar::{Archive, Builder};
|
use tar::{Archive, Builder};
|
||||||
use tracing::error;
|
use tracing::error;
|
||||||
use zstd::Encoder;
|
use zstd::Encoder;
|
||||||
|
use std::{fs::{self, File}, future::Future, iter, path::{Path, PathBuf}};
|
||||||
|
use color_eyre::eyre::{eyre, Result};
|
||||||
|
use serde_json::Value;
|
||||||
|
use sqlx::{query, query_as, FromRow, SqliteConnection};
|
||||||
|
use crate::{images::{get_image_from_db, Image}, kinds::ServiceItemKind, model::get_db, presentations::{get_presentation_from_db, PresKind, Presentation}, service_items::ServiceItem, slides::Background, songs::{get_song_from_db, Song}, videos::{get_video_from_db, Video}};
|
||||||
|
|
||||||
pub async fn save(
|
pub async fn save(list: Vec<ServiceItem>, path: impl AsRef<Path>) -> Result<()> {
|
||||||
list: Vec<ServiceItem>,
|
|
||||||
path: impl AsRef<Path>,
|
|
||||||
) -> Result<()> {
|
|
||||||
let path = path.as_ref();
|
let path = path.as_ref();
|
||||||
let save_file = File::create(path)?;
|
let save_file = File::create(path)?;
|
||||||
let mut db = get_db().await;
|
let mut db = get_db().await;
|
||||||
let json = process_service_items(&list, &mut db).await?;
|
let json = process_service_items(&list, &mut db).await?;
|
||||||
let archive =
|
let archive = store_service_items(&list, &mut db, &save_file, &json).await?;
|
||||||
store_service_items(&list, &mut db, &save_file, &json)
|
|
||||||
.await?;
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn store_service_items(
|
async fn store_service_items(items: &Vec<ServiceItem>, db: &mut SqliteConnection, save_file: &File, json: &Value) -> Result<()> {
|
||||||
items: &Vec<ServiceItem>,
|
|
||||||
db: &mut SqliteConnection,
|
|
||||||
save_file: &File,
|
|
||||||
json: &Value,
|
|
||||||
) -> Result<()> {
|
|
||||||
let encoder = Encoder::new(save_file, 3).unwrap();
|
let encoder = Encoder::new(save_file, 3).unwrap();
|
||||||
let mut tar = Builder::new(encoder);
|
let mut tar = Builder::new(encoder);
|
||||||
let mut temp_dir = dirs::data_dir().unwrap();
|
let mut temp_dir = dirs::data_dir().unwrap();
|
||||||
temp_dir.push("lumina");
|
temp_dir.push("lumina");
|
||||||
let mut s: String =
|
let mut s: String =
|
||||||
iter::repeat_with(fastrand::alphanumeric).take(5).collect();
|
iter::repeat_with(fastrand::alphanumeric)
|
||||||
|
.take(5)
|
||||||
|
.collect();
|
||||||
s.insert_str(0, "temp_");
|
s.insert_str(0, "temp_");
|
||||||
temp_dir.push(s);
|
temp_dir.push(s);
|
||||||
fs::create_dir_all(&temp_dir)?;
|
fs::create_dir_all(&temp_dir)?;
|
||||||
let service_file = temp_dir.join("serviceitems.json");
|
let service_file = temp_dir.join("serviceitems.json");
|
||||||
fs::File::create(&service_file)?;
|
fs::File::create(&service_file)?;
|
||||||
match fs::File::options()
|
match fs::File::options().read(true).write(true).open(service_file) {
|
||||||
.read(true)
|
|
||||||
.write(true)
|
|
||||||
.open(service_file)
|
|
||||||
{
|
|
||||||
Ok(f) => {
|
Ok(f) => {
|
||||||
serde_json::to_writer_pretty(f, json)?;
|
serde_json::to_writer_pretty(f, json)?;
|
||||||
}
|
},
|
||||||
Err(e) => {
|
Err(e) => error!("There were problems making a file i guess: {e}"),
|
||||||
error!("There were problems making a file i guess: {e}")
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
for item in items {
|
for item in items {
|
||||||
let background;
|
let background;
|
||||||
let audio: Option<PathBuf>;
|
let audio: Option<PathBuf>;
|
||||||
match item.kind {
|
match item.kind {
|
||||||
ServiceItemKind::Song => {
|
ServiceItemKind::Song => {
|
||||||
let song =
|
let song = get_song_from_db(item.database_id, db).await?;
|
||||||
get_song_from_db(item.database_id, db).await?;
|
|
||||||
background = song.background;
|
background = song.background;
|
||||||
audio = song.audio;
|
audio = song.audio;
|
||||||
}
|
},
|
||||||
ServiceItemKind::Image => {
|
ServiceItemKind::Image => {
|
||||||
let image =
|
let image = get_image_from_db(item.database_id, db).await?;
|
||||||
get_image_from_db(item.database_id, db).await?;
|
|
||||||
background = Some(Background::try_from(image.path)?);
|
background = Some(Background::try_from(image.path)?);
|
||||||
audio = None;
|
audio = None;
|
||||||
}
|
},
|
||||||
ServiceItemKind::Video => {
|
ServiceItemKind::Video => {
|
||||||
let video =
|
let video = get_video_from_db(item.database_id, db).await?;
|
||||||
get_video_from_db(item.database_id, db).await?;
|
|
||||||
background = Some(Background::try_from(video.path)?);
|
background = Some(Background::try_from(video.path)?);
|
||||||
audio = None;
|
audio = None;
|
||||||
}
|
},
|
||||||
ServiceItemKind::Presentation(_) => {
|
ServiceItemKind::Presentation(_) => {
|
||||||
let presentation =
|
let presentation = get_presentation_from_db(item.database_id, db).await?;
|
||||||
get_presentation_from_db(item.database_id, db)
|
background = Some(Background::try_from(presentation.path)?);
|
||||||
.await?;
|
|
||||||
background =
|
|
||||||
Some(Background::try_from(presentation.path)?);
|
|
||||||
audio = None;
|
audio = None;
|
||||||
}
|
},
|
||||||
ServiceItemKind::Content => {
|
ServiceItemKind::Content => {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
if let Some(file) = audio {
|
if let Some(file) = audio {
|
||||||
let audio_file =
|
let audio_file = temp_dir.join(file.file_name().expect("Audio file couldn't be added to temp_dir"));
|
||||||
temp_dir.join(file.file_name().expect(
|
match fs::File::create(&audio_file) {
|
||||||
"Audio file couldn't be added to temp_dir",
|
Ok(_) => Ok(fs::copy(file, &audio_file)?),
|
||||||
));
|
Err(e) => Err(eyre!("Couldn't create audio file: {e}")),
|
||||||
if let Ok(file) = file.strip_prefix("file://") {
|
}?;
|
||||||
fs::File::create(&audio_file)
|
|
||||||
.wrap_err("Couldn't create audio file")?;
|
|
||||||
fs::copy(file, audio_file).wrap_err("Audio file could not be copied, the source file doesn't exist not be found");
|
|
||||||
} else {
|
|
||||||
fs::File::create(&audio_file)
|
|
||||||
.wrap_err("Couldn't create audio file")?;
|
|
||||||
fs::copy(file, audio_file).wrap_err("Audio file could not be copied, the source file doesn't exist not be found");
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
if let Some(file) = background {
|
if let Some(file) = background {
|
||||||
let background_file =
|
let background_file = temp_dir.join(file.path.file_name().expect("Background file couldn't be added to temp_dir"));
|
||||||
temp_dir.join(file.path.file_name().expect(
|
match fs::File::create(&background_file) {
|
||||||
"Background file couldn't be added to temp_dir",
|
Ok(_) => Ok(fs::copy(file.path, &background_file)?),
|
||||||
));
|
Err(e) => Err(eyre!("Couldn't create background file: {e}")),
|
||||||
if let Ok(file) = file.path.strip_prefix("file://") {
|
}?;
|
||||||
fs::File::create(&background_file)
|
|
||||||
.wrap_err("Couldn't create background file")?;
|
|
||||||
fs::copy(file, background_file).wrap_err("Background file could not be copied, the source file doesn't exist not be found");
|
|
||||||
} else {
|
|
||||||
fs::File::create(&background_file)
|
|
||||||
.wrap_err("Couldn't create background file")?;
|
|
||||||
fs::copy(file.path, background_file).wrap_err("Background file could not be copied, the source file doesn't exist not be found");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -137,96 +86,66 @@ async fn clear_temp_dir(temp_dir: &Path) -> Result<()> {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn process_service_items(
|
async fn process_service_items(items: &Vec<ServiceItem>, db: &mut SqliteConnection) -> Result<Value> {
|
||||||
items: &Vec<ServiceItem>,
|
|
||||||
db: &mut SqliteConnection,
|
|
||||||
) -> Result<Value> {
|
|
||||||
let mut values: Vec<Value> = vec![];
|
let mut values: Vec<Value> = vec![];
|
||||||
for item in items {
|
for item in items {
|
||||||
match item.kind {
|
match item.kind {
|
||||||
ServiceItemKind::Song => {
|
ServiceItemKind::Song => {
|
||||||
let value =
|
let value = process_song(item.database_id, db).await?;
|
||||||
process_song(item.database_id, db).await?;
|
|
||||||
values.push(value);
|
values.push(value);
|
||||||
}
|
},
|
||||||
ServiceItemKind::Image => {
|
ServiceItemKind::Image => {
|
||||||
let value =
|
let value = process_image(item.database_id, db).await?;
|
||||||
process_image(item.database_id, db).await?;
|
|
||||||
values.push(value);
|
values.push(value);
|
||||||
}
|
},
|
||||||
ServiceItemKind::Video => {
|
ServiceItemKind::Video => {
|
||||||
let value =
|
let value = process_video(item.database_id, db).await?;
|
||||||
process_video(item.database_id, db).await?;
|
|
||||||
values.push(value);
|
values.push(value);
|
||||||
}
|
},
|
||||||
ServiceItemKind::Presentation(_) => {
|
ServiceItemKind::Presentation(_) => {
|
||||||
let value =
|
let value = process_presentation(item.database_id, db).await?;
|
||||||
process_presentation(item.database_id, db)
|
|
||||||
.await?;
|
|
||||||
values.push(value);
|
values.push(value);
|
||||||
}
|
},
|
||||||
ServiceItemKind::Content => {
|
ServiceItemKind::Content => {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let json = Value::from(values);
|
let json = Value::from(values);
|
||||||
Ok(json)
|
Ok(json)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn process_song(
|
async fn process_song(database_id: i32, db: &mut SqliteConnection) -> Result<Value> {
|
||||||
database_id: i32,
|
|
||||||
db: &mut SqliteConnection,
|
|
||||||
) -> Result<Value> {
|
|
||||||
let song = get_song_from_db(database_id, db).await?;
|
let song = get_song_from_db(database_id, db).await?;
|
||||||
let song_json = serde_json::to_value(&song)?;
|
let song_json = serde_json::to_value(&song)?;
|
||||||
let kind_json = serde_json::to_value(ServiceItemKind::Song)?;
|
let kind_json = serde_json::to_value(ServiceItemKind::Song)?;
|
||||||
let json =
|
let json = serde_json::json!({"item": song_json, "kind": kind_json});
|
||||||
serde_json::json!({"item": song_json, "kind": kind_json});
|
|
||||||
Ok(json)
|
Ok(json)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn process_image(
|
async fn process_image(database_id: i32, db: &mut SqliteConnection) -> Result<Value> {
|
||||||
database_id: i32,
|
|
||||||
db: &mut SqliteConnection,
|
|
||||||
) -> Result<Value> {
|
|
||||||
let image = get_image_from_db(database_id, db).await?;
|
let image = get_image_from_db(database_id, db).await?;
|
||||||
let image_json = serde_json::to_value(&image)?;
|
let image_json = serde_json::to_value(&image)?;
|
||||||
let kind_json = serde_json::to_value(ServiceItemKind::Image)?;
|
let kind_json = serde_json::to_value(ServiceItemKind::Image)?;
|
||||||
let json =
|
let json = serde_json::json!({"item": image_json, "kind": kind_json});
|
||||||
serde_json::json!({"item": image_json, "kind": kind_json});
|
|
||||||
Ok(json)
|
Ok(json)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn process_video(
|
async fn process_video(database_id: i32, db: &mut SqliteConnection) -> Result<Value> {
|
||||||
database_id: i32,
|
|
||||||
db: &mut SqliteConnection,
|
|
||||||
) -> Result<Value> {
|
|
||||||
let video = get_video_from_db(database_id, db).await?;
|
let video = get_video_from_db(database_id, db).await?;
|
||||||
let video_json = serde_json::to_value(&video)?;
|
let video_json = serde_json::to_value(&video)?;
|
||||||
let kind_json = serde_json::to_value(ServiceItemKind::Video)?;
|
let kind_json = serde_json::to_value(ServiceItemKind::Video)?;
|
||||||
let json =
|
let json = serde_json::json!({"item": video_json, "kind": kind_json});
|
||||||
serde_json::json!({"item": video_json, "kind": kind_json});
|
|
||||||
Ok(json)
|
Ok(json)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn process_presentation(
|
async fn process_presentation(database_id: i32, db: &mut SqliteConnection) -> Result<Value> {
|
||||||
database_id: i32,
|
let presentation = get_presentation_from_db(database_id, db).await?;
|
||||||
db: &mut SqliteConnection,
|
|
||||||
) -> Result<Value> {
|
|
||||||
let presentation =
|
|
||||||
get_presentation_from_db(database_id, db).await?;
|
|
||||||
let presentation_json = serde_json::to_value(&presentation)?;
|
let presentation_json = serde_json::to_value(&presentation)?;
|
||||||
let kind_json = match presentation.kind {
|
let kind_json = match presentation.kind {
|
||||||
PresKind::Html => serde_json::to_value(
|
PresKind::Html => serde_json::to_value(ServiceItemKind::Presentation(PresKind::Html))?,
|
||||||
ServiceItemKind::Presentation(PresKind::Html),
|
PresKind::Pdf => serde_json::to_value(ServiceItemKind::Presentation(PresKind::Pdf))?,
|
||||||
)?,
|
PresKind::Generic => serde_json::to_value(ServiceItemKind::Presentation(PresKind::Generic))?,
|
||||||
PresKind::Pdf => serde_json::to_value(
|
|
||||||
ServiceItemKind::Presentation(PresKind::Pdf),
|
|
||||||
)?,
|
|
||||||
PresKind::Generic => serde_json::to_value(
|
|
||||||
ServiceItemKind::Presentation(PresKind::Generic),
|
|
||||||
)?,
|
|
||||||
};
|
};
|
||||||
let json = serde_json::json!({"item": presentation_json, "kind": kind_json});
|
let json = serde_json::json!({"item": presentation_json, "kind": kind_json});
|
||||||
Ok(json)
|
Ok(json)
|
||||||
|
@ -236,11 +155,11 @@ async fn process_presentation(
|
||||||
mod test {
|
mod test {
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use super::*;
|
|
||||||
use fs::canonicalize;
|
use fs::canonicalize;
|
||||||
use pretty_assertions::assert_eq;
|
|
||||||
use sqlx::Connection;
|
use sqlx::Connection;
|
||||||
|
use pretty_assertions::{assert_eq, assert_ne};
|
||||||
use tracing::debug;
|
use tracing::debug;
|
||||||
|
use super::*;
|
||||||
|
|
||||||
async fn get_db() -> SqliteConnection {
|
async fn get_db() -> SqliteConnection {
|
||||||
let mut data = dirs::data_local_dir().unwrap();
|
let mut data = dirs::data_local_dir().unwrap();
|
||||||
|
@ -248,7 +167,9 @@ mod test {
|
||||||
data.push("library-db.sqlite3");
|
data.push("library-db.sqlite3");
|
||||||
let mut db_url = String::from("sqlite://");
|
let mut db_url = String::from("sqlite://");
|
||||||
db_url.push_str(data.to_str().unwrap());
|
db_url.push_str(data.to_str().unwrap());
|
||||||
SqliteConnection::connect(&db_url).await.expect("problems")
|
SqliteConnection::connect(&db_url)
|
||||||
|
.await
|
||||||
|
.expect("problems")
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test(flavor = "current_thread")]
|
#[tokio::test(flavor = "current_thread")]
|
||||||
|
@ -318,8 +239,7 @@ mod test {
|
||||||
async fn test_process_presentation() {
|
async fn test_process_presentation() {
|
||||||
let mut db = get_db().await;
|
let mut db = get_db().await;
|
||||||
let result = process_presentation(54, &mut db).await;
|
let result = process_presentation(54, &mut db).await;
|
||||||
let json_presentation_file =
|
let json_presentation_file = PathBuf::from("./test/test_presentation.json");
|
||||||
PathBuf::from("./test/test_presentation.json");
|
|
||||||
if let Ok(path) = canonicalize(json_presentation_file) {
|
if let Ok(path) = canonicalize(json_presentation_file) {
|
||||||
debug!(file = ?&path);
|
debug!(file = ?&path);
|
||||||
if let Ok(s) = fs::read_to_string(path) {
|
if let Ok(s) = fs::read_to_string(path) {
|
||||||
|
@ -332,9 +252,7 @@ mod test {
|
||||||
panic!("String wasn't read from file");
|
panic!("String wasn't read from file");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
panic!(
|
panic!("Cannot find absolute path to test_presentation.json");
|
||||||
"Cannot find absolute path to test_presentation.json"
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -363,8 +281,7 @@ mod test {
|
||||||
async fn test_service_items() {
|
async fn test_service_items() {
|
||||||
let mut db = get_db().await;
|
let mut db = get_db().await;
|
||||||
let items = get_items();
|
let items = get_items();
|
||||||
let json_item_file =
|
let json_item_file = PathBuf::from("./test/test_service_items.json");
|
||||||
PathBuf::from("./test/test_service_items.json");
|
|
||||||
let result = process_service_items(&items, &mut db).await;
|
let result = process_service_items(&items, &mut db).await;
|
||||||
if let Ok(path) = canonicalize(json_item_file) {
|
if let Ok(path) = canonicalize(json_item_file) {
|
||||||
if let Ok(s) = fs::read_to_string(path) {
|
if let Ok(s) = fs::read_to_string(path) {
|
||||||
|
@ -388,23 +305,16 @@ mod test {
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn test_store() {
|
async fn test_store() {
|
||||||
let path = PathBuf::from(
|
let path = PathBuf::from("/home/chris/dev/lumina/src/rust/core/test.pres");
|
||||||
"/home/chris/dev/lumina/src/rust/core/test.pres",
|
let save_file = match File::create(path) {
|
||||||
);
|
|
||||||
let save_file = match File::create(path) {
|
|
||||||
Ok(f) => f,
|
Ok(f) => f,
|
||||||
Err(e) => panic!("Couldn't create save_file: {e}"),
|
Err(e) => panic!("Couldn't create save_file: {e}"),
|
||||||
};
|
};
|
||||||
let mut db = get_db().await;
|
let mut db = get_db().await;
|
||||||
let list = get_items();
|
let list = get_items();
|
||||||
if let Ok(json) = process_service_items(&list, &mut db).await
|
if let Ok(json) = process_service_items(&list, &mut db).await {
|
||||||
{
|
|
||||||
println!("{:?}", json);
|
println!("{:?}", json);
|
||||||
match store_service_items(
|
match store_service_items(&list, &mut db, &save_file, &json).await {
|
||||||
&list, &mut db, &save_file, &json,
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
{
|
|
||||||
Ok(_) => assert!(true),
|
Ok(_) => assert!(true),
|
||||||
Err(e) => panic!("There was an error: {e}"),
|
Err(e) => panic!("There was an error: {e}"),
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,9 +5,7 @@ use sqlx::{query_as, SqliteConnection};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use tracing::error;
|
use tracing::error;
|
||||||
|
|
||||||
#[derive(
|
#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
|
||||||
Clone, Debug, Default, PartialEq, Serialize, Deserialize,
|
|
||||||
)]
|
|
||||||
pub struct Image {
|
pub struct Image {
|
||||||
pub id: i32,
|
pub id: i32,
|
||||||
pub title: String,
|
pub title: String,
|
||||||
|
@ -18,7 +16,7 @@ impl Model<Image> {
|
||||||
pub fn load_from_db(&mut self) {
|
pub fn load_from_db(&mut self) {
|
||||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||||
rt.block_on(async {
|
rt.block_on(async {
|
||||||
let result = query_as!(Image, r#"SELECT title as "title!", file_path as "path!", id as "id: i32" from images"#).fetch_all(&mut self.db).await;
|
let result = query_as!(Image, r#"SELECT title as "title!", filePath as "path!", id as "id: i32" from images"#).fetch_all(&mut self.db).await;
|
||||||
match result {
|
match result {
|
||||||
Ok(v) => {
|
Ok(v) => {
|
||||||
for image in v.into_iter() {
|
for image in v.into_iter() {
|
||||||
|
@ -31,11 +29,9 @@ impl Model<Image> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_image_from_db(
|
|
||||||
database_id: i32,
|
pub async fn get_image_from_db(database_id: i32, db: &mut SqliteConnection) -> Result<Image> {
|
||||||
db: &mut SqliteConnection,
|
Ok(query_as!(Image, r#"SELECT title as "title!", filePath as "path!", id as "id: i32" from images where id = ?"#, database_id).fetch_one(db).await?)
|
||||||
) -> Result<Image> {
|
|
||||||
Ok(query_as!(Image, r#"SELECT title as "title!", file_path as "path!", id as "id: i32" from images where id = ?"#, database_id).fetch_one(db).await?)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -71,10 +67,7 @@ mod test {
|
||||||
let new_image = test_image("A newer image".into());
|
let new_image = test_image("A newer image".into());
|
||||||
match result {
|
match result {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
assert_eq!(
|
assert_eq!(&image, image_model.find(|i| i.id == 0).unwrap());
|
||||||
&image,
|
|
||||||
image_model.find(|i| i.id == 0).unwrap()
|
|
||||||
);
|
|
||||||
assert_ne!(
|
assert_ne!(
|
||||||
&new_image,
|
&new_image,
|
||||||
image_model.find(|i| i.id == 0).unwrap()
|
image_model.find(|i| i.id == 0).unwrap()
|
||||||
|
|
|
@ -4,9 +4,7 @@ use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::presentations::PresKind;
|
use crate::presentations::PresKind;
|
||||||
|
|
||||||
#[derive(
|
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize,
|
|
||||||
)]
|
|
||||||
pub enum ServiceItemKind {
|
pub enum ServiceItemKind {
|
||||||
#[default]
|
#[default]
|
||||||
Song,
|
Song,
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
pub mod file;
|
|
||||||
pub mod images;
|
pub mod images;
|
||||||
pub mod kinds;
|
pub mod kinds;
|
||||||
pub mod model;
|
pub mod model;
|
||||||
|
@ -7,3 +6,4 @@ pub mod service_items;
|
||||||
pub mod slides;
|
pub mod slides;
|
||||||
pub mod songs;
|
pub mod songs;
|
||||||
pub mod videos;
|
pub mod videos;
|
||||||
|
pub mod file;
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
mod service_items;
|
|
|
@ -36,7 +36,8 @@ impl<T> Model<T> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_item(&self, index: i32) -> Option<&T> {
|
pub fn get_item(&self, index: i32) -> Option<&T>
|
||||||
|
{
|
||||||
self.items.get(index as usize)
|
self.items.get(index as usize)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,8 +60,10 @@ impl<T> Default for Model<T> {
|
||||||
items: vec![],
|
items: vec![],
|
||||||
db: {
|
db: {
|
||||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||||
rt.block_on(async { get_db().await })
|
rt.block_on(async {
|
||||||
},
|
get_db().await
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -71,7 +74,9 @@ pub async fn get_db() -> SqliteConnection {
|
||||||
data.push("library-db.sqlite3");
|
data.push("library-db.sqlite3");
|
||||||
let mut db_url = String::from("sqlite://");
|
let mut db_url = String::from("sqlite://");
|
||||||
db_url.push_str(data.to_str().unwrap());
|
db_url.push_str(data.to_str().unwrap());
|
||||||
SqliteConnection::connect(&db_url).await.expect("problems")
|
SqliteConnection::connect(&db_url)
|
||||||
|
.await
|
||||||
|
.expect("problems")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Modeling {
|
pub trait Modeling {
|
||||||
|
|
|
@ -1,16 +1,12 @@
|
||||||
|
use std::path::PathBuf;
|
||||||
use color_eyre::eyre::Result;
|
use color_eyre::eyre::Result;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use sqlx::{
|
use sqlx::{prelude::FromRow, query, sqlite::SqliteRow, Row, SqliteConnection};
|
||||||
prelude::FromRow, query, sqlite::SqliteRow, Row, SqliteConnection,
|
|
||||||
};
|
|
||||||
use std::path::PathBuf;
|
|
||||||
use tracing::error;
|
use tracing::error;
|
||||||
|
|
||||||
use crate::model::Model;
|
use crate::model::Model;
|
||||||
|
|
||||||
#[derive(
|
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize,
|
|
||||||
)]
|
|
||||||
pub enum PresKind {
|
pub enum PresKind {
|
||||||
Html,
|
Html,
|
||||||
#[default]
|
#[default]
|
||||||
|
@ -18,9 +14,7 @@ pub enum PresKind {
|
||||||
Generic,
|
Generic,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(
|
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize,
|
|
||||||
)]
|
|
||||||
pub struct Presentation {
|
pub struct Presentation {
|
||||||
pub id: i32,
|
pub id: i32,
|
||||||
pub title: String,
|
pub title: String,
|
||||||
|
@ -63,7 +57,7 @@ impl Model<Presentation> {
|
||||||
pub fn load_from_db(&mut self) {
|
pub fn load_from_db(&mut self) {
|
||||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||||
rt.block_on(async {
|
rt.block_on(async {
|
||||||
let result = query!(r#"SELECT id as "id: i32", title, file_path as "path", html from presentations"#).fetch_all(&mut self.db).await;
|
let result = query!(r#"SELECT id as "id: i32", title, filePath as "path", html from presentations"#).fetch_all(&mut self.db).await;
|
||||||
match result {
|
match result {
|
||||||
Ok(v) => {
|
Ok(v) => {
|
||||||
for presentation in v.into_iter() {
|
for presentation in v.into_iter() {
|
||||||
|
@ -85,11 +79,8 @@ impl Model<Presentation> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_presentation_from_db(
|
pub async fn get_presentation_from_db(database_id: i32, db: &mut SqliteConnection) -> Result<Presentation> {
|
||||||
database_id: i32,
|
let row = query(r#"SELECT id as "id: i32", title, filePath as "path", html from presentations where id = $1"#).bind(database_id).fetch_one(db).await?;
|
||||||
db: &mut SqliteConnection,
|
|
||||||
) -> Result<Presentation> {
|
|
||||||
let row = query(r#"SELECT id as "id: i32", title, file_path as "path", html from presentations where id = $1"#).bind(database_id).fetch_one(db).await?;
|
|
||||||
Ok(Presentation::from_row(&row)?)
|
Ok(Presentation::from_row(&row)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,9 +111,7 @@ mod test {
|
||||||
let mut presentation_model: Model<Presentation> =
|
let mut presentation_model: Model<Presentation> =
|
||||||
Model::default();
|
Model::default();
|
||||||
presentation_model.load_from_db();
|
presentation_model.load_from_db();
|
||||||
if let Some(presentation) =
|
if let Some(presentation) = presentation_model.find(|p| p.id == 54) {
|
||||||
presentation_model.find(|p| p.id == 54)
|
|
||||||
{
|
|
||||||
let test_presentation = test_presentation();
|
let test_presentation = test_presentation();
|
||||||
assert_eq!(&test_presentation, presentation);
|
assert_eq!(&test_presentation, presentation);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -15,7 +15,7 @@ pub struct ServiceItem {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default, PartialEq)]
|
#[derive(Debug, Default, PartialEq)]
|
||||||
pub struct ServiceItemModel {
|
struct ServiceItemModel {
|
||||||
items: Vec<ServiceItem>,
|
items: Vec<ServiceItem>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,9 +52,7 @@ impl From<&Image> for ServiceItem {
|
||||||
impl From<&Presentation> for ServiceItem {
|
impl From<&Presentation> for ServiceItem {
|
||||||
fn from(presentation: &Presentation) -> Self {
|
fn from(presentation: &Presentation) -> Self {
|
||||||
Self {
|
Self {
|
||||||
kind: ServiceItemKind::Presentation(
|
kind: ServiceItemKind::Presentation(presentation.kind.clone()),
|
||||||
presentation.kind.clone(),
|
|
||||||
),
|
|
||||||
database_id: presentation.id,
|
database_id: presentation.id,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
|
@ -62,10 +60,7 @@ impl From<&Presentation> for ServiceItem {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ServiceItemModel {
|
impl ServiceItemModel {
|
||||||
fn add_item(
|
fn add_item(&mut self, item: impl Into<ServiceItem>) -> Result<()> {
|
||||||
&mut self,
|
|
||||||
item: impl Into<ServiceItem>,
|
|
||||||
) -> Result<()> {
|
|
||||||
let service_item: ServiceItem = item.into();
|
let service_item: ServiceItem = item.into();
|
||||||
self.items.push(service_item);
|
self.items.push(service_item);
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -99,6 +94,7 @@ mod test {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
pub fn test_service_item() {
|
pub fn test_service_item() {
|
||||||
let song = test_song();
|
let song = test_song();
|
||||||
|
@ -108,16 +104,10 @@ mod test {
|
||||||
let mut service_model = ServiceItemModel::default();
|
let mut service_model = ServiceItemModel::default();
|
||||||
match service_model.add_item(&song) {
|
match service_model.add_item(&song) {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
assert_eq!(
|
assert_eq!(ServiceItemKind::Song, service_model.items[0].kind);
|
||||||
ServiceItemKind::Song,
|
assert_eq!(ServiceItemKind::Presentation(PresKind::Html), pres_item.kind);
|
||||||
service_model.items[0].kind
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
ServiceItemKind::Presentation(PresKind::Html),
|
|
||||||
pres_item.kind
|
|
||||||
);
|
|
||||||
assert_eq!(service_item, service_model.items[0]);
|
assert_eq!(service_item, service_model.items[0]);
|
||||||
}
|
},
|
||||||
Err(e) => panic!("Problem adding item: {:?}", e),
|
Err(e) => panic!("Problem adding item: {:?}", e),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,4 @@
|
||||||
use std::{
|
use std::{error::Error, fmt::Display, path::{Path, PathBuf}};
|
||||||
error::Error,
|
|
||||||
fmt::Display,
|
|
||||||
path::{Path, PathBuf},
|
|
||||||
};
|
|
||||||
|
|
||||||
use color_eyre::eyre::{eyre, Result};
|
use color_eyre::eyre::{eyre, Result};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
@ -14,9 +10,7 @@ use crate::{
|
||||||
presentations::Presentation, songs::Song, videos::Video,
|
presentations::Presentation, songs::Song, videos::Video,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(
|
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize,
|
|
||||||
)]
|
|
||||||
pub enum TextAlignment {
|
pub enum TextAlignment {
|
||||||
TopLeft,
|
TopLeft,
|
||||||
TopCenter,
|
TopCenter,
|
||||||
|
@ -30,9 +24,7 @@ pub enum TextAlignment {
|
||||||
BottomRight,
|
BottomRight,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(
|
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize,
|
|
||||||
)]
|
|
||||||
pub struct Background {
|
pub struct Background {
|
||||||
pub path: PathBuf,
|
pub path: PathBuf,
|
||||||
pub kind: BackgroundKind,
|
pub kind: BackgroundKind,
|
||||||
|
@ -44,7 +36,7 @@ impl TryFrom<String> for Background {
|
||||||
let value = value.trim_start_matches("file://");
|
let value = value.trim_start_matches("file://");
|
||||||
let path = PathBuf::from(value);
|
let path = PathBuf::from(value);
|
||||||
if !path.exists() {
|
if !path.exists() {
|
||||||
return Err(ParseError::DoesNotExist);
|
return Err(ParseError::DoesNotExist)
|
||||||
}
|
}
|
||||||
let extension = value.rsplit_once('.').unwrap_or_default();
|
let extension = value.rsplit_once('.').unwrap_or_default();
|
||||||
match extension.1 {
|
match extension.1 {
|
||||||
|
@ -114,15 +106,11 @@ impl DatabaseError for ParseError {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_error_mut(
|
fn as_error_mut(&mut self) -> &mut (dyn Error + Send + Sync + 'static) {
|
||||||
&mut self,
|
|
||||||
) -> &mut (dyn Error + Send + Sync + 'static) {
|
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn into_error(
|
fn into_error(self: Box<Self>) -> Box<dyn Error + Send + Sync + 'static> {
|
||||||
self: Box<Self>,
|
|
||||||
) -> Box<dyn Error + Send + Sync + 'static> {
|
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,15 +128,15 @@ impl Display for ParseError {
|
||||||
Self::NonBackgroundFile => {
|
Self::NonBackgroundFile => {
|
||||||
"The file is not a recognized image or video type"
|
"The file is not a recognized image or video type"
|
||||||
}
|
}
|
||||||
Self::DoesNotExist => "This file doesn't exist",
|
Self::DoesNotExist => {
|
||||||
|
"This file doesn't exist"
|
||||||
|
}
|
||||||
};
|
};
|
||||||
write!(f, "Error: {message}")
|
write!(f, "Error: {message}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(
|
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize,
|
|
||||||
)]
|
|
||||||
pub enum BackgroundKind {
|
pub enum BackgroundKind {
|
||||||
#[default]
|
#[default]
|
||||||
Image,
|
Image,
|
||||||
|
|
|
@ -2,10 +2,7 @@ use std::{collections::HashMap, path::PathBuf};
|
||||||
|
|
||||||
use color_eyre::eyre::{eyre, Context, Result};
|
use color_eyre::eyre::{eyre, Context, Result};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use sqlx::{
|
use sqlx::{query, query_as, sqlite::SqliteRow, FromRow, Row, SqliteConnection};
|
||||||
query, query_as, sqlite::SqliteRow, FromRow, Row,
|
|
||||||
SqliteConnection,
|
|
||||||
};
|
|
||||||
use tracing::{debug, error};
|
use tracing::{debug, error};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -13,9 +10,7 @@ use crate::{
|
||||||
slides::{Background, TextAlignment},
|
slides::{Background, TextAlignment},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(
|
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize,
|
|
||||||
)]
|
|
||||||
pub struct Song {
|
pub struct Song {
|
||||||
pub id: i32,
|
pub id: i32,
|
||||||
pub title: String,
|
pub title: String,
|
||||||
|
@ -61,24 +56,17 @@ impl FromRow<'_, SqliteRow> for Song {
|
||||||
text_alignment: Some({
|
text_alignment: Some({
|
||||||
let horizontal_alignment: String = row.try_get(3)?;
|
let horizontal_alignment: String = row.try_get(3)?;
|
||||||
let vertical_alignment: String = row.try_get(4)?;
|
let vertical_alignment: String = row.try_get(4)?;
|
||||||
match (
|
match (horizontal_alignment.to_lowercase().as_str(), vertical_alignment.to_lowercase().as_str()) {
|
||||||
horizontal_alignment.to_lowercase().as_str(),
|
|
||||||
vertical_alignment.to_lowercase().as_str(),
|
|
||||||
) {
|
|
||||||
("left", "top") => TextAlignment::TopLeft,
|
("left", "top") => TextAlignment::TopLeft,
|
||||||
("left", "center") => TextAlignment::MiddleLeft,
|
("left", "center") => TextAlignment::MiddleLeft,
|
||||||
("left", "bottom") => TextAlignment::BottomLeft,
|
("left", "bottom") => TextAlignment::BottomLeft,
|
||||||
("center", "top") => TextAlignment::TopCenter,
|
("center", "top") => TextAlignment::TopCenter,
|
||||||
("center", "center") => {
|
("center", "center") => TextAlignment::MiddleCenter,
|
||||||
TextAlignment::MiddleCenter
|
("center", "bottom") => TextAlignment::BottomCenter,
|
||||||
}
|
|
||||||
("center", "bottom") => {
|
|
||||||
TextAlignment::BottomCenter
|
|
||||||
}
|
|
||||||
("right", "top") => TextAlignment::TopRight,
|
("right", "top") => TextAlignment::TopRight,
|
||||||
("right", "center") => TextAlignment::MiddleRight,
|
("right", "center") => TextAlignment::MiddleRight,
|
||||||
("right", "bottom") => TextAlignment::BottomRight,
|
("right", "bottom") => TextAlignment::BottomRight,
|
||||||
_ => TextAlignment::MiddleCenter,
|
_ => TextAlignment::MiddleCenter
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
font: row.try_get(6)?,
|
font: row.try_get(6)?,
|
||||||
|
@ -87,20 +75,19 @@ impl FromRow<'_, SqliteRow> for Song {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_song_from_db(
|
|
||||||
index: i32,
|
pub async fn get_song_from_db(index: i32, db: &mut SqliteConnection) -> Result<Song> {
|
||||||
db: &mut SqliteConnection,
|
let row = query(r#"SELECT vorder as "verse_order!", fontSize as "font_size!: i32", backgroundType as "background_type!", horizontalTextAlignment as "horizontal_text_alignment!", verticalTextAlignment as "vertical_text_alignment!", title as "title!", font as "font!", background as "background!", lyrics as "lyrics!", ccli as "ccli!", author as "author!", audio as "audio!", id as "id: i32" from songs where id = $1"#).bind(index).fetch_one(db).await?;
|
||||||
) -> Result<Song> {
|
|
||||||
let row = query(r#"SELECT verse_order as "verse_order!", font_size as "font_size!: i32", background_type as "background_type!", horizontal_text_alignment as "horizontal_text_alignment!", vertical_text_alignment as "vertical_text_alignment!", title as "title!", font as "font!", background as "background!", lyrics as "lyrics!", ccli as "ccli!", author as "author!", audio as "audio!", id as "id: i32" from songs where id = $1"#).bind(index).fetch_one(db).await?;
|
|
||||||
Ok(Song::from_row(&row)?)
|
Ok(Song::from_row(&row)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl Model<Song> {
|
impl Model<Song> {
|
||||||
pub fn load_from_db(&mut self) {
|
pub fn load_from_db(&mut self) {
|
||||||
// static DATABASE_URL: &str = "sqlite:///home/chris/.local/share/lumina/library-db.sqlite3";
|
// static DATABASE_URL: &str = "sqlite:///home/chris/.local/share/lumina/library-db.sqlite3";
|
||||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||||
rt.block_on(async {
|
rt.block_on(async {
|
||||||
let result = query(r#"SELECT verse_order as "verse_order!", font_size as "font_size!: i32", background_type as "background_type!", horizontal_text_alignment as "horizontal_text_alignment!", vertical_text_alignment as "vertical_text_alignment!", title as "title!", font as "font!", background as "background!", lyrics as "lyrics!", ccli as "ccli!", author as "author!", audio as "audio!", id as "id: i32" from songs"#).fetch_all(&mut self.db).await;
|
let result = query(r#"SELECT vorder as "verse_order!", fontSize as "font_size!: i32", backgroundType as "background_type!", horizontalTextAlignment as "horizontal_text_alignment!", verticalTextAlignment as "vertical_text_alignment!", title as "title!", font as "font!", background as "background!", lyrics as "lyrics!", ccli as "ccli!", author as "author!", audio as "audio!", id as "id: i32" from songs"#).fetch_all(&mut self.db).await;
|
||||||
match result {
|
match result {
|
||||||
Ok(s) => {
|
Ok(s) => {
|
||||||
for song in s.into_iter() {
|
for song in s.into_iter() {
|
||||||
|
|
|
@ -5,9 +5,7 @@ use sqlx::{query_as, SqliteConnection};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use tracing::error;
|
use tracing::error;
|
||||||
|
|
||||||
#[derive(
|
#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
|
||||||
Clone, Debug, Default, PartialEq, Serialize, Deserialize,
|
|
||||||
)]
|
|
||||||
pub struct Video {
|
pub struct Video {
|
||||||
pub id: i32,
|
pub id: i32,
|
||||||
pub title: String,
|
pub title: String,
|
||||||
|
@ -21,7 +19,7 @@ impl Model<Video> {
|
||||||
pub fn load_from_db(&mut self) {
|
pub fn load_from_db(&mut self) {
|
||||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||||
rt.block_on(async {
|
rt.block_on(async {
|
||||||
let result = query_as!(Video, r#"SELECT title as "title!", file_path as "path!", start_time as "start_time!: f32", end_time as "end_time!: f32", loop as "looping!", id as "id: i32" from videos"#).fetch_all(&mut self.db).await;
|
let result = query_as!(Video, r#"SELECT title as "title!", filePath as "path!", startTime as "start_time!: f32", endTime as "end_time!: f32", loop as "looping!", id as "id: i32" from videos"#).fetch_all(&mut self.db).await;
|
||||||
match result {
|
match result {
|
||||||
Ok(v) => {
|
Ok(v) => {
|
||||||
for video in v.into_iter() {
|
for video in v.into_iter() {
|
||||||
|
@ -34,13 +32,12 @@ impl Model<Video> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_video_from_db(
|
|
||||||
database_id: i32,
|
pub async fn get_video_from_db(database_id: i32, db: &mut SqliteConnection) -> Result<Video> {
|
||||||
db: &mut SqliteConnection,
|
Ok(query_as!(Video, r#"SELECT title as "title!", filePath as "path!", startTime as "start_time!: f32", endTime as "end_time!: f32", loop as "looping!", id as "id: i32" from videos where id = ?"#, database_id).fetch_one(db).await?)
|
||||||
) -> Result<Video> {
|
|
||||||
Ok(query_as!(Video, r#"SELECT title as "title!", file_path as "path!", start_time as "start_time!: f32", end_time as "end_time!: f32", loop as "looping!", id as "id: i32" from videos where id = ?"#, database_id).fetch_one(db).await?)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
@ -74,10 +71,7 @@ mod test {
|
||||||
let new_video = test_video("A newer video".into());
|
let new_video = test_video("A newer video".into());
|
||||||
match result {
|
match result {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
assert_eq!(
|
assert_eq!(&video, video_model.find(|v| v.id == 0).unwrap());
|
||||||
&video,
|
|
||||||
video_model.find(|v| v.id == 0).unwrap()
|
|
||||||
);
|
|
||||||
assert_ne!(
|
assert_ne!(
|
||||||
&new_video,
|
&new_video,
|
||||||
video_model.find(|v| v.id == 0).unwrap()
|
video_model.find(|v| v.id == 0).unwrap()
|
||||||
|
|
|
@ -10,9 +10,6 @@ mod file_helper {
|
||||||
// include!("cxx-qt-lib/qvariant.h");
|
// include!("cxx-qt-lib/qvariant.h");
|
||||||
// type QVariant = cxx_qt_lib::QVariant;
|
// type QVariant = cxx_qt_lib::QVariant;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[auto_cxx_name]
|
|
||||||
#[auto_rust_name]
|
|
||||||
unsafe extern "RustQt" {
|
unsafe extern "RustQt" {
|
||||||
#[qobject]
|
#[qobject]
|
||||||
#[qml_element]
|
#[qml_element]
|
||||||
|
@ -99,9 +96,7 @@ impl file_helper::FileHelper {
|
||||||
QUrl::from(string.as_str())
|
QUrl::from(string.as_str())
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
error!(
|
error!("There was an error, is xdg-desktop-portals correctly setup?");
|
||||||
"There was an error, is xdg-desktop-portals correctly setup?"
|
|
||||||
);
|
|
||||||
QUrl::default()
|
QUrl::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -150,9 +145,7 @@ impl file_helper::FileHelper {
|
||||||
QUrl::from(string.as_str())
|
QUrl::from(string.as_str())
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
error!(
|
error!("Couldn't load file, is xdg-desktop-portals correctly setup?");
|
||||||
"Couldn't load file, is xdg-desktop-portals correctly setup?"
|
|
||||||
);
|
|
||||||
QUrl::default()
|
QUrl::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
pub mod image_model {
|
pub mod image_model {
|
||||||
unsafe extern "C++" {
|
unsafe extern "C++" {
|
||||||
include!(< QAbstractListModel >);
|
include!(< QAbstractListModel >);
|
||||||
type QAbstractListModel;
|
|
||||||
include!("cxx-qt-lib/qhash.h");
|
include!("cxx-qt-lib/qhash.h");
|
||||||
type QHash_i32_QByteArray =
|
type QHash_i32_QByteArray =
|
||||||
cxx_qt_lib::QHash<cxx_qt_lib::QHashPair_i32_QByteArray>;
|
cxx_qt_lib::QHash<cxx_qt_lib::QHashPair_i32_QByteArray>;
|
||||||
|
@ -32,18 +31,15 @@ pub mod image_model {
|
||||||
Title,
|
Title,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[auto_cxx_name]
|
|
||||||
#[auto_rust_name]
|
|
||||||
unsafe extern "RustQt" {
|
unsafe extern "RustQt" {
|
||||||
#[qobject]
|
#[qobject]
|
||||||
#[base = QAbstractListModel]
|
#[base = "QAbstractListModel"]
|
||||||
#[qml_element]
|
#[qml_element]
|
||||||
#[qproperty(i32, count)]
|
#[qproperty(i32, count)]
|
||||||
type ImageModel = super::ImageModelRust;
|
type ImageModel = super::ImageModelRust;
|
||||||
|
|
||||||
#[inherit]
|
#[inherit]
|
||||||
#[qsignal]
|
#[qsignal]
|
||||||
#[cxx_name = "dataChanged"]
|
|
||||||
fn data_changed(
|
fn data_changed(
|
||||||
self: Pin<&mut ImageModel>,
|
self: Pin<&mut ImageModel>,
|
||||||
top_left: &QModelIndex,
|
top_left: &QModelIndex,
|
||||||
|
@ -85,11 +81,8 @@ pub mod image_model {
|
||||||
|
|
||||||
impl cxx_qt::Threading for ImageModel {}
|
impl cxx_qt::Threading for ImageModel {}
|
||||||
|
|
||||||
#[auto_cxx_name]
|
|
||||||
#[auto_rust_name]
|
|
||||||
unsafe extern "RustQt" {
|
unsafe extern "RustQt" {
|
||||||
#[inherit]
|
#[inherit]
|
||||||
#[cxx_name = "beginInsertRows"]
|
|
||||||
unsafe fn begin_insert_rows(
|
unsafe fn begin_insert_rows(
|
||||||
self: Pin<&mut ImageModel>,
|
self: Pin<&mut ImageModel>,
|
||||||
parent: &QModelIndex,
|
parent: &QModelIndex,
|
||||||
|
@ -98,11 +91,9 @@ pub mod image_model {
|
||||||
);
|
);
|
||||||
|
|
||||||
#[inherit]
|
#[inherit]
|
||||||
#[cxx_name = "endInsertRows"]
|
|
||||||
unsafe fn end_insert_rows(self: Pin<&mut ImageModel>);
|
unsafe fn end_insert_rows(self: Pin<&mut ImageModel>);
|
||||||
|
|
||||||
#[inherit]
|
#[inherit]
|
||||||
#[cxx_name = "beginRemoveRows"]
|
|
||||||
unsafe fn begin_remove_rows(
|
unsafe fn begin_remove_rows(
|
||||||
self: Pin<&mut ImageModel>,
|
self: Pin<&mut ImageModel>,
|
||||||
parent: &QModelIndex,
|
parent: &QModelIndex,
|
||||||
|
@ -111,7 +102,6 @@ pub mod image_model {
|
||||||
);
|
);
|
||||||
|
|
||||||
#[inherit]
|
#[inherit]
|
||||||
#[cxx_name = "beginMoveRows"]
|
|
||||||
unsafe fn begin_move_rows(
|
unsafe fn begin_move_rows(
|
||||||
self: Pin<&mut ImageModel>,
|
self: Pin<&mut ImageModel>,
|
||||||
source_parent: &QModelIndex,
|
source_parent: &QModelIndex,
|
||||||
|
@ -122,23 +112,18 @@ pub mod image_model {
|
||||||
) -> bool;
|
) -> bool;
|
||||||
|
|
||||||
#[inherit]
|
#[inherit]
|
||||||
#[cxx_name = "endMoveRows"]
|
|
||||||
unsafe fn end_move_rows(self: Pin<&mut ImageModel>);
|
unsafe fn end_move_rows(self: Pin<&mut ImageModel>);
|
||||||
|
|
||||||
#[inherit]
|
#[inherit]
|
||||||
#[cxx_name = "endRemoveRows"]
|
|
||||||
unsafe fn end_remove_rows(self: Pin<&mut ImageModel>);
|
unsafe fn end_remove_rows(self: Pin<&mut ImageModel>);
|
||||||
|
|
||||||
#[inherit]
|
#[inherit]
|
||||||
#[cxx_name = "beginResetModel"]
|
|
||||||
unsafe fn begin_reset_model(self: Pin<&mut ImageModel>);
|
unsafe fn begin_reset_model(self: Pin<&mut ImageModel>);
|
||||||
|
|
||||||
#[inherit]
|
#[inherit]
|
||||||
#[cxx_name = "endResetModel"]
|
|
||||||
unsafe fn end_reset_model(self: Pin<&mut ImageModel>);
|
unsafe fn end_reset_model(self: Pin<&mut ImageModel>);
|
||||||
|
|
||||||
#[inherit]
|
#[inherit]
|
||||||
#[cxx_name = "canFetchMore"]
|
|
||||||
fn can_fetch_more(
|
fn can_fetch_more(
|
||||||
self: &ImageModel,
|
self: &ImageModel,
|
||||||
parent: &QModelIndex,
|
parent: &QModelIndex,
|
||||||
|
@ -162,20 +147,18 @@ pub mod image_model {
|
||||||
|
|
||||||
#[qinvokable]
|
#[qinvokable]
|
||||||
#[cxx_override]
|
#[cxx_override]
|
||||||
#[cxx_name = "roleNames"]
|
|
||||||
fn role_names(self: &ImageModel) -> QHash_i32_QByteArray;
|
fn role_names(self: &ImageModel) -> QHash_i32_QByteArray;
|
||||||
|
|
||||||
#[qinvokable]
|
#[qinvokable]
|
||||||
#[cxx_override]
|
#[cxx_override]
|
||||||
#[cxx_name = "rowCount"]
|
|
||||||
fn row_count(self: &ImageModel, _parent: &QModelIndex)
|
fn row_count(self: &ImageModel, _parent: &QModelIndex)
|
||||||
-> i32;
|
-> i32;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
use cxx_qt::CxxQtType;
|
use cxx_qt::CxxQtType;
|
||||||
use cxx_qt_lib::{QModelIndex, QString, QUrl, QVariant};
|
use cxx_qt_lib::{QModelIndex, QString, QUrl, QVariant};
|
||||||
use sqlx::{Connection, SqliteConnection, query, query_as};
|
use sqlx::{query, query_as, Connection, SqliteConnection};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::pin::Pin;
|
use std::pin::Pin;
|
||||||
use tracing::{debug, error};
|
use tracing::{debug, error};
|
||||||
|
@ -198,7 +181,7 @@ pub struct ImageModelRust {
|
||||||
highest_id: i32,
|
highest_id: i32,
|
||||||
images: Vec<Image>,
|
images: Vec<Image>,
|
||||||
inner_images: Vec<Image>,
|
inner_images: Vec<Image>,
|
||||||
db: SqliteConnection,
|
db: SqliteConnection
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for ImageModelRust {
|
impl Default for ImageModelRust {
|
||||||
|
@ -216,11 +199,9 @@ impl Default for ImageModelRust {
|
||||||
let mut db_url = String::from("sqlite://");
|
let mut db_url = String::from("sqlite://");
|
||||||
db_url.push_str(data.to_str().unwrap());
|
db_url.push_str(data.to_str().unwrap());
|
||||||
rt.block_on(async {
|
rt.block_on(async {
|
||||||
SqliteConnection::connect(&db_url)
|
SqliteConnection::connect(&db_url).await.expect("problems")
|
||||||
.await
|
|
||||||
.expect("problems")
|
|
||||||
})
|
})
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -234,13 +215,11 @@ pub fn get_image(index: i32) -> color_eyre::Result<Image> {
|
||||||
let mut db_url = String::from("sqlite://");
|
let mut db_url = String::from("sqlite://");
|
||||||
db_url.push_str(data.to_str().unwrap());
|
db_url.push_str(data.to_str().unwrap());
|
||||||
rt.block_on(async {
|
rt.block_on(async {
|
||||||
SqliteConnection::connect(&db_url)
|
SqliteConnection::connect(&db_url).await.expect("problems")
|
||||||
.await
|
|
||||||
.expect("problems")
|
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
rt.block_on(async {
|
rt.block_on(async {
|
||||||
let result = query_as!(Image, r#"SELECT id as "id: i32", title as "title!", file_path as "path!" from images where id = ?"#, index).fetch_one(&mut db).await?;
|
let result = query_as!(Image, r#"SELECT id as "id: i32", title as "title!", filePath as "path!" from images where id = ?"#, index).fetch_one(&mut db).await?;
|
||||||
Ok(result)
|
Ok(result)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -257,7 +236,7 @@ impl image_model::ImageModel {
|
||||||
pub fn setup(mut self: Pin<&mut Self>) {
|
pub fn setup(mut self: Pin<&mut Self>) {
|
||||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||||
rt.block_on(async {
|
rt.block_on(async {
|
||||||
let result = query_as!(Image, r#"SELECT id as "id: i32", title as "title!", file_path as "path!" from images"#).fetch_all(&mut self.as_mut().rust_mut().db).await;
|
let result = query_as!(Image, r#"SELECT id as "id: i32", title as "title!", filePath as "path!" from images"#).fetch_all(&mut self.as_mut().rust_mut().db).await;
|
||||||
match result {
|
match result {
|
||||||
Ok(i) => i.into_iter().for_each(|i| self.as_mut().add_image(i)),
|
Ok(i) => i.into_iter().for_each(|i| self.as_mut().add_image(i)),
|
||||||
Err(e) => error!("There was an error in converting songs: {e}"),
|
Err(e) => error!("There was an error in converting songs: {e}"),
|
||||||
|
@ -272,10 +251,7 @@ impl image_model::ImageModel {
|
||||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||||
|
|
||||||
rt.block_on(async {
|
rt.block_on(async {
|
||||||
let result =
|
let result = query!("delete from images where id = ?", index).execute(&mut self.as_mut().rust_mut().db).await;
|
||||||
query!("delete from images where id = ?", index)
|
|
||||||
.execute(&mut self.as_mut().rust_mut().db)
|
|
||||||
.await;
|
|
||||||
match result {
|
match result {
|
||||||
Ok(_i) => {
|
Ok(_i) => {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -332,7 +308,7 @@ impl image_model::ImageModel {
|
||||||
rt.block_on(async {
|
rt.block_on(async {
|
||||||
let image_title = image_title.to_string();
|
let image_title = image_title.to_string();
|
||||||
let image_path = image_path.to_string();
|
let image_path = image_path.to_string();
|
||||||
let result = query!(r#"INSERT into images (id, title, file_path) VALUES (?, ?, ?)"#,
|
let result = query!(r#"INSERT into images (id, title, filePath) VALUES (?, ?, ?)"#,
|
||||||
image_id,
|
image_id,
|
||||||
image_title,
|
image_title,
|
||||||
image_path)
|
image_path)
|
||||||
|
@ -391,13 +367,9 @@ impl image_model::ImageModel {
|
||||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||||
rt.block_on(async {
|
rt.block_on(async {
|
||||||
let title = updated_title.to_string();
|
let title = updated_title.to_string();
|
||||||
let result = query!(
|
let result = query!("UPDATE images SET title = ? where id = ?", title, index)
|
||||||
"UPDATE images SET title = ? where id = ?",
|
.execute(&mut self.as_mut().rust_mut().db)
|
||||||
title,
|
.await;
|
||||||
index
|
|
||||||
)
|
|
||||||
.execute(&mut self.as_mut().rust_mut().db)
|
|
||||||
.await;
|
|
||||||
match result {
|
match result {
|
||||||
Ok(_i) => {
|
Ok(_i) => {
|
||||||
for image in self
|
for image in self
|
||||||
|
@ -408,11 +380,9 @@ impl image_model::ImageModel {
|
||||||
.filter(|x| x.id == index)
|
.filter(|x| x.id == index)
|
||||||
{
|
{
|
||||||
image.title = title.clone();
|
image.title = title.clone();
|
||||||
debug!(
|
debug!(title = image.title,
|
||||||
title = image.title,
|
title = title,
|
||||||
title = title,
|
"updated image title");
|
||||||
"updated image title"
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
self.as_mut().data_changed(
|
self.as_mut().data_changed(
|
||||||
model_index,
|
model_index,
|
||||||
|
@ -424,7 +394,7 @@ impl image_model::ImageModel {
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
error!("Error connecting to db: {e}");
|
error!("Error connecting to db: {e}");
|
||||||
false
|
false
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
true
|
true
|
||||||
|
@ -444,13 +414,9 @@ impl image_model::ImageModel {
|
||||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||||
rt.block_on(async {
|
rt.block_on(async {
|
||||||
let updated_path = updated_path.to_string();
|
let updated_path = updated_path.to_string();
|
||||||
let result = query!(
|
let result = query!("UPDATE images SET filePath = ? where id = ?", updated_path, index)
|
||||||
"UPDATE images SET file_path = ? where id = ?",
|
.execute(&mut self.as_mut().rust_mut().db)
|
||||||
updated_path,
|
.await;
|
||||||
index
|
|
||||||
)
|
|
||||||
.execute(&mut self.as_mut().rust_mut().db)
|
|
||||||
.await;
|
|
||||||
match result {
|
match result {
|
||||||
Ok(_i) => {
|
Ok(_i) => {
|
||||||
for image in self
|
for image in self
|
||||||
|
@ -461,11 +427,9 @@ impl image_model::ImageModel {
|
||||||
.filter(|x| x.id == index)
|
.filter(|x| x.id == index)
|
||||||
{
|
{
|
||||||
image.path = updated_path.clone();
|
image.path = updated_path.clone();
|
||||||
debug!(
|
debug!(title = image.title,
|
||||||
title = image.title,
|
path = updated_path,
|
||||||
path = updated_path,
|
"updated image path");
|
||||||
"updated image path"
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
self.as_mut().data_changed(
|
self.as_mut().data_changed(
|
||||||
model_index,
|
model_index,
|
||||||
|
@ -477,7 +441,7 @@ impl image_model::ImageModel {
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
error!("Error connecting to db: {e}");
|
error!("Error connecting to db: {e}");
|
||||||
false
|
false
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
true
|
true
|
||||||
|
|
|
@ -8,9 +8,10 @@ pub mod service_item_model;
|
||||||
pub mod settings;
|
pub mod settings;
|
||||||
pub mod slide_model;
|
pub mod slide_model;
|
||||||
pub mod slide_object;
|
pub mod slide_object;
|
||||||
pub mod slide_types;
|
|
||||||
pub mod songs;
|
pub mod songs;
|
||||||
pub mod utils;
|
pub mod utils;
|
||||||
pub mod video_model;
|
pub mod video_model;
|
||||||
pub mod ytdl;
|
pub mod ytdl;
|
||||||
|
pub mod slide_types;
|
||||||
|
// pub mod core;
|
||||||
// mod video_thumbnail;
|
// mod video_thumbnail;
|
||||||
|
|
|
@ -4,20 +4,8 @@ pub mod settings;
|
||||||
fn main() {
|
fn main() {
|
||||||
let mut app = QGuiApplication::new();
|
let mut app = QGuiApplication::new();
|
||||||
let mut engine = QQmlApplicationEngine::new();
|
let mut engine = QQmlApplicationEngine::new();
|
||||||
let mut kde_qml_dir =
|
|
||||||
String::from("/usr/lib/x86_64-linux-gnu/qt6/qml/");
|
|
||||||
|
|
||||||
if let Ok(qml_dir) = env::var("NIXPKGS_QT6_QML_IMPORT_PATH") {
|
|
||||||
kde_qml_dir = qml_dir;
|
|
||||||
} else {
|
|
||||||
println!(
|
|
||||||
"cargo:warning=KDE_QMLDIR is not defined, used default value: {}",
|
|
||||||
kde_qml_dir
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(engine) = engine.as_mut() {
|
if let Some(engine) = engine.as_mut() {
|
||||||
engine.add_import_path(&QString::from(kde_qml_dir.as_str()));
|
|
||||||
engine.load(&QUrl::from(
|
engine.load(&QUrl::from(
|
||||||
"qrc:/qt/qml/com/cochrun/xyz/qml/main.qml",
|
"qrc:/qt/qml/com/cochrun/xyz/qml/main.qml",
|
||||||
));
|
));
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
use core::fmt;
|
use core::fmt;
|
||||||
use cxx_qt::CxxQtType;
|
use cxx_qt::CxxQtType;
|
||||||
use cxx_qt_lib::{QString, QStringList};
|
use cxx_qt_lib::{QString, QStringList};
|
||||||
use obws::Client;
|
|
||||||
use obws::responses::scenes::{CurrentProgramScene, Scenes};
|
use obws::responses::scenes::{CurrentProgramScene, Scenes};
|
||||||
|
use obws::Client;
|
||||||
|
|
||||||
|
|
||||||
use std::{error::Error, pin::Pin};
|
use std::{error::Error, pin::Pin};
|
||||||
use tracing::{debug, error};
|
use tracing::{debug, error};
|
||||||
|
@ -21,10 +22,7 @@ impl fmt::Debug for Obs {
|
||||||
f.debug_struct("Client")
|
f.debug_struct("Client")
|
||||||
.field("scenes", &self.scenes)
|
.field("scenes", &self.scenes)
|
||||||
.field("client", &self.client.is_some())
|
.field("client", &self.client.is_some())
|
||||||
.field(
|
.field("current_program_scene", &self.current_program_scene)
|
||||||
"current_program_scene",
|
|
||||||
&self.current_program_scene,
|
|
||||||
)
|
|
||||||
.finish()
|
.finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -39,6 +37,8 @@ impl Clone for Obs {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
impl Obs {
|
impl Obs {
|
||||||
pub async fn new() -> Result<Self, Box<dyn Error>> {
|
pub async fn new() -> Result<Self, Box<dyn Error>> {
|
||||||
let client =
|
let client =
|
||||||
|
@ -112,7 +112,7 @@ impl Obs {
|
||||||
fn make_client() -> Client {
|
fn make_client() -> Client {
|
||||||
let runtime = tokio::runtime::Runtime::new().unwrap();
|
let runtime = tokio::runtime::Runtime::new().unwrap();
|
||||||
let future = Client::connect("localhost", 4455, Some(""));
|
let future = Client::connect("localhost", 4455, Some(""));
|
||||||
|
|
||||||
runtime.block_on(future).unwrap()
|
runtime.block_on(future).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,8 +127,6 @@ mod obs {
|
||||||
type QList_QString = cxx_qt_lib::QList<QString>;
|
type QList_QString = cxx_qt_lib::QList<QString>;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[auto_cxx_name]
|
|
||||||
#[auto_rust_name]
|
|
||||||
unsafe extern "RustQt" {
|
unsafe extern "RustQt" {
|
||||||
#[qobject]
|
#[qobject]
|
||||||
#[qml_element]
|
#[qml_element]
|
||||||
|
@ -220,7 +218,7 @@ impl obs::ObsModel {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[ignore]
|
#[ignore]
|
||||||
#[test]
|
#[test]
|
||||||
pub fn test_obs_setting_scene() {
|
pub fn test_obs_setting_scene() {
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
pub mod presentation_model {
|
pub mod presentation_model {
|
||||||
unsafe extern "C++" {
|
unsafe extern "C++" {
|
||||||
include!(< QAbstractListModel >);
|
include!(< QAbstractListModel >);
|
||||||
type QAbstractListModel;
|
|
||||||
include!("cxx-qt-lib/qhash.h");
|
include!("cxx-qt-lib/qhash.h");
|
||||||
type QHash_i32_QByteArray =
|
type QHash_i32_QByteArray =
|
||||||
cxx_qt_lib::QHash<cxx_qt_lib::QHashPair_i32_QByteArray>;
|
cxx_qt_lib::QHash<cxx_qt_lib::QHashPair_i32_QByteArray>;
|
||||||
|
@ -34,18 +33,15 @@ pub mod presentation_model {
|
||||||
PageCount,
|
PageCount,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[auto_cxx_name]
|
|
||||||
#[auto_rust_name]
|
|
||||||
unsafe extern "RustQt" {
|
unsafe extern "RustQt" {
|
||||||
#[qobject]
|
#[qobject]
|
||||||
#[base = QAbstractListModel]
|
#[base = "QAbstractListModel"]
|
||||||
#[qml_element]
|
#[qml_element]
|
||||||
#[qproperty(i32, count)]
|
#[qproperty(i32, count)]
|
||||||
type PresentationModel = super::PresentationModelRust;
|
type PresentationModel = super::PresentationModelRust;
|
||||||
|
|
||||||
#[inherit]
|
#[inherit]
|
||||||
#[qsignal]
|
#[qsignal]
|
||||||
#[cxx_name = "dataChanged"]
|
|
||||||
fn data_changed(
|
fn data_changed(
|
||||||
self: Pin<&mut PresentationModel>,
|
self: Pin<&mut PresentationModel>,
|
||||||
top_left: &QModelIndex,
|
top_left: &QModelIndex,
|
||||||
|
@ -103,11 +99,8 @@ pub mod presentation_model {
|
||||||
|
|
||||||
impl cxx_qt::Threading for PresentationModel {}
|
impl cxx_qt::Threading for PresentationModel {}
|
||||||
|
|
||||||
#[auto_cxx_name]
|
|
||||||
#[auto_rust_name]
|
|
||||||
unsafe extern "RustQt" {
|
unsafe extern "RustQt" {
|
||||||
#[inherit]
|
#[inherit]
|
||||||
#[cxx_name = "beginInsertRows"]
|
|
||||||
unsafe fn begin_insert_rows(
|
unsafe fn begin_insert_rows(
|
||||||
self: Pin<&mut PresentationModel>,
|
self: Pin<&mut PresentationModel>,
|
||||||
parent: &QModelIndex,
|
parent: &QModelIndex,
|
||||||
|
@ -116,11 +109,9 @@ pub mod presentation_model {
|
||||||
);
|
);
|
||||||
|
|
||||||
#[inherit]
|
#[inherit]
|
||||||
#[cxx_name = "endInsertRows"]
|
|
||||||
unsafe fn end_insert_rows(self: Pin<&mut PresentationModel>);
|
unsafe fn end_insert_rows(self: Pin<&mut PresentationModel>);
|
||||||
|
|
||||||
#[inherit]
|
#[inherit]
|
||||||
#[cxx_name = "beginRemoveRows"]
|
|
||||||
unsafe fn begin_remove_rows(
|
unsafe fn begin_remove_rows(
|
||||||
self: Pin<&mut PresentationModel>,
|
self: Pin<&mut PresentationModel>,
|
||||||
parent: &QModelIndex,
|
parent: &QModelIndex,
|
||||||
|
@ -129,7 +120,6 @@ pub mod presentation_model {
|
||||||
);
|
);
|
||||||
|
|
||||||
#[inherit]
|
#[inherit]
|
||||||
#[cxx_name = "beginMoveRows"]
|
|
||||||
unsafe fn begin_move_rows(
|
unsafe fn begin_move_rows(
|
||||||
self: Pin<&mut PresentationModel>,
|
self: Pin<&mut PresentationModel>,
|
||||||
source_parent: &QModelIndex,
|
source_parent: &QModelIndex,
|
||||||
|
@ -140,25 +130,20 @@ pub mod presentation_model {
|
||||||
) -> bool;
|
) -> bool;
|
||||||
|
|
||||||
#[inherit]
|
#[inherit]
|
||||||
#[cxx_name = "endMoveRows"]
|
|
||||||
unsafe fn end_move_rows(self: Pin<&mut PresentationModel>);
|
unsafe fn end_move_rows(self: Pin<&mut PresentationModel>);
|
||||||
|
|
||||||
#[inherit]
|
#[inherit]
|
||||||
#[cxx_name = "endRemoveRows"]
|
|
||||||
unsafe fn end_remove_rows(self: Pin<&mut PresentationModel>);
|
unsafe fn end_remove_rows(self: Pin<&mut PresentationModel>);
|
||||||
|
|
||||||
#[inherit]
|
#[inherit]
|
||||||
#[cxx_name = "beginResetModel"]
|
|
||||||
unsafe fn begin_reset_model(
|
unsafe fn begin_reset_model(
|
||||||
self: Pin<&mut PresentationModel>,
|
self: Pin<&mut PresentationModel>,
|
||||||
);
|
);
|
||||||
|
|
||||||
#[inherit]
|
#[inherit]
|
||||||
#[cxx_name = "endResetModel"]
|
|
||||||
unsafe fn end_reset_model(self: Pin<&mut PresentationModel>);
|
unsafe fn end_reset_model(self: Pin<&mut PresentationModel>);
|
||||||
|
|
||||||
#[inherit]
|
#[inherit]
|
||||||
#[cxx_name = "canFetchMore"]
|
|
||||||
fn can_fetch_more(
|
fn can_fetch_more(
|
||||||
self: &PresentationModel,
|
self: &PresentationModel,
|
||||||
parent: &QModelIndex,
|
parent: &QModelIndex,
|
||||||
|
@ -182,14 +167,12 @@ pub mod presentation_model {
|
||||||
|
|
||||||
#[qinvokable]
|
#[qinvokable]
|
||||||
#[cxx_override]
|
#[cxx_override]
|
||||||
#[cxx_name = "roleNames"]
|
|
||||||
fn role_names(
|
fn role_names(
|
||||||
self: &PresentationModel,
|
self: &PresentationModel,
|
||||||
) -> QHash_i32_QByteArray;
|
) -> QHash_i32_QByteArray;
|
||||||
|
|
||||||
#[qinvokable]
|
#[qinvokable]
|
||||||
#[cxx_override]
|
#[cxx_override]
|
||||||
#[cxx_name = "rowCount"]
|
|
||||||
fn row_count(
|
fn row_count(
|
||||||
self: &PresentationModel,
|
self: &PresentationModel,
|
||||||
_parent: &QModelIndex,
|
_parent: &QModelIndex,
|
||||||
|
@ -201,7 +184,7 @@ use crate::presentation_model::presentation_model::QMap_QString_QVariant;
|
||||||
use crate::reveal_js;
|
use crate::reveal_js;
|
||||||
use cxx_qt::CxxQtType;
|
use cxx_qt::CxxQtType;
|
||||||
use cxx_qt_lib::{QModelIndex, QString, QUrl, QVariant};
|
use cxx_qt_lib::{QModelIndex, QString, QUrl, QVariant};
|
||||||
use sqlx::{Connection, SqliteConnection, query, query_as};
|
use sqlx::{query, query_as, Connection, SqliteConnection};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::pin::Pin;
|
use std::pin::Pin;
|
||||||
use tracing::{debug, error};
|
use tracing::{debug, error};
|
||||||
|
@ -225,7 +208,7 @@ pub struct PresentationModelRust {
|
||||||
highest_id: i32,
|
highest_id: i32,
|
||||||
presentations: Vec<Presentation>,
|
presentations: Vec<Presentation>,
|
||||||
inner_presentations: Vec<Presentation>,
|
inner_presentations: Vec<Presentation>,
|
||||||
db: SqliteConnection,
|
db: SqliteConnection
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for PresentationModelRust {
|
impl Default for PresentationModelRust {
|
||||||
|
@ -243,18 +226,14 @@ impl Default for PresentationModelRust {
|
||||||
let mut db_url = String::from("sqlite://");
|
let mut db_url = String::from("sqlite://");
|
||||||
db_url.push_str(data.to_str().unwrap());
|
db_url.push_str(data.to_str().unwrap());
|
||||||
rt.block_on(async {
|
rt.block_on(async {
|
||||||
SqliteConnection::connect(&db_url)
|
SqliteConnection::connect(&db_url).await.expect("problems")
|
||||||
.await
|
|
||||||
.expect("problems")
|
|
||||||
})
|
})
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_presentation(
|
pub fn get_presentation(index: i32) -> color_eyre::Result<Presentation> {
|
||||||
index: i32,
|
|
||||||
) -> color_eyre::Result<Presentation> {
|
|
||||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||||
let mut db = {
|
let mut db = {
|
||||||
let mut data = dirs::data_local_dir().unwrap();
|
let mut data = dirs::data_local_dir().unwrap();
|
||||||
|
@ -263,13 +242,11 @@ pub fn get_presentation(
|
||||||
let mut db_url = String::from("sqlite://");
|
let mut db_url = String::from("sqlite://");
|
||||||
db_url.push_str(data.to_str().unwrap());
|
db_url.push_str(data.to_str().unwrap());
|
||||||
rt.block_on(async {
|
rt.block_on(async {
|
||||||
SqliteConnection::connect(&db_url)
|
SqliteConnection::connect(&db_url).await.expect("problems")
|
||||||
.await
|
|
||||||
.expect("problems")
|
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
rt.block_on(async {
|
rt.block_on(async {
|
||||||
let result = query_as!(Presentation, r#"SELECT id as "id: i32", title as "title!", file_path as "path!", html as "html!", pageCount as "page_count!: i32" from presentations where id = ?"#, index).fetch_one(&mut db).await?;
|
let result = query_as!(Presentation, r#"SELECT id as "id: i32", title as "title!", filePath as "path!", html as "html!", pageCount as "page_count!: i32" from presentations where id = ?"#, index).fetch_one(&mut db).await?;
|
||||||
Ok(result)
|
Ok(result)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -286,7 +263,7 @@ impl presentation_model::PresentationModel {
|
||||||
pub fn setup(mut self: Pin<&mut Self>) {
|
pub fn setup(mut self: Pin<&mut Self>) {
|
||||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||||
rt.block_on(async {
|
rt.block_on(async {
|
||||||
let result = query_as!(Presentation, r#"SELECT id as "id: i32", title as "title!", file_path as "path!", html as "html!", pageCount as "page_count!: i32" from presentations"#).fetch_all(&mut self.as_mut().rust_mut().db).await;
|
let result = query_as!(Presentation, r#"SELECT id as "id: i32", title as "title!", filePath as "path!", html as "html!", pageCount as "page_count!: i32" from presentations"#).fetch_all(&mut self.as_mut().rust_mut().db).await;
|
||||||
match result {
|
match result {
|
||||||
Ok(p) => p.into_iter().for_each(|p| self.as_mut().add_presentation(p)),
|
Ok(p) => p.into_iter().for_each(|p| self.as_mut().add_presentation(p)),
|
||||||
Err(e) => error!("There was an error in converting songs: {e}"),
|
Err(e) => error!("There was an error in converting songs: {e}"),
|
||||||
|
@ -301,12 +278,7 @@ impl presentation_model::PresentationModel {
|
||||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||||
|
|
||||||
rt.block_on(async {
|
rt.block_on(async {
|
||||||
let result = query!(
|
let result = query!("delete from presentations where id = ?", index).execute(&mut self.as_mut().rust_mut().db).await;
|
||||||
"delete from presentations where id = ?",
|
|
||||||
index
|
|
||||||
)
|
|
||||||
.execute(&mut self.as_mut().rust_mut().db)
|
|
||||||
.await;
|
|
||||||
match result {
|
match result {
|
||||||
Ok(_i) => {
|
Ok(_i) => {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -393,7 +365,7 @@ impl presentation_model::PresentationModel {
|
||||||
rt.block_on(async {
|
rt.block_on(async {
|
||||||
let presentation_title = presentation_title.to_string();
|
let presentation_title = presentation_title.to_string();
|
||||||
let presentation_path = presentation_path.to_string();
|
let presentation_path = presentation_path.to_string();
|
||||||
let result = query!(r#"INSERT into presentations (id, title, file_path, html, pageCount) VALUES (?, ?, ?, ?, ?)"#,
|
let result = query!(r#"INSERT into presentations (id, title, filePath, html, pageCount) VALUES (?, ?, ?, ?, ?)"#,
|
||||||
presentation_id,
|
presentation_id,
|
||||||
presentation_title,
|
presentation_title,
|
||||||
presentation_path,
|
presentation_path,
|
||||||
|
@ -531,13 +503,9 @@ impl presentation_model::PresentationModel {
|
||||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||||
rt.block_on(async {
|
rt.block_on(async {
|
||||||
let title = updated_title.to_string();
|
let title = updated_title.to_string();
|
||||||
let result = query!(
|
let result = query!("UPDATE presentations SET title = ? where id = ?", title, index)
|
||||||
"UPDATE presentations SET title = ? where id = ?",
|
.execute(&mut self.as_mut().rust_mut().db)
|
||||||
title,
|
.await;
|
||||||
index
|
|
||||||
)
|
|
||||||
.execute(&mut self.as_mut().rust_mut().db)
|
|
||||||
.await;
|
|
||||||
match result {
|
match result {
|
||||||
Ok(_i) => {
|
Ok(_i) => {
|
||||||
for presentation in self
|
for presentation in self
|
||||||
|
@ -548,11 +516,9 @@ impl presentation_model::PresentationModel {
|
||||||
.filter(|x| x.id == index)
|
.filter(|x| x.id == index)
|
||||||
{
|
{
|
||||||
presentation.title = title.clone();
|
presentation.title = title.clone();
|
||||||
debug!(
|
debug!(title = presentation.title,
|
||||||
title = presentation.title,
|
title = title,
|
||||||
title = title,
|
"updated presentation title");
|
||||||
"updated presentation title"
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
self.as_mut().data_changed(
|
self.as_mut().data_changed(
|
||||||
model_index,
|
model_index,
|
||||||
|
@ -564,7 +530,7 @@ impl presentation_model::PresentationModel {
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
error!("Error connecting to db: {e}");
|
error!("Error connecting to db: {e}");
|
||||||
false
|
false
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
true
|
true
|
||||||
|
@ -583,13 +549,9 @@ impl presentation_model::PresentationModel {
|
||||||
|
|
||||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||||
rt.block_on(async {
|
rt.block_on(async {
|
||||||
let result = query!(
|
let result = query!("UPDATE presentations SET pageCount = ? where id = ?", updated_page_count, index)
|
||||||
"UPDATE presentations SET pageCount = ? where id = ?",
|
.execute(&mut self.as_mut().rust_mut().db)
|
||||||
updated_page_count,
|
.await;
|
||||||
index
|
|
||||||
)
|
|
||||||
.execute(&mut self.as_mut().rust_mut().db)
|
|
||||||
.await;
|
|
||||||
match result {
|
match result {
|
||||||
Ok(_i) => {
|
Ok(_i) => {
|
||||||
for presentation in self
|
for presentation in self
|
||||||
|
@ -599,13 +561,10 @@ impl presentation_model::PresentationModel {
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
.filter(|x| x.id == index)
|
.filter(|x| x.id == index)
|
||||||
{
|
{
|
||||||
presentation.page_count =
|
presentation.page_count = updated_page_count.clone();
|
||||||
updated_page_count.clone();
|
debug!(title = presentation.title,
|
||||||
debug!(
|
page_count = updated_page_count,
|
||||||
title = presentation.title,
|
"updated presentation page_count");
|
||||||
page_count = updated_page_count,
|
|
||||||
"updated presentation page_count"
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
self.as_mut().data_changed(
|
self.as_mut().data_changed(
|
||||||
model_index,
|
model_index,
|
||||||
|
@ -617,7 +576,7 @@ impl presentation_model::PresentationModel {
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
error!("Error connecting to db: {e}");
|
error!("Error connecting to db: {e}");
|
||||||
false
|
false
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
true
|
true
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
mod service_item_model {
|
mod service_item_model {
|
||||||
unsafe extern "C++" {
|
unsafe extern "C++" {
|
||||||
include!(< QAbstractListModel >);
|
include!(< QAbstractListModel >);
|
||||||
type QAbstractListModel;
|
|
||||||
include!("cxx-qt-lib/qhash.h");
|
include!("cxx-qt-lib/qhash.h");
|
||||||
type QHash_i32_QByteArray =
|
type QHash_i32_QByteArray =
|
||||||
cxx_qt_lib::QHash<cxx_qt_lib::QHashPair_i32_QByteArray>;
|
cxx_qt_lib::QHash<cxx_qt_lib::QHashPair_i32_QByteArray>;
|
||||||
|
@ -44,11 +43,9 @@ mod service_item_model {
|
||||||
Id,
|
Id,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[auto_cxx_name]
|
|
||||||
#[auto_rust_name]
|
|
||||||
unsafe extern "RustQt" {
|
unsafe extern "RustQt" {
|
||||||
#[qobject]
|
#[qobject]
|
||||||
#[base = QAbstractListModel]
|
#[base = "QAbstractListModel"]
|
||||||
#[qml_element]
|
#[qml_element]
|
||||||
#[qproperty(i32, count)]
|
#[qproperty(i32, count)]
|
||||||
#[qproperty(f32, save_progress)]
|
#[qproperty(f32, save_progress)]
|
||||||
|
@ -57,7 +54,6 @@ mod service_item_model {
|
||||||
|
|
||||||
#[inherit]
|
#[inherit]
|
||||||
#[qsignal]
|
#[qsignal]
|
||||||
#[cxx_name = "dataChanged"]
|
|
||||||
fn data_changed(
|
fn data_changed(
|
||||||
self: Pin<&mut ServiceItemModel>,
|
self: Pin<&mut ServiceItemModel>,
|
||||||
top_left: &QModelIndex,
|
top_left: &QModelIndex,
|
||||||
|
@ -186,20 +182,17 @@ mod service_item_model {
|
||||||
|
|
||||||
#[qinvokable]
|
#[qinvokable]
|
||||||
fn save(self: Pin<&mut ServiceItemModel>, file: QUrl)
|
fn save(self: Pin<&mut ServiceItemModel>, file: QUrl)
|
||||||
-> bool;
|
-> bool;
|
||||||
|
|
||||||
#[qinvokable]
|
#[qinvokable]
|
||||||
fn load(self: Pin<&mut ServiceItemModel>, file: QUrl)
|
fn load(self: Pin<&mut ServiceItemModel>, file: QUrl)
|
||||||
-> bool;
|
-> bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl cxx_qt::Threading for ServiceItemModel {}
|
impl cxx_qt::Threading for ServiceItemModel {}
|
||||||
|
|
||||||
#[auto_cxx_name]
|
|
||||||
#[auto_rust_name]
|
|
||||||
unsafe extern "RustQt" {
|
unsafe extern "RustQt" {
|
||||||
#[inherit]
|
#[inherit]
|
||||||
#[cxx_name = "beginInsertRows"]
|
|
||||||
unsafe fn begin_insert_rows(
|
unsafe fn begin_insert_rows(
|
||||||
self: Pin<&mut ServiceItemModel>,
|
self: Pin<&mut ServiceItemModel>,
|
||||||
parent: &QModelIndex,
|
parent: &QModelIndex,
|
||||||
|
@ -208,11 +201,9 @@ mod service_item_model {
|
||||||
);
|
);
|
||||||
|
|
||||||
#[inherit]
|
#[inherit]
|
||||||
#[cxx_name = "endInsertRows"]
|
|
||||||
unsafe fn end_insert_rows(self: Pin<&mut ServiceItemModel>);
|
unsafe fn end_insert_rows(self: Pin<&mut ServiceItemModel>);
|
||||||
|
|
||||||
#[inherit]
|
#[inherit]
|
||||||
#[cxx_name = "beginRemoveRows"]
|
|
||||||
unsafe fn begin_remove_rows(
|
unsafe fn begin_remove_rows(
|
||||||
self: Pin<&mut ServiceItemModel>,
|
self: Pin<&mut ServiceItemModel>,
|
||||||
parent: &QModelIndex,
|
parent: &QModelIndex,
|
||||||
|
@ -221,7 +212,6 @@ mod service_item_model {
|
||||||
);
|
);
|
||||||
|
|
||||||
#[inherit]
|
#[inherit]
|
||||||
#[cxx_name = "beginMoveRows"]
|
|
||||||
unsafe fn begin_move_rows(
|
unsafe fn begin_move_rows(
|
||||||
self: Pin<&mut ServiceItemModel>,
|
self: Pin<&mut ServiceItemModel>,
|
||||||
source_parent: &QModelIndex,
|
source_parent: &QModelIndex,
|
||||||
|
@ -232,23 +222,18 @@ mod service_item_model {
|
||||||
) -> bool;
|
) -> bool;
|
||||||
|
|
||||||
#[inherit]
|
#[inherit]
|
||||||
#[cxx_name = "endMoveRows"]
|
|
||||||
unsafe fn end_move_rows(self: Pin<&mut ServiceItemModel>);
|
unsafe fn end_move_rows(self: Pin<&mut ServiceItemModel>);
|
||||||
|
|
||||||
#[inherit]
|
#[inherit]
|
||||||
#[cxx_name = "endRemoveRows"]
|
|
||||||
unsafe fn end_remove_rows(self: Pin<&mut ServiceItemModel>);
|
unsafe fn end_remove_rows(self: Pin<&mut ServiceItemModel>);
|
||||||
|
|
||||||
#[inherit]
|
#[inherit]
|
||||||
#[cxx_name = "beginResetModel"]
|
|
||||||
unsafe fn begin_reset_model(self: Pin<&mut ServiceItemModel>);
|
unsafe fn begin_reset_model(self: Pin<&mut ServiceItemModel>);
|
||||||
|
|
||||||
#[inherit]
|
#[inherit]
|
||||||
#[cxx_name = "endResetModel"]
|
|
||||||
unsafe fn end_reset_model(self: Pin<&mut ServiceItemModel>);
|
unsafe fn end_reset_model(self: Pin<&mut ServiceItemModel>);
|
||||||
|
|
||||||
#[inherit]
|
#[inherit]
|
||||||
#[cxx_name = "canFetchMore"]
|
|
||||||
fn can_fetch_more(
|
fn can_fetch_more(
|
||||||
self: &ServiceItemModel,
|
self: &ServiceItemModel,
|
||||||
parent: &QModelIndex,
|
parent: &QModelIndex,
|
||||||
|
@ -272,14 +257,12 @@ mod service_item_model {
|
||||||
|
|
||||||
#[qinvokable]
|
#[qinvokable]
|
||||||
#[cxx_override]
|
#[cxx_override]
|
||||||
#[cxx_name = "roleNames"]
|
|
||||||
fn role_names(
|
fn role_names(
|
||||||
self: &ServiceItemModel,
|
self: &ServiceItemModel,
|
||||||
) -> QHash_i32_QByteArray;
|
) -> QHash_i32_QByteArray;
|
||||||
|
|
||||||
#[qinvokable]
|
#[qinvokable]
|
||||||
#[cxx_override]
|
#[cxx_override]
|
||||||
#[cxx_name = "rowCount"]
|
|
||||||
fn row_count(
|
fn row_count(
|
||||||
self: &ServiceItemModel,
|
self: &ServiceItemModel,
|
||||||
_parent: &QModelIndex,
|
_parent: &QModelIndex,
|
||||||
|
@ -288,21 +271,15 @@ mod service_item_model {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
use self::service_item_model::{
|
|
||||||
QHash_i32_QByteArray, QMap_QString_QVariant, QVector_i32,
|
|
||||||
ServiceRoles,
|
|
||||||
};
|
|
||||||
use crate::service_item_model::service_item_model::QList_QString;
|
use crate::service_item_model::service_item_model::QList_QString;
|
||||||
use crate::slide_types::SlideType;
|
use crate::songs::song_model::{get_song, Song};
|
||||||
use crate::songs::song_model::{Song, get_song};
|
|
||||||
use crate::{image_model, presentation_model, video_model};
|
use crate::{image_model, presentation_model, video_model};
|
||||||
use cxx_qt::{CxxQtType, Threading};
|
use cxx_qt::{CxxQtType, Threading};
|
||||||
use cxx_qt_lib::{
|
use cxx_qt_lib::{
|
||||||
QByteArray, QModelIndex, QString, QStringList, QUrl, QVariant,
|
QByteArray, QModelIndex, QString, QStringList, QUrl, QVariant,
|
||||||
};
|
};
|
||||||
use dirs;
|
use dirs;
|
||||||
// use lumina_core::service_items::ServiceItem as SI;
|
use serde_json::{json, Value};
|
||||||
use serde_json::{Value, json};
|
|
||||||
use std::iter;
|
use std::iter;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::pin::Pin;
|
use std::pin::Pin;
|
||||||
|
@ -311,6 +288,12 @@ use std::{fs, println};
|
||||||
use tar::{Archive, Builder};
|
use tar::{Archive, Builder};
|
||||||
use tracing::{debug, error};
|
use tracing::{debug, error};
|
||||||
use zstd::{Decoder, Encoder};
|
use zstd::{Decoder, Encoder};
|
||||||
|
use self::service_item_model::{
|
||||||
|
QHash_i32_QByteArray, QMap_QString_QVariant, QVector_i32,
|
||||||
|
ServiceRoles,
|
||||||
|
};
|
||||||
|
use crate::slide_types::SlideType;
|
||||||
|
use lumina_core::service_items::ServiceItem as SI;
|
||||||
|
|
||||||
use super::service_item_model::service_item_model::ServiceItemModel;
|
use super::service_item_model::service_item_model::ServiceItemModel;
|
||||||
|
|
||||||
|
@ -394,9 +377,7 @@ impl service_item_model::ServiceItemModel {
|
||||||
pub fn remove_items(mut self: Pin<&mut Self>) {
|
pub fn remove_items(mut self: Pin<&mut Self>) {
|
||||||
let mut indices = vec![];
|
let mut indices = vec![];
|
||||||
let mut items = self.service_items.clone();
|
let mut items = self.service_items.clone();
|
||||||
for (index, _item) in
|
for (index, _item) in items.iter_mut().enumerate().filter(|(_y, x)| x.selected) {
|
||||||
items.iter_mut().enumerate().filter(|(_y, x)| x.selected)
|
|
||||||
{
|
|
||||||
let index = index as i32;
|
let index = index as i32;
|
||||||
indices.push(index);
|
indices.push(index);
|
||||||
}
|
}
|
||||||
|
@ -455,10 +436,7 @@ impl service_item_model::ServiceItemModel {
|
||||||
self.as_mut().end_insert_rows();
|
self.as_mut().end_insert_rows();
|
||||||
}
|
}
|
||||||
debug!("ADDING: {:?}", &service_item);
|
debug!("ADDING: {:?}", &service_item);
|
||||||
self.as_mut().item_added(
|
self.as_mut().item_added(&service_item.database_id.unwrap_or_default(), &QString::from(&service_item.ty.to_string()));
|
||||||
&service_item.database_id.unwrap_or_default(),
|
|
||||||
&QString::from(&service_item.ty.to_string()),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn insert_item(
|
pub fn insert_item(
|
||||||
|
@ -497,11 +475,7 @@ impl service_item_model::ServiceItemModel {
|
||||||
self.as_mut().end_insert_rows();
|
self.as_mut().end_insert_rows();
|
||||||
}
|
}
|
||||||
debug!("ADDING: {:?}", &service_item);
|
debug!("ADDING: {:?}", &service_item);
|
||||||
self.as_mut().item_inserted(
|
self.as_mut().item_inserted(&index, &service_item.database_id.unwrap_or_default(), &QString::from(&service_item.ty.to_string()));
|
||||||
&index,
|
|
||||||
&service_item.database_id.unwrap_or_default(),
|
|
||||||
&QString::from(&service_item.ty.to_string()),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_item(
|
pub fn get_item(
|
||||||
|
@ -902,7 +876,8 @@ impl service_item_model::ServiceItemModel {
|
||||||
Some(name) => {
|
Some(name) => {
|
||||||
println!("audio: {:?}", &name);
|
println!("audio: {:?}", &name);
|
||||||
if name.to_str().unwrap() != "temp" {
|
if name.to_str().unwrap() != "temp" {
|
||||||
flat_audio = name.to_str().unwrap()
|
flat_audio =
|
||||||
|
name.to_str().unwrap()
|
||||||
} else {
|
} else {
|
||||||
flat_audio = "";
|
flat_audio = "";
|
||||||
}
|
}
|
||||||
|
@ -986,18 +961,12 @@ impl service_item_model::ServiceItemModel {
|
||||||
debug!(time = ?now.elapsed(), "file written");
|
debug!(time = ?now.elapsed(), "file written");
|
||||||
std::thread::spawn(move || {
|
std::thread::spawn(move || {
|
||||||
debug!(time = ?now.elapsed(), "idk");
|
debug!(time = ?now.elapsed(), "idk");
|
||||||
let dir = fs::read_dir(&temp_dir)
|
let dir = fs::read_dir(&temp_dir).expect("idk");
|
||||||
.expect("idk");
|
|
||||||
for (index, file) in dir.enumerate() {
|
for (index, file) in dir.enumerate() {
|
||||||
if let Ok(file) = file {
|
if let Ok(file) = file {
|
||||||
let file_name =
|
let file_name = file.file_name();
|
||||||
file.file_name();
|
|
||||||
debug!(?file, ?file_name);
|
debug!(?file, ?file_name);
|
||||||
let mut file =
|
let mut file = std::fs::File::open(file.path()).expect("missing file");
|
||||||
std::fs::File::open(
|
|
||||||
file.path(),
|
|
||||||
)
|
|
||||||
.expect("missing file");
|
|
||||||
tar.append_file(file_name, &mut file).expect("Error in moving file to tar");
|
tar.append_file(file_name, &mut file).expect("Error in moving file to tar");
|
||||||
thread.queue(move |mut service| {
|
thread.queue(move |mut service| {
|
||||||
service
|
service
|
||||||
|
@ -1008,11 +977,10 @@ impl service_item_model::ServiceItemModel {
|
||||||
)
|
)
|
||||||
}).expect("Problem queuing on cxx thread");
|
}).expect("Problem queuing on cxx thread");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
if let Ok(encoder) = tar.into_inner()
|
if let Ok(encoder) = tar.into_inner() {
|
||||||
{
|
if let Ok(done) = encoder.finish() {
|
||||||
if let Ok(done) = encoder.finish()
|
|
||||||
{
|
|
||||||
debug!(time = ?now.elapsed(), ?done, "tar finished");
|
debug!(time = ?now.elapsed(), ?done, "tar finished");
|
||||||
thread.queue(move |mut service| {
|
thread.queue(move |mut service| {
|
||||||
service.as_mut().set_save_progress(100.0);
|
service.as_mut().set_save_progress(100.0);
|
||||||
|
@ -1032,7 +1000,9 @@ impl service_item_model::ServiceItemModel {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
fs::remove_dir_all(&temp_dir)
|
fs::remove_dir_all(&temp_dir)
|
||||||
.expect("error in removal");
|
.expect(
|
||||||
|
"error in removal",
|
||||||
|
);
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -1088,9 +1058,7 @@ impl service_item_model::ServiceItemModel {
|
||||||
if !file_path.exists() {
|
if !file_path.exists() {
|
||||||
match file.unpack_in(&datadir) {
|
match file.unpack_in(&datadir) {
|
||||||
Ok(_t) => (),
|
Ok(_t) => (),
|
||||||
Err(e) => {
|
Err(e) => error!("Error unpacking archive: {}", e),
|
||||||
error!("Error unpacking archive: {}", e)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1312,9 +1280,7 @@ impl service_item_model::ServiceItemModel {
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
self.as_mut().add_service_item(&service_item);
|
self.as_mut().add_service_item(&service_item);
|
||||||
error!(
|
error!("Loaded service item with generic type since it was an unknown type.");
|
||||||
"Loaded service item with generic type since it was an unknown type."
|
|
||||||
);
|
|
||||||
// // files implement the Read trait
|
// // files implement the Read trait
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1375,9 +1341,7 @@ impl service_item_model::ServiceItemModel {
|
||||||
let mut vector_roles = QVector_i32::default();
|
let mut vector_roles = QVector_i32::default();
|
||||||
vector_roles.append(self.as_ref().get_role(role));
|
vector_roles.append(self.as_ref().get_role(role));
|
||||||
if let Some(index) =
|
if let Some(index) =
|
||||||
self.as_ref().service_items.iter().position(|x| {
|
self.as_ref().service_items.iter().position(|x| x.database_id.unwrap_or_default() == item_id)
|
||||||
x.database_id.unwrap_or_default() == item_id
|
|
||||||
})
|
|
||||||
{
|
{
|
||||||
let model_index = self.as_ref().index(
|
let model_index = self.as_ref().index(
|
||||||
index as i32,
|
index as i32,
|
||||||
|
@ -1391,6 +1355,7 @@ impl service_item_model::ServiceItemModel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub fn load_last_saved(self: Pin<&mut Self>) -> bool {
|
pub fn load_last_saved(self: Pin<&mut Self>) -> bool {
|
||||||
todo!();
|
todo!();
|
||||||
// Don't actually need
|
// Don't actually need
|
||||||
|
@ -1429,9 +1394,9 @@ impl service_item_model::ServiceItemModel {
|
||||||
ServiceRoles::Name => {
|
ServiceRoles::Name => {
|
||||||
QVariant::from(&service_item.name)
|
QVariant::from(&service_item.name)
|
||||||
}
|
}
|
||||||
ServiceRoles::Type => QVariant::from(&QString::from(
|
ServiceRoles::Type => {
|
||||||
&service_item.ty.clone().to_string(),
|
QVariant::from(&QString::from(&service_item.ty.clone().to_string()))
|
||||||
)),
|
}
|
||||||
ServiceRoles::Audio => {
|
ServiceRoles::Audio => {
|
||||||
QVariant::from(&service_item.audio)
|
QVariant::from(&service_item.audio)
|
||||||
}
|
}
|
||||||
|
@ -1468,9 +1433,9 @@ impl service_item_model::ServiceItemModel {
|
||||||
ServiceRoles::VideoEndTime => {
|
ServiceRoles::VideoEndTime => {
|
||||||
QVariant::from(&service_item.video_end_time)
|
QVariant::from(&service_item.video_end_time)
|
||||||
}
|
}
|
||||||
ServiceRoles::Id => QVariant::from(
|
ServiceRoles::Id => {
|
||||||
&service_item.database_id.unwrap_or_default(),
|
QVariant::from(&service_item.database_id.unwrap_or_default())
|
||||||
),
|
}
|
||||||
_ => QVariant::default(),
|
_ => QVariant::default(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -1538,21 +1503,22 @@ impl service_item_model::ServiceItemModel {
|
||||||
ServiceRoles::VideoEndTime.repr,
|
ServiceRoles::VideoEndTime.repr,
|
||||||
QByteArray::from("videoEndTime"),
|
QByteArray::from("videoEndTime"),
|
||||||
);
|
);
|
||||||
roles.insert(ServiceRoles::Id.repr, QByteArray::from("id"));
|
roles.insert(
|
||||||
|
ServiceRoles::Id.repr,
|
||||||
|
QByteArray::from("id"),
|
||||||
|
);
|
||||||
roles
|
roles
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn row_count(&self, _parent: &QModelIndex) -> i32 {
|
pub fn row_count(&self, _parent: &QModelIndex) -> i32 {
|
||||||
|
|
||||||
// println!("row count is {cnt}");
|
// println!("row count is {cnt}");
|
||||||
self.service_items.len() as i32
|
self.service_items.len() as i32
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ServiceItemModelRust {
|
impl ServiceItemModelRust {
|
||||||
pub fn save(
|
pub fn save(_model: Pin<&mut ServiceItemModel>, _file: QUrl) -> bool {
|
||||||
_model: Pin<&mut ServiceItemModel>,
|
|
||||||
_file: QUrl,
|
|
||||||
) -> bool {
|
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,8 +7,6 @@ mod settings {
|
||||||
type QUrl = cxx_qt_lib::QUrl;
|
type QUrl = cxx_qt_lib::QUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[auto_cxx_name]
|
|
||||||
#[auto_rust_name]
|
|
||||||
unsafe extern "RustQt" {
|
unsafe extern "RustQt" {
|
||||||
#[qobject]
|
#[qobject]
|
||||||
#[qml_element]
|
#[qml_element]
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
pub mod slide_model {
|
pub mod slide_model {
|
||||||
unsafe extern "C++" {
|
unsafe extern "C++" {
|
||||||
include!(< QAbstractListModel >);
|
include!(< QAbstractListModel >);
|
||||||
type QAbstractListModel;
|
|
||||||
include!("cxx-qt-lib/qhash.h");
|
include!("cxx-qt-lib/qhash.h");
|
||||||
type QHash_i32_QByteArray =
|
type QHash_i32_QByteArray =
|
||||||
cxx_qt_lib::QHash<cxx_qt_lib::QHashPair_i32_QByteArray>;
|
cxx_qt_lib::QHash<cxx_qt_lib::QHashPair_i32_QByteArray>;
|
||||||
|
@ -19,23 +18,18 @@ pub mod slide_model {
|
||||||
type QVector_i32 = cxx_qt_lib::QVector<i32>;
|
type QVector_i32 = cxx_qt_lib::QVector<i32>;
|
||||||
include!("cxx-qt-lib/qlist.h");
|
include!("cxx-qt-lib/qlist.h");
|
||||||
type QList_QString = cxx_qt_lib::QList<QString>;
|
type QList_QString = cxx_qt_lib::QList<QString>;
|
||||||
include!("liblumina/src/rust/slide_object.cxxqt.h");
|
include!("cxx-qt-gen/slide_object.cxxqt.h");
|
||||||
type SlideObject = crate::slide_object::qobject::SlideObject;
|
type SlideObject = crate::slide_object::slide_object::SlideObject;
|
||||||
include!("liblumina/src/rust/songs/song_model.cxxqt.h");
|
include!("cxx-qt-gen/song_model.cxxqt.h");
|
||||||
type SongModel =
|
type SongModel = crate::songs::song_model::song_model::SongModel;
|
||||||
crate::songs::song_model::song_model::SongModel;
|
include!("cxx-qt-gen/video_model.cxxqt.h");
|
||||||
include!("liblumina/src/rust/video_model.cxxqt.h");
|
|
||||||
type VideoModel = crate::video_model::video_model::VideoModel;
|
type VideoModel = crate::video_model::video_model::VideoModel;
|
||||||
include!("liblumina/src/rust/image_model.cxxqt.h");
|
include!("cxx-qt-gen/image_model.cxxqt.h");
|
||||||
type ImageModel = crate::image_model::image_model::ImageModel;
|
type ImageModel = crate::image_model::image_model::ImageModel;
|
||||||
include!("liblumina/src/rust/presentation_model.cxxqt.h");
|
include!("cxx-qt-gen/presentation_model.cxxqt.h");
|
||||||
type PresentationModel = crate::presentation_model::presentation_model::PresentationModel;
|
type PresentationModel = crate::presentation_model::presentation_model::PresentationModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
// extern "C++" {
|
|
||||||
// type SlideObject = crate::slide_object::qobject::SlideObject;
|
|
||||||
// }
|
|
||||||
|
|
||||||
#[qenum(SlideModel)]
|
#[qenum(SlideModel)]
|
||||||
enum SlideRoles {
|
enum SlideRoles {
|
||||||
Ty,
|
Ty,
|
||||||
|
@ -60,11 +54,9 @@ pub mod slide_model {
|
||||||
ObsScene,
|
ObsScene,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[auto_cxx_name]
|
|
||||||
#[auto_rust_name]
|
|
||||||
unsafe extern "RustQt" {
|
unsafe extern "RustQt" {
|
||||||
#[qobject]
|
#[qobject]
|
||||||
#[base = QAbstractListModel]
|
#[base = "QAbstractListModel"]
|
||||||
#[qml_element]
|
#[qml_element]
|
||||||
#[qproperty(i32, count)]
|
#[qproperty(i32, count)]
|
||||||
#[qproperty(*mut SlideObject, slide_object)]
|
#[qproperty(*mut SlideObject, slide_object)]
|
||||||
|
@ -76,7 +68,6 @@ pub mod slide_model {
|
||||||
|
|
||||||
#[inherit]
|
#[inherit]
|
||||||
#[qsignal]
|
#[qsignal]
|
||||||
#[cxx_name = "dataChanged"]
|
|
||||||
fn data_changed(
|
fn data_changed(
|
||||||
self: Pin<&mut SlideModel>,
|
self: Pin<&mut SlideModel>,
|
||||||
top_left: &QModelIndex,
|
top_left: &QModelIndex,
|
||||||
|
@ -160,11 +151,8 @@ pub mod slide_model {
|
||||||
|
|
||||||
impl cxx_qt::Threading for SlideModel {}
|
impl cxx_qt::Threading for SlideModel {}
|
||||||
|
|
||||||
#[auto_cxx_name]
|
|
||||||
#[auto_rust_name]
|
|
||||||
unsafe extern "RustQt" {
|
unsafe extern "RustQt" {
|
||||||
#[inherit]
|
#[inherit]
|
||||||
#[cxx_name = "beginInsertRows"]
|
|
||||||
unsafe fn begin_insert_rows(
|
unsafe fn begin_insert_rows(
|
||||||
self: Pin<&mut SlideModel>,
|
self: Pin<&mut SlideModel>,
|
||||||
parent: &QModelIndex,
|
parent: &QModelIndex,
|
||||||
|
@ -173,11 +161,9 @@ pub mod slide_model {
|
||||||
);
|
);
|
||||||
|
|
||||||
#[inherit]
|
#[inherit]
|
||||||
#[cxx_name = "endInsertRows"]
|
|
||||||
unsafe fn end_insert_rows(self: Pin<&mut SlideModel>);
|
unsafe fn end_insert_rows(self: Pin<&mut SlideModel>);
|
||||||
|
|
||||||
#[inherit]
|
#[inherit]
|
||||||
#[cxx_name = "beginRemoveRows"]
|
|
||||||
unsafe fn begin_remove_rows(
|
unsafe fn begin_remove_rows(
|
||||||
self: Pin<&mut SlideModel>,
|
self: Pin<&mut SlideModel>,
|
||||||
parent: &QModelIndex,
|
parent: &QModelIndex,
|
||||||
|
@ -186,19 +172,15 @@ pub mod slide_model {
|
||||||
);
|
);
|
||||||
|
|
||||||
#[inherit]
|
#[inherit]
|
||||||
#[cxx_name = "endRemoveRows"]
|
|
||||||
unsafe fn end_remove_rows(self: Pin<&mut SlideModel>);
|
unsafe fn end_remove_rows(self: Pin<&mut SlideModel>);
|
||||||
|
|
||||||
#[inherit]
|
#[inherit]
|
||||||
#[cxx_name = "beginResetModel"]
|
|
||||||
unsafe fn begin_reset_model(self: Pin<&mut SlideModel>);
|
unsafe fn begin_reset_model(self: Pin<&mut SlideModel>);
|
||||||
|
|
||||||
#[inherit]
|
#[inherit]
|
||||||
#[cxx_name = "endResetModel"]
|
|
||||||
unsafe fn end_reset_model(self: Pin<&mut SlideModel>);
|
unsafe fn end_reset_model(self: Pin<&mut SlideModel>);
|
||||||
|
|
||||||
#[inherit]
|
#[inherit]
|
||||||
#[cxx_name = "beginMoveRows"]
|
|
||||||
unsafe fn begin_move_rows(
|
unsafe fn begin_move_rows(
|
||||||
self: Pin<&mut SlideModel>,
|
self: Pin<&mut SlideModel>,
|
||||||
source_parent: &QModelIndex,
|
source_parent: &QModelIndex,
|
||||||
|
@ -209,11 +191,9 @@ pub mod slide_model {
|
||||||
) -> bool;
|
) -> bool;
|
||||||
|
|
||||||
#[inherit]
|
#[inherit]
|
||||||
#[cxx_name = "endMoveRows"]
|
|
||||||
unsafe fn end_move_rows(self: Pin<&mut SlideModel>);
|
unsafe fn end_move_rows(self: Pin<&mut SlideModel>);
|
||||||
|
|
||||||
#[inherit]
|
#[inherit]
|
||||||
#[cxx_name = "canFetchMore"]
|
|
||||||
fn can_fetch_more(
|
fn can_fetch_more(
|
||||||
self: &SlideModel,
|
self: &SlideModel,
|
||||||
parent: &QModelIndex,
|
parent: &QModelIndex,
|
||||||
|
@ -237,43 +217,38 @@ pub mod slide_model {
|
||||||
|
|
||||||
#[qinvokable]
|
#[qinvokable]
|
||||||
#[cxx_override]
|
#[cxx_override]
|
||||||
#[cxx_name = "roleNames"]
|
|
||||||
fn role_names(self: &SlideModel) -> QHash_i32_QByteArray;
|
fn role_names(self: &SlideModel) -> QHash_i32_QByteArray;
|
||||||
|
|
||||||
#[qinvokable]
|
#[qinvokable]
|
||||||
#[cxx_override]
|
#[cxx_override]
|
||||||
#[cxx_name = "rowCount"]
|
|
||||||
fn row_count(self: &SlideModel, _parent: &QModelIndex)
|
fn row_count(self: &SlideModel, _parent: &QModelIndex)
|
||||||
-> i32;
|
-> i32;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
use crate::image_model::image_model::ImageModel;
|
use crate::image_model::image_model::ImageModel;
|
||||||
use crate::image_model::{self, Image, ImageModelRust};
|
use crate::image_model::{self, Image, ImageModelRust};
|
||||||
use crate::obs::Obs;
|
|
||||||
use crate::presentation_model::presentation_model::PresentationModel;
|
use crate::presentation_model::presentation_model::PresentationModel;
|
||||||
use crate::presentation_model::{
|
use crate::presentation_model::{self, Presentation, PresentationModelRust};
|
||||||
self, Presentation, PresentationModelRust,
|
|
||||||
};
|
|
||||||
use crate::slide_model::slide_model::QList_QString;
|
|
||||||
use crate::songs::song_model::song_model::{self, SongModel};
|
use crate::songs::song_model::song_model::{self, SongModel};
|
||||||
use crate::songs::song_model::{Song, SongModelRust, get_song};
|
use crate::songs::song_model::{get_song, Song, SongModelRust};
|
||||||
use crate::video_model::video_model::VideoModel;
|
use crate::video_model::video_model::VideoModel;
|
||||||
use crate::video_model::{self, Video, VideoModelRust};
|
use crate::video_model::{self, Video, VideoModelRust};
|
||||||
use crate::{ffmpeg, slide_types::SlideType};
|
use crate::{ffmpeg, slide_types::SlideType};
|
||||||
use color_eyre::Section;
|
use crate::obs::Obs;
|
||||||
|
use crate::slide_model::slide_model::QList_QString;
|
||||||
use color_eyre::eyre::Result;
|
use color_eyre::eyre::Result;
|
||||||
|
use color_eyre::Section;
|
||||||
use cxx_qt::{CxxQtType, Threading};
|
use cxx_qt::{CxxQtType, Threading};
|
||||||
use cxx_qt_lib::{
|
use cxx_qt_lib::{
|
||||||
CaseSensitivity, QByteArray, QList, QModelIndex, QString,
|
CaseSensitivity, QByteArray, QList, QModelIndex, QString, QStringList, QVariant
|
||||||
QStringList, QVariant,
|
|
||||||
};
|
};
|
||||||
use slide_model::SlideObject;
|
use slide_model::SlideObject;
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::fmt::Display;
|
use std::fmt::{Display};
|
||||||
use std::{path::PathBuf, pin::Pin};
|
use std::{path::PathBuf, pin::Pin};
|
||||||
use tracing::{debug, error, warn};
|
use tracing::{debug, error};
|
||||||
|
|
||||||
use self::slide_model::{
|
use self::slide_model::{
|
||||||
QHash_i32_QByteArray, QMap_QString_QVariant, QVector_i32,
|
QHash_i32_QByteArray, QMap_QString_QVariant, QVector_i32,
|
||||||
|
@ -344,9 +319,7 @@ impl Display for ParseSlideError {
|
||||||
f: &mut std::fmt::Formatter<'_>,
|
f: &mut std::fmt::Formatter<'_>,
|
||||||
) -> std::fmt::Result {
|
) -> std::fmt::Result {
|
||||||
let message = match self {
|
let message = match self {
|
||||||
Self::UnknownType => {
|
Self::UnknownType => "The type does not exist. It needs to be one of 'song', 'video', 'image', 'presentation', or 'content'",
|
||||||
"The type does not exist. It needs to be one of 'song', 'video', 'image', 'presentation', or 'content'"
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
write!(f, "Error: {message}")
|
write!(f, "Error: {message}")
|
||||||
}
|
}
|
||||||
|
@ -363,40 +336,45 @@ impl Slide {
|
||||||
fn slides_from_song(song: Song) -> Result<Vec<Self>> {
|
fn slides_from_song(song: Song) -> Result<Vec<Self>> {
|
||||||
let list = song.get_lyric_list();
|
let list = song.get_lyric_list();
|
||||||
let total = list.len();
|
let total = list.len();
|
||||||
let vector = list
|
let mut vector: Vec<Slide> = vec![];
|
||||||
.iter()
|
list.iter().map(|t| t.to_string()).enumerate()
|
||||||
.map(|t| {
|
.for_each(|(i, s)| {
|
||||||
let s = t.to_string();
|
if song.background_type == "image" {
|
||||||
warn!(s);
|
vector.push(
|
||||||
s
|
Self {
|
||||||
})
|
text: s,
|
||||||
.enumerate()
|
ty: SlideType::Song,
|
||||||
.map(|(i, s)| Self {
|
audio: song.audio.clone(),
|
||||||
text: s,
|
image_background: song.background.clone(),
|
||||||
ty: SlideType::Song,
|
video_background: "".to_owned(),
|
||||||
audio: song.audio.clone(),
|
htext_alignment: song.horizontal_text_alignment.clone(),
|
||||||
image_background: if song.background_type == "image" {
|
vtext_alignment: song.vertical_text_alignment.clone(),
|
||||||
song.background.clone()
|
font: song.font.clone(),
|
||||||
} else {
|
font_size: song.font_size,
|
||||||
"".into()
|
slide_count: total as i32,
|
||||||
},
|
slide_index: i as i32,
|
||||||
video_background: if song.background_type == "video" {
|
..Default::default()
|
||||||
song.background.clone()
|
}
|
||||||
} else {
|
);
|
||||||
"".to_owned()
|
} else {
|
||||||
},
|
vector.push(
|
||||||
htext_alignment: song
|
Self {
|
||||||
.horizontal_text_alignment
|
text: s,
|
||||||
.clone(),
|
ty: SlideType::Song,
|
||||||
vtext_alignment: song.vertical_text_alignment.clone(),
|
audio: song.audio.clone(),
|
||||||
font: song.font.clone(),
|
image_background: "".to_owned(),
|
||||||
font_size: song.font_size,
|
video_background: song.background.clone(),
|
||||||
slide_count: total as i32,
|
htext_alignment: song.horizontal_text_alignment.clone(),
|
||||||
slide_index: i as i32,
|
vtext_alignment: song.vertical_text_alignment.clone(),
|
||||||
..Default::default()
|
font: song.font.clone(),
|
||||||
})
|
font_size: song.font_size,
|
||||||
.collect();
|
slide_count: total as i32,
|
||||||
warn!(?vector);
|
slide_index: i as i32,
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
});
|
||||||
Ok(vector)
|
Ok(vector)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -417,9 +395,7 @@ impl Slide {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn slides_from_presentation(
|
fn slides_from_presentation(presentation: Presentation) -> Result<Vec<Self>> {
|
||||||
presentation: Presentation,
|
|
||||||
) -> Result<Vec<Self>> {
|
|
||||||
let total = presentation.page_count;
|
let total = presentation.page_count;
|
||||||
let mut slides: Vec<Slide> = vec![];
|
let mut slides: Vec<Slide> = vec![];
|
||||||
for i in 0..total {
|
for i in 0..total {
|
||||||
|
@ -430,7 +406,7 @@ impl Slide {
|
||||||
image_background: presentation.path.clone(),
|
image_background: presentation.path.clone(),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
}
|
};
|
||||||
Ok(slides)
|
Ok(slides)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -480,12 +456,9 @@ impl slide_model::SlideModel {
|
||||||
index: i32,
|
index: i32,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let mut vector_roles = QVector_i32::default();
|
let mut vector_roles = QVector_i32::default();
|
||||||
vector_roles
|
vector_roles.append(self.get_role(SlideRoles::VideoThumbnail));
|
||||||
.append(self.get_role(SlideRoles::VideoThumbnail));
|
vector_roles.append(self.get_role(SlideRoles::VideoBackground));
|
||||||
vector_roles
|
vector_roles.append(self.get_role(SlideRoles::ImageBackground));
|
||||||
.append(self.get_role(SlideRoles::VideoBackground));
|
|
||||||
vector_roles
|
|
||||||
.append(self.get_role(SlideRoles::ImageBackground));
|
|
||||||
let rc = self.as_ref().count() - 1;
|
let rc = self.as_ref().count() - 1;
|
||||||
let tl = self.as_ref().index(0, 0, &QModelIndex::default());
|
let tl = self.as_ref().index(0, 0, &QModelIndex::default());
|
||||||
let br = self.as_ref().index(rc, 0, &QModelIndex::default());
|
let br = self.as_ref().index(rc, 0, &QModelIndex::default());
|
||||||
|
@ -497,11 +470,7 @@ impl slide_model::SlideModel {
|
||||||
let path =
|
let path =
|
||||||
PathBuf::from(slide.video_background.to_string());
|
PathBuf::from(slide.video_background.to_string());
|
||||||
let screenshot = ffmpeg::bg_path_from_video(&path);
|
let screenshot = ffmpeg::bg_path_from_video(&path);
|
||||||
let mut screenshot_string = screenshot
|
let mut screenshot_string = screenshot.clone().into_os_string().into_string().unwrap_or_default();
|
||||||
.clone()
|
|
||||||
.into_os_string()
|
|
||||||
.into_string()
|
|
||||||
.unwrap_or_default();
|
|
||||||
screenshot_string.insert_str(0, "file://");
|
screenshot_string.insert_str(0, "file://");
|
||||||
slide.video_thumbnail = screenshot_string;
|
slide.video_thumbnail = screenshot_string;
|
||||||
std::thread::spawn(move || {
|
std::thread::spawn(move || {
|
||||||
|
@ -514,7 +483,7 @@ impl slide_model::SlideModel {
|
||||||
"Error making video background"
|
"Error making video background"
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
match thread.queue(move |mut slide_model| {
|
match thread.queue(move |mut slide_model| {
|
||||||
slide_model.as_mut().data_changed(
|
slide_model.as_mut().data_changed(
|
||||||
&tl,
|
&tl,
|
||||||
|
@ -647,56 +616,37 @@ impl slide_model::SlideModel {
|
||||||
SlideType::Song => {
|
SlideType::Song => {
|
||||||
let song = get_song(item_model_id)?;
|
let song = get_song(item_model_id)?;
|
||||||
let slides = Slide::slides_from_song(song)?;
|
let slides = Slide::slides_from_song(song)?;
|
||||||
slides.iter().enumerate().for_each(|(i, slide)| {
|
slides.iter().for_each(|slide| self.as_mut().insert_slide(slide, index));
|
||||||
self.as_mut()
|
|
||||||
.insert_slide(slide, index + i as i32)
|
|
||||||
});
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
},
|
||||||
SlideType::Video => {
|
SlideType::Video => {
|
||||||
let video = video_model::get_video(item_model_id)?;
|
let video = video_model::get_video(item_model_id)?;
|
||||||
self.insert_slide(
|
self.insert_slide(&Slide::slide_from_video(video)?, index);
|
||||||
&Slide::slide_from_video(video)?,
|
|
||||||
index,
|
|
||||||
);
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
},
|
||||||
SlideType::Image => {
|
SlideType::Image => {
|
||||||
let result = image_model::get_image(item_model_id);
|
let result = image_model::get_image(item_model_id);
|
||||||
match result {
|
match result {
|
||||||
Ok(image) => self.insert_slide(
|
Ok(image) => self.insert_slide(&Slide::slide_from_image(image)?, index),
|
||||||
&Slide::slide_from_image(image)?,
|
|
||||||
index,
|
|
||||||
),
|
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
e.with_note(|| {
|
e.with_note(|| {
|
||||||
format!("This might fail if we are loading the items from a file")
|
format!("This might fail if we are loading the items from a file")
|
||||||
});
|
});
|
||||||
let mut slide = Slide::default();
|
let mut slide = Slide::default();
|
||||||
slide.image_background =
|
slide.image_background = "qrc:/assets/black.jpg".to_owned();
|
||||||
"qrc:/assets/black.jpg".to_owned();
|
|
||||||
self.insert_slide(&slide, index);
|
self.insert_slide(&slide, index);
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
},
|
||||||
SlideType::Content => {
|
SlideType::Content => {
|
||||||
todo!();
|
todo!();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
},
|
||||||
SlideType::Presentation(_) => {
|
SlideType::Presentation(_) => {
|
||||||
let presentation =
|
let presentation = presentation_model::get_presentation(item_model_id)?;
|
||||||
presentation_model::get_presentation(
|
let slides = Slide::slides_from_presentation(presentation)?;
|
||||||
item_model_id,
|
slides.iter().for_each(|slide| self.as_mut().insert_slide(slide, slide.slide_index + index));
|
||||||
)?;
|
|
||||||
let slides =
|
|
||||||
Slide::slides_from_presentation(presentation)?;
|
|
||||||
slides.iter().for_each(|slide| {
|
|
||||||
self.as_mut().insert_slide(
|
|
||||||
slide,
|
|
||||||
slide.slide_index + index,
|
|
||||||
)
|
|
||||||
});
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -706,7 +656,7 @@ impl slide_model::SlideModel {
|
||||||
self: Pin<&mut Self>,
|
self: Pin<&mut Self>,
|
||||||
item_model_id: i32,
|
item_model_id: i32,
|
||||||
kind: &QString,
|
kind: &QString,
|
||||||
) -> Result<()> {
|
) -> Result<()>{
|
||||||
let index = self.count;
|
let index = self.count;
|
||||||
self.insert_item_from_service(index, item_model_id, kind)
|
self.insert_item_from_service(index, item_model_id, kind)
|
||||||
}
|
}
|
||||||
|
@ -742,8 +692,7 @@ impl slide_model::SlideModel {
|
||||||
|
|
||||||
if let Some((i, slide)) = slides_iter
|
if let Some((i, slide)) = slides_iter
|
||||||
.clone()
|
.clone()
|
||||||
.enumerate()
|
.enumerate().find(|slide| slide.1.service_item_id == source_index)
|
||||||
.find(|slide| slide.1.service_item_id == source_index)
|
|
||||||
{
|
{
|
||||||
debug!(index = i, ?slide);
|
debug!(index = i, ?slide);
|
||||||
first_slide = i as i32;
|
first_slide = i as i32;
|
||||||
|
@ -756,8 +705,11 @@ impl slide_model::SlideModel {
|
||||||
|
|
||||||
// lets get the dest_slide and count
|
// lets get the dest_slide and count
|
||||||
if move_down {
|
if move_down {
|
||||||
if let Some((i, slide)) =
|
if let Some((i, slide)) = slides_iter
|
||||||
slides_iter.clone().enumerate().rev().find(|slide| {
|
.clone()
|
||||||
|
.enumerate()
|
||||||
|
.rev()
|
||||||
|
.find(|slide| {
|
||||||
slide.1.service_item_id == destination_index
|
slide.1.service_item_id == destination_index
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
|
@ -772,8 +724,9 @@ impl slide_model::SlideModel {
|
||||||
dest_slide, dest_count
|
dest_slide, dest_count
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else if let Some((i, slide)) =
|
} else if let Some((i, slide)) = slides_iter
|
||||||
slides_iter.enumerate().find(|slide| {
|
.enumerate()
|
||||||
|
.find(|slide| {
|
||||||
slide.1.service_item_id == destination_index
|
slide.1.service_item_id == destination_index
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
|
@ -820,9 +773,7 @@ impl slide_model::SlideModel {
|
||||||
// Change the service_item_id of the moved slide
|
// Change the service_item_id of the moved slide
|
||||||
if count > 1 {
|
if count > 1 {
|
||||||
if move_down {
|
if move_down {
|
||||||
debug!(
|
debug!("While moving down, change service items id of moved slide");
|
||||||
"While moving down, change service items id of moved slide"
|
|
||||||
);
|
|
||||||
for (i, _slide) in slides_iter
|
for (i, _slide) in slides_iter
|
||||||
.clone()
|
.clone()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
|
@ -840,16 +791,13 @@ impl slide_model::SlideModel {
|
||||||
debug!(
|
debug!(
|
||||||
?slide,
|
?slide,
|
||||||
"rust: these ones right here officer. from {:?} to {:?}",
|
"rust: these ones right here officer. from {:?} to {:?}",
|
||||||
slide.service_item_id,
|
slide.service_item_id, destination_index
|
||||||
destination_index
|
|
||||||
);
|
);
|
||||||
slide.service_item_id = destination_index;
|
slide.service_item_id = destination_index;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
debug!(
|
debug!("While moving up, change service items id of moved slide");
|
||||||
"While moving up, change service items id of moved slide"
|
|
||||||
);
|
|
||||||
for (i, _slide) in slides_iter
|
for (i, _slide) in slides_iter
|
||||||
.clone()
|
.clone()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
|
@ -862,8 +810,7 @@ impl slide_model::SlideModel {
|
||||||
debug!(
|
debug!(
|
||||||
?slide,
|
?slide,
|
||||||
"rust: these ones right here officer. from {:?} to {:?}",
|
"rust: these ones right here officer. from {:?} to {:?}",
|
||||||
slide.service_item_id,
|
slide.service_item_id, destination_index
|
||||||
destination_index
|
|
||||||
);
|
);
|
||||||
slide.service_item_id = destination_index;
|
slide.service_item_id = destination_index;
|
||||||
}
|
}
|
||||||
|
@ -935,9 +882,7 @@ impl slide_model::SlideModel {
|
||||||
// self.as_mut().end_reset_model();
|
// self.as_mut().end_reset_model();
|
||||||
// }
|
// }
|
||||||
|
|
||||||
debug!(
|
debug!("rust-move: {first_slide} to {dest_slide} with {count} slides");
|
||||||
"rust-move: {first_slide} to {dest_slide} with {count} slides"
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn move_items(
|
fn move_items(
|
||||||
|
@ -1056,8 +1001,7 @@ impl slide_model::SlideModel {
|
||||||
debug!(service_item = index, "Getting slide from this item");
|
debug!(service_item = index, "Getting slide from this item");
|
||||||
let mut id = 0;
|
let mut id = 0;
|
||||||
if let Some((i, slide)) = slides_iter
|
if let Some((i, slide)) = slides_iter
|
||||||
.enumerate()
|
.enumerate().find(|(_i, slide)| slide.service_item_id == index)
|
||||||
.find(|(_i, slide)| slide.service_item_id == index)
|
|
||||||
{
|
{
|
||||||
debug!(slide_id = i, ?slide);
|
debug!(slide_id = i, ?slide);
|
||||||
id = i as i32;
|
id = i as i32;
|
||||||
|
@ -1161,6 +1105,7 @@ impl slide_model::SlideModel {
|
||||||
(0, QModelIndex::default(), vector_roles)
|
(0, QModelIndex::default(), vector_roles)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// QAbstractListModel implementation
|
// QAbstractListModel implementation
|
||||||
|
@ -1169,30 +1114,22 @@ impl slide_model::SlideModel {
|
||||||
let role = SlideRoles { repr: role };
|
let role = SlideRoles { repr: role };
|
||||||
if let Some(slide) = self.slides.get(index.row() as usize) {
|
if let Some(slide) = self.slides.get(index.row() as usize) {
|
||||||
return match role {
|
return match role {
|
||||||
SlideRoles::Ty => QVariant::from(&QString::from(
|
SlideRoles::Ty => QVariant::from(&QString::from(&slide.ty.to_string())),
|
||||||
&slide.ty.to_string(),
|
SlideRoles::Text => QVariant::from(&QString::from(&slide.text)),
|
||||||
)),
|
SlideRoles::Audio => QVariant::from(&QString::from(&slide.audio)),
|
||||||
SlideRoles::Text => {
|
SlideRoles::ImageBackground => {
|
||||||
QVariant::from(&QString::from(&slide.text))
|
QVariant::from(&QString::from(&slide.image_background))
|
||||||
}
|
}
|
||||||
SlideRoles::Audio => {
|
SlideRoles::VideoBackground => {
|
||||||
QVariant::from(&QString::from(&slide.audio))
|
QVariant::from(&QString::from(&slide.video_background))
|
||||||
}
|
}
|
||||||
SlideRoles::ImageBackground => QVariant::from(
|
SlideRoles::HTextAlignment => {
|
||||||
&QString::from(&slide.image_background),
|
QVariant::from(&QString::from(&slide.htext_alignment))
|
||||||
),
|
|
||||||
SlideRoles::VideoBackground => QVariant::from(
|
|
||||||
&QString::from(&slide.video_background),
|
|
||||||
),
|
|
||||||
SlideRoles::HTextAlignment => QVariant::from(
|
|
||||||
&QString::from(&slide.htext_alignment),
|
|
||||||
),
|
|
||||||
SlideRoles::VTextAlignment => QVariant::from(
|
|
||||||
&QString::from(&slide.vtext_alignment),
|
|
||||||
),
|
|
||||||
SlideRoles::Font => {
|
|
||||||
QVariant::from(&QString::from(&slide.font))
|
|
||||||
}
|
}
|
||||||
|
SlideRoles::VTextAlignment => {
|
||||||
|
QVariant::from(&QString::from(&slide.vtext_alignment))
|
||||||
|
}
|
||||||
|
SlideRoles::Font => QVariant::from(&QString::from(&slide.font)),
|
||||||
SlideRoles::FontSize => {
|
SlideRoles::FontSize => {
|
||||||
QVariant::from(&slide.font_size)
|
QVariant::from(&slide.font_size)
|
||||||
}
|
}
|
||||||
|
@ -1210,9 +1147,9 @@ impl slide_model::SlideModel {
|
||||||
QVariant::from(&slide.selected)
|
QVariant::from(&slide.selected)
|
||||||
}
|
}
|
||||||
SlideRoles::Looping => QVariant::from(&slide.looping),
|
SlideRoles::Looping => QVariant::from(&slide.looping),
|
||||||
SlideRoles::VideoThumbnail => QVariant::from(
|
SlideRoles::VideoThumbnail => {
|
||||||
&QString::from(&slide.video_thumbnail),
|
QVariant::from(&QString::from(&slide.video_thumbnail))
|
||||||
),
|
}
|
||||||
SlideRoles::VideoStartTime => {
|
SlideRoles::VideoStartTime => {
|
||||||
QVariant::from(&slide.video_start_time)
|
QVariant::from(&slide.video_start_time)
|
||||||
}
|
}
|
||||||
|
@ -1319,8 +1256,7 @@ impl slide_model::SlideModel {
|
||||||
fn extract_string(item: &QMap_QString_QVariant, key: &str) -> String {
|
fn extract_string(item: &QMap_QString_QVariant, key: &str) -> String {
|
||||||
item.get(&QString::from(key))
|
item.get(&QString::from(key))
|
||||||
.unwrap_or(QVariant::from(&QString::default()))
|
.unwrap_or(QVariant::from(&QString::default()))
|
||||||
.value_or_default::<QString>()
|
.value_or_default::<QString>().to_string()
|
||||||
.to_string()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn extract_value(item: &QMap_QString_QVariant, key: &str) -> i32 {
|
fn extract_value(item: &QMap_QString_QVariant, key: &str) -> i32 {
|
||||||
|
@ -1341,11 +1277,12 @@ fn extract_bool(item: &QMap_QString_QVariant, key: &str) -> bool {
|
||||||
.value_or_default::<bool>()
|
.value_or_default::<bool>()
|
||||||
}
|
}
|
||||||
|
|
||||||
// #[cfg(test)]
|
#[cfg(test)]
|
||||||
// mod test {
|
mod test {
|
||||||
|
|
||||||
|
|
||||||
// #[test]
|
#[test]
|
||||||
// pub fn test_obs_setting_scene() {
|
pub fn test_obs_setting_scene() {
|
||||||
// assert_eq!(true, true)
|
assert_eq!(true, true)
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#[cxx_qt::bridge]
|
#[cxx_qt::bridge]
|
||||||
pub mod qobject {
|
pub mod slide_object {
|
||||||
unsafe extern "C++" {
|
unsafe extern "C++" {
|
||||||
include!("cxx-qt-lib/qstring.h");
|
include!("cxx-qt-lib/qstring.h");
|
||||||
type QString = cxx_qt_lib::QString;
|
type QString = cxx_qt_lib::QString;
|
||||||
|
@ -10,31 +10,7 @@ pub mod qobject {
|
||||||
// type SlideModel = crate::slide_model::slide_model::SlideModel;
|
// type SlideModel = crate::slide_model::slide_model::SlideModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[auto_cxx_name]
|
|
||||||
#[auto_rust_name]
|
|
||||||
unsafe extern "RustQt" {
|
unsafe extern "RustQt" {
|
||||||
#[qobject]
|
|
||||||
#[qml_element]
|
|
||||||
#[qproperty(i32, slide_index)]
|
|
||||||
#[qproperty(i32, slide_size)]
|
|
||||||
#[qproperty(i32, inner_slide_index)]
|
|
||||||
#[qproperty(bool, is_playing)]
|
|
||||||
#[qproperty(bool, looping)]
|
|
||||||
#[qproperty(QString, text)]
|
|
||||||
#[qproperty(QString, ty)]
|
|
||||||
#[qproperty(QString, audio)]
|
|
||||||
#[qproperty(QString, image_background)]
|
|
||||||
#[qproperty(QString, video_background)]
|
|
||||||
#[qproperty(bool, html)]
|
|
||||||
#[qproperty(QString, vtext_alignment)]
|
|
||||||
#[qproperty(QString, htext_alignment)]
|
|
||||||
#[qproperty(QString, font)]
|
|
||||||
#[qproperty(i32, font_size)]
|
|
||||||
#[qproperty(f32, video_start_time)]
|
|
||||||
#[qproperty(f32, video_end_time)]
|
|
||||||
// #[qproperty(*mut SlideModel, slide_model)]
|
|
||||||
type SlideObject = super::SlideObjectRust;
|
|
||||||
|
|
||||||
#[qsignal]
|
#[qsignal]
|
||||||
fn playing_changed(
|
fn playing_changed(
|
||||||
self: Pin<&mut SlideObject>,
|
self: Pin<&mut SlideObject>,
|
||||||
|
@ -59,6 +35,28 @@ pub mod qobject {
|
||||||
#[qsignal]
|
#[qsignal]
|
||||||
fn reveal_prev(self: Pin<&mut SlideObject>);
|
fn reveal_prev(self: Pin<&mut SlideObject>);
|
||||||
|
|
||||||
|
#[qobject]
|
||||||
|
#[qml_element]
|
||||||
|
#[qproperty(i32, slide_index)]
|
||||||
|
#[qproperty(i32, slide_size)]
|
||||||
|
#[qproperty(i32, inner_slide_index)]
|
||||||
|
#[qproperty(bool, is_playing)]
|
||||||
|
#[qproperty(bool, looping)]
|
||||||
|
#[qproperty(QString, text)]
|
||||||
|
#[qproperty(QString, ty)]
|
||||||
|
#[qproperty(QString, audio)]
|
||||||
|
#[qproperty(QString, image_background)]
|
||||||
|
#[qproperty(QString, video_background)]
|
||||||
|
#[qproperty(bool, html)]
|
||||||
|
#[qproperty(QString, vtext_alignment)]
|
||||||
|
#[qproperty(QString, htext_alignment)]
|
||||||
|
#[qproperty(QString, font)]
|
||||||
|
#[qproperty(i32, font_size)]
|
||||||
|
#[qproperty(f32, video_start_time)]
|
||||||
|
#[qproperty(f32, video_end_time)]
|
||||||
|
// #[qproperty(*mut SlideModel, slide_model)]
|
||||||
|
type SlideObject = super::SlideObjectRust;
|
||||||
|
|
||||||
#[qinvokable]
|
#[qinvokable]
|
||||||
fn change_slide(
|
fn change_slide(
|
||||||
self: Pin<&mut SlideObject>,
|
self: Pin<&mut SlideObject>,
|
||||||
|
@ -91,11 +89,10 @@ use cxx_qt_lib::{CaseSensitivity, QString, QVariant};
|
||||||
use tracing::{debug, error};
|
use tracing::{debug, error};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
slide_model::{Slide, slide_model},
|
slide_model::{slide_model, Slide}, slide_types::SlideType
|
||||||
slide_types::SlideType,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use self::qobject::QMap_QString_QVariant;
|
use self::slide_object::QMap_QString_QVariant;
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct SlideObjectRust {
|
pub struct SlideObjectRust {
|
||||||
|
@ -144,7 +141,7 @@ impl Default for SlideObjectRust {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl qobject::SlideObject {
|
impl slide_object::SlideObject {
|
||||||
pub fn change_slide(
|
pub fn change_slide(
|
||||||
mut self: Pin<&mut Self>,
|
mut self: Pin<&mut Self>,
|
||||||
item: QMap_QString_QVariant,
|
item: QMap_QString_QVariant,
|
||||||
|
@ -487,18 +484,10 @@ impl qobject::SlideObject {
|
||||||
self.as_mut().set_text(QString::from(&slide.text));
|
self.as_mut().set_text(QString::from(&slide.text));
|
||||||
self.as_mut().set_ty(QString::from(&slide.ty.to_string()));
|
self.as_mut().set_ty(QString::from(&slide.ty.to_string()));
|
||||||
self.as_mut().set_audio(QString::from(&slide.audio));
|
self.as_mut().set_audio(QString::from(&slide.audio));
|
||||||
self.as_mut().set_image_background(QString::from(
|
self.as_mut().set_image_background(QString::from(&slide.image_background));
|
||||||
&slide.image_background,
|
self.as_mut().set_video_background(QString::from(&slide.video_background));
|
||||||
));
|
self.as_mut().set_vtext_alignment(QString::from(&slide.vtext_alignment));
|
||||||
self.as_mut().set_video_background(QString::from(
|
self.as_mut().set_htext_alignment(QString::from(&slide.htext_alignment));
|
||||||
&slide.video_background,
|
|
||||||
));
|
|
||||||
self.as_mut().set_vtext_alignment(QString::from(
|
|
||||||
&slide.vtext_alignment,
|
|
||||||
));
|
|
||||||
self.as_mut().set_htext_alignment(QString::from(
|
|
||||||
&slide.htext_alignment,
|
|
||||||
));
|
|
||||||
self.as_mut().set_font(QString::from(&slide.font));
|
self.as_mut().set_font(QString::from(&slide.font));
|
||||||
self.as_mut().set_font_size(slide.font_size);
|
self.as_mut().set_font_size(slide.font_size);
|
||||||
self.as_mut().set_video_start_time(slide.video_start_time);
|
self.as_mut().set_video_start_time(slide.video_start_time);
|
||||||
|
|
|
@ -15,13 +15,11 @@ pub mod song_editor {
|
||||||
include!("cxx-qt-lib/qlist.h");
|
include!("cxx-qt-lib/qlist.h");
|
||||||
type QList_QString = cxx_qt_lib::QList<QString>;
|
type QList_QString = cxx_qt_lib::QList<QString>;
|
||||||
|
|
||||||
include!("liblumina/src/rust/songs/song_model.cxxqt.h");
|
include!("cxx-qt-gen/song_model.cxxqt.h");
|
||||||
type SongModel =
|
type SongModel =
|
||||||
crate::songs::song_model::song_model::SongModel;
|
crate::songs::song_model::song_model::SongModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[auto_cxx_name]
|
|
||||||
#[auto_rust_name]
|
|
||||||
unsafe extern "RustQt" {
|
unsafe extern "RustQt" {
|
||||||
#[qobject]
|
#[qobject]
|
||||||
#[qml_element]
|
#[qml_element]
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
pub mod song_model {
|
pub mod song_model {
|
||||||
unsafe extern "C++" {
|
unsafe extern "C++" {
|
||||||
include!(< QAbstractListModel >);
|
include!(< QAbstractListModel >);
|
||||||
type QAbstractListModel;
|
|
||||||
include!("cxx-qt-lib/qhash.h");
|
include!("cxx-qt-lib/qhash.h");
|
||||||
type QHash_i32_QByteArray =
|
type QHash_i32_QByteArray =
|
||||||
cxx_qt_lib::QHash<cxx_qt_lib::QHashPair_i32_QByteArray>;
|
cxx_qt_lib::QHash<cxx_qt_lib::QHashPair_i32_QByteArray>;
|
||||||
|
@ -40,18 +39,15 @@ pub mod song_model {
|
||||||
FontSize,
|
FontSize,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[auto_cxx_name]
|
|
||||||
#[auto_rust_name]
|
|
||||||
unsafe extern "RustQt" {
|
unsafe extern "RustQt" {
|
||||||
#[qobject]
|
#[qobject]
|
||||||
#[base = QAbstractListModel]
|
#[base = "QAbstractListModel"]
|
||||||
#[qml_element]
|
#[qml_element]
|
||||||
#[qproperty(i32, count)]
|
#[qproperty(i32, count)]
|
||||||
type SongModel = super::SongModelRust;
|
type SongModel = super::SongModelRust;
|
||||||
|
|
||||||
#[inherit]
|
#[inherit]
|
||||||
#[qsignal]
|
#[qsignal]
|
||||||
#[cxx_name = "dataChanged"]
|
|
||||||
fn data_changed(
|
fn data_changed(
|
||||||
self: Pin<&mut SongModel>,
|
self: Pin<&mut SongModel>,
|
||||||
top_left: &QModelIndex,
|
top_left: &QModelIndex,
|
||||||
|
@ -79,7 +75,7 @@ pub mod song_model {
|
||||||
fn setup(self: Pin<&mut SongModel>);
|
fn setup(self: Pin<&mut SongModel>);
|
||||||
#[qinvokable]
|
#[qinvokable]
|
||||||
fn remove_item(self: Pin<&mut SongModel>, index: i32)
|
fn remove_item(self: Pin<&mut SongModel>, index: i32)
|
||||||
-> bool;
|
-> bool;
|
||||||
#[qinvokable]
|
#[qinvokable]
|
||||||
fn new_song(self: Pin<&mut SongModel>) -> bool;
|
fn new_song(self: Pin<&mut SongModel>) -> bool;
|
||||||
#[qinvokable]
|
#[qinvokable]
|
||||||
|
@ -170,11 +166,8 @@ pub mod song_model {
|
||||||
|
|
||||||
impl cxx_qt::Threading for SongModel {}
|
impl cxx_qt::Threading for SongModel {}
|
||||||
|
|
||||||
#[auto_cxx_name]
|
|
||||||
#[auto_rust_name]
|
|
||||||
unsafe extern "RustQt" {
|
unsafe extern "RustQt" {
|
||||||
#[inherit]
|
#[inherit]
|
||||||
#[cxx_name = "beginInsertRows"]
|
|
||||||
unsafe fn begin_insert_rows(
|
unsafe fn begin_insert_rows(
|
||||||
self: Pin<&mut SongModel>,
|
self: Pin<&mut SongModel>,
|
||||||
parent: &QModelIndex,
|
parent: &QModelIndex,
|
||||||
|
@ -183,11 +176,9 @@ pub mod song_model {
|
||||||
);
|
);
|
||||||
|
|
||||||
#[inherit]
|
#[inherit]
|
||||||
#[cxx_name = "endInsertRows"]
|
|
||||||
unsafe fn end_insert_rows(self: Pin<&mut SongModel>);
|
unsafe fn end_insert_rows(self: Pin<&mut SongModel>);
|
||||||
|
|
||||||
#[inherit]
|
#[inherit]
|
||||||
#[cxx_name = "beginRemoveRows"]
|
|
||||||
unsafe fn begin_remove_rows(
|
unsafe fn begin_remove_rows(
|
||||||
self: Pin<&mut SongModel>,
|
self: Pin<&mut SongModel>,
|
||||||
parent: &QModelIndex,
|
parent: &QModelIndex,
|
||||||
|
@ -196,7 +187,6 @@ pub mod song_model {
|
||||||
);
|
);
|
||||||
|
|
||||||
#[inherit]
|
#[inherit]
|
||||||
#[cxx_name = "beginMoveRows"]
|
|
||||||
unsafe fn begin_move_rows(
|
unsafe fn begin_move_rows(
|
||||||
self: Pin<&mut SongModel>,
|
self: Pin<&mut SongModel>,
|
||||||
source_parent: &QModelIndex,
|
source_parent: &QModelIndex,
|
||||||
|
@ -207,23 +197,18 @@ pub mod song_model {
|
||||||
) -> bool;
|
) -> bool;
|
||||||
|
|
||||||
#[inherit]
|
#[inherit]
|
||||||
#[cxx_name = "endMoveRows"]
|
|
||||||
unsafe fn end_move_rows(self: Pin<&mut SongModel>);
|
unsafe fn end_move_rows(self: Pin<&mut SongModel>);
|
||||||
|
|
||||||
#[inherit]
|
#[inherit]
|
||||||
#[cxx_name = "endRemoveRows"]
|
|
||||||
unsafe fn end_remove_rows(self: Pin<&mut SongModel>);
|
unsafe fn end_remove_rows(self: Pin<&mut SongModel>);
|
||||||
|
|
||||||
#[inherit]
|
#[inherit]
|
||||||
#[cxx_name = "beginResetModel"]
|
|
||||||
unsafe fn begin_reset_model(self: Pin<&mut SongModel>);
|
unsafe fn begin_reset_model(self: Pin<&mut SongModel>);
|
||||||
|
|
||||||
#[inherit]
|
#[inherit]
|
||||||
#[cxx_name = "endResetModel"]
|
|
||||||
unsafe fn end_reset_model(self: Pin<&mut SongModel>);
|
unsafe fn end_reset_model(self: Pin<&mut SongModel>);
|
||||||
|
|
||||||
#[inherit]
|
#[inherit]
|
||||||
#[cxx_name = "canFetchMore"]
|
|
||||||
fn can_fetch_more(
|
fn can_fetch_more(
|
||||||
self: &SongModel,
|
self: &SongModel,
|
||||||
parent: &QModelIndex,
|
parent: &QModelIndex,
|
||||||
|
@ -247,26 +232,24 @@ pub mod song_model {
|
||||||
|
|
||||||
#[qinvokable]
|
#[qinvokable]
|
||||||
#[cxx_override]
|
#[cxx_override]
|
||||||
#[cxx_name = "roleNames"]
|
|
||||||
fn role_names(self: &SongModel) -> QHash_i32_QByteArray;
|
fn role_names(self: &SongModel) -> QHash_i32_QByteArray;
|
||||||
|
|
||||||
#[qinvokable]
|
#[qinvokable]
|
||||||
#[cxx_override]
|
#[cxx_override]
|
||||||
#[cxx_name = "rowCount"]
|
|
||||||
fn row_count(self: &SongModel, _parent: &QModelIndex) -> i32;
|
fn row_count(self: &SongModel, _parent: &QModelIndex) -> i32;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
use crate::songs::song_editor::song_editor::QList_QString;
|
use crate::songs::song_editor::song_editor::QList_QString;
|
||||||
use color_eyre::Result;
|
|
||||||
use cxx_qt::{CxxQtType, Threading};
|
use cxx_qt::{CxxQtType, Threading};
|
||||||
use cxx_qt_lib::{
|
use cxx_qt_lib::{
|
||||||
QByteArray, QModelIndex, QString, QStringList, QVariant,
|
QByteArray, QModelIndex, QString, QStringList, QVariant,
|
||||||
};
|
};
|
||||||
use sqlx::{Connection, SqliteConnection, query, query_as};
|
use sqlx::{query, query_as, Connection, SqliteConnection};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::pin::Pin;
|
use std::pin::Pin;
|
||||||
use tracing::{debug, error};
|
use tracing::{debug, error};
|
||||||
|
use color_eyre::Result;
|
||||||
|
|
||||||
use self::song_model::{
|
use self::song_model::{
|
||||||
QHash_i32_QByteArray, QMap_QString_QVariant, QVector_i32,
|
QHash_i32_QByteArray, QMap_QString_QVariant, QVector_i32,
|
||||||
|
@ -305,86 +288,90 @@ impl Default for Song {
|
||||||
impl Song {
|
impl Song {
|
||||||
pub fn get_lyric_list(&self) -> QList_QString {
|
pub fn get_lyric_list(&self) -> QList_QString {
|
||||||
let mut lyric_list = QList_QString::default();
|
let mut lyric_list = QList_QString::default();
|
||||||
if self.lyrics.is_empty() {
|
if self.lyrics.is_empty() {
|
||||||
return QList_QString::default();
|
return QList_QString::default();
|
||||||
}
|
|
||||||
let raw_lyrics = self.lyrics.clone();
|
|
||||||
println!("raw-lyrics: {:?}", raw_lyrics);
|
|
||||||
let vorder: Vec<&str> = self.verse_order.split(' ').collect();
|
|
||||||
let keywords = vec![
|
|
||||||
"Verse 1", "Verse 2", "Verse 3", "Verse 4", "Verse 5",
|
|
||||||
"Verse 6", "Verse 7", "Verse 8", "Chorus 1", "Chorus 2",
|
|
||||||
"Chorus 3", "Chorus 4", "Bridge 1", "Bridge 2",
|
|
||||||
"Bridge 3", "Bridge 4", "Intro 1", "Intro 2", "Ending 1",
|
|
||||||
"Ending 2", "Other 1", "Other 2", "Other 3", "Other 4",
|
|
||||||
];
|
|
||||||
let _first_item = true;
|
|
||||||
|
|
||||||
let mut lyric_map = HashMap::new();
|
|
||||||
let mut verse_title = String::from("");
|
|
||||||
let mut lyric = String::from("");
|
|
||||||
for (i, line) in raw_lyrics.split('\n').enumerate() {
|
|
||||||
if keywords.contains(&line) {
|
|
||||||
if i != 0 {
|
|
||||||
// println!("{verse_title}");
|
|
||||||
// println!("{lyric}");
|
|
||||||
lyric_map.insert(verse_title, lyric);
|
|
||||||
lyric = String::from("");
|
|
||||||
verse_title = line.to_string();
|
|
||||||
// println!("{line}");
|
|
||||||
// println!("\n");
|
|
||||||
} else {
|
|
||||||
verse_title = line.to_string();
|
|
||||||
// println!("{line}");
|
|
||||||
// println!("\n");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
lyric.push_str(line);
|
|
||||||
lyric.push('\n');
|
|
||||||
}
|
}
|
||||||
}
|
let raw_lyrics = self.lyrics.clone();
|
||||||
lyric_map.insert(verse_title, lyric);
|
println!("raw-lyrics: {:?}", raw_lyrics);
|
||||||
// println!("da-map: {:?}", lyric_map);
|
let vorder: Vec<&str> =
|
||||||
|
self.verse_order.split(' ').collect();
|
||||||
|
let keywords = vec![
|
||||||
|
"Verse 1", "Verse 2", "Verse 3", "Verse 4",
|
||||||
|
"Verse 5", "Verse 6", "Verse 7", "Verse 8",
|
||||||
|
"Chorus 1", "Chorus 2", "Chorus 3", "Chorus 4",
|
||||||
|
"Bridge 1", "Bridge 2", "Bridge 3", "Bridge 4",
|
||||||
|
"Intro 1", "Intro 2", "Ending 1", "Ending 2",
|
||||||
|
"Other 1", "Other 2", "Other 3", "Other 4",
|
||||||
|
];
|
||||||
|
let _first_item = true;
|
||||||
|
|
||||||
for verse in vorder {
|
let mut lyric_map = HashMap::new();
|
||||||
let mut verse_name = "";
|
let mut verse_title = String::from("");
|
||||||
// debug!(verse = verse);
|
let mut lyric = String::from("");
|
||||||
for word in keywords.clone() {
|
for (i, line) in raw_lyrics.split('\n').enumerate() {
|
||||||
let end_verse = verse.get(1..2).unwrap_or_default();
|
if keywords.contains(&line) {
|
||||||
let beg_verse = verse.get(0..1).unwrap_or_default();
|
if i != 0 {
|
||||||
// println!(
|
// println!("{verse_title}");
|
||||||
// "verse: {:?}, beginning: {:?}, end: {:?}, word: {:?}",
|
// println!("{lyric}");
|
||||||
// verse, beg_verse, end_verse, word
|
lyric_map.insert(verse_title, lyric);
|
||||||
// );
|
lyric = String::from("");
|
||||||
if word.starts_with(beg_verse)
|
verse_title = line.to_string();
|
||||||
&& word.ends_with(end_verse)
|
// println!("{line}");
|
||||||
{
|
// println!("\n");
|
||||||
verse_name = word;
|
} else {
|
||||||
// println!("TITLE: {verse_name}");
|
verse_title = line.to_string();
|
||||||
continue;
|
// println!("{line}");
|
||||||
}
|
// println!("\n");
|
||||||
}
|
|
||||||
if let Some(lyric) = lyric_map.get(verse_name) {
|
|
||||||
if lyric.contains("\n\n") {
|
|
||||||
let split_lyrics: Vec<&str> =
|
|
||||||
lyric.split("\n\n").collect();
|
|
||||||
for lyric in split_lyrics {
|
|
||||||
if lyric.is_empty() {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
lyric_list.append(QString::from(lyric));
|
|
||||||
}
|
}
|
||||||
continue;
|
} else {
|
||||||
|
lyric.push_str(line);
|
||||||
|
lyric.push('\n');
|
||||||
}
|
}
|
||||||
lyric_list.append(QString::from(lyric));
|
}
|
||||||
} else {
|
lyric_map.insert(verse_title, lyric);
|
||||||
println!("NOT WORKING!");
|
// println!("da-map: {:?}", lyric_map);
|
||||||
};
|
|
||||||
}
|
for verse in vorder {
|
||||||
for lyric in lyric_list.iter() {
|
let mut verse_name = "";
|
||||||
// println!("da-list: {:?}", lyric);
|
// debug!(verse = verse);
|
||||||
debug!(lyric = ?lyric)
|
for word in keywords.clone() {
|
||||||
}
|
let end_verse =
|
||||||
|
verse.get(1..2).unwrap_or_default();
|
||||||
|
let beg_verse =
|
||||||
|
verse.get(0..1).unwrap_or_default();
|
||||||
|
// println!(
|
||||||
|
// "verse: {:?}, beginning: {:?}, end: {:?}, word: {:?}",
|
||||||
|
// verse, beg_verse, end_verse, word
|
||||||
|
// );
|
||||||
|
if word.starts_with(beg_verse)
|
||||||
|
&& word.ends_with(end_verse)
|
||||||
|
{
|
||||||
|
verse_name = word;
|
||||||
|
// println!("TITLE: {verse_name}");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let Some(lyric) = lyric_map.get(verse_name) {
|
||||||
|
if lyric.contains("\n\n") {
|
||||||
|
let split_lyrics: Vec<&str> =
|
||||||
|
lyric.split("\n\n").collect();
|
||||||
|
for lyric in split_lyrics {
|
||||||
|
if lyric.is_empty() {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
lyric_list.append(QString::from(lyric));
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
lyric_list.append(QString::from(lyric));
|
||||||
|
} else {
|
||||||
|
println!("NOT WORKING!");
|
||||||
|
};
|
||||||
|
}
|
||||||
|
for lyric in lyric_list.iter() {
|
||||||
|
// println!("da-list: {:?}", lyric);
|
||||||
|
debug!(lyric = ?lyric)
|
||||||
|
}
|
||||||
lyric_list
|
lyric_list
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -413,11 +400,9 @@ impl Default for SongModelRust {
|
||||||
let mut db_url = String::from("sqlite://");
|
let mut db_url = String::from("sqlite://");
|
||||||
db_url.push_str(data.to_str().unwrap());
|
db_url.push_str(data.to_str().unwrap());
|
||||||
rt.block_on(async {
|
rt.block_on(async {
|
||||||
SqliteConnection::connect(&db_url)
|
SqliteConnection::connect(&db_url).await.expect("problems")
|
||||||
.await
|
|
||||||
.expect("problems")
|
|
||||||
})
|
})
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -431,14 +416,12 @@ pub fn get_song(id: i32) -> Result<Song> {
|
||||||
let mut db_url = String::from("sqlite://");
|
let mut db_url = String::from("sqlite://");
|
||||||
db_url.push_str(data.to_str().unwrap());
|
db_url.push_str(data.to_str().unwrap());
|
||||||
rt.block_on(async {
|
rt.block_on(async {
|
||||||
SqliteConnection::connect(&db_url)
|
SqliteConnection::connect(&db_url).await.expect("problems")
|
||||||
.await
|
|
||||||
.expect("problems")
|
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
debug!("getting song with id: {id}");
|
debug!("getting song with id: {id}");
|
||||||
rt.block_on(async {
|
rt.block_on(async {
|
||||||
let result = query_as!(Song, r#"SELECT verse_order as "verse_order!", font_size as "font_size!: i32", background_type as "background_type!", horizontal_text_alignment as "horizontal_text_alignment!", vertical_text_alignment as "vertical_text_alignment!", title as "title!", font as "font!", background as "background!", lyrics as "lyrics!", ccli as "ccli!", author as "author!", audio as "audio!", id as "id: i32" from songs where id = $1"#, id).fetch_one(&mut db).await?;
|
let result = query_as!(Song, r#"SELECT vorder as "verse_order!", fontSize as "font_size!: i32", backgroundType as "background_type!", horizontalTextAlignment as "horizontal_text_alignment!", verticalTextAlignment as "vertical_text_alignment!", title as "title!", font as "font!", background as "background!", lyrics as "lyrics!", ccli as "ccli!", author as "author!", audio as "audio!", id as "id: i32" from songs where id = ?"#, id).fetch_one(&mut db).await?;
|
||||||
debug!(?result);
|
debug!(?result);
|
||||||
Ok(result)
|
Ok(result)
|
||||||
})
|
})
|
||||||
|
@ -457,7 +440,7 @@ impl song_model::SongModel {
|
||||||
static DATABASE_URL: &str = "sqlite:///home/chris/.local/share/lumina/library-db.sqlite3";
|
static DATABASE_URL: &str = "sqlite:///home/chris/.local/share/lumina/library-db.sqlite3";
|
||||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||||
rt.block_on(async {
|
rt.block_on(async {
|
||||||
let result = query_as!(Song, r#"SELECT verse_order as "verse_order!", font_size as "font_size!: i32", background_type as "background_type!", horizontal_text_alignment as "horizontal_text_alignment!", vertical_text_alignment as "vertical_text_alignment!", title as "title!", font as "font!", background as "background!", lyrics as "lyrics!", ccli as "ccli!", author as "author!", audio as "audio!", id as "id: i32" from songs"#).fetch_all(&mut self.as_mut().rust_mut().db).await;
|
let result = query_as!(Song, r#"SELECT vorder as "verse_order!", fontSize as "font_size!: i32", backgroundType as "background_type!", horizontalTextAlignment as "horizontal_text_alignment!", verticalTextAlignment as "vertical_text_alignment!", title as "title!", font as "font!", background as "background!", lyrics as "lyrics!", ccli as "ccli!", author as "author!", audio as "audio!", id as "id: i32" from songs"#).fetch_all(&mut self.as_mut().rust_mut().db).await;
|
||||||
match result {
|
match result {
|
||||||
Ok(s) => s.into_iter().for_each(|s| self.as_mut().add_song(s)),
|
Ok(s) => s.into_iter().for_each(|s| self.as_mut().add_song(s)),
|
||||||
Err(e) => error!("There was an error in converting songs: {e}"),
|
Err(e) => error!("There was an error in converting songs: {e}"),
|
||||||
|
@ -470,13 +453,7 @@ impl song_model::SongModel {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
let song_id = self
|
let song_id = self.as_mut().rust_mut().songs.get(index as usize).unwrap().id;
|
||||||
.as_mut()
|
|
||||||
.rust_mut()
|
|
||||||
.songs
|
|
||||||
.get(index as usize)
|
|
||||||
.unwrap()
|
|
||||||
.id;
|
|
||||||
let thread = self.qt_thread();
|
let thread = self.qt_thread();
|
||||||
let db = &mut self.as_mut().rust_mut().db;
|
let db = &mut self.as_mut().rust_mut().db;
|
||||||
|
|
||||||
|
@ -527,7 +504,7 @@ impl song_model::SongModel {
|
||||||
};
|
};
|
||||||
|
|
||||||
rt.block_on(async {
|
rt.block_on(async {
|
||||||
let result = query!(r#"INSERT into songs (verse_order, font_size, background_type, horizontal_text_alignment, vertical_text_alignment, title, font, background, lyrics, ccli, author, audio, id) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"#,
|
let result = query!(r#"INSERT into songs (vorder, fontSize, backgroundType, horizontalTextAlignment, verticalTextAlignment, title, font, background, lyrics, ccli, author, audio, id) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"#,
|
||||||
song.verse_order,
|
song.verse_order,
|
||||||
song.font_size,
|
song.font_size,
|
||||||
song.background_type,
|
song.background_type,
|
||||||
|
@ -542,7 +519,7 @@ impl song_model::SongModel {
|
||||||
song.audio,
|
song.audio,
|
||||||
song.id)
|
song.id)
|
||||||
.fetch_all(&mut self.as_mut().rust_mut().db).await;
|
.fetch_all(&mut self.as_mut().rust_mut().db).await;
|
||||||
|
|
||||||
match result {
|
match result {
|
||||||
Ok(_i) => {
|
Ok(_i) => {
|
||||||
self.as_mut().add_song(song);
|
self.as_mut().add_song(song);
|
||||||
|
@ -609,23 +586,16 @@ impl song_model::SongModel {
|
||||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||||
let db_string = updated_title.clone().to_string();
|
let db_string = updated_title.clone().to_string();
|
||||||
rt.block_on(async {
|
rt.block_on(async {
|
||||||
let result = query!(
|
let result = query!("UPDATE songs SET title = ? where id = ?", db_string, song_id)
|
||||||
"UPDATE songs SET title = ? where id = ?",
|
.execute(&mut self.as_mut().rust_mut().db)
|
||||||
db_string,
|
.await;
|
||||||
song_id
|
|
||||||
)
|
|
||||||
.execute(&mut self.as_mut().rust_mut().db)
|
|
||||||
.await;
|
|
||||||
|
|
||||||
match result {
|
match result {
|
||||||
Ok(_i) => {
|
Ok(_i) => {
|
||||||
if let Some(song) =
|
if let Some(song) =
|
||||||
self.as_mut().rust_mut().songs.get_mut(index)
|
self.as_mut().rust_mut().songs.get_mut(index)
|
||||||
{
|
{
|
||||||
debug!(
|
debug!(?song, title = updated_title.to_string());
|
||||||
?song,
|
|
||||||
title = updated_title.to_string()
|
|
||||||
);
|
|
||||||
song.title = updated_title.to_string();
|
song.title = updated_title.to_string();
|
||||||
self.as_mut().data_changed(
|
self.as_mut().data_changed(
|
||||||
&model_index,
|
&model_index,
|
||||||
|
@ -638,11 +608,9 @@ impl song_model::SongModel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
error!(
|
error!("There was an error updating title in db: {e}");
|
||||||
"There was an error updating title in db: {e}"
|
|
||||||
);
|
|
||||||
false
|
false
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
true
|
true
|
||||||
|
@ -746,13 +714,9 @@ impl song_model::SongModel {
|
||||||
let db_string = updated_audio.clone().to_string();
|
let db_string = updated_audio.clone().to_string();
|
||||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||||
rt.block_on(async {
|
rt.block_on(async {
|
||||||
let result = query!(
|
let result = query!("UPDATE songs SET audio = ? where id = ?", db_string, song_id)
|
||||||
"UPDATE songs SET audio = ? where id = ?",
|
.execute(&mut self.as_mut().rust_mut().db)
|
||||||
db_string,
|
.await;
|
||||||
song_id
|
|
||||||
)
|
|
||||||
.execute(&mut self.as_mut().rust_mut().db)
|
|
||||||
.await;
|
|
||||||
|
|
||||||
match result {
|
match result {
|
||||||
Ok(_i) => {
|
Ok(_i) => {
|
||||||
|
@ -775,11 +739,9 @@ impl song_model::SongModel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
error!(
|
error!("There was an error updating audio in db: {e}");
|
||||||
"There was an error updating audio in db: {e}"
|
|
||||||
);
|
|
||||||
false
|
false
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
true
|
true
|
||||||
|
@ -796,13 +758,9 @@ impl song_model::SongModel {
|
||||||
let db_string = updated_ccli.clone().to_string();
|
let db_string = updated_ccli.clone().to_string();
|
||||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||||
rt.block_on(async {
|
rt.block_on(async {
|
||||||
let result = query!(
|
let result = query!("UPDATE songs SET ccli = ? where id = ?", db_string, song_id)
|
||||||
"UPDATE songs SET ccli = ? where id = ?",
|
.execute(&mut self.as_mut().rust_mut().db)
|
||||||
db_string,
|
.await;
|
||||||
song_id
|
|
||||||
)
|
|
||||||
.execute(&mut self.as_mut().rust_mut().db)
|
|
||||||
.await;
|
|
||||||
|
|
||||||
match result {
|
match result {
|
||||||
Ok(_i) => {
|
Ok(_i) => {
|
||||||
|
@ -825,11 +783,9 @@ impl song_model::SongModel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
error!(
|
error!("There was an error updating ccli in db: {e}");
|
||||||
"There was an error updating ccli in db: {e}"
|
|
||||||
);
|
|
||||||
false
|
false
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
true
|
true
|
||||||
|
@ -846,7 +802,7 @@ impl song_model::SongModel {
|
||||||
let db_string = updated_verse_order.clone().to_string();
|
let db_string = updated_verse_order.clone().to_string();
|
||||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||||
rt.block_on(async {
|
rt.block_on(async {
|
||||||
let result = query!("UPDATE songs SET verse_order = ? where id = ?", db_string, song_id)
|
let result = query!("UPDATE songs SET vorder = ? where id = ?", db_string, song_id)
|
||||||
.execute(&mut self.as_mut().rust_mut().db)
|
.execute(&mut self.as_mut().rust_mut().db)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
|
@ -935,7 +891,7 @@ impl song_model::SongModel {
|
||||||
let db_string = updated_background_type.clone().to_string();
|
let db_string = updated_background_type.clone().to_string();
|
||||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||||
rt.block_on(async {
|
rt.block_on(async {
|
||||||
let result = query!("UPDATE songs SET background_type = ? where id = ?", db_string, song_id)
|
let result = query!("UPDATE songs SET backgroundType = ? where id = ?", db_string, song_id)
|
||||||
.execute(&mut self.as_mut().rust_mut().db)
|
.execute(&mut self.as_mut().rust_mut().db)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
|
@ -977,11 +933,10 @@ impl song_model::SongModel {
|
||||||
.as_mut()
|
.as_mut()
|
||||||
.get_indices(song_id, SongRoles::HorizontalTextAlignment);
|
.get_indices(song_id, SongRoles::HorizontalTextAlignment);
|
||||||
|
|
||||||
let db_string =
|
let db_string = updated_horizontal_text_alignment.clone().to_string();
|
||||||
updated_horizontal_text_alignment.clone().to_string();
|
|
||||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||||
rt.block_on(async {
|
rt.block_on(async {
|
||||||
let result = query!("UPDATE songs SET horizontal_text_alignment = ? where id = ?", db_string, song_id)
|
let result = query!("UPDATE songs SET horizontalTextAlignment = ? where id = ?", db_string, song_id)
|
||||||
.execute(&mut self.as_mut().rust_mut().db)
|
.execute(&mut self.as_mut().rust_mut().db)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
|
@ -1023,11 +978,10 @@ impl song_model::SongModel {
|
||||||
.as_mut()
|
.as_mut()
|
||||||
.get_indices(song_id, SongRoles::VerticalTextAlignment);
|
.get_indices(song_id, SongRoles::VerticalTextAlignment);
|
||||||
|
|
||||||
let db_string =
|
let db_string = updated_vertical_text_alignment.clone().to_string();
|
||||||
updated_vertical_text_alignment.clone().to_string();
|
|
||||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||||
rt.block_on(async {
|
rt.block_on(async {
|
||||||
let result = query!("UPDATE songs SET vertical_text_alignment = ? where id = ?", db_string, song_id)
|
let result = query!("UPDATE songs SET verticalTextAlignment = ? where id = ?", db_string, song_id)
|
||||||
.execute(&mut self.as_mut().rust_mut().db)
|
.execute(&mut self.as_mut().rust_mut().db)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
|
@ -1071,13 +1025,9 @@ impl song_model::SongModel {
|
||||||
let db_string = updated_font.clone().to_string();
|
let db_string = updated_font.clone().to_string();
|
||||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||||
rt.block_on(async {
|
rt.block_on(async {
|
||||||
let result = query!(
|
let result = query!("UPDATE songs SET font = ? where id = ?", db_string, song_id)
|
||||||
"UPDATE songs SET font = ? where id = ?",
|
.execute(&mut self.as_mut().rust_mut().db)
|
||||||
db_string,
|
.await;
|
||||||
song_id
|
|
||||||
)
|
|
||||||
.execute(&mut self.as_mut().rust_mut().db)
|
|
||||||
.await;
|
|
||||||
|
|
||||||
match result {
|
match result {
|
||||||
Ok(_i) => {
|
Ok(_i) => {
|
||||||
|
@ -1100,11 +1050,9 @@ impl song_model::SongModel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
error!(
|
error!("There was an error updating font in db: {e}");
|
||||||
"There was an error updating font in db: {e}"
|
|
||||||
);
|
|
||||||
false
|
false
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
true
|
true
|
||||||
|
@ -1121,7 +1069,7 @@ impl song_model::SongModel {
|
||||||
let db_string = updated_font_size.clone().to_string();
|
let db_string = updated_font_size.clone().to_string();
|
||||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||||
rt.block_on(async {
|
rt.block_on(async {
|
||||||
let result = query!("UPDATE songs SET font_size = ? where id = ?", db_string, song_id)
|
let result = query!("UPDATE songs SET fontSize = ? where id = ?", db_string, song_id)
|
||||||
.execute(&mut self.as_mut().rust_mut().db)
|
.execute(&mut self.as_mut().rust_mut().db)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
pub mod video_model {
|
pub mod video_model {
|
||||||
unsafe extern "C++" {
|
unsafe extern "C++" {
|
||||||
include!(< QAbstractListModel >);
|
include!(< QAbstractListModel >);
|
||||||
type QAbstractListModel;
|
|
||||||
include!("cxx-qt-lib/qhash.h");
|
include!("cxx-qt-lib/qhash.h");
|
||||||
type QHash_i32_QByteArray =
|
type QHash_i32_QByteArray =
|
||||||
cxx_qt_lib::QHash<cxx_qt_lib::QHashPair_i32_QByteArray>;
|
cxx_qt_lib::QHash<cxx_qt_lib::QHashPair_i32_QByteArray>;
|
||||||
|
@ -35,18 +34,15 @@ pub mod video_model {
|
||||||
Looping,
|
Looping,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[auto_cxx_name]
|
|
||||||
#[auto_rust_name]
|
|
||||||
unsafe extern "RustQt" {
|
unsafe extern "RustQt" {
|
||||||
#[qobject]
|
#[qobject]
|
||||||
#[base = QAbstractListModel]
|
#[base = "QAbstractListModel"]
|
||||||
#[qml_element]
|
#[qml_element]
|
||||||
#[qproperty(i32, count)]
|
#[qproperty(i32, count)]
|
||||||
type VideoModel = super::VideoModelRust;
|
type VideoModel = super::VideoModelRust;
|
||||||
|
|
||||||
#[inherit]
|
#[inherit]
|
||||||
#[qsignal]
|
#[qsignal]
|
||||||
#[cxx_name = "dataChanged"]
|
|
||||||
fn data_changed(
|
fn data_changed(
|
||||||
self: Pin<&mut VideoModel>,
|
self: Pin<&mut VideoModel>,
|
||||||
top_left: &QModelIndex,
|
top_left: &QModelIndex,
|
||||||
|
@ -106,11 +102,8 @@ pub mod video_model {
|
||||||
|
|
||||||
impl cxx_qt::Threading for VideoModel {}
|
impl cxx_qt::Threading for VideoModel {}
|
||||||
|
|
||||||
#[auto_cxx_name]
|
|
||||||
#[auto_rust_name]
|
|
||||||
unsafe extern "RustQt" {
|
unsafe extern "RustQt" {
|
||||||
#[inherit]
|
#[inherit]
|
||||||
#[cxx_name = "beginInsertRows"]
|
|
||||||
unsafe fn begin_insert_rows(
|
unsafe fn begin_insert_rows(
|
||||||
self: Pin<&mut VideoModel>,
|
self: Pin<&mut VideoModel>,
|
||||||
parent: &QModelIndex,
|
parent: &QModelIndex,
|
||||||
|
@ -119,11 +112,9 @@ pub mod video_model {
|
||||||
);
|
);
|
||||||
|
|
||||||
#[inherit]
|
#[inherit]
|
||||||
#[cxx_name = "endInsertRows"]
|
|
||||||
unsafe fn end_insert_rows(self: Pin<&mut VideoModel>);
|
unsafe fn end_insert_rows(self: Pin<&mut VideoModel>);
|
||||||
|
|
||||||
#[inherit]
|
#[inherit]
|
||||||
#[cxx_name = "beginRemoveRows"]
|
|
||||||
unsafe fn begin_remove_rows(
|
unsafe fn begin_remove_rows(
|
||||||
self: Pin<&mut VideoModel>,
|
self: Pin<&mut VideoModel>,
|
||||||
parent: &QModelIndex,
|
parent: &QModelIndex,
|
||||||
|
@ -132,7 +123,6 @@ pub mod video_model {
|
||||||
);
|
);
|
||||||
|
|
||||||
#[inherit]
|
#[inherit]
|
||||||
#[cxx_name = "beginMoveRows"]
|
|
||||||
unsafe fn begin_move_rows(
|
unsafe fn begin_move_rows(
|
||||||
self: Pin<&mut VideoModel>,
|
self: Pin<&mut VideoModel>,
|
||||||
source_parent: &QModelIndex,
|
source_parent: &QModelIndex,
|
||||||
|
@ -143,23 +133,18 @@ pub mod video_model {
|
||||||
) -> bool;
|
) -> bool;
|
||||||
|
|
||||||
#[inherit]
|
#[inherit]
|
||||||
#[cxx_name = "endMoveRows"]
|
|
||||||
unsafe fn end_move_rows(self: Pin<&mut VideoModel>);
|
unsafe fn end_move_rows(self: Pin<&mut VideoModel>);
|
||||||
|
|
||||||
#[inherit]
|
#[inherit]
|
||||||
#[cxx_name = "endRemoveRows"]
|
|
||||||
unsafe fn end_remove_rows(self: Pin<&mut VideoModel>);
|
unsafe fn end_remove_rows(self: Pin<&mut VideoModel>);
|
||||||
|
|
||||||
#[inherit]
|
#[inherit]
|
||||||
#[cxx_name = "beginResetModel"]
|
|
||||||
unsafe fn begin_reset_model(self: Pin<&mut VideoModel>);
|
unsafe fn begin_reset_model(self: Pin<&mut VideoModel>);
|
||||||
|
|
||||||
#[inherit]
|
#[inherit]
|
||||||
#[cxx_name = "endResetModel"]
|
|
||||||
unsafe fn end_reset_model(self: Pin<&mut VideoModel>);
|
unsafe fn end_reset_model(self: Pin<&mut VideoModel>);
|
||||||
|
|
||||||
#[inherit]
|
#[inherit]
|
||||||
#[cxx_name = "canFetchMore"]
|
|
||||||
fn can_fetch_more(
|
fn can_fetch_more(
|
||||||
self: &VideoModel,
|
self: &VideoModel,
|
||||||
parent: &QModelIndex,
|
parent: &QModelIndex,
|
||||||
|
@ -183,22 +168,19 @@ pub mod video_model {
|
||||||
|
|
||||||
#[qinvokable]
|
#[qinvokable]
|
||||||
#[cxx_override]
|
#[cxx_override]
|
||||||
#[cxx_name = "roleNames"]
|
|
||||||
fn role_names(self: &VideoModel) -> QHash_i32_QByteArray;
|
fn role_names(self: &VideoModel) -> QHash_i32_QByteArray;
|
||||||
|
|
||||||
#[qinvokable]
|
#[qinvokable]
|
||||||
#[cxx_override]
|
#[cxx_override]
|
||||||
#[cxx_name = "rowCount"]
|
|
||||||
fn row_count(self: &VideoModel, _parent: &QModelIndex)
|
fn row_count(self: &VideoModel, _parent: &QModelIndex)
|
||||||
-> i32;
|
-> i32;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
use color_eyre::eyre::Error;
|
|
||||||
use cxx_qt::{CxxQtType, Threading};
|
use cxx_qt::{CxxQtType, Threading};
|
||||||
use cxx_qt_lib::{QByteArray, QModelIndex, QString, QUrl, QVariant};
|
use cxx_qt_lib::{QByteArray, QModelIndex, QString, QUrl, QVariant};
|
||||||
use sqlx::{Connection, SqliteConnection, query, query_as};
|
use sqlx::{query, query_as, Connection, SqliteConnection};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::pin::Pin;
|
use std::pin::Pin;
|
||||||
use tracing::{debug, error};
|
use tracing::{debug, error};
|
||||||
|
@ -242,11 +224,9 @@ impl Default for VideoModelRust {
|
||||||
let mut db_url = String::from("sqlite://");
|
let mut db_url = String::from("sqlite://");
|
||||||
db_url.push_str(data.to_str().unwrap());
|
db_url.push_str(data.to_str().unwrap());
|
||||||
rt.block_on(async {
|
rt.block_on(async {
|
||||||
SqliteConnection::connect(&db_url)
|
SqliteConnection::connect(&db_url).await.expect("problems")
|
||||||
.await
|
|
||||||
.expect("problems")
|
|
||||||
})
|
})
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -260,20 +240,12 @@ pub fn get_video(index: i32) -> color_eyre::Result<Video> {
|
||||||
let mut db_url = String::from("sqlite://");
|
let mut db_url = String::from("sqlite://");
|
||||||
db_url.push_str(data.to_str().unwrap());
|
db_url.push_str(data.to_str().unwrap());
|
||||||
rt.block_on(async {
|
rt.block_on(async {
|
||||||
SqliteConnection::connect(&db_url)
|
SqliteConnection::connect(&db_url).await.expect("problems")
|
||||||
.await
|
|
||||||
.expect("problems")
|
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
rt.block_on(async {
|
rt.block_on(async {
|
||||||
let result = query_as!(Video, r#"SELECT id as "id: i32", title as "title!", file_path as "path!", start_time as "start_time!: f32", end_time as "end_time!: f32", loop as "looping!" from videos where id = ?"#, index).fetch_one(&mut db).await;
|
let result = query_as!(Video, r#"SELECT id as "id: i32", title as "title!", filePath as "path!", startTime as "start_time!: f32", endTime as "end_time!: f32", loop as "looping!" from videos where id = ?"#, index).fetch_one(&mut db).await?;
|
||||||
match result {
|
Ok(result)
|
||||||
Ok(v) => Ok(v),
|
|
||||||
Err(e) => {
|
|
||||||
error!(?e);
|
|
||||||
Err(color_eyre::Report::from(e))
|
|
||||||
},
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -289,7 +261,7 @@ impl video_model::VideoModel {
|
||||||
pub fn setup(mut self: Pin<&mut Self>) {
|
pub fn setup(mut self: Pin<&mut Self>) {
|
||||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||||
rt.block_on(async {
|
rt.block_on(async {
|
||||||
let result = query_as!(Video, r#"SELECT id as "id: i32", title as "title!", file_path as "path!", start_time as "start_time!: f32", end_time as "end_time!: f32", loop as "looping!" from videos"#).fetch_all(&mut self.as_mut().rust_mut().db).await;
|
let result = query_as!(Video, r#"SELECT id as "id: i32", title as "title!", filePath as "path!", startTime as "start_time!: f32", endTime as "end_time!: f32", loop as "looping!" from videos"#).fetch_all(&mut self.as_mut().rust_mut().db).await;
|
||||||
match result {
|
match result {
|
||||||
Ok(v) => v.into_iter().for_each(|v| self.as_mut().add_video(v)),
|
Ok(v) => v.into_iter().for_each(|v| self.as_mut().add_video(v)),
|
||||||
Err(e) => error!("There was an error in converting songs: {e}"),
|
Err(e) => error!("There was an error in converting songs: {e}"),
|
||||||
|
@ -305,10 +277,7 @@ impl video_model::VideoModel {
|
||||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||||
|
|
||||||
rt.block_on(async {
|
rt.block_on(async {
|
||||||
let result =
|
let result = query!("delete from videos where id = ?", video_id).execute(&mut self.as_mut().rust_mut().db).await;
|
||||||
query!("delete from videos where id = ?", video_id)
|
|
||||||
.execute(&mut self.as_mut().rust_mut().db)
|
|
||||||
.await;
|
|
||||||
match result {
|
match result {
|
||||||
Ok(_i) => {
|
Ok(_i) => {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -365,7 +334,7 @@ impl video_model::VideoModel {
|
||||||
rt.block_on(async {
|
rt.block_on(async {
|
||||||
let video_title = video_title.to_string();
|
let video_title = video_title.to_string();
|
||||||
let video_path = video_path.to_string();
|
let video_path = video_path.to_string();
|
||||||
let result = query!(r#"INSERT into videos (id, title, file_path, start_time, end_time, loop) VALUES (?, ?, ?, ?, ?, ?)"#,
|
let result = query!(r#"INSERT into videos (id, title, filePath, startTime, endTime, loop) VALUES (?, ?, ?, ?, ?, ?)"#,
|
||||||
video_id,
|
video_id,
|
||||||
video_title,
|
video_title,
|
||||||
video_path,
|
video_path,
|
||||||
|
@ -466,13 +435,9 @@ impl video_model::VideoModel {
|
||||||
|
|
||||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||||
rt.block_on(async {
|
rt.block_on(async {
|
||||||
let result = query!(
|
let result = query!("UPDATE videos SET loop = ? where id = ?", loop_value, index)
|
||||||
"UPDATE videos SET loop = ? where id = ?",
|
.execute(&mut self.as_mut().rust_mut().db)
|
||||||
loop_value,
|
.await;
|
||||||
index
|
|
||||||
)
|
|
||||||
.execute(&mut self.as_mut().rust_mut().db)
|
|
||||||
.await;
|
|
||||||
match result {
|
match result {
|
||||||
Ok(_i) => {
|
Ok(_i) => {
|
||||||
for video in self
|
for video in self
|
||||||
|
@ -483,11 +448,9 @@ impl video_model::VideoModel {
|
||||||
.filter(|x| x.id == index)
|
.filter(|x| x.id == index)
|
||||||
{
|
{
|
||||||
video.looping = loop_value;
|
video.looping = loop_value;
|
||||||
debug!(
|
debug!(title = video.title,
|
||||||
title = video.title,
|
looping = loop_value,
|
||||||
looping = loop_value,
|
"updated video loop");
|
||||||
"updated video loop"
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
self.as_mut().data_changed(
|
self.as_mut().data_changed(
|
||||||
model_index,
|
model_index,
|
||||||
|
@ -499,7 +462,7 @@ impl video_model::VideoModel {
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
error!("Error connecting to db: {e}");
|
error!("Error connecting to db: {e}");
|
||||||
false
|
false
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
true
|
true
|
||||||
|
@ -518,13 +481,9 @@ impl video_model::VideoModel {
|
||||||
|
|
||||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||||
rt.block_on(async {
|
rt.block_on(async {
|
||||||
let result = query!(
|
let result = query!("UPDATE videos SET endTime = ? where id = ?", updated_end_time, index)
|
||||||
"UPDATE videos SET end_time = ? where id = ?",
|
.execute(&mut self.as_mut().rust_mut().db)
|
||||||
updated_end_time,
|
.await;
|
||||||
index
|
|
||||||
)
|
|
||||||
.execute(&mut self.as_mut().rust_mut().db)
|
|
||||||
.await;
|
|
||||||
match result {
|
match result {
|
||||||
Ok(_i) => {
|
Ok(_i) => {
|
||||||
for video in self
|
for video in self
|
||||||
|
@ -535,11 +494,9 @@ impl video_model::VideoModel {
|
||||||
.filter(|x| x.id == index)
|
.filter(|x| x.id == index)
|
||||||
{
|
{
|
||||||
video.end_time = updated_end_time;
|
video.end_time = updated_end_time;
|
||||||
debug!(
|
debug!(title = video.title,
|
||||||
title = video.title,
|
end_time = updated_end_time,
|
||||||
end_time = updated_end_time,
|
"updated video end_time");
|
||||||
"updated video end_time"
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
self.as_mut().data_changed(
|
self.as_mut().data_changed(
|
||||||
model_index,
|
model_index,
|
||||||
|
@ -551,7 +508,7 @@ impl video_model::VideoModel {
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
error!("Error connecting to db: {e}");
|
error!("Error connecting to db: {e}");
|
||||||
false
|
false
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
true
|
true
|
||||||
|
@ -570,13 +527,9 @@ impl video_model::VideoModel {
|
||||||
|
|
||||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||||
rt.block_on(async {
|
rt.block_on(async {
|
||||||
let result = query!(
|
let result = query!("UPDATE videos SET startTime = ? where id = ?", updated_start_time, index)
|
||||||
"UPDATE videos SET start_time = ? where id = ?",
|
.execute(&mut self.as_mut().rust_mut().db)
|
||||||
updated_start_time,
|
.await;
|
||||||
index
|
|
||||||
)
|
|
||||||
.execute(&mut self.as_mut().rust_mut().db)
|
|
||||||
.await;
|
|
||||||
match result {
|
match result {
|
||||||
Ok(_i) => {
|
Ok(_i) => {
|
||||||
for video in self
|
for video in self
|
||||||
|
@ -587,11 +540,9 @@ impl video_model::VideoModel {
|
||||||
.filter(|x| x.id == index)
|
.filter(|x| x.id == index)
|
||||||
{
|
{
|
||||||
video.start_time = updated_start_time;
|
video.start_time = updated_start_time;
|
||||||
debug!(
|
debug!(title = video.title,
|
||||||
title = video.title,
|
start_time = updated_start_time,
|
||||||
start_time = updated_start_time,
|
"updated video start_time");
|
||||||
"updated video start_time"
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
self.as_mut().data_changed(
|
self.as_mut().data_changed(
|
||||||
model_index,
|
model_index,
|
||||||
|
@ -603,7 +554,7 @@ impl video_model::VideoModel {
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
error!("Error connecting to db: {e}");
|
error!("Error connecting to db: {e}");
|
||||||
false
|
false
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
true
|
true
|
||||||
|
@ -623,13 +574,9 @@ impl video_model::VideoModel {
|
||||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||||
rt.block_on(async {
|
rt.block_on(async {
|
||||||
let title = updated_title.to_string();
|
let title = updated_title.to_string();
|
||||||
let result = query!(
|
let result = query!("UPDATE videos SET title = ? where id = ?", title, index)
|
||||||
"UPDATE videos SET title = ? where id = ?",
|
.execute(&mut self.as_mut().rust_mut().db)
|
||||||
title,
|
.await;
|
||||||
index
|
|
||||||
)
|
|
||||||
.execute(&mut self.as_mut().rust_mut().db)
|
|
||||||
.await;
|
|
||||||
match result {
|
match result {
|
||||||
Ok(_i) => {
|
Ok(_i) => {
|
||||||
for video in self
|
for video in self
|
||||||
|
@ -640,11 +587,9 @@ impl video_model::VideoModel {
|
||||||
.filter(|x| x.id == index)
|
.filter(|x| x.id == index)
|
||||||
{
|
{
|
||||||
video.title = title.clone();
|
video.title = title.clone();
|
||||||
debug!(
|
debug!(title = video.title,
|
||||||
title = video.title,
|
title = title,
|
||||||
title = title,
|
"updated video title");
|
||||||
"updated video title"
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
self.as_mut().data_changed(
|
self.as_mut().data_changed(
|
||||||
model_index,
|
model_index,
|
||||||
|
@ -656,7 +601,7 @@ impl video_model::VideoModel {
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
error!("Error connecting to db: {e}");
|
error!("Error connecting to db: {e}");
|
||||||
false
|
false
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
true
|
true
|
||||||
|
@ -675,13 +620,9 @@ impl video_model::VideoModel {
|
||||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||||
rt.block_on(async {
|
rt.block_on(async {
|
||||||
let updated_path = updated_path.to_string();
|
let updated_path = updated_path.to_string();
|
||||||
let result = query!(
|
let result = query!("UPDATE videos SET filePath = ? where id = ?", updated_path, index)
|
||||||
"UPDATE videos SET file_path = ? where id = ?",
|
.execute(&mut self.as_mut().rust_mut().db)
|
||||||
updated_path,
|
.await;
|
||||||
index
|
|
||||||
)
|
|
||||||
.execute(&mut self.as_mut().rust_mut().db)
|
|
||||||
.await;
|
|
||||||
match result {
|
match result {
|
||||||
Ok(_i) => {
|
Ok(_i) => {
|
||||||
for video in self
|
for video in self
|
||||||
|
@ -692,11 +633,9 @@ impl video_model::VideoModel {
|
||||||
.filter(|x| x.id == index)
|
.filter(|x| x.id == index)
|
||||||
{
|
{
|
||||||
video.path = updated_path.clone();
|
video.path = updated_path.clone();
|
||||||
debug!(
|
debug!(title = video.title,
|
||||||
title = video.title,
|
path = updated_path,
|
||||||
path = updated_path,
|
"updated video path");
|
||||||
"updated video path"
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
self.as_mut().data_changed(
|
self.as_mut().data_changed(
|
||||||
model_index,
|
model_index,
|
||||||
|
@ -708,7 +647,7 @@ impl video_model::VideoModel {
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
error!("Error connecting to db: {e}");
|
error!("Error connecting to db: {e}");
|
||||||
false
|
false
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
true
|
true
|
||||||
|
|
|
@ -7,8 +7,6 @@ mod ytdl {
|
||||||
type QString = cxx_qt_lib::QString;
|
type QString = cxx_qt_lib::QString;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[auto_cxx_name]
|
|
||||||
#[auto_rust_name]
|
|
||||||
unsafe extern "RustQt" {
|
unsafe extern "RustQt" {
|
||||||
#[qobject]
|
#[qobject]
|
||||||
#[qml_element]
|
#[qml_element]
|
||||||
|
@ -69,10 +67,14 @@ impl ytdl::Ytdl {
|
||||||
.run()
|
.run()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let output = ytdl.into_single_video().unwrap();
|
let output = ytdl.into_single_video().unwrap();
|
||||||
debug!(output.title, output.thumbnail, output.url);
|
debug!(
|
||||||
|
output.title,
|
||||||
|
output.thumbnail, output.url
|
||||||
|
);
|
||||||
let title = QString::from(&output.title);
|
let title = QString::from(&output.title);
|
||||||
let thumbnail =
|
let thumbnail = QUrl::from(
|
||||||
QUrl::from(&output.thumbnail.unwrap_or_default());
|
&output.thumbnail.unwrap_or_default(),
|
||||||
|
);
|
||||||
let mut file = String::from(output_dirs);
|
let mut file = String::from(output_dirs);
|
||||||
file.push('/');
|
file.push('/');
|
||||||
file.push_str(&output.title);
|
file.push_str(&output.title);
|
||||||
|
@ -84,8 +86,12 @@ impl ytdl::Ytdl {
|
||||||
qobject_ytdl.as_mut().set_loaded(true);
|
qobject_ytdl.as_mut().set_loaded(true);
|
||||||
qobject_ytdl.as_mut().set_loading(false);
|
qobject_ytdl.as_mut().set_loading(false);
|
||||||
qobject_ytdl.as_mut().set_title(title);
|
qobject_ytdl.as_mut().set_title(title);
|
||||||
qobject_ytdl.as_mut().set_thumbnail(thumbnail);
|
qobject_ytdl
|
||||||
qobject_ytdl.as_mut().set_file(QUrl::from(&file));
|
.as_mut()
|
||||||
|
.set_thumbnail(thumbnail);
|
||||||
|
qobject_ytdl
|
||||||
|
.as_mut()
|
||||||
|
.set_file(QUrl::from(&file));
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
true
|
true
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue