Moved the CppHoverHandler to the CppEditor plugin

It used to be in CppTools, but since the hover handler only makes sense
in the context of the C++ editor, this is a better place.
This commit is contained in:
Thorbjørn Lindeijer
2008-12-16 12:22:08 +01:00
parent 24e6d15879
commit 1efe71992b
12 changed files with 65 additions and 45 deletions

View File

@@ -1,270 +0,0 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file. Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception
** version 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#include "cpphoverhandler.h"
#include "cppmodelmanager.h"
#include <coreplugin/icore.h>
#include <coreplugin/uniqueidmanager.h>
#include <texteditor/itexteditor.h>
#include <texteditor/basetexteditor.h>
#include <debugger/debuggerconstants.h>
#include <CoreTypes.h>
#include <FullySpecifiedType.h>
#include <Literals.h>
#include <Names.h>
#include <Scope.h>
#include <Symbol.h>
#include <Symbols.h>
#include <cplusplus/ExpressionUnderCursor.h>
#include <cplusplus/Overview.h>
#include <cplusplus/TypeOfExpression.h>
#include <QtGui/QToolTip>
#include <QtGui/QTextCursor>
#include <QtGui/QTextBlock>
#include <QtHelp/QHelpEngineCore>
#include <QtCore/QtCore>
using namespace CppTools::Internal;
using namespace CPlusPlus;
CppHoverHandler::CppHoverHandler(CppModelManager *manager, QObject *parent)
: QObject(parent), m_manager(manager), m_helpEngineNeedsSetup(false)
{
QFileInfo fi(ExtensionSystem::PluginManager::instance()->getObject<Core::ICore>()->settings()->fileName());
m_helpEngine = new QHelpEngineCore(fi.absolutePath()
+ QLatin1String("/helpcollection.qhc"), this);
//m_helpEngine->setAutoSaveFilter(false);
m_helpEngine->setupData();
m_helpEngine->setCurrentFilter(tr("Unfiltered"));
m_helpEngineNeedsSetup = m_helpEngine->registeredDocumentations().count() == 0;
}
void CppHoverHandler::updateContextHelpId(TextEditor::ITextEditor *editor, int pos)
{
updateHelpIdAndTooltip(editor, pos);
}
void CppHoverHandler::showToolTip(TextEditor::ITextEditor *editor, const QPoint &point, int pos)
{
const int dbgcontext = m_manager->core()->
uniqueIDManager()->uniqueIdentifier(Debugger::Constants::C_GDBDEBUGGER);
if (m_manager->core()->hasContext(dbgcontext))
return;
if (! editor)
return;
updateHelpIdAndTooltip(editor, pos);
if (m_toolTip.isEmpty())
QToolTip::hideText();
else {
const QPoint pnt = point - QPoint(0,
#ifdef Q_WS_WIN
24
#else
16
#endif
);
QToolTip::showText(pnt, m_toolTip);
}
}
static QString buildHelpId(const FullySpecifiedType &type,
const Symbol *symbol)
{
Name *name = 0;
Scope *scope = 0;
if (const Function *f = type->asFunction()) {
name = f->name();
scope = f->scope();
} else if (const Class *c = type->asClass()) {
name = c->name();
scope = c->scope();
} else if (const Enum *e = type->asEnum()) {
name = e->name();
scope = e->scope();
} else if (const NamedType *t = type->asNamedType()) {
name = t->name();
} else if (const Declaration *d = symbol->asDeclaration()) {
if (d->scope() && d->scope()->owner()->isEnum()) {
name = d->name();
scope = d->scope();
}
}
Overview overview;
overview.setShowArgumentNames(false);
overview.setShowReturnTypes(false);
QStringList qualifiedNames;
qualifiedNames.prepend(overview.prettyName(name));
for (; scope; scope = scope->enclosingScope()) {
if (scope->owner() && scope->owner()->name() && !scope->isEnumScope()) {
Name *name = scope->owner()->name();
Identifier *id = 0;
if (NameId *nameId = name->asNameId()) {
id = nameId->identifier();
} else if (TemplateNameId *nameId = name->asTemplateNameId()) {
id = nameId->identifier();
}
if (id)
qualifiedNames.prepend(QString::fromLatin1(id->chars(), id->size()));
}
}
return qualifiedNames.join(QLatin1String("::"));
}
void CppHoverHandler::updateHelpIdAndTooltip(TextEditor::ITextEditor *editor, int pos)
{
m_helpId.clear();
m_toolTip.clear();
TextEditor::BaseTextEditor *edit = qobject_cast<TextEditor::BaseTextEditor *>(editor->widget());
if (!edit)
return;
QTextCursor tc(edit->document());
tc.setPosition(pos);
const Snapshot documents = m_manager->snapshot();
const int lineNumber = tc.block().blockNumber() + 1;
const QString fileName = editor->file()->fileName();
Document::Ptr doc = documents.value(fileName);
if (doc) {
foreach (Document::DiagnosticMessage m, doc->diagnosticMessages()) {
if (m.line() == lineNumber) {
m_toolTip = m.text();
break;
}
}
if (m_toolTip.isEmpty()) {
unsigned lineno = tc.blockNumber() + 1;
foreach (const Document::Include &incl, doc->includes()) {
if (lineno == incl.line()) {
m_toolTip = incl.fileName();
break;
}
}
}
}
if (m_toolTip.isEmpty()) {
// Move to the end of a qualified name
bool stop = false;
while (!stop) {
const QChar ch = editor->characterAt(tc.position());
if (ch.isLetterOrNumber() || ch == QLatin1Char('_'))
tc.setPosition(tc.position() + 1);
else if (ch == QLatin1Char(':') && editor->characterAt(tc.position() + 1) == QLatin1Char(':')) {
tc.setPosition(tc.position() + 2);
} else {
stop = true;
}
}
// Fetch the expression's code.
ExpressionUnderCursor expressionUnderCursor;
const QString expression = expressionUnderCursor(tc);
if (doc) {
// Find the last symbol up to the cursor position
int line = 0, column = 0;
editor->convertPosition(tc.position(), &line, &column);
Symbol *lastSymbol = doc->findSymbolAt(line, column);
TypeOfExpression typeOfExpression;
typeOfExpression.setSnapshot(documents);
QList<TypeOfExpression::Result> types = typeOfExpression(expression, doc, lastSymbol);
if (!types.isEmpty()) {
FullySpecifiedType firstType = types.first().first;
FullySpecifiedType docType = firstType;
if (const PointerType *pt = firstType->asPointerType()) {
docType = pt->elementType();
} else if (const ReferenceType *rt = firstType->asReferenceType()) {
docType = rt->elementType();
}
m_helpId = buildHelpId(docType, types.first().second);
QString displayName = buildHelpId(firstType, types.first().second);
if (!firstType->isClass() && !firstType->isNamedType()) {
Overview overview;
overview.setShowArgumentNames(true);
overview.setShowReturnTypes(true);
m_toolTip = overview.prettyType(firstType, displayName);
} else {
m_toolTip = m_helpId;
}
}
}
}
if (doc && m_toolTip.isEmpty()) {
foreach (const Document::MacroUse &use, doc->macroUses()) {
if (use.contains(pos)) {
m_toolTip = use.macro().toString();
m_helpId = use.macro().name;
break;
}
}
}
if (m_helpEngineNeedsSetup
&& m_helpEngine->registeredDocumentations().count() > 0) {
m_helpEngine->setupData();
m_helpEngineNeedsSetup = false;
}
if (!m_helpId.isEmpty() && !m_helpEngine->linksForIdentifier(m_helpId).isEmpty()) {
m_toolTip = QString(QLatin1String("<table><tr><td valign=middle><nobr>%1</td>"
"<td><img src=\":/cpptools/images/f1.svg\"></td></tr></table>"))
.arg(Qt::escape(m_toolTip));
editor->setContextHelpId(m_helpId);
} else if (!m_toolTip.isEmpty()) {
m_toolTip = QString(QLatin1String("<nobr>%1")).arg(Qt::escape(m_toolTip));
}
}

