Refreshing optimizations:

- Reset data list and initialization on single step.
- Just add a log on new call log.
- Remove updateView : it should not be needed as contains are updated automatically from its items.
- Clean AbstractListProxy from LimitProxy implementation.
- Avoid to reset left panel if not needed to not reload lists.
- Fix missing objectName in history list view.

Fix display on new call button.
This commit is contained in:
Julien Wadel 2024-10-16 15:12:14 +02:00
parent df7f0a6bc6
commit 3589029ec5
26 changed files with 111 additions and 193 deletions

View file

@ -65,8 +65,7 @@ void AccountList::setSelf(QSharedPointer<AccountList> me) {
}
mModelConnection->invokeToCore([this, accounts, defaultAccountCore]() {
mustBeInMainThread(getClassName());
resetData();
add(*accounts);
resetData<AccountCore>(*accounts);
setHaveAccount(accounts->size() > 0);
setDefaultAccount(defaultAccountCore);
delete accounts;

View file

@ -67,8 +67,7 @@ void CarddavList::setSelf(QSharedPointer<CarddavList> me) {
}
mModelConnection->invokeToCore([this, carddavs]() {
mustBeInMainThread(getClassName());
resetData();
add(*carddavs);
resetData<CarddavCore>(*carddavs);
delete carddavs;
});
});

View file

@ -64,8 +64,7 @@ void LdapList::setSelf(QSharedPointer<LdapList> me) {
}
mModelConnection->invokeToCore([this, ldaps]() {
mustBeInMainThread(getClassName());
resetData();
add(*ldaps);
resetData<LdapCore>(*ldaps);
delete ldaps;
});
});

View file

@ -54,6 +54,7 @@ CallHistoryCore::CallHistoryCore(const std::shared_ptr<linphone::CallLog> &callL
mIsOutgoing = callLog->getDir() == linphone::Call::Dir::Outgoing;
mDuration = QString::number(callLog->getDuration());
mIsConference = callLog->wasConference();
mCallId = Utils::coreStringToAppString(callLog->getCallId());
if (mIsConference) {
auto confinfo = callLog->getConferenceInfo();
mConferenceInfo = ConferenceInfoCore::create(confinfo);
@ -98,4 +99,4 @@ void CallHistoryCore::setDuration(const QString &duration) {
void CallHistoryCore::remove() {
mHistoryModelConnection->invokeToModel([this]() { mCallHistoryModel->removeCallHistory(); });
}
}

View file

@ -62,6 +62,7 @@ public:
bool mIsOutgoing;
bool mIsConference = false;
LinphoneEnums::CallStatus mStatus;
QString mCallId;
signals:
void durationChanged(QString duration);

View file

@ -71,28 +71,35 @@ void CallHistoryList::setSelf(QSharedPointer<CallHistoryList> me) {
}
mModelConnection->invokeToCore([this, callLogs]() {
mustBeInMainThread(getClassName());
resetData();
add(*callLogs);
/*
if (callLogs->size() > 0) {
int count = qMin(callLogs->size(), mMaxDisplayItems);
// QModelIndex firstIndex = index(0, 0);
beginInsertRows(QModelIndex(), 0, count - 1);
for (auto i : *callLogs)
mList << i.template objectCast<QObject>();
endInsertRows();
// auto lastIndex = index(count - 1, 0);
// emit dataChanged(firstIndex, lastIndex);
}*/
resetData<CallHistoryCore>(*callLogs);
delete callLogs;
});
});
});
mModelConnection->makeConnectToModel(&CoreModel::defaultAccountChanged,
[this]() { mModelConnection->invokeToCore([this]() { lUpdate(); }); });
mModelConnection->makeConnectToModel(&CoreModel::callLogUpdated,
[this]() { mModelConnection->invokeToCore([this]() { lUpdate(); }); });
mModelConnection->makeConnectToModel(
&CoreModel::callLogUpdated,
[this](const std::shared_ptr<linphone::Core> &core, const std::shared_ptr<linphone::CallLog> &callLog) {
QSharedPointer<CallHistoryCore> *callLogs = new QSharedPointer<CallHistoryCore>[1];
auto model = createCallHistoryCore(callLog);
callLogs[0] = model;
mModelConnection->invokeToCore([this, callLogs]() {
auto oldLog = std::find_if(mList.begin(), mList.end(), [callLogs](QSharedPointer<QObject> log) {
return (*callLogs)->mCallId == log.objectCast<CallHistoryCore>()->mCallId;
});
if (oldLog == mList.end()) { // New
prepend(*callLogs);
} else { // Update
qWarning() << log()
.arg("LinphoneCore::onCallLogUpdated has been call for an existant log which "
"should not be the "
"case. Check with the SDK. CallID=%1")
.arg((*callLogs)->mCallId);
}
delete[] callLogs;
});
});
emit lUpdate();
}
@ -121,14 +128,3 @@ 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();
}
}
*/

