Help: Move resolution of help from multiple candidate IDs to HelpItem

No need for code duplication.

Change-Id: I3d2c795d072b8de5818e1844b8126e526339c0da
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
Eike Ziller
2019-01-28 13:00:03 +01:00
parent 1f4b733cc1
commit 443931c1da
12 changed files with 81 additions and 106 deletions

View File

@@ -258,19 +258,11 @@ void ClangHoverHandler::processToolTipInfo(const CppTools::ToolTipInfo &info)
if (!info.briefComment.isEmpty())
text.append("\n\n" + info.briefComment);
for (const QString &qdocIdCandidate : info.qDocIdCandidates) {
qCDebug(hoverLog) << "Querying help manager with"
<< qdocIdCandidate
<< info.qDocMark
<< helpItemCategoryAsString(info.qDocCategory);
const QMap<QString, QUrl> helpLinks = Core::HelpManager::linksForIdentifier(qdocIdCandidate);
if (!helpLinks.isEmpty()) {
qCDebug(hoverLog) << " Match!";
setLastHelpItemIdentified(
Core::HelpItem(qdocIdCandidate, info.qDocMark, info.qDocCategory, helpLinks));
break;
}
}
qCDebug(hoverLog) << "Querying help manager with"
<< info.qDocIdCandidates
<< info.qDocMark
<< helpItemCategoryAsString(info.qDocCategory);
setLastHelpItemIdentified({info.qDocIdCandidates, info.qDocMark, info.qDocCategory});
if (!info.sizeInBytes.isEmpty())
text.append("\n\n" + tr("%1 bytes").arg(info.sizeInBytes));

View File

@@ -71,7 +71,7 @@ void CMakeEditor::contextHelp(const HelpCallback &callback) const
break;
chr = characterAt(pos);
if (chr == QLatin1Char('(')) {
callback(QString());
callback({});
return;
}
} while (chr.unicode() != QChar::ParagraphSeparator);
@@ -97,12 +97,12 @@ void CMakeEditor::contextHelp(const HelpCallback &callback) const
// Not a command
if (chr != QLatin1Char('(')) {
callback(QString());
callback({});
return;
}
QString command = textAt(begin, end - begin).toLower();
callback(QString("command/" + command));
const QString id = "command/" + textAt(begin, end - begin).toLower();
callback(id);
}
//

View File

