1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2016 The Qt Company Ltd. |
4 | ** Contact: https://www.qt.io/licensing/ |
5 | ** |
6 | ** This file is part of the Assistant module of the Qt Toolkit. |
7 | ** |
8 | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$ |
9 | ** Commercial License Usage |
10 | ** Licensees holding valid commercial Qt licenses may use this file in |
11 | ** accordance with the commercial license agreement provided with the |
12 | ** Software or, alternatively, in accordance with the terms contained in |
13 | ** a written agreement between you and The Qt Company. For licensing terms |
14 | ** and conditions see https://www.qt.io/terms-conditions. For further |
15 | ** information use the contact form at https://www.qt.io/contact-us. |
16 | ** |
17 | ** GNU General Public License Usage |
18 | ** Alternatively, this file may be used under the terms of the GNU |
19 | ** General Public License version 3 as published by the Free Software |
20 | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT |
21 | ** included in the packaging of this file. Please review the following |
22 | ** information to ensure the GNU General Public License requirements will |
23 | ** be met: https://www.gnu.org/licenses/gpl-3.0.html. |
24 | ** |
25 | ** $QT_END_LICENSE$ |
26 | ** |
27 | ****************************************************************************/ |
28 | |
29 | #include "openpagesswitcher.h" |
30 | |
31 | #include "centralwidget.h" |
32 | #include "openpagesmodel.h" |
33 | #include "openpageswidget.h" |
34 | #include "tracer.h" |
35 | |
36 | #include <QtCore/QEvent> |
37 | |
38 | #include <QtGui/QKeyEvent> |
39 | #include <QtWidgets/QVBoxLayout> |
40 | |
41 | QT_BEGIN_NAMESPACE |
42 | |
43 | const int gWidth = 300; |
44 | const int gHeight = 200; |
45 | |
46 | OpenPagesSwitcher::OpenPagesSwitcher(OpenPagesModel *model) |
47 | : QFrame(nullptr, Qt::Popup) |
48 | , m_openPagesModel(model) |
49 | { |
50 | TRACE_OBJ |
51 | resize(w: gWidth, h: gHeight); |
52 | |
53 | m_openPagesWidget = new OpenPagesWidget(m_openPagesModel); |
54 | |
55 | // We disable the frame on this list view and use a QFrame around it instead. |
56 | // This improves the look with QGTKStyle. |
57 | #ifndef Q_OS_MAC |
58 | setFrameStyle(m_openPagesWidget->frameStyle()); |
59 | #endif |
60 | m_openPagesWidget->setFrameStyle(QFrame::NoFrame); |
61 | |
62 | m_openPagesWidget->allowContextMenu(ok: false); |
63 | m_openPagesWidget->installEventFilter(filterObj: this); |
64 | |
65 | QVBoxLayout *layout = new QVBoxLayout(this); |
66 | layout->setContentsMargins(QMargins()); |
67 | layout->addWidget(m_openPagesWidget); |
68 | |
69 | connect(sender: m_openPagesWidget, signal: &OpenPagesWidget::closePage, |
70 | receiver: this, slot: &OpenPagesSwitcher::closePage); |
71 | connect(sender: m_openPagesWidget, signal: &OpenPagesWidget::setCurrentPage, |
72 | receiver: this, slot: &OpenPagesSwitcher::setCurrentPage); |
73 | } |
74 | |
75 | OpenPagesSwitcher::~OpenPagesSwitcher() |
76 | { |
77 | TRACE_OBJ |
78 | } |
79 | |
80 | void OpenPagesSwitcher::gotoNextPage() |
81 | { |
82 | TRACE_OBJ |
83 | selectPageUpDown(summand: 1); |
84 | } |
85 | |
86 | void OpenPagesSwitcher::gotoPreviousPage() |
87 | { |
88 | TRACE_OBJ |
89 | selectPageUpDown(summand: -1); |
90 | } |
91 | |
92 | void OpenPagesSwitcher::selectAndHide() |
93 | { |
94 | TRACE_OBJ |
95 | setVisible(false); |
96 | emit setCurrentPage(m_openPagesWidget->currentIndex()); |
97 | } |
98 | |
99 | void OpenPagesSwitcher::selectCurrentPage() |
100 | { |
101 | TRACE_OBJ |
102 | m_openPagesWidget->selectCurrentPage(); |
103 | } |
104 | |
105 | void OpenPagesSwitcher::setVisible(bool visible) |
106 | { |
107 | TRACE_OBJ |
108 | QWidget::setVisible(visible); |
109 | if (visible) |
110 | setFocus(); |
111 | } |
112 | |
113 | void OpenPagesSwitcher::focusInEvent(QFocusEvent *event) |
114 | { |
115 | TRACE_OBJ |
116 | Q_UNUSED(event); |
117 | m_openPagesWidget->setFocus(); |
118 | } |
119 | |
120 | bool OpenPagesSwitcher::eventFilter(QObject *object, QEvent *event) |
121 | { |
122 | TRACE_OBJ |
123 | if (object == m_openPagesWidget) { |
124 | if (event->type() == QEvent::KeyPress) { |
125 | QKeyEvent *ke = static_cast<QKeyEvent*>(event); |
126 | if (ke->key() == Qt::Key_Escape) { |
127 | setVisible(false); |
128 | return true; |
129 | } |
130 | |
131 | const int key = ke->key(); |
132 | if (key == Qt::Key_Return || key == Qt::Key_Enter || key == Qt::Key_Space) { |
133 | emit setCurrentPage(m_openPagesWidget->currentIndex()); |
134 | return true; |
135 | } |
136 | |
137 | Qt::KeyboardModifier modifier = Qt::ControlModifier; |
138 | #ifdef Q_OS_MAC |
139 | modifier = Qt::AltModifier; |
140 | #endif |
141 | if (key == Qt::Key_Backtab |
142 | && (ke->modifiers() == (modifier | Qt::ShiftModifier))) |
143 | gotoPreviousPage(); |
144 | else if (key == Qt::Key_Tab && (ke->modifiers() == modifier)) |
145 | gotoNextPage(); |
146 | } else if (event->type() == QEvent::KeyRelease) { |
147 | QKeyEvent *ke = static_cast<QKeyEvent*>(event); |
148 | if (ke->modifiers() == 0 |
149 | /*HACK this is to overcome some event inconsistencies between platforms*/ |
150 | || (ke->modifiers() == Qt::AltModifier |
151 | && (ke->key() == Qt::Key_Alt || ke->key() == -1))) { |
152 | selectAndHide(); |
153 | } |
154 | } |
155 | } |
156 | return QWidget::eventFilter(watched: object, event); |
157 | } |
158 | |
159 | void OpenPagesSwitcher::selectPageUpDown(int summand) |
160 | { |
161 | TRACE_OBJ |
162 | const int pageCount = m_openPagesModel->rowCount(); |
163 | if (pageCount < 2) |
164 | return; |
165 | |
166 | const QModelIndexList &list = m_openPagesWidget->selectionModel()->selectedIndexes(); |
167 | if (list.isEmpty()) |
168 | return; |
169 | |
170 | QModelIndex index = list.first(); |
171 | if (!index.isValid()) |
172 | return; |
173 | |
174 | index = m_openPagesModel->index(row: (index.row() + summand + pageCount) % pageCount, column: 0); |
175 | if (index.isValid()) { |
176 | m_openPagesWidget->setCurrentIndex(index); |
177 | m_openPagesWidget->scrollTo(index, hint: QAbstractItemView::PositionAtCenter); |
178 | } |
179 | } |
180 | |
181 | QT_END_NAMESPACE |
182 | |