Skip to content
Snippets Groups Projects
Commit e073c6f8 authored by Sébastien Blin's avatar Sébastien Blin Committed by Aline Gondim Santos
Browse files

i18n: support RTL languages

This patch introduces some mechanisms to fully support RTL languages:
1. RTL detection via UtilsAdapter::isRTL() checking the locale name
2. Using QML mirroring when needed based on UtilsAdapter.isRTL
3. Inverting panels in DualPaneView and JamiListView when needed
with SinglePane support

Moreover, lot of anchors are added to automatically manage layout
updates.

GitLab: #235
Change-Id: I40c245f2d7fae96d796c53505af5403f5e813e7f
parent 44d807e6
No related branches found
No related tags found
No related merge requests found
Showing
with 99 additions and 29 deletions
...@@ -37,6 +37,11 @@ import "commoncomponents" ...@@ -37,6 +37,11 @@ import "commoncomponents"
ApplicationWindow { ApplicationWindow {
id: root id: root
property bool isRTL: UtilsAdapter.isRTL
LayoutMirroring.enabled: isRTL
LayoutMirroring.childrenInherit: isRTL
enum LoadedSource { enum LoadedSource {
WizardView, WizardView,
MainView, MainView,
......
...@@ -31,6 +31,8 @@ PushButton { ...@@ -31,6 +31,8 @@ PushButton {
preferredHeight: JamiTheme.wizardViewPageBackButtonHeight preferredHeight: JamiTheme.wizardViewPageBackButtonHeight
hoveredColor: JamiTheme.hoveredButtonColorWizard hoveredColor: JamiTheme.hoveredButtonColorWizard
mirror: Qt.application.layoutDirection === Qt.RightToLeft
source: JamiResources.ic_arrow_back_24dp_svg source: JamiResources.ic_arrow_back_24dp_svg
toolTipText: JamiStrings.back toolTipText: JamiStrings.back
......
...@@ -30,8 +30,11 @@ BaseView { ...@@ -30,8 +30,11 @@ BaseView {
property alias splitViewStateKey: splitView.splitViewStateKey property alias splitViewStateKey: splitView.splitViewStateKey
property real leftPaneMinWidth: JamiTheme.mainViewLeftPaneMinWidth property real minorPaneMinWidth: JamiTheme.mainViewLeftPaneMinWidth
property real rightPaneMinWidth: JamiTheme.mainViewPaneMinWidth property real majorPaneMinWidth: JamiTheme.mainViewPaneMinWidth
property real previousMinorPaneWidth: leftPane.width
property real previousMajorPaneWidth: rightPane.width
property bool isSinglePane property bool isSinglePane
...@@ -50,10 +53,9 @@ BaseView { ...@@ -50,10 +53,9 @@ BaseView {
onIsSinglePaneChanged.connect(isSinglePaneChangedHandler); onIsSinglePaneChanged.connect(isSinglePaneChangedHandler);
} }
property real previousLeftPaneWidth: leftPane.width
onWidthChanged: resolvePanes() onWidthChanged: resolvePanes()
function resolvePanes() { function resolvePanes() {
isSinglePane = width < rightPaneMinWidth + previousLeftPaneWidth; isSinglePane = width < majorPaneMinWidth + previousMinorPaneWidth;
} }
// Override this if needed. // Override this if needed.
...@@ -65,19 +67,27 @@ BaseView { ...@@ -65,19 +67,27 @@ BaseView {
id: splitView id: splitView
anchors.fill: parent anchors.fill: parent
splitViewStateKey: viewNode.objectName splitViewStateKey: viewNode.objectName
isSinglePane: viewNode.isSinglePane
Item { SplitPane {
id: leftPane id: leftPane
onWidthChanged: if (!isSinglePane) isMinorPane: true
previousLeftPaneWidth = width
SplitView.minimumWidth: isSinglePane ? viewNode.width : viewNode.leftPaneMinWidth
SplitView.maximumWidth: isSinglePane ? viewNode.width : viewNode.width - rightPaneMinWidth
SplitView.preferredWidth: viewNode.leftPaneMinWidth
clip: true
} }
Item { SplitPane {
id: rightPane id: rightPane
clip: true isMinorPane: false
}
}
component SplitPane: Item {
clip: true
required property bool isMinorPane
onWidthChanged: {
if (!isSinglePane && isMinorPane)
previousMinorPaneWidth = width;
} }
SplitView.minimumWidth: isSinglePane ? viewNode.width : (isMinorPane ? minorPaneMinWidth : majorPaneMinWidth)
SplitView.maximumWidth: isSinglePane ? viewNode.width : viewNode.width - (isMinorPane ? majorPaneMinWidth : minorPaneMinWidth)
SplitView.preferredWidth: isMinorPane ? minorPaneMinWidth : majorPaneMinWidth
} }
} }
...@@ -22,6 +22,13 @@ import net.jami.Constants 1.1 ...@@ -22,6 +22,13 @@ import net.jami.Constants 1.1
SplitView { SplitView {
id: root id: root
property bool isRTL: UtilsAdapter.isRTL
property bool isSinglePane: false
property bool isSwapped: UtilsAdapter.isRTL
onIsRTLChanged: swapItems()
onIsSinglePaneChanged: swapItems()
property string splitViewStateKey: objectName property string splitViewStateKey: objectName
property bool autoManageState: !(parent instanceof BaseView) property bool autoManageState: !(parent instanceof BaseView)
...@@ -41,11 +48,26 @@ SplitView { ...@@ -41,11 +48,26 @@ SplitView {
visible ? restoreSplitViewState() : saveSplitViewState(); visible ? restoreSplitViewState() : saveSplitViewState();
} }
function swapItems() {
if ((isSinglePane && !isSwapped) // Do not swap in isSinglePane mode
|| (!isRTL && !isSwapped)) // Do not swap if not RTL
return;
var qqci = children[0];
if (qqci.children.length > 1) {
// swap the children
var tempPane = qqci.children[0];
qqci.children[0] = qqci.children[1];
qqci.children.push(tempPane);
isSwapped = true
}
}
handle: Rectangle { handle: Rectangle {
implicitWidth: JamiTheme.splitViewHandlePreferredWidth implicitWidth: JamiTheme.splitViewHandlePreferredWidth
implicitHeight: root.height implicitHeight: root.height
color: JamiTheme.primaryBackgroundColor color: JamiTheme.primaryBackgroundColor
Rectangle { Rectangle {
anchors.left: parent.left
implicitWidth: 1 implicitWidth: 1
implicitHeight: root.height implicitHeight: root.height
color: JamiTheme.tabbarBorderColor color: JamiTheme.tabbarBorderColor
......
...@@ -72,8 +72,10 @@ RadioButton { ...@@ -72,8 +72,10 @@ RadioButton {
contentItem: Text { contentItem: Text {
text: root.text text: root.text
color: root.color color: root.color
leftPadding: root.indicator.width + root.spacing anchors.left: rect.right
anchors.leftMargin: root.spacing
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignLeft
font.pixelSize: JamiTheme.settingsDescriptionPixelSize font.pixelSize: JamiTheme.settingsDescriptionPixelSize
} }
......
...@@ -74,6 +74,8 @@ AbstractButton { ...@@ -74,6 +74,8 @@ AbstractButton {
property alias imagePadding: image.padding property alias imagePadding: image.padding
property alias imageOffset: image.offset property alias imageOffset: image.offset
property alias mirror: image.mirror
width: preferredWidth ? preferredWidth : preferredSize width: preferredWidth ? preferredWidth : preferredSize
height: preferredHeight ? preferredHeight : preferredSize height: preferredHeight ? preferredHeight : preferredSize
......
...@@ -32,6 +32,7 @@ Item { ...@@ -32,6 +32,7 @@ Item {
property alias source: image.source property alias source: image.source
property alias status: image.status property alias status: image.status
property alias cache: image.cache property alias cache: image.cache
property alias mirror: image.mirror
property string color: "transparent" property string color: "transparent"
property bool hovered: false property bool hovered: false
property bool mirrorHorizontally: false property bool mirrorHorizontally: false
...@@ -67,8 +68,6 @@ Item { ...@@ -67,8 +68,6 @@ Item {
antialiasing: true antialiasing: true
asynchronous: true asynchronous: true
visible: false visible: false
mirror: root.mirrorHorizontally
mirrorVertically: root.mirrorVertically
function setSourceSize() { function setSourceSize() {
sourceSize = undefined; sourceSize = undefined;
......
...@@ -85,7 +85,12 @@ ComboBox { ...@@ -85,7 +85,12 @@ ComboBox {
} }
contentItem: Text { contentItem: Text {
leftPadding: root.indicator.width
anchors.left: parent.left
anchors.right: parent.right
anchors.leftMargin: root.indicator.width
width: parent.width - root.indicator.width * 2
anchors.rightMargin: root.indicator.width * 2
font.pixelSize: JamiTheme.settingsDescriptionPixelSize font.pixelSize: JamiTheme.settingsDescriptionPixelSize
text: root.displayText text: root.displayText
color: JamiTheme.comboboxTextColor color: JamiTheme.comboboxTextColor
......
...@@ -455,9 +455,8 @@ Item { ...@@ -455,9 +455,8 @@ Item {
property real typingDotsSize: 8 property real typingDotsSize: 8
// MessageWebView File Transfer Container // MessageWebView File Transfer Container
property real filesToSendContainerSpacing: 120 property real filesToSendContainerSpacing: 25
property real filesToSendContainerPadding: 10 property real filesToSendContainerPadding: 10
property real filesToSendDelegateWidth: 100
property real filesToSendDelegateHeight: 100 property real filesToSendDelegateHeight: 100
property real filesToSendDelegateRadius: 7 property real filesToSendDelegateRadius: 7
property real filesToSendDelegateButtonSize: 16 property real filesToSendDelegateButtonSize: 16
......
...@@ -139,6 +139,7 @@ Label { ...@@ -139,6 +139,7 @@ Label {
font.pointSize: JamiTheme.textFontSize font.pointSize: JamiTheme.textFontSize
color: JamiTheme.textColor color: JamiTheme.textColor
elide: Text.ElideRight elide: Text.ElideRight
horizontalAlignment: Text.AlignLeft
} }
Text { Text {
...@@ -155,6 +156,7 @@ Label { ...@@ -155,6 +156,7 @@ Label {
font.pointSize: JamiTheme.textFontSize font.pointSize: JamiTheme.textFontSize
color: JamiTheme.faddedLastInteractionFontColor color: JamiTheme.faddedLastInteractionFontColor
elide: Text.ElideRight elide: Text.ElideRight
horizontalAlignment: Text.AlignLeft
} }
} }
......
...@@ -72,6 +72,7 @@ ItemDelegate { ...@@ -72,6 +72,7 @@ ItemDelegate {
font.pointSize: JamiTheme.textFontSize font.pointSize: JamiTheme.textFontSize
color: JamiTheme.textColor color: JamiTheme.textColor
elide: Text.ElideRight elide: Text.ElideRight
horizontalAlignment: Text.AlignLeft
} }
Text { Text {
...@@ -86,6 +87,7 @@ ItemDelegate { ...@@ -86,6 +87,7 @@ ItemDelegate {
font.pointSize: JamiTheme.textFontSize font.pointSize: JamiTheme.textFontSize
color: JamiTheme.faddedLastInteractionFontColor color: JamiTheme.faddedLastInteractionFontColor
elide: Text.ElideRight elide: Text.ElideRight
horizontalAlignment: Text.AlignLeft
} }
} }
......
...@@ -72,6 +72,7 @@ Item { ...@@ -72,6 +72,7 @@ Item {
Layout.leftMargin: root.margin Layout.leftMargin: root.margin
Layout.preferredWidth: root.prefWidth - 2 * root.margin - root.iconSize Layout.preferredWidth: root.prefWidth - 2 * root.margin - root.iconSize
font.pixelSize: JamiTheme.tipBoxTitleFontSize font.pixelSize: JamiTheme.tipBoxTitleFontSize
horizontalAlignment: Text.AlignLeft
elide: Qt.ElideRight elide: Qt.ElideRight
} }
} }
...@@ -87,6 +88,7 @@ Item { ...@@ -87,6 +88,7 @@ Item {
font.weight: Font.Normal font.weight: Font.Normal
text: JamiStrings.whyBackupAccount text: JamiStrings.whyBackupAccount
color: JamiTheme.textColor color: JamiTheme.textColor
horizontalAlignment: Text.AlignLeft
} }
Text { Text {
...@@ -98,6 +100,7 @@ Item { ...@@ -98,6 +100,7 @@ Item {
wrapMode: Text.WordWrap wrapMode: Text.WordWrap
text: JamiStrings.backupAccountInfos text: JamiStrings.backupAccountInfos
color: JamiTheme.textColor color: JamiTheme.textColor
horizontalAlignment: Text.AlignLeft
} }
MaterialButton { MaterialButton {
......
...@@ -250,6 +250,9 @@ Rectangle { ...@@ -250,6 +250,9 @@ Rectangle {
StackLayout { StackLayout {
id: chatViewStack id: chatViewStack
LayoutMirroring.enabled: false
LayoutMirroring.childrenInherit: true
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
Layout.fillWidth: true Layout.fillWidth: true
Layout.fillHeight: true Layout.fillHeight: true
......
...@@ -221,8 +221,8 @@ Rectangle { ...@@ -221,8 +221,8 @@ Rectangle {
objectName: "dataTransferSendContainer" objectName: "dataTransferSendContainer"
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
Layout.preferredWidth: footerColumnLayout.width Layout.fillWidth: true
Layout.maximumWidth: JamiTheme.chatViewMaximumWidth Layout.rightMargin: 10
Layout.preferredHeight: filesToSendCount ? JamiTheme.filesToSendDelegateHeight : 0 Layout.preferredHeight: filesToSendCount ? JamiTheme.filesToSendDelegateHeight : 0
} }
} }
......
...@@ -83,6 +83,8 @@ Rectangle { ...@@ -83,6 +83,8 @@ Rectangle {
preferredSize: 24 preferredSize: 24
mirror: UtilsAdapter.isRTL
source: JamiResources.back_24dp_svg source: JamiResources.back_24dp_svg
toolTipText: CurrentConversation.inCall ? JamiStrings.backCall : JamiStrings.hideChat toolTipText: CurrentConversation.inCall ? JamiStrings.backCall : JamiStrings.hideChat
......
...@@ -61,6 +61,7 @@ ColumnLayout { ...@@ -61,6 +61,7 @@ ColumnLayout {
visible: !opened visible: !opened
Layout.alignment: Qt.AlignLeft Layout.alignment: Qt.AlignLeft
Layout.leftMargin: column.margin Layout.leftMargin: column.margin
horizontalAlignment: Text.AlignLeft
font.pixelSize: JamiTheme.tipBoxTitleFontSize font.pixelSize: JamiTheme.tipBoxTitleFontSize
elide: Qt.ElideRight elide: Qt.ElideRight
} }
...@@ -71,6 +72,7 @@ ColumnLayout { ...@@ -71,6 +72,7 @@ ColumnLayout {
Layout.leftMargin: 20 Layout.leftMargin: 20
Layout.topMargin: 8 Layout.topMargin: 8
Layout.bottomMargin: 15 Layout.bottomMargin: 15
horizontalAlignment: Text.AlignLeft
font.pixelSize: JamiTheme.tipBoxContentFontSize font.pixelSize: JamiTheme.tipBoxContentFontSize
visible: !opened visible: !opened
wrapMode: Text.WordWrap wrapMode: Text.WordWrap
......
...@@ -107,13 +107,11 @@ Item { ...@@ -107,13 +107,11 @@ Item {
anchors.fill: parent anchors.fill: parent
anchors.margins: 8 anchors.margins: 8
source: { source: {
if(mediaInfo.isVideo) if (mediaInfo.isVideo)
return JamiResources.video_file_svg return JamiResources.video_file_svg;
if (mediaInfo.isAudio)
if(mediaInfo.isAudio) return JamiResources.audio_file_svg;
return JamiResources.audio_file_svg return JamiResources.attached_file_svg;
return JamiResources.attached_file_svg
} }
cache: false cache: false
color: JamiTheme.textColor color: JamiTheme.textColor
...@@ -163,6 +161,7 @@ Item { ...@@ -163,6 +161,7 @@ Item {
color: JamiTheme.chatviewTextColor color: JamiTheme.chatviewTextColor
text: TransferName text: TransferName
elide: Text.ElideRight elide: Text.ElideRight
horizontalAlignment: Text.AlignLeft
} }
RowLayout { RowLayout {
......
...@@ -19,6 +19,7 @@ import QtQuick ...@@ -19,6 +19,7 @@ import QtQuick
import QtQuick.Controls import QtQuick.Controls
import net.jami.Models 1.1 import net.jami.Models 1.1
import net.jami.Constants 1.1 import net.jami.Constants 1.1
import net.jami.Adapters 1.1
import "../../commoncomponents" import "../../commoncomponents"
Rectangle { Rectangle {
...@@ -28,6 +29,9 @@ Rectangle { ...@@ -28,6 +29,9 @@ Rectangle {
property alias filesToSendCount: repeater.count property alias filesToSendCount: repeater.count
color: JamiTheme.primaryBackgroundColor color: JamiTheme.primaryBackgroundColor
LayoutMirroring.enabled: UtilsAdapter.isRTL
LayoutMirroring.childrenInherit: true
JamiFlickable { JamiFlickable {
id: filesToSendContainerScrollView id: filesToSendContainerScrollView
...@@ -44,6 +48,8 @@ Rectangle { ...@@ -44,6 +48,8 @@ Rectangle {
anchors.centerIn: parent anchors.centerIn: parent
layoutDirection: UtilsAdapter.isRTL ? Qt.RightToLeft : Qt.LeftToRight
spacing: JamiTheme.filesToSendContainerSpacing spacing: JamiTheme.filesToSendContainerSpacing
padding: JamiTheme.filesToSendContainerPadding padding: JamiTheme.filesToSendContainerPadding
...@@ -53,7 +59,6 @@ Rectangle { ...@@ -53,7 +59,6 @@ Rectangle {
delegate: FilesToSendDelegate { delegate: FilesToSendDelegate {
anchors.verticalCenter: filesToSendContainerRow.verticalCenter anchors.verticalCenter: filesToSendContainerRow.verticalCenter
width: JamiTheme.filesToSendDelegateWidth
height: JamiTheme.filesToSendDelegateHeight height: JamiTheme.filesToSendDelegateHeight
onRemoveFileButtonClicked: function (index) { onRemoveFileButtonClicked: function (index) {
......
...@@ -29,6 +29,8 @@ Item { ...@@ -29,6 +29,8 @@ Item {
property real margin: 5 property real margin: 5
signal removeFileButtonClicked(int index) signal removeFileButtonClicked(int index)
width: JamiTheme.layoutWidthFileTransfer * 2
RowLayout { RowLayout {
anchors.fill: root anchors.fill: root
...@@ -158,6 +160,7 @@ Item { ...@@ -158,6 +160,7 @@ Item {
font.bold: true font.bold: true
text: FileName text: FileName
elide: Text.ElideRight elide: Text.ElideRight
horizontalAlignment: Text.AlignLeft
} }
RowLayout { RowLayout {
......
...@@ -62,6 +62,7 @@ ColumnLayout { ...@@ -62,6 +62,7 @@ ColumnLayout {
Layout.leftMargin: 8 Layout.leftMargin: 8
Layout.preferredWidth: column.prefWidth - 2 * column.margin - column.iconSize Layout.preferredWidth: column.prefWidth - 2 * column.margin - column.iconSize
font.pixelSize: JamiTheme.tipBoxTitleFontSize font.pixelSize: JamiTheme.tipBoxTitleFontSize
horizontalAlignment: Text.AlignLeft
elide: Qt.ElideRight elide: Qt.ElideRight
} }
} }
...@@ -75,6 +76,7 @@ ColumnLayout { ...@@ -75,6 +76,7 @@ ColumnLayout {
wrapMode: Text.WordWrap wrapMode: Text.WordWrap
font.weight: opened ? Font.Medium : Font.Normal font.weight: opened ? Font.Medium : Font.Normal
text: root.title text: root.title
horizontalAlignment: Text.AlignLeft
color: JamiTheme.textColor color: JamiTheme.textColor
} }
...@@ -85,6 +87,7 @@ ColumnLayout { ...@@ -85,6 +87,7 @@ ColumnLayout {
visible: opened visible: opened
wrapMode: Text.WordWrap wrapMode: Text.WordWrap
text: root.description text: root.description
horizontalAlignment: Text.AlignLeft
color: JamiTheme.textColor color: JamiTheme.textColor
} }
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment