mirror of
https://gitlab.linphone.org/BC/public/linphone-desktop.git
synced 2026-01-17 11:28:07 +00:00
FIXES :
conf creation loading+error; fix info popup layout move contact edition in contact page (switch to contact tab if creation requested) fix contact creation + select new contact on creation conference info list : creation signal (to finish when conference scheduler is updated, see comment) fix crash if no vcard fix calendar ui +spacings layout polish (! on string in meetinglist)
This commit is contained in:
parent
abba6cffaa
commit
eb5b3b5141
48 changed files with 809 additions and 510 deletions
|
|
@ -102,7 +102,7 @@ public:
|
|||
|
||||
void onLoggerInitialized();
|
||||
|
||||
QQuickWindow *getCallsWindow(QVariant callGui);
|
||||
QQuickWindow *getCallsWindow(QVariant callGui = QVariant());
|
||||
void setCallsWindowProperty(const char *id, QVariant property);
|
||||
void closeCallsWindow();
|
||||
|
||||
|
|
|
|||
|
|
@ -136,7 +136,15 @@ void CallCore::setSelf(QSharedPointer<CallCore> me) {
|
|||
mCallModelConnection->invokeToModel([this]() { mCallModel->stopRecording(); });
|
||||
});
|
||||
mCallModelConnection->makeConnectToModel(&CallModel::recordingChanged, [this](bool recording) {
|
||||
mCallModelConnection->invokeToCore([this, recording]() { setRecording(recording); });
|
||||
mCallModelConnection->invokeToCore([this, recording]() {
|
||||
setRecording(recording);
|
||||
if (recording == false) {
|
||||
Utils::showInformationPopup(tr("Enregistrement terminé"),
|
||||
tr("L'appel a été enregistré dans le fichier : %1")
|
||||
.arg(QString::fromStdString(mCallModel->getRecordFile())),
|
||||
true, App::getInstance()->getCallsWindow());
|
||||
}
|
||||
});
|
||||
});
|
||||
mCallModelConnection->makeConnectToCore(&CallCore::lVerifyAuthenticationToken, [this](bool verified) {
|
||||
mCallModelConnection->invokeToModel(
|
||||
|
|
|
|||
|
|
@ -194,33 +194,37 @@ void ConferenceInfoCore::setSelf(QSharedPointer<ConferenceInfoCore> me) {
|
|||
&ConferenceInfoModel::schedulerStateChanged, [this](linphone::ConferenceScheduler::State state) {
|
||||
auto confInfoState = mConferenceInfoModel->getState();
|
||||
QString uri;
|
||||
if (state == linphone::ConferenceScheduler::State::Ready)
|
||||
if (state == linphone::ConferenceScheduler::State::Ready) {
|
||||
uri = mConferenceInfoModel->getConferenceScheduler()->getUri();
|
||||
}
|
||||
mConfInfoModelConnection->invokeToCore([this, state = LinphoneEnums::fromLinphone(state),
|
||||
infoState = LinphoneEnums::fromLinphone(confInfoState),
|
||||
uri] {
|
||||
lDebug() << "scheduler state changed" << state;
|
||||
setConferenceSchedulerState(state);
|
||||
setConferenceInfoState(infoState);
|
||||
if (state == LinphoneEnums::ConferenceSchedulerState::Ready) {
|
||||
setUri(uri);
|
||||
mConfInfoModelConnection->invokeToModel([this, uri] {
|
||||
CoreModel::getInstance()->conferenceInfoCreated(
|
||||
mConferenceInfoModel->getConferenceInfo());
|
||||
});
|
||||
}
|
||||
setConferenceSchedulerState(state);
|
||||
});
|
||||
});
|
||||
mConfInfoModelConnection->makeConnectToModel(
|
||||
&ConferenceInfoModel::infoStateChanged, [this](linphone::ConferenceInfo::State state) {
|
||||
auto uri = mConferenceInfoModel->getConferenceScheduler()->getUri();
|
||||
mConfInfoModelConnection->invokeToCore([this, infoState = LinphoneEnums::fromLinphone(state), uri] {
|
||||
setConferenceInfoState(infoState);
|
||||
});
|
||||
});
|
||||
mConfInfoModelConnection->makeConnectToModel(
|
||||
&ConferenceInfoModel::invitationsSent,
|
||||
[this](const std::list<std::shared_ptr<linphone::Address>> &failedInvitations) {
|
||||
lDebug() << "invitations sent";
|
||||
});
|
||||
[this](const std::list<std::shared_ptr<linphone::Address>> &failedInvitations) {});
|
||||
} else { // Create
|
||||
mCoreModelConnection = QSharedPointer<SafeConnection<ConferenceInfoCore, CoreModel>>(
|
||||
new SafeConnection<ConferenceInfoCore, CoreModel>(me, CoreModel::getInstance()), &QObject::deleteLater);
|
||||
mCoreModelConnection->makeConnectToModel(
|
||||
&CoreModel::conferenceInfoReceived,
|
||||
[this](const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<const linphone::ConferenceInfo> &conferenceInfo) {
|
||||
lDebug() << "CONF INFO RECEIVED ==================";
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -566,6 +570,11 @@ void ConferenceInfoCore::save() {
|
|||
});
|
||||
} else {
|
||||
mCoreModelConnection->invokeToModel([this, thisCopy]() {
|
||||
if (CoreModel::getInstance()->getCore()->getDefaultAccount()->getState() !=
|
||||
linphone::RegistrationState::Ok) {
|
||||
Utils::showInformationPopup(tr("Erreur"), tr("Votre compte est déconnecté"), false);
|
||||
return;
|
||||
}
|
||||
auto linphoneConf =
|
||||
CoreModel::getInstance()->getCore()->findConferenceInformationFromUri(ToolModel::interpretUrl(mUri));
|
||||
|
||||
|
|
|
|||
|
|
@ -68,7 +68,17 @@ void ConferenceInfoList::setSelf(QSharedPointer<ConferenceInfoList> me) {
|
|||
int currentDateIndex = sort(*items);
|
||||
add(*items);
|
||||
updateHaveCurrentDate();
|
||||
setCurrentDateIndex(mHaveCurrentDate ? currentDateIndex + 1 : currentDateIndex);
|
||||
if (mLastConfInfoInserted) {
|
||||
int index = -1;
|
||||
// TODO : uncomment when linphone conference scheduler updated
|
||||
// and model returns the scheduler conferenceInfo uri
|
||||
index = findConfInfoIndexByUri(mLastConfInfoInserted->getUri());
|
||||
// int index2;
|
||||
// get(mLastConfInfoInserted.get(), &index2);
|
||||
if (index != -1) setCurrentDateIndex(index);
|
||||
else setCurrentDateIndex(mHaveCurrentDate ? currentDateIndex + 1 : currentDateIndex);
|
||||
mLastConfInfoInserted = nullptr;
|
||||
} else setCurrentDateIndex(mHaveCurrentDate ? currentDateIndex + 1 : currentDateIndex);
|
||||
delete items;
|
||||
});
|
||||
});
|
||||
|
|
@ -76,10 +86,20 @@ void ConferenceInfoList::setSelf(QSharedPointer<ConferenceInfoList> me) {
|
|||
|
||||
mCoreModelConnection->makeConnectToModel(&CoreModel::defaultAccountChanged, &ConferenceInfoList::lUpdate);
|
||||
mCoreModelConnection->makeConnectToModel(&CoreModel::conferenceInfoReceived, &ConferenceInfoList::lUpdate);
|
||||
mCoreModelConnection->makeConnectToModel(&CoreModel::conferenceStateChanged, [this] {
|
||||
lDebug() << "list: conf state changed";
|
||||
lUpdate();
|
||||
});
|
||||
mCoreModelConnection->makeConnectToModel(
|
||||
&CoreModel::conferenceInfoCreated, [this](const std::shared_ptr<linphone::ConferenceInfo> &confInfo) {
|
||||
auto confInfoCore = ConferenceInfoCore::create(confInfo);
|
||||
auto haveConf =
|
||||
std::find_if(mList.begin(), mList.end(), [confInfoCore](const QSharedPointer<QObject> &item) {
|
||||
auto isConfInfo = item.objectCast<ConferenceInfoCore>();
|
||||
if (!isConfInfo) return false;
|
||||
return isConfInfo->getUri() == confInfoCore->getUri();
|
||||
});
|
||||
if (haveConf == mList.end()) {
|
||||
mLastConfInfoInserted = confInfoCore;
|
||||
emit lUpdate();
|
||||
}
|
||||
});
|
||||
mCoreModelConnection->makeConnectToModel(
|
||||
&CoreModel::callCreated, [this](const std::shared_ptr<linphone::Call> &call) {
|
||||
lDebug() << "call created" << Utils::coreStringToAppString(call->getRemoteAddress()->asString());
|
||||
|
|
@ -128,19 +148,13 @@ void ConferenceInfoList::setCurrentDateIndex(int index) {
|
|||
}
|
||||
}
|
||||
|
||||
QSharedPointer<ConferenceInfoCore>
|
||||
ConferenceInfoList::get(std::shared_ptr<linphone::ConferenceInfo> conferenceInfo) const {
|
||||
auto uri = Utils::coreStringToAppString(conferenceInfo->getUri()->asStringUriOnly());
|
||||
for (auto item : mList) {
|
||||
auto model = item.objectCast<ConferenceInfoCore>();
|
||||
if (model) {
|
||||
auto confUri = model->getUri();
|
||||
if (confUri == uri) {
|
||||
return model;
|
||||
}
|
||||
}
|
||||
int ConferenceInfoList::findConfInfoIndexByUri(const QString &uri) {
|
||||
auto items = getSharedList<ConferenceInfoCore>();
|
||||
for (int i = 0; i < items.size(); ++i) {
|
||||
if (!items[i]) continue;
|
||||
if (items[i]->getUri() == uri) return i;
|
||||
}
|
||||
return nullptr;
|
||||
return -1;
|
||||
}
|
||||
|
||||
QSharedPointer<ConferenceInfoCore>
|
||||
|
|
@ -160,13 +174,6 @@ ConferenceInfoList::build(const std::shared_ptr<linphone::ConferenceInfo> &confe
|
|||
} else return nullptr;
|
||||
}
|
||||
|
||||
void ConferenceInfoList::remove(const int &row) {
|
||||
// List is modified asynchronously
|
||||
// so no need to specify the begin/endRemoveRows
|
||||
auto item = mList[row].objectCast<ConferenceInfoCore>();
|
||||
if (item) emit item->lDeleteConferenceInfo();
|
||||
}
|
||||
|
||||
QHash<int, QByteArray> ConferenceInfoList::roleNames() const {
|
||||
QHash<int, QByteArray> roles;
|
||||
roles[Qt::DisplayRole] = "$modelData";
|
||||
|
|
|
|||
|
|
@ -46,10 +46,9 @@ public:
|
|||
int getCurrentDateIndex() const;
|
||||
void setCurrentDateIndex(int index);
|
||||
|
||||
QSharedPointer<ConferenceInfoCore> get(std::shared_ptr<linphone::ConferenceInfo> conferenceInfo) const;
|
||||
QSharedPointer<ConferenceInfoCore> build(const std::shared_ptr<linphone::ConferenceInfo> &conferenceInfo) const;
|
||||
int findConfInfoIndexByUri(const QString &uri);
|
||||
|
||||
void remove(const int &row);
|
||||
QSharedPointer<ConferenceInfoCore> build(const std::shared_ptr<linphone::ConferenceInfo> &conferenceInfo) const;
|
||||
|
||||
QHash<int, QByteArray> roleNames() const override;
|
||||
|
||||
|
|
@ -64,6 +63,8 @@ signals:
|
|||
|
||||
private:
|
||||
QSharedPointer<SafeConnection<ConferenceInfoList, CoreModel>> mCoreModelConnection;
|
||||
std::shared_ptr<CoreModel> mCoreModel;
|
||||
QSharedPointer<ConferenceInfoCore> mLastConfInfoInserted;
|
||||
bool mHaveCurrentDate = false;
|
||||
int mCurrentDateIndex = -1;
|
||||
DECLARE_ABSTRACT_OBJECT
|
||||
|
|
|
|||
|
|
@ -32,7 +32,6 @@ ConferenceInfoProxy::ConferenceInfoProxy(QObject *parent) : SortFilterProxy(pare
|
|||
invalidate();
|
||||
updateCurrentDateIndex();
|
||||
});
|
||||
connect(this, &ConferenceInfoProxy::lUpdate, mList.get(), &ConferenceInfoList::lUpdate);
|
||||
connect(mList.get(), &ConferenceInfoList::haveCurrentDateChanged, [this] {
|
||||
invalidate();
|
||||
updateCurrentDateIndex();
|
||||
|
|
@ -77,10 +76,9 @@ bool ConferenceInfoProxy::filterAcceptsRow(int sourceRow, const QModelIndex &sou
|
|||
if (ciCore) {
|
||||
if (!ciCore->getSubject().contains(mSearchText)) return false;
|
||||
QDateTime currentDateTime = QDateTime::currentDateTimeUtc();
|
||||
// TODO : use enums
|
||||
if (mFilterType == 0) {
|
||||
if (mFilterType == int(ConferenceInfoProxy::ConferenceInfoFiltering::None)) {
|
||||
return true;
|
||||
} else if (mFilterType == 1) {
|
||||
} else if (mFilterType == int(ConferenceInfoProxy::ConferenceInfoFiltering::Future)) {
|
||||
auto res = ciCore->getEndDateTimeUtc() >= currentDateTime;
|
||||
return res;
|
||||
} else return mFilterType == -1;
|
||||
|
|
@ -88,4 +86,4 @@ bool ConferenceInfoProxy::filterAcceptsRow(int sourceRow, const QModelIndex &sou
|
|||
return !mList->haveCurrentDate();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -33,30 +33,31 @@ class ConferenceInfoProxy : public SortFilterProxy, public AbstractObject {
|
|||
Q_PROPERTY(bool haveCurrentDate READ haveCurrentDate NOTIFY haveCurrentDateChanged)
|
||||
Q_PROPERTY(int currentDateIndex READ getCurrentDateIndex NOTIFY currentDateIndexChanged)
|
||||
|
||||
public:
|
||||
enum ConferenceInfoFiltering { None = 0, Future = 1 };
|
||||
Q_ENUM(ConferenceInfoFiltering)
|
||||
public:
|
||||
ConferenceInfoProxy(QObject *parent = Q_NULLPTR);
|
||||
~ConferenceInfoProxy();
|
||||
|
||||
QString getSearchText() const;
|
||||
void setSearchText(const QString &search);
|
||||
|
||||
|
||||
bool haveCurrentDate() const;
|
||||
|
||||
|
||||
int getCurrentDateIndex() const;
|
||||
void updateCurrentDateIndex();
|
||||
|
||||
protected:
|
||||
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override;
|
||||
// Do not use the sort feature. We cannot retrieve indexes with mapToSource because Qt return -1 for items that are not displayed.
|
||||
// We need it to know where
|
||||
// The workaround is to implement ourself the sort into the List.
|
||||
//bool lessThan(const QModelIndex &left, const QModelIndex &right) const override;
|
||||
// Do not use the sort feature. We cannot retrieve indexes with mapToSource because Qt return -1 for items that are
|
||||
// not displayed. We need it to know where The workaround is to implement ourself the sort into the List.
|
||||
// bool lessThan(const QModelIndex &left, const QModelIndex &right) const override;
|
||||
|
||||
signals:
|
||||
void searchTextChanged();
|
||||
void haveCurrentDateChanged();
|
||||
void currentDateIndexChanged();
|
||||
void lUpdate();
|
||||
|
||||
private:
|
||||
QString mSearchText;
|
||||
|
|
|
|||
|
|
@ -54,10 +54,12 @@ FriendCore::FriendCore(const std::shared_ptr<linphone::Friend> &contact) : QObje
|
|||
mPresenceTimestamp = mFriendModel->getPresenceTimestamp();
|
||||
mPictureUri = Utils::coreStringToAppString(contact->getPhoto());
|
||||
auto vcard = contact->getVcard();
|
||||
mOrganization = Utils::coreStringToAppString(vcard->getOrganization());
|
||||
mJob = Utils::coreStringToAppString(vcard->getJobTitle());
|
||||
mGivenName = Utils::coreStringToAppString(vcard->getGivenName());
|
||||
mFamilyName = Utils::coreStringToAppString(vcard->getFamilyName());
|
||||
if (vcard) {
|
||||
mOrganization = Utils::coreStringToAppString(vcard->getOrganization());
|
||||
mJob = Utils::coreStringToAppString(vcard->getJobTitle());
|
||||
mGivenName = Utils::coreStringToAppString(vcard->getGivenName());
|
||||
mFamilyName = Utils::coreStringToAppString(vcard->getFamilyName());
|
||||
}
|
||||
auto addresses = contact->getAddresses();
|
||||
for (auto &address : addresses) {
|
||||
mAddressList.append(
|
||||
|
|
@ -451,8 +453,8 @@ void FriendCore::remove() {
|
|||
if (mFriendModel) { // Update
|
||||
mFriendModelConnection->invokeToModel([this]() {
|
||||
auto contact = mFriendModel->getFriend();
|
||||
// emit CoreModel::getInstance()->friendRemoved(contact);
|
||||
contact->remove();
|
||||
emit CoreModel::getInstance()->friendRemoved();
|
||||
mFriendModelConnection->invokeToCore([this]() { removed(this); });
|
||||
});
|
||||
}
|
||||
|
|
@ -506,22 +508,24 @@ void FriendCore::save() { // Save Values to model
|
|||
auto contact = core->createFriend();
|
||||
auto friendModel = Utils::makeQObject_ptr<FriendModel>(contact);
|
||||
friendModel->setSelf(friendModel);
|
||||
mCoreModelConnection->invokeToCore([this, thisCopy, friendModel] {
|
||||
mCoreModelConnection->invokeToCore([this, thisCopy, friendModel, contact] {
|
||||
mFriendModel = friendModel;
|
||||
mCoreModelConnection->invokeToModel([this, thisCopy] {
|
||||
mCoreModelConnection->invokeToModel([this, thisCopy, contact] {
|
||||
auto core = CoreModel::getInstance()->getCore();
|
||||
thisCopy->writeIntoModel(mFriendModel);
|
||||
thisCopy->deleteLater();
|
||||
bool created =
|
||||
(core->getDefaultFriendList()->addFriend(contact) == linphone::FriendList::Status::OK);
|
||||
if (created) {
|
||||
core->getDefaultFriendList()->updateSubscriptions();
|
||||
emit CoreModel::getInstance()->friendCreated(contact);
|
||||
}
|
||||
mCoreModelConnection->invokeToCore([this, created]() {
|
||||
if (created) setSelf(mCoreModelConnection->mCore);
|
||||
setIsSaved(created);
|
||||
});
|
||||
});
|
||||
});
|
||||
bool created = (core->getDefaultFriendList()->addFriend(contact) == linphone::FriendList::Status::OK);
|
||||
if (created) {
|
||||
core->getDefaultFriendList()->updateSubscriptions();
|
||||
emit CoreModel::getInstance()->friendAdded();
|
||||
}
|
||||
mCoreModelConnection->invokeToCore([this, created]() {
|
||||
if (created) setSelf(mCoreModelConnection->mCore);
|
||||
setIsSaved(created);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -72,7 +72,6 @@ void MagicSearchList::setSelf(QSharedPointer<MagicSearchList> me) {
|
|||
&MagicSearchModel::aggregationFlagChanged, [this](LinphoneEnums::MagicSearchAggregation flag) {
|
||||
mModelConnection->invokeToCore([this, flag]() { setAggregationFlag(flag); });
|
||||
});
|
||||
|
||||
mModelConnection->makeConnectToModel(
|
||||
&MagicSearchModel::searchResultsReceived,
|
||||
[this](const std::list<std::shared_ptr<linphone::SearchResult>> &results) {
|
||||
|
|
@ -83,12 +82,14 @@ void MagicSearchList::setSelf(QSharedPointer<MagicSearchList> me) {
|
|||
contact = FriendCore::create(it->getFriend());
|
||||
contacts->append(contact);
|
||||
} else if (auto address = it->getAddress()) {
|
||||
contact = FriendCore::create(nullptr);
|
||||
auto linphoneFriend = CoreModel::getInstance()->getCore()->createFriend();
|
||||
contact = FriendCore::create(linphoneFriend);
|
||||
contact->setGivenName(Utils::coreStringToAppString(address->asStringUriOnly()));
|
||||
contact->appendAddress(Utils::coreStringToAppString(address->asStringUriOnly()));
|
||||
contacts->append(contact);
|
||||
} else if (!it->getPhoneNumber().empty()) {
|
||||
contact = FriendCore::create(it->getFriend());
|
||||
auto linphoneFriend = CoreModel::getInstance()->getCore()->createFriend();
|
||||
contact = FriendCore::create(linphoneFriend);
|
||||
contact->setGivenName(Utils::coreStringToAppString(it->getPhoneNumber()));
|
||||
contact->appendPhoneNumber(tr("Phone"), Utils::coreStringToAppString(it->getPhoneNumber()));
|
||||
contacts->append(contact);
|
||||
|
|
@ -99,6 +100,26 @@ void MagicSearchList::setSelf(QSharedPointer<MagicSearchList> me) {
|
|||
delete contacts;
|
||||
});
|
||||
});
|
||||
|
||||
mCoreModelConnection = QSharedPointer<SafeConnection<MagicSearchList, CoreModel>>(
|
||||
new SafeConnection<MagicSearchList, CoreModel>(me, CoreModel::getInstance()), &QObject::deleteLater);
|
||||
mCoreModelConnection->makeConnectToModel(
|
||||
&CoreModel::friendCreated, [this](const std::shared_ptr<linphone::Friend> &f) {
|
||||
auto friendCore = FriendCore::create(f);
|
||||
auto haveContact =
|
||||
std::find_if(mList.begin(), mList.end(), [friendCore](const QSharedPointer<QObject> &item) {
|
||||
return item.objectCast<FriendCore>()->getDefaultAddress() == friendCore->getDefaultAddress();
|
||||
});
|
||||
if (haveContact == mList.end()) {
|
||||
connect(friendCore.get(), &FriendCore::removed, this, qOverload<QObject *>(&MagicSearchList::remove));
|
||||
add(friendCore);
|
||||
int index = -1;
|
||||
get(friendCore.get(), &index);
|
||||
if (index != -1) {
|
||||
emit friendCreated(index);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void MagicSearchList::setResults(const QList<QSharedPointer<FriendCore>> &contacts) {
|
||||
|
|
@ -109,6 +130,9 @@ void MagicSearchList::setResults(const QList<QSharedPointer<FriendCore>> &contac
|
|||
add(contacts);
|
||||
}
|
||||
|
||||
void MagicSearchList::addResult(const QSharedPointer<FriendCore> &contact) {
|
||||
}
|
||||
|
||||
void MagicSearchList::setSearch(const QString &search) {
|
||||
if (!search.isEmpty()) {
|
||||
lSearch(search);
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ public:
|
|||
void setSelf(QSharedPointer<MagicSearchList> me);
|
||||
void setSearch(const QString &search);
|
||||
void setResults(const QList<QSharedPointer<FriendCore>> &contacts);
|
||||
void addResult(const QSharedPointer<FriendCore> &contact);
|
||||
|
||||
int getSourceFlags() const;
|
||||
void setSourceFlags(int flags);
|
||||
|
|
@ -59,6 +60,8 @@ signals:
|
|||
void sourceFlagsChanged(int sourceFlags);
|
||||
void aggregationFlagChanged(LinphoneEnums::MagicSearchAggregation flag);
|
||||
|
||||
void friendCreated(int index);
|
||||
|
||||
private:
|
||||
int mSourceFlags;
|
||||
LinphoneEnums::MagicSearchAggregation mAggregationFlag;
|
||||
|
|
|
|||
|
|
@ -20,14 +20,17 @@
|
|||
|
||||
#include "MagicSearchProxy.hpp"
|
||||
#include "MagicSearchList.hpp"
|
||||
#include "core/friend/FriendGui.hpp"
|
||||
|
||||
MagicSearchProxy::MagicSearchProxy(QObject *parent) : SortFilterProxy(parent) {
|
||||
mList = MagicSearchList::create();
|
||||
connect(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(CoreModel::getInstance().get(), &CoreModel::friendRemoved, this,
|
||||
[this] { emit mList->lSearch(mSearchText); });
|
||||
connect(this, &MagicSearchProxy::forceUpdate, [this] { emit mList->lSearch(mSearchText); });
|
||||
sort(0);
|
||||
}
|
||||
|
|
@ -58,4 +61,19 @@ LinphoneEnums::MagicSearchAggregation MagicSearchProxy::getAggregationFlag() con
|
|||
|
||||
void MagicSearchProxy::setAggregationFlag(LinphoneEnums::MagicSearchAggregation flag) {
|
||||
qobject_cast<MagicSearchList *>(sourceModel())->lSetAggregationFlag(flag);
|
||||
}
|
||||
|
||||
bool MagicSearchProxy::lessThan(const QModelIndex &left, const QModelIndex &right) const {
|
||||
auto l = sourceModel()->data(left);
|
||||
auto r = sourceModel()->data(right);
|
||||
|
||||
auto lIsFriend = l.value<FriendGui *>();
|
||||
auto rIsFriend = r.value<FriendGui *>();
|
||||
|
||||
if (lIsFriend && rIsFriend) {
|
||||
auto lName = lIsFriend->getCore()->getDisplayName().toLower();
|
||||
auto rName = rIsFriend->getCore()->getDisplayName().toLower();
|
||||
return lName < rName;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
@ -55,10 +55,12 @@ signals:
|
|||
void sourceFlagsChanged(int sourceFlags);
|
||||
void aggregationFlagChanged(LinphoneEnums::MagicSearchAggregation aggregationFlag);
|
||||
void forceUpdate();
|
||||
void friendCreated(int index);
|
||||
|
||||
protected:
|
||||
QString mSearchText;
|
||||
QSharedPointer<MagicSearchList> mList;
|
||||
virtual bool lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const override;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
32
Linphone/data/image/video-conference-selected.svg
Normal file
32
Linphone/data/image/video-conference-selected.svg
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
<svg width="28" height="26" viewBox="0 0 28 26" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_3638_14815)" filter="url(#filter0_d_3638_14815)">
|
||||
<g filter="url(#filter1_d_3638_14815)">
|
||||
<path d="M21.125 9.25C21.125 9.4725 21.059 9.69001 20.9354 9.87502C20.8118 10.06 20.6361 10.2042 20.4305 10.2894C20.225 10.3745 19.9988 10.3968 19.7805 10.3534C19.5623 10.31 19.3618 10.2028 19.2045 10.0455C19.0472 9.88816 18.94 9.68771 18.8966 9.46948C18.8532 9.25125 18.8755 9.02505 18.9606 8.81948C19.0458 8.61391 19.19 8.43821 19.375 8.3146C19.56 8.19098 19.7775 8.125 20 8.125C20.2984 8.125 20.5845 8.24353 20.7955 8.4545C21.0065 8.66548 21.125 8.95163 21.125 9.25ZM20 15.625C19.7775 15.625 19.56 15.691 19.375 15.8146C19.19 15.9382 19.0458 16.1139 18.9606 16.3195C18.8755 16.525 18.8532 16.7512 18.8966 16.9695C18.94 17.1877 19.0472 17.3882 19.2045 17.5455C19.3618 17.7028 19.5623 17.81 19.7805 17.8534C19.9988 17.8968 20.225 17.8745 20.4305 17.7894C20.6361 17.7042 20.8118 17.56 20.9354 17.375C21.059 17.19 21.125 16.9725 21.125 16.75C21.125 16.4516 21.0065 16.1655 20.7955 15.9545C20.5845 15.7435 20.2984 15.625 20 15.625ZM11 10.75C10.7033 10.75 10.4133 10.838 10.1666 11.0028C9.91997 11.1676 9.72771 11.4019 9.61418 11.676C9.50065 11.9501 9.47094 12.2517 9.52882 12.5426C9.5867 12.8336 9.72956 13.1009 9.93934 13.3107C10.1491 13.5204 10.4164 13.6633 10.7074 13.7212C10.9983 13.7791 11.2999 13.7494 11.574 13.6358C11.8481 13.5223 12.0824 13.33 12.2472 13.0834C12.412 12.8367 12.5 12.5467 12.5 12.25C12.5 11.8522 12.342 11.4706 12.0607 11.1893C11.7794 10.908 11.3978 10.75 11 10.75ZM23.75 6.25V19.75C23.75 20.1478 23.592 20.5294 23.3107 20.8107C23.0294 21.092 22.6478 21.25 22.25 21.25H5.75C5.35218 21.25 4.97064 21.092 4.68934 20.8107C4.40804 20.5294 4.25 20.1478 4.25 19.75V6.25C4.25 5.85218 4.40804 5.47064 4.68934 5.18934C4.97064 4.90804 5.35218 4.75 5.75 4.75H22.25C22.6478 4.75 23.0294 4.90804 23.3107 5.18934C23.592 5.47064 23.75 5.85218 23.75 6.25ZM17.75 12.25H22.25V6.25H17.75V12.25ZM14.7266 16.5625C14.4839 15.6563 13.9084 14.875 13.115 14.3744C13.5363 13.9555 13.8238 13.421 13.941 12.8386C14.0582 12.2562 13.9999 11.652 13.7733 11.1028C13.5468 10.5536 13.1623 10.084 12.6686 9.75358C12.1748 9.42315 11.5941 9.24675 11 9.24675C10.4059 9.24675 9.82517 9.42315 9.33143 9.75358C8.8377 10.084 8.45319 10.5536 8.22666 11.1028C8.00012 11.652 7.94175 12.2562 8.05896 12.8386C8.17616 13.421 8.46366 13.9555 8.885 14.3744C8.09211 14.8755 7.51681 15.6566 7.27344 16.5625C7.22371 16.7552 7.25257 16.9598 7.35366 17.1312C7.45475 17.3026 7.6198 17.4268 7.8125 17.4766C8.0052 17.5263 8.20975 17.4974 8.38118 17.3963C8.55259 17.2952 8.67683 17.1302 8.72656 16.9375C8.97406 15.9766 9.95094 15.25 11 15.25C12.0491 15.25 13.0269 15.9747 13.2734 16.9375C13.3232 17.1302 13.4474 17.2952 13.6188 17.3963C13.7902 17.4974 13.9948 17.5263 14.1875 17.4766C14.3802 17.4268 14.5452 17.3026 14.6463 17.1312C14.7474 16.9598 14.7763 16.7552 14.7266 16.5625ZM22.25 19.75V13.75H17.75V19.75H22.25Z" fill="white"/>
|
||||
</g>
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="filter0_d_3638_14815" x="-2" y="-3" width="32" height="32" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset/>
|
||||
<feGaussianBlur stdDeviation="2"/>
|
||||
<feComposite in2="hardAlpha" operator="out"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.15 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_3638_14815"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_3638_14815" result="shape"/>
|
||||
</filter>
|
||||
<filter id="filter1_d_3638_14815" x="0.25" y="0.75" width="27.5" height="24.5" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset/>
|
||||
<feGaussianBlur stdDeviation="2"/>
|
||||
<feComposite in2="hardAlpha" operator="out"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.15 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_3638_14815"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_3638_14815" result="shape"/>
|
||||
</filter>
|
||||
<clipPath id="clip0_3638_14815">
|
||||
<rect width="24" height="24" fill="white" transform="translate(2 1)"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.4 KiB |
1
Linphone/data/image/video-conference.svg
Normal file
1
Linphone/data/image/video-conference.svg
Normal file
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" fill="#000000" viewBox="0 0 256 256"><path d="M216,40H40A16,16,0,0,0,24,56V200a16,16,0,0,0,16,16H216a16,16,0,0,0,16-16V56A16,16,0,0,0,216,40Zm0,80H168V56h48ZM40,56H152V200H40ZM216,200H168V136h48v64ZM180,88a12,12,0,1,1,12,12A12,12,0,0,1,180,88Zm24,80a12,12,0,1,1-12-12A12,12,0,0,1,204,168Zm-68.25-2a39.76,39.76,0,0,0-17.19-23.34,32,32,0,1,0-45.12,0A39.84,39.84,0,0,0,56.25,166a8,8,0,0,0,15.5,4c2.64-10.25,13.06-18,24.25-18s21.62,7.73,24.25,18a8,8,0,1,0,15.5-4ZM80,120a16,16,0,1,1,16,16A16,16,0,0,1,80,120Z"></path></svg>
|
||||
|
After Width: | Height: | Size: 582 B |
|
|
@ -185,7 +185,6 @@ void CallModel::stopRecording() {
|
|||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||
mMonitor->stopRecording();
|
||||
emit recordingChanged(mMonitor->getParams()->isRecording());
|
||||
// TODO : display notification
|
||||
}
|
||||
|
||||
void CallModel::setRecordFile(const std::string &path) {
|
||||
|
|
|
|||
|
|
@ -45,6 +45,10 @@ void ConferenceInfoModel::createConferenceScheduler() {
|
|||
mustBeInLinphoneThread(getClassName() + "::createConferenceScheduler()");
|
||||
}
|
||||
|
||||
std::shared_ptr<linphone::ConferenceInfo> ConferenceInfoModel::getConferenceInfo() const {
|
||||
return mConferenceInfo;
|
||||
}
|
||||
|
||||
std::shared_ptr<ConferenceSchedulerModel> ConferenceInfoModel::getConferenceScheduler() const {
|
||||
return mConferenceSchedulerModel;
|
||||
}
|
||||
|
|
@ -106,7 +110,9 @@ QString ConferenceInfoModel::getOrganizerName() const {
|
|||
}
|
||||
|
||||
QString ConferenceInfoModel::getOrganizerAddress() const {
|
||||
return Utils::coreStringToAppString(mConferenceInfo->getOrganizer()->asStringUriOnly());
|
||||
if (auto organizer = mConferenceInfo->getOrganizer())
|
||||
return Utils::coreStringToAppString(organizer->asStringUriOnly());
|
||||
return QString();
|
||||
}
|
||||
|
||||
QString ConferenceInfoModel::getDescription() const {
|
||||
|
|
@ -118,7 +124,7 @@ QString ConferenceInfoModel::getUri() const {
|
|||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||
if (auto uriAddr = mConferenceInfo->getUri()) {
|
||||
return Utils::coreStringToAppString(uriAddr->asString());
|
||||
} else return QString();
|
||||
} else return mConferenceSchedulerModel->getUri();
|
||||
}
|
||||
|
||||
std::list<std::shared_ptr<linphone::ParticipantInfo>> ConferenceInfoModel::getParticipantInfos() const {
|
||||
|
|
|
|||
|
|
@ -36,6 +36,8 @@ public:
|
|||
|
||||
void createConferenceScheduler();
|
||||
|
||||
std::shared_ptr<linphone::ConferenceInfo> getConferenceInfo() const;
|
||||
|
||||
std::shared_ptr<ConferenceSchedulerModel> getConferenceScheduler() const;
|
||||
void setConferenceScheduler(const std::shared_ptr<ConferenceSchedulerModel> &model);
|
||||
QDateTime getDateTime() const;
|
||||
|
|
|
|||
|
|
@ -86,8 +86,6 @@ void ConferenceModel::startRecording() {
|
|||
void ConferenceModel::stopRecording() {
|
||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||
mMonitor->stopRecording();
|
||||
// emit recordingChanged(mMonitor->getParams()->isRecording());
|
||||
// TODO : display notification
|
||||
}
|
||||
|
||||
void ConferenceModel::setRecordFile(const std::string &path) {
|
||||
|
|
|
|||
|
|
@ -48,6 +48,10 @@ QString ConferenceSchedulerModel::getUri() {
|
|||
} else return QString();
|
||||
}
|
||||
|
||||
linphone::ConferenceScheduler::State ConferenceSchedulerModel::getState() const {
|
||||
return mState;
|
||||
}
|
||||
|
||||
void ConferenceSchedulerModel::setInfo(const std::shared_ptr<linphone::ConferenceInfo> &confInfo) {
|
||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||
mMonitor->setInfo(confInfo);
|
||||
|
|
@ -60,6 +64,7 @@ void ConferenceSchedulerModel::cancelConference(const std::shared_ptr<linphone::
|
|||
|
||||
void ConferenceSchedulerModel::onStateChanged(const std::shared_ptr<linphone::ConferenceScheduler> &conferenceScheduler,
|
||||
linphone::ConferenceScheduler::State state) {
|
||||
mState = state;
|
||||
emit stateChanged(state);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ public:
|
|||
~ConferenceSchedulerModel();
|
||||
|
||||
QString getUri();
|
||||
linphone::ConferenceScheduler::State getState() const;
|
||||
void setInfo(const std::shared_ptr<linphone::ConferenceInfo> &confInfo);
|
||||
void cancelConference(const std::shared_ptr<linphone::ConferenceInfo> &confInfo);
|
||||
|
||||
|
|
@ -48,6 +49,7 @@ signals:
|
|||
|
||||
private:
|
||||
DECLARE_ABSTRACT_OBJECT
|
||||
linphone::ConferenceScheduler::State mState;
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
// LINPHONE
|
||||
|
|
|
|||
|
|
@ -56,8 +56,9 @@ public:
|
|||
|
||||
signals:
|
||||
void loggerInitialized();
|
||||
void friendAdded();
|
||||
void friendRemoved();
|
||||
void friendCreated(const std::shared_ptr<linphone::Friend> &f);
|
||||
void friendRemoved(const std::shared_ptr<linphone::Friend> &f);
|
||||
void conferenceInfoCreated(const std::shared_ptr<linphone::ConferenceInfo> &confInfo);
|
||||
void unreadNotificationsChanged();
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -150,70 +150,90 @@ void FriendModel::setName(const QString &name) {
|
|||
|
||||
QString FriendModel::getGivenName() const {
|
||||
auto vcard = mMonitor->getVcard();
|
||||
bool created = false;
|
||||
if (!vcard) {
|
||||
mMonitor->createVcard(mMonitor->getName());
|
||||
created = mMonitor->createVcard(mMonitor->getName());
|
||||
}
|
||||
return Utils::coreStringToAppString(mMonitor->getVcard()->getGivenName());
|
||||
if (mMonitor->getVcard()) return Utils::coreStringToAppString(mMonitor->getVcard()->getGivenName());
|
||||
else return QString();
|
||||
}
|
||||
|
||||
void FriendModel::setGivenName(const QString &name) {
|
||||
auto vcard = mMonitor->getVcard();
|
||||
bool created = false;
|
||||
if (!vcard) {
|
||||
mMonitor->createVcard(mMonitor->getName());
|
||||
created = mMonitor->createVcard(mMonitor->getName());
|
||||
}
|
||||
if (mMonitor->getVcard()) {
|
||||
mMonitor->getVcard()->setGivenName(Utils::appStringToCoreString(name));
|
||||
emit givenNameChanged(name);
|
||||
}
|
||||
mMonitor->getVcard()->setGivenName(Utils::appStringToCoreString(name));
|
||||
emit givenNameChanged(name);
|
||||
}
|
||||
|
||||
QString FriendModel::getFamilyName() const {
|
||||
auto vcard = mMonitor->getVcard();
|
||||
bool created = false;
|
||||
if (!vcard) {
|
||||
mMonitor->createVcard(mMonitor->getName());
|
||||
created = mMonitor->createVcard(mMonitor->getName());
|
||||
}
|
||||
return Utils::coreStringToAppString(mMonitor->getVcard()->getFamilyName());
|
||||
if (mMonitor->getVcard()) return Utils::coreStringToAppString(mMonitor->getVcard()->getFamilyName());
|
||||
else return QString();
|
||||
}
|
||||
|
||||
void FriendModel::setFamilyName(const QString &name) {
|
||||
auto vcard = mMonitor->getVcard();
|
||||
bool created = false;
|
||||
if (!vcard) {
|
||||
mMonitor->createVcard(mMonitor->getName());
|
||||
created = mMonitor->createVcard(mMonitor->getName());
|
||||
}
|
||||
if (mMonitor->getVcard()) {
|
||||
mMonitor->getVcard()->setFamilyName(Utils::appStringToCoreString(name));
|
||||
emit familyNameChanged(name);
|
||||
}
|
||||
mMonitor->getVcard()->setFamilyName(Utils::appStringToCoreString(name));
|
||||
emit familyNameChanged(name);
|
||||
}
|
||||
|
||||
QString FriendModel::getOrganization() const {
|
||||
auto vcard = mMonitor->getVcard();
|
||||
bool created = false;
|
||||
if (!vcard) {
|
||||
mMonitor->createVcard(mMonitor->getName());
|
||||
created = mMonitor->createVcard(mMonitor->getName());
|
||||
}
|
||||
return Utils::coreStringToAppString(mMonitor->getVcard()->getOrganization());
|
||||
if (mMonitor->getVcard()) return Utils::coreStringToAppString(mMonitor->getVcard()->getOrganization());
|
||||
else return QString();
|
||||
}
|
||||
|
||||
void FriendModel::setOrganization(const QString &orga) {
|
||||
auto vcard = mMonitor->getVcard();
|
||||
bool created = false;
|
||||
if (!vcard) {
|
||||
mMonitor->createVcard(mMonitor->getName());
|
||||
created = mMonitor->createVcard(mMonitor->getName());
|
||||
}
|
||||
if (mMonitor->getVcard()) {
|
||||
mMonitor->getVcard()->setOrganization(Utils::appStringToCoreString(orga));
|
||||
emit organizationChanged(orga);
|
||||
}
|
||||
mMonitor->getVcard()->setOrganization(Utils::appStringToCoreString(orga));
|
||||
emit organizationChanged(orga);
|
||||
}
|
||||
|
||||
QString FriendModel::getJob() const {
|
||||
auto vcard = mMonitor->getVcard();
|
||||
bool created = false;
|
||||
if (!vcard) {
|
||||
mMonitor->createVcard(mMonitor->getName());
|
||||
created = mMonitor->createVcard(mMonitor->getName());
|
||||
}
|
||||
return Utils::coreStringToAppString(mMonitor->getVcard()->getJobTitle());
|
||||
if (mMonitor->getVcard()) return Utils::coreStringToAppString(mMonitor->getVcard()->getJobTitle());
|
||||
else return QString();
|
||||
}
|
||||
|
||||
void FriendModel::setJob(const QString &job) {
|
||||
auto vcard = mMonitor->getVcard();
|
||||
bool created = false;
|
||||
if (!vcard) {
|
||||
mMonitor->createVcard(mMonitor->getName());
|
||||
created = mMonitor->createVcard(mMonitor->getName());
|
||||
}
|
||||
if (mMonitor->getVcard()) {
|
||||
mMonitor->getVcard()->setJobTitle(Utils::appStringToCoreString(job));
|
||||
emit jobChanged(job);
|
||||
}
|
||||
mMonitor->getVcard()->setJobTitle(Utils::appStringToCoreString(job));
|
||||
emit jobChanged(job);
|
||||
}
|
||||
|
||||
bool FriendModel::getStarred() const {
|
||||
|
|
@ -231,10 +251,12 @@ void FriendModel::onPresenceReceived(const std::shared_ptr<linphone::Friend> &co
|
|||
|
||||
QString FriendModel::getPictureUri() const {
|
||||
auto vcard = mMonitor->getVcard();
|
||||
bool created = false;
|
||||
if (!vcard) {
|
||||
mMonitor->createVcard(mMonitor->getName());
|
||||
created = mMonitor->createVcard(mMonitor->getName());
|
||||
}
|
||||
return Utils::coreStringToAppString(mMonitor->getVcard()->getPhoto());
|
||||
if (mMonitor->getVcard()) return Utils::coreStringToAppString(mMonitor->getVcard()->getPhoto());
|
||||
else return QString();
|
||||
}
|
||||
|
||||
void FriendModel::setPictureUri(const QString &uri) {
|
||||
|
|
|
|||
|
|
@ -30,11 +30,6 @@ DEFINE_ABSTRACT_OBJECT(MagicSearchModel)
|
|||
MagicSearchModel::MagicSearchModel(const std::shared_ptr<linphone::MagicSearch> &data, QObject *parent)
|
||||
: ::Listener<linphone::MagicSearch, linphone::MagicSearchListener>(data, parent) {
|
||||
mustBeInLinphoneThread(getClassName());
|
||||
// Removed is managed by FriendCore that allow to remove result automatically.
|
||||
// No need to restart a new search in this case
|
||||
connect(CoreModel::getInstance().get(), &CoreModel::friendAdded, this, [this]() {
|
||||
if (!mLastSearch.isEmpty()) search(mLastSearch);
|
||||
});
|
||||
}
|
||||
|
||||
MagicSearchModel::~MagicSearchModel() {
|
||||
|
|
|
|||
|
|
@ -187,9 +187,9 @@ linphone::ConferenceInfo::State toLinphone(const LinphoneEnums::ConferenceInfoSt
|
|||
LinphoneEnums::ConferenceInfoState fromLinphone(const linphone::ConferenceInfo::State &state);
|
||||
|
||||
enum class ConferenceSchedulerState {
|
||||
AllocationPending = int(linphone::ConferenceScheduler::State::AllocationPending),
|
||||
Error = int(linphone::ConferenceScheduler::State::Error),
|
||||
Idle = int(linphone::ConferenceScheduler::State::Idle),
|
||||
Error = int(linphone::ConferenceScheduler::State::Error),
|
||||
AllocationPending = int(linphone::ConferenceScheduler::State::AllocationPending),
|
||||
Ready = int(linphone::ConferenceScheduler::State::Ready),
|
||||
Updating = int(linphone::ConferenceScheduler::State::Updating)
|
||||
};
|
||||
|
|
|
|||
|
|
@ -111,6 +111,9 @@ void Utils::createCall(const QString &sipAddress,
|
|||
|
||||
// TODO : change conf info only from qml
|
||||
// (bug si on est déjà en appel et qu'on lance une conf)
|
||||
// demander à jonhatan pour le design : quand on est déjà en appel
|
||||
// et qu'on join une conf on retourne donc sur la waiting room
|
||||
// Comment on annule ? Si on ferme la fenêtre ça va finir l'appel en cours
|
||||
void Utils::setupConference(ConferenceInfoGui *confGui) {
|
||||
if (!confGui) return;
|
||||
auto window = App::getInstance()->getCallsWindow(QVariant());
|
||||
|
|
@ -1124,6 +1127,10 @@ QString Utils::toDateMonthString(const QDateTime &date) {
|
|||
return QLocale().toString(date, "MMMM");
|
||||
}
|
||||
|
||||
QString Utils::toDateMonthAndYearString(const QDateTime &date) {
|
||||
return QLocale().toString(date, "MMMM yyyy");
|
||||
}
|
||||
|
||||
bool Utils::isCurrentDay(QDateTime date) {
|
||||
auto dateDayNum = date.date().day();
|
||||
auto currentDate = QDateTime::currentDateTime();
|
||||
|
|
@ -1152,6 +1159,10 @@ bool Utils::datesAreEqual(const QDate &a, const QDate &b) {
|
|||
return a.month() == b.month() && a.year() == b.year() && a.day() == b.day();
|
||||
}
|
||||
|
||||
bool Utils::dateisInMonth(const QDate &a, int month, int year) {
|
||||
return a.month() == month && a.year() == year;
|
||||
}
|
||||
|
||||
QDateTime Utils::createDateTime(const QDate &date, int hour, int min) {
|
||||
QTime time(hour, min);
|
||||
return QDateTime(date, time);
|
||||
|
|
@ -1177,6 +1188,11 @@ QDateTime Utils::addSecs(QDateTime date, int secs) {
|
|||
return date;
|
||||
}
|
||||
|
||||
QDateTime Utils::addYears(QDateTime date, int years) {
|
||||
date = date.addYears(years);
|
||||
return date;
|
||||
}
|
||||
|
||||
int Utils::getYear(const QDate &date) {
|
||||
return date.year();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -87,17 +87,20 @@ public:
|
|||
Q_INVOKABLE static QString toDateHourString(const QDateTime &date);
|
||||
Q_INVOKABLE static QString toDateDayNameString(const QDateTime &date);
|
||||
Q_INVOKABLE static QString toDateMonthString(const QDateTime &date);
|
||||
Q_INVOKABLE static QString toDateMonthAndYearString(const QDateTime &date);
|
||||
Q_INVOKABLE static bool isCurrentDay(QDateTime date);
|
||||
Q_INVOKABLE static bool isCurrentDay(QDate date);
|
||||
Q_INVOKABLE static bool isCurrentMonth(QDate date);
|
||||
Q_INVOKABLE static bool isBeforeToday(QDate date);
|
||||
Q_INVOKABLE static bool datesAreEqual(const QDate &a, const QDate &b);
|
||||
Q_INVOKABLE static bool dateisInMonth(const QDate &a, int month, int year);
|
||||
Q_INVOKABLE static QDateTime createDateTime(const QDate &date, int hour, int min);
|
||||
Q_INVOKABLE static QDateTime getCurrentDateTime();
|
||||
Q_INVOKABLE static QDateTime getCurrentDateTimeUtc();
|
||||
Q_INVOKABLE static int getYear(const QDate &date);
|
||||
Q_INVOKABLE static int secsTo(const QString &start, const QString &end);
|
||||
Q_INVOKABLE static QDateTime addSecs(QDateTime date, int secs);
|
||||
Q_INVOKABLE static QDateTime addYears(QDateTime date, int years);
|
||||
Q_INVOKABLE static QString generateLinphoneSipAddress(const QString &uri);
|
||||
Q_INVOKABLE static QString findAvatarByAddress(const QString &address);
|
||||
static QString generateSavedFilename(const QString &from, const QString &to);
|
||||
|
|
|
|||
|
|
@ -275,7 +275,6 @@ Window {
|
|||
Layout.preferredWidth: 30 * DefaultStyle.dp
|
||||
Layout.preferredHeight: 30 * DefaultStyle.dp
|
||||
// TODO : change with broadcast or meeting icon when available
|
||||
// +
|
||||
imageSource: !mainWindow.call
|
||||
? AppIcons.meeting
|
||||
: (mainWindow.callState === LinphoneEnums.CallState.End
|
||||
|
|
@ -725,18 +724,16 @@ Window {
|
|||
Connections {
|
||||
target: participantsStack
|
||||
onCurrentItemChanged: {
|
||||
console.log("changing title", participantsStack.currentItem == participantList)
|
||||
if (participantsStack.currentItem == participantList) rightPanel.headerTitleText = qsTr("Participants (%1)").arg(participantList.count)
|
||||
}
|
||||
}
|
||||
Connections {
|
||||
target: rightPanel
|
||||
// TODO : chercher comment relier ces infos pour faire le add des participants
|
||||
//onValidateRequested: {
|
||||
// participantList.model.addAddresses(participantsStack.selectedParticipants)
|
||||
// participantsStack.pop()
|
||||
// participantsStack.participantAdded()
|
||||
//}
|
||||
onValidateRequested: {
|
||||
participantList.model.addAddresses(participantsStack.selectedParticipants)
|
||||
participantsStack.pop()
|
||||
participantsStack.participantAdded()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,6 +26,11 @@ Item {
|
|||
transferSucceedPopup.open()
|
||||
}
|
||||
|
||||
function createContact(name, address) {
|
||||
tabbar.currentIndex = 1
|
||||
contactPage.createContact(name, address)
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: autoClosePopup
|
||||
interval: 5000
|
||||
|
|
@ -119,7 +124,7 @@ Item {
|
|||
{icon: AppIcons.phone, selectedIcon: AppIcons.phoneSelected, label: qsTr("Appels")},
|
||||
{icon: AppIcons.adressBook, selectedIcon: AppIcons.adressBookSelected, label: qsTr("Contacts")},
|
||||
{icon: AppIcons.chatTeardropText, selectedIcon: AppIcons.chatTeardropTextSelected, label: qsTr("Conversations")},
|
||||
{icon: AppIcons.usersThree, selectedIcon: AppIcons.usersThreeSelected, label: qsTr("Réunions")}
|
||||
{icon: AppIcons.videoconference, selectedIcon: AppIcons.videoconferenceSelected, label: qsTr("Réunions")}
|
||||
]
|
||||
|
||||
}
|
||||
|
|
@ -269,9 +274,8 @@ Item {
|
|||
Item {Layout.fillWidth: true}
|
||||
}
|
||||
onClicked: {
|
||||
var currentItem = mainStackLayout.children[mainStackLayout.currentIndex]
|
||||
mainItem.createContact(magicSearchBar.text, sipAddr.text)
|
||||
listPopup.close()
|
||||
currentItem.createContact(magicSearchBar.text, sipAddr.text)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -360,8 +364,13 @@ Item {
|
|||
Layout.topMargin: 24 * DefaultStyle.dp
|
||||
CallPage {
|
||||
id: callPage
|
||||
onCreateContactRequested: (name, address) => {
|
||||
mainItem.createContact(name, address)
|
||||
}
|
||||
}
|
||||
ContactPage{
|
||||
id: contactPage
|
||||
}
|
||||
ContactPage{}
|
||||
Item{}
|
||||
//ConversationPage{}
|
||||
MeetingPage{}
|
||||
|
|
|
|||
|
|
@ -33,6 +33,10 @@ ApplicationWindow {
|
|||
mainWindowStackView.currentItem.transferCallSucceed()
|
||||
}
|
||||
|
||||
function removeFromPopupLayout(index) {
|
||||
popupLayout.popupList.splice(index, 1)
|
||||
}
|
||||
|
||||
Component {
|
||||
id: popupComp
|
||||
InformationPopup{}
|
||||
|
|
@ -42,26 +46,44 @@ ApplicationWindow {
|
|||
infoPopup.index = popupLayout.popupList.length
|
||||
popupLayout.popupList.push(infoPopup)
|
||||
infoPopup.open()
|
||||
infoPopup.closePopup.connect(removeFromPopupLayout)
|
||||
}
|
||||
function showLoadingPopup(text) {
|
||||
loadingPopup.text = text
|
||||
loadingPopup.open()
|
||||
}
|
||||
function closeLoadingPopup() {
|
||||
loadingPopup.close()
|
||||
}
|
||||
|
||||
|
||||
ColumnLayout {
|
||||
id: popupLayout
|
||||
anchors.fill: parent
|
||||
Layout.alignment: Qt.AlignBottom
|
||||
property int nextY: mainWindow.height
|
||||
property list<Popup> popupList
|
||||
property list<InformationPopup> popupList
|
||||
property int popupCount: popupList.length
|
||||
spacing: 15
|
||||
spacing: 15 * DefaultStyle.dp
|
||||
onPopupCountChanged: {
|
||||
nextY = mainWindow.height
|
||||
for(var i = 0; i < popupCount; ++i) {
|
||||
popupList[i].y = nextY - popupList[i].height
|
||||
popupList[i].index = i
|
||||
nextY = nextY - popupList[i].height - 15
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LoadingPopup {
|
||||
id: loadingPopup
|
||||
modal: true
|
||||
closePolicy: Popup.NoAutoClose
|
||||
anchors.centerIn: parent
|
||||
padding: 20 * DefaultStyle.dp
|
||||
underlineColor: DefaultStyle.main1_500_main
|
||||
radius: 15 * DefaultStyle.dp
|
||||
}
|
||||
|
||||
AccountProxy {
|
||||
// TODO : change this so it does not display the main page for one second
|
||||
// when we fail trying to connect the first account (account is added and
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ list(APPEND _LINPHONEAPP_QML_FILES
|
|||
|
||||
view/Layout/FormItemLayout.qml
|
||||
view/Layout/Mosaic.qml
|
||||
view/Layout/RightPanelLayout.qml
|
||||
view/Layout/Section.qml
|
||||
|
||||
view/Item/Account/Accounts.qml
|
||||
|
|
@ -58,6 +59,7 @@ list(APPEND _LINPHONEAPP_QML_FILES
|
|||
view/Item/ErrorText.qml
|
||||
view/Item/IconLabelButton.qml
|
||||
view/Item/InformationPopup.qml
|
||||
view/Item/LoadingPopup.qml
|
||||
view/Item/MovableMouseArea.qml
|
||||
view/Item/NumericPad.qml
|
||||
view/Item/PhoneNumberComboBox.qml
|
||||
|
|
|
|||
|
|
@ -7,35 +7,39 @@ import Linphone
|
|||
import ConstantsCpp 1.0
|
||||
import UtilsCpp 1.0
|
||||
|
||||
// TODO : spacing
|
||||
ListView {
|
||||
id: mainItem
|
||||
// width: 400 * DefaultStyle.dp
|
||||
// height: 400 * DefaultStyle.dp
|
||||
snapMode: ListView.SnapOneItem
|
||||
orientation: Qt.Horizontal
|
||||
clip: true
|
||||
property int maxYears: 5
|
||||
readonly property var currentDate: new Date()
|
||||
highlightMoveDuration: 100
|
||||
// height: contentHeight
|
||||
|
||||
property var selectedDate
|
||||
|
||||
|
||||
property int currentMonth: calendarModel.monthAt(currentIndex) + 1 //january is index 0
|
||||
property int currentYear: calendarModel.yearAt(currentIndex)
|
||||
onCurrentYearChanged: console.log("currentyear", currentYear)
|
||||
onCurrentMonthChanged: console.log("current month", currentMonth)
|
||||
|
||||
model: Control.CalendarModel {
|
||||
id: calendarModel
|
||||
from: new Date()
|
||||
// TODO : dynamically add 5 years
|
||||
to: new Date(2025, 12, 31)
|
||||
to: UtilsCpp.addYears(new Date(), 5)
|
||||
}
|
||||
|
||||
delegate: ColumnLayout {
|
||||
width: mainItem.width
|
||||
height: mainItem.height
|
||||
property int currentMonth: model.month
|
||||
spacing: 18 * DefaultStyle.dp
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: 38 * DefaultStyle.dp
|
||||
Text {
|
||||
// TODO (high prio): don't use javascript, C++
|
||||
text: new Date(model.year, model.month, 15).toLocaleString(Qt.locale(ConstantsCpp.DefaultLocale), 'MMMM yyyy')// 15 because of timezones that can change the date for localeString
|
||||
text: UtilsCpp.toDateMonthAndYearString(new Date(model.year, model.month, 15))// 15 because of timezones that can change the date for localeString
|
||||
font {
|
||||
pixelSize: 14 * DefaultStyle.dp
|
||||
weight: 700 * DefaultStyle.dp
|
||||
|
|
@ -52,7 +56,7 @@ ListView {
|
|||
icon.height: height
|
||||
background: Item{}
|
||||
icon.source: AppIcons.leftArrow
|
||||
onClicked: if (mainItem.currentIndex > 0) --mainItem.currentIndex
|
||||
onClicked: if (mainItem.currentIndex > 0) mainItem.currentIndex = mainItem.currentIndex - 1
|
||||
}
|
||||
Button {
|
||||
Layout.preferredWidth: 20 * DefaultStyle.dp
|
||||
|
|
@ -61,62 +65,69 @@ ListView {
|
|||
icon.height: height
|
||||
background: Item{}
|
||||
icon.source: AppIcons.rightArrow
|
||||
onClicked: if (mainItem.currentIndex < mainItem.count) ++mainItem.currentIndex
|
||||
}
|
||||
}
|
||||
Control.DayOfWeekRow {
|
||||
locale: monthGrid.locale
|
||||
Layout.column: 1
|
||||
Layout.fillWidth: true
|
||||
delegate: Text {
|
||||
text: model.shortName
|
||||
color: DefaultStyle.main2_400
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
font {
|
||||
pixelSize: 12 * DefaultStyle.dp
|
||||
weight: 300 * DefaultStyle.dp
|
||||
}
|
||||
onClicked: if (mainItem.currentIndex < mainItem.count) mainItem.currentIndex = mainItem.currentIndex + 1
|
||||
}
|
||||
}
|
||||
|
||||
Control.MonthGrid {
|
||||
id: monthGrid
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
|
||||
year: model.year
|
||||
month: model.month
|
||||
// locale: Qt.locale("en_US")
|
||||
delegate: Item {
|
||||
property bool isSelectedDay: mainItem.selectedDate ? UtilsCpp.datesAreEqual(mainItem.selectedDate, model.date) : false
|
||||
Rectangle {
|
||||
anchors.centerIn: parent
|
||||
width: 30 * DefaultStyle.dp
|
||||
height: 30 * DefaultStyle.dp
|
||||
radius: 50 * DefaultStyle.dp
|
||||
color: isSelectedDay ? DefaultStyle.main1_500_main : "transparent"
|
||||
}
|
||||
Text {
|
||||
anchors.centerIn: parent
|
||||
text: monthGrid.locale.toString(model.date, "d")
|
||||
color: isSelectedDay
|
||||
? DefaultStyle.grey_0
|
||||
: UtilsCpp.isCurrentDay(model.date)
|
||||
? DefaultStyle.main1_500_main
|
||||
: UtilsCpp.isCurrentMonth(model.date)
|
||||
? DefaultStyle.main2_700
|
||||
: DefaultStyle.main2_400
|
||||
ColumnLayout {
|
||||
spacing: 12 * DefaultStyle.dp
|
||||
Control.DayOfWeekRow {
|
||||
locale: monthGrid.locale
|
||||
Layout.column: 1
|
||||
Layout.fillWidth: true
|
||||
delegate: Text {
|
||||
text: model.shortName
|
||||
color: DefaultStyle.main2_400
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
font {
|
||||
pixelSize: 12 * DefaultStyle.dp
|
||||
weight: 300 * DefaultStyle.dp
|
||||
}
|
||||
}
|
||||
}
|
||||
onClicked: (date) => {
|
||||
if (UtilsCpp.isBeforeToday(date)) return;
|
||||
mainItem.selectedDate = date
|
||||
}
|
||||
}
|
||||
|
||||
Control.MonthGrid {
|
||||
id: monthGrid
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
year: model.year
|
||||
month: model.month
|
||||
property var curDate: model.date
|
||||
onMonthChanged: console.log("cur date changed", month)
|
||||
locale: Qt.locale(ConstantsCpp.DefaultLocale)
|
||||
delegate: Item {
|
||||
property bool isSelectedDay: mainItem.selectedDate ? UtilsCpp.datesAreEqual(mainItem.selectedDate, model.date) : false
|
||||
// width: 30 * DefaultStyle.dp
|
||||
// height: 30 * DefaultStyle.dp
|
||||
Rectangle {
|
||||
anchors.centerIn: parent
|
||||
width: 30 * DefaultStyle.dp
|
||||
height: 30 * DefaultStyle.dp
|
||||
radius: 50 * DefaultStyle.dp
|
||||
color: isSelectedDay ? DefaultStyle.main1_500_main : "transparent"
|
||||
}
|
||||
Text {
|
||||
anchors.centerIn: parent
|
||||
text: UtilsCpp.toDateDayString(model.date)
|
||||
color: isSelectedDay
|
||||
? DefaultStyle.grey_0
|
||||
: UtilsCpp.isCurrentDay(model.date)
|
||||
? DefaultStyle.main1_500_main
|
||||
: UtilsCpp.dateisInMonth(model.date, mainItem.currentMonth, mainItem.currentYear)
|
||||
? DefaultStyle.main2_700
|
||||
: DefaultStyle.main2_400
|
||||
font {
|
||||
pixelSize: 12 * DefaultStyle.dp
|
||||
weight: 300 * DefaultStyle.dp
|
||||
}
|
||||
}
|
||||
}
|
||||
onClicked: (date) => {
|
||||
if (UtilsCpp.isBeforeToday(date)) return;
|
||||
mainItem.selectedDate = date
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
import QtQuick
|
||||
import QtQuick.Controls as Control
|
||||
import QtQuick.Effects
|
||||
import QtQuick.Layouts
|
||||
import Linphone
|
||||
|
||||
ComboBox {
|
||||
|
|
@ -25,7 +26,12 @@ ComboBox {
|
|||
width: 321 * DefaultStyle.dp
|
||||
height: 270 * DefaultStyle.dp
|
||||
closePolicy: Popup.NoAutoClose
|
||||
topPadding: 25 * DefaultStyle.dp
|
||||
bottomPadding: 24 * DefaultStyle.dp
|
||||
leftPadding: 21 * DefaultStyle.dp
|
||||
rightPadding: 19 * DefaultStyle.dp
|
||||
background: Item {
|
||||
anchors.fill: parent
|
||||
Rectangle {
|
||||
id: calendarBg
|
||||
anchors.fill: parent
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ Button {
|
|||
background: Rectangle {
|
||||
anchors.fill: parent
|
||||
color: mainItem.backgroundColor
|
||||
radius: mainItem.width * 1.29
|
||||
radius: mainItem.width /2
|
||||
}
|
||||
icon.source: checkedIconUrl && mainItem.checked ? checkedIconUrl : iconUrl
|
||||
icon.width: width * 0.58
|
||||
|
|
|
|||
|
|
@ -7,265 +7,281 @@ import QtQuick.Layouts
|
|||
import Linphone
|
||||
import UtilsCpp 1.0
|
||||
|
||||
ColumnLayout {
|
||||
RightPanelLayout {
|
||||
id: mainItem
|
||||
|
||||
property FriendGui contact
|
||||
Connections {
|
||||
target: contact.core
|
||||
onIsSavedChanged: {
|
||||
if (contact.core.isSaved) {
|
||||
var mainWin = UtilsCpp.getMainWindow()
|
||||
UtilsCpp.smartShowWindow(mainWin)
|
||||
mainWin.goToContactDetail(contact)
|
||||
}
|
||||
}
|
||||
}
|
||||
property string title: qsTr("Modifier contact")
|
||||
property string saveButtonText: qsTr("Enregistrer")
|
||||
property string oldPictureUri
|
||||
signal closeEdition()
|
||||
|
||||
Rectangle {
|
||||
Layout.alignment: Qt.AlignTop | Qt.AlignLeft
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 40 * DefaultStyle.dp
|
||||
Text {
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: 10 * DefaultStyle.dp
|
||||
text: mainItem.title
|
||||
font {
|
||||
pixelSize: 20 * DefaultStyle.dp
|
||||
weight: 800 * DefaultStyle.dp
|
||||
headerContent: [
|
||||
Text {
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: 31 * DefaultStyle.dp
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
text: mainItem.title
|
||||
font {
|
||||
pixelSize: 20 * DefaultStyle.dp
|
||||
weight: 800 * DefaultStyle.dp
|
||||
}
|
||||
},
|
||||
Button {
|
||||
background: Item{}
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: 41 * DefaultStyle.dp
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
width: 24 * DefaultStyle.dp
|
||||
height: 24 * DefaultStyle.dp
|
||||
icon.source: AppIcons.closeX
|
||||
icon.width: 24 * DefaultStyle.dp
|
||||
icon.height: 24 * DefaultStyle.dp
|
||||
onClicked: {
|
||||
// contact.core.pictureUri = mainItem.oldPictureUri
|
||||
mainItem.contact.core.undo()
|
||||
mainItem.closeEdition()
|
||||
}
|
||||
}
|
||||
}
|
||||
Button {
|
||||
background: Item{}
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: 10 * DefaultStyle.dp
|
||||
width: 24 * DefaultStyle.dp
|
||||
height: 24 * DefaultStyle.dp
|
||||
icon.source: AppIcons.closeX
|
||||
icon.width: 24 * DefaultStyle.dp
|
||||
icon.height: 24 * DefaultStyle.dp
|
||||
onClicked: {
|
||||
// contact.core.pictureUri = mainItem.oldPictureUri
|
||||
mainItem.contact.core.undo()
|
||||
mainItem.closeEdition()
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
}
|
||||
ColumnLayout {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
Layout.topMargin: 69 * DefaultStyle.dp
|
||||
Avatar {
|
||||
contact: mainItem.contact
|
||||
Layout.preferredWidth: 72 * DefaultStyle.dp
|
||||
Layout.preferredHeight: 72 * DefaultStyle.dp
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
}
|
||||
IconLabelButton {
|
||||
visible: !mainItem.contact || mainItem.contact.core.pictureUri.length === 0
|
||||
Layout.preferredWidth: width
|
||||
Layout.preferredHeight: 17 * DefaultStyle.dp
|
||||
iconSource: AppIcons.camera
|
||||
iconSize: 17 * DefaultStyle.dp
|
||||
text: qsTr("Ajouter une image")
|
||||
onClicked: fileDialog.open()
|
||||
}
|
||||
RowLayout {
|
||||
visible: mainItem.contact && mainItem.contact.core.pictureUri.length != 0
|
||||
content: ColumnLayout {
|
||||
anchors.centerIn: parent
|
||||
// anchors.leftMargin: 103 * DefaultStyle.dp
|
||||
ColumnLayout {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
Layout.topMargin: 69 * DefaultStyle.dp
|
||||
Avatar {
|
||||
contact: mainItem.contact
|
||||
Layout.preferredWidth: 72 * DefaultStyle.dp
|
||||
Layout.preferredHeight: 72 * DefaultStyle.dp
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
}
|
||||
IconLabelButton {
|
||||
visible: !mainItem.contact || mainItem.contact.core.pictureUri.length === 0
|
||||
Layout.preferredWidth: width
|
||||
Layout.preferredHeight: 17 * DefaultStyle.dp
|
||||
iconSource: AppIcons.pencil
|
||||
iconSource: AppIcons.camera
|
||||
iconSize: 17 * DefaultStyle.dp
|
||||
text: qsTr("Modifier")
|
||||
text: qsTr("Ajouter une image")
|
||||
onClicked: fileDialog.open()
|
||||
}
|
||||
FileDialog {
|
||||
id: fileDialog
|
||||
currentFolder: StandardPaths.standardLocations(StandardPaths.PicturesLocation)[0]
|
||||
onAccepted: {
|
||||
mainItem.oldPictureUri = mainItem.contact.core.pictureUri
|
||||
var avatarPath = UtilsCpp.createAvatar( selectedFile )
|
||||
if(avatarPath){
|
||||
mainItem.contact.core.pictureUri = avatarPath
|
||||
RowLayout {
|
||||
visible: mainItem.contact && mainItem.contact.core.pictureUri.length != 0
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
IconLabelButton {
|
||||
Layout.preferredWidth: width
|
||||
Layout.preferredHeight: 17 * DefaultStyle.dp
|
||||
iconSource: AppIcons.pencil
|
||||
iconSize: 17 * DefaultStyle.dp
|
||||
text: qsTr("Modifier")
|
||||
onClicked: fileDialog.open()
|
||||
}
|
||||
FileDialog {
|
||||
id: fileDialog
|
||||
currentFolder: StandardPaths.standardLocations(StandardPaths.PicturesLocation)[0]
|
||||
onAccepted: {
|
||||
mainItem.oldPictureUri = mainItem.contact.core.pictureUri
|
||||
var avatarPath = UtilsCpp.createAvatar( selectedFile )
|
||||
if(avatarPath){
|
||||
mainItem.contact.core.pictureUri = avatarPath
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
IconLabelButton {
|
||||
Layout.preferredHeight: 17 * DefaultStyle.dp
|
||||
Layout.preferredWidth: width
|
||||
iconSize: 17 * DefaultStyle.dp
|
||||
iconSource: AppIcons.trashCan
|
||||
text: qsTr("Supprimer")
|
||||
onClicked: mainItem.contact.core.pictureUri = ""
|
||||
IconLabelButton {
|
||||
Layout.preferredHeight: 17 * DefaultStyle.dp
|
||||
Layout.preferredWidth: width
|
||||
iconSize: 17 * DefaultStyle.dp
|
||||
iconSource: AppIcons.trashCan
|
||||
text: qsTr("Supprimer")
|
||||
onClicked: mainItem.contact.core.pictureUri = ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
RowLayout {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
Layout.fillHeight: true
|
||||
Layout.fillWidth: true
|
||||
spacing: 100 * DefaultStyle.dp
|
||||
Layout.topMargin: 50 * DefaultStyle.dp
|
||||
Layout.bottomMargin: 50 * DefaultStyle.dp
|
||||
ColumnLayout {
|
||||
spacing: 20 * DefaultStyle.dp
|
||||
FormItemLayout {
|
||||
label: qsTr("Prénom")
|
||||
contentItem: TextField {
|
||||
initialText: contact.core.givenName
|
||||
onEditingFinished: contact.core.givenName = text
|
||||
backgroundColor: DefaultStyle.grey_0
|
||||
}
|
||||
}
|
||||
FormItemLayout {
|
||||
label: qsTr("Nom")
|
||||
contentItem: TextField {
|
||||
initialText: contact.core.familyName
|
||||
onEditingFinished: contact.core.familyName = text
|
||||
backgroundColor: DefaultStyle.grey_0
|
||||
}
|
||||
}
|
||||
FormItemLayout {
|
||||
label: qsTr("Entreprise")
|
||||
contentItem: TextField {
|
||||
initialText: contact.core.organization
|
||||
onEditingFinished: contact.core.organization = text
|
||||
backgroundColor: DefaultStyle.grey_0
|
||||
}
|
||||
}
|
||||
FormItemLayout {
|
||||
label: qsTr("Fonction")
|
||||
contentItem: TextField {
|
||||
initialText: contact.core.job
|
||||
onEditingFinished: contact.core.job = text
|
||||
backgroundColor: DefaultStyle.grey_0
|
||||
}
|
||||
}
|
||||
Item{Layout.fillHeight: true}
|
||||
}
|
||||
Control.ScrollView {
|
||||
RowLayout {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
Layout.fillHeight: true
|
||||
contentHeight: content.height
|
||||
Layout.fillWidth: true
|
||||
spacing: 100 * DefaultStyle.dp
|
||||
Layout.topMargin: 50 * DefaultStyle.dp
|
||||
Layout.bottomMargin: 50 * DefaultStyle.dp
|
||||
ColumnLayout {
|
||||
id: content
|
||||
anchors.rightMargin: 10 * DefaultStyle.dp
|
||||
spacing: 20 * DefaultStyle.dp
|
||||
Repeater {
|
||||
model: VariantList {
|
||||
model: mainItem.contact && mainItem.contact.core.addresses || []
|
||||
}
|
||||
delegate: RowLayout {
|
||||
FormItemLayout {
|
||||
label: modelData.label
|
||||
contentItem: TextField {
|
||||
onEditingFinished: {
|
||||
if (text.length != 0) mainItem.contact.core.setAddressAt(index, qsTr("Address SIP"), text)
|
||||
}
|
||||
initialText: modelData.address
|
||||
backgroundColor: DefaultStyle.grey_0
|
||||
}
|
||||
}
|
||||
Button {
|
||||
Layout.preferredWidth: 24 * DefaultStyle.dp
|
||||
Layout.preferredHeight: 24 * DefaultStyle.dp
|
||||
background: Item{}
|
||||
icon.source: AppIcons.closeX
|
||||
width: 24 * DefaultStyle.dp
|
||||
height: 24 * DefaultStyle.dp
|
||||
icon.width: 24 * DefaultStyle.dp
|
||||
icon.height: 24 * DefaultStyle.dp
|
||||
onClicked: mainItem.contact.core.removeAddress(index)
|
||||
}
|
||||
FormItemLayout {
|
||||
label: qsTr("Prénom")
|
||||
contentItem: TextField {
|
||||
initialText: contact.core.givenName
|
||||
onEditingFinished: contact.core.givenName = text
|
||||
backgroundColor: DefaultStyle.grey_0
|
||||
}
|
||||
}
|
||||
RowLayout {
|
||||
FormItemLayout {
|
||||
label: qsTr("Adresse SIP")
|
||||
contentItem: TextField {
|
||||
backgroundColor: DefaultStyle.grey_0
|
||||
onEditingFinished: {
|
||||
if (text.length != 0) mainItem.contact.core.appendAddress(text)
|
||||
text = ""
|
||||
}
|
||||
}
|
||||
}
|
||||
Item {
|
||||
Layout.preferredWidth: 24 * DefaultStyle.dp
|
||||
Layout.preferredHeight: 24 * DefaultStyle.dp
|
||||
FormItemLayout {
|
||||
label: qsTr("Nom")
|
||||
contentItem: TextField {
|
||||
initialText: contact.core.familyName
|
||||
onEditingFinished: contact.core.familyName = text
|
||||
backgroundColor: DefaultStyle.grey_0
|
||||
}
|
||||
}
|
||||
Repeater {
|
||||
// phone numbers
|
||||
model: VariantList {
|
||||
model: mainItem.contact && mainItem.contact.core.phoneNumbers || []
|
||||
}
|
||||
delegate: RowLayout {
|
||||
FormItemLayout {
|
||||
label: modelData.label
|
||||
contentItem: TextField {
|
||||
initialText: modelData.address
|
||||
onEditingFinished: {
|
||||
if (text.length != 0) mainItem.contact.core.setPhoneNumberAt(index, qsTr("Téléphone"), text)
|
||||
}
|
||||
backgroundColor: DefaultStyle.grey_0
|
||||
}
|
||||
}
|
||||
Button {
|
||||
Layout.preferredWidth: 24 * DefaultStyle.dp
|
||||
Layout.preferredHeight: 24 * DefaultStyle.dp
|
||||
background: Item{}
|
||||
icon.source: AppIcons.closeX
|
||||
width: 24 * DefaultStyle.dp
|
||||
height: 24 * DefaultStyle.dp
|
||||
icon.width: 24 * DefaultStyle.dp
|
||||
icon.height: 24 * DefaultStyle.dp
|
||||
onClicked: mainItem.contact.core.removePhoneNumber(index)
|
||||
}
|
||||
FormItemLayout {
|
||||
label: qsTr("Entreprise")
|
||||
contentItem: TextField {
|
||||
initialText: contact.core.organization
|
||||
onEditingFinished: contact.core.organization = text
|
||||
backgroundColor: DefaultStyle.grey_0
|
||||
}
|
||||
}
|
||||
RowLayout {
|
||||
FormItemLayout {
|
||||
label: qsTr("Phone")
|
||||
contentItem: TextField {
|
||||
backgroundColor: DefaultStyle.grey_0
|
||||
onEditingFinished: {
|
||||
if (text.length != 0) mainItem.contact.core.appendPhoneNumber(label, text)
|
||||
setText("")
|
||||
}
|
||||
}
|
||||
}
|
||||
Item {
|
||||
Layout.preferredWidth: 24 * DefaultStyle.dp
|
||||
Layout.preferredHeight: 24 * DefaultStyle.dp
|
||||
FormItemLayout {
|
||||
label: qsTr("Fonction")
|
||||
contentItem: TextField {
|
||||
initialText: contact.core.job
|
||||
onEditingFinished: contact.core.job = text
|
||||
backgroundColor: DefaultStyle.grey_0
|
||||
}
|
||||
}
|
||||
Item{Layout.fillHeight: true}
|
||||
}
|
||||
Control.ScrollBar.vertical: Control.ScrollBar{
|
||||
id: scrollbar
|
||||
active: true
|
||||
interactive: true
|
||||
policy: Control.ScrollBar.AsNeeded
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.right: parent.right
|
||||
anchors.leftMargin: 15 * DefaultStyle.dp
|
||||
}
|
||||
Control.ScrollBar.horizontal: Control.ScrollBar{
|
||||
visible: false
|
||||
Control.ScrollView {
|
||||
Layout.fillHeight: true
|
||||
contentHeight: content.height
|
||||
ColumnLayout {
|
||||
id: content
|
||||
anchors.rightMargin: 10 * DefaultStyle.dp
|
||||
spacing: 20 * DefaultStyle.dp
|
||||
Repeater {
|
||||
model: VariantList {
|
||||
model: mainItem.contact && mainItem.contact.core.addresses || []
|
||||
}
|
||||
delegate: FormItemLayout {
|
||||
label: modelData.label
|
||||
contentItem: RowLayout {
|
||||
TextField {
|
||||
onEditingFinished: {
|
||||
if (text.length != 0) mainItem.contact.core.setAddressAt(index, qsTr("Address SIP"), text)
|
||||
}
|
||||
initialText: modelData.address
|
||||
backgroundColor: DefaultStyle.grey_0
|
||||
Layout.preferredWidth: width
|
||||
Layout.preferredHeight: height
|
||||
}
|
||||
Button {
|
||||
Layout.preferredWidth: 24 * DefaultStyle.dp
|
||||
Layout.preferredHeight: 24 * DefaultStyle.dp
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
background: Item{}
|
||||
icon.source: AppIcons.closeX
|
||||
width: 24 * DefaultStyle.dp
|
||||
height: 24 * DefaultStyle.dp
|
||||
icon.width: 24 * DefaultStyle.dp
|
||||
icon.height: 24 * DefaultStyle.dp
|
||||
onClicked: mainItem.contact.core.removeAddress(index)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
RowLayout {
|
||||
FormItemLayout {
|
||||
label: qsTr("Adresse SIP")
|
||||
contentItem: TextField {
|
||||
backgroundColor: DefaultStyle.grey_0
|
||||
onEditingFinished: {
|
||||
if (text.length != 0) mainItem.contact.core.appendAddress(text)
|
||||
text = ""
|
||||
}
|
||||
}
|
||||
}
|
||||
Item {
|
||||
Layout.preferredWidth: 24 * DefaultStyle.dp
|
||||
Layout.preferredHeight: 24 * DefaultStyle.dp
|
||||
}
|
||||
}
|
||||
Repeater {
|
||||
// phone numbers
|
||||
model: VariantList {
|
||||
model: mainItem.contact && mainItem.contact.core.phoneNumbers || []
|
||||
}
|
||||
delegate: RowLayout {
|
||||
FormItemLayout {
|
||||
label: modelData.label
|
||||
contentItem: TextField {
|
||||
initialText: modelData.address
|
||||
onEditingFinished: {
|
||||
if (text.length != 0) mainItem.contact.core.setPhoneNumberAt(index, qsTr("Téléphone"), text)
|
||||
}
|
||||
backgroundColor: DefaultStyle.grey_0
|
||||
}
|
||||
}
|
||||
Button {
|
||||
Layout.preferredWidth: 24 * DefaultStyle.dp
|
||||
Layout.preferredHeight: 24 * DefaultStyle.dp
|
||||
background: Item{}
|
||||
icon.source: AppIcons.closeX
|
||||
width: 24 * DefaultStyle.dp
|
||||
height: 24 * DefaultStyle.dp
|
||||
icon.width: 24 * DefaultStyle.dp
|
||||
icon.height: 24 * DefaultStyle.dp
|
||||
onClicked: mainItem.contact.core.removePhoneNumber(index)
|
||||
}
|
||||
}
|
||||
}
|
||||
RowLayout {
|
||||
FormItemLayout {
|
||||
label: qsTr("Phone")
|
||||
contentItem: TextField {
|
||||
backgroundColor: DefaultStyle.grey_0
|
||||
onEditingFinished: {
|
||||
if (text.length != 0) mainItem.contact.core.appendPhoneNumber(label, text)
|
||||
setText("")
|
||||
}
|
||||
}
|
||||
}
|
||||
Item {
|
||||
Layout.preferredWidth: 24 * DefaultStyle.dp
|
||||
Layout.preferredHeight: 24 * DefaultStyle.dp
|
||||
}
|
||||
}
|
||||
Item{Layout.fillHeight: true}
|
||||
}
|
||||
Control.ScrollBar.vertical: Control.ScrollBar{
|
||||
id: scrollbar
|
||||
active: true
|
||||
interactive: true
|
||||
policy: Control.ScrollBar.AsNeeded
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.right: parent.right
|
||||
anchors.leftMargin: 15 * DefaultStyle.dp
|
||||
}
|
||||
Control.ScrollBar.horizontal: Control.ScrollBar{
|
||||
visible: false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
Layout.bottomMargin: 100 * DefaultStyle.dp
|
||||
Layout.preferredWidth: 165 * DefaultStyle.dp
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
enabled: mainItem.contact && mainItem.contact.core.givenName.length > 0
|
||||
text: mainItem.saveButtonText
|
||||
leftPadding: 20 * DefaultStyle.dp
|
||||
rightPadding: 20 * DefaultStyle.dp
|
||||
topPadding: 11 * DefaultStyle.dp
|
||||
bottomPadding: 11 * DefaultStyle.dp
|
||||
onClicked: {
|
||||
mainItem.contact.core.save()
|
||||
mainItem.closeEdition()
|
||||
Button {
|
||||
Layout.bottomMargin: 100 * DefaultStyle.dp
|
||||
Layout.preferredWidth: 165 * DefaultStyle.dp
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
enabled: mainItem.contact && mainItem.contact.core.givenName.length > 0
|
||||
text: mainItem.saveButtonText
|
||||
leftPadding: 20 * DefaultStyle.dp
|
||||
rightPadding: 20 * DefaultStyle.dp
|
||||
topPadding: 11 * DefaultStyle.dp
|
||||
bottomPadding: 11 * DefaultStyle.dp
|
||||
onClicked: {
|
||||
mainItem.contact.core.save()
|
||||
mainItem.closeEdition()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4,6 +4,7 @@ import QtQuick.Controls as Control
|
|||
|
||||
import Linphone
|
||||
import UtilsCpp 1.0
|
||||
import ConstantsCpp 1.0
|
||||
|
||||
ListView {
|
||||
id: mainItem
|
||||
|
|
@ -40,11 +41,7 @@ ListView {
|
|||
property FriendGui selectedContact: model.getAt(currentIndex) || null
|
||||
|
||||
onCurrentIndexChanged: selectedContact = model.getAt(currentIndex) || null
|
||||
onCountChanged: {
|
||||
selectedContact = model.getAt(currentIndex) || null
|
||||
}
|
||||
|
||||
// signal contactSelected(var contact)
|
||||
signal contactStarredChanged()
|
||||
signal contactDeletionRequested(FriendGui contact)
|
||||
signal contactAddedToSelection()
|
||||
|
|
@ -66,6 +63,9 @@ ListView {
|
|||
|
||||
model: MagicSearchProxy {
|
||||
searchText: searchBarText.length === 0 ? "*" : searchBarText
|
||||
onFriendCreated: (index) => {
|
||||
mainItem.currentIndex = index
|
||||
}
|
||||
}
|
||||
|
||||
Control.ScrollBar.vertical: ScrollBar {
|
||||
|
|
@ -85,9 +85,10 @@ ListView {
|
|||
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
|
||||
target: modelData.core
|
||||
onStarredChanged: mainItem.contactStarredChanged()
|
||||
}
|
||||
|
|
@ -98,7 +99,7 @@ ListView {
|
|||
anchors.verticalCenter: parent.verticalCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
width: 20 * DefaultStyle.dp
|
||||
opacity: (!previousItem || !previousDisplayName.startsWith(displayName[0])) ? 1 : 0
|
||||
opacity: (!previousItem || !previousDisplayName.toLocaleLowerCase(ConstantsCpp.DefaultLocale).startsWith(displayName[0].toLocaleLowerCase(ConstantsCpp.DefaultLocale))) ? 1 : 0
|
||||
text: displayName[0]
|
||||
color: DefaultStyle.main2_400
|
||||
font {
|
||||
|
|
|
|||
|
|
@ -9,12 +9,11 @@ Popup {
|
|||
property string title
|
||||
property string description
|
||||
property int index
|
||||
signal closePopup(int index)
|
||||
onClosed: closePopup(index)
|
||||
onAboutToShow: {
|
||||
autoClosePopup.restart()
|
||||
}
|
||||
onAboutToHide: {
|
||||
popupLayout.popupList.splice(mainItem.index, 1)
|
||||
}
|
||||
closePolicy: Popup.NoAutoClose
|
||||
x : parent.x + parent.width - width
|
||||
// y : parent.y + parent.height - height
|
||||
|
|
|
|||
32
Linphone/view/Item/LoadingPopup.qml
Normal file
32
Linphone/view/Item/LoadingPopup.qml
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
import QtQuick 2.15
|
||||
import QtQuick.Layouts 1.3
|
||||
import QtQuick.Controls
|
||||
import Linphone
|
||||
|
||||
Popup {
|
||||
id: mainItem
|
||||
property string text
|
||||
modal: true
|
||||
closePolicy: Control.Popup.NoAutoClose
|
||||
anchors.centerIn: parent
|
||||
padding: 20 * DefaultStyle.dp
|
||||
underlineColor: DefaultStyle.main1_500_main
|
||||
radius: 15 * DefaultStyle.dp
|
||||
// onAboutToShow: width = contentText.implicitWidth
|
||||
contentItem: ColumnLayout {
|
||||
spacing: 15 * DefaultStyle.dp
|
||||
BusyIndicator{
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
Layout.preferredWidth: 33 * DefaultStyle.dp
|
||||
Layout.preferredHeight: 33 * DefaultStyle.dp
|
||||
}
|
||||
Text {
|
||||
id: contentText
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
text: mainItem.text
|
||||
font.pixelSize: 14 * DefaultStyle.dp
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -14,14 +14,14 @@ ListView {
|
|||
property string searchBarText
|
||||
property bool hoverEnabled: true
|
||||
property var delegateButtons
|
||||
property ConferenceInfoGui selectedConference: model.getAt(currentIndex) || null
|
||||
property ConferenceInfoGui selectedConference: currentIndex != -1 ? model.getAt(currentIndex) : null
|
||||
|
||||
spacing: 8 * DefaultStyle.dp
|
||||
currentIndex: confInfoProxy.currentDateIndex
|
||||
|
||||
onCountChanged: selectedConference = model.getAt(currentIndex) || null
|
||||
onCountChanged: selectedConference = currentIndex != -1 ? model.getAt(currentIndex) : null
|
||||
onCurrentIndexChanged: {
|
||||
selectedConference = currentIndex != confInfoProxy.currentDateIndex ? model.getAt(currentIndex) : null
|
||||
selectedConference = model.getAt(currentIndex)
|
||||
}
|
||||
onVisibleChanged: if( visible) {
|
||||
mainItem.positionViewAtIndex(currentIndex, ListView.Center)// First approximative move
|
||||
|
|
@ -34,16 +34,13 @@ ListView {
|
|||
}
|
||||
// using highlight doesn't center, take time before moving and don't work for not visible item (like not loaded)
|
||||
highlightFollowsCurrentItem: false
|
||||
|
||||
function forceUpdate() {
|
||||
confInfoProxy.lUpdate()
|
||||
}
|
||||
|
||||
signal conferenceSelected(var contact)
|
||||
|
||||
model: ConferenceInfoProxy {
|
||||
id: confInfoProxy
|
||||
searchText: searchBarText.length === 0 ? "" : searchBarText
|
||||
filterType: ConferenceInfoProxy.None
|
||||
}
|
||||
|
||||
section {
|
||||
|
|
@ -91,12 +88,12 @@ ListView {
|
|||
Layout.fillWidth: false
|
||||
Layout.preferredWidth: 32 * DefaultStyle.dp
|
||||
Layout.minimumWidth: 32 * DefaultStyle.dp
|
||||
height: 51 * DefaultStyle.dp
|
||||
visible: !previousDateString || previousDateString != dateString
|
||||
Layout.preferredHeight: 51 * DefaultStyle.dp
|
||||
visible: previousDateString.length == 0 || previousDateString != dateString
|
||||
spacing: 0
|
||||
//anchors.leftMargin: 45 * DefaultStyle.dp
|
||||
Text {
|
||||
Layout.preferredHeight: 19 * DefaultStyle.dp
|
||||
Layout.alignment: Qt.AlignCenter
|
||||
text: day.substring(0,3) + '.'
|
||||
color: DefaultStyle.main2_500main
|
||||
wrapMode: Text.NoWrap
|
||||
|
|
@ -109,8 +106,8 @@ ListView {
|
|||
}
|
||||
Rectangle {
|
||||
id: dayNum
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: width
|
||||
Layout.preferredWidth: 32 * DefaultStyle.dp
|
||||
Layout.preferredHeight: 32 * DefaultStyle.dp
|
||||
Layout.alignment: Qt.AlignCenter
|
||||
radius: height/2
|
||||
property var isCurrentDay: UtilsCpp.isCurrentDay(dateTime)
|
||||
|
|
@ -118,9 +115,9 @@ ListView {
|
|||
color: isCurrentDay ? DefaultStyle.main1_500_main : "transparent"
|
||||
|
||||
Text {
|
||||
id: dayNumText
|
||||
anchors.centerIn: parent
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
text: UtilsCpp.toDateDayString(dateTime)
|
||||
color: dayNum.isCurrentDay ? DefaultStyle.grey_0 : DefaultStyle.main2_500main
|
||||
wrapMode: Text.NoWrap
|
||||
|
|
@ -208,18 +205,16 @@ ListView {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
MouseArea {
|
||||
id: confArea
|
||||
hoverEnabled: mainItem.hoverEnabled
|
||||
visible: !dateDay.visible && itemDelegate.haveModel
|
||||
anchors.fill: parent
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: {
|
||||
mainItem.currentIndex = index
|
||||
mainItem.conferenceSelected($modelData)
|
||||
}
|
||||
}
|
||||
// MouseArea {
|
||||
// id: confArea
|
||||
// hoverEnabled: mainItem.hoverEnabled
|
||||
// visible: !dateDay.visible && itemDelegate.haveModel
|
||||
// anchors.fill: parent
|
||||
// cursorShape: Qt.PointingHandCursor
|
||||
// onClicked: {
|
||||
// mainItem.currentIndex = index
|
||||
// mainItem.conferenceSelected($modelData)
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ import QtQuick.Controls as Control
|
|||
import Linphone
|
||||
import UtilsCpp 1.0
|
||||
|
||||
//TODO : spacing layout
|
||||
ColumnLayout {
|
||||
id: mainItem
|
||||
spacing: 8 * DefaultStyle.dp
|
||||
|
|
@ -18,7 +17,6 @@ ColumnLayout {
|
|||
Connections {
|
||||
target: mainItem.conferenceInfoGui.core
|
||||
onSchedulerStateChanged: {
|
||||
console.log("scheduler state changed", mainItem.conferenceInfoGui.core.schedulerState)
|
||||
if (mainItem.conferenceInfoGui.core.schedulerState == LinphoneEnums.ConferenceSchedulerState.Ready) {
|
||||
mainItem.saveSucceed(isCreation)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ import Linphone
|
|||
|
||||
Control.TabBar {
|
||||
id: mainItem
|
||||
spacing: 15 * DefaultStyle.dp
|
||||
topPadding: 20 * DefaultStyle.dp
|
||||
spacing: 32 * DefaultStyle.dp
|
||||
topPadding: 36 * DefaultStyle.dp
|
||||
|
||||
property var model
|
||||
readonly property alias cornerRadius: bottomLeftCorner.radius
|
||||
|
|
|
|||
|
|
@ -68,17 +68,17 @@ Item {
|
|||
Component{
|
||||
id: activeSpeakerComponent
|
||||
ActiveSpeakerLayout{
|
||||
Layout.Layout.fillWidth: true
|
||||
Layout.Layout.fillHeight: true
|
||||
call: mainItem.call
|
||||
Layout.Layout.fillWidth: true
|
||||
Layout.Layout.fillHeight: true
|
||||
call: mainItem.call
|
||||
}
|
||||
}
|
||||
Component{
|
||||
id: gridComponent
|
||||
GridLayout{
|
||||
Layout.Layout.fillWidth: true
|
||||
Layout.Layout.fillHeight: true
|
||||
call: mainItem.call
|
||||
Layout.Layout.fillWidth: true
|
||||
Layout.Layout.fillHeight: true
|
||||
call: mainItem.call
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,7 +55,6 @@ ColumnLayout {
|
|||
// Layout.fillWidth: true
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
Avatar {
|
||||
// TODO : find friend and pass contact argument
|
||||
id: detailAvatar
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
width: 100 * DefaultStyle.dp
|
||||
|
|
|
|||
30
Linphone/view/Layout/RightPanelLayout.qml
Normal file
30
Linphone/view/Layout/RightPanelLayout.qml
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
import QtQuick 2.15
|
||||
import QtQuick.Effects
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Controls as Control
|
||||
import Linphone
|
||||
import UtilsCpp 1.0
|
||||
|
||||
Item {
|
||||
id: mainItem
|
||||
property color panelColor: DefaultStyle.grey_100
|
||||
property alias headerContent: rightPanelHeader.children
|
||||
property alias content: rightPanelContent.children
|
||||
|
||||
Rectangle {
|
||||
id: rightPanelHeader
|
||||
color: DefaultStyle.grey_0
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
height: 57 * DefaultStyle.dp
|
||||
}
|
||||
Rectangle {
|
||||
id: rightPanelContent
|
||||
color: mainItem.panelColor
|
||||
anchors.top: rightPanelHeader.bottom
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.bottom: parent.bottom
|
||||
}
|
||||
}
|
||||
|
|
@ -18,24 +18,8 @@ Item {
|
|||
property color rightPanelColor: DefaultStyle.grey_100
|
||||
property alias leftPanelContent: leftPanel.children
|
||||
property alias rightPanelStackView: rightPanelStackView
|
||||
property alias contactEditionComp: contactEditionComp
|
||||
property alias rightPanel: rightPanel
|
||||
signal noItemButtonPressed()
|
||||
signal contactEditionClosed()
|
||||
|
||||
function createContact(name, address) {
|
||||
var friendGui = Qt.createQmlObject('import Linphone
|
||||
FriendGui{
|
||||
}', mainItem)
|
||||
friendGui.core.givenName = UtilsCpp.getGivenNameFromFullName(name)
|
||||
friendGui.core.familyName = UtilsCpp.getFamilyNameFromFullName(name)
|
||||
friendGui.core.defaultAddress = address
|
||||
rightPanelStackView.push(contactEditionComp, {"contact": friendGui, "title": qsTr("Nouveau contact"), "saveButtonText": qsTr("Créer")})
|
||||
}
|
||||
|
||||
function editContact(friendGui) {
|
||||
rightPanelStackView.push(contactEditionComp, {"contact": friendGui, "title": qsTr("Modifier contact"), "saveButtonText": qsTr("Enregistrer")})
|
||||
}
|
||||
|
||||
// Control.SplitView {
|
||||
// id: splitView
|
||||
|
|
@ -223,24 +207,8 @@ Item {
|
|||
}
|
||||
|
||||
}
|
||||
Item {
|
||||
Control.StackView {
|
||||
id: rightPanelStackView
|
||||
anchors.fill: parent
|
||||
anchors.topMargin: 39 * DefaultStyle.dp
|
||||
anchors.leftMargin: 39 * DefaultStyle.dp
|
||||
}
|
||||
}
|
||||
// We need this component here as it is used in multiple subPages (Call and Contact pages)
|
||||
Component {
|
||||
id: contactEditionComp
|
||||
ContactEdition {
|
||||
property string objectName: "contactEdition"
|
||||
onCloseEdition: {
|
||||
rightPanelStackView.pop(Control.StackView.Immediate)
|
||||
mainItem.contactEditionClosed()
|
||||
}
|
||||
}
|
||||
Control.StackView {
|
||||
id: rightPanelStackView
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ AbstractMainPage {
|
|||
property bool isRegistered: account ? account.core.registrationState == LinphoneEnums.RegistrationState.Ok : false
|
||||
property int selectedParticipantsCount
|
||||
signal startGroupCallRequested()
|
||||
signal createContactRequested(string name, string address)
|
||||
|
||||
Connections {
|
||||
enabled: confInfoGui
|
||||
|
|
@ -529,7 +530,7 @@ AbstractMainPage {
|
|||
}
|
||||
onClicked: {
|
||||
detailOptions.close()
|
||||
mainItem.createContact(contactDetail.contactName, contactDetail.contactAddress)
|
||||
mainItem.createContactRequested(contactDetail.contactName, contactDetail.contactAddress)
|
||||
}
|
||||
}
|
||||
Button {
|
||||
|
|
|
|||
|
|
@ -25,25 +25,28 @@ AbstractMainPage {
|
|||
|
||||
onNoItemButtonPressed: createContact("", "")
|
||||
|
||||
function createContact(name, address) {
|
||||
var friendGui = Qt.createQmlObject('import Linphone
|
||||
FriendGui{
|
||||
}', mainItem)
|
||||
friendGui.core.givenName = UtilsCpp.getGivenNameFromFullName(name)
|
||||
friendGui.core.familyName = UtilsCpp.getFamilyNameFromFullName(name)
|
||||
friendGui.core.defaultAddress = address
|
||||
rightPanelStackView.push(contactEdition, {"contact": friendGui, "title": qsTr("Nouveau contact"), "saveButtonText": qsTr("Créer")})
|
||||
}
|
||||
|
||||
function editContact(friendGui) {
|
||||
rightPanelStackView.push(contactEdition, {"contact": friendGui, "title": qsTr("Modifier contact"), "saveButtonText": qsTr("Enregistrer")})
|
||||
}
|
||||
|
||||
// rightPanelStackView.initialItem: contactDetail
|
||||
Binding {
|
||||
mainItem.showDefaultItem: false
|
||||
when: rightPanelStackView.currentItem && rightPanelStackView.currentItem.objectName == "contactEdition"
|
||||
when: rightPanelStackView.currentItem
|
||||
restoreMode: Binding.RestoreBinding
|
||||
}
|
||||
Connections {
|
||||
target: mainItem
|
||||
onContactEditionClosed: {
|
||||
mainItem.forceListsUpdate()
|
||||
// mainItem.rightPanelStackView.replace(contactDetail, Control.StackView.Immediate)
|
||||
}
|
||||
}
|
||||
|
||||
showDefaultItem: contactList.model.sourceModel.count === 0
|
||||
|
||||
function goToNewCall() {
|
||||
listStackView.replace(newCallItem)
|
||||
}
|
||||
|
||||
property MagicSearchProxy allFriends: MagicSearchProxy {
|
||||
searchText: searchBar.text.length === 0 ? "*" : searchBar.text
|
||||
|
|
@ -107,6 +110,7 @@ AbstractMainPage {
|
|||
id: searchBar
|
||||
Layout.leftMargin: leftPanel.leftMargin
|
||||
Layout.rightMargin: leftPanel.rightMargin
|
||||
Layout.topMargin: 18 * DefaultStyle.dp
|
||||
Layout.fillWidth: true
|
||||
placeholderText: qsTr("Rechercher un contact")
|
||||
}
|
||||
|
|
@ -223,6 +227,12 @@ AbstractMainPage {
|
|||
contactMenuVisible: true
|
||||
searchBarText: searchBar.text
|
||||
model: allFriends
|
||||
Connections {
|
||||
target: allFriends
|
||||
onFriendCreated: (index) => {
|
||||
contactList.currentIndex = index
|
||||
}
|
||||
}
|
||||
onSelectedContactChanged: {
|
||||
if (selectedContact) {
|
||||
favoriteList.currentIndex = -1
|
||||
|
|
@ -592,4 +602,15 @@ AbstractMainPage {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: contactEdition
|
||||
ContactEdition {
|
||||
Control.StackView.onActivated: console.log("edit/create contact")
|
||||
onCloseEdition: {
|
||||
if (rightPanelStackView.depth <= 1) rightPanelStackView.clear()
|
||||
else rightPanelStackView.pop(Control.StackView.Immediate)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,14 +16,13 @@ AbstractMainPage {
|
|||
property bool leftPanelEnabled: true
|
||||
property ConferenceInfoGui selectedConference
|
||||
property int meetingListCount
|
||||
signal newConfCreated()
|
||||
signal returnRequested()
|
||||
signal addParticipantsValidated(list<string> selectedParticipants)
|
||||
Component.onCompleted: rightPanelStackView.push(overridenRightPanel, Control.StackView.Immediate)
|
||||
|
||||
onSelectedConferenceChanged: {
|
||||
overridenRightPanelStackView.clear()
|
||||
if (selectedConference) {
|
||||
if (selectedConference && selectedConference.core.haveModel) {
|
||||
if (!overridenRightPanelStackView.currentItem || overridenRightPanelStackView.currentItem != meetingDetail) overridenRightPanelStackView.replace(meetingDetail, Control.StackView.Immediate)
|
||||
}
|
||||
}
|
||||
|
|
@ -136,7 +135,6 @@ AbstractMainPage {
|
|||
mainItem.selectedConference = conferenceList.selectedConference
|
||||
}
|
||||
RowLayout {
|
||||
visible: leftPanelStackView.currentItem == listLayout
|
||||
enabled: mainItem.leftPanelEnabled
|
||||
Layout.rightMargin: 39 * DefaultStyle.dp
|
||||
spacing: 0
|
||||
|
|
@ -200,10 +198,6 @@ AbstractMainPage {
|
|||
}
|
||||
Connections {
|
||||
target: mainItem
|
||||
onNewConfCreated: {
|
||||
// TODO : manque un connect côté c++
|
||||
conferenceList.forceUpdate()
|
||||
}
|
||||
}
|
||||
Control.ScrollBar.vertical: ScrollBar {
|
||||
id: meetingsScrollbar
|
||||
|
|
@ -222,8 +216,10 @@ AbstractMainPage {
|
|||
Component {
|
||||
id: createConf
|
||||
ColumnLayout {
|
||||
id: createConfLayout
|
||||
property ConferenceInfoGui conferenceInfoGui
|
||||
property bool isCreation
|
||||
spacing: 33 * DefaultStyle.dp
|
||||
|
||||
RowLayout {
|
||||
width: 320 * DefaultStyle.dp
|
||||
|
|
@ -235,6 +231,8 @@ AbstractMainPage {
|
|||
Layout.preferredHeight: 24 * DefaultStyle.dp
|
||||
icon.width: 24 * DefaultStyle.dp
|
||||
icon.height: 24 * DefaultStyle.dp
|
||||
topPadding: 6 * DefaultStyle.dp
|
||||
bottomPadding: 6 * DefaultStyle.dp
|
||||
onClicked: {
|
||||
meetingSetup.conferenceInfoGui.core.undo()
|
||||
leftPanelStackView.pop()
|
||||
|
|
@ -250,10 +248,20 @@ AbstractMainPage {
|
|||
Layout.fillWidth: true
|
||||
}
|
||||
Button {
|
||||
Layout.preferredWidth: 57 * DefaultStyle.dp
|
||||
topPadding: 6 * DefaultStyle.dp
|
||||
bottomPadding: 6 * DefaultStyle.dp
|
||||
text: qsTr("Créer")
|
||||
textSize: 13 * DefaultStyle.dp
|
||||
contentItem: Text {
|
||||
text: qsTr("Créer")
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
|
||||
font {
|
||||
pixelSize: 13 * DefaultStyle.dp
|
||||
weight: 600 * DefaultStyle.dp
|
||||
}
|
||||
color: DefaultStyle.grey_0
|
||||
}
|
||||
onClicked: {
|
||||
if (meetingSetup.conferenceInfoGui.core.subject.length === 0) {
|
||||
UtilsCpp.showInformationPopup(qsTr("Erreur"), qsTr("La conférence doit contenir un sujet"), false)
|
||||
|
|
@ -272,8 +280,23 @@ AbstractMainPage {
|
|||
conferenceInfoGui: parent.conferenceInfoGui
|
||||
isCreation: parent.isCreation
|
||||
Layout.rightMargin: 35 * DefaultStyle.dp
|
||||
Connections {
|
||||
target: meetingSetup.conferenceInfoGui ? meetingSetup.conferenceInfoGui.core : null
|
||||
onConferenceSchedulerStateChanged: {
|
||||
var mainWin = UtilsCpp.getMainWindow()
|
||||
if (meetingSetup.conferenceInfoGui.core.schedulerState == LinphoneEnums.ConferenceSchedulerState.AllocationPending
|
||||
|| meetingSetup.conferenceInfoGui.core.schedulerState == LinphoneEnums.ConferenceSchedulerState.Updating) {
|
||||
mainWin.showLoadingPopup(qsTr("Création de la conférence en cours..."))
|
||||
} else {
|
||||
if (meetingSetup.conferenceInfoGui.core.schedulerState == LinphoneEnums.ConferenceSchedulerState.Error) {
|
||||
UtilsCpp.showInformationPopup(qsTr("Erreur"), qsTr("La création de la conférence a échoué"), false)
|
||||
}
|
||||
mainWin.closeLoadingPopup()
|
||||
}
|
||||
createConfLayout.enabled = meetingSetup.conferenceInfoGui.core.schedulerState != LinphoneEnums.ConferenceSchedulerState.AllocationPending
|
||||
}
|
||||
}
|
||||
onSaveSucceed: {
|
||||
mainItem.newConfCreated()
|
||||
leftPanelStackView.pop()
|
||||
UtilsCpp.showInformationPopup(qsTr("Nouvelle réunion"), qsTr("Réunion planifiée avec succès"), true)
|
||||
}
|
||||
|
|
@ -364,6 +387,15 @@ AbstractMainPage {
|
|||
overridenRightPanelStackView.pop()
|
||||
}
|
||||
}
|
||||
Connections {
|
||||
target: conferenceEdit.conferenceInfoGui ? conferenceEdit.conferenceInfoGui.core : null
|
||||
onConferenceSchedulerStateChanged: {
|
||||
var mainWin = UtilsCpp.getMainWindow()
|
||||
if (conferenceEdit.conferenceInfoGui.core.schedulerState == LinphoneEnums.ConferenceSchedulerState.Error) {
|
||||
UtilsCpp.showInformationPopup(qsTr("Erreur"), qsTr("L'édition de la conférence a échoué"), false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -382,12 +414,12 @@ AbstractMainPage {
|
|||
Layout.preferredHeight: 24 * DefaultStyle.dp
|
||||
icon.width: 24 * DefaultStyle.dp
|
||||
icon.height: 24 * DefaultStyle.dp
|
||||
onClicked: mainItem.returnRequested()
|
||||
onClicked: container.pop()
|
||||
}
|
||||
ColumnLayout {
|
||||
spacing: 3 * DefaultStyle.dp
|
||||
Text {
|
||||
text: qsTr("Appel de groupe")
|
||||
text: qsTr("Ajouter des participants")
|
||||
color: DefaultStyle.main1_500_main
|
||||
maximumLineCount: 1
|
||||
font {
|
||||
|
|
@ -434,6 +466,7 @@ AbstractMainPage {
|
|||
visible: mainItem.selectedConference
|
||||
spacing: 25 * DefaultStyle.dp
|
||||
Section {
|
||||
Layout.topMargin: 58 * DefaultStyle.dp
|
||||
visible: mainItem.selectedConference
|
||||
content: RowLayout {
|
||||
spacing: 8 * DefaultStyle.dp
|
||||
|
|
|
|||
|
|
@ -87,4 +87,6 @@ QtObject {
|
|||
property string squaresFour: "image://internal/squares-four.svg"
|
||||
property string handWaving: "image://internal/hand-waving.svg"
|
||||
property string screencast: "image://internal/screencast.svg"
|
||||
property string videoconference: "image://internal/video-conference.svg"
|
||||
property string videoconferenceSelected: "image://internal/video-conference-selected.svg"
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue