1 /****************************************************************************
3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the Qt Assistant of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** No Commercial Usage
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
16 ** GNU Lesser General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU Lesser
18 ** General Public License version 2.1 as published by the Free Software
19 ** Foundation and appearing in the file LICENSE.LGPL included in the
20 ** packaging of this file. Please review the following information to
21 ** ensure the GNU Lesser General Public License version 2.1 requirements
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 ** In addition, as a special exception, Nokia gives you certain additional
25 ** rights. These rights are described in the Nokia Qt LGPL Exception
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
40 ****************************************************************************/
42 #include "qhelpcontentwidget.h"
43 #include "qhelpenginecore.h"
44 #include "qhelpengine_p.h"
45 #include "qhelpdbreader_p.h"
47 #include <QtCore/QDir>
48 #include <QtCore/QStack>
49 #include <QtCore/QThread>
50 #include <QtCore/QMutex>
51 #include <QtGui/QHeaderView>
55 class QHelpContentItemPrivate
58 QHelpContentItemPrivate(const QString
&t
, const QString
&l
,
59 QHelpDBReader
*r
, QHelpContentItem
*p
)
67 QList
<QHelpContentItem
*> childItems
;
68 QHelpContentItem
*parent
;
71 QHelpDBReader
*helpDBReader
;
74 class QHelpContentProvider
: public QThread
77 QHelpContentProvider(QHelpEnginePrivate
*helpEngine
);
78 ~QHelpContentProvider();
79 void collectContents(const QString
&customFilterName
);
80 void stopCollecting();
81 QHelpContentItem
*rootItem();
82 int nextChildCount() const;
87 QHelpEnginePrivate
*m_helpEngine
;
88 QHelpContentItem
*m_rootItem
;
89 QStringList m_filterAttributes
;
90 QQueue
<QHelpContentItem
*> m_rootItems
;
95 class QHelpContentModelPrivate
98 QHelpContentItem
*rootItem
;
99 QHelpContentProvider
*qhelpContentProvider
;
105 \class QHelpContentItem
107 \brief The QHelpContentItem class provides an item for use with QHelpContentModel.
111 QHelpContentItem::QHelpContentItem(const QString
&name
, const QString
&link
,
112 QHelpDBReader
*reader
, QHelpContentItem
*parent
)
114 d
= new QHelpContentItemPrivate(name
, link
, reader
, parent
);
118 Destroys the help content item.
120 QHelpContentItem::~QHelpContentItem()
122 qDeleteAll(d
->childItems
);
126 void QHelpContentItem::appendChild(QHelpContentItem
*item
)
128 d
->childItems
.append(item
);
132 Returns the child of the content item in the give \a row.
136 QHelpContentItem
*QHelpContentItem::child(int row
) const
138 if (row
>= childCount())
140 return d
->childItems
.value(row
);
144 Returns the number of child items.
146 int QHelpContentItem::childCount() const
148 return d
->childItems
.count();
152 Returns the row of this item from its parents view.
154 int QHelpContentItem::row() const
157 return d
->parent
->d
->childItems
.indexOf(const_cast<QHelpContentItem
*>(this));
162 Returns the title of the content item.
164 QString
QHelpContentItem::title() const
170 Returns the URL of this content item.
172 QUrl
QHelpContentItem::url() const
174 return d
->helpDBReader
->urlOfPath(d
->link
);
178 Returns the parent content item.
180 QHelpContentItem
*QHelpContentItem::parent() const
186 Returns the position of a given \a child.
188 int QHelpContentItem::childPosition(QHelpContentItem
*child
) const
190 return d
->childItems
.indexOf(child
);
195 QHelpContentProvider::QHelpContentProvider(QHelpEnginePrivate
*helpEngine
)
196 : QThread(helpEngine
)
198 m_helpEngine
= helpEngine
;
203 QHelpContentProvider::~QHelpContentProvider()
208 void QHelpContentProvider::collectContents(const QString
&customFilterName
)
211 m_filterAttributes
= m_helpEngine
->q
->filterAttributes(customFilterName
);
221 void QHelpContentProvider::stopCollecting()
231 QHelpContentItem
*QHelpContentProvider::rootItem()
233 QMutexLocker
locker(&m_mutex
);
234 return m_rootItems
.dequeue();
237 int QHelpContentProvider::nextChildCount() const
239 return m_rootItems
.head()->childCount();
242 void QHelpContentProvider::run()
247 QHelpContentItem
*item
= 0;
250 m_rootItem
= new QHelpContentItem(QString(), QString(), 0);
251 m_rootItems
.enqueue(m_rootItem
);
252 QStringList atts
= m_filterAttributes
;
253 const QStringList fileNames
= m_helpEngine
->orderedFileNameList
;
256 foreach (QString dbFileName
, fileNames
) {
264 QHelpDBReader
reader(dbFileName
,
265 QHelpGlobal::uniquifyConnectionName(dbFileName
+
266 QLatin1String("FromQHelpContentProvider"),
267 QThread::currentThread()), 0);
270 foreach (const QByteArray
& ba
, reader
.contentsForFilter(atts
)) {
276 QStack
<QHelpContentItem
*> stack
;
288 item
= new QHelpContentItem(title
, link
,
289 m_helpEngine
->fileNameReaderMap
.value(dbFileName
), m_rootItem
);
290 m_rootItem
->appendChild(item
);
296 if (depth
> _depth
&& _root
) {
300 if (depth
== _depth
) {
301 item
= new QHelpContentItem(title
, link
,
302 m_helpEngine
->fileNameReaderMap
.value(dbFileName
), stack
.top());
303 stack
.top()->appendChild(item
);
304 } else if (depth
< _depth
) {
321 \class QHelpContentModel
323 \brief The QHelpContentModel class provides a model that supplies content to views.
328 \fn void QHelpContentModel::contentsCreationStarted()
330 This signal is emitted when the creation of the contents has
331 started. The current contents are invalid from this point on
332 until the signal contentsCreated() is emitted.
334 \sa isCreatingContents()
338 \fn void QHelpContentModel::contentsCreated()
340 This signal is emitted when the contents have been created.
343 QHelpContentModel::QHelpContentModel(QHelpEnginePrivate
*helpEngine
)
344 : QAbstractItemModel(helpEngine
)
346 d
= new QHelpContentModelPrivate();
348 d
->qhelpContentProvider
= new QHelpContentProvider(helpEngine
);
350 connect(d
->qhelpContentProvider
, SIGNAL(finished()),
351 this, SLOT(insertContents()), Qt::QueuedConnection
);
352 connect(helpEngine
->q
, SIGNAL(setupStarted()), this, SLOT(invalidateContents()));
356 Destroys the help content model.
358 QHelpContentModel::~QHelpContentModel()
364 void QHelpContentModel::invalidateContents(bool onShutDown
)
367 disconnect(this, SLOT(insertContents()));
368 d
->qhelpContentProvider
->stopCollecting();
377 Creates new contents by querying the help system
378 for contents specified for the \a customFilterName.
380 void QHelpContentModel::createContents(const QString
&customFilterName
)
382 d
->qhelpContentProvider
->collectContents(customFilterName
);
383 emit
contentsCreationStarted();
386 void QHelpContentModel::insertContents()
390 count
= d
->rootItem
->childCount() - 1;
391 beginRemoveRows(QModelIndex(), 0, count
> 0 ? count
: 0);
397 count
= d
->qhelpContentProvider
->nextChildCount() - 1;
398 beginInsertRows(QModelIndex(), 0, count
> 0 ? count
: 0);
399 d
->rootItem
= d
->qhelpContentProvider
->rootItem();
402 emit
contentsCreated();
406 Returns true if the contents are currently rebuilt, otherwise
409 bool QHelpContentModel::isCreatingContents() const
411 return d
->qhelpContentProvider
->isRunning();
415 Returns the help content item at the model index position
418 QHelpContentItem
*QHelpContentModel::contentItemAt(const QModelIndex
&index
) const
421 return static_cast<QHelpContentItem
*>(index
.internalPointer());
427 Returns the index of the item in the model specified by
428 the given \a row, \a column and \a parent index.
430 QModelIndex
QHelpContentModel::index(int row
, int column
, const QModelIndex
&parent
) const
433 return QModelIndex();
435 QHelpContentItem
*parentItem
= contentItemAt(parent
);
436 QHelpContentItem
*item
= parentItem
->child(row
);
438 return QModelIndex();
439 return createIndex(row
, column
, item
);
443 Returns the parent of the model item with the given
444 \a index, or QModelIndex() if it has no parent.
446 QModelIndex
QHelpContentModel::parent(const QModelIndex
&index
) const
448 QHelpContentItem
*item
= contentItemAt(index
);
450 return QModelIndex();
452 QHelpContentItem
*parentItem
= static_cast<QHelpContentItem
*>(item
->parent());
454 return QModelIndex();
456 QHelpContentItem
*grandparentItem
= static_cast<QHelpContentItem
*>(parentItem
->parent());
457 if (!grandparentItem
)
458 return QModelIndex();
460 int row
= grandparentItem
->childPosition(parentItem
);
461 return createIndex(row
, index
.column(), parentItem
);
465 Returns the number of rows under the given \a parent.
467 int QHelpContentModel::rowCount(const QModelIndex
&parent
) const
469 QHelpContentItem
*parentItem
= contentItemAt(parent
);
472 return parentItem
->childCount();
476 Returns the number of columns under the given \a parent. Currently returns always 1.
478 int QHelpContentModel::columnCount(const QModelIndex
&parent
) const
486 Returns the data stored under the given \a role for
487 the item referred to by the \a index.
489 QVariant
QHelpContentModel::data(const QModelIndex
&index
, int role
) const
491 if (role
!= Qt::DisplayRole
)
494 QHelpContentItem
*item
= contentItemAt(index
);
497 return item
->title();
503 \class QHelpContentWidget
505 \brief The QHelpContentWidget class provides a tree view for displaying help content model items.
510 \fn void QHelpContentWidget::linkActivated(const QUrl &link)
512 This signal is emitted when a content item is activated and
513 its associated \a link should be shown.
516 QHelpContentWidget::QHelpContentWidget()
520 setUniformRowHeights(true);
521 connect(this, SIGNAL(activated(QModelIndex
)),
522 this, SLOT(showLink(QModelIndex
)));
526 Returns the index of the content item with the \a link.
527 An invalid index is returned if no such an item exists.
529 QModelIndex
QHelpContentWidget::indexOf(const QUrl
&link
)
531 QHelpContentModel
*contentModel
=
532 qobject_cast
<QHelpContentModel
*>(model());
533 if (!contentModel
|| link
.scheme() != QLatin1String("qthelp"))
534 return QModelIndex();
536 m_syncIndex
= QModelIndex();
537 for (int i
=0; i
<contentModel
->rowCount(); ++i
) {
538 QHelpContentItem
*itm
=
539 contentModel
->contentItemAt(contentModel
->index(i
, 0));
540 if (itm
&& itm
->url().host() == link
.host()) {
541 QString path
= link
.path();
542 if (path
.startsWith(QLatin1Char('/')))
544 if (searchContentItem(contentModel
, contentModel
->index(i
, 0), path
)) {
549 return QModelIndex();
552 bool QHelpContentWidget::searchContentItem(QHelpContentModel
*model
,
553 const QModelIndex
&parent
, const QString
&path
)
555 QHelpContentItem
*parentItem
= model
->contentItemAt(parent
);
559 if (QDir::cleanPath(parentItem
->url().path()) == path
) {
560 m_syncIndex
= parent
;
564 for (int i
=0; i
<parentItem
->childCount(); ++i
) {
565 if (searchContentItem(model
, model
->index(i
, 0, parent
), path
))
571 void QHelpContentWidget::showLink(const QModelIndex
&index
)
573 QHelpContentModel
*contentModel
= qobject_cast
<QHelpContentModel
*>(model());
577 QHelpContentItem
*item
= contentModel
->contentItemAt(index
);
580 QUrl url
= item
->url();
582 emit
linkActivated(url
);