diff options
author | Jarek Kobus <jaroslaw.kobus@nokia.com> | 2011-11-10 11:55:05 +0100 |
---|---|---|
committer | Jarek Kobus <jaroslaw.kobus@nokia.com> | 2011-11-10 16:55:11 +0100 |
commit | da14d8610497ea5a272fae715efa18fc8643b9d7 (patch) | |
tree | 99c3b8189404d6405e7162c6edcadb904372055e /src | |
parent | 8fcb4d808415eab5f9b02fa448b03dff60191d9a (diff) | |
download | qt-creator-da14d8610497ea5a272fae715efa18fc8643b9d7.tar.gz |
Implement context help for pro file editor
Task-number: QTCREATORBUG-6325
Change-Id: Ie8b2eb582eb527eac6af56d0c69a8ae1dafdc1df
Reviewed-by: Leandro Melo <leandro.melo@nokia.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/libs/utils/htmldocextractor.cpp | 51 | ||||
-rw-r--r-- | src/libs/utils/htmldocextractor.h | 4 | ||||
-rw-r--r-- | src/plugins/help/helpplugin.cpp | 6 | ||||
-rw-r--r-- | src/plugins/qt4projectmanager/profilehoverhandler.cpp | 170 | ||||
-rw-r--r-- | src/plugins/qt4projectmanager/profilehoverhandler.h | 87 | ||||
-rw-r--r-- | src/plugins/qt4projectmanager/qt4projectmanager.pro | 2 | ||||
-rw-r--r-- | src/plugins/qt4projectmanager/qt4projectmanagerplugin.cpp | 2 | ||||
-rw-r--r-- | src/plugins/texteditor/basehoverhandler.cpp | 2 | ||||
-rw-r--r-- | src/plugins/texteditor/basehoverhandler.h | 2 | ||||
-rw-r--r-- | src/plugins/texteditor/helpitem.cpp | 11 | ||||
-rw-r--r-- | src/plugins/texteditor/helpitem.h | 1 |
11 files changed, 332 insertions, 6 deletions
diff --git a/src/libs/utils/htmldocextractor.cpp b/src/libs/utils/htmldocextractor.cpp index f375bf1d06..36983d22d9 100644 --- a/src/libs/utils/htmldocextractor.cpp +++ b/src/libs/utils/htmldocextractor.cpp @@ -147,10 +147,10 @@ QString HtmlDocExtractor::getQmlComponentDescription(const QString &html, const QString HtmlDocExtractor::getQmlPropertyDescription(const QString &html, const QString &mark) const { - QString startMark = QString("<a name=\"%1-prop\">").arg(mark); + QString startMark = QString::fromLatin1("<a name=\"%1-prop\">").arg(mark); int index = html.indexOf(startMark); if (index == -1) { - startMark = QString("<a name=\"%1-signal\">").arg(mark); + startMark = QString::fromLatin1("<a name=\"%1-signal\">").arg(mark); index = html.indexOf(startMark); } if (index == -1) @@ -166,6 +166,42 @@ QString HtmlDocExtractor::getQmlPropertyDescription(const QString &html, const Q return contents; } +QString HtmlDocExtractor::getQMakeVariableOrFunctionDescription(const QString &html, + const QString &mark) const +{ + const QString startMark = QString::fromLatin1("<a name=\"%1\"></a>").arg(mark); + int index = html.indexOf(startMark); + if (index == -1) + return QString(); + + QString contents = html.mid(index + startMark.size()); + index = contents.indexOf(QLatin1String("<!-- @@@qmake")); + if (index == -1) + return QString(); + contents = contents.left(index); + processOutput(&contents); + + return contents; +} + +QString HtmlDocExtractor::getQMakeFunctionId(const QString &html, + const QString &mark) const +{ + const QString startMark = QString::fromLatin1("<a name=\"%1-").arg(mark); + const int startIndex = html.indexOf(startMark); + if (startIndex == -1) + return QString(); + + const int startKeyIndex = html.indexOf(mark, startIndex); + + const QString endMark = QLatin1String("\"></a>"); + const int endKeyIndex = html.indexOf(endMark, startKeyIndex); + if (endKeyIndex == -1) + return QString(); + + return html.mid(startKeyIndex, endKeyIndex - startKeyIndex); +} + QString HtmlDocExtractor::getClassOrNamespaceMemberDescription(const QString &html, const QString &startMark, const QString &endMark) const @@ -206,9 +242,18 @@ void HtmlDocExtractor::processOutput(QString *html) const if (m_mode == FirstParagraph) { // Try to get the entire first paragraph, but if one is not found or if its opening // tag is not in the very beginning (using an empirical value as the limit) the html - // is cleared to avoid too much content. + // is cleared to avoid too much content. In case the first paragraph looks like: + // <p><i>This is only used on the Maemo platform.</i></p> + // or: <p><tt>This is used on Windows only.</tt></p> + // or: <p>[Conditional]</p> + // include also the next paragraph. int index = html->indexOf(QLatin1String("<p>")); if (index != -1 && index < 400) { + if (html->indexOf(QLatin1String("<p><i>")) == index || + html->indexOf(QLatin1String("<p><tt>")) == index || + html->indexOf(QLatin1String("<p>[Conditional]</p>")) == index) + index = html->indexOf(QLatin1String("<p>"), index + 6); // skip the first paragraph + index = html->indexOf(QLatin1String("</p>"), index + 3); if (index != -1) { // Most paragraphs end with a period, but there are cases without punctuation diff --git a/src/libs/utils/htmldocextractor.h b/src/libs/utils/htmldocextractor.h index 68523ff151..508c5aff03 100644 --- a/src/libs/utils/htmldocextractor.h +++ b/src/libs/utils/htmldocextractor.h @@ -62,6 +62,10 @@ public: const bool mainOverload = true) const; QString getQmlComponentDescription(const QString &html, const QString &mark) const; QString getQmlPropertyDescription(const QString &html, const QString &mark) const; + QString getQMakeVariableOrFunctionDescription(const QString &html, + const QString &mark) const; + QString getQMakeFunctionId(const QString &html, + const QString &mark) const; private: QString getClassOrNamespaceMemberDescription(const QString &html, diff --git a/src/plugins/help/helpplugin.cpp b/src/plugins/help/helpplugin.cpp index 04e0645b9b..addc4b9909 100644 --- a/src/plugins/help/helpplugin.cpp +++ b/src/plugins/help/helpplugin.cpp @@ -883,6 +883,12 @@ void HelpPlugin::activateContext() if (IContext *context = m_core->currentContextObject()) { m_idFromContext = context->contextHelpId(); links = Core::HelpManager::instance()->linksForIdentifier(m_idFromContext); + if (links.isEmpty()) { + // Maybe this is already an URL... + QUrl url(m_idFromContext); + if (url.isValid()) + links.insert(m_idFromContext, m_idFromContext); + } } if (HelpViewer* viewer = viewerForContextMode()) { diff --git a/src/plugins/qt4projectmanager/profilehoverhandler.cpp b/src/plugins/qt4projectmanager/profilehoverhandler.cpp new file mode 100644 index 0000000000..4320834642 --- /dev/null +++ b/src/plugins/qt4projectmanager/profilehoverhandler.cpp @@ -0,0 +1,170 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +#include "profilehoverhandler.h" +#include "profileeditor.h" +#include "profilekeywords.h" + +#include <coreplugin/editormanager/ieditor.h> +#include <coreplugin/editormanager/editormanager.h> +#include <coreplugin/helpmanager.h> +#include <extensionsystem/pluginmanager.h> +#include <texteditor/itexteditor.h> +#include <texteditor/basetexteditor.h> +#include <texteditor/helpitem.h> +#include <texteditor/tooltip/tooltip.h> +#include <utils/htmldocextractor.h> + +#include <QtGui/QTextCursor> +#include <QtGui/QTextBlock> +#include <QtCore/QUrl> + +using namespace Qt4ProjectManager; +using namespace Qt4ProjectManager::Internal; +using namespace Core; + +ProFileHoverHandler::ProFileHoverHandler(QObject *parent) + : BaseHoverHandler(parent), + m_manualKind(UnknownManual) +{ +} + +ProFileHoverHandler::~ProFileHoverHandler() +{} + +bool ProFileHoverHandler::acceptEditor(IEditor *editor) +{ + if (qobject_cast<ProFileEditor *>(editor) != 0) + return true; + return false; +} + +void ProFileHoverHandler::identifyMatch(TextEditor::ITextEditor *editor, int pos) +{ + m_docFragment = QString(); + m_manualKind = UnknownManual; + if (ProFileEditorWidget *proFileEditor = qobject_cast<ProFileEditorWidget *>(editor->widget())) { + if (!proFileEditor->extraSelectionTooltip(pos).isEmpty()) { + setToolTip(proFileEditor->extraSelectionTooltip(pos)); + } else { + QTextDocument *document = proFileEditor->document(); + QTextBlock block = document->findBlock(pos); + identifyQMakeKeyword(block.text(), pos - block.position()); + + if (m_manualKind != UnknownManual) { + QUrl url(QString::fromLatin1("qthelp://com.trolltech.qmake/qdoc/qmake-%1-reference.html#%2") + .arg(manualName()).arg(m_docFragment)); + setLastHelpItemIdentified(TextEditor::HelpItem(url.toString(), + m_docFragment, TextEditor::HelpItem::QMakeVariableOfFunction)); + } else { + // General qmake manual will be shown outside any function or variable + setLastHelpItemIdentified(TextEditor::HelpItem(QLatin1String("qmake"), + TextEditor::HelpItem::Unknown)); + } + } + } +} + +void ProFileHoverHandler::identifyQMakeKeyword(const QString &text, int pos) +{ + if (text.isEmpty()) + return; + + QString buf; + + for (int i = 0; i < text.length(); ++i) { + const QChar c = text.at(i); + bool checkBuffer = false; + if (c.isLetter() || c == QLatin1Char('_') || c == QLatin1Char('.') || c.isDigit()) { + buf += c; + if (i == text.length() - 1) + checkBuffer = true; + } else { + checkBuffer = true; + } + if (checkBuffer) { + if (!buf.isEmpty()) { + if ((i >= pos) && (i - buf.size() <= pos)) { + if (ProFileKeywords::isFunction(buf)) + identifyDocFragment(FunctionManual, buf); + else if (ProFileKeywords::isVariable(buf)) + identifyDocFragment(VariableManual, buf); + break; + } + buf.clear(); + } else { + if (i >= pos) + break; // we are after the tooltip pos + } + if (c == '#') + break; // comment start + } + } +} + +QString ProFileHoverHandler::manualName() const +{ + if (m_manualKind == FunctionManual) + return QLatin1String("function"); + else if (m_manualKind == VariableManual) + return QLatin1String("variable"); + return QString(); +} + +void ProFileHoverHandler::identifyDocFragment(ProFileHoverHandler::ManualKind manualKind, + const QString &keyword) +{ + m_manualKind = manualKind; + m_docFragment = keyword.toLower(); + // Special case: _PRO_FILE_ and _PRO_FILE_PWD_ ids + // don't have starting and ending '_'. + if (m_docFragment.startsWith(QLatin1Char('_'))) + m_docFragment = m_docFragment.mid(1); + if (m_docFragment.endsWith(QLatin1Char('_'))) + m_docFragment = m_docFragment.left(m_docFragment.size() - 1); + m_docFragment.replace(QLatin1Char('.'), QLatin1Char('-')); + m_docFragment.replace(QLatin1Char('_'), QLatin1Char('-')); + + if (m_manualKind == FunctionManual) { + QUrl url(QString::fromLatin1("qthelp://com.trolltech.qmake/qdoc/qmake-%1-reference.html").arg(manualName())); + const QByteArray &html = Core::HelpManager::instance()->fileData(url); + + Utils::HtmlDocExtractor htmlExtractor; + htmlExtractor.setMode(Utils::HtmlDocExtractor::FirstParagraph); + + // Document fragment of qmake function is retrieved from docs. + // E.g. in case of the keyword "find" the document fragment + // parsed from docs is "find-variablename-substr". + m_docFragment = htmlExtractor.getQMakeFunctionId(html, m_docFragment); + } +} + diff --git a/src/plugins/qt4projectmanager/profilehoverhandler.h b/src/plugins/qt4projectmanager/profilehoverhandler.h new file mode 100644 index 0000000000..32b43c051f --- /dev/null +++ b/src/plugins/qt4projectmanager/profilehoverhandler.h @@ -0,0 +1,87 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ + +#ifndef PROFILEHOVERHANDLER_H +#define PROFILEHOVERHANDLER_H + +#include <texteditor/basehoverhandler.h> + +#include <QtCore/QObject> + +QT_BEGIN_NAMESPACE +class QUrl; +QT_END_NAMESPACE + +namespace Core { +class IEditor; +} + +namespace TextEditor { +class ITextEditor; +} + +namespace Qt4ProjectManager { +namespace Internal { + +class ProFileHoverHandler : public TextEditor::BaseHoverHandler +{ + Q_OBJECT +public: + ProFileHoverHandler(QObject *parent = 0); + virtual ~ProFileHoverHandler(); + +signals: + void creatorHelpRequested(const QUrl &url); + +private: + virtual bool acceptEditor(Core::IEditor *editor); + virtual void identifyMatch(TextEditor::ITextEditor *editor, int pos); + void identifyQMakeKeyword(const QString &text, int pos); + + enum ManualKind { + VariableManual, + FunctionManual, + UnknownManual + }; + + QString manualName() const; + void identifyDocFragment(ManualKind manualKind, + const QString &keyword); + + QString m_docFragment; + ManualKind m_manualKind; +}; + +} // namespace Internal +} // namespace Qt4ProjectManager + +#endif // PROFILEHOVERHANDLER_H diff --git a/src/plugins/qt4projectmanager/qt4projectmanager.pro b/src/plugins/qt4projectmanager/qt4projectmanager.pro index 81410e78fb..81c8548fdf 100644 --- a/src/plugins/qt4projectmanager/qt4projectmanager.pro +++ b/src/plugins/qt4projectmanager/qt4projectmanager.pro @@ -13,6 +13,7 @@ HEADERS += \ profileeditor.h \ profilehighlighter.h \ profileeditorfactory.h \ + profilehoverhandler.h \ wizards/qtprojectparameters.h \ wizards/guiappwizard.h \ wizards/mobileapp.h \ @@ -75,6 +76,7 @@ SOURCES += qt4projectmanagerplugin.cpp \ profileeditor.cpp \ profilehighlighter.cpp \ profileeditorfactory.cpp \ + profilehoverhandler.cpp \ wizards/qtprojectparameters.cpp \ wizards/guiappwizard.cpp \ wizards/mobileapp.cpp \ diff --git a/src/plugins/qt4projectmanager/qt4projectmanagerplugin.cpp b/src/plugins/qt4projectmanager/qt4projectmanagerplugin.cpp index 00dac5e408..1c4cd99910 100644 --- a/src/plugins/qt4projectmanager/qt4projectmanagerplugin.cpp +++ b/src/plugins/qt4projectmanager/qt4projectmanagerplugin.cpp @@ -47,6 +47,7 @@ #include "wizards/html5appwizard.h" #include "customwidgetwizard/customwidgetwizard.h" #include "profileeditorfactory.h" +#include "profilehoverhandler.h" #include "qt4projectmanagerconstants.h" #include "qt4project.h" #include "profileeditor.h" @@ -159,6 +160,7 @@ bool Qt4ProjectManagerPlugin::initialize(const QStringList &arguments, QString * addAutoReleasedObject(new WinCeQtVersionFactory); addAutoReleasedObject(new ProFileCompletionAssistProvider); + addAutoReleasedObject(new ProFileHoverHandler(this)); // TODO reenable //m_embeddedPropertiesPage = new EmbeddedPropertiesPage; diff --git a/src/plugins/texteditor/basehoverhandler.cpp b/src/plugins/texteditor/basehoverhandler.cpp index 0a41dced8d..ae18e63b3b 100644 --- a/src/plugins/texteditor/basehoverhandler.cpp +++ b/src/plugins/texteditor/basehoverhandler.cpp @@ -157,8 +157,8 @@ void BaseHoverHandler::decorateToolTip() if (!contents.isEmpty()) { setToolTip(Qt::escape(toolTip())); appendToolTip(contents); + addF1ToToolTip(); } - addF1ToToolTip(); } } diff --git a/src/plugins/texteditor/basehoverhandler.h b/src/plugins/texteditor/basehoverhandler.h index d2cbeacef1..74c76d3798 100644 --- a/src/plugins/texteditor/basehoverhandler.h +++ b/src/plugins/texteditor/basehoverhandler.h @@ -61,8 +61,6 @@ public: private slots: void editorOpened(Core::IEditor *editor); - -public slots: void showToolTip(TextEditor::ITextEditor *editor, const QPoint &point, int pos); void updateContextHelpId(TextEditor::ITextEditor *editor, int pos); diff --git a/src/plugins/texteditor/helpitem.cpp b/src/plugins/texteditor/helpitem.cpp index af20367bf1..022d2eb59c 100644 --- a/src/plugins/texteditor/helpitem.cpp +++ b/src/plugins/texteditor/helpitem.cpp @@ -77,6 +77,8 @@ bool HelpItem::isValid() const { if (!Core::HelpManager::instance()->linksForIdentifier(m_helpId).isEmpty()) return true; + if (QUrl(m_helpId).isValid()) + return true; return false; } @@ -90,6 +92,12 @@ QString HelpItem::extractContent(bool extended) const QString contents; QMap<QString, QUrl> helpLinks = Core::HelpManager::instance()->linksForIdentifier(m_helpId); + if (helpLinks.isEmpty()) { + // Maybe this is already an URL... + QUrl url(m_helpId); + if (url.isValid()) + helpLinks.insert(m_helpId, m_helpId); + } foreach (const QUrl &url, helpLinks) { const QByteArray &html = Core::HelpManager::instance()->fileData(url); switch (m_category) { @@ -117,6 +125,9 @@ QString HelpItem::extractContent(bool extended) const case QmlProperty: contents = htmlExtractor.getQmlPropertyDescription(html, m_docMark); break; + case QMakeVariableOfFunction: + contents = htmlExtractor.getQMakeVariableOrFunctionDescription(html, m_docMark); + break; default: break; diff --git a/src/plugins/texteditor/helpitem.h b/src/plugins/texteditor/helpitem.h index 0be6b7dc95..9f034165cf 100644 --- a/src/plugins/texteditor/helpitem.h +++ b/src/plugins/texteditor/helpitem.h @@ -51,6 +51,7 @@ public: Function, QmlComponent, QmlProperty, + QMakeVariableOfFunction, Unknown }; |