View file

@ -47,10 +47,6 @@ void CallHistoryProxy::removeEntriesWithFilter() {
}
}
void CallHistoryProxy::updateView() {
mHistoryList->lUpdate();
}
//------------------------------------------------------------------------------------------
bool CallHistoryProxy::SortFilterList::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const {

View file

@ -39,7 +39,6 @@ public:
Q_INVOKABLE void removeAllEntries();
Q_INVOKABLE void removeEntriesWithFilter();
Q_INVOKABLE void updateView();
protected:
QSharedPointer<CallHistoryList> mHistoryList;

View file

@ -71,8 +71,7 @@ void CallList::setSelf(QSharedPointer<CallList> me) {
}
mModelConnection->invokeToCore([this, calls, currentCallCore]() {
mustBeInMainThread(getClassName());
resetData();
add(*calls);
resetData<CallCore>(*calls);
setHaveCall(calls->size() > 0);
setCurrentCall(currentCallCore);
delete calls;

View file

@ -67,9 +67,8 @@ void ConferenceInfoList::setSelf(QSharedPointer<ConferenceInfoList> me) {
}
mCoreModelConnection->invokeToCore([this, items]() {
mustBeInMainThread(getClassName());
resetData();
int currentDateIndex = sort(*items);
add(*items);
resetData<ConferenceInfoCore>(*items);
updateHaveCurrentDate();
if (mLastConfInfoInserted) {
int index = -1;

View file

@ -74,8 +74,7 @@ QSharedPointer<ParticipantDeviceCore> ParticipantDeviceList::getMe() const {
void ParticipantDeviceList::setDevices(QList<QSharedPointer<ParticipantDeviceCore>> devices) {
mustBeInMainThread(log().arg(Q_FUNC_INFO));
resetData();
add(devices);
resetData<ParticipantDeviceCore>(devices);
lDebug() << log().arg("Add %1 devices").arg(devices.size());
}

View file

@ -70,8 +70,7 @@ void ParticipantList::setSelf(QSharedPointer<ParticipantList> me) {
participantList->push_back(meModel);
mConferenceModelConnection->invokeToCore([this, participantList]() {
mustBeInMainThread(getClassName());
resetData();
add(*participantList);
resetData<ParticipantCore>(*participantList);
delete participantList;
});
});

View file

@ -67,8 +67,7 @@ void PayloadTypeList::setSelf(QSharedPointer<PayloadTypeList> me) {
}
mModelConnection->invokeToCore([this, payloadTypes]() {
mustBeInMainThread(getClassName());
resetData();
add(*payloadTypes);
resetData<PayloadTypeCore>(*payloadTypes);
delete payloadTypes;
});
});

View file

@ -48,8 +48,7 @@ PhoneNumberList::PhoneNumberList(QObject *parent) : ListProxy(parent) {
// Invoke for adding stuffs in caller thread
QMetaObject::invokeMethod(this, [this, numbers]() {
mustBeInMainThread(this->log().arg(Q_FUNC_INFO));
resetData();
add(*numbers);
resetData<PhoneNumber>(*numbers);
delete numbers;
});
});

View file

@ -35,9 +35,9 @@ public:
virtual ~AbstractListProxy() {
clearData();
}
virtual int rowCount(const QModelIndex &index = QModelIndex()) const override {
return getDisplayCount(mList.size());
return mList.size();
}
virtual QHash<int, QByteArray> roleNames() const override {
@ -45,7 +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();
@ -61,31 +61,23 @@ public:
// Add functions
virtual void add(T item) {
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(lastIndex, lastIndex);
}
beginInsertRows(QModelIndex(), row, row);
mList << item;
endInsertRows();
auto lastIndex = index(mList.size() - 1, 0);
emit dataChanged(lastIndex, lastIndex);
}
virtual void add(QList<T> items) {
int count = items.size();
if (count > 0 ) {
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;
int newCount = mList.size() + count;
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);
}
}
@ -94,9 +86,6 @@ public:
beginInsertRows(QModelIndex(), 0, 0);
mList.prepend(item);
endInsertRows();
if(mMaxDisplayItems > 0 && currentCount + 1 >= mMaxDisplayItems){
setMaxDisplayItems(mMaxDisplayItems+1);
}
emit dataChanged(index(0), index(0));
}
@ -109,9 +98,6 @@ public:
items << mList;
mList = items;
endInsertRows();
if(mMaxDisplayItems > 0 && newCount >= mMaxDisplayItems){
setMaxDisplayItems(newCount);
}
emit dataChanged(index(0), index(items.size() - 1));
}
}
@ -133,24 +119,23 @@ public:
virtual void clearData() override {
mList.clear();
setMaxDisplayItems(getInitialDisplayItems());
}
virtual void resetData() override {
virtual void resetData(QList<T> newData = QList<T>()) {
beginResetModel();
clearData();
mList = newData;
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();
}
}*/
/*
void displayMore() {
int oldCount = rowCount();
int newCount = getDisplayCount(oldCount + mList.size(), mMaxDisplayItems + mDisplayItemsStep);
if (newCount != oldCount) {
setMaxDisplayItems(newCount);
beginInsertRows(QModelIndex(), oldCount, newCount - 1);
endInsertRows();
}
}*/
protected:
QList<T> mList;

