This commit is contained in:
gallaert 2018-10-15 22:29:01 +01:00
commit 5665403d66
6 changed files with 126 additions and 33 deletions

View File

@ -32,6 +32,7 @@ include (GenerateExportHeader)
# only relevant for building shared libs but let's set it regardless # only relevant for building shared libs but let's set it regardless
set(CMAKE_OSX_RPATH 1) set(CMAKE_OSX_RPATH 1)
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.9" CACHE STRING "Minimum OS X deployment version")
# let's use & require C++11 - note these are only functional with CMake 3.1 # let's use & require C++11 - note these are only functional with CMake 3.1
# we do manual fallbacks for CMake 3.0 in the compilers section # we do manual fallbacks for CMake 3.0 in the compilers section
@ -44,12 +45,7 @@ string(STRIP ${versionFile} SIMGEAR_VERSION)
project(SimGear VERSION ${SIMGEAR_VERSION} LANGUAGES C CXX) project(SimGear VERSION ${SIMGEAR_VERSION} LANGUAGES C CXX)
# using 10.7 because boost requires libc++ and 10.6 doesn't include it # add a dependency on the version file
# Cmake documentation says we must set this before calling project(), but
# it only seems to be picked up setting it /after/ the call to project()
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.7")
# add a dependency on the versino file
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS version) set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS version)
set_property(GLOBAL PROPERTY FIND_LIBRARY_USE_LIB64_PATHS TRUE) set_property(GLOBAL PROPERTY FIND_LIBRARY_USE_LIB64_PATHS TRUE)

View File

@ -148,6 +148,7 @@ int parseTest()
SGPath rootPath = simgear::Dir::current().path(); SGPath rootPath = simgear::Dir::current().path();
rootPath.append("testRoot"); rootPath.append("testRoot");
pkg::Root* root = new pkg::Root(rootPath, "8.1.12"); pkg::Root* root = new pkg::Root(rootPath, "8.1.12");
root->setLocale("de");
pkg::CatalogRef cat = pkg::Catalog::createFromPath(root, SGPath(SRC_DIR "/catalogTest1")); pkg::CatalogRef cat = pkg::Catalog::createFromPath(root, SGPath(SRC_DIR "/catalogTest1"));
SG_VERIFY(cat.valid()); SG_VERIFY(cat.valid());
@ -172,7 +173,7 @@ int parseTest()
pkg::PackageRef p2 = cat->getPackageById("c172p"); pkg::PackageRef p2 = cat->getPackageById("c172p");
SG_VERIFY(p2.valid()); SG_VERIFY(p2.valid());
SG_CHECK_EQUAL(p2->qualifiedId(), "org.flightgear.test.catalog1.c172p"); SG_CHECK_EQUAL(p2->qualifiedId(), "org.flightgear.test.catalog1.c172p");
SG_CHECK_EQUAL(p2->description(), "A plane made by Cessna on Jupiter"); SG_CHECK_EQUAL(p2->description(), "German description of C172");
pkg::Package::PreviewVec thumbs = p2->previewsForVariant(0); pkg::Package::PreviewVec thumbs = p2->previewsForVariant(0);
SG_CHECK_EQUAL(thumbs.size(), 3); SG_CHECK_EQUAL(thumbs.size(), 3);
@ -217,7 +218,7 @@ int parseTest()
SG_CHECK_EQUAL(skisVariant, skisVariantFull); SG_CHECK_EQUAL(skisVariant, skisVariantFull);
SG_CHECK_EQUAL(p2->getLocalisedProp("description", skisVariant), SG_CHECK_EQUAL(p2->getLocalisedProp("description", skisVariant),
"A plane with skis"); "German description of C172 with skis");
SG_CHECK_EQUAL(p2->getLocalisedProp("author", skisVariant), SG_CHECK_EQUAL(p2->getLocalisedProp("author", skisVariant),
"Standard author"); "Standard author");
@ -225,6 +226,7 @@ int parseTest()
SG_VERIFY(floatsVariant > 0); SG_VERIFY(floatsVariant > 0);
SG_CHECK_EQUAL(p2->parentIdForVariant(floatsVariant), "c172p"); SG_CHECK_EQUAL(p2->parentIdForVariant(floatsVariant), "c172p");
// no DE localisation description provided for the floats variant
SG_CHECK_EQUAL(p2->getLocalisedProp("description", floatsVariant), SG_CHECK_EQUAL(p2->getLocalisedProp("description", floatsVariant),
"A plane with floats"); "A plane with floats");
SG_CHECK_EQUAL(p2->getLocalisedProp("author", floatsVariant), SG_CHECK_EQUAL(p2->getLocalisedProp("author", floatsVariant),
@ -257,6 +259,12 @@ int parseTest()
string_list primaries = {"c172p", "c172r"}; string_list primaries = {"c172p", "c172r"};
SG_VERIFY(p2->primaryVariants() == primaries); SG_VERIFY(p2->primaryVariants() == primaries);
///////////
pkg::PackageRef p3 = cat->getPackageById("b737-NG");
SG_VERIFY(p3.valid());
SG_CHECK_EQUAL(p3->description(), "German description of B737NG XYZ");
// test filtering / searching too // test filtering / searching too
string_set tags(p2->tags()); string_set tags(p2->tags());
SG_CHECK_EQUAL(tags.size(), 4); SG_CHECK_EQUAL(tags.size(), 4);
@ -305,6 +313,16 @@ int parseTest()
queryText->setStringValue("any-of/description", "float"); queryText->setStringValue("any-of/description", "float");
SG_VERIFY(p2->matches(queryText.ptr())); SG_VERIFY(p2->matches(queryText.ptr()));
} }
// match localized variant descriptions
{
SGPropertyNode_ptr queryText(new SGPropertyNode);
queryText->setStringValue("any-of/description", "XYZ");
SG_VERIFY(p3->matches(queryText.ptr()));
}
delete root; delete root;
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }

