logic: fixed tooltip text encoding and source locations
also removed duplicate of utilityString from lib
This commit is contained in:
@@ -1769,20 +1769,18 @@ TooltipSnippet PersistentStorage::getTooltipSnippetForNode(const StorageNode& no
|
||||
{
|
||||
TRACE();
|
||||
|
||||
const TextCodec codec(ApplicationSettings::getInstance()->getTextEncoding());
|
||||
|
||||
const NameHierarchy nameHierarchy = NameHierarchy::deserialize(node.serializedName);
|
||||
TooltipSnippet snippet;
|
||||
snippet.code = codec.encode(nameHierarchy.getQualifiedNameWithSignature());
|
||||
snippet.code = nameHierarchy.getQualifiedNameWithSignature();
|
||||
snippet.locationFile = std::make_shared<SourceLocationFile>(
|
||||
FilePath(nameHierarchy.getDelimiter() == NAME_DELIMITER_JAVA ? L"main.java" : L"main.cpp"), true, true);
|
||||
|
||||
if (nameHierarchy.hasSignature())
|
||||
{
|
||||
snippet.code = utility::breakSignature(
|
||||
codec.encode(nameHierarchy.getSignature().getPrefix()),
|
||||
codec.encode(nameHierarchy.getQualifiedName()),
|
||||
codec.encode(nameHierarchy.getSignature().getPostfix()),
|
||||
nameHierarchy.getSignature().getPrefix(),
|
||||
nameHierarchy.getQualifiedName(),
|
||||
nameHierarchy.getSignature().getPostfix(),
|
||||
50,
|
||||
ApplicationSettings::getInstance()->getCodeTabWidth()
|
||||
);
|
||||
@@ -1796,8 +1794,8 @@ TooltipSnippet PersistentStorage::getTooltipSnippetForNode(const StorageNode& no
|
||||
}
|
||||
}
|
||||
|
||||
std::set<std::pair<std::string, Id>, bool(*)(const std::pair<std::string, Id>&, const std::pair<std::string, Id>&)> typeNames(
|
||||
[](const std::pair<std::string, Id>& a, const std::pair<std::string, Id>& b)
|
||||
std::set<std::pair<std::wstring, Id>, bool(*)(const std::pair<std::wstring, Id>&, const std::pair<std::wstring, Id>&)> typeNames(
|
||||
[](const std::pair<std::wstring, Id>& a, const std::pair<std::wstring, Id>& b)
|
||||
{
|
||||
if (a.first.size() == b.first.size())
|
||||
{
|
||||
@@ -1808,11 +1806,11 @@ TooltipSnippet PersistentStorage::getTooltipSnippetForNode(const StorageNode& no
|
||||
}
|
||||
);
|
||||
|
||||
typeNames.insert(std::make_pair(codec.encode(nameHierarchy.getQualifiedName()), node.id));
|
||||
typeNames.insert(std::make_pair(nameHierarchy.getQualifiedName(), node.id));
|
||||
for (const auto& typeNode : m_sqliteIndexStorage.getAllByIds<StorageNode>(typeNodeIds))
|
||||
{
|
||||
typeNames.insert(std::make_pair(
|
||||
codec.encode(NameHierarchy::deserialize(typeNode.serializedName).getQualifiedName()),
|
||||
NameHierarchy::deserialize(typeNode.serializedName).getQualifiedName(),
|
||||
typeNode.id
|
||||
));
|
||||
}
|
||||
@@ -1821,21 +1819,21 @@ TooltipSnippet PersistentStorage::getTooltipSnippetForNode(const StorageNode& no
|
||||
for (const auto& p : typeNames)
|
||||
{
|
||||
size_t pos = 0;
|
||||
while (pos != std::string::npos)
|
||||
while (pos != std::wstring::npos)
|
||||
{
|
||||
pos = snippet.code.find(p.first, pos);
|
||||
if (pos == std::string::npos)
|
||||
if (pos == std::wstring::npos)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
bool inRange = false;
|
||||
for (const auto& p : locationRanges)
|
||||
for (const auto& locationRange : locationRanges)
|
||||
{
|
||||
if (pos + 1 >= p.first && pos + 1 <= p.second)
|
||||
if (pos + 1 >= locationRange.first && pos + 1 <= locationRange.second)
|
||||
{
|
||||
inRange = true;
|
||||
pos = p.second + 1;
|
||||
pos = locationRange.second + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1883,7 +1881,7 @@ TooltipInfo PersistentStorage::getTooltipInfoForSourceLocationIdsAndLocalSymbolI
|
||||
TooltipSnippet snippet;
|
||||
|
||||
const NameHierarchy nameHierarchy = NameHierarchy::deserialize(node.serializedName);
|
||||
snippet.code = codec.encode(nameHierarchy.getQualifiedName());
|
||||
snippet.code = nameHierarchy.getQualifiedName();
|
||||
snippet.locationFile = std::make_shared<SourceLocationFile>(
|
||||
FilePath(nameHierarchy.getDelimiter() == NAME_DELIMITER_JAVA ? L"main.java" : L"main.cpp"), true, true);
|
||||
|
||||
@@ -1892,7 +1890,7 @@ TooltipInfo PersistentStorage::getTooltipInfoForSourceLocationIdsAndLocalSymbolI
|
||||
|
||||
if (NodeType(utility::intToType(node.type)).isCallable())
|
||||
{
|
||||
snippet.code += "()";
|
||||
snippet.code += L"()";
|
||||
}
|
||||
|
||||
info.snippets.push_back(snippet);
|
||||
@@ -1903,7 +1901,7 @@ TooltipInfo PersistentStorage::getTooltipInfoForSourceLocationIdsAndLocalSymbolI
|
||||
{
|
||||
TooltipSnippet snippet;
|
||||
|
||||
snippet.code = "local symbol";
|
||||
snippet.code = L"local symbol";
|
||||
snippet.locationFile = std::make_shared<SourceLocationFile>(FilePath(L"main.cpp"), true, true);
|
||||
snippet.locationFile->addSourceLocation(
|
||||
LOCATION_LOCAL_SYMBOL, 0, std::vector<Id>(1, id), 1, 1, 1, snippet.code.size());
|
||||
|
||||
@@ -10,7 +10,7 @@ class SourceLocationFile;
|
||||
|
||||
struct TooltipSnippet
|
||||
{
|
||||
std::string code;
|
||||
std::wstring code;
|
||||
std::shared_ptr<SourceLocationFile> locationFile;
|
||||
};
|
||||
|
||||
|
||||
@@ -1,477 +0,0 @@
|
||||
#include "utility/utilityString.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cctype>
|
||||
#include <iterator>
|
||||
#include <string>
|
||||
|
||||
#include <boost/locale/encoding_utf.hpp>
|
||||
|
||||
namespace
|
||||
{
|
||||
template <typename StringType>
|
||||
StringType doReplace(StringType str, const StringType& from, const StringType& to)
|
||||
{
|
||||
size_t pos = 0;
|
||||
|
||||
if (from.size() == 0)
|
||||
{
|
||||
return str;
|
||||
}
|
||||
|
||||
while ((pos = str.find(from, pos)) != std::string::npos)
|
||||
{
|
||||
str.replace(pos, from.length(), to);
|
||||
pos += to.length();
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
template <typename StringType>
|
||||
StringType doReplaceBetween(const StringType& str, typename StringType::value_type startDelimiter, typename StringType::value_type endDelimiter, const StringType& to)
|
||||
{
|
||||
size_t startPos = str.find(startDelimiter);
|
||||
if (startPos == StringType::npos)
|
||||
{
|
||||
return str;
|
||||
}
|
||||
|
||||
size_t depth = 1;
|
||||
|
||||
for (size_t pos = startPos + 1; pos < str.size(); pos++)
|
||||
{
|
||||
if (str[pos] == endDelimiter && depth)
|
||||
{
|
||||
depth--;
|
||||
|
||||
if (depth == 0)
|
||||
{
|
||||
StringType end = doReplaceBetween<StringType>(str.substr(pos + 1), startDelimiter, endDelimiter, to);
|
||||
return str.substr(0, startPos) + startDelimiter + to + endDelimiter + end;
|
||||
}
|
||||
}
|
||||
|
||||
if (str[pos] == startDelimiter)
|
||||
{
|
||||
depth++;
|
||||
}
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
}
|
||||
|
||||
namespace utility
|
||||
{
|
||||
std::string encodeToUtf8(const std::wstring& s)
|
||||
{
|
||||
return boost::locale::conv::utf_to_utf<char>(s.c_str(), s.c_str() + s.size());
|
||||
}
|
||||
|
||||
std::wstring decodeFromUtf8(const std::string& s)
|
||||
{
|
||||
return boost::locale::conv::utf_to_utf<wchar_t>(s.c_str(), s.c_str() + s.size());
|
||||
}
|
||||
|
||||
std::deque<std::string> split(const std::string& str, char delimiter)
|
||||
{
|
||||
return split<std::deque<std::string>>(str, std::string(1, delimiter));
|
||||
}
|
||||
|
||||
std::deque<std::string> split(const std::string& str, const std::string& delimiter)
|
||||
{
|
||||
return split<std::deque<std::string>>(str, delimiter);
|
||||
}
|
||||
|
||||
std::vector<std::string> splitToVector(const std::string& str, char delimiter)
|
||||
{
|
||||
return split<std::vector<std::string>>(str, std::string(1, delimiter));
|
||||
}
|
||||
|
||||
std::vector<std::string> splitToVector(const std::string& str, const std::string& delimiter)
|
||||
{
|
||||
return split<std::vector<std::string>>(str, delimiter);
|
||||
}
|
||||
|
||||
std::vector<std::wstring> splitToVector(const std::wstring& str, wchar_t delimiter)
|
||||
{
|
||||
return split<std::vector<std::wstring>>(str, std::wstring(1, delimiter));
|
||||
}
|
||||
|
||||
std::vector<std::wstring> splitToVector(const std::wstring& str, const std::wstring& delimiter)
|
||||
{
|
||||
return split<std::vector<std::wstring>>(str, delimiter);
|
||||
}
|
||||
|
||||
std::string join(const std::deque<std::string>& list, char delimiter)
|
||||
{
|
||||
return join<std::deque<std::string> >(list, std::string(1, delimiter));
|
||||
}
|
||||
|
||||
std::string join(const std::deque<std::string>& list, const std::string& delimiter)
|
||||
{
|
||||
return join<std::deque<std::string> >(list, delimiter);
|
||||
}
|
||||
|
||||
std::string join(const std::vector<std::string>& list, char delimiter)
|
||||
{
|
||||
return join<std::vector<std::string> >(list, std::string(1, delimiter));
|
||||
}
|
||||
|
||||
std::string join(const std::vector<std::string>& list, const std::string& delimiter)
|
||||
{
|
||||
return join<std::vector<std::string> >(list, delimiter);
|
||||
}
|
||||
|
||||
std::deque<std::string> tokenize(const std::string& str, char delimiter)
|
||||
{
|
||||
return tokenize(str, std::string(1, delimiter));
|
||||
}
|
||||
|
||||
std::deque<std::string> tokenize(const std::string& str, const std::string& delimiter)
|
||||
{
|
||||
size_t pos = 0;
|
||||
size_t oldPos = 0;
|
||||
std::deque<std::string> c;
|
||||
|
||||
do
|
||||
{
|
||||
pos = str.find(delimiter, oldPos);
|
||||
|
||||
if (pos != oldPos)
|
||||
{
|
||||
c.push_back(str.substr(oldPos, pos - oldPos));
|
||||
}
|
||||
|
||||
if (pos != std::string::npos)
|
||||
{
|
||||
c.push_back(str.substr(pos, delimiter.size()));
|
||||
}
|
||||
|
||||
oldPos = pos + delimiter.size();
|
||||
}
|
||||
while (pos != std::string::npos && oldPos < str.size());
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
std::deque<std::string> tokenize(const std::deque<std::string>& list, char delimiter)
|
||||
{
|
||||
return tokenize(list, std::string(1, delimiter));
|
||||
}
|
||||
|
||||
std::deque<std::string> tokenize(const std::deque<std::string>& list, const std::string& delimiter)
|
||||
{
|
||||
std::deque<std::string> c;
|
||||
|
||||
for (const std::string& str : list)
|
||||
{
|
||||
if (str.size())
|
||||
{
|
||||
std::deque<std::string> c2 = tokenize(str, delimiter);
|
||||
c.insert(c.end(), c2.begin(), c2.end());
|
||||
}
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
std::string substrBeforeFirst(const std::string& str, char delimiter)
|
||||
{
|
||||
size_t pos = str.find(delimiter);
|
||||
if (pos != std::string::npos)
|
||||
{
|
||||
return str.substr(0, pos);
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
std::string substrBeforeFirst(const std::string& str, const std::string& delimiter)
|
||||
{
|
||||
size_t pos = str.find(delimiter);
|
||||
if (pos != std::string::npos)
|
||||
{
|
||||
return str.substr(0, pos);
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
std::string substrBeforeLast(const std::string& str, char delimiter)
|
||||
{
|
||||
size_t pos = str.rfind(delimiter);
|
||||
if (pos != std::string::npos)
|
||||
{
|
||||
return str.substr(0, pos);
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
std::wstring substrBeforeLast(const std::wstring& str, wchar_t delimiter)
|
||||
{
|
||||
size_t pos = str.rfind(delimiter);
|
||||
if (pos != std::wstring::npos)
|
||||
{
|
||||
return str.substr(0, pos);
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
std::string substrAfter(const std::string& str, char delimiter)
|
||||
{
|
||||
size_t pos = str.find(delimiter);
|
||||
if (pos != std::string::npos)
|
||||
{
|
||||
return str.substr(pos + 1, str.size());
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
std::string substrAfter(const std::string& str, const std::string& delimiter)
|
||||
{
|
||||
size_t pos = str.find(delimiter);
|
||||
if (pos != std::string::npos)
|
||||
{
|
||||
return str.substr(pos + delimiter.size(), str.size());
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
std::string toUpperCase(const std::string& in)
|
||||
{
|
||||
std::string out;
|
||||
std::transform(in.begin(), in.end(), std::back_inserter(out), toupper);
|
||||
return out;
|
||||
}
|
||||
|
||||
std::string toLowerCase(const std::string& in)
|
||||
{
|
||||
std::string out;
|
||||
std::transform(in.begin(), in.end(), std::back_inserter(out), tolower);
|
||||
return out;
|
||||
}
|
||||
|
||||
std::wstring toLowerCase(const std::wstring& in)
|
||||
{
|
||||
std::wstring out;
|
||||
std::transform(in.begin(), in.end(), std::back_inserter(out), tolower);
|
||||
return out;
|
||||
}
|
||||
|
||||
std::string replace(std::string str, const std::string& from, const std::string& to)
|
||||
{
|
||||
return doReplace(str, from, to);
|
||||
}
|
||||
|
||||
std::wstring replace(std::wstring str, const std::wstring& from, const std::wstring& to)
|
||||
{
|
||||
return doReplace(str, from, to);
|
||||
}
|
||||
|
||||
std::string replaceBetween(const std::string& str, char startDelimiter, char endDelimiter, const std::string& to)
|
||||
{
|
||||
return doReplaceBetween<std::string>(str, startDelimiter, endDelimiter, to);
|
||||
}
|
||||
|
||||
std::wstring replaceBetween(const std::wstring& str, wchar_t startDelimiter, wchar_t endDelimiter, const std::wstring& to)
|
||||
{
|
||||
return doReplaceBetween<std::wstring>(str, startDelimiter, endDelimiter, to);
|
||||
}
|
||||
|
||||
std::string insertLineBreaksAtBlankSpaces(const std::string& s, size_t maxLineLength)
|
||||
{
|
||||
const std::vector<std::string> atoms = splitToVector(s, " ");
|
||||
|
||||
std::string ret = "";
|
||||
std::string currentLine = "";
|
||||
for (const std::string& atom: atoms)
|
||||
{
|
||||
if (currentLine.size() + 1 + atom.size() <= maxLineLength)
|
||||
{
|
||||
currentLine += " " + atom;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!ret.empty())
|
||||
{
|
||||
ret += "\n";
|
||||
}
|
||||
|
||||
if (currentLine.empty())
|
||||
{
|
||||
ret += atom;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret += currentLine;
|
||||
currentLine = atom;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!currentLine.empty())
|
||||
{
|
||||
if (!ret.empty())
|
||||
{
|
||||
ret += "\n";
|
||||
}
|
||||
ret += currentLine;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::string breakSignature(
|
||||
std::string returnPart, std::string namePart, std::string paramPart,
|
||||
size_t maxLineLength, size_t tabWidth)
|
||||
{
|
||||
namePart = ' ' + namePart;
|
||||
|
||||
size_t totalSize = returnPart.size() + namePart.size() + paramPart.size();
|
||||
if (totalSize <= maxLineLength)
|
||||
{
|
||||
return returnPart + namePart + paramPart;
|
||||
}
|
||||
|
||||
if (paramPart.size())
|
||||
{
|
||||
namePart += paramPart[0];
|
||||
paramPart.erase(0, 1);
|
||||
}
|
||||
|
||||
size_t parenPos = paramPart.rfind(')');
|
||||
std::string endPart;
|
||||
if (parenPos == 0)
|
||||
{
|
||||
namePart += paramPart;
|
||||
paramPart = "";
|
||||
}
|
||||
else if (parenPos != std::string::npos)
|
||||
{
|
||||
endPart = paramPart.substr(parenPos);
|
||||
paramPart = paramPart.substr(0, parenPos);
|
||||
}
|
||||
|
||||
if (paramPart.size() && paramPart.size() + tabWidth - endPart.size() > maxLineLength)
|
||||
{
|
||||
std::vector<std::string> paramLines;
|
||||
while (true)
|
||||
{
|
||||
size_t parenCount = 0;
|
||||
bool split = false;
|
||||
for (size_t i = 0; i < paramPart.size(); i++)
|
||||
{
|
||||
char c = paramPart[i];
|
||||
if (parenCount == 0 && c == ',')
|
||||
{
|
||||
paramLines.push_back(paramPart.substr(0, i + 1));
|
||||
paramPart = paramPart.substr(i + 2);
|
||||
split = true;
|
||||
break;
|
||||
}
|
||||
else if (c == '<' || c == '(')
|
||||
{
|
||||
parenCount++;
|
||||
}
|
||||
else if (c == '>' || c == ')')
|
||||
{
|
||||
parenCount--;
|
||||
}
|
||||
}
|
||||
|
||||
if (!split)
|
||||
{
|
||||
paramLines.push_back(paramPart);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
paramPart = "";
|
||||
for (const std::string& str : paramLines)
|
||||
{
|
||||
paramPart += "\n\t" + str;
|
||||
size_t length = tabWidth + str.size();
|
||||
maxLineLength = std::max(length, maxLineLength);
|
||||
}
|
||||
}
|
||||
else if (paramPart.size())
|
||||
{
|
||||
paramPart = "\n\t" + paramPart;
|
||||
}
|
||||
|
||||
if (returnPart.size() + namePart.size() <= maxLineLength)
|
||||
{
|
||||
namePart = returnPart + namePart;
|
||||
returnPart = "";
|
||||
}
|
||||
|
||||
std::string sig;
|
||||
|
||||
if (returnPart.size())
|
||||
{
|
||||
sig += returnPart + '\n';
|
||||
}
|
||||
|
||||
sig += namePart;
|
||||
|
||||
if (paramPart.size())
|
||||
{
|
||||
sig += paramPart;
|
||||
}
|
||||
|
||||
if (endPart.size())
|
||||
{
|
||||
sig += '\n' + endPart;
|
||||
}
|
||||
|
||||
return sig;
|
||||
}
|
||||
|
||||
std::string trim(const std::string &str)
|
||||
{
|
||||
auto wsfront = std::find_if_not(str.begin(), str.end(), [](int c) { return std::isspace(c); });
|
||||
auto wsback = std::find_if_not(str.rbegin(), str.rend(), [](int c) { return std::isspace(c); }).base();
|
||||
return (wsback <= wsfront ? std::string() : std::string(wsfront, wsback));
|
||||
}
|
||||
|
||||
std::wstring trim(const std::wstring &str)
|
||||
{
|
||||
auto wsfront = std::find_if_not(str.begin(), str.end(), [](int c) { return std::isspace(c); });
|
||||
auto wsback = std::find_if_not(str.rbegin(), str.rend(), [](int c) { return std::isspace(c); }).base();
|
||||
return (wsback <= wsfront ? std::wstring() : std::wstring(wsfront, wsback));
|
||||
}
|
||||
|
||||
std::string elide(const std::string& str, ElideMode mode, size_t size)
|
||||
{
|
||||
if (str.size() <= size || str.size() <= 3)
|
||||
{
|
||||
return str;
|
||||
}
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case ELIDE_LEFT:
|
||||
return "..." + str.substr(str.size() - size - 3, str.size());
|
||||
case ELIDE_MIDDLE:
|
||||
return str.substr(0, size / 2 - 1) + "..." + str.substr(str.size() - (size / 2 - 2), str.size());
|
||||
case ELIDE_RIGHT:
|
||||
return str.substr(0, size - 3) + "...";
|
||||
}
|
||||
}
|
||||
|
||||
std::wstring elide(const std::wstring& str, ElideMode mode, size_t size)
|
||||
{
|
||||
if (str.size() <= size || str.size() <= 3)
|
||||
{
|
||||
return str;
|
||||
}
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case ELIDE_LEFT:
|
||||
return L"..." + str.substr(str.size() - size - 3, str.size());
|
||||
case ELIDE_MIDDLE:
|
||||
return str.substr(0, size / 2 - 1) + L"..." + str.substr(str.size() - (size / 2 - 2), str.size());
|
||||
case ELIDE_RIGHT:
|
||||
return str.substr(0, size - 3) + L"...";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,206 +0,0 @@
|
||||
#ifndef UTILITY_STRING_H
|
||||
#define UTILITY_STRING_H
|
||||
|
||||
#include <deque>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace utility
|
||||
{
|
||||
std::string encodeToUtf8(const std::wstring& s);
|
||||
std::wstring decodeFromUtf8(const std::string& s);
|
||||
|
||||
template <typename ContainerType>
|
||||
ContainerType split(const std::string& str, const std::string& delimiter);
|
||||
|
||||
template <typename ContainerType>
|
||||
ContainerType split(const std::wstring& str, const std::wstring& delimiter);
|
||||
|
||||
std::deque<std::string> split(const std::string& str, char delimiter);
|
||||
std::deque<std::string> split(const std::string& str, const std::string& delimiter);
|
||||
std::vector<std::string> splitToVector(const std::string& str, char delimiter);
|
||||
std::vector<std::string> splitToVector(const std::string& str, const std::string& delimiter);
|
||||
std::vector<std::wstring> splitToVector(const std::wstring& str, wchar_t delimiter);
|
||||
std::vector<std::wstring> splitToVector(const std::wstring& str, const std::wstring& delimiter);
|
||||
|
||||
template <typename ContainerType>
|
||||
std::string join(const ContainerType& list, const std::string& delimiter);
|
||||
|
||||
template <typename ContainerType>
|
||||
std::wstring join(const ContainerType& list, const std::wstring& delimiter);
|
||||
|
||||
std::string join(const std::deque<std::string>& list, char delimiter);
|
||||
std::string join(const std::deque<std::string>& list, const std::string& delimiter);
|
||||
std::string join(const std::vector<std::string>& list, char delimiter);
|
||||
std::string join(const std::vector<std::string>& list, const std::string& delimiter);
|
||||
|
||||
std::deque<std::string> tokenize(const std::string& str, char delimiter);
|
||||
std::deque<std::string> tokenize(const std::string& str, const std::string& delimiter);
|
||||
std::deque<std::string> tokenize(const std::deque<std::string>& list, char delimiter);
|
||||
std::deque<std::string> tokenize(const std::deque<std::string>& list, const std::string& delimiter);
|
||||
|
||||
std::string substrBeforeFirst(const std::string& str, char delimiter);
|
||||
std::string substrBeforeFirst(const std::string& str, const std::string& delimiter);
|
||||
std::string substrBeforeLast(const std::string& str, char delimiter);
|
||||
std::wstring substrBeforeLast(const std::wstring& str, wchar_t delimiter);
|
||||
std::string substrAfter(const std::string& str, char delimiter);
|
||||
std::string substrAfter(const std::string& str, const std::string& delimiter);
|
||||
|
||||
template <typename StringType>
|
||||
StringType substrBetween(const StringType& str, const StringType& delimiter1, const StringType& delimiter2);
|
||||
|
||||
template <typename StringType>
|
||||
bool isPrefix(const StringType& prefix, const StringType& text);
|
||||
|
||||
template <typename StringType>
|
||||
bool isPostfix(const StringType& postfix, const StringType& text);
|
||||
|
||||
std::string toUpperCase(const std::string& in);
|
||||
std::string toLowerCase(const std::string& in);
|
||||
std::wstring toLowerCase(const std::wstring& in);
|
||||
|
||||
template <typename StringType>
|
||||
bool equalsCaseInsensitive(const std::string& a, const std::string& b);
|
||||
|
||||
std::string replace(std::string str, const std::string& from, const std::string& to);
|
||||
std::wstring replace(std::wstring str, const std::wstring& from, const std::wstring& to);
|
||||
|
||||
std::string replaceBetween(const std::string& str, char startDelimiter, char endDelimiter, const std::string& to);
|
||||
std::wstring replaceBetween(const std::wstring& str, wchar_t startDelimiter, wchar_t endDelimiter, const std::wstring& to);
|
||||
|
||||
std::string insertLineBreaksAtBlankSpaces(const std::string& s, size_t maxLineLength);
|
||||
std::string breakSignature(
|
||||
std::string returnPart, std::string namePart, std::string paramPart,
|
||||
size_t maxLineLength, size_t tabWidth);
|
||||
|
||||
std::string trim(const std::string &str);
|
||||
std::wstring trim(const std::wstring &str);
|
||||
|
||||
enum ElideMode
|
||||
{
|
||||
ELIDE_LEFT,
|
||||
ELIDE_MIDDLE,
|
||||
ELIDE_RIGHT
|
||||
};
|
||||
|
||||
std::string elide(const std::string& str, ElideMode mode, size_t size);
|
||||
std::wstring elide(const std::wstring& str, ElideMode mode, size_t size);
|
||||
|
||||
template <typename ContainerType>
|
||||
ContainerType split(const std::string& str, const std::string& delimiter)
|
||||
{
|
||||
size_t pos = 0;
|
||||
size_t oldPos = 0;
|
||||
ContainerType c;
|
||||
|
||||
do
|
||||
{
|
||||
pos = str.find(delimiter, oldPos);
|
||||
c.push_back(str.substr(oldPos, pos - oldPos));
|
||||
oldPos = pos + delimiter.size();
|
||||
} while (pos != std::string::npos);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
template <typename ContainerType>
|
||||
ContainerType split(const std::wstring& str, const std::wstring& delimiter)
|
||||
{
|
||||
size_t pos = 0;
|
||||
size_t oldPos = 0;
|
||||
ContainerType c;
|
||||
|
||||
do
|
||||
{
|
||||
pos = str.find(delimiter, oldPos);
|
||||
c.push_back(str.substr(oldPos, pos - oldPos));
|
||||
oldPos = pos + delimiter.size();
|
||||
} while (pos != std::wstring::npos);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
template <typename ContainerType>
|
||||
std::string join(const ContainerType& list, const std::string& delimiter)
|
||||
{
|
||||
std::stringstream ss;
|
||||
bool first = true;
|
||||
for (const std::string& str : list)
|
||||
{
|
||||
if (!first)
|
||||
{
|
||||
ss << delimiter;
|
||||
}
|
||||
first = false;
|
||||
|
||||
ss << str;
|
||||
}
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
|
||||
template <typename ContainerType>
|
||||
std::wstring join(const ContainerType& list, const std::wstring& delimiter)
|
||||
{
|
||||
std::wstringstream ss;
|
||||
bool first = true;
|
||||
for (const std::wstring& str : list)
|
||||
{
|
||||
if (!first)
|
||||
{
|
||||
ss << delimiter;
|
||||
}
|
||||
first = false;
|
||||
|
||||
ss << str;
|
||||
}
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
|
||||
template <typename StringType>
|
||||
StringType substrBetween(const StringType& str, const StringType& delimiter1, const StringType& delimiter2)
|
||||
{
|
||||
size_t found_delimiter1 = str.find(delimiter1);
|
||||
found_delimiter1 += delimiter1.length();
|
||||
size_t found_delimiter2 = str.find(delimiter2, found_delimiter1);
|
||||
if (found_delimiter1 != str.npos && found_delimiter2 != str.npos)
|
||||
{
|
||||
return str.substr(found_delimiter1, found_delimiter2 - found_delimiter1);
|
||||
}
|
||||
return StringType();
|
||||
}
|
||||
|
||||
|
||||
template <typename StringType>
|
||||
bool isPrefix(const StringType& prefix, const StringType& text)
|
||||
{
|
||||
if (prefix.size() <= text.size())
|
||||
{
|
||||
std::pair<typename StringType::const_iterator, typename StringType::const_iterator> res =
|
||||
std::mismatch(prefix.begin(), prefix.end(), text.begin());
|
||||
|
||||
return res.first == prefix.end();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename StringType>
|
||||
bool isPostfix(const StringType& postfix, const StringType& text)
|
||||
{
|
||||
return text.size() >= postfix.size() && text.rfind(postfix) == (text.size() - postfix.size());
|
||||
}
|
||||
|
||||
template <typename StringType>
|
||||
bool equalsCaseInsensitive(const StringType& a, const StringType& b)
|
||||
{
|
||||
if (a.size() == b.size())
|
||||
{
|
||||
return toLowerCase(a) == toLowerCase(b);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // UTILITY_STRING_H
|
||||
@@ -27,6 +27,7 @@ QtCodeField::QtCodeField(
|
||||
uint startLineNumber,
|
||||
const std::string& code,
|
||||
std::shared_ptr<SourceLocationFile> locationFile,
|
||||
bool convertLocationsOnDemand,
|
||||
QWidget* parent
|
||||
)
|
||||
: QPlainTextEdit(parent)
|
||||
@@ -50,14 +51,14 @@ QtCodeField::QtCodeField(
|
||||
}
|
||||
|
||||
TextCodec codec(ApplicationSettings::getInstance()->getTextEncoding().c_str());
|
||||
if (codec.isValid())
|
||||
if (convertLocationsOnDemand && codec.isValid())
|
||||
{
|
||||
QString convertedDisplayCode = QString::fromStdWString(codec.decode(displayCode));
|
||||
setPlainText(convertedDisplayCode);
|
||||
if (displayCode.size() != size_t(convertedDisplayCode.length()))
|
||||
{
|
||||
LOG_INFO("Converting displayed code to " + codec.getName() + " resulted in offset of source locations. Correcting this now.");
|
||||
createMultibyteCharacterLocationCache();
|
||||
createMultibyteCharacterLocationCache(convertedDisplayCode);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -651,15 +652,14 @@ void QtCodeField::createLineLengthCache()
|
||||
}
|
||||
}
|
||||
|
||||
void QtCodeField::createMultibyteCharacterLocationCache()
|
||||
void QtCodeField::createMultibyteCharacterLocationCache(const QString& code)
|
||||
{
|
||||
m_multibyteCharacterLocations.clear();
|
||||
QTextCodec* codec = QTextCodec::codecForName(ApplicationSettings::getInstance()->getTextEncoding().c_str());
|
||||
|
||||
for (QTextBlock itLine = document()->begin(); itLine != document()->end(); itLine = itLine.next())
|
||||
for (const QString& line: code.split("\n"))
|
||||
{
|
||||
std::vector<std::pair<int, int>> columnsToOffsets;
|
||||
const QString line = itLine.text();
|
||||
for (int i = 0; i < line.size(); i++)
|
||||
{
|
||||
if (line[i].unicode() > 127)
|
||||
|
||||
@@ -25,7 +25,9 @@ public:
|
||||
uint startLineNumber,
|
||||
const std::string& code,
|
||||
std::shared_ptr<SourceLocationFile> locationFile,
|
||||
QWidget* parent = nullptr);
|
||||
bool convertLocationsOnDemand = true,
|
||||
QWidget* parent = nullptr);
|
||||
|
||||
~QtCodeField();
|
||||
|
||||
virtual QSize sizeHint() const Q_DECL_OVERRIDE;
|
||||
@@ -105,7 +107,7 @@ private:
|
||||
static std::vector<AnnotationColor> s_annotationColors;
|
||||
|
||||
void createLineLengthCache();
|
||||
void createMultibyteCharacterLocationCache();
|
||||
void createMultibyteCharacterLocationCache(const QString& code);
|
||||
int getColumnCorrectedForMultibyteCharacters(int line, int column) const;
|
||||
|
||||
const uint m_startLineNumber;
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
#include "data/location/SourceLocationFile.h"
|
||||
#include "data/tooltip/TooltipInfo.h"
|
||||
#include "qt/element/QtCodeField.h"
|
||||
#include "settings/ApplicationSettings.h"
|
||||
#include "utility/TextCodec.h"
|
||||
|
||||
QtTooltip::QtTooltip(QWidget* parent)
|
||||
: QFrame(parent)
|
||||
@@ -32,14 +34,16 @@ QtTooltip::~QtTooltip()
|
||||
|
||||
void QtTooltip::setTooltipInfo(TooltipInfo info)
|
||||
{
|
||||
if (info.title.size())
|
||||
if (!info.title.empty())
|
||||
{
|
||||
addTitle(QString::fromStdWString(info.title), info.count, info.countText.c_str());
|
||||
}
|
||||
|
||||
for (TooltipSnippet& snippet : info.snippets)
|
||||
for (const TooltipSnippet& snippet : info.snippets)
|
||||
{
|
||||
QtCodeField* field = new QtCodeField(1, snippet.code, snippet.locationFile);
|
||||
const TextCodec codec(ApplicationSettings::getInstance()->getTextEncoding());
|
||||
|
||||
QtCodeField* field = new QtCodeField(1, codec.encode(snippet.code), snippet.locationFile, false);
|
||||
|
||||
QSize size = field->sizeHint() + QSize(15, 5);
|
||||
if (size.width() > 600)
|
||||
|
||||
@@ -277,7 +277,7 @@ namespace utility
|
||||
{
|
||||
return doReplaceBetween<std::wstring>(str, startDelimiter, endDelimiter, to);
|
||||
}
|
||||
|
||||
|
||||
std::string insertLineBreaksAtBlankSpaces(const std::string& s, size_t maxLineLength)
|
||||
{
|
||||
const std::vector<std::string> atoms = splitToVector(s, " ");
|
||||
@@ -319,11 +319,11 @@ namespace utility
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::string breakSignature(
|
||||
std::string returnPart, std::string namePart, std::string paramPart,
|
||||
std::wstring breakSignature(
|
||||
std::wstring returnPart, std::wstring namePart, std::wstring paramPart,
|
||||
size_t maxLineLength, size_t tabWidth)
|
||||
{
|
||||
namePart = ' ' + namePart;
|
||||
namePart = L' ' + namePart;
|
||||
|
||||
size_t totalSize = returnPart.size() + namePart.size() + paramPart.size();
|
||||
if (totalSize <= maxLineLength)
|
||||
@@ -331,47 +331,47 @@ namespace utility
|
||||
return returnPart + namePart + paramPart;
|
||||
}
|
||||
|
||||
if (paramPart.size())
|
||||
if (!paramPart.empty())
|
||||
{
|
||||
namePart += paramPart[0];
|
||||
paramPart.erase(0, 1);
|
||||
}
|
||||
|
||||
size_t parenPos = paramPart.rfind(')');
|
||||
std::string endPart;
|
||||
size_t parenPos = paramPart.rfind(L')');
|
||||
std::wstring endPart;
|
||||
if (parenPos == 0)
|
||||
{
|
||||
namePart += paramPart;
|
||||
paramPart = "";
|
||||
paramPart = L"";
|
||||
}
|
||||
else if (parenPos != std::string::npos)
|
||||
else if (parenPos != std::wstring::npos)
|
||||
{
|
||||
endPart = paramPart.substr(parenPos);
|
||||
paramPart = paramPart.substr(0, parenPos);
|
||||
}
|
||||
|
||||
if (paramPart.size() && paramPart.size() + tabWidth - endPart.size() > maxLineLength)
|
||||
if (!paramPart.empty() && paramPart.size() + tabWidth - endPart.size() > maxLineLength)
|
||||
{
|
||||
std::vector<std::string> paramLines;
|
||||
std::vector<std::wstring> paramLines;
|
||||
while (true)
|
||||
{
|
||||
size_t parenCount = 0;
|
||||
bool split = false;
|
||||
for (size_t i = 0; i < paramPart.size(); i++)
|
||||
{
|
||||
char c = paramPart[i];
|
||||
if (parenCount == 0 && c == ',')
|
||||
const wchar_t c = paramPart[i];
|
||||
if (parenCount == 0 && c == L',')
|
||||
{
|
||||
paramLines.push_back(paramPart.substr(0, i + 1));
|
||||
paramPart = paramPart.substr(i + 2);
|
||||
split = true;
|
||||
break;
|
||||
}
|
||||
else if (c == '<' || c == '(')
|
||||
else if (c == L'<' || c == L'(')
|
||||
{
|
||||
parenCount++;
|
||||
}
|
||||
else if (c == '>' || c == ')')
|
||||
else if (c == L'>' || c == L')')
|
||||
{
|
||||
parenCount--;
|
||||
}
|
||||
@@ -384,42 +384,42 @@ namespace utility
|
||||
}
|
||||
}
|
||||
|
||||
paramPart = "";
|
||||
for (const std::string& str : paramLines)
|
||||
paramPart = L"";
|
||||
for (const std::wstring& str : paramLines)
|
||||
{
|
||||
paramPart += "\n\t" + str;
|
||||
size_t length = tabWidth + str.size();
|
||||
paramPart += L"\n\t" + str;
|
||||
const size_t length = tabWidth + str.size();
|
||||
maxLineLength = std::max(length, maxLineLength);
|
||||
}
|
||||
}
|
||||
else if (paramPart.size())
|
||||
else if (!paramPart.empty())
|
||||
{
|
||||
paramPart = "\n\t" + paramPart;
|
||||
paramPart = L"\n\t" + paramPart;
|
||||
}
|
||||
|
||||
if (returnPart.size() + namePart.size() <= maxLineLength)
|
||||
{
|
||||
namePart = returnPart + namePart;
|
||||
returnPart = "";
|
||||
returnPart = L"";
|
||||
}
|
||||
|
||||
std::string sig;
|
||||
std::wstring sig;
|
||||
|
||||
if (returnPart.size())
|
||||
if (!returnPart.empty())
|
||||
{
|
||||
sig += returnPart + '\n';
|
||||
sig += returnPart + L'\n';
|
||||
}
|
||||
|
||||
sig += namePart;
|
||||
|
||||
if (paramPart.size())
|
||||
if (!paramPart.empty())
|
||||
{
|
||||
sig += paramPart;
|
||||
}
|
||||
|
||||
if (endPart.size())
|
||||
if (!endPart.empty())
|
||||
{
|
||||
sig += '\n' + endPart;
|
||||
sig += L'\n' + endPart;
|
||||
}
|
||||
|
||||
return sig;
|
||||
|
||||
@@ -70,8 +70,8 @@ namespace utility
|
||||
std::wstring replaceBetween(const std::wstring& str, wchar_t startDelimiter, wchar_t endDelimiter, const std::wstring& to);
|
||||
|
||||
std::string insertLineBreaksAtBlankSpaces(const std::string& s, size_t maxLineLength);
|
||||
std::string breakSignature(
|
||||
std::string returnPart, std::string namePart, std::string paramPart,
|
||||
std::wstring breakSignature(
|
||||
std::wstring returnPart, std::wstring namePart, std::wstring paramPart,
|
||||
size_t maxLineLength, size_t tabWidth);
|
||||
|
||||
std::string trim(const std::string &str);
|
||||
|
||||
Reference in New Issue
Block a user