View file

@ -38,8 +38,9 @@ bool LimitProxy::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent
void LimitProxy::setSourceModels(SortFilterProxy *firstList) {
auto secondList = firstList->sourceModel();
connect(secondList, &QAbstractItemModel::rowsInserted, this, &LimitProxy::invalidateFilter);
connect(secondList, &QAbstractItemModel::rowsRemoved, this, &LimitProxy::invalidateFilter);
connect(secondList, &QAbstractItemModel::rowsInserted, this, &LimitProxy::onAdded);
connect(secondList, &QAbstractItemModel::rowsRemoved, this, &LimitProxy::onRemoved);
connect(secondList, &QAbstractItemModel::modelReset, this, &LimitProxy::invalidateRowsFilter);
connect(firstList, &SortFilterProxy::filterTextChanged, this, &LimitProxy::filterTextChanged);
connect(firstList, &SortFilterProxy::filterTypeChanged, this, &LimitProxy::filterTypeChanged);
@ -149,3 +150,15 @@ void LimitProxy::displayMore() {
setMaxDisplayItems(mMaxDisplayItems + mDisplayItemsStep);
}
}
void LimitProxy::onAdded() {
int count = sourceModel()->rowCount();
if (mMaxDisplayItems > 0 && mMaxDisplayItems <= count) setMaxDisplayItems(mMaxDisplayItems + 1);
}
void LimitProxy::onRemoved() {
int count = sourceModel()->rowCount();
if (mMaxDisplayItems > 0 && mMaxDisplayItems <= count) {
invalidateFilter();
}
}