@@ -26,6 +26,7 @@
#include "helpitem.h"
#include "helpmanager.h"
#include <utils/algorithm.h>
#include <utils/htmldocextractor.h>
using namespace Core;
@@ -33,11 +34,11 @@ using namespace Core;
HelpItem::HelpItem() = default;
HelpItem::HelpItem(const char *helpId)
: m_helpId(QString::fromUtf8(helpId))
: HelpItem(QStringList(QString::fromUtf8(helpId)), {}, Unknown)
{}
HelpItem::HelpItem(const QString &helpId)
: m_helpId(helpId)
: HelpItem(QStringList(helpId), {}, Unknown)
{}
HelpItem::HelpItem(const QUrl &url)
@@ -60,14 +61,16 @@ HelpItem::HelpItem(const QUrl &url,
, m_helpLinks(helpLinks)
{}
HelpItem::HelpItem(const QString &helpId, const QString &docMark, Category category) :
m_helpId(helpId), m_docMark(docMark), m_category(category)
HelpItem::HelpItem(const QString &helpId, const QString &docMark, Category category)
: HelpItem(QStringList(helpId), docMark, category)
{}
HelpItem::HelpItem(const QString &helpId, const QString &docMark, Category category,
const QMap<QString, QUrl> &helpLinks) :
m_helpId(helpId), m_docMark(docMark), m_category(category), m_helpLinks(helpLinks)
{}
HelpItem::HelpItem(const QStringList &helpIds, const QString &docMark, Category category)
: m_docMark(docMark)
, m_category(category)
{
setHelpIds(helpIds);
}
void HelpItem::setHelpUrl(const QUrl &url)
{
@@ -79,11 +82,16 @@ const QUrl &HelpItem::helpUrl() const
return m_helpUrl;
}
void HelpItem::setHelpId(const QString &id)
{ m_helpId = id; }
void HelpItem::setHelpIds(const QStringList &ids)
{
m_helpIds = Utils::filteredUnique(
Utils::filtered(ids, [](const QString &s) { return !s.isEmpty(); }));
}
const QString &HelpItem::helpId() const
{ return m_helpId; }
const QStringList &HelpItem::helpIds() const
{
return m_helpIds;
}
void HelpItem::setDocMark(const QString &mark)
{ m_docMark = mark; }
@@ -99,7 +107,7 @@ HelpItem::Category HelpItem::category() const
bool HelpItem::isValid() const
{
if (m_helpUrl.isEmpty() && m_helpId.isEmpty())
if (m_helpUrl.isEmpty() && m_helpIds.isEmpty())
return false;
return !links().isEmpty();
}
@@ -157,10 +165,16 @@ QString HelpItem::extractContent(bool extended) const
const QMap<QString, QUrl> &HelpItem::links() const
{
if (!m_helpLinks) {
if (!m_helpUrl.isEmpty())
if (!m_helpUrl.isEmpty()) {
m_helpLinks.emplace(QMap<QString, QUrl>({{m_helpUrl.toString(), m_helpUrl}}));
else
m_helpLinks = Core::HelpManager::linksForIdentifier(m_helpId);
} else {
m_helpLinks.emplace(); // set a value even if there are no help IDs
for (const QString &id : m_helpIds) {
m_helpLinks = Core::HelpManager::linksForIdentifier(id);
if (!m_helpLinks->isEmpty())
break;
}
}
}
return *m_helpLinks;
}

View File

@@ -56,9 +56,8 @@ public:
HelpItem(const char *helpId);
HelpItem(const QString &helpId);
HelpItem(const QString &helpId, const QString &docMark, Category category);
HelpItem(const QString &helpId, const QString &docMark, Category category,
const QMap<QString, QUrl> &helpLinks);
HelpItem(const QUrl &url);
HelpItem(const QStringList &helpIds, const QString &docMark, Category category);
explicit HelpItem(const QUrl &url);
HelpItem(const QUrl &url, const QString &docMark, Category category);
HelpItem(const QUrl &url, const QString &docMark, Category category,
const QMap<QString, QUrl> &helpLinks);
@@ -66,8 +65,8 @@ public:
void setHelpUrl(const QUrl &url);
const QUrl &helpUrl() const;
void setHelpId(const QString &id);
const QString &helpId() const;
void setHelpIds(const QStringList &ids);
const QStringList &helpIds() const;
void setDocMark(const QString &mark);
const QString &docMark() const;
@@ -83,7 +82,7 @@ public:
private:
QUrl m_helpUrl;
QString m_helpId;
QStringList m_helpIds;
QString m_docMark;
Category m_category = Unknown;
mutable Utils::optional<QMap<QString, QUrl>> m_helpLinks; // cached help links

View File

@@ -30,7 +30,6 @@
#include <coreplugin/helpmanager.h>
#include <texteditor/texteditor.h>
#include <utils/optional.h>
#include <utils/textutils.h>
#include <utils/executeondestruction.h>
@@ -61,19 +60,9 @@ void CppHoverHandler::identifyMatch(TextEditorWidget *editorWidget, int pos, Rep
const QSharedPointer<CppElement> &cppElement = evaluator.cppElement();
QStringList candidates = cppElement->helpIdCandidates;
candidates.removeDuplicates();
Utils::optional<HelpItem> helpItem;
foreach (const QString &helpId, candidates) {
if (helpId.isEmpty())
continue;
const QMap<QString, QUrl> helpLinks = HelpManager::linksForIdentifier(helpId);
if (!helpLinks.isEmpty()) {
helpItem.emplace(helpId, cppElement->helpMark, cppElement->helpCategory, helpLinks);
break;
}
}
if (helpItem)
setLastHelpItemIdentified(helpItem.value()); // tool tip appended by decorateToolTip
else
const HelpItem helpItem(candidates, cppElement->helpMark, cppElement->helpCategory);
setLastHelpItemIdentified(helpItem); // tool tip appended by decorateToolTip
if (!helpItem.isValid())
tip += cppElement->tooltip;
}
setToolTip(tip);

View File

@@ -56,7 +56,6 @@ public:
setIcon(QIcon());
setPriority(0);
setId("HelloWorld.HelloWorldMode");
setContextHelp(QString());
}
};

View File

@@ -676,7 +676,7 @@ void HelpPluginPrivate::showContextHelp(const HelpItem &contextHelp)
.arg(HelpPlugin::tr("No Documentation"))
.arg(creatorTheme()->color(Theme::BackgroundColorNormal).name())
.arg(creatorTheme()->color(Theme::TextColorNormal).name())
.arg(contextHelp.helpId())
.arg(contextHelp.helpIds().join(", "))
.arg(HelpPlugin::tr("No documentation available.")));
}
} else {

View File

@@ -666,7 +666,7 @@ void DesignDocument::contextHelp(const Core::IContext::HelpCallback &callback) c
if (view())
view()->contextHelp(callback);
else
callback(QString());
callback({});
}
} // namespace QmlDesigner

View File

@@ -163,7 +163,7 @@ void NavigatorWidget::contextHelp(const Core::IContext::HelpCallback &callback)
if (navigatorView())
navigatorView()->contextHelp(callback);
else
callback(QString());
callback({});
}
void NavigatorWidget::disableNavigator()

