/* AdvoTracker - Hotline tackingtool for Advocats * * Copyright 2020 Ralf Zerres * SPDX-License-Identifier: (0BSD or MIT) * * Based on an example from https://github.com/woboq/qmetaobject-rs/tree/master/examples * Copyright 2019 Olivier Goffart * */ import QtQuick 2.10 // Qt 5.10 import QtQuick.Controls 2.3 // Qt 5.10 import QtQuick.Layouts 1.3 // Qt 5.10 import QtQuick.Controls.Material 2.3 // Qt 5.10 // AdvoTracker Modules import de.networkx.AdvoTracker 1.0 as Nwx import SortFilterProxyModel 0.2 Page { id: pageNumberHarmList //padding: 12 //Material.theme: Material.System //Material.theme: Material.Light //rightPadding: 24 // include AdvoTracker Type 'SearchToolBar' header: SearchToolBar { id: searchToolBar // search field: searchToolBar.text Material.foreground: "white" Layout.fillWidth: true focus:true onFocusChanged: console.log("searchToolBar: Focus changed " + focus) /* Keys.onPressed: { if (event.key == Qt.Key_Ctrl + Qt.Key_S) { console.log("search"); event.accepted = true; } } */ } // simple Filter as starter ... SortFilterProxyModel { id: filterNumberHarm sourceModel: modelNumberHarm filters: [ ValueFilter { //enabled: onlyShowFavoritesCheckbox.checked roleName: "numberHarm" //value: "Administrator" //value: "*" }, AnyOf { RegExpFilter { roleName: "numberHarm" pattern: searchToolBar.text caseSensitivity: Qt.CaseInsensitive } RegExpFilter { roleName: "numberPolicyholder" pattern: searchToolBar.text caseSensitivity: Qt.CaseInsensitive } } ] sorters: [ //RoleSorter { roleName: "userId"; sortOrder: Qt.DescendingOrder }, RoleSorter { roleName: "clerkId"; sortOrder: Qt.AscendingOrder }, StringSorter { roleName: "dateRecored"; sortOrder: Qt.DescendingOrder }, StringSorter { roleName: "numberPolicyholder" } ] } // filterNumberHarm /* complex filter with two roles SortFilterProxyModel { id: filterComplex sourceModel: modelNumberHarm sorters: [ RoleSorter { roleName: "numberHarm"; sortOrder: Qt.DescendingOrder }, StringSorter { roleName: "numberHarm" } ] filters: RegExpFilter { id: nameFilter roleName: "numberHarm" enable: textSearch.nameFilter //pattern: searchToolBar.text pattern: "^" + searchToolBar.text caseSensitivity: Qt.CaseInsensitive } proxyRoles: SwitchRole { name: "sectionRole" filters: RegExpFilter { roleName: "numberHarm" enable: search value: true SwitchRole.value: "*" } defaultRoleName: "numberHarm" } } */ // simple filter: one role, given explicit search pattern /* SortFilterProxyModel { id: filterNumberHarm sourceModel: modelNumberHarm filters: [ ValueFilter { //enabled: onlyShowFavoritesCheckbox.checked roleName: "numberHarm" value: "47114711" //value: "*" }, AnyOf { RegExpFilter { roleName: "numberHarm" pattern: searchToolBar.text caseSensitivity: Qt.CaseInsensitive } RegExpFilter { roleName: "numberPolicyholder" pattern: searchToolBar.text caseSensitivity: Qt.CaseInsensitive } } ] sorters: [ RoleSorter { roleName: "numberHarm"; sortOrder: Qt.AscendingOrder }, //StringSorter { roleName: "numberHarm", "clerkId" } StringSorter { roleName: "numberPolicyholder" } ] } // filterNumberHarm */ Component { id: headerNumberHarmList Pane { id: frameHeaderNumberHarmList Layout.fillWidth: true width: parent.width Material.background: Material.color(Material.Grey) RowLayout { id: rowHeaderNumberHarmList spacing: 8 width: parent.width //anchors.verticalCenter: parent.verticalCenter //anchors.right: parent.right Layout.fillWidth: true //Material.foreground: Material.accent Label { id: labelHeaderNumberHarm text: qsTr("Number harm") //font.pixelsize: 18 Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter Layout.preferredWidth: 150 anchors.left: parent.left } Label { id: labelHeaderNumberPolicyholder text: qsTr("Number policyholder") Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter Layout.fillWidth: true Layout.preferredWidth: 300 Layout.minimumWidth: 300 } Label { id: labelHeaderClerkId text: qsTr("Clerk Id") Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter Layout.fillWidth: true Layout.preferredWidth: 80 Layout.minimumWidth: 80 } Label { id: labelHeaderDateRecorded text: qsTr("Date recorded") Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter Layout.preferredWidth: 200 Layout.minimumWidth: 200 anchors.left: labelHeaderClerkId.right anchors.right: parent.right; //anchors.right: rowHeaderNumberHarmList.right } } // rowHeaderNumberHarmList } // frameHeaderNumberHarmList } // headerNumberHarmList Component { id: footerNumberHarmList Rectangle { id: root width: ListView.view.width height: 20 //color: "#ffffff" //border.color: Qt.darker(color, 1.2) property alias text: label.text property color fontColor: '#1f1f1f' Text { id: label anchors.centerIn: parent //font.pixelSize: 14 color: root.fontColor text: qsTr("List ends here") } } } // footerNumberHarmList Component { id: highlightNumberHarmList Item { width: listNumberHarmList.width height: listNumberHarmList.currentItem.height y: listNumberHarmList.currentItem.y Behavior on y { SequentialAnimation { PropertyAnimation { target: rectangleHeighlight property: "opacity" to: 0 duration: 500 } NumberAnimation { duration: 5 } PropertyAnimation { target: rectangleHeighlight property: "opacity" to: 1 duration: 200 } //SpringAnimation { spring: 2; damping: 0.1 } } } Rectangle { id: rectangleHeighlight width: listNumberHarmList.width height: listNumberHarmList.currentItem.height anchors.fill: parent anchors.margins: 5 color: "lightsteelblue" radius: 5 } // Rectangle } // Item } // highlightNumberHarmList Component { id: delegateNumberHarmList ItemDelegate { id: itemNumberHarmList Layout.fillWidth: true width: parent.width anchors.right: parent.fill focus: true contentItem: RowLayout { id: rowNumberHarmList spacing: 8 anchors.horizontalCenter: parent.horizontalCenter focus: true Label { id: numberHarm text: model.numberHarm Layout.preferredWidth: 150 } Label { id: numberPolicyholder text: model.numberPolicyholder Layout.preferredWidth: 300 Layout.minimumWidth: 300 Layout.fillWidth: true //width: labelHeaderNumberPolicyholder.width //Layout.preferredWidth: labelHeaderNumberPolicyholder.width } Label { id: clerkId text: model.clerkId Layout.preferredWidth: 80 Layout.minimumWidth: 80 Layout.fillWidth: true //width: labelHeaderNumberPolicyholder.width //Layout.preferredWidth: labelHeaderNumberPolicyholder.width } Label { id: dateRecorded text: Qt.formatDateTime(model.dateRecorded, "ddd dd.MM.yyyy hh:mm") Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter Layout.preferredWidth: 200 Layout.minimumWidth: 200 anchors.left: clerkId.right anchors.right: parent.right; } } // rowNumberHarmList (contentItem) // adapt the current item states: State { name: "Current" when: itemNumberHarmList.ListView.isCurrentItem PropertyChanges { target: numberHarm ; color: Material.color(Material.primary, Material.ShadeA700) } //PropertyChanges { target: numberPolicyholder ; color: Material.color(Material.accent, Material.ShadeA700) } } transitions: Transition { NumberAnimation { properties: "color"; duration: 200 } SpringAnimation { spring: 2; damping: 0.1 } } MouseArea { anchors.fill: parent acceptedButtons: Qt.LeftButton onPressed: { console.log("Mouse-Press: left; index:", index, "; iconName:", filterNumberHarm.get(index).numberHarm) itemNumberHarmList.ListView.view.currentIndex = index } onDoubleClicked: { console.log("Mouse-Press: double; index:", index, "; numberHarm:", filterNumberHarm.get(index).numberHarm) console.log("Mouse-Press: double; index:", index, "; userId:", filterNumberHarm.get(index).clerkId) // stackViewMain.push(componentDetail, { numberHarm: filterNumberHarm.get(index).numberHarm } ) stackViewMain.push("qrc:/pages/PageNumberHarm.qml", { numberHarm: filterNumberHarm.get(index).numberHarm } ) //Loader { id: pagePolicy, source: "qrc:/PolicyPage.qml" } } } // MouseArea MouseArea { anchors.fill: parent acceptedButtons: Qt.RightButton onPressed: { console.log("Mouse-Press: right; index:", index, "; numberHarm:", filterNumberHarm.get(index).numberHarm) itemNumberHarmList.ListView.view.currentIndex = index } } // MouseArea Shortcut { context: Qt.ApplicationShortcut sequence: [ StandardKey.NextChild, "Ctrl+N" ] // onActivated: view.currentIndex++ onActivated: itemNumberHarmList.ListView.view.currentIndex++ } Keys.onReturnPressed: { console.log("Key-Press: retrun; index:", index, "; iconName:", filterNumberHarm.get(index).numberHarm) itemNumberHarmList.ListView.view.currentIndex = index stackViewMain.push(componentDetail, { numberHarm: "filterNumberHarm.get(index).numberHarm" } ) } Keys.onTabPressed: { // Windows: Ctrl-Tab, Alt+Right, Ctrl-F6 // Gnome: Ctrl-Tab console.log("Key-Press: Tab; index:", index, "; iconName:", filterNumberHarm.get(index).numberHarm) itemNumberHarmList.ListView.view.currentIndex = index + 1 } Keys.onBacktabPressed: { // Windows: Ctrl-Shift-Tab, Alt+Left, Ctrl-Shift-F6 // Gnome: Ctrl-Shift-Tab, Alt+Left console.log("Key-Press: Backtab (Shift+tab); index:", index, "; iconName:", filterNumberHarm.get(index).numberHarm) itemNumberHarmList.ListView.view.currentIndex = index -1 } } // itemNumberHarmList } // delegateNumberHarmList // just here for testing!!! Component { // called via: stackViewMain.push(componentDetail) id: componentDetail Page { id: pageDetail leftPadding: 26 rightPadding: 26 topPadding: 18 bottomPadding: 18 property string userId header: ToolBar { Material.foreground: "white" ToolButton { text: Nwx.MdiFont.Icon.pencil + " " + qsTr("Edit") anchors.left: parent.left anchors.leftMargin: 10 anchors.verticalCenter: parent.verticalCenter onClicked: { console.log("Mouse-Press: left; index:", index, "; userId:", filterNumberHarm.get(index).userId) stackViewMain.push(componentEdit, { userId: filterNumberHarm.get(index).userId } ) } } Label { id: pageTitle text: qsTr("Show Number harm detail") //font.pointSize: 18 //font.pointSize: { // if (main_window.main_w < main_window.width) // return main_window.main_w / 35 // we need 20pt // return main_window.width / 35 //} anchors.centerIn: parent } } // header ColumnLayout { id: columnDetail anchors.fill: parent Layout.fillWidth: true Layout.fillHeight: true //anchors.right: parent.fill ListView { id: listDetail anchors.fill: parent //Layout.fillWidth: true //Layout.fillHeight: true //Layout.margins: 12 //displayMarginBeginning: 40 //displayMarginEnd: 40 // simple model model: SortFilterProxyModel { id: filterNumberHarm sourceModel: modelNumberHarm filters: RegExpFilter { // useRole roleName: "numberHarm" pattern: numberHarm //pattern: "account" //caseSensitivity: Qt.CaseInsensitive //caseSensitivity: Qt.Sensitive } sorters: [ RoleSorter { roleName: "numberHarm"; sortOrder: Qt.DescendingOrder }, StringSorter { roleName: "dateRecording"; sortOrder: Qt.DescendingOrder }, StringSorter { roleName: "clerkId" } ] } // model: filterNumberHarm //header: headerDetail //footer: footerDetail delegate: Pane { id: paneDetails anchors.fill: parent Layout.fillWidth: true //Layout.fillWidth: true //Layout.fillHeight: true leftPadding: 6 rightPadding: 6 topPadding: 6 bottomPadding: 6 ColumnLayout { id: columnDetail width: parent.width anchors.topMargin: 12 spacing: 2 GroupBox { id: groupDetailNumberHarm title: qsTr("Number harm data") width: parent.width Layout.fillWidth: true ColumnLayout { id: columnDetailNumberHarm width: parent.width anchors.topMargin: 12 spacing: 2 RowLayout { Layout.fillWidth: true //spacing: 12 Label { Layout.preferredWidth: 160 text: qsTr("Number harm") } Pane { Layout.fillWidth: true background: Rectangle { color: "lightgrey" radius: 5 } Label { //anchors.horizontalCenter: parent.horizontalCenter Layout.preferredWidth: 120 text: numberHarm } } } RowLayout { Layout.fillWidth: true //spacing: 12 Label { Layout.preferredWidth: 160 text: qsTr("Number policyholder") } Pane { Layout.fillWidth: true background: Rectangle { color: "lightgrey" radius: 5 } Label { text: numberPolicyholder } } } RowLayout { Layout.fillWidth: true //spacing: 12 Label { Layout.preferredWidth: 160 text: qsTr("Date recorded") } Pane { Layout.fillWidth: true background: Rectangle { color: "lightgrey" radius: 5 } Label { text: dateRecording Layout.preferredWidth: 150 // width: 100; } } } } // columnDetail } // groupDetailNumberHarm GroupBox { id: groupDetailRole title: qsTr("User data") width: parent.width Layout.fillWidth: true ColumnLayout { id: columnDetailRole width: parent.width anchors.topMargin: 12 spacing: 2 RowLayout { id: rowDetailRole Layout.fillWidth: true //spacing: 12 Label { Layout.preferredWidth: 160 text: qsTr("User Id") } Pane { Layout.fillWidth: true background: Rectangle { color: "lightgrey" radius: 5 } Label { text: userId } } } // rowRole } // columnDetail } // groupDetailRole } // paneDetail (contentItem) } // columnDetailNumberHarm } // listDetail } // columnDetail } // pageDetail } // componentDetail Component { // called via: stackViewMain.push(pageEdit) id: componentEdit Page { id: pageEdit leftPadding: 26 rightPadding: 26 topPadding: 18 bottomPadding: 18 property string numberHarm header: ToolBar { Material.foreground: "white" ToolButton { text: Nwx.MdiFont.Icon.settings + " " +qsTr("Edit") anchors.left: parent.left anchors.leftMargin: 10 anchors.verticalCenter: parent.verticalCenter onClicked: stackViewMain.push(componentEdit) } Label { id: pageTitle text: qsTr("Edit user details") font.pixelSize: 20 anchors.centerIn: parent } } // header ColumnLayout { id: columnEdit anchors.right: parent.fill ListView { id: listEdit anchors.fill: parent spacing: 20 Layout.fillWidth: true Layout.fillHeight: true Layout.margins: 6 //displayMarginBeginning: 40 //displayMarginEnd: 40 // simple model model: SortFilterProxyModel { id: filterNumberHarm sourceModel: modelNumberHarm filters: RegExpFilter { // useRole roleName: "numberHarm" pattern: numberHarm //pattern: "account" //caseSensitivity: Qt.CaseInsensitive //caseSensitivity: Qt.Sensitive } sorters: [ StringSorter { roleName: "numberHarm" } ] } // model: filterNumberHarm //header: headerEdit //footer: footerEdit delegate: ColumnLayout { id: columnEdits //anchors.right: parent.right anchors.fill: parent Layout.fillWidth: true Layout.fillHeight: true spacing: 12 GroupBox { id: groupEdit title: qsTr("Number harm data") width: parent.width Layout.fillWidth: true Layout.fillHeight: true RowLayout { Label { text: qsTr("User-Id") } Text { //anchors.horizontalCenter: parent.horizontalCenter text: userId width: 50 } } RowLayout { Label { text: qsTr("Role") } Text { text: roleName //width: 150; } } RowLayout { Label { text: qsTr("Lastname") } Text { text: lastName // width: 120 } } RowLayout { Label { text: qsTr("Firstname") } Text { text: firstName // width: 100; } } RowLayout { Label { text: qsTr("Email") } Text { text: email // width: 100; } } RowLayout { Label { text: qsTr("Intitials") } Text { text: userInitials //width: 50; } } } // groupEdit } // columnEdit (contentItem) } // listEdit } // columnEdit } // pageEdit } // componentEdit ListView { id: listNumberHarmList anchors.fill: parent anchors.rightMargin: 12 Layout.fillWidth: true Layout.fillHeight: true spacing: 4 model: filterNumberHarm //model: modelNumberHarm delegate: delegateNumberHarmList header: headerNumberHarmList footer: footerNumberHarmList highlight: highlightNumberHarmList highlightFollowsCurrentItem: false //focus: true //contentWidth: headerNumberHarmList.width flickableDirection: Flickable.VerticalFlick /* Keys.onPressed: { console.log("list-item: " + event.key + " : " + event.text) } */ Shortcut { context: Qt.ApplicationShortcut sequence: [ "Ctrl+S" ] //onActivated: view.currentIndex++ onActivated: { searchToolBar.forceActiveFocus() console.log("Key-Press->Ctrl+S: Shortcut activated.") } } Keys.onUpPressed: scrollBarNumberHarmList.decrease() Keys.onDownPressed: scrollBarNumberHarmList.increase() //Component.onCompleted: positionViewAtEnd() //Component.onCompleted: positionViewAtIndex(ListView.Center) ScrollBar.vertical: Nwx.ScrollBar { id: scrollBarNumberHarmList // leftPadding: 2 // topPadding: 2 // color: "lightsteelblue" parent: listNumberHarmList.parent anchors.top: listNumberHarmList.top anchors.left: listNumberHarmList.right anchors.bottom: listNumberHarmList.bottom } /* ScrollIndicator.vertical: Nwx.ScrollIndicator { id: scrollIndicatorNumberHarmList leftPadding: 5 topPadding: 5 } */ } // listNumberHarmList } // pageNumberHarmList