11 Commits

7 changed files with 168 additions and 83 deletions

View File

@ -11,7 +11,7 @@ set(CMAKE_INSTALL_PREFIX "${CMAKE_SOURCE_DIR}/dist/${BUILDCORE_BUILD_CONFIG}")
set(CMAKE_EXPORT_COMPILE_COMMANDS ON) set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON) set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF) set(CMAKE_CXX_EXTENSIONS OFF)
# enable ccache # enable ccache
@ -26,9 +26,14 @@ if(CMAKE_BUILD_TYPE STREQUAL "Debug")
add_definitions(-DDEBUG) add_definitions(-DDEBUG)
else() else()
add_definitions(-DNDEBUG) add_definitions(-DNDEBUG)
if(APPLE)
set(CMAKE_OSX_ARCHITECTURES arm64;x86_64)
endif()
endif() endif()
if(NOT MSVC) if(MSVC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Zc:preprocessor")
else()
# forces colored output when using ninja # forces colored output when using ninja
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fdiagnostics-color") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fdiagnostics-color")
# enable warnings # enable warnings
@ -39,7 +44,7 @@ if(NOT MSVC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wformat=2") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wformat=2")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wmissing-field-initializers") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wmissing-field-initializers")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wnon-virtual-dtor") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wnon-virtual-dtor")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wnull-dereference") #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wnull-dereference")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wold-style-cast") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wold-style-cast")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Woverloaded-virtual") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Woverloaded-virtual")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wpedantic") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wpedantic")

View File