View File

@@ -1,77 +0,0 @@
/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the packaging
** of this file. Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception
** version 1.2, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/
#ifndef CPPHOVERHANDLER_H
#define CPPHOVERHANDLER_H
#include <QtCore/QObject>
#include <QtCore/QPoint>
QT_BEGIN_NAMESPACE
class QHelpEngineCore;
QT_END_NAMESPACE
namespace TextEditor {
class ITextEditor;
}
namespace CppTools {
namespace Internal {
class CppModelManager;
class CppHoverHandler : public QObject
{
Q_OBJECT
public:
CppHoverHandler(CppModelManager *manager, QObject *parent);
public slots:
void showToolTip(TextEditor::ITextEditor *editor, const QPoint &point, int pos);
void updateContextHelpId(TextEditor::ITextEditor *editor, int pos);
private:
void updateHelpIdAndTooltip(TextEditor::ITextEditor *editor, int pos);
CppModelManager *m_manager;
QHelpEngineCore *m_helpEngine;
QString m_helpId;
QString m_toolTip;
bool m_helpEngineNeedsSetup;
};
} // namespace Internal
} // namespace CppTools
#endif // CPPHOVERHANDLER_H

View File

@@ -34,7 +34,6 @@
#include <cplusplus/pp.h>
#include "cppmodelmanager.h"
#include "cpphoverhandler.h"
#include "cpptoolsconstants.h"
#include "cpptoolseditorsupport.h"
@@ -464,8 +463,6 @@ CppModelManager::CppModelManager(QObject *parent) :
connect(this, SIGNAL(documentUpdated(CPlusPlus::Document::Ptr)),
this, SLOT(onDocumentUpdated(CPlusPlus::Document::Ptr)));
m_hoverHandler = new CppHoverHandler(this, this);
// Listen for editor closed and opened events so that we can keep track of changing files
connect(m_core->editorManager(), SIGNAL(editorOpened(Core::IEditor *)),
this, SLOT(editorOpened(Core::IEditor *)));
@@ -633,14 +630,6 @@ void CppModelManager::editorOpened(Core::IEditor *editor)
CppEditorSupport *editorSupport = new CppEditorSupport(this);
editorSupport->setTextEditor(textEditor);
m_editorSupport[textEditor] = editorSupport;
// ### move in CppEditorSupport
connect(editor, SIGNAL(tooltipRequested(TextEditor::ITextEditor*, QPoint, int)),
m_hoverHandler, SLOT(showToolTip(TextEditor::ITextEditor*, QPoint, int)));
// ### move in CppEditorSupport
connect(editor, SIGNAL(contextHelpIdRequested(TextEditor::ITextEditor*, int)),
m_hoverHandler, SLOT(updateContextHelpId(TextEditor::ITextEditor*, int)));
}
}

