]> git.mxchange.org Git - flightgear.git/commitdiff
Navaid diagram for launcher
authorJames Turner <zakalawe@mac.com>
Tue, 10 Nov 2015 22:54:57 +0000 (22:54 +0000)
committerJames Turner <zakalawe@mac.com>
Mon, 23 Nov 2015 00:47:01 +0000 (00:47 +0000)
- work in progress, needs labels

23 files changed:
src/Airports/airport.cxx
src/Airports/airport.hxx
src/GUI/BaseDiagram.cxx
src/GUI/BaseDiagram.hxx
src/GUI/LocationWidget.cxx
src/GUI/LocationWidget.hxx
src/GUI/LocationWidget.ui
src/GUI/NavaidDiagram.cxx
src/GUI/QtLauncher.cxx
src/GUI/airport-icon.png [new file with mode: 0644]
src/GUI/airport-tower-icon.png [new file with mode: 0644]
src/GUI/heliport-icon.png [new file with mode: 0644]
src/GUI/large-search-icon.png [deleted file]
src/GUI/ndb-icon.png [new file with mode: 0644]
src/GUI/resources.qrc
src/GUI/seaport-icon.png [new file with mode: 0644]
src/GUI/seaport-tower-icon.png [new file with mode: 0644]
src/GUI/spinner.gif [new file with mode: 0644]
src/GUI/vor-dme-icon.png [new file with mode: 0644]
src/GUI/vor-icon.png [new file with mode: 0644]
src/GUI/vortac-icon.png [new file with mode: 0644]
src/GUI/waypoint-icon.png [new file with mode: 0644]
src/Main/positioninit.cxx

index 60a711bf567cf6d30d646754e602e9f7801134c9..ce8fd1a39edf8586b6bc3f746d50ec2af94f01dd 100644 (file)
@@ -76,6 +76,7 @@ FGAirport::FGAirport( PositionedID aGuid,
     _has_metar(has_metar),
     _dynamics(0),
     mTowerDataLoaded(false),
+    mHasTower(false),
     mRunwaysLoaded(false),
     mHelipadsLoaded(false),
     mTaxiwaysLoaded(false),
@@ -314,6 +315,20 @@ bool FGAirport::hasHardRunwayOfLengthFt(double aLengthFt) const
   return false;
 }
 
+FGRunwayRef FGAirport::longestRunway() const
+{
+    FGRunwayRef r;
+    loadRunways();
+
+    BOOST_FOREACH(FGRunwayRef rwy, mRunways) {
+        if (!r || (r->lengthFt() < rwy->lengthFt())) {
+             r = rwy;
+        }
+    } // of runways iteration
+
+    return r;
+}
+
 //------------------------------------------------------------------------------
 FGRunwayList FGAirport::getRunways() const
 {
@@ -663,13 +678,14 @@ void FGAirport::validateTowerData() const
   NavDataCache* cache = NavDataCache::instance();
   PositionedIDVec towers = cache->airportItemsOfType(guid(), FGPositioned::TOWER);
   if (towers.empty()) {
-    SG_LOG(SG_GENERAL, SG_ALERT, "No towers defined for:" <<ident());
+    mHasTower = false;
     mTowerPosition = geod(); // use airport position
     // increase tower elevation by 20 metres above the field elevation
     mTowerPosition.setElevationM(geod().getElevationM() + 20.0);
   } else {
     FGPositionedRef tower = cache->loadById(towers.front());
     mTowerPosition = tower->geod();
+    mHasTower = true;
   }
   
   SGPath path;
@@ -681,6 +697,7 @@ void FGAirport::validateTowerData() const
     SGPropertyNode_ptr rootNode = new SGPropertyNode;
     readProperties(path.str(), rootNode);
     const_cast<FGAirport*>(this)->readTowerData(rootNode);
+    mHasTower = true;
   } catch (sg_exception& e){
     SG_LOG(SG_NAVAID, SG_WARN, ident() << "loading twr XML failed:" << e.getFormattedMessage());
   }
@@ -723,6 +740,12 @@ void FGAirport::validateILSData()
   }
 }
 
