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