Navaid search: optionally constrain results
This commit is contained in:
parent
f0c48110d3
commit
f33b15575f
2 changed files with 57 additions and 18 deletions
|
@ -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];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue