Ref T472, utility functions for aircraft categories

This commit is contained in:
Klaus Basan
2019-03-03 17:47:19 +01:00
committed by Mat Sutcliffe
parent b57003c4e8
commit 5846860382
4 changed files with 148 additions and 1 deletions

View File

@@ -83,6 +83,15 @@ namespace BlackMisc
m_l3 = l3;
}
QList<int> CAircraftCategory::getLevel() const
{
QList<int> l;
if (m_l1 > 0) l << m_l1;
if (m_l2 > 0) l << m_l2;
if (m_l3 > 0) l << m_l3;
return l;
}
bool CAircraftCategory::isFirstLevel() const
{
return (m_l3 == 0 && m_l2 == 0 && m_l1 > 0);
@@ -110,6 +119,23 @@ namespace BlackMisc
return stringCompare(path, this->getPath(), cs);
}
bool CAircraftCategory::matchesLevel(int l1, int l2, int l3) const
{
if (l1 != m_l1) { return false; }
if (l2 > 0 && l2 != m_l2) { return false; }
if (l3 > 0 && l3 != m_l3) { return false; }
return true;
}
bool CAircraftCategory::matchesLevel(const QList<int> &level) const
{
if (level.isEmpty()) { return false; }
const int l1 = level.first();
const int l2 = level.size() > 1 ? level.at(1) : 0;
const int l3 = level.size() > 2 ? level.at(2) : 0;
return this->matchesLevel(l1, l2, l3);
}
CVariant CAircraftCategory::propertyByIndex(const BlackMisc::CPropertyIndex &index) const
{
if (index.isMyself()) { return CVariant::from(*this); }
@@ -184,5 +210,11 @@ namespace BlackMisc
c = Compare::compare(m_l3, other.m_l3);
return c;
}
bool CAircraftCategory::isHigherLevel(const CAircraftCategory &other) const
{
const int c = this->compareByLevel(other);
return c < 0;
}
} // namespace
} // namespace

View File

@@ -21,6 +21,7 @@
#include <QJsonObject>
#include <QMap>
#include <QList>
#include <QStringList>
#include <QMetaType>
@@ -77,6 +78,9 @@ namespace BlackMisc
//! Level
void setLevel(int l1, int l2, int l3);
//! Levels depending on depth, 3.2 -> 3,2 / 1.0 -> 1 / 4.3.1 -> 4,3,1
QList<int> getLevel() const;
//! First level
int getFirstLevel() const { return m_l1; }
@@ -95,6 +99,12 @@ namespace BlackMisc
//! Matching path?
bool matchesPath(const QString &path, Qt::CaseSensitivity cs);
//! Is matching the level, 0 ignored
bool matchesLevel(int l1, int l2 = 0, int l3 = 0) const;
//! Is matching the level, 0 ignored
bool matchesLevel(const QList<int> &level) const;
//! Assignable?
bool isAssignable() const { return m_assignable; }
@@ -122,6 +132,9 @@ namespace BlackMisc
//! Level compare
int compareByLevel(const CAircraftCategory &other) const;
//! Higher level?
bool isHigherLevel(const CAircraftCategory &other) const;
//! NULL object
static const CAircraftCategory &null();

View File

@@ -12,6 +12,7 @@
#include <QJsonObject>
#include <QJsonValue>
#include <Qt>
#include <QMap>
namespace BlackMisc
{
@@ -68,12 +69,57 @@ namespace BlackMisc
return ll;
}
CAircraftCategoryList CAircraftCategoryList::findHighestLevels(const CAircraftCategoryList &categories)
{
if (categories.isEmpty()) { return CAircraftCategoryList(); }
QMap<int, CAircraftCategory> highestLevels;
for (const CAircraftCategory &category : *this)
{
const int fl = category.getFirstLevel();
if (highestLevels.contains(fl))
{
if (highestLevels[fl].isHigherLevel(category))
{
highestLevels[fl] = category;
}
}
else
{
highestLevels[fl] = category;
}
}
CAircraftCategoryList topLevels;
for (const CAircraftCategory &category : highestLevels.values())
{
topLevels.push_back(category);
}
return topLevels;
}
CAircraftCategoryList CAircraftCategoryList::findByFirstLevel(int level) const
{
CAircraftCategoryList categories;
for (const CAircraftCategory &category : *this)
{
if (category.getFirstLevel() != level) { continue; }
if (category.getFirstLevel() == level)
{
categories.push_back(category);
}
}
return categories;
}
CAircraftCategoryList CAircraftCategoryList::findByLevel(const QList<int> &level) const
{
CAircraftCategoryList categories;
if (level.isEmpty()) { return categories; }
for (const CAircraftCategory &category : *this)
{
if (category.matchesLevel(level))
{
categories.push_back(category);
}
}
return categories;
}
@@ -83,6 +129,45 @@ namespace BlackMisc
return this->findBy(&CAircraftCategory::isFirstLevel, true);
}
CAircraftCategoryList CAircraftCategoryList::findSiblings(const CAircraftCategory &category) const
{
QList<int> levels = category.getLevel();
CAircraftCategoryList categories;
if (levels.size() < 2)
{
categories = this->findFirstLevels();
}
else
{
levels.removeLast();
categories = this->findByLevel(levels);
}
categories.remove(category);
return categories;
}
int CAircraftCategoryList::removeIfLevel(const QList<int> &level)
{
if (level.isEmpty()) { return 0; }
const int c = this->size();
const CAircraftCategoryList removed = this->removedLevel(level);
const int delta = c - removed.size();
if (delta > 0) { *this = removed; }
return delta;
}
CAircraftCategoryList CAircraftCategoryList::removedLevel(const QList<int> &level) const
{
if (level.isEmpty()) { return *this; } // nothing removed
CAircraftCategoryList removed;
for (const CAircraftCategory &category : * this)
{
if (category.matchesLevel(level)) { continue; }
removed.push_back(category);
}
return removed;
}
CAircraftCategoryList CAircraftCategoryList::fromDatabaseJson(const QJsonArray &array)
{
CAircraftCategoryList categories;

View File

@@ -21,6 +21,7 @@
#include <QJsonArray>
#include <QMetaType>
#include <QSet>
#include <QList>
#include <tuple>
namespace BlackMisc
@@ -57,12 +58,28 @@ namespace BlackMisc
//! All levels sorted
QList<int> getFirstLevels() const;
//! Find highest (top) level of categories
CAircraftCategoryList findHighestLevels(const CAircraftCategoryList &categories);
//! Find by first level
CAircraftCategoryList findByFirstLevel(int level) const;
//! Find by levels
CAircraftCategoryList findByLevel(const QList<int> &level) const;
//! Find first levels
CAircraftCategoryList findFirstLevels() const;
//! Find siblings
//! \remark if level is 3.2, siblings are 3.1 and 3.3
CAircraftCategoryList findSiblings(const CAircraftCategory &category) const;
//! Remove by level
int removeIfLevel(const QList<int> &level);
//! With removed categories
CAircraftCategoryList removedLevel(const QList<int> &level) const;
//! From our database JSON format
static CAircraftCategoryList fromDatabaseJson(const QJsonArray &array);
};