]> git.mxchange.org Git - flightgear.git/commitdiff
Launcher GUI for in-air / navaid starts
authorJames Turner <zakalawe@mac.com>
Sun, 25 Oct 2015 00:40:41 +0000 (19:40 -0500)
committerJames Turner <zakalawe@mac.com>
Mon, 23 Nov 2015 00:46:25 +0000 (00:46 +0000)
src/GUI/QtLauncher.cxx
src/GUI/QtLauncher_private.hxx
src/Main/positioninit.cxx
src/Navaids/NavDataCache.cxx
src/Navaids/positioned.hxx

index a96ed7abb36c2627415211dafe1a1995eac8f6a4..e79585fe6d5f477c4a7a194ecd05ea68a29f1cf7 100644 (file)
@@ -235,6 +235,20 @@ private:
 
 } // of anonymous namespace
 
+class IdentSearchFilter : public FGPositioned::TypeFilter
+{
+public:
+    IdentSearchFilter()
+    {
+        addType(FGPositioned::AIRPORT);
+        addType(FGPositioned::SEAPORT);
+        addType(FGPositioned::HELIPAD);
+        addType(FGPositioned::VOR);
+        addType(FGPositioned::FIX);
+        addType(FGPositioned::NDB);
+    }
+};
+
 class AirportSearchModel : public QAbstractListModel
 {
     Q_OBJECT
@@ -248,23 +262,25 @@ public:
     {
         beginResetModel();
 
-        m_airports.clear();
+        m_items.clear();
         m_ids.clear();
 
         std::string term(t.toUpper().toStdString());
-        // try ICAO lookup first
-        FGAirportRef ref = FGAirport::findByIdent(term);
 
-        if (ref) {
-            m_ids.push_back(ref->guid());
-            m_airports.push_back(ref);
-            endResetModel();
-            return;
+        IdentSearchFilter filter;
+        FGPositionedList exactMatches = NavDataCache::instance()->findAllWithIdent(term, &filter, true);
+
+        for (unsigned int i=0; i<exactMatches.size(); ++i) {
+            m_ids.push_back(exactMatches[i]->guid());
+            m_items.push_back(exactMatches[i]);
         }
+        endResetModel();
+
 
         m_search.reset(new NavDataCache::ThreadedGUISearch(term));
         QTimer::singleShot(100, this, SLOT(onSearchResultsPoll()));
         m_searchActive = true;
+        endResetModel();
     }
 
     bool isSearchActive() const
@@ -283,19 +299,14 @@ public:
         if (!index.isValid())
             return QVariant();
 
-        FGAirportRef apt = m_airports[index.row()];
-        if (!apt.valid()) {
-            apt = FGPositioned::loadById<FGAirport>(m_ids[index.row()]);
-            m_airports[index.row()] = apt;
-        }
-
+        FGPositionedRef pos = itemAtRow(index.row());
         if (role == Qt::DisplayRole) {
-            QString name = QString::fromStdString(apt->name());
-            return QString("%1: %2").arg(QString::fromStdString(apt->ident())).arg(name);
+            QString name = QString::fromStdString(pos->name());
+            return QString("%1: %2").arg(QString::fromStdString(pos->ident())).arg(name);
         }
 
         if (role == Qt::EditRole) {
-            return QString::fromStdString(apt->ident());
+            return QString::fromStdString(pos->ident());
         }
 
         if (role == Qt::UserRole) {
@@ -305,18 +316,16 @@ public:
         return QVariant();
     }
 
-    QString firstIdent() const
+    FGPositionedRef itemAtRow(unsigned int row) const
     {
-        if (m_ids.empty())
-            return QString();
-
-        if (!m_airports.front().valid()) {
-            m_airports[0] = FGPositioned::loadById<FGAirport>(m_ids.front());
+        FGPositionedRef pos = m_items[row];
+        if (!pos.valid()) {
+            pos = NavDataCache::instance()->loadById(m_ids[row]);
+            m_items[row] = pos;
         }
 
-        return QString::fromStdString(m_airports.front()->ident());
+        return pos;
     }
-
 Q_SIGNALS:
     void searchComplete();
 
@@ -328,7 +337,7 @@ private slots:
         beginInsertRows(QModelIndex(), m_ids.size(), newIds.size() - 1);
         for (unsigned int i=m_ids.size(); i < newIds.size(); ++i) {
             m_ids.push_back(newIds[i]);
-            m_airports.push_back(FGAirportRef()); // null ref
+            m_items.push_back(FGPositionedRef()); // null ref
         }
         endInsertRows();
 
@@ -343,7 +352,7 @@ private slots:
 
 private:
     PositionedIDVec m_ids;
-    mutable std::vector<FGAirportRef> m_airports;
+    mutable FGPositionedList m_items;
     bool m_searchActive;
     QScopedPointer<NavDataCache::ThreadedGUISearch> m_search;
 };
@@ -531,15 +540,15 @@ QtLauncher::QtLauncher() :
             m_aircraftProxy, &QSortFilterProxyModel::setFilterFixedString);
 
     connect(m_ui->runwayCombo, SIGNAL(currentIndexChanged(int)),
-            this, SLOT(updateAirportDescription()));
+            this, SLOT(updateLocationDescription()));
     connect(m_ui->parkingCombo, SIGNAL(currentIndexChanged(int)),
-            this, SLOT(updateAirportDescription()));
+            this, SLOT(updateLocationDescription()));
     connect(m_ui->runwayRadio, SIGNAL(toggled(bool)),
-            this, SLOT(updateAirportDescription()));
+            this, SLOT(updateLocationDescription()));
     connect(m_ui->parkingRadio, SIGNAL(toggled(bool)),
-            this, SLOT(updateAirportDescription()));
+            this, SLOT(updateLocationDescription()));
     connect(m_ui->onFinalCheckbox, SIGNAL(toggled(bool)),
-            this, SLOT(updateAirportDescription()));
+            this, SLOT(updateLocationDescription()));
 
 
     connect(m_ui->airportDiagram, &AirportDiagram::clickedRunway,
@@ -724,12 +733,14 @@ void QtLauncher::restoreSettings()
 
     updateSelectedAircraft();
 
-    // ICAO identifiers
-    m_recentAirports = settings.value("recent-airports").toStringList();
+    Q_FOREACH(QVariant v, settings.value("recent-locations").toList()) {
+        m_recentAirports.push_back(v.toLongLong());
+    }
+
     if (!m_recentAirports.empty()) {
-        setAirport(FGAirport::findByIdent(m_recentAirports.front().toStdString()));
+        setBaseLocation(NavDataCache::instance()->loadById(m_recentAirports.front()));
     }
-    updateAirportDescription();
+    updateLocationDescription();
 
     // rating filters
     m_ui->ratingsFilterCheck->setChecked(settings.value("ratings-filter", true).toBool());
@@ -755,7 +766,13 @@ void QtLauncher::saveSettings()
     settings.setValue("start-paused", m_ui->startPausedCheck->isChecked());
     settings.setValue("ratings-filter", m_ui->ratingsFilterCheck->isChecked());
     settings.setValue("recent-aircraft", QUrl::toStringList(m_recentAircraft));
-    settings.setValue("recent-airports", m_recentAirports);
+
+    QVariantList locations;
+    Q_FOREACH(PositionedID v, m_recentAirports) {
+        locations.push_back(v);
+    }
+
+    settings.setValue("recent-airports", locations);
     settings.setValue("timeofday", m_ui->timeOfDayCombo->currentIndex());
     settings.setValue("season", m_ui->seasonCombo->currentIndex());
     settings.setValue("additional-args", m_ui->commandLineArgs->toPlainText());
@@ -819,26 +836,7 @@ void QtLauncher::onRun()
           m_recentAircraft.pop_back();
     }
 
