diff --git a/CMakeLists.txt b/CMakeLists.txt index 57bb74b6..0582f93e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -196,14 +196,15 @@ endif() # # Discover Qt dependencies. # -find_package(Qt5 5.15 COMPONENTS Core Widgets LinguistTools Concurrent Svg Multimedia Qml QuickControls2 QuickWidgets REQUIRED) -find_package(Qt5QuickCompiler) -find_package(Qt5DBus) +find_package(Qt6 6.2 COMPONENTS Core Widgets LinguistTools Svg Multimedia Qml QuickControls2 REQUIRED) +#find_package(Qt5QuickCompiler) +find_package(Qt6DBus) if (USE_BUNDLED_QTKEYCHAIN) include(FetchContent) + set(BUILD_WITH_QT6 ON) FetchContent_Declare( - qt5keychain + qt6keychain GIT_REPOSITORY https://github.com/frankosterfeld/qtkeychain.git GIT_TAG v0.13.1 ) @@ -213,13 +214,13 @@ if (USE_BUNDLED_QTKEYCHAIN) set(QTKEYCHAIN_STATIC ON CACHE INTERNAL "") endif() set(BUILD_TEST_APPLICATION OFF CACHE INTERNAL "") - FetchContent_MakeAvailable(qt5keychain) + FetchContent_MakeAvailable(qt6keychain) else() - find_package(Qt5Keychain REQUIRED) + find_package(Qt6Keychain REQUIRED) endif() if (APPLE) - find_package(Qt5MacExtras REQUIRED) + find_package(Qt6MacExtras REQUIRED) endif(APPLE) if (Qt5Widgets_FOUND) @@ -505,7 +506,7 @@ if (NOT APPLE AND NOT WIN32) add_compile_definitions(NHEKO_DBUS_SYS) endif() -qt5_wrap_cpp(MOC_HEADERS +qt_wrap_cpp(MOC_HEADERS # Dialogs src/dialogs/FallbackAuth.h src/dialogs/ReCaptcha.h @@ -645,7 +646,7 @@ elseif(WIN32) target_compile_options(nheko PUBLIC "/Zc:__cplusplus") endif() else() - target_link_libraries (nheko PRIVATE Qt5::DBus) + target_link_libraries (nheko PRIVATE Qt::DBus) if (FLATPAK) target_compile_definitions(nheko PRIVATE NHEKO_FLATPAK) endif() @@ -654,21 +655,19 @@ target_include_directories(nheko PRIVATE src includes third_party/blurhash third # Fixup bundled keychain include dirs if (USE_BUNDLED_QTKEYCHAIN) - target_include_directories(nheko PRIVATE ${qt5keychain_SOURCE_DIR} ${qt5keychain_BINARY_DIR}) + target_include_directories(nheko PRIVATE ${qt6keychain_SOURCE_DIR} ${qt6keychain_BINARY_DIR}) endif() target_link_libraries(nheko PRIVATE MatrixClient::MatrixClient cmark::cmark spdlog::spdlog - Qt5::Widgets - Qt5::Svg - Qt5::Concurrent - Qt5::Multimedia - Qt5::Qml - Qt5::QuickControls2 - Qt5::QuickWidgets - qt5keychain + Qt::Widgets + Qt::Svg + Qt::Multimedia + Qt::Qml + Qt::QuickControls2 + qt6keychain nlohmann_json::nlohmann_json lmdbxx::lmdbxx liblmdb::lmdb diff --git a/cmake/Translations.cmake b/cmake/Translations.cmake index 887697a8..5f5481b2 100644 --- a/cmake/Translations.cmake +++ b/cmake/Translations.cmake @@ -4,9 +4,10 @@ file(GLOB LANG_TS_SRC "${CMAKE_CURRENT_SOURCE_DIR}/resources/langs/*.ts") -qt5_add_translation(QM_SRC ${LANG_TS_SRC}) -qt5_create_translation(${QM_SRC}) +qt_add_translation(QM_SRC ${LANG_TS_SRC}) +qt_create_translation(${QM_SRC}) add_custom_target(LANG_QRC ALL DEPENDS ${QM_SRC}) +set_target_properties(LANG_QRC PROPERTIES QT_RESOURCE_PREFIX /) # Generate a qrc file for the translations set(_qrc ${CMAKE_CURRENT_BINARY_DIR}/translations.qrc) @@ -20,9 +21,9 @@ if(NOT EXISTS ${_qrc}) file(APPEND ${_qrc} " \n\n") endif() -qt5_add_resources(LANG_QRC ${_qrc}) +qt_add_resources(LANG_QRC ${_qrc}) if(Qt5QuickCompiler_FOUND AND COMPILE_QML) qtquick_compiler_add_resources(QRC resources/res.qrc) else() - qt5_add_resources(QRC resources/res.qrc) + qt_add_resources(QRC resources/res.qrc) endif() diff --git a/resources/qml/PrivacyScreen.qml b/resources/qml/PrivacyScreen.qml index fb3818df..300ddc79 100644 --- a/resources/qml/PrivacyScreen.qml +++ b/resources/qml/PrivacyScreen.qml @@ -3,7 +3,7 @@ // // SPDX-License-Identifier: GPL-3.0-or-later -import QtGraphicalEffects 1.0 +//import QtGraphicalEffects 1.0 import QtQuick 2.12 import QtQuick.Window 2.2 import im.nheko 1.0 @@ -120,13 +120,13 @@ Item { } ] - FastBlur { - id: blur + //FastBlur { + // id: blur - anchors.fill: parent - source: timelineRoot - radius: 50 - } + // anchors.fill: parent + // source: timelineRoot + // radius: 50 + //} } diff --git a/resources/qml/Root.qml b/resources/qml/Root.qml index 72f30b7a..c8c6b461 100644 --- a/resources/qml/Root.qml +++ b/resources/qml/Root.qml @@ -21,7 +21,26 @@ import im.nheko.EmojiModel 1.0 Pane { id: timelineRoot - palette: Nheko.colors + palette { + windowText: "#caccd1" + button: "white" + light: "#caccd1" + dark: "#3c464d" + mid: "#202228" + text: "#caccd1" + brightText: "#f4f5f8" + base: "#202228" + window: "#2d3139" + + alternateBase: "#2d3139" + highlight: "#38a3d8" + highlightedText: "#f4f5f8" + toolTipBase: base + toolTipText: text + link: "#38a3d8" + buttonText: "#828284" + + } background: null padding: 0 diff --git a/resources/qml/components/FlatButton.qml b/resources/qml/components/FlatButton.qml index 2c9ea061..e19f9681 100644 --- a/resources/qml/components/FlatButton.qml +++ b/resources/qml/components/FlatButton.qml @@ -3,7 +3,7 @@ // // SPDX-License-Identifier: GPL-3.0-or-later -import QtGraphicalEffects 1.12 +//import QtGraphicalEffects 1.12 import QtQuick 2.9 import QtQuick.Controls 2.5 import QtQuick.Layouts 1.2 @@ -19,16 +19,16 @@ Button { property string iconImage: "" - DropShadow { - anchors.fill: control.background - horizontalOffset: 3 - verticalOffset: 3 - radius: 8 - samples: 17 - cached: true - color: "#80000000" - source: control.background - } + //DropShadow { + // anchors.fill: control.background + // horizontalOffset: 3 + // verticalOffset: 3 + // radius: 8 + // samples: 17 + // cached: true + // color: "#80000000" + // source: control.background + //} contentItem: RowLayout { spacing: 0 diff --git a/resources/qml/delegates/PlayableMediaMessage.qml b/resources/qml/delegates/PlayableMediaMessage.qml index 4828843c..5cb52f60 100644 --- a/resources/qml/delegates/PlayableMediaMessage.qml +++ b/resources/qml/delegates/PlayableMediaMessage.qml @@ -5,7 +5,7 @@ import "../" import "../ui/media" -import QtMultimedia 5.15 +import QtMultimedia import QtQuick 2.15 import QtQuick.Controls 2.15 import QtQuick.Layouts 1.15 @@ -36,13 +36,13 @@ Item { MxcMedia { id: mxcmedia - // TODO: Show error in overlay or so? - onError: console.log(error) roomm: room - // desiredVolume is a float from 0.0 -> 1.0, MediaPlayer volume is an int from 0 to 100 - // this value automatically gets clamped for us between these two values. - volume: mediaControls.desiredVolume * 100 - muted: mediaControls.muted + + audioOutput: AudioOutput { + muted: mediaControls.muted + volume: mediaControls.desiredVolume + } + videoOutput: videoOutput } Rectangle { @@ -69,8 +69,7 @@ Item { clip: true anchors.fill: parent fillMode: VideoOutput.PreserveAspectFit - source: mxcmedia - flushMode: VideoOutput.FirstFrame + //flushMode: VideoOutput.FirstFrame orientation: mxcmedia.orientation } diff --git a/resources/qml/emoji/EmojiPicker.qml b/resources/qml/emoji/EmojiPicker.qml index dc813566..d234eda9 100644 --- a/resources/qml/emoji/EmojiPicker.qml +++ b/resources/qml/emoji/EmojiPicker.qml @@ -4,7 +4,6 @@ // SPDX-License-Identifier: GPL-3.0-or-later import "../" -import QtGraphicalEffects 1.0 import QtQuick 2.9 import QtQuick.Controls 2.3 import QtQuick.Layouts 1.3 diff --git a/resources/qml/emoji/StickerPicker.qml b/resources/qml/emoji/StickerPicker.qml index d38461a1..41e8c3b6 100644 --- a/resources/qml/emoji/StickerPicker.qml +++ b/resources/qml/emoji/StickerPicker.qml @@ -4,7 +4,6 @@ // SPDX-License-Identifier: GPL-3.0-or-later import "../" -import QtGraphicalEffects 1.0 import QtQuick 2.9 import QtQuick.Controls 2.3 import QtQuick.Layouts 1.3 diff --git a/resources/qml/ui/Ripple.qml b/resources/qml/ui/Ripple.qml index 0619d924..e0532702 100644 --- a/resources/qml/ui/Ripple.qml +++ b/resources/qml/ui/Ripple.qml @@ -3,7 +3,6 @@ // // SPDX-License-Identifier: GPL-3.0-or-later -import QtGraphicalEffects 1.0 import QtQuick 2.15 import QtQuick.Controls 2.15 diff --git a/resources/qml/ui/Spinner.qml b/resources/qml/ui/Spinner.qml index 3681a36b..6d897d2b 100644 --- a/resources/qml/ui/Spinner.qml +++ b/resources/qml/ui/Spinner.qml @@ -4,7 +4,7 @@ // SPDX-License-Identifier: GPL-3.0-or-later import "./animations" -import QtGraphicalEffects 1.12 +//import QtGraphicalEffects 1.12 import QtQuick 2.12 Item { @@ -140,17 +140,17 @@ Item { } - Glow { - anchors.fill: row - radius: 14 - samples: 17 - color: spinner.foreground - source: row + //Glow { + // anchors.fill: row + // radius: 14 + // samples: 17 + // color: spinner.foreground + // source: row - transform: Matrix4x4 { - matrix: Qt.matrix4x4(Math.cos(spinner.a), -Math.sin(spinner.a), 0, 0, 0, Math.cos(spinner.a), 0, 0, 0, 0, 1, 0, 0, 0, 0, 1) - } + // transform: Matrix4x4 { + // matrix: Qt.matrix4x4(Math.cos(spinner.a), -Math.sin(spinner.a), 0, 0, 0, Math.cos(spinner.a), 0, 0, 0, 0, 1, 0, 0, 0, 0, 1) + // } - } + //} } diff --git a/resources/qml/ui/animations/BlinkAnimation.qml b/resources/qml/ui/animations/BlinkAnimation.qml index 87e3b135..04625481 100644 --- a/resources/qml/ui/animations/BlinkAnimation.qml +++ b/resources/qml/ui/animations/BlinkAnimation.qml @@ -3,7 +3,6 @@ // // SPDX-License-Identifier: GPL-3.0-or-later -import QtGraphicalEffects 1.12 import QtQuick 2.12 SequentialAnimation { diff --git a/src/Cache.cpp b/src/Cache.cpp index c651b61b..b7862d67 100644 --- a/src/Cache.cpp +++ b/src/Cache.cpp @@ -4040,7 +4040,8 @@ Cache::displayName(const QString &room_id, const QString &user_id) static bool isDisplaynameSafe(const std::string &s) { - for (QChar c : QString::fromStdString(s).toStdU32String()) { + for (uint32_t cc : QString::fromStdString(s).toStdU32String()) { + auto c = QChar(cc); if (c.isPrint() && !c.isSpace()) return false; } diff --git a/src/CompletionProxyModel.cpp b/src/CompletionProxyModel.cpp index 07ecdf72..9387e806 100644 --- a/src/CompletionProxyModel.cpp +++ b/src/CompletionProxyModel.cpp @@ -55,7 +55,7 @@ CompletionProxyModel::CompletionProxyModel(QAbstractItemModel *model, finder.toNextBoundary(); auto end = finder.position(); - auto ref = str.midRef(start, end - start).trimmed(); + auto ref = QStringView(str).mid(start, end - start).trimmed(); if (!ref.isEmpty()) trie_.insert(ref.toUcs4(), i); } while (finder.position() < str.size()); diff --git a/src/JdenticonProvider.h b/src/JdenticonProvider.h index 72c1fa03..db93e190 100644 --- a/src/JdenticonProvider.h +++ b/src/JdenticonProvider.h @@ -78,11 +78,12 @@ public slots: if (queryStart != -1) { id_ = id.left(queryStart); auto query = id.mid(queryStart + 1); - auto queryBits = query.splitRef('&'); + auto queryBits = QStringView(query).split('&'); for (const auto &b : queryBits) { if (b.startsWith(QStringView(u"radius="))) { radius = b.mid(7).toDouble(); + break; } } } diff --git a/src/UserSettingsPage.cpp b/src/UserSettingsPage.cpp index 932c3beb..e9e51267 100644 --- a/src/UserSettingsPage.cpp +++ b/src/UserSettingsPage.cpp @@ -1373,7 +1373,6 @@ UserSettingsModel::data(const QModelIndex &index, int role) const l.push_back(QString::fromStdString(d)); return l; }; - static QFontDatabase fontDb; switch (index.row()) { case Theme: @@ -1393,9 +1392,9 @@ UserSettingsModel::data(const QModelIndex &index, int role) const i->camera().toStdString(), i->cameraResolution().toStdString())); case Font: - return fontDb.families(); + return QFontDatabase::families(); case EmojiFont: - return fontDb.families(QFontDatabase::WritingSystem::Symbol); + return QFontDatabase::families(QFontDatabase::WritingSystem::Symbol); case Ringtone: QStringList l{ QStringLiteral("Mute"), @@ -1438,8 +1437,6 @@ UserSettingsModel::data(const QModelIndex &index, int role) const bool UserSettingsModel::setData(const QModelIndex &index, const QVariant &value, int role) { - static QFontDatabase fontDb; - auto i = UserSettings::instance(); if (role == Value) { switch (index.row()) { @@ -1464,7 +1461,7 @@ UserSettingsModel::setData(const QModelIndex &index, const QVariant &value, int return false; } case ScaleFactor: { - if (value.canConvert(QMetaType::Double)) { + if (value.canConvert(QMetaType::fromType())) { utils::setScaleFactor(static_cast(value.toDouble())); return true; } else @@ -1548,7 +1545,7 @@ UserSettingsModel::setData(const QModelIndex &index, const QVariant &value, int return false; } case TimelineMaxWidth: { - if (value.canConvert(QMetaType::Int)) { + if (value.canConvert(QMetaType::fromType())) { i->setTimelineMaxWidth(value.toInt()); return true; } else @@ -1619,7 +1616,7 @@ UserSettingsModel::setData(const QModelIndex &index, const QVariant &value, int return false; } case PrivacyScreenTimeout: { - if (value.canConvert(QMetaType::Int)) { + if (value.canConvert(QMetaType::fromType())) { i->setPrivacyScreenTimeout(value.toInt()); return true; } else @@ -1633,7 +1630,7 @@ UserSettingsModel::setData(const QModelIndex &index, const QVariant &value, int return false; } case FontSize: { - if (value.canConvert(QMetaType::Double)) { + if (value.canConvert(QMetaType::fromType())) { i->setFontSize(value.toDouble()); return true; } else @@ -1641,7 +1638,7 @@ UserSettingsModel::setData(const QModelIndex &index, const QVariant &value, int } case Font: { if (value.userType() == QMetaType::Int) { - i->setFontFamily(fontDb.families().at(value.toInt())); + i->setFontFamily(QFontDatabase::families().at(value.toInt())); return true; } else return false; @@ -1649,7 +1646,7 @@ UserSettingsModel::setData(const QModelIndex &index, const QVariant &value, int case EmojiFont: { if (value.userType() == QMetaType::Int) { i->setEmojiFontFamily( - fontDb.families(QFontDatabase::WritingSystem::Symbol).at(value.toInt())); + QFontDatabase::families(QFontDatabase::WritingSystem::Symbol).at(value.toInt())); return true; } else return false; diff --git a/src/Utils.cpp b/src/Utils.cpp index 0ac37d8e..b529135e 100644 --- a/src/Utils.cpp +++ b/src/Utils.cpp @@ -268,7 +268,8 @@ utils::firstChar(const QString &input) return QString::fromUcs4(&c, 1).toUpper(); } - return QString::fromUcs4(&input.toUcs4().at(0), 1).toUpper(); + auto c = static_cast(input.toUcs4().at(0)); + return QString::fromUcs4(&c, 1).toUpper(); } QString diff --git a/src/main.cpp b/src/main.cpp index 47ebba27..2941c82e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -152,8 +152,6 @@ main(int argc, char *argv[]) QCoreApplication::setApplicationVersion(nheko::version); QCoreApplication::setOrganizationName(QStringLiteral("nheko")); QCoreApplication::setAttribute(Qt::AA_DontCreateNativeWidgetSiblings); - QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); - QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); // this needs to be after setting the application name. Or how would we find our settings // file then? @@ -287,16 +285,16 @@ main(int argc, char *argv[]) QLocale::setDefault(QLocale(QLocale::English, QLocale::UnitedKingdom)); QTranslator qtTranslator; - qtTranslator.load(QLocale(), + if(qtTranslator.load(QLocale(), QStringLiteral("qt"), QStringLiteral("_"), - QLibraryInfo::location(QLibraryInfo::TranslationsPath)); - app.installTranslator(&qtTranslator); + QLibraryInfo::path(QLibraryInfo::TranslationsPath))) + app.installTranslator(&qtTranslator); QTranslator appTranslator; - appTranslator.load( - QLocale(), QStringLiteral("nheko"), QStringLiteral("_"), QStringLiteral(":/translations")); - app.installTranslator(&appTranslator); + if(appTranslator.load( + QLocale(), QStringLiteral("nheko"), QStringLiteral("_"), QStringLiteral(":/translations"))) + app.installTranslator(&appTranslator); MainWindow w; // QQuickView w; diff --git a/src/timeline/DelegateChooser.cpp b/src/timeline/DelegateChooser.cpp index c8ab1511..0ec42441 100644 --- a/src/timeline/DelegateChooser.cpp +++ b/src/timeline/DelegateChooser.cpp @@ -78,13 +78,13 @@ DelegateChooser::appendChoice(QQmlListProperty *p, DelegateChoic dc->choices_.append(c); } -int +qsizetype DelegateChooser::choiceCount(QQmlListProperty *p) { return static_cast(p->object)->choices_.count(); } DelegateChoice * -DelegateChooser::choice(QQmlListProperty *p, int index) +DelegateChooser::choice(QQmlListProperty *p, qsizetype index) { return static_cast(p->object)->choices_.at(index); } diff --git a/src/timeline/DelegateChooser.h b/src/timeline/DelegateChooser.h index 1772c0c2..19766302 100644 --- a/src/timeline/DelegateChooser.h +++ b/src/timeline/DelegateChooser.h @@ -86,7 +86,7 @@ private: DelegateIncubator incubator{*this}; static void appendChoice(QQmlListProperty *, DelegateChoice *); - static int choiceCount(QQmlListProperty *); - static DelegateChoice *choice(QQmlListProperty *, int index); + static qsizetype choiceCount(QQmlListProperty *); + static DelegateChoice *choice(QQmlListProperty *, qsizetype index); static void clearChoices(QQmlListProperty *); }; diff --git a/src/timeline/InputBar.cpp b/src/timeline/InputBar.cpp index 1de7a141..9db20e69 100644 --- a/src/timeline/InputBar.cpp +++ b/src/timeline/InputBar.cpp @@ -5,12 +5,14 @@ #include "InputBar.h" +#include #include #include #include #include #include #include +#include #include #include #include @@ -52,55 +54,6 @@ MediaUpload::thumbnailDataUrl() const return QString("data:image/png;base64,") + base64; } -bool -InputVideoSurface::present(const QVideoFrame &frame) -{ - QImage::Format format = QVideoFrame::imageFormatFromPixelFormat(frame.pixelFormat()); - - if (format == QImage::Format_Invalid) { - emit newImage({}); - return false; - } else { - QVideoFrame frametodraw(frame); - - if (!frametodraw.map(QAbstractVideoBuffer::ReadOnly)) { - emit newImage({}); - return false; - } - - // this is a shallow operation. it just refer the frame buffer - QImage image(qAsConst(frametodraw).bits(), - frametodraw.width(), - frametodraw.height(), - frametodraw.bytesPerLine(), - format); - image.detach(); - - frametodraw.unmap(); - - emit newImage(std::move(image)); - return true; - } -} - -QList -InputVideoSurface::supportedPixelFormats(QAbstractVideoBuffer::HandleType type) const -{ - if (type == QAbstractVideoBuffer::NoHandle) { - return { - QVideoFrame::Format_ARGB32, - QVideoFrame::Format_ARGB32_Premultiplied, - QVideoFrame::Format_RGB24, - QVideoFrame::Format_BGR24, - QVideoFrame::Format_RGB32, - QVideoFrame::Format_RGB565, - QVideoFrame::Format_RGB555, - }; - } else { - return {}; - } -} - void InputBar::paste(bool fromMouse) { @@ -371,7 +324,7 @@ InputBar::message(const QString &msg, MarkdownOverride useMarkdown, bool rainbow QString body; bool firstLine = true; - auto lines = related.quoted_body.splitRef(u'\n'); + auto lines = QStringView(related.quoted_body).split(u'\n'); for (auto line : qAsConst(lines)) { if (firstLine) { firstLine = false; @@ -799,21 +752,22 @@ MediaUpload::MediaUpload(std::unique_ptr source_, blurhash_ = QString::fromStdString(blurhash::encode(data_.data(), img.width(), img.height(), 4, 3)); } else if (mimeClass_ == u"video" || mimeClass_ == u"audio") { - auto mediaPlayer = new QMediaPlayer( - this, - mimeClass_ == u"video" ? QFlags{QMediaPlayer::VideoSurface} : QMediaPlayer::Flags{}); - mediaPlayer->setMuted(true); + auto mediaPlayer = new QMediaPlayer(this); + + mediaPlayer->setAudioOutput(nullptr); if (mimeClass_ == u"video") { - auto newSurface = new InputVideoSurface(this); + auto newSurface = new QVideoSink(this); connect( - newSurface, &InputVideoSurface::newImage, this, [this, mediaPlayer](QImage img) { + newSurface, &QVideoSink::videoFrameChanged, this, [this, mediaPlayer](const QVideoFrame& frame) { + QImage img = frame.toImage(); + if (img.size().isEmpty()) return; mediaPlayer->stop(); - auto orientation = mediaPlayer->metaData(QMediaMetaData::Orientation).toInt(); + auto orientation = mediaPlayer->metaData().value(QMediaMetaData::Orientation).toInt(); if (orientation == 90 || orientation == 270 || orientation == 180) { img = img.transformed(QTransform().rotate(orientation), Qt::SmoothTransformation); @@ -844,11 +798,11 @@ MediaUpload::MediaUpload(std::unique_ptr source_, } connect(mediaPlayer, - qOverload(&QMediaPlayer::error), + &QMediaPlayer::error, this, - [mediaPlayer](QMediaPlayer::Error error) { + [mediaPlayer]() { nhlog::ui()->debug("Media player error {} and errorStr {}", - error, + mediaPlayer->error(), mediaPlayer->errorString().toStdString()); }); connect(mediaPlayer, @@ -858,18 +812,18 @@ MediaUpload::MediaUpload(std::unique_ptr source_, "Media player status {} and error {}", status, mediaPlayer->error()); }); connect(mediaPlayer, - qOverload(&QMediaPlayer::metaDataChanged), - [this, mediaPlayer](QString t, QVariant) { - nhlog::ui()->debug("Got metadata {}", t.toStdString()); + &QMediaPlayer::metaDataChanged, + [this, mediaPlayer]() { + nhlog::ui()->debug("Got metadata"); if (mediaPlayer->duration() > 0) this->duration_ = mediaPlayer->duration(); - auto dimensions = mediaPlayer->metaData(QMediaMetaData::Resolution).toSize(); + auto dimensions = mediaPlayer->metaData().value(QMediaMetaData::Resolution).toSize(); if (!dimensions.isEmpty()) { dimensions_ = dimensions; auto orientation = - mediaPlayer->metaData(QMediaMetaData::Orientation).toInt(); + mediaPlayer->metaData().value(QMediaMetaData::Orientation).toInt(); if (orientation == 90 || orientation == 270) { dimensions_.transpose(); } @@ -886,8 +840,8 @@ MediaUpload::MediaUpload(std::unique_ptr source_, auto originalFile = qobject_cast(source.get()); - mediaPlayer->setMedia( - QMediaContent(originalFile ? originalFile->fileName() : originalFilename_), source.get()); + mediaPlayer->setSourceDevice( + source.get(), QUrl(originalFile ? originalFile->fileName() : originalFilename_) ); mediaPlayer->play(); } diff --git a/src/timeline/InputBar.h b/src/timeline/InputBar.h index 28a4bcf6..7d276806 100644 --- a/src/timeline/InputBar.h +++ b/src/timeline/InputBar.h @@ -5,7 +5,6 @@ #pragma once -#include #include #include #include @@ -32,24 +31,6 @@ enum class MarkdownOverride OFF, }; -class InputVideoSurface : public QAbstractVideoSurface -{ - Q_OBJECT - -public: - InputVideoSurface(QObject *parent) - : QAbstractVideoSurface(parent) - {} - - bool present(const QVideoFrame &frame) override; - - QList - supportedPixelFormats(QAbstractVideoBuffer::HandleType type) const override; - -signals: - void newImage(QImage img); -}; - class MediaUpload : public QObject { Q_OBJECT diff --git a/src/timeline/TimelineViewManager.cpp b/src/timeline/TimelineViewManager.cpp index 3bccd8f3..c6576507 100644 --- a/src/timeline/TimelineViewManager.cpp +++ b/src/timeline/TimelineViewManager.cpp @@ -272,7 +272,7 @@ TimelineViewManager::saveMedia(QString mxcUrl) { const QString downloadsFolder = QStandardPaths::writableLocation(QStandardPaths::DownloadLocation); - const QString openLocation = downloadsFolder + "/" + mxcUrl.splitRef(u'/').constLast(); + const QString openLocation = downloadsFolder + "/" + mxcUrl.split(u'/').constLast(); const QString filename = QFileDialog::getSaveFileName(nullptr, {}, openLocation); diff --git a/src/ui/MxcAnimatedImage.cpp b/src/ui/MxcAnimatedImage.cpp index b8e707bb..98d18476 100644 --- a/src/ui/MxcAnimatedImage.cpp +++ b/src/ui/MxcAnimatedImage.cpp @@ -148,9 +148,9 @@ MxcAnimatedImage::startDownload() } void -MxcAnimatedImage::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) +MxcAnimatedImage::geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) { - QQuickItem::geometryChanged(newGeometry, oldGeometry); + QQuickItem::geometryChange(newGeometry, oldGeometry); if (newGeometry.size() != oldGeometry.size()) { if (height() != 0 && width() != 0) diff --git a/src/ui/MxcAnimatedImage.h b/src/ui/MxcAnimatedImage.h index 8891e57e..8f4c639b 100644 --- a/src/ui/MxcAnimatedImage.h +++ b/src/ui/MxcAnimatedImage.h @@ -60,7 +60,7 @@ public: } } - void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) override; + void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) override; QSGNode *updatePaintNode(QSGNode *oldNode, QQuickItem::UpdatePaintNodeData *updatePaintNodeData) override; diff --git a/src/ui/MxcMediaProxy.cpp b/src/ui/MxcMediaProxy.cpp index 96ef89b5..007a4148 100644 --- a/src/ui/MxcMediaProxy.cpp +++ b/src/ui/MxcMediaProxy.cpp @@ -9,17 +9,11 @@ #include #include #include -#include #include #include #include #include -#if defined(Q_OS_MACOS) -// TODO (red_sky): Remove for Qt6. See other ifdef below -#include -#endif - #include "EventAccessors.h" #include "Logging.h" #include "MatrixClient.h" @@ -31,44 +25,27 @@ MxcMediaProxy::MxcMediaProxy(QObject *parent) connect(this, &MxcMediaProxy::eventIdChanged, &MxcMediaProxy::startDownload); connect(this, &MxcMediaProxy::roomChanged, &MxcMediaProxy::startDownload); connect(this, - qOverload(&MxcMediaProxy::error), - [this](QMediaPlayer::Error error) { + &MxcMediaProxy::error, + [this]() { nhlog::ui()->info("Media player error {} and errorStr {}", - error, + error(), this->errorString().toStdString()); }); connect(this, &MxcMediaProxy::mediaStatusChanged, [this](QMediaPlayer::MediaStatus status) { nhlog::ui()->info("Media player status {} and error {}", status, this->error()); }); connect(this, - qOverload(&MxcMediaProxy::metaDataChanged), - [this](QString t, QVariant) { - if (t == QMediaMetaData::Orientation) - emit orientationChanged(); + &MxcMediaProxy::metaDataChanged, + [this]() { + emit orientationChanged(); }); } -void -MxcMediaProxy::setVideoSurface(QAbstractVideoSurface *surface) -{ - if (surface != m_surface) { - qDebug() << "Changing surface"; - m_surface = surface; - setVideoOutput(m_surface); - emit videoSurfaceChanged(); - } -} - -QAbstractVideoSurface * -MxcMediaProxy::getVideoSurface() -{ - return m_surface; -} int MxcMediaProxy::orientation() const { - nhlog::ui()->debug("metadata: {}", availableMetaData().join(QStringLiteral(",")).toStdString()); - auto orientation = metaData(QMediaMetaData::Orientation).toInt(); + //nhlog::ui()->debug("metadata: {}", metaData(). + auto orientation = metaData().value(QMediaMetaData::Orientation).toInt(); nhlog::ui()->debug("Video orientation: {}", orientation); return orientation; } @@ -129,34 +106,10 @@ MxcMediaProxy::startDownload() buffer.open(QIODevice::ReadOnly); buffer.reset(); - QTimer::singleShot(0, this, [this, filename, suffix, encryptionInfo] { -#if defined(Q_OS_MACOS) - if (encryptionInfo) { - // macOS has issues reading from a buffer in setMedia for whatever reason. - // Instead, write the buffer to a temporary file and read from that. - // This should be fixed in Qt6, so update this when we do that! - // TODO: REMOVE IN QT6 - QTemporaryFile tempFile; - tempFile.setFileTemplate(tempFile.fileTemplate() + QLatin1Char('.') + suffix); - tempFile.open(); - tempFile.write(buffer.data()); - tempFile.close(); - nhlog::ui()->debug("Playing media from temp buffer file: {}. Remove in QT6!", - filename.filePath().toStdString()); - this->setMedia(QUrl::fromLocalFile(tempFile.fileName())); - } else { - nhlog::ui()->info( - "Playing buffer with size: {}, {}", buffer.bytesAvailable(), buffer.isOpen()); - this->setMedia(QUrl::fromLocalFile(filename.filePath())); - } -#else - Q_UNUSED(suffix) - Q_UNUSED(encryptionInfo) - + QTimer::singleShot(0, this, [this, filename] { nhlog::ui()->info( "Playing buffer with size: {}, {}", buffer.bytesAvailable(), buffer.isOpen()); - this->setMedia(QMediaContent(filename.fileName()), &buffer); -#endif + this->setSourceDevice( &buffer, QUrl(filename.fileName())); emit loadedChanged(); }); }; diff --git a/src/ui/MxcMediaProxy.h b/src/ui/MxcMediaProxy.h index 1b6bf34e..df67f561 100644 --- a/src/ui/MxcMediaProxy.h +++ b/src/ui/MxcMediaProxy.h @@ -5,14 +5,14 @@ #pragma once -#include +#include #include -#include #include #include #include #include +#include "timeline/TimelineModel.h" #include "Logging.h" class TimelineModel; @@ -24,8 +24,6 @@ class MxcMediaProxy : public QMediaPlayer Q_OBJECT Q_PROPERTY(TimelineModel *roomm READ room WRITE setRoom NOTIFY roomChanged REQUIRED) Q_PROPERTY(QString eventId READ eventId WRITE setEventId NOTIFY eventIdChanged) - Q_PROPERTY(QAbstractVideoSurface *videoSurface READ getVideoSurface WRITE setVideoSurface NOTIFY - videoSurfaceChanged) Q_PROPERTY(bool loaded READ loaded NOTIFY loadedChanged) Q_PROPERTY(int orientation READ orientation NOTIFY orientationChanged) @@ -45,8 +43,6 @@ public: room_ = room; emit roomChanged(); } - void setVideoSurface(QAbstractVideoSurface *surface); - QAbstractVideoSurface *getVideoSurface(); int orientation() const; @@ -54,10 +50,9 @@ signals: void roomChanged(); void eventIdChanged(); void loadedChanged(); - void newBuffer(QMediaContent, QIODevice *buf); + void newBuffer(QUrl, QIODevice *buf); void orientationChanged(); - void videoSurfaceChanged(); private slots: void startDownload(); @@ -67,5 +62,5 @@ private: QString eventId_; QString filename_; QBuffer buffer; - QAbstractVideoSurface *m_surface = nullptr; + QObject *m_surface = nullptr; }; diff --git a/src/voip/CallManager.cpp b/src/voip/CallManager.cpp index 54d86620..118550e9 100644 --- a/src/voip/CallManager.cpp +++ b/src/voip/CallManager.cpp @@ -10,7 +10,6 @@ #include #include -#include #include #include "Cache.h" @@ -144,11 +143,11 @@ CallManager::CallManager(QObject *parent) }); connect(&player_, - QOverload::of(&QMediaPlayer::error), + &QMediaPlayer::error, this, - [this](QMediaPlayer::Error error) { + [this]() { stopRingtone(); - switch (error) { + switch (player_.error()) { case QMediaPlayer::FormatError: case QMediaPlayer::ResourceError: nhlog::ui()->error("WebRTC: valid ringtone file not found"); @@ -497,19 +496,17 @@ CallManager::retrieveTurnServer() void CallManager::playRingtone(const QUrl &ringtone, bool repeat) { - static QMediaPlaylist playlist; - playlist.clear(); - playlist.setPlaybackMode(repeat ? QMediaPlaylist::CurrentItemInLoop - : QMediaPlaylist::CurrentItemOnce); - playlist.addMedia(ringtone); - player_.setVolume(100); - player_.setPlaylist(&playlist); + player_.setLoops(repeat ? QMediaPlayer::Infinite : + 1); + player_.setSource(ringtone); + //player_.audioOutput()->setVolume(100); + player_.play(); } void CallManager::stopRingtone() { - player_.setPlaylist(nullptr); + player_.stop(); } QStringList