View File

@@ -162,7 +162,7 @@ void TextEditorView::qmlJSEditorContextHelp(const Core::IContext::HelpCallback &
if (m_widget->textEditor())
m_widget->textEditor()->contextHelp(callback);
else
callback(QString());
callback({});
}
void TextEditorView::nodeIdChanged(const ModelNode& /*node*/, const QString &/*newId*/, const QString &/*oldId*/)

View File

@@ -559,7 +559,7 @@ void DesignModeWidget::contextHelp(const Core::IContext::HelpCallback &callback)
if (currentDesignDocument())
currentDesignDocument()->contextHelp(callback);
else
callback(QString());
callback({});
}
void DesignModeWidget::initialize()

View File

@@ -147,36 +147,28 @@ bool QmlJSHoverHandler::setQmlTypeHelp(const ScopeChain &scopeChain, const Docum
{
QString moduleName = getModuleName(scopeChain, qmlDocument, value);
QMap<QString, QUrl> urlMap;
QString helpId;
do {
QStringList helpIdPieces(qName);
helpIdPieces.prepend(moduleName);
helpIdPieces.prepend(QLatin1String("QML"));
helpId = helpIdPieces.join(QLatin1Char('.'));
urlMap = HelpManager::linksForIdentifier(helpId);
if (!urlMap.isEmpty())
break;
if (helpIdPieces.size() > 3) {
QString lm = helpIdPieces.value(2);
helpIdPieces.removeAt(2);
helpId = helpIdPieces.join(QLatin1Char('.'));
urlMap = HelpManager::linksForIdentifier(helpId);
if (!urlMap.isEmpty())
break;
helpIdPieces.replace(1, lm);
urlMap = HelpManager::linksForIdentifier(helpId);
if (!urlMap.isEmpty())
break;
}
helpIdPieces.removeAt(1);
helpId = helpIdPieces.join(QLatin1Char('.'));
urlMap = HelpManager::linksForIdentifier(helpId);
if (!urlMap.isEmpty())
break;
return false;
} while (false);
QStringList helpIdCandidates;
QStringList helpIdPieces(qName);
helpIdPieces.prepend(moduleName);
helpIdPieces.prepend("QML");
helpIdCandidates += helpIdPieces.join('.');
if (helpIdPieces.size() > 3) {
QString lm = helpIdPieces.value(2);
helpIdPieces.removeAt(2);
helpIdCandidates += helpIdPieces.join('.');
helpIdPieces.replace(1, lm);
helpIdCandidates += helpIdPieces.join('.');
}
helpIdPieces.removeAt(1);
helpIdCandidates += helpIdPieces.join('.');
const HelpItem helpItem(helpIdCandidates, qName.join('.'), HelpItem::QmlComponent);
const QMap<QString, QUrl> urlMap = helpItem.links();
// Check if the module name contains a major version.
QRegularExpression version("^([^\\d]*)(\\d+)\\.*\\d*$");
@@ -199,7 +191,7 @@ bool QmlJSHoverHandler::setQmlTypeHelp(const ScopeChain &scopeChain, const Docum
return true;
}
}
setLastHelpItemIdentified(HelpItem(helpId, qName.join(QLatin1Char('.')), HelpItem::QmlComponent));
setLastHelpItemIdentified(helpItem);
return true;
}
@@ -500,23 +492,13 @@ bool QmlJSHoverHandler::setQmlHelpItem(const ScopeChain &scopeChain,
const QString className = cur->className();
if (!className.isEmpty()) {
moduleName = getModuleName(scopeChain, qmlDocument, cur);
QString helpId;
do {
helpId = QLatin1String("QML.") + moduleName + QLatin1Char('.') + className
+ QLatin1String("::") + name;
if (!HelpManager::linksForIdentifier(helpId).isEmpty())
break;
helpId = QLatin1String("QML.") + className + QLatin1String("::") + name;
if (!HelpManager::linksForIdentifier(helpId).isEmpty())
break;
helpId = className + QLatin1String("::") + name;
if (!HelpManager::linksForIdentifier(helpId).isEmpty())
break;
helpId.clear();
} while (false);
if (!helpId.isEmpty()) {
setLastHelpItemIdentified(HelpItem(helpId, name, HelpItem::QmlProperty));
const QStringList helpIdCandidates = {"QML." + moduleName + '.' + className
+ "::" + name,
"QML." + className + "::" + name,
className + "::" + name};
const HelpItem helpItem(helpIdCandidates, name, HelpItem::QmlProperty);
if (helpItem.isValid()) {
setLastHelpItemIdentified(helpItem);
return true;
}
}