-    // airport / location
-    if (m_selectedAirport) {
-        opt->addOption("airport", m_selectedAirport->ident());
-    }
-
-    if (m_ui->runwayRadio->isChecked()) {
-        int index = m_ui->runwayCombo->itemData(m_ui->runwayCombo->currentIndex()).toInt();
-        if ((index >= 0) && m_selectedAirport) {
-            // explicit runway choice
-            opt->addOption("runway", m_selectedAirport->getRunwayByIndex(index)->ident());
-        }
-
-        if (m_ui->onFinalCheckbox->isChecked()) {
-            opt->addOption("glideslope", "3.0");
-            opt->addOption("offset-distance", "10.0"); // in nautical miles
-        }
-    } else if (m_ui->parkingRadio->isChecked()) {
-        // parking selection
-        opt->addOption("parkpos", m_ui->parkingCombo->currentText().toStdString());
-    }
+    setLocationOptions();
 
     // time of day
     if (m_ui->timeOfDayCombo->currentIndex() != 0) {
@@ -897,6 +895,54 @@ void QtLauncher::onRun()
     saveSettings();
 }
 
+void QtLauncher::setLocationOptions()
+{
+    flightgear::Options* opt = flightgear::Options::sharedInstance();
+
+    if (!m_location) {
+        return;
+    }
+
+    if (FGAirport::isAirportType(m_location.ptr())) {
+        FGAirport* apt = static_cast<FGAirport*>(m_location.ptr());
+        opt->addOption("airport", apt->ident());
+
+        if (m_ui->runwayRadio->isChecked()) {
+            int index = m_ui->runwayCombo->itemData(m_ui->runwayCombo->currentIndex()).toInt();
+            if (index >= 0) {
+                // explicit runway choice
+                opt->addOption("runway", apt->getRunwayByIndex(index)->ident());
+            }
+
+            if (m_ui->onFinalCheckbox->isChecked()) {
+                opt->addOption("glideslope", "3.0");
+                opt->addOption("offset-distance", "10.0"); // in nautical miles
+            }
+        } else if (m_ui->parkingRadio->isChecked()) {
+            // parking selection
+            opt->addOption("parkpos", m_ui->parkingCombo->currentText().toStdString());
+        }
+        // of location is an airport
+    }
+
+    FGPositioned::Type ty = m_location->type();
+    switch (ty) {
+    case FGPositioned::VOR:
+    case FGPositioned::NDB:
+    case FGPositioned::FIX:
+        // set disambiguation property
+        globals->get_props()->setIntValue("/sim/presets/navaid-id",
+                                          static_cast<int>(m_location->guid()));
+
+        // we always set 'fix', but really this is just to force positionInit
+        // code to check for the navaid-id value above.
+        opt->addOption("fix", m_location->ident());
+        break;
+    default:
+        break;
+    }
+}
+
 void QtLauncher::onApply()
 {
     accept();
@@ -951,8 +997,7 @@ void QtLauncher::onSearchAirports()
         m_ui->searchStatusText->setText(QString("Searching for '%1'").arg(search));
         m_ui->locationStack->setCurrentIndex(2);
     } else if (m_airportsModel->rowCount(QModelIndex()) == 1) {
-        QString ident = m_airportsModel->firstIdent();
-        setAirport(FGAirport::findByIdent(ident.toStdString()));
+        setBaseLocation(m_airportsModel->itemAtRow(0));
         m_ui->locationStack->setCurrentIndex(0);
     }
 }