+bool FGAirport::hasTower() const
+{
+    validateTowerData();
+    return mHasTower;
+}
+
 void FGAirport::readILSData(SGPropertyNode* aRoot)
 {  
   NavDataCache* cache = NavDataCache::instance();
index b9155d68dc5c6a799b7f6c8b01a6aa83bbbe7bc9..b585d19d84464df7a5b12adcb409ffc17cc687e9 100644 (file)
@@ -73,6 +73,8 @@ class FGAirport : public FGPositioned
      */
     void validateILSData();
 
+    bool hasTower() const;
+
     SGGeod getTowerLocation() const;
 
     void setMetar(bool value) { _has_metar = value; }
@@ -142,6 +144,8 @@ class FGAirport : public FGPositioned
      */
     bool hasHardRunwayOfLengthFt(double aLengthFt) const;
 
+    FGRunwayRef longestRunway() const;
+
     unsigned int numTaxiways() const;
     FGTaxiwayRef getTaxiwayByIndex(unsigned int aIndex) const;
     FGTaxiwayList getTaxiways() const;
@@ -319,6 +323,7 @@ private:
     void loadProcedures() const;
     
     mutable bool mTowerDataLoaded;
+    mutable bool mHasTower;
     mutable SGGeod mTowerPosition;
   
     mutable bool mRunwaysLoaded;
index ddc59f0adad11fa972113a982f43108414e63d6e..1c938a0a0b51d8199e3354b4d7b20a9f9e9e9af6 100644 (file)
 #include <QVector2D>
 #include <QMouseEvent>
 
+#include <Navaids/navrecord.hxx>
+#include <Navaids/positioned.hxx>
+#include <Airports/airport.hxx>
+
 /* equatorial and polar earth radius */
 const float rec  = 6378137;          // earth radius, equator (?)
 const float rpol = 6356752.314f;      // earth radius, polar   (?)
@@ -62,6 +66,21 @@ QTransform BaseDiagram::transform() const
     return t;
 }
 
+void BaseDiagram::extendRect(QRectF &r, const QPointF &p)
+{
+    if (p.x() < r.left()) {
+        r.setLeft(p.x());
+    } else if (p.x() > r.right()) {
+        r.setRight(p.x());
+    }
+
+    if (p.y() < r.top()) {
+        r.setTop(p.y());
+    } else if (p.y() > r.bottom()) {
+        r.setBottom(p.y());
+    }
+}
+
 void BaseDiagram::paintEvent(QPaintEvent* pe)
 {
     QPainter p(this);
@@ -79,9 +98,92 @@ void BaseDiagram::paintEvent(QPaintEvent* pe)
     QTransform t(transform());
     p.setTransform(t);
 
+    paintNavaids(&p);
+
     paintContents(&p);
 }
 
+class MapFilter : public FGPositioned::TypeFilter
+{
+public:
+    MapFilter()
+    {
+      //  addType(FGPositioned::FIX);
+        addType(FGPositioned::AIRPORT);
+        addType(FGPositioned::NDB);
+        addType(FGPositioned::VOR);
+    }
+
+    virtual bool pass(FGPositioned* aPos) const
+    {
+        bool ok = TypeFilter::pass(aPos);
+        if (ok && (aPos->type() == FGPositioned::FIX)) {
+            // ignore fixes which end in digits
+            if (aPos->ident().length() > 4 && isdigit(aPos->ident()[3]) && isdigit(aPos->ident()[4])) {
+                return false;
+            }
+        }
+
+        return ok;
+    }
+};
+
+
+void BaseDiagram::paintNavaids(QPainter* painter)
+{
+    QTransform xf = painter->transform();
+    painter->setTransform(QTransform()); // reset to identity
+    QTransform invT = xf.inverted();
+    SGGeod topLeft = unproject(invT.map(QPointF(0,0)), m_projectionCenter);
+
+    double minRunwayLengthFt = (16 / m_scale) * SG_METER_TO_FEET;
+    // add 10nm fudge factor
+    double drawRangeNm = SGGeodesy::distanceNm(m_projectionCenter, topLeft) + 10.0;
+    //qDebug() << "draw range computed as:" << drawRangeNm;
+
+    MapFilter f;
+    FGPositionedList items = FGPositioned::findWithinRange(m_projectionCenter, drawRangeNm, &f);
+
+    // pass 0 - icons
+
+    FGPositionedList::const_iterator it;
+    for (it = items.begin(); it != items.end(); ++it) {
+        bool drawAsIcon = true;
+
+        if ((*it)->type() == FGPositioned::AIRPORT) {
+            FGAirport* apt = static_cast<FGAirport*>(it->ptr());
+            if (apt->hasHardRunwayOfLengthFt(minRunwayLengthFt)) {
+
+                drawAsIcon = false;
+                painter->setTransform(xf);
+                QVector<QLineF> lines = projectAirportRuwaysWithCenter(apt, m_projectionCenter);
+
+                QPen pen(QColor(0x03, 0x83, 0xbf), 8);
+                pen.setCosmetic(true);
+                painter->setPen(pen);
+                painter->drawLines(lines);
+
+                QPen linePen(Qt::white, 2);
+                linePen.setCosmetic(true);
+                painter->setPen(linePen);
+                painter->drawLines(lines);
+
+                painter->resetTransform();
+            }
+        }
+
+        if (drawAsIcon) {
+            QPixmap pm = iconForPositioned(*it);
+            QPointF loc = xf.map(project((*it)->geod()));
+            loc -= QPointF(pm.width() >> 1, pm.height() >> 1);
+            painter->drawPixmap(loc, pm);
+        }
+    }
+
+    // restore transform
+    painter->setTransform(xf);
+}
+
 void BaseDiagram::mousePressEvent(QMouseEvent *me)
 {
     m_lastMousePos = me->pos();
@@ -132,9 +234,8 @@ void BaseDiagram::wheelEvent(QWheelEvent *we)
     update();
 }
 
-void BaseDiagram::paintContents(QPainter*)
+void BaseDiagram::paintContents(QPainter* painter)
 {
-
 }
 
 void BaseDiagram::recomputeBounds(bool resetZoom)
@@ -158,24 +259,14 @@ void BaseDiagram::doComputeBounds()
 
 void BaseDiagram::extendBounds(const QPointF& p)
 {
-    if (p.x() < m_bounds.left()) {
-        m_bounds.setLeft(p.x());
-    } else if (p.x() > m_bounds.right()) {
-        m_bounds.setRight(p.x());
-    }
-
-    if (p.y() < m_bounds.top()) {
-        m_bounds.setTop(p.y());
-    } else if (p.y() > m_bounds.bottom()) {
-        m_bounds.setBottom(p.y());
-    }
+    extendRect(m_bounds, p);
 }
 
-QPointF BaseDiagram::project(const SGGeod& geod) const
+QPointF BaseDiagram::project(const SGGeod& geod, const SGGeod& center)
 {
     double r = earth_radius_lat(geod.getLatitudeRad());
-    double ref_lat = m_projectionCenter.getLatitudeRad(),
-    ref_lon = m_projectionCenter.getLongitudeRad(),
+    double ref_lat = center.getLatitudeRad(),
+    ref_lon = center.getLongitudeRad(),
     lat = geod.getLatitudeRad(),
     lon = geod.getLongitudeRad(),
     lonDiff = lon - ref_lon;
@@ -206,3 +297,170 @@ QPointF BaseDiagram::project(const SGGeod& geod) const
 
     return QPointF(x, -y) * r;
 }
