Restore name completion support.
parent
55f67a8c44
commit
8490d93082
|
@ -18,8 +18,8 @@ void NameDatabase::add(const uint32_t catalogNumber, const std::string& name, bo
|
|||
// Add the new name
|
||||
//nameIndex.insert(NameIndex::value_type(name, catalogNumber));
|
||||
std::string fname = ReplaceGreekLetterAbbr(name);
|
||||
|
||||
nameIndex[fname] = catalogNumber;
|
||||
|
||||
nameIndex[fname] = catalogNumber;
|
||||
numberIndex.insert(NumberIndex::value_type(catalogNumber, fname));
|
||||
}
|
||||
}
|
||||
|
@ -83,17 +83,35 @@ NameDatabase::NumberIndex::const_iterator NameDatabase::getFinalNameIter() const
|
|||
return numberIndex.end();
|
||||
}
|
||||
|
||||
std::vector<std::string> NameDatabase::getCompletion(const std::string& name) const
|
||||
std::vector<std::string> NameDatabase::getCompletion(const std::string& name, bool greek) const
|
||||
{
|
||||
if (greek)
|
||||
{
|
||||
auto compList = getGreekCompletion(name);
|
||||
compList.push_back(name);
|
||||
return getCompletion(compList);
|
||||
}
|
||||
|
||||
std::vector<std::string> completion;
|
||||
int name_length = UTF8Length(name);
|
||||
|
||||
for (NameIndex::const_iterator iter = nameIndex.begin(); iter != nameIndex.end(); ++iter)
|
||||
{
|
||||
if (!UTF8StringCompare(iter->first, name, name_length))
|
||||
if (!UTF8StringCompare(iter->first, name, name_length, true))
|
||||
{
|
||||
completion.push_back(iter->first);
|
||||
}
|
||||
}
|
||||
return completion;
|
||||
}
|
||||
|
||||
std::vector<std::string> NameDatabase::getCompletion(const std::vector<std::string> &list) const
|
||||
{
|
||||
std::vector<std::string> completion;
|
||||
for (const auto &n : list)
|
||||
{
|
||||
for (const auto &nn : getCompletion(n, false))
|
||||
completion.emplace_back(nn);
|
||||
}
|
||||
return completion;
|
||||
}
|
||||
|
|
|
@ -48,7 +48,8 @@ class NameDatabase
|
|||
NumberIndex::const_iterator getFirstNameIter(const uint32_t catalogNumber) const;
|
||||
NumberIndex::const_iterator getFinalNameIter() const;
|
||||
|
||||
std::vector<std::string> getCompletion(const std::string& name) const;
|
||||
std::vector<std::string> getCompletion(const std::string& name, bool greek = true) const;
|
||||
std::vector<std::string> getCompletion(const std::vector<std::string> &list) const;
|
||||
|
||||
protected:
|
||||
NameIndex nameIndex;
|
||||
|
|
|
@ -18,6 +18,10 @@ using namespace std;
|
|||
|
||||
uint32_t StarNameDatabase::findCatalogNumberByName(const string& name) const
|
||||
{
|
||||
uint32_t catalogNumber = getCatalogNumberByName(name);
|
||||
if (catalogNumber != Star::InvalidCatalogNumber)
|
||||
return catalogNumber;
|
||||
|
||||
string priName = name;
|
||||
string altName;
|
||||
|
||||
|
@ -31,7 +35,7 @@ uint32_t StarNameDatabase::findCatalogNumberByName(const string& name) const
|
|||
if (con != nullptr)
|
||||
{
|
||||
char digit = ' ';
|
||||
int len = prefix.length();
|
||||
int len = prefix.length();
|
||||
|
||||
// If the first character of the prefix is a letter
|
||||
// and the last character is a digit, we may have
|
||||
|
@ -40,7 +44,7 @@ uint32_t StarNameDatabase::findCatalogNumberByName(const string& name) const
|
|||
if (len > 2 && isalpha(prefix[0]) && isdigit(prefix[len - 1]))
|
||||
{
|
||||
--len;
|
||||
digit = prefix[len];
|
||||
digit = prefix[len];
|
||||
}
|
||||
|
||||
// We have a valid constellation as the last part
|
||||
|
@ -59,34 +63,34 @@ uint32_t StarNameDatabase::findCatalogNumberByName(const string& name) const
|
|||
}
|
||||
else
|
||||
{
|
||||
priName = letter + digit + ' ' + con->getAbbreviation();
|
||||
priName = letter + digit + ' ' + con->getAbbreviation();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Something other than a Bayer designation
|
||||
priName = prefix + ' ' + con->getAbbreviation();
|
||||
priName = prefix + ' ' + con->getAbbreviation();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t catalogNumber = getCatalogNumberByName(priName);
|
||||
catalogNumber = getCatalogNumberByName(priName);
|
||||
if (catalogNumber != Star::InvalidCatalogNumber)
|
||||
return catalogNumber;
|
||||
|
||||
priName += " A"; // try by appending an A
|
||||
catalogNumber = getCatalogNumberByName(priName);
|
||||
priName += " A"; // try by appending an A
|
||||
catalogNumber = getCatalogNumberByName(priName);
|
||||
if (catalogNumber != Star::InvalidCatalogNumber)
|
||||
return catalogNumber;
|
||||
|
||||
// If the first search failed, try using the alternate name
|
||||
if (altName.length() != 0)
|
||||
{
|
||||
catalogNumber = getCatalogNumberByName(altName);
|
||||
catalogNumber = getCatalogNumberByName(altName);
|
||||
if (catalogNumber == Star::InvalidCatalogNumber)
|
||||
{
|
||||
altName += " A";
|
||||
catalogNumber = getCatalogNumberByName(altName);
|
||||
altName += " A";
|
||||
catalogNumber = getCatalogNumberByName(altName);
|
||||
} // Intentional fallthrough.
|
||||
}
|
||||
|
||||
|
|
|
@ -3763,7 +3763,7 @@ void CelestiaCore::renderOverlay()
|
|||
glTranslatef(0.0f, fontHeight * 3.0f + 35.0f, 0.0f);
|
||||
glColor4f(0.6f, 0.6f, 1.0f, 1.0f);
|
||||
overlay->beginText();
|
||||
*overlay << _("Target name: ") << typedText;
|
||||
fmt::fprintf(*overlay, _("Target name: %s"), typedText);
|
||||
overlay->endText();
|
||||
overlay->setFont(font);
|
||||
if (typedTextCompletion.size() >= 1)
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
#include <cctype>
|
||||
#include <cstring>
|
||||
#include "util.h"
|
||||
#include <wchar.h>
|
||||
#include <climits>
|
||||
|
||||
uint16_t WGL4_Normalization_00[256] = {
|
||||
0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
|
||||
|
@ -557,7 +559,7 @@ int UTF8StringCompare(const std::string& s0, const std::string& s1)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int UTF8StringCompare(const std::string& s0, const std::string& s1, size_t n)
|
||||
int UTF8StringCompare(const std::string& s0, const std::string& s1, size_t n, bool ignoreCase)
|
||||
{
|
||||
int len0 = s0.length();
|
||||
int len1 = s1.length();
|
||||
|
@ -577,6 +579,11 @@ int UTF8StringCompare(const std::string& s0, const std::string& s1, size_t n)
|
|||
ch0 = UTF8Normalize(ch0);
|
||||
ch1 = UTF8Normalize(ch1);
|
||||
|
||||
if (ignoreCase)
|
||||
{
|
||||
ch0 = std::tolower(ch0);
|
||||
ch1 = std::tolower(ch1);
|
||||
}
|
||||
if (ch0 < ch1)
|
||||
return -1;
|
||||
if (ch0 > ch1)
|
||||
|
@ -897,3 +904,91 @@ ReplaceGreekLetterAbbr(char *dst, unsigned int dstSize, const char* src, unsigne
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int findGreekNameIndexBySubstr(const std::string &, int = 0, unsigned int = UINT_MAX);
|
||||
static std::string firstGreekAbbrCompletion(const std::string &);
|
||||
|
||||
bool inline isSubstringIgnoringCase(const std::string &s0, const std::string &s1, size_t n)
|
||||
{
|
||||
return UTF8StringCompare(s0, s1, n, true) == 0;
|
||||
}
|
||||
|
||||
static int findGreekNameIndexBySubstr(const std::string &s, int start, unsigned int n)
|
||||
{
|
||||
Greek *instance = Greek::getInstance();
|
||||
|
||||
if (s.empty())
|
||||
return -1;
|
||||
|
||||
for (int i = start; i < instance->nLetters; i++)
|
||||
{
|
||||
if (isSubstringIgnoringCase(instance->names[i], s, n))
|
||||
return i;
|
||||
}
|
||||
|
||||
for (int i = start; i < instance->nLetters; i++)
|
||||
{
|
||||
if (isSubstringIgnoringCase(instance->abbrevs[i], s, n))
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static std::string firstGreekAbbrCompletion(const std::string &s)
|
||||
{
|
||||
std::string ret;
|
||||
size_t sp = s.find_first_of(' ');
|
||||
if (sp == std::string::npos)
|
||||
{
|
||||
int i = findGreekNameIndexBySubstr(s);
|
||||
return (i >= 0) ? Greek::getInstance()->abbrevs[i] : s;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string prefix = s.substr(0, sp);
|
||||
ret = Greek::canonicalAbbreviation(prefix);
|
||||
return ret.empty() ? s : prefix + s.substr(sp);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::vector<std::string> getGreekCompletion(const std::string &s)
|
||||
{
|
||||
std::vector<std::string> ret;
|
||||
if (s.empty())
|
||||
return ret;
|
||||
|
||||
size_t sp = s.find_first_of(' ');
|
||||
if (sp == std::string::npos)
|
||||
{
|
||||
sp = UTF8Length(s);
|
||||
for(int i = 0; i >= 0;)
|
||||
{
|
||||
std::string rets;
|
||||
i = findGreekNameIndexBySubstr(s, i, sp);
|
||||
if (i >= 0)
|
||||
{
|
||||
rets = Greek::getInstance()->abbrevs[i];
|
||||
rets += " ";
|
||||
ret.emplace_back(ReplaceGreekLetterAbbr(rets));
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string prefix = s.substr(0, sp);
|
||||
std::string rets = Greek::canonicalAbbreviation(prefix);
|
||||
if (!rets.empty())
|
||||
{
|
||||
rets += s.substr(sp);;
|
||||
ret.emplace_back(ReplaceGreekLetterAbbr(rets));
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
#define _CELUTIL_UTF8_
|
||||
|
||||
#include <string>
|
||||
#include <wchar.h>
|
||||
#include <vector>
|
||||
|
||||
#define UTF8_DEGREE_SIGN "\302\260"
|
||||
#define UTF8_MULTIPLICATION_SIGN "\303\227"
|
||||
|
@ -24,7 +24,7 @@ bool UTF8Decode(const std::string& str, int pos, wchar_t& ch);
|
|||
bool UTF8Decode(const char* str, int pos, int length, wchar_t& ch);
|
||||
int UTF8Encode(wchar_t ch, char* s);
|
||||
int UTF8StringCompare(const std::string& s0, const std::string& s1);
|
||||
int UTF8StringCompare(const std::string& s0, const std::string& s1, size_t n);
|
||||
int UTF8StringCompare(const std::string& s0, const std::string& s1, size_t n, bool ignoreCase = false);
|
||||
|
||||
class UTF8StringOrderingPredicate
|
||||
{
|
||||
|
@ -123,4 +123,6 @@ private:
|
|||
std::string* abbrevs;
|
||||
};
|
||||
|
||||
std::vector<std::string> getGreekCompletion(const std::string &);
|
||||
|
||||
#endif // _CELUTIL_UTF8_
|
||||
|
|
Loading…
Reference in New Issue