Basic running app on qt6

qt6
Nicolas Werner 3 years ago
parent 8c66945be9
commit 7303275793
No known key found for this signature in database
GPG Key ID: C8D75E610773F2D9
  1. 35
      CMakeLists.txt
  2. 9
      cmake/Translations.cmake
  3. 14
      resources/qml/PrivacyScreen.qml
  4. 21
      resources/qml/Root.qml
  5. 22
      resources/qml/components/FlatButton.qml
  6. 17
      resources/qml/delegates/PlayableMediaMessage.qml
  7. 1
      resources/qml/emoji/EmojiPicker.qml
  8. 1
      resources/qml/emoji/StickerPicker.qml
  9. 1
      resources/qml/ui/Ripple.qml
  10. 22
      resources/qml/ui/Spinner.qml
  11. 1
      resources/qml/ui/animations/BlinkAnimation.qml
  12. 3
      src/Cache.cpp
  13. 2
      src/CompletionProxyModel.cpp
  14. 3
      src/JdenticonProvider.h
  15. 19
      src/UserSettingsPage.cpp
  16. 3
      src/Utils.cpp
  17. 14
      src/main.cpp
  18. 4
      src/timeline/DelegateChooser.cpp
  19. 4
      src/timeline/DelegateChooser.h
  20. 88
      src/timeline/InputBar.cpp
  21. 19
      src/timeline/InputBar.h
  22. 2
      src/timeline/TimelineViewManager.cpp
  23. 4
      src/ui/MxcAnimatedImage.cpp
  24. 2
      src/ui/MxcAnimatedImage.h
  25. 67
      src/ui/MxcMediaProxy.cpp
  26. 13
      src/ui/MxcMediaProxy.h
  27. 21
      src/voip/CallManager.cpp

@ -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

@ -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} " </qresource>\n</RCC>\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()

@ -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
//}
}

@ -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

@ -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

@ -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
}

@ -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

@ -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

@ -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

@ -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)
// }
}
//}
}

@ -3,7 +3,6 @@
//
// SPDX-License-Identifier: GPL-3.0-or-later
import QtGraphicalEffects 1.12
import QtQuick 2.12
SequentialAnimation {

@ -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;
}

@ -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());

@ -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;
}
}
}

@ -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<double>())) {
utils::setScaleFactor(static_cast<float>(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<int>())) {
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<int>())) {
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<double>())) {
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;

@ -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<char32_t>(input.toUcs4().at(0));
return QString::fromUcs4(&c, 1).toUpper();
}
QString

@ -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;

@ -78,13 +78,13 @@ DelegateChooser::appendChoice(QQmlListProperty<DelegateChoice> *p, DelegateChoic
dc->choices_.append(c);
}
int
qsizetype
DelegateChooser::choiceCount(QQmlListProperty<DelegateChoice> *p)
{
return static_cast<DelegateChooser *>(p->object)->choices_.count();
}
DelegateChoice *
DelegateChooser::choice(QQmlListProperty<DelegateChoice> *p, int index)
DelegateChooser::choice(QQmlListProperty<DelegateChoice> *p, qsizetype index)
{
return static_cast<DelegateChooser *>(p->object)->choices_.at(index);
}

@ -86,7 +86,7 @@ private:
DelegateIncubator incubator{*this};
static void appendChoice(QQmlListProperty<DelegateChoice> *, DelegateChoice *);
static int choiceCount(QQmlListProperty<DelegateChoice> *);
static DelegateChoice *choice(QQmlListProperty<DelegateChoice> *, int index);
static qsizetype choiceCount(QQmlListProperty<DelegateChoice> *);
static DelegateChoice *choice(QQmlListProperty<DelegateChoice> *, qsizetype index);
static void clearChoices(QQmlListProperty<DelegateChoice> *);
};

@ -5,12 +5,14 @@
#include "InputBar.h"
#include <QVideoSink>
#include <QBuffer>
#include <QClipboard>
#include <QDropEvent>
#include <QFileDialog>
#include <QGuiApplication>
#include <QInputMethod>
#include <QVideoFrame>
#include <QMediaMetaData>
#include <QMediaPlayer>
#include <QMimeData>
@ -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<QVideoFrame::PixelFormat>
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<QIODevice> 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<QIODevice> source_,
}
connect(mediaPlayer,
qOverload<QMediaPlayer::Error>(&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<QIODevice> source_,
"Media player status {} and error {}", status, mediaPlayer->error());
});
connect(mediaPlayer,
qOverload<const QString &, const QVariant &>(&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<QIODevice> source_,
auto originalFile = qobject_cast<QFile *>(source.get());
mediaPlayer->setMedia(
QMediaContent(originalFile ? originalFile->fileName() : originalFilename_), source.get());
mediaPlayer->setSourceDevice(
source.get(), QUrl(originalFile ? originalFile->fileName() : originalFilename_) );
mediaPlayer->play();
}

@ -5,7 +5,6 @@
#pragma once
#include <QAbstractVideoSurface>
#include <QIODevice>
#include <QImage>
#include <QObject>
@ -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<QVideoFrame::PixelFormat>
supportedPixelFormats(QAbstractVideoBuffer::HandleType type) const override;
signals:
void newImage(QImage img);
};
class MediaUpload : public QObject
{
Q_OBJECT

@ -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);

@ -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)

@ -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;

@ -9,17 +9,11 @@
#include <QFile>
#include <QFileInfo>
#include <QMediaMetaData>
#include <QMediaObject>
#include <QMediaPlayer>
#include <QMimeDatabase>
#include <QStandardPaths>
#include <QUrl>
#if defined(Q_OS_MACOS)
// TODO (red_sky): Remove for Qt6. See other ifdef below
#include <QTemporaryFile>
#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<QMediaPlayer::Error>(&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<const QString &, const QVariant &>(&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();
});
};

@ -5,14 +5,14 @@
#pragma once
#include <QAbstractVideoSurface>
#include <QVideoSink>
#include <QBuffer>
#include <QMediaContent>
#include <QMediaPlayer>
#include <QObject>
#include <QPointer>
#include <QString>
#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;
};

@ -10,7 +10,6 @@
#include <cstdlib>
#include <memory>
#include <QMediaPlaylist>
#include <QUrl>
#include "Cache.h"
@ -144,11 +143,11 @@ CallManager::CallManager(QObject *parent)
});
connect(&player_,
QOverload<QMediaPlayer::Error>::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

Loading…
Cancel
Save