@@ -963,60 +1008,62 @@ void QtLauncher::onAirportSearchComplete()
     if (numResults == 0) {
         m_ui->searchStatusText->setText(QString("No matching airports for '%1'").arg(m_ui->airportEdit->text()));
     } else if (numResults == 1) {
-        QString ident = m_airportsModel->firstIdent();
-        setAirport(FGAirport::findByIdent(ident.toStdString()));
+        setBaseLocation(m_airportsModel->itemAtRow(0));
         m_ui->locationStack->setCurrentIndex(0);
     } else {
         m_ui->locationStack->setCurrentIndex(1);
     }
 }
 
-void QtLauncher::onAirportChanged()
+void QtLauncher::onLocationChanged()
 {
-    m_ui->runwayCombo->setEnabled(m_selectedAirport);
-    m_ui->parkingCombo->setEnabled(m_selectedAirport);
-    m_ui->airportDiagram->setAirport(m_selectedAirport);
+    bool locIsAirport = FGAirport::isAirportType(m_location.ptr());
+
+    m_ui->runwayCombo->setEnabled(locIsAirport);
+    m_ui->parkingCombo->setEnabled(locIsAirport);
+    if (locIsAirport) {
+        FGAirport* apt = static_cast<FGAirport*>(m_location.ptr());
+        m_ui->airportDiagram->setAirport(apt);
+
+        m_ui->runwayRadio->setChecked(true); // default back to runway mode
+        // unless multiplayer is enabled ?
+        m_ui->airportDiagram->setEnabled(true);
+
+        m_ui->runwayCombo->clear();
+        m_ui->runwayCombo->addItem("Automatic", -1);
+        for (unsigned int r=0; r<apt->numRunways(); ++r) {
+            FGRunwayRef rwy = apt->getRunwayByIndex(r);
+            // add runway with index as data role
+            m_ui->runwayCombo->addItem(QString::fromStdString(rwy->ident()), r);
+
+            m_ui->airportDiagram->addRunway(rwy);
+        }
 
-    m_ui->runwayRadio->setChecked(true); // default back to runway mode
-    // unelss multiplayer is enabled ?
+        m_ui->parkingCombo->clear();
+        FGAirportDynamics* dynamics = apt->getDynamics();
+        PositionedIDVec parkings = NavDataCache::instance()->airportItemsOfType(m_location->guid(),
+                                                                                FGPositioned::PARKING);
+        if (parkings.empty()) {
+            m_ui->parkingCombo->setEnabled(false);
+            m_ui->parkingRadio->setEnabled(false);
+        } else {
+            m_ui->parkingCombo->setEnabled(true);
+            m_ui->parkingRadio->setEnabled(true);
+            Q_FOREACH(PositionedID parking, parkings) {
+                FGParking* park = dynamics->getParking(parking);
+                m_ui->parkingCombo->addItem(QString::fromStdString(park->getName()),
+                                            static_cast<qlonglong>(parking));
+
+                m_ui->airportDiagram->addParking(park);
+            }
+        }
 
-    if (!m_selectedAirport) {
-        m_ui->airportDescription->setText(QString());
-        m_ui->airportDiagram->setEnabled(false);
-        return;
-    }
 
-    m_ui->airportDiagram->setEnabled(true);
+    } // of location is aiport
+
 
-    m_ui->runwayCombo->clear();
-    m_ui->runwayCombo->addItem("Automatic", -1);
-    for (unsigned int r=0; r<m_selectedAirport->numRunways(); ++r) {
-        FGRunwayRef rwy = m_selectedAirport->getRunwayByIndex(r);
-        // add runway with index as data role
-        m_ui->runwayCombo->addItem(QString::fromStdString(rwy->ident()), r);
 
-        m_ui->airportDiagram->addRunway(rwy);
-    }
 
-    m_ui->parkingCombo->clear();
-    FGAirportDynamics* dynamics = m_selectedAirport->getDynamics();
-    PositionedIDVec parkings = NavDataCache::instance()->airportItemsOfType(
-                                                                            m_selectedAirport->guid(),
-                                                                            FGPositioned::PARKING);
-    if (parkings.empty()) {
-        m_ui->parkingCombo->setEnabled(false);
-        m_ui->parkingRadio->setEnabled(false);
-    } else {
-        m_ui->parkingCombo->setEnabled(true);
-        m_ui->parkingRadio->setEnabled(true);
-        Q_FOREACH(PositionedID parking, parkings) {
-            FGParking* park = dynamics->getParking(parking);
-            m_ui->parkingCombo->addItem(QString::fromStdString(park->getName()),
-                                        static_cast<qlonglong>(parking));
-
-            m_ui->airportDiagram->addParking(park);
-        }
-    }
 }
 
 void QtLauncher::onOffsetRadioToggled(bool on)