+
+SGGeod BaseDiagram::unproject(const QPointF& xy, const SGGeod& center)
+{
+    double r = earth_radius_lat(center.getLatitudeRad());
+    double lat = 0,
+           lon = 0,
+           ref_lat = center.getLatitudeRad(),
+           ref_lon = center.getLongitudeRad(),
+           rho = QVector2D(xy).length(),
+           c = rho/r;
+
+    if (rho == 0) {
+        return center;
+    }
+
+    double x = xy.x(), y = xy.y();
+    lat = asin( cos(c) * sin(ref_lat) + (y * sin(c) * cos(ref_lat)) / rho);
+
+    if (ref_lat == (90 * SG_DEGREES_TO_RADIANS)) // north pole
+    {
+        lon = ref_lon + atan(-x/y);
+    }
+    else if (ref_lat == -(90 * SG_DEGREES_TO_RADIANS)) // south pole
+    {
+        lon = ref_lon + atan(x/y);
+    }
+    else
+    {
+        lon = ref_lon + atan(x* sin(c) / (rho * cos(ref_lat) * cos(c) - y * sin(ref_lat) * sin(c)));
+    }
+
+    return SGGeod::fromRad(lon, lat);
+}
+
+QPointF BaseDiagram::project(const SGGeod& geod) const
+{
+    return project(geod, m_projectionCenter);
+}
+
+QPixmap BaseDiagram::iconForPositioned(const FGPositionedRef& pos)
+{
+    // if airport type, check towered or untowered
+
+    bool isTowered = false;
+    if (FGAirport::isAirportType(pos)) {
+        FGAirport* apt = static_cast<FGAirport*>(pos.ptr());
+        isTowered = apt->hasTower();
+    }
+
+    switch (pos->type()) {
+    case FGPositioned::VOR:
+        // check for VORTAC
+
+        if (static_cast<FGNavRecord*>(pos.ptr())->hasDME())
+            return QPixmap(":/vor-dme-icon");
+
+        return QPixmap(":/vor-icon");
+
+    case FGPositioned::AIRPORT:
+        return iconForAirport(static_cast<FGAirport*>(pos.ptr()));
+
+    case FGPositioned::HELIPORT:
+        return QPixmap(":/heliport-icon");
+    case FGPositioned::SEAPORT:
+        return QPixmap(isTowered ? ":/seaport-tower-icon" : ":/seaport-icon");
+    case FGPositioned::NDB:
+        return QPixmap(":/ndb-icon");
+    case FGPositioned::FIX:
+        return QPixmap(":/waypoint-icon");
+
+    default:
+        break;
+    }
+
+    return QPixmap();
+}
+
+QPixmap BaseDiagram::iconForAirport(FGAirport* apt)
+{
+    if (!apt->hasHardRunwayOfLengthFt(1500)) {
+        return QPixmap(apt->hasTower() ? ":/airport-tower-icon" : ":/airport-icon");
+    }
+
+    if (apt->hasHardRunwayOfLengthFt(8500)) {
+        QPixmap result(32, 32);
+        result.fill(Qt::transparent);
+        {
+            QPainter p(&result);
+            p.setRenderHint(QPainter::Antialiasing, true);
+            QRectF b = result.rect().adjusted(4, 4, -4, -4);
+            QVector<QLineF> lines = projectAirportRuwaysIntoRect(apt, b);
+
+            p.setPen(QPen(QColor(0x03, 0x83, 0xbf), 8));
+            p.drawLines(lines);
+
+            p.setPen(QPen(Qt::white, 2));
+            p.drawLines(lines);
+        }
+        return result;
+    }
+
+    QPixmap result(25, 25);
+    result.fill(Qt::transparent);
+
+    {
+        QPainter p(&result);
+        p.setRenderHint(QPainter::Antialiasing, true);
+        p.setPen(Qt::NoPen);
+
+        p.setBrush(apt->hasTower() ? QColor(0x03, 0x83, 0xbf) :
+                                     QColor(0x9b, 0x5d, 0xa2));
+        p.drawEllipse(QPointF(13, 13), 10, 10);
+
+        FGRunwayRef r = apt->longestRunway();
+
+        p.setPen(QPen(Qt::white, 2));
+        p.translate(13, 13);
+        p.rotate(r->headingDeg());
+        p.drawLine(0, -8, 0, 8);
+    }
+
+    return result;
+}
+
+QVector<QLineF> BaseDiagram::projectAirportRuwaysWithCenter(FGAirportRef apt, const SGGeod& c)
+{
+    QVector<QLineF> r;
+
+    const FGRunwayList& runways(apt->getRunwaysWithoutReciprocals());
+    FGRunwayList::const_iterator it;
+
+    for (it = runways.begin(); it != runways.end(); ++it) {
+        FGRunwayRef rwy = *it;
+        QPointF p1 = project(rwy->geod(), c);
+        QPointF p2 = project(rwy->end(), c);
+        r.append(QLineF(p1, p2));
+    }
+
+    return r;
+}
+
+QVector<QLineF> BaseDiagram::projectAirportRuwaysIntoRect(FGAirportRef apt, const QRectF &bounds)
+{
+    QVector<QLineF> r = projectAirportRuwaysWithCenter(apt, apt->geod());
+
+    QRectF extent;
+    Q_FOREACH(const QLineF& l, r) {
+        extendRect(extent, l.p1());
+        extendRect(extent, l.p2());
+    }
+
+ // find constraining scale factor
+    double ratioInX = bounds.width() / extent.width();
+    double ratioInY = bounds.height() / extent.height();
+
+    QTransform t;
+    t.translate(bounds.left(), bounds.top());
+    t.scale(std::min(ratioInX, ratioInY),
+            std::min(ratioInX, ratioInY));
+    t.translate(-extent.left(), -extent.top()); // move unscaled to 0,0
+
+    for (int i=0; i<r.size(); ++i) {
+        r[i] = t.map(r[i]);
+    }
+
+    return r;
+}
index 782344e83cf5d5c18ddd52c6d9990766f042ae1a..9ad65eb8483a9096c70cc24ddbee82c53ab4f0ef 100644 (file)
 
 #include <simgear/math/sg_geodesy.hxx>
 
+#include <Navaids/positioned.hxx>
+#include <Airports/airport.hxx>
+
 class BaseDiagram : public QWidget
 {
     Q_OBJECT
 public:
     BaseDiagram(QWidget* pr);
 
+    static QPixmap iconForPositioned(const FGPositionedRef &pos);
+    static QPixmap iconForAirport(FGAirport *apt);
 
-    
+    static QVector<QLineF> projectAirportRuwaysIntoRect(FGAirportRef apt, const QRectF& bounds);
+    static QVector<QLineF> projectAirportRuwaysWithCenter(FGAirportRef apt, const SGGeod &c);
 protected:
     virtual void paintEvent(QPaintEvent* pe);
 
@@ -60,6 +66,15 @@ protected:
     QPointF m_panOffset, m_lastMousePos;
     int m_wheelAngleDeltaAccumulator;
     bool m_didPan;
+
+    static void extendRect(QRectF& r, const QPointF& p);
+
+    static QPointF project(const SGGeod &geod, const SGGeod &center);
+
+    static SGGeod unproject(const QPointF &xy, const SGGeod &center);
+private:
+    void paintNavaids(QPainter *p);
+
 };
 
 #endif // of GUI_BASEDIAGRAM_HXX
