paste code register
bold search result part of display names
fix magic search list
fix navigation
This commit is contained in:
Gaelle Braud 2024-09-20 15:07:40 +02:00
parent 1f764df150
commit e07cd93fad
46 changed files with 404 additions and 226 deletions

View file

@ -553,6 +553,7 @@ void App::initCppInterfaces() {
qmlRegisterType<FriendGui>(Constants::MainQmlUri, 1, 0, "FriendGui");
qmlRegisterUncreatableType<FriendCore>(Constants::MainQmlUri, 1, 0, "FriendCore", QLatin1String("Uncreatable"));
qmlRegisterType<MagicSearchProxy>(Constants::MainQmlUri, 1, 0, "MagicSearchProxy");
qmlRegisterType<MagicSearchList>(Constants::MainQmlUri, 1, 0, "MagicSearchList");
qmlRegisterType<CameraGui>(Constants::MainQmlUri, 1, 0, "CameraGui");
qmlRegisterType<FPSCounter>(Constants::MainQmlUri, 1, 0, "FPSCounter");

View file

@ -35,9 +35,9 @@ QSharedPointer<AccountDeviceList> AccountDeviceList::create() {
return model;
}
QSharedPointer<AccountDeviceList> AccountDeviceList::create(const std::shared_ptr<AccountModel> &accountModel) {
QSharedPointer<AccountDeviceList> AccountDeviceList::create(const QSharedPointer<AccountCore> &account) {
auto model = create();
model->setAccountModel(accountModel);
model->setAccount(account);
return model;
}
@ -59,15 +59,15 @@ AccountDeviceList::buildDevices(const std::list<std::shared_ptr<linphone::Accoun
return devices;
}
const std::shared_ptr<AccountModel> &AccountDeviceList::getAccountModel() const {
return mAccountModel;
const QSharedPointer<AccountCore> &AccountDeviceList::getAccount() const {
return mAccountCore;
}
void AccountDeviceList::setAccountModel(const std::shared_ptr<AccountModel> &accountModel) {
void AccountDeviceList::setAccount(const QSharedPointer<AccountCore> &accountCore) {
mustBeInMainThread(log().arg(Q_FUNC_INFO));
if (mAccountModel != accountModel) {
mAccountModel = accountModel;
lDebug() << log().arg("Set account model") << mAccountModel.get();
if (mAccountCore != accountCore) {
mAccountCore = accountCore;
lDebug() << log().arg("Set account model") << mAccountCore.get();
// oldConnect.unlock();
refreshDevices();
// }
@ -79,12 +79,12 @@ void AccountDeviceList::refreshDevices() {
beginResetModel();
clearData();
endResetModel();
if (mAccountModel) {
if (mAccountCore) {
auto requestDeviceList = [this] {
if (!mAccountManagerServicesModelConnection) return;
mAccountManagerServicesModelConnection->invokeToModel([this]() {
auto identityAddress = mAccountModel->getMonitor()->getParams()->getIdentityAddress();
auto authinfo = mAccountModel->getMonitor()->findAuthInfo();
auto identityAddress = mAccountCore->getModel()->getMonitor()->getParams()->getIdentityAddress();
auto authinfo = mAccountCore->getModel()->getMonitor()->findAuthInfo();
qDebug() << "[AccountDeviceList] request devices for address" << identityAddress->asStringUriOnly();
mAccountManagerServicesModel->getDeviceList(identityAddress);
});
@ -110,8 +110,8 @@ void AccountDeviceList::deleteDevice(AccountDeviceGui *deviceGui) {
auto deviceModel = deviceCore->getModel();
mAccountManagerServicesModelConnection->invokeToModel([this, deviceModel]() {
auto linphoneDevice = deviceModel->getDevice();
auto identityAddress = mAccountModel->getMonitor()->getParams()->getIdentityAddress();
auto authinfo = mAccountModel->getMonitor()->findAuthInfo();
auto identityAddress = mAccountCore->getModel()->getMonitor()->getParams()->getIdentityAddress();
auto authinfo = mAccountCore->getModel()->getMonitor()->findAuthInfo();
qDebug() << "[AccountDeviceList] delete device" << linphoneDevice->getName() << "of address"
<< identityAddress->asStringUriOnly();
mAccountManagerServicesModel->deleteDevice(identityAddress, linphoneDevice);

View file

@ -25,7 +25,6 @@
#include "AccountDeviceCore.hpp"
#include "core/account/AccountGui.hpp"
#include "model/account/AccountManagerServicesModel.hpp"
#include "model/account/AccountModel.hpp"
#include "tool/AbstractObject.hpp"
#include "tool/thread/SafeConnection.hpp"
@ -35,7 +34,7 @@ class AccountDeviceList : public ListProxy, public AbstractObject {
public:
static QSharedPointer<AccountDeviceList> create();
static QSharedPointer<AccountDeviceList> create(const std::shared_ptr<AccountModel> &accountModel);
static QSharedPointer<AccountDeviceList> create(const QSharedPointer<AccountCore> &accountCore);
AccountDeviceList();
~AccountDeviceList();
@ -43,8 +42,8 @@ public:
QList<QSharedPointer<AccountDeviceCore>>
buildDevices(const std::list<std::shared_ptr<linphone::AccountDevice>> &devicesList);
const std::shared_ptr<AccountModel> &getAccountModel() const;
void setAccountModel(const std::shared_ptr<AccountModel> &accountModel);
const QSharedPointer<AccountCore> &getAccount() const;
void setAccount(const QSharedPointer<AccountCore> &accountCore);
void refreshDevices();
void setDevices(QList<QSharedPointer<AccountDeviceCore>> devices);
@ -58,7 +57,7 @@ signals:
void componentReady();
private:
std::shared_ptr<AccountModel> mAccountModel;
QSharedPointer<AccountCore> mAccountCore;
std::shared_ptr<AccountManagerServicesModel> mAccountManagerServicesModel;
QSharedPointer<SafeConnection<AccountDeviceList, AccountManagerServicesModel>>
mAccountManagerServicesModelConnection;

View file

@ -37,22 +37,16 @@ AccountDeviceProxy::AccountDeviceProxy(QObject *parent) : SortFilterProxy(parent
}
AccountDeviceProxy::~AccountDeviceProxy() {
setSourceModel(nullptr);
// setSourceModel(nullptr);
}
AccountGui *AccountDeviceProxy::getAccount() const {
return mAccount ? new AccountGui(mAccount) : nullptr;
auto account = mAccountDeviceList->getAccount();
return account ? new AccountGui(account) : nullptr;
}
void AccountDeviceProxy::setAccount(AccountGui *accountGui) {
auto currentAccountModel = mAccountDeviceList->getAccountModel();
auto accountCore = accountGui ? QSharedPointer<AccountCore>(accountGui->getCore()) : nullptr;
auto newModel = accountCore ? accountCore->getModel() : nullptr;
if (newModel != currentAccountModel) {
mAccount = accountCore;
mAccountDeviceList->setAccountModel(accountGui->getCore()->getModel());
emit accountChanged();
}
mAccountDeviceList->setAccount(accountGui ? accountGui->mCore : nullptr);
}
void AccountDeviceProxy::deleteDevice(AccountDeviceGui *device) {

View file

@ -52,7 +52,6 @@ signals:
void accountChanged();
private:
QSharedPointer<AccountCore> mAccount;
QString mSearchText;
QSharedPointer<AccountDeviceList> mAccountDeviceList;
QSharedPointer<SafeConnection<AccountDeviceProxy, CoreModel>> mCoreModelConnection;

View file

@ -73,7 +73,8 @@ bool CallHistoryProxy::filterAcceptsRow(int sourceRow, const QModelIndex &source
QRegularExpression::CaseInsensitiveOption |
QRegularExpression::UseUnicodePropertiesOption);
auto callLog = qobject_cast<CallHistoryList *>(sourceModel())->getAt<CallHistoryCore>(sourceRow);
show = callLog->mRemoteAddress.contains(search) || callLog->mDisplayName.contains(search);
show =
callLog->mIsConference ? callLog->mDisplayName.contains(search) : callLog->mRemoteAddress.contains(search);
}
return show;

View file

@ -37,6 +37,13 @@ QSharedPointer<MagicSearchList> MagicSearchList::create() {
return model;
}
QSharedPointer<MagicSearchList> MagicSearchList::create(MagicSearchList *magicSearchList) {
auto model = QSharedPointer<MagicSearchList>(magicSearchList, &QObject::deleteLater);
model->moveToThread(App::getInstance()->thread());
model->setSelf(model);
return model;
}
MagicSearchList::MagicSearchList(QObject *parent) : ListProxy(parent) {
mustBeInMainThread(getClassName());
mSourceFlags = (int)linphone::MagicSearch::Source::Friends | (int)linphone::MagicSearch::Source::LdapServers;
@ -82,6 +89,10 @@ void MagicSearchList::setSelf(QSharedPointer<MagicSearchList> me) {
mModelConnection->makeConnectToCore(&MagicSearchList::lSetSourceFlags, [this](int flags) {
mModelConnection->invokeToModel([this, flags]() { mMagicSearch->setSourceFlags(flags); });
});
mModelConnection->makeConnectToCore(
&MagicSearchList::lSetAggregationFlag, [this](LinphoneEnums::MagicSearchAggregation flag) {
mModelConnection->invokeToModel([this, flag]() { mMagicSearch->setAggregationFlag(flag); });
});
mModelConnection->makeConnectToModel(&MagicSearchModel::sourceFlagsChanged, [this](int flags) {
mModelConnection->invokeToCore([this, flags]() { setSourceFlags(flags); });
});
@ -124,9 +135,15 @@ void MagicSearchList::setSelf(QSharedPointer<MagicSearchList> me) {
}
void MagicSearchList::setResults(const QList<QSharedPointer<FriendCore>> &contacts) {
for (auto item : mList) {
auto isFriendCore = item.objectCast<FriendCore>();
if (!isFriendCore) continue;
disconnect(isFriendCore.get());
}
resetData();
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);
}

View file

@ -36,6 +36,7 @@ class MagicSearchList : public ListProxy, public AbstractObject {
Q_OBJECT
public:
static QSharedPointer<MagicSearchList> create();
static QSharedPointer<MagicSearchList> create(MagicSearchList *magicSearchList);
MagicSearchList(QObject *parent = Q_NULLPTR);
~MagicSearchList();

View file

@ -23,29 +23,48 @@
#include "core/friend/FriendGui.hpp"
MagicSearchProxy::MagicSearchProxy(QObject *parent) : SortFilterProxy(parent) {
mList = MagicSearchList::create();
mSourceFlags = (int)LinphoneEnums::MagicSearchSource::Friends | (int)LinphoneEnums::MagicSearchSource::LdapServers;
mAggregationFlag = LinphoneEnums::MagicSearchAggregation::Friend;
(mList.get(), &MagicSearchList::sourceFlagsChanged, this, &MagicSearchProxy::sourceFlagsChanged);
connect(mList.get(), &MagicSearchList::aggregationFlagChanged, this, &MagicSearchProxy::aggregationFlagChanged);
connect(mList.get(), &MagicSearchList::friendCreated, this, [this](int index) {
auto proxyIndex = mapFromSource(sourceModel()->index(index, 0));
emit friendCreated(proxyIndex.row());
});
setSourceModel(mList.get());
connect(this, &MagicSearchProxy::forceUpdate, [this] { emit mList->lSearch(mSearchText); });
setSourceModel(new MagicSearchList());
sort(0);
connect(mList.get(), &MagicSearchList::initialized, this, [this] {
emit mList->lSetSourceFlags(mSourceFlags);
emit mList->lSetAggregationFlag(mAggregationFlag);
connect(this, &MagicSearchProxy::forceUpdate, [this] {
auto magicSearchList = qobject_cast<MagicSearchList *>(sourceModel());
if (magicSearchList) emit magicSearchList->lSearch(mSearchText);
});
}
MagicSearchProxy::~MagicSearchProxy() {
setSourceModel(nullptr);
}
void MagicSearchProxy::setSourceModel(QAbstractItemModel *model) {
auto oldMagicSearchList = dynamic_cast<MagicSearchList *>(sourceModel());
if (oldMagicSearchList) {
disconnect(oldMagicSearchList);
}
auto newMagicSearchList = dynamic_cast<MagicSearchList *>(model);
if (newMagicSearchList) {
mList = MagicSearchList::create(newMagicSearchList);
connect(newMagicSearchList, &MagicSearchList::sourceFlagsChanged, this, &MagicSearchProxy::sourceFlagsChanged);
connect(newMagicSearchList, &MagicSearchList::aggregationFlagChanged, this,
&MagicSearchProxy::aggregationFlagChanged);
connect(newMagicSearchList, &MagicSearchList::friendCreated, this, [this](int index) {
auto proxyIndex = mapFromSource(sourceModel()->index(index, 0));
emit friendCreated(proxyIndex.row());
});
connect(newMagicSearchList, &MagicSearchList::initialized, this, [this, newMagicSearchList] {
emit newMagicSearchList->lSetSourceFlags(mSourceFlags);
emit newMagicSearchList->lSetAggregationFlag(mAggregationFlag);
});
}
QSortFilterProxyModel::setSourceModel(model);
}
int MagicSearchProxy::findFriendIndexByAddress(const QString &address) {
return mapFromSource(mList->index(mList->findFriendIndexByAddress(address), 0)).row();
auto magicSearchList = qobject_cast<MagicSearchList *>(sourceModel());
if (magicSearchList)
return mapFromSource(magicSearchList->index(magicSearchList->findFriendIndexByAddress(address), 0)).row();
else return -1;
}
QString MagicSearchProxy::getSearchText() const {
@ -53,8 +72,10 @@ QString MagicSearchProxy::getSearchText() const {
}
void MagicSearchProxy::setSearchText(const QString &search) {
mSearchText = search;
mList->setSearch(mSearchText);
if (mSearchText != search) {
mSearchText = search;
mList->setSearch(mSearchText);
}
}
int MagicSearchProxy::getSourceFlags() const {
@ -68,6 +89,17 @@ void MagicSearchProxy::setSourceFlags(int flags) {
}
}
bool MagicSearchProxy::showFavouritesOnly() const {
return mShowFavouritesOnly;
}
void MagicSearchProxy::setShowFavouritesOnly(bool show) {
if (mShowFavouritesOnly != show) {
mShowFavouritesOnly = show;
emit showFavouriteOnlyChanged();
}
}
LinphoneEnums::MagicSearchAggregation MagicSearchProxy::getAggregationFlag() const {
return mAggregationFlag;
}
@ -79,6 +111,17 @@ void MagicSearchProxy::setAggregationFlag(LinphoneEnums::MagicSearchAggregation
}
}
bool MagicSearchProxy::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const {
QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent);
auto model = sourceModel()->data(index);
auto friendGui = model.value<FriendGui *>();
auto friendCore = friendGui->getCore();
if (friendCore) {
return !mShowFavouritesOnly || friendCore->getStarred();
}
return false;
}
bool MagicSearchProxy::lessThan(const QModelIndex &left, const QModelIndex &right) const {
auto l = sourceModel()->data(left);
auto r = sourceModel()->data(right);
@ -92,4 +135,4 @@ bool MagicSearchProxy::lessThan(const QModelIndex &left, const QModelIndex &righ
return lName < rName;
}
return true;
}
}

View file

@ -34,6 +34,8 @@ class MagicSearchProxy : public SortFilterProxy {
Q_PROPERTY(int sourceFlags READ getSourceFlags WRITE setSourceFlags NOTIFY sourceFlagsChanged)
Q_PROPERTY(LinphoneEnums::MagicSearchAggregation aggregationFlag READ getAggregationFlag WRITE setAggregationFlag
NOTIFY aggregationFlagChanged)
Q_PROPERTY(
bool showFavouritesOnly READ showFavouritesOnly WRITE setShowFavouritesOnly NOTIFY showFavouriteOnlyChanged)
public:
MagicSearchProxy(QObject *parent = Q_NULLPTR);
@ -48,6 +50,11 @@ public:
LinphoneEnums::MagicSearchAggregation getAggregationFlag() const;
void setAggregationFlag(LinphoneEnums::MagicSearchAggregation flag);
bool showFavouritesOnly() const;
void setShowFavouritesOnly(bool show);
void setSourceModel(QAbstractItemModel *sourceModel) override;
// Q_INVOKABLE forceUpdate();
Q_INVOKABLE int findFriendIndexByAddress(const QString &address);
@ -57,12 +64,15 @@ signals:
void aggregationFlagChanged(LinphoneEnums::MagicSearchAggregation aggregationFlag);
void forceUpdate();
void friendCreated(int index);
void showFavouriteOnlyChanged();
protected:
QString mSearchText;
int mSourceFlags;
bool mShowFavouritesOnly = false;
LinphoneEnums::MagicSearchAggregation mAggregationFlag;
QSharedPointer<MagicSearchList> mList;
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override;
virtual bool lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const override;
};

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 25 KiB

View file

@ -302,7 +302,7 @@ QString Utils::interpretUrl(const QString &uri) {
QString address = uri;
if (!address.contains('@')) {
App::postModelBlock([address, uri]() mutable {
App::postModelBlock([&address, uri]() mutable {
auto addr = ToolModel::interpretUrl(uri);
if (addr) address = Utils::coreStringToAppString(addr->asStringUriOnly());
});
@ -1357,4 +1357,25 @@ void Utils::useFetchConfig(const QString &configUrl) {
void Utils::playDtmf(const QString &dtmf) {
const char key = dtmf.constData()[0].toLatin1();
App::postModelSync([key]() { CoreModel::getInstance()->getCore()->playDtmf(key, 200); });
}
bool Utils::isInteger(const QString &text) {
QRegularExpression re(QRegularExpression::anchoredPattern("\\d+"));
if (re.match(text).hasMatch()) {
return true;
}
return false;
}
QString Utils::boldTextPart(const QString &text, const QString &regex) {
int regexIndex = text.indexOf(regex, 0, Qt::CaseInsensitive);
if (regex.isEmpty() || regexIndex == -1) return text;
QString result;
QStringList splittedText = text.split(regex, Qt::KeepEmptyParts, Qt::CaseInsensitive);
for (int i = 0; i < splittedText.size() - 1; ++i) {
result.append(splittedText[i]);
result.append("<b>" + regex + "</b>");
}
if (splittedText.size() > 0) result.append(splittedText[splittedText.size() - 1]);
return result;
}

View file

@ -128,6 +128,8 @@ public:
static QString getCountryName(const QLocale::Territory &p_country);
Q_INVOKABLE static void useFetchConfig(const QString &configUrl);
Q_INVOKABLE void playDtmf(const QString &dtmf);
Q_INVOKABLE bool isInteger(const QString &text);
Q_INVOKABLE QString boldTextPart(const QString &text, const QString &regex);
static QString getApplicationProduct();
static QString getOsProduct();

View file

@ -65,7 +65,7 @@ Control.Button {
// Crash : https://bugreports.qt.io/browse/QTBUG-124730
shadowEnabled: true //mainItem.shadowEnabled
shadowColor: DefaultStyle.grey_1000
shadowBlur: 1
shadowBlur: 0.1
shadowOpacity: mainItem.shadowEnabled ? 0.5 : 0.0
}
}

View file

@ -47,7 +47,7 @@ ComboBox {
anchors.fill: calendarBg
source: calendarBg
shadowEnabled: true
shadowBlur: 1
shadowBlur: 0.1
shadowOpacity: 0.1
}
}

View file

@ -33,7 +33,7 @@ Control.CheckBox {
// Crash : https://bugreports.qt.io/browse/QTBUG-124730
shadowEnabled: true //mainItem.shadowEnabled
shadowColor: DefaultStyle.grey_1000
shadowBlur: 1
shadowBlur: 0.1
shadowOpacity: mainItem.shadowEnabled ? 0.5 : 0.0
}
}

View file

@ -238,7 +238,7 @@ Control.ComboBox {
source: cboxBg
shadowEnabled: true
shadowColor: DefaultStyle.grey_1000
shadowBlur: 1
shadowBlur: 0.1
shadowOpacity: 0.1
}
}

View file

@ -112,6 +112,7 @@ ColumnLayout {
keyNavigationEnabled: true
keyNavigationWraps: true
maximumFlickVelocity: 1500
spacing: 10 * DefaultStyle.dp
highlight: Rectangle {
anchors.left: parent.left
anchors.right: parent.right
@ -205,7 +206,7 @@ ColumnLayout {
source: popupBg
shadowEnabled: true
shadowColor: DefaultStyle.grey_1000
shadowBlur: 1
shadowBlur: 0.1
shadowOpacity: 0.1
}
}

View file

@ -64,7 +64,7 @@ MouseArea {
// Crash : https://bugreports.qt.io/browse/QTBUG-124730
shadowEnabled: true //mainItem.shadowEnabled
shadowColor: DefaultStyle.grey_1000
shadowBlur: 1
shadowBlur: 0.1
shadowOpacity: mainItem.shadowEnabled ? 0.5 : 0.0
}
}

View file

@ -42,7 +42,7 @@ Item{
// Crash : https://bugreports.qt.io/browse/QTBUG-124730
shadowEnabled: true //mainItem.shadowEnabled
shadowColor: DefaultStyle.grey_1000
shadowBlur: 1
shadowBlur: 0.1
shadowOpacity: mainItem.shadowEnabled ? 0.5 : 0.0
}*/

View file

@ -51,7 +51,7 @@ Button {
// Crash : https://bugreports.qt.io/browse/QTBUG-124730
shadowEnabled: true //mainItem.shadowEnabled
shadowColor: DefaultStyle.grey_1000
shadowBlur: 1
shadowBlur: 0.1
shadowOpacity: mainItem.shadowEnabled ? 0.5 : 0.0
}
}
@ -102,8 +102,8 @@ Button {
source: popupBackground
anchors.fill: popupBackground
shadowEnabled: true
shadowBlur: 1
shadowColor: DefaultStyle.grey_900
shadowBlur: 0.1
shadowColor: DefaultStyle.grey_1000
shadowOpacity: 0.4
}
}

View file

@ -52,7 +52,7 @@ Control.RadioButton {
// Crash : https://bugreports.qt.io/browse/QTBUG-124730
shadowEnabled: true //mainItem.shadowEnabled
shadowColor: DefaultStyle.grey_1000
shadowBlur: 1
shadowBlur: 0.1
shadowOpacity: mainItem.shadowEnabled ? 0.5 : 0.0
}
}

View file

@ -41,7 +41,7 @@ Control.Slider {
// Crash : https://bugreports.qt.io/browse/QTBUG-124730
shadowEnabled: true //mainItem.shadowEnabled
shadowColor: DefaultStyle.grey_1000
shadowBlur: 1
shadowBlur: 0.1
shadowOpacity: mainItem.shadowEnabled ? 0.5 : 0.0
}
}
@ -62,7 +62,7 @@ Control.Slider {
anchors.fill: handleRect
shadowEnabled: true
shadowColor: DefaultStyle.grey_1000
shadowBlur: 1
shadowBlur: 0.1
shadowOpacity: 0.1
}
}

View file

@ -44,7 +44,7 @@ Control.Switch {
// Crash : https://bugreports.qt.io/browse/QTBUG-124730
shadowEnabled: true //mainItem.shadowEnabled
shadowColor: DefaultStyle.grey_1000
shadowBlur: 1
shadowBlur: 0.1
shadowOpacity: mainItem.shadowEnabled ? 0.5 : 0.0
}
}

View file

@ -78,7 +78,7 @@ Control.TabBar {
// Crash : https://bugreports.qt.io/browse/QTBUG-124730
shadowEnabled: true //mainItem.shadowEnabled
shadowColor: DefaultStyle.grey_1000
shadowBlur: 1
shadowBlur: 0.1
shadowOpacity: tabButton.shadowEnabled ? 0.5 : 0.0
}
}

View file

@ -143,7 +143,7 @@ StackView {
source: initialItem
anchors.fill: initialItem
shadowEnabled: true
shadowBlur: 1
shadowBlur: 0.1
shadowColor: DefaultStyle.grey_1000
shadowOpacity: 0.1
}

View file

@ -14,7 +14,6 @@ ListView {
//keyNavigationWraps: true
// rightMargin: 5 * DefaultStyle.dp
property string searchBarText
property bool selectionEnabled: true
property bool hoverEnabled: true
@ -24,7 +23,18 @@ ListView {
property bool actionLayoutVisible: false
property bool initialHeadersVisible: true
property bool displayNameCapitalization: true
property bool showOnlyFavourites: false
property bool showFavouritesOnly: false
property bool showDefaultAddress: false
property var sourceModel: MagicSearchList{}
// Model properties
// set searchBarText without specifying a model to bold
// matching names
property string searchBarText
property string searchText: searchBarText.length === 0 ? "*" : searchBarText
property var aggregationFlag: LinphoneEnums.MagicSearchAggregation.Friend
property var sourceFlags: LinphoneEnums.MagicSearchSource.Friends | LinphoneEnums.MagicSearchSource.LdapServers
property ConferenceInfoGui confInfoGui
@ -76,12 +86,19 @@ ListView {
}else {
currentIndex = -1
}
model: MagicSearchProxy {
id: magicSearchProxy
searchText: searchBarText.length === 0 ? "*" : searchBarText
searchText: mainItem.searchText
// This property is needed instead of playing on the delegate visibility
// considering its starred status. Otherwise, the row in the list still
// exists even if its delegate is not visible, and creates navigation issues
showFavouritesOnly: mainItem.showFavouritesOnly
onFriendCreated: (index) => {
mainItem.currentIndex = index
}
aggregationFlag: mainItem.aggregationFlag
sourceModel: mainItem.sourceModel
}
Control.ScrollBar.vertical: ScrollBar {
@ -99,13 +116,11 @@ ListView {
}
delegate: FocusScope {
id: itemDelegate
height: display ? 56 * DefaultStyle.dp : 0
height: 56 * DefaultStyle.dp
width: mainItem.width
property var previousItem : mainItem.model.count > 0 && index > 0 ? mainItem.model.getAt(index-1) : null
property var previousDisplayName: previousItem ? previousItem.core.displayName : ""
property var displayName: modelData.core.displayName
property bool display: !mainItem.showOnlyFavourites || modelData.core.starred
visible: display
Connections {
enabled: modelData.core
@ -134,19 +149,34 @@ ListView {
anchors.left: initial.visible ? initial.right : parent.left
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
spacing: 10 * DefaultStyle.dp
spacing: 16 * DefaultStyle.dp
z: 1
Avatar {
Layout.preferredWidth: 45 * DefaultStyle.dp
Layout.preferredHeight: 45 * DefaultStyle.dp
contact: modelData
}
Text {
text: itemDelegate.displayName
font.pixelSize: 14 * DefaultStyle.dp
font.capitalization: mainItem.displayNameCapitalization ? Font.Capitalize : Font.MixedCase
maximumLineCount: 1
Layout.fillWidth: true
ColumnLayout {
spacing: 0
Text {
text: UtilsCpp.boldTextPart(itemDelegate.displayName, mainItem.searchBarText)
font{
pixelSize: mainItem.showDefaultAddress ? 16 * DefaultStyle.dp : 14 * DefaultStyle.dp
capitalization: mainItem.displayNameCapitalization ? Font.Capitalize : Font.MixedCase
weight: mainItem.showDefaultAddress ? 800 * DefaultStyle.dp : 400 * DefaultStyle.dp
}
maximumLineCount: 1
Layout.fillWidth: true
}
Text {
Layout.topMargin: 2 * DefaultStyle.dp
visible: mainItem.showDefaultAddress
text: modelData.core.defaultAddress
font {
weight: 300 * DefaultStyle.dp
pixelSize: 12 * DefaultStyle.dp
}
}
}
EffectImage {
id: isSelectedCheck
@ -169,7 +199,7 @@ ListView {
// anchors.right: parent.right
Layout.rightMargin: 5 * DefaultStyle.dp
// anchors.verticalCenter: parent.verticalCenter
spacing: 10 * DefaultStyle.dp // TODO : change when mockup ready
spacing: 16 * DefaultStyle.dp
RowLayout{
id: actionButtons
visible: mainItem.actionLayoutVisible
@ -304,7 +334,7 @@ ListView {
if (mouse && mouse.button == Qt.RightButton) {
friendPopup.open()
} else {
mainItem.currentIndex = -1
mainItem.forceActiveFocus()
mainItem.currentIndex = index
if (mainItem.multiSelectionEnabled) {
var indexInSelection = mainItem.selectedContacts.indexOf(modelData.core.defaultAddress)

View file

@ -49,7 +49,7 @@ Item {
// // Crash : https://bugreports.qt.io/browse/QTBUG-124730
// shadowEnabled: true //mainItem.shadowEnabled
// shadowColor: DefaultStyle.grey_1000
// shadowBlur: 1
// shadowBlur: 0.1
// shadowOpacity: mainItem.shadowEnabled ? 0.5 : 0.0
// }
onClicked: {

View file

@ -267,7 +267,7 @@ Item {
anchors.fill: background
shadowEnabled: true
shadowColor: DefaultStyle.grey_1000
shadowBlur: 1
shadowBlur: 0.1
shadowOpacity: 0.4
}
RowLayout{

View file

@ -7,12 +7,19 @@ import Linphone
Text {
id: mainItem
color: DefaultStyle.danger_500main
visible: false
function clear() {
autoHideErrorMessage.stop()
text = ""
mainItem.visible = false
}
function setText(text) {
mainItem.text = text
if (text.length === 0) {
clear()
} else {
mainItem.visible = true
mainItem.text = text
}
}
font {
pixelSize: 12 * DefaultStyle.dp
@ -21,7 +28,9 @@ Text {
Timer {
id: autoHideErrorMessage
interval: 5000
onTriggered: mainItem.text = ""
onTriggered: {
mainItem.clear()
}
}
onTextChanged: if (mainItem.text.length > 0) autoHideErrorMessage.restart()

View file

@ -16,7 +16,7 @@ ColumnLayout {
enableErrorText: true
contentItem: TextField {
id: usernameEdit
isError: username.errorTextVisible
isError: username.errorTextVisible || errorText.visible
Layout.preferredWidth: 360 * DefaultStyle.dp
Layout.preferredHeight: 49 * DefaultStyle.dp
}
@ -30,7 +30,7 @@ ColumnLayout {
enableErrorText: true
contentItem: TextField {
id: passwordEdit
isError: password.errorTextVisible
isError: password.errorTextVisible || errorText.visible
Layout.preferredWidth: 360 * DefaultStyle.dp
Layout.preferredHeight: 49 * DefaultStyle.dp
hidden: true
@ -130,7 +130,7 @@ ColumnLayout {
color: DefaultStyle.main2_500main
text: qsTr("Mot de passe oublié ?")
font{
underline: forgottenButton.underline
underline: true
pixelSize: 13 * DefaultStyle.dp
weight: 600 * DefaultStyle.dp
}

View file

@ -42,7 +42,7 @@ Control.TextField {
return true
}
property int idleTimeOut: 200
property bool empty: mainItem.propertyOwner[mainItem.propertyName]?.length == 0
property bool empty: mainItem.propertyOwner!= undefined && mainItem.propertyOwner[mainItem.propertyName]?.length == 0
property bool canBeEmpty: true
signal validationChecked(bool valid)
@ -144,7 +144,7 @@ Control.TextField {
running: false
interval: mainItem.idleTimeOut
repeat: false
onTriggered: textField.editingFinished()
onTriggered: mainItem.editingFinished()
}
onEditingFinished: {
updateText()
@ -162,7 +162,7 @@ Control.TextField {
mainItem.validationChecked(false)
return
}
if (isValid(text)) {
if (isValid(text) && mainItem.propertyOwner && mainItem.propertyName) {
if (mainItem.propertyOwner[mainItem.propertyName] != text)
mainItem.propertyOwner[mainItem.propertyName] = text
mainItem.validationChecked(true)

View file

@ -111,7 +111,7 @@ Dialog {
source: backgroundItem
shadowEnabled: true
shadowColor: DefaultStyle.grey_900
shadowBlur: 1.0
shadowBlur: 0.1
shadowOpacity: 0.1
}
}
@ -215,7 +215,7 @@ Dialog {
anchors.fill: code
shadowEnabled: true
shadowOpacity: 0.1
shadowBlur: 1.0
shadowBlur: 0.1
}
}
}

View file

@ -65,6 +65,6 @@ DesktopPopup {
shadowEnabled: true
shadowColor: DefaultStyle.grey_1000
shadowOpacity: 0.1
shadowBlur: 1
shadowBlur: 0.1
}
}

View file

@ -37,7 +37,7 @@ Control.Popup {
shadowEnabled: true
shadowColor: DefaultStyle.grey_1000
shadowOpacity: 0.1
shadowBlur: 1
shadowBlur: 0.1
z: -1
}
Rectangle {

View file

@ -30,8 +30,8 @@ Control.Popup{
anchors.fill: backgroundItem
source: backgroundItem
shadowEnabled: true
shadowColor: DefaultStyle.grey_900
shadowBlur: 1.0
shadowColor: DefaultStyle.grey_1000
shadowBlur: 0.1
shadowOpacity: 0.1
}
MouseArea {

View file

@ -126,9 +126,7 @@ FocusScope {
Layout.preferredHeight: contentHeight
Control.ScrollBar.vertical.visible: false
contactMenuVisible: false
model: MagicSearchProxy {
searchText: searchBar.text.length === 0 ? "*" : searchBar.text
}
searchBarText: searchBar.text
onSelectedContactChanged: mainItem.selectedContact = selectedContact
onClicked: mainItem.callSelectedContact()
}
@ -151,11 +149,8 @@ FocusScope {
Layout.preferredHeight: contentHeight
initialHeadersVisible: false
displayNameCapitalization: false
model: MagicSearchProxy {
searchText: searchBar.text.length === 0 ? "*" : searchBar.text
sourceFlags: LinphoneEnums.MagicSearchSource.All
aggregationFlag: LinphoneEnums.MagicSearchAggregation.Friend
}
searchBarText: searchBar.text
sourceFlags: LinphoneEnums.MagicSearchSource.All
onSelectedContactChanged: mainItem.selectedContact = selectedContact
onClicked: mainItem.callSelectedContact()
}

View file

@ -83,89 +83,96 @@ LoginLayout {
Component {
id: firstItem
ColumnLayout {
spacing: 0
spacing: 85 * DefaultStyle.dp
Layout.maximumHeight: 420 * DefaultStyle.dp
ColumnLayout {
Text {
Layout.fillWidth: true
Layout.preferredWidth: rootStackView.width
wrapMode: Text.WordWrap
color: DefaultStyle.main2_600
font {
pixelSize: 14 * DefaultStyle.dp
weight: 400* DefaultStyle.dp
spacing: 0
ColumnLayout {
spacing: 28 * DefaultStyle.dp
Text {
Layout.fillWidth: true
Layout.preferredWidth: rootStackView.width
wrapMode: Text.WordWrap
color: DefaultStyle.main2_900
font {
pixelSize: 14 * DefaultStyle.dp
weight: 400* DefaultStyle.dp
}
text: "Certaines fonctionnalités nécessitent un compte Linphone, comme la messagerie de groupe, les vidéoconférences..."
}
Text {
Layout.fillWidth: true
Layout.preferredWidth: rootStackView.width
wrapMode: Text.WordWrap
color: DefaultStyle.main2_900
font {
pixelSize: 14 * DefaultStyle.dp
weight: 400* DefaultStyle.dp
}
text:"Ces fonctionnalités sont cachées lorsque vous vous enregistrez avec un compte SIP tiers."
}
Text {
Layout.fillWidth: true
Layout.preferredWidth: rootStackView.width
wrapMode: Text.WordWrap
color: DefaultStyle.main2_900
font {
pixelSize: 14 * DefaultStyle.dp
weight: 400* DefaultStyle.dp
}
text: "Pour les activer dans un projet commercial, veuillez nous contacter. "
}
text: "Certaines fonctionnalités nécessitent un compte Linphone, comme la messagerie de groupe, les vidéoconférences..."
}
Text {
Layout.fillWidth: true
Layout.preferredWidth: rootStackView.width
wrapMode: Text.WordWrap
color: DefaultStyle.main2_600
font {
pixelSize: 14 * DefaultStyle.dp
weight: 400* DefaultStyle.dp
Button {
id: openLinkButton
Layout.alignment: Qt.AlignCenter
Layout.topMargin: 18 * DefaultStyle.dp
text: "linphone.org/contact"
textSize: 13 * DefaultStyle.dp
inversedColors: true
leftPadding: 12 * DefaultStyle.dp
rightPadding: 12 * DefaultStyle.dp
topPadding: 6 * DefaultStyle.dp
bottomPadding: 6 * DefaultStyle.dp
onClicked: {
Qt.openUrlExternally(ConstantsCpp.ContactUrl)
}
text:"Ces fonctionnalités sont cachées lorsque vous vous enregistrez avec un compte SIP tiers."
}
Text {
Layout.fillWidth: true
Layout.preferredWidth: rootStackView.width
wrapMode: Text.WordWrap
color: DefaultStyle.main2_600
font {
pixelSize: 14 * DefaultStyle.dp
weight: 400* DefaultStyle.dp
}
text: "Pour les activer dans un projet commercial, veuillez nous contacter. "
KeyNavigation.up: backButton
KeyNavigation.down: createAccountButton
}
}
Button {
id: openLinkButton
Layout.alignment: Qt.AlignCenter
Layout.topMargin: 18 * DefaultStyle.dp
text: "linphone.org/contact"
textSize: 13 * DefaultStyle.dp
inversedColors: true
leftPadding: 12 * DefaultStyle.dp
rightPadding: 12 * DefaultStyle.dp
topPadding: 6 * DefaultStyle.dp
bottomPadding: 6 * DefaultStyle.dp
onClicked: {
Qt.openUrlExternally(ConstantsCpp.ContactUrl)
ColumnLayout {
spacing: 20 * DefaultStyle.dp
Button {
id: createAccountButton
// Layout.topMargin: 85 * DefaultStyle.dp
Layout.fillWidth: true
inversedColors: true
text: qsTr("Créer un compte linphone")
leftPadding: 20 * DefaultStyle.dp
rightPadding: 20 * DefaultStyle.dp
topPadding: 11 * DefaultStyle.dp
bottomPadding: 11 * DefaultStyle.dp
onClicked: {
console.debug("[SIPLoginPage] User: click register")
mainItem.goToRegister()
}
KeyNavigation.up: openLinkButton
KeyNavigation.down: continueButton
}
KeyNavigation.up: backButton
KeyNavigation.down: createAccountButton
}
Button {
id: createAccountButton
Layout.topMargin: 85 * DefaultStyle.dp
Layout.fillWidth: true
inversedColors: true
text: qsTr("Créer un compte linphone")
leftPadding: 20 * DefaultStyle.dp
rightPadding: 20 * DefaultStyle.dp
topPadding: 11 * DefaultStyle.dp
bottomPadding: 11 * DefaultStyle.dp
onClicked: {
console.debug("[SIPLoginPage] User: click register")
mainItem.goToRegister()
Button {
id: continueButton
Layout.fillWidth: true
text: qsTr("Je comprends")
leftPadding: 20 * DefaultStyle.dp
rightPadding: 20 * DefaultStyle.dp
topPadding: 11 * DefaultStyle.dp
bottomPadding: 11 * DefaultStyle.dp
onClicked: {
rootStackView.replace(secondItem)
}
KeyNavigation.up: createAccountButton
}
KeyNavigation.up: openLinkButton
KeyNavigation.down: continueButton
}
Button {
id: continueButton
Layout.topMargin: 20 * DefaultStyle.dp
Layout.fillWidth: true
text: qsTr("Je comprends")
leftPadding: 20 * DefaultStyle.dp
rightPadding: 20 * DefaultStyle.dp
topPadding: 11 * DefaultStyle.dp
bottomPadding: 11 * DefaultStyle.dp
onClicked: {
rootStackView.replace(secondItem)
}
KeyNavigation.up: createAccountButton
}
Item {
Layout.fillHeight: true

View file

@ -2,6 +2,7 @@ import QtQuick 2.15
import QtQuick.Layouts 1.3
import QtQuick.Controls as Control
import Linphone
import UtilsCpp
LoginLayout {
id: mainItem
@ -11,6 +12,8 @@ LoginLayout {
property string address
property string sipIdentityAddress
property string code
property bool ctrlIsPressed
onCtrlIsPressedChanged: console.log("ctrl is pressed", ctrlIsPressed)
titleContent: [
RowLayout {
spacing: 21 * DefaultStyle.dp
@ -74,11 +77,26 @@ LoginLayout {
spacing: 45 * DefaultStyle.dp
Repeater {
model: 4
id: repeater
signal pasteRequested(string text)
DigitInput {
id: digitInput
required property int index
Layout.preferredWidth: width
Layout.preferredHeight: height
onTextEdited: {
Connections {
target: repeater
function onPasteRequested(text) {
console.log("paste requested", text[digitInput.index])
var test= text;
if (UtilsCpp.isInteger(text))
{
digitInput.text = text[digitInput.index]
}
}
}
onTextChanged: {
console.log("text edited", text)
if (text.length > 0 ) {
mainItem.code = mainItem.code.slice(0, index) + text + mainItem.code.slice(index)
if (index < 3)
@ -90,7 +108,32 @@ LoginLayout {
} else {
if (index > 0)
nextItemInFocusChain(false).forceActiveFocus()
}
}
}
Keys.onPressed: (event) => {
if (event.key == Qt.Key_Backspace) {
if (text.length === 0) {
nextItemInFocusChain(false).forceActiveFocus()
event.accepted = true
} else {
event.accepted = false
}
} else if (event.key == Qt.Key_Control) {
mainItem.ctrlIsPressed = true
event.accepted = false
} else if (mainItem.ctrlIsPressed && event.key == Qt.Key_V) {
var clipboard = UtilsCpp.getClipboardText()
console.log("paste", clipboard)
repeater.pasteRequested(clipboard)
} else {
event.accepted = false
}
}
Keys.onReleased: (event) => {
if (event.key == Qt.Key_Control) {
mainItem.ctrlIsPressed = false
event.accepted = true
}
}
}
}

View file

@ -15,7 +15,7 @@ AbstractMainPage {
signal goBack()
function layoutUrl(name) {
function layoutUrl(name) {
return layoutsPath+"/"+name+".qml"
}

View file

@ -233,7 +233,7 @@ Item {
source: popupBg
anchors.fill: popupBg
shadowEnabled: true
shadowBlur: 1
shadowBlur: 0.1
shadowColor: DefaultStyle.grey_1000
shadowOpacity: 0.1
}
@ -260,11 +260,9 @@ Item {
contactMenuVisible: false
actionLayoutVisible: true
selectionEnabled: false
showDefaultAddress: true
Control.ScrollBar.vertical: scrollbar
model: MagicSearchProxy {
searchText: magicSearchBar.text.length === 0 ? "*" : magicSearchBar.text
aggregationFlag: LinphoneEnums.MagicSearchAggregation.Friend
}
searchText: magicSearchBar.text
Keys.onPressed: (event) => {
if(event.key == Qt.Key_Down){
@ -335,13 +333,11 @@ Item {
Layout.preferredHeight: 45 * DefaultStyle.dp
_address: magicSearchBar.text
}
ColumnLayout {
Text {
text: magicSearchBar.text
font {
pixelSize: 12 * DefaultStyle.dp
weight: 300 * DefaultStyle.dp
}
Text {
text: UtilsCpp.interpretUrl(magicSearchBar.text)
font {
pixelSize: 12 * DefaultStyle.dp
weight: 300 * DefaultStyle.dp
}
}
Item {

View file

@ -46,7 +46,7 @@ AbstractSettingsLayout {
Layout.rightMargin: 44 * DefaultStyle.dp
Layout.leftMargin: 64 * DefaultStyle.dp
Layout.topMargin: 20 * DefaultStyle.dp
ValidatedTextField {
DecoratedTextField {
propertyName: "mwiServerAddress"
propertyOwner: account.core
title: qsTr("URI du serveur de messagerie vocale")
@ -105,7 +105,7 @@ AbstractSettingsLayout {
propertyName: "transport"
propertyOwner: account.core
}
ValidatedTextField {
DecoratedTextField {
title: qsTr("URL du serveur mandataire")
propertyName: "serverAddress"
propertyOwner: account.core
@ -116,7 +116,7 @@ AbstractSettingsLayout {
propertyName: "outboundProxyEnabled"
propertyOwner: account.core
}
ValidatedTextField {
DecoratedTextField {
propertyName: "stunServer"
propertyOwner: account.core
title: qsTr("Adresse du serveur STUN")
@ -137,26 +137,26 @@ AbstractSettingsLayout {
propertyName: "bundleModeEnabled"
propertyOwner: account.core
}
ValidatedTextField {
DecoratedTextField {
propertyName: "expire"
propertyOwner: account.core
title: qsTr("Expiration (en seconde)")
canBeEmpty: false
isValid: function(text) { return !isNaN(Number(text)); }
}
ValidatedTextField {
DecoratedTextField {
title: qsTr("URI de lusine à conversations")
propertyName: "conferenceFactoryAddress"
propertyOwner: account.core
isValid: function(text) { return UtilsCpp.isValidSIPAddress(text); }
}
ValidatedTextField {
DecoratedTextField {
title: qsTr("URI de lusine à réunions")
propertyName: "audioVideoConferenceFactoryAddress"
propertyOwner: account.core
isValid: function(text) { return UtilsCpp.isValidSIPAddress(text); }
}
ValidatedTextField {
DecoratedTextField {
title: qsTr("URL du serveur déchange de clés de chiffrement")
propertyName: "limeServerUrl"
propertyOwner: account.core

View file

@ -93,18 +93,18 @@ AbstractSettingsLayout {
Layout.rightMargin: 44 * DefaultStyle.dp
Layout.topMargin: 20 * DefaultStyle.dp
Layout.leftMargin: 64 * DefaultStyle.dp
ValidatedTextField {
DecoratedTextField {
id: server
propertyName: "server"
propertyOwner: ldapGui.core
title: qsTr("URL du serveur (ne peut être vide)")
}
ValidatedTextField {
DecoratedTextField {
propertyName: "bindDn"
propertyOwner: ldapGui.core
title: qsTr("Bind DN")
}
ValidatedTextField {
DecoratedTextField {
propertyName: "password"
hidden: true
propertyOwner: ldapGui.core
@ -115,51 +115,51 @@ AbstractSettingsLayout {
propertyName: "tls"
propertyOwner: ldapGui.core
}
ValidatedTextField {
DecoratedTextField {
propertyName: "baseObject"
propertyOwner: ldapGui.core
title: qsTr("Base de recherche (ne peut être vide)")
}
ValidatedTextField {
DecoratedTextField {
propertyName: "filter"
propertyOwner: ldapGui.core
title: qsTr("Filtre")
}
ValidatedTextField {
DecoratedTextField {
propertyName: "maxResults"
propertyOwner: ldapGui.core
validator: RegularExpressionValidator { regularExpression: /[0-9]+/ }
title: qsTr("Nombre maximum de résultats")
}
ValidatedTextField {
DecoratedTextField {
propertyName: "delay"
propertyOwner: ldapGui.core
validator: RegularExpressionValidator { regularExpression: /[0-9]+/ }
title: qsTr("Délai entre 2 requêtes (en millisecondes)")
}
ValidatedTextField {
DecoratedTextField {
propertyName: "timeout"
propertyOwner: ldapGui.core
title: qsTr("Durée maximun (en secondes)")
validator: RegularExpressionValidator { regularExpression: /[0-9]+/ }
}
ValidatedTextField {
DecoratedTextField {
propertyName: "minChars"
propertyOwner: ldapGui.core
title: qsTr("Nombre minimum de caractères pour la requête")
validator: RegularExpressionValidator { regularExpression: /[0-9]+/ }
}
ValidatedTextField {
DecoratedTextField {
propertyName: "nameAttribute"
propertyOwner: ldapGui.core
title: qsTr("Attributs de nom")
}
ValidatedTextField {
DecoratedTextField {
propertyName: "sipAttribute"
propertyOwner: ldapGui.core
title: qsTr("Attributs SIP")
}
ValidatedTextField {
DecoratedTextField {
propertyName: "sipDomain"
propertyOwner: ldapGui.core
title: qsTr("Domaine SIP")

View file

@ -283,6 +283,7 @@ AbstractMainPage {
RowLayout {
z: 1
anchors.fill: parent
spacing: 10 * DefaultStyle.dp
Item {
Layout.preferredWidth: historyAvatar.width
Layout.preferredHeight: historyAvatar.height
@ -291,8 +292,8 @@ AbstractMainPage {
source: historyAvatar
anchors.fill: historyAvatar
shadowEnabled: true
shadowBlur: 1
shadowColor: DefaultStyle.grey_900
shadowBlur: 0.1
shadowColor: DefaultStyle.grey_1000
shadowOpacity: 0.1
}
Avatar {
@ -317,7 +318,7 @@ AbstractMainPage {
}
}
RowLayout {
spacing: 3 * DefaultStyle.dp
spacing: 6 * DefaultStyle.dp
EffectImage {
id: statusIcon
imageSource: modelData.core.status === LinphoneEnums.CallStatus.Declined
@ -403,7 +404,6 @@ AbstractMainPage {
onPressed: {
historyListView.currentIndex = model.index
historyListView.forceActiveFocus()
}
}
}

View file

@ -52,10 +52,9 @@ AbstractMainPage {
}
showDefaultItem: contactList.model.sourceModel.count === 0
property MagicSearchProxy allFriends: MagicSearchProxy {
searchText: searchBar.text.length === 0 ? "*" : searchBar.text
aggregationFlag: LinphoneEnums.MagicSearchAggregation.Friend
MagicSearchList {
id: allFriends
}
function deleteContact(contact) {
@ -268,14 +267,15 @@ AbstractMainPage {
}
ContactListView{
id: favoriteList
onActiveFocusChanged: if (activeFocus) console.log("favorite list focus")
hoverEnabled: mainItem.leftPanelEnabled
highlightFollowsCurrentItem: true
Layout.fillWidth: true
Layout.preferredHeight: contentHeight
Control.ScrollBar.vertical.visible: false
showOnlyFavourites: true
showFavouritesOnly: true
contactMenuVisible: true
model: allFriends
searchBarText: searchBar.text
sourceModel: allFriends
onSelectedContactChanged: {
if (selectedContact) {
contactList.currentIndex = -1
@ -320,7 +320,6 @@ AbstractMainPage {
}
ContactListView{
id: contactList
onActiveFocusChanged: if (activeFocus) console.log("contact list focus")
onCountChanged: {
if (initialFriendToDisplay.length !== 0) {
if (selectContact(initialFriendToDisplay) != -1) initialFriendToDisplay = ""
@ -328,14 +327,14 @@ AbstractMainPage {
}
Layout.fillWidth: true
Layout.preferredHeight: contentHeight
interactive: false
Control.ScrollBar.vertical.visible: false
hoverEnabled: mainItem.leftPanelEnabled
contactMenuVisible: true
highlightFollowsCurrentItem: true
searchBarText: searchBar.text
model: allFriends
sourceModel: allFriends
Connections {
target: allFriends
target: contactList.model
function onFriendCreated(index) {
contactList.currentIndex = index
}

View file

@ -14,6 +14,7 @@ QtObject {
property color main2_600: "#4E6074"
property color main2_700: "#364860"
property color main2_800: "#22334D"
property color main2_900: "#2D3648"
property color grey_0: "#FFFFFF"
property color grey_100: "#F9F9F9"