@@ -1036,7 +1083,7 @@ void QtLauncher::onAirportDiagramClicked(FGRunwayRef rwy)
         m_ui->runwayCombo->setCurrentIndex(rwyIndex);
     }
 
-    updateAirportDescription();
+    updateLocationDescription();
 }
 
 void QtLauncher::onToggleTerrasync(bool enabled)
@@ -1095,17 +1142,18 @@ void QtLauncher::onAircraftInstallFailed(QModelIndex index, QString errorMessage
     maybeUpdateSelectedAircraft(index);
 }
 
-void QtLauncher::updateAirportDescription()
+void QtLauncher::updateLocationDescription()
 {
-    if (!m_selectedAirport) {
-        m_ui->airportDescription->setText(QString("No airport selected"));
+    if (!m_location) {
+        m_ui->airportDescription->setText(QString("No location selected"));
         return;
     }
 
-    QString ident = QString::fromStdString(m_selectedAirport->ident()),
-        name = QString::fromStdString(m_selectedAirport->name());
+    QString ident = QString::fromStdString(m_location->ident()),
+        name = QString::fromStdString(m_location->name());
     QString locationOnAirport;
     if (m_ui->runwayRadio->isChecked()) {
+        FGAirport* apt = static_cast<FGAirport*>(m_location.ptr());
         bool onFinal = m_ui->onFinalCheckbox->isChecked();
         int comboIndex = m_ui->runwayCombo->currentIndex();
         QString runwayName = (comboIndex == 0) ?
@@ -1120,7 +1168,7 @@ void QtLauncher::updateAirportDescription()
 
         int runwayIndex = m_ui->runwayCombo->itemData(comboIndex).toInt();
         FGRunwayRef rwy = (runwayIndex >= 0) ?
-            m_selectedAirport->getRunwayByIndex(runwayIndex) : FGRunwayRef();
+            apt->getRunwayByIndex(runwayIndex) : FGRunwayRef();
         m_ui->airportDiagram->setSelectedRunway(rwy);
     } else if (m_ui->parkingRadio->isChecked()) {
         locationOnAirport =  QString("at parking position %1").arg(m_ui->parkingCombo->currentText());
@@ -1132,7 +1180,7 @@ void QtLauncher::updateAirportDescription()
 void QtLauncher::onAirportChoiceSelected(const QModelIndex& index)
 {
     m_ui->locationStack->setCurrentIndex(0);
-    setAirport(FGPositioned::loadById<FGAirport>(index.data(Qt::UserRole).toULongLong()));
+    setBaseLocation(m_airportsModel->itemAtRow(index.row()));
 }
 
 void QtLauncher::onOffsetBearingTrueChanged(bool on)
@@ -1202,6 +1250,7 @@ void QtLauncher::onPopupAirportHistory()
         return;
     }
 
+#if 0
     QMenu m;
     Q_FOREACH(QString aptCode, m_recentAirports) {
         FGAirportRef apt = FGAirport::findByIdent(aptCode.toStdString());
@@ -1218,6 +1267,7 @@ void QtLauncher::onPopupAirportHistory()
         m_ui->airportEdit->clear();
         m_ui->locationStack->setCurrentIndex(0);
     }
+#endif
 }
 
 QModelIndex QtLauncher::proxyIndexForAircraftURI(QUrl uri) const
@@ -1261,14 +1311,15 @@ void QtLauncher::onPopupAircraftHistory()
     }
 }
 
-void QtLauncher::setAirport(FGAirportRef ref)
+void QtLauncher::setBaseLocation(FGPositionedRef ref)
 {
-    if (m_selectedAirport == ref)
+    if (m_location == ref)
         return;
 
-    m_selectedAirport = ref;
-    onAirportChanged();
+    m_location = ref;
+    onLocationChanged();
 
+#if 0
     if (ref.valid()) {
         // maintain the recent airport list
         QString icao = QString::fromStdString(ref->ident());
@@ -1284,8 +1335,9 @@ void QtLauncher::setAirport(FGAirportRef ref)
             }
         }
     }
+#endif
 
-    updateAirportDescription();
+    updateLocationDescription();
 }
 
 void QtLauncher::onEditRatingsFilter()
index 17f7a1c4ce514c35dd75907479e1c8d1fc480fc2..7eb6b38546cc31296efacdb25e4f6e9f020dc268 100644 (file)
@@ -66,7 +66,7 @@ private slots:
 
     void onSearchAirports();
 
-    void onAirportChanged();
+    void onLocationChanged();
 
     void onAirportChoiceSelected(const QModelIndex& index);
     void onAircraftSelected(const QModelIndex& index);
@@ -78,7 +78,7 @@ private slots:
 
     void onEditRatingsFilter();
 
-    void updateAirportDescription();
+    void updateLocationDescription();
     void updateSettingsSummary();
 
     void onAirportSearchComplete();