index 0136103baa3af3043218416ef9f52cf9cdfae9fa..69723a1b58bcbacfebacb7ed8d770e08492be3f4 100644 (file)
@@ -26,6 +26,8 @@
 #include <QTimer>
 #include <QDebug>
 #include <QToolButton>
+#include <QMovie>
+#include <QPainter>
 
 #include "AirportDiagram.hxx"
 #include "NavaidDiagram.hxx"
@@ -202,6 +204,10 @@ public:
             }
         }
 
+        if (role == Qt::DecorationRole) {
+            return AirportDiagram::iconForPositioned(pos);
+        }
+
         if (role == Qt::EditRole) {
             return QString::fromStdString(pos->ident());
         }
@@ -228,7 +234,6 @@ Q_SIGNALS:
 
 private:
 
-
     void onSearchResultsPoll()
     {
         PositionedIDVec newIds = m_search->results();
@@ -267,7 +272,8 @@ LocationWidget::LocationWidget(QWidget *parent) :
     QIcon historyIcon(":/history-icon");
     m_ui->searchHistory->setIcon(historyIcon);
 
-    m_ui->searchIcon->setPixmap(QPixmap(":/search-icon"));
+    QByteArray format;
+    m_ui->searchIcon->setMovie(new QMovie(":/spinner", format, this));
 
     m_searchModel = new NavSearchModel;
     m_ui->searchResultsList->setModel(m_searchModel);
@@ -310,8 +316,9 @@ LocationWidget::LocationWidget(QWidget *parent) :
             this, SLOT(onOffsetDataChanged()));
 
     m_backButton = new QToolButton(this);
-    m_backButton->setGeometry(0, 0, 32, 32);
-    m_backButton->setIcon(QIcon(":/search-icon"));
+    m_backButton->setGeometry(0, 0, 64, 32);
+    m_backButton->setText("<< Back");
+    //m_backButton->setIcon(QIcon(":/search-icon"));
     m_backButton->raise();
 
     connect(m_backButton, &QAbstractButton::clicked,
@@ -374,6 +381,9 @@ void LocationWidget::setLocationOptions()
 {
     flightgear::Options* opt = flightgear::Options::sharedInstance();
 
+    std::string altStr = QString::number(m_ui->altitudeSpinbox->value()).toStdString();
+    std::string vcStr = QString::number(m_ui->airspeedSpinbox->value()).toStdString();
+
     if (m_locationIsLatLon) {
         // bypass the options mechanism because converting to deg:min:sec notation
         // just to parse back again is nasty.
@@ -381,6 +391,9 @@ void LocationWidget::setLocationOptions()
         fgSetDouble("/position/latitude-deg", m_geodLocation.getLatitudeDeg());
         fgSetDouble("/sim/presets/longitude-deg", m_geodLocation.getLongitudeDeg());
         fgSetDouble("/position/longitude-deg", m_geodLocation.getLongitudeDeg());
+
+        opt->addOption("altitude", altStr);
+        opt->addOption("vc", vcStr);
         return;
     }
 
@@ -396,35 +409,79 @@ void LocationWidget::setLocationOptions()
             int index = m_ui->runwayCombo->itemData(m_ui->runwayCombo->currentIndex()).toInt();
             if (index >= 0) {
                 // explicit runway choice
-                opt->addOption("runway", apt->getRunwayByIndex(index)->ident());
+                FGRunwayRef runway = apt->getRunwayByIndex(index);
+                opt->addOption("runway", runway->ident());
+
+                // set nav-radio 1 based on selected runway
+                if (runway->ILS()) {
+                    double mhz = runway->ILS()->get_freq() / 100.0;
+                    QString navOpt = QString("%1:%2").arg(runway->headingDeg()).arg(mhz);
+                    opt->addOption("nav1", navOpt.toStdString());
+                }
             }
 
             if (m_ui->onFinalCheckbox->isChecked()) {
                 opt->addOption("glideslope", "3.0");
-                opt->addOption("offset-distance", "10.0"); // in nautical miles
+                double offsetNm = m_ui->approachDistanceSpin->value();
+                opt->addOption("offset-distance", QString::number(offsetNm).toStdString());
             }
+
         } else if (m_ui->parkingRadio->isChecked()) {
             // parking selection
             opt->addOption("parkpos", m_ui->parkingCombo->currentText().toStdString());
         }
         // of location is an airport
-    }
+    } else {
+        // location is a navaid
+        // note setting the ident here is ambigious, we really only need and
+        // want the 'navaid-id' property. However setting the 'real' option
+        // gives a better UI experience (eg existing Position in Air dialog)
+        FGPositioned::Type ty = m_location->type();
+        switch (ty) {
+        case FGPositioned::VOR:
+            opt->addOption("vor", m_location->ident());
+            setNavRadioOption();
+            break;
+
+        case FGPositioned::NDB:
+            opt->addOption("ndb", m_location->ident());
+            setNavRadioOption();
+            break;
+
+        case FGPositioned::FIX:
+            opt->addOption("fix", m_location->ident());
+            break;
+        default:
+            break;
+        }
+
+        opt->addOption("altitude", altStr);
+        opt->addOption("vc", vcStr);
 
-    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 LocationWidget::setNavRadioOption()
+{
+    flightgear::Options* opt = flightgear::Options::sharedInstance();
+
+    if (m_location->type() == FGPositioned::VOR) {
+        FGNavRecordRef nav(static_cast<FGNavRecord*>(m_location.ptr()));
+        double mhz = nav->get_freq() / 100.0;
+        int heading = 0; // add heading support
+        QString navOpt = QString("%1:%2").arg(heading).arg(mhz);
+        opt->addOption("nav1", navOpt.toStdString());
+    } else {
+        FGNavRecordRef nav(static_cast<FGNavRecord*>(m_location.ptr()));
+        int khz = nav->get_freq() / 100;
+        int heading = 0;
+        QString adfOpt = QString("%1:%2").arg(heading).arg(khz);
+        qDebug() << "ADF opt is:" << adfOpt;
+        opt->addOption("adf1", adfOpt.toStdString());
     }
 }
 
@@ -446,7 +503,9 @@ void LocationWidget::onSearch()
 
     if (m_searchModel->isSearchActive()) {
         m_ui->searchStatusText->setText(QString("Searching for '%1'").arg(search));
+        qDebug() << "setting icon visible";
         m_ui->searchIcon->setVisible(true);
+        m_ui->searchIcon->movie()->start();
     } else if (m_searchModel->rowCount(QModelIndex()) == 1) {
         setBaseLocation(m_searchModel->itemAtRow(0));
     }
index dc99873374f89209eccd3452c73665a3a32ea91e..d6910d036cf38ddda4af16946dcb45492cf827e0 100644 (file)
@@ -88,6 +88,7 @@ private:
 
     void onOffsetEnabledToggled(bool on);
     void onBackToSearch();
+    void setNavRadioOption();
 };
 
 #endif // LOCATIONWIDGET_H
