File indexing completed on 2024-05-05 04:40:52

0001 /*
0002     SPDX-FileCopyrightText: 2013 Aleix Pol Gonzalez <aleixpol@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include "documentationquickopenprovider.h"
0008 #include <interfaces/icore.h>
0009 #include <interfaces/idocumentationcontroller.h>
0010 #include <interfaces/idocumentationprovider.h>
0011 #include <KLocalizedString>
0012 #include <QAbstractItemModel>
0013 #include <QIcon>
0014 
0015 using namespace KDevelop;
0016 
0017 class DocumentationQuickOpenItem
0018     : public QuickOpenDataBase
0019 {
0020 public:
0021     DocumentationQuickOpenItem(const QModelIndex& data, IDocumentationProvider* p)
0022         : QuickOpenDataBase()
0023         , m_data(data)
0024         , m_provider(p)
0025     {}
0026 
0027     QString text() const override
0028     {
0029         return m_data.data().toString();
0030     }
0031     QString htmlDescription() const override
0032     {
0033         return i18n("Documentation in the %1", m_provider->name());
0034     }
0035     bool execute(QString&) override
0036     {
0037         IDocumentation::Ptr docu = m_provider->documentationForIndex(m_data);
0038         if (docu) {
0039             ICore::self()->documentationController()->showDocumentation(docu);
0040         }
0041         return docu;
0042     }
0043     QIcon icon() const override
0044     {
0045         return m_provider->icon();
0046     }
0047 
0048 private:
0049     const QModelIndex m_data;
0050     IDocumentationProvider* const m_provider;
0051 };
0052 
0053 namespace {
0054 uint recursiveRowCount(const QAbstractItemModel* m, const QModelIndex& idx)
0055 {
0056     uint rows = m->rowCount(idx);
0057     uint ret = rows;
0058 
0059     for (uint i = 0; i < rows; i++) {
0060         ret += recursiveRowCount(m, m->index(i, 0, idx));
0061     }
0062 
0063     return ret;
0064 }
0065 
0066 void matchingIndexes(const QAbstractItemModel* m, const QString& match, const QModelIndex& idx, QList<QModelIndex>& ret, int& preferred)
0067 {
0068     if (m->hasChildren(idx)) {
0069         for (int i = 0, rows = m->rowCount(); i < rows; i++) {
0070             matchingIndexes(m, match, m->index(i, 0, idx), ret, preferred);
0071         }
0072     } else {
0073         int index = idx.data().toString().indexOf(match, 0, Qt::CaseInsensitive);
0074         if (index == 0) {
0075             ret.insert(preferred++, idx);
0076         } else if (index > 0) {
0077             ret.append(idx);
0078         }
0079     }
0080 }
0081 }
0082 
0083 DocumentationQuickOpenProvider::DocumentationQuickOpenProvider()
0084 {
0085     connect(ICore::self()->documentationController(), &IDocumentationController::providersChanged,
0086             this, &DocumentationQuickOpenProvider::reset);
0087 }
0088 
0089 void DocumentationQuickOpenProvider::setFilterText(const QString& text)
0090 {
0091     if (text.size() < 2) {
0092         return;
0093     }
0094     m_results.clear();
0095     int split = 0;
0096     const QList<IDocumentationProvider*> providers = ICore::self()->documentationController()->documentationProviders();
0097     for (IDocumentationProvider* p : providers) {
0098         QList<QModelIndex> idxs;
0099         int internalSplit = 0;
0100         int i = 0;
0101         matchingIndexes(p->indexModel(), text, QModelIndex(), idxs, internalSplit);
0102         for (const QModelIndex& idx : qAsConst(idxs)) {
0103             m_results.insert(split + i, QuickOpenDataPointer(new DocumentationQuickOpenItem(idx, p)));
0104             i++;
0105         }
0106 
0107         split += internalSplit;
0108     }
0109 }
0110 
0111 uint DocumentationQuickOpenProvider::unfilteredItemCount() const
0112 {
0113     uint ret = 0;
0114     const QList<IDocumentationProvider*> providers = ICore::self()->documentationController()->documentationProviders();
0115     for (IDocumentationProvider* p : providers) {
0116         ret += recursiveRowCount(p->indexModel(), QModelIndex());
0117     }
0118 
0119     return ret;
0120 }
0121 
0122 QuickOpenDataPointer DocumentationQuickOpenProvider::data(uint row) const
0123 {
0124     return m_results.at(row);
0125 }
0126 
0127 uint DocumentationQuickOpenProvider::itemCount() const
0128 {
0129     return m_results.size();
0130 }
0131 
0132 void DocumentationQuickOpenProvider::reset()
0133 {
0134     m_results.clear();
0135 }
0136 
0137 #include "moc_documentationquickopenprovider.cpp"