mailmodel 0.1.0

A proof-of-concept mail viewer writting with Qt using QML
import QtQuick 2.7
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.2
import QtQml.Models 2.3

Item {
    readonly property var currentUid: folder.currentIndex.valid ? folder.model.uid(folder.currentIndex) : undefined
    readonly property string filter: filterField.text
    QtObject {
        id: p
        property var currentIndex
        property var selectedIndexes
    }
    Layout.preferredWidth: 300
    TextField {
        id: filterField
        width: parent.width
        placeholderText: qsTr("Search this folder")
    }
    TreeView {
        id: folder
        headerVisible: false
        frameVisible: false
        y: filterField.height
        width: parent.width
        height: parent.height - filterField.height
        model: mailmodel.folder_threads
        selectionMode: SelectionMode.ExtendedSelection
        selection: ItemSelectionModel {
            model: mailmodel.folder_threads
        }
        onExpanded: expandRecursive(folder, index)
        TableViewColumn {
            title: "Mail"
            role: "subject"
            width: folder.width - 20
        }
        itemDelegate: delegate
        rowDelegate: Rectangle {
            height: 3 * systemFont.font.pixelSize
            color: styleData.selected
                ? folder.activeFocus
                    ? palette.highlight
                    : Qt.lighter(palette.highlight, 1.5)
                : rowMouse.containsMouse
                    ? styleData.alternate
                        ? Qt.darker(palette.alternateBase, 1.02)
                        : Qt.darker(palette.base, 1.02)
                    : styleData.alternate ? palette.alternateBase : palette.base
            MouseArea {
                id: rowMouse
                anchors.fill: parent
                hoverEnabled: true
                acceptedButtons: Qt.NoButton
            }
        }
        section.property: "section"
        section.delegate: Rectangle {
            color: palette.mid
            height: 1.5 * section_text.font.pixelSize
            width: folder.width
            Text {
                id: section_text
                anchors.fill: parent
                font.bold: true
                text: section
                verticalAlignment: Text.AlignVCenter
            }
        }
    }
    Component {
        id: delegate
        Item {
            property color textColor: styleData.selected
                    ? folder.activeFocus ? palette.highlightedText : palette.text
                    : (valid() && mailmodel.folder_threads.seen(styleData.index)) ? palette.text : palette.highlight
            width: parent.width
            function valid() {
                return styleData.index && styleData.index.valid
            }
            Text {
                id: s
                text: styleData.value || ""
                color: textColor
                textFormat: Text.PlainText
                anchors.left: parent.left
                anchors.right: parent.right
                anchors.top: parent.top
                elide: Text.ElideRight
            }
            Text {
                id: f
                text: valid() ? mailmodel.folder_threads.from(styleData.index) : ""
                color: textColor
                textFormat: Text.PlainText
                width: s.width - d.width
                anchors.top: s.bottom
                anchors.left: parent.left
                anchors.bottom: parent.bottom
                font.italic: true
                elide: Text.ElideRight
            }
            Text {
                id: d
                text: valid() ? mailmodel.folder_threads.date(styleData.index) : ""
                color: textColor
                textFormat: Text.PlainText
                width: contentWidth
                anchors.top: s.bottom
                anchors.right: parent.right
                anchors.bottom: parent.bottom
                font.italic: true
                horizontalAlignment: Text.AlignRight
            }
        }
    }
    function saveSelection() {
        p.currentIndex = folder.selection.currentIndex;
        p.selectedIndexes = folder.selection.selectedIndexes;
    }
    function restoreSelection() {
        var s;
        for (s in p.selectedIndexes) {
            folder.selection.select(s, ItemSelectionModel.Select);
        }
        folder.selection.setCurrentIndex(p.currentIndex, ItemSelectionModel.Select);
    }
    Component.onCompleted: {
        folder.model.modelReset.connect(function () {
        });
        folder.model.layoutAboutToBeChanged.connect(saveSelection);
        folder.model.layoutChanged.connect(function () {
            restoreSelection();
        });
        folder.model.rowsInserted.connect(function (parent) {
        });
    }
}