@@ -99,7 +99,8 @@ private slots:
     void onAircraftInstalledCompleted(QModelIndex index);
     void onAircraftInstallFailed(QModelIndex index, QString errorMessage);
 private:
-    void setAirport(FGAirportRef ref);
+    void setLocationOptions();
+    void setBaseLocation(FGPositionedRef ref);
 
     /**
      * Check if the passed index is the selected aircraft, and if so, refresh
@@ -122,11 +123,11 @@ private:
     AirportSearchModel* m_airportsModel;
     AircraftProxyModel* m_aircraftProxy;
     AircraftItemModel* m_aircraftModel;
-    FGAirportRef m_selectedAirport;
+    FGPositionedRef m_location;
 
     QUrl m_selectedAircraft;
     QList<QUrl> m_recentAircraft;
-    QStringList m_recentAirports;
+    QVector<PositionedID> m_recentAirports;
     QTimer* m_subsystemIdleTimer;
     bool m_inAppMode;
 
index 6acbe21597fa53cc95a40b6fba601cd726cfa07d..59000c10b5651fbca2af4506c3bbf7ef7d93d20b 100644 (file)
@@ -430,10 +430,16 @@ static bool fgSetPosFromCarrier( const string& carrier, const string& posid ) {
 }
 
 // Set current_options lon/lat given an airport id and heading (degrees)
-static bool fgSetPosFromFix( const string& id )
+static bool fgSetPosFromFix( const string& id, PositionedID guid )
 {
-  FGPositioned::TypeFilter fixFilter(FGPositioned::FIX);
-  FGPositioned* fix = FGPositioned::findFirstWithIdent(id, &fixFilter);
+    FGPositioned* fix = NULL;
+    if (guid != 0) {
+        fix = FGPositioned::loadById<FGPositioned>(guid);
+    } else {
+        FGPositioned::TypeFilter fixFilter(FGPositioned::FIX);
+        fix = FGPositioned::findFirstWithIdent(id, &fixFilter);
+    }
+
   if (!fix) {
     SG_LOG( SG_GENERAL, SG_ALERT, "Failed to locate fix = " << id );
     return false;
@@ -491,6 +497,10 @@ bool initPosition()
   string carrier = fgGetString("/sim/presets/carrier");
   string parkpos = fgGetString("/sim/presets/parkpos");
   string fix = fgGetString("/sim/presets/fix");
+
+  // the launcher sets this to precisely identify a navaid
+    PositionedID navaidId = fgGetInt("/sim/presets/navaid-id");
+
   SGPropertyNode *hdg_preset = fgGetNode("/sim/presets/heading-deg", true);
   double hdg = hdg_preset->getDoubleValue();
   
@@ -569,7 +579,7 @@ bool initPosition()
   
   if ( !set_pos && !fix.empty() ) {
     // a Fix is requested
-    if ( fgSetPosFromFix( fix ) ) {
+    if ( fgSetPosFromFix( fix, navaidId ) ) {
       set_pos = true;
     }
   }
index e18c382bc29e13607c2bf908f55918883ed2a3ef..4942b902dcf1005216fe549a9edaa6fecb5ef9af 100644 (file)
@@ -2325,7 +2325,7 @@ NavDataCache::ThreadedGUISearch::ThreadedGUISearch(const std::string& term) :
     sqlite3_open_v2(pathUtf8.c_str(), &d->db, openFlags, NULL);
 
     std::string sql = "SELECT rowid FROM positioned WHERE name LIKE '%" + term
-        + "%' AND type >= 1 AND type <= 3";
+        + "%' AND ((type >= 1 AND type <= 3) OR ((type >= 9 AND type <= 11))) ";
     sqlite3_prepare_v2(d->db, sql.c_str(), sql.length(), &d->query, NULL);
 
     d->start();
index 012edb0b18d0ae7cda9c3e556d09942eab726bd2..59b23b1dd8c7b453f7818f28a955566bba540353 100644 (file)
@@ -1,4 +1,4 @@
-// positioned.hxx - base class for objects which are positioned 
+// positioned.hxx - base class for objects which are positioned
 //
 // Copyright (C) 2008 James Turner
 //