Accessibility and code improvments:

* Normalize and correct linphone color
* Add border when user focus using keyboard navigation
* Correct some keyboard navigation
* Add accessibility screen reading to interactive elements except chat and meeting
This commit is contained in:
Alexandre Jörgensen 2025-09-22 10:58:55 +02:00
parent 1f97112306
commit a9a78cb4bf
99 changed files with 5011 additions and 2825 deletions

View file

@ -98,6 +98,8 @@
#include "tool/Constants.hpp" #include "tool/Constants.hpp"
#include "tool/EnumsToString.hpp" #include "tool/EnumsToString.hpp"
#include "tool/Utils.hpp" #include "tool/Utils.hpp"
#include "tool/accessibility/AccessibilityHelper.hpp"
#include "tool/accessibility/FocusHelper.hpp"
#include "tool/native/DesktopTools.hpp" #include "tool/native/DesktopTools.hpp"
#include "tool/providers/AvatarProvider.hpp" #include "tool/providers/AvatarProvider.hpp"
#include "tool/providers/EmojiProvider.hpp" #include "tool/providers/EmojiProvider.hpp"
@ -725,6 +727,12 @@ void App::initCppInterfaces() {
"SettingsCpp", 1, 0, "SettingsCpp", "SettingsCpp", 1, 0, "SettingsCpp",
[this](QQmlEngine *engine, QJSEngine *) -> QObject * { return mSettings.get(); }); [this](QQmlEngine *engine, QJSEngine *) -> QObject * { return mSettings.get(); });
qmlRegisterSingletonType<AccessibilityHelper>(
"AccessibilityHelperCpp", 1, 0, "AccessibilityHelperCpp",
[](QQmlEngine *engine, QJSEngine *) -> QObject * { return new AccessibilityHelper(engine); });
qmlRegisterType<FocusHelper>("CustomControls", 1, 0, "FocusHelper");
qmlRegisterType<DashRectangle>(Constants::MainQmlUri, 1, 0, "DashRectangle"); qmlRegisterType<DashRectangle>(Constants::MainQmlUri, 1, 0, "DashRectangle");
qmlRegisterType<PhoneNumberProxy>(Constants::MainQmlUri, 1, 0, "PhoneNumberProxy"); qmlRegisterType<PhoneNumberProxy>(Constants::MainQmlUri, 1, 0, "PhoneNumberProxy");
qmlRegisterType<VariantObject>(Constants::MainQmlUri, 1, 0, "VariantObject"); qmlRegisterType<VariantObject>(Constants::MainQmlUri, 1, 0, "VariantObject");

View file

@ -60,10 +60,7 @@ AccountCore::AccountCore(const std::shared_ptr<linphone::Account> &account) : QO
mRegisterEnabled = params->registerEnabled(); mRegisterEnabled = params->registerEnabled();
mMwiServerAddress = mMwiServerAddress =
params->getMwiServerAddress() ? Utils::coreStringToAppString(params->getMwiServerAddress()->asString()) : ""; params->getMwiServerAddress() ? Utils::coreStringToAppString(params->getMwiServerAddress()->asString()) : "";
mTransports << "UDP" mTransports << "UDP" << "TCP" << "TLS" << "DTLS";
<< "TCP"
<< "TLS"
<< "DTLS";
mTransport = LinphoneEnums::toString(LinphoneEnums::fromLinphone(params->getTransport())); mTransport = LinphoneEnums::toString(LinphoneEnums::fromLinphone(params->getTransport()));
mRegistrarUri = mRegistrarUri =
params->getServerAddress() ? Utils::coreStringToAppString(params->getServerAddress()->asString()) : ""; params->getServerAddress() ? Utils::coreStringToAppString(params->getServerAddress()->asString()) : "";
@ -458,13 +455,13 @@ QColor AccountCore::getRegistrationColor() const {
mustBeInMainThread(log().arg(Q_FUNC_INFO)); mustBeInMainThread(log().arg(Q_FUNC_INFO));
switch (mRegistrationState) { switch (mRegistrationState) {
case LinphoneEnums::RegistrationState::Ok: case LinphoneEnums::RegistrationState::Ok:
return Utils::getDefaultStyleColor("success_500main"); return Utils::getDefaultStyleColor("success_500_main");
case LinphoneEnums::RegistrationState::Refreshing: case LinphoneEnums::RegistrationState::Refreshing:
return Utils::getDefaultStyleColor("main2_500main"); return Utils::getDefaultStyleColor("main2_500_main");
case LinphoneEnums::RegistrationState::Progress: case LinphoneEnums::RegistrationState::Progress:
return Utils::getDefaultStyleColor("main2_500main"); return Utils::getDefaultStyleColor("main2_500_main");
case LinphoneEnums::RegistrationState::Failed: case LinphoneEnums::RegistrationState::Failed:
return Utils::getDefaultStyleColor("danger_500main"); return Utils::getDefaultStyleColor("danger_500_main");
case LinphoneEnums::RegistrationState::None: case LinphoneEnums::RegistrationState::None:
case LinphoneEnums::RegistrationState::Cleared: case LinphoneEnums::RegistrationState::Cleared:
return Utils::getDefaultStyleColor("warning_600"); return Utils::getDefaultStyleColor("warning_600");

View file

@ -36,6 +36,7 @@
#include "core/chat/ChatGui.hpp" #include "core/chat/ChatGui.hpp"
#include "model/tool/ToolModel.hpp" #include "model/tool/ToolModel.hpp"
#include "tool/LinphoneEnums.hpp" #include "tool/LinphoneEnums.hpp"
#include "tool/accessibility/AccessibilityHelper.hpp"
#include "tool/providers/AvatarProvider.hpp" #include "tool/providers/AvatarProvider.hpp"
#include "tool/providers/ImageProvider.hpp" #include "tool/providers/ImageProvider.hpp"
@ -302,6 +303,11 @@ void Notifier::notifyReceivedCall(const shared_ptr<linphone::Call> &call) {
QString displayName = call->getCallLog() && call->getCallLog()->getConferenceInfo() QString displayName = call->getCallLog() && call->getCallLog()->getConferenceInfo()
? Utils::coreStringToAppString(call->getCallLog()->getConferenceInfo()->getSubject()) ? Utils::coreStringToAppString(call->getCallLog()->getConferenceInfo()->getSubject())
: Utils::coreStringToAppString(call->getRemoteAddress()->getDisplayName()); : Utils::coreStringToAppString(call->getRemoteAddress()->getDisplayName());
// Accessibility alert
//: New call from %1
AccessibilityHelper::announceMessage(tr("new_call_alert_accessible_name").arg(displayName));
App::postCoreAsync([this, gui, displayName]() { App::postCoreAsync([this, gui, displayName]() {
mustBeInMainThread(getClassName()); mustBeInMainThread(getClassName());
QVariantMap map; QVariantMap map;
@ -381,6 +387,10 @@ void Notifier::notifyReceivedMessages(const std::shared_ptr<linphone::ChatRoom>
auto chatCore = ChatCore::create(room); auto chatCore = ChatCore::create(room);
// Accessibility alert
//: New message on chatroom %1
AccessibilityHelper::announceMessage(tr("new_message_alert_accessible_name").arg(chatCore->getTitle()));
App::postCoreAsync([this, txt, chatCore, remoteAddress]() { App::postCoreAsync([this, txt, chatCore, remoteAddress]() {
mustBeInMainThread(getClassName()); mustBeInMainThread(getClassName());
QVariantMap map; QVariantMap map;

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -28,6 +28,9 @@ list(APPEND _LINPHONEAPP_SOURCES
tool/ui/DashRectangle.cpp tool/ui/DashRectangle.cpp
tool/accessibility/FocusHelper.cpp
tool/accessibility/AccessibilityHelper.cpp
) )
if (APPLE) if (APPLE)

View file

@ -1765,16 +1765,16 @@ QColor Utils::getPresenceColor(LinphoneEnums::Presence presence) {
QColor presenceColor = QColorConstants::Transparent; QColor presenceColor = QColorConstants::Transparent;
switch (presence) { switch (presence) {
case LinphoneEnums::Presence::Online: case LinphoneEnums::Presence::Online:
presenceColor = Utils::getDefaultStyleColor("success_500main"); presenceColor = Utils::getDefaultStyleColor("success_500_main");
break; break;
case LinphoneEnums::Presence::Away: case LinphoneEnums::Presence::Away:
presenceColor = Utils::getDefaultStyleColor("warning_500_main"); presenceColor = Utils::getDefaultStyleColor("warning_500_main");
break; break;
case LinphoneEnums::Presence::Busy: case LinphoneEnums::Presence::Busy:
presenceColor = Utils::getDefaultStyleColor("danger_500main"); presenceColor = Utils::getDefaultStyleColor("danger_500_main");
break; break;
case LinphoneEnums::Presence::DoNotDisturb: case LinphoneEnums::Presence::DoNotDisturb:
presenceColor = Utils::getDefaultStyleColor("danger_500main"); presenceColor = Utils::getDefaultStyleColor("danger_500_main");
break; break;
case LinphoneEnums::Presence::Offline: case LinphoneEnums::Presence::Offline:
presenceColor = Utils::getDefaultStyleColor("main2_600"); presenceColor = Utils::getDefaultStyleColor("main2_600");

View file

@ -0,0 +1,36 @@
/*
* Copyright (c) 2010-2025 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 "AccessibilityHelper.hpp"
#include "tool/Utils.hpp"
#include <QAccessible>
#include <QAccessibleAnnouncementEvent>
#include <QQuickWindow>
DEFINE_ABSTRACT_OBJECT(AccessibilityHelper)
void AccessibilityHelper::announceMessage(const QString &message, QObject *context, bool assertive) {
QObject *target = context ? context : static_cast<QObject *>(Utils::getMainWindow());
QAccessibleAnnouncementEvent event(target, message);
event.setPoliteness(assertive ? QAccessible::AnnouncementPoliteness::Assertive
: QAccessible::AnnouncementPoliteness::Polite);
QAccessible::updateAccessibility(&event);
}

View file

@ -0,0 +1,41 @@
/*
* Copyright (c) 2010-2025 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 ACCESSIBILITY_HELPER_H
#define ACCESSIBILITY_HELPER_H
#include <QObject>
#include <QString>
#include "tool/AbstractObject.hpp"
class AccessibilityHelper : public QObject, public AbstractObject {
Q_OBJECT
public:
AccessibilityHelper(QObject *parent = nullptr) : QObject(parent) {
}
Q_INVOKABLE static void announceMessage(const QString &message, QObject *context = nullptr, bool assertive = false);
private:
DECLARE_ABSTRACT_OBJECT
};
#endif // ACCESSIBILITY_HELPER_H

View file

@ -0,0 +1,54 @@
/*
* Copyright (c) 2010-2025 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 "FocusHelper.hpp"
#include <iostream>
FocusHelperAttached::FocusHelperAttached(QObject *parent) : QObject(parent) {
if (auto item = qobject_cast<QQuickItem *>(parent)) {
m_item = item;
m_item->installEventFilter(this);
}
}
bool FocusHelperAttached::eventFilter(QObject *watched, QEvent *event) {
if (watched == m_item) {
if (event->type() == QEvent::FocusIn) {
auto fe = static_cast<QFocusEvent *>(event);
if (fe) {
int focusReason = fe->reason();
m_keyboardFocus = (focusReason == Qt::TabFocusReason || focusReason == Qt::BacktabFocusReason);
m_otherFocus = focusReason == Qt::OtherFocusReason;
emit keyboardFocusChanged();
emit otherFocusChanged();
}
} else if (event->type() == QEvent::FocusOut) {
m_keyboardFocus = false;
m_otherFocus = false;
emit keyboardFocusChanged();
emit otherFocusChanged();
}
}
return QObject::eventFilter(watched, event);
}
FocusHelperAttached *FocusHelper::qmlAttachedProperties(QObject *obj) {
return new FocusHelperAttached(obj);
}

View file

@ -0,0 +1,66 @@
/*
* Copyright (c) 2010-2025 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/>.
*/
#pragma once
#include <QFocusEvent>
#include <QObject>
#include <QPointer>
#include <QQuickItem>
class FocusHelperAttached : public QObject {
Q_OBJECT
Q_PROPERTY(bool keyboardFocus READ keyboardFocus NOTIFY keyboardFocusChanged)
Q_PROPERTY(bool otherFocus READ otherFocus NOTIFY otherFocusChanged)
public:
explicit FocusHelperAttached(QObject *parent = nullptr);
bool keyboardFocus() const {
return m_keyboardFocus;
}
bool otherFocus() const {
return m_otherFocus;
}
signals:
void keyboardFocusChanged();
void otherFocusChanged();
protected:
bool eventFilter(QObject *watched, QEvent *event) override;
private:
QPointer<QQuickItem> m_item;
bool m_keyboardFocus = false;
bool m_otherFocus = false;
friend class FocusHelper;
};
class FocusHelper : public QObject {
Q_OBJECT
public:
using QObject::QObject;
static FocusHelperAttached *qmlAttachedProperties(QObject *obj);
};
QML_DECLARE_TYPEINFO(FocusHelper, QML_HAS_ATTACHED_PROPERTIES)

View file

@ -45,12 +45,13 @@ list(APPEND _LINPHONEAPP_QML_FILES
view/Control/Display/EffectImage.qml view/Control/Display/EffectImage.qml
view/Control/Display/Flickable.qml view/Control/Display/Flickable.qml
view/Control/Display/GradientRectangle.qml view/Control/Display/GradientRectangle.qml
view/Control/Display/TemporaryText.qml view/Control/Display/HorizontalBar.qml
view/Control/Display/MediaProgressBar.qml view/Control/Display/MediaProgressBar.qml
view/Control/Display/ProgressBar.qml view/Control/Display/ProgressBar.qml
view/Control/Display/RoundedPane.qml view/Control/Display/RoundedPane.qml
view/Control/Display/RoundProgressBar.qml view/Control/Display/RoundProgressBar.qml
view/Control/Display/Sticker.qml view/Control/Display/Sticker.qml
view/Control/Display/TemporaryText.qml
view/Control/Display/Text.qml view/Control/Display/Text.qml
view/Control/Display/ToolTip.qml view/Control/Display/ToolTip.qml
view/Control/Display/Call/CallListView.qml view/Control/Display/Call/CallListView.qml
@ -72,6 +73,7 @@ list(APPEND _LINPHONEAPP_QML_FILES
view/Control/Display/Chat/VideoFileView.qml view/Control/Display/Chat/VideoFileView.qml
view/Control/Display/Contact/Avatar.qml view/Control/Display/Contact/Avatar.qml
view/Control/Display/Contact/Contact.qml view/Control/Display/Contact/Contact.qml
view/Control/Display/Contact/ContactStatusPopup.qml
view/Control/Display/Contact/Presence.qml view/Control/Display/Contact/Presence.qml
view/Control/Display/Contact/PresenceStatusItem.qml view/Control/Display/Contact/PresenceStatusItem.qml
view/Control/Display/Contact/PresenceSetCustomStatus.qml view/Control/Display/Contact/PresenceSetCustomStatus.qml

View file

@ -4,42 +4,63 @@ import QtQuick.Effects
import QtQuick.Layouts import QtQuick.Layouts
import QtQml import QtQml
import Linphone import Linphone
import CustomControls 1.0
import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils
import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle
Control.Button { Control.Button {
id: mainItem id: mainItem
property int capitalization
property var style property var style
property bool asynchronous: false
hoverEnabled: enabled
activeFocusOnTab: true
property color disabledFilterColor: color.hslLightness > 0.5
? DefaultStyle.grey_0
: DefaultStyle.grey_400
property bool hasNavigationFocus: enabled && (activeFocus || hovered)
property bool keyboardFocus: FocusHelper.keyboardFocus
// Background properties
property color color: style?.color?.normal || DefaultStyle.main1_500_main property color color: style?.color?.normal || DefaultStyle.main1_500_main
property color hoveredColor: style?.color?.hovered || Qt.darker(color, 1.05) property color hoveredColor: style?.color?.hovered || Qt.darker(color, 1.05)
property color pressedColor: style?.color?.pressed || Qt.darker(color, 1.1) property color pressedColor: style?.color?.pressed || Qt.darker(color, 1.1)
property color checkedColor: style?.color?.checked || style?.color?.pressed || Qt.darker(color, 1.1) property color checkedColor: style?.color?.checked || style?.color?.pressed || Qt.darker(color, 1.1)
property bool shadowEnabled: false
property int capitalization
property color backgroundColor: mainItem.checkable && mainItem.checked
? mainItem.checkedColor || mainItem.pressedColor
: mainItem.pressed
? mainItem.pressedColor
: mainItem.hovered
? mainItem.hoveredColor
: mainItem.color
// Text properties
property bool underline: false
property real textSize: Utils.getSizeWithScreenRatio(18)
property real textWeight: Typography.b1.weight
property color textColor: style?.text?.normal || DefaultStyle.grey_0 property color textColor: style?.text?.normal || DefaultStyle.grey_0
property color hoveredTextColor: style?.text?.hovered || Qt.darker(textColor, 1.05) property color hoveredTextColor: style?.text?.hovered || Qt.darker(textColor, 1.05)
property color pressedTextColor: style?.text?.pressed || Qt.darker(textColor, 1.1) property color pressedTextColor: style?.text?.pressed || Qt.darker(textColor, 1.1)
property color borderColor: style?.borderColor || "transparent" property var textFormat: Text.AutoText
property var textHAlignment: Text.AlignHCenter
// Tooltip properties
ToolTip.visible: hovered && ToolTip.text != "" ToolTip.visible: hovered && ToolTip.text != ""
ToolTip.delay: 500 ToolTip.delay: 500
property color disabledFilterColor: color.hslLightness > 0.5 // Border properties
? DefaultStyle.grey_0 property color borderColor: style?.borderColor?.normal || "transparent"
: DefaultStyle.grey_400 property color keyboardFocusedBorderColor: style?.borderColor?.keybaordFocused || DefaultStyle.main2_900
property real textSize: Math.round(18 * DefaultStyle.dp) property real borderWidth: Utils.getSizeWithScreenRatio(1)
property real textWeight: Typography.b1.weight property real keyboardFocusedBorderWidth: Utils.getSizeWithScreenRatio(3)
property var textHAlignment: Text.AlignHCenter // Image properties
property real radius: Math.round(48 * DefaultStyle.dp)
property bool underline: false
property bool hasNavigationFocus: enabled && (activeFocus || hovered)
property bool shadowEnabled: false
property var contentImageColor: style?.image?.normal || DefaultStyle.main2_600 property var contentImageColor: style?.image?.normal || DefaultStyle.main2_600
property var hoveredImageColor: style?.image?.pressed || Qt.darker(contentImageColor, 1.05) property var hoveredImageColor: style?.image?.pressed || Qt.darker(contentImageColor, 1.05)
property var checkedImageColor: style?.image?.checked || Qt.darker(contentImageColor, 1.1) property var checkedImageColor: style?.image?.checked || Qt.darker(contentImageColor, 1.1)
property var pressedImageColor: style?.image?.pressed || Qt.darker(contentImageColor, 1.1) property var pressedImageColor: style?.image?.pressed || Qt.darker(contentImageColor, 1.1)
property bool asynchronous: false
property var textFormat: Text.AutoText
spacing: Math.round(5 * DefaultStyle.dp)
hoverEnabled: enabled
activeFocusOnTab: true
icon.source: style?.iconSource || "" icon.source: style?.iconSource || ""
property color colorizationColor: mainItem.checkable && mainItem.checked ? mainItem.checkedImageColor || mainItem.checkedColor || mainItem.pressedColor : mainItem.pressed ? mainItem.pressedImageColor : mainItem.hovered ? mainItem.hoveredImageColor : mainItem.contentImageColor
// Size properties
spacing: Utils.getSizeWithScreenRatio(5)
property real radius: Math.ceil(height / 2)
MouseArea { MouseArea {
id: mouseArea id: mouseArea
z: stacklayout.z + 1 z: stacklayout.z + 1
@ -54,18 +75,15 @@ Control.Button {
anchors.fill: parent anchors.fill: parent
sourceComponent: Item { sourceComponent: Item {
width: mainItem.width
height: mainItem.height
Rectangle { Rectangle {
id: buttonBackground id: buttonBackground
anchors.fill: parent anchors.fill: parent
color: mainItem.checkable && mainItem.checked color: mainItem.backgroundColor
? mainItem.checkedColor || mainItem.pressedColor
: mainItem.pressed
? mainItem.pressedColor
: mainItem.hovered || mainItem.hasNavigationFocus
? mainItem.hoveredColor
: mainItem.color
radius: mainItem.radius radius: mainItem.radius
border.color: mainItem.borderColor border.color: mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderColor : mainItem.borderColor
border.width: mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderWidth : mainItem.borderWidth
} }
MultiEffect { MultiEffect {
enabled: mainItem.shadowEnabled enabled: mainItem.shadowEnabled
@ -115,7 +133,7 @@ Control.Button {
family: DefaultStyle.defaultFont family: DefaultStyle.defaultFont
capitalization: mainItem.capitalization capitalization: mainItem.capitalization
underline: mainItem.underline underline: mainItem.underline
bold: mainItem.style === ButtonStyle.noBackground && (mainItem.hovered || mainItem.pressed) bold: (mainItem.style === ButtonStyle.noBackground || mainItem.style === ButtonStyle.noBackgroundRed) && (mainItem.hovered || mainItem.pressed)
} }
TextMetrics { TextMetrics {
id: textMetrics id: textMetrics
@ -129,13 +147,7 @@ Control.Button {
imageSource: mainItem.icon.source imageSource: mainItem.icon.source
imageWidth: mainItem.icon.width imageWidth: mainItem.icon.width
imageHeight: mainItem.icon.height imageHeight: mainItem.icon.height
colorizationColor: mainItem.checkable && mainItem.checked colorizationColor: mainItem.colorizationColor
? mainItem.checkedImageColor || mainItem.checkedColor || mainItem.pressedColor
: mainItem.pressed
? mainItem.pressedImageColor
: mainItem.hovered
? mainItem.hoveredImageColor
: mainItem.contentImageColor
} }
contentItem: Control.StackView{ contentItem: Control.StackView{

View file

@ -20,19 +20,9 @@ Button {
? pressedColor ? pressedColor
: color : color
checkable: true checkable: true
background: Rectangle { Accessible.role: Accessible.Button
anchors.fill: parent
color: mainItem.backgroundColor
radius: mainItem.width /2
Rectangle {
anchors.fill: parent
visible: !mainItem.enabled
opacity: 0.2
color: DefaultStyle.grey_600
}
}
icon.source: checkedIconUrl && mainItem.checked ? checkedIconUrl : iconUrl icon.source: checkedIconUrl && mainItem.checked ? checkedIconUrl : iconUrl
icon.width: width * 0.58 icon.width: Math.round(width * 0.58)
icon.height: width * 0.58 icon.height: Math.round(width * 0.58)
contentImageColor: style?.image?.normal || DefaultStyle.grey_0 contentImageColor: style?.image?.normal || DefaultStyle.grey_0
} }

View file

@ -3,267 +3,268 @@ import QtQuick.Controls.Basic as Control
import QtQuick.Layouts import QtQuick.Layouts
import QtQuick.Effects import QtQuick.Effects
import Linphone import Linphone
import CustomControls 1.0
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
Control.ComboBox { Control.ComboBox {
id: mainItem id: mainItem
// Usage : each item of the model list must be {text: , img: } // Usage : each item of the model list must be {text: , img: }
// If string list, only text part of the delegate will be filled // If string list, only text part of the delegate will be filled
// readonly property string currentText: selectedItemText.text // readonly property string currentText: selectedItemText.text
property alias listView: listView property alias listView: listView
property string constantImageSource property string constantImageSource
property real pixelSize: Typography.p1.pixelSize property real pixelSize: Typography.p1.pixelSize
property real weight: Typography.p1.weight property real weight: Typography.p1.weight
property real leftMargin: Math.round(10 * DefaultStyle.dp) property real leftMargin: Utils.getSizeWithScreenRatio(10)
property bool oneLine: false property bool oneLine: false
property bool shadowEnabled: mainItem.activeFocus || mainItem.hovered property bool shadowEnabled: mainItem.activeFocus || mainItem.hovered
property string flagRole// Specific case if flag is shown (special font) property string flagRole // Specific case if flag is shown (special font)
property var indicatorColor: DefaultStyle.main2_600 property var indicatorColor: DefaultStyle.main2_600
property int indicatorRightMargin: Math.round(20 * DefaultStyle.dp) property int indicatorRightMargin: Utils.getSizeWithScreenRatio(20)
leftPadding: Math.round(10 * DefaultStyle.dp) leftPadding: Utils.getSizeWithScreenRatio(10)
rightPadding: indicImage.width + indicatorRightMargin rightPadding: indicImage.width + indicatorRightMargin
property bool keyboardFocus: FocusHelper.keyboardFocus
// Text properties
property color textColor: DefaultStyle.main2_600
property color disabledTextColor: DefaultStyle.grey_400
// Border properties
property color borderColor: DefaultStyle.grey_200
property color disabledBorderColor: DefaultStyle.grey_400
property color activeFocusedBorderColor: DefaultStyle.main1_500_main
property color keyboardFocusedBorderColor: DefaultStyle.main2_900
property real borderWidth: Utils.getSizeWithScreenRatio(1)
property real keyboardFocusedBorderWidth: Utils.getSizeWithScreenRatio(3)
// Background properties
property color color: DefaultStyle.grey_100
property color disabledColor: DefaultStyle.grey_200
onConstantImageSourceChanged: if (constantImageSource) selectedItemImg.imageSource = constantImageSource onConstantImageSourceChanged: if (constantImageSource)
onCurrentIndexChanged: { selectedItemImg.imageSource = constantImageSource
var item = model[currentIndex] onCurrentIndexChanged: {
if (!item) item = model.getAt(currentIndex) var item = model[currentIndex];
if (!item) return if (!item)
selectedItemText.text = mainItem.textRole item = model.getAt(currentIndex);
? item[mainItem.textRole] if (!item)
: item.text return;
? item.text selectedItemText.text = mainItem.textRole ? item[mainItem.textRole] : item.text ? item.text : item ? item : "";
: item if (mainItem.flagRole)
? item selectedItemFlag.text = item[mainItem.flagRole];
: "" selectedItemImg.imageSource = constantImageSource ? constantImageSource : item.img ? item.img : "";
if(mainItem.flagRole) selectedItemFlag.text = item[mainItem.flagRole] }
selectedItemImg.imageSource = constantImageSource
? constantImageSource
: item.img
? item.img
: ""
}
Keys.onPressed: (event)=>{ Keys.onPressed: event => {
if(!mainItem.contentItem.activeFocus && (event.key == Qt.Key_Space || event.key == Qt.Key_Enter || event.key == Qt.Key_Return)){ if (!mainItem.contentItem.activeFocus && (event.key == Qt.Key_Space || event.key == Qt.Key_Enter || event.key == Qt.Key_Return)) {
mainItem.popup.open() mainItem.popup.open();
event.accepted = true event.accepted = true;
} }
} }
background: Item{ background: Item {
Rectangle { Rectangle {
id: buttonBackground id: buttonBackground
anchors.fill: parent anchors.fill: parent
radius: Math.round(63 * DefaultStyle.dp) radius: Math.round(mainItem.height / 2)
color: mainItem.enabled ? DefaultStyle.grey_100 : DefaultStyle.grey_200 color: mainItem.enabled ? mainItem.color : mainItem.disabledColor
border.color: mainItem.enabled border.color: !mainItem.enabled ? mainItem.disabledBorderColor : mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderColor : mainItem.activeFocus || mainItem.popup.opened ? mainItem.activeFocusedBorderColor : mainItem.borderColor
? mainItem.activeFocus border.width: mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderWidth : mainItem.borderWidth
? DefaultStyle.main1_500_main }
: DefaultStyle.grey_200 MultiEffect {
: DefaultStyle.grey_400 enabled: mainItem.shadowEnabled
} anchors.fill: buttonBackground
MultiEffect { source: buttonBackground
enabled: mainItem.shadowEnabled visible: mainItem.shadowEnabled
anchors.fill: buttonBackground // Crash : https://bugreports.qt.io/browse/QTBUG-124730
source: buttonBackground shadowEnabled: true //mainItem.shadowEnabled
visible: mainItem.shadowEnabled shadowColor: DefaultStyle.grey_1000
// Crash : https://bugreports.qt.io/browse/QTBUG-124730 shadowBlur: 0.5
shadowEnabled: true //mainItem.shadowEnabled shadowOpacity: mainItem.shadowEnabled ? 0.1 : 0.0
shadowColor: DefaultStyle.grey_1000 }
shadowBlur: 0.5 }
shadowOpacity: mainItem.shadowEnabled ? 0.1 : 0.0 contentItem: RowLayout {
} spacing: Utils.getSizeWithScreenRatio(5)
} EffectImage {
contentItem: RowLayout { id: selectedItemImg
spacing: Math.round(5 * DefaultStyle.dp) Layout.preferredWidth: visible ? Utils.getSizeWithScreenRatio(24) : 0
EffectImage { Layout.preferredHeight: visible ? Utils.getSizeWithScreenRatio(24) : 0
id: selectedItemImg Layout.leftMargin: mainItem.leftMargin
Layout.preferredWidth: visible ? Math.round(24 * DefaultStyle.dp) : 0 imageSource: mainItem.constantImageSource ? mainItem.constantImageSource : ""
Layout.preferredHeight: visible ? Math.round(24 * DefaultStyle.dp) : 0 colorizationColor: mainItem.enabled ? mainItem.textColor : mainItem.disabledTextColor
Layout.leftMargin: mainItem.leftMargin visible: imageSource != ""
imageSource: mainItem.constantImageSource ? mainItem.constantImageSource : "" fillMode: Image.PreserveAspectFit
colorizationColor: DefaultStyle.main2_600 }
visible: imageSource != "" Text {
fillMode: Image.PreserveAspectFit id: selectedItemFlag
} Layout.preferredWidth: implicitWidth
Text { Layout.leftMargin: selectedItemImg.visible ? 0 : Utils.getSizeWithScreenRatio(5)
id: selectedItemFlag Layout.alignment: Qt.AlignCenter
Layout.preferredWidth: implicitWidth color: mainItem.enabled ? mainItem.textColor : mainItem.disabledTextColor
Layout.leftMargin: selectedItemImg.visible ? 0 : Math.round(5 * DefaultStyle.dp) font {
Layout.alignment: Qt.AlignCenter family: DefaultStyle.flagFont
color: mainItem.enabled ? DefaultStyle.main2_600 : DefaultStyle.grey_400 pixelSize: mainItem.pixelSize
font { weight: mainItem.weight
family: DefaultStyle.flagFont }
pixelSize: mainItem.pixelSize }
weight: mainItem.weight Text {
} id: selectedItemText
} Layout.fillWidth: true
Text { Layout.leftMargin: selectedItemImg.visible ? 0 : Utils.getSizeWithScreenRatio(5)
id: selectedItemText Layout.rightMargin: Utils.getSizeWithScreenRatio(20)
Layout.fillWidth: true Layout.alignment: Qt.AlignCenter
Layout.leftMargin: selectedItemImg.visible ? 0 : Math.round(5 * DefaultStyle.dp) color: mainItem.enabled ? mainItem.textColor : mainItem.disabledTextColor
Layout.rightMargin: Math.round(20 * DefaultStyle.dp) elide: Text.ElideRight
Layout.alignment: Qt.AlignCenter maximumLineCount: oneLine ? 1 : 2
color: mainItem.enabled ? DefaultStyle.main2_600 : DefaultStyle.grey_400 wrapMode: Text.WrapAnywhere
elide: Text.ElideRight font {
maximumLineCount: oneLine ? 1 : 2 family: DefaultStyle.defaultFont
wrapMode: Text.WrapAnywhere pixelSize: mainItem.pixelSize
font { weight: mainItem.weight
family: DefaultStyle.defaultFont }
pixelSize: mainItem.pixelSize }
weight: mainItem.weight }
}
}
}
indicator: EffectImage {
id: indicImage
z: 1
anchors.right: parent.right
anchors.rightMargin: mainItem.indicatorRightMargin
anchors.verticalCenter: parent.verticalCenter
imageSource: AppIcons.downArrow
width: Utils.getSizeWithScreenRatio(15)
height: Utils.getSizeWithScreenRatio(15)
fillMode: Image.PreserveAspectFit
colorizationColor: mainItem.indicatorColor
// Rotate when popup open/close
transformOrigin: Item.Center
rotation: mainItem.popup.opened ? 180 : 0
Behavior on rotation {
NumberAnimation {
duration: 200
easing.type: Easing.InOutQuad
}
}
}
indicator: EffectImage { popup: Control.Popup {
id: indicImage id: popup
z: 1 y: mainItem.height - 1
anchors.right: parent.right width: mainItem.width
anchors.rightMargin: mainItem.indicatorRightMargin implicitHeight: Math.min(contentItem.implicitHeight, mainWindow.height)
anchors.verticalCenter: parent.verticalCenter
imageSource: AppIcons.downArrow
width: Math.round(15 * DefaultStyle.dp)
height: Math.round(15 * DefaultStyle.dp)
fillMode: Image.PreserveAspectFit
colorizationColor: mainItem.indicatorColor
}
popup: Control.Popup {
id: popup
y: mainItem.height - 1
width: mainItem.width
implicitHeight: Math.min(contentItem.implicitHeight, mainWindow.height)
padding: Math.max(Math.round(1 * DefaultStyle.dp), 1) padding: Math.max(Math.round(1 * DefaultStyle.dp), 1)
onOpened: { onOpened: {
listView.positionViewAtIndex(listView.currentIndex, ListView.Center) listView.positionViewAtIndex(listView.currentIndex, ListView.Center);
listView.forceActiveFocus() listView.forceActiveFocus();
} }
contentItem: ListView { contentItem: ListView {
id: listView id: listView
clip: true clip: true
implicitHeight: contentHeight implicitHeight: contentHeight
height: popup.height height: popup.height
model: visible? mainItem.model : [] model: visible ? mainItem.model : []
currentIndex: mainItem.highlightedIndex >= 0 ? mainItem.highlightedIndex : 0 currentIndex: mainItem.highlightedIndex >= 0 ? mainItem.highlightedIndex : 0
highlightFollowsCurrentItem: true highlightFollowsCurrentItem: true
highlightMoveDuration: -1 highlightMoveDuration: -1
highlightMoveVelocity: -1 highlightMoveVelocity: -1
highlight: Rectangle { highlight: Rectangle {
width: listView.width width: listView.width
color: DefaultStyle.main2_200 color: DefaultStyle.main2_200
radius: Math.round(15 * DefaultStyle.dp) radius: Math.round(15 * DefaultStyle.dp)
y: listView.currentItem? listView.currentItem.y : 0 y: listView.currentItem ? listView.currentItem.y : 0
} }
Keys.onPressed: (event)=>{ Keys.onPressed: event => {
if(event.key == Qt.Key_Space || event.key == Qt.Key_Enter || event.key == Qt.Key_Return){ if (event.key == Qt.Key_Space || event.key == Qt.Key_Enter || event.key == Qt.Key_Return) {
event.accepted = true event.accepted = true;
mainItem.currentIndex = listView.currentIndex mainItem.currentIndex = listView.currentIndex;
popup.close() popup.close();
} }
} }
delegate: Item { delegate: Item {
width:mainItem.width width: mainItem.width
height: mainItem.height height: mainItem.height
// anchors.left: listView.left // anchors.left: listView.left
// anchors.right: listView.right // anchors.right: listView.right
RowLayout{ Accessible.name: typeof (modelData) != "undefined" ? mainItem.textRole ? modelData[mainItem.textRole] : modelData.text ? modelData.text : modelData : $modelData ? mainItem.textRole ? $modelData[mainItem.textRole] : $modelData : ""
anchors.fill: parent RowLayout {
EffectImage { anchors.fill: parent
id: delegateImg EffectImage {
id: delegateImg
Layout.preferredWidth: visible ? Math.round(20 * DefaultStyle.dp) : 0 Layout.preferredWidth: visible ? Math.round(20 * DefaultStyle.dp) : 0
Layout.leftMargin: Math.round(10 * DefaultStyle.dp) Layout.leftMargin: Math.round(10 * DefaultStyle.dp)
visible: imageSource != "" visible: imageSource != ""
imageWidth: Math.round(20 * DefaultStyle.dp) imageWidth: Math.round(20 * DefaultStyle.dp)
imageSource: typeof(modelData) != "undefined" && modelData.img ? modelData.img : "" imageSource: typeof (modelData) != "undefined" && modelData.img ? modelData.img : ""
fillMode: Image.PreserveAspectFit fillMode: Image.PreserveAspectFit
} }
Text { Text {
Layout.preferredWidth: implicitWidth id: flagItem
Layout.leftMargin: delegateImg.visible ? 0 : Math.round(5 * DefaultStyle.dp) Layout.preferredWidth: implicitWidth
Layout.alignment: Qt.AlignCenter
visible: mainItem.flagRole
font {
family: DefaultStyle.flagFont
pixelSize: mainItem.pixelSize
weight: mainItem.weight
}
text: mainItem.flagRole
? typeof(modelData) != "undefined"
? modelData[mainItem.flagRole]
: $modelData[mainItem.flagRole]
: ""
}
Text {
Layout.fillWidth: true
Layout.leftMargin: delegateImg.visible ? 0 : Math.round(5 * DefaultStyle.dp) Layout.leftMargin: delegateImg.visible ? 0 : Math.round(5 * DefaultStyle.dp)
Layout.alignment: Qt.AlignCenter
visible: mainItem.flagRole
font {
family: DefaultStyle.flagFont
pixelSize: mainItem.pixelSize
weight: mainItem.weight
}
text: mainItem.flagRole ? typeof (modelData) != "undefined" ? modelData[mainItem.flagRole] : $modelData[mainItem.flagRole] : ""
}
Text {
Layout.fillWidth: true
Layout.leftMargin: delegateImg.visible ? 0 : flagItem.visble ? Utils.getSizeWithScreenRatio(5) : Utils.getSizeWithScreenRatio(25)
Layout.rightMargin: Math.round(20 * DefaultStyle.dp) Layout.rightMargin: Math.round(20 * DefaultStyle.dp)
Layout.alignment: Qt.AlignCenter Layout.alignment: Qt.AlignCenter
text: typeof(modelData) != "undefined" text: typeof (modelData) != "undefined" ? mainItem.textRole ? modelData[mainItem.textRole] : modelData.text ? modelData.text : modelData : $modelData ? mainItem.textRole ? $modelData[mainItem.textRole] : $modelData : ""
? mainItem.textRole elide: Text.ElideRight
? modelData[mainItem.textRole] maximumLineCount: 1
: modelData.text wrapMode: Text.WrapAnywhere
? modelData.text font {
: modelData family: DefaultStyle.defaultFont
: $modelData pixelSize: Utils.getSizeWithScreenRatio(15)
? mainItem.textRole weight: Math.min(Utils.getSizeWithScreenRatio(400), 1000)
? $modelData[mainItem.textRole] }
: $modelData }
: "" }
elide: Text.ElideRight
maximumLineCount: 1
wrapMode: Text.WrapAnywhere
font {
family: DefaultStyle.defaultFont
pixelSize: Math.round(14 * DefaultStyle.dp)
weight: Math.min(Math.round(400 * DefaultStyle.dp), 1000)
}
}
}
MouseArea { MouseArea {
id: mouseArea id: mouseArea
anchors.fill: parent anchors.fill: parent
hoverEnabled: true hoverEnabled: true
Rectangle { Rectangle {
anchors.fill: parent anchors.fill: parent
opacity: 0.1 opacity: 0.1
radius: Math.round(15 * DefaultStyle.dp) radius: Utils.getSizeWithScreenRatio(15)
color: DefaultStyle.main2_500main color: DefaultStyle.main2_500_main
visible: parent.containsMouse visible: parent.containsMouse
} }
onClicked: { onClicked: {
mainItem.currentIndex = index mainItem.currentIndex = index;
popup.close() popup.close();
} }
} }
} }
Control.ScrollIndicator.vertical: Control.ScrollIndicator { } Control.ScrollIndicator.vertical: Control.ScrollIndicator {}
} }
background: Item {
implicitWidth: mainItem.width
background: Item { implicitHeight: Utils.getSizeWithScreenRatio(30)
implicitWidth: mainItem.width Rectangle {
implicitHeight: Math.round(30 * DefaultStyle.dp) id: cboxBg
Rectangle { anchors.fill: parent
id: cboxBg radius: Utils.getSizeWithScreenRatio(15)
anchors.fill: parent }
radius: Math.round(15 * DefaultStyle.dp) MultiEffect {
} anchors.fill: cboxBg
MultiEffect { source: cboxBg
anchors.fill: cboxBg shadowEnabled: true
source: cboxBg shadowColor: DefaultStyle.grey_1000
shadowEnabled: true shadowBlur: 0.1
shadowColor: DefaultStyle.grey_1000 shadowOpacity: 0.1
shadowBlur: 0.1 }
shadowOpacity: 0.1 }
} }
}
}
} }

View file

@ -26,6 +26,7 @@ ColumnLayout {
Control.ComboBox { Control.ComboBox {
id: combobox id: combobox
currentIndex: phoneNumberModel.count > 0 ? Math.max(0, phoneNumberModel.findIndexByCountryCallingCode(defaultCallingCode)) : -1 currentIndex: phoneNumberModel.count > 0 ? Math.max(0, phoneNumberModel.findIndexByCountryCallingCode(defaultCallingCode)) : -1
Accessible.name: mainItem.Accessible.name
model: PhoneNumberProxy { model: PhoneNumberProxy {
id: phoneNumberModel id: phoneNumberModel
} }
@ -36,7 +37,7 @@ ColumnLayout {
color: mainItem.enableBackgroundColor ? DefaultStyle.grey_100 : "transparent" color: mainItem.enableBackgroundColor ? DefaultStyle.grey_100 : "transparent"
border.color: mainItem.enableBackgroundColors border.color: mainItem.enableBackgroundColors
? (mainItem.errorMessage.length > 0 ? (mainItem.errorMessage.length > 0
? DefaultStyle.danger_500main ? DefaultStyle.danger_500_main
: textField.activeFocus : textField.activeFocus
? DefaultStyle.main1_500_main ? DefaultStyle.main1_500_main
: DefaultStyle.grey_200) : DefaultStyle.grey_200)
@ -140,7 +141,7 @@ ColumnLayout {
id: countryText id: countryText
text: $modelData.country text: $modelData.country
elide: Text.ElideRight elide: Text.ElideRight
color: DefaultStyle.main2_500main color: DefaultStyle.main2_500_main
font { font {
pixelSize: Typography.p1.pixelSize pixelSize: Typography.p1.pixelSize
weight: Typography.p1.weight weight: Typography.p1.weight
@ -151,13 +152,13 @@ ColumnLayout {
id: separator id: separator
width: Math.max(Math.round(1 * DefaultStyle.dp), 1) width: Math.max(Math.round(1 * DefaultStyle.dp), 1)
height: combobox.height / 2 height: combobox.height / 2
color: DefaultStyle.main2_500main color: DefaultStyle.main2_500_main
} }
Text { Text {
text: "+" + $modelData.countryCallingCode text: "+" + $modelData.countryCallingCode
elide: Text.ElideRight elide: Text.ElideRight
color: DefaultStyle.main2_500main color: DefaultStyle.main2_500_main
font { font {
pixelSize: Typography.p1.pixelSize pixelSize: Typography.p1.pixelSize
weight: Typography.p1.weight weight: Typography.p1.weight
@ -174,7 +175,7 @@ ColumnLayout {
anchors.fill: parent anchors.fill: parent
opacity: 0.1 opacity: 0.1
radius: Math.round(15 * DefaultStyle.dp) radius: Math.round(15 * DefaultStyle.dp)
color: DefaultStyle.main2_500main color: DefaultStyle.main2_500_main
visible: parent.containsMouse visible: parent.containsMouse
} }
onClicked: { onClicked: {

View file

@ -50,7 +50,7 @@ MouseArea {
verticalAlignment: Text.AlignTop verticalAlignment: Text.AlignTop
Layout.fillWidth: true Layout.fillWidth: true
text: mainItem.subTitle text: mainItem.subTitle
color: DefaultStyle.main2_500main color: DefaultStyle.main2_500_main
visible: subTitle.length > 0 visible: subTitle.length > 0
font: Typography.p1 font: Typography.p1
} }

View file

@ -22,7 +22,7 @@ Button {
: mainItem.hovered || mainItem.hasNavigationFocus : mainItem.hovered || mainItem.hasNavigationFocus
? mainItem.hoveredColor ? mainItem.hoveredColor
: mainItem.color : mainItem.color
border.color: mainItem.borderColor border.color: mainItem.hovered ? mainItem.focusedBorderColor : mainItem.borderColor
} }
contentItem: EffectImage { contentItem: EffectImage {

View file

@ -24,6 +24,7 @@ ColumnLayout {
contentImageColor: DefaultStyle.main2_600 contentImageColor: DefaultStyle.main2_600
radius: Math.round(40 * DefaultStyle.dp) radius: Math.round(40 * DefaultStyle.dp)
style: ButtonStyle.grey style: ButtonStyle.grey
Accessible.name: labelButton.label
} }
Text { Text {
id: text id: text

View file

@ -2,94 +2,100 @@ import QtQuick
import QtQuick.Controls.Basic as Control import QtQuick.Controls.Basic as Control
import QtQuick.Effects import QtQuick.Effects
import Linphone import Linphone
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
Button { Button {
id: mainItem id: mainItem
property alias popup: popup property alias popup: popup
property bool shadowEnabled: mainItem.activeFocus || hovered property bool shadowEnabled: mainItem.activeFocus && !keyboardFocus || hovered
property alias popupBackgroundColor: popupBackground.color property alias popupBackgroundColor: popupBackground.color
property color backgroundColor: checked ? pressedColor : hovered ? hoveredColor : color property color backgroundColor: checked ? pressedColor : hovered || mainItem.activeFocus ? hoveredColor : color
property string popUpTitle: ""
Accessible.name: popup.visible ?
//: "Close %1 popup"
qsTr("close_popup_panel_accessible_name").arg(popUpTitle) :
//: "Open %1" popup
qsTr("open_popup_panel_accessible_name").arg(popUpTitle)
style: ButtonStyle.popupButton style: ButtonStyle.popupButton
checked: popup.visible checked: popup.visible
implicitWidth: Math.round(24 * DefaultStyle.dp)
implicitHeight: Math.round(24 * DefaultStyle.dp)
width: Math.round(24 * DefaultStyle.dp)
height: Math.round(24 * DefaultStyle.dp)
leftPadding: 0 leftPadding: 0
rightPadding: 0 rightPadding: 0
topPadding: 0 topPadding: 0
bottomPadding: 0 bottomPadding: 0
icon.source: AppIcons.verticalDots icon.source: AppIcons.verticalDots
icon.width: width icon.width: Utils.getSizeWithScreenRatio(24)
icon.height: width icon.height: Utils.getSizeWithScreenRatio(24)
implicitWidth: Utils.getSizeWithScreenRatio(30)
implicitHeight: Utils.getSizeWithScreenRatio(30)
function close() { function close() {
popup.close() popup.close();
} }
function open() { function open() {
popup.open() popup.open();
} }
function isFocusable(item) { function isFocusable(item) {
return item.activeFocusOnTab return item.activeFocusOnTab;
} }
/**
* Check if an element has at least one child that is focusable
*/
function hasFocusableChild(content) {
return content.children.some(child => isFocusable(child));
}
function getPreviousItem(index) { function getPreviousItem(index) {
return _getPreviousItem( return _getPreviousItem(popup.contentItem instanceof FocusScope ? popup.contentItem.children[0] : popup.contentItem, index);
popup.contentItem
instanceof FocusScope ? popup.contentItem.children[0] : popup.contentItem,
index)
} }
function getNextItem(index) { function getNextItem(index) {
return _getNextItem( return _getNextItem(popup.contentItem instanceof FocusScope ? popup.contentItem.children[0] : popup.contentItem, index);
popup.contentItem
instanceof FocusScope ? popup.contentItem.children[0] : popup.contentItem,
index)
} }
function _getPreviousItem(content, index) { function _getPreviousItem(content, index) {
if (content.visibleChildren.length == 0) if (content.visibleChildren.length == 0 || !hasFocusableChild(content))
return null return null;
--index --index;
while (index >= 0) { while (index >= 0) {
if (isFocusable(content.children[index]) if (isFocusable(content.children[index]) && content.children[index].visible)
&& content.children[index].visible) return content.children[index];
return content.children[index] --index;
--index
} }
return _getPreviousItem(content, content.children.length) return _getPreviousItem(content, content.visibleChildren.length);
} }
function _getNextItem(content, index) { function _getNextItem(content, index) {
++index if (content.visibleChildren.length == 0 || !hasFocusableChild(content))
return null;
++index;
while (index < content.children.length) { while (index < content.children.length) {
if (isFocusable(content.children[index]) if (isFocusable(content.children[index]) && content.children[index].visible)
&& content.children[index].visible) return content.children[index];
return content.children[index] ++index;
++index
} }
return _getNextItem(content, -1) return _getNextItem(content, -1);
} }
Keys.onPressed: event => { Keys.onPressed: event => {
if (mainItem.checked) { if (mainItem.checked) {
if (event.key == Qt.Key_Escape if (event.key == Qt.Key_Escape || event.key == Qt.Key_Left || event.key == Qt.Key_Space) {
|| event.key == Qt.Key_Left mainItem.close();
|| event.key == Qt.Key_Space) { mainItem.forceActiveFocus(Qt.TabFocusReason);
mainItem.close() event.accepted = true;
mainItem.forceActiveFocus() } else if (event.key == Qt.Key_Up) {
event.accepted = true getPreviousItem(0).forceActiveFocus(Qt.TabFocusReason);
} else if (event.key == Qt.Key_Up) { event.accepted = true;
getPreviousItem(0).forceActiveFocus() } else if (event.key == Qt.Key_Tab || event.key == Qt.Key_Down) {
event.accepted = true getNextItem(-1).forceActiveFocus(Qt.BacktabFocusReason);
} else if (event.key == Qt.Key_Tab event.accepted = true;
|| event.key == Qt.Key_Down) { }
getNextItem(-1).forceActiveFocus() } else if (event.key == Qt.Key_Space) {
event.accepted = true mainItem.open();
} event.accepted = true;
} else if (event.key == Qt.Key_Space) { }
mainItem.open() }
event.accepted = true
}
}
background: Item { background: Item {
anchors.fill: mainItem anchors.fill: mainItem
@ -97,7 +103,9 @@ Button {
id: buttonBackground id: buttonBackground
anchors.fill: parent anchors.fill: parent
color: mainItem.backgroundColor color: mainItem.backgroundColor
radius: Math.round(40 * DefaultStyle.dp) radius: Utils.getSizeWithScreenRatio(40)
border.color: mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderColor : mainItem.borderColor
border.width: mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderWidth : mainItem.borderWidth
} }
MultiEffect { MultiEffect {
enabled: mainItem.shadowEnabled enabled: mainItem.shadowEnabled
@ -119,45 +127,37 @@ Button {
} }
onPressed: { onPressed: {
if (popup.visible) if (popup.visible)
popup.close() popup.close();
else else
popup.open() popup.open();
} }
Control.Popup { Control.Popup {
id: popup id: popup
x: 0 x: 0
y: mainItem.height y: mainItem.height
visible: false visible: false
closePolicy: Popup.CloseOnPressOutsideParent | Popup.CloseOnPressOutside closePolicy: Popup.CloseOnPressOutsideParent | Popup.CloseOnPressOutside | Popup.CloseOnEscape
| Popup.CloseOnEscape padding: Utils.getSizeWithScreenRatio(10)
padding: Math.round(10 * DefaultStyle.dp)
parent: mainItem // Explicit define for coordinates references. parent: mainItem // Explicit define for coordinates references.
function updatePosition() { function updatePosition() {
if (!visible) if (!visible)
return return;
var popupHeight = popup.height + popup.padding var popupHeight = popup.height + popup.padding;
var popupWidth = popup.width + popup.padding var popupWidth = popup.width + popup.padding;
var winPosition = mainItem.Window.contentItem ? mainItem.Window.contentItem.mapToItem( var winPosition = mainItem.Window.contentItem ? mainItem.Window.contentItem.mapToItem(mainItem, 0, 0) : {
mainItem, 0, "x": 0,
0) : { "y": 0
"x": 0, };
"y": 0
}
// Stay inside main window // Stay inside main window
y = Math.max(Math.min( y = Math.max(Math.min(winPosition.y + mainItem.Window.height - popupHeight, mainItem.height), winPosition.y);
winPosition.y + mainItem.Window.height - popupHeight, x = Math.max(Math.min(winPosition.x + mainItem.Window.width - popupWidth, 0), winPosition.x);
mainItem.height), winPosition.y)
x = Math.max(
Math.min(
winPosition.x + mainItem.Window.width - popupWidth,
0), winPosition.x)
// Avoid overlapping with popup button by going to the right (todo: check if left is better?) // Avoid overlapping with popup button by going to the right (todo: check if left is better?)
if (y < mainItem.height && y + popupHeight > 0) { if (y < mainItem.height && y + popupHeight > 0) {
x += mainItem.width x += mainItem.width;
} }
var globalPos = mapToItem(mainItem.Window.contentItem, x, y) var globalPos = mapToItem(mainItem.Window.contentItem, x, y);
if (globalPos.x + popupWidth >= mainItem.Window.width) { if (globalPos.x + popupWidth >= mainItem.Window.width) {
x = -popupWidth x = -popupWidth;
} }
} }
@ -168,21 +168,20 @@ Button {
Connections { Connections {
target: mainItem.Window target: mainItem.Window
function onHeightChanged() { function onHeightChanged() {
Qt.callLater(popup.updatePosition) Qt.callLater(popup.updatePosition);
} }
function onWidthChanged() { function onWidthChanged() {
Qt.callLater(popup.updatePosition) Qt.callLater(popup.updatePosition);
} }
} }
background: Item { background: Item {
anchors.fill: parent anchors.fill: parent
Rectangle { Rectangle {
id: popupBackground id: popupBackground
anchors.fill: parent anchors.fill: parent
color: DefaultStyle.grey_0 color: DefaultStyle.grey_0
radius: Math.round(16 * DefaultStyle.dp) radius: Utils.getSizeWithScreenRatio(16)
} }
MultiEffect { MultiEffect {
source: popupBackground source: popupBackground
@ -192,7 +191,7 @@ Button {
shadowColor: DefaultStyle.grey_1000 shadowColor: DefaultStyle.grey_1000
shadowOpacity: 0.4 shadowOpacity: 0.4
} }
MouseArea{ MouseArea {
anchors.fill: parent anchors.fill: parent
} }
} }

View file

@ -6,7 +6,7 @@ import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils
ComboBox { ComboBox {
id: mainItem id: mainItem
Layout.preferredHeight: Math.round(49 * DefaultStyle.dp) Layout.preferredHeight: Utils.getSizeWithScreenRatio(49)
property string propertyName property string propertyName
property var propertyOwner property var propertyOwner

View file

@ -2,6 +2,7 @@ import QtQuick
import QtQuick.Controls.Basic import QtQuick.Controls.Basic
import QtQuick.Layouts import QtQuick.Layouts
import Linphone import Linphone
import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils
RowLayout { RowLayout {
id:mainItem id:mainItem
@ -45,6 +46,8 @@ RowLayout {
enabled: mainItem.enabled enabled: mainItem.enabled
onCheckedChanged: mainItem.checkedChanged(checked) onCheckedChanged: mainItem.checkedChanged(checked)
onToggled: binding.when = true onToggled: binding.when = true
implicitHeight: Utils.getSizeWithScreenRatio(30)
Accessible.name: "%1 %2".arg(mainItem.titleText).arg(mainItem.subTitleText)
} }
Binding { Binding {
id: binding id: binding

View file

@ -3,22 +3,30 @@ import QtQuick.Effects
import QtQuick.Layouts import QtQuick.Layouts
import QtQuick.Controls.Basic as Control import QtQuick.Controls.Basic as Control
import Linphone import Linphone
import CustomControls 1.0
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
Control.Slider { Control.Slider {
id: mainItem id: mainItem
property bool shadowEnabled: mainItem.hovered || mainItem.activeFocus property bool keyboardFocus: FocusHelper.keyboardFocus
property bool shadowEnabled: mainItem.hovered || mainItem.activeFocus && !keyboardFocus
hoverEnabled: true hoverEnabled: true
// Border properties
property color borderColor: "transparent"
property color keyboardFocusedBorderColor: DefaultStyle.main2_900
property real borderWidth: 0
property real keyboardFocusedBorderWidth: Utils.getSizeWithScreenRatio(3)
background: Item{ background: Item{
x: mainItem.leftPadding x: mainItem.leftPadding
y: mainItem.topPadding + mainItem.availableHeight / 2 - height / 2 y: mainItem.topPadding + mainItem.availableHeight / 2 - height / 2
implicitWidth: Math.round(200 * DefaultStyle.dp) implicitWidth: Utils.getSizeWithScreenRatio(200)
implicitHeight: Math.round(4 * DefaultStyle.dp) implicitHeight: Utils.getSizeWithScreenRatio(4)
width: mainItem.availableWidth width: mainItem.availableWidth
height: implicitHeight height: implicitHeight
Rectangle { Rectangle {
id: sliderBackground id: sliderBackground
anchors.fill: parent anchors.fill: parent
radius: Math.round(30 * DefaultStyle.dp) radius: Math.round(height / 2)
// TODO : change the colors when mockup indicates their names // TODO : change the colors when mockup indicates their names
color: DefaultStyle.grey_850 color: DefaultStyle.grey_850
@ -30,7 +38,7 @@ Control.Slider {
GradientStop { position: 0.0; color: DefaultStyle.main1_300 } GradientStop { position: 0.0; color: DefaultStyle.main1_300 }
GradientStop { position: 1.0; color: DefaultStyle.main1_500_main } GradientStop { position: 1.0; color: DefaultStyle.main1_500_main }
} }
radius: Math.round(40 * DefaultStyle.dp) radius: Math.round(height / 2)
} }
} }
MultiEffect { MultiEffect {
@ -49,13 +57,15 @@ Control.Slider {
handle: Item { handle: Item {
x: mainItem.leftPadding + mainItem.visualPosition * (mainItem.availableWidth - width) x: mainItem.leftPadding + mainItem.visualPosition * (mainItem.availableWidth - width)
y: mainItem.topPadding + mainItem.availableHeight / 2 - height / 2 y: mainItem.topPadding + mainItem.availableHeight / 2 - height / 2
implicitWidth: Math.round(16 * DefaultStyle.dp) implicitWidth: Utils.getSizeWithScreenRatio(16)
implicitHeight: Math.round(16 * DefaultStyle.dp) implicitHeight: Utils.getSizeWithScreenRatio(16)
Rectangle { Rectangle {
id: handleRect id: handleRect
anchors.fill: parent anchors.fill: parent
radius: Math.round(30 * DefaultStyle.dp) radius: Math.round(height / 2)
color: DefaultStyle.grey_0 color: DefaultStyle.grey_0
border.color: mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderColor : mainItem.borderColor
border.width: mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderWidth : mainItem.borderWidth
} }
MultiEffect { MultiEffect {
source: handleRect source: handleRect
@ -63,7 +73,7 @@ Control.Slider {
shadowEnabled: true shadowEnabled: true
shadowColor: DefaultStyle.grey_1000 shadowColor: DefaultStyle.grey_1000
shadowBlur: 0.1 shadowBlur: 0.1
shadowOpacity: 0.1 shadowOpacity: 0.5
} }
} }
} }

View file

@ -1,52 +1,69 @@
import QtQuick import QtQuick
import QtQuick.Controls.Basic as Control import QtQuick.Controls.Basic as Control
import QtQuick.Effects import QtQuick.Effects
import Linphone import Linphone
import CustomControls 1.0
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
Control.Switch { Control.Switch {
id: mainItem id: mainItem
property bool shadowEnabled: mainItem.hovered || mainItem.activeFocus
hoverEnabled: true hoverEnabled: true
font { property bool keyboardFocus: FocusHelper.keyboardFocus
property bool shadowEnabled: mainItem.hovered || mainItem.activeFocus && !keyboardFocus
// Text properties
font {
pixelSize: Typography.p1.pixelSize pixelSize: Typography.p1.pixelSize
weight: Typography.p1.weight weight: Typography.p1.weight
} }
indicator: Item{ // Size properties
implicitWidth: Math.round(32 * DefaultStyle.dp) implicitHeight: Utils.getSizeWithScreenRatio(20)
implicitHeight: Math.round(20 * DefaultStyle.dp) implicitWidth: Math.round(implicitHeight * 1.6)
x: mainItem.leftPadding // Border properties
y: parent.height / 2 - height / 2 property color borderColor: "transparent"
Rectangle { property color keyboardFocusedBorderColor: DefaultStyle.main2_900
id: indicatorBackground property real borderWidth: 0
anchors.fill: parent property real keyboardFocusedBorderWidth: Utils.getSizeWithScreenRatio(3)
radius: Math.round(10 * DefaultStyle.dp)
color: mainItem.checked? DefaultStyle.success_500main : DefaultStyle.main2_400
Rectangle { indicator: Item {
anchors.verticalCenter: parent.verticalCenter id: indicatorItem
property real margin: Math.round(4 * DefaultStyle.dp) x: mainItem.leftPadding
x: mainItem.checked ? parent.width - width - margin : margin y: parent.height / 2 - height / 2
width: Math.round(12 * DefaultStyle.dp) height: mainItem.height
height: Math.round(12 * DefaultStyle.dp) width: mainItem.width
radius: Math.round(10 * DefaultStyle.dp) Rectangle {
color: DefaultStyle.grey_0 id: indicatorBackground
Behavior on x { anchors.fill: parent
NumberAnimation{duration: 100} radius: Math.round(indicatorItem.height / 2)
} color: mainItem.checked ? DefaultStyle.success_500_main : DefaultStyle.main2_400
} border.color: mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderColor : mainItem.borderColor
} border.width: mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderWidth : mainItem.borderWidth
Rectangle {
anchors.verticalCenter: parent.verticalCenter
height: Math.round(indicatorItem.height * 0.6)
width: height
property real margin: Math.round((indicatorItem.height - height) / 2)
radius: Math.round(height / 2)
x: mainItem.checked ? parent.width - width - margin : margin
color: DefaultStyle.grey_0
Behavior on x {
NumberAnimation {
duration: 100
}
}
}
}
MultiEffect { MultiEffect {
enabled: mainItem.shadowEnabled enabled: mainItem.shadowEnabled
anchors.fill: indicatorBackground anchors.fill: indicatorBackground
source: indicatorBackground source: indicatorBackground
visible: mainItem.shadowEnabled visible: mainItem.shadowEnabled
// Crash : https://bugreports.qt.io/browse/QTBUG-124730 // Crash : https://bugreports.qt.io/browse/QTBUG-124730
shadowEnabled: true //mainItem.shadowEnabled shadowEnabled: true //mainItem.shadowEnabled
shadowColor: DefaultStyle.grey_1000 shadowColor: DefaultStyle.grey_1000
shadowBlur: 0.1 shadowBlur: 0.1
shadowOpacity: mainItem.shadowEnabled ? 0.5 : 0.0 shadowOpacity: mainItem.shadowEnabled ? 0.5 : 0.0
} }
} }
contentItem: Text { contentItem: Text {

View file

@ -43,7 +43,7 @@ Rectangle {
Text { Text {
font: Typography.p3 font: Typography.p3
color: DefaultStyle.main2_500main color: DefaultStyle.main2_500_main
text: mainItem.friendCore?.presenceNote || "" text: mainItem.friendCore?.presenceNote || ""
wrapMode: Text.Wrap wrapMode: Text.Wrap
Layout.fillWidth: true Layout.fillWidth: true

View file

@ -6,6 +6,7 @@ import QtQuick.Effects
import Linphone import Linphone
import UtilsCpp import UtilsCpp
import SettingsCpp import SettingsCpp
import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils
FocusScope { FocusScope {
id: mainItem id: mainItem
@ -19,20 +20,20 @@ FocusScope {
clip: true clip: true
property alias topContent: topLayout.data property alias topContent: topLayout.data
property bool topLayoutVisible: topLayout.children.length > 0 property bool topLayoutVisible: topLayout.children.length > 0
property int searchBarRightMaring: Math.round(39 * DefaultStyle.dp) property int searchBarRightMaring: Utils.getSizeWithScreenRatio(39)
ColumnLayout { ColumnLayout {
anchors.fill: parent anchors.fill: parent
spacing: Math.round(22 * DefaultStyle.dp) spacing: Utils.getSizeWithScreenRatio(22)
ColumnLayout { ColumnLayout {
id: topLayout id: topLayout
visible: mainItem.topLayoutVisible visible: mainItem.topLayoutVisible
spacing: Math.round(18 * DefaultStyle.dp) spacing: Utils.getSizeWithScreenRatio(18)
} }
ColumnLayout { ColumnLayout {
onVisibleChanged: if (!visible && mainItem.numPadPopup) mainItem.numPadPopup.close() onVisibleChanged: if (!visible && mainItem.numPadPopup) mainItem.numPadPopup.close()
spacing: Math.round(38 * DefaultStyle.dp) spacing: Utils.getSizeWithScreenRatio(38)
SearchBar { SearchBar {
id: searchBar id: searchBar
Layout.alignment: Qt.AlignTop Layout.alignment: Qt.AlignTop
@ -44,28 +45,32 @@ FocusScope {
//: "Rechercher un contact" //: "Rechercher un contact"
placeholderText: qsTr("search_bar_look_for_contact_text") placeholderText: qsTr("search_bar_look_for_contact_text")
numericPadPopup: mainItem.numPadPopup numericPadPopup: mainItem.numPadPopup
KeyNavigation.down: grouCreationButton KeyNavigation.down: groupCreationButton
} }
ColumnLayout { ColumnLayout {
id: content id: content
spacing: Math.round(32 * DefaultStyle.dp) spacing: Utils.getSizeWithScreenRatio(32)
Button { Button {
id: grouCreationButton id: groupCreationButton
Layout.preferredWidth: Math.round(320 * DefaultStyle.dp) Layout.preferredWidth: Utils.getSizeWithScreenRatio(320)
Layout.preferredHeight: Math.round(44 * DefaultStyle.dp) Layout.preferredHeight: Utils.getSizeWithScreenRatio(44)
padding: 0 padding: 0
KeyNavigation.up: searchBar KeyNavigation.up: searchBar
KeyNavigation.down: contactList KeyNavigation.down: contactList
onClicked: mainItem.groupCreationRequested() onClicked: mainItem.groupCreationRequested()
background: Rectangle { background: Rectangle {
anchors.fill: parent anchors.fill: parent
radius: Math.round(50 * DefaultStyle.dp) radius: height / 2
gradient: Gradient { gradient: Gradient {
orientation: Gradient.Horizontal orientation: Gradient.Horizontal
GradientStop { position: 0.0; color: DefaultStyle.main2_100} GradientStop { position: 0.0; color: DefaultStyle.main2_100}
GradientStop { position: 1.0; color: DefaultStyle.grey_0} GradientStop { position: 1.0; color: DefaultStyle.grey_0}
} }
// Black border for keyboard navigation
border.color: DefaultStyle.main2_900
border.width: groupCreationButton.keyboardFocus ? Utils.getSizeWithScreenRatio(3) : 0
} }
Accessible.name: mainItem.startGroupButtonText
contentItem: RowLayout { contentItem: RowLayout {
spacing: Math.round(16 * DefaultStyle.dp) spacing: Math.round(16 * DefaultStyle.dp)
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
@ -96,9 +101,9 @@ FocusScope {
} }
EffectImage { EffectImage {
imageSource: AppIcons.rightArrow imageSource: AppIcons.rightArrow
Layout.preferredWidth: Math.round(24 * DefaultStyle.dp) Layout.preferredWidth: Utils.getSizeWithScreenRatio(24)
Layout.preferredHeight: Math.round(24 * DefaultStyle.dp) Layout.preferredHeight: Utils.getSizeWithScreenRatio(24)
colorizationColor: DefaultStyle.main2_500main colorizationColor: DefaultStyle.main2_500_main
} }
} }
} }

View file

@ -67,6 +67,7 @@ FocusScope{
Layout.preferredHeight: Math.round(24 * DefaultStyle.dp) Layout.preferredHeight: Math.round(24 * DefaultStyle.dp)
style: ButtonStyle.noBackground style: ButtonStyle.noBackground
icon.source: AppIcons.info icon.source: AppIcons.info
popUpTitle: mainItem.label
popup.contentItem: Text { popup.contentItem: Text {
text: mainItem.tooltip text: mainItem.tooltip
} }
@ -85,7 +86,7 @@ FocusScope{
TemporaryText { TemporaryText {
id: errorText id: errorText
anchors.top: contentItem.bottom anchors.top: contentItem.bottom
color: DefaultStyle.danger_500main color: DefaultStyle.danger_500_main
} }
} }

View file

@ -6,6 +6,7 @@ import QtQuick.Effects
import Linphone import Linphone
import UtilsCpp import UtilsCpp
import SettingsCpp import SettingsCpp
import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils
import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
FocusScope { FocusScope {
@ -22,16 +23,20 @@ FocusScope {
spacing: 0 spacing: 0
anchors.fill: parent anchors.fill: parent
RowLayout { RowLayout {
spacing: Math.round(10 * DefaultStyle.dp) spacing: Utils.getSizeWithScreenRatio(10)
Button { Button {
id: backGroupCallButton id: backGroupCallButton
style: ButtonStyle.noBackgroundOrange style: ButtonStyle.noBackgroundOrange
icon.source: AppIcons.leftArrow icon.source: AppIcons.leftArrow
Layout.preferredWidth: Math.round(24 * DefaultStyle.dp) Layout.preferredWidth: Utils.getSizeWithScreenRatio(30)
Layout.preferredHeight: Math.round(24 * DefaultStyle.dp) Layout.preferredHeight: Utils.getSizeWithScreenRatio(30)
icon.width: Utils.getSizeWithScreenRatio(24)
icon.height: Utils.getSizeWithScreenRatio(24)
KeyNavigation.down: groupName KeyNavigation.down: groupName
KeyNavigation.right: groupCallButton KeyNavigation.right: groupCallButton
KeyNavigation.left: groupCallButton KeyNavigation.left: groupCallButton
//: Return
Accessible.name: qsTr("return_accessible_name")
onClicked: { onClicked: {
mainItem.returnRequested() mainItem.returnRequested()
} }
@ -41,7 +46,7 @@ FocusScope {
color: DefaultStyle.main1_500_main color: DefaultStyle.main1_500_main
maximumLineCount: 1 maximumLineCount: 1
font { font {
pixelSize: Math.round(18 * DefaultStyle.dp) pixelSize: Utils.getSizeWithScreenRatio(18)
weight: Typography.h4.weight weight: Typography.h4.weight
} }
Layout.fillWidth: true Layout.fillWidth: true
@ -49,7 +54,7 @@ FocusScope {
SmallButton { SmallButton {
id: groupCallButton id: groupCallButton
enabled: mainItem.selectedParticipantsCount.length != 0 enabled: mainItem.selectedParticipantsCount.length != 0
Layout.rightMargin: Math.round(21 * DefaultStyle.dp) Layout.rightMargin: Utils.getSizeWithScreenRatio(21)
text: mainItem.createGroupButtonText text: mainItem.createGroupButtonText
style: ButtonStyle.main style: ButtonStyle.main
KeyNavigation.down: addParticipantsLayout KeyNavigation.down: addParticipantsLayout
@ -62,8 +67,8 @@ FocusScope {
} }
RowLayout { RowLayout {
spacing: 0 spacing: 0
Layout.topMargin: Math.round(18 * DefaultStyle.dp) Layout.topMargin: Utils.getSizeWithScreenRatio(18)
Layout.rightMargin: Math.round(38 * DefaultStyle.dp) Layout.rightMargin: Utils.getSizeWithScreenRatio(38)
Text { Text {
font.pixelSize: Typography.p2.pixelSize font.pixelSize: Typography.p2.pixelSize
font.weight: Typography.p2.weight font.weight: Typography.p2.weight
@ -74,8 +79,8 @@ FocusScope {
Layout.fillWidth: true Layout.fillWidth: true
} }
Text { Text {
font.pixelSize: Math.round(12 * DefaultStyle.dp) font.pixelSize: Utils.getSizeWithScreenRatio(12)
font.weight: Math.round(300 * DefaultStyle.dp) font.weight: Utils.getSizeWithScreenRatio(300)
//: "Requis" //: "Requis"
text: qsTr("required") text: qsTr("required")
} }
@ -83,16 +88,17 @@ FocusScope {
TextField { TextField {
id: groupName id: groupName
Layout.fillWidth: true Layout.fillWidth: true
Layout.rightMargin: Math.round(38 * DefaultStyle.dp) Layout.rightMargin: Utils.getSizeWithScreenRatio(38)
Layout.preferredHeight: Math.round(49 * DefaultStyle.dp) Layout.preferredHeight: Utils.getSizeWithScreenRatio(49)
focus: true focus: true
KeyNavigation.down: addParticipantsLayout //participantList.count > 0 ? participantList : searchbar KeyNavigation.down: addParticipantsLayout //participantList.count > 0 ? participantList : searchbar
Accessible.name: qsTr("group_start_dialog_subject_hint")
} }
AddParticipantsForm { AddParticipantsForm {
id: addParticipantsLayout id: addParticipantsLayout
Layout.fillWidth: true Layout.fillWidth: true
Layout.fillHeight: true Layout.fillHeight: true
Layout.topMargin: Math.round(15 * DefaultStyle.dp) Layout.topMargin: Utils.getSizeWithScreenRatio(15)
onSelectedParticipantsCountChanged: mainItem.selectedParticipantsCount = selectedParticipantsCount onSelectedParticipantsCountChanged: mainItem.selectedParticipantsCount = selectedParticipantsCount
focus: true focus: true

View file

@ -3,6 +3,8 @@ import QtQuick.Layouts
import QtQuick.Controls.Basic as Control import QtQuick.Controls.Basic as Control
import QtQuick.Effects import QtQuick.Effects
import Linphone import Linphone
import CustomControls 1.0
import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils
Control.TabBar { Control.TabBar {
id: mainItem id: mainItem
@ -20,7 +22,7 @@ Control.TabBar {
Rectangle { Rectangle {
id: barBG id: barBG
height: Math.round(4 * DefaultStyle.dp) height: Utils.getSizeWithScreenRatio(4)
color: DefaultStyle.grey_200 color: DefaultStyle.grey_200
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
width: parent.width width: parent.width
@ -49,9 +51,11 @@ Control.TabBar {
required property string modelData required property string modelData
required property int index required property int index
property bool shadowEnabled: activeFocus || hovered property bool shadowEnabled: activeFocus || hovered
property bool keyboardFocus: FocusHelper.keyboardFocus
width: implicitWidth width: implicitWidth
activeFocusOnTab: true activeFocusOnTab: true
hoverEnabled: true hoverEnabled: true
Accessible.name: modelData
ToolTip { ToolTip {
visible: tabText.truncated && hovered visible: tabText.truncated && hovered
delay: 1000 delay: 1000
@ -65,27 +69,35 @@ Control.TabBar {
background: Item { background: Item {
anchors.fill: parent anchors.fill: parent
visible: mainItem.currentIndex === index || tabButton.hovered
Rectangle { Rectangle {
id: tabBackground id: tabBackground
height: Math.round(5 * DefaultStyle.dp) visible: mainItem.currentIndex === index || tabButton.hovered
height: Utils.getSizeWithScreenRatio(5)
color: mainItem.currentIndex === index ? DefaultStyle.main1_500_main : DefaultStyle.main2_400 color: mainItem.currentIndex === index ? DefaultStyle.main1_500_main : DefaultStyle.main2_400
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
} }
MultiEffect { MultiEffect {
visible: (mainItem.currentIndex === index || tabButton.hovered) && tabButton.shadowEnabled
enabled: tabButton.shadowEnabled enabled: tabButton.shadowEnabled
anchors.fill: tabBackground anchors.fill: tabBackground
source: tabBackground source: tabBackground
visible: tabButton.shadowEnabled
// Crash : https://bugreports.qt.io/browse/QTBUG-124730 // Crash : https://bugreports.qt.io/browse/QTBUG-124730
shadowEnabled: true //mainItem.shadowEnabled shadowEnabled: true //mainItem.shadowEnabled
shadowColor: DefaultStyle.grey_1000 shadowColor: DefaultStyle.grey_1000
shadowBlur: 0.1 shadowBlur: 0.1
shadowOpacity: tabButton.shadowEnabled ? 0.5 : 0.0 shadowOpacity: tabButton.shadowEnabled ? 0.5 : 0.0
} }
Rectangle{
id: borderBackground
visible: tabButton.keyboardFocus
height: tabButton.height
width: tabButton.width
color: "transparent"
border.color: "black"
border.width: 3
}
} }
contentItem: Text { contentItem: Text {
@ -100,7 +112,7 @@ Control.TabBar {
elide: Text.ElideRight elide: Text.ElideRight
maximumLineCount: 1 maximumLineCount: 1
text: modelData text: modelData
bottomPadding: Math.round(5 * DefaultStyle.dp) bottomPadding: Utils.getSizeWithScreenRatio(5)
} }
} }
} }

View file

@ -2,14 +2,15 @@ import QtQuick
import QtQuick.Layouts import QtQuick.Layouts
import QtQuick.Controls.Basic as Control import QtQuick.Controls.Basic as Control
import QtQuick.Effects import QtQuick.Effects
import Linphone import Linphone
import SettingsCpp import SettingsCpp
import CustomControls 1.0
import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils
Control.TabBar { Control.TabBar {
id: mainItem id: mainItem
//spacing: Math.round(32 * DefaultStyle.dp) //spacing: Utils.getSizeWithScreenRatio(32)
topPadding: Math.round(36 * DefaultStyle.dp) topPadding: Utils.getSizeWithScreenRatio(36)
property var model property var model
readonly property alias cornerRadius: bottomLeftCorner.radius readonly property alias cornerRadius: bottomLeftCorner.radius
@ -38,10 +39,10 @@ Control.TabBar {
component UnreadNotification: Rectangle { component UnreadNotification: Rectangle {
property int unread: 0 property int unread: 0
visible: unread > 0 visible: unread > 0
width: Math.round(15 * DefaultStyle.dp) width: Utils.getSizeWithScreenRatio(15)
height: Math.round(15 * DefaultStyle.dp) height: Utils.getSizeWithScreenRatio(15)
radius: width/2 radius: width/2
color: DefaultStyle.danger_500main color: DefaultStyle.danger_500_main
Text{ Text{
id: unreadCount id: unreadCount
anchors.fill: parent anchors.fill: parent
@ -77,7 +78,7 @@ Control.TabBar {
id: bottomLeftCorner id: bottomLeftCorner
anchors.fill: parent anchors.fill: parent
color: DefaultStyle.main1_500_main color: DefaultStyle.main1_500_main
radius: Math.round(25 * DefaultStyle.dp) radius: Utils.getSizeWithScreenRatio(25)
} }
Rectangle { Rectangle {
color: DefaultStyle.main1_500_main color: DefaultStyle.main1_500_main
@ -100,10 +101,12 @@ Control.TabBar {
id: tabButton id: tabButton
width: mainItem.width width: mainItem.width
height: visible && buttonIcon.isImageReady ? undefined : 0 height: visible && buttonIcon.isImageReady ? undefined : 0
bottomInset: Math.round(32 * DefaultStyle.dp) bottomInset: Utils.getSizeWithScreenRatio(32)
topInset: Math.round(32 * DefaultStyle.dp) topInset: Utils.getSizeWithScreenRatio(32)
hoverEnabled: true hoverEnabled: true
visible: modelData?.visible != undefined ? modelData.visible : true visible: modelData?.visible != undefined ? modelData.visible : true
text: modelData.accessibilityLabel
property bool keyboardFocus: FocusHelper.keyboardFocus
UnreadNotification { UnreadNotification {
unread: !defaultAccount unread: !defaultAccount
? -1 ? -1
@ -113,7 +116,7 @@ Control.TabBar {
? defaultAccount.core?.unreadMessageNotifications || -1 ? defaultAccount.core?.unreadMessageNotifications || -1
: 0 : 0
anchors.right: parent.right anchors.right: parent.right
anchors.rightMargin: Math.round(15 * DefaultStyle.dp) anchors.rightMargin: Utils.getSizeWithScreenRatio(15)
anchors.top: parent.top anchors.top: parent.top
} }
MouseArea { MouseArea {
@ -121,10 +124,19 @@ Control.TabBar {
cursorShape: tabButton.hovered ? Qt.PointingHandCursor : Qt.ArrowCursor cursorShape: tabButton.hovered ? Qt.PointingHandCursor : Qt.ArrowCursor
acceptedButtons: Qt.NoButton acceptedButtons: Qt.NoButton
} }
background: Rectangle{
// Black border for keyboard navigation
visible: tabButton.keyboardFocus
color: "transparent"
border.color: DefaultStyle.main2_900
border.width: Utils.getSizeWithScreenRatio(3)
radius: Utils.getSizeWithScreenRatio(5)
anchors.fill: tabButton
}
contentItem: ColumnLayout { contentItem: ColumnLayout {
EffectImage { EffectImage {
id: buttonIcon id: buttonIcon
property real buttonSize: mainItem.currentIndex !== index && tabButton.hovered ? Math.round(26 * DefaultStyle.dp) : Math.round(24 * DefaultStyle.dp) property real buttonSize: mainItem.currentIndex !== index && tabButton.hovered ? Utils.getSizeWithScreenRatio(26) : Utils.getSizeWithScreenRatio(24)
imageSource: mainItem.currentIndex === index ? modelData.selectedIcon : modelData.icon imageSource: mainItem.currentIndex === index ? modelData.selectedIcon : modelData.icon
Layout.preferredWidth: buttonSize Layout.preferredWidth: buttonSize
Layout.preferredHeight: buttonSize Layout.preferredHeight: buttonSize
@ -139,19 +151,19 @@ Control.TabBar {
text: modelData.label text: modelData.label
font { font {
weight: mainItem.currentIndex === index weight: mainItem.currentIndex === index
? Math.round(800 * DefaultStyle.dp) ? Utils.getSizeWithScreenRatio(800)
: tabButton.hovered : tabButton.hovered
? Math.round(600 * DefaultStyle.dp) ? Utils.getSizeWithScreenRatio(600)
: Math.round(400 * DefaultStyle.dp) : Utils.getSizeWithScreenRatio(400)
pixelSize: Math.round(11 * DefaultStyle.dp) pixelSize: Utils.getSizeWithScreenRatio(11)
} }
color: DefaultStyle.grey_0 color: DefaultStyle.grey_0
Layout.fillWidth: true Layout.fillWidth: true
Layout.preferredHeight: txtMeter.height Layout.preferredHeight: txtMeter.height
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
leftPadding: Math.round(3 * DefaultStyle.dp) leftPadding: Utils.getSizeWithScreenRatio(3)
rightPadding: Math.round(3 * DefaultStyle.dp) rightPadding: Utils.getSizeWithScreenRatio(3)
} }
} }
TextMetrics { TextMetrics {
@ -159,15 +171,13 @@ Control.TabBar {
text: modelData.label text: modelData.label
font: buttonText.font font: buttonText.font
Component.onCompleted: { Component.onCompleted: {
font.weight = Math.round(800 * DefaultStyle.dp) font.weight = Utils.getSizeWithScreenRatio(800)
mainItem.implicitWidth = Math.max(mainItem.implicitWidth, advanceWidth + buttonIcon.buttonSize) mainItem.implicitWidth = Math.max(mainItem.implicitWidth, advanceWidth + buttonIcon.buttonSize)
} }
} }
onClicked: { onClicked: {
mainItem.setCurrentIndex(TabBar.index) mainItem.setCurrentIndex(TabBar.index)
} }
background: Item {}
} }
} }
} }

View file

@ -15,7 +15,7 @@ ListView {
property SearchBar searchBar property SearchBar searchBar
property bool loading: false property bool loading: false
property string searchText: searchBar?.text property string searchText: searchBar?.text
property real busyIndicatorSize: Math.round(60 * DefaultStyle.dp) property real busyIndicatorSize: Utils.getSizeWithScreenRatio(60)
signal resultsReceived signal resultsReceived
@ -34,14 +34,14 @@ ListView {
onFilterTextChanged: maxDisplayItems = initialDisplayItems onFilterTextChanged: maxDisplayItems = initialDisplayItems
initialDisplayItems: Math.max( initialDisplayItems: Math.max(
20, 20,
2 * mainItem.height / (Math.round(56 * DefaultStyle.dp))) 2 * mainItem.height / (Utils.getSizeWithScreenRatio(56)))
displayItemsStep: 3 * initialDisplayItems / 2 displayItemsStep: 3 * initialDisplayItems / 2
onModelReset: { onModelReset: {
mainItem.resultsReceived() mainItem.resultsReceived()
} }
} }
flickDeceleration: 10000 flickDeceleration: 10000
spacing: Math.round(10 * DefaultStyle.dp) spacing: Utils.getSizeWithScreenRatio(10)
Keys.onPressed: event => { Keys.onPressed: event => {
if (event.key == Qt.Key_Escape) { if (event.key == Qt.Key_Escape) {
@ -122,20 +122,20 @@ ListView {
property int lastMouseContainsIndex: -1 property int lastMouseContainsIndex: -1
delegate: FocusScope { delegate: FocusScope {
width: mainItem.width width: mainItem.width
height: Math.round(56 * DefaultStyle.dp) height: Utils.getSizeWithScreenRatio(56)
RowLayout { RowLayout {
z: 1 z: 1
anchors.fill: parent anchors.fill: parent
anchors.leftMargin: Math.round(10 * DefaultStyle.dp) anchors.leftMargin: Utils.getSizeWithScreenRatio(10)
spacing: Math.round(10 * DefaultStyle.dp) spacing: Utils.getSizeWithScreenRatio(10)
Avatar { Avatar {
id: historyAvatar id: historyAvatar
property var contactObj: UtilsCpp.findFriendByAddress(modelData.core.remoteAddress) property var contactObj: UtilsCpp.findFriendByAddress(modelData.core.remoteAddress)
contact: contactObj?.value || null contact: contactObj?.value || null
displayNameVal: modelData.core.displayName displayNameVal: modelData.core.displayName
secured: securityLevel === LinphoneEnums.SecurityLevel.EndToEndEncryptedAndVerified secured: securityLevel === LinphoneEnums.SecurityLevel.EndToEndEncryptedAndVerified
width: Math.round(45 * DefaultStyle.dp) width: Utils.getSizeWithScreenRatio(45)
height: Math.round(45 * DefaultStyle.dp) height: Utils.getSizeWithScreenRatio(45)
isConference: modelData.core.isConference isConference: modelData.core.isConference
shadowEnabled: false shadowEnabled: false
asynchronous: false asynchronous: false
@ -143,7 +143,7 @@ ListView {
ColumnLayout { ColumnLayout {
Layout.fillHeight: true Layout.fillHeight: true
Layout.fillWidth: true Layout.fillWidth: true
spacing: Math.round(5 * DefaultStyle.dp) spacing: Utils.getSizeWithScreenRatio(5)
Text { Text {
Layout.fillWidth: true Layout.fillWidth: true
maximumLineCount: 1 maximumLineCount: 1
@ -154,7 +154,7 @@ ListView {
} }
} }
RowLayout { RowLayout {
spacing: Math.round(6 * DefaultStyle.dp) spacing: Utils.getSizeWithScreenRatio(6)
EffectImage { EffectImage {
id: statusIcon id: statusIcon
imageSource: modelData.core.status === LinphoneEnums.CallStatus.Declined imageSource: modelData.core.status === LinphoneEnums.CallStatus.Declined
@ -170,9 +170,9 @@ ListView {
=== LinphoneEnums.CallStatus.Aborted === LinphoneEnums.CallStatus.Aborted
|| modelData.core.status || modelData.core.status
=== LinphoneEnums.CallStatus.EarlyAborted === LinphoneEnums.CallStatus.EarlyAborted
|| modelData.core.status === LinphoneEnums.CallStatus.Missed ? DefaultStyle.danger_500main : modelData.core.isOutgoing ? DefaultStyle.info_500_main : DefaultStyle.success_500main || modelData.core.status === LinphoneEnums.CallStatus.Missed ? DefaultStyle.danger_500_main : modelData.core.isOutgoing ? DefaultStyle.info_500_main : DefaultStyle.success_500_main
Layout.preferredWidth: Math.round(12 * DefaultStyle.dp) Layout.preferredWidth: Utils.getSizeWithScreenRatio(12)
Layout.preferredHeight: Math.round(12 * DefaultStyle.dp) Layout.preferredHeight: Utils.getSizeWithScreenRatio(12)
transform: Rotation { transform: Rotation {
angle: modelData.core.isOutgoing angle: modelData.core.isOutgoing
&& (modelData.core.status === LinphoneEnums.CallStatus.Declined && (modelData.core.status === LinphoneEnums.CallStatus.Declined
@ -191,8 +191,8 @@ ListView {
// text: modelData.core.date // text: modelData.core.date
text: UtilsCpp.formatDate(modelData.core.date) text: UtilsCpp.formatDate(modelData.core.date)
font { font {
pixelSize: Math.round(12 * DefaultStyle.dp) pixelSize: Utils.getSizeWithScreenRatio(12)
weight: Math.round(300 * DefaultStyle.dp) weight: Utils.getSizeWithScreenRatio(300)
} }
} }
} }
@ -203,6 +203,8 @@ ListView {
focus: true focus: true
activeFocusOnTab: false activeFocusOnTab: false
asynchronous: false asynchronous: false
//: Call %1
Accessible.name: qsTr("call_name_accessible_button").arg(historyAvatar.displayNameVal)
onClicked: { onClicked: {
if (modelData.core.isConference) { if (modelData.core.isConference) {
var callsWindow = UtilsCpp.getCallsWindow() var callsWindow = UtilsCpp.getCallsWindow()
@ -228,7 +230,7 @@ ListView {
Rectangle { Rectangle {
anchors.fill: parent anchors.fill: parent
opacity: 0.7 opacity: 0.7
radius: Math.round(8 * DefaultStyle.dp) radius: Utils.getSizeWithScreenRatio(8)
color: mainItem.currentIndex color: mainItem.currentIndex
=== index ? DefaultStyle.main2_200 : DefaultStyle.main2_100 === index ? DefaultStyle.main2_200 : DefaultStyle.main2_100
visible: mainItem.lastMouseContainsIndex === index visible: mainItem.lastMouseContainsIndex === index

View file

@ -24,9 +24,12 @@ ListView {
property string currentRemoteAddress: AppCpp.calls.currentCall ? AppCpp.calls.currentCall.core.remoteAddress : "" property string currentRemoteAddress: AppCpp.calls.currentCall ? AppCpp.calls.currentCall.core.remoteAddress : ""
delegate: RowLayout { delegate: RowLayout {
id: callInformationItem
spacing: Math.round(8 * DefaultStyle.dp) spacing: Math.round(8 * DefaultStyle.dp)
width: mainItem.width width: mainItem.width
height: Math.round(45 * DefaultStyle.dp) height: Math.round(45 * DefaultStyle.dp)
property var remoteNameObj: UtilsCpp.getDisplayName(modelData.core.remoteAddress)
property var callName : modelData.core.isConference ? modelData.core.conference.core.subject : remoteNameObj ? remoteNameObj.value : ""
Avatar { Avatar {
id: delegateAvatar id: delegateAvatar
Layout.preferredWidth: Math.round(45 * DefaultStyle.dp) Layout.preferredWidth: Math.round(45 * DefaultStyle.dp)
@ -41,9 +44,7 @@ ListView {
Text { Text {
id: delegateName id: delegateName
property var remoteNameObj: UtilsCpp.getDisplayName(modelData.core.remoteAddress) property var remoteNameObj: UtilsCpp.getDisplayName(modelData.core.remoteAddress)
text: modelData.core.isConference text: callInformationItem.callName
? modelData.core.conference.core.subject
: remoteNameObj ? remoteNameObj.value : ""
font.pixelSize: Math.round(14 * DefaultStyle.dp) font.pixelSize: Math.round(14 * DefaultStyle.dp)
Layout.fillWidth: true Layout.fillWidth: true
maximumLineCount: 1 maximumLineCount: 1
@ -79,6 +80,8 @@ ListView {
onClicked: { onClicked: {
mainItem.transferCallToAnotherRequested(modelData) mainItem.transferCallToAnotherRequested(modelData)
} }
//: Transfer call %1
Accessible.name: qsTr("transfer_call_name_accessible_name").arg(callInformationItem.callName)
} }
Button { Button {
id: pausingButton id: pausingButton
@ -91,7 +94,7 @@ ListView {
topPadding: Math.round(5 * DefaultStyle.dp) topPadding: Math.round(5 * DefaultStyle.dp)
bottomPadding: Math.round(5 * DefaultStyle.dp) bottomPadding: Math.round(5 * DefaultStyle.dp)
property bool pausedByUser: modelData.core.state === LinphoneEnums.CallState.Paused property bool pausedByUser: modelData.core.state === LinphoneEnums.CallState.Paused
color: pausedByUser ? DefaultStyle.success_500main : DefaultStyle.grey_500 color: pausedByUser ? DefaultStyle.success_500_main : DefaultStyle.grey_500
contentImageColor: DefaultStyle.grey_0 contentImageColor: DefaultStyle.grey_0
KeyNavigation.right: endCallButton KeyNavigation.right: endCallButton
KeyNavigation.left: endCallButton KeyNavigation.left: endCallButton
@ -104,6 +107,12 @@ ListView {
text: pausingButton.text text: pausingButton.text
font.bold: true font.bold: true
} }
Accessible.name: (pausedByUser ?
//: Resume %1 call
qsTr("resume_call_name_accessible_name") :
//: Pause %1 call
qsTr("pause_call_name_accessible_name")
).arg(callInformationItem.callName)
} }
SmallButton { SmallButton {
id: endCallButton id: endCallButton
@ -124,6 +133,8 @@ ListView {
text: endCallButton.text text: endCallButton.text
font.bold: true font.bold: true
} }
//: End %1 call
Accessible.name: qsTr("end_call_name_accessible_name").arg(callInformationItem.callName)
} }
} }
} }

View file

@ -141,7 +141,7 @@ ListView {
id: background id: background
anchors.fill: parent anchors.fill: parent
radius: width/2 radius: width/2
color: DefaultStyle.danger_500main color: DefaultStyle.danger_500_main
Text{ Text{
anchors.fill: parent anchors.fill: parent
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
@ -295,7 +295,7 @@ ListView {
RowLayout { RowLayout {
Item{Layout.fillWidth: true} Item{Layout.fillWidth: true}
Text { Text {
color: DefaultStyle.main2_500main color: DefaultStyle.main2_500_main
text: modelData ? UtilsCpp.formatDate(modelData.core.lastUpdatedTime, true, false) : "" text: modelData ? UtilsCpp.formatDate(modelData.core.lastUpdatedTime, true, false) : ""
font { font {
pixelSize: Typography.p3.pixelSize pixelSize: Typography.p3.pixelSize

View file

@ -73,7 +73,7 @@ Control.Control {
width: implicitWidth width: implicitWidth
x: mapToItem(this, chatBubble.x, chatBubble.y).x x: mapToItem(this, chatBubble.x, chatBubble.y).x
text: mainItem.chatMessage.core.fromName text: mainItem.chatMessage.core.fromName
color: DefaultStyle.main2_500main color: DefaultStyle.main2_500_main
font { font {
pixelSize: Typography.p4.pixelSize pixelSize: Typography.p4.pixelSize
weight: Typography.p4.weight weight: Typography.p4.weight
@ -87,7 +87,7 @@ Control.Control {
Layout.alignment: mainItem.isRemoteMessage ? Qt.AlignLeft: Qt.AlignRight Layout.alignment: mainItem.isRemoteMessage ? Qt.AlignLeft: Qt.AlignRight
EffectImage { EffectImage {
imageSource: AppIcons.forward imageSource: AppIcons.forward
colorizationColor: DefaultStyle.main2_500main colorizationColor: DefaultStyle.main2_500_main
Layout.preferredWidth: Math.round(12 * DefaultStyle.dp) Layout.preferredWidth: Math.round(12 * DefaultStyle.dp)
Layout.preferredHeight: Math.round(12 * DefaultStyle.dp) Layout.preferredHeight: Math.round(12 * DefaultStyle.dp)
} }
@ -115,7 +115,7 @@ Control.Control {
Layout.alignment: mainItem.isRemoteMessage ? Qt.AlignLeft : Qt.AlignRight Layout.alignment: mainItem.isRemoteMessage ? Qt.AlignLeft : Qt.AlignRight
EffectImage { EffectImage {
imageSource: AppIcons.reply imageSource: AppIcons.reply
colorizationColor: DefaultStyle.main2_500main colorizationColor: DefaultStyle.main2_500_main
Layout.preferredWidth: Math.round(12 * DefaultStyle.dp) Layout.preferredWidth: Math.round(12 * DefaultStyle.dp)
Layout.preferredHeight: Math.round(12 * DefaultStyle.dp) Layout.preferredHeight: Math.round(12 * DefaultStyle.dp)
} }
@ -270,7 +270,7 @@ Control.Control {
Text { Text {
id: ephemeralTime id: ephemeralTime
visible: mainItem.chatMessage.core.isEphemeral visible: mainItem.chatMessage.core.isEphemeral
color: DefaultStyle.main2_500main color: DefaultStyle.main2_500_main
text: UtilsCpp.formatDuration(mainItem.chatMessage.core.ephemeralDuration * 1000) text: UtilsCpp.formatDuration(mainItem.chatMessage.core.ephemeralDuration * 1000)
font { font {
pixelSize: Typography.p3.pixelSize pixelSize: Typography.p3.pixelSize
@ -280,7 +280,7 @@ Control.Control {
EffectImage { EffectImage {
visible: mainItem.chatMessage.core.isEphemeral visible: mainItem.chatMessage.core.isEphemeral
imageSource: AppIcons.clockCountDown imageSource: AppIcons.clockCountDown
colorizationColor: DefaultStyle.main2_500main colorizationColor: DefaultStyle.main2_500_main
Layout.preferredWidth: visible ? 14 * DefaultStyle.dp : 0 Layout.preferredWidth: visible ? 14 * DefaultStyle.dp : 0
Layout.preferredHeight: visible ? 14 * DefaultStyle.dp : 0 Layout.preferredHeight: visible ? 14 * DefaultStyle.dp : 0
} }
@ -292,7 +292,7 @@ Control.Control {
Text { Text {
Layout.alignment: Qt.AlignVCenter Layout.alignment: Qt.AlignVCenter
text: UtilsCpp.formatDate(mainItem.chatMessage.core.timestamp, true, false, "dd/MM") text: UtilsCpp.formatDate(mainItem.chatMessage.core.timestamp, true, false, "dd/MM")
color: DefaultStyle.main2_500main color: DefaultStyle.main2_500_main
font { font {
pixelSize: Typography.p3.pixelSize pixelSize: Typography.p3.pixelSize
weight: Typography.p3.weight weight: Typography.p3.weight

View file

@ -71,7 +71,7 @@ ColumnLayout {
conferenceInfo.state == LinphoneEnums.ConferenceInfoState.Updated ? conferenceInfo.state == LinphoneEnums.ConferenceInfoState.Updated ?
DefaultStyle.warning_600 : DefaultStyle.warning_600 :
conferenceInfo.state == LinphoneEnums.ConferenceInfoState.Cancelled ? conferenceInfo.state == LinphoneEnums.ConferenceInfoState.Cancelled ?
DefaultStyle.danger_500main : DefaultStyle.danger_500_main :
DefaultStyle.main2_600 DefaultStyle.main2_600
} }
@ -109,7 +109,7 @@ ColumnLayout {
Layout.fillWidth: true Layout.fillWidth: true
// Layout.preferredWidth: advancedWidth // Layout.preferredWidth: advancedWidth
text: conferenceInfo.dateTime.toLocaleString(Qt.locale(), "ddd") text: conferenceInfo.dateTime.toLocaleString(Qt.locale(), "ddd")
color: DefaultStyle.main2_500main color: DefaultStyle.main2_500_main
font { font {
pixelSize: Typography.p4.pixelSize pixelSize: Typography.p4.pixelSize
weight: Typography.p4.weight weight: Typography.p4.weight
@ -161,7 +161,7 @@ ColumnLayout {
Text { Text {
text: conferenceInfo.dateTime.toLocaleString(Qt.locale(), "dddd d MMMM yyyy") text: conferenceInfo.dateTime.toLocaleString(Qt.locale(), "dddd d MMMM yyyy")
font: Typography.p4 font: Typography.p4
color: DefaultStyle.main2_500main color: DefaultStyle.main2_500_main
} }
Text { Text {
//: from %1 to %2 (UTC%3) //: from %1 to %2 (UTC%3)
@ -171,14 +171,14 @@ ColumnLayout {
text: qsTr("").arg( text: qsTr("").arg(
conferenceInfo.dateTime.toLocaleString(Qt.locale(), "hh:mm")).arg( conferenceInfo.dateTime.toLocaleString(Qt.locale(), "hh:mm")).arg(
conferenceInfo.endDateTime.toLocaleString(Qt.locale(), "hh:mm")).arg(offsetFromUtc) conferenceInfo.endDateTime.toLocaleString(Qt.locale(), "hh:mm")).arg(offsetFromUtc)
color: DefaultStyle.main2_500main color: DefaultStyle.main2_500_main
font: Typography.p4 font: Typography.p4
} }
Text { Text {
text: timeRangeText text: timeRangeText
font: Typography.p4 font: Typography.p4
color: DefaultStyle.main2_500main color: DefaultStyle.main2_500_main
} }
} }
} }
@ -244,7 +244,7 @@ ColumnLayout {
wrapMode: Text.WordWrap wrapMode: Text.WordWrap
textFormat: Text.RichText textFormat: Text.RichText
font: Typography.p4 font: Typography.p4
color: DefaultStyle.main2_500main color: DefaultStyle.main2_500_main
maximumLineCount: 3 maximumLineCount: 3
elide: Text.ElideRight elide: Text.ElideRight
visible: conferenceInfo.description.length > 0 visible: conferenceInfo.description.length > 0

View file

@ -25,7 +25,7 @@ RowLayout {
id: message id: message
text: eventLogCore.eventDetails text: eventLogCore.eventDetails
font: Typography.p3 font: Typography.p3
color: eventLogCore.important ? DefaultStyle.danger_500main : DefaultStyle.main2_500main color: eventLogCore.important ? DefaultStyle.danger_500_main : DefaultStyle.main2_500_main
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
} }
@ -33,7 +33,7 @@ RowLayout {
id: date id: date
text: UtilsCpp.toDateTimeString(eventLogCore.timestamp) text: UtilsCpp.toDateTimeString(eventLogCore.timestamp)
font: Typography.p3 font: Typography.p3
color: DefaultStyle.main2_500main color: DefaultStyle.main2_500_main
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
} }

View file

@ -119,7 +119,7 @@ Item {
width: Math.round(24 * DefaultStyle.dp) width: Math.round(24 * DefaultStyle.dp)
height: Math.round(24 * DefaultStyle.dp) height: Math.round(24 * DefaultStyle.dp)
imageSource: AppIcons.playFill imageSource: AppIcons.playFill
colorizationColor: DefaultStyle.main2_0 colorizationColor: DefaultStyle.main2_000
} }
Text { Text {
z: parent.z + 1 z: parent.z + 1

View file

@ -94,7 +94,7 @@ Loader{
color: "transparent" color: "transparent"
border { border {
width: Math.round(2 * DefaultStyle.dp) width: Math.round(2 * DefaultStyle.dp)
color: mainItem.secured ? DefaultStyle.info_500_main : DefaultStyle.danger_500main color: mainItem.secured ? DefaultStyle.info_500_main : DefaultStyle.danger_500_main
} }
EffectImage { EffectImage {
x: parent.width / 7 x: parent.width / 7

View file

@ -8,24 +8,44 @@ import QtQuick.Controls.Basic as Control
import Linphone import Linphone
import UtilsCpp import UtilsCpp
import SettingsCpp import SettingsCpp
import CustomControls 1.0
import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils
import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle
Control.Control{ Control.Control{
id: mainItem id: mainItem
padding: Math.round(10 * DefaultStyle.dp) activeFocusOnTab: true
padding: Utils.getSizeWithScreenRatio(10)
property AccountGui account property AccountGui account
property color backgroundColor: DefaultStyle.grey_0 leftPadding: Utils.getSizeWithScreenRatio(8)
leftPadding: Math.round(8 * DefaultStyle.dp) rightPadding: Utils.getSizeWithScreenRatio(8)
rightPadding: Math.round(8 * DefaultStyle.dp) property var style
property bool isSelected
property bool keyboardFocus: FocusHelper.keyboardFocus
// Background properties
readonly property color defaultBackgroundColor: style?.color?.normal ?? DefaultStyle.grey_0
readonly property color hoveredBackgroundColor: style?.color?.hovered ?? defaultBackgroundColor
readonly property color selectedBackgroundColor: style?.color?.selected ?? defaultBackgroundColor
readonly property color focusedBackgroundColor: style?.color?.keybaordFocused ?? defaultBackgroundColor
// Border properties
readonly property color defaultBorderColor: style?.borderColor?.normal ?? "transparent"
readonly property color hoveredBorderColor: style?.borderColor?.hovered ?? defaultBorderColor
readonly property color selectedBorderColor: style?.borderColor?.selected ?? defaultBorderColor
readonly property color keyboardFocusedBorderColor: style?.borderColor?.keybaordFocused || DefaultStyle.main2_900
property real borderWidth: Utils.getSizeWithScreenRatio(1)
property real keyboardFocusedBorderWidth: Utils.getSizeWithScreenRatio(3)
signal avatarClicked() signal avatarClicked()
signal backgroundClicked() signal backgroundClicked()
signal edit() signal edit()
background: Rectangle { background: Rectangle {
radius: Math.round(10 * DefaultStyle.dp) radius: Utils.getSizeWithScreenRatio(10)
color: mainItem.backgroundColor color: mainItem.isSelected ? mainItem.selectedBackgroundColor : hovered ? mainItem.hoveredBackgroundColor : mainItem.defaultBackgroundColor
border.color: mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderColor : mainItem.isSelected ? mainItem.selectedBorderColor : hovered ? mainItem.hoveredBorderColor : mainItem.defaultBorderColor
border.width: mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderWidth : mainItem.borderWidth
MouseArea{ MouseArea{
id: mouseArea id: mouseArea
anchors.fill: parent anchors.fill: parent
@ -35,21 +55,39 @@ Control.Control{
contentItem: RowLayout{ contentItem: RowLayout{
spacing: 0 spacing: 0
RowLayout { RowLayout {
spacing: Math.round(10 * DefaultStyle.dp) spacing: Utils.getSizeWithScreenRatio(10)
Avatar{ Button {
id: avatar id: avatarButton
Layout.preferredWidth: Math.round(45 * DefaultStyle.dp) onClicked: mainItem.avatarClicked()
Layout.preferredHeight: Math.round(45 * DefaultStyle.dp) Layout.preferredWidth: Utils.getSizeWithScreenRatio(45)
account: mainItem.account Layout.preferredHeight: Utils.getSizeWithScreenRatio(45)
MouseArea{ color: "transparent"
contentItem: Item{
anchors.fill: parent anchors.fill: parent
onClicked: mainItem.avatarClicked() width: avatarButton.width
height: avatarButton.height
Avatar{
id: avatar
height: avatarButton.height
width: avatarButton.width
account: mainItem.account
}
Rectangle{
// Black border for keyboard navigation
visible: avatarButton.keyboardFocus
width: avatarButton.width
height: avatarButton.height
color: "transparent"
border.color: DefaultStyle.main2_900
border.width: Utils.getSizeWithScreenRatio(3)
radius: width / 2
}
} }
} }
Item { Item {
Layout.preferredWidth: Math.round(200 * DefaultStyle.dp) Layout.preferredWidth: Utils.getSizeWithScreenRatio(200)
Layout.fillHeight: true Layout.fillHeight: true
Layout.rightMargin: Math.round(10 * DefaultStyle.dp) Layout.rightMargin: Utils.getSizeWithScreenRatio(10)
ContactDescription{ ContactDescription{
id: description id: description
anchors.fill: parent anchors.fill: parent
@ -57,118 +95,26 @@ Control.Control{
} }
} }
} }
PopupButton { ContactStatusPopup{}
id: presenceAndRegistrationItem
Layout.minimumWidth: Math.round(86 * DefaultStyle.dp)
Layout.maximumWidth: Math.round(150 * DefaultStyle.dp)
Layout.preferredHeight: Math.round(24 * DefaultStyle.dp)
Layout.preferredWidth: presenceOrRegistrationText.implicitWidth + Math.round(50 * DefaultStyle.dp)
enabled: mainItem.account && mainItem.account.core.registrationState === LinphoneEnums.RegistrationState.Ok
onEnabledChanged: if(!enabled) close()
contentItem: Rectangle {
id: presenceBar
property bool isRegistered: mainItem.account?.core.registrationState === LinphoneEnums.RegistrationState.Ok
color: DefaultStyle.main2_200
radius: Math.round(15 * DefaultStyle.dp)
RowLayout {
anchors.fill: parent
Image {
id: registrationImage
sourceSize.width: Math.round(11 * DefaultStyle.dp)
sourceSize.height: Math.round(11 * DefaultStyle.dp)
smooth: false
Layout.preferredWidth: Math.round(11 * DefaultStyle.dp)
Layout.preferredHeight: Math.round(11 * DefaultStyle.dp)
source: presenceBar.isRegistered
? mainItem.account.core.presenceIcon
: mainItem.account?.core.registrationIcon || ""
Layout.leftMargin: Math.round(8 * DefaultStyle.dp)
RotationAnimator on rotation {
running: mainItem.account && mainItem.account.core.registrationState === LinphoneEnums.RegistrationState.Progress
direction: RotationAnimator.Clockwise
from: 0
to: 360
loops: Animation.Infinite
duration: 10000
}
}
Text {
id: presenceOrRegistrationText
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
visible: mainItem.account
// Test texts
// Timer{
// running: true
// interval: 1000
// repeat: true
// onTriggered: text.mode = (++text.mode) % 4
// }
font.weight: Math.round(300 * DefaultStyle.dp)
font.pixelSize: Math.round(12 * DefaultStyle.dp)
color: presenceBar.isRegistered ? mainItem.account.core.presenceColor : mainItem.account?.core.registrationColor
text: presenceBar.isRegistered ? mainItem.account.core.presenceStatus : mainItem.account?.core.humaneReadableRegistrationState
}
EffectImage {
fillMode: Image.PreserveAspectFit
imageSource: AppIcons.downArrow
colorizationColor: DefaultStyle.main2_600
Layout.preferredHeight: Math.round(14 * DefaultStyle.dp)
Layout.preferredWidth: Math.round(14 * DefaultStyle.dp)
Layout.rightMargin: 8 * DefaultStyle.dp
}
}
}
popup.contentItem: Rectangle {
implicitWidth: 280 * DefaultStyle.dp
implicitHeight: 20 * DefaultStyle.dp + (setCustomStatus.visible ? 240 * DefaultStyle.dp : setPresence.implicitHeight)
Presence {
id: setPresence
anchors.fill: parent
anchors.margins: 20 * DefaultStyle.dp
accountCore: mainItem.account.core
onSetCustomStatusClicked: {
setPresence.visible = false
setCustomStatus.visible = true
}
onIsSet: presenceAndRegistrationItem.popup.close()
}
PresenceSetCustomStatus {
id: setCustomStatus
visible: false
anchors.fill: parent
anchors.margins: 20 * DefaultStyle.dp
accountCore: mainItem.account.core
onVisibleChanged: {
if (!visible) {
setPresence.visible = true
setCustomStatus.visible = false
}
}
onIsSet: presenceAndRegistrationItem.popup.close()
}
}
}
Item{ Item{
Layout.preferredWidth: Math.round(26 * DefaultStyle.dp) Layout.preferredWidth: Utils.getSizeWithScreenRatio(26)
Layout.preferredHeight: Math.round(26 * DefaultStyle.dp) Layout.preferredHeight: Utils.getSizeWithScreenRatio(26)
Layout.fillHeight: true Layout.fillHeight: true
Layout.leftMargin: Math.round(40 * DefaultStyle.dp) Layout.leftMargin: Utils.getSizeWithScreenRatio(40)
visible: mainItem.account.core.unreadNotifications > 0 visible: mainItem.account.core.unreadNotifications > 0
Rectangle{ Rectangle{
id: unreadNotifications id: unreadNotifications
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
width: Math.round(26 * DefaultStyle.dp) width: Utils.getSizeWithScreenRatio(26)
height: Math.round(26 * DefaultStyle.dp) height: Utils.getSizeWithScreenRatio(26)
radius: width/2 radius: width/2
color: DefaultStyle.danger_500main color: DefaultStyle.danger_500_main
border.color: DefaultStyle.grey_0 border.color: DefaultStyle.grey_0
border.width: Math.round(2 * DefaultStyle.dp) border.width: Utils.getSizeWithScreenRatio(2)
Text{ Text{
id: unreadCount id: unreadCount
anchors.fill: parent anchors.fill: parent
anchors.margins: Math.round(2 * DefaultStyle.dp) anchors.margins: Utils.getSizeWithScreenRatio(2)
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
color: DefaultStyle.grey_0 color: DefaultStyle.grey_0
@ -188,10 +134,10 @@ Control.Control{
} }
} }
Voicemail { Voicemail {
Layout.leftMargin: Math.round(18 * DefaultStyle.dp) Layout.leftMargin: Utils.getSizeWithScreenRatio(18)
Layout.rightMargin: Math.round(20 * DefaultStyle.dp) Layout.rightMargin: Utils.getSizeWithScreenRatio(20)
Layout.preferredWidth: Math.round(30 * DefaultStyle.dp) Layout.preferredWidth: Utils.getSizeWithScreenRatio(30)
Layout.preferredHeight: Math.round(26 * DefaultStyle.dp) Layout.preferredHeight: Utils.getSizeWithScreenRatio(26)
scaleFactor: 0.7 scaleFactor: 0.7
showMwi: mainItem.account.core.showMwi showMwi: mainItem.account.core.showMwi
visible: mainItem.account.core.voicemailAddress.length > 0 || mainItem.account.core.showMwi visible: mainItem.account.core.voicemailAddress.length > 0 || mainItem.account.core.showMwi
@ -207,20 +153,19 @@ Control.Control{
} }
} }
Item{Layout.fillWidth: true} Item{Layout.fillWidth: true}
EffectImage { Button {
id: manageAccount id: manageAccount
imageSource: AppIcons.manageProfile style: ButtonStyle.noBackground
Layout.preferredWidth: Math.round(24 * DefaultStyle.dp) icon.source: AppIcons.manageProfile
Layout.preferredHeight: Math.round(24 * DefaultStyle.dp) Layout.preferredWidth: Utils.getSizeWithScreenRatio(30)
Layout.alignment: Qt.AlignHCenter Layout.preferredHeight: Utils.getSizeWithScreenRatio(30)
icon.width: Utils.getSizeWithScreenRatio(24)
icon.height: Utils.getSizeWithScreenRatio(24)
visible: !SettingsCpp.hideAccountSettings visible: !SettingsCpp.hideAccountSettings
width: Math.round(24 * DefaultStyle.dp) //: Account settings of %1
fillMode: Image.PreserveAspectFit Accessible.name: qsTr("account_settings_name_accessible_name")
colorizationColor: DefaultStyle.main2_500main onClicked: {
MouseArea{ mainItem.edit()
anchors.fill: parent
onClicked: mainItem.edit()
cursorShape: Qt.PointingHandCursor
} }
} }
} }

View file

@ -40,6 +40,7 @@ FocusScope {
signal clicked(var mouse) signal clicked(var mouse)
signal contactDeletionRequested(FriendGui contact) signal contactDeletionRequested(FriendGui contact)
signal containsMouseChanged(bool containsMouse) signal containsMouseChanged(bool containsMouse)
Accessible.name: displayName
MouseArea { MouseArea {
Text { Text {
@ -200,9 +201,9 @@ FocusScope {
: qsTr("contact_details_add_to_favourites") : qsTr("contact_details_add_to_favourites")
icon.source: searchResultItem.core.starred ? AppIcons.heartFill : AppIcons.heart icon.source: searchResultItem.core.starred ? AppIcons.heartFill : AppIcons.heart
spacing: Math.round(10 * DefaultStyle.dp) spacing: Math.round(10 * DefaultStyle.dp)
textColor: DefaultStyle.main2_500main textColor: DefaultStyle.main2_500_main
hoveredImageColor: searchResultItem.core.starred ? DefaultStyle.main1_700 : DefaultStyle.danger_700 hoveredImageColor: searchResultItem.core.starred ? DefaultStyle.main1_700 : DefaultStyle.danger_700
contentImageColor: searchResultItem.core.starred ? DefaultStyle.danger_500main : DefaultStyle.main2_600 contentImageColor: searchResultItem.core.starred ? DefaultStyle.danger_500_main : DefaultStyle.main2_600
onClicked: { onClicked: {
searchResultItem.core.lSetStarred( searchResultItem.core.lSetStarred(
!searchResultItem.core.starred) !searchResultItem.core.starred)
@ -215,7 +216,7 @@ FocusScope {
Layout.fillWidth: true Layout.fillWidth: true
icon.source: AppIcons.shareNetwork icon.source: AppIcons.shareNetwork
spacing: Math.round(10 * DefaultStyle.dp) spacing: Math.round(10 * DefaultStyle.dp)
textColor: DefaultStyle.main2_500main textColor: DefaultStyle.main2_500_main
onClicked: { onClicked: {
var vcard = searchResultItem.core.getVCard() var vcard = searchResultItem.core.getVCard()
var username = searchResultItem.core.givenName var username = searchResultItem.core.givenName

View file

@ -40,9 +40,9 @@ ListView {
property bool haveContacts: count > 0 property bool haveContacts: count > 0
property real sectionsPixelSize: Typography.h4.pixelSize property real sectionsPixelSize: Typography.h4.pixelSize
property real sectionsWeight: Typography.h4.weight property real sectionsWeight: Typography.h4.weight
property real sectionsSpacing: Math.round(18 * DefaultStyle.dp) property real sectionsSpacing: Utils.getSizeWithScreenRatio(18)
property real itemsRightMargin: Math.round(39 * DefaultStyle.dp) property real itemsRightMargin: Utils.getSizeWithScreenRatio(39)
property bool expanded: true property bool expanded: true
property real headerHeight: headerItem?.height property real headerHeight: headerItem?.height
@ -56,7 +56,7 @@ ListView {
highlightFollowsCurrentItem: false highlightFollowsCurrentItem: false
cacheBuffer: 400 cacheBuffer: 400
implicitHeight: contentHeight implicitHeight: contentHeight
spacing: expanded ? Math.round(4 * DefaultStyle.dp) : 0 spacing: expanded ? Utils.getSizeWithScreenRatio(4) : 0
onVisibleChanged: if (visible && !expanded) expanded = true onVisibleChanged: if (visible && !expanded) expanded = true
@ -150,7 +150,7 @@ ListView {
Item{// Do not use directly RowLayout : there is an issue where the layout doesn't update on visible Item{// Do not use directly RowLayout : there is an issue where the layout doesn't update on visible
Layout.fillWidth: true Layout.fillWidth: true
Layout.preferredHeight: mainItem.count > 0 ? headerTitleLayout.implicitHeight : 0 Layout.preferredHeight: mainItem.count > 0 ? headerTitleLayout.implicitHeight : 0
Layout.bottomMargin: Math.round(4 * DefaultStyle.dp) Layout.bottomMargin: Utils.getSizeWithScreenRatio(4)
RowLayout { RowLayout {
id: headerTitleLayout id: headerTitleLayout
anchors.fill: parent anchors.fill: parent
@ -174,6 +174,11 @@ ListView {
Layout.rightMargin: mainItem.itemsRightMargin Layout.rightMargin: mainItem.itemsRightMargin
focus: true focus: true
onClicked: mainItem.expanded = !mainItem.expanded onClicked: mainItem.expanded = !mainItem.expanded
Accessible.name: (mainItem.expanded ?
//: Shrink %1
qsTr("shrink_accessible_name") :
//: Expand %1
qsTr("expand_accessible_name")).arg(mainItem.title)
} }
} }
} }

View file

@ -0,0 +1,98 @@
import QtQuick
import QtQuick.Effects
import QtQuick.Layouts
import QtQuick.Controls.Basic as Control
import Linphone
import UtilsCpp
import SettingsCpp
import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils
import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle
PopupButton {
id: presenceAndRegistrationItem
Layout.minimumWidth: Utils.getSizeWithScreenRatio(86)
Layout.maximumWidth: Utils.getSizeWithScreenRatio(150)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(24)
Layout.preferredWidth: presenceOrRegistrationText.implicitWidth + Utils.getSizeWithScreenRatio(50)
enabled: mainItem.account && mainItem.account.core.registrationState === LinphoneEnums.RegistrationState.Ok
onEnabledChanged: if(!enabled) close()
property bool editCustomStatus : false
contentItem: Rectangle {
id: presenceBar
property bool isRegistered: mainItem.account?.core.registrationState === LinphoneEnums.RegistrationState.Ok
color: DefaultStyle.main2_200
radius: Utils.getSizeWithScreenRatio(15)
RowLayout {
anchors.fill: parent
Image {
id: registrationImage
sourceSize.width: Utils.getSizeWithScreenRatio(11)
sourceSize.height: Utils.getSizeWithScreenRatio(11)
smooth: false
Layout.preferredWidth: Utils.getSizeWithScreenRatio(11)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(11)
source: presenceBar.isRegistered
? mainItem.account.core.presenceIcon
: mainItem.account?.core.registrationIcon || ""
Layout.leftMargin: Utils.getSizeWithScreenRatio(8)
RotationAnimator on rotation {
running: mainItem.account && mainItem.account.core.registrationState === LinphoneEnums.RegistrationState.Progress
direction: RotationAnimator.Clockwise
from: 0
to: 360
loops: Animation.Infinite
duration: 10000
}
}
Text {
id: presenceOrRegistrationText
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
visible: mainItem.account
font.weight: Utils.getSizeWithScreenRatio(300)
font.pixelSize: Utils.getSizeWithScreenRatio(12)
color: presenceBar.isRegistered ? mainItem.account.core.presenceColor : mainItem.account?.core.registrationColor
text: presenceBar.isRegistered ? mainItem.account.core.presenceStatus : mainItem.account?.core.humaneReadableRegistrationState
}
EffectImage {
fillMode: Image.PreserveAspectFit
imageSource: AppIcons.downArrow
colorizationColor: DefaultStyle.main2_600
Layout.preferredHeight: Utils.getSizeWithScreenRatio(14)
Layout.preferredWidth: Utils.getSizeWithScreenRatio(14)
Layout.rightMargin: 8 * DefaultStyle.dp
}
}
}
popup.contentItem: Rectangle {
implicitWidth: Utils.getSizeWithScreenRatio(280)
implicitHeight: 20 * DefaultStyle.dp + (setCustomStatus.visible ? 240 * DefaultStyle.dp : setPresence.implicitHeight)
Presence {
id: setPresence
visible: !presenceAndRegistrationItem.editCustomStatus
anchors.fill: parent
anchors.margins: 20 * DefaultStyle.dp
accountCore: mainItem.account.core
onSetCustomStatusClicked: {
presenceAndRegistrationItem.editCustomStatus = true
}
onIsSet: presenceAndRegistrationItem.popup.close()
}
PresenceSetCustomStatus {
id: setCustomStatus
visible: presenceAndRegistrationItem.editCustomStatus
anchors.fill: parent
anchors.margins: 20 * DefaultStyle.dp
accountCore: mainItem.account.core
onVisibleChanged: {
if (!visible) {
presenceAndRegistrationItem.editCustomStatus = false
}
}
onIsSet: presenceAndRegistrationItem.popup.close()
}
}
}

View file

@ -2,6 +2,7 @@ import QtQuick
import QtQuick.Controls import QtQuick.Controls
import QtQuick.Layouts import QtQuick.Layouts
import Linphone import Linphone
import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils
import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle
ColumnLayout { ColumnLayout {
@ -11,7 +12,7 @@ ColumnLayout {
signal setCustomStatusClicked signal setCustomStatusClicked
signal isSet signal isSet
spacing: 8 * DefaultStyle.dp spacing: Utils.getSizeWithScreenRatio(8)
PresenceStatusItem { presence: LinphoneEnums.Presence.Online; accountCore: mainItem.accountCore; onClick: mainItem.isSet()} PresenceStatusItem { presence: LinphoneEnums.Presence.Online; accountCore: mainItem.accountCore; onClick: mainItem.isSet()}
PresenceStatusItem { presence: LinphoneEnums.Presence.Away; accountCore: mainItem.accountCore; onClick: mainItem.isSet()} PresenceStatusItem { presence: LinphoneEnums.Presence.Away; accountCore: mainItem.accountCore; onClick: mainItem.isSet()}
PresenceStatusItem { presence: LinphoneEnums.Presence.Busy; accountCore: mainItem.accountCore; onClick: mainItem.isSet()} PresenceStatusItem { presence: LinphoneEnums.Presence.Busy; accountCore: mainItem.accountCore; onClick: mainItem.isSet()}
@ -22,8 +23,8 @@ ColumnLayout {
spacing: 0 spacing: 0
visible: accountCore.explicitPresence != LinphoneEnums.Presence.Undefined visible: accountCore.explicitPresence != LinphoneEnums.Presence.Undefined
Layout.alignment: Qt.AlignLeft Layout.alignment: Qt.AlignLeft
Layout.topMargin: Math.round(3 * DefaultStyle.dp) Layout.topMargin: Utils.getSizeWithScreenRatio(3)
Layout.bottomMargin: Math.round(3 * DefaultStyle.dp) Layout.bottomMargin: Utils.getSizeWithScreenRatio(3)
Label { Label {
font: Typography.p1 font: Typography.p1
text: qsTr("contact_presence_reset_status") text: qsTr("contact_presence_reset_status")
@ -32,46 +33,30 @@ ColumnLayout {
Item { Item {
Layout.fillWidth: true Layout.fillWidth: true
} }
Item { Button {
width: Math.round(17 * DefaultStyle.dp) id: resetStatusItem
height: Math.round(17 * DefaultStyle.dp) style: ButtonStyle.noBackground
icon.width: Utils.getSizeWithScreenRatio(17)
MouseArea { icon.height: Utils.getSizeWithScreenRatio(17)
id: hoverArea icon.source: AppIcons.reloadArrow
anchors.fill: parent onClicked: accountCore.resetToAutomaticPresence()
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: {
accountCore.resetToAutomaticPresence()
}
}
EffectImage {
fillMode: Image.PreserveAspectFit
imageSource: AppIcons.reloadArrow
colorizationColor: hoverArea.containsMouse ? DefaultStyle.main2_800 : DefaultStyle.main2_600
anchors.fill: parent
}
} }
} }
Rectangle { HorizontalBar {
height: 1 Layout.topMargin: Utils.getSizeWithScreenRatio(8)
width: parent.width
color: DefaultStyle.main2_500main
Layout.topMargin: 8 * DefaultStyle.dp
} }
ColumnLayout { ColumnLayout {
spacing: 19 * DefaultStyle.dp spacing: Utils.getSizeWithScreenRatio(19)
RowLayout { RowLayout {
spacing: 10 * DefaultStyle.dp spacing: Utils.getSizeWithScreenRatio(10)
Layout.topMargin: Math.round(3 * DefaultStyle.dp) Layout.topMargin: Utils.getSizeWithScreenRatio(3)
Layout.alignment: Qt.AlignLeft Layout.alignment: Qt.AlignLeft
Text { Text {
font: Typography.p1 font: Typography.p1
text: accountCore.presenceNote.length > 0 ? accountCore.presenceNote : qsTr("contact_presence_custom_status") text: accountCore.presenceNote.length > 0 ? accountCore.presenceNote : qsTr("contact_presence_custom_status")
color: DefaultStyle.main2_600 color: DefaultStyle.main2_600
wrapMode: Text.WordWrap wrapMode: Text.WordWrap
Layout.preferredWidth: (accountCore.presenceNote.length == 0 ? 175 : 230) * DefaultStyle.dp Layout.preferredWidth: Utils.getSizeWithScreenRatio(accountCore.presenceNote.length == 0 ? 175 : 230)
} }
Item { Item {
Layout.fillWidth: true Layout.fillWidth: true
@ -87,7 +72,7 @@ ColumnLayout {
} }
RowLayout { RowLayout {
visible: accountCore.presenceNote.length > 0 visible: accountCore.presenceNote.length > 0
spacing: 10 * DefaultStyle.dp spacing: Utils.getSizeWithScreenRatio(10)
Item { Item {
Layout.fillWidth: true Layout.fillWidth: true
} }

View file

@ -34,7 +34,7 @@ Column {
id: statusMessage id: statusMessage
wrapMode: TextEdit.Wrap wrapMode: TextEdit.Wrap
font: Typography.p1 font: Typography.p1
color: DefaultStyle.main2_500main color: DefaultStyle.main2_500_main
Layout.fillHeight: true Layout.fillHeight: true
Layout.fillWidth: true Layout.fillWidth: true
property string previoustext: "" property string previoustext: ""

View file

@ -3,51 +3,34 @@ import QtQuick.Controls
import QtQuick.Layouts import QtQuick.Layouts
import Linphone import Linphone
import UtilsCpp import UtilsCpp
import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils
import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
Rectangle { IconLabelButton {
id: mainItem id: mainItem
property var accountCore property var accountCore
property var presence property var presence
signal click() signal click()
color: mouseArea.containsMouse ? DefaultStyle.main2_100 : "transparent" style: ButtonStyle.hoveredBackgroundBis
width: 236 * DefaultStyle.dp height: Utils.getSizeWithScreenRatio(22)
height: 22 * DefaultStyle.dp radius: Utils.getSizeWithScreenRatio(5)
radius: 5 * DefaultStyle.dp text: UtilsCpp.getPresenceStatus(presence)
textSize: Typography.p1.pixelSize
textColor: UtilsCpp.getPresenceColor(mainItem.presence)
textWeight: Typography.p1.weight
icon.width: Utils.getSizeWithScreenRatio(11)
icon.height: Utils.getSizeWithScreenRatio(11)
icon.source: UtilsCpp.getPresenceIcon(mainItem.presence)
Layout.fillWidth: true
shadowEnabled: false
contentImageColor: undefined
padding: 0
RowLayout { onClicked: {
anchors.fill: parent mainItem.accountCore.presence = mainItem.presence
spacing: 10 * DefaultStyle.dp mainItem.click()
Layout.alignment: Qt.AlignLeft
Image {
sourceSize.width: 11 * DefaultStyle.dp
sourceSize.height: 11 * DefaultStyle.dp
smooth: false
Layout.preferredWidth: 11 * DefaultStyle.dp
Layout.preferredHeight: 11 * DefaultStyle.dp
source: UtilsCpp.getPresenceIcon(mainItem.presence)
}
Text {
text: UtilsCpp.getPresenceStatus(mainItem.presence)
font: Typography.p1
horizontalAlignment: Text.AlignLeft
Layout.alignment: Qt.AlignLeft
Layout.fillWidth: true
color: UtilsCpp.getPresenceColor(mainItem.presence)
}
} }
MouseArea {
id: mouseArea
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: {
mainItem.accountCore.presence = mainItem.presence
mainItem.click()
}
}
} }

View file

@ -40,7 +40,7 @@ Rectangle{
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
font.weight: Typography.p2.weight font.weight: Typography.p2.weight
font.pixelSize: Typography.p2.pixelSize * scaleFactor font.pixelSize: Typography.p2.pixelSize * scaleFactor
color: DefaultStyle.danger_500main color: DefaultStyle.danger_500_main
text: voicemailCount >= 100 ? '99+' : voicemailCount text: voicemailCount >= 100 ? '99+' : voicemailCount
visible: showMwi && voicemailCount > 0 visible: showMwi && voicemailCount > 0
maximumLineCount: 1 maximumLineCount: 1
@ -49,7 +49,7 @@ Rectangle{
Rectangle { Rectangle {
anchors.top: parent.top anchors.top: parent.top
anchors.right: parent.right anchors.right: parent.right
color: DefaultStyle.danger_500main color: DefaultStyle.danger_500_main
visible: showMwi && voicemailCount == 0 visible: showMwi && voicemailCount == 0
width: Math.round(14 * DefaultStyle.dp) * scaleFactor width: Math.round(14 * DefaultStyle.dp) * scaleFactor
height: width height: width

View file

@ -10,7 +10,7 @@ import Linphone
Loader { Loader {
id: mainItem id: mainItem
active: visible active: visible
property var imageSource property url imageSource: ""
property var fillMode: Image.PreserveAspectFit property var fillMode: Image.PreserveAspectFit
property var colorizationColor property var colorizationColor
property real imageWidth: width property real imageWidth: width
@ -23,7 +23,7 @@ Loader {
Image { Image {
id: image id: image
visible: !effect2.effectEnabled visible: !effect2.effectEnabled
source: mainItem.imageSource ? mainItem.imageSource : "" source: mainItem.imageSource
fillMode: mainItem.fillMode fillMode: mainItem.fillMode
sourceSize.width: width sourceSize.width: width
sourceSize.height: height sourceSize.height: height

View file

@ -0,0 +1,11 @@
import QtQuick
import QtQuick.Layouts
import QtQuick.Controls
import Linphone
import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils
Rectangle{
height: 1
Layout.fillWidth: true
color: DefaultStyle.main2_500_main
}

View file

@ -146,7 +146,7 @@ ProgressBar {
spacing: mainItem.recording ? Math.round(5 * DefaultStyle.dp) : 0 spacing: mainItem.recording ? Math.round(5 * DefaultStyle.dp) : 0
EffectImage { EffectImage {
visible: mainItem.recording visible: mainItem.recording
colorizationColor: DefaultStyle.danger_500main colorizationColor: DefaultStyle.danger_500_main
imageSource: AppIcons.recordFill imageSource: AppIcons.recordFill
Layout.preferredWidth: Math.round(14 * DefaultStyle.dp) Layout.preferredWidth: Math.round(14 * DefaultStyle.dp)
Layout.preferredHeight: Math.round(14 * DefaultStyle.dp) Layout.preferredHeight: Math.round(14 * DefaultStyle.dp)

View file

@ -200,7 +200,7 @@ ListView {
Layout.preferredHeight: Math.round(19 * DefaultStyle.dp) Layout.preferredHeight: Math.round(19 * DefaultStyle.dp)
Layout.alignment: Qt.AlignCenter Layout.alignment: Qt.AlignCenter
text: day.substring(0,3) + '.' text: day.substring(0,3) + '.'
color: DefaultStyle.main2_500main color: DefaultStyle.main2_500_main
wrapMode: Text.NoWrap wrapMode: Text.NoWrap
elide: Text.ElideNone elide: Text.ElideNone
font { font {
@ -224,7 +224,7 @@ ListView {
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
text: UtilsCpp.toDateDayString(dateTime) text: UtilsCpp.toDateDayString(dateTime)
color: dayNum.isCurrentDay ? DefaultStyle.grey_0 : DefaultStyle.main2_500main color: dayNum.isCurrentDay ? DefaultStyle.grey_0 : DefaultStyle.main2_500_main
wrapMode: Text.NoWrap wrapMode: Text.NoWrap
font { font {
pixelSize: Math.round(20 * DefaultStyle.dp) pixelSize: Math.round(20 * DefaultStyle.dp)
@ -275,7 +275,7 @@ ListView {
Text { Text {
//: "Réunion annulée" //: "Réunion annulée"
text: itemDelegate.isCanceled ? qsTr("meeting_info_cancelled") : UtilsCpp.toDateHourString(dateTime) + " - " + UtilsCpp.toDateHourString(endDateTime) text: itemDelegate.isCanceled ? qsTr("meeting_info_cancelled") : UtilsCpp.toDateHourString(dateTime) + " - " + UtilsCpp.toDateHourString(endDateTime)
color: itemDelegate.isCanceled ? DefaultStyle.danger_500main : DefaultStyle.main2_500main color: itemDelegate.isCanceled ? DefaultStyle.danger_500_main : DefaultStyle.main2_500_main
font { font {
pixelSize: Typography.p1.pixelSize pixelSize: Typography.p1.pixelSize
weight: Typography.p1.weight weight: Typography.p1.weight

View file

@ -3,20 +3,24 @@ import QtQuick.Controls.Basic as Control
import QtQuick.Layouts import QtQuick.Layouts
import QtQuick.Effects import QtQuick.Effects
import Linphone import Linphone
import CustomControls 1.0
import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils
Item { Item {
id: mainItem id: mainItem
height: visible ? Utils.getSizeWithScreenRatio(50) : 0
height: visible ? Math.round(50 * DefaultStyle.dp) : 0
anchors.right: parent.right anchors.right: parent.right
anchors.left: parent.left anchors.left: parent.left
property bool keyboardOtherFocus: FocusHelper.keyboardFocus || FocusHelper.otherFocus
property string titleText property string titleText
property bool isSelected: false property bool isSelected: false
property bool shadowEnabled: mainItem.activeFocus || mouseArea.containsMouse
signal selected() signal selected()
//: %1 settings
Accessible.name: qsTr("setting_tab_accessible_name").arg(titleText)
Keys.onPressed: (event)=>{ Keys.onPressed: (event)=>{
if(event.key == Qt.Key_Space || event.key == Qt.Key_Return || event.key == Qt.Key_Enter){ if(event.key == Qt.Key_Space || event.key == Qt.Key_Return || event.key == Qt.Key_Enter){
mainItem.selected() mainItem.selected()
@ -29,29 +33,14 @@ Item {
Rectangle { Rectangle {
id: background id: background
anchors.fill: parent anchors.fill: parent
color: DefaultStyle.main2_200 color: mainItem.isSelected ? DefaultStyle.main2_200 : parent.containsMouse ? DefaultStyle.main2_100 : "transparent"
radius: Math.round(35 * DefaultStyle.dp) radius: mainItem.height / 2
visible: parent.containsMouse || isSelected || mainItem.shadowEnabled bottomRightRadius: 0
topRightRadius: 0
visible: parent.containsMouse || mainItem.isSelected || mainItem.keyboardOtherFocus
border.color: DefaultStyle.main2_900
border.width: mainItem.keyboardOtherFocus ? Utils.getSizeWithScreenRatio(3) : 0
} }
Rectangle {
id: backgroundRightFiller
anchors.right: parent.right
color: DefaultStyle.main2_200
width: Math.round(35 * DefaultStyle.dp)
height: Math.round(50 * DefaultStyle.dp)
visible: parent.containsMouse || isSelected
}
// MultiEffect {
// enabled: mainItem.shadowEnabled
// anchors.fill: background
// source: background
// visible: mainItem.shadowEnabled
// // Crash : https://bugreports.qt.io/browse/QTBUG-124730
// shadowEnabled: true //mainItem.shadowEnabled
// shadowColor: DefaultStyle.grey_1000
// shadowBlur: 0.1
// shadowOpacity: mainItem.shadowEnabled ? 0.5 : 0.0
// }
onClicked: { onClicked: {
mainItem.selected() mainItem.selected()
} }
@ -61,7 +50,7 @@ Item {
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
text: titleText text: mainItem.titleText
font: Typography.h4 font: Typography.h4
} }

View file

@ -303,7 +303,7 @@ Item {
imageWidth: Math.min(mainItem.width / 16, Math.round(20 * DefaultStyle.dp)) imageWidth: Math.min(mainItem.width / 16, Math.round(20 * DefaultStyle.dp))
imageHeight: Math.min(mainItem.width / 16, Math.round(20 * DefaultStyle.dp)) imageHeight: Math.min(mainItem.width / 16, Math.round(20 * DefaultStyle.dp))
imageSource: AppIcons.microphoneSlash imageSource: AppIcons.microphoneSlash
colorizationColor: DefaultStyle.main2_500main colorizationColor: DefaultStyle.main2_500_main
} }
} }
} }

View file

@ -6,7 +6,7 @@ import Linphone
Text { Text {
id: mainItem id: mainItem
color: DefaultStyle.danger_500main color: DefaultStyle.danger_500_main
property bool isVisible: text.length > 0 property bool isVisible: text.length > 0
function clear() { function clear() {
autoHideErrorMessage.stop() autoHideErrorMessage.stop()

View file

@ -50,11 +50,11 @@ FocusScope {
Layout.preferredWidth: Math.round(32 * DefaultStyle.dp) Layout.preferredWidth: Math.round(32 * DefaultStyle.dp)
Layout.preferredHeight: Math.round(32 * DefaultStyle.dp) Layout.preferredHeight: Math.round(32 * DefaultStyle.dp)
imageSource: modelData.imgUrl imageSource: modelData.imgUrl
colorizationColor: DefaultStyle.main2_500main colorizationColor: DefaultStyle.main2_500_main
} }
Text { Text {
text: modelData.text text: modelData.text
color: DefaultStyle.main2_500main color: DefaultStyle.main2_500_main
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
font.pixelSize: Math.round(14 * DefaultStyle.dp) font.pixelSize: Math.round(14 * DefaultStyle.dp)
Layout.fillWidth: true Layout.fillWidth: true

View file

@ -3,41 +3,47 @@ import QtQuick.Layouts
import QtQuick.Controls.Basic as Control import QtQuick.Controls.Basic as Control
import Linphone import Linphone
import ConstantsCpp 1.0 import ConstantsCpp 1.0
import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils
import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle
ColumnLayout { ColumnLayout {
id: mainItem id: mainItem
spacing: Math.round(8 * DefaultStyle.dp) spacing: Utils.getSizeWithScreenRatio(8)
FormItemLayout { FormItemLayout {
id: username id: username
Layout.preferredWidth: Math.round(346 * DefaultStyle.dp) Layout.preferredWidth: Utils.getSizeWithScreenRatio(346)
//: Nom d'utilisateur : username //: Nom d'utilisateur : username
label: qsTr("username") label: qsTr("username")
mandatory: true mandatory: true
enableErrorText: true enableErrorText: true
contentItem: TextField { contentItem: TextField {
id: usernameEdit id: usernameEdit
Layout.preferredWidth: Math.round(360 * DefaultStyle.dp) Layout.preferredWidth: Utils.getSizeWithScreenRatio(360)
Layout.preferredHeight: Math.round(49 * DefaultStyle.dp) Layout.preferredHeight: Utils.getSizeWithScreenRatio(49)
isError: username.errorTextVisible || (errorText.isVisible && text.length > 0) isError: username.errorTextVisible || (errorText.isVisible && text.length > 0)
onAccepted: passwordEdit.forceActiveFocus()
//: "%1 mandatory"
Accessible.name: qsTr("mandatory_field_accessible_name").arg(qsTr("username"))
} }
} }
Item { Item {
Layout.preferredHeight: password.implicitHeight Layout.preferredHeight: password.implicitHeight
FormItemLayout { FormItemLayout {
id: password id: password
width: Math.round(346 * DefaultStyle.dp) width: Utils.getSizeWithScreenRatio(346)
//: Mot de passe //: Mot de passe
label: qsTr("password") label: qsTr("password")
mandatory: true mandatory: true
enableErrorText: true enableErrorText: true
contentItem: TextField { contentItem: TextField {
id: passwordEdit id: passwordEdit
Layout.preferredWidth: Math.round(360 * DefaultStyle.dp) Layout.preferredWidth: Utils.getSizeWithScreenRatio(360)
Layout.preferredHeight: Math.round(49 * DefaultStyle.dp) Layout.preferredHeight: Utils.getSizeWithScreenRatio(49)
isError: password.errorTextVisible || (errorText.isVisible && text.length > 0) isError: password.errorTextVisible || (errorText.isVisible && text.length > 0)
hidden: true hidden: true
onAccepted: connectionButton.trigger()
Accessible.name: qsTr("password")
} }
TemporaryText { TemporaryText {
id: errorText id: errorText
@ -55,11 +61,12 @@ ColumnLayout {
} }
RowLayout { RowLayout {
Layout.topMargin: Math.round(7 * DefaultStyle.dp) Layout.topMargin: Utils.getSizeWithScreenRatio(7)
spacing: Math.round(29 * DefaultStyle.dp) spacing: Utils.getSizeWithScreenRatio(29)
BigButton { BigButton {
id: connectionButton id: connectionButton
style: ButtonStyle.main style: ButtonStyle.main
Accessible.name: qsTr("assistant_account_login")
contentItem: StackLayout { contentItem: StackLayout {
id: connectionButtonContent id: connectionButtonContent
currentIndex: 0 currentIndex: 0
@ -115,11 +122,6 @@ ColumnLayout {
connectionButtonContent.currentIndex = 1 connectionButtonContent.currentIndex = 1
} }
Shortcut {
sequences: ["Return", "Enter"]
onActivated: if(passwordEdit.activeFocus) connectionButton.trigger()
else if( usernameEdit.activeFocus) passwordEdit.forceActiveFocus()
}
onPressed: connectionButton.trigger() onPressed: connectionButton.trigger()
} }
SmallButton { SmallButton {

View file

@ -3,6 +3,7 @@ import QtQuick.Controls.Basic as Control
import QtQuick.Layouts import QtQuick.Layouts
import Linphone import Linphone
import SettingsCpp import SettingsCpp
import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils
ColumnLayout { ColumnLayout {
id: mainItem id: mainItem
@ -13,31 +14,31 @@ ColumnLayout {
property string microDevice: inputAudioDeviceCBox.currentText property string microDevice: inputAudioDeviceCBox.currentText
property bool ringerDevicesVisible: false property bool ringerDevicesVisible: false
property bool backgroundVisible: true property bool backgroundVisible: true
spacing: Math.round(40 * DefaultStyle.dp) spacing: Utils.getSizeWithScreenRatio(40)
RoundedPane { RoundedPane {
background.visible: mainItem.backgroundVisible background.visible: mainItem.backgroundVisible
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
height: contentItem.implicitHeight + topPadding + bottomPadding height: contentItem.implicitHeight + topPadding + bottomPadding
Layout.fillWidth: true Layout.fillWidth: true
topPadding: background.visible ? Math.round(25 * DefaultStyle.dp) : 0 topPadding: background.visible ? Utils.getSizeWithScreenRatio(25) : 0
bottomPadding: background.visible ? Math.round(25 * DefaultStyle.dp) : 0 bottomPadding: background.visible ? Utils.getSizeWithScreenRatio(25) : 0
leftPadding: background.visible ? Math.round(25 * DefaultStyle.dp) : 0 leftPadding: background.visible ? Utils.getSizeWithScreenRatio(25) : 0
rightPadding: background.visible ? Math.round(25 * DefaultStyle.dp) : 0 rightPadding: background.visible ? Utils.getSizeWithScreenRatio(25) : 0
contentItem: ColumnLayout { contentItem: ColumnLayout {
spacing: mainItem.spacing spacing: mainItem.spacing
ColumnLayout { ColumnLayout {
spacing: Math.round(12 * DefaultStyle.dp) spacing: Utils.getSizeWithScreenRatio(12)
visible: mainItem.ringerDevicesVisible visible: mainItem.ringerDevicesVisible
RowLayout { RowLayout {
spacing: Math.round(8 * DefaultStyle.dp) spacing: Utils.getSizeWithScreenRatio(8)
EffectImage { EffectImage {
imageSource: AppIcons.bellRinger imageSource: AppIcons.bellRinger
colorizationColor: DefaultStyle.main1_500_main colorizationColor: DefaultStyle.main1_500_main
Layout.preferredWidth: Math.round(24 * DefaultStyle.dp) Layout.preferredWidth: Utils.getSizeWithScreenRatio(24)
Layout.preferredHeight: Math.round(24 * DefaultStyle.dp) Layout.preferredHeight: Utils.getSizeWithScreenRatio(24)
imageWidth: Math.round(24 * DefaultStyle.dp) imageWidth: Utils.getSizeWithScreenRatio(24)
imageHeight: Math.round(24 * DefaultStyle.dp) imageHeight: Utils.getSizeWithScreenRatio(24)
} }
Text { Text {
//: Ringtone - Incoming calls //: Ringtone - Incoming calls
@ -49,28 +50,30 @@ ColumnLayout {
} }
ComboSetting { ComboSetting {
Layout.fillWidth: true Layout.fillWidth: true
Layout.topMargin: Math.round(12 * DefaultStyle.dp) Layout.topMargin: Utils.getSizeWithScreenRatio(12)
Layout.preferredWidth: parent.width Layout.preferredWidth: parent.width
entries: SettingsCpp.ringerDevices entries: SettingsCpp.ringerDevices
propertyName: "ringerDevice" propertyName: "ringerDevice"
propertyOwner: SettingsCpp propertyOwner: SettingsCpp
textRole: 'display_name' textRole: 'display_name'
//: Choose %1
Accessible.name: qsTr("choose_something_accessible_name").arg(qsTr("multimedia_settings_ringer_title"))
} }
Item { Item {
Layout.fillHeight: true Layout.fillHeight: true
} }
} }
ColumnLayout { ColumnLayout {
spacing: Math.round(12 * DefaultStyle.dp) spacing: Utils.getSizeWithScreenRatio(12)
RowLayout { RowLayout {
spacing: Math.round(8 * DefaultStyle.dp) spacing: Utils.getSizeWithScreenRatio(8)
EffectImage { EffectImage {
imageSource: AppIcons.speaker imageSource: AppIcons.speaker
colorizationColor: DefaultStyle.main1_500_main colorizationColor: DefaultStyle.main1_500_main
Layout.preferredWidth: Math.round(24 * DefaultStyle.dp) Layout.preferredWidth: Utils.getSizeWithScreenRatio(24)
Layout.preferredHeight: Math.round(24 * DefaultStyle.dp) Layout.preferredHeight: Utils.getSizeWithScreenRatio(24)
imageWidth: Math.round(24 * DefaultStyle.dp) imageWidth: Utils.getSizeWithScreenRatio(24)
imageHeight: Math.round(24 * DefaultStyle.dp) imageHeight: Utils.getSizeWithScreenRatio(24)
} }
Text { Text {
//: "Haut-parleurs" //: "Haut-parleurs"
@ -83,7 +86,7 @@ ColumnLayout {
id: outputAudioDeviceCBox id: outputAudioDeviceCBox
Layout.fillWidth: true Layout.fillWidth: true
Layout.preferredWidth: parent.width Layout.preferredWidth: parent.width
Layout.preferredHeight: Math.round(49 * DefaultStyle.dp) Layout.preferredHeight: Utils.getSizeWithScreenRatio(49)
entries: SettingsCpp.playbackDevices entries: SettingsCpp.playbackDevices
propertyName: "playbackDevice" propertyName: "playbackDevice"
propertyOwner: SettingsCpp propertyOwner: SettingsCpp
@ -95,6 +98,7 @@ ColumnLayout {
SettingsCpp.lSetPlaybackDevice(outputAudioDeviceCBox.currentValue) SettingsCpp.lSetPlaybackDevice(outputAudioDeviceCBox.currentValue)
} }
} }
Accessible.name: qsTr("choose_something_accessible_name").arg(qsTr("multimedia_settings_speaker_title"))
} }
Slider { Slider {
id: speakerVolume id: speakerVolume
@ -106,19 +110,21 @@ ColumnLayout {
if (mainItem.call) SettingsCpp.lSetPlaybackGain(value) if (mainItem.call) SettingsCpp.lSetPlaybackGain(value)
else SettingsCpp.playbackGain = value else SettingsCpp.playbackGain = value
} }
//: %1 volume
Accessible.name: qsTr("device_volume_accessible_name").arg(qsTr("multimedia_settings_speaker_title"))
} }
} }
ColumnLayout { ColumnLayout {
spacing: Math.round(12 * DefaultStyle.dp) spacing: Utils.getSizeWithScreenRatio(12)
RowLayout { RowLayout {
spacing: Math.round(8 * DefaultStyle.dp) spacing: Utils.getSizeWithScreenRatio(8)
EffectImage { EffectImage {
imageSource: AppIcons.microphone imageSource: AppIcons.microphone
colorizationColor: DefaultStyle.main1_500_main colorizationColor: DefaultStyle.main1_500_main
Layout.preferredWidth: Math.round(24 * DefaultStyle.dp) Layout.preferredWidth: Utils.getSizeWithScreenRatio(24)
Layout.preferredHeight: Math.round(24 * DefaultStyle.dp) Layout.preferredHeight: Utils.getSizeWithScreenRatio(24)
imageWidth: Math.round(24 * DefaultStyle.dp) imageWidth: Utils.getSizeWithScreenRatio(24)
imageHeight: Math.round(24 * DefaultStyle.dp) imageHeight: Utils.getSizeWithScreenRatio(24)
} }
Text { Text {
//: "Microphone" //: "Microphone"
@ -131,7 +137,7 @@ ColumnLayout {
id: inputAudioDeviceCBox id: inputAudioDeviceCBox
Layout.fillWidth: true Layout.fillWidth: true
Layout.preferredWidth: parent.width Layout.preferredWidth: parent.width
Layout.preferredHeight: Math.round(49 * DefaultStyle.dp) Layout.preferredHeight: Utils.getSizeWithScreenRatio(49)
entries: SettingsCpp.captureDevices entries: SettingsCpp.captureDevices
propertyName: "captureDevice" propertyName: "captureDevice"
propertyOwner: SettingsCpp propertyOwner: SettingsCpp
@ -143,6 +149,7 @@ ColumnLayout {
SettingsCpp.lSetCaptureDevice(inputAudioDeviceCBox.currentValue) SettingsCpp.lSetCaptureDevice(inputAudioDeviceCBox.currentValue)
} }
} }
Accessible.name: qsTr("choose_something_accessible_name").arg(qsTr("multimedia_settings_microphone_title"))
} }
Slider { Slider {
id: microVolume id: microVolume
@ -154,6 +161,8 @@ ColumnLayout {
if (mainItem.call) SettingsCpp.lSetCaptureGain(value) if (mainItem.call) SettingsCpp.lSetCaptureGain(value)
else SettingsCpp.captureGain = value else SettingsCpp.captureGain = value
} }
//: %1 volume
Accessible.name: qsTr("device_volume_accessible_name").arg(qsTr("multimedia_settings_microphone_title"))
} }
Timer { Timer {
id: audioTestSliderTimer id: audioTestSliderTimer
@ -168,16 +177,16 @@ ColumnLayout {
id: audioTestSlider id: audioTestSlider
Layout.fillWidth: true Layout.fillWidth: true
enabled: false enabled: false
Layout.preferredHeight: Math.round(10 * DefaultStyle.dp) Layout.preferredHeight: Utils.getSizeWithScreenRatio(10)
background: Rectangle { background: Rectangle {
x: audioTestSlider.leftPadding x: audioTestSlider.leftPadding
y: audioTestSlider.topPadding + audioTestSlider.availableHeight / 2 - height / 2 y: audioTestSlider.topPadding + audioTestSlider.availableHeight / 2 - height / 2
implicitWidth: Math.round(200 * DefaultStyle.dp) implicitWidth: Utils.getSizeWithScreenRatio(200)
implicitHeight: Math.round(10 * DefaultStyle.dp) implicitHeight: Utils.getSizeWithScreenRatio(10)
width: audioTestSlider.availableWidth width: audioTestSlider.availableWidth
height: implicitHeight height: implicitHeight
radius: Math.round(2 * DefaultStyle.dp) radius: Utils.getSizeWithScreenRatio(2)
color: DefaultStyle.grey_850 color: DefaultStyle.grey_850
Rectangle { Rectangle {
@ -188,24 +197,24 @@ ColumnLayout {
GradientStop { position: 0.0; color: DefaultStyle.vue_meter_light_green } GradientStop { position: 0.0; color: DefaultStyle.vue_meter_light_green }
GradientStop { position: 1.0; color: DefaultStyle.vue_meter_dark_green} GradientStop { position: 1.0; color: DefaultStyle.vue_meter_dark_green}
} }
radius: Math.round(2 * DefaultStyle.dp) radius: Utils.getSizeWithScreenRatio(2)
} }
} }
handle: Item {visible: false} handle: Item {visible: false}
} }
} }
ColumnLayout { ColumnLayout {
spacing: Math.round(12 * DefaultStyle.dp) spacing: Utils.getSizeWithScreenRatio(12)
visible: SettingsCpp.videoEnabled visible: SettingsCpp.videoEnabled
RowLayout { RowLayout {
spacing: Math.round(8 * DefaultStyle.dp) spacing: Utils.getSizeWithScreenRatio(8)
EffectImage { EffectImage {
imageSource: AppIcons.videoCamera imageSource: AppIcons.videoCamera
colorizationColor: DefaultStyle.main1_500_main colorizationColor: DefaultStyle.main1_500_main
Layout.preferredWidth: Math.round(24 * DefaultStyle.dp) Layout.preferredWidth: Utils.getSizeWithScreenRatio(24)
Layout.preferredHeight: Math.round(24 * DefaultStyle.dp) Layout.preferredHeight: Utils.getSizeWithScreenRatio(24)
imageWidth: Math.round(24 * DefaultStyle.dp) imageWidth: Utils.getSizeWithScreenRatio(24)
imageHeight: Math.round(24 * DefaultStyle.dp) imageHeight: Utils.getSizeWithScreenRatio(24)
} }
Text { Text {
//: "Caméra" //: "Caméra"
@ -218,7 +227,7 @@ ColumnLayout {
id: videoDevicesCbox id: videoDevicesCbox
Layout.fillWidth: true Layout.fillWidth: true
Layout.preferredWidth: parent.width Layout.preferredWidth: parent.width
Layout.preferredHeight: Math.round(49 * DefaultStyle.dp) Layout.preferredHeight: Utils.getSizeWithScreenRatio(49)
entries: SettingsCpp.videoDevices entries: SettingsCpp.videoDevices
propertyName: "videoDevice" propertyName: "videoDevice"
propertyOwner: SettingsCpp propertyOwner: SettingsCpp
@ -229,6 +238,7 @@ ColumnLayout {
SettingsCpp.lSetVideoDevice(videoDevicesCbox.currentValue) SettingsCpp.lSetVideoDevice(videoDevicesCbox.currentValue)
} }
} }
Accessible.name: qsTr("choose_something_accessible_name").arg(qsTr("multimedia_settings_camera_title"))
} }
} }
Connections { Connections {

View file

@ -22,7 +22,7 @@ ColumnLayout {
//: "Veuillez choisir lécran ou la fenêtre que vous souihaitez partager au autres participants" //: "Veuillez choisir lécran ou la fenêtre que vous souihaitez partager au autres participants"
text: qsTr("screencast_settings_choose_window_text") text: qsTr("screencast_settings_choose_window_text")
font.pixelSize: Math.round(14 * DefaultStyle.dp) font.pixelSize: Math.round(14 * DefaultStyle.dp)
color: DefaultStyle.main2_500main color: DefaultStyle.main2_500_main
} }
TabBar { TabBar {
Layout.fillWidth: true Layout.fillWidth: true

View file

@ -158,6 +158,7 @@ Control.Control {
} }
onCursorRectangleChanged: sendingAreaFlickable.ensureVisible(cursorRectangle) onCursorRectangleChanged: sendingAreaFlickable.ensureVisible(cursorRectangle)
wrapMode: TextEdit.WordWrap wrapMode: TextEdit.WordWrap
KeyNavigation.tab: recordButton.visible ? recordButton : sendMessageButton
Keys.onPressed: (event) => { Keys.onPressed: (event) => {
if ((event.key == Qt.Key_Enter || event.key == Qt.Key_Return)) if ((event.key == Qt.Key_Enter || event.key == Qt.Key_Return))
if(!(event.modifiers & Qt.ShiftModifier)) { if(!(event.modifiers & Qt.ShiftModifier)) {
@ -194,6 +195,7 @@ Control.Control {
} }
} }
BigButton { BigButton {
id: sendMessageButton
visible: sendingTextArea.text.length !== 0 || mainItem.selectedFilesCount > 0 visible: sendingTextArea.text.length !== 0 || mainItem.selectedFilesCount > 0
style: ButtonStyle.noBackgroundOrange style: ButtonStyle.noBackgroundOrange
icon.source: AppIcons.paperPlaneRight icon.source: AppIcons.paperPlaneRight
@ -275,7 +277,7 @@ Control.Control {
Rectangle { Rectangle {
id: hoverContent id: hoverContent
anchors.fill: parent anchors.fill: parent
color: DefaultStyle.main2_0 color: DefaultStyle.main2_000
visible: false visible: false
radius: Math.round(20 * DefaultStyle.dp) radius: Math.round(20 * DefaultStyle.dp)
@ -284,14 +286,14 @@ Control.Control {
imageSource: AppIcons.filePlus imageSource: AppIcons.filePlus
width: Math.round(37 * DefaultStyle.dp) width: Math.round(37 * DefaultStyle.dp)
height: Math.round(37 * DefaultStyle.dp) height: Math.round(37 * DefaultStyle.dp)
colorizationColor: DefaultStyle.main2_500main colorizationColor: DefaultStyle.main2_500_main
} }
DashRectangle { DashRectangle {
x: parent.x x: parent.x
y: parent.y y: parent.y
radius: hoverContent.radius radius: hoverContent.radius
color: DefaultStyle.main2_500main color: DefaultStyle.main2_500_main
width: parent.width width: parent.width
height: parent.height height: parent.height
} }

View file

@ -60,6 +60,7 @@ FormItemLayout {
} }
} }
onTextChanged: mainItem.clearErrorText() onTextChanged: mainItem.clearErrorText()
Accessible.name: mainItem.title
} }
} }

View file

@ -5,7 +5,7 @@ import Linphone
Control.TextField { Control.TextField {
id: mainItem id: mainItem
property real inputSize: Math.round(100 * DefaultStyle.dp) property real inputSize: Math.round(100 * DefaultStyle.dp)
color: activeFocus ? DefaultStyle.main1_500_main : DefaultStyle.main2_500main color: activeFocus ? DefaultStyle.main1_500_main : DefaultStyle.main2_500_main
validator: IntValidator{bottom: 0; top: 9} validator: IntValidator{bottom: 0; top: 9}
width: inputSize * 0.9 width: inputSize * 0.9
@ -33,7 +33,7 @@ Control.TextField {
Rectangle { Rectangle {
id: background id: background
border.width: Math.round(Math.max(DefaultStyle.dp), 1) border.width: Math.round(Math.max(DefaultStyle.dp), 1)
border.color: mainItem.activeFocus ? DefaultStyle.main1_500_main : DefaultStyle.main2_500main border.color: mainItem.activeFocus ? DefaultStyle.main1_500_main : DefaultStyle.main2_500_main
radius: mainItem.inputSize * 0.15 radius: mainItem.inputSize * 0.15
width: mainItem.inputSize * 0.9 width: mainItem.inputSize * 0.9
height: mainItem.inputSize height: mainItem.inputSize

View file

@ -2,6 +2,7 @@ import QtQuick
import QtQuick.Controls.Basic import QtQuick.Controls.Basic
import QtQuick.Layouts import QtQuick.Layouts
import Linphone import Linphone
import CustomControls 1.0
ColumnLayout { ColumnLayout {
id: mainItem id: mainItem
@ -16,6 +17,7 @@ ColumnLayout {
readonly property string phoneNumber: textField.text readonly property string phoneNumber: textField.text
readonly property string countryCode: combobox.currentText readonly property string countryCode: combobox.currentText
property string defaultCallingCode property string defaultCallingCode
property bool keyboardFocus: FocusHelper.keyboardFocus
Text { Text {
visible: label.length > 0 visible: label.length > 0
@ -38,7 +40,7 @@ ColumnLayout {
radius: Math.round(63 * DefaultStyle.dp) radius: Math.round(63 * DefaultStyle.dp)
color: DefaultStyle.grey_100 color: DefaultStyle.grey_100
border.color: mainItem.errorMessage.length > 0 border.color: mainItem.errorMessage.length > 0
? DefaultStyle.danger_500main ? DefaultStyle.danger_500_main
: (textField.hasActiveFocus || combobox.hasActiveFocus) : (textField.hasActiveFocus || combobox.hasActiveFocus)
? DefaultStyle.main1_500_main ? DefaultStyle.main1_500_main
: DefaultStyle.grey_200 : DefaultStyle.grey_200
@ -48,6 +50,9 @@ ColumnLayout {
id: combobox id: combobox
implicitWidth: Math.round(110 * DefaultStyle.dp) implicitWidth: Math.round(110 * DefaultStyle.dp)
defaultCallingCode: mainItem.defaultCallingCode defaultCallingCode: mainItem.defaultCallingCode
property bool keyboardFocus: FocusHelper.keyboardFocus
//: %1 prefix
Accessible.name: qsTr("prefix_phone_number_accessible_name").arg(mainItem.Accessible.name)
} }
Rectangle { Rectangle {
Layout.preferredWidth: Math.max(Math.round(1 * DefaultStyle.dp), 1) Layout.preferredWidth: Math.max(Math.round(1 * DefaultStyle.dp), 1)
@ -63,6 +68,9 @@ ColumnLayout {
background: Item{} background: Item{}
initialText: initialPhoneNumber initialText: initialPhoneNumber
validator: RegularExpressionValidator{ regularExpression: /[0-9]+/} validator: RegularExpressionValidator{ regularExpression: /[0-9]+/}
property bool keyboardFocus: FocusHelper.keyboardFocus
//: %1 number
Accessible.name: qsTr("number_phone_number_accessible_name").arg(mainItem.Accessible.name)
} }
} }
} }
@ -71,7 +79,7 @@ ColumnLayout {
anchors.top: contentBackground.bottom anchors.top: contentBackground.bottom
// visible: mainItem.enableErrorText // visible: mainItem.enableErrorText
text: mainItem.errorMessage text: mainItem.errorMessage
color: DefaultStyle.danger_500main color: DefaultStyle.danger_500_main
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
elide: Text.ElideRight elide: Text.ElideRight
wrapMode: Text.Wrap wrapMode: Text.Wrap

View file

@ -2,16 +2,12 @@ import QtQuick
import QtQuick.Controls.Basic as Control import QtQuick.Controls.Basic as Control
import QtQuick.Layouts import QtQuick.Layouts
import Linphone import Linphone
import CustomControls 1.0
import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils
import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle
FocusScope { FocusScope {
id: mainItem id: mainItem
property string placeholderText: ""
property color placeholderTextColor: DefaultStyle.main2_400
property real textInputWidth: Math.round(350 * DefaultStyle.dp)
property color borderColor: "transparent"
property color focusedBorderColor: DefaultStyle.main2_500main
property string text: textField.searchText
property bool magnifierVisible: true property bool magnifierVisible: true
property var validator: RegularExpressionValidator{} property var validator: RegularExpressionValidator{}
property var numericPadPopup property var numericPadPopup
@ -20,6 +16,17 @@ FocusScope {
property alias color: backgroundItem.color property alias color: backgroundItem.color
property bool delaySearch: true // Wait some idle time after typing to start searching property bool delaySearch: true // Wait some idle time after typing to start searching
property bool handleNumericPadPopupButtonsPressed: true property bool handleNumericPadPopupButtonsPressed: true
// Border properties
property color borderColor: "transparent"
property color focusedBorderColor: DefaultStyle.main2_500_main
property color keyboardFocusedBorderColor: DefaultStyle.main2_900
property real borderWidth: Utils.getSizeWithScreenRatio(1)
property real keyboardFocusedBorderWidth: Utils.getSizeWithScreenRatio(3)
// Text properties
property string placeholderText: ""
property color placeholderTextColor: DefaultStyle.main2_400
property real textInputWidth: Math.round(350 * DefaultStyle.dp)
property string text: textField.searchText
signal openNumericPadRequested()// Useful for redirection before displaying numeric pad. signal openNumericPadRequested()// Useful for redirection before displaying numeric pad.
@ -45,12 +52,13 @@ FocusScope {
anchors.fill: parent anchors.fill: parent
radius: Math.round(28 * DefaultStyle.dp) radius: Math.round(28 * DefaultStyle.dp)
color: DefaultStyle.grey_100 color: DefaultStyle.grey_100
border.color: textField.activeFocus ? mainItem.focusedBorderColor : mainItem.borderColor border.color: textField.keyboardFocus ? mainItem.keyboardFocusedBorderColor : textField.activeFocus ? mainItem.focusedBorderColor : mainItem.borderColor
border.width: textField.keyboardFocus ? mainItem.keyboardFocusedBorderWidth : mainItem.borderWidth
} }
EffectImage { EffectImage {
id: magnifier id: magnifier
visible: mainItem.magnifierVisible visible: mainItem.magnifierVisible
colorizationColor: DefaultStyle.main2_500main colorizationColor: DefaultStyle.main2_500_main
anchors.left: parent.left anchors.left: parent.left
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
anchors.leftMargin: Math.round(10 * DefaultStyle.dp) anchors.leftMargin: Math.round(10 * DefaultStyle.dp)
@ -64,6 +72,7 @@ FocusScope {
anchors.leftMargin: magnifier.visible ? 0 : Math.round(10 * DefaultStyle.dp) anchors.leftMargin: magnifier.visible ? 0 : Math.round(10 * DefaultStyle.dp)
anchors.right: clearTextButton.left anchors.right: clearTextButton.left
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
property bool keyboardFocus: FocusHelper.keyboardFocus
property string searchText property string searchText
@ -86,7 +95,7 @@ FocusScope {
} }
cursorDelegate: Rectangle { cursorDelegate: Rectangle {
visible: textField.cursorVisible visible: textField.cursorVisible
color: DefaultStyle.main2_500main color: DefaultStyle.main2_500_main
width: Math.max(Math.round(1 * DefaultStyle.dp), 1) width: Math.max(Math.round(1 * DefaultStyle.dp), 1)
} }
Timer{ Timer{
@ -104,11 +113,15 @@ FocusScope {
icon.source: AppIcons.dialer icon.source: AppIcons.dialer
contentImageColor: checked ? DefaultStyle.main1_500_main : DefaultStyle.main2_600 contentImageColor: checked ? DefaultStyle.main1_500_main : DefaultStyle.main2_600
hoveredImageColor: contentImageColor hoveredImageColor: contentImageColor
width: Math.round(24 * DefaultStyle.dp) width: Math.round(30 * DefaultStyle.dp)
height: Math.round(24 * DefaultStyle.dp) height: Math.round(30* DefaultStyle.dp)
icon.width: Utils.getSizeWithScreenRatio(24)
icon.height: Utils.getSizeWithScreenRatio(24)
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right anchors.right: parent.right
anchors.rightMargin: Math.round(20 * DefaultStyle.dp) anchors.rightMargin: Math.round(20 * DefaultStyle.dp)
//: "Open dialer"
Accessible.name: qsTr("open_dialer_acccessibility_label")
onClicked: { onClicked: {
if(!checked){ if(!checked){
mainItem.openNumericPadRequested() mainItem.openNumericPadRequested()
@ -127,6 +140,8 @@ FocusScope {
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
anchors.right: parent.right anchors.right: parent.right
anchors.rightMargin: Math.round(20 * DefaultStyle.dp) anchors.rightMargin: Math.round(20 * DefaultStyle.dp)
//: "Clear text input"
Accessible.name: qsTr("clear_text_input_acccessibility_label")
onClicked: { onClicked: {
textField.clear() textField.clear()
} }

View file

@ -17,6 +17,7 @@ TextEdit {
topPadding: Math.round(5 * DefaultStyle.dp) topPadding: Math.round(5 * DefaultStyle.dp)
bottomPadding: Math.round(5 * DefaultStyle.dp) bottomPadding: Math.round(5 * DefaultStyle.dp)
activeFocusOnTab: true activeFocusOnTab: true
KeyNavigation.priority: KeyNavigation.BeforeItem
property bool displayAsRichText: false property bool displayAsRichText: false
property var encodeTextObj: UtilsCpp.encodeTextToQmlRichFormat(text) property var encodeTextObj: UtilsCpp.encodeTextToQmlRichFormat(text)

View file

@ -2,17 +2,19 @@ import QtQuick
import QtQuick.Controls.Basic as Control import QtQuick.Controls.Basic as Control
import QtQuick.Layouts import QtQuick.Layouts
import Linphone import Linphone
import CustomControls 1.0
import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils
import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
Control.TextField { Control.TextField {
id: mainItem id: mainItem
property var customWidth property var customWidth
width: Math.round((customWidth ? customWidth - 1 : 360) * DefaultStyle.dp) width: Math.round((customWidth ? customWidth - 1 : 360) * DefaultStyle.dp)
height: Math.round(49 * DefaultStyle.dp) height: Utils.getSizeWithScreenRatio(49)
leftPadding: Math.round(15 * DefaultStyle.dp) leftPadding: Utils.getSizeWithScreenRatio(15)
rightPadding: eyeButton.visible rightPadding: eyeButton.visible
? Math.round(5 * DefaultStyle.dp) + eyeButton.width + eyeButton.rightMargin ? Utils.getSizeWithScreenRatio(5) + eyeButton.width + eyeButton.rightMargin
: Math.round(15 * DefaultStyle.dp) : Utils.getSizeWithScreenRatio(15)
echoMode: (hidden && !eyeButton.checked) ? TextInput.Password : TextInput.Normal echoMode: (hidden && !eyeButton.checked) ? TextInput.Password : TextInput.Normal
// Workaround for Windows slowness when first typing a password // Workaround for Windows slowness when first typing a password
@ -23,7 +25,7 @@ Control.TextField {
} }
verticalAlignment: TextInput.AlignVCenter verticalAlignment: TextInput.AlignVCenter
color: isError ? DefaultStyle.danger_500main : DefaultStyle.main2_600 color: isError ? DefaultStyle.danger_500_main : DefaultStyle.main2_600
placeholderTextColor: DefaultStyle.placeholders placeholderTextColor: DefaultStyle.placeholders
font { font {
family: DefaultStyle.defaultFont family: DefaultStyle.defaultFont
@ -38,10 +40,19 @@ Control.TextField {
property bool controlIsDown: false property bool controlIsDown: false
property bool hidden: false property bool hidden: false
property bool isError: false property bool isError: false
property bool keyboardFocus: FocusHelper.keyboardFocus
// Background properties
property bool backgroundVisible: true property bool backgroundVisible: true
property color backgroundColor: DefaultStyle.grey_100 property color backgroundColor: DefaultStyle.grey_100
property color disabledBackgroundColor: DefaultStyle.grey_200 property color disabledBackgroundColor: DefaultStyle.grey_200
// Border properties
property color backgroundBorderColor: DefaultStyle.grey_200 property color backgroundBorderColor: DefaultStyle.grey_200
property color activeBorderColor: DefaultStyle.main1_500_main
property color keyboardFocusedBorderColor: DefaultStyle.main2_900
property color errorBorderColor: DefaultStyle.danger_500_main
property real borderWidth: Utils.getSizeWithScreenRatio(1)
property real keyboardFocusedBorderWidth: Utils.getSizeWithScreenRatio(3)
// Text properties
property string initialText property string initialText
property real pixelSize: Typography.p1.pixelSize property real pixelSize: Typography.p1.pixelSize
property real weight: Typography.p1.weight property real weight: Typography.p1.weight
@ -116,15 +127,16 @@ Control.TextField {
id: inputBackground id: inputBackground
visible: mainItem.backgroundVisible visible: mainItem.backgroundVisible
anchors.fill: parent anchors.fill: parent
radius: Math.round(79 * DefaultStyle.dp) radius: Utils.getSizeWithScreenRatio(79)
color: mainItem.enabled ? mainItem.backgroundColor : mainItem.disabledBackgroundColor color: mainItem.enabled ? mainItem.backgroundColor : mainItem.disabledBackgroundColor
border.color: mainItem.isError ? DefaultStyle.danger_500main : mainItem.activeFocus ? DefaultStyle.main1_500_main : mainItem.backgroundBorderColor border.color: mainItem.isError ? mainItem.errorBorderColor : mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderColor : mainItem.activeFocus ? mainItem.activeBorderColor : mainItem.backgroundBorderColor
border.width: mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderWidth : mainItem.borderWidth
} }
cursorDelegate: Rectangle { cursorDelegate: Rectangle {
id: cursor id: cursor
color: DefaultStyle.main1_500_main color: DefaultStyle.main1_500_main
width: Math.max(Math.round(1 * DefaultStyle.dp), 1) width: Math.max(Utils.getSizeWithScreenRatio(1), 1)
anchors.verticalCenter: mainItem.verticalCenter anchors.verticalCenter: mainItem.verticalCenter
SequentialAnimation { SequentialAnimation {
@ -175,18 +187,25 @@ Control.TextField {
Button { Button {
id: eyeButton id: eyeButton
KeyNavigation.left: mainItem KeyNavigation.left: mainItem
property real rightMargin: Math.round(15 * DefaultStyle.dp) property real rightMargin: Utils.getSizeWithScreenRatio(15)
z: 1 z: 1
visible: mainItem.hidden visible: mainItem.hidden
checkable: true checkable: true
style: ButtonStyle.noBackground style: ButtonStyle.noBackground
icon.source: eyeButton.checked ? AppIcons.eyeShow : AppIcons.eyeHide icon.source: eyeButton.checked ? AppIcons.eyeShow : AppIcons.eyeHide
width: Math.round(20 * DefaultStyle.dp) width: Utils.getSizeWithScreenRatio(20)
height: Math.round(20 * DefaultStyle.dp) height: Utils.getSizeWithScreenRatio(20)
icon.width: width icon.width: width
icon.height: height icon.height: height
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right anchors.right: parent.right
anchors.rightMargin: rightMargin anchors.rightMargin: rightMargin
Accessible.name: (eyeButton.checked ?
//: Hide %1
qsTr("hide_accessible_name") :
//: Show %1
qsTr("show_accessible_name")
).arg(mainItem.Accessible.name)
} }
} }

View file

@ -32,7 +32,7 @@ Dialog {
width: mainItem.width width: mainItem.width
height: mainItem.implicitHeight height: mainItem.implicitHeight
color: mainItem.securityError color: mainItem.securityError
? DefaultStyle.danger_500main ? DefaultStyle.danger_500_main
: mainItem.isCaseMismatch : mainItem.isCaseMismatch
? DefaultStyle.warning_600 ? DefaultStyle.warning_600
: DefaultStyle.info_500_main : DefaultStyle.info_500_main
@ -244,8 +244,8 @@ Dialog {
//: "Aucune correspondance" //: "Aucune correspondance"
text: qsTr("call_dialog_zrtp_validate_trust_letters_do_not_match") text: qsTr("call_dialog_zrtp_validate_trust_letters_do_not_match")
color: DefaultStyle.grey_0 color: DefaultStyle.grey_0
borderColor: DefaultStyle.danger_500main borderColor: DefaultStyle.danger_500_main
textColor: DefaultStyle.danger_500main textColor: DefaultStyle.danger_500_main
visible: !mainItem.securityError visible: !mainItem.securityError
onClicked: { onClicked: {
if(mainItem.call) mainItem.call.core.lCheckAuthenticationTokenSelected(" ") if(mainItem.call) mainItem.call.core.lCheckAuthenticationTokenSelected(" ")

View file

@ -21,8 +21,10 @@ Popup {
rightMargin: Math.round(20 * DefaultStyle.dp) rightMargin: Math.round(20 * DefaultStyle.dp)
bottomMargin: Math.round(20 * DefaultStyle.dp) bottomMargin: Math.round(20 * DefaultStyle.dp)
padding: Math.round(20 * DefaultStyle.dp) padding: Math.round(20 * DefaultStyle.dp)
underlineColor: mainItem.isSuccess ? DefaultStyle.success_500main : DefaultStyle.danger_500main underlineColor: mainItem.isSuccess ? DefaultStyle.success_500_main : DefaultStyle.danger_500_main
radius: 0 radius: 0
focus: true
onHoveredChanged: { onHoveredChanged: {
if (hovered) autoClosePopup.stop() if (hovered) autoClosePopup.stop()
else autoClosePopup.restart() else autoClosePopup.restart()
@ -36,9 +38,11 @@ Popup {
} }
contentItem: RowLayout { contentItem: RowLayout {
spacing: Math.round(24 * DefaultStyle.dp) spacing: Math.round(24 * DefaultStyle.dp)
Accessible.role: Accessible.AlertMessage
Accessible.name: "%1, %2".arg(mainItem.title).arg(mainItem.description)
EffectImage { EffectImage {
imageSource: mainItem.isSuccess ? AppIcons.smiley : AppIcons.smileySad imageSource: mainItem.isSuccess ? AppIcons.smiley : AppIcons.smileySad
colorizationColor: mainItem.isSuccess ? DefaultStyle.success_500main : DefaultStyle.danger_500main colorizationColor: mainItem.isSuccess ? DefaultStyle.success_500_main : DefaultStyle.danger_500_main
Layout.preferredWidth: Math.round(32 * DefaultStyle.dp) Layout.preferredWidth: Math.round(32 * DefaultStyle.dp)
Layout.preferredHeight: Math.round(32 * DefaultStyle.dp) Layout.preferredHeight: Math.round(32 * DefaultStyle.dp)
width: Math.round(32 * DefaultStyle.dp) width: Math.round(32 * DefaultStyle.dp)
@ -56,7 +60,7 @@ Popup {
Text { Text {
Layout.fillWidth: true Layout.fillWidth: true
text: mainItem.title text: mainItem.title
color: mainItem.isSuccess ? DefaultStyle.success_500main : DefaultStyle.danger_500main color: mainItem.isSuccess ? DefaultStyle.success_500_main : DefaultStyle.danger_500_main
font { font {
pixelSize: Typography.h4.pixelSize pixelSize: Typography.h4.pixelSize
weight: Typography.h4.weight weight: Typography.h4.weight
@ -80,7 +84,7 @@ Popup {
Layout.maximumWidth: Math.round(300 * DefaultStyle.dp) Layout.maximumWidth: Math.round(300 * DefaultStyle.dp)
text: mainItem.description text: mainItem.description
wrapMode: Text.WordWrap wrapMode: Text.WordWrap
color: DefaultStyle.main2_500main color: DefaultStyle.main2_500_main
font { font {
pixelSize: Math.round(12 * DefaultStyle.dp) pixelSize: Math.round(12 * DefaultStyle.dp)
weight: Math.round(300 * DefaultStyle.dp) weight: Math.round(300 * DefaultStyle.dp)

View file

@ -2,6 +2,7 @@ import QtQuick
import QtQuick.Controls.Basic as Control import QtQuick.Controls.Basic as Control
import QtQuick.Effects import QtQuick.Effects
import Linphone import Linphone
import CustomControls 1.0
Control.Popup{ Control.Popup{
id: mainItem id: mainItem
@ -9,6 +10,7 @@ Control.Popup{
property color underlineColor : DefaultStyle.main1_500_main property color underlineColor : DefaultStyle.main1_500_main
property real radius: Math.round(16 * DefaultStyle.dp) property real radius: Math.round(16 * DefaultStyle.dp)
property bool hovered: mouseArea.containsMouse property bool hovered: mouseArea.containsMouse
property bool keyboardFocus: FocusHelper.keyboardFocus
background: Item{ background: Item{
Rectangle { Rectangle {

View file

@ -138,6 +138,49 @@ function getTopParent (object, useFakeParent) {
return parent return parent
} }
// -----------------------------------------------------------------------------
// Check that an item is descendant of another one
function isDescendant(child, parent) {
console.debug("---")
console.debug(child)
var current = child.parent
while (current) {
console.debug(current)
if (current === parent)
return true
current = current.parent
}
return false
}
// -----------------------------------------------------------------------------
// Retrieve first focussable item of an Item. If no item found, return undefined
function getFirstFocussableItemInItem(item) {
var next = item.nextItemInFocusChain();
if (next && isDescendant(next, item)){
return next;
}
return undefined;
}
// Retrieve last focussable item of an Item. If no item found, return undefined
function getLastFocussableItemInItem(item) {
var next = item.nextItemInFocusChain();
if(next && !isDescendant(next, item)){
return undefined;
}
var current
do{
current = next;
next = current.nextItemInFocusChain();
} while(isDescendant(next, item) && next.visible)
console.log("find last content", current)
return current;
}
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Load by default a window in the ui/views folder. // Load by default a window in the ui/views folder.
@ -827,3 +870,13 @@ function codepointFromFilename(filename) {
var unicode = String.fromCodePoint(...codePoints); var unicode = String.fromCodePoint(...codePoints);
return unicode; return unicode;
} }
// -----------------------------------------------------------------------------
function getSizeWithScreenRatio(size){
if (size == 0) {
return size;
}
return Math.max(Math.round(size * Linphone.DefaultStyle.dp), 1);
}

View file

@ -425,7 +425,7 @@ FocusScope {
Layout.fillWidth: true Layout.fillWidth: true
//: Reply to %1 //: Reply to %1
text: mainItem.chatMessage ? qsTr("reply_to_label").arg(UtilsCpp.boldTextPart(mainItem.chatMessage.core.fromName, mainItem.chatMessage.core.fromName)) : "" text: mainItem.chatMessage ? qsTr("reply_to_label").arg(UtilsCpp.boldTextPart(mainItem.chatMessage.core.fromName, mainItem.chatMessage.core.fromName)) : ""
color: DefaultStyle.main2_500main color: DefaultStyle.main2_500_main
font { font {
pixelSize: Typography.p3.pixelSize pixelSize: Typography.p3.pixelSize
weight: Typography.p3.weight weight: Typography.p3.weight

View file

@ -7,6 +7,7 @@ import QtQuick.Layouts
import Linphone import Linphone
import UtilsCpp import UtilsCpp
import SettingsCpp import SettingsCpp
import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils
import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle
MainRightPanel { MainRightPanel {
@ -36,7 +37,7 @@ MainRightPanel {
mainItem.contact.core.undo() mainItem.contact.core.undo()
mainItem.closeEdition('') mainItem.closeEdition('')
} }
width: Math.round(278 * DefaultStyle.dp) width: Utils.getSizeWithScreenRatio(278)
//: "Les changements seront annulés. Souhaitez-vous continuer ?" //: "Les changements seront annulés. Souhaitez-vous continuer ?"
text: qsTr("contact_editor_dialog_cancel_change_message") text: qsTr("contact_editor_dialog_cancel_change_message")
} }
@ -45,18 +46,20 @@ MainRightPanel {
Text { Text {
text: mainItem.title text: mainItem.title
font { font {
pixelSize: Math.round(20 * DefaultStyle.dp) pixelSize: Utils.getSizeWithScreenRatio(20)
weight: Typography.h4.weight weight: Typography.h4.weight
} }
} }
Item{Layout.fillWidth: true} Item{Layout.fillWidth: true}
Button { Button {
style: ButtonStyle.noBackground style: ButtonStyle.noBackground
width: Math.round(24 * DefaultStyle.dp) Layout.preferredWidth: Utils.getSizeWithScreenRatio(30)
height: Math.round(24 * DefaultStyle.dp) Layout.preferredHeight: Utils.getSizeWithScreenRatio(30)
icon.source: AppIcons.closeX icon.source: AppIcons.closeX
icon.width: Math.round(24 * DefaultStyle.dp) icon.width: Utils.getSizeWithScreenRatio(24)
icon.height: Math.round(24 * DefaultStyle.dp) icon.height: Utils.getSizeWithScreenRatio(24)
//: Close %n
Accessible.name: qsTr("close_accessible_name").arg(mainItem.title)
onClicked: { onClicked: {
if (contact.core.isSaved) mainItem.closeEdition('') if (contact.core.isSaved) mainItem.closeEdition('')
else showConfirmationLambdaPopup("", qsTr("contact_editor_dialog_cancel_change_message"), "", function(confirmed) { else showConfirmationLambdaPopup("", qsTr("contact_editor_dialog_cancel_change_message"), "", function(confirmed) {
@ -70,9 +73,16 @@ MainRightPanel {
} }
content: ContactLayout { content: ContactLayout {
id: contactLayoutItem
anchors.fill: parent anchors.fill: parent
contact: mainItem.contact contact: mainItem.contact
button.text: mainItem.saveButtonText button.text: mainItem.saveButtonText
button.Keys.onPressed: (event) => {
if(event.key == Qt.Key_Up){
phoneNumberInput.forceActiveFocus(Qt.BacktabFocusReason)
event.accepted = true
}
}
// Let some time to GUI to set fields on losing focus. // Let some time to GUI to set fields on losing focus.
Timer{ Timer{
@ -114,7 +124,7 @@ MainRightPanel {
RowLayout { RowLayout {
visible: mainItem.contact && mainItem.contact.core.pictureUri.length != 0 visible: mainItem.contact && mainItem.contact.core.pictureUri.length != 0
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
spacing: Math.round(32 * DefaultStyle.dp) spacing: Utils.getSizeWithScreenRatio(32)
IconLabelButton { IconLabelButton {
id: editButton id: editButton
Layout.preferredWidth: width Layout.preferredWidth: width
@ -128,6 +138,8 @@ MainRightPanel {
textWeight: Typography.h4.weight textWeight: Typography.h4.weight
KeyNavigation.right: removeButton KeyNavigation.right: removeButton
onClicked: fileDialog.open() onClicked: fileDialog.open()
//: "Edit contact image"
Accessible.name: qsTr("edit_contact_image_accessible_name")
} }
FileDialog { FileDialog {
id: fileDialog id: fileDialog
@ -153,6 +165,8 @@ MainRightPanel {
textWeight: Typography.h4.weight textWeight: Typography.h4.weight
KeyNavigation.left: editButton KeyNavigation.left: editButton
onClicked: mainItem.contact.core.pictureUri = "" onClicked: mainItem.contact.core.pictureUri = ""
//: "Delete contact image"
Accessible.name: qsTr("delete_contact_image_accessible_name")
} }
}, },
Item{Layout.fillWidth: true} Item{Layout.fillWidth: true}
@ -195,7 +209,7 @@ MainRightPanel {
ScrollBar.horizontal: Control.ScrollBar { ScrollBar.horizontal: Control.ScrollBar {
} }
ColumnLayout { ColumnLayout {
spacing: Math.round(20 * DefaultStyle.dp) spacing: Utils.getSizeWithScreenRatio(20)
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
@ -207,15 +221,16 @@ MainRightPanel {
label: qsTr("contact_editor_first_name") label: qsTr("contact_editor_first_name")
contentItem: TextField { contentItem: TextField {
id: givenNameEdit id: givenNameEdit
Layout.preferredHeight: Math.round(49 * DefaultStyle.dp) Layout.preferredHeight: Utils.getSizeWithScreenRatio(49)
initialText: contact.core.givenName initialText: contact.core.givenName
onTextEdited: { onTextEdited: {
contact.core.givenName = givenNameEdit.text contact.core.givenName = givenNameEdit.text
} }
backgroundColor: DefaultStyle.grey_0 backgroundColor: DefaultStyle.grey_0
backgroundBorderColor: givenName.errorTextVisible ? DefaultStyle.danger_500main : DefaultStyle.grey_200 backgroundBorderColor: givenName.errorTextVisible ? DefaultStyle.danger_500_main : DefaultStyle.grey_200
KeyNavigation.up: editButton.visible ? editButton : addPictureButton KeyNavigation.up: editButton.visible ? editButton : addPictureButton
KeyNavigation.down: nameTextField KeyNavigation.down: nameTextField
Accessible.name: qsTr("contact_editor_first_name")
} }
} }
FormItemLayout { FormItemLayout {
@ -229,6 +244,7 @@ MainRightPanel {
backgroundColor: DefaultStyle.grey_0 backgroundColor: DefaultStyle.grey_0
KeyNavigation.up: givenNameEdit KeyNavigation.up: givenNameEdit
KeyNavigation.down: companyTextField KeyNavigation.down: companyTextField
Accessible.name: qsTr("contact_editor_last_name")
} }
} }
FormItemLayout { FormItemLayout {
@ -242,6 +258,7 @@ MainRightPanel {
backgroundColor: DefaultStyle.grey_0 backgroundColor: DefaultStyle.grey_0
KeyNavigation.up: nameTextField KeyNavigation.up: nameTextField
KeyNavigation.down: jobTextField KeyNavigation.down: jobTextField
Accessible.name: qsTr("contact_editor_company")
} }
} }
FormItemLayout { FormItemLayout {
@ -256,13 +273,11 @@ MainRightPanel {
KeyNavigation.up: companyTextField KeyNavigation.up: companyTextField
Keys.onPressed: (event) => { Keys.onPressed: (event) => {
if(event.key == Qt.Key_Down){ if(event.key == Qt.Key_Down){
if(addressesList.count > 0) (addressesList.count > 0 ? addressesList.itemAt(0) : newAddressTextField).forceActiveFocus(Qt.TabFocusReason)
addressesList.itemAt(0).forceActiveFocus()
else
newAddressTextField.forceActiveFocus()
event.accepted = true event.accepted = true
} }
} }
Accessible.name: qsTr("contact_editor_job_title")
} }
} }
Repeater { Repeater {
@ -275,25 +290,23 @@ MainRightPanel {
label: modelData.label label: modelData.label
contentItem: RowLayout { contentItem: RowLayout {
id: addressLayout id: addressLayout
spacing: Math.round(10 * DefaultStyle.dp) spacing: Utils.getSizeWithScreenRatio(10)
function updateFocus(event){ function updateFocus(event){
if(event.key == Qt.Key_Up){ if(event.key == Qt.Key_Up){
if(index - 1 >=0 ) (index - 1 >=0 ? addressesList.itemAt(index - 1) : jobTextField).forceActiveFocus(Qt.BacktabFocusReason)
addressesList.itemAt(index - 1).forceActiveFocus()
else
jobTextField.forceActiveFocus()
event.accepted = true event.accepted = true
}else if(event.key == Qt.Key_Down){ }else if(event.key == Qt.Key_Down){
if(index + 1 < addressesList.count) (index + 1 < addressesList.count ? addressesList.itemAt(index+1) : newAddressTextField).forceActiveFocus(Qt.TabFocusReason)
addressesList.itemAt(index+1).forceActiveFocus()
else
newAddressTextField.forceActiveFocus()
event.accepted = true event.accepted = true
}else if(event.key == Qt.Key_Right && addressTextField.activeFocus){
removeAddressButton.forceActiveFocus(Qt.TabFocusReason)
}else if(event.key == Qt.Key_Left && removeAddressButton.activeFocus){
addressTextField.forceActiveFocus(Qt.BacktabFocusReason)
} }
} }
TextField { TextField {
id: addressTextField id: addressTextField
Layout.preferredWidth: Math.round(421 * DefaultStyle.dp) Layout.preferredWidth: Utils.getSizeWithScreenRatio(421)
Layout.preferredHeight: height Layout.preferredHeight: height
onEditingFinished: { onEditingFinished: {
var label = qsTr("sip_address") var label = qsTr("sip_address")
@ -305,19 +318,23 @@ MainRightPanel {
focus: true focus: true
KeyNavigation.right: removeAddressButton KeyNavigation.right: removeAddressButton
Keys.onPressed: (event) => addressLayout.updateFocus(event) Keys.onPressed: (event) => addressLayout.updateFocus(event)
//: "SIP address number %1"
Accessible.name: qsTr("sip_address_number_accessible_name").arg(index+1)
} }
Button { Button {
id: removeAddressButton id: removeAddressButton
Layout.preferredWidth: Math.round(24 * DefaultStyle.dp) Layout.preferredWidth: Utils.getSizeWithScreenRatio(30)
Layout.preferredHeight: Math.round(24 * DefaultStyle.dp) Layout.preferredHeight: Utils.getSizeWithScreenRatio(30)
Layout.alignment: Qt.AlignVCenter Layout.alignment: Qt.AlignVCenter
icon.source: AppIcons.closeX icon.source: AppIcons.closeX
icon.width: Math.round(24 * DefaultStyle.dp) icon.width: Utils.getSizeWithScreenRatio(24)
icon.height: Math.round(24 * DefaultStyle.dp) icon.height: Utils.getSizeWithScreenRatio(24)
style: ButtonStyle.noBackground style: ButtonStyle.noBackground
KeyNavigation.left: addressTextField KeyNavigation.left: addressTextField
Keys.onPressed: (event) => addressLayout.updateFocus(event) Keys.onPressed: (event) => addressLayout.updateFocus(event)
onClicked: mainItem.contact.core.removeAddress(index) onClicked: mainItem.contact.core.removeAddress(index)
//: "Remove SIP address %1"
Accessible.name: qsTr("remove_sip_address_accessible_name").arg(addressTextField.text)
} }
} }
} }
@ -334,16 +351,10 @@ MainRightPanel {
backgroundColor: DefaultStyle.grey_0 backgroundColor: DefaultStyle.grey_0
Keys.onPressed: (event) => { Keys.onPressed: (event) => {
if(event.key == Qt.Key_Up){ if(event.key == Qt.Key_Up){
if(addressesList.count > 0 ) (addressesList.count > 0 ? addressesList.itemAt(addressesList.count - 1) : jobTextField).forceActiveFocus(Qt.BacktabFocusReason)
addressesList.itemAt(addressesList.count - 1).forceActiveFocus()
else
jobTextField.forceActiveFocus()
event.accepted = true event.accepted = true
}else if(event.key == Qt.Key_Down){ }else if(event.key == Qt.Key_Down){
if(phoneNumberList.count > 0) (phoneNumberList.count > 0 ? phoneNumberList.itemAt(0) : phoneNumberInputTextField).forceActiveFocus(Qt.TabFocusReason)
phoneNumberList.itemAt(0).forceActiveFocus()
else
phoneNumberInputTextField.forceActiveFocus()
event.accepted = true event.accepted = true
} }
} }
@ -352,6 +363,8 @@ MainRightPanel {
newAddressTextField.clear() newAddressTextField.clear()
editionLayout.connectOnce(editionLayout.ensureVisibleRequested, editionLayout.ensureVisible) editionLayout.connectOnce(editionLayout.ensureVisibleRequested, editionLayout.ensureVisible)
} }
//: "New SIP address"
Accessible.name: qsTr("new_sip_address_accessible_name")
} }
} }
Repeater { Repeater {
@ -363,25 +376,19 @@ MainRightPanel {
label: modelData.label label: modelData.label
contentItem: RowLayout { contentItem: RowLayout {
id: phoneNumberLayout id: phoneNumberLayout
spacing: Math.round(10 * DefaultStyle.dp) spacing: Utils.getSizeWithScreenRatio(10)
function updateFocus(event){ function updateFocus(event){
if(event.key == Qt.Key_Up){ if(event.key == Qt.Key_Up){
if(index - 1 >=0 ) (index - 1 >=0 ? phoneNumberList.itemAt(index - 1): newAddressTextField).forceActiveFocus(Qt.BacktabFocusReason)
phoneNumberList.itemAt(index - 1).forceActiveFocus()
else
newAddressTextField.forceActiveFocus()
event.accepted = true event.accepted = true
}else if(event.key == Qt.Key_Down){ }else if(event.key == Qt.Key_Down){
if(index + 1 < phoneNumberList.count) (index + 1 < phoneNumberList.count ? phoneNumberList.itemAt(index+1) : phoneNumberInputTextField).forceActiveFocus(Qt.TabFocusReason)
phoneNumberList.itemAt(index+1).forceActiveFocus()
else
phoneNumberInputTextField.forceActiveFocus()
event.accepted = true event.accepted = true
} }
} }
TextField { TextField {
id: phoneTextField id: phoneTextField
Layout.preferredWidth: Math.round(421 * DefaultStyle.dp) Layout.preferredWidth: Utils.getSizeWithScreenRatio(421)
Layout.preferredHeight: height Layout.preferredHeight: height
initialText: modelData.address initialText: modelData.address
backgroundColor: DefaultStyle.grey_0 backgroundColor: DefaultStyle.grey_0
@ -392,19 +399,23 @@ MainRightPanel {
//: "Téléphone" //: "Téléphone"
if (text.length != 0) mainItem.contact.core.setPhoneNumberAt(index, qsTr("phone"), text) if (text.length != 0) mainItem.contact.core.setPhoneNumberAt(index, qsTr("phone"), text)
} }
//: "Phone number number %1"
Accessible.name: qsTr("phone_number_number_accessible_name").arg(index+1)
} }
Button { Button {
id: removePhoneButton id: removePhoneButton
Layout.preferredWidth: Math.round(24 * DefaultStyle.dp) Layout.preferredWidth: Utils.getSizeWithScreenRatio(30)
Layout.preferredHeight: Math.round(24 * DefaultStyle.dp) Layout.preferredHeight: Utils.getSizeWithScreenRatio(30)
Layout.alignment: Qt.AlignVCenter Layout.alignment: Qt.AlignVCenter
style: ButtonStyle.noBackground style: ButtonStyle.noBackground
icon.source: AppIcons.closeX icon.source: AppIcons.closeX
icon.width: Math.round(24 * DefaultStyle.dp) icon.width: Utils.getSizeWithScreenRatio(24)
icon.height: Math.round(24 * DefaultStyle.dp) icon.height: Utils.getSizeWithScreenRatio(24)
KeyNavigation.left: phoneTextField KeyNavigation.left: phoneTextField
Keys.onPressed: (event) => phoneNumberLayout.updateFocus(event) Keys.onPressed: (event) => phoneNumberLayout.updateFocus(event)
onClicked: mainItem.contact.core.removePhoneNumber(index) onClicked: mainItem.contact.core.removePhoneNumber(index)
//: Remove phone number %1
Accessible.name: qsTr("remove_phone_number_accessible_name").arg(phoneTextField.text)
} }
} }
} }
@ -421,16 +432,10 @@ MainRightPanel {
backgroundColor: DefaultStyle.grey_0 backgroundColor: DefaultStyle.grey_0
Keys.onPressed: (event) => { Keys.onPressed: (event) => {
if(event.key == Qt.Key_Up){ if(event.key == Qt.Key_Up){
if(phoneNumberList.count > 0 ) (phoneNumberList.count > 0 ? phoneNumberList.itemAt(phoneNumberList.count - 1) : newAddressTextField).forceActiveFocus(Qt.BacktabFocusReason)
phoneNumberList.itemAt(phoneNumberList.count - 1).forceActiveFocus()
else
newAddressTextField.forceActiveFocus()
event.accepted = true event.accepted = true
}else if(event.key == Qt.Key_Down){ }else if(event.key == Qt.Key_Down){
if(saveButton.enabled) (contactLayoutItem.button.enabled ? contactLayoutItem.button : givenNameEdit).forceActiveFocus(Qt.TabFocusReason)
saveButton.forceActiveFocus()
else
givenNameEdit.forceActiveFocus()
event.accepted = true event.accepted = true
} }
} }
@ -439,6 +444,8 @@ MainRightPanel {
phoneNumberInputTextField.clear() phoneNumberInputTextField.clear()
editionLayout.connectOnce(editionLayout.ensureVisibleRequested, editionLayout.ensureVisible) editionLayout.connectOnce(editionLayout.ensureVisibleRequested, editionLayout.ensureVisible)
} }
//: "New phone number"
Accessible.name: qsTr("new_phone_number_accessible_name")
} }
} }
TemporaryText { TemporaryText {

View file

@ -5,6 +5,7 @@ import QtQuick.Controls.Basic as Control
import Linphone import Linphone
import UtilsCpp import UtilsCpp
import SettingsCpp import SettingsCpp
import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils
import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle
LoginLayout { LoginLayout {
@ -19,23 +20,25 @@ LoginLayout {
BigButton { BigButton {
enabled: mainItem.showBackButton enabled: mainItem.showBackButton
opacity: mainItem.showBackButton ? 1.0 : 0 opacity: mainItem.showBackButton ? 1.0 : 0
Layout.leftMargin: Math.round(79 * DefaultStyle.dp) Layout.leftMargin: Utils.getSizeWithScreenRatio(79)
icon.source: AppIcons.leftArrow icon.source: AppIcons.leftArrow
style: ButtonStyle.noBackground style: ButtonStyle.noBackground
onClicked: { onClicked: {
console.debug("[LoginLayout] User: return") console.debug("[LoginLayout] User: return")
mainItem.goBack() mainItem.goBack()
} }
//: Return
Accessible.name: qsTr("return_accessible_name")
}, },
RowLayout { RowLayout {
spacing: Math.round(15 * DefaultStyle.dp) spacing: Utils.getSizeWithScreenRatio(15)
Layout.leftMargin: Math.round(21 * DefaultStyle.dp) Layout.leftMargin: Utils.getSizeWithScreenRatio(21)
EffectImage { EffectImage {
fillMode: Image.PreserveAspectFit fillMode: Image.PreserveAspectFit
imageSource: AppIcons.profile imageSource: AppIcons.profile
colorizationColor: DefaultStyle.main2_600 colorizationColor: DefaultStyle.main2_600
Layout.preferredHeight: Math.round(34 * DefaultStyle.dp) Layout.preferredHeight: Utils.getSizeWithScreenRatio(34)
Layout.preferredWidth: Math.round(34 * DefaultStyle.dp) Layout.preferredWidth: Utils.getSizeWithScreenRatio(34)
} }
Text { Text {
//: Connexion //: Connexion
@ -51,11 +54,11 @@ LoginLayout {
}, },
RowLayout { RowLayout {
visible: !SettingsCpp.assistantHideCreateAccount visible: !SettingsCpp.assistantHideCreateAccount
spacing: Math.round(20 * DefaultStyle.dp) spacing: Utils.getSizeWithScreenRatio(20)
Layout.rightMargin: Math.round(Math.max(10 * DefaultStyle.dp, (51 - ((51/(DefaultStyle.defaultWidth - mainWindow.minimumWidth))*(DefaultStyle.defaultWidth-mainWindow.width))) * DefaultStyle.dp)) Layout.rightMargin: Math.round(Math.max(10 * DefaultStyle.dp, (51 - ((51/(DefaultStyle.defaultWidth - mainWindow.minimumWidth))*(DefaultStyle.defaultWidth-mainWindow.width))) * DefaultStyle.dp))
Text { Text {
Layout.rightMargin: Math.round(15 * DefaultStyle.dp) Layout.rightMargin: Utils.getSizeWithScreenRatio(15)
//: "Pas encore de compte ?" //: "Pas encore de compte ?"
text: qsTr("assistant_no_account_yet") text: qsTr("assistant_no_account_yet")
font.pixelSize: Typography.p1.pixelSize font.pixelSize: Typography.p1.pixelSize
@ -77,7 +80,7 @@ LoginLayout {
Flickable { Flickable {
anchors.left: parent.left anchors.left: parent.left
anchors.top: parent.top anchors.top: parent.top
anchors.leftMargin: Math.round(127 * DefaultStyle.dp) anchors.leftMargin: Utils.getSizeWithScreenRatio(127)
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
ColumnLayout { ColumnLayout {
id: content id: content
@ -87,8 +90,8 @@ LoginLayout {
} }
BigButton { BigButton {
Layout.preferredWidth: loginForm.width Layout.preferredWidth: loginForm.width
Layout.preferredHeight: Math.round(47 * DefaultStyle.dp) Layout.preferredHeight: Utils.getSizeWithScreenRatio(47)
Layout.topMargin: Math.round(39 * DefaultStyle.dp) Layout.topMargin: Utils.getSizeWithScreenRatio(39)
visible: !SettingsCpp.assistantHideThirdPartyAccount visible: !SettingsCpp.assistantHideThirdPartyAccount
//: "Compte SIP tiers" //: "Compte SIP tiers"
text: qsTr("assistant_login_third_party_sip_account_title") text: qsTr("assistant_login_third_party_sip_account_title")
@ -97,8 +100,8 @@ LoginLayout {
} }
BigButton { BigButton {
Layout.preferredWidth: loginForm.width Layout.preferredWidth: loginForm.width
Layout.preferredHeight: Math.round(47 * DefaultStyle.dp) Layout.preferredHeight: Utils.getSizeWithScreenRatio(47)
Layout.topMargin: Math.round(25 * DefaultStyle.dp) Layout.topMargin: Utils.getSizeWithScreenRatio(25)
//: "Configuration distante" //: "Configuration distante"
text: qsTr("assistant_login_remote_provisioning") text: qsTr("assistant_login_remote_provisioning")
style: ButtonStyle.secondary style: ButtonStyle.secondary
@ -110,22 +113,22 @@ LoginLayout {
z: -1 z: -1
anchors.top: parent.top anchors.top: parent.top
anchors.right: parent.right anchors.right: parent.right
anchors.topMargin: Math.round(129 * DefaultStyle.dp) anchors.topMargin: Utils.getSizeWithScreenRatio(129)
anchors.rightMargin: Math.round(127 * DefaultStyle.dp) anchors.rightMargin: Utils.getSizeWithScreenRatio(127)
width: Math.round(395 * DefaultStyle.dp) width: Utils.getSizeWithScreenRatio(395)
height: Math.round(350 * DefaultStyle.dp) height: Utils.getSizeWithScreenRatio(350)
fillMode: Image.PreserveAspectFit fillMode: Image.PreserveAspectFit
source: AppIcons.loginImage source: AppIcons.loginImage
} }
] ]
Dialog{ Dialog{
id: fetchConfigDialog id: fetchConfigDialog
height: Math.round(315 * DefaultStyle.dp) height: Utils.getSizeWithScreenRatio(315)
width: Math.round(637 * DefaultStyle.dp) width: Utils.getSizeWithScreenRatio(637)
leftPadding: Math.round(33 * DefaultStyle.dp) leftPadding: Utils.getSizeWithScreenRatio(33)
rightPadding: Math.round(33 * DefaultStyle.dp) rightPadding: Utils.getSizeWithScreenRatio(33)
topPadding: Math.round(41 * DefaultStyle.dp) topPadding: Utils.getSizeWithScreenRatio(41)
bottomPadding: Math.round(29 * DefaultStyle.dp) bottomPadding: Utils.getSizeWithScreenRatio(29)
radius: 0 radius: 0
//: "Télécharger une configuration distante" //: "Télécharger une configuration distante"
title: qsTr('assistant_login_download_remote_config') title: qsTr('assistant_login_download_remote_config')
@ -147,7 +150,7 @@ LoginLayout {
TextField{ TextField{
id: configUrl id: configUrl
Layout.fillWidth: true Layout.fillWidth: true
Layout.preferredHeight: Math.round(49 * DefaultStyle.dp) Layout.preferredHeight: Utils.getSizeWithScreenRatio(49)
//: 'Lien de configuration distante' //: 'Lien de configuration distante'
placeholderText: qsTr("settings_advanced_remote_provisioning_url") placeholderText: qsTr("settings_advanced_remote_provisioning_url")
} }

View file

@ -29,6 +29,8 @@ LoginLayout {
console.debug("[SIPLoginPage] User: return") console.debug("[SIPLoginPage] User: return")
mainItem.goBack() mainItem.goBack()
} }
//: Return
Accessible.name: qsTr("return_accessible_name")
} }
EffectImage { EffectImage {
fillMode: Image.PreserveAspectFit fillMode: Image.PreserveAspectFit
@ -194,6 +196,8 @@ LoginLayout {
isError: username.errorTextVisible || (LoginPageCpp.badIds && errorText.isVisible) isError: username.errorTextVisible || (LoginPageCpp.badIds && errorText.isVisible)
Layout.preferredWidth: Math.round(360 * DefaultStyle.dp) Layout.preferredWidth: Math.round(360 * DefaultStyle.dp)
KeyNavigation.down: passwordEdit KeyNavigation.down: passwordEdit
//: "%1 mandatory"
Accessible.name: qsTr("mandatory_field_accessible_name").arg(qsTr("username"))
} }
} }
FormItemLayout { FormItemLayout {
@ -209,6 +213,7 @@ LoginLayout {
Layout.preferredWidth: Math.round(360 * DefaultStyle.dp) Layout.preferredWidth: Math.round(360 * DefaultStyle.dp)
KeyNavigation.up: usernameEdit KeyNavigation.up: usernameEdit
KeyNavigation.down: domainEdit KeyNavigation.down: domainEdit
Accessible.name: qsTr("password")
} }
} }
FormItemLayout { FormItemLayout {
@ -225,6 +230,8 @@ LoginLayout {
Layout.preferredWidth: Math.round(360 * DefaultStyle.dp) Layout.preferredWidth: Math.round(360 * DefaultStyle.dp)
KeyNavigation.up: passwordEdit KeyNavigation.up: passwordEdit
KeyNavigation.down: displayName KeyNavigation.down: displayName
//: "%1 mandatory"
Accessible.name: qsTr("mandatory_field_accessible_name").arg(qsTr("sip_address_domain"))
} }
Connections { Connections {
target: SettingsCpp target: SettingsCpp
@ -242,6 +249,7 @@ LoginLayout {
Layout.preferredWidth: Math.round(360 * DefaultStyle.dp) Layout.preferredWidth: Math.round(360 * DefaultStyle.dp)
KeyNavigation.up: domainEdit KeyNavigation.up: domainEdit
KeyNavigation.down: transportCbox KeyNavigation.down: transportCbox
Accessible.name: qsTr("sip_address_display_name")
} }
} }
FormItemLayout { FormItemLayout {
@ -263,6 +271,9 @@ LoginLayout {
currentIndex: Utils.findIndex(model, function (entry) { currentIndex: Utils.findIndex(model, function (entry) {
return entry.text === SettingsCpp.assistantThirdPartySipAccountTransport.toUpperCase() return entry.text === SettingsCpp.assistantThirdPartySipAccountTransport.toUpperCase()
}) })
KeyNavigation.up: displayName
KeyNavigation.down: outboundProxyUriEdit
Accessible.name: qsTr("transport")
} }
} }
} }
@ -283,6 +294,8 @@ LoginLayout {
id: connectionButton id: connectionButton
Layout.topMargin: Math.round(15 * DefaultStyle.dp) Layout.topMargin: Math.round(15 * DefaultStyle.dp)
style: ButtonStyle.main style: ButtonStyle.main
property Item tabTarget
Accessible.name: qsTr("assistant_account_login")
contentItem: StackLayout { contentItem: StackLayout {
id: connectionButtonContent id: connectionButtonContent
currentIndex: 0 currentIndex: 0
@ -330,7 +343,8 @@ LoginLayout {
loginDelay.restart() loginDelay.restart()
} }
onPressed: trigger() onPressed: trigger()
KeyNavigation.up: transportCbox KeyNavigation.up: connectionId
KeyNavigation.tab: tabTarget
Timer{ Timer{
id: loginDelay id: loginDelay
interval: 200 interval: 200
@ -347,12 +361,13 @@ LoginLayout {
} }
console.debug("[SIPLoginPage] User: Log in") console.debug("[SIPLoginPage] User: Log in")
LoginPageCpp.login(usernameEdit.text, passwordEdit.text, displayName.text, domainEdit.text, LoginPageCpp.login(usernameEdit.text, passwordEdit.text, displayName.text, domainEdit.text,
transportCbox.currentValue, registrarUriEdit.text, outboundProxyUriEdit.text, connectionIdEdit.text); transportCbox.currentValue, serverAddressEdit.text, connectionIdEdit.text);
connectionButton.enabled = false connectionButton.enabled = false
connectionButtonContent.currentIndex = 1 connectionButtonContent.currentIndex = 1
} }
} }
} }
Item { Item {
Layout.fillHeight: true Layout.fillHeight: true
} }
@ -379,6 +394,8 @@ LoginLayout {
contentItem: TextField { contentItem: TextField {
id: outboundProxyUriEdit id: outboundProxyUriEdit
Layout.preferredWidth: Math.round(360 * DefaultStyle.dp) Layout.preferredWidth: Math.round(360 * DefaultStyle.dp)
Accessible.name: qsTr("login_proxy_server_url")
KeyNavigation.up: transportCbox
KeyNavigation.down: registrarUriEdit KeyNavigation.down: registrarUriEdit
} }
} }
@ -390,6 +407,7 @@ LoginLayout {
contentItem: TextField { contentItem: TextField {
id: registrarUriEdit id: registrarUriEdit
Layout.preferredWidth: Math.round(360 * DefaultStyle.dp) Layout.preferredWidth: Math.round(360 * DefaultStyle.dp)
Accessible.name: qsTr("login_registrar_uri")
KeyNavigation.up: outboundProxyUriEdit KeyNavigation.up: outboundProxyUriEdit
KeyNavigation.down: connectionIdEdit KeyNavigation.down: connectionIdEdit
} }
@ -403,6 +421,7 @@ LoginLayout {
id: connectionIdEdit id: connectionIdEdit
Layout.preferredWidth: Math.round(360 * DefaultStyle.dp) Layout.preferredWidth: Math.round(360 * DefaultStyle.dp)
KeyNavigation.up: registrarUriEdit KeyNavigation.up: registrarUriEdit
Accessible.name: qsTr("login_id")
} }
} }
} }

View file

@ -5,182 +5,173 @@ import QtQuick.Controls.Basic as Control
import Linphone import Linphone
import UtilsCpp import UtilsCpp
import SettingsCpp import SettingsCpp
import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
FocusScope{ FocusScope {
id: mainItem id: mainItem
//: "Rechercher des contacts" //: "Rechercher des contacts"
property string placeHolderText: qsTr("search_bar_search_contacts_placeholder") property string placeHolderText: qsTr("search_bar_search_contacts_placeholder")
property list<string> selectedParticipants property list<string> selectedParticipants
property int selectedParticipantsCount: selectedParticipants.length property int selectedParticipantsCount: selectedParticipants.length
property ConferenceInfoGui conferenceInfoGui property ConferenceInfoGui conferenceInfoGui
property color searchBarColor: DefaultStyle.grey_100 property color searchBarColor: DefaultStyle.grey_100
property color searchBarBorderColor: "transparent" property color searchBarBorderColor: "transparent"
property int participantscSrollBarRightMargin: Math.round(8 * DefaultStyle.dp) property int participantscSrollBarRightMargin: Utils.getSizeWithScreenRatio(8)
function clearSelectedParticipants() { function clearSelectedParticipants() {
// TODO // TODO
//contactList.selectedContacts.clear() //contactList.selectedContacts.clear()
} }
ColumnLayout { ColumnLayout {
anchors.fill: parent anchors.fill: parent
spacing: Math.round(15 * DefaultStyle.dp) spacing: Utils.getSizeWithScreenRatio(15)
GridView { GridView {
id: participantList id: participantList
Layout.fillWidth: true Layout.fillWidth: true
visible: contentHeight > 0 visible: contentHeight > 0
Layout.preferredHeight: contentHeight Layout.preferredHeight: contentHeight
Layout.maximumHeight: mainItem.height / 3 Layout.maximumHeight: mainItem.height / 3
width: mainItem.width width: mainItem.width
cellWidth: Math.round((50 + 18) * DefaultStyle.dp) cellWidth: Math.round((50 + 18) * DefaultStyle.dp)
cellHeight: Math.round(80 * DefaultStyle.dp) cellHeight: Utils.getSizeWithScreenRatio(80)
// columnCount: Math.floor(width/cellWidth) // columnCount: Math.floor(width/cellWidth)
model: mainItem.selectedParticipants model: mainItem.selectedParticipants
clip: true clip: true
// columnSpacing: Math.round(18 * DefaultStyle.dp) // columnSpacing: Utils.getSizeWithScreenRatio(18)
// rowSpacing: Math.round(9 * DefaultStyle.dp) // rowSpacing: Utils.getSizeWithScreenRatio(9)
Keys.onPressed: (event) => { Keys.onPressed: event => {
if(currentIndex <=0 && event.key == Qt.Key_Up){ if (currentIndex <= 0 && event.key == Qt.Key_Up) {
nextItemInFocusChain(false).forceActiveFocus() nextItemInFocusChain(false).forceActiveFocus();
} }
} }
header: ColumnLayout { header: ColumnLayout {
Layout.fillWidth: true Layout.fillWidth: true
Text { Text {
Layout.fillWidth: true Layout.fillWidth: true
horizontalAlignment: Text.AlignLeft horizontalAlignment: Text.AlignLeft
visible: mainItem.selectedParticipantsCount > 0 visible: mainItem.selectedParticipantsCount > 0
//: "%n participant(s) sélectionné(s)" //: "%n participant(s) sélectionné(s)"
text: qsTr("add_participant_selected_count", '0', mainItem.selectedParticipantsCount).arg(mainItem.selectedParticipantsCount) text: qsTr("add_participant_selected_count", '0', mainItem.selectedParticipantsCount).arg(mainItem.selectedParticipantsCount)
maximumLineCount: 1 maximumLineCount: 1
color: DefaultStyle.grey_1000 color: DefaultStyle.grey_1000
font { font {
pixelSize: Math.round(12 * DefaultStyle.dp) pixelSize: Utils.getSizeWithScreenRatio(12)
weight: Math.round(300 * DefaultStyle.dp) weight: Utils.getSizeWithScreenRatio(300)
} }
} }
Item { Item {
Layout.preferredHeight: Math.round(10 * DefaultStyle.dp) Layout.preferredHeight: Utils.getSizeWithScreenRatio(10)
} }
} }
delegate: FocusScope { delegate: FocusScope {
ColumnLayout { ColumnLayout {
anchors.fill: parent anchors.fill: parent
spacing: Math.round(4 * DefaultStyle.dp) spacing: Utils.getSizeWithScreenRatio(4)
width: Math.round(50 * DefaultStyle.dp) width: Utils.getSizeWithScreenRatio(50)
Item { Item {
Layout.alignment: Qt.AlignHCenter id: participantItem
Layout.preferredWidth: Math.round(50 * DefaultStyle.dp) property var nameObj: UtilsCpp.getDisplayName(modelData)
Layout.preferredHeight: Math.round(50 * DefaultStyle.dp) property string displayName: nameObj ? nameObj.value : ""
Avatar { Layout.alignment: Qt.AlignHCenter
anchors.fill: parent Layout.preferredWidth: Utils.getSizeWithScreenRatio(50)
_address: modelData Layout.preferredHeight: Utils.getSizeWithScreenRatio(50)
shadowEnabled: false Avatar {
secured: friendSecurityLevel === LinphoneEnums.SecurityLevel.EndToEndEncryptedAndVerified anchors.fill: parent
} _address: modelData
Button { shadowEnabled: false
Layout.preferredWidth: Math.round(17 * DefaultStyle.dp) secured: friendSecurityLevel === LinphoneEnums.SecurityLevel.EndToEndEncryptedAndVerified
Layout.preferredHeight: Math.round(17 * DefaultStyle.dp) }
icon.width: Math.round(12 * DefaultStyle.dp) Button {
icon.height: Math.round(12 * DefaultStyle.dp) width: Utils.getSizeWithScreenRatio(17)
icon.source: AppIcons.closeX height: Utils.getSizeWithScreenRatio(17)
anchors.top: parent.top icon.width: Utils.getSizeWithScreenRatio(12)
anchors.right: parent.right icon.height: Utils.getSizeWithScreenRatio(12)
background: Item { icon.source: AppIcons.closeX
Rectangle { anchors.top: parent.top
id: backgroundRect anchors.right: parent.right
color: DefaultStyle.grey_0 //: Remove participant %1
anchors.fill: parent Accessible.name: qsTr("remove_participant_accessible_name").arg(participantItem.displayName)
radius: Math.round(50 * DefaultStyle.dp) style: ButtonStyle.whiteSelected
} shadowEnabled: true
MultiEffect { onClicked: contactList.removeSelectedContactByAddress(modelData)
anchors.fill: backgroundRect }
source: backgroundRect }
shadowEnabled: true Text {
shadowColor: DefaultStyle.grey_1000 Layout.alignment: Qt.AlignHCenter
shadowBlur: 0.1 Layout.preferredWidth: width
shadowOpacity: 0.5 width: Utils.getSizeWithScreenRatio(50)
} maximumLineCount: 1
} clip: true
onClicked: contactList.removeSelectedContactByAddress(modelData) text: participantItem.displayName
} color: DefaultStyle.main2_700
} wrapMode: Text.WrapAnywhere
Text {
Layout.alignment: Qt.AlignHCenter
Layout.preferredWidth: width
width: Math.round(50 * DefaultStyle.dp)
maximumLineCount: 1
clip: true
property var nameObj: UtilsCpp.getDisplayName(modelData)
text: nameObj ? nameObj.value : ""
color: DefaultStyle.main2_700
wrapMode: Text.WrapAnywhere
font { font {
pixelSize: Typography.p3.pixelSize pixelSize: Typography.p3.pixelSize
weight: Typography.p3.weight weight: Typography.p3.weight
capitalization: Font.Capitalize capitalization: Font.Capitalize
} }
} }
} }
} }
Control.ScrollBar.vertical: ScrollBar { Control.ScrollBar.vertical: ScrollBar {
id: scrollbar id: scrollbar
active: true active: true
interactive: true interactive: true
policy: Control.ScrollBar.AsNeeded policy: Control.ScrollBar.AsNeeded
anchors.top: parent.top anchors.top: parent.top
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
anchors.right: parent.right anchors.right: parent.right
anchors.rightMargin: mainItem.participantscSrollBarRightMargin anchors.rightMargin: mainItem.participantscSrollBarRightMargin
visible: participantList.height < participantList.contentHeight visible: participantList.height < participantList.contentHeight
} }
} }
SearchBar { SearchBar {
id: searchBar id: searchBar
Layout.fillWidth: true Layout.fillWidth: true
Layout.topMargin: Math.round(6 * DefaultStyle.dp) Layout.topMargin: Utils.getSizeWithScreenRatio(6)
Layout.rightMargin: Math.round(28 * DefaultStyle.dp) Layout.rightMargin: Utils.getSizeWithScreenRatio(28)
Layout.preferredHeight: Math.round(45 * DefaultStyle.dp) Layout.preferredHeight: Utils.getSizeWithScreenRatio(45)
placeholderText: mainItem.placeHolderText placeholderText: mainItem.placeHolderText
focus: participantList.count == 0 focus: participantList.count == 0
color: mainItem.searchBarColor color: mainItem.searchBarColor
borderColor: mainItem.searchBarColor borderColor: mainItem.searchBarColor
KeyNavigation.up: participantList.count > 0 KeyNavigation.up: participantList.count > 0 ? participantList : nextItemInFocusChain(false)
? participantList KeyNavigation.down: contactList
: nextItemInFocusChain(false) }
KeyNavigation.down: contactList ColumnLayout {
} id: content
ColumnLayout { spacing: Utils.getSizeWithScreenRatio(15)
id: content Text {
spacing: Math.round(15 * DefaultStyle.dp) visible: !contactList.loading && contactList.count === 0
Text { Layout.alignment: Qt.AlignHCenter
visible: !contactList.loading && contactList.count === 0 Layout.topMargin: Utils.getSizeWithScreenRatio(137)
Layout.alignment: Qt.AlignHCenter
Layout.topMargin: Math.round(137 * DefaultStyle.dp)
//: "Aucun contact" //: "Aucun contact"
text: searchBar.text.length !== 0 ? qsTr("list_filter_no_result_found") : qsTr("contact_list_empty") text: searchBar.text.length !== 0 ? qsTr("list_filter_no_result_found") : qsTr("contact_list_empty")
font { font {
pixelSize: Typography.h4.pixelSize pixelSize: Typography.h4.pixelSize
weight: Typography.h4.weight weight: Typography.h4.weight
} }
} }
AllContactListView{ AllContactListView {
id: contactList id: contactList
Layout.fillWidth: true Layout.fillWidth: true
Layout.fillHeight: true Layout.fillHeight: true
itemsRightMargin: Math.round(28 * DefaultStyle.dp) itemsRightMargin: Utils.getSizeWithScreenRatio(28)
multiSelectionEnabled: true multiSelectionEnabled: true
showContactMenu: false showContactMenu: false
confInfoGui: mainItem.conferenceInfoGui confInfoGui: mainItem.conferenceInfoGui
selectedContacts: mainItem.selectedParticipants selectedContacts: mainItem.selectedParticipants
onSelectedContactsChanged: Qt.callLater(function(){mainItem.selectedParticipants = selectedContacts}) onSelectedContactsChanged: Qt.callLater(function () {
searchBarText: searchBar.text mainItem.selectedParticipants = selectedContacts;
onContactAddedToSelection: (address) => { })
contactList.addContactToSelection(address) searchBarText: searchBar.text
} onContactAddedToSelection: address => {
onContactRemovedFromSelection: (address) => contactList.removeSelectedContactByAddress(address) contactList.addContactToSelection(address);
} }
} onContactRemovedFromSelection: address => contactList.removeSelectedContactByAddress(address)
} }
}
}
} }

View file

@ -239,6 +239,7 @@ FocusScope {
event.accepted = true; event.accepted = true;
} }
} }
KeyNavigation.tab: addParticipantsButton
background: Rectangle { background: Rectangle {
anchors.fill: parent anchors.fill: parent
color: descriptionEdit.hovered || descriptionEdit.activeFocus ? DefaultStyle.grey_100 : "transparent" color: descriptionEdit.hovered || descriptionEdit.activeFocus ? DefaultStyle.grey_100 : "transparent"

View file

@ -4,6 +4,7 @@ import QtQuick.Controls.Basic as Control
import Linphone import Linphone
import UtilsCpp 1.0 import UtilsCpp 1.0
import ConstantsCpp 1.0 import ConstantsCpp 1.0
import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils
import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle
LoginLayout { LoginLayout {
@ -32,8 +33,8 @@ LoginLayout {
titleContent: [ titleContent: [
RowLayout { RowLayout {
spacing: Math.round(21 * DefaultStyle.dp) spacing: Utils.getSizeWithScreenRatio(21)
Layout.leftMargin: Math.round(79 * DefaultStyle.dp) Layout.leftMargin: Utils.getSizeWithScreenRatio(79)
BigButton { BigButton {
style: ButtonStyle.noBackground style: ButtonStyle.noBackground
icon.source: AppIcons.leftArrow icon.source: AppIcons.leftArrow
@ -41,12 +42,14 @@ LoginLayout {
console.debug("[RegisterPage] User: return") console.debug("[RegisterPage] User: return")
returnToLogin() returnToLogin()
} }
//: Return
Accessible.name: qsTr("return_accessible_name")
} }
EffectImage { EffectImage {
fillMode: Image.PreserveAspectFit fillMode: Image.PreserveAspectFit
imageSource: AppIcons.profile imageSource: AppIcons.profile
Layout.preferredHeight: Math.round(34 * DefaultStyle.dp) Layout.preferredHeight: Utils.getSizeWithScreenRatio(34)
Layout.preferredWidth: Math.round(34 * DefaultStyle.dp) Layout.preferredWidth: Utils.getSizeWithScreenRatio(34)
colorizationColor: DefaultStyle.main2_600 colorizationColor: DefaultStyle.main2_600
} }
Text { Text {
@ -65,10 +68,10 @@ LoginLayout {
Layout.fillWidth: true Layout.fillWidth: true
}, },
RowLayout { RowLayout {
spacing: Math.round(20 * DefaultStyle.dp) spacing: Utils.getSizeWithScreenRatio(20)
Layout.rightMargin: Math.round(Math.max(10 * DefaultStyle.dp,(51 - ((51/(DefaultStyle.defaultWidth - mainWindow.minimumWidth))*(DefaultStyle.defaultWidth-mainWindow.width))) * DefaultStyle.dp)) Layout.rightMargin: Math.round(Math.max(10 * DefaultStyle.dp,(51 - ((51/(DefaultStyle.defaultWidth - mainWindow.minimumWidth))*(DefaultStyle.defaultWidth-mainWindow.width))) * DefaultStyle.dp))
Text { Text {
Layout.rightMargin: Math.round(15 * DefaultStyle.dp) Layout.rightMargin: Utils.getSizeWithScreenRatio(15)
color: DefaultStyle.main2_700 color: DefaultStyle.main2_700
// "Déjà un compte ?" // "Déjà un compte ?"
text: qsTr("assistant_already_have_an_account") text: qsTr("assistant_already_have_an_account")
@ -92,13 +95,13 @@ LoginLayout {
ColumnLayout { ColumnLayout {
id: registerForm id: registerForm
anchors.fill: parent anchors.fill: parent
anchors.leftMargin: Math.round(127 * DefaultStyle.dp) anchors.leftMargin: Utils.getSizeWithScreenRatio(127)
spacing: Math.round(50 * DefaultStyle.dp) spacing: Utils.getSizeWithScreenRatio(50)
TabBar { TabBar {
Layout.fillWidth: true Layout.fillWidth: true
id: bar id: bar
spacing: Math.round(40 * DefaultStyle.dp) spacing: Utils.getSizeWithScreenRatio(40)
Layout.rightMargin: Math.round(Math.max(5 * DefaultStyle.dp,(127 - ((127/(DefaultStyle.defaultWidth - mainWindow.minimumWidth))*(DefaultStyle.defaultWidth-mainWindow.width))) * DefaultStyle.dp)) Layout.rightMargin: Math.round(Math.max(5 * DefaultStyle.dp,(127 - ((127/(DefaultStyle.defaultWidth - mainWindow.minimumWidth))*(DefaultStyle.defaultWidth-mainWindow.width))) * DefaultStyle.dp))
// "S'inscrire avec un numéro de téléphone" // "S'inscrire avec un numéro de téléphone"
model: [qsTr("assistant_account_register_with_phone_number"), model: [qsTr("assistant_account_register_with_phone_number"),
@ -127,35 +130,38 @@ LoginLayout {
id: contentLayout id: contentLayout
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
spacing: Math.round(8 * DefaultStyle.dp) spacing: Utils.getSizeWithScreenRatio(8)
ColumnLayout { ColumnLayout {
id: formLayout id: formLayout
spacing: Math.round(24 * DefaultStyle.dp) spacing: Utils.getSizeWithScreenRatio(24)
RowLayout { RowLayout {
Layout.preferredHeight: usernameItem.height Layout.preferredHeight: usernameItem.height
spacing: Math.round(16 * DefaultStyle.dp) spacing: Utils.getSizeWithScreenRatio(16)
FormItemLayout { FormItemLayout {
id: usernameItem id: usernameItem
label: qsTr("username") label: qsTr("username")
mandatory: true mandatory: true
enableErrorText: true enableErrorText: true
Layout.preferredWidth: Math.round(346 * DefaultStyle.dp) Layout.preferredWidth: Utils.getSizeWithScreenRatio(346)
contentItem: TextField { contentItem: TextField {
id: usernameInput id: usernameInput
backgroundBorderColor: usernameItem.errorMessage.length > 0 ? DefaultStyle.danger_500main : DefaultStyle.grey_200 backgroundBorderColor: usernameItem.errorMessage.length > 0 ? DefaultStyle.danger_500_main : DefaultStyle.grey_200
//: "%1 mandatory"
Accessible.name: qsTr("mandatory_field_accessible_name").arg(qsTr("username"))
} }
} }
RowLayout { RowLayout {
spacing: Math.round(10 * DefaultStyle.dp) spacing: Utils.getSizeWithScreenRatio(10)
ComboBox { ComboBox {
Layout.preferredWidth: Math.round(210 * DefaultStyle.dp) Layout.preferredWidth: Utils.getSizeWithScreenRatio(210)
Layout.preferredHeight: Math.round(49 * DefaultStyle.dp) Layout.preferredHeight: Utils.getSizeWithScreenRatio(49)
enabled: false enabled: false
model: [{text:"@sip.linphone.org"}] model: [{text:"@sip.linphone.org"}]
Accessible.name: qsTr("domain")
} }
EffectImage { EffectImage {
Layout.preferredWidth: Math.round(16 * DefaultStyle.dp) Layout.preferredWidth: Utils.getSizeWithScreenRatio(16)
Layout.preferredHeight: Math.round(16 * DefaultStyle.dp) Layout.preferredHeight: Utils.getSizeWithScreenRatio(16)
imageSource: AppIcons.lock imageSource: AppIcons.lock
colorizationColor: DefaultStyle.main2_600 colorizationColor: DefaultStyle.main2_600
} }
@ -165,7 +171,7 @@ LoginLayout {
currentIndex: bar.currentIndex currentIndex: bar.currentIndex
PhoneNumberInput { PhoneNumberInput {
id: phoneNumberInput id: phoneNumberInput
Layout.preferredWidth: Math.round(346 * DefaultStyle.dp) Layout.preferredWidth: Utils.getSizeWithScreenRatio(346)
property string completePhoneNumber: countryCode + phoneNumber property string completePhoneNumber: countryCode + phoneNumber
//: "Numéro de téléphone" //: "Numéro de téléphone"
label: qsTr("phone_number") label: qsTr("phone_number")
@ -173,17 +179,21 @@ LoginLayout {
mandatory: true mandatory: true
placeholderText: qsTr("phone_number") placeholderText: qsTr("phone_number")
defaultCallingCode: "33" defaultCallingCode: "33"
//: "%1 mandatory"
Accessible.name: qsTr("mandatory_field_accessible_name").arg(qsTr("phone_number"))
} }
FormItemLayout { FormItemLayout {
id: emailItem id: emailItem
Layout.fillWidth: false Layout.fillWidth: false
Layout.preferredWidth: Math.round(346 * DefaultStyle.dp) Layout.preferredWidth: Utils.getSizeWithScreenRatio(346)
label: qsTr("email") label: qsTr("email")
mandatory: true mandatory: true
enableErrorText: true enableErrorText: true
contentItem: TextField { contentItem: TextField {
id: emailInput id: emailInput
backgroundBorderColor: emailItem.errorMessage.length > 0 ? DefaultStyle.danger_500main : DefaultStyle.grey_200 backgroundBorderColor: emailItem.errorMessage.length > 0 ? DefaultStyle.danger_500_main : DefaultStyle.grey_200
//: "%1 mandatory"
Accessible.name: qsTr("mandatory_field_accessible_name").arg(qsTr("email"))
} }
} }
} }
@ -193,22 +203,24 @@ LoginLayout {
clip: false clip: false
RowLayout { RowLayout {
id: rowlayout id: rowlayout
spacing: Math.round(16 * DefaultStyle.dp) spacing: Utils.getSizeWithScreenRatio(16)
FormItemLayout { FormItemLayout {
id: passwordItem id: passwordItem
Layout.preferredWidth: Math.round(346 * DefaultStyle.dp) Layout.preferredWidth: Utils.getSizeWithScreenRatio(346)
label: qsTr("password") label: qsTr("password")
mandatory: true mandatory: true
enableErrorText: true enableErrorText: true
contentItem: TextField { contentItem: TextField {
id: pwdInput id: pwdInput
hidden: true hidden: true
Layout.preferredWidth: Math.round(346 * DefaultStyle.dp) Layout.preferredWidth: Utils.getSizeWithScreenRatio(346)
backgroundBorderColor: passwordItem.errorMessage.length > 0 ? DefaultStyle.danger_500main : DefaultStyle.grey_200 backgroundBorderColor: passwordItem.errorMessage.length > 0 ? DefaultStyle.danger_500_main : DefaultStyle.grey_200
//: "%1 mandatory"
Accessible.name: qsTr("mandatory_field_accessible_name").arg(qsTr("password"))
} }
} }
FormItemLayout { FormItemLayout {
Layout.preferredWidth: Math.round(346 * DefaultStyle.dp) Layout.preferredWidth: Utils.getSizeWithScreenRatio(346)
//: "Confirmation mot de passe" //: "Confirmation mot de passe"
label: qsTr("assistant_account_register_password_confirmation") label: qsTr("assistant_account_register_password_confirmation")
mandatory: true mandatory: true
@ -216,22 +228,24 @@ LoginLayout {
contentItem: TextField { contentItem: TextField {
id: confirmPwdInput id: confirmPwdInput
hidden: true hidden: true
Layout.preferredWidth: Math.round(346 * DefaultStyle.dp) Layout.preferredWidth: Utils.getSizeWithScreenRatio(346)
backgroundBorderColor: passwordItem.errorMessage.length > 0 ? DefaultStyle.danger_500main : DefaultStyle.grey_200 backgroundBorderColor: passwordItem.errorMessage.length > 0 ? DefaultStyle.danger_500_main : DefaultStyle.grey_200
//: "%1 mandatory"
Accessible.name: qsTr("mandatory_field_accessible_name").arg(qsTr("assistant_account_register_password_confirmation"))
} }
} }
} }
TemporaryText { TemporaryText {
id: otherErrorText id: otherErrorText
Layout.fillWidth: true Layout.fillWidth: true
Layout.topMargin: Math.round(5 * DefaultStyle.dp) Layout.topMargin: Utils.getSizeWithScreenRatio(5)
} }
} }
} }
// ColumnLayout { // ColumnLayout {
// spacing: Math.round(18 * DefaultStyle.dp) // spacing: Utils.getSizeWithScreenRatio(18)
// RowLayout { // RowLayout {
// spacing: Math.round(10 * DefaultStyle.dp) // spacing: Utils.getSizeWithScreenRatio(10)
// CheckBox { // CheckBox {
// id: subscribeToNewsletterCheckBox // id: subscribeToNewsletterCheckBox
// } // }
@ -249,17 +263,20 @@ LoginLayout {
// } // }
RowLayout { RowLayout {
spacing: Math.round(10 * DefaultStyle.dp) id: acceptCguAndPrivacyPolicyItem
CheckBox { spacing: Utils.getSizeWithScreenRatio(10)
id: termsCheckBox //: "J'accepte les %1 et la %2"
} property string associatedText: qsTr("assistant_dialog_cgu_and_privacy_policy_message")
Text {
//: "J'accepte les %1 et la %2"
text: qsTr("assistant_dialog_cgu_and_privacy_policy_message")
//: "conditions d'utilisation" //: "conditions d'utilisation"
.arg(("<a href='%1'><font color='DefaultStyle.main2_600'>%2</font></a>").arg(ConstantsCpp.CguUrl).arg(qsTr("assistant_dialog_general_terms_label"))) .arg(("<a href='%1'><font color='DefaultStyle.main2_600'>%2</font></a>").arg(ConstantsCpp.CguUrl).arg(qsTr("assistant_dialog_general_terms_label")))
//: "politique de confidentialité" //: "politique de confidentialité"
.arg(("<a href='%1'><font color='DefaultStyle.main2_600'>%2</font></a>").arg(ConstantsCpp.PrivatePolicyUrl).arg(qsTr("assistant_dialog_privacy_policy_label"))) .arg(("<a href='%1'><font color='DefaultStyle.main2_600'>%2</font></a>").arg(ConstantsCpp.PrivatePolicyUrl).arg(qsTr("assistant_dialog_privacy_policy_label")))
CheckBox {
id: termsCheckBox
Accessible.name: acceptCguAndPrivacyPolicyItem.associatedText
}
Text {
text: acceptCguAndPrivacyPolicyItem.associatedText
onLinkActivated: (link) => Qt.openUrlExternally(link) onLinkActivated: (link) => Qt.openUrlExternally(link)
font { font {
pixelSize: Typography.p1.pixelSize pixelSize: Typography.p1.pixelSize
@ -318,10 +335,10 @@ LoginLayout {
// visible: registerForm.x+registerForm.width < x // visible: registerForm.x+registerForm.width < x
anchors.top: parent.top anchors.top: parent.top
anchors.right: parent.right anchors.right: parent.right
anchors.topMargin: Math.round(129 * DefaultStyle.dp) anchors.topMargin: Utils.getSizeWithScreenRatio(129)
anchors.rightMargin: Math.round(127 * DefaultStyle.dp) anchors.rightMargin: Utils.getSizeWithScreenRatio(127)
width: Math.round(395 * DefaultStyle.dp) width: Utils.getSizeWithScreenRatio(395)
height: Math.round(350 * DefaultStyle.dp) height: Utils.getSizeWithScreenRatio(350)
fillMode: Image.PreserveAspectFit fillMode: Image.PreserveAspectFit
source: AppIcons.loginImage source: AppIcons.loginImage
} }

View file

@ -4,6 +4,7 @@ import QtQuick.Layouts
import QtQuick.Controls.Basic as Control import QtQuick.Controls.Basic as Control
import Linphone import Linphone
import UtilsCpp import UtilsCpp
import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils
import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle
AbstractMainPage { AbstractMainPage {
@ -28,17 +29,19 @@ AbstractMainPage {
id: leftPanel id: leftPanel
Layout.fillWidth: true Layout.fillWidth: true
Layout.fillHeight: true Layout.fillHeight: true
property real sideMargin: Math.round(45 * DefaultStyle.dp) property real sideMargin: Utils.getSizeWithScreenRatio(45)
spacing: Math.round(5 * DefaultStyle.dp) spacing: Utils.getSizeWithScreenRatio(5)
RowLayout { RowLayout {
Layout.fillWidth: true Layout.fillWidth: true
Layout.leftMargin: leftPanel.sideMargin Layout.leftMargin: leftPanel.sideMargin
Layout.rightMargin: leftPanel.sideMargin Layout.rightMargin: leftPanel.sideMargin
spacing: Math.round(5 * DefaultStyle.dp) spacing: Utils.getSizeWithScreenRatio(5)
Button { Button {
id: backButton id: backButton
Layout.preferredHeight: Math.round(24 * DefaultStyle.dp) icon.width: Utils.getSizeWithScreenRatio(24)
Layout.preferredWidth: Math.round(24 * DefaultStyle.dp) icon.height: Utils.getSizeWithScreenRatio(24)
Layout.preferredWidth: Utils.getSizeWithScreenRatio(30)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(30)
icon.source: AppIcons.leftArrow icon.source: AppIcons.leftArrow
style: ButtonStyle.noBackground style: ButtonStyle.noBackground
focus: true focus: true
@ -61,10 +64,11 @@ AbstractMainPage {
Layout.fillWidth: true Layout.fillWidth: true
Layout.fillHeight: true Layout.fillHeight: true
model: mainItem.families model: mainItem.families
Layout.topMargin: Math.round(41 * DefaultStyle.dp) Layout.topMargin: Utils.getSizeWithScreenRatio(41)
Layout.leftMargin: leftPanel.sideMargin Layout.leftMargin: leftPanel.sideMargin
property int selectedIndex: mainItem.defaultIndex != -1 ? mainItem.defaultIndex : 0 property int selectedIndex: mainItem.defaultIndex != -1 ? mainItem.defaultIndex : 0
activeFocusOnTab: true activeFocusOnTab: true
spacing: Utils.getSizeWithScreenRatio(5)
delegate: SettingsMenuItem { delegate: SettingsMenuItem {
titleText: modelData.title titleText: modelData.title

View file

@ -118,7 +118,7 @@ ColumnLayout {
anchors.fill: parent anchors.fill: parent
fillMode: Image.PreserveAspectFit fillMode: Image.PreserveAspectFit
imageSource: titleMainItem.isEditingSubject ? AppIcons.check : AppIcons.pencil imageSource: titleMainItem.isEditingSubject ? AppIcons.check : AppIcons.pencil
colorizationColor: titleMainItem.isEditingSubject ? DefaultStyle.main1_500_main : DefaultStyle.main2_500main colorizationColor: titleMainItem.isEditingSubject ? DefaultStyle.main1_500_main : DefaultStyle.main2_500_main
} }
MouseArea { MouseArea {
@ -352,7 +352,7 @@ ColumnLayout {
visible: true, visible: true,
//: Delete history //: Delete history
text: qsTr("group_infos_delete_history"), text: qsTr("group_infos_delete_history"),
color: DefaultStyle.danger_500main, color: DefaultStyle.danger_500_main,
showRightArrow: false, showRightArrow: false,
action: function() { action: function() {
//: Delete history ? //: Delete history ?
@ -383,7 +383,7 @@ ColumnLayout {
icon: AppIcons.trashCan, icon: AppIcons.trashCan,
visible: true, visible: true,
text: qsTr("one_one_infos_delete_history"), text: qsTr("one_one_infos_delete_history"),
color: DefaultStyle.danger_500main, color: DefaultStyle.danger_500_main,
showRightArrow: false, showRightArrow: false,
action: function() { action: function() {
//: Delete history ? //: Delete history ?

View file

@ -93,7 +93,7 @@ ColumnLayout {
visible: participantCore.isAdmin visible: participantCore.isAdmin
text: qsTr("group_infos_participant_is_admin") text: qsTr("group_infos_participant_is_admin")
font: Typography.p3 font: Typography.p3
color: DefaultStyle.main2_500main color: DefaultStyle.main2_500_main
} }
} }
} }

View file

@ -8,6 +8,7 @@ import QtQuick.Controls.Basic as Control
import Linphone import Linphone
import ConstantsCpp import ConstantsCpp
import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils
import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle
Rectangle { Rectangle {
@ -18,15 +19,15 @@ Rectangle {
component AboutLine: RowLayout { component AboutLine: RowLayout {
id: line id: line
spacing: Math.round(20 * DefaultStyle.dp) spacing: Utils.getSizeWithScreenRatio(20)
property var imageSource property var imageSource
property string title property string title
property string text property string text
property bool enableMouseArea: false property bool enableMouseArea: false
signal contentClicked() signal contentClicked()
EffectImage { EffectImage {
Layout.preferredWidth: Math.round(32 * DefaultStyle.dp) Layout.preferredWidth: Utils.getSizeWithScreenRatio(32)
Layout.preferredHeight: Math.round(32 * DefaultStyle.dp) Layout.preferredHeight: Utils.getSizeWithScreenRatio(32)
imageSource: parent.imageSource imageSource: parent.imageSource
colorizationColor: DefaultStyle.main1_500_main colorizationColor: DefaultStyle.main1_500_main
} }
@ -46,8 +47,8 @@ Rectangle {
id: content id: content
Layout.fillWidth: true Layout.fillWidth: true
text: line.text text: line.text
color: DefaultStyle.main2_500main color: DefaultStyle.main2_500_main
font.pixelSize: Math.round(14 * DefaultStyle.dp) font.pixelSize: Utils.getSizeWithScreenRatio(14)
horizontalAlignment: Layout.AlignLeft horizontalAlignment: Layout.AlignLeft
Keys.onPressed: (event)=> { Keys.onPressed: (event)=> {
if (event.key == Qt.Key_Space || event.key == Qt.Key_Enter || event.key == Qt.Key_Return) { if (event.key == Qt.Key_Space || event.key == Qt.Key_Enter || event.key == Qt.Key_Return) {
@ -71,14 +72,14 @@ Rectangle {
Dialog { Dialog {
id: aboutPopup id: aboutPopup
anchors.centerIn: parent anchors.centerIn: parent
width: Math.round(637 * DefaultStyle.dp) width: Utils.getSizeWithScreenRatio(637)
//: À propos de %1 //: À propos de %1
title: qsTr("help_about_title").arg(applicationName) title: qsTr("help_about_title").arg(applicationName)
bottomPadding: Math.round(10 * DefaultStyle.dp) bottomPadding: Utils.getSizeWithScreenRatio(10)
buttons: [] buttons: []
content: RowLayout { content: RowLayout {
ColumnLayout { ColumnLayout {
spacing: Math.round(17 * DefaultStyle.dp) spacing: Utils.getSizeWithScreenRatio(17)
Layout.alignment: Qt.AlignTop | Qt.AlignLeft Layout.alignment: Qt.AlignTop | Qt.AlignLeft
AboutLine { AboutLine {
imageSource: AppIcons.detective imageSource: AppIcons.detective
@ -109,7 +110,7 @@ Rectangle {
} }
Item { Item {
// Item to shift close button // Item to shift close button
Layout.preferredHeight: Math.round(10 * DefaultStyle.dp) Layout.preferredHeight: Utils.getSizeWithScreenRatio(10)
} }
} }
MediumButton { MediumButton {
@ -137,10 +138,10 @@ Rectangle {
id: aboutButton id: aboutButton
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
icon.source: AppIcons.info icon.source: AppIcons.info
text: qsTr("help_about_title").arg(applicationName) text: qsTr("help_about_title").arg(applicationName)
textSize: Typography.p1.pixelSize textSize: Typography.p1.pixelSize
textWeight: Typography.p1.weight textWeight: Typography.p1.weight
textColor: DefaultStyle.main2_500main textColor: DefaultStyle.main2_500_main
onClicked: aboutPopup.open() onClicked: aboutPopup.open()
style: ButtonStyle.noBackground style: ButtonStyle.noBackground
} }
@ -165,7 +166,7 @@ Rectangle {
source: AppIcons.belledonne source: AppIcons.belledonne
fillMode: Image.Stretch fillMode: Image.Stretch
Layout.fillWidth: true Layout.fillWidth: true
Layout.preferredHeight: Math.round(108 * DefaultStyle.dp) Layout.preferredHeight: Utils.getSizeWithScreenRatio(108)
} }
} }

View file

@ -24,64 +24,65 @@ Item {
signal displayChatRequested(string contactAddress) signal displayChatRequested(string contactAddress)
signal openChatRequested(ChatGui chat) signal openChatRequested(ChatGui chat)
signal createContactRequested(string name, string address) signal createContactRequested(string name, string address)
signal scheduleMeetingRequested(string subject, list<string> addresses) signal scheduleMeetingRequested(string subject, list<string> addresses)
signal accountRemoved signal accountRemoved
function goToNewCall() { function goToNewCall() {
tabbar.currentIndex = 0 tabbar.currentIndex = 0;
mainItem.openNewCallRequest() mainItem.openNewCallRequest();
} }
function goToCallHistory() { function goToCallHistory() {
tabbar.currentIndex = 0 tabbar.currentIndex = 0;
mainItem.openCallHistory() mainItem.openCallHistory();
} }
function displayContactPage(contactAddress) { function displayContactPage(contactAddress) {
tabbar.currentIndex = 1 tabbar.currentIndex = 1;
mainItem.displayContactRequested(contactAddress) mainItem.displayContactRequested(contactAddress);
} }
function displayChatPage(contactAddress) { function displayChatPage(contactAddress) {
tabbar.currentIndex = 2 tabbar.currentIndex = 2;
mainItem.displayChatRequested(contactAddress) mainItem.displayChatRequested(contactAddress);
} }
function openChat(chat) { function openChat(chat) {
tabbar.currentIndex = 2 tabbar.currentIndex = 2;
mainItem.openChatRequested(chat) mainItem.openChatRequested(chat);
} }
function createContact(name, address) { function createContact(name, address) {
tabbar.currentIndex = 1 tabbar.currentIndex = 1;
mainItem.createContactRequested(name, address) mainItem.createContactRequested(name, address);
} }
function scheduleMeeting(subject, addresses) { function scheduleMeeting(subject, addresses) {
tabbar.currentIndex = 3 tabbar.currentIndex = 3;
mainItem.scheduleMeetingRequested(subject, addresses) mainItem.scheduleMeetingRequested(subject, addresses);
} }
function openContextualMenuComponent(component) { function openContextualMenuComponent(component) {
if (mainItem.contextualMenuOpenedComponent if (mainItem.contextualMenuOpenedComponent && mainItem.contextualMenuOpenedComponent != component) {
&& mainItem.contextualMenuOpenedComponent != component) { mainStackView.pop();
mainStackView.pop()
if (mainItem.contextualMenuOpenedComponent) { if (mainItem.contextualMenuOpenedComponent) {
mainItem.contextualMenuOpenedComponent.destroy() mainItem.contextualMenuOpenedComponent.destroy();
} }
mainItem.contextualMenuOpenedComponent = undefined mainItem.contextualMenuOpenedComponent = undefined;
} }
if (!mainItem.contextualMenuOpenedComponent) { if (!mainItem.contextualMenuOpenedComponent) {
mainStackView.push(component) mainStackView.push(component);
mainItem.contextualMenuOpenedComponent = component mainItem.contextualMenuOpenedComponent = component;
} }
settingsMenuButton.popup.close() settingsMenuButton.popup.close();
} }
function closeContextualMenuComponent() { function closeContextualMenuComponent() {
mainStackView.pop() mainStackView.pop();
if (mainItem.contextualMenuOpenedComponent) if (mainItem.contextualMenuOpenedComponent)
mainItem.contextualMenuOpenedComponent.destroy() mainItem.contextualMenuOpenedComponent.destroy();
mainItem.contextualMenuOpenedComponent = undefined mainItem.contextualMenuOpenedComponent = undefined;
} }
function openAccountSettings(account) { function openAccountSettings(account) {
var page = accountSettingsPageComponent.createObject(parent, {"account": account}) var page = accountSettingsPageComponent.createObject(parent, {
openContextualMenuComponent(page) "account": account
});
openContextualMenuComponent(page);
} }
AccountProxy { AccountProxy {
@ -103,10 +104,7 @@ Item {
id: currentCallNotif id: currentCallNotif
background: Item {} background: Item {}
closePolicy: Control.Popup.NoAutoClose closePolicy: Control.Popup.NoAutoClose
visible: currentCall visible: currentCall && currentCall.core.state != LinphoneEnums.CallState.Idle && currentCall.core.state != LinphoneEnums.CallState.IncomingReceived && currentCall.core.state != LinphoneEnums.CallState.PushIncomingReceived
&& currentCall.core.state != LinphoneEnums.CallState.Idle
&& currentCall.core.state != LinphoneEnums.CallState.IncomingReceived
&& currentCall.core.state != LinphoneEnums.CallState.PushIncomingReceived
x: mainItem.width / 2 - width / 2 x: mainItem.width / 2 - width / 2
y: contentItem.height / 2 y: contentItem.height / 2
property var currentCall: callsModel.currentCall ? callsModel.currentCall : null property var currentCall: callsModel.currentCall ? callsModel.currentCall : null
@ -115,9 +113,8 @@ Item {
style: ButtonStyle.toast style: ButtonStyle.toast
text: currentCallNotif.currentCall ? currentCallNotif.currentCall.core.conference ? ("Réunion en cours : ") + currentCallNotif.currentCall.core.conference.core.subject : (("Appel en cours : ") + currentCallNotif.remoteName) : "appel en cours" text: currentCallNotif.currentCall ? currentCallNotif.currentCall.core.conference ? ("Réunion en cours : ") + currentCallNotif.currentCall.core.conference.core.subject : (("Appel en cours : ") + currentCallNotif.remoteName) : "appel en cours"
onClicked: { onClicked: {
var callsWindow = UtilsCpp.getCallsWindow( var callsWindow = UtilsCpp.getCallsWindow(currentCallNotif.currentCall);
currentCallNotif.currentCall) UtilsCpp.smartShowWindow(callsWindow);
UtilsCpp.smartShowWindow(callsWindow)
} }
} }
} }
@ -125,71 +122,85 @@ Item {
RowLayout { RowLayout {
anchors.fill: parent anchors.fill: parent
spacing: 0 spacing: 0
anchors.topMargin: Math.round(25 * DefaultStyle.dp) anchors.topMargin: Utils.getSizeWithScreenRatio(25)
VerticalTabBar { VerticalTabBar {
id: tabbar id: tabbar
Layout.fillHeight: true Layout.fillHeight: true
Layout.preferredWidth: Math.round(82 * DefaultStyle.dp) Layout.preferredWidth: Utils.getSizeWithScreenRatio(82)
defaultAccount: accountProxy.defaultAccount defaultAccount: accountProxy.defaultAccount
currentIndex: 0 currentIndex: 0
Binding on currentIndex { Binding on currentIndex {
when: mainItem.contextualMenuOpenedComponent != undefined when: mainItem.contextualMenuOpenedComponent != undefined
value: -1 value: -1
} }
model: [{ model: [
{
"icon": AppIcons.phone, "icon": AppIcons.phone,
"selectedIcon": AppIcons.phoneSelected, "selectedIcon": AppIcons.phoneSelected,
//: "Appels" //: "Appels"
"label": qsTr("bottom_navigation_calls_label") "label": qsTr("bottom_navigation_calls_label"),
}, { //: "Open calls page"
"accessibilityLabel": qsTr("open_calls_page_accessible_name")
},
{
"icon": AppIcons.adressBook, "icon": AppIcons.adressBook,
"selectedIcon": AppIcons.adressBookSelected, "selectedIcon": AppIcons.adressBookSelected,
//: "Contacts" //: "Contacts"
"label": qsTr("bottom_navigation_contacts_label") "label": qsTr("bottom_navigation_contacts_label"),
}, { //: "Open contacts page"
"accessibilityLabel": qsTr("open_contacts_page_accessible_name")
},
{
"icon": AppIcons.chatTeardropText, "icon": AppIcons.chatTeardropText,
"selectedIcon": AppIcons.chatTeardropTextSelected, "selectedIcon": AppIcons.chatTeardropTextSelected,
//: "Conversations" //: "Conversations"
"label": qsTr("bottom_navigation_conversations_label"), "label": qsTr("bottom_navigation_conversations_label"),
//: "Open conversations page"
"accessibilityLabel": qsTr("open_conversations_page_accessible_name"),
"visible": !SettingsCpp.disableChatFeature "visible": !SettingsCpp.disableChatFeature
}, { },
{
"icon": AppIcons.videoconference, "icon": AppIcons.videoconference,
"selectedIcon": AppIcons.videoconferenceSelected, "selectedIcon": AppIcons.videoconferenceSelected,
//: "Réunions" //: "Réunions"
"label": qsTr("bottom_navigation_meetings_label"), "label": qsTr("bottom_navigation_meetings_label"),
//: "Open meetings page"
"accessibilityLabel": qsTr("open_contact_page_accessible_name"),
"visible": !SettingsCpp.disableMeetingsFeature "visible": !SettingsCpp.disableMeetingsFeature
}] }
]
onCurrentIndexChanged: { onCurrentIndexChanged: {
if (currentIndex === -1) if (currentIndex === -1)
return return;
if (currentIndex === 0 && accountProxy.defaultAccount) if (currentIndex === 0 && accountProxy.defaultAccount)
accountProxy.defaultAccount.core?.lResetMissedCalls() accountProxy.defaultAccount.core?.lResetMissedCalls();
if (mainItem.contextualMenuOpenedComponent) { if (mainItem.contextualMenuOpenedComponent) {
closeContextualMenuComponent() closeContextualMenuComponent();
} }
} }
Keys.onPressed: event => { Keys.onPressed: event => {
if (event.key == Qt.Key_Right) { if (event.key == Qt.Key_Right) {
mainStackView.currentItem.forceActiveFocus() mainStackView.currentItem.forceActiveFocus();
} }
} }
Component.onCompleted: { Component.onCompleted: {
if (SettingsCpp.shortcutCount > 0) { if (SettingsCpp.shortcutCount > 0) {
var shortcuts = SettingsCpp.shortcuts var shortcuts = SettingsCpp.shortcuts;
shortcuts.forEach(shortcut => { shortcuts.forEach(shortcut => {
model.push({ model.push({
"icon": shortcut.icon, "icon": shortcut.icon,
"selectedIcon": shortcut.icon, "selectedIcon": shortcut.icon,
"label": shortcut.name, "label": shortcut.name,
"colored": true, "colored": true,
"link": shortcut.link "link": shortcut.link
}) });
}) });
} }
initButtons() initButtons();
currentIndex = SettingsCpp.getLastActiveTabIndex() currentIndex = SettingsCpp.getLastActiveTabIndex();
if (currentIndex === -1) currentIndex = 0 if (currentIndex === -1)
currentIndex = 0;
} }
} }
ColumnLayout { ColumnLayout {
@ -197,18 +208,17 @@ Item {
RowLayout { RowLayout {
id: topRow id: topRow
Layout.preferredHeight: Math.round(50 * DefaultStyle.dp) Layout.preferredHeight: Utils.getSizeWithScreenRatio(50)
Layout.leftMargin: Math.round(45 * DefaultStyle.dp) Layout.leftMargin: Utils.getSizeWithScreenRatio(45)
Layout.rightMargin: Math.round(41 * DefaultStyle.dp) Layout.rightMargin: Utils.getSizeWithScreenRatio(41)
spacing: Math.round(25 * DefaultStyle.dp) spacing: Utils.getSizeWithScreenRatio(25)
SearchBar { SearchBar {
id: magicSearchBar id: magicSearchBar
Layout.fillWidth: true Layout.fillWidth: true
//: "Rechercher un contact, appeler %1" //: "Rechercher un contact, appeler %1"
placeholderText: qsTr("searchbar_placeholder_text").arg(SettingsCpp.disableChatFeature placeholderText: qsTr("searchbar_placeholder_text").arg(SettingsCpp.disableChatFeature ? "…" :
? "…" //: "ou envoyer un message "
//: "ou envoyer un message " qsTr("searchbar_placeholder_text_chat_feature_enabled"))
: qsTr("searchbar_placeholder_text_chat_feature_enabled"))
focusedBorderColor: DefaultStyle.main1_500_main focusedBorderColor: DefaultStyle.main1_500_main
numericPadButton.visible: text.length === 0 numericPadButton.visible: text.length === 0
numericPadButton.checkable: false numericPadButton.checkable: false
@ -219,16 +229,16 @@ Item {
Connections { Connections {
target: mainItem target: mainItem
function onCallCreated() { function onCallCreated() {
magicSearchBar.focus = false magicSearchBar.focus = false;
magicSearchBar.clearText() magicSearchBar.clearText();
} }
} }
onTextChanged: { onTextChanged: {
if (text.length != 0) if (text.length != 0)
listPopup.open() listPopup.open();
else else
listPopup.close() listPopup.close();
} }
KeyNavigation.down: contactList //contactLoader.item?.count > 0 || !contactLoader.item?.footerItem? contactLoader.item : contactLoader.item?.footerItem KeyNavigation.down: contactList //contactLoader.item?.count > 0 || !contactLoader.item?.footerItem? contactLoader.item : contactLoader.item?.footerItem
KeyNavigation.up: contactList //contactLoader.item?.footerItem ? contactLoader.item?.footerItem : contactLoader.item KeyNavigation.up: contactList //contactLoader.item?.footerItem ? contactLoader.item?.footerItem : contactLoader.item
@ -236,24 +246,22 @@ Item {
Popup { Popup {
id: listPopup id: listPopup
width: magicSearchBar.width width: magicSearchBar.width
property real maxHeight: Math.round(400 * DefaultStyle.dp) property real maxHeight: Utils.getSizeWithScreenRatio(400)
property bool displayScrollbar: contactList.height > maxHeight property bool displayScrollbar: contactList.height > maxHeight
height: Math.min( height: Math.min(contactList.contentHeight, maxHeight) + topPadding + bottomPadding
contactList.contentHeight,
maxHeight) + topPadding + bottomPadding
y: magicSearchBar.height y: magicSearchBar.height
// closePolicy: Popup.CloseOnEscape // closePolicy: Popup.CloseOnEscape
topPadding: Math.round(20 * DefaultStyle.dp) topPadding: Utils.getSizeWithScreenRatio(20)
bottomPadding: Math.round((contactList.haveContacts ? 20 : 10) * DefaultStyle.dp) bottomPadding: Math.round((contactList.haveContacts ? 20 : 10) * DefaultStyle.dp)
rightPadding: Math.round(8 * DefaultStyle.dp) rightPadding: Utils.getSizeWithScreenRatio(8)
leftPadding: Math.round(20 * DefaultStyle.dp) leftPadding: Utils.getSizeWithScreenRatio(20)
visible: magicSearchBar.text.length != 0 visible: magicSearchBar.text.length != 0
background: Item { background: Item {
anchors.fill: parent anchors.fill: parent
Rectangle { Rectangle {
id: popupBg id: popupBg
radius: Math.round(16 * DefaultStyle.dp) radius: Utils.getSizeWithScreenRatio(16)
color: DefaultStyle.grey_0 color: DefaultStyle.grey_0
anchors.fill: parent anchors.fill: parent
border.color: DefaultStyle.main1_500_main border.color: DefaultStyle.main1_500_main
@ -271,9 +279,8 @@ Item {
contentItem: AllContactListView { contentItem: AllContactListView {
id: contactList id: contactList
width: listPopup.width - listPopup.leftPadding width: listPopup.width - listPopup.leftPadding - listPopup.rightPadding
- listPopup.rightPadding itemsRightMargin: Utils.getSizeWithScreenRatio(5) //(Actions have already 10 of margin)
itemsRightMargin: Math.round(5 * DefaultStyle.dp) //(Actions have already 10 of margin)
showInitials: false showInitials: false
showContactMenu: false showContactMenu: false
showActions: true showActions: true
@ -283,26 +290,28 @@ Item {
sectionsPixelSize: Typography.p2.pixelSize sectionsPixelSize: Typography.p2.pixelSize
sectionsWeight: Typography.p2.weight sectionsWeight: Typography.p2.weight
sectionsSpacing: Math.round(5 * DefaultStyle.dp) sectionsSpacing: Utils.getSizeWithScreenRatio(5)
searchBarText: magicSearchBar.text searchBarText: magicSearchBar.text
} }
} }
} }
RowLayout { RowLayout {
spacing: Math.round(10 * DefaultStyle.dp) spacing: Utils.getSizeWithScreenRatio(10)
PopupButton { PopupButton {
id: deactivateDndButton id: deactivateDndButton
Layout.preferredWidth: Math.round(32 * DefaultStyle.dp) Layout.preferredWidth: Utils.getSizeWithScreenRatio(32)
Layout.preferredHeight: Math.round(32 * DefaultStyle.dp) Layout.preferredHeight: Utils.getSizeWithScreenRatio(32)
popup.padding: Math.round(14 * DefaultStyle.dp) popup.padding: Utils.getSizeWithScreenRatio(14)
//: "Do not disturb"
popUpTitle: qsTr("do_not_disturb_accessible_name")
visible: SettingsCpp.dnd visible: SettingsCpp.dnd
contentItem: EffectImage { contentItem: EffectImage {
imageSource: AppIcons.bellDnd imageSource: AppIcons.bellDnd
width: Math.round(32 * DefaultStyle.dp) width: Utils.getSizeWithScreenRatio(32)
height: Math.round(32 * DefaultStyle.dp) height: Utils.getSizeWithScreenRatio(32)
Layout.preferredWidth: Math.round(32 * DefaultStyle.dp) Layout.preferredWidth: Utils.getSizeWithScreenRatio(32)
Layout.preferredHeight: Math.round(32 * DefaultStyle.dp) Layout.preferredHeight: Utils.getSizeWithScreenRatio(32)
fillMode: Image.PreserveAspectFit fillMode: Image.PreserveAspectFit
colorizationColor: DefaultStyle.main1_500_main colorizationColor: DefaultStyle.main1_500_main
} }
@ -310,199 +319,195 @@ Item {
IconLabelButton { IconLabelButton {
Layout.fillWidth: true Layout.fillWidth: true
focus: visible focus: visible
icon.width: Math.round(32 * DefaultStyle.dp) icon.width: Utils.getSizeWithScreenRatio(32)
icon.height: Math.round(32 * DefaultStyle.dp) icon.height: Utils.getSizeWithScreenRatio(32)
//: "Désactiver ne pas déranger" //: "Désactiver ne pas déranger"
text: qsTr("contact_presence_status_disable_do_not_disturb") text: qsTr("contact_presence_status_disable_do_not_disturb")
icon.source: AppIcons.bellDnd icon.source: AppIcons.bellDnd
onClicked: { onClicked: {
deactivateDndButton.popup.close() deactivateDndButton.popup.close();
SettingsCpp.dnd = false SettingsCpp.dnd = false;
} }
} }
} }
} }
Voicemail { Voicemail {
id: voicemail id: voicemail
Layout.preferredWidth: Math.round(42 * DefaultStyle.dp) Layout.preferredWidth: Utils.getSizeWithScreenRatio(42)
Layout.preferredHeight: Math.round(36 * DefaultStyle.dp) Layout.preferredHeight: Utils.getSizeWithScreenRatio(36)
Repeater { Repeater {
model: accountProxy model: accountProxy
delegate: Item { delegate: Item {
Connections { Connections {
target: modelData.core target: modelData.core
function onShowMwiChanged() { function onShowMwiChanged() {
voicemail.updateCumulatedMwi() voicemail.updateCumulatedMwi();
} }
function onVoicemailAddressChanged() { function onVoicemailAddressChanged() {
voicemail.updateCumulatedMwi() voicemail.updateCumulatedMwi();
} }
} }
} }
} }
function updateCumulatedMwi() { function updateCumulatedMwi() {
var count = 0 var count = 0;
var showMwi = false var showMwi = false;
var supportsVoiceMail = false var supportsVoiceMail = false;
for (var i = 0; i < accountProxy.count; i++) { for (var i = 0; i < accountProxy.count; i++) {
var core = accountProxy.getAt(i).core var core = accountProxy.getAt(i).core;
count += core.voicemailCount count += core.voicemailCount;
showMwi |= core.showMwi showMwi |= core.showMwi;
supportsVoiceMail |= core.voicemailAddress.length > 0 supportsVoiceMail |= core.voicemailAddress.length > 0;
} }
voicemail.showMwi = showMwi voicemail.showMwi = showMwi;
voicemail.voicemailCount = count voicemail.voicemailCount = count;
voicemail.visible = showMwi || supportsVoiceMail voicemail.visible = showMwi || supportsVoiceMail;
} }
Component.onCompleted: { Component.onCompleted: {
updateCumulatedMwi() updateCumulatedMwi();
} }
onClicked: { onClicked: {
if (accountProxy.count > 1) { if (accountProxy.count > 1) {
avatarButton.popup.open() avatarButton.popup.open();
} else { } else {
if (accountProxy.defaultAccount.core.voicemailAddress.length if (accountProxy.defaultAccount.core.voicemailAddress.length > 0)
> 0) UtilsCpp.createCall(accountProxy.defaultAccount.core.voicemailAddress);
UtilsCpp.createCall(
accountProxy.defaultAccount.core.voicemailAddress)
else else
UtilsCpp.showInformationPopup(qsTr("information_popup_error_title"), UtilsCpp.showInformationPopup(qsTr("information_popup_error_title"),
//: "L'URI de messagerie vocale n'est pas définie." //: "L'URI de messagerie vocale n'est pas définie."
qsTr("no_voicemail_uri_error_message"), false) qsTr("no_voicemail_uri_error_message"), false);
} }
} }
} }
PopupButton { PopupButton {
id: avatarButton id: avatarButton
Layout.preferredWidth: Math.round(54 * DefaultStyle.dp) Layout.preferredWidth: Utils.getSizeWithScreenRatio(54)
Layout.preferredHeight: width Layout.preferredHeight: width
popup.topPadding: Math.round(23 * DefaultStyle.dp) popup.topPadding: Utils.getSizeWithScreenRatio(23)
popup.bottomPadding: Math.round(23 * DefaultStyle.dp) popup.bottomPadding: Utils.getSizeWithScreenRatio(23)
popup.leftPadding: Math.round(24 * DefaultStyle.dp) popup.leftPadding: Utils.getSizeWithScreenRatio(24)
popup.rightPadding: Math.round(24 * DefaultStyle.dp) popup.rightPadding: Utils.getSizeWithScreenRatio(24)
contentItem: Avatar { //: "Account list"
id: avatar popUpTitle: qsTr("account_list_accessible_name")
height: avatarButton.height contentItem: Item {
width: avatarButton.width Avatar {
account: accountProxy.defaultAccount id: avatar
} height: avatarButton.height
popup.contentItem: ColumnLayout { width: avatarButton.width
AccountListView { account: accountProxy.defaultAccount
id: accounts
onAddAccountRequest: mainItem.addAccountRequest()
onEditAccount: function (account) {
avatarButton.popup.close()
openAccountSettings(account)
}
} }
Rectangle {
// Black border for keyboard navigation
visible: avatarButton.keyboardFocus
width: avatar.width
height: avatar.height
color: "transparent"
border.color: DefaultStyle.main2_900
border.width: Utils.getSizeWithScreenRatio(3)
radius: width / 2
}
}
popup.contentItem: AccountListView {
id: accounts
popupId: avatarButton
onAddAccountRequest: mainItem.addAccountRequest()
onEditAccount: function (account) {
avatarButton.popup.close();
openAccountSettings(account);
}
getPreviousItem: avatarButton.getPreviousItem
getNextItem: avatarButton.getNextItem
} }
} }
PopupButton { PopupButton {
id: settingsMenuButton id: settingsMenuButton
Layout.preferredWidth: Math.round(24 * DefaultStyle.dp) icon.width: Utils.getSizeWithScreenRatio(24)
Layout.preferredHeight: Math.round(24 * DefaultStyle.dp) icon.height: Utils.getSizeWithScreenRatio(24)
popup.width: Math.round(271 * DefaultStyle.dp) popup.width: Utils.getSizeWithScreenRatio(271)
popup.padding: Math.round(14 * DefaultStyle.dp) popup.padding: Utils.getSizeWithScreenRatio(14)
//: "Application options"
popUpTitle: qsTr("application_options_accessible_name")
popup.contentItem: FocusScope { popup.contentItem: FocusScope {
id: popupFocus id: popupFocus
implicitHeight: settingsButtons.implicitHeight implicitHeight: settingsButtons.implicitHeight
implicitWidth: settingsButtons.implicitWidth implicitWidth: settingsButtons.implicitWidth
Keys.onPressed: event => { Keys.onPressed: event => {
if (event.key == Qt.Key_Left if (event.key == Qt.Key_Left || event.key == Qt.Key_Escape) {
|| event.key == Qt.Key_Escape) { settingsMenuButton.popup.close();
settingsMenuButton.popup.close() event.accepted = true;
event.accepted = true }
} }
}
ColumnLayout { ColumnLayout {
id: settingsButtons id: settingsButtons
spacing: Math.round(16 * DefaultStyle.dp) spacing: Utils.getSizeWithScreenRatio(16)
anchors.fill: parent anchors.fill: parent
IconLabelButton { IconLabelButton {
id: accountButton id: accountButton
Layout.fillWidth: true Layout.fillWidth: true
visible: !SettingsCpp.hideAccountSettings visible: !SettingsCpp.hideAccountSettings
icon.width: Math.round(32 * DefaultStyle.dp) icon.width: Utils.getSizeWithScreenRatio(32)
icon.height: Math.round(32 * DefaultStyle.dp) icon.height: Utils.getSizeWithScreenRatio(32)
//: Mon compte //: Mon compte
text: qsTr("drawer_menu_manage_account") text: qsTr("drawer_menu_manage_account")
icon.source: AppIcons.manageProfile icon.source: AppIcons.manageProfile
onClicked: openAccountSettings(accountProxy.defaultAccount onClicked: openAccountSettings(accountProxy.defaultAccount ? accountProxy.defaultAccount : accountProxy.firstAccount())
? accountProxy.defaultAccount KeyNavigation.up: visibleChildren.length != 0 ? settingsMenuButton.getPreviousItem(0) : null
: accountProxy.firstAccount()) KeyNavigation.down: visibleChildren.length != 0 ? settingsMenuButton.getNextItem(0) : null
KeyNavigation.up: visibleChildren.length
!= 0 ? settingsMenuButton.getPreviousItem(
0) : null
KeyNavigation.down: visibleChildren.length
!= 0 ? settingsMenuButton.getNextItem(
0) : null
} }
IconLabelButton { IconLabelButton {
id: dndButton id: dndButton
Layout.fillWidth: true Layout.fillWidth: true
icon.width: Math.round(32 * DefaultStyle.dp) icon.width: Utils.getSizeWithScreenRatio(32)
icon.height: Math.round(32 * DefaultStyle.dp) icon.height: Utils.getSizeWithScreenRatio(32)
text: SettingsCpp.dnd ? qsTr("contact_presence_status_disable_do_not_disturb") text: SettingsCpp.dnd ? qsTr("contact_presence_status_disable_do_not_disturb") :
//: "Activer ne pas déranger" //: "Activer ne pas déranger"
: qsTr("contact_presence_status_enable_do_not_disturb") qsTr("contact_presence_status_enable_do_not_disturb")
icon.source: AppIcons.bellDnd icon.source: AppIcons.bellDnd
onClicked: { onClicked: {
settingsMenuButton.popup.close() settingsMenuButton.popup.close();
SettingsCpp.dnd = !SettingsCpp.dnd SettingsCpp.dnd = !SettingsCpp.dnd;
} }
KeyNavigation.up: visibleChildren.length KeyNavigation.up: visibleChildren.length != 0 ? settingsMenuButton.getPreviousItem(1) : null
!= 0 ? settingsMenuButton.getPreviousItem( KeyNavigation.down: visibleChildren.length != 0 ? settingsMenuButton.getNextItem(1) : null
1) : null
KeyNavigation.down: visibleChildren.length
!= 0 ? settingsMenuButton.getNextItem(
1) : null
} }
IconLabelButton { IconLabelButton {
id: settingsButton id: settingsButton
Layout.fillWidth: true Layout.fillWidth: true
visible: !SettingsCpp.hideSettings visible: !SettingsCpp.hideSettings
icon.width: Math.round(32 * DefaultStyle.dp) icon.width: Utils.getSizeWithScreenRatio(32)
icon.height: Math.round(32 * DefaultStyle.dp) icon.height: Utils.getSizeWithScreenRatio(32)
text: qsTr("settings_title") text: qsTr("settings_title")
icon.source: AppIcons.settings icon.source: AppIcons.settings
onClicked: { onClicked: {
var page = settingsPageComponent.createObject(parent); var page = settingsPageComponent.createObject(parent);
openContextualMenuComponent(page) openContextualMenuComponent(page)
} }
KeyNavigation.up: visibleChildren.length KeyNavigation.up: visibleChildren.length != 0 ? settingsMenuButton.getPreviousItem(2) : null
!= 0 ? settingsMenuButton.getPreviousItem( KeyNavigation.down: visibleChildren.length != 0 ? settingsMenuButton.getNextItem(2) : null
2) : null
KeyNavigation.down: visibleChildren.length
!= 0 ? settingsMenuButton.getNextItem(
2) : null
} }
IconLabelButton { IconLabelButton {
id: recordsButton id: recordsButton
Layout.fillWidth: true Layout.fillWidth: true
visible: !SettingsCpp.disableCallRecordings visible: !SettingsCpp.disableCallRecordings
icon.width: Math.round(32 * DefaultStyle.dp) icon.width: Utils.getSizeWithScreenRatio(32)
icon.height: Math.round(32 * DefaultStyle.dp) icon.height: Utils.getSizeWithScreenRatio(32)
//: "Enregistrements" //: "Enregistrements"
text: qsTr("recordings_title") text: qsTr("recordings_title")
icon.source: AppIcons.micro icon.source: AppIcons.micro
KeyNavigation.up: visibleChildren.length KeyNavigation.up: visibleChildren.length != 0 ? settingsMenuButton.getPreviousItem(3) : null
!= 0 ? settingsMenuButton.getPreviousItem( KeyNavigation.down: visibleChildren.length != 0 ? settingsMenuButton.getNextItem(3) : null
3) : null
KeyNavigation.down: visibleChildren.length
!= 0 ? settingsMenuButton.getNextItem(
3) : null
} }
IconLabelButton { IconLabelButton {
id: helpButton id: helpButton
Layout.fillWidth: true Layout.fillWidth: true
icon.width: Math.round(32 * DefaultStyle.dp) icon.width: Utils.getSizeWithScreenRatio(32)
icon.height: Math.round(32 * DefaultStyle.dp) icon.height: Utils.getSizeWithScreenRatio(32)
//: "Aide" //: "Aide"
text: qsTr("help_title") text: qsTr("help_title")
icon.source: AppIcons.question icon.source: AppIcons.question
@ -510,62 +515,48 @@ Item {
var page = helpPageComponent.createObject(parent); var page = helpPageComponent.createObject(parent);
openContextualMenuComponent(page) openContextualMenuComponent(page)
} }
KeyNavigation.up: visibleChildren.length KeyNavigation.up: visibleChildren.length != 0 ? settingsMenuButton.getPreviousItem(4) : null
!= 0 ? settingsMenuButton.getPreviousItem( KeyNavigation.down: visibleChildren.length != 0 ? settingsMenuButton.getNextItem(4) : null
4) : null
KeyNavigation.down: visibleChildren.length
!= 0 ? settingsMenuButton.getNextItem(
4) : null
} }
IconLabelButton { IconLabelButton {
id: quitButton id: quitButton
Layout.fillWidth: true Layout.fillWidth: true
icon.width: Math.round(32 * DefaultStyle.dp) icon.width: Utils.getSizeWithScreenRatio(32)
icon.height: Math.round(32 * DefaultStyle.dp) icon.height: Utils.getSizeWithScreenRatio(32)
//: "Quitter l'application" //: "Quitter l'application"
text: qsTr("help_quit_title") text: qsTr("help_quit_title")
icon.source: AppIcons.power icon.source: AppIcons.power
onClicked: { onClicked: {
settingsMenuButton.popup.close() settingsMenuButton.popup.close();
//: "Quitter %1 ?" //: "Quitter %1 ?"
UtilsCpp.getMainWindow().showConfirmationLambdaPopup("", qsTr("quit_app_question").arg(applicationName),"", UtilsCpp.getMainWindow().showConfirmationLambdaPopup("", qsTr("quit_app_question").arg(applicationName), "", function (confirmed) {
function (confirmed) { if (confirmed) {
if (confirmed) { console.info("Exiting App from Top Menu");
console.info("Exiting App from Top Menu") Qt.quit();
Qt.quit() }
} });
})
} }
KeyNavigation.up: visibleChildren.length KeyNavigation.up: visibleChildren.length != 0 ? settingsMenuButton.getPreviousItem(5) : null
!= 0 ? settingsMenuButton.getPreviousItem( KeyNavigation.down: visibleChildren.length != 0 ? settingsMenuButton.getNextItem(5) : null
5) : null
KeyNavigation.down: visibleChildren.length
!= 0 ? settingsMenuButton.getNextItem(
5) : null
} }
Rectangle { Rectangle {
Layout.fillWidth: true Layout.fillWidth: true
Layout.preferredHeight: Math.max(Math.round(1 * DefaultStyle.dp), 1) Layout.preferredHeight: Math.max(Utils.getSizeWithScreenRatio(1), 1)
visible: addAccountButton.visible visible: addAccountButton.visible
color: DefaultStyle.main2_400 color: DefaultStyle.main2_400
} }
IconLabelButton { IconLabelButton {
id: addAccountButton id: addAccountButton
Layout.fillWidth: true Layout.fillWidth: true
visible: SettingsCpp.maxAccount == 0 visible: SettingsCpp.maxAccount == 0 || SettingsCpp.maxAccount > accountProxy.count
|| SettingsCpp.maxAccount > accountProxy.count icon.width: Utils.getSizeWithScreenRatio(32)
icon.width: Math.round(32 * DefaultStyle.dp) icon.height: Utils.getSizeWithScreenRatio(32)
icon.height: Math.round(32 * DefaultStyle.dp)
//: "Ajouter un compte" //: "Ajouter un compte"
text: qsTr("drawer_menu_add_account") text: qsTr("drawer_menu_add_account")
icon.source: AppIcons.plusCircle icon.source: AppIcons.plusCircle
onClicked: mainItem.addAccountRequest() onClicked: mainItem.addAccountRequest()
KeyNavigation.up: visibleChildren.length KeyNavigation.up: visibleChildren.length != 0 ? settingsMenuButton.getPreviousItem(7) : null
!= 0 ? settingsMenuButton.getPreviousItem( KeyNavigation.down: visibleChildren.length != 0 ? settingsMenuButton.getNextItem(7) : null
7) : null
KeyNavigation.down: visibleChildren.length
!= 0 ? settingsMenuButton.getNextItem(
7) : null
} }
} }
} }
@ -579,16 +570,15 @@ Item {
objectName: "mainStackLayout" objectName: "mainStackLayout"
property int _currentIndex: tabbar.currentIndex property int _currentIndex: tabbar.currentIndex
currentIndex: -1 currentIndex: -1
onActiveFocusChanged: if (activeFocus onActiveFocusChanged: if (activeFocus && currentIndex >= 0)
&& currentIndex >= 0) children[currentIndex].forceActiveFocus()
children[currentIndex].forceActiveFocus()
on_CurrentIndexChanged: { on_CurrentIndexChanged: {
if (count > 0) { if (count > 0) {
if (_currentIndex >= count && tabbar.model[_currentIndex].link) { if (_currentIndex >= count && tabbar.model[_currentIndex].link) {
Qt.openUrlExternally(tabbar.model[_currentIndex].link) Qt.openUrlExternally(tabbar.model[_currentIndex].link);
} else if (_currentIndex >= 0) { } else if (_currentIndex >= 0) {
currentIndex = _currentIndex currentIndex = _currentIndex;
SettingsCpp.setLastActiveTabIndex(currentIndex) SettingsCpp.setLastActiveTabIndex(currentIndex);
} }
} }
} }
@ -597,41 +587,40 @@ Item {
Connections { Connections {
target: mainItem target: mainItem
function onOpenNewCallRequest() { function onOpenNewCallRequest() {
callPage.goToNewCall() callPage.goToNewCall();
} }
function onCallCreated() { function onCallCreated() {
callPage.goToCallHistory() callPage.goToCallHistory();
} }
function onOpenCallHistory() { function onOpenCallHistory() {
callPage.goToCallHistory() callPage.goToCallHistory();
} }
function onOpenNumPadRequest() { function onOpenNumPadRequest() {
callPage.openNumPadRequest() callPage.openNumPadRequest();
} }
} }
onCreateContactRequested: (name, address) => { onCreateContactRequested: (name, address) => {
mainItem.createContact( mainItem.createContact(name, address);
name, address) }
}
Component.onCompleted: { Component.onCompleted: {
magicSearchBar.numericPadPopup = callPage.numericPadPopup magicSearchBar.numericPadPopup = callPage.numericPadPopup;
} }
onGoToCallForwardSettings: { onGoToCallForwardSettings: {
var page = settingsPageComponent.createObject(parent, { var page = settingsPageComponent.createObject(parent, {
defaultIndex: 1 defaultIndex: 1
}); });
openContextualMenuComponent(page) openContextualMenuComponent(page);
} }
} }
ContactPage { ContactPage {
id: contactPage id: contactPage
Connections { Connections {
target: mainItem target: mainItem
function onCreateContactRequested(name, address) { function onCreateContactRequested(name, address) {
contactPage.createContact(name, address) contactPage.createContact(name, address);
} }
function onDisplayContactRequested(contactAddress) { function onDisplayContactRequested(contactAddress) {
contactPage.initialFriendToDisplay = contactAddress contactPage.initialFriendToDisplay = contactAddress;
} }
} }
} }
@ -640,25 +629,25 @@ Item {
Connections { Connections {
target: mainItem target: mainItem
function onDisplayChatRequested(contactAddress) { function onDisplayChatRequested(contactAddress) {
console.log("display chat requested, open with address", contactAddress) console.log("display chat requested, open with address", contactAddress);
chatPage.remoteAddress = "" chatPage.remoteAddress = "";
chatPage.remoteAddress = contactAddress chatPage.remoteAddress = contactAddress;
} }
function onOpenChatRequested(chat) { function onOpenChatRequested(chat) {
console.log("open chat requested, open", chat.core.title) console.log("open chat requested, open", chat.core.title);
chatPage.openChatRequested(chat) chatPage.openChatRequested(chat);
} }
} }
} }
MeetingPage { MeetingPage {
id: meetingPage id: meetingPage
Connections { Connections {
target: mainItem target: mainItem
function onScheduleMeetingRequested(subject, addresses) { function onScheduleMeetingRequested(subject, addresses) {
meetingPage.createPreFilledMeeting(subject, addresses) meetingPage.createPreFilledMeeting(subject, addresses);
} }
} }
} }
} }
} }
Component { Component {
@ -666,8 +655,8 @@ Item {
AccountSettingsPage { AccountSettingsPage {
onGoBack: closeContextualMenuComponent() onGoBack: closeContextualMenuComponent()
onAccountRemoved: { onAccountRemoved: {
closeContextualMenuComponent() closeContextualMenuComponent();
mainItem.accountRemoved() mainItem.accountRemoved();
} }
} }
} }
@ -697,7 +686,7 @@ Item {
pushExit: noTransition pushExit: noTransition
popEnter: noTransition popEnter: noTransition
popExit: noTransition popExit: noTransition
Layout.topMargin: Math.round(24 * DefaultStyle.dp) Layout.topMargin: Utils.getSizeWithScreenRatio(24)
Layout.fillWidth: true Layout.fillWidth: true
Layout.fillHeight: true Layout.fillHeight: true
initialItem: mainStackLayoutComponent initialItem: mainStackLayoutComponent

View file

@ -2,8 +2,8 @@
import QtQuick import QtQuick
import QtQuick.Layouts import QtQuick.Layouts
import QtQuick.Controls.Basic as Control import QtQuick.Controls.Basic as Control
import Linphone import Linphone
import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils
import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle
Rectangle { Rectangle {
@ -17,7 +17,7 @@ Rectangle {
color: DefaultStyle.grey_0 color: DefaultStyle.grey_0
property var container property var container
// property real contentHeight: contentListView.contentHeight // property real contentHeight: contentListView.contentHeight
property real minimumWidthForSwitchintToRowLayout: Math.round(981 * DefaultStyle.dp) property real minimumWidthForSwitchintToRowLayout: Utils.getSizeWithScreenRatio(981)
property var useVerticalLayout property var useVerticalLayout
property bool saveButtonVisible: true property bool saveButtonVisible: true
signal save() signal save()
@ -38,8 +38,8 @@ Rectangle {
id: header id: header
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
leftPadding: Math.round(45 * DefaultStyle.dp) leftPadding: Utils.getSizeWithScreenRatio(45)
rightPadding: Math.round(45 * DefaultStyle.dp) rightPadding: Utils.getSizeWithScreenRatio(45)
z: 1 z: 1
background: Rectangle { background: Rectangle {
anchors.fill: parent anchors.fill: parent
@ -48,21 +48,23 @@ Rectangle {
contentItem: ColumnLayout { contentItem: ColumnLayout {
RowLayout { RowLayout {
Layout.fillWidth: true Layout.fillWidth: true
Layout.topMargin: Math.round(20 * DefaultStyle.dp) Layout.topMargin: Utils.getSizeWithScreenRatio(20)
spacing: Math.round(5 * DefaultStyle.dp) spacing: Utils.getSizeWithScreenRatio(5)
Layout.bottomMargin: Math.round(10 * DefaultStyle.dp) Layout.bottomMargin: Utils.getSizeWithScreenRatio(10)
Button { Button {
id: backButton id: backButton
Layout.preferredHeight: Math.round(24 * DefaultStyle.dp) Layout.preferredHeight: Utils.getSizeWithScreenRatio(30)
Layout.preferredWidth: Math.round(24 * DefaultStyle.dp) Layout.preferredWidth: Utils.getSizeWithScreenRatio(30)
icon.source: AppIcons.leftArrow icon.source: AppIcons.leftArrow
focus: true focus: true
visible: mainItem.container.depth > 1 visible: mainItem.container.depth > 1
Layout.rightMargin: Math.round(41 * DefaultStyle.dp) Layout.rightMargin: Utils.getSizeWithScreenRatio(41)
style: ButtonStyle.noBackground style: ButtonStyle.noBackground
onClicked: { onClicked: {
mainItem.container.pop() mainItem.container.pop()
} }
//: Return
Accessible.name: qsTr("return_accessible_name")
} }
Text { Text {
text: titleText text: titleText
@ -75,15 +77,17 @@ Rectangle {
Loader { Loader {
Layout.alignment: Qt.AlignRight Layout.alignment: Qt.AlignRight
sourceComponent: mainItem.topbarOptionalComponent sourceComponent: mainItem.topbarOptionalComponent
Layout.rightMargin: Math.round(34 * DefaultStyle.dp) Layout.rightMargin: Utils.getSizeWithScreenRatio(34)
} }
MediumButton { MediumButton {
id: saveButton id: saveButton
style: ButtonStyle.main style: ButtonStyle.main
//: "Enregistrer" //: "Enregistrer"
text: qsTr("save") text: qsTr("save")
Layout.rightMargin: Math.round(6 * DefaultStyle.dp) Layout.rightMargin: Utils.getSizeWithScreenRatio(6)
visible: mainItem.saveButtonVisible visible: mainItem.saveButtonVisible
//: Save %1 settings
Accessible.name: qsTr("save_settings_accessible_name").arg(mainItem.titleText)
onClicked: { onClicked: {
mainItem.save() mainItem.save()
} }
@ -91,8 +95,8 @@ Rectangle {
} }
Rectangle { Rectangle {
Layout.fillWidth: true Layout.fillWidth: true
height: Math.max(Math.round(1 * DefaultStyle.dp), 1) height: Math.max(Utils.getSizeWithScreenRatio(1), 1)
color: DefaultStyle.main2_500main color: DefaultStyle.main2_500_main
} }
} }
} }
@ -102,7 +106,7 @@ Rectangle {
anchors.right: parent.right anchors.right: parent.right
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
anchors.top: header.bottom anchors.top: header.bottom
anchors.topMargin: Math.round(16 * DefaultStyle.dp) anchors.topMargin: Utils.getSizeWithScreenRatio(16)
// Workaround while the CI is made with Qt6.5.3 // Workaround while the CI is made with Qt6.5.3
// When updated to 6.8, remove this Item and // When updated to 6.8, remove this Item and
// change the ScrollView with a Flickable // change the ScrollView with a Flickable
@ -116,7 +120,7 @@ Rectangle {
anchors.top: parent.top anchors.top: parent.top
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
anchors.right: parent.right anchors.right: parent.right
anchors.rightMargin: Math.round(15 * DefaultStyle.dp) anchors.rightMargin: Utils.getSizeWithScreenRatio(15)
} }
Control.ScrollBar.horizontal: ScrollBar { Control.ScrollBar.horizontal: ScrollBar {
active: false active: false
@ -126,22 +130,22 @@ Rectangle {
model: mainItem.contentModel model: mainItem.contentModel
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
anchors.leftMargin: Math.round(45 * DefaultStyle.dp) anchors.leftMargin: Utils.getSizeWithScreenRatio(45)
anchors.rightMargin: Math.round(45 * DefaultStyle.dp) anchors.rightMargin: Utils.getSizeWithScreenRatio(45)
height: contentHeight height: contentHeight
spacing: Math.round(10 * DefaultStyle.dp) spacing: Utils.getSizeWithScreenRatio(10)
delegate: ColumnLayout { delegate: ColumnLayout {
visible: modelData.visible != undefined ? modelData.visible: true visible: modelData.visible != undefined ? modelData.visible: true
Component.onCompleted: if (!visible) height = 0 Component.onCompleted: if (!visible) height = 0
spacing: Math.round(16 * DefaultStyle.dp) spacing: Utils.getSizeWithScreenRatio(16)
width: contentListView.width width: contentListView.width
Rectangle { Rectangle {
visible: index !== 0 visible: index !== 0
Layout.topMargin: Math.round((modelData.hideTopSeparator ? 0 : 16) * DefaultStyle.dp) Layout.topMargin: Math.round((modelData.hideTopSeparator ? 0 : 16) * DefaultStyle.dp)
Layout.bottomMargin: Math.round(16 * DefaultStyle.dp) Layout.bottomMargin: Utils.getSizeWithScreenRatio(16)
Layout.fillWidth: true Layout.fillWidth: true
height: Math.max(Math.round(1 * DefaultStyle.dp), 1) height: Math.max(Utils.getSizeWithScreenRatio(1), 1)
color: modelData.hideTopSeparator ? 'transparent' : DefaultStyle.main2_500main color: modelData.hideTopSeparator ? 'transparent' : DefaultStyle.main2_500_main
} }
GridLayout { GridLayout {
rows: 1 rows: 1
@ -149,11 +153,11 @@ Rectangle {
Layout.fillWidth: true Layout.fillWidth: true
// Layout.preferredWidth: parent.width // Layout.preferredWidth: parent.width
rowSpacing: Math.round((modelData.title.length > 0 || modelData.subTitle.length > 0 ? 20 : 0) * DefaultStyle.dp) rowSpacing: Math.round((modelData.title.length > 0 || modelData.subTitle.length > 0 ? 20 : 0) * DefaultStyle.dp)
columnSpacing: Math.round(47 * DefaultStyle.dp) columnSpacing: Utils.getSizeWithScreenRatio(47)
ColumnLayout { ColumnLayout {
Layout.preferredWidth: Math.round(341 * DefaultStyle.dp) Layout.preferredWidth: Utils.getSizeWithScreenRatio(341)
Layout.maximumWidth: Math.round(341 * DefaultStyle.dp) Layout.maximumWidth: Utils.getSizeWithScreenRatio(341)
spacing: Math.round(3 * DefaultStyle.dp) spacing: Utils.getSizeWithScreenRatio(3)
Text { Text {
text: modelData.title text: modelData.title
visible: modelData.title.length > 0 visible: modelData.title.length > 0
@ -176,8 +180,8 @@ Rectangle {
} }
RowLayout { RowLayout {
Layout.topMargin: Math.round((modelData.hideTopMargin ? 0 : (mainItem.useVerticalLayout ? 10 : 21)) * DefaultStyle.dp) Layout.topMargin: Math.round((modelData.hideTopMargin ? 0 : (mainItem.useVerticalLayout ? 10 : 21)) * DefaultStyle.dp)
Layout.bottomMargin: Math.round(21 * DefaultStyle.dp) Layout.bottomMargin: Utils.getSizeWithScreenRatio(21)
Layout.leftMargin: mainItem.useVerticalLayout ? 0 : Math.round(17 * DefaultStyle.dp) Layout.leftMargin: mainItem.useVerticalLayout ? 0 : Utils.getSizeWithScreenRatio(17)
Layout.preferredWidth: Math.round((modelData.customWidth > 0 ? modelData.customWidth : 545) * DefaultStyle.dp) Layout.preferredWidth: Math.round((modelData.customWidth > 0 ? modelData.customWidth : 545) * DefaultStyle.dp)
Layout.alignment: Qt.AlignRight Layout.alignment: Qt.AlignRight
Loader { Loader {

View file

@ -180,7 +180,7 @@ AbstractSettingsLayout {
text: qsTr("manage_account_delete") text: qsTr("manage_account_delete")
font: Typography.p2l font: Typography.p2l
wrapMode: Text.WordWrap wrapMode: Text.WordWrap
color: DefaultStyle.danger_500main color: DefaultStyle.danger_500_main
Layout.fillWidth: true Layout.fillWidth: true
} }
Text { Text {
@ -188,7 +188,7 @@ AbstractSettingsLayout {
text: qsTr("manage_account_delete_message") text: qsTr("manage_account_delete_message")
font: Typography.p1 font: Typography.p1
wrapMode: Text.WordWrap wrapMode: Text.WordWrap
color: DefaultStyle.main2_500main color: DefaultStyle.main2_500_main
Layout.fillWidth: true Layout.fillWidth: true
} }
} }

View file

@ -99,6 +99,8 @@ AbstractSettingsLayout {
//: Invalid URL format //: Invalid URL format
UtilsCpp.showInformationPopup(qsTr("information_popup_error_title"), qsTr("settings_advanced_invalid_url_message"), false, UtilsCpp.getMainWindow()) UtilsCpp.showInformationPopup(qsTr("information_popup_error_title"), qsTr("settings_advanced_invalid_url_message"), false, UtilsCpp.getMainWindow())
} }
//: "Download and apply remote provisioning"
Accessible.name: qsTr("download_apply_remote_provisioning_accessible_name")
} }
} }
} }
@ -124,6 +126,7 @@ AbstractSettingsLayout {
propertyName: "mediaEncryption" propertyName: "mediaEncryption"
textRole: 'display_name' textRole: 'display_name'
propertyOwner: SettingsCpp propertyOwner: SettingsCpp
Accessible.name: qsTr("settings_advanced_media_encryption_title")
} }
} }
SwitchSetting { SwitchSetting {

View file

@ -126,6 +126,8 @@ AbstractSettingsLayout {
onClicked: { onClicked: {
fileDialog.open() fileDialog.open()
} }
//: Choose ringtone file
Accessible.name:qsTr("choose_ringtone_file_accessible_name")
} }
} }
} }

View file

@ -42,6 +42,10 @@ AbstractSettingsLayout {
addText: qsTr("settings_contacts_add_ldap_server_title") addText: qsTr("settings_contacts_add_ldap_server_title")
//: "Modifier un annuaire LDAP" //: "Modifier un annuaire LDAP"
editText: qsTr("settings_contacts_edit_ldap_server_title") editText: qsTr("settings_contacts_edit_ldap_server_title")
//: "Editer le serveur LDAP %1"
accessibleEditButtonText: qsTr("edit_ldap_server_accessible_name")
//: "Utiliser le serveur LDAP %1"
accessibleUseButtonText: qsTr("use_ldap_server_accessible_name")
proxyModel: LdapProxy {} proxyModel: LdapProxy {}
newItemGui: createGuiObject('Ldap') newItemGui: createGuiObject('Ldap')
settingsLayout: layoutUrl("LdapSettingsLayout") settingsLayout: layoutUrl("LdapSettingsLayout")
@ -69,6 +73,10 @@ AbstractSettingsLayout {
addText: qsTr("settings_contacts_add_carddav_server_title") addText: qsTr("settings_contacts_add_carddav_server_title")
//: "Modifier un carnet d'adresse CardDAV" //: "Modifier un carnet d'adresse CardDAV"
editText: qsTr("settings_contacts_edit_carddav_server_title") editText: qsTr("settings_contacts_edit_carddav_server_title")
//: "Editer le carnet d'adresses CardDAV %1"
accessibleEditButtonText: qsTr("edit_cardav_server_accessible_name")
//: "Utiliser le d'adresses CardDAV %1"
accessibleUseButtonText: qsTr("use_cardav_server_accessible_name")
proxyModel: CarddavProxy { proxyModel: CarddavProxy {
onModelReset: { onModelReset: {
carddavProvider.showAddButton = carddavProvider.proxyModel.count == 0 carddavProvider.showAddButton = carddavProvider.proxyModel.count == 0

View file

@ -5,6 +5,7 @@ import QtQuick.Controls.Basic as Control
import SettingsCpp 1.0 import SettingsCpp 1.0
import UtilsCpp import UtilsCpp
import Linphone import Linphone
import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils
import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle
RowLayout { RowLayout {
@ -14,6 +15,8 @@ RowLayout {
property string addText property string addText
property string addTextDescription property string addTextDescription
property string editText property string editText
property string accessibleEditButtonText
property string accessibleUseButtonText
property var newItemGui property var newItemGui
property string settingsLayout property string settingsLayout
property var proxyModel property var proxyModel
@ -25,18 +28,18 @@ RowLayout {
signal save() signal save()
signal undo() signal undo()
spacing: Math.round(5 * DefaultStyle.dp) spacing: Utils.getSizeWithScreenRatio(5)
ColumnLayout { ColumnLayout {
Layout.fillWidth: true Layout.fillWidth: true
Layout.fillHeight: true Layout.fillHeight: true
spacing: Math.round(16 * DefaultStyle.dp) spacing: Utils.getSizeWithScreenRatio(16)
Repeater { Repeater {
model: mainItem.proxyModel model: mainItem.proxyModel
RowLayout { RowLayout {
Layout.fillWidth: true Layout.fillWidth: true
Layout.alignment: Qt.AlignLeft|Qt.AlignHCenter Layout.alignment: Qt.AlignLeft|Qt.AlignHCenter
Layout.preferredHeight: Math.round(74 * DefaultStyle.dp) Layout.preferredHeight: Utils.getSizeWithScreenRatio(74)
spacing: Math.round(20 * DefaultStyle.dp) spacing: Utils.getSizeWithScreenRatio(20)
Text { Text {
text: modelData.core[titleProperty] text: modelData.core[titleProperty]
font: Typography.p2l font: Typography.p2l
@ -51,8 +54,10 @@ RowLayout {
Button { Button {
style: ButtonStyle.noBackground style: ButtonStyle.noBackground
icon.source: AppIcons.pencil icon.source: AppIcons.pencil
icon.width: Math.round(24 * DefaultStyle.dp) icon.width: Utils.getSizeWithScreenRatio(24)
icon.height: Math.round(24 * DefaultStyle.dp) icon.height: Utils.getSizeWithScreenRatio(24)
Layout.preferredWidth: Utils.getSizeWithScreenRatio(30)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(30)
onClicked: { onClicked: {
mainItem.owner.container.push(mainItem.settingsLayout, { mainItem.owner.container.push(mainItem.settingsLayout, {
titleText: mainItem.editText, titleText: mainItem.editText,
@ -60,6 +65,7 @@ RowLayout {
container: mainItem.owner.container, container: mainItem.owner.container,
isNew: false}) isNew: false})
} }
Accessible.name: mainItem.accessibleEditButtonText.arg(modelData.core[titleProperty])
} }
Switch { Switch {
id: switchButton id: switchButton
@ -69,6 +75,7 @@ RowLayout {
onToggled: { onToggled: {
binding.when = true binding.when = true
} }
Accessible.name: mainItem.accessibleUseButtonText.arg(modelData.core[titleProperty])
} }
Binding { Binding {
id: binding id: binding
@ -106,7 +113,7 @@ RowLayout {
} }
RowLayout { RowLayout {
Layout.fillWidth: true Layout.fillWidth: true
spacing: Math.round(5 * DefaultStyle.dp) spacing: Utils.getSizeWithScreenRatio(5)
Item { Item {
Layout.fillWidth: true Layout.fillWidth: true
} }
@ -114,6 +121,7 @@ RowLayout {
Layout.alignment: Qt.AlignRight | Qt.AlignHCenter Layout.alignment: Qt.AlignRight | Qt.AlignHCenter
//: "Ajouter" //: "Ajouter"
text: qsTr("add") text: qsTr("add")
Accessible.name: mainItem.addText
style: ButtonStyle.main style: ButtonStyle.main
visible: mainItem.showAddButton visible: mainItem.showAddButton
onClicked: { onClicked: {

View file

@ -6,6 +6,7 @@ import QtQuick.Dialogs
import Linphone import Linphone
import SettingsCpp 1.0 import SettingsCpp 1.0
import UtilsCpp import UtilsCpp
import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils
import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle
AbstractSettingsLayout { AbstractSettingsLayout {
@ -39,12 +40,14 @@ AbstractSettingsLayout {
Component { Component {
id: topBar id: topBar
RowLayout { RowLayout {
spacing: Math.round(20 * DefaultStyle.dp) spacing: Utils.getSizeWithScreenRatio(20)
Button { Button {
style: ButtonStyle.noBackground style: ButtonStyle.noBackground
icon.source: AppIcons.trashCan icon.source: AppIcons.trashCan
icon.width: Math.round(32 * DefaultStyle.dp) icon.width: Utils.getSizeWithScreenRatio(30)
icon.height: Math.round(32 * DefaultStyle.dp) icon.height: Utils.getSizeWithScreenRatio(30)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(38)
Layout.preferredWidth: Utils.getSizeWithScreenRatio(38)
visible: !isNew visible: !isNew
onClicked: { onClicked: {
var mainWin = UtilsCpp.getMainWindow() var mainWin = UtilsCpp.getMainWindow()
@ -60,6 +63,8 @@ AbstractSettingsLayout {
} }
) )
} }
//: Delete LDAP server
Accessible.name: qsTr("delete_ldap_server_accessible_name")
} }
} }
} }
@ -68,10 +73,10 @@ AbstractSettingsLayout {
id: ldapParametersComponent id: ldapParametersComponent
ColumnLayout { ColumnLayout {
Layout.fillWidth: true Layout.fillWidth: true
spacing: Math.round(20 * DefaultStyle.dp) spacing: Utils.getSizeWithScreenRatio(20)
Layout.rightMargin: Math.round(44 * DefaultStyle.dp) Layout.rightMargin: Utils.getSizeWithScreenRatio(44)
Layout.topMargin: Math.round(20 * DefaultStyle.dp) Layout.topMargin: Utils.getSizeWithScreenRatio(20)
Layout.leftMargin: Math.round(64 * DefaultStyle.dp) Layout.leftMargin: Utils.getSizeWithScreenRatio(64)
DecoratedTextField { DecoratedTextField {
id: server id: server
propertyName: "serverUrl" propertyName: "serverUrl"

View file

@ -7,84 +7,93 @@ import QtQuick.Dialogs
import Linphone import Linphone
import UtilsCpp import UtilsCpp
import SettingsCpp import SettingsCpp
import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils
import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle
Item { ColumnLayout{
id: mainItem id: mainItem
width: Math.round(517 * DefaultStyle.dp) anchors.top: parent.top
anchors.topMargin: Utils.getSizeWithScreenRatio(23)
readonly property real spacing: Math.round(16 * DefaultStyle.dp) anchors.left: parent.left
property AccountProxy accountProxy anchors.leftMargin: Utils.getSizeWithScreenRatio(24)
anchors.right: parent.right
anchors.rightMargin: Utils.getSizeWithScreenRatio(24)
anchors.bottom: parent.bottom
anchors.bottomMargin: Utils.getSizeWithScreenRatio(23)
signal addAccountRequest() signal addAccountRequest()
signal editAccount(AccountGui account) signal editAccount(AccountGui account)
readonly property var childrenWidth: Utils.getSizeWithScreenRatio(517)
implicitHeight: list.contentHeight + Math.round(32 * DefaultStyle.dp) + 1 + addAccountButton.height readonly property real spacing: Utils.getSizeWithScreenRatio(16)
ColumnLayout{ required property var getPreviousItem
id: childLayout required property var getNextItem
anchors.top: parent.top property AccountProxy accountProxy
anchors.topMargin: mainItem.topPadding property var popupId
anchors.left: parent.left Component{
anchors.leftMargin: mainItem.leftPadding id: contactDelegate
anchors.right: parent.right Contact{
anchors.rightMargin: mainItem.rightPadding id: contactItem
anchors.bottom: parent.bottom Layout.preferredWidth: mainItem.childrenWidth
anchors.bottomMargin: mainItem.bottomPadding account: modelData
ListView{ isSelected: modelData && accountProxy.defaultAccount && modelData.core === accountProxy.defaultAccount.core
id: list onAvatarClicked: fileDialog.open()
Layout.preferredHeight: contentHeight onBackgroundClicked: {
Layout.fillWidth: true modelData.core.lSetDefaultAccount()
spacing: mainItem.spacing
model: AccountProxy {
id: accountProxy
sourceModel: AppCpp.accounts
} }
delegate: Contact{ onEdit: editAccount(modelData)
id: contactItem hoverEnabled: true
width: list.width spacing: mainItem.spacing
account: modelData FileDialog {
property bool isSelected: modelData && accountProxy.defaultAccount && modelData.core === accountProxy.defaultAccount.core id: fileDialog
onAvatarClicked: fileDialog.open() currentFolder: StandardPaths.standardLocations(StandardPaths.PicturesLocation)[0]
onBackgroundClicked: { onAccepted: {
modelData.core.lSetDefaultAccount() var avatarPath = UtilsCpp.createAvatar( selectedFile )
} if(avatarPath){
onEdit: editAccount(modelData) modelData.core.pictureUri = avatarPath
hoverEnabled: true
backgroundColor: contactItem.isSelected
? DefaultStyle.grey_200
: hovered
? DefaultStyle.main2_100
: DefaultStyle.grey_0
FileDialog {
id: fileDialog
currentFolder: StandardPaths.standardLocations(StandardPaths.PicturesLocation)[0]
onAccepted: {
var avatarPath = UtilsCpp.createAvatar( selectedFile )
if(avatarPath){
modelData.core.pictureUri = avatarPath
}
} }
} }
} }
} style: ButtonStyle.whiteSelected
Rectangle{ KeyNavigation.up: visibleChildren.length
id: separator != 0 ? getPreviousItem(
Layout.fillWidth: true index) : null
Layout.topMargin: mainItem.spacing KeyNavigation.down: visibleChildren.length
Layout.bottomMargin: mainItem.spacing != 0 ? getNextItem(
visible: addAccountButton.visible index) : null
height: Math.max(Math.round(1 * DefaultStyle.dp), 1)
color: DefaultStyle.main2_300
}
IconLabelButton{
id: addAccountButton
Layout.fillWidth: true
visible: SettingsCpp.maxAccount == 0 || SettingsCpp.maxAccount > accountProxy.count
onClicked: mainItem.addAccountRequest()
icon.source: AppIcons.plusCircle
icon.width: Math.round(32 * DefaultStyle.dp)
icon.height: Math.round(32 * DefaultStyle.dp)
text: 'Ajouter un compte'
} }
} }
}
Repeater{
model: AccountProxy {
id: accountProxy
sourceModel: AppCpp.accounts
}
delegate: contactDelegate
}
HorizontalBar{
Layout.topMargin: mainItem.spacing
Layout.bottomMargin: mainItem.spacing
visible: addAccountButton.visible
color: DefaultStyle.main2_300
}
IconLabelButton{
id: addAccountButton
Layout.fillWidth: true
visible: SettingsCpp.maxAccount == 0 || SettingsCpp.maxAccount > accountProxy.count
onClicked: mainItem.addAccountRequest()
icon.source: AppIcons.plusCircle
icon.width: Utils.getSizeWithScreenRatio(32)
icon.height: Utils.getSizeWithScreenRatio(32)
//: Add an account
text: qsTr("add_an_account")
KeyNavigation.up: visibleChildren.length
!= 0 ? getPreviousItem(
AppCpp.accounts.getCount()) : null
KeyNavigation.down: visibleChildren.length
!= 0 ? getNextItem(
AppCpp.accounts.getCount()) : null
}
}

View file

@ -60,7 +60,7 @@ AbstractMainPage {
Control.StackView.Immediate) Control.StackView.Immediate)
} }
rightPanelStackView.initialItem: emptySelection rightPanelStackView.initialItem: emptySelection
rightPanelStackView.width: Math.round(360 * DefaultStyle.dp) rightPanelStackView.width: Utils.getSizeWithScreenRatio(360)
onNoItemButtonPressed: goToNewCall() onNoItemButtonPressed: goToNewCall()
@ -81,7 +81,7 @@ AbstractMainPage {
Dialog { Dialog {
id: deleteHistoryPopup id: deleteHistoryPopup
width: Math.round(637 * DefaultStyle.dp) width: Utils.getSizeWithScreenRatio(637)
//: Supprimer l\'historique d\'appels ? //: Supprimer l\'historique d\'appels ?
title: qsTr("history_dialog_delete_all_call_logs_title") title: qsTr("history_dialog_delete_all_call_logs_title")
//: "L'ensemble de votre historique d'appels sera définitivement supprimé." //: "L'ensemble de votre historique d'appels sera définitivement supprimé."
@ -89,7 +89,7 @@ AbstractMainPage {
} }
Dialog { Dialog {
id: deleteForUserPopup id: deleteForUserPopup
width: Math.round(637 * DefaultStyle.dp) width: Utils.getSizeWithScreenRatio(637)
//: Supprimer l'historique d\'appels ? //: Supprimer l'historique d\'appels ?
title: qsTr("history_dialog_delete_call_logs_title") title: qsTr("history_dialog_delete_call_logs_title")
//: "L\'ensemble de votre historique d\'appels avec ce correspondant sera définitivement supprimé." //: "L\'ensemble de votre historique d\'appels avec ce correspondant sera définitivement supprimé."
@ -104,7 +104,7 @@ AbstractMainPage {
Control.StackView { Control.StackView {
id: listStackView id: listStackView
anchors.fill: parent anchors.fill: parent
anchors.leftMargin: Math.round(45 * DefaultStyle.dp) anchors.leftMargin: Utils.getSizeWithScreenRatio(45)
clip: true clip: true
initialItem: historyListItem initialItem: historyListItem
focus: true focus: true
@ -117,7 +117,7 @@ AbstractMainPage {
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
height: Math.round(402 * DefaultStyle.dp) height: Utils.getSizeWithScreenRatio(402)
NumericPadPopup { NumericPadPopup {
id: numericPadPopupItem id: numericPadPopupItem
width: parent.width width: parent.width
@ -140,7 +140,7 @@ AbstractMainPage {
spacing: 0 spacing: 0
RowLayout { RowLayout {
id: titleCallLayout id: titleCallLayout
spacing: Math.round(16 * DefaultStyle.dp) spacing: Utils.getSizeWithScreenRatio(16)
Text { Text {
Layout.fillWidth: true Layout.fillWidth: true
//: "Appels" //: "Appels"
@ -154,12 +154,14 @@ AbstractMainPage {
} }
PopupButton { PopupButton {
id: removeHistory id: removeHistory
width: Math.round(24 * DefaultStyle.dp) icon.width: Utils.getSizeWithScreenRatio(24)
height: Math.round(24 * DefaultStyle.dp) icon.height: Utils.getSizeWithScreenRatio(24)
focus: true focus: true
popup.x: 0 popup.x: 0
KeyNavigation.right: newCallButton KeyNavigation.right: newCallButton
KeyNavigation.down: listStackView KeyNavigation.down: listStackView
//: Call history options
popUpTitle: qsTr("call_history_list_options_accessible_name")
popup.contentItem: ColumnLayout { popup.contentItem: ColumnLayout {
IconLabelButton { IconLabelButton {
Layout.fillWidth: true Layout.fillWidth: true
@ -186,13 +188,15 @@ AbstractMainPage {
id: newCallButton id: newCallButton
style: ButtonStyle.noBackground style: ButtonStyle.noBackground
icon.source: AppIcons.newCall icon.source: AppIcons.newCall
Layout.preferredWidth: Math.round(28 * DefaultStyle.dp) Layout.preferredWidth: Utils.getSizeWithScreenRatio(34)
Layout.preferredHeight: Math.round(28 * DefaultStyle.dp) Layout.preferredHeight: Utils.getSizeWithScreenRatio(34)
Layout.rightMargin: Math.round(39 * DefaultStyle.dp) Layout.rightMargin: Utils.getSizeWithScreenRatio(39)
icon.width: Math.round(28 * DefaultStyle.dp) icon.width: Utils.getSizeWithScreenRatio(28)
icon.height: Math.round(28 * DefaultStyle.dp) icon.height: Utils.getSizeWithScreenRatio(28)
KeyNavigation.left: removeHistory KeyNavigation.left: removeHistory
KeyNavigation.down: listStackView KeyNavigation.down: listStackView
//: Create new call
Accessible.name: qsTr("create_new_call_accessible_name")
onClicked: { onClicked: {
console.debug("[CallPage]User: create new call") console.debug("[CallPage]User: create new call")
listStackView.push(newCallItem) listStackView.push(newCallItem)
@ -202,8 +206,8 @@ AbstractMainPage {
SearchBar { SearchBar {
id: searchBar id: searchBar
Layout.fillWidth: true Layout.fillWidth: true
Layout.topMargin: Math.round(18 * DefaultStyle.dp) Layout.topMargin: Utils.getSizeWithScreenRatio(18)
Layout.rightMargin: Math.round(39 * DefaultStyle.dp) Layout.rightMargin: Utils.getSizeWithScreenRatio(39)
//: "Rechercher un appel" //: "Rechercher un appel"
placeholderText: qsTr("call_search_in_history") placeholderText: qsTr("call_search_in_history")
visible: historyListView.count !== 0 || text.length !== 0 visible: historyListView.count !== 0 || text.length !== 0
@ -220,9 +224,9 @@ AbstractMainPage {
Rectangle { Rectangle {
visible: SettingsCpp.callForwardToAddress.length > 0 visible: SettingsCpp.callForwardToAddress.length > 0
Layout.fillWidth: true Layout.fillWidth: true
Layout.preferredHeight: Math.round(40 * DefaultStyle.dp) Layout.preferredHeight: Utils.getSizeWithScreenRatio(40)
Layout.topMargin: Math.round(18 * DefaultStyle.dp) Layout.topMargin: Utils.getSizeWithScreenRatio(18)
Layout.rightMargin: Math.round(39 * DefaultStyle.dp) Layout.rightMargin: Utils.getSizeWithScreenRatio(39)
color: "transparent" color: "transparent"
radius: 25 * DefaultStyle.dp radius: 25 * DefaultStyle.dp
border.color: DefaultStyle.warning_500_main border.color: DefaultStyle.warning_500_main
@ -235,8 +239,8 @@ AbstractMainPage {
fillMode: Image.PreserveAspectFit fillMode: Image.PreserveAspectFit
imageSource: AppIcons.callForward imageSource: AppIcons.callForward
colorizationColor: DefaultStyle.warning_500_main colorizationColor: DefaultStyle.warning_500_main
Layout.preferredHeight: Math.round(24 * DefaultStyle.dp) Layout.preferredHeight: Utils.getSizeWithScreenRatio(24)
Layout.preferredWidth: Math.round(24 * DefaultStyle.dp) Layout.preferredWidth: Utils.getSizeWithScreenRatio(24)
} }
Text { Text {
text: qsTr("call_forward_to_address_info") + (SettingsCpp.callForwardToAddress == 'voicemail' ? qsTr("call_forward_to_address_info_voicemail") : SettingsCpp.callForwardToAddress) text: qsTr("call_forward_to_address_info") + (SettingsCpp.callForwardToAddress == 'voicemail' ? qsTr("call_forward_to_address_info_voicemail") : SettingsCpp.callForwardToAddress)
@ -259,14 +263,14 @@ AbstractMainPage {
Control.Control { Control.Control {
id: listLayout id: listLayout
anchors.fill: parent anchors.fill: parent
anchors.rightMargin: Math.round(39 * DefaultStyle.dp) anchors.rightMargin: Utils.getSizeWithScreenRatio(39)
padding: 0 padding: 0
background: Item {} background: Item {}
contentItem: ColumnLayout { contentItem: ColumnLayout {
Text { Text {
visible: historyListView.count === 0 && !historyListView.loading visible: historyListView.count === 0 && !historyListView.loading
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
Layout.topMargin: Math.round(137 * DefaultStyle.dp) Layout.topMargin: Utils.getSizeWithScreenRatio(137)
//: "Aucun résultat" //: "Aucun résultat"
text: searchBar.text.length != 0 ? qsTr("list_filter_no_result_found") text: searchBar.text.length != 0 ? qsTr("list_filter_no_result_found")
//: "Aucun appel dans votre historique" //: "Aucun appel dans votre historique"
@ -280,7 +284,7 @@ AbstractMainPage {
id: historyListView id: historyListView
Layout.fillWidth: true Layout.fillWidth: true
Layout.fillHeight: true Layout.fillHeight: true
Layout.topMargin: Math.round(38 * DefaultStyle.dp) Layout.topMargin: Utils.getSizeWithScreenRatio(38)
searchBar: searchBar searchBar: searchBar
Control.ScrollBar.vertical: scrollbar Control.ScrollBar.vertical: scrollbar
@ -314,7 +318,7 @@ AbstractMainPage {
anchors.top: parent.top anchors.top: parent.top
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
anchors.right: parent.right anchors.right: parent.right
anchors.rightMargin: Math.round(8 * DefaultStyle.dp) anchors.rightMargin: Utils.getSizeWithScreenRatio(8)
policy: Control.ScrollBar.AsNeeded policy: Control.ScrollBar.AsNeeded
} }
} }
@ -336,14 +340,18 @@ AbstractMainPage {
anchors.fill: parent anchors.fill: parent
spacing: 0 spacing: 0
RowLayout { RowLayout {
spacing: Math.round(10 * DefaultStyle.dp) spacing: Utils.getSizeWithScreenRatio(10)
Button { Button {
Layout.preferredWidth: Math.round(24 * DefaultStyle.dp) icon.width: Utils.getSizeWithScreenRatio(24)
Layout.preferredHeight: Math.round(24 * DefaultStyle.dp) icon.height: Utils.getSizeWithScreenRatio(24)
Layout.preferredWidth: Utils.getSizeWithScreenRatio(30)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(30)
style: ButtonStyle.noBackground style: ButtonStyle.noBackground
icon.source: AppIcons.leftArrow icon.source: AppIcons.leftArrow
focus: true focus: true
KeyNavigation.down: listStackView KeyNavigation.down: listStackView
//: Return to call history
Accessible.name: qsTr("return_to_call_history_accessible_name")
onClicked: { onClicked: {
console.debug( console.debug(
"[CallPage]User: return to call history") "[CallPage]User: return to call history")
@ -365,7 +373,7 @@ AbstractMainPage {
} }
NewCallForm { NewCallForm {
id: callContactsList id: callContactsList
Layout.topMargin: Math.round(18 * DefaultStyle.dp) Layout.topMargin: Utils.getSizeWithScreenRatio(18)
Layout.fillWidth: true Layout.fillWidth: true
Layout.fillHeight: true Layout.fillHeight: true
focus: true focus: true
@ -433,8 +441,8 @@ AbstractMainPage {
CallHistoryLayout { CallHistoryLayout {
id: contactDetail id: contactDetail
anchors.fill: parent anchors.fill: parent
anchors.topMargin: Math.round(45 * DefaultStyle.dp) anchors.topMargin: Utils.getSizeWithScreenRatio(45)
anchors.bottomMargin: Math.round(45 * DefaultStyle.dp) anchors.bottomMargin: Utils.getSizeWithScreenRatio(45)
visible: mainItem.selectedRowHistoryGui != undefined visible: mainItem.selectedRowHistoryGui != undefined
callHistoryGui: selectedRowHistoryGui callHistoryGui: selectedRowHistoryGui
@ -448,6 +456,7 @@ AbstractMainPage {
id: detailOptions id: detailOptions
anchors.right: parent.right anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
popUpTitle: qsTr("call_history_options_accessible_name")
popup.x: width popup.x: width
popup.contentItem: FocusScope { popup.contentItem: FocusScope {
implicitHeight: detailsButtons.implicitHeight implicitHeight: detailsButtons.implicitHeight
@ -463,14 +472,15 @@ AbstractMainPage {
id: detailsButtons id: detailsButtons
anchors.fill: parent anchors.fill: parent
IconLabelButton { IconLabelButton {
id: addContactButton
Layout.fillWidth: true Layout.fillWidth: true
//: "Show contact" //: "Show contact"
text: contactDetail.isLocalFriend ? qsTr("menu_see_existing_contact") : text: contactDetail.isLocalFriend ? qsTr("menu_see_existing_contact") :
//: "Add to contacts" //: "Add to contacts"
qsTr("menu_add_address_to_contacts") qsTr("menu_add_address_to_contacts")
icon.source: AppIcons.plusCircle icon.source: AppIcons.plusCircle
icon.width: Math.round(32 * DefaultStyle.dp) icon.width: Utils.getSizeWithScreenRatio(32)
icon.height: Math.round(32 * DefaultStyle.dp) icon.height: Utils.getSizeWithScreenRatio(32)
onClicked: { onClicked: {
detailOptions.close() detailOptions.close()
if (contactDetail.isLocalFriend) if (contactDetail.isLocalFriend)
@ -478,14 +488,21 @@ AbstractMainPage {
else else
mainItem.createContactRequested(contactDetail.contactName, contactDetail.contactAddress) mainItem.createContactRequested(contactDetail.contactName, contactDetail.contactAddress)
} }
KeyNavigation.up: visibleChildren.length
!= 0 ? detailOptions.getPreviousItem(
0) : null
KeyNavigation.down: visibleChildren.length
!= 0 ? detailOptions.getNextItem(
0) : null
} }
IconLabelButton { IconLabelButton {
id: copySIPAddressButton
Layout.fillWidth: true Layout.fillWidth: true
//: "Copier l'adresse SIP" //: "Copier l'adresse SIP"
text: qsTr("menu_copy_sip_address") text: qsTr("menu_copy_sip_address")
icon.source: AppIcons.copy icon.source: AppIcons.copy
icon.width: Math.round(32 * DefaultStyle.dp) icon.width: Utils.getSizeWithScreenRatio(32)
icon.height: Math.round(32 * DefaultStyle.dp) icon.height: Utils.getSizeWithScreenRatio(32)
onClicked: { onClicked: {
detailOptions.close() detailOptions.close()
var success = UtilsCpp.copyToClipboard( var success = UtilsCpp.copyToClipboard(
@ -505,6 +522,12 @@ AbstractMainPage {
qsTr("sip_address_copy_to_clipboard_error"), qsTr("sip_address_copy_to_clipboard_error"),
false) false)
} }
KeyNavigation.up: visibleChildren.length
!= 0 ? detailOptions.getPreviousItem(
1) : null
KeyNavigation.down: visibleChildren.length
!= 0 ? detailOptions.getNextItem(
1) : null
} }
// IconLabelButton { // IconLabelButton {
// background: Item {} // background: Item {}
@ -517,17 +540,18 @@ AbstractMainPage {
// } // }
Rectangle { Rectangle {
Layout.fillWidth: true Layout.fillWidth: true
Layout.preferredHeight: Math.round(2 * DefaultStyle.dp) Layout.preferredHeight: Utils.getSizeWithScreenRatio(2)
color: DefaultStyle.main2_400 color: DefaultStyle.main2_400
} }
IconLabelButton { IconLabelButton {
id: deleteHistoryButton
Layout.fillWidth: true Layout.fillWidth: true
//: "Supprimer l'historique" //: "Supprimer l'historique"
text: qsTr("menu_delete_history") text: qsTr("menu_delete_history")
icon.source: AppIcons.trashCan icon.source: AppIcons.trashCan
icon.width: Math.round(32 * DefaultStyle.dp) icon.width: Utils.getSizeWithScreenRatio(32)
icon.height: Math.round(32 * DefaultStyle.dp) icon.height: Utils.getSizeWithScreenRatio(32)
style: ButtonStyle.hoveredBackgroundRed style: ButtonStyle.hoveredBackgroundRed
Connections { Connections {
target: deleteForUserPopup target: deleteForUserPopup
@ -541,12 +565,18 @@ AbstractMainPage {
detailOptions.close() detailOptions.close()
deleteForUserPopup.open() deleteForUserPopup.open()
} }
KeyNavigation.up: visibleChildren.length
!= 0 ? detailOptions.getPreviousItem(
2) : null
KeyNavigation.down: visibleChildren.length
!= 0 ? detailOptions.getNextItem(
2) : null
} }
} }
} }
} }
detailContent: Item { detailContent: Item {
Layout.preferredWidth: Math.round(360 * DefaultStyle.dp) Layout.preferredWidth: Utils.getSizeWithScreenRatio(360)
Layout.fillHeight: true Layout.fillHeight: true
RoundedPane { RoundedPane {
id: detailControl id: detailControl
@ -557,7 +587,7 @@ AbstractMainPage {
id: detailListBackground id: detailListBackground
anchors.fill: parent anchors.fill: parent
color: DefaultStyle.grey_0 color: DefaultStyle.grey_0
radius: Math.round(15 * DefaultStyle.dp) radius: Utils.getSizeWithScreenRatio(15)
} }
contentItem: Control.ScrollView { contentItem: Control.ScrollView {
@ -573,37 +603,37 @@ AbstractMainPage {
id: detailListView id: detailListView
Layout.fillWidth: true Layout.fillWidth: true
Layout.fillHeight: true Layout.fillHeight: true
Layout.rightMargin: historyScrollBar.width + Math.round(8 * DefaultStyle.dp) Layout.rightMargin: historyScrollBar.width + Utils.getSizeWithScreenRatio(8)
spacing: Math.round(14 * DefaultStyle.dp) spacing: Utils.getSizeWithScreenRatio(14)
clip: true clip: true
searchText: mainItem.selectedRowHistoryGui ? mainItem.selectedRowHistoryGui.core.remoteAddress : "" searchText: mainItem.selectedRowHistoryGui ? mainItem.selectedRowHistoryGui.core.remoteAddress : ""
busyIndicatorSize: Math.round(40 * DefaultStyle.dp) busyIndicatorSize: Utils.getSizeWithScreenRatio(40)
delegate: Item { delegate: Item {
width: detailListView.width width: detailListView.width
height: Math.round(56 * DefaultStyle.dp) height: Utils.getSizeWithScreenRatio(56)
RowLayout { RowLayout {
anchors.fill: parent anchors.fill: parent
anchors.leftMargin: Math.round(20 * DefaultStyle.dp) anchors.leftMargin: Utils.getSizeWithScreenRatio(20)
anchors.rightMargin: Math.round(20 * DefaultStyle.dp) anchors.rightMargin: Utils.getSizeWithScreenRatio(20)
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
ColumnLayout { ColumnLayout {
Layout.alignment: Qt.AlignVCenter Layout.alignment: Qt.AlignVCenter
RowLayout { RowLayout {
EffectImage { EffectImage {
id: statusIcon id: statusIcon
imageSource: modelData.core.status imageSource: modelData.core.status
=== LinphoneEnums.CallStatus.Declined === LinphoneEnums.CallStatus.Declined
|| modelData.core.status === LinphoneEnums.CallStatus.DeclinedElsewhere || modelData.core.status === LinphoneEnums.CallStatus.Aborted || modelData.core.status === LinphoneEnums.CallStatus.EarlyAborted ? AppIcons.arrowElbow : modelData.core.isOutgoing ? AppIcons.arrowUpRight : AppIcons.arrowDownLeft || modelData.core.status === LinphoneEnums.CallStatus.DeclinedElsewhere || modelData.core.status === LinphoneEnums.CallStatus.Aborted || modelData.core.status === LinphoneEnums.CallStatus.EarlyAborted ? AppIcons.arrowElbow : modelData.core.isOutgoing ? AppIcons.arrowUpRight : AppIcons.arrowDownLeft
colorizationColor: modelData.core.status === LinphoneEnums.CallStatus.Declined || modelData.core.status === LinphoneEnums.CallStatus.DeclinedElsewhere || modelData.core.status === LinphoneEnums.CallStatus.Aborted || modelData.core.status === LinphoneEnums.CallStatus.EarlyAborted || modelData.core.status === LinphoneEnums.CallStatus.Missed ? DefaultStyle.danger_500main : modelData.core.isOutgoing ? DefaultStyle.info_500_main : DefaultStyle.success_500main colorizationColor: modelData.core.status === LinphoneEnums.CallStatus.Declined || modelData.core.status === LinphoneEnums.CallStatus.DeclinedElsewhere || modelData.core.status === LinphoneEnums.CallStatus.Aborted || modelData.core.status === LinphoneEnums.CallStatus.EarlyAborted || modelData.core.status === LinphoneEnums.CallStatus.Missed ? DefaultStyle.danger_500_main : modelData.core.isOutgoing ? DefaultStyle.info_500_main : DefaultStyle.success_500_main
Layout.preferredWidth: Math.round(16 * DefaultStyle.dp) Layout.preferredWidth: Utils.getSizeWithScreenRatio(16)
Layout.preferredHeight: Math.round(16 * DefaultStyle.dp) Layout.preferredHeight: Utils.getSizeWithScreenRatio(16)
transform: Rotation { transform: Rotation {
angle: modelData.core.isOutgoing angle: modelData.core.isOutgoing
&& (modelData.core.status === LinphoneEnums.CallStatus.Declined || modelData.core.status === LinphoneEnums.CallStatus.DeclinedElsewhere || modelData.core.status === LinphoneEnums.CallStatus.Aborted || modelData.core.status === LinphoneEnums.CallStatus.EarlyAborted) ? 180 : 0 && (modelData.core.status === LinphoneEnums.CallStatus.Declined || modelData.core.status === LinphoneEnums.CallStatus.DeclinedElsewhere || modelData.core.status === LinphoneEnums.CallStatus.Aborted || modelData.core.status === LinphoneEnums.CallStatus.EarlyAborted) ? 180 : 0
origin { origin {
x: statusIcon.width / 2 x: statusIcon.width / 2
y: statusIcon.height / 2 y: statusIcon.height / 2
} }
} }
} }
@ -623,10 +653,10 @@ AbstractMainPage {
} }
Text { Text {
text: UtilsCpp.formatDate(modelData.core.date) text: UtilsCpp.formatDate(modelData.core.date)
color: modelData.core.status === LinphoneEnums.CallStatus.Missed ? DefaultStyle.danger_500main : DefaultStyle.main2_500main color: modelData.core.status === LinphoneEnums.CallStatus.Missed ? DefaultStyle.danger_500_main : DefaultStyle.main2_500_main
font { font {
pixelSize: Math.round(12 * DefaultStyle.dp) pixelSize: Utils.getSizeWithScreenRatio(12)
weight: Math.round(300 * DefaultStyle.dp) weight: Utils.getSizeWithScreenRatio(300)
} }
} }
} }
@ -639,8 +669,8 @@ AbstractMainPage {
modelData.core.duration, modelData.core.duration,
false) false)
font { font {
pixelSize: Math.round(12 * DefaultStyle.dp) pixelSize: Utils.getSizeWithScreenRatio(12)
weight: Math.round(300 * DefaultStyle.dp) weight: Utils.getSizeWithScreenRatio(300)
} }
} }
} }
@ -660,11 +690,11 @@ AbstractMainPage {
id: iconLabel id: iconLabel
property string text property string text
property string iconSource property string iconSource
property color colorizationColor: DefaultStyle.main2_500main property color colorizationColor: DefaultStyle.main2_500_main
EffectImage { EffectImage {
imageSource: iconLabel.iconSource imageSource: iconLabel.iconSource
Layout.preferredWidth: Math.round(24 * DefaultStyle.dp) Layout.preferredWidth: Utils.getSizeWithScreenRatio(24)
Layout.preferredHeight: Math.round(24 * DefaultStyle.dp) Layout.preferredHeight: Utils.getSizeWithScreenRatio(24)
fillMode: Image.PreserveAspectFit fillMode: Image.PreserveAspectFit
colorizationColor: iconLabel.colorizationColor colorizationColor: iconLabel.colorizationColor
} }

View file

@ -2,6 +2,7 @@ import QtQuick
import QtQuick.Layouts import QtQuick.Layouts
import QtQuick.Controls.Basic as Control import QtQuick.Controls.Basic as Control
import Linphone import Linphone
import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils
import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle
Control.Page { Control.Page {
@ -11,6 +12,8 @@ Control.Page {
property alias customHeaderButtons: customButtonLayout.children property alias customHeaderButtons: customButtonLayout.children
property int contentItemHeight: scrollview.height property int contentItemHeight: scrollview.height
property bool closeButtonVisible: true property bool closeButtonVisible: true
property Item firstContentFocusableItem: undefined
property Item lastContentFocusableItem: undefined
clip: true clip: true
property string headerTitleText property string headerTitleText
@ -77,6 +80,9 @@ Control.Page {
style: ButtonStyle.noBackground style: ButtonStyle.noBackground
icon.source: AppIcons.closeX icon.source: AppIcons.closeX
onClicked: mainItem.visible = false onClicked: mainItem.visible = false
//: Close %1 panel
Accessible.name: qsTr("close_name_panel_accessible_button").arg(mainItem.headerTitleText)
KeyNavigation.tab : firstContentFocusableItem ?? nextItemInFocusChain()
} }
} }
RowLayout { RowLayout {
@ -106,7 +112,7 @@ Control.Page {
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
text: mainItem.headerSubtitleText text: mainItem.headerSubtitleText
color: DefaultStyle.main2_500main color: DefaultStyle.main2_500_main
font { font {
pixelSize: Math.round(12 * DefaultStyle.dp) pixelSize: Math.round(12 * DefaultStyle.dp)
weight: Math.round(300 * DefaultStyle.dp) weight: Math.round(300 * DefaultStyle.dp)

View file

@ -245,6 +245,8 @@ FriendGui{
mainItem.createContact("", "") mainItem.createContact("", "")
} }
KeyNavigation.down: searchBar KeyNavigation.down: searchBar
//: Create new contact
Accessible.name: qsTr("create_contact_accessible_name")
} }
} }
@ -340,6 +342,8 @@ FriendGui{
icon.source: contactDetailLayout.icon icon.source: contactDetailLayout.icon
style: ButtonStyle.noBackgroundOrange style: ButtonStyle.noBackgroundOrange
onClicked: contactDetailLayout.titleIconClicked() onClicked: contactDetailLayout.titleIconClicked()
//: More info %1
Accessible.name: qsTr("more_info_accessible_name").arg(contactDetailLayout.label)
} }
Item { Item {
Layout.fillWidth: true Layout.fillWidth: true
@ -351,6 +355,12 @@ FriendGui{
checked: true checked: true
icon.source: checked ? AppIcons.upArrow : AppIcons.downArrow icon.source: checked ? AppIcons.upArrow : AppIcons.downArrow
KeyNavigation.down: contentControl KeyNavigation.down: contentControl
Accessible.name: (checked ?
//: Shrink %1
qsTr("shrink_accessible_name"):
//: Expand %1
qsTr("expand_accessible_name")).arg(contactDetailLayout.label)
} }
} }
RoundedPane { RoundedPane {
@ -378,28 +388,6 @@ FriendGui{
property var computedContactNameObj: UtilsCpp.getDisplayName(contactAddress) property var computedContactNameObj: UtilsCpp.getDisplayName(contactAddress)
property string computedContactName: computedContactNameObj ? computedContactNameObj.value : "" property string computedContactName: computedContactNameObj ? computedContactNameObj.value : ""
property string contactName: contact ? contact.core.fullName : computedContactName property string contactName: contact ? contact.core.fullName : computedContactName
component LabelButton: ColumnLayout {
id: labelButton
// property alias image: buttonImg
property alias button: button
property string label
spacing: Math.round(8 * DefaultStyle.dp)
RoundButton {
id: button
Layout.alignment: Qt.AlignHCenter
Layout.preferredWidth: Math.round(56 * DefaultStyle.dp)
Layout.preferredHeight: Math.round(56 * DefaultStyle.dp)
style: ButtonStyle.grey
}
Text {
Layout.alignment: Qt.AlignHCenter
text: labelButton.label
font {
pixelSize: Typography.p1.pixelSize
weight: Typography.p1.weight
}
}
}
component ActionsButtons: RowLayout { component ActionsButtons: RowLayout {
spacing: Math.round(58 * DefaultStyle.dp) spacing: Math.round(58 * DefaultStyle.dp)
LabelButton { LabelButton {
@ -533,6 +521,8 @@ FriendGui{
UtilsCpp.createCall( UtilsCpp.createCall(
listViewModelData.address) listViewModelData.address)
} }
//: Call address %1
Accessible.name: qsTr("call_adress_accessible_name").arg(listViewModelData.address)
} }
} }
@ -639,6 +629,7 @@ FriendGui{
} }
onClicked: console.debug( onClicked: console.debug(
"TODO : go to shared media") "TODO : go to shared media")
Accessible.name: qsTr("contact_details_medias_subtitle")
} }
} }
ContactDetailLayout { ContactDetailLayout {
@ -707,6 +698,8 @@ FriendGui{
style: ButtonStyle.tertiary style: ButtonStyle.tertiary
//: "Vérifier" //: "Vérifier"
text: qsTr("contact_make_call_check_device_trust") text: qsTr("contact_make_call_check_device_trust")
//: Verify %1 device
Accessible.name: qsTr("verify_device_accessible_name").arg(deviceDelegate.deviceName)
onClicked: { onClicked: {
if (SettingsCpp.getDisplayDeviceCheckConfirmation( if (SettingsCpp.getDisplayDeviceCheckConfirmation(
)) { )) {

View file

@ -600,7 +600,7 @@ AbstractMainPage {
Text { Text {
//: "%n participant(s) sélectionné(s)" //: "%n participant(s) sélectionné(s)"
text: qsTr("group_call_participant_selected", '', addParticipantLayout.selectedParticipantsCount).arg(addParticipantLayout.selectedParticipantsCount) text: qsTr("group_call_participant_selected", '', addParticipantLayout.selectedParticipantsCount).arg(addParticipantLayout.selectedParticipantsCount)
color: DefaultStyle.main2_500main color: DefaultStyle.main2_500_main
Layout.leftMargin: addParticipantsBackButton.width + addParticipantsButtons.spacing Layout.leftMargin: addParticipantsBackButton.width + addParticipantsButtons.spacing
maximumLineCount: 1 maximumLineCount: 1
font { font {

View file

@ -275,7 +275,7 @@ ApplicationWindow {
font.pixelSize: Math.round(14 * DefaultStyle.dp) font.pixelSize: Math.round(14 * DefaultStyle.dp)
// "%1 FPS" // "%1 FPS"
text: qsTr("fps_counter").arg(parent.fps) text: qsTr("fps_counter").arg(parent.fps)
color: parent.fps < 30 ? DefaultStyle.danger_500main : DefaultStyle.main2_900 color: parent.fps < 30 ? DefaultStyle.danger_500_main : DefaultStyle.main2_900
} }
} }
} }

View file

@ -7,6 +7,7 @@ import EnumsToStringCpp
import UtilsCpp import UtilsCpp
import SettingsCpp import SettingsCpp
import DesktopToolsCpp import DesktopToolsCpp
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle import "qrc:/qt/qml/Linphone/view/Style/buttonStyle.js" as ButtonStyle
AbstractWindow { AbstractWindow {
@ -28,6 +29,16 @@ AbstractWindow {
property bool callTerminatedByUser: false property bool callTerminatedByUser: false
property var callState: call ? call.core.state : LinphoneEnums.CallState.Idle property var callState: call ? call.core.state : LinphoneEnums.CallState.Idle
property var transferState: call && call.core.transferState property var transferState: call && call.core.transferState
property bool startingCall: mainWindow.callState == LinphoneEnums.CallState.OutgoingInit
|| mainWindow.callState
== LinphoneEnums.CallState.OutgoingProgress
|| mainWindow.callState
== LinphoneEnums.CallState.OutgoingRinging
|| mainWindow.callState
== LinphoneEnums.CallState.OutgoingEarlyMedia
|| mainWindow.callState == LinphoneEnums.CallState.IncomingReceived
property Item firstButtonInBottomTab : mainWindow.startingCall ? endCallButton : (videoCameraButton.visible && videoCameraButton.enabled ? videoCameraButton : audioMicrophoneButton)
property Item lastButtonInBottomTab : mainWindow.startingCall ? Utils.getLastFocussableItemInItem(controlCallButtons) : endCallButton
onCallStateChanged: { onCallStateChanged: {
if (callState === LinphoneEnums.CallState.Connected) { if (callState === LinphoneEnums.CallState.Connected) {
@ -338,7 +349,7 @@ AbstractWindow {
=== LinphoneEnums.CallState.End === LinphoneEnums.CallState.End
|| mainWindow.callState || mainWindow.callState
=== LinphoneEnums.CallState.Released === LinphoneEnums.CallState.Released
|| mainWindow.conference ? DefaultStyle.danger_500main : mainWindow.call.core.dir === LinphoneEnums.CallDir.Outgoing ? DefaultStyle.info_500_main : DefaultStyle.success_500main || mainWindow.conference ? DefaultStyle.danger_500_main : mainWindow.call.core.dir === LinphoneEnums.CallDir.Outgoing ? DefaultStyle.info_500_main : DefaultStyle.success_500_main
onColorizationColorChanged: { onColorizationColorChanged: {
callStatusIcon.active = !callStatusIcon.active callStatusIcon.active = !callStatusIcon.active
callStatusIcon.active = !callStatusIcon.active callStatusIcon.active = !callStatusIcon.active
@ -520,31 +531,36 @@ AbstractWindow {
Item { Item {
Layout.fillWidth: true Layout.fillWidth: true
} }
EffectImage {
Layout.preferredWidth: Math.round(32 * DefaultStyle.dp) // Button open statistics panel
Layout.preferredHeight: Math.round(32 * DefaultStyle.dp) Button{
Layout.rightMargin: Math.round(30 * DefaultStyle.dp) id: openStatisticPanelButton
property int quality: mainWindow.call ? mainWindow.call.core.quality : 0 property int quality: mainWindow.call ? mainWindow.call.core.quality : 0
imageSource: quality >= 4 ? AppIcons.cellSignalFull : quality >= 3 ? AppIcons.cellSignalMedium : quality >= 2 ? AppIcons.cellSignalLow : AppIcons.cellSignalNone icon.width: Math.round(32 * DefaultStyle.dp)
icon.height: Math.round(32 * DefaultStyle.dp)
Layout.preferredWidth: Math.round(40 * DefaultStyle.dp)
Layout.preferredHeight: Math.round(40 * DefaultStyle.dp)
Layout.rightMargin: Math.round(30 * DefaultStyle.dp)
icon.source: quality >= 4 ? AppIcons.cellSignalFull : quality >= 3 ? AppIcons.cellSignalMedium : quality >= 2 ? AppIcons.cellSignalLow : AppIcons.cellSignalNone
colorizationColor: DefaultStyle.grey_0 colorizationColor: DefaultStyle.grey_0
MouseArea { style: ButtonStyle.noBackgroundLightBorder
anchors.fill: parent Accessible.name: qsTr("open_statistic_panel_accessible_name")
hoverEnabled: true onClicked: {
cursorShape: containsMouse ? Qt.PointingHandCursor : Qt.ArrowCursor if (rightPanel.visible
onClicked: { && rightPanel.contentLoader.item.objectName
if (rightPanel.visible === "statsPanel")
&& rightPanel.contentLoader.item.objectName rightPanel.visible = false
=== "statsPanel") else {
rightPanel.visible = false rightPanel.visible = true
else { rightPanel.replace(statsPanel)
rightPanel.visible = true
rightPanel.replace(statsPanel)
}
} }
} }
KeyNavigation.tab: rightPanel.visible ? nextItemInFocusChain() : mainWindow.firstButtonInBottomTab
KeyNavigation.backtab: mainWindow.lastButtonInBottomTab
} }
} }
// Banner middle of header - screen sharing or record screen
Control.Control { Control.Control {
id: screenSharingOrRecordBanner id: screenSharingOrRecordBanner
property var isScreenSharing: mainWindow.conference && mainWindow.conference.core.isLocalScreenSharing property var isScreenSharing: mainWindow.conference && mainWindow.conference.core.isLocalScreenSharing
@ -573,14 +589,14 @@ AbstractWindow {
: AppIcons.recordFill : AppIcons.recordFill
colorizationColor: screenSharingOrRecordBanner.isScreenSharing colorizationColor: screenSharingOrRecordBanner.isScreenSharing
? DefaultStyle.grey_0 ? DefaultStyle.grey_0
: DefaultStyle.danger_500main : DefaultStyle.danger_500_main
Layout.preferredWidth: Math.round(24 * DefaultStyle.dp) Layout.preferredWidth: Math.round(24 * DefaultStyle.dp)
Layout.preferredHeight: Math.round(24 * DefaultStyle.dp) Layout.preferredHeight: Math.round(24 * DefaultStyle.dp)
} }
Text { Text {
color: screenSharingOrRecordBanner.isScreenSharing color: screenSharingOrRecordBanner.isScreenSharing
? DefaultStyle.grey_0 ? DefaultStyle.grey_0
: DefaultStyle.danger_500main : DefaultStyle.danger_500_main
font: Typography.b1 font: Typography.b1
text: mainWindow.call text: mainWindow.call
? screenSharingOrRecordBanner.isScreenSharing ? screenSharingOrRecordBanner.isScreenSharing
@ -603,12 +619,18 @@ AbstractWindow {
MediumButton { MediumButton {
visible: mainWindow.call visible: mainWindow.call
&& mainWindow.call.core.recording || screenSharingOrRecordBanner.isScreenSharing && mainWindow.call.core.recording || screenSharingOrRecordBanner.isScreenSharing
//: "Stop recording"
text: screenSharingOrRecordBanner.isScreenSharing text: screenSharingOrRecordBanner.isScreenSharing
? qsTr("call_stop_recording")
//: "Stop sharing" //: "Stop sharing"
: qsTr("call_stop_screen_sharing") ? qsTr("call_stop_screen_sharing")
style: ButtonStyle.main //: "Stop recording"
: qsTr("call_stop_recording")
Accessible.name: screenSharingOrRecordBanner.isScreenSharing ?
//: "Stop screen sharing"
qsTr("stop_screen_sharing_accessible_name")
//: Stop recording
: qsTr("stop_recording_accessible_name")
style: ButtonStyle.mainLightBorder
onPressed: { onPressed: {
if (screenSharingOrRecordBanner.isScreenSharing) mainWindow.conference.core.lToggleScreenSharing() if (screenSharingOrRecordBanner.isScreenSharing) mainWindow.conference.core.lToggleScreenSharing()
else mainWindow.call.core.lStopRecording() else mainWindow.call.core.lStopRecording()
@ -643,6 +665,7 @@ AbstractWindow {
} }
headerStack.currentIndex: 0 headerStack.currentIndex: 0
headerValidateButtonText: qsTr("add") headerValidateButtonText: qsTr("add")
KeyNavigation.tab : Utils.isDescendant(nextItemInFocusChain(), rightPanel) ? nextItemInFocusChain() : videoCameraButton
// Do not consider padding for chat // Do not consider padding for chat
Binding on topPadding { Binding on topPadding {
@ -711,6 +734,14 @@ AbstractWindow {
if (!rightPanel.contentLoader.item || rightPanel.contentLoader.item.objectName !== "screencastPanel") screencastPanelButton.checked = false if (!rightPanel.contentLoader.item || rightPanel.contentLoader.item.objectName !== "screencastPanel") screencastPanelButton.checked = false
if (!rightPanel.contentLoader.item || rightPanel.contentLoader.item.objectName !== "chatPanel") chatPanelButton.checked = false if (!rightPanel.contentLoader.item || rightPanel.contentLoader.item.objectName !== "chatPanel") chatPanelButton.checked = false
if (!rightPanel.contentLoader.item || rightPanel.contentLoader.item.objectName !== "participantListPanel") participantListButton.checked = false if (!rightPanel.contentLoader.item || rightPanel.contentLoader.item.objectName !== "participantListPanel") participantListButton.checked = false
// Update tab focus properties
var firstContentFocusableItem = Utils.getFirstFocussableItemInItem(rightPanel.contentLoader.item)
rightPanel.firstContentFocusableItem = firstContentFocusableItem ?? mainWindow.firstButtonInBottomTab
var lastContentFocusableItem = Utils.getLastFocussableItemInItem(rightPanel.contentLoader.item)
if(lastContentFocusableItem != undefined){
lastContentFocusableItem.KeyNavigation.tab = mainWindow.firstButtonInBottomTab
}
} }
} }
@ -1209,11 +1240,16 @@ AbstractWindow {
} }
} }
// -----------------------------------------------------------------------------
// Bottom round buttons
// -----------------------------------------------------------------------------
RowLayout { RowLayout {
id: bottomButtonsLayout id: bottomButtonsLayout
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
spacing: Math.round(58 * DefaultStyle.dp) spacing: Math.round(58 * DefaultStyle.dp)
visible: middleItemStackView.currentItem.objectName == "inCallItem" visible: middleItemStackView.currentItem.objectName == "inCallItem"
property bool moreOptionsButtonVisibility: true
function refreshLayout() { function refreshLayout() {
if (mainWindow.callState === LinphoneEnums.CallState.Connected if (mainWindow.callState === LinphoneEnums.CallState.Connected
@ -1221,12 +1257,12 @@ AbstractWindow {
|| mainWindow.callState === LinphoneEnums.CallState.Paused || mainWindow.callState === LinphoneEnums.CallState.Paused
|| mainWindow.callState === LinphoneEnums.CallState.PausedByRemote) { || mainWindow.callState === LinphoneEnums.CallState.PausedByRemote) {
connectedCallButtons.visible = bottomButtonsLayout.visible connectedCallButtons.visible = bottomButtonsLayout.visible
moreOptionsButton.visible = bottomButtonsLayout.visible moreOptionsButtonVisibility = bottomButtonsLayout.visible
bottomButtonsLayout.layoutDirection = Qt.RightToLeft bottomButtonsLayout.layoutDirection = Qt.RightToLeft
} else if (mainWindow.callState === LinphoneEnums.CallState.OutgoingInit) { } else if (mainWindow.callState === LinphoneEnums.CallState.OutgoingInit) {
connectedCallButtons.visible = false connectedCallButtons.visible = false
bottomButtonsLayout.layoutDirection = Qt.LeftToRight bottomButtonsLayout.layoutDirection = Qt.LeftToRight
moreOptionsButton.visible = false moreOptionsButtonVisibility = false
} }
} }
@ -1244,35 +1280,40 @@ AbstractWindow {
children[i].enabled = false children[i].enabled = false
} }
} }
// End call button
BigButton { BigButton {
id: endCallButton
Layout.row: 0 Layout.row: 0
icon.width: Math.round(32 * DefaultStyle.dp) icon.width: Math.round(32 * DefaultStyle.dp)
icon.height: Math.round(32 * DefaultStyle.dp) icon.height: Math.round(32 * DefaultStyle.dp)
//: "Terminer l'appel" //: "Terminer l'appel"
ToolTip.text: qsTr("call_action_end_call") ToolTip.text: qsTr("call_action_end_call")
Accessible.name: qsTr("call_action_end_call")
Layout.preferredWidth: Math.round(75 * DefaultStyle.dp) Layout.preferredWidth: Math.round(75 * DefaultStyle.dp)
Layout.preferredHeight: Math.round(55 * DefaultStyle.dp) Layout.preferredHeight: Math.round(55 * DefaultStyle.dp)
radius: Math.round(71 * DefaultStyle.dp) radius: Math.round(71 * DefaultStyle.dp)
style: ButtonStyle.phoneRed style: ButtonStyle.phoneRedLightBorder
Layout.column: mainWindow.callState == LinphoneEnums.CallState.OutgoingInit Layout.column: mainWindow.startingCall ? 0 : bottomButtonsLayout.columns - 1
|| mainWindow.callState KeyNavigation.tab: mainWindow.startingCall ? (videoCameraButton.visible && videoCameraButton.enabled ? videoCameraButton : audioMicrophoneButton) : openStatisticPanelButton
== LinphoneEnums.CallState.OutgoingProgress KeyNavigation.backtab: mainWindow.startingCall ? rightPanel.visible ? Utils.getLastFocussableItemInItem(rightPanel) : nextItemInFocusChain(false): callListButton
|| mainWindow.callState
== LinphoneEnums.CallState.OutgoingRinging
|| mainWindow.callState
== LinphoneEnums.CallState.OutgoingEarlyMedia
|| mainWindow.callState == LinphoneEnums.CallState.IncomingReceived ? 0 : bottomButtonsLayout.columns - 1
onClicked: { onClicked: {
mainWindow.callTerminatedByUser = true mainWindow.callTerminatedByUser = true
mainWindow.endCall(mainWindow.call) mainWindow.endCall(mainWindow.call)
} }
} }
// -----------------------------------------------------------------------------
// Group button: pauseCall, transfertCall, newCall, callList
// -----------------------------------------------------------------------------
RowLayout { RowLayout {
id: connectedCallButtons id: connectedCallButtons
visible: false visible: false
Layout.row: 0 Layout.row: 0
Layout.column: 1 Layout.column: 1
spacing: Math.round(10 * DefaultStyle.dp) spacing: Math.round(10 * DefaultStyle.dp)
// Pause call button
CheckableButton { CheckableButton {
id: pauseButton id: pauseButton
Layout.preferredWidth: Math.round(55 * DefaultStyle.dp) Layout.preferredWidth: Math.round(55 * DefaultStyle.dp)
@ -1283,11 +1324,7 @@ AbstractWindow {
ToolTip.text: checked ? qsTr("call_action_resume_call") ToolTip.text: checked ? qsTr("call_action_resume_call")
//: "Mettre l'appel en pause" //: "Mettre l'appel en pause"
: qsTr("call_action_pause_call") : qsTr("call_action_pause_call")
background: Rectangle { Accessible.name: checked ? qsTr("call_action_resume_call") : qsTr("call_action_pause_call")
anchors.fill: parent
radius: Math.round(71 * DefaultStyle.dp)
color: parent.enabled ? parent.checked ? DefaultStyle.success_500main : parent.pressed || parent.hovered ? DefaultStyle.main2_400 : DefaultStyle.grey_500 : DefaultStyle.grey_600
}
enabled: mainWindow.conference enabled: mainWindow.conference
|| mainWindow.callState != LinphoneEnums.CallState.PausedByRemote || mainWindow.callState != LinphoneEnums.CallState.PausedByRemote
icon.source: enabled icon.source: enabled
@ -1298,11 +1335,17 @@ AbstractWindow {
|| (!mainWindow.conference || (!mainWindow.conference
&& mainWindow.callState && mainWindow.callState
== LinphoneEnums.CallState.PausedByRemote) == LinphoneEnums.CallState.PausedByRemote)
color: enabled ? DefaultStyle.grey_500 : DefaultStyle.grey_600
pressedColor: enabled ? DefaultStyle.success_500_main : DefaultStyle.grey_600
hoveredColor: enabled ? DefaultStyle.main2_400 : DefaultStyle.grey_600
onClicked: { onClicked: {
mainWindow.call.core.lSetPaused( mainWindow.call.core.lSetPaused(
!mainWindow.call.core.paused) !mainWindow.call.core.paused)
} }
KeyNavigation.backtab: moreOptionsButton
} }
// Transfert call button
CheckableButton { CheckableButton {
id: transferCallButton id: transferCallButton
visible: !mainWindow.conference visible: !mainWindow.conference
@ -1314,6 +1357,7 @@ AbstractWindow {
contentImageColor: DefaultStyle.grey_0 contentImageColor: DefaultStyle.grey_0
//: "Transférer l'appel" //: "Transférer l'appel"
ToolTip.text: qsTr("call_action_transfer_call") ToolTip.text: qsTr("call_action_transfer_call")
Accessible.name: qsTr("call_action_transfer_call")
onToggled: { onToggled: {
console.log("checked transfer changed", checked) console.log("checked transfer changed", checked)
if (checked) { if (checked) {
@ -1324,6 +1368,8 @@ AbstractWindow {
} }
} }
} }
// New call button
CheckableButton { CheckableButton {
id: newCallButton id: newCallButton
checkable: true checkable: true
@ -1334,6 +1380,7 @@ AbstractWindow {
icon.height: Math.round(32 * DefaultStyle.dp) icon.height: Math.round(32 * DefaultStyle.dp)
//: "Initier un nouvel appel" //: "Initier un nouvel appel"
ToolTip.text: qsTr("call_action_start_new_call_hint") ToolTip.text: qsTr("call_action_start_new_call_hint")
Accessible.name: qsTr("call_action_start_new_call_hint")
onToggled: { onToggled: {
console.log("checked newcall changed", checked) console.log("checked newcall changed", checked)
if (checked) { if (checked) {
@ -1344,6 +1391,8 @@ AbstractWindow {
} }
} }
} }
// Call list button
CheckableButton { CheckableButton {
id: callListButton id: callListButton
Layout.preferredWidth: Math.round(55 * DefaultStyle.dp) Layout.preferredWidth: Math.round(55 * DefaultStyle.dp)
@ -1354,6 +1403,7 @@ AbstractWindow {
icon.height: Math.round(32 * DefaultStyle.dp) icon.height: Math.round(32 * DefaultStyle.dp)
//: "Afficher la liste d'appels" //: "Afficher la liste d'appels"
ToolTip.text: qsTr("call_display_call_list_hint") ToolTip.text: qsTr("call_display_call_list_hint")
Accessible.name: qsTr("call_display_call_list_hint")
onToggled: { onToggled: {
if (checked) { if (checked) {
rightPanel.visible = true rightPanel.visible = true
@ -1362,19 +1412,20 @@ AbstractWindow {
rightPanel.visible = false rightPanel.visible = false
} }
} }
KeyNavigation.tab: mainWindow.startingCall ? nextItemInFocusChain() : endCallButton
} }
} }
// -----------------------------------------------------------------------------
// Group button: Video, audio, screensharing, chat, raiseHand, reaction, participantList, callOptions
// -----------------------------------------------------------------------------
RowLayout { RowLayout {
id: controlCallButtons
Layout.row: 0 Layout.row: 0
Layout.column: mainWindow.callState == LinphoneEnums.CallState.OutgoingInit Layout.column: mainWindow.startingCall ? bottomButtonsLayout.columns - 1 : 0
|| mainWindow.callState
== LinphoneEnums.CallState.OutgoingProgress
|| mainWindow.callState
== LinphoneEnums.CallState.OutgoingRinging
|| mainWindow.callState
== LinphoneEnums.CallState.OutgoingEarlyMedia
|| mainWindow.callState == LinphoneEnums.CallState.IncomingReceived ? bottomButtonsLayout.columns - 1 : 0
spacing: Math.round(10 * DefaultStyle.dp) spacing: Math.round(10 * DefaultStyle.dp)
// Video camera button
CheckableButton { CheckableButton {
id: videoCameraButton id: videoCameraButton
visible: SettingsCpp.videoEnabled visible: SettingsCpp.videoEnabled
@ -1387,6 +1438,7 @@ AbstractWindow {
//: "Désactiver la vidéo" //: "Désactiver la vidéo"
//: "Activer la vidéo" //: "Activer la vidéo"
ToolTip.text: mainWindow.localVideoEnabled ? qsTr("call_deactivate_video_hint") : qsTr("call_activate_video_hint") ToolTip.text: mainWindow.localVideoEnabled ? qsTr("call_deactivate_video_hint") : qsTr("call_activate_video_hint")
Accessible.name: mainWindow.localVideoEnabled ? qsTr("call_deactivate_video_hint") : qsTr("call_activate_video_hint")
checked: !mainWindow.localVideoEnabled checked: !mainWindow.localVideoEnabled
Layout.preferredWidth: Math.round(55 * DefaultStyle.dp) Layout.preferredWidth: Math.round(55 * DefaultStyle.dp)
Layout.preferredHeight: Math.round(55 * DefaultStyle.dp) Layout.preferredHeight: Math.round(55 * DefaultStyle.dp)
@ -1395,29 +1447,36 @@ AbstractWindow {
onClicked: mainWindow.call.core.lSetLocalVideoEnabled( onClicked: mainWindow.call.core.lSetLocalVideoEnabled(
!mainWindow.call.core.localVideoEnabled) !mainWindow.call.core.localVideoEnabled)
} }
// Audio microphone button
CheckableButton { CheckableButton {
id: audioMicrophoneButton
iconUrl: AppIcons.microphone iconUrl: AppIcons.microphone
checkedIconUrl: AppIcons.microphoneSlash
ToolTip.text: mainWindow.call && mainWindow.call.core.microphoneMuted ToolTip.text: mainWindow.call && mainWindow.call.core.microphoneMuted
//: "Activer le micro" //: "Activer le micro"
? qsTr("call_activate_microphone") ? qsTr("call_activate_microphone")
//: "Désactiver le micro" //: "Désactiver le micro"
: qsTr("call_deactivate_microphone") : qsTr("call_deactivate_microphone")
checkedIconUrl: AppIcons.microphoneSlash Accessible.name: mainWindow.call && mainWindow.call.core.microphoneMuted ? qsTr("call_activate_microphone") : qsTr("call_deactivate_microphone")
checked: mainWindow.call checked: mainWindow.call && mainWindow.call.core.microphoneMuted
&& mainWindow.call.core.microphoneMuted
Layout.preferredWidth: Math.round(55 * DefaultStyle.dp) Layout.preferredWidth: Math.round(55 * DefaultStyle.dp)
Layout.preferredHeight: Math.round(55 * DefaultStyle.dp) Layout.preferredHeight: Math.round(55 * DefaultStyle.dp)
icon.width: Math.round(32 * DefaultStyle.dp) icon.width: Math.round(32 * DefaultStyle.dp)
icon.height: Math.round(32 * DefaultStyle.dp) icon.height: Math.round(32 * DefaultStyle.dp)
onClicked: mainWindow.call.core.lSetMicrophoneMuted( onClicked: mainWindow.call.core.lSetMicrophoneMuted(
!mainWindow.call.core.microphoneMuted) !mainWindow.call.core.microphoneMuted)
KeyNavigation.backtab: videoCameraButton.visible && videoCameraButton.enabled ? videoCameraButton : nextItemInFocusChain(false)
} }
// Screen cast button
CheckableButton { CheckableButton {
id: screencastPanelButton id: screencastPanelButton
iconUrl: AppIcons.screencast iconUrl: AppIcons.screencast
visible: !!mainWindow.conference visible: !!mainWindow.conference
//: Partager l'écran //: Partager l'écran
ToolTip.text: qsTr("call_share_screen_hint") ToolTip.text: qsTr("call_share_screen_hint")
Accessible.name: qsTr("call_share_screen_hint")
Layout.preferredWidth: Math.round(55 * DefaultStyle.dp) Layout.preferredWidth: Math.round(55 * DefaultStyle.dp)
Layout.preferredHeight: Math.round(55 * DefaultStyle.dp) Layout.preferredHeight: Math.round(55 * DefaultStyle.dp)
icon.width: Math.round(32 * DefaultStyle.dp) icon.width: Math.round(32 * DefaultStyle.dp)
@ -1431,11 +1490,14 @@ AbstractWindow {
} }
} }
} }
// Chat panel button
CheckableButton { CheckableButton {
id: chatPanelButton id: chatPanelButton
iconUrl: AppIcons.chatTeardropText iconUrl: AppIcons.chatTeardropText
//: Open chat //: Open chat
ToolTip.text: qsTr("call_open_chat_hint") ToolTip.text: qsTr("call_open_chat_hint")
Accessible.name: qsTr("call_open_chat_hint")
Layout.preferredWidth: Math.round(55 * DefaultStyle.dp) Layout.preferredWidth: Math.round(55 * DefaultStyle.dp)
Layout.preferredHeight: Math.round(55 * DefaultStyle.dp) Layout.preferredHeight: Math.round(55 * DefaultStyle.dp)
icon.width: Math.round(32 * DefaultStyle.dp) icon.width: Math.round(32 * DefaultStyle.dp)
@ -1449,31 +1511,42 @@ AbstractWindow {
} }
} }
} }
// Raise hand button
CheckableButton { CheckableButton {
id: raiseHandButton
visible: false visible: false
checkable: false checkable: false
iconUrl: AppIcons.handWaving iconUrl: AppIcons.handWaving
//: "Lever la main" //: "Lever la main"
ToolTip.text: qsTr("call_rise_hand_hint") ToolTip.text: qsTr("call_rise_hand_hint")
Accessible.name: qsTr("call_rise_hand_hint")
Layout.preferredWidth: Math.round(55 * DefaultStyle.dp) Layout.preferredWidth: Math.round(55 * DefaultStyle.dp)
Layout.preferredHeight: Math.round(55 * DefaultStyle.dp) Layout.preferredHeight: Math.round(55 * DefaultStyle.dp)
icon.width: Math.round(32 * DefaultStyle.dp) icon.width: Math.round(32 * DefaultStyle.dp)
icon.height: Math.round(32 * DefaultStyle.dp) icon.height: Math.round(32 * DefaultStyle.dp)
} }
// Reaction button
CheckableButton { CheckableButton {
id: reactionButton
visible: false visible: false
iconUrl: AppIcons.smiley iconUrl: AppIcons.smiley
//: "Envoyer une réaction" //: "Envoyer une réaction"
ToolTip.text: qsTr("call_send_reaction_hint") ToolTip.text: qsTr("call_send_reaction_hint")
Accessible.name: qsTr("call_send_reaction_hint")
Layout.preferredWidth: Math.round(55 * DefaultStyle.dp) Layout.preferredWidth: Math.round(55 * DefaultStyle.dp)
Layout.preferredHeight: Math.round(55 * DefaultStyle.dp) Layout.preferredHeight: Math.round(55 * DefaultStyle.dp)
icon.width: Math.round(32 * DefaultStyle.dp) icon.width: Math.round(32 * DefaultStyle.dp)
icon.height: Math.round(32 * DefaultStyle.dp) icon.height: Math.round(32 * DefaultStyle.dp)
} }
// Participant list button
CheckableButton { CheckableButton {
id: participantListButton id: participantListButton
//: "Gérer les participants" //: "Gérer les participants"
ToolTip.text: qsTr("call_manage_participants_hint") ToolTip.text: qsTr("call_manage_participants_hint")
Accessible.name: qsTr("call_manage_participants_hint")
visible: mainWindow.conference visible: mainWindow.conference
iconUrl: AppIcons.usersTwo iconUrl: AppIcons.usersTwo
Layout.preferredWidth: Math.round(55 * DefaultStyle.dp) Layout.preferredWidth: Math.round(55 * DefaultStyle.dp)
@ -1489,12 +1562,15 @@ AbstractWindow {
} }
} }
} }
// More option button
PopupButton { PopupButton {
id: moreOptionsButton id: moreOptionsButton
//: "Plus d'options" //: "Plus d'options"
ToolTip.text: qsTr("call_more_options_hint") ToolTip.text: qsTr("call_more_options_hint")
Layout.preferredWidth: Math.round(55 * DefaultStyle.dp) popUpTitle: qsTr("call_more_options_hint")
Layout.preferredHeight: Math.round(55 * DefaultStyle.dp) implicitWidth: Math.round(55 * DefaultStyle.dp)
implicitHeight: Math.round(55 * DefaultStyle.dp)
popup.topPadding: Math.round(20 * DefaultStyle.dp) popup.topPadding: Math.round(20 * DefaultStyle.dp)
popup.bottomPadding: Math.round(20 * DefaultStyle.dp) popup.bottomPadding: Math.round(20 * DefaultStyle.dp)
popup.leftPadding: Math.round(10 * DefaultStyle.dp) popup.leftPadding: Math.round(10 * DefaultStyle.dp)
@ -1502,6 +1578,8 @@ AbstractWindow {
style: ButtonStyle.checkable style: ButtonStyle.checkable
icon.width: Math.round(32 * DefaultStyle.dp) icon.width: Math.round(32 * DefaultStyle.dp)
icon.height: Math.round(32 * DefaultStyle.dp) icon.height: Math.round(32 * DefaultStyle.dp)
KeyNavigation.tab: connectedCallButtons.visible ? pauseButton : nextItemInFocusChain()
visible: bottomButtonsLayout.moreOptionsButtonVisibility
Connections { Connections {
target: moreOptionsButton.popup target: moreOptionsButton.popup
@ -1528,6 +1606,8 @@ AbstractWindow {
rightPanel.replace(changeLayoutPanel) rightPanel.replace(changeLayoutPanel)
moreOptionsButton.close() moreOptionsButton.close()
} }
KeyNavigation.up: visibleChildren.length != 0 ? moreOptionsButton.getPreviousItem(0) : null
KeyNavigation.down: visibleChildren.length != 0 ? moreOptionsButton.getNextItem(0) : null
} }
IconLabelButton { IconLabelButton {
Layout.fillWidth: true Layout.fillWidth: true
@ -1549,6 +1629,8 @@ AbstractWindow {
} }
moreOptionsButton.close() moreOptionsButton.close()
} }
KeyNavigation.up: visibleChildren.length != 0 ? moreOptionsButton.getPreviousItem(1) : null
KeyNavigation.down: visibleChildren.length != 0 ? moreOptionsButton.getNextItem(1) : null
} }
IconLabelButton { IconLabelButton {
Layout.fillWidth: true Layout.fillWidth: true
@ -1562,6 +1644,8 @@ AbstractWindow {
rightPanel.replace(dialerPanel) rightPanel.replace(dialerPanel)
moreOptionsButton.close() moreOptionsButton.close()
} }
KeyNavigation.up: visibleChildren.length != 0 ? moreOptionsButton.getPreviousItem(2) : null
KeyNavigation.down: visibleChildren.length != 0 ? moreOptionsButton.getNextItem(2) : null
} }
IconLabelButton { IconLabelButton {
Layout.fillWidth: true Layout.fillWidth: true
@ -1579,14 +1663,14 @@ AbstractWindow {
&& mainWindow.call.core.recording && mainWindow.call.core.recording
hoveredImageColor: contentImageColor hoveredImageColor: contentImageColor
contentImageColor: mainWindow.call contentImageColor: mainWindow.call
&& mainWindow.call.core.recording ? DefaultStyle.danger_500main : DefaultStyle.main2_500main && mainWindow.call.core.recording ? DefaultStyle.danger_500_main : DefaultStyle.main2_500_main
text: mainWindow.call && mainWindow.call.core.recording text: mainWindow.call && mainWindow.call.core.recording
//: "Terminer l'enregistrement" //: "Terminer l'enregistrement"
? qsTr("call_action_stop_recording") ? qsTr("call_action_stop_recording")
//: "Enregistrer l'appel" //: "Enregistrer l'appel"
: qsTr("call_action_record") : qsTr("call_action_record")
textColor: mainWindow.call textColor: mainWindow.call
&& mainWindow.call.core.recording ? DefaultStyle.danger_500main : DefaultStyle.main2_500main && mainWindow.call.core.recording ? DefaultStyle.danger_500_main : DefaultStyle.main2_500_main
hoveredTextColor: textColor hoveredTextColor: textColor
onToggled: { onToggled: {
if (mainWindow.call) if (mainWindow.call)
@ -1596,6 +1680,8 @@ AbstractWindow {
else else
mainWindow.call.core.lStartRecording() mainWindow.call.core.lStartRecording()
} }
KeyNavigation.up: visibleChildren.length != 0 ? moreOptionsButton.getPreviousItem(3) : null
KeyNavigation.down: visibleChildren.length != 0 ? moreOptionsButton.getNextItem(3) : null
} }
IconLabelButton { IconLabelButton {
Layout.fillWidth: true Layout.fillWidth: true
@ -1606,7 +1692,7 @@ AbstractWindow {
icon.source: !mainWindow.call icon.source: !mainWindow.call
|| mainWindow.call.core.speakerMuted ? AppIcons.speakerSlash : AppIcons.speaker || mainWindow.call.core.speakerMuted ? AppIcons.speakerSlash : AppIcons.speaker
contentImageColor: mainWindow.call contentImageColor: mainWindow.call
&& mainWindow.call.core.speakerMuted ? DefaultStyle.danger_500main : DefaultStyle.main2_500main && mainWindow.call.core.speakerMuted ? DefaultStyle.danger_500_main : DefaultStyle.main2_500_main
hoveredImageColor: contentImageColor hoveredImageColor: contentImageColor
text: mainWindow.call && mainWindow.call.core.speakerMuted text: mainWindow.call && mainWindow.call.core.speakerMuted
//: "Activer le son" //: "Activer le son"
@ -1614,13 +1700,15 @@ AbstractWindow {
//: "Désactiver le son" //: "Désactiver le son"
: qsTr("call_deactivate_speaker_hint") : qsTr("call_deactivate_speaker_hint")
textColor: mainWindow.call textColor: mainWindow.call
&& mainWindow.call.core.speakerMuted ? DefaultStyle.danger_500main : DefaultStyle.main2_500main && mainWindow.call.core.speakerMuted ? DefaultStyle.danger_500_main : DefaultStyle.main2_500_main
hoveredTextColor: textColor hoveredTextColor: textColor
onCheckedChanged: { onCheckedChanged: {
if (mainWindow.call) if (mainWindow.call)
mainWindow.call.core.lSetSpeakerMuted( mainWindow.call.core.lSetSpeakerMuted(
!mainWindow.call.core.speakerMuted) !mainWindow.call.core.speakerMuted)
} }
KeyNavigation.up: visibleChildren.length != 0 ? moreOptionsButton.getPreviousItem(4) : null
KeyNavigation.down: visibleChildren.length != 0 ? moreOptionsButton.getNextItem(4) : null
} }
IconLabelButton { IconLabelButton {
Layout.fillWidth: true Layout.fillWidth: true
@ -1635,6 +1723,8 @@ AbstractWindow {
rightPanel.replace(settingsPanel) rightPanel.replace(settingsPanel)
moreOptionsButton.close() moreOptionsButton.close()
} }
KeyNavigation.up: visibleChildren.length != 0 ? moreOptionsButton.getPreviousItem(5) : null
KeyNavigation.down: visibleChildren.length != 0 ? moreOptionsButton.getNextItem(5) : null
} }
} }
} }

View file

@ -116,6 +116,7 @@ AbstractWindow {
console.log("Showing authentication dialog") console.log("Showing authentication dialog")
var popup = authenticationPopupComp.createObject(mainWindow, {"identity": identity, "domain": domain, "callback":callback}) // Callback ownership is not passed var popup = authenticationPopupComp.createObject(mainWindow, {"identity": identity, "domain": domain, "callback":callback}) // Callback ownership is not passed
popup.open() popup.open()
popup.announce()
} }
Connections { Connections {

View file

@ -15,12 +15,12 @@ QtObject {
property color main1_600: currentTheme.main600 property color main1_600: currentTheme.main600
property color main1_700: currentTheme.main700 property color main1_700: currentTheme.main700
property color main2_0: "#FAFEFF" property color main2_000: "#FAFEFF"
property color main2_100: "#EEF6F8" property color main2_100: "#EEF6F8"
property color main2_200: "#DFECF2" property color main2_200: "#DFECF2"
property color main2_300: "#C0D1D9" property color main2_300: "#C0D1D9"
property color main2_400: "#9AABB5" property color main2_400: "#9AABB5"
property color main2_500main: "#6C7A87" property color main2_500_main: "#6C7A87"
property color main2_600: "#4E6074" property color main2_600: "#4E6074"
property color main2_700: "#364860" property color main2_700: "#364860"
property color main2_800: "#22334D" property color main2_800: "#22334D"
@ -38,11 +38,11 @@ QtObject {
property color grey_1000: "#000000" property color grey_1000: "#000000"
property color warning_600: "#DBB820" property color warning_600: "#DBB820"
property color danger_500main: "#DD5F5F" property color danger_500_main: "#DD5F5F"
property color warning_500_main: "#FFDC2E" property color warning_500_main: "#FFDC2E"
property color danger_700: "#9E3548" property color danger_700: "#9E3548"
property color danger_900: "#723333" property color danger_900: "#723333"
property color success_500main: "#4FAE80" property color success_500_main: "#4FAE80"
property color success_700: "#377d71" property color success_700: "#377d71"
property color success_900: "#1E4C53" property color success_900: "#1E4C53"
property color info_500_main: "#4AA8FF" property color info_500_main: "#4AA8FF"

View file

@ -19,6 +19,11 @@
pressed: Linphone.DefaultStyle.grey_0 pressed: Linphone.DefaultStyle.grey_0
} }
} }
var mainLightBorder = Object.assign({
borderColor : {
keybaordFocused: Linphone.DefaultStyle.main2_000
}
}, main)
// White with orange border // White with orange border
var secondary = { var secondary = {
@ -27,7 +32,10 @@
hovered: Linphone.DefaultStyle.main1_100, hovered: Linphone.DefaultStyle.main1_100,
pressed: Linphone.DefaultStyle.main1_500_main pressed: Linphone.DefaultStyle.main1_500_main
}, },
borderColor: Linphone.DefaultStyle.main1_500_main, borderColor: {
normal: Linphone.DefaultStyle.main1_500_main,
keybaordFocused: Linphone.DefaultStyle.main2_900
},
text: { text: {
normal: Linphone.DefaultStyle.main1_500_main, normal: Linphone.DefaultStyle.main1_500_main,
pressed: Linphone.DefaultStyle.grey_0 pressed: Linphone.DefaultStyle.grey_0
@ -80,11 +88,11 @@
pressed: Linphone.DefaultStyle.main2_400 pressed: Linphone.DefaultStyle.main2_400
}, },
text: { text: {
normal: Linphone.DefaultStyle.main2_500main, normal: Linphone.DefaultStyle.main2_500_main,
pressed: Linphone.DefaultStyle.main2_700 pressed: Linphone.DefaultStyle.main2_700
}, },
image: { image: {
normal: Linphone.DefaultStyle.main2_500main, normal: Linphone.DefaultStyle.main2_500_main,
pressed: Linphone.DefaultStyle.main2_700 pressed: Linphone.DefaultStyle.main2_700
} }
} }
@ -93,7 +101,7 @@
var phoneRed = { var phoneRed = {
iconSource: Linphone.AppIcons.endCall, iconSource: Linphone.AppIcons.endCall,
color: { color: {
normal: Linphone.DefaultStyle.danger_500main, normal: Linphone.DefaultStyle.danger_500_main,
hovered: Linphone.DefaultStyle.danger_700, hovered: Linphone.DefaultStyle.danger_700,
pressed: Linphone.DefaultStyle.danger_900 pressed: Linphone.DefaultStyle.danger_900
}, },
@ -106,12 +114,17 @@
pressed: Linphone.DefaultStyle.grey_0 pressed: Linphone.DefaultStyle.grey_0
} }
} }
var phoneRedLightBorder = Object.assign({
borderColor : {
keybaordFocused: Linphone.DefaultStyle.main2_000
}
}, phoneRed)
// Green phone // Green phone
var phoneGreen = { var phoneGreen = {
iconSource: Linphone.AppIcons.phone, iconSource: Linphone.AppIcons.phone,
color: { color: {
normal: Linphone.DefaultStyle.success_500main, normal: Linphone.DefaultStyle.success_500_main,
hovered: Linphone.DefaultStyle.success_700, hovered: Linphone.DefaultStyle.success_700,
pressed: Linphone.DefaultStyle.success_900 pressed: Linphone.DefaultStyle.success_900
}, },
@ -137,6 +150,9 @@
normal: Linphone.DefaultStyle.grey_0, normal: Linphone.DefaultStyle.grey_0,
pressed: Linphone.DefaultStyle.grey_0 pressed: Linphone.DefaultStyle.grey_0
}, },
borderColor: {
keybaordFocused: Linphone.DefaultStyle.main2_000
},
image: { image: {
normal: Linphone.DefaultStyle.grey_0, normal: Linphone.DefaultStyle.grey_0,
pressed: Linphone.DefaultStyle.grey_0, pressed: Linphone.DefaultStyle.grey_0,
@ -156,13 +172,13 @@
normal: Linphone.DefaultStyle.main2_200, normal: Linphone.DefaultStyle.main2_200,
hovered: Linphone.DefaultStyle.main2_300, hovered: Linphone.DefaultStyle.main2_300,
pressed: Linphone.DefaultStyle.main2_400, pressed: Linphone.DefaultStyle.main2_400,
checked: Linphone.DefaultStyle.main1_500main checked: Linphone.DefaultStyle.main1_500_main
}, },
image: { image: {
normal: Linphone.DefaultStyle.main2_200, normal: Linphone.DefaultStyle.main2_200,
hovered: Linphone.DefaultStyle.main2_300, hovered: Linphone.DefaultStyle.main2_300,
pressed: Linphone.DefaultStyle.main2_400, pressed: Linphone.DefaultStyle.main2_400,
checked: Linphone.DefaultStyle.main1_500main, checked: Linphone.DefaultStyle.main1_500_main,
} }
} }
@ -178,15 +194,20 @@
normal: Linphone.DefaultStyle.main2_600, normal: Linphone.DefaultStyle.main2_600,
hovered: Linphone.DefaultStyle.main2_700, hovered: Linphone.DefaultStyle.main2_700,
pressed: Linphone.DefaultStyle.main2_800, pressed: Linphone.DefaultStyle.main2_800,
checked: Linphone.DefaultStyle.main1_500main checked: Linphone.DefaultStyle.main1_500_main
}, },
image: { image: {
normal: Linphone.DefaultStyle.main2_600, normal: Linphone.DefaultStyle.main2_600,
hovered: Linphone.DefaultStyle.main2_700, hovered: Linphone.DefaultStyle.main2_700,
pressed: Linphone.DefaultStyle.main2_800, pressed: Linphone.DefaultStyle.main2_800,
checked: Linphone.DefaultStyle.main1_500main, checked: Linphone.DefaultStyle.main1_500_main,
} }
} }
var noBackgroundLightBorder = Object.assign({
borderColor : {
keybaordFocused: Linphone.DefaultStyle.main2_000
}
}, noBackground)
// No background red // No background red
var noBackgroundRed = { var noBackgroundRed = {
@ -196,12 +217,12 @@
pressed: "#00000000" pressed: "#00000000"
}, },
text: { text: {
normal: Linphone.DefaultStyle.danger_500main, normal: Linphone.DefaultStyle.danger_500_main,
hovered: Linphone.DefaultStyle.danger_700, hovered: Linphone.DefaultStyle.danger_700,
pressed: Linphone.DefaultStyle.danger_900 pressed: Linphone.DefaultStyle.danger_900
}, },
image: { image: {
normal: Linphone.DefaultStyle.danger_500main, normal: Linphone.DefaultStyle.danger_500_main,
hovered: Linphone.DefaultStyle.danger_700, hovered: Linphone.DefaultStyle.danger_700,
pressed: Linphone.DefaultStyle.danger_900, pressed: Linphone.DefaultStyle.danger_900,
checked: Linphone.DefaultStyle.danger_900 checked: Linphone.DefaultStyle.danger_900
@ -254,14 +275,14 @@
pressed: Linphone.DefaultStyle.main2_100 pressed: Linphone.DefaultStyle.main2_100
}, },
text: { text: {
normal: Linphone.DefaultStyle.main2_500main, normal: Linphone.DefaultStyle.main2_500_main,
hovered: Linphone.DefaultStyle.main2_500main, hovered: Linphone.DefaultStyle.main2_500_main,
pressed: Linphone.DefaultStyle.main2_500main pressed: Linphone.DefaultStyle.main2_500_main
}, },
image: { image: {
normal: Linphone.DefaultStyle.main2_500main, normal: Linphone.DefaultStyle.main2_500_main,
hovered: Linphone.DefaultStyle.main2_500main, hovered: Linphone.DefaultStyle.main2_500_main,
pressed: Linphone.DefaultStyle.main2_500main pressed: Linphone.DefaultStyle.main2_500_main
} }
} }
@ -273,12 +294,12 @@
pressed: Linphone.DefaultStyle.main2_100 pressed: Linphone.DefaultStyle.main2_100
}, },
text: { text: {
normal: Linphone.DefaultStyle.danger_500main, normal: Linphone.DefaultStyle.danger_500_main,
hovered: Linphone.DefaultStyle.danger_700, hovered: Linphone.DefaultStyle.danger_700,
pressed: Linphone.DefaultStyle.danger_900 pressed: Linphone.DefaultStyle.danger_900
}, },
image: { image: {
normal: Linphone.DefaultStyle.danger_500main, normal: Linphone.DefaultStyle.danger_500_main,
hovered: Linphone.DefaultStyle.danger_700, hovered: Linphone.DefaultStyle.danger_700,
pressed: Linphone.DefaultStyle.danger_900 pressed: Linphone.DefaultStyle.danger_900
} }
@ -304,9 +325,12 @@
hovered: Linphone.DefaultStyle.grey_0, hovered: Linphone.DefaultStyle.grey_0,
pressed: Linphone.DefaultStyle.grey_0 pressed: Linphone.DefaultStyle.grey_0
}, },
borderColor: Linphone.DefaultStyle.success_500main, borderColor: {
normal: Linphone.DefaultStyle.success_500_main,
keybaordFocused: Linphone.DefaultStyle.main2_900
},
text: { text: {
normal: Linphone.DefaultStyle.success_500main, normal: Linphone.DefaultStyle.success_500_main,
pressed: Linphone.DefaultStyle.success_700 pressed: Linphone.DefaultStyle.success_700
} }
} }
@ -318,7 +342,10 @@
hovered: Linphone.DefaultStyle.grey_0, hovered: Linphone.DefaultStyle.grey_0,
pressed: Linphone.DefaultStyle.grey_0 pressed: Linphone.DefaultStyle.grey_0
}, },
borderColor: Linphone.DefaultStyle.info_500_main, borderColor: {
normal: Linphone.DefaultStyle.info_500_main,
keybaordFocused: Linphone.DefaultStyle.main2_900
},
text: { text: {
normal: Linphone.DefaultStyle.info_500_main, normal: Linphone.DefaultStyle.info_500_main,
pressed: Linphone.DefaultStyle.info_500_main pressed: Linphone.DefaultStyle.info_500_main
@ -332,9 +359,32 @@
hovered: Linphone.DefaultStyle.grey_0, hovered: Linphone.DefaultStyle.grey_0,
pressed: Linphone.DefaultStyle.grey_0 pressed: Linphone.DefaultStyle.grey_0
}, },
borderColor: Linphone.DefaultStyle.danger_500main, borderColor: {
normal: Linphone.DefaultStyle.danger_500_main,
keybaordFocused: Linphone.DefaultStyle.main2_900
},
text: { text: {
normal: Linphone.DefaultStyle.danger_500main, normal: Linphone.DefaultStyle.danger_500_main,
pressed: Linphone.DefaultStyle.danger_500main pressed: Linphone.DefaultStyle.danger_500_main
}
}
// White selected
var whiteSelected = {
color: {
normal: Linphone.DefaultStyle.grey_0,
hovered: Linphone.DefaultStyle.main2_100,
selected: Linphone.DefaultStyle.grey_200,
},
borderColor: {
keybaordFocused: Linphone.DefaultStyle.main2_900
}
}
var hoveredBackgroundBis = {
color: {
normal: "#00000000",
hovered: Linphone.DefaultStyle.main2_100,
pressed: Linphone.DefaultStyle.main2_100
} }
} }

View file

@ -327,6 +327,30 @@ Please note that we don't offer free support and these contributions will be add
- external : external projects. - external : external projects.
- linphone-sdk - linphone-sdk
#### Add new text/label
For each text/label that you want to put in the application, you need to follow thoses steps:
1. In you code, add the label like this :
```qml
//: "Trad in english"
qsTr("variable_name")
```
2. Build the application with the target `update_translations`
3. In the translation files on `Linphone/data/languages/*.ts`, modify all translations that you can. They have been generated with `<translation type="unfinished"></translation>`
```xml
<message>
<location filename="xxx.qml" line="xxx"/>
<source>variable_name</source>
<extracomment>&quot;Trad in english&quot;</extracomment>
<translation>My Translation</translation>
</message>
```
4. Build again the application with the target `release_translations`
### Languages ### Languages
<a href="https://weblate.linphone.org/engage/linphone/"> <a href="https://weblate.linphone.org/engage/linphone/">