From 2bd862a0fbd9f6e89ee148752ca1eee8fa6817eb Mon Sep 17 00:00:00 2001 From: Rossmaxx <74815851+Rossmaxx@users.noreply.github.com> Date: Thu, 25 Apr 2024 09:28:14 +0530 Subject: [PATCH] Add experimental Qt 6 support flags. (#7182) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactored gui_templates.h * experimental qt6 support enabled * replace qt5_wrap_ui with cmake_autouic * Make the minimum code compile for Qt6 The following changes are applied to make the minimum build configuration compile: * Remove usage of a `QKeyEvent` constructor in `ColorChooser.h` by directly forwarding the original event. * Change `QMap` to `QMulitMap` in several places in `ControlLayout.h` because that's what in fact is used. * Change the parameter from `QEvent` to `QEnterEvent` in some `enterEvent` overrides. * Add an include for `algorithm` in `MixHelpers.cpp` * Fix a problem with string argument replacement in `embed.cpp` * Introduce the usage of `QKeySequence` including the replacement of the `+` operator with the `|` operator. * Add an include for `QActionGroup` in `ProjectNotes.cpp`. * Use `QPalette::window` instead of `QPalette::background` in `ClipView.cpp` * Use `qBound` instead of `qBound` in `PianoRoll.cpp`. Add a cast. * Replace the deprecated call to `QLayout::setMargin` with `QLayout::setContentsMargins` Note: there are still lots of warnings when you compile this state with Qt6! * Qt 5 support * Fix Qt5 build for ControlLayout Fix the Qt5 build for `ControlLayout` by intoducing typedefs depending on the Qt version and using these throughout `ControlLayout`. * Prepare LadspaMatrixControlDialog for Qt6 Use `setContentsMargins` instead of `setMargin`. * CMakeLists.txt adjustments for Qt6 Add the dependency to "Core5Compat" to the main CMakeLists.txt. It is needed so that we can use `QTextCodec` which is used by the Hydrogen importer plugin. Adjust the CMakeLists.txt of the ZynAddSubFx plugin so that it also makes use of `QT_VERSION_MAJOR` and therefore builds under Qt5 and Qt6. * force qt 5 on vst for now * cleanup qt5compat finding code * Fix build Fix the build that failed after the merge of master. The data type that `QColor::getRgbF` uses has changed between Qt5 and Qt6. This is solved with a using because changing the type to `float` which is used by Qt6 did not work with Qt5 either. * Fix warnings in AutomationClip.cpp Fix warnings in `AutomationClip.cpp`. These have been warnings of the type: "Warning: »QMap::const_iterator operator-(QMap::const_iterator, QMap::const_iterator::difference_type)« is deprecated: Use std::prev; QMap iterators are not random access [-Wdeprecated-declarations] * Fix warning in AutomationClipView Fix build warning about deprecated iterator operators in `AutomationClipView`. * Fix deprecated usage of x() and y() methods Fix the deprecated usage of the following methods: * `QMouseEvent:x()` * `QMouseEvent:y()` * `QDropEvent:x()` * `QDropEvent:y()` This is done by adding two new helper methods names `position` to `DeprecationHelper.h` and using these methods in the event methods. * Fix more iterator operator warnings Fix more warnings about iterator operators by using `std::prev` and `std::next`. * Fix QKeyCombination warning Fix warnings about `QKeyCombination::operator+`. * added minimum version check Co-authored-by: Dalton Messmer * zyn build fix for msvc qt6 --------- Co-authored-by: Michael Gregorius Co-authored-by: Dalton Messmer --- CMakeLists.txt | 59 ++++++--- cmake/install/CMakeLists.txt | 2 +- cmake/modules/BuildPlugin.cmake | 11 +- cmake/modules/GenQrc.cmake | 2 +- data/locale/CMakeLists.txt | 4 +- include/ColorChooser.h | 3 +- include/ColorHelper.h | 18 ++- include/ControlLayout.h | 12 +- include/DeprecationHelper.h | 30 +++++ include/FloatModelEditorBase.h | 5 + include/PluginBrowser.h | 7 +- .../AudioFileProcessorWaveView.cpp | 23 ++-- plugins/Delay/DelayControlsDialog.cpp | 11 +- .../LadspaMatrixControlDialog.cpp | 2 +- plugins/SlicerT/SlicerTWaveform.cpp | 23 ++-- plugins/ZynAddSubFx/CMakeLists.txt | 16 ++- src/CMakeLists.txt | 12 +- src/core/AutomationClip.cpp | 43 ++++--- src/core/MixHelpers.cpp | 2 + src/gui/ControlLayout.cpp | 6 +- src/gui/MainWindow.cpp | 34 +++--- src/gui/PluginBrowser.cpp | 9 +- src/gui/ProjectNotes.cpp | 1 + src/gui/clips/AutomationClipView.cpp | 12 +- src/gui/clips/ClipView.cpp | 15 ++- src/gui/clips/MidiClipView.cpp | 6 +- src/gui/editors/AutomationEditor.cpp | 52 ++++---- src/gui/editors/Editor.cpp | 4 +- src/gui/editors/PianoRoll.cpp | 115 ++++++++++-------- src/gui/editors/SongEditor.cpp | 6 +- src/gui/editors/TimeLineWidget.cpp | 19 ++- src/gui/embed.cpp | 2 +- src/gui/tracks/TrackContentWidget.cpp | 15 ++- src/gui/tracks/TrackView.cpp | 16 ++- src/gui/widgets/ComboBox.cpp | 5 +- src/gui/widgets/Fader.cpp | 5 +- src/gui/widgets/FloatModelEditorBase.cpp | 8 +- src/gui/widgets/Graph.cpp | 17 ++- src/gui/widgets/GroupBox.cpp | 5 +- src/gui/widgets/LcdFloatSpinBox.cpp | 4 +- src/gui/widgets/LcdSpinBox.cpp | 5 +- src/gui/widgets/SimpleTextFloat.cpp | 2 +- 42 files changed, 433 insertions(+), 215 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 48d1904f023..29330bf6b9d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -103,6 +103,7 @@ option(WANT_DEBUG_TSAN "Enable ThreadSanitizer" OFF) option(WANT_DEBUG_MSAN "Enable MemorySanitizer" OFF) option(WANT_DEBUG_UBSAN "Enable UndefinedBehaviorSanitizer" OFF) OPTION(BUNDLE_QT_TRANSLATIONS "Install Qt translation files for LMMS" OFF) +option(WANT_QT6 "Build with experimental Qt6 support" OFF) IF(LMMS_BUILD_APPLE) @@ -179,30 +180,59 @@ 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 REQUIRED) -FIND_PACKAGE(Qt5 COMPONENTS LinguistTools QUIET) +IF(WANT_QT6) + MESSAGE("Building with Qt6 is experimental, not guaranteed to succeed") + SET(QT_VERSION_MAJOR 6) + SET(LMMS_QT_MIN_VERSION 6.0.0) + SET(WANT_VST OFF) + SET(STATUS_VST "VSTs not supported with Qt 6") + SET(STATUS_QT6 "ENABLED") +ELSE() + SET(QT_VERSION_MAJOR 5) + SET(LMMS_QT_MIN_VERSION 5.9.0) + SET(STATUS_QT6 "NOT ENABLED") +ENDIF() + +FIND_PACKAGE(Qt${QT_VERSION_MAJOR} ${LMMS_QT_MIN_VERSION} COMPONENTS Core Gui Widgets Xml REQUIRED) +FIND_PACKAGE(Qt${QT_VERSION_MAJOR} COMPONENTS LinguistTools QUIET) INCLUDE_DIRECTORIES( - ${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 + Qt${QT_VERSION_MAJOR}::Core + Qt${QT_VERSION_MAJOR}::Gui + Qt${QT_VERSION_MAJOR}::Widgets + Qt${QT_VERSION_MAJOR}::Xml ) +IF(WANT_QT6) + # Core5Compat is needed so that we get QTextCodec which is used by + # the Hydrogen importer plugin. + # TODO : fix hydrogen importer plugin with qt6 + # See: https://doc.qt.io/qt-6/qtcore5-index.html + FIND_PACKAGE(Qt6 COMPONENTS Core5Compat REQUIRED) + INCLUDE_DIRECTORIES(${Qt6Core5Compat_INCLUDE_DIRS}) + SET(QT_LIBRARIES ${QT_LIBRARIES} Qt6::Core5Compat) +ENDIF() + IF(LMMS_BUILD_LINUX AND WANT_VST) + # Todo, enable qt6 for vst support 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 +IF(WANT_QT6) + FIND_PROGRAM(QT_QMAKE_EXECUTABLE NAME qmake.exe + PATHS "${CMAKE_PREFIX_PATH}/bin" /opt/Qt6/bin) # TODO: add more paths here +ELSE() + GET_TARGET_PROPERTY(QT_QMAKE_EXECUTABLE "${Qt5Core_QMAKE_EXECUTABLE}" IMPORTED_LOCATION) +ENDIF() # Find the location of Qt translation files execute_process(COMMAND ${QT_QMAKE_EXECUTABLE} -query QT_INSTALL_TRANSLATIONS @@ -215,8 +245,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) @@ -890,6 +920,7 @@ MESSAGE( "* Debug using ThreadSanitizer : ${STATUS_DEBUG_TSAN}\n" "* Debug using MemorySanitizer : ${STATUS_DEBUG_MSAN}\n" "* Debug using UBSanitizer : ${STATUS_DEBUG_UBSAN}\n" +"* Experimental Qt6 support : ${STATUS_QT6}\n" ) MESSAGE( diff --git a/cmake/install/CMakeLists.txt b/cmake/install/CMakeLists.txt index 3f6e3624ecb..19c69923082 100644 --- a/cmake/install/CMakeLists.txt +++ b/cmake/install/CMakeLists.txt @@ -1,6 +1,6 @@ SET(PLUGIN_FILES "") IF(LMMS_BUILD_WIN32) - INSTALL(FILES $ DESTINATION platforms) + INSTALL(FILES $ DESTINATION platforms) ENDIF() IF(LMMS_BUILD_WIN32 OR LMMS_INSTALL_DEPENDENCIES) diff --git a/cmake/modules/BuildPlugin.cmake b/cmake/modules/BuildPlugin.cmake index 70e518c93ce..b00f5dafd85 100644 --- a/cmake/modules/BuildPlugin.cmake +++ b/cmake/modules/BuildPlugin.cmake @@ -30,8 +30,13 @@ 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}) - QT5_WRAP_UI(plugin_UIC_out ${PLUGIN_UICFILES}) + IF(WANT_QT6) + QT6_WRAP_CPP(plugin_MOC_out ${PLUGIN_MOCFILES}) + QT6_WRAP_UI(plugin_UIC_out ${PLUGIN_UICFILES}) + ELSE() + QT5_WRAP_CPP(plugin_MOC_out ${PLUGIN_MOCFILES}) + QT5_WRAP_UI(plugin_UIC_out ${PLUGIN_UICFILES}) + ENDIF() FOREACH(f ${PLUGIN_SOURCES}) ADD_FILE_DEPENDENCIES(${f} ${RCC_OUT} ${plugin_UIC_out}) @@ -56,7 +61,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 9614e5ef4b8..62df5afbbbd 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 f7f9071e79e..8070c77a7ad 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 0e85ea9bb8b..67b2abc364d 100644 --- a/include/ColorChooser.h +++ b/include/ColorChooser.h @@ -55,8 +55,7 @@ class ColorChooser : public QColorDialog //! 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 78f99b9e2c1..2cc81915aea 100644 --- a/include/ColorHelper.h +++ b/include/ColorHelper.h @@ -34,16 +34,22 @@ 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 float interH = lerp(ar, br, t); - const float interS = lerp(ag, bg, t); - const float interV = lerp(ab, bb, t); - const float interA = lerp(aa, ba, t); + const colorType interH = lerp(ar, br, t); + const colorType interS = lerp(ag, bg, t); + const colorType interV = lerp(ab, bb, t); + const colorType interA = lerp(aa, ba, t); return QColor::fromRgbF(interH, interS, interV, interA); } diff --git a/include/ControlLayout.h b/include/ControlLayout.h index 568ce1a854d..80fb373c0c7 100644 --- a/include/ControlLayout.h +++ b/include/ControlLayout.h @@ -98,6 +98,14 @@ class ControlLayout : public QLayout { Q_OBJECT +#if (QT_VERSION > QT_VERSION_CHECK(6, 0, 0)) + using ControlLayoutMap = QMultiMap; + using ControlLayoutMapIterator = QMultiMapIterator; +#else + using ControlLayoutMap = QMap; + using ControlLayoutMapIterator = QMapIterator; +#endif + public: explicit ControlLayout(QWidget *parent, int margin = -1, int hSpacing = -1, int vSpacing = -1); @@ -126,9 +134,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 b9be6d42ff3..5bd9c739718 100644 --- a/include/DeprecationHelper.h +++ b/include/DeprecationHelper.h @@ -64,6 +64,36 @@ inline QPoint position(QWheelEvent *wheelEvent) #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(QMouseEvent* me) +{ +#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) + return me->position().toPoint(); +#else + return me->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(QDropEvent* de) +{ +#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) + return de->position().toPoint(); +#else + return de->pos(); +#endif +} + } // namespace lmms #endif // LMMS_DEPRECATIONHELPER_H diff --git a/include/FloatModelEditorBase.h b/include/FloatModelEditorBase.h index 72f1450de5a..1e03b1f14fe 100644 --- a/include/FloatModelEditorBase.h +++ b/include/FloatModelEditorBase.h @@ -81,7 +81,12 @@ class LMMS_EXPORT FloatModelEditorBase : public QWidget, public FloatModelView void paintEvent(QPaintEvent * me) override; void wheelEvent(QWheelEvent * me) override; + // Todo : cleanup once we drop QT5 support + #if (QT_VERSION > QT_VERSION_CHECK(6, 0, 0)) + void enterEvent(QEnterEvent *event) override; + #else void enterEvent(QEvent *event) override; + #endif void leaveEvent(QEvent *event) override; virtual float getValue(const QPoint & p); diff --git a/include/PluginBrowser.h b/include/PluginBrowser.h index 2bb1b6d5ccf..7e7fab1589c 100644 --- a/include/PluginBrowser.h +++ b/include/PluginBrowser.h @@ -66,7 +66,12 @@ class PluginDescWidget : public QWidget void openInNewInstrumentTrack(QString value); protected: - void enterEvent( QEvent * _e ) override; + // Todo : cleanup once QT 5 support is dropped + #if (QT_VERSION > QT_VERSION_CHECK(6, 0, 0)) + void enterEvent( QEnterEvent * _e) override; + #else + void enterEvent(QEvent* _e) override; + #endif void leaveEvent( QEvent * _e ) override; void mousePressEvent( QMouseEvent * _me ) override; void paintEvent( QPaintEvent * _pe ) override; diff --git a/plugins/AudioFileProcessor/AudioFileProcessorWaveView.cpp b/plugins/AudioFileProcessor/AudioFileProcessorWaveView.cpp index 1742ee3a7cd..a83b2236617 100644 --- a/plugins/AudioFileProcessor/AudioFileProcessorWaveView.cpp +++ b/plugins/AudioFileProcessor/AudioFileProcessorWaveView.cpp @@ -25,6 +25,7 @@ #include "AudioFileProcessorWaveView.h" #include "ConfigManager.h" +#include "DeprecationHelper.h" #include "gui_templates.h" #include "SampleWaveform.h" @@ -113,10 +114,12 @@ void AudioFileProcessorWaveView::leaveEvent(QEvent * e) void AudioFileProcessorWaveView::mousePressEvent(QMouseEvent * me) { + const auto pos = position(me); + m_isDragging = true; m_draggingLastPoint = me->pos(); - const int x = me->x(); + const int x = pos.x(); const int start_dist = qAbs(m_startFrameX - x); const int end_dist = qAbs(m_endFrameX - x); @@ -154,7 +157,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: @@ -168,14 +173,14 @@ void AudioFileProcessorWaveView::mouseMoveEvent(QMouseEvent * me) 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())) { slide(step); } else { - zoom(me->y() < m_draggingLastPoint.y()); + zoom(pos.y() < m_draggingLastPoint.y()); } } @@ -474,11 +479,13 @@ void AudioFileProcessorWaveView::reverse() void AudioFileProcessorWaveView::updateCursor(QMouseEvent * me) { + const auto pos = position(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)); + (isCloseTo(pos.x(), m_startFrameX) || + isCloseTo(pos.x(), m_endFrameX) || + isCloseTo(pos.x(), m_loopFrameX)); if (!m_isDragging && pointerCloseToStartEndOrLoop) setCursor(Qt::SizeHorCursor); diff --git a/plugins/Delay/DelayControlsDialog.cpp b/plugins/Delay/DelayControlsDialog.cpp index 065b3d1e4e5..1f8042fdc22 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" @@ -139,18 +140,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 4c9cd50acde..486773136f2 100644 --- a/plugins/LadspaEffect/LadspaMatrixControlDialog.cpp +++ b/plugins/LadspaEffect/LadspaMatrixControlDialog.cpp @@ -182,7 +182,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/SlicerT/SlicerTWaveform.cpp b/plugins/SlicerT/SlicerTWaveform.cpp index 3793ed2f159..bd45313800a 100644 --- a/plugins/SlicerT/SlicerTWaveform.cpp +++ b/plugins/SlicerT/SlicerTWaveform.cpp @@ -26,6 +26,7 @@ #include +#include "DeprecationHelper.h" #include "SampleWaveform.h" #include "SlicerT.h" #include "SlicerTView.h" @@ -242,13 +243,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() < s_seekerHeight) + if (pos.y() < s_seekerHeight) { if (std::abs(normalizedClickSeeker - m_seekerStart) < s_distanceForClick) { @@ -303,6 +306,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: @@ -314,7 +319,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) @@ -345,8 +350,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; @@ -396,7 +403,9 @@ void SlicerTWaveform::mouseDoubleClickEvent(QMouseEvent* me) { if (me->button() != Qt::MouseButton::LeftButton) { return; } - float normalizedClickEditor = static_cast(me->x()) / m_editorWidth; + const auto pos = position(me); + + 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/ZynAddSubFx/CMakeLists.txt b/plugins/ZynAddSubFx/CMakeLists.txt index 3369a793865..f99c41a5b07 100644 --- a/plugins/ZynAddSubFx/CMakeLists.txt +++ b/plugins/ZynAddSubFx/CMakeLists.txt @@ -117,12 +117,17 @@ target_sources(ZynAddSubFxCore INTERFACE 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 ) +# Workaround for a build fail on MSVC with Qt 6 +IF(MSVC) + TARGET_COMPILE_OPTIONS(ZynAddSubFxCoreObjs PUBLIC "/Zc:__cplusplus" "/permissive-") +ENDIF() + LINK_DIRECTORIES("${CMAKE_CURRENT_BINARY_DIR}/..") IF(LMMS_BUILD_LINUX) LINK_LIBRARIES(-Wl,--enable-new-dtags) @@ -163,6 +168,11 @@ SET_PROPERTY(GLOBAL APPEND PROPERTY PLUGINS_BUILT "RemoteZynAddSubFx") TARGET_COMPILE_DEFINITIONS(RemoteZynAddSubFx PRIVATE BUILD_REMOTE_PLUGIN_CLIENT) +# Workaround for a build fail on MSVC with Qt 6 +IF(MSVC) + TARGET_COMPILE_OPTIONS(RemoteZynAddSubFx PUBLIC "/Zc:__cplusplus" "/permissive-") +ENDIF() + IF(LMMS_BUILD_WIN32) SET_TARGET_PROPERTIES(RemoteZynAddSubFx PROPERTIES LINK_FLAGS "${LINK_FLAGS} -mwindows") ENDIF(LMMS_BUILD_WIN32) @@ -183,7 +193,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/CMakeLists.txt b/src/CMakeLists.txt index d71b34c5944..8a5081ab5dc 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -23,7 +23,12 @@ ADD_SUBDIRECTORY(tracks) LIST(APPEND LMMS_SRCS ${LMMS_COMMON_SRCS}) -QT5_WRAP_UI(LMMS_UI_OUT ${LMMS_UIS}) +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}" @@ -117,6 +122,11 @@ TARGET_INCLUDE_DIRECTORIES(lmms PUBLIC ${CMAKE_CURRENT_BINARY_DIR} ) +# Workaround for a build fail on MSVC with Qt 6 +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 0e427182238..75dce70c218 100644 --- a/src/core/AutomationClip.cpp +++ b/src/core/AutomationClip.cpp @@ -211,7 +211,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; } @@ -598,13 +598,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)); } @@ -626,9 +629,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; } @@ -642,16 +646,18 @@ 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 = pow(t, 2); auto t3 = pow(t, 3); 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; } } @@ -664,12 +670,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++ ) @@ -1198,7 +1206,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 @@ -1209,7 +1219,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); } @@ -1222,9 +1232,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); @@ -1232,9 +1245,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/MixHelpers.cpp b/src/core/MixHelpers.cpp index 209640b70b2..c589835c6e1 100644 --- a/src/core/MixHelpers.cpp +++ b/src/core/MixHelpers.cpp @@ -29,6 +29,8 @@ #endif #include +#include + #include #include "ValueBuffer.h" diff --git a/src/gui/ControlLayout.cpp b/src/gui/ControlLayout.cpp index 75133c8e3d8..8221afcd4e7 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(); + ControlLayoutMap::const_iterator itr = m_itemMap.cbegin(); for (; itr != m_itemMap.cend() && (index > 0 || skip(itr.value())); ++itr) { if(!skip(itr.value())) { index--; } @@ -242,7 +242,7 @@ int ControlLayout::doLayout(const QRect &rect, bool testOnly) const const QString filterText = m_searchBar->text(); bool first = true; - QMapIterator itr(m_itemMap); + ControlLayoutMapIterator itr(m_itemMap); while (itr.hasNext()) { itr.next(); diff --git a/src/gui/MainWindow.cpp b/src/gui/MainWindow.cpp index 3522d0e2dca..f5a51d6d6ff 100644 --- a/src/gui/MainWindow.cpp +++ b/src/gui/MainWindow.cpp @@ -292,11 +292,11 @@ void MainWindow::finalize() project_menu->addAction( embed::getIconPixmap( "project_save" ), tr( "Save &As..." ), this, SLOT(saveProjectAs()), - Qt::CTRL + Qt::SHIFT + Qt::Key_S ); + QKeySequence(Qt::CTRL | Qt::SHIFT | Qt::Key_S)); project_menu->addAction( embed::getIconPixmap( "project_save" ), tr( "Save as New &Version" ), this, SLOT(saveProjectAsNewVersion()), - Qt::CTRL + Qt::ALT + Qt::Key_S ); + QKeySequence(Qt::CTRL | Qt::ALT | Qt::Key_S)); project_menu->addAction( embed::getIconPixmap( "project_save" ), tr( "Save as default template" ), @@ -311,23 +311,23 @@ void MainWindow::finalize() tr( "E&xport..." ), this, SLOT(onExportProject()), - Qt::CTRL + Qt::Key_E ); + QKeySequence(Qt::CTRL | Qt::Key_E)); project_menu->addAction( embed::getIconPixmap( "project_export" ), tr( "E&xport Tracks..." ), this, SLOT(onExportProjectTracks()), - Qt::CTRL + Qt::SHIFT + Qt::Key_E ); + QKeySequence(Qt::CTRL | Qt::SHIFT | Qt::Key_E)); project_menu->addAction( embed::getIconPixmap( "midi_file" ), tr( "Export &MIDI..." ), this, SLOT(onExportProjectMidi()), - Qt::CTRL + Qt::Key_M ); + QKeySequence(Qt::CTRL | Qt::Key_M)); project_menu->addSeparator(); project_menu->addAction( embed::getIconPixmap( "exit" ), tr( "&Quit" ), qApp, SLOT(closeAllWindows()), - Qt::CTRL + Qt::Key_Q ); + QKeySequence(Qt::CTRL | Qt::Key_Q)); auto edit_menu = new QMenu(this); menuBar()->addMenu( edit_menu )->setText( tr( "&Edit" ) ); @@ -340,13 +340,13 @@ void MainWindow::finalize() this, SLOT(redo()), QKeySequence::Redo ); // Ensure that both (Ctrl+Y) and (Ctrl+Shift+Z) activate redo shortcut regardless of OS defaults - if (QKeySequence(QKeySequence::Redo) != QKeySequence(Qt::CTRL + Qt::Key_Y)) + if (QKeySequence(QKeySequence::Redo) != QKeySequence(Qt::CTRL | Qt::Key_Y)) { - new QShortcut( QKeySequence( Qt::CTRL + Qt::Key_Y ), this, SLOT(redo())); + new QShortcut( QKeySequence( Qt::CTRL | Qt::Key_Y ), this, SLOT(redo())); } - if (QKeySequence(QKeySequence::Redo) != QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_Z )) + if (QKeySequence(QKeySequence::Redo) != QKeySequence(Qt::CTRL | Qt::SHIFT | Qt::Key_Z )) { - new QShortcut( QKeySequence( Qt::CTRL + Qt::SHIFT + Qt::Key_Z ), this, SLOT(redo())); + new QShortcut( QKeySequence( Qt::CTRL | Qt::SHIFT | Qt::Key_Z ), this, SLOT(redo())); } edit_menu->addSeparator(); @@ -445,31 +445,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( Qt::CTRL + Qt::Key_1 ); + song_editor_window->setShortcut(QKeySequence(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(Qt::CTRL + Qt::Key_2); + pattern_editor_window->setShortcut(QKeySequence(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( Qt::CTRL + Qt::Key_3 ); + piano_roll_window->setShortcut(QKeySequence(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( Qt::CTRL + Qt::Key_4 ); + automation_editor_window->setShortcut(QKeySequence(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( Qt::CTRL + Qt::Key_5 ); + mixer_window->setShortcut(QKeySequence(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( Qt::CTRL + Qt::Key_6 ); + controllers_window->setShortcut(QKeySequence(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( Qt::CTRL + Qt::Key_7 ); + project_notes_window->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_7)); m_toolBarLayout->addWidget( song_editor_window, 1, 1 ); m_toolBarLayout->addWidget( pattern_editor_window, 1, 2 ); diff --git a/src/gui/PluginBrowser.cpp b/src/gui/PluginBrowser.cpp index 963609c431c..7e7fe9c26b4 100644 --- a/src/gui/PluginBrowser.cpp +++ b/src/gui/PluginBrowser.cpp @@ -258,9 +258,12 @@ void PluginDescWidget::paintEvent( QPaintEvent * ) } - - -void PluginDescWidget::enterEvent( QEvent * _e ) +// Todo : cleanup once we drop QT5 support +#if (QT_VERSION > QT_VERSION_CHECK(6, 0, 0)) +void PluginDescWidget::enterEvent(QEnterEvent * _e) +#else +void PluginDescWidget::enterEvent(QEvent * _e) +#endif { m_mouseOver = true; diff --git a/src/gui/ProjectNotes.cpp b/src/gui/ProjectNotes.cpp index a71f146c66e..18dc3d8f4fa 100644 --- a/src/gui/ProjectNotes.cpp +++ b/src/gui/ProjectNotes.cpp @@ -26,6 +26,7 @@ #include "ProjectNotes.h" #include +#include #include #include #include diff --git a/src/gui/clips/AutomationClipView.cpp b/src/gui/clips/AutomationClipView.cpp index 9b71bb74c74..bb2d4b62e9f 100644 --- a/src/gui/clips/AutomationClipView.cpp +++ b/src/gui/clips/AutomationClipView.cpp @@ -289,7 +289,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; const auto x2 = (float)(width() - BORDER_WIDTH); @@ -316,13 +318,13 @@ 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, 0.0f); path.moveTo( origin ); path.moveTo(QPointF(POS(it) * ppTick,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; if( x > ( width() - BORDER_WIDTH ) ) break; @@ -330,8 +332,8 @@ void AutomationClipView::paintEvent( QPaintEvent * ) path.lineTo( QPointF( x, value ) ); } - path.lineTo((POS(it + 1)) * ppTick, nextValue); - path.lineTo((POS(it + 1)) * ppTick, 0.0f); + path.lineTo((POS(nit)) * ppTick, nextValue); + path.lineTo((POS(nit)) * ppTick, 0.0f); path.lineTo( origin ); if( gradient() ) diff --git a/src/gui/clips/ClipView.cpp b/src/gui/clips/ClipView.cpp index 5c8a12b91e3..525003b8022 100644 --- a/src/gui/clips/ClipView.cpp +++ b/src/gui/clips/ClipView.cpp @@ -36,6 +36,7 @@ #include "ColorChooser.h" #include "ComboBoxModel.h" #include "DataFile.h" +#include "DeprecationHelper.h" #include "Engine.h" #include "embed.h" #include "GuiApplication.h" @@ -356,7 +357,7 @@ void ClipView::selectColor() // Get a color from the user const auto newColor = ColorChooser{this} .withPalette(ColorChooser::Palette::Track) - ->getColor(m_clip->color().value_or(palette().background().color())); + ->getColor(m_clip->color().value_or(palette().window().color())); if (newColor.isValid()) { setColor(newColor); } } @@ -495,9 +496,11 @@ void ClipView::updateCursor(QMouseEvent * me) auto sClip = dynamic_cast(m_clip); auto pClip = dynamic_cast(m_clip); + const auto posX = position(me).x(); + // If we are at the edges, use the resize cursor if (!me->buttons() && !m_clip->getAutoResize() && !isSelected() - && ((me->x() > width() - RESIZE_GRIP_WIDTH) || (me->x() < RESIZE_GRIP_WIDTH && (sClip || pClip)))) + && ((posX > width() - RESIZE_GRIP_WIDTH) || (posX < RESIZE_GRIP_WIDTH && (sClip || pClip)))) { setCursor(Qt::SizeHorCursor); } @@ -618,6 +621,8 @@ void ClipView::paintTextLabel(QString const & text, QPainter & painter) */ void ClipView::mousePressEvent( QMouseEvent * me ) { + const auto posX = position(me).x(); + // 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 @@ -669,12 +674,12 @@ void ClipView::mousePressEvent( QMouseEvent * me ) m_action = Action::Move; setCursor( Qt::SizeAllCursor ); } - else if( me->x() >= width() - RESIZE_GRIP_WIDTH ) + else if( posX >= width() - RESIZE_GRIP_WIDTH ) { m_action = Action::Resize; setCursor( Qt::SizeHorCursor ); } - else if( me->x() < RESIZE_GRIP_WIDTH && (sClip || pClip) ) + else if( posX < RESIZE_GRIP_WIDTH && (sClip || pClip) ) { m_action = Action::ResizeLeft; setCursor( Qt::SizeHorCursor ); @@ -881,7 +886,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( position(me).x() * TimePos::ticksPerBar() / ppb ); // If the user is holding alt, or pressed ctrl after beginning the drag, don't quantize if ( unquantizedModHeld(me) ) diff --git a/src/gui/clips/MidiClipView.cpp b/src/gui/clips/MidiClipView.cpp index 0a6fece3168..90bf60e2168 100644 --- a/src/gui/clips/MidiClipView.cpp +++ b/src/gui/clips/MidiClipView.cpp @@ -245,16 +245,18 @@ void MidiClipView::constructContextMenu( QMenu * _cm ) 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 tmp = ( ( float(pos.x()) - BORDER_WIDTH ) * float( m_clip -> m_steps ) ) / float(width() - BORDER_WIDTH*2); int step = int( tmp ); diff --git a/src/gui/editors/AutomationEditor.cpp b/src/gui/editors/AutomationEditor.cpp index 46521b3f02b..e68344fd2ca 100644 --- a/src/gui/editors/AutomationEditor.cpp +++ b/src/gui/editors/AutomationEditor.cpp @@ -429,13 +429,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; @@ -454,7 +456,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) { @@ -623,7 +625,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()) @@ -664,14 +666,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) { @@ -729,12 +733,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; @@ -883,8 +889,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); @@ -1307,11 +1313,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; @@ -1334,17 +1342,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 ); @@ -2035,17 +2043,17 @@ AutomationEditorWindow::AutomationEditorWindow() : auto editModeGroup = new ActionGroup(this); m_drawAction = editModeGroup->addAction(embed::getIconPixmap("edit_draw"), tr("Draw mode (Shift+D)")); - m_drawAction->setShortcut(Qt::SHIFT | Qt::Key_D); + m_drawAction->setShortcut(QKeySequence(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(Qt::SHIFT | Qt::Key_E); + m_eraseAction->setShortcut(QKeySequence(Qt::SHIFT | Qt::Key_E)); m_drawOutAction = editModeGroup->addAction(embed::getIconPixmap("edit_draw_outvalue"), tr("Draw outValues mode (Shift+C)")); - m_drawOutAction->setShortcut(Qt::SHIFT | Qt::Key_C); + m_drawOutAction->setShortcut(QKeySequence(Qt::SHIFT | Qt::Key_C)); m_editTanAction = editModeGroup->addAction(embed::getIconPixmap("edit_tangent"), tr("Edit tangents mode (Shift+T)")); - m_editTanAction->setShortcut(Qt::SHIFT | Qt::Key_T); + m_editTanAction->setShortcut(QKeySequence(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 a61c2cd6081..c1c7e94c8bf 100644 --- a/src/gui/editors/Editor.cpp +++ b/src/gui/editors/Editor.cpp @@ -116,8 +116,8 @@ Editor::Editor(bool record, bool stepRecord) : connect(m_toggleStepRecordingAction, SIGNAL(triggered()), this, SLOT(toggleStepRecording())); connect(m_stopAction, SIGNAL(triggered()), this, SLOT(stop())); new QShortcut(Qt::Key_Space, this, SLOT(togglePlayStop())); - new QShortcut(QKeySequence(Qt::SHIFT + Qt::Key_Space), this, SLOT(togglePause())); - new QShortcut(QKeySequence(Qt::SHIFT + Qt::Key_F11), this, SLOT(toggleMaximize())); + new QShortcut(QKeySequence(Qt::SHIFT | Qt::Key_Space), this, SLOT(togglePause())); + new QShortcut(QKeySequence(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 7d4a9552a54..f6cba3ee255 100644 --- a/src/gui/editors/PianoRoll.cpp +++ b/src/gui/editors/PianoRoll.cpp @@ -1103,7 +1103,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 @@ -1128,7 +1131,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) @@ -1606,6 +1609,8 @@ void PianoRoll::mousePressEvent(QMouseEvent * me ) return; } + const auto pos = position(me); + // -- Knife if (m_editMode == EditMode::Knife && me->button() == Qt::LeftButton) { @@ -1657,25 +1662,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()) + 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) @@ -1932,7 +1937,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) @@ -1943,8 +1948,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( QPoint( pos.x(), pos.y() ) ) ); } else if( me->buttons() == Qt::LeftButton ) { @@ -1970,7 +1975,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( QPoint( pos.x(), pos.y() ) ) ); } } } @@ -1986,13 +1991,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 ) * @@ -2343,11 +2350,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; @@ -2356,12 +2365,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 @@ -2382,14 +2391,14 @@ void PianoRoll::mouseMoveEvent( QMouseEvent * me ) updateKnifePos(me); } - 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() ) + 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 @@ -2418,8 +2427,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 @@ -2460,15 +2469,15 @@ void PianoRoll::mouseMoveEvent( QMouseEvent * me ) { vol = qBound( MinVolume, MinVolume + - ( ( (float)noteEditBottom() ) - ( (float)me->y() ) ) / + ( ( (float)noteEditBottom() ) - ( (float)pos.y() ) ) / ( (float)( noteEditBottom() - noteEditTop() ) ) * ( MaxVolume - MinVolume ), MaxVolume ); - pan = qBound( PanningLeft, - PanningLeft + - ( (float)( noteEditBottom() - me->y() ) ) / + pan = qBound( PanningLeft, + static_cast(PanningLeft + + ( (float)( noteEditBottom() - pos.y() ) ) / ( (float)( noteEditBottom() - noteEditTop() ) ) * - ( (float)( PanningRight - PanningLeft ) ), + ( (float)( PanningRight - PanningLeft ) )), PanningRight); } @@ -2678,13 +2687,13 @@ void PianoRoll::mouseMoveEvent( QMouseEvent * me ) m_action == Action::SelectNotes ) { - int x = me->x() - m_whiteKeyWidth; + int x = pos.x() - m_whiteKeyWidth; if( x < 0 && m_currentPosition > 0 ) { x = 0; QCursor::setPos( mapToGlobal( QPoint( m_whiteKeyWidth, - me->y() ) ) ); + pos.y() ) ) ); if( m_currentPosition >= 4 ) { m_leftRightScroll->setValue( @@ -2699,7 +2708,7 @@ void PianoRoll::mouseMoveEvent( QMouseEvent * me ) { x = width() - m_whiteKeyWidth; QCursor::setPos( mapToGlobal( QPoint( width(), - me->y() ) ) ); + pos.y() ) ) ); m_leftRightScroll->setValue( m_currentPosition + 4 ); } @@ -2718,7 +2727,7 @@ void PianoRoll::mouseMoveEvent( QMouseEvent * me ) } - int key_num = getKey( me->y() ); + int key_num = getKey( pos.y() ); int visible_keys = ( height() - PR_TOP_MARGIN - PR_BOTTOM_MARGIN - m_notesEditHeight ) / @@ -2727,7 +2736,7 @@ void PianoRoll::mouseMoveEvent( QMouseEvent * me ) if( key_num <= s_key ) { - QCursor::setPos( mapToGlobal( QPoint( me->x(), + QCursor::setPos( mapToGlobal( QPoint( pos.x(), keyAreaBottom() ) ) ); m_topBottomScroll->setValue( m_topBottomScroll->value() + 1 ); @@ -2735,7 +2744,7 @@ void PianoRoll::mouseMoveEvent( QMouseEvent * me ) } else if( key_num >= s_key + visible_keys ) { - QCursor::setPos( mapToGlobal( QPoint( me->x(), + QCursor::setPos( mapToGlobal( QPoint( pos.x(), PR_TOP_MARGIN ) ) ); m_topBottomScroll->setValue( m_topBottomScroll->value() - 1 ); @@ -2751,8 +2760,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(); } @@ -2762,8 +2771,10 @@ void PianoRoll::mouseMoveEvent( QMouseEvent * me ) void PianoRoll::updateKnifePos(QMouseEvent* me) { + const auto pos = position(me); + // Calculate the TimePos from the mouse - int mouseViewportPos = me->x() - m_whiteKeyWidth; + int mouseViewportPos = pos.x() - m_whiteKeyWidth; int mouseTickPos = mouseViewportPos * TimePos::ticksPerBar() / m_ppb + m_currentPosition; // If ctrl is not pressed, quantize the position @@ -3798,7 +3809,7 @@ void PianoRoll::wheelEvent(QWheelEvent * we ) { for ( Note * n : nv ) { - panning_t pan = qBound( PanningLeft, n->getPanning() + step, PanningRight ); + panning_t pan = qBound( PanningLeft, n->getPanning() + static_cast(step), PanningRight ); n->setPanning( pan ); } bool allPansEqual = std::all_of( nv.begin(), nv.end(), @@ -4753,10 +4764,10 @@ PianoRollWindow::PianoRollWindow() : drawAction->setChecked( true ); - drawAction->setShortcut( Qt::SHIFT | Qt::Key_D ); - eraseAction->setShortcut( Qt::SHIFT | Qt::Key_E ); - selectAction->setShortcut( Qt::SHIFT | Qt::Key_S ); - pitchBendAction->setShortcut( Qt::SHIFT | Qt::Key_T ); + drawAction->setShortcut(QKeySequence(Qt::SHIFT | Qt::Key_D )); + eraseAction->setShortcut(QKeySequence(Qt::SHIFT | Qt::Key_E)); + selectAction->setShortcut(QKeySequence(Qt::SHIFT | Qt::Key_S)); + pitchBendAction->setShortcut(QKeySequence(Qt::SHIFT | Qt::Key_T)); connect( editModeGroup, SIGNAL(triggered(int)), m_editor, SLOT(setEditMode(int))); @@ -4815,9 +4826,9 @@ PianoRollWindow::PianoRollWindow() : auto pasteAction = new QAction(embed::getIconPixmap("edit_paste"), tr("Paste (%1+V)").arg(UI_CTRL_KEY), this); - cutAction->setShortcut( Qt::CTRL | Qt::Key_X ); - copyAction->setShortcut( Qt::CTRL | Qt::Key_C ); - pasteAction->setShortcut( Qt::CTRL | Qt::Key_V ); + cutAction->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_X)); + copyAction->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_C)); + pasteAction->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_V)); connect( cutAction, SIGNAL(triggered()), m_editor, SLOT(cutSelectedNotes())); connect( copyAction, SIGNAL(triggered()), m_editor, SLOT(copySelectedNotes())); @@ -4838,19 +4849,19 @@ PianoRollWindow::PianoRollWindow() : auto glueAction = new QAction(embed::getIconPixmap("glue"), tr("Glue"), noteToolsButton); connect(glueAction, SIGNAL(triggered()), m_editor, SLOT(glueNotes())); - glueAction->setShortcut( Qt::SHIFT | Qt::Key_G ); + glueAction->setShortcut(QKeySequence(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( Qt::SHIFT | Qt::Key_K ); + knifeAction->setShortcut(QKeySequence(Qt::SHIFT | Qt::Key_K)); auto fillAction = new QAction(embed::getIconPixmap("fill"), tr("Fill"), noteToolsButton); connect(fillAction, &QAction::triggered, [this](){ m_editor->fitNoteLengths(true); }); - fillAction->setShortcut(Qt::SHIFT | Qt::Key_F); + fillAction->setShortcut(QKeySequence(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(Qt::SHIFT | Qt::Key_C); + cutOverlapsAction->setShortcut(QKeySequence(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); }); diff --git a/src/gui/editors/SongEditor.cpp b/src/gui/editors/SongEditor.cpp index 1806f29312f..6490586be69 100644 --- a/src/gui/editors/SongEditor.cpp +++ b/src/gui/editors/SongEditor.cpp @@ -602,6 +602,8 @@ 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 @@ -615,8 +617,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; } diff --git a/src/gui/editors/TimeLineWidget.cpp b/src/gui/editors/TimeLineWidget.cpp index 7657e2916cd..7dfd08f53c5 100644 --- a/src/gui/editors/TimeLineWidget.cpp +++ b/src/gui/editors/TimeLineWidget.cpp @@ -35,6 +35,7 @@ #include #include "ConfigManager.h" +#include "DeprecationHelper.h" #include "embed.h" #include "GuiApplication.h" #include "NStateButton.h" @@ -241,8 +242,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") @@ -285,7 +288,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; @@ -297,14 +302,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 { @@ -328,7 +333,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 ) @@ -389,7 +396,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 d934adcde64..a57d9e7c856 100644 --- a/src/gui/embed.cpp +++ b/src/gui/embed.cpp @@ -37,7 +37,7 @@ QPixmap getIconPixmap(const QString& pixmapName, QString cacheName; if (width > 0 && height > 0) { - cacheName = QString("%1_%2_%3").arg(pixmapName, width, height); + cacheName = QString("%1_%2_%3").arg(pixmapName).arg(width).arg(height); } else { diff --git a/src/gui/tracks/TrackContentWidget.cpp b/src/gui/tracks/TrackContentWidget.cpp index 619eff8317b..e6ac49b85f6 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" @@ -283,7 +284,9 @@ TimePos TrackContentWidget::getPosition( int mouseX ) */ void TrackContentWidget::dragEnterEvent( QDragEnterEvent * dee ) { - TimePos clipPos = getPosition( dee->pos().x() ); + const auto pos = position(dee); + + TimePos clipPos = getPosition( pos.x() ); if( canPasteSelection( clipPos, dee ) == false ) { dee->ignore(); @@ -519,7 +522,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(); @@ -535,6 +540,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 ){ @@ -560,9 +567,9 @@ void TrackContentWidget::mousePressEvent( QMouseEvent * me ) so.at( i )->setSelected( false); } getTrack()->addJournalCheckPoint(); - const TimePos pos = getPosition( me->x() ).getBar() * + const TimePos timePos = getPosition( pos.x() ).getBar() * TimePos::ticksPerBar(); - getTrack()->createClip(pos); + getTrack()->createClip(timePos); } } diff --git a/src/gui/tracks/TrackView.cpp b/src/gui/tracks/TrackView.cpp index e2323602154..eaee2509483 100644 --- a/src/gui/tracks/TrackView.cpp +++ b/src/gui/tracks/TrackView.cpp @@ -36,6 +36,7 @@ #include "AudioEngine.h" #include "ConfigManager.h" #include "DataFile.h" +#include "DeprecationHelper.h" #include "Engine.h" #include "FadeButton.h" #include "PixmapButton.h" @@ -255,6 +256,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 && @@ -270,7 +272,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 ); } @@ -279,14 +281,14 @@ void TrackView::mousePressEvent( QMouseEvent * me ) if( me->modifiers() & Qt::ShiftModifier ) { m_action = Action::Resize; - QCursor::setPos( mapToGlobal( QPoint( me->x(), + QCursor::setPos( mapToGlobal( QPoint( pos.x(), height() ) ) ); QCursor c( Qt::SizeVerCursor); QApplication::setOverrideCursor( c ); } else { - if( me->x()>10 ) // 10 = The width of the grip + 2 pixels to the left and right. + if( pos.x()>10 ) // 10 = The width of the grip + 2 pixels to the left and right. { QWidget::mousePressEvent( me ); return; @@ -330,11 +332,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 ); } @@ -352,7 +356,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 ); } @@ -364,7 +368,7 @@ void TrackView::mouseMoveEvent( QMouseEvent * me ) } else if( m_action == Action::Resize ) { - resizeToHeight(me->y()); + resizeToHeight(pos.y()); } if( height() < DEFAULT_TRACK_HEIGHT ) diff --git a/src/gui/widgets/ComboBox.cpp b/src/gui/widgets/ComboBox.cpp index eb019876a06..419d322e1f5 100644 --- a/src/gui/widgets/ComboBox.cpp +++ b/src/gui/widgets/ComboBox.cpp @@ -32,6 +32,7 @@ #include #include "CaptionMenu.h" +#include "DeprecationHelper.h" #include "gui_templates.h" #define QT_SUPPORTS_WIDGET_SCREEN (QT_VERSION >= QT_VERSION_CHECK(5,14,0)) @@ -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 1eb06756a2e..168b0bcc9e1 100644 --- a/src/gui/widgets/Fader.cpp +++ b/src/gui/widgets/Fader.cpp @@ -55,6 +55,7 @@ #include "embed.h" #include "CaptionMenu.h" #include "ConfigManager.h" +#include "DeprecationHelper.h" #include "SimpleTextFloat.h" namespace lmms::gui @@ -124,6 +125,8 @@ void Fader::mouseMoveEvent(QMouseEvent* mouseEvent) void Fader::mousePressEvent(QMouseEvent* mouseEvent) { + const auto pos = position(mouseEvent); + if (mouseEvent->button() == Qt::LeftButton && !(mouseEvent->modifiers() & Qt::ControlModifier)) { @@ -134,7 +137,7 @@ void Fader::mousePressEvent(QMouseEvent* mouseEvent) thisModel->saveJournallingState(false); } - if (mouseEvent->y() >= knobPosY() - (m_knob).height() && mouseEvent->y() < knobPosY()) + if (pos.y() >= knobPosY() - (m_knob).height() && pos.y() < knobPosY()) { updateTextFloat(); s_textFloat->show(); diff --git a/src/gui/widgets/FloatModelEditorBase.cpp b/src/gui/widgets/FloatModelEditorBase.cpp index dd6be89583e..d6331141dc9 100644 --- a/src/gui/widgets/FloatModelEditorBase.cpp +++ b/src/gui/widgets/FloatModelEditorBase.cpp @@ -232,8 +232,12 @@ void FloatModelEditorBase::mouseReleaseEvent(QMouseEvent* event) s_textFloat->hide(); } - -void FloatModelEditorBase::enterEvent(QEvent *event) +// Todo : cleanup once Qt 5 support is dropped +#if (QT_VERSION > QT_VERSION_CHECK(6, 0, 0)) +void FloatModelEditorBase::enterEvent(QEnterEvent* event) +#else +void FloatModelEditorBase::enterEvent(QEvent* event) +#endif { showTextFloat(700, 2000); } diff --git a/src/gui/widgets/Graph.cpp b/src/gui/widgets/Graph.cpp index 0781d4f1113..c10e5642b68 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 "SampleBuffer.h" @@ -100,9 +101,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; @@ -147,13 +150,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 ); @@ -166,8 +171,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 e7d78acb9dd..374b28e762c 100644 --- a/src/gui/widgets/GroupBox.cpp +++ b/src/gui/widgets/GroupBox.cpp @@ -30,6 +30,7 @@ #endif #include "GroupBox.h" +#include "DeprecationHelper.h" #include "embed.h" #include "gui_templates.h" @@ -86,7 +87,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 c71d665689e..0c42f7634a1 100644 --- a/src/gui/widgets/LcdFloatSpinBox.cpp +++ b/src/gui/widgets/LcdFloatSpinBox.cpp @@ -134,12 +134,14 @@ 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(); if (event->button() == Qt::LeftButton && !(event->modifiers() & Qt::ControlModifier) && - event->y() < m_wholeDisplay.cellHeight() + 2) + pos.y() < m_wholeDisplay.cellHeight() + 2) { m_mouseMoving = true; m_origMousePos = event->globalPos(); diff --git a/src/gui/widgets/LcdSpinBox.cpp b/src/gui/widgets/LcdSpinBox.cpp index b53d7ddb5b0..a34b3775648 100644 --- a/src/gui/widgets/LcdSpinBox.cpp +++ b/src/gui/widgets/LcdSpinBox.cpp @@ -29,6 +29,7 @@ #include "LcdSpinBox.h" #include "CaptionMenu.h" +#include "DeprecationHelper.h" namespace lmms::gui @@ -78,9 +79,11 @@ void LcdSpinBox::contextMenuEvent(QContextMenuEvent* event) void LcdSpinBox::mousePressEvent( QMouseEvent* event ) { + const auto pos = position(event); + if( event->button() == Qt::LeftButton && ! ( event->modifiers() & Qt::ControlModifier ) && - event->y() < cellHeight() + 2 ) + pos.y() < cellHeight() + 2 ) { m_mouseMoving = true; m_lastMousePos = event->globalPos(); diff --git a/src/gui/widgets/SimpleTextFloat.cpp b/src/gui/widgets/SimpleTextFloat.cpp index e37753229ac..870869fe919 100644 --- a/src/gui/widgets/SimpleTextFloat.cpp +++ b/src/gui/widgets/SimpleTextFloat.cpp @@ -40,7 +40,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);