From 51529cefb16f700acf92a4ab484a3fc0415ccc90 Mon Sep 17 00:00:00 2001 From: Tres Finocchiaro Date: Mon, 3 Nov 2025 12:58:15 -0500 Subject: [PATCH] Add Qt6 Support (#7339) * Rebase against master Co-authored-by: michaelgregorius Co-authored-by: Rossmaxx <74815851+Rossmaxx@users.noreply.github.com> * Fix Qt6 DMG on Apple (#7240) - Fix linking issues with Qt Framework files - Fix qmake detection * Fixes after rebase * Fix embed.cpp compilation Fix implicit conversion from int when using QString.arg(...) * Fix Qt6 signature change for nativeEventFilter (#7254) * Adds win32EventFilter a wrapper for nativeEventFilter on Windows * win32EventFilter is currently used to intercept top-level Window events (currently, to avoid VSTs setting transparency of the parent application) * fix broken signal slot connections (#7274) QComboBox activated() replaced with textActivated() since Qt 5.14 * Enabled VSTs on Qt 6 (#7273) * enabled VST support for Qt 6 builds * Note : Embedding on QT6 will be buggy on linux as a result of using qt embedding, which unfortunately is a qt bug which hasn't been resolved. * Changed bar lines to follow snap size (#7034) * Added lines in between bars * Changed bar lines to follow snap size * Changed default zoom and quantization value * Added constants for line widths * Added QSS configuration for new grid line colors * Tied line widths to QSS properties * Changed default quantization to 1/4 * Removed clear() from destructor model * Removed destructor in ComboBoxModel.h * Changed member set/get functions to pass by value * Updated signal connection with newer syntax * Fix compilation * Fix MSVC builds * fix nullptr deref in AudioFileProcessor (qt6 branch) (#7532) * ensured mouse event != nullptr before deref * separation of concerns: AFP WaveView updateCursor extract check to pointerCloseToStartEndOrLoop() * marked some function parameters as const * Remove Core5Compat usage * Fix bad merge * Fixes after rebase * Simplify QTX_WRAP_CPP call * Remove comments that are obvious to a developer * Whitespace * Try using Qt 6 for MSVC CI I chose Qt 6.5 because it's the last Qt LTS release with declared support for Visual Studio 2019. Once we upgrade to Visual Studio 2022, we could upgrade Qt as well. * Fix MSVC build Also fixes two memory leaks in MidiWinMM * Fix GuiApplication on MSVC * Fix interpolateInRgb * Try building with patched Calf * Fix submodule * Fix OpulenZ build * Try to fix zyn * Fix comment * Ty to fix zyn (again) * Ty to fix RemotePluginBase * Revert "Ty to fix RemotePluginBase" This reverts commit 92dac44ffb11e19d1d5a21d9155369f017bd59e9. * Update plugins/ZynAddSubFx/CMakeLists.txt Co-authored-by: Dalton Messmer * Fix vertical & horizontal scroll wheel in SongEditor * AppImage: Fix finding of Qt6 libs * Fix implicit QString --> QFileInfo conversion * Point submodule to lmms * Fix multiple deprecation warnings * Fix for Clang compiler * Build with latest Qt LTS version now that we use MSVC 2022 * Update jurplel/install-qt-action to v4.3.0 * Bump minimum Qt6 version for MSVC * Fix incorrect Qt version checks Some comparisons were using ">" rather than ">=" * `QSize()` != `QSize(0, 0)` * Fix more deprecation warnings * Fix style * Simplify Spectrum Analyzer mouse events The Qt bug that used to be present appears to have been fixed, so the workaround can be removed * Minor changes * Fix deprecated QCheckBox signal * Fix setContent helper functions * Remove QMultiMap usage from ControlLayout * Remove SIGNAL and SLOT macros * Revert TrackView.cpp changes * Remove Q_DISABLE_MOVE usage since it does not seem to be available in Qt6 --------- Co-authored-by: michaelgregorius Co-authored-by: Rossmaxx <74815851+Rossmaxx@users.noreply.github.com> Co-authored-by: BoredGuy1 <66702733+BoredGuy1@users.noreply.github.com> Co-authored-by: Hyunjin Song Co-authored-by: Lisa Magdalena Riedler Co-authored-by: Dalton Messmer --- .github/workflows/build.yml | 7 +- CMakeLists.txt | 50 ++++-- cmake/install/CMakeLists.txt | 8 +- cmake/linux/LinuxDeploy.cmake | 4 + cmake/modules/BuildPlugin.cmake | 4 +- cmake/modules/GenQrc.cmake | 2 +- data/locale/CMakeLists.txt | 4 +- include/ColorChooser.h | 3 +- include/ColorHelper.h | 20 ++- include/ControlLayout.h | 6 +- include/DeprecationHelper.h | 122 +++++++++++++- include/FileRevealer.h | 10 ++ include/FileSearchJob.h | 6 +- include/FloatModelEditorBase.h | 6 +- include/MainApplication.h | 12 +- include/PluginBrowser.h | 6 +- include/TabWidget.h | 2 +- include/base64.h | 6 +- include/embed.h | 8 +- .../AudioFileProcessorWaveView.cpp | 44 +++-- .../AudioFileProcessorWaveView.h | 3 +- plugins/Delay/DelayControlsDialog.cpp | 11 +- .../LadspaMatrixControlDialog.cpp | 2 +- plugins/OpulenZ/OpulenZ.cpp | 2 +- plugins/SlicerT/SlicerTWaveform.cpp | 25 ++- plugins/SpectrumAnalyzer/SaSpectrumView.cpp | 13 +- plugins/SpectrumAnalyzer/SaWaterfallView.cpp | 13 +- plugins/VstBase/VstPlugin.cpp | 6 +- plugins/VstBase/vstbase/CMakeLists.txt | 2 +- plugins/ZynAddSubFx/CMakeLists.txt | 15 +- src/3rdparty/CMakeLists.txt | 2 +- src/CMakeLists.txt | 11 ++ src/core/AutomationClip.cpp | 43 +++-- src/core/ConfigManager.cpp | 7 +- src/core/DataFile.cpp | 11 +- src/core/InstrumentFunctions.cpp | 4 +- src/core/base64.cpp | 8 +- src/core/main.cpp | 5 + src/core/midi/MidiWinMM.cpp | 12 +- src/gui/ControlLayout.cpp | 8 +- src/gui/ControllerRackView.cpp | 4 +- src/gui/EffectRackView.cpp | 4 +- src/gui/FileBrowser.cpp | 23 ++- src/gui/GuiApplication.cpp | 8 +- src/gui/MainApplication.cpp | 8 +- src/gui/MainWindow.cpp | 156 +++++++++--------- src/gui/MixerChannelView.cpp | 12 +- src/gui/PluginBrowser.cpp | 10 +- src/gui/ProjectNotes.cpp | 23 ++- src/gui/SubWindow.cpp | 2 +- src/gui/clips/AutomationClipView.cpp | 12 +- src/gui/clips/ClipView.cpp | 28 ++-- src/gui/clips/MidiClipView.cpp | 8 +- src/gui/editors/AutomationEditor.cpp | 53 +++--- src/gui/editors/Editor.cpp | 2 +- src/gui/editors/PianoRoll.cpp | 137 ++++++++------- src/gui/editors/SongEditor.cpp | 10 +- src/gui/editors/TimeLineWidget.cpp | 19 ++- src/gui/embed.cpp | 2 +- src/gui/instrument/PianoView.cpp | 17 +- src/gui/modals/SetupDialog.cpp | 19 ++- src/gui/tracks/AutomationTrackView.cpp | 12 +- src/gui/tracks/SampleTrackView.cpp | 6 +- src/gui/tracks/TrackContentWidget.cpp | 13 +- src/gui/tracks/TrackLabelButton.cpp | 4 +- src/gui/tracks/TrackOperationsWidget.cpp | 12 +- src/gui/tracks/TrackView.cpp | 22 ++- src/gui/widgets/ComboBox.cpp | 5 +- src/gui/widgets/Fader.cpp | 7 +- src/gui/widgets/FloatModelEditorBase.cpp | 19 ++- src/gui/widgets/Graph.cpp | 17 +- src/gui/widgets/GroupBox.cpp | 5 +- src/gui/widgets/LcdFloatSpinBox.cpp | 13 +- src/gui/widgets/LcdSpinBox.cpp | 16 +- src/gui/widgets/SimpleTextFloat.cpp | 2 +- src/gui/widgets/TabWidget.cpp | 12 +- 76 files changed, 798 insertions(+), 457 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 81a65e15b..14b35e2a2 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -372,10 +372,10 @@ jobs: - name: Install tools run: choco install ccache - name: Install Qt - uses: jurplel/install-qt-action@b3ea5275e37b734d027040e2c7fe7a10ea2ef946 + uses: jurplel/install-qt-action@d325aaf2a8baeeda41ad0b5d39f84a6af9bcf005 with: - version: '5.15.2' - arch: "win64_msvc2019_64" + version: '6.8.*' + arch: "win64_msvc2022_64" archives: qtbase qtsvg qttools cache: true - name: Set up build environment @@ -392,6 +392,7 @@ jobs: --toolchain C:/vcpkg/scripts/buildsystems/vcpkg.cmake ` -Werror=dev ` -DCMAKE_BUILD_TYPE=RelWithDebInfo ` + -DWANT_QT6=ON ` -DUSE_COMPILE_CACHE=ON ` -DUSE_WERROR=ON ` -DVCPKG_TARGET_TRIPLET="x64-windows" ` diff --git a/CMakeLists.txt b/CMakeLists.txt index e45d8b7b2..7d39a5890 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -107,6 +107,7 @@ option(WANT_DEBUG_GPROF "Enable gprof profiler" OFF) OPTION(BUNDLE_QT_TRANSLATIONS "Install Qt translation files for LMMS" OFF) option(WANT_DEBUG_CPACK "Show detailed logs for packaging commands" OFF) option(WANT_CPACK_TARBALL "Request CPack to create a tarball instead of an installer" OFF) +option(WANT_QT6 "Build with experimental Qt6 support" OFF) IF(LMMS_BUILD_APPLE) @@ -174,31 +175,45 @@ check_library_exists(rt shm_open "" LMMS_HAVE_LIBRT) LIST(APPEND CMAKE_PREFIX_PATH "${CMAKE_INSTALL_PREFIX}") -FIND_PACKAGE(Qt5 5.9.0 COMPONENTS Core Gui Widgets Xml Svg REQUIRED) -FIND_PACKAGE(Qt5 COMPONENTS LinguistTools QUIET) +if(WANT_QT6) + set(QT_VERSION_MAJOR 6) + if(MSVC) + set(LMMS_QT_MIN_VERSION 6.8.0) + else() + set(LMMS_QT_MIN_VERSION 6.0.0) + endif() + set(STATUS_QT6 "Enabled") +else() + set(QT_VERSION_MAJOR 5) + set(LMMS_QT_MIN_VERSION 5.9.0) + set(STATUS_QT6 "Disabled") +endif() + +find_package(Qt${QT_VERSION_MAJOR} ${LMMS_QT_MIN_VERSION} COMPONENTS Core Gui Widgets Xml Svg REQUIRED) +find_package(Qt${QT_VERSION_MAJOR} COMPONENTS LinguistTools QUIET) include_directories(SYSTEM - ${Qt5Core_INCLUDE_DIRS} - ${Qt5Gui_INCLUDE_DIRS} - ${Qt5Widgets_INCLUDE_DIRS} - ${Qt5Xml_INCLUDE_DIRS} + ${Qt${QT_VERSION_MAJOR}Core_INCLUDE_DIRS} + ${Qt${QT_VERSION_MAJOR}Gui_INCLUDE_DIRS} + ${Qt${QT_VERSION_MAJOR}Widgets_INCLUDE_DIRS} + ${Qt${QT_VERSION_MAJOR}Xml_INCLUDE_DIRS} ) -SET(QT_LIBRARIES - Qt5::Core - Qt5::Gui - Qt5::Widgets - Qt5::Xml - Qt5::Svg +set(QT_LIBRARIES + Qt${QT_VERSION_MAJOR}::Core + Qt${QT_VERSION_MAJOR}::Gui + Qt${QT_VERSION_MAJOR}::Widgets + Qt${QT_VERSION_MAJOR}::Xml + Qt${QT_VERSION_MAJOR}::Svg ) -IF(LMMS_BUILD_LINUX AND WANT_VST) +IF(LMMS_BUILD_LINUX AND WANT_VST AND NOT WANT_QT6) FIND_PACKAGE(Qt5 COMPONENTS X11Extras REQUIRED) LIST(APPEND QT_LIBRARIES Qt5::X11Extras) ENDIF() -# Resolve Qt5::qmake to full path for use in packaging scripts -GET_TARGET_PROPERTY(QT_QMAKE_EXECUTABLE "${Qt5Core_QMAKE_EXECUTABLE}" IMPORTED_LOCATION) +# Resolve qmake to full path for use in packaging scripts +get_target_property(QT_QMAKE_EXECUTABLE Qt${QT_VERSION_MAJOR}::qmake IMPORTED_LOCATION) # Find the location of Qt translation files execute_process(COMMAND ${QT_QMAKE_EXECUTABLE} -query QT_INSTALL_TRANSLATIONS @@ -211,8 +226,8 @@ IF(EXISTS "${QT_TRANSLATIONS_DIR}") ADD_DEFINITIONS("-DQT_TRANSLATIONS_DIR=\"${QT_TRANSLATIONS_DIR}\"") ENDIF() -FIND_PACKAGE(Qt5Test) -SET(QT_QTTEST_LIBRARY Qt5::Test) +FIND_PACKAGE(Qt${QT_VERSION_MAJOR}Test) +SET(QT_QTTEST_LIBRARY Qt${QT_VERSION_MAJOR}::Test) # check for libsndfile FIND_PACKAGE(SndFile REQUIRED) @@ -878,6 +893,7 @@ MESSAGE( "* Debug packaging commands : ${STATUS_DEBUG_CPACK}\n" "* Profile using GNU profiler : ${STATUS_GPROF}\n" "* Debug assertions : ${STATUS_ASSERTIONS}\n" +"* Experimental Qt6 support : ${STATUS_QT6}\n" ) MESSAGE( diff --git a/cmake/install/CMakeLists.txt b/cmake/install/CMakeLists.txt index 0b81039ab..f5e5acf72 100644 --- a/cmake/install/CMakeLists.txt +++ b/cmake/install/CMakeLists.txt @@ -1,9 +1,9 @@ SET(PLUGIN_FILES "") IF(LMMS_BUILD_WIN32) - INSTALL(FILES $ DESTINATION platforms) - INSTALL(FILES $ DESTINATION iconengines) - INSTALL(FILES $ DESTINATION imageformats) - INSTALL(FILES $ DESTINATION .) + INSTALL(FILES $ DESTINATION platforms) + INSTALL(FILES $ DESTINATION iconengines) + INSTALL(FILES $ DESTINATION imageformats) + INSTALL(FILES $ DESTINATION .) ENDIF() IF(LMMS_BUILD_WIN32 OR LMMS_INSTALL_DEPENDENCIES) diff --git a/cmake/linux/LinuxDeploy.cmake b/cmake/linux/LinuxDeploy.cmake index dd961d535..233449bfe 100644 --- a/cmake/linux/LinuxDeploy.cmake +++ b/cmake/linux/LinuxDeploy.cmake @@ -128,6 +128,10 @@ set(ENV{PATH} "${QTBIN}:$ENV{PATH}") # Promote finding our own libraries first set(ENV{LD_LIBRARY_PATH} "${APP}/usr/lib/${lmms}/:${APP}/usr/lib/${lmms}/optional:$ENV{LD_LIBRARY_PATH}") +# Workaround for finding libs from online installer +# https://github.com/linuxdeploy/linuxdeploy-plugin-qt/issues/193 +set(ENV{LD_LIBRARY_PATH} "${QTBIN}/../lib:$ENV{LD_LIBRARY_PATH}") + # Skip slow searching of copyright files https://github.com/linuxdeploy/linuxdeploy/issues/278 set(ENV{DISABLE_COPYRIGHT_FILES_DEPLOYMENT} 1) diff --git a/cmake/modules/BuildPlugin.cmake b/cmake/modules/BuildPlugin.cmake index 69af41ecb..9f6a89a99 100644 --- a/cmake/modules/BuildPlugin.cmake +++ b/cmake/modules/BuildPlugin.cmake @@ -30,7 +30,7 @@ MACRO(BUILD_PLUGIN PLUGIN_NAME) ADD_GEN_QRC(RCC_OUT "${PLUGIN_NAME}.qrc" PREFIX artwork/${PLUGIN_NAME} ${PLUGIN_EMBEDDED_RESOURCES}) ENDIF(ER_LEN) - QT5_WRAP_CPP(plugin_MOC_out ${PLUGIN_MOCFILES}) + cmake_language(CALL QT${QT_VERSION_MAJOR}_WRAP_CPP plugin_MOC_out ${PLUGIN_MOCFILES}) FOREACH(f ${PLUGIN_SOURCES}) ADD_FILE_DEPENDENCIES(${f} ${RCC_OUT}) @@ -51,7 +51,7 @@ MACRO(BUILD_PLUGIN PLUGIN_NAME) ADD_LIBRARY(${PLUGIN_NAME} ${PLUGIN_LINK} ${PLUGIN_SOURCES} ${plugin_MOC_out} ${RCC_OUT}) - target_link_libraries("${PLUGIN_NAME}" lmms Qt5::Widgets Qt5::Xml) + target_link_libraries("${PLUGIN_NAME}" lmms Qt${QT_VERSION_MAJOR}::Widgets Qt${QT_VERSION_MAJOR}::Xml) INSTALL(TARGETS ${PLUGIN_NAME} LIBRARY DESTINATION "${PLUGIN_DIR}" diff --git a/cmake/modules/GenQrc.cmake b/cmake/modules/GenQrc.cmake index 9614e5ef4..62df5afbb 100644 --- a/cmake/modules/GenQrc.cmake +++ b/cmake/modules/GenQrc.cmake @@ -58,7 +58,7 @@ function(add_gen_qrc RCC_OUT QRC_NAME) # generators. See issue #6177. add_custom_command( OUTPUT "${CPP_FILE}" - COMMAND Qt5::rcc + COMMAND Qt${QT_VERSION_MAJOR}::rcc --name "${RESOURCE_NAME}" --output "${CPP_FILE}" "${QRC_FILE}" diff --git a/data/locale/CMakeLists.txt b/data/locale/CMakeLists.txt index f7f9071e7..8070c77a7 100644 --- a/data/locale/CMakeLists.txt +++ b/data/locale/CMakeLists.txt @@ -1,5 +1,5 @@ -SET(QT_LUPDATE_EXECUTABLE "${Qt5_LUPDATE_EXECUTABLE}") -SET(QT_LRELEASE_EXECUTABLE "${Qt5_LRELEASE_EXECUTABLE}") +SET(QT_LUPDATE_EXECUTABLE "${Qt${QT_VERSION_MAJOR}_LUPDATE_EXECUTABLE}") +SET(QT_LRELEASE_EXECUTABLE "${Qt${QT_VERSION_MAJOR}_LRELEASE_EXECUTABLE}") IF(QT_LUPDATE_EXECUTABLE STREQUAL "") EXECUTE_PROCESS(COMMAND "lupdate" "-help" RESULT_VARIABLE LUPDATE_FALLBACK OUTPUT_QUIET) diff --git a/include/ColorChooser.h b/include/ColorChooser.h index 0e85ea9bb..67b2abc36 100644 --- a/include/ColorChooser.h +++ b/include/ColorChooser.h @@ -55,8 +55,7 @@ protected: //! Forward key events to the parent to prevent stuck notes when the dialog gets focus void keyReleaseEvent(QKeyEvent *event) override { - QKeyEvent ke(*event); - QApplication::sendEvent(parentWidget(), &ke); + QApplication::sendEvent(parentWidget(), event); } private: //! Copy the current QColorDialog palette into an array diff --git a/include/ColorHelper.h b/include/ColorHelper.h index b313d9b46..e09ff1600 100644 --- a/include/ColorHelper.h +++ b/include/ColorHelper.h @@ -35,17 +35,23 @@ class ColorHelper public: static QColor interpolateInRgb(const QColor& a, const QColor& b, float t) { - qreal ar, ag, ab, aa; +#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) + using ColorType = float; +#else + using ColorType = qreal; +#endif + + ColorType ar, ag, ab, aa; a.getRgbF(&ar, &ag, &ab, &aa); - qreal br, bg, bb, ba; + ColorType br, bg, bb, ba; b.getRgbF(&br, &bg, &bb, &ba); - const auto t2 = static_cast(t); - const float interH = std::lerp(ar, br, t2); - const float interS = std::lerp(ag, bg, t2); - const float interV = std::lerp(ab, bb, t2); - const float interA = std::lerp(aa, ba, t2); + const auto t2 = static_cast(t); + const auto interH = std::lerp(ar, br, t2); + const auto interS = std::lerp(ag, bg, t2); + const auto interV = std::lerp(ab, bb, t2); + const auto interA = std::lerp(aa, ba, t2); return QColor::fromRgbF(interH, interS, interV, interA); } diff --git a/include/ControlLayout.h b/include/ControlLayout.h index 29ec5850c..af56af630 100644 --- a/include/ControlLayout.h +++ b/include/ControlLayout.h @@ -96,6 +96,8 @@ class ControlLayout : public QLayout { Q_OBJECT + using ControlLayoutMap = QMap; + public: explicit ControlLayout(QWidget *parent, int margin = -1, int hSpacing = -1, int vSpacing = -1); @@ -124,9 +126,9 @@ private slots: private: int doLayout(const QRect &rect, bool testOnly) const; int smartSpacing(QStyle::PixelMetric pm) const; - QMap::const_iterator pairAt(int index) const; + ControlLayoutMap::const_iterator pairAt(int index) const; - QMultiMap m_itemMap; + ControlLayoutMap m_itemMap; int m_hSpace; int m_vSpace; // relevant dimension is width, as later, heightForWidth() will be called diff --git a/include/DeprecationHelper.h b/include/DeprecationHelper.h index 02a57c3fa..437f8a96b 100644 --- a/include/DeprecationHelper.h +++ b/include/DeprecationHelper.h @@ -29,8 +29,10 @@ #include +#include #include #include +#include #include namespace lmms @@ -58,15 +60,74 @@ inline int horizontalAdvance(const QFontMetrics& metrics, const QString& text) * @param wheelEvent * @return the position of wheelEvent */ -inline QPoint position(QWheelEvent *wheelEvent) +inline QPoint position(const QWheelEvent* wheelEvent) { -#if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)) +#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)) return wheelEvent->position().toPoint(); #else return wheelEvent->pos(); #endif } +/** + * @brief position is a backwards-compatible adapter for + * QDropEvent::position and pos functions. + * @param me + * @return the position of the drop event + */ +inline QPoint position(const QDropEvent* de) +{ +#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) + return de->position().toPoint(); +#else + return de->pos(); +#endif +} + +/** + * @brief position is a backwards-compatible adapter for + * QMouseEvent::position and pos functions. + * @param me + * @return the position of the mouse event + */ +inline QPoint position(const QMouseEvent* me) +{ +#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) + return me->position().toPoint(); +#else + return me->pos(); +#endif +} + +/** + * @brief positionF is a backwards-compatible adapter for + * QMouseEvent::position and localPos functions. + * @param me + * @return the position of the mouse event + */ +inline QPointF positionF(const QMouseEvent* me) +{ +#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) + return me->position(); +#else + return me->localPos(); +#endif +} + +/** + * @brief globalPosition is a backwards-compatible adapter for + * QMouseEvent::globalPosition and globalPos functions. + * @param me + * @return the global position of the mouse event + */ +inline QPoint globalPosition(const QMouseEvent* me) +{ +#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) + return me->globalPosition().toPoint(); +#else + return me->globalPos(); +#endif +} namespace detail { @@ -77,20 +138,69 @@ inline constexpr bool IsKeyOrModifier = std::is_same_v } // namespace detail - /** * @brief Combines Qt key and modifier arguments together, * replacing `A | B` which was deprecated in C++20 * due to the enums being different types. (P1120R0) * @param args Any number of Qt::Key, Qt::Modifier, or Qt::KeyboardModifier - * @return The combination of the given keys/modifiers as an int + * @return The combination of the given keys/modifiers as a QKeySequence */ -template && ...), bool> = true> -constexpr int combine(Args... args) +template requires (detail::IsKeyOrModifier && ...) +inline QKeySequence keySequence(Args... args) { return (0 | ... | static_cast(args)); } +/** + * @brief typeId is a backwards-compatible adapter for + * QVariant::typeId and type functions. + * @param variant + * @return the type id of the variant + */ +inline QMetaType::Type typeId(const QVariant& variant) +{ +#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) + return static_cast(variant.typeId()); +#else + return static_cast(variant.type()); +#endif +} + +//! Backwards-compatible adapter for QDomDocument::setContent +inline bool setContent(QDomDocument& doc, const QByteArray& text, + QString* errorMsg = nullptr, int* errorLine = nullptr, int* errorColumn = nullptr) +{ +#if (QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)) + auto result = doc.setContent(text, QDomDocument::ParseOption::Default); + if (result) { return true; } + if (errorMsg) { *errorMsg = std::move(result.errorMessage); } + if (errorLine) { *errorLine = static_cast(result.errorLine); } + if (errorColumn) { *errorColumn = static_cast(result.errorColumn); } + return false; +#else + return doc.setContent(text, errorMsg, errorLine, errorColumn); +#endif +} + +//! Backwards-compatible adapter for QDomDocument::setContent +inline bool setContent(QDomDocument& doc, QIODevice* dev, bool namespaceProcessing, + QString* errorMsg = nullptr, int* errorLine = nullptr, int* errorColumn = nullptr) +{ +#if (QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)) + const auto options = namespaceProcessing + ? QDomDocument::ParseOption::UseNamespaceProcessing + : QDomDocument::ParseOption::Default; + auto result = doc.setContent(dev, options); + if (result) { return true; } + if (errorMsg) { *errorMsg = std::move(result.errorMessage); } + if (errorLine) { *errorLine = static_cast(result.errorLine); } + if (errorColumn) { *errorColumn = static_cast(result.errorColumn); } + return false; +#else + return doc.setContent(dev, namespaceProcessing, errorMsg, errorLine, errorColumn); +#endif +} + } // namespace lmms #endif // LMMS_DEPRECATIONHELPER_H diff --git a/include/FileRevealer.h b/include/FileRevealer.h index 46c52cd8c..0deba627e 100644 --- a/include/FileRevealer.h +++ b/include/FileRevealer.h @@ -48,6 +48,11 @@ public: */ static void openDir(const QFileInfo item); + static void openDir(const QString& itemPath) + { + openDir(QFileInfo(itemPath)); + } + /** * @brief Checks whether the file manager supports selecting a specific file. * @return True if selection is supported, otherwise false. @@ -60,6 +65,11 @@ public: */ static void reveal(const QFileInfo item); + static void reveal(const QString& itemPath) + { + reveal(QFileInfo(itemPath)); + } + private: static bool s_canSelect; diff --git a/include/FileSearchJob.h b/include/FileSearchJob.h index ac158d900..673c8d871 100644 --- a/include/FileSearchJob.h +++ b/include/FileSearchJob.h @@ -52,6 +52,11 @@ public: //! Stop processing and destroys the object. ~FileSearchJob(); + FileSearchJob(const FileSearchJob&) = delete; + FileSearchJob(FileSearchJob&&) = delete; + FileSearchJob& operator=(const FileSearchJob&) = delete; + FileSearchJob& operator=(FileSearchJob&&) = delete; + //! Commit to searching with the given @p task. //! Cancels any previous search. //! Callers can connect to the provided signals to interact with the search and its progress. @@ -68,7 +73,6 @@ signals: void finished(); private: - Q_DISABLE_MOVE(FileSearchJob) void runSearch(Task task); std::future m_task; std::atomic_flag m_stop = ATOMIC_FLAG_INIT; diff --git a/include/FloatModelEditorBase.h b/include/FloatModelEditorBase.h index 458459c9f..ef32bcc0d 100644 --- a/include/FloatModelEditorBase.h +++ b/include/FloatModelEditorBase.h @@ -81,7 +81,11 @@ protected: void paintEvent(QPaintEvent * me) override; void wheelEvent(QWheelEvent * me) override; - void enterEvent(QEvent *event) override; +#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) + void enterEvent(QEnterEvent*) override; +#else + void enterEvent(QEvent*) override; +#endif void leaveEvent(QEvent *event) override; virtual float getValue(const QPoint & p); diff --git a/include/MainApplication.h b/include/MainApplication.h index 98fcdef20..e26fe677d 100644 --- a/include/MainApplication.h +++ b/include/MainApplication.h @@ -49,10 +49,14 @@ public: MainApplication(int& argc, char** argv); bool event(QEvent* event) override; #ifdef LMMS_BUILD_WIN32 - bool winEventFilter(MSG* msg, long* result); - bool nativeEventFilter(const QByteArray& eventType, void* message, - long* result); -#endif +#if (QT_VERSION < QT_VERSION_CHECK(6,0,0)) + using FilterResult = long; +#else + using FilterResult = qintptr; +#endif // QT6 check + bool win32EventFilter(MSG* msg, FilterResult* result); + bool nativeEventFilter(const QByteArray& eventType, void* message, FilterResult* result); +#endif // LMMS_BUILD_WIN32 inline QString& queuedFile() { return m_queuedFile; diff --git a/include/PluginBrowser.h b/include/PluginBrowser.h index 31cfe1dc3..48386790e 100644 --- a/include/PluginBrowser.h +++ b/include/PluginBrowser.h @@ -65,7 +65,11 @@ public: void openInNewInstrumentTrack(QString value); protected: - void enterEvent( QEvent * _e ) override; +#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) + void enterEvent(QEnterEvent* event) override; +#else + void enterEvent(QEvent* event) override; +#endif void leaveEvent( QEvent * _e ) override; void mousePressEvent( QMouseEvent * _me ) override; void paintEvent( QPaintEvent * _pe ) override; diff --git a/include/TabWidget.h b/include/TabWidget.h index 52e59d577..3ad7be575 100644 --- a/include/TabWidget.h +++ b/include/TabWidget.h @@ -48,7 +48,7 @@ public: void setActiveTab(int idx); - int findTabAtPos(const QPoint* pos); + int findTabAtPos(const QPoint& pos); inline int activeTab() const { diff --git a/include/base64.h b/include/base64.h index 42066d564..3b8100e74 100644 --- a/include/base64.h +++ b/include/base64.h @@ -27,6 +27,7 @@ #define LMMS_BASE64_H #include +#include #include #include @@ -47,9 +48,10 @@ namespace lmms::base64 *_data = new T[*_size / sizeof(T)]; memcpy( *_data, data.constData(), *_size ); } + // for compatibility-code only - QVariant decode( const QString & _b64, - QVariant::Type _force_type = QVariant::Invalid ); + QVariant decode(const QString& b64, + QMetaType::Type forceType = QMetaType::UnknownType); } // namespace lmms::base64 diff --git a/include/embed.h b/include/embed.h index cbe4509ee..0bcc83d5a 100644 --- a/include/embed.h +++ b/include/embed.h @@ -58,16 +58,12 @@ auto LMMS_EXPORT getText(std::string_view name) -> QString; * @param pixmap The pixmap to get the size of. * @return The device-independent size of the pixmap. */ -#if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0) -[[deprecated("Use QPixmap::deviceIndependentSize() instead; See " - "https://doc.qt.io/qt-6/qpixmap.html#deviceIndependentSize")]] -#endif -inline auto logicalSize(const QPixmap &pixmap) noexcept +inline auto logicalSize(const QPixmap& pixmap) noexcept { #if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0) return pixmap.deviceIndependentSize().toSize(); #else - return pixmap.isNull() ? QSize() : pixmap.size() / pixmap.devicePixelRatio(); + return pixmap.isNull() ? QSize(0, 0) : pixmap.size() / pixmap.devicePixelRatio(); #endif } diff --git a/plugins/AudioFileProcessor/AudioFileProcessorWaveView.cpp b/plugins/AudioFileProcessor/AudioFileProcessorWaveView.cpp index f120fbf25..0ae261f00 100644 --- a/plugins/AudioFileProcessor/AudioFileProcessorWaveView.cpp +++ b/plugins/AudioFileProcessor/AudioFileProcessorWaveView.cpp @@ -26,9 +26,11 @@ #include "Sample.h" #include "ConfigManager.h" +#include "DeprecationHelper.h" #include "SampleThumbnail.h" #include "FontHelper.h" + #include #include @@ -114,10 +116,12 @@ void AudioFileProcessorWaveView::leaveEvent(QEvent * e) void AudioFileProcessorWaveView::mousePressEvent(QMouseEvent * me) { - m_isDragging = true; - m_draggingLastPoint = me->pos(); + const auto pos = position(me); - const int x = me->x(); + m_isDragging = true; + m_draggingLastPoint = pos; + + const int x = pos.x(); const int start_dist = qAbs(m_startFrameX - x); const int end_dist = qAbs(m_endFrameX - x); @@ -155,7 +159,9 @@ void AudioFileProcessorWaveView::mouseMoveEvent(QMouseEvent * me) return; } - const int step = me->x() - m_draggingLastPoint.x(); + const auto pos = position(me); + + const int step = pos.x() - m_draggingLastPoint.x(); switch(m_draggingType) { case DraggingType::SampleStart: @@ -171,12 +177,12 @@ void AudioFileProcessorWaveView::mouseMoveEvent(QMouseEvent * me) slide(step); break; case DraggingType::ZoomWave: - zoom(me->y() < m_draggingLastPoint.y()); + zoom(pos.y() < m_draggingLastPoint.y()); break; case DraggingType::Wave: default: - if (qAbs(me->y() - m_draggingLastPoint.y()) - < 2 * qAbs(me->x() - m_draggingLastPoint.x())) + if (qAbs(pos.y() - m_draggingLastPoint.y()) + < 2 * qAbs(pos.x() - m_draggingLastPoint.x())) { m_draggingType = DraggingType::SlideWave; } @@ -186,7 +192,7 @@ void AudioFileProcessorWaveView::mouseMoveEvent(QMouseEvent * me) } } - m_draggingLastPoint = me->pos(); + m_draggingLastPoint = pos; update(); } @@ -483,20 +489,30 @@ void AudioFileProcessorWaveView::reverse() m_reversed = ! m_reversed; } -void AudioFileProcessorWaveView::updateCursor(QMouseEvent * me) +void AudioFileProcessorWaveView::updateCursor(const QMouseEvent* me) { bool const waveIsDragged = m_isDragging && (m_draggingType == DraggingType::Wave); - bool const pointerCloseToStartEndOrLoop = (me != nullptr) && - (isCloseTo(me->x(), m_startFrameX) || - isCloseTo(me->x(), m_endFrameX) || - isCloseTo(me->x(), m_loopFrameX)); - if (!m_isDragging && pointerCloseToStartEndOrLoop) + if (!m_isDragging && pointerCloseToStartEndOrLoop(me)) + { setCursor(Qt::SizeHorCursor); + } else if (waveIsDragged) + { setCursor(Qt::ClosedHandCursor); + } else + { setCursor(Qt::OpenHandCursor); + } +} + +bool AudioFileProcessorWaveView::pointerCloseToStartEndOrLoop(const QMouseEvent* me) const +{ + if (!me) { return false; } + + const QPoint pos = position(me); + return isCloseTo(pos.x(), m_startFrameX) || isCloseTo(pos.x(), m_endFrameX) || isCloseTo(pos.x(), m_loopFrameX); } void AudioFileProcessorWaveView::configureKnobRelationsAndWaveViews() diff --git a/plugins/AudioFileProcessor/AudioFileProcessorWaveView.h b/plugins/AudioFileProcessor/AudioFileProcessorWaveView.h index ac36bf9ec..41d2710b6 100644 --- a/plugins/AudioFileProcessor/AudioFileProcessorWaveView.h +++ b/plugins/AudioFileProcessor/AudioFileProcessorWaveView.h @@ -169,7 +169,8 @@ private: void updateGraph(); void reverse(); - void updateCursor(QMouseEvent* me = nullptr); + void updateCursor(const QMouseEvent* me = nullptr); + bool pointerCloseToStartEndOrLoop(const QMouseEvent* me) const; void configureKnobRelationsAndWaveViews(); diff --git a/plugins/Delay/DelayControlsDialog.cpp b/plugins/Delay/DelayControlsDialog.cpp index 6d3e4a3ec..fc15b6b49 100644 --- a/plugins/Delay/DelayControlsDialog.cpp +++ b/plugins/Delay/DelayControlsDialog.cpp @@ -25,6 +25,7 @@ #include "AutomatableModel.h" #include "DelayControlsDialog.h" #include "DelayControls.h" +#include "DeprecationHelper.h" #include "embed.h" #include "TempoSyncKnob.h" #include "../Eq/EqFader.h" @@ -135,18 +136,20 @@ void XyPad::mouseReleaseEvent(QMouseEvent *event) void XyPad::mouseMoveEvent(QMouseEvent *event) { - if( m_acceptInput && (event->x() >= 0) && ( event->x() < width() ) - && ( event->y() >= 0) && ( event->y() < height() ) ) + const auto pos = position(event); + + if (m_acceptInput && (pos.x() >= 0) && (pos.x() < width()) + && (pos.y() >= 0) && (pos.y() < height())) { //set xmodel float xRange = m_xModel->maxValue() - m_xModel->minValue(); float xInc = xRange / width(); - m_xModel->setValue( m_xModel->minValue() + ( event->x() * xInc ) ); + m_xModel->setValue(m_xModel->minValue() + (pos.x() * xInc)); //set ymodel float yRange = m_yModel->maxValue() - m_yModel->minValue(); float yInc = yRange / height(); - m_yModel->setValue( m_yModel->minValue() + ( event->y() * yInc ) ); + m_yModel->setValue(m_yModel->minValue() + (pos.y() * yInc)); } } diff --git a/plugins/LadspaEffect/LadspaMatrixControlDialog.cpp b/plugins/LadspaEffect/LadspaMatrixControlDialog.cpp index c05481c6d..f8cfbe3b3 100644 --- a/plugins/LadspaEffect/LadspaMatrixControlDialog.cpp +++ b/plugins/LadspaEffect/LadspaMatrixControlDialog.cpp @@ -178,7 +178,7 @@ QWidget * LadspaMatrixControlDialog::createMatrixWidget() { QWidget *widget = new QWidget(this); QGridLayout *gridLayout = new QGridLayout(widget); - gridLayout->setMargin(0); + gridLayout->setContentsMargins(0, 0, 0, 0); widget->setLayout(gridLayout); arrangeControls(widget, gridLayout); diff --git a/plugins/OpulenZ/OpulenZ.cpp b/plugins/OpulenZ/OpulenZ.cpp index 451cf3707..c91680ee9 100644 --- a/plugins/OpulenZ/OpulenZ.cpp +++ b/plugins/OpulenZ/OpulenZ.cpp @@ -590,7 +590,7 @@ void OpulenzInstrument::loadFile( const QString& file ) { return; } if( sbidata.size() != 52 ) { - printf("SBI size error: expected 52, got %d\n",sbidata.size() ); + printf("SBI size error: expected 52, got %d\n", static_cast(sbidata.size())); } // Minimum size of SBI if we ignore "reserved" bytes at end diff --git a/plugins/SlicerT/SlicerTWaveform.cpp b/plugins/SlicerT/SlicerTWaveform.cpp index 899aabf5b..4e21ffa01 100644 --- a/plugins/SlicerT/SlicerTWaveform.cpp +++ b/plugins/SlicerT/SlicerTWaveform.cpp @@ -29,6 +29,7 @@ #include #include +#include "DeprecationHelper.h" #include "SampleThumbnail.h" #include "SlicerT.h" #include "SlicerTView.h" @@ -297,13 +298,15 @@ void SlicerTWaveform::updateUI() // updates the closest object and changes the cursor respectivly void SlicerTWaveform::updateClosest(QMouseEvent* me) { - float normalizedClickSeeker = static_cast(me->x() - s_seekerHorMargin) / m_seekerWidth; - float normalizedClickEditor = static_cast(me->x()) / m_editorWidth; + const auto pos = position(me); + + float normalizedClickSeeker = static_cast(pos.x() - s_seekerHorMargin) / m_seekerWidth; + float normalizedClickEditor = static_cast(pos.x()) / m_editorWidth; m_closestObject = UIObjects::Nothing; m_closestSlice = -1; - if (me->y() < m_seekerHeight) + if (pos.y() < m_seekerHeight) { if (std::abs(normalizedClickSeeker - m_seekerStart) < s_distanceForClick) { @@ -358,6 +361,8 @@ void SlicerTWaveform::updateCursor() // handles deletion, reset and middles seeker void SlicerTWaveform::mousePressEvent(QMouseEvent* me) { + const auto pos = position(me); + switch (me->button()) { case Qt::MouseButton::MiddleButton: @@ -369,7 +374,7 @@ void SlicerTWaveform::mousePressEvent(QMouseEvent* me) case Qt::MouseButton::LeftButton: if (m_slicerTParent->m_originalSample.sampleSize() <= 1) { static_cast(parent())->openFiles(); } // update seeker middle for correct movement - m_seekerMiddle = static_cast(me->x() - s_seekerHorMargin) / m_seekerWidth; + m_seekerMiddle = static_cast(pos.x() - s_seekerHorMargin) / m_seekerWidth; break; case Qt::MouseButton::RightButton: if (m_slicerTParent->m_slicePoints.size() > 2 && m_closestObject == UIObjects::SlicePoint) @@ -400,8 +405,10 @@ void SlicerTWaveform::mouseMoveEvent(QMouseEvent* me) return; } - float normalizedClickSeeker = static_cast(me->x() - s_seekerHorMargin) / m_seekerWidth; - float normalizedClickEditor = static_cast(me->x()) / m_editorWidth; + const auto pos = position(me); + + float normalizedClickSeeker = static_cast(pos.x() - s_seekerHorMargin) / m_seekerWidth; + float normalizedClickEditor = static_cast(pos.x()) / m_editorWidth; float distStart = m_seekerStart - m_seekerMiddle; float distEnd = m_seekerEnd - m_seekerMiddle; @@ -449,9 +456,11 @@ void SlicerTWaveform::mouseMoveEvent(QMouseEvent* me) void SlicerTWaveform::mouseDoubleClickEvent(QMouseEvent* me) { - if (me->button() != Qt::MouseButton::LeftButton || me->y() < m_seekerHeight) { return; } + const auto pos = position(me); - float normalizedClickEditor = static_cast(me->x()) / m_editorWidth; + if (me->button() != Qt::MouseButton::LeftButton || pos.y() < m_seekerHeight) { return; } + + float normalizedClickEditor = static_cast(pos.x()) / m_editorWidth; float startFrame = m_seekerStart; float endFrame = m_seekerEnd; float slicePosition = startFrame + normalizedClickEditor * (endFrame - startFrame); diff --git a/plugins/SpectrumAnalyzer/SaSpectrumView.cpp b/plugins/SpectrumAnalyzer/SaSpectrumView.cpp index dd97d3d87..669b242ac 100644 --- a/plugins/SpectrumAnalyzer/SaSpectrumView.cpp +++ b/plugins/SpectrumAnalyzer/SaSpectrumView.cpp @@ -33,6 +33,7 @@ #include #include +#include "DeprecationHelper.h" #include "fft_helpers.h" #include "GuiApplication.h" #include "MainWindow.h" @@ -819,18 +820,14 @@ void SaSpectrumView::periodicUpdate() // Handle mouse input: set new cursor position. -// For some reason (a bug?), localPos() only returns integers. As a workaround -// the fractional part is taken from windowPos() (which works correctly). -void SaSpectrumView::mouseMoveEvent(QMouseEvent *event) +void SaSpectrumView::mouseMoveEvent(QMouseEvent* event) { - m_cursor = QPointF( event->localPos().x() - (event->windowPos().x() - (long)event->windowPos().x()), - event->localPos().y() - (event->windowPos().y() - (long)event->windowPos().y())); + m_cursor = positionF(event); } -void SaSpectrumView::mousePressEvent(QMouseEvent *event) +void SaSpectrumView::mousePressEvent(QMouseEvent* event) { - m_cursor = QPointF( event->localPos().x() - (event->windowPos().x() - (long)event->windowPos().x()), - event->localPos().y() - (event->windowPos().y() - (long)event->windowPos().y())); + m_cursor = positionF(event); } diff --git a/plugins/SpectrumAnalyzer/SaWaterfallView.cpp b/plugins/SpectrumAnalyzer/SaWaterfallView.cpp index b3e57d7c0..c0f12c99a 100644 --- a/plugins/SpectrumAnalyzer/SaWaterfallView.cpp +++ b/plugins/SpectrumAnalyzer/SaWaterfallView.cpp @@ -33,6 +33,7 @@ #include #include +#include "DeprecationHelper.h" #include "EffectControlDialog.h" #include "GuiApplication.h" #include "MainWindow.h" @@ -324,18 +325,14 @@ void SaWaterfallView::drawCursor(QPainter &painter) // Handle mouse input: set new cursor position. -// For some reason (a bug?), localPos() only returns integers. As a workaround -// the fractional part is taken from windowPos() (which works correctly). -void SaWaterfallView::mouseMoveEvent(QMouseEvent *event) +void SaWaterfallView::mouseMoveEvent(QMouseEvent* event) { - m_cursor = QPointF( event->localPos().x() - (event->windowPos().x() - (long)event->windowPos().x()), - event->localPos().y() - (event->windowPos().y() - (long)event->windowPos().y())); + m_cursor = positionF(event); } -void SaWaterfallView::mousePressEvent(QMouseEvent *event) +void SaWaterfallView::mousePressEvent(QMouseEvent* event) { - m_cursor = QPointF( event->localPos().x() - (event->windowPos().x() - (long)event->windowPos().x()), - event->localPos().y() - (event->windowPos().y() - (long)event->windowPos().y())); + m_cursor = positionF(event); } diff --git a/plugins/VstBase/VstPlugin.cpp b/plugins/VstBase/VstPlugin.cpp index f26245728..c224d0d5f 100644 --- a/plugins/VstBase/VstPlugin.cpp +++ b/plugins/VstBase/VstPlugin.cpp @@ -34,7 +34,7 @@ #include #include -#ifdef LMMS_BUILD_LINUX +#if defined(LMMS_BUILD_LINUX) && (QT_VERSION < QT_VERSION_CHECK(6,0,0)) # include # include #endif @@ -415,7 +415,7 @@ bool VstPlugin::processMessage( const message & _m ) (LONG_PTR) gui::getGUI()->mainWindow()->winId() ); #endif -#ifdef LMMS_BUILD_LINUX +#if defined(LMMS_BUILD_LINUX) && (QT_VERSION < QT_VERSION_CHECK(6,0,0)) XSetTransientForHint( QX11Info::display(), m_pluginWindowID, gui::getGUI()->mainWindow()->winId() ); @@ -772,7 +772,7 @@ void VstPlugin::createUI( QWidget * parent ) } else #endif -#ifdef LMMS_BUILD_LINUX +#if defined(LMMS_BUILD_LINUX) && (QT_VERSION < QT_VERSION_CHECK(6,0,0)) if (m_embedMethod == "xembed" ) { if (parent) diff --git a/plugins/VstBase/vstbase/CMakeLists.txt b/plugins/VstBase/vstbase/CMakeLists.txt index 4e8cbd97c..3a69d20fc 100644 --- a/plugins/VstBase/vstbase/CMakeLists.txt +++ b/plugins/VstBase/vstbase/CMakeLists.txt @@ -15,6 +15,6 @@ TARGET_INCLUDE_DIRECTORIES(vstbase PUBLIC ../ ) -IF(LMMS_BUILD_LINUX) +IF(LMMS_BUILD_LINUX AND NOT WANT_QT6) TARGET_LINK_LIBRARIES(vstbase qx11embedcontainer) ENDIF() diff --git a/plugins/ZynAddSubFx/CMakeLists.txt b/plugins/ZynAddSubFx/CMakeLists.txt index cbd7326fe..4bc5badd4 100644 --- a/plugins/ZynAddSubFx/CMakeLists.txt +++ b/plugins/ZynAddSubFx/CMakeLists.txt @@ -23,8 +23,13 @@ if(NOT MSVC AND (LMMS_HOST_X86 OR LMMS_HOST_X86_64)) ADD_DEFINITIONS(-DASM_F2I_YES) endif() -# build ZynAddSubFX with full optimizations -if(NOT MSVC) +if(MSVC) + # enable updated C++ language standards, disable certain permissive behavior + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Zc:__cplusplus /permissive-") + # workaround _WIN32 vs WIN32 differences + add_compile_definitions(WIN32) +else() + # build ZynAddSubFX with full optimizations, treat nonconformant code as warnings set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2 -fpermissive") endif() @@ -126,8 +131,8 @@ target_static_libraries(ZynAddSubFxCore PUBLIC target_link_libraries(ZynAddSubFxCore INTERFACE ${FFTW3F_LIBRARIES} ${QT_LIBRARIES} - Qt5::Widgets - Qt5::Xml + Qt${QT_VERSION_MAJOR}::Widgets + Qt${QT_VERSION_MAJOR}::Xml Threads::Threads ZLIB::ZLIB ) @@ -192,7 +197,7 @@ if(LMMS_HAVE_LIBRT) endif() # Support qt_version_tag in Qt 5.6 -TARGET_LINK_LIBRARIES(RemoteZynAddSubFx Qt5::Core) +TARGET_LINK_LIBRARIES(RemoteZynAddSubFx Qt${QT_VERSION_MAJOR}::Core) # link Qt libraries when on win32 IF(LMMS_BUILD_WIN32) diff --git a/src/3rdparty/CMakeLists.txt b/src/3rdparty/CMakeLists.txt index a959e3c7b..839a76fe4 100644 --- a/src/3rdparty/CMakeLists.txt +++ b/src/3rdparty/CMakeLists.txt @@ -1,6 +1,6 @@ set_directory_properties(PROPERTIES SYSTEM TRUE) -if(LMMS_BUILD_LINUX AND LMMS_HAVE_VST) +if(LMMS_BUILD_LINUX AND LMMS_HAVE_VST AND NOT WANT_QT6) set(BUILD_SHARED_LIBS OFF) add_subdirectory(qt5-x11embed) ENDIF() diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 8bdbbeaf5..eb86a847a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -35,6 +35,12 @@ ADD_SUBDIRECTORY(tracks) LIST(APPEND LMMS_SRCS ${LMMS_COMMON_SRCS}) +IF(WANT_QT6) + QT6_WRAP_UI(LMMS_UI_OUT ${LMMS_UIS}) +ELSE() + QT5_WRAP_UI(LMMS_UI_OUT ${LMMS_UIS}) +ENDIF() + INCLUDE_DIRECTORIES( "${CMAKE_CURRENT_BINARY_DIR}" "${CMAKE_BINARY_DIR}" @@ -114,6 +120,11 @@ TARGET_INCLUDE_DIRECTORIES(lmms ) target_static_libraries(lmms PUBLIC lmmsobjs) +# Enable updated C++ language standards +IF(MSVC) + TARGET_COMPILE_OPTIONS(lmmsobjs PUBLIC "/Zc:__cplusplus" "/permissive-") +ENDIF() + # CMake doesn't define target_EXPORTS for OBJECT libraries. # See the documentation of DEFINE_SYMBOL for details. # Also add LMMS_STATIC_DEFINE for targets linking against it. diff --git a/src/core/AutomationClip.cpp b/src/core/AutomationClip.cpp index 40b329c38..f766565bc 100644 --- a/src/core/AutomationClip.cpp +++ b/src/core/AutomationClip.cpp @@ -186,7 +186,7 @@ TimePos AutomationClip::timeMapLength() const if (m_timeMap.isEmpty()) { return one_bar; } timeMap::const_iterator it = m_timeMap.end(); - auto last_tick = static_cast(POS(it - 1)); + auto last_tick = static_cast(POS(std::prev(it))); // if last_tick is 0 (single item at tick 0) // return length as a whole bar to prevent disappearing Clip if (last_tick == 0) { return one_bar; } @@ -582,13 +582,16 @@ float AutomationClip::valueAt( const TimePos & _time ) const { return 0; } + + const auto pv = std::prev(v); + if( v == m_timeMap.end() ) { // When the time is after the last node, we want the outValue of it - return OUTVAL(v - 1); + return OUTVAL(pv); } - return valueAt(v - 1, _time - POS(v - 1)); + return valueAt(pv, _time - POS(pv)); } @@ -610,9 +613,10 @@ float AutomationClip::valueAt( timeMap::const_iterator v, int offset ) const } else if( m_progressionType == ProgressionType::Linear ) { + auto const nv = std::next(v); float slope = - (INVAL(v + 1) - OUTVAL(v)) - / (POS(v + 1) - POS(v)); + (INVAL(nv) - OUTVAL(v)) + / (POS(nv) - POS(v)); return OUTVAL(v) + offset * slope; } @@ -626,15 +630,17 @@ float AutomationClip::valueAt( timeMap::const_iterator v, int offset ) const // value: y. To make this work we map the values of x that this // segment spans to values of t for t = 0.0 -> 1.0 and scale the // tangents _m1 and _m2 - int numValues = (POS(v + 1) - POS(v)); + auto const nv = std::next(v); + + int numValues = (POS(nv) - POS(v)); float t = (float) offset / (float) numValues; float m1 = OUTTAN(v) * numValues * m_tension; - float m2 = INTAN(v + 1) * numValues * m_tension; + float m2 = INTAN(nv) * numValues * m_tension; auto t2 = t * t, t3 = t2 * t; return (2 * t3 - 3 * t2 + 1) * OUTVAL(v) + (t3 - 2 * t2 + t) * m1 - + (-2 * t3 + 3 * t2) * INVAL(v + 1) + + (-2 * t3 + 3 * t2) * INVAL(nv) + (t3 - t2) * m2; } } @@ -647,12 +653,14 @@ float *AutomationClip::valuesAfter( const TimePos & _time ) const QMutexLocker m(&m_clipMutex); timeMap::const_iterator v = m_timeMap.lowerBound(_time); - if( v == m_timeMap.end() || (v+1) == m_timeMap.end() ) + auto const nv = std::next(v); + + if (v == m_timeMap.end() || nv == m_timeMap.end()) { return nullptr; } - int numValues = POS(v + 1) - POS(v); + int numValues = POS(nv) - POS(v); auto ret = new float[numValues]; for( int i = 0; i < numValues; i++ ) @@ -1156,7 +1164,9 @@ void AutomationClip::generateTangents(timeMap::iterator it, int numToGenerate) continue; } - if (it + 1 == m_timeMap.end()) + auto const nit = std::next(it); + + if (nit == m_timeMap.end()) { // Previously, the last value's tangent was always set to 0. That logic was kept for both tangents // of the last node @@ -1167,7 +1177,7 @@ void AutomationClip::generateTangents(timeMap::iterator it, int numToGenerate) { // On the first node there's no curve behind it, so we will only calculate the outTangent // and inTangent will be set to 0. - float tangent = (INVAL(it + 1) - OUTVAL(it)) / (POS(it + 1) - POS(it)); + float tangent = (INVAL(nit) - OUTVAL(it)) / (POS(nit) - POS(it)); it.value().setInTangent(0); it.value().setOutTangent(tangent); } @@ -1180,9 +1190,12 @@ void AutomationClip::generateTangents(timeMap::iterator it, int numToGenerate) // TODO: This behavior means that a very small difference between the inValue and outValue can // result in a big change in the curve. In the future, allowing the user to manually adjust // the tangents would be better. + + auto const pit = std::prev(it); + if (OFFSET(it) == 0) { - float inTangent = (INVAL(it + 1) - OUTVAL(it - 1)) / (POS(it + 1) - POS(it - 1)); + float inTangent = (INVAL(nit) - OUTVAL(pit)) / (POS(nit) - POS(pit)); it.value().setInTangent(inTangent); // inTangent == outTangent in this case it.value().setOutTangent(inTangent); @@ -1190,9 +1203,9 @@ void AutomationClip::generateTangents(timeMap::iterator it, int numToGenerate) else { // Calculate the left side of the curve - float inTangent = (INVAL(it) - OUTVAL(it - 1)) / (POS(it) - POS(it - 1)); + float inTangent = (INVAL(it) - OUTVAL(pit)) / (POS(it) - POS(pit)); // Calculate the right side of the curve - float outTangent = (INVAL(it + 1) - OUTVAL(it)) / (POS(it + 1) - POS(it)); + float outTangent = (INVAL(nit) - OUTVAL(it)) / (POS(nit) - POS(it)); it.value().setInTangent(inTangent); it.value().setOutTangent(outTangent); } diff --git a/src/core/ConfigManager.cpp b/src/core/ConfigManager.cpp index bdf4d6c32..66f01b144 100644 --- a/src/core/ConfigManager.cpp +++ b/src/core/ConfigManager.cpp @@ -24,7 +24,6 @@ #include "ConfigManager.h" -#include #include #include #include @@ -32,8 +31,10 @@ #include #include +#include "DeprecationHelper.h" #include "GuiApplication.h" #include "MainWindow.h" +#include "PathUtil.h" #include "ProjectVersion.h" #include "lmmsversion.h" @@ -202,7 +203,7 @@ QStringList ConfigManager::availableVstEmbedMethods() #ifdef LMMS_BUILD_WIN32 methods.append("win32"); #endif -#ifdef LMMS_BUILD_LINUX +#if defined(LMMS_BUILD_LINUX) && (QT_VERSION < QT_VERSION_CHECK(6,0,0)) if (static_cast(QApplication::instance())-> platformName() == "xcb") { @@ -429,7 +430,7 @@ void ConfigManager::loadConfigFile(const QString & configFile) { QString errorString; int errorLine, errorCol; - if(dom_tree.setContent(&cfg_file, false, &errorString, &errorLine, &errorCol)) + if (lmms::setContent(dom_tree, &cfg_file, false, &errorString, &errorLine, &errorCol)) { // get the head information from the DOM QDomElement root = dom_tree.documentElement(); diff --git a/src/core/DataFile.cpp b/src/core/DataFile.cpp index 04a3574d7..48d7613a0 100644 --- a/src/core/DataFile.cpp +++ b/src/core/DataFile.cpp @@ -40,6 +40,7 @@ #include "base64.h" #include "ConfigManager.h" +#include "DeprecationHelper.h" #include "Effect.h" #include "embed.h" #include "GuiApplication.h" @@ -1027,19 +1028,19 @@ void DataFile::upgrade_0_4_0_beta1() if( !k.isEmpty() ) { const QList l = - base64::decode( k, QVariant::List ).toList(); + base64::decode(k, QMetaType::QVariantList).toList(); if( !l.isEmpty() ) { QString name = l[0].toString(); QVariant u = l[1]; EffectKey::AttributeMap m; // VST-effect? - if( u.type() == QVariant::String ) + if (typeId(u) == QMetaType::QString) { m["file"] = u.toString(); } // LADSPA-effect? - else if( u.type() == QVariant::StringList ) + else if (typeId(u) == QMetaType::QStringList) { const QStringList sl = u.toStringList(); m["plugin"] = sl.value( 0 ); @@ -2124,13 +2125,13 @@ void DataFile::loadData( const QByteArray & _data, const QString & _sourceFile ) { QString errorMsg; int line = -1, col = -1; - if( !setContent( _data, &errorMsg, &line, &col ) ) + if (!lmms::setContent(*this, _data, &errorMsg, &line, &col)) { // parsing failed? then try to uncompress data QByteArray uncompressed = qUncompress( _data ); if( !uncompressed.isEmpty() ) { - if( setContent( uncompressed, &errorMsg, &line, &col ) ) + if (lmms::setContent(*this, uncompressed, &errorMsg, &line, &col)) { line = col = -1; } diff --git a/src/core/InstrumentFunctions.cpp b/src/core/InstrumentFunctions.cpp index f517a0942..4ed3751fe 100644 --- a/src/core/InstrumentFunctions.cpp +++ b/src/core/InstrumentFunctions.cpp @@ -489,9 +489,9 @@ void InstrumentFunctionArpeggio::processNote( NotePlayHandle * _n ) } else { - const auto octaveDiv = std::div(cur_arp_idx, total_chord_size); + const auto octaveDiv = std::div(cur_arp_idx, static_cast(total_chord_size)); const int octave = octaveDiv.quot; - const auto arpDiv = std::div(octaveDiv.rem, cnphv.size()); + const auto arpDiv = std::div(octaveDiv.rem, static_cast(cnphv.size())); const int arpIndex = arpDiv.rem; const int chordIndex = arpDiv.quot; sub_note_key = cnphv[arpIndex]->key() diff --git a/src/core/base64.cpp b/src/core/base64.cpp index b1c26b610..b066665dd 100644 --- a/src/core/base64.cpp +++ b/src/core/base64.cpp @@ -28,22 +28,24 @@ #include #include +#include "DeprecationHelper.h" + namespace lmms::base64 { -QVariant decode( const QString & _b64, QVariant::Type _force_type ) +QVariant decode(const QString& b64, QMetaType::Type forceType) { char * dst = nullptr; int dsize = 0; - base64::decode( _b64, &dst, &dsize ); + base64::decode(b64, &dst, &dsize); QByteArray ba( dst, dsize ); QBuffer buf( &ba ); buf.open( QBuffer::ReadOnly ); QDataStream in( &buf ); QVariant ret; in >> ret; - if( _force_type != QVariant::Invalid && ret.type() != _force_type ) + if (forceType != QMetaType::UnknownType && typeId(ret) != forceType) { buf.reset(); in.setVersion( QDataStream::Qt_3_3 ); diff --git a/src/core/main.cpp b/src/core/main.cpp index 3f83339b0..a63e6633c 100644 --- a/src/core/main.cpp +++ b/src/core/main.cpp @@ -360,7 +360,12 @@ int main( int argc, char * * argv ) return EXIT_FAILURE; } #endif + +#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) + // High-DPI scaling is always enabled in Qt >= 6.0 QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); +#endif + QCoreApplication * app = coreOnly ? new QCoreApplication( argc, argv ) : new gui::MainApplication(argc, argv); diff --git a/src/core/midi/MidiWinMM.cpp b/src/core/midi/MidiWinMM.cpp index 811e0842c..8917fa51e 100644 --- a/src/core/midi/MidiWinMM.cpp +++ b/src/core/midi/MidiWinMM.cpp @@ -275,15 +275,15 @@ void MidiWinMM::openDevices() m_inputDevices.clear(); for( unsigned int i = 0; i < midiInGetNumDevs(); ++i ) { - MIDIINCAPS c; - midiInGetDevCaps( i, &c, sizeof( c ) ); + MIDIINCAPSW c; + midiInGetDevCapsW(i, &c, sizeof(c)); HMIDIIN hm = 0; MMRESULT res = midiInOpen( &hm, i, (DWORD_PTR) &inputCallback, (DWORD_PTR) this, CALLBACK_FUNCTION ); if( res == MMSYSERR_NOERROR ) { - m_inputDevices[hm] = qstrdup( c.szPname ); + m_inputDevices[hm] = QString::fromWCharArray(c.szPname); midiInStart( hm ); } } @@ -291,13 +291,13 @@ void MidiWinMM::openDevices() m_outputDevices.clear(); for( unsigned int i = 0; i < midiOutGetNumDevs(); ++i ) { - MIDIOUTCAPS c; - midiOutGetDevCaps( i, &c, sizeof( c ) ); + MIDIOUTCAPSW c; + midiOutGetDevCapsW(i, &c, sizeof(c)); HMIDIOUT hm = 0; MMRESULT res = midiOutOpen( &hm, i, 0, 0, CALLBACK_NULL ); if( res == MMSYSERR_NOERROR ) { - m_outputDevices[hm] = qstrdup( c.szPname ); + m_outputDevices[hm] = QString::fromWCharArray(c.szPname); } } } diff --git a/src/gui/ControlLayout.cpp b/src/gui/ControlLayout.cpp index 75133c8e3..ed2855ecf 100644 --- a/src/gui/ControlLayout.cpp +++ b/src/gui/ControlLayout.cpp @@ -141,7 +141,7 @@ int ControlLayout::count() const return m_itemMap.size() - 1; } -QMap::const_iterator +ControlLayout::ControlLayoutMap::const_iterator ControlLayout::pairAt(int index) const { if (index < 0) { return m_itemMap.cend(); } @@ -151,7 +151,7 @@ ControlLayout::pairAt(int index) const return item->widget()->objectName() == s_searchBarName; }; - QMap::const_iterator itr = m_itemMap.cbegin(); + auto itr = m_itemMap.cbegin(); for (; itr != m_itemMap.cend() && (index > 0 || skip(itr.value())); ++itr) { if(!skip(itr.value())) { index--; } @@ -242,10 +242,8 @@ int ControlLayout::doLayout(const QRect &rect, bool testOnly) const const QString filterText = m_searchBar->text(); bool first = true; - QMapIterator itr(m_itemMap); - while (itr.hasNext()) + for (auto itr = m_itemMap.cbegin(); itr != m_itemMap.cend(); ++itr) { - itr.next(); QLayoutItem* item = itr.value(); QWidget *wid = item->widget(); if (wid) diff --git a/src/gui/ControllerRackView.cpp b/src/gui/ControllerRackView.cpp index 1cc80c08f..a3c504323 100644 --- a/src/gui/ControllerRackView.cpp +++ b/src/gui/ControllerRackView.cpp @@ -169,13 +169,13 @@ void ControllerRackView::addController(Controller* controller) connect(controllerView, &ControllerView::removedController, this, &ControllerRackView::deleteController, Qt::QueuedConnection); auto moveUpAction = new QAction(controllerView); - moveUpAction->setShortcut(combine(Qt::Key_Up, Qt::AltModifier)); + moveUpAction->setShortcut(keySequence(Qt::Key_Up, Qt::AltModifier)); moveUpAction->setShortcutContext(Qt::WidgetShortcut); connect(moveUpAction, &QAction::triggered, controllerView, &ControllerView::moveUp); controllerView->addAction(moveUpAction); auto moveDownAction = new QAction(controllerView); - moveDownAction->setShortcut(combine(Qt::Key_Down, Qt::AltModifier)); + moveDownAction->setShortcut(keySequence(Qt::Key_Down, Qt::AltModifier)); moveDownAction->setShortcutContext(Qt::WidgetShortcut); connect(moveDownAction, &QAction::triggered, controllerView, &ControllerView::moveDown); controllerView->addAction(moveDownAction); diff --git a/src/gui/EffectRackView.cpp b/src/gui/EffectRackView.cpp index c6d62b334..f8f0069da 100644 --- a/src/gui/EffectRackView.cpp +++ b/src/gui/EffectRackView.cpp @@ -179,13 +179,13 @@ void EffectRackView::update() connect(view, &EffectView::deletedPlugin, this, &EffectRackView::deletePlugin, Qt::QueuedConnection); QAction* moveUpAction = new QAction(view); - moveUpAction->setShortcut(combine(Qt::Key_Up, Qt::AltModifier)); + moveUpAction->setShortcut(keySequence(Qt::Key_Up, Qt::AltModifier)); moveUpAction->setShortcutContext(Qt::WidgetShortcut); connect(moveUpAction, &QAction::triggered, view, &EffectView::moveUp); view->addAction(moveUpAction); QAction* moveDownAction = new QAction(view); - moveDownAction->setShortcut(combine(Qt::Key_Down, Qt::AltModifier)); + moveDownAction->setShortcut(keySequence(Qt::Key_Down, Qt::AltModifier)); moveDownAction->setShortcutContext(Qt::WidgetShortcut); connect(moveDownAction, &QAction::triggered, view, &EffectView::moveDown); view->addAction(moveDownAction); diff --git a/src/gui/FileBrowser.cpp b/src/gui/FileBrowser.cpp index f11dd9931..e39166cfc 100644 --- a/src/gui/FileBrowser.cpp +++ b/src/gui/FileBrowser.cpp @@ -43,6 +43,7 @@ #include "AudioEngine.h" #include "ConfigManager.h" #include "DataFile.h" +#include "DeprecationHelper.h" #include "Engine.h" #include "FileBrowser.h" #include "FileRevealer.h" @@ -177,7 +178,13 @@ void FileBrowser::addContentCheckBox() auto configCheckBox = [this](QBoxLayout* boxLayout, QCheckBox* box, Qt::CheckState checkState) { box->setCheckState(checkState); - connect(box, SIGNAL(stateChanged(int)), this, SLOT(reloadTree())); + +#if (QT_VERSION >= QT_VERSION_CHECK(6, 7, 0)) + connect(box, &QCheckBox::checkStateChanged, this, &FileBrowser::reloadTree); +#else + connect(box, &QCheckBox::stateChanged, this, &FileBrowser::reloadTree); +#endif + boxLayout->addWidget(box); }; @@ -721,8 +728,10 @@ QList FileBrowserTreeWidget::getContextActions(FileItem* file, bool so void FileBrowserTreeWidget::mousePressEvent(QMouseEvent * me ) { + const auto pos = position(me); + // Forward the event - QTreeWidgetItem * i = itemAt(me->pos()); + QTreeWidgetItem* i = itemAt(pos); QTreeWidget::mousePressEvent(me); // QTreeWidget handles right clicks for us, so we only care about left clicks if(me->button() != Qt::LeftButton) { return; } @@ -730,13 +739,13 @@ void FileBrowserTreeWidget::mousePressEvent(QMouseEvent * me ) if (i) { // TODO: Restrict to visible selection -// if ( _me->x() > header()->cellPos( header()->mapToActual( 0 ) ) +// if ( pos.x() > header()->cellPos( header()->mapToActual( 0 ) ) // + treeStepSize() * ( i->depth() + ( rootIsDecorated() ? // 1 : 0 ) ) + itemMargin() || -// _me->x() < header()->cellPos( +// pos.x() < header()->cellPos( // header()->mapToActual( 0 ) ) ) // { - m_pressPos = me->pos(); + m_pressPos = pos; m_mousePressed = true; // } } @@ -830,9 +839,7 @@ void FileBrowserTreeWidget::stopPreview() void FileBrowserTreeWidget::mouseMoveEvent( QMouseEvent * me ) { - if( m_mousePressed == true && - ( m_pressPos - me->pos() ).manhattanLength() > - QApplication::startDragDistance() ) + if (m_mousePressed && (m_pressPos - position(me)).manhattanLength() > QApplication::startDragDistance()) { // make sure any playback is stopped mouseReleaseEvent( nullptr ); diff --git a/src/gui/GuiApplication.cpp b/src/gui/GuiApplication.cpp index f2d570e89..fb7e4e7c1 100644 --- a/src/gui/GuiApplication.cpp +++ b/src/gui/GuiApplication.cpp @@ -308,9 +308,9 @@ void GuiApplication::sigintOccurred() */ QFont GuiApplication::getWin32SystemFont() { - NONCLIENTMETRICS metrics = { sizeof( NONCLIENTMETRICS ) }; - SystemParametersInfo( SPI_GETNONCLIENTMETRICS, sizeof( NONCLIENTMETRICS ), &metrics, 0 ); - int pointSize = metrics.lfMessageFont.lfHeight; + auto metrics = NONCLIENTMETRICSW{ .cbSize = sizeof(NONCLIENTMETRICSW) }; + SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICSW), &metrics, 0); + int pointSize = static_cast(metrics.lfMessageFont.lfHeight); if ( pointSize < 0 ) { // height is in pixels, convert to points @@ -319,7 +319,7 @@ QFont GuiApplication::getWin32SystemFont() ReleaseDC( nullptr, hDC ); } - return QFont( QString::fromUtf8( metrics.lfMessageFont.lfFaceName ), pointSize ); + return QFont{QString::fromWCharArray(metrics.lfMessageFont.lfFaceName), pointSize}; } #endif diff --git a/src/gui/MainApplication.cpp b/src/gui/MainApplication.cpp index 48c400a24..0ab086e93 100644 --- a/src/gui/MainApplication.cpp +++ b/src/gui/MainApplication.cpp @@ -86,8 +86,8 @@ bool MainApplication::event(QEvent* event) } #ifdef LMMS_BUILD_WIN32 -// This can be moved into nativeEventFilter once Qt4 support has been dropped -bool MainApplication::winEventFilter(MSG* msg, long* result) +// Helper function for nativeEventFilter +bool MainApplication::win32EventFilter(MSG* msg, FilterResult* result) { switch(msg->message) { @@ -110,11 +110,11 @@ bool MainApplication::winEventFilter(MSG* msg, long* result) } bool MainApplication::nativeEventFilter(const QByteArray& eventType, - void* message, long* result) + void* message, FilterResult* result) { if(eventType == "windows_generic_MSG") { - return winEventFilter(static_cast(message), result); + return win32EventFilter(static_cast(message), result); } return false; } diff --git a/src/gui/MainWindow.cpp b/src/gui/MainWindow.cpp index ff5b05bed..27cd91a70 100644 --- a/src/gui/MainWindow.cpp +++ b/src/gui/MainWindow.cpp @@ -264,87 +264,79 @@ void MainWindow::finalize() resetWindowTitle(); setWindowIcon( embed::getIconPixmap( "icon_small" ) ); + auto addAction = [this](QMenu* menu, std::string_view icon, const QString& text, + const QKeySequence& shortcut, auto(MainWindow::* slot)()) -> QAction* + { +#if (QT_VERSION >= QT_VERSION_CHECK(6, 3, 0)) + return menu->addAction(embed::getIconPixmap(icon), text, shortcut, this, slot); +#else + return menu->addAction(embed::getIconPixmap(icon), text, this, slot, shortcut); +#endif + }; // project-popup-menu auto project_menu = new QMenu(this); menuBar()->addMenu( project_menu )->setText( tr( "&File" ) ); - project_menu->addAction( embed::getIconPixmap( "project_new" ), - tr( "&New" ), - this, SLOT(createNewProject()), - QKeySequence::New ); + + addAction(project_menu, "project_new", tr("&New"), + QKeySequence::New, &MainWindow::createNewProject); auto templates_menu = new TemplatesMenu( this ); project_menu->addMenu(templates_menu); - project_menu->addAction( embed::getIconPixmap( "project_open" ), - tr( "&Open..." ), - this, SLOT(openProject()), - QKeySequence::Open ); + addAction(project_menu, "project_open", tr("&Open..."), + QKeySequence::Open, &MainWindow::openProject); project_menu->addMenu(new RecentProjectsMenu(this)); - project_menu->addAction( embed::getIconPixmap( "project_save" ), - tr( "&Save" ), - this, SLOT(saveProject()), - QKeySequence::Save ); - project_menu->addAction( embed::getIconPixmap( "project_save" ), - tr( "Save &As..." ), - this, SLOT(saveProjectAs()), - combine(Qt::CTRL, Qt::SHIFT, Qt::Key_S)); - project_menu->addAction( embed::getIconPixmap( "project_save" ), - tr( "Save as New &Version" ), - this, SLOT(saveProjectAsNewVersion()), - combine(Qt::CTRL, Qt::ALT, Qt::Key_S)); + addAction(project_menu, "project_save", tr("&Save"), + QKeySequence::Save, &MainWindow::saveProject); - project_menu->addAction( embed::getIconPixmap( "project_save" ), - tr( "Save as default template" ), - this, SLOT(saveProjectAsDefaultTemplate())); + addAction(project_menu, "project_save", tr("Save &As..."), + keySequence(Qt::CTRL, Qt::SHIFT, Qt::Key_S), &MainWindow::saveProjectAs); + + addAction(project_menu, "project_save", tr("Save as New &Version"), + keySequence(Qt::CTRL, Qt::ALT, Qt::Key_S), &MainWindow::saveProjectAsNewVersion); + + project_menu->addAction(embed::getIconPixmap("project_save"), tr("Save as default template"), + this, &MainWindow::saveProjectAsDefaultTemplate); project_menu->addSeparator(); - project_menu->addAction( embed::getIconPixmap( "project_import" ), - tr( "Import..." ), - this, - SLOT(onImportProject())); - project_menu->addAction( embed::getIconPixmap( "project_export" ), - tr( "E&xport..." ), - this, - SLOT(onExportProject()), - combine(Qt::CTRL, Qt::Key_E)); - project_menu->addAction( embed::getIconPixmap( "project_export" ), - tr("Export &Tracks..."), - this, - SLOT(onExportProjectTracks()), - combine(Qt::CTRL, Qt::SHIFT, Qt::Key_E)); - project_menu->addAction( embed::getIconPixmap( "midi_file" ), - tr( "Export &MIDI..." ), - this, - SLOT(onExportProjectMidi()), - combine(Qt::CTRL, Qt::Key_M)); + project_menu->addAction(embed::getIconPixmap("project_import"), tr("Import..."), + this, &MainWindow::onImportProject); + + addAction(project_menu, "project_export", tr("E&xport..."), + keySequence(Qt::CTRL, Qt::Key_E), &MainWindow::onExportProject); + + addAction(project_menu, "project_export", tr("Export &Tracks..."), + keySequence(Qt::CTRL, Qt::SHIFT, Qt::Key_E), &MainWindow::onExportProjectTracks); + + addAction(project_menu, "midi_file", tr("Export &MIDI..."), + keySequence(Qt::CTRL, Qt::Key_M), &MainWindow::onExportProjectMidi); project_menu->addSeparator(); - project_menu->addAction( embed::getIconPixmap( "exit" ), tr( "&Quit" ), - qApp, SLOT(closeAllWindows()), - combine(Qt::CTRL, Qt::Key_Q)); + + project_menu->addAction(embed::getIconPixmap("exit"), tr("&Quit"), + qApp, SLOT(closeAllWindows()))->setShortcut(keySequence(Qt::CTRL, Qt::Key_Q)); auto edit_menu = new QMenu(this); menuBar()->addMenu( edit_menu )->setText( tr( "&Edit" ) ); - m_undoAction = edit_menu->addAction( embed::getIconPixmap( "edit_undo" ), - tr( "Undo" ), - this, SLOT(undo()), - QKeySequence::Undo ); - m_redoAction = edit_menu->addAction( embed::getIconPixmap( "edit_redo" ), - tr( "Redo" ), - this, SLOT(redo()), - QKeySequence::Redo ); + + m_undoAction = addAction(edit_menu, "edit_undo", tr("Undo"), + QKeySequence::Undo, &MainWindow::undo); + + m_redoAction = addAction(edit_menu, "edit_redo", tr("Redo"), + QKeySequence::Redo, &MainWindow::redo); + // Ensure that both (Ctrl+Y) and (Ctrl+Shift+Z) activate redo shortcut regardless of OS defaults - if (QKeySequence(QKeySequence::Redo) != QKeySequence(combine(Qt::CTRL, Qt::Key_Y))) + if (QKeySequence(QKeySequence::Redo) != keySequence(Qt::CTRL, Qt::Key_Y)) { - new QShortcut(QKeySequence(combine(Qt::CTRL, Qt::Key_Y)), this, SLOT(redo())); + new QShortcut(keySequence(Qt::CTRL, Qt::Key_Y), this, SLOT(redo())); } - if (QKeySequence(QKeySequence::Redo) != QKeySequence(combine(Qt::CTRL, Qt::SHIFT, Qt::Key_Z))) + if (QKeySequence(QKeySequence::Redo) != keySequence(Qt::CTRL, Qt::SHIFT, Qt::Key_Z)) { - new QShortcut(QKeySequence(combine(Qt::CTRL, Qt::SHIFT, Qt::Key_Z)), this, SLOT(redo())); + new QShortcut(keySequence(Qt::CTRL, Qt::SHIFT, Qt::Key_Z), this, SLOT(redo())); } edit_menu->addSeparator(); @@ -443,31 +435,31 @@ void MainWindow::finalize() // window-toolbar auto song_editor_window = new ToolButton(embed::getIconPixmap("songeditor"), tr("Song Editor") + " (Ctrl+1)", this, SLOT(toggleSongEditorWin()), m_toolBar); - song_editor_window->setShortcut(combine(Qt::CTRL, Qt::Key_1)); + song_editor_window->setShortcut(keySequence(Qt::CTRL, Qt::Key_1)); auto pattern_editor_window = new ToolButton(embed::getIconPixmap("pattern_track_btn"), tr("Pattern Editor") + " (Ctrl+2)", this, SLOT(togglePatternEditorWin()), m_toolBar); - pattern_editor_window->setShortcut(combine(Qt::CTRL, Qt::Key_2)); + pattern_editor_window->setShortcut(keySequence(Qt::CTRL, Qt::Key_2)); auto piano_roll_window = new ToolButton( embed::getIconPixmap("piano"), tr("Piano Roll") + " (Ctrl+3)", this, SLOT(togglePianoRollWin()), m_toolBar); - piano_roll_window->setShortcut(combine(Qt::CTRL, Qt::Key_3)); + piano_roll_window->setShortcut(keySequence(Qt::CTRL, Qt::Key_3)); auto automation_editor_window = new ToolButton(embed::getIconPixmap("automation"), tr("Automation Editor") + " (Ctrl+4)", this, SLOT(toggleAutomationEditorWin()), m_toolBar); - automation_editor_window->setShortcut(combine(Qt::CTRL, Qt::Key_4)); + automation_editor_window->setShortcut(keySequence(Qt::CTRL, Qt::Key_4)); auto mixer_window = new ToolButton( embed::getIconPixmap("mixer"), tr("Mixer") + " (Ctrl+5)", this, SLOT(toggleMixerWin()), m_toolBar); - mixer_window->setShortcut(combine(Qt::CTRL, Qt::Key_5)); + mixer_window->setShortcut(keySequence(Qt::CTRL, Qt::Key_5)); auto controllers_window = new ToolButton(embed::getIconPixmap("controller"), tr("Show/hide controller rack") + " (Ctrl+6)", this, SLOT(toggleControllerRack()), m_toolBar); - controllers_window->setShortcut(combine(Qt::CTRL, Qt::Key_6)); + controllers_window->setShortcut(keySequence(Qt::CTRL, Qt::Key_6)); auto project_notes_window = new ToolButton(embed::getIconPixmap("project_notes"), tr("Show/hide project notes") + " (Ctrl+7)", this, SLOT(toggleProjectNotesWin()), m_toolBar); - project_notes_window->setShortcut(combine(Qt::CTRL, Qt::Key_7)); + project_notes_window->setShortcut(keySequence(Qt::CTRL, Qt::Key_7)); m_toolBarLayout->addWidget( song_editor_window, 1, 1 ); m_toolBarLayout->addWidget( pattern_editor_window, 1, 2 ); @@ -620,15 +612,19 @@ bool MainWindow::mayChangeProject(bool stopPlayback) "last saving. Do you want to save it " "now?" ); - QMessageBox mb( ( getSession() == SessionState::Recover ? - messageTitleRecovered : messageTitleUnsaved ), - ( getSession() == SessionState::Recover ? - messageRecovered : messageUnsaved ), - QMessageBox::Question, - QMessageBox::Save, - QMessageBox::Discard, - QMessageBox::Cancel, - this ); + const auto& title = getSession() == SessionState::Recover + ? messageTitleRecovered + : messageTitleUnsaved; + + const auto& text = getSession() == SessionState::Recover + ? messageRecovered + : messageUnsaved; + + const auto buttons = QMessageBox::Save + | QMessageBox::Discard + | QMessageBox::Cancel; + + auto mb = QMessageBox{QMessageBox::Question, title, text, buttons, this}; int answer = mb.exec(); if( answer == QMessageBox::Save ) @@ -1607,8 +1603,9 @@ MainWindow::MovableQMdiArea::MovableQMdiArea(QWidget* parent) : void MainWindow::MovableQMdiArea::mousePressEvent(QMouseEvent* event) { - m_lastX = event->x(); - m_lastY = event->y(); + const auto pos = position(event); + m_lastX = pos.x(); + m_lastY = pos.y(); m_isBeingMoved = true; setCursor(Qt::ClosedHandCursor); } @@ -1639,8 +1636,9 @@ void MainWindow::MovableQMdiArea::mouseMoveEvent(QMouseEvent* event) } } - int scrollX = m_lastX - event->x(); - int scrollY = m_lastY - event->y(); + const auto pos = position(event); + int scrollX = m_lastX - pos.x(); + int scrollY = m_lastY - pos.y(); scrollX = scrollX < 0 && minX >= minXBoundary ? 0 : scrollX; scrollX = scrollX > 0 && maxX <= maxXBoundary ? 0 : scrollX; @@ -1657,8 +1655,8 @@ void MainWindow::MovableQMdiArea::mouseMoveEvent(QMouseEvent* event) } } - m_lastX = event->x(); - m_lastY = event->y(); + m_lastX = pos.x(); + m_lastY = pos.y(); } void MainWindow::MovableQMdiArea::mouseReleaseEvent(QMouseEvent* event) diff --git a/src/gui/MixerChannelView.cpp b/src/gui/MixerChannelView.cpp index abc619ec3..e0ca4333d 100644 --- a/src/gui/MixerChannelView.cpp +++ b/src/gui/MixerChannelView.cpp @@ -343,10 +343,16 @@ bool MixerChannelView::confirmRemoval(int index) QString messageTitleRemoveTrack = tr("Confirm removal"); QString askAgainText = tr("Don't ask again"); auto askAgainCheckBox = new QCheckBox(askAgainText, nullptr); - connect(askAgainCheckBox, &QCheckBox::stateChanged, [](int state) { + auto onCheckedStateChanged = [](auto state) { // Invert button state, if it's checked we *shouldn't* ask again - ConfigManager::inst()->setValue("ui", "mixerchanneldeletionwarning", state ? "0" : "1"); - }); + ConfigManager::inst()->setValue("ui", "mixerchanneldeletionwarning", state != Qt::Unchecked ? "0" : "1"); + }; + +#if (QT_VERSION >= QT_VERSION_CHECK(6, 7, 0)) + connect(askAgainCheckBox, &QCheckBox::checkStateChanged, onCheckedStateChanged); +#else + connect(askAgainCheckBox, &QCheckBox::stateChanged, onCheckedStateChanged); +#endif QMessageBox mb; mb.setText(messageRemoveTrack); diff --git a/src/gui/PluginBrowser.cpp b/src/gui/PluginBrowser.cpp index 4bf62d4ea..d3f2236a2 100644 --- a/src/gui/PluginBrowser.cpp +++ b/src/gui/PluginBrowser.cpp @@ -258,13 +258,15 @@ void PluginDescWidget::paintEvent( QPaintEvent * ) } - - -void PluginDescWidget::enterEvent( QEvent * _e ) +#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) +void PluginDescWidget::enterEvent(QEnterEvent* event) +#else +void PluginDescWidget::enterEvent(QEvent* event) +#endif { m_mouseOver = true; - QWidget::enterEvent( _e ); + QWidget::enterEvent(event); } diff --git a/src/gui/ProjectNotes.cpp b/src/gui/ProjectNotes.cpp index bf760ec21..ea9861012 100644 --- a/src/gui/ProjectNotes.cpp +++ b/src/gui/ProjectNotes.cpp @@ -26,6 +26,7 @@ #include "ProjectNotes.h" #include +#include #include #include #include @@ -146,8 +147,15 @@ void ProjectNotes::setupActions() m_comboFont->setEditable( true ); QFontDatabase db; m_comboFont->addItems( db.families() ); - connect( m_comboFont, SIGNAL( activated( const QString& ) ), - m_edit, SLOT( setFontFamily( const QString& ) ) ); + + connect(m_comboFont, +#if (QT_VERSION < QT_VERSION_CHECK(5, 14, 0)) + QOverload::of(&QComboBox::activated), +#else + &QComboBox::textActivated, +#endif + m_edit, &QTextEdit::setFontFamily); + m_comboFont->lineEdit()->setText( QApplication::font().family() ); m_comboSize = new QComboBox( tb ); @@ -158,8 +166,15 @@ void ProjectNotes::setupActions() { m_comboSize->addItem( QString::number( *it ) ); } - connect( m_comboSize, SIGNAL( activated( const QString& ) ), - this, SLOT( textSize( const QString& ) ) ); + + connect(m_comboSize, +#if (QT_VERSION < QT_VERSION_CHECK(5, 14, 0)) + QOverload::of(&QComboBox::activated), +#else + &QComboBox::textActivated, +#endif + this, &ProjectNotes::textSize); + m_comboSize->lineEdit()->setText( QString::number( QApplication::font().pointSize() ) ); diff --git a/src/gui/SubWindow.cpp b/src/gui/SubWindow.cpp index ad9da761d..a9a652e98 100644 --- a/src/gui/SubWindow.cpp +++ b/src/gui/SubWindow.cpp @@ -81,7 +81,7 @@ SubWindow::SubWindow(QWidget *parent, Qt::WindowFlags windowFlags) : // Disable the minimize button and make sure that the custom window hint is set setWindowFlags((this->windowFlags() & ~Qt::WindowMinimizeButtonHint) | Qt::CustomizeWindowHint); - connect( mdiArea(), SIGNAL(subWindowActivated(QMdiSubWindow*)), this, SLOT(focusChanged(QMdiSubWindow*))); + connect(mdiArea(), &QMdiArea::subWindowActivated, this, &SubWindow::focusChanged); } diff --git a/src/gui/clips/AutomationClipView.cpp b/src/gui/clips/AutomationClipView.cpp index 57447e87f..07d5a2c5f 100644 --- a/src/gui/clips/AutomationClipView.cpp +++ b/src/gui/clips/AutomationClipView.cpp @@ -293,7 +293,9 @@ void AutomationClipView::paintEvent( QPaintEvent * ) m_clip->getTimeMap().begin(); it != m_clip->getTimeMap().end(); ++it ) { - if( it+1 == m_clip->getTimeMap().end() ) + const auto nit = std::next(it); + + if (nit == m_clip->getTimeMap().end()) { const float x1 = POS(it) * ppTick + offset; const auto x2 = (float)(width() - BORDER_WIDTH); @@ -320,21 +322,21 @@ void AutomationClipView::paintEvent( QPaintEvent * ) // the next node. float nextValue = m_clip->progressionType() == AutomationClip::ProgressionType::Discrete ? OUTVAL(it) - : INVAL(it + 1); + : INVAL(nit); QPainterPath path; QPointF origin = QPointF(POS(it) * ppTick + offset, 0.0f); path.moveTo(origin); path.moveTo(QPointF(POS(it) * ppTick + offset, values[0])); - for (int i = POS(it) + 1; i < POS(it + 1); i++) + for (int i = POS(it) + 1; i < POS(nit); ++i) { float x = i * ppTick + offset; if(x > (width() - BORDER_WIDTH)) break; float value = values[i - POS(it)]; path.lineTo(QPointF(x, value)); } - path.lineTo((POS(it + 1)) * ppTick + offset, nextValue); - path.lineTo((POS(it + 1)) * ppTick + offset, 0.0f); + path.lineTo((POS(nit)) * ppTick + offset, nextValue); + path.lineTo((POS(nit)) * ppTick + offset, 0.0f); path.lineTo(origin); if( gradient() ) diff --git a/src/gui/clips/ClipView.cpp b/src/gui/clips/ClipView.cpp index 5e92e661f..a4e702bc9 100644 --- a/src/gui/clips/ClipView.cpp +++ b/src/gui/clips/ClipView.cpp @@ -35,6 +35,7 @@ #include "Clipboard.h" #include "ColorChooser.h" #include "DataFile.h" +#include "DeprecationHelper.h" #include "Engine.h" #include "embed.h" #include "GuiApplication.h" @@ -482,9 +483,11 @@ void ClipView::dropEvent( QDropEvent * de ) */ void ClipView::updateCursor(QMouseEvent * me) { + const auto posX = position(me).x(); + // If we are at the edges, use the resize cursor if (!me->buttons() && m_clip->manuallyResizable() && !isSelected() - && ((me->x() > width() - RESIZE_GRIP_WIDTH) || (me->x() < RESIZE_GRIP_WIDTH))) + && ((posX > width() - RESIZE_GRIP_WIDTH) || (posX < RESIZE_GRIP_WIDTH))) { setCursor(Qt::SizeHorCursor); } @@ -606,13 +609,15 @@ void ClipView::paintTextLabel(QString const & text, QPainter & painter) */ void ClipView::mousePressEvent( QMouseEvent * me ) { + const auto pos = position(me); + // Right now, active is only used on right/mid clicks actions, so we use a ternary operator // to avoid the overhead of calling getClickedClips when it's not used auto active = me->button() == Qt::LeftButton ? QVector() : getClickedClips(); - setInitialPos( me->pos() ); + setInitialPos(pos); setInitialOffsets(); if( !fixedClips() && me->button() == Qt::LeftButton ) { @@ -647,7 +652,7 @@ void ClipView::mousePressEvent( QMouseEvent * me ) m_clip->setJournalling(false); } - setInitialPos( me->pos() ); + setInitialPos(pos); setInitialOffsets(); if (!m_clip->manuallyResizable() && !knifeMode) @@ -655,12 +660,12 @@ void ClipView::mousePressEvent( QMouseEvent * me ) m_action = Action::Move; setCursor( Qt::SizeAllCursor ); } - else if( me->x() >= width() - RESIZE_GRIP_WIDTH ) + else if (pos.x() >= width() - RESIZE_GRIP_WIDTH) { m_action = Action::Resize; setCursor( Qt::SizeHorCursor ); } - else if (me->x() < RESIZE_GRIP_WIDTH) + else if (pos.x() < RESIZE_GRIP_WIDTH) { m_action = Action::ResizeLeft; setCursor( Qt::SizeHorCursor ); @@ -823,6 +828,7 @@ void ClipView::mouseMoveEvent( QMouseEvent * me ) m_hint = nullptr; } + const auto pos = position(me); const float ppb = m_trackView->trackContainerView()->pixelsPerBar(); if( m_action == Action::Move ) { @@ -875,7 +881,7 @@ void ClipView::mouseMoveEvent( QMouseEvent * me ) if( m_action == Action::Resize ) { // The clip's new length - TimePos l = static_cast( me->x() * TimePos::ticksPerBar() / ppb ); + TimePos l = static_cast(pos.x() * TimePos::ticksPerBar() / ppb); // If the user is holding alt, or pressed ctrl after beginning the drag, don't quantize if ( unquantizedModHeld(me) ) @@ -910,7 +916,7 @@ void ClipView::mouseMoveEvent( QMouseEvent * me ) { auto pClip = dynamic_cast(m_clip); - const int x = mapToParent( me->pos() ).x() - m_initialMousePos.x(); + const int x = mapToParent(pos).x() - m_initialMousePos.x(); TimePos t = qMax( 0, (int) m_trackView->trackContainerView()->currentPosition() + @@ -1020,7 +1026,7 @@ void ClipView::mouseReleaseEvent( QMouseEvent * me ) else if( m_action == Action::Split ) { const float ppb = m_trackView->trackContainerView()->pixelsPerBar(); - const TimePos relPos = me->pos().x() * TimePos::ticksPerBar() / ppb; + const TimePos relPos = position(me).x() * TimePos::ticksPerBar() / ppb; if (me->modifiers() & Qt::ShiftModifier) { destructiveSplitClip(unquantizedModHeld(me) ? relPos : quantizeSplitPos(relPos)); @@ -1282,7 +1288,7 @@ void ClipView::setInitialOffsets() */ bool ClipView::mouseMovedDistance( QMouseEvent * me, int distance ) { - QPoint dPos = mapToGlobal( me->pos() ) - m_initialMouseGlobalPos; + QPoint dPos = mapToGlobal(position(me)) - m_initialMouseGlobalPos; const int pixelsMoved = dPos.manhattanLength(); return ( pixelsMoved > distance || pixelsMoved < -distance ); } @@ -1308,7 +1314,7 @@ TimePos ClipView::draggedClipPos( QMouseEvent * me ) //Pixels per bar const float ppb = m_trackView->trackContainerView()->pixelsPerBar(); // The pixel distance that the mouse has moved - const int mouseOff = mapToGlobal(me->pos()).x() - m_initialMouseGlobalPos.x(); + const int mouseOff = mapToGlobal(position(me)).x() - m_initialMouseGlobalPos.x(); TimePos newPos = m_initialClipPos + mouseOff * TimePos::ticksPerBar() / ppb; TimePos offset = newPos - m_initialClipPos; // If the user is holding alt, or pressed ctrl after beginning the drag, don't quantize @@ -1340,7 +1346,7 @@ TimePos ClipView::draggedClipPos( QMouseEvent * me ) int ClipView::knifeMarkerPos( QMouseEvent * me ) { //Position relative to start of clip - const int markerPos = me->pos().x(); + const int markerPos = position(me).x(); //In unquantized mode, we don't have to mess with the position at all if ( unquantizedModHeld(me) ) { return markerPos; } diff --git a/src/gui/clips/MidiClipView.cpp b/src/gui/clips/MidiClipView.cpp index 28ffd1ade..cdbdb6187 100644 --- a/src/gui/clips/MidiClipView.cpp +++ b/src/gui/clips/MidiClipView.cpp @@ -421,17 +421,19 @@ void MidiClipView::bulkClearNotesOutOfBounds(QVector clipvs) void MidiClipView::mousePressEvent( QMouseEvent * _me ) { + const auto pos = position(_me); + bool displayPattern = fixedClips() || (pixelsPerBar() >= 96 && m_legacySEPattern); if (_me->button() == Qt::LeftButton && m_clip->m_clipType == MidiClip::Type::BeatClip && displayPattern - && _me->y() > BeatStepButtonOffset && _me->y() < BeatStepButtonOffset + m_stepBtnOff.height()) + && pos.y() > BeatStepButtonOffset && pos.y() < BeatStepButtonOffset + m_stepBtnOff.height()) // when mouse button is pressed in pattern mode { // get the step number that was clicked on and // do calculations in floats to prevent rounding errors... - float tmp = ( ( float(_me->x()) - BORDER_WIDTH ) * - float( m_clip -> m_steps ) ) / float(width() - BORDER_WIDTH*2); + float tmp = ((static_cast(pos.x()) - BORDER_WIDTH) + * static_cast(m_clip->m_steps)) / static_cast(width() - BORDER_WIDTH * 2); int step = int( tmp ); diff --git a/src/gui/editors/AutomationEditor.cpp b/src/gui/editors/AutomationEditor.cpp index 362640b0b..5036a233f 100644 --- a/src/gui/editors/AutomationEditor.cpp +++ b/src/gui/editors/AutomationEditor.cpp @@ -428,13 +428,15 @@ void AutomationEditor::mousePressEvent( QMouseEvent* mouseEvent ) } }; + const auto pos = position(mouseEvent); + // If we clicked inside the AutomationEditor viewport (where the nodes are represented) - if (mouseEvent->y() > TOP_MARGIN && mouseEvent->x() >= VALUES_WIDTH) + if (pos.y() > TOP_MARGIN && pos.x() >= VALUES_WIDTH) { - float level = getLevel( mouseEvent->y() ); + float level = getLevel(pos.y()); // Get the viewport X - int x = mouseEvent->x() - VALUES_WIDTH; + int x = pos.x() - VALUES_WIDTH; // Get tick in which the user clicked int posTicks = (x * TimePos::ticksPerBar() / m_ppb) + m_currentPosition; @@ -453,7 +455,7 @@ void AutomationEditor::mousePressEvent( QMouseEvent* mouseEvent ) || (m_editMode == EditMode::Erase && m_mouseDownRight) ); - timeMap::iterator clickedNode = getNodeAt(mouseEvent->x(), mouseEvent->y(), editingOutValue); + timeMap::iterator clickedNode = getNodeAt(pos.x(), pos.y(), editingOutValue); switch (m_editMode) { @@ -622,7 +624,7 @@ void AutomationEditor::mousePressEvent( QMouseEvent* mouseEvent ) m_clip->addJournalCheckPoint(); // Gets the closest node to the mouse click - timeMap::iterator node = getClosestNode(mouseEvent->x()); + timeMap::iterator node = getClosestNode(pos.x()); // Starts dragging a tangent if (m_mouseDownLeft && node != tm.end()) @@ -663,14 +665,16 @@ void AutomationEditor::mousePressEvent( QMouseEvent* mouseEvent ) void AutomationEditor::mouseDoubleClickEvent(QMouseEvent * mouseEvent) { + const auto pos = position(mouseEvent); + if (!validClip()) { return; } // If we double clicked outside the AutomationEditor viewport return - if (mouseEvent->y() <= TOP_MARGIN || mouseEvent->x() < VALUES_WIDTH) { return; } + if (pos.y() <= TOP_MARGIN || pos.x() < VALUES_WIDTH) { return; } // Are we fine tuning the inValue or outValue? const bool isOutVal = (m_editMode == EditMode::DrawOutValues); - timeMap::iterator clickedNode = getNodeAt(mouseEvent->x(), mouseEvent->y(), isOutVal); + timeMap::iterator clickedNode = getNodeAt(pos.x(), pos.y(), isOutVal); switch (m_editMode) { @@ -728,12 +732,14 @@ void AutomationEditor::mouseMoveEvent(QMouseEvent * mouseEvent ) return; } + const auto pos = position(mouseEvent); + // If the mouse y position is inside the Automation Editor viewport - if (mouseEvent->y() > TOP_MARGIN) + if (pos.y() > TOP_MARGIN) { - float level = getLevel(mouseEvent->y()); + float level = getLevel(pos.y()); // Get the viewport X position where the mouse is at - int x = mouseEvent->x() - VALUES_WIDTH; + int x = pos.x() - VALUES_WIDTH; // Get the X position in ticks int posTicks = (x * TimePos::ticksPerBar() / m_ppb) + m_currentPosition; @@ -882,8 +888,8 @@ void AutomationEditor::mouseMoveEvent(QMouseEvent * mouseEvent ) ? yCoordOfLevel(OUTVAL(it)) : yCoordOfLevel(INVAL(it)); float dy = m_draggedOutTangent - ? y - mouseEvent->y() - : mouseEvent->y() - y; + ? y - pos.y() + : pos.y() - y; float dx = std::abs(posTicks - POS(it)); float newTangent = dy / std::max(dx, 1.0f); @@ -1314,11 +1320,13 @@ void AutomationEditor::paintEvent(QPaintEvent * pe ) if( time_map.size() > 0 ) { timeMap::iterator it = time_map.begin(); - while( it+1 != time_map.end() ) + while (std::next(it) != time_map.end()) { // skip this section if it occurs completely before the // visible area - int next_x = xCoordOfTick(POS(it+1)); + const auto nit = std::next(it); + + int next_x = xCoordOfTick(POS(nit)); if( next_x < 0 ) { ++it; @@ -1341,17 +1349,17 @@ void AutomationEditor::paintEvent(QPaintEvent * pe ) // the next node. float nextValue = m_clip->progressionType() == AutomationClip::ProgressionType::Discrete ? OUTVAL(it) - : INVAL(it + 1); + : INVAL(nit); p.setRenderHints( QPainter::Antialiasing, true ); QPainterPath path; path.moveTo(QPointF(xCoordOfTick(POS(it)), yCoordOfLevel(0))); - for (int i = 0; i < POS(it + 1) - POS(it); i++) + for (int i = 0; i < POS(nit) - POS(it); ++i) { path.lineTo(QPointF(xCoordOfTick(POS(it) + i), yCoordOfLevel(values[i]))); } - path.lineTo(QPointF(xCoordOfTick(POS(it + 1)), yCoordOfLevel(nextValue))); - path.lineTo(QPointF(xCoordOfTick(POS(it + 1)), yCoordOfLevel(0))); + path.lineTo(QPointF(xCoordOfTick(POS(nit)), yCoordOfLevel(nextValue))); + path.lineTo(QPointF(xCoordOfTick(POS(nit)), yCoordOfLevel(0))); path.lineTo(QPointF(xCoordOfTick(POS(it)), yCoordOfLevel(0))); p.fillPath(path, m_graphColor); p.setRenderHints( QPainter::Antialiasing, false ); @@ -2060,17 +2068,18 @@ AutomationEditorWindow::AutomationEditorWindow() : auto editModeGroup = new ActionGroup(this); m_drawAction = editModeGroup->addAction(embed::getIconPixmap("edit_draw"), tr("Draw mode (Shift+D)")); - m_drawAction->setShortcut(combine(Qt::SHIFT, Qt::Key_D)); + + m_drawAction->setShortcut(keySequence(Qt::SHIFT, Qt::Key_D)); m_drawAction->setChecked(true); m_eraseAction = editModeGroup->addAction(embed::getIconPixmap("edit_erase"), tr("Erase mode (Shift+E)")); - m_eraseAction->setShortcut(combine(Qt::SHIFT, Qt::Key_E)); + m_eraseAction->setShortcut(keySequence(Qt::SHIFT, Qt::Key_E)); m_drawOutAction = editModeGroup->addAction(embed::getIconPixmap("edit_draw_outvalue"), tr("Draw outValues mode (Shift+C)")); - m_drawOutAction->setShortcut(combine(Qt::SHIFT, Qt::Key_C)); + m_drawOutAction->setShortcut(keySequence(Qt::SHIFT, Qt::Key_C)); m_editTanAction = editModeGroup->addAction(embed::getIconPixmap("edit_tangent"), tr("Edit tangents mode (Shift+T)")); - m_editTanAction->setShortcut(combine(Qt::SHIFT, Qt::Key_T)); + m_editTanAction->setShortcut(keySequence(Qt::SHIFT, Qt::Key_T)); m_editTanAction->setEnabled(false); m_flipYAction = new QAction(embed::getIconPixmap("flip_y"), tr("Flip vertically"), this); diff --git a/src/gui/editors/Editor.cpp b/src/gui/editors/Editor.cpp index d6b96887a..2b2c1534c 100644 --- a/src/gui/editors/Editor.cpp +++ b/src/gui/editors/Editor.cpp @@ -120,7 +120,7 @@ Editor::Editor(bool record, bool stepRecord) : connect(m_recordAccompanyAction, SIGNAL(triggered()), this, SLOT(recordAccompany())); connect(m_toggleStepRecordingAction, SIGNAL(triggered()), this, SLOT(toggleStepRecording())); connect(m_stopAction, SIGNAL(triggered()), this, SLOT(stop())); - new QShortcut(QKeySequence(combine(Qt::SHIFT, Qt::Key_F11)), this, SLOT(toggleMaximize())); + new QShortcut(keySequence(Qt::SHIFT, Qt::Key_F11), this, SLOT(toggleMaximize())); // Add actions to toolbar addButton(m_playAction, "playButton"); diff --git a/src/gui/editors/PianoRoll.cpp b/src/gui/editors/PianoRoll.cpp index f95603511..37951bc37 100644 --- a/src/gui/editors/PianoRoll.cpp +++ b/src/gui/editors/PianoRoll.cpp @@ -1117,7 +1117,10 @@ void PianoRoll::drawDetuningInfo( QPainter & _p, const Note * _n, int _x, { // Previous node values (based on outValue). We just calculate // the y level because the x will be the same as old_x. - const float pre_level = OUTVAL(it - 1); + const auto pit = std::prev(it); + const auto nit = std::next(it); + + const float pre_level = OUTVAL(pit); int pre_y = middle_y - pre_level * m_keyLineHeight; // Draws the line representing the discrete jump if there's one @@ -1142,7 +1145,7 @@ void PianoRoll::drawDetuningInfo( QPainter & _p, const Note * _n, int _x, // If we are in the last node and there's a discrete jump, we draw a // vertical line representing it - if ((it + 1) == map.end()) + if (nit == map.end()) { const float last_level = OUTVAL(it); if (cur_level != last_level) @@ -1631,6 +1634,8 @@ void PianoRoll::mousePressEvent(QMouseEvent * me ) return; } + const auto pos = position(me); + // -- Knife if (m_editMode == EditMode::Knife && me->button() == Qt::LeftButton) { @@ -1684,25 +1689,25 @@ void PianoRoll::mousePressEvent(QMouseEvent * me ) // keep track of the point where the user clicked down if( me->button() == Qt::LeftButton ) { - m_moveStartX = me->x(); - m_moveStartY = me->y(); + m_moveStartX = pos.x(); + m_moveStartY = pos.y(); } - if(me->button() == Qt::LeftButton && - me->y() > keyAreaBottom() && me->y() < noteEditTop()) + if (me->button() == Qt::LeftButton + && pos.y() > keyAreaBottom() && pos.y() < noteEditTop()) { // resizing the note edit area m_action = Action::ResizeNoteEditArea; return; } - if( me->y() > PR_TOP_MARGIN ) + if (pos.y() > PR_TOP_MARGIN) { - bool edit_note = ( me->y() > noteEditTop() ); + bool edit_note = (pos.y() > noteEditTop()); - int key_num = getKey( me->y() ); + int key_num = getKey(pos.y()); - int x = me->x(); + int x = pos.x(); if (x > m_whiteKeyWidth) @@ -1959,7 +1964,7 @@ void PianoRoll::mousePressEvent(QMouseEvent * me ) update(); } - else if( me->y() < keyAreaBottom() ) + else if (pos.y() < keyAreaBottom()) { // reference to last key needed for both // right click (used for copy all keys on note) @@ -1970,8 +1975,8 @@ void PianoRoll::mousePressEvent(QMouseEvent * me ) if( me->buttons() == Qt::RightButton ) { // right click - tone marker contextual menu - m_pianoKeySelected = getKey( me->y() ); - m_semiToneMarkerMenu->popup( mapToGlobal( QPoint( me->x(), me->y() ) ) ); + m_pianoKeySelected = getKey(pos.y()); + m_semiToneMarkerMenu->popup(mapToGlobal(pos)); } else if( me->buttons() == Qt::LeftButton ) { @@ -1997,7 +2002,7 @@ void PianoRoll::mousePressEvent(QMouseEvent * me ) else if( me->buttons() == Qt::RightButton ) { // pop menu asking which one they want to edit - m_noteEditMenu->popup( mapToGlobal( QPoint( me->x(), me->y() ) ) ); + m_noteEditMenu->popup(mapToGlobal(pos)); } } } @@ -2013,13 +2018,15 @@ void PianoRoll::mouseDoubleClickEvent(QMouseEvent * me ) return; } + const auto pos = position(me); + // if they clicked in the note edit area, enter value for the volume bar - if( me->x() > noteEditLeft() && me->x() < noteEditRight() - && me->y() > noteEditTop() && me->y() < noteEditBottom() ) + if (pos.x() > noteEditLeft() && pos.x() < noteEditRight() + && pos.y() > noteEditTop() && pos.y() < noteEditBottom()) { // get values for going through notes int pixel_range = 4; - int x = me->x() - m_whiteKeyWidth; + int x = pos.x() - m_whiteKeyWidth; const int ticks_start = ( x-pixel_range/2 ) * TimePos::ticksPerBar() / m_ppb + m_currentPosition; const int ticks_end = ( x+pixel_range/2 ) * @@ -2407,11 +2414,13 @@ void PianoRoll::mouseMoveEvent( QMouseEvent * me ) return; } + const auto pos = position(me); + if( m_action == Action::None && me->buttons() == 0 ) { // When cursor is between note editing area and volume/panning // area show vertical size cursor. - if( me->y() > keyAreaBottom() && me->y() < noteEditTop() ) + if (pos.y() > keyAreaBottom() && pos.y() < noteEditTop()) { setCursor( Qt::SizeVerCursor ); return; @@ -2420,12 +2429,12 @@ void PianoRoll::mouseMoveEvent( QMouseEvent * me ) else if( m_action == Action::ResizeNoteEditArea ) { // Don't try to show more keys than the full keyboard, bail if trying to - if (m_pianoKeysVisible == NumKeys && me->y() > m_moveStartY) + if (m_pianoKeysVisible == NumKeys && pos.y() > m_moveStartY) { return; } - int newHeight = height() - me->y(); - if (me->y() < KEY_AREA_MIN_HEIGHT) + int newHeight = height() - pos.y(); + if (pos.y() < KEY_AREA_MIN_HEIGHT) { newHeight = height() - KEY_AREA_MIN_HEIGHT - PR_TOP_MARGIN - PR_BOTTOM_MARGIN; // - NOTE_EDIT_RESIZE_BAR @@ -2452,14 +2461,14 @@ void PianoRoll::mouseMoveEvent( QMouseEvent * me ) updateStrumPos(me, false, me->modifiers() & Qt::ShiftModifier); } - if( me->y() > PR_TOP_MARGIN || m_action != Action::None ) + if (pos.y() > PR_TOP_MARGIN || m_action != Action::None) { - bool edit_note = ( me->y() > noteEditTop() ) - && m_action != Action::SelectNotes; + bool edit_note = (pos.y() > noteEditTop()) + && m_action != Action::SelectNotes; - int key_num = getKey( me->y() ); - int x = me->x(); + int key_num = getKey(pos.y()); + int x = pos.x(); // see if they clicked on the keyboard on the left if (x < m_whiteKeyWidth && m_action == Action::None @@ -2488,8 +2497,8 @@ void PianoRoll::mouseMoveEvent( QMouseEvent * me ) } dragNotes( - me->x(), - me->y(), + pos.x(), + pos.y(), me->modifiers() & Qt::AltModifier, me->modifiers() & Qt::ShiftModifier, me->modifiers() & Qt::ControlModifier @@ -2528,29 +2537,26 @@ void PianoRoll::mouseMoveEvent( QMouseEvent * me ) if( me->buttons() & Qt::LeftButton ) { - vol = qBound( MinVolume, - MinVolume + - ( ( (float)noteEditBottom() ) - ( (float)me->y() ) ) / - ( (float)( noteEditBottom() - noteEditTop() ) ) * - ( MaxVolume - MinVolume ), - MaxVolume ); - pan = qBound( PanningLeft, - PanningLeft + - ( (float)( noteEditBottom() - me->y() ) ) / - ( (float)( noteEditBottom() - noteEditTop() ) ) * - ( (float)( PanningRight - PanningLeft ) ), - PanningRight); + vol = qBound(MinVolume, static_cast(MinVolume + + static_cast(noteEditBottom() - pos.y()) + / static_cast(noteEditBottom() - noteEditTop()) + * (MaxVolume - MinVolume)), MaxVolume); + + pan = qBound(PanningLeft, static_cast(PanningLeft + + static_cast(noteEditBottom() - pos.y()) + / static_cast(noteEditBottom() - noteEditTop()) + * (PanningRight - PanningLeft)), PanningRight); } if( m_noteEditMode == NoteEditMode::Volume ) { m_lastNoteVolume = vol; - showVolTextFloat( vol, me->pos() ); + showVolTextFloat(vol, position(me)); } else if( m_noteEditMode == NoteEditMode::Panning ) { m_lastNotePanning = pan; - showPanTextFloat( pan, me->pos() ); + showPanTextFloat(pan, position(me)); } // When alt is pressed we only edit the note under the cursor @@ -2746,8 +2752,8 @@ void PianoRoll::mouseMoveEvent( QMouseEvent * me ) setCursor( Qt::ArrowCursor ); } - m_lastMouseX = me->x(); - m_lastMouseY = me->y(); + m_lastMouseX = pos.x(); + m_lastMouseY = pos.y(); update(); } @@ -2757,9 +2763,11 @@ void PianoRoll::mouseMoveEvent( QMouseEvent * me ) void PianoRoll::updateKnifePos(QMouseEvent* me, bool initial) { + const auto pos = position(me); + // Calculate the TimePos from the mouse - int mouseViewportPosX = me->x() - m_whiteKeyWidth; - int mouseViewportPosY = keyAreaBottom() - 1 - me->y(); + int mouseViewportPosX = pos.x() - m_whiteKeyWidth; + int mouseViewportPosY = keyAreaBottom() - 1 - pos.y(); int mouseTickPos = mouseViewportPosX * TimePos::ticksPerBar() / m_ppb + m_currentPosition; int mouseKey = std::round(1.f * mouseViewportPosY / m_keyLineHeight) + m_startKey - 1; @@ -2824,16 +2832,17 @@ void PianoRoll::updateStrumPos(QMouseEvent* me, bool initial, bool warp) { if (!hasValidMidiClip()) { return; } // Calculate the TimePos from the mouse - int mouseViewportPos = me->x() - m_whiteKeyWidth; + const auto pos = position(me); + int mouseViewportPos = pos.x() - m_whiteKeyWidth; int mouseTickPos = mouseViewportPos * TimePos::ticksPerBar() / m_ppb + m_currentPosition; // Should we add quantization? probably not? if (initial) { m_strumStartTime = mouseTickPos; - m_strumStartVertical = me->y(); + m_strumStartVertical = pos.y(); } m_strumCurrentTime = mouseTickPos; - m_strumCurrentVertical = me->y(); + m_strumCurrentVertical = pos.y(); int strumTicksHorizontal = m_strumCurrentTime - m_strumStartTime; float strumPower = fastPow10f(0.01f * (m_strumCurrentVertical - m_strumStartVertical)); @@ -3923,8 +3932,8 @@ void PianoRoll::wheelEvent(QWheelEvent * we ) { for ( Note * n : nv ) { - panning_t pan = qBound( PanningLeft, n->getPanning() + step, PanningRight ); - n->setPanning( pan ); + panning_t pan = qBound(PanningLeft, static_cast(n->getPanning() + step), PanningRight); + n->setPanning(pan); } bool allPansEqual = std::all_of( nv.begin(), nv.end(), [nv](const Note *note) @@ -4902,10 +4911,10 @@ PianoRollWindow::PianoRollWindow() : drawAction->setChecked( true ); - drawAction->setShortcut(combine(Qt::SHIFT, Qt::Key_D)); - eraseAction->setShortcut(combine(Qt::SHIFT, Qt::Key_E)); - selectAction->setShortcut(combine(Qt::SHIFT, Qt::Key_S)); - pitchBendAction->setShortcut(combine(Qt::SHIFT, Qt::Key_T)); + drawAction->setShortcut(keySequence(Qt::SHIFT, Qt::Key_D )); + eraseAction->setShortcut(keySequence(Qt::SHIFT, Qt::Key_E)); + selectAction->setShortcut(keySequence(Qt::SHIFT, Qt::Key_S)); + pitchBendAction->setShortcut(keySequence(Qt::SHIFT, Qt::Key_T)); connect( editModeGroup, SIGNAL(triggered(int)), m_editor, SLOT(setEditMode(int))); @@ -4964,9 +4973,9 @@ PianoRollWindow::PianoRollWindow() : auto pasteAction = new QAction(embed::getIconPixmap("edit_paste"), tr("Paste (%1+V)").arg(UI_CTRL_KEY), this); - cutAction->setShortcut(combine(Qt::CTRL, Qt::Key_X)); - copyAction->setShortcut(combine(Qt::CTRL, Qt::Key_C)); - pasteAction->setShortcut(combine(Qt::CTRL, Qt::Key_V)); + cutAction->setShortcut(keySequence(Qt::CTRL, Qt::Key_X)); + copyAction->setShortcut(keySequence(Qt::CTRL, Qt::Key_C)); + pasteAction->setShortcut(keySequence(Qt::CTRL, Qt::Key_V)); connect( cutAction, SIGNAL(triggered()), m_editor, SLOT(cutSelectedNotes())); connect( copyAction, SIGNAL(triggered()), m_editor, SLOT(copySelectedNotes())); @@ -4987,23 +4996,23 @@ PianoRollWindow::PianoRollWindow() : auto glueAction = new QAction(embed::getIconPixmap("glue"), tr("Glue"), noteToolsButton); connect(glueAction, SIGNAL(triggered()), m_editor, SLOT(glueNotes())); - glueAction->setShortcut(combine(Qt::SHIFT, Qt::Key_G)); + glueAction->setShortcut(keySequence(Qt::SHIFT, Qt::Key_G)); auto knifeAction = new QAction(embed::getIconPixmap("edit_knife"), tr("Knife"), noteToolsButton); connect(knifeAction, &QAction::triggered, m_editor, &PianoRoll::setKnifeAction); - knifeAction->setShortcut(combine(Qt::SHIFT, Qt::Key_K)); + knifeAction->setShortcut(keySequence(Qt::SHIFT, Qt::Key_K)); auto strumAction = new QAction(embed::getIconPixmap("arp_free"), tr("Strum"), noteToolsButton); connect(strumAction, &QAction::triggered, m_editor, &PianoRoll::setStrumAction); - strumAction->setShortcut(combine(Qt::SHIFT, Qt::Key_J)); + strumAction->setShortcut(keySequence(Qt::SHIFT, Qt::Key_J)); auto fillAction = new QAction(embed::getIconPixmap("fill"), tr("Fill"), noteToolsButton); connect(fillAction, &QAction::triggered, [this](){ m_editor->fitNoteLengths(true); }); - fillAction->setShortcut(combine(Qt::SHIFT, Qt::Key_F)); + fillAction->setShortcut(keySequence(Qt::SHIFT, Qt::Key_F)); auto cutOverlapsAction = new QAction(embed::getIconPixmap("cut_overlaps"), tr("Cut overlaps"), noteToolsButton); connect(cutOverlapsAction, &QAction::triggered, [this](){ m_editor->fitNoteLengths(false); }); - cutOverlapsAction->setShortcut(combine(Qt::SHIFT, Qt::Key_C)); + cutOverlapsAction->setShortcut(keySequence(Qt::SHIFT, Qt::Key_C)); auto minLengthAction = new QAction(embed::getIconPixmap("min_length"), tr("Min length as last"), noteToolsButton); connect(minLengthAction, &QAction::triggered, [this](){ m_editor->constrainNoteLengths(false); }); @@ -5013,7 +5022,7 @@ PianoRollWindow::PianoRollWindow() : auto reverseAction = new QAction(embed::getIconPixmap("flip_x"), tr("Reverse Notes"), noteToolsButton); connect(reverseAction, &QAction::triggered, [this](){ m_editor->reverseNotes(); }); - reverseAction->setShortcut(combine(Qt::SHIFT, Qt::Key_R)); + reverseAction->setShortcut(keySequence(Qt::SHIFT, Qt::Key_R)); noteToolsButton->addAction(glueAction); noteToolsButton->addAction(knifeAction); diff --git a/src/gui/editors/SongEditor.cpp b/src/gui/editors/SongEditor.cpp index 64743a52c..a5119373f 100644 --- a/src/gui/editors/SongEditor.cpp +++ b/src/gui/editors/SongEditor.cpp @@ -587,11 +587,13 @@ void SongEditor::closeEvent( QCloseEvent * ce ) void SongEditor::mousePressEvent(QMouseEvent *me) { + const auto pos = position(me); + if (allowRubberband()) { //we save the position of scrollbars, mouse position and zooming level m_scrollPos = QPoint(m_leftRightScroll->value(), contentWidget()->verticalScrollBar()->value()); - m_origin = contentWidget()->mapFromParent(QPoint(me->pos().x(), me->pos().y())); + m_origin = contentWidget()->mapFromParent(pos); m_rubberbandPixelsPerBar = pixelsPerBar(); //paint the rubberband @@ -600,8 +602,8 @@ void SongEditor::mousePressEvent(QMouseEvent *me) rubberBand()->show(); //the trackView(index) and the time position where the mouse was clicked - m_rubberBandStartTrackview = trackIndexFromSelectionPoint(me->y()); - m_rubberbandStartTimePos = TimePos((me->x() - m_trackHeadWidth) + m_rubberBandStartTrackview = trackIndexFromSelectionPoint(pos.y()); + m_rubberbandStartTimePos = TimePos((pos.x() - m_trackHeadWidth) / pixelsPerBar() * TimePos::ticksPerBar()) + m_currentPosition; } @@ -613,7 +615,7 @@ void SongEditor::mousePressEvent(QMouseEvent *me) void SongEditor::mouseMoveEvent(QMouseEvent *me) { - m_mousePos = me->pos(); + m_mousePos = position(me); updateRubberband(); QWidget::mouseMoveEvent(me); } diff --git a/src/gui/editors/TimeLineWidget.cpp b/src/gui/editors/TimeLineWidget.cpp index d87fbfe15..a10d2dc07 100644 --- a/src/gui/editors/TimeLineWidget.cpp +++ b/src/gui/editors/TimeLineWidget.cpp @@ -33,6 +33,7 @@ #include #include "ConfigManager.h" +#include "DeprecationHelper.h" #include "embed.h" #include "KeyboardShortcuts.h" #include "NStateButton.h" @@ -239,8 +240,10 @@ auto TimeLineWidget::getClickedTime(const int xPosition) const -> TimePos auto TimeLineWidget::getLoopAction(QMouseEvent* event) const -> TimeLineWidget::Action { + const auto pos = position(event); + const auto mode = ConfigManager::inst()->value("app", "loopmarkermode"); - const auto xPos = event->x(); + const auto xPos = pos.x(); const auto button = event->button(); if (mode == "handles") @@ -283,7 +286,9 @@ auto TimeLineWidget::actionCursor(Action action) const -> QCursor void TimeLineWidget::mousePressEvent(QMouseEvent* event) { - if (event->x() < m_xOffset) { return; } + const auto pos = position(event); + + if (pos.x() < m_xOffset) { return; } const auto shift = event->modifiers() & Qt::ShiftModifier; const auto ctrl = event->modifiers() & Qt::ControlModifier; @@ -295,14 +300,14 @@ void TimeLineWidget::mousePressEvent(QMouseEvent* event) if (m_action == Action::MoveLoop) { - m_dragStartPos = getClickedTime(event->x()); + m_dragStartPos = getClickedTime(pos.x()); m_oldLoopPos = {m_timeline->loopBegin(), m_timeline->loopEnd()}; } } else if (event->button() == Qt::LeftButton && ctrl) // selection { m_action = Action::SelectSongClip; - m_initalXSelect = event->x(); + m_initalXSelect = pos.x(); } else if (event->button() == Qt::LeftButton && !ctrl) // move playhead { @@ -326,7 +331,9 @@ void TimeLineWidget::mouseMoveEvent( QMouseEvent* event ) { parentWidget()->update(); // essential for widgets that this timeline had taken their mouse move event from. - auto timeAtCursor = getClickedTime(event->x()); + const auto pos = position(event); + + auto timeAtCursor = getClickedTime(pos.x()); const auto control = event->modifiers() & Qt::ControlModifier; switch( m_action ) @@ -387,7 +394,7 @@ void TimeLineWidget::mouseMoveEvent( QMouseEvent* event ) break; } case Action::SelectSongClip: - emit regionSelectedFromPixels( m_initalXSelect , event->x() ); + emit regionSelectedFromPixels(m_initalXSelect, pos.x()); break; default: diff --git a/src/gui/embed.cpp b/src/gui/embed.cpp index b47e2d75f..bd08027dc 100644 --- a/src/gui/embed.cpp +++ b/src/gui/embed.cpp @@ -110,7 +110,7 @@ auto getIconPixmap(std::string_view name, int width, int height, const char* con const auto pixmapName = QString::fromUtf8(name.data(), name.size()); const auto cacheName = (width > 0 && height > 0) - ? QStringLiteral("%1_%2_%3").arg(pixmapName, width, height) + ? QStringLiteral("%1_%2_%3").arg(pixmapName).arg(width).arg(height) : pixmapName; // Return cached pixmap if it exists diff --git a/src/gui/instrument/PianoView.cpp b/src/gui/instrument/PianoView.cpp index 0f7fbc9dd..34b280a9b 100644 --- a/src/gui/instrument/PianoView.cpp +++ b/src/gui/instrument/PianoView.cpp @@ -45,6 +45,7 @@ #include #include "AutomatableModelView.h" +#include "DeprecationHelper.h" #include "PianoView.h" #include "Piano.h" #include "CaptionMenu.h" @@ -417,11 +418,13 @@ void PianoView::mousePressEvent(QMouseEvent *me) { if (me->button() == Qt::LeftButton && m_piano != nullptr) { + const auto pos = position(me); + // get pressed key - int key_num = getKeyFromMouse(me->pos()); - if (me->pos().y() > PIANO_BASE) + int key_num = getKeyFromMouse(pos); + if (pos.y() > PIANO_BASE) { - int y_diff = me->pos().y() - PIANO_BASE; + int y_diff = pos.y() - PIANO_BASE; int velocity = static_cast( static_cast(y_diff) / getKeyHeight(key_num) * m_piano->instrumentTrack()->midiPort()->baseVelocity()); @@ -519,8 +522,10 @@ void PianoView::mouseMoveEvent( QMouseEvent * _me ) return; } - int key_num = getKeyFromMouse( _me->pos() ); - int y_diff = _me->pos().y() - PIANO_BASE; + const auto pos = position(_me); + + int key_num = getKeyFromMouse(pos); + int y_diff = pos.y() - PIANO_BASE; int velocity = (int)( (float) y_diff / ( Piano::isWhiteKey( key_num ) ? PW_WHITE_KEY_HEIGHT : PW_BLACK_KEY_HEIGHT ) * @@ -551,7 +556,7 @@ void PianoView::mouseMoveEvent( QMouseEvent * _me ) } if( _me->buttons() & Qt::LeftButton ) { - if( _me->pos().y() > PIANO_BASE ) + if (pos.y() > PIANO_BASE) { m_piano->midiEventProcessor()->processInEvent( MidiEvent( MidiNoteOn, -1, key_num, velocity ) ); m_piano->setKeyState( key_num, true ); diff --git a/src/gui/modals/SetupDialog.cpp b/src/gui/modals/SetupDialog.cpp index 4ea0d4ddd..242b4f46c 100644 --- a/src/gui/modals/SetupDialog.cpp +++ b/src/gui/modals/SetupDialog.cpp @@ -550,8 +550,13 @@ SetupDialog::SetupDialog(ConfigTab tab_to_open) : setCurrentIndex(m_audioInterfaces->findText(audioDevName)); m_audioIfaceSetupWidgets[audioDevName]->show(); - connect(m_audioInterfaces, SIGNAL(activated(const QString&)), - this, SLOT(audioInterfaceChanged(const QString&))); + connect(m_audioInterfaces, +#if (QT_VERSION < QT_VERSION_CHECK(5, 14, 0)) + QOverload::of(&QComboBox::activated), +#else + &QComboBox::textActivated, +#endif + this, &SetupDialog::audioInterfaceChanged); // Advanced setting, hidden for now // // TODO Handle or remove. @@ -725,9 +730,13 @@ SetupDialog::SetupDialog(ConfigTab tab_to_open) : m_midiInterfaces->setCurrentIndex(m_midiInterfaces->findText(midiDevName)); m_midiIfaceSetupWidgets[midiDevName]->show(); - connect(m_midiInterfaces, SIGNAL(activated(const QString&)), - this, SLOT(midiInterfaceChanged(const QString&))); - + connect(m_midiInterfaces, +#if (QT_VERSION < QT_VERSION_CHECK(5, 14, 0)) + QOverload::of(&QComboBox::activated), +#else + &QComboBox::textActivated, +#endif + this, &SetupDialog::midiInterfaceChanged); // MIDI autoassign group QGroupBox * midiAutoAssignBox = new QGroupBox(tr("Automatically assign MIDI controller to selected track"), midi_w); diff --git a/src/gui/tracks/AutomationTrackView.cpp b/src/gui/tracks/AutomationTrackView.cpp index 53e022c15..aeabde61d 100644 --- a/src/gui/tracks/AutomationTrackView.cpp +++ b/src/gui/tracks/AutomationTrackView.cpp @@ -26,6 +26,7 @@ #include "AutomationTrackView.h" #include "AutomationClip.h" #include "AutomationTrack.h" +#include "DeprecationHelper.h" #include "embed.h" #include "Engine.h" #include "ProjectJournal.h" @@ -64,13 +65,10 @@ void AutomationTrackView::dropEvent( QDropEvent * _de ) auto mod = dynamic_cast(Engine::projectJournal()->journallingObject(val.toInt())); if( mod != nullptr ) { - TimePos pos = TimePos( trackContainerView()-> - currentPosition() + - ( _de->pos().x() - - getTrackContentWidget()->x() ) * - TimePos::ticksPerBar() / - static_cast( trackContainerView()->pixelsPerBar() ) ) - .toAbsoluteBar(); + const int deX = position(_de).x(); + TimePos pos = TimePos(trackContainerView()->currentPosition() + + (deX - getTrackContentWidget()->x()) * TimePos::ticksPerBar() + / static_cast(trackContainerView()->pixelsPerBar())).toAbsoluteBar(); if( pos.getTicks() < 0 ) { diff --git a/src/gui/tracks/SampleTrackView.cpp b/src/gui/tracks/SampleTrackView.cpp index f70d2c3bf..ffccfda38 100644 --- a/src/gui/tracks/SampleTrackView.cpp +++ b/src/gui/tracks/SampleTrackView.cpp @@ -31,6 +31,7 @@ #include #include "ConfigManager.h" +#include "DeprecationHelper.h" #include "embed.h" #include "Engine.h" #include "FadeButton.h" @@ -207,9 +208,10 @@ void SampleTrackView::dropEvent(QDropEvent *de) ? DEFAULT_SETTINGS_WIDGET_WIDTH_COMPACT + TRACK_OP_WIDTH_COMPACT : DEFAULT_SETTINGS_WIDGET_WIDTH + TRACK_OP_WIDTH; - int xPos = de->pos().x() < trackHeadWidth + const int deX = position(de).x(); + int xPos = deX < trackHeadWidth ? trackHeadWidth - : de->pos().x(); + : deX; const float snapSize = getGUI()->songEditor()->m_editor->getSnapSize(); TimePos clipPos = trackContainerView()->fixedClips() diff --git a/src/gui/tracks/TrackContentWidget.cpp b/src/gui/tracks/TrackContentWidget.cpp index 974212628..086a77c12 100644 --- a/src/gui/tracks/TrackContentWidget.cpp +++ b/src/gui/tracks/TrackContentWidget.cpp @@ -32,6 +32,7 @@ #include "AutomationClip.h" #include "Clipboard.h" #include "DataFile.h" +#include "DeprecationHelper.h" #include "Engine.h" #include "GuiApplication.h" #include "PatternEditor.h" @@ -321,7 +322,7 @@ TimePos TrackContentWidget::getPosition( int mouseX ) */ void TrackContentWidget::dragEnterEvent( QDragEnterEvent * dee ) { - TimePos clipPos = getPosition( dee->pos().x() ); + TimePos clipPos = getPosition(position(dee).x()); if( canPasteSelection( clipPos, dee ) == false ) { dee->ignore(); @@ -557,7 +558,9 @@ bool TrackContentWidget::pasteSelection( TimePos clipPos, const QMimeData * md, */ void TrackContentWidget::dropEvent( QDropEvent * de ) { - TimePos clipPos = TimePos( getPosition( de->pos().x() ) ); + const auto pos = position(de); + + TimePos clipPos = TimePos(getPosition(pos.x())); if( pasteSelection( clipPos, de ) == true ) { de->accept(); @@ -573,6 +576,8 @@ void TrackContentWidget::dropEvent( QDropEvent * de ) */ void TrackContentWidget::mousePressEvent( QMouseEvent * me ) { + const auto pos = position(me); + // Enable box select if control is held when clicking an empty space // (If we had clicked a Clip it would have intercepted the mouse event) if( me->modifiers() & Qt::ControlModifier ){ @@ -599,8 +604,8 @@ void TrackContentWidget::mousePressEvent( QMouseEvent * me ) } getTrack()->addJournalCheckPoint(); const float snapSize = getGUI()->songEditor()->m_editor->getSnapSize(); - const TimePos pos = TimePos(getPosition(me->x())).quantize(snapSize, true); - getTrack()->createClip(pos); + const TimePos timePos = TimePos(getPosition(pos.x())).quantize(snapSize, true); + getTrack()->createClip(timePos); } } diff --git a/src/gui/tracks/TrackLabelButton.cpp b/src/gui/tracks/TrackLabelButton.cpp index b8dcc333b..92c946b3c 100644 --- a/src/gui/tracks/TrackLabelButton.cpp +++ b/src/gui/tracks/TrackLabelButton.cpp @@ -29,6 +29,7 @@ #include #include "ConfigManager.h" +#include "DeprecationHelper.h" #include "embed.h" #include "Instrument.h" #include "InstrumentTrack.h" @@ -181,7 +182,8 @@ void TrackLabelButton::mouseDoubleClickEvent( QMouseEvent * _me ) void TrackLabelButton::mouseReleaseEvent( QMouseEvent *_me ) { - if( m_buttonRect.contains( _me->globalPos(), true ) && m_renameLineEdit->isHidden() ) + const auto globalPos = globalPosition(_me); + if (m_buttonRect.contains(globalPos, true) && m_renameLineEdit->isHidden()) { QToolButton::mousePressEvent( _me ); } diff --git a/src/gui/tracks/TrackOperationsWidget.cpp b/src/gui/tracks/TrackOperationsWidget.cpp index d6ddc7027..458877701 100644 --- a/src/gui/tracks/TrackOperationsWidget.cpp +++ b/src/gui/tracks/TrackOperationsWidget.cpp @@ -175,10 +175,16 @@ bool TrackOperationsWidget::confirmRemoval() QString messageTitleRemoveTrack = tr("Confirm removal"); QString askAgainText = tr("Don't ask again"); auto askAgainCheckBox = new QCheckBox(askAgainText, nullptr); - connect(askAgainCheckBox, &QCheckBox::stateChanged, [](int state){ + auto onCheckedStateChanged = [](auto state){ // Invert button state, if it's checked we *shouldn't* ask again - ConfigManager::inst()->setValue("ui", "trackdeletionwarning", state ? "0" : "1"); - }); + ConfigManager::inst()->setValue("ui", "trackdeletionwarning", state != Qt::Unchecked ? "0" : "1"); + }; + +#if (QT_VERSION >= QT_VERSION_CHECK(6, 7, 0)) + connect(askAgainCheckBox, &QCheckBox::checkStateChanged, onCheckedStateChanged); +#else + connect(askAgainCheckBox, &QCheckBox::stateChanged, onCheckedStateChanged); +#endif QMessageBox mb; mb.setText(messageRemoveTrack); diff --git a/src/gui/tracks/TrackView.cpp b/src/gui/tracks/TrackView.cpp index 6388b7fb2..1d282338f 100644 --- a/src/gui/tracks/TrackView.cpp +++ b/src/gui/tracks/TrackView.cpp @@ -36,6 +36,7 @@ #include "AutomatableButton.h" #include "ConfigManager.h" #include "DataFile.h" +#include "DeprecationHelper.h" #include "Engine.h" #include "FadeButton.h" #include "StringPairDrag.h" @@ -259,6 +260,7 @@ void TrackView::dropEvent( QDropEvent * de ) */ void TrackView::mousePressEvent( QMouseEvent * me ) { + const auto pos = position(me); // If previously dragged too small, restore on shift-leftclick if( height() < DEFAULT_TRACK_HEIGHT && @@ -274,7 +276,7 @@ void TrackView::mousePressEvent( QMouseEvent * me ) "compacttrackbuttons" ).toInt()==1 ? DEFAULT_SETTINGS_WIDGET_WIDTH_COMPACT + TRACK_OP_WIDTH_COMPACT : DEFAULT_SETTINGS_WIDGET_WIDTH + TRACK_OP_WIDTH; - if( m_trackContainerView->allowRubberband() == true && me->x() > widgetTotal ) + if (m_trackContainerView->allowRubberband() == true && pos.x() > widgetTotal) { QWidget::mousePressEvent( me ); } @@ -283,10 +285,8 @@ void TrackView::mousePressEvent( QMouseEvent * me ) if( me->modifiers() & Qt::ShiftModifier ) { m_action = Action::Resize; - QCursor::setPos( mapToGlobal( QPoint( me->x(), - height() ) ) ); - QCursor c( Qt::SizeVerCursor); - QApplication::setOverrideCursor( c ); + QCursor::setPos(mapToGlobal(QPoint(pos.x(), height()))); + QApplication::setOverrideCursor(Qt::SizeVerCursor); } me->accept(); @@ -318,11 +318,13 @@ void TrackView::mousePressEvent( QMouseEvent * me ) */ void TrackView::mouseMoveEvent( QMouseEvent * me ) { + const auto pos = position(me); + int widgetTotal = ConfigManager::inst()->value( "ui", "compacttrackbuttons" ).toInt()==1 ? DEFAULT_SETTINGS_WIDGET_WIDTH_COMPACT + TRACK_OP_WIDTH_COMPACT : DEFAULT_SETTINGS_WIDGET_WIDTH + TRACK_OP_WIDTH; - if( m_trackContainerView->allowRubberband() == true && me->x() > widgetTotal ) + if (m_trackContainerView->allowRubberband() == true && pos.x() > widgetTotal) { QWidget::mouseMoveEvent( me ); } @@ -330,7 +332,7 @@ void TrackView::mouseMoveEvent( QMouseEvent * me ) { // look which track-widget the mouse-cursor is over const int yPos = - m_trackContainerView->contentWidget()->mapFromGlobal( me->globalPos() ).y(); + m_trackContainerView->contentWidget()->mapFromGlobal(globalPosition(me)).y(); const TrackView * trackAtY = m_trackContainerView->trackViewAt( yPos ); // debug code @@ -340,7 +342,7 @@ void TrackView::mouseMoveEvent( QMouseEvent * me ) if( trackAtY != nullptr && trackAtY != this ) { // then move us up/down there! - if( me->y() < 0 ) + if (pos.y() < 0) { m_trackContainerView->moveTrackViewUp( this ); } @@ -352,7 +354,7 @@ void TrackView::mouseMoveEvent( QMouseEvent * me ) } else if( m_action == Action::Resize ) { - resizeToHeight(me->y()); + resizeToHeight(pos.y()); } if( height() < DEFAULT_TRACK_HEIGHT ) @@ -393,7 +395,9 @@ void TrackView::wheelEvent(QWheelEvent* we) { resizeToHeight(height() + stepSize * direction); we->accept(); + return; } + we->ignore(); } diff --git a/src/gui/widgets/ComboBox.cpp b/src/gui/widgets/ComboBox.cpp index 3683cd68c..e9d127e7f 100644 --- a/src/gui/widgets/ComboBox.cpp +++ b/src/gui/widgets/ComboBox.cpp @@ -33,6 +33,7 @@ #include "CaptionMenu.h" #include "FontHelper.h" +#include "DeprecationHelper.h" #define QT_SUPPORTS_WIDGET_SCREEN (QT_VERSION >= QT_VERSION_CHECK(5,14,0)) #if !QT_SUPPORTS_WIDGET_SCREEN @@ -105,9 +106,11 @@ void ComboBox::mousePressEvent( QMouseEvent* event ) return; } + const auto pos = position(event); + if( event->button() == Qt::LeftButton && ! ( event->modifiers() & Qt::ControlModifier ) ) { - if( event->x() > width() - CB_ARROW_BTN_WIDTH ) + if (pos.x() > width() - CB_ARROW_BTN_WIDTH) { m_pressed = true; update(); diff --git a/src/gui/widgets/Fader.cpp b/src/gui/widgets/Fader.cpp index f7f9ce72b..ae72e1235 100644 --- a/src/gui/widgets/Fader.cpp +++ b/src/gui/widgets/Fader.cpp @@ -54,6 +54,7 @@ #include "lmms_math.h" #include "CaptionMenu.h" #include "ConfigManager.h" +#include "DeprecationHelper.h" #include "KeyboardShortcuts.h" #include "SimpleTextFloat.h" @@ -172,7 +173,7 @@ void Fader::contextMenuEvent(QContextMenuEvent* ev) void Fader::mouseMoveEvent(QMouseEvent* mouseEvent) { - const int localY = mouseEvent->y(); + const int localY = position(mouseEvent).y(); setVolumeByLocalPixelValue(localY); @@ -186,6 +187,8 @@ void Fader::mouseMoveEvent(QMouseEvent* mouseEvent) void Fader::mousePressEvent(QMouseEvent* mouseEvent) { + const auto pos = position(mouseEvent); + if (mouseEvent->button() == Qt::LeftButton && !(mouseEvent->modifiers() & KBD_COPY_MODIFIER)) { @@ -196,7 +199,7 @@ void Fader::mousePressEvent(QMouseEvent* mouseEvent) thisModel->saveJournallingState(false); } - const int localY = mouseEvent->y(); + const int localY = pos.y(); const auto knobLowerPosY = calculateKnobPosYFromModel(); const auto knobUpperPosY = knobLowerPosY - m_knobSize.height(); diff --git a/src/gui/widgets/FloatModelEditorBase.cpp b/src/gui/widgets/FloatModelEditorBase.cpp index ed09fa261..357505337 100644 --- a/src/gui/widgets/FloatModelEditorBase.cpp +++ b/src/gui/widgets/FloatModelEditorBase.cpp @@ -30,6 +30,7 @@ #include #include "lmms_math.h" +#include "DeprecationHelper.h" #include "CaptionMenu.h" #include "ControllerConnection.h" #include "GuiApplication.h" @@ -166,8 +167,7 @@ void FloatModelEditorBase::mousePressEvent(QMouseEvent * me) thisModel->saveJournallingState(false); } - const QPoint & p = me->pos(); - m_lastMousePos = p; + m_lastMousePos = position(me); m_leftOver = 0.0f; emit sliderPressed(); @@ -196,13 +196,15 @@ void FloatModelEditorBase::mousePressEvent(QMouseEvent * me) void FloatModelEditorBase::mouseMoveEvent(QMouseEvent * me) { - if (m_buttonPressed && me->pos() != m_lastMousePos) + const auto pos = position(me); + + if (m_buttonPressed && pos != m_lastMousePos) { // knob position is changed depending on last mouse position - setPosition(me->pos() - m_lastMousePos); + setPosition(pos - m_lastMousePos); emit sliderMoved(model()->value()); // original position for next time is current position - m_lastMousePos = me->pos(); + m_lastMousePos = pos; } s_textFloat->setText(displayValue()); s_textFloat->show(); @@ -229,8 +231,11 @@ void FloatModelEditorBase::mouseReleaseEvent(QMouseEvent* event) s_textFloat->hide(); } - -void FloatModelEditorBase::enterEvent(QEvent *event) +#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) +void FloatModelEditorBase::enterEvent(QEnterEvent*) +#else +void FloatModelEditorBase::enterEvent(QEvent*) +#endif { showTextFloat(700, 2000); } diff --git a/src/gui/widgets/Graph.cpp b/src/gui/widgets/Graph.cpp index 7b20e7499..4ce504400 100644 --- a/src/gui/widgets/Graph.cpp +++ b/src/gui/widgets/Graph.cpp @@ -26,6 +26,7 @@ #include #include "Graph.h" +#include "DeprecationHelper.h" #include "SampleLoader.h" #include "StringPairDrag.h" #include "Oscillator.h" @@ -99,9 +100,11 @@ void graph::loadSampleFromFile( const QString & _filename ) void Graph::mouseMoveEvent ( QMouseEvent * _me ) { + const auto pos = position(_me); + // get position - int x = _me->x(); - int y = _me->y(); + int x = pos.x(); + int y = pos.y(); /* static bool skip = false; @@ -146,13 +149,15 @@ void Graph::mouseMoveEvent ( QMouseEvent * _me ) void Graph::mousePressEvent( QMouseEvent * _me ) { + const auto pos = position(_me); + if( _me->button() == Qt::LeftButton ) { if ( !( _me->modifiers() & Qt::ShiftModifier ) ) { // get position - int x = _me->x(); - int y = _me->y(); + int x = pos.x(); + int y = pos.y(); changeSampleAt( x, y ); @@ -165,8 +170,8 @@ void Graph::mousePressEvent( QMouseEvent * _me ) { //when shift-clicking, draw a line from last position to current //position - int x = _me->x(); - int y = _me->y(); + int x = pos.x(); + int y = pos.y(); drawLineAt( x, y, m_lastCursorX ); diff --git a/src/gui/widgets/GroupBox.cpp b/src/gui/widgets/GroupBox.cpp index 041e11c43..60771a657 100644 --- a/src/gui/widgets/GroupBox.cpp +++ b/src/gui/widgets/GroupBox.cpp @@ -26,6 +26,7 @@ #include #include "GroupBox.h" +#include "DeprecationHelper.h" #include "embed.h" #include "FontHelper.h" @@ -81,7 +82,9 @@ void GroupBox::setLedButtonShown(bool value) void GroupBox::mousePressEvent( QMouseEvent * _me ) { - if (ledButtonShown() && _me->y() > 1 && _me->y() < 13 && _me->button() == Qt::LeftButton) + const auto pos = position(_me); + + if (ledButtonShown() && pos.y() > 1 && pos.y() < 13 && _me->button() == Qt::LeftButton) { model()->setValue(!model()->value()); } diff --git a/src/gui/widgets/LcdFloatSpinBox.cpp b/src/gui/widgets/LcdFloatSpinBox.cpp index 75762b8a1..98998a006 100644 --- a/src/gui/widgets/LcdFloatSpinBox.cpp +++ b/src/gui/widgets/LcdFloatSpinBox.cpp @@ -136,15 +136,17 @@ void LcdFloatSpinBox::contextMenuEvent(QContextMenuEvent* event) void LcdFloatSpinBox::mousePressEvent(QMouseEvent* event) { + const auto pos = position(event); + // switch between integer and fractional step based on cursor position - m_intStep = event->x() < m_wholeDisplay.width(); + m_intStep = pos.x() < m_wholeDisplay.width(); if (event->button() == Qt::LeftButton && !(event->modifiers() & KBD_COPY_MODIFIER) && - event->y() < m_wholeDisplay.cellHeight() + 2) + pos.y() < m_wholeDisplay.cellHeight() + 2) { m_mouseMoving = true; - m_origMousePos = event->globalPos(); + m_origMousePos = globalPosition(event); AutomatableModel *thisModel = model(); if (thisModel) @@ -164,13 +166,14 @@ void LcdFloatSpinBox::mouseMoveEvent(QMouseEvent* event) { if (m_mouseMoving) { - int dy = event->globalY() - m_origMousePos.y(); + const auto globalPos = globalPosition(event); + int dy = globalPos.y() - m_origMousePos.y(); if (getGUI()->mainWindow()->isShiftPressed()) { dy = qBound(-4, dy/4, 4); } if (dy > 1 || dy < -1) { model()->setValue(model()->value() - dy / 2 * getStep()); emit manualChange(); - m_origMousePos = event->globalPos(); + m_origMousePos = globalPos; } } } diff --git a/src/gui/widgets/LcdSpinBox.cpp b/src/gui/widgets/LcdSpinBox.cpp index 9d04d5fdb..0f383937f 100644 --- a/src/gui/widgets/LcdSpinBox.cpp +++ b/src/gui/widgets/LcdSpinBox.cpp @@ -30,6 +30,7 @@ #include "LcdSpinBox.h" #include "KeyboardShortcuts.h" #include "CaptionMenu.h" +#include "DeprecationHelper.h" namespace lmms::gui @@ -79,12 +80,14 @@ void LcdSpinBox::contextMenuEvent(QContextMenuEvent* event) void LcdSpinBox::mousePressEvent( QMouseEvent* event ) { - if( event->button() == Qt::LeftButton && - ! (event->modifiers() & KBD_COPY_MODIFIER) && - event->y() < cellHeight() + 2 ) + const auto pos = position(event); + + if (event->button() == Qt::LeftButton + && !(event->modifiers() & KBD_COPY_MODIFIER) + && pos.y() < cellHeight() + 2) { m_mouseMoving = true; - m_lastMousePos = event->globalPos(); + m_lastMousePos = globalPosition(event); AutomatableModel *thisModel = model(); if( thisModel ) @@ -106,7 +109,8 @@ void LcdSpinBox::mouseMoveEvent( QMouseEvent* event ) { if( m_mouseMoving ) { - int dy = event->globalY() - m_lastMousePos.y(); + const auto globalPos = globalPosition(event); + int dy = globalPos.y() - m_lastMousePos.y(); if( dy ) { auto fdy = static_cast(dy); @@ -119,7 +123,7 @@ void LcdSpinBox::mouseMoveEvent( QMouseEvent* event ) m_remainder = floatValNotRounded - floatValRounded; model()->setValue( floatValRounded ); emit manualChange(); - m_lastMousePos = event->globalPos(); + m_lastMousePos = globalPos; } } } diff --git a/src/gui/widgets/SimpleTextFloat.cpp b/src/gui/widgets/SimpleTextFloat.cpp index 89a45c7f7..4e08f4cfb 100644 --- a/src/gui/widgets/SimpleTextFloat.cpp +++ b/src/gui/widgets/SimpleTextFloat.cpp @@ -39,7 +39,7 @@ SimpleTextFloat::SimpleTextFloat() : QWidget(getGUI()->mainWindow(), Qt::ToolTip) { QHBoxLayout * layout = new QHBoxLayout(this); - layout->setMargin(3); + layout->setContentsMargins(3, 3, 3, 3); setLayout(layout); m_textLabel = new QLabel(this); diff --git a/src/gui/widgets/TabWidget.cpp b/src/gui/widgets/TabWidget.cpp index 81fae1c04..1990066f8 100644 --- a/src/gui/widgets/TabWidget.cpp +++ b/src/gui/widgets/TabWidget.cpp @@ -123,10 +123,10 @@ void TabWidget::setActiveTab(int idx) // Return the index of the tab at position "pos" -int TabWidget::findTabAtPos(const QPoint* pos) +int TabWidget::findTabAtPos(const QPoint& pos) { - if (pos->y() > 1 && pos->y() < m_tabbarHeight - 1) + if (pos.y() > 1 && pos.y() < m_tabbarHeight - 1) { int cx = ((m_caption == "") ? 4 : 14) + horizontalAdvance(fontMetrics(), m_caption); @@ -134,7 +134,7 @@ int TabWidget::findTabAtPos(const QPoint* pos) { int const currentWidgetWidth = it->nwidth; - if (pos->x() >= cx && pos->x() <= cx + currentWidgetWidth) + if (pos.x() >= cx && pos.x() <= cx + currentWidgetWidth) { return(it.key()); } @@ -155,7 +155,7 @@ bool TabWidget::event(QEvent* event) { auto helpEvent = static_cast(event); - int idx = findTabAtPos(& helpEvent->pos()); + int idx = findTabAtPos(helpEvent->pos()); if (idx != -1) { @@ -180,10 +180,8 @@ bool TabWidget::event(QEvent* event) // Activate tab when clicked void TabWidget::mousePressEvent(QMouseEvent* me) { - // Find index of tab that has been clicked - QPoint pos = me->pos(); - int idx = findTabAtPos(&pos); + const int idx = findTabAtPos(position(me)); // When found, activate tab that has been clicked if (idx != -1)