From 2c175f57ae45b6eae3fc0eebafa45e5182a05adf Mon Sep 17 00:00:00 2001
From: James Turner <zakalawe@mac.com>
Date: Tue, 7 Dec 2010 10:33:14 +0000
Subject: [PATCH 1/5] Override puaComboBox recalc_bbox, ignore the popup-menu

---
 src/GUI/WaypointList.cxx |  1 +
 src/GUI/dialog.cxx       | 32 ++++++++++++++++++++++++++++++++
 src/GUI/dialog.hxx       |  5 ++++-
 src/GUI/layout.cxx       |  2 +-
 4 files changed, 38 insertions(+), 2 deletions(-)

diff --git a/src/GUI/WaypointList.cxx b/src/GUI/WaypointList.cxx
index 1c1014e03..31c5e480c 100644
--- a/src/GUI/WaypointList.cxx
+++ b/src/GUI/WaypointList.cxx
@@ -818,6 +818,7 @@ void ScrolledWaypointList::setScrollPercent(float v)
 void ScrolledWaypointList::setSize(int w, int h)
 {
   updateWantsScroll(w, h);
+  puGroup::setSize(w, h);
 }
 
 void ScrolledWaypointList::updateWantsScroll(int w, int h)
diff --git a/src/GUI/dialog.cxx b/src/GUI/dialog.cxx
index 71852fbc7..8a4160499 100644
--- a/src/GUI/dialog.cxx
+++ b/src/GUI/dialog.cxx
@@ -1376,4 +1376,36 @@ int fgComboBox::checkHit(int b, int up, int x, int y)
   return r;
 }
 
+void fgComboBox::setSize(int w, int h)
+{
+  puaComboBox::setSize(w, h);
+  recalc_bbox();
+}
+
+void fgComboBox::recalc_bbox()
+{
+// bug-fix for issue #192
+// http://code.google.com/p/flightgear-bugs/issues/detail?id=192
+// puaComboBox is including the height of its popupMenu in the height
+// computation, which breaks layout computations.
+// this implementation skips popup-menus
+  
+  puBox contents;
+  contents.empty();
+  
+  for (puObject *bo = dlist; bo != NULL; bo = bo -> getNextObject()) {
+    if (bo->getType() & PUCLASS_POPUPMENU) {
+      continue;
+    }
+    
+    contents.extend (bo -> getBBox()) ;
+  }
+  
+  abox.max[0] = abox.min[0] + contents.max[0] ;
+  abox.max[1] = abox.min[1] + contents.max[1] ;
+
+  puObject::recalc_bbox () ;
+
+}
+
 // end of dialog.cxx
diff --git a/src/GUI/dialog.hxx b/src/GUI/dialog.hxx
index 10739280d..497e07104 100644
--- a/src/GUI/dialog.hxx
+++ b/src/GUI/dialog.hxx
@@ -266,8 +266,11 @@ public:
         
     void update();
     
+    virtual void setSize(int w, int h);
+    
     virtual int checkHit(int b, int up, int x, int y);
-
+    
+    virtual void recalc_bbox();
 private:
     bool _inHit;
 };
