summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJarek Kobus <jaroslaw.kobus@nokia.com>2011-11-10 11:55:05 +0100
committerJarek Kobus <jaroslaw.kobus@nokia.com>2011-11-10 16:55:11 +0100
commitda14d8610497ea5a272fae715efa18fc8643b9d7 (patch)
tree99c3b8189404d6405e7162c6edcadb904372055e /src
parent8fcb4d808415eab5f9b02fa448b03dff60191d9a (diff)
downloadqt-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.cpp51
-rw-r--r--src/libs/utils/htmldocextractor.h4
-rw-r--r--src/plugins/help/helpplugin.cpp6
-rw-r--r--src/plugins/qt4projectmanager/profilehoverhandler.cpp170
-rw-r--r--src/plugins/qt4projectmanager/profilehoverhandler.h87
-rw-r--r--src/plugins/qt4projectmanager/qt4projectmanager.pro2
-rw-r--r--src/plugins/qt4projectmanager/qt4projectmanagerplugin.cpp2
-rw-r--r--src/plugins/texteditor/basehoverhandler.cpp2
-rw-r--r--src/plugins/texteditor/basehoverhandler.h2
-rw-r--r--src/plugins/texteditor/helpitem.cpp11
-rw-r--r--src/plugins/texteditor/helpitem.h1
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
};