QtPass 2.0.0
Developer documentation
Loading...
Searching...
No Matches
deselectabletreeview.h
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2016 Anne Jan Brouwer
2// SPDX-License-Identifier: GPL-3.0-or-later
8#ifndef SRC_DESELECTABLETREEVIEW_H_
9#define SRC_DESELECTABLETREEVIEW_H_
10
11#include <QGuiApplication>
12#include <QMouseEvent>
13#include <QStyleHints>
14#include <QTimer>
15#include <QTreeView>
16
29class DeselectableTreeView : public QTreeView {
30 Q_OBJECT
31
32public:
37 explicit DeselectableTreeView(QWidget *parent) : QTreeView(parent) {
38 deselectTimer.setSingleShot(true);
39 connect(&deselectTimer, &QTimer::timeout, this,
41 }
42
45 ~DeselectableTreeView() override = default;
46
47signals:
54
55private:
60 bool doubleClickHappened = false;
65 bool clickSelected = false;
71
77 void mousePressEvent(QMouseEvent *event) override {
78 // A new press belongs to a new click: whatever the previous release left
79 // pending must not clear the selection this press is about to make.
80 deselectTimer.stop();
82 selectionModel()->isSelected(indexAt(event->position().toPoint()));
83 QTreeView::mousePressEvent(event);
84 }
85
92 void mouseReleaseEvent(QMouseEvent *event) override {
93 const QModelIndex item = indexAt(event->position().toPoint());
94 const bool pressWasOnSelection = clickSelected;
95 clickSelected = false;
96
97 // Handle the release immediately: waiting here would delay selection —
98 // and therefore every decrypt — by the double-click interval.
99 QTreeView::mouseReleaseEvent(event);
100
101 const bool emptyOrSelected =
102 !item.isValid() || selectionModel()->isSelected(item);
103 if (!pressWasOnSelection || !emptyOrSelected)
104 return;
105
106 // Deselecting is the one decision that must wait: a double-click starts
107 // with a release, and opening the editor must win over clearing the
108 // selection. Ask the platform how long a double-click may take instead
109 // of assuming 200 ms.
110 doubleClickHappened = false;
111 deselectTimer.start(
112 QGuiApplication::styleHints()->mouseDoubleClickInterval());
113 }
114
119 void deselect() {
121 return;
122 clearSelection();
123 selectionModel()->setCurrentIndex(QModelIndex(),
124 QItemSelectionModel::Select);
125 emit emptyClicked();
126 }
127
133 void mouseDoubleClickEvent(QMouseEvent *event) override {
134 doubleClickHappened = true;
135 deselectTimer.stop();
136 QTreeView::mouseDoubleClickEvent(event);
137 }
138};
139
140#endif // SRC_DESELECTABLETREEVIEW_H_
void mouseReleaseEvent(QMouseEvent *event) override
Let QTreeView handle the release at once, then, if the press was on a selected row and the release is...
QTimer deselectTimer
Single-shot timer, started by a qualifying release for one double-click interval; its timeout runs de...
bool doubleClickHappened
Set by mouseDoubleClickEvent() so a deselect() that fires after a double-click's first release does n...
void mouseDoubleClickEvent(QMouseEvent *event) override
Cancel the pending deselect so the double-click opens the entry instead of clearing the selection.
bool clickSelected
Whether the row under the last press was already selected; read and reset by the matching release.
DeselectableTreeView(QWidget *parent)
Construct the view and arm the single-shot deselect timer.
void mousePressEvent(QMouseEvent *event) override
Remember whether the pressed row was already selected and cancel any pending deselect from the previo...
void emptyClicked()
Emitted after deselect() has cleared the selection because of a single click on empty space or on a s...
~DeselectableTreeView() override=default
Default destructor.
void deselect()
Timer slot: clear the selection and current index and emit emptyClicked(), unless a double-click happ...