diff --git a/docs/phpdocsplugin.cpp b/docs/phpdocsplugin.cpp index 548b740..12901db 100644 --- a/docs/phpdocsplugin.cpp +++ b/docs/phpdocsplugin.cpp @@ -1,224 +1,224 @@ /* 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(), dec->comment()); } 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::addToHistory(const QUrl& url) +void PhpDocsPlugin::showDocumentation(const QUrl& url) { auto doc = documentationForUrl(url, url.toString()); - emit addHistory(doc); + 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 98fc665..3030974 100644 --- a/docs/phpdocsplugin.h +++ b/docs/phpdocsplugin.h @@ -1,67 +1,64 @@ /* 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; QIcon icon() const override; QString name() const override; KDevelop::IDocumentation::Ptr homePage() const override; - void addToHistory(const QUrl& url); - - signals: - void addHistory(const KDevelop::IDocumentation::Ptr& doc) 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 diff --git a/docs/phpdocumentationwidget.cpp b/docs/phpdocumentationwidget.cpp index 000785f..6a84419 100644 --- a/docs/phpdocumentationwidget.cpp +++ b/docs/phpdocumentationwidget.cpp @@ -1,117 +1,116 @@ /* 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 "phpdocumentationwidget.h" #include #include #include #include #include #include #include #include "phpdocsplugin.h" #include QTemporaryFile* createStyleSheet(QObject* parent) { auto* file = new QTemporaryFile(parent); bool ret = file->open(); Q_ASSERT(ret); Q_UNUSED(ret); QTextStream ts(file); ts << ".page-tools { float: none !important; } body { background: white !important; };"; return file; } PhpDocumentationWidget::PhpDocumentationWidget(KDevelop::DocumentationFindWidget* find, const QUrl &url, PhpDocsPlugin* provider, QWidget* parent) : QStackedWidget(parent) , m_loading(new QWidget(this)) , m_styleSheet(createStyleSheet(this)) , m_provider(provider) { m_part = new KDevelop::StandardDocumentationView(find, this); m_part->setDelegateLinks(true); addWidget(m_part); addWidget(m_loading); auto* progressbar = new QProgressBar; progressbar->setValue(0); progressbar->setMinimum(0); progressbar->setMaximum(100); progressbar->setAlignment(Qt::AlignCenter); // temporary disabled for initial porting to QWidget-only StandardDocumentationView #if 0 connect( m_part, &KDevelop::StandardDocumentationView::loadProgress, progressbar, &QProgressBar::setValue ); #endif auto* layout = new QVBoxLayout; layout->addStretch(); QLabel* label = new QLabel(i18n("...loading documentation...")); label->setAlignment(Qt::AlignCenter); layout->addWidget(label); layout->addWidget(progressbar); layout->addStretch(); m_loading->setLayout(layout); // temporary disabled for initial porting to QWidget-only StandardDocumentationView #if 0 setCurrentWidget(m_loading); #endif // instead directly show part setCurrentWidget(m_part); connect(m_part, &KDevelop::StandardDocumentationView::linkClicked, this, &PhpDocumentationWidget::linkClicked); // temporary disabled for initial porting to QWidget-only StandardDocumentationView #if 0 connect(m_part, &KDevelop::StandardDocumentationView::loadFinished, this, &PhpDocumentationWidget::documentLoaded); #endif m_part->load( url ); } PhpDocumentationWidget::~PhpDocumentationWidget() { // make sure we don't get called by any of the m_part signals on shutdown, see also: // https://codereview.qt-project.org/#/c/83800/ disconnect(m_part, nullptr, this, nullptr); } void PhpDocumentationWidget::linkClicked(const QUrl& url) { - m_part->load(url); - m_provider->addToHistory(url); + m_provider->showDocumentation(url); } void PhpDocumentationWidget::documentLoaded() { m_part->setOverrideCss(QUrl::fromLocalFile(m_styleSheet->fileName())); setCurrentWidget(m_part); removeWidget(m_loading); delete m_loading; m_loading = nullptr; }