mirror of
https://git.jami.net/savoirfairelinux/jami-client-qt.git
synced 2025-09-10 12:03:18 +02:00
qml interop: start replacing QMetaObject::invokeMethod with signals
It seems concurrent calls to invokeMethod using qml component object pointers can lead to access violations. These method invocations can be replaced with a signal/slot mechanism. This patch replaces only the invocations in conversationsadapter and accountsadapter that are known to be problematic for now. Some code cleanup is done for QmlAdapterBase derived classes. Gitlab: #61 Change-Id: I72f47c9229a9bf42299ae52822c3a1a8c04eb423
This commit is contained in:
parent
346b255c77
commit
eb53a622b7
22 changed files with 147 additions and 191 deletions
|
@ -174,7 +174,6 @@ SOURCES += ./src/bannedlistmodel.cpp \
|
|||
./src/conversationsadapter.cpp \
|
||||
./src/distantrenderer.cpp \
|
||||
./src/previewrenderer.cpp \
|
||||
./src/qmladapterbase.cpp \
|
||||
./src/avadapter.cpp \
|
||||
./src/contactadapter.cpp \
|
||||
./src/mediahandleradapter.cpp \
|
||||
|
|
|
@ -30,8 +30,6 @@ AccountAdapter::AccountAdapter(QObject *parent)
|
|||
: QmlAdapterBase(parent)
|
||||
{}
|
||||
|
||||
AccountAdapter::~AccountAdapter() {}
|
||||
|
||||
AccountAdapter &
|
||||
AccountAdapter::instance()
|
||||
{
|
||||
|
@ -40,7 +38,7 @@ AccountAdapter::instance()
|
|||
}
|
||||
|
||||
void
|
||||
AccountAdapter::initQmlObject()
|
||||
AccountAdapter::safeInit()
|
||||
{
|
||||
setSelectedAccount(LRCInstance::getCurrAccId());
|
||||
}
|
||||
|
@ -334,7 +332,7 @@ void
|
|||
AccountAdapter::backToWelcomePage()
|
||||
{
|
||||
deselectConversation();
|
||||
QMetaObject::invokeMethod(qmlObj_, "backToWelcomePage");
|
||||
emit navigateToWelcomePageRequested();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -27,13 +27,18 @@
|
|||
#include "lrcinstance.h"
|
||||
#include "utils.h"
|
||||
|
||||
class AccountAdapter : public QmlAdapterBase
|
||||
class AccountAdapter final : public QmlAdapterBase
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit AccountAdapter(QObject *parent = 0);
|
||||
~AccountAdapter();
|
||||
~AccountAdapter() = default;
|
||||
|
||||
protected:
|
||||
void safeInit() override;
|
||||
|
||||
public:
|
||||
//Singleton
|
||||
static AccountAdapter &instance();
|
||||
|
||||
|
@ -94,9 +99,9 @@ signals:
|
|||
*/
|
||||
void reportFailure();
|
||||
void accountAdded(bool showBackUp, int index);
|
||||
void navigateToWelcomePageRequested();
|
||||
|
||||
private:
|
||||
void initQmlObject() override final;
|
||||
void setSelectedAccount(const QString &accountId);
|
||||
void backToWelcomePage();
|
||||
void deselectConversation();
|
||||
|
|
|
@ -28,12 +28,6 @@ AvAdapter::AvAdapter(QObject *parent)
|
|||
: QmlAdapterBase(parent)
|
||||
{}
|
||||
|
||||
AvAdapter::~AvAdapter() {}
|
||||
|
||||
void
|
||||
AvAdapter::initQmlObject()
|
||||
{}
|
||||
|
||||
QVariantMap
|
||||
AvAdapter::populateVideoDeviceContextMenuItem()
|
||||
{
|
||||
|
|
|
@ -24,13 +24,16 @@
|
|||
#include <QVariant>
|
||||
#include <QString>
|
||||
|
||||
class AvAdapter : public QmlAdapterBase
|
||||
class AvAdapter final : public QmlAdapterBase
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit AvAdapter(QObject *parent = nullptr);
|
||||
~AvAdapter();
|
||||
~AvAdapter() = default;
|
||||
|
||||
protected:
|
||||
void safeInit() override {};
|
||||
|
||||
/*
|
||||
* Return needed info for populating video device context menu item.
|
||||
|
@ -62,6 +65,4 @@ public:
|
|||
*/
|
||||
Q_INVOKABLE void shareScreenArea(int screenNumber, int x, int y, int width, int height);
|
||||
|
||||
private:
|
||||
void initQmlObject() override;
|
||||
};
|
||||
|
|
|
@ -30,12 +30,6 @@
|
|||
CallAdapter::CallAdapter(QObject* parent)
|
||||
: QmlAdapterBase(parent)
|
||||
, oneSecondTimer_(new QTimer(this))
|
||||
{}
|
||||
|
||||
CallAdapter::~CallAdapter() {}
|
||||
|
||||
void
|
||||
CallAdapter::initQmlObject()
|
||||
{
|
||||
connectCallModel(LRCInstance::getCurrAccId());
|
||||
|
||||
|
@ -676,4 +670,4 @@ CallAdapter::setTime(const QString& accountId, const QString& convUid)
|
|||
auto timeString = LRCInstance::getCurrentCallModel()->getFormattedCallDuration(callId);
|
||||
emit updateTimeText(timeString);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,19 +26,18 @@
|
|||
#include <QString>
|
||||
#include <QVariant>
|
||||
|
||||
class CallAdapter : public QmlAdapterBase
|
||||
class CallAdapter final : public QmlAdapterBase
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit CallAdapter(QObject* parent = nullptr);
|
||||
~CallAdapter();
|
||||
~CallAdapter() = default;
|
||||
|
||||
/*
|
||||
* This is needed to be public since it has to be recognized by qml.
|
||||
*/
|
||||
Q_INVOKABLE void initQmlObject() override;
|
||||
protected:
|
||||
void safeInit() override {};
|
||||
|
||||
public:
|
||||
Q_INVOKABLE void placeAudioOnlyCall();
|
||||
Q_INVOKABLE void placeCall();
|
||||
Q_INVOKABLE void hangUpACall(const QString& accountId, const QString& convUid);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/*!
|
||||
* Copyright (C) 2020 by Savoir-faire Linux
|
||||
* Author: Edric Ladent Milaret <edric.ladent-milaret@savoirfairelinux.com>
|
||||
* Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>
|
||||
|
@ -28,8 +28,6 @@ ContactAdapter::ContactAdapter(QObject *parent)
|
|||
selectableProxyModel_.reset(new SelectableProxyModel(smartListModel_.get()));
|
||||
}
|
||||
|
||||
ContactAdapter::~ContactAdapter() {}
|
||||
|
||||
QVariant
|
||||
ContactAdapter::getContactSelectableModel(int type)
|
||||
{
|
||||
|
@ -175,7 +173,3 @@ ContactAdapter::setCalleeDisplayName(const QString &name)
|
|||
{
|
||||
calleeDisplayName_ = name;
|
||||
}
|
||||
|
||||
void
|
||||
ContactAdapter::initQmlObject()
|
||||
{}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/*!
|
||||
* Copyright (C) 2020 by Savoir-faire Linux
|
||||
* Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com>
|
||||
*
|
||||
|
@ -34,7 +34,7 @@
|
|||
*
|
||||
* Additionally, user need to setFilterRegExp to be able to get input QRegExp from FilterPredicate.
|
||||
*/
|
||||
class SelectableProxyModel : public QSortFilterProxyModel
|
||||
class SelectableProxyModel final : public QSortFilterProxyModel
|
||||
{
|
||||
public:
|
||||
using FilterPredicate = std::function<bool(const QModelIndex &, const QRegExp &)>;
|
||||
|
@ -68,13 +68,16 @@ private:
|
|||
std::function<bool(const QModelIndex &, const QRegExp &)> filterPredicate_;
|
||||
};
|
||||
|
||||
class ContactAdapter : public QmlAdapterBase
|
||||
class ContactAdapter final : public QmlAdapterBase
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ContactAdapter(QObject *parent = nullptr);
|
||||
~ContactAdapter();
|
||||
~ContactAdapter() = default;
|
||||
|
||||
protected:
|
||||
void safeInit() override {};
|
||||
|
||||
Q_INVOKABLE QVariant getContactSelectableModel(int type);
|
||||
Q_INVOKABLE void setSearchFilter(const QString &filter);
|
||||
|
@ -82,8 +85,6 @@ public:
|
|||
Q_INVOKABLE void setCalleeDisplayName(const QString &name);
|
||||
|
||||
private:
|
||||
void initQmlObject() override;
|
||||
|
||||
SmartListModel::Type listModeltype_;
|
||||
|
||||
/*
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/*!
|
||||
* Copyright (C) 2020 by Savoir-faire Linux
|
||||
* Author: Edric Ladent Milaret <edric.ladent-milaret@savoirfairelinux.com>
|
||||
* Author: Anthony L�onard <anthony.leonard@savoirfairelinux.com>
|
||||
|
@ -29,15 +29,12 @@ ConversationsAdapter::ConversationsAdapter(QObject *parent)
|
|||
: QmlAdapterBase(parent)
|
||||
{}
|
||||
|
||||
ConversationsAdapter::~ConversationsAdapter() {}
|
||||
|
||||
void
|
||||
ConversationsAdapter::initQmlObject()
|
||||
ConversationsAdapter::safeInit()
|
||||
{
|
||||
conversationSmartListModel_ = new SmartListModel(LRCInstance::getCurrAccId(), this);
|
||||
|
||||
QMetaObject::invokeMethod(qmlObj_, "setModel",
|
||||
Q_ARG(QVariant, QVariant::fromValue(conversationSmartListModel_)));
|
||||
emit modelChanged(QVariant::fromValue(conversationSmartListModel_));
|
||||
|
||||
connect(&LRCInstance::behaviorController(),
|
||||
&BehaviorController::showChatView,
|
||||
|
@ -57,7 +54,7 @@ void
|
|||
ConversationsAdapter::backToWelcomePage()
|
||||
{
|
||||
deselectConversation();
|
||||
QMetaObject::invokeMethod(qmlObj_, "backToWelcomePage");
|
||||
emit navigateToWelcomePageRequested();
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -198,7 +195,7 @@ ConversationsAdapter::connectConversationModel(bool updateFilter)
|
|||
[this]() {
|
||||
conversationSmartListModel_->fillConversationsList();
|
||||
updateConversationsFilterWidget();
|
||||
QMetaObject::invokeMethod(qmlObj_, "updateConversationSmartListView");
|
||||
emit updateListViewRequested();
|
||||
auto* convModel = LRCInstance::getCurrentConversationModel();
|
||||
const auto conversation = convModel->getConversationForUID(LRCInstance::getCurrentConvUid());
|
||||
|
||||
|
@ -211,7 +208,7 @@ ConversationsAdapter::connectConversationModel(bool updateFilter)
|
|||
== lrc::api::profile::Type::TEMPORARY) {
|
||||
return;
|
||||
}
|
||||
QMetaObject::invokeMethod(qmlObj_, "modelSorted", Q_ARG(QVariant, contactURI));
|
||||
emit modelSorted(QVariant::fromValue(contactURI));
|
||||
});
|
||||
|
||||
modelUpdatedConnection_ = QObject::connect(currentConversationModel,
|
||||
|
@ -219,7 +216,7 @@ ConversationsAdapter::connectConversationModel(bool updateFilter)
|
|||
[this](const QString &convUid) {
|
||||
conversationSmartListModel_->updateConversation(convUid);
|
||||
updateConversationsFilterWidget();
|
||||
QMetaObject::invokeMethod(qmlObj_, "updateConversationSmartListView");
|
||||
emit updateListViewRequested();
|
||||
});
|
||||
|
||||
filterChangedConnection_ = QObject::connect(currentConversationModel,
|
||||
|
@ -228,7 +225,7 @@ ConversationsAdapter::connectConversationModel(bool updateFilter)
|
|||
conversationSmartListModel_->fillConversationsList();
|
||||
conversationSmartListModel_->setAccount(LRCInstance::getCurrAccId());
|
||||
updateConversationsFilterWidget();
|
||||
QMetaObject::invokeMethod(qmlObj_, "updateConversationSmartListView");
|
||||
emit updateListViewRequested();
|
||||
});
|
||||
|
||||
newConversationConnection_ = QObject::connect(currentConversationModel,
|
||||
|
@ -265,9 +262,10 @@ ConversationsAdapter::connectConversationModel(bool updateFilter)
|
|||
searchResultUpdatedConnection_ = QObject::connect(currentConversationModel,
|
||||
&lrc::api::ConversationModel::searchResultUpdated,
|
||||
[this]() {
|
||||
|
||||
conversationSmartListModel_->fillConversationsList();
|
||||
conversationSmartListModel_->setAccount(LRCInstance::getCurrAccId());
|
||||
QMetaObject::invokeMethod(qmlObj_, "updateConversationSmartListView");
|
||||
emit updateListViewRequested();
|
||||
});
|
||||
|
||||
if (updateFilter) currentConversationModel->setFilter("");
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/*!
|
||||
* Copyright (C) 2020 by Savoir-faire Linux
|
||||
* Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com>
|
||||
*
|
||||
|
@ -25,14 +25,17 @@
|
|||
#include <QObject>
|
||||
#include <QString>
|
||||
|
||||
class ConversationsAdapter : public QmlAdapterBase
|
||||
class ConversationsAdapter final : public QmlAdapterBase
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ConversationsAdapter(QObject *parent = nullptr);
|
||||
~ConversationsAdapter();
|
||||
~ConversationsAdapter() = default;
|
||||
|
||||
protected:
|
||||
void safeInit() override;
|
||||
|
||||
public:
|
||||
Q_INVOKABLE bool connectConversationModel(bool updateFilter = true);
|
||||
Q_INVOKABLE void disconnectConversationModel();
|
||||
Q_INVOKABLE void selectConversation(const QString &accountId,
|
||||
|
@ -50,8 +53,12 @@ signals:
|
|||
void showConversationTabs(bool visible);
|
||||
void showSearchStatus(const QString &status);
|
||||
|
||||
void modelChanged(const QVariant& model);
|
||||
void modelSorted(const QVariant& uri);
|
||||
void updateListViewRequested();
|
||||
void navigateToWelcomePageRequested();
|
||||
|
||||
private:
|
||||
void initQmlObject() override;
|
||||
void setConversationFilter(lrc::api::profile::Type filter);
|
||||
void backToWelcomePage();
|
||||
bool selectConversation(const lrc::api::conversation::Info &item,
|
||||
|
|
|
@ -704,10 +704,6 @@ Window {
|
|||
height: userProfile.contentHeight
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
CallAdapter.initQmlObject()
|
||||
}
|
||||
|
||||
onClosing: {
|
||||
close.accepted = false
|
||||
mainViewWindow.hide()
|
||||
|
|
|
@ -27,14 +27,10 @@ ComboBox {
|
|||
id: accountComboBox
|
||||
|
||||
signal accountChanged(int index)
|
||||
signal needToBackToWelcomePage()
|
||||
signal needToBackToWelcomePage
|
||||
signal newAccountButtonClicked
|
||||
signal settingBtnClicked
|
||||
|
||||
function backToWelcomePage() {
|
||||
needToBackToWelcomePage()
|
||||
}
|
||||
|
||||
// Reset accountListModel.
|
||||
function resetAccountListModel() {
|
||||
accountListModel.reset()
|
||||
|
@ -53,6 +49,14 @@ ComboBox {
|
|||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: ClientWrapper.accountAdaptor
|
||||
|
||||
function onNavigateToWelcomePageRequested() {
|
||||
needToBackToWelcomePage()
|
||||
}
|
||||
}
|
||||
|
||||
Image {
|
||||
id: userImageRoot
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
|
||||
/*
|
||||
* Copyright (C) 2020 by Savoir-faire Linux
|
||||
* Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com>
|
||||
* Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -16,13 +16,14 @@
|
|||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import QtQuick 2.14
|
||||
import QtQuick.Controls 2.14
|
||||
import QtQuick.Layouts 1.14
|
||||
import net.jami.Models 1.0
|
||||
|
||||
ListView {
|
||||
id: conversationSmartListView
|
||||
id: root
|
||||
|
||||
signal needToAccessMessageWebView(string currentUserDisplayName, string currentUserAlias, string currentUID, bool callStackViewShouldShow, bool isAudioOnly, int callState)
|
||||
signal needToSelectItems(string conversationUid)
|
||||
|
@ -34,60 +35,59 @@ ListView {
|
|||
signal currentIndexIsChanged
|
||||
signal forceUpdatePotentialInvalidItem
|
||||
|
||||
|
||||
/*
|
||||
* When model is sorted, we need to reset to focus (currentIndex)
|
||||
* to the real conversation that we focused.
|
||||
*/
|
||||
function modelSorted(contactURIToCompare) {
|
||||
var conversationSmartListViewModel = conversationSmartListView.model
|
||||
conversationSmartListView.currentIndex = -1
|
||||
updateConversationSmartListView()
|
||||
for (var i = 0; i < count; i++) {
|
||||
if (conversationSmartListViewModel.data(
|
||||
conversationSmartListViewModel.index(i, 0),
|
||||
261) === contactURIToCompare) {
|
||||
conversationSmartListView.currentIndex = i
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Refresh all item within model.
|
||||
*/
|
||||
function updateConversationSmartListView() {
|
||||
var conversationSmartListViewModel = conversationSmartListView.model
|
||||
conversationSmartListViewModel.dataChanged(
|
||||
conversationSmartListViewModel.index(0, 0),
|
||||
conversationSmartListViewModel.index(
|
||||
conversationSmartListViewModel.rowCount() - 1, 0))
|
||||
conversationSmartListView.forceUpdatePotentialInvalidItem()
|
||||
}
|
||||
|
||||
function setModel(model) {
|
||||
conversationSmartListView.model = model
|
||||
}
|
||||
|
||||
function backToWelcomePage() {
|
||||
conversationSmartListView.needToBackToWelcomePage()
|
||||
// Refresh all items within the model.
|
||||
function updateListView() {
|
||||
root.model.dataChanged(
|
||||
root.model.index(0, 0),
|
||||
root.model.index(
|
||||
root.model.rowCount() - 1, 0))
|
||||
root.forceUpdatePotentialInvalidItem()
|
||||
}
|
||||
|
||||
ConversationSmartListContextMenu {
|
||||
id: smartListContextMenu
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: ConversationsAdapter
|
||||
|
||||
function onModelChanged(model) {
|
||||
root.model = model
|
||||
}
|
||||
|
||||
// When the model has been sorted, we need to adjust the focus (currentIndex)
|
||||
// to the previously focused conversation item.
|
||||
function onModelSorted(uri) {
|
||||
root.currentIndex = -1
|
||||
updateListView()
|
||||
for (var i = 0; i < count; i++) {
|
||||
if (root.model.data(
|
||||
root.model.index(i, 0), 261) === uri) {
|
||||
root.currentIndex = i
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function onUpdateListViewRequested() {
|
||||
updateListView()
|
||||
}
|
||||
|
||||
function onNavigateToWelcomePageRequested() {
|
||||
root.needToBackToWelcomePage()
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: CallAdapter
|
||||
|
||||
function onUpdateConversationSmartList() {
|
||||
updateConversationSmartListView()
|
||||
updateListView()
|
||||
}
|
||||
}
|
||||
|
||||
onCurrentIndexChanged: {
|
||||
conversationSmartListView.currentIndexIsChanged()
|
||||
root.currentIndexIsChanged()
|
||||
}
|
||||
|
||||
clip: true
|
||||
|
@ -101,7 +101,7 @@ ListView {
|
|||
Shortcut {
|
||||
sequence: "Ctrl+Shift+X"
|
||||
context: Qt.ApplicationShortcut
|
||||
enabled: conversationSmartListView.visible
|
||||
enabled: root.visible
|
||||
onActivated: {
|
||||
CallAdapter.placeCall()
|
||||
}
|
||||
|
@ -110,7 +110,7 @@ ListView {
|
|||
Shortcut {
|
||||
sequence: "Ctrl+Shift+C"
|
||||
context: Qt.ApplicationShortcut
|
||||
enabled: conversationSmartListView.visible
|
||||
enabled: root.visible
|
||||
onActivated: {
|
||||
CallAdapter.placeAudioOnlyCall()
|
||||
}
|
||||
|
@ -119,7 +119,7 @@ ListView {
|
|||
Shortcut {
|
||||
sequence: "Ctrl+Shift+L"
|
||||
context: Qt.ApplicationShortcut
|
||||
enabled: conversationSmartListView.visible
|
||||
enabled: root.visible
|
||||
onActivated: {
|
||||
ClientWrapper.utilsAdaptor.clearConversationHistory(ClientWrapper.utilsAdaptor.getCurrAccId(),
|
||||
ClientWrapper.utilsAdaptor.getCurrConvId())
|
||||
|
@ -129,18 +129,18 @@ ListView {
|
|||
Shortcut {
|
||||
sequence: "Ctrl+Shift+B"
|
||||
context: Qt.ApplicationShortcut
|
||||
enabled: conversationSmartListView.visible
|
||||
enabled: root.visible
|
||||
onActivated: {
|
||||
ClientWrapper.utilsAdaptor.removeConversation(ClientWrapper.utilsAdaptor.getCurrAccId(),
|
||||
ClientWrapper.utilsAdaptor.getCurrConvId(), true)
|
||||
conversationSmartListView.needToBackToWelcomePage()
|
||||
root.needToBackToWelcomePage()
|
||||
}
|
||||
}
|
||||
|
||||
Shortcut {
|
||||
sequence: "Ctrl+Shift+Delete"
|
||||
context: Qt.ApplicationShortcut
|
||||
enabled: conversationSmartListView.visible
|
||||
enabled: root.visible
|
||||
onActivated: {
|
||||
ClientWrapper.utilsAdaptor.removeConversation(ClientWrapper.utilsAdaptor.getCurrAccId(),
|
||||
ClientWrapper.utilsAdaptor.getCurrConvId(), false)
|
||||
|
@ -150,21 +150,22 @@ ListView {
|
|||
Shortcut {
|
||||
sequence: "Ctrl+Down"
|
||||
context: Qt.ApplicationShortcut
|
||||
enabled: conversationSmartListView.visible
|
||||
enabled: root.visible
|
||||
onActivated: {
|
||||
if (currentIndex + 1 >= count) return
|
||||
conversationSmartListView.currentIndex += 1
|
||||
if (currentIndex + 1 >= count)
|
||||
return
|
||||
root.currentIndex += 1
|
||||
}
|
||||
}
|
||||
|
||||
Shortcut {
|
||||
sequence: "Ctrl+Up"
|
||||
context: Qt.ApplicationShortcut
|
||||
enabled: conversationSmartListView.visible
|
||||
enabled: root.visible
|
||||
onActivated: {
|
||||
if (currentIndex <= 0) return
|
||||
conversationSmartListView.currentIndex -= 1
|
||||
if (currentIndex <= 0)
|
||||
return
|
||||
root.currentIndex -= 1
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -91,7 +91,7 @@ Rectangle {
|
|||
}
|
||||
|
||||
function forceUpdateConversationSmartListView() {
|
||||
conversationSmartListView.updateConversationSmartListView()
|
||||
conversationSmartListView.updateListView()
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -24,8 +24,6 @@ MediaHandlerAdapter::MediaHandlerAdapter(QObject* parent)
|
|||
: QmlAdapterBase(parent)
|
||||
{}
|
||||
|
||||
MediaHandlerAdapter::~MediaHandlerAdapter() {}
|
||||
|
||||
QVariant
|
||||
MediaHandlerAdapter::getMediaHandlerSelectableModel()
|
||||
{
|
||||
|
@ -61,7 +59,3 @@ MediaHandlerAdapter::getMediaHandlerPreferencesSelectableModel(QString pluginId)
|
|||
|
||||
return QVariant::fromValue(mediaHandlerListPreferenceModel_.get());
|
||||
}
|
||||
|
||||
void
|
||||
MediaHandlerAdapter::initQmlObject()
|
||||
{}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/**
|
||||
/*!
|
||||
* Copyright (C) 2020 by Savoir-faire Linux
|
||||
* Author: Aline Gondim Santos <aline.gondimsantos@savoirfairelinux.com>
|
||||
*
|
||||
|
@ -19,7 +19,6 @@
|
|||
#pragma once
|
||||
|
||||
#include "qmladapterbase.h"
|
||||
//#include "smartlistmodel.h"
|
||||
#include "mediahandleritemlistmodel.h"
|
||||
#include "mediahandlerlistpreferencemodel.h"
|
||||
#include "preferenceitemlistmodel.h"
|
||||
|
@ -28,22 +27,23 @@
|
|||
#include <QSortFilterProxyModel>
|
||||
#include <QString>
|
||||
|
||||
class MediaHandlerAdapter : public QmlAdapterBase
|
||||
class MediaHandlerAdapter final : public QmlAdapterBase
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit MediaHandlerAdapter(QObject* parent = nullptr);
|
||||
~MediaHandlerAdapter();
|
||||
~MediaHandlerAdapter() = default;
|
||||
|
||||
protected:
|
||||
void safeInit() override {};
|
||||
|
||||
Q_INVOKABLE QVariant getMediaHandlerSelectableModel();
|
||||
Q_INVOKABLE QVariant getMediaHandlerPreferencesModel(QString pluginId, QString mediaHandlerName);
|
||||
Q_INVOKABLE QVariant getMediaHandlerPreferencesSelectableModel(QString pluginId);
|
||||
|
||||
private:
|
||||
void initQmlObject();
|
||||
|
||||
std::unique_ptr<MediaHandlerItemListModel> mediaHandlerListModel_;
|
||||
std::unique_ptr<PreferenceItemListModel> mediaHandlerPreferenceItemListModel_;
|
||||
std::unique_ptr<MediaHandlerListPreferenceModel> mediaHandlerListPreferenceModel_;
|
||||
|
||||
};
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
/*!
|
||||
* Copyright (C) 2020 by Savoir-faire Linux
|
||||
* Author: Edric Ladent Milaret <edric.ladent-milaret@savoirfairelinux.com>
|
||||
* Author: Anthony L�onard <anthony.leonard@savoirfairelinux.com>
|
||||
* Author: Anthony Léonard <anthony.leonard@savoirfairelinux.com>
|
||||
* Author: Olivier Soldano <olivier.soldano@savoirfairelinux.com>
|
||||
* Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>
|
||||
* Author: Isa Nanic <isa.nanic@savoirfairelinux.com>
|
||||
|
@ -22,9 +22,9 @@
|
|||
*/
|
||||
|
||||
#include "messagesadapter.h"
|
||||
#include "webchathelpers.h"
|
||||
|
||||
#include "utils.h"
|
||||
#include "webchathelpers.h"
|
||||
|
||||
#include <QDesktopServices>
|
||||
#include <QFileInfo>
|
||||
|
@ -36,10 +36,8 @@ MessagesAdapter::MessagesAdapter(QObject *parent)
|
|||
: QmlAdapterBase(parent)
|
||||
{}
|
||||
|
||||
MessagesAdapter::~MessagesAdapter() {}
|
||||
|
||||
void
|
||||
MessagesAdapter::initQmlObject() {
|
||||
MessagesAdapter::safeInit() {
|
||||
connect(&LRCInstance::instance(),
|
||||
&LRCInstance::currentAccountChanged,
|
||||
[this](){
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/*!
|
||||
* Copyright (C) 2020 by Savoir-faire Linux
|
||||
* Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com>
|
||||
*
|
||||
|
@ -24,13 +24,15 @@
|
|||
#include <QObject>
|
||||
#include <QString>
|
||||
|
||||
class MessagesAdapter : public QmlAdapterBase
|
||||
class MessagesAdapter final : public QmlAdapterBase
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit MessagesAdapter(QObject *parent = 0);
|
||||
~MessagesAdapter();
|
||||
~MessagesAdapter() = default;
|
||||
|
||||
protected:
|
||||
void safeInit() override;
|
||||
|
||||
Q_INVOKABLE void setupChatView(const QString &uid);
|
||||
Q_INVOKABLE void connectConversationModel();
|
||||
|
@ -93,7 +95,6 @@ public slots:
|
|||
void slotMessagesLoaded();
|
||||
|
||||
private:
|
||||
void initQmlObject() override final;
|
||||
void setConversationProfileData(const lrc::api::conversation::Info &convInfo);
|
||||
void newInteraction(const QString &accountId,
|
||||
const QString &convUid,
|
||||
|
|
|
@ -1,35 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2020 by Savoir-faire Linux
|
||||
* Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "qmladapterbase.h"
|
||||
|
||||
QmlAdapterBase::QmlAdapterBase(QObject *parent)
|
||||
: QObject(parent)
|
||||
{
|
||||
qmlObj_ = nullptr;
|
||||
}
|
||||
|
||||
QmlAdapterBase::~QmlAdapterBase() {}
|
||||
|
||||
void
|
||||
QmlAdapterBase::setQmlObject(QObject *obj)
|
||||
{
|
||||
qmlObj_ = obj;
|
||||
|
||||
initQmlObject();
|
||||
}
|
|
@ -28,20 +28,27 @@ class QmlAdapterBase : public QObject
|
|||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit QmlAdapterBase(QObject *parent = nullptr);
|
||||
~QmlAdapterBase();
|
||||
explicit QmlAdapterBase(QObject *parent = nullptr)
|
||||
: QObject(parent)
|
||||
, qmlObj_(nullptr) {};
|
||||
|
||||
virtual ~QmlAdapterBase() = default;
|
||||
|
||||
/*
|
||||
* This function should be called in the Component.onCompleted slot
|
||||
* in the qml component that this adapter should attach to.
|
||||
*/
|
||||
Q_INVOKABLE void setQmlObject(QObject *obj);
|
||||
Q_INVOKABLE void setQmlObject(QObject *obj)
|
||||
{
|
||||
qmlObj_ = obj;
|
||||
safeInit();
|
||||
};
|
||||
|
||||
protected:
|
||||
/*
|
||||
*Once the qml object is set, custom actions can be done in this function.
|
||||
* Once the qml object is set, Qml method invokation can be done
|
||||
*/
|
||||
virtual void initQmlObject() = 0;
|
||||
virtual void safeInit() = 0;
|
||||
|
||||
/*
|
||||
* Object pointer.
|
||||
|
|
|
@ -135,6 +135,7 @@ void registerTypes()
|
|||
QML_REGISTERSINGLETONTYPE_URL(QStringLiteral("qrc:/src/constant/JamiQmlUtils.qml"),
|
||||
JamiQmlUtils, 1, 0);
|
||||
|
||||
QML_REGISTERSINGLETONTYPE("net.jami.Models", AccountAdapter, 1, 0);
|
||||
QML_REGISTERSINGLETONTYPE("net.jami.Models", CallAdapter, 1, 0);
|
||||
QML_REGISTERSINGLETONTYPE("net.jami.Models", MessagesAdapter, 1, 0);
|
||||
QML_REGISTERSINGLETONTYPE("net.jami.Models", ConversationsAdapter, 1, 0);
|
||||
|
@ -167,7 +168,6 @@ void registerTypes()
|
|||
* qmlRegisterUncreatableType & Q_DECLARE_METATYPE to expose models in qml.
|
||||
*/
|
||||
QML_REGISTERUNCREATABLE("net.jami.Models", RenderManager, 1, 0);
|
||||
QML_REGISTERUNCREATABLE("net.jami.Models", AccountAdapter, 1, 0);
|
||||
QML_REGISTERUNCREATABLE("net.jami.Models", UtilsAdapter, 1, 0);
|
||||
QML_REGISTERUNCREATABLE("net.jami.Models", NameDirectory, 1, 0);
|
||||
QML_REGISTERUNCREATABLE("net.jami.Models", LRCInstance, 1, 0);
|
||||
|
|
Loading…
Add table
Reference in a new issue