diff --git a/mobile-datovka.pro b/mobile-datovka.pro
index 97b0fe8784b838d7516c69de4835ff32d6bc7c26..9e2cc1682556d1ac5f3db9e5a667022204771597 100644
--- a/mobile-datovka.pro
+++ b/mobile-datovka.pro
@@ -125,6 +125,7 @@ SOURCES += \
src/qml_interaction/interaction_zfo_file.cpp \
src/qml_interaction/message_envelope.cpp \
src/qml_interaction/message_info.cpp \
+ src/qml_interaction/string_manipulation.cpp \
src/settings.cpp \
src/setwrapper.cpp \
src/sqlite/account_db.cpp \
@@ -188,6 +189,7 @@ HEADERS += \
src/qml_interaction/interaction_zfo_file.h \
src/qml_interaction/message_envelope.h \
src/qml_interaction/message_info.h \
+ src/qml_interaction/string_manipulation.h \
src/settings.h \
src/setwrapper.h \
src/sqlite/account_db.h \
diff --git a/qml/components/AccessibleButton.qml b/qml/components/AccessibleButton.qml
new file mode 100644
index 0000000000000000000000000000000000000000..dedabcdd3312476d02da62f5530895a1a435b58d
--- /dev/null
+++ b/qml/components/AccessibleButton.qml
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2014-2018 CZ.NIC
+ *
+ * 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 .
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations including
+ * the two.
+ */
+
+import QtQuick 2.7
+import QtQuick.Controls 2.2
+
+/*
+ * Accessible button component.
+ */
+Button {
+ id: root
+
+ /* These properties must be set by caller. */
+ property string accessibleDescription: ""
+ property string accessibleName: ""
+
+ Accessible.role: Accessible.Button
+ Accessible.checkable: root.checkable
+ Accessible.checked: root.checked
+ Accessible.description: root.accessibleDescription
+ Accessible.name: (root.accessibleName !== "") ? root.accessibleName : root.text
+ Accessible.pressed: root.pressed
+ Accessible.onPressAction: {
+ root.clicked()
+ }
+}
diff --git a/qml/components/AccessibleComboBox.qml b/qml/components/AccessibleComboBox.qml
new file mode 100644
index 0000000000000000000000000000000000000000..e0320a75d89a1d1b93b9dce12d923e80f8f8cda9
--- /dev/null
+++ b/qml/components/AccessibleComboBox.qml
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2014-2018 CZ.NIC
+ *
+ * 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 .
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations including
+ * the two.
+ */
+
+import QtQuick 2.7
+import QtQuick.Controls 2.2
+import cz.nic.mobileDatovka 1.0
+
+/*
+ * Accessible combo box component.
+ */
+ComboBox {
+ id: root
+
+ /* These properties must be set by caller. */
+ property string accessibleDescription: ""
+
+ /*
+ * The model entries must contain these properties.
+ * label - (string with item description)
+ * item description
+ * key - (string holding one of the keys)
+ * unique string identifying an item
+ * e.g.:
+ ListModel {
+ id: listModel
+ ListElement {
+ label: qsTr("Some selection")
+ key: "some"
+ }
+ }
+ */
+
+ currentIndex: 0
+ textRole: "label"
+
+ height: inputItemHeight
+ font.pointSize: defaultTextFont.font.pointSize
+
+ /*
+ * Return current key value.
+ */
+ function currentKey() {
+ return root.model.get(root.currentIndex).key
+ }
+
+ /*
+ * Selects entry with given key.
+ */
+ function selectCurrentKey(key) {
+ for (var i = 0; i < root.model.count; ++i) {
+ //root.model.get(i)["key"]
+ if (root.model.get(i).key === key) {
+ root.currentIndex = i;
+ return;
+ }
+ }
+ /* Not found. */
+ console.log("No entry found for key '" + key + "'.");
+ }
+
+ delegate: ItemDelegate {
+ width: root.width
+ height: inputItemHeight
+ contentItem: AccessibleTextButton {
+ text: label
+ color: datovkaPalette.text
+ font.pointSize: defaultTextFont.font.pointSize
+ elide: Text.ElideRight
+ verticalAlignment: Text.AlignVCenter
+ onClicked: {
+ root.currentIndex = index
+ root.popup.close()
+ }
+ }
+ highlighted: root.highlightedIndex == index
+ }
+
+ Accessible.role: Accessible.ComboBox
+ Accessible.description: accessibleDescription
+ Accessible.name: root.currentText
+ Accessible.onPressAction: {
+ root.popup.open()
+ }
+}
diff --git a/qml/components/AccessibleImageButton.qml b/qml/components/AccessibleImageButton.qml
new file mode 100644
index 0000000000000000000000000000000000000000..5029d0828555ac45a84cdcc365270bf925a0ef26
--- /dev/null
+++ b/qml/components/AccessibleImageButton.qml
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2014-2018 CZ.NIC
+ *
+ * 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 .
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations including
+ * the two.
+ */
+
+import QtQuick 2.7
+
+/*
+ * Accessible button image component.
+ */
+Image {
+ id: root
+
+ /* These properties must be set by caller. */
+ property string accessibleName: ""
+
+ signal clicked()
+
+ MouseArea {
+ function handleClick() {
+ root.clicked()
+ }
+
+ anchors.fill: parent
+
+ Accessible.role: Accessible.Button
+ Accessible.name: root.accessibleName
+ Accessible.onPressAction: {
+ handleClick()
+ }
+ onClicked: {
+ handleClick()
+ }
+ }
+}
diff --git a/qml/components/AccessibleMenu.qml b/qml/components/AccessibleMenu.qml
new file mode 100644
index 0000000000000000000000000000000000000000..23352d2e7075b8a1ae60db4ed734e857a92efbd0
--- /dev/null
+++ b/qml/components/AccessibleMenu.qml
@@ -0,0 +1,183 @@
+/*
+ * Copyright (C) 2014-2018 CZ.NIC
+ *
+ * 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 .
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations including
+ * the two.
+ */
+
+import QtGraphicalEffects 1.0
+import QtQuick 2.7
+import cz.nic.mobileDatovka 1.0
+
+/*
+ * Accessible menu component.
+ *
+ * An object containing functions to be called and a model in specified form
+ * must be provided.
+ */
+ScrollableListView {
+ id: root
+
+ delegateHeight: headerHeight
+
+ /* These properties must be set by caller. */
+ property var funcArr: null /* https://stackoverflow.com/a/24376300 */
+
+ /*
+ * The property funcArr must hold an object (associative array).
+ * The keys must be strings, values must be functions.
+ * e.g.:
+ property var funcs: {
+ "funcName": function callFuncName {
+ console.log("Calling function funcName.")
+ }
+ }
+
+ * The model entries must contain these properties.
+ * image - (string containing path of image resource)
+ * image to be shown in the menu before the text
+ * showEntry - (boolean value)
+ * true means that the entire menu entry is being shown
+ * showNext - (boolean value)
+ * true means that an further menu is being indicated
+ * name - (string with action description)
+ * action
+ * funcName - (string holding one of function array keys)
+ * string identifying function to be called
+ * e.g.:
+ ListModel {
+ id: listModel
+ ListElement {
+ image: "qrc:/ui/settings.svg"
+ showEntry: true
+ showNext: false
+ name: qsTr("Perform some action")
+ funcName: "funcName"
+ }
+ }
+ */
+
+ /*
+ * Return the first index of the element having a specified property of
+ * specified value.
+ *
+ * Returns -1 if nothing found.
+ */
+ function get_model_index(model, property, value) {
+ for (var i = 0; i < model.count; ++i) {
+ if (model.get(i)[property] === value) {
+ return i;
+ }
+ }
+ /* Not found. */
+ return -1;
+ }
+
+ /* https://stackoverflow.com/a/7356528 */
+ function isFunction(functionToCheck) {
+ var getType = {};
+ return functionToCheck && getType.toString.call(functionToCheck) === '[object Function]';
+ }
+
+ Component {
+ id: menuDelegate
+ Rectangle {
+ visible: showEntry
+ color: datovkaPalette.base
+ height: showEntry ? root.delegateHeight : 0 /* Collapse when not visible. */
+ width: parent.width
+ Image {
+ id: menuImage
+ anchors.verticalCenter: parent.verticalCenter
+ anchors.left: parent.left
+ anchors.leftMargin: defaultMargin
+ sourceSize.height: imgHeight
+ source: image
+ }
+ ColorOverlay {
+ anchors.fill: menuImage
+ source: menuImage
+ color: datovkaPalette.text
+ }
+ Text {
+ anchors.verticalCenter: parent.verticalCenter
+ anchors.left: menuImage.right
+ anchors.leftMargin: defaultMargin
+ color: datovkaPalette.text
+ text: name
+ }
+ Rectangle {
+ id: next2
+ visible: showNext
+ anchors.verticalCenter: parent.verticalCenter
+ anchors.right: parent.right
+ height: parent.height
+ width: parent.width * 0.07
+ color: parent.color
+ Image {
+ id: nextImage2
+ anchors.verticalCenter: parent.verticalCenter
+ anchors.right: parent.right
+ anchors.rightMargin: defaultMargin
+ sourceSize.height: navImgHeight
+ source: "qrc:/ui/next.svg"
+ }
+ ColorOverlay {
+ anchors.fill: nextImage2
+ source: nextImage2
+ color: datovkaPalette.text
+ }
+ }
+ MouseArea {
+ function handleClick() {
+ /* https://stackoverflow.com/a/1098955 */
+ if (funcName in funcArr) {
+ if (isFunction(funcArr[funcName])) {
+ /* Call function. */
+ funcArr[funcName]()
+ } else {
+ console.log("'" + funcName + "' is not a function.")
+ }
+ } else {
+ console.log("Unknown function '" + funcName + "'.")
+ }
+ }
+
+ anchors.fill: parent
+
+ Accessible.role: Accessible.Button
+ Accessible.name: name
+ Accessible.onScrollDownAction: {
+ root.scrollDown()
+ }
+ Accessible.onScrollUpAction: {
+ root.scrollUp()
+ }
+ Accessible.onPressAction: {
+ handleClick()
+ }
+ onClicked: {
+ handleClick()
+ }
+ }
+ }
+ }
+
+ delegate: menuDelegate
+}
diff --git a/qml/components/AccessibleOverlaidImageButton.qml b/qml/components/AccessibleOverlaidImageButton.qml
new file mode 100644
index 0000000000000000000000000000000000000000..e17652bed0a7397efaaab653fe603e4f031fa0bb
--- /dev/null
+++ b/qml/components/AccessibleOverlaidImageButton.qml
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2014-2018 CZ.NIC
+ *
+ * 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 .
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations including
+ * the two.
+ */
+
+import QtQuick 2.7
+import cz.nic.mobileDatovka 1.0
+
+/*
+ * Accessible button ovelaid image component.
+ */
+OverlaidImage {
+ id: root
+
+ /* These properties must be set by caller. */
+ property string accessibleName: ""
+
+ signal clicked()
+
+ MouseArea {
+ function handleClick() {
+ root.clicked()
+ }
+
+ anchors.fill: parent
+
+ Accessible.role: Accessible.Button
+ Accessible.name: root.accessibleName
+ Accessible.onPressAction: {
+ handleClick()
+ }
+ onClicked: {
+ handleClick()
+ }
+ }
+}
diff --git a/qml/components/AccessibleSpinBox.qml b/qml/components/AccessibleSpinBox.qml
new file mode 100644
index 0000000000000000000000000000000000000000..c5bba9d7756e7f7d881fb05d2347a8e84fdd52bd
--- /dev/null
+++ b/qml/components/AccessibleSpinBox.qml
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2014-2018 CZ.NIC
+ *
+ * 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 .
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations including
+ * the two.
+ */
+
+import QtQuick 2.7
+import QtQuick.Controls 2.2
+
+/*
+ * Accessible spin box component.
+ */
+SpinBox {
+ id: root
+
+ /* These properties must be set by caller. */
+ property string accessibleDescription: ""
+
+ height: inputItemHeight
+ font.pointSize: defaultTextFont.font.pointSize
+
+ /*
+ * Return spin box value.
+ */
+ function val() {
+ return root.value;
+ }
+
+ /*
+ * Set spin box value.
+ */
+ function setVal(v) {
+ if (v < root.from) {
+ root.value = root.from
+ } else if (v > root.to) {
+ root.value = root.to
+ } else {
+ root.value = v
+ }
+ }
+
+ MouseArea {
+ anchors.fill: root.down.indicator
+
+ function handleClick() {
+ root.decrease()
+ root.valueModified()
+ }
+
+ Accessible.role: Accessible.Button
+ Accessible.description: root.accessibleDescription
+ //Accessible.focusable: true
+ Accessible.name: qsTr("Decrease value '%1'.").arg(root.val())
+ Accessible.onPressAction: {
+ handleClick()
+ }
+ onClicked: {
+ handleClick()
+ }
+ }
+ MouseArea {
+ anchors.top: root.top
+ anchors.bottom: root.bottom
+ anchors.left: (root.down.indicator.x < root.up.indicator.x) ? root.down.indicator.right : root.up.indicator.right
+ anchors.right: (root.down.indicator.x < root.up.indicator.x) ? root.up.indicator.left : root.up.indicator.left
+
+ Accessible.role: root.editable ? Accessible.EditableText : Accessible.StaticText
+ Accessible.description: root.accessibleDescription
+ Accessible.editable: root.editable
+ Accessible.focusable: true
+ Accessible.multiLine: false
+ Accessible.name: root.val()
+ Accessible.readOnly: !root.editable
+ }
+ MouseArea {
+ anchors.fill: root.up.indicator
+
+ function handleClick() {
+ root.increase()
+ root.valueModified()
+ }
+
+ Accessible.role: Accessible.Button
+ Accessible.description: root.accessibleDescription
+ //Accessible.focusable: true
+ Accessible.name: qsTr("Increase value '%1'.").arg(root.val())
+ Accessible.onPressAction: {
+ handleClick()
+ }
+ onClicked: {
+ handleClick()
+ }
+ }
+}
diff --git a/qml/components/SpinBoxZeroMax.qml b/qml/components/AccessibleSpinBoxZeroMax.qml
similarity index 55%
rename from qml/components/SpinBoxZeroMax.qml
rename to qml/components/AccessibleSpinBoxZeroMax.qml
index eaa0bd2da9ad6bd05f10b35734905ef4dbbb9d10..0be7bfeb9bbf7d4ce42c0d46e98694cdfbb1190a 100644
--- a/qml/components/SpinBoxZeroMax.qml
+++ b/qml/components/AccessibleSpinBoxZeroMax.qml
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014-2017 CZ.NIC
+ * Copyright (C) 2014-2018 CZ.NIC
*
* 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
@@ -21,9 +21,13 @@
* the two.
*/
+import QtQuick 2.7
import QtQuick.Controls 2.2
+import cz.nic.mobileDatovka 1.0
+
+AccessibleSpinBox {
+ id: root
-SpinBox {
/* Must be a non-decreasing list ending with infinity. */
property var items: [1, qsTr("max")]
property int dfltIdx: 0
@@ -73,4 +77,57 @@ SpinBox {
value = from
}
}
+
+ MouseArea {
+ anchors.fill: root.down.indicator
+
+ function handleClick() {
+ root.decrease()
+ root.valueModified()
+ }
+
+ Accessible.role: Accessible.Button
+ Accessible.description: root.accessibleDescription
+ //Accessible.focusable: true
+ Accessible.name: qsTr("Decrease value '%1'.").arg(root.textFromValue(root.value))
+ Accessible.onPressAction: {
+ handleClick()
+ }
+ onClicked: {
+ handleClick()
+ }
+ }
+ MouseArea {
+ anchors.top: root.top
+ anchors.bottom: root.bottom
+ anchors.left: (root.down.indicator.x < root.up.indicator.x) ? root.down.indicator.right : root.up.indicator.right
+ anchors.right: (root.down.indicator.x < root.up.indicator.x) ? root.up.indicator.left : root.up.indicator.left
+
+ Accessible.role: root.editable ? Accessible.EditableText : Accessible.StaticText
+ Accessible.description: root.accessibleDescription
+ Accessible.editable: root.editable
+ Accessible.focusable: true
+ Accessible.multiLine: false
+ Accessible.name: root.textFromValue(root.value)
+ Accessible.readOnly: !root.editable
+ }
+ MouseArea {
+ anchors.fill: root.up.indicator
+
+ function handleClick() {
+ root.increase()
+ root.valueModified()
+ }
+
+ Accessible.role: Accessible.Button
+ Accessible.description: root.accessibleDescription
+ //Accessible.focusable: true
+ Accessible.name: qsTr("Increase value '%1'.").arg(root.textFromValue(root.value))
+ Accessible.onPressAction: {
+ handleClick()
+ }
+ onClicked: {
+ handleClick()
+ }
+ }
}
diff --git a/qml/components/AccessibleSwitch.qml b/qml/components/AccessibleSwitch.qml
new file mode 100644
index 0000000000000000000000000000000000000000..6479f198221af769c3f77f3f269ced65a5b6e313
--- /dev/null
+++ b/qml/components/AccessibleSwitch.qml
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2014-2018 CZ.NIC
+ *
+ * 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 .
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations including
+ * the two.
+ */
+
+import QtQuick 2.7
+import QtQuick.Controls 2.2
+
+/*
+ * Accessible switch component.
+ */
+Switch {
+ id: root
+
+ /* These properties must be set by caller. */
+ property string accessibleDescription: ""
+ property string accessibleName: ""
+
+ Accessible.role: Accessible.CheckBox
+ Accessible.checkStateMixed: false
+ Accessible.checkable: true
+ Accessible.checked: root.checked
+ Accessible.description: root.accessibleDescription
+ //Accessible.focusable: true
+ Accessible.name: (root.accessibleName !== "") ? root.accessibleName : root.text
+ Accessible.onPressAction: {
+ root.toggle()
+ }
+ Accessible.onToggleAction: {
+ root.toggle()
+ }
+}
diff --git a/qml/components/AccessibleTabButton.qml b/qml/components/AccessibleTabButton.qml
new file mode 100644
index 0000000000000000000000000000000000000000..484edc97eb0f5d7c38c5d55039eb90a277126095
--- /dev/null
+++ b/qml/components/AccessibleTabButton.qml
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2014-2018 CZ.NIC
+ *
+ * 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 .
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations including
+ * the two.
+ */
+
+import QtQuick 2.7
+import QtQuick.Controls 2.2
+
+/*
+ * Accessible button component.
+ */
+TabButton {
+ id: root
+
+ /* These properties must be set by caller. */
+ property string accessibleDescription: ""
+ property string accessibleName: ""
+
+ Accessible.role: Accessible.Button
+ Accessible.checkable: root.checkable
+ Accessible.checked: root.checked
+ Accessible.description: root.accessibleDescription
+ Accessible.name: (root.accessibleName !== "") ? root.accessibleName : root.text
+ Accessible.onPressAction: {
+ /*
+ * It looks like TabBar is actually a Container of checkable
+ * AbstractButton elements. For further details see sources of
+ * QQuickTabBar, QQuickContainer and QQuickAbstractButton. Some hints
+ * can also be found here: https://stackoverflow.com/a/32426364
+ */
+ root.checked = true
+ }
+}
diff --git a/qml/components/AccessibleText.qml b/qml/components/AccessibleText.qml
new file mode 100644
index 0000000000000000000000000000000000000000..7b96f36ac274374ee536f85260d97a3ee0b6d138
--- /dev/null
+++ b/qml/components/AccessibleText.qml
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2014-2018 CZ.NIC
+ *
+ * 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 .
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations including
+ * the two.
+ */
+
+import QtQuick 2.7
+
+/*
+ * Accessible text component.
+ *
+ * This component exposes its text to the accessibility interface. Rich text
+ * is converted onto plain text.
+ * If accessibleName is specified then its content is used instead of the text
+ * property value.
+ */
+Text {
+ id: root
+
+ /* These properties must be set by caller. */
+ property string accessibleName: ""
+
+ Accessible.role: Accessible.StaticText
+ Accessible.focusable: true /* This enables the text to selectable and readable by Android TalkBack. */
+ Accessible.name: (root.accessibleName !== "") ? root.accessibleName : ((root.textFormat !== TextEdit.RichText) ? root.text : strManipulation.removeRich(root.text))
+}
diff --git a/qml/components/AccessibleTextButton.qml b/qml/components/AccessibleTextButton.qml
new file mode 100644
index 0000000000000000000000000000000000000000..da62ad1d9e3a6dbe68cd18fbcdd0b167d5fa07e3
--- /dev/null
+++ b/qml/components/AccessibleTextButton.qml
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2014-2018 CZ.NIC
+ *
+ * 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 .
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations including
+ * the two.
+ */
+
+import QtQuick 2.7
+
+/*
+ * Accessible text component.
+ *
+ * This component exposes the its text to the accessibility interface.
+ * If accessibleName is specified then its content is used instead of the text
+ * property value.
+ */
+Text {
+ id: root
+
+ /* These properties must be set by caller. */
+ property string accessibleName: ""
+
+ signal clicked()
+
+ MouseArea {
+ function handleClick() {
+ root.clicked()
+ }
+
+ anchors.fill: parent
+
+ Accessible.role: Accessible.Button
+ Accessible.name: (root.accessibleName !== "") ? root.accessibleName : ((root.textFormat !== TextEdit.RichText) ? root.text : strManipulation.removeRich(root.text))
+ Accessible.onPressAction: {
+ handleClick()
+ }
+ onClicked: {
+ handleClick()
+ }
+ }
+}
diff --git a/qml/components/AccessibleTextField.qml b/qml/components/AccessibleTextField.qml
new file mode 100644
index 0000000000000000000000000000000000000000..fd72f612e71edb3d44024a45152ea1e52fd57d47
--- /dev/null
+++ b/qml/components/AccessibleTextField.qml
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2014-2018 CZ.NIC
+ *
+ * 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 .
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations including
+ * the two.
+ */
+
+import QtQuick 2.7
+import QtQuick.Controls 2.2
+
+/*
+ * Accessible text field component.
+ */
+TextField {
+ id: root
+
+ /* These properties must be set by caller. */
+ property string accessibleDescription: ""
+
+ Accessible.role: Accessible.EditableText
+ Accessible.description: (root.accessibleDescription !== "") ? root.accessibleDescription : root.placeholderText
+ Accessible.editable: root.enabled
+ //Accessible.focusable: true
+ Accessible.multiLine: false
+ Accessible.name: root.text
+ Accessible.passwordEdit: (root.echoMode === TextInput.Password) || (root.echoMode === TextInput.PasswordEchoOnEdit)
+ Accessible.readOnly: root.readOnly
+ Accessible.searchEdit: false
+ Accessible.selectableText: true
+}
diff --git a/qml/components/DataboxList.qml b/qml/components/DataboxList.qml
index 01605592271d51fb356a30dc224e1f47e7f45971..28c27749d773fa4133169e97edfddbcd551d189c 100644
--- a/qml/components/DataboxList.qml
+++ b/qml/components/DataboxList.qml
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014-2017 CZ.NIC
+ * Copyright (C) 2014-2018 CZ.NIC
*
* 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
@@ -25,12 +25,14 @@ import QtGraphicalEffects 1.0
import QtQuick 2.7
import QtQuick.Layouts 1.3
import QtQuick.Controls 2.1
-
+import cz.nic.mobileDatovka 1.0
import cz.nic.mobileDatovka.modelEntries 1.0
-ListView {
+ScrollableListView {
id: root
+ delegateHeight: listItemHeight
+
/* These properties must be set by caller. */
property bool canDetailBoxes: false // enables viewing of box details
property bool canSelectBoxes: false // enables selecting of entries
@@ -47,7 +49,7 @@ ListView {
delegate: Rectangle {
id: dbItem
- height: listItemHeight
+ height: root.delegateHeight
width: parent.width
color: rDbSelected ? readBgColor : datovkaPalette.base
Item {
@@ -132,17 +134,79 @@ ListView {
} // GridLayout
} // Item
MouseArea {
- anchors.fill: parent
- onClicked: {
+ /*
+ * Returns specified value:
+ * -1 - none ov below
+ * 0 - show box detail
+ * 1 - deselect box
+ * 2 - select box
+ */
+ function actionOnClick() {
+ var ret = -1;
if (canDetailBoxes && !(canSelectBoxes || canDeselectBoxes)) {
- root.boxDetail(rDbID)
+ ret = 0;
} else if (!canDetailBoxes && (canSelectBoxes || canDeselectBoxes)) {
if (rDbSelected && canDeselectBoxes) {
- root.boxDeselect(rDbID)
+ ret = 1;
} else if (!rDbSelected && canSelectBoxes) {
- root.boxSelect(rDbID)
+ ret = 2;
}
}
+ return ret;
+ }
+
+ /* Construct string to be presented to accessibility interface. */
+ function accessibleText() {
+ var aText = "";
+
+ switch (actionOnClick()) {
+ case 0:
+ aText += qsTr("View details about data box '%1' (identifier '%2').").arg(rDbName).arg(rDbID);
+ break;
+ case 1:
+ aText += qsTr("Deselect data box '%1' (identifier '%2').").arg(rDbName).arg(rDbID);
+ break;
+ case 2:
+ aText += qsTr("Select data box '%1' (identifier '%2').").arg(rDbName).arg(rDbID);
+ break;
+ default:
+ break;
+ }
+
+ return aText;
+ }
+
+ function handleClick() {
+ switch (actionOnClick()) {
+ case 0:
+ root.boxDetail(rDbID)
+ break;
+ case 1:
+ root.boxDeselect(rDbID)
+ break;
+ case 2:
+ root.boxSelect(rDbID)
+ break;
+ default:
+ break;
+ }
+ }
+
+ anchors.fill: parent
+
+ Accessible.role: Accessible.Button
+ Accessible.name: accessibleText()
+ Accessible.onScrollDownAction: {
+ root.scrollDown()
+ }
+ Accessible.onScrollUpAction: {
+ root.scrollUp()
+ }
+ Accessible.onPressAction: {
+ handleClick()
+ }
+ onClicked: {
+ handleClick()
}
}
Rectangle {
@@ -183,14 +247,43 @@ ListView {
MouseArea {
// visible only if canDetailBoxes
visible: (!canDetailBoxes && !(canSelectBoxes || canDeselectBoxes) && canRemoveBoxes)
- anchors.fill: parent
- onClicked: {
- // we must allow remove exist recipients from model.
- if (!canDetailBoxes && !(canSelectBoxes || canDeselectBoxes) && canRemoveBoxes) {
+
+ /*
+ * Returns true if can delete entries.
+ */
+ function canRemoveEntries() {
+ return !canDetailBoxes && !(canSelectBoxes || canDeselectBoxes) && canRemoveBoxes;
+ }
+
+ /* Construct string to be presented to accessibility interface. */
+ function accessibleText() {
+ var aText = "";
+
+ if (canRemoveEntries()) {
+ aText += qsTr("Remove data box '%1' (identifier '%2').").arg(rDbName).arg(rDbID);
+ }
+
+ return aText;
+ }
+
+ function handleClick() {
+ /* We must allow removal of existing recipients from model. */
+ if (canRemoveEntries()) {
root.boxRemove(rDbID)
}
}
- } // MouseArea
+
+ anchors.fill: parent
+
+ Accessible.role: Accessible.Button
+ Accessible.name: accessibleText()
+ Accessible.onPressAction: {
+ handleClick()
+ }
+ onClicked: {
+ handleClick()
+ }
+ }
} // Rectangle
Rectangle {
anchors.top: parent.bottom
diff --git a/qml/components/FilterBar.qml b/qml/components/FilterBar.qml
new file mode 100644
index 0000000000000000000000000000000000000000..e3ef95dae81f24d0491ecce239eff5519eba2ac2
--- /dev/null
+++ b/qml/components/FilterBar.qml
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2014-2018 CZ.NIC
+ *
+ * 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 .
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations including
+ * the two.
+ */
+
+import QtQuick 2.7
+import QtQuick.Controls 2.1
+
+/*
+ * Filter bar component.
+ */
+Rectangle {
+ id: root
+
+ /* These properties must be set by caller. */
+ property string placeholderText: ""
+ property real fontPointSize: 1.0
+ property int buttonImageHeight: 1
+ property string buttonAccessibleName: ""
+
+ signal textChanged(string text)
+ signal clearClicked()
+
+ property alias filterField: filterField
+
+ AccessibleTextField {
+ id: filterField
+
+ anchors.top: parent.top
+ width: parent.width - clearFilterButton.width
+ placeholderText: root.placeholderText
+ font.pointSize: root.fontPointSize
+ inputMethodHints: Qt.ImhNoPredictiveText
+ /*
+ * Using explicit top, left, ... padding because plain padding
+ * does not centre the text properly.
+ */
+ topPadding: 8.0
+ bottomPadding: 8.0
+ leftPadding: 8.0
+ rightPadding: 8.0
+ /* TODO - remove background if used materials */
+ background: Rectangle {
+ anchors.fill: parent
+ color: "transparent"
+ border.color: "transparent"
+ }
+ onTextChanged: {
+ root.textChanged(filterField.text)
+ }
+
+ Accessible.searchEdit: true
+ }
+ AccessibleImageButton {
+ id: clearFilterButton
+ anchors.right: parent.right
+ anchors.verticalCenter: parent.verticalCenter
+ sourceSize.height: buttonImageHeight
+ source: "qrc:/ui/remove.svg"
+ accessibleName: buttonAccessibleName
+ onClicked: {
+ filterField.clear()
+ root.clearClicked()
+ }
+ }
+}
diff --git a/qml/components/MessageList.qml b/qml/components/MessageList.qml
index 483db65165b669232ad2cce5d1040234cbfbc8c8..a3a67894c2bc81fedc8b63e7f6303ffccaf76083 100644
--- a/qml/components/MessageList.qml
+++ b/qml/components/MessageList.qml
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014-2017 CZ.NIC
+ * Copyright (C) 2014-2018 CZ.NIC
*
* 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
@@ -24,19 +24,22 @@
import QtGraphicalEffects 1.0
import QtQuick 2.7
import QtQuick.Layouts 1.3
-import QtQuick.Controls 2.1
+import QtQuick.Controls 2.2
+import cz.nic.mobileDatovka 1.0
import cz.nic.mobileDatovka.messages 1.0
-ListView {
+ScrollableListView {
id: root
+ delegateHeight: listItemHeight
+
/* These signals should be captured to implement message interaction. */
signal msgClicked(string userName, int msgType, string msgId)
signal msgPressAndHold(string userName, int msgType, string msgId, bool canDelete)
delegate: Rectangle {
id: messageItem
- height: listItemHeight
+ height: root.delegateHeight
width: parent.width
color: (rMsgType == MessageType.TYPE_RECEIVED && !rReadLocally) ? datovkaPalette.base : readBgColor
Item {
@@ -131,11 +134,41 @@ ListView {
}
} // Rectangle
MouseArea {
+ /* Construct string to be presented to accessibility interface. */
+ function accessibleText() {
+ var aText = "";
+ if (rMsgType == MessageType.TYPE_RECEIVED) {
+ aText += !rReadLocally ? qsTr("Unread message from sender") : qsTr("Read message from sender")
+ } else {
+ aText += qsTr("Message to receiver")
+ }
+ aText += " '" + ((rMsgType == MessageType.TYPE_RECEIVED) ? rFrom : rTo) + "'. "
+ aText += qsTr("Subject") + ": '" + rAnnotation + "'."
+ return aText;
+ }
+
+ function handleClick() {
+ root.msgClicked(rUserName, rMsgType, rMsgId)
+ }
+
anchors.fill: parent
+
+ Accessible.role: Accessible.Button
+ Accessible.name: accessibleText()
+ Accessible.onScrollDownAction: {
+ root.scrollDown()
+ }
+ Accessible.onScrollUpAction: {
+ root.scrollUp()
+ }
+ Accessible.onPressAction: {
+ handleClick()
+ }
onClicked: {
- root.msgClicked(rUserName, rMsgType, rMsgId)
+ handleClick()
}
onPressAndHold: {
+ /* Accessible doesn't support this type of action. */
root.msgPressAndHold(rUserName, rMsgType, rMsgId, compareMsgDate(rDelivTime))
}
}
@@ -146,5 +179,6 @@ ListView {
color: datovkaPalette.dark
}
} // Rectangle
+
ScrollIndicator.vertical: ScrollIndicator {}
} // ListView
diff --git a/qml/components/PageHeader.qml b/qml/components/PageHeader.qml
index 7257c1bedf284a3adee2c02d229e570b7527fe87..7e6ff5c80552b354197172dbc5e0383f306c26c6 100644
--- a/qml/components/PageHeader.qml
+++ b/qml/components/PageHeader.qml
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014-2017 CZ.NIC
+ * Copyright (C) 2014-2018 CZ.NIC
*
* 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
@@ -22,20 +22,26 @@
*/
import QtQuick 2.7
+import cz.nic.mobileDatovka 1.0
/*
* Page header component.
*/
Rectangle {
id: root
+
+ /* These properties must be set by caller. */
property string title: ""
+
+ signal backClicked()
+
anchors.top: parent.top
width: parent.width
height: headerHeight
color: headerColor
z: 1
Image {
- id: backElement
+ id: backIcon
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
anchors.leftMargin: defaultMargin
@@ -43,15 +49,36 @@ Rectangle {
source: "qrc:/ui/back.svg"
}
Text {
+ id: backText
anchors.verticalCenter: parent.verticalCenter
- anchors.left: backElement.right
+ anchors.left: backIcon.right
anchors.leftMargin: defaultMargin
//font.bold: true
color: datovkaPalette.text
text: qsTr("Back")
}
- Text {
+ MouseArea {
+ function handleClick() {
+ backClicked()
+ }
+
+ anchors.left: backIcon.left
+ anchors.top: parent.top
+ anchors.bottom: parent.bottom
+ anchors.right: backText.right
+ Accessible.role: Accessible.Button
+ Accessible.name: backText.text
+ Accessible.onPressAction: {
+ handleClick()
+ }
+ onClicked: {
+ handleClick()
+ }
+ }
+ AccessibleText {
anchors.centerIn: parent
+ height: parent.height
+ verticalAlignment: Text.AlignVCenter
font.bold: true
color: datovkaPalette.base
text: title
diff --git a/qml/components/ProgressBar.qml b/qml/components/ProgressBar.qml
index 5afa85ed2565b2d83b9ec181da8c22b0bc61be24..e57b1840a87a7711b0fc7a2553c4d9883bef82d8 100644
--- a/qml/components/ProgressBar.qml
+++ b/qml/components/ProgressBar.qml
@@ -28,6 +28,7 @@ import QtQuick.Controls 2.1
Rectangle {
id: root
+
visible: false
property int statusBarTimer: 5000
anchors.left: parent.left
@@ -35,19 +36,20 @@ Rectangle {
anchors.right: parent.right
height: headerHeight
color: datovkaPalette.text
+
Column {
anchors.left: parent.left
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
anchors.margins: defaultMargin
spacing: formItemVerticalSpacing
- Text {
+ AccessibleText {
id: statusBarText
color: datovkaPalette.base
anchors.horizontalCenter: parent.horizontalCenter
text: mainWindow.width + " x "+ mainWindow.height
Connections {
- target: isds
+ target: isds
onStatusBarTextChanged: {
root.visible = isVisible
statusBarText.text = txt
diff --git a/qml/components/ScrollableListView.qml b/qml/components/ScrollableListView.qml
new file mode 100644
index 0000000000000000000000000000000000000000..6fbae03fa3f8a7fb10e436cdeb5aac636de02458
--- /dev/null
+++ b/qml/components/ScrollableListView.qml
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2014-2018 CZ.NIC
+ *
+ * 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 .
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations including
+ * the two.
+ */
+
+import QtQuick 2.7
+
+/*
+ * List view that can be scrolled programmatically.
+ */
+ListView {
+ id: root
+
+ /* These properties must be set by caller. */
+ property real delegateHeight: 1.0
+
+ /*
+ * Scroll list down.
+ */
+ function scrollDown() {
+ var numViewed = Math.ceil(root.height / (2 * delegateHeight))
+ if (numViewed < 1) {
+ numViewed = 1
+ }
+ var indexAtTop = root.indexAt(1, 1 + root.contentY)
+ indexAtTop = (indexAtTop >= 0) ? (indexAtTop + numViewed) : 0
+ root.positionViewAtIndex(indexAtTop, ListView.Beginning)
+ root.returnToBounds()
+ }
+
+ /*
+ * Scroll list up.
+ */
+ function scrollUp() {
+ var numViewed = Math.ceil(root.height / (2 * delegateHeight))
+ if (numViewed < 1) {
+ numViewed = 1
+ }
+ var indexAtBottom = root.indexAt(1, root.height - 2 + root.contentY)
+ indexAtBottom = (indexAtBottom >= 0) ? (indexAtBottom - numViewed) : 0
+ root.positionViewAtIndex(indexAtBottom, ListView.End)
+ root.returnToBounds()
+ }
+}
diff --git a/qml/dialogues/FileDialogue.qml b/qml/dialogues/FileDialogue.qml
index 86beb37ba7064f4208b05ff6b4dd55205ccd2578..95637d3eb7f7305c5fbe940b71dc15d1a4955206 100644
--- a/qml/dialogues/FileDialogue.qml
+++ b/qml/dialogues/FileDialogue.qml
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014-2017 CZ.NIC
+ * Copyright (C) 2014-2018 CZ.NIC
*
* 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
@@ -22,9 +22,10 @@
*/
import QtQuick 2.7
-import QtQuick.Controls 2.1
+import QtQuick.Controls 2.2
import QtQuick.Layouts 1.3
import Qt.labs.folderlistmodel 2.1
+import cz.nic.mobileDatovka 1.0
import cz.nic.mobileDatovka.qmlInteraction 1.0
Dialog {
@@ -33,7 +34,20 @@ Dialog {
focus: true
modal: true
title: qsTr("Select path")
- standardButtons: (selectedFileIndex != -1) ? (Dialog.Ok | Dialog.Cancel) : Dialog.Cancel
+ //standardButtons: (selectedFileIndex != -1) ? (Dialog.Ok | Dialog.Cancel) : Dialog.Cancel
+
+ footer: DialogButtonBox {
+ AccessibleButton {
+ text: qsTr("Cancel")
+ DialogButtonBox.buttonRole: DialogButtonBox.RejectRole
+ }
+ AccessibleButton {
+ text: qsTr("OK")
+ enabled: (selectedFileIndex != -1)
+ visible: (selectedFileIndex != -1)
+ DialogButtonBox.buttonRole: DialogButtonBox.AcceptRole
+ }
+ }
/* Place the dialogue in the centre. */
x: 2 * defaultMargin
@@ -96,53 +110,51 @@ Dialog {
contentItem: ColumnLayout {
spacing: formItemVerticalSpacing
- ComboBox {
+ AccessibleComboBox {
anchors {
left: parent.left;
right: parent.right;
}
- textRole: "label"
+ accessibleDescription: qsTr("Select location type")
model: ListModel {
- ListElement { label: qsTr("Desktop"); value: "desktop" }
- ListElement { label: qsTr("Documents"); value: "document" }
- ListElement { label: qsTr("Downloads"); value: "download" }
- ListElement { label: qsTr("Pictures"); value: "picture" }
- ListElement { label: qsTr("Temp"); value: "temp" }
+ ListElement { label: qsTr("Desktop"); key: "desktop" }
+ ListElement { label: qsTr("Documents"); key: "document" }
+ ListElement { label: qsTr("Downloads"); key: "download" }
+ ListElement { label: qsTr("Pictures"); key: "picture" }
+ ListElement { label: qsTr("Temp"); key: "temp" }
}
onActivated: {
var location = InteractionFilesystem.DESKTOP_LOCATION
- if (model.get(currentIndex).value === "document") {
+ if (currentKey() === "document") {
location = InteractionFilesystem.DOCUMENTS_LOCATION
- } else if (model.get(currentIndex).value === "download") {
+ } else if (currentKey() === "download") {
location = InteractionFilesystem.DOWNLOAD_LOCATION
- } else if (model.get(currentIndex).value === "picture") {
+ } else if (currentKey() === "picture") {
location = InteractionFilesystem.PICTURE_LOCATION
- } else if (model.get(currentIndex).value === "temp") {
+ } else if (currentKey() === "temp") {
location = InteractionFilesystem.TEMP_LOCATION
}
folderModel.folder = standardLocationUrl(location)
}
- } // ComboBox
+ }
RowLayout {
anchors {
left: parent.left;
right: parent.right;
}
spacing: formItemVerticalSpacing
- Button {
+ AccessibleButton {
id: upButton
text: "<"
- MouseArea {
- anchors.fill: parent
- onClicked: {
- /* Navigate to parent folder. */
- if (folderModel.parentFolder !== "") {
- folderModel.folder = folderModel.parentFolder
- }
+ accessibleName: qsTr("Up") /* Needs to be specified as "<" is not read. */
+ onClicked: {
+ /* Navigate to parent folder. */
+ if (folderModel.parentFolder !== "") {
+ folderModel.folder = folderModel.parentFolder
}
}
}
- TextField {
+ AccessibleTextField {
id: pathField
Layout.fillWidth: true
text: stripUrlPrefix(folderModel.folder)
@@ -161,10 +173,13 @@ Dialog {
}
}
}
- } // TextField
+ }
} // RowLayout
- ListView {
+ ScrollableListView {
id: fileList
+
+ delegateHeight: imgHeightHeader
+
/* Fill remaining space with the list content. */
Layout.fillHeight: true
Layout.fillWidth: true
@@ -190,7 +205,7 @@ Dialog {
(index === selectedFileIndex) ? datovkaPalette.highlight : datovkaPalette.window
}
width: fileList.width
- height: imgHeightHeader
+ height: fileList.delegateHeight
RowLayout {
anchors.fill: parent
Text {
@@ -207,8 +222,21 @@ Dialog {
}
}
MouseArea {
- anchors.fill: parent
- onClicked: {
+ function accessibleDescriptionText() {
+ var aText = "";
+ if (fileIsDir) {
+ aText += qsTr("Open directory.");
+ } else {
+ if (isSelected(pathListModel, index) >= 0) {
+ aText += qsTr("File is selected.")
+ } else {
+ aText += qsTr("File is not selected.")
+ }
+ }
+ return aText;
+ }
+
+ function handleClick() {
if (fileIsDir) {
/* Navigate to selected directory. */
folderModel.folder = fileURL
@@ -233,6 +261,20 @@ Dialog {
}
}
}
+
+ anchors.fill: parent
+
+ Accessible.role: Accessible.Button
+ Accessible.description: accessibleDescriptionText()
+ Accessible.name: fileName
+ Accessible.onScrollDownAction: fileList.scrollDown()
+ Accessible.onScrollUpAction: fileList.scrollUp()
+ Accessible.onPressAction: {
+ handleClick()
+ }
+ onClicked: {
+ handleClick()
+ }
}
}
} // Component
diff --git a/qml/dialogues/InputDialogue.qml b/qml/dialogues/InputDialogue.qml
index 9e6595700a7f9c9c0135d7222d11e6e5612d2cb1..c17fc2023a609a2235d91b66e01096a71c7c891d 100644
--- a/qml/dialogues/InputDialogue.qml
+++ b/qml/dialogues/InputDialogue.qml
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014-2017 CZ.NIC
+ * Copyright (C) 2014-2018 CZ.NIC
*
* 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
@@ -24,6 +24,7 @@
import QtQuick 2.7
import QtQuick.Layouts 1.3
import QtQuick.Controls 2.1
+import cz.nic.mobileDatovka 1.0
/*
* Input dialog for password or OTP code.
@@ -44,16 +45,16 @@ Dialog {
dPwdType = pwdType
dUserName = userName
root.title = title
- roottext.text = text
- rootpwd.clear()
- rootpwd.placeholderText = placeholderText
- rootpwd.echoMode = (hidePwd) ? TextInput.Password : TextInput.Normal
+ rootText.text = text
+ rootPwd.clear()
+ rootPwd.placeholderText = placeholderText
+ rootPwd.echoMode = (hidePwd) ? TextInput.Password : TextInput.Normal
if (pwdType == "totp" || pwdType == "hotp") {
- rootpwd.inputMethodHints = Qt.ImhPreferNumbers
+ rootPwd.inputMethodHints = Qt.ImhPreferNumbers
} else {
- rootpwd.inputMethodHints = Qt.ImhNone
+ rootPwd.inputMethodHints = Qt.ImhNone
}
- rootpwd.focus = true
+ rootPwd.focus = true
root.open()
}
@@ -69,16 +70,16 @@ Dialog {
standardButtons: Dialog.Ok | Dialog.Cancel
contentItem: ColumnLayout {
- Text {
- id: roottext
+ AccessibleText {
+ id: rootText
Layout.fillWidth: true
Layout.minimumWidth: minimumInputSize
text: ""
Layout.alignment: Qt.AlignLeft | Qt.AlignBaseline
wrapMode: Text.WordWrap
}
- TextField {
- id: rootpwd
+ AccessibleTextField {
+ id: rootPwd
focus: true
Layout.fillWidth: true
Layout.minimumWidth: minimumInputSize
@@ -90,6 +91,6 @@ Dialog {
}
} // ColumnLayout
- onAccepted: finished(dIsdsAction, dPwdType, dUserName, rootpwd.text.toString())
+ onAccepted: finished(dIsdsAction, dPwdType, dUserName, rootPwd.text.toString())
onRejected: canceled(dIsdsAction, dUserName)
}
diff --git a/qml/dialogues/MessageDialogue.qml b/qml/dialogues/MessageDialogue.qml
index dc3920ced712fd54f99b822c71b5dd1573cf8abb..cab6c90997c018b9511598d298ca158dba31e0cd 100644
--- a/qml/dialogues/MessageDialogue.qml
+++ b/qml/dialogues/MessageDialogue.qml
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014-2017 CZ.NIC
+ * Copyright (C) 2014-2018 CZ.NIC
*
* 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
@@ -24,6 +24,7 @@
import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Dialogs 1.2
+import cz.nic.mobileDatovka 1.0
import cz.nic.mobileDatovka.dialogues 1.0
/*
@@ -72,7 +73,7 @@ Item {
anchors.fill: parent
- Text { /* Currently there is only a text information. */
+ AccessibleText { /* Currently there is only a text information. */
id: importanceText
objectName: "importanceText"
@@ -91,7 +92,7 @@ Item {
visible: dialogue.icon != Dialogues.NO_ICON
}
- Text {
+ AccessibleText {
id: messageText
objectName: "messageText"
@@ -104,7 +105,7 @@ Item {
horizontalAlignment: Text.AlignHCenter
wrapMode: Text.Wrap
}
- Text {
+ AccessibleText {
id: infoMessageText
objectName: "infoMessageText"
diff --git a/qml/dialogues/PasteInputDialogue.qml b/qml/dialogues/PasteInputDialogue.qml
index 8b2a62dfdb6a03b7f677c298e0b048e45a656751..328ded177cf73d5123924474887ed6b96c8552c7 100644
--- a/qml/dialogues/PasteInputDialogue.qml
+++ b/qml/dialogues/PasteInputDialogue.qml
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014-2017 CZ.NIC
+ * Copyright (C) 2014-2018 CZ.NIC
*
* 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
@@ -80,7 +80,7 @@ Item {
anchors.fill: parent
- Text {
+ AccessibleText {
id: messageText
objectName: "messageText"
@@ -93,7 +93,7 @@ Item {
horizontalAlignment: Text.AlignHCenter
wrapMode: Text.Wrap
}
- TextField {
+ AccessibleTextField {
id: textInput
objectName: "textInput"
diff --git a/qml/main.qml b/qml/main.qml
index 5288222452cebf372f0296a9427c086346a55bcc..7a16be08790446a6e1ae8bc18b5b5adbe7b4528d 100644
--- a/qml/main.qml
+++ b/qml/main.qml
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014-2017 CZ.NIC
+ * Copyright (C) 2014-2018 CZ.NIC
*
* 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
@@ -100,7 +100,6 @@ ApplicationWindow {
property int acntListSpacing: defaultMargin * 4
property int formItemVerticalSpacing: defaultMargin
property int formButtonHorizontalSpacing: defaultMargin * 5
- property real backMouseAreaRatio: 0.2
/* compare message delivery date with current date-90days */
property int deleteAfterDays: 90
@@ -182,7 +181,7 @@ ApplicationWindow {
Column {
anchors.centerIn: parent
spacing: formItemVerticalSpacing
- TextField {
+ AccessibleTextField {
id: pinCodeInput
height: inputItemHeight
font.pointSize: defaultTextFont.font.pointSize
@@ -205,7 +204,7 @@ ApplicationWindow {
}
}
}
- Text {
+ AccessibleText {
id: wrongPin
font.bold: true
visible: false
@@ -213,7 +212,7 @@ ApplicationWindow {
anchors.horizontalCenter: parent.horizontalCenter
text: qsTr("Wrong PIN code!")
}
- Button {
+ AccessibleButton {
text: qsTr("Enter")
anchors.horizontalCenter: parent.horizontalCenter
font.pointSize: defaultTextFont.font.pointSize
@@ -228,14 +227,14 @@ ApplicationWindow {
height: headerHeight
anchors.horizontalCenter: parent.horizontalCenter
}
- Image{
+ Image {
id: datovkaLogo
anchors.horizontalCenter: parent.horizontalCenter
width: imgHeightHeader * 1.4
height: imgHeightHeader * 1.4
source: "qrc:/datovka.png"
}
- Text {
+ AccessibleText {
id: versionLabel
anchors.horizontalCenter: parent.horizontalCenter
color: datovkaPalette.text
diff --git a/qml/pages/PageAboutApp.qml b/qml/pages/PageAboutApp.qml
index f0824a143028c5c940eab578cc53641f0ede5632..758b372a48b931772d2745e2f0b7b2bdc59aa64d 100644
--- a/qml/pages/PageAboutApp.qml
+++ b/qml/pages/PageAboutApp.qml
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014-2017 CZ.NIC
+ * Copyright (C) 2014-2018 CZ.NIC
*
* 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
@@ -23,7 +23,7 @@
import QtQuick 2.7
import QtQuick.Layouts 1.3
-import QtQuick.Controls 2.1
+import QtQuick.Controls 2.2
import cz.nic.mobileDatovka 1.0
Item {
@@ -36,16 +36,10 @@ Item {
PageHeader {
id: headerBar
title: qsTr("About Datovka")
- MouseArea {
- anchors.left: parent.left
- anchors.top: parent.top
- anchors.bottom: parent.bottom
- width: parent.width * backMouseAreaRatio
- onClicked: {
- pageView.pop(StackView.Immediate)
- }
+ onBackClicked: {
+ pageView.pop(StackView.Immediate)
}
- } // PageHeader
+ }
Flickable {
id: flickable
z: 0
@@ -54,6 +48,15 @@ Item {
anchors.left: parent.left
anchors.bottom: parent.bottom
contentHeight: flickContent.implicitHeight
+
+ /*
+ * TODO
+ * There are bugs in Qt preventing flicing on iOS when VoiceOver
+ * is activated:
+ * http://lists.qt-project.org/pipermail/accessibility/2015-March/000073.html
+ * https://bugreports.qt.io/browse/QTBUG-41980
+ */
+
Pane {
id: flickContent
anchors.fill: parent
@@ -61,58 +64,33 @@ Item {
anchors.right: parent.right
anchors.left: parent.left
spacing: formItemVerticalSpacing * 2
- Text {
- id: pageLabel
- anchors.horizontalCenter: parent.horizontalCenter
- width: parent.width
- font.bold: true
- color: datovkaPalette.text
- horizontalAlignment: Text.AlignHCenter
- wrapMode: Text.WordWrap
- text: qsTr("Datovka - free mobile Data-Box client")
- }
- Image{
+ AccessibleImageButton {
id: datovkaLogo
anchors.horizontalCenter: parent.horizontalCenter
width: imgHeightHeader * 1.4
height: imgHeightHeader * 1.4
source: "qrc:/datovka.png"
- MouseArea {
- anchors.fill: parent
- onClicked: {
- Qt.openUrlExternally("http://www.datovka.cz/")
- }
+ accessibleName: qsTr("Open application home page.")
+ onClicked: {
+ Qt.openUrlExternally("http://www.datovka.cz/")
}
}
- Text {
- id: versionLabel
- anchors.horizontalCenter: parent.horizontalCenter
- font.bold: true
- color: datovkaPalette.text
- text: qsTr("Version") + ": " + settings.appVersion()
- }
- Text {
- id: infoLabel01
+ AccessibleText {
+ id: pageLabel
anchors.horizontalCenter: parent.horizontalCenter
- color: datovkaPalette.text
width: parent.width
- textFormat: TextEdit.RichText
- horizontalAlignment: Text.AlignHCenter
- wrapMode: Text.WordWrap
- text: qsTr("This application provides the means to access data boxes in the ISDS system. It enables you to download and to view the content of messages held within the data box. You can also, with some limitations, send messages from this application.")
- }
- Text {
- id: infoLabel02
- anchors.horizontalCenter: parent.horizontalCenter
+ font.bold: true
color: datovkaPalette.text
- width: parent.width
- textFormat: TextEdit.RichText
horizontalAlignment: Text.AlignHCenter
wrapMode: Text.WordWrap
- text: qsTr("You may use this application only at your own risk. The association CZ.NIC is not the operator of the data box system. CZ.NIC is not liable for any damage that may be directly or indirectly caused by using this application.")
+ text: {
+ qsTr("Datovka - free mobile Data-Box client")
+ + "\n" +
+ qsTr("Version: %1").arg(settings.appVersion())
+ }
}
- Text {
- id: infoLabel03
+ AccessibleText {
+ id: infoLabel
anchors.horizontalCenter: parent.horizontalCenter
color: datovkaPalette.text
width: parent.width
@@ -120,27 +98,31 @@ Item {
horizontalAlignment: Text.AlignHCenter
wrapMode: Text.WordWrap
onLinkActivated: Qt.openUrlExternally(link)
- text: qsTr("If you have problems using this application or want help or you just want more information then start by reading through the information in the user manual or on the project web page.")
- .arg("https://secure.nic.cz/files/datove_schranky/redirect/mobile-manual.html")
- .arg("https://www.datovka.cz/cs/pages/mobilni-datovka.html")
+ text: {
+ qsTr("This application provides the means to access data boxes in the ISDS system. It enables you to download and to view the content of messages held within the data box. You can also, with some limitations, send messages from this application.")
+ + "
" +
+ qsTr("You may use this application only at your own risk. The association CZ.NIC is not the operator of the data box system. CZ.NIC is not liable for any damage that may be directly or indirectly caused by using this application.")
+ + "
" +
+ qsTr("If you have problems using this application or want help or you just want more information then start by reading through the information in the user manual or on the project web page.")
+ .arg("https://secure.nic.cz/files/datove_schranky/redirect/mobile-manual.html")
+ .arg("https://www.datovka.cz/cs/pages/mobilni-datovka.html")
+ }
}
- Text {
+ AccessibleText {
id: cznicLabel
anchors.horizontalCenter: parent.horizontalCenter
font.bold: true
color: datovkaPalette.text
text: qsTr("Powered by")
}
- Image{
+ AccessibleImageButton {
id: cznicLogo
anchors.horizontalCenter: parent.horizontalCenter
sourceSize.height: imgHeightHeader
source: "qrc:/cznic.png"
- MouseArea {
- anchors.fill: parent
- onClicked: {
- Qt.openUrlExternally("http://www.nic.cz/")
- }
+ accessibleName: qsTr("Open home page of the CZ.NIC association.")
+ onClicked: {
+ Qt.openUrlExternally("http://www.nic.cz/")
}
}
} // Column layout
diff --git a/qml/pages/PageAccountDetail.qml b/qml/pages/PageAccountDetail.qml
index dd001681188adb7b56d9b85bce9bbbe36458fd90..84ba6a7d901cf4c20424796007934bfcc2b310e5 100644
--- a/qml/pages/PageAccountDetail.qml
+++ b/qml/pages/PageAccountDetail.qml
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014-2017 CZ.NIC
+ * Copyright (C) 2014-2018 CZ.NIC
*
* 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
@@ -47,33 +47,25 @@ Component {
}
Component.onDestruction: {
- statusBar.visible = false
+ statusBar.visible = false
}
PageHeader {
id: headerBar
title: qsTr("Account info")
- MouseArea {
- anchors.left: parent.left
- anchors.top: parent.top
- anchors.bottom: parent.bottom
- width: parent.width * backMouseAreaRatio
- onClicked: {
- pageView.pop(StackView.Immediate)
- }
+ onBackClicked: {
+ pageView.pop(StackView.Immediate)
}
- Image {
+ AccessibleImageButton {
id: actionButton
anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right
anchors.rightMargin: defaultMargin
sourceSize.height: imgHeightHeader
source: "qrc:/ui/sync.svg"
- MouseArea {
- anchors.fill: parent
- onClicked: {
- isds.doIsdsAction("getAccountInfo", userName)
- }
+ accessibleName: qsTr("Refresh information about the account.")
+ onClicked: {
+ isds.doIsdsAction("getAccountInfo", userName)
}
Connections {
target: isds
@@ -82,7 +74,8 @@ Component {
}
}
}
- } // PageHeader
+ }
+
Flickable {
id: flickable
z: 0
@@ -94,23 +87,25 @@ Component {
Pane {
id: flickContent
anchors.fill: parent
- Text {
+ AccessibleText {
id: accountDetailText
color: datovkaPalette.text
width: parent.width
textFormat: TextEdit.RichText
wrapMode: Text.WordWrap
}
- } // Pane
+ }
ScrollIndicator.vertical: ScrollIndicator {}
- } // Flickable
- Text {
+ }
+
+ AccessibleText {
id: emptyList
visible: true
color: datovkaPalette.text
anchors.centerIn: parent
text: qsTr("Account info has not been downloaded yet.")
- } // Text
+ }
+
Connections {
target: isds
onDownloadAccountInfoFinishedSig: {
diff --git a/qml/pages/PageAccountList.qml b/qml/pages/PageAccountList.qml
index 3c8a0592b983a38073b517f23abc1390ea91a682..18f69a58b00a9daf1f8acf93a12bf808d5e2f189 100644
--- a/qml/pages/PageAccountList.qml
+++ b/qml/pages/PageAccountList.qml
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014-2017 CZ.NIC
+ * Copyright (C) 2014-2018 CZ.NIC
*
* 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
@@ -25,6 +25,7 @@ import QtQuick 2.7
import QtQuick.Controls 2.1
import QtQuick.Layouts 1.2
import QtGraphicalEffects 1.0
+import cz.nic.mobileDatovka 1.0
import cz.nic.mobileDatovka.messages 1.0
import cz.nic.mobileDatovka.models 1.0
@@ -77,21 +78,19 @@ Component {
width: parent.width
height: headerHeight
color: mainHeaderBgColor
- Image {
+ AccessibleImageButton {
id: headerLogo
anchors.left: parent.left
anchors.leftMargin: defaultMargin
anchors.verticalCenter: parent.verticalCenter
sourceSize.height: imgHeightHeader
source: "qrc:/ui/datovka@2x.png"
- MouseArea {
- anchors.fill: parent
- onClicked: {
- pageView.push(pageAboutApp, {
- "pageView": pageView,
- "statusBar": statusBar
- }, StackView.Immediate)
- }
+ accessibleName: qsTr("Show information about the application.")
+ onClicked: {
+ pageView.push(pageAboutApp, {
+ "pageView": pageView,
+ "statusBar": statusBar
+ }, StackView.Immediate)
}
}
Row {
@@ -99,58 +98,54 @@ Component {
spacing: defaultMargin
anchors.right: parent.right
anchors.rightMargin: defaultMargin
- Image {
+ AccessibleImageButton {
id: syncAllButton
anchors.verticalCenter: parent.verticalCenter
sourceSize.height: imgHeightHeader
source: "qrc:/ui/sync-all.svg"
- MouseArea {
- anchors.fill: parent
- onClicked: {
- isds.doIsdsAction("syncAllAccounts", "")
- }
+ accessibleName: qsTr("Synchronise all accounts.")
+ onClicked: {
+ isds.doIsdsAction("syncAllAccounts", "")
}
}
- Image {
+ AccessibleImageButton {
id: settingsButton
anchors.verticalCenter: parent.verticalCenter
sourceSize.height: imgHeightHeader
source: "qrc:/ui/menu.svg"
- MouseArea {
- anchors.fill: parent
- onClicked: {
- pageView.push(pageMenuDatovkaSettings, {
- "pageView": pageView,
- "statusBar": statusBar,
- "accountModel": accountModel
- }, StackView.Immediate)
- }
+ accessibleName: qsTr("Show application preferences.")
+ onClicked: {
+ pageView.push(pageMenuDatovkaSettings, {
+ "pageView": pageView,
+ "statusBar": statusBar,
+ "accountModel": accountModel
+ }, StackView.Immediate)
}
}
}
}
- Text {
+ AccessibleTextButton {
id: emptyList
visible: false
color: datovkaPalette.text
anchors.centerIn: parent
font.bold: true
text: qsTr("Add a new account")
- MouseArea {
- anchors.fill: parent
- onClicked: {
- pageView.push(pageSettingsAccount, {
- "pageView": pageView,
- "statusBar": statusBar,
- "acntName": "",
- "userName": "",
- "accountModel": accountModel
- }, StackView.Immediate)
- }
+ onClicked: {
+ pageView.push(pageSettingsAccount, {
+ "pageView": pageView,
+ "statusBar": statusBar,
+ "acntName": "",
+ "userName": "",
+ "accountModel": accountModel
+ }, StackView.Immediate)
}
}
- ListView {
+ ScrollableListView {
id: accountList
+
+ delegateHeight: headerHeight * 3
+
anchors.top: datovkaHeader.bottom
anchors.bottom: parent.bottom
clip: true
@@ -176,7 +171,7 @@ Component {
delegate: Item {
id: accountItem
width: parent.width
- height: headerHeight * 3
+ height: accountList.delegateHeight
ColumnLayout {
spacing: 0
width: parent.width
@@ -234,8 +229,7 @@ Component {
height: parent.height
color: "transparent"
MouseArea {
- anchors.fill: parent
- onClicked: {
+ function handleClick() {
statusBar.visible = false
pageView.push(pageMenuAccount, {
"pageView": pageView,
@@ -245,20 +239,31 @@ Component {
"accountModel": accountModel
}, StackView.Immediate)
}
+
+ anchors.fill: parent
+
+ Accessible.role: Accessible.Button
+ Accessible.name: !rTestAccount ? qsTr("Account '%1'.").arg(rAcntName) : qsTr("Testing account '%1'.").arg(rAcntName)
+ Accessible.onScrollDownAction: accountList.scrollDown()
+ Accessible.onScrollUpAction: accountList.scrollUp()
+ Accessible.onPressAction: {
+ handleClick()
+ }
+ onClicked: {
+ handleClick()
+ }
}
}
- Image {
+ AccessibleImageButton {
id: syncThisButton
anchors.right: parent.right
anchors.rightMargin: defaultMargin
anchors.verticalCenter: parent.verticalCenter
sourceSize.height: imgHeightHeader
source: "qrc:/ui/sync.svg"
- MouseArea {
- anchors.fill: parent
- onClicked: {
- isds.doIsdsAction("syncOneAccount", rUserName)
- }
+ accessibleName: qsTr("Synchronise account '%1'.").arg(rAcntName)
+ onClicked: {
+ isds.doIsdsAction("syncOneAccount", rUserName)
}
Connections {
target: isds
@@ -330,8 +335,7 @@ Component {
}
}
MouseArea {
- anchors.fill: parent
- onClicked: {
+ function handleClick() {
statusBar.visible = false
pageView.push(pageMessageList, {
"pageView": pageView,
@@ -342,6 +346,19 @@ Component {
"accountModel": accountModel
})
}
+
+ anchors.fill: parent
+
+ Accessible.role: Accessible.Button
+ Accessible.name: qsTr("Received messages of account '%1'. (Unread %2 of %3 received messages.)").arg(rAcntName).arg(rRcvdUnread).arg(rRcvdTotal)
+ Accessible.onScrollDownAction: accountList.scrollDown()
+ Accessible.onScrollUpAction: accountList.scrollUp()
+ Accessible.onPressAction: {
+ handleClick()
+ }
+ onClicked: {
+ handleClick()
+ }
}
Rectangle {
anchors.bottom: parent.bottom
@@ -399,8 +416,7 @@ Component {
}
}
MouseArea {
- anchors.fill: parent
- onClicked: {
+ function handleClick() {
statusBar.visible = false
pageView.push(pageMessageList, {
"pageView": pageView,
@@ -411,6 +427,19 @@ Component {
"accountModel": accountModel
})
}
+
+ anchors.fill: parent
+
+ Accessible.role: Accessible.Button
+ Accessible.name: qsTr("Sent messages of account '%1'. (Total of %2 sent messages.)").arg(rAcntName).arg(rSntTotal)
+ Accessible.onScrollDownAction: accountList.scrollDown()
+ Accessible.onScrollUpAction: accountList.scrollUp()
+ Accessible.onPressAction: {
+ handleClick()
+ }
+ onClicked: {
+ handleClick()
+ }
}
Rectangle {
anchors.bottom: parent.bottom
diff --git a/qml/pages/PageChangePassword.qml b/qml/pages/PageChangePassword.qml
index dc3f5bff68090a9b2374e9166d9db0d16da67182..bc73afd171002bdcd6c07ecfa6fed451a7046d80 100644
--- a/qml/pages/PageChangePassword.qml
+++ b/qml/pages/PageChangePassword.qml
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014-2017 CZ.NIC
+ * Copyright (C) 2014-2018 CZ.NIC
*
* 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
@@ -61,58 +61,50 @@ Item {
PageHeader {
id: headerBar
title: qsTr("Change password") + ": " + userName
- MouseArea {
- anchors.left: parent.left
- anchors.top: parent.top
- anchors.bottom: parent.bottom
- width: parent.width * backMouseAreaRatio
- onClicked: {
- pageView.pop(StackView.Immediate)
- }
+ onBackClicked: {
+ pageView.pop(StackView.Immediate)
}
Row {
anchors.verticalCenter: parent.verticalCenter
spacing: defaultMargin
anchors.right: parent.right
anchors.rightMargin: defaultMargin
- Image {
+ AccessibleImageButton {
id: actionButton
anchors.verticalCenter: parent.verticalCenter
sourceSize.height: imgHeightHeader
source: "qrc:/ui/checkbox-marked-circle.svg"
- MouseArea {
- anchors.fill: parent
- onClicked: {
- if (oldPwd.text == "" || newPwd.text == "") {
- errLineText.text = qsTr("Old password and new password must be filled!")
- errLineText.visible = true
- } else {
- if (newPwd.text == newPwdAgain.text) {
- if (isds.isCorrectPassword(newPwd.text.toString())) {
- if (loginMethod == "totp" && otpCode.text == "") {
- errLineText.text = qsTr("SMS code must be filled!")
- errLineText.visible = true
- } else if (loginMethod == "hotp" && otpCode.text == "") {
- errLineText.text = qsTr("Security code must be filled!")
- errLineText.visible = true
+ accessibleName: qsTr("Accept changes")
+ onClicked: {
+ if (oldPwd.text == "" || newPwd.text == "") {
+ errLineText.text = qsTr("Old password and new password must be filled!")
+ errLineText.visible = true
+ } else {
+ if (newPwd.text == newPwdAgain.text) {
+ if (isds.isCorrectPassword(newPwd.text.toString())) {
+ if (loginMethod == "totp" && otpCode.text == "") {
+ errLineText.text = qsTr("SMS code must be filled!")
+ errLineText.visible = true
+ } else if (loginMethod == "hotp" && otpCode.text == "") {
+ errLineText.text = qsTr("Security code must be filled!")
+ errLineText.visible = true
+ } else {
+ errLineText.visible = false
+ if (isds.changePassword(userName, oldPwd.text.toString(), newPwd.text.toString(), otpCode.text.toString())) {
+ settings.saveAllSettings(accountModel)
+ pageView.pop(StackView.Immediate)
} else {
- errLineText.visible = false
- if (isds.changePassword(userName, oldPwd.text.toString(), newPwd.text.toString(), otpCode.text.toString())) {
- settings.saveAllSettings(accountModel)
- pageView.pop(StackView.Immediate)
- } else {
- errLineText.text = qsTr("Password change failed!")
- errLineText.visible = true
- }
+ errLineText.text = qsTr("Password change failed!")
+ errLineText.visible = true
}
- } else {
- errLineText.text = qsTr("Wrong password format! The new password must contain at least 8 characters including at least 1 number and at least 1 upper-case letter.")
- errLineText.visible = true
- }
+ }
} else {
- errLineText.text = qsTr("The entered new passwords do not match!")
+ errLineText.text = qsTr("Wrong password format! The new password must contain at least 8 characters including at least 1 number and at least 1 upper-case letter.")
errLineText.visible = true
}
+ } else {
+ errLineText.text = qsTr("The entered new passwords do not match!")
+ errLineText.visible = true
}
}
}
@@ -134,7 +126,7 @@ Item {
anchors.right: parent.right
anchors.left: parent.left
spacing: formItemVerticalSpacing
- Text {
+ AccessibleText {
id: topLineText
anchors.horizontalCenter: parent.horizontalCenter
color: datovkaPalette.mid
@@ -146,7 +138,7 @@ Item {
Column {
anchors.horizontalCenter: parent.horizontalCenter
spacing: formItemVerticalSpacing
- TextField {
+ AccessibleTextField {
id: oldPwd
// Fit widest element.
anchors.left: parent.left
@@ -160,7 +152,7 @@ Item {
horizontalAlignment: TextInput.AlignHCenter
text: ""
}
- TextField {
+ AccessibleTextField {
id: newPwd
// Fit widest element.
anchors.left: parent.left
@@ -174,7 +166,7 @@ Item {
horizontalAlignment: TextInput.AlignHCenter
text: ""
}
- TextField {
+ AccessibleTextField {
id: newPwdAgain
// Widest element.
anchors.horizontalCenter: parent.horizontalCenter
@@ -187,7 +179,7 @@ Item {
horizontalAlignment: TextInput.AlignHCenter
text: ""
}
- Text {
+ AccessibleText {
id: errLineText
visible: false
anchors.horizontalCenter: parent.horizontalCenter
@@ -198,7 +190,7 @@ Item {
horizontalAlignment: Text.AlignHCenter
wrapMode: Text.Wrap
}
- Button {
+ AccessibleButton {
id: sendSmsButton
visible: false
enabled: false
@@ -227,7 +219,7 @@ Item {
}
}
}
- TextField {
+ AccessibleTextField {
id: otpCode
visible: false
anchors.left: parent.left
diff --git a/qml/pages/PageContactList.qml b/qml/pages/PageContactList.qml
index 7e981b661da0c46581d1a66fb0d3f925c6c71952..a0a8ac5c6b20f2a354ae0255554754a74f2c9ed0 100644
--- a/qml/pages/PageContactList.qml
+++ b/qml/pages/PageContactList.qml
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014-2017 CZ.NIC
+ * Copyright (C) 2014-2018 CZ.NIC
*
* 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
@@ -46,7 +46,7 @@ Item {
messages.fillContactList(foundBoxModel, userName, currentBoxId)
if (foundBoxModel.rowCount() === 0) {
emptyList.visible = true
- searchButton.visible = false
+ filterButton.visible = false
}
if (recipBoxModel != null) {
foundBoxModel.selectEntries(recipBoxModel.boxIds(), true)
@@ -73,90 +73,56 @@ Item {
PageHeader {
id: headerBar
title: qsTr("Contacts")
- MouseArea {
- anchors.left: parent.left
- anchors.top: parent.top
- anchors.bottom: parent.bottom
- width: parent.width * backMouseAreaRatio
- onClicked: {
- pageView.pop(StackView.Immediate)
- }
+ onBackClicked: {
+ pageView.pop(StackView.Immediate)
}
Row {
anchors.verticalCenter: parent.verticalCenter
spacing: defaultMargin
anchors.right: parent.right
anchors.rightMargin: defaultMargin
- Image {
- id: searchButton
+ AccessibleImageButton {
+ id: filterButton
anchors.verticalCenter: parent.verticalCenter
sourceSize.height: imgHeightHeader
source: "qrc:/ui/magnify.svg"
- MouseArea {
- anchors.fill: parent
- onClicked: {
- databoxList.anchors.top = filterBar.bottom
- filterBar.visible = true
- filter.forceActiveFocus()
- Qt.inputMethod.show()
- }
+ accessibleName: qsTr("Filter data boxes.")
+ onClicked: {
+ databoxList.anchors.top = filterBar.bottom
+ filterBar.visible = true
+ filterBar.filterField.forceActiveFocus()
+ Qt.inputMethod.show()
}
}
}
} // PageHeader
- Rectangle {
+ FilterBar {
id: filterBar
visible: false
z: 1
anchors.top: headerBar.bottom
width: parent.width
- height: filter.height
- color: (filter.text.length == 0) ? datovkaPalette.alternateBase :
+ height: filterField.height
+ color: (filterField.text.length == 0) ? datovkaPalette.alternateBase :
(databoxList.count > 0) ? "#afffaf" : "#ffafaf"
- border.color: filter.activeFocus ? "#0066ff" : "#bdbebf"
- TextField {
- id: filter
- anchors.top: parent.top
- width: parent.width - close.width
- placeholderText: qsTr("Set filter")
- font.pointSize: defaultTextFont.font.pointSize
- inputMethodHints: Qt.ImhNoPredictiveText
- /*
- * Using explicit top, left, ... padding because plain padding
- * does not centre the text properly.
- */
- topPadding: 8.0
- bottomPadding: 8.0
- leftPadding: 8.0
- rightPadding: 8.0
- /* TODO - remove background if used materials */
- background: Rectangle {
- anchors.fill: parent
- color: "transparent"
- border.color: "transparent"
- }
- onTextChanged: {
- proxyDataboxModel.setFilterRegExpStr(filter.text)
- }
+ border.color: filterField.activeFocus ? "#0066ff" : "#bdbebf"
+
+ placeholderText: qsTr("Set filter")
+ fontPointSize: defaultTextFont.font.pointSize
+ buttonImageHeight: imgHeight
+ buttonAccessibleName: qsTr("Clear and hide filter field")
+
+ onTextChanged: {
+ proxyDataboxModel.setFilterRegExpStr(text)
}
- Image {
- id: close
- anchors.right: parent.right
- anchors.verticalCenter: parent.verticalCenter
- sourceSize.height: imgHeight
- source: "qrc:/ui/remove.svg"
- MouseArea {
- anchors.fill: parent
- onClicked: {
- filterBar.visible = false
- filter.clear()
- databoxList.anchors.top = headerBar.bottom
- Qt.inputMethod.hide()
- }
- }
+
+ onClearClicked: {
+ filterBar.visible = false
+ databoxList.anchors.top = headerBar.bottom
+ Qt.inputMethod.hide()
}
- } // Rectangle
- Text {
+ }
+ AccessibleText {
id: emptyList
visible: false
color: datovkaPalette.text
diff --git a/qml/pages/PageDataboxDetail.qml b/qml/pages/PageDataboxDetail.qml
index 649c424c454e76c853132f1cb9f4d7d1ab0b4784..5e1d90bc07e35a775ffd64b9d914ac918a4d45c0 100644
--- a/qml/pages/PageDataboxDetail.qml
+++ b/qml/pages/PageDataboxDetail.qml
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014-2017 CZ.NIC
+ * Copyright (C) 2014-2018 CZ.NIC
*
* 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
@@ -40,25 +40,15 @@ Component {
Component.onCompleted: {
isds.doIsdsAction("findDatabox", userName)
}
- Connections {
- target: isds
- onRunFindDataboxSig: {
- databoxDetailText.text = isds.findDatabox(userName, dbID, dbType)
- }
- }
+
PageHeader {
id: headerBar
title: qsTr("Databox info")
- MouseArea {
- anchors.left: parent.left
- anchors.top: parent.top
- anchors.bottom: parent.bottom
- width: parent.width * backMouseAreaRatio
- onClicked: {
- pageView.pop(StackView.Immediate)
- }
+ onBackClicked: {
+ pageView.pop(StackView.Immediate)
}
- } // PageHeader
+ }
+
Flickable {
id: flickable
z: 0
@@ -70,15 +60,22 @@ Component {
Pane {
id: flickContent
anchors.fill: parent
- Text {
+ AccessibleText {
id: databoxDetailText
color: datovkaPalette.text
width: parent.width
textFormat: TextEdit.RichText
wrapMode: Text.WordWrap
}
- } // Pane
+ }
ScrollIndicator.vertical: ScrollIndicator {}
- } // Flickable
+ }
+
+ Connections {
+ target: isds
+ onRunFindDataboxSig: {
+ databoxDetailText.text = isds.findDatabox(userName, dbID, dbType)
+ }
+ }
}
}
diff --git a/qml/pages/PageDataboxSearch.qml b/qml/pages/PageDataboxSearch.qml
index 222b97ea89ab30ebb4ab5bec5404762e1bba342e..06312f9777353c1f7394f373091fe3de5fcc70f7 100644
--- a/qml/pages/PageDataboxSearch.qml
+++ b/qml/pages/PageDataboxSearch.qml
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014-2017 CZ.NIC
+ * Copyright (C) 2014-2018 CZ.NIC
*
* 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
@@ -78,47 +78,37 @@ Item {
PageHeader {
id: headerBar
title: qsTr("Find databox")
- MouseArea {
- anchors.left: parent.left
- anchors.top: parent.top
- anchors.bottom: parent.bottom
- width: parent.width * backMouseAreaRatio
- onClicked: {
- pageView.pop(StackView.Immediate)
- }
+ onBackClicked: {
+ pageView.pop(StackView.Immediate)
}
Row {
anchors.verticalCenter: parent.verticalCenter
spacing: defaultMargin
anchors.right: parent.right
anchors.rightMargin: defaultMargin
- Image {
- id: searchButton
+ AccessibleImageButton {
+ id: filterButton
visible: false
anchors.verticalCenter: parent.verticalCenter
sourceSize.height: imgHeightHeader
source: "qrc:/ui/magnify.svg"
- MouseArea {
- anchors.fill: parent
- onClicked: {
- databoxList.anchors.top = filterBar.bottom
- filterBar.visible = true
- filter.forceActiveFocus()
- Qt.inputMethod.show()
- }
+ accessibleName: qsTr("Filter data boxes.")
+ onClicked: {
+ databoxList.anchors.top = filterBar.bottom
+ filterBar.visible = true
+ filterBar.filterField.forceActiveFocus()
+ Qt.inputMethod.show()
}
}
- Image {
+ AccessibleImageButton {
id: actionButton
anchors.verticalCenter: parent.verticalCenter
sourceSize.height: imgHeightHeader
source: "qrc:/ui/account-search.svg"
- MouseArea {
- anchors.fill: parent
- onClicked: {
- searchPhraseText.focus = false
- searchPanel.doSearchRequest()
- }
+ accessibleName: qsTr("Search data boxes.")
+ onClicked: {
+ searchPhraseText.focus = false
+ searchPanel.doSearchRequest()
}
}
}
@@ -134,66 +124,36 @@ Item {
anchors.right: parent.right
anchors.left: parent.left
spacing: formItemVerticalSpacing
- ComboBox {
+ AccessibleComboBox {
id: searchScopeComboBox
- currentIndex: 0
width: parent.width
- height: inputItemHeight
- textRole: "label"
- font.pointSize: defaultTextFont.font.pointSize
- delegate: ItemDelegate {
- width: searchScopeComboBox.width
- height: inputItemHeight
- contentItem: Text {
- text: label
- color: datovkaPalette.text
- font.pointSize: defaultTextFont.font.pointSize
- elide: Text.ElideRight
- verticalAlignment: Text.AlignVCenter
- }
- highlighted: searchScopeComboBox.highlightedIndex == index
- }
+ accessibleDescription: qsTr("Select type of sought data box")
model: ListModel {
id: searchScopeComboBoxModel
- ListElement { label: qsTr("All databoxes"); value: "ALL" }
- ListElement { label: qsTr("OVM"); value: "OVM" }
- ListElement { label: qsTr("PO"); value: "PO" }
- ListElement { label: qsTr("PFO"); value: "PFO" }
- ListElement { label: qsTr("FO"); value: "FO" }
+ ListElement { label: qsTr("All databoxes"); key: "ALL" }
+ ListElement { label: qsTr("OVM"); key: "OVM" }
+ ListElement { label: qsTr("PO"); key: "PO" }
+ ListElement { label: qsTr("PFO"); key: "PFO" }
+ ListElement { label: qsTr("FO"); key: "FO" }
}
- onCurrentIndexChanged: searchScope = searchScopeComboBoxModel.get(currentIndex).value
+ onCurrentIndexChanged: searchScope = currentKey()
}
- ComboBox {
+ AccessibleComboBox {
id: searchTypeComboBox
- currentIndex: 0
width: parent.width
- height: inputItemHeight
- textRole: "label"
- font.pointSize: defaultTextFont.font.pointSize
- delegate: ItemDelegate {
- width: searchTypeComboBox.width
- height: inputItemHeight
- contentItem: Text {
- text: label
- color: datovkaPalette.text
- font.pointSize: defaultTextFont.font.pointSize
- elide: Text.ElideRight
- verticalAlignment: Text.AlignVCenter
- }
- highlighted: searchTypeComboBox.highlightedIndex == index
- }
+ accessibleDescription: qsTr("Select entries to search in")
model: ListModel {
id: searchTypeComboBoxModel
- ListElement { label: qsTr("All fields"); value: "GENERAL" }
- ListElement { label: qsTr("Address"); value: "ADDRESS" }
- ListElement { label: qsTr("IČ"); value: "ICO" }
- ListElement { label: qsTr("Databox ID"); value: "DBID" }
+ ListElement { label: qsTr("All fields"); key: "GENERAL" }
+ ListElement { label: qsTr("Address"); key: "ADDRESS" }
+ ListElement { label: qsTr("IČ"); key: "ICO" }
+ ListElement { label: qsTr("Databox ID"); key: "DBID" }
}
- onCurrentIndexChanged: searchType = searchTypeComboBoxModel.get(currentIndex).value
+ onCurrentIndexChanged: searchType = currentKey()
}
- TextField {
+ AccessibleTextField {
id: searchPhraseText
- placeholderText: qsTr("Enter phrase")
+ placeholderText: qsTr("Enter sought phrase")
focus: true
width: parent.width
font.pointSize: defaultTextFont.font.pointSize
@@ -237,8 +197,8 @@ Item {
color: enabled ? headerColor : datovkaPalette.mid
}
MouseArea {
- anchors.fill: parent
- onClicked: {
+ /* TODO -- Make this a separate component (image button?). */
+ function handleClick() {
if (page > 0) {
page = page-1
}
@@ -247,9 +207,20 @@ Item {
foundBoxModel.selectEntries(recipBoxModel.boxIds(), true)
}
}
+
+ anchors.fill: parent
+
+ Accessible.role: Accessible.Button
+ Accessible.name: qsTr("Previous")
+ Accessible.onPressAction: {
+ handleClick()
+ }
+ onClicked: {
+ handleClick()
+ }
}
}
- Text {
+ AccessibleText {
id: searchResultText
color: datovkaPalette.text
text: ""
@@ -276,72 +247,57 @@ Item {
color: enabled ? headerColor : datovkaPalette.mid
}
MouseArea {
- anchors.fill: parent
- onClicked: {
+ /* TODO -- Make this a separate component (image button?). */
+ function handleClick() {
page = page+1
isds.findDataboxFulltext(userName, foundBoxModel, searchTextTmp, searchTypeTmp, searchScopeTmp, page)
if (recipBoxModel != null) {
foundBoxModel.selectEntries(recipBoxModel.boxIds(), true)
}
}
+
+ anchors.fill: parent
+
+ Accessible.role: Accessible.Button
+ Accessible.name: qsTr("Next")
+ Accessible.onPressAction: {
+ handleClick()
+ }
+ onClicked: {
+ handleClick()
+ }
}
} // Rectangle
} // Item
} // Column
} // Pane
- Rectangle {
+ FilterBar {
id: filterBar
visible: false
z: 1
anchors.top: searchPanel.bottom
width: parent.width
- height: filter.height
- color: (filter.text.length == 0) ? datovkaPalette.alternateBase :
+ height: filterField.height
+ color: (filterField.text.length == 0) ? datovkaPalette.alternateBase :
(databoxList.count > 0) ? "#afffaf" : "#ffafaf"
- border.color: filter.activeFocus ? "#0066ff" : "#bdbebf"
- TextField {
- id: filter
- anchors.top: parent.top
- width: parent.width - close.width
- placeholderText: qsTr("Set filter")
- font.pointSize: defaultTextFont.font.pointSize
- inputMethodHints: Qt.ImhNoPredictiveText
- /*
- * Using explicit top, left, ... padding because plain padding
- * does not centre the text properly.
- */
- topPadding: 8.0
- bottomPadding: 8.0
- leftPadding: 8.0
- rightPadding: 8.0
- /* TODO - remove background if used materials */
- background: Rectangle {
- anchors.fill: parent
- color: "transparent"
- border.color: "transparent"
- }
- onTextChanged: {
- proxyDataboxModel.setFilterRegExpStr(filter.text)
- }
+ border.color: filterField.activeFocus ? "#0066ff" : "#bdbebf"
+
+ placeholderText: qsTr("Set filter")
+ fontPointSize: defaultTextFont.font.pointSize
+ buttonImageHeight: imgHeight
+ buttonAccessibleName: qsTr("Clear and hide filter field")
+
+ onTextChanged: {
+ proxyDataboxModel.setFilterRegExpStr(text)
}
- Image {
- id: close
- anchors.right: parent.right
- anchors.verticalCenter: parent.verticalCenter
- sourceSize.height: imgHeight
- source: "qrc:/ui/remove.svg"
- MouseArea {
- anchors.fill: parent
- onClicked: {
- filterBar.visible = false
- filter.clear()
- databoxList.anchors.top = searchPanel.bottom
- Qt.inputMethod.hide()
- }
- }
+
+ onClearClicked: {
+ filterBar.visible = false
+ databoxList.anchors.top = searchPanel.bottom
+ Qt.inputMethod.hide()
}
- } // Rectangle
- Text {
+ }
+ AccessibleText {
id: emptyList
visible: false
color: datovkaPalette.text
@@ -409,9 +365,10 @@ Item {
isds.findDataboxFulltext(userName, foundBoxModel, searchPhraseText.text, searchType, searchScope, page)
if (foundBoxModel.rowCount() <= 0) {
emptyList.visible = true
- searchButton.visible = false
+ filterButton.visible = false
} else {
- searchButton.visible = true
+ emptyList.visible = false
+ filterButton.visible = true
}
if (recipBoxModel != null) {
foundBoxModel.selectEntries(recipBoxModel.boxIds(), true)
diff --git a/qml/pages/PageMenuAccount.qml b/qml/pages/PageMenuAccount.qml
index 5c3f3907883b9ee403d33c8bfc3fa4cfd01b3c10..2ecba80c1a507826fb2857bc938831b1ebd68b8a 100644
--- a/qml/pages/PageMenuAccount.qml
+++ b/qml/pages/PageMenuAccount.qml
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014-2017 CZ.NIC
+ * Copyright (C) 2014-2018 CZ.NIC
*
* 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
@@ -23,7 +23,6 @@
import QtQuick 2.7
import QtQuick.Controls 2.1
-import QtGraphicalEffects 1.0
import cz.nic.mobileDatovka 1.0
Component {
@@ -41,164 +40,120 @@ Component {
PageHeader {
id: headerBar
title: qsTr("Account properties")
- MouseArea {
- anchors.left: parent.left
- anchors.top: parent.top
- anchors.bottom: parent.bottom
- width: parent.width * backMouseAreaRatio
- onClicked: {
+ onBackClicked: {
+ pageView.pop(StackView.Immediate)
+ }
+ }
+
+ /* Object (associative array) holding functions. */
+ property var funcs: {
+ "accSett": function callAccSett() {
+ pageView.replace(pageSettingsAccount, {
+ "pageView": pageView,
+ "statusBar": statusBar,
+ "acntName": acntName,
+ "userName": userName,
+ "accountModel": accountModel
+ }, StackView.Immediate)
+ },
+ "viewAcntInfo": function callViewAcntInfo() {
+ pageView.replace(pageAccountDetail, {
+ "pageView": pageView,
+ "statusBar": statusBar,
+ "acntName": acntName,
+ "userName": userName
+ }, StackView.Immediate)
+ },
+ "createMsg": function callCreateMsg() {
+ pageView.replace(pageSendMessage, {
+ "pageView": pageView,
+ "statusBar": statusBar,
+ "acntName" : acntName,
+ "userName": userName,
+ "action": "new"
+ }, StackView.Immediate)
+ },
+ "findBox": function callFindBox() {
+ pageView.replace(pageDataboxSearch, {
+ "pageView": pageView,
+ "statusBar": statusBar,
+ "userName": userName,
+ }, StackView.Immediate)
+ },
+ "cleanDb": function callCleanDb() {
+ files.deleteFileDb(userName)
+ },
+ "changePwd": function callChangePwd() {
+ pageView.replace(pageChangePassword, {
+ "pageView": pageView,
+ "statusBar": statusBar,
+ "acntName": acntName,
+ "userName": userName,
+ "accountModel": accountModel
+ }, StackView.Immediate)
+ },
+ "delAcnt": function callDelAcnt() {
+ if (accounts.removeAccount(accountModel, userName, true)) {
+ settings.saveAllSettings(accountModel)
pageView.pop(StackView.Immediate)
}
}
}
+
ListModel {
id: accountMenuListModel
ListElement {
- index: 0
- name: qsTr("Account settings")
image: "qrc:/ui/settings.svg"
+ showEntry: true
showNext: true
+ name: qsTr("Account settings")
+ funcName: "accSett"
}
ListElement {
- index: 1
- name: qsTr("View account info")
image: "qrc:/ui/account-box.svg"
+ showEntry: true
showNext: true
+ name: qsTr("View account info")
+ funcName: "viewAcntInfo"
}
ListElement {
- index: 6
- name: qsTr("Create message")
image: "qrc:/ui/pencil-box-outline.svg"
+ showEntry: true
showNext: true
+ name: qsTr("Create message")
+ funcName: "createMsg"
}
ListElement {
- index: 5
- name: qsTr("Find databox")
image: "qrc:/ui/account-search.svg"
+ showEntry: true
showNext: true
+ name: qsTr("Find databox")
+ funcName: "findBox"
}
ListElement {
- index: 2
- name: qsTr("Clean up the file database")
image: "qrc:/ui/database.svg"
+ showEntry: true
showNext: false
+ name: qsTr("Clean up the file database")
+ funcName: "cleanDb"
}
ListElement {
- index: 3
- name: qsTr("Change password")
image: "qrc:/ui/account-key.svg"
+ showEntry: true
showNext: false
+ name: qsTr("Change password")
+ funcName: "changePwd"
}
ListElement {
- index: 4
- name: qsTr("Delete account")
image: "qrc:/ui/account-remove.svg"
+ showEntry: true
showNext: false
+ name: qsTr("Delete account")
+ funcName: "delAcnt"
}
}
- Component {
- id: accountMenuComponent
- Rectangle {
- color: datovkaPalette.base
- height: headerHeight
- width: parent.width
- Image {
- id: menuImage
- anchors.verticalCenter: parent.verticalCenter
- anchors.left: parent.left
- anchors.leftMargin: defaultMargin
- sourceSize.height: imgHeight
- source: image
- }
- ColorOverlay {
- anchors.fill: menuImage
- source: menuImage
- color: datovkaPalette.text
- }
- Text {
- anchors.verticalCenter: parent.verticalCenter
- anchors.left: menuImage.right
- anchors.leftMargin: defaultMargin
- color: datovkaPalette.text
- text: name
- }
- Rectangle {
- id: next2
- visible: showNext
- anchors.verticalCenter: parent.verticalCenter
- anchors.right: parent.right
- height: parent.height
- width: parent.width * 0.07
- color: parent.color
- Image {
- id: nextImage2
- anchors.verticalCenter: parent.verticalCenter
- anchors.right: parent.right
- anchors.rightMargin: defaultMargin
- sourceSize.height: navImgHeight
- source: "qrc:/ui/next.svg"
- }
- ColorOverlay {
- anchors.fill: nextImage2
- source: nextImage2
- color: datovkaPalette.text
- }
- }
- MouseArea {
- anchors.fill: parent
- onClicked: {
- if (index == 0) {
- pageView.replace(pageSettingsAccount, {
- "pageView": pageView,
- "statusBar": statusBar,
- "acntName": acntName,
- "userName": userName,
- "accountModel": accountModel
- }, StackView.Immediate)
- } else if (index == 1) {
- pageView.replace(pageAccountDetail, {
- "pageView": pageView,
- "statusBar": statusBar,
- "acntName": acntName,
- "userName": userName
- }, StackView.Immediate)
- } else if (index == 2) {
- files.deleteFileDb(userName)
- } else if (index == 3) {
- pageView.replace(pageChangePassword, {
- "pageView": pageView,
- "statusBar": statusBar,
- "acntName": acntName,
- "userName": userName,
- "accountModel": accountModel
- }, StackView.Immediate)
- } else if (index == 4) {
- if (accounts.removeAccount(accountModel, userName, true)) {
- settings.saveAllSettings(accountModel)
- pageView.pop(StackView.Immediate)
- }
- } else if (index == 5) {
- pageView.replace(pageDataboxSearch, {
- "pageView": pageView,
- "statusBar": statusBar,
- "userName": userName,
- }, StackView.Immediate)
- } else if (index == 6) {
- pageView.replace(pageSendMessage, {
- "pageView": pageView,
- "statusBar": statusBar,
- "acntName" : acntName,
- "userName": userName,
- "action": "new"
- }, StackView.Immediate)
- } else {
- pageView.pop(StackView.Immediate)
- }
- }
- }
- }
- }
- ListView {
+
+ AccessibleMenu {
id: accountMenuList
anchors.top: headerBar.bottom
anchors.bottom: parent.bottom
@@ -206,8 +161,9 @@ Component {
clip: true
spacing: 1
opacity: 1
+
+ funcArr: funcs
model: accountMenuListModel
- delegate: accountMenuComponent
}
}
}
diff --git a/qml/pages/PageMenuDatovkaSettings.qml b/qml/pages/PageMenuDatovkaSettings.qml
index 4b3a1b2f3c9a4d7e8a7543a1248672fa2d95f76a..8a078696c6859449e7b51d7a82c751ff617b5afe 100644
--- a/qml/pages/PageMenuDatovkaSettings.qml
+++ b/qml/pages/PageMenuDatovkaSettings.qml
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014-2017 CZ.NIC
+ * Copyright (C) 2014-2018 CZ.NIC
*
* 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
@@ -23,7 +23,6 @@
import QtQuick 2.7
import QtQuick.Controls 2.1
-import QtGraphicalEffects 1.0
import cz.nic.mobileDatovka 1.0
Component {
@@ -40,175 +39,133 @@ Component {
if (accountModel.rowCount() <= 0) {
// Hide some menu items
// Note: remove argument is ListModel item index
- settingsListModel.remove(1)
+ settingsMenuListModel.remove(1)
}
}
PageHeader {
id: headerBar
title: qsTr("Settings")
- MouseArea {
- anchors.left: parent.left
- anchors.top: parent.top
- anchors.bottom: parent.bottom
- width: parent.width * backMouseAreaRatio
- onClicked: {
- pageView.pop(StackView.Immediate)
- }
+ onBackClicked: {
+ pageView.pop(StackView.Immediate)
}
}
+
+ /* Object (associative array) holding functions. */
+ property var funcs: {
+ "addAcnt": function callAddAcnt() {
+ pageView.replace(pageSettingsAccount, {
+ "pageView": pageView,
+ "statusBar": statusBar,
+ "acntName": "",
+ "userName": "",
+ "accountModel": accountModel
+ }, StackView.Immediate)
+ },
+ "searchMsg": function callSearchMsg() {
+ pageView.replace(pageMessageSearch, {
+ "pageView": pageView,
+ "statusBar": statusBar
+ }, StackView.Immediate)
+ },
+ "settGeneral": function callSettGeneral() {
+ pageView.replace(pageSettingsGeneral, {
+ "pageView": pageView,
+ "statusBar": statusBar,
+ "accountModel": accountModel
+ }, StackView.Immediate)
+ },
+ "settSync": function callSettSync() {
+ pageView.replace(pageSettingsSync, {
+ "pageView": pageView,
+ "statusBar": statusBar,
+ "accountModel": accountModel
+ }, StackView.Immediate)
+ },
+ "settStorage": function callSettStorage() {
+ pageView.replace(pageSettingsStorage, {
+ "pageView": pageView,
+ "statusBar": statusBar,
+ "accountModel": accountModel
+ }, StackView.Immediate)
+ },
+ "settSecPin": function callSettSecPin() {
+ pageView.replace(pageSettingsPin, {
+ "pageView": pageView,
+ "statusBar": statusBar,
+ "accountModel": accountModel
+ }, StackView.Immediate)
+ },
+ "userGuide": function callUserGuide() {
+ Qt.openUrlExternally("https://secure.nic.cz/files/datove_schranky/redirect/mobile-manual.html")
+ pageView.pop(StackView.Immediate)
+ }
+ }
+
ListModel {
- id: settingsListModel
+ id: settingsMenuListModel
ListElement {
- index: 0
- name: qsTr("Add account")
image: "qrc:/ui/account-plus.svg"
+ showEntry: true
showNext: true
+ name: qsTr("Add account")
+ funcName: "addAcnt"
}
ListElement {
- index: 1
- name: qsTr("Search message")
image: "qrc:/ui/magnify.svg"
+ showEntry: true
showNext: true
+ name: qsTr("Search message")
+ funcName: "searchMsg"
}
ListElement {
- index: 2
- name: qsTr("General")
image: "qrc:/ui/settings.svg"
+ showEntry: true
showNext: true
+ name: qsTr("General")
+ funcName: "settGeneral"
}
ListElement {
- index: 3
- name: qsTr("Synchronization")
image: "qrc:/ui/sync-all.svg"
+ showEntry: true
showNext: true
+ name: qsTr("Synchronization")
+ funcName: "settSync"
}
ListElement {
- index: 4
- name: qsTr("Storage")
image: "qrc:/ui/database.svg"
+ showEntry: true
showNext: true
+ name: qsTr("Storage")
+ funcName: "settStorage"
}
ListElement {
- index: 5
- name: qsTr("Security and PIN")
image: "qrc:/ui/key-variant.svg"
+ showEntry: true
showNext: true
+ name: qsTr("Security and PIN")
+ funcName: "settSecPin"
}
ListElement {
- index: 6
- name: qsTr("User Guide")
image: "qrc:/ui/information.svg"
+ showEntry: true
showNext: false
+ name: qsTr("User Guide")
+ funcName: "userGuide"
}
}
- Component {
- id: settingsComponent
- Rectangle {
- color: datovkaPalette.base
- height: headerHeight
- width: parent.width
- Image {
- id: msgSentImage
- anchors.verticalCenter: parent.verticalCenter
- anchors.left: parent.left
- anchors.leftMargin: defaultMargin
- sourceSize.height: imgHeight
- source: image
- }
- ColorOverlay {
- anchors.fill: msgSentImage
- source: msgSentImage
- color: datovkaPalette.text
- }
- Text {
- anchors.verticalCenter: parent.verticalCenter
- anchors.left: msgSentImage.right
- anchors.leftMargin: defaultMargin
- color: datovkaPalette.text
- text: name
- }
- Rectangle {
- visible: showNext
- anchors.verticalCenter: parent.verticalCenter
- anchors.right: parent.right
- height: parent.height
- width: parent.width * 0.07
- color: parent.color
- Image {
- id: nextImage
- anchors.verticalCenter: parent.verticalCenter
- anchors.right: parent.right
- anchors.rightMargin: defaultMargin
- sourceSize.height: navImgHeight
- source: "qrc:/ui/next.svg"
- }
- ColorOverlay {
- anchors.fill: nextImage
- source: nextImage
- color: datovkaPalette.text
- }
- }
- MouseArea {
- anchors.fill: parent
- onClicked: {
- if (index == 0) {
- pageView.replace(pageSettingsAccount, {
- "pageView": pageView,
- "statusBar": statusBar,
- "acntName": "",
- "userName": "",
- "accountModel": accountModel
- }, StackView.Immediate)
- } else if (index == 1) {
- pageView.replace(pageMessageSearch, {
- "pageView": pageView,
- "statusBar": statusBar
- }, StackView.Immediate)
- } else if (index == 2) {
- pageView.replace(pageSettingsGeneral, {
- "pageView": pageView,
- "statusBar": statusBar,
- "accountModel": accountModel
- }, StackView.Immediate)
- } else if (index == 3) {
- pageView.replace(pageSettingsSync, {
- "pageView": pageView,
- "statusBar": statusBar,
- "accountModel": accountModel
- }, StackView.Immediate)
- } else if (index == 4) {
- pageView.replace(pageSettingsStorage, {
- "pageView": pageView,
- "statusBar": statusBar,
- "accountModel": accountModel
- }, StackView.Immediate)
- } else if (index == 5) {
- pageView.replace(pageSettingsPin, {
- "pageView": pageView,
- "statusBar": statusBar,
- "accountModel": accountModel
- }, StackView.Immediate)
- } else if (index == 6) {
- Qt.openUrlExternally("https://secure.nic.cz/files/datove_schranky/redirect/mobile-manual.html")
- pageView.pop(StackView.Immediate)
- } else {
- pageView.pop(StackView.Immediate)
- }
- }
- }
- }
- }
- ListView {
- id: settingsList
+
+ AccessibleMenu {
+ id: settingsMenuList
anchors.top: headerBar.bottom
anchors.bottom: parent.bottom
width: parent.width
clip: true
spacing: 1
opacity: 1
- model: settingsListModel
- delegate: settingsComponent
+
+ funcArr: funcs
+ model: settingsMenuListModel
}
}
}
diff --git a/qml/pages/PageMenuMessage.qml b/qml/pages/PageMenuMessage.qml
index bb6b30556c9d13c2843e5aa9cb3b9832d37ded8a..77158f4c0a0d45f8598d9e879bddc64c164eacdd 100644
--- a/qml/pages/PageMenuMessage.qml
+++ b/qml/pages/PageMenuMessage.qml
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014-2017 CZ.NIC
+ * Copyright (C) 2014-2018 CZ.NIC
*
* 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
@@ -23,7 +23,6 @@
import QtQuick 2.7
import QtQuick.Controls 2.1
-import QtGraphicalEffects 1.0
import cz.nic.mobileDatovka 1.0
import cz.nic.mobileDatovka.messages 1.0
import cz.nic.mobileDatovka.models 1.0
@@ -45,119 +44,73 @@ Component {
property var messageModel: null
Component.onCompleted: {
- messageMenuListModel.setProperty(3, "showIt", canDeleteMsg)
+ var index = messageMenuList.get_model_index(messageMenuListModel, "funcName", "delMsg");
+ if (index >= 0) {
+ messageMenuListModel.setProperty(index, "showEntry", canDeleteMsg)
+ }
}
+
PageHeader {
id: headerBar
- title: qsTr("Message") + ": " + msgId
- MouseArea {
- anchors.left: parent.left
- anchors.top: parent.top
- anchors.bottom: parent.bottom
- width: parent.width * backMouseAreaRatio
- onClicked: {
- pageView.pop(StackView.Immediate)
- }
+ title: qsTr("Message") + ": " + msgId
+ onBackClicked: {
+ pageView.pop(StackView.Immediate)
+ }
+ }
+
+ /* Object (associative array) holding functions. */
+ property var funcs: {
+ "downlAttch": function callDownlAttch() {
+ isds.doIsdsAction("downloadMessage", userName)
+ pageView.pop(StackView.Immediate)
+ },
+ "markRead": function callMarkRead() {
+ messages.markMessageAsLocallyRead(messageModel, userName, msgId, true)
+ pageView.pop(StackView.Immediate)
+ },
+ "markUnread": function callMarkUnread() {
+ messages.markMessageAsLocallyRead(messageModel, userName, msgId, false)
+ pageView.pop(StackView.Immediate)
+ },
+ "delMsg": function callDelMsg() {
+ messages.deleteMessageFromDbs(accountModel, messageModel, userName, msgId)
+ pageView.pop(StackView.Immediate)
}
}
+
ListModel {
id: messageMenuListModel
ListElement {
- index: 0
- showIt: true
- name: qsTr("Download attachments")
image: "qrc:/ui/datovka-email-download.svg"
+ showEntry: true
showNext: false
+ name: qsTr("Download attachments")
+ funcName: "downlAttch"
}
ListElement {
- index: 1
- showIt: true
- name: qsTr("Mark as read")
image: "qrc:/ui/email-open-outline.svg"
+ showEntry: true
showNext: false
+ name: qsTr("Mark as read")
+ funcName: "markRead"
}
ListElement {
- index: 2
- showIt: true
- name: qsTr("Mark as unread")
image: "qrc:/ui/email-outline.svg"
+ showEntry: true
showNext: false
+ name: qsTr("Mark as unread")
+ funcName: "markUnread"
}
ListElement {
- index: 3
- showIt: true
- name: qsTr("Delete message")
image: "qrc:/ui/delete.svg"
+ showEntry: true
showNext: false
+ name: qsTr("Delete message")
+ funcName: "delMsg"
}
}
- Component {
- id: messageMenuComponent
- Rectangle {
- visible: showIt
- color: datovkaPalette.base
- height: headerHeight
- width: parent.width
- Image {
- id: menuImage
- anchors.verticalCenter: parent.verticalCenter
- anchors.left: parent.left
- anchors.leftMargin: defaultMargin
- sourceSize.height: imgHeight
- source: image
- }
- ColorOverlay {
- anchors.fill: menuImage
- source: menuImage
- color: datovkaPalette.text
- }
- Text {
- anchors.verticalCenter: parent.verticalCenter
- anchors.left: menuImage.right
- anchors.leftMargin: defaultMargin
- color: datovkaPalette.text
- text: name
- }
- Rectangle {
- id: next2
- visible: showNext
- anchors.verticalCenter: parent.verticalCenter
- anchors.right: parent.right
- height: parent.height
- width: parent.width * 0.07
- color: parent.color
- Image {
- id: nextImage2
- anchors.verticalCenter: parent.verticalCenter
- anchors.right: parent.right
- anchors.rightMargin: defaultMargin
- sourceSize.height: navImgHeight
- source: "qrc:/ui/next.svg"
- }
- ColorOverlay {
- anchors.fill: nextImage2
- source: nextImage2
- color: datovkaPalette.text
- }
- }
- MouseArea {
- anchors.fill: parent
- onClicked: {
- if (index == 0) {
- isds.doIsdsAction("downloadMessage", userName)
- } else if (index == 1) {
- messages.markMessageAsLocallyRead(messageModel, userName, msgId, true)
- } else if (index == 2) {
- messages.markMessageAsLocallyRead(messageModel, userName, msgId, false)
- } else if (index == 3) {
- messages.deleteMessageFromDbs(accountModel, messageModel, userName, msgId)
- }
- pageView.pop(StackView.Immediate)
- }
- }
- }
- }
- ListView {
+
+ AccessibleMenu {
id: messageMenuList
anchors.top: headerBar.bottom
anchors.bottom: parent.bottom
@@ -165,9 +118,11 @@ Component {
clip: true
spacing: 1
opacity: 1
+
+ funcArr: funcs
model: messageMenuListModel
- delegate: messageMenuComponent
}
+
Connections {
target: isds
onRunDownloadMessageSig: {
diff --git a/qml/pages/PageMenuMessageDetail.qml b/qml/pages/PageMenuMessageDetail.qml
index 9b51057163e05ea527ec05ffdfc386355d4feb06..cff0bac6401dceb66d8af460b98f0b575e72a27e 100644
--- a/qml/pages/PageMenuMessageDetail.qml
+++ b/qml/pages/PageMenuMessageDetail.qml
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014-2017 CZ.NIC
+ * Copyright (C) 2014-2018 CZ.NIC
*
* 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
@@ -23,7 +23,6 @@
import QtQuick 2.7
import QtQuick.Controls 2.1
-import QtGraphicalEffects 1.0
import cz.nic.mobileDatovka 1.0
import cz.nic.mobileDatovka.messages 1.0
import cz.nic.mobileDatovka.models 1.0
@@ -47,169 +46,133 @@ Component {
if (msgType == MessageType.TYPE_SENT) {
// Hide some menu items for sent messages
// Note: remove argument is ListModel item index
- messageDetailMenuListModel.remove(1)
+ var index = messageDetailMenuList.get_model_index(messageDetailMenuListModel, "funcName", "reply");
+ if (index >= 0) {
+ messageDetailMenuListModel.setProperty(index, "showEntry", false)
+ //messageDetailMenuListModel.remove(index)
+ }
}
}
PageHeader {
id: headerBar
- title: qsTr("Message") + ": " + msgId
- MouseArea {
- anchors.left: parent.left
- anchors.top: parent.top
- anchors.bottom: parent.bottom
- width: parent.width * backMouseAreaRatio
- onClicked: {
- pageView.pop(StackView.Immediate)
+ title: qsTr("Message") + ": " + msgId
+ onBackClicked: {
+ pageView.pop(StackView.Immediate)
+ }
+ }
+
+ /* Object (associative array) holding functions. */
+ property var funcs: {
+ "downlAttch": function callDownlAttch() {
+ isds.doIsdsAction("downloadMessage", userName)
+ pageView.pop(StackView.Immediate)
+ },
+ "reply": function callReply() {
+ pageView.replace(pageSendMessage, {
+ "pageView": pageView,
+ "statusBar": statusBar,
+ "acntName" : acntName,
+ "userName": userName,
+ "msgId": msgId,
+ "msgType": msgType,
+ "action": "reply"
+ }, StackView.Immediate)
+ },
+ "forward": function callForward() {
+ pageView.replace(pageSendMessage, {
+ "pageView": pageView,
+ "statusBar": statusBar,
+ "acntName" : acntName,
+ "userName": userName,
+ "msgId": msgId,
+ "msgType": msgType,
+ "action": "fwdzfo"
+ }, StackView.Immediate)
+ },
+ "useTemplate": function callUseTemplate() {
+ pageView.replace(pageSendMessage, {
+ "pageView": pageView,
+ "statusBar": statusBar,
+ "acntName" : acntName,
+ "userName": userName,
+ "msgId": msgId,
+ "msgType": msgType,
+ "action": "template"
+ }, StackView.Immediate)
+ },
+ "sendEmail": function callSendEmail() {
+ files.sendAttachmentsWithEmail(userName, msgId)
+ pageView.pop(StackView.Immediate)
+ },
+ "saveAttachs": function callSaveAttachs() {
+ files.saveAttachmentsToDiskDb(userName, msgId)
+ pageView.pop(StackView.Immediate)
+ },
+ "delAttachs": function callDelAttachs() {
+ if (files.deleteAttachmentsFromDb(userName, msgId)) {
+ if (attachmentModel != null) {
+ attachmentModel.clearAll()
+ }
}
+ pageView.pop(StackView.Immediate)
}
}
+
ListModel {
id: messageDetailMenuListModel
ListElement {
- index: 0
- name: qsTr("Download attachments")
image: "qrc:/ui/datovka-email-download.svg"
+ showEntry: true
showNext: false
+ name: qsTr("Download attachments")
+ funcName: "downlAttch"
}
ListElement {
- index: 1
- name: qsTr("Reply")
image: "qrc:/ui/reply.svg"
+ showEntry: true
showNext: true
+ name: qsTr("Reply")
+ funcName: "reply"
}
ListElement {
- index: 2
- name: qsTr("Forward")
image: "qrc:/ui/forward.svg"
+ showEntry: true
showNext: true
+ name: qsTr("Forward")
+ funcName: "forward"
}
ListElement {
- index: 3
- name: qsTr("Use as template")
image: "qrc:/ui/datovka-email-sample.svg"
+ showEntry: true
showNext: true
+ name: qsTr("Use as template")
+ funcName: "useTemplate"
}
ListElement {
- index: 4
- name: qsTr("Send attachments by email")
image: "qrc:/ui/attach-to-mail.svg"
+ showEntry: true
showNext: false
+ name: qsTr("Send attachments by email")
+ funcName: "sendEmail"
}
ListElement {
- index: 5
- name: qsTr("Save attachments")
image: "qrc:/ui/save-to-disk.svg"
+ showEntry: true
showNext: false
+ name: qsTr("Save attachments")
+ funcName: "saveAttachs"
}
ListElement {
- index: 6
- name: qsTr("Delete attachments")
image: "qrc:/ui/delete.svg"
+ showEntry: true
showNext: false
+ name: qsTr("Delete attachments")
+ funcName: "delAttachs"
}
}
- Component {
- id: messageDetailMenuComponent
- Rectangle {
- height: headerHeight
- width: parent.width
- Image {
- id: menuImage
- anchors.verticalCenter: parent.verticalCenter
- anchors.left: parent.left
- anchors.leftMargin: defaultMargin
- sourceSize.height: imgHeight
- source: image
- }
- ColorOverlay {
- anchors.fill: menuImage
- source: menuImage
- color: datovkaPalette.text
- }
- Text {
- anchors.verticalCenter: parent.verticalCenter
- anchors.left: menuImage.right
- anchors.leftMargin: defaultMargin
- color: datovkaPalette.text
- text: name
- }
- Rectangle {
- visible: showNext
- anchors.verticalCenter: parent.verticalCenter
- anchors.right: parent.right
- height: parent.height
- width: parent.width * 0.07
- color: parent.color
- Image {
- id: nextImage
- anchors.verticalCenter: parent.verticalCenter
- anchors.right: parent.right
- anchors.rightMargin: defaultMargin
- sourceSize.height: navImgHeight
- source: "qrc:/ui/next.svg"
- }
- ColorOverlay {
- anchors.fill: nextImage
- source: nextImage
- color: datovkaPalette.text
- }
- }
- MouseArea {
- anchors.fill: parent
- onClicked: {
- if (index == 0) {
- isds.doIsdsAction("downloadMessage", userName)
- pageView.pop(StackView.Immediate)
- } else if (index == 1) {
- pageView.replace(pageSendMessage, {
- "pageView": pageView,
- "statusBar": statusBar,
- "acntName" : acntName,
- "userName": userName,
- "msgId": msgId,
- "msgType": msgType,
- "action": "reply"
- }, StackView.Immediate)
- } else if (index == 2) {
- pageView.replace(pageSendMessage, {
- "pageView": pageView,
- "statusBar": statusBar,
- "acntName" : acntName,
- "userName": userName,
- "msgId": msgId,
- "msgType": msgType,
- "action": "fwdzfo"
- }, StackView.Immediate)
- } else if (index == 3) {
- pageView.replace(pageSendMessage, {
- "pageView": pageView,
- "statusBar": statusBar,
- "acntName" : acntName,
- "userName": userName,
- "msgId": msgId,
- "msgType": msgType,
- "action": "template"
- }, StackView.Immediate)
- } else if (index == 4) {
- files.sendAttachmentsWithEmail(userName, msgId)
- pageView.pop(StackView.Immediate)
- } else if (index == 5) {
- files.saveAttachmentsToDiskDb(userName, msgId)
- pageView.pop(StackView.Immediate)
- } else if (index == 6) {
- if (files.deleteAttachmentsFromDb(userName, msgId)) {
- if (attachmentModel != null) {
- attachmentModel.clearAll()
- }
- }
- pageView.pop(StackView.Immediate)
- }
- }
- }
- }
- }
- ListView {
+
+ AccessibleMenu {
id: messageDetailMenuList
anchors.top: headerBar.bottom
anchors.bottom: parent.bottom
@@ -217,8 +180,9 @@ Component {
clip: true
spacing: 1
opacity: 1
+
+ funcArr: funcs
model: messageDetailMenuListModel
- delegate: messageDetailMenuComponent
}
}
}
diff --git a/qml/pages/PageMenuMessageList.qml b/qml/pages/PageMenuMessageList.qml
index 7feb3c80633b1e9d4f0e6f4fc2a7ff641dfaa982..35796ea642e139a55c465fd2466f3d1b02619cca 100644
--- a/qml/pages/PageMenuMessageList.qml
+++ b/qml/pages/PageMenuMessageList.qml
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014-2017 CZ.NIC
+ * Copyright (C) 2014-2018 CZ.NIC
*
* 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
@@ -23,7 +23,6 @@
import QtQuick 2.7
import QtQuick.Controls 2.1
-import QtGraphicalEffects 1.0
import cz.nic.mobileDatovka 1.0
import cz.nic.mobileDatovka.messages 1.0
@@ -43,92 +42,42 @@ Component {
PageHeader {
id: headerBar
title: qsTr("Message operations")
- MouseArea {
- anchors.left: parent.left
- anchors.top: parent.top
- anchors.bottom: parent.bottom
- width: parent.width * backMouseAreaRatio
- onClicked: {
- pageView.pop(StackView.Immediate)
- }
+ onBackClicked: {
+ pageView.pop(StackView.Immediate)
}
}
+
+ /* Object (associative array) holding functions. */
+ property var funcs: {
+ "markRead": function callMarkRead() {
+ messages.markMessagesAsLocallyRead(messageModel, userName, msgType, true)
+ pageView.pop(StackView.Immediate)
+ },
+ "markUnread": function callMarkUnread() {
+ messages.markMessagesAsLocallyRead(messageModel, userName, msgType, false)
+ pageView.pop(StackView.Immediate)
+ }
+ }
+
ListModel {
id: messagesMenuListModel
ListElement {
- index: 0
- name: qsTr("Mark messages as read")
image: "qrc:/ui/email-open-outline.svg"
+ showEntry: true
showNext: false
+ name: qsTr("Mark messages as read")
+ funcName: "markRead"
}
ListElement {
- index: 1
- name: qsTr("Mark messages as unread")
image: "qrc:/ui/email-outline.svg"
+ showEntry: true
showNext: false
+ name: qsTr("Mark messages as unread")
+ funcName: "markUnread"
}
}
- Component {
- id: messagesMenuComponent
- Rectangle {
- color: datovkaPalette.base
- height: headerHeight
- width: parent.width
- Image {
- id: menuImage
- anchors.verticalCenter: parent.verticalCenter
- anchors.left: parent.left
- anchors.leftMargin: defaultMargin
- sourceSize.height: imgHeight
- source: image
- }
- ColorOverlay {
- anchors.fill: menuImage
- source: menuImage
- color: datovkaPalette.text
- }
- Text {
- anchors.verticalCenter: parent.verticalCenter
- anchors.left: menuImage.right
- anchors.leftMargin: defaultMargin
- color: datovkaPalette.text
- text: name
- }
- Rectangle {
- visible: showNext
- anchors.verticalCenter: parent.verticalCenter
- anchors.right: parent.right
- height: parent.height
- width: parent.width * 0.07
- color: parent.color
- Image {
- id: nextImage
- anchors.verticalCenter: parent.verticalCenter
- anchors.right: parent.right
- anchors.rightMargin: defaultMargin
- sourceSize.height: navImgHeight
- source: "qrc:/ui/next.svg"
- }
- ColorOverlay {
- anchors.fill: nextImage
- source: nextImage
- color: datovkaPalette.text
- }
- }
- MouseArea {
- anchors.fill: parent
- onClicked: {
- if (index == 0) {
- messages.markMessagesAsLocallyRead(messageModel, userName, msgType, true)
- } else if (index == 1) {
- messages.markMessagesAsLocallyRead(messageModel, userName, msgType, false)
- }
- pageView.pop(StackView.Immediate)
- }
- }
- }
- }
- ListView {
+
+ AccessibleMenu {
id: messagesMenuList
anchors.top: headerBar.bottom
anchors.bottom: parent.bottom
@@ -136,8 +85,9 @@ Component {
clip: true
spacing: 1
opacity: 1
+
+ funcArr: funcs
model: messagesMenuListModel
- delegate: messagesMenuComponent
}
}
}
diff --git a/qml/pages/PageMessageDetail.qml b/qml/pages/PageMessageDetail.qml
index 4235c2584368c292983e7a38d1d6c638d523a5c7..c93b1a86787255486856e6d9de899c9faba7515c 100644
--- a/qml/pages/PageMessageDetail.qml
+++ b/qml/pages/PageMessageDetail.qml
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014-2017 CZ.NIC
+ * Copyright (C) 2014-2018 CZ.NIC
*
* 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
@@ -135,85 +135,71 @@ Component {
}
return str
}
- MouseArea {
- anchors.left: parent.left
- anchors.top: parent.top
- anchors.bottom: parent.bottom
- width: parent.width * backMouseAreaRatio
- onClicked: {
- if (typeof(statusBar) != "undefined") {
- statusBar.visible = false
- }
- pageView.pop()
+ onBackClicked: {
+ if (typeof(statusBar) != "undefined") {
+ statusBar.visible = false
}
+ pageView.pop()
}
Row {
anchors.verticalCenter: parent.verticalCenter
spacing: defaultMargin
anchors.right: parent.right
anchors.rightMargin: defaultMargin
- Image {
+ AccessibleImageButton {
id: msgEmailButton
anchors.verticalCenter: parent.verticalCenter
sourceSize.height: imgHeightHeader
source: "qrc:/ui/reply.svg"
- MouseArea {
- anchors.fill: parent
- onClicked: {
- files.sendAttachmentEmailZfo(attachmentModel, zfoId, msgAnnotation, emailBody)
- }
+ accessibleName: qsTr("Email attachments")
+ onClicked: {
+ files.sendAttachmentEmailZfo(attachmentModel, zfoId, msgAnnotation, emailBody)
}
}
- Image {
+ AccessibleImageButton {
id: attachmentSaveButon
anchors.verticalCenter: parent.verticalCenter
sourceSize.height: imgHeightHeader
source: "qrc:/ui/save-to-disk.svg"
- MouseArea {
- anchors.fill: parent
- onClicked: {
- if (!fromLocalDb) {
- files.saveAttachmentsToDiskZfo(attachmentModel, zfoId)
- } else {
- files.saveAttachmentsToDiskDb(userName, zfoId)
- }
+ accessibleName: qsTr("Save attachments.")
+ onClicked: {
+ if (!fromLocalDb) {
+ files.saveAttachmentsToDiskZfo(attachmentModel, zfoId)
+ } else {
+ files.saveAttachmentsToDiskDb(userName, zfoId)
}
}
}
- Image {
+ AccessibleImageButton {
id: msgDownloadButton
anchors.verticalCenter: parent.verticalCenter
sourceSize.height: imgHeightHeader
source: "qrc:/ui/datovka-email-download.svg"
- MouseArea {
- anchors.fill: parent
- onClicked: {
- if (fromLocalDb) {
- isds.doIsdsAction("downloadMessage", userName)
- }
+ accessibleName: qsTr("Download message")
+ onClicked: {
+ if (fromLocalDb) {
+ isds.doIsdsAction("downloadMessage", userName)
}
}
}
- Image {
+ AccessibleImageButton {
id: attachmentMenuButon
anchors.verticalCenter: parent.verticalCenter
sourceSize.height: imgHeightHeader
source: "qrc:/ui/menu.svg"
- MouseArea {
- anchors.fill: parent
- onClicked: {
- if (fromLocalDb) {
- pageView.push(pageMenuMessageDetail, {
- "pageView": pageView,
- "statusBar": statusBar,
- "acntName": acntName,
- "userName": userName,
- "msgType": msgType,
- "msgId": zfoId,
- "messageModel": messageModel,
- "attachmentModel" : attachmentModel
- }, StackView.Immediate)
- }
+ accessibleName: qsTr("Show menu of available operations")
+ onClicked: {
+ if (fromLocalDb) {
+ pageView.push(pageMenuMessageDetail, {
+ "pageView": pageView,
+ "statusBar": statusBar,
+ "acntName": acntName,
+ "userName": userName,
+ "msgType": msgType,
+ "msgId": zfoId,
+ "messageModel": messageModel,
+ "attachmentModel" : attachmentModel
+ }, StackView.Immediate)
}
}
}
@@ -230,7 +216,7 @@ Component {
Pane {
id: flickContent
anchors.fill: parent
- Text {
+ AccessibleText {
id: messageDetailText
color: datovkaPalette.text
width: parent.width
@@ -252,7 +238,7 @@ Component {
id: attachmentLabel
width: parent.width
height: textFontSizeInPixels * 3
- Text {
+ AccessibleText {
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
anchors.leftMargin: defaultMargin * 2
@@ -267,8 +253,11 @@ Component {
color: datovkaPalette.dark
}
}
- ListView {
+ ScrollableListView {
id: attachmentList
+
+ delegateHeight: headerHeight
+
anchors.top: attachmentLabel.bottom
anchors.bottom: parent.bottom
clip: true
@@ -285,7 +274,7 @@ Component {
delegate: Rectangle {
id: attachmentItem
width: parent.width
- height: headerHeight
+ height: attachmentList.delegateHeight
color: datovkaPalette.base
Image {
id: imageAttachment
@@ -340,8 +329,7 @@ Component {
}
}
MouseArea {
- anchors.fill: parent
- onClicked: {
+ function handleClick() {
locker.ignoreNextSuspension()
if (files.isZfoFile(rFileName)) {
console.log("Attachment is ZFO: " + rFileName)
@@ -365,6 +353,19 @@ Component {
}
}
}
+
+ anchors.fill: parent
+
+ Accessible.role: Accessible.Button
+ Accessible.name: qsTr("Open attachment '%1'.").arg(rFileName)
+ Accessible.onScrollDownAction: attachmentList.scrollDown()
+ Accessible.onScrollUpAction: attachmentList.scrollUp()
+ Accessible.onPressAction: {
+ handleClick()
+ }
+ onClicked: {
+ handleClick()
+ }
}
Rectangle {
anchors.top: parent.bottom
@@ -390,7 +391,7 @@ Component {
}
ScrollIndicator.vertical: ScrollIndicator {}
} // Listview
- Text {
+ AccessibleTextButton {
id: emptyList
visible: false
color: datovkaPalette.text
@@ -401,17 +402,14 @@ Component {
verticalAlignment: Text.AlignVCenter
wrapMode: Text.Wrap
text: fromLocalDb ? qsTr("Attachments have not been downloaded yet.\nClick the icon or this text for their download.") : qsTr("No attachments present.")
- MouseArea {
- anchors.fill: parent
- onClicked: {
- if (fromLocalDb) {
- isds.doIsdsAction("downloadMessage", userName)
- }
+ onClicked: {
+ if (fromLocalDb) {
+ isds.doIsdsAction("downloadMessage", userName)
}
}
} // Text
} // Rectangle
- Text {
+ AccessibleText {
id: errorNotification
visible: false
color: datovkaPalette.text
diff --git a/qml/pages/PageMessageList.qml b/qml/pages/PageMessageList.qml
index 64571250ff5bcf45a2e70b52634790b20254243f..aac19993d94db764b807527ad88e2b33dfb57fa9 100644
--- a/qml/pages/PageMessageList.qml
+++ b/qml/pages/PageMessageList.qml
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014-2017 CZ.NIC
+ * Copyright (C) 2014-2018 CZ.NIC
*
* 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
@@ -50,7 +50,7 @@ Component {
if (messageModel.rowCount() === 0) {
emptyList.visible = true
/* Don't use visible property as it hides the element. */
- settingsButton.visible = false
+ menuButton.visible = false
searchButton.visible = false
}
@@ -58,7 +58,7 @@ Component {
/* Don't use message settings for sent messages */
if (msgType == MessageType.TYPE_SENT) {
- settingsButton.visible = false
+ menuButton.visible = false
}
}
@@ -86,111 +86,75 @@ Component {
PageHeader {
id: headerBar
title: (msgType == MessageType.TYPE_RECEIVED) ? qsTr("Received messages") : qsTr("Sent messages");
- MouseArea {
- anchors.left: parent.left
- anchors.top: parent.top
- anchors.bottom: parent.bottom
- width: parent.width * backMouseAreaRatio
- onClicked: {
- pageView.pop()
- }
+ onBackClicked: {
+ pageView.pop()
}
Row {
anchors.verticalCenter: parent.verticalCenter
spacing: defaultMargin
anchors.right: parent.right
anchors.rightMargin: defaultMargin
- Image {
+ AccessibleImageButton {
id: searchButton
anchors.verticalCenter: parent.verticalCenter
sourceSize.height: imgHeightHeader
source: "qrc:/ui/magnify.svg"
- MouseArea {
- anchors.fill: parent
- onClicked: {
- messageList.anchors.top = filterBar.bottom
- filterBar.visible = true
- filter.forceActiveFocus()
- Qt.inputMethod.show()
- }
+ accessibleName: qsTr("Filter messages.")
+ onClicked: {
+ messageList.anchors.top = filterBar.bottom
+ filterBar.visible = true
+ filterBar.filterField.forceActiveFocus()
+ Qt.inputMethod.show()
}
}
- Image {
- id: settingsButton
+ AccessibleImageButton {
+ id: menuButton
anchors.verticalCenter: parent.verticalCenter
sourceSize.height: imgHeightHeader
source: "qrc:/ui/menu.svg"
- MouseArea {
- anchors.fill: parent
- onClicked: {
- statusBar.visible = false
- Qt.inputMethod.hide()
- pageView.push(pageMenuMessageList, {
- "pageView": pageView,
- "statusBar": statusBar,
- "acntName": acntName,
- "userName": userName,
- "msgType": msgType,
- "messageModel": messageModel
- }, StackView.Immediate)
- }
+ accessibleName: qsTr("Show menu of available operations.")
+ onClicked: {
+ statusBar.visible = false
+ Qt.inputMethod.hide()
+ pageView.push(pageMenuMessageList, {
+ "pageView": pageView,
+ "statusBar": statusBar,
+ "acntName": acntName,
+ "userName": userName,
+ "msgType": msgType,
+ "messageModel": messageModel
+ }, StackView.Immediate)
}
}
}
}
- Rectangle {
+ FilterBar {
id: filterBar
visible: false
z: 1
anchors.top: headerBar.bottom
width: parent.width
- height: filter.height
- color: (filter.text.length == 0) ? datovkaPalette.alternateBase :
+ height: filterField.height
+ color: (filterField.text.length == 0) ? datovkaPalette.alternateBase :
(messageList.count > 0) ? "#afffaf" : "#ffafaf"
- border.color: filter.activeFocus ? "#0066ff" : "#bdbebf"
- TextField {
- id: filter
- anchors.top: parent.top
- width: parent.width - close.width
- placeholderText: qsTr("Set filter")
- font.pointSize: defaultTextFont.font.pointSize
- inputMethodHints: Qt.ImhNoPredictiveText
- /*
- * Using explicit top, left, ... padding because plain padding
- * does not centre the text properly.
- */
- topPadding: 8.0
- bottomPadding: 8.0
- leftPadding: 8.0
- rightPadding: 8.0
- /* TODO - remove background if used materials */
- background: Rectangle {
- anchors.fill: parent
- color: "transparent"
- border.color: "transparent"
- }
- onTextChanged: {
- proxyMessageModel.setFilterRegExpStr(filter.text)
- }
+ border.color: filterField.activeFocus ? "#0066ff" : "#bdbebf"
+
+ placeholderText: qsTr("Set filter")
+ fontPointSize: defaultTextFont.font.pointSize
+ buttonImageHeight: imgHeight
+ buttonAccessibleName: qsTr("Clear and hide filter field")
+
+ onTextChanged: {
+ proxyMessageModel.setFilterRegExpStr(text)
}
- Image {
- id: close
- anchors.right: parent.right
- anchors.verticalCenter: parent.verticalCenter
- sourceSize.height: imgHeight
- source: "qrc:/ui/remove.svg"
- MouseArea {
- anchors.fill: parent
- onClicked: {
- filterBar.visible = false
- filter.clear()
- messageList.anchors.top = headerBar.bottom
- Qt.inputMethod.hide()
- }
- }
+
+ onClearClicked: {
+ filterBar.visible = false
+ messageList.anchors.top = headerBar.bottom
+ Qt.inputMethod.hide()
}
- } // Rectangle
- Text {
+ }
+ AccessibleText {
id: emptyList
visible: false
color: datovkaPalette.text
@@ -198,9 +162,9 @@ Component {
width: parent.width
horizontalAlignment: Text.AlignHCenter
wrapMode: Text.Wrap
- text: (filter.text.length == 0) ?
+ text: (filterBar.filterField.text.length == 0) ?
qsTr("No messages or have not been downloaded yet.") :
- qsTr("No message found that matches filter text '%1'.").arg(filter.text)
+ qsTr("No message found that matches filter text '%1'.").arg(filterBar.filterField.text)
}
MessageList {
id: messageList
@@ -217,10 +181,10 @@ Component {
onCountChanged: {
if (messageList.count == 0) {
emptyList.visible = true
- settingsButton.enabled = false
+ menuButton.enabled = false
} else {
emptyList.visible = false
- settingsButton.enabled = true
+ menuButton.enabled = true
}
}
onMsgClicked: {
diff --git a/qml/pages/PageMessageSearch.qml b/qml/pages/PageMessageSearch.qml
index b2453361d6fd08c37be785e9fd5f25e8cdff7a82..83060c6bfb9499e3a82225e95a7e54e1639d1c9f 100644
--- a/qml/pages/PageMessageSearch.qml
+++ b/qml/pages/PageMessageSearch.qml
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014-2017 CZ.NIC
+ * Copyright (C) 2014-2018 CZ.NIC
*
* 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
@@ -58,33 +58,25 @@ Item {
PageHeader {
id: headerBar
title: qsTr("Search message")
- MouseArea {
- anchors.left: parent.left
- anchors.top: parent.top
- anchors.bottom: parent.bottom
- width: parent.width * backMouseAreaRatio
- onClicked: {
- pageView.pop(StackView.Immediate)
- }
+ onBackClicked: {
+ pageView.pop(StackView.Immediate)
}
Row {
anchors.verticalCenter: parent.verticalCenter
spacing: defaultMargin
anchors.right: parent.right
anchors.rightMargin: defaultMargin
- Image {
+ AccessibleImageButton {
id: actionButton
anchors.verticalCenter: parent.verticalCenter
sourceSize.height: imgHeightHeader
source: "qrc:/ui/magnify.svg"
- MouseArea {
- anchors.fill: parent
- onClicked: {
- // Set textfield focus on false = hide input keyboard
- // and obtain textfield value
- searchPhraseText.focus = false
- emptyList.visible = searchPanel.doSearchRequest()
- }
+ accessibleName: qsTr("Search messages.")
+ onClicked: {
+ // Set textfield focus on false = hide input keyboard
+ // and obtain textfield value
+ searchPhraseText.focus = false
+ emptyList.visible = searchPanel.doSearchRequest()
}
}
}
@@ -100,42 +92,26 @@ Item {
anchors.right: parent.right
anchors.left: parent.left
spacing: formItemVerticalSpacing
- ComboBox {
+ AccessibleComboBox {
id: searchOptionComboBox
- currentIndex: 0
width: parent.width
- height: inputItemHeight
- textRole: "label"
- font.pointSize: defaultTextFont.font.pointSize
- delegate: ItemDelegate {
- width: searchOptionComboBox.width
- height: inputItemHeight
- contentItem: Text {
- text: label
- color: datovkaPalette.text
- font.pointSize: defaultTextFont.font.pointSize
- elide: Text.ElideRight
- verticalAlignment: Text.AlignVCenter
- }
- highlighted: searchOptionComboBox.highlightedIndex == index
- }
+ accessibleDescription: qsTr("Select type of sought messages")
model: ListModel {
id: searchOptionComboBoxModel
- // Don't change position of list elements and keys.
- /* Cannot have an expression here becacuse QML complains that it cannot use script for property value. */
- ListElement { label: qsTr("All messages"); value: -1 }
- ListElement { label: qsTr("Received messages"); value: MessageType.TYPE_RECEIVED }
- ListElement { label: qsTr("Sent messages"); value: MessageType.TYPE_SENT }
+ /* Cannot have an expression here because QML complains that it cannot use script for property key. */
+ ListElement { label: qsTr("All messages"); key: -1 }
+ ListElement { label: qsTr("Received messages"); key: MessageType.TYPE_RECEIVED }
+ ListElement { label: qsTr("Sent messages"); key: MessageType.TYPE_SENT }
}
onCurrentIndexChanged: {
- if (searchOptionComboBoxModel.get(currentIndex).value == -1) {
+ if (currentKey() == -1) {
soughtMsgType = MessageType.TYPE_RECEIVED | MessageType.TYPE_SENT
} else {
- soughtMsgType = searchOptionComboBoxModel.get(currentIndex).value
+ soughtMsgType = currentKey()
}
}
}
- TextField {
+ AccessibleTextField {
id: searchPhraseText
placeholderText: qsTr("Enter phrase")
focus: true
diff --git a/qml/pages/PageSendMessage.qml b/qml/pages/PageSendMessage.qml
index cef90b0fea4eb59f4d86f3a1e9885372a462f2a8..00278eeed91c26c74851eff98ab988da6250288c 100644
--- a/qml/pages/PageSendMessage.qml
+++ b/qml/pages/PageSendMessage.qml
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014-2017 CZ.NIC
+ * Copyright (C) 2014-2018 CZ.NIC
*
* 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
@@ -191,32 +191,24 @@ Item {
PageHeader {
id: headerBar
title: qsTr("Create message")
- MouseArea {
- anchors.left: parent.left
- anchors.top: parent.top
- anchors.bottom: parent.bottom
- width: parent.width * backMouseAreaRatio
- onClicked: {
- pageView.pop(StackView.Immediate)
- }
+ onBackClicked: {
+ pageView.pop(StackView.Immediate)
}
- OverlaidImage {
+ AccessibleOverlaidImageButton {
id: actionButton
anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right
anchors.rightMargin: defaultMargin
image.sourceSize.height: imgHeightHeader
image.source: "qrc:/ui/send-msg.svg"
- MouseArea {
- anchors.fill: parent
- onClicked: {
- actionButton.enabled = false
- mainPanel.doSendRequest()
- }
+ accessibleName: qsTr("Send message")
+ onClicked: {
+ actionButton.enabled = false
+ mainPanel.doSendRequest()
}
}
} // PageHeader
- Text {
+ AccessibleText {
id: errorText
visible: false
color: datovkaPalette.text
@@ -263,7 +255,7 @@ Item {
width: parent.width
Repeater {
model: [qsTr("General"), qsTr("Recipients"), qsTr("Attachments"), qsTr("Additional")]
- TabButton {
+ AccessibleTabButton {
text: modelData
width: Math.max(100, tabBar.width / 4)
}
@@ -291,7 +283,7 @@ Item {
anchors.right: parent.right
anchors.left: parent.left
spacing: formItemVerticalSpacing
- Text {
+ AccessibleText {
color: datovkaPalette.mid
wrapMode: Text.Wrap
horizontalAlignment: Text.AlignHCenter
@@ -301,24 +293,24 @@ Item {
Text {
text: " "
}
- Text {
+ AccessibleText {
color: datovkaPalette.text
font.bold: true
text: qsTr("Sender account")
}
- Text {
+ AccessibleText {
color: datovkaPalette.text
text: acntName + " (" + userName + ")"
}
Text {
text: " "
}
- Text {
+ AccessibleText {
color: datovkaPalette.text
font.bold: true
text: qsTr("Subject")
}
- TextField {
+ AccessibleTextField {
id: dmAnnotation
width: parent.width
height: inputItemHeight
@@ -339,33 +331,33 @@ Item {
mainPanel.areReguiredFieldsFilled()
}
}
- Switch {
+ AccessibleSwitch {
id: dmPublishOwnID
text: qsTr("Include sender identification")
font.pointSize: defaultTextFont.font.pointSize
checked: true
}
- Switch {
+ AccessibleSwitch {
id: dmPersonalDelivery
text: qsTr("Personal delivery")
font.pointSize: defaultTextFont.font.pointSize
checked: false
}
- Switch {
+ AccessibleSwitch {
id: dmAllowSubstDelivery
visible: false
text: qsTr("Allow acceptance through fiction")
font.pointSize: defaultTextFont.font.pointSize
checked: true
}
- Switch {
+ AccessibleSwitch {
id: dmOVM
visible: false
text: qsTr("Send as OVM")
font.pointSize: defaultTextFont.font.pointSize
checked: true
}
- Switch {
+ AccessibleSwitch {
id: initPDZ
visible: false
text: qsTr("Pay transfer charges for reply")
@@ -375,7 +367,7 @@ Item {
(initPDZ.checked) ? dmType = "I" : dmType = ""
}
}
- Switch {
+ AccessibleSwitch {
id: replyPDZ
visible: false
text: qsTr("Use transfer charges from recipient")
@@ -399,7 +391,7 @@ Item {
Row {
spacing: formItemVerticalSpacing * 5
anchors.horizontalCenter: parent.horizontalCenter
- Button {
+ AccessibleButton {
id: addContact
height: inputItemHeight
font.pointSize: defaultTextFont.font.pointSize
@@ -413,7 +405,7 @@ Item {
}, StackView.Immediate)
}
}
- Button {
+ AccessibleButton {
id: findDS
height: inputItemHeight
font.pointSize: defaultTextFont.font.pointSize
@@ -454,7 +446,7 @@ Item {
//----ATTACHMENT SECTION------------
Item {
id: tabAttachments
- Button {
+ AccessibleButton {
id: addFile
height: inputItemHeight
anchors.horizontalCenter: parent.horizontalCenter
@@ -469,11 +461,10 @@ Item {
Rectangle {
id: attachmentItem
width: parent.width
- height: listItemHeight
+ height: attachmentListSend.delegateHeight
color: datovkaPalette.base
MouseArea {
- anchors.fill: parent
- onClicked: {
+ function handleClick() {
// fileId is set and is valid, use files from database
if (rFileId > 0) {
if (files.isZfoFile(rFileName)) {
@@ -503,12 +494,23 @@ Item {
}
}
}
+
+ anchors.fill: parent
+
+ Accessible.role: Accessible.Button
+ Accessible.name: qsTr("Open file '%1'.").arg(rFileName)
+ Accessible.onPressAction: {
+ handleClick()
+ }
+ onClicked: {
+ handleClick()
+ }
}
Image {
id: imageAttachment
anchors.left: parent.left
anchors.verticalCenter: parent.verticalCenter
- sourceSize.height: listItemHeight * 0.8
+ sourceSize.height: attachmentListSend.delegateHeight * 0.8
source: rFileIcon
}
Item {
@@ -558,9 +560,21 @@ Item {
color: datovkaPalette.windowText
}
MouseArea {
+ function handleClick() {
+ sendMsgAttachmentModel.removeItem(index)
+ }
+
anchors.fill: parent
+
+ Accessible.role: Accessible.Button
+ Accessible.name: qsTr("Remove file '%1' from list.").arg(rFileName)
+ Accessible.onScrollDownAction: attachmentListSend.scrollDown()
+ Accessible.onScrollUpAction: attachmentListSend.scrollUp()
+ Accessible.onPressAction: {
+ handleClick()
+ }
onClicked: {
- sendMsgAttachmentModel.removeItem(index)
+ handleClick()
}
}
} // Rectangle
@@ -572,8 +586,11 @@ Item {
}
} // Rectangle
} // Component
- ListView {
+ ScrollableListView {
id: attachmentListSend
+
+ delegateHeight: listItemHeight
+
anchors.top: addFile.bottom
anchors.bottom: parent.bottom
clip: true
@@ -605,58 +622,58 @@ Item {
anchors.left: parent.left
spacing: formItemVerticalSpacing
//---Mandate---------------------
- Text {
+ AccessibleText {
font.bold: true
text: qsTr("Mandate")
}
Row {
width: parent.width
spacing: defaultMargin
- TextField {
+ AccessibleTextField {
id: dmLegalTitleLaw
width: mandateFieldLenght
height: inputItemHeight
maximumLength: 4
font.pointSize: defaultTextFont.font.pointSize
}
- Text {
+ AccessibleText {
anchors.verticalCenter: parent.verticalCenter
text: "/"
}
- TextField {
+ AccessibleTextField {
id: dmLegalTitleYear
width: mandateFieldLenght
height: inputItemHeight
maximumLength: 4
font.pointSize: defaultTextFont.font.pointSize
}
- Text {
+ AccessibleText {
anchors.verticalCenter: parent.verticalCenter
text: "§"
}
- TextField {
+ AccessibleTextField {
id: dmLegalTitleSect
width: mandateFieldLenght
height: inputItemHeight
maximumLength: 4
font.pointSize: defaultTextFont.font.pointSize
}
- Text {
+ AccessibleText {
anchors.verticalCenter: parent.verticalCenter
text: qsTr("par.")
}
- TextField {
+ AccessibleTextField {
id: dmLegalTitlePar
width: mandateFieldLenght / 2
height: inputItemHeight
maximumLength: 2
font.pointSize: defaultTextFont.font.pointSize
}
- Text {
+ AccessibleText {
anchors.verticalCenter: parent.verticalCenter
text: qsTr("let.")
}
- TextField {
+ AccessibleTextField {
id: dmLegalTitlePoint
width: mandateFieldLenght / 2
height: inputItemHeight
@@ -665,11 +682,11 @@ Item {
}
}
//---Our ref.number---------------------
- Text {
+ AccessibleText {
font.bold: true
text: qsTr("Our reference number")
}
- TextField {
+ AccessibleTextField {
id: dmSenderRefNumber
height: inputItemHeight
font.pointSize: defaultTextFont.font.pointSize
@@ -688,11 +705,11 @@ Item {
}
}
//---Our file mark---------------------
- Text {
+ AccessibleText {
font.bold: true
text: qsTr("Our file mark")
}
- TextField {
+ AccessibleTextField {
id: dmSenderIdent
height: inputItemHeight
font.pointSize: defaultTextFont.font.pointSize
@@ -711,11 +728,11 @@ Item {
}
}
//---Your ref.number---------------------
- Text {
+ AccessibleText {
font.bold: true
text: qsTr("Your reference number")
}
- TextField {
+ AccessibleTextField {
id: dmRecipientRefNumber
height: inputItemHeight
font.pointSize: defaultTextFont.font.pointSize
@@ -734,11 +751,11 @@ Item {
}
}
//---Your file mark---------------------
- Text {
+ AccessibleText {
font.bold: true
text: qsTr("Your file mark")
}
- TextField {
+ AccessibleTextField {
id: dmRecipientIdent
height: inputItemHeight
font.pointSize: defaultTextFont.font.pointSize
@@ -757,11 +774,11 @@ Item {
}
}
//---To hands---------------------
- Text {
+ AccessibleText {
font.bold: true
text: qsTr("To hands")
}
- TextField {
+ AccessibleTextField {
id: dmToHands
height: inputItemHeight
font.pointSize: defaultTextFont.font.pointSize
diff --git a/qml/pages/PageSettingsAccount.qml b/qml/pages/PageSettingsAccount.qml
index a3add3ca5f5eb21c411b046461f4bd530f2530c4..905899ed5ddc23324dfb23ac0dbb70c7c05dc787 100644
--- a/qml/pages/PageSettingsAccount.qml
+++ b/qml/pages/PageSettingsAccount.qml
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014-2017 CZ.NIC
+ * Copyright (C) 2014-2018 CZ.NIC
*
* 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
@@ -68,51 +68,43 @@ Item {
PageHeader {
id: headerBar
title: qsTr("New account")
- MouseArea {
- anchors.left: parent.left
- anchors.top: parent.top
- anchors.bottom: parent.bottom
- width: parent.width * backMouseAreaRatio
- onClicked: {
- pageView.pop(StackView.Immediate)
- }
+ onBackClicked: {
+ pageView.pop(StackView.Immediate)
}
Row {
anchors.verticalCenter: parent.verticalCenter
spacing: defaultMargin
anchors.right: parent.right
anchors.rightMargin: defaultMargin
- Image {
+ AccessibleImageButton {
id: actionButton
anchors.verticalCenter: parent.verticalCenter
sourceSize.height: imgHeightHeader
source: "qrc:/ui/checkbox-marked-circle.svg"
- MouseArea {
- anchors.fill: parent
- onClicked: {
- if (isNewAccount) {
- // Create a new account context data and add to model.
- if (accounts.createAccount(accountModel, sLoginMethod,
+ accessibleName: qsTr("Accept changes")
+ onClicked: {
+ if (isNewAccount) {
+ // Create a new account context data and add to model.
+ if (accounts.createAccount(accountModel, sLoginMethod,
+ accountNameTextField.text.toString(),
+ userNameTextField.text.toString(),
+ passwordTextField.text.toString(),
+ testAccount.checked, rememberPassword.checked,
+ useLS.checked, certPathLabelId.text.toString())) {
+ // Login to new account.
+ isds.doIsdsAction("addNewAccount", userNameTextField.text.toString())
+ }
+ } else {
+ // Update account context data.
+ if (accounts.updateAccount(accountModel, sLoginMethod,
accountNameTextField.text.toString(),
userNameTextField.text.toString(),
passwordTextField.text.toString(),
testAccount.checked, rememberPassword.checked,
useLS.checked, certPathLabelId.text.toString())) {
- // Login to new account.
- isds.doIsdsAction("addNewAccount", userNameTextField.text.toString())
- }
- } else {
- // Update account context data.
- if (accounts.updateAccount(accountModel, sLoginMethod,
- accountNameTextField.text.toString(),
- userNameTextField.text.toString(),
- passwordTextField.text.toString(),
- testAccount.checked, rememberPassword.checked,
- useLS.checked, certPathLabelId.text.toString())) {
- settings.saveAllSettings(accountModel)
- }
- pageView.pop(StackView.Immediate)
+ settings.saveAllSettings(accountModel)
}
+ pageView.pop(StackView.Immediate)
}
}
Connections {
@@ -159,40 +151,25 @@ Item {
anchors.right: parent.right
anchors.left: parent.left
spacing: formItemVerticalSpacing
- Text {
+ AccessibleText {
id: loginMethodLabel
color: datovkaPalette.text
text: qsTr("Login method")
}
- ComboBox {
+ AccessibleComboBox {
id: loginMethodComboBox
- currentIndex: 0
width: parent.width
- height: inputItemHeight
- textRole: "label"
- font.pointSize: defaultTextFont.font.pointSize
- delegate: ItemDelegate {
- width: loginMethodComboBox.width
- height: inputItemHeight
- contentItem: Text {
- text: label
- color: datovkaPalette.text
- font.pointSize: defaultTextFont.font.pointSize
- elide: Text.ElideRight
- verticalAlignment: Text.AlignVCenter
- }
- highlighted: loginMethodComboBox.highlightedIndex == index
- }
+ accessibleDescription: qsTr("Select login method")
model: ListModel {
id: loginMethodModel
- // Don't change position of list elements, keys and values.
- ListElement { label: qsTr("Username + Password"); value: "pwd" }
- ListElement { label: qsTr("Certificate + Password"); value: "cert" }
- ListElement { label: qsTr("Password + Security code"); value: "hotp" }
- ListElement { label: qsTr("Password + Security SMS"); value: "totp" }
+ /* Key values must be equivalent to constants defined in C++ code! */
+ ListElement { label: qsTr("Username + Password"); key: "pwd" } // USERNAME_PWD_ONLY
+ ListElement { label: qsTr("Certificate + Password"); key: "cert" } // USERNAME_PWD_CERT
+ ListElement { label: qsTr("Password + Security code"); key: "hotp" } // USERNAME_PWD_HOTP
+ ListElement { label: qsTr("Password + Security SMS"); key: "totp" } // USERNAME_PWD_TOTP
}
onCurrentIndexChanged: {
- sLoginMethod = loginMethodModel.get(currentIndex).value
+ sLoginMethod = currentKey()
if (sLoginMethod === "cert") {
certificateLabel.visible = true
certPathButtonId.visible = true
@@ -204,13 +181,13 @@ Item {
}
}
}
- Text {
+ AccessibleText {
id: certificateLabel
visible: false
color: datovkaPalette.text
text: qsTr("Certificate")
}
- Text {
+ AccessibleText {
id: certPathLabelId
visible: false
color: datovkaPalette.text
@@ -218,7 +195,7 @@ Item {
wrapMode: Text.WrapAnywhere
text: ""
}
- Button {
+ AccessibleButton {
id: certPathButtonId
visible: false
text: qsTr("Choose file")
@@ -228,11 +205,11 @@ Item {
fileDialogue.raise("Select certificate file", "*.pem", true)
}
}
- Text {
+ AccessibleText {
color: datovkaPalette.text
text: qsTr("Account title")
}
- TextField {
+ AccessibleTextField {
id: accountNameTextField
width: parent.width
height: inputItemHeight
@@ -250,11 +227,11 @@ Item {
}
}
}
- Text {
+ AccessibleText {
color: datovkaPalette.text
text: qsTr("Username")
}
- TextField {
+ AccessibleTextField {
id: userNameTextField
width: parent.width
height: inputItemHeight
@@ -273,11 +250,11 @@ Item {
}
}
}
- Text {
+ AccessibleText {
color: datovkaPalette.text
text: qsTr("Password")
}
- TextField {
+ AccessibleTextField {
id: passwordTextField
width: parent.width
height: inputItemHeight
@@ -297,31 +274,31 @@ Item {
}
}
}
- Switch {
+ AccessibleSwitch {
id: rememberPassword
text: qsTr("Remember password")
font.pointSize: defaultTextFont.font.pointSize
checked: true
}
- Switch {
+ AccessibleSwitch {
id: testAccount
text: qsTr("Test account")
font.pointSize: defaultTextFont.font.pointSize
}
- Text {
+ AccessibleText {
id: testAccountLabel
color: datovkaPalette.mid
width: parent.width
text: qsTr("Test accounts are used to access the ISDS testing environment.")
wrapMode: Text.Wrap
}
- Switch {
+ AccessibleSwitch {
id: useLS
font.pointSize: defaultTextFont.font.pointSize
text: qsTr("Use local storage (database)")
checked: true
}
- Text {
+ AccessibleText {
color: datovkaPalette.mid
width: parent.width
text: (useLS.checked ?
@@ -340,7 +317,7 @@ Item {
testAccount.checked = isTestAccount
useLS.checked = storeToDisk
certPathLabelId.text = certPath
- loginMethodComboBox.currentIndex = loginMethod
+ loginMethodComboBox.selectCurrentKey(loginMethod)
userNameTextField.enabled = false
testAccount.enabled = false
headerBar.title = qsTr("Account settings")
diff --git a/qml/pages/PageSettingsGeneral.qml b/qml/pages/PageSettingsGeneral.qml
index 46760be351cd64797aeeea2eaa8629473756d75f..4d5de6b331da410deef525fef93d317f4692616f 100644
--- a/qml/pages/PageSettingsGeneral.qml
+++ b/qml/pages/PageSettingsGeneral.qml
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014-2017 CZ.NIC
+ * Copyright (C) 2014-2018 CZ.NIC
*
* 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
@@ -35,14 +35,7 @@ Item {
property var accountModel: null
Component.onCompleted: {
- var lang = settings.language()
- var langugeComboBoxIndex = 0;
- if (lang === "cs") {
- langugeComboBoxIndex = 1;
- } else if (lang === "en") {
- langugeComboBoxIndex = 2;
- }
- languageComboBoxId.currentIndex = langugeComboBoxIndex
+ languageComboBox.selectCurrentKey(settings.language())
fontSizeSpinBox.setVal(settings.fontSize())
}
@@ -53,16 +46,10 @@ Item {
PageHeader {
id: headerBar
title: qsTr("General settings")
- MouseArea {
- anchors.left: parent.left
- anchors.top: parent.top
- anchors.bottom: parent.bottom
- width: parent.width * backMouseAreaRatio
- onClicked: {
- pageView.pop(StackView.Immediate)
- }
+ onBackClicked: {
+ pageView.pop(StackView.Immediate)
}
- } // PageHeader
+ }
Flickable {
id: flickable
z: 0
@@ -78,79 +65,54 @@ Item {
anchors.right: parent.right
anchors.left: parent.left
spacing: formItemVerticalSpacing
- Text {
+ AccessibleText {
id: languageLabel
color: datovkaPalette.text
text: qsTr("Language")
}
- ComboBox {
- id: languageComboBoxId
- currentIndex: 0
+ AccessibleComboBox {
+ id: languageComboBox
width: parent.width
- height: inputItemHeight
- textRole: "label"
- font.pointSize: defaultTextFont.font.pointSize
- delegate: ItemDelegate {
- width: languageComboBoxId.width
- height: inputItemHeight
- contentItem: Text {
- text: label
- color: datovkaPalette.text
- font.pointSize: defaultTextFont.font.pointSize
- elide: Text.ElideRight
- verticalAlignment: Text.AlignVCenter
- }
- highlighted: languageComboBoxId.highlightedIndex == index
- }
+ accessibleDescription: qsTr("Select language")
model: ListModel {
id: langMethodModel
- // Don't change position of list elements, keys and values.
- ListElement { label: qsTr("System"); value: "system" }
- ListElement { label: qsTr("Czech"); value: "cs" }
- ListElement { label: qsTr("English"); value: "en" }
+ /* Don't change keys and labels. */
+ ListElement { label: qsTr("System"); key: "system" }
+ ListElement { label: qsTr("Czech"); key: "cs" }
+ ListElement { label: qsTr("English"); key: "en" }
}
- onCurrentIndexChanged: settings.setLanguage(langMethodModel.get(currentIndex).value)
+ onCurrentIndexChanged: settings.setLanguage(currentKey())
}
- Text {
+ AccessibleText {
color: datovkaPalette.mid
width: parent.width
text: qsTr("Note: Language will be changed after application restart.")
wrapMode: Text.Wrap
}
- Text {
+ AccessibleText {
id: fontSizeLabel
color: datovkaPalette.text
width: parent.width
text: qsTr("Font size and application scale")
}
- SpinBox {
+ AccessibleSpinBox {
/* Actually holds font pixel size. */
id: fontSizeSpinBox
- height: inputItemHeight
- font.pointSize: defaultTextFont.font.pointSize
+
property int dflt: 16
from: 14
to: 20
stepSize: 1
+
+ accessibleDescription: qsTr("Set application font size")
+
/*
* Cannot use onValueChanged here because this resets
* the font size to minimal value on spin box creation.
*/
onValueModified: settings.setFontSize(fontSizeSpinBox.val())
- function val() {
- return value
- }
- function setVal(v) {
- if (v < from) {
- value = from
- } else if (v > to) {
- value = to
- } else {
- value = v
- }
- }
}
- Text {
+ AccessibleText {
color: datovkaPalette.mid
width: parent.width
text: qsTr("Note: Font size will be changed after application restart. Default is %1.").arg(fontSizeSpinBox.dflt)
diff --git a/qml/pages/PageSettingsPin.qml b/qml/pages/PageSettingsPin.qml
index 39cb2eb78f19d167472e4415223b9a19caf878c6..d1f1b186aeaffde0794e91f63d894bebd180369c 100644
--- a/qml/pages/PageSettingsPin.qml
+++ b/qml/pages/PageSettingsPin.qml
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014-2017 CZ.NIC
+ * Copyright (C) 2014-2018 CZ.NIC
*
* 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
@@ -119,20 +119,12 @@ Item {
PageHeader {
id: headerBar
title: qsTr("PIN Settings")
- MouseArea {
- anchors.left: parent.left
- anchors.top: parent.top
- anchors.bottom: parent.bottom
- width: parent.width * backMouseAreaRatio
- onClicked: {
- onClicked: {
- if (actionName != "unspecified") {
- /* Navigate to initial action. */
- actionName = "unspecified"
- } else {
- pageView.pop(StackView.Immediate)
- }
- }
+ onBackClicked: {
+ if (actionName != "unspecified") {
+ /* Navigate to initial action. */
+ actionName = "unspecified"
+ } else {
+ pageView.pop(StackView.Immediate)
}
}
Row {
@@ -140,25 +132,46 @@ Item {
spacing: defaultMargin
anchors.right: parent.right
anchors.rightMargin: defaultMargin
- Image {
+ AccessibleImageButton {
id: acceptElement
anchors.verticalCenter: parent.verticalCenter
sourceSize.height: imgHeightHeader
source: "qrc:/ui/checkbox-marked-circle.svg"
- MouseArea {
- anchors.fill: parent
- onClicked: {
- if (actionName == "unspecified") {
- if (currentPIN == "") {
- settings.setInactivityInterval(0)
- locker.setInactivityInterval(0)
- } else {
- settings.setInactivityInterval(lockIntervalSpinBox.val())
- locker.setInactivityInterval(lockIntervalSpinBox.val())
+ accessibleName: qsTr("Accept changes")
+ onClicked: {
+ if (actionName == "unspecified") {
+ if (currentPIN == "") {
+ settings.setInactivityInterval(0)
+ locker.setInactivityInterval(0)
+ } else {
+ settings.setInactivityInterval(lockIntervalSpinBox.val())
+ locker.setInactivityInterval(lockIntervalSpinBox.val())
+ }
+ pageView.pop(StackView.Immediate)
+ /* set new pin code */
+ } else if (actionName == "new") {
+ if (pinConfirmField1.text == "" || pinConfirmField2.text == "") {
+ errLineText.text = qsTr("Error: Both new PIN code fields must be filled in!")
+ errLineText.visible = true
+ if (pinConfirmField1.text == "") {
+ pinConfirmField1.focus = true
+ } else if (pinConfirmField2.text == "") {
+ pinConfirmField2.focus = true
}
+ } else if (pinConfirmField2.text != pinConfirmField1.text) {
+ pinConfirmField2.focus = true
+ errLineText.text = qsTr("Error: Newly entered PIN codes are different!")
+ errLineText.visible = true
+ } else {
+ errLineText.visible = false
+ settings.updatePinSettings(pinConfirmField1.text.toString())
+ settings.saveAllSettings(accountModel)
pageView.pop(StackView.Immediate)
- /* set new pin code */
- } else if (actionName == "new") {
+ }
+ /* change current pin code */
+ } else if (actionName == "change") {
+ if (pinValueField.text == currentPIN) {
+ errLineText.visible = false
if (pinConfirmField1.text == "" || pinConfirmField2.text == "") {
errLineText.text = qsTr("Error: Both new PIN code fields must be filled in!")
errLineText.visible = true
@@ -177,49 +190,26 @@ Item {
settings.saveAllSettings(accountModel)
pageView.pop(StackView.Immediate)
}
- /* change current pin code */
- } else if (actionName == "change") {
- if (pinValueField.text == currentPIN) {
- errLineText.visible = false
- if (pinConfirmField1.text == "" || pinConfirmField2.text == "") {
- errLineText.text = qsTr("Error: Both new PIN code fields must be filled in!")
- errLineText.visible = true
- if (pinConfirmField1.text == "") {
- pinConfirmField1.focus = true
- } else if (pinConfirmField2.text == "") {
- pinConfirmField2.focus = true
- }
- } else if (pinConfirmField2.text != pinConfirmField1.text) {
- pinConfirmField2.focus = true
- errLineText.text = qsTr("Error: Newly entered PIN codes are different!")
- errLineText.visible = true
- } else {
- errLineText.visible = false
- settings.updatePinSettings(pinConfirmField1.text.toString())
- settings.saveAllSettings(accountModel)
- pageView.pop(StackView.Immediate)
- }
- } else {
- pinValueField.text = ""
- pinValueField.focus = true
- errLineText.text = qsTr("Error: Current PIN code is wrong!")
- errLineText.visible = true
- }
- /* remove/disable current pin code */
- } else if (actionName == "disable") {
- if (pinValueField.text == currentPIN) {
- errLineText.visible = false
- settings.updatePinSettings("")
- settings.saveAllSettings(accountModel)
- settings.setInactivityInterval(0)
- locker.setInactivityInterval(0)
- pageView.pop(StackView.Immediate)
- } else {
- pinValueField.text = ""
- pinValueField.focus = true
- errLineText.text = qsTr("Error: Current PIN code is wrong!")
- errLineText.visible = true
- }
+ } else {
+ pinValueField.text = ""
+ pinValueField.focus = true
+ errLineText.text = qsTr("Error: Current PIN code is wrong!")
+ errLineText.visible = true
+ }
+ /* remove/disable current pin code */
+ } else if (actionName == "disable") {
+ if (pinValueField.text == currentPIN) {
+ errLineText.visible = false
+ settings.updatePinSettings("")
+ settings.saveAllSettings(accountModel)
+ settings.setInactivityInterval(0)
+ locker.setInactivityInterval(0)
+ pageView.pop(StackView.Immediate)
+ } else {
+ pinValueField.text = ""
+ pinValueField.focus = true
+ errLineText.text = qsTr("Error: Current PIN code is wrong!")
+ errLineText.visible = true
}
}
}
@@ -241,7 +231,7 @@ Item {
anchors.right: parent.right
anchors.left: parent.left
spacing: formItemVerticalSpacing
- Text {
+ AccessibleText {
id: topLineText
anchors.horizontalCenter: parent.horizontalCenter
color: datovkaPalette.mid
@@ -250,7 +240,7 @@ Item {
horizontalAlignment: Text.AlignHCenter
wrapMode: Text.Wrap
}
- Button {
+ AccessibleButton {
id: setPinButton
height: inputItemHeight
font.pointSize: defaultTextFont.font.pointSize
@@ -260,7 +250,7 @@ Item {
actionName = "new"
}
}
- Button {
+ AccessibleButton {
id: changePinButton
height: inputItemHeight
font.pointSize: defaultTextFont.font.pointSize
@@ -270,7 +260,7 @@ Item {
actionName = "change"
}
}
- Button {
+ AccessibleButton {
id: disablePinButton
height: inputItemHeight
font.pointSize: defaultTextFont.font.pointSize
@@ -280,7 +270,7 @@ Item {
actionName = "disable"
}
}
- TextField {
+ AccessibleTextField {
id: pinValueField
anchors.horizontalCenter: parent.horizontalCenter
height: inputItemHeight
@@ -292,7 +282,7 @@ Item {
horizontalAlignment: TextInput.AlignHCenter
text: ""
}
- TextField {
+ AccessibleTextField {
id: pinConfirmField1
anchors.horizontalCenter: parent.horizontalCenter
height: inputItemHeight
@@ -304,7 +294,7 @@ Item {
horizontalAlignment: TextInput.AlignHCenter
text: ""
}
- TextField {
+ AccessibleTextField {
id: pinConfirmField2
anchors.horizontalCenter: parent.horizontalCenter
height: inputItemHeight
@@ -316,7 +306,7 @@ Item {
horizontalAlignment: TextInput.AlignHCenter
text: ""
}
- Text {
+ AccessibleText {
id: errLineText
anchors.horizontalCenter: parent.horizontalCenter
font.bold: true
@@ -326,7 +316,7 @@ Item {
horizontalAlignment: Text.AlignHCenter
wrapMode: Text.Wrap
}
- Text {
+ AccessibleText {
id: lockIntervalLabel
color: datovkaPalette.text
anchors.horizontalCenter: parent.horizontalCenter
@@ -334,15 +324,18 @@ Item {
text: qsTr("Lock after seconds of inactivity")
horizontalAlignment: Text.AlignHCenter
}
- SpinBoxZeroMax {
+ AccessibleSpinBoxZeroMax {
/* Holds value in seconds. */
id: lockIntervalSpinBox
+
anchors.horizontalCenter: parent.horizontalCenter
- height: inputItemHeight
- font.pointSize: defaultTextFont.font.pointSize
+
/* Must be a non-decreasing list ending with infinity. */
items: [15, 30, 60, 90, 120, 150, 180, qsTr("don't lock")]
dfltIdx: 0
+
+ accessibleDescription: qsTr("Select the number of seconds after which the application is going to be locked.")
+
onValueModified: {
/* Enable accept button. Always visible? */
acceptElement.visible = val() != settings.inactivityInterval()
diff --git a/qml/pages/PageSettingsStorage.qml b/qml/pages/PageSettingsStorage.qml
index 0103518dfbc1835c88b8d0fa38a3ba986c6a5945..5880d3631e89516a1c851b2c2f269e4c0c1026e6 100644
--- a/qml/pages/PageSettingsStorage.qml
+++ b/qml/pages/PageSettingsStorage.qml
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014-2017 CZ.NIC
+ * Copyright (C) 2014-2018 CZ.NIC
*
* 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
@@ -60,16 +60,10 @@ Item {
PageHeader {
id: headerBar
title: qsTr("Storage settings")
- MouseArea {
- anchors.left: parent.left
- anchors.top: parent.top
- anchors.bottom: parent.bottom
- width: parent.width * backMouseAreaRatio
- onClicked: {
- pageView.pop(StackView.Immediate)
- }
+ onBackClicked: {
+ pageView.pop(StackView.Immediate)
}
- } // PageHeader
+ }
Flickable {
id: flickable
z: 0
@@ -85,22 +79,24 @@ Item {
anchors.right: parent.right
anchors.left: parent.left
spacing: formItemVerticalSpacing
- Text {
+ AccessibleText {
id: messageLifeLabel
color: datovkaPalette.text
text: qsTr("Number of days to keep messages")
}
- SpinBoxZeroMax {
+ AccessibleSpinBoxZeroMax {
/* Holds value in days. */
id: messageLifeSpinBox
- height: inputItemHeight
- font.pointSize: defaultTextFont.font.pointSize
+
/* Must be a non-decreasing list ending with infinity. */
items: [90, 95, 100, 105, 110, 115, 120, 125, 130, 135, 140, 145, 150, 155, 160, 165, 170, 175, 180, qsTr("don't delete")]
dfltIdx: 0
+
+ accessibleDescription: qsTr("Select the number of days how long downloaded messages are kept in local storage after download.")
+
onValueModified: settings.setMessageLifeDays(messageLifeSpinBox.val())
}
- Text {
+ AccessibleText {
color: datovkaPalette.mid
width: parent.width
text: if (messageLifeSpinBox.val() === 0) {
@@ -110,22 +106,24 @@ Item {
}
wrapMode: Text.Wrap
}
- Text {
+ AccessibleText {
id: attachLifeLabel
color: datovkaPalette.text
text: qsTr("Number of days to keep attachments")
}
- SpinBoxZeroMax {
+ AccessibleSpinBoxZeroMax {
/* Holds value in days. */
id: attachLifeSpinBox
- height: inputItemHeight
- font.pointSize: defaultTextFont.font.pointSize
+
/* Must be a non-decreasing list ending with infinity. */
items: [5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, qsTr("like messages")]
dfltIdx: 1
+
+ accessibleDescription: qsTr("Select the number of days how long message content is kept in local storage after download.")
+
onValueModified: settings.setAttachmentLifeDays(attachLifeSpinBox.val())
}
- Text {
+ AccessibleText {
color: datovkaPalette.mid
width: parent.width
text: if (attachLifeSpinBox.val() === 0) {
@@ -135,44 +133,46 @@ Item {
}
wrapMode: Text.Wrap
}
- Text {
+ AccessibleText {
id: zfoLifeLabel
color: datovkaPalette.text
text: qsTr("ZFO storage size limit in MB")
}
- SpinBox {
+ AccessibleSpinBox {
/* Holds value in MBs. */
id: zfoDbSizeSpinBox
- height: inputItemHeight
- font.pointSize: defaultTextFont.font.pointSize
+
from: 0
to: 1000
stepSize: 100
- onValueModified: settings.setZfoDbSizeMBs(zfoDbSizeSpinBox.value)
+
+ accessibleDescription: qsTr("Specify the maximal amount of memory for preserving recently downloaded messages.")
+
+ onValueModified: settings.setZfoDbSizeMBs(zfoDbSizeSpinBox.val())
}
- Text {
+ AccessibleText {
color: datovkaPalette.mid
width: parent.width
- text: if (zfoDbSizeSpinBox.value === 0) {
+ text: if (zfoDbSizeSpinBox.val() === 0) {
qsTr("Message ZFO data won't be automatically stored.")
} else {
- qsTr("Maximum size of stored message ZFO data is set to %1 MB. Default is %2 MB.").arg(zfoDbSizeSpinBox.value).arg(200)
+ qsTr("Maximum size of stored message ZFO data is set to %1 MB. Default is %2 MB.").arg(zfoDbSizeSpinBox.val()).arg(200)
}
wrapMode: Text.Wrap
}
- Text {
+ AccessibleText {
id: dbPathLabel
color: datovkaPalette.text
text: qsTr("Databases location")
}
- Text {
+ AccessibleText {
id: dbPathText
color: datovkaPalette.mid
width: parent.width
wrapMode: Text.Wrap
text: ""
}
- Button {
+ AccessibleButton {
id: dbPathButton
font.pointSize: defaultTextFont.font.pointSize
height: inputItemHeight
@@ -190,7 +190,7 @@ Item {
}
}
}
- Button {
+ AccessibleButton {
id: dbResetPathButton
text: qsTr("Set default")
font.pointSize: defaultTextFont.font.pointSize
@@ -208,12 +208,12 @@ Item {
}
}
}
- Text {
+ AccessibleText {
id: vacuumLabel
color: datovkaPalette.text
text: qsTr("Clean up all databases")
}
- Button {
+ AccessibleButton {
id: vacuumButton
font.pointSize: defaultTextFont.font.pointSize
height: inputItemHeight
@@ -222,7 +222,7 @@ Item {
files.vacuumFileDbs()
}
}
- Text {
+ AccessibleText {
id: vacuumText
color: datovkaPalette.mid
width: parent.width
diff --git a/qml/pages/PageSettingsSync.qml b/qml/pages/PageSettingsSync.qml
index 59d3839c105d086962d9ab9b452a66883fcb6291..11511c28b0c536985d0e3bc8637da1e0aa2fd36a 100644
--- a/qml/pages/PageSettingsSync.qml
+++ b/qml/pages/PageSettingsSync.qml
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014-2017 CZ.NIC
+ * Copyright (C) 2014-2018 CZ.NIC
*
* 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
@@ -46,16 +46,10 @@ Item {
PageHeader {
id: headerBar
title: qsTr("Synchronization settings")
- MouseArea {
- anchors.left: parent.left
- anchors.top: parent.top
- anchors.bottom: parent.bottom
- width: parent.width * backMouseAreaRatio
- onClicked: {
- pageView.pop(StackView.Immediate)
- }
+ onBackClicked: {
+ pageView.pop(StackView.Immediate)
}
- } // PageHeader
+ }
Flickable {
id: flickable
z: 0
@@ -71,14 +65,14 @@ Item {
anchors.right: parent.right
anchors.left: parent.left
spacing: formItemVerticalSpacing
- Switch {
+ AccessibleSwitch {
id: downloadOnlyNewMsgs
text: qsTr("Download only newer messages")
font.pointSize: defaultTextFont.font.pointSize
checked: true
onClicked: settings.setDownloadOnlyNewMsgs(downloadOnlyNewMsgs.checked)
}
- Text {
+ AccessibleText {
id: downloadOnlyNewDescription
color: datovkaPalette.mid
width: parent.width
@@ -87,13 +81,13 @@ Item {
qsTr("All available messages (including those in the data vault) will be downloaded."))
wrapMode: Text.Wrap
}
- Switch {
+ AccessibleSwitch {
id: downloadCompleteMsgs
text: qsTr("Download complete messages")
font.pointSize: defaultTextFont.font.pointSize
onClicked: settings.setDownloadCompleteMsgs(downloadCompleteMsgs.checked)
}
- Text {
+ AccessibleText {
color: datovkaPalette.mid
width: parent.width
text: (downloadCompleteMsgs.checked ?
diff --git a/res/locale/datovka_cs.ts b/res/locale/datovka_cs.ts
index be2c8f1f2264346c9d5226f3bed7ec2fb98bac9f..08f840687ed1d104dc04eb9b4b9c040270799388 100644
--- a/res/locale/datovka_cs.ts
+++ b/res/locale/datovka_cs.ts
@@ -1,69 +1,132 @@
+
+ AccessibleSpinBox
+
+
+
+ Decrease value '%1'.
+ Snížit hodnotu '%1'.
+
+
+
+
+ Increase value '%1'.
+ Zvýšit hodnotu '%1'.
+
+
+
+ AccessibleSpinBoxZeroMax
+
+
+
+ max
+ max
+
+
+
+
+ Decrease value '%1'.
+ Snížit hodnotu '%1'.
+
+
+
+
+ Increase value '%1'.
+ Zvýšit hodnotu '%1'.
+
+Accounts
-
+ Remove account: %1Odstranit účet: %1
-
+ Do you want to remove the account '%1'?Opravdu chcete odstranit účet '%1'?
-
+ Note: It will also remove all related local databases and account information.Poznámka: Budou odstraněny také všechny odpovídající lokální databáze a informace o účtu.
-
+ Problem while updating accountProblém při vytváření účtu
-
+ Account name has not been specified!Název účtu nebyl vyplněn!
-
+ This field must be filled in.Tato položka musí být vyplněna.
-
+ Problem while creating accountProblém při vytváření účtu
-
+ User name, password or account name has not been specified!Uživatelské jméno, heslo nebo jméno účtu nebylo vyplněno!
-
+ These fields must be filled in.Tyto položky musí být vyplněny.
-
+ Creating account: %1Vytváření účtu: %1
-
+ Account '%1' could not be created.Účet '%1' nemohl být vytvořen.
-
+ Account with user name '%1' already exists.Účet s uživatelským jménem '%1' již existuje.
+
+ DataboxList
+
+
+
+ View details about data box '%1' (identifier '%2').
+ Zobrazit informace o datové schránce '%1' (identifikátor '%2').
+
+
+
+
+ Deselect data box '%1' (identifier '%2').
+ Zrušit výběr datové schránky '%1' (identifikátor '%2').
+
+
+
+
+ Select data box '%1' (identifier '%2').
+ Vybrat datovou schránku '%1' (identifikátor '%2').
+
+
+
+
+ Remove data box '%1' (identifier '%2').
+ Odebrat datovou schránku '%1' (identifikátor '%2').
+
+DbWrapper
@@ -236,41 +299,83 @@
FileDialogue
-
-
+
+ Select pathVybrat cestu
-
-
+
+
+ Cancel
+ Zrušit
+
+
+
+
+ OK
+ OK
+
+
+
+
+ Select location type
+ Vyberte typ umístění
+
+
+
+ DesktopPlocha
-
-
+
+ DocumentsDokumenty
-
-
+
+ DownloadsStažené
-
-
+
+ PicturesObrázky
-
-
+
+ TempDočasné
+
+
+
+ Up
+ Nahoru
+
+
+
+
+ Open directory.
+ Otevřít adresář.
+
+
+
+
+ File is selected.
+ Soubor je vybrán.
+
+
+
+
+ File is not selected.
+ Soubor není vybrán.
+ Files
@@ -352,8 +457,8 @@
InputDialogue
-
-
+
+ QML input dialogQML vstupní dialog
@@ -1008,30 +1113,57 @@
MessageDialogue
-
-
+
+ QuestionDotaz
-
-
+
+ InformationInformace
-
-
+
+ WarningVarování
-
-
+
+ CriticalKritické
+
+ MessageList
+
+
+
+ Unread message from sender
+ Nepřečtená zpráva od odesílatele
+
+
+
+
+ Read message from sender
+ Přečtená zpráva od odesílatele
+
+
+
+
+ Message to receiver
+ Zpráva příjemci
+
+
+
+
+ Subject
+ Předmět
+
+Messages
@@ -1167,16 +1299,22 @@
O Datovce
-
-
+
+ Datovka - free mobile Data-Box clientDatovka - svobodný mobilní klient pro Datové schránky
-
-
- Version
- Verze
+
+
+ Open application home page.
+ Otevřít domovskou stránku aplikace.
+
+
+
+
+ Version: %1
+ Verze: %1
@@ -1185,23 +1323,29 @@
Tato aplikace poskytuje přístup k datovým schránkám v systému ISDS. Dovoluje Vám stahovat a prohlížet obsah zpráv uvnitř datové schránky. Můžete také, s jistými omezeními, z této aplikace zprávy odesílat.
-
-
+
+ You may use this application only at your own risk. The association CZ.NIC is not the operator of the data box system. CZ.NIC is not liable for any damage that may be directly or indirectly caused by using this application.Tuto aplikaci můžete používat pouze na vlastní nebezpečí. Sdružení CZ.NIC není provozovatelem systému datových schránek. CZ.NIC neručí za zádné škody, které mohou být přímo či nepřímo způsobeny použitím této aplikace.
-
-
+
+ If you have problems using this application or want help or you just want more information then start by reading through the information in the <a href="%1">user manual</a> or on the <a href="%2">project web page</a>.Máte-li potíže s používáním této aplikace, potřebujete-li pomoc, či jen chcete další informace, tak začněte pročítáním informací v <a href="%1">uživatelské příručce</a> nebo na <a href="%2">webových stránkách projektu</a>.
-
-
+
+ Powered byVyvíjeno
+
+
+
+ Open home page of the CZ.NIC association.
+ Otevřít domovskou stránku sdružení CZ.NIC.
+ PageAccountDetail
@@ -1212,8 +1356,14 @@
Informace o účtu
-
-
+
+
+ Refresh information about the account.
+ Obnovit informace o účtu.
+
+
+
+ Account info has not been downloaded yet.Informace o účtu nebyly doposud staženy.
@@ -1221,23 +1371,71 @@
PageAccountList
-
-
+
+
+ Show information about the application.
+ Zobrazit informace o aplikaci.
+
+
+
+
+ Synchronise all accounts.
+ Synchronizovat všechny účty.
+
+
+
+
+ Show application preferences.
+ Zobrazit nastavení aplikace.
+
+
+
+ Add a new accountPřidat nový účet
-
-
+
+
+ Account '%1'.
+ Účet '%1'.
+
+
+
+
+ Testing account '%1'.
+ Testovací účet '%1'.
+
+
+
+
+ Synchronise account '%1'.
+ Synchronizovat účet '%1'.
+
+
+
+ Received messagesPřijaté zprávy
-
-
+
+
+ Received messages of account '%1'. (Unread %2 of %3 received messages.)
+ Přijaté zprávy účtu '%1'. (Nepřečteno %2 z %3 přijatých zpráv.)
+
+
+
+ Sent messagesOdeslané zprávy
+
+
+
+ Sent messages of account '%1'. (Total of %2 sent messages.)
+ Odeslané zprávy účtu '%1'. (Celkem %2 odeslaných zpráv.)
+ PageChangePassword
@@ -1278,92 +1476,98 @@
Změnit heslo
-
-
+
+
+ Accept changes
+ Přijmout změny
+
+
+
+ Old password and new password must be filled!Staré heslo a nové heslo musí být vyplněno!
-
-
+
+ SMS code must be filled!SMS kód musí být vyplněn!
-
-
+
+ Security code must be filled!Bezpečnostní kód musí být vyplněn!
-
-
+
+ Password change failed!Změna hesla se nezdařila!
-
-
+
+ Wrong password format! The new password must contain at least 8 characters including at least 1 number and at least 1 upper-case letter.Špatný formát hesla! Nové heslo musí obsahovat nejméně 8 znaků, alespoň 1 číslici a alespoň 1 velké písmeno.
-
-
+
+ The entered new passwords do not match!Nově zadaná hesla si neodpovídají!
-
-
+
+ Enter the current password and a new password.Zadejte aktuální heslo a nové heslo.
-
-
+
+ Current passwordAktuální heslo
-
-
+
+ New passwordNové heslo
-
-
+
+ Confirm the new passwordPotvrďte nové heslo
-
-
+
+ Send SMS codeZaslat kód SMS
-
-
+
+ Enter current password for SMS code sending!Zadejte aktuální heslo pro odesílání SMS kódu!
-
-
+
+ SMS code was sent...SMS kód byl odeslán...
-
-
+
+ SMS code cannot be sent! Wrong current password or ISDS server is out of service.SMS kód nelze odeslat! Chybné aktuální heslo nebo ISDS server je mimo provoz.
-
-
+
+ Enter OTP codeZadejte OTP kód
@@ -1377,14 +1581,26 @@
Kontakty
-
-
+
+
+ Filter data boxes.
+ Filtrovat datové schránky.
+
+
+
+ Set filterNastavit filtr
-
-
+
+
+ Clear and hide filter field
+ Vymazat a schovat pole filtru
+
+
+
+ No databox found in contacts.Nenalezeny žádné schránky.
@@ -1392,8 +1608,8 @@
PageDataboxDetail
-
-
+
+ Databox infoInformace o schránce
@@ -1407,88 +1623,130 @@
Vyhledat schránku
-
-
+
+
+ Enter sought phrase
+ Zadejte hledaný text
+
+
+
+
+ Previous
+ Předchozí
+
+
+
+
+ Next
+ Následující
+
+
+
+ Set filterNastavit filtr
-
-
+
+ All databoxesVšechny schránky
-
-
+
+
+ Filter data boxes.
+ Filtrovat datové schránky.
+
+
+
+
+ Search data boxes.
+ Vyhledat datové schránky.
+
+
+
+
+ Select type of sought data box
+ Vyberte typ hledané datové schránky
+
+
+
+ OVMOVM
-
-
+
+ POPO
-
-
+
+ PFOPFO
-
-
+
+ FOFO
-
-
+
+
+ Select entries to search in
+ Vyberte položky, ve kterých se bude vyhledávat
+
+
+
+ All fieldsVšechny položky
-
-
+
+ AddressAdresa
-
-
+
+ IČIČ
-
-
+
+ Databox IDID schránky
-
-
- Enter phrase
- Zadejte text
+
+
+ Clear and hide filter field
+ Vymazat a schovat pole filtru
-
-
+
+ No databox found for given search criteria.Nenalezena žádná schránka pro zadaná kritéria.
-
-
-
-
+
+
+
+ FoundNalezeno
-
-
+
+ ShownZobrazeno
@@ -1496,8 +1754,8 @@
PageHeader
-
-
+
+ BackZpět
@@ -1505,50 +1763,50 @@
PageMenuAccount
-
-
+
+ Account propertiesVlastnosti účtu
-
-
+
+ Account settingsNastavení účtu
-
-
+
+ View account infoZobrazit info o účtu
-
-
+
+ Create messageVytvořit zprávu
-
-
+
+ Find databoxVyhledat schránku
-
-
+
+ Clean up the file databaseVyčistit databázi souborů
-
-
+
+ Change passwordZměnit heslo
-
-
+
+ Delete accountOdstranit účet
@@ -1556,50 +1814,50 @@
PageMenuDatovkaSettings
-
-
+
+ SettingsNastavení
-
-
+
+ Add accountPřidat účet
-
-
+
+ Search messageHledat zprávu
-
-
+
+ GeneralObecné
-
-
+
+ SynchronizationSynchronizace
-
-
+
+ StorageÚložiště
-
-
+
+ Security and PINZabezpečení a PIN
-
-
+
+ User GuideUživatelská příručka
@@ -1607,32 +1865,32 @@
PageMenuMessage
-
-
+
+ MessageZpráva
-
-
+
+ Download attachmentsStáhnout přílohy
-
-
+
+ Mark as readOznačit jako přečtené
-
-
+
+ Mark as unreadOznačit jako nepřečtené
-
-
+
+ Delete messageSmazat zprávu
@@ -1640,50 +1898,50 @@
PageMenuMessageDetail
-
-
+
+ MessageZpráva
-
-
+
+ Download attachmentsStáhnout přílohy
-
-
+
+ ReplyOdpověď
-
-
+
+ ForwardPřeposlat
-
-
+
+ Use as templatePoužít jako šablonu
-
-
+
+ Send attachments by emailOdeslat přílohy emailem
-
-
+
+ Save attachmentsUložit přílohy
-
-
+
+ Delete attachmentsSmazat přílohy
@@ -1691,20 +1949,20 @@
PageMenuMessageList
-
-
+
+ Message operationsOperace se zprávami
-
-
+
+ Mark messages as readOznačit vše jako přečtené
-
-
+
+ Mark messages as unreadOznačit vše jako nepřečtené
@@ -1754,22 +2012,52 @@
ID zprávy
-
-
+
+
+ Email attachments
+ Poslat přílohy emailem
+
+
+
+
+ Save attachments.
+ Uložit přílohy.
+
+
+
+
+ Download message
+ Stáhnout zprávu
+
+
+
+
+ Show menu of available operations
+ Zobrazit menu s dostupnými operacemi
+
+
+
+ AttachmentsPřílohy
-
-
+
+
+ Open attachment '%1'.
+ Otevřít přílohu '%1'.
+
+
+
+ Attachments have not been downloaded yet.
Click the icon or this text for their download.Přílohy nebyly doposud staženy.
Klikněte na ikonu nebo na tento text pro jejich stažení.
-
-
+
+ No attachments present.Přílohy nejsou přítomny.
@@ -1789,20 +2077,38 @@ Klikněte na ikonu nebo na tento text pro jejich stažení.
Přijaté zprávy
-
-
+
+
+ Filter messages.
+ Filtrovat zprávy.
+
+
+
+
+ Show menu of available operations.
+ Zobrazit menu s dostupnými operacemi.
+
+
+
+ Set filterNastavit filtr
-
-
+
+
+ Clear and hide filter field
+ Vymazat a schovat pole filtru
+
+
+
+ No messages or have not been downloaded yet.Žádné zprávy nebo doposud nebyly žádné staženy.
-
-
+
+ No message found that matches filter text '%1'.Nenalezena žádná zpráva odpovídající textu filtru '%1'.
@@ -1816,32 +2122,44 @@ Klikněte na ikonu nebo na tento text pro jejich stažení.
Hledat zprávu
-
-
+
+
+ Search messages.
+ Hledat zprávy.
+
+
+
+
+ Select type of sought messages
+ Vyberte typ hledaných zpráv
+
+
+
+ All messagesVšechny zprávy
-
-
+
+ Received messagesPřijaté zprávy
-
-
+
+ Sent messagesOdeslané zprávy
-
-
+
+ Enter phraseZadejte text
-
-
+
+ No message found for given search phrase.Nenalezena žádná zpráva pro uvedený hledaný text.
@@ -1885,200 +2203,218 @@ Klikněte na ikonu nebo na tento text pro jejich stažení.
Vytvořit zprávu
-
-
+
+
+ Send message
+ Odeslat zprávu
+
+
+
+ Error during message creation.Chyba při vytváření zprávy.
-
-
+
+ GeneralObecné
-
-
+
+ RecipientsPříjemci
-
-
+
+ AttachmentsPřílohy
-
-
+
+ Please fill in the subject of the message, select at least one recipient data box and specify at least one attachment file before sending the message.Před odesláním zprávy vyplňte prosím předmět zprávy, vyberte alespoň jednu datovou schránku příjemce a uveďtě alespoň jeden soubor s přílohou.
-
-
+
+ Sender accountÚčet odesílatele
-
-
+
+ SubjectPředmět
-
-
+
+ Enter subjectZadejte předmět
-
-
+
+ Include sender identificationPřidat identifikaci odesílatele
-
-
+
+ Personal deliveryDoručení do vlastních rukou
-
-
+
+ Allow acceptance through fictionPovolit doručení fikcí
-
-
+
+ Send as OVMPoslat v režimu OVM
-
-
+
+ Pay transfer charges for replyZaplatit poplatky za odpověď
-
-
+
+ AddPřidat
-
-
+
+ FindNajít
-
-
+
+ Add filePřidat soubor
-
-
+
+ Select filesVybrat soubory
-
-
+
+
+ Open file '%1'.
+ Otevřít soubor '%1'.
+
+
+
+ Local databaseLokální databáze
-
-
+
+
+ Remove file '%1' from list.
+ Odebrat soubor '%1' ze seznamu.
+
+
+
+ MandatePověření
-
-
+
+ Our reference numberNaše číslo jednací
-
-
+
+ Our file markNaše spisová značka
-
-
+
+ Your reference numberVaše číslo jednací
-
-
+
+ Your file markVaše spisová značka
-
-
+
+ To handsK rukám
-
-
+
+ par.odst.
-
-
+
+ AdditionalDoplňující
-
-
+
+ Use transfer charges from recipientVyužít platbu příjemce za odpověď
-
-
+
+ let.písm.
-
-
+
+ Enter our reference numberZadejte jednací číslo
-
-
+
+ Enter our file markZadejte spisovou značku
-
-
+
+ Enter your reference numberZadejte jednací číslo
-
-
+
+ Enter your file markZadejte spisovou značku
-
-
+
+ Enter nameZadejte jméno
@@ -2086,20 +2422,20 @@ Klikněte na ikonu nebo na tento text pro jejich stažení.
PageSettingsAccount
-
-
+
+ CertificateCertifikát
-
-
+
+ Choose fileVybrat soubor
-
-
+
+ Login methodZpůsob přihlašování
@@ -2110,104 +2446,116 @@ Klikněte na ikonu nebo na tento text pro jejich stažení.
Nový účet
-
-
+
+ Username + PasswordJméno + Heslo
-
-
+
+ Certificate + PasswordCertifikát + Heslo
-
-
+
+ Password + Security codeHeslo + Bezpečnostní kód
-
-
+
+ Password + Security SMSHeslo + SMS kód
-
-
+
+ Account titlePojmenování účtu
-
-
+
+ UsernameUživatelské jméno
-
-
+
+ PasswordHeslo
-
-
+
+ Enter the login nameZadejte přihlašovací jméno
-
-
+
+
+ Accept changes
+ Přijmout změny
+
+
+
+
+ Select login method
+ Vyberte přihlašovací metodu
+
+
+
+ Enter custom account nameZadejte vlastní název účtu
-
-
+
+ Enter the passwordZadejte heslo
-
-
+
+ Remember passwordZapamatovat si heslo
-
-
+
+ Test accountTestovací účet
-
-
+
+ Test accounts are used to access the ISDS testing environment.Testovací účty jsou využívány k přístupu do testovacího prostředí ISDS.
-
-
+
+ Use local storage (database)Použít lokální úložiště (databázi)
-
-
+
+ Messages and attachments will be locally stored. No active internet connection is needed to access locally stored data.Zprávy a přílohy budou lokálně ukládány. K přístupu lokálně uloženým datům není potřeba aktivního připojení k internetu.
-
-
+
+ Messages and attachments will be stored only temporarily in memory. These data will be lost on application exit.Zprávy a přílohy budou ukládány pouze dočasně v paměti. Tyto data budou při vypnutí aplikace zahozena.
-
-
+
+ Account settingsNastavení účtu
@@ -2215,50 +2563,62 @@ Klikněte na ikonu nebo na tento text pro jejich stažení.
PageSettingsGeneral
-
-
+
+ General settingsObecné nastavení
-
-
+
+ LanguageJazyk
-
-
+
+
+ Select language
+ Vyberte jazyk
+
+
+
+ SystemZe systému
-
-
+
+ CzechČeský
-
-
+
+ EnglishAnglický
-
-
+
+ Note: Language will be changed after application restart.Poznámka: Jazyk bude změněn až po restartu aplikace.
-
-
+
+ Font size and application scaleVelikost písma a měřítko
-
-
+
+
+ Set application font size
+ Nastavit velikost fontu
+
+
+
+ Note: Font size will be changed after application restart. Default is %1.Poznámka: Změna velikosti se projeví až po restartu aplikace. Výchozí hodnota je %1.
@@ -2304,77 +2664,89 @@ Klikněte na ikonu nebo na tento text pro jejich stažení.
Nastavení PINu
-
-
-
-
+
+
+ Accept changes
+ Přijmout změny
+
+
+
+
+
+ Error: Both new PIN code fields must be filled in!Chyba: Obě pole s novým PIN kódem musí být vyplněna!
-
-
-
-
+
+
+
+ Error: Newly entered PIN codes are different!Chyba: Nově zadané PIN kódy se liší!
-
-
-
-
+
+
+
+ Error: Current PIN code is wrong!Chyba: Současný PIN kód je nesprávný!
-
-
+
+ Set PINNastavit PIN
-
-
+
+ Change PINZměnit PIN
-
-
+
+ Disable PINZrušit PIN
-
-
+
+ Current PIN codeSoučasný PIN kód
-
-
+
+ New PIN codeNový PIN kód
-
-
+
+ Confirm new PIN codePotvrdit nový PIN kód
-
-
+
+ Lock after seconds of inactivityZamknout po sekundách neaktivity
-
-
+
+ don't locknezamykat
+
+
+
+ Select the number of seconds after which the application is going to be locked.
+ Vybrat dobu (v sekundách), za jak dlouho se aplikace uzamkne.
+ PageSettingsStorage
@@ -2385,59 +2757,77 @@ Klikněte na ikonu nebo na tento text pro jejich stažení.
Nastavení úložiště
-
-
+
+ Number of days to keep messagesPočet dní pro uchování zpráv
-
-
+
+ don't deletenemazat
-
-
+
+
+ Select the number of days how long downloaded messages are kept in local storage after download.
+ Vybrat dobu (ve dnech), jak dlouho po stažení budou zprávy uchovávány v lokálním úložišti.
+
+
+
+ Messages won't automatically be deleted from the local storage.Zprávy nebudou automaticky mazány z místního úložiště.
-
-
+
+ Messages will be locally stored for a period of %1 days since their acceptance time. Default is %2 days.Zprávy budou uchovávány po dobu %1 dnů od doby dodání. Výchozí hodnota je %2 dnů.
-
-
+
+ Number of days to keep attachmentsPočet dní pro uchování příloh
-
-
+
+ like messagesjako zprávy
-
-
+
+
+ Select the number of days how long message content is kept in local storage after download.
+ Vybrat dobu (ve dnech), jak dlouho po stažení bude v lokálním úložišti uchováván obsah zpráv.
+
+
+
+ Attachments won't be deleted from the local storage as long as the corresponding messages won't be deleted.Přílohy nebudou smazány s místního úložiště po dobu, po kterou nebudou smazány odpovídající zprávy.
-
-
+
+ Attachments will be locally stored, but no longer than corresponding messages, for a period of %1 days since their download time. Default is %2 days.Přílohy budou uchovány po dobu %1 dnů od jejich stažení, ale ne déle než odpovídající zprávy. Výchozí hodnota je %2 dnů.
-
-
+
+ ZFO storage size limit in MBVelikost úložiště ZFO v MB
+
+
+
+ Specify the maximal amount of memory for preserving recently downloaded messages.
+ Určit maximální množství paměti určené pro uchovávání nedávno stažených zpráv.
+
@@ -2496,38 +2886,38 @@ Klikněte na ikonu nebo na tento text pro jejich stažení.
Nastavení synchronizace
-
-
+
+ Download only newer messagesStahovat pouze novější zprávy
-
-
+
+ Only messages which are not older than 90 days will be downloaded.Budou stahovány jen zprávy, které nejsou starší 90 dnů.
-
-
+
+ All available messages (including those in the data vault) will be downloaded.Budou stahovány všechny zprávy (včetně těch v datovém trezoru).
-
-
+
+ Download complete messagesStahovat kompletní zprávy
-
-
+
+ Complete messages will be downloaded during account synchronisation. This may be slow.V průběhu synchronizace účtů budou stahovány kompletní zprávy. To může být pomalé.
-
-
+
+ Only message envelopes will be downloaded during account synchronisation.V průběhu synchronizace účtů budou stahovány pouze obálky zpráv.
@@ -2966,32 +3356,32 @@ Klikněte na ikonu nebo na tento text pro jejich stažení.
ID schránky
-
+ Data box applicationAplikace pro datové schránky
-
+ ZFO file to be viewed.Soubor zfo, který má být zobrazen.
-
+ Last synchronisation: %1Poslední synchronizace: %1
-
+ Security problemBezpečnostní problém
-
+ OpenSSL support is required!Je nezbytná podpora OpenSSL!
-
+ The device does not support OpenSSL. The application won't work correctly.Vaše zařízení nepodporuje OpenSSL. Aplikace nebude pracovat správně.
@@ -3011,15 +3401,6 @@ Klikněte na ikonu nebo na tento text pro jejich stažení.
Interní chyba
-
- SpinBoxZeroMax
-
-
-
- max
- max
-
-TaskFindDataboxFulltext
@@ -3048,26 +3429,26 @@ Klikněte na ikonu nebo na tento text pro jejich stažení.
main
-
-
+
+ VersionVerze
-
-
+
+ Enter PIN codeZadejte PIN kód
-
-
+
+ Wrong PIN code!Špatný PIN kód!
-
-
+
+ EnterVstoupit
diff --git a/res/locale/datovka_en.ts b/res/locale/datovka_en.ts
index ca329ff2c2c194d3b2f4af39e0486adea663671e..5d3e2de7656a26447391152e7f10f04536259429 100644
--- a/res/locale/datovka_en.ts
+++ b/res/locale/datovka_en.ts
@@ -1,69 +1,132 @@
+
+ AccessibleSpinBox
+
+
+
+ Decrease value '%1'.
+
+
+
+
+
+ Increase value '%1'.
+
+
+
+
+ AccessibleSpinBoxZeroMax
+
+
+
+ max
+
+
+
+
+
+ Decrease value '%1'.
+
+
+
+
+
+ Increase value '%1'.
+
+
+Accounts
-
+ Remove account: %1
-
+ Do you want to remove the account '%1'?
-
+ Note: It will also remove all related local databases and account information.
-
+ Problem while updating account
-
+ Account name has not been specified!
-
+ This field must be filled in.
-
+ Problem while creating account
-
+ User name, password or account name has not been specified!
-
+ These fields must be filled in.
-
+ Creating account: %1
-
+ Account '%1' could not be created.
-
+ Account with user name '%1' already exists.
+
+ DataboxList
+
+
+
+ View details about data box '%1' (identifier '%2').
+
+
+
+
+
+ Deselect data box '%1' (identifier '%2').
+
+
+
+
+
+ Select data box '%1' (identifier '%2').
+
+
+
+
+
+ Remove data box '%1' (identifier '%2').
+
+
+DbWrapper
@@ -236,41 +299,83 @@
FileDialogue
-
-
+
+ Select path
-
-
+
+
+ Cancel
+
+
+
+
+
+ OK
+
+
+
+
+
+ Select location type
+
+
+
+
+ Desktop
-
-
+
+ Documents
-
-
+
+ Downloads
-
-
+
+ Pictures
-
-
+
+ Temp
+
+
+
+ Up
+
+
+
+
+
+ Open directory.
+
+
+
+
+
+ File is selected.
+
+
+
+
+
+ File is not selected.
+
+ Files
@@ -352,8 +457,8 @@
InputDialogue
-
-
+
+ QML input dialog
@@ -1007,31 +1112,58 @@
MessageDialogue
-
-
-
- Question
-
-
- Information
+ Question
- Warning
+ Information
+ Warning
+
+
+
+
+ Critical
+
+ MessageList
+
+
+
+ Unread message from sender
+
+
+
+
+
+ Read message from sender
+
+
+
+
+
+ Message to receiver
+
+
+
+
+
+ Subject
+
+
+Messages
@@ -1167,15 +1299,21 @@
-
-
+
+ Datovka - free mobile Data-Box client
-
-
- Version
+
+
+ Open application home page.
+
+
+
+
+
+ Version: %1
@@ -1185,23 +1323,29 @@
-
-
+
+ You may use this application only at your own risk. The association CZ.NIC is not the operator of the data box system. CZ.NIC is not liable for any damage that may be directly or indirectly caused by using this application.
-
-
+
+ If you have problems using this application or want help or you just want more information then start by reading through the information in the <a href="%1">user manual</a> or on the <a href="%2">project web page</a>.
-
-
+
+ Powered by
+
+
+
+ Open home page of the CZ.NIC association.
+
+ PageAccountDetail
@@ -1212,8 +1356,14 @@
-
-
+
+
+ Refresh information about the account.
+
+
+
+
+ Account info has not been downloaded yet.
@@ -1221,23 +1371,71 @@
PageAccountList
-
-
+
+
+ Show information about the application.
+
+
+
+
+
+ Synchronise all accounts.
+
+
+
+
+
+ Show application preferences.
+
+
+
+
+ Add a new account
-
-
+
+
+ Account '%1'.
+
+
+
+
+
+ Testing account '%1'.
+
+
+
+
+
+ Synchronise account '%1'.
+
+
+
+
+ Received messages
-
-
+
+
+ Received messages of account '%1'. (Unread %2 of %3 received messages.)
+
+
+
+
+ Sent messages
+
+
+
+ Sent messages of account '%1'. (Total of %2 sent messages.)
+
+ PageChangePassword
@@ -1278,92 +1476,98 @@
-
-
+
+
+ Accept changes
+
+
+
+
+ Old password and new password must be filled!
-
-
+
+ SMS code must be filled!
-
-
+
+ Security code must be filled!
-
-
+
+ Password change failed!
-
-
+
+ Wrong password format! The new password must contain at least 8 characters including at least 1 number and at least 1 upper-case letter.
-
-
+
+ The entered new passwords do not match!
-
-
+
+ Enter the current password and a new password.
-
-
+
+ Current password
-
-
+
+ New password
-
-
+
+ Confirm the new password
-
-
+
+ Send SMS code
-
-
+
+ Enter current password for SMS code sending!
-
-
+
+ SMS code was sent...
-
-
+
+ SMS code cannot be sent! Wrong current password or ISDS server is out of service.
-
-
+
+ Enter OTP code
@@ -1377,14 +1581,26 @@
-
-
+
+
+ Filter data boxes.
+
+
+
+
+ Set filter
-
-
+
+
+ Clear and hide filter field
+
+
+
+
+ No databox found in contacts.
@@ -1392,8 +1608,8 @@
PageDataboxDetail
-
-
+
+ Databox info
@@ -1407,88 +1623,130 @@
-
-
+
+
+ Enter sought phrase
+
+
+
+
+
+ Previous
+
+
+
+
+
+ Next
+
+
+
+
+ Set filter
-
-
+
+ All databoxes
-
-
+
+
+ Filter data boxes.
+
+
+
+
+
+ Search data boxes.
+
+
+
+
+
+ Select type of sought data box
+
+
+
+
+ OVM
-
-
+
+ PO
-
-
+
+ PFO
-
-
+
+ FO
-
-
+
+
+ Select entries to search in
+
+
+
+
+ All fields
-
-
+
+ Address
-
-
+
+ IČ
-
-
+
+ Databox ID
-
-
- Enter phrase
+
+
+ Clear and hide filter field
-
-
+
+ No databox found for given search criteria.
-
-
-
-
+
+
+
+ Found
-
-
+
+ Shown
@@ -1496,8 +1754,8 @@
PageHeader
-
-
+
+ Back
@@ -1505,50 +1763,50 @@
PageMenuAccount
-
-
+
+ Account properties
-
-
+
+ Account settings
-
-
+
+ View account info
-
-
+
+ Create message
-
-
+
+ Find databox
-
-
+
+ Clean up the file database
-
-
+
+ Change password
-
-
+
+ Delete account
@@ -1556,50 +1814,50 @@
PageMenuDatovkaSettings
-
-
+
+ Settings
-
-
+
+ Add account
-
-
+
+ Search message
-
-
+
+ General
-
-
+
+ Synchronization
-
-
+
+ Storage
-
-
+
+ Security and PIN
-
-
+
+ User Guide
@@ -1607,32 +1865,32 @@
PageMenuMessage
-
-
+
+ Message
-
-
+
+ Download attachments
-
-
+
+ Mark as read
-
-
+
+ Mark as unread
-
-
+
+ Delete message
@@ -1640,50 +1898,50 @@
PageMenuMessageDetail
-
-
+
+ Message
-
-
+
+ Download attachments
-
-
+
+ Reply
-
-
+
+ Forward
-
-
+
+ Use as template
-
-
+
+ Send attachments by email
-
-
+
+ Save attachments
-
-
+
+ Delete attachments
@@ -1691,20 +1949,20 @@
PageMenuMessageList
-
-
+
+ Message operations
-
-
+
+ Mark messages as read
-
-
+
+ Mark messages as unread
@@ -1754,21 +2012,51 @@
-
-
+
+
+ Email attachments
+
+
+
+
+
+ Save attachments.
+
+
+
+
+
+ Download message
+
+
+
+
+
+ Show menu of available operations
+
+
+
+
+ Attachments
-
-
+
+
+ Open attachment '%1'.
+
+
+
+
+ Attachments have not been downloaded yet.
Click the icon or this text for their download.
-
-
+
+ No attachments present.
@@ -1788,20 +2076,38 @@ Click the icon or this text for their download.
-
-
+
+
+ Filter messages.
+
+
+
+
+
+ Show menu of available operations.
+
+
+
+
+ Set filter
-
-
+
+
+ Clear and hide filter field
+
+
+
+
+ No messages or have not been downloaded yet.
-
-
+
+ No message found that matches filter text '%1'.
@@ -1815,32 +2121,44 @@ Click the icon or this text for their download.
-
-
+
+
+ Search messages.
+
+
+
+
+
+ Select type of sought messages
+
+
+
+
+ All messages
-
-
+
+ Received messages
-
-
+
+ Sent messages
-
-
+
+ Enter phrase
-
-
+
+ No message found for given search phrase.
@@ -1884,200 +2202,218 @@ Click the icon or this text for their download.
-
-
+
+
+ Send message
+
+
+
+
+ Error during message creation.
-
-
+
+ General
-
-
+
+ Recipients
-
-
+
+ Attachments
-
-
+
+ Additional
-
-
+
+ Sender account
-
-
+
+ Subject
-
-
+
+ Enter subject
-
-
+
+ Include sender identification
-
-
+
+ Personal delivery
-
-
+
+ Allow acceptance through fiction
-
-
+
+ Send as OVM
-
-
+
+ Pay transfer charges for reply
-
-
+
+ Add
-
-
+
+ Find
-
-
+
+ Add file
-
-
+
+ Select files
-
-
+
+
+ Open file '%1'.
+
+
+
+
+ Local database
-
-
+
+
+ Remove file '%1' from list.
+
+
+
+
+ Mandate
-
-
+
+ Our reference number
-
-
+
+ Our file mark
-
-
+
+ Your reference number
-
-
+
+ Your file mark
-
-
+
+ To hands
-
-
+
+ par.
-
-
+
+ Please fill in the subject of the message, select at least one recipient data box and specify at least one attachment file before sending the message.
-
-
+
+ Use transfer charges from recipient
-
-
+
+ let.
-
-
+
+ Enter our reference number
-
-
+
+ Enter our file mark
-
-
+
+ Enter your reference number
-
-
+
+ Enter your file mark
-
-
+
+ Enter name
@@ -2085,20 +2421,20 @@ Click the icon or this text for their download.
PageSettingsAccount
-
-
+
+ Certificate
-
-
+
+ Choose file
-
-
+
+ Login method
@@ -2109,104 +2445,116 @@ Click the icon or this text for their download.
-
-
+
+
+ Accept changes
+
+
+
+
+
+ Select login method
+
+
+
+
+ Username + Password
-
-
+
+ Certificate + Password
-
-
+
+ Password + Security code
-
-
+
+ Password + Security SMS
-
-
+
+ Enter custom account name
-
-
+
+ Username
-
-
+
+ Enter the login name
-
-
+
+ Password
-
-
+
+ Enter the password
-
-
+
+ Account title
-
-
+
+ Remember password
-
-
+
+ Test account
-
-
+
+ Test accounts are used to access the ISDS testing environment.
-
-
+
+ Use local storage (database)
-
-
+
+ Messages and attachments will be locally stored. No active internet connection is needed to access locally stored data.
-
-
+
+ Messages and attachments will be stored only temporarily in memory. These data will be lost on application exit.
-
-
+
+ Account settings
@@ -2214,50 +2562,62 @@ Click the icon or this text for their download.
PageSettingsGeneral
-
-
+
+ General settings
-
-
+
+ Language
-
-
+
+
+ Select language
+
+
+
+
+ System
-
-
+
+ Czech
-
-
+
+ English
-
-
+
+ Note: Language will be changed after application restart.
-
-
+
+ Font size and application scale
-
-
+
+
+ Set application font size
+
+
+
+
+ Note: Font size will be changed after application restart. Default is %1.
@@ -2303,77 +2663,89 @@ Click the icon or this text for their download.
-
-
-
-
+
+
+ Accept changes
+
+
+
+
+
+
+ Error: Both new PIN code fields must be filled in!
-
-
-
-
+
+
+
+ Error: Newly entered PIN codes are different!
-
-
-
-
+
+
+
+ Error: Current PIN code is wrong!
-
-
+
+ Set PIN
-
-
+
+ Change PIN
-
-
+
+ Disable PIN
-
-
+
+ Current PIN code
-
-
+
+ New PIN code
-
-
+
+ Confirm new PIN code
-
-
+
+ Lock after seconds of inactivity
-
-
+
+ don't lock
+
+
+
+ Select the number of seconds after which the application is going to be locked.
+
+ PageSettingsStorage
@@ -2384,59 +2756,77 @@ Click the icon or this text for their download.
-
-
+
+ Number of days to keep messages
-
-
+
+ don't delete
-
-
+
+
+ Select the number of days how long downloaded messages are kept in local storage after download.
+
+
+
+
+ Messages won't automatically be deleted from the local storage.
-
-
+
+ Messages will be locally stored for a period of %1 days since their acceptance time. Default is %2 days.
-
-
+
+ Number of days to keep attachments
-
-
+
+ like messages
-
-
+
+
+ Select the number of days how long message content is kept in local storage after download.
+
+
+
+
+ Attachments won't be deleted from the local storage as long as the corresponding messages won't be deleted.
-
-
+
+ Attachments will be locally stored, but no longer than corresponding messages, for a period of %1 days since their download time. Default is %2 days.
-
-
+
+ ZFO storage size limit in MB
+
+
+
+ Specify the maximal amount of memory for preserving recently downloaded messages.
+
+
@@ -2495,38 +2885,38 @@ Click the icon or this text for their download.
-
-
+
+ Download only newer messages
-
-
+
+ Only messages which are not older than 90 days will be downloaded.
-
-
+
+ All available messages (including those in the data vault) will be downloaded.
-
-
+
+ Download complete messages
-
-
+
+ Complete messages will be downloaded during account synchronisation. This may be slow.
-
-
+
+ Only message envelopes will be downloaded during account synchronisation.
@@ -2965,32 +3355,32 @@ Click the icon or this text for their download.
-
+ Data box application
-
+ ZFO file to be viewed.
-
+ Last synchronisation: %1
-
+ Security problem
-
+ OpenSSL support is required!
-
+ The device does not support OpenSSL. The application won't work correctly.
@@ -3010,15 +3400,6 @@ Click the icon or this text for their download.
-
- SpinBoxZeroMax
-
-
-
- max
-
-
-TaskFindDataboxFulltext
@@ -3047,26 +3428,26 @@ Click the icon or this text for their download.
main
-
-
+
+ Version
-
-
+
+ Enter PIN code
-
-
+
+ Wrong PIN code!
-
-
+
+ Enter
diff --git a/res/qml.qrc b/res/qml.qrc
index b3e1512abf0d7f0d01a0754f6ebdc3be30e6b0fd..6fe75e7c387e565a7ab03359b876220f8515d0a3 100644
--- a/res/qml.qrc
+++ b/res/qml.qrc
@@ -100,13 +100,26 @@
datovka.pngcznic.pngui/datovka@2x.png
+ ../qml/components/AccessibleButton.qml
+ ../qml/components/AccessibleComboBox.qml
+ ../qml/components/AccessibleImageButton.qml
+ ../qml/components/AccessibleMenu.qml
+ ../qml/components/AccessibleOverlaidImageButton.qml
+ ../qml/components/AccessibleSpinBox.qml
+ ../qml/components/AccessibleSpinBoxZeroMax.qml
+ ../qml/components/AccessibleSwitch.qml
+ ../qml/components/AccessibleTabButton.qml
+ ../qml/components/AccessibleText.qml
+ ../qml/components/AccessibleTextButton.qml
+ ../qml/components/AccessibleTextField.qml../qml/components/DataboxList.qml
+ ../qml/components/FilterBar.qml../qml/components/InputLineMenu.qml../qml/components/MessageList.qml../qml/components/OverlaidImage.qml../qml/components/PageHeader.qml../qml/components/ProgressBar.qml
- ../qml/components/SpinBoxZeroMax.qml
+ ../qml/components/ScrollableListView.qml../qml/dialogues/InputDialogue.qml../qml/dialogues/FileDialogue.qml../qml/dialogues/MessageDialogue.qml
diff --git a/src/accounts.cpp b/src/accounts.cpp
index 465674a8fbf5c6dd951b213132abccecbe55d3ed..252fac91cafd1561612b3bb928af61a3e9baba2f 100644
--- a/src/accounts.cpp
+++ b/src/accounts.cpp
@@ -90,24 +90,8 @@ void Accounts::getAccountData(const QString &userName)
const AcntData &acntData(AccountListModel::globAccounts[userName]);
- /* Set login method model index for combobox in QML page.
- * See AccountSettingsPage.qml for logim method order. Default is:
- * 0 .. Username + Password
- * 1 .. Certificate + Password
- * 2 .. Password + Security code
- * 3 .. Password + Security SMS
- */
- int qmlLoginMethodIndex = 0;
- if (acntData.loginMethod() == USERNAME_PWD_CERT) {
- qmlLoginMethodIndex = 1;
- } else if (acntData.loginMethod() == USERNAME_PWD_HOTP) {
- qmlLoginMethodIndex = 2;
- } else if (acntData.loginMethod() == USERNAME_PWD_TOTP) {
- qmlLoginMethodIndex = 3;
- }
-
emit sendAccountData(acntData.accountName(), userName,
- qmlLoginMethodIndex, acntData.password(), acntData.isTestAccount(),
+ acntData.loginMethod(), acntData.password(), acntData.isTestAccount(),
acntData.rememberPwd(), acntData.storeToDisk(), acntData.certPath());
}
diff --git a/src/accounts.h b/src/accounts.h
index 731bfc04673fd8511d1b21a7d4857c1781458164..7586431144f3132271fd467bfeae8e87390c3fdd 100644
--- a/src/accounts.h
+++ b/src/accounts.h
@@ -156,7 +156,7 @@ signals:
* @param[in] certPath Certificate path (can be null).
*/
void sendAccountData(QString acntName, QString userName,
- int loginMethod, QString password, bool isTestAccount,
+ QString loginMethod, QString password, bool isTestAccount,
bool rememberPwd, bool storeToDisk, QString certPath);
/*!
diff --git a/src/main.cpp b/src/main.cpp
index 9f0b27b8650c7777378850ea8f0ee6358413c456..abffacd6a5cfb460fb4feedf964ad24e822e13b7 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014-2017 CZ.NIC
+ * Copyright (C) 2014-2018 CZ.NIC
*
* 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
@@ -52,6 +52,7 @@
#include "src/qml_interaction/interaction_filesystem.h"
#include "src/qml_interaction/interaction_zfo_file.h"
#include "src/qml_interaction/message_envelope.h"
+#include "src/qml_interaction/string_manipulation.h"
#include "src/settings.h"
#include "src/setwrapper.h"
#include "src/sqlite/db_tables.h"
@@ -122,13 +123,26 @@ const struct QmlTypeEntry qmlPages[] = {
*/
static
const struct QmlTypeEntry qmlComponents[] = {
+ { "AccessibleButton", 1, 0 },
+ { "AccessibleComboBox", 1, 0 },
+ { "AccessibleImageButton", 1, 0 },
+ { "AccessibleMenu", 1, 0 },
+ { "AccessibleOverlaidImageButton", 1, 0 },
+ { "AccessibleSpinBox", 1, 0 },
+ { "AccessibleSpinBoxZeroMax", 1, 0 },
+ { "AccessibleSwitch", 1, 0 },
+ { "AccessibleTabButton", 1, 0 },
+ { "AccessibleText", 1, 0 },
+ { "AccessibleTextButton", 1, 0 },
+ { "AccessibleTextField", 1, 0 },
{ "DataboxList", 1, 0 },
+ { "FilterBar", 1, 0 },
{ "InputLineMenu", 1, 0 },
{ "MessageList", 1, 0 },
{ "OverlaidImage", 1, 0 },
{ "PageHeader", 1, 0 },
{ "ProgressBar", 1, 0 },
- { "SpinBoxZeroMax", 1, 0 },
+ { "ScrollableListView", 1, 0 },
{ NULL, 0, 0 }
};
@@ -273,6 +287,7 @@ int main(int argc, char *argv[])
Files files;
IsdsWrapper isds;
GlobalSettingsQmlWrapper settings;
+ StringManipulation strManipulation;
Zfo zfo;
/* Connect slot for isds cxt delete when account was deleted or updated */
@@ -332,6 +347,7 @@ int main(int argc, char *argv[])
ctx->setContextProperty("accounts", &accounts);
ctx->setContextProperty("files", &files);
ctx->setContextProperty("settings", &settings);
+ ctx->setContextProperty("strManipulation", &strManipulation);
ctx->setContextProperty("locker", &locker);
ctx->setContextProperty("interactionZfoFile", &interactionZfoFile);
ctx->setContextProperty("dlgEmitter", QmlDlgHelper::dlgEmitter);
diff --git a/src/qml_interaction/string_manipulation.cpp b/src/qml_interaction/string_manipulation.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..928d422f87ab60f1e4b1a3a21f75a8740fbc51c3
--- /dev/null
+++ b/src/qml_interaction/string_manipulation.cpp
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2014-2018 CZ.NIC
+ *
+ * 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 .
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations including
+ * the two.
+ */
+
+#include /* QQuickTextDocument? */
+
+#include "src/qml_interaction/string_manipulation.h"
+
+QString StringManipulation::removeRich(const QString &inStr)
+{
+ QTextDocument doc;
+ doc.setHtml(inStr);
+
+ return doc.toPlainText();
+}
diff --git a/src/qml_interaction/string_manipulation.h b/src/qml_interaction/string_manipulation.h
new file mode 100644
index 0000000000000000000000000000000000000000..c4854937c3e97e9a12dae2747bea442298b23394
--- /dev/null
+++ b/src/qml_interaction/string_manipulation.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2014-2018 CZ.NIC
+ *
+ * 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 .
+ *
+ * In addition, as a special exception, the copyright holders give
+ * permission to link the code of portions of this program with the
+ * OpenSSL library under certain conditions as described in each
+ * individual source file, and distribute linked combinations including
+ * the two.
+ */
+
+#ifndef _STRING_MANIPULATION_H_
+#define _STRING_MANIPULATION_H_
+
+#include
+#include
+
+/*!
+ * @brief Convenience class for string manipulation.
+ */
+class StringManipulation : public QObject {
+ Q_OBJECT
+
+public:
+ /*!
+ * @brief Converts rich text to plain text.
+ *
+ * @param[in] inStr String that may contain rich text tags.
+ * @return Plain text.
+ */
+ Q_INVOKABLE static
+ QString removeRich(const QString &inStr);
+};
+
+#endif /* _STRING_MANIPULATION_H_ */