ui: Show list in tooltip when clicking source location with multiple tokens or local symbols

* Also shows list of all implicit symbols at a source location e.g. default constructors or template specializations
This commit is contained in:
Eberhard Graether
2017-08-02 12:32:13 +02:00
parent 91969770d5
commit 8c5b69dce6
14 changed files with 207 additions and 114 deletions
@@ -1,6 +1,7 @@
#tooltip {
background-color: <color:code/file/background>;
border: 1px solid <color:code/file/background>;
border-bottom: none;
}
#tooltip_title {
@@ -21,6 +22,7 @@
#tooltip_widget {
background-color: <color:code/snippet/background>;
border-bottom: 1px solid <color:code/file/background>;
padding: 3px;
color: <color:code/snippet/syntax/normal>;
}
@@ -32,6 +32,11 @@ void TooltipController::handleMessage(MessageActivateTokens* message)
clear();
}
void TooltipController::handleMessage(MessageActivateLocalSymbols* message)
{
clear();
}
void TooltipController::handleMessage(MessageFocusIn* message)
{
if (!message->tokenIds.size())
@@ -52,6 +57,16 @@ void TooltipController::handleMessage(MessageGraphNodeExpand* message)
clear();
}
void TooltipController::handleMessage(MessageScrollCode* message)
{
clear();
}
void TooltipController::handleMessage(MessageScrollGraph* message)
{
clear();
}
void TooltipController::handleMessage(MessageTooltipHide* message)
{
clear();
@@ -59,7 +74,23 @@ void TooltipController::handleMessage(MessageTooltipHide* message)
void TooltipController::handleMessage(MessageTooltipShow* message)
{
requestTooltipShow(std::vector<Id>(), message->tooltipInfo, message->origin);
if (message->tooltipInfo.title.size())
{
requestTooltipShow(std::vector<Id>(), message->tooltipInfo, message->origin);
}
else
{
TooltipInfo info = m_storageAccess->getTooltipInfoForSourceLocationIdsAndLocalSymbolIds(
message->sourceLocationIds, message->localSymbolIds);
if (info.snippets.size())
{
getView()->showTooltip(info, getViewForOrigin(message->origin));
m_showRequest.reset();
m_hideRequest = false;
}
}
}
void TooltipController::handleMessage(MessageWindowFocus* message)
@@ -4,9 +4,12 @@
#include "component/controller/Controller.h"
#include "utility/messaging/MessageListener.h"
#include "utility/messaging/type/MessageActivateTokens.h"
#include "utility/messaging/type/MessageActivateLocalSymbols.h"
#include "utility/messaging/type/MessageFocusIn.h"
#include "utility/messaging/type/MessageFocusOut.h"
#include "utility/messaging/type/MessageGraphNodeExpand.h"
#include "utility/messaging/type/MessageScrollCode.h"
#include "utility/messaging/type/MessageScrollGraph.h"
#include "utility/messaging/type/MessageTooltipHide.h"
#include "utility/messaging/type/MessageTooltipShow.h"
#include "utility/messaging/type/MessageWindowFocus.h"
@@ -17,9 +20,12 @@ class TooltipView;
class TooltipController
: public Controller
, public MessageListener<MessageActivateTokens>
, public MessageListener<MessageActivateLocalSymbols>
, public MessageListener<MessageFocusIn>
, public MessageListener<MessageFocusOut>
, public MessageListener<MessageGraphNodeExpand>
, public MessageListener<MessageScrollCode>
, public MessageListener<MessageScrollGraph>
, public MessageListener<MessageTooltipHide>
, public MessageListener<MessageTooltipShow>
, public MessageListener<MessageWindowFocus>
@@ -33,9 +39,12 @@ public:
// MessageListener
virtual void handleMessage(MessageActivateTokens* message);
virtual void handleMessage(MessageActivateLocalSymbols* message);
virtual void handleMessage(MessageFocusIn* message);
virtual void handleMessage(MessageFocusOut* message);
virtual void handleMessage(MessageGraphNodeExpand* message);
virtual void handleMessage(MessageScrollCode* message);
virtual void handleMessage(MessageScrollGraph* message);
virtual void handleMessage(MessageTooltipHide* message);
virtual void handleMessage(MessageTooltipShow* message);
virtual void handleMessage(MessageWindowFocus* message);
+2
View File
@@ -97,6 +97,8 @@ public:
virtual std::vector<BookmarkCategory> getAllBookmarkCategories() const = 0;
virtual TooltipInfo getTooltipInfoForTokenIds(const std::vector<Id>& tokenIds, TooltipOrigin origin) const = 0;
virtual TooltipInfo getTooltipInfoForSourceLocationIdsAndLocalSymbolIds(
const std::vector<Id>& locationIds, const std::vector<Id>& localSymbolIds) const = 0;
protected:
ErrorFilter m_errorFilter;
@@ -425,6 +425,17 @@ TooltipInfo StorageAccessProxy::getTooltipInfoForTokenIds(const std::vector<Id>&
return TooltipInfo();
}
TooltipInfo StorageAccessProxy::getTooltipInfoForSourceLocationIdsAndLocalSymbolIds(
const std::vector<Id>& locationIds, const std::vector<Id>& localSymbolIds) const
{
if (hasSubject())
{
return m_subject->getTooltipInfoForSourceLocationIdsAndLocalSymbolIds(locationIds, localSymbolIds);
}
return TooltipInfo();
}
void StorageAccessProxy::setErrorFilter(const ErrorFilter& filter)
{
StorageAccess::setErrorFilter(filter);
+2
View File
@@ -83,6 +83,8 @@ public:
virtual std::vector<BookmarkCategory> getAllBookmarkCategories() const;
virtual TooltipInfo getTooltipInfoForTokenIds(const std::vector<Id>& tokenIds, TooltipOrigin origin) const;
virtual TooltipInfo getTooltipInfoForSourceLocationIdsAndLocalSymbolIds(
const std::vector<Id>& locationIds, const std::vector<Id>& localSymbolIds) const;
protected:
virtual void setErrorFilter(const ErrorFilter& filter);
+9 -2
View File
@@ -71,7 +71,10 @@ SourceLocation* SourceLocationFile::addSourceLocation(
m_locations.insert(start);
m_locations.insert(end);
m_locationIndex.emplace(start->getLocationId(), start.get());
if (start->getLocationId())
{
m_locationIndex.emplace(start->getLocationId(), start.get());
}
return start.get();
}
@@ -96,7 +99,11 @@ SourceLocation* SourceLocationFile::addSourceLocationCopy(const SourceLocation*
std::shared_ptr<SourceLocation> copy = std::make_shared<SourceLocation>(location, this);
m_locations.insert(copy);
m_locationIndex.emplace(copy->getLocationId(), copy.get());
if (copy->getLocationId())
{
m_locationIndex.emplace(copy->getLocationId(), copy.get());
}
// If the old location was added before, then link them with each other.
if (oldLocation)
+58 -27
View File
@@ -1073,43 +1073,22 @@ std::vector<Id> PersistentStorage::getNodeIdsForLocationIds(const std::vector<Id
std::set<Id> edgeIds;
std::set<Id> nodeIds;
std::set<Id> implicitNodeIds;
for (const StorageOccurrence& occurrence: m_sqliteIndexStorage.getOccurrencesForLocationIds(locationIds))
{
const Id elementId = occurrence.elementId;
StorageEdge edge = m_sqliteIndexStorage.getFirstById<StorageEdge>(elementId);
if (edge.id != 0) // here we test if location is an edge.
if (edge.id != 0)
{
edgeIds.insert(edge.targetNodeId);
}
else if(m_sqliteIndexStorage.isNode(elementId))
else if (m_sqliteIndexStorage.isNode(elementId))
{
StorageSymbol symbol = m_sqliteIndexStorage.getFirstById<StorageSymbol>(elementId);
if (symbol.id != 0) // here we test if location is a symbol
{
if (intToDefinitionKind(symbol.definitionKind) == DEFINITION_IMPLICIT)
{
implicitNodeIds.insert(elementId);
}
else
{
nodeIds.insert(elementId);
}
}
else // is file
{
nodeIds.insert(elementId);
}
nodeIds.insert(elementId);
}
}
if (nodeIds.size() == 0)
{
nodeIds = implicitNodeIds;
}
if (nodeIds.size())
{
return utility::toVector(nodeIds);
@@ -1707,7 +1686,6 @@ TooltipSnippet PersistentStorage::getTooltipSnippetForNode(const StorageNode& no
));
}
Id locationId = 1;
std::vector<std::pair<size_t, size_t>> locationRanges;
for (auto p : typeNames)
{
@@ -1734,11 +1712,10 @@ TooltipSnippet PersistentStorage::getTooltipSnippetForNode(const StorageNode& no
if (!inRange)
{
snippet.locationFile->addSourceLocation(
LOCATION_TOKEN, locationId, std::vector<Id>(1, p.second), 1, pos + 1, 1, pos + p.first.size());
LOCATION_TOKEN, 0, std::vector<Id>(1, p.second), 1, pos + 1, 1, pos + p.first.size());
locationRanges.push_back(std::make_pair(pos + 1, pos + p.first.size()));
pos += p.first.size();
locationId++;
}
}
}
@@ -1752,6 +1729,60 @@ TooltipSnippet PersistentStorage::getTooltipSnippetForNode(const StorageNode& no
return snippet;
}
TooltipInfo PersistentStorage::getTooltipInfoForSourceLocationIdsAndLocalSymbolIds(
const std::vector<Id>& locationIds, const std::vector<Id>& localSymbolIds) const
{
TRACE();
TooltipInfo info;
if (!locationIds.size() && !localSymbolIds.size())
{
return info;
}
if (locationIds.size())
{
std::vector<Id> tokenIds = getNodeIdsForLocationIds(locationIds);
for (StorageNode node : m_sqliteIndexStorage.getAllByIds<StorageNode>(tokenIds))
{
TooltipSnippet snippet;
NameHierarchy nameHierarchy = NameHierarchy::deserialize(node.serializedName);
snippet.code = nameHierarchy.getQualifiedName();
snippet.locationFile = std::make_shared<SourceLocationFile>(
FilePath(nameHierarchy.getDelimiter() == NAME_DELIMITER_JAVA ? "main.java" : "main.cpp"), true, true);
snippet.locationFile->addSourceLocation(
LOCATION_TOKEN, 0, std::vector<Id>(1, node.id), 1, 1, 1, snippet.code.size());
if (Node::intToType(node.type) & (Node::NODE_METHOD | Node::NODE_FUNCTION))
{
snippet.code += "()";
}
info.snippets.push_back(snippet);
}
}
for (Id id : localSymbolIds)
{
TooltipSnippet snippet;
snippet.code = "local symbol";
snippet.locationFile = std::make_shared<SourceLocationFile>(FilePath("main.cpp"), true, true);
snippet.locationFile->addSourceLocation(
LOCATION_LOCAL_SYMBOL, 0, std::vector<Id>(1, id), 1, 1, 1, snippet.code.size());
info.snippets.push_back(snippet);
}
info.offset = Vec2i(0, 15);
return info;
}
Id PersistentStorage::getFileNodeId(const FilePath& filePath) const
{
if (filePath.empty())
+2
View File
@@ -138,6 +138,8 @@ public:
virtual TooltipInfo getTooltipInfoForTokenIds(const std::vector<Id>& tokenIds, TooltipOrigin origin) const;
TooltipSnippet getTooltipSnippetForNode(const StorageNode& node) const;
virtual TooltipInfo getTooltipInfoForSourceLocationIdsAndLocalSymbolIds(
const std::vector<Id>& locationIds, const std::vector<Id>& localSymbolIds) const;
private:
Id getFileNodeId(const FilePath& filePath) const;
@@ -17,12 +17,24 @@ public:
setSendAsTask(false);
}
MessageTooltipShow(const std::vector<Id>& sourceLocationIds, const std::vector<Id>& localSymbolIds, TooltipOrigin origin)
: sourceLocationIds(sourceLocationIds)
, localSymbolIds(localSymbolIds)
, origin(origin)
{
setSendAsTask(false);
}
static const std::string getStaticType()
{
return "MessageTooltipShow";
}
const TooltipInfo tooltipInfo;
const std::vector<Id> sourceLocationIds;
const std::vector<Id> localSymbolIds;
const TooltipOrigin origin;
};
+1 -71
View File
@@ -14,8 +14,6 @@
#include "data/location/SourceLocationFile.h"
#include "utility/messaging/type/MessageActivateLocalSymbols.h"
#include "utility/messaging/type/MessageActivateSourceLocations.h"
#include "utility/messaging/type/MessageActivateTokenIds.h"
#include "utility/messaging/type/MessageFocusIn.h"
#include "utility/messaging/type/MessageFocusOut.h"
#include "utility/messaging/type/MessageMoveIDECursor.h"
@@ -364,8 +362,7 @@ void QtCodeArea::mouseReleaseEvent(QMouseEvent* event)
}
else
{
activateSourceLocations(annotations);
activateLocalSymbols(annotations);
activateAnnotations(annotations);
}
}
else if (m_navigator->getActiveLocalSymbolIds().size())
@@ -518,73 +515,6 @@ void QtCodeArea::setIDECursorPosition()
MessageMoveIDECursor(getSourceLocationFile()->getFilePath().str(), lineColumn.first, lineColumn.second).dispatch();
}
void QtCodeArea::activateSourceLocations(const std::vector<const Annotation*>& annotations)
{
std::vector<Id> locationIds;
std::set<Id> tokenIds;
bool allActive = true;
for (const Annotation* annotation : annotations)
{
if (annotation->locationType == LOCATION_TOKEN)
{
if (!annotation->isActive)
{
allActive = false;
}
if (annotation->locationId > 0)
{
locationIds.push_back(annotation->locationId);
}
if (annotation->tokenIds.size())
{
tokenIds.insert(annotation->tokenIds.begin(), annotation->tokenIds.end());
}
}
}
if (!allActive)
{
if (locationIds.size())
{
MessageActivateSourceLocations(locationIds).dispatch();
}
else if (tokenIds.size()) // fallback for links in project description
{
MessageActivateTokenIds(utility::toVector(tokenIds)).dispatch();
}
}
}
void QtCodeArea::activateLocalSymbols(const std::vector<const Annotation*>& annotations)
{
std::vector<Id> localSymbolIds;
bool allActive = true;
for (const Annotation* annotation : annotations)
{
if (annotation->locationType == LOCATION_LOCAL_SYMBOL)
{
if (!annotation->isActive)
{
allActive = false;
}
if (annotation->tokenIds.size())
{
localSymbolIds.insert(localSymbolIds.end(), annotation->tokenIds.begin(), annotation->tokenIds.end());
}
}
}
if (!allActive || localSymbolIds.size())
{
MessageActivateLocalSymbols(localSymbolIds).dispatch();
}
}
void QtCodeArea::activateErrors(const std::vector<const Annotation*>& annotations)
{
std::vector<Id> errorIds;
-2
View File
@@ -100,8 +100,6 @@ private slots:
void setIDECursorPosition();
private:
void activateSourceLocations(const std::vector<const Annotation*>& annotations);
void activateLocalSymbols(const std::vector<const Annotation*>& annotations);
void activateErrors(const std::vector<const Annotation*>& annotations);
void annotateText();
+66 -11
View File
@@ -8,7 +8,10 @@
#include "qt/utility/QtHighlighter.h"
#include "settings/ApplicationSettings.h"
#include "settings/ColorScheme.h"
#include "utility/messaging/type/MessageActivateLocalSymbols.h"
#include "utility/messaging/type/MessageActivateSourceLocations.h"
#include "utility/messaging/type/MessageActivateTokenIds.h"
#include "utility/messaging/type/MessageTooltipShow.h"
#include "utility/utility.h"
std::vector<QtCodeField::AnnotationColor> QtCodeField::s_annotationColors;
@@ -253,16 +256,7 @@ void QtCodeField::mouseReleaseEvent(QMouseEvent* event)
return;
}
std::set<Id> tokenIds;
for (const Annotation* annotation : annotations)
{
tokenIds.insert(annotation->tokenIds.begin(), annotation->tokenIds.end());
}
if (tokenIds.size())
{
MessageActivateTokenIds(utility::toVector(tokenIds)).dispatch();
}
activateAnnotations(annotations);
}
void QtCodeField::focusTokenIds(const std::vector<Id>& tokenIds)
@@ -353,7 +347,7 @@ void QtCodeField::createAnnotations(std::shared_ptr<SourceLocationFile> location
locationFile->forEachSourceLocation(
[&](const SourceLocation* location)
{
if (locationIds.find(location->getLocationId()) != locationIds.end())
if (location->getLocationId() && locationIds.find(location->getLocationId()) != locationIds.end())
{
return;
}
@@ -409,6 +403,67 @@ void QtCodeField::createAnnotations(std::shared_ptr<SourceLocationFile> location
);
}
void QtCodeField::activateAnnotations(const std::vector<const Annotation*>& annotations)
{
std::vector<Id> locationIds;
std::set<Id> tokenIds;
std::set<Id> localSymbolIds;
bool allActive = true;
for (const Annotation* annotation : annotations)
{
if (annotation->locationType == LOCATION_TOKEN)
{
if (!annotation->isActive)
{
allActive = false;
}
if (annotation->locationId > 0)
{
locationIds.push_back(annotation->locationId);
}
if (annotation->tokenIds.size())
{
tokenIds.insert(annotation->tokenIds.begin(), annotation->tokenIds.end());
}
}
else if (annotation->locationType == LOCATION_LOCAL_SYMBOL)
{
if (!annotation->isActive)
{
allActive = false;
}
if (annotation->tokenIds.size())
{
localSymbolIds.insert(annotation->tokenIds.begin(), annotation->tokenIds.end());
}
}
}
if (!allActive)
{
if (tokenIds.size() > 1 || localSymbolIds.size() > 1 || (tokenIds.size() && localSymbolIds.size()))
{
MessageTooltipShow(locationIds, utility::toVector(localSymbolIds), TOOLTIP_ORIGIN_CODE).dispatch();
}
else if (locationIds.size())
{
MessageActivateSourceLocations(locationIds).dispatch();
}
else if (tokenIds.size()) // fallback for links in project description
{
MessageActivateTokenIds(utility::toVector(tokenIds)).dispatch();
}
else if (localSymbolIds.size())
{
MessageActivateLocalSymbols(utility::toVector(localSymbolIds)).dispatch();
}
}
}
int QtCodeField::toTextEditPosition(int lineNumber, int columnNumber) const
{
lineNumber -= m_startLineNumber - 1;
+1
View File
@@ -83,6 +83,7 @@ protected:
const std::set<Id>& activeSymbolIds, const std::set<Id>& activeLocationIds, const std::set<Id>& focusedSymbolIds);
void createAnnotations(std::shared_ptr<SourceLocationFile> locationFile);
void activateAnnotations(const std::vector<const Annotation*>& annotations);
int toTextEditPosition(int lineNumber, int columnNumber) const;
std::pair<int, int> toLineColumn(int textEditPosition) const;