logic: extended CodeView to show locations of edges to the active Token and merge overlapping snippets

This commit is contained in:
Eberhard Graether
2014-07-26 23:07:47 +02:00
parent eeacb92b55
commit 16d49e58cc
18 changed files with 173 additions and 42 deletions
+5 -2
View File
@@ -36,10 +36,13 @@ const std::string& QtCodeFile::getFileName() const
}
void QtCodeFile::addCodeSnippet(
const std::string& str, const TokenLocationFile& locationFile, int startLineNumber, Id activeTokenId
int startLineNumber,
const std::string& code,
const TokenLocationFile& locationFile,
const std::vector<Id>& activeTokenIds
){
std::shared_ptr<QtCodeSnippet> snippet(
new QtCodeSnippet(m_parentView, str, locationFile, startLineNumber, activeTokenId, this)
new QtCodeSnippet(m_parentView, startLineNumber, code, locationFile, activeTokenIds, this)
);
layout()->addWidget(snippet.get());
m_snippets.push_back(snippet);
+4 -1
View File
@@ -22,7 +22,10 @@ public:
const std::string& getFileName() const;
void addCodeSnippet(
const std::string& str, const TokenLocationFile& locationFile, int startLineNumber, Id activeTokenId
int startLineNumber,
const std::string& code,
const TokenLocationFile& locationFile,
const std::vector<Id>& activeTokenIds
);
private:
+6 -4
View File
@@ -34,16 +34,16 @@ void QtCodeSnippet::LineNumberArea::paintEvent(QPaintEvent *event)
QtCodeSnippet::QtCodeSnippet(
QtCodeView* parentView,
int startLineNumber,
const std::string& code,
const TokenLocationFile& locationFile,
int startLineNumber,
Id activeTokenId,
const std::vector<Id>& activeTokenIds,
QWidget *parent
)
: QPlainTextEdit(parent)
, m_parentView(parentView)
, m_startLineNumber(startLineNumber)
, m_activeTokenId(activeTokenId)
, m_activeTokenIds(activeTokenIds)
, m_digits(0)
{
setObjectName("code_snippet");
@@ -171,7 +171,9 @@ void QtCodeSnippet::annotateText(const TokenLocationFile& locationFile)
m_annotations.push_back(annotation);
Colori color;
if (location->getTokenId() == m_activeTokenId)
const std::vector<Id>& ids = m_activeTokenIds;
bool isActive = std::find(ids.begin(), ids.end(), location->getTokenId()) != ids.end();
if (isActive)
{
color = ApplicationSettings::getInstance()->getCodeActiveLinkColor();
}
+3 -3
View File
@@ -37,10 +37,10 @@ public:
QtCodeSnippet(
QtCodeView* parentView,
int startLineNumber,
const std::string& code,
const TokenLocationFile& locationFile,
int startLineNumber,
Id activeTokenId,
const std::vector<Id>& activeTokenIds,
QWidget *parent = 0
);
virtual ~QtCodeSnippet();
@@ -81,7 +81,7 @@ private:
QWidget *m_lineNumberArea;
const int m_startLineNumber;
const Id m_activeTokenId;
const std::vector<Id> m_activeTokenIds;
int m_digits;
std::vector<Annotation> m_annotations;
+1 -1
View File
@@ -99,7 +99,7 @@ void QtCodeView::doAddCodeSnippet(const CodeSnippetParams params)
m_frame->layout()->addWidget(file);
}
file->addCodeSnippet(params.code, params.locationFile, params.startLineNumber, params.activeTokenId);
file->addCodeSnippet(params.startLineNumber, params.code, params.locationFile, params.activeTokenIds);
}
void QtCodeView::doClearCodeSnippets()
+1 -1
View File
@@ -28,7 +28,7 @@ ComponentFactory::~ComponentFactory()
std::shared_ptr<Component> ComponentFactory::createCodeComponent()
{
std::shared_ptr<CodeView> view = m_viewFactory->createCodeView(m_viewLayout);
std::shared_ptr<CodeController> controller = std::make_shared<CodeController>(m_locationAccess);
std::shared_ptr<CodeController> controller = std::make_shared<CodeController>(m_graphAccess, m_locationAccess);
std::shared_ptr<Component> component = std::make_shared<Component>(view, controller);
return component;
+57 -17
View File
@@ -1,15 +1,16 @@
#include "component/controller/CodeController.h"
#include "component/view/CodeView.h"
#include "data/access/GraphAccess.h"
#include "data/access/LocationAccess.h"
#include "data/location/TokenLocation.h"
#include "data/location/TokenLocationCollection.h"
#include "data/location/TokenLocationFile.h"
#include "utility/logging/logging.h"
#include "utility/text/TextAccess.h"
CodeController::CodeController(LocationAccess* locationAccess)
: m_locationAccess(locationAccess)
CodeController::CodeController(GraphAccess* graphAccess, LocationAccess* locationAccess)
: m_graphAccess(graphAccess)
, m_locationAccess(locationAccess)
{
}
@@ -19,23 +20,25 @@ CodeController::~CodeController()
void CodeController::setActiveTokenId(Id id)
{
const unsigned int lineRadius = 2;
const uint lineRadius = 2;
getView()->clearCodeSnippets();
TokenLocationCollection collection = m_locationAccess->getTokenLocationsForTokenId(id);
collection.forEachTokenLocation(
[&](TokenLocation* tokenLocation) -> void
{
if (tokenLocation->isStartTokenLocation())
{
const std::string filePath = tokenLocation->getFilePath();
std::shared_ptr<TextAccess> textAccess = TextAccess::createFromFile(filePath);
std::vector<Id> activeTokenIds = m_graphAccess->getActiveTokenIdsForId(id);
std::vector<Id> locationIds = m_graphAccess->getLocationIdsForTokenIds(activeTokenIds);
unsigned int firstLineNumber = std::max<int>(1, tokenLocation->getLineNumber() - lineRadius);
unsigned int lastLineNumber = std::min<int>(
textAccess->getLineCount(), tokenLocation->getEndTokenLocation()->getLineNumber() + lineRadius
);
TokenLocationCollection collection = m_locationAccess->getTokenLocationsForLocationIds(locationIds);
collection.forEachTokenLocationFile(
[&](TokenLocationFile* file) -> void
{
const std::string filePath = file->getFilePath();
std::shared_ptr<TextAccess> textAccess = TextAccess::createFromFile(filePath);
std::vector<std::pair<uint, uint>> ranges = getSnippetRangesForFile(file, lineRadius);
for (const std::pair<uint, uint>& range: ranges)
{
unsigned int firstLineNumber = std::max<int>(1, range.first - lineRadius);
unsigned int lastLineNumber = std::min<int>(textAccess->getLineCount(), range.second + lineRadius);
CodeView::CodeSnippetParams params;
for (const std::string& line: textAccess->getLines(firstLineNumber, lastLineNumber))
@@ -46,7 +49,7 @@ void CodeController::setActiveTokenId(Id id)
params.startLineNumber = firstLineNumber;
params.locationFile =
m_locationAccess->getTokenLocationsForLinesInFile(filePath, firstLineNumber, lastLineNumber);
params.activeTokenId = id;
params.activeTokenIds = activeTokenIds;
getView()->addCodeSnippet(params);
}
@@ -68,3 +71,40 @@ CodeView* CodeController::getView()
{
return Controller::getView<CodeView>();
}
std::vector<std::pair<uint, uint>> CodeController::getSnippetRangesForFile(
TokenLocationFile* file, const uint lineRadius
) const
{
std::vector<std::pair<uint, uint>> ranges;
uint start = 0;
uint end = 0;
file->forEachTokenLocation(
[&](TokenLocation* location) -> void
{
uint lineNumber = location->getLineNumber();
if (location->isStartTokenLocation())
{
if (!start)
{
start = lineNumber;
}
else if (end && lineNumber > end + 2 * lineRadius + 1)
{
ranges.push_back(std::make_pair(uint(start), uint(end)));
start = lineNumber;
end = 0;
}
}
else
{
end = lineNumber;
}
}
);
ranges.push_back(std::make_pair(uint(start), uint(end)));
return ranges;
}
@@ -10,7 +10,9 @@
#include "utility/types.h"
class CodeView;
class GraphAccess;
class LocationAccess;
class TokenLocationFile;
struct AnnotatedText
{
@@ -24,7 +26,7 @@ class CodeController
, public MessageListener<MessageRefresh>
{
public:
CodeController(LocationAccess* locationAccess);
CodeController(GraphAccess* graphAccess, LocationAccess* locationAccess);
~CodeController();
void setActiveTokenId(Id id);
@@ -32,8 +34,12 @@ public:
private:
virtual void handleMessage(MessageActivateToken* message);
virtual void handleMessage(MessageRefresh* message);
CodeView* getView();
std::vector<std::pair<uint, uint>> getSnippetRangesForFile(TokenLocationFile* file, const uint lineRadius) const;
GraphAccess* m_graphAccess;
LocationAccess* m_locationAccess;
};
+2 -2
View File
@@ -14,10 +14,10 @@ public:
{
CodeSnippetParams();
int startLineNumber;
std::string code;
TokenLocationFile locationFile;
int startLineNumber;
Id activeTokenId;
std::vector<Id> activeTokenIds;
};
CodeView(ViewLayout* viewLayout);
+50 -5
View File
@@ -387,17 +387,62 @@ bool Storage::checkTokenIsNode(const Id id) const
return false;
}
TokenLocationCollection Storage::getTokenLocationsForTokenId(Id id) const
std::vector<Id> Storage::getActiveTokenIdsForId(Id tokenId) const
{
TokenLocationCollection ret;
Token* token = m_graph.getTokenById(id);
std::vector<Id> ret;
Token* token = m_graph.getTokenById(tokenId);
if (!token)
{
return ret;
}
std::vector<Id> locationIds = token->getLocationIds();
Node* node;
if (token->isEdge())
{
node = dynamic_cast<Edge*>(token)->getTo();
}
else
{
node = dynamic_cast<Node*>(token);
}
ret.push_back(node->getId());
node->forEachEdge(
[&node, &ret](Edge* e)
{
if (e->getTo() == node)
{
ret.push_back(e->getId());
}
}
);
return ret;
}
std::vector<Id> Storage::getLocationIdsForTokenIds(const std::vector<Id>& tokenIds) const
{
std::vector<Id> ret;
for (Id tokenId : tokenIds)
{
Token* token = m_graph.getTokenById(tokenId);
if (!token)
{
continue;
}
ret.insert(ret.end(), token->getLocationIds().begin(), token->getLocationIds().end());
}
return ret;
}
TokenLocationCollection Storage::getTokenLocationsForLocationIds(const std::vector<Id>& locationIds) const
{
TokenLocationCollection ret;
for (Id locationId: locationIds)
{
TokenLocation* location = m_locationCollection.findTokenLocationById(locationId);
+4 -1
View File
@@ -81,8 +81,11 @@ public:
virtual bool checkTokenIsNode(const Id id) const;
virtual std::vector<Id> getActiveTokenIdsForId(Id tokenId) const;
virtual std::vector<Id> getLocationIdsForTokenIds(const std::vector<Id>& tokenIds) const;
// LocationAccess implementation
virtual TokenLocationCollection getTokenLocationsForTokenId(Id locationId) const;
virtual TokenLocationCollection getTokenLocationsForLocationIds(const std::vector<Id>& locationIds) const;
virtual TokenLocationFile getTokenLocationsForLinesInFile(
const std::string& fileName, unsigned int firstLineNumber, unsigned int lastLineNumber
) const;
+3
View File
@@ -30,6 +30,9 @@ public:
virtual std::pair<Id, Id> getNodesOfEdge(const Id id) const = 0;
virtual bool checkTokenIsNode(const Id id) const = 0;
virtual std::vector<Id> getActiveTokenIdsForId(Id tokenId) const = 0;
virtual std::vector<Id> getLocationIdsForTokenIds(const std::vector<Id>& tokenIds) const = 0;
};
#endif // GRAPH_ACCESS_H
+20
View File
@@ -166,3 +166,23 @@ bool GraphAccessProxy::checkTokenIsNode(const Id id) const
return false;
}
std::vector<Id> GraphAccessProxy::getActiveTokenIdsForId(Id tokenId) const
{
if (hasSubject())
{
return m_subject->getActiveTokenIdsForId(tokenId);
}
return std::vector<Id>();
}
std::vector<Id> GraphAccessProxy::getLocationIdsForTokenIds(const std::vector<Id>& tokenIds) const
{
if (hasSubject())
{
return m_subject->getLocationIdsForTokenIds(tokenIds);
}
return std::vector<Id>();
}
+3
View File
@@ -30,6 +30,9 @@ public:
virtual bool checkTokenIsNode(const Id id) const;
virtual std::vector<Id> getActiveTokenIdsForId(Id tokenId) const;
virtual std::vector<Id> getLocationIdsForTokenIds(const std::vector<Id>& tokenIds) const;
private:
GraphAccess* m_subject;
};
+2 -1
View File
@@ -2,6 +2,7 @@
#define LOCATION_ACCESS_H
#include <string>
#include <vector>
#include "utility/types.h"
@@ -12,7 +13,7 @@ class LocationAccess
{
public:
virtual ~LocationAccess();
virtual TokenLocationCollection getTokenLocationsForTokenId(Id id) const = 0;
virtual TokenLocationCollection getTokenLocationsForLocationIds(const std::vector<Id>& locationIds) const = 0;
virtual TokenLocationFile getTokenLocationsForLinesInFile(
const std::string& fileName, unsigned int firstLineNumber, unsigned int lastLineNumber
) const = 0;
+2 -2
View File
@@ -29,11 +29,11 @@ void LocationAccessProxy::setSubject(LocationAccess* subject)
m_subject = subject;
}
TokenLocationCollection LocationAccessProxy::getTokenLocationsForTokenId(Id id) const
TokenLocationCollection LocationAccessProxy::getTokenLocationsForLocationIds(const std::vector<Id>& locationIds) const
{
if (hasSubject())
{
return m_subject->getTokenLocationsForTokenId(id);
return m_subject->getTokenLocationsForLocationIds(locationIds);
}
return TokenLocationCollection();
+1 -1
View File
@@ -13,7 +13,7 @@ public:
void setSubject(LocationAccess* subject);
// LocationAccess implementation
virtual TokenLocationCollection getTokenLocationsForTokenId(Id id) const;
virtual TokenLocationCollection getTokenLocationsForLocationIds(const std::vector<Id>& locationIds) const;
virtual TokenLocationFile getTokenLocationsForLinesInFile(
const std::string& fileName, unsigned int firstLineNumber, unsigned int lastLineNumber
) const;
+2
View File
@@ -3,4 +3,6 @@
typedef unsigned long Id;
typedef unsigned int uint;
#endif // TYPES_H