contacts list
This commit is contained in:
parent
97c01e66f8
commit
6849b8d378
29 changed files with 933 additions and 376 deletions
|
|
@ -42,6 +42,7 @@
|
||||||
#include "core/camera/CameraGui.hpp"
|
#include "core/camera/CameraGui.hpp"
|
||||||
#include "core/friend/FriendCore.hpp"
|
#include "core/friend/FriendCore.hpp"
|
||||||
#include "core/friend/FriendGui.hpp"
|
#include "core/friend/FriendGui.hpp"
|
||||||
|
#include "core/friend/FriendInitialProxy.hpp"
|
||||||
#include "core/logger/QtLogger.hpp"
|
#include "core/logger/QtLogger.hpp"
|
||||||
#include "core/login/LoginPage.hpp"
|
#include "core/login/LoginPage.hpp"
|
||||||
#include "core/notifier/Notifier.hpp"
|
#include "core/notifier/Notifier.hpp"
|
||||||
|
|
@ -163,6 +164,7 @@ void App::initCppInterfaces() {
|
||||||
qmlRegisterType<FriendGui>(Constants::MainQmlUri, 1, 0, "FriendGui");
|
qmlRegisterType<FriendGui>(Constants::MainQmlUri, 1, 0, "FriendGui");
|
||||||
qmlRegisterUncreatableType<FriendCore>(Constants::MainQmlUri, 1, 0, "FriendCore", QLatin1String("Uncreatable"));
|
qmlRegisterUncreatableType<FriendCore>(Constants::MainQmlUri, 1, 0, "FriendCore", QLatin1String("Uncreatable"));
|
||||||
qmlRegisterType<MagicSearchProxy>(Constants::MainQmlUri, 1, 0, "MagicSearchProxy");
|
qmlRegisterType<MagicSearchProxy>(Constants::MainQmlUri, 1, 0, "MagicSearchProxy");
|
||||||
|
qmlRegisterType<FriendInitialProxy>(Constants::MainQmlUri, 1, 0, "FriendInitialProxy");
|
||||||
qmlRegisterType<CameraGui>(Constants::MainQmlUri, 1, 0, "CameraGui");
|
qmlRegisterType<CameraGui>(Constants::MainQmlUri, 1, 0, "CameraGui");
|
||||||
LinphoneEnums::registerMetaTypes();
|
LinphoneEnums::registerMetaTypes();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ list(APPEND _LINPHONEAPP_SOURCES
|
||||||
core/camera/CameraDummy.cpp
|
core/camera/CameraDummy.cpp
|
||||||
core/friend/FriendCore.cpp
|
core/friend/FriendCore.cpp
|
||||||
core/friend/FriendGui.cpp
|
core/friend/FriendGui.cpp
|
||||||
|
core/friend/FriendInitialProxy.cpp
|
||||||
core/logger/QtLogger.cpp
|
core/logger/QtLogger.cpp
|
||||||
core/login/LoginPage.cpp
|
core/login/LoginPage.cpp
|
||||||
core/notifier/Notifier.cpp
|
core/notifier/Notifier.cpp
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@ CallHistoryCore::CallHistoryCore(const std::shared_ptr<linphone::CallLog> &callL
|
||||||
}
|
}
|
||||||
|
|
||||||
CallHistoryCore::~CallHistoryCore() {
|
CallHistoryCore::~CallHistoryCore() {
|
||||||
qDebug() << "[CallHistoryCore] delete" << this;
|
// qDebug() << "[CallHistoryCore] delete" << this;
|
||||||
mustBeInMainThread("~" + getClassName());
|
mustBeInMainThread("~" + getClassName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,8 @@
|
||||||
|
|
||||||
#include "FriendCore.hpp"
|
#include "FriendCore.hpp"
|
||||||
#include "core/App.hpp"
|
#include "core/App.hpp"
|
||||||
|
#include "model/object/VariantObject.hpp"
|
||||||
|
#include "model/tool/ToolModel.hpp"
|
||||||
#include "tool/Utils.hpp"
|
#include "tool/Utils.hpp"
|
||||||
#include "tool/thread/SafeConnection.hpp"
|
#include "tool/thread/SafeConnection.hpp"
|
||||||
|
|
||||||
|
|
@ -42,7 +44,11 @@ FriendCore::FriendCore(const std::shared_ptr<linphone::Friend> &contact) : QObje
|
||||||
mPresenceTimestamp = mFriendModel->getPresenceTimestamp();
|
mPresenceTimestamp = mFriendModel->getPresenceTimestamp();
|
||||||
mPictureUri = Utils::coreStringToAppString(contact->getPhoto());
|
mPictureUri = Utils::coreStringToAppString(contact->getPhoto());
|
||||||
auto address = contact->getAddress();
|
auto address = contact->getAddress();
|
||||||
mAddress = address ? Utils::coreStringToAppString(contact->getAddress()->asString()) : "NoAddress";
|
mAddress = address ? Utils::coreStringToAppString(contact->getAddress()->asStringUriOnly()) : "NoAddress";
|
||||||
|
auto name = contact->getName();
|
||||||
|
mName =
|
||||||
|
name.empty() ? Utils::getDisplayName(mAddress)->getValue().toString() : Utils::coreStringToAppString(name);
|
||||||
|
mStarred = contact->getStarred();
|
||||||
mIsSaved = true;
|
mIsSaved = true;
|
||||||
} else mIsSaved = false;
|
} else mIsSaved = false;
|
||||||
}
|
}
|
||||||
|
|
@ -76,11 +82,20 @@ void FriendCore::setSelf(QSharedPointer<FriendCore> me) {
|
||||||
mFriendModelConnection->makeConnectToModel(&FriendModel::pictureUriChanged, [this](QString uri) {
|
mFriendModelConnection->makeConnectToModel(&FriendModel::pictureUriChanged, [this](QString uri) {
|
||||||
mFriendModelConnection->invokeToCore([this, uri]() { this->onPictureUriChanged(uri); });
|
mFriendModelConnection->invokeToCore([this, uri]() { this->onPictureUriChanged(uri); });
|
||||||
});
|
});
|
||||||
|
mFriendModelConnection->makeConnectToModel(&FriendModel::starredChanged, [this](bool starred) {
|
||||||
|
mFriendModelConnection->invokeToCore([this, starred]() { this->onStarredChanged(starred); });
|
||||||
|
});
|
||||||
|
mFriendModelConnection->makeConnectToModel(
|
||||||
|
&FriendModel::objectNameChanged,
|
||||||
|
[this](const QString &objectName) { qDebug() << "object name changed" << objectName; });
|
||||||
|
|
||||||
// From GUI
|
// From GUI
|
||||||
mFriendModelConnection->makeConnectToCore(&FriendCore::lSetPictureUri, [this](QString uri) {
|
mFriendModelConnection->makeConnectToCore(&FriendCore::lSetPictureUri, [this](QString uri) {
|
||||||
mFriendModelConnection->invokeToModel([this, uri]() { mFriendModel->setPictureUri(uri); });
|
mFriendModelConnection->invokeToModel([this, uri]() { mFriendModel->setPictureUri(uri); });
|
||||||
});
|
});
|
||||||
|
mFriendModelConnection->makeConnectToCore(&FriendCore::lSetStarred, [this](bool starred) {
|
||||||
|
mFriendModelConnection->invokeToModel([this, starred]() { mFriendModel->setStarred(starred); });
|
||||||
|
});
|
||||||
|
|
||||||
} else { // Create
|
} else { // Create
|
||||||
mCoreModelConnection = QSharedPointer<SafeConnection<FriendCore, CoreModel>>(
|
mCoreModelConnection = QSharedPointer<SafeConnection<FriendCore, CoreModel>>(
|
||||||
|
|
@ -107,6 +122,16 @@ void FriendCore::setName(QString data) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool FriendCore::getStarred() const {
|
||||||
|
return mStarred;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FriendCore::onStarredChanged(bool starred) {
|
||||||
|
mStarred = starred;
|
||||||
|
save();
|
||||||
|
emit starredChanged();
|
||||||
|
}
|
||||||
|
|
||||||
QString FriendCore::getAddress() const {
|
QString FriendCore::getAddress() const {
|
||||||
return mAddress;
|
return mAddress;
|
||||||
}
|
}
|
||||||
|
|
@ -190,35 +215,66 @@ void FriendCore::remove() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FriendCore::save() { // Save Values to model
|
void FriendCore::save() { // Save Values to model
|
||||||
FriendCore *thisCopy = new FriendCore(*this); // Pointer to avoid multiple copies in lambdas
|
FriendCore *thisCopy = new FriendCore(*this); // Pointer to avoid multiple copies in lambdas
|
||||||
if (mFriendModel) { // Update
|
auto linphoneAddr = ToolModel::interpretUrl(mAddress);
|
||||||
|
|
||||||
|
if (mFriendModel) {
|
||||||
mFriendModelConnection->invokeToModel([this, thisCopy]() { // Copy values to avoid concurrency
|
mFriendModelConnection->invokeToModel([this, thisCopy]() { // Copy values to avoid concurrency
|
||||||
auto core = CoreModel::getInstance()->getCore();
|
|
||||||
auto contact = mFriendModel->getFriend();
|
auto contact = mFriendModel->getFriend();
|
||||||
thisCopy->writeInto(contact);
|
thisCopy->writeInto(contact);
|
||||||
thisCopy->deleteLater();
|
thisCopy->deleteLater();
|
||||||
mFriendModelConnection->invokeToCore([this]() { saved(); });
|
mFriendModelConnection->invokeToCore([this]() { saved(); });
|
||||||
});
|
});
|
||||||
} else { // Creation
|
} else {
|
||||||
mCoreModelConnection->invokeToModel([this, thisCopy]() {
|
mCoreModelConnection->invokeToModel([this, thisCopy, linphoneAddr]() {
|
||||||
auto core = CoreModel::getInstance()->getCore();
|
auto core = CoreModel::getInstance()->getCore();
|
||||||
auto contact = core->createFriend();
|
auto contact = core->findFriend(linphoneAddr);
|
||||||
thisCopy->writeInto(contact);
|
auto friendExists = contact != nullptr;
|
||||||
thisCopy->deleteLater();
|
if (contact != nullptr) {
|
||||||
bool created = (core->getDefaultFriendList()->addFriend(contact) == linphone::FriendList::Status::OK);
|
thisCopy->writeInto(contact);
|
||||||
if (created) {
|
thisCopy->deleteLater();
|
||||||
mFriendModel = Utils::makeQObject_ptr<FriendModel>(contact);
|
if (mFriendModelConnection) mFriendModelConnection->invokeToCore([this] { saved(); });
|
||||||
mFriendModel->setSelf(mFriendModel);
|
else mCoreModelConnection->invokeToCore([this] { saved(); });
|
||||||
core->getDefaultFriendList()->updateSubscriptions();
|
} else {
|
||||||
|
auto contact = core->createFriend();
|
||||||
|
thisCopy->writeInto(contact);
|
||||||
|
thisCopy->deleteLater();
|
||||||
|
bool created = (core->getDefaultFriendList()->addFriend(contact) == linphone::FriendList::Status::OK);
|
||||||
|
if (created) {
|
||||||
|
mFriendModel = Utils::makeQObject_ptr<FriendModel>(contact);
|
||||||
|
mFriendModel->setSelf(mFriendModel);
|
||||||
|
core->getDefaultFriendList()->updateSubscriptions();
|
||||||
|
}
|
||||||
|
emit CoreModel::getInstance()->friendAdded();
|
||||||
|
mCoreModelConnection->invokeToCore([this, created]() {
|
||||||
|
if (created) setSelf(mCoreModelConnection->mCore);
|
||||||
|
setIsSaved(created);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
emit CoreModel::getInstance()->friendAdded();
|
|
||||||
mCoreModelConnection->invokeToCore([this, created]() {
|
|
||||||
if (created) setSelf(mCoreModelConnection->mCore);
|
|
||||||
setIsSaved(created);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if (mFriendModel) { // Update
|
||||||
|
// } else { // Creation
|
||||||
|
// mCoreModelConnection->invokeToModel([this, thisCopy]() {
|
||||||
|
// auto core = CoreModel::getInstance()->getCore();
|
||||||
|
// auto contact = core->createFriend();
|
||||||
|
// thisCopy->writeInto(contact);
|
||||||
|
// thisCopy->deleteLater();
|
||||||
|
// bool created = (core->getDefaultFriendList()->addFriend(contact) == linphone::FriendList::Status::OK);
|
||||||
|
// if (created) {
|
||||||
|
// mFriendModel = Utils::makeQObject_ptr<FriendModel>(contact);
|
||||||
|
// mFriendModel->setSelf(mFriendModel);
|
||||||
|
// core->getDefaultFriendList()->updateSubscriptions();
|
||||||
|
// }
|
||||||
|
// emit CoreModel::getInstance()->friendAdded();
|
||||||
|
// mCoreModelConnection->invokeToCore([this, created]() {
|
||||||
|
// if (created) setSelf(mCoreModelConnection->mCore);
|
||||||
|
// setIsSaved(created);
|
||||||
|
// });
|
||||||
|
// });
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
void FriendCore::undo() { // Retrieve values from model
|
void FriendCore::undo() { // Retrieve values from model
|
||||||
|
|
|
||||||
|
|
@ -46,6 +46,7 @@ class FriendCore : public QObject, public AbstractObject {
|
||||||
consolidatedPresenceChanged)
|
consolidatedPresenceChanged)
|
||||||
Q_PROPERTY(bool isSaved READ getIsSaved NOTIFY isSavedChanged)
|
Q_PROPERTY(bool isSaved READ getIsSaved NOTIFY isSavedChanged)
|
||||||
Q_PROPERTY(QString pictureUri READ getPictureUri WRITE lSetPictureUri NOTIFY pictureUriChanged)
|
Q_PROPERTY(QString pictureUri READ getPictureUri WRITE lSetPictureUri NOTIFY pictureUriChanged)
|
||||||
|
Q_PROPERTY(bool starred READ getStarred WRITE lSetStarred NOTIFY starredChanged)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Should be call from model Thread. Will be automatically in App thread after initialization
|
// Should be call from model Thread. Will be automatically in App thread after initialization
|
||||||
|
|
@ -60,6 +61,9 @@ public:
|
||||||
QString getName() const;
|
QString getName() const;
|
||||||
void setName(QString data);
|
void setName(QString data);
|
||||||
|
|
||||||
|
bool getStarred() const;
|
||||||
|
void onStarredChanged(bool starred);
|
||||||
|
|
||||||
QString getAddress() const;
|
QString getAddress() const;
|
||||||
void setAddress(QString address);
|
void setAddress(QString address);
|
||||||
|
|
||||||
|
|
@ -84,6 +88,7 @@ public:
|
||||||
signals:
|
signals:
|
||||||
void contactUpdated();
|
void contactUpdated();
|
||||||
void nameChanged(QString name);
|
void nameChanged(QString name);
|
||||||
|
void starredChanged();
|
||||||
void addressChanged(QString address);
|
void addressChanged(QString address);
|
||||||
void consolidatedPresenceChanged(LinphoneEnums::ConsolidatedPresence level);
|
void consolidatedPresenceChanged(LinphoneEnums::ConsolidatedPresence level);
|
||||||
void presenceTimestampChanged(QDateTime presenceTimestamp);
|
void presenceTimestampChanged(QDateTime presenceTimestamp);
|
||||||
|
|
@ -95,6 +100,7 @@ signals:
|
||||||
void removed(FriendCore *contact);
|
void removed(FriendCore *contact);
|
||||||
|
|
||||||
void lSetPictureUri(QString pictureUri);
|
void lSetPictureUri(QString pictureUri);
|
||||||
|
void lSetStarred(bool starred);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void writeInto(std::shared_ptr<linphone::Friend> contact) const;
|
void writeInto(std::shared_ptr<linphone::Friend> contact) const;
|
||||||
|
|
@ -103,6 +109,7 @@ protected:
|
||||||
LinphoneEnums::ConsolidatedPresence mConsolidatedPresence = LinphoneEnums::ConsolidatedPresence::Offline;
|
LinphoneEnums::ConsolidatedPresence mConsolidatedPresence = LinphoneEnums::ConsolidatedPresence::Offline;
|
||||||
QDateTime mPresenceTimestamp;
|
QDateTime mPresenceTimestamp;
|
||||||
QString mName;
|
QString mName;
|
||||||
|
bool mStarred;
|
||||||
QString mAddress;
|
QString mAddress;
|
||||||
QString mPictureUri;
|
QString mPictureUri;
|
||||||
bool mIsSaved;
|
bool mIsSaved;
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,9 @@ FriendGui::~FriendGui() {
|
||||||
mustBeInMainThread("~" + getClassName());
|
mustBeInMainThread("~" + getClassName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FriendGui::createContact(const QString &address) {
|
||||||
|
}
|
||||||
|
|
||||||
FriendCore *FriendGui::getCore() const {
|
FriendCore *FriendGui::getCore() const {
|
||||||
return mCore.get();
|
return mCore.get();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@ public:
|
||||||
FriendGui(QSharedPointer<FriendCore> core);
|
FriendGui(QSharedPointer<FriendCore> core);
|
||||||
~FriendGui();
|
~FriendGui();
|
||||||
FriendCore *getCore() const;
|
FriendCore *getCore() const;
|
||||||
|
Q_INVOKABLE void createContact(const QString &address);
|
||||||
QSharedPointer<FriendCore> mCore;
|
QSharedPointer<FriendCore> mCore;
|
||||||
DECLARE_ABSTRACT_OBJECT
|
DECLARE_ABSTRACT_OBJECT
|
||||||
};
|
};
|
||||||
|
|
|
||||||
76
Linphone/core/friend/FriendInitialProxy.cpp
Normal file
76
Linphone/core/friend/FriendInitialProxy.cpp
Normal file
|
|
@ -0,0 +1,76 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2010-2024 Belledonne Communications SARL.
|
||||||
|
*
|
||||||
|
* This file is part of linphone-desktop
|
||||||
|
* (see https://www.linphone.org).
|
||||||
|
*
|
||||||
|
* 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 "FriendInitialProxy.hpp"
|
||||||
|
#include "FriendCore.hpp"
|
||||||
|
#include "FriendGui.hpp"
|
||||||
|
#include "tool/Utils.hpp"
|
||||||
|
|
||||||
|
DEFINE_ABSTRACT_OBJECT(FriendInitialProxy)
|
||||||
|
|
||||||
|
FriendInitialProxy::FriendInitialProxy(QObject *parent) : SortFilterProxy(parent) {
|
||||||
|
}
|
||||||
|
|
||||||
|
FriendInitialProxy::~FriendInitialProxy() {
|
||||||
|
setSourceModel(nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString FriendInitialProxy::getFilterText() const {
|
||||||
|
return mFilterText;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FriendInitialProxy::setFilterText(const QString &filter) {
|
||||||
|
if (mFilterText != filter) {
|
||||||
|
mFilterText = filter;
|
||||||
|
invalidate();
|
||||||
|
emit filterTextChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// void FriendInitialProxy::setSourceModel(QAbstractItemModel *sourceModel) {
|
||||||
|
// mSource = qSharedPointerCast<MagicSearchProxy>(QSharedPointer<QAbstractItemModel>(sourceModel));
|
||||||
|
// }
|
||||||
|
|
||||||
|
// QAbstractItemModel *FriendInitialProxy::sourceModel() const {
|
||||||
|
// return mSource.get();
|
||||||
|
// }
|
||||||
|
|
||||||
|
bool FriendInitialProxy::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const {
|
||||||
|
bool show = (mFilterText.isEmpty() || mFilterText == "*");
|
||||||
|
if (!show) {
|
||||||
|
QRegularExpression search(mFilterText, QRegularExpression::CaseInsensitiveOption |
|
||||||
|
QRegularExpression::UseUnicodePropertiesOption);
|
||||||
|
auto friendData = sourceModel()->data(sourceModel()->index(sourceRow, 0, sourceParent)).value<FriendGui *>();
|
||||||
|
auto name = friendData->getCore()->getName();
|
||||||
|
show = friendData->getCore()->getName().indexOf(search) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return show;
|
||||||
|
}
|
||||||
|
|
||||||
|
// bool FriendInitialProxy::lessThan(const QModelIndex &left, const QModelIndex &right) const {
|
||||||
|
// // auto l = getItemAt<MagicSearchProxy, FriendCore>(left.row());
|
||||||
|
// // auto r = getItemAt<MagicSearchProxy, FriendCore>(right.row());
|
||||||
|
// // return l->getName() < r->getName();
|
||||||
|
// }
|
||||||
|
|
||||||
|
QVariant FriendInitialProxy::data(const QModelIndex &index, int role) const {
|
||||||
|
return sourceModel()->data(mapToSource(index));
|
||||||
|
}
|
||||||
63
Linphone/core/friend/FriendInitialProxy.hpp
Normal file
63
Linphone/core/friend/FriendInitialProxy.hpp
Normal file
|
|
@ -0,0 +1,63 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2010-2024 Belledonne Communications SARL.
|
||||||
|
*
|
||||||
|
* This file is part of linphone-desktop
|
||||||
|
* (see https://www.linphone.org).
|
||||||
|
*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef FRIEND_INITIAL_PROXY_H_
|
||||||
|
#define FRIEND_INITIAL_PROXY_H_
|
||||||
|
|
||||||
|
#include "../proxy/SortFilterProxy.hpp"
|
||||||
|
#include "core/search/MagicSearchList.hpp"
|
||||||
|
#include "core/search/MagicSearchProxy.hpp"
|
||||||
|
#include "tool/AbstractObject.hpp"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A proxy to filter the friends list with the first letter of the names
|
||||||
|
**/
|
||||||
|
// =============================================================================
|
||||||
|
|
||||||
|
class FriendInitialProxy : public SortFilterProxy, public AbstractObject {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
Q_PROPERTY(QString filterText READ getFilterText WRITE setFilterText NOTIFY filterTextChanged)
|
||||||
|
// Q_PROPERTY(QAbstractItemModel *sourceModel READ sourceModel WRITE setSourceModel NOTIFY sourceModelChanged)
|
||||||
|
|
||||||
|
public:
|
||||||
|
FriendInitialProxy(QObject *parent = Q_NULLPTR);
|
||||||
|
~FriendInitialProxy();
|
||||||
|
|
||||||
|
QString getFilterText() const;
|
||||||
|
void setFilterText(const QString &filter);
|
||||||
|
|
||||||
|
virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void filterTextChanged();
|
||||||
|
void sourceModelChanged();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override;
|
||||||
|
// virtual bool lessThan(const QModelIndex &left, const QModelIndex &right) const override;
|
||||||
|
|
||||||
|
QString mFilterText;
|
||||||
|
QSharedPointer<MagicSearchProxy> mSource;
|
||||||
|
|
||||||
|
DECLARE_ABSTRACT_OBJECT
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -133,6 +133,8 @@ void MagicSearchList::setAggregationFlag(LinphoneEnums::MagicSearchAggregation f
|
||||||
QVariant MagicSearchList::data(const QModelIndex &index, int role) const {
|
QVariant MagicSearchList::data(const QModelIndex &index, int role) const {
|
||||||
int row = index.row();
|
int row = index.row();
|
||||||
if (!index.isValid() || row < 0 || row >= mList.count()) return QVariant();
|
if (!index.isValid() || row < 0 || row >= mList.count()) return QVariant();
|
||||||
if (role == Qt::DisplayRole) return QVariant::fromValue(new FriendGui(mList[row].objectCast<FriendCore>()));
|
if (role == Qt::DisplayRole) {
|
||||||
|
return QVariant::fromValue(new FriendGui(mList[row].objectCast<FriendCore>()));
|
||||||
|
}
|
||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ list(APPEND _LINPHONEAPP_RC_FILES data/assistant/use-app-sip-account.rc
|
||||||
"data/image/caret-down.svg"
|
"data/image/caret-down.svg"
|
||||||
"data/image/caret-left.svg"
|
"data/image/caret-left.svg"
|
||||||
"data/image/caret-right.svg"
|
"data/image/caret-right.svg"
|
||||||
|
"data/image/caret-up.svg"
|
||||||
"data/image/verif_page_image.svg"
|
"data/image/verif_page_image.svg"
|
||||||
"data/image/check.svg"
|
"data/image/check.svg"
|
||||||
"data/image/dialer.svg"
|
"data/image/dialer.svg"
|
||||||
|
|
@ -61,6 +62,8 @@ list(APPEND _LINPHONEAPP_RC_FILES data/assistant/use-app-sip-account.rc
|
||||||
"data/image/trash-simple.svg"
|
"data/image/trash-simple.svg"
|
||||||
"data/image/copy.svg"
|
"data/image/copy.svg"
|
||||||
"data/image/empty.svg"
|
"data/image/empty.svg"
|
||||||
|
"data/image/heart.svg"
|
||||||
|
"data/image/heart-fill.svg"
|
||||||
|
|
||||||
data/shaders/roundEffect.vert.qsb
|
data/shaders/roundEffect.vert.qsb
|
||||||
data/shaders/roundEffect.frag.qsb
|
data/shaders/roundEffect.frag.qsb
|
||||||
|
|
|
||||||
|
|
@ -33,8 +33,8 @@ CallHistoryModel::CallHistoryModel(const std::shared_ptr<linphone::CallLog> &cal
|
||||||
}
|
}
|
||||||
|
|
||||||
CallHistoryModel::~CallHistoryModel() {
|
CallHistoryModel::~CallHistoryModel() {
|
||||||
qDebug() << "[CallHistoryModel] delete" << this;
|
// qDebug() << "[CallHistoryModel] delete" << this;
|
||||||
mustBeInLinphoneThread("~" + getClassName());
|
// mustBeInLinphoneThread("~" + getClassName());
|
||||||
}
|
}
|
||||||
|
|
||||||
void CallHistoryModel::removeCallHistory() {
|
void CallHistoryModel::removeCallHistory() {
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,23 @@ QDateTime FriendModel::getPresenceTimestamp() const {
|
||||||
} else return QDateTime();
|
} else return QDateTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString FriendModel::getAddress() const {
|
||||||
|
return Utils::coreStringToAppString(mMonitor->getAddress()->asStringUriOnly());
|
||||||
|
}
|
||||||
|
|
||||||
|
QString FriendModel::getName() const {
|
||||||
|
return Utils::coreStringToAppString(mMonitor->getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FriendModel::getStarred() const {
|
||||||
|
return mMonitor->getStarred();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FriendModel::setStarred(bool starred) {
|
||||||
|
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||||
|
mMonitor->setStarred(starred);
|
||||||
|
emit starredChanged(starred);
|
||||||
|
}
|
||||||
void FriendModel::onPresenceReceived(const std::shared_ptr<linphone::Friend> &contact) {
|
void FriendModel::onPresenceReceived(const std::shared_ptr<linphone::Friend> &contact) {
|
||||||
emit presenceReceived(LinphoneEnums::fromLinphone(contact->getConsolidatedPresence()), getPresenceTimestamp());
|
emit presenceReceived(LinphoneEnums::fromLinphone(contact->getConsolidatedPresence()), getPresenceTimestamp());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -39,12 +39,17 @@ public:
|
||||||
~FriendModel();
|
~FriendModel();
|
||||||
|
|
||||||
QDateTime getPresenceTimestamp() const;
|
QDateTime getPresenceTimestamp() const;
|
||||||
|
QString getAddress() const;
|
||||||
|
QString getName() const;
|
||||||
|
bool getStarred() const;
|
||||||
std::shared_ptr<linphone::Friend> getFriend() const;
|
std::shared_ptr<linphone::Friend> getFriend() const;
|
||||||
|
|
||||||
void setPictureUri(QString uri);
|
void setPictureUri(QString uri);
|
||||||
|
void setStarred(bool starred);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void pictureUriChanged(QString uri);
|
void pictureUriChanged(QString uri);
|
||||||
|
void starredChanged(bool starred);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DECLARE_ABSTRACT_OBJECT
|
DECLARE_ABSTRACT_OBJECT
|
||||||
|
|
|
||||||
|
|
@ -59,6 +59,7 @@ QString ToolModel::getDisplayName(const std::shared_ptr<const linphone::Address>
|
||||||
// auto sipAddressEntry = getSipAddressEntry(qtAddress, cleanAddress);
|
// auto sipAddressEntry = getSipAddressEntry(qtAddress, cleanAddress);
|
||||||
// displayName = sipAddressEntry->displayNames.get();
|
// displayName = sipAddressEntry->displayNames.get();
|
||||||
}
|
}
|
||||||
|
displayName.replace('.', ' ');
|
||||||
return displayName;
|
return displayName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -170,6 +170,13 @@ LinphoneEnums::MagicSearchAggregation LinphoneEnums::fromLinphone(const linphone
|
||||||
return static_cast<LinphoneEnums::MagicSearchAggregation>(data);
|
return static_cast<LinphoneEnums::MagicSearchAggregation>(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
linphone::MagicSearch::Source LinphoneEnums::toLinphone(const LinphoneEnums::MagicSearchSource &data) {
|
||||||
|
return static_cast<linphone::MagicSearch::Source>(data);
|
||||||
|
}
|
||||||
|
LinphoneEnums::MagicSearchSource LinphoneEnums::fromLinphone(const linphone::MagicSearch::Source &data) {
|
||||||
|
return static_cast<LinphoneEnums::MagicSearchSource>(data);
|
||||||
|
}
|
||||||
|
|
||||||
linphone::LogLevel LinphoneEnums::toLinphone(const QtMsgType &data) {
|
linphone::LogLevel LinphoneEnums::toLinphone(const QtMsgType &data) {
|
||||||
switch (data) {
|
switch (data) {
|
||||||
case QtDebugMsg:
|
case QtDebugMsg:
|
||||||
|
|
|
||||||
|
|
@ -218,6 +218,24 @@ Q_ENUM_NS(MagicSearchAggregation);
|
||||||
linphone::MagicSearch::Aggregation toLinphone(const LinphoneEnums::MagicSearchAggregation &data);
|
linphone::MagicSearch::Aggregation toLinphone(const LinphoneEnums::MagicSearchAggregation &data);
|
||||||
LinphoneEnums::MagicSearchAggregation fromLinphone(const linphone::MagicSearch::Aggregation &data);
|
LinphoneEnums::MagicSearchAggregation fromLinphone(const linphone::MagicSearch::Aggregation &data);
|
||||||
|
|
||||||
|
enum class MagicSearchSource {
|
||||||
|
None = int(linphone::MagicSearch::Source::None),
|
||||||
|
Friends = int(linphone::MagicSearch::Source::Friends),
|
||||||
|
CallLogs = int(linphone::MagicSearch::Source::CallLogs),
|
||||||
|
LdapServers = int(linphone::MagicSearch::Source::LdapServers),
|
||||||
|
ChatRooms = int(linphone::MagicSearch::Source::ChatRooms),
|
||||||
|
Request = int(linphone::MagicSearch::Source::Request),
|
||||||
|
FavoriteFriends = int(linphone::MagicSearch::Source::FavoriteFriends),
|
||||||
|
ConferencesInfo = int(linphone::MagicSearch::Source::ConferencesInfo),
|
||||||
|
All = int(linphone::MagicSearch::Source::All)
|
||||||
|
};
|
||||||
|
Q_ENUM_NS(MagicSearchSource);
|
||||||
|
// Q_DECLARE_FLAGS(MagicSearchSources, MagicSearchSource)
|
||||||
|
// Q_DECLARE_OPERATORS_FOR_FLAGS(MagicSearchSources)
|
||||||
|
|
||||||
|
linphone::MagicSearch::Source toLinphone(const LinphoneEnums::MagicSearchSource &data);
|
||||||
|
LinphoneEnums::MagicSearchSource fromLinphone(const linphone::MagicSearch::Source &data);
|
||||||
|
|
||||||
linphone::LogLevel toLinphone(const QtMsgType &data);
|
linphone::LogLevel toLinphone(const QtMsgType &data);
|
||||||
QtMsgType fromLinphone(const linphone::LogLevel &data);
|
QtMsgType fromLinphone(const linphone::LogLevel &data);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -454,7 +454,7 @@ Window {
|
||||||
}
|
}
|
||||||
Component {
|
Component {
|
||||||
id: contactsListPanel
|
id: contactsListPanel
|
||||||
ContactsList {
|
CallContactsLists {
|
||||||
sideMargin: 10 * DefaultStyle.dp
|
sideMargin: 10 * DefaultStyle.dp
|
||||||
topMargin: 15 * DefaultStyle.dp
|
topMargin: 15 * DefaultStyle.dp
|
||||||
groupCallVisible: false
|
groupCallVisible: false
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ list(APPEND _LINPHONEAPP_QML_FILES
|
||||||
|
|
||||||
view/Item/Account/Accounts.qml
|
view/Item/Account/Accounts.qml
|
||||||
|
|
||||||
view/Item/Call/ContactsList.qml
|
view/Item/Call/CallContactsLists.qml
|
||||||
view/Item/Call/OngoingCallRightPanel.qml
|
view/Item/Call/OngoingCallRightPanel.qml
|
||||||
|
|
||||||
view/Item/Notification/Notification.qml
|
view/Item/Notification/Notification.qml
|
||||||
|
|
@ -25,6 +25,7 @@ list(APPEND _LINPHONEAPP_QML_FILES
|
||||||
view/Item/Carousel.qml
|
view/Item/Carousel.qml
|
||||||
view/Item/CheckBox.qml
|
view/Item/CheckBox.qml
|
||||||
view/Item/ComboBox.qml
|
view/Item/ComboBox.qml
|
||||||
|
view/Item/ContactsList.qml
|
||||||
view/Item/DesktopPopup.qml
|
view/Item/DesktopPopup.qml
|
||||||
view/Item/DigitInput.qml
|
view/Item/DigitInput.qml
|
||||||
view/Item/EffectImage.qml
|
view/Item/EffectImage.qml
|
||||||
|
|
|
||||||
307
Linphone/view/Item/Call/CallContactsLists.qml
Normal file
307
Linphone/view/Item/Call/CallContactsLists.qml
Normal file
|
|
@ -0,0 +1,307 @@
|
||||||
|
import QtQuick 2.7
|
||||||
|
import QtQuick.Layouts 1.3
|
||||||
|
import QtQuick.Controls 2.2 as Control
|
||||||
|
import QtQuick.Effects
|
||||||
|
|
||||||
|
import Linphone
|
||||||
|
import UtilsCpp 1.0
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: mainItem
|
||||||
|
property int sideMargin: 25 * DefaultStyle.dp
|
||||||
|
property int topMargin: 5 * DefaultStyle.dp
|
||||||
|
property bool groupCallVisible
|
||||||
|
property color searchBarColor: DefaultStyle.grey_100
|
||||||
|
property color searchBarBorderColor: "transparent"
|
||||||
|
signal callButtonPressed(string address)
|
||||||
|
clip: true
|
||||||
|
|
||||||
|
Popup {
|
||||||
|
id: startCallPopup
|
||||||
|
property FriendGui contact
|
||||||
|
onContactChanged: {
|
||||||
|
|
||||||
|
}
|
||||||
|
underlineColor: DefaultStyle.main1_500_main
|
||||||
|
anchors.centerIn: parent
|
||||||
|
width: parent.width
|
||||||
|
modal: true
|
||||||
|
leftPadding: 15 * DefaultStyle.dp
|
||||||
|
rightPadding: 15 * DefaultStyle.dp
|
||||||
|
topPadding: 20 * DefaultStyle.dp
|
||||||
|
bottomPadding: 25 * DefaultStyle.dp
|
||||||
|
contentItem: ColumnLayout {
|
||||||
|
RowLayout {
|
||||||
|
Text {
|
||||||
|
text: qsTr("Select channel")
|
||||||
|
font {
|
||||||
|
pixelSize: 16 * DefaultStyle.dp
|
||||||
|
weight: 800 * DefaultStyle.dp
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Item {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
Button {
|
||||||
|
Layout.preferredWidth: 24 * DefaultStyle.dp
|
||||||
|
Layout.preferredHeight: 24 * DefaultStyle.dp
|
||||||
|
background: Item{}
|
||||||
|
contentItem: Image {
|
||||||
|
anchors.fill: parent
|
||||||
|
source: AppIcons.closeX
|
||||||
|
}
|
||||||
|
onClicked: startCallPopup.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Repeater {
|
||||||
|
id: adresses
|
||||||
|
model: [{label: "SIP", address: startCallPopup.contact ? startCallPopup.contact.core.address : ""},
|
||||||
|
{label: "Work", address: "06000000000"},
|
||||||
|
{label: "Personal", address: "060000000"}
|
||||||
|
] //account.adresses
|
||||||
|
Button {
|
||||||
|
id: channel
|
||||||
|
// required property int index
|
||||||
|
leftPadding: 0
|
||||||
|
rightPadding: 0
|
||||||
|
// topPadding: 0
|
||||||
|
bottomPadding: 0
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
background: Item{}
|
||||||
|
contentItem: ColumnLayout {
|
||||||
|
RowLayout {
|
||||||
|
ColumnLayout {
|
||||||
|
Text {
|
||||||
|
Layout.leftMargin: 5 * DefaultStyle.dp
|
||||||
|
Layout.rightMargin: 5 * DefaultStyle.dp
|
||||||
|
text: modelData.label
|
||||||
|
font {
|
||||||
|
pixelSize: 14 * DefaultStyle.dp
|
||||||
|
weight: 700 * DefaultStyle.dp
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Text {
|
||||||
|
Layout.leftMargin: 5 * DefaultStyle.dp
|
||||||
|
Layout.rightMargin: 5 * DefaultStyle.dp
|
||||||
|
text: modelData.address
|
||||||
|
font {
|
||||||
|
pixelSize: 13 * DefaultStyle.dp
|
||||||
|
weight: 400 * DefaultStyle.dp
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Item {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Rectangle {
|
||||||
|
visible: index < adresses.count - 1
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.preferredHeight: 1 * DefaultStyle.dp
|
||||||
|
color: DefaultStyle.main2_200
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onClicked: mainItem.callButtonPressed(modelData.address)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Control.ScrollBar {
|
||||||
|
id: contactsScrollbar
|
||||||
|
active: true
|
||||||
|
interactive: true
|
||||||
|
policy: Control.ScrollBar.AlwaysOn
|
||||||
|
// Layout.fillWidth: true
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
anchors.right: parent.right
|
||||||
|
// x: mainItem.x + mainItem.width - width
|
||||||
|
// anchors.left: control.right
|
||||||
|
}
|
||||||
|
|
||||||
|
Control.Control {
|
||||||
|
id: listLayout
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.topMargin: mainItem.topMargin
|
||||||
|
background: Item {
|
||||||
|
anchors.fill: parent
|
||||||
|
}
|
||||||
|
contentItem: ColumnLayout {
|
||||||
|
anchors.fill: parent
|
||||||
|
spacing: 10 * DefaultStyle.dp
|
||||||
|
SearchBar {
|
||||||
|
id: searchBar
|
||||||
|
Layout.alignment: Qt.AlignTop
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.maximumWidth: mainItem.width
|
||||||
|
Layout.leftMargin: mainItem.sideMargin
|
||||||
|
Layout.rightMargin: mainItem.sideMargin
|
||||||
|
color: mainItem.searchBarColor
|
||||||
|
borderColor: mainItem.searchBarBorderColor
|
||||||
|
placeholderText: qsTr("Rechercher un contact")
|
||||||
|
numericPad: numPad
|
||||||
|
}
|
||||||
|
Control.ScrollView {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
Layout.leftMargin: mainItem.sideMargin
|
||||||
|
Layout.topMargin: 25 * DefaultStyle.dp
|
||||||
|
rightPadding: mainItem.sideMargin
|
||||||
|
contentWidth: width - mainItem.sideMargin
|
||||||
|
contentHeight: content.height
|
||||||
|
clip: true
|
||||||
|
Control.ScrollBar.vertical: contactsScrollbar
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: content
|
||||||
|
width: parent.width
|
||||||
|
spacing: 25 * DefaultStyle.dp
|
||||||
|
Button {
|
||||||
|
visible: mainItem.groupCallVisible
|
||||||
|
Layout.fillWidth: true
|
||||||
|
leftPadding: 0
|
||||||
|
topPadding: 0
|
||||||
|
rightPadding: 0
|
||||||
|
bottomPadding: 0
|
||||||
|
background: Rectangle {
|
||||||
|
color: DefaultStyle.groupCallButtonColor
|
||||||
|
anchors.fill: parent
|
||||||
|
radius: 50 * DefaultStyle.dp
|
||||||
|
}
|
||||||
|
contentItem: RowLayout {
|
||||||
|
Image {
|
||||||
|
source: AppIcons.groupCall
|
||||||
|
Layout.preferredWidth: 35 * DefaultStyle.dp
|
||||||
|
sourceSize.width: 35 * DefaultStyle.dp
|
||||||
|
fillMode: Image.PreserveAspectFit
|
||||||
|
}
|
||||||
|
Text {
|
||||||
|
text: "Appel de groupe"
|
||||||
|
font {
|
||||||
|
pixelSize: 16 * DefaultStyle.dp
|
||||||
|
weight: 800 * DefaultStyle.dp
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Item {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
Image {
|
||||||
|
source: AppIcons.rightArrow
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
visible: searchBar.text.length > 0
|
||||||
|
Layout.maximumWidth: parent.width
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Text {
|
||||||
|
text: searchBar.text
|
||||||
|
maximumLineCount: 1
|
||||||
|
elide: Text.ElideRight
|
||||||
|
}
|
||||||
|
Item {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
Control.Button {
|
||||||
|
implicitWidth: 30 * DefaultStyle.dp
|
||||||
|
implicitHeight: 30 * DefaultStyle.dp
|
||||||
|
background: Item {
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
contentItem: Image {
|
||||||
|
source: AppIcons.phone
|
||||||
|
width: 20 * DefaultStyle.dp
|
||||||
|
sourceSize.width: 20 * DefaultStyle.dp
|
||||||
|
fillMode: Image.PreserveAspectFit
|
||||||
|
}
|
||||||
|
onClicked: {
|
||||||
|
mainItem.callButtonPressed(searchBar.text)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ColumnLayout {
|
||||||
|
Text {
|
||||||
|
text: qsTr("All contacts")
|
||||||
|
font {
|
||||||
|
pixelSize: 16 * DefaultStyle.dp
|
||||||
|
weight: 800 * DefaultStyle.dp
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Repeater {
|
||||||
|
model: ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "\\d"]
|
||||||
|
RowLayout {
|
||||||
|
visible: contactList.count > 0
|
||||||
|
spacing: 8 * DefaultStyle.dp
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Text {
|
||||||
|
Layout.preferredWidth: 20 * DefaultStyle.dp
|
||||||
|
Layout.alignment: Qt.AlignTop
|
||||||
|
Layout.topMargin: 15 * DefaultStyle.dp // Align center with the first row
|
||||||
|
text: modelData == "\\d" ? " " : modelData
|
||||||
|
color: DefaultStyle.main2_400
|
||||||
|
font {
|
||||||
|
pixelSize: 20 * DefaultStyle.dp
|
||||||
|
weight: 500 * DefaultStyle.dp
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ContactsList{
|
||||||
|
Layout.fillWidth: true
|
||||||
|
id: contactList
|
||||||
|
initialProxyModel: modelData
|
||||||
|
searchBarText: searchBar.text
|
||||||
|
// contactMenuVisible: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ColumnLayout {
|
||||||
|
Text {
|
||||||
|
text: qsTr("Suggestions")
|
||||||
|
font {
|
||||||
|
pixelSize: 16 * DefaultStyle.dp
|
||||||
|
weight: 800 * DefaultStyle.dp
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ContactsList{
|
||||||
|
contactMenuVisible: false
|
||||||
|
Layout.fillHeight: true
|
||||||
|
|
||||||
|
model: FriendInitialProxy {
|
||||||
|
filterText: ""
|
||||||
|
property int sourceFlags: LinphoneEnums.MagicSearchSource.FavoriteFriends//mainItem.magicSearchSourceFlags
|
||||||
|
sourceModel: MagicSearchProxy {
|
||||||
|
id: search
|
||||||
|
searchText: searchBar.text.length === 0 ? "*" : searchBar.text
|
||||||
|
aggregationFlag: LinphoneEnums.MagicSearchAggregation.Friend
|
||||||
|
sourceFlags: LinphoneEnums.MagicSearchSource.FavoriteFriends
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Item {
|
||||||
|
Layout.fillHeight: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
height: numPad.implicitHeight
|
||||||
|
NumericPad {
|
||||||
|
id: numPad
|
||||||
|
width: parent.width
|
||||||
|
onLaunchCall: {
|
||||||
|
var callVarObject = UtilsCpp.createCall(searchBar.text + "@sip.linphone.org")
|
||||||
|
// TODO : auto completion instead of sip linphone
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,165 +0,0 @@
|
||||||
import QtQuick 2.7
|
|
||||||
import QtQuick.Layouts 1.3
|
|
||||||
import QtQuick.Controls 2.2 as Control
|
|
||||||
import QtQuick.Effects
|
|
||||||
|
|
||||||
import Linphone
|
|
||||||
|
|
||||||
Item {
|
|
||||||
id: mainItem
|
|
||||||
property int sideMargin: 25 * DefaultStyle.dp
|
|
||||||
property int topMargin: 5 * DefaultStyle.dp
|
|
||||||
property bool groupCallVisible
|
|
||||||
property color searchBarColor: DefaultStyle.grey_100
|
|
||||||
property color searchBarBorderColor: "transparent"
|
|
||||||
signal callButtonPressed(string address)
|
|
||||||
clip: true
|
|
||||||
Control.Control {
|
|
||||||
id: listLayout
|
|
||||||
anchors.fill: parent
|
|
||||||
anchors.leftMargin: mainItem.sideMargin
|
|
||||||
anchors.rightMargin: mainItem.sideMargin
|
|
||||||
anchors.topMargin: mainItem.topMargin
|
|
||||||
background: Item {
|
|
||||||
anchors.fill: parent
|
|
||||||
}
|
|
||||||
contentItem: ColumnLayout {
|
|
||||||
anchors.fill: parent
|
|
||||||
spacing: 10 * DefaultStyle.dp
|
|
||||||
SearchBar {
|
|
||||||
id: searchBar
|
|
||||||
Layout.alignment: Qt.AlignTop
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.maximumWidth: mainItem.width
|
|
||||||
color: mainItem.searchBarColor
|
|
||||||
borderColor: mainItem.searchBarBorderColor
|
|
||||||
placeholderText: qsTr("Rechercher un contact")
|
|
||||||
numericPad: numPad
|
|
||||||
}
|
|
||||||
Button {
|
|
||||||
visible: mainItem.groupCallVisible
|
|
||||||
Layout.fillWidth: true
|
|
||||||
leftPadding: 0
|
|
||||||
topPadding: 0
|
|
||||||
rightPadding: 0
|
|
||||||
bottomPadding: 0
|
|
||||||
background: Rectangle {
|
|
||||||
color: DefaultStyle.groupCallButtonColor
|
|
||||||
anchors.fill: parent
|
|
||||||
radius: 50 * DefaultStyle.dp
|
|
||||||
}
|
|
||||||
contentItem: RowLayout {
|
|
||||||
Image {
|
|
||||||
source: AppIcons.groupCall
|
|
||||||
Layout.preferredWidth: 35 * DefaultStyle.dp
|
|
||||||
sourceSize.width: 35 * DefaultStyle.dp
|
|
||||||
fillMode: Image.PreserveAspectFit
|
|
||||||
}
|
|
||||||
Text {
|
|
||||||
text: "Appel de groupe"
|
|
||||||
font {
|
|
||||||
pixelSize: 16 * DefaultStyle.dp
|
|
||||||
weight: 800 * DefaultStyle.dp
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Item {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
}
|
|
||||||
Image {
|
|
||||||
source: AppIcons.rightArrow
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RowLayout {
|
|
||||||
visible: searchBar.text.length > 0 // && contactList.count === 0 (pas trouvé dans la liste)
|
|
||||||
Layout.maximumWidth: parent.width
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Text {
|
|
||||||
text: searchBar.text
|
|
||||||
maximumLineCount: 1
|
|
||||||
elide: Text.ElideRight
|
|
||||||
}
|
|
||||||
Item {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
}
|
|
||||||
Control.Button {
|
|
||||||
implicitWidth: 30 * DefaultStyle.dp
|
|
||||||
implicitHeight: 30 * DefaultStyle.dp
|
|
||||||
background: Item {
|
|
||||||
visible: false
|
|
||||||
}
|
|
||||||
contentItem: Image {
|
|
||||||
source: AppIcons.phone
|
|
||||||
width: 20 * DefaultStyle.dp
|
|
||||||
sourceSize.width: 20 * DefaultStyle.dp
|
|
||||||
fillMode: Image.PreserveAspectFit
|
|
||||||
}
|
|
||||||
onClicked: {
|
|
||||||
mainItem.callButtonPressed(searchBar.text)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ListView {
|
|
||||||
id: contactList
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.fillHeight: true
|
|
||||||
// call history
|
|
||||||
model: 30
|
|
||||||
delegate: Item {
|
|
||||||
required property int index
|
|
||||||
width:contactList.width
|
|
||||||
height: 30 * DefaultStyle.dp
|
|
||||||
RowLayout {
|
|
||||||
anchors.fill: parent
|
|
||||||
Image {
|
|
||||||
source: AppIcons.info
|
|
||||||
}
|
|
||||||
ColumnLayout {
|
|
||||||
Text {
|
|
||||||
text: "John Doe"
|
|
||||||
}
|
|
||||||
// RowLayout {
|
|
||||||
// Image {
|
|
||||||
// source: AppIcons.incomingCall
|
|
||||||
// }
|
|
||||||
// Text {
|
|
||||||
// text: "info sur l'appel"
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
Item {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
MouseArea {
|
|
||||||
hoverEnabled: true
|
|
||||||
Rectangle {
|
|
||||||
anchors.fill: parent
|
|
||||||
opacity: 0.1
|
|
||||||
radius: 15 * DefaultStyle.dp
|
|
||||||
color: DefaultStyle.main2_500main
|
|
||||||
visible: parent.containsMouse
|
|
||||||
}
|
|
||||||
onClicked: contactList.currentIndex = parent.index
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Item {
|
|
||||||
anchors.bottom: parent.bottom
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.right: parent.right
|
|
||||||
height: numPad.implicitHeight
|
|
||||||
NumericPad {
|
|
||||||
id: numPad
|
|
||||||
width: parent.width
|
|
||||||
onLaunchCall: {
|
|
||||||
var callVarObject = UtilsCpp.createCall(searchBar.text + "@sip.linphone.org")
|
|
||||||
// TODO : auto completion instead of sip linphone
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -19,7 +19,9 @@ StackView{
|
||||||
? account.core.identityAddress
|
? account.core.identityAddress
|
||||||
: call
|
: call
|
||||||
? call.core.peerAddress
|
? call.core.peerAddress
|
||||||
: ''
|
: contact
|
||||||
|
? contact.core.address
|
||||||
|
: ''
|
||||||
property var displayNameObj: UtilsCpp.getDisplayName(address)
|
property var displayNameObj: UtilsCpp.getDisplayName(address)
|
||||||
property bool haveAvatar: (account && account.core.pictureUri )
|
property bool haveAvatar: (account && account.core.pictureUri )
|
||||||
|| (contact && contact.core.pictureUri)
|
|| (contact && contact.core.pictureUri)
|
||||||
|
|
|
||||||
129
Linphone/view/Item/ContactsList.qml
Normal file
129
Linphone/view/Item/ContactsList.qml
Normal file
|
|
@ -0,0 +1,129 @@
|
||||||
|
import QtQuick 2.7
|
||||||
|
import QtQuick.Layouts 1.3
|
||||||
|
|
||||||
|
import Linphone
|
||||||
|
import UtilsCpp 1.0
|
||||||
|
|
||||||
|
ListView {
|
||||||
|
id: mainItem
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.preferredHeight: contentHeight
|
||||||
|
height: contentHeight
|
||||||
|
visible: count > 0
|
||||||
|
|
||||||
|
property string initialProxyModel
|
||||||
|
|
||||||
|
property bool favorite: true
|
||||||
|
// Component.onCompleted: model.sourceModel.sourceFlags = magicSearchSourceFlags
|
||||||
|
|
||||||
|
property string searchBarText
|
||||||
|
|
||||||
|
property bool contactMenuVisible: true
|
||||||
|
|
||||||
|
model: FriendInitialProxy {
|
||||||
|
filterText: initialProxyModel
|
||||||
|
property int sourceFlags: LinphoneEnums.MagicSearchSource.FavoriteFriends//mainItem.magicSearchSourceFlags
|
||||||
|
sourceModel: MagicSearchProxy {
|
||||||
|
id: search
|
||||||
|
searchText: searchBarText.length === 0 ? "*" : searchBarText
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delegate: Item {
|
||||||
|
width: mainItem.width
|
||||||
|
height: 56 * DefaultStyle.dp
|
||||||
|
RowLayout {
|
||||||
|
anchors.fill: parent
|
||||||
|
z: 1
|
||||||
|
Avatar {
|
||||||
|
Layout.preferredWidth: 45 * DefaultStyle.dp
|
||||||
|
Layout.preferredHeight: 45 * DefaultStyle.dp
|
||||||
|
contact: modelData
|
||||||
|
}
|
||||||
|
Text {
|
||||||
|
text: UtilsCpp.getDisplayName(modelData.core.address).value
|
||||||
|
font.pixelSize: 14 * DefaultStyle.dp
|
||||||
|
font.capitalization: Font.Capitalize
|
||||||
|
|
||||||
|
}
|
||||||
|
Item {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
PopupButton {
|
||||||
|
id: friendPopup
|
||||||
|
hoverEnabled: true
|
||||||
|
visible: mainItem.contactMenuVisible && (contactArea.containsMouse || hovered || popup.opened)
|
||||||
|
popup.x: 0
|
||||||
|
popup.padding: 10 * DefaultStyle.dp
|
||||||
|
popup.contentItem: ColumnLayout {
|
||||||
|
Button {
|
||||||
|
background: Item{}
|
||||||
|
contentItem: RowLayout {
|
||||||
|
Image {
|
||||||
|
source: modelData.core.starred ? AppIcons.heartFill : AppIcons.heart
|
||||||
|
fillMode: Image.PreserveAspectFit
|
||||||
|
width: 24 * DefaultStyle.dp
|
||||||
|
height: 24 * DefaultStyle.dp
|
||||||
|
Layout.preferredWidth: 24 * DefaultStyle.dp
|
||||||
|
Layout.preferredHeight: 24 * DefaultStyle.dp
|
||||||
|
}
|
||||||
|
Text {
|
||||||
|
text: modelData.core.starred ? qsTr("Enlever des favoris") : qsTr("Mettre en favori")
|
||||||
|
color: DefaultStyle.main2_500main
|
||||||
|
font {
|
||||||
|
pixelSize: 14 * DefaultStyle.dp
|
||||||
|
weight: 400 * DefaultStyle.dp
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onClicked: {
|
||||||
|
modelData.core.lSetStarred(!modelData.core.starred)
|
||||||
|
friendPopup.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Button {
|
||||||
|
background: Item{}
|
||||||
|
contentItem: RowLayout {
|
||||||
|
EffectImage {
|
||||||
|
image.source: AppIcons.trashCan
|
||||||
|
width: 24 * DefaultStyle.dp
|
||||||
|
height: 24 * DefaultStyle.dp
|
||||||
|
Layout.preferredWidth: 24 * DefaultStyle.dp
|
||||||
|
Layout.preferredHeight: 24 * DefaultStyle.dp
|
||||||
|
image.fillMode: Image.PreserveAspectFit
|
||||||
|
colorizationColor: DefaultStyle.danger_500main
|
||||||
|
}
|
||||||
|
Text {
|
||||||
|
text: qsTr("Supprimmer")
|
||||||
|
color: DefaultStyle.danger_500main
|
||||||
|
font {
|
||||||
|
pixelSize: 14 * DefaultStyle.dp
|
||||||
|
weight: 400 * DefaultStyle.dp
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onClicked: {
|
||||||
|
modelData.core.remove()
|
||||||
|
friendPopup.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MouseArea {
|
||||||
|
id: contactArea
|
||||||
|
hoverEnabled: true
|
||||||
|
anchors.fill: parent
|
||||||
|
Rectangle {
|
||||||
|
anchors.fill: contactArea
|
||||||
|
opacity: 0.1
|
||||||
|
color: DefaultStyle.main2_500main
|
||||||
|
visible: contactArea.containsMouse || friendPopup.hovered
|
||||||
|
}
|
||||||
|
onClicked: {
|
||||||
|
startCallPopup.contact = modelData
|
||||||
|
startCallPopup.open()
|
||||||
|
// mainItem.callButtonPressed(modelData.core.address)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -13,7 +13,7 @@ Button {
|
||||||
rightPadding: 0
|
rightPadding: 0
|
||||||
topPadding: 0
|
topPadding: 0
|
||||||
bottomPadding: 0
|
bottomPadding: 0
|
||||||
function closePopup() {
|
function close() {
|
||||||
popup.close()
|
popup.close()
|
||||||
}
|
}
|
||||||
background: Rectangle {
|
background: Rectangle {
|
||||||
|
|
|
||||||
|
|
@ -27,10 +27,10 @@ Item {
|
||||||
implicitWidth: 8 * DefaultStyle.dp
|
implicitWidth: 8 * DefaultStyle.dp
|
||||||
color: Control.SplitHandle.hovered ? DefaultStyle.grey_200 : DefaultStyle.grey_100
|
color: Control.SplitHandle.hovered ? DefaultStyle.grey_200 : DefaultStyle.grey_100
|
||||||
}
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: leftPanel
|
id: leftPanel
|
||||||
Control.SplitView.preferredWidth: 350 * DefaultStyle.dp
|
Control.SplitView.preferredWidth: 350 * DefaultStyle.dp
|
||||||
|
Control.SplitView.minimumWidth: 350 * DefaultStyle.dp
|
||||||
}
|
}
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: rightPanel
|
id: rightPanel
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,7 @@ AbstractMainPage {
|
||||||
colorizationColor: DefaultStyle.danger_500main
|
colorizationColor: DefaultStyle.danger_500main
|
||||||
}
|
}
|
||||||
Text {
|
Text {
|
||||||
text: qsTr("Supprimmer l’historique")
|
text: qsTr("Supprimer l’historique")
|
||||||
color: DefaultStyle.danger_500main
|
color: DefaultStyle.danger_500main
|
||||||
font {
|
font {
|
||||||
pixelSize: 14 * DefaultStyle.dp
|
pixelSize: 14 * DefaultStyle.dp
|
||||||
|
|
@ -80,7 +80,7 @@ AbstractMainPage {
|
||||||
}
|
}
|
||||||
onClicked: {
|
onClicked: {
|
||||||
historyListView.model.removeAllEntries()
|
historyListView.model.removeAllEntries()
|
||||||
removeHistory.closePopup()
|
removeHistory.close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -101,194 +101,197 @@ AbstractMainPage {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RowLayout {
|
ColumnLayout {
|
||||||
Control.Control {
|
SearchBar {
|
||||||
id: listLayout
|
id: searchBar
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.fillHeight: true
|
|
||||||
Layout.leftMargin: listStackView.sideMargin
|
Layout.leftMargin: listStackView.sideMargin
|
||||||
Layout.rightMargin: listStackView.sideMargin
|
Layout.rightMargin: listStackView.sideMargin
|
||||||
|
placeholderText: qsTr("Rechercher un appel")
|
||||||
|
}
|
||||||
|
RowLayout {
|
||||||
|
Layout.topMargin: 30 * DefaultStyle.dp
|
||||||
|
Control.Control {
|
||||||
|
id: listLayout
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
Layout.leftMargin: listStackView.sideMargin
|
||||||
|
Layout.rightMargin: listStackView.sideMargin
|
||||||
|
|
||||||
background: Rectangle {
|
background: Rectangle {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
}
|
|
||||||
ColumnLayout {
|
|
||||||
anchors.fill: parent
|
|
||||||
SearchBar {
|
|
||||||
id: searchBar
|
|
||||||
Layout.alignment: Qt.AlignTop
|
|
||||||
Layout.fillWidth: true
|
|
||||||
placeholderText: qsTr("Rechercher un appel")
|
|
||||||
}
|
}
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
Text {
|
anchors.fill: parent
|
||||||
text: qsTr("Aucun appel")
|
ColumnLayout {
|
||||||
font {
|
Text {
|
||||||
pixelSize: 16 * DefaultStyle.dp
|
text: qsTr("Aucun appel")
|
||||||
weight: 800 * DefaultStyle.dp
|
font {
|
||||||
}
|
pixelSize: 16 * DefaultStyle.dp
|
||||||
visible: historyListView.count === 0
|
weight: 800 * DefaultStyle.dp
|
||||||
Layout.alignment: Qt.AlignHCenter
|
}
|
||||||
Layout.topMargin: 30 * DefaultStyle.dp
|
visible: historyListView.count === 0
|
||||||
}
|
Layout.alignment: Qt.AlignHCenter
|
||||||
ListView {
|
|
||||||
id: historyListView
|
|
||||||
clip: true
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.fillHeight: true
|
|
||||||
Layout.topMargin: 30 * DefaultStyle.dp
|
|
||||||
model: CallHistoryProxy{
|
|
||||||
filterText: searchBar.text
|
|
||||||
}
|
|
||||||
currentIndex: -1
|
|
||||||
onCurrentIndexChanged: {
|
|
||||||
mainItem.selectedRowHistoryGui = model.getAt(currentIndex)
|
|
||||||
}
|
|
||||||
spacing: 10 * DefaultStyle.dp
|
|
||||||
highlightMoveDuration: 10
|
|
||||||
highlightMoveVelocity: -1
|
|
||||||
// highlightFollowsCurrentItem: true
|
|
||||||
highlight: Rectangle {
|
|
||||||
x: historyListView.x
|
|
||||||
width: historyListView.width
|
|
||||||
height: historyListView.height
|
|
||||||
color: DefaultStyle.main2_100
|
|
||||||
y: historyListView.currentItem? historyListView.currentItem.y : 0
|
|
||||||
}
|
}
|
||||||
|
ListView {
|
||||||
|
id: historyListView
|
||||||
|
clip: true
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
model: CallHistoryProxy{
|
||||||
|
filterText: searchBar.text
|
||||||
|
}
|
||||||
|
currentIndex: -1
|
||||||
|
|
||||||
delegate: Item {
|
spacing: 10 * DefaultStyle.dp
|
||||||
width:historyListView.width
|
highlightMoveDuration: 10
|
||||||
height: 56 * DefaultStyle.dp
|
highlightMoveVelocity: -1
|
||||||
anchors.topMargin: 5 * DefaultStyle.dp
|
// highlightFollowsCurrentItem: true
|
||||||
anchors.bottomMargin: 5 * DefaultStyle.dp
|
highlight: Rectangle {
|
||||||
RowLayout {
|
x: historyListView.x
|
||||||
z: 1
|
width: historyListView.width
|
||||||
anchors.fill: parent
|
height: historyListView.height
|
||||||
Item {
|
color: DefaultStyle.main2_100
|
||||||
Layout.preferredWidth: historyAvatar.width
|
y: historyListView.currentItem? historyListView.currentItem.y : 0
|
||||||
Layout.preferredHeight: historyAvatar.height
|
}
|
||||||
Layout.leftMargin: 5 * DefaultStyle.dp
|
|
||||||
MultiEffect {
|
delegate: Item {
|
||||||
source: historyAvatar
|
width:historyListView.width
|
||||||
anchors.fill: historyAvatar
|
height: 56 * DefaultStyle.dp
|
||||||
shadowEnabled: true
|
anchors.topMargin: 5 * DefaultStyle.dp
|
||||||
shadowBlur: 1
|
anchors.bottomMargin: 5 * DefaultStyle.dp
|
||||||
shadowColor: DefaultStyle.grey_900
|
RowLayout {
|
||||||
shadowOpacity: 0.1
|
z: 1
|
||||||
}
|
anchors.fill: parent
|
||||||
Avatar {
|
Item {
|
||||||
id: historyAvatar
|
Layout.preferredWidth: historyAvatar.width
|
||||||
address: modelData.core.remoteAddress
|
Layout.preferredHeight: historyAvatar.height
|
||||||
width: 45 * DefaultStyle.dp
|
Layout.leftMargin: 5 * DefaultStyle.dp
|
||||||
height: 45 * DefaultStyle.dp
|
MultiEffect {
|
||||||
}
|
source: historyAvatar
|
||||||
}
|
anchors.fill: historyAvatar
|
||||||
ColumnLayout {
|
shadowEnabled: true
|
||||||
Layout.alignment: Qt.AlignVCenter
|
shadowBlur: 1
|
||||||
Text {
|
shadowColor: DefaultStyle.grey_900
|
||||||
property var remoteAddress: modelData ? UtilsCpp.getDisplayName(modelData.core.remoteAddress) : undefined
|
shadowOpacity: 0.1
|
||||||
text: remoteAddress ? remoteAddress.value : ""
|
}
|
||||||
font {
|
Avatar {
|
||||||
pixelSize: 14 * DefaultStyle.dp
|
id: historyAvatar
|
||||||
weight: 400 * DefaultStyle.dp
|
address: modelData.core.remoteAddress
|
||||||
|
width: 45 * DefaultStyle.dp
|
||||||
|
height: 45 * DefaultStyle.dp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RowLayout {
|
ColumnLayout {
|
||||||
Image {
|
Layout.alignment: Qt.AlignVCenter
|
||||||
source: modelData.core.status === LinphoneEnums.CallStatus.Declined
|
|
||||||
|| modelData.core.status === LinphoneEnums.CallStatus.DeclinedElsewhere
|
|
||||||
|| modelData.core.status === LinphoneEnums.CallStatus.Aborted
|
|
||||||
|| modelData.core.status === LinphoneEnums.CallStatus.EarlyAborted
|
|
||||||
? modelData.core.isOutgoing
|
|
||||||
? AppIcons.outgoingCallRejected
|
|
||||||
: AppIcons.incomingCallRejected
|
|
||||||
: modelData.core.status === LinphoneEnums.CallStatus.Missed
|
|
||||||
? modelData.core.isOutgoing
|
|
||||||
? AppIcons.outgoingCallMissed
|
|
||||||
: AppIcons.incomingCallMissed
|
|
||||||
: modelData.core.isOutgoing
|
|
||||||
? AppIcons.outgoingCall
|
|
||||||
: AppIcons.incomingCall
|
|
||||||
Layout.preferredWidth: 5 * DefaultStyle.dp
|
|
||||||
Layout.preferredHeight: 5 * DefaultStyle.dp
|
|
||||||
sourceSize.width: 5 * DefaultStyle.dp
|
|
||||||
sourceSize.height: 5 * DefaultStyle.dp
|
|
||||||
}
|
|
||||||
Text {
|
Text {
|
||||||
// text: modelData.core.date
|
property var remoteAddress: modelData ? UtilsCpp.getDisplayName(modelData.core.remoteAddress) : undefined
|
||||||
text: UtilsCpp.formatDateElapsedTime(modelData.core.date)
|
text: remoteAddress ? remoteAddress.value : ""
|
||||||
font {
|
font {
|
||||||
pixelSize: 12 * DefaultStyle.dp
|
pixelSize: 14 * DefaultStyle.dp
|
||||||
weight: 300 * DefaultStyle.dp
|
weight: 400 * DefaultStyle.dp
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RowLayout {
|
||||||
|
Image {
|
||||||
|
source: modelData.core.status === LinphoneEnums.CallStatus.Declined
|
||||||
|
|| modelData.core.status === LinphoneEnums.CallStatus.DeclinedElsewhere
|
||||||
|
|| modelData.core.status === LinphoneEnums.CallStatus.Aborted
|
||||||
|
|| modelData.core.status === LinphoneEnums.CallStatus.EarlyAborted
|
||||||
|
? modelData.core.isOutgoing
|
||||||
|
? AppIcons.outgoingCallRejected
|
||||||
|
: AppIcons.incomingCallRejected
|
||||||
|
: modelData.core.status === LinphoneEnums.CallStatus.Missed
|
||||||
|
? modelData.core.isOutgoing
|
||||||
|
? AppIcons.outgoingCallMissed
|
||||||
|
: AppIcons.incomingCallMissed
|
||||||
|
: modelData.core.isOutgoing
|
||||||
|
? AppIcons.outgoingCall
|
||||||
|
: AppIcons.incomingCall
|
||||||
|
Layout.preferredWidth: 5 * DefaultStyle.dp
|
||||||
|
Layout.preferredHeight: 5 * DefaultStyle.dp
|
||||||
|
sourceSize.width: 5 * DefaultStyle.dp
|
||||||
|
sourceSize.height: 5 * DefaultStyle.dp
|
||||||
|
}
|
||||||
|
Text {
|
||||||
|
// text: modelData.core.date
|
||||||
|
text: UtilsCpp.formatDateElapsedTime(modelData.core.date)
|
||||||
|
font {
|
||||||
|
pixelSize: 12 * DefaultStyle.dp
|
||||||
|
weight: 300 * DefaultStyle.dp
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
Item {
|
||||||
Item {
|
Layout.fillWidth: true
|
||||||
Layout.fillWidth: true
|
|
||||||
}
|
|
||||||
Control.Button {
|
|
||||||
implicitWidth: 24 * DefaultStyle.dp
|
|
||||||
implicitHeight: 24 * DefaultStyle.dp
|
|
||||||
Layout.rightMargin: 5 * DefaultStyle.dp
|
|
||||||
padding: 0
|
|
||||||
background: Item {
|
|
||||||
visible: false
|
|
||||||
}
|
}
|
||||||
contentItem: Image {
|
Control.Button {
|
||||||
source: AppIcons.phone
|
implicitWidth: 24 * DefaultStyle.dp
|
||||||
width: 24 * DefaultStyle.dp
|
implicitHeight: 24 * DefaultStyle.dp
|
||||||
sourceSize.width: 24 * DefaultStyle.dp
|
Layout.rightMargin: 5 * DefaultStyle.dp
|
||||||
fillMode: Image.PreserveAspectFit
|
padding: 0
|
||||||
}
|
background: Item {
|
||||||
onClicked: {
|
visible: false
|
||||||
var addr = modelData.core.remoteAddress
|
}
|
||||||
var addressEnd = "@sip.linphone.org"
|
contentItem: Image {
|
||||||
if (!addr.endsWith(addressEnd)) addr += addressEnd
|
source: AppIcons.phone
|
||||||
var callVarObject = UtilsCpp.createCall(addr)
|
width: 24 * DefaultStyle.dp
|
||||||
|
sourceSize.width: 24 * DefaultStyle.dp
|
||||||
|
fillMode: Image.PreserveAspectFit
|
||||||
|
}
|
||||||
|
onClicked: {
|
||||||
|
var addr = modelData.core.remoteAddress
|
||||||
|
var addressEnd = "@sip.linphone.org"
|
||||||
|
if (!addr.endsWith(addressEnd)) addr += addressEnd
|
||||||
|
var callVarObject = UtilsCpp.createCall(addr)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
MouseArea {
|
||||||
MouseArea {
|
hoverEnabled: true
|
||||||
hoverEnabled: true
|
|
||||||
anchors.fill: parent
|
|
||||||
Rectangle {
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
opacity: 0.1
|
Rectangle {
|
||||||
color: DefaultStyle.main2_500main
|
anchors.fill: parent
|
||||||
visible: parent.containsMouse
|
opacity: 0.1
|
||||||
}
|
color: DefaultStyle.main2_500main
|
||||||
onPressed: {
|
visible: parent.containsMouse
|
||||||
historyListView.currentIndex = model.index
|
}
|
||||||
|
onPressed: {
|
||||||
|
historyListView.currentIndex = model.index
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
onCurrentIndexChanged: {
|
||||||
|
mainItem.selectedRowHistoryGui = model.getAt(currentIndex)
|
||||||
onCountChanged: {
|
|
||||||
mainItem.showDefaultItem = historyListView.count === 0 && historyListView.visible
|
|
||||||
}
|
|
||||||
|
|
||||||
onVisibleChanged: {
|
|
||||||
mainItem.showDefaultItem = historyListView.count === 0 && historyListView.visible
|
|
||||||
if (!visible) currentIndex = -1
|
|
||||||
}
|
|
||||||
|
|
||||||
Connections {
|
|
||||||
target: mainItem
|
|
||||||
onShowDefaultItemChanged: mainItem.showDefaultItem = mainItem.showDefaultItem && historyListView.count === 0 && historyListView.visible
|
|
||||||
onListViewUpdated: {
|
|
||||||
historyListView.model.updateView()
|
|
||||||
}
|
}
|
||||||
|
onCountChanged: {
|
||||||
|
mainItem.showDefaultItem = historyListView.count === 0 && historyListView.visible
|
||||||
|
}
|
||||||
|
|
||||||
|
onVisibleChanged: {
|
||||||
|
mainItem.showDefaultItem = historyListView.count === 0 && historyListView.visible
|
||||||
|
if (!visible) currentIndex = -1
|
||||||
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: mainItem
|
||||||
|
onShowDefaultItemChanged: mainItem.showDefaultItem = mainItem.showDefaultItem && historyListView.count === 0 && historyListView.visible
|
||||||
|
onListViewUpdated: {
|
||||||
|
historyListView.model.updateView()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Control.ScrollBar.vertical: scrollbar
|
||||||
}
|
}
|
||||||
Control.ScrollBar.vertical: scrollbar
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
Control.ScrollBar {
|
||||||
Control.ScrollBar {
|
id: scrollbar
|
||||||
id: scrollbar
|
active: true
|
||||||
active: true
|
policy: Control.ScrollBar.AlwaysOn
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -324,18 +327,24 @@ AbstractMainPage {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ContactsList {
|
RowLayout {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
Layout.maximumWidth: parent.width
|
// Layout.maximumWidth: parent.width
|
||||||
groupCallVisible: true
|
CallContactsLists {
|
||||||
searchBarColor: DefaultStyle.grey_100
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
// Layout.leftMargin: listStackView.sideMargin
|
||||||
|
// Layout.rightMargin: listStackView.sideMargin
|
||||||
|
groupCallVisible: true
|
||||||
|
searchBarColor: DefaultStyle.grey_100
|
||||||
|
|
||||||
onCallButtonPressed: (address) => {
|
onCallButtonPressed: (address) => {
|
||||||
var addressEnd = "@sip.linphone.org"
|
var addressEnd = "@sip.linphone.org"
|
||||||
if (!address.endsWith(addressEnd)) address += addressEnd
|
if (!address.endsWith(addressEnd)) address += addressEnd
|
||||||
var callVarObject = UtilsCpp.createCall(address)
|
var callVarObject = UtilsCpp.createCall(address)
|
||||||
// var window = UtilsCpp.getCallsWindow()
|
// var window = UtilsCpp.getCallsWindow()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -366,7 +375,7 @@ AbstractMainPage {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
width: 100 * DefaultStyle.dp
|
width: 100 * DefaultStyle.dp
|
||||||
height: 100 * DefaultStyle.dp
|
height: 100 * DefaultStyle.dp
|
||||||
address: mainItem.selectedRowHistoryGui ? mainItem.selectedRowHistoryGui.core.remoteAddress : ""
|
address: mainItem.selectedRowHistoryGui && mainItem.selectedRowHistoryGui.core.remoteAddress || ""
|
||||||
}
|
}
|
||||||
PopupButton {
|
PopupButton {
|
||||||
id: detailOptions
|
id: detailOptions
|
||||||
|
|
@ -381,7 +390,14 @@ AbstractMainPage {
|
||||||
text: qsTr("Ajouter aux contacts")
|
text: qsTr("Ajouter aux contacts")
|
||||||
iconSource: AppIcons.plusCircle
|
iconSource: AppIcons.plusCircle
|
||||||
}
|
}
|
||||||
onClicked: console.debug("[CallPage.qml] TODO : add to contact")
|
onClicked: {
|
||||||
|
// console.debug("[CallPage.qml] TODO : add to contact")
|
||||||
|
var friendGui = Qt.createQmlObject('import Linphone
|
||||||
|
FriendGui{}', detailAvatar)
|
||||||
|
friendGui.core.name = contactName.text
|
||||||
|
friendGui.core.address = contactAddress.text
|
||||||
|
friendGui.core.save()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Button {
|
Button {
|
||||||
background: Item {}
|
background: Item {}
|
||||||
|
|
@ -413,8 +429,8 @@ AbstractMainPage {
|
||||||
}
|
}
|
||||||
onClicked: {
|
onClicked: {
|
||||||
detailListView.model.removeEntriesWithFilter()
|
detailListView.model.removeEntriesWithFilter()
|
||||||
detailListView.currentIndex = -1 // reset index for ui
|
// detailListView.currentIndex = -1 // reset index for ui
|
||||||
detailOptions.closePopup()
|
detailOptions.close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -424,6 +440,7 @@ AbstractMainPage {
|
||||||
Layout.alignment: Qt.AlignHCenter
|
Layout.alignment: Qt.AlignHCenter
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Text {
|
Text {
|
||||||
|
id: contactName
|
||||||
property var remoteAddress: mainItem.selectedRowHistoryGui ? UtilsCpp.getDisplayName(mainItem.selectedRowHistoryGui.core.remoteAddress) : undefined
|
property var remoteAddress: mainItem.selectedRowHistoryGui ? UtilsCpp.getDisplayName(mainItem.selectedRowHistoryGui.core.remoteAddress) : undefined
|
||||||
Layout.alignment: Qt.AlignHCenter
|
Layout.alignment: Qt.AlignHCenter
|
||||||
text: remoteAddress ? remoteAddress.value : ""
|
text: remoteAddress ? remoteAddress.value : ""
|
||||||
|
|
@ -434,6 +451,7 @@ AbstractMainPage {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Text {
|
Text {
|
||||||
|
id: contactAddress
|
||||||
text: mainItem.selectedRowHistoryGui ? mainItem.selectedRowHistoryGui.core.remoteAddress : ""
|
text: mainItem.selectedRowHistoryGui ? mainItem.selectedRowHistoryGui.core.remoteAddress : ""
|
||||||
horizontalAlignment: Text.AlignHCenter
|
horizontalAlignment: Text.AlignHCenter
|
||||||
font {
|
font {
|
||||||
|
|
@ -554,7 +572,6 @@ AbstractMainPage {
|
||||||
sourceSize.height: 6.67 * DefaultStyle.dp
|
sourceSize.height: 6.67 * DefaultStyle.dp
|
||||||
}
|
}
|
||||||
Text {
|
Text {
|
||||||
Component.onCompleted: console.log("status", modelData.core.status)
|
|
||||||
text: modelData.core.status === LinphoneEnums.CallStatus.Missed
|
text: modelData.core.status === LinphoneEnums.CallStatus.Missed
|
||||||
? qsTr("Appel manqué")
|
? qsTr("Appel manqué")
|
||||||
: modelData.core.isOutgoing
|
: modelData.core.isOutgoing
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ Window{
|
||||||
contact.core.save()
|
contact.core.save()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Text{
|
Text {
|
||||||
text: 'IsSaved:'+contact.core.isSaved
|
text: 'IsSaved:'+contact.core.isSaved
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -40,6 +40,7 @@ Window{
|
||||||
id: friends
|
id: friends
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
onCountChanged: console.log("count changed", count)
|
||||||
|
|
||||||
model: MagicSearchProxy{
|
model: MagicSearchProxy{
|
||||||
id: search
|
id: search
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ QtObject {
|
||||||
property string downArrow: "image://internal/caret-down.svg"
|
property string downArrow: "image://internal/caret-down.svg"
|
||||||
property string returnArrow: "image://internal/caret-left.svg"
|
property string returnArrow: "image://internal/caret-left.svg"
|
||||||
property string rightArrow: "image://internal/caret-right.svg"
|
property string rightArrow: "image://internal/caret-right.svg"
|
||||||
|
property string upArrow: "image://internal/caret-up.svg"
|
||||||
property string info: "image://internal/info.svg"
|
property string info: "image://internal/info.svg"
|
||||||
property string loginImage: "image://internal/login_image.svg"
|
property string loginImage: "image://internal/login_image.svg"
|
||||||
property string belledonne: "image://internal/belledonne.svg"
|
property string belledonne: "image://internal/belledonne.svg"
|
||||||
|
|
@ -61,4 +62,6 @@ QtObject {
|
||||||
property string trashCan: "image://internal/trash-simple.svg"
|
property string trashCan: "image://internal/trash-simple.svg"
|
||||||
property string copy: "image://internal/copy.svg"
|
property string copy: "image://internal/copy.svg"
|
||||||
property string empty: "image://internal/empty.svg"
|
property string empty: "image://internal/empty.svg"
|
||||||
|
property string heart: "image://internal/heart.svg"
|
||||||
|
property string heartFill: "image://internal/heart-fill.svg"
|
||||||
}
|
}
|
||||||
Loading…
Reference in a new issue