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 Qt Assistant 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 | #include "tracer.h" |
29 | |
30 | #include "topicchooser.h" |
31 | #include "helpenginewrapper.h" |
32 | |
33 | #include <QKeyEvent> |
34 | #include <QStandardItemModel> |
35 | #include <QSortFilterProxyModel> |
36 | #include <QUrl> |
37 | |
38 | #include <QtHelp/QHelpLink> |
39 | |
40 | QT_BEGIN_NAMESPACE |
41 | |
42 | TopicChooser::TopicChooser(QWidget *parent, const QString &keyword, const QList<QHelpLink> &docs) |
43 | : QDialog(parent) |
44 | , m_filterModel(new QSortFilterProxyModel(this)) |
45 | { |
46 | TRACE_OBJ |
47 | ui.setupUi(this); |
48 | |
49 | setFocusProxy(ui.lineEdit); |
50 | ui.lineEdit->installEventFilter(filterObj: this); |
51 | ui.lineEdit->setPlaceholderText(tr(s: "Filter" )); |
52 | ui.label->setText(tr(s: "Choose a topic for <b>%1</b>:" ).arg(a: keyword)); |
53 | |
54 | QStandardItemModel *model = new QStandardItemModel(this); |
55 | m_filterModel->setSourceModel(model); |
56 | m_filterModel->setFilterCaseSensitivity(Qt::CaseInsensitive); |
57 | |
58 | for (const auto &doc : docs) { |
59 | m_links.append(t: doc.url); |
60 | QStandardItem *item = new QStandardItem(doc.title); |
61 | item->setToolTip(doc.url.toString()); |
62 | model->appendRow(aitem: item); |
63 | } |
64 | |
65 | ui.listWidget->setModel(m_filterModel); |
66 | ui.listWidget->setUniformItemSizes(true); |
67 | ui.listWidget->setEditTriggers(QAbstractItemView::NoEditTriggers); |
68 | |
69 | if (m_filterModel->rowCount() != 0) |
70 | ui.listWidget->setCurrentIndex(m_filterModel->index(row: 0, column: 0)); |
71 | |
72 | connect(sender: ui.buttonCancel, signal: &QAbstractButton::clicked, |
73 | receiver: this, slot: &QDialog::reject); |
74 | connect(sender: ui.buttonDisplay, signal: &QAbstractButton::clicked, |
75 | receiver: this, slot: &TopicChooser::acceptDialog); |
76 | connect(sender: ui.lineEdit, signal: &QLineEdit::textChanged, |
77 | receiver: this, slot: &TopicChooser::setFilter); |
78 | connect(sender: ui.listWidget, signal: &QAbstractItemView::activated, |
79 | receiver: this, slot: &TopicChooser::activated); |
80 | |
81 | const QByteArray ba = HelpEngineWrapper::instance().topicChooserGeometry(); |
82 | if (!ba.isEmpty()) |
83 | restoreGeometry(geometry: ba); |
84 | } |
85 | |
86 | TopicChooser::~TopicChooser() |
87 | { |
88 | HelpEngineWrapper::instance().setTopicChooserGeometry(saveGeometry()); |
89 | } |
90 | |
91 | QUrl TopicChooser::link() const |
92 | { |
93 | TRACE_OBJ |
94 | if (m_activedIndex.isValid()) |
95 | return m_links.at(i: m_filterModel->mapToSource(proxyIndex: m_activedIndex).row()); |
96 | return QUrl(); |
97 | } |
98 | |
99 | void TopicChooser::acceptDialog() |
100 | { |
101 | TRACE_OBJ |
102 | m_activedIndex = ui.listWidget->currentIndex(); |
103 | accept(); |
104 | } |
105 | |
106 | void TopicChooser::setFilter(const QString &pattern) |
107 | { |
108 | TRACE_OBJ |
109 | m_filterModel->setFilterFixedString(pattern); |
110 | if (m_filterModel->rowCount() != 0 && !ui.listWidget->currentIndex().isValid()) |
111 | ui.listWidget->setCurrentIndex(m_filterModel->index(row: 0, column: 0)); |
112 | } |
113 | |
114 | void TopicChooser::activated(const QModelIndex &index) |
115 | { |
116 | TRACE_OBJ |
117 | m_activedIndex = index; |
118 | accept(); |
119 | } |
120 | |
121 | bool TopicChooser::eventFilter(QObject *object, QEvent *event) |
122 | { |
123 | TRACE_OBJ |
124 | if (object == ui.lineEdit && event->type() == QEvent::KeyPress) { |
125 | QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event); |
126 | switch (keyEvent->key()) { |
127 | case Qt::Key_Up: |
128 | case Qt::Key_Down: |
129 | case Qt::Key_PageUp: |
130 | case Qt::Key_PageDown: |
131 | QCoreApplication::sendEvent(receiver: ui.listWidget, event); |
132 | break; |
133 | } |
134 | } else if (ui.lineEdit && event->type() == QEvent::FocusIn |
135 | && static_cast<QFocusEvent *>(event)->reason() != Qt::MouseFocusReason) { |
136 | ui.lineEdit->selectAll(); |
137 | ui.lineEdit->setFocus(); |
138 | } |
139 | return QDialog::eventFilter(object, event); |
140 | } |
141 | |
142 | QT_END_NAMESPACE |
143 | |