index 719fe1921d20d323da78189ac4376204d2c29252..f68766eeff0053925eb1ceb47cbf191c799cd4ad 100644 (file)
@@ -26,7 +26,7 @@
    <item>
     <widget class="QStackedWidget" name="stack">
      <property name="currentIndex">
-      <number>1</number>
+      <number>2</number>
      </property>
      <widget class="QWidget" name="airportPage">
       <layout class="QGridLayout" name="gridLayout" columnstretch="1,0,0,0">
      </widget>
      <widget class="QWidget" name="searchPage">
       <layout class="QVBoxLayout" name="verticalLayout_2">
+       <property name="spacing">
+        <number>2</number>
+       </property>
        <property name="leftMargin">
         <number>0</number>
        </property>
         </layout>
        </item>
        <item>
-        <layout class="QHBoxLayout" name="horizontalLayout">
+        <layout class="QHBoxLayout" name="horizontalLayout" stretch="1,0">
          <item>
           <widget class="QLabel" name="searchStatusText">
            <property name="text">
          </item>
          <item>
           <widget class="QLabel" name="searchIcon">
+           <property name="minimumSize">
+            <size>
+             <width>16</width>
+             <height>16</height>
+            </size>
+           </property>
            <property name="text">
             <string>TextLabel</string>
            </property>
index b31e881cdb391244302ded7c9cd8957ba73ee52f..fa6b78c2c241cae2377caa2b47a5baaa3623eb95 100644 (file)
@@ -82,8 +82,6 @@ void NavaidDiagram::paintContents(QPainter *painter)
         SGGeod offsetGeod = SGGeodesy::direct(m_geod, m_offsetBearingDeg, d);
         QPointF offset = project(offsetGeod);
 
-        qDebug() << base << offset;
-
         QPen pen(Qt::green);
         pen.setCosmetic(true);
         painter->setPen(pen);
