Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
f4a41cd4c6
28 changed files with 1248 additions and 349 deletions
|
@ -13,7 +13,7 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||||
|
|
||||||
find_package(ECM ${KF5_MIN_VERSION} REQUIRED NO_MODULE)
|
find_package(ECM ${KF5_MIN_VERSION} REQUIRED NO_MODULE)
|
||||||
|
|
||||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${ECM_MODULE_PATH})
|
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${ECM_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
|
||||||
|
|
||||||
include(KDEInstallDirs)
|
include(KDEInstallDirs)
|
||||||
include(KDECMakeSettings)
|
include(KDECMakeSettings)
|
||||||
|
@ -27,6 +27,10 @@ kde_enable_exceptions()
|
||||||
find_package(Qt5 ${QT_MIN_VERSION} REQUIRED NO_MODULE COMPONENTS Core Quick Test Gui QuickControls2 Widgets Sql X11Extras)
|
find_package(Qt5 ${QT_MIN_VERSION} REQUIRED NO_MODULE COMPONENTS Core Quick Test Gui QuickControls2 Widgets Sql X11Extras)
|
||||||
find_package(KF5 ${KF_MIN_VERSION} REQUIRED COMPONENTS Kirigami2 I18n CoreAddons)
|
find_package(KF5 ${KF_MIN_VERSION} REQUIRED COMPONENTS Kirigami2 I18n CoreAddons)
|
||||||
|
|
||||||
|
find_package(Libmpv)
|
||||||
|
set_package_properties(Libmpv PROPERTIES TYPE REQUIRED)
|
||||||
|
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 17)
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
|
||||||
|
|
|
@ -7,12 +7,12 @@ This is an attempt at building a church presentation application in Qt/QML. QML
|
||||||
** Features (planned are in parentheses)
|
** Features (planned are in parentheses)
|
||||||
- Presents songs lyrics with image and video backgrounds
|
- Presents songs lyrics with image and video backgrounds
|
||||||
- Use MPV as a rendering system for videos
|
- Use MPV as a rendering system for videos
|
||||||
|
- Simple song creation with a powerful text parser - Almost fully finished
|
||||||
- (Present Slides)
|
- (Present Slides)
|
||||||
- (Custom slide builder)
|
- (Custom slide builder)
|
||||||
- (Simple song creation with a powerful text parser)
|
|
||||||
|
|
||||||
** MPV
|
** MPV
|
||||||
You will need MPV installed in order to use this. All videos run through it. This, however, enables us to make videos work very well and with a lot of control and since it uses ffmpeg underneath, nearly any codec regardless of underlying system. This prevents the need for the user to go and install other codecs to work with Windows or MacOS. It also means a much easier control system and the potential to stream web content as well.
|
You will need MPV installed in order to use this. All videos run through it. This, however, enables us to make videos work very well and with a lot of control and since it uses ffmpeg underneath, nearly any codec regardless of underlying system. This prevents the need for the user to install other codecs to work with Windows or MacOS. It also means a much easier control system and the potential to stream web content as well without downloading first.
|
||||||
|
|
||||||
* Build and Run
|
* Build and Run
|
||||||
First get the source code
|
First get the source code
|
||||||
|
@ -33,4 +33,4 @@ Then run.
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
* Contact Me
|
* Contact Me
|
||||||
If, for whatever reason, you need to contact me and get something ironed out, please do so at [[mailto:chris@tfcconnection.org][chris@tfcconnection.org]]
|
If, for whatever reason, you need to contact me and get something ironed out, please do so at [[mailto:chris@tfcconnection.org][chris@cochrun.xyz]]
|
||||||
|
|
100
TODO.org
100
TODO.org
|
@ -1,11 +1,105 @@
|
||||||
#+TITLE: Todo List
|
#+TITLE: Todo List
|
||||||
|
:PROPERTIES:
|
||||||
|
:CATEGORY: dev
|
||||||
|
:END:
|
||||||
|
|
||||||
* Inbox
|
* Inbox
|
||||||
** TODO Need to make ListModel capable of bringing in a string list [2/4] [50%]
|
** TODO Need to make =getLyricList= give back the verses with empty lines as separate slides :core:
|
||||||
|
[[file:~/dev/church-presenter/src/songsqlmodel.cpp:://TODO make sure to split empty line in verse into two slides]]
|
||||||
|
|
||||||
|
** TODO Make toolbar functional for =songeditor= [3/4] [75%] :core:
|
||||||
|
[[file:~/dev/church-presenter/src/qml/presenter/SongEditor.qml::Controls.ToolBar {]]
|
||||||
|
|
||||||
|
- [X] alignment
|
||||||
|
- [X] font - Need to finish the UI portion of it
|
||||||
|
- [X] fontsize - Need to finish the UI portion of it
|
||||||
|
- [ ] effects?
|
||||||
|
For effects, I'm not 100% sure how to do this in an easy to build out way. Should I just do them the same as the other attributes or have effects be individually stored? Which effects to use?
|
||||||
|
|
||||||
|
I'm thinking shadows for sure for readability on slides. Also, maybe I should have an effect of like glow? But maybe I'll come back to this after more of the core system is finished.
|
||||||
|
|
||||||
|
** TODO bug in changing slides with the arrows :core:
|
||||||
|
[[file:~/dev/church-presenter/src/qml/presenter/Presentation.qml::function changeSlide() {]]
|
||||||
|
|
||||||
|
slides are inconsistent in changing from one slide to the next or previous. Both functions need looked at.
|
||||||
|
|
||||||
|
Maybe my best solution would be to architect a model or class for both the presentation controller and the presentation window to follow and do all the heavy lifting in there.
|
||||||
|
|
||||||
|
** TODO Check for edge cases in inputing wrong vorder and lyrics :core:
|
||||||
|
[[file:~/dev/church-presenter/TODO.org::*Fix broken append when importing River song][Fix broken append when importing River song]]
|
||||||
|
|
||||||
|
** TODO Images stored in sql need to have aspect saved and applied dynamically here :core:
|
||||||
|
[[file:~/dev/church-presenter/src/qml/presenter/Slide.qml::fillMode: Image.PreserveAspectCrop]]
|
||||||
|
|
||||||
|
** TODO Build out a slide preview system so we can see each slide in the song or image slideshow :ui:
|
||||||
|
[[file:~/dev/church-presenter/src/qml/presenter/SongEditor.qml::Presenter.SlideEditor {]]
|
||||||
|
|
||||||
|
- [X] Initial ListView with text coming from =getLyricList=
|
||||||
|
- [ ] Depending on this [[*Need to make getLyricList give back the verses with empty lines as separate slides][Need to make getLyricList give back the verses with empty lines as separate slides]]
|
||||||
|
- [ ] Need to perhaps address the MPV crashing problem for a smoother experience.
|
||||||
|
Essentially, mpv objects cause a seg fault when we remove them from the qml graph scene and are somehow re-referencing them. Using =reuseItems=, I can prevent the seg fault but then we are storing a lot of things in memory and will definitely cause slowdowns on older hardware.
|
||||||
|
|
||||||
|
** TODO Fix possible bug in arrangingItems in draghandler [1/3] [33%] :bug:
|
||||||
|
[[file:~/dev/church-presenter/src/qml/presenter/DragHandle.qml::function arrangeItem() {]]
|
||||||
|
|
||||||
|
- [X] Basic fixed drag n drop
|
||||||
|
- [ ] Allow for a less buggy interaction
|
||||||
|
- [ ] Need to check for edge cases
|
||||||
|
|
||||||
|
** PROJ [#A] Make Presentation Window follow the presenter component :core:
|
||||||
|
[[file:~/dev/church-presenter/src/qml/presenter/MainWindow.qml::Presenter.Slide {]]
|
||||||
|
|
||||||
|
** TODO Finish toolbar in presentation display :ui:
|
||||||
|
[[file:~/dev/church-presenter/src/qml/presenter/Presentation.qml::Controls.ToolBar {]]
|
||||||
|
|
||||||
|
** TODO Find a way to maths the textsize :slide:
|
||||||
|
[[file:~/dev/church-presenter/src/qml/presenter/Slide.qml::property real textSize: 50]]
|
||||||
|
|
||||||
|
This may not be as needed. Apparently the text shrinks to fit it's space.
|
||||||
|
|
||||||
|
** TODO Create a nextslide function to be used after the end of the list of slides :slide:
|
||||||
|
[[file:~/dev/church-presenter/src/qml/presenter/Presentation.qml::function nextSlide() {]]
|
||||||
|
|
||||||
|
- [ ] Check to make sure this works in all conditions but I believe it works ok.
|
||||||
|
|
||||||
|
** TODO Make sure the video gets changed in a proper manner to not have left over video showing from previous items :video:slide:
|
||||||
|
[[file:~/dev/church-presenter/src/qml/presenter/Presentation.qml::currentServiceItem++;]]
|
||||||
|
|
||||||
|
- [X] Build a basic system that changes to black first and then switches to the video
|
||||||
|
- [ ] Build out a loading system that will load the next video if it needs to and then the switch can be instant.
|
||||||
|
|
||||||
|
The second option is the best, but requires a lot more work. I have the first already working so I'll come back to this once I have more of an idea of how to do it.
|
||||||
|
|
||||||
|
** DONE images and videos need a better get system
|
||||||
|
[[file:~/dev/church-presenter/src/videosqlmodel.cpp::QVariantList VideoSqlModel::getVideo(const int &row) {]]
|
||||||
|
|
||||||
|
** DONE Fix broken append when importing River song
|
||||||
|
[[file:~/dev/church-presenter/src/qml/presenter/LeftDock.qml::function appendItem(name, type, background, backgroundType, text, itemID) {]]
|
||||||
|
|
||||||
|
This was due to the song not having a vorder. Need to protect from edge cases of the user inputing the formatted text that doesn't fit what's expected in code.
|
||||||
|
|
||||||
|
** DONE implement previousSlide and previousAction
|
||||||
|
[[file:~/dev/church-presenter/src/qml/presenter/Presentation.qml::function nextSlide() {]]
|
||||||
|
|
||||||
|
** DONE Need to make ListModel capable of bringing in a string list [2/2] [100%]
|
||||||
- [X] Create a Model
|
- [X] Create a Model
|
||||||
- [X] Create a class that we'll make a list of in the model
|
- [X] Create a class that we'll make a list of in the model
|
||||||
- [ ] Implement move functions
|
|
||||||
- [ ] Implement insert functions
|
** DONE Make an image sql model
|
||||||
|
[[file:~/dev/church-presenter/src/videosqlmodel.h::ifndef VIDEOSQLMODEL_H]]
|
||||||
|
|
||||||
** DONE Parse Lyrics to create a list of strings for slides
|
** DONE Parse Lyrics to create a list of strings for slides
|
||||||
SCHEDULED: <2022-03-23 Wed 10:00>
|
SCHEDULED: <2022-03-23 Wed 10:00>
|
||||||
|
|
||||||
|
** DONE BUG in dropping and then selecting song will duplicate entries :dev:
|
||||||
|
SCHEDULED: <2022-04-05 Tue>
|
||||||
|
[[file:~/dev/church-presenter/src/qml/presenter/LeftDock.qml::Layout.fillHeight: true]]
|
||||||
|
|
||||||
|
or at least turns the entry above it into the same as itself while retaining it's title?
|
||||||
|
|
||||||
|
** DONE Make nextSlideText a nextAction function to incorporate other types of items
|
||||||
|
[[file:~/dev/church-presenter/src/qml/presenter/Presentation.qml::function nextSlideText() {]]
|
||||||
|
|
||||||
|
** DONE Fix file dialog using basic QT theme
|
||||||
|
[[file:~/dev/church-presenter/src/qml/presenter/SongEditor.qml::FileDialog {]]
|
||||||
|
|
||||||
|
|
41
flake.lock
generated
Normal file
41
flake.lock
generated
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
{
|
||||||
|
"nodes": {
|
||||||
|
"flake-utils": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1652776076,
|
||||||
|
"narHash": "sha256-gzTw/v1vj4dOVbpBSJX4J0DwUR6LIyXo7/SuuTJp1kM=",
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"rev": "04c1b180862888302ddfb2e3ad9eaa63afc60cf8",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1653117584,
|
||||||
|
"narHash": "sha256-5uUrHeHBIaySBTrRExcCoW8fBBYVSDjDYDU5A6iOl+k=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "f4dfed73ee886b115a99e5b85fdfbeb683290d83",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"id": "nixpkgs",
|
||||||
|
"type": "indirect"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": {
|
||||||
|
"inputs": {
|
||||||
|
"flake-utils": "flake-utils",
|
||||||
|
"nixpkgs": "nixpkgs"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": "root",
|
||||||
|
"version": 7
|
||||||
|
}
|
14
flake.nix
Normal file
14
flake.nix
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
{
|
||||||
|
description = "A Church Presentation Application";
|
||||||
|
|
||||||
|
inputs.flake-utils.url = "github:numtide/flake-utils";
|
||||||
|
|
||||||
|
outputs = { self, nixpkgs, flake-utils }:
|
||||||
|
flake-utils.lib.eachDefaultSystem
|
||||||
|
(system:
|
||||||
|
let pkgs = nixpkgs.legacyPackages.${system}; in
|
||||||
|
{
|
||||||
|
devShell = import ./shell.nix { inherit pkgs; };
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
42
shell.nix
Normal file
42
shell.nix
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
{ pkgs ? <nixpkgs> { } }:
|
||||||
|
with pkgs;
|
||||||
|
mkShell {
|
||||||
|
name = "presenter-env";
|
||||||
|
|
||||||
|
nativeBuildInputs = [
|
||||||
|
gcc
|
||||||
|
gnumake
|
||||||
|
clang
|
||||||
|
cmake
|
||||||
|
extra-cmake-modules
|
||||||
|
pkg-config
|
||||||
|
libsForQt5.wrapQtAppsHook
|
||||||
|
# gccStdenv
|
||||||
|
# stdenv
|
||||||
|
];
|
||||||
|
|
||||||
|
buildInputs = [
|
||||||
|
qt5.qtbase
|
||||||
|
qt5.qttools
|
||||||
|
qt5.qtquickcontrols2
|
||||||
|
qt5.qtx11extras
|
||||||
|
qt5.qtmultimedia
|
||||||
|
libsForQt5.kirigami2
|
||||||
|
libsForQt5.ki18n
|
||||||
|
libsForQt5.kcoreaddons
|
||||||
|
mpv
|
||||||
|
# libsForQt5.kconfig
|
||||||
|
# ffmpeg-full
|
||||||
|
# yt-dlp
|
||||||
|
];
|
||||||
|
|
||||||
|
# This creates the proper qt env so that plugins are found right.
|
||||||
|
shellHook = ''
|
||||||
|
setQtEnvironment=$(mktemp --suffix .setQtEnvironment.sh)
|
||||||
|
echo "shellHook: setQtEnvironment = $setQtEnvironment"
|
||||||
|
makeWrapper "/bin/sh" "$setQtEnvironment" "''${qtWrapperArgs[@]}"
|
||||||
|
sed "/^exec/d" -i "$setQtEnvironment"
|
||||||
|
source "$setQtEnvironment"
|
||||||
|
fish
|
||||||
|
'';
|
||||||
|
}
|
|
@ -7,6 +7,7 @@ target_sources(presenter
|
||||||
serviceitemmodel.cpp serviceitemmodel.h
|
serviceitemmodel.cpp serviceitemmodel.h
|
||||||
serviceitem.cpp serviceitem.h
|
serviceitem.cpp serviceitem.h
|
||||||
videosqlmodel.cpp videosqlmodel.h
|
videosqlmodel.cpp videosqlmodel.h
|
||||||
|
imagesqlmodel.cpp imagesqlmodel.h
|
||||||
mpv/mpvobject.h mpv/mpvobject.cpp
|
mpv/mpvobject.h mpv/mpvobject.cpp
|
||||||
mpv/qthelper.hpp mpv/mpvhelpers.h
|
mpv/qthelper.hpp mpv/mpvhelpers.h
|
||||||
)
|
)
|
||||||
|
|
18
src/main.cpp
18
src/main.cpp
|
@ -22,10 +22,13 @@
|
||||||
|
|
||||||
#include <QtQuick/QQuickWindow>
|
#include <QtQuick/QQuickWindow>
|
||||||
#include <QtQuick/QQuickView>
|
#include <QtQuick/QQuickView>
|
||||||
|
#include <qapplication.h>
|
||||||
|
#include <qcoreapplication.h>
|
||||||
#include <qdir.h>
|
#include <qdir.h>
|
||||||
#include <qglobal.h>
|
#include <qglobal.h>
|
||||||
#include <qguiapplication.h>
|
#include <qguiapplication.h>
|
||||||
#include <qqml.h>
|
#include <qqml.h>
|
||||||
|
#include <qquickstyle.h>
|
||||||
#include <qsqldatabase.h>
|
#include <qsqldatabase.h>
|
||||||
#include <qsqlquery.h>
|
#include <qsqlquery.h>
|
||||||
#include <qstringliteral.h>
|
#include <qstringliteral.h>
|
||||||
|
@ -34,6 +37,7 @@
|
||||||
#include "serviceitemmodel.h"
|
#include "serviceitemmodel.h"
|
||||||
#include "songsqlmodel.h"
|
#include "songsqlmodel.h"
|
||||||
#include "videosqlmodel.h"
|
#include "videosqlmodel.h"
|
||||||
|
#include "imagesqlmodel.h"
|
||||||
|
|
||||||
static void connectToDatabase() {
|
static void connectToDatabase() {
|
||||||
// let's setup our sql database
|
// let's setup our sql database
|
||||||
|
@ -67,20 +71,25 @@ static void connectToDatabase() {
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||||
QGuiApplication app(argc, argv);
|
QApplication app(argc, argv);
|
||||||
KLocalizedString::setApplicationDomain("presenter");
|
KLocalizedString::setApplicationDomain("librepresenter");
|
||||||
QCoreApplication::setOrganizationName(QStringLiteral("presenter"));
|
QCoreApplication::setOrganizationName(QStringLiteral("librepresenter"));
|
||||||
QCoreApplication::setOrganizationDomain(QStringLiteral("tfcconnection.org"));
|
QCoreApplication::setOrganizationDomain(QStringLiteral("tfcconnection.org"));
|
||||||
QCoreApplication::setApplicationName(QStringLiteral("Church Presenter"));
|
QCoreApplication::setApplicationName(QStringLiteral("Libre Presenter"));
|
||||||
|
|
||||||
#ifdef Q_OS_WINDOWS
|
#ifdef Q_OS_WINDOWS
|
||||||
QIcon::setFallbackThemeName("breeze");
|
QIcon::setFallbackThemeName("breeze");
|
||||||
QQuickStyle::setStyle(QStringLiteral("org.kde.breeze"));
|
QQuickStyle::setStyle(QStringLiteral("org.kde.breeze"));
|
||||||
|
// QApplication::setStyle(QStringLiteral("breeze"));
|
||||||
#else
|
#else
|
||||||
|
QIcon::setFallbackThemeName("breeze");
|
||||||
QQuickStyle::setStyle(QStringLiteral("org.kde.desktop"));
|
QQuickStyle::setStyle(QStringLiteral("org.kde.desktop"));
|
||||||
|
QQuickStyle::setFallbackStyle(QStringLiteral("breeze"));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
QGuiApplication::setWindowIcon(QIcon::fromTheme(QStringLiteral("system-config-display")));
|
QGuiApplication::setWindowIcon(QIcon::fromTheme(QStringLiteral("system-config-display")));
|
||||||
|
qDebug() << QQuickStyle::availableStyles();
|
||||||
|
qDebug() << QIcon::themeName();
|
||||||
|
|
||||||
// apparently mpv needs this class set
|
// apparently mpv needs this class set
|
||||||
// let's register mpv as well
|
// let's register mpv as well
|
||||||
|
@ -90,6 +99,7 @@ int main(int argc, char *argv[])
|
||||||
//register our models
|
//register our models
|
||||||
qmlRegisterType<SongSqlModel>("org.presenter", 1, 0, "SongSqlModel");
|
qmlRegisterType<SongSqlModel>("org.presenter", 1, 0, "SongSqlModel");
|
||||||
qmlRegisterType<VideoSqlModel>("org.presenter", 1, 0, "VideoSqlModel");
|
qmlRegisterType<VideoSqlModel>("org.presenter", 1, 0, "VideoSqlModel");
|
||||||
|
qmlRegisterType<ImageSqlModel>("org.presenter", 1, 0, "ImageSqlModel");
|
||||||
qmlRegisterType<ServiceItemModel>("org.presenter", 1, 0, "ServiceItemModel");
|
qmlRegisterType<ServiceItemModel>("org.presenter", 1, 0, "ServiceItemModel");
|
||||||
|
|
||||||
connectToDatabase();
|
connectToDatabase();
|
||||||
|
|
|
@ -87,7 +87,7 @@ MpvRenderer::~MpvRenderer() {
|
||||||
if (mpv_gl)
|
if (mpv_gl)
|
||||||
mpv_render_context_free(mpv_gl);
|
mpv_render_context_free(mpv_gl);
|
||||||
|
|
||||||
mpv_terminate_destroy(obj->mpv);
|
// mpv_destroy(obj->mpv);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MpvRenderer::render() {
|
void MpvRenderer::render() {
|
||||||
|
@ -242,7 +242,7 @@ MpvObject::MpvObject(QQuickItem *parent)
|
||||||
|
|
||||||
MpvObject::~MpvObject()
|
MpvObject::~MpvObject()
|
||||||
{
|
{
|
||||||
|
// quit();
|
||||||
}
|
}
|
||||||
|
|
||||||
QQuickFramebufferObject::Renderer *MpvObject::createRenderer() const
|
QQuickFramebufferObject::Renderer *MpvObject::createRenderer() const
|
||||||
|
@ -340,6 +340,10 @@ void MpvObject::handle_mpv_event(mpv_event *event)
|
||||||
// See: https://github.com/mpv-player/mpv/blob/master/player/lua.c#L471
|
// See: https://github.com/mpv-player/mpv/blob/master/player/lua.c#L471
|
||||||
|
|
||||||
switch (event->event_id) {
|
switch (event->event_id) {
|
||||||
|
case MPV_EVENT_SHUTDOWN: {
|
||||||
|
mpv_destroy(mpv);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case MPV_EVENT_LOG_MESSAGE: {
|
case MPV_EVENT_LOG_MESSAGE: {
|
||||||
mpv_event_log_message *logData = (mpv_event_log_message *)event->data;
|
mpv_event_log_message *logData = (mpv_event_log_message *)event->data;
|
||||||
Q_EMIT logMessage(
|
Q_EMIT logMessage(
|
||||||
|
@ -487,7 +491,7 @@ void MpvObject::pause()
|
||||||
{
|
{
|
||||||
// qDebug() << "pause";
|
// qDebug() << "pause";
|
||||||
if (isPlaying()) {
|
if (isPlaying()) {
|
||||||
// qDebug() << "!isPlaying";
|
qDebug() << "!isPlaying";
|
||||||
set_paused(true);
|
set_paused(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ import Qt.labs.platform 1.1 as Labs
|
||||||
import QtQuick.Window 2.13
|
import QtQuick.Window 2.13
|
||||||
import QtQuick.Layouts 1.2
|
import QtQuick.Layouts 1.2
|
||||||
import QtMultimedia 5.15
|
import QtMultimedia 5.15
|
||||||
import QtAudioEngine 1.15
|
/* import QtAudioEngine 1.15 */
|
||||||
import org.kde.kirigami 2.13 as Kirigami
|
import org.kde.kirigami 2.13 as Kirigami
|
||||||
import "./presenter" as Presenter
|
import "./presenter" as Presenter
|
||||||
|
|
||||||
|
@ -121,6 +121,7 @@ Kirigami.ApplicationWindow {
|
||||||
/* print(Qt.application.state); */
|
/* print(Qt.application.state); */
|
||||||
screens = Qt.application.screens;
|
screens = Qt.application.screens;
|
||||||
presentationScreen = screens[1]
|
presentationScreen = screens[1]
|
||||||
|
print(Kirigami.Settings.Style);
|
||||||
for (let i = 0; i < screens.length; i++) {
|
for (let i = 0; i < screens.length; i++) {
|
||||||
/* print(screens[i]); */
|
/* print(screens[i]); */
|
||||||
/* print(screens[i].name); */
|
/* print(screens[i].name); */
|
||||||
|
|
|
@ -4,7 +4,7 @@ import QtQuick.Controls 2.15 as Controls
|
||||||
import QtQuick.Window 2.13
|
import QtQuick.Window 2.13
|
||||||
import QtQuick.Layouts 1.2
|
import QtQuick.Layouts 1.2
|
||||||
import QtMultimedia 5.15
|
import QtMultimedia 5.15
|
||||||
import QtAudioEngine 1.15
|
/* import QtAudioEngine 1.15 */
|
||||||
import org.kde.kirigami 2.13 as Kirigami
|
import org.kde.kirigami 2.13 as Kirigami
|
||||||
import "./" as Presenter
|
import "./" as Presenter
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,7 @@ Item {
|
||||||
|
|
||||||
// Emitted when clicking to activate underneath mousearea
|
// Emitted when clicking to activate underneath mousearea
|
||||||
signal clicked()
|
signal clicked()
|
||||||
|
signal rightClicked()
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
id: mouseArea
|
id: mouseArea
|
||||||
|
@ -55,12 +56,15 @@ Item {
|
||||||
property int mouseDownY
|
property int mouseDownY
|
||||||
property Item originalParent
|
property Item originalParent
|
||||||
property int autoScrollThreshold: (listView.contentHeight > listView.height) ? listItem.height * 3 : 0
|
property int autoScrollThreshold: (listView.contentHeight > listView.height) ? listItem.height * 3 : 0
|
||||||
opacity: mouseArea.pressed || (!Kirigami.Settings.tabletMode && listItem.hovered) ? 1 : 0.6
|
|
||||||
|
|
||||||
function arrangeItem() {
|
function arrangeItem() {
|
||||||
var newIndex = listView.indexAt(1, listView.contentItem.mapFromItem(listItem, 0, 0).y + mouseArea.mouseDownY);
|
var newIndex = listView.indexAt(1,
|
||||||
|
listView.contentItem.mapFromItem(listItem, 0, 0).y +
|
||||||
|
mouseArea.mouseDownY);
|
||||||
|
|
||||||
if (Math.abs(listItem.y - mouseArea.startY) > height && newIndex > -1 && newIndex !== index) {
|
if (Math.abs(listItem.y - mouseArea.startY) > height && newIndex > -1 &&
|
||||||
|
newIndex !== index) {
|
||||||
|
print("old index is: " + index + " and new index is: " + newIndex);
|
||||||
root.moveRequested(index, newIndex);
|
root.moveRequested(index, newIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -127,10 +131,16 @@ Item {
|
||||||
MouseArea {
|
MouseArea {
|
||||||
id: clickArea
|
id: clickArea
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
onClicked: root.clicked()
|
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
|
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||||
onEntered: root.containsMouse = true
|
onEntered: root.containsMouse = true
|
||||||
onExited: root.containsMouse = false
|
onExited: root.containsMouse = false
|
||||||
|
onClicked: {
|
||||||
|
if (mouse.button === Qt.RightButton)
|
||||||
|
root.rightClicked();
|
||||||
|
else
|
||||||
|
root.clicked();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,9 @@ import "./" as Presenter
|
||||||
Item {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
|
property string type: "image"
|
||||||
|
property var image
|
||||||
|
|
||||||
GridLayout {
|
GridLayout {
|
||||||
id: mainLayout
|
id: mainLayout
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
@ -27,7 +30,7 @@ Item {
|
||||||
implicitWidth: 300
|
implicitWidth: 300
|
||||||
editable: true
|
editable: true
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
onCurrentTextChanged: showPassiveNotification(currentText)
|
/* onCurrentTextChanged: showPassiveNotification(currentText) */
|
||||||
}
|
}
|
||||||
Controls.SpinBox {
|
Controls.SpinBox {
|
||||||
editable: true
|
editable: true
|
||||||
|
@ -40,18 +43,6 @@ Item {
|
||||||
implicitWidth: 100
|
implicitWidth: 100
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
}
|
}
|
||||||
Controls.ToolButton {
|
|
||||||
text: "B"
|
|
||||||
hoverEnabled: true
|
|
||||||
}
|
|
||||||
Controls.ToolButton {
|
|
||||||
text: "I"
|
|
||||||
hoverEnabled: true
|
|
||||||
}
|
|
||||||
Controls.ToolButton {
|
|
||||||
text: "U"
|
|
||||||
hoverEnabled: true
|
|
||||||
}
|
|
||||||
Controls.ToolSeparator {}
|
Controls.ToolSeparator {}
|
||||||
Item { Layout.fillWidth: true }
|
Item { Layout.fillWidth: true }
|
||||||
Controls.ToolSeparator {}
|
Controls.ToolSeparator {}
|
||||||
|
@ -63,7 +54,7 @@ Item {
|
||||||
}
|
}
|
||||||
Controls.ToolButton {
|
Controls.ToolButton {
|
||||||
id: backgroundButton
|
id: backgroundButton
|
||||||
text: "Background"
|
text: "Select Image"
|
||||||
icon.name: "fileopen"
|
icon.name: "fileopen"
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
onClicked: backgroundType.open()
|
onClicked: backgroundType.open()
|
||||||
|
@ -83,15 +74,15 @@ Item {
|
||||||
border.color: Kirigami.Theme.activeBackgroundColor
|
border.color: Kirigami.Theme.activeBackgroundColor
|
||||||
border.width: 2
|
border.width: 2
|
||||||
}
|
}
|
||||||
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutsideParent
|
closePolicy: Controls.Popup.CloseOnEscape | Controls.Popup.CloseOnPressOutsideParent
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
Controls.ToolButton {
|
Controls.ToolButton {
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
text: "Video"
|
text: "Image"
|
||||||
icon.name: "emblem-videos-symbolic"
|
icon.name: "emblem-images-symbolic"
|
||||||
onClicked: videoFileDialog.open() & backgroundType.close()
|
onClicked: imageFileDialog.open() & backgroundType.close()
|
||||||
}
|
}
|
||||||
Controls.ToolButton {
|
Controls.ToolButton {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
@ -121,11 +112,11 @@ Item {
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
Controls.SplitView.fillHeight: true
|
Controls.SplitView.fillHeight: true
|
||||||
Controls.SplitView.preferredWidth: 500
|
Controls.SplitView.preferredWidth: 300
|
||||||
Controls.SplitView.minimumWidth: 500
|
Controls.SplitView.minimumWidth: 100
|
||||||
|
|
||||||
Controls.TextField {
|
Controls.TextField {
|
||||||
id: songTitleField
|
id: imageTitleField
|
||||||
|
|
||||||
Layout.preferredWidth: 300
|
Layout.preferredWidth: 300
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
@ -133,98 +124,46 @@ Item {
|
||||||
Layout.rightMargin: 20
|
Layout.rightMargin: 20
|
||||||
|
|
||||||
placeholderText: "Song Title..."
|
placeholderText: "Song Title..."
|
||||||
text: songTitle
|
text: image.title
|
||||||
padding: 10
|
padding: 10
|
||||||
onEditingFinished: updateTitle(text);
|
/* onEditingFinished: updateTitle(text); */
|
||||||
}
|
|
||||||
Controls.TextField {
|
|
||||||
id: songVorderField
|
|
||||||
|
|
||||||
Layout.preferredWidth: 300
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.leftMargin: 20
|
|
||||||
Layout.rightMargin: 20
|
|
||||||
|
|
||||||
placeholderText: "verse order..."
|
|
||||||
text: songVorder
|
|
||||||
padding: 10
|
|
||||||
onEditingFinished: updateVerseOrder(text);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Controls.ScrollView {
|
Item {
|
||||||
id: songLyricsField
|
id: empty
|
||||||
|
|
||||||
Layout.preferredHeight: 3000
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
Layout.leftMargin: 20
|
|
||||||
|
|
||||||
rightPadding: 20
|
|
||||||
|
|
||||||
Controls.TextArea {
|
|
||||||
id: lyricsEditor
|
|
||||||
width: parent.width
|
|
||||||
placeholderText: "Put lyrics here..."
|
|
||||||
persistentSelection: true
|
|
||||||
text: songLyrics
|
|
||||||
textFormat: TextEdit.MarkdownText
|
|
||||||
padding: 10
|
|
||||||
onEditingFinished: {
|
|
||||||
updateLyrics(text);
|
|
||||||
editorTimer.running = false;
|
|
||||||
}
|
|
||||||
onPressed: editorTimer.running = true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Controls.TextField {
|
|
||||||
id: songAuthorField
|
|
||||||
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.preferredWidth: 300
|
|
||||||
Layout.leftMargin: 20
|
|
||||||
Layout.rightMargin: 20
|
|
||||||
|
|
||||||
placeholderText: "Author..."
|
|
||||||
text: songAuthor
|
|
||||||
padding: 10
|
|
||||||
onEditingFinished: updateAuthor(text)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
Controls.SplitView.fillHeight: true
|
Controls.SplitView.fillHeight: true
|
||||||
Controls.SplitView.preferredWidth: 700
|
Controls.SplitView.preferredWidth: 700
|
||||||
Controls.SplitView.minimumWidth: 300
|
Controls.SplitView.minimumWidth: 300
|
||||||
|
spacing: 5
|
||||||
|
|
||||||
Rectangle {
|
Item {
|
||||||
id: slideBar
|
id: topEmpty
|
||||||
color: Kirigami.Theme.highlightColor
|
Layout.fillHeight: true
|
||||||
|
|
||||||
Layout.preferredWidth: 500
|
|
||||||
Layout.preferredHeight: songTitleField.height
|
|
||||||
Layout.rightMargin: 20
|
|
||||||
Layout.leftMargin: 20
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Presenter.SlideEditor {
|
Image {
|
||||||
id: slideEditor
|
id: imagePreview
|
||||||
Layout.preferredWidth: 500
|
Layout.preferredWidth: 600
|
||||||
Layout.fillWidth: true
|
Layout.preferredHeight: Layout.preferredWidth / 16 * 9
|
||||||
Layout.preferredHeight: slideEditor.width / 16 * 9
|
Layout.alignment: Qt.AlignCenter
|
||||||
Layout.bottomMargin: 30
|
fillMode: Image.PreserveAspectFit
|
||||||
Layout.rightMargin: 20
|
source: image.filePath
|
||||||
Layout.leftMargin: 20
|
}
|
||||||
|
Item {
|
||||||
|
id: botEmpty
|
||||||
|
Layout.fillHeight: true
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function changeImage(image) {
|
||||||
|
root.image = image;
|
||||||
|
print(image.filePath.toString());
|
||||||
}
|
}
|
||||||
Timer {
|
|
||||||
id: editorTimer
|
|
||||||
interval: 1000
|
|
||||||
repeat: true
|
|
||||||
running: false
|
|
||||||
onTriggered: updateLyrics(lyricsEditor.text)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,8 +3,9 @@ import QtQuick.Dialogs 1.0
|
||||||
import QtQuick.Controls 2.0 as Controls
|
import QtQuick.Controls 2.0 as Controls
|
||||||
import QtQuick.Window 2.13
|
import QtQuick.Window 2.13
|
||||||
import QtQuick.Layouts 1.2
|
import QtQuick.Layouts 1.2
|
||||||
|
import QtQml.Models 2.12
|
||||||
import QtMultimedia 5.15
|
import QtMultimedia 5.15
|
||||||
import QtAudioEngine 1.15
|
/* import QtAudioEngine 1.15 */
|
||||||
import org.kde.kirigami 2.13 as Kirigami
|
import org.kde.kirigami 2.13 as Kirigami
|
||||||
import "./" as Presenter
|
import "./" as Presenter
|
||||||
|
|
||||||
|
@ -34,6 +35,7 @@ ColumnLayout {
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
onDropped: {
|
onDropped: {
|
||||||
|
print("DROPPED AT END");
|
||||||
appendItem(dragItemTitle,
|
appendItem(dragItemTitle,
|
||||||
dragItemType,
|
dragItemType,
|
||||||
dragItemBackground,
|
dragItemBackground,
|
||||||
|
@ -46,13 +48,14 @@ ColumnLayout {
|
||||||
ListView {
|
ListView {
|
||||||
id: serviceItemList
|
id: serviceItemList
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
model: serviceItemModel
|
/* model: serviceItemModel */
|
||||||
delegate: Kirigami.DelegateRecycler {
|
/* delegate: Kirigami.DelegateRecycler { */
|
||||||
width: serviceItemList.width
|
/* width: serviceItemList.width */
|
||||||
sourceComponent: itemDelegate
|
/* sourceComponent: itemDelegate */
|
||||||
}
|
/* } */
|
||||||
clip: true
|
clip: true
|
||||||
spacing: 3
|
spacing: 3
|
||||||
|
property int dragItemIndex
|
||||||
|
|
||||||
addDisplaced: Transition {
|
addDisplaced: Transition {
|
||||||
NumberAnimation {properties: "x, y"; duration: 100}
|
NumberAnimation {properties: "x, y"; duration: 100}
|
||||||
|
@ -73,68 +76,182 @@ ColumnLayout {
|
||||||
NumberAnimation {properties: "x, y"; duration: 100}
|
NumberAnimation {properties: "x, y"; duration: 100}
|
||||||
}
|
}
|
||||||
|
|
||||||
Component {
|
model: DelegateModel {
|
||||||
id: itemDelegate
|
id: visualModel
|
||||||
Item {
|
model: serviceItemModel
|
||||||
id: serviceItem
|
delegate: DropArea {
|
||||||
|
id: serviceDrop
|
||||||
implicitWidth: serviceItemList.width
|
implicitWidth: serviceItemList.width
|
||||||
height: 50
|
height: 50
|
||||||
|
onEntered: (drag) => {
|
||||||
|
/* dropPlacement(drag); */
|
||||||
|
const from = (drag.source as visServiceItem)
|
||||||
|
visualModel.items.move(dragItemIndex, index);
|
||||||
|
}
|
||||||
|
onDropped: (drag) => {
|
||||||
|
print("DROPPED IN ITEM AREA: " + drag.keys);
|
||||||
|
print(dragItemIndex + " " + index);
|
||||||
|
const hlIndex = serviceItemList.currentIndex;
|
||||||
|
if (drag.keys === ["library"]) {
|
||||||
|
addItem(index,
|
||||||
|
dragItemTitle,
|
||||||
|
dragItemType,
|
||||||
|
dragItemBackground,
|
||||||
|
dragItemBackgroundType,
|
||||||
|
dragItemText,
|
||||||
|
dragItemIndex);
|
||||||
|
} else if (drag.keys === ["serviceitem"]) {
|
||||||
|
moveRequested(dragItemIndex, index);
|
||||||
|
if (hlIndex === dragItemIndex)
|
||||||
|
serviceItemList.currentIndex = index;
|
||||||
|
else if (hlIndex === index)
|
||||||
|
serviceItemList.currentIndex = index + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
keys: ["library","serviceitem"]
|
||||||
|
|
||||||
Kirigami.BasicListItem {
|
Kirigami.BasicListItem {
|
||||||
anchors.fill: parent
|
id: visServiceItem
|
||||||
|
width: serviceDrop.width
|
||||||
|
height: serviceDrop.height
|
||||||
|
anchors {
|
||||||
|
horizontalCenter: parent.horizontalCenter
|
||||||
|
verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
label: name
|
label: name
|
||||||
subtitle: type
|
subtitle: type
|
||||||
hoverEnabled: true
|
hoverEnabled: false
|
||||||
supportsMouseEvents: false
|
supportsMouseEvents: false
|
||||||
backgroundColor: {
|
backgroundColor: {
|
||||||
if (parent.ListView.isCurrentItem) {
|
if (serviceItemList.currentIndex === index ||
|
||||||
|
mouseHandler.containsMouse)
|
||||||
Kirigami.Theme.highlightColor;
|
Kirigami.Theme.highlightColor;
|
||||||
/* } else if (serviceDrop.constainsDrag){ */
|
else
|
||||||
/* Kirigami.Theme.hoverColor; */
|
Kirigami.Theme.backgroundColor;
|
||||||
} else if (mouseHandler.containsMouse){
|
|
||||||
Kirigami.Theme.highlightColor;
|
|
||||||
} else {
|
|
||||||
Kirigami.Theme.backgroundColor;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
textColor: {
|
textColor: {
|
||||||
if (parent.ListView.isCurrentItem || mouseHandler.containsMouse)
|
if (serviceItemList.currentIndex === index ||
|
||||||
|
mouseHandler.containsMouse)
|
||||||
activeTextColor;
|
activeTextColor;
|
||||||
else
|
else
|
||||||
Kirigami.Theme.textColor;
|
Kirigami.Theme.textColor;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
Presenter.DragHandle {
|
states: [
|
||||||
id: mouseHandler
|
State {
|
||||||
anchors.fill: parent
|
when: mouseHandler.drag.active
|
||||||
listItem: serviceItem
|
ParentChange {
|
||||||
listView: serviceItemList
|
target: visServiceItem
|
||||||
onMoveRequested: serviceItemModel.move(oldIndex, newIndex)
|
parent: serviceItemList
|
||||||
onClicked: {
|
}
|
||||||
serviceItemList.currentIndex = index;
|
|
||||||
/* showPassiveNotification(serviceItemList.currentIndex); */
|
PropertyChanges {
|
||||||
changeSlideBackground(background, backgroundType);
|
target: visServiceItem
|
||||||
changeSlideText(text);
|
backgroundColor: Kirigami.Theme.backgroundColor
|
||||||
changeSlideType(type);
|
textColor: Kirigami.Theme.textColor
|
||||||
|
anchors.verticalCenter: undefined
|
||||||
|
anchors.horizontalCenter: undefined
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
/* Drag.dragType: Drag.Automatic */
|
||||||
|
Drag.active: mouseHandler.drag.active
|
||||||
|
Drag.hotSpot.x: width / 2
|
||||||
|
Drag.hotSpot.y: height / 2
|
||||||
|
Drag.keys: ["serviceitem"]
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: mouseHandler
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||||
|
preventStealing: true
|
||||||
|
|
||||||
|
drag {
|
||||||
|
target: visServiceItem
|
||||||
|
axis: Drag.YAxis
|
||||||
|
/* minimumY: root.y */
|
||||||
|
/* maximumY: serviceItemList.height - serviceDrop.height */
|
||||||
|
smoothed: false
|
||||||
|
}
|
||||||
|
|
||||||
|
drag.onActiveChanged: {
|
||||||
|
if (mouseHandler.drag.active) {
|
||||||
|
dragItemIndex = index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* onPositionChanged: { */
|
||||||
|
/* if (!pressed) { */
|
||||||
|
/* return; */
|
||||||
|
/* } */
|
||||||
|
/* mouseArea.arrangeItem(); */
|
||||||
|
/* } */
|
||||||
|
|
||||||
|
onPressed: {
|
||||||
|
serviceItemList.interactive = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
if (mouse.button === Qt.RightButton)
|
||||||
|
rightClickMenu.popup();
|
||||||
|
else {
|
||||||
|
serviceItemList.currentIndex = index;
|
||||||
|
currentServiceItem = index;
|
||||||
|
changeServiceItem(index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onReleased: {
|
||||||
|
print("should drop");
|
||||||
|
visServiceItem.Drag.drop();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DropArea {
|
/* Presenter.DragHandle { */
|
||||||
id: serviceDrop
|
/* id: mouseHandler */
|
||||||
anchors.fill: parent
|
/* anchors.fill: parent */
|
||||||
onDropped: {
|
/* listItem: serviceItem */
|
||||||
addItem(index,
|
/* listView: serviceItemList */
|
||||||
dragItemTitle,
|
/* onMoveRequested: { */
|
||||||
dragItemType,
|
/* print(oldIndex, newIndex); */
|
||||||
dragItemText,
|
/* serviceItemModel.move(oldIndex, newIndex); */
|
||||||
dragItemBackgroundType,
|
/* } */
|
||||||
dragItemBackground,
|
/* onDropped: { */
|
||||||
dragItemIndex);
|
/* } */
|
||||||
|
/* onClicked: { */
|
||||||
|
/* serviceItemList.currentIndex = index; */
|
||||||
|
/* currentServiceItem = index; */
|
||||||
|
/* changeServiceItem(index); */
|
||||||
|
/* } */
|
||||||
|
/* onRightClicked: rightClickMenu.popup() */
|
||||||
|
/* } */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Controls.Menu {
|
||||||
|
id: rightClickMenu
|
||||||
|
x: mouseHandler.mouseX
|
||||||
|
y: mouseHandler.mouseY + 10
|
||||||
|
Kirigami.Action {
|
||||||
|
text: "delete"
|
||||||
|
onTriggered: serviceItemModel.removeItem(index)
|
||||||
}
|
}
|
||||||
keys: ["library"]
|
}
|
||||||
|
|
||||||
|
function moveRequested(oldIndex, newIndex) {
|
||||||
|
serviceItemModel.move(oldIndex, newIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
function dropPlacement(drag) {
|
||||||
|
print(drag.y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Kirigami.WheelHandler {
|
Kirigami.WheelHandler {
|
||||||
id: wheelHandler
|
id: wheelHandler
|
||||||
target: serviceItemList
|
target: serviceItemList
|
||||||
|
@ -150,16 +267,21 @@ ColumnLayout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function addItem(index, name, type,
|
function addItem(index, name, type,
|
||||||
background, backgroundType, text, itemID) {
|
background, backgroundType, text, itemID) {
|
||||||
|
const newtext = songsqlmodel.getLyricList(itemID);
|
||||||
|
print("adding: " + name + " of type " + type);
|
||||||
serviceItemModel.insertItem(index, name,
|
serviceItemModel.insertItem(index, name,
|
||||||
type, text, background,
|
type, background,
|
||||||
backgroundType)
|
backgroundType, newtext);
|
||||||
}
|
}
|
||||||
|
|
||||||
function appendItem(name, type, background, backgroundType, text, itemID) {
|
function appendItem(name, type, background, backgroundType, text, itemID) {
|
||||||
|
print("adding: " + name + " of type " + type);
|
||||||
let lyrics;
|
let lyrics;
|
||||||
if (type == "song") {
|
if (type === "song") {
|
||||||
|
print(itemID);
|
||||||
lyrics = songsqlmodel.getLyricList(itemID);
|
lyrics = songsqlmodel.getLyricList(itemID);
|
||||||
print(lyrics);
|
print(lyrics);
|
||||||
}
|
}
|
||||||
|
|
|
@ -195,9 +195,14 @@ Item {
|
||||||
target: songListItem
|
target: songListItem
|
||||||
x: x
|
x: x
|
||||||
y: y
|
y: y
|
||||||
|
width: width
|
||||||
|
height: height
|
||||||
|
}
|
||||||
|
ParentChange {
|
||||||
|
target: videoListItem
|
||||||
|
parent: rootApp.overlay
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
|
@ -411,6 +416,12 @@ Item {
|
||||||
target: videoListItem
|
target: videoListItem
|
||||||
x: x
|
x: x
|
||||||
y: y
|
y: y
|
||||||
|
width: width
|
||||||
|
height: height
|
||||||
|
}
|
||||||
|
ParentChange {
|
||||||
|
target: videoListItem
|
||||||
|
parent: rootApp.overlay
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -474,12 +485,40 @@ Item {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.alignment: Qt.AlignTop
|
Layout.alignment: Qt.AlignTop
|
||||||
color: Kirigami.Theme.backgroundColor
|
color: Kirigami.Theme.backgroundColor
|
||||||
|
opacity: 1.0
|
||||||
|
|
||||||
Controls.Label {
|
Controls.Label {
|
||||||
|
id: imageLabel
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
text: "Images"
|
text: "Images"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Controls.Label {
|
||||||
|
id: imageCount
|
||||||
|
anchors {left: imageLabel.right
|
||||||
|
verticalCenter: imageLabel.verticalCenter
|
||||||
|
leftMargin: 15}
|
||||||
|
text: imagesqlmodel.rowCount()
|
||||||
|
font.pixelSize: 15
|
||||||
|
color: Kirigami.Theme.disabledTextColor
|
||||||
|
}
|
||||||
|
|
||||||
|
Kirigami.Icon {
|
||||||
|
id: imageDrawerArrow
|
||||||
|
anchors {right: parent.right
|
||||||
|
verticalCenter: imageCount.verticalCenter
|
||||||
|
rightMargin: 10}
|
||||||
|
source: "arrow-down"
|
||||||
|
rotation: selectedLibrary == "images" ? 0 : 180
|
||||||
|
|
||||||
|
Behavior on rotation {
|
||||||
|
NumberAnimation {
|
||||||
|
easing.type: Easing.OutCubic
|
||||||
|
duration: 300
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
onClicked: {
|
onClicked: {
|
||||||
|
@ -497,6 +536,9 @@ Item {
|
||||||
Layout.preferredHeight: parent.height - 200
|
Layout.preferredHeight: parent.height - 200
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.alignment: Qt.AlignTop
|
Layout.alignment: Qt.AlignTop
|
||||||
|
model: imagesqlmodel
|
||||||
|
delegate: imageDelegate
|
||||||
|
clip: true
|
||||||
state: "deselected"
|
state: "deselected"
|
||||||
|
|
||||||
states: [
|
states: [
|
||||||
|
@ -523,6 +565,118 @@ Item {
|
||||||
duration: 300
|
duration: 300
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: imageDelegate
|
||||||
|
Item{
|
||||||
|
implicitWidth: ListView.view.width
|
||||||
|
height: selectedLibrary == "images" ? 50 : 0
|
||||||
|
Kirigami.BasicListItem {
|
||||||
|
id: imageListItem
|
||||||
|
|
||||||
|
property bool rightMenu: false
|
||||||
|
|
||||||
|
implicitWidth: imageLibraryList.width
|
||||||
|
height: selectedLibrary == "images" ? 50 : 0
|
||||||
|
clip: true
|
||||||
|
label: title
|
||||||
|
/* subtitle: author */
|
||||||
|
supportsMouseEvents: false
|
||||||
|
backgroundColor: {
|
||||||
|
if (parent.ListView.isCurrentItem) {
|
||||||
|
Kirigami.Theme.highlightColor;
|
||||||
|
} else if (imageDragHandler.containsMouse){
|
||||||
|
Kirigami.Theme.highlightColor;
|
||||||
|
} else {
|
||||||
|
Kirigami.Theme.backgroundColor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
textColor: {
|
||||||
|
if (parent.ListView.isCurrentItem || imageDragHandler.containsMouse)
|
||||||
|
activeTextColor;
|
||||||
|
else
|
||||||
|
Kirigami.Theme.textColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on height {
|
||||||
|
NumberAnimation {
|
||||||
|
easing.type: Easing.OutCubic
|
||||||
|
duration: 300
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Drag.active: imageDragHandler.drag.active
|
||||||
|
Drag.hotSpot.x: width / 2
|
||||||
|
Drag.hotSpot.y: height / 2
|
||||||
|
Drag.keys: [ "library" ]
|
||||||
|
|
||||||
|
states: State {
|
||||||
|
name: "dragged"
|
||||||
|
when: imageListItem.Drag.active
|
||||||
|
PropertyChanges {
|
||||||
|
target: imageListItem
|
||||||
|
x: x
|
||||||
|
y: y
|
||||||
|
width: width
|
||||||
|
height: height
|
||||||
|
}
|
||||||
|
ParentChange {
|
||||||
|
target: imageListItem
|
||||||
|
parent: rootApp.overlay
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: imageDragHandler
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
drag {
|
||||||
|
target: imageListItem
|
||||||
|
onActiveChanged: {
|
||||||
|
if (imageDragHandler.drag.active) {
|
||||||
|
dragItemTitle = title;
|
||||||
|
dragItemType = "image";
|
||||||
|
dragItemText = "";
|
||||||
|
dragItemBackgroundType = "image";
|
||||||
|
dragItemBackground = filePath;
|
||||||
|
} else {
|
||||||
|
imageListItem.Drag.drop()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
filterChildren: true
|
||||||
|
threshold: 10
|
||||||
|
}
|
||||||
|
MouseArea {
|
||||||
|
id: imageClickHandler
|
||||||
|
anchors.fill: parent
|
||||||
|
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||||
|
onClicked: {
|
||||||
|
if(mouse.button == Qt.RightButton)
|
||||||
|
rightClickImageMenu.popup()
|
||||||
|
else{
|
||||||
|
imageLibraryList.currentIndex = index
|
||||||
|
const image = imagesqlmodel.getImage(imageLibraryList.currentIndex);
|
||||||
|
if (!editMode)
|
||||||
|
editMode = true;
|
||||||
|
editType = "image";
|
||||||
|
editSwitch(image);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Controls.Menu {
|
||||||
|
id: rightClickImageMenu
|
||||||
|
x: imageClickHandler.mouseX
|
||||||
|
y: imageClickHandler.mouseY + 10
|
||||||
|
Kirigami.Action {
|
||||||
|
text: "delete"
|
||||||
|
onTriggered: imagesqlmodel.deleteImage(index)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
|
@ -666,7 +820,7 @@ Item {
|
||||||
videoLibraryList.currentIndex = videosqlmodel.rowCount();
|
videoLibraryList.currentIndex = videosqlmodel.rowCount();
|
||||||
print(videosqlmodel.getVideo(videoLibraryList.currentIndex));
|
print(videosqlmodel.getVideo(videoLibraryList.currentIndex));
|
||||||
const video = videosqlmodel.getVideo(videoLibraryList.currentIndex);
|
const video = videosqlmodel.getVideo(videoLibraryList.currentIndex);
|
||||||
showPassiveNotification("newest video: " + video);
|
showPassiveNotification("newest video: " + video.title);
|
||||||
if (!editMode)
|
if (!editMode)
|
||||||
editMode = true;
|
editMode = true;
|
||||||
editSwitch("video", video);
|
editSwitch("video", video);
|
||||||
|
|
|
@ -12,6 +12,7 @@ Controls.Page {
|
||||||
padding: 0
|
padding: 0
|
||||||
|
|
||||||
// properties passed around for the slides
|
// properties passed around for the slides
|
||||||
|
property int currentServiceItem
|
||||||
property url imageBackground: ""
|
property url imageBackground: ""
|
||||||
property url videoBackground: ""
|
property url videoBackground: ""
|
||||||
property int blurRadius: 0
|
property int blurRadius: 0
|
||||||
|
@ -65,6 +66,7 @@ Controls.Page {
|
||||||
id: presentation
|
id: presentation
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
}
|
}
|
||||||
|
|
||||||
Presenter.SongEditor {
|
Presenter.SongEditor {
|
||||||
id: songEditor
|
id: songEditor
|
||||||
visible: false
|
visible: false
|
||||||
|
@ -76,6 +78,12 @@ Controls.Page {
|
||||||
visible: false
|
visible: false
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Presenter.ImageEditor {
|
||||||
|
id: imageEditor
|
||||||
|
visible: false
|
||||||
|
anchors.fill: parent
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Presenter.Library {
|
Presenter.Library {
|
||||||
|
@ -90,35 +98,7 @@ Controls.Page {
|
||||||
Loader {
|
Loader {
|
||||||
id: presentLoader
|
id: presentLoader
|
||||||
active: presenting
|
active: presenting
|
||||||
sourceComponent: presentWindowComp
|
source: "PresentationWindow.qml"
|
||||||
}
|
|
||||||
|
|
||||||
Component {
|
|
||||||
id: presentWindowComp
|
|
||||||
Window {
|
|
||||||
id: presentationWindow
|
|
||||||
title: "presentation-window"
|
|
||||||
height: maximumHeight
|
|
||||||
width: maximumWidth
|
|
||||||
screen: presentationScreen
|
|
||||||
flags: Qt.X11BypassWindowManagerHint
|
|
||||||
onClosing: presenting = false
|
|
||||||
|
|
||||||
Component.onCompleted: {
|
|
||||||
presentationWindow.showFullScreen();
|
|
||||||
print(screen.name);
|
|
||||||
}
|
|
||||||
|
|
||||||
Presenter.Slide {
|
|
||||||
id: presentationSlide
|
|
||||||
anchors.fill: parent
|
|
||||||
imageSource: imageBackground
|
|
||||||
videoSource: videoBackground
|
|
||||||
text: ""
|
|
||||||
|
|
||||||
Component.onCompleted: slideItem = presentationSlide
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SongSqlModel {
|
SongSqlModel {
|
||||||
|
@ -129,52 +109,41 @@ Controls.Page {
|
||||||
id: videosqlmodel
|
id: videosqlmodel
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ImageSqlModel {
|
||||||
|
id: imagesqlmodel
|
||||||
|
}
|
||||||
|
|
||||||
ServiceItemModel {
|
ServiceItemModel {
|
||||||
id: serviceItemModel
|
id: serviceItemModel
|
||||||
}
|
}
|
||||||
|
|
||||||
function changeSlideType(type) {
|
function changeServiceItem(index) {
|
||||||
presentation.itemType = type;
|
const item = serviceItemModel.getItem(index);
|
||||||
if (slideItem)
|
print("index grabbed: " + index);
|
||||||
slideItem.itemType = type;
|
|
||||||
}
|
|
||||||
|
|
||||||
function changeSlideText(text) {
|
presentation.stopVideo()
|
||||||
presentation.text = text;
|
presentation.itemType = item.type;
|
||||||
if (slideItem)
|
print("Time to start changing");
|
||||||
slideItem.text = text;
|
|
||||||
}
|
|
||||||
|
|
||||||
function changeSlideBackground(background, type) {
|
if (item.backgroundType === "image") {
|
||||||
showPassiveNotification("starting background change..");
|
|
||||||
showPassiveNotification(background);
|
|
||||||
showPassiveNotification(type);
|
|
||||||
if (type == "image") {
|
|
||||||
presentation.vidbackground = "";
|
presentation.vidbackground = "";
|
||||||
presentation.imagebackground = background;
|
presentation.imagebackground = item.background;
|
||||||
if (slideItem) {
|
|
||||||
slideItem.videoSource = "";
|
|
||||||
slideItem.stopVideo();
|
|
||||||
slideItem.imageSource = background;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
presentation.imagebackground = "";
|
presentation.imagebackground = "";
|
||||||
presentation.vidbackground = background;
|
presentation.vidbackground = item.background;
|
||||||
presentation.loadVideo()
|
presentation.loadVideo()
|
||||||
if (slideItem) {
|
|
||||||
slideItem.imageSource = "";
|
|
||||||
slideItem.videoSource = background;
|
|
||||||
slideItem.loadVideo()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
function changeSlideNext() {
|
print(item.text.length)
|
||||||
showPassiveNotification("next slide please")
|
if (item.text.length === 0) {
|
||||||
}
|
presentation.text = [""];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
presentation.text = item.text;
|
||||||
|
presentation.textIndex = 0;
|
||||||
|
presentation.changeSlide();
|
||||||
|
|
||||||
function changeSlidePrevious() {
|
print("Slide changed to: " + item.name);
|
||||||
showPassiveNotification("previous slide please")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function editSwitch(item) {
|
function editSwitch(item) {
|
||||||
|
@ -184,24 +153,30 @@ Controls.Page {
|
||||||
presentation.visible = false;
|
presentation.visible = false;
|
||||||
videoEditor.visible = false;
|
videoEditor.visible = false;
|
||||||
videoEditor.stop();
|
videoEditor.stop();
|
||||||
|
imageEditor.visible = false;
|
||||||
songEditor.visible = true;
|
songEditor.visible = true;
|
||||||
songEditor.changeSong(item);
|
songEditor.changeSong(item);
|
||||||
break;
|
break;
|
||||||
case "video" :
|
case "video" :
|
||||||
presentation.visible = false;
|
presentation.visible = false;
|
||||||
songEditor.visible = false;
|
songEditor.visible = false;
|
||||||
|
imageEditor.visible = false;
|
||||||
videoEditor.visible = true;
|
videoEditor.visible = true;
|
||||||
videoEditor.changeVideo(item);
|
videoEditor.changeVideo(item);
|
||||||
break;
|
break;
|
||||||
case "image" :
|
case "image" :
|
||||||
mainPageArea.pop(Controls.StackView.Immediate);
|
presentation.visible = false;
|
||||||
mainPageArea.push(imageEditorComp, Controls.StackView.Immediate);
|
videoEditor.visible = false;
|
||||||
videoEditor.stop();
|
videoEditor.stop();
|
||||||
|
songEditor.visible = false;
|
||||||
|
imageEditor.visible = true;
|
||||||
|
imageEditor.changeImage(item);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
videoEditor.visible = false;
|
videoEditor.visible = false;
|
||||||
videoEditor.stop();
|
videoEditor.stop();
|
||||||
songEditor.visible = false;
|
songEditor.visible = false;
|
||||||
|
imageEditor.visible = false;
|
||||||
presentation.visible = true;
|
presentation.visible = true;
|
||||||
editMode = false;
|
editMode = false;
|
||||||
}
|
}
|
||||||
|
@ -209,6 +184,7 @@ Controls.Page {
|
||||||
videoEditor.visible = false;
|
videoEditor.visible = false;
|
||||||
videoEditor.stop();
|
videoEditor.stop();
|
||||||
songEditor.visible = false;
|
songEditor.visible = false;
|
||||||
|
imageEditor.visible = false;
|
||||||
presentation.visible = true;
|
presentation.visible = true;
|
||||||
editMode = false;
|
editMode = false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,18 +3,21 @@ import QtQuick.Dialogs 1.0
|
||||||
import QtQuick.Controls 2.15 as Controls
|
import QtQuick.Controls 2.15 as Controls
|
||||||
import QtQuick.Window 2.13
|
import QtQuick.Window 2.13
|
||||||
import QtQuick.Layouts 1.2
|
import QtQuick.Layouts 1.2
|
||||||
import QtAudioEngine 1.15
|
/* import QtAudioEngine 1.15 */
|
||||||
import org.kde.kirigami 2.13 as Kirigami
|
import org.kde.kirigami 2.13 as Kirigami
|
||||||
import "./" as Presenter
|
import "./" as Presenter
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
property string text
|
property var text
|
||||||
|
property int textIndex: 0
|
||||||
property string itemType
|
property string itemType
|
||||||
property url imagebackground
|
property url imagebackground
|
||||||
property url vidbackground
|
property url vidbackground
|
||||||
|
|
||||||
|
Component.onCompleted: nextSlideAction()
|
||||||
|
|
||||||
GridLayout {
|
GridLayout {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
columns: 3
|
columns: 3
|
||||||
|
@ -29,11 +32,18 @@ Item {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
||||||
Controls.ToolButton {
|
Controls.ToolButton {
|
||||||
text: "Grid"
|
text: "Solo"
|
||||||
|
icon.name: "viewimage"
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
}
|
}
|
||||||
Controls.ToolButton {
|
Controls.ToolButton {
|
||||||
text: "Solo"
|
text: "Grid"
|
||||||
|
icon.name: "view-app-grid-symbolic"
|
||||||
|
hoverEnabled: true
|
||||||
|
}
|
||||||
|
Controls.ToolButton {
|
||||||
|
text: "Details"
|
||||||
|
icon.name: "view-list-details"
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
}
|
}
|
||||||
Controls.ToolSeparator {}
|
Controls.ToolSeparator {}
|
||||||
|
@ -45,13 +55,6 @@ Item {
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
onClicked: {}
|
onClicked: {}
|
||||||
}
|
}
|
||||||
Controls.ToolButton {
|
|
||||||
id: backgroundButton
|
|
||||||
text: "Background"
|
|
||||||
icon.name: "fileopen"
|
|
||||||
hoverEnabled: true
|
|
||||||
onClicked: backgroundType.open()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,7 +72,7 @@ Item {
|
||||||
Layout.alignment: Qt.AlignRight
|
Layout.alignment: Qt.AlignRight
|
||||||
MouseArea {
|
MouseArea {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
onPressed: changeSlidePrevious()
|
onPressed: previousSlideAction()
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -81,7 +84,6 @@ Item {
|
||||||
Layout.minimumWidth: 300
|
Layout.minimumWidth: 300
|
||||||
Layout.alignment: Qt.AlignCenter
|
Layout.alignment: Qt.AlignCenter
|
||||||
textSize: width / 15
|
textSize: width / 15
|
||||||
text: root.text
|
|
||||||
itemType: root.itemType
|
itemType: root.itemType
|
||||||
imageSource: imagebackground
|
imageSource: imagebackground
|
||||||
videoSource: vidbackground
|
videoSource: vidbackground
|
||||||
|
@ -95,7 +97,7 @@ Item {
|
||||||
Layout.alignment: Qt.AlignLeft
|
Layout.alignment: Qt.AlignLeft
|
||||||
MouseArea {
|
MouseArea {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
onPressed: changeSlideNext()
|
onPressed: nextSlideAction()
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -112,4 +114,83 @@ Item {
|
||||||
function loadVideo() {
|
function loadVideo() {
|
||||||
previewSlide.loadVideo();
|
previewSlide.loadVideo();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function stopVideo() {
|
||||||
|
previewSlide.stopVideo()
|
||||||
|
}
|
||||||
|
|
||||||
|
function nextSlideAction() {
|
||||||
|
print(textIndex);
|
||||||
|
if (itemType === "song") {
|
||||||
|
if (textIndex === 0) {
|
||||||
|
previewSlide.text = root.text[textIndex];
|
||||||
|
print(root.text[textIndex]);
|
||||||
|
textIndex++;
|
||||||
|
} else if (textIndex < root.text.length) {
|
||||||
|
previewSlide.text = root.text[textIndex];
|
||||||
|
print(root.text[textIndex]);
|
||||||
|
textIndex++;
|
||||||
|
} else {
|
||||||
|
print("Next slide time");
|
||||||
|
textIndex = 0;
|
||||||
|
clearText();
|
||||||
|
nextSlide();
|
||||||
|
}
|
||||||
|
} else if (itemType === "video") {
|
||||||
|
clearText();
|
||||||
|
nextSlide();
|
||||||
|
}
|
||||||
|
else if (itemType === "image") {
|
||||||
|
clearText();
|
||||||
|
nextSlide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function nextSlide() {
|
||||||
|
changeServiceItem(currentServiceItem++);
|
||||||
|
print(slideItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
function previousSlideAction() {
|
||||||
|
print(textIndex);
|
||||||
|
if (itemType === "song") {
|
||||||
|
if (textIndex === 0) {
|
||||||
|
clearText();
|
||||||
|
nextSlide();
|
||||||
|
} else if (textIndex <= root.text.length) {
|
||||||
|
previewSlide.text = root.text[textIndex];
|
||||||
|
print(root.text[textIndex]);
|
||||||
|
--textIndex;
|
||||||
|
}
|
||||||
|
} else if (itemType === "video") {
|
||||||
|
clearText();
|
||||||
|
previousSlide();
|
||||||
|
}
|
||||||
|
else if (itemType === "image") {
|
||||||
|
clearText();
|
||||||
|
previousSlide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function previousSlide() {
|
||||||
|
changeServiceItem(--currentServiceItem);
|
||||||
|
print(slideItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
function changeSlide() {
|
||||||
|
if (itemType === "song") {
|
||||||
|
previewSlide.text = root.text[textIndex];
|
||||||
|
print(root.text[textIndex]);
|
||||||
|
textIndex++;
|
||||||
|
} else if (itemType === "video") {
|
||||||
|
clearText();
|
||||||
|
}
|
||||||
|
else if (itemType === "image") {
|
||||||
|
clearText();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function clearText() {
|
||||||
|
previewSlide.text = "";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ import QtQuick 2.13
|
||||||
import QtQuick.Controls 2.15 as Controls
|
import QtQuick.Controls 2.15 as Controls
|
||||||
import QtQuick.Layouts 1.2
|
import QtQuick.Layouts 1.2
|
||||||
/* import QtMultimedia 5.15 */
|
/* import QtMultimedia 5.15 */
|
||||||
import QtAudioEngine 1.15
|
/* import QtAudioEngine 1.15 */
|
||||||
import QtGraphicalEffects 1.15
|
import QtGraphicalEffects 1.15
|
||||||
import org.kde.kirigami 2.13 as Kirigami
|
import org.kde.kirigami 2.13 as Kirigami
|
||||||
import "./" as Presenter
|
import "./" as Presenter
|
||||||
|
@ -15,13 +15,15 @@ Item {
|
||||||
property bool editMode: false
|
property bool editMode: false
|
||||||
|
|
||||||
// These properties are for the slides visuals
|
// These properties are for the slides visuals
|
||||||
property real textSize: 72
|
property real textSize: 50
|
||||||
property bool dropShadow: false
|
property bool dropShadow: false
|
||||||
property url imageSource: imageBackground
|
property url imageSource: imageBackground
|
||||||
property url videoSource: videoBackground
|
property url videoSource: videoBackground
|
||||||
property string chosenFont: "Quicksand"
|
property string chosenFont: "Quicksand"
|
||||||
property string text: "This is demo text"
|
property var text: "This is demo text"
|
||||||
property color backgroundColor
|
property color backgroundColor
|
||||||
|
property var hTextAlignment: Text.AlignHCenter
|
||||||
|
property var vTextAlignment: Text.AlignVCenter
|
||||||
|
|
||||||
//these properties are for giving video info to parents
|
//these properties are for giving video info to parents
|
||||||
property int mpvPosition: mpv.position
|
property int mpvPosition: mpv.position
|
||||||
|
@ -32,6 +34,9 @@ Item {
|
||||||
property string itemType
|
property string itemType
|
||||||
property bool preview: false
|
property bool preview: false
|
||||||
|
|
||||||
|
implicitWidth: 1920
|
||||||
|
implicitHeight: 1080
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: basePrColor
|
id: basePrColor
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
@ -45,22 +50,24 @@ Item {
|
||||||
enableAudio: !preview
|
enableAudio: !preview
|
||||||
Component.onCompleted: mpvLoadingTimer.start()
|
Component.onCompleted: mpvLoadingTimer.start()
|
||||||
onFileLoaded: {
|
onFileLoaded: {
|
||||||
showPassiveNotification(videoSource + " has been loaded");
|
/* showPassiveNotification(videoSource + " has been loaded"); */
|
||||||
if (itemType == "song")
|
if (itemType == "song")
|
||||||
mpv.setProperty("loop", "inf");
|
mpv.setProperty("loop", "inf");
|
||||||
showPassiveNotification(mpv.getProperty("loop"));
|
else
|
||||||
|
mpv.setProperty("loop", "no");
|
||||||
|
/* showPassiveNotification(mpv.getProperty("loop")); */
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
id: playArea
|
id: playArea
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
enabled: editMode
|
enabled: editMode
|
||||||
onPressed: mpv.loadFile(videoSource.toString());
|
onPressed: mpv.playPause();
|
||||||
cursorShape: preview ? Qt.ArrowCursor : Qt.BlankCursor
|
cursorShape: preview ? Qt.ArrowCursor : Qt.BlankCursor
|
||||||
}
|
}
|
||||||
|
|
||||||
Controls.ProgressBar {
|
Controls.ProgressBar {
|
||||||
anchors.centerIn: parent
|
anchors.top: parent.bottom
|
||||||
visible: editMode
|
visible: editMode
|
||||||
width: parent.width - 400
|
width: parent.width - 400
|
||||||
value: mpv.position
|
value: mpv.position
|
||||||
|
@ -71,7 +78,36 @@ Item {
|
||||||
Timer {
|
Timer {
|
||||||
id: mpvLoadingTimer
|
id: mpvLoadingTimer
|
||||||
interval: 100
|
interval: 100
|
||||||
onTriggered: mpv.loadFile(videoSource.toString())
|
onTriggered: {
|
||||||
|
/* showPassiveNotification("YIPPEEE!") */
|
||||||
|
mpv.loadFile(videoSource.toString());
|
||||||
|
if (editMode) {
|
||||||
|
print("WHY AREN'T YOU PASUING!");
|
||||||
|
pauseTimer.restart();
|
||||||
|
}
|
||||||
|
blackTimer.restart();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: pauseTimer
|
||||||
|
interval: 200
|
||||||
|
onTriggered: mpv.pause()
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: blackTimer
|
||||||
|
interval: 400
|
||||||
|
onTriggered: {
|
||||||
|
black.visible = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: black
|
||||||
|
color: "Black"
|
||||||
|
anchors.fill: parent
|
||||||
|
visible: false
|
||||||
}
|
}
|
||||||
|
|
||||||
Image {
|
Image {
|
||||||
|
@ -87,7 +123,7 @@ Item {
|
||||||
FastBlur {
|
FastBlur {
|
||||||
id: imageBlue
|
id: imageBlue
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
source: imageSource == "" ? mpv : backgroundImage
|
source: imageSource === "" ? mpv : backgroundImage
|
||||||
radius: blurRadius
|
radius: blurRadius
|
||||||
|
|
||||||
Controls.Label {
|
Controls.Label {
|
||||||
|
@ -97,9 +133,10 @@ Item {
|
||||||
/* minimumPointSize: 5 */
|
/* minimumPointSize: 5 */
|
||||||
fontSizeMode: Text.Fit
|
fontSizeMode: Text.Fit
|
||||||
font.family: chosenFont
|
font.family: chosenFont
|
||||||
|
horizontalAlignment: hTextAlignment
|
||||||
|
verticalAlignment: vTextAlignment
|
||||||
style: Text.Raised
|
style: Text.Raised
|
||||||
anchors.centerIn: parent
|
anchors.fill: parent
|
||||||
/* width: parent.width */
|
|
||||||
clip: true
|
clip: true
|
||||||
|
|
||||||
layer.enabled: true
|
layer.enabled: true
|
||||||
|
@ -123,6 +160,12 @@ Item {
|
||||||
}
|
}
|
||||||
|
|
||||||
function stopVideo() {
|
function stopVideo() {
|
||||||
mpv.stop()
|
mpv.stop();
|
||||||
|
black.visible = true;
|
||||||
|
showPassiveNotification("Black is: " + black.visible);
|
||||||
|
}
|
||||||
|
|
||||||
|
function pauseVideo() {
|
||||||
|
mpv.pause();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import QtQuick 2.13
|
import QtQuick 2.15
|
||||||
import QtQuick.Dialogs 1.0
|
import QtQuick.Dialogs 1.0
|
||||||
import QtQuick.Controls 2.15 as Controls
|
import QtQuick.Controls 2.15 as Controls
|
||||||
import QtQuick.Window 2.13
|
import QtQuick.Window 2.13
|
||||||
import QtQuick.Layouts 1.2
|
import QtQuick.Layouts 1.2
|
||||||
import QtMultimedia 5.15
|
import QtMultimedia 5.15
|
||||||
import QtAudioEngine 1.15
|
/* import QtAudioEngine 1.15 */
|
||||||
import org.kde.kirigami 2.13 as Kirigami
|
import org.kde.kirigami 2.13 as Kirigami
|
||||||
import "./" as Presenter
|
import "./" as Presenter
|
||||||
|
|
||||||
|
@ -13,14 +13,86 @@ Item {
|
||||||
|
|
||||||
property string imageBackground
|
property string imageBackground
|
||||||
property string videoBackground
|
property string videoBackground
|
||||||
|
property var hTextAlignment
|
||||||
|
property var vTextAlignment
|
||||||
|
property string font
|
||||||
|
property real fontSize
|
||||||
|
|
||||||
Presenter.Slide {
|
property ListModel songs: songModel
|
||||||
id: representation
|
|
||||||
|
ListView {
|
||||||
|
id: slideList
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
textSize: width / 15
|
model: songModel
|
||||||
editMode: true
|
clip: true
|
||||||
imageSource: imageBackground
|
cacheBuffer: 900
|
||||||
videoSource: videoBackground
|
reuseItems: true
|
||||||
preview: true
|
spacing: Kirigami.Units.gridUnit
|
||||||
|
flickDeceleration: 4000
|
||||||
|
/* boundsMovement: Flickable.StopAtBounds */
|
||||||
|
synchronousDrag: true
|
||||||
|
delegate: Presenter.Slide {
|
||||||
|
id: representation
|
||||||
|
editMode: true
|
||||||
|
imageSource: root.imageBackground
|
||||||
|
videoSource: root.videoBackground
|
||||||
|
hTextAlignment: root.hTextAlignment
|
||||||
|
vTextAlignment: root.vTextAlignment
|
||||||
|
chosenFont: root.font
|
||||||
|
textSize: root.fontSize
|
||||||
|
preview: true
|
||||||
|
text: verse
|
||||||
|
implicitWidth: slideList.width
|
||||||
|
implicitHeight: width * 9 / 16
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
}
|
||||||
|
|
||||||
|
ListModel {
|
||||||
|
id: songModel
|
||||||
|
}
|
||||||
|
|
||||||
|
function appendVerse(verse) {
|
||||||
|
print(verse);
|
||||||
|
songModel.append({"verse": verse})
|
||||||
|
}
|
||||||
|
|
||||||
|
/* function loadVideo() { */
|
||||||
|
/* representation.loadVideo(); */
|
||||||
|
/* } */
|
||||||
|
|
||||||
|
function updateHAlignment(alignment) {
|
||||||
|
switch (alignment) {
|
||||||
|
case "left" :
|
||||||
|
root.hTextAlignment = Text.AlignLeft;
|
||||||
|
break;
|
||||||
|
case "center" :
|
||||||
|
root.hTextAlignment = Text.AlignHCenter;
|
||||||
|
break;
|
||||||
|
case "right" :
|
||||||
|
root.hTextAlignment = Text.AlignRight;
|
||||||
|
break;
|
||||||
|
case "justify" :
|
||||||
|
root.hTextAlignment = Text.AlignJustify;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateVAlignment(alignment) {
|
||||||
|
switch (alignment) {
|
||||||
|
case "top" :
|
||||||
|
root.vTextAlignment = Text.AlignTop;
|
||||||
|
break;
|
||||||
|
case "center" :
|
||||||
|
root.vTextAlignment = Text.AlignVCenter;
|
||||||
|
break;
|
||||||
|
case "bottom" :
|
||||||
|
root.vTextAlignment = Text.AlignBottom;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import QtQuick 2.13
|
import QtQuick 2.13
|
||||||
import QtQuick.Controls 2.15 as Controls
|
import QtQuick.Controls 2.15 as Controls
|
||||||
|
import Qt.labs.platform 1.1 as Labs
|
||||||
import QtQuick.Dialogs 1.3
|
import QtQuick.Dialogs 1.3
|
||||||
import QtQuick.Layouts 1.2
|
import QtQuick.Layouts 1.2
|
||||||
import org.kde.kirigami 2.13 as Kirigami
|
import org.kde.kirigami 2.13 as Kirigami
|
||||||
|
@ -9,14 +10,7 @@ Item {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
property int songIndex
|
property int songIndex
|
||||||
property string songTitle
|
property var song
|
||||||
property string songLyrics
|
|
||||||
property string songAuthor
|
|
||||||
property string songCcli
|
|
||||||
property string songAudio
|
|
||||||
property string songVorder
|
|
||||||
property string songBackground
|
|
||||||
property string songBackgroundType
|
|
||||||
|
|
||||||
GridLayout {
|
GridLayout {
|
||||||
id: mainLayout
|
id: mainLayout
|
||||||
|
@ -33,34 +27,52 @@ Item {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
||||||
Controls.ComboBox {
|
Controls.ComboBox {
|
||||||
|
id: fontBox
|
||||||
model: Qt.fontFamilies()
|
model: Qt.fontFamilies()
|
||||||
implicitWidth: 300
|
implicitWidth: 300
|
||||||
editable: true
|
editable: true
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
onCurrentTextChanged: showPassiveNotification(currentText)
|
flat: true
|
||||||
|
onActivated: updateFont(currentText)
|
||||||
}
|
}
|
||||||
Controls.SpinBox {
|
Controls.SpinBox {
|
||||||
|
id: fontSizeBox
|
||||||
editable: true
|
editable: true
|
||||||
from: 5
|
from: 5
|
||||||
to: 72
|
to: 72
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
|
onValueModified: updateFontSize(value)
|
||||||
}
|
}
|
||||||
Controls.ComboBox {
|
Controls.ComboBox {
|
||||||
|
id: hAlignmentBox
|
||||||
model: ["Left", "Center", "Right", "Justify"]
|
model: ["Left", "Center", "Right", "Justify"]
|
||||||
implicitWidth: 100
|
implicitWidth: 100
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
|
flat: true
|
||||||
|
onActivated: updateHorizontalTextAlignment(currentText.toLowerCase());
|
||||||
|
}
|
||||||
|
Controls.ComboBox {
|
||||||
|
id: vAlignmentBox
|
||||||
|
model: ["Top", "Center", "Bottom"]
|
||||||
|
implicitWidth: 100
|
||||||
|
hoverEnabled: true
|
||||||
|
flat: true
|
||||||
|
onActivated: updateVerticalTextAlignment(currentText.toLowerCase());
|
||||||
}
|
}
|
||||||
Controls.ToolButton {
|
Controls.ToolButton {
|
||||||
text: "B"
|
text: "B"
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
|
visible: false
|
||||||
}
|
}
|
||||||
Controls.ToolButton {
|
Controls.ToolButton {
|
||||||
text: "I"
|
text: "I"
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
|
visible: false
|
||||||
}
|
}
|
||||||
Controls.ToolButton {
|
Controls.ToolButton {
|
||||||
text: "U"
|
text: "U"
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
|
visible: false
|
||||||
}
|
}
|
||||||
Controls.ToolSeparator {}
|
Controls.ToolSeparator {}
|
||||||
Item { Layout.fillWidth: true }
|
Item { Layout.fillWidth: true }
|
||||||
|
@ -143,7 +155,7 @@ Item {
|
||||||
Layout.rightMargin: 20
|
Layout.rightMargin: 20
|
||||||
|
|
||||||
placeholderText: "Song Title..."
|
placeholderText: "Song Title..."
|
||||||
text: songTitle
|
text: song.title
|
||||||
padding: 10
|
padding: 10
|
||||||
onEditingFinished: updateTitle(text);
|
onEditingFinished: updateTitle(text);
|
||||||
}
|
}
|
||||||
|
@ -156,7 +168,7 @@ Item {
|
||||||
Layout.rightMargin: 20
|
Layout.rightMargin: 20
|
||||||
|
|
||||||
placeholderText: "verse order..."
|
placeholderText: "verse order..."
|
||||||
text: songVorder
|
text: song.vorder
|
||||||
padding: 10
|
padding: 10
|
||||||
onEditingFinished: updateVerseOrder(text);
|
onEditingFinished: updateVerseOrder(text);
|
||||||
}
|
}
|
||||||
|
@ -176,7 +188,7 @@ Item {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
placeholderText: "Put lyrics here..."
|
placeholderText: "Put lyrics here..."
|
||||||
persistentSelection: true
|
persistentSelection: true
|
||||||
text: songLyrics
|
text: song.lyrics
|
||||||
textFormat: TextEdit.PlainText
|
textFormat: TextEdit.PlainText
|
||||||
padding: 10
|
padding: 10
|
||||||
onEditingFinished: {
|
onEditingFinished: {
|
||||||
|
@ -195,7 +207,7 @@ Item {
|
||||||
Layout.rightMargin: 20
|
Layout.rightMargin: 20
|
||||||
|
|
||||||
placeholderText: "Author..."
|
placeholderText: "Author..."
|
||||||
text: songAuthor
|
text: song.author
|
||||||
padding: 10
|
padding: 10
|
||||||
onEditingFinished: updateAuthor(text)
|
onEditingFinished: updateAuthor(text)
|
||||||
}
|
}
|
||||||
|
@ -210,8 +222,9 @@ Item {
|
||||||
id: slideEditor
|
id: slideEditor
|
||||||
Layout.preferredWidth: 500
|
Layout.preferredWidth: 500
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.preferredHeight: slideEditor.width / 16 * 9
|
Layout.fillHeight: true
|
||||||
Layout.bottomMargin: 30
|
Layout.bottomMargin: 30
|
||||||
|
Layout.topMargin: 30
|
||||||
Layout.rightMargin: 20
|
Layout.rightMargin: 20
|
||||||
Layout.leftMargin: 20
|
Layout.leftMargin: 20
|
||||||
}
|
}
|
||||||
|
@ -262,24 +275,25 @@ Item {
|
||||||
}
|
}
|
||||||
|
|
||||||
function changeSong(index) {
|
function changeSong(index) {
|
||||||
const song = songsqlmodel.getSong(index);
|
const s = songsqlmodel.getSong(index);
|
||||||
|
song = s;
|
||||||
songIndex = index;
|
songIndex = index;
|
||||||
songTitle = song[0];
|
|
||||||
songLyrics = song[1];
|
if (song.backgroundType == "image") {
|
||||||
songAuthor = song[2];
|
|
||||||
songCcli = song[3];
|
|
||||||
songAudio = song[4];
|
|
||||||
songVorder = song[5];
|
|
||||||
songBackground = song[6];
|
|
||||||
songBackgroundType = song[7];
|
|
||||||
if (songBackgroundType == "image") {
|
|
||||||
slideEditor.videoBackground = "";
|
slideEditor.videoBackground = "";
|
||||||
slideEditor.imageBackground = songBackground;
|
slideEditor.imageBackground = song.background;
|
||||||
} else {
|
} else {
|
||||||
slideEditor.imageBackground = "";
|
slideEditor.imageBackground = "";
|
||||||
slideEditor.videoBackground = songBackground;
|
slideEditor.videoBackground = song.background;
|
||||||
|
/* slideEditor.loadVideo(); */
|
||||||
}
|
}
|
||||||
print(song);
|
|
||||||
|
changeSlideHAlignment(song.horizontalTextAlignment);
|
||||||
|
changeSlideVAlignment(song.verticalTextAlignment);
|
||||||
|
changeSlideFont(song.font, true);
|
||||||
|
changeSlideFontSize(song.fontSize, true)
|
||||||
|
changeSlideText(songIndex);
|
||||||
|
print(s.title);
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateLyrics(lyrics) {
|
function updateLyrics(lyrics) {
|
||||||
|
@ -312,4 +326,83 @@ Item {
|
||||||
songsqlmodel.updateBackgroundType(songIndex, backgroundType);
|
songsqlmodel.updateBackgroundType(songIndex, backgroundType);
|
||||||
print("changed background");
|
print("changed background");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function updateHorizontalTextAlignment(textAlignment) {
|
||||||
|
changeSlideHAlignment(textAlignment);
|
||||||
|
songsqlmodel.updateHorizontalTextAlignment(songIndex, textAlignment);
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateVerticalTextAlignment(textAlignment) {
|
||||||
|
changeSlideVAlignment(textAlignment);
|
||||||
|
songsqlmodel.updateVerticalTextAlignment(songIndex, textAlignment)
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateFont(font) {
|
||||||
|
changeSlideFont(font, false);
|
||||||
|
songsqlmodel.updateFont(songIndex, font);
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateFontSize(fontSize) {
|
||||||
|
changeSlideFontSize(fontSize, false);
|
||||||
|
songsqlmodel.updateFontSize(songIndex, fontSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
function changeSlideHAlignment(alignment) {
|
||||||
|
switch (alignment) {
|
||||||
|
case "left" :
|
||||||
|
hAlignmentBox.currentIndex = 0;
|
||||||
|
slideEditor.hTextAlignment = Text.AlignLeft;
|
||||||
|
break;
|
||||||
|
case "center" :
|
||||||
|
hAlignmentBox.currentIndex = 1;
|
||||||
|
slideEditor.hTextAlignment = Text.AlignHCenter;
|
||||||
|
break;
|
||||||
|
case "right" :
|
||||||
|
hAlignmentBox.currentIndex = 2;
|
||||||
|
slideEditor.hTextAlignment = Text.AlignRight;
|
||||||
|
break;
|
||||||
|
case "justify" :
|
||||||
|
hAlignmentBox.currentIndex = 3;
|
||||||
|
slideEditor.hTextAlignment = Text.AlignJustify;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function changeSlideVAlignment(alignment) {
|
||||||
|
switch (alignment) {
|
||||||
|
case "top" :
|
||||||
|
vAlignmentBox.currentIndex = 0;
|
||||||
|
slideEditor.vTextAlignment = Text.AlignTop;
|
||||||
|
break;
|
||||||
|
case "center" :
|
||||||
|
vAlignmentBox.currentIndex = 1;
|
||||||
|
slideEditor.vTextAlignment = Text.AlignVCenter;
|
||||||
|
break;
|
||||||
|
case "bottom" :
|
||||||
|
vAlignmentBox.currentIndex = 2;
|
||||||
|
slideEditor.vTextAlignment = Text.AlignBottom;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function changeSlideFont(font, updateBox) {
|
||||||
|
const fontIndex = fontBox.find(font);
|
||||||
|
if (updateBox)
|
||||||
|
fontBox.currentIndex = fontIndex;
|
||||||
|
slideEditor.font = font;
|
||||||
|
}
|
||||||
|
|
||||||
|
function changeSlideFontSize(fontSize, updateBox) {
|
||||||
|
if (updateBox)
|
||||||
|
fontSizeBox.value = fontSize;
|
||||||
|
slideEditor.fontSize = fontSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
function changeSlideText(id) {
|
||||||
|
const verses = songsqlmodel.getLyricList(id);
|
||||||
|
print("Here are the verses: " + verses);
|
||||||
|
slideEditor.songs.clear()
|
||||||
|
verses.forEach(slideEditor.appendVerse);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,7 @@ Item {
|
||||||
implicitWidth: 300
|
implicitWidth: 300
|
||||||
editable: true
|
editable: true
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
onCurrentTextChanged: showPassiveNotification(currentText)
|
/* onCurrentTextChanged: showPassiveNotification(currentText) */
|
||||||
}
|
}
|
||||||
Controls.SpinBox {
|
Controls.SpinBox {
|
||||||
editable: true
|
editable: true
|
||||||
|
@ -138,7 +138,7 @@ Item {
|
||||||
Layout.rightMargin: 20
|
Layout.rightMargin: 20
|
||||||
|
|
||||||
placeholderText: "Song Title..."
|
placeholderText: "Song Title..."
|
||||||
text: video[0]
|
text: video.title
|
||||||
padding: 10
|
padding: 10
|
||||||
/* onEditingFinished: updateTitle(text); */
|
/* onEditingFinished: updateTitle(text); */
|
||||||
}
|
}
|
||||||
|
@ -170,7 +170,7 @@ Item {
|
||||||
Component.onCompleted: mpvLoadingTimer.start()
|
Component.onCompleted: mpvLoadingTimer.start()
|
||||||
onPositionChanged: videoSlider.value = position
|
onPositionChanged: videoSlider.value = position
|
||||||
onFileLoaded: {
|
onFileLoaded: {
|
||||||
showPassiveNotification(video[0] + " has been loaded");
|
showPassiveNotification(video.title + " has been loaded");
|
||||||
videoPreview.pause();
|
videoPreview.pause();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -220,7 +220,7 @@ Item {
|
||||||
id: mpvLoadingTimer
|
id: mpvLoadingTimer
|
||||||
interval: 100
|
interval: 100
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
videoPreview.loadFile(video[1].toString());
|
videoPreview.loadFile(video.filePath.toString());
|
||||||
/* showPassiveNotification(video[0]); */
|
/* showPassiveNotification(video[0]); */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,5 +17,6 @@
|
||||||
<file>qml/presenter/Presentation.qml</file>
|
<file>qml/presenter/Presentation.qml</file>
|
||||||
<file>qml/presenter/Settings.qml</file>
|
<file>qml/presenter/Settings.qml</file>
|
||||||
<file>assets/parallel.jpg</file>
|
<file>assets/parallel.jpg</file>
|
||||||
|
<file>assets/black.jpg</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "serviceitemmodel.h"
|
#include "serviceitemmodel.h"
|
||||||
#include "serviceitem.h"
|
#include "serviceitem.h"
|
||||||
#include <qabstractitemmodel.h>
|
#include <qabstractitemmodel.h>
|
||||||
|
#include <qglobal.h>
|
||||||
#include <qnamespace.h>
|
#include <qnamespace.h>
|
||||||
#include <qvariant.h>
|
#include <qvariant.h>
|
||||||
#include <qdebug.h>
|
#include <qdebug.h>
|
||||||
|
@ -115,13 +116,17 @@ Qt::ItemFlags ServiceItemModel::flags(const QModelIndex &index) const {
|
||||||
|
|
||||||
void ServiceItemModel::addItem(ServiceItem *item) {
|
void ServiceItemModel::addItem(ServiceItem *item) {
|
||||||
const int index = m_items.size();
|
const int index = m_items.size();
|
||||||
|
qDebug() << index;
|
||||||
|
// foreach (item, m_items) {
|
||||||
|
// qDebug() << item;
|
||||||
|
// }
|
||||||
beginInsertRows(QModelIndex(), index, index);
|
beginInsertRows(QModelIndex(), index, index);
|
||||||
m_items.append(item);
|
m_items.append(item);
|
||||||
endInsertRows();
|
endInsertRows();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ServiceItemModel::insertItem(const int &index, ServiceItem *item) {
|
void ServiceItemModel::insertItem(const int &index, ServiceItem *item) {
|
||||||
beginInsertRows(this->index(index), index, index);
|
beginInsertRows(this->index(index).parent(), index, index);
|
||||||
m_items.insert(index, item);
|
m_items.insert(index, item);
|
||||||
endInsertRows();
|
endInsertRows();
|
||||||
qDebug() << "Success";
|
qDebug() << "Success";
|
||||||
|
@ -164,7 +169,7 @@ void ServiceItemModel::insertItem(const int &index, const QString &name, const Q
|
||||||
const QStringList &text) {
|
const QStringList &text) {
|
||||||
ServiceItem *item = new ServiceItem(name, type, background, backgroundType, text);
|
ServiceItem *item = new ServiceItem(name, type, background, backgroundType, text);
|
||||||
insertItem(index, item);
|
insertItem(index, item);
|
||||||
qDebug() << name << type << background;
|
qDebug() << name << type << background << text;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ServiceItemModel::removeItem(int index) {
|
void ServiceItemModel::removeItem(int index) {
|
||||||
|
@ -174,17 +179,36 @@ void ServiceItemModel::removeItem(int index) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ServiceItemModel::move(int sourceIndex, int destIndex) {
|
bool ServiceItemModel::move(int sourceIndex, int destIndex) {
|
||||||
qDebug() << "starting move";
|
qDebug() << index(sourceIndex).row();
|
||||||
|
qDebug() << index(destIndex).row();
|
||||||
|
// beginResetModel();
|
||||||
QModelIndex parent = index(sourceIndex).parent();
|
QModelIndex parent = index(sourceIndex).parent();
|
||||||
bool begsuc = beginMoveRows(parent, sourceIndex, sourceIndex, parent, destIndex);
|
if (sourceIndex >= 0 && sourceIndex != destIndex && destIndex >= 0 && destIndex < rowCount() && sourceIndex < rowCount()) {
|
||||||
qDebug() << begsuc;
|
qDebug() << "starting move of: " << "source: " << sourceIndex << "dest: " << destIndex;
|
||||||
if (!begsuc) {
|
bool begsuc = beginMoveRows(QModelIndex(), sourceIndex, sourceIndex, QModelIndex(), destIndex);
|
||||||
qDebug() << "Failed to start moving rows";
|
if (begsuc)
|
||||||
m_items.move(sourceIndex, destIndex);
|
m_items.move(sourceIndex, destIndex);
|
||||||
return false;
|
endMoveRows();
|
||||||
}
|
}
|
||||||
// bool success = moveRow(index(sourceIndex).parent(), sourceIndex, index(destIndex).parent(), destIndex);
|
// endResetModel();
|
||||||
endMoveRows();
|
// emit dataChanged(index(sourceIndex), QModelIndex());
|
||||||
// qDebug() << success;
|
// qDebug() << success;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QVariantMap ServiceItemModel::getItem(int index) const {
|
||||||
|
QVariantMap data;
|
||||||
|
const QModelIndex idx = this->index(index,0);
|
||||||
|
// qDebug() << idx;
|
||||||
|
if( !idx.isValid() )
|
||||||
|
return data;
|
||||||
|
const QHash<int,QByteArray> rn = roleNames();
|
||||||
|
// qDebug() << rn;
|
||||||
|
QHashIterator<int,QByteArray> it(rn);
|
||||||
|
while (it.hasNext()) {
|
||||||
|
it.next();
|
||||||
|
qDebug() << it.key() << ":" << it.value();
|
||||||
|
data[it.value()] = idx.data(it.key());
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
|
@ -56,6 +56,7 @@ public:
|
||||||
const QString &backgroundType, const QStringList &text);
|
const QString &backgroundType, const QStringList &text);
|
||||||
Q_INVOKABLE void removeItem(int index);
|
Q_INVOKABLE void removeItem(int index);
|
||||||
Q_INVOKABLE bool move(int sourceIndex, int destIndex);
|
Q_INVOKABLE bool move(int sourceIndex, int destIndex);
|
||||||
|
Q_INVOKABLE QVariantMap getItem(int index) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QList<ServiceItem *> m_items;
|
QList<ServiceItem *> m_items;
|
||||||
|
|
|
@ -34,27 +34,39 @@ static void createTable()
|
||||||
" 'vorder' TEXT,"
|
" 'vorder' TEXT,"
|
||||||
" 'background' TEXT,"
|
" 'background' TEXT,"
|
||||||
" 'backgroundType' TEXT,"
|
" 'backgroundType' TEXT,"
|
||||||
|
" 'horizontalTextAlignment' TEXT,"
|
||||||
|
" 'verticalTextAlignment' TEXT,"
|
||||||
|
" 'font' TEXT,"
|
||||||
|
" 'fontSize' INTEGER,"
|
||||||
" PRIMARY KEY(id))")) {
|
" PRIMARY KEY(id))")) {
|
||||||
qFatal("Failed to query database: %s",
|
qFatal("Failed to query database: %s",
|
||||||
qPrintable(query.lastError().text()));
|
qPrintable(query.lastError().text()));
|
||||||
}
|
}
|
||||||
qDebug() << query.lastQuery();
|
// qDebug() << query.lastQuery();
|
||||||
qDebug() << "inserting into songs";
|
// qDebug() << "inserting into songs";
|
||||||
|
|
||||||
query.exec("INSERT INTO songs (title, lyrics, author, ccli, audio, vorder, background, backgroundType) VALUES ('10,000 Reasons', '10,000 reasons for my heart to sing', 'Matt Redman', '13470183', '', '', '', '')");
|
query.exec(
|
||||||
qDebug() << query.lastQuery();
|
"INSERT INTO songs (title, lyrics, author, ccli, audio, vorder, "
|
||||||
query.exec("INSERT INTO songs (title, lyrics, author, ccli, audio, vorder, background, backgroundType) VALUES ('River', 'Im going down to the river', 'Jordan Feliz', '13470183', '', '', '', '')");
|
"background, backgroundType, horizontalTextAlignment, verticalTextAlignment, font, fontSize) VALUES ('10,000 Reasons', '10,000 reasons "
|
||||||
query.exec("INSERT INTO songs (title, lyrics, author, ccli, audio, vorder, background, backgroundType) VALUES ('Marvelous Light', 'Into marvelous "
|
"for my heart to sing', 'Matt Redman', '13470183', '', '', '', '', 'center', 'center', '', '')");
|
||||||
"light Im running', 'Chris Tomlin', '13470183', '', '', '', '')");
|
// qDebug() << query.lastQuery();
|
||||||
|
query.exec("INSERT INTO songs (title, lyrics, author, ccli, audio, vorder, "
|
||||||
|
"background, backgroundType, horizontalTextAlignment, verticalTextAlignment, font, fontSize) VALUES ('River', 'Im going down to "
|
||||||
|
"the river', 'Jordan Feliz', '13470183', '', '', '', '', 'center', 'center', '', '')");
|
||||||
|
query.exec(
|
||||||
|
"INSERT INTO songs (title, lyrics, author, ccli, audio, vorder, "
|
||||||
|
"background, backgroundType, horizontalTextAlignment, verticalTextAlignment, font, fontSize) VALUES ('Marvelous Light', 'Into marvelous "
|
||||||
|
"light Im running', 'Chris Tomlin', '13470183', '', '', '', '', 'center', 'center', '', '')");
|
||||||
|
|
||||||
|
// qDebug() << query.lastQuery();
|
||||||
query.exec("select * from songs");
|
query.exec("select * from songs");
|
||||||
qDebug() << query.lastQuery();
|
// qDebug() << query.lastQuery();
|
||||||
}
|
}
|
||||||
|
|
||||||
SongSqlModel::SongSqlModel(QObject *parent)
|
SongSqlModel::SongSqlModel(QObject *parent)
|
||||||
: QSqlTableModel(parent)
|
: QSqlTableModel(parent)
|
||||||
{
|
{
|
||||||
qDebug() << "creating table";
|
// qDebug() << "creating table";
|
||||||
createTable();
|
createTable();
|
||||||
setTable(songsTableName);
|
setTable(songsTableName);
|
||||||
setEditStrategy(QSqlTableModel::OnManualSubmit);
|
setEditStrategy(QSqlTableModel::OnManualSubmit);
|
||||||
|
@ -85,6 +97,10 @@ QHash<int, QByteArray> SongSqlModel::roleNames() const
|
||||||
names[Qt::UserRole + 6] = "vorder";
|
names[Qt::UserRole + 6] = "vorder";
|
||||||
names[Qt::UserRole + 7] = "background";
|
names[Qt::UserRole + 7] = "background";
|
||||||
names[Qt::UserRole + 8] = "backgroundType";
|
names[Qt::UserRole + 8] = "backgroundType";
|
||||||
|
names[Qt::UserRole + 9] = "horizontalTextAlignment";
|
||||||
|
names[Qt::UserRole + 10] = "verticalTextAlignment";
|
||||||
|
names[Qt::UserRole + 11] = "font";
|
||||||
|
names[Qt::UserRole + 12] = "fontSize";
|
||||||
return names;
|
return names;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,25 +129,24 @@ void SongSqlModel::deleteSong(const int &row) {
|
||||||
submitAll();
|
submitAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariantList SongSqlModel::getSong(const int &row) {
|
QVariantMap SongSqlModel::getSong(const int &row) {
|
||||||
QSqlRecord recordData = record(row);
|
// this whole function returns all data in the song
|
||||||
if (recordData.isEmpty()) {
|
// regardless of it's length. When new things are added
|
||||||
qDebug() << "this is not a song";
|
// it will still work without refactoring.
|
||||||
QVariantList empty;
|
QVariantMap data;
|
||||||
return empty;
|
const QModelIndex idx = this->index(row,0);
|
||||||
|
// qDebug() << idx;
|
||||||
|
if( !idx.isValid() )
|
||||||
|
return data;
|
||||||
|
const QHash<int,QByteArray> rn = roleNames();
|
||||||
|
// qDebug() << rn;
|
||||||
|
QHashIterator<int,QByteArray> it(rn);
|
||||||
|
while (it.hasNext()) {
|
||||||
|
it.next();
|
||||||
|
qDebug() << it.key() << ":" << it.value();
|
||||||
|
data[it.value()] = idx.data(it.key());
|
||||||
}
|
}
|
||||||
|
return data;
|
||||||
QVariantList song;
|
|
||||||
song.append(recordData.value("title"));
|
|
||||||
song.append(recordData.value("lyrics"));
|
|
||||||
song.append(recordData.value("author"));
|
|
||||||
song.append(recordData.value("ccli"));
|
|
||||||
song.append(recordData.value("audio"));
|
|
||||||
song.append(recordData.value("vorder"));
|
|
||||||
song.append(recordData.value("background"));
|
|
||||||
song.append(recordData.value("backgroundType"));
|
|
||||||
|
|
||||||
return song;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList SongSqlModel::getLyricList(const int &row) {
|
QStringList SongSqlModel::getLyricList(const int &row) {
|
||||||
|
@ -162,8 +177,11 @@ QStringList SongSqlModel::getLyricList(const int &row) {
|
||||||
QString line;
|
QString line;
|
||||||
QMap<QString, QString> verses;
|
QMap<QString, QString> verses;
|
||||||
|
|
||||||
|
//TODO make sure to split empty line in verse into two slides
|
||||||
|
|
||||||
// This first function pulls out each verse into our verses map
|
// This first function pulls out each verse into our verses map
|
||||||
foreach (line, rawLyrics) {
|
foreach (line, rawLyrics) {
|
||||||
|
qDebug() << line;
|
||||||
if (firstItem) {
|
if (firstItem) {
|
||||||
if (keywords.contains(line)) {
|
if (keywords.contains(line)) {
|
||||||
recordVerse = true;
|
recordVerse = true;
|
||||||
|
@ -187,6 +205,16 @@ QStringList SongSqlModel::getLyricList(const int &row) {
|
||||||
}
|
}
|
||||||
qDebug() << verses;
|
qDebug() << verses;
|
||||||
|
|
||||||
|
// let's check to see if there is a verse order, if not return the list given
|
||||||
|
if (vorder.first().isEmpty()) {
|
||||||
|
qDebug() << "NO VORDER";
|
||||||
|
foreach (verse, verses) {
|
||||||
|
qDebug() << verse;
|
||||||
|
lyrics.append(verse);
|
||||||
|
}
|
||||||
|
qDebug() << lyrics;
|
||||||
|
return lyrics;
|
||||||
|
}
|
||||||
// this function appends the verse that matches the verse order from the map
|
// this function appends the verse that matches the verse order from the map
|
||||||
foreach (const QString &vstr, vorder) {
|
foreach (const QString &vstr, vorder) {
|
||||||
foreach (line, rawLyrics) {
|
foreach (line, rawLyrics) {
|
||||||
|
@ -394,3 +422,107 @@ void SongSqlModel::updateBackgroundType(const int &row, const QString &backgroun
|
||||||
submitAll();
|
submitAll();
|
||||||
emit backgroundTypeChanged();
|
emit backgroundTypeChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString SongSqlModel::horizontalTextAlignment() const {
|
||||||
|
return m_horizontalTextAlignment;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SongSqlModel::setHorizontalTextAlignment(const QString &horizontalTextAlignment) {
|
||||||
|
if (horizontalTextAlignment == m_horizontalTextAlignment)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_horizontalTextAlignment = horizontalTextAlignment;
|
||||||
|
|
||||||
|
select();
|
||||||
|
emit horizontalTextAlignmentChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
// This function is for updating the lyrics from outside the delegate
|
||||||
|
void SongSqlModel::updateHorizontalTextAlignment(const int &row, const QString &horizontalTextAlignment) {
|
||||||
|
qDebug() << "Row is " << row;
|
||||||
|
QSqlRecord rowdata = record(row);
|
||||||
|
qDebug() << rowdata;
|
||||||
|
rowdata.setValue("horizontalTextAlignment", horizontalTextAlignment);
|
||||||
|
setRecord(row, rowdata);
|
||||||
|
qDebug() << rowdata;
|
||||||
|
submitAll();
|
||||||
|
emit horizontalTextAlignmentChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString SongSqlModel::verticalTextAlignment() const {
|
||||||
|
return m_verticalTextAlignment;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SongSqlModel::setVerticalTextAlignment(const QString &verticalTextAlignment) {
|
||||||
|
if (verticalTextAlignment == m_verticalTextAlignment)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_verticalTextAlignment = verticalTextAlignment;
|
||||||
|
|
||||||
|
select();
|
||||||
|
emit verticalTextAlignmentChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
// This function is for updating the lyrics from outside the delegate
|
||||||
|
void SongSqlModel::updateVerticalTextAlignment(const int &row, const QString &verticalTextAlignment) {
|
||||||
|
qDebug() << "Row is " << row;
|
||||||
|
QSqlRecord rowdata = record(row);
|
||||||
|
qDebug() << rowdata;
|
||||||
|
rowdata.setValue("verticalTextAlignment", verticalTextAlignment);
|
||||||
|
setRecord(row, rowdata);
|
||||||
|
qDebug() << rowdata;
|
||||||
|
submitAll();
|
||||||
|
emit verticalTextAlignmentChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString SongSqlModel::font() const {
|
||||||
|
return m_font;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SongSqlModel::setFont(const QString &font) {
|
||||||
|
if (font == m_font)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_font = font;
|
||||||
|
|
||||||
|
select();
|
||||||
|
emit fontChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
// This function is for updating the lyrics from outside the delegate
|
||||||
|
void SongSqlModel::updateFont(const int &row, const QString &font) {
|
||||||
|
qDebug() << "Row is " << row;
|
||||||
|
QSqlRecord rowdata = record(row);
|
||||||
|
qDebug() << rowdata;
|
||||||
|
rowdata.setValue("font", font);
|
||||||
|
setRecord(row, rowdata);
|
||||||
|
qDebug() << rowdata;
|
||||||
|
submitAll();
|
||||||
|
emit fontChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
int SongSqlModel::fontSize() const {
|
||||||
|
return m_fontSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SongSqlModel::setFontSize(const int &fontSize) {
|
||||||
|
if (fontSize == m_fontSize)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_fontSize = fontSize;
|
||||||
|
|
||||||
|
select();
|
||||||
|
emit fontSizeChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
// This function is for updating the lyrics from outside the delegate
|
||||||
|
void SongSqlModel::updateFontSize(const int &row, const int &fontSize) {
|
||||||
|
qDebug() << "Row is " << row;
|
||||||
|
QSqlRecord rowdata = record(row);
|
||||||
|
qDebug() << rowdata;
|
||||||
|
rowdata.setValue("fontSize", fontSize);
|
||||||
|
setRecord(row, rowdata);
|
||||||
|
qDebug() << rowdata;
|
||||||
|
submitAll();
|
||||||
|
emit fontSizeChanged();
|
||||||
|
}
|
||||||
|
|
|
@ -18,6 +18,10 @@ class SongSqlModel : public QSqlTableModel
|
||||||
Q_PROPERTY(QString vorder READ vorder WRITE setVerseOrder NOTIFY vorderChanged)
|
Q_PROPERTY(QString vorder READ vorder WRITE setVerseOrder NOTIFY vorderChanged)
|
||||||
Q_PROPERTY(QString background READ background WRITE setBackground NOTIFY backgroundChanged)
|
Q_PROPERTY(QString background READ background WRITE setBackground NOTIFY backgroundChanged)
|
||||||
Q_PROPERTY(QString backgroundType READ backgroundType WRITE setBackgroundType NOTIFY backgroundTypeChanged)
|
Q_PROPERTY(QString backgroundType READ backgroundType WRITE setBackgroundType NOTIFY backgroundTypeChanged)
|
||||||
|
Q_PROPERTY(QString horizontalTextAlignment READ horizontalTextAlignment WRITE setHorizontalTextAlignment NOTIFY horizontalTextAlignmentChanged)
|
||||||
|
Q_PROPERTY(QString verticalTextAlignment READ verticalTextAlignment WRITE setVerticalTextAlignment NOTIFY verticalTextAlignmentChanged)
|
||||||
|
Q_PROPERTY(QString font READ font WRITE setFont NOTIFY fontChanged)
|
||||||
|
Q_PROPERTY(int fontSize READ fontSize WRITE setFontSize NOTIFY fontSizeChanged)
|
||||||
QML_ELEMENT
|
QML_ELEMENT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -32,6 +36,10 @@ public:
|
||||||
QString vorder() const;
|
QString vorder() const;
|
||||||
QString background() const;
|
QString background() const;
|
||||||
QString backgroundType() const;
|
QString backgroundType() const;
|
||||||
|
QString horizontalTextAlignment() const;
|
||||||
|
QString verticalTextAlignment() const;
|
||||||
|
QString font() const;
|
||||||
|
int fontSize() const;
|
||||||
|
|
||||||
void setTitle(const QString &title);
|
void setTitle(const QString &title);
|
||||||
void setLyrics(const QString &lyrics);
|
void setLyrics(const QString &lyrics);
|
||||||
|
@ -41,6 +49,10 @@ public:
|
||||||
void setVerseOrder(const QString &vorder);
|
void setVerseOrder(const QString &vorder);
|
||||||
void setBackground(const QString &background);
|
void setBackground(const QString &background);
|
||||||
void setBackgroundType(const QString &backgroundType);
|
void setBackgroundType(const QString &backgroundType);
|
||||||
|
void setHorizontalTextAlignment(const QString &horizontalTextAlignment);
|
||||||
|
void setVerticalTextAlignment(const QString &verticalTextAlignment);
|
||||||
|
void setFont(const QString &font);
|
||||||
|
void setFontSize(const int &fontSize);
|
||||||
|
|
||||||
Q_INVOKABLE void updateTitle(const int &row, const QString &title);
|
Q_INVOKABLE void updateTitle(const int &row, const QString &title);
|
||||||
Q_INVOKABLE void updateLyrics(const int &row, const QString &lyrics);
|
Q_INVOKABLE void updateLyrics(const int &row, const QString &lyrics);
|
||||||
|
@ -50,10 +62,14 @@ public:
|
||||||
Q_INVOKABLE void updateVerseOrder(const int &row, const QString &vorder);
|
Q_INVOKABLE void updateVerseOrder(const int &row, const QString &vorder);
|
||||||
Q_INVOKABLE void updateBackground(const int &row, const QString &background);
|
Q_INVOKABLE void updateBackground(const int &row, const QString &background);
|
||||||
Q_INVOKABLE void updateBackgroundType(const int &row, const QString &backgroundType);
|
Q_INVOKABLE void updateBackgroundType(const int &row, const QString &backgroundType);
|
||||||
|
Q_INVOKABLE void updateHorizontalTextAlignment(const int &row, const QString &horizontalTextAlignment);
|
||||||
|
Q_INVOKABLE void updateVerticalTextAlignment(const int &row, const QString &horizontalTextAlignment);
|
||||||
|
Q_INVOKABLE void updateFont(const int &row, const QString &font);
|
||||||
|
Q_INVOKABLE void updateFontSize(const int &row, const int &fontSize);
|
||||||
|
|
||||||
Q_INVOKABLE void newSong();
|
Q_INVOKABLE void newSong();
|
||||||
Q_INVOKABLE void deleteSong(const int &row);
|
Q_INVOKABLE void deleteSong(const int &row);
|
||||||
Q_INVOKABLE QVariantList getSong(const int &row);
|
Q_INVOKABLE QVariantMap getSong(const int &row);
|
||||||
Q_INVOKABLE QStringList getLyricList(const int &row);
|
Q_INVOKABLE QStringList getLyricList(const int &row);
|
||||||
|
|
||||||
QVariant data(const QModelIndex &index, int role) const override;
|
QVariant data(const QModelIndex &index, int role) const override;
|
||||||
|
@ -68,6 +84,10 @@ signals:
|
||||||
void vorderChanged();
|
void vorderChanged();
|
||||||
void backgroundChanged();
|
void backgroundChanged();
|
||||||
void backgroundTypeChanged();
|
void backgroundTypeChanged();
|
||||||
|
void horizontalTextAlignmentChanged();
|
||||||
|
void verticalTextAlignmentChanged();
|
||||||
|
void fontChanged();
|
||||||
|
void fontSizeChanged();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int m_id;
|
int m_id;
|
||||||
|
@ -79,6 +99,10 @@ private:
|
||||||
QString m_vorder;
|
QString m_vorder;
|
||||||
QString m_background;
|
QString m_background;
|
||||||
QString m_backgroundType;
|
QString m_backgroundType;
|
||||||
|
QString m_horizontalTextAlignment;
|
||||||
|
QString m_verticalTextAlignment;
|
||||||
|
QString m_font;
|
||||||
|
int m_fontSize;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //SONGSQLMODEL_H
|
#endif //SONGSQLMODEL_H
|
||||||
|
|
|
@ -156,12 +156,28 @@ void VideoSqlModel::updateFilePath(const int &row, const QUrl &filePath) {
|
||||||
emit filePathChanged();
|
emit filePathChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariantList VideoSqlModel::getVideo(const int &row) {
|
QVariantMap VideoSqlModel::getVideo(const int &row) {
|
||||||
qDebug() << "Row we are getting is " << row;
|
// qDebug() << "Row we are getting is " << row;
|
||||||
QVariantList video;
|
// QVariantList video;
|
||||||
QSqlRecord rec = record(row);
|
// QSqlRecord rec = record(row);
|
||||||
qDebug() << rec.value("title");
|
// qDebug() << rec.value("title");
|
||||||
video.append(rec.value("title"));
|
// video.append(rec.value("title"));
|
||||||
video.append(rec.value("filePath"));
|
// video.append(rec.value("filePath"));
|
||||||
return video;
|
// return video;
|
||||||
|
|
||||||
|
QVariantMap data;
|
||||||
|
const QModelIndex idx = this->index(row,0);
|
||||||
|
// qDebug() << idx;
|
||||||
|
if( !idx.isValid() )
|
||||||
|
return data;
|
||||||
|
const QHash<int,QByteArray> rn = roleNames();
|
||||||
|
// qDebug() << rn;
|
||||||
|
QHashIterator<int,QByteArray> it(rn);
|
||||||
|
while (it.hasNext()) {
|
||||||
|
it.next();
|
||||||
|
qDebug() << it.key() << ":" << it.value();
|
||||||
|
data[it.value()] = idx.data(it.key());
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,7 @@ public:
|
||||||
|
|
||||||
Q_INVOKABLE void newVideo(const QUrl &filePath);
|
Q_INVOKABLE void newVideo(const QUrl &filePath);
|
||||||
Q_INVOKABLE void deleteVideo(const int &row);
|
Q_INVOKABLE void deleteVideo(const int &row);
|
||||||
Q_INVOKABLE QVariantList getVideo(const int &row);
|
Q_INVOKABLE QVariantMap getVideo(const int &row);
|
||||||
|
|
||||||
QVariant data(const QModelIndex &index, int role) const override;
|
QVariant data(const QModelIndex &index, int role) const override;
|
||||||
QHash<int, QByteArray> roleNames() const override;
|
QHash<int, QByteArray> roleNames() const override;
|
||||||
|
@ -46,4 +46,4 @@ private:
|
||||||
QUrl m_filePath;
|
QUrl m_filePath;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //SONGSQLMODEL_H
|
#endif //VIDEOSQLMODEL_H
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue