mirror of
https://gitlab.linphone.org/BC/public/linphone-desktop.git
synced 2026-01-18 11:58:11 +00:00
feat(ui/views/App/Calls/ConferenceManager): in progress
This commit is contained in:
parent
bace15a00d
commit
a00a2cbf4d
13 changed files with 245 additions and 99 deletions
|
|
@ -106,6 +106,7 @@ set(SOURCES
|
|||
src/components/codecs/AbstractCodecsModel.cpp
|
||||
src/components/codecs/AudioCodecsModel.cpp
|
||||
src/components/codecs/VideoCodecsModel.cpp
|
||||
src/components/conference/ConferenceAddModel.cpp
|
||||
src/components/conference/ConferenceHelperModel.cpp
|
||||
src/components/contact/ContactModel.cpp
|
||||
src/components/contact/VcardModel.cpp
|
||||
|
|
@ -148,6 +149,7 @@ set(HEADERS
|
|||
src/components/codecs/AudioCodecsModel.hpp
|
||||
src/components/codecs/VideoCodecsModel.hpp
|
||||
src/components/Components.hpp
|
||||
src/components/conference/ConferenceAddModel.hpp
|
||||
src/components/conference/ConferenceHelperModel.hpp
|
||||
src/components/contact/ContactModel.hpp
|
||||
src/components/contact/VcardModel.hpp
|
||||
|
|
|
|||
|
|
@ -342,7 +342,6 @@
|
|||
<file>ui/views/App/Calls/AbstractStartingCall.qml</file>
|
||||
<file>ui/views/App/Calls/CallsWindow.js</file>
|
||||
<file>ui/views/App/Calls/CallsWindow.qml</file>
|
||||
<file>ui/views/App/Calls/ConferenceManager.js</file>
|
||||
<file>ui/views/App/Calls/ConferenceManager.qml</file>
|
||||
<file>ui/views/App/Calls/EndedCall.qml</file>
|
||||
<file>ui/views/App/Calls/IncallFullscreenWindow.qml</file>
|
||||
|
|
|
|||
|
|
@ -359,6 +359,7 @@ void App::registerTypes () {
|
|||
registerMetaType<ChatModel::EntryType>("ChatModel::EntryType");
|
||||
|
||||
registerUncreatableType(CallModel, "CallModel");
|
||||
registerUncreatableType(ConferenceAddModel, "ConferenceAddModel");
|
||||
registerUncreatableType(ContactModel, "ContactModel");
|
||||
registerUncreatableType(SipAddressObserver, "SipAddressObserver");
|
||||
registerUncreatableType(VcardModel, "VcardModel");
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
#include "chat/ChatProxyModel.hpp"
|
||||
#include "codecs/AudioCodecsModel.hpp"
|
||||
#include "codecs/VideoCodecsModel.hpp"
|
||||
#include "conference/ConferenceAddModel.hpp"
|
||||
#include "conference/ConferenceHelperModel.hpp"
|
||||
#include "contacts/ContactsListProxyModel.hpp"
|
||||
#include "core/CoreManager.hpp"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,118 @@
|
|||
/*
|
||||
* ConferenceAddModel.cpp
|
||||
* Copyright (C) 2017 Belledonne Communications, Grenoble, France
|
||||
*
|
||||
* 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 2
|
||||
* 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, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Created on: May 18, 2017
|
||||
* Author: Ronan Abhamon
|
||||
*/
|
||||
|
||||
#include "../../Utils.hpp"
|
||||
#include "../core/CoreManager.hpp"
|
||||
#include "ConferenceHelperModel.hpp"
|
||||
|
||||
#include "ConferenceAddModel.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
// =============================================================================
|
||||
|
||||
ConferenceAddModel::ConferenceAddModel (QObject *parent) : QAbstractListModel(parent) {
|
||||
mConferenceHelperModel = qobject_cast<ConferenceHelperModel *>(parent);
|
||||
Q_ASSERT(mConferenceHelperModel != nullptr);
|
||||
|
||||
for (auto &participant : CoreManager::getInstance()->getCore()->getConference()->getParticipants())
|
||||
addToConference(participant);
|
||||
}
|
||||
|
||||
int ConferenceAddModel::rowCount (const QModelIndex &) const {
|
||||
return mRefs.count();
|
||||
}
|
||||
|
||||
QHash<int, QByteArray> ConferenceAddModel::roleNames () const {
|
||||
QHash<int, QByteArray> roles;
|
||||
roles[Qt::DisplayRole] = "$sipAddress";
|
||||
return roles;
|
||||
}
|
||||
|
||||
QVariant ConferenceAddModel::data (const QModelIndex &index, int role) const {
|
||||
int row = index.row();
|
||||
|
||||
if (!index.isValid() || row < 0 || row >= mRefs.count())
|
||||
return QVariant();
|
||||
|
||||
if (role == Qt::DisplayRole)
|
||||
return QVariant::fromValue(*mRefs[row]);
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
bool ConferenceAddModel::addToConference (const QString &sipAddress) {
|
||||
if (mSipAddresses.contains(sipAddress))
|
||||
return false;
|
||||
|
||||
int row = rowCount();
|
||||
|
||||
beginInsertRows(QModelIndex(), row, row);
|
||||
|
||||
qInfo() << QStringLiteral("Add sip address to conference: `%1`.").arg(sipAddress);
|
||||
shared_ptr<linphone::Address> linphoneAddress = CoreManager::getInstance()->getCore()->interpretUrl(
|
||||
::Utils::qStringToLinphoneString(sipAddress)
|
||||
);
|
||||
addToConference(linphoneAddress);
|
||||
|
||||
endInsertRows();
|
||||
|
||||
mConferenceHelperModel->invalidate();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ConferenceAddModel::removeFromConference (const QString &sipAddress) {
|
||||
auto it = mSipAddresses.find(sipAddress);
|
||||
if (it == mSipAddresses.end())
|
||||
return false;
|
||||
|
||||
int row = mRefs.indexOf(&(*it));
|
||||
|
||||
beginRemoveRows(QModelIndex(), row, row);
|
||||
|
||||
qInfo() << QStringLiteral("Remove sip address from conference: `%1`.").arg(sipAddress);
|
||||
|
||||
mRefs.removeAt(row);
|
||||
mSipAddresses.remove(sipAddress);
|
||||
|
||||
endRemoveRows();
|
||||
|
||||
mConferenceHelperModel->invalidate();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void ConferenceAddModel::addToConference (const std::shared_ptr<linphone::Address> &linphoneAddress) {
|
||||
QString sipAddress = ::Utils::linphoneStringToQString(linphoneAddress->asStringUriOnly());
|
||||
QVariantMap map;
|
||||
|
||||
map["sipAddress"] = sipAddress;
|
||||
map["__linphoneAddress"] = QVariant::fromValue(linphoneAddress);
|
||||
|
||||
mSipAddresses[sipAddress] = map;
|
||||
mRefs << &mSipAddresses[sipAddress];
|
||||
}
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* ConferenceAddModel.hpp
|
||||
* Copyright (C) 2017 Belledonne Communications, Grenoble, France
|
||||
*
|
||||
* 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 2
|
||||
* 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, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Created on: May 18, 2017
|
||||
* Author: Ronan Abhamon
|
||||
*/
|
||||
|
||||
#ifndef CONFERENCE_ADD_MODEL_H_
|
||||
#define CONFERENCE_ADD_MODEL_H_
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <QAbstractListModel>
|
||||
|
||||
// =============================================================================
|
||||
|
||||
class ConferenceHelperModel;
|
||||
|
||||
namespace linphone {
|
||||
class Address;
|
||||
}
|
||||
|
||||
class ConferenceAddModel : public QAbstractListModel {
|
||||
Q_OBJECT;
|
||||
|
||||
public:
|
||||
ConferenceAddModel (QObject *parent = Q_NULLPTR);
|
||||
~ConferenceAddModel () = default;
|
||||
|
||||
int rowCount (const QModelIndex &index = QModelIndex()) const override;
|
||||
|
||||
QHash<int, QByteArray> roleNames () const override;
|
||||
QVariant data (const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||
|
||||
Q_INVOKABLE bool addToConference (const QString &sipAddress);
|
||||
Q_INVOKABLE bool removeFromConference (const QString &sipAddress);
|
||||
|
||||
bool contains (const QString &sipAddress) const {
|
||||
return mSipAddresses.contains(sipAddress);
|
||||
}
|
||||
|
||||
private:
|
||||
void addToConference (const std::shared_ptr<linphone::Address> &linphoneAddress);
|
||||
|
||||
QHash<QString, QVariantMap> mSipAddresses;
|
||||
QList<const QVariantMap *> mRefs;
|
||||
|
||||
ConferenceHelperModel *mConferenceHelperModel;
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(std::shared_ptr<linphone::Address> );
|
||||
|
||||
#endif // CONFERENCE_ADD_MODEL_H_
|
||||
|
|
@ -20,24 +20,26 @@
|
|||
* Author: Ronan Abhamon
|
||||
*/
|
||||
|
||||
#include "../../Utils.hpp"
|
||||
#include "../../app/App.hpp"
|
||||
#include "../core/CoreManager.hpp"
|
||||
#include "../sip-addresses/SipAddressesProxyModel.hpp"
|
||||
#include "ConferenceAddModel.hpp"
|
||||
|
||||
#include "ConferenceHelperModel.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
// =============================================================================
|
||||
|
||||
ConferenceHelperModel::ConferenceHelperModel (QObject *parent) : QSortFilterProxyModel(parent) {
|
||||
CoreManager *coreManager = CoreManager::getInstance();
|
||||
shared_ptr<linphone::Core> core = CoreManager::getInstance()->getCore();
|
||||
|
||||
for (const auto &participant : coreManager->getCore()->getConference()->getParticipants())
|
||||
mInConference << ::Utils::linphoneStringToQString(participant->asStringUriOnly());
|
||||
mConference = core->getConference();
|
||||
if (!mConference)
|
||||
mConference = core->createConferenceWithParams(core->createConferenceParams());
|
||||
|
||||
CallsListModel *calls = coreManager->getCallsListModel();
|
||||
|
||||
QObject::connect(calls, &CallsListModel::rowsAboutToBeRemoved, this, &ConferenceHelperModel::handleCallsAboutToBeRemoved);
|
||||
QObject::connect(calls, &CallsListModel::callRunning, this, &ConferenceHelperModel::handleCallRunning);
|
||||
mConferenceAddModel = new ConferenceAddModel(this);
|
||||
App::getInstance()->getEngine()->setObjectOwnership(mConferenceAddModel, QQmlEngine::CppOwnership);
|
||||
|
||||
setSourceModel(new SipAddressesProxyModel(this));
|
||||
}
|
||||
|
|
@ -59,57 +61,6 @@ void ConferenceHelperModel::setFilter (const QString &pattern) {
|
|||
bool ConferenceHelperModel::filterAcceptsRow (int sourceRow, const QModelIndex &sourceParent) const {
|
||||
const QModelIndex &index = sourceModel()->index(sourceRow, 0, sourceParent);
|
||||
const QVariantMap &data = index.data().toMap();
|
||||
const QString &sipAddress = data["sipAddress"].toString();
|
||||
|
||||
return !mInConference.contains(sipAddress) && !mToAdd.contains(sipAddress);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void ConferenceHelperModel::handleCallsAboutToBeRemoved (const QModelIndex &, int first, int last) {
|
||||
CallsListModel *calls = CoreManager::getInstance()->getCallsListModel();
|
||||
bool soFarSoGood = false;
|
||||
|
||||
for (int i = first; i <= last; ++i) {
|
||||
const CallModel *callModel = calls->data(calls->index(first, 0)).value<CallModel *>();
|
||||
const QString &sipAddress = callModel->getSipAddress();
|
||||
|
||||
if (removeFromConference(sipAddress))
|
||||
soFarSoGood = true;
|
||||
}
|
||||
|
||||
if (soFarSoGood) {
|
||||
invalidateFilter();
|
||||
emit inConferenceChanged(mInConference);
|
||||
}
|
||||
}
|
||||
|
||||
void ConferenceHelperModel::handleCallRunning (int, CallModel *callModel) {
|
||||
const QString &sipAddress = callModel->getSipAddress();
|
||||
bool soFarSoGood = callModel->getCall()->getConference()
|
||||
? addToConference(sipAddress)
|
||||
: removeFromConference(sipAddress);
|
||||
|
||||
if (soFarSoGood) {
|
||||
invalidateFilter();
|
||||
emit inConferenceChanged(mInConference);
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
bool ConferenceHelperModel::addToConference (const QString &sipAddress) {
|
||||
bool ret = !mInConference.contains(sipAddress);
|
||||
if (ret) {
|
||||
qInfo() << QStringLiteral("Add sip address to conference: `%1`.").arg(sipAddress);
|
||||
mInConference << sipAddress;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool ConferenceHelperModel::removeFromConference (const QString &sipAddress) {
|
||||
bool ret = mInConference.removeOne(sipAddress);
|
||||
if (ret)
|
||||
qInfo() << QStringLiteral("Remove sip address from conference: `%1`.").arg(sipAddress);
|
||||
return ret;
|
||||
return !mConferenceAddModel->contains(data["sipAddress"].toString());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,16 +20,26 @@
|
|||
* Author: Ronan Abhamon
|
||||
*/
|
||||
|
||||
#ifndef CONFERENCE_HELPER_MODEL_H_
|
||||
#define CONFERENCE_HELPER_MODEL_H_
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <QSortFilterProxyModel>
|
||||
|
||||
// =============================================================================
|
||||
|
||||
class CallModel;
|
||||
class ConferenceAddModel;
|
||||
|
||||
namespace linphone {
|
||||
class Conference;
|
||||
}
|
||||
|
||||
class ConferenceHelperModel : public QSortFilterProxyModel {
|
||||
Q_OBJECT;
|
||||
|
||||
Q_PROPERTY(QStringList inConference READ getInConference NOTIFY inConferenceChanged);
|
||||
Q_PROPERTY(ConferenceAddModel * toAdd READ getConferenceAddModel CONSTANT);
|
||||
|
||||
public:
|
||||
ConferenceHelperModel (QObject *parent = Q_NULLPTR);
|
||||
|
|
@ -37,25 +47,21 @@ public:
|
|||
|
||||
QHash<int, QByteArray> roleNames () const override;
|
||||
|
||||
Q_INVOKABLE void setFilter (const QString &pattern);
|
||||
void update ();
|
||||
|
||||
signals:
|
||||
void inConferenceChanged (const QStringList &inConference);
|
||||
Q_INVOKABLE void setFilter (const QString &pattern);
|
||||
|
||||
protected:
|
||||
bool filterAcceptsRow (int sourceRow, const QModelIndex &sourceParent) const override;
|
||||
|
||||
private:
|
||||
void handleCallRunning (int index, CallModel *callModel);
|
||||
void handleCallsAboutToBeRemoved (const QModelIndex &parent, int first, int last);
|
||||
|
||||
bool addToConference (const QString &sipAddress);
|
||||
bool removeFromConference (const QString &sipAddress);
|
||||
|
||||
QStringList getInConference () {
|
||||
return mInConference;
|
||||
ConferenceAddModel *getConferenceAddModel () const {
|
||||
return mConferenceAddModel;
|
||||
}
|
||||
|
||||
QStringList mInConference;
|
||||
QStringList mToAdd;
|
||||
ConferenceAddModel *mConferenceAddModel;
|
||||
|
||||
std::shared_ptr<linphone::Conference> mConference;
|
||||
};
|
||||
|
||||
#endif // CONFERENCE_HELPER_MODEL_H_
|
||||
|
|
|
|||
|
|
@ -66,6 +66,8 @@ SearchBox {
|
|||
|
||||
genSipAddress: searchBar.filter
|
||||
|
||||
model: SipAddressesProxyModel {}
|
||||
|
||||
onEntryClicked: {
|
||||
searchBar.closeMenu()
|
||||
searchBar.entryClicked(entry)
|
||||
|
|
|
|||
|
|
@ -260,10 +260,4 @@ ScrollableListView {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Model.
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
model: SipAddressesProxyModel {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +0,0 @@
|
|||
// =============================================================================
|
||||
// `ConferenceManager.qml` Logic.
|
||||
// =============================================================================
|
||||
|
||||
function updateFilter (text) {
|
||||
console.log('TODO')
|
||||
}
|
||||
|
|
@ -6,8 +6,6 @@ import Linphone 1.0
|
|||
|
||||
import App.Styles 1.0
|
||||
|
||||
import 'ConferenceManager.js' as Logic
|
||||
|
||||
// =============================================================================
|
||||
|
||||
ConfirmDialog {
|
||||
|
|
@ -46,7 +44,7 @@ ConfirmDialog {
|
|||
|
||||
icon: 'search'
|
||||
|
||||
onTextChanged: Logic.updateFilter(text)
|
||||
onTextChanged: conferenceHelperModel.setFilter(text)
|
||||
}
|
||||
|
||||
ScrollableListViewField {
|
||||
|
|
@ -54,22 +52,22 @@ ConfirmDialog {
|
|||
Layout.fillWidth: true
|
||||
|
||||
SipAddressesView {
|
||||
id: view
|
||||
|
||||
anchors.fill: parent
|
||||
|
||||
actions: [{
|
||||
icon: 'video_call',
|
||||
icon: 'video_call', // TODO: replace me.
|
||||
handler: function (entry) {
|
||||
console.log('toto')
|
||||
conferenceHelperModel.toAdd.addToConference(entry.sipAddress)
|
||||
}
|
||||
}]
|
||||
|
||||
genSipAddress: filter.text
|
||||
|
||||
onEntryClicked: {
|
||||
console.log('todo2')
|
||||
model: ConferenceHelperModel {
|
||||
id: conferenceHelperModel
|
||||
}
|
||||
|
||||
onEntryClicked: actions[0].handler(entry)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -93,9 +91,22 @@ ConfirmDialog {
|
|||
// -------------------------------------------------------------------------
|
||||
|
||||
ScrollableListViewField {
|
||||
Layout.topMargin: filter.height + ConferenceManagerStyle.columns.selector.spacing
|
||||
Layout.fillHeight: true
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: filter.height + ConferenceManagerStyle.columns.selector.spacing
|
||||
|
||||
SipAddressesView {
|
||||
anchors.fill: parent
|
||||
|
||||
actions: [{
|
||||
icon: 'video_call', // TODO: replace me.
|
||||
handler: function (entry) {
|
||||
model.removeFromConference(entry.sipAddress)
|
||||
}
|
||||
}]
|
||||
|
||||
model: conferenceHelperModel.toAdd
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit 84441343adedad0007a05b438abe04a7c105c6ca
|
||||
Subproject commit 1e113618275ba4ab8bcadb8cbbd6c641045d8d41
|
||||
Loading…
Add table
Reference in a new issue