This repository has been archived on 2022-07-15. You can view files and clone it, but cannot push or open issues or pull requests.
libqt5raspi/debian/usr/local/qt5raspi-5.12.5/qml/QtQuick/Controls/TreeView.qml

416 lines
16 KiB
QML

/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Quick Controls module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
import QtQuick 2.4
import QtQuick.Controls 1.4
import QtQuick.Controls.Private 1.0
import QtQuick.Controls.Styles 1.2
import QtQml.Models 2.2
BasicTableView {
id: root
property var model: null
property alias rootIndex: modelAdaptor.rootIndex
readonly property var currentIndex: modelAdaptor.mapRowToModelIndex(__currentRow)
property ItemSelectionModel selection: null
signal activated(var index)
signal clicked(var index)
signal doubleClicked(var index)
signal pressAndHold(var index)
signal expanded(var index)
signal collapsed(var index)
function isExpanded(index) {
if (index.valid && index.model !== model) {
console.warn("TreeView.isExpanded: model and index mismatch")
return false
}
return modelAdaptor.isExpanded(index)
}
function collapse(index) {
if (index.valid && index.model !== model)
console.warn("TreeView.collapse: model and index mismatch")
else
modelAdaptor.collapse(index)
}
function expand(index) {
if (index.valid && index.model !== model)
console.warn("TreeView.expand: model and index mismatch")
else
modelAdaptor.expand(index)
}
function indexAt(x, y) {
var obj = root.mapToItem(__listView.contentItem, x, y)
return modelAdaptor.mapRowToModelIndex(__listView.indexAt(obj.x, obj.y))
}
style: Settings.styleComponent(Settings.style, "TreeViewStyle.qml", root)
// Internal stuff. Do not look
__viewTypeName: "TreeView"
__model: TreeModelAdaptor {
id: modelAdaptor
model: root.model
onExpanded: root.expanded(index)
onCollapsed: root.collapsed(index)
}
__itemDelegateLoader: TreeViewItemDelegateLoader {
__style: root.__style
__itemDelegate: root.itemDelegate
__mouseArea: mouseArea
__treeModel: modelAdaptor
}
onSelectionModeChanged: if (!!selection) selection.clear()
__mouseArea: MouseArea {
id: mouseArea
parent: __listView
width: __listView.width
height: __listView.height
z: -1
propagateComposedEvents: true
focus: true
// If there is not a touchscreen, keep the flickable from eating our mouse drags.
// If there is a touchscreen, flicking is possible, but selection can be done only by tapping, not by dragging.
preventStealing: !Settings.hasTouchScreen
property var clickedIndex: undefined
property var pressedIndex: undefined
property bool selectOnRelease: false
property int pressedColumn: -1
readonly property alias currentRow: root.__currentRow
readonly property alias currentIndex: root.currentIndex
// Handle vertical scrolling whem dragging mouse outside boundaries
property int autoScroll: 0 // 0 -> do nothing; 1 -> increment; 2 -> decrement
property bool shiftPressed: false // forward shift key state to the autoscroll timer
Timer {
running: mouseArea.autoScroll !== 0 && __verticalScrollBar.visible
interval: 20
repeat: true
onTriggered: {
var oldPressedIndex = mouseArea.pressedIndex
var row
if (mouseArea.autoScroll === 1) {
__listView.incrementCurrentIndexBlocking();
row = __listView.indexAt(0, __listView.height + __listView.contentY)
if (row === -1)
row = __listView.count - 1
} else {
__listView.decrementCurrentIndexBlocking();
row = __listView.indexAt(0, __listView.contentY)
}
var index = modelAdaptor.mapRowToModelIndex(row)
if (index !== oldPressedIndex) {
mouseArea.pressedIndex = index
var modifiers = mouseArea.shiftPressed ? Qt.ShiftModifier : Qt.NoModifier
mouseArea.mouseSelect(index, modifiers, true /* drag */)
}
}
}
function mouseSelect(modelIndex, modifiers, drag) {
if (!selection) {
maybeWarnAboutSelectionMode()
return
}
if (selectionMode) {
selection.setCurrentIndex(modelIndex, ItemSelectionModel.NoUpdate)
if (selectionMode === SelectionMode.SingleSelection) {
selection.select(modelIndex, ItemSelectionModel.ClearAndSelect)
} else {
var selectRowRange = (drag && (selectionMode === SelectionMode.MultiSelection
|| (selectionMode === SelectionMode.ExtendedSelection
&& modifiers & Qt.ControlModifier)))
|| modifiers & Qt.ShiftModifier
var itemSelection = !selectRowRange || clickedIndex === modelIndex ? modelIndex
: modelAdaptor.selectionForRowRange(clickedIndex, modelIndex)
if (selectionMode === SelectionMode.MultiSelection
|| selectionMode === SelectionMode.ExtendedSelection && modifiers & Qt.ControlModifier) {
if (drag)
selection.select(itemSelection, ItemSelectionModel.ToggleCurrent)
else
selection.select(modelIndex, ItemSelectionModel.Toggle)
} else if (modifiers & Qt.ShiftModifier) {
selection.select(itemSelection, ItemSelectionModel.SelectCurrent)
} else {
clickedIndex = modelIndex // Needed only when drag is true
selection.select(modelIndex, ItemSelectionModel.ClearAndSelect)
}
}
}
}
function keySelect(keyModifiers) {
if (selectionMode) {
if (!keyModifiers)
clickedIndex = currentIndex
if (!(keyModifiers & Qt.ControlModifier))
mouseSelect(currentIndex, keyModifiers, keyModifiers & Qt.ShiftModifier)
}
}
function selected(row) {
if (selectionMode === SelectionMode.NoSelection)
return false
var modelIndex = null
if (!!selection) {
modelIndex = modelAdaptor.mapRowToModelIndex(row)
if (modelIndex.valid) {
if (selectionMode === SelectionMode.SingleSelection)
return selection.currentIndex === modelIndex
return selection.hasSelection && selection.isSelected(modelIndex)
} else {
return false
}
}
return row === currentRow
&& (selectionMode === SelectionMode.SingleSelection
|| (selectionMode > SelectionMode.SingleSelection && !selection))
}
function branchDecorationContains(x, y) {
var clickedItem = __listView.itemAt(0, y + __listView.contentY)
if (!(clickedItem && clickedItem.rowItem))
return false
var branchDecoration = clickedItem.rowItem.branchDecoration
if (!branchDecoration)
return false
var pos = mapToItem(branchDecoration, x, y)
return branchDecoration.contains(Qt.point(pos.x, pos.y))
}
function maybeWarnAboutSelectionMode() {
if (selectionMode > SelectionMode.SingleSelection)
console.warn("TreeView: Non-single selection is not supported without an ItemSelectionModel.")
}
onPressed: {
var pressedRow = __listView.indexAt(0, mouseY + __listView.contentY)
pressedIndex = modelAdaptor.mapRowToModelIndex(pressedRow)
pressedColumn = __listView.columnAt(mouseX)
selectOnRelease = false
__listView.forceActiveFocus()
if (pressedRow === -1
|| Settings.hasTouchScreen
|| branchDecorationContains(mouse.x, mouse.y)) {
return
}
if (selectionMode === SelectionMode.ExtendedSelection
&& selection.isSelected(pressedIndex)) {
selectOnRelease = true
return
}
__listView.currentIndex = pressedRow
if (!clickedIndex)
clickedIndex = pressedIndex
mouseSelect(pressedIndex, mouse.modifiers, false)
if (!mouse.modifiers)
clickedIndex = pressedIndex
}
onReleased: {
if (selectOnRelease) {
var releasedRow = __listView.indexAt(0, mouseY + __listView.contentY)
var releasedIndex = modelAdaptor.mapRowToModelIndex(releasedRow)
if (releasedRow >= 0 && releasedIndex === pressedIndex)
mouseSelect(pressedIndex, mouse.modifiers, false)
}
pressedIndex = undefined
pressedColumn = -1
autoScroll = 0
selectOnRelease = false
}
onPositionChanged: {
// NOTE: Testing for pressed is not technically needed, at least
// until we decide to support tooltips or some other hover feature
if (mouseY > __listView.height && pressed) {
if (autoScroll === 1) return;
autoScroll = 1
} else if (mouseY < 0 && pressed) {
if (autoScroll === 2) return;
autoScroll = 2
} else {
autoScroll = 0
}
if (pressed && containsMouse) {
var oldPressedIndex = pressedIndex
var pressedRow = __listView.indexAt(0, mouseY + __listView.contentY)
pressedIndex = modelAdaptor.mapRowToModelIndex(pressedRow)
pressedColumn = __listView.columnAt(mouseX)
if (pressedRow > -1 && oldPressedIndex !== pressedIndex) {
__listView.currentIndex = pressedRow
mouseSelect(pressedIndex, mouse.modifiers, true /* drag */)
}
}
}
onExited: {
pressedIndex = undefined
pressedColumn = -1
selectOnRelease = false
}
onCanceled: {
pressedIndex = undefined
pressedColumn = -1
autoScroll = 0
selectOnRelease = false
}
onClicked: {
var clickIndex = __listView.indexAt(0, mouseY + __listView.contentY)
if (clickIndex > -1) {
var modelIndex = modelAdaptor.mapRowToModelIndex(clickIndex)
if (branchDecorationContains(mouse.x, mouse.y)) {
if (modelAdaptor.isExpanded(modelIndex))
modelAdaptor.collapse(modelIndex)
else
modelAdaptor.expand(modelIndex)
} else {
if (Settings.hasTouchScreen) {
// compensate for the fact that onPressed didn't select on press: do it here instead
pressedIndex = modelAdaptor.mapRowToModelIndex(clickIndex)
pressedColumn = __listView.columnAt(mouseX)
selectOnRelease = false
__listView.forceActiveFocus()
__listView.currentIndex = clickIndex
if (!clickedIndex)
clickedIndex = pressedIndex
mouseSelect(pressedIndex, mouse.modifiers, false)
if (!mouse.modifiers)
clickedIndex = pressedIndex
}
if (root.__activateItemOnSingleClick && !mouse.modifiers)
root.activated(modelIndex)
}
root.clicked(modelIndex)
}
}
onDoubleClicked: {
var clickIndex = __listView.indexAt(0, mouseY + __listView.contentY)
if (clickIndex > -1) {
var modelIndex = modelAdaptor.mapRowToModelIndex(clickIndex)
if (!root.__activateItemOnSingleClick)
root.activated(modelIndex)
root.doubleClicked(modelIndex)
}
}
onPressAndHold: {
var pressIndex = __listView.indexAt(0, mouseY + __listView.contentY)
if (pressIndex > -1) {
var modelIndex = modelAdaptor.mapRowToModelIndex(pressIndex)
root.pressAndHold(modelIndex)
}
}
Keys.forwardTo: [root]
Keys.onUpPressed: {
event.accepted = __listView.decrementCurrentIndexBlocking()
keySelect(event.modifiers)
}
Keys.onDownPressed: {
event.accepted = __listView.incrementCurrentIndexBlocking()
keySelect(event.modifiers)
}
Keys.onRightPressed: {
if (root.currentIndex.valid)
root.expand(currentIndex)
else
event.accepted = false
}
Keys.onLeftPressed: {
if (root.currentIndex.valid)
root.collapse(currentIndex)
else
event.accepted = false
}
Keys.onReturnPressed: {
if (root.currentIndex.valid)
root.activated(currentIndex)
else
event.accepted = false
}
Keys.onPressed: {
__listView.scrollIfNeeded(event.key)
if (event.key === Qt.Key_A && event.modifiers & Qt.ControlModifier
&& !!selection && selectionMode > SelectionMode.SingleSelection) {
var sel = modelAdaptor.selectionForRowRange(0, __listView.count - 1)
selection.select(sel, ItemSelectionModel.SelectCurrent)
} else if (event.key === Qt.Key_Shift) {
shiftPressed = true
}
}
Keys.onReleased: {
if (event.key === Qt.Key_Shift)
shiftPressed = false
}
}
}