index 1cd689d73252aa08550cc84f007e08890506e2ee..57f8be6f31cc4ee9b5a890cd66facdcb12b0c034 100644 (file)
@@ -787,6 +787,7 @@ void QtLauncher::onRun()
     bool startPaused = m_ui->startPausedCheck->isChecked() ||
             m_ui->location->shouldStartPaused();
     if (startPaused) {
+        qDebug() << "will start paused";
         opt->addOption("enable-freeze", "");
     }
 
diff --git a/src/GUI/airport-icon.png b/src/GUI/airport-icon.png
new file mode 100644 (file)
index 0000000..1d23061
Binary files /dev/null and b/src/GUI/airport-icon.png differ
diff --git a/src/GUI/airport-tower-icon.png b/src/GUI/airport-tower-icon.png
new file mode 100644 (file)
index 0000000..cb0be99
Binary files /dev/null and b/src/GUI/airport-tower-icon.png differ
diff --git a/src/GUI/heliport-icon.png b/src/GUI/heliport-icon.png
new file mode 100644 (file)
index 0000000..1607581
Binary files /dev/null and b/src/GUI/heliport-icon.png differ
diff --git a/src/GUI/large-search-icon.png b/src/GUI/large-search-icon.png
deleted file mode 100644 (file)
index 8ab5253..0000000
Binary files a/src/GUI/large-search-icon.png and /dev/null differ
diff --git a/src/GUI/ndb-icon.png b/src/GUI/ndb-icon.png
new file mode 100644 (file)
index 0000000..3d0fd3f
Binary files /dev/null and b/src/GUI/ndb-icon.png differ
index 4cbca391dae800ecbba192719207c288b21110e7..c48a7d40f75547735b770d4608992bc4d17bdef4 100644 (file)
@@ -1,9 +1,19 @@
 <RCC>
     <qresource prefix="/">
         <file alias="history-icon">history-icon.png</file>
-        <file alias="search-icon">large-search-icon.png</file>
         <file alias="right-arrow-icon">arrow-right-icon.png</file>
         <file alias="left-arrow-icon">arrow-left-icon.png</file>
         <file alias="app-icon-large">../../icons/128x128/apps/flightgear.png</file>
+        <file alias="spinner">spinner.gif</file>
+        <file alias="heliport-icon">heliport-icon.png</file>
+        <file alias="seaport-icon">seaport-icon.png</file>
+        <file alias="vor-icon">vor-icon.png</file>
+        <file alias="vortac-icon">vortac-icon.png</file>
+        <file alias="waypoint-icon">waypoint-icon.png</file>
+        <file alias="ndb-icon">ndb-icon.png</file>
+        <file alias="airport-icon">airport-icon.png</file>
+        <file alias="airport-tower-icon">airport-tower-icon.png</file>
+        <file alias="vor-dme-icon">vor-dme-icon.png</file>
+        <file alias="seaport-tower-icon">seaport-tower-icon.png</file>
     </qresource>