diff --git a/src/GUI/layout.cxx b/src/GUI/layout.cxx
index f9581b3d5..b6fa5ab8f 100644
--- a/src/GUI/layout.cxx
+++ b/src/GUI/layout.cxx
@@ -80,7 +80,7 @@ void LayoutWidget::calcPrefSize(int* w, int* h)
         if(getBool("vertical")) *w = 4*UNIT;
         else                    *h = 4*UNIT;
     } else if (isType("list") || isType("airport-list")
-            || isType("property-list") || isType("dial")) {
+            || isType("property-list") || isType("dial") || isType("waypointlist")) {
         *w = *h = 12*UNIT;
     } else if (isType("hrule")) {
         *h = 1;

From d2bbaa69e07aafb157d58a84f2eb8d83eea51b73 Mon Sep 17 00:00:00 2001
From: James Turner <zakalawe@mac.com>
Date: Tue, 7 Dec 2010 17:55:45 +0000
Subject: [PATCH 2/5] Change how ils.xml data is loaded, to reduce impact on
 startup time.

---
 src/Navaids/navdb.cxx     | 61 +++++++++++++++++++++++++++++++++++++++
 src/Navaids/navdb.hxx     |  7 +++++
 src/Navaids/navrecord.cxx | 37 ++++--------------------
 3 files changed, 73 insertions(+), 32 deletions(-)

diff --git a/src/Navaids/navdb.cxx b/src/Navaids/navdb.cxx
index 4f7c10e7f..96d38c153 100644
--- a/src/Navaids/navdb.cxx
+++ b/src/Navaids/navdb.cxx
@@ -34,6 +34,7 @@
 #include <simgear/misc/sg_path.hxx>
 #include <simgear/structure/exception.hxx>
 #include <simgear/misc/sgstream.hxx>
+#include <simgear/props/props_io.hxx>
 
 #include "navrecord.hxx"
 #include "navlist.hxx"
@@ -41,9 +42,16 @@
 #include <Main/globals.hxx>
 #include <Navaids/markerbeacon.hxx>
 #include <Airports/simple.hxx>
+#include <Airports/runways.hxx>
+#include <Airports/xmlloader.hxx>
+#include <Main/fg_props.hxx>
 
 using std::string;
 
+typedef std::map<FGAirport*, SGPropertyNode_ptr> AirportPropertyMap;
+
+static AirportPropertyMap static_airportIlsData;
+
 static FGPositioned::Type
 mapRobinTypeToFGPType(int aTy)
 {
@@ -223,9 +231,62 @@ bool fgNavDBInit( FGNavList *navlist, FGNavList *loclist, FGNavList *gslist,
  // end ReadChanFile
 
 
+  // flush all the parsed ils.xml data, we don't need it anymore,
+  // since it's been meregd into the FGNavRecords
+    static_airportIlsData.clear();
+
     return true;
 }
 
+SGPropertyNode* ilsDataForRunwayAndNavaid(FGRunway* aRunway, const std::string& aNavIdent)
+{
+  if (!fgGetBool("/sim/paths/use-custom-scenery-data")) {
+    return NULL; 
+  }
+  
+  if (!aRunway) {
+    return NULL;
+  }
+  
+  FGAirport* apt = aRunway->airport();
+// find (or load) the airprot ILS data
+  AirportPropertyMap::iterator it = static_airportIlsData.find(apt);
+  if (it == static_airportIlsData.end()) {
+    SGPath path;
+    if (!XMLLoader::findAirportData(apt->ident(), "ils", path)) {
+    // no ils.xml file for this airpot, insert a NULL entry so we don't
+    // check again
+      static_airportIlsData.insert(it, std::make_pair(apt, SGPropertyNode_ptr()));
+      return NULL;
+    }
+    
+    SGPropertyNode_ptr rootNode = new SGPropertyNode;
+    readProperties(path.str(), rootNode);
+    it = static_airportIlsData.insert(it, std::make_pair(apt, rootNode));
+  } // of ils.xml file not loaded
+  
+  if (!it->second) {
+    return NULL;
+  }
+  
+// find the entry matching the runway
+  SGPropertyNode* runwayNode, *ilsNode;
+  for (int i=0; (runwayNode = it->second->getChild("runway", i)) != NULL; ++i) {
+    for (int j=0; (ilsNode = runwayNode->getChild("ils", j)) != NULL; ++j) {
+      // must match on both nav-ident and runway ident, to support the following:
+      // - runways with multiple distinct ILS installations (KEWD, for example)
+      // - runways where both ends share the same nav ident (LFAT, for example)
+      if ((ilsNode->getStringValue("nav-id") == aNavIdent) &&
+          (ilsNode->getStringValue("rwy") == aRunway->ident())) 
+      {
+        return ilsNode;
+      }
+    } // of ILS iteration
+  } // of runway iteration
+
+  return NULL;
+}
+
 FGRunway* getRunwayFromName(const std::string& aName)
 {
   vector<string> parts = simgear::strutils::split(aName);
diff --git a/src/Navaids/navdb.hxx b/src/Navaids/navdb.hxx
index 5c2aa117c..a4aa9be1b 100644
--- a/src/Navaids/navdb.hxx
+++ b/src/Navaids/navdb.hxx
@@ -37,6 +37,13 @@ bool fgNavDBInit( FGNavList *navlist, FGNavList *loclist, FGNavList *gslist,
                   FGTACANList *channellist );
 
 
+/**
+ * Return the property node corresponding to the runway ILS installation,
+ * from the Airports/I/C/A/ICAO.ils.xml file (loading it if necessary)
+ * returns NULL is no ILS data is defined for the runway.
+ */
+SGPropertyNode* ilsDataForRunwayAndNavaid(FGRunway* aRunway, const std::string& aNavIdent);
+
 /**
  * Helper to map a nav.data name (eg 'KBWI 33R GS') into a FGRunway reference.
  * returns NULL, and complains loudly, if the airport/runway is not found.
diff --git a/src/Navaids/navrecord.cxx b/src/Navaids/navrecord.cxx
index a22bebb69..03317a57d 100644
--- a/src/Navaids/navrecord.cxx
+++ b/src/Navaids/navrecord.cxx
@@ -32,7 +32,7 @@
 #include <simgear/debug/logstream.hxx>
 #include <simgear/sg_inlines.h>
 #include <simgear/props/props.hxx>
-#include <simgear/props/props_io.hxx>
+
 
 #include <Navaids/navrecord.hxx>
 #include <Navaids/navdb.hxx>
@@ -97,7 +97,10 @@ void FGNavRecord::initAirportRelation()
   }
   
   if (type() != GS) {
-    readAirportSceneryData();
+    SGPropertyNode* ilsData = ilsDataForRunwayAndNavaid(mRunway, ident());
+    if (ilsData) {
+      processSceneryILS(ilsData);
+    }
   }
         
   // fudge elevation to the runway elevation if it's not specified
@@ -121,36 +124,6 @@ void FGNavRecord::initAirportRelation()
   }
 }
 
-void FGNavRecord::readAirportSceneryData()
-{
-  // allow users to disable the scenery data in the short-term
-  // longer term, this option can probably disappear
-  if (!fgGetBool("/sim/use-scenery-airport-data")) {
-    return; 
-  }
-  
-  SGPath path;
-  SGPropertyNode_ptr rootNode = new SGPropertyNode;
-  if (!XMLLoader::findAirportData(mRunway->airport()->ident(), "ils", path)) {
-    return;
-  }
-  
-  readProperties(path.str(), rootNode);
-  SGPropertyNode* runwayNode, *ilsNode;
-  for (int i=0; (runwayNode = rootNode->getChild("runway", i)) != NULL; ++i) {
-    for (int j=0; (ilsNode = runwayNode->getChild("ils", j)) != NULL; ++j) {
-      // must match on both nav-ident and runway ident, to support the following:
-      // - runways with multiple distinct ILS installations (KEWD, for example)
-      // - runways where both ends share the same nav ident (LFAT, for example)
-      if ((ilsNode->getStringValue("nav-id") == ident()) &&
-          (ilsNode->getStringValue("rwy") == mRunway->ident())) {
-        processSceneryILS(ilsNode);
-        return;
-      }
-    } // of ILS iteration
-  } // of runway iteration
-}
-
 void FGNavRecord::processSceneryILS(SGPropertyNode* aILSNode)
 {
   double hdgDeg = aILSNode->getDoubleValue("hdg-deg"),

From 340bb58579cbc767c2d89b141b0ccdb6cb281311 Mon Sep 17 00:00:00 2001
From: Torsten Dreyer <Torsten@t3r.de>
Date: Thu, 9 Dec 2010 09:08:49 +0100
Subject: [PATCH 3/5] Export the 2d cloudlayer transparency to the property
 tree

---
 src/Environment/environment_mgr.cxx | 17 ++++++++++++++++-
 src/Environment/environment_mgr.hxx |  2 ++
 2 files changed, 18 insertions(+), 1 deletion(-)

diff --git a/src/Environment/environment_mgr.cxx b/src/Environment/environment_mgr.cxx
index 7b276eb62..4d05fab29 100644
--- a/src/Environment/environment_mgr.cxx
+++ b/src/Environment/environment_mgr.cxx
@@ -156,7 +156,9 @@ FGEnvironmentMgr::bind ()
         &FGEnvironmentMgr::get_cloud_layer_visibility_m,
         &FGEnvironmentMgr::set_cloud_layer_visibility_m);
 
-
+    _tiedProperties.Tie( layerNode->getNode( "alpha",true), this, i,
+        &FGEnvironmentMgr::get_cloud_layer_maxalpha,
+        &FGEnvironmentMgr::set_cloud_layer_maxalpha);
   }
 
   _tiedProperties.setRoot( fgGetNode("/sim/rendering", true ) );
@@ -332,6 +334,19 @@ FGEnvironmentMgr::set_cloud_layer_visibility_m (int index, double visibility_m)
     thesky->get_cloud_layer(index)->setVisibility_m(visibility_m);
 }
 
+double 
+FGEnvironmentMgr::get_cloud_layer_maxalpha (int index ) const
+{
+    return thesky->get_cloud_layer(index)->getMaxAlpha();
+}
+
+void 
+FGEnvironmentMgr::set_cloud_layer_maxalpha (int index, double maxalpha)
+{
+    thesky->get_cloud_layer(index)->setMaxAlpha(maxalpha);
+}
+
+
 
 
 void 
diff --git a/src/Environment/environment_mgr.hxx b/src/Environment/environment_mgr.hxx
index 7b5ad76cb..d9c770319 100644
--- a/src/Environment/environment_mgr.hxx
+++ b/src/Environment/environment_mgr.hxx
@@ -89,6 +89,8 @@ private:
   void set_cloud_layer_coverage_type (int index, int type );
   double get_cloud_layer_visibility_m (int index) const;
   void set_cloud_layer_visibility_m (int index, double visibility_m);
+  double get_cloud_layer_maxalpha (int index ) const;
+  void set_cloud_layer_maxalpha (int index, double maxalpha);
 
   FGEnvironment * _environment;	// always the same, for now
   FGClouds *fgClouds;

From 87daa1290aace4cdadcd775e7700650fb96cde43 Mon Sep 17 00:00:00 2001
From: Torsten Dreyer <Torsten@t3r.de>
Date: Thu, 9 Dec 2010 11:08:36 +0100
Subject: [PATCH 4/5] Improved fog/mist/haze creation from METAR

---
 src/Environment/metarproperties.cxx | 52 ++++++++++++++++++++---------
 1 file changed, 36 insertions(+), 16 deletions(-)

diff --git a/src/Environment/metarproperties.cxx b/src/Environment/metarproperties.cxx
index 23d16b59c..ea605d73a 100644
--- a/src/Environment/metarproperties.cxx
+++ b/src/Environment/metarproperties.cxx
@@ -239,26 +239,46 @@ void MetarProperties::set_metar( const char * metar )
         unsigned layerOffset = 0; // Oh, this is ugly!
         bool setGroundCloudLayer = _rootNode->getBoolValue("set-ground-cloud-layer", false );
 
-        if( setGroundCloudLayer && isFG ) {
-            // make sure fog actually starts at ground and set it's bottom at a constant
+        if( setGroundCloudLayer ) {
+            // create a cloud layer #0 starting at the ground if its fog, mist or haze
+
+            // make sure layer actually starts at ground and set it's bottom at a constant
             // value below the station's elevation
             const double LAYER_BOTTOM_BELOW_STATION_ELEVATION=200;
 
-            // fog - create a cloud layer #0 starting at the ground
+            SGMetarCloud::Coverage coverage = SGMetarCloud::COVERAGE_NIL;
+            double thickness = 0;
+            double alpha = 1.0;
+
+            if( isFG ) { // fog
+                coverage = isBC ? SGMetarCloud::COVERAGE_SCATTERED : SGMetarCloud::COVERAGE_BROKEN;
+                thickness = isMI ? 
+                   30 + LAYER_BOTTOM_BELOW_STATION_ELEVATION : // shallow fog, 10m/30ft
+                   500 + LAYER_BOTTOM_BELOW_STATION_ELEVATION; // fog, 150m/500ft
+                alpha = 1.0;
+
+            } else if( isBR ) { // mist
+                coverage = SGMetarCloud::COVERAGE_OVERCAST;
+                thickness = 2000 + LAYER_BOTTOM_BELOW_STATION_ELEVATION;
+                alpha = 0.8;
+            } else if( isHZ ) { // hase
+                coverage = SGMetarCloud::COVERAGE_OVERCAST;
+                thickness = 2000 + LAYER_BOTTOM_BELOW_STATION_ELEVATION;
+                alpha = 0.6;
+            }
             // fog is "overcast" by default of "broken" for patches of fog
-            SGPropertyNode_ptr layerNode = cloudsNode->getChild(LAYER, 0, true );
-            SGMetarCloud::Coverage coverage = isBC ? SGMetarCloud::COVERAGE_SCATTERED : SGMetarCloud::COVERAGE_BROKEN;
-            layerNode->setDoubleValue( "coverage-type", SGCloudLayer::getCoverageType(coverage_string[coverage]) );
-            layerNode->setStringValue( "coverage", coverage_string[coverage] );
-            layerNode->setDoubleValue( "elevation-ft", _station_elevation - LAYER_BOTTOM_BELOW_STATION_ELEVATION );
-            layerNode->setDoubleValue( "thickness-ft", isMI ? 
-               30 + LAYER_BOTTOM_BELOW_STATION_ELEVATION : // shallow fog, 10m/30ft
-               500 + LAYER_BOTTOM_BELOW_STATION_ELEVATION ); // fog, 150m/500ft
-            layerNode->setDoubleValue( "visibility-m", _min_visibility );
-            _min_visibility = _max_visibility = 20000.0; // assume good visibility above the fog
-            layerOffset = 1;  // shudder
-        } else if( setGroundCloudLayer && isHZ ) {
-        }
+            if( coverage != SGMetarCloud::COVERAGE_NIL ) {
+                SGPropertyNode_ptr layerNode = cloudsNode->getChild(LAYER, 0, true );
+                layerNode->setDoubleValue( "coverage-type", SGCloudLayer::getCoverageType(coverage_string[coverage]) );
+                layerNode->setStringValue( "coverage", coverage_string[coverage] );
+                layerNode->setDoubleValue( "elevation-ft", _station_elevation - LAYER_BOTTOM_BELOW_STATION_ELEVATION );
+                layerNode->setDoubleValue( "thickness-ft", thickness );
+                layerNode->setDoubleValue( "visibility-m", _min_visibility );
+                layerNode->setDoubleValue( "alpha", alpha );
+                _min_visibility = _max_visibility = 20000.0; // assume good visibility above the fog
+                layerOffset = 1;  // shudder
+            }
+        } 
 
         for( unsigned i = 0; i < 5-layerOffset; i++ ) {
             SGPropertyNode_ptr layerNode = cloudsNode->getChild(LAYER, i+layerOffset, true );

From b4478b56c9fa5b1d6dac32c37a48dc7de59c0de2 Mon Sep 17 00:00:00 2001
From: ThorstenB <brehmt@gmail.com>
Date: Thu, 9 Dec 2010 16:57:12 +0100
Subject: [PATCH 5/5] Issue #66: Non alphanumeric characters in callsign

---
 src/Main/options.cxx | 26 +++++++++++++++++++++++++-
 1 file changed, 25 insertions(+), 1 deletion(-)

diff --git a/src/Main/options.cxx b/src/Main/options.cxx
index 5604e2f98..8041e67df 100644
--- a/src/Main/options.cxx
+++ b/src/Main/options.cxx
@@ -1256,6 +1256,30 @@ fgOptFgviewer(const char* arg)
     return FG_OPTIONS_OK;
 }
 
+static int
+fgOptCallSign(const char * arg)
+{
+    int i;
+    char callsign[11];
+    strncpy(callsign,arg,10);
+    callsign[10]=0;
+    for (i=0;callsign[i];i++)
+    {
+        switch (callsign[i])
+        {
+            case 'A'...'Z':break;
+            case 'a'...'z':break;
+            case '0'...'9':break;
+            case '_':case '-':break;
+            default:
+                // convert any other illegal characters
+                callsign[i]='-';
+                break;
+        }
+    }
+    fgSetString("sim/multiplay/callsign", callsign );
+    return FG_OPTIONS_OK;
+}
 
 
 static map<string,size_t> fgOptionMap;
@@ -1440,7 +1464,7 @@ struct OptionDesc {
     {"joyclient",                    true,  OPTION_CHANNEL, "", false, "", 0 },
     {"jsclient",                     true,  OPTION_CHANNEL, "", false, "", 0 },
     {"proxy",                        true,  OPTION_FUNC,    "", false, "", fgSetupProxy },
-    {"callsign",                     true, OPTION_STRING,  "sim/multiplay/callsign", false, "", 0 },
+    {"callsign",                     true,  OPTION_FUNC,    "", false, "", fgOptCallSign},
     {"multiplay",                    true,  OPTION_CHANNEL, "", false, "", 0 },
     {"trace-read",                   true,  OPTION_FUNC,   "", false, "", fgOptTraceRead },
     {"trace-write",                  true,  OPTION_FUNC,   "", false, "", fgOptTraceWrite },