mirror of
https://gitlab.linphone.org/BC/public/linphone-desktop.git
synced 2026-01-17 03:18:07 +00:00
Optimizations: Paging and asynchronous loaders.
This commit is contained in:
parent
8b3abc7f6d
commit
e1b8befde4
57 changed files with 1171 additions and 872 deletions
|
|
@ -39,6 +39,7 @@ list(APPEND _LINPHONEAPP_SOURCES
|
|||
core/proxy/ListProxy.cpp
|
||||
core/proxy/Proxy.cpp
|
||||
core/proxy/SortFilterProxy.cpp
|
||||
core/proxy/LimitProxy.cpp
|
||||
|
||||
core/variant/VariantList.cpp
|
||||
|
||||
|
|
|
|||
|
|
@ -30,10 +30,9 @@
|
|||
DEFINE_ABSTRACT_OBJECT(AccountDeviceProxy)
|
||||
DEFINE_GUI_OBJECT(AccountDeviceProxy)
|
||||
|
||||
AccountDeviceProxy::AccountDeviceProxy(QObject *parent) : SortFilterProxy(parent) {
|
||||
AccountDeviceProxy::AccountDeviceProxy(QObject *parent) : LimitProxy(parent) {
|
||||
mAccountDeviceList = AccountDeviceList::create();
|
||||
setSourceModel(mAccountDeviceList.get());
|
||||
sort(0); //, Qt::DescendingOrder);
|
||||
setSourceModels(new SortFilterList(mAccountDeviceList.get(), Qt::DescendingOrder));
|
||||
}
|
||||
|
||||
AccountDeviceProxy::~AccountDeviceProxy() {
|
||||
|
|
@ -53,13 +52,10 @@ void AccountDeviceProxy::deleteDevice(AccountDeviceGui *device) {
|
|||
mAccountDeviceList->deleteDevice(device);
|
||||
}
|
||||
|
||||
bool AccountDeviceProxy::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const {
|
||||
bool AccountDeviceProxy::SortFilterList::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AccountDeviceProxy::lessThan(const QModelIndex &left, const QModelIndex &right) const {
|
||||
auto deviceA = sourceModel()->data(left).value<AccountDeviceGui *>()->getCore();
|
||||
auto deviceB = sourceModel()->data(right).value<AccountDeviceGui *>()->getCore();
|
||||
|
||||
return left.row() < right.row();
|
||||
bool AccountDeviceProxy::SortFilterList::lessThan(const QModelIndex &sourceLeft, const QModelIndex &sourceRight) const {
|
||||
return sourceLeft.row() < sourceRight.row();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,21 +21,22 @@
|
|||
#ifndef ACCOUNT_DEVICE_PROXY_MODEL_H_
|
||||
#define ACCOUNT_DEVICE_PROXY_MODEL_H_
|
||||
|
||||
#include "../proxy/SortFilterProxy.hpp"
|
||||
#include "../proxy/LimitProxy.hpp"
|
||||
#include "core/account/AccountDeviceGui.hpp"
|
||||
#include "core/account/AccountGui.hpp"
|
||||
#include "core/call/CallGui.hpp"
|
||||
#include "tool/AbstractObject.hpp"
|
||||
|
||||
class AccountDeviceList;
|
||||
class AccountDeviceGui;
|
||||
|
||||
class AccountDeviceProxy : public SortFilterProxy, public AbstractObject {
|
||||
class AccountDeviceProxy : public LimitProxy, public AbstractObject {
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(AccountGui *account READ getAccount WRITE setAccount NOTIFY accountChanged)
|
||||
|
||||
public:
|
||||
DECLARE_GUI_OBJECT
|
||||
DECLARE_SORTFILTER_CLASS()
|
||||
|
||||
AccountDeviceProxy(QObject *parent = Q_NULLPTR);
|
||||
~AccountDeviceProxy();
|
||||
|
||||
|
|
@ -44,9 +45,6 @@ public:
|
|||
Q_INVOKABLE void deleteDevice(AccountDeviceGui *device);
|
||||
|
||||
protected:
|
||||
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override;
|
||||
bool lessThan(const QModelIndex &left, const QModelIndex &right) const override;
|
||||
|
||||
signals:
|
||||
void lUpdate();
|
||||
void accountChanged();
|
||||
|
|
|
|||
|
|
@ -23,29 +23,18 @@
|
|||
#include "AccountList.hpp"
|
||||
#include "core/App.hpp"
|
||||
|
||||
AccountProxy::AccountProxy(QObject *parent) : SortFilterProxy(parent) {
|
||||
setSourceModel(App::getInstance()->getAccountList().get());
|
||||
sort(0);
|
||||
AccountProxy::AccountProxy(QObject *parent) : LimitProxy(parent) {
|
||||
setSourceModels(new SortFilterList(App::getInstance()->getAccountList().get(), Qt::AscendingOrder));
|
||||
}
|
||||
|
||||
AccountProxy::~AccountProxy() {
|
||||
setSourceModel(nullptr);
|
||||
}
|
||||
|
||||
QString AccountProxy::getFilterText() const {
|
||||
return mFilterText;
|
||||
}
|
||||
|
||||
void AccountProxy::setFilterText(const QString &filter) {
|
||||
if (mFilterText != filter) {
|
||||
mFilterText = filter;
|
||||
invalidate();
|
||||
emit filterTextChanged();
|
||||
}
|
||||
}
|
||||
|
||||
AccountGui *AccountProxy::getDefaultAccount() {
|
||||
if (!mDefaultAccount) mDefaultAccount = dynamic_cast<AccountList *>(sourceModel())->getDefaultAccountCore();
|
||||
if (!mDefaultAccount)
|
||||
mDefaultAccount = dynamic_cast<AccountList *>(dynamic_cast<SortFilterList *>(sourceModel())->sourceModel())
|
||||
->getDefaultAccountCore();
|
||||
return new AccountGui(mDefaultAccount);
|
||||
}
|
||||
|
||||
|
|
@ -59,19 +48,19 @@ void AccountProxy::resetDefaultAccount() {
|
|||
}
|
||||
|
||||
AccountGui *AccountProxy::findAccountByAddress(const QString &address) {
|
||||
return dynamic_cast<AccountList *>(sourceModel())->findAccountByAddress(address);
|
||||
return getListModel<AccountList>()->findAccountByAddress(address);
|
||||
}
|
||||
|
||||
AccountGui *AccountProxy::firstAccount() {
|
||||
return dynamic_cast<AccountList *>(sourceModel())->firstAccount();
|
||||
return getListModel<AccountList>()->firstAccount();
|
||||
}
|
||||
|
||||
bool AccountProxy::getHaveAccount() const {
|
||||
return dynamic_cast<AccountList *>(sourceModel())->getHaveAccount();
|
||||
return getListModel<AccountList>()->getHaveAccount();
|
||||
}
|
||||
|
||||
void AccountProxy::setSourceModel(QAbstractItemModel *model) {
|
||||
auto oldAccountList = dynamic_cast<AccountList *>(sourceModel());
|
||||
auto oldAccountList = getListModel<AccountList>();
|
||||
if (oldAccountList) {
|
||||
disconnect(oldAccountList);
|
||||
}
|
||||
|
|
@ -87,25 +76,24 @@ void AccountProxy::setSourceModel(QAbstractItemModel *model) {
|
|||
QSortFilterProxyModel::setSourceModel(model);
|
||||
}
|
||||
|
||||
bool AccountProxy::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const {
|
||||
//------------------------------------------------------------------------------------------
|
||||
|
||||
bool AccountProxy::SortFilterList::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const {
|
||||
bool show = (mFilterText.isEmpty() || mFilterText == "*");
|
||||
if (!show) {
|
||||
QRegularExpression search(QRegularExpression::escape(mFilterText),
|
||||
QRegularExpression::CaseInsensitiveOption |
|
||||
QRegularExpression::UseUnicodePropertiesOption);
|
||||
QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent);
|
||||
auto model = sourceModel()->data(index);
|
||||
auto account = model.value<AccountGui *>();
|
||||
show = account->getCore()->getIdentityAddress().contains(search);
|
||||
auto account = getItemAtSource<AccountList, AccountCore>(sourceRow);
|
||||
show = account->getIdentityAddress().contains(search);
|
||||
}
|
||||
|
||||
return show;
|
||||
}
|
||||
|
||||
bool AccountProxy::lessThan(const QModelIndex &left, const QModelIndex &right) const {
|
||||
auto l = sourceModel()->data(left);
|
||||
auto r = sourceModel()->data(right);
|
||||
bool AccountProxy::SortFilterList::lessThan(const QModelIndex &sourceLeft, const QModelIndex &sourceRight) const {
|
||||
auto l = getItemAtSource<AccountList, AccountCore>(sourceLeft.row());
|
||||
auto r = getItemAtSource<AccountList, AccountCore>(sourceRight.row());
|
||||
|
||||
return l.value<AccountGui *>()->getCore()->getIdentityAddress() <
|
||||
r.value<AccountGui *>()->getCore()->getIdentityAddress();
|
||||
return l->getIdentityAddress() < r->getIdentityAddress();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,26 +21,25 @@
|
|||
#ifndef ACCOUNT_PROXY_H_
|
||||
#define ACCOUNT_PROXY_H_
|
||||
|
||||
#include "../proxy/LimitProxy.hpp"
|
||||
#include "../proxy/SortFilterProxy.hpp"
|
||||
#include "core/account/AccountGui.hpp"
|
||||
#include "core/account/AccountList.hpp"
|
||||
|
||||
// =============================================================================
|
||||
|
||||
class AccountProxy : public SortFilterProxy {
|
||||
class AccountProxy : public LimitProxy {
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(QString filterText READ getFilterText WRITE setFilterText NOTIFY filterTextChanged)
|
||||
Q_PROPERTY(AccountGui *defaultAccount READ getDefaultAccount WRITE setDefaultAccount NOTIFY defaultAccountChanged)
|
||||
Q_PROPERTY(bool haveAccount READ getHaveAccount NOTIFY haveAccountChanged)
|
||||
|
||||
public:
|
||||
DECLARE_SORTFILTER_CLASS()
|
||||
|
||||
AccountProxy(QObject *parent = Q_NULLPTR);
|
||||
~AccountProxy();
|
||||
|
||||
QString getFilterText() const;
|
||||
void setFilterText(const QString &filter);
|
||||
|
||||
AccountGui *getDefaultAccount(); // Get a new object from List or give the stored one.
|
||||
void setDefaultAccount(AccountGui *account); // TODO
|
||||
void resetDefaultAccount(); // Reset the default account to let UI build its new object if needed.
|
||||
|
|
@ -52,16 +51,11 @@ public:
|
|||
void setSourceModel(QAbstractItemModel *sourceModel) override;
|
||||
|
||||
signals:
|
||||
void filterTextChanged();
|
||||
void defaultAccountChanged();
|
||||
void haveAccountChanged();
|
||||
void initialized();
|
||||
|
||||
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<AccountCore> mDefaultAccount; // When null, a new UI object is build from List
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -24,36 +24,24 @@
|
|||
|
||||
DEFINE_ABSTRACT_OBJECT(CarddavProxy)
|
||||
|
||||
CarddavProxy::CarddavProxy(QObject *parent) : SortFilterProxy(parent) {
|
||||
CarddavProxy::CarddavProxy(QObject *parent) : LimitProxy(parent) {
|
||||
mCarddavList = CarddavList::create();
|
||||
setSourceModel(mCarddavList.get());
|
||||
setSourceModels(new SortFilterList(mCarddavList.get(), Qt::AscendingOrder));
|
||||
}
|
||||
|
||||
CarddavProxy::~CarddavProxy() {
|
||||
setSourceModel(nullptr);
|
||||
}
|
||||
|
||||
QString CarddavProxy::getFilterText() const {
|
||||
return mFilterText;
|
||||
}
|
||||
|
||||
void CarddavProxy::setFilterText(const QString &filter) {
|
||||
if (mFilterText != filter) {
|
||||
mFilterText = filter;
|
||||
invalidate();
|
||||
emit filterTextChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void CarddavProxy::removeAllEntries() {
|
||||
static_cast<CarddavList *>(sourceModel())->removeAllEntries();
|
||||
}
|
||||
|
||||
void CarddavProxy::removeEntriesWithFilter() {
|
||||
std::list<QSharedPointer<CarddavCore>> itemList(rowCount());
|
||||
QList<QSharedPointer<CarddavCore>> itemList(rowCount());
|
||||
for (auto i = rowCount() - 1; i >= 0; --i) {
|
||||
auto item = getItemAt<CarddavList, CarddavCore>(i);
|
||||
itemList.emplace_back(item);
|
||||
auto item = getItemAt<SortFilterList, CarddavList, CarddavCore>(i);
|
||||
itemList[i] = item;
|
||||
}
|
||||
for (auto item : itemList) {
|
||||
mCarddavList->ListProxy::remove(item.get());
|
||||
|
|
@ -61,13 +49,13 @@ void CarddavProxy::removeEntriesWithFilter() {
|
|||
}
|
||||
}
|
||||
|
||||
bool CarddavProxy::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const {
|
||||
bool CarddavProxy::SortFilterList::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CarddavProxy::lessThan(const QModelIndex &left, const QModelIndex &right) const {
|
||||
auto l = getItemAt<CarddavList, CarddavCore>(left.row());
|
||||
auto r = getItemAt<CarddavList, CarddavCore>(right.row());
|
||||
bool CarddavProxy::SortFilterList::lessThan(const QModelIndex &sourceLeft, const QModelIndex &sourceRight) const {
|
||||
auto l = getItemAtSource<CarddavList, CarddavCore>(sourceLeft.row());
|
||||
auto r = getItemAtSource<CarddavList, CarddavCore>(sourceRight.row());
|
||||
|
||||
return l->mDisplayName < r->mDisplayName;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,37 +21,27 @@
|
|||
#ifndef CARDDAV_PROXY_H_
|
||||
#define CARDDAV_PROXY_H_
|
||||
|
||||
#include "../../proxy/SortFilterProxy.hpp"
|
||||
#include "../../proxy/LimitProxy.hpp"
|
||||
#include "CarddavGui.hpp"
|
||||
#include "CarddavList.hpp"
|
||||
#include "tool/AbstractObject.hpp"
|
||||
|
||||
// =============================================================================
|
||||
|
||||
class CarddavProxy : public SortFilterProxy, public AbstractObject {
|
||||
class CarddavProxy : public LimitProxy, public AbstractObject {
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(QString filterText READ getFilterText WRITE setFilterText NOTIFY filterTextChanged)
|
||||
|
||||
public:
|
||||
DECLARE_SORTFILTER_CLASS()
|
||||
|
||||
CarddavProxy(QObject *parent = Q_NULLPTR);
|
||||
~CarddavProxy();
|
||||
|
||||
QString getFilterText() const;
|
||||
void setFilterText(const QString &filter);
|
||||
|
||||
Q_INVOKABLE void removeAllEntries();
|
||||
Q_INVOKABLE void removeEntriesWithFilter();
|
||||
Q_INVOKABLE void updateView();
|
||||
|
||||
signals:
|
||||
void filterTextChanged();
|
||||
|
||||
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<CarddavList> mCarddavList;
|
||||
|
||||
DECLARE_ABSTRACT_OBJECT
|
||||
|
|
|
|||
|
|
@ -19,55 +19,42 @@
|
|||
*/
|
||||
|
||||
#include "LdapProxy.hpp"
|
||||
#include "LdapGui.hpp"
|
||||
#include "LdapCore.hpp"
|
||||
#include "LdapList.hpp"
|
||||
|
||||
DEFINE_ABSTRACT_OBJECT(LdapProxy)
|
||||
|
||||
LdapProxy::LdapProxy(QObject *parent) : SortFilterProxy(parent) {
|
||||
LdapProxy::LdapProxy(QObject *parent) : LimitProxy(parent) {
|
||||
mLdapList = LdapList::create();
|
||||
setSourceModel(mLdapList.get());
|
||||
setSourceModels(new SortFilterList(mLdapList.get(), Qt::AscendingOrder));
|
||||
}
|
||||
|
||||
LdapProxy::~LdapProxy() {
|
||||
setSourceModel(nullptr);
|
||||
}
|
||||
|
||||
QString LdapProxy::getFilterText() const {
|
||||
return mFilterText;
|
||||
}
|
||||
|
||||
void LdapProxy::setFilterText(const QString &filter) {
|
||||
if (mFilterText != filter) {
|
||||
mFilterText = filter;
|
||||
invalidate();
|
||||
emit filterTextChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void LdapProxy::removeAllEntries() {
|
||||
static_cast<LdapList *>(sourceModel())->removeAllEntries();
|
||||
getListModel<LdapList>()->removeAllEntries();
|
||||
}
|
||||
|
||||
void LdapProxy::removeEntriesWithFilter() {
|
||||
std::list<QSharedPointer<LdapCore>> itemList(rowCount());
|
||||
QList<QSharedPointer<LdapCore>> itemList(rowCount());
|
||||
for (auto i = rowCount() - 1; i >= 0; --i) {
|
||||
auto item = getItemAt<LdapList, LdapCore>(i);
|
||||
itemList.emplace_back(item);
|
||||
auto item = getItemAt<SortFilterList, LdapList, LdapCore>(i);
|
||||
itemList[i] = item;
|
||||
}
|
||||
for (auto item : itemList) {
|
||||
mLdapList->ListProxy::remove(item.get());
|
||||
if (item) item->remove();
|
||||
}
|
||||
}
|
||||
|
||||
bool LdapProxy::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const {
|
||||
bool LdapProxy::SortFilterList::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LdapProxy::lessThan(const QModelIndex &left, const QModelIndex &right) const {
|
||||
auto l = getItemAt<LdapList, LdapCore>(left.row());
|
||||
auto r = getItemAt<LdapList, LdapCore>(right.row());
|
||||
bool LdapProxy::SortFilterList::lessThan(const QModelIndex &sourceLeft, const QModelIndex &sourceRight) const {
|
||||
auto l = getItemAtSource<LdapList, LdapCore>(sourceLeft.row());
|
||||
auto r = getItemAtSource<LdapList, LdapCore>(sourceRight.row());
|
||||
|
||||
return l->mSipDomain < r->mSipDomain;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,25 +21,21 @@
|
|||
#ifndef LDAP_PROXY_H_
|
||||
#define LDAP_PROXY_H_
|
||||
|
||||
#include "../../proxy/SortFilterProxy.hpp"
|
||||
#include "LdapGui.hpp"
|
||||
#include "../../proxy/LimitProxy.hpp"
|
||||
#include "LdapList.hpp"
|
||||
#include "tool/AbstractObject.hpp"
|
||||
|
||||
// =============================================================================
|
||||
|
||||
class LdapProxy : public SortFilterProxy, public AbstractObject {
|
||||
class LdapProxy : public LimitProxy, public AbstractObject {
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(QString filterText READ getFilterText WRITE setFilterText NOTIFY filterTextChanged)
|
||||
|
||||
public:
|
||||
DECLARE_SORTFILTER_CLASS()
|
||||
|
||||
LdapProxy(QObject *parent = Q_NULLPTR);
|
||||
~LdapProxy();
|
||||
|
||||
QString getFilterText() const;
|
||||
void setFilterText(const QString &filter);
|
||||
|
||||
Q_INVOKABLE void removeAllEntries();
|
||||
Q_INVOKABLE void removeEntriesWithFilter();
|
||||
Q_INVOKABLE void updateView();
|
||||
|
|
@ -48,10 +44,6 @@ signals:
|
|||
void filterTextChanged();
|
||||
|
||||
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<LdapList> mLdapList;
|
||||
|
||||
DECLARE_ABSTRACT_OBJECT
|
||||
|
|
|
|||
|
|
@ -73,6 +73,18 @@ void CallHistoryList::setSelf(QSharedPointer<CallHistoryList> me) {
|
|||
mustBeInMainThread(getClassName());
|
||||
resetData();
|
||||
add(*callLogs);
|
||||
|
||||
/*
|
||||
if (callLogs->size() > 0) {
|
||||
int count = qMin(callLogs->size(), mMaxDisplayItems);
|
||||
// QModelIndex firstIndex = index(0, 0);
|
||||
beginInsertRows(QModelIndex(), 0, count - 1);
|
||||
for (auto i : *callLogs)
|
||||
mList << i.template objectCast<QObject>();
|
||||
endInsertRows();
|
||||
// auto lastIndex = index(count - 1, 0);
|
||||
// emit dataChanged(firstIndex, lastIndex);
|
||||
}*/
|
||||
delete callLogs;
|
||||
});
|
||||
});
|
||||
|
|
@ -109,3 +121,14 @@ QVariant CallHistoryList::data(const QModelIndex &index, int role) const {
|
|||
}
|
||||
return QVariant();
|
||||
}
|
||||
/*
|
||||
void CallHistoryList::displayMore() {
|
||||
int oldCount = qMin(mList.size(), mDisplayCount);
|
||||
int newCount = qMin(mList.size(), mDisplayCount + mDisplayStep);
|
||||
if (newCount != oldCount) {
|
||||
mDisplayCount = newCount;
|
||||
beginInsertRows(QModelIndex(), oldCount, mDisplayCount - 1);
|
||||
endInsertRows();
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@ public:
|
|||
// roles[Qt::DisplayRole + 2] = "date";
|
||||
// return roles;
|
||||
// }
|
||||
//void displayMore();
|
||||
|
||||
signals:
|
||||
void lUpdate();
|
||||
|
|
|
|||
|
|
@ -24,41 +24,26 @@
|
|||
|
||||
DEFINE_ABSTRACT_OBJECT(CallHistoryProxy)
|
||||
|
||||
CallHistoryProxy::CallHistoryProxy(QObject *parent) : SortFilterProxy(parent) {
|
||||
CallHistoryProxy::CallHistoryProxy(QObject *parent) : LimitProxy(parent) {
|
||||
mHistoryList = CallHistoryList::create();
|
||||
setSourceModel(mHistoryList.get());
|
||||
// sort(0);
|
||||
setSourceModels(new SortFilterList(mHistoryList.get(), Qt::DescendingOrder));
|
||||
}
|
||||
|
||||
CallHistoryProxy::~CallHistoryProxy() {
|
||||
setSourceModel(nullptr);
|
||||
}
|
||||
|
||||
QString CallHistoryProxy::getFilterText() const {
|
||||
return mFilterText;
|
||||
}
|
||||
|
||||
void CallHistoryProxy::setFilterText(const QString &filter) {
|
||||
if (mFilterText != filter) {
|
||||
mFilterText = filter;
|
||||
invalidate();
|
||||
emit filterTextChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void CallHistoryProxy::removeAllEntries() {
|
||||
static_cast<CallHistoryList *>(sourceModel())->removeAllEntries();
|
||||
mHistoryList->removeAllEntries();
|
||||
}
|
||||
|
||||
void CallHistoryProxy::removeEntriesWithFilter() {
|
||||
std::list<QSharedPointer<CallHistoryCore>> itemList(rowCount());
|
||||
QList<QSharedPointer<CallHistoryCore>> itemList(rowCount());
|
||||
for (auto i = rowCount() - 1; i >= 0; --i) {
|
||||
auto item = getItemAt<CallHistoryList, CallHistoryCore>(i);
|
||||
itemList.emplace_back(item);
|
||||
auto item = getItemAt<SortFilterList, CallHistoryList, CallHistoryCore>(i);
|
||||
itemList[i] = item;
|
||||
}
|
||||
for (auto item : itemList) {
|
||||
mHistoryList->ListProxy::remove(item.get());
|
||||
if (item) item->remove();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -66,8 +51,12 @@ void CallHistoryProxy::updateView() {
|
|||
mHistoryList->lUpdate();
|
||||
}
|
||||
|
||||
bool CallHistoryProxy::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const {
|
||||
//------------------------------------------------------------------------------------------
|
||||
|
||||
bool CallHistoryProxy::SortFilterList::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const {
|
||||
bool show = (mFilterText.isEmpty() || mFilterText == "*");
|
||||
auto sortProxy = dynamic_cast<SortFilterList *>(sourceModel());
|
||||
|
||||
if (!show) {
|
||||
QRegularExpression search(QRegularExpression::escape(mFilterText),
|
||||
QRegularExpression::CaseInsensitiveOption |
|
||||
|
|
@ -76,13 +65,12 @@ bool CallHistoryProxy::filterAcceptsRow(int sourceRow, const QModelIndex &source
|
|||
show =
|
||||
callLog->mIsConference ? callLog->mDisplayName.contains(search) : callLog->mRemoteAddress.contains(search);
|
||||
}
|
||||
|
||||
return show;
|
||||
}
|
||||
|
||||
bool CallHistoryProxy::lessThan(const QModelIndex &left, const QModelIndex &right) const {
|
||||
auto l = getItemAt<CallHistoryList, CallHistoryCore>(left.row());
|
||||
auto r = getItemAt<CallHistoryList, CallHistoryCore>(right.row());
|
||||
bool CallHistoryProxy::SortFilterList::lessThan(const QModelIndex &sourceLeft, const QModelIndex &sourceRight) const {
|
||||
auto l = getItemAtSource<CallHistoryList, CallHistoryCore>(sourceLeft.row());
|
||||
auto r = getItemAtSource<CallHistoryList, CallHistoryCore>(sourceRight.row());
|
||||
|
||||
return l->mDate < r->mDate;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,37 +21,27 @@
|
|||
#ifndef CALL_HISTORY_PROXY_H_
|
||||
#define CALL_HISTORY_PROXY_H_
|
||||
|
||||
#include "../proxy/LimitProxy.hpp"
|
||||
#include "../proxy/SortFilterProxy.hpp"
|
||||
#include "CallHistoryGui.hpp"
|
||||
#include "CallHistoryList.hpp"
|
||||
#include "tool/AbstractObject.hpp"
|
||||
#include <QSortFilterProxyModel>
|
||||
|
||||
// =============================================================================
|
||||
|
||||
class CallHistoryProxy : public SortFilterProxy, public AbstractObject {
|
||||
class CallHistoryProxy : public LimitProxy, public AbstractObject {
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(QString filterText READ getFilterText WRITE setFilterText NOTIFY filterTextChanged)
|
||||
|
||||
public:
|
||||
DECLARE_SORTFILTER_CLASS()
|
||||
|
||||
CallHistoryProxy(QObject *parent = Q_NULLPTR);
|
||||
~CallHistoryProxy();
|
||||
|
||||
QString getFilterText() const;
|
||||
void setFilterText(const QString &filter);
|
||||
|
||||
Q_INVOKABLE void removeAllEntries();
|
||||
Q_INVOKABLE void removeEntriesWithFilter();
|
||||
Q_INVOKABLE void updateView();
|
||||
|
||||
signals:
|
||||
void filterTextChanged();
|
||||
|
||||
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<CallHistoryList> mHistoryList;
|
||||
|
||||
DECLARE_ABSTRACT_OBJECT
|
||||
|
|
|
|||
|
|
@ -25,34 +25,21 @@
|
|||
|
||||
DEFINE_ABSTRACT_OBJECT(CallProxy)
|
||||
|
||||
CallProxy::CallProxy(QObject *parent) : SortFilterProxy(parent) {
|
||||
CallProxy::CallProxy(QObject *parent) : LimitProxy(parent) {
|
||||
setSourceModel(App::getInstance()->getCallList().get());
|
||||
sort(0);
|
||||
}
|
||||
|
||||
CallProxy::~CallProxy() {
|
||||
setSourceModel(nullptr);
|
||||
}
|
||||
|
||||
QString CallProxy::getFilterText() const {
|
||||
return mFilterText;
|
||||
}
|
||||
|
||||
void CallProxy::setFilterText(const QString &filter) {
|
||||
if (mFilterText != filter) {
|
||||
mFilterText = filter;
|
||||
invalidate();
|
||||
emit filterTextChanged();
|
||||
}
|
||||
}
|
||||
|
||||
CallGui *CallProxy::getCurrentCall() {
|
||||
if (!mCurrentCall) mCurrentCall = dynamic_cast<CallList *>(sourceModel())->getCurrentCall();
|
||||
auto model = getListModel<CallList>();
|
||||
if (!mCurrentCall && model) mCurrentCall = model->getCurrentCall();
|
||||
return mCurrentCall;
|
||||
}
|
||||
|
||||
void CallProxy::setCurrentCall(CallGui *call) {
|
||||
dynamic_cast<CallList *>(sourceModel())->setCurrentCall(call->mCore);
|
||||
getListModel<CallList>()->setCurrentCall(call->mCore);
|
||||
}
|
||||
|
||||
// Reset the default account to let UI build its new object if needed.
|
||||
|
|
@ -62,11 +49,11 @@ void CallProxy::resetCurrentCall() {
|
|||
}
|
||||
|
||||
bool CallProxy::getHaveCall() const {
|
||||
return dynamic_cast<CallList *>(sourceModel())->getHaveCall();
|
||||
return getListModel<CallList>()->getHaveCall();
|
||||
}
|
||||
|
||||
void CallProxy::setSourceModel(QAbstractItemModel *model) {
|
||||
auto oldCallList = dynamic_cast<CallList *>(sourceModel());
|
||||
auto oldCallList = getListModel<CallList>();
|
||||
if (oldCallList) {
|
||||
disconnect(oldCallList);
|
||||
}
|
||||
|
|
@ -76,27 +63,26 @@ void CallProxy::setSourceModel(QAbstractItemModel *model) {
|
|||
connect(newCallList, &CallList::haveCallChanged, this, &CallProxy::haveCallChanged, Qt::QueuedConnection);
|
||||
connect(this, &CallProxy::lMergeAll, newCallList, &CallList::lMergeAll);
|
||||
}
|
||||
QSortFilterProxyModel::setSourceModel(model);
|
||||
setSourceModels(new SortFilterList(model, Qt::AscendingOrder));
|
||||
}
|
||||
|
||||
bool CallProxy::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const {
|
||||
bool CallProxy::SortFilterList::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const {
|
||||
bool show = (mFilterText.isEmpty() || mFilterText == "*");
|
||||
if (!show) {
|
||||
QRegularExpression search(QRegularExpression::escape(mFilterText),
|
||||
QRegularExpression::CaseInsensitiveOption |
|
||||
QRegularExpression::UseUnicodePropertiesOption);
|
||||
QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent);
|
||||
auto model = sourceModel()->data(index);
|
||||
auto call = model.value<CallGui *>();
|
||||
show = call->getCore()->getPeerAddress().contains(search);
|
||||
auto call = qobject_cast<CallList *>(sourceModel())->getAt<CallCore>(sourceRow);
|
||||
|
||||
show = call->getPeerAddress().contains(search);
|
||||
}
|
||||
|
||||
return show;
|
||||
}
|
||||
|
||||
bool CallProxy::lessThan(const QModelIndex &left, const QModelIndex &right) const {
|
||||
auto l = sourceModel()->data(left);
|
||||
auto r = sourceModel()->data(right);
|
||||
bool CallProxy::SortFilterList::lessThan(const QModelIndex &sourceLeft, const QModelIndex &sourceRight) const {
|
||||
auto l = getItemAtSource<CallList, CallCore>(sourceLeft.row());
|
||||
auto r = getItemAtSource<CallList, CallCore>(sourceRight.row());
|
||||
|
||||
return l.value<CallGui *>()->getCore()->getPeerAddress() < r.value<CallGui *>()->getCore()->getPeerAddress();
|
||||
return l->getPeerAddress() < r->getPeerAddress();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,26 +21,24 @@
|
|||
#ifndef CALL_PROXY_H_
|
||||
#define CALL_PROXY_H_
|
||||
|
||||
#include "../proxy/SortFilterProxy.hpp"
|
||||
#include "../proxy/LimitProxy.hpp"
|
||||
#include "core/call/CallGui.hpp"
|
||||
#include "core/call/CallList.hpp"
|
||||
#include "tool/AbstractObject.hpp"
|
||||
|
||||
// =============================================================================
|
||||
|
||||
class CallProxy : public SortFilterProxy, public AbstractObject {
|
||||
class CallProxy : public LimitProxy, public AbstractObject {
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(QString filterText READ getFilterText WRITE setFilterText NOTIFY filterTextChanged)
|
||||
Q_PROPERTY(CallGui *currentCall READ getCurrentCall WRITE setCurrentCall NOTIFY currentCallChanged)
|
||||
Q_PROPERTY(bool haveCall READ getHaveCall NOTIFY haveCallChanged)
|
||||
|
||||
public:
|
||||
DECLARE_SORTFILTER_CLASS()
|
||||
|
||||
CallProxy(QObject *parent = Q_NULLPTR);
|
||||
~CallProxy();
|
||||
|
||||
QString getFilterText() const;
|
||||
void setFilterText(const QString &filter);
|
||||
// Get a new object from List or give the stored one.
|
||||
CallGui *getCurrentCall();
|
||||
// TODO for manual setting. Changing the currentCall is automatically done by call->onStateChanged() on
|
||||
|
|
@ -54,15 +52,10 @@ public:
|
|||
|
||||
signals:
|
||||
void lMergeAll();
|
||||
void filterTextChanged();
|
||||
void currentCallChanged();
|
||||
void haveCallChanged();
|
||||
|
||||
protected:
|
||||
virtual bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override;
|
||||
virtual bool lessThan(const QModelIndex &left, const QModelIndex &right) const override;
|
||||
|
||||
QString mFilterText;
|
||||
CallGui *mCurrentCall = nullptr; // When null, a new UI object is build from List
|
||||
|
||||
DECLARE_ABSTRACT_OBJECT
|
||||
|
|
|
|||
|
|
@ -25,15 +25,11 @@
|
|||
|
||||
DEFINE_ABSTRACT_OBJECT(ConferenceInfoProxy)
|
||||
|
||||
ConferenceInfoProxy::ConferenceInfoProxy(QObject *parent) : SortFilterProxy(parent) {
|
||||
ConferenceInfoProxy::ConferenceInfoProxy(QObject *parent) : LimitProxy(parent) {
|
||||
mList = ConferenceInfoList::create();
|
||||
setSourceModel(mList.get());
|
||||
setSourceModels(new SortFilterList(mList.get()));
|
||||
connect(
|
||||
this, &ConferenceInfoProxy::searchTextChanged, this,
|
||||
[this] {
|
||||
invalidate();
|
||||
updateCurrentDateIndex();
|
||||
},
|
||||
this, &ConferenceInfoProxy::filterTextChanged, this, [this] { updateCurrentDateIndex(); },
|
||||
Qt::QueuedConnection);
|
||||
connect(
|
||||
mList.get(), &ConferenceInfoList::haveCurrentDateChanged, this,
|
||||
|
|
@ -49,16 +45,6 @@ ConferenceInfoProxy::ConferenceInfoProxy(QObject *parent) : SortFilterProxy(pare
|
|||
}
|
||||
|
||||
ConferenceInfoProxy::~ConferenceInfoProxy() {
|
||||
setSourceModel(nullptr);
|
||||
}
|
||||
|
||||
QString ConferenceInfoProxy::getSearchText() const {
|
||||
return mSearchText;
|
||||
}
|
||||
|
||||
void ConferenceInfoProxy::setSearchText(const QString &search) {
|
||||
mSearchText = search;
|
||||
emit searchTextChanged();
|
||||
}
|
||||
|
||||
bool ConferenceInfoProxy::haveCurrentDate() const {
|
||||
|
|
@ -77,15 +63,16 @@ void ConferenceInfoProxy::updateCurrentDateIndex() {
|
|||
}
|
||||
}
|
||||
|
||||
bool ConferenceInfoProxy::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const {
|
||||
auto ciCore = qobject_cast<ConferenceInfoList *>(sourceModel())->template getAt<ConferenceInfoCore>(sourceRow);
|
||||
bool ConferenceInfoProxy::SortFilterList::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const {
|
||||
auto list = qobject_cast<ConferenceInfoList *>(sourceModel());
|
||||
auto ciCore = list->getAt<ConferenceInfoCore>(sourceRow);
|
||||
if (ciCore) {
|
||||
bool searchTextInSubject = false;
|
||||
bool searchTextInParticipant = false;
|
||||
if (ciCore->getSubject().contains(mSearchText, Qt::CaseInsensitive)) searchTextInSubject = true;
|
||||
if (ciCore->getSubject().contains(mFilterText, Qt::CaseInsensitive)) searchTextInSubject = true;
|
||||
for (auto &contact : ciCore->getParticipants()) {
|
||||
auto infos = contact.toMap();
|
||||
if (infos["displayName"].toString().contains(mSearchText, Qt::CaseInsensitive)) {
|
||||
if (infos["displayName"].toString().contains(mFilterText, Qt::CaseInsensitive)) {
|
||||
searchTextInParticipant = true;
|
||||
break;
|
||||
}
|
||||
|
|
@ -99,7 +86,12 @@ bool ConferenceInfoProxy::filterAcceptsRow(int sourceRow, const QModelIndex &sou
|
|||
return res;
|
||||
} else return mFilterType == -1;
|
||||
} else {
|
||||
return !mList->haveCurrentDate() && mList->getCount() > 1 &&
|
||||
mSearchText.isEmpty(); // if mlist count == 1 there is only the dummy row which we don't display alone
|
||||
return !list->haveCurrentDate() && list->getCount() > 1 && mFilterText.isEmpty();
|
||||
// if mlist count == 1 there is only the dummy row which we don't display alone
|
||||
}
|
||||
}
|
||||
|
||||
bool ConferenceInfoProxy::SortFilterList::lessThan(const QModelIndex &sourceLeft,
|
||||
const QModelIndex &sourceRight) const {
|
||||
return true; // Not used
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,15 +21,14 @@
|
|||
#ifndef CONFERENCE_INFO_PROXY_H_
|
||||
#define CONFERENCE_INFO_PROXY_H_
|
||||
|
||||
#include "../proxy/SortFilterProxy.hpp"
|
||||
#include "../proxy/LimitProxy.hpp"
|
||||
#include "tool/AbstractObject.hpp"
|
||||
|
||||
class ConferenceInfoList;
|
||||
|
||||
class ConferenceInfoProxy : public SortFilterProxy, public AbstractObject {
|
||||
class ConferenceInfoProxy : public LimitProxy, public AbstractObject {
|
||||
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QString searchText READ getSearchText WRITE setSearchText NOTIFY searchTextChanged)
|
||||
Q_PROPERTY(bool haveCurrentDate READ haveCurrentDate NOTIFY haveCurrentDateChanged)
|
||||
Q_PROPERTY(int currentDateIndex READ getCurrentDateIndex NOTIFY currentDateIndexChanged)
|
||||
|
||||
|
|
@ -37,32 +36,24 @@ public:
|
|||
enum ConferenceInfoFiltering { None = 0, Future = 1 };
|
||||
Q_ENUM(ConferenceInfoFiltering)
|
||||
public:
|
||||
DECLARE_SORTFILTER_CLASS()
|
||||
|
||||
ConferenceInfoProxy(QObject *parent = Q_NULLPTR);
|
||||
~ConferenceInfoProxy();
|
||||
|
||||
QString getSearchText() const;
|
||||
void setSearchText(const QString &search);
|
||||
|
||||
bool haveCurrentDate() const;
|
||||
|
||||
int getCurrentDateIndex() const;
|
||||
void updateCurrentDateIndex();
|
||||
|
||||
protected:
|
||||
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override;
|
||||
// Do not use the sort feature. We cannot retrieve indexes with mapToSource because Qt return -1 for items that are
|
||||
// not displayed. We need it to know where The workaround is to implement ourself the sort into the List.
|
||||
// bool lessThan(const QModelIndex &left, const QModelIndex &right) const override;
|
||||
|
||||
signals:
|
||||
void searchTextChanged();
|
||||
void haveCurrentDateChanged();
|
||||
void currentDateIndexChanged();
|
||||
|
||||
private:
|
||||
QString mSearchText;
|
||||
QSharedPointer<ConferenceInfoList> mList;
|
||||
int mCurrentDateIndex = -1;
|
||||
|
||||
DECLARE_ABSTRACT_OBJECT
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ void FPSCounter::recalculateFPS() {
|
|||
|
||||
int currentCount = _times.length();
|
||||
_currentFPS = (currentCount + _cacheCount) / 2;
|
||||
lDebug() << _currentFPS;
|
||||
// lDebug() << _currentFPS;
|
||||
|
||||
if (currentCount != _cacheCount) fpsChanged(_currentFPS);
|
||||
|
||||
|
|
@ -58,11 +58,13 @@ int FPSCounter::fps() const {
|
|||
void FPSCounter::paint(QPainter *painter) {
|
||||
recalculateFPS();
|
||||
// lDebug()<< __FUNCTION__;
|
||||
/*
|
||||
QBrush brush(Qt::yellow);
|
||||
|
||||
painter->setBrush(brush);
|
||||
painter->setPen(Qt::NoPen);
|
||||
painter->setRenderHint(QPainter::Antialiasing);
|
||||
painter->drawRoundedRect(0, 0, boundingRect().width(), boundingRect().height(), 0, 0);
|
||||
*/
|
||||
update();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,67 +0,0 @@
|
|||
/*
|
||||
* 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"
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
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 friendCore = friendData->getCore();
|
||||
show = friendCore->getGivenName().indexOf(search) == 0 || friendCore->getFamilyName().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));
|
||||
}
|
||||
|
|
@ -1,59 +0,0 @@
|
|||
/*
|
||||
* 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)
|
||||
|
||||
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;
|
||||
|
||||
QString mFilterText;
|
||||
DECLARE_ABSTRACT_OBJECT
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -30,17 +30,15 @@
|
|||
DEFINE_ABSTRACT_OBJECT(ParticipantDeviceProxy)
|
||||
DEFINE_GUI_OBJECT(ParticipantDeviceProxy)
|
||||
|
||||
ParticipantDeviceProxy::ParticipantDeviceProxy(QObject *parent) : SortFilterProxy(parent) {
|
||||
ParticipantDeviceProxy::ParticipantDeviceProxy(QObject *parent) : LimitProxy(parent) {
|
||||
mParticipants = ParticipantDeviceList::create();
|
||||
connect(mParticipants.get(), &ParticipantDeviceList::countChanged, this, &ParticipantDeviceProxy::meChanged,
|
||||
Qt::QueuedConnection);
|
||||
|
||||
setSourceModel(mParticipants.get());
|
||||
sort(0); //, Qt::DescendingOrder);
|
||||
setSourceModels(new SortFilterList(mParticipants.get(), Qt::AscendingOrder));
|
||||
}
|
||||
|
||||
ParticipantDeviceProxy::~ParticipantDeviceProxy() {
|
||||
setSourceModel(nullptr);
|
||||
}
|
||||
|
||||
CallGui *ParticipantDeviceProxy::getCurrentCall() const {
|
||||
|
|
@ -86,13 +84,14 @@ ParticipantDeviceGui *ParticipantDeviceProxy::getMe() const {
|
|||
}
|
||||
}
|
||||
|
||||
bool ParticipantDeviceProxy::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const {
|
||||
bool ParticipantDeviceProxy::SortFilterList::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ParticipantDeviceProxy::lessThan(const QModelIndex &left, const QModelIndex &right) const {
|
||||
auto deviceA = sourceModel()->data(left).value<ParticipantDeviceGui *>()->getCore();
|
||||
auto deviceB = sourceModel()->data(right).value<ParticipantDeviceGui *>()->getCore();
|
||||
bool ParticipantDeviceProxy::SortFilterList::lessThan(const QModelIndex &sourceLeft,
|
||||
const QModelIndex &sourceRight) const {
|
||||
auto l = getItemAtSource<ParticipantDeviceList, ParticipantDeviceCore>(sourceLeft.row());
|
||||
auto r = getItemAtSource<ParticipantDeviceList, ParticipantDeviceCore>(sourceRight.row());
|
||||
|
||||
return deviceB->isMe() || (!deviceB->isMe() && left.row() < right.row());
|
||||
return r->isMe() || (!r->isMe() && sourceLeft.row() < sourceRight.row());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@
|
|||
#ifndef PARTICIPANT_DEVICE_PROXY_MODEL_H_
|
||||
#define PARTICIPANT_DEVICE_PROXY_MODEL_H_
|
||||
|
||||
#include "../proxy/SortFilterProxy.hpp"
|
||||
#include "../proxy/LimitProxy.hpp"
|
||||
#include "core/call/CallGui.hpp"
|
||||
#include "core/participant/ParticipantDeviceGui.hpp"
|
||||
#include "tool/AbstractObject.hpp"
|
||||
|
|
@ -29,13 +29,15 @@
|
|||
class ParticipantDeviceList;
|
||||
class ParticipantDeviceGui;
|
||||
|
||||
class ParticipantDeviceProxy : public SortFilterProxy, public AbstractObject {
|
||||
class ParticipantDeviceProxy : public LimitProxy, public AbstractObject {
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(CallGui *currentCall READ getCurrentCall WRITE setCurrentCall NOTIFY currentCallChanged)
|
||||
Q_PROPERTY(ParticipantDeviceGui *me READ getMe NOTIFY meChanged)
|
||||
|
||||
public:
|
||||
DECLARE_GUI_OBJECT
|
||||
DECLARE_SORTFILTER_CLASS()
|
||||
|
||||
ParticipantDeviceProxy(QObject *parent = Q_NULLPTR);
|
||||
~ParticipantDeviceProxy();
|
||||
|
||||
|
|
@ -44,17 +46,12 @@ public:
|
|||
|
||||
ParticipantDeviceGui *getMe() const;
|
||||
|
||||
protected:
|
||||
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override;
|
||||
bool lessThan(const QModelIndex &left, const QModelIndex &right) const override;
|
||||
|
||||
signals:
|
||||
void lUpdate();
|
||||
void currentCallChanged();
|
||||
void meChanged();
|
||||
|
||||
private:
|
||||
QString mSearchText;
|
||||
CallGui *mCurrentCall = nullptr;
|
||||
QSharedPointer<ParticipantDeviceList> mParticipants;
|
||||
DECLARE_ABSTRACT_OBJECT
|
||||
|
|
|
|||
|
|
@ -34,15 +34,14 @@
|
|||
|
||||
DEFINE_ABSTRACT_OBJECT(ParticipantProxy)
|
||||
|
||||
ParticipantProxy::ParticipantProxy(QObject *parent) : SortFilterProxy(parent) {
|
||||
ParticipantProxy::ParticipantProxy(QObject *parent) : LimitProxy(parent) {
|
||||
mParticipants = ParticipantList::create();
|
||||
connect(this, &ParticipantProxy::chatRoomModelChanged, this, &ParticipantProxy::countChanged);
|
||||
connect(this, &ParticipantProxy::conferenceModelChanged, this, &ParticipantProxy::countChanged);
|
||||
setSourceModel(mParticipants.get());
|
||||
setSourceModels(new SortFilterList(mParticipants.get(), Qt::AscendingOrder));
|
||||
}
|
||||
|
||||
ParticipantProxy::~ParticipantProxy() {
|
||||
setSourceModel(nullptr);
|
||||
}
|
||||
|
||||
CallGui *ParticipantProxy::getCurrentCall() const {
|
||||
|
|
@ -77,7 +76,7 @@ void ParticipantProxy::setCurrentCall(CallGui *call) {
|
|||
}
|
||||
|
||||
bool ParticipantProxy::getShowMe() const {
|
||||
return mShowMe;
|
||||
return dynamic_cast<SortFilterList *>(sourceModel())->mShowMe;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
@ -107,10 +106,11 @@ bool ParticipantProxy::getShowMe() const {
|
|||
// }
|
||||
|
||||
void ParticipantProxy::setShowMe(const bool &show) {
|
||||
if (mShowMe != show) {
|
||||
mShowMe = show;
|
||||
auto list = dynamic_cast<SortFilterList *>(sourceModel());
|
||||
if (list->mShowMe != show) {
|
||||
list->mShowMe = show;
|
||||
emit showMeChanged();
|
||||
invalidate();
|
||||
invalidateFilter();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -135,16 +135,15 @@ void ParticipantProxy::setParticipantAdminStatus(ParticipantCore *participant, b
|
|||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
bool ParticipantProxy::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const {
|
||||
bool ParticipantProxy::SortFilterList::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const {
|
||||
if (mShowMe) return true;
|
||||
else {
|
||||
const ParticipantCore *a =
|
||||
sourceModel()->data(sourceModel()->index(sourceRow, 0, sourceParent)).value<ParticipantCore *>();
|
||||
return !a->isMe();
|
||||
auto participant = qobject_cast<ParticipantList *>(sourceModel())->getAt<ParticipantCore>(sourceRow);
|
||||
return !participant->isMe();
|
||||
}
|
||||
}
|
||||
|
||||
bool ParticipantProxy::lessThan(const QModelIndex &left, const QModelIndex &right) const {
|
||||
bool ParticipantProxy::SortFilterList::lessThan(const QModelIndex &left, const QModelIndex &right) const {
|
||||
const ParticipantCore *a = sourceModel()->data(left).value<ParticipantCore *>();
|
||||
const ParticipantCore *b = sourceModel()->data(right).value<ParticipantCore *>();
|
||||
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@
|
|||
#ifndef PARTICIPANT_PROXY_H_
|
||||
#define PARTICIPANT_PROXY_H_
|
||||
|
||||
#include "../proxy/SortFilterProxy.hpp"
|
||||
#include "../proxy/LimitProxy.hpp"
|
||||
#include "core/call/CallGui.hpp"
|
||||
#include "tool/AbstractObject.hpp"
|
||||
|
||||
|
|
@ -36,22 +36,21 @@ class ConferenceInfoModel;
|
|||
|
||||
class QWindow;
|
||||
|
||||
class ParticipantProxy : public SortFilterProxy, public AbstractObject {
|
||||
class ParticipantProxy : public LimitProxy, public AbstractObject {
|
||||
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(CallGui *currentCall READ getCurrentCall WRITE setCurrentCall NOTIFY currentCallChanged)
|
||||
Q_PROPERTY(bool showMe READ getShowMe WRITE setShowMe NOTIFY showMeChanged)
|
||||
|
||||
public:
|
||||
DECLARE_SORTFILTER_CLASS(bool mShowMe;)
|
||||
|
||||
ParticipantProxy(QObject *parent = Q_NULLPTR);
|
||||
~ParticipantProxy();
|
||||
|
||||
CallGui *getCurrentCall() const;
|
||||
void setCurrentCall(CallGui *callGui);
|
||||
|
||||
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override;
|
||||
bool lessThan(const QModelIndex &left, const QModelIndex &right) const override;
|
||||
|
||||
bool getShowMe() const;
|
||||
void setShowMe(const bool &show);
|
||||
|
||||
|
|
@ -71,7 +70,6 @@ signals:
|
|||
void currentCallChanged();
|
||||
|
||||
private:
|
||||
bool mShowMe = true;
|
||||
CallGui *mCurrentCall = nullptr;
|
||||
QSharedPointer<ParticipantList> mParticipants;
|
||||
DECLARE_ABSTRACT_OBJECT
|
||||
|
|
|
|||
|
|
@ -24,23 +24,34 @@
|
|||
|
||||
DEFINE_ABSTRACT_OBJECT(PayloadTypeProxy)
|
||||
|
||||
PayloadTypeProxy::PayloadTypeProxy(QObject *parent) : SortFilterProxy(parent) {
|
||||
PayloadTypeProxy::PayloadTypeProxy(QObject *parent) : LimitProxy(parent) {
|
||||
mPayloadTypeList = PayloadTypeList::create();
|
||||
setSourceModel(mPayloadTypeList.get());
|
||||
setSourceModels(new SortFilterList(mPayloadTypeList.get(), Qt::AscendingOrder));
|
||||
}
|
||||
|
||||
PayloadTypeProxy::~PayloadTypeProxy() {
|
||||
setSourceModel(nullptr);
|
||||
}
|
||||
|
||||
bool PayloadTypeProxy::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const {
|
||||
auto data = sourceModel()->data(sourceModel()->index(sourceRow, 0, sourceParent)).value<PayloadTypeGui *>();
|
||||
return data->getCore()->getFamily() == mFamily;
|
||||
PayloadTypeCore::Family PayloadTypeProxy::getFamily() const {
|
||||
return dynamic_cast<SortFilterList *>(sourceModel())->mFamily;
|
||||
}
|
||||
|
||||
bool PayloadTypeProxy::lessThan(const QModelIndex &left, const QModelIndex &right) const {
|
||||
auto l = getItemAt<PayloadTypeList, PayloadTypeCore>(left.row());
|
||||
auto r = getItemAt<PayloadTypeList, PayloadTypeCore>(right.row());
|
||||
void PayloadTypeProxy::setFamily(PayloadTypeCore::Family data) {
|
||||
auto list = dynamic_cast<SortFilterList *>(sourceModel());
|
||||
if (list->mFamily != data) {
|
||||
list->mFamily = data;
|
||||
familyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
bool PayloadTypeProxy::SortFilterList::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const {
|
||||
auto payload = qobject_cast<PayloadTypeList *>(sourceModel())->getAt<PayloadTypeCore>(sourceRow);
|
||||
return payload->getFamily() == mFamily;
|
||||
}
|
||||
|
||||
bool PayloadTypeProxy::SortFilterList::lessThan(const QModelIndex &sourceLeft, const QModelIndex &sourceRight) const {
|
||||
auto l = getItemAtSource<PayloadTypeList, PayloadTypeCore>(sourceLeft.row());
|
||||
auto r = getItemAtSource<PayloadTypeList, PayloadTypeCore>(sourceRight.row());
|
||||
|
||||
return l->getMimeType() < r->getMimeType();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,27 +21,30 @@
|
|||
#ifndef PAYLOAD_TYPE_PROXY_H_
|
||||
#define PAYLOAD_TYPE_PROXY_H_
|
||||
|
||||
#include "../proxy/SortFilterProxy.hpp"
|
||||
#include "PayloadTypeGui.hpp"
|
||||
#include "../proxy/LimitProxy.hpp"
|
||||
#include "PayloadTypeList.hpp"
|
||||
#include "tool/AbstractObject.hpp"
|
||||
|
||||
// =============================================================================
|
||||
|
||||
class PayloadTypeProxy : public SortFilterProxy, public AbstractObject {
|
||||
class PayloadTypeProxy : public LimitProxy, public AbstractObject {
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(PayloadTypeCore::Family family MEMBER mFamily)
|
||||
Q_PROPERTY(PayloadTypeCore::Family family READ getFamily WRITE setFamily NOTIFY familyChanged)
|
||||
|
||||
public:
|
||||
DECLARE_SORTFILTER_CLASS(PayloadTypeCore::Family mFamily;)
|
||||
|
||||
PayloadTypeProxy(QObject *parent = Q_NULLPTR);
|
||||
~PayloadTypeProxy();
|
||||
|
||||
protected:
|
||||
virtual bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override;
|
||||
virtual bool lessThan(const QModelIndex &left, const QModelIndex &right) const override;
|
||||
PayloadTypeCore::Family getFamily() const;
|
||||
void setFamily(PayloadTypeCore::Family data);
|
||||
|
||||
PayloadTypeCore::Family mFamily;
|
||||
signals:
|
||||
void familyChanged();
|
||||
|
||||
protected:
|
||||
QSharedPointer<PayloadTypeList> mPayloadTypeList;
|
||||
|
||||
DECLARE_ABSTRACT_OBJECT
|
||||
|
|
|
|||
|
|
@ -23,30 +23,16 @@
|
|||
|
||||
DEFINE_ABSTRACT_OBJECT(PhoneNumberProxy)
|
||||
|
||||
PhoneNumberProxy::PhoneNumberProxy(QObject *parent) : SortFilterProxy(parent) {
|
||||
PhoneNumberProxy::PhoneNumberProxy(QObject *parent) : LimitProxy(parent) {
|
||||
mPhoneNumberList = PhoneNumberList::create();
|
||||
setSourceModel(mPhoneNumberList.get());
|
||||
sort(0);
|
||||
setSourceModels(new SortFilterList(mPhoneNumberList.get(), Qt::AscendingOrder));
|
||||
}
|
||||
|
||||
PhoneNumberProxy::~PhoneNumberProxy() {
|
||||
setSourceModel(nullptr);
|
||||
}
|
||||
|
||||
QString PhoneNumberProxy::getFilterText() const {
|
||||
return mFilterText;
|
||||
}
|
||||
|
||||
void PhoneNumberProxy::setFilterText(const QString &filter) {
|
||||
if (mFilterText != filter) {
|
||||
mFilterText = filter;
|
||||
invalidate();
|
||||
emit filterTextChanged();
|
||||
}
|
||||
}
|
||||
|
||||
int PhoneNumberProxy::findIndexByCountryCallingCode(const QString &countryCallingCode) {
|
||||
auto model = qobject_cast<PhoneNumberList *>(sourceModel());
|
||||
auto model = getListModel<PhoneNumberList>();
|
||||
if (!model) return -1;
|
||||
if (countryCallingCode.isEmpty()) return -1;
|
||||
|
||||
|
|
@ -58,24 +44,22 @@ int PhoneNumberProxy::findIndexByCountryCallingCode(const QString &countryCallin
|
|||
return proxyModelIndex.row();
|
||||
}
|
||||
|
||||
bool PhoneNumberProxy::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const {
|
||||
bool PhoneNumberProxy::SortFilterList::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const {
|
||||
bool show = (mFilterText.isEmpty() || mFilterText == "*");
|
||||
if (!show) {
|
||||
QRegularExpression search(QRegularExpression::escape(mFilterText),
|
||||
QRegularExpression::CaseInsensitiveOption |
|
||||
QRegularExpression::UseUnicodePropertiesOption);
|
||||
QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent);
|
||||
auto model = sourceModel()->data(index);
|
||||
auto phoneNumber = model.value<PhoneNumber *>();
|
||||
auto phoneNumber = qobject_cast<PhoneNumberList *>(sourceModel())->getAt<PhoneNumber>(sourceRow);
|
||||
|
||||
show = phoneNumber->mCountry.contains(search) || phoneNumber->mCountryCallingCode.contains(search);
|
||||
}
|
||||
|
||||
return show;
|
||||
}
|
||||
|
||||
bool PhoneNumberProxy::lessThan(const QModelIndex &left, const QModelIndex &right) const {
|
||||
auto l = sourceModel()->data(left);
|
||||
auto r = sourceModel()->data(right);
|
||||
|
||||
return l.value<PhoneNumber *>()->mCountry < r.value<PhoneNumber *>()->mCountry;
|
||||
bool PhoneNumberProxy::SortFilterList::lessThan(const QModelIndex &sourceLeft, const QModelIndex &sourceRight) const {
|
||||
auto l = getItemAtSource<PhoneNumberList, PhoneNumber>(sourceLeft.row());
|
||||
auto r = getItemAtSource<PhoneNumberList, PhoneNumber>(sourceRight.row());
|
||||
return l->mCountry < r->mCountry;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,34 +21,23 @@
|
|||
#ifndef PHONE_NUMBER_PROXY_H_
|
||||
#define PHONE_NUMBER_PROXY_H_
|
||||
|
||||
#include "../proxy/SortFilterProxy.hpp"
|
||||
#include "../proxy/LimitProxy.hpp"
|
||||
#include "PhoneNumberList.hpp"
|
||||
#include "tool/AbstractObject.hpp"
|
||||
|
||||
// =============================================================================
|
||||
|
||||
class PhoneNumberProxy : public SortFilterProxy, public AbstractObject {
|
||||
class PhoneNumberProxy : public LimitProxy, public AbstractObject {
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(QString filterText READ getFilterText WRITE setFilterText NOTIFY filterTextChanged)
|
||||
|
||||
public:
|
||||
DECLARE_SORTFILTER_CLASS()
|
||||
|
||||
PhoneNumberProxy(QObject *parent = Q_NULLPTR);
|
||||
~PhoneNumberProxy();
|
||||
|
||||
QString getFilterText() const;
|
||||
void setFilterText(const QString &filter);
|
||||
|
||||
Q_INVOKABLE int findIndexByCountryCallingCode(const QString &countryCallingCode);
|
||||
|
||||
signals:
|
||||
void filterTextChanged();
|
||||
|
||||
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<PhoneNumberList> mPhoneNumberList;
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -35,9 +35,9 @@ public:
|
|||
virtual ~AbstractListProxy() {
|
||||
clearData();
|
||||
}
|
||||
|
||||
|
||||
virtual int rowCount(const QModelIndex &index = QModelIndex()) const override {
|
||||
return mList.count();
|
||||
return getDisplayCount(mList.size());
|
||||
}
|
||||
|
||||
virtual QHash<int, QByteArray> roleNames() const override {
|
||||
|
|
@ -45,6 +45,7 @@ public:
|
|||
roles[Qt::DisplayRole] = "$modelData";
|
||||
return roles;
|
||||
}
|
||||
|
||||
virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override {
|
||||
int row = index.row();
|
||||
if (!index.isValid() || row < 0 || row >= mList.count()) return QVariant();
|
||||
|
|
@ -59,37 +60,58 @@ public:
|
|||
|
||||
// Add functions
|
||||
virtual void add(T item) {
|
||||
int row = mList.count();
|
||||
beginInsertRows(QModelIndex(), row, row);
|
||||
mList << item;
|
||||
endInsertRows();
|
||||
auto lastIndex = index(mList.size() - 1, 0);
|
||||
emit dataChanged(lastIndex, lastIndex);
|
||||
}
|
||||
virtual void add(QList<T> items) {
|
||||
if (items.size() > 0) {
|
||||
QModelIndex firstIndex = mList.size() > 0 ? index(mList.size() - 1, 0) : index(0, 0);
|
||||
beginInsertRows(QModelIndex(), mList.size(), mList.size() + items.size() - 1);
|
||||
mList << items;
|
||||
int row = rowCount();
|
||||
if (mMaxDisplayItems > 0 && row + 1 >= mMaxDisplayItems) {// New item is not in display range
|
||||
mList << item;
|
||||
}else{
|
||||
beginInsertRows(QModelIndex(), row, row);
|
||||
mList << item;
|
||||
endInsertRows();
|
||||
auto lastIndex = index(mList.size() - 1, 0);
|
||||
emit dataChanged(firstIndex, lastIndex);
|
||||
emit dataChanged(lastIndex, lastIndex);
|
||||
}
|
||||
|
||||
}
|
||||
virtual void add(QList<T> items) {
|
||||
int count = items.size();
|
||||
if (count > 0 ) {
|
||||
int currentCount = rowCount();
|
||||
int newCount = getDisplayCount(mList.size() + count);
|
||||
if(newCount != currentCount){
|
||||
beginInsertRows(QModelIndex(), currentCount, newCount - 1);
|
||||
mList << items;
|
||||
endInsertRows();
|
||||
QModelIndex firstIndex = currentCount > 0 ? index(currentCount-1, 0) : index(0, 0);
|
||||
auto lastIndex = index(newCount - 1, 0);
|
||||
emit dataChanged(firstIndex, lastIndex);
|
||||
}else
|
||||
mList << items;
|
||||
}
|
||||
}
|
||||
|
||||
virtual void prepend(T item) {
|
||||
int currentCount = rowCount();
|
||||
beginInsertRows(QModelIndex(), 0, 0);
|
||||
mList.prepend(item);
|
||||
endInsertRows();
|
||||
if(mMaxDisplayItems > 0 && currentCount + 1 >= mMaxDisplayItems){
|
||||
setMaxDisplayItems(mMaxDisplayItems+1);
|
||||
}
|
||||
emit dataChanged(index(0), index(0));
|
||||
}
|
||||
|
||||
virtual void prepend(QList<T> items) {
|
||||
if (items.size() > 0) {
|
||||
int count = items.size();
|
||||
if (count > 0) {
|
||||
int currentCount = rowCount();
|
||||
int newCount = currentCount + count;
|
||||
beginInsertRows(QModelIndex(), 0, items.size() - 1);
|
||||
items << mList;
|
||||
mList = items;
|
||||
endInsertRows();
|
||||
if(mMaxDisplayItems > 0 && newCount >= mMaxDisplayItems){
|
||||
setMaxDisplayItems(newCount);
|
||||
}
|
||||
emit dataChanged(index(0), index(items.size() - 1));
|
||||
}
|
||||
}
|
||||
|
|
@ -111,6 +133,7 @@ public:
|
|||
|
||||
virtual void clearData() override {
|
||||
mList.clear();
|
||||
setMaxDisplayItems(getInitialDisplayItems());
|
||||
}
|
||||
|
||||
virtual void resetData() override {
|
||||
|
|
@ -118,6 +141,16 @@ public:
|
|||
clearData();
|
||||
endResetModel();
|
||||
}
|
||||
/*
|
||||
void displayMore() {
|
||||
int oldCount = rowCount();
|
||||
int newCount = getDisplayCount(oldCount + mList.size(), mMaxDisplayItems + mDisplayItemsStep);
|
||||
if (newCount != oldCount) {
|
||||
setMaxDisplayItems(newCount);
|
||||
beginInsertRows(QModelIndex(), oldCount, newCount - 1);
|
||||
endInsertRows();
|
||||
}
|
||||
}*/
|
||||
|
||||
protected:
|
||||
QList<T> mList;
|
||||
|
|
|
|||
151
Linphone/core/proxy/LimitProxy.cpp
Normal file
151
Linphone/core/proxy/LimitProxy.cpp
Normal file
|
|
@ -0,0 +1,151 @@
|
|||
/*
|
||||
* Copyright (c) 2022-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 "LimitProxy.hpp"
|
||||
|
||||
LimitProxy::LimitProxy(QObject *parent) : QSortFilterProxyModel(parent) {
|
||||
connect(this, &LimitProxy::rowsInserted, this, &LimitProxy::countChanged);
|
||||
connect(this, &LimitProxy::rowsRemoved, this, &LimitProxy::countChanged);
|
||||
}
|
||||
/*
|
||||
LimitProxy::LimitProxy(QAbstractItemModel *sortFilterProxy, QObject *parent) : QSortFilterProxyModel(parent) {
|
||||
setSourceModel(sortFilterProxy);
|
||||
}*/
|
||||
LimitProxy::~LimitProxy() {
|
||||
// if (mDeleteSourceModel) deleteSourceModel();
|
||||
}
|
||||
|
||||
bool LimitProxy::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const {
|
||||
return mMaxDisplayItems == -1 || sourceRow < mMaxDisplayItems;
|
||||
}
|
||||
|
||||
void LimitProxy::setSourceModels(SortFilterProxy *firstList) {
|
||||
auto secondList = firstList->sourceModel();
|
||||
connect(secondList, &QAbstractItemModel::rowsInserted, this, &LimitProxy::invalidateFilter);
|
||||
connect(secondList, &QAbstractItemModel::rowsRemoved, this, &LimitProxy::invalidateFilter);
|
||||
connect(firstList, &SortFilterProxy::filterTextChanged, this, &LimitProxy::filterTextChanged);
|
||||
connect(firstList, &SortFilterProxy::filterTypeChanged, this, &LimitProxy::filterTypeChanged);
|
||||
|
||||
// Restore old values
|
||||
auto oldModel = dynamic_cast<SortFilterProxy *>(sourceModel());
|
||||
if (oldModel) {
|
||||
firstList->setFilterType(oldModel->getFilterType());
|
||||
firstList->setFilterText(oldModel->getFilterText());
|
||||
}
|
||||
|
||||
QSortFilterProxyModel::setSourceModel(firstList);
|
||||
}
|
||||
|
||||
/*
|
||||
void LimitProxy::setSourceModels(SortFilterProxy *firstList, QAbstractItemModel *secondList) {
|
||||
connect(secondList, &QAbstractItemModel::rowsInserted, this, &LimitProxy::invalidateFilter);
|
||||
connect(secondList, &QAbstractItemModel::rowsRemoved, this, &LimitProxy::invalidateFilter);
|
||||
connect(firstList, &SortFilterProxy::filterTextChanged, this, &LimitProxy::filterTextChanged);
|
||||
setSourceModel(firstList);
|
||||
}*/
|
||||
|
||||
QVariant LimitProxy::getAt(const int &atIndex) const {
|
||||
auto modelIndex = index(atIndex, 0);
|
||||
return sourceModel()->data(mapToSource(modelIndex), 0);
|
||||
}
|
||||
|
||||
int LimitProxy::getCount() const {
|
||||
return rowCount();
|
||||
}
|
||||
|
||||
int LimitProxy::getInitialDisplayItems() const {
|
||||
return mInitialDisplayItems;
|
||||
}
|
||||
|
||||
void LimitProxy::setInitialDisplayItems(int initialItems) {
|
||||
if (initialItems != 0 && mInitialDisplayItems != initialItems) {
|
||||
mInitialDisplayItems = initialItems;
|
||||
if (getMaxDisplayItems() <= mInitialDisplayItems) setMaxDisplayItems(initialItems);
|
||||
if (getDisplayItemsStep() <= 0) setDisplayItemsStep(initialItems);
|
||||
emit initialDisplayItemsChanged();
|
||||
}
|
||||
}
|
||||
|
||||
int LimitProxy::getDisplayCount(int listCount, int maxCount) {
|
||||
return maxCount >= 0 ? qMin(listCount, maxCount) : listCount;
|
||||
}
|
||||
|
||||
int LimitProxy::getDisplayCount(int listCount) const {
|
||||
return getDisplayCount(listCount, mMaxDisplayItems);
|
||||
}
|
||||
|
||||
int LimitProxy::getMaxDisplayItems() const {
|
||||
return mMaxDisplayItems;
|
||||
}
|
||||
void LimitProxy::setMaxDisplayItems(int maxItems) {
|
||||
if (maxItems != 0 && mMaxDisplayItems != maxItems) {
|
||||
auto model = sourceModel();
|
||||
int modelCount = model ? model->rowCount() : 0;
|
||||
int oldCount = getDisplayCount(modelCount);
|
||||
mMaxDisplayItems = maxItems;
|
||||
if (getInitialDisplayItems() > mMaxDisplayItems) setInitialDisplayItems(maxItems);
|
||||
if (getDisplayItemsStep() <= 0) setDisplayItemsStep(maxItems);
|
||||
emit maxDisplayItemsChanged();
|
||||
|
||||
if (model && getDisplayCount(modelCount) != oldCount) {
|
||||
invalidateFilter();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int LimitProxy::getDisplayItemsStep() const {
|
||||
return mDisplayItemsStep;
|
||||
}
|
||||
|
||||
void LimitProxy::setDisplayItemsStep(int step) {
|
||||
if (step > 0 && mDisplayItemsStep != step) {
|
||||
mDisplayItemsStep = step;
|
||||
emit displayItemsStepChanged();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
QString LimitProxy::getFilterText() const {
|
||||
return dynamic_cast<SortFilterProxy *>(sourceModel())->getFilterText();
|
||||
}
|
||||
|
||||
void LimitProxy::setFilterText(const QString &filter) {
|
||||
dynamic_cast<SortFilterProxy *>(sourceModel())->setFilterText(filter);
|
||||
}
|
||||
|
||||
int LimitProxy::getFilterType() const {
|
||||
return dynamic_cast<SortFilterProxy *>(sourceModel())->getFilterType();
|
||||
}
|
||||
|
||||
void LimitProxy::setFilterType(int filter) {
|
||||
dynamic_cast<SortFilterProxy *>(sourceModel())->setFilterType(filter);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
void LimitProxy::displayMore() {
|
||||
int oldCount = rowCount();
|
||||
auto model = sourceModel();
|
||||
int newCount = getDisplayCount(model ? model->rowCount() : 0, mMaxDisplayItems + mDisplayItemsStep);
|
||||
if (newCount != oldCount) {
|
||||
setMaxDisplayItems(mMaxDisplayItems + mDisplayItemsStep);
|
||||
}
|
||||
}
|
||||
97
Linphone/core/proxy/LimitProxy.hpp
Normal file
97
Linphone/core/proxy/LimitProxy.hpp
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
* Copyright (c) 2022-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 LIMIT_PROXY_H_
|
||||
#define LIMIT_PROXY_H_
|
||||
|
||||
#include "SortFilterProxy.hpp"
|
||||
#include <QSortFilterProxyModel>
|
||||
|
||||
class LimitProxy : public QSortFilterProxyModel {
|
||||
Q_OBJECT
|
||||
public:
|
||||
Q_PROPERTY(int count READ getCount NOTIFY countChanged)
|
||||
Q_PROPERTY(int initialDisplayItems READ getInitialDisplayItems WRITE setInitialDisplayItems NOTIFY
|
||||
initialDisplayItemsChanged)
|
||||
Q_PROPERTY(int maxDisplayItems READ getMaxDisplayItems WRITE setMaxDisplayItems NOTIFY maxDisplayItemsChanged)
|
||||
Q_PROPERTY(int displayItemsStep READ getDisplayItemsStep WRITE setDisplayItemsStep NOTIFY displayItemsStepChanged)
|
||||
|
||||
// Propagation
|
||||
Q_PROPERTY(QString filterText READ getFilterText WRITE setFilterText NOTIFY filterTextChanged)
|
||||
Q_PROPERTY(int filterType READ getFilterType WRITE setFilterType NOTIFY filterTypeChanged)
|
||||
|
||||
LimitProxy(QObject *parent = nullptr);
|
||||
virtual ~LimitProxy();
|
||||
virtual bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override;
|
||||
|
||||
// Helper for setting the limit with sorted/filtered list
|
||||
void setSourceModels(SortFilterProxy *firstList);
|
||||
|
||||
Q_INVOKABLE void displayMore();
|
||||
Q_INVOKABLE QVariant getAt(const int &index) const;
|
||||
virtual int getCount() const;
|
||||
|
||||
// Get the item following by what is shown from 2 lists
|
||||
template <class A, class B, class C>
|
||||
QSharedPointer<C> getItemAt(const int &atIndex) const {
|
||||
return dynamic_cast<A *>(sourceModel())->template getItemAt<B, C>(atIndex);
|
||||
}
|
||||
|
||||
template <class A>
|
||||
inline A *getListModel() const {
|
||||
auto model = dynamic_cast<SortFilterProxy *>(sourceModel());
|
||||
if (model) return dynamic_cast<A *>(model->sourceModel());
|
||||
else return nullptr;
|
||||
}
|
||||
|
||||
static int getDisplayCount(int listCount, int maxCount);
|
||||
int getDisplayCount(int listCount) const;
|
||||
int getInitialDisplayItems() const;
|
||||
void setInitialDisplayItems(int initialItems);
|
||||
|
||||
int getMaxDisplayItems() const;
|
||||
void setMaxDisplayItems(int maxItems);
|
||||
|
||||
int getDisplayItemsStep() const;
|
||||
void setDisplayItemsStep(int step);
|
||||
|
||||
//-------------------------------------------------------------
|
||||
QString getFilterText() const;
|
||||
void setFilterText(const QString &filter);
|
||||
|
||||
virtual int getFilterType() const;
|
||||
virtual void setFilterType(int filterType);
|
||||
//-------------------------------------------------------------
|
||||
|
||||
int mInitialDisplayItems = -1;
|
||||
int mMaxDisplayItems = -1;
|
||||
int mDisplayItemsStep = 5;
|
||||
|
||||
signals:
|
||||
void countChanged();
|
||||
void initialDisplayItemsChanged();
|
||||
void maxDisplayItemsChanged();
|
||||
void displayItemsStepChanged();
|
||||
//-----------------------------------------------------------------
|
||||
void filterTypeChanged(int filterType);
|
||||
void filterTextChanged();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -63,14 +63,21 @@ public:
|
|||
|
||||
template <class T>
|
||||
void add(QList<QSharedPointer<T>> items) {
|
||||
if (items.size() > 0) {
|
||||
QModelIndex firstIndex = mList.size() > 0 ? index(mList.size() - 1, 0) : index(0, 0);
|
||||
beginInsertRows(QModelIndex(), mList.size(), mList.size() + items.size() - 1);
|
||||
for (auto i : items)
|
||||
mList << i.template objectCast<QObject>();
|
||||
endInsertRows();
|
||||
auto lastIndex = index(mList.size() - 1, 0);
|
||||
emit dataChanged(firstIndex, lastIndex);
|
||||
int count = items.size();
|
||||
if (count > 0 ) {
|
||||
int currentCount = rowCount();
|
||||
int newCount = getDisplayCount(mList.size() + count);
|
||||
if(newCount != currentCount){
|
||||
beginInsertRows(QModelIndex(), currentCount, newCount - 1);
|
||||
for (auto i : items)
|
||||
mList << i.template objectCast<QObject>();
|
||||
endInsertRows();
|
||||
QModelIndex firstIndex = currentCount > 0 ? index(currentCount-1, 0) : index(0, 0);
|
||||
auto lastIndex = index(newCount - 1, 0);
|
||||
emit dataChanged(firstIndex, lastIndex);
|
||||
}else
|
||||
for (auto i : items)
|
||||
mList << i.template objectCast<QObject>();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -81,13 +88,7 @@ public:
|
|||
|
||||
template <class T>
|
||||
void prepend(QList<QSharedPointer<T>> items) {
|
||||
if (items.size() > 0) {
|
||||
beginInsertRows(QModelIndex(), 0, items.size() - 1);
|
||||
items << mList;
|
||||
mList = items;
|
||||
endInsertRows();
|
||||
emit dataChanged(index(0), index(items.size() - 1));
|
||||
}
|
||||
AbstractListProxy<QSharedPointer<QObject>>::prepend(items);
|
||||
}
|
||||
|
||||
virtual bool remove(QObject *itemToRemove) override {
|
||||
|
|
|
|||
|
|
@ -24,13 +24,57 @@ Proxy::Proxy(QObject *parent) : QAbstractListModel(parent) {
|
|||
connect(this, &Proxy::rowsInserted, this, &Proxy::countChanged);
|
||||
connect(this, &Proxy::rowsRemoved, this, &Proxy::countChanged);
|
||||
}
|
||||
|
||||
int Proxy::getCount() const {
|
||||
return rowCount();
|
||||
}
|
||||
|
||||
int Proxy::getDisplayCount(int listCount) const {
|
||||
return mMaxDisplayItems >= 0 ? qMin(listCount, mMaxDisplayItems) : listCount;
|
||||
}
|
||||
|
||||
bool Proxy::remove(QObject *itemToRemove) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void Proxy::clearData() {
|
||||
}
|
||||
|
||||
void Proxy::resetData() {
|
||||
}
|
||||
|
||||
int Proxy::getInitialDisplayItems() const {
|
||||
return mInitialDisplayItems;
|
||||
}
|
||||
|
||||
void Proxy::setInitialDisplayItems(int initialItems) {
|
||||
if (mInitialDisplayItems != initialItems) {
|
||||
mInitialDisplayItems = initialItems;
|
||||
if(getMaxDisplayItems() == -1)
|
||||
setMaxDisplayItems(initialItems);
|
||||
emit initialDisplayItemsChanged();
|
||||
}
|
||||
}
|
||||
|
||||
int Proxy::getMaxDisplayItems() const {
|
||||
return mMaxDisplayItems;
|
||||
}
|
||||
void Proxy::setMaxDisplayItems(int maxItems) {
|
||||
if (mMaxDisplayItems != maxItems) {
|
||||
mMaxDisplayItems = maxItems;
|
||||
if( getInitialDisplayItems() == -1)
|
||||
setInitialDisplayItems(maxItems);
|
||||
emit maxDisplayItemsChanged();
|
||||
}
|
||||
}
|
||||
|
||||
int Proxy::getDisplayItemsStep() const {
|
||||
return mDisplayItemsStep;
|
||||
}
|
||||
|
||||
void Proxy::setDisplayItemsStep(int step) {
|
||||
if (mDisplayItemsStep != step) {
|
||||
mDisplayItemsStep = step;
|
||||
emit displayItemsStepChanged();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,15 +30,35 @@ class Proxy : public QAbstractListModel {
|
|||
public:
|
||||
Q_PROPERTY(int count READ getCount NOTIFY countChanged)
|
||||
Q_PROPERTY(int length READ getCount NOTIFY countChanged)
|
||||
Q_PROPERTY(int initialDisplayItems READ getInitialDisplayItems WRITE setInitialDisplayItems NOTIFY initialDisplayItemsChanged)
|
||||
Q_PROPERTY(int maxDisplayItems READ getMaxDisplayItems WRITE setMaxDisplayItems NOTIFY maxDisplayItemsChanged)
|
||||
Q_PROPERTY(int displayItemsStep READ getDisplayItemsStep WRITE setDisplayItemsStep NOTIFY displayItemsStepChanged)
|
||||
|
||||
Proxy(QObject *parent = nullptr);
|
||||
Q_INVOKABLE virtual int getCount() const;
|
||||
int getDisplayCount(int listCount) const;
|
||||
Q_INVOKABLE virtual bool remove(QObject *itemToRemove);
|
||||
Q_INVOKABLE virtual void clearData();
|
||||
Q_INVOKABLE virtual void resetData();
|
||||
|
||||
int getInitialDisplayItems() const;
|
||||
void setInitialDisplayItems(int initialItems);
|
||||
|
||||
int getMaxDisplayItems() const;
|
||||
void setMaxDisplayItems(int maxItems);
|
||||
|
||||
int getDisplayItemsStep() const;
|
||||
void setDisplayItemsStep(int step);
|
||||
|
||||
int mInitialDisplayItems = -1;
|
||||
int mMaxDisplayItems = -1;
|
||||
int mDisplayItemsStep = -1;
|
||||
|
||||
signals:
|
||||
void countChanged();
|
||||
void initialDisplayItemsChanged();
|
||||
void maxDisplayItemsChanged();
|
||||
void displayItemsStepChanged();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -19,10 +19,15 @@
|
|||
*/
|
||||
|
||||
#include "SortFilterProxy.hpp"
|
||||
|
||||
SortFilterProxy::SortFilterProxy(QObject *parent) : QSortFilterProxyModel(parent) {
|
||||
#include "Proxy.hpp"
|
||||
SortFilterProxy::SortFilterProxy(QAbstractItemModel *list) : QSortFilterProxyModel(list) {
|
||||
connect(this, &SortFilterProxy::rowsInserted, this, &SortFilterProxy::countChanged);
|
||||
connect(this, &SortFilterProxy::rowsRemoved, this, &SortFilterProxy::countChanged);
|
||||
setSourceModel(list);
|
||||
}
|
||||
|
||||
SortFilterProxy::SortFilterProxy(QAbstractItemModel *list, Qt::SortOrder order) : SortFilterProxy(list) {
|
||||
sort(0, order);
|
||||
}
|
||||
|
||||
SortFilterProxy::~SortFilterProxy() {
|
||||
|
|
@ -37,12 +42,15 @@ void SortFilterProxy::deleteSourceModel() {
|
|||
}
|
||||
}
|
||||
|
||||
int SortFilterProxy::getCount() const {
|
||||
return rowCount();
|
||||
void SortFilterProxy::setSourceModel(QAbstractItemModel *model) {
|
||||
auto listModel = dynamic_cast<Proxy *>(model);
|
||||
auto oldSourceModel = sourceModel();
|
||||
if (oldSourceModel) disconnect(oldSourceModel);
|
||||
QSortFilterProxyModel::setSourceModel(model);
|
||||
}
|
||||
|
||||
int SortFilterProxy::getFilterType() const {
|
||||
return mFilterType;
|
||||
int SortFilterProxy::getCount() const {
|
||||
return rowCount();
|
||||
}
|
||||
|
||||
QVariant SortFilterProxy::getAt(const int &atIndex) const {
|
||||
|
|
@ -50,8 +58,8 @@ QVariant SortFilterProxy::getAt(const int &atIndex) const {
|
|||
return sourceModel()->data(mapToSource(modelIndex), 0);
|
||||
}
|
||||
|
||||
void SortFilterProxy::setSortOrder(const Qt::SortOrder &order) {
|
||||
sort(0, order);
|
||||
int SortFilterProxy::getFilterType() const {
|
||||
return mFilterType;
|
||||
}
|
||||
|
||||
void SortFilterProxy::setFilterType(int filterType) {
|
||||
|
|
@ -62,6 +70,22 @@ void SortFilterProxy::setFilterType(int filterType) {
|
|||
}
|
||||
}
|
||||
|
||||
QString SortFilterProxy::getFilterText() const {
|
||||
return mFilterText;
|
||||
}
|
||||
|
||||
void SortFilterProxy::setFilterText(const QString &filter) {
|
||||
if (mFilterText != filter) {
|
||||
mFilterText = filter;
|
||||
invalidateFilter();
|
||||
emit filterTextChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void SortFilterProxy::setSortOrder(const Qt::SortOrder &order) {
|
||||
sort(0, order);
|
||||
}
|
||||
|
||||
void SortFilterProxy::remove(int index, int count) {
|
||||
QSortFilterProxyModel::removeRows(index, count);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,37 +22,62 @@
|
|||
#define SORT_FILTER_PROXY_H_
|
||||
|
||||
#include <QSortFilterProxyModel>
|
||||
#define DECLARE_SORTFILTER_CLASS(...) \
|
||||
class SortFilterList : public SortFilterProxy { \
|
||||
public: \
|
||||
SortFilterList(QAbstractItemModel *list) : SortFilterProxy(list) { \
|
||||
} \
|
||||
SortFilterList(QAbstractItemModel *list, Qt::SortOrder order) : SortFilterProxy(list, order) { \
|
||||
} \
|
||||
virtual bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override; \
|
||||
virtual bool lessThan(const QModelIndex &sourceLeft, const QModelIndex &sourceRight) const override; \
|
||||
__VA_ARGS__ \
|
||||
};
|
||||
|
||||
class SortFilterProxy : public QSortFilterProxyModel {
|
||||
Q_OBJECT
|
||||
public:
|
||||
Q_PROPERTY(int count READ getCount NOTIFY countChanged)
|
||||
Q_PROPERTY(int filterType READ getFilterType WRITE setFilterType NOTIFY filterTypeChanged)
|
||||
Q_PROPERTY(QString filterText READ getFilterText WRITE setFilterText NOTIFY filterTextChanged)
|
||||
|
||||
SortFilterProxy(QObject *parent = nullptr);
|
||||
SortFilterProxy(QAbstractItemModel *parent);
|
||||
SortFilterProxy(QAbstractItemModel *parent, Qt::SortOrder order);
|
||||
virtual ~SortFilterProxy();
|
||||
virtual void deleteSourceModel();
|
||||
virtual void setSourceModel(QAbstractItemModel *sourceModel) override;
|
||||
|
||||
virtual int getCount() const;
|
||||
virtual int getFilterType() const;
|
||||
|
||||
Q_INVOKABLE QVariant getAt(const int &index) const;
|
||||
template <class A, class B>
|
||||
QSharedPointer<B> getItemAt(const int &atIndex) const {
|
||||
auto modelIndex = index(atIndex, 0);
|
||||
return qobject_cast<A *>(sourceModel())->template getAt<B>(mapToSource(modelIndex).row());
|
||||
}
|
||||
template <class A, class B>
|
||||
QSharedPointer<B> getItemAtSource(const int &atIndex) const {
|
||||
return qobject_cast<A *>(sourceModel())->template getAt<B>(atIndex);
|
||||
}
|
||||
|
||||
virtual int getFilterType() const;
|
||||
virtual void setFilterType(int filterType);
|
||||
|
||||
Q_INVOKABLE void setSortOrder(const Qt::SortOrder &order);
|
||||
|
||||
virtual void setFilterType(int filterType);
|
||||
QString getFilterText() const;
|
||||
void setFilterText(const QString &filter);
|
||||
|
||||
Q_INVOKABLE void remove(int index, int count = 1);
|
||||
|
||||
signals:
|
||||
void countChanged();
|
||||
void filterTypeChanged(int filterType);
|
||||
void filterTextChanged();
|
||||
|
||||
protected:
|
||||
int mFilterType = 0;
|
||||
QString mFilterText;
|
||||
bool mDeleteSourceModel = false;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -24,18 +24,28 @@
|
|||
#include "ScreenProxy.hpp"
|
||||
// =============================================================================
|
||||
|
||||
ScreenProxy::ScreenProxy(QObject *parent) : SortFilterProxy(parent) {
|
||||
setSourceModel(new ScreenList(this));
|
||||
sort(0);
|
||||
ScreenProxy::ScreenProxy(QObject *parent) : LimitProxy(parent) {
|
||||
setSourceModels(new SortFilterList(new ScreenList(this), Qt::AscendingOrder));
|
||||
}
|
||||
ScreenList::Mode ScreenProxy::getMode() const {
|
||||
return dynamic_cast<ScreenList *>(sourceModel())->getMode();
|
||||
return getListModel<ScreenList>()->getMode();
|
||||
}
|
||||
|
||||
void ScreenProxy::setMode(ScreenList::Mode data) {
|
||||
dynamic_cast<ScreenList *>(sourceModel())->setMode(data);
|
||||
getListModel<ScreenList>()->setMode(data);
|
||||
}
|
||||
|
||||
void ScreenProxy::update() {
|
||||
dynamic_cast<ScreenList *>(sourceModel())->update();
|
||||
getListModel<ScreenList>()->update();
|
||||
}
|
||||
|
||||
bool ScreenProxy::SortFilterList::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ScreenProxy::SortFilterList::lessThan(const QModelIndex &sourceLeft, const QModelIndex &sourceRight) const {
|
||||
auto l = qobject_cast<ScreenList *>(sourceModel())->getAt(sourceLeft.row());
|
||||
auto r = qobject_cast<ScreenList *>(sourceModel())->getAt(sourceRight.row());
|
||||
|
||||
return l["screenIndex"].toInt() < r["screenIndex"].toInt();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,17 +22,18 @@
|
|||
#define SCREEN_PROXY_H_
|
||||
|
||||
#include "ScreenList.hpp"
|
||||
#include "core/proxy/SortFilterProxy.hpp"
|
||||
#include "core/proxy/LimitProxy.hpp"
|
||||
// =============================================================================
|
||||
|
||||
class QWindow;
|
||||
|
||||
class ScreenProxy : public SortFilterProxy {
|
||||
class ScreenProxy : public LimitProxy {
|
||||
class ScreenModelFilter;
|
||||
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(ScreenList::Mode mode READ getMode WRITE setMode NOTIFY modeChanged)
|
||||
public:
|
||||
DECLARE_SORTFILTER_CLASS()
|
||||
ScreenProxy(QObject *parent = Q_NULLPTR);
|
||||
|
||||
ScreenList::Mode getMode() const;
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
#include "MagicSearchList.hpp"
|
||||
#include "core/friend/FriendGui.hpp"
|
||||
|
||||
MagicSearchProxy::MagicSearchProxy(QObject *parent) : SortFilterProxy(parent) {
|
||||
MagicSearchProxy::MagicSearchProxy(QObject *parent) : LimitProxy(parent) {
|
||||
mSourceFlags = (int)LinphoneEnums::MagicSearchSource::Friends | (int)LinphoneEnums::MagicSearchSource::LdapServers;
|
||||
mAggregationFlag = LinphoneEnums::MagicSearchAggregation::Friend;
|
||||
setList(MagicSearchList::create());
|
||||
|
|
@ -41,6 +41,7 @@ void MagicSearchProxy::setList(QSharedPointer<MagicSearchList> newList) {
|
|||
if (mList) {
|
||||
disconnect(mList.get());
|
||||
}
|
||||
auto oldModel = dynamic_cast<SortFilterList *>(sourceModel());
|
||||
mList = newList;
|
||||
if (mList) {
|
||||
connect(mList.get(), &MagicSearchList::sourceFlagsChanged, this, &MagicSearchProxy::sourceFlagsChanged,
|
||||
|
|
@ -50,8 +51,11 @@ void MagicSearchProxy::setList(QSharedPointer<MagicSearchList> newList) {
|
|||
connect(
|
||||
mList.get(), &MagicSearchList::friendCreated, this,
|
||||
[this](int index) {
|
||||
auto proxyIndex = mapFromSource(sourceModel()->index(index, 0));
|
||||
emit friendCreated(proxyIndex.row());
|
||||
auto proxyIndex =
|
||||
dynamic_cast<SortFilterList *>(sourceModel())->mapFromSource(mList->index(index, 0)).row();
|
||||
// auto proxyIndex = mapFromSource(sourceModel()->index(index, 0)); // OLD (keep for checking new proxy
|
||||
// behavior)
|
||||
emit friendCreated(proxyIndex);
|
||||
},
|
||||
Qt::QueuedConnection);
|
||||
connect(
|
||||
|
|
@ -63,11 +67,13 @@ void MagicSearchProxy::setList(QSharedPointer<MagicSearchList> newList) {
|
|||
},
|
||||
Qt::QueuedConnection);
|
||||
}
|
||||
setSourceModel(mList.get());
|
||||
auto sortFilterList = new SortFilterList(mList.get(), Qt::AscendingOrder);
|
||||
if (oldModel) sortFilterList->mShowFavoritesOnly = oldModel->mShowFavoritesOnly;
|
||||
setSourceModels(sortFilterList);
|
||||
}
|
||||
|
||||
int MagicSearchProxy::findFriendIndexByAddress(const QString &address) {
|
||||
auto magicSearchList = qobject_cast<MagicSearchList *>(sourceModel());
|
||||
auto magicSearchList = getListModel<MagicSearchList>();
|
||||
if (magicSearchList)
|
||||
return mapFromSource(magicSearchList->index(magicSearchList->findFriendIndexByAddress(address), 0)).row();
|
||||
else return -1;
|
||||
|
|
@ -96,12 +102,14 @@ void MagicSearchProxy::setSourceFlags(int flags) {
|
|||
}
|
||||
|
||||
bool MagicSearchProxy::showFavoritesOnly() const {
|
||||
return mShowFavoritesOnly;
|
||||
return dynamic_cast<SortFilterList *>(sourceModel())->mShowFavoritesOnly;
|
||||
}
|
||||
|
||||
void MagicSearchProxy::setShowFavoritesOnly(bool show) {
|
||||
if (mShowFavoritesOnly != show) {
|
||||
mShowFavoritesOnly = show;
|
||||
auto list = dynamic_cast<SortFilterList *>(sourceModel());
|
||||
if (list->mShowFavoritesOnly != show) {
|
||||
list->mShowFavoritesOnly = show;
|
||||
list->invalidate();
|
||||
emit showFavoriteOnlyChanged();
|
||||
}
|
||||
}
|
||||
|
|
@ -122,27 +130,21 @@ void MagicSearchProxy::setAggregationFlag(LinphoneEnums::MagicSearchAggregation
|
|||
}
|
||||
}
|
||||
|
||||
bool MagicSearchProxy::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const {
|
||||
QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent);
|
||||
auto model = sourceModel()->data(index);
|
||||
auto friendGui = model.value<FriendGui *>();
|
||||
auto friendCore = friendGui->getCore();
|
||||
bool MagicSearchProxy::SortFilterList::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const {
|
||||
auto friendCore = getItemAtSource<MagicSearchList, FriendCore>(sourceRow);
|
||||
if (friendCore) {
|
||||
return !mShowFavoritesOnly || friendCore->getStarred();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MagicSearchProxy::lessThan(const QModelIndex &left, const QModelIndex &right) const {
|
||||
auto l = sourceModel()->data(left);
|
||||
auto r = sourceModel()->data(right);
|
||||
bool MagicSearchProxy::SortFilterList::lessThan(const QModelIndex &sourceLeft, const QModelIndex &sourceRight) const {
|
||||
auto l = getItemAtSource<MagicSearchList, FriendCore>(sourceLeft.row());
|
||||
auto r = getItemAtSource<MagicSearchList, FriendCore>(sourceRight.row());
|
||||
|
||||
auto lIsFriend = l.value<FriendGui *>();
|
||||
auto rIsFriend = r.value<FriendGui *>();
|
||||
|
||||
if (lIsFriend && rIsFriend) {
|
||||
auto lName = lIsFriend->getCore()->getDisplayName().toLower();
|
||||
auto rName = rIsFriend->getCore()->getDisplayName().toLower();
|
||||
if (l && r) {
|
||||
auto lName = l->getDisplayName().toLower();
|
||||
auto rName = r->getDisplayName().toLower();
|
||||
return lName < rName;
|
||||
}
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -21,13 +21,13 @@
|
|||
#ifndef MAGIC_SEARCH_PROXY_H_
|
||||
#define MAGIC_SEARCH_PROXY_H_
|
||||
|
||||
#include "../proxy/SortFilterProxy.hpp"
|
||||
#include "../proxy/LimitProxy.hpp"
|
||||
#include "core/search/MagicSearchList.hpp"
|
||||
#include "tool/LinphoneEnums.hpp"
|
||||
|
||||
// =============================================================================
|
||||
|
||||
class MagicSearchProxy : public SortFilterProxy {
|
||||
class MagicSearchProxy : public LimitProxy {
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(QString searchText READ getSearchText WRITE setSearchText NOTIFY searchTextChanged)
|
||||
|
|
@ -38,6 +38,7 @@ class MagicSearchProxy : public SortFilterProxy {
|
|||
Q_PROPERTY(MagicSearchProxy *parentProxy WRITE setParentProxy NOTIFY parentProxyChanged)
|
||||
|
||||
public:
|
||||
DECLARE_SORTFILTER_CLASS(bool mShowFavoritesOnly = false;)
|
||||
MagicSearchProxy(QObject *parent = Q_NULLPTR);
|
||||
~MagicSearchProxy();
|
||||
|
||||
|
|
@ -72,11 +73,8 @@ signals:
|
|||
protected:
|
||||
QString mSearchText;
|
||||
int mSourceFlags;
|
||||
bool mShowFavoritesOnly = false;
|
||||
LinphoneEnums::MagicSearchAggregation mAggregationFlag;
|
||||
QSharedPointer<MagicSearchList> mList;
|
||||
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override;
|
||||
virtual bool lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const override;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -80,6 +80,7 @@ SettingsCore::SettingsCore(QObject *parent) : QObject(parent) {
|
|||
INIT_CORE_MEMBER(DisableBroadcastFeature, settingsModel)
|
||||
INIT_CORE_MEMBER(HideSettings, settingsModel)
|
||||
INIT_CORE_MEMBER(HideAccountSettings, settingsModel)
|
||||
INIT_CORE_MEMBER(HideFps, settingsModel)
|
||||
INIT_CORE_MEMBER(DisableCallRecordings, settingsModel)
|
||||
INIT_CORE_MEMBER(AssistantHideCreateAccount, settingsModel)
|
||||
INIT_CORE_MEMBER(AssistantHideCreateAccount, settingsModel)
|
||||
|
|
@ -311,6 +312,8 @@ void SettingsCore::setSelf(QSharedPointer<SettingsCore> me) {
|
|||
HideSettings)
|
||||
DEFINE_CORE_GETSET_CONNECT(mSettingsModelConnection, SettingsCore, SettingsModel, settingsModel, bool,
|
||||
hideAccountSettings, HideAccountSettings)
|
||||
DEFINE_CORE_GETSET_CONNECT(mSettingsModelConnection, SettingsCore, SettingsModel, settingsModel, bool,
|
||||
hideFps, HideFps)
|
||||
DEFINE_CORE_GETSET_CONNECT(mSettingsModelConnection, SettingsCore, SettingsModel, settingsModel, bool,
|
||||
disableCallRecordings, DisableCallRecordings)
|
||||
DEFINE_CORE_GETSET_CONNECT(mSettingsModelConnection, SettingsCore, SettingsModel, settingsModel, bool,
|
||||
|
|
|
|||
|
|
@ -148,6 +148,7 @@ public:
|
|||
DECLARE_CORE_GETSET_MEMBER(bool, disableBroadcastFeature, DisableBroadcastFeature)
|
||||
DECLARE_CORE_GETSET_MEMBER(bool, hideSettings, HideSettings)
|
||||
DECLARE_CORE_GETSET_MEMBER(bool, hideAccountSettings, HideAccountSettings)
|
||||
DECLARE_CORE_GETSET_MEMBER(bool, hideFps, HideFps)
|
||||
DECLARE_CORE_GETSET_MEMBER(bool, disableCallRecordings, DisableCallRecordings)
|
||||
DECLARE_CORE_GETSET_MEMBER(bool, assistantHideCreateAccount, AssistantHideCreateAccount)
|
||||
DECLARE_CORE_GETSET_MEMBER(bool, assistantDisableQrCode, AssistantDisableQrCode)
|
||||
|
|
|
|||
|
|
@ -24,19 +24,20 @@
|
|||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
TimeZoneProxy::TimeZoneProxy(QObject *parent) : SortFilterProxy(parent) {
|
||||
mDeleteSourceModel = true;
|
||||
TimeZoneProxy::TimeZoneProxy(QObject *parent) : LimitProxy(parent) {
|
||||
mList = TimeZoneList::create();
|
||||
setSourceModel(mList.get());
|
||||
sort(0);
|
||||
setSourceModels(new SortFilterList(mList.get(), Qt::AscendingOrder));
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
bool TimeZoneProxy::lessThan(const QModelIndex &left, const QModelIndex &right) const {
|
||||
auto test = sourceModel()->data(left);
|
||||
auto l = getItemAt<TimeZoneList, TimeZoneModel>(left.row());
|
||||
auto r = getItemAt<TimeZoneList, TimeZoneModel>(right.row());
|
||||
bool TimeZoneProxy::SortFilterList::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TimeZoneProxy::SortFilterList::lessThan(const QModelIndex &sourceLeft, const QModelIndex &sourceRight) const {
|
||||
auto l = getItemAtSource<TimeZoneList, TimeZoneModel>(sourceLeft.row());
|
||||
auto r = getItemAtSource<TimeZoneList, TimeZoneModel>(sourceRight.row());
|
||||
if (!l || !r) return true;
|
||||
auto timeA = l->getStandardTimeOffset() / 3600;
|
||||
auto timeB = r->getStandardTimeOffset() / 3600;
|
||||
|
|
@ -47,5 +48,5 @@ bool TimeZoneProxy::lessThan(const QModelIndex &left, const QModelIndex &right)
|
|||
int TimeZoneProxy::getIndex(TimeZoneModel *model) const {
|
||||
int index = 0;
|
||||
index = mList->get(model ? model->getTimeZone() : QTimeZone::systemTimeZone());
|
||||
return mapFromSource(mList->index(index, 0)).row();
|
||||
return dynamic_cast<SortFilterList *>(sourceModel())->mapFromSource(mList->index(index, 0)).row();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,16 +21,18 @@
|
|||
#ifndef TIME_ZONE_PROXY_MODEL_H_
|
||||
#define TIME_ZONE_PROXY_MODEL_H_
|
||||
|
||||
#include "../proxy/SortFilterProxy.hpp"
|
||||
#include "../proxy/LimitProxy.hpp"
|
||||
|
||||
// =============================================================================
|
||||
|
||||
class TimeZoneModel;
|
||||
class TimeZoneList;
|
||||
|
||||
class TimeZoneProxy : public SortFilterProxy {
|
||||
class TimeZoneProxy : public LimitProxy {
|
||||
Q_OBJECT
|
||||
public:
|
||||
DECLARE_SORTFILTER_CLASS()
|
||||
|
||||
TimeZoneProxy(QObject *parent = Q_NULLPTR);
|
||||
Q_PROPERTY(int defaultIndex READ getIndex CONSTANT)
|
||||
|
||||
|
|
@ -38,7 +40,6 @@ public:
|
|||
|
||||
protected:
|
||||
QSharedPointer<TimeZoneList> mList;
|
||||
bool lessThan(const QModelIndex &left, const QModelIndex &right) const override;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -38,13 +38,15 @@ void cleanStream() {
|
|||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
#if defined _WIN32
|
||||
// log in console only if launched from console
|
||||
if (AttachConsole(ATTACH_PARENT_PROCESS)) {
|
||||
freopen_s(&gStream, "CONOUT$", "w", stdout);
|
||||
freopen_s(&gStream, "CONOUT$", "w", stderr);
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
#if defined _WIN32
|
||||
// log in console only if launched from console
|
||||
if (AttachConsole(ATTACH_PARENT_PROCESS)) {
|
||||
freopen_s(&gStream, "CONOUT$", "w", stdout);
|
||||
freopen_s(&gStream, "CONOUT$", "w", stderr);
|
||||
}
|
||||
#endif
|
||||
*/
|
||||
// Useful to share camera on Fullscreen (other context) or multiscreens
|
||||
QApplication::setAttribute(Qt::AA_ShareOpenGLContexts);
|
||||
// Disable QML cache. Avoid malformed cache.
|
||||
|
|
|
|||
|
|
@ -568,6 +568,7 @@ void SettingsModel::notifyConfigReady(){
|
|||
DEFINE_NOTIFY_CONFIG_READY(disableMeetingsFeature, DisableMeetingsFeature)
|
||||
DEFINE_NOTIFY_CONFIG_READY(hideSettings,HideSettings)
|
||||
DEFINE_NOTIFY_CONFIG_READY(hideAccountSettings, HideAccountSettings)
|
||||
DEFINE_NOTIFY_CONFIG_READY(hideFps, HideFps)
|
||||
DEFINE_NOTIFY_CONFIG_READY(disableCallRecordings, DisableCallRecordings)
|
||||
DEFINE_NOTIFY_CONFIG_READY(assistantHideCreateAccount, AssistantHideCreateAccount)
|
||||
DEFINE_NOTIFY_CONFIG_READY(assistantDisableQrCode, AssistantDisableQrCode)
|
||||
|
|
@ -596,6 +597,7 @@ DEFINE_GETSET_CONFIG(SettingsModel,
|
|||
DEFINE_GETSET_CONFIG(SettingsModel, bool, Bool, hideSettings, HideSettings, "hide_settings", false)
|
||||
DEFINE_GETSET_CONFIG(
|
||||
SettingsModel, bool, Bool, hideAccountSettings, HideAccountSettings, "hide_account_settings", false)
|
||||
DEFINE_GETSET_CONFIG(SettingsModel, bool, Bool, hideFps, HideFps, "hide_fps", true )
|
||||
DEFINE_GETSET_CONFIG(SettingsModel,
|
||||
bool,
|
||||
Bool,
|
||||
|
|
|
|||
|
|
@ -139,6 +139,7 @@ public:
|
|||
DECLARE_GETSET(bool, disableBroadcastFeature, DisableBroadcastFeature)
|
||||
DECLARE_GETSET(bool, hideSettings, HideSettings)
|
||||
DECLARE_GETSET(bool, hideAccountSettings, HideAccountSettings)
|
||||
DECLARE_GETSET(bool, hideFps, HideFps)
|
||||
DECLARE_GETSET(bool, disableCallRecordings, DisableCallRecordings)
|
||||
DECLARE_GETSET(bool, assistantHideCreateAccount, AssistantHideCreateAccount)
|
||||
DECLARE_GETSET(bool, assistantDisableQrCode, AssistantDisableQrCode)
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import QtQuick.Controls.Basic as Control
|
|||
import QtQuick.Effects
|
||||
import QtQuick.Layouts
|
||||
import Linphone
|
||||
|
||||
|
||||
Control.Button {
|
||||
id: mainItem
|
||||
property int capitalization
|
||||
|
|
@ -26,7 +26,8 @@ Control.Button {
|
|||
// rightPadding: 20 * DefaultStyle.dp
|
||||
// topPadding: 11 * DefaultStyle.dp
|
||||
// bottomPadding: 11 * DefaultStyle.dp
|
||||
|
||||
implicitHeight: contentItem.implicitHeight + bottomPadding + topPadding
|
||||
implicitWidth: contentItem.implicitWidth + leftPadding + rightPadding
|
||||
MouseArea {
|
||||
id: mouseArea
|
||||
anchors.fill: parent
|
||||
|
|
@ -34,42 +35,48 @@ Control.Button {
|
|||
cursorShape: containsMouse ? Qt.PointingHandCursor : Qt.ArrowCursor
|
||||
acceptedButtons: Qt.NoButton
|
||||
}
|
||||
|
||||
background: Item {
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
id: buttonBackground
|
||||
color: mainItem.enabled
|
||||
? inversedColors
|
||||
? mainItem.pressed || mainItem.shadowEnabled
|
||||
? DefaultStyle.grey_100
|
||||
: mainItem.borderColor
|
||||
: mainItem.pressed || mainItem.shadowEnabled
|
||||
? mainItem.pressedColor
|
||||
: mainItem.color
|
||||
: mainItem.disabledColor
|
||||
radius: mainItem.radius
|
||||
border.color: inversedColors ? mainItem.color : mainItem.borderColor
|
||||
|
||||
MouseArea {
|
||||
|
||||
background: Loader{
|
||||
asynchronous: true
|
||||
anchors.fill: parent
|
||||
|
||||
sourceComponent:
|
||||
Item {
|
||||
Rectangle {
|
||||
id: buttonBackground
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
cursorShape: containsMouse ? Qt.PointingHandCursor : Qt.ArrowCursor
|
||||
color: mainItem.enabled
|
||||
? inversedColors
|
||||
? mainItem.pressed || mainItem.shadowEnabled
|
||||
? DefaultStyle.grey_100
|
||||
: mainItem.borderColor
|
||||
: mainItem.pressed || mainItem.shadowEnabled
|
||||
? mainItem.pressedColor
|
||||
: mainItem.color
|
||||
: mainItem.disabledColor
|
||||
radius: mainItem.radius
|
||||
border.color: inversedColors ? mainItem.color : mainItem.borderColor
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
cursorShape: containsMouse ? Qt.PointingHandCursor : Qt.ArrowCursor
|
||||
}
|
||||
}
|
||||
MultiEffect {
|
||||
enabled: mainItem.shadowEnabled
|
||||
anchors.fill: buttonBackground
|
||||
source: buttonBackground
|
||||
visible: mainItem.shadowEnabled
|
||||
// Crash : https://bugreports.qt.io/browse/QTBUG-124730
|
||||
shadowEnabled: true //mainItem.shadowEnabled
|
||||
shadowColor: DefaultStyle.grey_1000
|
||||
shadowBlur: 0.1
|
||||
shadowOpacity: mainItem.shadowEnabled ? 0.5 : 0.0
|
||||
}
|
||||
}
|
||||
MultiEffect {
|
||||
enabled: mainItem.shadowEnabled
|
||||
anchors.fill: buttonBackground
|
||||
source: buttonBackground
|
||||
visible: mainItem.shadowEnabled
|
||||
// Crash : https://bugreports.qt.io/browse/QTBUG-124730
|
||||
shadowEnabled: true //mainItem.shadowEnabled
|
||||
shadowColor: DefaultStyle.grey_1000
|
||||
shadowBlur: 0.1
|
||||
shadowOpacity: mainItem.shadowEnabled ? 0.5 : 0.0
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
component ButtonText: Text {
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
|
|
@ -90,7 +97,7 @@ Control.Button {
|
|||
bold: mainItem.font.bold
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
component ButtonImage: EffectImage {
|
||||
// Layout.fillWidth: true
|
||||
// Layout.fillHeight: true
|
||||
|
|
@ -100,7 +107,70 @@ Control.Button {
|
|||
colorizationColor: mainItem.contentImageColor
|
||||
shadowEnabled: mainItem.shadowEnabled
|
||||
}
|
||||
|
||||
|
||||
contentItem: Control.StackView{
|
||||
id: stacklayout
|
||||
width: mainItem.width
|
||||
// TODO Qt bug : contentItem is never changed....
|
||||
implicitHeight: contentItem && contentItem.implicitHeight? contentItem.implicitHeight : 0
|
||||
implicitWidth: contentItem && contentItem.implicitWidth? contentItem.implicitWidth: 0
|
||||
function updateComponent(){
|
||||
var item
|
||||
var component = mainItem.text.length != 0 && mainItem.icon.source.toString().length != 0
|
||||
? imageTextComponent
|
||||
: mainItem.text.length != 0
|
||||
? textComponent
|
||||
: mainItem.icon.source.toString().length != 0
|
||||
? imageComponent
|
||||
: emptyComponent
|
||||
if( stacklayout.depth == 0)
|
||||
item = stacklayout.push(component, Control.StackView.Immediate)
|
||||
else if( component != stacklayout.get(0))
|
||||
item = stacklayout.replace(component, Control.StackView.Immediate)
|
||||
if(item){// Workaround for Qt bug : set from the item and not from the contentItem
|
||||
implicitHeight = item.implicitHeight
|
||||
implicitWidth = item.implicitWidth
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
updateComponent()
|
||||
}
|
||||
|
||||
Connections{
|
||||
target: mainItem
|
||||
function onTextChanged(){stacklayout.updateComponent()}
|
||||
function onIconChanged(){stacklayout.updateComponent()}
|
||||
}
|
||||
|
||||
Component{
|
||||
id: imageTextComponent
|
||||
RowLayout {
|
||||
spacing: mainItem.spacing
|
||||
ButtonImage{
|
||||
Layout.preferredWidth: mainItem.icon.width
|
||||
Layout.preferredHeight: mainItem.icon.height
|
||||
}
|
||||
ButtonText{}
|
||||
}
|
||||
}
|
||||
Component{
|
||||
id: textComponent
|
||||
ButtonText {}
|
||||
}
|
||||
Component{
|
||||
id: imageComponent
|
||||
ButtonImage{}
|
||||
}
|
||||
Component{
|
||||
id: emptyComponent
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
contentItem: StackLayout {
|
||||
id: stacklayout
|
||||
currentIndex: mainItem.text.length != 0 && mainItem.icon.source.toString().length != 0
|
||||
|
|
@ -110,7 +180,7 @@ Control.Button {
|
|||
: mainItem.icon.source.toString().length != 0
|
||||
? 2
|
||||
: 3
|
||||
|
||||
|
||||
width: mainItem.width
|
||||
RowLayout {
|
||||
spacing: mainItem.spacing
|
||||
|
|
@ -126,5 +196,5 @@ Control.Button {
|
|||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,176 +10,199 @@ import SettingsCpp
|
|||
// Fill contact, account or call
|
||||
// Initials will be displayed if there isn't any avatar.
|
||||
// TODO : get FriendGui from Call.
|
||||
|
||||
StackView {
|
||||
Loader{
|
||||
id: mainItem
|
||||
property AccountGui account: null
|
||||
property FriendGui contact: null
|
||||
property CallGui call: null
|
||||
property string _address: account
|
||||
? account.core?.identityAddress || ""
|
||||
: call
|
||||
? call.core.peerAddress
|
||||
: contact
|
||||
? contact.core.defaultAddress
|
||||
: ''
|
||||
? account.core?.identityAddress || ""
|
||||
: call
|
||||
? call.core.peerAddress
|
||||
: contact
|
||||
? contact.core.defaultAddress
|
||||
: ''
|
||||
readonly property string address: SettingsCpp.onlyDisplaySipUriUsername ? UtilsCpp.getUsername(_address) : _address
|
||||
property var displayNameObj: UtilsCpp.getDisplayName(_address)
|
||||
property string displayNameVal: displayNameObj ? displayNameObj.value : ""
|
||||
property bool haveAvatar: (account && account.core?.pictureUri || false)
|
||||
|| (contact && contact.core.pictureUri)
|
||||
|| computedAvatarUri.length != 0
|
||||
|| (contact && contact.core.pictureUri)
|
||||
|| computedAvatarUri.length != 0
|
||||
property string computedAvatarUri: UtilsCpp.findAvatarByAddress(_address)
|
||||
|
||||
|
||||
onHaveAvatarChanged: replace(haveAvatar ? avatar : initials, StackView.Immediate)
|
||||
|
||||
|
||||
property var securityLevelObj: UtilsCpp.getFriendAddressSecurityLevel(_address)
|
||||
property var securityLevel: securityLevelObj ? securityLevelObj.value : LinphoneEnums.SecurityLevel.None
|
||||
property bool secured: call && call.core.encryption === LinphoneEnums.MediaEncryption.Zrtp
|
||||
? call.core.tokenVerified
|
||||
: contact
|
||||
? contact.core.devices.length != 0 && contact.core.verifiedDeviceCount === contact.core.devices.length
|
||||
: securityLevel === LinphoneEnums.SecurityLevel.EndToEndEncrypted
|
||||
|
||||
property bool securityBreach: securityLevel === LinphoneEnums.SecurityLevel.Unsafe
|
||||
|
||||
property bool displayPresence: account
|
||||
? account.core?.registrationState != LinphoneEnums.RegistrationState.Progress && account.core?.registrationState != LinphoneEnums.RegistrationState.Refreshing || false
|
||||
: contact
|
||||
? contact.core?.consolidatedPresence != LinphoneEnums.ConsolidatedPresence.Offline || false
|
||||
: false
|
||||
? call.core.tokenVerified
|
||||
: contact
|
||||
? contact.core.devices.length != 0 && contact.core.verifiedDeviceCount === contact.core.devices.length
|
||||
: securityLevel === LinphoneEnums.SecurityLevel.EndToEndEncrypted
|
||||
|
||||
initialItem: haveAvatar ? avatar : initials
|
||||
|
||||
Rectangle {
|
||||
visible: mainItem.secured || mainItem.securityBreach
|
||||
anchors.fill: mainItem.currentItem
|
||||
radius: mainItem.width / 2
|
||||
z: 1
|
||||
color: "transparent"
|
||||
border {
|
||||
width: 3 * DefaultStyle.dp
|
||||
color: mainItem.secured ? DefaultStyle.info_500_main : DefaultStyle.danger_500main
|
||||
}
|
||||
Image {
|
||||
source: mainItem.secured ? AppIcons.trusted : AppIcons.notTrusted
|
||||
x: mainItem.width / 7
|
||||
width: mainItem.width / 4.5
|
||||
height: width
|
||||
sourceSize.width: width
|
||||
sourceSize.height: height
|
||||
fillMode: Image.PreserveAspectFit
|
||||
anchors.bottom: parent.bottom
|
||||
}
|
||||
}
|
||||
Rectangle {
|
||||
visible: mainItem.displayPresence
|
||||
width: mainItem.width/4.5
|
||||
height: width
|
||||
radius: width / 2
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: mainItem.width / 15
|
||||
z: 1
|
||||
color: account
|
||||
? account.core?.registrationState == LinphoneEnums.RegistrationState.Ok
|
||||
? DefaultStyle.success_500main
|
||||
: account.core?.registrationState == LinphoneEnums.RegistrationState.Cleared || account.core?.registrationState == LinphoneEnums.RegistrationState.None
|
||||
? DefaultStyle.warning_600
|
||||
: account.core?.registrationState == LinphoneEnums.RegistrationState.Progress || account.core?.registrationState == LinphoneEnums.RegistrationState.Refreshing
|
||||
? DefaultStyle.main2_500main
|
||||
: DefaultStyle.danger_500main
|
||||
: contact
|
||||
? contact.core.consolidatedPresence === LinphoneEnums.ConsolidatedPresence.Online
|
||||
? DefaultStyle.success_500main
|
||||
: contact.core.consolidatedPresence === LinphoneEnums.ConsolidatedPresence.Busy
|
||||
? DefaultStyle.warning_600
|
||||
: contact.core.consolidatedPresence === LinphoneEnums.ConsolidatedPresence.DoNotDisturb
|
||||
? DefaultStyle.danger_500main
|
||||
: DefaultStyle.main2_500main
|
||||
: "transparent"
|
||||
border {
|
||||
width: 2 * DefaultStyle.dp
|
||||
color: DefaultStyle.grey_0
|
||||
}
|
||||
}
|
||||
Component{
|
||||
id: initials
|
||||
property bool securityBreach: securityLevel === LinphoneEnums.SecurityLevel.Unsafe
|
||||
|
||||
property bool displayPresence: account
|
||||
? account.core?.registrationState != LinphoneEnums.RegistrationState.Progress && account.core?.registrationState != LinphoneEnums.RegistrationState.Refreshing || false
|
||||
: contact
|
||||
? contact.core?.consolidatedPresence != LinphoneEnums.ConsolidatedPresence.Offline || false
|
||||
: false
|
||||
|
||||
|
||||
asynchronous: true
|
||||
sourceComponent: Component{
|
||||
Item {
|
||||
id: avatarItem
|
||||
height: mainItem.height
|
||||
width: height
|
||||
Rectangle {
|
||||
id: initialItem
|
||||
property string initials: UtilsCpp.getInitials(mainItem.displayNameVal)
|
||||
radius: width / 2
|
||||
color: DefaultStyle.main2_200
|
||||
height: mainItem.height
|
||||
width: height
|
||||
Text {
|
||||
anchors.fill: parent
|
||||
anchors.centerIn: parent
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
text: initialItem.initials
|
||||
font {
|
||||
pixelSize: initialItem.height * 36 / 120
|
||||
weight: 800 * DefaultStyle.dp
|
||||
capitalization: Font.AllUppercase
|
||||
}
|
||||
}
|
||||
Image {
|
||||
id: initialImg
|
||||
visible: initialItem.initials == ''
|
||||
width: mainItem.width/3
|
||||
height: width
|
||||
source: AppIcons.profile
|
||||
sourceSize.width: width
|
||||
sourceSize.height: height
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
}
|
||||
anchors.fill: parent
|
||||
|
||||
MultiEffect {
|
||||
source: initialItem
|
||||
anchors.fill: initialItem
|
||||
source: stackView
|
||||
anchors.fill: stackView
|
||||
shadowEnabled: true
|
||||
shadowBlur: 0.1
|
||||
shadowColor: DefaultStyle.grey_1000
|
||||
shadowOpacity: 0.1
|
||||
}
|
||||
}
|
||||
}
|
||||
Component{
|
||||
id: avatar
|
||||
Item {
|
||||
id: avatarItem
|
||||
height: mainItem.height
|
||||
width: height
|
||||
Image {
|
||||
id: image
|
||||
visible: false
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
sourceSize.width: avatarItem.width
|
||||
sourceSize.height: avatarItem.height
|
||||
fillMode: Image.PreserveAspectCrop
|
||||
anchors.centerIn: parent
|
||||
source: mainItem.account && mainItem.account.core.pictureUri
|
||||
|| mainItem.contact && mainItem.contact.core.pictureUri
|
||||
|| computedAvatarUri
|
||||
mipmap: true
|
||||
layer.enabled: true
|
||||
}
|
||||
ShaderEffect {
|
||||
id: roundEffect
|
||||
property variant src: image
|
||||
property real edge: 0.9
|
||||
property real edgeSoftness: 0.9
|
||||
property real radius: width / 2.0
|
||||
property real shadowSoftness: 0.5
|
||||
property real shadowOffset: 0.01
|
||||
StackView {
|
||||
id: stackView
|
||||
|
||||
initialItem: haveAvatar ? avatar : initials
|
||||
anchors.fill: parent
|
||||
fragmentShader: 'qrc:/data/shaders/roundEffect.frag.qsb'
|
||||
Rectangle {
|
||||
visible: mainItem.secured || mainItem.securityBreach
|
||||
anchors.fill: stackView.currentItem
|
||||
radius: stackView.width / 2
|
||||
z: 1
|
||||
color: "transparent"
|
||||
border {
|
||||
width: 3 * DefaultStyle.dp
|
||||
color: mainItem.secured ? DefaultStyle.info_500_main : DefaultStyle.danger_500main
|
||||
}
|
||||
Image {
|
||||
x: stackView.width / 7
|
||||
anchors.bottom: parent.bottom
|
||||
width: stackView.width / 4.5
|
||||
height: width
|
||||
asynchronous: true
|
||||
source: mainItem.secured ? AppIcons.trusted : AppIcons.notTrusted
|
||||
sourceSize.width: width
|
||||
sourceSize.height: height
|
||||
fillMode: Image.PreserveAspectFit
|
||||
|
||||
}
|
||||
}
|
||||
Rectangle {
|
||||
visible: mainItem.displayPresence
|
||||
width: stackView.width/4.5
|
||||
height: width
|
||||
radius: width / 2
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: stackView.width / 15
|
||||
z: 1
|
||||
color: account
|
||||
? account.core?.registrationState == LinphoneEnums.RegistrationState.Ok
|
||||
? DefaultStyle.success_500main
|
||||
: account.core?.registrationState == LinphoneEnums.RegistrationState.Cleared || account.core?.registrationState == LinphoneEnums.RegistrationState.None
|
||||
? DefaultStyle.warning_600
|
||||
: account.core?.registrationState == LinphoneEnums.RegistrationState.Progress || account.core?.registrationState == LinphoneEnums.RegistrationState.Refreshing
|
||||
? DefaultStyle.main2_500main
|
||||
: DefaultStyle.danger_500main
|
||||
: contact
|
||||
? contact.core.consolidatedPresence === LinphoneEnums.ConsolidatedPresence.Online
|
||||
? DefaultStyle.success_500main
|
||||
: contact.core.consolidatedPresence === LinphoneEnums.ConsolidatedPresence.Busy
|
||||
? DefaultStyle.warning_600
|
||||
: contact.core.consolidatedPresence === LinphoneEnums.ConsolidatedPresence.DoNotDisturb
|
||||
? DefaultStyle.danger_500main
|
||||
: DefaultStyle.main2_500main
|
||||
: "transparent"
|
||||
border {
|
||||
width: 2 * DefaultStyle.dp
|
||||
color: DefaultStyle.grey_0
|
||||
}
|
||||
}
|
||||
|
||||
Component{
|
||||
id: initials
|
||||
Item {
|
||||
id: avatarItem
|
||||
height: stackView.height
|
||||
width: height
|
||||
Rectangle {
|
||||
id: initialItem
|
||||
property string initials: UtilsCpp.getInitials(mainItem.displayNameVal)
|
||||
radius: width / 2
|
||||
color: DefaultStyle.main2_200
|
||||
height: stackView.height
|
||||
width: height
|
||||
Text {
|
||||
anchors.fill: parent
|
||||
anchors.centerIn: parent
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
text: initialItem.initials
|
||||
font {
|
||||
pixelSize: initialItem.height * 36 / 120
|
||||
weight: 800 * DefaultStyle.dp
|
||||
capitalization: Font.AllUppercase
|
||||
}
|
||||
}
|
||||
Image {
|
||||
id: initialImg
|
||||
visible: initialItem.initials == ''
|
||||
width: stackView.width/3
|
||||
height: width
|
||||
source: AppIcons.profile
|
||||
sourceSize.width: width
|
||||
sourceSize.height: height
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
}
|
||||
MultiEffect {
|
||||
source: initialItem
|
||||
anchors.fill: initialItem
|
||||
shadowEnabled: true
|
||||
shadowBlur: 0.1
|
||||
shadowColor: DefaultStyle.grey_1000
|
||||
shadowOpacity: 0.1
|
||||
}
|
||||
}
|
||||
}
|
||||
Component{
|
||||
id: avatar
|
||||
Item {
|
||||
id: avatarItem
|
||||
height: stackView.height
|
||||
width: height
|
||||
Image {
|
||||
id: image
|
||||
visible: false
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
sourceSize.width: avatarItem.width
|
||||
sourceSize.height: avatarItem.height
|
||||
fillMode: Image.PreserveAspectCrop
|
||||
anchors.centerIn: parent
|
||||
source: mainItem.account && mainItem.account.core.pictureUri
|
||||
|| mainItem.contact && mainItem.contact.core.pictureUri
|
||||
|| computedAvatarUri
|
||||
mipmap: true
|
||||
layer.enabled: true
|
||||
}
|
||||
ShaderEffect {
|
||||
id: roundEffect
|
||||
property variant src: image
|
||||
property real edge: 0.9
|
||||
property real edgeSoftness: 0.9
|
||||
property real radius: width / 2.0
|
||||
property real shadowSoftness: 0.5
|
||||
property real shadowOffset: 0.01
|
||||
anchors.fill: parent
|
||||
fragmentShader: 'qrc:/data/shaders/roundEffect.frag.qsb'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -275,7 +275,7 @@ ListView {
|
|||
|
||||
popup.contentItem: ColumnLayout {
|
||||
Button {
|
||||
text: modelData.core.starred ? qsTr("Enlever des favoris") : qsTr("Mettre en favori")
|
||||
text: $modelData.core.starred ? qsTr("Enlever des favoris") : qsTr("Mettre en favori")
|
||||
background: Item{}
|
||||
icon.source: modelData.core.starred ? AppIcons.heartFill : AppIcons.heart
|
||||
icon.width: 24 * DefaultStyle.dp
|
||||
|
|
|
|||
|
|
@ -17,7 +17,8 @@ Loader {
|
|||
property int imageHeight: height
|
||||
property bool useColor: colorizationColor != undefined
|
||||
property bool shadowEnabled: false
|
||||
sourceComponent: Item {
|
||||
asynchronous: true
|
||||
sourceComponent: Component{Item {
|
||||
Image {
|
||||
id: image
|
||||
visible: !effect2.effectEnabled
|
||||
|
|
@ -80,4 +81,5 @@ Loader {
|
|||
shadowOpacity: mainItem.shadowEnabled ? 0.7 : 0.0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,8 +16,12 @@ ListView {
|
|||
property var delegateButtons
|
||||
property ConferenceInfoGui selectedConference: model && currentIndex != -1 ? model.getAt(currentIndex) : null
|
||||
|
||||
signal conferenceSelected(var contact)
|
||||
|
||||
spacing: 8 * DefaultStyle.dp
|
||||
currentIndex: confInfoProxy.currentDateIndex
|
||||
// using highlight doesn't center, take time before moving and don't work for not visible item (like not loaded)
|
||||
highlightFollowsCurrentItem: false
|
||||
|
||||
onCountChanged: selectedConference = model && currentIndex != -1 && currentIndex < model.count ? model.getAt(currentIndex) : null
|
||||
onCurrentIndexChanged: {
|
||||
|
|
@ -27,20 +31,20 @@ ListView {
|
|||
mainItem.positionViewAtIndex(currentIndex, ListView.Center)// First approximative move
|
||||
delayMove.restart() // Move to exact position after load.
|
||||
}
|
||||
onAtYEndChanged: if(atYEnd) confInfoProxy.displayMore()
|
||||
|
||||
Timer{
|
||||
id: delayMove
|
||||
interval: 60
|
||||
onTriggered: mainItem.positionViewAtIndex(currentIndex, ListView.Center)
|
||||
}
|
||||
// using highlight doesn't center, take time before moving and don't work for not visible item (like not loaded)
|
||||
highlightFollowsCurrentItem: false
|
||||
|
||||
signal conferenceSelected(var contact)
|
||||
|
||||
|
||||
model: ConferenceInfoProxy {
|
||||
id: confInfoProxy
|
||||
searchText: searchBarText
|
||||
filterText: searchBarText
|
||||
filterType: ConferenceInfoProxy.None
|
||||
initialDisplayItems: mainItem.height / (63 * DefaultStyle.dp) + 5
|
||||
displayItemsStep: initialDisplayItems/2
|
||||
}
|
||||
|
||||
section {
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ Window{
|
|||
|
||||
model: MagicSearchProxy{
|
||||
id: search
|
||||
searchText: ''
|
||||
filterText: ''
|
||||
}
|
||||
delegate: Rectangle{
|
||||
height: 50
|
||||
|
|
@ -92,7 +92,7 @@ Window{
|
|||
text: 'Get'
|
||||
Layout.rightMargin: 20
|
||||
onClicked: {
|
||||
search.searchText = '*'
|
||||
search.filterText = '*'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -162,6 +162,26 @@ AbstractSettingsLayout {
|
|||
}
|
||||
}
|
||||
}
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 35 * DefaultStyle.dp
|
||||
Layout.bottomMargin: 9 * DefaultStyle.dp
|
||||
height: 1 * DefaultStyle.dp
|
||||
color: DefaultStyle.main2_500main
|
||||
}
|
||||
RowLayout {
|
||||
Layout.topMargin: 16 * DefaultStyle.dp
|
||||
spacing: 5 * DefaultStyle.dp
|
||||
Item {
|
||||
Layout.preferredWidth: 341 * DefaultStyle.dp
|
||||
}
|
||||
SwitchSetting {
|
||||
Layout.rightMargin: 44 * DefaultStyle.dp
|
||||
titleText:qsTr("Cacher les FPS")
|
||||
propertyName: "hideFps"
|
||||
propertyOwner: SettingsCpp
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -242,10 +242,13 @@ AbstractMainPage {
|
|||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
model: CallHistoryProxy {
|
||||
id: callHistoryProxy
|
||||
filterText: searchBar.text
|
||||
onFilterTextChanged: maxDisplayItems = initialDisplayItems
|
||||
initialDisplayItems: historyListView.height / (56 * DefaultStyle.dp) + 5
|
||||
displayItemsStep: initialDisplayItems / 2
|
||||
}
|
||||
|
||||
currentIndex: -1
|
||||
cacheBuffer: contentHeight>0 ? contentHeight : 0// cache all items
|
||||
flickDeceleration: 10000
|
||||
spacing: 10 * DefaultStyle.dp
|
||||
highlightFollowsCurrentItem: true
|
||||
|
|
@ -267,145 +270,137 @@ AbstractMainPage {
|
|||
historyListView.model.removeAllEntries()
|
||||
}
|
||||
}
|
||||
|
||||
onAtYEndChanged: if(atYEnd) callHistoryProxy.displayMore()
|
||||
delegate: FocusScope {
|
||||
width:historyListView.width
|
||||
height: 56 * DefaultStyle.dp
|
||||
anchors.topMargin: 5 * DefaultStyle.dp
|
||||
anchors.bottomMargin: 5 * DefaultStyle.dp
|
||||
RowLayout {
|
||||
z: 1
|
||||
anchors.fill: parent
|
||||
spacing: 10 * DefaultStyle.dp
|
||||
Item {
|
||||
Layout.preferredWidth: historyAvatar.width
|
||||
Layout.preferredHeight: historyAvatar.height
|
||||
Layout.leftMargin: 5 * DefaultStyle.dp
|
||||
MultiEffect {
|
||||
source: historyAvatar
|
||||
anchors.fill: historyAvatar
|
||||
shadowEnabled: true
|
||||
shadowBlur: 0.1
|
||||
shadowColor: DefaultStyle.grey_1000
|
||||
shadowOpacity: 0.1
|
||||
}
|
||||
width:historyListView.width
|
||||
height: 56 * DefaultStyle.dp
|
||||
anchors.topMargin: 5 * DefaultStyle.dp
|
||||
anchors.bottomMargin: 5 * DefaultStyle.dp
|
||||
visible: !!modelData
|
||||
RowLayout {
|
||||
z: 1
|
||||
anchors.fill: parent
|
||||
spacing: 10 * DefaultStyle.dp
|
||||
Avatar {
|
||||
id: historyAvatar
|
||||
_address: modelData.core.remoteAddress
|
||||
width: 45 * DefaultStyle.dp
|
||||
height: 45 * DefaultStyle.dp
|
||||
}
|
||||
}
|
||||
ColumnLayout {
|
||||
Layout.fillHeight: true
|
||||
Layout.fillWidth: true
|
||||
spacing: 5 * DefaultStyle.dp
|
||||
Text {
|
||||
id: friendAddress
|
||||
ColumnLayout {
|
||||
Layout.fillHeight: true
|
||||
Layout.fillWidth: true
|
||||
maximumLineCount: 1
|
||||
text: modelData.core.displayName
|
||||
font {
|
||||
pixelSize: 14 * DefaultStyle.dp
|
||||
weight: 400 * DefaultStyle.dp
|
||||
capitalization: Font.Capitalize
|
||||
spacing: 5 * DefaultStyle.dp
|
||||
Text {
|
||||
id: friendAddress
|
||||
Layout.fillWidth: true
|
||||
maximumLineCount: 1
|
||||
text: modelData.core.displayName
|
||||
font {
|
||||
pixelSize: 14 * DefaultStyle.dp
|
||||
weight: 400 * DefaultStyle.dp
|
||||
capitalization: Font.Capitalize
|
||||
}
|
||||
}
|
||||
}
|
||||
RowLayout {
|
||||
spacing: 6 * DefaultStyle.dp
|
||||
EffectImage {
|
||||
id: statusIcon
|
||||
imageSource: modelData.core.status === LinphoneEnums.CallStatus.Declined
|
||||
|| modelData.core.status === LinphoneEnums.CallStatus.DeclinedElsewhere
|
||||
|| modelData.core.status === LinphoneEnums.CallStatus.Aborted
|
||||
|| modelData.core.status === LinphoneEnums.CallStatus.EarlyAborted
|
||||
? AppIcons.arrowElbow
|
||||
: modelData.core.isOutgoing
|
||||
? AppIcons.arrowUpRight
|
||||
: AppIcons.arrowDownLeft
|
||||
colorizationColor: 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.status === LinphoneEnums.CallStatus.Missed
|
||||
? DefaultStyle.danger_500main
|
||||
: modelData.core.isOutgoing
|
||||
? DefaultStyle.info_500_main
|
||||
: DefaultStyle.success_500main
|
||||
Layout.preferredWidth: 12 * DefaultStyle.dp
|
||||
Layout.preferredHeight: 12 * DefaultStyle.dp
|
||||
transform: Rotation {
|
||||
angle: modelData.core.isOutgoing && (modelData.core.status === LinphoneEnums.CallStatus.Declined
|
||||
|| modelData.core.status === LinphoneEnums.CallStatus.DeclinedElsewhere
|
||||
|| modelData.core.status === LinphoneEnums.CallStatus.Aborted
|
||||
|| modelData.core.status === LinphoneEnums.CallStatus.EarlyAborted) ? 180 : 0
|
||||
origin {
|
||||
x: statusIcon.width/2
|
||||
y: statusIcon.height/2
|
||||
RowLayout {
|
||||
spacing: 6 * DefaultStyle.dp
|
||||
EffectImage {
|
||||
id: statusIcon
|
||||
imageSource: modelData.core.status === LinphoneEnums.CallStatus.Declined
|
||||
|| modelData.core.status === LinphoneEnums.CallStatus.DeclinedElsewhere
|
||||
|| modelData.core.status === LinphoneEnums.CallStatus.Aborted
|
||||
|| modelData.core.status === LinphoneEnums.CallStatus.EarlyAborted
|
||||
? AppIcons.arrowElbow
|
||||
: modelData.core.isOutgoing
|
||||
? AppIcons.arrowUpRight
|
||||
: AppIcons.arrowDownLeft
|
||||
colorizationColor: 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.status === LinphoneEnums.CallStatus.Missed
|
||||
? DefaultStyle.danger_500main
|
||||
: modelData.core.isOutgoing
|
||||
? DefaultStyle.info_500_main
|
||||
: DefaultStyle.success_500main
|
||||
Layout.preferredWidth: 12 * DefaultStyle.dp
|
||||
Layout.preferredHeight: 12 * DefaultStyle.dp
|
||||
transform: Rotation {
|
||||
angle: modelData.core.isOutgoing && (modelData.core.status === LinphoneEnums.CallStatus.Declined
|
||||
|| modelData.core.status === LinphoneEnums.CallStatus.DeclinedElsewhere
|
||||
|| modelData.core.status === LinphoneEnums.CallStatus.Aborted
|
||||
|| modelData.core.status === LinphoneEnums.CallStatus.EarlyAborted) ? 180 : 0
|
||||
origin {
|
||||
x: statusIcon.width/2
|
||||
y: statusIcon.height/2
|
||||
}
|
||||
}
|
||||
}
|
||||
Text {
|
||||
// text: modelData.core.date
|
||||
text: UtilsCpp.formatDate(modelData.core.date)
|
||||
font {
|
||||
pixelSize: 12 * DefaultStyle.dp
|
||||
weight: 300 * DefaultStyle.dp
|
||||
}
|
||||
}
|
||||
}
|
||||
Text {
|
||||
// text: modelData.core.date
|
||||
text: UtilsCpp.formatDate(modelData.core.date, true)
|
||||
font {
|
||||
pixelSize: 12 * DefaultStyle.dp
|
||||
weight: 300 * DefaultStyle.dp
|
||||
}
|
||||
Button {
|
||||
Layout.rightMargin: 5 * DefaultStyle.dp
|
||||
padding: 0
|
||||
background: Item {
|
||||
visible: false
|
||||
}
|
||||
icon.source: AppIcons.phone
|
||||
Layout.preferredWidth: 24 * DefaultStyle.dp
|
||||
Layout.preferredHeight: 24 * DefaultStyle.dp
|
||||
icon.width: 24 * DefaultStyle.dp
|
||||
icon.height: 24 * DefaultStyle.dp
|
||||
focus: true
|
||||
activeFocusOnTab: false
|
||||
onClicked: {
|
||||
if (modelData.core.isConference) {
|
||||
var callsWindow = UtilsCpp.getCallsWindow()
|
||||
callsWindow.setupConference(modelData.core.conferenceInfo)
|
||||
callsWindow.show()
|
||||
}
|
||||
else {
|
||||
UtilsCpp.createCall(modelData.core.remoteAddress)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Button {
|
||||
Layout.rightMargin: 5 * DefaultStyle.dp
|
||||
padding: 0
|
||||
background: Item {
|
||||
visible: false
|
||||
}
|
||||
icon.source: AppIcons.phone
|
||||
Layout.preferredWidth: 24 * DefaultStyle.dp
|
||||
Layout.preferredHeight: 24 * DefaultStyle.dp
|
||||
icon.width: 24 * DefaultStyle.dp
|
||||
icon.height: 24 * DefaultStyle.dp
|
||||
MouseArea {
|
||||
hoverEnabled: true
|
||||
anchors.fill: parent
|
||||
focus: true
|
||||
activeFocusOnTab: false
|
||||
onClicked: {
|
||||
if (modelData.core.isConference) {
|
||||
var callsWindow = UtilsCpp.getCallsWindow()
|
||||
callsWindow.setupConference(modelData.core.conferenceInfo)
|
||||
callsWindow.show()
|
||||
}
|
||||
else {
|
||||
UtilsCpp.createCall(modelData.core.remoteAddress)
|
||||
}
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
opacity: 0.1
|
||||
color: DefaultStyle.main2_500main
|
||||
visible: parent.containsMouse
|
||||
}
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
visible: historyListView.currentIndex === model.index
|
||||
color: DefaultStyle.main2_100
|
||||
}
|
||||
onPressed: {
|
||||
historyListView.currentIndex = model.index
|
||||
historyListView.forceActiveFocus()
|
||||
}
|
||||
}
|
||||
}
|
||||
MouseArea {
|
||||
hoverEnabled: true
|
||||
anchors.fill: parent
|
||||
focus: true
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
opacity: 0.1
|
||||
color: DefaultStyle.main2_500main
|
||||
visible: parent.containsMouse
|
||||
}
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
visible: historyListView.currentIndex === model.index
|
||||
color: DefaultStyle.main2_100
|
||||
}
|
||||
onPressed: {
|
||||
historyListView.currentIndex = model.index
|
||||
historyListView.forceActiveFocus()
|
||||
}
|
||||
}
|
||||
}
|
||||
//}
|
||||
//}
|
||||
onCurrentIndexChanged: {
|
||||
positionViewAtIndex(currentIndex, ListView.Visible)
|
||||
mainItem.selectedRowHistoryGui = model.getAt(currentIndex)
|
||||
}
|
||||
onCountChanged: mainItem.selectedRowHistoryGui = model.getAt(currentIndex)
|
||||
onCountChanged: {
|
||||
mainItem.selectedRowHistoryGui = model.getAt(currentIndex)
|
||||
}
|
||||
onVisibleChanged: {
|
||||
if (!visible) currentIndex = -1
|
||||
}
|
||||
|
|
|
|||
|
|
@ -188,7 +188,6 @@ AbstractMainPage {
|
|||
Layout.topMargin: 38 * DefaultStyle.dp - 24 * DefaultStyle.dp
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
visible: count != 0
|
||||
hoverEnabled: mainItem.leftPanelEnabled
|
||||
highlightFollowsCurrentItem: true
|
||||
preferredHighlightBegin: height/2 - 10
|
||||
|
|
|
|||
|
|
@ -249,4 +249,19 @@ ApplicationWindow {
|
|||
underlineColor: DefaultStyle.main1_500_main
|
||||
radius: 15 * DefaultStyle.dp
|
||||
}
|
||||
FPSCounter{
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
height: 50
|
||||
width: 120
|
||||
z: 100
|
||||
visible: !SettingsCpp.hideFps
|
||||
Text{
|
||||
font.bold: true
|
||||
font.italic: true
|
||||
font.pixelSize: 14 * DefaultStyle.dp
|
||||
text: parent.fps + " FPS"
|
||||
color: parent.fps < 30 ? DefaultStyle.danger_500main : DefaultStyle.main2_900
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue