1
0
Fork 0

Navaid search: optionally constrain results

This commit is contained in:
James Turner 2018-08-11 22:02:47 +02:00
parent f0c48110d3
commit f33b15575f
2 changed files with 57 additions and 18 deletions

View file

@ -148,6 +148,14 @@ void NavaidSearchModel::clear()
emit haveExistingSearchChanged(); emit haveExistingSearchChanged();
} }
qlonglong NavaidSearchModel::guidAtIndex(int index) const
{
if ((index < 0) || (index >= m_ids.size()))
return 0;
return m_ids.at(index);
}
void NavaidSearchModel::setSearch(QString t, NavaidSearchModel::AircraftType aircraft) void NavaidSearchModel::setSearch(QString t, NavaidSearchModel::AircraftType aircraft)
{ {
beginResetModel(); beginResetModel();
@ -160,18 +168,14 @@ void NavaidSearchModel::setSearch(QString t, NavaidSearchModel::AircraftType air
IdentSearchFilter filter(static_cast<LauncherController::AircraftType>(aircraft), m_airportsOnly); IdentSearchFilter filter(static_cast<LauncherController::AircraftType>(aircraft), m_airportsOnly);
FGPositionedList exactMatches = NavDataCache::instance()->findAllWithIdent(term, &filter, true); FGPositionedList exactMatches = NavDataCache::instance()->findAllWithIdent(term, &filter, true);
// truncate based on max results
if ((m_maxResults > 0) && (exactMatches.size() > m_maxResults)) {
auto it = exactMatches.begin() + m_maxResults;
exactMatches.erase(it, exactMatches.end());
}
m_ids.reserve(exactMatches.size()); m_ids.reserve(exactMatches.size());
m_items.reserve(exactMatches.size()); m_items.reserve(exactMatches.size());
for (auto match : exactMatches) { for (auto match : exactMatches) {
m_ids.push_back(match->guid()); m_ids.push_back(match->guid());
m_items.push_back(match); m_items.push_back(match);
} }
resort();
endResetModel(); endResetModel();
m_search.reset(new NavDataCache::ThreadedGUISearch(term, m_airportsOnly)); m_search.reset(new NavDataCache::ThreadedGUISearch(term, m_airportsOnly));
@ -188,7 +192,10 @@ bool NavaidSearchModel::haveExistingSearch() const
int NavaidSearchModel::rowCount(const QModelIndex &) const int NavaidSearchModel::rowCount(const QModelIndex &) const
{ {
return m_ids.size(); if (m_maxResults > 0)
return std::min(static_cast<int>(m_ids.size()), m_maxResults);
return static_cast<int>(m_ids.size());
} }
QVariant NavaidSearchModel::data(const QModelIndex &index, int role) const QVariant NavaidSearchModel::data(const QModelIndex &index, int role) const
@ -239,6 +246,7 @@ void NavaidSearchModel::setItems(const FGPositionedList &items)
m_ids.push_back(m_items[i]->guid()); m_ids.push_back(m_items[i]->guid());
} }
// don't sort in this case
endResetModel(); endResetModel();
emit searchActiveChanged(); emit searchActiveChanged();
} }
@ -265,6 +273,11 @@ qlonglong NavaidSearchModel::exactMatch() const
return m_ids.back(); // which is also the front return m_ids.back(); // which is also the front
} }
int NavaidSearchModel::numResults() const
{
return static_cast<int>(m_ids.size());
}
void NavaidSearchModel::onSearchResultsPoll() void NavaidSearchModel::onSearchResultsPoll()
{ {
if (m_search.isNull()) { if (m_search.isNull()) {
@ -272,22 +285,14 @@ void NavaidSearchModel::onSearchResultsPoll()
} }
PositionedIDVec newIds = m_search->results(); PositionedIDVec newIds = m_search->results();
int newTotalSize = m_ids.size() + newIds.size();
if ((m_maxResults > 0) && (newTotalSize > m_maxResults)) {
// truncate new results as necessary
int numNewAllowed = m_maxResults - m_ids.size();
auto it = newIds.begin() + numNewAllowed;
newIds.erase(it, newIds.end());
// possible that newIDs is empty now
}
if (!newIds.empty()) { if (!newIds.empty()) {
beginInsertRows(QModelIndex(), m_ids.size(), newIds.size() - 1); beginResetModel(); // reset the model since we will re-sort
for (auto id : newIds) { for (auto id : newIds) {
m_ids.push_back(id); m_ids.push_back(id);
m_items.push_back({}); // null ref m_items.push_back({}); // null ref
} }
endInsertRows(); resort();
endResetModel();
} }
if (m_search->isComplete()) { if (m_search->isComplete()) {
@ -300,3 +305,31 @@ void NavaidSearchModel::onSearchResultsPoll()
QTimer::singleShot(100, this, SLOT(onSearchResultsPoll())); QTimer::singleShot(100, this, SLOT(onSearchResultsPoll()));
} }
} }
void NavaidSearchModel::resort()
{
if (!m_airportsOnly) {
return;
}
// clear m_items
std::fill(m_items.begin(), m_items.end(), FGPositionedRef{});
// build runway length cache
std::map<PositionedID, double> longestRunwayCache;
for (auto a : m_ids) {
const FGAirportRef apt = FGPositioned::loadById<FGAirport>(a);
if (apt) {
const auto rwy = apt->longestRunway();
if (rwy) {
longestRunwayCache[a] = rwy->lengthFt();
}
}
}
std::sort(m_ids.begin(), m_ids.end(),
[&longestRunwayCache](const PositionedID a, const PositionedID& b)
{
return longestRunwayCache[a] > longestRunwayCache[b];
});
}

View file

@ -36,6 +36,7 @@ class NavaidSearchModel : public QAbstractListModel
Q_PROPERTY(bool haveExistingSearch READ haveExistingSearch NOTIFY haveExistingSearchChanged) Q_PROPERTY(bool haveExistingSearch READ haveExistingSearch NOTIFY haveExistingSearchChanged)
Q_PROPERTY(bool airportsOnly MEMBER m_airportsOnly NOTIFY airportsOnlyChanged) Q_PROPERTY(bool airportsOnly MEMBER m_airportsOnly NOTIFY airportsOnlyChanged)
Q_PROPERTY(int maxResults MEMBER m_maxResults NOTIFY maxResultsChanged) Q_PROPERTY(int maxResults MEMBER m_maxResults NOTIFY maxResultsChanged)
Q_PROPERTY(int numResults READ numResults NOTIFY searchActiveChanged)
Q_PROPERTY(qlonglong exactMatch READ exactMatch NOTIFY searchActiveChanged) Q_PROPERTY(qlonglong exactMatch READ exactMatch NOTIFY searchActiveChanged)
@ -67,6 +68,8 @@ public:
Q_INVOKABLE void clear(); Q_INVOKABLE void clear();
Q_INVOKABLE qlonglong guidAtIndex(int index) const;
bool isSearchActive() const bool isSearchActive() const
{ {
return m_searchActive; return m_searchActive;
@ -86,6 +89,7 @@ public:
qlonglong exactMatch() const; qlonglong exactMatch() const;
int numResults() const;
Q_SIGNALS: Q_SIGNALS:
void searchComplete(); void searchComplete();
void searchActiveChanged(); void searchActiveChanged();
@ -97,6 +101,8 @@ private slots:
void onSearchResultsPoll(); void onSearchResultsPoll();
private: private:
void resort();
PositionedIDVec m_ids; PositionedIDVec m_ids;
mutable FGPositionedList m_items; mutable FGPositionedList m_items;
bool m_searchActive = false; bool m_searchActive = false;