ui: improved code snippet location clicks
* activate token of most nested location * show parts of locations with start or end outside of snippet * (fix for multiple parsing of function and method bodies)
This commit is contained in:
@@ -139,26 +139,37 @@ void QtCodeSnippet::annotateText(const TokenLocationFile& locationFile)
|
||||
{
|
||||
QList<QTextEdit::ExtraSelection> extraSelections;
|
||||
|
||||
for (const TokenLocationFile::TokenLocationLinePairType& lineItem : locationFile.getTokenLocationLines())
|
||||
{
|
||||
for (const TokenLocationLine::TokenLocationPairType& locationItem : lineItem.second->getTokenLocations())
|
||||
locationFile.forEachTokenLocation(
|
||||
[&](TokenLocation* location)
|
||||
{
|
||||
TokenLocation* location = locationItem.second.get();
|
||||
if (!location->isStartTokenLocation())
|
||||
if (location->isEndTokenLocation() && location->getStartTokenLocation())
|
||||
{
|
||||
continue;
|
||||
return;
|
||||
}
|
||||
|
||||
Annotation annotation;
|
||||
annotation.start = toTextEditPosition(location->getLineNumber(), location->getColumnNumber() - 1);
|
||||
annotation.end = toTextEditPosition(
|
||||
location->getEndTokenLocation()->getLineNumber(),
|
||||
location->getEndTokenLocation()->getColumnNumber());
|
||||
if (location->isStartTokenLocation())
|
||||
{
|
||||
annotation.start = toTextEditPosition(location->getLineNumber(), location->getColumnNumber() - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
annotation.start = startTextEditPosition();
|
||||
}
|
||||
|
||||
TokenLocation* endLocation = location->getEndTokenLocation();
|
||||
if (endLocation)
|
||||
{
|
||||
annotation.end = toTextEditPosition(endLocation->getLineNumber(), endLocation->getColumnNumber());
|
||||
}
|
||||
else
|
||||
{
|
||||
annotation.end = endTextEditPosition();
|
||||
}
|
||||
|
||||
annotation.tokenId = location->getTokenId();
|
||||
m_annotations.push_back(annotation);
|
||||
|
||||
QTextEdit::ExtraSelection selection;
|
||||
|
||||
Colori color;
|
||||
if (location->getTokenId() == m_activeTokenId)
|
||||
{
|
||||
@@ -169,6 +180,7 @@ void QtCodeSnippet::annotateText(const TokenLocationFile& locationFile)
|
||||
color = ApplicationSettings::getInstance()->getCodeLinkColor();
|
||||
}
|
||||
|
||||
QTextEdit::ExtraSelection selection;
|
||||
selection.format.setBackground(QColor(color.r, color.g, color.b, color.a));
|
||||
|
||||
selection.cursor = textCursor();
|
||||
@@ -178,7 +190,7 @@ void QtCodeSnippet::annotateText(const TokenLocationFile& locationFile)
|
||||
|
||||
extraSelections.append(selection);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
setExtraSelections(extraSelections);
|
||||
}
|
||||
@@ -216,14 +228,26 @@ void QtCodeSnippet::updateLineNumberArea(const QRect &rect, int dy)
|
||||
void QtCodeSnippet::clickTokenLocation()
|
||||
{
|
||||
int clickPosition = textCursor().position();
|
||||
int diff = endTextEditPosition() + 1;
|
||||
Id tokenId = 0;
|
||||
|
||||
for (Annotation annotation : m_annotations)
|
||||
{
|
||||
if (clickPosition >= annotation.start && clickPosition <= annotation.end)
|
||||
{
|
||||
m_parentView->activateToken(annotation.tokenId);
|
||||
return;
|
||||
int d = annotation.end - annotation.start;
|
||||
if (d < diff)
|
||||
{
|
||||
diff = d;
|
||||
tokenId = annotation.tokenId;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (tokenId)
|
||||
{
|
||||
m_parentView->activateToken(tokenId);
|
||||
}
|
||||
}
|
||||
|
||||
void QtCodeSnippet::clearSelection()
|
||||
@@ -236,13 +260,30 @@ void QtCodeSnippet::clearSelection()
|
||||
int QtCodeSnippet::toTextEditPosition(int lineNumber, int columnNumber) const
|
||||
{
|
||||
lineNumber -= m_startLineNumber - 1;
|
||||
|
||||
int position = 0;
|
||||
|
||||
for (int i = 0; i < lineNumber - 1; i++)
|
||||
{
|
||||
position += document()->findBlockByLineNumber(i).length();
|
||||
}
|
||||
position += columnNumber;
|
||||
|
||||
position += columnNumber;
|
||||
return position;
|
||||
}
|
||||
|
||||
int QtCodeSnippet::startTextEditPosition() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int QtCodeSnippet::endTextEditPosition() const
|
||||
{
|
||||
int position = 0;
|
||||
|
||||
for (int i = 0; i < document()->blockCount(); i++)
|
||||
{
|
||||
position += document()->findBlockByLineNumber(i).length();
|
||||
}
|
||||
|
||||
return position - 1;
|
||||
}
|
||||
|
||||
@@ -70,6 +70,8 @@ private:
|
||||
};
|
||||
|
||||
int toTextEditPosition(int lineNumber, int columnNumber) const;
|
||||
int startTextEditPosition() const;
|
||||
int endTextEditPosition() const;
|
||||
|
||||
QtCodeView* m_parentView;
|
||||
QtHighlighter* m_highlighter;
|
||||
|
||||
@@ -26,31 +26,34 @@ void CodeController::setActiveTokenId(Id id)
|
||||
getView()->clearCodeSnippets();
|
||||
|
||||
TokenLocationCollection collection = m_locationAccess->getTokenLocationsForTokenId(id);
|
||||
collection.forEachTokenLocation([&] (TokenLocation* tokenLocation) -> void {
|
||||
if (tokenLocation->isStartTokenLocation())
|
||||
collection.forEachTokenLocation(
|
||||
[&](TokenLocation* tokenLocation) -> void
|
||||
{
|
||||
CodeView::CodeSnippetParams params;
|
||||
const std::string filePath = tokenLocation->getFilePath();
|
||||
std::shared_ptr<TextAccess> textAccess = TextAccess::createFromFile(filePath);
|
||||
|
||||
unsigned int firstLineNumber = std::max<int>(1, tokenLocation->getLineNumber() - lineRadius);
|
||||
unsigned int lastLineNumber = std::min<int>(
|
||||
textAccess->getLineCount(), tokenLocation->getEndTokenLocation()->getLineNumber() + lineRadius
|
||||
);
|
||||
|
||||
for (std::string line: textAccess->getLines(firstLineNumber, lastLineNumber))
|
||||
if (tokenLocation->isStartTokenLocation())
|
||||
{
|
||||
params.code += line;
|
||||
const std::string filePath = tokenLocation->getFilePath();
|
||||
std::shared_ptr<TextAccess> textAccess = TextAccess::createFromFile(filePath);
|
||||
|
||||
unsigned int firstLineNumber = std::max<int>(1, tokenLocation->getLineNumber() - lineRadius);
|
||||
unsigned int lastLineNumber = std::min<int>(
|
||||
textAccess->getLineCount(), tokenLocation->getEndTokenLocation()->getLineNumber() + lineRadius
|
||||
);
|
||||
|
||||
CodeView::CodeSnippetParams params;
|
||||
for (const std::string& line: textAccess->getLines(firstLineNumber, lastLineNumber))
|
||||
{
|
||||
params.code += line;
|
||||
}
|
||||
|
||||
params.startLineNumber = firstLineNumber;
|
||||
params.locationFile =
|
||||
m_locationAccess->getTokenLocationsForLinesInFile(filePath, firstLineNumber, lastLineNumber);
|
||||
params.activeTokenId = id;
|
||||
|
||||
getView()->addCodeSnippet(params);
|
||||
}
|
||||
|
||||
params.startLineNumber = firstLineNumber;
|
||||
params.locationFile =
|
||||
m_locationAccess->getTokenLocationsForLinesInFile(filePath, firstLineNumber, lastLineNumber);
|
||||
params.activeTokenId = id;
|
||||
|
||||
getView()->addCodeSnippet(params);
|
||||
}
|
||||
});
|
||||
);
|
||||
}
|
||||
|
||||
void CodeController::handleMessage(MessageActivateToken* message)
|
||||
|
||||
+16
-17
@@ -263,26 +263,25 @@ TokenLocationFile Storage::getTokenLocationsForLinesInFile(
|
||||
TokenLocationFile ret(fileName);
|
||||
|
||||
TokenLocationFile* locationFile = m_locationCollection.findTokenLocationFileByPath(fileName);
|
||||
if (locationFile)
|
||||
if (!locationFile)
|
||||
{
|
||||
for (unsigned int i = firstLineNumber; i <= lastLineNumber; i++)
|
||||
return ret;
|
||||
}
|
||||
|
||||
for (unsigned int i = firstLineNumber; i <= lastLineNumber; i++)
|
||||
{
|
||||
TokenLocationLine* locationLine = locationFile->findTokenLocationLineByNumber(i);
|
||||
if (!locationLine)
|
||||
{
|
||||
TokenLocationLine* locationLine = locationFile->findTokenLocationLineByNumber(i);
|
||||
if (locationLine)
|
||||
{
|
||||
locationLine->forEachTokenLocation([&] (TokenLocation* tokenLocation) -> void {
|
||||
if (tokenLocation->getOtherTokenLocation() &&
|
||||
tokenLocation->isStartTokenLocation() &&
|
||||
tokenLocation->getLineNumber() >= firstLineNumber &&
|
||||
tokenLocation->getOtherTokenLocation()->isEndTokenLocation() &&
|
||||
tokenLocation->getOtherTokenLocation()->getLineNumber() <= lastLineNumber)
|
||||
{
|
||||
ret.addTokenLocationAsPlainCopy(tokenLocation);
|
||||
ret.addTokenLocationAsPlainCopy(tokenLocation->getOtherTokenLocation());
|
||||
}
|
||||
});
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
locationLine->forEachTokenLocation(
|
||||
[&](TokenLocation* tokenLocation) -> void
|
||||
{
|
||||
ret.addTokenLocationAsPlainCopy(tokenLocation);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
@@ -141,7 +141,7 @@ bool ASTVisitor::VisitFunctionDecl(clang::FunctionDecl* declaration)
|
||||
getParameters(declaration)
|
||||
);
|
||||
|
||||
if (declaration->hasBody())
|
||||
if (declaration->hasBody() && declaration->isThisDeclarationADefinition())
|
||||
{
|
||||
ASTBodyVisitor bodyVisitor(this, declaration);
|
||||
bodyVisitor.Visit(declaration->getBody());
|
||||
@@ -176,7 +176,7 @@ bool ASTVisitor::VisitCXXMethodDecl(clang::CXXMethodDecl* declaration)
|
||||
declaration->isStatic()
|
||||
);
|
||||
|
||||
if (declaration->hasBody())
|
||||
if (declaration->hasBody() && declaration->isThisDeclarationADefinition())
|
||||
{
|
||||
ASTBodyVisitor bodyVisitor(this, declaration);
|
||||
bodyVisitor.Visit(declaration->getBody());
|
||||
|
||||
Reference in New Issue
Block a user