View File

@ -44,7 +44,7 @@ void Package::initWithProps(const SGPropertyNode* aProps)
{ {
m_props = const_cast<SGPropertyNode*>(aProps); m_props = const_cast<SGPropertyNode*>(aProps);
// cache tag values // cache tag values
BOOST_FOREACH(const SGPropertyNode* c, aProps->getChildren("tag")) { for (auto c : aProps->getChildren("tag")) {
std::string t(c->getStringValue()); std::string t(c->getStringValue());
m_tags.insert(boost::to_lower_copy(t)); m_tags.insert(boost::to_lower_copy(t));
} }
@ -133,23 +133,9 @@ bool Package::matches(const SGPropertyNode* aFilter) const
if ((filter_name == "text") || (filter_name == "description")) { if ((filter_name == "text") || (filter_name == "description")) {
handled = true; handled = true;
std::string n(aFilter->getStringValue()); if (matchesDescription(aFilter->getStringValue())) {
boost::to_lower(n);
size_t pos = boost::to_lower_copy(description()).find(n);
if (pos != std::string::npos) {
return true; return true;
} }
for (auto var : m_props->getChildren("variant")) {
if (var->hasChild("description")) {
std::string variantDesc(var->getStringValue("description"));
boost::to_lower(variantDesc);
size_t pos = variantDesc.find(n);
if (pos != std::string::npos) {
return true;
}
}
}
} }
if (!handled) { if (!handled) {
@ -159,6 +145,50 @@ bool Package::matches(const SGPropertyNode* aFilter) const
return false; return false;
} }
bool Package::matchesDescription(const std::string &search) const
{
std::string n(search);
boost::to_lower(n);
bool localized;
auto d = getLocalisedString(m_props, "description", &localized);
boost::to_lower(d);
if (d.find(n) != std::string::npos) {
return true;
}
// try non-localized description too, if the abovce was a localized one
if (localized) {
const std::string baseDesc = m_props->getStringValue("description");
auto pos = boost::to_lower_copy(baseDesc).find(n);
if (pos != std::string::npos) {
return true;
}
}
// try each variant's description
for (auto var : m_props->getChildren("variant")) {
auto vd = getLocalisedString(var, "description", &localized);
if (!vd.empty()) {
boost::to_lower(vd);
if (vd.find(n) != std::string::npos) {
return true;
}
}
if (localized) {
// try non-localized variant description
std::string vd = var->getStringValue("description");
boost::to_lower(vd);
if (vd.find(n) != std::string::npos) {
return true;
}
}
} // of variant iteration
return false;
}
bool Package::isInstalled() const bool Package::isInstalled() const
{ {
// anything to check for? look for a valid revision file? // anything to check for? look for a valid revision file?
@ -307,14 +337,29 @@ std::string Package::getLocalisedProp(const std::string& aName, const unsigned i
return getLocalisedString(propsForVariant(vIndex, aName.c_str()), aName.c_str()); return getLocalisedString(propsForVariant(vIndex, aName.c_str()), aName.c_str());
} }
std::string Package::getLocalisedString(const SGPropertyNode* aRoot, const char* aName) const std::string Package::getLocalisedString(const SGPropertyNode* aRoot, const char* aName, bool* isLocalized) const
{ {
std::string locale = m_catalog->root()->getLocale(); // we used to place localised strings under /sim/<locale>/name - but this
if (aRoot->hasChild(locale)) { // potentially pollutes the /sim namespace
const SGPropertyNode* localeRoot = aRoot->getChild(locale.c_str()); // we now check first in /sim/localized/<locale>/name first
if (localeRoot->hasChild(aName)) { const auto& locale = m_catalog->root()->getLocale();
return localeRoot->getStringValue(aName); if (isLocalized) *isLocalized = false;
if (locale.empty()) {
return aRoot->getStringValue(aName);
} }
const SGPropertyNode* localeRoot;
if (aRoot->hasChild("localized")) {
localeRoot = aRoot->getChild("localized")->getChild(locale);
} else {
// old behaviour where locale nodes are directly beneath /sim
localeRoot = aRoot->getChild(locale);
}
if (localeRoot && localeRoot->hasChild(aName)) {
if (isLocalized) *isLocalized = true;
return localeRoot->getStringValue(aName);
} }
return aRoot->getStringValue(aName); return aRoot->getStringValue(aName);

View File

@ -225,12 +225,14 @@ private:
*/ */
bool validate() const; bool validate() const;
std::string getLocalisedString(const SGPropertyNode* aRoot, const char* aName) const; std::string getLocalisedString(const SGPropertyNode* aRoot, const char* aName, bool* isLocalized = nullptr) const;
PreviewVec previewsFromProps(const SGPropertyNode_ptr& ptr) const; PreviewVec previewsFromProps(const SGPropertyNode_ptr& ptr) const;
SGPropertyNode_ptr propsForVariant(const unsigned int vIndex, const char* propName = nullptr) const; SGPropertyNode_ptr propsForVariant(const unsigned int vIndex, const char* propName = nullptr) const;
bool matchesDescription(const std::string &search) const;
SGPropertyNode_ptr m_props; SGPropertyNode_ptr m_props;
std::string m_id; std::string m_id;
string_set m_tags; string_set m_tags;

View File

@ -595,6 +595,12 @@ void Root::scheduleToUpdate(InstallRef aInstall)
throw sg_exception("missing argument to scheduleToUpdate"); throw sg_exception("missing argument to scheduleToUpdate");
} }
auto it = std::find(d->updateDeque.begin(), d->updateDeque.end(), aInstall);
if (it != d->updateDeque.end()) {
// already scheduled to update
return;
}
PackageList deps = aInstall->package()->dependencies(); PackageList deps = aInstall->package()->dependencies();
for (Package* dep : deps) { for (Package* dep : deps) {
// will internally schedule for update if required // will internally schedule for update if required

View File

@ -32,6 +32,15 @@
<file-size-bytes type="int">860</file-size-bytes> <file-size-bytes type="int">860</file-size-bytes>
<author>Standard author</author> <author>Standard author</author>
<localized>
<de>
<description>German description of C172</description>
</de>
<fr>
<description>French description of C172</description>
</fr>
</localized>
<tag>cessna</tag> <tag>cessna</tag>
<tag>ga</tag> <tag>ga</tag>
<tag>piston</tag> <tag>piston</tag>
@ -99,6 +108,15 @@
<name>C172 with skis</name> <name>C172 with skis</name>
<description>A plane with skis</description> <description>A plane with skis</description>
<localized>
<de>
<description>German description of C172 with skis</description>
</de>
<fr>
<description>French description of C172 with skis</description>
</fr>
</localized>
<variant-of>c172p</variant-of> <variant-of>c172p</variant-of>
<preview> <preview>
@ -157,6 +175,14 @@
<tag>jet</tag> <tag>jet</tag>
<tag>ifr</tag> <tag>ifr</tag>
<!-- not within a localized element -->
<de>
<description>German description of B737NG XYZ</description>
</de>
<fr>
<description>French description of B737NG</description>
</fr>
<rating> <rating>
<FDM type="int">5</FDM> <FDM type="int">5</FDM>
<systems type="int">5</systems> <systems type="int">5</systems>