@ -16,16 +16,27 @@ else
HOST_ENV=${OS}-$(shell uname -m) HOST_ENV=${OS}-$(shell uname -m)
endif endif
ifeq ($(shell python -c 'import sys; print(sys.version_info[0])'),3) DEVENV=devenv$(shell pwd | sed 's/\//-/g')
PYTHON3=python DEVENV_IMAGE=${PROJECT_NAME}-devenv
else ifneq ($(shell which docker 2> /dev/null),)
ifeq ($(shell docker inspect --format="{{.State.Status}}" ${DEVENV} 2>&1),running)
ENV_RUN=docker exec -i -t --user $(shell id -u ${USER}) ${DEVENV}
endif
endif
ifneq ($(shell which python3 2> /dev/null),)
PYTHON3=python3 PYTHON3=python3
else
ifeq ($(shell ${ENV_RUN} python -c 'import sys; print(sys.version_info[0])'),3)
PYTHON3=python
endif
endif endif
SCRIPTS=${BUILDCORE_PATH}/scripts SCRIPTS=${BUILDCORE_PATH}/scripts
SETUP_BUILD=${PYTHON3} ${SCRIPTS}/setup-build.py SETUP_BUILD=${PYTHON3} ${SCRIPTS}/setup-build.py
PYBB=${PYTHON3} ${SCRIPTS}/pybb.py PYBB=${PYTHON3} ${SCRIPTS}/pybb.py
CMAKE_BUILD=${PYBB} cmake-build CMAKE_BUILD=${PYBB} cmake-build
CTEST=${PYBB} ctest-all
RM_RF=${PYBB} rm RM_RF=${PYBB} rm
ifdef USE_VCPKG ifdef USE_VCPKG
ifndef VCPKG_DIR_BASE ifndef VCPKG_DIR_BASE
@ -37,19 +48,12 @@ ifdef USE_VCPKG
VCPKG_TOOLCHAIN=--toolchain=${VCPKG_DIR}/scripts/buildsystems/vcpkg.cmake VCPKG_TOOLCHAIN=--toolchain=${VCPKG_DIR}/scripts/buildsystems/vcpkg.cmake
endif endif
ifeq ($(OS),darwin) ifeq ($(OS),darwin)
DEBUGGER=lldb DEBUGGER=lldb --
else else
DEBUGGER=gdb --args DEBUGGER=gdb --args
endif endif
VCPKG_DIR=$(VCPKG_DIR_BASE)/$(VCPKG_VERSION)-$(HOST_ENV) VCPKG_DIR=$(VCPKG_DIR_BASE)/$(VCPKG_VERSION)-$(HOST_ENV)
DEVENV=devenv$(shell pwd | sed 's/\//-/g')
DEVENV_IMAGE=${PROJECT_NAME}-devenv
ifneq ($(shell which docker 2> /dev/null),)
ifeq ($(shell docker inspect --format="{{.State.Status}}" ${DEVENV} 2>&1),running)
ENV_RUN=docker exec -i -t --user $(shell id -u ${USER}) ${DEVENV}
endif
endif
CURRENT_BUILD=$(HOST_ENV)-$(shell ${PYBB} cat .current_build) CURRENT_BUILD=$(HOST_ENV)-$(shell ${PYBB} cat .current_build)
.PHONY: build .PHONY: build
@ -69,6 +73,12 @@ purge:
.PHONY: test .PHONY: test
test: build test: build
${ENV_RUN} ${CMAKE_BUILD} build test ${ENV_RUN} ${CMAKE_BUILD} build test
.PHONY: test-verbose
test-verbose: build
${ENV_RUN} ${CTEST} build --output-on-failure
.PHONY: test-rerun-verbose
test-rerun-verbose: build
${ENV_RUN} ${CTEST} build --rerun-failed --output-on-failure
.PHONY: devenv-image .PHONY: devenv-image
devenv-image: devenv-image:
@ -89,11 +99,14 @@ devenv-create:
.PHONY: devenv-destroy .PHONY: devenv-destroy
devenv-destroy: devenv-destroy:
docker rm -f ${DEVENV} docker rm -f ${DEVENV}
ifdef ENV_RUN
.PHONY: devenv-shell .PHONY: devenv-shell
devenv-shell: devenv-shell:
${ENV_RUN} bash ${ENV_RUN} bash
endif
ifdef USE_VCPKG ifdef USE_VCPKG
.PHONY: vcpkg .PHONY: vcpkg
vcpkg: ${VCPKG_DIR} vcpkg-install vcpkg: ${VCPKG_DIR} vcpkg-install
@ -114,18 +127,24 @@ ifneq (${OS},windows)
else else
${VCPKG_DIR}/vcpkg install --triplet x64-windows ${VCPKG_PKGS} ${VCPKG_DIR}/vcpkg install --triplet x64-windows ${VCPKG_PKGS}
endif endif
else # USE_VCPKG
else ifdef USE_CONAN # USE_VCPKG ################################################
.PHONY: setup-conan .PHONY: setup-conan
conan-config: conan-config:
conan profile new nostalgia --detect --force ${ENV_RUN} conan profile new ${PROJECT_NAME} --detect --force
ifeq ($(OS),linux) ifeq ($(OS),linux)
conan profile update settings.compiler.libcxx=libstdc++11 ${PROJECT_NAME} ${ENV_RUN} conan profile update settings.compiler.libcxx=libstdc++11 ${PROJECT_NAME}
else
${ENV_RUN} conan profile update settings.compiler.cppstd=20 ${PROJECT_NAME}
ifeq ($(OS),windows)
${ENV_RUN} conan profile update settings.compiler.runtime=static ${PROJECT_NAME}
endif
endif endif
.PHONY: conan .PHONY: conan
conan: conan:
@mkdir -p .conanbuild && cd .conanbuild && conan install ../ --build=missing -pr=${PROJECT_NAME} ${ENV_RUN} ${PYBB} conan-install ${PROJECT_NAME}
endif # USE_VCPKG endif # USE_VCPKG ###############################################
.PHONY: configure-xcode .PHONY: configure-xcode
configure-xcode: configure-xcode:

View File

