diff --git a/linphone-app/src/app/proxyModel/SortFilterProxyModel.cpp b/linphone-app/src/app/proxyModel/SortFilterProxyModel.cpp index 99e5cda25..782bcea9a 100644 --- a/linphone-app/src/app/proxyModel/SortFilterProxyModel.cpp +++ b/linphone-app/src/app/proxyModel/SortFilterProxyModel.cpp @@ -34,6 +34,11 @@ int SortFilterProxyModel::getFilterType () const{ return mFilterType; } +QVariant SortFilterProxyModel::getAt(const int& atIndex) const { + auto modelIndex = index(atIndex,0); + return sourceModel()->data(mapToSource(modelIndex), 0); +} + void SortFilterProxyModel::setFilterType (int filterType) { if (getFilterType() != filterType) { mFilterType = filterType; diff --git a/linphone-app/src/app/proxyModel/SortFilterProxyModel.hpp b/linphone-app/src/app/proxyModel/SortFilterProxyModel.hpp index 73ca796d8..700060ef1 100644 --- a/linphone-app/src/app/proxyModel/SortFilterProxyModel.hpp +++ b/linphone-app/src/app/proxyModel/SortFilterProxyModel.hpp @@ -33,10 +33,12 @@ public: virtual int getCount() const; virtual int getFilterType () const; + Q_INVOKABLE QVariant getAt(const int& index) const; virtual void setFilterType (int filterType); Q_INVOKABLE void remove(int index, int count = 1); + signals: void countChanged(); diff --git a/linphone-app/src/components/conferenceInfo/ConferenceInfoMapModel.cpp b/linphone-app/src/components/conferenceInfo/ConferenceInfoMapModel.cpp index 189fbb0f6..929cc6037 100644 --- a/linphone-app/src/components/conferenceInfo/ConferenceInfoMapModel.cpp +++ b/linphone-app/src/components/conferenceInfo/ConferenceInfoMapModel.cpp @@ -51,15 +51,13 @@ ConferenceInfoMapModel::ConferenceInfoMapModel (QObject *parent) : ProxyAbstract }) != participants.end()); if(haveMe){ auto conferenceInfoModel = ConferenceInfoModel::create( conferenceInfo ); - QDate t = conferenceInfoModel->getDateTime().date(); - if( !mMappedList.contains(t)){ - //auto proxy = new SortFilterAbstractProxyModel(new ConferenceInfoListModel(), this); + QDate conferenceDateTimeSystem = conferenceInfoModel->getDateTimeSystem().date(); + if( !mMappedList.contains(conferenceDateTimeSystem)){ auto proxy = new ConferenceInfoProxyListModel(this); connect(this, &ConferenceInfoMapModel::filterTypeChanged, proxy, &ConferenceInfoProxyListModel::setFilterType); - mMappedList[t] = proxy; + mMappedList[conferenceDateTimeSystem] = proxy; } - //mMappedList[t] = new ConferenceInfoProxyModel(new ConferenceInfoListModel(), this); - mMappedList[t]->add(conferenceInfoModel); + mMappedList[conferenceDateTimeSystem]->add(conferenceInfoModel); } } } diff --git a/linphone-app/src/components/conferenceInfo/ConferenceInfoModel.cpp b/linphone-app/src/components/conferenceInfo/ConferenceInfoModel.cpp index bcb85f053..49fdd55ce 100644 --- a/linphone-app/src/components/conferenceInfo/ConferenceInfoModel.cpp +++ b/linphone-app/src/components/conferenceInfo/ConferenceInfoModel.cpp @@ -49,6 +49,7 @@ #include "components/core/CoreHandlers.hpp" #include "components/core/CoreManager.hpp" #include "components/notifier/Notifier.hpp" +#include "components/other/timeZone/TimeZoneModel.hpp" #include "components/settings/AccountSettingsModel.hpp" #include "components/settings/SettingsModel.hpp" #include "components/participant/ParticipantModel.hpp" @@ -79,8 +80,11 @@ QSharedPointer ConferenceInfoModel::create(std::shared_ptr< ConferenceInfoModel::ConferenceInfoModel (QObject * parent) : QObject(parent){ //App::getInstance()->getEngine()->setObjectOwnership(this, QQmlEngine::CppOwnership);// Avoid QML to destroy it when passing by Q_INVOKABLE + mTimeZone = QTimeZone::systemTimeZone(); mConferenceInfo = linphone::Factory::get()->createConferenceInfo(); - mConferenceInfo->setDateTime(QDateTime::currentMSecsSinceEpoch() / 1000 + 60); + QDateTime currentDateTime = QDateTime::currentDateTime(); + QDateTime utc = currentDateTime.addSecs( -mTimeZone.offsetFromUtc(currentDateTime)); + mConferenceInfo->setDateTime(utc.toMSecsSinceEpoch() / 1000); mConferenceInfo->setDuration(1200); mIsScheduled = true; auto accountAddress = CoreManager::getInstance()->getCore()->getDefaultAccount()->getContactAddress(); @@ -90,9 +94,8 @@ ConferenceInfoModel::ConferenceInfoModel (QObject * parent) : QObject(parent){ ConferenceInfoModel::ConferenceInfoModel (std::shared_ptr conferenceInfo, QObject * parent) : QObject(parent){ App::getInstance()->getEngine()->setObjectOwnership(this, QQmlEngine::CppOwnership);// Avoid QML to destroy it when passing by Q_INVOKABLE - + mTimeZone = QTimeZone::systemTimeZone(); mConferenceInfo = conferenceInfo; - //mIsScheduled = getDateTime() >= QDateTime::currentDateTime(); mIsScheduled = true; } @@ -107,16 +110,22 @@ std::shared_ptr ConferenceInfoModel::getConferenceInfo //------------------------------------------------------------------------------------------------ -QDateTime ConferenceInfoModel::getDateTime() const{ +QDateTime ConferenceInfoModel::getDateTimeUtc() const{ return QDateTime::fromMSecsSinceEpoch(mConferenceInfo->getDateTime() * 1000); } +QDateTime ConferenceInfoModel::getDateTimeSystem() const{ + QDateTime utc = getDateTimeUtc(); + QDateTime system = utc.addSecs(mTimeZone.offsetFromUtc(utc)); + return system; +} + int ConferenceInfoModel::getDuration() const{ return mConferenceInfo->getDuration(); } QDateTime ConferenceInfoModel::getEndDateTime() const{ - return getDateTime().addSecs(getDuration()*60); + return getDateTimeUtc().addSecs(getDuration()*60); } QString ConferenceInfoModel::getOrganizer() const{ @@ -140,7 +149,6 @@ QString ConferenceInfoModel::displayNamesToString()const{ txt << displayName; } } - //txt.removeFirst();// Remove me return txt.join(", "); } @@ -164,11 +172,17 @@ QVariantList ConferenceInfoModel::getParticipants() const{ return addresses; } -//------------------------------------------------------------------------------------------------ +TimeZoneModel* ConferenceInfoModel::getTimeZoneModel() const{ + TimeZoneModel * model = new TimeZoneModel(mTimeZone); + App::getInstance()->getEngine()->setObjectOwnership(model, QQmlEngine::JavaScriptOwnership); + return model; +} +//------------------------------------------------------------------------------------------------ +// Convert into UTC with TimeZone void ConferenceInfoModel::setDateTime(const QDateTime& dateTime){ - mConferenceInfo->setDateTime(dateTime.toMSecsSinceEpoch() / 1000); - qWarning() << "Set DateTime: " << mConferenceInfo->getDateTime() << " from " << dateTime.toMSecsSinceEpoch() / 1000; + QDateTime utc = dateTime.addSecs( -mTimeZone.offsetFromUtc(dateTime)); + mConferenceInfo->setDateTime(utc.toMSecsSinceEpoch() / 1000); emit dateTimeChanged(); } @@ -197,6 +211,13 @@ void ConferenceInfoModel::setParticipants(ParticipantListModel * participants){ mConferenceInfo->setParticipants(participants->getParticipants()); } +void ConferenceInfoModel::setTimeZoneModel(TimeZoneModel * model){ + if( mTimeZone != model->getTimeZone()){ + mTimeZone = model->getTimeZone(); + emit timeZoneModelChanged(); + } +} + void ConferenceInfoModel::setIsScheduled(const bool& on){ if( mIsScheduled != on){ mIsScheduled = on; @@ -244,13 +265,13 @@ void ConferenceInfoModel::createConference(const int& securityLevel, const int& //------------------------------------------------------------------------------------------------- void ConferenceInfoModel::onStateChanged(linphone::ConferenceSchedulerState state){ - qWarning() << "ConferenceInfoModel::onStateChanged: " << (int) state; + qDebug() << "ConferenceInfoModel::onStateChanged: " << (int) state; if( state == linphone::ConferenceSchedulerState::Ready) emit conferenceCreated(); else if( state == linphone::ConferenceSchedulerState::Error) emit conferenceCreationFailed(); } void ConferenceInfoModel::onInvitationsSent(const std::list> & failedInvitations) { - qWarning() << "ConferenceInfoModel::onInvitationsSent"; + qDebug() << "ConferenceInfoModel::onInvitationsSent"; emit invitationsSent(); } diff --git a/linphone-app/src/components/conferenceInfo/ConferenceInfoModel.hpp b/linphone-app/src/components/conferenceInfo/ConferenceInfoModel.hpp index d6d9c1d8f..8e8d15a52 100644 --- a/linphone-app/src/components/conferenceInfo/ConferenceInfoModel.hpp +++ b/linphone-app/src/components/conferenceInfo/ConferenceInfoModel.hpp @@ -25,16 +25,18 @@ #include #include #include +#include class ParticipantListModel; class ConferenceScheduler; +class TimeZoneModel; class ConferenceInfoModel : public QObject { Q_OBJECT public: - - Q_PROPERTY(QDateTime dateTime READ getDateTime WRITE setDateTime NOTIFY dateTimeChanged) + Q_PROPERTY(TimeZoneModel * timeZoneModel READ getTimeZoneModel WRITE setTimeZoneModel NOTIFY timeZoneModelChanged) + Q_PROPERTY(QDateTime dateTime READ getDateTimeSystem WRITE setDateTime NOTIFY dateTimeChanged) Q_PROPERTY(int duration READ getDuration WRITE setDuration NOTIFY durationChanged) Q_PROPERTY(QDateTime endDateTime READ getEndDateTime NOTIFY dateTimeChanged) Q_PROPERTY(QString organizer READ getOrganizer WRITE setOrganizer NOTIFY organizerChanged) @@ -54,7 +56,8 @@ public: //------------------------------- - QDateTime getDateTime() const; + QDateTime getDateTimeUtc() const; + QDateTime getDateTimeSystem() const; int getDuration() const; QDateTime getEndDateTime() const; QString getOrganizer() const; @@ -64,6 +67,7 @@ public: QString getUri() const; bool isScheduled() const; Q_INVOKABLE QVariantList getParticipants() const; + Q_INVOKABLE TimeZoneModel* getTimeZoneModel() const; void setDateTime(const QDateTime& dateTime); void setDuration(const int& duration); @@ -73,6 +77,7 @@ public: void setIsScheduled(const bool& on); Q_INVOKABLE void setParticipants(ParticipantListModel * participants); + Q_INVOKABLE void setTimeZoneModel(TimeZoneModel * model); // Tools Q_INVOKABLE void createConference(const int& securityLevel, const int& inviteMode); @@ -84,6 +89,7 @@ public: signals: + void timeZoneModelChanged(); void dateTimeChanged(); void durationChanged(); void organizerChanged(); @@ -100,6 +106,7 @@ signals: private: std::shared_ptr mConferenceInfo; QSharedPointer mConferenceScheduler= nullptr; + QTimeZone mTimeZone; bool mIsScheduled = true; }; diff --git a/linphone-app/src/components/other/timeZone/TimeZoneListModel.cpp b/linphone-app/src/components/other/timeZone/TimeZoneListModel.cpp index c5b5a97cc..a0721a110 100644 --- a/linphone-app/src/components/other/timeZone/TimeZoneListModel.cpp +++ b/linphone-app/src/components/other/timeZone/TimeZoneListModel.cpp @@ -72,12 +72,11 @@ QVariant TimeZoneListModel::data (const QModelIndex &index, int role) const { return QVariant(); } -int TimeZoneListModel::getDefaultIndex () const { - auto defaultTimezone = QTimeZone::systemTimeZone(); +int TimeZoneListModel::get (const QTimeZone& timeZone) const { const auto it = find_if( - mList.cbegin(), mList.cend(), [&defaultTimezone](QSharedPointer item) { - return item.objectCast()->getTimeZone() == defaultTimezone; + mList.cbegin(), mList.cend(), [&timeZone](QSharedPointer item) { + return item.objectCast()->getTimeZone() == timeZone; } ); return it != mList.cend() ? int(distance(mList.cbegin(), it)) : 0; -} \ No newline at end of file +} diff --git a/linphone-app/src/components/other/timeZone/TimeZoneListModel.hpp b/linphone-app/src/components/other/timeZone/TimeZoneListModel.hpp index 226f34b8a..3b93f74d8 100644 --- a/linphone-app/src/components/other/timeZone/TimeZoneListModel.hpp +++ b/linphone-app/src/components/other/timeZone/TimeZoneListModel.hpp @@ -33,7 +33,7 @@ public: TimeZoneListModel (QObject *parent = Q_NULLPTR); void initTimeZones(); - int getDefaultIndex () const; + int get(const QTimeZone& timeZone = QTimeZone::systemTimeZone())const; QHash roleNames () const override; QVariant data (const QModelIndex &index, int role = Qt::DisplayRole) const override; diff --git a/linphone-app/src/components/other/timeZone/TimeZoneProxyModel.cpp b/linphone-app/src/components/other/timeZone/TimeZoneProxyModel.cpp index 3baa2639f..0d837c0a9 100644 --- a/linphone-app/src/components/other/timeZone/TimeZoneProxyModel.cpp +++ b/linphone-app/src/components/other/timeZone/TimeZoneProxyModel.cpp @@ -26,18 +26,13 @@ // ----------------------------------------------------------------------------- -TimeZoneProxyModel::TimeZoneProxyModel (QObject *parent) : QSortFilterProxyModel(parent) { +TimeZoneProxyModel::TimeZoneProxyModel (QObject *parent) : SortFilterProxyModel(parent) { setSourceModel(new TimeZoneListModel(parent)); sort(0); } // ----------------------------------------------------------------------------- -bool TimeZoneProxyModel::filterAcceptsRow (int sourceRow, const QModelIndex &sourceParent) const { - const QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent); - return true; -} - bool TimeZoneProxyModel::lessThan (const QModelIndex &left, const QModelIndex &right) const { auto test = sourceModel()->data(left); const TimeZoneModel* a = sourceModel()->data(left).value(); @@ -45,18 +40,15 @@ bool TimeZoneProxyModel::lessThan (const QModelIndex &left, const QModelIndex &r auto timeA = a->getStandardTimeOffset(); auto timeB = b->getStandardTimeOffset(); -/* - const QVariantMap mapA = sourceModel()->data(left).value(); - const QVariantMap mapB = sourceModel()->data(right).value(); - const TimeZoneModel* a = mapA["timeZoneModel"].value(); - const TimeZoneModel* b = mapB["timeZoneModel"].value(); - auto timeA = a->getStandardTimeOffset(); - auto timeB = b->getStandardTimeOffset(); - */ - return timeA < timeB || (timeA == timeB && a->getCountryName() < b->getCountryName()); } -int TimeZoneProxyModel::getDefaultIndex() const{ - return mapFromSource(sourceModel()->index(qobject_cast(sourceModel())->getDefaultIndex(), 0)).row(); +int TimeZoneProxyModel::getIndex(TimeZoneModel * model) const{ + auto listModel = qobject_cast(sourceModel()); + int index = 0; + if(model) + index = listModel->get(model->getTimeZone()); + else + index = listModel->get(); + return mapFromSource(sourceModel()->index(index, 0)).row(); } diff --git a/linphone-app/src/components/other/timeZone/TimeZoneProxyModel.hpp b/linphone-app/src/components/other/timeZone/TimeZoneProxyModel.hpp index 0a645879b..b7d88839e 100644 --- a/linphone-app/src/components/other/timeZone/TimeZoneProxyModel.hpp +++ b/linphone-app/src/components/other/timeZone/TimeZoneProxyModel.hpp @@ -21,20 +21,21 @@ #ifndef TIME_ZONE_PROXY_MODEL_H_ #define TIME_ZONE_PROXY_MODEL_H_ -#include +#include "app/proxyModel/SortFilterProxyModel.hpp" // ============================================================================= -class TimeZoneProxyModel : public QSortFilterProxyModel { +class TimeZoneModel; + +class TimeZoneProxyModel : public SortFilterProxyModel { Q_OBJECT public: TimeZoneProxyModel (QObject *parent = Q_NULLPTR); - Q_PROPERTY(int defaultIndex READ getDefaultIndex CONSTANT) + Q_PROPERTY(int defaultIndex READ getIndex CONSTANT) - int getDefaultIndex() const; + Q_INVOKABLE int getIndex(TimeZoneModel * model = nullptr) const; protected: - bool filterAcceptsRow (int sourceRow, const QModelIndex &sourceParent) const override; bool lessThan (const QModelIndex &left, const QModelIndex &right) const override; }; diff --git a/linphone-app/ui/modules/Linphone/Chat/ChatCalendarMessage.qml b/linphone-app/ui/modules/Linphone/Chat/ChatCalendarMessage.qml index 296f6d6d4..822fab262 100644 --- a/linphone-app/ui/modules/Linphone/Chat/ChatCalendarMessage.qml +++ b/linphone-app/ui/modules/Linphone/Chat/ChatCalendarMessage.qml @@ -125,7 +125,7 @@ Loader{ RowLayout { id: participantsRow Layout.fillWidth: true - Layout.preferredHeight: ChatCalendarMessageStyle.lineHeight + Layout.preferredHeight: ChatCalendarMessageStyle.participants.iconSize Layout.leftMargin: 5 Layout.rightMargin: 15 @@ -152,6 +152,7 @@ Loader{ isCustom: true colorSet: mainItem.gotoButtonMode == 0 ? ChatCalendarMessageStyle.gotoButton : ChatCalendarMessageStyle.infoButton backgroundRadius: width/2 + toggled: mainItem.isExpanded onClicked: mainItem.expandToggle() } } @@ -159,11 +160,13 @@ Loader{ id: expandedDescription Layout.fillWidth: true Layout.fillHeight: true + Layout.topMargin: 5 visible: mainItem.isExpanded + spacing: 0 ScrollableListView{ id: expandedParticipantsList Layout.fillWidth: true - Layout.minimumHeight: Math.min( count * ChatCalendarMessageStyle.lineHeight, parent.height/2) + Layout.minimumHeight: Math.min( count * ChatCalendarMessageStyle.lineHeight, parent.height/(descriptionTitle.visible?3:2)) Layout.leftMargin: 10 spacing: 0 visible: mainItem.isExpanded @@ -191,6 +194,7 @@ Loader{ id: descriptionTitle Layout.fillWidth: true Layout.leftMargin: 10 + Layout.topMargin: 5 color: ChatCalendarMessageStyle.subject.color font.pointSize: ChatCalendarMessageStyle.subject.pointSize font.weight: Font.Bold @@ -203,6 +207,7 @@ Loader{ Layout.fillWidth: true Layout.fillHeight: true Layout.leftMargin: 10 + padding: 0 color: 'transparent' readOnly: true textColor: ChatCalendarMessageStyle.description.color @@ -216,6 +221,10 @@ Loader{ text: mainItem.conferenceInfoModel.description } + Item{ + Layout.fillHeight: true + Layout.fillWidth: true + } Text{ id: linkTitle Layout.fillWidth: true diff --git a/linphone-app/ui/modules/Linphone/Styles/Chat/ChatCalendarMessageStyle.qml b/linphone-app/ui/modules/Linphone/Styles/Chat/ChatCalendarMessageStyle.qml index edae3c1c9..ad2ec891e 100644 --- a/linphone-app/ui/modules/Linphone/Styles/Chat/ChatCalendarMessageStyle.qml +++ b/linphone-app/ui/modules/Linphone/Styles/Chat/ChatCalendarMessageStyle.qml @@ -72,9 +72,11 @@ QtObject { property color backgroundNormalColor : ColorsList.addImageColor(sectionName+'_'+name+'_b_n', icon, 's_n_b_bg').color property color backgroundHoveredColor : ColorsList.addImageColor(sectionName+'_'+name+'_b_h', icon, 's_h_b_bg').color property color backgroundPressedColor : ColorsList.addImageColor(sectionName+'_'+name+'_b_p', icon, 's_p_b_bg').color + property color backgroundUpdatingColor : ColorsList.addImageColor(sectionName+'_'+name+'_b_c', icon, 's_p_b_bg').color property color foregroundNormalColor : ColorsList.addImageColor(sectionName+'_'+name+'_f_n', icon, 's_n_b_fg').color property color foregroundHoveredColor : ColorsList.addImageColor(sectionName+'_'+name+'_f_h', icon, 's_h_b_fg').color property color foregroundPressedColor : ColorsList.addImageColor(sectionName+'_'+name+'_f_p', icon, 's_p_b_fg').color + property color foregroundUpdatingColor : ColorsList.addImageColor(sectionName+'_'+name+'_f_c', icon, 's_p_b_fg').color } property QtObject infoButton: QtObject{ property int iconSize: 35 @@ -83,9 +85,11 @@ QtObject { property color backgroundNormalColor : ColorsList.addImageColor(sectionName+'_'+name+'_b_n', icon, 'me_n_b_bg').color property color backgroundHoveredColor : ColorsList.addImageColor(sectionName+'_'+name+'_b_h', icon, 'me_h_b_bg').color property color backgroundPressedColor : ColorsList.addImageColor(sectionName+'_'+name+'_b_p', icon, 'me_p_b_bg').color + property color backgroundUpdatingColor : ColorsList.addImageColor(sectionName+'_'+name+'_b_c', icon, 'me_p_b_bg').color property color foregroundNormalColor : ColorsList.addImageColor(sectionName+'_'+name+'_f_n', icon, 'me_n_b_fg').color property color foregroundHoveredColor : ColorsList.addImageColor(sectionName+'_'+name+'_f_h', icon, 'me_h_b_fg').color property color foregroundPressedColor : ColorsList.addImageColor(sectionName+'_'+name+'_f_p', icon, 'me_p_b_fg').color + property color foregroundUpdatingColor : ColorsList.addImageColor(sectionName+'_'+name+'_f_c', icon, 'me_p_b_fg').color } property QtObject organizer: QtObject { diff --git a/linphone-app/ui/views/App/Dialog/NewConference.qml b/linphone-app/ui/views/App/Dialog/NewConference.qml index 5ba0ccbbc..1b6628ade 100644 --- a/linphone-app/ui/views/App/Dialog/NewConference.qml +++ b/linphone-app/ui/views/App/Dialog/NewConference.qml @@ -122,6 +122,7 @@ DialogPlus { if( scheduledSwitch.checked){ var startDateTime = Utils.buildDate(dateField.getDate(), timeField.getTime()) startDateTime.setSeconds(0) + conferenceInfoModel.timeZoneModel = timeZoneField.model.getAt(timeZoneField.currentIndex) conferenceInfoModel.dateTime = startDateTime conferenceInfoModel.duration = durationField.text } @@ -318,9 +319,10 @@ DialogPlus { text: conferenceManager.conferenceInfoModel ? conferenceManager.conferenceInfoModel.duration : '1200' } ComboBox{ + id: timeZoneField Layout.preferredWidth: parent.cellWidth; //color: NewConferenceStyle.fields.textColor; font.weight: NewConferenceStyle.fields.weight; font.pointSize: NewConferenceStyle.fields.pointSize - currentIndex: model.defaultIndex + currentIndex: conferenceManager.conferenceInfoModel ? model.getIndex(conferenceManager.conferenceInfoModel.timeZoneModel) : -1 model: TimeZoneProxyModel{} onActivated: console.log("activated : " +index) textRole: "displayText" diff --git a/linphone-app/ui/views/App/Main/Conferences.qml b/linphone-app/ui/views/App/Main/Conferences.qml index 9567d90e5..116241de6 100644 --- a/linphone-app/ui/views/App/Main/Conferences.qml +++ b/linphone-app/ui/views/App/Main/Conferences.qml @@ -164,9 +164,9 @@ Item{ id: calendarGrid property bool expanded : false //anchors.fill: parent cellWidth: width/2 - cellHeight: expanded ? 300 : 100 + cellHeight: expanded ? 450 : 100 model: $modelData - height: cellHeight * ( (count+1) /2) + height: cellHeight * Math.floor( (count+1) / 2) width: mainItem.width - 20 delegate:Rectangle { id: entry