Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
openpageswidget.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
3
5
8#include "tracer.h"
9
10#include <QtWidgets/QApplication>
11#include <QtWidgets/QHeaderView>
12#include <QtGui/QKeyEvent>
13#include <QtGui/QMouseEvent>
14#include <QtWidgets/QMenu>
15#include <QtGui/QPainter>
16
18
24
25void OpenPagesDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
26 const QModelIndex &index) const
27{
29 if (option.state & QStyle::State_MouseOver) {
30QT_WARNING_PUSH
31QT_WARNING_DISABLE_DEPRECATED
32 if ((QApplication::mouseButtons() & Qt::LeftButton) == 0)
33 pressedIndex = QModelIndex();
34QT_WARNING_POP
35 QBrush brush = option.palette.alternateBase();
36 if (index == pressedIndex)
37 brush = option.palette.dark();
38 painter->fillRect(option.rect, brush);
39 }
40
41 QStyledItemDelegate::paint(painter, option, index);
42
43 if (index.column() == 1 && index.model()->rowCount() > 1
44 && option.state & QStyle::State_MouseOver) {
45 QIcon icon((option.state & QStyle::State_Selected)
46 ? ":/qt-project.org/assistant/images/closebutton.png"
47 : ":/qt-project.org/assistant/images/darkclosebutton.png");
48
49 const QRect iconRect(option.rect.right() - option.rect.height(),
50 option.rect.top(), option.rect.height(), option.rect.height());
51 icon.paint(painter, iconRect, Qt::AlignRight | Qt::AlignVCenter);
52 }
53}
54
55// -- OpenPagesWidget
56
57OpenPagesWidget::OpenPagesWidget(OpenPagesModel *model)
58 : m_allowContextMenu(true)
59{
61 setModel(model);
62 setIndentation(0);
63 setItemDelegate((m_delegate = new OpenPagesDelegate(this)));
64
65 setTextElideMode(Qt::ElideMiddle);
66 setAttribute(Qt::WA_MacShowFocusRect, false);
67
68 viewport()->setAttribute(Qt::WA_Hover);
69 setSelectionBehavior(QAbstractItemView::SelectRows);
70 setSelectionMode(QAbstractItemView::SingleSelection);
71
72 header()->hide();
73 header()->setStretchLastSection(false);
74 header()->setSectionResizeMode(0, QHeaderView::Stretch);
75 header()->setSectionResizeMode(1, QHeaderView::Fixed);
76 header()->resizeSection(1, 18);
77
78 installEventFilter(this);
79 setUniformRowHeights(true);
80 setContextMenuPolicy(Qt::CustomContextMenu);
81
82 connect(this, &QAbstractItemView::clicked,
83 this, &OpenPagesWidget::handleClicked);
84 connect(this, &QAbstractItemView::pressed,
85 this, &OpenPagesWidget::handlePressed);
86 connect(this, &QWidget::customContextMenuRequested,
87 this, &OpenPagesWidget::contextMenuRequested);
88}
89
94
96{
98 const QModelIndex &current =
100
101 QItemSelectionModel * const selModel = selectionModel();
102 selModel->select(current,
103 QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
104 selModel->clearSelection();
105
106 setCurrentIndex(current);
107 scrollTo(currentIndex());
108}
109
111{
113 m_allowContextMenu = ok;
114}
115
116void OpenPagesWidget::contextMenuRequested(QPoint pos)
117{
119 QModelIndex index = indexAt(pos);
120 if (!index.isValid() || !m_allowContextMenu)
121 return;
122
123 if (index.column() == 1)
124 index = index.sibling(index.row(), 0);
125 QMenu contextMenu;
126 QAction *closeEditor = contextMenu.addAction(tr("Close %1").arg(index.data()
127 .toString()));
128 QAction *closeOtherEditors = contextMenu.addAction(tr("Close All Except %1")
129 .arg(index.data().toString()));
130
131 if (model()->rowCount() == 1) {
132 closeEditor->setEnabled(false);
133 closeOtherEditors->setEnabled(false);
134 }
135
136 QAction *action = contextMenu.exec(mapToGlobal(pos));
137 if (action == closeEditor)
138 emit closePage(index);
139 else if (action == closeOtherEditors)
140 emit closePagesExcept(index);
141}
142
143void OpenPagesWidget::handlePressed(const QModelIndex &index)
144{
146 if (index.column() == 0)
147 emit setCurrentPage(index);
148
149 if (index.column() == 1)
150 m_delegate->pressedIndex = index;
151}
152
153void OpenPagesWidget::handleClicked(const QModelIndex &index)
154{
156 // implemented here to handle the funky close button and to work around a
157 // bug in item views where the delegate wouldn't get the QStyle::State_MouseOver
158 if (index.column() == 1) {
159 if (model()->rowCount() > 1)
160 emit closePage(index);
161
162 QWidget *vp = viewport();
163 const QPoint &cursorPos = QCursor::pos();
164 QMouseEvent e(QEvent::MouseMove, vp->mapFromGlobal(cursorPos), cursorPos,
165 Qt::NoButton, {}, {});
166 QCoreApplication::sendEvent(vp, &e);
167 }
168}
169
170bool OpenPagesWidget::eventFilter(QObject *obj, QEvent *event)
171{
173 if (obj != this)
174 return QWidget::eventFilter(obj, event);
175
176 if (event->type() == QEvent::KeyPress) {
177 QKeyEvent *ke = static_cast<QKeyEvent*>(event);
178 if (currentIndex().isValid() && ke->modifiers() == 0) {
179 const int key = ke->key();
180 if (key == Qt::Key_Return || key == Qt::Key_Enter
181 || key == Qt::Key_Space) {
182 emit setCurrentPage(currentIndex());
183 } else if ((key == Qt::Key_Delete || key == Qt::Key_Backspace)
184 && model()->rowCount() > 1) {
185 emit closePage(currentIndex());
186 }
187 }
188 } else if (event->type() == QEvent::KeyRelease) {
189 QKeyEvent *ke = static_cast<QKeyEvent*>(event);
190 if (ke->modifiers() == 0
191 && (ke->key() == Qt::Key_Up || ke->key() == Qt::Key_Down)) {
192 emit setCurrentPage(currentIndex());
193 }
194 }
195 return QWidget::eventFilter(obj, event);
196}
197
198QT_END_NAMESPACE
int currentIndex() const
static CentralWidget * instance()
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override
This pure abstract function must be reimplemented if you want to provide custom rendering.
void allowContextMenu(bool ok)
~OpenPagesWidget() override
\inmodule QtCore
QObject * parent
Definition qobject.h:73
\inmodule QtCore
Definition qobject.h:103
Combined button and popup list for selecting options.
#define TRACE_OBJ
Definition tracer.h:34