@ -8,7 +8,7 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/. # file, You can obtain one at http://mozilla.org/MPL/2.0/.
# #
# "Python Busy Box" - adds cross platform equivalents to Unix commands that # "Python Busy Box" - adds cross-platform equivalents to Unix commands that
# don't translate well to that other operating system # don't translate well to that other operating system
import os import os
@ -17,31 +17,56 @@ import subprocess
import sys import sys
def cat(path): def cat(paths: [str]) -> int:
for path in paths:
try: try:
with open(path) as f: with open(path) as f:
data = f.read() data = f.read()
print(data) sys.stdout.write(data)
return 0
except FileNotFoundError: except FileNotFoundError:
sys.stderr.write('cat: {}: no such file or directory\n'.format(path)) sys.stderr.write('cat: {}: no such file or directory\n'.format(path))
return 1 return 1
sys.stdout.write('\n')
return 0
def mkdir(path): def mkdir(path: str) -> int:
if not os.path.exists(path) and os.path.isdir(path): if not os.path.exists(path):
try:
os.mkdir(path) os.mkdir(path)
except:
return 1
return 0
if os.path.isdir(path):
return 0
return 1
# this exists because Windows is utterly incapable of providing a proper rm -rf # this exists because Windows is utterly incapable of providing a proper rm -rf
def rm(path): def rm(path: str) -> int:
if (os.path.exists(path) or os.path.islink(path)) and not os.path.isdir(path): if (os.path.exists(path) or os.path.islink(path)) and not os.path.isdir(path):
os.remove(path) os.remove(path)
elif os.path.isdir(path): elif os.path.isdir(path):
shutil.rmtree(path) shutil.rmtree(path)
return 0
def cmake_build(base_path, target): def ctest_all() -> int:
base_path = sys.argv[2]
if not os.path.isdir(base_path):
# no generated projects
return 0
args = ['ctest'] + sys.argv[3:]
orig_dir = os.getcwd()
for d in os.listdir(base_path):
os.chdir(os.path.join(orig_dir, base_path, d))
err = subprocess.run(args).returncode
if err != 0:
return err
return 0
def cmake_build(base_path: str, target: str) -> int:
if not os.path.isdir(base_path): if not os.path.isdir(base_path):
# nothing to build # nothing to build
return 0 return 0
@ -52,24 +77,47 @@ def cmake_build(base_path, target):
err = subprocess.run(args).returncode err = subprocess.run(args).returncode
if err != 0: if err != 0:
return err return err
return 0
def conan() -> int:
project_name = sys.argv[2]
conan_dir = '.conanbuild'
err = mkdir(conan_dir)
if err != 0:
return err
args = ['conan', 'install', '../', '--build=missing', '-pr', project_name]
os.chdir(conan_dir)
err = subprocess.run(args).returncode
if err != 0:
return err
return 0
def main(): def main():
err = 0
if sys.argv[1] == 'mkdir': if sys.argv[1] == 'mkdir':
mkdir(sys.argv[2]) err = mkdir(sys.argv[2])
elif sys.argv[1] == 'rm': elif sys.argv[1] == 'rm':
for i in range(2, len(sys.argv)): for i in range(2, len(sys.argv)):
rm(sys.argv[i]) rm(sys.argv[i])
elif sys.argv[1] == 'conan-install':
err = conan()
elif sys.argv[1] == 'ctest-all':
err = ctest_all()
elif sys.argv[1] == 'cmake-build': elif sys.argv[1] == 'cmake-build':
err = cmake_build(sys.argv[2], sys.argv[3] if len(sys.argv) > 3 else None) err = cmake_build(sys.argv[2], sys.argv[3] if len(sys.argv) > 3 else None)
sys.exit(err)
elif sys.argv[1] == 'cat': elif sys.argv[1] == 'cat':
err = cat(sys.argv[2]) err = cat(sys.argv[2:])
sys.exit(err) else:
sys.stderr.write('Command not found\n')
err = 1
return err
if __name__ == '__main__': if __name__ == '__main__':
try: try:
main() err = main()
sys.exit(err)
except KeyboardInterrupt: except KeyboardInterrupt:
sys.exit(1) sys.exit(1)

View File

@ -66,15 +66,21 @@ def main():
build_dir = '{:s}/build/{:s}'.format(project_dir, build_config) build_dir = '{:s}/build/{:s}'.format(project_dir, build_config)
rm(build_dir) rm(build_dir)
mkdir(build_dir) mkdir(build_dir)
subprocess.run(['cmake', '-S', project_dir, '-B', build_dir, build_tool, cmake_cmd = [
'cmake', '-S', project_dir, '-B', build_dir, build_tool,
'-DCMAKE_EXPORT_COMPILE_COMMANDS=ON', '-DCMAKE_EXPORT_COMPILE_COMMANDS=ON',
'-DCMAKE_TOOLCHAIN_FILE={:s}'.format(args.toolchain), '-DCMAKE_TOOLCHAIN_FILE={:s}'.format(args.toolchain),
'-DCMAKE_BUILD_TYPE={:s}'.format(build_type_arg), '-DCMAKE_BUILD_TYPE={:s}'.format(build_type_arg),
'-DUSE_ASAN={:s}'.format(sanitizer_status), '-DUSE_ASAN={:s}'.format(sanitizer_status),
'-DBUILDCORE_BUILD_CONFIG={:s}'.format(build_config), '-DBUILDCORE_BUILD_CONFIG={:s}'.format(build_config),
'-DBUILDCORE_TARGET={:s}'.format(args.target), '-DBUILDCORE_TARGET={:s}'.format(args.target),
qt_path, ]
]) if qt_path != '':
cmake_cmd.append(qt_path)
if platform.system() == 'Windows':
cmake_cmd.append('-A x64')
subprocess.run(cmake_cmd)
mkdir('dist') mkdir('dist')
if int(args.current_build) != 0: if int(args.current_build) != 0:

