Timezones and prepare conference view with them.

Fix ICS views (better filterring).
Factorization of isMe() to test lcoal address.
New ComboBox design with better scrolling (like phone numbers in creation page).
This commit is contained in:
Julien Wadel 2022-05-12 19:56:11 +02:00
parent 8c9e610107
commit a8339bebc3
29 changed files with 902 additions and 474 deletions

View file

@ -209,6 +209,9 @@ set(SOURCES
src/components/other/images/ImageListModel.cpp
src/components/other/images/ImageProxyModel.cpp
src/components/other/text-to-speech/TextToSpeech.cpp
src/components/other/timeZone/TimeZoneModel.cpp
src/components/other/timeZone/TimeZoneListModel.cpp
src/components/other/timeZone/TimeZoneProxyModel.cpp
src/components/other/units/Units.cpp
src/components/participant/ParticipantModel.cpp
src/components/participant/ParticipantListModel.cpp
@ -342,6 +345,9 @@ set(HEADERS
src/components/other/images/ImageProxyModel.hpp
src/components/other/desktop-tools/DesktopTools.hpp
src/components/other/text-to-speech/TextToSpeech.hpp
src/components/other/timeZone/TimeZoneModel.hpp
src/components/other/timeZone/TimeZoneListModel.hpp
src/components/other/timeZone/TimeZoneProxyModel.hpp
src/components/other/units/Units.hpp
src/components/participant/ParticipantModel.hpp
src/components/participant/ParticipantListModel.hpp

View file

@ -645,7 +645,7 @@ void App::registerTypes () {
registerType<SipAddressesProxyModel>("SipAddressesProxyModel");
registerType<SearchSipAddressesModel>("SearchSipAddressesModel");
registerType<SearchSipAddressesProxyModel>("SearchSipAddressesProxyModel");
registerType<TimeZoneProxyModel>("TimeZoneProxyModel");
registerType<ColorProxyModel>("ColorProxyModel");
registerType<ImageColorsProxyModel>("ImageColorsProxyModel");

View file

@ -101,6 +101,9 @@
#include "other/images/ImageListModel.hpp"
#include "other/images/ImageProxyModel.hpp"
#include "other/text-to-speech/TextToSpeech.hpp"
#include "other/timeZone/TimeZoneModel.hpp"
#include "other/timeZone/TimeZoneListModel.hpp"
#include "other/timeZone/TimeZoneProxyModel.hpp"
#include "other/units/Units.hpp"
#endif // COMPONENTS_H_

View file

@ -215,7 +215,7 @@ QString ChatMessageModel::getForwardInfo() const{
QString ChatMessageModel::getForwardInfoDisplayName() const{
QString forwardInfo = getForwardInfo();
auto forwardAddress = Utils::interpretUrl(forwardInfo);
if(!forwardAddress || CoreManager::getInstance()->getAccountSettingsModel()->getUsedSipAddress()->weakEqual(forwardAddress))
if(!forwardAddress || Utils::isMe(forwardAddress))
return "";// myself
else
return Utils::getDisplayName(forwardInfo);

View file

@ -435,7 +435,7 @@ bool ChatRoomModel::isMeAdmin() const{
}
bool ChatRoomModel::isCurrentAccount() const{
return mChatRoom->getLocalAddress()->weakEqual(CoreManager::getInstance()->getAccountSettingsModel()->getUsedSipAddress());
return Utils::isMe(mChatRoom->getLocalAddress());
}
bool ChatRoomModel::canHandleParticipants() const{

View file

@ -80,6 +80,9 @@ QSharedPointer<ConferenceInfoModel> 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
mConferenceInfo = linphone::Factory::get()->createConferenceInfo();
mConferenceInfo->setDateTime(QDateTime::currentMSecsSinceEpoch() / 1000 + 60);
mConferenceInfo->setDuration(1200);
mIsScheduled = true;
auto accountAddress = CoreManager::getInstance()->getCore()->getDefaultAccount()->getContactAddress();
accountAddress->clean();
mConferenceInfo->setOrganizer(accountAddress);
@ -89,6 +92,8 @@ ConferenceInfoModel::ConferenceInfoModel (std::shared_ptr<linphone::ConferenceIn
App::getInstance()->getEngine()->setObjectOwnership(this, QQmlEngine::CppOwnership);// Avoid QML to destroy it when passing by Q_INVOKABLE
mConferenceInfo = conferenceInfo;
//mIsScheduled = getDateTime() >= QDateTime::currentDateTime();
mIsScheduled = true;
}
ConferenceInfoModel::~ConferenceInfoModel () {
@ -140,7 +145,8 @@ QString ConferenceInfoModel::displayNamesToString()const{
}
QString ConferenceInfoModel::getUri() const{
return QString::fromStdString(mConferenceInfo->getUri()->asString());
auto address = mConferenceInfo->getUri();
return address->isValid() && !address->getDomain().empty() ? QString::fromStdString(address->asString()) : "";
}
bool ConferenceInfoModel::isScheduled() const{

View file

@ -26,6 +26,8 @@
#include "ConferenceInfoListModel.hpp"
#include "ConferenceInfoMapModel.hpp"
#include "utils/Utils.hpp"
// =============================================================================
@ -48,8 +50,11 @@ bool ConferenceInfoProxyListModel::filterAcceptsRow (int sourceRow, const QModel
if( mFilterType == 0){
return ics->getEndDateTime() < currentDateTime;
}else if( mFilterType == 1){
return ics->getDateTime() >= currentDateTime;
}
return ics->getEndDateTime() >= currentDateTime;
}else if( mFilterType == 2){
return !Utils::isMe(ics->getOrganizer());
}else
return mFilterType == -1;
}
}
return true;

View file

@ -151,7 +151,7 @@ void ContentListModel::updateContents(ChatMessageModel * messageModel){
while( c < mList.size() && mList.at(c).objectCast<ContentModel>()->getContent() != content)
++c;
if( c < mList.size()){// Found => swap position
mList.swap(count, c);
mList.swapItemsAt(count, c);
}else{// content is new
mList.insert(count, QSharedPointer<ContentModel>::create(content, messageModel));
}

View file

@ -220,7 +220,7 @@ void CoreHandlers::onMessageReceived (
// 2. Notify with Notification popup.
const App *app = App::getInstance();
if (coreManager->getSettingsModel()->getChatNotificationsEnabled() && (!app->hasFocus() || !chatRoom->getLocalAddress()->weakEqual(coreManager->getAccountSettingsModel()->getUsedSipAddress())))
if (coreManager->getSettingsModel()->getChatNotificationsEnabled() && (!app->hasFocus() || !Utils::isMe(chatRoom->getLocalAddress())))
app->getNotifier()->notifyReceivedMessage(message);
// 3. Notify with sound.

View file

@ -39,7 +39,6 @@ LdapListModel::LdapListModel (QObject *parent) : ProxyListModel(parent) {
// -----------------------------------------------------------------------------
void LdapListModel::reset(){
resetInternalData();
initLdap();
}
@ -49,6 +48,7 @@ void LdapListModel::reset(){
void LdapListModel::initLdap () {
CoreManager *coreManager = CoreManager::getInstance();
auto ldapList = coreManager->getCore()->getLdapList();
resetData();
for(auto ldap : ldapList){
ProxyListModel::add(QSharedPointer<LdapModel>::create(ldap));
}

View file

@ -0,0 +1,83 @@
/*
* Copyright (c) 2022 Belledonne Communications SARL.
*
* This file is part of linphone-desktop
* (see https://www.linphone.org).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "TimeZoneListModel.hpp"
#include <QTimeZone>
// =============================================================================
using namespace std;
TimeZoneListModel::TimeZoneListModel (QObject *parent) : ProxyListModel(parent) {
initTimeZones();
}
// -----------------------------------------------------------------------------
void TimeZoneListModel::initTimeZones () {
resetData();
for(auto id : QTimeZone::availableTimeZoneIds()){
auto model = QSharedPointer<TimeZoneModel>::create(QTimeZone(id));
if(model->getCountryName().toUpper() != "DEFAULT")
ProxyListModel::add(model);
}
}
QHash<int, QByteArray> TimeZoneListModel::roleNames () const {
QHash<int, QByteArray> roles;
roles[Qt::DisplayRole] = "$modelData";
roles[Qt::DisplayRole+1] = "displayText";
return roles;
}
QVariant TimeZoneListModel::data (const QModelIndex &index, int role) const {
int row = index.row();
if (!index.isValid() || row < 0 || row >= mList.count())
return QVariant();
auto timeZoneModel = getAt<TimeZoneModel>(row);
if (role == Qt::DisplayRole) {
return QVariant::fromValue(timeZoneModel.get());
}else{
int offset = timeZoneModel->getStandardTimeOffset()/3600;
int absOffset = std::abs(offset);
return QStringLiteral("%1 (UTC%2%3%4) %5")
.arg(timeZoneModel->getCountryName())
.arg(offset >=0 ? "+" : "-")
.arg(absOffset <10 ? "0" : "")
.arg(absOffset)
.arg(timeZoneModel->getTimeZone().comment());
}
return QVariant();
}
int TimeZoneListModel::getDefaultIndex () const {
auto defaultTimezone = QTimeZone::systemTimeZone();
const auto it = find_if(
mList.cbegin(), mList.cend(), [&defaultTimezone](QSharedPointer<QObject> item) {
return item.objectCast<TimeZoneModel>()->getTimeZone() == defaultTimezone;
}
);
return it != mList.cend() ? int(distance(mList.cbegin(), it)) : 0;
}

View file

@ -0,0 +1,43 @@
/*
* Copyright (c) 2021 Belledonne Communications SARL.
*
* This file is part of linphone-desktop
* (see https://www.linphone.org).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef TIME_ZONE_LIST_MODEL_H_
#define TIME_ZONE_LIST_MODEL_H_
#include "TimeZoneModel.hpp"
#include "app/proxyModel/ProxyListModel.hpp"
// =============================================================================
class TimeZoneListModel : public ProxyListModel {
Q_OBJECT
public:
TimeZoneListModel (QObject *parent = Q_NULLPTR);
void initTimeZones();
int getDefaultIndex () const;
QHash<int, QByteArray> roleNames () const override;
QVariant data (const QModelIndex &index, int role = Qt::DisplayRole) const override;
};
#endif

View file

@ -0,0 +1,56 @@
/*
* Copyright (c) 2022 Belledonne Communications SARL.
*
* This file is part of linphone-desktop
* (see https://www.linphone.org).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "TimeZoneModel.hpp"
#include "app/App.hpp"
#include "utils/Utils.hpp"
#include <QQmlApplicationEngine>
// =============================================================================
TimeZoneModel::TimeZoneModel (const QTimeZone& timeZone, QObject *parent ) : QObject(parent){
App::getInstance()->getEngine()->setObjectOwnership(this, QQmlEngine::CppOwnership);// Avoid QML to destroy it when passing by Q_INVOKABLE
mTimeZone = timeZone;
}
TimeZoneModel::~TimeZoneModel(){
}
QTimeZone TimeZoneModel::getTimeZone()const{
return mTimeZone;
}
int TimeZoneModel::getOffsetFromUtc() const{
return mTimeZone.offsetFromUtc(QDateTime::currentDateTime());
}
int TimeZoneModel::getStandardTimeOffset() const{
return mTimeZone.standardTimeOffset(QDateTime::currentDateTime());
}
QString TimeZoneModel::getCountryName() const{
return Utils::getCountryName(mTimeZone.country());
}
QString TimeZoneModel::getDisplayName() const{
return mTimeZone.displayName(QTimeZone::TimeType::GenericTime);
}

View file

@ -0,0 +1,54 @@
/*
* Copyright (c) 2022 Belledonne Communications SARL.
*
* This file is part of linphone-desktop
* (see https://www.linphone.org).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef TIME_ZONE_MODEL_H_
#define TIME_ZONE_MODEL_H_
#include <QObject>
#include <QTimeZone>
#include <linphone++/linphone.hh>
// =============================================================================
class TimeZoneModel : public QObject {
Q_OBJECT
Q_PROPERTY(QTimeZone timezone MEMBER mTimeZone CONSTANT)
Q_PROPERTY(int offsetFromUtc READ getOffsetFromUtc CONSTANT)
Q_PROPERTY(int standardTimeOffset READ getStandardTimeOffset CONSTANT)
Q_PROPERTY(QString countryName READ getCountryName CONSTANT)
Q_PROPERTY(QString displayName READ getDisplayName CONSTANT)
public:
TimeZoneModel (const QTimeZone& timeZone, QObject *parent = nullptr);
virtual ~TimeZoneModel();
QTimeZone getTimeZone()const;
int getOffsetFromUtc() const;
int getStandardTimeOffset() const;
QString getCountryName() const;
QString getDisplayName() const;
private:
QTimeZone mTimeZone;
};
Q_DECLARE_METATYPE(TimeZoneModel*);
#endif

View file

@ -0,0 +1,62 @@
/*
* Copyright (c) 2022 Belledonne Communications SARL.
*
* This file is part of linphone-desktop
* (see https://www.linphone.org).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "components/core/CoreManager.hpp"
#include "TimeZoneModel.hpp"
#include "TimeZoneListModel.hpp"
#include "TimeZoneProxyModel.hpp"
// -----------------------------------------------------------------------------
TimeZoneProxyModel::TimeZoneProxyModel (QObject *parent) : QSortFilterProxyModel(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<TimeZoneModel*>();
const TimeZoneModel* b = sourceModel()->data(right).value<TimeZoneModel*>();
auto timeA = a->getStandardTimeOffset();
auto timeB = b->getStandardTimeOffset();
/*
const QVariantMap mapA = sourceModel()->data(left).value<QVariantMap>();
const QVariantMap mapB = sourceModel()->data(right).value<QVariantMap>();
const TimeZoneModel* a = mapA["timeZoneModel"].value<TimeZoneModel*>();
const TimeZoneModel* b = mapB["timeZoneModel"].value<TimeZoneModel*>();
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<TimeZoneListModel*>(sourceModel())->getDefaultIndex(), 0)).row();
}

View file

@ -0,0 +1,41 @@
/*
* Copyright (c) 2022 Belledonne Communications SARL.
*
* This file is part of linphone-desktop
* (see https://www.linphone.org).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef TIME_ZONE_PROXY_MODEL_H_
#define TIME_ZONE_PROXY_MODEL_H_
#include <QSortFilterProxyModel>
// =============================================================================
class TimeZoneProxyModel : public QSortFilterProxyModel {
Q_OBJECT
public:
TimeZoneProxyModel (QObject *parent = Q_NULLPTR);
Q_PROPERTY(int defaultIndex READ getDefaultIndex CONSTANT)
int getDefaultIndex() const;
protected:
bool filterAcceptsRow (int sourceRow, const QModelIndex &sourceParent) const override;
bool lessThan (const QModelIndex &left, const QModelIndex &right) const override;
};
#endif

View file

@ -65,8 +65,7 @@ bool ParticipantModel::getInviting() const{
}
bool ParticipantModel::isMe() const{
QString sipAddress = getSipAddress();
return !sipAddress.isEmpty() ? CoreManager::getInstance()->getAccountSettingsModel()->getUsedSipAddress()->weakEqual(Utils::interpretUrl(sipAddress)) : false;
return Utils::isMe(getSipAddress());
}
QString ParticipantModel::getSipAddress() const{

View file

@ -26,229 +26,229 @@
using namespace std;
const QList<QPair<QLocale::Country, QString>> TelephoneNumbersModel::mCountryCodes = {
{ QLocale::Afghanistan, "93" },
{ QLocale::Albania, "355" },
{ QLocale::Algeria, "213" },
{ QLocale::AmericanSamoa, "1" },
{ QLocale::Andorra, "376" },
{ QLocale::Angola, "244" },
{ QLocale::Anguilla, "1" },
{ QLocale::AntiguaAndBarbuda, "1" },
{ QLocale::Argentina, "54" },
{ QLocale::Armenia, "374" },
{ QLocale::Aruba, "297" },
{ QLocale::Australia, "61" },
{ QLocale::Austria, "43" },
{ QLocale::Azerbaijan, "994" },
{ QLocale::Bahamas, "1" },
{ QLocale::Bahrain, "973" },
{ QLocale::Bangladesh, "880" },
{ QLocale::Barbados, "1" },
{ QLocale::Belarus, "375" },
{ QLocale::Belgium, "32" },
{ QLocale::Belize, "501" },
{ QLocale::Benin, "229" },
{ QLocale::Bermuda, "1" },
{ QLocale::Bhutan, "975" },
{ QLocale::Bolivia, "591" },
{ QLocale::BosniaAndHerzegowina, "387" },
{ QLocale::Botswana, "267" },
{ QLocale::Brazil, "55" },
{ QLocale::Brunei, "673" },
{ QLocale::Bulgaria, "359" },
{ QLocale::BurkinaFaso, "226" },
{ QLocale::Burundi, "257" },
{ QLocale::Cambodia, "855" },
{ QLocale::Cameroon, "237" },
{ QLocale::Canada, "1" },
{ QLocale::CapeVerde, "238" },
{ QLocale::CaymanIslands, "1" },
{ QLocale::CentralAfricanRepublic, "236" },
{ QLocale::Chad, "235" },
{ QLocale::Chile, "56" },
{ QLocale::China, "86" },
{ QLocale::Colombia, "57" },
{ QLocale::Comoros, "269" },
{ QLocale::PeoplesRepublicOfCongo, "242" },
{ QLocale::DemocraticRepublicOfCongo, "243" },
{ QLocale::CookIslands, "682" },
{ QLocale::CostaRica, "506" },
{ QLocale::IvoryCoast, "225" },
{ QLocale::Croatia, "385" },
{ QLocale::Cuba, "53" },
{ QLocale::Cyprus, "357" },
{ QLocale::CzechRepublic, "420" },
{ QLocale::Denmark, "45" },
{ QLocale::Djibouti, "253" },
{ QLocale::Dominica, "1" },
{ QLocale::DominicanRepublic, "1" },
{ QLocale::Ecuador, "593" },
{ QLocale::Egypt, "20" },
{ QLocale::ElSalvador, "503" },
{ QLocale::EquatorialGuinea, "240" },
{ QLocale::Eritrea, "291" },
{ QLocale::Estonia, "372" },
{ QLocale::Ethiopia, "251" },
{ QLocale::FalklandIslands, "500" },
{ QLocale::FaroeIslands, "298" },
{ QLocale::Fiji, "679" },
{ QLocale::Finland, "358" },
{ QLocale::France, "33" },
{ QLocale::FrenchGuiana, "594" },
{ QLocale::FrenchPolynesia, "689" },
{ QLocale::Gabon, "241" },
{ QLocale::Gambia, "220" },
{ QLocale::Georgia, "995" },
{ QLocale::Germany, "49" },
{ QLocale::Ghana, "233" },
{ QLocale::Gibraltar, "350" },
{ QLocale::Greece, "30" },
{ QLocale::Greenland, "299" },
{ QLocale::Grenada, "1" },
{ QLocale::Guadeloupe, "590" },
{ QLocale::Guam, "1" },
{ QLocale::Guatemala, "502" },
{ QLocale::Guinea, "224" },
{ QLocale::GuineaBissau, "245" },
{ QLocale::Guyana, "592" },
{ QLocale::Haiti, "509" },
{ QLocale::Honduras, "504" },
{ QLocale::HongKong, "852" },
{ QLocale::Hungary, "36" },
{ QLocale::Iceland, "354" },
{ QLocale::India, "91" },
{ QLocale::Indonesia, "62" },
{ QLocale::Iran, "98" },
{ QLocale::Iraq, "964" },
{ QLocale::Ireland, "353" },
{ QLocale::Israel, "972" },
{ QLocale::Italy, "39" },
{ QLocale::Jamaica, "1" },
{ QLocale::Japan, "81" },
{ QLocale::Jordan, "962" },
{ QLocale::Kazakhstan, "7" },
{ QLocale::Kenya, "254" },
{ QLocale::Kiribati, "686" },
{ QLocale::DemocraticRepublicOfKorea, "850" },
{ QLocale::RepublicOfKorea, "82" },
{ QLocale::Kuwait, "965" },
{ QLocale::Kyrgyzstan, "996" },
{ QLocale::Laos, "856" },
{ QLocale::Latvia, "371" },
{ QLocale::Lebanon, "961" },
{ QLocale::Lesotho, "266" },
{ QLocale::Liberia, "231" },
{ QLocale::Libya, "218" },
{ QLocale::Liechtenstein, "423" },
{ QLocale::Lithuania, "370" },
{ QLocale::Luxembourg, "352" },
{ QLocale::Macau, "853" },
{ QLocale::Macedonia, "389" },
{ QLocale::Madagascar, "261" },
{ QLocale::Malawi, "265" },
{ QLocale::Malaysia, "60" },
{ QLocale::Maldives, "960" },
{ QLocale::Mali, "223" },
{ QLocale::Malta, "356" },
{ QLocale::MarshallIslands, "692" },
{ QLocale::Martinique, "596" },
{ QLocale::Mauritania, "222" },
{ QLocale::Mauritius, "230" },
{ QLocale::Mayotte, "262" },
{ QLocale::Mexico, "52" },
{ QLocale::Micronesia, "691" },
{ QLocale::Moldova, "373" },
{ QLocale::Monaco, "377" },
{ QLocale::Mongolia, "976" },
{ QLocale::Montenegro, "382" },
{ QLocale::Montserrat, "664" },
{ QLocale::Morocco, "212" },
{ QLocale::Mozambique, "258" },
{ QLocale::Myanmar, "95" },
{ QLocale::Namibia, "264" },
{ QLocale::NauruCountry, "674" },
{ QLocale::Nepal, "43" },
{ QLocale::Netherlands, "31" },
{ QLocale::NewCaledonia, "687" },
{ QLocale::NewZealand, "64" },
{ QLocale::Nicaragua, "505" },
{ QLocale::Niger, "227" },
{ QLocale::Nigeria, "234" },
{ QLocale::Niue, "683" },
{ QLocale::NorfolkIsland, "672" },
{ QLocale::NorthernMarianaIslands, "1" },
{ QLocale::Norway, "47" },
{ QLocale::Oman, "968" },
{ QLocale::Pakistan, "92" },
{ QLocale::Palau, "680" },
{ QLocale::PalestinianTerritories, "970" },
{ QLocale::Panama, "507" },
{ QLocale::PapuaNewGuinea, "675" },
{ QLocale::Paraguay, "595" },
{ QLocale::Peru, "51" },
{ QLocale::Philippines, "63" },
{ QLocale::Poland, "48" },
{ QLocale::Portugal, "351" },
{ QLocale::PuertoRico, "1" },
{ QLocale::Qatar, "974" },
{ QLocale::Reunion, "262" },
{ QLocale::Romania, "40" },
{ QLocale::RussianFederation, "7" },
{ QLocale::Rwanda, "250" },
{ QLocale::SaintHelena, "290" },
{ QLocale::SaintKittsAndNevis, "1" },
{ QLocale::SaintLucia, "1" },
{ QLocale::SaintPierreAndMiquelon, "508" },
{ QLocale::SaintVincentAndTheGrenadines, "1" },
{ QLocale::Samoa, "685" },
{ QLocale::SanMarino, "378" },
{ QLocale::SaoTomeAndPrincipe, "239" },
{ QLocale::SaudiArabia, "966" },
{ QLocale::Senegal, "221" },
{ QLocale::Serbia, "381" },
{ QLocale::Seychelles, "248" },
{ QLocale::SierraLeone, "232" },
{ QLocale::Singapore, "65" },
{ QLocale::Slovakia, "421" },
{ QLocale::Slovenia, "386" },
{ QLocale::SolomonIslands, "677" },
{ QLocale::Somalia, "252" },
{ QLocale::SouthAfrica, "27" },
{ QLocale::Spain, "34" },
{ QLocale::SriLanka, "94" },
{ QLocale::Sudan, "249" },
{ QLocale::Suriname, "597" },
{ QLocale::Swaziland, "268" },
{ QLocale::Sweden, "46" },
{ QLocale::Switzerland, "41" },
{ QLocale::Syria, "963" },
{ QLocale::Taiwan, "886" },
{ QLocale::Tajikistan, "992" },
{ QLocale::Tanzania, "255" },
{ QLocale::Thailand, "66" },
{ QLocale::Togo, "228" },
{ QLocale::Tokelau, "690" },
{ QLocale::Tonga, "676" },
{ QLocale::TrinidadAndTobago, "1" },
{ QLocale::Tunisia, "216" },
{ QLocale::Turkey, "90" },
{ QLocale::Turkmenistan, "993" },
{ QLocale::TurksAndCaicosIslands, "1" },
{ QLocale::Tuvalu, "688" },
{ QLocale::Uganda, "256" },
{ QLocale::Ukraine, "380" },
{ QLocale::UnitedArabEmirates, "971" },
{ QLocale::UnitedKingdom, "44" },
{ QLocale::UnitedStates, "1" },
{ QLocale::Uruguay, "598" },
{ QLocale::Uzbekistan, "998" },
{ QLocale::Vanuatu, "678" },
{ QLocale::Venezuela, "58" },
{ QLocale::Vietnam, "84" },
{ QLocale::WallisAndFutunaIslands, "681" },
{ QLocale::Yemen, "967" },
{ QLocale::Zambia, "260" },
{ QLocale::Zimbabwe, "263" }
{ QLocale::Afghanistan, "93" },
{ QLocale::Albania, "355" },
{ QLocale::Algeria, "213" },
{ QLocale::AmericanSamoa, "1" },
{ QLocale::Andorra, "376" },
{ QLocale::Angola, "244" },
{ QLocale::Anguilla, "1" },
{ QLocale::AntiguaAndBarbuda, "1" },
{ QLocale::Argentina, "54" },
{ QLocale::Armenia, "374" },
{ QLocale::Aruba, "297" },
{ QLocale::Australia, "61" },
{ QLocale::Austria, "43" },
{ QLocale::Azerbaijan, "994" },
{ QLocale::Bahamas, "1" },
{ QLocale::Bahrain, "973" },
{ QLocale::Bangladesh, "880" },
{ QLocale::Barbados, "1" },
{ QLocale::Belarus, "375" },
{ QLocale::Belgium, "32" },
{ QLocale::Belize, "501" },
{ QLocale::Benin, "229" },
{ QLocale::Bermuda, "1" },
{ QLocale::Bhutan, "975" },
{ QLocale::Bolivia, "591" },
{ QLocale::BosniaAndHerzegowina, "387" },
{ QLocale::Botswana, "267" },
{ QLocale::Brazil, "55" },
{ QLocale::Brunei, "673" },
{ QLocale::Bulgaria, "359" },
{ QLocale::BurkinaFaso, "226" },
{ QLocale::Burundi, "257" },
{ QLocale::Cambodia, "855" },
{ QLocale::Cameroon, "237" },
{ QLocale::Canada, "1" },
{ QLocale::CapeVerde, "238" },
{ QLocale::CaymanIslands, "1" },
{ QLocale::CentralAfricanRepublic, "236" },
{ QLocale::Chad, "235" },
{ QLocale::Chile, "56" },
{ QLocale::China, "86" },
{ QLocale::Colombia, "57" },
{ QLocale::Comoros, "269" },
{ QLocale::PeoplesRepublicOfCongo, "242" },
{ QLocale::DemocraticRepublicOfCongo, "243" },
{ QLocale::CookIslands, "682" },
{ QLocale::CostaRica, "506" },
{ QLocale::IvoryCoast, "225" },
{ QLocale::Croatia, "385" },
{ QLocale::Cuba, "53" },
{ QLocale::Cyprus, "357" },
{ QLocale::CzechRepublic, "420" },
{ QLocale::Denmark, "45" },
{ QLocale::Djibouti, "253" },
{ QLocale::Dominica, "1" },
{ QLocale::DominicanRepublic, "1" },
{ QLocale::Ecuador, "593" },
{ QLocale::Egypt, "20" },
{ QLocale::ElSalvador, "503" },
{ QLocale::EquatorialGuinea, "240" },
{ QLocale::Eritrea, "291" },
{ QLocale::Estonia, "372" },
{ QLocale::Ethiopia, "251" },
{ QLocale::FalklandIslands, "500" },
{ QLocale::FaroeIslands, "298" },
{ QLocale::Fiji, "679" },
{ QLocale::Finland, "358" },
{ QLocale::France, "33" },
{ QLocale::FrenchGuiana, "594" },
{ QLocale::FrenchPolynesia, "689" },
{ QLocale::Gabon, "241" },
{ QLocale::Gambia, "220" },
{ QLocale::Georgia, "995" },
{ QLocale::Germany, "49" },
{ QLocale::Ghana, "233" },
{ QLocale::Gibraltar, "350" },
{ QLocale::Greece, "30" },
{ QLocale::Greenland, "299" },
{ QLocale::Grenada, "1" },
{ QLocale::Guadeloupe, "590" },
{ QLocale::Guam, "1" },
{ QLocale::Guatemala, "502" },
{ QLocale::Guinea, "224" },
{ QLocale::GuineaBissau, "245" },
{ QLocale::Guyana, "592" },
{ QLocale::Haiti, "509" },
{ QLocale::Honduras, "504" },
{ QLocale::HongKong, "852" },
{ QLocale::Hungary, "36" },
{ QLocale::Iceland, "354" },
{ QLocale::India, "91" },
{ QLocale::Indonesia, "62" },
{ QLocale::Iran, "98" },
{ QLocale::Iraq, "964" },
{ QLocale::Ireland, "353" },
{ QLocale::Israel, "972" },
{ QLocale::Italy, "39" },
{ QLocale::Jamaica, "1" },
{ QLocale::Japan, "81" },
{ QLocale::Jordan, "962" },
{ QLocale::Kazakhstan, "7" },
{ QLocale::Kenya, "254" },
{ QLocale::Kiribati, "686" },
{ QLocale::DemocraticRepublicOfKorea, "850" },
{ QLocale::RepublicOfKorea, "82" },
{ QLocale::Kuwait, "965" },
{ QLocale::Kyrgyzstan, "996" },
{ QLocale::Laos, "856" },
{ QLocale::Latvia, "371" },
{ QLocale::Lebanon, "961" },
{ QLocale::Lesotho, "266" },
{ QLocale::Liberia, "231" },
{ QLocale::Libya, "218" },
{ QLocale::Liechtenstein, "423" },
{ QLocale::Lithuania, "370" },
{ QLocale::Luxembourg, "352" },
{ QLocale::Macau, "853" },
{ QLocale::Macedonia, "389" },
{ QLocale::Madagascar, "261" },
{ QLocale::Malawi, "265" },
{ QLocale::Malaysia, "60" },
{ QLocale::Maldives, "960" },
{ QLocale::Mali, "223" },
{ QLocale::Malta, "356" },
{ QLocale::MarshallIslands, "692" },
{ QLocale::Martinique, "596" },
{ QLocale::Mauritania, "222" },
{ QLocale::Mauritius, "230" },
{ QLocale::Mayotte, "262" },
{ QLocale::Mexico, "52" },
{ QLocale::Micronesia, "691" },
{ QLocale::Moldova, "373" },
{ QLocale::Monaco, "377" },
{ QLocale::Mongolia, "976" },
{ QLocale::Montenegro, "382" },
{ QLocale::Montserrat, "664" },
{ QLocale::Morocco, "212" },
{ QLocale::Mozambique, "258" },
{ QLocale::Myanmar, "95" },
{ QLocale::Namibia, "264" },
{ QLocale::NauruCountry, "674" },
{ QLocale::Nepal, "43" },
{ QLocale::Netherlands, "31" },
{ QLocale::NewCaledonia, "687" },
{ QLocale::NewZealand, "64" },
{ QLocale::Nicaragua, "505" },
{ QLocale::Niger, "227" },
{ QLocale::Nigeria, "234" },
{ QLocale::Niue, "683" },
{ QLocale::NorfolkIsland, "672" },
{ QLocale::NorthernMarianaIslands, "1" },
{ QLocale::Norway, "47" },
{ QLocale::Oman, "968" },
{ QLocale::Pakistan, "92" },
{ QLocale::Palau, "680" },
{ QLocale::PalestinianTerritories, "970" },
{ QLocale::Panama, "507" },
{ QLocale::PapuaNewGuinea, "675" },
{ QLocale::Paraguay, "595" },
{ QLocale::Peru, "51" },
{ QLocale::Philippines, "63" },
{ QLocale::Poland, "48" },
{ QLocale::Portugal, "351" },
{ QLocale::PuertoRico, "1" },
{ QLocale::Qatar, "974" },
{ QLocale::Reunion, "262" },
{ QLocale::Romania, "40" },
{ QLocale::RussianFederation, "7" },
{ QLocale::Rwanda, "250" },
{ QLocale::SaintHelena, "290" },
{ QLocale::SaintKittsAndNevis, "1" },
{ QLocale::SaintLucia, "1" },
{ QLocale::SaintPierreAndMiquelon, "508" },
{ QLocale::SaintVincentAndTheGrenadines, "1" },
{ QLocale::Samoa, "685" },
{ QLocale::SanMarino, "378" },
{ QLocale::SaoTomeAndPrincipe, "239" },
{ QLocale::SaudiArabia, "966" },
{ QLocale::Senegal, "221" },
{ QLocale::Serbia, "381" },
{ QLocale::Seychelles, "248" },
{ QLocale::SierraLeone, "232" },
{ QLocale::Singapore, "65" },
{ QLocale::Slovakia, "421" },
{ QLocale::Slovenia, "386" },
{ QLocale::SolomonIslands, "677" },
{ QLocale::Somalia, "252" },
{ QLocale::SouthAfrica, "27" },
{ QLocale::Spain, "34" },
{ QLocale::SriLanka, "94" },
{ QLocale::Sudan, "249" },
{ QLocale::Suriname, "597" },
{ QLocale::Swaziland, "268" },
{ QLocale::Sweden, "46" },
{ QLocale::Switzerland, "41" },
{ QLocale::Syria, "963" },
{ QLocale::Taiwan, "886" },
{ QLocale::Tajikistan, "992" },
{ QLocale::Tanzania, "255" },
{ QLocale::Thailand, "66" },
{ QLocale::Togo, "228" },
{ QLocale::Tokelau, "690" },
{ QLocale::Tonga, "676" },
{ QLocale::TrinidadAndTobago, "1" },
{ QLocale::Tunisia, "216" },
{ QLocale::Turkey, "90" },
{ QLocale::Turkmenistan, "993" },
{ QLocale::TurksAndCaicosIslands, "1" },
{ QLocale::Tuvalu, "688" },
{ QLocale::Uganda, "256" },
{ QLocale::Ukraine, "380" },
{ QLocale::UnitedArabEmirates, "971" },
{ QLocale::UnitedKingdom, "44" },
{ QLocale::UnitedStates, "1" },
{ QLocale::Uruguay, "598" },
{ QLocale::Uzbekistan, "998" },
{ QLocale::Vanuatu, "678" },
{ QLocale::Venezuela, "58" },
{ QLocale::Vietnam, "84" },
{ QLocale::WallisAndFutunaIslands, "681" },
{ QLocale::Yemen, "967" },
{ QLocale::Zambia, "260" },
{ QLocale::Zimbabwe, "263" }
};
// -----------------------------------------------------------------------------
@ -256,41 +256,38 @@ const QList<QPair<QLocale::Country, QString>> TelephoneNumbersModel::mCountryCod
TelephoneNumbersModel::TelephoneNumbersModel (QObject *parent) : QAbstractListModel(parent) {}
int TelephoneNumbersModel::rowCount (const QModelIndex &) const {
return mCountryCodes.count();
return mCountryCodes.count();
}
QHash<int, QByteArray> TelephoneNumbersModel::roleNames () const {
QHash<int, QByteArray> roles;
roles[Qt::DisplayRole] = "$phoneNumber";
return roles;
QHash<int, QByteArray> roles;
roles[Qt::DisplayRole] = "countryCode";
roles[Qt::DisplayRole+1] = "countryName";
return roles;
}
QVariant TelephoneNumbersModel::data (const QModelIndex &index, int role) const {
int row = index.row();
if (!index.isValid() || row < 0 || row >= mCountryCodes.count())
return QVariant();
if (role == Qt::DisplayRole) {
const QPair<QLocale::Country, QString> &countryCode = mCountryCodes[row];
QVariantMap map;
map["countryCode"] = countryCode.second;
map["countryName"] = QStringLiteral("%1 (+%2)")
.arg(Utils::getCountryName(countryCode.first))
.arg(countryCode.second);
return map;
}
return QVariant();
int row = index.row();
if (!index.isValid() || row < 0 || row >= mCountryCodes.count())
return QVariant();
const QPair<QLocale::Country, QString> &countryCode = mCountryCodes[row];
if (role == Qt::DisplayRole) {
return countryCode.second;
}else if(role == Qt::DisplayRole+1)
return QStringLiteral("%1 (+%2)")
.arg(Utils::getCountryName(countryCode.first))
.arg(countryCode.second);
return QVariant();
}
int TelephoneNumbersModel::getDefaultIndex () const {
QLocale::Country country = QLocale().country();
const auto it = find_if(
mCountryCodes.cbegin(), mCountryCodes.cend(), [&country](const QPair<QLocale::Country, QString> &pair) {
return country == pair.first;
}
);
return it != mCountryCodes.cend() ? int(distance(mCountryCodes.cbegin(), it)) : 0;
QLocale::Country country = QLocale().country();
const auto it = find_if(
mCountryCodes.cbegin(), mCountryCodes.cend(), [&country](const QPair<QLocale::Country, QString> &pair) {
return country == pair.first;
}
);
return it != mCountryCodes.cend() ? int(distance(mCountryCodes.cbegin(), it)) : 0;
}

View file

@ -31,6 +31,7 @@
#include "components/contacts/ContactsListModel.hpp"
#include "components/contact/ContactModel.hpp"
#include "components/contact/VcardModel.hpp"
#include "components/settings/AccountSettingsModel.hpp"
#include "components/settings/SettingsModel.hpp"
#include "app/paths/Paths.hpp"
@ -517,4 +518,12 @@ QString Utils::computeUserAgent(const std::shared_ptr<linphone::Config>& config)
.arg(SettingsModel::getDeviceName(config))
.arg(QSysInfo::prettyProductName())
.arg(qVersion());
}
}
bool Utils::isMe(const QString& address){
return !address.isEmpty() ? CoreManager::getInstance()->getAccountSettingsModel()->getUsedSipAddress()->weakEqual(Utils::interpretUrl(address)) : false;
}
bool Utils::isMe(const std::shared_ptr<const linphone::Address>& address){
return address ? CoreManager::getInstance()->getAccountSettingsModel()->getUsedSipAddress()->weakEqual(address) : false;
}

View file

@ -59,6 +59,7 @@ public:
Q_INVOKABLE static QString toDateString(QDateTime date);
Q_INVOKABLE static QString getDisplayName(const QString& address);
Q_INVOKABLE static QString toString(const LinphoneEnums::TunnelMode& mode);
Q_INVOKABLE static bool isMe(const QString& address);
//----------------------------------------------------------------------------------
static inline QString coreStringToAppString (const std::string &str) {
@ -128,6 +129,9 @@ public:
static QString getDisplayName(const std::shared_ptr<const linphone::Address>& address); // Get the displayname from addres in this order : Friends, Contact, Display address, Username address
static std::shared_ptr<linphone::Config> getConfigIfExists (const QString& configPath);
static QString computeUserAgent(const std::shared_ptr<linphone::Config>& config);
static bool isMe(const std::shared_ptr<const linphone::Address>& address);
};
#endif // UTILS_H_

View file

@ -10,88 +10,126 @@ import 'ComboBox.js' as Logic
// =============================================================================
Controls.ComboBox {
id: comboBox
// ---------------------------------------------------------------------------
property var iconRole
property bool haveBorder: true
property bool haveMargin: true
property color backgroundColor: ComboBoxStyle.background.color.normal
// ---------------------------------------------------------------------------
background: Rectangle {
border {
color: ComboBoxStyle.background.border.color
width: comboBox.haveBorder ? ComboBoxStyle.background.border.width : 0
}
color: comboBox.enabled
? comboBox.backgroundColor
: ComboBoxStyle.background.color.readOnly
radius: ComboBoxStyle.background.radius
implicitHeight: ComboBoxStyle.background.height
implicitWidth: ComboBoxStyle.background.width
}
// ---------------------------------------------------------------------------
contentItem: Item {
height: comboBox.height
width: comboBox.width
RowLayout {
anchors {
fill: parent
leftMargin: comboBox.haveMargin ? ComboBoxStyle.contentItem.leftMargin : 0
}
spacing: ComboBoxStyle.contentItem.spacing
Icon {
icon: Logic.getSelectedEntryIcon()
iconSize: ComboBoxStyle.contentItem.iconSize
visible: icon.length > 0
}
Text {
Layout.fillWidth: true
color: ComboBoxStyle.contentItem.text.color
elide: Text.ElideRight
font.pointSize: ComboBoxStyle.contentItem.text.pointSize
rightPadding: comboBox.indicator.width + comboBox.spacing
text: Logic.getSelectedEntryText()
}
}
}
// ---------------------------------------------------------------------------
indicator: Icon {
icon: ComboBoxStyle.indicator.dropDown.icon
iconSize: ComboBoxStyle.indicator.dropDown.iconSize
overwriteColor: ComboBoxStyle.indicator.dropDown.color
x: comboBox.width - width - comboBox.rightPadding
y: comboBox.topPadding + (comboBox.availableHeight - height) / 2
}
// ---------------------------------------------------------------------------
delegate: CommonItemDelegate {
id: item
container: comboBox
flattenedModel: comboBox.textRole.length &&
(typeof modelData !== 'undefined' ? modelData : model)
itemIcon: Logic.getItemIcon(item)
width: comboBox.width
}
id: comboBox
// ---------------------------------------------------------------------------
property var iconRole
property bool haveBorder: true
property bool haveMargin: true
property color backgroundColor: ComboBoxStyle.background.color.normal
property color foregroundColor: ComboBoxStyle.contentItem.text.color
property var rootItem
property int yPopup: rootItem ? -mapToItem(rootItem,x,y).y : height + 1
property int maxPopupHeight : rootItem ? rootItem.height : 400
property int selectionWidth: width
clip: true
// ---------------------------------------------------------------------------
background: Rectangle {
border {
color: ComboBoxStyle.background.border.color
width: comboBox.haveBorder ? ComboBoxStyle.background.border.width : 0
}
color: comboBox.enabled
? comboBox.backgroundColor
: ComboBoxStyle.background.color.readOnly
radius: ComboBoxStyle.background.radius
implicitHeight: ComboBoxStyle.background.height
implicitWidth: ComboBoxStyle.background.width
}
// ---------------------------------------------------------------------------
contentItem: Item {
height: comboBox.height
width: comboBox.selectionWidth
clip: true
RowLayout {
anchors {
fill: parent
leftMargin: comboBox.haveMargin ? ComboBoxStyle.contentItem.leftMargin : 0
}
spacing: ComboBoxStyle.contentItem.spacing
Icon {
icon: Logic.getSelectedEntryIcon()
iconSize: ComboBoxStyle.contentItem.iconSize
visible: icon.length > 0
}
Text {
Layout.fillWidth: true
color: comboBox.foregroundColor
elide: Text.ElideRight
font.pointSize: ComboBoxStyle.contentItem.text.pointSize
rightPadding: comboBox.indicator.width + comboBox.spacing
text: Logic.getSelectedEntryText()
}
}
}
// ---------------------------------------------------------------------------
indicator: Icon {
icon: ComboBoxStyle.indicator.dropDown.icon
iconSize: ComboBoxStyle.indicator.dropDown.iconSize
overwriteColor: ComboBoxStyle.indicator.dropDown.color
x: comboBox.width - width - comboBox.rightPadding
y: comboBox.topPadding + (comboBox.availableHeight - height) / 2
}
// ---------------------------------------------------------------------------
/*
delegate: CommonItemDelegate {
id: item
clip: true
container: comboBox
flattenedModel: comboBox.textRole.length &&
(typeof modelData !== 'undefined' ? modelData : model)
itemIcon: Logic.getItemIcon(item)
width: comboBox.selectionWidth
onWidthChanged: console.log(width)
}*/
popup: Controls.Popup{
y: comboBox.yPopup
width: comboBox.selectionWidth
//height: comboBox.maxPopupHeight
//height: contentItem.contentHeight
implicitHeight: contentItem.contentHeight
topPadding: 0
bottomPadding: 0
leftPadding: 0
rightPadding: 0
contentItem: ListItemSelector{
//implicitHeight: contentHeight
model: comboBox.popup.visible ? comboBox.model : null
currentIndex: comboBox.highlightedIndex
textRole: comboBox.textRole
onActivated: {comboBox.activated(index);comboBox.currentIndex = index;comboBox.popup.close()}
/*
delegate: CommonItemDelegate {
id: item
clip: true
container: comboBox
flattenedModel: comboBox.textRole.length &&
(typeof modelData !== 'undefined' ? modelData : model)
itemIcon: Logic.getItemIcon(item)
width: comboBox.selectionWidth
onWidthChanged: console.log(width)
}*/
}
}
}

View file

@ -8,72 +8,70 @@ import Common.Styles 1.0
// =============================================================================
Controls.ItemDelegate {
id: item
property var container
property var flattenedModel
property var itemIcon
default property alias _content: content.data
hoverEnabled: true
background: Rectangle {
color: item.hovered
? CommonItemDelegateStyle.color.hovered
: CommonItemDelegateStyle.color.normal
Rectangle {
anchors.left: parent.left
color: CommonItemDelegateStyle.indicator.color
height: parent.height
width: CommonItemDelegateStyle.indicator.width
visible: item.hovered
}
Rectangle {
anchors.bottom: parent.bottom
color: CommonItemDelegateStyle.separator.color
height: CommonItemDelegateStyle.separator.height
width: parent.width
visible: container.count !== index + 1
}
}
contentItem: RowLayout {
spacing: CommonItemDelegateStyle.contentItem.spacing
width: item.width
Icon {
icon: item.itemIcon
iconSize: CommonItemDelegateStyle.contentItem.iconSize
visible: icon.length > 0
}
Text {
Layout.fillWidth: true
color: CommonItemDelegateStyle.contentItem.text.color
elide: Text.ElideRight
font {
bold: container.currentIndex === index
pointSize: CommonItemDelegateStyle.contentItem.text.pointSize
}
text: item.flattenedModel[container.textRole] || modelData
}
Item {
id: content
Layout.preferredWidth: CommonItemDelegateStyle.contentItem.iconSize
Layout.preferredHeight: CommonItemDelegateStyle.contentItem.iconSize
}
}
id: item
property var container
property var flattenedModel
property var itemIcon
default property alias _content: content.data
hoverEnabled: true
background: Rectangle {
color: item.hovered
? CommonItemDelegateStyle.color.hovered
: CommonItemDelegateStyle.color.normal
Rectangle {
anchors.left: parent.left
color: CommonItemDelegateStyle.indicator.color
height: parent.height
width: CommonItemDelegateStyle.indicator.width
visible: item.hovered
}
Rectangle {
anchors.bottom: parent.bottom
color: CommonItemDelegateStyle.separator.color
height: CommonItemDelegateStyle.separator.height
width: parent.width
visible: container.count !== index + 1
}
}
contentItem: RowLayout {
spacing: CommonItemDelegateStyle.contentItem.spacing
width: item.width
Icon {
icon: item.itemIcon
iconSize: CommonItemDelegateStyle.contentItem.iconSize
visible: icon.length > 0
}
Text {
Layout.fillWidth: true
color: CommonItemDelegateStyle.contentItem.text.color
elide: Text.ElideRight
font {
bold: container.currentIndex === index
pointSize: CommonItemDelegateStyle.contentItem.text.pointSize
}
text: item.flattenedModel[container.textRole] || modelData
}
Item {
id: content
Layout.preferredWidth: CommonItemDelegateStyle.contentItem.iconSize
Layout.preferredHeight: CommonItemDelegateStyle.contentItem.iconSize
}
}
}

View file

@ -14,8 +14,8 @@ Rectangle {
property QtObject textFieldStyle : TextFieldStyle.normal
color: textFieldStyle.background.color.normal
radius: textFieldStyle.background.radius
color: textFieldStyle ? textFieldStyle.background.color.normal : undefined
radius: textFieldStyle ? textFieldStyle.background.radius : 0
Item {
id: content
@ -27,8 +27,8 @@ Rectangle {
anchors.fill: parent
border {
color: textFieldStyle.background.border.color.normal
width: textFieldStyle.background.border.width
color: textFieldStyle ? textFieldStyle.background.border.color.normal : undefined
width: textFieldStyle ? textFieldStyle.background.border.width : 0
}
color: 'transparent'
@ -37,7 +37,7 @@ Rectangle {
Rectangle {
anchors.fill: parent
color: textFieldStyle.background.color.readOnly
color: textFieldStyle ? textFieldStyle.background.color.readOnly : undefined
opacity: 0.8
visible: field.readOnly
}

View file

@ -1,3 +1,6 @@
import QtQuick 2.7
import QtQuick.Controls 2.2
import Common 1.0
import 'ListItemSelector.js' as Logic
@ -5,38 +8,39 @@ import 'ListItemSelector.js' as Logic
// =============================================================================
ScrollableListViewField {
property alias currentIndex: view.currentIndex
property alias iconRole: view.iconRole
property alias model: view.model
property alias textRole: view.textRole
signal activated (int index)
radius: 0
ScrollableListView {
id: view
// -------------------------------------------------------------------------
property string textRole
property var iconRole
// -------------------------------------------------------------------------
anchors.fill: parent
currentIndex: -1
delegate: CommonItemDelegate {
id: item
container: view
flattenedModel: view.textRole.length &&
(typeof modelData !== 'undefined' ? modelData : model)
itemIcon: Logic.getItemIcon(item)
width: parent.width
onClicked: activated(index)
}
}
property alias currentIndex: view.currentIndex
property alias iconRole: view.iconRole
property alias model: view.model
property alias textRole: view.textRole
property alias contentHeight: view.contentHeight
//property alias implicitHeight: view.implicitHeight
//implicitHeight: view.implicitHeight
signal activated (int index)
color: 'red'
radius: 0
ScrollableListView {
id: view
// -------------------------------------------------------------------------
property string textRole
property var iconRole
onContentHeightChanged: parent.implicitHeight = contentHeight
// -------------------------------------------------------------------------
anchors.fill: parent
currentIndex: -1
delegate: CommonItemDelegate {
id: item
container: view
flattenedModel: view.textRole.length &&
(typeof modelData !== 'undefined' ? modelData : model)
itemIcon: Logic.getItemIcon(item)
width: view.width
onClicked: {activated(index)}
}
}
}

View file

@ -47,11 +47,11 @@ Loader{
//: 'Read by %1 - %2' Little message to indicate the state of a message
//~ Context %1 is someone, %2 is a date/time. The state that the message has been read.
return qsTr('deliveryDisplayed').arg(displayName).arg(stateChangeTime)
else if(state == LinphoneEnums.ChatMessageStateNotDelivered)
else// if(state == LinphoneEnums.ChatMessageStateNotDelivered)
//: "%1 have nothing received" Little message to indicate the state of a message
//~ Context %1 is someone. The state is that the message hasn't been delivered.
return qsTr('deliveryNotDelivered').arg(displayName)
else return ''
//else return ''
}
delegate:Text{
height: ChatStyle.composingText.height-5

View file

@ -75,7 +75,7 @@ Item {
delegate: Rectangle {
height: menu.entryHeight
width: parent.width
width: list.width
color: mouseArea.pressed
? SipAddressesMenuStyle.entry.color.pressed

View file

@ -17,10 +17,11 @@ import 'qrc:/ui/scripts/Utils/utils.js' as Utils
DialogPlus {
id: conferenceManager
property ConferenceInfoModel conferenceInfoModel: ConferenceInfoModel{
property bool isNew: true
}
onConferenceInfoModelChanged: if( conferenceInfoModel && !conferenceInfoModel.isNew) selectedParticipants.setAddresses(conferenceInfoModel)
property bool isNew: !conferenceInfoModel || conferenceInfoModel.uri === ''
onIsNewChanged: console.log("Is New:"+isNew+", "+conferenceInfoModel + ", " + (conferenceInfoModel? conferenceInfoModel.uri : 'noUri'))
Component.onCompleted: console.log("Completed: Is New:"+isNew+", "+conferenceInfoModel + ", " + (conferenceInfoModel? conferenceInfoModel.uri : 'noUri'))
property ConferenceInfoModel conferenceInfoModel: ConferenceInfoModel{}
onConferenceInfoModelChanged: selectedParticipants.setAddresses(conferenceInfoModel)
Connections{
target: conferenceInfoModel
onConferenceCreated: {
@ -107,7 +108,7 @@ DialogPlus {
TextButtonB {
enabled: selectedParticipants.count >= conferenceManager.minParticipants && subject.text != '' && AccountSettingsModel.conferenceURI != ''
//: 'Launch' : Start button
text: conferenceInfoModel.isNew ? qsTr('startButton') : 'Mettre à jour'
text: conferenceManager.isNew ? qsTr('startButton') : 'Mettre à jour'
capitalization: Font.AllUppercase
function getInviteMode(){
@ -166,7 +167,7 @@ DialogPlus {
buttonsAlignment: Qt.AlignRight
buttonsLeftMargin: 15
//: 'Start a video conference' : Title of a popup about creation of a video conference
title: conferenceInfoModel.isNew ? qsTr('newConferenceTitle') : 'Changer la conférence'
title: conferenceManager.isNew ? qsTr('newConferenceTitle') : 'Changer la conférence'
height: window.height - 100
width: window.width - 100
@ -227,7 +228,7 @@ DialogPlus {
Layout.alignment: Qt.AlignVCenter
width:50
enabled: true
checked: true
checked: conferenceInfoModel.isScheduled
onClicked: {
checked = !checked
@ -254,7 +255,7 @@ DialogPlus {
property var locale: Qt.locale()
property date currentDate: new Date()
property int cellWidth: (parent.width-15)/columns
Component.onCompleted: scheduleForm.updateDateTime()
//Component.onCompleted: scheduleForm.updateDateTime()
@ -270,6 +271,7 @@ DialogPlus {
function setDate(date){
text = date.toLocaleDateString(scheduleForm.locale, 'yyyy/MM/dd')
}
text: conferenceManager.conferenceInfoModel? conferenceManager.conferenceInfoModel.dateTime.toLocaleDateString(scheduleForm.locale, 'yyyy/MM/dd') : ''
MouseArea{
anchors.fill: parent
onClicked: {
@ -293,6 +295,7 @@ DialogPlus {
function setTime(date){
text = date.toLocaleTimeString(scheduleForm.locale, 'hh:mm')
}
text: conferenceManager.conferenceInfoModel? conferenceManager.conferenceInfoModel.dateTime.toLocaleTimeString(scheduleForm.locale, 'hh:mm') : ''
MouseArea{
anchors.top: parent.top
anchors.bottom: parent.bottom
@ -311,8 +314,21 @@ DialogPlus {
}
}
}
NumericField{id: durationField; text: '1200'; Layout.preferredWidth: parent.cellWidth; color: NewConferenceStyle.fields.textColor; font.weight: NewConferenceStyle.fields.weight; font.pointSize: NewConferenceStyle.fields.pointSize}
TextField{ text: 'Paris'; readOnly: true; Layout.preferredWidth: parent.cellWidth; color: NewConferenceStyle.fields.textColor; font.weight: NewConferenceStyle.fields.weight; font.pointSize: NewConferenceStyle.fields.pointSize}
NumericField{id: durationField; Layout.preferredWidth: parent.cellWidth; color: NewConferenceStyle.fields.textColor; font.weight: NewConferenceStyle.fields.weight; font.pointSize: NewConferenceStyle.fields.pointSize
text: conferenceManager.conferenceInfoModel ? conferenceManager.conferenceInfoModel.duration : '1200'
}
ComboBox{
Layout.preferredWidth: parent.cellWidth;
//color: NewConferenceStyle.fields.textColor; font.weight: NewConferenceStyle.fields.weight; font.pointSize: NewConferenceStyle.fields.pointSize
currentIndex: model.defaultIndex
model: TimeZoneProxyModel{}
onActivated: console.log("activated : " +index)
textRole: "displayText"
selectionWidth: 500
rootItem: conferenceManager
}
//TextField{ text: 'Paris'; readOnly: true; Layout.preferredWidth: parent.cellWidth; color: NewConferenceStyle.fields.textColor; font.weight: NewConferenceStyle.fields.weight; font.pointSize: NewConferenceStyle.fields.pointSize}
function updateDateTime(){
var storedDate
if( dateField.text != '' && timeField.text != ''){
@ -327,11 +343,13 @@ DialogPlus {
}
}
Timer{
running: scheduleForm.visible
running: scheduleForm.visible && conferenceManager.isNew
repeat: true
interval: 1000
triggeredOnStart: true
onTriggered: {
scheduleForm.updateDateTime()
if(conferenceManager.isNew)
scheduleForm.updateDateTime()
}
}
}
@ -358,7 +376,7 @@ DialogPlus {
Layout.fillHeight: true
//: 'Description' : Placeholder in a form about setting a description
placeholderText : 'Description'
text: ''
text: conferenceManager.conferenceInfoModel ? conferenceManager.conferenceInfoModel.description : ''
Keys.onReturnPressed: nextItemInFocusChain().forceActiveFocus()
TooltipArea{
//: 'This description will describe the conference' : Explanation about the description of the conference
@ -484,7 +502,7 @@ DialogPlus {
anchors.fill: parent
showContactAddress:false
showSwitch : conferenceInfoModel.isNew
showSwitch : conferenceManager.isNew
showSeparator: false
isSelectable: false
showInvitingIndicator: false

View file

@ -12,8 +12,10 @@ AssistantAbstractView {
property alias phoneNumberError: phoneNumber.error
function setCountryCode (index) {
var model = country.model
assistantModel.countryCode = model.data(model.index(index, 0)).countryCode
if(index>=0){
var model = country.model
assistantModel.countryCode = model.data(model.index(index, 0),"countryCode")
}
}
title: qsTr('createAppSipAccountTitle').replace('%1', Qt.application.name.toUpperCase())

@ -1 +1 @@
Subproject commit 0bf934b0669e77ddecfcd8298ea615bb998aa28a
Subproject commit e3f284058e17f0e01e6005659532a437ea1b0a34