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
qhelpcontentwidget.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
7
8#if QT_CONFIG(future)
9#include <QtCore/qfuturewatcher.h>
10#endif
11
12#include <QtCore/qdir.h>
13#include <QtWidgets/qheaderview.h>
14
16
17using namespace Qt::StringLiterals;
18
20{
21#if QT_CONFIG(future)
23
24 struct WatcherDeleter
25 {
28 watcher->cancel();
30 delete watcher;
31 }
32 };
33#endif
34
35public:
36#if QT_CONFIG(future)
38#endif
39
40 QHelpContentModel *q = nullptr;
41 QHelpEngineCore *helpEngine = nullptr;
43#if QT_CONFIG(future)
45#endif
46};
47
48#if QT_CONFIG(future)
49void QHelpContentModelPrivate::createContents(const ItemFutureProvider &futureProvider)
50{
51 const bool wasRunning = bool(watcher);
52 watcher.reset(new QFutureWatcher<std::shared_ptr<QHelpContentItem>>);
53 QObject::connect(watcher.get(), &QFutureWatcherBase::finished, q, [this] {
54 if (!watcher->isCanceled()) {
55 const std::shared_ptr<QHelpContentItem> result = watcher->result();
56 if (result && result.get()) {
57 q->beginResetModel();
58 rootItem = result;
59 q->endResetModel();
60 }
61 }
62 watcher.release()->deleteLater();
63 emit q->contentsCreated();
64 });
65 watcher->setFuture(futureProvider());
66
67 if (wasRunning)
68 return;
69
70 if (rootItem) {
71 q->beginResetModel();
72 rootItem.reset();
73 q->endResetModel();
74 }
75 emit q->contentsCreationStarted();
76}
77#endif
78
79/*!
80 \class QHelpContentModel
81 \inmodule QtHelp
82 \brief The QHelpContentModel class provides a model that supplies content to views.
83 \since 4.4
84*/
85
86/*!
87 \fn void QHelpContentModel::contentsCreationStarted()
88
89 This signal is emitted when the creation of the contents has
90 started. The current contents are invalid from this point on
91 until the signal contentsCreated() is emitted.
92
93 \sa isCreatingContents()
94*/
95
96/*!
97 \fn void QHelpContentModel::contentsCreated()
98
99 This signal is emitted when the contents have been created.
100*/
101
102QHelpContentModel::QHelpContentModel(QHelpEngineCore *helpEngine)
103 : QAbstractItemModel(helpEngine)
104 , d(new QHelpContentModelPrivate{this, helpEngine})
105{}
106
107/*!
108 Destroys the help content model.
109*/
110QHelpContentModel::~QHelpContentModel()
111{
112 delete d;
113}
114
115/*!
116 \since 6.8
117
118 Creates new contents by querying the help system for contents specified for the current filter.
119*/
120void QHelpContentModel::createContentsForCurrentFilter()
121{
122#if QT_CONFIG(future)
123 d->createContents([this] { return d->helpEngine->requestContentForCurrentFilter(); });
124#endif
125}
126
127/*!
128 Creates new contents by querying the help system
129 for contents specified for the custom \a filter name.
130*/
131void QHelpContentModel::createContents(const QString &filter)
132{
133#if QT_CONFIG(future)
134 d->createContents([this, filter] { return d->helpEngine->requestContent(filter); });
135#endif
136}
137
138// TODO: Remove me
139void QHelpContentModel::insertContents()
140{}
141
142/*!
143 Returns true if the contents are currently rebuilt, otherwise
144 false.
145*/
146bool QHelpContentModel::isCreatingContents() const
147{
148#if QT_CONFIG(future)
149 return bool(d->watcher);
150#else
151 return false;
152#endif
153}
154
155/*!
156 Returns the help content item at the model index position
157 \a index.
158*/
159QHelpContentItem *QHelpContentModel::contentItemAt(const QModelIndex &index) const
160{
161 return index.isValid() ? static_cast<QHelpContentItem *>(index.internalPointer())
162 : d->rootItem.get();
163}
164
165/*!
166 Returns the index of the item in the model specified by
167 the given \a row, \a column and \a parent index.
168*/
169QModelIndex QHelpContentModel::index(int row, int column, const QModelIndex &parent) const
170{
171 if (!d->rootItem)
172 return {};
173
174 QHelpContentItem *parentItem = contentItemAt(parent);
175 QHelpContentItem *item = parentItem->child(row);
176 if (!item)
177 return {};
178 return createIndex(row, column, item);
179}
180
181/*!
182 Returns the parent of the model item with the given
183 \a index, or QModelIndex() if it has no parent.
184*/
185QModelIndex QHelpContentModel::parent(const QModelIndex &index) const
186{
187 QHelpContentItem *item = contentItemAt(index);
188 if (!item)
189 return {};
190
191 QHelpContentItem *parentItem = static_cast<QHelpContentItem*>(item->parent());
192 if (!parentItem)
193 return {};
194
195 QHelpContentItem *grandparentItem = static_cast<QHelpContentItem*>(parentItem->parent());
196 if (!grandparentItem)
197 return {};
198
199 const int row = grandparentItem->childPosition(parentItem);
200 return createIndex(row, index.column(), parentItem);
201}
202
203/*!
204 Returns the number of rows under the given \a parent.
205*/
206int QHelpContentModel::rowCount(const QModelIndex &parent) const
207{
208 QHelpContentItem *parentItem = contentItemAt(parent);
209 if (parentItem)
210 return parentItem->childCount();
211 return 0;
212}
213
214/*!
215 Returns the number of columns under the given \a parent. Currently returns always 1.
216*/
217int QHelpContentModel::columnCount(const QModelIndex &parent) const
218{
219 Q_UNUSED(parent);
220 return 1;
221}
222
223/*!
224 Returns the data stored under the given \a role for
225 the item referred to by the \a index.
226*/
227QVariant QHelpContentModel::data(const QModelIndex &index, int role) const
228{
229 if (role == Qt::DisplayRole) {
230 QHelpContentItem *item = contentItemAt(index);
231 if (item)
232 return item->title();
233 }
234 return {};
235}
236
237/*!
238 \class QHelpContentWidget
239 \inmodule QtHelp
240 \brief The QHelpContentWidget class provides a tree view for displaying help content model items.
241 \since 4.4
242*/
243
244/*!
245 \fn void QHelpContentWidget::linkActivated(const QUrl &link)
246
247 This signal is emitted when a content item is activated and
248 its associated \a link should be shown.
249*/
250
251QHelpContentWidget::QHelpContentWidget()
252{
253 header()->hide();
254 setUniformRowHeights(true);
255 connect(this, &QAbstractItemView::activated, this, &QHelpContentWidget::showLink);
256}
257
258/*!
259 Returns the index of the content item with the \a link.
260 An invalid index is returned if no such an item exists.
261*/
262QModelIndex QHelpContentWidget::indexOf(const QUrl &link)
263{
264 QHelpContentModel *contentModel = qobject_cast<QHelpContentModel*>(model());
265 if (!contentModel || link.scheme() != "qthelp"_L1)
266 return {};
267
268 m_syncIndex = {};
269 for (int i = 0; i < contentModel->rowCount(); ++i) {
270 QHelpContentItem *itm = contentModel->contentItemAt(contentModel->index(i, 0));
271 if (itm && itm->url().host() == link.host()) {
272 if (searchContentItem(contentModel, contentModel->index(i, 0), QDir::cleanPath(link.path())))
273 return m_syncIndex;
274 }
275 }
276 return {};
277}
278
279bool QHelpContentWidget::searchContentItem(QHelpContentModel *model, const QModelIndex &parent,
280 const QString &cleanPath)
281{
282 QHelpContentItem *parentItem = model->contentItemAt(parent);
283 if (!parentItem)
284 return false;
285
286 if (QDir::cleanPath(parentItem->url().path()) == cleanPath) {
287 m_syncIndex = parent;
288 return true;
289 }
290
291 for (int i = 0; i < parentItem->childCount(); ++i) {
292 if (searchContentItem(model, model->index(i, 0, parent), cleanPath))
293 return true;
294 }
295 return false;
296}
297
298void QHelpContentWidget::showLink(const QModelIndex &index)
299{
300 QHelpContentModel *contentModel = qobject_cast<QHelpContentModel*>(model());
301 if (!contentModel)
302 return;
303
304 QHelpContentItem *item = contentModel->contentItemAt(index);
305 if (!item)
306 return;
307 QUrl url = item->url();
308 if (url.isValid())
309 emit linkActivated(url);
310}
311
312QT_END_NAMESPACE
std::shared_ptr< QHelpContentItem > rootItem
Combined button and popup list for selecting options.