-</RCC>
\ No newline at end of file
+</RCC>
diff --git a/src/GUI/seaport-icon.png b/src/GUI/seaport-icon.png
new file mode 100644 (file)
index 0000000..61755fe
Binary files /dev/null and b/src/GUI/seaport-icon.png differ
diff --git a/src/GUI/seaport-tower-icon.png b/src/GUI/seaport-tower-icon.png
new file mode 100644 (file)
index 0000000..c1c0f76
Binary files /dev/null and b/src/GUI/seaport-tower-icon.png differ
diff --git a/src/GUI/spinner.gif b/src/GUI/spinner.gif
new file mode 100644 (file)
index 0000000..5b33f7e
Binary files /dev/null and b/src/GUI/spinner.gif differ
diff --git a/src/GUI/vor-dme-icon.png b/src/GUI/vor-dme-icon.png
new file mode 100644 (file)
index 0000000..e5e5a48
Binary files /dev/null and b/src/GUI/vor-dme-icon.png differ
diff --git a/src/GUI/vor-icon.png b/src/GUI/vor-icon.png
new file mode 100644 (file)
index 0000000..111b014
Binary files /dev/null and b/src/GUI/vor-icon.png differ
diff --git a/src/GUI/vortac-icon.png b/src/GUI/vortac-icon.png
new file mode 100644 (file)
index 0000000..e126420
Binary files /dev/null and b/src/GUI/vortac-icon.png differ
diff --git a/src/GUI/waypoint-icon.png b/src/GUI/waypoint-icon.png
new file mode 100644 (file)
index 0000000..173dd96
Binary files /dev/null and b/src/GUI/waypoint-icon.png differ
index 59000c10b5651fbca2af4506c3bbf7ef7d93d20b..681296687ba771a8732384586ff1cbcf992a685a 100644 (file)
@@ -353,37 +353,51 @@ static void fgSetDistOrAltFromGlideSlope() {
 
 
 // Set current_options lon/lat given an airport id and heading (degrees)
-static bool fgSetPosFromNAV( const string& id, const double& freq, FGPositioned::Type type )
+static bool fgSetPosFromNAV( const string& id,
+                             const double& freq,
+                             FGPositioned::Type type,
+                             PositionedID guid)
 {
-  FGNavList::TypeFilter filter(type);
-  const nav_list_type navlist = FGNavList::findByIdentAndFreq( id.c_str(), freq, &filter );
-  
-  if (navlist.empty()) {
-    SG_LOG( SG_GENERAL, SG_ALERT, "Failed to locate NAV = "
-           << id << ":" << freq );
-    return false;
-  }
-  
-  if( navlist.size() > 1 ) {
-    std::ostringstream buf;
-    buf << "Ambigous NAV-ID: '" << id << "'. Specify id and frequency. Available stations:" << endl;
-    for( nav_list_type::const_iterator it = navlist.begin(); it != navlist.end(); ++it ) {
-      // NDB stored in kHz, VOR stored in MHz * 100 :-P
-      double factor = (*it)->type() == FGPositioned::NDB ? 1.0 : 1/100.0;
-      string unit = (*it)->type() == FGPositioned::NDB ? "kHz" : "MHz";
-      buf << (*it)->ident() << " "
-      << std::setprecision(5) << (double)((*it)->get_freq() * factor) << " "
-      << (*it)->get_lat() << "/" << (*it)->get_lon()
-      << endl;
+    FGNavRecord* nav = 0;
+
+
+    if (guid != 0) {
+        nav = FGPositioned::loadById<FGNavRecord>(guid);
+        if (!nav)
+            return false;
+    } else {
+        FGNavList::TypeFilter filter(type);
+        const nav_list_type navlist = FGNavList::findByIdentAndFreq( id.c_str(), freq, &filter );
+
+        if (navlist.empty()) {
+          SG_LOG( SG_GENERAL, SG_ALERT, "Failed to locate NAV = "
+                 << id << ":" << freq );
+          return false;
+        }
+
+        if( navlist.size() > 1 ) {
+          std::ostringstream buf;
+          buf << "Ambigous NAV-ID: '" << id << "'. Specify id and frequency. Available stations:" << endl;
+          for( nav_list_type::const_iterator it = navlist.begin(); it != navlist.end(); ++it ) {
+            // NDB stored in kHz, VOR stored in MHz * 100 :-P
+            double factor = (*it)->type() == FGPositioned::NDB ? 1.0 : 1/100.0;
+            string unit = (*it)->type() == FGPositioned::NDB ? "kHz" : "MHz";
+            buf << (*it)->ident() << " "
+            << std::setprecision(5) << (double)((*it)->get_freq() * factor) << " "
+            << (*it)->get_lat() << "/" << (*it)->get_lon()
+            << endl;
+          }
+
+          SG_LOG( SG_GENERAL, SG_ALERT, buf.str() );
+          return false;
+        }
+
+        // nav list must be of length 1
+        nav = navlist[0];
     }
-    
-    SG_LOG( SG_GENERAL, SG_ALERT, buf.str() );
-    return false;
-  }
-  
-  FGNavRecord *nav = navlist[0];
-  fgApplyStartOffset(nav->geod(), fgGetDouble("/sim/presets/heading-deg"));
-  return true;
+
+    fgApplyStartOffset(nav->geod(), fgGetDouble("/sim/presets/heading-deg"));
+    return true;
 }
 
 // Set current_options lon/lat given an aircraft carrier id
@@ -429,7 +443,7 @@ static bool fgSetPosFromCarrier( const string& carrier, const string& posid ) {
   }
 }
 
-// Set current_options lon/lat given an airport id and heading (degrees)
+// Set current_options lon/lat given a fix ident and GUID
 static bool fgSetPosFromFix( const string& id, PositionedID guid )
 {
     FGPositioned* fix = NULL;
@@ -558,14 +572,14 @@ bool initPosition()
   
   if ( !set_pos && !vor.empty() ) {
     // a VOR is requested
-    if ( fgSetPosFromNAV( vor, vor_freq, FGPositioned::VOR ) ) {
+    if ( fgSetPosFromNAV( vor, vor_freq, FGPositioned::VOR, navaidId ) ) {
       set_pos = true;
     }
   }
   
   if ( !set_pos && !ndb.empty() ) {
     // an NDB is requested
-    if ( fgSetPosFromNAV( ndb, ndb_freq, FGPositioned::NDB ) ) {
+    if ( fgSetPosFromNAV( ndb, ndb_freq, FGPositioned::NDB, navaidId ) ) {
       set_pos = true;
     }
   }