kde-extraapps/kdevelop/projectmanagers/cmake/cmakedocumentation.cpp

204 lines
6.7 KiB
C++
Raw Normal View History

/* KDevelop CMake Support
*
* Copyright 2009 Aleix Pol <aleixpol@kde.org>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU 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 "cmakedocumentation.h"
#include "cmakeutils.h"
#include <KDebug>
#include <QString>
#include <QTextDocument>
#include <QStringListModel>
#include <interfaces/iproject.h>
#include <KStandardDirs>
#include <KIcon>
#include <KGlobalSettings>
#include <KMimeType>
#include <documentation/standarddocumentationview.h>
#include <language/duchain/declaration.h>
#include <interfaces/iplugincontroller.h>
#include <interfaces/iprojectcontroller.h>
#include <interfaces/icore.h>
#include "cmakemanager.h"
#include "cmakeparserutils.h"
#include "cmakehelpdocumentation.h"
#include "cmakedoc.h"
K_PLUGIN_FACTORY(CMakeSupportDocFactory, registerPlugin<CMakeDocumentation>(); )
K_EXPORT_PLUGIN(CMakeSupportDocFactory(KAboutData("kdevcmakedocumentation","kdevcmake", ki18n("CMake Documentation"), "1.0", ki18n("Support for CMake documentation"), KAboutData::License_GPL)))
CMakeDocumentation* CMakeDoc::s_provider=0;
KDevelop::IDocumentationProvider* CMakeDoc::provider() const { return s_provider; }
CMakeDocumentation::CMakeDocumentation(QObject* parent, const QVariantList&)
: KDevelop::IPlugin( CMakeSupportDocFactory::componentData(), parent )
, mCMakeCmd(KStandardDirs::findExe("cmake"))
{
KDEV_USE_EXTENSION_INTERFACE( KDevelop::IDocumentationProvider )
KDEV_USE_EXTENSION_INTERFACE( ICMakeDocumentation )
if (mCMakeCmd.isEmpty()) {
return;
}
CMakeDoc::s_provider=this;
m_index= new QStringListModel(this);
initializeModel();
}
bool CMakeDocumentation::hasError() const
{
return mCMakeCmd.isEmpty();
}
QString CMakeDocumentation::errorDescription() const
{
return mCMakeCmd.isEmpty() ? i18n("cmake is not installed") : QString();
}
static const char* args[] = { "--help-command", "--help-variable", "--help-module", "--help-property", 0, 0 };
void CMakeDocumentation::delayedInitialization()
{
for(int i=0; i<=Property; i++) {
collectIds(QString(args[i])+"-list", (Type) i);
}
m_index->setStringList(m_typeForName.keys());
}
void CMakeDocumentation::collectIds(const QString& param, Type type)
{
QStringList ids=CMakeParserUtils::executeProcess(mCMakeCmd, QStringList(param)).split('\n');
ids.takeFirst();
foreach(const QString& name, ids)
{
m_typeForName[name]=type;
}
}
QStringList CMakeDocumentation::names(CMakeDocumentation::Type t) const
{
return m_typeForName.keys(t);
}
QString CMakeDocumentation::descriptionForIdentifier(const QString& id, Type t) const
{
QString desc;
if(args[t]) {
desc = Qt::escape(CMakeParserUtils::executeProcess(mCMakeCmd, QStringList(args[t]) << id.simplified()));
int firstLine = desc.indexOf('\n');
firstLine = desc.indexOf('\n', firstLine+1);
if(firstLine>=0)
desc = desc.mid(firstLine+1).trimmed(); //we remove the cmake version and the command name
desc.replace(QLatin1String("\n "), QLatin1String("\n"));
desc = QString("<b>%1</b><pre>%2</pre>").arg(id).arg(desc);
}
return desc;
}
KSharedPtr<KDevelop::IDocumentation> CMakeDocumentation::description(const QString& identifier, const KUrl& file) const
{
initializeModel(); //make it not queued
if(!KMimeType::findByUrl(file)->is("text/x-cmake"))
return KSharedPtr<KDevelop::IDocumentation>();
kDebug() << "seeking documentation for " << identifier;
QString desc;
if(m_typeForName.contains(identifier)) {
desc=descriptionForIdentifier(identifier, m_typeForName[identifier]);
} else if(m_typeForName.contains(identifier.toLower())) {
desc=descriptionForIdentifier(identifier, m_typeForName[identifier.toLower()]);
} else if(m_typeForName.contains(identifier.toUpper())) {
desc=descriptionForIdentifier(identifier, m_typeForName[identifier.toUpper()]);
}
KDevelop::IProject* p=KDevelop::ICore::self()->projectController()->findProjectForUrl(file);
ICMakeManager* m=0;
if(p)
m=p->managerPlugin()->extension<ICMakeManager>();
if(m)
{
QPair<QString, QString> entry = m->cacheValue(p, identifier);
if(!entry.first.isEmpty())
desc += i18n("<br /><em>Cache Value:</em> %1\n", entry.first);
if(!entry.second.isEmpty())
desc += i18n("<br /><em>Cache Documentation:</em> %1\n", entry.second);
}
if(desc.isEmpty())
return KSharedPtr<KDevelop::IDocumentation>();
else
return KSharedPtr<KDevelop::IDocumentation>(new CMakeDoc(identifier, desc));
}
KSharedPtr<KDevelop::IDocumentation> CMakeDocumentation::documentationForDeclaration(KDevelop::Declaration* decl) const
{
return description(decl->identifier().toString(), decl->url().toUrl());
}
KSharedPtr<KDevelop::IDocumentation > CMakeDocumentation::documentationForIndex(const QModelIndex& idx) const
{
return description(idx.data().toString(), KUrl("CMakeLists.txt"));
}
QAbstractListModel* CMakeDocumentation::indexModel() const
{
initializeModel();
return m_index;
}
QIcon CMakeDocumentation::icon() const
{
return KIcon("cmake");
}
QString CMakeDocumentation::name() const
{
return "CMake";
}
KSharedPtr<KDevelop::IDocumentation> CMakeDocumentation::homePage() const
{
if(!m_typeForName.isEmpty())
const_cast<CMakeDocumentation*>(this)->delayedInitialization();
// initializeModel();
return KSharedPtr<KDevelop::IDocumentation>(new CMakeHomeDocumentation);
}
void CMakeDocumentation::initializeModel() const
{
if(!m_typeForName.isEmpty())
return;
QMetaObject::invokeMethod(const_cast<CMakeDocumentation*>(this), "delayedInitialization", Qt::QueuedConnection);
}
//////////CMakeDoc
QWidget* CMakeDoc::documentationWidget(KDevelop::DocumentationFindWidget* findWidget, QWidget* parent)
{
KDevelop::StandardDocumentationView* view = new KDevelop::StandardDocumentationView(findWidget, parent);
view->setFont(KGlobalSettings::fixedFont());
view->setHtml("<html><body style='background:#fff'><code>"+description()+"</code></body></html>");
return view;
}