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