/* * This file is part of KDevelop * * Copyright 2013 Aleix Pol Gonzalez * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program; if not, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "documentationquickopenprovider.h" #include #include #include #include #include #include #include #include using namespace KDevelop; class DocumentationQuickOpenItem : public QuickOpenDataBase { public: DocumentationQuickOpenItem(const QModelIndex& data, IDocumentationProvider* p) : QuickOpenDataBase() , m_data(data) , m_provider(p) {} virtual QString text() const { return m_data.data().toString(); } virtual QString htmlDescription() const { return i18n("Documentation in the %1", m_provider->name()); } virtual bool execute(QString&) { IDocumentation::Ptr docu = m_provider->documentationForIndex(m_data); if(docu) { ICore::self()->documentationController()->showDocumentation(docu); } return docu; } virtual QIcon icon() const { return m_provider->icon(); } private: QModelIndex m_data; IDocumentation::Ptr m_ptr; IDocumentationProvider* m_provider; }; namespace { uint recursiveRowCount(const QAbstractItemModel* m, const QModelIndex& idx) { uint rows = m->rowCount(idx); uint ret = rows; for(uint i = 0; i < rows; i++) { ret += recursiveRowCount(m, m->index(i, 0, idx)); } return ret; } void matchingIndexes(const QAbstractItemModel* m, const QString& match, const QModelIndex& idx, QList& ret, int& preferred) { if(m->hasChildren(idx)) { for(int i = 0, rows = m->rowCount(); i < rows; i++) { matchingIndexes(m, match, m->index(i, 0, idx), ret, preferred); } } else { int index = idx.data().toString().indexOf(match, 0, Qt::CaseInsensitive); if(index == 0) { ret.insert(preferred++, idx); } else if(index > 0) { ret.append(idx); } } } } DocumentationQuickOpenProvider::DocumentationQuickOpenProvider() { } void DocumentationQuickOpenProvider::setFilterText(const QString& text) { if(text.size() < 2) { return; } m_results.clear(); int split = 0; QList providers = ICore::self()->documentationController()->documentationProviders(); foreach(IDocumentationProvider* p, providers) { QList idxs; int internalSplit = 0; int i = 0; matchingIndexes(p->indexModel(), text, QModelIndex(), idxs, internalSplit); foreach(const QModelIndex& idx, idxs) { m_results.insert(split+i, QuickOpenDataPointer(new DocumentationQuickOpenItem(idx, p))); i++; } split += internalSplit; } } uint DocumentationQuickOpenProvider::unfilteredItemCount() const { uint ret = 0; QList providers = ICore::self()->documentationController()->documentationProviders(); foreach(IDocumentationProvider* p, providers) { ret += recursiveRowCount(p->indexModel(), QModelIndex()); } return ret; } QuickOpenDataPointer DocumentationQuickOpenProvider::data(uint row) const { return m_results.at(row); } uint DocumentationQuickOpenProvider::itemCount() const { return m_results.size(); } void DocumentationQuickOpenProvider::reset() { m_results.clear(); }