View file

@ -80,6 +80,9 @@ public:
virtual void setFilterType(int filterType);
//-------------------------------------------------------------
void onAdded();
void onRemoved();
int mInitialDisplayItems = -1;
int mMaxDisplayItems = -1;
int mDisplayItemsStep = 5;

View file

@ -64,20 +64,16 @@ public:
template <class T>
void add(QList<QSharedPointer<T>> items) {
int count = items.size();
if (count > 0 ) {
if (count > 0) {
int currentCount = rowCount();
int newCount = getDisplayCount(mList.size() + count);
if(newCount != currentCount){
beginInsertRows(QModelIndex(), currentCount, newCount - 1);
for (auto i : items)
mList << i.template objectCast<QObject>();
endInsertRows();
QModelIndex firstIndex = currentCount > 0 ? index(currentCount-1, 0) : index(0, 0);
auto lastIndex = index(newCount - 1, 0);
emit dataChanged(firstIndex, lastIndex);
}else
for (auto i : items)
mList << i.template objectCast<QObject>();
int newCount = mList.size() + count;
beginInsertRows(QModelIndex(), currentCount, newCount - 1);
for (auto i : items)
mList << i.template objectCast<QObject>();
endInsertRows();
QModelIndex firstIndex = currentCount > 0 ? index(currentCount - 1, 0) : index(0, 0);
auto lastIndex = index(newCount - 1, 0);
emit dataChanged(firstIndex, lastIndex);
}
}
@ -91,6 +87,15 @@ public:
AbstractListProxy<QSharedPointer<QObject>>::prepend(items);
}
template <class T>
void resetData(QList<QSharedPointer<T>> items) {
beginResetModel();
mList.clear();
for (auto i : items)
mList << i.template objectCast<QObject>();
endResetModel();
}
virtual bool remove(QObject *itemToRemove) override {
bool removed = false;
if (itemToRemove) {

View file

@ -29,52 +29,9 @@ 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();
}
}

View file

@ -30,35 +30,14 @@ 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

View file

