diff --git a/docs/phpdocsplugin.cpp b/docs/phpdocsplugin.cpp index ca84fad..9b8bafa 100644 --- a/docs/phpdocsplugin.cpp +++ b/docs/phpdocsplugin.cpp @@ -1,224 +1,233 @@ /* This file is part of the KDevelop PHP Documentation Plugin Copyright 2012 Milian Wolff 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) version 3 or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 14 of version 3 of the license. 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, see . */ #include "phpdocsplugin.h" #include "phpdocsmodel.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "phpdocsdebug.h" #include "phpdocumentation.h" #include "phpdocssettings.h" using namespace KDevelop; K_PLUGIN_FACTORY_WITH_JSON(PhpDocsFactory, "kdevphpdocs.json", registerPlugin();) PhpDocsPlugin::PhpDocsPlugin(QObject* parent, const QVariantList& args) : IPlugin(QStringLiteral("kdevphpdocs"), parent) , m_model(new PhpDocsModel(this)) { Q_UNUSED(args); readConfig(); KSettings::Dispatcher::registerComponent( QStringLiteral("kdevphpdocs_config"), this, "readConfig" ); } PhpDocsPlugin::~PhpDocsPlugin() { } QString PhpDocsPlugin::name() const { return QStringLiteral("PHP"); } QIcon PhpDocsPlugin::icon() const { static QIcon icon = QIcon::fromTheme(QStringLiteral("application-x-php")); return icon; } void PhpDocsPlugin::readConfig() { // since PhpDocsSettings pointer in this plugin is distinct from the one in the KCM // we have to trigger reading manually PhpDocsSettings::self()->load(); } ///TODO: possibly return multiple filenames (i.e. fallbacks) when doing local lookups QString PhpDocsPlugin::getDocumentationFilename( KDevelop::Declaration* dec, const bool& isLocal ) const { QString fname; //TODO: most of the SPL stuff is not found for me in the deb package php-doc // => check newer documentation or give a fallback to ref.spl.html if ( ClassFunctionDeclaration* fdec = dynamic_cast( dec ) ) { // class methods -> php.net/CLASS.METHOD // local: either CLASS.METHOD.html or function.CLASS-METHOD.html... really sucks :-/ // for now, use the latter... if ( dec->context() && dec->context()->type() == DUContext::Class && dec->context()->owner() ) { QString className = dec->context()->owner()->identifier().toString(); if ( !isLocal ) { fname = className + '.' + fdec->identifier().toString(); } else { if ( fdec->isConstructor() ) { fname = QStringLiteral("construct"); } else if ( fdec->isDestructor() ) { fname = QStringLiteral("destruct"); } else { fname = fdec->identifier().toString(); } //TODO: CLASS.METHOD.html e.g. for xmlreader etc. pp. fname = "function." + className + '-' + fname; } } } else if ( dynamic_cast(dec) ) { fname = "class." + dec->identifier().toString(); } else if ( dynamic_cast(dec) ) { fname = "function." + dec->identifier().toString(); } // check for superglobals / reserved variables else if ( dec->identifier() == Identifier(QStringLiteral("GLOBALS")) || dec->identifier() == Identifier(QStringLiteral("php_errormsg")) || dec->identifier() == Identifier(QStringLiteral("HTTP_RAW_POST_DATA")) || dec->identifier() == Identifier(QStringLiteral("http_response_header")) || dec->identifier() == Identifier(QStringLiteral("argc")) || dec->identifier() == Identifier(QStringLiteral("argv")) || dec->identifier() == Identifier(QStringLiteral("_GET")) || dec->identifier() == Identifier(QStringLiteral("_POST")) || dec->identifier() == Identifier(QStringLiteral("_FILES")) || dec->identifier() == Identifier(QStringLiteral("_REQUEST")) || dec->identifier() == Identifier(QStringLiteral("_SESSION")) || dec->identifier() == Identifier(QStringLiteral("_ENV")) || dec->identifier() == Identifier(QStringLiteral("_COOKIE")) ) { if ( isLocal ) { fname = QStringLiteral("reserved.variables.") + dec->identifier().toString().remove('_'); } else { fname = dec->identifier().toString(); } } qCDebug(DOCS) << fname; if ( !fname.isEmpty() && isLocal ) { fname = fname.toLower(); fname.replace('_', '-'); fname.append(".html"); } return fname; } IDocumentation::Ptr PhpDocsPlugin::documentationForDeclaration( Declaration* dec ) const { if ( dec ) { DUChainReadLocker lock( DUChain::lock() ); // filter non global or non-php declarations if ( dec->topContext()->url() != m_model->internalFunctionFile() ) { return {}; } QUrl url = PhpDocsSettings::phpDocLocation(); qCDebug(DOCS) << url; QString file = getDocumentationFilename( dec, url.isLocalFile() ); if ( file.isEmpty() ) { qCDebug(DOCS) << "no documentation pattern found for" << dec->toString(); return {}; } url.setPath( url.path() + '/' + file); if ( url.isLocalFile() && !QFile::exists( url.toLocalFile() ) ) { qCDebug(DOCS) << "bad path" << url << "for documentation of" << dec->toString() << " - aborting"; return {}; } qCDebug(DOCS) << "php documentation located at " << url << "for" << dec->toString(); return documentationForUrl(url, dec->qualifiedIdentifier().toString()); } return {}; } +IDocumentation::Ptr PhpDocsPlugin::documentation(const QUrl& url) const +{ + if (url.toString().startsWith(PhpDocsSettings::phpDocLocation().toString())) { + return documentationForUrl(url, QString()); + } + return {}; +} + + QAbstractListModel* PhpDocsPlugin::indexModel() const { return m_model; } IDocumentation::Ptr PhpDocsPlugin::documentationForIndex(const QModelIndex& index) const { return documentationForDeclaration(static_cast( index.data(PhpDocsModel::DeclarationRole).value().data() )); } void PhpDocsPlugin::loadUrl(const QUrl& url) const { qCDebug(DOCS) << "loading URL" << url; auto doc = documentationForUrl(url, QString()); ICore::self()->documentationController()->showDocumentation(doc); } void PhpDocsPlugin::showDocumentation(const QUrl& url) { auto doc = documentationForUrl(url, url.toString()); ICore::self()->documentationController()->showDocumentation(doc); } IDocumentation::Ptr PhpDocsPlugin::documentationForUrl(const QUrl& url, const QString& name, const QByteArray& description) const { return IDocumentation::Ptr(new PhpDocumentation( url, name, description, const_cast(this))); } IDocumentation::Ptr PhpDocsPlugin::homePage() const { QUrl url = PhpDocsSettings::phpDocLocation(); if ( url.isLocalFile() ) { url.setPath(url.path() + "/index.html"); } else { url.setPath(url.path() + "/manual"); } return documentationForUrl(url, i18n("PHP Documentation")); } #include "phpdocsplugin.moc" diff --git a/docs/phpdocsplugin.h b/docs/phpdocsplugin.h index 3030974..5da3f07 100644 --- a/docs/phpdocsplugin.h +++ b/docs/phpdocsplugin.h @@ -1,64 +1,65 @@ /* This file is part of the KDevelop PHP Documentation Plugin Copyright 2012 Milian Wolff 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) version 3 or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 14 of version 3 of the license. 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, see . */ #ifndef PHPDOCSPLUGIN_H #define PHPDOCSPLUGIN_H #include #include #include #include class PhpDocsModel; class PhpDocsPlugin : public KDevelop::IPlugin, public KDevelop::IDocumentationProvider { Q_OBJECT Q_INTERFACES( KDevelop::IDocumentationProvider ) public: explicit PhpDocsPlugin(QObject *parent, const QVariantList & args= QVariantList()); ~PhpDocsPlugin() override; KDevelop::IDocumentation::Ptr documentationForDeclaration (KDevelop::Declaration* dec) const override; QAbstractListModel* indexModel() const override; KDevelop::IDocumentation::Ptr documentationForIndex(const QModelIndex& index) const override; + KDevelop::IDocumentation::Ptr documentation(const QUrl& url) const override; QIcon icon() const override; QString name() const override; KDevelop::IDocumentation::Ptr homePage() const override; void showDocumentation(const QUrl& url); public slots: void loadUrl(const QUrl &url) const; private: KDevelop::IDocumentation::Ptr documentationForUrl( const QUrl& url, const QString& name, const QByteArray& description = QByteArray() ) const; QString getDocumentationFilename(KDevelop::Declaration* dec, const bool& isLocal) const; PhpDocsModel* m_model; private slots: void readConfig(); }; #endif // PHPDOCSPLUGIN_H