View File

@@ -60,7 +60,6 @@ namespace Internal {
class CppEditorSupport;
class CppPreprocessor;
class CppHoverHandler;
class CppModelManager : public CppModelManagerInterface
{
@@ -144,7 +143,6 @@ private:
private:
Core::ICore *m_core;
ProjectExplorer::ProjectExplorerPlugin *m_projectExplorer;
CppHoverHandler *m_hoverHandler;
CPlusPlus::Snapshot m_snapshot;
// cache

View File

@@ -25,14 +25,11 @@ SOURCES += cppquickopenfilter.cpp \
# Input
SOURCES += cpptoolsplugin.cpp \
cppmodelmanager.cpp \
cppcodecompletion.cpp \
cpphoverhandler.cpp
cppcodecompletion.cpp
HEADERS += cpptoolsplugin.h \
cppmodelmanager.h \
cppcodecompletion.h \
cpphoverhandler.h \
cppmodelmanagerinterface.h \
cpptoolseditorsupport.h \
cpptoolsconstants.h
RESOURCES += cpptools.qrc
FORMS += completionsettingspage.ui

View File

@@ -1,5 +0,0 @@
<RCC>
<qresource prefix="/cpptools" >
<file>images/f1.svg</file>
</qresource>
</RCC>

View File

@@ -40,7 +40,6 @@
QT_BEGIN_NAMESPACE
class QTimer;
class QByteArray;
QT_END_NAMESPACE
namespace TextEditor {

View File

@@ -37,7 +37,6 @@
#include "cppclassesfilter.h"
#include "cppcodecompletion.h"
#include "cppfunctionsfilter.h"
#include "cpphoverhandler.h"
#include "cppmodelmanager.h"
#include "cpptoolsconstants.h"
#include "cppquickopenfilter.h"

View File

@@ -1,175 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="24"
height="24"
id="svg2411"
sodipodi:version="0.32"
inkscape:version="0.46"
version="1.0"
sodipodi:docname="f1.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape">
<defs
id="defs2413">
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient001"
id="linearGradient3201"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(3.6285394,0,0,3.6290105,-1258.7023,-359.38242)"
spreadMethod="pad"
x1="375.31006"
y1="88.869247"
x2="466.8873"
y2="180.4346" />
<linearGradient
id="linearGradient001">
<stop
id="stop608"
offset="0.000000"
style="stop-color:#cfcfcf;stop-opacity:1;" />
<stop
id="stop609"
offset="1.000000"
style="stop-color:#efefef;stop-opacity:1;" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient001"
id="linearGradient3207"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(3.8401167,0,0,3.8424815,-1348.031,-388.46373)"
spreadMethod="pad"
x1="470.3931"
y1="136.23064"
x2="374.90988"
y2="136.23064" />
<linearGradient
id="linearGradient002">
<stop
id="stop566"
offset="0.000000"
style="stop-color:#9d9d9f;stop-opacity:1;" />
<stop
id="stop567"
offset="1.000000"
style="stop-color:#e5e5e5;stop-opacity:1;" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient002"
id="linearGradient2419"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(3.6611924,0,0,3.6628816,-1231.7325,-383.72165)"
spreadMethod="pad"
x1="471.00525"
y1="201.05208"
x2="348.94803"
y2="79.051147" />
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 526.18109 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="744.09448 : 526.18109 : 1"
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
id="perspective2419" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="11.2"
inkscape:cx="22.801892"
inkscape:cy="10.456883"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="963"
inkscape:window-height="667"
inkscape:window-x="207"
inkscape:window-y="207" />
<metadata
id="metadata2416">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Ebene 1"
inkscape:groupmode="layer"
id="layer1">
<g
transform="matrix(4.3636364e-2,0,0,4.3636364e-2,0,6.1090908)"
id="g2404">
<rect
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
y="-140"
x="2.4832567e-14"
width="550"
style="font-size:12px;fill:#b0b0b0;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.81658993pt;stroke-opacity:1"
ry="81.511414"
id="rect621"
height="550" />
<rect
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="c:\Documents and Settings\aportale\Desktop\rect621.png"
y="-128.55069"
x="11.458333"
width="527.08331"
style="font-size:12px;fill:url(#linearGradient2419);fill-rule:evenodd;stroke:none;stroke-width:1.03125;stroke-miterlimit:4;stroke-dasharray:none"
ry="78.116447"
id="rect2417"
height="527.09235" />
<rect
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="c:\Documents and Settings\aportale\Desktop\rect621.png"
y="-71.25"
x="68.950378"
width="412.29962"
style="font-size:12px;fill:url(#linearGradient3207);fill-rule:evenodd;stroke:none;stroke-width:2.4979167;stroke-miterlimit:4;stroke-dasharray:none"
ry="39.785442"
rx="34.514793"
id="rect3205"
height="412.5" />
<rect
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="c:\Documents and Settings\aportale\Desktop\rect621.png"
y="-59.791668"
x="80.208336"
width="389.58334"
style="font-size:12px;fill:url(#linearGradient3201);fill-rule:evenodd;stroke:none;stroke-width:25.41458321;stroke-miterlimit:4;stroke-dasharray:none"
ry="25.400656"
rx="22.902761"
id="rect3199"
height="389.58334" />
<path
sodipodi:nodetypes="ccccccccccccccccsccc"
inkscape:export-ydpi="90"
inkscape:export-xdpi="90"
inkscape:export-filename="c:\Documents and Settings\aportale\Desktop\rect621.png"
id="text3219"
d="M 137.5,157.91667 L 137.5,-2.4752517 L 229.16667,-2.5 L 229.16667,20.416667 L 160.41667,20.416667 L 160.41667,66.25 L 206.25,66.25 L 206.25,89.166667 L 160.41667,89.166667 L 160.41667,157.91667 L 137.5,157.91667 z M 320.89291,157.91667 L 297.91667,157.91667 L 297.91667,40.04211 C 284.08134,48.574912 275.21133,59.2993 252.08333,66.25 L 252.08333,47.355939 C 263.04835,44.807707 286.00818,25.67917 293.48823,18.312241 C 300.9682,10.945593 306.26379,4.4293192 309.375,-2.5 L 320.83333,-2.5 L 320.89291,157.91667 z"
style="font-size:261.65481567px;font-style:normal;font-weight:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans" />
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 6.4 KiB