@ -19,7 +19,7 @@
*/
#include "SortFilterProxy.hpp"
#include "Proxy.hpp"
SortFilterProxy::SortFilterProxy(QAbstractItemModel *list) : QSortFilterProxyModel(list) {
connect(this, &SortFilterProxy::rowsInserted, this, &SortFilterProxy::countChanged);
connect(this, &SortFilterProxy::rowsRemoved, this, &SortFilterProxy::countChanged);
@ -43,7 +43,6 @@ void SortFilterProxy::deleteSourceModel() {
}
void SortFilterProxy::setSourceModel(QAbstractItemModel *model) {
auto listModel = dynamic_cast<Proxy *>(model);
auto oldSourceModel = sourceModel();
if (oldSourceModel) disconnect(oldSourceModel);
QSortFilterProxyModel::setSourceModel(model);

View file

@ -142,12 +142,11 @@ void MagicSearchList::setResults(const QList<QSharedPointer<FriendCore>> &contac
if (!isFriendCore) continue;
disconnect(isFriendCore.get());
}
resetData();
resetData<FriendCore>(contacts);
for (auto it : contacts) {
connect(it.get(), &FriendCore::removed, this, qOverload<QObject *>(&MagicSearchList::remove));
connect(it.get(), &FriendCore::starredChanged, this, [this] { lSearch(mSearchFilter); });
}
add(contacts);
}
void MagicSearchList::addResult(const QSharedPointer<FriendCore> &contact) {

View file

@ -46,17 +46,18 @@ TimeZoneList::~TimeZoneList() {
// -----------------------------------------------------------------------------
void TimeZoneList::initTimeZones() {
resetData();
QList<QSharedPointer<QObject>> models;
for (auto id : QTimeZone::availableTimeZoneIds()) {
auto model = QSharedPointer<TimeZoneModel>::create(QTimeZone(id));
if (std::find_if(mList.begin(), mList.end(), [id](const QSharedPointer<QObject> &a) {
return a.objectCast<TimeZoneModel>()->getTimeZone() == QTimeZone(id);
}) == mList.end()) {
if (model->getCountryName().toUpper() != "DEFAULT") {
add(model);
models << model;
}
}
}
resetData(models);
}
QHash<int, QByteArray> TimeZoneList::roleNames() const {

View file

@ -70,6 +70,7 @@ FocusScope {
id: grouCallButton
visible: mainItem.groupCallVisible && !SettingsCpp.disableMeetingsFeature
Layout.preferredWidth: 320 * DefaultStyle.dp
Layout.preferredHeight: 44 * DefaultStyle.dp
padding: 0
KeyNavigation.up: searchBar
KeyNavigation.down: contactList.count >0 ? contactList : searchList
@ -85,7 +86,6 @@ FocusScope {
}
contentItem: RowLayout {
spacing: 16 * DefaultStyle.dp
anchors.verticalCenter: parent.verticalCenter
Image {
source: AppIcons.groupCall
Layout.preferredWidth: 44 * DefaultStyle.dp

View file

@ -617,7 +617,7 @@ Item {
Connections {
target: mainItem
function onOpenNewCallRequest(){ callPage.goToNewCall()}
function onCallCreated(){ callPage.resetLeftPanel()}
function onCallCreated(){ callPage.goToCallHistory()}
function onOpenCallHistory(){ callPage.goToCallHistory()}
function onOpenNumPadRequest(){ callPage.openNumPadRequest()}
}

View file

@ -17,7 +17,7 @@ AbstractMainPage {
signal listViewUpdated()
onVisibleChanged: if (!visible) {
resetLeftPanel()
goToCallHistory()
}
//Group call properties
@ -53,10 +53,6 @@ AbstractMainPage {
showDefaultItem: listStackView.currentItem && listStackView.currentItem.listView && listStackView.currentItem.listView.count === 0 && listStackView.currentItem.listView.model.sourceModel.count === 0 || false
function resetLeftPanel() {
listStackView.clear()
listStackView.push(listStackView.initialItem)
}
function goToNewCall() {
if (listStackView.currentItem && listStackView.currentItem.objectName != "newCallItem") listStackView.push(newCallItem)
}
@ -197,6 +193,7 @@ AbstractMainPage {
Component {
id: historyListItem
FocusScope{
objectName: "historyListItem"
Control.StackView.onActivated: titleLoader.sourceComponent = historyListTitle
ColumnLayout {
anchors.fill: parent
@ -246,7 +243,9 @@ AbstractMainPage {
onFilterTextChanged: maxDisplayItems = initialDisplayItems
initialDisplayItems: historyListView.height / (56 * DefaultStyle.dp) + 5
displayItemsStep: initialDisplayItems / 2
onCountChanged: console.log("callHistoryProxy : " +count)
}
Component.onCompleted: console.log("historyListView completed")
cacheBuffer: contentHeight>0 ? contentHeight : 0// cache all items
flickDeceleration: 10000
spacing: 10 * DefaultStyle.dp
@ -276,6 +275,7 @@ AbstractMainPage {
anchors.topMargin: 5 * DefaultStyle.dp
anchors.bottomMargin: 5 * DefaultStyle.dp
visible: !!modelData
Component.onCompleted: console.log(index + " => Completed "+visible)
RowLayout {
z: 1
anchors.fill: parent
@ -405,13 +405,6 @@ AbstractMainPage {
onVisibleChanged: {
if (!visible) currentIndex = -1
}
Connections {
target: mainItem
function onListViewUpdated() {
historyListView.model.updateView()
}
}
Control.ScrollBar.vertical: scrollbar
}
}