diff --git a/Linphone/core/App.cpp b/Linphone/core/App.cpp index 12f6168c4..bfd7fa73d 100644 --- a/Linphone/core/App.cpp +++ b/Linphone/core/App.cpp @@ -26,6 +26,8 @@ #include "core/logger/QtLogger.hpp" #include "core/login/LoginPage.hpp" +#include "core/phone-number/PhoneNumber.hpp" +#include "core/phone-number/PhoneNumberProxy.hpp" #include "core/singleapplication/singleapplication.h" #include "tool/Constants.hpp" #include "tool/providers/ImageProvider.hpp" @@ -91,6 +93,9 @@ void App::initCppInterfaces() { qmlRegisterSingletonType( "ConstantsCpp", 1, 0, "ConstantsCpp", [](QQmlEngine *engine, QJSEngine *) -> QObject * { return new Constants(engine); }); + + qmlRegisterType(Constants::MainQmlUri, 1, 0, "PhoneNumberProxy"); + qmlRegisterUncreatableType(Constants::MainQmlUri, 1, 0, "PhoneNumber", QLatin1String("Uncreatable")); } //------------------------------------------------------------ diff --git a/Linphone/core/CMakeLists.txt b/Linphone/core/CMakeLists.txt index 9043627d3..50dc48235 100644 --- a/Linphone/core/CMakeLists.txt +++ b/Linphone/core/CMakeLists.txt @@ -3,8 +3,16 @@ list(APPEND _LINPHONEAPP_SOURCES core/logger/QtLogger.cpp core/login/LoginPage.cpp core/path/Paths.cpp + core/phone-number/PhoneNumber.cpp + core/phone-number/PhoneNumberList.cpp + core/phone-number/PhoneNumberProxy.cpp + core/setting/Settings.cpp core/thread/Thread.cpp + + core/proxy/ListProxy.cpp + core/proxy/Proxy.cpp + core/proxy/SortFilterProxy.cpp ) ## Single Application diff --git a/Linphone/core/phone-number/PhoneNumber.cpp b/Linphone/core/phone-number/PhoneNumber.cpp new file mode 100644 index 000000000..7d18f1596 --- /dev/null +++ b/Linphone/core/phone-number/PhoneNumber.cpp @@ -0,0 +1,33 @@ +/* + * 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 "PhoneNumber.hpp" +#include "tool/Utils.hpp" +#include + +PhoneNumber::PhoneNumber(const std::shared_ptr &dialPlan) : QObject(nullptr) { + // Should be call from model Thread + mFlag = Utils::coreStringToAppString(dialPlan->getFlag()); + mNationalNumberLength = dialPlan->getNationalNumberLength(); + mCountryCallingCode = Utils::coreStringToAppString(dialPlan->getCountryCallingCode()); + mIsoCountryCode = Utils::coreStringToAppString(dialPlan->getIsoCountryCode()); + mInternationalCallPrefix = Utils::coreStringToAppString(dialPlan->getInternationalCallPrefix()); + mCountry = Utils::coreStringToAppString(dialPlan->getCountry()); +} diff --git a/Linphone/core/phone-number/PhoneNumber.hpp b/Linphone/core/phone-number/PhoneNumber.hpp new file mode 100644 index 000000000..176a2fb94 --- /dev/null +++ b/Linphone/core/phone-number/PhoneNumber.hpp @@ -0,0 +1,49 @@ +/* + * 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 PHONE_NUMBER_H_ +#define PHONE_NUMBER_H_ + +#include +#include + +class PhoneNumber : public QObject { + Q_OBJECT + + Q_PROPERTY(QString flag MEMBER mFlag CONSTANT) + Q_PROPERTY(int nationalNumberLength MEMBER mNationalNumberLength CONSTANT) + Q_PROPERTY(QString countryCallingCode MEMBER mCountryCallingCode CONSTANT) + Q_PROPERTY(QString isoCountryCode MEMBER mIsoCountryCode CONSTANT) + Q_PROPERTY(QString internationalCallPrefix MEMBER mInternationalCallPrefix CONSTANT) + Q_PROPERTY(QString country MEMBER mCountry CONSTANT) + +public: + // Should be call from model Thread. Will be automatically in App thread after initialization + PhoneNumber(const std::shared_ptr &dialPlan); + + QString mFlag; + int mNationalNumberLength; + QString mCountryCallingCode; + QString mIsoCountryCode; + QString mInternationalCallPrefix; + QString mCountry; +}; + +#endif diff --git a/Linphone/core/phone-number/PhoneNumberList.cpp b/Linphone/core/phone-number/PhoneNumberList.cpp new file mode 100644 index 000000000..966177bd2 --- /dev/null +++ b/Linphone/core/phone-number/PhoneNumberList.cpp @@ -0,0 +1,44 @@ +/* + * 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 "PhoneNumberList.hpp" +#include "PhoneNumber.hpp" +#include "core/App.hpp" +#include +#include + +// ============================================================================= + +PhoneNumberList::PhoneNumberList(QObject *parent) : ListProxy(parent) { + + App::postModelAsync([=]() { + // Model thread. + auto dialPlans = linphone::Factory::get()->getDialPlans(); + QList> numbers; + QVector results; + for (auto it : dialPlans) { + auto numberModel = QSharedPointer::create(it); + numberModel->moveToThread(this->thread()); + numbers.push_back(numberModel); + } + // Invoke for adding stuffs in caller thread + QMetaObject::invokeMethod(this, [this, numbers]() { add(numbers); }); + }); +} diff --git a/Linphone/core/phone-number/PhoneNumberList.hpp b/Linphone/core/phone-number/PhoneNumberList.hpp new file mode 100644 index 000000000..786c9416a --- /dev/null +++ b/Linphone/core/phone-number/PhoneNumberList.hpp @@ -0,0 +1,34 @@ +/* + * 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 PHONE_NUMBER_LIST_H_ +#define PHONE_NUMBER_LIST_H_ + +#include "../proxy/ListProxy.hpp" +#include +// ============================================================================= + +class PhoneNumberList : public ListProxy { + Q_OBJECT +public: + PhoneNumberList(QObject *parent = Q_NULLPTR); +}; + +#endif diff --git a/Linphone/core/phone-number/PhoneNumberProxy.cpp b/Linphone/core/phone-number/PhoneNumberProxy.cpp new file mode 100644 index 000000000..2fcfa1217 --- /dev/null +++ b/Linphone/core/phone-number/PhoneNumberProxy.cpp @@ -0,0 +1,62 @@ +/* + * 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 "PhoneNumberProxy.hpp" +#include "PhoneNumber.hpp" +#include "PhoneNumberList.hpp" + +PhoneNumberProxy::PhoneNumberProxy(QObject *parent) : SortFilterProxy(parent) { + setSourceModel(new PhoneNumberList(this)); + sort(0); +} + +QString PhoneNumberProxy::getFilterText() const { + return mFilterText; +} + +void PhoneNumberProxy::setFilterText(const QString &filter) { + if (mFilterText != filter) { + mFilterText = filter; + invalidate(); + emit filterTextChanged(); + } +} + +bool PhoneNumberProxy::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(); + 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; +} diff --git a/Linphone/core/phone-number/PhoneNumberProxy.hpp b/Linphone/core/phone-number/PhoneNumberProxy.hpp new file mode 100644 index 000000000..291add975 --- /dev/null +++ b/Linphone/core/phone-number/PhoneNumberProxy.hpp @@ -0,0 +1,49 @@ +/* + * 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 PHONE_NUMBER_PROXY_H_ +#define PHONE_NUMBER_PROXY_H_ + +#include "../proxy/SortFilterProxy.hpp" + +// ============================================================================= + +class PhoneNumberProxy : public SortFilterProxy { + Q_OBJECT + + Q_PROPERTY(QString filterText READ getFilterText WRITE setFilterText NOTIFY filterTextChanged) + +public: + PhoneNumberProxy(QObject *parent = Q_NULLPTR); + + QString getFilterText() const; + void setFilterText(const QString &filter); + +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; +}; + +#endif diff --git a/Linphone/core/proxy/AbstractListProxy.hpp b/Linphone/core/proxy/AbstractListProxy.hpp new file mode 100644 index 000000000..70d8daa49 --- /dev/null +++ b/Linphone/core/proxy/AbstractListProxy.hpp @@ -0,0 +1,126 @@ +/* + * Copyright (c) 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 ABSTRACT_LIST_PROXY_H_ +#define ABSTRACT_LIST_PROXY_H_ + +#include +#include + +#include "Proxy.hpp" + +template +class AbstractListProxy : public Proxy { +public: + AbstractListProxy(QObject *parent = Q_NULLPTR) : Proxy(parent) { + } + + virtual ~AbstractListProxy() { + clearData(); + } + + virtual int rowCount(const QModelIndex &index = QModelIndex()) const override { + return mList.count(); + } + + virtual QHash roleNames() const override { + QHash roles; + 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(); + else if (role == Qt::DisplayRole) return QVariant::fromValue(mList[row]); + else return QVariant(); + } + + virtual T getAt(const int &index) const { + if (index < 0 || index >= mList.count()) return nullptr; + else return mList[index]; + } + + // 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; + endInsertRows(); + auto lastIndex = index(mList.size() - 1, 0); + emit dataChanged(firstIndex, lastIndex); + } + } + + virtual void prepend(T item) { + beginInsertRows(QModelIndex(), 0, 0); + mList.prepend(item); + endInsertRows(); + emit dataChanged(index(0), index(0)); + } + + virtual 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)); + } + } + + // Remove functions + virtual bool removeRow(int row, const QModelIndex &parent = QModelIndex()) { + return removeRows(row, 1, parent); + } + virtual bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()) override { + int limit = row + count - 1; + if (row < 0 || count < 0 || limit >= mList.count()) return false; + beginRemoveRows(parent, row, limit); + for (int i = 0; i < count; ++i) + mList.takeAt(row); + endRemoveRows(); + emit dataChanged(index(row), index(limit)); + return true; + } + + virtual void clearData() override { + mList.clear(); + } + + virtual void resetData() override { + beginResetModel(); + clearData(); + endResetModel(); + } + +protected: + QList mList; +}; + +#endif diff --git a/Linphone/core/proxy/AbstractMapProxy.hpp b/Linphone/core/proxy/AbstractMapProxy.hpp new file mode 100644 index 000000000..0a4396e67 --- /dev/null +++ b/Linphone/core/proxy/AbstractMapProxy.hpp @@ -0,0 +1,66 @@ +/* + * Copyright (c) 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 ABSTRACT_MAP_PROXY_H_ +#define ABSTRACT_MAP_PROXY_H_ + +#include + +#include "Proxy.hpp" + +template +class AbstractMapProxy : public Proxy { +public: + AbstractMapProxy(QObject *parent = Q_NULLPTR) : Proxy(parent) { + } + + virtual ~AbstractMapProxy() { + clearData(); + } + + virtual int rowCount(const QModelIndex &index = QModelIndex()) const override { + return mMappedList.count(); + } + + virtual QHash roleNames() const override { + QHash roles; + roles[Qt::DisplayRole] = "$modelData"; + roles[Qt::DisplayRole + 1] = "$modelKey"; + return roles; + } + + virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override { + int row = index.row(); + auto it = mMappedList.begin() + row; + if (role == Qt::DisplayRole) return QVariant::fromValue(*it); + else if (role == Qt::DisplayRole + 1) return QVariant::fromValue(it.key()); + + return QVariant(); + } + + virtual void clearData() override { + mMappedList.clear(); + } + +protected: + QMap mMappedList; +}; + +#endif diff --git a/Linphone/core/proxy/AbstractSortFilterProxy.hpp b/Linphone/core/proxy/AbstractSortFilterProxy.hpp new file mode 100644 index 000000000..a157e53b0 --- /dev/null +++ b/Linphone/core/proxy/AbstractSortFilterProxy.hpp @@ -0,0 +1,53 @@ +/* + * 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 ABSTRACT_SORT_FILTER_PROXY_H_ +#define ABSTRACT_SORT_FILTER_PROXY_H_ + +#include "SortFilterProxy.hpp" +#include + +template +class AbstractSortFilterProxy : public SortFilterProxy { +public: + AbstractSortFilterProxy(T *model, QObject *parent = nullptr) : SortFilterProxy(parent) { + update(model); + } + + void update(T *model) { + setSourceModel(model); + sort(0, Qt::DescendingOrder); + } + + template + void add(QSharedPointer x) { + qobject_cast(sourceModel())->add(x); + } + template + void removeShared(QSharedPointer x) { + qobject_cast(sourceModel())->remove(x); + } + template + void remove(X x) { + qobject_cast(sourceModel())->remove(x); + } +}; + +#endif diff --git a/Linphone/core/proxy/ListProxy.cpp b/Linphone/core/proxy/ListProxy.cpp new file mode 100644 index 000000000..311459ccf --- /dev/null +++ b/Linphone/core/proxy/ListProxy.cpp @@ -0,0 +1,43 @@ +/* + * Copyright (c) 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 "ListProxy.hpp" + +#include + +// ============================================================================= + +ListProxy::ListProxy(QObject *parent) : AbstractListProxy(parent) { +} + +ListProxy::~ListProxy() { +} + +QSharedPointer ListProxy::get(QObject *itemToGet, int *index) const { + int row = 0; + for (auto item : mList) + if (item.get() == itemToGet) { + if (index) *index = row; + return item; + } else ++row; + return nullptr; +} + +// ----------------------------------------------------------------------------- diff --git a/Linphone/core/proxy/ListProxy.hpp b/Linphone/core/proxy/ListProxy.hpp new file mode 100644 index 000000000..280419bcb --- /dev/null +++ b/Linphone/core/proxy/ListProxy.hpp @@ -0,0 +1,114 @@ +/* + * Copyright (c) 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 _LIST_PROXY_H_ +#define _LIST_PROXY_H_ + +#include "AbstractListProxy.hpp" +#include + +// ============================================================================= + +class ListProxy : public AbstractListProxy> { + Q_OBJECT + +public: + Q_PROPERTY(int count READ getCount NOTIFY countChanged) + ListProxy(QObject *parent = Q_NULLPTR); + virtual ~ListProxy(); + + template + QSharedPointer getAt(const int &index) const { + return AbstractListProxy>::getAt(index).objectCast(); + } + + QSharedPointer get(QObject *itemToGet, int *index = nullptr) const; + + template + QList> getSharedList() { + QList> newList; + for (auto item : mList) + newList << item.objectCast(); + return newList; + } + // Add functions + 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(); + if (role == Qt::DisplayRole) return QVariant::fromValue(mList[row].get()); + return QVariant(); + } + template + void add(QSharedPointer item) { + AbstractListProxy>::add(item.template objectCast()); + } + + 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); + } + } + + template + void prepend(QSharedPointer item) { + AbstractListProxy>::prepend(item.template objectCast()); + } + + 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)); + } + } + + virtual bool remove(QObject *itemToRemove) override { + bool removed = false; + if (itemToRemove) { + qInfo() << QStringLiteral("Removing ") << itemToRemove->metaObject()->className() << QStringLiteral(" : ") + << itemToRemove; + int index = 0; + for (auto item : mList) + if (item == itemToRemove) { + removed = removeRow(index); + break; + } else ++index; + if (!removed) + qWarning() << QStringLiteral("Unable to remove ") << itemToRemove->metaObject()->className() + << QStringLiteral(" : ") << itemToRemove; + } + return removed; + } + virtual bool remove(QSharedPointer itemToRemove) { + return remove(itemToRemove.get()); + } +}; + +#endif diff --git a/Linphone/core/proxy/Proxy.cpp b/Linphone/core/proxy/Proxy.cpp new file mode 100644 index 000000000..947ff013c --- /dev/null +++ b/Linphone/core/proxy/Proxy.cpp @@ -0,0 +1,36 @@ +/* + * Copyright (c) 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 "Proxy.hpp" + +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(); +} +bool Proxy::remove(QObject *itemToRemove) { + return false; +} +void Proxy::clearData() { +} +void Proxy::resetData() { +} diff --git a/Linphone/core/proxy/Proxy.hpp b/Linphone/core/proxy/Proxy.hpp new file mode 100644 index 000000000..87dd9166c --- /dev/null +++ b/Linphone/core/proxy/Proxy.hpp @@ -0,0 +1,44 @@ +/* + * Copyright (c) 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 PROXY_H_ +#define PROXY_H_ + +#include +#include + +// Use a regular declaration for Qt signal/slots handling +class Proxy : public QAbstractListModel { + Q_OBJECT +public: + Q_PROPERTY(int count READ getCount NOTIFY countChanged) + Q_PROPERTY(int length READ getCount NOTIFY countChanged) + + Proxy(QObject *parent = nullptr); + Q_INVOKABLE virtual int getCount() const; + Q_INVOKABLE virtual bool remove(QObject *itemToRemove); + Q_INVOKABLE virtual void clearData(); + Q_INVOKABLE virtual void resetData(); + +signals: + void countChanged(); +}; + +#endif diff --git a/Linphone/core/proxy/SortFilterProxy.cpp b/Linphone/core/proxy/SortFilterProxy.cpp new file mode 100644 index 000000000..c99a5fdb4 --- /dev/null +++ b/Linphone/core/proxy/SortFilterProxy.cpp @@ -0,0 +1,68 @@ +/* + * 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 "SortFilterProxy.hpp" + +SortFilterProxy::SortFilterProxy(QObject *parent) : QSortFilterProxyModel(parent) { + mFilterType = 0; + connect(this, &SortFilterProxy::rowsInserted, this, &SortFilterProxy::countChanged); + connect(this, &SortFilterProxy::rowsRemoved, this, &SortFilterProxy::countChanged); +} + +SortFilterProxy::~SortFilterProxy() { + if (mDeleteSourceModel) deleteSourceModel(); +} + +void SortFilterProxy::deleteSourceModel() { + auto oldSourceModel = sourceModel(); + if (oldSourceModel) { + oldSourceModel->deleteLater(); + setSourceModel(nullptr); + } +} + +int SortFilterProxy::getCount() const { + return rowCount(); +} + +int SortFilterProxy::getFilterType() const { + return mFilterType; +} + +QVariant SortFilterProxy::getAt(const int &atIndex) const { + auto modelIndex = index(atIndex, 0); + return sourceModel()->data(mapToSource(modelIndex), 0); +} + +void SortFilterProxy::setSortOrder(const Qt::SortOrder &order) { + sort(0, order); +} + +void SortFilterProxy::setFilterType(int filterType) { + if (getFilterType() != filterType) { + mFilterType = filterType; + emit filterTypeChanged(filterType); + invalidate(); + } +} + +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 new file mode 100644 index 000000000..8a5dec126 --- /dev/null +++ b/Linphone/core/proxy/SortFilterProxy.hpp @@ -0,0 +1,54 @@ +/* + * 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 SORT_FILTER_PROXY_H_ +#define SORT_FILTER_PROXY_H_ + +#include + +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) + + SortFilterProxy(QObject *parent = nullptr); + virtual ~SortFilterProxy(); + virtual void deleteSourceModel(); + + virtual int getCount() const; + virtual int getFilterType() const; + Q_INVOKABLE QVariant getAt(const int &index) const; + Q_INVOKABLE void setSortOrder(const Qt::SortOrder &order); + + virtual void setFilterType(int filterType); + + Q_INVOKABLE void remove(int index, int count = 1); + +signals: + void countChanged(); + void filterTypeChanged(int filterType); + +protected: + int mFilterType; + bool mDeleteSourceModel = false; +}; + +#endif diff --git a/Linphone/view/CMakeLists.txt b/Linphone/view/CMakeLists.txt index d4d7ce4ea..6ce235d3d 100644 --- a/Linphone/view/CMakeLists.txt +++ b/Linphone/view/CMakeLists.txt @@ -15,7 +15,9 @@ list(APPEND _LINPHONEAPP_QML_FILES view/Page/Login/LoginPage.qml view/Page/Login/SIPLoginPage.qml view/Page/Login/WelcomePage.qml - + +# Prototypes + view/Prototype/PhoneNumberItem.qml ) list(APPEND _LINPHONEAPP_QML_SINGLETONS @@ -24,4 +26,4 @@ list(APPEND _LINPHONEAPP_QML_SINGLETONS ) set(_LINPHONEAPP_QML_FILES ${_LINPHONEAPP_QML_FILES} PARENT_SCOPE) -set(_LINPHONEAPP_QML_SINGLETONS ${_LINPHONEAPP_QML_SINGLETONS} PARENT_SCOPE) \ No newline at end of file +set(_LINPHONEAPP_QML_SINGLETONS ${_LINPHONEAPP_QML_SINGLETONS} PARENT_SCOPE) diff --git a/Linphone/view/Prototype/PhoneNumberItem.qml b/Linphone/view/Prototype/PhoneNumberItem.qml new file mode 100644 index 000000000..ff5d24ca6 --- /dev/null +++ b/Linphone/view/Prototype/PhoneNumberItem.qml @@ -0,0 +1,29 @@ +import QtQuick 2.15 +import QtQuick.Layouts 1.0 +import QtQuick.Controls as Control +import Linphone +// Snippet + +ListView{ + id: mainItem + model: PhoneNumberProxy{} + delegate: Rectangle{ + height: 20 + width: mainItem.width + RowLayout{ + anchors.fill: parent + Text{ + text: $modelData.flag + font.family: 'Noto Color Emoji' + } + Text{ + text: $modelData.country + } + } + MouseArea{ + anchors.fill: parent + onClicked: console.debug("[ProtoPhoneNumber] Phone number Select: " +$modelData.flag + " / " +$modelData.nationalNumberLength + " / "+$modelData.countryCallingCode + " / " +$modelData.isoCountryCode + " / " +$modelData.internationalCallPrefix + " / " +$modelData.country ) + } + } +} +