diff --git a/Linphone/core/CMakeLists.txt b/Linphone/core/CMakeLists.txt index 05134bf97..92c8a0df4 100644 --- a/Linphone/core/CMakeLists.txt +++ b/Linphone/core/CMakeLists.txt @@ -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 diff --git a/Linphone/core/account/AccountDeviceProxy.cpp b/Linphone/core/account/AccountDeviceProxy.cpp index 8a29f4338..a5e18a2d2 100644 --- a/Linphone/core/account/AccountDeviceProxy.cpp +++ b/Linphone/core/account/AccountDeviceProxy.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()->getCore(); - auto deviceB = sourceModel()->data(right).value()->getCore(); - - return left.row() < right.row(); +bool AccountDeviceProxy::SortFilterList::lessThan(const QModelIndex &sourceLeft, const QModelIndex &sourceRight) const { + return sourceLeft.row() < sourceRight.row(); } diff --git a/Linphone/core/account/AccountDeviceProxy.hpp b/Linphone/core/account/AccountDeviceProxy.hpp index 1fbd99ea9..b4139b30d 100644 --- a/Linphone/core/account/AccountDeviceProxy.hpp +++ b/Linphone/core/account/AccountDeviceProxy.hpp @@ -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(); diff --git a/Linphone/core/account/AccountProxy.cpp b/Linphone/core/account/AccountProxy.cpp index d3e32ea55..8af029ff4 100644 --- a/Linphone/core/account/AccountProxy.cpp +++ b/Linphone/core/account/AccountProxy.cpp @@ -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(sourceModel())->getDefaultAccountCore(); + if (!mDefaultAccount) + mDefaultAccount = dynamic_cast(dynamic_cast(sourceModel())->sourceModel()) + ->getDefaultAccountCore(); return new AccountGui(mDefaultAccount); } @@ -59,19 +48,19 @@ void AccountProxy::resetDefaultAccount() { } AccountGui *AccountProxy::findAccountByAddress(const QString &address) { - return dynamic_cast(sourceModel())->findAccountByAddress(address); + return getListModel()->findAccountByAddress(address); } AccountGui *AccountProxy::firstAccount() { - return dynamic_cast(sourceModel())->firstAccount(); + return getListModel()->firstAccount(); } bool AccountProxy::getHaveAccount() const { - return dynamic_cast(sourceModel())->getHaveAccount(); + return getListModel()->getHaveAccount(); } void AccountProxy::setSourceModel(QAbstractItemModel *model) { - auto oldAccountList = dynamic_cast(sourceModel()); + auto oldAccountList = getListModel(); 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(); - show = account->getCore()->getIdentityAddress().contains(search); + auto account = getItemAtSource(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(sourceLeft.row()); + auto r = getItemAtSource(sourceRight.row()); - return l.value()->getCore()->getIdentityAddress() < - r.value()->getCore()->getIdentityAddress(); + return l->getIdentityAddress() < r->getIdentityAddress(); } diff --git a/Linphone/core/account/AccountProxy.hpp b/Linphone/core/account/AccountProxy.hpp index 0a1a03013..601baa2bf 100644 --- a/Linphone/core/account/AccountProxy.hpp +++ b/Linphone/core/account/AccountProxy.hpp @@ -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 mDefaultAccount; // When null, a new UI object is build from List }; diff --git a/Linphone/core/address-books/carddav/CarddavProxy.cpp b/Linphone/core/address-books/carddav/CarddavProxy.cpp index d7559784e..dbaa9c3fe 100644 --- a/Linphone/core/address-books/carddav/CarddavProxy.cpp +++ b/Linphone/core/address-books/carddav/CarddavProxy.cpp @@ -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(sourceModel())->removeAllEntries(); } void CarddavProxy::removeEntriesWithFilter() { - std::list> itemList(rowCount()); + QList> itemList(rowCount()); for (auto i = rowCount() - 1; i >= 0; --i) { - auto item = getItemAt(i); - itemList.emplace_back(item); + auto item = getItemAt(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(left.row()); - auto r = getItemAt(right.row()); +bool CarddavProxy::SortFilterList::lessThan(const QModelIndex &sourceLeft, const QModelIndex &sourceRight) const { + auto l = getItemAtSource(sourceLeft.row()); + auto r = getItemAtSource(sourceRight.row()); return l->mDisplayName < r->mDisplayName; } diff --git a/Linphone/core/address-books/carddav/CarddavProxy.hpp b/Linphone/core/address-books/carddav/CarddavProxy.hpp index 143616203..fa7971c8f 100644 --- a/Linphone/core/address-books/carddav/CarddavProxy.hpp +++ b/Linphone/core/address-books/carddav/CarddavProxy.hpp @@ -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 mCarddavList; DECLARE_ABSTRACT_OBJECT diff --git a/Linphone/core/address-books/ldap/LdapProxy.cpp b/Linphone/core/address-books/ldap/LdapProxy.cpp index ecdb2d6ad..f74cedde8 100644 --- a/Linphone/core/address-books/ldap/LdapProxy.cpp +++ b/Linphone/core/address-books/ldap/LdapProxy.cpp @@ -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(sourceModel())->removeAllEntries(); + getListModel()->removeAllEntries(); } void LdapProxy::removeEntriesWithFilter() { - std::list> itemList(rowCount()); + QList> itemList(rowCount()); for (auto i = rowCount() - 1; i >= 0; --i) { - auto item = getItemAt(i); - itemList.emplace_back(item); + auto item = getItemAt(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(left.row()); - auto r = getItemAt(right.row()); +bool LdapProxy::SortFilterList::lessThan(const QModelIndex &sourceLeft, const QModelIndex &sourceRight) const { + auto l = getItemAtSource(sourceLeft.row()); + auto r = getItemAtSource(sourceRight.row()); return l->mSipDomain < r->mSipDomain; } diff --git a/Linphone/core/address-books/ldap/LdapProxy.hpp b/Linphone/core/address-books/ldap/LdapProxy.hpp index 4295063ab..cf0e75370 100644 --- a/Linphone/core/address-books/ldap/LdapProxy.hpp +++ b/Linphone/core/address-books/ldap/LdapProxy.hpp @@ -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 mLdapList; DECLARE_ABSTRACT_OBJECT diff --git a/Linphone/core/call-history/CallHistoryList.cpp b/Linphone/core/call-history/CallHistoryList.cpp index 88dad89bf..11855facf 100644 --- a/Linphone/core/call-history/CallHistoryList.cpp +++ b/Linphone/core/call-history/CallHistoryList.cpp @@ -73,6 +73,18 @@ void CallHistoryList::setSelf(QSharedPointer 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(); + 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(); + } +} +*/ diff --git a/Linphone/core/call-history/CallHistoryList.hpp b/Linphone/core/call-history/CallHistoryList.hpp index dcb2ae9a4..98f686852 100644 --- a/Linphone/core/call-history/CallHistoryList.hpp +++ b/Linphone/core/call-history/CallHistoryList.hpp @@ -54,6 +54,7 @@ public: // roles[Qt::DisplayRole + 2] = "date"; // return roles; // } + //void displayMore(); signals: void lUpdate(); diff --git a/Linphone/core/call-history/CallHistoryProxy.cpp b/Linphone/core/call-history/CallHistoryProxy.cpp index ea368d6f0..d1ef23296 100644 --- a/Linphone/core/call-history/CallHistoryProxy.cpp +++ b/Linphone/core/call-history/CallHistoryProxy.cpp @@ -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(sourceModel())->removeAllEntries(); + mHistoryList->removeAllEntries(); } void CallHistoryProxy::removeEntriesWithFilter() { - std::list> itemList(rowCount()); + QList> itemList(rowCount()); for (auto i = rowCount() - 1; i >= 0; --i) { - auto item = getItemAt(i); - itemList.emplace_back(item); + auto item = getItemAt(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(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(left.row()); - auto r = getItemAt(right.row()); +bool CallHistoryProxy::SortFilterList::lessThan(const QModelIndex &sourceLeft, const QModelIndex &sourceRight) const { + auto l = getItemAtSource(sourceLeft.row()); + auto r = getItemAtSource(sourceRight.row()); return l->mDate < r->mDate; } diff --git a/Linphone/core/call-history/CallHistoryProxy.hpp b/Linphone/core/call-history/CallHistoryProxy.hpp index 628fcc68c..8bbb5d636 100644 --- a/Linphone/core/call-history/CallHistoryProxy.hpp +++ b/Linphone/core/call-history/CallHistoryProxy.hpp @@ -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 // ============================================================================= -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 mHistoryList; DECLARE_ABSTRACT_OBJECT diff --git a/Linphone/core/call/CallProxy.cpp b/Linphone/core/call/CallProxy.cpp index 0f14f670d..43140c0d0 100644 --- a/Linphone/core/call/CallProxy.cpp +++ b/Linphone/core/call/CallProxy.cpp @@ -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(sourceModel())->getCurrentCall(); + auto model = getListModel(); + if (!mCurrentCall && model) mCurrentCall = model->getCurrentCall(); return mCurrentCall; } void CallProxy::setCurrentCall(CallGui *call) { - dynamic_cast(sourceModel())->setCurrentCall(call->mCore); + getListModel()->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(sourceModel())->getHaveCall(); + return getListModel()->getHaveCall(); } void CallProxy::setSourceModel(QAbstractItemModel *model) { - auto oldCallList = dynamic_cast(sourceModel()); + auto oldCallList = getListModel(); 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(); - show = call->getCore()->getPeerAddress().contains(search); + auto call = qobject_cast(sourceModel())->getAt(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(sourceLeft.row()); + auto r = getItemAtSource(sourceRight.row()); - return l.value()->getCore()->getPeerAddress() < r.value()->getCore()->getPeerAddress(); + return l->getPeerAddress() < r->getPeerAddress(); } diff --git a/Linphone/core/call/CallProxy.hpp b/Linphone/core/call/CallProxy.hpp index 40bcf78f1..591d0a06f 100644 --- a/Linphone/core/call/CallProxy.hpp +++ b/Linphone/core/call/CallProxy.hpp @@ -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 diff --git a/Linphone/core/conference/ConferenceInfoProxy.cpp b/Linphone/core/conference/ConferenceInfoProxy.cpp index f1c7f3f45..b7f8063b4 100644 --- a/Linphone/core/conference/ConferenceInfoProxy.cpp +++ b/Linphone/core/conference/ConferenceInfoProxy.cpp @@ -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(sourceModel())->template getAt(sourceRow); +bool ConferenceInfoProxy::SortFilterList::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const { + auto list = qobject_cast(sourceModel()); + auto ciCore = list->getAt(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 +} diff --git a/Linphone/core/conference/ConferenceInfoProxy.hpp b/Linphone/core/conference/ConferenceInfoProxy.hpp index df76d0ae4..d9e6acb67 100644 --- a/Linphone/core/conference/ConferenceInfoProxy.hpp +++ b/Linphone/core/conference/ConferenceInfoProxy.hpp @@ -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 mList; int mCurrentDateIndex = -1; + DECLARE_ABSTRACT_OBJECT }; diff --git a/Linphone/core/fps-counter/FPSCounter.cpp b/Linphone/core/fps-counter/FPSCounter.cpp index b6fbdc912..8040772c2 100644 --- a/Linphone/core/fps-counter/FPSCounter.cpp +++ b/Linphone/core/fps-counter/FPSCounter.cpp @@ -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(); } diff --git a/Linphone/core/friend/FriendInitialProxy.cpp b/Linphone/core/friend/FriendInitialProxy.cpp deleted file mode 100644 index 2dfc4cfe1..000000000 --- a/Linphone/core/friend/FriendInitialProxy.cpp +++ /dev/null @@ -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 . - */ - -#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(); - 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(left.row()); -// // auto r = getItemAt(right.row()); -// // return l->getName() < r->getName(); -// } - -QVariant FriendInitialProxy::data(const QModelIndex &index, int role) const { - return sourceModel()->data(mapToSource(index)); -} diff --git a/Linphone/core/friend/FriendInitialProxy.hpp b/Linphone/core/friend/FriendInitialProxy.hpp deleted file mode 100644 index 216de761d..000000000 --- a/Linphone/core/friend/FriendInitialProxy.hpp +++ /dev/null @@ -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 . - */ - -#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 diff --git a/Linphone/core/participant/ParticipantDeviceProxy.cpp b/Linphone/core/participant/ParticipantDeviceProxy.cpp index a5e0e1daf..a5ffcb81f 100644 --- a/Linphone/core/participant/ParticipantDeviceProxy.cpp +++ b/Linphone/core/participant/ParticipantDeviceProxy.cpp @@ -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()->getCore(); - auto deviceB = sourceModel()->data(right).value()->getCore(); +bool ParticipantDeviceProxy::SortFilterList::lessThan(const QModelIndex &sourceLeft, + const QModelIndex &sourceRight) const { + auto l = getItemAtSource(sourceLeft.row()); + auto r = getItemAtSource(sourceRight.row()); - return deviceB->isMe() || (!deviceB->isMe() && left.row() < right.row()); + return r->isMe() || (!r->isMe() && sourceLeft.row() < sourceRight.row()); } diff --git a/Linphone/core/participant/ParticipantDeviceProxy.hpp b/Linphone/core/participant/ParticipantDeviceProxy.hpp index 9bf384b50..cb5a7597e 100644 --- a/Linphone/core/participant/ParticipantDeviceProxy.hpp +++ b/Linphone/core/participant/ParticipantDeviceProxy.hpp @@ -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 mParticipants; DECLARE_ABSTRACT_OBJECT diff --git a/Linphone/core/participant/ParticipantProxy.cpp b/Linphone/core/participant/ParticipantProxy.cpp index 28e7b8caf..58bee96d5 100644 --- a/Linphone/core/participant/ParticipantProxy.cpp +++ b/Linphone/core/participant/ParticipantProxy.cpp @@ -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(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(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(); - return !a->isMe(); + auto participant = qobject_cast(sourceModel())->getAt(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(); const ParticipantCore *b = sourceModel()->data(right).value(); diff --git a/Linphone/core/participant/ParticipantProxy.hpp b/Linphone/core/participant/ParticipantProxy.hpp index 7205b378a..c54dcecb8 100644 --- a/Linphone/core/participant/ParticipantProxy.hpp +++ b/Linphone/core/participant/ParticipantProxy.hpp @@ -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 mParticipants; DECLARE_ABSTRACT_OBJECT diff --git a/Linphone/core/payload-type/PayloadTypeProxy.cpp b/Linphone/core/payload-type/PayloadTypeProxy.cpp index 9d14cb970..ee9f4f683 100644 --- a/Linphone/core/payload-type/PayloadTypeProxy.cpp +++ b/Linphone/core/payload-type/PayloadTypeProxy.cpp @@ -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(); - return data->getCore()->getFamily() == mFamily; +PayloadTypeCore::Family PayloadTypeProxy::getFamily() const { + return dynamic_cast(sourceModel())->mFamily; } -bool PayloadTypeProxy::lessThan(const QModelIndex &left, const QModelIndex &right) const { - auto l = getItemAt(left.row()); - auto r = getItemAt(right.row()); +void PayloadTypeProxy::setFamily(PayloadTypeCore::Family data) { + auto list = dynamic_cast(sourceModel()); + if (list->mFamily != data) { + list->mFamily = data; + familyChanged(); + } +} + +bool PayloadTypeProxy::SortFilterList::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const { + auto payload = qobject_cast(sourceModel())->getAt(sourceRow); + return payload->getFamily() == mFamily; +} + +bool PayloadTypeProxy::SortFilterList::lessThan(const QModelIndex &sourceLeft, const QModelIndex &sourceRight) const { + auto l = getItemAtSource(sourceLeft.row()); + auto r = getItemAtSource(sourceRight.row()); return l->getMimeType() < r->getMimeType(); } diff --git a/Linphone/core/payload-type/PayloadTypeProxy.hpp b/Linphone/core/payload-type/PayloadTypeProxy.hpp index c4ceeab8c..ba79e15e4 100644 --- a/Linphone/core/payload-type/PayloadTypeProxy.hpp +++ b/Linphone/core/payload-type/PayloadTypeProxy.hpp @@ -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 mPayloadTypeList; DECLARE_ABSTRACT_OBJECT diff --git a/Linphone/core/phone-number/PhoneNumberProxy.cpp b/Linphone/core/phone-number/PhoneNumberProxy.cpp index 1efc784fb..74ede3f86 100644 --- a/Linphone/core/phone-number/PhoneNumberProxy.cpp +++ b/Linphone/core/phone-number/PhoneNumberProxy.cpp @@ -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(sourceModel()); + auto model = getListModel(); 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(); + auto phoneNumber = qobject_cast(sourceModel())->getAt(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()->mCountry < r.value()->mCountry; +bool PhoneNumberProxy::SortFilterList::lessThan(const QModelIndex &sourceLeft, const QModelIndex &sourceRight) const { + auto l = getItemAtSource(sourceLeft.row()); + auto r = getItemAtSource(sourceRight.row()); + return l->mCountry < r->mCountry; } diff --git a/Linphone/core/phone-number/PhoneNumberProxy.hpp b/Linphone/core/phone-number/PhoneNumberProxy.hpp index 0c99a8d7f..34615a7a0 100644 --- a/Linphone/core/phone-number/PhoneNumberProxy.hpp +++ b/Linphone/core/phone-number/PhoneNumberProxy.hpp @@ -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 mPhoneNumberList; private: diff --git a/Linphone/core/proxy/AbstractListProxy.hpp b/Linphone/core/proxy/AbstractListProxy.hpp index 001f40d3e..f1c0b6b43 100644 --- a/Linphone/core/proxy/AbstractListProxy.hpp +++ b/Linphone/core/proxy/AbstractListProxy.hpp @@ -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 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 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 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 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 mList; diff --git a/Linphone/core/proxy/LimitProxy.cpp b/Linphone/core/proxy/LimitProxy.cpp new file mode 100644 index 000000000..52d323df0 --- /dev/null +++ b/Linphone/core/proxy/LimitProxy.cpp @@ -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 . + */ + +#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(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(sourceModel())->getFilterText(); +} + +void LimitProxy::setFilterText(const QString &filter) { + dynamic_cast(sourceModel())->setFilterText(filter); +} + +int LimitProxy::getFilterType() const { + return dynamic_cast(sourceModel())->getFilterType(); +} + +void LimitProxy::setFilterType(int filter) { + dynamic_cast(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); + } +} diff --git a/Linphone/core/proxy/LimitProxy.hpp b/Linphone/core/proxy/LimitProxy.hpp new file mode 100644 index 000000000..b4c329b99 --- /dev/null +++ b/Linphone/core/proxy/LimitProxy.hpp @@ -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 . + */ + +#ifndef LIMIT_PROXY_H_ +#define LIMIT_PROXY_H_ + +#include "SortFilterProxy.hpp" +#include + +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 + QSharedPointer getItemAt(const int &atIndex) const { + return dynamic_cast(sourceModel())->template getItemAt(atIndex); + } + + template + inline A *getListModel() const { + auto model = dynamic_cast(sourceModel()); + if (model) return dynamic_cast(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 diff --git a/Linphone/core/proxy/ListProxy.hpp b/Linphone/core/proxy/ListProxy.hpp index c4f8a56b7..de6877634 100644 --- a/Linphone/core/proxy/ListProxy.hpp +++ b/Linphone/core/proxy/ListProxy.hpp @@ -63,14 +63,21 @@ public: template void add(QList> 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(); - 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(); + 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(); } } @@ -81,13 +88,7 @@ public: template void prepend(QList> 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>::prepend(items); } virtual bool remove(QObject *itemToRemove) override { diff --git a/Linphone/core/proxy/Proxy.cpp b/Linphone/core/proxy/Proxy.cpp index 947ff013c..264235543 100644 --- a/Linphone/core/proxy/Proxy.cpp +++ b/Linphone/core/proxy/Proxy.cpp @@ -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(); + } +} diff --git a/Linphone/core/proxy/Proxy.hpp b/Linphone/core/proxy/Proxy.hpp index 87dd9166c..4759a1c97 100644 --- a/Linphone/core/proxy/Proxy.hpp +++ b/Linphone/core/proxy/Proxy.hpp @@ -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 diff --git a/Linphone/core/proxy/SortFilterProxy.cpp b/Linphone/core/proxy/SortFilterProxy.cpp index 93f123ca6..480fc7db0 100644 --- a/Linphone/core/proxy/SortFilterProxy.cpp +++ b/Linphone/core/proxy/SortFilterProxy.cpp @@ -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(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); } diff --git a/Linphone/core/proxy/SortFilterProxy.hpp b/Linphone/core/proxy/SortFilterProxy.hpp index 80784dbd4..16a3d3369 100644 --- a/Linphone/core/proxy/SortFilterProxy.hpp +++ b/Linphone/core/proxy/SortFilterProxy.hpp @@ -22,37 +22,62 @@ #define SORT_FILTER_PROXY_H_ #include +#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 QSharedPointer getItemAt(const int &atIndex) const { auto modelIndex = index(atIndex, 0); return qobject_cast(sourceModel())->template getAt(mapToSource(modelIndex).row()); } + template + QSharedPointer getItemAtSource(const int &atIndex) const { + return qobject_cast(sourceModel())->template getAt(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; }; diff --git a/Linphone/core/screen/ScreenProxy.cpp b/Linphone/core/screen/ScreenProxy.cpp index 3b7ba3338..faf2e04a6 100644 --- a/Linphone/core/screen/ScreenProxy.cpp +++ b/Linphone/core/screen/ScreenProxy.cpp @@ -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(sourceModel())->getMode(); + return getListModel()->getMode(); } void ScreenProxy::setMode(ScreenList::Mode data) { - dynamic_cast(sourceModel())->setMode(data); + getListModel()->setMode(data); } void ScreenProxy::update() { - dynamic_cast(sourceModel())->update(); + getListModel()->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(sourceModel())->getAt(sourceLeft.row()); + auto r = qobject_cast(sourceModel())->getAt(sourceRight.row()); + + return l["screenIndex"].toInt() < r["screenIndex"].toInt(); } diff --git a/Linphone/core/screen/ScreenProxy.hpp b/Linphone/core/screen/ScreenProxy.hpp index 365b7e8fc..c5128161c 100644 --- a/Linphone/core/screen/ScreenProxy.hpp +++ b/Linphone/core/screen/ScreenProxy.hpp @@ -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; diff --git a/Linphone/core/search/MagicSearchProxy.cpp b/Linphone/core/search/MagicSearchProxy.cpp index 625376add..0250fef01 100644 --- a/Linphone/core/search/MagicSearchProxy.cpp +++ b/Linphone/core/search/MagicSearchProxy.cpp @@ -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 newList) { if (mList) { disconnect(mList.get()); } + auto oldModel = dynamic_cast(sourceModel()); mList = newList; if (mList) { connect(mList.get(), &MagicSearchList::sourceFlagsChanged, this, &MagicSearchProxy::sourceFlagsChanged, @@ -50,8 +51,11 @@ void MagicSearchProxy::setList(QSharedPointer 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(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 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(sourceModel()); + auto magicSearchList = getListModel(); 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(sourceModel())->mShowFavoritesOnly; } void MagicSearchProxy::setShowFavoritesOnly(bool show) { - if (mShowFavoritesOnly != show) { - mShowFavoritesOnly = show; + auto list = dynamic_cast(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(); - auto friendCore = friendGui->getCore(); +bool MagicSearchProxy::SortFilterList::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const { + auto friendCore = getItemAtSource(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(sourceLeft.row()); + auto r = getItemAtSource(sourceRight.row()); - auto lIsFriend = l.value(); - auto rIsFriend = r.value(); - - 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; diff --git a/Linphone/core/search/MagicSearchProxy.hpp b/Linphone/core/search/MagicSearchProxy.hpp index f5ccbee74..4f1554fe3 100644 --- a/Linphone/core/search/MagicSearchProxy.hpp +++ b/Linphone/core/search/MagicSearchProxy.hpp @@ -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 mList; - bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override; - virtual bool lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const override; }; #endif diff --git a/Linphone/core/setting/SettingsCore.cpp b/Linphone/core/setting/SettingsCore.cpp index 16b8abf4b..bc130c10c 100644 --- a/Linphone/core/setting/SettingsCore.cpp +++ b/Linphone/core/setting/SettingsCore.cpp @@ -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 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, diff --git a/Linphone/core/setting/SettingsCore.hpp b/Linphone/core/setting/SettingsCore.hpp index ea31c9568..2139eeefd 100644 --- a/Linphone/core/setting/SettingsCore.hpp +++ b/Linphone/core/setting/SettingsCore.hpp @@ -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) diff --git a/Linphone/core/timezone/TimeZoneProxy.cpp b/Linphone/core/timezone/TimeZoneProxy.cpp index c8e18a86d..d8d8ef3d7 100644 --- a/Linphone/core/timezone/TimeZoneProxy.cpp +++ b/Linphone/core/timezone/TimeZoneProxy.cpp @@ -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(left.row()); - auto r = getItemAt(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(sourceLeft.row()); + auto r = getItemAtSource(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(sourceModel())->mapFromSource(mList->index(index, 0)).row(); } diff --git a/Linphone/core/timezone/TimeZoneProxy.hpp b/Linphone/core/timezone/TimeZoneProxy.hpp index dbd7d294b..32186ae08 100644 --- a/Linphone/core/timezone/TimeZoneProxy.hpp +++ b/Linphone/core/timezone/TimeZoneProxy.hpp @@ -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 mList; - bool lessThan(const QModelIndex &left, const QModelIndex &right) const override; }; #endif diff --git a/Linphone/main.cpp b/Linphone/main.cpp index 202b69d13..7a0dddd8d 100644 --- a/Linphone/main.cpp +++ b/Linphone/main.cpp @@ -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. diff --git a/Linphone/model/setting/SettingsModel.cpp b/Linphone/model/setting/SettingsModel.cpp index 7b85cbdb1..2e0f17221 100644 --- a/Linphone/model/setting/SettingsModel.cpp +++ b/Linphone/model/setting/SettingsModel.cpp @@ -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, diff --git a/Linphone/model/setting/SettingsModel.hpp b/Linphone/model/setting/SettingsModel.hpp index c0f247d35..e30ef19ac 100644 --- a/Linphone/model/setting/SettingsModel.hpp +++ b/Linphone/model/setting/SettingsModel.hpp @@ -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) diff --git a/Linphone/view/Control/Button/Button.qml b/Linphone/view/Control/Button/Button.qml index 5e000aa69..dc47f7992 100644 --- a/Linphone/view/Control/Button/Button.qml +++ b/Linphone/view/Control/Button/Button.qml @@ -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 } - } + }*/ } diff --git a/Linphone/view/Control/Display/Contact/Avatar.qml b/Linphone/view/Control/Display/Contact/Avatar.qml index 4e5cb065d..dd58c5c5c 100644 --- a/Linphone/view/Control/Display/Contact/Avatar.qml +++ b/Linphone/view/Control/Display/Contact/Avatar.qml @@ -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' + } + } + } + } } } diff --git a/Linphone/view/Control/Display/Contact/ContactListView.qml b/Linphone/view/Control/Display/Contact/ContactListView.qml index 993e74cbf..e95866b31 100644 --- a/Linphone/view/Control/Display/Contact/ContactListView.qml +++ b/Linphone/view/Control/Display/Contact/ContactListView.qml @@ -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 diff --git a/Linphone/view/Control/Display/EffectImage.qml b/Linphone/view/Control/Display/EffectImage.qml index 26ca45480..639e9ce9e 100644 --- a/Linphone/view/Control/Display/EffectImage.qml +++ b/Linphone/view/Control/Display/EffectImage.qml @@ -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 } } + } } diff --git a/Linphone/view/Control/Display/Meeting/MeetingListView.qml b/Linphone/view/Control/Display/Meeting/MeetingListView.qml index 37537e7d5..caf5e887f 100644 --- a/Linphone/view/Control/Display/Meeting/MeetingListView.qml +++ b/Linphone/view/Control/Display/Meeting/MeetingListView.qml @@ -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 { diff --git a/Linphone/view/Control/Tool/Prototype/FriendPrototype.qml b/Linphone/view/Control/Tool/Prototype/FriendPrototype.qml index 880c3ccb8..0984e46ad 100644 --- a/Linphone/view/Control/Tool/Prototype/FriendPrototype.qml +++ b/Linphone/view/Control/Tool/Prototype/FriendPrototype.qml @@ -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 = '*' } } } diff --git a/Linphone/view/Page/Layout/Settings/AdvancedSettingsLayout.qml b/Linphone/view/Page/Layout/Settings/AdvancedSettingsLayout.qml index 171161a1e..ac94057d1 100644 --- a/Linphone/view/Page/Layout/Settings/AdvancedSettingsLayout.qml +++ b/Linphone/view/Page/Layout/Settings/AdvancedSettingsLayout.qml @@ -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 + } + } } } } diff --git a/Linphone/view/Page/Main/Call/CallPage.qml b/Linphone/view/Page/Main/Call/CallPage.qml index 0320c170c..cf86618b9 100644 --- a/Linphone/view/Page/Main/Call/CallPage.qml +++ b/Linphone/view/Page/Main/Call/CallPage.qml @@ -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 } diff --git a/Linphone/view/Page/Main/Meeting/MeetingPage.qml b/Linphone/view/Page/Main/Meeting/MeetingPage.qml index 37ea9a317..3710bedaf 100644 --- a/Linphone/view/Page/Main/Meeting/MeetingPage.qml +++ b/Linphone/view/Page/Main/Meeting/MeetingPage.qml @@ -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 diff --git a/Linphone/view/Page/Window/AbstractWindow.qml b/Linphone/view/Page/Window/AbstractWindow.qml index 0185d9523..d0ebfa8b7 100644 --- a/Linphone/view/Page/Window/AbstractWindow.qml +++ b/Linphone/view/Page/Window/AbstractWindow.qml @@ -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 + } + } }