View File

@ -26,31 +26,38 @@ MainWindow::MainWindow(QWidget *parent): QMainWindow(parent) {
rootLyt->addWidget(m_slideView); rootLyt->addWidget(m_slideView);
rootLyt->addLayout(controlsLayout); rootLyt->addLayout(controlsLayout);
// setup slide controls // setup slide controls
const auto showHideLyt = new QHBoxLayout;
rootLyt->addLayout(showHideLyt);
const auto btnPrevSong = new QPushButton(tr("Previous Song (Left)"), this); const auto btnPrevSong = new QPushButton(tr("Previous Song (Left)"), this);
const auto btnPrevSlide = new QPushButton(tr("Previous Slide (Up)"), this); const auto btnPrevSlide = new QPushButton(tr("Previous Slide (Up)"), this);
const auto btnNextSlide = new QPushButton(tr("Next Slide (Down)"), this); const auto btnNextSlide = new QPushButton(tr("Next Slide (Down)"), this);
const auto btnNextSong = new QPushButton(tr("Next Song (Right)"), this); const auto btnNextSong = new QPushButton(tr("Next Song (Right)"), this);
const auto btnBlankSlides = new QPushButton(tr("Blank Slides (,)"), this); const auto btnHideSlides = new QPushButton(tr("Hide (1)"), this);
const auto btnShowSlides = new QPushButton(tr("Show Slides (.)"), this); const auto btnOpenLpShowSlides = new QPushButton(tr("Show in OpenLP Only (2)"), this);
controlsLayout->addWidget(btnPrevSlide, 0, 0); const auto btnShowSlides = new QPushButton(tr("Show (3)"), mainWidget);
controlsLayout->addWidget(btnNextSlide, 0, 1); controlsLayout->addWidget(btnPrevSlide, 0, 1);
controlsLayout->addWidget(btnPrevSong, 1, 0); controlsLayout->addWidget(btnNextSlide, 0, 2);
controlsLayout->addWidget(btnNextSong, 1, 1); controlsLayout->addWidget(btnPrevSong, 0, 0);
controlsLayout->addWidget(btnBlankSlides, 2, 0); controlsLayout->addWidget(btnNextSong, 0, 3);
controlsLayout->addWidget(btnShowSlides, 2, 1); showHideLyt->addWidget(btnHideSlides);
showHideLyt->addWidget(btnOpenLpShowSlides);
showHideLyt->addWidget(btnShowSlides);
btnNextSong->setShortcut(Qt::Key_Right); btnNextSong->setShortcut(Qt::Key_Right);
btnPrevSong->setShortcut(Qt::Key_Left); btnPrevSong->setShortcut(Qt::Key_Left);
btnNextSlide->setShortcut(Qt::Key_Down); btnNextSlide->setShortcut(Qt::Key_Down);
btnPrevSlide->setShortcut(Qt::Key_Up); btnPrevSlide->setShortcut(Qt::Key_Up);
btnBlankSlides->setShortcut(Qt::Key_Comma); btnHideSlides->setShortcut(Qt::Key_1);
btnShowSlides->setShortcut(Qt::Key_Period); btnOpenLpShowSlides->setShortcut(Qt::Key_2);
btnBlankSlides->setToolTip(tr("Also hides slides in OBS")); btnHideSlides->setToolTip(tr("Also hides slides in OBS"));
btnShowSlides->setShortcut(Qt::Key_3);
connect(btnNextSlide, &QPushButton::clicked, &m_openlpClient, &OpenLPClient::nextSlide); connect(btnNextSlide, &QPushButton::clicked, &m_openlpClient, &OpenLPClient::nextSlide);
connect(btnPrevSlide, &QPushButton::clicked, &m_openlpClient, &OpenLPClient::prevSlide); connect(btnPrevSlide, &QPushButton::clicked, &m_openlpClient, &OpenLPClient::prevSlide);
connect(btnNextSong, &QPushButton::clicked, &m_openlpClient, &OpenLPClient::nextSong); connect(btnNextSong, &QPushButton::clicked, &m_openlpClient, &OpenLPClient::nextSong);
connect(btnPrevSong, &QPushButton::clicked, &m_openlpClient, &OpenLPClient::prevSong); connect(btnPrevSong, &QPushButton::clicked, &m_openlpClient, &OpenLPClient::prevSong);
connect(btnBlankSlides, &QPushButton::clicked, &m_openlpClient, &OpenLPClient::blankScreen); connect(btnHideSlides, &QPushButton::clicked, &m_openlpClient, &OpenLPClient::blankScreen);
connect(btnBlankSlides, &QPushButton::clicked, &m_obsClient, &OBSClient::hideSlides); connect(btnHideSlides, &QPushButton::clicked, &m_obsClient, &OBSClient::hideSlides);
connect(btnOpenLpShowSlides, &QPushButton::clicked, &m_openlpClient, &OpenLPClient::showSlides);
connect(btnShowSlides, &QPushButton::clicked, &m_obsClient, &OBSClient::showSlides);
connect(btnShowSlides, &QPushButton::clicked, &m_openlpClient, &OpenLPClient::showSlides); connect(btnShowSlides, &QPushButton::clicked, &m_openlpClient, &OpenLPClient::showSlides);
connect(&m_openlpClient, &OpenLPClient::pollUpdate, m_slideView, &SlideView::pollUpdate); connect(&m_openlpClient, &OpenLPClient::pollUpdate, m_slideView, &SlideView::pollUpdate);
connect(&m_openlpClient, &OpenLPClient::songListUpdate, m_slideView, &SlideView::songListUpdate); connect(&m_openlpClient, &OpenLPClient::songListUpdate, m_slideView, &SlideView::songListUpdate);
@ -59,16 +66,7 @@ MainWindow::MainWindow(QWidget *parent): QMainWindow(parent) {
connect(m_slideView, &SlideView::songChanged, &m_openlpClient, &OpenLPClient::changeSong); connect(m_slideView, &SlideView::songChanged, &m_openlpClient, &OpenLPClient::changeSong);
connect(m_slideView, &SlideView::slideChanged, &m_openlpClient, &OpenLPClient::changeSlide); connect(m_slideView, &SlideView::slideChanged, &m_openlpClient, &OpenLPClient::changeSlide);
// setup scene selector // setup scene selector
const auto btnObsHideSlides = new QPushButton(tr("Hide Slides in OBS (;)"), mainWidget); connect(btnOpenLpShowSlides, &QPushButton::clicked, &m_obsClient, &OBSClient::hideSlides);
const auto btnObsShowSlides = new QPushButton(tr("Show Slides in OBS (')"), mainWidget);
controlsLayout->addWidget(btnObsHideSlides, 3, 0);
controlsLayout->addWidget(btnObsShowSlides, 3, 1);
btnObsHideSlides->setShortcut(Qt::Key_Semicolon);
btnObsShowSlides->setShortcut(Qt::Key_Apostrophe);
btnObsShowSlides->setToolTip(tr("Also shows slides in OpenLP"));
connect(btnObsHideSlides, &QPushButton::clicked, &m_obsClient, &OBSClient::hideSlides);
connect(btnObsShowSlides, &QPushButton::clicked, &m_obsClient, &OBSClient::showSlides);
connect(btnObsShowSlides, &QPushButton::clicked, &m_openlpClient, &OpenLPClient::showSlides);
// setup status bar // setup status bar
setStatusBar(new QStatusBar(this)); setStatusBar(new QStatusBar(this));
connect(&m_openlpClient, &OpenLPClient::songChanged, this, &MainWindow::refreshStatusBar); connect(&m_openlpClient, &OpenLPClient::songChanged, this, &MainWindow::refreshStatusBar);

View File

@ -8,15 +8,16 @@
#include <QComboBox> #include <QComboBox>
#include <QDebug> #include <QDebug>
#include <QHBoxLayout>
#include <QHeaderView> #include <QHeaderView>
#include <QListWidget>
#include <QTableWidget> #include <QTableWidget>
#include <QVBoxLayout>
#include "slideview.hpp" #include "slideview.hpp"
SlideView::SlideView(QWidget *parent): QWidget(parent) { SlideView::SlideView(QWidget *parent): QWidget(parent) {
auto lyt = new QVBoxLayout(this); auto lyt = new QHBoxLayout(this);
m_songSelector = new QComboBox(this); m_songSelector = new QListWidget(this);
m_slideTable = new QTableWidget(this); m_slideTable = new QTableWidget(this);
auto header = m_slideTable->horizontalHeader(); auto header = m_slideTable->horizontalHeader();
header->setVisible(false); header->setVisible(false);
@ -28,24 +29,29 @@ SlideView::SlideView(QWidget *parent): QWidget(parent) {
#ifndef _WIN32 #ifndef _WIN32
m_slideTable->setAlternatingRowColors(true); m_slideTable->setAlternatingRowColors(true);
#endif #endif
lyt->addWidget(m_songSelector);
lyt->addWidget(m_slideTable); lyt->addWidget(m_slideTable);
lyt->addWidget(m_songSelector);
connect(m_slideTable, &QTableWidget::currentCellChanged, this, &SlideView::slideChanged); connect(m_slideTable, &QTableWidget::currentCellChanged, this, &SlideView::slideChanged);
} }
QString SlideView::getNextSong() const { QString SlideView::getNextSong() const {
const auto cnt = m_songSelector->count(); const auto cnt = m_songSelector->count();
const auto idx = m_songSelector->currentIndex() + 1; const auto idx = m_songSelector->currentRow() + 1;
if (idx < cnt) { if (idx < cnt) {
return m_songSelector->itemText(idx); return m_songSelector->currentItem()->text();
} }
return ""; return "";
} }
void SlideView::pollUpdate(QString songName, int slide) { void SlideView::pollUpdate(QString songName, int slide) {
if (songName != m_currentSong) { auto songItems = m_songSelector->findItems(songName, Qt::MatchFixedString);
if (songItems.size() < 1) {
return;
}
auto songItem = songItems.first();
if (songItem != m_songSelector->currentItem()) {
m_currentSong = songName; m_currentSong = songName;
m_songSelector->setCurrentText(songName); m_songSelector->setCurrentItem(songItem);
} }
if (slide != m_currentSlide) { if (slide != m_currentSlide) {
m_currentSlide = slide; m_currentSlide = slide;
@ -54,7 +60,8 @@ void SlideView::pollUpdate(QString songName, int slide) {
} }
void SlideView::changeSong(int song) { void SlideView::changeSong(int song) {
if (m_songSelector->currentText() != m_currentSong) { auto songItem = m_songSelector->item(song);
if (songItem->text() != m_currentSong) {
emit songChanged(song); emit songChanged(song);
} }
} }
@ -90,5 +97,5 @@ void SlideView::songListUpdate(QStringList songList) {
if (isReplacement) { if (isReplacement) {
changeSong(0); changeSong(0);
} }
connect(m_songSelector, SIGNAL(currentIndexChanged(int)), this, SLOT(changeSong(int))); connect(m_songSelector, &QListWidget::currentRowChanged, this, &SlideView::changeSong);
} }

View File

@ -13,12 +13,14 @@ class SlideView: public QWidget {
Q_OBJECT Q_OBJECT
private: private:
class QTableWidget *m_slideTable = nullptr; class QTableWidget *m_slideTable = nullptr;
class QComboBox *m_songSelector = nullptr; class QListWidget *m_songSelector = nullptr;
QString m_currentSong; QString m_currentSong;
int m_currentSlide = -1; int m_currentSlide = -1;
public: public:
explicit SlideView(QWidget *parent = nullptr); explicit SlideView(QWidget *parent = nullptr);
[[nodiscard]]
QString getNextSong() const; QString getNextSong() const;
public slots: public slots: