Restore name completion support.

pull/233/head
pirogronian 2019-02-08 23:06:39 +01:00
parent 55f67a8c44
commit 8490d93082
6 changed files with 139 additions and 19 deletions

View File

@ -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;
}

View File

@ -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;

View File

@ -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.
}

View File

@ -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)

View File

@ -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;
}

View File

@ -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_