Changeset 10791 in ntrip


Ignore:
Timestamp:
Dec 3, 2025, 5:37:16 PM (4 weeks ago)
Author:
mervart
Message:

BNC Multifrequency and PPPAR Client (initial version)

Location:
trunk/BNC
Files:
10 added
48 edited

Legend:

Unmodified
Added
Removed
  • trunk/BNC/bnc.pro

    r9983 r10791  
    44TEMPLATE = subdirs
    55
    6 CONFIG += c++11
     6CONFIG += c++17
    77CONFIG += ordered
    88
  • trunk/BNC/newmat/bandmat.cpp

    r9434 r10791  
    2929#endif
    3030
    31 static inline int my_min(int x, int y) { return x < y ? x : y; }
    32 static inline int my_max(int x, int y) { return x > y ? x : y; }
     31////static inline int my_min(int x, int y) { return x < y ? x : y; }
     32////static inline int my_max(int x, int y) { return x > y ? x : y; }
    3333
    3434
     
    360360   // while (i--) { sum *= *a; a += w; }
    361361   if (i) for (;;) { sum *= *a; if (!(--i)) break; a += w; }
    362    if (!d) sum.ChangeSign(); return sum;
     362   if (!d) sum.ChangeSign();
     363   return sum;
    363364}
    364365
  • trunk/BNC/newmat/myexcept.cpp

    r9434 r10791  
    2121
    2222#include "myexcept.h"                  // for exception handling
     23#include "newmat.h"                  // for exception handling
    2324
    2425#ifdef use_namespace
     
    5152
    5253
    53 unsigned long BaseException::Select;
    54 char* BaseException::what_error;
    55 int BaseException::SoFar;
    56 int BaseException::LastOne;
    57 
    58 BaseException::BaseException(const char* a_what)
    59 {
    60    Select++; SoFar = 0;
    61    if (!what_error)                   // make space for exception message
    62    {
    63       LastOne = 511;
    64       what_error = new char[512];
    65       if (!what_error)                // fail to make space
    66       {
    67          LastOne = 0;
    68          what_error = (char *)"No heap space for exception message\n";
    69       }
    70    }
    71    AddMessage("\n\nAn exception has been thrown\n");
    72    AddMessage(a_what);
    73    if (a_what) Tracer::AddTrace();
    74 }
    75 
    76 void BaseException::AddMessage(const char* a_what)
    77 {
    78    if (a_what)
    79    {
    80       int l = strlen(a_what); int r = LastOne - SoFar;
    81       if (l < r) { strcpy(what_error+SoFar, a_what); SoFar += l; }
    82       else if (r > 0)
    83       {
    84          strncpy(what_error+SoFar, a_what, r);
    85          what_error[LastOne] = 0;
    86          SoFar = LastOne;
    87       }
    88    }
    89 }
    90 
    91 void BaseException::AddInt(int value)
    92 {
    93    bool negative;
    94    if (value == 0) { AddMessage("0"); return; }
    95    else if (value < 0) { value = -value; negative = true; }
    96    else negative = false;
    97    int n = 0; int v = value;        // how many digits will we need?
    98    while (v > 0) { v /= 10; n++; }
    99    if (negative) n++;
    100    if (LastOne-SoFar < n) { AddMessage("***"); return; }
    101 
    102    SoFar += n; n = SoFar; what_error[n] = 0;
    103    while (value > 0)
    104    {
     54BaseException::BaseException(const char* a_what) {
     55  _what = new char[MAXSIZE];
     56  if (!_what) {                // fail to make space
     57    _what = (char *)"No heap space for exception message\n";
     58    _deleteMe = false;
     59  }
     60  else {
     61    _deleteMe = true;
     62  }
     63  AddMessage("\n\nAn exception has been thrown\n");
     64  AddMessage(a_what);
     65}
     66
     67BaseException::BaseException(const BaseException& oth) {
     68  _what = new char[MAXSIZE];
     69  if (!_what) {                // fail to make space
     70    _what = (char *)"No heap space for exception message\n";
     71    _deleteMe = false;
     72  }
     73  else {
     74    _deleteMe = true;
     75    strcpy(_what, oth._what);
     76  }
     77}
     78 
     79BaseException& BaseException::operator=(const BaseException& oth) {
     80  if (this == &oth) return *this;
     81  _what = new char[MAXSIZE];
     82  if (!_what) {                // fail to make space
     83    _what = (char *)"No heap space for exception message\n";
     84    _deleteMe = false;
     85  }
     86  else {
     87    _deleteMe = true;
     88    strcpy(_what, oth._what);
     89  }
     90  return *this;
     91}
     92 
     93BaseException::~BaseException() {
     94  if (_deleteMe) delete[] _what;
     95}
     96
     97void BaseException::AddMessage(const char* a_what) {
     98  if (a_what) {
     99    size_t nn = MAXSIZE - strlen(_what) - 1;
     100    strncat(_what, a_what, nn);
     101  }
     102}
     103
     104void BaseException::AddInt(int value) {
     105  bool negative = false;
     106   if (value == 0) {
     107     AddMessage("0");
     108     return;
     109   }
     110   else if (value < 0) {
     111     value = -value;
     112     negative = true;
     113   }
     114   int nn = (negative ? 1 : 0); // how many digits will we need?
     115   int vv = value;       
     116   while (vv > 0) { vv /= 10; ++nn; }
     117   if ((int)(MAXSIZE - strlen(_what)) < nn) {
     118     AddMessage("***");
     119     return;
     120   }
     121
     122   nn += strlen(_what);
     123   _what[nn] = 0;
     124   while (value > 0) {
    105125      int nv = value / 10; int rm = value - nv * 10;  value = nv;
    106       what_error[--n] = (char)(rm + '0');
    107    }
    108    if (negative) what_error[--n] = '-';
    109    return;
    110 }
    111 
    112 void Tracer::PrintTrace()
    113 {
    114    cout << "\n";
    115    for (Tracer* et = last; et; et=et->previous)
    116       cout << "  * " << et->entry << "\n";
    117 }
    118 
    119 void Tracer::AddTrace()
    120 {
    121    if (last)
    122    {
    123       BaseException::AddMessage("Trace: ");
    124       BaseException::AddMessage(last->entry);
    125       for (Tracer* et = last->previous; et; et=et->previous)
    126       {
    127          BaseException::AddMessage("; ");
    128          BaseException::AddMessage(et->entry);
    129       }
    130       BaseException::AddMessage(".\n");
    131    }
    132 }
     126      _what[--nn] = (char)(rm + '0');
     127   }
     128   if (negative) _what[--nn] = '-';
     129}
     130
     131 
     132void BaseException::MatrixDetails(const GeneralMatrix& A)
     133{
     134   MatrixBandWidth bw = A.bandwidth();
     135   int ubw = bw.upper_val; int lbw = bw.lower_val;
     136   AddMessage("MatrixType = ");
     137   AddMessage(A.Type().Value());
     138   AddMessage("  # Rows = "); BaseException::AddInt(A.Nrows());
     139   AddMessage("; # Cols = "); BaseException::AddInt(A.Ncols());
     140   if (lbw >=0)
     141   {
     142      AddMessage("; lower BW = ");
     143      AddInt(lbw);
     144   }
     145   if (ubw >=0)
     146   {
     147      AddMessage("; upper BW = ");
     148      AddInt(ubw);
     149   }
     150   AddMessage("\n");
     151}
     152
    133153
    134154#ifdef SimulateExceptions
     
    230250{
    231251   cout << "\n\nThere has been an exception with no handler - exiting";
    232    const char* what = BaseException::what();
    233    if (what) cout << what << "\n";
    234252   exit(1);
    235253}
     
    479497
    480498
     499unsigned long BaseException::Select;
    481500unsigned long Logic_error::Select;
    482501unsigned long Runtime_error::Select;
  • trunk/BNC/newmat/myexcept.h

    r9434 r10791  
    6363
    6464class BaseException;
     65class GeneralMatrix;
    6566
    6667class Tracer                             // linked list showing how
    6768{                                        // we got here
    68    const char* entry;
    69    Tracer* previous;
    70 public:
    71    Tracer(const char*);
    72    ~Tracer();
    73    void ReName(const char*);
    74    static void PrintTrace();             // for printing trace
    75    static void AddTrace();               // insert trace in exception record
    76    static Tracer* last;                  // points to Tracer list
    77    friend class BaseException;
    78 };
    79 
    80 
    81 class BaseException                          // The base exception class
    82 {
    83 protected:
    84    static char* what_error;              // error message
    85    static int SoFar;                     // no. characters already entered
    86    static int LastOne;                   // last location in error buffer
    87 public:
    88    static void AddMessage(const char* a_what);
    89                                          // messages about exception
    90    static void AddInt(int value);        // integer to error message
    91    static unsigned long Select;          // for identifying exception
    92    BaseException(const char* a_what = 0);
    93    static const char* what() { return what_error; }
    94                                          // for getting error message
    95 };
    96 
     69public:
     70  Tracer(const char*) {};
     71  ~Tracer() {}
     72  void ReName(const char*) {}
     73  static void PrintTrace() {};             // for printing trace
     74  static void AddTrace() {};               // insert trace in exception record
     75  static Tracer* last;                  // points to Tracer list
     76};
     77
     78
     79class BaseException {                     // The base exception class
     80 protected:
     81  int    MAXSIZE = 512;
     82  char*  _what;                            // error message
     83  bool   _deleteMe;
     84 public:
     85  static unsigned long Select;
     86  BaseException(const char* a_what = 0);
     87  BaseException(const BaseException& oth);
     88  BaseException& operator=(const BaseException& oth);
     89  ~BaseException();
     90  void AddMessage(const char* a_what);
     91  void AddInt(int value);
     92  void MatrixDetails(const GeneralMatrix& A);
     93  const char* what() { return _what; }
     94};
     95
     96 
    9797#ifdef TypeDefException
    9898typedef BaseException Exception;        // for compatibility with my older libraries
    9999#endif
    100 
    101 inline Tracer::Tracer(const char* e)
    102    : entry(e), previous(last) { last = this; }
    103 
    104 inline Tracer::~Tracer() { last = previous; }
    105 
    106 inline void Tracer::ReName(const char* e) { entry=e; }
    107100
    108101#ifdef SimulateExceptions                // SimulateExceptions
  • trunk/BNC/newmat/newmat.h

    r9434 r10791  
    18341834   MatrixInput(const MatrixInput& mi) : n(mi.n), r(mi.r) {}
    18351835   MatrixInput(int nx, Real* rx) : n(nx), r(rx) {}
    1836    ~MatrixInput();
     1836  ~MatrixInput() noexcept(false);
    18371837   MatrixInput operator<<(double);
    18381838   MatrixInput operator<<(float);
  • trunk/BNC/newmat/newmat2.cpp

    r9434 r10791  
    3939   REPORT
    4040   int f = mrc.skip; int l = f + mrc.storage; int lx = skip + storage;
    41    if (f < skip) f = skip; if (l > lx) l = lx; l -= f;
     41   if (f < skip) f = skip;
     42   if (l > lx) l = lx;
     43   l -= f;
    4244   if (l<=0) return;
    4345   Real* elx=data+(f-skip); Real* el=mrc.data+(f-mrc.skip);
     
    5052   // THIS += (mrc * x)
    5153   int f = mrc.skip; int l = f + mrc.storage; int lx = skip + storage;
    52    if (f < skip) f = skip; if (l > lx) l = lx; l -= f;
     54   if (f < skip) f = skip;
     55   if (l > lx) l = lx;
     56   l -= f;
    5357   if (l<=0) return;
    5458   Real* elx=data+(f-skip); Real* el=mrc.data+(f-mrc.skip);
     
    6165   // THIS -= mrc
    6266   int f = mrc.skip; int l = f + mrc.storage; int lx = skip + storage;
    63    if (f < skip) f = skip; if (l > lx) l = lx; l -= f;
     67   if (f < skip) f = skip;
     68   if (l > lx) l = lx;
     69   l -= f;
    6470   if (l<=0) return;
    6571   Real* elx=data+(f-skip); Real* el=mrc.data+(f-mrc.skip);
     
    7278   REPORT
    7379   int f = mrc.skip; int l = f + mrc.storage; int lx = skip + storage;
    74    if (f < skip) f = skip; if (l > lx) l = lx; l -= f;
     80   if (f < skip) f = skip;
     81   if (l > lx) l = lx;
     82   l -= f;
    7583   if (l<=0) return;
    7684   Real* elx=data+(f-skip); Real* ely=mrc.data+(f-mrc.skip);
     
    8391   int f = mrc1.skip; int f2 = mrc2.skip;
    8492   int l = f + mrc1.storage; int l2 = f2 + mrc2.storage;
    85    if (f < f2) f = f2; if (l > l2) l = l2; l -= f;
     93   if (f < f2) f = f2;
     94   if (l > l2) l = l2;
     95   l -= f;
    8696   if (l<=0) return 0.0;
    8797
     
    97107   int f = skip; int l = skip + storage;
    98108   int f1 = mrc1.skip; int l1 = f1 + mrc1.storage;
    99    if (f1<f) f1=f; if (l1>l) l1=l;
     109   if (f1<f) f1=f;
     110   if (l1>l) l1=l;
    100111   int f2 = mrc2.skip; int l2 = f2 + mrc2.storage;
    101    if (f2<f) f2=f; if (l2>l) l2=l;
     112   if (f2<f) f2=f;
     113   if (l2>l) l2=l;
    102114   Real* el = data + (f-skip);
    103115   Real* el1 = mrc1.data+(f1-mrc1.skip); Real* el2 = mrc2.data+(f2-mrc2.skip);
     
    169181   int f = skip; int l = skip + storage;
    170182   int f1 = mrc1.skip; int l1 = f1 + mrc1.storage;
    171    if (f1<f) f1=f; if (l1>l) l1=l;
     183   if (f1<f) f1=f;
     184   if (l1>l) l1=l;
    172185   int f2 = mrc2.skip; int l2 = f2 + mrc2.storage;
    173    if (f2<f) f2=f; if (l2>l) l2=l;
     186   if (f2<f) f2=f;
     187   if (l2>l) l2=l;
    174188   Real* el = data + (f-skip);
    175189   Real* el1 = mrc1.data+(f1-mrc1.skip); Real* el2 = mrc2.data+(f2-mrc2.skip);
     
    333347   int f = skip; int l = skip + storage;
    334348   int f1 = mrc1.skip; int l1 = f1 + mrc1.storage;
    335    if (f1<f) f1=f; if (l1>l) l1=l;
     349   if (f1<f) f1=f;
     350   if (l1>l) l1=l;
    336351   int f2 = mrc2.skip; int l2 = f2 + mrc2.storage;
    337    if (f2<f) f2=f; if (l2>l) l2=l;
     352   if (f2<f) f2=f;
     353   if (l2>l) l2=l;
    338354   Real* el = data + (f-skip); int i;
    339    if (f1<f2) f1 = f2; if (l1>l2) l1 = l2;
     355   if (f1<f2) f1 = f2;
     356   if (l1>l2) l1 = l2;
    340357   if (l1<=f1) { REPORT i = l-f; while (i--) *el++ = 0.0; }  // disjoint
    341358   else
  • trunk/BNC/newmat/newmat3.cpp

    r9434 r10791  
    668668         Throw(InternalException("SymmetricBandMatrix::GetRow(MatrixRowCol&)"));
    669669      int w = w1+lower_val; s += w-ncols_val; Real* RowCopy;
    670       if (s>0) w -= s; mrc.storage = w; int w2 = w-w1;
     670      if (s>0) w -= s;
     671      mrc.storage = w;
     672      int w2 = w-w1;
    671673      if (!(mrc.cw*HaveStore))
    672674      {
     
    709711         Throw(InternalException("SymmetricBandMatrix::GetCol(MatrixRowCol&)"));
    710712      int w = w1+lower_val; s += w-ncols_val; Real* ColCopy;
    711       if (s>0) w -= s; mrc.storage = w; int w2 = w-w1;
     713      if (s>0) w -= s;
     714      mrc.storage = w;
     715      int w2 = w-w1;
    712716
    713717      if ( +(mrc.cw*HaveStore) ) { REPORT ColCopy = mrc.data; }
     
    759763
    760764      int w = w1+lower_val; s += w-ncols_val;
    761       if (s>0) w -= s; mrc.storage = w; int w2 = w-w1;
     765      if (s>0) w -= s;
     766      mrc.storage = w;
     767      int w2 = w-w1;
    762768
    763769      Real* ColCopy = mrc.data = mrc.store+mrc.skip;
  • trunk/BNC/newmat/newmat5.cpp

    r9434 r10791  
    488488   return MatrixInput(n, r+1);
    489489}
    490 MatrixInput::~MatrixInput()
     490MatrixInput::~MatrixInput() noexcept(false)
    491491{
    492492   REPORT
  • trunk/BNC/newmat/newmat6.cpp

    r9470 r10791  
    352352   // MatrixConversionCheck mcc;
    353353   Eq(X,MatrixType::Rt);
    354 }
     354} 
    355355
    356356void SquareMatrix::operator=(const BaseMatrix& X)
     
    429429   if (&gm == this) { REPORT tag_val = -1; return; }
    430430   REPORT
    431    if (indx) { delete [] indx; indx = 0; }
     431   if (indx != 0) { delete [] indx; indx = 0; }
    432432   ((CroutMatrix&)gm).get_aux(*this);
    433433   Eq(gm);
    434434}
    435 
     435   
    436436
    437437
  • trunk/BNC/newmat/newmat7.cpp

    r9434 r10791  
    545545         { REPORT AddDS(gm1,gm2); gm2->tDelete(); gmx = gm1; }
    546546      else if (c2 && gm2->reuse() )
    547          { REPORT AddDS(gm2,gm1); if (!c1) gm1->tDelete(); gmx = gm2; }
     547        { REPORT AddDS(gm2,gm1);
     548           if (!c1) gm1->tDelete();
     549           gmx = gm2;
     550        }
    548551      else
    549552      {
     
    552555         CatchAll
    553556         {
    554             if (!c1) gm1->tDelete(); if (!c2) gm2->tDelete();
     557            if (!c1) gm1->tDelete();
     558            if (!c2) gm2->tDelete();
    555559            ReThrow;
    556560         }
    557561         AddDS(gmx,gm1,gm2);
    558          if (!c1) gm1->tDelete(); if (!c2) gm2->tDelete();
     562         if (!c1) gm1->tDelete();
     563         if (!c2) gm2->tDelete();
    559564         gmx->ReleaseAndDelete();
    560565      }
     
    616621      {
    617622         REPORT ReverseSubtractDS(gm2,gm1);
    618          if (!c1) gm1->tDelete(); gmx = gm2;
     623         if (!c1) gm1->tDelete();
     624         gmx = gm2;
    619625      }
    620626      else
     
    625631         CatchAll
    626632         {
    627             if (!c1) gm1->tDelete(); if (!c2) gm2->tDelete();
     633            if (!c1) gm1->tDelete();
     634            if (!c2) gm2->tDelete();
    628635            ReThrow;
    629636         }
    630637         SubtractDS(gmx,gm1,gm2);
    631          if (!c1) gm1->tDelete(); if (!c2) gm2->tDelete();
     638         if (!c1) gm1->tDelete();
     639         if (!c2) gm2->tDelete();
    632640         gmx->ReleaseAndDelete();
    633641      }
     
    695703         CatchAll
    696704         {
    697             if (!c1) gm1->tDelete(); if (!c2) gm2->tDelete();
     705            if (!c1) gm1->tDelete();
     706            if (!c2) gm2->tDelete();
    698707            ReThrow;
    699708         }
    700709         SPDS(gmx,gm1,gm2);
    701          if (!c1) gm1->tDelete(); if (!c2) gm2->tDelete();
     710         if (!c1) gm1->tDelete();
     711         if (!c2) gm2->tDelete();
    702712         gmx->ReleaseAndDelete();
    703713      }
     
    779789   while (i--)
    780790   {
    781       if (*s1++ != *s2++) return false; if (*s1++ != *s2++) return false;
    782       if (*s1++ != *s2++) return false; if (*s1++ != *s2++) return false;
     791      if (*s1++ != *s2++) return false;
     792      if (*s1++ != *s2++) return false;
     793      if (*s1++ != *s2++) return false;
     794      if (*s1++ != *s2++) return false;
    783795   }
    784796   i = n & 3; while (i--) if (*s1++ != *s2++) return false;
     
    791803   while (i--)
    792804   {
    793       if (*s1++ != *s2++) return false; if (*s1++ != *s2++) return false;
    794       if (*s1++ != *s2++) return false; if (*s1++ != *s2++) return false;
     805      if (*s1++ != *s2++) return false;
     806      if (*s1++ != *s2++) return false;
     807      if (*s1++ != *s2++) return false;
     808      if (*s1++ != *s2++) return false;
    795809   }
    796810   i = n & 3; while (i--) if (*s1++ != *s2++) return false;
     
    869883   while (i--)
    870884   {
    871       if (*s++) return false; if (*s++) return false;
    872       if (*s++) return false; if (*s++) return false;
     885      if (*s++) return false;
     886      if (*s++) return false;
     887      if (*s++) return false;
     888      if (*s++) return false;
    873889   }
    874890   i = storage & 3; while (i--) if (*s++) return false;
  • trunk/BNC/newmat/newmat8.cpp

    r9434 r10791  
    713713      s += dd;
    714714   }
    715    if (!d) sum.ChangeSign(); return sum;
     715   if (!d) sum.ChangeSign();
     716   return sum;
    716717
    717718}
  • trunk/BNC/newmat/newmat9.cpp

    r9434 r10791  
    1515#include "newmatio.h"
    1616#include "newmatrc.h"
     17
     18#ifdef USE_STD_NAMESPACE
     19using namespace std;
     20#endif
    1721
    1822#ifdef use_namespace
     
    4448   MatrixRow mr((GeneralMatrix*)&X, LoadOnEntry);
    4549   int w = s.width();  int nr = X.Nrows();  ios_format_flags f = s.flags();
    46    s.setf(ios::fixed, ios::floatfield);
     50   /////s.setf(ios::fixed, ios::floatfield);
    4751   for (int i=1; i<=nr; i++)
    4852   {
  • trunk/BNC/newmat/newmatex.cpp

    r9434 r10791  
    2929
    3030
    31 static void MatrixDetails(const GeneralMatrix& A)
    32 // write matrix details to Exception buffer
    33 {
    34    MatrixBandWidth bw = A.bandwidth();
    35    int ubw = bw.upper_val; int lbw = bw.lower_val;
    36    BaseException::AddMessage("MatrixType = ");
    37    BaseException::AddMessage(A.Type().Value());
    38    BaseException::AddMessage("  # Rows = "); BaseException::AddInt(A.Nrows());
    39    BaseException::AddMessage("; # Cols = "); BaseException::AddInt(A.Ncols());
    40    if (lbw >=0)
    41    {
    42       BaseException::AddMessage("; lower BW = ");
    43       BaseException::AddInt(lbw);
    44    }
    45    if (ubw >=0)
    46    {
    47       BaseException::AddMessage("; upper BW = ");
    48       BaseException::AddInt(ubw);
    49    }
    50    BaseException::AddMessage("\n");
    51 }
     31////static void MatrixDetails(const GeneralMatrix& A)
     32////// write matrix details to Exception buffer
     33////{
     34////   MatrixBandWidth bw = A.bandwidth();
     35////   int ubw = bw.upper_val; int lbw = bw.lower_val;
     36////   BaseException::AddMessage("MatrixType = ");
     37////   BaseException::AddMessage(A.Type().Value());
     38////   BaseException::AddMessage("  # Rows = "); BaseException::AddInt(A.Nrows());
     39////   BaseException::AddMessage("; # Cols = "); BaseException::AddInt(A.Ncols());
     40////   if (lbw >=0)
     41////   {
     42////      BaseException::AddMessage("; lower BW = ");
     43////      BaseException::AddInt(lbw);
     44////   }
     45////   if (ubw >=0)
     46////   {
     47////      BaseException::AddMessage("; upper BW = ");
     48////      BaseException::AddInt(ubw);
     49////   }
     50////   BaseException::AddMessage("\n");
     51////}
    5252
    5353NPDException::NPDException(const GeneralMatrix& A)
  • trunk/BNC/newmat/newmatio.h

    r9434 r10791  
    1515
    1616#include "newmat.h"
     17#include <iostream>
    1718
    18 #ifdef USE_STD_NAMESPACE
    19 using namespace std;
     19#ifdef use_namespace
     20namespace NEWMAT {
    2021#endif
     22
     23
    2124
    2225// **************************** input/output *****************************/
    2326
    24 ostream& operator<<(ostream&, const BaseMatrix&);
     27std::ostream& operator<<(std::ostream&, const BaseMatrix&);
    2528
    26 ostream& operator<<(ostream&, const GeneralMatrix&);
     29std::ostream& operator<<(std::ostream&, const GeneralMatrix&);
    2730
    2831
  • trunk/BNC/src/PPP/pppClient.cpp

    r10765 r10791  
    117117//////////////////////////////////////////////////////////////////////////////
    118118void t_pppClient::putOrbCorrections(const vector<t_orbCorr*>& corr) {
     119  if (OPT->_logMode == t_pppOptions::normal && corr.size() > 0) {
     120    LOG << "orbCorrections " << string(corr[0]->_time) << ' ' << corr.size() << endl;
     121  }
    119122  for (unsigned ii = 0; ii < corr.size(); ii++) {
    120123    _ephPool->putOrbCorrection(new t_orbCorr(*corr[ii]));
     
    125128//////////////////////////////////////////////////////////////////////////////
    126129void t_pppClient::putClkCorrections(const vector<t_clkCorr*>& corr) {
     130  if (OPT->_logMode == t_pppOptions::normal && corr.size() > 0) {
     131    LOG << "clkCorrections " << string(corr[0]->_time) << ' ' << corr.size() << endl;
     132  }
    127133  for (unsigned ii = 0; ii < corr.size(); ii++) {
    128134    _ephPool->putClkCorrection(new t_clkCorr(*corr[ii]));
     
    133139//////////////////////////////////////////////////////////////////////////////
    134140void t_pppClient::putCodeBiases(const vector<t_satCodeBias*>& biases) {
     141  if (OPT->_logMode == t_pppOptions::normal && biases.size() > 0) {
     142    LOG << "codeBiases     " << string(biases[0]->_time) << ' ' << biases.size() << endl;
     143  }
     144  set<char> systems;
    135145  for (unsigned ii = 0; ii < biases.size(); ii++) {
    136     _obsPool->putCodeBias(new t_satCodeBias(*biases[ii]));
     146    t_satCodeBias* newBias = new t_satCodeBias(*biases[ii]);
     147    char sys = newBias->_prn.system();
     148    if (systems.find(sys) == systems.end()) {
     149      _obsPool->clearCodeBiases(sys);
     150      systems.insert(sys);
     151    }
     152    _obsPool->putCodeBias(newBias);
    137153  }
    138154}
     
    141157//////////////////////////////////////////////////////////////////////////////
    142158void t_pppClient::putPhaseBiases(const vector<t_satPhaseBias*>& biases) {
     159  if (OPT->_logMode == t_pppOptions::normal && biases.size() > 0) {
     160    LOG << "phaseBiases    " << string(biases[0]->_time) << ' ' << biases.size() << endl;
     161  }
     162  set<char> systems;
    143163  for (unsigned ii = 0; ii < biases.size(); ii++) {
    144     _obsPool->putPhaseBias(new t_satPhaseBias(*biases[ii]));
     164    t_satPhaseBias* newBias = new t_satPhaseBias(*biases[ii]);
     165    char sys = newBias->_prn.system();
     166    if (systems.find(sys) == systems.end()) {
     167      _obsPool->clearPhaseBiases(sys);
     168      systems.insert(sys);
     169    }
     170    _obsPool->putPhaseBias(newBias);
    145171  }
    146172}
     
    211237    }
    212238  }
    213 /*
    214   vector<t_pppSatObs*>::iterator it = obsVector.begin();
    215   while (it != obsVector.end()) {
    216     t_pppSatObs* satObs = *it;
    217     satObs->printObsMinusComputed();
    218     it++;
    219   }
    220 */
     239
     240  if (OPT->_logMode == t_pppOptions::all) {
     241    vector<t_pppSatObs*>::iterator it = obsVector.begin();
     242    while (it != obsVector.end()) {
     243      t_pppSatObs* satObs = *it;
     244      satObs->printObsMinusComputed();
     245      it++;
     246    }
     247  }
    221248  return pseudoObsIono;
    222249}
    223 
    224 //
    225 //////////////////////////////////////////////////////////////////////////////
    226 void t_pppClient::useObsWithCodeBiasesOnly(std::vector<t_pppSatObs*>& obsVector) {
    227 
    228   vector<t_pppSatObs*>::iterator it = obsVector.begin();
    229   while (it != obsVector.end()) {
    230     t_pppSatObs* pppSatObs = *it;
    231     bool codeBiasesAvailable = false;
    232     if (pppSatObs->getCodeBias(pppSatObs->fType1()) &&
    233         pppSatObs->getCodeBias(pppSatObs->fType2())) {
    234         codeBiasesAvailable = true;
    235     }
    236     if (codeBiasesAvailable) {
    237       ++it;
    238     }
    239     else {
    240       it = obsVector.erase(it);
    241       delete pppSatObs;
    242     }
    243   }
    244   return;
    245 }
    246 
    247250
    248251// Compute the Bancroft position, check for blunders
     
    251254                                  vector<t_pppSatObs*>& obsVector,
    252255                                  ColumnVector& xyzc, bool print) {
    253   t_lc::type tLC = t_lc::dummy;
     256
    254257  int  numBancroft = obsVector.size();
    255258
     
    259262    for (unsigned ii = 0; ii < obsVector.size(); ii++) {
    260263      const t_pppSatObs* satObs = obsVector.at(ii);
    261       if (tLC == t_lc::dummy) {
    262         if (satObs->isValid(t_lc::cIF)) {
    263           tLC = t_lc::cIF;
    264         }
    265         else if (satObs->isValid(t_lc::c1)) {
    266           tLC = t_lc::c1;
    267         }
    268         else if (satObs->isValid(t_lc::c2)) {
    269           tLC = t_lc::c2;
    270         }
    271       }
    272       if ( satObs->isValid(tLC) &&
     264      t_lc LC = satObs->rangeLC();
     265      if ( satObs->isValid(LC) &&
    273266          (!satObs->modelSet() || satObs->eleSat() >= _opt->_minEle) ) {
    274267        ++iObs;
     
    276269        BB[iObs][1] = satObs->xc()[1];
    277270        BB[iObs][2] = satObs->xc()[2];
    278         BB[iObs][3] = satObs->obsValue(tLC) - satObs->cmpValueForBanc(tLC);
     271        BB[iObs][3] = satObs->obsValue(LC) - satObs->cmpValueForBanc(LC);
    279272      }
    280273    }
     
    297290    for (unsigned ii = 0; ii < obsVector.size(); ii++) {
    298291      const t_pppSatObs* satObs = obsVector.at(ii);
    299       if (satObs->isValid() &&
     292      t_lc LC = satObs->rangeLC();
     293      if (satObs->isValid(LC) &&
    300294          (!satObs->modelSet() || satObs->eleSat() >= _opt->_minEle) ) {
    301295        ColumnVector rr = satObs->xc().Rows(1,3) - xyzc.Rows(1,3);
    302         double res = rr.NormFrobenius() - satObs->obsValue(tLC)
     296        double res = rr.NormFrobenius() - satObs->obsValue(LC)
    303297                   - (satObs->xc()[3] - xyzc[3]) * t_CST::c;
    304298        if (fabs(res) > maxRes) {
     
    354348//
    355349//////////////////////////////////////////////////////////////////////////////
    356 void t_pppClient::finish(t_irc irc, int ind) {
     350void t_pppClient::finish(t_irc irc, int /*ind*/) {
    357351#ifdef BNC_DEBUG_PPP
    358352  LOG << "t_pppClient::finish(" << ind << "): " << irc << endl;
     
    463457      }
    464458    }
    465     // use observations only if satellite code biases are available
    466     /* ------------------------------------------------------------
    467     if (!_opt->_corrMount.empty() {
    468         useObsWithCodeBiasesOnly(_obsRover);
    469     }*/
     459
     460    // Use observations only if satellite code biases are available
     461    // ------------------------------------------------------------
     462    if (_opt->ambRes()) {
     463      useObsWithBiasesOnly(_obsRover);
     464    }
    470465
    471466    if (int(_obsRover.size()) < _opt->_minObs) {
     
    613608
    614609}
     610
     611//
     612//////////////////////////////////////////////////////////////////////////////
     613void t_pppClient::useObsWithBiasesOnly(vector<t_pppSatObs*>& obsVector) const {
     614  vector<t_pppSatObs*>::iterator it = obsVector.begin();
     615  while (it != obsVector.end()) {
     616    t_pppSatObs* pppSatObs = *it;
     617    if (pppSatObs->hasBiases()) {
     618      ++it;
     619    }
     620    else {
     621      it = obsVector.erase(it);
     622      delete pppSatObs;
     623    }
     624  }
     625}
  • trunk/BNC/src/PPP/pppClient.h

    r10599 r10791  
    5252                   std::vector<t_pppSatObs*>& obsVector, bncTime& epoTime);
    5353  bool  preparePseudoObs(std::vector<t_pppSatObs*>& obsVector);
    54   void  useObsWithCodeBiasesOnly(std::vector<t_pppSatObs*>& obsVector);
    5554  t_irc cmpModel(t_pppStation* station, const ColumnVector& xyzc,
    5655                 std::vector<t_pppSatObs*>& obsVector);
     
    6160  double cmpOffGal(std::vector<t_pppSatObs*>& obsVector);
    6261  double cmpOffBds(std::vector<t_pppSatObs*>& obsVector);
    63 
     62  void   useObsWithBiasesOnly(std::vector<t_pppSatObs*>& obsVector) const;
    6463
    6564  t_output*                 _output;
     
    7574  t_tides*                  _tides;
    7675  bool                      _pseudoObsIono;
    77   QMap<char, int>           _usedSystems;
    7876  bool                      _running;
    7977};
  • trunk/BNC/src/PPP/pppEphPool.cpp

    r10330 r10791  
    1616
    1717#include <iostream>
     18#include <iomanip>
    1819#include "pppEphPool.h"
    1920#include "pppInclude.h"
     
    4142  if (corr) {
    4243    _satEphPool[corr->_prn.toInt()].putOrbCorrection(corr);
     44    if (OPT->_logMode > t_pppOptions::normal) {
     45      LOG << "orbCorr " << string(corr->_time) << ' ' << corr->_prn.toString() << endl;
     46    }
    4347  }
    4448}
     
    4953  if (corr) {
    5054    _satEphPool[corr->_prn.toInt()].putClkCorrection(corr);
     55    if (OPT->_logMode > t_pppOptions::normal) {
     56      LOG.setf(ios::fixed);
     57      LOG << "clkCorr " << string(corr->_time) << ' ' << corr->_prn.toString() << ' '
     58          << setw(7) << setprecision(3) << corr->_dClk * t_CST::c << endl;
     59    }
    5160  }
    5261}
  • trunk/BNC/src/PPP/pppFilter.cpp

    r10631 r10791  
    1616
    1717#include <iostream>
     18#include <sstream>
    1819#include <iomanip>
    1920#include <cmath>
     
    2829#include "pppStation.h"
    2930#include "pppClient.h"
     31#include "ambres.h"
    3032
    3133using namespace BNC_PPP;
     
    107109  }
    108110
    109   // close epoch processing
     111  // Dillution of Precision
    110112  // ----------------------
    111113  cmpDOP(allObs);
    112   _parlist->printResult(_epoTime, _QFlt, _xFlt);
     114 
     115  // Ambiguity Resolution
     116  // --------------------
     117  if (OPT->ambRes()) {
     118    AmbRes ambRes;
     119    ostringstream msg;
     120    ColumnVector    xFix     = _xFlt;
     121    SymmetricMatrix QFix     = _QFlt;
     122    double          fixRatio = 0.0;
     123    ambRes.run(_epoTime, _parlist->params(), QFix, xFix, fixRatio, msg);
     124    LOG << msg.str();
     125    _parlist->printResult(_epoTime, QFix, xFix, fixRatio);
     126  }
     127
     128  // Float Solution
     129  // --------------
     130  else {
     131    _parlist->printResult(_epoTime, _QFlt, _xFlt);
     132  }
     133
    113134  _lastEpoTimeOK = _epoTime; // remember time of last successful epoch processing
     135
    114136  return success;
    115137}
     
    117139// Process Selected LCs
    118140////////////////////////////////////////////////////////////////////////////
    119 t_irc t_pppFilter::processSystem(const vector<t_lc::type> &LCs,
     141t_irc t_pppFilter::processSystem(const vector<t_lc>& LCs,
    120142                                 const vector<t_pppSatObs*> &obsVector,
    121143                                 bool pseudoObsIonoAvailable) {
     
    158180    int iObs = -1;
    159181    vector<t_pppSatObs*> usedObs;
    160     vector<t_lc::type> usedTypes;
     182    vector<t_lc>        usedTypes;
    161183
    162184    // Real Observations
     
    171193        nSat++;
    172194        for (unsigned jj = 0; jj < usedLCs; jj++) {
    173           const t_lc::type tLC = LCs[jj];
    174           if (tLC == t_lc::GIM) {
     195          const t_lc LC = LCs[jj];
     196          if (LC._type == t_lc::GIM) {
     197            continue;
     198          }
     199          if (LC._frq1 == t_frequency::G5 && !obs->isValid(LC)) {
    175200            continue;
    176201          }
    177202          ++iObs;
    178203          usedObs.push_back(obs);
    179           usedTypes.push_back(tLC);
     204          usedTypes.push_back(LC);
    180205          for (unsigned iPar = 0; iPar < nPar; iPar++) {
    181206            const t_pppParam *par = params[iPar];
    182             AA[iObs][iPar] = par->partial(_epoTime, obs, tLC);
    183           }
    184 
    185           ll[iObs] = obs->obsValue(tLC) - obs->cmpValue(tLC) - DotProduct(_x0, AA.Row(iObs + 1));
    186           PP[iObs] = 1.0 / (obs->sigma(tLC) * obs->sigma(tLC));
     207            AA[iObs][iPar] = par->partial(_epoTime, obs, LC);
     208          }
     209
     210          ll[iObs] = obs->obsValue(LC) - obs->cmpValue(LC) - DotProduct(_x0, AA.Row(iObs + 1));
     211          PP[iObs] = 1.0 / (obs->sigma(LC) * obs->sigma(LC));
    187212        }
    188213      }
     
    202227        if (!obs->outlier()) {
    203228          for (unsigned jj = 0; jj < usedLCs; jj++) {
    204             const t_lc::type tLC = LCs[jj];
    205             if (tLC == t_lc::GIM) {
     229            const t_lc LC = LCs[jj];
     230            if (LC._type == t_lc::GIM) {
    206231              ++iObs;
    207232            } else {
     
    209234            }
    210235            usedObs.push_back(obs);
    211             usedTypes.push_back(tLC);
     236            usedTypes.push_back(LC);
    212237            for (unsigned iPar = 0; iPar < nPar; iPar++) {
    213238              const t_pppParam *par = params[iPar];
    214               AA[iObs][iPar] = par->partial(_epoTime, obs, tLC);
     239              AA[iObs][iPar] = par->partial(_epoTime, obs, LC);
    215240            }
    216             ll[iObs] = obs->obsValue(tLC) - obs->cmpValue(tLC) - DotProduct(_x0, AA.Row(iObs + 1));
    217             PP[iObs] = 1.0 / (obs->sigma(tLC) * obs->sigma(tLC));
     241            ll[iObs] = obs->obsValue(LC) - obs->cmpValue(LC) - DotProduct(_x0, AA.Row(iObs + 1));
     242            PP[iObs] = 1.0 / (obs->sigma(LC) * obs->sigma(LC));
    218243          }
    219244        }
     
    236261    double maxOutlier = 0.0;
    237262    int maxOutlierIndex = -1;
    238     t_lc::type maxOutlierLC = t_lc::dummy;
     263    t_lc maxOutlierLC;
    239264    for (unsigned ii = 0; ii < usedObs.size(); ii++) {
    240       const t_lc::type tLC = usedTypes[ii];
     265      const t_lc LC = usedTypes[ii];
    241266      double res = fabs(vv[ii]);
    242       if (res > usedObs[ii]->maxRes(tLC)) {
     267      if (res > usedObs[ii]->maxRes(LC)) {
    243268        if (res > fabs(maxOutlier)) {
    244269          maxOutlier = vv[ii];
    245270          maxOutlierIndex = ii;
    246           maxOutlierLC = tLC;
     271          maxOutlierLC = LC;
    247272        }
    248273      }
     
    254279      t_pppSatObs *obs = usedObs[maxOutlierIndex];
    255280      t_pppParam *par = 0;
    256       LOG << epoTimeStr << " Outlier " << t_lc::toString(maxOutlierLC) << ' '
     281      LOG << epoTimeStr << " Outlier " << maxOutlierLC.toString() << ' '
    257282          << obs->prn().toString() << ' ' << setw(8) << setprecision(4)
    258283          << maxOutlier << endl;
    259284      for (unsigned iPar = 0; iPar < nPar; iPar++) {
    260         t_pppParam *hlp = params[iPar];
     285        t_pppParam* hlp = params[iPar];
    261286        if (hlp->type() == t_pppParam::amb &&
    262287            hlp->prn()  == obs->prn() &&
    263             hlp->tLC()  == usedTypes[maxOutlierIndex]) {
     288            hlp->LC()   == usedTypes[maxOutlierIndex]) {
    264289          par = hlp;
    265290        }
     
    277302        for (unsigned jj = 0; jj < LCs.size(); jj++) {
    278303          for (unsigned ii = 0; ii < usedObs.size(); ii++) {
    279             const t_lc::type tLC = usedTypes[ii];
    280             t_pppSatObs *obs = usedObs[ii];
    281             if (tLC == LCs[jj]) {
    282               obs->setRes(tLC, vv[ii]);
     304            const t_lc LC = usedTypes[ii];
     305            t_pppSatObs* obs = usedObs[ii];
     306            if (LC == LCs[jj]) {
     307              obs->setRes(LC, vv[ii]);
    283308              LOG << epoTimeStr << " RES " << left << setw(3)
    284                   << t_lc::toString(tLC) << right << ' '
     309                  << LC.toString() << right << ' '
    285310                  << obs->prn().toString() << ' '
    286311                  << setw(8) << setprecision(4) << vv[ii] << endl;
     
    296321// Cycle-Slip Detection
    297322////////////////////////////////////////////////////////////////////////////
    298 t_irc t_pppFilter::detectCycleSlips(const vector<t_lc::type> &LCs,
     323t_irc t_pppFilter::detectCycleSlips(const vector<t_lc>& LCs,
    299324                                    const vector<t_pppSatObs*> &obsVector) {
    300325
     
    309334  SLIP *= fac;
    310335  string epoTimeStr = string(_epoTime);
    311   const vector<t_pppParam*> &params = _parlist->params();
    312336
    313337  for (unsigned ii = 0; ii < LCs.size(); ii++) {
    314     const t_lc::type &tLC = LCs[ii];
    315     if (t_lc::includesPhase(tLC)) {
     338    const t_lc& LC = LCs[ii];
     339    if (LC.includesPhase()) {
    316340      for (unsigned iObs = 0; iObs < obsVector.size(); iObs++) {
    317341        const t_pppSatObs *obs = obsVector[iObs];
     
    343367        // --------
    344368        if (slip) {
    345           resetAmb(obs->prn(), obsVector, tLC);
    346         }
    347 
    348         // Check Pre-Fit Residuals
    349         /* -----------------------
    350         else {
    351           ColumnVector AA(params.size());
    352           for (unsigned iPar = 0; iPar < params.size(); iPar++) {
    353             const t_pppParam* par = params[iPar];
    354             AA[iPar] = par->partial(_epoTime, obs, tLC);
    355           }
    356           double ll = obs->obsValue(tLC) - obs->cmpValue(tLC) - DotProduct(_x0, AA);
    357           double vv = DotProduct(AA, _xFlt) - ll;
    358 
    359           if (fabs(vv) > SLIP) {
    360             LOG << epoTimeStr << " cycle slip detected " << t_lc::toString(tLC) << ' '
    361                 << obs->prn().toString() << ' ' << setw(8) << setprecision(4) << vv << endl;
    362             resetAmb(obs->prn(), obsVector, tLC);
    363           }
    364         }*/
     369          resetAmb(obs->prn(), obsVector, t_lc());
     370        }
    365371      }
    366372    }
     
    371377// Reset Ambiguity Parameter (cycle slip)
    372378////////////////////////////////////////////////////////////////////////////
    373 t_irc t_pppFilter::resetAmb(const t_prn prn, const vector<t_pppSatObs*> &obsVector, t_lc::type lc,
     379t_irc t_pppFilter::resetAmb(const t_prn prn, const vector<t_pppSatObs*> &obsVector, t_lc lc,
    374380                            SymmetricMatrix *QSav, ColumnVector *xSav) {
    375381
     
    386392      (par->firstObsTime().undef()) ?
    387393        firstObsTime = lastObsTime : firstObsTime = par->firstObsTime();
    388       t_lc::type tLC = par->tLC();
    389       if (tLC != lc) {continue;}
     394      t_lc LC = par->LC();
     395      if (lc.valid() && LC != lc) {continue;}
    390396      LOG << string(_epoTime) << " RESET " << par->toString() << endl;
    391       delete par; par = new t_pppParam(t_pppParam::amb, prn, tLC, &obsVector);
     397      delete par; par = new t_pppParam(t_pppParam::amb, prn, LC, &obsVector);
    392398      par->setIndex(ind);
    393399      par->setFirstObsTime(firstObsTime);
     
    436442        for (unsigned iPar = 0; iPar < numPar; iPar++) {
    437443          t_pppParam* par = _parlist->params()[iPar];
    438           AA[_numSat - 1][iPar] = par->partial(_epoTime, obs, t_lc::c1);
     444          AA[_numSat - 1][iPar] = par->partial(_epoTime, obs, obs->rangeLC());
    439445          if      (par->type() == t_pppParam::crdX) {
    440446            parX = par;
  • trunk/BNC/src/PPP/pppFilter.h

    r10256 r10791  
    7373  };
    7474
    75   t_irc processSystem(const std::vector<t_lc::type>& LCs,
     75  t_irc processSystem(const std::vector<t_lc>& LCs,
    7676                      const std::vector<t_pppSatObs*>& obsVector,
    7777                      bool pseudoObsIonoAvailable);
    7878
    79   t_irc detectCycleSlips(const std::vector<t_lc::type>& LCs,
     79  t_irc detectCycleSlips(const std::vector<t_lc>& LCs,
    8080                         const std::vector<t_pppSatObs*>& obsVector);
    8181
    82   t_irc resetAmb(t_prn prn, const std::vector<t_pppSatObs*>& obsVector, t_lc::type lc,
     82  t_irc resetAmb(t_prn prn, const std::vector<t_pppSatObs*>& obsVector, t_lc lc,
    8383                 SymmetricMatrix* QSav = 0, ColumnVector* xSav = 0);
    8484
  • trunk/BNC/src/PPP/pppObsPool.cpp

    r10034 r10791  
    1515 * -----------------------------------------------------------------------*/
    1616
     17#include <iomanip>
    1718#include "pppObsPool.h"
     19#include "pppClient.h"
    1820
    1921using namespace BNC_PPP;
     
    7476  delete _satCodeBiases[iPrn];
    7577  _satCodeBiases[iPrn] = satCodeBias;
     78  if (OPT->_logMode > t_pppOptions::normal) {
     79    LOG << "codeBias " << string(satCodeBias->_time) << ' ' << satCodeBias->_prn.toString();
     80    for (const auto& bias : satCodeBias->_bias) {
     81      LOG << "  " << bias._rnxType2ch << ' ' << setw(7) << setprecision(3) << bias._value;
     82    }
     83    LOG << endl;
     84  }
    7685}
    7786
     
    8291  delete _satPhaseBiases[iPrn];
    8392  _satPhaseBiases[iPrn] = satPhaseBias;
     93  if (OPT->_logMode > t_pppOptions::normal) {
     94    LOG.setf(ios::fixed);
     95    LOG << "phaseBias " << string(satPhaseBias->_time) << ' ' << satPhaseBias->_prn.toString()
     96        << ' ' << setw(7) << setprecision(2) << satPhaseBias->_yaw     * 180.0 / M_PI
     97        << ' ' << setw(7) << setprecision(3) << satPhaseBias->_yawRate * 180.0 / M_PI;
     98    for (const auto& bias : satPhaseBias->_bias) {
     99      LOG << "  " << bias._rnxType2ch << ' ' << setw(2) << bias._jumpCounter;
     100      if (bias._fixIndicator) {
     101        LOG << " x ";
     102      }
     103      else {
     104        LOG << " . ";
     105      }
     106      LOG << setw(6) << setprecision(3) << bias._value;
     107    }
     108    LOG << endl;
     109  }
     110}
     111
     112//
     113/////////////////////////////////////////////////////////////////////////////
     114void t_pppObsPool::clearCodeBiases(char sys) {
     115  for (unsigned iPrn = 1; iPrn <= t_prn::MAXPRN; ++iPrn) {
     116    t_prn prn; prn.set(iPrn);
     117    if (prn.system() == sys) {
     118      delete _satCodeBiases[iPrn];
     119      _satCodeBiases[iPrn] = 0;
     120    }
     121  }
     122}
     123
     124//
     125/////////////////////////////////////////////////////////////////////////////
     126void t_pppObsPool::clearPhaseBiases(char sys) {
     127  for (unsigned iPrn = 1; iPrn <= t_prn::MAXPRN; ++iPrn) {
     128    t_prn prn; prn.set(iPrn);
     129    if (prn.system() == sys) {
     130      delete _satPhaseBiases[iPrn];
     131      _satPhaseBiases[iPrn] = 0;
     132    }
     133  }
    84134}
    85135
  • trunk/BNC/src/PPP/pppObsPool.h

    r10034 r10791  
    3333  void putPhaseBias(t_satPhaseBias* satPhaseBias);
    3434  void putTec(t_vTec* _vTec);
     35  void clearCodeBiases(char sys);
     36  void clearPhaseBiases(char sys);
    3537
    3638  void putEpoch(const bncTime& epoTime, std::vector<t_pppSatObs*>& obsVector,
  • trunk/BNC/src/PPP/pppParlist.cpp

    r10623 r10791  
    3434// Constructor
    3535////////////////////////////////////////////////////////////////////////////
    36 t_pppParam::t_pppParam(e_type type, const t_prn& prn, t_lc::type tLC,
     36t_pppParam::t_pppParam(e_type type, const t_prn& prn, t_lc LC,
    3737                       const vector<t_pppSatObs*>* obsVector) {
    3838
    3939  _type     = type;
    4040  _prn      = prn;
    41   _tLC      = tLC;
     41  _sys      = '?';
     42  _LC       = LC;
    4243  _x0       = 0.0;
    4344  _indexOld = -1;
     
    4748
    4849  switch (_type) {
    49    case crdX:
    50      _epoSpec = false;
    51      _sigma0  = OPT->_aprSigCrd[0];
    52      _noise   = OPT->_noiseCrd[0];
    53      break;
    54    case crdY:
    55      _epoSpec = false;
    56      _sigma0  = OPT->_aprSigCrd[1];
    57      _noise   = OPT->_noiseCrd[1];
    58      break;
    59    case crdZ:
    60      _epoSpec = false;
    61      _sigma0  = OPT->_aprSigCrd[2];
    62      _noise   = OPT->_noiseCrd[2];
    63      break;
    64    case rClkG:
    65      _epoSpec = true;
    66      _sigma0  = OPT->_aprSigClk;
    67      break;
    68    case rClkR:
    69      _epoSpec = true;
    70      _sigma0  = OPT->_aprSigClk;
    71      break;
    72    case rClkE:
    73      _epoSpec = true;
    74      _sigma0  = OPT->_aprSigClk;
    75      break;
    76    case rClkC:
    77      _epoSpec = true;
    78      _sigma0  = OPT->_aprSigClk;
    79      break;
    80    case amb:
    81      _epoSpec = false;
    82      _sigma0  = OPT->_aprSigAmb;
    83      if (obsVector) {
    84        for (unsigned ii = 0; ii < obsVector->size(); ii++) {
    85          const t_pppSatObs* obs = obsVector->at(ii);
    86          if (obs->prn() == _prn) {
    87            _x0 = floor((obs->obsValue(tLC) - obs->cmpValue(tLC)) / obs->lambda(tLC) + 0.5);
    88            break;
    89          }
    90        }
    91      }
    92      break;
    93    case trp:
    94      _epoSpec = false;
    95      _sigma0  = OPT->_aprSigTrp;
    96      _noise   = OPT->_noiseTrp;
    97      break;
    98     case ion:
    99       _epoSpec = false;
    100       _sigma0  = OPT->_aprSigIon;
    101       _noise   = OPT->_noiseIon;
    102      break;
    103     case cBiasG1:   case cBiasR1:   case cBiasE1:   case cBiasC1:
    104     case cBiasG2:   case cBiasR2:   case cBiasE2:   case cBiasC2:
    105       _epoSpec = false;
    106       _sigma0  = OPT->_aprSigCodeBias;
    107       _noise   = OPT->_noiseCodeBias;
    108       break;
    109     case pBiasG1:   case pBiasR1:   case pBiasE1:   case pBiasC1:
    110     case pBiasG2:   case pBiasR2:   case pBiasE2:   case pBiasC2:
    111       _epoSpec = false;
    112       _sigma0  = OPT->_aprSigPhaseBias;
    113       _noise   = OPT->_noisePhaseBias;
    114       break;
     50  case crdX:
     51    _epoSpec = false;
     52    _sigma0  = OPT->_aprSigCrd[0];
     53    _noise   = OPT->_noiseCrd[0];
     54    break;
     55  case crdY:
     56    _epoSpec = false;
     57    _sigma0  = OPT->_aprSigCrd[1];
     58    _noise   = OPT->_noiseCrd[1];
     59    break;
     60  case crdZ:
     61    _epoSpec = false;
     62    _sigma0  = OPT->_aprSigCrd[2];
     63    _noise   = OPT->_noiseCrd[2];
     64    break;
     65  case rClk:
     66    _epoSpec = true;
     67    _sigma0  = OPT->_aprSigClk;
     68    break;
     69  case amb:
     70    _epoSpec = false;
     71    _sigma0  = OPT->_aprSigAmb;
     72    if (obsVector) {
     73      for (unsigned ii = 0; ii < obsVector->size(); ii++) {
     74        const t_pppSatObs* obs = obsVector->at(ii);
     75        if (obs->prn() == _prn) {
     76          _x0 = floor((obs->obsValue(LC) - obs->cmpValue(LC)) / obs->lambda(LC) + 0.5);
     77          break;
     78        }
     79      }
     80    }
     81    break;
     82  case trp:
     83    _epoSpec = false;
     84    _sigma0  = OPT->_aprSigTrp;
     85    _noise   = OPT->_noiseTrp;
     86    break;
     87  case ion:
     88    _epoSpec = true;
     89    _sigma0  = OPT->_aprSigIon;
     90    break;
     91  case bias:
     92    _epoSpec = true;
     93    _sigma0  = OPT->_aprSigCodeBias;
     94    break;
    11595  }
    11696}
     
    124104////////////////////////////////////////////////////////////////////////////
    125105double t_pppParam::partial(const bncTime& /* epoTime */, const t_pppSatObs* obs,
    126                            const t_lc::type& tLC) const {
     106                           const t_lc& obsLC) const {
    127107
    128108  // Special Case - Melbourne-Wuebbena
    129109  // ---------------------------------
    130   if (tLC == t_lc::MW && _type != amb) {
     110  if (obsLC._type == t_lc::MW && _type != amb) {
    131111    return 0.0;
     112  }
     113
     114  // Special Case - GIM
     115  // ------------------
     116  if (obsLC._type == t_lc::GIM) {
     117    if (_type == ion) {
     118      return 1.0;
     119    }
     120    else {
     121      return 0.0;
     122    }
    132123  }
    133124
     
    138129  map<t_frequency::type, double> phaseCoeff;
    139130  map<t_frequency::type, double> ionoCoeff;
    140   obs->lcCoeff(tLC, codeCoeff, phaseCoeff, ionoCoeff);
    141 
     131  obs->lcCoeff(obsLC, codeCoeff, phaseCoeff, ionoCoeff);
     132 
    142133  switch (_type) {
    143134  case crdX:
    144     if (tLC == t_lc::GIM) {return 0.0;}
    145135    return (sta->xyzApr()[0] - obs->xc()[0]) / rhoV.NormFrobenius();
    146136  case crdY:
    147     if (tLC == t_lc::GIM) {return 0.0;}
    148137    return (sta->xyzApr()[1] - obs->xc()[1]) / rhoV.NormFrobenius();
    149138  case crdZ:
    150     if (tLC == t_lc::GIM) {return 0.0;}
    151139    return (sta->xyzApr()[2] - obs->xc()[2]) / rhoV.NormFrobenius();
    152   case rClkG:
    153     if (tLC == t_lc::GIM) {return 0.0;}
    154     return (obs->prn().system() == 'G') ? 1.0 : 0.0;
    155   case rClkR:
    156     if (tLC == t_lc::GIM) {return 0.0;}
    157     return (obs->prn().system() == 'R') ? 1.0 : 0.0;
    158   case rClkE:
    159     if (tLC == t_lc::GIM) {return 0.0;}
    160     return (obs->prn().system() == 'E') ? 1.0 : 0.0;
    161   case rClkC:
    162     if (tLC == t_lc::GIM) {return 0.0;}
    163     return (obs->prn().system() == 'C') ? 1.0 : 0.0;
     140  case rClk:
     141    return (_sys != obsLC.system() || obsLC.isGeometryFree()) ? 0.0 : 1.0;
    164142  case amb:
    165     if (tLC == t_lc::GIM) {
    166       return 0.0;
    167     }
    168     else {
    169       if (obs->prn() == _prn) {
    170         if      (tLC == _tLC) {
    171           return (obs->lambda(tLC));
    172         }
    173         else if (tLC == t_lc::lIF && _tLC == t_lc::MW) {
    174           return obs->lambda(t_lc::lIF) * obs->lambda(t_lc::MW) / obs->lambda(t_lc::l2);
    175         }
    176         else {
    177           if      (_tLC == t_lc::l1) {
    178             return obs->lambda(t_lc::l1) * phaseCoeff[obs->fType1()];
    179           }
    180           else if (_tLC == t_lc::l2) {
    181             return obs->lambda(t_lc::l2) * phaseCoeff[obs->fType2()];
    182           }
    183         }
     143    if (obs->prn() == _prn) {
     144      if      (obsLC == _LC) {
     145        return (obs->lambda(obsLC));
     146      }
     147      else if (_LC._type == t_lc::phase) {
     148        return obs->lambda(_LC) * phaseCoeff[_LC._frq1];
     149      }
     150      else if (obsLC._type == t_lc::phaseIF && _LC._type == t_lc::MW) {
     151        return obs->lambda(obsLC) * obs->lambda(_LC) / obs->lambda(t_lc(t_lc::phase, _LC._frq2));
    184152      }
    185153    }
    186154    break;
    187155  case trp:
    188     if      (tLC == t_lc::GIM) {
    189       return 0.0;
    190     }
    191     else {
    192       return 1.0 / sin(obs->eleSat());
    193     }
     156    return 1.0 / sin(obs->eleSat());
    194157  case ion:
    195158    if (obs->prn() == _prn) {
    196       if      (tLC == t_lc::c1) {
    197         return ionoCoeff[obs->fType1()];
    198       }
    199       else if (tLC == t_lc::c2) {
    200         return ionoCoeff[obs->fType2()];
    201       }
    202       else if (tLC == t_lc::l1) {
    203         return ionoCoeff[obs->fType1()];
    204       }
    205       else if (tLC == t_lc::l2) {
    206         return ionoCoeff[obs->fType2()];
    207       }
    208       else if (tLC == t_lc::GIM) {
    209         return 1.0;
    210       }
    211     }
    212     break;
    213   case cBiasG1:
    214     if ((obs->prn().system() == 'G') && (tLC == t_lc::c1)) {return 1.0;} else {return 0.0;}
    215     break;
    216   case cBiasR1:
    217     if ((obs->prn().system() == 'R') && (tLC == t_lc::c1)) {return 1.0;} else {return 0.0;}
    218     break;
    219   case cBiasE1:
    220     if ((obs->prn().system() == 'E') && (tLC == t_lc::c1)) {return 1.0;} else {return 0.0;}
    221     break;
    222   case cBiasC1:
    223     if ((obs->prn().system() == 'C') && (tLC == t_lc::c1)) {return 1.0;} else {return 0.0;}
    224     break;
    225   case cBiasG2:
    226     if ((obs->prn().system() == 'G') && (tLC == t_lc::c2)) {return 1.0;} else {return 0.0;}
    227     break;
    228   case cBiasR2:
    229     if ((obs->prn().system() == 'R') && (tLC == t_lc::c2)) {return 1.0;} else {return 0.0;}
    230     break;
    231   case cBiasE2:
    232     if ((obs->prn().system() == 'E') && (tLC == t_lc::c2)) {return 1.0;} else {return 0.0;}
    233         break;
    234   case cBiasC2:
    235     if ((obs->prn().system() == 'C') && (tLC == t_lc::c2)) {return 1.0;} else {return 0.0;}
    236     break;
    237   case pBiasG1:
    238     if ((obs->prn().system() == 'G') && (tLC == t_lc::l1)) {return 1.0;} else {return 0.0;}
    239     break;
    240   case pBiasR1:
    241     if ((obs->prn().system() == 'R') && (tLC == t_lc::l1)) {return 1.0;} else {return 0.0;}
    242     break;
    243   case pBiasE1:
    244     if ((obs->prn().system() == 'E') && (tLC == t_lc::l1)) {return 1.0;} else {return 0.0;}
    245     break;
    246   case pBiasC1:
    247     if ((obs->prn().system() == 'C') && (tLC == t_lc::l1)) {return 1.0;} else {return 0.0;}
    248     break;
    249   case pBiasG2:
    250     if ((obs->prn().system() == 'G') && (tLC == t_lc::l2)) {return 1.0;} else {return 0.0;}
    251     break;
    252   case pBiasR2:
    253     if ((obs->prn().system() == 'R') && (tLC == t_lc::l2)) {return 1.0;} else {return 0.0;}
    254     break;
    255   case pBiasE2:
    256     if ((obs->prn().system() == 'E') && (tLC == t_lc::l2)) {return 1.0;} else {return 0.0;}
    257     break;
    258   case pBiasC2:
    259     if ((obs->prn().system() == 'C') && (tLC == t_lc::l2)) {return 1.0;} else {return 0.0;}
    260     break;
    261 
     159      if (obsLC._type == t_lc::code || obsLC._type == t_lc::phase) {
     160        return ionoCoeff[obsLC._frq1];
     161      }
     162    }
     163    break;
     164  case bias:
     165    return (_LC == obsLC ? 1.0 : 0.0);
    262166  }
    263167  return 0.0;
     
    278182    ss << "CRD_Z";
    279183    break;
    280   case rClkG:
    281     ss << "REC_CLK  G  ";
    282     break;
    283   case rClkR:
    284     ss << "REC_CLK  R  ";
    285     break;
    286   case rClkE:
    287     ss << "REC_CLK  E  ";
    288     break;
    289   case rClkC:
    290     ss << "REC_CLK  C  ";
     184  case rClk:
     185    ss << "REC_CLK  " << _sys << "  ";
    291186    break;
    292187  case trp:
     
    294189    break;
    295190  case amb:
    296     ss << "AMB  " << left << setw(3) << t_lc::toString(_tLC) << right << ' ' << _prn.toString();
     191    ss << "AMB  " << left << setw(3) << _LC.toString() << right << ' ' << _prn.toString();
    297192    break;
    298193  case ion:
    299     ss << "ION  " << left << setw(3) << t_lc::toString(_tLC) << right << ' ' << _prn.toString();
    300     break;
    301   case cBiasG1:  case pBiasG1:
    302   case cBiasG2:  case pBiasG2:
    303     ss << "BIA  " << left << setw(3) << t_lc::toString(_tLC) << right << " G  ";
    304     break;
    305   case cBiasR1:  case pBiasR1:
    306   case cBiasR2:  case pBiasR2:
    307     ss << "BIA  " << left << setw(3) << t_lc::toString(_tLC) << right << " R  ";
    308     break;
    309   case cBiasE1:  case pBiasE1:
    310   case cBiasE2:  case pBiasE2:
    311     ss << "BIA  " << left << setw(3) << t_lc::toString(_tLC) << right << " E  ";
    312     break;
    313   case cBiasC1:  case pBiasC1:
    314   case cBiasC2:  case pBiasC2:
    315     ss << "BIA  " << left << setw(3) << t_lc::toString(_tLC) << right << " C  ";
     194    ss << "ION  " << left << setw(3) << _LC.toString() << right << ' ' << _prn.toString();
     195    break;
     196  case bias:
     197    char sys = t_frequency::toSystem(_LC._frq1);
     198    ss << "BIA  " << left << setw(3) << _LC.toString() << right << ' ' << sys << "  ";
    316199    break;
    317200  }
     
    353236             par->type() == t_pppParam::crdY ||
    354237             par->type() == t_pppParam::crdZ ||
    355              par->type() == t_pppParam::ion  ||
    356              par->type() == t_pppParam::cBiasC1 ||
    357              par->type() == t_pppParam::cBiasC2 ||
    358              par->type() == t_pppParam::cBiasE1 ||
    359              par->type() == t_pppParam::cBiasE2 ||
    360              par->type() == t_pppParam::cBiasR1 ||
    361              par->type() == t_pppParam::cBiasR2 ||
    362              par->type() == t_pppParam::pBiasC1 ||
    363              par->type() == t_pppParam::pBiasC2 ||
    364              par->type() == t_pppParam::pBiasE1 ||
    365              par->type() == t_pppParam::pBiasE2 ||
    366              par->type() == t_pppParam::pBiasR1 ||
    367              par->type() == t_pppParam::pBiasR2) {
     238             par->type() == t_pppParam::ion  ) {
    368239      if (par->lastObsTime().valid() && (epoTime - par->lastObsTime() > 60.0)) {
    369240        remove = true;
     
    383254  }
    384255
    385   // check which systems have observations
     256  // Check which systems have observations
    386257  // -------------------------------------
    387   _usedSystems['G'] = _usedSystems['R'] = _usedSystems['E'] = _usedSystems['C'] = 0;
    388   for (unsigned jj = 0; jj < obsVector.size(); jj++) {
    389     const t_pppSatObs* satObs = obsVector[jj];
    390     char sys = satObs->prn().system();
    391     if (OPT->LCs(sys).size()) {
    392       _usedSystems[sys]++;
     258  vector<char> systems = OPT->systems();
     259  for (char sys : systems) {
     260    _usedSystems[sys] = 0;
     261    for (unsigned jj = 0; jj < obsVector.size(); jj++) {
     262      const t_pppSatObs* satObs = obsVector[jj];
     263      if (satObs->prn().system() == sys) {
     264        _usedSystems[sys]++;
     265      }
    393266    }
    394267  };
    395 
    396268
    397269  // Check whether parameters have observations
     
    425297  // Coordinates
    426298  // -----------
    427   required.push_back(new t_pppParam(t_pppParam::crdX, t_prn(), t_lc::dummy));
    428   required.push_back(new t_pppParam(t_pppParam::crdY, t_prn(), t_lc::dummy));
    429   required.push_back(new t_pppParam(t_pppParam::crdZ, t_prn(), t_lc::dummy));
     299  required.push_back(new t_pppParam(t_pppParam::crdX, t_prn()));
     300  required.push_back(new t_pppParam(t_pppParam::crdY, t_prn()));
     301  required.push_back(new t_pppParam(t_pppParam::crdZ, t_prn()));
    430302
    431303  // Receiver Clocks
    432304  // ---------------
    433    if (_usedSystems['G']) {
    434    //if (OPT->useSystem('G')) {
    435      required.push_back(new t_pppParam(t_pppParam::rClkG, t_prn(), t_lc::dummy));
    436    }
    437    if (_usedSystems['R']) {
    438    //if (OPT->useSystem('R')) {
    439      required.push_back(new t_pppParam(t_pppParam::rClkR, t_prn(), t_lc::dummy));
    440    }
    441    if (_usedSystems['E']) {
    442    //if (OPT->useSystem('E')) {
    443      required.push_back(new t_pppParam(t_pppParam::rClkE, t_prn(), t_lc::dummy));
    444    }
    445    if (_usedSystems['C']) {
    446    //if (OPT->useSystem('C')) {
    447      required.push_back(new t_pppParam(t_pppParam::rClkC, t_prn(), t_lc::dummy));
    448    }
     305  for (const auto& [sys, numObs] : _usedSystems) {
     306    if (numObs > 0) {
     307      t_pppParam* clk = new t_pppParam(t_pppParam::rClk, t_prn());
     308      clk->setSystem(sys);
     309      required.push_back(clk);
     310    }
     311  }
    449312
    450313  // Troposphere
    451314  // -----------
    452315  if (OPT->estTrp()) {
    453     required.push_back(new t_pppParam(t_pppParam::trp, t_prn(), t_lc::dummy));
     316    required.push_back(new t_pppParam(t_pppParam::trp, t_prn()));
    454317  }
    455318
     
    459322    for (unsigned jj = 0; jj < obsVector.size(); jj++) {
    460323      const t_pppSatObs* satObs = obsVector[jj];
    461       char sys = satObs->prn().system();
    462       std::vector<t_lc::type> LCs = OPT->LCs(sys);
    463       if (std::find(LCs.begin(), LCs.end(), t_lc::cIF) == LCs.end() &&
    464           std::find(LCs.begin(), LCs.end(), t_lc::lIF) == LCs.end()) {
    465         required.push_back(new t_pppParam(t_pppParam::ion, satObs->prn(), t_lc::dummy));
    466       }
    467     }
    468   }
     324      std::vector<t_lc> LCs = OPT->LCs(satObs->prn().system());
     325      for (auto it = LCs.begin(); it != LCs.end(); ++it) {
     326        const t_lc& lc = *it;
     327        if (!lc.isIonoFree()) {
     328          required.push_back(new t_pppParam(t_pppParam::ion, satObs->prn()));
     329          break;
     330        }
     331      }
     332    }
     333  }
     334 
    469335  // Ambiguities
    470336  // -----------
     
    472338    const t_pppSatObs*  satObs = obsVector[jj];
    473339    char sys = satObs->prn().system();
    474     const vector<t_lc::type>& ambLCs = OPT->ambLCs(sys);
     340    const vector<t_lc>& ambLCs = OPT->ambLCs(sys);
    475341    for (unsigned ii = 0; ii < ambLCs.size(); ii++) {
     342      if (ambLCs[ii]._frq1 == t_frequency::G5 && !satObs->isValid(ambLCs[ii])) {
     343        continue;
     344      }
    476345      required.push_back(new t_pppParam(t_pppParam::amb, satObs->prn(), ambLCs[ii], &obsVector));
    477346    }
    478347  }
    479348
    480   // Receiver Code Biases
    481   // --------------------
    482     if (OPT->_ionoModelType == OPT->PPP_RTK) {
    483     std::vector<t_lc::type> lc;
    484     if (OPT->useSystem('G')) {
    485       lc = OPT->LCs('G');
    486       if (std::find(lc.begin(), lc.end(), t_lc::c1) != lc.end()) {
    487         required.push_back(new t_pppParam(t_pppParam::cBiasG1, t_prn(), t_lc::c1));
    488       }
    489       if (std::find(lc.begin(), lc.end(), t_lc::c2) != lc.end()) {
    490         required.push_back(new t_pppParam(t_pppParam::cBiasG2, t_prn(), t_lc::c2));
    491       }
    492     }
    493     if (OPT->useSystem('R')) {
    494       lc = OPT->LCs('R');
    495       if (std::find(lc.begin(), lc.end(), t_lc::c1) != lc.end()) {
    496         required.push_back(new t_pppParam(t_pppParam::cBiasR1, t_prn(), t_lc::c1));
    497       }
    498       if (std::find(lc.begin(), lc.end(), t_lc::c2) != lc.end()) {
    499         required.push_back(new t_pppParam(t_pppParam::cBiasR2, t_prn(), t_lc::c2));
    500       }
    501     }
    502     if (OPT->useSystem('E')) {
    503       lc = OPT->LCs('E');
    504       if (std::find(lc.begin(), lc.end(), t_lc::c1) != lc.end()) {
    505         required.push_back(new t_pppParam(t_pppParam::cBiasE1, t_prn(), t_lc::c1));
    506       }
    507       if (std::find(lc.begin(), lc.end(), t_lc::c2) != lc.end()) {
    508         required.push_back(new t_pppParam(t_pppParam::cBiasE2, t_prn(), t_lc::c2));
    509       }
    510     }
    511     if (OPT->useSystem('C')) {
    512       lc = OPT->LCs('C');
    513       if (std::find(lc.begin(), lc.end(), t_lc::c1) != lc.end()) {
    514         required.push_back(new t_pppParam(t_pppParam::cBiasC1, t_prn(), t_lc::c1));
    515       }
    516       if (std::find(lc.begin(), lc.end(), t_lc::c2) != lc.end()) {
    517         required.push_back(new t_pppParam(t_pppParam::cBiasC2, t_prn(), t_lc::c2));
    518       }
    519     }
    520   }
    521 
    522   if (OPT->_pseudoObsIono) {
    523     std::vector<t_lc::type> lc;
    524     if (OPT->useSystem('G')) {
    525       lc = OPT->LCs('G');
    526       if (std::find(lc.begin(), lc.end(), t_lc::c2) != lc.end()) {
    527         required.push_back(new t_pppParam(t_pppParam::cBiasG2, t_prn(), t_lc::c2));
    528       }
    529     }
    530     if (OPT->useSystem('R')) {
    531       lc = OPT->LCs('R');
    532       if (std::find(lc.begin(), lc.end(), t_lc::c2) != lc.end()) {
    533         required.push_back(new t_pppParam(t_pppParam::cBiasR2, t_prn(), t_lc::c2));
    534       }
    535     }
    536     if (OPT->useSystem('E')) {
    537       lc = OPT->LCs('E');
    538       if (std::find(lc.begin(), lc.end(), t_lc::c2) != lc.end()) {
    539         required.push_back(new t_pppParam(t_pppParam::cBiasE2, t_prn(), t_lc::c2));
    540       }
    541     }
    542     if (OPT->useSystem('C')) {
    543       lc = OPT->LCs('C');
    544       if (std::find(lc.begin(), lc.end(), t_lc::c2) != lc.end()) {
    545         required.push_back(new t_pppParam(t_pppParam::cBiasC2, t_prn(), t_lc::c2));
    546       }
    547     }
    548   }
    549 
    550   if (OPT->_ionoModelType == OPT->PPP_RTK) {
    551     std::vector<t_lc::type> lc;
    552     if (OPT->useSystem('G')) {
    553       lc = OPT->LCs('G');
    554       if (std::find(lc.begin(), lc.end(), t_lc::l1) != lc.end()) {
    555         required.push_back(new t_pppParam(t_pppParam::pBiasG1, t_prn(), t_lc::l1));
    556       }
    557       if (std::find(lc.begin(), lc.end(), t_lc::l2) != lc.end()) {
    558         required.push_back(new t_pppParam(t_pppParam::pBiasG2, t_prn(), t_lc::l2));
    559       }
    560     }
    561     if (OPT->useSystem('R')) {
    562       lc = OPT->LCs('R');
    563       if (std::find(lc.begin(), lc.end(), t_lc::l1) != lc.end()) {
    564         required.push_back(new t_pppParam(t_pppParam::pBiasR1, t_prn(), t_lc::l1));
    565       }
    566       if (std::find(lc.begin(), lc.end(), t_lc::l2) != lc.end()) {
    567         required.push_back(new t_pppParam(t_pppParam::pBiasR2, t_prn(), t_lc::l2));
    568       }
    569     }
    570     if (OPT->useSystem('E')) {
    571       lc = OPT->LCs('E');
    572       if (std::find(lc.begin(), lc.end(), t_lc::l1) != lc.end()) {
    573         required.push_back(new t_pppParam(t_pppParam::pBiasE1, t_prn(), t_lc::l1));
    574       }
    575       if (std::find(lc.begin(), lc.end(), t_lc::l2) != lc.end()) {
    576         required.push_back(new t_pppParam(t_pppParam::pBiasE2, t_prn(), t_lc::l2));
    577       }
    578     }
    579     if (OPT->useSystem('C')) {
    580       lc = OPT->LCs('C');
    581       if (std::find(lc.begin(), lc.end(), t_lc::l1) != lc.end()) {
    582         required.push_back(new t_pppParam(t_pppParam::pBiasC1, t_prn(), t_lc::l1));
    583       }
    584       if (std::find(lc.begin(), lc.end(), t_lc::l2) != lc.end()) {
    585         required.push_back(new t_pppParam(t_pppParam::pBiasC2, t_prn(), t_lc::l2));
     349  // Biases
     350  // ------
     351  int maxSkip = (OPT->_pseudoObsIono ? 1 : 2);
     352  for (const auto& [sys, numObs] : _usedSystems) {
     353    if (numObs > 0) {
     354      bool ar   = OPT->arSystem(sys);
     355      int  skip = 0;
     356      vector<t_lc> LCs = OPT->LCs(sys);
     357      for (const t_lc& lc : LCs) {
     358        if (ar) {
     359          if (skip < maxSkip && lc.includesPhase()) {
     360            skip += 1;
     361          }
     362          else {
     363            required.push_back(new t_pppParam(t_pppParam::bias, t_prn(), lc));
     364          }
     365        }
     366        else {
     367          if (lc.includesCode()) {
     368            if (skip < maxSkip) {
     369              skip += 1;
     370            }
     371            else {
     372              required.push_back(new t_pppParam(t_pppParam::bias, t_prn(), lc));
     373            }
     374          }
     375        }
    586376      }
    587377    }
     
    605395    }
    606396    else {
    607 #ifdef BNC_DEBUG_PPP
    608       //LOG << "push_back  parReq " << parReq->toString() << std::endl;
    609 #endif
    610397      _params.push_back(parReq);
    611398    }
     
    634421////////////////////////////////////////////////////////////////////////////
    635422void t_pppParlist::printResult(const bncTime& epoTime, const SymmetricMatrix& QQ,
    636                                const ColumnVector& xx) const {
     423                               const ColumnVector& xx, double fixRatio) const {
    637424
    638425  string epoTimeStr = string(epoTime);
     
    703490
    704491        << " dU = " << setprecision(4) << neu[2] << " +- "
    705         << setprecision(4) << sqrt(QQneu[2][2])
    706 
    707         << endl;
     492        << setprecision(4) << sqrt(QQneu[2][2]);
     493
     494    if (fixRatio > 0.0) {
     495      LOG << " fix " <<  int(100*fixRatio) << " %";
     496    }
     497    else {
     498      LOG << " flt ";
     499    }
     500
     501    LOG << endl;
    708502  }
    709503  return;
  • trunk/BNC/src/PPP/pppParlist.h

    r10583 r10791  
    1414class t_pppParam {
    1515 public:
    16   enum e_type {crdX, crdY, crdZ, rClkG, rClkR, rClkE, rClkC, trp, ion, amb,
    17                cBiasG1, cBiasR1, cBiasE1, cBiasC1, pBiasG1, pBiasR1, pBiasE1, pBiasC1,
    18                cBiasG2, cBiasR2, cBiasE2, cBiasC2, pBiasG2, pBiasR2, pBiasE2, pBiasC2};
     16  enum e_type {crdX, crdY, crdZ, rClk, trp, ion, amb, bias};
    1917
    20   t_pppParam(e_type type, const t_prn& prn, t_lc::type tLC, const std::vector<t_pppSatObs*>* obsVector = 0);
     18  t_pppParam(e_type type, const t_prn& prn, t_lc LC = t_lc(), const std::vector<t_pppSatObs*>* obsVector = 0);
    2119  ~t_pppParam();
    2220
    2321  e_type type() const {return _type;}
    2422  double x0()  const {return _x0;}
    25   double partial(const bncTime& epoTime, const t_pppSatObs* obs,
    26                  const t_lc::type& tLC) const;
     23  double partial(const bncTime& epoTime, const t_pppSatObs* obs, const t_lc& LC) const;
    2724  bool   epoSpec() const {return _epoSpec;}
    2825  bool   isEqual(const t_pppParam* par2) const {
    29     return (_type == par2->_type && _prn == par2->_prn && _tLC == par2->_tLC);
     26    return (_type == par2->_type && _prn == par2->_prn && _LC == par2->_LC && _sys == par2->_sys);
    3027  }
    3128  void   setIndex(int indexNew) {
     
    3633    _indexOld = -1;
    3734  }
    38   int indexOld() const {return _indexOld;}
    39   int indexNew() const {return _indexNew;}
    40   double sigma0() const {return _sigma0;}
    41   double noise() const {return _noise;}
    42   t_lc::type tLC() const {return _tLC;}
    43   t_prn prn() const {return _prn;}
     35  int         indexOld() const {return _indexOld;}
     36  int         indexNew() const {return _indexNew;}
     37  double      sigma0() const {return _sigma0;}
     38  double      noise() const {return _noise;}
     39  t_lc        LC() const {return _LC;}
     40  t_prn       prn() const {return _prn;}
    4441  std::string toString() const;
    4542
     
    5552  unsigned ambNumEpo() const           {return _ambInfo ? _ambInfo->_numEpo : 0;}
    5653  void     stepAmbNumEpo()             {if (_ambInfo) _ambInfo->_numEpo += 1;}
     54  char     system() const {
     55    if (_prn.valid()) {
     56      return _prn.system();
     57    }
     58    else if (_LC.valid()) {
     59      return _LC.system();
     60    }
     61    else {
     62      return _sys;
     63    }
     64  }
     65  void     setSystem(char sys) {_sys = sys;}
    5766
    5867  static bool sortFunction(const t_pppParam* p1, const t_pppParam* p2) {
     
    6069      return p1->_type < p2->_type;
    6170    }
    62     else if (p1->_tLC != p2->_tLC) {
    63       return p1->_tLC < p2->_tLC;
     71    else if (p1->_LC != p2->_LC) {
     72      return p1->_LC < p2->_LC;
    6473    }
    6574    else if (p1->_prn != p2->_prn) {
     
    8493  e_type       _type;
    8594  t_prn        _prn;
    86   t_lc::type   _tLC;
     95  char         _sys;
     96  t_lc         _LC;
    8797  double       _x0;
    8898  bool         _epoSpec;
     
    104114  const std::vector<t_pppParam*>& params() const {return _params;}
    105115  std::vector<t_pppParam*>& params() {return _params;}
    106   const QMap<char, int>& usedSystems() const {return _usedSystems;}
    107116  void printResult(const bncTime& epoTime, const SymmetricMatrix& QQ,
    108                    const ColumnVector& xx) const;
     117                   const ColumnVector& xx, double fixRatio = 0.0) const;
    109118  void printParams(const bncTime& epoTime);
    110119
    111120 private:
    112121  std::vector<t_pppParam*> _params;
    113   QMap<char, int>          _usedSystems;
     122  std::map<char, int>      _usedSystems;
    114123};
    115124
  • trunk/BNC/src/PPP/pppSatObs.cpp

    r10626 r10791  
    1919#include <iomanip>
    2020#include <cmath>
     21#include <algorithm>
     22#include <set>
    2123#include <newmatio.h>
    2224
     
    4345  _reference  = false;
    4446  _stecSat    = 0.0;
    45   _signalPriorities = QString::fromStdString(OPT->_signalPriorities);
    4647  for (unsigned ii = 0; ii < t_frequency::max; ii++) {
    4748    _obs[ii] = 0;
     
    6061//
    6162////////////////////////////////////////////////////////////////////////////
    62 void t_pppSatObs::prepareObs(const t_satObs& pppSatObs) {
     63bool t_pppSatObs::isBetter(const t_frqObs* aa, t_frqObs* bb, const string& trkModes) const {
     64
     65  if (!trkModes.empty()) {
     66    size_t posA = trkModes.find(aa->trkChar());
     67    size_t posB = trkModes.find(bb->trkChar());
     68    if (posA != posB) {
     69      if      (posA == string::npos) {
     70        return false;
     71      }
     72      else if (posB == string::npos) {
     73        return true;
     74      }
     75      else {
     76        return posA < posB;
     77      }
     78    }
     79  }
     80     
     81  unsigned numValA = 0;
     82  if (aa->_codeValid)  numValA += 1;
     83  if (aa->_phaseValid) numValA += 1;
     84
     85  unsigned numValB = 0;
     86  if (bb->_codeValid)  numValB += 1;
     87  if (bb->_phaseValid) numValB += 1;
     88
     89  if (numValA != numValB) {
     90    return numValA > numValB;
     91  }
     92
     93  return false;
     94}
     95
     96//
     97////////////////////////////////////////////////////////////////////////////
     98void t_pppSatObs::prepareObs(const t_satObs& satObs) {
    6399
    64100  _model.reset();
    65101
    66   std::vector<char> bb = OPT->frqBands(_prn.system());
    67   char frqNum1 = '0';
    68   if (bb.size() >= 1) {
    69     frqNum1 = bb[0];
    70   }
    71   char frqNum2 = '0';
    72   if (bb.size() == 2) {
    73     frqNum2 = bb[1];
    74   }
    75 
    76   // Select pseudo-ranges and phase observations
    77   // -------------------------------------------
    78   QStringList priorList = _signalPriorities.split(" ", Qt::SkipEmptyParts);
    79   string preferredAttrib;
    80   for (unsigned iFreq = 1; iFreq < t_frequency::max; iFreq++) {
    81     t_frequency::type frqType = static_cast<t_frequency::type>(iFreq);
    82     char frqSys = t_frequency::toString(frqType)[0]; //cout << "frqSys: " << frqSys << endl;
    83     char frqNum = t_frequency::toString(frqType)[1]; //cout << "frqNum: " << frqNum << endl;
    84     if (frqSys != _prn.system()) {
    85       continue;
    86     }
    87     if (frqNum != frqNum1 &&
    88         frqNum != frqNum2 ) {
    89       continue;
    90     }
    91     QStringList hlp;
    92     for (int ii = 0; ii < priorList.size(); ii++) {
    93       if (priorList[ii].indexOf(":") != -1) {
    94         hlp = priorList[ii].split(":", Qt::SkipEmptyParts);
    95         if (hlp.size() == 2 && hlp[0].length() == 1 && hlp[0][0] == frqSys) {
    96           hlp = hlp[1].split("&", Qt::SkipEmptyParts);
    97         }
    98         if (hlp.size() == 2 && hlp[0].indexOf(frqNum) != -1) {
    99           preferredAttrib = hlp[1].toStdString(); //cout << "preferredAttrib: " << preferredAttrib << endl;
    100         }
    101       }
    102       for (unsigned iPref = 0; iPref < preferredAttrib.length(); iPref++) {
    103         QString obsType = QString("%1").arg(frqNum) + preferredAttrib[iPref];  //cout << "obstype: " << obsType.toStdString().c_str() << endl;
    104         if (_obs[iFreq] == 0) {
    105           for (unsigned ii = 0; ii < pppSatObs._obs.size(); ii++) {
    106             const t_frqObs* obs = pppSatObs._obs[ii];
    107             //cout << "observation2char: " << obs->_rnxType2ch << " vs. " << obsType.toStdString().c_str()<< endl;
    108             if (obs->_rnxType2ch == obsType.toStdString() &&
    109                 obs->_codeValid  && obs->_code &&
    110                 obs->_phaseValid && obs->_phase) {
    111               _obs[iFreq] = new t_frqObs(*obs); //cout << "================> newObs: " << obs->_rnxType2ch << " obs->_lockTime: " << obs->_lockTime << endl;
    112             }
    113           }
    114         }
    115       }
    116     }
    117   }
    118 
    119   // Used frequency types
    120   // --------------------
    121   _fType1 = t_frqBand::toFreq(_prn.system(), frqNum1);
    122   _fType2 = t_frqBand::toFreq(_prn.system(), frqNum2);
    123 
     102  const t_pppOptions::SysTrkModes* sysTrkModes = OPT->sysTrkModes(_prn.system());
     103  using FrqTrkModes = t_pppOptions::SysTrkModes::FrqTrkModes;
     104 
     105  for (const t_frqObs* obs : satObs._obs) {
     106    if ( (obs->_codeValid || obs->_phaseValid)) {
     107      t_frequency::type frq = t_frequency::toFreq(_prn.system(), obs->frqChar());
     108      if (frq == t_frequency::dummy) {
     109        continue;
     110      }
     111      string trkModes;
     112      if (sysTrkModes) {
     113        const vector<FrqTrkModes>& frqTrkModes = sysTrkModes->_frqTrkModes;
     114        auto it = find_if(frqTrkModes.begin(), frqTrkModes.end(),
     115                          [frq](const FrqTrkModes& mm){return mm._frq == frq;});
     116        if (it != frqTrkModes.end()) {
     117          trkModes = it->_trkModes;
     118        }
     119      }
     120      if (_obs[frq] == 0 || isBetter(obs, _obs[frq], trkModes)) {
     121        delete _obs[frq]; 
     122        _obs[frq] = new t_frqObs(*obs);
     123      }
     124    }
     125  }
     126 
    124127  // Check whether all required frequencies available
    125128  // ------------------------------------------------
    126   for (unsigned ii = 0; ii < OPT->LCs(_prn.system()).size(); ii++) {
    127     t_lc::type tLC = OPT->LCs(_prn.system())[ii];
    128     if (tLC == t_lc::GIM) {continue;}
    129     if (!isValid(tLC)) {
     129  const std::vector<t_lc>& LCs = OPT->LCs(_prn.system());
     130  for (unsigned ii = 0; ii < LCs.size(); ii++) {
     131    t_lc LC = LCs[ii];
     132    if (LC._type == t_lc::GIM) {
     133      continue;
     134    }
     135    if (LC._frq1 != t_frequency::G5 && !isValid(LC)) {
    130136      _valid = false;
    131137      return;
     
    148154  bool totOK  = false;
    149155  ColumnVector satPosOld(6); satPosOld = 0.0;
    150   t_lc::type tLC = t_lc::dummy;
    151   if (isValid(t_lc::cIF)) {
    152     tLC = t_lc::cIF;
    153   }
    154   if (tLC == t_lc::dummy && isValid(t_lc::c1)) {
    155       tLC = t_lc::c1;
    156   }
    157   if (tLC == t_lc::dummy && isValid(t_lc::c2)) {
    158       tLC = t_lc::c2;
    159   }
    160   if (tLC == t_lc::dummy) {
    161     _valid = false;
     156
     157  _valid = false;
     158  t_frequency::type frq1 = t_frequency::dummy;
     159  t_frequency::type frq2 = t_frequency::dummy;
     160  OPT->defaultFrqs(_prn.system(), frq1, frq2);
     161  if (frq1 != t_frequency::dummy) {
     162    t_lc lc1(t_lc::code, frq1);
     163    if (isValid(lc1)) {
     164      _valid = true;
     165      _rangeLC = lc1;
     166    }
     167    if (frq2 != t_frequency::dummy) {
     168      t_lc lcIF(t_lc::codeIF, frq1, frq2);
     169      if (isValid(lcIF)) {
     170        _valid = true;
     171        _rangeLC = lcIF;
     172      }
     173    }
     174  }
     175  if (!_valid) {
    162176    return;
    163177  }
    164   double prange = obsValue(tLC);
     178 
     179  double prange = obsValue(_rangeLC);
    165180  for (int ii = 1; ii <= 10; ii++) {
    166181    bncTime ToT = _time - prange / t_CST::c - _xcSat[3];
     
    188203//
    189204////////////////////////////////////////////////////////////////////////////
    190 void t_pppSatObs::lcCoeff(t_lc::type tLC,
     205void t_pppSatObs::lcCoeff(t_lc LC,
    191206                          map<t_frequency::type, double>& codeCoeff,
    192207                          map<t_frequency::type, double>& phaseCoeff,
     
    197212  ionoCoeff.clear();
    198213
    199   double f1 = t_CST::freq(_fType1, _channel);
    200   double f2 = t_CST::freq(_fType2, _channel);
     214  double f1 = t_CST::freq(LC._frq1, _channel);
     215  double f2 = t_CST::freq(LC._frq2, _channel);
    201216  double f1GPS = t_CST::freq(t_frequency::G1, 0);
    202217
    203   switch (tLC) {
    204   case t_lc::l1:
    205     phaseCoeff[_fType1] =  1.0;
    206     ionoCoeff [_fType1] = -1.0 * pow(f1GPS, 2) / pow(f1, 2);
     218  switch (LC._type) {
     219  case t_lc::phase:
     220    phaseCoeff[LC._frq1] =  1.0;
     221    ionoCoeff [LC._frq1] = -1.0 * pow(f1GPS, 2) / pow(f1, 2);
    207222    return;
    208   case t_lc::l2:
    209     phaseCoeff[_fType2] = 1.0;
    210     ionoCoeff [_fType2] = -1.0 * pow(f1GPS, 2) / pow(f2, 2);
     223  case t_lc::code:
     224    codeCoeff[LC._frq1] = 1.0;
     225    ionoCoeff[LC._frq1] = pow(f1GPS, 2) / pow(f1, 2);
    211226    return;
    212   case t_lc::lIF:
    213     phaseCoeff[_fType1] =  f1 * f1 / (f1 * f1 - f2 * f2);
    214     phaseCoeff[_fType2] = -f2 * f2 / (f1 * f1 - f2 * f2);
     227  case t_lc::phaseIF:
     228    phaseCoeff[LC._frq1] =  f1 * f1 / (f1 * f1 - f2 * f2);
     229    phaseCoeff[LC._frq2] = -f2 * f2 / (f1 * f1 - f2 * f2);
     230    return;
     231  case t_lc::codeIF:
     232    codeCoeff[LC._frq1] =  f1 * f1 / (f1 * f1 - f2 * f2);
     233    codeCoeff[LC._frq2] = -f2 * f2 / (f1 * f1 - f2 * f2);
    215234    return;
    216235  case t_lc::MW:
    217     phaseCoeff[_fType1] =  f1 / (f1 - f2);
    218     phaseCoeff[_fType2] = -f2 / (f1 - f2);
    219     codeCoeff[_fType1] = -f1 / (f1 + f2);
    220     codeCoeff[_fType2] = -f2 / (f1 + f2);
     236    phaseCoeff[LC._frq1] =  f1 / (f1 - f2);
     237    phaseCoeff[LC._frq2] = -f2 / (f1 - f2);
     238    codeCoeff [LC._frq1] = -f1 / (f1 + f2);
     239    codeCoeff [LC._frq2] = -f2 / (f1 + f2);
    221240    return;
    222241  case t_lc::CL:
    223     phaseCoeff[_fType1] =  0.5;
    224     codeCoeff [_fType1] =  0.5;
    225     return;
    226   case t_lc::c1:
    227     codeCoeff[_fType1] = 1.0;
    228     ionoCoeff[_fType1] = pow(f1GPS, 2) / pow(f1, 2);
    229     return;
    230   case t_lc::c2:
    231     codeCoeff[_fType2] = 1.0;
    232     ionoCoeff[_fType2] = pow(f1GPS, 2) / pow(f2, 2);
    233     return;
    234   case t_lc::cIF:
    235     codeCoeff[_fType1] =  f1 * f1 / (f1 * f1 - f2 * f2);
    236     codeCoeff[_fType2] = -f2 * f2 / (f1 * f1 - f2 * f2);
     242    phaseCoeff[LC._frq1] =  0.5;
     243    codeCoeff [LC._frq1] =  0.5;
    237244    return;
    238245  case t_lc::GIM:
     
    245252//
    246253////////////////////////////////////////////////////////////////////////////
    247 bool t_pppSatObs::isValid(t_lc::type tLC) const {
     254bool t_pppSatObs::isValid(t_lc LC) const {
    248255  bool valid = true;
    249   obsValue(tLC, &valid);
     256  obsValue(LC, &valid);
    250257
    251258  return valid;
     
    253260//
    254261////////////////////////////////////////////////////////////////////////////
    255 double t_pppSatObs::obsValue(t_lc::type tLC, bool* valid) const {
     262double t_pppSatObs::obsValue(t_lc LC, bool* valid) const {
    256263
    257264  double retVal = 0.0;
     
    259266
    260267  // Pseudo observations
    261   if (tLC == t_lc::GIM) {
     268  if (LC._type == t_lc::GIM) {
    262269    if (_stecSat == 0.0) {
    263270      if (valid) *valid = false;
     
    272279  map<t_frequency::type, double> phaseCoeff;
    273280  map<t_frequency::type, double> ionoCoeff;
    274   lcCoeff(tLC, codeCoeff, phaseCoeff, ionoCoeff);
     281  lcCoeff(LC, codeCoeff, phaseCoeff, ionoCoeff);
    275282
    276283  map<t_frequency::type, double>::const_iterator it;
     
    303310//
    304311////////////////////////////////////////////////////////////////////////////
    305 double t_pppSatObs::lambda(t_lc::type tLC) const {
    306 
    307   double f1 = t_CST::freq(_fType1, _channel);
    308   double f2 = t_CST::freq(_fType2, _channel);
    309 
    310   if      (tLC == t_lc::l1) {
     312double t_pppSatObs::lambda(t_lc LC) const {
     313
     314  double f1 = t_CST::freq(LC._frq1, _channel);
     315  double f2 = t_CST::freq(LC._frq2, _channel);
     316
     317  if      (LC._type == t_lc::phase) {
    311318    return t_CST::c / f1;
    312319  }
    313   else if (tLC == t_lc::l2) {
    314     return t_CST::c / f2;
    315   }
    316   else if (tLC == t_lc::lIF) {
     320  else if (LC._type == t_lc::phaseIF) {
    317321    return t_CST::c / (f1 + f2);
    318322  }
    319   else if (tLC == t_lc::MW) {
     323  else if (LC._type == t_lc::MW) {
    320324    return t_CST::c / (f1 - f2);
    321325  }
    322   else if (tLC == t_lc::CL) {
     326  else if (LC._type == t_lc::CL) {
    323327    return t_CST::c / f1 / 2.0;
    324328  }
     
    329333//
    330334////////////////////////////////////////////////////////////////////////////
    331 double t_pppSatObs::sigma(t_lc::type tLC) const {
     335double t_pppSatObs::sigma(t_lc LC) const {
    332336
    333337  double retVal = 0.0;
     
    335339  map<t_frequency::type, double> phaseCoeff;
    336340  map<t_frequency::type, double> ionoCoeff;
    337   lcCoeff(tLC, codeCoeff, phaseCoeff, ionoCoeff);
    338 
    339   if (tLC == t_lc::GIM) {
     341  lcCoeff(LC, codeCoeff, phaseCoeff, ionoCoeff);
     342
     343  if (LC._type == t_lc::GIM) {
    340344    retVal = OPT->_sigmaGIM * OPT->_sigmaGIM;
    341345  }
     
    354358  // De-Weight R
    355359  // -----------
    356   if (_prn.system() == 'R'&& t_lc::includesCode(tLC)) {
     360  if (_prn.system() == 'R'&& LC.includesCode()) {
    357361    retVal *= 5.0;
    358362  }
     
    361365  // -----------------------------
    362366  double cEle = 1.0;
    363   if ( (OPT->_eleWgtCode  && t_lc::includesCode(tLC)) ||
    364        (OPT->_eleWgtPhase && t_lc::includesPhase(tLC)) ) {
     367  if ( (OPT->_eleWgtCode  && LC.includesCode()) ||
     368       (OPT->_eleWgtPhase && LC.includesPhase()) ) {
    365369    double eleD = eleSat()*180.0/M_PI;
    366370    double hlp  = fabs(90.0 - eleD);
     
    373377//
    374378////////////////////////////////////////////////////////////////////////////
    375 double t_pppSatObs::maxRes(t_lc::type tLC) const {
     379double t_pppSatObs::maxRes(t_lc LC) const {
    376380  double retVal = 0.0;
    377381
     
    379383  map<t_frequency::type, double> phaseCoeff;
    380384  map<t_frequency::type, double> ionoCoeff;
    381   lcCoeff(tLC, codeCoeff, phaseCoeff, ionoCoeff);
     385  lcCoeff(LC, codeCoeff, phaseCoeff, ionoCoeff);
    382386
    383387  map<t_frequency::type, double>::const_iterator it;
     
    388392    retVal += it->second * it->second * OPT->_maxResL1 * OPT->_maxResL1;
    389393  }
    390   if (tLC == t_lc::GIM) {
     394  if (LC._type == t_lc::GIM) {
    391395    retVal = OPT->_maxResGIM * OPT->_maxResGIM + OPT->_maxResGIM * OPT->_maxResGIM;
    392396  }
     
    517521        }
    518522        const t_frqObs* obs = _obs[iFreq];
    519         if (obs &&
    520             obs->_rnxType2ch == bias._rnxType2ch) {
    521           _model._codeBias[iFreq]  = bias._value;
     523        if (obs && obs->_rnxType2ch == bias._rnxType2ch) {
     524          _model._codeBias[iFreq] = (bias._value != 0.0 ? bias._value : ZEROVALUE);
    522525        }
    523526      }
     
    527530  // Phase Biases
    528531  // -----------
    529   const t_satPhaseBias* satPhaseBias = PPP_CLIENT->obsPool()->satPhaseBias(_prn);
    530   double yaw = 0.0;
    531   bool ssr = false;
    532   if (satPhaseBias) {
    533     double dt = station->epochTime() - satPhaseBias->_time;
    534     if (satPhaseBias->_updateInt) {
    535       dt -= (0.5 * ssrUpdateInt[satPhaseBias->_updateInt]);
    536     }
    537     yaw = satPhaseBias->_yaw + satPhaseBias->_yawRate * dt;
    538     ssr = true;
    539     for (unsigned ii = 0; ii < satPhaseBias->_bias.size(); ii++) {
    540       const t_frqPhaseBias& bias = satPhaseBias->_bias[ii];
    541       for (unsigned iFreq = 1; iFreq < t_frequency::max; iFreq++) {
    542         string frqStr = t_frequency::toString(t_frequency::type(iFreq));
    543         if (frqStr[0] != _prn.system()) {
    544           continue;
    545         }
    546         const t_frqObs* obs = _obs[iFreq];
    547         if (obs &&
    548             obs->_rnxType2ch == bias._rnxType2ch) {
    549           _model._phaseBias[iFreq]  = bias._value;
     532  double yaw    = 0.0;
     533  bool   useYaw = false;
     534  if (OPT->arSystem(_prn.system())) {
     535    const t_satPhaseBias* satPhaseBias = PPP_CLIENT->obsPool()->satPhaseBias(_prn);
     536    if (satPhaseBias) {
     537      if (OPT->_ar._useYaw) {
     538        double dt = station->epochTime() - satPhaseBias->_time;
     539        if (satPhaseBias->_updateInt) {
     540          dt -= (0.5 * ssrUpdateInt[satPhaseBias->_updateInt]);
     541        }
     542        yaw = satPhaseBias->_yaw + satPhaseBias->_yawRate * dt;
     543        useYaw = true;
     544      }
     545      for (unsigned ii = 0; ii < satPhaseBias->_bias.size(); ii++) {
     546        const t_frqPhaseBias& bias = satPhaseBias->_bias[ii];
     547        if (bias._fixIndicator) {  // if AR, biases without fixIndicator not used
     548          for (unsigned iFreq = 1; iFreq < t_frequency::max; iFreq++) {
     549            string frqStr = t_frequency::toString(t_frequency::type(iFreq));
     550            if (frqStr[0] != _prn.system()) {
     551              continue;
     552            }
     553            t_frqObs* obs = _obs[iFreq];
     554            if (obs && obs->_rnxType2ch[0] == bias._rnxType2ch[0]) { // allow different tracking mode
     555              _model._phaseBias[iFreq] = (bias._value != 0.0 ? bias._value : ZEROVALUE);
     556              obs->_biasJumpCounter = bias._jumpCounter;
     557            }
     558          }
    550559        }
    551560      }
     
    555564  // Phase Wind-Up
    556565  // -------------
    557   _model._windUp = station->windUp(_time, _prn, rSat, ssr, yaw, vSat) ;
     566  _model._windUp = station->windUp(_time, _prn, rSat, useYaw, yaw, vSat) ;
    558567
    559568  // Relativistic effect due to earth gravity
     
    574583  bool vTecUsage = true;
    575584  for (unsigned ii = 0; ii < OPT->LCs(_prn.system()).size(); ii++) {
    576     t_lc::type tLC = OPT->LCs(_prn.system())[ii];
    577     if (tLC == t_lc::cIF || tLC == t_lc::lIF) {
     585    t_lc LC = OPT->LCs(_prn.system())[ii];
     586    if (LC._type == t_lc::codeIF || LC._type == t_lc::phaseIF) {
    578587      vTecUsage = false;
    579588    }
     
    601610  _model._set = true;
    602611
    603   //printModel();
     612  if (OPT->_logMode == t_pppOptions::all) {
     613    printModel();
     614  }
    604615
    605616  return success;
     
    636647      if (_prn.system() == frqStr[0]) {
    637648      LOG << "PCO           : " << frqStr << setw(12) << setprecision(3) << _model._antPCO[iFreq]       << endl
    638           << "BIAS CODE     : " << frqStr << setw(12) << setprecision(3) << _model._codeBias[iFreq]     << "\t(" << _obs[iFreq]->_rnxType2ch[1] << ") " << endl
    639           << "BIAS PHASE    : " << frqStr << setw(12) << setprecision(3) << _model._phaseBias[iFreq]    << "\t(" << _obs[iFreq]->_rnxType2ch[1] << ") " << endl
     649          << "BIAS CODE     : " << frqStr << setw(12) << setprecision(3) << _model._codeBias[iFreq]     << "\t(" << _obs[iFreq]->trkChar() << ") " << endl
     650          << "BIAS PHASE    : " << frqStr << setw(12) << setprecision(3) << _model._phaseBias[iFreq]    << "\t(" << _obs[iFreq]->trkChar() << ") " << endl
    640651          << "IONO CODEDELAY: " << frqStr << setw(12) << setprecision(3) << _model._ionoCodeDelay[iFreq]<< endl;
    641652      }
     
    652663  char sys = _prn.system();
    653664  for (unsigned ii = 0; ii < OPT->LCs(sys).size(); ii++) {
    654     t_lc::type tLC = OPT->LCs(sys)[ii];
    655     LOG << "OBS-CMP " << setw(4) << t_lc::toString(tLC) << ": " << _prn.toString() << " "
    656         << setw(12) << setprecision(3) << obsValue(tLC) << " "
    657         << setw(12) << setprecision(3) << cmpValue(tLC) << " "
    658         << setw(12) << setprecision(3) << obsValue(tLC)  - cmpValue(tLC) << endl;
    659   }
    660 }
    661 
    662 //
    663 ////////////////////////////////////////////////////////////////////////////
    664 double t_pppSatObs::cmpValueForBanc(t_lc::type tLC) const {
    665   return cmpValue(tLC) - _model._rho - _model._sagnac - _model._recClkM;
    666 }
    667 
    668 //
    669 ////////////////////////////////////////////////////////////////////////////
    670 double t_pppSatObs::cmpValue(t_lc::type tLC) const {
     665    t_lc LC = OPT->LCs(sys)[ii];
     666    LOG << "OBS-CMP " << setw(4) << LC.toString() << ": " << _prn.toString() << " "
     667        << setw(12) << setprecision(3) << obsValue(LC) << " "
     668        << setw(12) << setprecision(3) << cmpValue(LC) << " "
     669        << setw(12) << setprecision(3) << obsValue(LC)  - cmpValue(LC) << endl;
     670  }
     671}
     672
     673//
     674////////////////////////////////////////////////////////////////////////////
     675double t_pppSatObs::cmpValueForBanc(t_lc LC) const {
     676  return cmpValue(LC) - _model._rho - _model._sagnac - _model._recClkM;
     677}
     678
     679//
     680////////////////////////////////////////////////////////////////////////////
     681double t_pppSatObs::cmpValue(t_lc LC) const {
    671682  double cmpValue;
    672683
    673   if      (!isValid(tLC)) {
     684  if      (!isValid(LC)) {
    674685    cmpValue =  0.0;
    675686  }
    676   else if (tLC == t_lc::GIM) {
     687  else if (LC._type == t_lc::GIM) {
    677688    cmpValue =  _stecSat;
    678689  }
     
    691702    map<t_frequency::type, double> phaseCoeff;
    692703    map<t_frequency::type, double> ionoCoeff;
    693     lcCoeff(tLC, codeCoeff, phaseCoeff, ionoCoeff);
     704    lcCoeff(LC, codeCoeff, phaseCoeff, ionoCoeff);
    694705    map<t_frequency::type, double>::const_iterator it;
    695706    for (it = codeCoeff.begin(); it != codeCoeff.end(); it++) {
    696707      t_frequency::type tFreq = it->first;
    697708      dispPart += it->second * (_model._antPCO[tFreq] - _model._codeBias[tFreq]);
    698       if (OPT->PPP_RTK) {
    699         dispPart += it->second * (_model._ionoCodeDelay[tFreq]);
    700       }
    701709    }
    702710    for (it = phaseCoeff.begin(); it != phaseCoeff.end(); it++) {
     
    704712      dispPart += it->second * (_model._antPCO[tFreq] - _model._phaseBias[tFreq] +
    705713                                _model._windUp * t_CST::lambda(tFreq, _channel));
    706       if (OPT->PPP_RTK) {
    707         dispPart += it->second * (- _model._ionoCodeDelay[tFreq]);
    708       }
    709714    }
    710715    cmpValue = nonDisp + dispPart;
     
    716721//
    717722////////////////////////////////////////////////////////////////////////////
    718 void t_pppSatObs::setRes(t_lc::type tLC, double res) {
    719   _res[tLC] = res;
    720 }
    721 
    722 //
    723 ////////////////////////////////////////////////////////////////////////////
    724 double t_pppSatObs::getRes(t_lc::type tLC) const {
    725   map<t_lc::type, double>::const_iterator it = _res.find(tLC);
     723void t_pppSatObs::setRes(t_lc LC, double res) {
     724  _res[LC] = res;
     725}
     726
     727//
     728////////////////////////////////////////////////////////////////////////////
     729double t_pppSatObs::getRes(t_lc LC) const {
     730  map<t_lc, double>::const_iterator it = _res.find(LC);
    726731  if (it != _res.end()) {
    727732    return it->second;
     
    742747  return pseudoObsIono;
    743748}
     749
     750//
     751////////////////////////////////////////////////////////////////////////////
     752bool t_pppSatObs::hasBiases() const {
     753  bool ar = OPT->arSystem(_prn.system());
     754  set<t_frequency::type> frqs;
     755  for (const auto& lc : OPT->LCs(_prn.system())) {
     756    if (lc._frq1 != t_frequency::dummy) frqs.insert(lc._frq1);
     757    if (lc._frq2 != t_frequency::dummy) frqs.insert(lc._frq2);
     758  }
     759  for (int iFreq : frqs) {
     760    if (_obs[iFreq] != 0) {
     761      if (_model._codeBias[iFreq] == 0 || (ar && _model._phaseBias[iFreq] == 0)) {
     762        return false;
     763      }
     764    }
     765  }
     766  return true;
     767}
  • trunk/BNC/src/PPP/pppSatObs.h

    r10251 r10791  
    1111namespace BNC_PPP {
    1212
    13 class t_pppStation;
     13  class t_pppStation;
    1414
    15 class t_pppSatObs {
    16  public:
    17   t_pppSatObs(const t_satObs& satObs);
    18   ~t_pppSatObs();
    19   bool                isValid() const {return _valid;};
    20   bool                isValid(t_lc::type tLC) const;
    21   bool                isReference() const {return _reference;};
    22   void                setAsReference() {_reference = true;};
    23   void                resetReference() {_reference = false;};
    24   const t_prn&        prn() const {return _prn;}
    25   const ColumnVector& xc() const {return _xcSat;}
    26   const bncTime&      time() const {return _time;}
    27   t_irc               cmpModel(const t_pppStation* station);
    28   double              obsValue(t_lc::type tLC, bool* valid = 0) const;
    29   double              cmpValue(t_lc::type tLC) const;
    30   double              cmpValueForBanc(t_lc::type tLC) const;
    31   double              rho() const {return _model._rho;}
    32   double              sagnac() const {return _model._sagnac;}
    33   double              eleSat() const {return _model._eleSat;}
    34   bool                modelSet() const {return _model._set;}
    35   void                printModel() const;
    36   void                printObsMinusComputed() const;
    37   void                lcCoeff(t_lc::type tLC,
    38                               std::map<t_frequency::type, double>& codeCoeff,
    39                               std::map<t_frequency::type, double>& phaseCoeff,
    40                               std::map<t_frequency::type, double>& ionoCoeff) const;
    41   double              lambda(t_lc::type tLC) const;
    42   double              sigma(t_lc::type tLC) const;
    43   double              maxRes(t_lc::type tLC) const;
    44   bool                outlier() const {return _outlier;}
    45   void                setOutlier() {_outlier = true;}
    46   void                resetOutlier() {_outlier = false;}
    47   void                setRes(t_lc::type tLC, double res);
    48   double              getRes(t_lc::type tLC) const;
    49   bool                setPseudoObsIono(t_frequency::type freq);
    50   double              getIonoCodeDelay(t_frequency::type freq) {return _model._ionoCodeDelay[freq];}
    51   double              getCodeBias(t_frequency::type freq) {return _model._codeBias[freq];}
    52   t_frequency::type   fType1() const {return _fType1;}
    53   t_frequency::type   fType2() const {return _fType2;}
     15  class t_pppSatObs {
     16  public:
     17    t_pppSatObs(const t_satObs& satObs);
     18    ~t_pppSatObs();
     19    bool                isValid() const {return _valid;};
     20    bool                isValid(t_lc LC) const;
     21    t_lc                rangeLC() const {return _rangeLC;};
     22    bool                isReference() const {return _reference;};
     23    void                setAsReference() {_reference = true;};
     24    void                resetReference() {_reference = false;};
     25    const t_prn&        prn() const {return _prn;}
     26    const ColumnVector& xc() const {return _xcSat;}
     27    const bncTime&      time() const {return _time;}
     28    t_irc               cmpModel(const t_pppStation* station);
     29    double              obsValue(t_lc LC, bool* valid = 0) const;
     30    double              cmpValue(t_lc LC) const;
     31    double              cmpValueForBanc(t_lc LC) const;
     32    double              rho() const {return _model._rho;}
     33    double              sagnac() const {return _model._sagnac;}
     34    double              eleSat() const {return _model._eleSat;}
     35    bool                modelSet() const {return _model._set;}
     36    void                printModel() const;
     37    void                printObsMinusComputed() const;
     38    void                lcCoeff(t_lc LC,
     39                                std::map<t_frequency::type, double>& codeCoeff,
     40                                std::map<t_frequency::type, double>& phaseCoeff,
     41                                std::map<t_frequency::type, double>& ionoCoeff) const;
     42    double              lambda(t_lc LC) const;
     43    double              sigma(t_lc LC) const;
     44    double              maxRes(t_lc LC) const;
     45    bool                outlier() const {return _outlier;}
     46    void                setOutlier() {_outlier = true;}
     47    void                resetOutlier() {_outlier = false;}
     48    void                setRes(t_lc LC, double res);
     49    double              getRes(t_lc LC) const;
     50    bool                setPseudoObsIono(t_frequency::type freq);
     51    double              getIonoCodeDelay(t_frequency::type freq) {return _model._ionoCodeDelay[freq];}
     52    double              getCodeBias(t_frequency::type freq) {return _model._codeBias[freq];}
     53    bool                hasBiases() const;
    5454
    55   // RINEX
    56   bool slip() const {
    57     for (unsigned ii = 1; ii < t_frequency::max; ii++) {
    58       if (_obs[ii] && _obs[ii]->_slip) {
    59         return true;
     55    // RINEX
     56    bool slip() const {
     57      for (unsigned ii = 1; ii < t_frequency::max; ii++) {
     58        if (_obs[ii] && _obs[ii]->_slip) {
     59          return true;
     60        }
    6061      }
     62      return false;
    6163    }
    62     return false;
    63   }
    6464
    65   // RTCM
    66   int slipCounter() const {
    67     int cnt = -1;
    68     for (unsigned ii = 1; ii < t_frequency::max; ii++) {
    69       if (_obs[ii] && _obs[ii]->_slipCounter > cnt) {
    70         cnt = _obs[ii]->_slipCounter;
     65    // RTCM
     66    int slipCounter() const {
     67      int cnt = -1;
     68      for (unsigned ii = 1; ii < t_frequency::max; ii++) {
     69        if (_obs[ii] && _obs[ii]->_slipCounter > cnt) {
     70          cnt = _obs[ii]->_slipCounter;
     71        }
    7172      }
     73      return cnt;
    7274    }
    73     return cnt;
    74   }
    7575
    76   int biasJumpCounter() const {
    77     int jmp = -1;
    78     for (unsigned ii = 1; ii < t_frequency::max; ii++) {
    79       if (_obs[ii] && _obs[ii]->_biasJumpCounter > jmp) {
    80         jmp = _obs[ii]->_biasJumpCounter;
     76    int biasJumpCounter() const {
     77      int jmp = -1;
     78      for (unsigned ii = 1; ii < t_frequency::max; ii++) {
     79        if (_obs[ii] && _obs[ii]->_biasJumpCounter > jmp) {
     80          jmp = _obs[ii]->_biasJumpCounter;
     81        }
    8182      }
     83      return jmp;
    8284    }
    83     return jmp;
    84   }
    8585
    86  private:
    87   class t_model {
    88    public:
    89     t_model() {reset();}
    90     ~t_model() {}
    91     void reset() {
    92       _set       = false;
    93       _rho       = 0.0;
    94       _eleSat    = 0.0;
    95       _azSat     = 0.0;
    96       _elTx      = 0.0;
    97       _azTx      = 0.0;
    98       _recClkM   = 0.0;
    99       _satClkM   = 0.0;
    100       _sagnac    = 0.0;
    101       _antEcc    = 0.0;
    102       _tropo     = 0.0;
    103       _tropo0    = 0.0;
    104       _tideEarth = 0.0;
    105       _tideOcean = 0.0;
    106       _windUp    = 0.0;
    107       _rel       = 0.0;
    108       for (unsigned ii = 0; ii < t_frequency::max; ii++) {
    109         _antPCO[ii]        = 0.0;
    110         _codeBias[ii]      = 0.0;
    111         _phaseBias[ii]     = 0.0;
    112         _ionoCodeDelay[ii] = 0.0;
     86  private:
     87    class t_model {
     88    public:
     89      t_model() {reset();}
     90      ~t_model() {}
     91      void reset() {
     92        _set       = false;
     93        _rho       = 0.0;
     94        _eleSat    = 0.0;
     95        _azSat     = 0.0;
     96        _elTx      = 0.0;
     97        _azTx      = 0.0;
     98        _recClkM   = 0.0;
     99        _satClkM   = 0.0;
     100        _sagnac    = 0.0;
     101        _antEcc    = 0.0;
     102        _tropo     = 0.0;
     103        _tropo0    = 0.0;
     104        _tideEarth = 0.0;
     105        _tideOcean = 0.0;
     106        _windUp    = 0.0;
     107        _rel       = 0.0;
     108        for (unsigned ii = 0; ii < t_frequency::max; ii++) {
     109          _antPCO[ii]        = 0.0;
     110          _codeBias[ii]      = 0.0;
     111          _phaseBias[ii]     = 0.0;
     112          _ionoCodeDelay[ii] = 0.0;
     113        }
    113114      }
    114     }
    115     bool   _set;
    116     double _rho;
    117     double _eleSat;
    118     double _azSat;
    119     double _elTx;
    120     double _azTx;
    121     double _recClkM;
    122     double _satClkM;
    123     double _sagnac;
    124     double _antEcc;
    125     double _tropo;
    126     double _tropo0;
    127     double _tideEarth;
    128     double _tideOcean;
    129     double _windUp;
    130     double _rel;
    131     double _antPCO[t_frequency::max];
    132     double _codeBias[t_frequency::max];
    133     double _phaseBias[t_frequency::max];
    134     double _ionoCodeDelay[t_frequency::max];
     115      bool   _set;
     116      double _rho;
     117      double _eleSat;
     118      double _azSat;
     119      double _elTx;
     120      double _azTx;
     121      double _recClkM;
     122      double _satClkM;
     123      double _sagnac;
     124      double _antEcc;
     125      double _tropo;
     126      double _tropo0;
     127      double _tideEarth;
     128      double _tideOcean;
     129      double _windUp;
     130      double _rel;
     131      double _antPCO[t_frequency::max];
     132      double _codeBias[t_frequency::max];
     133      double _phaseBias[t_frequency::max];
     134      double _ionoCodeDelay[t_frequency::max];
     135    };
     136
     137    void prepareObs(const t_satObs& satObs);
     138
     139    bool isBetter(const t_frqObs* aa, t_frqObs* bb, const std::string& trkModes) const;
     140
     141    bool                   _valid;
     142    bool                   _reference;
     143    t_lc                   _rangeLC;
     144    t_prn                  _prn;
     145    bncTime                _time;
     146    int                    _channel;
     147    t_frqObs*              _obs[t_frequency::max];
     148    ColumnVector           _xcSat;
     149    ColumnVector           _vvSat;
     150    t_model                _model;
     151    bool                   _outlier;
     152    std::map<t_lc, double> _res;
     153    double                 _signalPropagationTime;
     154    double                 _stecSat;
     155    double                 _tropo0;
    135156  };
    136 
    137   void prepareObs(const t_satObs& satObs);
    138 
    139   bool                         _valid;
    140   bool                         _reference;
    141   t_frequency::type            _fType1;
    142   t_frequency::type            _fType2;
    143   t_prn                        _prn;
    144   bncTime                      _time;
    145   int                          _channel;
    146   t_frqObs*                    _obs[t_frequency::max];
    147   ColumnVector                 _xcSat;
    148   ColumnVector                 _vvSat;
    149   t_model                      _model;
    150   bool                         _outlier;
    151   std::map<t_lc::type, double> _res;
    152   double                       _signalPropagationTime;
    153   double                       _stecSat;
    154   double                       _tropo0;
    155   QString                      _signalPriorities;
    156         };
    157157
    158158}
  • trunk/BNC/src/bncconst.cpp

    r10619 r10791  
    8181  return c / freq(fType, slotNum);
    8282}
     83
     84//
     85//////////////////////////////////////////////////////////////////////////////
     86t_frequency::type t_frequency::toFreq(char sys, char bb) {
     87  switch (bb) {
     88  case '1':
     89    if      (sys == 'G') return t_frequency::G1;
     90    else if (sys == 'R') return t_frequency::R1;
     91    else if (sys == 'E') return t_frequency::E1;
     92    else if (sys == 'C') return t_frequency::C1;
     93    else                 return t_frequency::dummy;
     94  case '2':
     95    if      (sys == 'G') return t_frequency::G2;
     96    else if (sys == 'R') return t_frequency::R2;
     97    else if (sys == 'C') return t_frequency::C2;
     98    else                 return t_frequency::dummy;
     99  case '5':
     100    if      (sys == 'G') return t_frequency::G5;
     101    else if (sys == 'E') return t_frequency::E5;
     102    else if (sys == 'C') return t_frequency::C5;
     103    else                 return t_frequency::dummy;
     104  case '6':
     105    if      (sys == 'E') return t_frequency::E6;
     106    else if (sys == 'C') return t_frequency::C6;
     107    else                 return t_frequency::dummy;
     108  case '7':
     109    if      (sys == 'E') return t_frequency::E7;
     110    else if (sys == 'C') return t_frequency::C7;
     111    else                 return t_frequency::dummy;
     112  case '8':
     113    if      (sys == 'E') return t_frequency::E8;
     114    else if (sys == 'C') return t_frequency::C8;
     115    else                 return t_frequency::dummy;
     116  }
     117  return t_frequency::dummy;
     118}
     119
  • trunk/BNC/src/bncconst.h

    r10619 r10791  
    106106    return std::string();
    107107  }
     108
     109  static char toSystem(type tt) {
     110    std::string str = t_frequency::toString(tt);
     111    if (str.length() > 0) {
     112      return str[0];
     113    }
     114    else {
     115      return '?';
     116    }
     117  }
     118 
    108119  static enum type toInt(std::string s) {
    109120    // GPS
     
    141152    return type();
    142153  }
     154
     155  static type toFreq(char sys, char frqChar);
    143156};
    144157
  • trunk/BNC/src/bncmain.cpp

    r10753 r10791  
    249249        "   PPP/logPath     {Directory for PPP log files [character string]}\n"
    250250        "   PPP/antexFile   {ANTEX file, full path [character string]}\n"
    251 #ifdef USE_PPP
    252251        "   PPP/blqFile     {BLQ file, full path [character string]}\n"
    253252        "   PPP/ionoMount   {VTEC mountpoint, [char string]}\n"
    254253        "   PPP/ionoFile    {VTEC file, full path [char string]}\n"
    255 #endif
    256254        "   PPP/nmeaPath      {Directory for NMEA output files [character string]}\n"
    257255        "   PPP/snxtroPath    {Directory for SINEX troposphere output files [character string]}\n"
     
    278276        "   PPP/corrWaitTime {Wait for clock corrections [integer number of seconds: 0-20]}\n"
    279277        "   PPP/seedingTime  {Seeding time span for Quick Start [integer number of seconds]}\n"
    280 #ifdef USE_PPP
    281278        "   PPP/constraints  {Specify, whether ionospheric constraints in form of pseudo-observations shall be added [character string: no|Ionosphere: pseudo-obs]}\n"
    282279        "   PPP/sigmaGIM     {Sigma for GIM pseudo observations in meters [floating-point number]}\n"
    283280        "   PPP/maxResGIM    {Maximal residuum for GIM pseudo observations in meters [floating-point number]}\n"
    284 #endif
    285281        "\n"
    286282        "PPP Client Panel 3 keys:\n"
  • trunk/BNC/src/bncsinextro.cpp

    r10548 r10791  
    8989    corr = settings.value("PPP/corrFile").toString();
    9090  }
    91   QString signalPriorities = QString::fromStdString(_opt->_signalPriorities);
    92   if (!signalPriorities.size()) {
    93     signalPriorities = "G:12&CWPSLX R:12&CP E:1&CBX E:5&QIX C:26&IQX";
    94   }
    95   QStringList priorList = signalPriorities.split(" ", Qt::SkipEmptyParts);
    96   QStringList frqStrList;
    97   for (unsigned iFreq = 1; iFreq < t_frequency::max; iFreq++) {
    98     t_frequency::type frqType = static_cast<t_frequency::type>(iFreq);
    99     char frqSys = t_frequency::toString(frqType)[0];
    100     char frqNum = t_frequency::toString(frqType)[1];
    101     QStringList hlp;
    102     for (int ii = 0; ii < priorList.size(); ii++) {
    103       if (priorList[ii].indexOf(":") != -1) {
    104         hlp = priorList[ii].split(":", Qt::SkipEmptyParts);
    105         if (hlp.size() == 2 && hlp[0].length() == 1 && hlp[0][0] == frqSys) {
    106           hlp = hlp[1].split("&", Qt::SkipEmptyParts);
    107         }
    108         if (hlp.size() == 2 && hlp[0].indexOf(frqNum) != -1) {
    109           frqStrList.append(QString("%1%2").arg(frqSys).arg(frqNum));
    110         }
    111       }
    112     }
    113   }
    11491
    11592  _out << "%=TRO 2.00 " << ac.toStdString() << " "
  • trunk/BNC/src/bncutils.cpp

    r10619 r10791  
    809809//
    810810//////////////////////////////////////////////////////////////////////////////
     811void kalman(const vector<unique_ptr<const RowVector>>& vAA,
     812            const vector<double>& vll, const vector<double>& sigma,
     813            SymmetricMatrix& QQ, ColumnVector& xx) {
     814
     815  unsigned nPar = xx.Nrows();
     816  unsigned nObs = vAA.size();
     817
     818  Matrix         AA(nObs, nPar);
     819  ColumnVector   ll(nObs);
     820  DiagonalMatrix PP(nObs);
     821  for (unsigned iObs = 0; iObs < nObs; ++iObs) {
     822    ll[iObs]       = vll[iObs];
     823    PP[iObs]       = 1.0 / (sigma[iObs] * sigma[iObs]);
     824    const RowVector& row = *vAA[iObs];
     825    AA.row(iObs+1) = row;
     826  }
     827   return kalman(AA, ll, PP, QQ, xx);
     828}
     829
     830//
     831//////////////////////////////////////////////////////////////////////////////
    811832void kalman(const Matrix& AA, const ColumnVector& ll, const DiagonalMatrix& PP,
    812833            SymmetricMatrix& QQ, ColumnVector& xx) {
     
    11041125  };
    11051126};
     1127
     1128//
     1129////////////////////////////////////////////////////////////////////////////
     1130double sqrtMod(double val) {
     1131  return val > 0.0 ? std::sqrt(val) : 0.0;
     1132}
  • trunk/BNC/src/bncutils.h

    r10599 r10791  
    137137                    SymmetricMatrix& QQ, ColumnVector& xx);
    138138
     139void         kalman(const std::vector<std::unique_ptr<const RowVector>>& AA,
     140                    const std::vector<double>& ll, const std::vector<double>& sigma,
     141                    SymmetricMatrix& QQ, ColumnVector& xx);
     142
    139143double       djul(long j1, long m1, double tt);
    140144
     
    157161double       factorial(int n);
    158162
     163double       sqrtMod(double val);
     164
    159165/** Convert RTCM3 lock-time indicator to lock time in seconds
    160166* depending on input message format. Returns -1 if format is
  • trunk/BNC/src/bncwindow.cpp

    r10776 r10791  
    102102bncWindow::bncWindow() {
    103103
    104     const static QPalette paletteWhite(QColor(255, 255, 255));
    105     const static QPalette paletteGray(QColor(230, 230, 230));
    106 
    107     _caster = 0;
    108     _casterEph = 0;
    109 
    110     _bncFigure = new bncFigure(this);
    111     _bncFigureLate = new bncFigureLate(this);
    112     _bncFigurePPP = new bncFigurePPP(this);
    113 
    114     connect(BNC_CORE, SIGNAL(newPosition(QByteArray, bncTime, QVector<double>)),
    115         _bncFigurePPP, SLOT(slotNewPosition(QByteArray, bncTime, QVector<double>)));
    116 
    117     connect(BNC_CORE, SIGNAL(progressRnxPPP(int)), this, SLOT(slotPostProcessingProgress(int)));
    118     connect(BNC_CORE, SIGNAL(finishedRnxPPP()), this, SLOT(slotPostProcessingFinished()));
    119 
    120     _runningRealTime = false;
    121     _runningPPP = false;
    122     _runningEdit = false;
    123     _runningQC = false;
    124     _runningSp3Comp = false;
    125     _reqcActionComboBox = 0; // necessary for enableStartStop()
    126 
    127     _mapWin = 0;
    128 
    129     int ww = QFontMetrics(this->font()).horizontalAdvance('w');
    130 
    131     static const QStringList labels = QString("account, Streams:   resource loader / mountpoint, decoder, country, lat, long, nmea, ntrip, bytes").split(",");
    132 
    133     setMinimumSize(100 * ww, 70 * ww);
    134 
    135     setWindowTitle(tr("BKG Ntrip Client (BNC) Version " BNCVERSION));
    136 
    137     connect(BNC_CORE, SIGNAL(newMessage(QByteArray, bool)),
    138         this, SLOT(slotWindowMessage(QByteArray, bool)));
    139 
    140     // Create Actions
    141     // --------------
    142     _actHelp = new QAction(tr("&Help Contents"), this);
    143     connect(_actHelp, SIGNAL(triggered()), SLOT(slotHelp()));
    144 
    145     _actAbout = new QAction(tr("&About BNC"), this);
    146     connect(_actAbout, SIGNAL(triggered()), SLOT(slotAbout()));
    147 
    148     _actFlowchart = new QAction(tr("&Flow Chart"), this);
    149     connect(_actFlowchart, SIGNAL(triggered()), SLOT(slotFlowchart()));
    150 
    151     _actFontSel = new QAction(tr("Select &Font"), this);
    152     connect(_actFontSel, SIGNAL(triggered()), SLOT(slotFontSel()));
    153 
    154     _actSaveOpt = new QAction(tr("&Reread && Save Configuration"), this);
    155     connect(_actSaveOpt, SIGNAL(triggered()), SLOT(slotSaveOptions()));
    156 
    157     _actQuit = new QAction(tr("&Quit"), this);
    158     connect(_actQuit, SIGNAL(triggered()), SLOT(close()));
    159 
    160     _actAddMountPoints = new QAction(tr("Add &Stream"), this);
    161     connect(_actAddMountPoints, SIGNAL(triggered()), SLOT(slotAddMountPoints()));
    162 
    163     _actDeleteMountPoints = new QAction(tr("&Delete Stream"), this);
    164     connect(_actDeleteMountPoints, SIGNAL(triggered()), SLOT(slotDeleteMountPoints()));
    165     _actDeleteMountPoints->setEnabled(false);
    166 
    167     _actMapMountPoints = new QAction(tr("&Map"), this);
    168     connect(_actMapMountPoints, SIGNAL(triggered()), SLOT(slotMapMountPoints()));
    169 
    170     _actStart = new QAction(tr("Sta&rt"), this);
    171     connect(_actStart, SIGNAL(triggered()), SLOT(slotStart()));
    172 
    173     _actStop = new QAction(tr("Sto&p"), this);
    174     connect(_actStop, SIGNAL(triggered()), SLOT(slotStop()));
    175     connect(_actStop, SIGNAL(triggered()), SLOT(slotMapPPPClosed()));
    176 
    177     _actwhatsthis = new QAction(tr("Help?=Shift+F1"), this);
    178     connect(_actwhatsthis, SIGNAL(triggered()), SLOT(slotWhatsThis()));
    179 
    180     CreateMenu();
    181     AddToolbar();
    182 
    183     bncSettings settings;
    184 
    185     // Network Options
    186     // ---------------
    187     _proxyHostLineEdit = new QLineEdit(settings.value("proxyHost").toString());
    188     _proxyPortLineEdit = new QLineEdit(settings.value("proxyPort").toString());
    189 
    190     connect(_proxyHostLineEdit, SIGNAL(textChanged(const QString&)),
    191         this, SLOT(slotBncTextChanged()));
    192 
    193     _sslCaCertPathLineEdit = new QLineEdit(settings.value("sslCaCertPath").toString());
    194     _sslClientCertPathLineEdit = new QLineEdit(settings.value("sslClientCertPath").toString());
    195     _sslIgnoreErrorsCheckBox = new QCheckBox();
    196     _sslIgnoreErrorsCheckBox->setCheckState(Qt::CheckState(
    197         settings.value("sslIgnoreErrors").toInt()));
    198 
    199     // General Options
    200     // ---------------
    201     _logFileLineEdit = new QLineEdit(settings.value("logFile").toString());
    202     _rawOutFileLineEdit = new QLineEdit(settings.value("rawOutFile").toString());
    203     _rnxAppendCheckBox = new QCheckBox();
    204     _rnxAppendCheckBox->setCheckState(Qt::CheckState(
    205         settings.value("rnxAppend").toInt()));
    206     _onTheFlyComboBox = new QComboBox();
    207     _onTheFlyComboBox->setEditable(false);
    208     _onTheFlyComboBox->addItems(QString("no,1 day,1 hour,5 min,1 min").split(","));
    209     int go = _onTheFlyComboBox->findText(settings.value("onTheFlyInterval").toString());
    210     if (go != -1) {
    211         _onTheFlyComboBox->setCurrentIndex(go);
    212     }
    213     _autoStartCheckBox = new QCheckBox();
    214     _autoStartCheckBox->setCheckState(Qt::CheckState(
    215         settings.value("autoStart").toInt()));
    216 
    217     // RINEX Observations Options
    218     // --------------------------
    219     _rnxPathLineEdit = new QLineEdit(settings.value("rnxPath").toString());
    220     _rnxIntrComboBox = new QComboBox();
    221     _rnxIntrComboBox->setEditable(false);
    222     _rnxIntrComboBox->addItems(QString("1 min,2 min,5 min,10 min,15 min,30 min,1 hour,1 day").split(","));
    223     int ii = _rnxIntrComboBox->findText(settings.value("rnxIntr").toString());
    224     if (ii != -1) {
    225         _rnxIntrComboBox->setCurrentIndex(ii);
    226     }
    227     _rnxSamplComboBox = new QComboBox();
    228     _rnxSamplComboBox->setEditable(false);
    229     _rnxSamplComboBox->addItems(QString("0.1 sec,1 sec,5 sec,10 sec,15 sec,30 sec,60 sec").split(","));
    230     int ij = _rnxSamplComboBox->findText(settings.value("rnxSampl").toString());
    231     if (ij != -1) {
    232         _rnxSamplComboBox->setCurrentIndex(ij);
    233     }
    234     _rnxFileCheckBox = new QCheckBox();
    235     _rnxFileCheckBox->setCheckState(Qt::CheckState(settings.value("rnxOnlyWithSKL").toInt()));
    236     _rnxSkelExtComboBox = new QComboBox();
    237     _rnxSkelExtComboBox->setEditable(false);
    238     _rnxSkelExtComboBox->addItems(QString("skl,SKL").split(","));
    239     int ik = _rnxSkelExtComboBox->findText(settings.value("rnxSkel").toString());
    240     if (ik != -1) {
    241         _rnxSkelExtComboBox->setCurrentIndex(ik);
    242     }
    243     _rnxSkelPathLineEdit = new QLineEdit(settings.value("rnxSkelPath").toString());
    244     _rnxScrpLineEdit = new QLineEdit(settings.value("rnxScript").toString());
    245     _rnxVersComboBox = new QComboBox();
    246     _rnxVersComboBox->setEditable(false);
    247     _rnxVersComboBox->addItems(QString("4,3,2").split(","));
    248     _rnxVersComboBox->setMaximumWidth(7 * ww);
    249     int il = _rnxVersComboBox->findText(settings.value("rnxVersion").toString());
    250     if (il != -1) {
    251         _rnxVersComboBox->setCurrentIndex(il);
    252     }
    253     QString hlp = settings.value("rnxV2Priority").toString();
    254     if (hlp.isEmpty()) {
    255         hlp = "G:12&PWCSLX G:5&IQX R:12&PC R:3&IQX R:46&ABX E:16&BCXZ E:578&IQX J:1&SLXCZ J:26&SLX J:5&IQX C:267&IQX C:18&DPX I:ABCX S:1&C S:5&IQX";
    256     }
    257     _rnxV2Priority = new QLineEdit(hlp);
    258 
    259     connect(_rnxPathLineEdit, SIGNAL(textChanged(const QString&)), this, SLOT(slotBncTextChanged()));
    260     connect(_rnxSkelPathLineEdit, SIGNAL(textChanged(const QString&)), this, SLOT(slotBncTextChanged()));
    261     connect(_rnxVersComboBox, SIGNAL(currentIndexChanged(const QString&)), this, SLOT(slotBncTextChanged()));
    262 
    263     // RINEX Ephemeris Options
    264     // -----------------------
    265     _ephPathLineEdit = new QLineEdit(settings.value("ephPath").toString());
    266     _ephIntrComboBox = new QComboBox();
    267     _ephIntrComboBox->setEditable(false);
    268     _ephIntrComboBox->addItems(QString("1 min,2 min,5 min,10 min,15 min,30 min,1 hour,1 day").split(","));
    269     int ji = _ephIntrComboBox->findText(settings.value("ephIntr").toString());
    270     if (ji != -1) {
    271         _ephIntrComboBox->setCurrentIndex(ji);
    272     }
    273     _ephOutPortLineEdit = new QLineEdit(settings.value("ephOutPort").toString());
    274     _ephVersComboBox = new QComboBox();
    275     _ephVersComboBox->setEditable(false);
    276     _ephVersComboBox->addItems(QString("4,3,2").split(","));
    277     _ephVersComboBox->setMaximumWidth(7 * ww);
    278     int jk = _ephVersComboBox->findText(settings.value("ephVersion").toString());
    279     if (jk != -1) {
    280         _ephVersComboBox->setCurrentIndex(jk);
    281     }
    282     //_ephFilePerStation = new QCheckBox();
    283     //_ephFilePerStation->setCheckState(Qt::CheckState(settings.value("ephFilePerStation").toInt()));
    284 
    285     connect(_ephOutPortLineEdit, SIGNAL(textChanged(const QString&)),
    286         this, SLOT(slotBncTextChanged()));
    287 
    288     connect(_ephPathLineEdit, SIGNAL(textChanged(const QString&)),
    289         this, SLOT(slotBncTextChanged()));
    290 
    291     // Broadcast Corrections Options
    292     // -----------------------------
    293     _corrPathLineEdit = new QLineEdit(settings.value("corrPath").toString());
    294     _corrIntrComboBox = new QComboBox();
    295     _corrIntrComboBox->setEditable(false);
    296     _corrIntrComboBox->addItems(QString("1 min,2 min,5 min,10 min,15 min,30 min,1 hour,1 day").split(","));
    297     int bi = _corrIntrComboBox->findText(settings.value("corrIntr").toString());
    298     if (bi != -1) {
    299         _corrIntrComboBox->setCurrentIndex(bi);
    300     }
    301     _corrPortLineEdit = new QLineEdit(settings.value("corrPort").toString());
    302 
    303     connect(_corrPathLineEdit, SIGNAL(textChanged(const QString&)),
    304         this, SLOT(slotBncTextChanged()));
    305 
    306     connect(_corrPortLineEdit, SIGNAL(textChanged(const QString&)),
    307         this, SLOT(slotBncTextChanged()));
    308 
    309     // Feed Engine Options
    310     // -------------------
    311     _outPortLineEdit = new QLineEdit(settings.value("outPort").toString());
    312     _outWaitSpinBox = new QSpinBox();
    313     _outWaitSpinBox->setMinimum(0);
    314     _outWaitSpinBox->setMaximum(30);
    315     _outWaitSpinBox->setSingleStep(1);
    316     _outWaitSpinBox->setSuffix(" sec");
    317     _outWaitSpinBox->setValue(settings.value("outWait").toInt());
    318     _outSamplComboBox = new QComboBox();
    319     _outSamplComboBox->addItems(QString("0.1 sec,1 sec,5 sec,10 sec,15 sec,30 sec,60 sec").split(","));
    320     int nn = _outSamplComboBox->findText(settings.value("outSampl").toString());
    321     if (nn != -1) {
    322         _outSamplComboBox->setCurrentIndex(nn);
    323     }
    324     _outFileLineEdit = new QLineEdit(settings.value("outFile").toString());
    325     _outUPortLineEdit = new QLineEdit(settings.value("outUPort").toString());
    326     _outLockTimeCheckBox = new QCheckBox();
    327     _outLockTimeCheckBox->setCheckState(Qt::CheckState(settings.value("outLockTime").toInt()));
    328 
    329     connect(_outPortLineEdit, SIGNAL(textChanged(const QString&)),
    330         this, SLOT(slotBncTextChanged()));
    331 
    332     connect(_outFileLineEdit, SIGNAL(textChanged(const QString&)),
    333         this, SLOT(slotBncTextChanged()));
    334 
    335     connect(_outLockTimeCheckBox, SIGNAL(stateChanged(int)),
    336         this, SLOT(slotBncTextChanged()));
    337 
    338     // Serial Output Options
    339     // ---------------------
    340     _serialMountPointLineEdit = new QLineEdit(settings.value("serialMountPoint").toString());
    341     _serialPortNameLineEdit = new QLineEdit(settings.value("serialPortName").toString());
    342     _serialBaudRateComboBox = new QComboBox();
    343     _serialBaudRateComboBox->addItems(QString("110,300,600,"
    344         "1200,2400,4800,9600,19200,38400,57600,115200").split(","));
    345     int kk = _serialBaudRateComboBox->findText(settings.value("serialBaudRate").toString());
    346     if (kk != -1) {
    347         _serialBaudRateComboBox->setCurrentIndex(kk);
    348     }
    349     _serialFlowControlComboBox = new QComboBox();
    350     _serialFlowControlComboBox->addItems(QString("OFF,XONXOFF,HARDWARE").split(","));
    351     kk = _serialFlowControlComboBox->findText(settings.value("serialFlowControl").toString());
    352     if (kk != -1) {
    353         _serialFlowControlComboBox->setCurrentIndex(kk);
    354     }
    355     _serialDataBitsComboBox = new QComboBox();
    356     _serialDataBitsComboBox->addItems(QString("5,6,7,8").split(","));
    357     kk = _serialDataBitsComboBox->findText(settings.value("serialDataBits").toString());
    358     if (kk != -1) {
    359         _serialDataBitsComboBox->setCurrentIndex(kk);
    360     }
    361     _serialParityComboBox = new QComboBox();
    362     _serialParityComboBox->addItems(QString("NONE,ODD,EVEN,SPACE").split(","));
    363     kk = _serialParityComboBox->findText(settings.value("serialParity").toString());
    364     if (kk != -1) {
    365         _serialParityComboBox->setCurrentIndex(kk);
    366     }
    367     _serialStopBitsComboBox = new QComboBox();
    368     _serialStopBitsComboBox->addItems(QString("1,2").split(","));
    369     kk = _serialStopBitsComboBox->findText(settings.value("serialStopBits").toString());
    370     if (kk != -1) {
    371         _serialStopBitsComboBox->setCurrentIndex(kk);
    372     }
    373     _serialAutoNMEAComboBox = new QComboBox();
    374     _serialAutoNMEAComboBox->addItems(QString("no,Auto,Manual GPGGA,Manual GNGGA").split(","));
    375     kk = _serialAutoNMEAComboBox->findText(settings.value("serialAutoNMEA").toString());
    376     if (kk != -1) {
    377         _serialAutoNMEAComboBox->setCurrentIndex(kk);
    378     }
    379     _serialFileNMEALineEdit = new QLineEdit(settings.value("serialFileNMEA").toString());
    380     _serialHeightNMEALineEdit = new QLineEdit(settings.value("serialHeightNMEA").toString());
    381 
    382     _serialNMEASamplingSpinBox = new QSpinBox();
    383     _serialNMEASamplingSpinBox->setMinimum(0);
    384     _serialNMEASamplingSpinBox->setMaximum(300);
    385     _serialNMEASamplingSpinBox->setSingleStep(10);
    386     _serialNMEASamplingSpinBox->setValue(settings.value("serialNMEASampling").toInt());
    387     _serialNMEASamplingSpinBox->setSuffix(" sec");
    388 
    389     connect(_serialMountPointLineEdit, SIGNAL(textChanged(const QString&)),
    390         this, SLOT(slotBncTextChanged()));
    391 
    392     connect(_serialAutoNMEAComboBox, SIGNAL(currentIndexChanged(const QString&)),
    393         this, SLOT(slotBncTextChanged()));
    394 
    395     // Outages Options
    396     // ---------------
    397     _adviseObsRateComboBox = new QComboBox();
    398     _adviseObsRateComboBox->setEditable(false);
    399     _adviseObsRateComboBox->addItems(QString(",0.1 Hz,0.2 Hz,0.5 Hz,1 Hz,5 Hz").split(","));
    400     kk = _adviseObsRateComboBox->findText(settings.value("adviseObsRate").toString());
    401     if (kk != -1) {
    402         _adviseObsRateComboBox->setCurrentIndex(kk);
    403     }
    404     _adviseFailSpinBox = new QSpinBox();
    405     _adviseFailSpinBox->setMinimum(0);
    406     _adviseFailSpinBox->setMaximum(60);
    407     _adviseFailSpinBox->setSingleStep(1);
    408     _adviseFailSpinBox->setSuffix(" min");
    409     _adviseFailSpinBox->setValue(settings.value("adviseFail").toInt());
    410     _adviseRecoSpinBox = new QSpinBox();
    411     _adviseRecoSpinBox->setMinimum(0);
    412     _adviseRecoSpinBox->setMaximum(60);
    413     _adviseRecoSpinBox->setSingleStep(1);
    414     _adviseRecoSpinBox->setSuffix(" min");
    415     _adviseRecoSpinBox->setValue(settings.value("adviseReco").toInt());
    416     _adviseScriptLineEdit = new QLineEdit(settings.value("adviseScript").toString());
    417 
    418     connect(_adviseObsRateComboBox, SIGNAL(currentIndexChanged(const QString&)),
    419         this, SLOT(slotBncTextChanged()));
    420 
    421     // Miscellaneous Options
    422     // ---------------------
    423     _miscMountLineEdit = new QLineEdit(settings.value("miscMount").toString());
    424     _miscPortLineEdit = new QLineEdit(settings.value("miscPort").toString());
    425     _miscIntrComboBox = new QComboBox();
    426     _miscIntrComboBox->setEditable(false);
    427     _miscIntrComboBox->addItems(QString(",2 sec,10 sec,1 min,5 min,15 min,1 hour,6 hours,1 day").split(","));
    428     int ll = _miscIntrComboBox->findText(settings.value("miscIntr").toString());
    429     if (ll != -1) {
    430         _miscIntrComboBox->setCurrentIndex(ll);
    431     }
    432     _miscScanRTCMCheckBox = new QCheckBox();
    433     _miscScanRTCMCheckBox->setCheckState(Qt::CheckState(
    434         settings.value("miscScanRTCM").toInt()));
    435 
    436     connect(_miscMountLineEdit, SIGNAL(textChanged(const QString&)),
    437         this, SLOT(slotBncTextChanged()));
    438 
    439     // Streams
    440     // -------
    441     _mountPointsTable = new QTableWidget(0, 9);
    442 
    443     _mountPointsTable->horizontalHeader()->resizeSection(1, 34 * ww);
    444     _mountPointsTable->horizontalHeader()->resizeSection(2, 9 * ww);
    445     _mountPointsTable->horizontalHeader()->resizeSection(3, 9 * ww);
    446     _mountPointsTable->horizontalHeader()->resizeSection(4, 7 * ww);
    447     _mountPointsTable->horizontalHeader()->resizeSection(5, 7 * ww);
    448     _mountPointsTable->horizontalHeader()->resizeSection(6, 5 * ww);
    449     _mountPointsTable->horizontalHeader()->resizeSection(7, 5 * ww);
     104  const static QPalette paletteWhite(QColor(255, 255, 255));
     105  const static QPalette paletteGray(QColor(230, 230, 230));
     106
     107  _caster = 0;
     108  _casterEph = 0;
     109
     110  _bncFigure = new bncFigure(this);
     111  _bncFigureLate = new bncFigureLate(this);
     112  _bncFigurePPP = new bncFigurePPP(this);
     113
     114  connect(BNC_CORE, SIGNAL(newPosition(QByteArray, bncTime, QVector<double>)),
     115          _bncFigurePPP, SLOT(slotNewPosition(QByteArray, bncTime, QVector<double>)));
     116
     117  connect(BNC_CORE, SIGNAL(progressRnxPPP(int)), this, SLOT(slotPostProcessingProgress(int)));
     118  connect(BNC_CORE, SIGNAL(finishedRnxPPP()), this, SLOT(slotPostProcessingFinished()));
     119
     120  _runningRealTime = false;
     121  _runningPPP = false;
     122  _runningEdit = false;
     123  _runningQC = false;
     124  _runningSp3Comp = false;
     125  _reqcActionComboBox = 0; // necessary for enableStartStop()
     126
     127  _mapWin = 0;
     128
     129  int ww = QFontMetrics(this->font()).horizontalAdvance('w');
     130
     131  static const QStringList labels = QString("account, Streams:   resource loader / mountpoint, decoder, country, lat, long, nmea, ntrip, bytes").split(",");
     132
     133  setMinimumSize(100 * ww, 70 * ww);
     134
     135  setWindowTitle(tr("BKG Ntrip Client (BNC) Version " BNCVERSION));
     136
     137  connect(BNC_CORE, SIGNAL(newMessage(QByteArray, bool)),
     138          this, SLOT(slotWindowMessage(QByteArray, bool)));
     139
     140  // Create Actions
     141  // --------------
     142  _actHelp = new QAction(tr("&Help Contents"), this);
     143  connect(_actHelp, SIGNAL(triggered()), SLOT(slotHelp()));
     144
     145  _actAbout = new QAction(tr("&About BNC"), this);
     146  connect(_actAbout, SIGNAL(triggered()), SLOT(slotAbout()));
     147
     148  _actFlowchart = new QAction(tr("&Flow Chart"), this);
     149  connect(_actFlowchart, SIGNAL(triggered()), SLOT(slotFlowchart()));
     150
     151  _actFontSel = new QAction(tr("Select &Font"), this);
     152  connect(_actFontSel, SIGNAL(triggered()), SLOT(slotFontSel()));
     153
     154  _actSaveOpt = new QAction(tr("&Reread && Save Configuration"), this);
     155  connect(_actSaveOpt, SIGNAL(triggered()), SLOT(slotSaveOptions()));
     156
     157  _actQuit = new QAction(tr("&Quit"), this);
     158  connect(_actQuit, SIGNAL(triggered()), SLOT(close()));
     159
     160  _actAddMountPoints = new QAction(tr("Add &Stream"), this);
     161  connect(_actAddMountPoints, SIGNAL(triggered()), SLOT(slotAddMountPoints()));
     162
     163  _actDeleteMountPoints = new QAction(tr("&Delete Stream"), this);
     164  connect(_actDeleteMountPoints, SIGNAL(triggered()), SLOT(slotDeleteMountPoints()));
     165  _actDeleteMountPoints->setEnabled(false);
     166
     167  _actMapMountPoints = new QAction(tr("&Map"), this);
     168  connect(_actMapMountPoints, SIGNAL(triggered()), SLOT(slotMapMountPoints()));
     169
     170  _actStart = new QAction(tr("Sta&rt"), this);
     171  connect(_actStart, SIGNAL(triggered()), SLOT(slotStart()));
     172
     173  _actStop = new QAction(tr("Sto&p"), this);
     174  connect(_actStop, SIGNAL(triggered()), SLOT(slotStop()));
     175  connect(_actStop, SIGNAL(triggered()), SLOT(slotMapPPPClosed()));
     176
     177  _actwhatsthis = new QAction(tr("Help?=Shift+F1"), this);
     178  connect(_actwhatsthis, SIGNAL(triggered()), SLOT(slotWhatsThis()));
     179
     180  CreateMenu();
     181  AddToolbar();
     182
     183  bncSettings settings;
     184
     185  // Network Options
     186  // ---------------
     187  _proxyHostLineEdit = new QLineEdit(settings.value("proxyHost").toString());
     188  _proxyPortLineEdit = new QLineEdit(settings.value("proxyPort").toString());
     189
     190  connect(_proxyHostLineEdit, SIGNAL(textChanged(const QString&)),
     191          this, SLOT(slotBncTextChanged()));
     192
     193  _sslCaCertPathLineEdit = new QLineEdit(settings.value("sslCaCertPath").toString());
     194  _sslClientCertPathLineEdit = new QLineEdit(settings.value("sslClientCertPath").toString());
     195  _sslIgnoreErrorsCheckBox = new QCheckBox();
     196  _sslIgnoreErrorsCheckBox->setCheckState(Qt::CheckState(
     197                                                         settings.value("sslIgnoreErrors").toInt()));
     198
     199  // General Options
     200  // ---------------
     201  _logFileLineEdit = new QLineEdit(settings.value("logFile").toString());
     202  _rawOutFileLineEdit = new QLineEdit(settings.value("rawOutFile").toString());
     203  _rnxAppendCheckBox = new QCheckBox();
     204  _rnxAppendCheckBox->setCheckState(Qt::CheckState(
     205                                                   settings.value("rnxAppend").toInt()));
     206  _onTheFlyComboBox = new QComboBox();
     207  _onTheFlyComboBox->setEditable(false);
     208  _onTheFlyComboBox->addItems(QString("no,1 day,1 hour,5 min,1 min").split(","));
     209  int go = _onTheFlyComboBox->findText(settings.value("onTheFlyInterval").toString());
     210  if (go != -1) {
     211    _onTheFlyComboBox->setCurrentIndex(go);
     212  }
     213  _autoStartCheckBox = new QCheckBox();
     214  _autoStartCheckBox->setCheckState(Qt::CheckState(
     215                                                   settings.value("autoStart").toInt()));
     216
     217  // RINEX Observations Options
     218  // --------------------------
     219  _rnxPathLineEdit = new QLineEdit(settings.value("rnxPath").toString());
     220  _rnxIntrComboBox = new QComboBox();
     221  _rnxIntrComboBox->setEditable(false);
     222  _rnxIntrComboBox->addItems(QString("1 min,2 min,5 min,10 min,15 min,30 min,1 hour,1 day").split(","));
     223  int ii = _rnxIntrComboBox->findText(settings.value("rnxIntr").toString());
     224  if (ii != -1) {
     225    _rnxIntrComboBox->setCurrentIndex(ii);
     226  }
     227  _rnxSamplComboBox = new QComboBox();
     228  _rnxSamplComboBox->setEditable(false);
     229  _rnxSamplComboBox->addItems(QString("0.1 sec,1 sec,5 sec,10 sec,15 sec,30 sec,60 sec").split(","));
     230  int ij = _rnxSamplComboBox->findText(settings.value("rnxSampl").toString());
     231  if (ij != -1) {
     232    _rnxSamplComboBox->setCurrentIndex(ij);
     233  }
     234  _rnxFileCheckBox = new QCheckBox();
     235  _rnxFileCheckBox->setCheckState(Qt::CheckState(settings.value("rnxOnlyWithSKL").toInt()));
     236  _rnxSkelExtComboBox = new QComboBox();
     237  _rnxSkelExtComboBox->setEditable(false);
     238  _rnxSkelExtComboBox->addItems(QString("skl,SKL").split(","));
     239  int ik = _rnxSkelExtComboBox->findText(settings.value("rnxSkel").toString());
     240  if (ik != -1) {
     241    _rnxSkelExtComboBox->setCurrentIndex(ik);
     242  }
     243  _rnxSkelPathLineEdit = new QLineEdit(settings.value("rnxSkelPath").toString());
     244  _rnxScrpLineEdit = new QLineEdit(settings.value("rnxScript").toString());
     245  _rnxVersComboBox = new QComboBox();
     246  _rnxVersComboBox->setEditable(false);
     247  _rnxVersComboBox->addItems(QString("4,3,2").split(","));
     248  _rnxVersComboBox->setMaximumWidth(7 * ww);
     249  int il = _rnxVersComboBox->findText(settings.value("rnxVersion").toString());
     250  if (il != -1) {
     251    _rnxVersComboBox->setCurrentIndex(il);
     252  }
     253  QString hlp = settings.value("rnxV2Priority").toString();
     254  if (hlp.isEmpty()) {
     255    hlp = "G:12&PWCSLX G:5&IQX R:12&PC R:3&IQX R:46&ABX E:16&BCXZ E:578&IQX J:1&SLXCZ J:26&SLX J:5&IQX C:267&IQX C:18&DPX I:ABCX S:1&C S:5&IQX";
     256  }
     257  _rnxV2Priority = new QLineEdit(hlp);
     258
     259  connect(_rnxPathLineEdit, SIGNAL(textChanged(const QString&)), this, SLOT(slotBncTextChanged()));
     260  connect(_rnxSkelPathLineEdit, SIGNAL(textChanged(const QString&)), this, SLOT(slotBncTextChanged()));
     261  connect(_rnxVersComboBox, SIGNAL(currentIndexChanged(const QString&)), this, SLOT(slotBncTextChanged()));
     262
     263  // RINEX Ephemeris Options
     264  // -----------------------
     265  _ephPathLineEdit = new QLineEdit(settings.value("ephPath").toString());
     266  _ephIntrComboBox = new QComboBox();
     267  _ephIntrComboBox->setEditable(false);
     268  _ephIntrComboBox->addItems(QString("1 min,2 min,5 min,10 min,15 min,30 min,1 hour,1 day").split(","));
     269  int ji = _ephIntrComboBox->findText(settings.value("ephIntr").toString());
     270  if (ji != -1) {
     271    _ephIntrComboBox->setCurrentIndex(ji);
     272  }
     273  _ephOutPortLineEdit = new QLineEdit(settings.value("ephOutPort").toString());
     274  _ephVersComboBox = new QComboBox();
     275  _ephVersComboBox->setEditable(false);
     276  _ephVersComboBox->addItems(QString("4,3,2").split(","));
     277  _ephVersComboBox->setMaximumWidth(7 * ww);
     278  int jk = _ephVersComboBox->findText(settings.value("ephVersion").toString());
     279  if (jk != -1) {
     280    _ephVersComboBox->setCurrentIndex(jk);
     281  }
     282  //_ephFilePerStation = new QCheckBox();
     283  //_ephFilePerStation->setCheckState(Qt::CheckState(settings.value("ephFilePerStation").toInt()));
     284
     285  connect(_ephOutPortLineEdit, SIGNAL(textChanged(const QString&)),
     286          this, SLOT(slotBncTextChanged()));
     287
     288  connect(_ephPathLineEdit, SIGNAL(textChanged(const QString&)),
     289          this, SLOT(slotBncTextChanged()));
     290
     291  // Broadcast Corrections Options
     292  // -----------------------------
     293  _corrPathLineEdit = new QLineEdit(settings.value("corrPath").toString());
     294  _corrIntrComboBox = new QComboBox();
     295  _corrIntrComboBox->setEditable(false);
     296  _corrIntrComboBox->addItems(QString("1 min,2 min,5 min,10 min,15 min,30 min,1 hour,1 day").split(","));
     297  int bi = _corrIntrComboBox->findText(settings.value("corrIntr").toString());
     298  if (bi != -1) {
     299    _corrIntrComboBox->setCurrentIndex(bi);
     300  }
     301  _corrPortLineEdit = new QLineEdit(settings.value("corrPort").toString());
     302
     303  connect(_corrPathLineEdit, SIGNAL(textChanged(const QString&)),
     304          this, SLOT(slotBncTextChanged()));
     305
     306  connect(_corrPortLineEdit, SIGNAL(textChanged(const QString&)),
     307          this, SLOT(slotBncTextChanged()));
     308
     309  // Feed Engine Options
     310  // -------------------
     311  _outPortLineEdit = new QLineEdit(settings.value("outPort").toString());
     312  _outWaitSpinBox = new QSpinBox();
     313  _outWaitSpinBox->setMinimum(0);
     314  _outWaitSpinBox->setMaximum(30);
     315  _outWaitSpinBox->setSingleStep(1);
     316  _outWaitSpinBox->setSuffix(" sec");
     317  _outWaitSpinBox->setValue(settings.value("outWait").toInt());
     318  _outSamplComboBox = new QComboBox();
     319  _outSamplComboBox->addItems(QString("0.1 sec,1 sec,5 sec,10 sec,15 sec,30 sec,60 sec").split(","));
     320  int nn = _outSamplComboBox->findText(settings.value("outSampl").toString());
     321  if (nn != -1) {
     322    _outSamplComboBox->setCurrentIndex(nn);
     323  }
     324  _outFileLineEdit = new QLineEdit(settings.value("outFile").toString());
     325  _outUPortLineEdit = new QLineEdit(settings.value("outUPort").toString());
     326  _outLockTimeCheckBox = new QCheckBox();
     327  _outLockTimeCheckBox->setCheckState(Qt::CheckState(settings.value("outLockTime").toInt()));
     328
     329  connect(_outPortLineEdit, SIGNAL(textChanged(const QString&)),
     330          this, SLOT(slotBncTextChanged()));
     331
     332  connect(_outFileLineEdit, SIGNAL(textChanged(const QString&)),
     333          this, SLOT(slotBncTextChanged()));
     334
     335  connect(_outLockTimeCheckBox, SIGNAL(stateChanged(int)),
     336          this, SLOT(slotBncTextChanged()));
     337
     338  // Serial Output Options
     339  // ---------------------
     340  _serialMountPointLineEdit = new QLineEdit(settings.value("serialMountPoint").toString());
     341  _serialPortNameLineEdit = new QLineEdit(settings.value("serialPortName").toString());
     342  _serialBaudRateComboBox = new QComboBox();
     343  _serialBaudRateComboBox->addItems(QString("110,300,600,"
     344                                            "1200,2400,4800,9600,19200,38400,57600,115200").split(","));
     345  int kk = _serialBaudRateComboBox->findText(settings.value("serialBaudRate").toString());
     346  if (kk != -1) {
     347    _serialBaudRateComboBox->setCurrentIndex(kk);
     348  }
     349  _serialFlowControlComboBox = new QComboBox();
     350  _serialFlowControlComboBox->addItems(QString("OFF,XONXOFF,HARDWARE").split(","));
     351  kk = _serialFlowControlComboBox->findText(settings.value("serialFlowControl").toString());
     352  if (kk != -1) {
     353    _serialFlowControlComboBox->setCurrentIndex(kk);
     354  }
     355  _serialDataBitsComboBox = new QComboBox();
     356  _serialDataBitsComboBox->addItems(QString("5,6,7,8").split(","));
     357  kk = _serialDataBitsComboBox->findText(settings.value("serialDataBits").toString());
     358  if (kk != -1) {
     359    _serialDataBitsComboBox->setCurrentIndex(kk);
     360  }
     361  _serialParityComboBox = new QComboBox();
     362  _serialParityComboBox->addItems(QString("NONE,ODD,EVEN,SPACE").split(","));
     363  kk = _serialParityComboBox->findText(settings.value("serialParity").toString());
     364  if (kk != -1) {
     365    _serialParityComboBox->setCurrentIndex(kk);
     366  }
     367  _serialStopBitsComboBox = new QComboBox();
     368  _serialStopBitsComboBox->addItems(QString("1,2").split(","));
     369  kk = _serialStopBitsComboBox->findText(settings.value("serialStopBits").toString());
     370  if (kk != -1) {
     371    _serialStopBitsComboBox->setCurrentIndex(kk);
     372  }
     373  _serialAutoNMEAComboBox = new QComboBox();
     374  _serialAutoNMEAComboBox->addItems(QString("no,Auto,Manual GPGGA,Manual GNGGA").split(","));
     375  kk = _serialAutoNMEAComboBox->findText(settings.value("serialAutoNMEA").toString());
     376  if (kk != -1) {
     377    _serialAutoNMEAComboBox->setCurrentIndex(kk);
     378  }
     379  _serialFileNMEALineEdit = new QLineEdit(settings.value("serialFileNMEA").toString());
     380  _serialHeightNMEALineEdit = new QLineEdit(settings.value("serialHeightNMEA").toString());
     381
     382  _serialNMEASamplingSpinBox = new QSpinBox();
     383  _serialNMEASamplingSpinBox->setMinimum(0);
     384  _serialNMEASamplingSpinBox->setMaximum(300);
     385  _serialNMEASamplingSpinBox->setSingleStep(10);
     386  _serialNMEASamplingSpinBox->setValue(settings.value("serialNMEASampling").toInt());
     387  _serialNMEASamplingSpinBox->setSuffix(" sec");
     388
     389  connect(_serialMountPointLineEdit, SIGNAL(textChanged(const QString&)),
     390          this, SLOT(slotBncTextChanged()));
     391
     392  connect(_serialAutoNMEAComboBox, SIGNAL(currentIndexChanged(const QString&)),
     393          this, SLOT(slotBncTextChanged()));
     394
     395  // Outages Options
     396  // ---------------
     397  _adviseObsRateComboBox = new QComboBox();
     398  _adviseObsRateComboBox->setEditable(false);
     399  _adviseObsRateComboBox->addItems(QString(",0.1 Hz,0.2 Hz,0.5 Hz,1 Hz,5 Hz").split(","));
     400  kk = _adviseObsRateComboBox->findText(settings.value("adviseObsRate").toString());
     401  if (kk != -1) {
     402    _adviseObsRateComboBox->setCurrentIndex(kk);
     403  }
     404  _adviseFailSpinBox = new QSpinBox();
     405  _adviseFailSpinBox->setMinimum(0);
     406  _adviseFailSpinBox->setMaximum(60);
     407  _adviseFailSpinBox->setSingleStep(1);
     408  _adviseFailSpinBox->setSuffix(" min");
     409  _adviseFailSpinBox->setValue(settings.value("adviseFail").toInt());
     410  _adviseRecoSpinBox = new QSpinBox();
     411  _adviseRecoSpinBox->setMinimum(0);
     412  _adviseRecoSpinBox->setMaximum(60);
     413  _adviseRecoSpinBox->setSingleStep(1);
     414  _adviseRecoSpinBox->setSuffix(" min");
     415  _adviseRecoSpinBox->setValue(settings.value("adviseReco").toInt());
     416  _adviseScriptLineEdit = new QLineEdit(settings.value("adviseScript").toString());
     417
     418  connect(_adviseObsRateComboBox, SIGNAL(currentIndexChanged(const QString&)),
     419          this, SLOT(slotBncTextChanged()));
     420
     421  // Miscellaneous Options
     422  // ---------------------
     423  _miscMountLineEdit = new QLineEdit(settings.value("miscMount").toString());
     424  _miscPortLineEdit = new QLineEdit(settings.value("miscPort").toString());
     425  _miscIntrComboBox = new QComboBox();
     426  _miscIntrComboBox->setEditable(false);
     427  _miscIntrComboBox->addItems(QString(",2 sec,10 sec,1 min,5 min,15 min,1 hour,6 hours,1 day").split(","));
     428  int ll = _miscIntrComboBox->findText(settings.value("miscIntr").toString());
     429  if (ll != -1) {
     430    _miscIntrComboBox->setCurrentIndex(ll);
     431  }
     432  _miscScanRTCMCheckBox = new QCheckBox();
     433  _miscScanRTCMCheckBox->setCheckState(Qt::CheckState(
     434                                                      settings.value("miscScanRTCM").toInt()));
     435
     436  connect(_miscMountLineEdit, SIGNAL(textChanged(const QString&)),
     437          this, SLOT(slotBncTextChanged()));
     438
     439  // Streams
     440  // -------
     441  _mountPointsTable = new QTableWidget(0, 9);
     442
     443  _mountPointsTable->horizontalHeader()->resizeSection(1, 34 * ww);
     444  _mountPointsTable->horizontalHeader()->resizeSection(2, 9 * ww);
     445  _mountPointsTable->horizontalHeader()->resizeSection(3, 9 * ww);
     446  _mountPointsTable->horizontalHeader()->resizeSection(4, 7 * ww);
     447  _mountPointsTable->horizontalHeader()->resizeSection(5, 7 * ww);
     448  _mountPointsTable->horizontalHeader()->resizeSection(6, 5 * ww);
     449  _mountPointsTable->horizontalHeader()->resizeSection(7, 5 * ww);
    450450#if QT_VERSION < 0x050000
    451     _mountPointsTable->horizontalHeader()->setResizeMode(QHeaderView::Interactive);
     451  _mountPointsTable->horizontalHeader()->setResizeMode(QHeaderView::Interactive);
    452452#else
    453     _mountPointsTable->horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive);
     453  _mountPointsTable->horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive);
    454454#endif
    455     _mountPointsTable->horizontalHeader()->setStretchLastSection(true);
    456     _mountPointsTable->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft);
    457     _mountPointsTable->setHorizontalHeaderLabels(labels);
    458     _mountPointsTable->setGridStyle(Qt::NoPen);
    459     _mountPointsTable->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    460     _mountPointsTable->setSelectionMode(QAbstractItemView::ExtendedSelection);
    461     _mountPointsTable->setSelectionBehavior(QAbstractItemView::SelectRows);
    462     _mountPointsTable->hideColumn(0);
    463     _mountPointsTable->hideColumn(3);
    464     connect(_mountPointsTable, SIGNAL(itemSelectionChanged()),
    465         SLOT(slotSelectionChanged()));
    466     populateMountPointsTable();
    467 
    468     _log = new QTextEdit();
    469     _log->setReadOnly(true);
    470     QFont msFont(""); msFont.setStyleHint(QFont::TypeWriter); // default monospace font
    471     _log->setFont(msFont);
    472     _log->document()->setMaximumBlockCount(1000);
    473 
    474     // Combine Corrections
    475     // -------------------
    476     _cmbTable = new QTableWidget(0, 4);
    477     _cmbTable->setHorizontalHeaderLabels(QString("Mountpoint, AC Name, Weight Factor, Exclude Satellites").split(","));
    478     _cmbTable->setSelectionMode(QAbstractItemView::ExtendedSelection);
    479     _cmbTable->setSelectionBehavior(QAbstractItemView::SelectRows);
    480     _cmbTable->setMaximumWidth(40 * ww);
    481     _cmbTable->horizontalHeader()->resizeSection(0, 10 * ww);
    482     _cmbTable->horizontalHeader()->resizeSection(1, 6 * ww);
    483     _cmbTable->horizontalHeader()->resizeSection(2, 9 * ww);
    484     _cmbTable->horizontalHeader()->resizeSection(3, 9 * ww);
     455  _mountPointsTable->horizontalHeader()->setStretchLastSection(true);
     456  _mountPointsTable->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft);
     457  _mountPointsTable->setHorizontalHeaderLabels(labels);
     458  _mountPointsTable->setGridStyle(Qt::NoPen);
     459  _mountPointsTable->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
     460  _mountPointsTable->setSelectionMode(QAbstractItemView::ExtendedSelection);
     461  _mountPointsTable->setSelectionBehavior(QAbstractItemView::SelectRows);
     462  _mountPointsTable->hideColumn(0);
     463  _mountPointsTable->hideColumn(3);
     464  connect(_mountPointsTable, SIGNAL(itemSelectionChanged()),
     465          SLOT(slotSelectionChanged()));
     466  populateMountPointsTable();
     467
     468  _log = new QTextEdit();
     469  _log->setReadOnly(true);
     470  QFont msFont(""); msFont.setStyleHint(QFont::TypeWriter); // default monospace font
     471  _log->setFont(msFont);
     472  _log->document()->setMaximumBlockCount(1000);
     473
     474  // Combine Corrections
     475  // -------------------
     476  _cmbTable = new QTableWidget(0, 4);
     477  _cmbTable->setHorizontalHeaderLabels(QString("Mountpoint, AC Name, Weight Factor, Exclude Satellites").split(","));
     478  _cmbTable->setSelectionMode(QAbstractItemView::ExtendedSelection);
     479  _cmbTable->setSelectionBehavior(QAbstractItemView::SelectRows);
     480  _cmbTable->setMaximumWidth(40 * ww);
     481  _cmbTable->horizontalHeader()->resizeSection(0, 10 * ww);
     482  _cmbTable->horizontalHeader()->resizeSection(1, 6 * ww);
     483  _cmbTable->horizontalHeader()->resizeSection(2, 9 * ww);
     484  _cmbTable->horizontalHeader()->resizeSection(3, 9 * ww);
    485485#if QT_VERSION < 0x050000
    486     _cmbTable->horizontalHeader()->setResizeMode(QHeaderView::Interactive);
     486  _cmbTable->horizontalHeader()->setResizeMode(QHeaderView::Interactive);
    487487#else
    488     _cmbTable->horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive);
     488  _cmbTable->horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive);
    489489#endif
    490     _cmbTable->horizontalHeader()->setStretchLastSection(true);
    491     _cmbTable->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft);
    492 
    493     _cmbMaxresLineEdit = new QLineEdit(settings.value("cmbMaxres").toString());
    494     _cmbMaxdisplacementLineEdit = new QLineEdit(settings.value("cmbMaxdisplacement").toString());
    495 
    496     _cmbSamplComboBox = new QComboBox();
    497     _cmbSamplComboBox->setEditable(false);
    498     _cmbSamplComboBox->addItems(QString("1 sec,2 sec,5 sec,10 sec,15 sec,30 sec,60 sec").split(","));
    499     int kl = _cmbSamplComboBox->findText(settings.value("cmbSampl").toString());
    500     if (kl != -1) {
    501         _cmbSamplComboBox->setCurrentIndex(kl);
    502     }
    503 
    504     _cmbLogPath = new QLineEdit(settings.value("cmbLogpath").toString());
    505 
    506     QPushButton* addCmbRowButton = new QPushButton("Add Row");
    507     QPushButton* delCmbRowButton = new QPushButton("Delete");
    508 
    509     connect(_cmbTable, SIGNAL(itemSelectionChanged()), SLOT(slotBncTextChanged()));
    510 
    511     _cmbMethodComboBox = new QComboBox();
    512     _cmbMethodComboBox->setEditable(false);
    513     _cmbMethodComboBox->addItems(QString("Kalman Filter,Single-Epoch").split(","));
    514     int cm = _cmbMethodComboBox->findText(settings.value("cmbMethod").toString());
    515     if (cm != -1) {
    516         _cmbMethodComboBox->setCurrentIndex(cm);
    517     }
    518 
    519     int iRow = _cmbTable->rowCount();
    520     if (iRow > 0) {
    521         enableWidget(true, _cmbMethodComboBox);
    522         enableWidget(true, _cmbMaxresLineEdit);
    523         enableWidget(true, _cmbMaxdisplacementLineEdit);
    524         enableWidget(true, _cmbSamplComboBox);
    525         enableWidget(true, _cmbLogPath);
     490  _cmbTable->horizontalHeader()->setStretchLastSection(true);
     491  _cmbTable->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft);
     492
     493  _cmbMaxresLineEdit = new QLineEdit(settings.value("cmbMaxres").toString());
     494  _cmbMaxdisplacementLineEdit = new QLineEdit(settings.value("cmbMaxdisplacement").toString());
     495
     496  _cmbSamplComboBox = new QComboBox();
     497  _cmbSamplComboBox->setEditable(false);
     498  _cmbSamplComboBox->addItems(QString("1 sec,2 sec,5 sec,10 sec,15 sec,30 sec,60 sec").split(","));
     499  int kl = _cmbSamplComboBox->findText(settings.value("cmbSampl").toString());
     500  if (kl != -1) {
     501    _cmbSamplComboBox->setCurrentIndex(kl);
     502  }
     503
     504  _cmbLogPath = new QLineEdit(settings.value("cmbLogpath").toString());
     505
     506  QPushButton* addCmbRowButton = new QPushButton("Add Row");
     507  QPushButton* delCmbRowButton = new QPushButton("Delete");
     508
     509  connect(_cmbTable, SIGNAL(itemSelectionChanged()), SLOT(slotBncTextChanged()));
     510
     511  _cmbMethodComboBox = new QComboBox();
     512  _cmbMethodComboBox->setEditable(false);
     513  _cmbMethodComboBox->addItems(QString("Kalman Filter,Single-Epoch").split(","));
     514  int cm = _cmbMethodComboBox->findText(settings.value("cmbMethod").toString());
     515  if (cm != -1) {
     516    _cmbMethodComboBox->setCurrentIndex(cm);
     517  }
     518
     519  int iRow = _cmbTable->rowCount();
     520  if (iRow > 0) {
     521    enableWidget(true, _cmbMethodComboBox);
     522    enableWidget(true, _cmbMaxresLineEdit);
     523    enableWidget(true, _cmbMaxdisplacementLineEdit);
     524    enableWidget(true, _cmbSamplComboBox);
     525    enableWidget(true, _cmbLogPath);
     526  }
     527  else {
     528    enableWidget(false, _cmbMethodComboBox);
     529    enableWidget(false, _cmbMaxresLineEdit);
     530    enableWidget(false, _cmbMaxdisplacementLineEdit);
     531    enableWidget(false, _cmbSamplComboBox);
     532    enableWidget(false, _cmbLogPath);
     533  }
     534  _cmbGpsCheckBox = new QCheckBox();
     535  _cmbGpsCheckBox->setCheckState(Qt::CheckState(settings.value("cmbGps").toInt()));
     536  _cmbGloCheckBox = new QCheckBox();
     537  _cmbGloCheckBox->setCheckState(Qt::CheckState(settings.value("cmbGlo").toInt()));
     538  _cmbGalCheckBox = new QCheckBox();
     539  _cmbGalCheckBox->setCheckState(Qt::CheckState(settings.value("cmbGal").toInt()));
     540  _cmbBdsCheckBox = new QCheckBox();
     541  _cmbBdsCheckBox->setCheckState(Qt::CheckState(settings.value("cmbBds").toInt()));
     542  _cmbQzssCheckBox = new QCheckBox();
     543  _cmbQzssCheckBox->setCheckState(Qt::CheckState(settings.value("cmbQzss").toInt()));
     544  _cmbSbasCheckBox = new QCheckBox();
     545  _cmbSbasCheckBox->setCheckState(Qt::CheckState(settings.value("cmbSbas").toInt()));
     546  _cmbNavicCheckBox = new QCheckBox();
     547  _cmbNavicCheckBox->setCheckState(Qt::CheckState(settings.value("cmbNavic").toInt()));
     548
     549  connect(_cmbGpsCheckBox, SIGNAL(stateChanged(int)), this, SLOT(slotBncTextChanged()));
     550  connect(_cmbGloCheckBox, SIGNAL(stateChanged(int)), this, SLOT(slotBncTextChanged()));
     551  connect(_cmbGalCheckBox, SIGNAL(stateChanged(int)), this, SLOT(slotBncTextChanged()));
     552  connect(_cmbBdsCheckBox, SIGNAL(stateChanged(int)), this, SLOT(slotBncTextChanged()));
     553  connect(_cmbQzssCheckBox, SIGNAL(stateChanged(int)), this, SLOT(slotBncTextChanged()));
     554  connect(_cmbSbasCheckBox, SIGNAL(stateChanged(int)), this, SLOT(slotBncTextChanged()));
     555  connect(_cmbNavicCheckBox, SIGNAL(stateChanged(int)), this, SLOT(slotBncTextChanged()));
     556
     557  _cmbBsxFile = new qtFileChooser(0, qtFileChooser::File);
     558  _cmbBsxFile->setFileName(settings.value("cmbBsxFile").toString());
     559
     560  // Upload Results
     561  // -------------
     562  _uploadTable = new QTableWidget(0, 16);
     563  _uploadTable->setHorizontalHeaderLabels(QString("Host, Port, Mountpoint, Ntrip, User, Password, System, Format, CoM, SP3 File, RNX File, BSX File, PID, SID, IOD, Bytes").split(","));
     564  _uploadTable->setSelectionMode(QAbstractItemView::ExtendedSelection);
     565  _uploadTable->setSelectionBehavior(QAbstractItemView::SelectRows);
     566  _uploadTable->horizontalHeader()->resizeSection(0, 13 * ww);
     567  _uploadTable->horizontalHeader()->resizeSection(1, 5 * ww);
     568  _uploadTable->horizontalHeader()->resizeSection(2, 10 * ww);
     569  _uploadTable->horizontalHeader()->resizeSection(3, 6 * ww);
     570  _uploadTable->horizontalHeader()->resizeSection(4, 8 * ww);
     571  _uploadTable->horizontalHeader()->resizeSection(5, 8 * ww);
     572  _uploadTable->horizontalHeader()->resizeSection(6, 11 * ww);
     573  _uploadTable->horizontalHeader()->resizeSection(7, 11 * ww);
     574  _uploadTable->horizontalHeader()->resizeSection(8, 4 * ww);
     575  _uploadTable->horizontalHeader()->resizeSection(9, 15 * ww);
     576  _uploadTable->horizontalHeader()->resizeSection(10, 15 * ww);
     577  _uploadTable->horizontalHeader()->resizeSection(11, 15 * ww);
     578  _uploadTable->horizontalHeader()->resizeSection(12, 4 * ww);
     579  _uploadTable->horizontalHeader()->resizeSection(13, 4 * ww);
     580  _uploadTable->horizontalHeader()->resizeSection(14, 4 * ww);
     581  _uploadTable->horizontalHeader()->resizeSection(15, 12 * ww);
     582#if QT_VERSION < 0x050000
     583  _uploadTable->horizontalHeader()->setResizeMode(QHeaderView::Interactive);
     584#else
     585  _uploadTable->horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive);
     586#endif
     587  _uploadTable->horizontalHeader()->setStretchLastSection(true);
     588  _uploadTable->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft);
     589
     590  connect(_uploadTable, SIGNAL(itemSelectionChanged()),
     591          SLOT(slotBncTextChanged()));
     592
     593  QPushButton* addUploadRowButton = new QPushButton("Add Row");
     594  QPushButton* delUploadRowButton = new QPushButton("Del Row");
     595  QPushButton* setUploadTrafoButton = new QPushButton("Custom Trafo");
     596  _uploadIntrComboBox = new QComboBox;
     597  _uploadIntrComboBox->setEditable(false);
     598  _uploadIntrComboBox->addItems(QString("1 day,1 hour, 30 min,15 min,10 min,5 min,2 min,1 min").split(","));
     599  ii = _uploadIntrComboBox->findText(settings.value("uploadIntr").toString());
     600  if (ii != -1) {
     601    _uploadIntrComboBox->setCurrentIndex(ii);
     602  }
     603
     604  _uploadAntexFile = new qtFileChooser(0, qtFileChooser::File);
     605  _uploadAntexFile->setFileName(settings.value("uploadAntexFile").toString());
     606
     607  _uploadSamplRtcmEphCorrComboBox = new QComboBox();
     608  _uploadSamplRtcmEphCorrComboBox->setEditable(false);
     609  _uploadSamplRtcmEphCorrComboBox->addItems(QString("0 sec,1 sec,2 sec,5 sec,10 sec,15 sec,30 sec,60 sec").split(","));
     610  int pp = _uploadSamplRtcmEphCorrComboBox->findText(settings.value("uploadSamplRtcmEphCorr").toString());
     611  if (pp != -1) {
     612    _uploadSamplRtcmEphCorrComboBox->setCurrentIndex(pp);
     613  }
     614
     615  _uploadSamplSp3ComboBox = new QComboBox();
     616  _uploadSamplSp3ComboBox->setEditable(false);
     617  _uploadSamplSp3ComboBox->addItems(QString("0 sec,30 sec,60 sec,300 sec,900 sec").split(","));
     618  int oo = _uploadSamplSp3ComboBox->findText(settings.value("uploadSamplSp3").toString());
     619  if (oo != -1) {
     620    _uploadSamplSp3ComboBox->setCurrentIndex(oo);
     621  }
     622
     623  _uploadSamplClkRnxSpinBox = new QSpinBox;
     624  _uploadSamplClkRnxSpinBox->setMinimum(0);
     625  _uploadSamplClkRnxSpinBox->setMaximum(60);
     626  _uploadSamplClkRnxSpinBox->setSingleStep(5);
     627  _uploadSamplClkRnxSpinBox->setMaximumWidth(9 * ww);
     628  _uploadSamplClkRnxSpinBox->setValue(settings.value("uploadSamplClkRnx").toInt());
     629  _uploadSamplClkRnxSpinBox->setSuffix(" sec");
     630
     631  _uploadSamplBiaSnxSpinBox = new QSpinBox;
     632  _uploadSamplBiaSnxSpinBox->setMinimum(0);
     633  _uploadSamplBiaSnxSpinBox->setMaximum(60);
     634  _uploadSamplBiaSnxSpinBox->setSingleStep(5);
     635  _uploadSamplBiaSnxSpinBox->setMaximumWidth(9 * ww);
     636  _uploadSamplBiaSnxSpinBox->setValue(settings.value("uploadSamplBiaSnx").toInt());
     637  _uploadSamplBiaSnxSpinBox->setSuffix(" sec");
     638
     639  int iRowT = _uploadTable->rowCount();
     640  if (iRowT > 0) {
     641    enableWidget(true, _uploadIntrComboBox);
     642    enableWidget(true, _uploadSamplRtcmEphCorrComboBox);
     643    enableWidget(true, _uploadSamplSp3ComboBox);
     644    enableWidget(true, _uploadSamplClkRnxSpinBox);
     645    enableWidget(true, _uploadSamplBiaSnxSpinBox);
     646    enableWidget(true, _uploadAntexFile);
     647  }
     648  else {
     649    enableWidget(false, _uploadIntrComboBox);
     650    enableWidget(false, _uploadSamplRtcmEphCorrComboBox);
     651    enableWidget(false, _uploadSamplSp3ComboBox);
     652    enableWidget(false, _uploadSamplClkRnxSpinBox);
     653    enableWidget(true, _uploadSamplBiaSnxSpinBox);
     654    enableWidget(false, _uploadAntexFile);
     655  }
     656
     657  // Upload RTCM3 Ephemeris
     658  // ----------------------
     659  _uploadEphTable = new QTableWidget(0, 7);
     660  _uploadEphTable->setColumnCount(8);
     661  _uploadEphTable->setRowCount(0);
     662  _uploadEphTable->setHorizontalHeaderLabels(QString("Host, Port, Mountpoint,  Ntrip, User, Password, System, Bytes").split(","));
     663  _uploadEphTable->setSelectionMode(QAbstractItemView::ExtendedSelection);
     664  _uploadEphTable->setSelectionBehavior(QAbstractItemView::SelectRows);
     665  _uploadEphTable->horizontalHeader()->resizeSection(0, 13 * ww);
     666  _uploadEphTable->horizontalHeader()->resizeSection(1, 5 * ww);
     667  _uploadEphTable->horizontalHeader()->resizeSection(2, 8 * ww);
     668  _uploadEphTable->horizontalHeader()->resizeSection(3, 6 * ww);
     669  _uploadEphTable->horizontalHeader()->resizeSection(4, 8 * ww);
     670  _uploadEphTable->horizontalHeader()->resizeSection(5, 8 * ww);
     671  _uploadEphTable->horizontalHeader()->resizeSection(6, 10 * ww);
     672  _uploadEphTable->horizontalHeader()->resizeSection(7, 12 * ww);
     673#if QT_VERSION < 0x050000
     674  _uploadEphTable->horizontalHeader()->setResizeMode(QHeaderView::Interactive);
     675#else
     676  _uploadEphTable->horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive);
     677#endif
     678  _uploadEphTable->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft);
     679
     680  connect(_uploadEphTable, SIGNAL(itemSelectionChanged()),
     681          SLOT(slotBncTextChanged()));
     682
     683  QPushButton* addUploadEphRowButton = new QPushButton("Add Row");
     684  addUploadEphRowButton->setMaximumWidth(9 * ww);
     685  QPushButton* delUploadEphRowButton = new QPushButton("Del Row");
     686  delUploadEphRowButton->setMaximumWidth(9 * ww);
     687
     688  _uploadSamplRtcmEphSpinBox = new QSpinBox;
     689  _uploadSamplRtcmEphSpinBox->setMinimum(0);
     690  _uploadSamplRtcmEphSpinBox->setMaximum(60);
     691  _uploadSamplRtcmEphSpinBox->setSingleStep(5);
     692  _uploadSamplRtcmEphSpinBox->setMaximumWidth(9 * ww);
     693  _uploadSamplRtcmEphSpinBox->setValue(settings.value("uploadSamplRtcmEph").toInt());
     694  _uploadSamplRtcmEphSpinBox->setSuffix(" sec");
     695
     696  iRowT = _uploadEphTable->rowCount();
     697  if (iRowT > 0) {
     698    enableWidget(true, _uploadSamplRtcmEphSpinBox);
     699  }
     700  else {
     701    enableWidget(false, _uploadSamplRtcmEphSpinBox);
     702  }
     703
     704  // Upload Raw data
     705  // ----------------------
     706  _uploadRawTable = new QTableWidget(0, 7);
     707  _uploadRawTable->setColumnCount(8);
     708  _uploadRawTable->setRowCount(0);
     709  _uploadRawTable->setHorizontalHeaderLabels(QString("Source Mountpoint, Host, Port, Upload Mountpoint,  Ntrip, User, Password, Bytes").split(","));
     710  _uploadRawTable->setSelectionMode(QAbstractItemView::ExtendedSelection);
     711  _uploadRawTable->setSelectionBehavior(QAbstractItemView::SelectRows);
     712  _uploadRawTable->horizontalHeader()->resizeSection(0, 13 * ww);
     713  _uploadRawTable->horizontalHeader()->resizeSection(1, 13 * ww);
     714  _uploadRawTable->horizontalHeader()->resizeSection(2, 5 * ww);
     715  _uploadRawTable->horizontalHeader()->resizeSection(3, 13 * ww);
     716  _uploadRawTable->horizontalHeader()->resizeSection(4, 6 * ww);
     717  _uploadRawTable->horizontalHeader()->resizeSection(5, 8 * ww);
     718  _uploadRawTable->horizontalHeader()->resizeSection(6, 8 * ww);
     719  _uploadRawTable->horizontalHeader()->resizeSection(7, 10 * ww);
     720  _uploadRawTable->horizontalHeader()->resizeSection(8, 12 * ww);
     721#if QT_VERSION < 0x050000
     722  _uploadRawTable->horizontalHeader()->setResizeMode(QHeaderView::Interactive);
     723#else
     724  _uploadRawTable->horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive);
     725#endif
     726  _uploadRawTable->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft);
     727
     728  connect(_uploadRawTable, SIGNAL(itemSelectionChanged()), SLOT(slotBncTextChanged()));
     729
     730  QPushButton* addUploadRawRowButton = new QPushButton("Add Row");
     731  addUploadRawRowButton->setMaximumWidth(9 * ww);
     732  QPushButton* delUploadRawRowButton = new QPushButton("Del Row");
     733  delUploadRawRowButton->setMaximumWidth(9 * ww);
     734
     735  // Canvas with Editable Fields
     736  // ---------------------------
     737  _canvas = new QWidget;
     738  setCentralWidget(_canvas);
     739
     740  _aogroup = new QTabWidget();
     741  _aogroup->setElideMode(Qt::ElideNone);
     742  _aogroup->setUsesScrollButtons(true);
     743  QWidget* pgroup = new QWidget();
     744  QWidget* ggroup = new QWidget();
     745  QWidget* sgroup = new QWidget();
     746  QWidget* egroup = new QWidget();
     747  QWidget* agroup = new QWidget();
     748  QWidget* cgroup = new QWidget();
     749  QWidget* ogroup = new QWidget();
     750  QWidget* rgroup = new QWidget();
     751  QWidget* sergroup = new QWidget();
     752  QWidget* pppGroup1 = new QWidget();
     753  QWidget* pppGroup2 = new QWidget();
     754  QWidget* pppGroup3 = new QWidget();
     755  QWidget* pppGroup4 = new QWidget();
     756  QWidget* reqcgroup = new QWidget();
     757  QWidget* sp3CompGroup = new QWidget();
     758  QWidget* cmbgroup = new QWidget();
     759  QWidget* uploadgroup = new QWidget();
     760  QWidget* uploadEphgroup = new QWidget();
     761  QWidget* uploadRawgroup = new QWidget();
     762  _aogroup->addTab(pgroup, tr("Network"));
     763  _aogroup->addTab(ggroup, tr("General"));
     764  _aogroup->addTab(ogroup, tr("RINEX Observations"));
     765  _aogroup->addTab(egroup, tr("RINEX Ephemeris"));
     766  _aogroup->addTab(reqcgroup, tr("RINEX Editing && QC"));
     767  _aogroup->addTab(sp3CompGroup, tr("SP3 Comparison"));
     768  _aogroup->addTab(cgroup, tr("Broadcast Corrections"));
     769  _aogroup->addTab(sgroup, tr("Feed Engine"));
     770  _aogroup->addTab(sergroup, tr("Serial Output"));
     771  _aogroup->addTab(agroup, tr("Outages"));
     772  _aogroup->addTab(rgroup, tr("Miscellaneous"));
     773  _aogroup->addTab(pppGroup1, tr("PPP (1)"));
     774  _aogroup->addTab(pppGroup2, tr("PPP (2)"));
     775  _aogroup->addTab(pppGroup3, tr("PPP (3)"));
     776  _aogroup->addTab(pppGroup4, tr("PPP (4)"));
     777  _aogroup->addTab(cmbgroup, tr("Combine Corrections"));
     778  _aogroup->addTab(uploadgroup, tr("Upload Corrections"));
     779  _aogroup->addTab(uploadEphgroup, tr("Upload Ephemeris"));
     780  _aogroup->addTab(uploadRawgroup, tr("Upload Raw Data"));
     781
     782  // Log Tab
     783  // -------
     784  _loggroup = new QTabWidget();
     785  _loggroup->addTab(_log, tr("Log"));
     786  _loggroup->addTab(_bncFigure, tr("Throughput"));
     787  _loggroup->addTab(_bncFigureLate, tr("Latency"));
     788  _loggroup->addTab(_bncFigurePPP, tr("PPP Plot"));
     789
     790  // Netowork (Proxy and SSL) Tab
     791  // ----------------------------
     792  QGridLayout* pLayout = new QGridLayout;
     793  pLayout->setColumnMinimumWidth(0, 13 * ww);
     794  _proxyPortLineEdit->setMaximumWidth(9 * ww);
     795
     796  pLayout->addWidget(new QLabel("Settings for proxy in protected networks and for SSL authorization, leave boxes blank if none.<br>"), 0, 0, 1, 50);
     797  pLayout->addWidget(new QLabel("Proxy host"), 1, 0);
     798  pLayout->addWidget(_proxyHostLineEdit, 1, 1, 1, 10);
     799  pLayout->addWidget(new QLabel("Proxy port"), 2, 0);
     800  pLayout->addWidget(_proxyPortLineEdit, 2, 1);
     801  pLayout->addWidget(new QLabel("Path to SSL certificates"), 3, 0);
     802  pLayout->addWidget(_sslCaCertPathLineEdit, 3, 1, 1, 10);
     803  pLayout->addWidget(new QLabel("Default:  " + bncSslConfig::defaultPath()), 3, 11, 1, 20);
     804  pLayout->addWidget(new QLabel("Path to SSL client certificates"), 4, 0);
     805  pLayout->addWidget(_sslClientCertPathLineEdit, 4, 1, 1, 10);
     806  pLayout->addWidget(new QLabel("Ignore SSL authorization errors"), 5, 0);
     807  pLayout->addWidget(_sslIgnoreErrorsCheckBox, 5, 1, 1, 10);
     808  pLayout->addWidget(new QLabel(""), 6, 1);
     809  pLayout->setRowStretch(6, 999);
     810
     811  pgroup->setLayout(pLayout);
     812
     813  // General Tab
     814  // -----------
     815  QGridLayout* gLayout = new QGridLayout;
     816  gLayout->setColumnMinimumWidth(0, 14 * ww);
     817  _onTheFlyComboBox->setMaximumWidth(9 * ww);
     818
     819  gLayout->addWidget(new QLabel("General settings for logfile, file handling, configuration on-the-fly, auto-start, and raw file output.<br>"), 0, 0, 1, 50);
     820  gLayout->addWidget(new QLabel("Logfile (full path)"), 1, 0);
     821  gLayout->addWidget(_logFileLineEdit, 1, 1, 1, 20);
     822  gLayout->addWidget(new QLabel("Append files"), 2, 0);
     823  gLayout->addWidget(_rnxAppendCheckBox, 2, 1);
     824  gLayout->addWidget(new QLabel("Reread configuration"), 3, 0);
     825  gLayout->addWidget(_onTheFlyComboBox, 3, 1);
     826  gLayout->addWidget(new QLabel("Auto start"), 4, 0);
     827  gLayout->addWidget(_autoStartCheckBox, 4, 1);
     828  gLayout->addWidget(new QLabel("Raw output file (full path)"), 5, 0);
     829  gLayout->addWidget(_rawOutFileLineEdit, 5, 1, 1, 20);
     830  gLayout->addWidget(new QLabel(""), 6, 1);
     831  gLayout->setRowStretch(7, 999);
     832
     833  ggroup->setLayout(gLayout);
     834
     835  // RINEX Observations
     836  // ------------------
     837  QGridLayout* oLayout = new QGridLayout;
     838  oLayout->setColumnMinimumWidth(0, 14 * ww);
     839  _rnxIntrComboBox->setMaximumWidth(9 * ww);
     840  _rnxSamplComboBox->setMaximumWidth(9 * ww);
     841  _rnxSkelExtComboBox->setMaximumWidth(9 * ww);
     842
     843  oLayout->addWidget(new QLabel("Saving RINEX observation files.<br>"), 0, 0, 1, 50);
     844  oLayout->addWidget(new QLabel("Directory"), 1, 0);
     845  oLayout->addWidget(_rnxPathLineEdit, 1, 1, 1, 15);
     846  oLayout->addWidget(new QLabel("Interval"), 2, 0);
     847  oLayout->addWidget(_rnxIntrComboBox, 2, 1);
     848  oLayout->addWidget(new QLabel("  Sampling"), 2, 2, Qt::AlignRight);
     849  oLayout->addWidget(_rnxSamplComboBox, 2, 3, Qt::AlignRight);
     850  oLayout->addWidget(new QLabel("Skeleton extension"), 3, 0);
     851  oLayout->addWidget(_rnxSkelExtComboBox, 3, 1, Qt::AlignLeft);
     852  oLayout->addWidget(new QLabel("Skeleton mandatory"), 3, 2, Qt::AlignRight);
     853  oLayout->addWidget(_rnxFileCheckBox, 3, 3);
     854  oLayout->addWidget(new QLabel("Skeleton Directory"), 4, 0);
     855  oLayout->addWidget(_rnxSkelPathLineEdit, 4, 1, 1, 15);
     856  oLayout->addWidget(new QLabel("Script (full path)"), 5, 0);
     857  oLayout->addWidget(_rnxScrpLineEdit, 5, 1, 1, 15);
     858  oLayout->addWidget(new QLabel("Version"), 6, 0);
     859  oLayout->addWidget(_rnxVersComboBox, 6, 1);
     860  oLayout->addWidget(new QLabel("Signal priority"), 6, 2, Qt::AlignRight);
     861  oLayout->addWidget(_rnxV2Priority, 6, 3, 1, 13);
     862  oLayout->addWidget(new QLabel(""), 7, 1);
     863  oLayout->setRowStretch(8, 999);
     864
     865  ogroup->setLayout(oLayout);
     866
     867  // RINEX Ephemeris
     868  // ---------------
     869  QGridLayout* eLayout = new QGridLayout;
     870  eLayout->setColumnMinimumWidth(0, 14 * ww);
     871  _ephIntrComboBox->setMaximumWidth(9 * ww);
     872  _ephOutPortLineEdit->setMaximumWidth(9 * ww);
     873
     874  eLayout->addWidget(new QLabel("Saving RINEX navigation files and ephemeris output through IP port.<br>"), 0, 0, 1, 70);
     875  eLayout->addWidget(new QLabel("Directory"), 1, 0);
     876  eLayout->addWidget(_ephPathLineEdit, 1, 1, 1, 30);
     877  eLayout->addWidget(new QLabel("Interval"), 2, 0);
     878  eLayout->addWidget(_ephIntrComboBox, 2, 1);
     879  eLayout->addWidget(new QLabel("Port"), 3, 0);
     880  eLayout->addWidget(_ephOutPortLineEdit, 3, 1);
     881  eLayout->addWidget(new QLabel("Version"), 4, 0);
     882  eLayout->addWidget(_ephVersComboBox, 4, 1);
     883  eLayout->setRowStretch(5, 999);
     884  //eLayout->addWidget(new QLabel("File per Station"),              5, 0);
     885  //eLayout->addWidget(_ephFilePerStation,                          5, 1);
     886  //eLayout->setRowStretch(6, 999);
     887
     888  egroup->setLayout(eLayout);
     889
     890
     891  // Broadcast Corrections
     892  // ---------------------
     893  QGridLayout* cLayout = new QGridLayout;
     894  cLayout->setColumnMinimumWidth(0, 14 * ww);
     895  _corrIntrComboBox->setMaximumWidth(9 * ww);
     896  _corrPortLineEdit->setMaximumWidth(9 * ww);
     897
     898  cLayout->addWidget(new QLabel("Saving Broadcast Ephemeris correction files and correction output through IP port.<br>"), 0, 0, 1, 70);
     899  cLayout->addWidget(new QLabel("Directory, ASCII"), 1, 0);
     900  cLayout->addWidget(_corrPathLineEdit, 1, 1, 1, 30);
     901  cLayout->addWidget(new QLabel("Interval"), 2, 0);
     902  cLayout->addWidget(_corrIntrComboBox, 2, 1);
     903  cLayout->addWidget(new QLabel("Port"), 3, 0);
     904  cLayout->addWidget(_corrPortLineEdit, 3, 1);
     905  cLayout->addWidget(new QLabel(""), 4, 1);
     906  cLayout->setRowStretch(7, 999);
     907  cgroup->setLayout(cLayout);
     908
     909  // Feed Engine
     910  // -----------
     911  QGridLayout* sLayout = new QGridLayout;
     912  sLayout->setColumnMinimumWidth(0, 14 * ww);
     913  _outPortLineEdit->setMaximumWidth(9 * ww);
     914  _outWaitSpinBox->setMaximumWidth(9 * ww);
     915  _outSamplComboBox->setMaximumWidth(9 * ww);
     916  _outUPortLineEdit->setMaximumWidth(9 * ww);
     917
     918  sLayout->addWidget(new QLabel("Output decoded observations in ASCII format to feed a real-time GNSS network engine.<br>"), 0, 0, 1, 50);
     919  sLayout->addWidget(new QLabel("Port"), 1, 0);
     920  sLayout->addWidget(_outPortLineEdit, 1, 1);
     921  sLayout->addWidget(new QLabel("       Wait for full obs epoch"), 1, 2, Qt::AlignRight);
     922  sLayout->addWidget(_outWaitSpinBox, 1, 3, Qt::AlignLeft);
     923  sLayout->addWidget(new QLabel("Sampling"), 2, 0);
     924  sLayout->addWidget(_outSamplComboBox, 2, 1, Qt::AlignLeft);
     925  sLayout->addWidget(new QLabel("File (full path)"), 3, 0);
     926  sLayout->addWidget(_outFileLineEdit, 3, 1, 1, 10);
     927  sLayout->addWidget(new QLabel("Port (unsynchronized)"), 4, 0);
     928  sLayout->addWidget(_outUPortLineEdit, 4, 1);
     929  sLayout->addWidget(new QLabel("Print lock time"), 5, 0);
     930  sLayout->addWidget(_outLockTimeCheckBox, 5, 1);
     931  sLayout->addWidget(new QLabel(""), 6, 1);
     932  sLayout->setRowStretch(7, 999);
     933
     934  sgroup->setLayout(sLayout);
     935
     936  // Serial Output
     937  // -------------
     938  QGridLayout* serLayout = new QGridLayout;
     939  serLayout->setColumnMinimumWidth(0, 12 * ww);
     940  _serialBaudRateComboBox->setMaximumWidth(9 * ww);
     941  _serialFlowControlComboBox->setMaximumWidth(11 * ww);
     942  _serialDataBitsComboBox->setMaximumWidth(5 * ww);
     943  _serialParityComboBox->setMaximumWidth(9 * ww);
     944  _serialStopBitsComboBox->setMaximumWidth(5 * ww);
     945  _serialAutoNMEAComboBox->setMaximumWidth(14 * ww);
     946  _serialHeightNMEALineEdit->setMaximumWidth(8 * ww);
     947  _serialNMEASamplingSpinBox->setMaximumWidth(8 * ww);
     948
     949  serLayout->addWidget(new QLabel("Port settings to feed a serial connected receiver.<br>"), 0, 0, 1, 30);
     950  serLayout->addWidget(new QLabel("Mountpoint"), 1, 0, Qt::AlignLeft);
     951  serLayout->addWidget(_serialMountPointLineEdit, 1, 1, 1, 2);
     952  serLayout->addWidget(new QLabel("Port name"), 2, 0, Qt::AlignLeft);
     953  serLayout->addWidget(_serialPortNameLineEdit, 2, 1, 1, 2);
     954  serLayout->addWidget(new QLabel("Baud rate"), 3, 0, Qt::AlignLeft);
     955  serLayout->addWidget(_serialBaudRateComboBox, 3, 1);
     956  serLayout->addWidget(new QLabel("Flow control"), 3, 2, Qt::AlignRight);
     957  serLayout->addWidget(_serialFlowControlComboBox, 3, 3);
     958  serLayout->addWidget(new QLabel("Data bits"), 4, 0, Qt::AlignLeft);
     959  serLayout->addWidget(_serialDataBitsComboBox, 4, 1);
     960  serLayout->addWidget(new QLabel("Parity"), 4, 2, Qt::AlignRight);
     961  serLayout->addWidget(_serialParityComboBox, 4, 3);
     962  serLayout->addWidget(new QLabel("   Stop bits"), 4, 4, Qt::AlignRight);
     963  serLayout->addWidget(_serialStopBitsComboBox, 4, 5);
     964  serLayout->addWidget(new QLabel("NMEA"), 5, 0);
     965  serLayout->addWidget(_serialAutoNMEAComboBox, 5, 1);
     966  serLayout->addWidget(new QLabel("    File (full path)"), 5, 2, Qt::AlignRight);
     967  serLayout->addWidget(_serialFileNMEALineEdit, 5, 3, 1, 10);
     968  serLayout->addWidget(new QLabel("Height"), 5, 14, Qt::AlignRight);
     969  serLayout->addWidget(_serialHeightNMEALineEdit, 5, 15, 1, 11);
     970  serLayout->addWidget(new QLabel("Sampling"), 5, 25, Qt::AlignRight);
     971  serLayout->addWidget(_serialNMEASamplingSpinBox, 5, 26, 1, 12);
     972  serLayout->addWidget(new QLabel(""), 6, 1);
     973  serLayout->setRowStretch(7, 999);
     974
     975  sergroup->setLayout(serLayout);
     976
     977  // Outages
     978  // -------
     979  QGridLayout* aLayout = new QGridLayout;
     980  aLayout->setColumnMinimumWidth(0, 14 * ww);
     981  _adviseObsRateComboBox->setMaximumWidth(9 * ww);
     982  _adviseFailSpinBox->setMaximumWidth(9 * ww);
     983  _adviseRecoSpinBox->setMaximumWidth(9 * ww);
     984
     985  aLayout->addWidget(new QLabel("Failure and recovery reports, advisory notes.<br>"), 0, 0, 1, 50, Qt::AlignLeft);
     986  aLayout->addWidget(new QLabel("Observation rate"), 1, 0);
     987  aLayout->addWidget(_adviseObsRateComboBox, 1, 1);
     988  aLayout->addWidget(new QLabel("Failure threshold"), 2, 0);
     989  aLayout->addWidget(_adviseFailSpinBox, 2, 1);
     990  aLayout->addWidget(new QLabel("Recovery threshold"), 3, 0);
     991  aLayout->addWidget(_adviseRecoSpinBox, 3, 1);
     992  aLayout->addWidget(new QLabel("Script (full path)"), 4, 0);
     993  aLayout->addWidget(_adviseScriptLineEdit, 4, 1, 1, 20);
     994  aLayout->addWidget(new QLabel(""), 5, 1);
     995  aLayout->setRowStretch(6, 999);
     996
     997  agroup->setLayout(aLayout);
     998
     999  // Miscellaneous
     1000  // -------------
     1001  QGridLayout* rLayout = new QGridLayout;
     1002  rLayout->setColumnMinimumWidth(0, 14 * ww);
     1003  _miscIntrComboBox->setMaximumWidth(9 * ww);
     1004  _miscPortLineEdit->setMaximumWidth(9 * ww);
     1005
     1006  rLayout->addWidget(new QLabel("Log latencies or scan RTCM streams for message types and antenna information or output raw data through TCP/IP port.<br>"), 0, 0, 1, 50);
     1007  rLayout->addWidget(new QLabel("Mountpoint"), 1, 0);
     1008  rLayout->addWidget(_miscMountLineEdit, 1, 1, 1, 7);
     1009  rLayout->addWidget(new QLabel("Log latency"), 2, 0);
     1010  rLayout->addWidget(_miscIntrComboBox, 2, 1);
     1011  rLayout->addWidget(new QLabel("Scan RTCM"), 3, 0);
     1012  rLayout->addWidget(_miscScanRTCMCheckBox, 3, 1);
     1013  rLayout->addWidget(new QLabel("Port"), 4, 0);
     1014  rLayout->addWidget(_miscPortLineEdit, 4, 1);
     1015  rLayout->addWidget(new QLabel(""), 5, 1);
     1016  rLayout->setRowStretch(6, 999);
     1017
     1018  rgroup->setLayout(rLayout);
     1019
     1020  // PPP
     1021  // ---
     1022  _pppWidgets._dataSource->setMaximumWidth(15 * ww);
     1023  _pppWidgets._corrMount->setMaximumWidth(15 * ww);
     1024  _pppWidgets._biasMount->setMaximumWidth(15 * ww);
     1025  _pppWidgets._nmeaPath->setMaximumWidth(35 * ww);
     1026  _pppWidgets._logPath->setMaximumWidth(15 * ww);
     1027  _pppWidgets._snxtroPath->setMaximumWidth(35 * ww);
     1028  _pppWidgets._snxtroIntr->setMaximumWidth(7 * ww);
     1029  _pppWidgets._snxtroAc->setMaximumWidth(7 * ww);
     1030  _pppWidgets._snxtroSolId->setMaximumWidth(7 * ww);
     1031  _pppWidgets._snxtroSolType->setMaximumWidth(7 * ww);
     1032  _pppWidgets._snxtroCampId->setMaximumWidth(7 * ww);
     1033  _pppWidgets._ionoMount->setMaximumWidth(15 * ww);
     1034
     1035
     1036  QGridLayout* pppLayout1 = new QGridLayout();
     1037  int ir = 0;
     1038  pppLayout1->addWidget(new QLabel("Precise Point Positioning - Input and Output.<br>"), ir, 0, 1, 7, Qt::AlignLeft);
     1039  ++ir;
     1040  pppLayout1->addWidget(new QLabel("Data source"), ir, 0);
     1041  pppLayout1->addWidget(_pppWidgets._dataSource, ir, 1);
     1042  pppLayout1->addWidget(new QLabel("   Logfile directory"), ir, 4);
     1043  pppLayout1->addWidget(_pppWidgets._logPath, ir, 5, 1, 2);
     1044  pppLayout1->addWidget(_pppWidgets._logMode, ir, 7);
     1045  ++ir;
     1046  pppLayout1->addWidget(new QLabel("Corrections stream"), ir, 0);
     1047  pppLayout1->addWidget(_pppWidgets._corrMount, ir, 1);
     1048  pppLayout1->addWidget(new QLabel("Corrections file"), ir, 2);
     1049  pppLayout1->addWidget(_pppWidgets._corrFile, ir, 3);
     1050  pppLayout1->addWidget(new QLabel("   NMEA directory"), ir, 4);
     1051  pppLayout1->addWidget(_pppWidgets._nmeaPath, ir, 5, 1, 3);
     1052  ++ir;
     1053  pppLayout1->addWidget(new QLabel("Biases stream"), ir, 0);
     1054  pppLayout1->addWidget(_pppWidgets._biasMount, ir, 1);
     1055  pppLayout1->addWidget(new QLabel("Biases file"), ir, 2);
     1056  pppLayout1->addWidget(_pppWidgets._biasFile, ir, 3);
     1057  pppLayout1->addWidget(new QLabel("   SNX TRO directory"), ir, 4);
     1058  pppLayout1->addWidget(_pppWidgets._snxtroPath, ir, 5, 1, 3);
     1059  ++ir;
     1060  pppLayout1->addWidget(new QLabel("Ionosphere stream"), ir, 0);
     1061  pppLayout1->addWidget(_pppWidgets._ionoMount, ir, 1);
     1062  pppLayout1->addWidget(new QLabel("Ionosphere file"), ir, 2);
     1063  pppLayout1->addWidget(_pppWidgets._ionoFile, ir, 3);
     1064  pppLayout1->addWidget(new QLabel("   SNX TRO interval"), ir, 4);
     1065  pppLayout1->addWidget(_pppWidgets._snxtroIntr, ir, 5);
     1066  pppLayout1->addWidget(new QLabel("   SNX TRO sampling"), ir, 6);
     1067  pppLayout1->addWidget(_pppWidgets._snxtroSampl, ir, 7, Qt::AlignRight);
     1068  ++ir;
     1069  pppLayout1->addWidget(new QLabel("RINEX Obs file"), ir, 0);
     1070  pppLayout1->addWidget(_pppWidgets._rinexObs, ir, 1);
     1071  pppLayout1->addWidget(new QLabel("RINEX Nav file"), ir, 2);
     1072  pppLayout1->addWidget(_pppWidgets._rinexNav, ir, 3);
     1073  pppLayout1->addWidget(new QLabel("   SNX TRO AC"), ir, 4);
     1074  pppLayout1->addWidget(_pppWidgets._snxtroAc, ir, 5);
     1075  pppLayout1->addWidget(new QLabel("   SNX TRO solution ID"), ir, 6);
     1076  pppLayout1->addWidget(_pppWidgets._snxtroSolId, ir, 7, Qt::AlignRight);
     1077  ++ir;
     1078  pppLayout1->addWidget(new QLabel("ANTEX file"), ir, 0);
     1079  pppLayout1->addWidget(_pppWidgets._antexFile, ir, 1);
     1080  pppLayout1->addWidget(new QLabel("Coordinates file"), ir, 2);
     1081  pppLayout1->addWidget(_pppWidgets._crdFile, ir, 3);
     1082  pppLayout1->addWidget(new QLabel("   SNX TRO campaign ID"), ir, 4);
     1083  pppLayout1->addWidget(_pppWidgets._snxtroCampId, ir, 5);
     1084  pppLayout1->addWidget(new QLabel("   SNX TRO solution type"), ir, 6);
     1085  pppLayout1->addWidget(_pppWidgets._snxtroSolType, ir, 7, Qt::AlignRight);
     1086  ++ir;
     1087  pppLayout1->addWidget(new QLabel("BLQ file"), ir, 0);
     1088  pppLayout1->addWidget(_pppWidgets._blqFile, ir, 1);
     1089
     1090  pppLayout1->setRowStretch(ir + 1, 999);
     1091  pppGroup1->setLayout(pppLayout1);
     1092
     1093  QGridLayout* pppLayout2 = new QGridLayout();
     1094  ir = 0;
     1095  pppLayout2->addWidget(new QLabel("Precise Point Positioning - Options.<br>"), ir, 0, 1, 2, Qt::AlignLeft);
     1096  ++ir;
     1097  pppLayout2->addWidget(new QLabel("GPS LCs"), ir, 0, Qt::AlignLeft);
     1098  pppLayout2->addWidget(_pppWidgets._lcGPS, ir, 1);
     1099  pppLayout2->addItem(new QSpacerItem(8 * ww, 0), ir, 2);
     1100  pppLayout2->addWidget(new QLabel("Sigma C1"), ir, 3, Qt::AlignLeft);
     1101  pppLayout2->addWidget(_pppWidgets._sigmaC1, ir, 4); _pppWidgets._sigmaC1->setMaximumWidth(8 * ww);
     1102  pppLayout2->addItem(new QSpacerItem(8 * ww, 0), ir, 5);
     1103  pppLayout2->addWidget(new QLabel("Sigma L1"), ir, 6, Qt::AlignLeft);
     1104  pppLayout2->addWidget(_pppWidgets._sigmaL1, ir, 7); _pppWidgets._sigmaL1->setMaximumWidth(8 * ww);
     1105  ++ir;
     1106  pppLayout2->addWidget(new QLabel("GLONASS LCs"), ir, 0, Qt::AlignLeft);
     1107  pppLayout2->addWidget(_pppWidgets._lcGLONASS, ir, 1);
     1108  pppLayout2->addWidget(new QLabel("Max Res C1"), ir, 3, Qt::AlignLeft);
     1109  pppLayout2->addWidget(_pppWidgets._maxResC1, ir, 4); _pppWidgets._maxResC1->setMaximumWidth(8 * ww);
     1110  pppLayout2->addWidget(new QLabel("Max Res L1"), ir, 6, Qt::AlignLeft);
     1111  pppLayout2->addWidget(_pppWidgets._maxResL1, ir, 7); _pppWidgets._maxResL1->setMaximumWidth(8 * ww);
     1112  ++ir;
     1113  pppLayout2->addWidget(new QLabel("Galileo LCs"), ir, 0, Qt::AlignLeft);
     1114  pppLayout2->addWidget(_pppWidgets._lcGalileo, ir, 1);
     1115  pppLayout2->addWidget(new QLabel("Ele Wgt Code"), ir, 3, Qt::AlignLeft);
     1116  pppLayout2->addWidget(_pppWidgets._eleWgtCode, ir, 4);
     1117  pppLayout2->addWidget(new QLabel("Ele Wgt Phase"), ir, 6, Qt::AlignLeft);
     1118  pppLayout2->addWidget(_pppWidgets._eleWgtPhase, ir, 7);
     1119  ++ir;
     1120  pppLayout2->addWidget(new QLabel("BDS LCs"), ir, 0, Qt::AlignLeft);
     1121  pppLayout2->addWidget(_pppWidgets._lcBDS, ir, 1);
     1122  pppLayout2->addWidget(new QLabel("Min # of Obs"), ir, 3, Qt::AlignLeft);
     1123  pppLayout2->addWidget(_pppWidgets._minObs, ir, 4);
     1124  pppLayout2->addWidget(new QLabel("Min Elevation"), ir, 6, Qt::AlignLeft);
     1125  pppLayout2->addWidget(_pppWidgets._minEle, ir, 7); _pppWidgets._minEle->setMaximumWidth(8 * ww);
     1126  ++ir;
     1127  pppLayout2->addWidget(new QLabel("Constraints"), ir, 0, Qt::AlignLeft);
     1128  pppLayout2->addWidget(_pppWidgets._constraints, ir, 1);
     1129  pppLayout2->addWidget(new QLabel("Sigma GIM"), ir, 3, Qt::AlignLeft);
     1130  pppLayout2->addWidget(_pppWidgets._sigmaGIM, ir, 4); _pppWidgets._sigmaGIM->setMaximumWidth(8 * ww);
     1131  pppLayout2->addItem(new QSpacerItem(8 * ww, 0), ir, 5);
     1132  pppLayout2->addWidget(new QLabel("Wait for clock corr."), ir, 6, Qt::AlignLeft);
     1133  pppLayout2->addWidget(_pppWidgets._corrWaitTime, ir, 7);
     1134  ++ir;
     1135  pppLayout2->addItem(new QSpacerItem(8 * ww, 0), ir, 2);
     1136  pppLayout2->addWidget(new QLabel("Max Res GIM"), ir, 3, Qt::AlignLeft);
     1137  pppLayout2->addWidget(_pppWidgets._maxResGIM, ir, 4); _pppWidgets._maxResGIM->setMaximumWidth(8 * ww);
     1138  pppLayout2->addWidget(new QLabel("Seeding (sec)"), ir, 6, Qt::AlignLeft);
     1139  pppLayout2->addWidget(_pppWidgets._seedingTime, ir, 7); _pppWidgets._seedingTime->setMaximumWidth(8 * ww);
     1140  ++ir;
     1141  QFrame* hLine = new QFrame();
     1142  hLine->setFrameShape(QFrame::HLine);
     1143  hLine->setFrameShadow(QFrame::Sunken);
     1144  pppLayout2->addWidget(hLine, ir, 0, 2, 8);
     1145  ++ir;
     1146  ++ir;
     1147  pppLayout2->addWidget(new QLabel("Amb. Res."), ir, 0);
     1148  QHBoxLayout* pL1 = new QHBoxLayout();
     1149  pL1->setSpacing(0);
     1150  pL1->setContentsMargins(0,0,0,0);
     1151  pL1->addWidget(new QLabel("GPS"));
     1152  pL1->addWidget(_pppWidgets._arGPS);
     1153  QHBoxLayout* pL2 = new QHBoxLayout();
     1154  pL2->setSpacing(0);
     1155  pL2->setContentsMargins(0,0,0,0);
     1156  pL2->addWidget(new QLabel("Gal"));
     1157  pL2->addWidget(_pppWidgets._arGalileo);
     1158  QHBoxLayout* pL3 = new QHBoxLayout();
     1159  pL3->setSpacing(0);
     1160  pL3->setContentsMargins(0,0,0,0);
     1161  pL3->addWidget(new QLabel("BDS"));
     1162  pL3->addWidget(_pppWidgets._arBDS);
     1163  QHBoxLayout* arLayout = new QHBoxLayout();
     1164  arLayout->addLayout(pL1);
     1165  arLayout->addLayout(pL2);
     1166  arLayout->addLayout(pL3);
     1167  pppLayout2->addLayout(arLayout, ir, 1);
     1168  ++ir;
     1169  _pppWidgets._arMinNumEpo->setMaximumWidth(8 * ww);
     1170  _pppWidgets._arMinNumSat->setMaximumWidth(8 * ww);
     1171  _pppWidgets._arMaxFrac->setMaximumWidth(8 * ww);
     1172  _pppWidgets._arMaxSig->setMaximumWidth(8 * ww);
     1173  QHBoxLayout* pAR = new QHBoxLayout();
     1174  pAR->addWidget(new QLabel("Min # Epo"));
     1175  pAR->addWidget(_pppWidgets._arMinNumEpo);
     1176  pAR->addStretch();
     1177  pAR->addWidget(new QLabel("Min # Sat"));
     1178  pAR->addWidget(_pppWidgets._arMinNumSat);
     1179  pAR->addStretch();
     1180  pAR->addWidget(new QLabel("Max Frac"));
     1181  pAR->addWidget(_pppWidgets._arMaxFrac);
     1182  pAR->addStretch();
     1183  pAR->addWidget(new QLabel("Max Sig"));
     1184  pAR->addWidget(_pppWidgets._arMaxSig);
     1185  pAR->addStretch();
     1186  pAR->addWidget(new QLabel("Use Yaw"));
     1187  pAR->addWidget(_pppWidgets._arUseYaw);
     1188  pppLayout2->addLayout(pAR, ir, 0, 1, 8);
     1189  ++ir;
     1190  pppLayout2->addWidget(new QLabel(""), ir, 8);
     1191  pppLayout2->setColumnStretch(8, 999);
     1192 
     1193  pppGroup2->setLayout(pppLayout2);
     1194
     1195  QVBoxLayout* pppLayout3 = new QVBoxLayout();
     1196  pppLayout3->addWidget(new QLabel("Precise Point Positioning - Processed Stations.<br>"));
     1197  pppLayout3->addWidget(_pppWidgets._staTable, 99);
     1198  QHBoxLayout* pppLayout3sub = new QHBoxLayout();
     1199  pppLayout3sub->addWidget(_pppWidgets._addStaButton);
     1200  pppLayout3sub->addWidget(_pppWidgets._delStaButton);
     1201  pppLayout3sub->addStretch(99);
     1202
     1203  pppLayout3->addLayout(pppLayout3sub);
     1204
     1205  pppGroup3->setLayout(pppLayout3);
     1206
     1207  // ------------------------
     1208  connect(_pppWidgets._mapWinButton, SIGNAL(clicked()), SLOT(slotMapPPP()));
     1209  _pppWidgets._mapSpeedSlider->setMinimumWidth(33 * ww);
     1210  _pppWidgets._audioResponse->setMaximumWidth(8 * ww);
     1211
     1212  QGridLayout* pppLayout4 = new QGridLayout();
     1213  ir = 0;
     1214  pppLayout4->addWidget(new QLabel("Precise Point Positioning - Plots.<br>"), ir, 0, 1, 50, Qt::AlignLeft);
     1215  ++ir;
     1216  pppLayout4->addWidget(new QLabel("PPP Plot"), ir, 0, Qt::AlignLeft);
     1217  pppLayout4->addWidget(_pppWidgets._plotCoordinates, ir, 1, Qt::AlignLeft);
     1218  pppLayout4->addWidget(new QLabel("Mountpoint"), ir, 2, 1, 10, Qt::AlignLeft);
     1219  pppLayout4->addWidget(_pppWidgets._audioResponse, ir, 4, Qt::AlignLeft);
     1220  pppLayout4->addWidget(new QLabel("Audio response"), ir, 5, Qt::AlignRight);
     1221  ++ir;
     1222  pppLayout4->addWidget(new QLabel("Track map"), ir, 0, Qt::AlignLeft);
     1223  pppLayout4->addWidget(_pppWidgets._mapWinButton, ir, 1, Qt::AlignLeft);
     1224  ++ir;
     1225  pppLayout4->addWidget(new QLabel("Dot-properties"), ir, 0, Qt::AlignLeft);
     1226  pppLayout4->addWidget(_pppWidgets._mapWinDotSize, ir, 1, Qt::AlignLeft);
     1227  pppLayout4->addWidget(new QLabel("Size    "), ir, 2, Qt::AlignLeft);
     1228  pppLayout4->addWidget(_pppWidgets._mapWinDotColor, ir, 3, Qt::AlignLeft);
     1229  pppLayout4->addWidget(new QLabel("Color"), ir, 4, Qt::AlignLeft);
     1230  ++ir;
     1231  pppLayout4->addWidget(new QLabel("Post-processing speed"), ir, 0, Qt::AlignLeft);
     1232  pppLayout4->addWidget(_pppWidgets._mapSpeedSlider, ir, 1, 1, 20, Qt::AlignLeft);
     1233  ++ir;
     1234  pppLayout4->addWidget(new QLabel(""), ir, 1);
     1235  pppLayout4->setRowStretch(ir, 999);
     1236
     1237  pppGroup4->setLayout(pppLayout4);
     1238
     1239  // Reqc Processing
     1240  // ---------------
     1241  _reqcActionComboBox = new QComboBox();
     1242  _reqcActionComboBox->setEditable(false);
     1243  _reqcActionComboBox->addItems(QString(",Edit/Concatenate,Analyze").split(","));
     1244  int ip = _reqcActionComboBox->findText(settings.value("reqcAction").toString());
     1245  if (ip != -1) {
     1246    _reqcActionComboBox->setCurrentIndex(ip);
     1247  }
     1248  connect(_reqcActionComboBox, SIGNAL(currentIndexChanged(const QString&)),
     1249          this, SLOT(slotBncTextChanged()));
     1250
     1251  QGridLayout* reqcLayout = new QGridLayout;
     1252  _reqcActionComboBox->setMinimumWidth(15 * ww);
     1253  _reqcActionComboBox->setMaximumWidth(20 * ww);
     1254
     1255  _reqcObsFileChooser = new qtFileChooser(0, qtFileChooser::Files);
     1256  _reqcObsFileChooser->setFileName(settings.value("reqcObsFile").toString());
     1257
     1258  _reqcNavFileChooser = new qtFileChooser(0, qtFileChooser::Files);
     1259  _reqcNavFileChooser->setFileName(settings.value("reqcNavFile").toString());
     1260  _reqcOutObsLineEdit = new QLineEdit(settings.value("reqcOutObsFile").toString());
     1261  _reqcOutNavLineEdit = new QLineEdit(settings.value("reqcOutNavFile").toString());
     1262  _reqcOutLogLineEdit = new QLineEdit(settings.value("reqcOutLogFile").toString());
     1263  _reqcPlotDirLineEdit = new QLineEdit(settings.value("reqcPlotDir").toString());
     1264  _reqcSkyPlotSignals = new QLineEdit(settings.value("reqcSkyPlotSignals").toString());
     1265
     1266  connect(_reqcSkyPlotSignals, SIGNAL(textChanged(const QString&)),
     1267          this, SLOT(slotBncTextChanged()));
     1268
     1269  _reqcLogSummaryOnly = new QCheckBox();
     1270  _reqcLogSummaryOnly->setCheckState(Qt::CheckState(settings.value("reqcLogSummaryOnly").toInt()));
     1271
     1272  ir = 0;
     1273  reqcLayout->addWidget(new QLabel("RINEX file editing, concatenation and quality check.<br>"), ir, 0, 1, 8);
     1274  ++ir;
     1275  reqcLayout->addWidget(new QLabel("Action"), ir, 0);
     1276  reqcLayout->addWidget(_reqcActionComboBox, ir, 1);
     1277  _reqcEditOptionButton = new QPushButton("Set Edit Options");
     1278  _reqcEditOptionButton->setMinimumWidth(15 * ww);
     1279  _reqcEditOptionButton->setMaximumWidth(20 * ww);
     1280
     1281  reqcLayout->addWidget(_reqcEditOptionButton, ir, 3);
     1282  ++ir;
     1283  reqcLayout->addWidget(new QLabel("Input files (full path)"), ir, 0);
     1284  reqcLayout->addWidget(_reqcObsFileChooser, ir, 1);
     1285  _reqcObsFileChooser->setMaximumWidth(40 * ww);
     1286  reqcLayout->addWidget(new QLabel("  Obs"), ir, 2);
     1287  reqcLayout->addWidget(_reqcNavFileChooser, ir, 3);
     1288  _reqcNavFileChooser->setMaximumWidth(40 * ww);
     1289  reqcLayout->addWidget(new QLabel("  Nav"), ir, 4);
     1290  ++ir;
     1291  reqcLayout->addWidget(new QLabel("Output file (full path)"), ir, 0);
     1292  reqcLayout->addWidget(_reqcOutObsLineEdit, ir, 1);
     1293  _reqcOutObsLineEdit->setMaximumWidth(40 * ww);
     1294  reqcLayout->addWidget(new QLabel("  Obs"), ir, 2);
     1295  reqcLayout->addWidget(_reqcOutNavLineEdit, ir, 3);
     1296  _reqcOutNavLineEdit->setMaximumWidth(40 * ww);
     1297  reqcLayout->addWidget(new QLabel("  Nav"), ir, 4);
     1298  ++ir;
     1299  reqcLayout->addWidget(new QLabel("Logfile"), ir, 0);
     1300  reqcLayout->addWidget(_reqcOutLogLineEdit, ir, 1);
     1301  _reqcOutLogLineEdit->setMaximumWidth(40 * ww);
     1302  reqcLayout->addWidget(new QLabel("  Summary only"), ir, 2);
     1303  reqcLayout->addWidget(_reqcLogSummaryOnly, ir, 3);
     1304  ++ir;
     1305  reqcLayout->addWidget(new QLabel("Plots for signals"), ir, 0);
     1306  reqcLayout->addWidget(_reqcSkyPlotSignals, ir, 1);
     1307  _reqcSkyPlotSignals->setMaximumWidth(40 * ww);
     1308  ++ir;
     1309  reqcLayout->addWidget(new QLabel("Directory for plots"), ir, 0);
     1310  reqcLayout->addWidget(_reqcPlotDirLineEdit, ir, 1);
     1311  _reqcPlotDirLineEdit->setMaximumWidth(40 * ww);
     1312  ++ir;
     1313  reqcLayout->setRowStretch(ir, 999);
     1314
     1315  reqcLayout->setColumnMinimumWidth(2, 8 * ww);
     1316  reqcLayout->setColumnMinimumWidth(4, 8 * ww);
     1317
     1318  reqcgroup->setLayout(reqcLayout);
     1319
     1320  connect(_reqcEditOptionButton, SIGNAL(clicked()),
     1321          this, SLOT(slotReqcEditOption()));
     1322
     1323  QGridLayout* sp3CompLayout = new QGridLayout;
     1324
     1325  _sp3CompFileChooser = new qtFileChooser(0, qtFileChooser::Files);
     1326  _sp3CompFileChooser->setFileName(settings.value("sp3CompFile").toString());
     1327  _sp3CompFileChooser->setMinimumWidth(15 * ww);
     1328  _sp3CompFileChooser->setMaximumWidth(40 * ww);
     1329
     1330  _sp3CompExclude = new QLineEdit(settings.value("sp3CompExclude").toString());
     1331  _sp3CompExclude->setMinimumWidth(18 * ww);
     1332  _sp3CompExclude->setMaximumWidth(18 * ww);
     1333
     1334  _sp3CompLogLineEdit = new QLineEdit(settings.value("sp3CompOutLogFile").toString());
     1335  _sp3CompLogLineEdit->setMinimumWidth(18 * ww);
     1336  _sp3CompLogLineEdit->setMaximumWidth(18 * ww);
     1337
     1338  _sp3CompSummaryOnly = new QCheckBox();
     1339  _sp3CompSummaryOnly->setCheckState(Qt::CheckState(settings.value("sp3CompSummaryOnly").toInt()));
     1340
     1341  ir = 0;
     1342  sp3CompLayout->addWidget(new QLabel("Orbit and clock comparison.<br>"), ir, 0, 1, 40);
     1343  ++ir;
     1344  sp3CompLayout->addWidget(new QLabel("Input SP3 files (full path)"), ir, 0, Qt::AlignLeft);
     1345  sp3CompLayout->addWidget(_sp3CompFileChooser, ir, 1, 1, 20);
     1346  ++ir;
     1347  sp3CompLayout->addWidget(new QLabel("Exclude satellites"), ir, 0, Qt::AlignLeft);
     1348  sp3CompLayout->addWidget(_sp3CompExclude, ir, 1, Qt::AlignRight);
     1349  ++ir;
     1350  sp3CompLayout->addWidget(new QLabel("Logfile"), ir, 0, Qt::AlignLeft);
     1351  sp3CompLayout->addWidget(_sp3CompLogLineEdit, ir, 1, Qt::AlignRight);
     1352  ++ir;
     1353  sp3CompLayout->addWidget(new QLabel("Summary only"), ir, 0);
     1354  sp3CompLayout->addWidget(_sp3CompSummaryOnly, ir, 1);
     1355  ++ir;
     1356  sp3CompLayout->addWidget(new QLabel(""), ir, 1);
     1357  ++ir;
     1358  sp3CompLayout->setRowStretch(ir, 999);
     1359
     1360  sp3CompLayout->setColumnMinimumWidth(2, 8 * ww);
     1361  sp3CompLayout->setColumnMinimumWidth(4, 8 * ww);
     1362
     1363  sp3CompGroup->setLayout(sp3CompLayout);
     1364
     1365  connect(_sp3CompFileChooser, SIGNAL(fileNameChanged(const QString&)),
     1366          this, SLOT(slotBncTextChanged()));
     1367
     1368  // Combine Corrections
     1369  // -------------------
     1370  QGridLayout* cmbLayout = new QGridLayout;
     1371
     1372  populateCmbTable();
     1373  cmbLayout->addWidget(_cmbTable, 0, 0, 8, 10);
     1374  cmbLayout->addWidget(new QLabel(" Combine Broadcast Correction streams"), 0, 10, 1, 10);
     1375  cmbLayout->addWidget(addCmbRowButton, 1, 10);
     1376  cmbLayout->addWidget(delCmbRowButton, 1, 11);
     1377  cmbLayout->addWidget(new QLabel("Method"), 2, 10, Qt::AlignLeft);
     1378  cmbLayout->addWidget(_cmbMethodComboBox, 2, 11);
     1379  cmbLayout->addWidget(new QLabel("BSX File"), 3, 10, Qt::AlignLeft);
     1380  cmbLayout->addWidget(_cmbBsxFile, 3, 11, Qt::AlignRight);
     1381  cmbLayout->addWidget(new QLabel("Max Clk Residual"), 4, 10, Qt::AlignLeft);
     1382  cmbLayout->addWidget(_cmbMaxresLineEdit, 4, 11, Qt::AlignRight);
     1383  cmbLayout->addWidget(new QLabel("Max Orb Displacement"), 5, 10, Qt::AlignLeft);
     1384  cmbLayout->addWidget(_cmbMaxdisplacementLineEdit, 5, 11, Qt::AlignRight);
     1385  cmbLayout->addWidget(new QLabel("Logfile directory"), 6, 10, Qt::AlignLeft);
     1386  cmbLayout->addWidget(_cmbLogPath, 6, 11, Qt::AlignRight);
     1387  cmbLayout->addWidget(new QLabel("Sampling"), 7, 10, Qt::AlignLeft);
     1388  cmbLayout->addWidget(_cmbSamplComboBox, 7, 11, Qt::AlignRight);
     1389
     1390
     1391  cmbLayout->addWidget(new QLabel("GNSS"), 0, 14, Qt::AlignLeft);
     1392  cmbLayout->addWidget(new QLabel("GPS (C1W/C2W)"), 1, 14);
     1393  cmbLayout->addWidget(_cmbGpsCheckBox, 1, 15);
     1394
     1395  cmbLayout->addWidget(new QLabel("GLONASS (C1P/C2P)"), 2, 14);
     1396  cmbLayout->addWidget(_cmbGloCheckBox, 2, 15);
     1397
     1398  cmbLayout->addWidget(new QLabel("Galileo (C1C/C5Q)"), 3, 14);
     1399  cmbLayout->addWidget(_cmbGalCheckBox, 3, 15);
     1400
     1401  cmbLayout->addWidget(new QLabel("Beidou (C2I/C6I)"), 4, 14);
     1402  cmbLayout->addWidget(_cmbBdsCheckBox, 4, 15);
     1403
     1404  cmbLayout->addWidget(new QLabel("QZSS (C1C/C2L)"), 5, 14);
     1405  cmbLayout->addWidget(_cmbQzssCheckBox, 5, 15);
     1406
     1407  cmbLayout->addWidget(new QLabel("SBAS (C1C/C5Q)"), 6, 14);
     1408  cmbLayout->addWidget(_cmbSbasCheckBox, 6, 15);
     1409
     1410  cmbLayout->addWidget(new QLabel("NavIC"), 7, 14);
     1411  cmbLayout->addWidget(_cmbNavicCheckBox, 7, 15);
     1412  cmbLayout->setRowStretch(9, 999);
     1413
     1414  connect(addCmbRowButton, SIGNAL(clicked()), this, SLOT(slotAddCmbRow()));
     1415  connect(delCmbRowButton, SIGNAL(clicked()), this, SLOT(slotDelCmbRow()));
     1416
     1417  cmbgroup->setLayout(cmbLayout);
     1418
     1419  // Upload Layout (Clocks)
     1420  // ----------------------
     1421  QGridLayout* uploadHlpLayout = new QGridLayout();
     1422
     1423  connect(addUploadRowButton, SIGNAL(clicked()), this, SLOT(slotAddUploadRow()));
     1424  connect(delUploadRowButton, SIGNAL(clicked()), this, SLOT(slotDelUploadRow()));
     1425  connect(setUploadTrafoButton, SIGNAL(clicked()), this, SLOT(slotSetUploadTrafo()));
     1426
     1427  uploadHlpLayout->addWidget(addUploadRowButton, 0, 0);
     1428  uploadHlpLayout->addWidget(delUploadRowButton, 0, 1);
     1429  uploadHlpLayout->addWidget(new QLabel("Interval"), 0, 2, Qt::AlignRight);
     1430  uploadHlpLayout->addWidget(_uploadIntrComboBox, 0, 3);
     1431  uploadHlpLayout->addWidget(new QLabel("     Sampling:    Orb"), 0, 4, Qt::AlignRight);
     1432  uploadHlpLayout->addWidget(_uploadSamplRtcmEphCorrComboBox, 0, 5);
     1433  uploadHlpLayout->addWidget(new QLabel("SP3"), 0, 6, Qt::AlignRight);
     1434  uploadHlpLayout->addWidget(_uploadSamplSp3ComboBox, 0, 7);
     1435  uploadHlpLayout->addWidget(new QLabel("RNX"), 0, 8, Qt::AlignRight);
     1436  uploadHlpLayout->addWidget(_uploadSamplClkRnxSpinBox, 0, 9);
     1437  uploadHlpLayout->addWidget(new QLabel("BSX"), 0, 10, Qt::AlignRight);
     1438  uploadHlpLayout->addWidget(_uploadSamplBiaSnxSpinBox, 0, 11);
     1439  uploadHlpLayout->addWidget(setUploadTrafoButton, 0, 12);
     1440  uploadHlpLayout->addWidget(new QLabel("ANTEX file"), 1, 0, Qt::AlignLeft);
     1441  uploadHlpLayout->addWidget(_uploadAntexFile, 1, 1, 1, 4);
     1442
     1443  QBoxLayout* uploadLayout = new QBoxLayout(QBoxLayout::TopToBottom);
     1444  populateUploadTable();
     1445
     1446  uploadLayout->addWidget(new QLabel("Upload RTCM Version 3 Broadcast Corrections to Broadcaster.<br>"));
     1447  uploadLayout->addWidget(_uploadTable);
     1448  uploadLayout->addLayout(uploadHlpLayout);
     1449
     1450  uploadgroup->setLayout(uploadLayout);
     1451
     1452  // Upload Layout (Ephemeris)
     1453  // -------------------------
     1454  QGridLayout* uploadHlpLayoutEph = new QGridLayout();
     1455
     1456  connect(addUploadEphRowButton, SIGNAL(clicked()), this, SLOT(slotAddUploadEphRow()));
     1457  connect(delUploadEphRowButton, SIGNAL(clicked()), this, SLOT(slotDelUploadEphRow()));
     1458
     1459  uploadHlpLayoutEph->addWidget(addUploadEphRowButton, 0, 0);
     1460  uploadHlpLayoutEph->addWidget(delUploadEphRowButton, 0, 1);
     1461  uploadHlpLayoutEph->addWidget(new QLabel("     Sampling"), 0, 2, Qt::AlignRight);
     1462  uploadHlpLayoutEph->addWidget(_uploadSamplRtcmEphSpinBox, 0, 3);
     1463
     1464  QBoxLayout* uploadLayoutEph = new QBoxLayout(QBoxLayout::TopToBottom);
     1465  populateUploadEphTable();
     1466
     1467  uploadLayoutEph->addWidget(new QLabel("Upload RTCM Version 3 Broadcast Ephemeris to Broadcaster.<br>"));
     1468  uploadLayoutEph->addWidget(_uploadEphTable);
     1469  uploadLayoutEph->addLayout(uploadHlpLayoutEph);
     1470
     1471  uploadEphgroup->setLayout(uploadLayoutEph);
     1472
     1473
     1474  // Upload Layout (Raw Data)
     1475  // -------------------------
     1476  QGridLayout* uploadHlpLayoutRaw = new QGridLayout();
     1477
     1478  connect(addUploadRawRowButton, SIGNAL(clicked()), this, SLOT(slotAddUploadRawRow()));
     1479  connect(delUploadRawRowButton, SIGNAL(clicked()), this, SLOT(slotDelUploadRawRow()));
     1480
     1481  uploadHlpLayoutRaw->addWidget(addUploadRawRowButton, 0, 0);
     1482  uploadHlpLayoutRaw->addWidget(delUploadRawRowButton, 0, 1);
     1483
     1484  QBoxLayout* uploadLayoutRaw = new QBoxLayout(QBoxLayout::TopToBottom);
     1485  populateUploadRawTable();
     1486
     1487  uploadLayoutRaw->addWidget(new QLabel("Upload Raw Data to Broadcaster (Ntrip Server Functionality).<br>"));
     1488  uploadLayoutRaw->addWidget(_uploadRawTable);
     1489  uploadLayoutRaw->addLayout(uploadHlpLayoutRaw);
     1490
     1491  uploadRawgroup->setLayout(uploadLayoutRaw);
     1492
     1493  // Main Layout
     1494  // -----------
     1495  QGridLayout* mLayout = new QGridLayout;
     1496  _aogroup->setCurrentIndex(settings.value("startTab").toInt());
     1497  mLayout->addWidget(_aogroup, 0, 0);
     1498  mLayout->addWidget(_mountPointsTable, 1, 0);
     1499  _loggroup->setCurrentIndex(settings.value("statusTab").toInt());
     1500  mLayout->addWidget(_loggroup, 2, 0);
     1501
     1502  _canvas->setLayout(mLayout);
     1503
     1504  // WhatsThis, Network
     1505  // ------------------
     1506  _proxyHostLineEdit->setWhatsThis(tr("<p>If you are running BNC within a protected Local Area Network (LAN), you may need to use a proxy server to access the Internet. Enter your proxy server IP and port number in case one is operated in front of BNC. If you do not know the IP and port of your proxy server, check the proxy server settings in your Internet browser or ask your network administrator. Without any entry, BNC will try to use the system proxies. </p><p>Note that IP streaming is sometimes not allowed in a LAN. In this case you need to ask your network administrator for an appropriate modification of the local security policy or for the installation of a TCP relay to the Ntrip Broadcasters. If this is not possible, you may need to run BNC outside your LAN on a network that has unobstructed connection to the Internet. <i>[key: proxyHost]</i></p>"));
     1507  _proxyPortLineEdit->setWhatsThis(tr("<p>Enter your proxy server port number in case a proxy is operated in front of BNC. <i>[key: proxyPort]</i></p>"));
     1508  _sslCaCertPathLineEdit->setWhatsThis(tr("<p>Communication with an Ntrip Broadcaster over SSL requires the exchange of server certificates. Specify the path to a directory where you save CA certificates on your system. </p><p>BNC creates from *.crt and *.pem files a CA certificate database, which is used by the socket during the handshake phase to validate the peer's certificate. </p><p>Note that SSL communication is usually done over port 443. <i>[key: sslCaCertPath]</i></p>"));
     1509  _sslClientCertPathLineEdit->setWhatsThis(tr("<p>Two-sided communication with an Ntrip Broadcaster over SSL requires in addition the exchange of client certificates. Specify the full path to the client certificates on your system.</p><p></p><p>The file naming convention for client certificates in BNC is as follows: &lt;hostname&gt;.&lt;port&gt;.crt for the certificate and &lt;hostname&gt;.&lt;port&gt;.key for the private key, where &lt;hostname&gt; is without https://. </p><p> If available, the client or personal authentication certificate is presented to the peer during the SSL handshake process. Password protected key files are not supported. </p><p>Don't try communication via two sided SSL if you are not sure whether this is supported by the involved Ntrip Broadcaster. </p><p>Note that SSL communication is usually done over port 443. <i>[key: sslClientCertPath]</i></p>"));
     1510  _sslIgnoreErrorsCheckBox->setWhatsThis(tr("<p>SSL communication may involve queries coming from the Ntrip Broadcaster. Tick 'Ignore SSL authorization errors' if you don't want to be bothered with this. <i>[key: sslIgnoreErrors]</i></p>"));
     1511
     1512  // WhatsThis, General
     1513  // ------------------
     1514  _logFileLineEdit->setWhatsThis(tr("<p>Records of BNC's activities are shown in the 'Log' tab on the bottom of this window. They can be saved into a file when a valid path for that is specified in the 'Logfile (full path)' field.</p><p>The logfile name will automatically be extended by a string '_YYMMDD' carrying the current date. <i>[key: logFile]</i></p>"));
     1515  _rnxAppendCheckBox->setWhatsThis(tr("<p>When BNC is started, new files are created by default and file content already available under the same name will be overwritten. However, users might want to append already existing files following a regular restart or a crash of BNC or its platform.</p><p>Tick 'Append files' to continue with existing files and keep what has been recorded so far. <i>[key: rnxAppend]</i></p>"));
     1516  _onTheFlyComboBox->setWhatsThis(tr("<p>When operating BNC online in 'no window' mode, some configuration parameters can be changed on-the-fly without interrupting the running process. For that BNC rereads parts of its configuration in pre-defined intervals. The default entry is 'no' that means the reread function is switched of. <p></p>Select '1 min', '5 min', '1 hour', or '1 day' to force BNC to reread its configuration every full minute, five minutes, hour, or day and let in between edited configuration options become effective on-the-fly without terminating uninvolved threads.</p><p>Note that when operating BNC in window mode, on-the-fly changeable configuration options become effective immediately via button 'Save & Reread Configuration'. <i>[key: onTheFlyInterval]</i></p>"));
     1517  _autoStartCheckBox->setWhatsThis(tr("<p>Tick 'Auto start' for auto-start of BNC at startup time in window mode with preassigned processing options. <i>[key: autoStart]</i></p>"));
     1518  _rawOutFileLineEdit->setWhatsThis(tr("<p>Save all data coming in through various streams in the received order and format in one file.</p><p>This option is primarily meant for debugging purposes. <i>[key: rawOutFile]</i></p>"));
     1519
     1520  // WhatsThis, RINEX Observations
     1521  // -----------------------------
     1522  _rnxPathLineEdit->setWhatsThis(tr("<p>Here you specify the path to where the RINEX Observation files will be stored.</p><p>If the specified directory does not exist, BNC will not create RINEX Observation files. <i>[key: rnxPath]</i></p>"));
     1523  _rnxIntrComboBox->setWhatsThis(tr("<p>Select the length of the RINEX Observation file. <i>[key: rnxIntr]</i></p>"));
     1524  _rnxSamplComboBox->setWhatsThis(tr("<p>Select the RINEX Observation sampling interval in seconds. <i>[key: rnxSampl]</i></p>"));
     1525  _rnxSkelExtComboBox->setWhatsThis(tr("<p>BNC allows using personal RINEX skeleton files that contain the RINEX header records you would like to include. You can derive a skeleton file from information given in an up to date sitelog.</p><p>A file in the RINEX Observations 'Directory' with a 'Skeleton extension' skl or SKL is interpreted by BNC as a personal RINEX header skeleton file for the corresponding stream. <i>[key: rnxSkel]</i></p>"));
     1526  _rnxSkelPathLineEdit->setWhatsThis(tr("<p>Here you specify the path to where local skeleton files are located.</p><p> If no directory is specified, the path is assumed to where the RINEX Observation files will stored. <i>[key: rnxSkelPath]</i></p>"));
     1527  _rnxFileCheckBox->setWhatsThis(tr("<p>Tick check box 'Skeleton mandatory' in case you want that RINEX files are only produced if skeleton files are available for BNC. If no skeleton file is available for a particular source then no RINEX Observation file will be produced from the affected stream.</p><p>Note that a skeleton file contains RINEX header information such as receiver and antenna types. In case of stream conversion to RINEX Version 3, a skeleton file should also contain information on potentially available observation types. A missing skeleton file will therefore enforce BNC to only save a default set of RINEX 3 observation types. <i>[key: rnxOnlyWithSKL]</i></p>"));
     1528  _rnxScrpLineEdit->setWhatsThis(tr("<p>Whenever a RINEX Observation file is finally saved, you may want to compress, copy or upload it immediately, for example via FTP. BNC allows you to execute a script/batch file to carry out such operation.</p><p>Specify the full path of a script or batch file. BNC will pass the full RINEX Observation file path to the script as command line parameter (%1 on Windows systems, $1 on Unix/Linux/Mac systems). <i>[key: rnxScript]</i></p>"));
     1529  _rnxV2Priority->setWhatsThis(tr("<p>Specify a priority list of characters defining signal attributes as defined in RINEX Version 3. Priorities will be used to map observations with RINEX Version 3 attributes from incoming streams to Version 2. The underscore character '_' stands for undefined attributes. A question mark '?' can be used as wildcard which represents any one character.</p><p>Signal priorities can be specified as equal for all systems, as system specific or as system and freq. specific. For example: </li><ul><li>'CWPX_?' (General signal priorities valid for all GNSS) </li><li>'I:ABCX' (System specific signal priorities for NavIC) </li><li>'G:12&PWCSLX G:5&IQX R:12&PC R:3&IQX' (System and frequency specific signal priorities) </li></ul>Default is the following priority list 'G:12&PWCSLX G:5&IQX R:12&PC R:3&IQX R:46&ABX E:16&BCXZ E:578&IQX J:1&SLXCZ J:26&SLX J:5&IQX C:267&IQX C:18&DPX I:ABCX S:1&C S:5&IQX'. <i>[key: rnxV2Priority]</i></p>"));
     1530  _rnxVersComboBox->setWhatsThis(tr("<p>Select the format for RINEX Observation files. <i>[key: rnxVersion]</i></p>"));
     1531
     1532  // WhatsThis, RINEX Ephemeris
     1533  // --------------------------
     1534  _ephPathLineEdit->setWhatsThis(tr("<p>Specify the path for saving Broadcast Ephemeris data as RINEX Navigation files.</p><p>If the specified directory does not exist, BNC will not create RINEX Navigation files. <i>[key: ephPath]</i></p>"));
     1535  _ephIntrComboBox->setWhatsThis(tr("<p>Select the length of the RINEX Navigation file. <i>[key: ephIntr]</i></p>"));
     1536  _ephOutPortLineEdit->setWhatsThis(tr("<p>BNC can produce ephemeris data in RINEX Navigation ASCII format on your local host through an IP port.</p><p>Specify a port number here to activate this function. <i>[key: ephOutPort]</i></p>"));
     1537  _ephVersComboBox->setWhatsThis(tr("<p>Select the format for RINEX Navigation files. <i>[key: ephVersion]</i></p>"));
     1538  //_ephFilePerStation->setWhatsThis(tr("<p>By default, all received Broadcast Ephemeris data will be stored within one File. Thick 'File per Stations' to get separate files per station/mountpoint. <i>[key: ephFilePerStation]</i></p>"));
     1539
     1540  // WhatsThis, RINEX Editing & QC
     1541  // -----------------------------
     1542  _reqcActionComboBox->setWhatsThis(tr("<p>BNC allows to 'Edit or Concatenate' RINEX Version 2 or 3 files or to perform a Quality Check (QC) and 'Analyze' data following UNAVCO's famous 'teqc' program. <i>[key: reqcAction]</i></p>"));
     1543  _reqcEditOptionButton->setWhatsThis(tr("<p>Specify options for editing RINEX Version 2 or 3 files.</p>"));
     1544  _reqcObsFileChooser->setWhatsThis(tr("<p>Specify the full path to input observation files in RINEX Version 2 or 3 format.</p><p>Note that when in 'Analyze' mode, specifying at least one RINEX observation file is mandatory. <i>[key: reqcObsFile]</i></p>"));
     1545  _reqcNavFileChooser->setWhatsThis(tr("<p>Specify the full path to input navigation files in RINEX Version 2 or 3 format.</p><p>Note that when in 'Analyze' mode, specifying at least one RINEX navigation file is mandatory. <i>[key: reqcNavFile]</i></p>"));
     1546  _reqcOutObsLineEdit->setWhatsThis(tr("<p>Specify the full path to a RINEX Observation output file.</p><p>Default is an empty option field, meaning that no RINEX Observation output file will be produced. <i>[key: reqcOutObsFile]</i></p>"));
     1547  _reqcOutNavLineEdit->setWhatsThis(tr("<p>Specify the full path to a RINEX Navigation output file.</p><p>Default is an empty option field, meaning that no RINEX Navigation output file will be produced. <i>[key: reqcOutNavFile]</i></p>"));
     1548  _reqcOutLogLineEdit->setWhatsThis(tr("<p>Specify the full path to a logfile.</p><p>Default is an empty option field, meaning that no 'RINEX Editing & QC' logfile will be produced. <i>[key: reqcOutLogFile]</i></p>"));
     1549  _reqcLogSummaryOnly->setWhatsThis(tr("<p>By default BNC produces a detailed 'Logfile' providing all information resulting from editing or analyzing RINEX data. If that is too much information, you can limit the logfile content to a short summary.</p><p>Tick 'Summary only' to suppress full logfile output and instead produce a logfile containing only summary information. <i>[key: reqcLogSummaryOnly]</i></p>"));
     1550  _reqcPlotDirLineEdit->setWhatsThis(tr("<p>Specify a directory for saving plots in PNG format.</p><p>Default is an empty option field, meaning that plots will not be saved on disk. <i>[key: reqcPlotDir]</i></p>"));
     1551  _reqcSkyPlotSignals->setWhatsThis(tr("<p>BNC can produce plots for multipath, signal-to-noise ratio, satellite availability, satellite elevation, and PDOP values. The 'Plots for signals' option lets you exactly specify observation signals to be used for that and also enables the plot generation. You can specify the navigation system, the frequency, and the tracking mode or channel as defined in RINEX Version 3. Specifications for frequency and tracking mode or channel must be separated by ampersand character '&'. Specifications for navigation systems must be separated by blank character ' '.</p><p>Examples for 'Plots for signals' option:<ul><li> G:1&2&5 R:1&2&3 E:1&7 C:2&6 J:1&2 I:5&9 S:1&5 <br>(Plots will be based on GPS observations on 1st and 2nd frequency, GLONASS observations on 1st and 2nd frequency, QZSS observations on 1st and 2nd frequency, Galileo observations on 1st and 7th frequency, BeiDou observations on 1st and 6th frequency, SBAS observations on 1st frequency.)</li><li>G:1C&5X<br>(Plots will be based on GPS observations on 1st frequency in C tracking mode and GPS observations on 5th frequency in X tracking mode.)</li><li>C:6I&7I<br>(Plots will be based on BeiDou observations on 6th frequency in I tracking mode and BeiDou observations on 7th frequency in I tracking mode.)<li></ul></p><p>Default is 'G:1&2 R:1&2 E:1&5 C:2&6 J:1&2 I:5&9 S:1&5'. Specifying an empty option string would be overruled by this default. <i>[key: reqcSkyPlotSignals]</i></p>"));
     1552
     1553  // WhatsThis, SP3 Comparison
     1554  // -------------------------
     1555  _sp3CompFileChooser->setWhatsThis(tr("<p>BNC can compare two SP3 files containing GNSS satellite orbit and clock information.</p></p>Specify the full path to two files with orbits and clocks in SP3 format, separate them by comma. <i>[key: sp3CompFile]</i></p>"));
     1556  _sp3CompExclude->setWhatsThis(tr("<p>Specify satellites to exclude them from orbit and clock comparison. Example:<p>G04,G31,R</p><p>This excludes GPS satellites PRN 4 and 31 as well as all GLONASS satellites from the comparison.</p><p>Default is an empty option field, meaning that no satellite is excluded from the comparison. <i>[key: sp3CompExclude]</i></p>"));
     1557  _sp3CompLogLineEdit->setWhatsThis(tr("<p>Specify the full path to a logfile saving comparison results.</p><p>Specifying a logfile is mandatory. Comparing SP3 files and not saving comparison results on disk would be useless. <i>[key: sp3CompOutLogFile]</i></p>"));
     1558  _sp3CompSummaryOnly->setWhatsThis(tr("<p>By default BNC produces a detailed 'Logfile' providing all information resulting from comparing SP3 files. If that is too much information, you can limit the logfile content to a short summary.</p><p>Tick 'Summary only' to suppress full logfile output and instead produce a logfile containing only summary information. <i>[key: sp3CompSummaryOnly]</i></p>"));
     1559
     1560  // WhatsThis, Broadcast Corrections
     1561  // --------------------------------
     1562  _corrPathLineEdit->setWhatsThis(tr("<p>Specify a directory for saving Broadcast Ephemeris Correction files.</p><p>If the specified directory does not exist, BNC will not create the files. <i>[key: corrPath]</i></p>"));
     1563  _corrIntrComboBox->setWhatsThis(tr("<p>Select the length of Broadcast Ephemeris Correction files. <i>[key: corrIntr]</i></p>"));
     1564  _corrPortLineEdit->setWhatsThis(tr("<p>BNC can produce Broadcast Ephemeris Corrections on your local host through an IP port.</p><p>Specify a port number here to activate this function. <i>[key: corrPort]</i></p>"));
     1565
     1566  // WhatsThis, Feed Engine
     1567  // ----------------------
     1568  _outPortLineEdit->setWhatsThis(tr("<p>BNC can produce synchronized observations in a plain ASCII format on your local host via IP port.</p><p>Specify a port number to activate this function. <i>[key: outPort]</i></p>"));
     1569  _outWaitSpinBox->setWhatsThis(tr("<p>When feeding a real-time GNSS network engine waiting for synchronized input epoch by epoch, BNC drops whatever is received later than 'Wait for full obs epoch' seconds.</p><p>A value of 3 to 5 seconds is recommended, depending on the latency of the incoming streams and the delay acceptable to your real-time GNSS network engine or product. <i>[key: outWait]</i></p>"));
     1570  _outSamplComboBox->setWhatsThis(tr("<p>Select a synchronized observation sampling interval in seconds. <i>[key: outSampl]</i></p>"));
     1571  _outFileLineEdit->setWhatsThis(tr("<p>Specify the full path to a file where synchronized observations are saved in plain ASCII format.</p><p>Beware that the size of this file can rapidly increase depending on the number of incoming streams. <i>[key: outFile]</i></p>"));
     1572  _outUPortLineEdit->setWhatsThis(tr("<p>BNC can produce unsynchronized observations in a plain ASCII format on your local host via IP port.</p><p>Specify a port number to activate this function. <i>[key: outUPort]</i></p>"));
     1573  _outLockTimeCheckBox->setWhatsThis(tr("<p>Print the lock time in seconds in the feed engine output.<i>[key: outLockTime]</i></p>"));
     1574
     1575  // WhatsThis, Serial Output
     1576  // ------------------------
     1577  _serialMountPointLineEdit->setWhatsThis(tr("<p>Enter a 'Mountpoint' to forward the corresponding stream to a serial connected receiver.</p><p>Depending on the stream content, the receiver may use it for example for Differential GNSS, Precise Point Positioning or any other purpose supported by its firmware. <i>[key: serialMountPoint]</i></p>"));
     1578  _serialPortNameLineEdit->setWhatsThis(tr("<p>Enter the serial 'Port name' selected for communication with your serial connected receiver. Valid port names are e.g.</p><pre>Windows:       COM1, COM2<br>Linux:         /dev/ttyS0, /dev/ttyS1<br>FreeBSD:       /dev/ttyd0, /dev/ttyd1<br>Digital Unix:  /dev/tty01, /dev/tty02<br>HP-UX:         /dev/tty1p0, /dev/tty2p0<br>SGI/IRIX:      /dev/ttyf1, /dev/ttyf2<br>SunOS/Solaris: /dev/ttya, /dev/ttyb</pre><p>Note that before you start BNC, you must plug a serial cable in the port defined here. <i>[key: serialPortName]</i></p>"));
     1579  _serialBaudRateComboBox->setWhatsThis(tr("<p>Select a 'Baud rate' for the serial output link.</p><p>Note that your selection must equal the baud rate configured to the serial connected receiver. Using a high baud rate is recommended. <i>[key: serialBaudRate]</i></p>"));
     1580  _serialFlowControlComboBox->setWhatsThis(tr("<p>Select a 'Flow control' for the serial output link.</p><p>Note that your selection must equal the flow control configured to the serial connected receiver. Select 'OFF' if you don't know better. <i>[key: serialFlowControl]</i></p>"));
     1581  _serialDataBitsComboBox->setWhatsThis(tr("<p>Select the number of 'Data bits' for the serial output link.</p><p>Note that your selection must equal the number of data bits configured to the serial connected receiver. Note further that often 8 data bits are used. <i>[key: serialDataBits]</i></p>"));
     1582  _serialParityComboBox->setWhatsThis(tr("<p>Select a 'Parity' for the serial output link.</p><p>Note that your selection must equal the parity selection configured to the serial connected receiver. The parity is often set to 'NONE'. <i>[key: serialParity]</i></p>"));
     1583  _serialStopBitsComboBox->setWhatsThis(tr("<p>Select the number of 'Stop bits' for the serial output link.</p><p>Note that your selection must equal the number of stop bits configured to the serial connected receiver. Note further that often 1 stop bit is used. <i>[key: serialStopBits]</i></p>"));
     1584  _serialAutoNMEAComboBox->setWhatsThis(tr("<p>The 'NMEA' option supports the so-called 'Virtual Reference Station' (VRS) concept which requires the receiver to send approximate position information to the Ntrip Broadcaster. Select 'no' if you don't want BNC to forward or upload any NMEA message to the Ntrip Broadcaster in support of VRS.</p><p>Select 'Auto' to automatically forward NMEA messages of type GGA from your serial connected receiver to the Ntrip Broadcaster and/or save them in a file.</p><p>Select 'Manual GPGGA' or 'Manual GNGGA' if you want BNC to produce and upload GPGGA or GNGGA NMEA messages to the Ntrip Broadcaster because your serial connected receiver doesn't generate these messages. A Talker ID 'GP' preceding the GGA string stands for GPS solutions while a Talker ID 'GN' stands for multi constellation solutions.</p><p>Note that selecting 'Auto' or 'Manual' works only for VRS streams which show up under the 'Streams' canvas on BNC's main window with 'nmea' stream attribute set to 'yes'. This attribute is either extracted from the Ntrip Broadcaster's source-table or introduced by the user via editing the BNC configuration file. <i>[key: serialAutoNMEA]</i></p>"));
     1585  _serialFileNMEALineEdit->setWhatsThis(tr("<p>Specify the full path to a file where NMEA messages coming from your serial connected receiver are saved.</p><p>Default is an empty option field, meaning that NMEA messages will not be saved on disk. <i>[key: serialFileNMEA]</i></p>"));
     1586  _serialHeightNMEALineEdit->setWhatsThis(tr("<p>Specify an approximate 'Height' above mean sea level in meters for the reference station introduced by option 'Mountpoint'. Together with the latitude and longitude from the source-table, the height information is used to build GGA messages to be sent to the Ntrip Broadcaster.</p><p>For adjusting latitude and longitude values of a VRS stream given in the 'Streams' canvas, you can double click the latitude/longitude data fields, specify appropriate values and then hit Enter.</p><p>This option is only relevant when option 'NMEA' is set to 'Manual GPGGA' or 'Manual GNGGA' respectively. <i>[key: serialHeightNMEA]</i></p>"));
     1587  _serialNMEASamplingSpinBox->setWhatsThis(tr("<p>Select a sampling interval in seconds for manual or receiver generated NMEA GGA sentences and their upload.</p><p>A sampling rate of '0' means, a GGA sentence will be send only once to initialize the requested VRS stream. Note that some VRS systems need GGA sentences at regular intervals. <i>[key: serialNMEASampling]</i></p>"));
     1588
     1589  // WhatsThis, Outages
     1590  // ------------------
     1591  _adviseObsRateComboBox->setWhatsThis(tr("<p>BNC can collect all returns (success or failure) coming from a decoder within a certain short time span to then decide whether a stream has an outage or its content is corrupted. The procedure needs a rough estimate of the expected 'Observation rate' of the incoming streams. When a continuous problem is detected, BNC can inform its operator about this event through an advisory note.</p><p>Default is an empty option field, meaning that you don't want BNC to report on stream failures or recoveries when exceeding a threshold time span. <i>[key: adviseObsRate]</i></p>"));
     1592  _adviseFailSpinBox->setWhatsThis(tr("<p>An advisory note is generated when no (or only corrupted) observations are seen throughout the 'Failure threshold' time span. A value of 15 min (default) is recommended.</p><p>A value of zero '0' means that for any stream failure, however short, BNC immediately generates an advisory note. <i>[key: adviseFail]</i></p>"));
     1593  _adviseRecoSpinBox->setWhatsThis(tr("<p>Following a stream outage or a longer series of bad observations, an advisory note is generated when valid observations are received again throughout the 'Recovery threshold' time span. A value of about 5min (default) is recommended.</p><p>A value of zero '0' means that for any stream recovery, however short, BNC immediately generates an advisory note. <i>[key: adviseReco]</i></p>"));
     1594  _adviseScriptLineEdit->setWhatsThis(tr("<p>Specify the full path to a script or batch file to handle advisory notes generated in the event of corrupted streams or stream outages. The affected mountpoint and a comment 'Begin_Outage', 'End_Outage', 'Begin_Corrupted', or 'End_Corrupted' are passed on to the script as command line parameters.</p><p>The script may have the task to send the advisory notes by email to BNC's operator and/or to the affected stream provider.</p><p>An empty option field (default) or invalid path means that you don't want to use this option. <i>[key: adviseScript]</i></p>"));
     1595
     1596  // WhatsThis, Miscellaneous
     1597  // ------------------------
     1598  _miscMountLineEdit->setWhatsThis(tr("<p>Specify a mountpoint to apply any of the options shown below. Enter 'ALL' if you want to apply these options to all configured streams.</p><p>An empty option field (default) means that you don't want BNC to apply any of these options. <i>[key: miscMount]</i></p>"));
     1599  _miscIntrComboBox->setWhatsThis(tr("<p>BNC can average latencies per stream over a certain period of GPS time. The resulting mean latencies are recorded in the 'Log' tab at the end of each 'Log latency' interval together with results of a statistical evaluation (approximate number of covered epochs, data gaps).</p><p>Select a 'Log latency' interval or select the empty option field if you do not want BNC to log latencies and statistical information. <i>[key: miscIntr]</i></p>"));
     1600  _miscScanRTCMCheckBox->setWhatsThis(tr("<p>Tick 'Scan RTCM' to log the numbers of incoming message types as well as contained antenna coordinates, antenna height, and antenna descriptor.</p><p>In case of RTCM Version 3 MSM streams, BNC will also log contained RINEX Version 3 observation types. <i>[key: miscScanRTCM]</i></p>"));
     1601  _miscPortLineEdit->setWhatsThis(tr("<p>BNC can output an incoming stream through an IP port of your local host.</p><p>Specify a port number to activate this function. In this case, the stream content remains untouched; BNC does not decode or reformat the data for this output.</p><p> If the decoder string is not an accepted one ('RTCM_2.x', 'RTCM_3.x' and 'RTNET'), please change the decoder string to <ul>"
     1602                                     "<li> 'ZERO' (forward the raw data) or </li>"
     1603                                     "<li> 'ZERO2FILE' (forward and store the raw data)</li> </ul> in addition. <i>[key: miscPort]</i></p>"));
     1604
     1605  // WhatsThis, PPP (1)
     1606  // ------------------
     1607  _pppWidgets._dataSource->setWhatsThis(tr("<p>Select 'Real-time Streams' for real-time PPP from RTCM streams or 'RINEX Files' for post processing PPP from RINEX files.</p><p><ul><li>Real-time PPP requires that you pull a RTCM stream carrying GNSS observations plus a stream providing corrections to Broadcast Ephemeris. If the observations stream does not contain Broadcast Ephemeris then you must in addition pull a Broadcast Ephemeris stream like 'RTCM3EPH' from Ntrip Broadcaster <u>products.igs-ip.net</u>.<br></li><li>Post processing PPP requires RINEX Observation files, RINEX Navigation files and a file with corrections to Broadcast Ephemeris in plain ASCII format as saved beforehand using BNC.</li></ul></p><p>Note that BNC allows to carry out PPP solutions simultaneously for several stations. <i>[key: PPP/dataSource]</i></p>"));
     1608  _pppWidgets._rinexObs->setWhatsThis(tr("<p>Specify the RINEX Observation file. <i>[key: PPP/rinexObs]</i></p>"));
     1609  _pppWidgets._rinexNav->setWhatsThis(tr("<p>Specify the RINEX Navigation file. <i>[key: PPP/rinexNav]</i></p>"));
     1610  _pppWidgets._corrMount->setWhatsThis(tr("<p>Specify a 'mountpoint' from the 'Streams' canvas below which provides corrections to Broadcast Ephemeris.</p><p>If you don't specify a corrections stream via this option, BNC will fall back to Single Point Positioning (SPP, positioning from observations and Broadcast Ephemeris only) instead of doing PPP. <i>[key: PPP/corrMount]</i></p>"));
     1611  _pppWidgets._ionoMount->setWhatsThis(tr("<p>Specify a 'mountpoint' from the 'Streams' canvas below which provides VTEC informations in SSR format.</p><p>If you don't specify a corrections stream via this option, BNC will use VTEC informations from the Corrections stream 'mountpoint', if available. <i>[key: PPP/ionoMount]</i></p>"));
     1612  _pppWidgets._corrFile->setWhatsThis(tr("<p>Specify the Broadcast Ephemeris Corrections file as saved beforehand using BNC.</p><p>If you don't specify corrections by this option, BNC will fall back to Single Point Positioning (SPP, positioning from RINEX Obs and RINEX Nav files only) instead of doing PPP. <i>[key: PPP/corrFile]</i></p>"));
     1613  _pppWidgets._ionoFile->setWhatsThis(tr("<p>Specify the VTEC file as saved beforehand using BNC.</p><p>If you don't specify corrections by this option, BNC will use VTEC informations from the Corrections file, if available. <i>[key: PPP/ionoFile]</i></p>"));
     1614  _pppWidgets._antexFile->setWhatsThis(tr("<p>Observations in RTCM streams or RINEX files should be referred to the receiver's and to the satellite's Antenna Phase Center (APC) and therefore be corrected for<ul><li>Receiver APC offsets and variations</li><li>Satellite APC offsets and variations.</li></ul> Specify the full path to an IGS 'ANTEX file' which contains APC offsets and variations for satellites and receiver.</p> <i>[key: PPP/antexFile]</i></p>"));
     1615  _pppWidgets._crdFile->setWhatsThis(tr("<p>Enter the full path to an ASCII file which specifies the streams or files of those stations you want to process. Specifying a 'Coordinates file' is optional. If it exists, it should contain one record per station with the following parameters separated by blank character:</p><ul><li>Specify the station either by:<ul><li>the 'Mountpoint' of the station's RTCM stream (in real-time PPP mode), or</li><li>the 9-char station ID of the RINEX Version 3 or 4 Observations file (in post processing PPP mode), or </li><li>the 4-char station ID of the RINEX Version 2 Observations file (in post processing PPP mode).</li></ul><li>Approximate X,Y,Z coordinate of station's Antenna Reference Point [m] (ARP, specify '0.0 0.0 0.0' if unknown).</li><li>North, East and Up component of antenna eccentricity [m] (specify '0.0 0.0 0.0' if unknown). </li><li>20 Characters describing the antenna type and radome following the IGS 'ANTEX file' standard (leave blank if unknown).</li><li>Receiver type following the naming conventions for IGS equipment.</li></ul>Records with exclamation mark '!' in the first column or blank records will be interpreted as comment lines and ignored.. <i>[key: PPP/crdFile]</i></p>"));
     1616  _pppWidgets._blqFile->setWhatsThis(tr("<p>Specify the full path to a 'BLQ file' containing the ocean loading coefficients for different stations. These coefficients can be obtained from the ocean loading service under request trough the web site http://holt.oso.chalmers.se/loading/. <i>[key: PPP/blqFile]</i></p>"));
     1617  _pppWidgets._logPath->setWhatsThis(tr("<p>Specify a directory for saving daily PPP logfiles. If the specified directory does not exist, BNC will not create such files.</p><p>Default is an empty option field, meaning that no PPP logfiles shall be produced. <i>[key: PPP/logPath]</i></p>"));
     1618  _pppWidgets._nmeaPath->setWhatsThis(tr("<p>Specify a directory for saving coordinates in daily NMEA files. If the specified directory does not exist, BNC will not create such files.</p><p>Default is an empty option field, meaning that no NMEA file shall be produced. <i>[key: PPP/nmeaPath]</i></p>"));
     1619  _pppWidgets._snxtroPath->setWhatsThis(tr("<p>Specify a directory for saving SINEX Troposphere files. If the specified directory does not exist, BNC will not create such files.</p><p>Default is an empty option field, meaning that no SINEX Troposphere files shall be produced. <i>[key: PPP/snxtroPath]</i></p>"));
     1620  _pppWidgets._snxtroIntr->setWhatsThis(tr("<p>Select a length for SINEX Troposphere files.</p><p>Default 'SNX TRO interval' for saving SINEX Troposphere files on disk is '1 hour'. <i>[key: PPP/snxtroIntr]</i></p>"));
     1621  _pppWidgets._snxtroSampl->setWhatsThis(tr("<p>Select a 'Sampling' rate for saving troposphere parameters. <i>[key: PPP/snxtroSampl]</i></p>"));
     1622  _pppWidgets._snxtroAc->setWhatsThis(tr("<p>Specify a 3-character abbreviation describing you as the generating Analysis Center (AC) in your SINEX troposphere files. <i>[key: PPP/snxtroAc]</i></p>"));
     1623  _pppWidgets._snxtroSolId->setWhatsThis(tr("<p>Specify a 1-character solution ID to allow a distinction between different solutions per AC. <i>[key: PPP/snxtroSolId]</i></p>"));
     1624  _pppWidgets._snxtroSolType->setWhatsThis(tr("<p>Specify a 3-character solution type, e.g. real-time (RTS), unknown (UNK), .. <i>[key: PPP/snxtroSolType]</i></p>"));
     1625  _pppWidgets._snxtroCampId->setWhatsThis(tr("<p>Specify a 3-character campaign ID, e.g. operational (OPS), demonstration (DEM), testing (TST), .. <i>[key: PPP/snxtroCampId]</i></p>"));
     1626
     1627  // WhatsThis, PPP (2)
     1628  // ------------------
     1629  _pppWidgets._lcGPS->setWhatsThis(tr("<p>Specify which kind of GPS observations you want to use and on which kind of linear combination the GPS ambiguity resolutions shall be based:</p><p><ul>"
     1630                                      "<li>'Pi&Li' means that uncombined code and phase data of two frequencies shall be used.</li>"
     1631                                      "<li>'Pi'    means that uncombined code data of two frequencies shall be used.</li>"
     1632                                      "<li>'P1&L1' means that uncombined code and phase data of one frequency shall be used.</li>"
     1633                                      "<li>'P1'    means that uncombined code data of one frequency shall be used.</li>"
     1634                                      "<li>'P3&L3' means that the inonosphere-free linear combination of code and phase data shall be used.</li>"
     1635                                      "<li>'P3'    means that the inonosphere-free linear combination of code data shall be used.</li>"
     1636                                      "<li>'L3'    means that the inonosphere-free linear combination of phase data shall be used.</li> "
     1637                                      "<li>'no'    means that you don't want BNC to use GPS data.</li></ul></p><p><i>[key: PPP/lcGPS]</i></p>"));
     1638  _pppWidgets._lcGLONASS->setWhatsThis(tr("<p>Specify which kind of GLONASS observations you want to use and on which kind of linear combination the GLONASS ambiguity resolutions shall be based:</p><p><ul>"
     1639                                          "<li>'Pi&Li' means that uncombined code and phase data of two frequencies shall be used.</li>"
     1640                                          "<li>'Pi'    means that uncombined code data of two frequencies shall be used.</li>"
     1641                                          "<li>'P1&L1' means that uncombined code and phase data of one frequency shall be used.</li>"
     1642                                          "<li>'P1'    means that uncombined code data of one frequency shall be used.</li>"
     1643                                          "<li>'P3&L3' means that the inonosphere-free linear combination of code and phase data shall be used.</li>"
     1644                                          "<li>'P3'    means that the inonosphere-free linear combination of code data shall be used.</li>"
     1645                                          "<li>'L3'    means that the inonosphere-free linear combination of phase data shall be used.</li> "
     1646                                          "<li>'no'    means that you don't want BNC to use GLONASS data.</li></ul></p><p><i>[key: PPP/lcGLONASS]</i></p>"));
     1647  _pppWidgets._lcGalileo->setWhatsThis(tr("<p>Specify which kind of Galileo observations you want to use and on which kind of linear combination the Galileo ambiguity resolutions shall be based:</p><p><ul>"
     1648                                          "<li>'Pi&Li' means that uncombined code and phase data of two frequencies shall be used.</li>"
     1649                                          "<li>'Pi'    means that uncombined code data of two frequencies shall be used.</li>"
     1650                                          "<li>'P1&L1' means that uncombined code and phase data of one frequency shall be used.</li>"
     1651                                          "<li>'P1'    means that uncombined code data of one frequency shall be used.</li>"
     1652                                          "<li>'P3&L3' means that the inonosphere-free linear combination of code and phase data shall be used.</li>"
     1653                                          "<li>'P3'    means that the inonosphere-free linear combination of code data shall be used.</li>"
     1654                                          "<li>'L3'    means that the inonosphere-free linear combination of phase data shall be used.</li> "
     1655                                          "<li>'no'    means that you don't want BNC to use Galileo data.</li></ul></p><p><i>[key: PPP/lcGalileo]</i></p>"));
     1656  _pppWidgets._lcBDS->setWhatsThis(tr("<p>Specify which kind of BDS observations you want to use and on which kind of linear combination the BDS ambiguity resolutions shall be based:</p><p><ul>"
     1657                                      "<li>'Pi&Li' means that uncombined code and phase data of two frequencies shall be used.</li>"
     1658                                      "<li>'Pi'    means that uncombined code data of two frequencies shall be used.</li>"
     1659                                      "<li>'P1&L1' means that uncombined code and phase data of one frequency shall be used.</li>"
     1660                                      "<li>'P1'    means that uncombined code data of one frequency shall be used.</li>"
     1661                                      "<li>'P3&L3' means that the inonosphere-free linear combination of code and phase data shall be used.</li>"
     1662                                      "<li>'P3'    means that the inonosphere-free linear combination of code data shall be used.</li>"
     1663                                      "<li>'L3'    means that the inonosphere-free linear combination of phase data shall be used.</li> "
     1664                                      "<li>'no'    means that you don't want BNC to use BDS data.</li></ul></p><p><i>[key: PPP/lcBDS]</i></p>"));
     1665  _pppWidgets._constraints->setWhatsThis(tr("<p>Specify, whether ionospheric constraints in form of pseudo-observations shall be added. Please note, this is only valid, if no ionosphere-free linear-combination is used and only helpful as soon as the ionosphere information is more accurate than the code data accuracy. <i>[key: PPP/constraints]</i></p>"));
     1666  _pppWidgets._sigmaC1->setWhatsThis(tr("<p>Enter a Sigma for GPS C1 code observations in meters.</p><p>The higher the sigma you enter, the less the contribution of GPS C1 code observations to a PPP solution from combined code and phase data. 1.0 is likely to be an appropriate choice.</p><p>Default is an empty option field, meaning<br>'Sigma C1 = 1.0' <i>[key: PPP/sigmaC1]</i></p>"));
     1667  _pppWidgets._sigmaL1->setWhatsThis(tr("<p>Enter a Sigma for GPS L1 phase observations in meters.</p><p>The higher the sigma you enter, the less the contribution of GPS L1 phase observations to a PPP solutions from combined code and phase data. 0.01 is likely to be an appropriate choice.</p><p>Default is an empty option field, meaning<br>'Sigma L1 = 0.01' <i>[key: PPP/sigmaL1]</i></p>"));
     1668  _pppWidgets._sigmaGIM->setWhatsThis(tr("<p>Enter a Sigma for GIM pseudo observations in meters.</p><p>The higher the sigma you enter, the less the contribution of GIM pseudo observations to a PPP solution. 5.0 is likely to be an appropriate choice.</p><p>Default is an empty option field, meaning<br>'Sigma GIM = 1.0' <i>[key: PPP/sigmaGIM]</i></p>"));
     1669  _pppWidgets._maxResC1->setWhatsThis(tr("<p>Specify a maximum for residuals from GPS C1 code observations in a PPP solution. '2.0' meters may be an appropriate choice for that.</p><p>If the maximum is exceeded, contributions from the corresponding observation will be ignored in the PPP solution.</p><p>Default is an empty option field, meaning<br>'Max Res C1 = 3.0' <i>[key: PPP/maxResC1]</i></p>"));
     1670  _pppWidgets._maxResL1->setWhatsThis(tr("<p>Specify a maximum for residuals from GPS L1 phase observations in a PPP solution. '0.02' meters may be an appropriate choice for that.</p><p>If the maximum is exceeded, contributions from the corresponding observation will be ignored in the PPP solution.</p><p>Default is an empty option field, meaning<br>'Max Res L1 = 0.03' <i>[key: PPP/maxResL1]</i></p>"));
     1671  _pppWidgets._maxResGIM->setWhatsThis(tr("<p>Specify a maximum for residuals from GIM pseudo observations in a PPP solution. '5.0' meters may be an appropriate choice for that.</p><p>If the maximum is exceeded, contributions from the corresponding observation will be ignored in the PPP solution.</p><p>Default is an empty option field, meaning<br>'Max Res GIM = 3.0' <i>[key: PPP/maxResGIM]</i></p>"));
     1672  _pppWidgets._eleWgtCode->setWhatsThis(tr("<p>Tic 'Ele Wgt Code' to use satellite Elevation depending Weights for Code observations in the PPP solution. <i>[key: PPP/eleWgtCode]</i></p>"));
     1673  _pppWidgets._eleWgtPhase->setWhatsThis(tr("<p>Tic 'Ele Wgt Phase' to use satellite Elevation depending Weights for Phase observations in the PPP solution. <i>[key: PPP/eleWgtPhase]</i></p>"));
     1674  _pppWidgets._minObs->setWhatsThis(tr("<p>Select a Minimum Number of Observations per epoch for a PPP solution.</p><p>BNC will only process epochs with observation numbers reaching or exceeding this minimum. <i>[key: PPP/minObs]</i></p>"));
     1675  _pppWidgets._minEle->setWhatsThis(tr("<p>Select a Minimum satellite Elevation for observations.</p><p>BNC will ignore an observation if the associated satellite Elevation does not reach or exceed this minimum.</p><p>Selecting '10 deg' may be an appropriate choice in order to avoid too noisy observations. <i>[key: PPP/minEle]</i></p>"));
     1676
     1677  // WhatsThis, Combine Corrections
     1678  // ------------------------------
     1679  _cmbTable->setWhatsThis(tr("<p>BNC allows to process several orbit and clock correction streams in real-time to produce, encode, upload and save a combination of correctors coming from different providers. </p><p>To add a line to the 'Combine Corrections' table hit the 'Add Row' button, double click on the 'Mountpoint' field to specify a Broadcast Ephemeris Correction mountpoint from the 'Streams' section below and hit Enter. Then double click on the 'AC Name' field to enter your choice of an abbreviation for the Analysis Center (AC) providing the stream. Double click on the 'Weight Factor' field to enter a weight factor to be applied for this stream in the combination. A Factor greater than 1 will enlarge the sigma of the clock pseudo-observations and with it down-weight its contribution. Finally, double click on the 'Exclude Satellites' field and specify satellites, to exclude them for an individual AC. An entry 'G04,G31,R' means to excludes GPS satellites PRN 4 and 31 as well as all GLONASS satellites from one individual AC. Default is an empty option field, meaning that no satellite is excluded from this individual AC.</p><p>Note that the orbit information in the resulting combination stream is just copied from one of the incoming streams. The stream used for providing the orbits may vary over time: if the orbit providing stream has an outage then BNC switches to the next remaining stream for getting hold of the orbit information.</p><p>The combination process requires Broadcast Ephemeris. Besides orbit and clock correction streams BNC should therefore pull a stream carrying Broadcast Ephemeris in the form of RTCM Version 3 messages.</p><p>It is possible to specify only one Broadcast Ephemeris Correction stream in the 'Combine Corrections' table. Instead of combining corrections BNC will then add the corrections to the Broadcast Ephemeris with the possibility to save final orbit and clock results in SP3 and/or Clock RINEX format. <i>[key: cmbStreams]</i></p>"));
     1680  addCmbRowButton->setWhatsThis(tr("<p>Hit 'Add Row' button to add another line to the 'Combine Corrections' table.</p>"));
     1681  delCmbRowButton->setWhatsThis(tr("<p>Hit 'Delete' button to delete the highlighted line(s) from the 'Combine Corrections' table.</p>"));
     1682  _cmbMethodComboBox->setWhatsThis(tr("<p>Select a clock combination approach. Options are 'Single-Epoch' and Kalman 'Filter'.</p><p>It is suggested to use the Kalman filter approach for the purpose of Precise Point Positioning. <i>[key: cmbMethod]</i></p>"));
     1683  _cmbMaxresLineEdit->setWhatsThis(tr("<p>BNC combines all incoming clocks according to specified weights. Individual clock estimates that differ by more than 'Maximal Clk Residuum' meters from the average of all clocks will be ignored.<p></p>It is suggested to specify a value of about 0.2 m for the Kalman filter combination approach and a value of about 3.0 meters for the Single-Epoch combination approach.</p><p>Default is a value of '999.0'. <i>[key: cmbMaxres]</i></p>"));
     1684  _cmbMaxdisplacementLineEdit->setWhatsThis(tr("<p>BNC builds mean values for all incoming orbit corrections per satellite. Individual orbit corrections that differ by more than 'Maximal Orb Displacement' meters from the average of all orbit corrections per satellite will be ignored.<p></p>It is suggested to specify a value of about 0.5 m.</p><p>Default is a value of '2.0'. <i>[key: cmbMaxdisplacement]</i></p>"));
     1685  _cmbSamplComboBox->setWhatsThis(tr("<p>Select a combination Sampling interval for the clocks. Clock corrections will be produced following that interval.</p><p>A value of 10 sec may be an appropriate choice. <i>[key: cmbSampl]</i></p>"));
     1686  _cmbLogPath->setWhatsThis(tr("<p>Specify a directory for saving daily Combination logfiles. If the specified directory does not exist, BNC will not create such files.</p><p>Default is an empty option field, meaning that no Combination logfiles shall be produced. <i>[key: cmbLogpath]</i></p>"));
     1687  _cmbGpsCheckBox->setWhatsThis(tr("<p>GPS clock corrections shall be combined. GPS Broadcast ephemeris and corrections are required. <i>[key: cmbGps]</i></p>"));
     1688  _cmbGloCheckBox->setWhatsThis(tr("<p>GLONASS clock corrections shall be combined; GLONASS Broadcast ephemeris and corrections are required. <i>[key: cmbGlo]</i></p>"));
     1689  _cmbGalCheckBox->setWhatsThis(tr("<p>Galileo clock corrections shall be combined; Galileo Broadcast ephemeris and corrections are required. <i>[key: cmbGal]</i></p>"));
     1690  _cmbBdsCheckBox->setWhatsThis(tr("<p>Beidou clock corrections shall be combined; BDS Broadcast ephemeris and corrections are required. <i>[key: cmbBds]</i></p>"));
     1691  _cmbQzssCheckBox->setWhatsThis(tr("<p>QZSS clock corrections shall be combined; QZSS Broadcast ephemeris and corrections are required. <i>[key: cmbQzss]</i></p>"));
     1692  _cmbSbasCheckBox->setWhatsThis(tr("<p>SBAS clock corrections shall be combined; SBAS Broadcast ephemeris and corrections are required. <i>[key: cmbSbas]</i></p>"));
     1693  _cmbNavicCheckBox->setWhatsThis(tr("<p>NavIC clock corrections shall be combined; NavIC Broadcast ephemeris and corrections are required. <i>[key: cmbNavic]</i></p>"));
     1694  _cmbBsxFile->setWhatsThis(tr("<p> Specify a Bias SINEX File that will be used to add satellite code biases to the combined clocks. <i>[key: cmbBsxFile]</i></p>"));
     1695
     1696  // WhatsThis, Upload Corrections
     1697  // -----------------------------
     1698  _uploadTable->setWhatsThis(tr("<p>BNC can upload clock and orbit corrections to Broadcast Ephemeris (Broadcast Corrections) as well as Code Biases in different SSR formats. You may have a situation where clocks, orbits and code biases come from an external Real-time Network Engine (1) or a situation where clock and orbit corrections are combined within BNC (2).</p><p>(1) BNC identifies a stream as coming from a Real-time Network Engine if its format is specified as 'RTNET' and hence its decoder string in the 'Streams' canvas is 'RTNET'. It encodes and uploads that stream to the specified Ntrip Broadcaster Host and Port</p><p>(2) BNC understands that it is expected to encode and upload combined Broadcast Ephemeris Corrections if you specify correction streams in the 'Combine Corrections' table.</p><p>To fill the 'Upload Corrections' table, hit the 'Add Row' button, double click on the 'Host' field to enter the IP or URL of an Ntrip Broadcaster and hit Enter. Select the Ntrip Version that shall be used for data upload. Then double click on the 'Port', 'Mountpoint' and 'Password' fields to enter the Ntrip Broadcaster IP port, the mountpoint and the stream upload password. If Ntrip Version 2 is chosen, click to the 'User' field to enter a stream upload user name. An empty 'Host' option field means that you don't want to upload corrections.</p><p>Select a target coordinate reference System (e.g. IGS20) for outgoing clock and orbit corrections.</p><p>Select a target SSR format (e.g. IGS-SSR) for outgoing clock and orbit corrections.</p><p>By default orbit and clock corrections refer to Antenna Phase Center (APC). Tick 'CoM' to refer uploaded corrections to Center of Mass instead of APC.</p><p>Specify a path for saving generated Broadcast Corrections plus Broadcast Ephemeris as SP3 orbit files. If the specified directory does not exist, BNC will not create such files. The following is a path example for a Linux system: /home/user/BKG0MGXRTS${V3PROD}.SP3.</p><p>Specify a path for saving generated Broadcast Correction clocks plus Broadcast Ephemeris clocks as Clock RINEX files. If the specified directory does not exist, BNC will not create Clock RINEX files. The following is a path example for a Linux system: /home/user/BKG0MGXRTS${V3PROD}.CLK.</p><p>Specify a path for saving generated Code Biases as SINEX Bias files. If the specified directory does not exist, BNC will not create SINEX Bias files. The following is a path example for a Linux system: /home/user/BKG0MGXRTS${V3PROD}.BIA.</p><p>Note that '${V3PROD}' produces the time stamp in the filename, which is related to the RINEX version 3 filename concept.</p><p>Finally, specify a SSR Provider ID (issued by RTCM), SSR Solution ID, and SSR Issue of Data number.</p><p>In case the 'Combine Corrections' table contains only one Broadcast Correction stream, BNC will add that stream content to the Broadcast Ephemeris to save results in files specified via SP3 and/or Clock RINEX file path. You should then define only the SP3 and Clock RINEX file path and no further option in the 'Upload Corrections' table. <i>[key: uploadMountpointsOut]</i></p>"));
     1699  addUploadRowButton->setWhatsThis(tr("<p>Hit 'Add Row' button to add another line to the 'Upload Corrections' table.</p>"));
     1700  delUploadRowButton->setWhatsThis(tr("<p>Hit 'Del Row' button to delete the highlighted line(s) from the 'Upload Corrections' table.</p>"));
     1701  _uploadIntrComboBox->setWhatsThis(tr("<p>Select the length of the SP3, Clock RINEX and Bias SINEX files. <i>[key: uploadIntr]</i></p>"));
     1702  _uploadSamplRtcmEphCorrComboBox->setWhatsThis(tr("<p>Select a stream's orbit correction sampling interval in seconds.</p><p>A value of zero '0' tells BNC to upload all available orbit and clock correction samples together in combined messages. <i>[key: uploadSamplRtcmEphCorr]</i></p>"));
     1703  _uploadSamplSp3ComboBox->setWhatsThis(tr("<p>Select a SP3 orbit file sampling interval in seconds.</p><p>A value of zero '0' tells BNC to store all available samples into SP3 orbit files. <i>[key: uploadSamplSp3]</i></p>"));
     1704  _uploadSamplClkRnxSpinBox->setWhatsThis(tr("<p>Select a Clock RINEX file sampling interval in seconds.</p><p>A value of zero '0' tells BNC to store all available samples into Clock RINEX files. <i>[key: uploadSamplClkRnx]</i></p>"));
     1705  _uploadSamplBiaSnxSpinBox->setWhatsThis(tr("<p>Select a Bias SINEX file sampling interval in seconds.</p><p>A value of zero '0' tells BNC to store all available samples into Bias SINEX files. <i>[key: uploadSamplBiaSnx]</i></p>"));
     1706  setUploadTrafoButton->setWhatsThis(tr("<p>Hit 'Custom Trafo' to specify your own 14 parameter Helmert Transformation instead of selecting a predefined transformation via option 'System'.</p>"));
     1707  _uploadAntexFile->setWhatsThis(tr("<p>When producing SP3 files or referring orbit and clock corrections to the satellite's Center of Mass (CoM) instead Antenna Phase Center (APC), an offset has to be applied which is available from the IGS 'ANTEX file'. You must therefore specify an 'ANTEX file' path if you want to save the stream content in SP3 format and/or refer correctors to CoM.</p><p>If you don't specify an 'ANTEX file' path, the SP3 file content as well as the orbit and clock correctors will be referred to satellite APCs. <i>[key: uploadAntexFile]</i></p>"));
     1708
     1709  // WhatsThis, Upload Ephemeris
     1710  // ---------------------------
     1711  _uploadEphTable->setWhatsThis(tr("<p>BNC can upload Broadcast Ephemeris streams in RTCM Version 3 format. </p><p>To fill the 'Upload Ephemeris' table, hit the 'Add Row' button, double click on the 'Host' field to enter the IP or URL of an Ntrip Broadcaster and hit Enter. Select the Ntrip Version that shall be used for data upload. Then double click on the 'Port', 'Mountpoint' and 'Password' fields to enter the Ntrip Broadcaster IP port, the mountpoint and the stream upload password. If Ntrip Version 2 is chosen, click to the 'User' field to enter a stream upload user name. Specify the satellite system(s) that shall be part of the uploaded stream (e.g. G for GPS or GRE for GPS+GLONASS+Galileo, or ALL). <i>[key: uploadEphMountpointsOut]</i></p>"));
     1712  addUploadEphRowButton->setWhatsThis(tr("<p>Hit 'Add Row' button to add another line to the 'Upload Ephemeris' table.</p>"));
     1713  delUploadEphRowButton->setWhatsThis(tr("<p>Hit 'Del Row' button to delete the highlighted line(s) from the 'Upload Ephemeris' table.</p>"));
     1714  _uploadSamplRtcmEphSpinBox->setWhatsThis(tr("<p>Select the Broadcast Ephemeris sampling interval in seconds.</p><p>Default is '5', meaning that a complete set of Broadcast Ephemeris is uploaded every 5 seconds. <i>[key: uploadSamplRtcmEph]</i></p>"));
     1715
     1716  // WhatsThis, Upload Raw Data
     1717  // ---------------------------
     1718  _uploadRawTable->setWhatsThis(tr("<p>BNC can upload Raw Data streams in any format like a NtripServer. </p><p>To fill the 'Upload Raw Data' table, hit the 'Add Row' button and double click on the 'Source Mountpoint' field to enter the Source of data from the 'Streams' section below, which shall be forwarded without decoding and hit Enter. Double click on the 'Host' field to enter the IP or URL of an Ntrip Broadcaster and hit Enter. Select the Ntrip Version that shall be used for data upload. Then double click on the 'Port', 'Upload Mountpoint' and 'Password' fields to enter the Ntrip Broadcaster IP port, the stream upload mountpoint and password. If Ntrip Version 2 is chosen, click to the 'User' field to enter a stream upload user name. </p><p> If the decoder string is not an accepted one ('RTCM_2.x', 'RTCM_3.x' and 'RTNET'), please change the decoder string to <ul>"
     1719                                   "<li> 'ZERO' (forward the raw data) or </li>"
     1720                                   "<li> 'ZERO2FILE' (forward and store the raw data)</li> </ul> in addition <i>[key: uploadRawMountpointsOut]</i></p>"));
     1721  addUploadEphRowButton->setWhatsThis(tr("<p>Hit 'Add Row' button to add another line to the 'Upload Raw Data' table.</p>"));
     1722  delUploadEphRowButton->setWhatsThis(tr("<p>Hit 'Del Row' button to delete the highlighted line(s) from the 'Upload Raw Data' table.</p>"));
     1723
     1724
     1725  // WhatsThis, Streams Canvas
     1726  // -------------------------
     1727  _mountPointsTable->setWhatsThis(tr("<p>Streams selected for retrieval are listed in the 'Streams' section. "
     1728                                     "Clicking on 'Add Stream' button opens a window that allows the user to select data streams from an Ntrip Broadcaster "
     1729                                     "according to their mountpoints. To remove a stream from the 'Streams' list, highlight it by clicking on it "
     1730                                     "and hit the 'Delete Stream' button. You can also remove multiple streams by highlighting them using +Shift and +Ctrl.</p><p>"
     1731                                     "BNC automatically allocates one of its internal decoders to a stream based on the stream's 'format' as given in the source-table. "
     1732                                     "BNC allows users to change this selection by editing the decoder string. "
     1733                                     "Double click on the 'decoder' field, enter your preferred decoder and then hit Enter. "
     1734                                     "Accepted decoder strings are 'RTCM_2.x', 'RTCM_3.x' and 'RTNET'.</p><p>"
     1735                                     "In case you need to log raw data as is, BNC allows to by-pass its decoders and directly save the input in daily log files. "
     1736                                     "To do this, specify the decoder string as 'ZERO2FILE'.</p><p>"
     1737                                     "BNC allows as well to forward streams related to the specified 'Mountpoint' on top of the 'Miscellaneous Panel' "
     1738                                     "through a TCP/IP port of your local host. "
     1739                                     "In this case, the stream content remains untouched; BNC does not decode or reformat the data for this output. "
     1740                                     "If the decoder string is not an accepted one, please change the decoder string to 'ZERO' (forward the raw data only) or 'ZERO2FILE' (forward and store the raw data) in addition.</p><p>"
     1741                                     "BNC can also retrieve streams from virtual reference stations (VRS). VRS streams are indicated by a 'yes' in the 'nmea' column. "
     1742                                     "To initiate such stream, the approximate latitude/longitude rover position is sent to the Ntrip Broadcaster "
     1743                                     "together with an approximation for the height. Default values for latitude and longitude can be change according to your requirement. "
     1744                                     "Double click on 'lat' and 'long' fields, enter the values you wish to send and then hit Enter. <i>[key: mountPoints]</i></p>"));
     1745  _actAddMountPoints->setWhatsThis(tr("<p>Add stream(s) to selection presented in the 'Streams' canvas.</p>"));
     1746  _actDeleteMountPoints->setWhatsThis(tr("<p>Delete stream(s) from selection presented in the 'Streams' canvas.</p>"));
     1747  _actMapMountPoints->setWhatsThis(tr("<p> Draw distribution map of stream selection presented in the 'Streams' canvas. Use mouse to zoom in or out.</p><p>Left button: Draw rectangle to zoom in.<br>Right button: Zoom out.<br>Middle button: Zoom back.</p>"));
     1748  _actStart->setWhatsThis(tr("<p> Start running BNC.</p>"));
     1749  _actStop->setWhatsThis(tr("<p> Stop running BNC.</p>"));
     1750
     1751  // WhatsThis, Log Canvas
     1752  // ---------------------
     1753  _log->setWhatsThis(tr("<p>Records of BNC's activities are shown in the 'Log' tab. The message log covers the communication status between BNC and the Ntrip Broadcaster as well as problems that occur in the communication link, stream availability, stream delay, stream conversion etc.</p>"));
     1754  _bncFigure->setWhatsThis(tr("<p>The bandwith consumption per stream is shown in the 'Throughput' tab in bits per second (bps) or kilobits per second (kbps).</p>"));
     1755  _bncFigureLate->setWhatsThis(tr("<p>The individual latency of observations of incoming streams is shown in the 'Latency' tab. Streams not carrying observations (e.g. those providing only Broadcast Ephemeris) remain unconsidered.</p><p>Note that the calculation of correct latencies requires the clock of the host computer to be properly synchronized.</p>"));
     1756  _bncFigurePPP->setWhatsThis(tr("<p>PPP time series of North (red), East (green) and Up (blue) displacements are shown in the 'PPP Plot' tab when the corresponding option is selected.</p><p>Values are referred to an XYZ a priori coordinate. The sliding PPP time series window covers the period of the latest 5 minutes.</p>"));
     1757
     1758
     1759  // Enable/Disable all Widgets
     1760  // --------------------------
     1761  slotBncTextChanged();
     1762  enableStartStop();
     1763
     1764  // Auto start
     1765  // ----------
     1766  if (Qt::CheckState(settings.value("autoStart").toInt()) == Qt::Checked) {
     1767    slotStart();
     1768  }
     1769}
     1770
     1771// Destructor
     1772////////////////////////////////////////////////////////////////////////////
     1773bncWindow::~bncWindow() {
     1774  if (_caster) {
     1775    delete _caster; BNC_CORE->setCaster(0);
     1776  }
     1777  if (_casterEph) {
     1778    delete _casterEph;
     1779  }
     1780  delete _bncFigureLate;
     1781  delete _bncFigurePPP;
     1782  delete _actHelp;
     1783  delete _actAbout;
     1784  delete _actFlowchart;
     1785  delete _actFontSel;
     1786  delete _actSaveOpt;
     1787  delete _actQuit;
     1788  delete _actAddMountPoints;
     1789  delete _actDeleteMountPoints;
     1790  delete _actMapMountPoints;
     1791  delete _actStart;
     1792  delete _actStop;
     1793  delete _actwhatsthis;
     1794  delete _proxyHostLineEdit;
     1795  delete _proxyPortLineEdit;
     1796  delete _sslCaCertPathLineEdit;
     1797  delete _sslClientCertPathLineEdit;
     1798  delete _sslIgnoreErrorsCheckBox;
     1799  delete _logFileLineEdit;
     1800  delete _rawOutFileLineEdit;
     1801  delete _rnxAppendCheckBox;
     1802  delete _onTheFlyComboBox;
     1803  delete _autoStartCheckBox;
     1804  delete _rnxPathLineEdit;
     1805  delete _rnxIntrComboBox;
     1806  delete _rnxSamplComboBox;
     1807  delete _rnxSkelExtComboBox;
     1808  delete _rnxSkelPathLineEdit;
     1809  delete _rnxFileCheckBox;
     1810  delete _rnxScrpLineEdit;
     1811  delete _rnxVersComboBox;
     1812  delete _rnxV2Priority;
     1813  delete _ephPathLineEdit;
     1814  //delete _ephFilePerStation;
     1815  delete _ephIntrComboBox;
     1816  delete _ephOutPortLineEdit;
     1817  delete _ephVersComboBox;
     1818  delete _corrPathLineEdit;
     1819  delete _corrIntrComboBox;
     1820  delete _corrPortLineEdit;
     1821  delete _outPortLineEdit;
     1822  delete _outWaitSpinBox;
     1823  delete _outSamplComboBox;
     1824  delete _outFileLineEdit;
     1825  delete _outUPortLineEdit;
     1826  delete _outLockTimeCheckBox;
     1827  delete _serialMountPointLineEdit;
     1828  delete _serialPortNameLineEdit;
     1829  delete _serialBaudRateComboBox;
     1830  delete _serialFlowControlComboBox;
     1831  delete _serialDataBitsComboBox;
     1832  delete _serialParityComboBox;
     1833  delete _serialStopBitsComboBox;
     1834  delete _serialAutoNMEAComboBox;
     1835  delete _serialFileNMEALineEdit;
     1836  delete _serialHeightNMEALineEdit;
     1837  delete _serialNMEASamplingSpinBox;
     1838  delete _adviseObsRateComboBox;
     1839  delete _adviseFailSpinBox;
     1840  delete _adviseRecoSpinBox;
     1841  delete _adviseScriptLineEdit;
     1842  delete _miscMountLineEdit;
     1843  delete _miscPortLineEdit;
     1844  delete _miscIntrComboBox;
     1845  delete _miscScanRTCMCheckBox;
     1846  _mountPointsTable->deleteLater();
     1847  delete _log;
     1848  delete _loggroup;
     1849  _cmbTable->deleteLater();
     1850  delete _cmbMaxresLineEdit;
     1851  delete _cmbMaxdisplacementLineEdit;
     1852  delete _cmbSamplComboBox;
     1853  delete _cmbLogPath;
     1854  delete _cmbMethodComboBox;
     1855  delete _cmbGpsCheckBox;
     1856  delete _cmbGloCheckBox;
     1857  delete _cmbGalCheckBox;
     1858  delete _cmbBdsCheckBox;
     1859  delete _cmbQzssCheckBox;
     1860  delete _cmbSbasCheckBox;
     1861  delete _cmbNavicCheckBox;
     1862  delete _cmbBsxFile;
     1863  delete _uploadSamplRtcmEphCorrComboBox;
     1864  _uploadEphTable->deleteLater();
     1865  _uploadRawTable->deleteLater();
     1866  _uploadTable->deleteLater();
     1867  delete _uploadIntrComboBox;
     1868  delete _uploadAntexFile;
     1869  delete _uploadSamplRtcmEphSpinBox;
     1870  delete _uploadSamplSp3ComboBox;
     1871  delete _uploadSamplClkRnxSpinBox;
     1872  delete _uploadSamplBiaSnxSpinBox;
     1873  delete _reqcActionComboBox;
     1874  delete _reqcObsFileChooser;
     1875  delete _reqcNavFileChooser;
     1876  delete _reqcOutObsLineEdit;
     1877  delete _reqcOutNavLineEdit;
     1878  delete _reqcOutLogLineEdit;
     1879  delete _reqcPlotDirLineEdit;
     1880  delete _reqcSkyPlotSignals;
     1881  delete _reqcLogSummaryOnly;
     1882  delete _reqcEditOptionButton;
     1883  delete _sp3CompFileChooser;
     1884  delete _sp3CompExclude;
     1885  delete _sp3CompLogLineEdit;
     1886  delete _sp3CompSummaryOnly;
     1887  //delete _canvas;
     1888}
     1889
     1890//
     1891////////////////////////////////////////////////////////////////////////////
     1892void bncWindow::populateMountPointsTable() {
     1893
     1894  for (int iRow = _mountPointsTable->rowCount() - 1; iRow >= 0; iRow--) {
     1895    _mountPointsTable->removeRow(iRow);
     1896  }
     1897
     1898  bncSettings settings;
     1899
     1900  QListIterator<QString> it(settings.value("mountPoints").toStringList());
     1901  int iRow = 0;
     1902  while (it.hasNext()) {
     1903    QStringList hlp = it.next().split(" ");
     1904    if (hlp.size() < 7) continue;
     1905    _mountPointsTable->insertRow(iRow);
     1906
     1907    QUrl    url(hlp[0]);
     1908
     1909    QString format(hlp[1]);
     1910    QString country(hlp[2]);
     1911    QString latitude(hlp[3]);
     1912    QString longitude(hlp[4]);
     1913    QString nmea(hlp[5]);
     1914    QString ntripVersion(hlp[6]);
     1915
     1916    QString fullPath;
     1917    if (ntripVersion == 'S') {
     1918      // url.userInfo() contains the case sensitive portName
     1919      // the portName shall be part of the mountpointString
     1920      // to inform the user about the source of the stream
     1921      if (url.host().contains(url.userInfo().toLower())) {
     1922        fullPath = url.host() + url.path();
     1923      }
     1924      else {
     1925        fullPath =  url.userInfo() + "-" + url.host() + url.path();
     1926      }
     1927    } else {
     1928      fullPath = url.host() + QString(":%1").arg(url.port()) + url.path();
     1929    }
     1930
     1931    QTableWidgetItem* it;
     1932    it = new QTableWidgetItem(url.userInfo());
     1933    it->setFlags(it->flags() & ~Qt::ItemIsEditable);
     1934    _mountPointsTable->setItem(iRow, 0, it);
     1935
     1936    it = new QTableWidgetItem(fullPath);
     1937    it->setFlags(it->flags() & ~Qt::ItemIsEditable);
     1938    _mountPointsTable->setItem(iRow, 1, it);
     1939
     1940    it = new QTableWidgetItem(format);
     1941    _mountPointsTable->setItem(iRow, 2, it);
     1942
     1943    it = new QTableWidgetItem(country);
     1944    _mountPointsTable->setItem(iRow, 3, it);
     1945
     1946    if (nmea == "yes") {
     1947      it = new QTableWidgetItem(latitude);
     1948      _mountPointsTable->setItem(iRow, 4, it);
     1949      it = new QTableWidgetItem(longitude);
     1950      _mountPointsTable->setItem(iRow, 5, it);
    5261951    }
    5271952    else {
    528         enableWidget(false, _cmbMethodComboBox);
    529         enableWidget(false, _cmbMaxresLineEdit);
    530         enableWidget(false, _cmbMaxdisplacementLineEdit);
    531         enableWidget(false, _cmbSamplComboBox);
    532         enableWidget(false, _cmbLogPath);
    533     }
    534     _cmbGpsCheckBox = new QCheckBox();
    535     _cmbGpsCheckBox->setCheckState(Qt::CheckState(settings.value("cmbGps").toInt()));
    536     _cmbGloCheckBox = new QCheckBox();
    537     _cmbGloCheckBox->setCheckState(Qt::CheckState(settings.value("cmbGlo").toInt()));
    538     _cmbGalCheckBox = new QCheckBox();
    539     _cmbGalCheckBox->setCheckState(Qt::CheckState(settings.value("cmbGal").toInt()));
    540     _cmbBdsCheckBox = new QCheckBox();
    541     _cmbBdsCheckBox->setCheckState(Qt::CheckState(settings.value("cmbBds").toInt()));
    542     _cmbQzssCheckBox = new QCheckBox();
    543     _cmbQzssCheckBox->setCheckState(Qt::CheckState(settings.value("cmbQzss").toInt()));
    544     _cmbSbasCheckBox = new QCheckBox();
    545     _cmbSbasCheckBox->setCheckState(Qt::CheckState(settings.value("cmbSbas").toInt()));
    546     _cmbNavicCheckBox = new QCheckBox();
    547     _cmbNavicCheckBox->setCheckState(Qt::CheckState(settings.value("cmbNavic").toInt()));
    548 
    549     connect(_cmbGpsCheckBox, SIGNAL(stateChanged(int)), this, SLOT(slotBncTextChanged()));
    550     connect(_cmbGloCheckBox, SIGNAL(stateChanged(int)), this, SLOT(slotBncTextChanged()));
    551     connect(_cmbGalCheckBox, SIGNAL(stateChanged(int)), this, SLOT(slotBncTextChanged()));
    552     connect(_cmbBdsCheckBox, SIGNAL(stateChanged(int)), this, SLOT(slotBncTextChanged()));
    553     connect(_cmbQzssCheckBox, SIGNAL(stateChanged(int)), this, SLOT(slotBncTextChanged()));
    554     connect(_cmbSbasCheckBox, SIGNAL(stateChanged(int)), this, SLOT(slotBncTextChanged()));
    555     connect(_cmbNavicCheckBox, SIGNAL(stateChanged(int)), this, SLOT(slotBncTextChanged()));
    556 
    557     _cmbBsxFile = new qtFileChooser(0, qtFileChooser::File);
    558     _cmbBsxFile->setFileName(settings.value("cmbBsxFile").toString());
    559 
    560     // Upload Results
    561     // -------------
    562     _uploadTable = new QTableWidget(0, 16);
    563     _uploadTable->setHorizontalHeaderLabels(QString("Host, Port, Mountpoint, Ntrip, User, Password, System, Format, CoM, SP3 File, RNX File, BSX File, PID, SID, IOD, Bytes").split(","));
    564     _uploadTable->setSelectionMode(QAbstractItemView::ExtendedSelection);
    565     _uploadTable->setSelectionBehavior(QAbstractItemView::SelectRows);
    566     _uploadTable->horizontalHeader()->resizeSection(0, 13 * ww);
    567     _uploadTable->horizontalHeader()->resizeSection(1, 5 * ww);
    568     _uploadTable->horizontalHeader()->resizeSection(2, 10 * ww);
    569     _uploadTable->horizontalHeader()->resizeSection(3, 6 * ww);
    570     _uploadTable->horizontalHeader()->resizeSection(4, 8 * ww);
    571     _uploadTable->horizontalHeader()->resizeSection(5, 8 * ww);
    572     _uploadTable->horizontalHeader()->resizeSection(6, 11 * ww);
    573     _uploadTable->horizontalHeader()->resizeSection(7, 11 * ww);
    574     _uploadTable->horizontalHeader()->resizeSection(8, 4 * ww);
    575     _uploadTable->horizontalHeader()->resizeSection(9, 15 * ww);
    576     _uploadTable->horizontalHeader()->resizeSection(10, 15 * ww);
    577     _uploadTable->horizontalHeader()->resizeSection(11, 15 * ww);
    578     _uploadTable->horizontalHeader()->resizeSection(12, 4 * ww);
    579     _uploadTable->horizontalHeader()->resizeSection(13, 4 * ww);
    580     _uploadTable->horizontalHeader()->resizeSection(14, 4 * ww);
    581     _uploadTable->horizontalHeader()->resizeSection(15, 12 * ww);
    582 #if QT_VERSION < 0x050000
    583     _uploadTable->horizontalHeader()->setResizeMode(QHeaderView::Interactive);
    584 #else
    585     _uploadTable->horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive);
    586 #endif
    587     _uploadTable->horizontalHeader()->setStretchLastSection(true);
    588     _uploadTable->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft);
    589 
    590     connect(_uploadTable, SIGNAL(itemSelectionChanged()),
    591         SLOT(slotBncTextChanged()));
    592 
    593     QPushButton* addUploadRowButton = new QPushButton("Add Row");
    594     QPushButton* delUploadRowButton = new QPushButton("Del Row");
    595     QPushButton* setUploadTrafoButton = new QPushButton("Custom Trafo");
    596     _uploadIntrComboBox = new QComboBox;
    597     _uploadIntrComboBox->setEditable(false);
    598     _uploadIntrComboBox->addItems(QString("1 day,1 hour, 30 min,15 min,10 min,5 min,2 min,1 min").split(","));
    599     ii = _uploadIntrComboBox->findText(settings.value("uploadIntr").toString());
    600     if (ii != -1) {
    601         _uploadIntrComboBox->setCurrentIndex(ii);
    602     }
    603 
    604     _uploadAntexFile = new qtFileChooser(0, qtFileChooser::File);
    605     _uploadAntexFile->setFileName(settings.value("uploadAntexFile").toString());
    606 
    607     _uploadSamplRtcmEphCorrComboBox = new QComboBox();
    608     _uploadSamplRtcmEphCorrComboBox->setEditable(false);
    609     _uploadSamplRtcmEphCorrComboBox->addItems(QString("0 sec,1 sec,2 sec,5 sec,10 sec,15 sec,30 sec,60 sec").split(","));
    610     int pp = _uploadSamplRtcmEphCorrComboBox->findText(settings.value("uploadSamplRtcmEphCorr").toString());
    611     if (pp != -1) {
    612         _uploadSamplRtcmEphCorrComboBox->setCurrentIndex(pp);
    613     }
    614 
    615     _uploadSamplSp3ComboBox = new QComboBox();
    616     _uploadSamplSp3ComboBox->setEditable(false);
    617     _uploadSamplSp3ComboBox->addItems(QString("0 sec,30 sec,60 sec,300 sec,900 sec").split(","));
    618     int oo = _uploadSamplSp3ComboBox->findText(settings.value("uploadSamplSp3").toString());
    619     if (oo != -1) {
    620         _uploadSamplSp3ComboBox->setCurrentIndex(oo);
    621     }
    622 
    623     _uploadSamplClkRnxSpinBox = new QSpinBox;
    624     _uploadSamplClkRnxSpinBox->setMinimum(0);
    625     _uploadSamplClkRnxSpinBox->setMaximum(60);
    626     _uploadSamplClkRnxSpinBox->setSingleStep(5);
    627     _uploadSamplClkRnxSpinBox->setMaximumWidth(9 * ww);
    628     _uploadSamplClkRnxSpinBox->setValue(settings.value("uploadSamplClkRnx").toInt());
    629     _uploadSamplClkRnxSpinBox->setSuffix(" sec");
    630 
    631     _uploadSamplBiaSnxSpinBox = new QSpinBox;
    632     _uploadSamplBiaSnxSpinBox->setMinimum(0);
    633     _uploadSamplBiaSnxSpinBox->setMaximum(60);
    634     _uploadSamplBiaSnxSpinBox->setSingleStep(5);
    635     _uploadSamplBiaSnxSpinBox->setMaximumWidth(9 * ww);
    636     _uploadSamplBiaSnxSpinBox->setValue(settings.value("uploadSamplBiaSnx").toInt());
    637     _uploadSamplBiaSnxSpinBox->setSuffix(" sec");
    638 
    639     int iRowT = _uploadTable->rowCount();
    640     if (iRowT > 0) {
    641         enableWidget(true, _uploadIntrComboBox);
    642         enableWidget(true, _uploadSamplRtcmEphCorrComboBox);
    643         enableWidget(true, _uploadSamplSp3ComboBox);
    644         enableWidget(true, _uploadSamplClkRnxSpinBox);
    645         enableWidget(true, _uploadSamplBiaSnxSpinBox);
    646         enableWidget(true, _uploadAntexFile);
     1953      it = new QTableWidgetItem(latitude);
     1954      it->setFlags(it->flags() & ~Qt::ItemIsEditable);
     1955      _mountPointsTable->setItem(iRow, 4, it);
     1956
     1957      it = new QTableWidgetItem(longitude);
     1958      it->setFlags(it->flags() & ~Qt::ItemIsEditable);
     1959      _mountPointsTable->setItem(iRow, 5, it);
     1960    }
     1961
     1962    it = new QTableWidgetItem(nmea);
     1963    it->setFlags(it->flags() & ~Qt::ItemIsEditable);
     1964    _mountPointsTable->setItem(iRow, 6, it);
     1965
     1966    it = new QTableWidgetItem(ntripVersion);
     1967    ////    it->setFlags(it->flags() & ~Qt::ItemIsEditable);
     1968    _mountPointsTable->setItem(iRow, 7, it);
     1969
     1970    bncTableItem* bncIt = new bncTableItem();
     1971    bncIt->setFlags(bncIt->flags() & ~Qt::ItemIsEditable);
     1972    _mountPointsTable->setItem(iRow, 8, bncIt);
     1973
     1974    iRow++;
     1975  }
     1976
     1977  _mountPointsTable->sortItems(1);
     1978
     1979  enableStartStop();
     1980}
     1981
     1982// Retrieve Table
     1983////////////////////////////////////////////////////////////////////////////
     1984void bncWindow::slotAddMountPoints() {
     1985
     1986  bncSettings settings;
     1987  QString proxyHost = settings.value("proxyHost").toString();
     1988  int     proxyPort = settings.value("proxyPort").toInt();
     1989  if (proxyHost != _proxyHostLineEdit->text() ||
     1990      proxyPort != _proxyPortLineEdit->text().toInt()) {
     1991    int iRet = QMessageBox::question(this, "Question", "Proxy options "
     1992                                     "changed. Use the new ones?",
     1993                                     QMessageBox::Yes, QMessageBox::No,
     1994                                     QMessageBox::NoButton);
     1995    if (iRet == QMessageBox::Yes) {
     1996      settings.setValue("proxyHost", _proxyHostLineEdit->text());
     1997      settings.setValue("proxyPort", _proxyPortLineEdit->text());
     1998    }
     1999  }
     2000
     2001  settings.setValue("sslCaCertPath", _sslCaCertPathLineEdit->text());
     2002  settings.setValue("sslClientCertPath", _sslClientCertPathLineEdit->text());
     2003  settings.setValue("sslIgnoreErrors", _sslIgnoreErrorsCheckBox->checkState());
     2004
     2005  QMessageBox msgBox;
     2006  msgBox.setIcon(QMessageBox::Question);
     2007  msgBox.setWindowTitle("Add Stream");
     2008  msgBox.setText("Add stream(s) coming from:");
     2009
     2010  QPushButton* buttonNtrip = msgBox.addButton(tr("Caster"), QMessageBox::ActionRole);
     2011  QPushButton* buttonIP = msgBox.addButton(tr("TCP/IP port"), QMessageBox::ActionRole);
     2012  QPushButton* buttonUDP = msgBox.addButton(tr("UDP port"), QMessageBox::ActionRole);
     2013  QPushButton* buttonSerial = msgBox.addButton(tr("Serial port"), QMessageBox::ActionRole);
     2014  QPushButton* buttonCancel = msgBox.addButton(tr("Cancel"), QMessageBox::ActionRole);
     2015
     2016  msgBox.exec();
     2017
     2018  if (msgBox.clickedButton() == buttonNtrip) {
     2019    bncTableDlg* dlg = new bncTableDlg(this);
     2020    dlg->move(this->pos().x() + 50, this->pos().y() + 50);
     2021    connect(dlg, SIGNAL(newMountPoints(QStringList*)),
     2022            this, SLOT(slotNewMountPoints(QStringList*)));
     2023    dlg->exec();
     2024    delete dlg;
     2025  }
     2026  else if (msgBox.clickedButton() == buttonIP) {
     2027    bncIpPort* ipp = new bncIpPort(this);
     2028    connect(ipp, SIGNAL(newMountPoints(QStringList*)),
     2029            this, SLOT(slotNewMountPoints(QStringList*)));
     2030    ipp->exec();
     2031    delete ipp;
     2032  }
     2033  else if (msgBox.clickedButton() == buttonUDP) {
     2034    bncUdpPort* udp = new bncUdpPort(this);
     2035    connect(udp, SIGNAL(newMountPoints(QStringList*)),
     2036            this, SLOT(slotNewMountPoints(QStringList*)));
     2037    udp->exec();
     2038    delete udp;
     2039  }
     2040  else if (msgBox.clickedButton() == buttonSerial) {
     2041    bncSerialPort* sep = new bncSerialPort(this);
     2042    connect(sep, SIGNAL(newMountPoints(QStringList*)),
     2043            this, SLOT(slotNewMountPoints(QStringList*)));
     2044    sep->exec();
     2045    delete sep;
     2046  }
     2047  else if (msgBox.clickedButton() == buttonCancel) {
     2048    // Cancel
     2049  }
     2050
     2051  enableStartStop();
     2052}
     2053
     2054// Delete Selected Mount Points
     2055////////////////////////////////////////////////////////////////////////////
     2056void bncWindow::slotDeleteMountPoints() {
     2057
     2058  int nRows = _mountPointsTable->rowCount();
     2059  std::vector <bool> flg(nRows);
     2060  for (int iRow = 0; iRow < nRows; iRow++) {
     2061    if (_mountPointsTable->item(iRow, 1)->isSelected()) {
     2062      flg[iRow] = true;
    6472063    }
    6482064    else {
    649         enableWidget(false, _uploadIntrComboBox);
    650         enableWidget(false, _uploadSamplRtcmEphCorrComboBox);
    651         enableWidget(false, _uploadSamplSp3ComboBox);
    652         enableWidget(false, _uploadSamplClkRnxSpinBox);
    653         enableWidget(true, _uploadSamplBiaSnxSpinBox);
    654         enableWidget(false, _uploadAntexFile);
    655     }
    656 
    657     // Upload RTCM3 Ephemeris
    658     // ----------------------
    659     _uploadEphTable = new QTableWidget(0, 7);
    660     _uploadEphTable->setColumnCount(8);
    661     _uploadEphTable->setRowCount(0);
    662     _uploadEphTable->setHorizontalHeaderLabels(QString("Host, Port, Mountpoint,  Ntrip, User, Password, System, Bytes").split(","));
    663     _uploadEphTable->setSelectionMode(QAbstractItemView::ExtendedSelection);
    664     _uploadEphTable->setSelectionBehavior(QAbstractItemView::SelectRows);
    665     _uploadEphTable->horizontalHeader()->resizeSection(0, 13 * ww);
    666     _uploadEphTable->horizontalHeader()->resizeSection(1, 5 * ww);
    667     _uploadEphTable->horizontalHeader()->resizeSection(2, 8 * ww);
    668     _uploadEphTable->horizontalHeader()->resizeSection(3, 6 * ww);
    669     _uploadEphTable->horizontalHeader()->resizeSection(4, 8 * ww);
    670     _uploadEphTable->horizontalHeader()->resizeSection(5, 8 * ww);
    671     _uploadEphTable->horizontalHeader()->resizeSection(6, 10 * ww);
    672     _uploadEphTable->horizontalHeader()->resizeSection(7, 12 * ww);
    673 #if QT_VERSION < 0x050000
    674     _uploadEphTable->horizontalHeader()->setResizeMode(QHeaderView::Interactive);
    675 #else
    676     _uploadEphTable->horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive);
    677 #endif
    678     _uploadEphTable->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft);
    679 
    680     connect(_uploadEphTable, SIGNAL(itemSelectionChanged()),
    681         SLOT(slotBncTextChanged()));
    682 
    683     QPushButton* addUploadEphRowButton = new QPushButton("Add Row");
    684     addUploadEphRowButton->setMaximumWidth(9 * ww);
    685     QPushButton* delUploadEphRowButton = new QPushButton("Del Row");
    686     delUploadEphRowButton->setMaximumWidth(9 * ww);
    687 
    688     _uploadSamplRtcmEphSpinBox = new QSpinBox;
    689     _uploadSamplRtcmEphSpinBox->setMinimum(0);
    690     _uploadSamplRtcmEphSpinBox->setMaximum(60);
    691     _uploadSamplRtcmEphSpinBox->setSingleStep(5);
    692     _uploadSamplRtcmEphSpinBox->setMaximumWidth(9 * ww);
    693     _uploadSamplRtcmEphSpinBox->setValue(settings.value("uploadSamplRtcmEph").toInt());
    694     _uploadSamplRtcmEphSpinBox->setSuffix(" sec");
    695 
    696     iRowT = _uploadEphTable->rowCount();
    697     if (iRowT > 0) {
    698         enableWidget(true, _uploadSamplRtcmEphSpinBox);
     2065      flg[iRow] = false;
     2066    }
     2067  }
     2068  for (int iRow = nRows - 1; iRow >= 0; iRow--) {
     2069    if (flg[iRow]) {
     2070      _mountPointsTable->removeRow(iRow);
     2071    }
     2072  }
     2073  _actDeleteMountPoints->setEnabled(false);
     2074
     2075  enableStartStop();
     2076}
     2077
     2078// New Mount Points Selected
     2079////////////////////////////////////////////////////////////////////////////
     2080void bncWindow::slotNewMountPoints(QStringList* mountPoints) {
     2081  int iRow = 0;
     2082  QListIterator<QString> it(*mountPoints);
     2083  while (it.hasNext()) {
     2084    QStringList hlp = it.next().split(" ");
     2085
     2086    QUrl url(hlp[0]);
     2087
     2088    QString format(hlp[1]);
     2089    QString country(hlp[2]);
     2090    QString latitude(hlp[3]);
     2091    QString longitude(hlp[4]);
     2092    QString nmea(hlp[5]);
     2093    QString ntripVersion(hlp[6]);
     2094
     2095    QString fullPath;
     2096    if (ntripVersion == 'S') {
     2097      // url.userInfo() contains the case sensitive portName
     2098      // the portName shall be part of the mountpointString
     2099      // to inform the user about the source of the stream
     2100      if (url.host().contains(url.userInfo().toLower())) {
     2101        fullPath = url.host() + url.path();
     2102      }
     2103      else {
     2104        fullPath =  url.userInfo() + "-" + url.host() + url.path();
     2105      }
     2106    } else {
     2107      fullPath = url.host() + QString(":%1").arg(url.port()) + url.path();
     2108    }
     2109
     2110    _mountPointsTable->insertRow(iRow);
     2111
     2112    QTableWidgetItem* it;
     2113    it = new QTableWidgetItem(url.userInfo());
     2114    it->setFlags(it->flags() & ~Qt::ItemIsEditable);
     2115    _mountPointsTable->setItem(iRow, 0, it);
     2116
     2117    it = new QTableWidgetItem(fullPath);
     2118    it->setFlags(it->flags() & ~Qt::ItemIsEditable);
     2119    _mountPointsTable->setItem(iRow, 1, it);
     2120
     2121    it = new QTableWidgetItem(format);
     2122    _mountPointsTable->setItem(iRow, 2, it);
     2123
     2124    it = new QTableWidgetItem(country);
     2125    _mountPointsTable->setItem(iRow, 3, it);
     2126
     2127    if (nmea == "yes") {
     2128      it = new QTableWidgetItem(latitude);
     2129      _mountPointsTable->setItem(iRow, 4, it);
     2130      it = new QTableWidgetItem(longitude);
     2131      _mountPointsTable->setItem(iRow, 5, it);
    6992132    }
    7002133    else {
    701         enableWidget(false, _uploadSamplRtcmEphSpinBox);
    702     }
    703 
    704     // Upload Raw data
    705     // ----------------------
    706     _uploadRawTable = new QTableWidget(0, 7);
    707     _uploadRawTable->setColumnCount(8);
    708     _uploadRawTable->setRowCount(0);
    709     _uploadRawTable->setHorizontalHeaderLabels(QString("Source Mountpoint, Host, Port, Upload Mountpoint,  Ntrip, User, Password, Bytes").split(","));
    710     _uploadRawTable->setSelectionMode(QAbstractItemView::ExtendedSelection);
    711     _uploadRawTable->setSelectionBehavior(QAbstractItemView::SelectRows);
    712     _uploadRawTable->horizontalHeader()->resizeSection(0, 13 * ww);
    713     _uploadRawTable->horizontalHeader()->resizeSection(1, 13 * ww);
    714     _uploadRawTable->horizontalHeader()->resizeSection(2, 5 * ww);
    715     _uploadRawTable->horizontalHeader()->resizeSection(3, 13 * ww);
    716     _uploadRawTable->horizontalHeader()->resizeSection(4, 6 * ww);
    717     _uploadRawTable->horizontalHeader()->resizeSection(5, 8 * ww);
    718     _uploadRawTable->horizontalHeader()->resizeSection(6, 8 * ww);
    719     _uploadRawTable->horizontalHeader()->resizeSection(7, 10 * ww);
    720     _uploadRawTable->horizontalHeader()->resizeSection(8, 12 * ww);
    721 #if QT_VERSION < 0x050000
    722     _uploadRawTable->horizontalHeader()->setResizeMode(QHeaderView::Interactive);
    723 #else
    724     _uploadRawTable->horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive);
    725 #endif
    726     _uploadRawTable->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft);
    727 
    728     connect(_uploadRawTable, SIGNAL(itemSelectionChanged()), SLOT(slotBncTextChanged()));
    729 
    730     QPushButton* addUploadRawRowButton = new QPushButton("Add Row");
    731     addUploadRawRowButton->setMaximumWidth(9 * ww);
    732     QPushButton* delUploadRawRowButton = new QPushButton("Del Row");
    733     delUploadRawRowButton->setMaximumWidth(9 * ww);
    734 
    735     // Canvas with Editable Fields
    736     // ---------------------------
    737     _canvas = new QWidget;
    738     setCentralWidget(_canvas);
    739 
    740     _aogroup = new QTabWidget();
    741     _aogroup->setElideMode(Qt::ElideNone);
    742     _aogroup->setUsesScrollButtons(true);
    743     QWidget* pgroup = new QWidget();
    744     QWidget* ggroup = new QWidget();
    745     QWidget* sgroup = new QWidget();
    746     QWidget* egroup = new QWidget();
    747     QWidget* agroup = new QWidget();
    748     QWidget* cgroup = new QWidget();
    749     QWidget* ogroup = new QWidget();
    750     QWidget* rgroup = new QWidget();
    751     QWidget* sergroup = new QWidget();
    752     QWidget* pppGroup1 = new QWidget();
    753     QWidget* pppGroup2 = new QWidget();
    754     QWidget* pppGroup3 = new QWidget();
    755     QWidget* pppGroup4 = new QWidget();
    756     QWidget* reqcgroup = new QWidget();
    757     QWidget* sp3CompGroup = new QWidget();
    758     QWidget* cmbgroup = new QWidget();
    759     QWidget* uploadgroup = new QWidget();
    760     QWidget* uploadEphgroup = new QWidget();
    761     QWidget* uploadRawgroup = new QWidget();
    762     _aogroup->addTab(pgroup, tr("Network"));
    763     _aogroup->addTab(ggroup, tr("General"));
    764     _aogroup->addTab(ogroup, tr("RINEX Observations"));
    765     _aogroup->addTab(egroup, tr("RINEX Ephemeris"));
    766     _aogroup->addTab(reqcgroup, tr("RINEX Editing && QC"));
    767     _aogroup->addTab(sp3CompGroup, tr("SP3 Comparison"));
    768     _aogroup->addTab(cgroup, tr("Broadcast Corrections"));
    769     _aogroup->addTab(sgroup, tr("Feed Engine"));
    770     _aogroup->addTab(sergroup, tr("Serial Output"));
    771     _aogroup->addTab(agroup, tr("Outages"));
    772     _aogroup->addTab(rgroup, tr("Miscellaneous"));
    773     _aogroup->addTab(pppGroup1, tr("PPP (1)"));
    774     _aogroup->addTab(pppGroup2, tr("PPP (2)"));
    775     _aogroup->addTab(pppGroup3, tr("PPP (3)"));
    776     _aogroup->addTab(pppGroup4, tr("PPP (4)"));
    777     _aogroup->addTab(cmbgroup, tr("Combine Corrections"));
    778     _aogroup->addTab(uploadgroup, tr("Upload Corrections"));
    779     _aogroup->addTab(uploadEphgroup, tr("Upload Ephemeris"));
    780     _aogroup->addTab(uploadRawgroup, tr("Upload Raw Data"));
    781 
    782     // Log Tab
    783     // -------
    784     _loggroup = new QTabWidget();
    785     _loggroup->addTab(_log, tr("Log"));
    786     _loggroup->addTab(_bncFigure, tr("Throughput"));
    787     _loggroup->addTab(_bncFigureLate, tr("Latency"));
    788     _loggroup->addTab(_bncFigurePPP, tr("PPP Plot"));
    789 
    790     // Netowork (Proxy and SSL) Tab
    791     // ----------------------------
    792     QGridLayout* pLayout = new QGridLayout;
    793     pLayout->setColumnMinimumWidth(0, 13 * ww);
    794     _proxyPortLineEdit->setMaximumWidth(9 * ww);
    795 
    796     pLayout->addWidget(new QLabel("Settings for proxy in protected networks and for SSL authorization, leave boxes blank if none.<br>"), 0, 0, 1, 50);
    797     pLayout->addWidget(new QLabel("Proxy host"), 1, 0);
    798     pLayout->addWidget(_proxyHostLineEdit, 1, 1, 1, 10);
    799     pLayout->addWidget(new QLabel("Proxy port"), 2, 0);
    800     pLayout->addWidget(_proxyPortLineEdit, 2, 1);
    801     pLayout->addWidget(new QLabel("Path to SSL certificates"), 3, 0);
    802     pLayout->addWidget(_sslCaCertPathLineEdit, 3, 1, 1, 10);
    803     pLayout->addWidget(new QLabel("Default:  " + bncSslConfig::defaultPath()), 3, 11, 1, 20);
    804     pLayout->addWidget(new QLabel("Path to SSL client certificates"), 4, 0);
    805     pLayout->addWidget(_sslClientCertPathLineEdit, 4, 1, 1, 10);
    806     pLayout->addWidget(new QLabel("Ignore SSL authorization errors"), 5, 0);
    807     pLayout->addWidget(_sslIgnoreErrorsCheckBox, 5, 1, 1, 10);
    808     pLayout->addWidget(new QLabel(""), 6, 1);
    809     pLayout->setRowStretch(6, 999);
    810 
    811     pgroup->setLayout(pLayout);
    812 
    813     // General Tab
    814     // -----------
    815     QGridLayout* gLayout = new QGridLayout;
    816     gLayout->setColumnMinimumWidth(0, 14 * ww);
    817     _onTheFlyComboBox->setMaximumWidth(9 * ww);
    818 
    819     gLayout->addWidget(new QLabel("General settings for logfile, file handling, configuration on-the-fly, auto-start, and raw file output.<br>"), 0, 0, 1, 50);
    820     gLayout->addWidget(new QLabel("Logfile (full path)"), 1, 0);
    821     gLayout->addWidget(_logFileLineEdit, 1, 1, 1, 20);
    822     gLayout->addWidget(new QLabel("Append files"), 2, 0);
    823     gLayout->addWidget(_rnxAppendCheckBox, 2, 1);
    824     gLayout->addWidget(new QLabel("Reread configuration"), 3, 0);
    825     gLayout->addWidget(_onTheFlyComboBox, 3, 1);
    826     gLayout->addWidget(new QLabel("Auto start"), 4, 0);
    827     gLayout->addWidget(_autoStartCheckBox, 4, 1);
    828     gLayout->addWidget(new QLabel("Raw output file (full path)"), 5, 0);
    829     gLayout->addWidget(_rawOutFileLineEdit, 5, 1, 1, 20);
    830     gLayout->addWidget(new QLabel(""), 6, 1);
    831     gLayout->setRowStretch(7, 999);
    832 
    833     ggroup->setLayout(gLayout);
    834 
    835     // RINEX Observations
    836     // ------------------
    837     QGridLayout* oLayout = new QGridLayout;
    838     oLayout->setColumnMinimumWidth(0, 14 * ww);
    839     _rnxIntrComboBox->setMaximumWidth(9 * ww);
    840     _rnxSamplComboBox->setMaximumWidth(9 * ww);
    841     _rnxSkelExtComboBox->setMaximumWidth(9 * ww);
    842 
    843     oLayout->addWidget(new QLabel("Saving RINEX observation files.<br>"), 0, 0, 1, 50);
    844     oLayout->addWidget(new QLabel("Directory"), 1, 0);
    845     oLayout->addWidget(_rnxPathLineEdit, 1, 1, 1, 15);
    846     oLayout->addWidget(new QLabel("Interval"), 2, 0);
    847     oLayout->addWidget(_rnxIntrComboBox, 2, 1);
    848     oLayout->addWidget(new QLabel("  Sampling"), 2, 2, Qt::AlignRight);
    849     oLayout->addWidget(_rnxSamplComboBox, 2, 3, Qt::AlignRight);
    850     oLayout->addWidget(new QLabel("Skeleton extension"), 3, 0);
    851     oLayout->addWidget(_rnxSkelExtComboBox, 3, 1, Qt::AlignLeft);
    852     oLayout->addWidget(new QLabel("Skeleton mandatory"), 3, 2, Qt::AlignRight);
    853     oLayout->addWidget(_rnxFileCheckBox, 3, 3);
    854     oLayout->addWidget(new QLabel("Skeleton Directory"), 4, 0);
    855     oLayout->addWidget(_rnxSkelPathLineEdit, 4, 1, 1, 15);
    856     oLayout->addWidget(new QLabel("Script (full path)"), 5, 0);
    857     oLayout->addWidget(_rnxScrpLineEdit, 5, 1, 1, 15);
    858     oLayout->addWidget(new QLabel("Version"), 6, 0);
    859     oLayout->addWidget(_rnxVersComboBox, 6, 1);
    860     oLayout->addWidget(new QLabel("Signal priority"), 6, 2, Qt::AlignRight);
    861     oLayout->addWidget(_rnxV2Priority, 6, 3, 1, 13);
    862     oLayout->addWidget(new QLabel(""), 7, 1);
    863     oLayout->setRowStretch(8, 999);
    864 
    865     ogroup->setLayout(oLayout);
    866 
    867     // RINEX Ephemeris
    868     // ---------------
    869     QGridLayout* eLayout = new QGridLayout;
    870     eLayout->setColumnMinimumWidth(0, 14 * ww);
    871     _ephIntrComboBox->setMaximumWidth(9 * ww);
    872     _ephOutPortLineEdit->setMaximumWidth(9 * ww);
    873 
    874     eLayout->addWidget(new QLabel("Saving RINEX navigation files and ephemeris output through IP port.<br>"), 0, 0, 1, 70);
    875     eLayout->addWidget(new QLabel("Directory"), 1, 0);
    876     eLayout->addWidget(_ephPathLineEdit, 1, 1, 1, 30);
    877     eLayout->addWidget(new QLabel("Interval"), 2, 0);
    878     eLayout->addWidget(_ephIntrComboBox, 2, 1);
    879     eLayout->addWidget(new QLabel("Port"), 3, 0);
    880     eLayout->addWidget(_ephOutPortLineEdit, 3, 1);
    881     eLayout->addWidget(new QLabel("Version"), 4, 0);
    882     eLayout->addWidget(_ephVersComboBox, 4, 1);
    883     eLayout->setRowStretch(5, 999);
    884     //eLayout->addWidget(new QLabel("File per Station"),              5, 0);
    885     //eLayout->addWidget(_ephFilePerStation,                          5, 1);
    886     //eLayout->setRowStretch(6, 999);
    887 
    888     egroup->setLayout(eLayout);
    889 
    890 
    891     // Broadcast Corrections
    892     // ---------------------
    893     QGridLayout* cLayout = new QGridLayout;
    894     cLayout->setColumnMinimumWidth(0, 14 * ww);
    895     _corrIntrComboBox->setMaximumWidth(9 * ww);
    896     _corrPortLineEdit->setMaximumWidth(9 * ww);
    897 
    898     cLayout->addWidget(new QLabel("Saving Broadcast Ephemeris correction files and correction output through IP port.<br>"), 0, 0, 1, 70);
    899     cLayout->addWidget(new QLabel("Directory, ASCII"), 1, 0);
    900     cLayout->addWidget(_corrPathLineEdit, 1, 1, 1, 30);
    901     cLayout->addWidget(new QLabel("Interval"), 2, 0);
    902     cLayout->addWidget(_corrIntrComboBox, 2, 1);
    903     cLayout->addWidget(new QLabel("Port"), 3, 0);
    904     cLayout->addWidget(_corrPortLineEdit, 3, 1);
    905     cLayout->addWidget(new QLabel(""), 4, 1);
    906     cLayout->setRowStretch(7, 999);
    907     cgroup->setLayout(cLayout);
    908 
    909     // Feed Engine
    910     // -----------
    911     QGridLayout* sLayout = new QGridLayout;
    912     sLayout->setColumnMinimumWidth(0, 14 * ww);
    913     _outPortLineEdit->setMaximumWidth(9 * ww);
    914     _outWaitSpinBox->setMaximumWidth(9 * ww);
    915     _outSamplComboBox->setMaximumWidth(9 * ww);
    916     _outUPortLineEdit->setMaximumWidth(9 * ww);
    917 
    918     sLayout->addWidget(new QLabel("Output decoded observations in ASCII format to feed a real-time GNSS network engine.<br>"), 0, 0, 1, 50);
    919     sLayout->addWidget(new QLabel("Port"), 1, 0);
    920     sLayout->addWidget(_outPortLineEdit, 1, 1);
    921     sLayout->addWidget(new QLabel("       Wait for full obs epoch"), 1, 2, Qt::AlignRight);
    922     sLayout->addWidget(_outWaitSpinBox, 1, 3, Qt::AlignLeft);
    923     sLayout->addWidget(new QLabel("Sampling"), 2, 0);
    924     sLayout->addWidget(_outSamplComboBox, 2, 1, Qt::AlignLeft);
    925     sLayout->addWidget(new QLabel("File (full path)"), 3, 0);
    926     sLayout->addWidget(_outFileLineEdit, 3, 1, 1, 10);
    927     sLayout->addWidget(new QLabel("Port (unsynchronized)"), 4, 0);
    928     sLayout->addWidget(_outUPortLineEdit, 4, 1);
    929     sLayout->addWidget(new QLabel("Print lock time"), 5, 0);
    930     sLayout->addWidget(_outLockTimeCheckBox, 5, 1);
    931     sLayout->addWidget(new QLabel(""), 6, 1);
    932     sLayout->setRowStretch(7, 999);
    933 
    934     sgroup->setLayout(sLayout);
    935 
    936     // Serial Output
    937     // -------------
    938     QGridLayout* serLayout = new QGridLayout;
    939     serLayout->setColumnMinimumWidth(0, 12 * ww);
    940     _serialBaudRateComboBox->setMaximumWidth(9 * ww);
    941     _serialFlowControlComboBox->setMaximumWidth(11 * ww);
    942     _serialDataBitsComboBox->setMaximumWidth(5 * ww);
    943     _serialParityComboBox->setMaximumWidth(9 * ww);
    944     _serialStopBitsComboBox->setMaximumWidth(5 * ww);
    945     _serialAutoNMEAComboBox->setMaximumWidth(14 * ww);
    946     _serialHeightNMEALineEdit->setMaximumWidth(8 * ww);
    947     _serialNMEASamplingSpinBox->setMaximumWidth(8 * ww);
    948 
    949     serLayout->addWidget(new QLabel("Port settings to feed a serial connected receiver.<br>"), 0, 0, 1, 30);
    950     serLayout->addWidget(new QLabel("Mountpoint"), 1, 0, Qt::AlignLeft);
    951     serLayout->addWidget(_serialMountPointLineEdit, 1, 1, 1, 2);
    952     serLayout->addWidget(new QLabel("Port name"), 2, 0, Qt::AlignLeft);
    953     serLayout->addWidget(_serialPortNameLineEdit, 2, 1, 1, 2);
    954     serLayout->addWidget(new QLabel("Baud rate"), 3, 0, Qt::AlignLeft);
    955     serLayout->addWidget(_serialBaudRateComboBox, 3, 1);
    956     serLayout->addWidget(new QLabel("Flow control"), 3, 2, Qt::AlignRight);
    957     serLayout->addWidget(_serialFlowControlComboBox, 3, 3);
    958     serLayout->addWidget(new QLabel("Data bits"), 4, 0, Qt::AlignLeft);
    959     serLayout->addWidget(_serialDataBitsComboBox, 4, 1);
    960     serLayout->addWidget(new QLabel("Parity"), 4, 2, Qt::AlignRight);
    961     serLayout->addWidget(_serialParityComboBox, 4, 3);
    962     serLayout->addWidget(new QLabel("   Stop bits"), 4, 4, Qt::AlignRight);
    963     serLayout->addWidget(_serialStopBitsComboBox, 4, 5);
    964     serLayout->addWidget(new QLabel("NMEA"), 5, 0);
    965     serLayout->addWidget(_serialAutoNMEAComboBox, 5, 1);
    966     serLayout->addWidget(new QLabel("    File (full path)"), 5, 2, Qt::AlignRight);
    967     serLayout->addWidget(_serialFileNMEALineEdit, 5, 3, 1, 10);
    968     serLayout->addWidget(new QLabel("Height"), 5, 14, Qt::AlignRight);
    969     serLayout->addWidget(_serialHeightNMEALineEdit, 5, 15, 1, 11);
    970     serLayout->addWidget(new QLabel("Sampling"), 5, 25, Qt::AlignRight);
    971     serLayout->addWidget(_serialNMEASamplingSpinBox, 5, 26, 1, 12);
    972     serLayout->addWidget(new QLabel(""), 6, 1);
    973     serLayout->setRowStretch(7, 999);
    974 
    975     sergroup->setLayout(serLayout);
    976 
    977     // Outages
    978     // -------
    979     QGridLayout* aLayout = new QGridLayout;
    980     aLayout->setColumnMinimumWidth(0, 14 * ww);
    981     _adviseObsRateComboBox->setMaximumWidth(9 * ww);
    982     _adviseFailSpinBox->setMaximumWidth(9 * ww);
    983     _adviseRecoSpinBox->setMaximumWidth(9 * ww);
    984 
    985     aLayout->addWidget(new QLabel("Failure and recovery reports, advisory notes.<br>"), 0, 0, 1, 50, Qt::AlignLeft);
    986     aLayout->addWidget(new QLabel("Observation rate"), 1, 0);
    987     aLayout->addWidget(_adviseObsRateComboBox, 1, 1);
    988     aLayout->addWidget(new QLabel("Failure threshold"), 2, 0);
    989     aLayout->addWidget(_adviseFailSpinBox, 2, 1);
    990     aLayout->addWidget(new QLabel("Recovery threshold"), 3, 0);
    991     aLayout->addWidget(_adviseRecoSpinBox, 3, 1);
    992     aLayout->addWidget(new QLabel("Script (full path)"), 4, 0);
    993     aLayout->addWidget(_adviseScriptLineEdit, 4, 1, 1, 20);
    994     aLayout->addWidget(new QLabel(""), 5, 1);
    995     aLayout->setRowStretch(6, 999);
    996 
    997     agroup->setLayout(aLayout);
    998 
    999     // Miscellaneous
    1000     // -------------
    1001     QGridLayout* rLayout = new QGridLayout;
    1002     rLayout->setColumnMinimumWidth(0, 14 * ww);
    1003     _miscIntrComboBox->setMaximumWidth(9 * ww);
    1004     _miscPortLineEdit->setMaximumWidth(9 * ww);
    1005 
    1006     rLayout->addWidget(new QLabel("Log latencies or scan RTCM streams for message types and antenna information or output raw data through TCP/IP port.<br>"), 0, 0, 1, 50);
    1007     rLayout->addWidget(new QLabel("Mountpoint"), 1, 0);
    1008     rLayout->addWidget(_miscMountLineEdit, 1, 1, 1, 7);
    1009     rLayout->addWidget(new QLabel("Log latency"), 2, 0);
    1010     rLayout->addWidget(_miscIntrComboBox, 2, 1);
    1011     rLayout->addWidget(new QLabel("Scan RTCM"), 3, 0);
    1012     rLayout->addWidget(_miscScanRTCMCheckBox, 3, 1);
    1013     rLayout->addWidget(new QLabel("Port"), 4, 0);
    1014     rLayout->addWidget(_miscPortLineEdit, 4, 1);
    1015     rLayout->addWidget(new QLabel(""), 5, 1);
    1016     rLayout->setRowStretch(6, 999);
    1017 
    1018     rgroup->setLayout(rLayout);
    1019 
    1020     // PPP
    1021     // ---
    1022     _pppWidgets._dataSource->setMaximumWidth(15 * ww);
    1023     _pppWidgets._corrMount->setMaximumWidth(15 * ww);
    1024     _pppWidgets._nmeaPath->setMaximumWidth(35 * ww);
    1025     _pppWidgets._logPath->setMaximumWidth(35 * ww);
    1026     _pppWidgets._snxtroPath->setMaximumWidth(35 * ww);
    1027     _pppWidgets._snxtroIntr->setMaximumWidth(7 * ww);
    1028     _pppWidgets._snxtroAc->setMaximumWidth(7 * ww);
    1029     _pppWidgets._snxtroSolId->setMaximumWidth(7 * ww);
    1030     _pppWidgets._snxtroSolType->setMaximumWidth(7 * ww);
    1031     _pppWidgets._snxtroCampId->setMaximumWidth(7 * ww);
    1032     _pppWidgets._ionoMount->setMaximumWidth(15 * ww);
    1033 
    1034 
    1035     QGridLayout* pppLayout1 = new QGridLayout();
    1036     int ir = 0;
    1037     pppLayout1->addWidget(new QLabel("Precise Point Positioning - Input and Output.<br>"), ir, 0, 1, 7, Qt::AlignLeft);
    1038     ++ir;
    1039     pppLayout1->addWidget(new QLabel("Data source"), ir, 0);
    1040     pppLayout1->addWidget(_pppWidgets._dataSource, ir, 1);
    1041     pppLayout1->addWidget(new QLabel("   Logfile directory"), ir, 4);
    1042     pppLayout1->addWidget(_pppWidgets._logPath, ir, 5, 1, 3);
    1043     ++ir;
    1044     pppLayout1->addWidget(new QLabel("Corrections stream"), ir, 0);
    1045     pppLayout1->addWidget(_pppWidgets._corrMount, ir, 1);
    1046     pppLayout1->addWidget(new QLabel("Corrections file"), ir, 2);
    1047     pppLayout1->addWidget(_pppWidgets._corrFile, ir, 3);
    1048     pppLayout1->addWidget(new QLabel("   NMEA directory"), ir, 4);
    1049     pppLayout1->addWidget(_pppWidgets._nmeaPath, ir, 5, 1, 3);
    1050     ++ir;
    1051 #ifdef USE_PPP
    1052     pppLayout1->addWidget(new QLabel("Ionosphere stream"), ir, 0);
    1053     pppLayout1->addWidget(_pppWidgets._ionoMount, ir, 1);
    1054     pppLayout1->addWidget(new QLabel("Ionosphere file"), ir, 2);
    1055     pppLayout1->addWidget(_pppWidgets._ionoFile, ir, 3);
    1056 #endif
    1057     pppLayout1->addWidget(new QLabel("   SNX TRO directory"), ir, 4);
    1058     pppLayout1->addWidget(_pppWidgets._snxtroPath, ir, 5, 1, 3);
    1059     ++ir;
    1060     pppLayout1->addWidget(new QLabel("RINEX Obs file"), ir, 0);
    1061     pppLayout1->addWidget(_pppWidgets._rinexObs, ir, 1);
    1062     pppLayout1->addWidget(new QLabel("RINEX Nav file"), ir, 2);
    1063     pppLayout1->addWidget(_pppWidgets._rinexNav, ir, 3);
    1064     pppLayout1->addWidget(new QLabel("   SNX TRO interval"), ir, 4);
    1065     pppLayout1->addWidget(_pppWidgets._snxtroIntr, ir, 5);
    1066     pppLayout1->addWidget(new QLabel("   SNX TRO sampling"), ir, 6);
    1067     pppLayout1->addWidget(_pppWidgets._snxtroSampl, ir, 7, Qt::AlignRight);
    1068     ++ir;
    1069     pppLayout1->addWidget(new QLabel("ANTEX file"), ir, 0);
    1070     pppLayout1->addWidget(_pppWidgets._antexFile, ir, 1);
    1071     pppLayout1->addWidget(new QLabel("Coordinates file"), ir, 2);
    1072     pppLayout1->addWidget(_pppWidgets._crdFile, ir, 3);
    1073     pppLayout1->addWidget(new QLabel("   SNX TRO AC"), ir, 4);
    1074     pppLayout1->addWidget(_pppWidgets._snxtroAc, ir, 5);
    1075     pppLayout1->addWidget(new QLabel("   SNX TRO solution ID"), ir, 6);
    1076     pppLayout1->addWidget(_pppWidgets._snxtroSolId, ir, 7, Qt::AlignRight);
    1077     ++ir;
    1078 #ifdef USE_PPP
    1079     pppLayout1->addWidget(new QLabel("BLQ file"), ir, 0);
    1080     pppLayout1->addWidget(_pppWidgets._blqFile, ir, 1);
    1081     pppLayout1->addWidget(new QLabel("   SNX TRO campaign ID"), ir, 4);
    1082     pppLayout1->addWidget(_pppWidgets._snxtroCampId, ir, 5);
    1083     pppLayout1->addWidget(new QLabel("   SNX TRO solution type"), ir, 6);
    1084     pppLayout1->addWidget(_pppWidgets._snxtroSolType, ir, 7, Qt::AlignRight);
    1085 #endif
    1086     pppLayout1->setRowStretch(ir + 1, 999);
    1087     pppGroup1->setLayout(pppLayout1);
    1088 
    1089     QGridLayout* pppLayout2 = new QGridLayout();
    1090     ir = 0;
    1091     pppLayout2->addWidget(new QLabel("Precise Point Positioning - Options.<br>"), ir, 0, 1, 2, Qt::AlignLeft);
    1092     ++ir;
    1093     pppLayout2->addWidget(new QLabel("GPS LCs"), ir, 0, Qt::AlignLeft);
    1094     pppLayout2->addWidget(_pppWidgets._lcGPS, ir, 1);
    1095     pppLayout2->addItem(new QSpacerItem(8 * ww, 0), ir, 2);
    1096     pppLayout2->addWidget(new QLabel("Sigma C1"), ir, 3, Qt::AlignLeft);
    1097     pppLayout2->addWidget(_pppWidgets._sigmaC1, ir, 4); _pppWidgets._sigmaC1->setMaximumWidth(8 * ww);
    1098     pppLayout2->addItem(new QSpacerItem(8 * ww, 0), ir, 5);
    1099     pppLayout2->addWidget(new QLabel("Sigma L1"), ir, 6, Qt::AlignLeft);
    1100     pppLayout2->addWidget(_pppWidgets._sigmaL1, ir, 7); _pppWidgets._sigmaL1->setMaximumWidth(8 * ww);
    1101     ++ir;
    1102     pppLayout2->addWidget(new QLabel("GLONASS LCs"), ir, 0, Qt::AlignLeft);
    1103     pppLayout2->addWidget(_pppWidgets._lcGLONASS, ir, 1);
    1104     pppLayout2->addWidget(new QLabel("Max Res C1"), ir, 3, Qt::AlignLeft);
    1105     pppLayout2->addWidget(_pppWidgets._maxResC1, ir, 4); _pppWidgets._maxResC1->setMaximumWidth(8 * ww);
    1106     pppLayout2->addWidget(new QLabel("Max Res L1"), ir, 6, Qt::AlignLeft);
    1107     pppLayout2->addWidget(_pppWidgets._maxResL1, ir, 7); _pppWidgets._maxResL1->setMaximumWidth(8 * ww);
    1108     ++ir;
    1109     pppLayout2->addWidget(new QLabel("Galileo LCs"), ir, 0, Qt::AlignLeft);
    1110     pppLayout2->addWidget(_pppWidgets._lcGalileo, ir, 1);
    1111     pppLayout2->addWidget(new QLabel("Ele Wgt Code"), ir, 3, Qt::AlignLeft);
    1112     pppLayout2->addWidget(_pppWidgets._eleWgtCode, ir, 4);
    1113     pppLayout2->addWidget(new QLabel("Ele Wgt Phase"), ir, 6, Qt::AlignLeft);
    1114     pppLayout2->addWidget(_pppWidgets._eleWgtPhase, ir, 7);
    1115     ++ir;
    1116     pppLayout2->addWidget(new QLabel("BDS LCs"), ir, 0, Qt::AlignLeft);
    1117     pppLayout2->addWidget(_pppWidgets._lcBDS, ir, 1);
    1118     pppLayout2->addWidget(new QLabel("Min # of Obs"), ir, 3, Qt::AlignLeft);
    1119     pppLayout2->addWidget(_pppWidgets._minObs, ir, 4);
    1120     pppLayout2->addWidget(new QLabel("Min Elevation"), ir, 6, Qt::AlignLeft);
    1121     pppLayout2->addWidget(_pppWidgets._minEle, ir, 7); _pppWidgets._minEle->setMaximumWidth(8 * ww);
    1122     ++ir;
    1123 #ifdef USE_PPP
    1124     pppLayout2->addWidget(new QLabel("Constraints"), ir, 0, Qt::AlignLeft);
    1125     pppLayout2->addWidget(_pppWidgets._constraints, ir, 1);
    1126     pppLayout2->addWidget(new QLabel("Sigma GIM"), ir, 3, Qt::AlignLeft);
    1127     pppLayout2->addWidget(_pppWidgets._sigmaGIM, ir, 4); _pppWidgets._sigmaGIM->setMaximumWidth(8 * ww);
    1128 #endif
    1129     pppLayout2->addItem(new QSpacerItem(8 * ww, 0), ir, 5);
    1130     pppLayout2->addWidget(new QLabel("Wait for clock corr."), ir, 6, Qt::AlignLeft);
    1131     pppLayout2->addWidget(_pppWidgets._corrWaitTime, ir, 7);
    1132     ++ir;
    1133     pppLayout2->addItem(new QSpacerItem(8 * ww, 0), ir, 2);
    1134 #ifdef USE_PPP
    1135     pppLayout2->addWidget(new QLabel("Max Res GIM"), ir, 3, Qt::AlignLeft);
    1136     pppLayout2->addWidget(_pppWidgets._maxResGIM, ir, 4); _pppWidgets._maxResGIM->setMaximumWidth(8 * ww);
    1137 #endif
    1138     pppLayout2->addWidget(new QLabel("Seeding (sec)"), ir, 6, Qt::AlignLeft);
    1139     pppLayout2->addWidget(_pppWidgets._seedingTime, ir, 7); _pppWidgets._seedingTime->setMaximumWidth(8 * ww);
    1140     ++ir;
    1141     pppLayout2->addWidget(new QLabel(""), ir, 8);
    1142     pppLayout2->setColumnStretch(8, 999);
    1143     ++ir;
    1144     pppLayout2->addWidget(new QLabel(""), ir, 1);
    1145     pppLayout2->setRowStretch(ir, 999);
    1146 
    1147     pppGroup2->setLayout(pppLayout2);
    1148 
    1149     QVBoxLayout* pppLayout3 = new QVBoxLayout();
    1150     pppLayout3->addWidget(new QLabel("Precise Point Positioning - Processed Stations.<br>"));
    1151     pppLayout3->addWidget(_pppWidgets._staTable, 99);
    1152     QHBoxLayout* pppLayout3sub = new QHBoxLayout();
    1153     pppLayout3sub->addWidget(_pppWidgets._addStaButton);
    1154     pppLayout3sub->addWidget(_pppWidgets._delStaButton);
    1155     pppLayout3sub->addStretch(99);
    1156 
    1157     pppLayout3->addLayout(pppLayout3sub);
    1158 
    1159     pppGroup3->setLayout(pppLayout3);
    1160 
    1161     // ------------------------
    1162     connect(_pppWidgets._mapWinButton, SIGNAL(clicked()), SLOT(slotMapPPP()));
    1163     _pppWidgets._mapSpeedSlider->setMinimumWidth(33 * ww);
    1164     _pppWidgets._audioResponse->setMaximumWidth(8 * ww);
    1165 
    1166     QGridLayout* pppLayout4 = new QGridLayout();
    1167     ir = 0;
    1168     pppLayout4->addWidget(new QLabel("Precise Point Positioning - Plots.<br>"), ir, 0, 1, 50, Qt::AlignLeft);
    1169     ++ir;
    1170     pppLayout4->addWidget(new QLabel("PPP Plot"), ir, 0, Qt::AlignLeft);
    1171     pppLayout4->addWidget(_pppWidgets._plotCoordinates, ir, 1, Qt::AlignLeft);
    1172     pppLayout4->addWidget(new QLabel("Mountpoint"), ir, 2, 1, 10, Qt::AlignLeft);
    1173     pppLayout4->addWidget(_pppWidgets._audioResponse, ir, 4, Qt::AlignLeft);
    1174     pppLayout4->addWidget(new QLabel("Audio response"), ir, 5, Qt::AlignRight);
    1175     ++ir;
    1176     pppLayout4->addWidget(new QLabel("Track map"), ir, 0, Qt::AlignLeft);
    1177     pppLayout4->addWidget(_pppWidgets._mapWinButton, ir, 1, Qt::AlignLeft);
    1178     ++ir;
    1179     pppLayout4->addWidget(new QLabel("Dot-properties"), ir, 0, Qt::AlignLeft);
    1180     pppLayout4->addWidget(_pppWidgets._mapWinDotSize, ir, 1, Qt::AlignLeft);
    1181     pppLayout4->addWidget(new QLabel("Size    "), ir, 2, Qt::AlignLeft);
    1182     pppLayout4->addWidget(_pppWidgets._mapWinDotColor, ir, 3, Qt::AlignLeft);
    1183     pppLayout4->addWidget(new QLabel("Color"), ir, 4, Qt::AlignLeft);
    1184     ++ir;
    1185     pppLayout4->addWidget(new QLabel("Post-processing speed"), ir, 0, Qt::AlignLeft);
    1186     pppLayout4->addWidget(_pppWidgets._mapSpeedSlider, ir, 1, 1, 20, Qt::AlignLeft);
    1187     ++ir;
    1188     pppLayout4->addWidget(new QLabel(""), ir, 1);
    1189     pppLayout4->setRowStretch(ir, 999);
    1190 
    1191     pppGroup4->setLayout(pppLayout4);
    1192 
    1193     // Reqc Processing
    1194     // ---------------
    1195     _reqcActionComboBox = new QComboBox();
    1196     _reqcActionComboBox->setEditable(false);
    1197     _reqcActionComboBox->addItems(QString(",Edit/Concatenate,Analyze").split(","));
    1198     int ip = _reqcActionComboBox->findText(settings.value("reqcAction").toString());
    1199     if (ip != -1) {
    1200         _reqcActionComboBox->setCurrentIndex(ip);
    1201     }
    1202     connect(_reqcActionComboBox, SIGNAL(currentIndexChanged(const QString&)),
    1203         this, SLOT(slotBncTextChanged()));
    1204 
    1205     QGridLayout* reqcLayout = new QGridLayout;
    1206     _reqcActionComboBox->setMinimumWidth(15 * ww);
    1207     _reqcActionComboBox->setMaximumWidth(20 * ww);
    1208 
    1209     _reqcObsFileChooser = new qtFileChooser(0, qtFileChooser::Files);
    1210     _reqcObsFileChooser->setFileName(settings.value("reqcObsFile").toString());
    1211 
    1212     _reqcNavFileChooser = new qtFileChooser(0, qtFileChooser::Files);
    1213     _reqcNavFileChooser->setFileName(settings.value("reqcNavFile").toString());
    1214     _reqcOutObsLineEdit = new QLineEdit(settings.value("reqcOutObsFile").toString());
    1215     _reqcOutNavLineEdit = new QLineEdit(settings.value("reqcOutNavFile").toString());
    1216     _reqcOutLogLineEdit = new QLineEdit(settings.value("reqcOutLogFile").toString());
    1217     _reqcPlotDirLineEdit = new QLineEdit(settings.value("reqcPlotDir").toString());
    1218     _reqcSkyPlotSignals = new QLineEdit(settings.value("reqcSkyPlotSignals").toString());
    1219 
    1220     connect(_reqcSkyPlotSignals, SIGNAL(textChanged(const QString&)),
    1221         this, SLOT(slotBncTextChanged()));
    1222 
    1223     _reqcLogSummaryOnly = new QCheckBox();
    1224     _reqcLogSummaryOnly->setCheckState(Qt::CheckState(settings.value("reqcLogSummaryOnly").toInt()));
    1225 
    1226     ir = 0;
    1227     reqcLayout->addWidget(new QLabel("RINEX file editing, concatenation and quality check.<br>"), ir, 0, 1, 8);
    1228     ++ir;
    1229     reqcLayout->addWidget(new QLabel("Action"), ir, 0);
    1230     reqcLayout->addWidget(_reqcActionComboBox, ir, 1);
    1231     _reqcEditOptionButton = new QPushButton("Set Edit Options");
    1232     _reqcEditOptionButton->setMinimumWidth(15 * ww);
    1233     _reqcEditOptionButton->setMaximumWidth(20 * ww);
    1234 
    1235     reqcLayout->addWidget(_reqcEditOptionButton, ir, 3);
    1236     ++ir;
    1237     reqcLayout->addWidget(new QLabel("Input files (full path)"), ir, 0);
    1238     reqcLayout->addWidget(_reqcObsFileChooser, ir, 1);
    1239     _reqcObsFileChooser->setMaximumWidth(40 * ww);
    1240     reqcLayout->addWidget(new QLabel("  Obs"), ir, 2);
    1241     reqcLayout->addWidget(_reqcNavFileChooser, ir, 3);
    1242     _reqcNavFileChooser->setMaximumWidth(40 * ww);
    1243     reqcLayout->addWidget(new QLabel("  Nav"), ir, 4);
    1244     ++ir;
    1245     reqcLayout->addWidget(new QLabel("Output file (full path)"), ir, 0);
    1246     reqcLayout->addWidget(_reqcOutObsLineEdit, ir, 1);
    1247     _reqcOutObsLineEdit->setMaximumWidth(40 * ww);
    1248     reqcLayout->addWidget(new QLabel("  Obs"), ir, 2);
    1249     reqcLayout->addWidget(_reqcOutNavLineEdit, ir, 3);
    1250     _reqcOutNavLineEdit->setMaximumWidth(40 * ww);
    1251     reqcLayout->addWidget(new QLabel("  Nav"), ir, 4);
    1252     ++ir;
    1253     reqcLayout->addWidget(new QLabel("Logfile"), ir, 0);
    1254     reqcLayout->addWidget(_reqcOutLogLineEdit, ir, 1);
    1255     _reqcOutLogLineEdit->setMaximumWidth(40 * ww);
    1256     reqcLayout->addWidget(new QLabel("  Summary only"), ir, 2);
    1257     reqcLayout->addWidget(_reqcLogSummaryOnly, ir, 3);
    1258     ++ir;
    1259     reqcLayout->addWidget(new QLabel("Plots for signals"), ir, 0);
    1260     reqcLayout->addWidget(_reqcSkyPlotSignals, ir, 1);
    1261     _reqcSkyPlotSignals->setMaximumWidth(40 * ww);
    1262     ++ir;
    1263     reqcLayout->addWidget(new QLabel("Directory for plots"), ir, 0);
    1264     reqcLayout->addWidget(_reqcPlotDirLineEdit, ir, 1);
    1265     _reqcPlotDirLineEdit->setMaximumWidth(40 * ww);
    1266     ++ir;
    1267     reqcLayout->setRowStretch(ir, 999);
    1268 
    1269     reqcLayout->setColumnMinimumWidth(2, 8 * ww);
    1270     reqcLayout->setColumnMinimumWidth(4, 8 * ww);
    1271 
    1272     reqcgroup->setLayout(reqcLayout);
    1273 
    1274     connect(_reqcEditOptionButton, SIGNAL(clicked()),
    1275         this, SLOT(slotReqcEditOption()));
    1276 
    1277     QGridLayout* sp3CompLayout = new QGridLayout;
    1278 
    1279     _sp3CompFileChooser = new qtFileChooser(0, qtFileChooser::Files);
    1280     _sp3CompFileChooser->setFileName(settings.value("sp3CompFile").toString());
    1281     _sp3CompFileChooser->setMinimumWidth(15 * ww);
    1282     _sp3CompFileChooser->setMaximumWidth(40 * ww);
    1283 
    1284     _sp3CompExclude = new QLineEdit(settings.value("sp3CompExclude").toString());
    1285     _sp3CompExclude->setMinimumWidth(18 * ww);
    1286     _sp3CompExclude->setMaximumWidth(18 * ww);
    1287 
    1288     _sp3CompLogLineEdit = new QLineEdit(settings.value("sp3CompOutLogFile").toString());
    1289     _sp3CompLogLineEdit->setMinimumWidth(18 * ww);
    1290     _sp3CompLogLineEdit->setMaximumWidth(18 * ww);
    1291 
    1292     _sp3CompSummaryOnly = new QCheckBox();
    1293     _sp3CompSummaryOnly->setCheckState(Qt::CheckState(settings.value("sp3CompSummaryOnly").toInt()));
    1294 
    1295     ir = 0;
    1296     sp3CompLayout->addWidget(new QLabel("Orbit and clock comparison.<br>"), ir, 0, 1, 40);
    1297     ++ir;
    1298     sp3CompLayout->addWidget(new QLabel("Input SP3 files (full path)"), ir, 0, Qt::AlignLeft);
    1299     sp3CompLayout->addWidget(_sp3CompFileChooser, ir, 1, 1, 20);
    1300     ++ir;
    1301     sp3CompLayout->addWidget(new QLabel("Exclude satellites"), ir, 0, Qt::AlignLeft);
    1302     sp3CompLayout->addWidget(_sp3CompExclude, ir, 1, Qt::AlignRight);
    1303     ++ir;
    1304     sp3CompLayout->addWidget(new QLabel("Logfile"), ir, 0, Qt::AlignLeft);
    1305     sp3CompLayout->addWidget(_sp3CompLogLineEdit, ir, 1, Qt::AlignRight);
    1306     ++ir;
    1307     sp3CompLayout->addWidget(new QLabel("Summary only"), ir, 0);
    1308     sp3CompLayout->addWidget(_sp3CompSummaryOnly, ir, 1);
    1309     ++ir;
    1310     sp3CompLayout->addWidget(new QLabel(""), ir, 1);
    1311     ++ir;
    1312     sp3CompLayout->setRowStretch(ir, 999);
    1313 
    1314     sp3CompLayout->setColumnMinimumWidth(2, 8 * ww);
    1315     sp3CompLayout->setColumnMinimumWidth(4, 8 * ww);
    1316 
    1317     sp3CompGroup->setLayout(sp3CompLayout);
    1318 
    1319     connect(_sp3CompFileChooser, SIGNAL(fileNameChanged(const QString&)),
    1320         this, SLOT(slotBncTextChanged()));
    1321 
    1322     // Combine Corrections
    1323     // -------------------
    1324     QGridLayout* cmbLayout = new QGridLayout;
    1325 
    1326     populateCmbTable();
    1327     cmbLayout->addWidget(_cmbTable, 0, 0, 8, 10);
    1328     cmbLayout->addWidget(new QLabel(" Combine Broadcast Correction streams"), 0, 10, 1, 10);
    1329     cmbLayout->addWidget(addCmbRowButton, 1, 10);
    1330     cmbLayout->addWidget(delCmbRowButton, 1, 11);
    1331     cmbLayout->addWidget(new QLabel("Method"), 2, 10, Qt::AlignLeft);
    1332     cmbLayout->addWidget(_cmbMethodComboBox, 2, 11);
    1333     cmbLayout->addWidget(new QLabel("BSX File"), 3, 10, Qt::AlignLeft);
    1334     cmbLayout->addWidget(_cmbBsxFile, 3, 11, Qt::AlignRight);
    1335     cmbLayout->addWidget(new QLabel("Max Clk Residual"), 4, 10, Qt::AlignLeft);
    1336     cmbLayout->addWidget(_cmbMaxresLineEdit, 4, 11, Qt::AlignRight);
    1337     cmbLayout->addWidget(new QLabel("Max Orb Displacement"), 5, 10, Qt::AlignLeft);
    1338     cmbLayout->addWidget(_cmbMaxdisplacementLineEdit, 5, 11, Qt::AlignRight);
    1339     cmbLayout->addWidget(new QLabel("Logfile directory"), 6, 10, Qt::AlignLeft);
    1340     cmbLayout->addWidget(_cmbLogPath, 6, 11, Qt::AlignRight);
    1341     cmbLayout->addWidget(new QLabel("Sampling"), 7, 10, Qt::AlignLeft);
    1342     cmbLayout->addWidget(_cmbSamplComboBox, 7, 11, Qt::AlignRight);
    1343 
    1344 
    1345     cmbLayout->addWidget(new QLabel("GNSS"), 0, 14, Qt::AlignLeft);
    1346     cmbLayout->addWidget(new QLabel("GPS (C1W/C2W)"), 1, 14);
    1347     cmbLayout->addWidget(_cmbGpsCheckBox, 1, 15);
    1348 
    1349     cmbLayout->addWidget(new QLabel("GLONASS (C1P/C2P)"), 2, 14);
    1350     cmbLayout->addWidget(_cmbGloCheckBox, 2, 15);
    1351 
    1352     cmbLayout->addWidget(new QLabel("Galileo (C1C/C5Q)"), 3, 14);
    1353     cmbLayout->addWidget(_cmbGalCheckBox, 3, 15);
    1354 
    1355     cmbLayout->addWidget(new QLabel("Beidou (C2I/C6I)"), 4, 14);
    1356     cmbLayout->addWidget(_cmbBdsCheckBox, 4, 15);
    1357 
    1358     cmbLayout->addWidget(new QLabel("QZSS (C1C/C2L)"), 5, 14);
    1359     cmbLayout->addWidget(_cmbQzssCheckBox, 5, 15);
    1360 
    1361     cmbLayout->addWidget(new QLabel("SBAS (C1C/C5Q)"), 6, 14);
    1362     cmbLayout->addWidget(_cmbSbasCheckBox, 6, 15);
    1363 
    1364     cmbLayout->addWidget(new QLabel("NavIC"), 7, 14);
    1365     cmbLayout->addWidget(_cmbNavicCheckBox, 7, 15);
    1366     cmbLayout->setRowStretch(9, 999);
    1367 
    1368     connect(addCmbRowButton, SIGNAL(clicked()), this, SLOT(slotAddCmbRow()));
    1369     connect(delCmbRowButton, SIGNAL(clicked()), this, SLOT(slotDelCmbRow()));
    1370 
    1371     cmbgroup->setLayout(cmbLayout);
    1372 
    1373     // Upload Layout (Clocks)
    1374     // ----------------------
    1375     QGridLayout* uploadHlpLayout = new QGridLayout();
    1376 
    1377     connect(addUploadRowButton, SIGNAL(clicked()), this, SLOT(slotAddUploadRow()));
    1378     connect(delUploadRowButton, SIGNAL(clicked()), this, SLOT(slotDelUploadRow()));
    1379     connect(setUploadTrafoButton, SIGNAL(clicked()), this, SLOT(slotSetUploadTrafo()));
    1380 
    1381     uploadHlpLayout->addWidget(addUploadRowButton, 0, 0);
    1382     uploadHlpLayout->addWidget(delUploadRowButton, 0, 1);
    1383     uploadHlpLayout->addWidget(new QLabel("Interval"), 0, 2, Qt::AlignRight);
    1384     uploadHlpLayout->addWidget(_uploadIntrComboBox, 0, 3);
    1385     uploadHlpLayout->addWidget(new QLabel("     Sampling:    Orb"), 0, 4, Qt::AlignRight);
    1386     uploadHlpLayout->addWidget(_uploadSamplRtcmEphCorrComboBox, 0, 5);
    1387     uploadHlpLayout->addWidget(new QLabel("SP3"), 0, 6, Qt::AlignRight);
    1388     uploadHlpLayout->addWidget(_uploadSamplSp3ComboBox, 0, 7);
    1389     uploadHlpLayout->addWidget(new QLabel("RNX"), 0, 8, Qt::AlignRight);
    1390     uploadHlpLayout->addWidget(_uploadSamplClkRnxSpinBox, 0, 9);
    1391     uploadHlpLayout->addWidget(new QLabel("BSX"), 0, 10, Qt::AlignRight);
    1392     uploadHlpLayout->addWidget(_uploadSamplBiaSnxSpinBox, 0, 11);
    1393     uploadHlpLayout->addWidget(setUploadTrafoButton, 0, 12);
    1394     uploadHlpLayout->addWidget(new QLabel("ANTEX file"), 1, 0, Qt::AlignLeft);
    1395     uploadHlpLayout->addWidget(_uploadAntexFile, 1, 1, 1, 4);
    1396 
    1397     QBoxLayout* uploadLayout = new QBoxLayout(QBoxLayout::TopToBottom);
    1398     populateUploadTable();
    1399 
    1400     uploadLayout->addWidget(new QLabel("Upload RTCM Version 3 Broadcast Corrections to Broadcaster.<br>"));
    1401     uploadLayout->addWidget(_uploadTable);
    1402     uploadLayout->addLayout(uploadHlpLayout);
    1403 
    1404     uploadgroup->setLayout(uploadLayout);
    1405 
    1406     // Upload Layout (Ephemeris)
    1407     // -------------------------
    1408     QGridLayout* uploadHlpLayoutEph = new QGridLayout();
    1409 
    1410     connect(addUploadEphRowButton, SIGNAL(clicked()), this, SLOT(slotAddUploadEphRow()));
    1411     connect(delUploadEphRowButton, SIGNAL(clicked()), this, SLOT(slotDelUploadEphRow()));
    1412 
    1413     uploadHlpLayoutEph->addWidget(addUploadEphRowButton, 0, 0);
    1414     uploadHlpLayoutEph->addWidget(delUploadEphRowButton, 0, 1);
    1415     uploadHlpLayoutEph->addWidget(new QLabel("     Sampling"), 0, 2, Qt::AlignRight);
    1416     uploadHlpLayoutEph->addWidget(_uploadSamplRtcmEphSpinBox, 0, 3);
    1417 
    1418     QBoxLayout* uploadLayoutEph = new QBoxLayout(QBoxLayout::TopToBottom);
    1419     populateUploadEphTable();
    1420 
    1421     uploadLayoutEph->addWidget(new QLabel("Upload RTCM Version 3 Broadcast Ephemeris to Broadcaster.<br>"));
    1422     uploadLayoutEph->addWidget(_uploadEphTable);
    1423     uploadLayoutEph->addLayout(uploadHlpLayoutEph);
    1424 
    1425     uploadEphgroup->setLayout(uploadLayoutEph);
    1426 
    1427 
    1428     // Upload Layout (Raw Data)
    1429     // -------------------------
    1430     QGridLayout* uploadHlpLayoutRaw = new QGridLayout();
    1431 
    1432     connect(addUploadRawRowButton, SIGNAL(clicked()), this, SLOT(slotAddUploadRawRow()));
    1433     connect(delUploadRawRowButton, SIGNAL(clicked()), this, SLOT(slotDelUploadRawRow()));
    1434 
    1435     uploadHlpLayoutRaw->addWidget(addUploadRawRowButton, 0, 0);
    1436     uploadHlpLayoutRaw->addWidget(delUploadRawRowButton, 0, 1);
    1437 
    1438     QBoxLayout* uploadLayoutRaw = new QBoxLayout(QBoxLayout::TopToBottom);
    1439     populateUploadRawTable();
    1440 
    1441     uploadLayoutRaw->addWidget(new QLabel("Upload Raw Data to Broadcaster (Ntrip Server Functionality).<br>"));
    1442     uploadLayoutRaw->addWidget(_uploadRawTable);
    1443     uploadLayoutRaw->addLayout(uploadHlpLayoutRaw);
    1444 
    1445     uploadRawgroup->setLayout(uploadLayoutRaw);
    1446 
    1447     // Main Layout
    1448     // -----------
    1449     QGridLayout* mLayout = new QGridLayout;
    1450     _aogroup->setCurrentIndex(settings.value("startTab").toInt());
    1451     mLayout->addWidget(_aogroup, 0, 0);
    1452     mLayout->addWidget(_mountPointsTable, 1, 0);
    1453     _loggroup->setCurrentIndex(settings.value("statusTab").toInt());
    1454     mLayout->addWidget(_loggroup, 2, 0);
    1455 
    1456     _canvas->setLayout(mLayout);
    1457 
    1458     // WhatsThis, Network
    1459     // ------------------
    1460     _proxyHostLineEdit->setWhatsThis(tr("<p>If you are running BNC within a protected Local Area Network (LAN), you may need to use a proxy server to access the Internet. Enter your proxy server IP and port number in case one is operated in front of BNC. If you do not know the IP and port of your proxy server, check the proxy server settings in your Internet browser or ask your network administrator. Without any entry, BNC will try to use the system proxies. </p><p>Note that IP streaming is sometimes not allowed in a LAN. In this case you need to ask your network administrator for an appropriate modification of the local security policy or for the installation of a TCP relay to the Ntrip Broadcasters. If this is not possible, you may need to run BNC outside your LAN on a network that has unobstructed connection to the Internet. <i>[key: proxyHost]</i></p>"));
    1461     _proxyPortLineEdit->setWhatsThis(tr("<p>Enter your proxy server port number in case a proxy is operated in front of BNC. <i>[key: proxyPort]</i></p>"));
    1462     _sslCaCertPathLineEdit->setWhatsThis(tr("<p>Communication with an Ntrip Broadcaster over SSL requires the exchange of server certificates. Specify the path to a directory where you save CA certificates on your system. </p><p>BNC creates from *.crt and *.pem files a CA certificate database, which is used by the socket during the handshake phase to validate the peer's certificate. </p><p>Note that SSL communication is usually done over port 443. <i>[key: sslCaCertPath]</i></p>"));
    1463     _sslClientCertPathLineEdit->setWhatsThis(tr("<p>Two-sided communication with an Ntrip Broadcaster over SSL requires in addition the exchange of client certificates. Specify the full path to the client certificates on your system.</p><p></p><p>The file naming convention for client certificates in BNC is as follows: &lt;hostname&gt;.&lt;port&gt;.crt for the certificate and &lt;hostname&gt;.&lt;port&gt;.key for the private key, where &lt;hostname&gt; is without https://. </p><p> If available, the client or personal authentication certificate is presented to the peer during the SSL handshake process. Password protected key files are not supported. </p><p>Don't try communication via two sided SSL if you are not sure whether this is supported by the involved Ntrip Broadcaster. </p><p>Note that SSL communication is usually done over port 443. <i>[key: sslClientCertPath]</i></p>"));
    1464     _sslIgnoreErrorsCheckBox->setWhatsThis(tr("<p>SSL communication may involve queries coming from the Ntrip Broadcaster. Tick 'Ignore SSL authorization errors' if you don't want to be bothered with this. <i>[key: sslIgnoreErrors]</i></p>"));
    1465 
    1466     // WhatsThis, General
    1467     // ------------------
    1468     _logFileLineEdit->setWhatsThis(tr("<p>Records of BNC's activities are shown in the 'Log' tab on the bottom of this window. They can be saved into a file when a valid path for that is specified in the 'Logfile (full path)' field.</p><p>The logfile name will automatically be extended by a string '_YYMMDD' carrying the current date. <i>[key: logFile]</i></p>"));
    1469     _rnxAppendCheckBox->setWhatsThis(tr("<p>When BNC is started, new files are created by default and file content already available under the same name will be overwritten. However, users might want to append already existing files following a regular restart or a crash of BNC or its platform.</p><p>Tick 'Append files' to continue with existing files and keep what has been recorded so far. <i>[key: rnxAppend]</i></p>"));
    1470     _onTheFlyComboBox->setWhatsThis(tr("<p>When operating BNC online in 'no window' mode, some configuration parameters can be changed on-the-fly without interrupting the running process. For that BNC rereads parts of its configuration in pre-defined intervals. The default entry is 'no' that means the reread function is switched of. <p></p>Select '1 min', '5 min', '1 hour', or '1 day' to force BNC to reread its configuration every full minute, five minutes, hour, or day and let in between edited configuration options become effective on-the-fly without terminating uninvolved threads.</p><p>Note that when operating BNC in window mode, on-the-fly changeable configuration options become effective immediately via button 'Save & Reread Configuration'. <i>[key: onTheFlyInterval]</i></p>"));
    1471     _autoStartCheckBox->setWhatsThis(tr("<p>Tick 'Auto start' for auto-start of BNC at startup time in window mode with preassigned processing options. <i>[key: autoStart]</i></p>"));
    1472     _rawOutFileLineEdit->setWhatsThis(tr("<p>Save all data coming in through various streams in the received order and format in one file.</p><p>This option is primarily meant for debugging purposes. <i>[key: rawOutFile]</i></p>"));
    1473 
    1474     // WhatsThis, RINEX Observations
    1475     // -----------------------------
    1476     _rnxPathLineEdit->setWhatsThis(tr("<p>Here you specify the path to where the RINEX Observation files will be stored.</p><p>If the specified directory does not exist, BNC will not create RINEX Observation files. <i>[key: rnxPath]</i></p>"));
    1477     _rnxIntrComboBox->setWhatsThis(tr("<p>Select the length of the RINEX Observation file. <i>[key: rnxIntr]</i></p>"));
    1478     _rnxSamplComboBox->setWhatsThis(tr("<p>Select the RINEX Observation sampling interval in seconds. <i>[key: rnxSampl]</i></p>"));
    1479     _rnxSkelExtComboBox->setWhatsThis(tr("<p>BNC allows using personal RINEX skeleton files that contain the RINEX header records you would like to include. You can derive a skeleton file from information given in an up to date sitelog.</p><p>A file in the RINEX Observations 'Directory' with a 'Skeleton extension' skl or SKL is interpreted by BNC as a personal RINEX header skeleton file for the corresponding stream. <i>[key: rnxSkel]</i></p>"));
    1480     _rnxSkelPathLineEdit->setWhatsThis(tr("<p>Here you specify the path to where local skeleton files are located.</p><p> If no directory is specified, the path is assumed to where the RINEX Observation files will stored. <i>[key: rnxSkelPath]</i></p>"));
    1481     _rnxFileCheckBox->setWhatsThis(tr("<p>Tick check box 'Skeleton mandatory' in case you want that RINEX files are only produced if skeleton files are available for BNC. If no skeleton file is available for a particular source then no RINEX Observation file will be produced from the affected stream.</p><p>Note that a skeleton file contains RINEX header information such as receiver and antenna types. In case of stream conversion to RINEX Version 3, a skeleton file should also contain information on potentially available observation types. A missing skeleton file will therefore enforce BNC to only save a default set of RINEX 3 observation types. <i>[key: rnxOnlyWithSKL]</i></p>"));
    1482     _rnxScrpLineEdit->setWhatsThis(tr("<p>Whenever a RINEX Observation file is finally saved, you may want to compress, copy or upload it immediately, for example via FTP. BNC allows you to execute a script/batch file to carry out such operation.</p><p>Specify the full path of a script or batch file. BNC will pass the full RINEX Observation file path to the script as command line parameter (%1 on Windows systems, $1 on Unix/Linux/Mac systems). <i>[key: rnxScript]</i></p>"));
    1483     _rnxV2Priority->setWhatsThis(tr("<p>Specify a priority list of characters defining signal attributes as defined in RINEX Version 3. Priorities will be used to map observations with RINEX Version 3 attributes from incoming streams to Version 2. The underscore character '_' stands for undefined attributes. A question mark '?' can be used as wildcard which represents any one character.</p><p>Signal priorities can be specified as equal for all systems, as system specific or as system and freq. specific. For example: </li><ul><li>'CWPX_?' (General signal priorities valid for all GNSS) </li><li>'I:ABCX' (System specific signal priorities for NavIC) </li><li>'G:12&PWCSLX G:5&IQX R:12&PC R:3&IQX' (System and frequency specific signal priorities) </li></ul>Default is the following priority list 'G:12&PWCSLX G:5&IQX R:12&PC R:3&IQX R:46&ABX E:16&BCXZ E:578&IQX J:1&SLXCZ J:26&SLX J:5&IQX C:267&IQX C:18&DPX I:ABCX S:1&C S:5&IQX'. <i>[key: rnxV2Priority]</i></p>"));
    1484     _rnxVersComboBox->setWhatsThis(tr("<p>Select the format for RINEX Observation files. <i>[key: rnxVersion]</i></p>"));
    1485 
    1486     // WhatsThis, RINEX Ephemeris
    1487     // --------------------------
    1488     _ephPathLineEdit->setWhatsThis(tr("<p>Specify the path for saving Broadcast Ephemeris data as RINEX Navigation files.</p><p>If the specified directory does not exist, BNC will not create RINEX Navigation files. <i>[key: ephPath]</i></p>"));
    1489     _ephIntrComboBox->setWhatsThis(tr("<p>Select the length of the RINEX Navigation file. <i>[key: ephIntr]</i></p>"));
    1490     _ephOutPortLineEdit->setWhatsThis(tr("<p>BNC can produce ephemeris data in RINEX Navigation ASCII format on your local host through an IP port.</p><p>Specify a port number here to activate this function. <i>[key: ephOutPort]</i></p>"));
    1491     _ephVersComboBox->setWhatsThis(tr("<p>Select the format for RINEX Navigation files. <i>[key: ephVersion]</i></p>"));
    1492     //_ephFilePerStation->setWhatsThis(tr("<p>By default, all received Broadcast Ephemeris data will be stored within one File. Thick 'File per Stations' to get separate files per station/mountpoint. <i>[key: ephFilePerStation]</i></p>"));
    1493 
    1494     // WhatsThis, RINEX Editing & QC
    1495     // -----------------------------
    1496     _reqcActionComboBox->setWhatsThis(tr("<p>BNC allows to 'Edit or Concatenate' RINEX Version 2 or 3 files or to perform a Quality Check (QC) and 'Analyze' data following UNAVCO's famous 'teqc' program. <i>[key: reqcAction]</i></p>"));
    1497     _reqcEditOptionButton->setWhatsThis(tr("<p>Specify options for editing RINEX Version 2 or 3 files.</p>"));
    1498     _reqcObsFileChooser->setWhatsThis(tr("<p>Specify the full path to input observation files in RINEX Version 2 or 3 format.</p><p>Note that when in 'Analyze' mode, specifying at least one RINEX observation file is mandatory. <i>[key: reqcObsFile]</i></p>"));
    1499     _reqcNavFileChooser->setWhatsThis(tr("<p>Specify the full path to input navigation files in RINEX Version 2 or 3 format.</p><p>Note that when in 'Analyze' mode, specifying at least one RINEX navigation file is mandatory. <i>[key: reqcNavFile]</i></p>"));
    1500     _reqcOutObsLineEdit->setWhatsThis(tr("<p>Specify the full path to a RINEX Observation output file.</p><p>Default is an empty option field, meaning that no RINEX Observation output file will be produced. <i>[key: reqcOutObsFile]</i></p>"));
    1501     _reqcOutNavLineEdit->setWhatsThis(tr("<p>Specify the full path to a RINEX Navigation output file.</p><p>Default is an empty option field, meaning that no RINEX Navigation output file will be produced. <i>[key: reqcOutNavFile]</i></p>"));
    1502     _reqcOutLogLineEdit->setWhatsThis(tr("<p>Specify the full path to a logfile.</p><p>Default is an empty option field, meaning that no 'RINEX Editing & QC' logfile will be produced. <i>[key: reqcOutLogFile]</i></p>"));
    1503     _reqcLogSummaryOnly->setWhatsThis(tr("<p>By default BNC produces a detailed 'Logfile' providing all information resulting from editing or analyzing RINEX data. If that is too much information, you can limit the logfile content to a short summary.</p><p>Tick 'Summary only' to suppress full logfile output and instead produce a logfile containing only summary information. <i>[key: reqcLogSummaryOnly]</i></p>"));
    1504     _reqcPlotDirLineEdit->setWhatsThis(tr("<p>Specify a directory for saving plots in PNG format.</p><p>Default is an empty option field, meaning that plots will not be saved on disk. <i>[key: reqcPlotDir]</i></p>"));
    1505     _reqcSkyPlotSignals->setWhatsThis(tr("<p>BNC can produce plots for multipath, signal-to-noise ratio, satellite availability, satellite elevation, and PDOP values. The 'Plots for signals' option lets you exactly specify observation signals to be used for that and also enables the plot generation. You can specify the navigation system, the frequency, and the tracking mode or channel as defined in RINEX Version 3. Specifications for frequency and tracking mode or channel must be separated by ampersand character '&'. Specifications for navigation systems must be separated by blank character ' '.</p><p>Examples for 'Plots for signals' option:<ul><li> G:1&2&5 R:1&2&3 E:1&7 C:2&6 J:1&2 I:5&9 S:1&5 <br>(Plots will be based on GPS observations on 1st and 2nd frequency, GLONASS observations on 1st and 2nd frequency, QZSS observations on 1st and 2nd frequency, Galileo observations on 1st and 7th frequency, BeiDou observations on 1st and 6th frequency, SBAS observations on 1st frequency.)</li><li>G:1C&5X<br>(Plots will be based on GPS observations on 1st frequency in C tracking mode and GPS observations on 5th frequency in X tracking mode.)</li><li>C:6I&7I<br>(Plots will be based on BeiDou observations on 6th frequency in I tracking mode and BeiDou observations on 7th frequency in I tracking mode.)<li></ul></p><p>Default is 'G:1&2 R:1&2 E:1&5 C:2&6 J:1&2 I:5&9 S:1&5'. Specifying an empty option string would be overruled by this default. <i>[key: reqcSkyPlotSignals]</i></p>"));
    1506 
    1507     // WhatsThis, SP3 Comparison
    1508     // -------------------------
    1509     _sp3CompFileChooser->setWhatsThis(tr("<p>BNC can compare two SP3 files containing GNSS satellite orbit and clock information.</p></p>Specify the full path to two files with orbits and clocks in SP3 format, separate them by comma. <i>[key: sp3CompFile]</i></p>"));
    1510     _sp3CompExclude->setWhatsThis(tr("<p>Specify satellites to exclude them from orbit and clock comparison. Example:<p>G04,G31,R</p><p>This excludes GPS satellites PRN 4 and 31 as well as all GLONASS satellites from the comparison.</p><p>Default is an empty option field, meaning that no satellite is excluded from the comparison. <i>[key: sp3CompExclude]</i></p>"));
    1511     _sp3CompLogLineEdit->setWhatsThis(tr("<p>Specify the full path to a logfile saving comparison results.</p><p>Specifying a logfile is mandatory. Comparing SP3 files and not saving comparison results on disk would be useless. <i>[key: sp3CompOutLogFile]</i></p>"));
    1512     _sp3CompSummaryOnly->setWhatsThis(tr("<p>By default BNC produces a detailed 'Logfile' providing all information resulting from comparing SP3 files. If that is too much information, you can limit the logfile content to a short summary.</p><p>Tick 'Summary only' to suppress full logfile output and instead produce a logfile containing only summary information. <i>[key: sp3CompSummaryOnly]</i></p>"));
    1513 
    1514     // WhatsThis, Broadcast Corrections
    1515     // --------------------------------
    1516     _corrPathLineEdit->setWhatsThis(tr("<p>Specify a directory for saving Broadcast Ephemeris Correction files.</p><p>If the specified directory does not exist, BNC will not create the files. <i>[key: corrPath]</i></p>"));
    1517     _corrIntrComboBox->setWhatsThis(tr("<p>Select the length of Broadcast Ephemeris Correction files. <i>[key: corrIntr]</i></p>"));
    1518     _corrPortLineEdit->setWhatsThis(tr("<p>BNC can produce Broadcast Ephemeris Corrections on your local host through an IP port.</p><p>Specify a port number here to activate this function. <i>[key: corrPort]</i></p>"));
    1519 
    1520     // WhatsThis, Feed Engine
    1521     // ----------------------
    1522     _outPortLineEdit->setWhatsThis(tr("<p>BNC can produce synchronized observations in a plain ASCII format on your local host via IP port.</p><p>Specify a port number to activate this function. <i>[key: outPort]</i></p>"));
    1523     _outWaitSpinBox->setWhatsThis(tr("<p>When feeding a real-time GNSS network engine waiting for synchronized input epoch by epoch, BNC drops whatever is received later than 'Wait for full obs epoch' seconds.</p><p>A value of 3 to 5 seconds is recommended, depending on the latency of the incoming streams and the delay acceptable to your real-time GNSS network engine or product. <i>[key: outWait]</i></p>"));
    1524     _outSamplComboBox->setWhatsThis(tr("<p>Select a synchronized observation sampling interval in seconds. <i>[key: outSampl]</i></p>"));
    1525     _outFileLineEdit->setWhatsThis(tr("<p>Specify the full path to a file where synchronized observations are saved in plain ASCII format.</p><p>Beware that the size of this file can rapidly increase depending on the number of incoming streams. <i>[key: outFile]</i></p>"));
    1526     _outUPortLineEdit->setWhatsThis(tr("<p>BNC can produce unsynchronized observations in a plain ASCII format on your local host via IP port.</p><p>Specify a port number to activate this function. <i>[key: outUPort]</i></p>"));
    1527     _outLockTimeCheckBox->setWhatsThis(tr("<p>Print the lock time in seconds in the feed engine output.<i>[key: outLockTime]</i></p>"));
    1528 
    1529     // WhatsThis, Serial Output
    1530     // ------------------------
    1531     _serialMountPointLineEdit->setWhatsThis(tr("<p>Enter a 'Mountpoint' to forward the corresponding stream to a serial connected receiver.</p><p>Depending on the stream content, the receiver may use it for example for Differential GNSS, Precise Point Positioning or any other purpose supported by its firmware. <i>[key: serialMountPoint]</i></p>"));
    1532     _serialPortNameLineEdit->setWhatsThis(tr("<p>Enter the serial 'Port name' selected for communication with your serial connected receiver. Valid port names are e.g.</p><pre>Windows:       COM1, COM2<br>Linux:         /dev/ttyS0, /dev/ttyS1<br>FreeBSD:       /dev/ttyd0, /dev/ttyd1<br>Digital Unix:  /dev/tty01, /dev/tty02<br>HP-UX:         /dev/tty1p0, /dev/tty2p0<br>SGI/IRIX:      /dev/ttyf1, /dev/ttyf2<br>SunOS/Solaris: /dev/ttya, /dev/ttyb</pre><p>Note that before you start BNC, you must plug a serial cable in the port defined here. <i>[key: serialPortName]</i></p>"));
    1533     _serialBaudRateComboBox->setWhatsThis(tr("<p>Select a 'Baud rate' for the serial output link.</p><p>Note that your selection must equal the baud rate configured to the serial connected receiver. Using a high baud rate is recommended. <i>[key: serialBaudRate]</i></p>"));
    1534     _serialFlowControlComboBox->setWhatsThis(tr("<p>Select a 'Flow control' for the serial output link.</p><p>Note that your selection must equal the flow control configured to the serial connected receiver. Select 'OFF' if you don't know better. <i>[key: serialFlowControl]</i></p>"));
    1535     _serialDataBitsComboBox->setWhatsThis(tr("<p>Select the number of 'Data bits' for the serial output link.</p><p>Note that your selection must equal the number of data bits configured to the serial connected receiver. Note further that often 8 data bits are used. <i>[key: serialDataBits]</i></p>"));
    1536     _serialParityComboBox->setWhatsThis(tr("<p>Select a 'Parity' for the serial output link.</p><p>Note that your selection must equal the parity selection configured to the serial connected receiver. The parity is often set to 'NONE'. <i>[key: serialParity]</i></p>"));
    1537     _serialStopBitsComboBox->setWhatsThis(tr("<p>Select the number of 'Stop bits' for the serial output link.</p><p>Note that your selection must equal the number of stop bits configured to the serial connected receiver. Note further that often 1 stop bit is used. <i>[key: serialStopBits]</i></p>"));
    1538     _serialAutoNMEAComboBox->setWhatsThis(tr("<p>The 'NMEA' option supports the so-called 'Virtual Reference Station' (VRS) concept which requires the receiver to send approximate position information to the Ntrip Broadcaster. Select 'no' if you don't want BNC to forward or upload any NMEA message to the Ntrip Broadcaster in support of VRS.</p><p>Select 'Auto' to automatically forward NMEA messages of type GGA from your serial connected receiver to the Ntrip Broadcaster and/or save them in a file.</p><p>Select 'Manual GPGGA' or 'Manual GNGGA' if you want BNC to produce and upload GPGGA or GNGGA NMEA messages to the Ntrip Broadcaster because your serial connected receiver doesn't generate these messages. A Talker ID 'GP' preceding the GGA string stands for GPS solutions while a Talker ID 'GN' stands for multi constellation solutions.</p><p>Note that selecting 'Auto' or 'Manual' works only for VRS streams which show up under the 'Streams' canvas on BNC's main window with 'nmea' stream attribute set to 'yes'. This attribute is either extracted from the Ntrip Broadcaster's source-table or introduced by the user via editing the BNC configuration file. <i>[key: serialAutoNMEA]</i></p>"));
    1539     _serialFileNMEALineEdit->setWhatsThis(tr("<p>Specify the full path to a file where NMEA messages coming from your serial connected receiver are saved.</p><p>Default is an empty option field, meaning that NMEA messages will not be saved on disk. <i>[key: serialFileNMEA]</i></p>"));
    1540     _serialHeightNMEALineEdit->setWhatsThis(tr("<p>Specify an approximate 'Height' above mean sea level in meters for the reference station introduced by option 'Mountpoint'. Together with the latitude and longitude from the source-table, the height information is used to build GGA messages to be sent to the Ntrip Broadcaster.</p><p>For adjusting latitude and longitude values of a VRS stream given in the 'Streams' canvas, you can double click the latitude/longitude data fields, specify appropriate values and then hit Enter.</p><p>This option is only relevant when option 'NMEA' is set to 'Manual GPGGA' or 'Manual GNGGA' respectively. <i>[key: serialHeightNMEA]</i></p>"));
    1541     _serialNMEASamplingSpinBox->setWhatsThis(tr("<p>Select a sampling interval in seconds for manual or receiver generated NMEA GGA sentences and their upload.</p><p>A sampling rate of '0' means, a GGA sentence will be send only once to initialize the requested VRS stream. Note that some VRS systems need GGA sentences at regular intervals. <i>[key: serialNMEASampling]</i></p>"));
    1542 
    1543     // WhatsThis, Outages
    1544     // ------------------
    1545     _adviseObsRateComboBox->setWhatsThis(tr("<p>BNC can collect all returns (success or failure) coming from a decoder within a certain short time span to then decide whether a stream has an outage or its content is corrupted. The procedure needs a rough estimate of the expected 'Observation rate' of the incoming streams. When a continuous problem is detected, BNC can inform its operator about this event through an advisory note.</p><p>Default is an empty option field, meaning that you don't want BNC to report on stream failures or recoveries when exceeding a threshold time span. <i>[key: adviseObsRate]</i></p>"));
    1546     _adviseFailSpinBox->setWhatsThis(tr("<p>An advisory note is generated when no (or only corrupted) observations are seen throughout the 'Failure threshold' time span. A value of 15 min (default) is recommended.</p><p>A value of zero '0' means that for any stream failure, however short, BNC immediately generates an advisory note. <i>[key: adviseFail]</i></p>"));
    1547     _adviseRecoSpinBox->setWhatsThis(tr("<p>Following a stream outage or a longer series of bad observations, an advisory note is generated when valid observations are received again throughout the 'Recovery threshold' time span. A value of about 5min (default) is recommended.</p><p>A value of zero '0' means that for any stream recovery, however short, BNC immediately generates an advisory note. <i>[key: adviseReco]</i></p>"));
    1548     _adviseScriptLineEdit->setWhatsThis(tr("<p>Specify the full path to a script or batch file to handle advisory notes generated in the event of corrupted streams or stream outages. The affected mountpoint and a comment 'Begin_Outage', 'End_Outage', 'Begin_Corrupted', or 'End_Corrupted' are passed on to the script as command line parameters.</p><p>The script may have the task to send the advisory notes by email to BNC's operator and/or to the affected stream provider.</p><p>An empty option field (default) or invalid path means that you don't want to use this option. <i>[key: adviseScript]</i></p>"));
    1549 
    1550     // WhatsThis, Miscellaneous
    1551     // ------------------------
    1552     _miscMountLineEdit->setWhatsThis(tr("<p>Specify a mountpoint to apply any of the options shown below. Enter 'ALL' if you want to apply these options to all configured streams.</p><p>An empty option field (default) means that you don't want BNC to apply any of these options. <i>[key: miscMount]</i></p>"));
    1553     _miscIntrComboBox->setWhatsThis(tr("<p>BNC can average latencies per stream over a certain period of GPS time. The resulting mean latencies are recorded in the 'Log' tab at the end of each 'Log latency' interval together with results of a statistical evaluation (approximate number of covered epochs, data gaps).</p><p>Select a 'Log latency' interval or select the empty option field if you do not want BNC to log latencies and statistical information. <i>[key: miscIntr]</i></p>"));
    1554     _miscScanRTCMCheckBox->setWhatsThis(tr("<p>Tick 'Scan RTCM' to log the numbers of incoming message types as well as contained antenna coordinates, antenna height, and antenna descriptor.</p><p>In case of RTCM Version 3 MSM streams, BNC will also log contained RINEX Version 3 observation types. <i>[key: miscScanRTCM]</i></p>"));
    1555     _miscPortLineEdit->setWhatsThis(tr("<p>BNC can output an incoming stream through an IP port of your local host.</p><p>Specify a port number to activate this function. In this case, the stream content remains untouched; BNC does not decode or reformat the data for this output.</p><p> If the decoder string is not an accepted one ('RTCM_2.x', 'RTCM_3.x' and 'RTNET'), please change the decoder string to <ul>"
    1556         "<li> 'ZERO' (forward the raw data) or </li>"
    1557         "<li> 'ZERO2FILE' (forward and store the raw data)</li> </ul> in addition. <i>[key: miscPort]</i></p>"));
    1558 
    1559     // WhatsThis, PPP (1)
    1560     // ------------------
    1561     _pppWidgets._dataSource->setWhatsThis(tr("<p>Select 'Real-time Streams' for real-time PPP from RTCM streams or 'RINEX Files' for post processing PPP from RINEX files.</p><p><ul><li>Real-time PPP requires that you pull a RTCM stream carrying GNSS observations plus a stream providing corrections to Broadcast Ephemeris. If the observations stream does not contain Broadcast Ephemeris then you must in addition pull a Broadcast Ephemeris stream like 'RTCM3EPH' from Ntrip Broadcaster <u>products.igs-ip.net</u>.<br></li><li>Post processing PPP requires RINEX Observation files, RINEX Navigation files and a file with corrections to Broadcast Ephemeris in plain ASCII format as saved beforehand using BNC.</li></ul></p><p>Note that BNC allows to carry out PPP solutions simultaneously for several stations. <i>[key: PPP/dataSource]</i></p>"));
    1562     _pppWidgets._rinexObs->setWhatsThis(tr("<p>Specify the RINEX Observation file. <i>[key: PPP/rinexObs]</i></p>"));
    1563     _pppWidgets._rinexNav->setWhatsThis(tr("<p>Specify the RINEX Navigation file. <i>[key: PPP/rinexNav]</i></p>"));
    1564     _pppWidgets._corrMount->setWhatsThis(tr("<p>Specify a 'mountpoint' from the 'Streams' canvas below which provides corrections to Broadcast Ephemeris.</p><p>If you don't specify a corrections stream via this option, BNC will fall back to Single Point Positioning (SPP, positioning from observations and Broadcast Ephemeris only) instead of doing PPP. <i>[key: PPP/corrMount]</i></p>"));
    1565     _pppWidgets._ionoMount->setWhatsThis(tr("<p>Specify a 'mountpoint' from the 'Streams' canvas below which provides VTEC informations in SSR format.</p><p>If you don't specify a corrections stream via this option, BNC will use VTEC informations from the Corrections stream 'mountpoint', if available. <i>[key: PPP/ionoMount]</i></p>"));
    1566     _pppWidgets._corrFile->setWhatsThis(tr("<p>Specify the Broadcast Ephemeris Corrections file as saved beforehand using BNC.</p><p>If you don't specify corrections by this option, BNC will fall back to Single Point Positioning (SPP, positioning from RINEX Obs and RINEX Nav files only) instead of doing PPP. <i>[key: PPP/corrFile]</i></p>"));
    1567     _pppWidgets._ionoFile->setWhatsThis(tr("<p>Specify the VTEC file as saved beforehand using BNC.</p><p>If you don't specify corrections by this option, BNC will use VTEC informations from the Corrections file, if available. <i>[key: PPP/ionoFile]</i></p>"));
    1568     _pppWidgets._antexFile->setWhatsThis(tr("<p>Observations in RTCM streams or RINEX files should be referred to the receiver's and to the satellite's Antenna Phase Center (APC) and therefore be corrected for<ul><li>Receiver APC offsets and variations</li><li>Satellite APC offsets and variations.</li></ul> Specify the full path to an IGS 'ANTEX file' which contains APC offsets and variations for satellites and receiver.</p> <i>[key: PPP/antexFile]</i></p>"));
    1569     _pppWidgets._crdFile->setWhatsThis(tr("<p>Enter the full path to an ASCII file which specifies the streams or files of those stations you want to process. Specifying a 'Coordinates file' is optional. If it exists, it should contain one record per station with the following parameters separated by blank character:</p><ul><li>Specify the station either by:<ul><li>the 'Mountpoint' of the station's RTCM stream (in real-time PPP mode), or</li><li>the 9-char station ID of the RINEX Version 3 or 4 Observations file (in post processing PPP mode), or </li><li>the 4-char station ID of the RINEX Version 2 Observations file (in post processing PPP mode).</li></ul><li>Approximate X,Y,Z coordinate of station's Antenna Reference Point [m] (ARP, specify '0.0 0.0 0.0' if unknown).</li><li>North, East and Up component of antenna eccentricity [m] (specify '0.0 0.0 0.0' if unknown). </li><li>20 Characters describing the antenna type and radome following the IGS 'ANTEX file' standard (leave blank if unknown).</li><li>Receiver type following the naming conventions for IGS equipment.</li></ul>Records with exclamation mark '!' in the first column or blank records will be interpreted as comment lines and ignored.. <i>[key: PPP/crdFile]</i></p>"));
    1570     _pppWidgets._blqFile->setWhatsThis(tr("<p>Specify the full path to a 'BLQ file' containing the ocean loading coefficients for different stations. These coefficients can be obtained from the ocean loading service under request trough the web site http://holt.oso.chalmers.se/loading/. <i>[key: PPP/blqFile]</i></p>"));
    1571     _pppWidgets._logPath->setWhatsThis(tr("<p>Specify a directory for saving daily PPP logfiles. If the specified directory does not exist, BNC will not create such files.</p><p>Default is an empty option field, meaning that no PPP logfiles shall be produced. <i>[key: PPP/logPath]</i></p>"));
    1572     _pppWidgets._nmeaPath->setWhatsThis(tr("<p>Specify a directory for saving coordinates in daily NMEA files. If the specified directory does not exist, BNC will not create such files.</p><p>Default is an empty option field, meaning that no NMEA file shall be produced. <i>[key: PPP/nmeaPath]</i></p>"));
    1573     _pppWidgets._snxtroPath->setWhatsThis(tr("<p>Specify a directory for saving SINEX Troposphere files. If the specified directory does not exist, BNC will not create such files.</p><p>Default is an empty option field, meaning that no SINEX Troposphere files shall be produced. <i>[key: PPP/snxtroPath]</i></p>"));
    1574     _pppWidgets._snxtroIntr->setWhatsThis(tr("<p>Select a length for SINEX Troposphere files.</p><p>Default 'SNX TRO interval' for saving SINEX Troposphere files on disk is '1 hour'. <i>[key: PPP/snxtroIntr]</i></p>"));
    1575     _pppWidgets._snxtroSampl->setWhatsThis(tr("<p>Select a 'Sampling' rate for saving troposphere parameters. <i>[key: PPP/snxtroSampl]</i></p>"));
    1576     _pppWidgets._snxtroAc->setWhatsThis(tr("<p>Specify a 3-character abbreviation describing you as the generating Analysis Center (AC) in your SINEX troposphere files. <i>[key: PPP/snxtroAc]</i></p>"));
    1577     _pppWidgets._snxtroSolId->setWhatsThis(tr("<p>Specify a 1-character solution ID to allow a distinction between different solutions per AC. <i>[key: PPP/snxtroSolId]</i></p>"));
    1578     _pppWidgets._snxtroSolType->setWhatsThis(tr("<p>Specify a 3-character solution type, e.g. real-time (RTS), unknown (UNK), .. <i>[key: PPP/snxtroSolType]</i></p>"));
    1579     _pppWidgets._snxtroCampId->setWhatsThis(tr("<p>Specify a 3-character campaign ID, e.g. operational (OPS), demonstration (DEM), testing (TST), .. <i>[key: PPP/snxtroCampId]</i></p>"));
    1580 
    1581     // WhatsThis, PPP (2)
    1582     // ------------------
    1583     _pppWidgets._lcGPS->setWhatsThis(tr("<p>Specify which kind of GPS observations you want to use and on which kind of linear combination the GPS ambiguity resolutions shall be based:</p><p><ul>"
    1584 #ifdef USE_PPP_SSR_I
    1585         "<li>'P3&L3' means that the inonosphere-free linear combination of code and phase data shall be used.</li>"
    1586         "<li>'P3'    means that the inonosphere-free linear combination of code data shall be used.</li>"
    1587 #else
    1588         "<li>'Pi&Li' means that uncombined code and phase data of two frequencies shall be used.</li>"
    1589         "<li>'Pi'    means that uncombined code data of two frequencies shall be used.</li>"
    1590         "<li>'P1&L1' means that uncombined code and phase data of one frequency shall be used.</li>"
    1591         "<li>'P1'    means that uncombined code data of one frequency shall be used.</li>"
    1592         "<li>'P3&L3' means that the inonosphere-free linear combination of code and phase data shall be used.</li>"
    1593         "<li>'P3'    means that the inonosphere-free linear combination of code data shall be used.</li>"
    1594         "<li>'L3'    means that the inonosphere-free linear combination of phase data shall be used.</li> "
    1595 #endif
    1596         "<li>'no'    means that you don't want BNC to use GPS data.</li></ul></p><p><i>[key: PPP/lcGPS]</i></p>"));
    1597     _pppWidgets._lcGLONASS->setWhatsThis(tr("<p>Specify which kind of GLONASS observations you want to use and on which kind of linear combination the GLONASS ambiguity resolutions shall be based:</p><p><ul>"
    1598 #ifdef USE_PPP_SSR_I
    1599         "<li>'P3&L3' means that the inonosphere-free linear combination of code and phase data shall be used.</li>"
    1600         "<li>'P3'    means that the inonosphere-free linear combination of code data shall be used.</li>"
    1601         "<li>'L3'    means that the inonosphere-free linear combination of phase data shall be used.</li> "
    1602 #else
    1603         "<li>'Pi&Li' means that uncombined code and phase data of two frequencies shall be used.</li>"
    1604         "<li>'Pi'    means that uncombined code data of two frequencies shall be used.</li>"
    1605         "<li>'P1&L1' means that uncombined code and phase data of one frequency shall be used.</li>"
    1606         "<li>'P1'    means that uncombined code data of one frequency shall be used.</li>"
    1607         "<li>'P3&L3' means that the inonosphere-free linear combination of code and phase data shall be used.</li>"
    1608         "<li>'P3'    means that the inonosphere-free linear combination of code data shall be used.</li>"
    1609         "<li>'L3'    means that the inonosphere-free linear combination of phase data shall be used.</li> "
    1610 #endif
    1611         "<li>'no'    means that you don't want BNC to use GLONASS data.</li></ul></p><p><i>[key: PPP/lcGLONASS]</i></p>"));
    1612     _pppWidgets._lcGalileo->setWhatsThis(tr("<p>Specify which kind of Galileo observations you want to use and on which kind of linear combination the Galileo ambiguity resolutions shall be based:</p><p><ul>"
    1613 #ifdef USE_PPP_SSR_I
    1614         "<li>'P3&L3' means that the inonosphere-free linear combination of code and phase data shall be used.</li>"
    1615         "<li>'P3'    means that the inonosphere-free linear combination of code data shall be used.</li>"
    1616         "<li>'L3'    means that the inonosphere-free linear combination of phase data shall be used.</li> "
    1617 #else
    1618         "<li>'Pi&Li' means that uncombined code and phase data of two frequencies shall be used.</li>"
    1619         "<li>'Pi'    means that uncombined code data of two frequencies shall be used.</li>"
    1620         "<li>'P1&L1' means that uncombined code and phase data of one frequency shall be used.</li>"
    1621         "<li>'P1'    means that uncombined code data of one frequency shall be used.</li>"
    1622         "<li>'P3&L3' means that the inonosphere-free linear combination of code and phase data shall be used.</li>"
    1623         "<li>'P3'    means that the inonosphere-free linear combination of code data shall be used.</li>"
    1624         "<li>'L3'    means that the inonosphere-free linear combination of phase data shall be used.</li> "
    1625 #endif
    1626         "<li>'no'    means that you don't want BNC to use Galileo data.</li></ul></p><p><i>[key: PPP/lcGalileo]</i></p>"));
    1627     _pppWidgets._lcBDS->setWhatsThis(tr("<p>Specify which kind of BDS observations you want to use and on which kind of linear combination the BDS ambiguity resolutions shall be based:</p><p><ul>"
    1628 #ifdef USE_PPP_SSR_I
    1629         "<li>'P3&L3' means that the inonosphere-free linear combination of code and phase data shall be used.</li>"
    1630         "<li>'P3'    means that the inonosphere-free linear combination of code data shall be used.</li>"
    1631         "<li>'L3'    means that the inonosphere-free linear combination of phase data shall be used.</li> "
    1632 #else
    1633         "<li>'Pi&Li' means that uncombined code and phase data of two frequencies shall be used.</li>"
    1634         "<li>'Pi'    means that uncombined code data of two frequencies shall be used.</li>"
    1635         "<li>'P1&L1' means that uncombined code and phase data of one frequency shall be used.</li>"
    1636         "<li>'P1'    means that uncombined code data of one frequency shall be used.</li>"
    1637         "<li>'P3&L3' means that the inonosphere-free linear combination of code and phase data shall be used.</li>"
    1638         "<li>'P3'    means that the inonosphere-free linear combination of code data shall be used.</li>"
    1639         "<li>'L3'    means that the inonosphere-free linear combination of phase data shall be used.</li> "
    1640 #endif
    1641         "<li>'no'    means that you don't want BNC to use BDS data.</li></ul></p><p><i>[key: PPP/lcBDS]</i></p>"));
    1642     _pppWidgets._constraints->setWhatsThis(tr("<p>Specify, whether ionospheric constraints in form of pseudo-observations shall be added. Please note, this is only valid, if no ionosphere-free linear-combination is used and only helpful as soon as the ionosphere information is more accurate than the code data accuracy. <i>[key: PPP/constraints]</i></p>"));
    1643     _pppWidgets._sigmaC1->setWhatsThis(tr("<p>Enter a Sigma for GPS C1 code observations in meters.</p><p>The higher the sigma you enter, the less the contribution of GPS C1 code observations to a PPP solution from combined code and phase data. 1.0 is likely to be an appropriate choice.</p><p>Default is an empty option field, meaning<br>'Sigma C1 = 1.0' <i>[key: PPP/sigmaC1]</i></p>"));
    1644     _pppWidgets._sigmaL1->setWhatsThis(tr("<p>Enter a Sigma for GPS L1 phase observations in meters.</p><p>The higher the sigma you enter, the less the contribution of GPS L1 phase observations to a PPP solutions from combined code and phase data. 0.01 is likely to be an appropriate choice.</p><p>Default is an empty option field, meaning<br>'Sigma L1 = 0.01' <i>[key: PPP/sigmaL1]</i></p>"));
    1645 #ifdef USE_PPP
    1646     _pppWidgets._sigmaGIM->setWhatsThis(tr("<p>Enter a Sigma for GIM pseudo observations in meters.</p><p>The higher the sigma you enter, the less the contribution of GIM pseudo observations to a PPP solution. 5.0 is likely to be an appropriate choice.</p><p>Default is an empty option field, meaning<br>'Sigma GIM = 1.0' <i>[key: PPP/sigmaGIM]</i></p>"));
    1647 #endif
    1648     _pppWidgets._maxResC1->setWhatsThis(tr("<p>Specify a maximum for residuals from GPS C1 code observations in a PPP solution. '2.0' meters may be an appropriate choice for that.</p><p>If the maximum is exceeded, contributions from the corresponding observation will be ignored in the PPP solution.</p><p>Default is an empty option field, meaning<br>'Max Res C1 = 3.0' <i>[key: PPP/maxResC1]</i></p>"));
    1649     _pppWidgets._maxResL1->setWhatsThis(tr("<p>Specify a maximum for residuals from GPS L1 phase observations in a PPP solution. '0.02' meters may be an appropriate choice for that.</p><p>If the maximum is exceeded, contributions from the corresponding observation will be ignored in the PPP solution.</p><p>Default is an empty option field, meaning<br>'Max Res L1 = 0.03' <i>[key: PPP/maxResL1]</i></p>"));
    1650 #ifdef USE_PPP
    1651     _pppWidgets._maxResGIM->setWhatsThis(tr("<p>Specify a maximum for residuals from GIM pseudo observations in a PPP solution. '5.0' meters may be an appropriate choice for that.</p><p>If the maximum is exceeded, contributions from the corresponding observation will be ignored in the PPP solution.</p><p>Default is an empty option field, meaning<br>'Max Res GIM = 3.0' <i>[key: PPP/maxResGIM]</i></p>"));
    1652 #endif
    1653     _pppWidgets._eleWgtCode->setWhatsThis(tr("<p>Tic 'Ele Wgt Code' to use satellite Elevation depending Weights for Code observations in the PPP solution. <i>[key: PPP/eleWgtCode]</i></p>"));
    1654     _pppWidgets._eleWgtPhase->setWhatsThis(tr("<p>Tic 'Ele Wgt Phase' to use satellite Elevation depending Weights for Phase observations in the PPP solution. <i>[key: PPP/eleWgtPhase]</i></p>"));
    1655     _pppWidgets._minObs->setWhatsThis(tr("<p>Select a Minimum Number of Observations per epoch for a PPP solution.</p><p>BNC will only process epochs with observation numbers reaching or exceeding this minimum. <i>[key: PPP/minObs]</i></p>"));
    1656     _pppWidgets._minEle->setWhatsThis(tr("<p>Select a Minimum satellite Elevation for observations.</p><p>BNC will ignore an observation if the associated satellite Elevation does not reach or exceed this minimum.</p><p>Selecting '10 deg' may be an appropriate choice in order to avoid too noisy observations. <i>[key: PPP/minEle]</i></p>"));
    1657 
    1658     // WhatsThis, Combine Corrections
    1659     // ------------------------------
    1660     _cmbTable->setWhatsThis(tr("<p>BNC allows to process several orbit and clock correction streams in real-time to produce, encode, upload and save a combination of correctors coming from different providers. </p><p>To add a line to the 'Combine Corrections' table hit the 'Add Row' button, double click on the 'Mountpoint' field to specify a Broadcast Ephemeris Correction mountpoint from the 'Streams' section below and hit Enter. Then double click on the 'AC Name' field to enter your choice of an abbreviation for the Analysis Center (AC) providing the stream. Double click on the 'Weight Factor' field to enter a weight factor to be applied for this stream in the combination. A Factor greater than 1 will enlarge the sigma of the clock pseudo-observations and with it down-weight its contribution. Finally, double click on the 'Exclude Satellites' field and specify satellites, to exclude them for an individual AC. An entry 'G04,G31,R' means to excludes GPS satellites PRN 4 and 31 as well as all GLONASS satellites from one individual AC. Default is an empty option field, meaning that no satellite is excluded from this individual AC.</p><p>Note that the orbit information in the resulting combination stream is just copied from one of the incoming streams. The stream used for providing the orbits may vary over time: if the orbit providing stream has an outage then BNC switches to the next remaining stream for getting hold of the orbit information.</p><p>The combination process requires Broadcast Ephemeris. Besides orbit and clock correction streams BNC should therefore pull a stream carrying Broadcast Ephemeris in the form of RTCM Version 3 messages.</p><p>It is possible to specify only one Broadcast Ephemeris Correction stream in the 'Combine Corrections' table. Instead of combining corrections BNC will then add the corrections to the Broadcast Ephemeris with the possibility to save final orbit and clock results in SP3 and/or Clock RINEX format. <i>[key: cmbStreams]</i></p>"));
    1661     addCmbRowButton->setWhatsThis(tr("<p>Hit 'Add Row' button to add another line to the 'Combine Corrections' table.</p>"));
    1662     delCmbRowButton->setWhatsThis(tr("<p>Hit 'Delete' button to delete the highlighted line(s) from the 'Combine Corrections' table.</p>"));
    1663     _cmbMethodComboBox->setWhatsThis(tr("<p>Select a clock combination approach. Options are 'Single-Epoch' and Kalman 'Filter'.</p><p>It is suggested to use the Kalman filter approach for the purpose of Precise Point Positioning. <i>[key: cmbMethod]</i></p>"));
    1664     _cmbMaxresLineEdit->setWhatsThis(tr("<p>BNC combines all incoming clocks according to specified weights. Individual clock estimates that differ by more than 'Maximal Clk Residuum' meters from the average of all clocks will be ignored.<p></p>It is suggested to specify a value of about 0.2 m for the Kalman filter combination approach and a value of about 3.0 meters for the Single-Epoch combination approach.</p><p>Default is a value of '999.0'. <i>[key: cmbMaxres]</i></p>"));
    1665     _cmbMaxdisplacementLineEdit->setWhatsThis(tr("<p>BNC builds mean values for all incoming orbit corrections per satellite. Individual orbit corrections that differ by more than 'Maximal Orb Displacement' meters from the average of all orbit corrections per satellite will be ignored.<p></p>It is suggested to specify a value of about 0.5 m.</p><p>Default is a value of '2.0'. <i>[key: cmbMaxdisplacement]</i></p>"));
    1666     _cmbSamplComboBox->setWhatsThis(tr("<p>Select a combination Sampling interval for the clocks. Clock corrections will be produced following that interval.</p><p>A value of 10 sec may be an appropriate choice. <i>[key: cmbSampl]</i></p>"));
    1667     _cmbLogPath->setWhatsThis(tr("<p>Specify a directory for saving daily Combination logfiles. If the specified directory does not exist, BNC will not create such files.</p><p>Default is an empty option field, meaning that no Combination logfiles shall be produced. <i>[key: cmbLogpath]</i></p>"));
    1668     _cmbGpsCheckBox->setWhatsThis(tr("<p>GPS clock corrections shall be combined. GPS Broadcast ephemeris and corrections are required. <i>[key: cmbGps]</i></p>"));
    1669     _cmbGloCheckBox->setWhatsThis(tr("<p>GLONASS clock corrections shall be combined; GLONASS Broadcast ephemeris and corrections are required. <i>[key: cmbGlo]</i></p>"));
    1670     _cmbGalCheckBox->setWhatsThis(tr("<p>Galileo clock corrections shall be combined; Galileo Broadcast ephemeris and corrections are required. <i>[key: cmbGal]</i></p>"));
    1671     _cmbBdsCheckBox->setWhatsThis(tr("<p>Beidou clock corrections shall be combined; BDS Broadcast ephemeris and corrections are required. <i>[key: cmbBds]</i></p>"));
    1672     _cmbQzssCheckBox->setWhatsThis(tr("<p>QZSS clock corrections shall be combined; QZSS Broadcast ephemeris and corrections are required. <i>[key: cmbQzss]</i></p>"));
    1673     _cmbSbasCheckBox->setWhatsThis(tr("<p>SBAS clock corrections shall be combined; SBAS Broadcast ephemeris and corrections are required. <i>[key: cmbSbas]</i></p>"));
    1674     _cmbNavicCheckBox->setWhatsThis(tr("<p>NavIC clock corrections shall be combined; NavIC Broadcast ephemeris and corrections are required. <i>[key: cmbNavic]</i></p>"));
    1675     _cmbBsxFile->setWhatsThis(tr("<p> Specify a Bias SINEX File that will be used to add satellite code biases to the combined clocks. <i>[key: cmbBsxFile]</i></p>"));
    1676 
    1677     // WhatsThis, Upload Corrections
    1678     // -----------------------------
    1679     _uploadTable->setWhatsThis(tr("<p>BNC can upload clock and orbit corrections to Broadcast Ephemeris (Broadcast Corrections) as well as Code Biases in different SSR formats. You may have a situation where clocks, orbits and code biases come from an external Real-time Network Engine (1) or a situation where clock and orbit corrections are combined within BNC (2).</p><p>(1) BNC identifies a stream as coming from a Real-time Network Engine if its format is specified as 'RTNET' and hence its decoder string in the 'Streams' canvas is 'RTNET'. It encodes and uploads that stream to the specified Ntrip Broadcaster Host and Port</p><p>(2) BNC understands that it is expected to encode and upload combined Broadcast Ephemeris Corrections if you specify correction streams in the 'Combine Corrections' table.</p><p>To fill the 'Upload Corrections' table, hit the 'Add Row' button, double click on the 'Host' field to enter the IP or URL of an Ntrip Broadcaster and hit Enter. Select the Ntrip Version that shall be used for data upload. Then double click on the 'Port', 'Mountpoint' and 'Password' fields to enter the Ntrip Broadcaster IP port, the mountpoint and the stream upload password. If Ntrip Version 2 is chosen, click to the 'User' field to enter a stream upload user name. An empty 'Host' option field means that you don't want to upload corrections.</p><p>Select a target coordinate reference System (e.g. IGS20) for outgoing clock and orbit corrections.</p><p>Select a target SSR format (e.g. IGS-SSR) for outgoing clock and orbit corrections.</p><p>By default orbit and clock corrections refer to Antenna Phase Center (APC). Tick 'CoM' to refer uploaded corrections to Center of Mass instead of APC.</p><p>Specify a path for saving generated Broadcast Corrections plus Broadcast Ephemeris as SP3 orbit files. If the specified directory does not exist, BNC will not create such files. The following is a path example for a Linux system: /home/user/BKG0MGXRTS${V3PROD}.SP3.</p><p>Specify a path for saving generated Broadcast Correction clocks plus Broadcast Ephemeris clocks as Clock RINEX files. If the specified directory does not exist, BNC will not create Clock RINEX files. The following is a path example for a Linux system: /home/user/BKG0MGXRTS${V3PROD}.CLK.</p><p>Specify a path for saving generated Code Biases as SINEX Bias files. If the specified directory does not exist, BNC will not create SINEX Bias files. The following is a path example for a Linux system: /home/user/BKG0MGXRTS${V3PROD}.BIA.</p><p>Note that '${V3PROD}' produces the time stamp in the filename, which is related to the RINEX version 3 filename concept.</p><p>Finally, specify a SSR Provider ID (issued by RTCM), SSR Solution ID, and SSR Issue of Data number.</p><p>In case the 'Combine Corrections' table contains only one Broadcast Correction stream, BNC will add that stream content to the Broadcast Ephemeris to save results in files specified via SP3 and/or Clock RINEX file path. You should then define only the SP3 and Clock RINEX file path and no further option in the 'Upload Corrections' table. <i>[key: uploadMountpointsOut]</i></p>"));
    1680     addUploadRowButton->setWhatsThis(tr("<p>Hit 'Add Row' button to add another line to the 'Upload Corrections' table.</p>"));
    1681     delUploadRowButton->setWhatsThis(tr("<p>Hit 'Del Row' button to delete the highlighted line(s) from the 'Upload Corrections' table.</p>"));
    1682     _uploadIntrComboBox->setWhatsThis(tr("<p>Select the length of the SP3, Clock RINEX and Bias SINEX files. <i>[key: uploadIntr]</i></p>"));
    1683     _uploadSamplRtcmEphCorrComboBox->setWhatsThis(tr("<p>Select a stream's orbit correction sampling interval in seconds.</p><p>A value of zero '0' tells BNC to upload all available orbit and clock correction samples together in combined messages. <i>[key: uploadSamplRtcmEphCorr]</i></p>"));
    1684     _uploadSamplSp3ComboBox->setWhatsThis(tr("<p>Select a SP3 orbit file sampling interval in seconds.</p><p>A value of zero '0' tells BNC to store all available samples into SP3 orbit files. <i>[key: uploadSamplSp3]</i></p>"));
    1685     _uploadSamplClkRnxSpinBox->setWhatsThis(tr("<p>Select a Clock RINEX file sampling interval in seconds.</p><p>A value of zero '0' tells BNC to store all available samples into Clock RINEX files. <i>[key: uploadSamplClkRnx]</i></p>"));
    1686     _uploadSamplBiaSnxSpinBox->setWhatsThis(tr("<p>Select a Bias SINEX file sampling interval in seconds.</p><p>A value of zero '0' tells BNC to store all available samples into Bias SINEX files. <i>[key: uploadSamplBiaSnx]</i></p>"));
    1687     setUploadTrafoButton->setWhatsThis(tr("<p>Hit 'Custom Trafo' to specify your own 14 parameter Helmert Transformation instead of selecting a predefined transformation via option 'System'.</p>"));
    1688     _uploadAntexFile->setWhatsThis(tr("<p>When producing SP3 files or referring orbit and clock corrections to the satellite's Center of Mass (CoM) instead Antenna Phase Center (APC), an offset has to be applied which is available from the IGS 'ANTEX file'. You must therefore specify an 'ANTEX file' path if you want to save the stream content in SP3 format and/or refer correctors to CoM.</p><p>If you don't specify an 'ANTEX file' path, the SP3 file content as well as the orbit and clock correctors will be referred to satellite APCs. <i>[key: uploadAntexFile]</i></p>"));
    1689 
    1690     // WhatsThis, Upload Ephemeris
    1691     // ---------------------------
    1692     _uploadEphTable->setWhatsThis(tr("<p>BNC can upload Broadcast Ephemeris streams in RTCM Version 3 format. </p><p>To fill the 'Upload Ephemeris' table, hit the 'Add Row' button, double click on the 'Host' field to enter the IP or URL of an Ntrip Broadcaster and hit Enter. Select the Ntrip Version that shall be used for data upload. Then double click on the 'Port', 'Mountpoint' and 'Password' fields to enter the Ntrip Broadcaster IP port, the mountpoint and the stream upload password. If Ntrip Version 2 is chosen, click to the 'User' field to enter a stream upload user name. Specify the satellite system(s) that shall be part of the uploaded stream (e.g. G for GPS or GRE for GPS+GLONASS+Galileo, or ALL). <i>[key: uploadEphMountpointsOut]</i></p>"));
    1693     addUploadEphRowButton->setWhatsThis(tr("<p>Hit 'Add Row' button to add another line to the 'Upload Ephemeris' table.</p>"));
    1694     delUploadEphRowButton->setWhatsThis(tr("<p>Hit 'Del Row' button to delete the highlighted line(s) from the 'Upload Ephemeris' table.</p>"));
    1695     _uploadSamplRtcmEphSpinBox->setWhatsThis(tr("<p>Select the Broadcast Ephemeris sampling interval in seconds.</p><p>Default is '5', meaning that a complete set of Broadcast Ephemeris is uploaded every 5 seconds. <i>[key: uploadSamplRtcmEph]</i></p>"));
    1696 
    1697     // WhatsThis, Upload Raw Data
    1698     // ---------------------------
    1699     _uploadRawTable->setWhatsThis(tr("<p>BNC can upload Raw Data streams in any format like a NtripServer. </p><p>To fill the 'Upload Raw Data' table, hit the 'Add Row' button and double click on the 'Source Mountpoint' field to enter the Source of data from the 'Streams' section below, which shall be forwarded without decoding and hit Enter. Double click on the 'Host' field to enter the IP or URL of an Ntrip Broadcaster and hit Enter. Select the Ntrip Version that shall be used for data upload. Then double click on the 'Port', 'Upload Mountpoint' and 'Password' fields to enter the Ntrip Broadcaster IP port, the stream upload mountpoint and password. If Ntrip Version 2 is chosen, click to the 'User' field to enter a stream upload user name. </p><p> If the decoder string is not an accepted one ('RTCM_2.x', 'RTCM_3.x' and 'RTNET'), please change the decoder string to <ul>"
    1700         "<li> 'ZERO' (forward the raw data) or </li>"
    1701         "<li> 'ZERO2FILE' (forward and store the raw data)</li> </ul> in addition <i>[key: uploadRawMountpointsOut]</i></p>"));
    1702     addUploadEphRowButton->setWhatsThis(tr("<p>Hit 'Add Row' button to add another line to the 'Upload Raw Data' table.</p>"));
    1703     delUploadEphRowButton->setWhatsThis(tr("<p>Hit 'Del Row' button to delete the highlighted line(s) from the 'Upload Raw Data' table.</p>"));
    1704 
    1705 
    1706     // WhatsThis, Streams Canvas
    1707     // -------------------------
    1708     _mountPointsTable->setWhatsThis(tr("<p>Streams selected for retrieval are listed in the 'Streams' section. "
    1709         "Clicking on 'Add Stream' button opens a window that allows the user to select data streams from an Ntrip Broadcaster "
    1710         "according to their mountpoints. To remove a stream from the 'Streams' list, highlight it by clicking on it "
    1711         "and hit the 'Delete Stream' button. You can also remove multiple streams by highlighting them using +Shift and +Ctrl.</p><p>"
    1712         "BNC automatically allocates one of its internal decoders to a stream based on the stream's 'format' as given in the source-table. "
    1713         "BNC allows users to change this selection by editing the decoder string. "
    1714         "Double click on the 'decoder' field, enter your preferred decoder and then hit Enter. "
    1715         "Accepted decoder strings are 'RTCM_2.x', 'RTCM_3.x' and 'RTNET'.</p><p>"
    1716         "In case you need to log raw data as is, BNC allows to by-pass its decoders and directly save the input in daily log files. "
    1717         "To do this, specify the decoder string as 'ZERO2FILE'.</p><p>"
    1718         "BNC allows as well to forward streams related to the specified 'Mountpoint' on top of the 'Miscellaneous Panel' "
    1719         "through a TCP/IP port of your local host. "
    1720         "In this case, the stream content remains untouched; BNC does not decode or reformat the data for this output. "
    1721         "If the decoder string is not an accepted one, please change the decoder string to 'ZERO' (forward the raw data only) or 'ZERO2FILE' (forward and store the raw data) in addition.</p><p>"
    1722         "BNC can also retrieve streams from virtual reference stations (VRS). VRS streams are indicated by a 'yes' in the 'nmea' column. "
    1723         "To initiate such stream, the approximate latitude/longitude rover position is sent to the Ntrip Broadcaster "
    1724         "together with an approximation for the height. Default values for latitude and longitude can be change according to your requirement. "
    1725         "Double click on 'lat' and 'long' fields, enter the values you wish to send and then hit Enter. <i>[key: mountPoints]</i></p>"));
    1726     _actAddMountPoints->setWhatsThis(tr("<p>Add stream(s) to selection presented in the 'Streams' canvas.</p>"));
    1727     _actDeleteMountPoints->setWhatsThis(tr("<p>Delete stream(s) from selection presented in the 'Streams' canvas.</p>"));
    1728     _actMapMountPoints->setWhatsThis(tr("<p> Draw distribution map of stream selection presented in the 'Streams' canvas. Use mouse to zoom in or out.</p><p>Left button: Draw rectangle to zoom in.<br>Right button: Zoom out.<br>Middle button: Zoom back.</p>"));
    1729     _actStart->setWhatsThis(tr("<p> Start running BNC.</p>"));
    1730     _actStop->setWhatsThis(tr("<p> Stop running BNC.</p>"));
    1731 
    1732     // WhatsThis, Log Canvas
    1733     // ---------------------
    1734     _log->setWhatsThis(tr("<p>Records of BNC's activities are shown in the 'Log' tab. The message log covers the communication status between BNC and the Ntrip Broadcaster as well as problems that occur in the communication link, stream availability, stream delay, stream conversion etc.</p>"));
    1735     _bncFigure->setWhatsThis(tr("<p>The bandwith consumption per stream is shown in the 'Throughput' tab in bits per second (bps) or kilobits per second (kbps).</p>"));
    1736     _bncFigureLate->setWhatsThis(tr("<p>The individual latency of observations of incoming streams is shown in the 'Latency' tab. Streams not carrying observations (e.g. those providing only Broadcast Ephemeris) remain unconsidered.</p><p>Note that the calculation of correct latencies requires the clock of the host computer to be properly synchronized.</p>"));
    1737     _bncFigurePPP->setWhatsThis(tr("<p>PPP time series of North (red), East (green) and Up (blue) displacements are shown in the 'PPP Plot' tab when the corresponding option is selected.</p><p>Values are referred to an XYZ a priori coordinate. The sliding PPP time series window covers the period of the latest 5 minutes.</p>"));
    1738 
    1739 
    1740     // Enable/Disable all Widgets
    1741     // --------------------------
    1742     slotBncTextChanged();
    1743     enableStartStop();
    1744 
    1745     // Auto start
    1746     // ----------
    1747     if (Qt::CheckState(settings.value("autoStart").toInt()) == Qt::Checked) {
    1748         slotStart();
    1749     }
    1750 }
    1751 
    1752 // Destructor
    1753 ////////////////////////////////////////////////////////////////////////////
    1754 bncWindow::~bncWindow() {
    1755     if (_caster) {
    1756         delete _caster; BNC_CORE->setCaster(0);
    1757     }
    1758     if (_casterEph) {
    1759         delete _casterEph;
    1760     }
    1761     delete _bncFigureLate;
    1762     delete _bncFigurePPP;
    1763     delete _actHelp;
    1764     delete _actAbout;
    1765     delete _actFlowchart;
    1766     delete _actFontSel;
    1767     delete _actSaveOpt;
    1768     delete _actQuit;
    1769     delete _actAddMountPoints;
    1770     delete _actDeleteMountPoints;
    1771     delete _actMapMountPoints;
    1772     delete _actStart;
    1773     delete _actStop;
    1774     delete _actwhatsthis;
    1775     delete _proxyHostLineEdit;
    1776     delete _proxyPortLineEdit;
    1777     delete _sslCaCertPathLineEdit;
    1778     delete _sslClientCertPathLineEdit;
    1779     delete _sslIgnoreErrorsCheckBox;
    1780     delete _logFileLineEdit;
    1781     delete _rawOutFileLineEdit;
    1782     delete _rnxAppendCheckBox;
    1783     delete _onTheFlyComboBox;
    1784     delete _autoStartCheckBox;
    1785     delete _rnxPathLineEdit;
    1786     delete _rnxIntrComboBox;
    1787     delete _rnxSamplComboBox;
    1788     delete _rnxSkelExtComboBox;
    1789     delete _rnxSkelPathLineEdit;
    1790     delete _rnxFileCheckBox;
    1791     delete _rnxScrpLineEdit;
    1792     delete _rnxVersComboBox;
    1793     delete _rnxV2Priority;
    1794     delete _ephPathLineEdit;
    1795     //delete _ephFilePerStation;
    1796     delete _ephIntrComboBox;
    1797     delete _ephOutPortLineEdit;
    1798     delete _ephVersComboBox;
    1799     delete _corrPathLineEdit;
    1800     delete _corrIntrComboBox;
    1801     delete _corrPortLineEdit;
    1802     delete _outPortLineEdit;
    1803     delete _outWaitSpinBox;
    1804     delete _outSamplComboBox;
    1805     delete _outFileLineEdit;
    1806     delete _outUPortLineEdit;
    1807     delete _outLockTimeCheckBox;
    1808     delete _serialMountPointLineEdit;
    1809     delete _serialPortNameLineEdit;
    1810     delete _serialBaudRateComboBox;
    1811     delete _serialFlowControlComboBox;
    1812     delete _serialDataBitsComboBox;
    1813     delete _serialParityComboBox;
    1814     delete _serialStopBitsComboBox;
    1815     delete _serialAutoNMEAComboBox;
    1816     delete _serialFileNMEALineEdit;
    1817     delete _serialHeightNMEALineEdit;
    1818     delete _serialNMEASamplingSpinBox;
    1819     delete _adviseObsRateComboBox;
    1820     delete _adviseFailSpinBox;
    1821     delete _adviseRecoSpinBox;
    1822     delete _adviseScriptLineEdit;
    1823     delete _miscMountLineEdit;
    1824     delete _miscPortLineEdit;
    1825     delete _miscIntrComboBox;
    1826     delete _miscScanRTCMCheckBox;
    1827     _mountPointsTable->deleteLater();
    1828     delete _log;
    1829     delete _loggroup;
    1830     _cmbTable->deleteLater();
    1831     delete _cmbMaxresLineEdit;
    1832     delete _cmbMaxdisplacementLineEdit;
    1833     delete _cmbSamplComboBox;
    1834     delete _cmbLogPath;
    1835     delete _cmbMethodComboBox;
    1836     delete _cmbGpsCheckBox;
    1837     delete _cmbGloCheckBox;
    1838     delete _cmbGalCheckBox;
    1839     delete _cmbBdsCheckBox;
    1840     delete _cmbQzssCheckBox;
    1841     delete _cmbSbasCheckBox;
    1842     delete _cmbNavicCheckBox;
    1843     delete _cmbBsxFile;
    1844     delete _uploadSamplRtcmEphCorrComboBox;
    1845     _uploadEphTable->deleteLater();
    1846     _uploadRawTable->deleteLater();
    1847     _uploadTable->deleteLater();
    1848     delete _uploadIntrComboBox;
    1849     delete _uploadAntexFile;
    1850     delete _uploadSamplRtcmEphSpinBox;
    1851     delete _uploadSamplSp3ComboBox;
    1852     delete _uploadSamplClkRnxSpinBox;
    1853     delete _uploadSamplBiaSnxSpinBox;
    1854     delete _reqcActionComboBox;
    1855     delete _reqcObsFileChooser;
    1856     delete _reqcNavFileChooser;
    1857     delete _reqcOutObsLineEdit;
    1858     delete _reqcOutNavLineEdit;
    1859     delete _reqcOutLogLineEdit;
    1860     delete _reqcPlotDirLineEdit;
    1861     delete _reqcSkyPlotSignals;
    1862     delete _reqcLogSummaryOnly;
    1863     delete _reqcEditOptionButton;
    1864     delete _sp3CompFileChooser;
    1865     delete _sp3CompExclude;
    1866     delete _sp3CompLogLineEdit;
    1867     delete _sp3CompSummaryOnly;
    1868     //delete _canvas;
    1869 }
    1870 
    1871 //
    1872 ////////////////////////////////////////////////////////////////////////////
    1873 void bncWindow::populateMountPointsTable() {
    1874 
    1875     for (int iRow = _mountPointsTable->rowCount() - 1; iRow >= 0; iRow--) {
    1876         _mountPointsTable->removeRow(iRow);
    1877     }
    1878 
    1879     bncSettings settings;
    1880 
    1881     QListIterator<QString> it(settings.value("mountPoints").toStringList());
    1882     int iRow = 0;
    1883     while (it.hasNext()) {
    1884         QStringList hlp = it.next().split(" ");
    1885         if (hlp.size() < 7) continue;
    1886         _mountPointsTable->insertRow(iRow);
    1887 
    1888         QUrl    url(hlp[0]);
    1889 
    1890         QString format(hlp[1]);
    1891         QString country(hlp[2]);
    1892         QString latitude(hlp[3]);
    1893         QString longitude(hlp[4]);
    1894         QString nmea(hlp[5]);
    1895         QString ntripVersion(hlp[6]);
    1896 
    1897         QString fullPath;
    1898         if (ntripVersion == 'S') {
    1899           // url.userInfo() contains the case sensitive portName
    1900           // the portName shall be part of the mountpointString
    1901           // to inform the user about the source of the stream
    1902           if (url.host().contains(url.userInfo().toLower())) {
    1903             fullPath = url.host() + url.path();
    1904           }
    1905           else {
    1906             fullPath =  url.userInfo() + "-" + url.host() + url.path();
    1907           }
    1908         } else {
    1909           fullPath = url.host() + QString(":%1").arg(url.port()) + url.path();
     2134      it = new QTableWidgetItem(latitude);
     2135      it->setFlags(it->flags() & ~Qt::ItemIsEditable);
     2136      _mountPointsTable->setItem(iRow, 4, it);
     2137      it = new QTableWidgetItem(longitude);
     2138      it->setFlags(it->flags() & ~Qt::ItemIsEditable);
     2139      _mountPointsTable->setItem(iRow, 5, it);
     2140    }
     2141
     2142    it = new QTableWidgetItem(nmea);
     2143    it->setFlags(it->flags() & ~Qt::ItemIsEditable);
     2144    _mountPointsTable->setItem(iRow, 6, it);
     2145
     2146    it = new QTableWidgetItem(ntripVersion);
     2147    //// it->setFlags(it->flags() & ~Qt::ItemIsEditable);
     2148    _mountPointsTable->setItem(iRow, 7, it);
     2149
     2150    bncTableItem* bncIt = new bncTableItem();
     2151    _mountPointsTable->setItem(iRow, 8, bncIt);
     2152
     2153    iRow++;
     2154  }
     2155  _mountPointsTable->hideColumn(0);
     2156  _mountPointsTable->hideColumn(3);
     2157  _mountPointsTable->sortItems(1);
     2158  delete mountPoints;
     2159
     2160  enableStartStop();
     2161}
     2162
     2163// Save Options (serialize)
     2164////////////////////////////////////////////////////////////////////////////
     2165void bncWindow::slotSaveOptions() {
     2166  saveOptions();
     2167  bncSettings settings;
     2168  settings.sync();
     2169}
     2170
     2171// Save Options (memory only)
     2172////////////////////////////////////////////////////////////////////////////
     2173void bncWindow::saveOptions() {
     2174
     2175  QStringList mountPoints;
     2176  for (int iRow = 0; iRow < _mountPointsTable->rowCount(); iRow++) {
     2177
     2178    QUrl url("//"
     2179             + _mountPointsTable->item(iRow, 0)->text() + "@"
     2180             + _mountPointsTable->item(iRow, 1)->text());
     2181
     2182    mountPoints.append(url.toString()
     2183                       + " " + _mountPointsTable->item(iRow, 2)->text()
     2184                       + " " + _mountPointsTable->item(iRow, 3)->text()
     2185                       + " " + _mountPointsTable->item(iRow, 4)->text()
     2186                       + " " + _mountPointsTable->item(iRow, 5)->text()
     2187                       + " " + _mountPointsTable->item(iRow, 6)->text()
     2188                       + " " + _mountPointsTable->item(iRow, 7)->text());
     2189  }
     2190
     2191  QStringList cmbStreams;
     2192  for (int iRow = 0; iRow < _cmbTable->rowCount(); iRow++) {
     2193    QString hlp;
     2194    for (int iCol = 0; iCol < _cmbTable->columnCount(); iCol++) {
     2195      if (_cmbTable->item(iRow, iCol)) {
     2196        hlp += _cmbTable->item(iRow, iCol)->text() + " ";
     2197      }
     2198    }
     2199    if (!hlp.isEmpty()) {
     2200      cmbStreams << hlp;
     2201    }
     2202  }
     2203
     2204  QStringList uploadMountpointsOut;
     2205  for (int iRow = 0; iRow < _uploadTable->rowCount(); iRow++) {
     2206    QString hlp;
     2207    for (int iCol = 0; iCol < _uploadTable->columnCount(); iCol++) {
     2208      if (_uploadTable->cellWidget(iRow, iCol) &&
     2209          (iCol == 3 || iCol == 4 || iCol == 5 || iCol == 6 || iCol == 7 || iCol == 8)) {
     2210        if (iCol == 3) {
     2211          QComboBox* ntripversion = (QComboBox*)(_uploadTable->cellWidget(iRow, iCol));
     2212          hlp += ntripversion->currentText() + ",";
    19102213        }
    1911 
    1912         QTableWidgetItem* it;
    1913         it = new QTableWidgetItem(url.userInfo());
    1914         it->setFlags(it->flags() & ~Qt::ItemIsEditable);
    1915         _mountPointsTable->setItem(iRow, 0, it);
    1916 
    1917         it = new QTableWidgetItem(fullPath);
    1918         it->setFlags(it->flags() & ~Qt::ItemIsEditable);
    1919         _mountPointsTable->setItem(iRow, 1, it);
    1920 
    1921         it = new QTableWidgetItem(format);
    1922         _mountPointsTable->setItem(iRow, 2, it);
    1923 
    1924         it = new QTableWidgetItem(country);
    1925         _mountPointsTable->setItem(iRow, 3, it);
    1926 
    1927         if (nmea == "yes") {
    1928             it = new QTableWidgetItem(latitude);
    1929             _mountPointsTable->setItem(iRow, 4, it);
    1930             it = new QTableWidgetItem(longitude);
    1931             _mountPointsTable->setItem(iRow, 5, it);
     2214        else if (iCol == 4) {
     2215          QLineEdit* user = (QLineEdit*)(_uploadTable->cellWidget(iRow, iCol));
     2216          hlp += user->text() + ",";
    19322217        }
    1933         else {
    1934             it = new QTableWidgetItem(latitude);
    1935             it->setFlags(it->flags() & ~Qt::ItemIsEditable);
    1936             _mountPointsTable->setItem(iRow, 4, it);
    1937 
    1938             it = new QTableWidgetItem(longitude);
    1939             it->setFlags(it->flags() & ~Qt::ItemIsEditable);
    1940             _mountPointsTable->setItem(iRow, 5, it);
     2218        else if (iCol == 5) {
     2219          QLineEdit* passwd = (QLineEdit*)(_uploadTable->cellWidget(iRow, iCol));
     2220          hlp += passwd->text() + ",";
    19412221        }
    1942 
    1943         it = new QTableWidgetItem(nmea);
    1944         it->setFlags(it->flags() & ~Qt::ItemIsEditable);
    1945         _mountPointsTable->setItem(iRow, 6, it);
    1946 
    1947         it = new QTableWidgetItem(ntripVersion);
    1948         ////    it->setFlags(it->flags() & ~Qt::ItemIsEditable);
    1949         _mountPointsTable->setItem(iRow, 7, it);
    1950 
    1951         bncTableItem* bncIt = new bncTableItem();
    1952         bncIt->setFlags(bncIt->flags() & ~Qt::ItemIsEditable);
    1953         _mountPointsTable->setItem(iRow, 8, bncIt);
    1954 
    1955         iRow++;
    1956     }
    1957 
    1958     _mountPointsTable->sortItems(1);
    1959 
    1960     enableStartStop();
    1961 }
    1962 
    1963 // Retrieve Table
    1964 ////////////////////////////////////////////////////////////////////////////
    1965 void bncWindow::slotAddMountPoints() {
    1966 
    1967     bncSettings settings;
    1968     QString proxyHost = settings.value("proxyHost").toString();
    1969     int     proxyPort = settings.value("proxyPort").toInt();
    1970     if (proxyHost != _proxyHostLineEdit->text() ||
    1971         proxyPort != _proxyPortLineEdit->text().toInt()) {
    1972         int iRet = QMessageBox::question(this, "Question", "Proxy options "
    1973             "changed. Use the new ones?",
    1974             QMessageBox::Yes, QMessageBox::No,
    1975             QMessageBox::NoButton);
    1976         if (iRet == QMessageBox::Yes) {
    1977             settings.setValue("proxyHost", _proxyHostLineEdit->text());
    1978             settings.setValue("proxyPort", _proxyPortLineEdit->text());
     2222        else if (iCol == 6) {
     2223          QComboBox* system = (QComboBox*)(_uploadTable->cellWidget(iRow, iCol));
     2224          hlp += system->currentText() + ",";
    19792225        }
    1980     }
    1981 
    1982     settings.setValue("sslCaCertPath", _sslCaCertPathLineEdit->text());
    1983     settings.setValue("sslClientCertPath", _sslClientCertPathLineEdit->text());
    1984     settings.setValue("sslIgnoreErrors", _sslIgnoreErrorsCheckBox->checkState());
    1985 
    1986     QMessageBox msgBox;
    1987     msgBox.setIcon(QMessageBox::Question);
    1988     msgBox.setWindowTitle("Add Stream");
    1989     msgBox.setText("Add stream(s) coming from:");
    1990 
    1991     QPushButton* buttonNtrip = msgBox.addButton(tr("Caster"), QMessageBox::ActionRole);
    1992     QPushButton* buttonIP = msgBox.addButton(tr("TCP/IP port"), QMessageBox::ActionRole);
    1993     QPushButton* buttonUDP = msgBox.addButton(tr("UDP port"), QMessageBox::ActionRole);
    1994     QPushButton* buttonSerial = msgBox.addButton(tr("Serial port"), QMessageBox::ActionRole);
    1995     QPushButton* buttonCancel = msgBox.addButton(tr("Cancel"), QMessageBox::ActionRole);
    1996 
    1997     msgBox.exec();
    1998 
    1999     if (msgBox.clickedButton() == buttonNtrip) {
    2000         bncTableDlg* dlg = new bncTableDlg(this);
    2001         dlg->move(this->pos().x() + 50, this->pos().y() + 50);
    2002         connect(dlg, SIGNAL(newMountPoints(QStringList*)),
    2003             this, SLOT(slotNewMountPoints(QStringList*)));
    2004         dlg->exec();
    2005         delete dlg;
    2006     }
    2007     else if (msgBox.clickedButton() == buttonIP) {
    2008         bncIpPort* ipp = new bncIpPort(this);
    2009         connect(ipp, SIGNAL(newMountPoints(QStringList*)),
    2010             this, SLOT(slotNewMountPoints(QStringList*)));
    2011         ipp->exec();
    2012         delete ipp;
    2013     }
    2014     else if (msgBox.clickedButton() == buttonUDP) {
    2015         bncUdpPort* udp = new bncUdpPort(this);
    2016         connect(udp, SIGNAL(newMountPoints(QStringList*)),
    2017             this, SLOT(slotNewMountPoints(QStringList*)));
    2018         udp->exec();
    2019         delete udp;
    2020     }
    2021     else if (msgBox.clickedButton() == buttonSerial) {
    2022         bncSerialPort* sep = new bncSerialPort(this);
    2023         connect(sep, SIGNAL(newMountPoints(QStringList*)),
    2024             this, SLOT(slotNewMountPoints(QStringList*)));
    2025         sep->exec();
    2026         delete sep;
    2027     }
    2028     else if (msgBox.clickedButton() == buttonCancel) {
    2029         // Cancel
    2030     }
    2031 
    2032     enableStartStop();
    2033 }
    2034 
    2035 // Delete Selected Mount Points
    2036 ////////////////////////////////////////////////////////////////////////////
    2037 void bncWindow::slotDeleteMountPoints() {
    2038 
    2039     int nRows = _mountPointsTable->rowCount();
    2040     std::vector <bool> flg(nRows);
    2041     for (int iRow = 0; iRow < nRows; iRow++) {
    2042         if (_mountPointsTable->item(iRow, 1)->isSelected()) {
    2043             flg[iRow] = true;
     2226        else if (iCol == 7) {
     2227          QComboBox* format = (QComboBox*)(_uploadTable->cellWidget(iRow, iCol));
     2228          hlp += format->currentText() + ",";
    20442229        }
    2045         else {
    2046             flg[iRow] = false;
    2047         }
    2048     }
    2049     for (int iRow = nRows - 1; iRow >= 0; iRow--) {
    2050         if (flg[iRow]) {
    2051             _mountPointsTable->removeRow(iRow);
    2052         }
    2053     }
    2054     _actDeleteMountPoints->setEnabled(false);
    2055 
    2056     enableStartStop();
    2057 }
    2058 
    2059 // New Mount Points Selected
    2060 ////////////////////////////////////////////////////////////////////////////
    2061 void bncWindow::slotNewMountPoints(QStringList* mountPoints) {
    2062     int iRow = 0;
    2063     QListIterator<QString> it(*mountPoints);
    2064     while (it.hasNext()) {
    2065         QStringList hlp = it.next().split(" ");
    2066 
    2067         QUrl url(hlp[0]);
    2068 
    2069         QString format(hlp[1]);
    2070         QString country(hlp[2]);
    2071         QString latitude(hlp[3]);
    2072         QString longitude(hlp[4]);
    2073         QString nmea(hlp[5]);
    2074         QString ntripVersion(hlp[6]);
    2075 
    2076         QString fullPath;
    2077         if (ntripVersion == 'S') {
    2078           // url.userInfo() contains the case sensitive portName
    2079           // the portName shall be part of the mountpointString
    2080           // to inform the user about the source of the stream
    2081           if (url.host().contains(url.userInfo().toLower())) {
    2082             fullPath = url.host() + url.path();
    2083           }
    2084           else {
    2085             fullPath =  url.userInfo() + "-" + url.host() + url.path();
    2086           }
    2087         } else {
    2088           fullPath = url.host() + QString(":%1").arg(url.port()) + url.path();
    2089         }
    2090 
    2091         _mountPointsTable->insertRow(iRow);
    2092 
    2093         QTableWidgetItem* it;
    2094         it = new QTableWidgetItem(url.userInfo());
    2095         it->setFlags(it->flags() & ~Qt::ItemIsEditable);
    2096         _mountPointsTable->setItem(iRow, 0, it);
    2097 
    2098         it = new QTableWidgetItem(fullPath);
    2099         it->setFlags(it->flags() & ~Qt::ItemIsEditable);
    2100         _mountPointsTable->setItem(iRow, 1, it);
    2101 
    2102         it = new QTableWidgetItem(format);
    2103         _mountPointsTable->setItem(iRow, 2, it);
    2104 
    2105         it = new QTableWidgetItem(country);
    2106         _mountPointsTable->setItem(iRow, 3, it);
    2107 
    2108         if (nmea == "yes") {
    2109             it = new QTableWidgetItem(latitude);
    2110             _mountPointsTable->setItem(iRow, 4, it);
    2111             it = new QTableWidgetItem(longitude);
    2112             _mountPointsTable->setItem(iRow, 5, it);
    2113         }
    2114         else {
    2115             it = new QTableWidgetItem(latitude);
    2116             it->setFlags(it->flags() & ~Qt::ItemIsEditable);
    2117             _mountPointsTable->setItem(iRow, 4, it);
    2118             it = new QTableWidgetItem(longitude);
    2119             it->setFlags(it->flags() & ~Qt::ItemIsEditable);
    2120             _mountPointsTable->setItem(iRow, 5, it);
    2121         }
    2122 
    2123         it = new QTableWidgetItem(nmea);
    2124         it->setFlags(it->flags() & ~Qt::ItemIsEditable);
    2125         _mountPointsTable->setItem(iRow, 6, it);
    2126 
    2127         it = new QTableWidgetItem(ntripVersion);
    2128         //// it->setFlags(it->flags() & ~Qt::ItemIsEditable);
    2129         _mountPointsTable->setItem(iRow, 7, it);
    2130 
    2131         bncTableItem* bncIt = new bncTableItem();
    2132         _mountPointsTable->setItem(iRow, 8, bncIt);
    2133 
    2134         iRow++;
    2135     }
    2136     _mountPointsTable->hideColumn(0);
    2137     _mountPointsTable->hideColumn(3);
    2138     _mountPointsTable->sortItems(1);
    2139     delete mountPoints;
    2140 
    2141     enableStartStop();
    2142 }
    2143 
    2144 // Save Options (serialize)
    2145 ////////////////////////////////////////////////////////////////////////////
    2146 void bncWindow::slotSaveOptions() {
    2147     saveOptions();
    2148     bncSettings settings;
    2149     settings.sync();
    2150 }
    2151 
    2152 // Save Options (memory only)
    2153 ////////////////////////////////////////////////////////////////////////////
    2154 void bncWindow::saveOptions() {
    2155 
    2156     QStringList mountPoints;
    2157     for (int iRow = 0; iRow < _mountPointsTable->rowCount(); iRow++) {
    2158 
    2159           QUrl url("//"
    2160               + _mountPointsTable->item(iRow, 0)->text() + "@"
    2161               + _mountPointsTable->item(iRow, 1)->text());
    2162 
    2163           mountPoints.append(url.toString()
    2164               + " " + _mountPointsTable->item(iRow, 2)->text()
    2165               + " " + _mountPointsTable->item(iRow, 3)->text()
    2166               + " " + _mountPointsTable->item(iRow, 4)->text()
    2167               + " " + _mountPointsTable->item(iRow, 5)->text()
    2168               + " " + _mountPointsTable->item(iRow, 6)->text()
    2169               + " " + _mountPointsTable->item(iRow, 7)->text());
    2170     }
    2171 
    2172     QStringList cmbStreams;
    2173     for (int iRow = 0; iRow < _cmbTable->rowCount(); iRow++) {
    2174         QString hlp;
    2175         for (int iCol = 0; iCol < _cmbTable->columnCount(); iCol++) {
    2176             if (_cmbTable->item(iRow, iCol)) {
    2177                 hlp += _cmbTable->item(iRow, iCol)->text() + " ";
    2178             }
    2179         }
    2180         if (!hlp.isEmpty()) {
    2181             cmbStreams << hlp;
    2182         }
    2183     }
    2184 
    2185     QStringList uploadMountpointsOut;
    2186     for (int iRow = 0; iRow < _uploadTable->rowCount(); iRow++) {
    2187         QString hlp;
    2188         for (int iCol = 0; iCol < _uploadTable->columnCount(); iCol++) {
    2189             if (_uploadTable->cellWidget(iRow, iCol) &&
    2190                 (iCol == 3 || iCol == 4 || iCol == 5 || iCol == 6 || iCol == 7 || iCol == 8)) {
    2191                 if (iCol == 3) {
    2192                     QComboBox* ntripversion = (QComboBox*)(_uploadTable->cellWidget(iRow, iCol));
    2193                     hlp += ntripversion->currentText() + ",";
    2194                 }
    2195                 else if (iCol == 4) {
    2196                     QLineEdit* user = (QLineEdit*)(_uploadTable->cellWidget(iRow, iCol));
    2197                     hlp += user->text() + ",";
    2198                 }
    2199                 else if (iCol == 5) {
    2200                     QLineEdit* passwd = (QLineEdit*)(_uploadTable->cellWidget(iRow, iCol));
    2201                     hlp += passwd->text() + ",";
    2202                 }
    2203                 else if (iCol == 6) {
    2204                     QComboBox* system = (QComboBox*)(_uploadTable->cellWidget(iRow, iCol));
    2205                     hlp += system->currentText() + ",";
    2206                 }
    2207                 else if (iCol == 7) {
    2208                     QComboBox* format = (QComboBox*)(_uploadTable->cellWidget(iRow, iCol));
    2209                     hlp += format->currentText() + ",";
    2210                 }
    2211                 else if (iCol == 8) {
    2212                     QCheckBox* com = (QCheckBox*)(_uploadTable->cellWidget(iRow, iCol));
    2213                     QString state; state.setNum(com->checkState());
    2214                     hlp += state + ",";
    2215                 }
    2216             }
    2217             else if (_uploadTable->item(iRow, iCol)) {
    2218                 hlp += _uploadTable->item(iRow, iCol)->text() + ",";
    2219             }
    2220         }
    2221         if (!hlp.isEmpty()) {
    2222             uploadMountpointsOut << hlp;
    2223         }
    2224     }
    2225 
    2226     QStringList uploadEphMountpointsOut;
    2227     for (int iRow = 0; iRow < _uploadEphTable->rowCount(); iRow++) {
    2228       QString hlp;
    2229       for (int iCol = 0; iCol < _uploadEphTable->columnCount(); iCol++) {
    2230           if (_uploadEphTable->cellWidget(iRow, iCol) &&
    2231               (iCol == 3 || iCol == 4 || iCol == 5 || iCol == 6)) {
    2232               if      (iCol == 3) {
    2233                   QComboBox* ntripversion = (QComboBox*)(_uploadEphTable->cellWidget(iRow, iCol));
    2234                   hlp += ntripversion->currentText() + ",";
    2235               }
    2236               else if (iCol == 4) {
    2237                   QLineEdit* user = (QLineEdit*)(_uploadEphTable->cellWidget(iRow, iCol));
    2238                   hlp += user->text() + ",";
    2239               }
    2240               else if (iCol == 5) {
    2241                   QLineEdit* passwd = (QLineEdit*)(_uploadEphTable->cellWidget(iRow, iCol));
    2242                   hlp += passwd->text() + ",";
    2243               }
    2244               else if (iCol == 6) {
    2245                   QLineEdit* system = (QLineEdit*)(_uploadEphTable->cellWidget(iRow, iCol));
    2246                   hlp += system->text() + ",";
    2247               }
    2248           }
    2249           else if (_uploadEphTable->item(iRow, iCol)) {
    2250               hlp += _uploadEphTable->item(iRow, iCol)->text() + ",";
    2251           }
    2252       }
    2253       if (!hlp.isEmpty()) {
    2254           uploadEphMountpointsOut << hlp;
    2255       }
    2256     }
    2257 
    2258     QStringList uploadRawMountpointsOut;
    2259     for (int iRow = 0; iRow < _uploadRawTable->rowCount(); iRow++) {
    2260       QString hlp;
    2261       for (int iCol = 0; iCol < _uploadRawTable->columnCount(); iCol++) {
    2262         if (_uploadRawTable->cellWidget(iRow, iCol) &&
    2263             (iCol == 4 || iCol == 5 || iCol == 6)) {
    2264             if      (iCol == 4) {
    2265                 QComboBox* ntripversion = (QComboBox*)(_uploadRawTable->cellWidget(iRow, iCol));
    2266                 hlp += ntripversion->currentText() + ",";
    2267             }
    2268             else if (iCol == 5) {
    2269                 QLineEdit* user = (QLineEdit*)(_uploadRawTable->cellWidget(iRow, iCol));
    2270                 hlp += user->text() + ",";
    2271             }
    2272             else if (iCol == 6) {
    2273                 QLineEdit* passwd = (QLineEdit*)(_uploadRawTable->cellWidget(iRow, iCol));
    2274                 hlp += passwd->text() + ",";
    2275             }
    2276         }
    2277         else if (_uploadRawTable->item(iRow, iCol)) {
    2278             hlp += _uploadRawTable->item(iRow, iCol)->text() + ",";
     2230        else if (iCol == 8) {
     2231          QCheckBox* com = (QCheckBox*)(_uploadTable->cellWidget(iRow, iCol));
     2232          QString state; state.setNum(com->checkState());
     2233          hlp += state + ",";
    22792234        }
    22802235      }
    2281       if (!hlp.isEmpty()) {
    2282           uploadRawMountpointsOut << hlp;
     2236      else if (_uploadTable->item(iRow, iCol)) {
     2237        hlp += _uploadTable->item(iRow, iCol)->text() + ",";
    22832238      }
    22842239    }
    2285 
    2286     bncSettings settings;
    2287 
    2288     settings.setValue("startTab", _aogroup->currentIndex());
    2289     settings.setValue("statusTab", _loggroup->currentIndex());
    2290     settings.setValue("mountPoints", mountPoints);
    2291     // Network
    2292     settings.setValue("proxyHost", _proxyHostLineEdit->text());
    2293     settings.setValue("proxyPort", _proxyPortLineEdit->text());
    2294     settings.setValue("sslCaCertPath", _sslCaCertPathLineEdit->text());
    2295     settings.setValue("sslClientCertPath", _sslClientCertPathLineEdit->text());
    2296     settings.setValue("sslIgnoreErrors", _sslIgnoreErrorsCheckBox->checkState());
    2297     // General
    2298     settings.setValue("logFile", _logFileLineEdit->text());
    2299     settings.setValue("rnxAppend", _rnxAppendCheckBox->checkState());
    2300     settings.setValue("onTheFlyInterval", _onTheFlyComboBox->currentText());
    2301     settings.setValue("autoStart", _autoStartCheckBox->checkState());
    2302     settings.setValue("rawOutFile", _rawOutFileLineEdit->text());
    2303     // RINEX Observations
    2304     settings.setValue("rnxPath", _rnxPathLineEdit->text());
    2305     settings.setValue("rnxIntr", _rnxIntrComboBox->currentText());
    2306     settings.setValue("rnxSampl", _rnxSamplComboBox->currentText());
    2307     settings.setValue("rnxSkel", _rnxSkelExtComboBox->currentText());
    2308     settings.setValue("rnxSkelPath", _rnxSkelPathLineEdit->text());
    2309     settings.setValue("rnxOnlyWithSKL", _rnxFileCheckBox->checkState());
    2310     settings.setValue("rnxScript", _rnxScrpLineEdit->text());
    2311     settings.setValue("rnxV2Priority", _rnxV2Priority->text());
    2312     settings.setValue("rnxVersion", _rnxVersComboBox->currentText());
    2313     // RINEX Ephemeris
    2314     settings.setValue("ephPath", _ephPathLineEdit->text());
    2315     settings.setValue("ephIntr", _ephIntrComboBox->currentText());
    2316     settings.setValue("ephOutPort", _ephOutPortLineEdit->text());
    2317     settings.setValue("ephVersion", _ephVersComboBox->currentText());
    2318     //settings.setValue("ephFilePerStation", _ephFilePerStation->checkState());
     2240    if (!hlp.isEmpty()) {
     2241      uploadMountpointsOut << hlp;
     2242    }
     2243  }
     2244
     2245  QStringList uploadEphMountpointsOut;
     2246  for (int iRow = 0; iRow < _uploadEphTable->rowCount(); iRow++) {
     2247    QString hlp;
     2248    for (int iCol = 0; iCol < _uploadEphTable->columnCount(); iCol++) {
     2249      if (_uploadEphTable->cellWidget(iRow, iCol) &&
     2250          (iCol == 3 || iCol == 4 || iCol == 5 || iCol == 6)) {
     2251        if      (iCol == 3) {
     2252          QComboBox* ntripversion = (QComboBox*)(_uploadEphTable->cellWidget(iRow, iCol));
     2253          hlp += ntripversion->currentText() + ",";
     2254        }
     2255        else if (iCol == 4) {
     2256          QLineEdit* user = (QLineEdit*)(_uploadEphTable->cellWidget(iRow, iCol));
     2257          hlp += user->text() + ",";
     2258        }
     2259        else if (iCol == 5) {
     2260          QLineEdit* passwd = (QLineEdit*)(_uploadEphTable->cellWidget(iRow, iCol));
     2261          hlp += passwd->text() + ",";
     2262        }
     2263        else if (iCol == 6) {
     2264          QLineEdit* system = (QLineEdit*)(_uploadEphTable->cellWidget(iRow, iCol));
     2265          hlp += system->text() + ",";
     2266        }
     2267      }
     2268      else if (_uploadEphTable->item(iRow, iCol)) {
     2269        hlp += _uploadEphTable->item(iRow, iCol)->text() + ",";
     2270      }
     2271    }
     2272    if (!hlp.isEmpty()) {
     2273      uploadEphMountpointsOut << hlp;
     2274    }
     2275  }
     2276
     2277  QStringList uploadRawMountpointsOut;
     2278  for (int iRow = 0; iRow < _uploadRawTable->rowCount(); iRow++) {
     2279    QString hlp;
     2280    for (int iCol = 0; iCol < _uploadRawTable->columnCount(); iCol++) {
     2281      if (_uploadRawTable->cellWidget(iRow, iCol) &&
     2282          (iCol == 4 || iCol == 5 || iCol == 6)) {
     2283        if      (iCol == 4) {
     2284          QComboBox* ntripversion = (QComboBox*)(_uploadRawTable->cellWidget(iRow, iCol));
     2285          hlp += ntripversion->currentText() + ",";
     2286        }
     2287        else if (iCol == 5) {
     2288          QLineEdit* user = (QLineEdit*)(_uploadRawTable->cellWidget(iRow, iCol));
     2289          hlp += user->text() + ",";
     2290        }
     2291        else if (iCol == 6) {
     2292          QLineEdit* passwd = (QLineEdit*)(_uploadRawTable->cellWidget(iRow, iCol));
     2293          hlp += passwd->text() + ",";
     2294        }
     2295      }
     2296      else if (_uploadRawTable->item(iRow, iCol)) {
     2297        hlp += _uploadRawTable->item(iRow, iCol)->text() + ",";
     2298      }
     2299    }
     2300    if (!hlp.isEmpty()) {
     2301      uploadRawMountpointsOut << hlp;
     2302    }
     2303  }
     2304
     2305  bncSettings settings;
     2306
     2307  settings.setValue("startTab", _aogroup->currentIndex());
     2308  settings.setValue("statusTab", _loggroup->currentIndex());
     2309  settings.setValue("mountPoints", mountPoints);
     2310  // Network
     2311  settings.setValue("proxyHost", _proxyHostLineEdit->text());
     2312  settings.setValue("proxyPort", _proxyPortLineEdit->text());
     2313  settings.setValue("sslCaCertPath", _sslCaCertPathLineEdit->text());
     2314  settings.setValue("sslClientCertPath", _sslClientCertPathLineEdit->text());
     2315  settings.setValue("sslIgnoreErrors", _sslIgnoreErrorsCheckBox->checkState());
     2316  // General
     2317  settings.setValue("logFile", _logFileLineEdit->text());
     2318  settings.setValue("rnxAppend", _rnxAppendCheckBox->checkState());
     2319  settings.setValue("onTheFlyInterval", _onTheFlyComboBox->currentText());
     2320  settings.setValue("autoStart", _autoStartCheckBox->checkState());
     2321  settings.setValue("rawOutFile", _rawOutFileLineEdit->text());
     2322  // RINEX Observations
     2323  settings.setValue("rnxPath", _rnxPathLineEdit->text());
     2324  settings.setValue("rnxIntr", _rnxIntrComboBox->currentText());
     2325  settings.setValue("rnxSampl", _rnxSamplComboBox->currentText());
     2326  settings.setValue("rnxSkel", _rnxSkelExtComboBox->currentText());
     2327  settings.setValue("rnxSkelPath", _rnxSkelPathLineEdit->text());
     2328  settings.setValue("rnxOnlyWithSKL", _rnxFileCheckBox->checkState());
     2329  settings.setValue("rnxScript", _rnxScrpLineEdit->text());
     2330  settings.setValue("rnxV2Priority", _rnxV2Priority->text());
     2331  settings.setValue("rnxVersion", _rnxVersComboBox->currentText());
     2332  // RINEX Ephemeris
     2333  settings.setValue("ephPath", _ephPathLineEdit->text());
     2334  settings.setValue("ephIntr", _ephIntrComboBox->currentText());
     2335  settings.setValue("ephOutPort", _ephOutPortLineEdit->text());
     2336  settings.setValue("ephVersion", _ephVersComboBox->currentText());
     2337  //settings.setValue("ephFilePerStation", _ephFilePerStation->checkState());
    23192338  // Broadcast Corrections
    2320     settings.setValue("corrPath", _corrPathLineEdit->text());
    2321     settings.setValue("corrIntr", _corrIntrComboBox->currentText());
    2322     settings.setValue("corrPort", _corrPortLineEdit->text());
    2323     // Feed Engine
    2324     settings.setValue("outPort", _outPortLineEdit->text());
    2325     settings.setValue("outWait", _outWaitSpinBox->value());
    2326     settings.setValue("outSampl", _outSamplComboBox->currentText());
    2327     settings.setValue("outFile", _outFileLineEdit->text());
    2328     settings.setValue("outLockTime", _outLockTimeCheckBox->checkState());
    2329     settings.setValue("outUPort", _outUPortLineEdit->text());
    2330     // Serial Output
    2331     settings.setValue("serialMountPoint", _serialMountPointLineEdit->text());
    2332     settings.setValue("serialPortName", _serialPortNameLineEdit->text());
    2333     settings.setValue("serialBaudRate", _serialBaudRateComboBox->currentText());
    2334     settings.setValue("serialFlowControl", _serialFlowControlComboBox->currentText());
    2335     settings.setValue("serialDataBits", _serialDataBitsComboBox->currentText());
    2336     settings.setValue("serialParity", _serialParityComboBox->currentText());
    2337     settings.setValue("serialStopBits", _serialStopBitsComboBox->currentText());
    2338     settings.setValue("serialAutoNMEA", _serialAutoNMEAComboBox->currentText());
    2339     settings.setValue("serialFileNMEA", _serialFileNMEALineEdit->text());
    2340     settings.setValue("serialHeightNMEA", _serialHeightNMEALineEdit->text());
    2341     settings.setValue("serialNMEASampling", _serialNMEASamplingSpinBox->value());
    2342     // Outages
    2343     settings.setValue("adviseObsRate", _adviseObsRateComboBox->currentText());
    2344     settings.setValue("adviseFail", _adviseFailSpinBox->value());
    2345     settings.setValue("adviseReco", _adviseRecoSpinBox->value());
    2346     settings.setValue("adviseScript", _adviseScriptLineEdit->text());
    2347     // Miscellaneous
    2348     settings.setValue("miscMount", _miscMountLineEdit->text());
    2349     settings.setValue("miscPort", _miscPortLineEdit->text());
    2350     settings.setValue("miscIntr", _miscIntrComboBox->currentText());
    2351     settings.setValue("miscScanRTCM", _miscScanRTCMCheckBox->checkState());
    2352     // Reqc
    2353     settings.setValue("reqcAction", _reqcActionComboBox->currentText());
    2354     settings.setValue("reqcObsFile", _reqcObsFileChooser->fileName());
    2355     settings.setValue("reqcNavFile", _reqcNavFileChooser->fileName());
    2356     settings.setValue("reqcOutObsFile", _reqcOutObsLineEdit->text());
    2357     settings.setValue("reqcOutNavFile", _reqcOutNavLineEdit->text());
    2358     settings.setValue("reqcOutLogFile", _reqcOutLogLineEdit->text());
    2359     settings.setValue("reqcPlotDir", _reqcPlotDirLineEdit->text());
    2360     settings.setValue("reqcSkyPlotSignals", _reqcSkyPlotSignals->text());
    2361     settings.setValue("reqcLogSummaryOnly", _reqcLogSummaryOnly->checkState());
    2362     // SP3 Comparison
    2363     settings.setValue("sp3CompFile", _sp3CompFileChooser->fileName());
    2364     settings.setValue("sp3CompExclude", _sp3CompExclude->text());
    2365     settings.setValue("sp3CompOutLogFile", _sp3CompLogLineEdit->text());
    2366     settings.setValue("sp3CompSummaryOnly", _sp3CompSummaryOnly->checkState());
    2367     // Combine Corrections
    2368     if (!cmbStreams.isEmpty()) {
    2369         settings.setValue("cmbStreams", cmbStreams);
     2339  settings.setValue("corrPath", _corrPathLineEdit->text());
     2340  settings.setValue("corrIntr", _corrIntrComboBox->currentText());
     2341  settings.setValue("corrPort", _corrPortLineEdit->text());
     2342  // Feed Engine
     2343  settings.setValue("outPort", _outPortLineEdit->text());
     2344  settings.setValue("outWait", _outWaitSpinBox->value());
     2345  settings.setValue("outSampl", _outSamplComboBox->currentText());
     2346  settings.setValue("outFile", _outFileLineEdit->text());
     2347  settings.setValue("outLockTime", _outLockTimeCheckBox->checkState());
     2348  settings.setValue("outUPort", _outUPortLineEdit->text());
     2349  // Serial Output
     2350  settings.setValue("serialMountPoint", _serialMountPointLineEdit->text());
     2351  settings.setValue("serialPortName", _serialPortNameLineEdit->text());
     2352  settings.setValue("serialBaudRate", _serialBaudRateComboBox->currentText());
     2353  settings.setValue("serialFlowControl", _serialFlowControlComboBox->currentText());
     2354  settings.setValue("serialDataBits", _serialDataBitsComboBox->currentText());
     2355  settings.setValue("serialParity", _serialParityComboBox->currentText());
     2356  settings.setValue("serialStopBits", _serialStopBitsComboBox->currentText());
     2357  settings.setValue("serialAutoNMEA", _serialAutoNMEAComboBox->currentText());
     2358  settings.setValue("serialFileNMEA", _serialFileNMEALineEdit->text());
     2359  settings.setValue("serialHeightNMEA", _serialHeightNMEALineEdit->text());
     2360  settings.setValue("serialNMEASampling", _serialNMEASamplingSpinBox->value());
     2361  // Outages
     2362  settings.setValue("adviseObsRate", _adviseObsRateComboBox->currentText());
     2363  settings.setValue("adviseFail", _adviseFailSpinBox->value());
     2364  settings.setValue("adviseReco", _adviseRecoSpinBox->value());
     2365  settings.setValue("adviseScript", _adviseScriptLineEdit->text());
     2366  // Miscellaneous
     2367  settings.setValue("miscMount", _miscMountLineEdit->text());
     2368  settings.setValue("miscPort", _miscPortLineEdit->text());
     2369  settings.setValue("miscIntr", _miscIntrComboBox->currentText());
     2370  settings.setValue("miscScanRTCM", _miscScanRTCMCheckBox->checkState());
     2371  // Reqc
     2372  settings.setValue("reqcAction", _reqcActionComboBox->currentText());
     2373  settings.setValue("reqcObsFile", _reqcObsFileChooser->fileName());
     2374  settings.setValue("reqcNavFile", _reqcNavFileChooser->fileName());
     2375  settings.setValue("reqcOutObsFile", _reqcOutObsLineEdit->text());
     2376  settings.setValue("reqcOutNavFile", _reqcOutNavLineEdit->text());
     2377  settings.setValue("reqcOutLogFile", _reqcOutLogLineEdit->text());
     2378  settings.setValue("reqcPlotDir", _reqcPlotDirLineEdit->text());
     2379  settings.setValue("reqcSkyPlotSignals", _reqcSkyPlotSignals->text());
     2380  settings.setValue("reqcLogSummaryOnly", _reqcLogSummaryOnly->checkState());
     2381  // SP3 Comparison
     2382  settings.setValue("sp3CompFile", _sp3CompFileChooser->fileName());
     2383  settings.setValue("sp3CompExclude", _sp3CompExclude->text());
     2384  settings.setValue("sp3CompOutLogFile", _sp3CompLogLineEdit->text());
     2385  settings.setValue("sp3CompSummaryOnly", _sp3CompSummaryOnly->checkState());
     2386  // Combine Corrections
     2387  if (!cmbStreams.isEmpty()) {
     2388    settings.setValue("cmbStreams", cmbStreams);
     2389  }
     2390  else {
     2391    settings.setValue("cmbStreams", "");
     2392  }
     2393  settings.setValue("cmbMethod", _cmbMethodComboBox->currentText());
     2394  settings.setValue("cmbMaxres", _cmbMaxresLineEdit->text());
     2395  settings.setValue("cmbMaxdisplacement", _cmbMaxdisplacementLineEdit->text());
     2396  settings.setValue("cmbSampl", _cmbSamplComboBox->currentText());
     2397  settings.setValue("cmbLogpath", _cmbLogPath->text());
     2398  settings.setValue("cmbGps", _cmbGpsCheckBox->checkState());
     2399  settings.setValue("cmbGlo", _cmbGloCheckBox->checkState());
     2400  settings.setValue("cmbGal", _cmbGalCheckBox->checkState());
     2401  settings.setValue("cmbBds", _cmbBdsCheckBox->checkState());
     2402  settings.setValue("cmbQzss", _cmbQzssCheckBox->checkState());
     2403  settings.setValue("cmbSbas", _cmbSbasCheckBox->checkState());
     2404  settings.setValue("cmbNavic", _cmbNavicCheckBox->checkState());
     2405  settings.setValue("cmbBsxFile", _cmbBsxFile->fileName());
     2406
     2407  // Upload Corrections
     2408  if (!uploadMountpointsOut.isEmpty()) {
     2409    settings.setValue("uploadMountpointsOut", uploadMountpointsOut);
     2410  }
     2411  else {
     2412    settings.setValue("uploadMountpointsOut", "");
     2413  }
     2414  settings.setValue("uploadIntr", _uploadIntrComboBox->currentText());
     2415  settings.setValue("uploadSamplRtcmEphCorr", _uploadSamplRtcmEphCorrComboBox->currentText());
     2416  settings.setValue("uploadSamplSp3", _uploadSamplSp3ComboBox->currentText());
     2417  settings.setValue("uploadSamplClkRnx", _uploadSamplClkRnxSpinBox->value());
     2418  settings.setValue("uploadSamplBiaSnx", _uploadSamplBiaSnxSpinBox->value());
     2419  settings.setValue("uploadAntexFile", _uploadAntexFile->fileName());
     2420  // Upload Ephemeris
     2421  if (!uploadEphMountpointsOut.isEmpty()) {
     2422    settings.setValue("uploadEphMountpointsOut", uploadEphMountpointsOut);
     2423  }
     2424  else {
     2425    settings.setValue("uploadEphMountpointsOut", "");
     2426  }
     2427  settings.setValue("uploadSamplRtcmEph", _uploadSamplRtcmEphSpinBox->value());
     2428  // Upload Raw Data
     2429  if (!uploadRawMountpointsOut.isEmpty()) {
     2430    settings.setValue("uploadRawMountpointsOut", uploadRawMountpointsOut);
     2431  }
     2432  else {
     2433    settings.setValue("uploadRawMountpointsOut", "");
     2434  }
     2435  if (_caster) {
     2436    _caster->readMountPoints();
     2437  }
     2438
     2439  _pppWidgets.saveOptions();
     2440}
     2441
     2442// All get slots terminated
     2443////////////////////////////////////////////////////////////////////////////
     2444void bncWindow::slotGetThreadsFinished() {
     2445  BNC_CORE->slotMessage("All Get Threads Terminated", true);
     2446  delete _caster;    _caster = 0; BNC_CORE->setCaster(0);
     2447  delete _casterEph; _casterEph = 0;
     2448  _runningRealTime = false;
     2449  enableStartStop();
     2450}
     2451
     2452// Start It!
     2453////////////////////////////////////////////////////////////////////////////
     2454void bncWindow::slotStart() {
     2455  saveOptions();
     2456  if (_pppWidgets._dataSource->currentText() == "RINEX Files") {
     2457    _runningPPP = true;
     2458    enableStartStop();
     2459    _caster = new bncCaster(); BNC_CORE->setCaster(_caster);
     2460    BNC_CORE->startPPP();
     2461    _bncFigurePPP->reset();
     2462  }
     2463  else if (!_reqcActionComboBox->currentText().isEmpty()) {
     2464    if (_reqcActionComboBox->currentText() == "Analyze") {
     2465      _runningQC = true;
     2466      t_reqcAnalyze* reqcAnalyze = new t_reqcAnalyze(this);
     2467      connect(reqcAnalyze, SIGNAL(finished()), this, SLOT(slotPostProcessingFinished()));
     2468      reqcAnalyze->start();
    23702469    }
    23712470    else {
    2372         settings.setValue("cmbStreams", "");
    2373     }
    2374     settings.setValue("cmbMethod", _cmbMethodComboBox->currentText());
    2375     settings.setValue("cmbMaxres", _cmbMaxresLineEdit->text());
    2376     settings.setValue("cmbMaxdisplacement", _cmbMaxdisplacementLineEdit->text());
    2377     settings.setValue("cmbSampl", _cmbSamplComboBox->currentText());
    2378     settings.setValue("cmbLogpath", _cmbLogPath->text());
    2379     settings.setValue("cmbGps", _cmbGpsCheckBox->checkState());
    2380     settings.setValue("cmbGlo", _cmbGloCheckBox->checkState());
    2381     settings.setValue("cmbGal", _cmbGalCheckBox->checkState());
    2382     settings.setValue("cmbBds", _cmbBdsCheckBox->checkState());
    2383     settings.setValue("cmbQzss", _cmbQzssCheckBox->checkState());
    2384     settings.setValue("cmbSbas", _cmbSbasCheckBox->checkState());
    2385     settings.setValue("cmbNavic", _cmbNavicCheckBox->checkState());
    2386     settings.setValue("cmbBsxFile", _cmbBsxFile->fileName());
    2387 
    2388     // Upload Corrections
    2389     if (!uploadMountpointsOut.isEmpty()) {
    2390         settings.setValue("uploadMountpointsOut", uploadMountpointsOut);
    2391     }
    2392     else {
    2393         settings.setValue("uploadMountpointsOut", "");
    2394     }
    2395     settings.setValue("uploadIntr", _uploadIntrComboBox->currentText());
    2396     settings.setValue("uploadSamplRtcmEphCorr", _uploadSamplRtcmEphCorrComboBox->currentText());
    2397     settings.setValue("uploadSamplSp3", _uploadSamplSp3ComboBox->currentText());
    2398     settings.setValue("uploadSamplClkRnx", _uploadSamplClkRnxSpinBox->value());
    2399     settings.setValue("uploadSamplBiaSnx", _uploadSamplBiaSnxSpinBox->value());
    2400     settings.setValue("uploadAntexFile", _uploadAntexFile->fileName());
    2401     // Upload Ephemeris
    2402     if (!uploadEphMountpointsOut.isEmpty()) {
    2403         settings.setValue("uploadEphMountpointsOut", uploadEphMountpointsOut);
    2404     }
    2405     else {
    2406         settings.setValue("uploadEphMountpointsOut", "");
    2407     }
    2408     settings.setValue("uploadSamplRtcmEph", _uploadSamplRtcmEphSpinBox->value());
    2409     // Upload Raw Data
    2410     if (!uploadRawMountpointsOut.isEmpty()) {
    2411         settings.setValue("uploadRawMountpointsOut", uploadRawMountpointsOut);
    2412     }
    2413     else {
    2414         settings.setValue("uploadRawMountpointsOut", "");
    2415     }
    2416     if (_caster) {
    2417         _caster->readMountPoints();
    2418     }
    2419 
    2420     _pppWidgets.saveOptions();
    2421 }
    2422 
    2423 // All get slots terminated
    2424 ////////////////////////////////////////////////////////////////////////////
    2425 void bncWindow::slotGetThreadsFinished() {
    2426     BNC_CORE->slotMessage("All Get Threads Terminated", true);
     2471      _runningEdit = true;
     2472      t_reqcEdit* reqcEdit = new t_reqcEdit(this);
     2473      connect(reqcEdit, SIGNAL(finished()), this, SLOT(slotPostProcessingFinished()));
     2474      reqcEdit->start();
     2475    }
     2476    enableStartStop();
     2477  }
     2478  else if (!_sp3CompFileChooser->fileName().isEmpty()) {
     2479    _runningSp3Comp = true;
     2480    t_sp3Comp* sp3Comp = new t_sp3Comp(this);
     2481    connect(sp3Comp, SIGNAL(finished()), this, SLOT(slotPostProcessingFinished()));
     2482    sp3Comp->start();
     2483    enableStartStop();
     2484  }
     2485  else {
     2486    startRealTime();
     2487    BNC_CORE->startPPP();
     2488  }
     2489}
     2490
     2491// Start Real-Time (Retrieve Data etc.)
     2492////////////////////////////////////////////////////////////////////////////
     2493void bncWindow::startRealTime() {
     2494
     2495  _runningRealTime = true;
     2496
     2497  _bncFigurePPP->reset();
     2498
     2499  _actDeleteMountPoints->setEnabled(false);
     2500
     2501  enableStartStop();
     2502
     2503  _caster = new bncCaster();
     2504
     2505  BNC_CORE->setCaster(_caster);
     2506  BNC_CORE->setPortEph(_ephOutPortLineEdit->text().toInt());
     2507  BNC_CORE->setPortCorr(_corrPortLineEdit->text().toInt());
     2508  BNC_CORE->initCombination();
     2509
     2510  connect(_caster, SIGNAL(getThreadsFinished()), this, SLOT(slotGetThreadsFinished()));
     2511
     2512  connect(_caster, SIGNAL(mountPointsRead(QList<bncGetThread*>)), this, SLOT(slotMountPointsRead(QList<bncGetThread*>)));
     2513
     2514  BNC_CORE->slotMessage("========== Start BNC v" BNCVERSION " (" BNC_OS ") ==========", true);
     2515
     2516  bncSettings settings;
     2517
     2518  // Active panels
     2519  // -------------
     2520  if (!_rnxPathLineEdit->text().isEmpty())
     2521    BNC_CORE->slotMessage("Panel 'RINEX Observations' active", true);
     2522  if (!_ephPathLineEdit->text().isEmpty())
     2523    BNC_CORE->slotMessage("Panel 'RINEX Ephemeris' active", true);
     2524  if (!_corrPathLineEdit->text().isEmpty())
     2525    BNC_CORE->slotMessage("Panel 'Broadcast Corrections' active", true);
     2526  if (!_outPortLineEdit->text().isEmpty())
     2527    BNC_CORE->slotMessage("Panel 'Feed Engine' active", true);
     2528  if (!_serialMountPointLineEdit->text().isEmpty())
     2529    BNC_CORE->slotMessage("Panel 'Serial Output' active", true);
     2530  if (!_adviseObsRateComboBox->currentText().isEmpty())
     2531    BNC_CORE->slotMessage("Panel 'Outages' active", true);
     2532  if (!_miscMountLineEdit->text().isEmpty())
     2533    BNC_CORE->slotMessage("Panel 'Miscellaneous' active", true);
     2534  if (_pppWidgets._dataSource->currentText() == "Real-Time Streams")
     2535    BNC_CORE->slotMessage("Panel 'PPP' active", true);
     2536  if (_cmbTable->rowCount() > 0)
     2537    BNC_CORE->slotMessage("Panel 'Combine Corrections' active", true);
     2538  if (_uploadTable->rowCount() > 0)
     2539    BNC_CORE->slotMessage("Panel 'Upload Corrections' active", true);
     2540  if (_uploadEphTable->rowCount() > 0)
     2541    BNC_CORE->slotMessage("Panel 'UploadEphemeris' active", true);
     2542
     2543  QDir rnxdir(settings.value("rnxPath").toString());
     2544  if (!rnxdir.exists()) BNC_CORE->slotMessage("Cannot find RINEX Observations directory", true);
     2545
     2546  QString rnx_file = settings.value("rnxScript").toString();
     2547  if (!rnx_file.isEmpty()) {
     2548    QFile rnxfile(settings.value("rnxScript").toString());
     2549    if (!rnxfile.exists()) BNC_CORE->slotMessage("Cannot find RINEX Observations script", true);
     2550  }
     2551
     2552  QDir ephdir(settings.value("ephPath").toString());
     2553  if (!ephdir.exists()) BNC_CORE->slotMessage("Cannot find RINEX Ephemeris directory", true);
     2554
     2555  QDir corrdir(settings.value("corrPath").toString());
     2556  if (!corrdir.exists()) BNC_CORE->slotMessage("Cannot find Broadcast Corrections directory", true);
     2557
     2558  QString advise_file = settings.value("adviseScript").toString();
     2559  if (!advise_file.isEmpty()) {
     2560    QFile advisefile(settings.value("adviseScript").toString());
     2561    if (!advisefile.exists()) BNC_CORE->slotMessage("Cannot find Outages script", true);
     2562  }
     2563
     2564  _caster->readMountPoints();
     2565
     2566  _casterEph = new bncEphUploadCaster();
     2567}
     2568
     2569// Retrieve Data
     2570////////////////////////////////////////////////////////////////////////////
     2571void bncWindow::slotStop() {
     2572  int iRet = QMessageBox::question(this, "Stop", "Stop retrieving/processing data?",
     2573                                   QMessageBox::Yes, QMessageBox::No,
     2574                                   QMessageBox::NoButton);
     2575  if (iRet == QMessageBox::Yes) {
     2576    BNC_CORE->stopPPP();
     2577    BNC_CORE->stopCombination();
    24272578    delete _caster;    _caster = 0; BNC_CORE->setCaster(0);
    24282579    delete _casterEph; _casterEph = 0;
    24292580    _runningRealTime = false;
     2581    _runningPPP = false;
    24302582    enableStartStop();
    2431 }
    2432 
    2433 // Start It!
    2434 ////////////////////////////////////////////////////////////////////////////
    2435 void bncWindow::slotStart() {
    2436     saveOptions();
    2437     if (_pppWidgets._dataSource->currentText() == "RINEX Files") {
    2438         _runningPPP = true;
    2439         enableStartStop();
    2440         _caster = new bncCaster(); BNC_CORE->setCaster(_caster);
    2441         BNC_CORE->startPPP();
    2442         _bncFigurePPP->reset();
    2443     }
    2444     else if (!_reqcActionComboBox->currentText().isEmpty()) {
    2445         if (_reqcActionComboBox->currentText() == "Analyze") {
    2446             _runningQC = true;
    2447             t_reqcAnalyze* reqcAnalyze = new t_reqcAnalyze(this);
    2448             connect(reqcAnalyze, SIGNAL(finished()), this, SLOT(slotPostProcessingFinished()));
    2449             reqcAnalyze->start();
    2450         }
    2451         else {
    2452             _runningEdit = true;
    2453             t_reqcEdit* reqcEdit = new t_reqcEdit(this);
    2454             connect(reqcEdit, SIGNAL(finished()), this, SLOT(slotPostProcessingFinished()));
    2455             reqcEdit->start();
    2456         }
    2457         enableStartStop();
    2458     }
    2459     else if (!_sp3CompFileChooser->fileName().isEmpty()) {
    2460         _runningSp3Comp = true;
    2461         t_sp3Comp* sp3Comp = new t_sp3Comp(this);
    2462         connect(sp3Comp, SIGNAL(finished()), this, SLOT(slotPostProcessingFinished()));
    2463         sp3Comp->start();
    2464         enableStartStop();
    2465     }
    2466     else {
    2467         startRealTime();
    2468         BNC_CORE->startPPP();
    2469     }
    2470 }
    2471 
    2472 // Start Real-Time (Retrieve Data etc.)
    2473 ////////////////////////////////////////////////////////////////////////////
    2474 void bncWindow::startRealTime() {
    2475 
    2476     _runningRealTime = true;
    2477 
    2478     _bncFigurePPP->reset();
    2479 
     2583  }
     2584}
     2585
     2586// Close Application gracefully
     2587////////////////////////////////////////////////////////////////////////////
     2588void bncWindow::closeEvent(QCloseEvent* event) {
     2589
     2590  int iRet = QMessageBox::question(this, "Close", "Save Options?",
     2591                                   QMessageBox::Yes, QMessageBox::No,
     2592                                   QMessageBox::Cancel);
     2593
     2594  if (iRet == QMessageBox::Cancel) {
     2595    event->ignore();
     2596    return;
     2597  }
     2598  else if (iRet == QMessageBox::Yes) {
     2599    slotSaveOptions();
     2600  }
     2601
     2602  BNC_CORE->stopPPP();
     2603
     2604  QMainWindow::closeEvent(event);
     2605}
     2606
     2607// User changed the selection of mountPoints
     2608////////////////////////////////////////////////////////////////////////////
     2609void bncWindow::slotSelectionChanged() {
     2610  if (_mountPointsTable->selectedItems().isEmpty()) {
    24802611    _actDeleteMountPoints->setEnabled(false);
    2481 
    2482     enableStartStop();
    2483 
    2484     _caster = new bncCaster();
    2485 
    2486     BNC_CORE->setCaster(_caster);
    2487     BNC_CORE->setPortEph(_ephOutPortLineEdit->text().toInt());
    2488     BNC_CORE->setPortCorr(_corrPortLineEdit->text().toInt());
    2489     BNC_CORE->initCombination();
    2490 
    2491     connect(_caster, SIGNAL(getThreadsFinished()), this, SLOT(slotGetThreadsFinished()));
    2492 
    2493     connect(_caster, SIGNAL(mountPointsRead(QList<bncGetThread*>)), this, SLOT(slotMountPointsRead(QList<bncGetThread*>)));
    2494 
    2495     BNC_CORE->slotMessage("========== Start BNC v" BNCVERSION " (" BNC_OS ") ==========", true);
    2496 
     2612  }
     2613  else {
     2614    _actDeleteMountPoints->setEnabled(true);
     2615  }
     2616}
     2617
     2618// Display Program Messages
     2619////////////////////////////////////////////////////////////////////////////
     2620void bncWindow::slotWindowMessage(const QByteArray msg, bool showOnScreen) {
     2621  if (showOnScreen) {
     2622    _log->append(QDateTime::currentDateTime().toUTC().toString("yy-MM-dd hh:mm:ss ") + msg);
     2623  }
     2624}
     2625
     2626// About Message
     2627////////////////////////////////////////////////////////////////////////////
     2628void bncWindow::slotAbout() {
     2629  new bncAboutDlg(0);
     2630}
     2631
     2632//Flowchart
     2633////////////////////////////////////////////////////////////////////////////
     2634void bncWindow::slotFlowchart() {
     2635  new bncFlowchartDlg(0);
     2636}
     2637
     2638// Help Window
     2639////////////////////////////////////////////////////////////////////////////
     2640void bncWindow::slotHelp() {
     2641  QUrl url = QUrl::fromLocalFile(":/bnchelp.html");
     2642  new bncHlpDlg(0, url);
     2643}
     2644
     2645// Select Fonts
     2646////////////////////////////////////////////////////////////////////////////
     2647void bncWindow::slotFontSel() {
     2648  bool ok;
     2649  QFont newFont = QFontDialog::getFont(&ok, this->font(), this);
     2650  if (ok) {
    24972651    bncSettings settings;
    2498 
    2499     // Active panels
    2500     // -------------
    2501     if (!_rnxPathLineEdit->text().isEmpty())
    2502         BNC_CORE->slotMessage("Panel 'RINEX Observations' active", true);
    2503     if (!_ephPathLineEdit->text().isEmpty())
    2504         BNC_CORE->slotMessage("Panel 'RINEX Ephemeris' active", true);
    2505     if (!_corrPathLineEdit->text().isEmpty())
    2506         BNC_CORE->slotMessage("Panel 'Broadcast Corrections' active", true);
    2507     if (!_outPortLineEdit->text().isEmpty())
    2508         BNC_CORE->slotMessage("Panel 'Feed Engine' active", true);
    2509     if (!_serialMountPointLineEdit->text().isEmpty())
    2510         BNC_CORE->slotMessage("Panel 'Serial Output' active", true);
    2511     if (!_adviseObsRateComboBox->currentText().isEmpty())
    2512         BNC_CORE->slotMessage("Panel 'Outages' active", true);
    2513     if (!_miscMountLineEdit->text().isEmpty())
    2514         BNC_CORE->slotMessage("Panel 'Miscellaneous' active", true);
    2515     if (_pppWidgets._dataSource->currentText() == "Real-Time Streams")
    2516         BNC_CORE->slotMessage("Panel 'PPP' active", true);
    2517     if (_cmbTable->rowCount() > 0)
    2518         BNC_CORE->slotMessage("Panel 'Combine Corrections' active", true);
    2519     if (_uploadTable->rowCount() > 0)
    2520         BNC_CORE->slotMessage("Panel 'Upload Corrections' active", true);
    2521     if (_uploadEphTable->rowCount() > 0)
    2522         BNC_CORE->slotMessage("Panel 'UploadEphemeris' active", true);
    2523 
    2524     QDir rnxdir(settings.value("rnxPath").toString());
    2525     if (!rnxdir.exists()) BNC_CORE->slotMessage("Cannot find RINEX Observations directory", true);
    2526 
    2527     QString rnx_file = settings.value("rnxScript").toString();
    2528     if (!rnx_file.isEmpty()) {
    2529         QFile rnxfile(settings.value("rnxScript").toString());
    2530         if (!rnxfile.exists()) BNC_CORE->slotMessage("Cannot find RINEX Observations script", true);
    2531     }
    2532 
    2533     QDir ephdir(settings.value("ephPath").toString());
    2534     if (!ephdir.exists()) BNC_CORE->slotMessage("Cannot find RINEX Ephemeris directory", true);
    2535 
    2536     QDir corrdir(settings.value("corrPath").toString());
    2537     if (!corrdir.exists()) BNC_CORE->slotMessage("Cannot find Broadcast Corrections directory", true);
    2538 
    2539     QString advise_file = settings.value("adviseScript").toString();
    2540     if (!advise_file.isEmpty()) {
    2541         QFile advisefile(settings.value("adviseScript").toString());
    2542         if (!advisefile.exists()) BNC_CORE->slotMessage("Cannot find Outages script", true);
    2543     }
    2544 
    2545     _caster->readMountPoints();
    2546 
    2547     _casterEph = new bncEphUploadCaster();
    2548 }
    2549 
    2550 // Retrieve Data
    2551 ////////////////////////////////////////////////////////////////////////////
    2552 void bncWindow::slotStop() {
    2553     int iRet = QMessageBox::question(this, "Stop", "Stop retrieving/processing data?",
    2554         QMessageBox::Yes, QMessageBox::No,
    2555         QMessageBox::NoButton);
    2556     if (iRet == QMessageBox::Yes) {
    2557         BNC_CORE->stopPPP();
    2558         BNC_CORE->stopCombination();
    2559         delete _caster;    _caster = 0; BNC_CORE->setCaster(0);
    2560         delete _casterEph; _casterEph = 0;
    2561         _runningRealTime = false;
    2562         _runningPPP = false;
    2563         enableStartStop();
    2564     }
    2565 }
    2566 
    2567 // Close Application gracefully
    2568 ////////////////////////////////////////////////////////////////////////////
    2569 void bncWindow::closeEvent(QCloseEvent* event) {
    2570 
    2571     int iRet = QMessageBox::question(this, "Close", "Save Options?",
    2572         QMessageBox::Yes, QMessageBox::No,
    2573         QMessageBox::Cancel);
    2574 
    2575     if (iRet == QMessageBox::Cancel) {
    2576         event->ignore();
    2577         return;
    2578     }
    2579     else if (iRet == QMessageBox::Yes) {
    2580         slotSaveOptions();
    2581     }
    2582 
    2583     BNC_CORE->stopPPP();
    2584 
    2585     QMainWindow::closeEvent(event);
    2586 }
    2587 
    2588 // User changed the selection of mountPoints
    2589 ////////////////////////////////////////////////////////////////////////////
    2590 void bncWindow::slotSelectionChanged() {
    2591     if (_mountPointsTable->selectedItems().isEmpty()) {
    2592         _actDeleteMountPoints->setEnabled(false);
    2593     }
    2594     else {
    2595         _actDeleteMountPoints->setEnabled(true);
    2596     }
    2597 }
    2598 
    2599 // Display Program Messages
    2600 ////////////////////////////////////////////////////////////////////////////
    2601 void bncWindow::slotWindowMessage(const QByteArray msg, bool showOnScreen) {
    2602     if (showOnScreen) {
    2603         _log->append(QDateTime::currentDateTime().toUTC().toString("yy-MM-dd hh:mm:ss ") + msg);
    2604     }
    2605 }
    2606 
    2607 // About Message
    2608 ////////////////////////////////////////////////////////////////////////////
    2609 void bncWindow::slotAbout() {
    2610     new bncAboutDlg(0);
    2611 }
    2612 
    2613 //Flowchart
    2614 ////////////////////////////////////////////////////////////////////////////
    2615 void bncWindow::slotFlowchart() {
    2616     new bncFlowchartDlg(0);
    2617 }
    2618 
    2619 // Help Window
    2620 ////////////////////////////////////////////////////////////////////////////
    2621 void bncWindow::slotHelp() {
    2622     QUrl url = QUrl::fromLocalFile(":/bnchelp.html");
    2623     new bncHlpDlg(0, url);
    2624 }
    2625 
    2626 // Select Fonts
    2627 ////////////////////////////////////////////////////////////////////////////
    2628 void bncWindow::slotFontSel() {
    2629     bool ok;
    2630     QFont newFont = QFontDialog::getFont(&ok, this->font(), this);
    2631     if (ok) {
    2632         bncSettings settings;
    2633         settings.setValue("font", newFont.toString());
    2634         QApplication::setFont(newFont);
    2635         int ww = QFontMetrics(newFont).horizontalAdvance('w');
    2636         setMinimumSize(60 * ww, 80 * ww);
    2637         resize(60 * ww, 80 * ww);
    2638     }
     2652    settings.setValue("font", newFont.toString());
     2653    QApplication::setFont(newFont);
     2654    int ww = QFontMetrics(newFont).horizontalAdvance('w');
     2655    setMinimumSize(60 * ww, 80 * ww);
     2656    resize(60 * ww, 80 * ww);
     2657  }
    26392658}
    26402659
    26412660// Whats This Help
    26422661void bncWindow::slotWhatsThis() {
    2643     QWhatsThis::enterWhatsThisMode();
     2662  QWhatsThis::enterWhatsThisMode();
    26442663}
    26452664
     
    26472666////////////////////////////////////////////////////////////////////////////
    26482667void bncWindow::slotMountPointsRead(QList<bncGetThread*> threads) {
    2649     _threads = threads;
    2650 
    2651     _bncFigure->updateMountPoints();
    2652     _bncFigureLate->updateMountPoints();
    2653 
    2654     populateMountPointsTable();
    2655     bncSettings settings;
    2656     _outSamplComboBox->findText(settings.value("outSampl").toString());
    2657     _outWaitSpinBox->setValue(settings.value("outWait").toInt());
    2658     QListIterator<bncGetThread*> iTh(threads);
    2659     while (iTh.hasNext()) {
    2660         bncGetThread* thread = iTh.next();
    2661         for (int iRow = 0; iRow < _mountPointsTable->rowCount(); iRow++) {
    2662             QUrl url("//" + _mountPointsTable->item(iRow, 0)->text() +
    2663                 "@" + _mountPointsTable->item(iRow, 1)->text());
    2664             if (url == thread->mountPoint() &&
    2665                 _mountPointsTable->item(iRow, 4)->text() == thread->latitude() &&
    2666                 _mountPointsTable->item(iRow, 5)->text() == thread->longitude()) {
    2667                 ((bncTableItem*)_mountPointsTable->item(iRow, 8))->setGetThread(thread);
    2668                 disconnect(thread, SIGNAL(newBytes(QByteArray, double)), _bncFigure, SLOT(slotNewData(QByteArray, double)));
    2669                 connect(thread, SIGNAL(newBytes(QByteArray, double)), _bncFigure, SLOT(slotNewData(QByteArray, double)));
    2670                 disconnect(thread, SIGNAL(newLatency(QByteArray, double)), _bncFigureLate, SLOT(slotNewLatency(QByteArray, double)));
    2671                 connect(thread, SIGNAL(newLatency(QByteArray, double)), _bncFigureLate, SLOT(slotNewLatency(QByteArray, double)));
    2672                 break;
    2673             }
    2674         }
    2675     }
     2668  _threads = threads;
     2669
     2670  _bncFigure->updateMountPoints();
     2671  _bncFigureLate->updateMountPoints();
     2672
     2673  populateMountPointsTable();
     2674  bncSettings settings;
     2675  _outSamplComboBox->findText(settings.value("outSampl").toString());
     2676  _outWaitSpinBox->setValue(settings.value("outWait").toInt());
     2677  QListIterator<bncGetThread*> iTh(threads);
     2678  while (iTh.hasNext()) {
     2679    bncGetThread* thread = iTh.next();
     2680    for (int iRow = 0; iRow < _mountPointsTable->rowCount(); iRow++) {
     2681      QUrl url("//" + _mountPointsTable->item(iRow, 0)->text() +
     2682               "@" + _mountPointsTable->item(iRow, 1)->text());
     2683      if (url == thread->mountPoint() &&
     2684          _mountPointsTable->item(iRow, 4)->text() == thread->latitude() &&
     2685          _mountPointsTable->item(iRow, 5)->text() == thread->longitude()) {
     2686        ((bncTableItem*)_mountPointsTable->item(iRow, 8))->setGetThread(thread);
     2687        disconnect(thread, SIGNAL(newBytes(QByteArray, double)), _bncFigure, SLOT(slotNewData(QByteArray, double)));
     2688        connect(thread, SIGNAL(newBytes(QByteArray, double)), _bncFigure, SLOT(slotNewData(QByteArray, double)));
     2689        disconnect(thread, SIGNAL(newLatency(QByteArray, double)), _bncFigureLate, SLOT(slotNewLatency(QByteArray, double)));
     2690        connect(thread, SIGNAL(newLatency(QByteArray, double)), _bncFigureLate, SLOT(slotNewLatency(QByteArray, double)));
     2691        break;
     2692      }
     2693    }
     2694  }
    26762695}
    26772696
     
    26792698////////////////////////////////////////////////////////////////////////////
    26802699void bncWindow::CreateMenu() {
    2681     // Create Menus
    2682     // ------------
    2683     _menuFile = menuBar()->addMenu(tr("&File"));
    2684     _menuFile->addAction(_actFontSel);
    2685     _menuFile->addSeparator();
    2686     _menuFile->addAction(_actSaveOpt);
    2687     _menuFile->addSeparator();
    2688     _menuFile->addAction(_actQuit);
    2689 
    2690     _menuHlp = menuBar()->addMenu(tr("&Help"));
    2691     _menuHlp->addAction(_actHelp);
    2692     _menuHlp->addAction(_actFlowchart);
    2693     _menuHlp->addAction(_actAbout);
     2700  // Create Menus
     2701  // ------------
     2702  _menuFile = menuBar()->addMenu(tr("&File"));
     2703  _menuFile->addAction(_actFontSel);
     2704  _menuFile->addSeparator();
     2705  _menuFile->addAction(_actSaveOpt);
     2706  _menuFile->addSeparator();
     2707  _menuFile->addAction(_actQuit);
     2708
     2709  _menuHlp = menuBar()->addMenu(tr("&Help"));
     2710  _menuHlp->addAction(_actHelp);
     2711  _menuHlp->addAction(_actFlowchart);
     2712  _menuHlp->addAction(_actAbout);
    26942713}
    26952714
     
    26972716////////////////////////////////////////////////////////////////////////////
    26982717void bncWindow::AddToolbar() {
    2699     QToolBar* toolBar = new QToolBar;
    2700     addToolBar(Qt::BottomToolBarArea, toolBar);
    2701     toolBar->setMovable(false);
    2702     toolBar->addAction(_actAddMountPoints);
    2703     toolBar->addAction(_actDeleteMountPoints);
    2704     toolBar->addAction(_actMapMountPoints);
    2705     toolBar->addAction(_actStart);
    2706     toolBar->addAction(_actStop);
    2707     toolBar->addWidget(new QLabel("                                           "));
    2708     toolBar->addAction(_actwhatsthis);
     2718  QToolBar* toolBar = new QToolBar;
     2719  addToolBar(Qt::BottomToolBarArea, toolBar);
     2720  toolBar->setMovable(false);
     2721  toolBar->addAction(_actAddMountPoints);
     2722  toolBar->addAction(_actDeleteMountPoints);
     2723  toolBar->addAction(_actMapMountPoints);
     2724  toolBar->addAction(_actStart);
     2725  toolBar->addAction(_actStop);
     2726  toolBar->addWidget(new QLabel("                                           "));
     2727  toolBar->addAction(_actwhatsthis);
    27092728}
    27102729
     
    27122731////////////////////////////////////////////////////////////////////////////
    27132732bncAboutDlg::bncAboutDlg(QWidget* parent) :
    2714     QDialog(parent) {
    2715 
    2716     QTextBrowser* tb = new QTextBrowser;
    2717     QUrl url = QUrl::fromLocalFile(":/bncabout.html");
    2718     tb->setSource(url);
    2719     tb->setReadOnly(true);
    2720 
    2721     int ww = QFontMetrics(font()).horizontalAdvance('w');
    2722     QPushButton* _closeButton = new QPushButton("Close");
    2723     _closeButton->setMaximumWidth(10 * ww);
    2724     connect(_closeButton, SIGNAL(clicked()), this, SLOT(close()));
    2725 
    2726     QGridLayout* dlgLayout = new QGridLayout();
    2727     QLabel* img = new QLabel();
    2728     img->setPixmap(QPixmap(":ntrip-logo.png"));
    2729     dlgLayout->addWidget(img, 0, 0);
    2730     dlgLayout->addWidget(new QLabel("BKG Ntrip Client (BNC) Version " BNCVERSION), 0, 1);
    2731     dlgLayout->addWidget(tb, 1, 0, 1, 2);
    2732     dlgLayout->addWidget(_closeButton, 2, 1, Qt::AlignRight);
    2733 
    2734     setLayout(dlgLayout);
    2735     resize(60 * ww, 60 * ww);
    2736     setWindowTitle("About BNC");
    2737     show();
     2733  QDialog(parent) {
     2734
     2735  QTextBrowser* tb = new QTextBrowser;
     2736  QUrl url = QUrl::fromLocalFile(":/bncabout.html");
     2737  tb->setSource(url);
     2738  tb->setReadOnly(true);
     2739
     2740  int ww = QFontMetrics(font()).horizontalAdvance('w');
     2741  QPushButton* _closeButton = new QPushButton("Close");
     2742  _closeButton->setMaximumWidth(10 * ww);
     2743  connect(_closeButton, SIGNAL(clicked()), this, SLOT(close()));
     2744
     2745  QGridLayout* dlgLayout = new QGridLayout();
     2746  QLabel* img = new QLabel();
     2747  img->setPixmap(QPixmap(":ntrip-logo.png"));
     2748  dlgLayout->addWidget(img, 0, 0);
     2749  dlgLayout->addWidget(new QLabel("BKG Ntrip Client (BNC) Version " BNCVERSION), 0, 1);
     2750  dlgLayout->addWidget(tb, 1, 0, 1, 2);
     2751  dlgLayout->addWidget(_closeButton, 2, 1, Qt::AlignRight);
     2752
     2753  setLayout(dlgLayout);
     2754  resize(60 * ww, 60 * ww);
     2755  setWindowTitle("About BNC");
     2756  show();
    27382757}
    27392758
     
    27472766////////////////////////////////////////////////////////////////////////////
    27482767bncFlowchartDlg::bncFlowchartDlg(QWidget* parent) :
    2749     QDialog(parent) {
    2750 
    2751     int ww = QFontMetrics(font()).horizontalAdvance('w');
    2752     QPushButton* _closeButton = new QPushButton("Close");
    2753     _closeButton->setMaximumWidth(10 * ww);
    2754     connect(_closeButton, SIGNAL(clicked()), this, SLOT(close()));
    2755 
    2756     QGridLayout* dlgLayout = new QGridLayout();
    2757     QLabel* img = new QLabel();
    2758     img->setPixmap(QPixmap(":bncflowchart.png"));
    2759     dlgLayout->addWidget(img, 0, 0);
    2760     dlgLayout->addWidget(_closeButton, 1, 0, Qt::AlignLeft);
    2761 
    2762     setLayout(dlgLayout);
    2763     setWindowTitle("Flow Chart");
    2764     show();
     2768  QDialog(parent) {
     2769
     2770  int ww = QFontMetrics(font()).horizontalAdvance('w');
     2771  QPushButton* _closeButton = new QPushButton("Close");
     2772  _closeButton->setMaximumWidth(10 * ww);
     2773  connect(_closeButton, SIGNAL(clicked()), this, SLOT(close()));
     2774
     2775  QGridLayout* dlgLayout = new QGridLayout();
     2776  QLabel* img = new QLabel();
     2777  img->setPixmap(QPixmap(":bncflowchart.png"));
     2778  dlgLayout->addWidget(img, 0, 0);
     2779  dlgLayout->addWidget(_closeButton, 1, 0, Qt::AlignLeft);
     2780
     2781  setLayout(dlgLayout);
     2782  setWindowTitle("Flow Chart");
     2783  show();
    27652784}
    27662785
     
    27742793void bncWindow::enableWidget(bool enable, QWidget* widget) {
    27752794
    2776     const static QPalette paletteWhite(QColor(255, 255, 255));
    2777     const static QPalette paletteGray(QColor(230, 230, 230));
    2778 
    2779     widget->setEnabled(enable);
    2780     if (enable) {
    2781         widget->setPalette(paletteWhite);
     2795  const static QPalette paletteWhite(QColor(255, 255, 255));
     2796  const static QPalette paletteGray(QColor(230, 230, 230));
     2797
     2798  widget->setEnabled(enable);
     2799  if (enable) {
     2800    widget->setPalette(paletteWhite);
     2801  }
     2802  else {
     2803    widget->setPalette(paletteGray);
     2804  }
     2805}
     2806
     2807//  Bnc Text
     2808////////////////////////////////////////////////////////////////////////////
     2809void bncWindow::slotBncTextChanged() {
     2810
     2811  const static QPalette paletteWhite(QColor(255, 255, 255));
     2812  const static QPalette paletteGray(QColor(230, 230, 230));
     2813
     2814  bool enable = true;
     2815
     2816  // Proxy
     2817  //------
     2818  if (sender() == 0 || sender() == _proxyHostLineEdit) {
     2819    enable = !_proxyHostLineEdit->text().isEmpty();
     2820    enableWidget(enable, _proxyPortLineEdit);
     2821  }
     2822
     2823  // RINEX Observations
     2824  // ------------------
     2825  if (sender() == 0 || sender() == _rnxPathLineEdit) {
     2826    enable = !_rnxPathLineEdit->text().isEmpty();
     2827    enableWidget(enable, _rnxIntrComboBox);
     2828    enableWidget(enable, _rnxSamplComboBox);
     2829    enableWidget(enable, _rnxSkelExtComboBox);
     2830    enableWidget(enable, _rnxSkelPathLineEdit);
     2831    enableWidget(enable, _rnxFileCheckBox);
     2832    enableWidget(enable, _rnxScrpLineEdit);
     2833    enableWidget(enable, _rnxV2Priority);
     2834    enableWidget(enable, _rnxVersComboBox);
     2835
     2836    bool enable1 = true;
     2837    enable1 = _rnxVersComboBox->currentText() == "2";
     2838    if (enable && enable1) {
     2839      enableWidget(true, _rnxV2Priority);
     2840    }
     2841    if (enable && !enable1) {
     2842      enableWidget(false, _rnxV2Priority);
     2843    }
     2844  }
     2845
     2846  // RINEX Observations, Signal Priority
     2847  // -----------------------------------
     2848  if (sender() == 0 || sender() == _rnxVersComboBox) {
     2849    if (!_rnxPathLineEdit->text().isEmpty()) {
     2850      enableWidget(enable, _rnxIntrComboBox);
     2851      enable = _rnxVersComboBox->currentText() == "2";
     2852      enableWidget(enable, _rnxV2Priority);
     2853    }
     2854  }
     2855
     2856  // RINEX Ephemeris
     2857  // ---------------
     2858  if (sender() == 0 || sender() == _ephPathLineEdit || sender() == _ephOutPortLineEdit) {
     2859    enable = !_ephPathLineEdit->text().isEmpty() || !_ephOutPortLineEdit->text().isEmpty();
     2860    enableWidget(enable, _ephIntrComboBox);
     2861    enableWidget(enable, _ephVersComboBox);
     2862    //enableWidget(enable, _ephVersComboBox);
     2863    //enableWidget(enable, _ephFilePerStation);
     2864  }
     2865
     2866  // Broadcast Corrections
     2867  // ---------------------
     2868  if (sender() == 0 || sender() == _corrPathLineEdit || sender() == _corrPortLineEdit) {
     2869    enable = !_corrPathLineEdit->text().isEmpty() || !_corrPortLineEdit->text().isEmpty();
     2870    enableWidget(enable, _corrIntrComboBox);
     2871  }
     2872
     2873  // Feed Engine
     2874  // -----------
     2875  if (sender() == 0 || sender() == _outPortLineEdit || sender() == _outFileLineEdit) {
     2876    enable = !_outPortLineEdit->text().isEmpty() || !_outFileLineEdit->text().isEmpty();
     2877    enableWidget(enable, _outWaitSpinBox);
     2878    enableWidget(enable, _outSamplComboBox);
     2879  }
     2880
     2881  // Serial Output
     2882  // -------------
     2883  if (sender() == 0 ||
     2884      sender() == _serialMountPointLineEdit ||
     2885      sender() == _serialAutoNMEAComboBox) {
     2886    enable = !_serialMountPointLineEdit->text().isEmpty();
     2887    enableWidget(enable, _serialPortNameLineEdit);
     2888    enableWidget(enable, _serialBaudRateComboBox);
     2889    enableWidget(enable, _serialParityComboBox);
     2890    enableWidget(enable, _serialDataBitsComboBox);
     2891    enableWidget(enable, _serialStopBitsComboBox);
     2892    enableWidget(enable, _serialFlowControlComboBox);
     2893    enableWidget(enable, _serialAutoNMEAComboBox);
     2894    if (enable && _serialAutoNMEAComboBox->currentText() == "Auto") {
     2895      enableWidget(true, _serialFileNMEALineEdit);
     2896      enableWidget(false, _serialHeightNMEALineEdit);
     2897      enableWidget(true, _serialNMEASamplingSpinBox);
     2898    }
     2899    else if (enable && _serialAutoNMEAComboBox->currentText().contains("Manual")) {
     2900      enableWidget(false, _serialFileNMEALineEdit);
     2901      enableWidget(true, _serialHeightNMEALineEdit);
     2902      enableWidget(true, _serialNMEASamplingSpinBox);
    27822903    }
    27832904    else {
    2784         widget->setPalette(paletteGray);
    2785     }
    2786 }
    2787 
    2788 //  Bnc Text
    2789 ////////////////////////////////////////////////////////////////////////////
    2790 void bncWindow::slotBncTextChanged() {
    2791 
    2792     const static QPalette paletteWhite(QColor(255, 255, 255));
    2793     const static QPalette paletteGray(QColor(230, 230, 230));
    2794 
    2795     bool enable = true;
    2796 
    2797     // Proxy
    2798     //------
    2799     if (sender() == 0 || sender() == _proxyHostLineEdit) {
    2800         enable = !_proxyHostLineEdit->text().isEmpty();
    2801         enableWidget(enable, _proxyPortLineEdit);
    2802     }
    2803 
    2804     // RINEX Observations
    2805     // ------------------
    2806     if (sender() == 0 || sender() == _rnxPathLineEdit) {
    2807         enable = !_rnxPathLineEdit->text().isEmpty();
    2808         enableWidget(enable, _rnxIntrComboBox);
    2809         enableWidget(enable, _rnxSamplComboBox);
    2810         enableWidget(enable, _rnxSkelExtComboBox);
    2811         enableWidget(enable, _rnxSkelPathLineEdit);
    2812         enableWidget(enable, _rnxFileCheckBox);
    2813         enableWidget(enable, _rnxScrpLineEdit);
    2814         enableWidget(enable, _rnxV2Priority);
    2815         enableWidget(enable, _rnxVersComboBox);
    2816 
    2817         bool enable1 = true;
    2818         enable1 = _rnxVersComboBox->currentText() == "2";
    2819         if (enable && enable1) {
    2820             enableWidget(true, _rnxV2Priority);
     2905      enableWidget(false, _serialFileNMEALineEdit);
     2906      enableWidget(false, _serialHeightNMEALineEdit);
     2907      enableWidget(false, _serialNMEASamplingSpinBox);
     2908    }
     2909  }
     2910
     2911  // Outages
     2912  // -------
     2913  if (sender() == 0 || sender() == _adviseObsRateComboBox) {
     2914    enable = !_adviseObsRateComboBox->currentText().isEmpty();
     2915    enableWidget(enable, _adviseFailSpinBox);
     2916    enableWidget(enable, _adviseRecoSpinBox);
     2917    enableWidget(enable, _adviseScriptLineEdit);
     2918  }
     2919
     2920  // Miscellaneous
     2921  // -------------
     2922  if (sender() == 0 || sender() == _miscMountLineEdit) {
     2923    enable = !_miscMountLineEdit->text().isEmpty();
     2924    enableWidget(enable, _miscIntrComboBox);
     2925    enableWidget(enable, _miscScanRTCMCheckBox);
     2926    enableWidget(enable, _miscPortLineEdit);
     2927  }
     2928
     2929  // Combine Corrections
     2930  // -------------------
     2931  if (sender() == 0 || sender() == _cmbTable) {
     2932    int iRow = _cmbTable->rowCount();
     2933    if (iRow > 0) {
     2934      enableWidget(true, _cmbMethodComboBox);
     2935      enableWidget(true, _cmbMaxresLineEdit);
     2936      enableWidget(true, _cmbMaxdisplacementLineEdit);
     2937      enableWidget(true, _cmbSamplComboBox);
     2938      enableWidget(true, _cmbLogPath);
     2939      enableWidget(true, _cmbGpsCheckBox);
     2940      enableWidget(true, _cmbGloCheckBox);
     2941      enableWidget(true, _cmbGalCheckBox);
     2942      enableWidget(true, _cmbBdsCheckBox);
     2943      enableWidget(true, _cmbQzssCheckBox);
     2944      enableWidget(true, _cmbSbasCheckBox);
     2945      enableWidget(true, _cmbNavicCheckBox);
     2946      enableWidget(true, _cmbBsxFile);
     2947    }
     2948    else {
     2949      enableWidget(false, _cmbMethodComboBox);
     2950      enableWidget(false, _cmbMaxresLineEdit);
     2951      enableWidget(false, _cmbMaxdisplacementLineEdit);
     2952      enableWidget(false, _cmbSamplComboBox);
     2953      enableWidget(false, _cmbLogPath);
     2954      enableWidget(false, _cmbGpsCheckBox);
     2955      enableWidget(false, _cmbGloCheckBox);
     2956      enableWidget(false, _cmbGalCheckBox);
     2957      enableWidget(false, _cmbBdsCheckBox);
     2958      enableWidget(false, _cmbQzssCheckBox);
     2959      enableWidget(false, _cmbSbasCheckBox);
     2960      enableWidget(false, _cmbNavicCheckBox);
     2961      enableWidget(false, _cmbBsxFile);
     2962    }
     2963  }
     2964
     2965  // Upload(clk)
     2966  // -----------
     2967  int iRow = _uploadTable->rowCount();
     2968  if (iRow > 0) {
     2969    enableWidget(true, _uploadIntrComboBox);
     2970    enableWidget(true, _uploadSamplRtcmEphCorrComboBox);
     2971    enableWidget(true, _uploadSamplClkRnxSpinBox);
     2972    enableWidget(true, _uploadSamplBiaSnxSpinBox);
     2973    enableWidget(true, _uploadSamplSp3ComboBox);
     2974    enableWidget(true, _uploadAntexFile);
     2975  }
     2976  else {
     2977    enableWidget(false, _uploadIntrComboBox);
     2978    enableWidget(false, _uploadSamplRtcmEphCorrComboBox);
     2979    enableWidget(false, _uploadSamplClkRnxSpinBox);
     2980    enableWidget(false, _uploadSamplBiaSnxSpinBox);
     2981    enableWidget(false, _uploadSamplSp3ComboBox);
     2982    enableWidget(false, _uploadAntexFile);
     2983  }
     2984
     2985  // Upload(eph)
     2986  // -----------
     2987  iRow = _uploadEphTable->rowCount();
     2988  if (iRow > 0) {
     2989    enableWidget(true, _uploadSamplRtcmEphSpinBox);
     2990  }
     2991  else {
     2992    enableWidget(false, _uploadSamplRtcmEphSpinBox);
     2993  }
     2994
     2995  // QC
     2996  // --
     2997  if (sender() == 0 || sender() == _reqcActionComboBox || sender() == _reqcSkyPlotSignals) {
     2998    enable = !_reqcActionComboBox->currentText().isEmpty();
     2999    bool enable10 = _reqcActionComboBox->currentText() == "Edit/Concatenate";
     3000    //  bool enablePlot = !_reqcSkyPlotSignals->text().isEmpty();
     3001    enableWidget(enable, _reqcObsFileChooser);
     3002    enableWidget(enable, _reqcNavFileChooser);
     3003    enableWidget(enable, _reqcOutLogLineEdit);
     3004    enableWidget(enable && enable10, _reqcEditOptionButton);
     3005    enableWidget(enable && enable10, _reqcOutObsLineEdit);
     3006    enableWidget(enable && enable10, _reqcOutNavLineEdit);
     3007    enableWidget(enable && !enable10, _reqcLogSummaryOnly);
     3008    enableWidget(enable && !enable10, _reqcSkyPlotSignals);
     3009    //  enableWidget(enable && !enable10 && enablePlot, _reqcPlotDirLineEdit);
     3010    enableWidget(enable && !enable10, _reqcPlotDirLineEdit);
     3011  }
     3012
     3013  // SP3 File Comparison
     3014  // -------------------
     3015  if (sender() == 0 || sender() == _sp3CompFileChooser) {
     3016    enable = !_sp3CompFileChooser->fileName().isEmpty();
     3017    enableWidget(enable, _sp3CompLogLineEdit);
     3018    enableWidget(enable, _sp3CompExclude);
     3019    enableWidget(enable, _sp3CompSummaryOnly);
     3020  }
     3021
     3022  enableStartStop();
     3023}
     3024
     3025//
     3026////////////////////////////////////////////////////////////////////////////
     3027void bncWindow::slotAddCmbRow() {
     3028  int iRow = _cmbTable->rowCount();
     3029  _cmbTable->insertRow(iRow);
     3030  for (int iCol = 0; iCol < _cmbTable->columnCount(); iCol++) {
     3031    _cmbTable->setItem(iRow, iCol, new QTableWidgetItem(""));
     3032  }
     3033}
     3034
     3035//
     3036////////////////////////////////////////////////////////////////////////////
     3037void bncWindow::slotDelCmbRow() {
     3038
     3039  const static QPalette paletteWhite(QColor(255, 255, 255));
     3040  const static QPalette paletteGray(QColor(230, 230, 230));
     3041
     3042  int nRows = _cmbTable->rowCount();
     3043  std::vector <bool> flg(nRows);
     3044  for (int iRow = 0; iRow < nRows; iRow++) {
     3045    if (_cmbTable->item(iRow, 1)->isSelected()) {
     3046      flg[iRow] = true;
     3047    }
     3048    else {
     3049      flg[iRow] = false;
     3050    }
     3051  }
     3052  for (int iRow = nRows - 1; iRow >= 0; iRow--) {
     3053    if (flg[iRow]) {
     3054      _cmbTable->removeRow(iRow);
     3055    }
     3056  }
     3057  nRows = _cmbTable->rowCount();
     3058  if (nRows < 1) {
     3059    enableWidget(false, _cmbMethodComboBox);
     3060    enableWidget(false, _cmbMaxresLineEdit);
     3061    enableWidget(false, _cmbMaxdisplacementLineEdit);
     3062    enableWidget(false, _cmbSamplComboBox);
     3063    enableWidget(false, _cmbLogPath);
     3064  }
     3065}
     3066
     3067//
     3068////////////////////////////////////////////////////////////////////////////
     3069void bncWindow::populateCmbTable() {
     3070
     3071  for (int iRow = _cmbTable->rowCount() - 1; iRow >= 0; iRow--) {
     3072    _cmbTable->removeRow(iRow);
     3073  }
     3074
     3075  bncSettings settings;
     3076
     3077  int iRow = -1;
     3078  QListIterator<QString> it(settings.value("cmbStreams").toStringList());
     3079  while (it.hasNext()) {
     3080    QStringList hlp = it.next().split(" ");
     3081    if (hlp.size() > 2) {
     3082      ++iRow;
     3083      _cmbTable->insertRow(iRow);
     3084    }
     3085    for (int iCol = 0; iCol < hlp.size(); iCol++) {
     3086      _cmbTable->setItem(iRow, iCol, new QTableWidgetItem(hlp[iCol]));
     3087    }
     3088  }
     3089}
     3090
     3091//
     3092////////////////////////////////////////////////////////////////////////////
     3093void bncWindow::slotAddUploadRow() {
     3094  int iRow = _uploadTable->rowCount();
     3095  _uploadTable->insertRow(iRow);
     3096  for (int iCol = 0; iCol < _uploadTable->columnCount(); iCol++) {
     3097    if (iCol == 3) {
     3098      QComboBox* ntripversion = new QComboBox();
     3099      ntripversion->setEditable(false);
     3100      ntripversion->addItems(QString("2s,2,1").split(","));
     3101      ntripversion->setFrame(false);
     3102      _uploadTable->setCellWidget(iRow, iCol, ntripversion);
     3103
     3104    }
     3105    else if (iCol == 4) {
     3106      QLineEdit* user = new QLineEdit();
     3107      user->setFrame(false);
     3108      _uploadTable->setCellWidget(iRow, iCol, user);
     3109    }
     3110    else if (iCol == 5) {
     3111      QLineEdit* passwd = new QLineEdit();
     3112      passwd->setFrame(false);
     3113      passwd->setEchoMode(QLineEdit::PasswordEchoOnEdit);
     3114      _uploadTable->setCellWidget(iRow, iCol, passwd);
     3115    }
     3116    else if (iCol == 6) {
     3117      QComboBox* system = new QComboBox();
     3118      system->setEditable(false);
     3119      system->addItems(QString("IGS20,ETRF2000,GDA2020,SIRGAS2000,DREF91,Custom").split(","));
     3120      system->setFrame(false);
     3121      _uploadTable->setCellWidget(iRow, iCol, system);
     3122    }
     3123    else if (iCol == 7) {
     3124      QComboBox* format = new QComboBox();
     3125      format->setEditable(false);
     3126      //format->addItems(QString("IGS-SSR,RTCM-SSR,RTCM-NEW-SSR").split(","));
     3127      format->addItems(QString("IGS-SSR,RTCM-SSR").split(","));
     3128      format->setFrame(false);
     3129      _uploadTable->setCellWidget(iRow, iCol, format);
     3130    }
     3131    else if (iCol == 8) {
     3132      QCheckBox* com = new QCheckBox();
     3133      _uploadTable->setCellWidget(iRow, iCol, com);
     3134    }
     3135    else if (iCol == 15) {
     3136      bncTableItem* bncIt = new bncTableItem();
     3137      bncIt->setFlags(bncIt->flags() & ~Qt::ItemIsEditable);
     3138      _uploadTable->setItem(iRow, iCol, bncIt);
     3139      BNC_CORE->_uploadTableItems[iRow] = bncIt;
     3140    }
     3141    else {
     3142      _uploadTable->setItem(iRow, iCol, new QTableWidgetItem(""));
     3143    }
     3144  }
     3145}
     3146
     3147//
     3148////////////////////////////////////////////////////////////////////////////
     3149void bncWindow::slotDelUploadRow() {
     3150  BNC_CORE->_uploadTableItems.clear();
     3151  int nRows = _uploadTable->rowCount();
     3152  std::vector <bool> flg(nRows);
     3153  for (int iRow = 0; iRow < nRows; iRow++) {
     3154    if (_uploadTable->item(iRow, 1)->isSelected()) {
     3155      flg[iRow] = true;
     3156    }
     3157    else {
     3158      flg[iRow] = false;
     3159    }
     3160  }
     3161  for (int iRow = nRows - 1; iRow >= 0; iRow--) {
     3162    if (flg[iRow]) {
     3163      _uploadTable->removeRow(iRow);
     3164    }
     3165  }
     3166  for (int iRow = 0; iRow < _uploadTable->rowCount(); iRow++) {
     3167    BNC_CORE->_uploadTableItems[iRow] =
     3168      (bncTableItem*)_uploadTable->item(iRow, 14);
     3169  }
     3170  nRows = _uploadTable->rowCount();
     3171  if (nRows < 1) {
     3172    enableWidget(false, _uploadIntrComboBox);
     3173    enableWidget(false, _uploadSamplRtcmEphCorrComboBox);
     3174    enableWidget(false, _uploadSamplSp3ComboBox);
     3175    enableWidget(false, _uploadSamplClkRnxSpinBox);
     3176    enableWidget(false, _uploadAntexFile);
     3177  }
     3178}
     3179
     3180//
     3181////////////////////////////////////////////////////////////////////////////
     3182void bncWindow::populateUploadTable() {
     3183  for (int iRow = _uploadTable->rowCount() - 1; iRow >= 0; iRow--) {
     3184    _uploadTable->removeRow(iRow);
     3185  }
     3186
     3187  bncSettings settings;
     3188
     3189  int iRow = -1;
     3190  QListIterator<QString> it(settings.value("uploadMountpointsOut").toStringList());
     3191
     3192  while (it.hasNext()) {
     3193    QStringList hlp = it.next().split(",");
     3194    if (hlp.size() > 6) {
     3195      ++iRow;
     3196      _uploadTable->insertRow(iRow);
     3197    }
     3198    for (int iCol = 0; iCol < hlp.size(); iCol++) {
     3199      if (iCol == 3) {
     3200        QComboBox* ntripversion = new QComboBox();
     3201        ntripversion->setEditable(false);
     3202        ntripversion->addItems(QString("1,2,2s").split(","));
     3203        ntripversion->setFrame(false);
     3204        ntripversion->setCurrentIndex(ntripversion->findText(hlp[iCol]));
     3205        _uploadTable->setCellWidget(iRow, iCol, ntripversion);
     3206      }
     3207      else if (iCol == 4) {
     3208        QLineEdit* user = new QLineEdit();
     3209        user->setFrame(false);
     3210        user->setText(hlp[iCol]);
     3211        _uploadTable->setCellWidget(iRow, iCol, user);
     3212      }
     3213      else if (iCol == 5) {
     3214        QLineEdit* passwd = new QLineEdit();
     3215        passwd->setFrame(false);
     3216        passwd->setEchoMode(QLineEdit::PasswordEchoOnEdit);
     3217        passwd->setText(hlp[iCol]);
     3218        _uploadTable->setCellWidget(iRow, iCol, passwd);
     3219      }
     3220      else if (iCol == 6) {
     3221        QComboBox* system = new QComboBox();
     3222        system->setEditable(false);
     3223        system->addItems(QString("IGS20,ETRF2000,GDA2020,SIRGAS2000,DREF91,Custom").split(","));
     3224        system->setFrame(false);
     3225        system->setCurrentIndex(system->findText(hlp[iCol]));
     3226        _uploadTable->setCellWidget(iRow, iCol, system);
     3227      }
     3228      else if (iCol == 7) {
     3229        QComboBox* format = new QComboBox();
     3230        format->setEditable(false);
     3231        //format->addItems(QString("IGS-SSR,RTCM-SSR,RTCM-NEW-SSR").split(","));
     3232        format->addItems(QString("IGS-SSR,RTCM-SSR").split(","));
     3233        format->setFrame(false);
     3234        format->setCurrentIndex(format->findText(hlp[iCol]));
     3235        _uploadTable->setCellWidget(iRow, iCol, format);
     3236      }
     3237      else if (iCol == 8) {
     3238        QCheckBox* com = new QCheckBox();
     3239        if (hlp[iCol].toInt() == Qt::Checked) {
     3240          com->setCheckState(Qt::Checked);
    28213241        }
    2822         if (enable && !enable1) {
    2823             enableWidget(false, _rnxV2Priority);
    2824         }
    2825     }
    2826 
    2827     // RINEX Observations, Signal Priority
    2828     // -----------------------------------
    2829     if (sender() == 0 || sender() == _rnxVersComboBox) {
    2830         if (!_rnxPathLineEdit->text().isEmpty()) {
    2831             enableWidget(enable, _rnxIntrComboBox);
    2832             enable = _rnxVersComboBox->currentText() == "2";
    2833             enableWidget(enable, _rnxV2Priority);
    2834         }
    2835     }
    2836 
    2837     // RINEX Ephemeris
    2838     // ---------------
    2839     if (sender() == 0 || sender() == _ephPathLineEdit || sender() == _ephOutPortLineEdit) {
    2840         enable = !_ephPathLineEdit->text().isEmpty() || !_ephOutPortLineEdit->text().isEmpty();
    2841         enableWidget(enable, _ephIntrComboBox);
    2842         enableWidget(enable, _ephVersComboBox);
    2843         //enableWidget(enable, _ephVersComboBox);
    2844         //enableWidget(enable, _ephFilePerStation);
    2845     }
    2846 
    2847     // Broadcast Corrections
    2848     // ---------------------
    2849     if (sender() == 0 || sender() == _corrPathLineEdit || sender() == _corrPortLineEdit) {
    2850         enable = !_corrPathLineEdit->text().isEmpty() || !_corrPortLineEdit->text().isEmpty();
    2851         enableWidget(enable, _corrIntrComboBox);
    2852     }
    2853 
    2854     // Feed Engine
    2855     // -----------
    2856     if (sender() == 0 || sender() == _outPortLineEdit || sender() == _outFileLineEdit) {
    2857         enable = !_outPortLineEdit->text().isEmpty() || !_outFileLineEdit->text().isEmpty();
    2858         enableWidget(enable, _outWaitSpinBox);
    2859         enableWidget(enable, _outSamplComboBox);
    2860     }
    2861 
    2862     // Serial Output
    2863     // -------------
    2864     if (sender() == 0 ||
    2865         sender() == _serialMountPointLineEdit ||
    2866         sender() == _serialAutoNMEAComboBox) {
    2867         enable = !_serialMountPointLineEdit->text().isEmpty();
    2868         enableWidget(enable, _serialPortNameLineEdit);
    2869         enableWidget(enable, _serialBaudRateComboBox);
    2870         enableWidget(enable, _serialParityComboBox);
    2871         enableWidget(enable, _serialDataBitsComboBox);
    2872         enableWidget(enable, _serialStopBitsComboBox);
    2873         enableWidget(enable, _serialFlowControlComboBox);
    2874         enableWidget(enable, _serialAutoNMEAComboBox);
    2875         if (enable && _serialAutoNMEAComboBox->currentText() == "Auto") {
    2876             enableWidget(true, _serialFileNMEALineEdit);
    2877             enableWidget(false, _serialHeightNMEALineEdit);
    2878             enableWidget(true, _serialNMEASamplingSpinBox);
    2879         }
    2880         else if (enable && _serialAutoNMEAComboBox->currentText().contains("Manual")) {
    2881             enableWidget(false, _serialFileNMEALineEdit);
    2882             enableWidget(true, _serialHeightNMEALineEdit);
    2883             enableWidget(true, _serialNMEASamplingSpinBox);
    2884         }
    2885         else {
    2886             enableWidget(false, _serialFileNMEALineEdit);
    2887             enableWidget(false, _serialHeightNMEALineEdit);
    2888             enableWidget(false, _serialNMEASamplingSpinBox);
    2889         }
    2890     }
    2891 
    2892     // Outages
    2893     // -------
    2894     if (sender() == 0 || sender() == _adviseObsRateComboBox) {
    2895         enable = !_adviseObsRateComboBox->currentText().isEmpty();
    2896         enableWidget(enable, _adviseFailSpinBox);
    2897         enableWidget(enable, _adviseRecoSpinBox);
    2898         enableWidget(enable, _adviseScriptLineEdit);
    2899     }
    2900 
    2901     // Miscellaneous
    2902     // -------------
    2903     if (sender() == 0 || sender() == _miscMountLineEdit) {
    2904         enable = !_miscMountLineEdit->text().isEmpty();
    2905         enableWidget(enable, _miscIntrComboBox);
    2906         enableWidget(enable, _miscScanRTCMCheckBox);
    2907         enableWidget(enable, _miscPortLineEdit);
    2908     }
    2909 
    2910     // Combine Corrections
    2911     // -------------------
    2912     if (sender() == 0 || sender() == _cmbTable) {
    2913         int iRow = _cmbTable->rowCount();
    2914         if (iRow > 0) {
    2915             enableWidget(true, _cmbMethodComboBox);
    2916             enableWidget(true, _cmbMaxresLineEdit);
    2917             enableWidget(true, _cmbMaxdisplacementLineEdit);
    2918             enableWidget(true, _cmbSamplComboBox);
    2919             enableWidget(true, _cmbLogPath);
    2920             enableWidget(true, _cmbGpsCheckBox);
    2921             enableWidget(true, _cmbGloCheckBox);
    2922             enableWidget(true, _cmbGalCheckBox);
    2923             enableWidget(true, _cmbBdsCheckBox);
    2924             enableWidget(true, _cmbQzssCheckBox);
    2925             enableWidget(true, _cmbSbasCheckBox);
    2926             enableWidget(true, _cmbNavicCheckBox);
    2927             enableWidget(true, _cmbBsxFile);
    2928         }
    2929         else {
    2930             enableWidget(false, _cmbMethodComboBox);
    2931             enableWidget(false, _cmbMaxresLineEdit);
    2932             enableWidget(false, _cmbMaxdisplacementLineEdit);
    2933             enableWidget(false, _cmbSamplComboBox);
    2934             enableWidget(false, _cmbLogPath);
    2935             enableWidget(false, _cmbGpsCheckBox);
    2936             enableWidget(false, _cmbGloCheckBox);
    2937             enableWidget(false, _cmbGalCheckBox);
    2938             enableWidget(false, _cmbBdsCheckBox);
    2939             enableWidget(false, _cmbQzssCheckBox);
    2940             enableWidget(false, _cmbSbasCheckBox);
    2941             enableWidget(false, _cmbNavicCheckBox);
    2942             enableWidget(false, _cmbBsxFile);
    2943         }
    2944     }
    2945 
    2946     // Upload(clk)
    2947     // -----------
    2948     int iRow = _uploadTable->rowCount();
    2949     if (iRow > 0) {
    2950         enableWidget(true, _uploadIntrComboBox);
    2951         enableWidget(true, _uploadSamplRtcmEphCorrComboBox);
    2952         enableWidget(true, _uploadSamplClkRnxSpinBox);
    2953         enableWidget(true, _uploadSamplBiaSnxSpinBox);
    2954         enableWidget(true, _uploadSamplSp3ComboBox);
    2955         enableWidget(true, _uploadAntexFile);
     3242        _uploadTable->setCellWidget(iRow, iCol, com);
     3243      }
     3244      else if (iCol == 15) {
     3245        bncTableItem* bncIt = new bncTableItem();
     3246        bncIt->setFlags(bncIt->flags() & ~Qt::ItemIsEditable);
     3247        _uploadTable->setItem(iRow, iCol, bncIt);
     3248        BNC_CORE->_uploadTableItems[iRow] = bncIt;
     3249      }
     3250      else {
     3251        _uploadTable->setItem(iRow, iCol, new QTableWidgetItem(hlp[iCol]));
     3252      }
     3253    }
     3254  }
     3255}
     3256
     3257//
     3258////////////////////////////////////////////////////////////////////////////
     3259void bncWindow::slotSetUploadTrafo() {
     3260  bncCustomTrafo* dlg = new bncCustomTrafo(this);
     3261  dlg->exec();
     3262  delete dlg;
     3263}
     3264
     3265//
     3266////////////////////////////////////////////////////////////////////////////
     3267void bncWindow::slotAddUploadEphRow() {
     3268  int iRow = _uploadEphTable->rowCount();
     3269  _uploadEphTable->insertRow(iRow);
     3270  for (int iCol = 0; iCol < _uploadEphTable->columnCount(); iCol++) {
     3271    if (iCol == 3) {
     3272      QComboBox* ntripversion = new QComboBox();
     3273      ntripversion->setEditable(false);
     3274      ntripversion->addItems(QString("2s,2,1").split(","));
     3275      ntripversion->setFrame(false);
     3276      _uploadEphTable->setCellWidget(iRow, iCol, ntripversion);
     3277
     3278    }
     3279    else if (iCol == 4) {
     3280      QLineEdit* user = new QLineEdit();
     3281      user->setFrame(false);
     3282      _uploadEphTable->setCellWidget(iRow, iCol, user);
     3283    }
     3284    else if (iCol == 5) {
     3285      QLineEdit* passwd = new QLineEdit();
     3286      passwd->setFrame(false);
     3287      passwd->setEchoMode(QLineEdit::PasswordEchoOnEdit);
     3288      _uploadEphTable->setCellWidget(iRow, iCol, passwd);
     3289    }
     3290    else if (iCol == 6) {
     3291      QLineEdit* system = new QLineEdit("GREC");
     3292      system->setFrame(false);
     3293      _uploadEphTable->setCellWidget(iRow, iCol, system);
     3294    }
     3295    else if (iCol == 7) {
     3296      bncTableItem* bncIt = new bncTableItem();
     3297      bncIt->setFlags(bncIt->flags() & ~Qt::ItemIsEditable);
     3298      _uploadEphTable->setItem(iRow, iCol, bncIt);
     3299      BNC_CORE->_uploadEphTableItems[iRow] = bncIt;
    29563300    }
    29573301    else {
    2958         enableWidget(false, _uploadIntrComboBox);
    2959         enableWidget(false, _uploadSamplRtcmEphCorrComboBox);
    2960         enableWidget(false, _uploadSamplClkRnxSpinBox);
    2961         enableWidget(false, _uploadSamplBiaSnxSpinBox);
    2962         enableWidget(false, _uploadSamplSp3ComboBox);
    2963         enableWidget(false, _uploadAntexFile);
    2964     }
    2965 
    2966     // Upload(eph)
    2967     // -----------
    2968     iRow = _uploadEphTable->rowCount();
    2969     if (iRow > 0) {
    2970         enableWidget(true, _uploadSamplRtcmEphSpinBox);
     3302      _uploadEphTable->setItem(iRow, iCol, new QTableWidgetItem(""));
     3303    }
     3304  }
     3305}
     3306
     3307//
     3308////////////////////////////////////////////////////////////////////////////
     3309void bncWindow::slotDelUploadEphRow() {
     3310  BNC_CORE->_uploadEphTableItems.clear();
     3311  int nRows = _uploadEphTable->rowCount();
     3312  std::vector <bool> flg(nRows);
     3313  for (int iRow = 0; iRow < nRows; iRow++) {
     3314    if (_uploadEphTable->item(iRow, 1)->isSelected()) {
     3315      flg[iRow] = true;
    29713316    }
    29723317    else {
    2973         enableWidget(false, _uploadSamplRtcmEphSpinBox);
    2974     }
    2975 
    2976     // QC
    2977     // --
    2978     if (sender() == 0 || sender() == _reqcActionComboBox || sender() == _reqcSkyPlotSignals) {
    2979         enable = !_reqcActionComboBox->currentText().isEmpty();
    2980         bool enable10 = _reqcActionComboBox->currentText() == "Edit/Concatenate";
    2981         //  bool enablePlot = !_reqcSkyPlotSignals->text().isEmpty();
    2982         enableWidget(enable, _reqcObsFileChooser);
    2983         enableWidget(enable, _reqcNavFileChooser);
    2984         enableWidget(enable, _reqcOutLogLineEdit);
    2985         enableWidget(enable && enable10, _reqcEditOptionButton);
    2986         enableWidget(enable && enable10, _reqcOutObsLineEdit);
    2987         enableWidget(enable && enable10, _reqcOutNavLineEdit);
    2988         enableWidget(enable && !enable10, _reqcLogSummaryOnly);
    2989         enableWidget(enable && !enable10, _reqcSkyPlotSignals);
    2990         //  enableWidget(enable && !enable10 && enablePlot, _reqcPlotDirLineEdit);
    2991         enableWidget(enable && !enable10, _reqcPlotDirLineEdit);
    2992     }
    2993 
    2994     // SP3 File Comparison
    2995     // -------------------
    2996     if (sender() == 0 || sender() == _sp3CompFileChooser) {
    2997         enable = !_sp3CompFileChooser->fileName().isEmpty();
    2998         enableWidget(enable, _sp3CompLogLineEdit);
    2999         enableWidget(enable, _sp3CompExclude);
    3000         enableWidget(enable, _sp3CompSummaryOnly);
    3001     }
    3002 
    3003     enableStartStop();
     3318      flg[iRow] = false;
     3319    }
     3320  }
     3321  for (int iRow = nRows - 1; iRow >= 0; iRow--) {
     3322    if (flg[iRow]) {
     3323      _uploadEphTable->removeRow(iRow);
     3324    }
     3325  }
     3326  for (int iRow = 0; iRow < _uploadTable->rowCount(); iRow++) {
     3327    BNC_CORE->_uploadEphTableItems[iRow] =
     3328      (bncTableItem*)_uploadEphTable->item(iRow, 7);
     3329  }
     3330  nRows = _uploadEphTable->rowCount();
     3331  if (nRows < 1) {
     3332    enableWidget(false, _uploadSamplRtcmEphSpinBox);
     3333  }
    30043334}
    30053335
    30063336//
    30073337////////////////////////////////////////////////////////////////////////////
    3008 void bncWindow::slotAddCmbRow() {
    3009     int iRow = _cmbTable->rowCount();
    3010     _cmbTable->insertRow(iRow);
    3011     for (int iCol = 0; iCol < _cmbTable->columnCount(); iCol++) {
    3012         _cmbTable->setItem(iRow, iCol, new QTableWidgetItem(""));
    3013     }
     3338void bncWindow::populateUploadEphTable() {
     3339  for (int iRow = _uploadEphTable->rowCount() - 1; iRow >= 0; iRow--) {
     3340    _uploadEphTable->removeRow(iRow);
     3341  }
     3342
     3343  bncSettings settings;
     3344
     3345  int iRow = -1;
     3346  QListIterator<QString> it(settings.value("uploadEphMountpointsOut").toStringList());
     3347  while (it.hasNext()) {
     3348    QStringList hlp = it.next().split(",");
     3349    if (hlp.size() > 6) {
     3350      ++iRow;
     3351      _uploadEphTable->insertRow(iRow);
     3352    }
     3353    for (int iCol = 0; iCol < hlp.size(); iCol++) {
     3354      if (iCol == 3) {
     3355        QComboBox* ntripversion = new QComboBox();
     3356        ntripversion->setEditable(false);
     3357        ntripversion->addItems(QString("1,2,2s").split(","));
     3358        ntripversion->setFrame(false);
     3359        ntripversion->setCurrentIndex(ntripversion->findText(hlp[iCol]));
     3360        _uploadEphTable->setCellWidget(iRow, iCol, ntripversion);
     3361      }
     3362      else if (iCol == 4) {
     3363        QLineEdit* user = new QLineEdit();
     3364        user->setFrame(false);
     3365        user->setText(hlp[iCol]);
     3366        _uploadEphTable->setCellWidget(iRow, iCol, user);
     3367      }
     3368      else if (iCol == 5) {
     3369        QLineEdit* passwd = new QLineEdit();
     3370        passwd->setFrame(false);
     3371        passwd->setEchoMode(QLineEdit::PasswordEchoOnEdit);
     3372        passwd->setText(hlp[iCol]);
     3373        _uploadEphTable->setCellWidget(iRow, iCol, passwd);
     3374      }
     3375      else if (iCol == 6) {
     3376        QLineEdit* system = new QLineEdit();
     3377        system->setFrame(false);
     3378        system->setText(hlp[iCol]);
     3379        _uploadEphTable->setCellWidget(iRow, iCol, system);
     3380      }
     3381      else if (iCol == 7) {
     3382        bncTableItem* bncIt = new bncTableItem();
     3383        bncIt->setFlags(bncIt->flags() & ~Qt::ItemIsEditable);
     3384        _uploadEphTable->setItem(iRow, iCol, bncIt);
     3385        BNC_CORE->_uploadEphTableItems[iRow] = bncIt;
     3386      }
     3387      else {
     3388        _uploadEphTable->setItem(iRow, iCol, new QTableWidgetItem(hlp[iCol]));
     3389      }
     3390    }
     3391  }
    30143392}
    30153393
    30163394//
    30173395////////////////////////////////////////////////////////////////////////////
    3018 void bncWindow::slotDelCmbRow() {
    3019 
    3020     const static QPalette paletteWhite(QColor(255, 255, 255));
    3021     const static QPalette paletteGray(QColor(230, 230, 230));
    3022 
    3023     int nRows = _cmbTable->rowCount();
    3024     std::vector <bool> flg(nRows);
    3025     for (int iRow = 0; iRow < nRows; iRow++) {
    3026         if (_cmbTable->item(iRow, 1)->isSelected()) {
    3027             flg[iRow] = true;
    3028         }
    3029         else {
    3030             flg[iRow] = false;
    3031         }
    3032     }
    3033     for (int iRow = nRows - 1; iRow >= 0; iRow--) {
    3034         if (flg[iRow]) {
    3035             _cmbTable->removeRow(iRow);
    3036         }
    3037     }
    3038     nRows = _cmbTable->rowCount();
    3039     if (nRows < 1) {
    3040         enableWidget(false, _cmbMethodComboBox);
    3041         enableWidget(false, _cmbMaxresLineEdit);
    3042         enableWidget(false, _cmbMaxdisplacementLineEdit);
    3043         enableWidget(false, _cmbSamplComboBox);
    3044         enableWidget(false, _cmbLogPath);
    3045     }
     3396void bncWindow::slotAddUploadRawRow() {
     3397  int iRow = _uploadRawTable->rowCount();
     3398  _uploadRawTable->insertRow(iRow);
     3399  for (int iCol = 0; iCol < _uploadRawTable->columnCount(); iCol++) {
     3400    if (iCol == 4) {
     3401      QComboBox* ntripversion = new QComboBox();
     3402      ntripversion->setEditable(false);
     3403      ntripversion->addItems(QString("2s,2,1").split(","));
     3404      ntripversion->setFrame(false);
     3405      _uploadRawTable->setCellWidget(iRow, iCol, ntripversion);
     3406
     3407    }
     3408    else if (iCol == 5) {
     3409      QLineEdit* user = new QLineEdit();
     3410      user->setFrame(false);
     3411      _uploadRawTable->setCellWidget(iRow, iCol, user);
     3412    }
     3413    else if (iCol == 6) {
     3414      QLineEdit* passwd = new QLineEdit();
     3415      passwd->setFrame(false);
     3416      passwd->setEchoMode(QLineEdit::PasswordEchoOnEdit);
     3417      _uploadRawTable->setCellWidget(iRow, iCol, passwd);
     3418    }
     3419    else if (iCol == 7) {
     3420      bncTableItem* bncIt = new bncTableItem();
     3421      bncIt->setFlags(bncIt->flags() & ~Qt::ItemIsEditable);
     3422      _uploadRawTable->setItem(iRow, iCol, bncIt);
     3423      BNC_CORE->_uploadRawTableItems[iRow] = bncIt;
     3424    }
     3425    else {
     3426      _uploadRawTable->setItem(iRow, iCol, new QTableWidgetItem(""));
     3427    }
     3428  }
    30463429}
    30473430
    30483431//
    30493432////////////////////////////////////////////////////////////////////////////
    3050 void bncWindow::populateCmbTable() {
    3051 
    3052     for (int iRow = _cmbTable->rowCount() - 1; iRow >= 0; iRow--) {
    3053         _cmbTable->removeRow(iRow);
    3054     }
    3055 
    3056     bncSettings settings;
    3057 
    3058     int iRow = -1;
    3059     QListIterator<QString> it(settings.value("cmbStreams").toStringList());
    3060     while (it.hasNext()) {
    3061         QStringList hlp = it.next().split(" ");
    3062         if (hlp.size() > 2) {
    3063             ++iRow;
    3064             _cmbTable->insertRow(iRow);
    3065         }
    3066         for (int iCol = 0; iCol < hlp.size(); iCol++) {
    3067             _cmbTable->setItem(iRow, iCol, new QTableWidgetItem(hlp[iCol]));
    3068         }
    3069     }
     3433void bncWindow::slotDelUploadRawRow() {
     3434  BNC_CORE->_uploadRawTableItems.clear();
     3435  int nRows = _uploadRawTable->rowCount();
     3436  std::vector <bool> flg(nRows);
     3437  for (int iRow = 0; iRow < nRows; iRow++) {
     3438    if (_uploadRawTable->item(iRow, 1)->isSelected()) {
     3439      flg[iRow] = true;
     3440    }
     3441    else {
     3442      flg[iRow] = false;
     3443    }
     3444  }
     3445  for (int iRow = nRows - 1; iRow >= 0; iRow--) {
     3446    if (flg[iRow]) {
     3447      _uploadRawTable->removeRow(iRow);
     3448    }
     3449  }
     3450  for (int iRow = 0; iRow < _uploadRawTable->rowCount(); iRow++) {
     3451    BNC_CORE->_uploadRawTableItems[iRow] =
     3452      (bncTableItem*)_uploadRawTable->item(iRow, 7);
     3453  }
    30703454}
    30713455
    30723456//
    30733457////////////////////////////////////////////////////////////////////////////
    3074 void bncWindow::slotAddUploadRow() {
    3075     int iRow = _uploadTable->rowCount();
    3076     _uploadTable->insertRow(iRow);
    3077     for (int iCol = 0; iCol < _uploadTable->columnCount(); iCol++) {
    3078         if (iCol == 3) {
    3079             QComboBox* ntripversion = new QComboBox();
    3080             ntripversion->setEditable(false);
    3081             ntripversion->addItems(QString("2s,2,1").split(","));
    3082             ntripversion->setFrame(false);
    3083             _uploadTable->setCellWidget(iRow, iCol, ntripversion);
    3084 
    3085         }
    3086         else if (iCol == 4) {
    3087             QLineEdit* user = new QLineEdit();
    3088             user->setFrame(false);
    3089             _uploadTable->setCellWidget(iRow, iCol, user);
    3090         }
    3091         else if (iCol == 5) {
    3092             QLineEdit* passwd = new QLineEdit();
    3093             passwd->setFrame(false);
    3094             passwd->setEchoMode(QLineEdit::PasswordEchoOnEdit);
    3095             _uploadTable->setCellWidget(iRow, iCol, passwd);
    3096         }
    3097         else if (iCol == 6) {
    3098             QComboBox* system = new QComboBox();
    3099             system->setEditable(false);
    3100             system->addItems(QString("IGS20,ETRF2000,GDA2020,SIRGAS2000,DREF91,Custom").split(","));
    3101             system->setFrame(false);
    3102             _uploadTable->setCellWidget(iRow, iCol, system);
    3103         }
    3104         else if (iCol == 7) {
    3105             QComboBox* format = new QComboBox();
    3106             format->setEditable(false);
    3107             //format->addItems(QString("IGS-SSR,RTCM-SSR,RTCM-NEW-SSR").split(","));
    3108             format->addItems(QString("IGS-SSR,RTCM-SSR").split(","));
    3109             format->setFrame(false);
    3110             _uploadTable->setCellWidget(iRow, iCol, format);
    3111         }
    3112         else if (iCol == 8) {
    3113             QCheckBox* com = new QCheckBox();
    3114             _uploadTable->setCellWidget(iRow, iCol, com);
    3115         }
    3116         else if (iCol == 15) {
    3117             bncTableItem* bncIt = new bncTableItem();
    3118             bncIt->setFlags(bncIt->flags() & ~Qt::ItemIsEditable);
    3119             _uploadTable->setItem(iRow, iCol, bncIt);
    3120             BNC_CORE->_uploadTableItems[iRow] = bncIt;
    3121         }
    3122         else {
    3123             _uploadTable->setItem(iRow, iCol, new QTableWidgetItem(""));
    3124         }
    3125     }
    3126 }
    3127 
    3128 //
    3129 ////////////////////////////////////////////////////////////////////////////
    3130 void bncWindow::slotDelUploadRow() {
    3131     BNC_CORE->_uploadTableItems.clear();
    3132     int nRows = _uploadTable->rowCount();
    3133     std::vector <bool> flg(nRows);
    3134     for (int iRow = 0; iRow < nRows; iRow++) {
    3135         if (_uploadTable->item(iRow, 1)->isSelected()) {
    3136             flg[iRow] = true;
    3137         }
    3138         else {
    3139             flg[iRow] = false;
    3140         }
    3141     }
    3142     for (int iRow = nRows - 1; iRow >= 0; iRow--) {
    3143         if (flg[iRow]) {
    3144             _uploadTable->removeRow(iRow);
    3145         }
    3146     }
    3147     for (int iRow = 0; iRow < _uploadTable->rowCount(); iRow++) {
    3148         BNC_CORE->_uploadTableItems[iRow] =
    3149             (bncTableItem*)_uploadTable->item(iRow, 14);
    3150     }
    3151     nRows = _uploadTable->rowCount();
    3152     if (nRows < 1) {
    3153         enableWidget(false, _uploadIntrComboBox);
    3154         enableWidget(false, _uploadSamplRtcmEphCorrComboBox);
    3155         enableWidget(false, _uploadSamplSp3ComboBox);
    3156         enableWidget(false, _uploadSamplClkRnxSpinBox);
    3157         enableWidget(false, _uploadAntexFile);
    3158     }
    3159 }
    3160 
    3161 //
    3162 ////////////////////////////////////////////////////////////////////////////
    3163 void bncWindow::populateUploadTable() {
    3164     for (int iRow = _uploadTable->rowCount() - 1; iRow >= 0; iRow--) {
    3165         _uploadTable->removeRow(iRow);
    3166     }
    3167 
    3168     bncSettings settings;
    3169 
    3170     int iRow = -1;
    3171     QListIterator<QString> it(settings.value("uploadMountpointsOut").toStringList());
    3172 
    3173     while (it.hasNext()) {
    3174         QStringList hlp = it.next().split(",");
    3175         if (hlp.size() > 6) {
    3176             ++iRow;
    3177             _uploadTable->insertRow(iRow);
    3178         }
    3179         for (int iCol = 0; iCol < hlp.size(); iCol++) {
    3180             if (iCol == 3) {
    3181                 QComboBox* ntripversion = new QComboBox();
    3182                 ntripversion->setEditable(false);
    3183                 ntripversion->addItems(QString("1,2,2s").split(","));
    3184                 ntripversion->setFrame(false);
    3185                 ntripversion->setCurrentIndex(ntripversion->findText(hlp[iCol]));
    3186                 _uploadTable->setCellWidget(iRow, iCol, ntripversion);
    3187             }
    3188             else if (iCol == 4) {
    3189                 QLineEdit* user = new QLineEdit();
    3190                 user->setFrame(false);
    3191                 user->setText(hlp[iCol]);
    3192                 _uploadTable->setCellWidget(iRow, iCol, user);
    3193             }
    3194             else if (iCol == 5) {
    3195                 QLineEdit* passwd = new QLineEdit();
    3196                 passwd->setFrame(false);
    3197                 passwd->setEchoMode(QLineEdit::PasswordEchoOnEdit);
    3198                 passwd->setText(hlp[iCol]);
    3199                 _uploadTable->setCellWidget(iRow, iCol, passwd);
    3200             }
    3201             else if (iCol == 6) {
    3202                 QComboBox* system = new QComboBox();
    3203                 system->setEditable(false);
    3204                 system->addItems(QString("IGS20,ETRF2000,GDA2020,SIRGAS2000,DREF91,Custom").split(","));
    3205                 system->setFrame(false);
    3206                 system->setCurrentIndex(system->findText(hlp[iCol]));
    3207                 _uploadTable->setCellWidget(iRow, iCol, system);
    3208             }
    3209             else if (iCol == 7) {
    3210                 QComboBox* format = new QComboBox();
    3211                 format->setEditable(false);
    3212                 //format->addItems(QString("IGS-SSR,RTCM-SSR,RTCM-NEW-SSR").split(","));
    3213                 format->addItems(QString("IGS-SSR,RTCM-SSR").split(","));
    3214                 format->setFrame(false);
    3215                 format->setCurrentIndex(format->findText(hlp[iCol]));
    3216                 _uploadTable->setCellWidget(iRow, iCol, format);
    3217             }
    3218             else if (iCol == 8) {
    3219                 QCheckBox* com = new QCheckBox();
    3220                 if (hlp[iCol].toInt() == Qt::Checked) {
    3221                     com->setCheckState(Qt::Checked);
    3222                 }
    3223                 _uploadTable->setCellWidget(iRow, iCol, com);
    3224             }
    3225             else if (iCol == 15) {
    3226                 bncTableItem* bncIt = new bncTableItem();
    3227                 bncIt->setFlags(bncIt->flags() & ~Qt::ItemIsEditable);
    3228                 _uploadTable->setItem(iRow, iCol, bncIt);
    3229                 BNC_CORE->_uploadTableItems[iRow] = bncIt;
    3230             }
    3231             else {
    3232                 _uploadTable->setItem(iRow, iCol, new QTableWidgetItem(hlp[iCol]));
    3233             }
    3234         }
    3235     }
    3236 }
    3237 
    3238 //
    3239 ////////////////////////////////////////////////////////////////////////////
    3240 void bncWindow::slotSetUploadTrafo() {
    3241     bncCustomTrafo* dlg = new bncCustomTrafo(this);
    3242     dlg->exec();
    3243     delete dlg;
    3244 }
    3245 
    3246 //
    3247 ////////////////////////////////////////////////////////////////////////////
    3248 void bncWindow::slotAddUploadEphRow() {
    3249     int iRow = _uploadEphTable->rowCount();
    3250     _uploadEphTable->insertRow(iRow);
    3251     for (int iCol = 0; iCol < _uploadEphTable->columnCount(); iCol++) {
    3252         if (iCol == 3) {
    3253             QComboBox* ntripversion = new QComboBox();
    3254             ntripversion->setEditable(false);
    3255             ntripversion->addItems(QString("2s,2,1").split(","));
    3256             ntripversion->setFrame(false);
    3257             _uploadEphTable->setCellWidget(iRow, iCol, ntripversion);
    3258 
    3259         }
    3260         else if (iCol == 4) {
    3261             QLineEdit* user = new QLineEdit();
    3262             user->setFrame(false);
    3263             _uploadEphTable->setCellWidget(iRow, iCol, user);
    3264         }
    3265         else if (iCol == 5) {
    3266             QLineEdit* passwd = new QLineEdit();
    3267             passwd->setFrame(false);
    3268             passwd->setEchoMode(QLineEdit::PasswordEchoOnEdit);
    3269             _uploadEphTable->setCellWidget(iRow, iCol, passwd);
    3270         }
    3271         else if (iCol == 6) {
    3272             QLineEdit* system = new QLineEdit("GREC");
    3273             system->setFrame(false);
    3274             _uploadEphTable->setCellWidget(iRow, iCol, system);
    3275         }
    3276         else if (iCol == 7) {
    3277             bncTableItem* bncIt = new bncTableItem();
    3278             bncIt->setFlags(bncIt->flags() & ~Qt::ItemIsEditable);
    3279             _uploadEphTable->setItem(iRow, iCol, bncIt);
    3280             BNC_CORE->_uploadEphTableItems[iRow] = bncIt;
    3281         }
    3282         else {
    3283             _uploadEphTable->setItem(iRow, iCol, new QTableWidgetItem(""));
    3284         }
    3285     }
    3286 }
    3287 
    3288 //
    3289 ////////////////////////////////////////////////////////////////////////////
    3290 void bncWindow::slotDelUploadEphRow() {
    3291     BNC_CORE->_uploadEphTableItems.clear();
    3292     int nRows = _uploadEphTable->rowCount();
    3293     std::vector <bool> flg(nRows);
    3294     for (int iRow = 0; iRow < nRows; iRow++) {
    3295         if (_uploadEphTable->item(iRow, 1)->isSelected()) {
    3296             flg[iRow] = true;
    3297         }
    3298         else {
    3299             flg[iRow] = false;
    3300         }
    3301     }
    3302     for (int iRow = nRows - 1; iRow >= 0; iRow--) {
    3303         if (flg[iRow]) {
    3304             _uploadEphTable->removeRow(iRow);
    3305         }
    3306     }
    3307     for (int iRow = 0; iRow < _uploadTable->rowCount(); iRow++) {
    3308         BNC_CORE->_uploadEphTableItems[iRow] =
    3309             (bncTableItem*)_uploadEphTable->item(iRow, 7);
    3310     }
    3311     nRows = _uploadEphTable->rowCount();
    3312     if (nRows < 1) {
    3313         enableWidget(false, _uploadSamplRtcmEphSpinBox);
    3314     }
    3315 }
    3316 
    3317 //
    3318 ////////////////////////////////////////////////////////////////////////////
    3319 void bncWindow::populateUploadEphTable() {
    3320     for (int iRow = _uploadEphTable->rowCount() - 1; iRow >= 0; iRow--) {
    3321         _uploadEphTable->removeRow(iRow);
    3322     }
    3323 
    3324     bncSettings settings;
    3325 
    3326     int iRow = -1;
    3327     QListIterator<QString> it(settings.value("uploadEphMountpointsOut").toStringList());
    3328     while (it.hasNext()) {
    3329         QStringList hlp = it.next().split(",");
    3330         if (hlp.size() > 6) {
    3331             ++iRow;
    3332             _uploadEphTable->insertRow(iRow);
    3333         }
    3334         for (int iCol = 0; iCol < hlp.size(); iCol++) {
    3335             if (iCol == 3) {
    3336                 QComboBox* ntripversion = new QComboBox();
    3337                 ntripversion->setEditable(false);
    3338                 ntripversion->addItems(QString("1,2,2s").split(","));
    3339                 ntripversion->setFrame(false);
    3340                 ntripversion->setCurrentIndex(ntripversion->findText(hlp[iCol]));
    3341                 _uploadEphTable->setCellWidget(iRow, iCol, ntripversion);
    3342             }
    3343             else if (iCol == 4) {
    3344                 QLineEdit* user = new QLineEdit();
    3345                 user->setFrame(false);
    3346                 user->setText(hlp[iCol]);
    3347                 _uploadEphTable->setCellWidget(iRow, iCol, user);
    3348             }
    3349             else if (iCol == 5) {
    3350                 QLineEdit* passwd = new QLineEdit();
    3351                 passwd->setFrame(false);
    3352                 passwd->setEchoMode(QLineEdit::PasswordEchoOnEdit);
    3353                 passwd->setText(hlp[iCol]);
    3354                 _uploadEphTable->setCellWidget(iRow, iCol, passwd);
    3355             }
    3356             else if (iCol == 6) {
    3357                 QLineEdit* system = new QLineEdit();
    3358                 system->setFrame(false);
    3359                 system->setText(hlp[iCol]);
    3360                 _uploadEphTable->setCellWidget(iRow, iCol, system);
    3361             }
    3362             else if (iCol == 7) {
    3363                 bncTableItem* bncIt = new bncTableItem();
    3364                 bncIt->setFlags(bncIt->flags() & ~Qt::ItemIsEditable);
    3365                 _uploadEphTable->setItem(iRow, iCol, bncIt);
    3366                 BNC_CORE->_uploadEphTableItems[iRow] = bncIt;
    3367             }
    3368             else {
    3369                 _uploadEphTable->setItem(iRow, iCol, new QTableWidgetItem(hlp[iCol]));
    3370             }
    3371         }
    3372     }
    3373 }
    3374 
    3375 //
    3376 ////////////////////////////////////////////////////////////////////////////
    3377 void bncWindow::slotAddUploadRawRow() {
    3378     int iRow = _uploadRawTable->rowCount();
    3379     _uploadRawTable->insertRow(iRow);
    3380     for (int iCol = 0; iCol < _uploadRawTable->columnCount(); iCol++) {
    3381         if (iCol == 4) {
    3382             QComboBox* ntripversion = new QComboBox();
    3383             ntripversion->setEditable(false);
    3384             ntripversion->addItems(QString("2s,2,1").split(","));
    3385             ntripversion->setFrame(false);
    3386             _uploadRawTable->setCellWidget(iRow, iCol, ntripversion);
    3387 
    3388         }
    3389         else if (iCol == 5) {
    3390             QLineEdit* user = new QLineEdit();
    3391             user->setFrame(false);
    3392             _uploadRawTable->setCellWidget(iRow, iCol, user);
    3393         }
    3394         else if (iCol == 6) {
    3395             QLineEdit* passwd = new QLineEdit();
    3396             passwd->setFrame(false);
    3397             passwd->setEchoMode(QLineEdit::PasswordEchoOnEdit);
    3398             _uploadRawTable->setCellWidget(iRow, iCol, passwd);
    3399         }
    3400         else if (iCol == 7) {
    3401             bncTableItem* bncIt = new bncTableItem();
    3402             bncIt->setFlags(bncIt->flags() & ~Qt::ItemIsEditable);
    3403             _uploadRawTable->setItem(iRow, iCol, bncIt);
    3404             BNC_CORE->_uploadRawTableItems[iRow] = bncIt;
    3405         }
    3406         else {
    3407           _uploadRawTable->setItem(iRow, iCol, new QTableWidgetItem(""));
    3408         }
    3409     }
    3410 }
    3411 
    3412 //
    3413 ////////////////////////////////////////////////////////////////////////////
    3414 void bncWindow::slotDelUploadRawRow() {
    3415     BNC_CORE->_uploadRawTableItems.clear();
    3416     int nRows = _uploadRawTable->rowCount();
    3417     std::vector <bool> flg(nRows);
    3418     for (int iRow = 0; iRow < nRows; iRow++) {
    3419         if (_uploadRawTable->item(iRow, 1)->isSelected()) {
    3420             flg[iRow] = true;
    3421         }
    3422         else {
    3423             flg[iRow] = false;
    3424         }
    3425     }
    3426     for (int iRow = nRows - 1; iRow >= 0; iRow--) {
    3427         if (flg[iRow]) {
    3428             _uploadRawTable->removeRow(iRow);
    3429         }
    3430     }
    3431     for (int iRow = 0; iRow < _uploadRawTable->rowCount(); iRow++) {
    3432         BNC_CORE->_uploadRawTableItems[iRow] =
    3433             (bncTableItem*)_uploadRawTable->item(iRow, 7);
    3434     }
    3435 }
    3436 
    3437 //
    3438 ////////////////////////////////////////////////////////////////////////////
    34393458void bncWindow::populateUploadRawTable() {
    3440     for (int iRow = _uploadRawTable->rowCount() - 1; iRow >= 0; iRow--) {
    3441       _uploadRawTable->removeRow(iRow);
    3442     }
    3443 
    3444     bncSettings settings;
    3445 
    3446     int iRow = -1;
    3447     QListIterator<QString> it(settings.value("uploadRawMountpointsOut").toStringList());
    3448     while (it.hasNext()) {
    3449         QStringList hlp = it.next().split(",");
    3450         if (hlp.size() > 6) {
    3451             ++iRow;
    3452             _uploadRawTable->insertRow(iRow);
    3453         }
    3454         for (int iCol = 0; iCol < hlp.size(); iCol++) {
    3455             if (iCol == 4) {
    3456                 QComboBox* ntripversion = new QComboBox();
    3457                 ntripversion->setEditable(false);
    3458                 ntripversion->addItems(QString("1,2,2s").split(","));
    3459                 ntripversion->setFrame(false);
    3460                 ntripversion->setCurrentIndex(ntripversion->findText(hlp[iCol]));
    3461                 _uploadRawTable->setCellWidget(iRow, iCol, ntripversion);
    3462             }
    3463             else if (iCol == 5) {
    3464                 QLineEdit* user = new QLineEdit();
    3465                 user->setFrame(false);
    3466                 user->setText(hlp[iCol]);
    3467                 _uploadRawTable->setCellWidget(iRow, iCol, user);
    3468             }
    3469             else if (iCol == 6) {
    3470                 QLineEdit* passwd = new QLineEdit();
    3471                 passwd->setFrame(false);
    3472                 passwd->setEchoMode(QLineEdit::PasswordEchoOnEdit);
    3473                 passwd->setText(hlp[iCol]);
    3474                 _uploadRawTable->setCellWidget(iRow, iCol, passwd);
    3475             }
    3476             else if (iCol == 7) {
    3477                 bncTableItem* bncIt = new bncTableItem();
    3478                 bncIt->setFlags(bncIt->flags() & ~Qt::ItemIsEditable);
    3479                 _uploadRawTable->setItem(iRow, iCol, bncIt);
    3480                 BNC_CORE->_uploadRawTableItems[iRow] = bncIt;
    3481             }
    3482             else {
    3483               _uploadRawTable->setItem(iRow, iCol, new QTableWidgetItem(hlp[iCol]));
    3484             }
    3485         }
    3486     }
     3459  for (int iRow = _uploadRawTable->rowCount() - 1; iRow >= 0; iRow--) {
     3460    _uploadRawTable->removeRow(iRow);
     3461  }
     3462
     3463  bncSettings settings;
     3464
     3465  int iRow = -1;
     3466  QListIterator<QString> it(settings.value("uploadRawMountpointsOut").toStringList());
     3467  while (it.hasNext()) {
     3468    QStringList hlp = it.next().split(",");
     3469    if (hlp.size() > 6) {
     3470      ++iRow;
     3471      _uploadRawTable->insertRow(iRow);
     3472    }
     3473    for (int iCol = 0; iCol < hlp.size(); iCol++) {
     3474      if (iCol == 4) {
     3475        QComboBox* ntripversion = new QComboBox();
     3476        ntripversion->setEditable(false);
     3477        ntripversion->addItems(QString("1,2,2s").split(","));
     3478        ntripversion->setFrame(false);
     3479        ntripversion->setCurrentIndex(ntripversion->findText(hlp[iCol]));
     3480        _uploadRawTable->setCellWidget(iRow, iCol, ntripversion);
     3481      }
     3482      else if (iCol == 5) {
     3483        QLineEdit* user = new QLineEdit();
     3484        user->setFrame(false);
     3485        user->setText(hlp[iCol]);
     3486        _uploadRawTable->setCellWidget(iRow, iCol, user);
     3487      }
     3488      else if (iCol == 6) {
     3489        QLineEdit* passwd = new QLineEdit();
     3490        passwd->setFrame(false);
     3491        passwd->setEchoMode(QLineEdit::PasswordEchoOnEdit);
     3492        passwd->setText(hlp[iCol]);
     3493        _uploadRawTable->setCellWidget(iRow, iCol, passwd);
     3494      }
     3495      else if (iCol == 7) {
     3496        bncTableItem* bncIt = new bncTableItem();
     3497        bncIt->setFlags(bncIt->flags() & ~Qt::ItemIsEditable);
     3498        _uploadRawTable->setItem(iRow, iCol, bncIt);
     3499        BNC_CORE->_uploadRawTableItems[iRow] = bncIt;
     3500      }
     3501      else {
     3502        _uploadRawTable->setItem(iRow, iCol, new QTableWidgetItem(hlp[iCol]));
     3503      }
     3504    }
     3505  }
    34873506}
    34883507
     
    34903509////////////////////////////////////////////////////////////////////////////
    34913510void bncWindow::slotPostProcessingProgress(int nEpo) {
    3492     _actStart->setText(QString("%1 Epochs").arg(nEpo));
     3511  _actStart->setText(QString("%1 Epochs").arg(nEpo));
    34933512}
    34943513
     
    34963515////////////////////////////////////////////////////////////////////////////
    34973516void bncWindow::slotPostProcessingFinished() {
    3498     delete _caster; _caster = 0; BNC_CORE->setCaster(0);
    3499     _runningPPP = false;
    3500     _runningEdit = false;
    3501     _runningQC = false;
    3502     _runningSp3Comp = false;
    3503     _actStart->setText(tr("Sta&rt"));
    3504     enableStartStop();
     3517  delete _caster; _caster = 0; BNC_CORE->setCaster(0);
     3518  _runningPPP = false;
     3519  _runningEdit = false;
     3520  _runningQC = false;
     3521  _runningSp3Comp = false;
     3522  _actStart->setText(tr("Sta&rt"));
     3523  enableStartStop();
    35053524}
    35063525
     
    35083527////////////////////////////////////////////////////////////////////////////
    35093528void bncWindow::slotReqcEditOption() {
    3510     saveOptions();
    3511     reqcDlg* dlg = new reqcDlg(this);
    3512     dlg->move(this->pos().x() + 50, this->pos().y() + 50);
    3513     dlg->exec();
    3514     delete dlg;
     3529  saveOptions();
     3530  reqcDlg* dlg = new reqcDlg(this);
     3531  dlg->move(this->pos().x() + 50, this->pos().y() + 50);
     3532  dlg->exec();
     3533  delete dlg;
    35153534}
    35163535
     
    35193538void bncWindow::enableStartStop() {
    35203539
    3521     if (running()) {
    3522         _actStart->setEnabled(false);
    3523         if (_runningRealTime || _runningPPP) {
    3524             _actStop->setEnabled(true);
    3525         }
    3526     }
    3527     else {
    3528         _actStart->setEnabled(true);
    3529         _actStop->setEnabled(false);
    3530     }
     3540  if (running()) {
     3541    _actStart->setEnabled(false);
     3542    if (_runningRealTime || _runningPPP) {
     3543      _actStop->setEnabled(true);
     3544    }
     3545  }
     3546  else {
     3547    _actStart->setEnabled(true);
     3548    _actStop->setEnabled(false);
     3549  }
    35313550}
    35323551
     
    35343553////////////////////////////////////////////////////////////////////////////
    35353554void bncWindow::slotMapMountPoints() {
    3536     saveOptions();
    3537     t_bncMap* bncMap = new t_bncMap(this);
    3538     bncMap->setMinimumSize(800, 600);
    3539     bncMap->setWindowTitle("Selected Mountpoints");
    3540 
    3541     bncSettings settings;
    3542     QListIterator<QString> it(settings.value("mountPoints").toStringList());
    3543     while (it.hasNext()) {
    3544         QStringList hlp = it.next().split(" ");
    3545         if (hlp.size() < 5) continue;
    3546         QUrl   url(hlp[0]);
    3547         double latDeg = hlp[3].toDouble();
    3548         double lonDeg = hlp[4].toDouble();
    3549         bncMap->slotNewPoint(QFileInfo(url.path()).fileName(), latDeg, lonDeg);
    3550     }
    3551 
    3552     bncMap->show();
     3555  saveOptions();
     3556  t_bncMap* bncMap = new t_bncMap(this);
     3557  bncMap->setMinimumSize(800, 600);
     3558  bncMap->setWindowTitle("Selected Mountpoints");
     3559
     3560  bncSettings settings;
     3561  QListIterator<QString> it(settings.value("mountPoints").toStringList());
     3562  while (it.hasNext()) {
     3563    QStringList hlp = it.next().split(" ");
     3564    if (hlp.size() < 5) continue;
     3565    QUrl   url(hlp[0]);
     3566    double latDeg = hlp[3].toDouble();
     3567    double lonDeg = hlp[4].toDouble();
     3568    bncMap->slotNewPoint(QFileInfo(url.path()).fileName(), latDeg, lonDeg);
     3569  }
     3570
     3571  bncMap->show();
    35533572}
    35543573
     
    35573576void bncWindow::slotMapPPP() {
    35583577#ifdef QT_WEBENGINE
    3559     saveOptions();
    3560     enableWidget(false, _pppWidgets._mapWinButton);
    3561     enableWidget(false, _pppWidgets._mapWinDotSize);
    3562     enableWidget(false, _pppWidgets._mapWinDotColor);
    3563 
    3564     if (!_mapWin) {
    3565         _mapWin = new bncMapWin(this);
    3566         connect(_mapWin, SIGNAL(mapClosed()), this, SLOT(slotMapPPPClosed()));
    3567         connect(BNC_CORE, SIGNAL(newPosition(QByteArray, bncTime, QVector<double>)),
     3578  saveOptions();
     3579  enableWidget(false, _pppWidgets._mapWinButton);
     3580  enableWidget(false, _pppWidgets._mapWinDotSize);
     3581  enableWidget(false, _pppWidgets._mapWinDotColor);
     3582
     3583  if (!_mapWin) {
     3584    _mapWin = new bncMapWin(this);
     3585    connect(_mapWin, SIGNAL(mapClosed()), this, SLOT(slotMapPPPClosed()));
     3586    connect(BNC_CORE, SIGNAL(newPosition(QByteArray, bncTime, QVector<double>)),
    35683587            _mapWin, SLOT(slotNewPosition(QByteArray, bncTime, QVector<double>)));
    3569     }
    3570     _mapWin->show();
     3588  }
     3589  _mapWin->show();
    35713590#else
    3572     QMessageBox::information(this, "Information",
    3573         "Qt Library compiled without QT_WEBENGINE");
     3591  QMessageBox::information(this, "Information",
     3592                           "Qt Library compiled without QT_WEBENGINE");
    35743593#endif
    35753594}
     
    35793598void bncWindow::slotMapPPPClosed() {
    35803599#ifdef QT_WEBENGINE
    3581     enableWidget(true, _pppWidgets._mapWinButton);
    3582     enableWidget(true, _pppWidgets._mapWinDotSize);
    3583     enableWidget(true, _pppWidgets._mapWinDotColor);
    3584     if (_mapWin) {
    3585         QListIterator<bncGetThread*> it(_threads);
    3586         while (it.hasNext()) {
    3587             bncGetThread* thread = it.next();
    3588             thread->disconnect(_mapWin);
    3589         }
    3590         _mapWin->deleteLater();
    3591         _mapWin = 0;
    3592     }
     3600  enableWidget(true, _pppWidgets._mapWinButton);
     3601  enableWidget(true, _pppWidgets._mapWinDotSize);
     3602  enableWidget(true, _pppWidgets._mapWinDotColor);
     3603  if (_mapWin) {
     3604    QListIterator<bncGetThread*> it(_threads);
     3605    while (it.hasNext()) {
     3606      bncGetThread* thread = it.next();
     3607      thread->disconnect(_mapWin);
     3608    }
     3609    _mapWin->deleteLater();
     3610    _mapWin = 0;
     3611  }
    35933612#endif
    35943613}
  • trunk/BNC/src/pppInclude.h

    r10409 r10791  
    55#include <vector>
    66#include <newmat.h>
     7#include <sstream>
    78
    89#include "bncconst.h"
     
    1415namespace BNC_PPP {
    1516
     17const double ZEROVALUE = 1e-100;
     18 
    1619class t_except {
    1720 public:
     
    4043};
    4144
     45class t_lc {
     46public:
     47  enum type {dummy = 0, code, phase, codeIF, phaseIF,  MW, CL, GIM, maxLc};
    4248
    43 class t_frqBand {
    44 public:
    45   static t_frequency::type toFreq(char sys, char bb) {
    46     switch (bb) {
    47     case '1':
    48       if      (sys == 'G') return t_frequency::G1;
    49       else if (sys == 'R') return t_frequency::R1;
    50       else if (sys == 'E') return t_frequency::E1;
    51       else if (sys == 'C') return t_frequency::C1;
    52       else                 return t_frequency::dummy;
    53     case '2':
    54       if      (sys == 'G') return t_frequency::G2;
    55       else if (sys == 'R') return t_frequency::R2;
    56       else if (sys == 'C') return t_frequency::C2;
    57       else                 return t_frequency::dummy;
    58     case '5':
    59       if      (sys == 'G') return t_frequency::G5;
    60       else if (sys == 'E') return t_frequency::E5;
    61       else if (sys == 'C') return t_frequency::C5;
    62       else                 return t_frequency::dummy;
    63     case '6':
    64       if      (sys == 'E') return t_frequency::E6;
    65       else if (sys == 'C') return t_frequency::C6;
    66       else                 return t_frequency::dummy;
    67     case '7':
    68       if      (sys == 'E') return t_frequency::E7;
    69       else if (sys == 'C') return t_frequency::C7;
    70       else                 return t_frequency::dummy;
    71     case '8':
    72       if      (sys == 'E') return t_frequency::E8;
    73       else if (sys == 'C') return t_frequency::C8;
    74       else                 return t_frequency::dummy;
    75     }
    76     return t_frequency::dummy;
     49  t_lc() : _type(dummy), _frq1(t_frequency::dummy), _frq2(t_frequency::dummy) {}
     50 
     51  t_lc(type tt, t_frequency::type frq1, t_frequency::type frq2 = t_frequency::dummy)
     52    : _type(tt), _frq1(frq1), _frq2(frq2) {
    7753  }
    78 };
    7954
    80 class t_lc {
    81  public:
    82   enum type {dummy = 0, c1, c2, cIF, l1, l2, lIF,  MW, CL, GIM, maxLc};
    83 
    84   static bool includesPhase(type tt) {
    85     switch (tt) {
    86     case l1:
    87     case l2:
    88     case lIF:
    89     case MW:
    90     case CL:
    91       return true;
    92     case c1:
    93     case c2:
    94     case cIF:
    95       return false;
    96     case dummy:
    97     case maxLc:
    98     case GIM:
     55  bool valid() const {
     56    if      (_type == dummy) {
    9957      return false;
    10058    }
    101     return false;
     59    else if (_type == GIM) {
     60      return true;
     61    }
     62    else {
     63      if (_frq1 == t_frequency::dummy) {
     64        return false;
     65      }
     66      if (t_lc::needs2ndFrq(_type) && _frq2 == t_frequency::dummy) {
     67        return false;
     68      }
     69      return true;
     70    }
    10271  }
    10372
    104   static bool includesCode(type tt) {
    105     switch (tt) {
    106     case c1:
    107     case c2:
    108     case cIF:
    109     case MW:
    110     case CL:
     73  char system() const {
     74    return t_frequency::toSystem(_frq1);
     75  }
     76
     77  static bool needs2ndFrq(type tt) {
     78    if (tt == codeIF || tt == phaseIF || tt == MW) {
    11179      return true;
    112     case l1:
    113     case l2:
    114     case lIF:
    115       return false;
    116     case dummy:
    117     case maxLc:
    118     case GIM:
     80    }
     81    else {
    11982      return false;
    12083    }
    121     return false;
     84  }
     85 
     86  bool includesPhase() const {
     87    if (_type == phase || _type == phaseIF || _type == MW || _type == CL) {
     88      return true;
     89    }
     90    else {
     91      return false;
     92    }
    12293  }
    12394
    124   static t_frequency::type toFreq(char sys, type tt) {
    125     switch (tt) {
    126     case l1: case c1:
    127       if      (sys == 'G') return t_frequency::G1;
    128       else if (sys == 'R') return t_frequency::R1;
    129       else if (sys == 'E') return t_frequency::E1;
    130       else if (sys == 'C') return t_frequency::C2;
    131       else                 return t_frequency::dummy;
    132     case l2: case c2:
    133       if      (sys == 'G') return t_frequency::G2;
    134       else if (sys == 'R') return t_frequency::R2;
    135       else if (sys == 'E') return t_frequency::E5;
    136       else if (sys == 'C') return t_frequency::C6;
    137       else                 return t_frequency::dummy;
    138     case lIF: case cIF: case MW: case CL:
    139       return t_frequency::dummy;
    140     case dummy:
    141     case maxLc:
    142     case GIM:
     95  bool includesCode() const {
     96    if (_type == code || _type == codeIF || _type == MW || _type == CL) {
     97      return true;
     98    }
     99    else {
     100      return false;
     101    }
     102  }
     103
     104  bool isIonoFree() const {
     105    if (_type == codeIF || _type == phaseIF || _type == MW || _type == CL) {
     106      return true;
     107    }
     108    else {
     109      return false;
     110    }
     111  }
     112 
     113  bool isGeometryFree() const {
     114    if (_type == MW || _type == CL || _type == GIM) {
     115      return true;
     116    }
     117    else {
     118      return false;
     119    }
     120  }
     121 
     122  t_frequency::type toFreq() const {
     123    if (_frq2 != t_frequency::dummy) {
    143124      return t_frequency::dummy;
    144125    }
    145     return t_frequency::dummy;
     126    else {
     127      return _frq1;
     128    }
    146129  }
    147130
    148   static std::string toString(type tt) {
    149     switch (tt) {
    150     case l1:  return "l1";
    151     case l2:  return "l2";
    152     case lIF: return "lIF";
    153     case MW:  return "MW";
    154     case CL:  return "CL";
    155     case c1:  return "c1";
    156     case c2:  return "c2";
    157     case cIF: return "cIF";
    158     case GIM: return "GIM";
    159     case dummy:
    160     case maxLc:
    161       return "";
     131  std::string toString() const {
     132    std::stringstream out;
     133    if      (_type == code) {
     134      out << 'c' << t_frequency::toString(_frq1);
    162135    }
    163     return "";
     136    else if (_type == phase) {
     137      out << 'l' << t_frequency::toString(_frq1);
     138    }
     139    else if (_type == codeIF) {
     140      out << 'c' << t_frequency::toSystem(_frq1) << "IF" ;
     141    }
     142    else if (_type == phaseIF) {
     143      out << 'l' << t_frequency::toSystem(_frq1) << "IF" ;
     144    }
     145    else if (_type == MW) {
     146      out << t_frequency::toSystem(_frq1) << "MW" ;
     147    }
     148    else if (_type == CL) {
     149      out << t_frequency::toSystem(_frq1) << "CL" ;
     150    }
     151    else if (_type == GIM) {
     152      out << t_frequency::toSystem(_frq1) << "GIM" ;
     153    }
     154    return out.str();
    164155  }
     156
     157  bool operator==(const t_lc& other) const {
     158    if (_type == other._type && _frq1 == other._frq1 && _frq2 == other._frq2) {
     159      return true;
     160    }
     161    else {
     162      return false;
     163    }
     164  }
     165
     166  bool operator!=(const t_lc& other) const {
     167    return !(*this == other);
     168  }
     169
     170  bool operator <(const t_lc& other) const {
     171    if      (_type != other._type) {
     172      return _type < other._type;
     173    }
     174    else if (_frq1 != other._frq1) {
     175      return _frq1 < other._frq1;
     176    }
     177    else {
     178      return _frq2 < other._frq2;
     179    }
     180  }
     181
     182  type              _type;
     183  t_frequency::type _frq1;
     184  t_frequency::type _frq2;
    165185};
    166186
  • trunk/BNC/src/pppMain.cpp

    r10638 r10791  
    149149    t_pppOptions* opt = new t_pppOptions();
    150150
    151     opt->_realTime         = _realTime;
    152     opt->_roverName        = hlp[0].toStdString();
    153     opt->_aprSigCrd[0]     = hlp[1].toDouble()+1e-10;
    154     opt->_aprSigCrd[1]     = hlp[2].toDouble()+1e-10;
    155     opt->_aprSigCrd[2]     = hlp[3].toDouble()+1e-10;
    156     opt->_noiseCrd[0]      = hlp[4].toDouble()+1e-10;
    157     opt->_noiseCrd[1]      = hlp[5].toDouble()+1e-10;
    158     opt->_noiseCrd[2]      = hlp[6].toDouble()+1e-10;
    159     opt->_aprSigTrp        = hlp[7].toDouble();
    160     opt->_noiseTrp         = hlp[8].toDouble();
    161     opt->_nmeaPort         = hlp[9].toInt();
    162 #ifdef USE_PPP
    163     opt->_signalPriorities = hlp[10].toStdString();
    164     if (!opt->_signalPriorities.size()) {
    165       opt->_signalPriorities = "G:12&CWPSLX R:12&CP E:1&CBX E:5&QIX C:26&IQX";
    166     }
    167 #endif
     151    if      (settings.value("PPP/logMode").toString() == "debug") {
     152      opt->_logMode = t_pppOptions::debug;
     153    }
     154    else if (settings.value("PPP/logMode").toString() == "all") {
     155      opt->_logMode = t_pppOptions::all;
     156    }
     157    else {
     158      opt->_logMode = t_pppOptions::normal;
     159    }
     160
     161    opt->_realTime     = _realTime;
     162    opt->_roverName    = hlp[0].toStdString();
     163    opt->_aprSigCrd[0] = hlp[1].toDouble()+1e-10;
     164    opt->_aprSigCrd[1] = hlp[2].toDouble()+1e-10;
     165    opt->_aprSigCrd[2] = hlp[3].toDouble()+1e-10;
     166    opt->_noiseCrd[0]  = hlp[4].toDouble()+1e-10;
     167    opt->_noiseCrd[1]  = hlp[5].toDouble()+1e-10;
     168    opt->_noiseCrd[2]  = hlp[6].toDouble()+1e-10;
     169    opt->_aprSigTrp    = hlp[7].toDouble();
     170    opt->_noiseTrp     = hlp[8].toDouble();
     171    opt->_nmeaPort     = hlp[9].toInt();
     172
     173    string trkStr      = hlp[10].trimmed().toStdString();
     174    if (trkStr.length() == 0) {
     175      trkStr = "G:12&CWPSLX R:12&CP E:1&CBX E:5&QIX C:26&IQX";
     176    }
     177    opt->setTrkModes(trkStr);
     178   
    168179    if (_realTime) {
    169180      opt->_corrMount.assign(settings.value("PPP/corrMount").toString().toStdString());
    170181      opt->_isAPC = (opt->_corrMount.substr(0,4)=="SSRA");
     182      opt->_biasMount.assign(settings.value("PPP/biasMount").toString().toStdString());
    171183      opt->_ionoMount.assign(settings.value("PPP/ionoMount").toString().toStdString());
    172184    }
     
    177189      QFileInfo tmp = QFileInfo(QString::fromStdString(opt->_corrFile));
    178190      opt->_isAPC = (tmp.baseName().mid(0,4)=="SSRA");
     191      opt->_biasFile.assign(settings.value("PPP/biasFile").toString().toStdString());
    179192      opt->_ionoFile.assign(settings.value("PPP/ionoFile").toString().toStdString());
    180193    }
     
    182195    opt->_crdFile.assign(settings.value("PPP/crdFile").toString().toStdString());
    183196    opt->_antexFileName.assign(settings.value("PPP/antexFile").toString().toStdString());
    184 #ifdef USE_PPP
    185197    opt->_blqFileName.assign(settings.value("PPP/blqFile").toString().toStdString());
    186 #endif
    187198    opt->_sigmaC1      = settings.value("PPP/sigmaC1").toDouble(); if (opt->_sigmaC1 <= 0.0)  opt->_sigmaC1  = 1.00;
    188199    opt->_sigmaL1      = settings.value("PPP/sigmaL1").toDouble(); if (opt->_sigmaL1 <= 0.0)  opt->_sigmaL1  = 0.01;
     
    195206    opt->_pseudoObsIono  = false;
    196207    opt->_refSatRequired = false;
    197 #ifdef USE_PPP_SSR_I
    198     if (settings.value("PPP/lcGPS").toString() == "P3&L3") {
    199       opt->_LCsGPS.push_back(t_lc::cIF);
    200       opt->_LCsGPS.push_back(t_lc::lIF);
    201     }
    202     if (settings.value("PPP/lcGPS").toString() == "P3") {
    203       opt->_LCsGPS.push_back(t_lc::cIF);
    204     }
    205     if (settings.value("PPP/lcGLONASS").toString() == "P3&L3") {
    206       opt->_LCsGLONASS.push_back(t_lc::cIF);
    207       opt->_LCsGLONASS.push_back(t_lc::lIF);
    208     }
    209     if (settings.value("PPP/lcGLONASS").toString() == "P3") {
    210       opt->_LCsGLONASS.push_back(t_lc::cIF);
    211     }
    212     if (settings.value("PPP/lcGLONASS").toString() == "L3") {
    213       opt->_LCsGLONASS.push_back(t_lc::lIF);
    214     }
    215     if (settings.value("PPP/lcGalileo").toString() == "P3&L3") {
    216       opt->_LCsGalileo.push_back(t_lc::cIF);
    217       opt->_LCsGalileo.push_back(t_lc::lIF);
    218     }
    219     if (settings.value("PPP/lcGalileo").toString() == "P3") {
    220       opt->_LCsGalileo.push_back(t_lc::cIF);
    221     }
    222     if (settings.value("PPP/lcGalileo").toString() == "L3") {
    223       opt->_LCsGalileo.push_back(t_lc::lIF);
    224     }
    225     if (settings.value("PPP/lcBDS").toString() == "P3&L3") {
    226       opt->_LCsBDS.push_back(t_lc::cIF);
    227       opt->_LCsBDS.push_back(t_lc::lIF);
    228     }
    229     if (settings.value("PPP/lcBDS").toString() == "P3") {
    230       opt->_LCsBDS.push_back(t_lc::cIF);
    231     }
    232     if (settings.value("PPP/lcBDS").toString() == "L3") {
    233       opt->_LCsBDS.push_back(t_lc::lIF);
    234     }
    235 #else
    236208    // Pseudo Observations
    237209    if      (settings.value("PPP/constraints").toString() == "no") {
     
    245217      opt->_ionoModelType = opt->est;
    246218    }
    247     // GPS
    248     if (settings.value("PPP/lcGPS").toString() == "Pi&Li") {
    249       opt->_LCsGPS.push_back(t_lc::c1);
    250       opt->_LCsGPS.push_back(t_lc::c2);
    251       opt->_LCsGPS.push_back(t_lc::l1);
    252       opt->_LCsGPS.push_back(t_lc::l2);
    253       if (opt->_pseudoObsIono) {
    254         opt->_LCsGPS.push_back(t_lc::GIM);
    255       }
    256     }
    257     if (settings.value("PPP/lcGPS").toString() == "Pi") {
    258       opt->_LCsGPS.push_back(t_lc::c1);
    259       opt->_LCsGPS.push_back(t_lc::c2);
    260       if (opt->_pseudoObsIono) {
    261         opt->_LCsGPS.push_back(t_lc::GIM);
    262       }
    263     }
    264     if (settings.value("PPP/lcGPS").toString() == "P1&L1") {
    265       opt->_LCsGPS.push_back(t_lc::c1);
    266       opt->_LCsGPS.push_back(t_lc::l1);
    267       if (opt->_pseudoObsIono) {
    268         opt->_LCsGPS.push_back(t_lc::GIM);
    269       }
    270     }
    271     if (settings.value("PPP/lcGPS").toString() == "P1") {
    272         opt->_LCsGPS.push_back(t_lc::c1);
    273         if (opt->_pseudoObsIono) {
    274           opt->_LCsGPS.push_back(t_lc::GIM);
    275         }
    276     }
    277     if (settings.value("PPP/lcGPS").toString() == "P3&L3") {
    278       opt->_LCsGPS.push_back(t_lc::cIF);
    279       opt->_LCsGPS.push_back(t_lc::lIF);
    280     }
    281     if (settings.value("PPP/lcGPS").toString() == "P3") {
    282       opt->_LCsGPS.push_back(t_lc::cIF);
    283     }
    284     if (settings.value("PPP/lcGPS").toString() == "L3") {
    285       opt->_LCsGPS.push_back(t_lc::lIF);
    286     }
    287     // GLONASS
    288     if (settings.value("PPP/lcGLONASS").toString() == "Pi&Li") {
    289       opt->_LCsGLONASS.push_back(t_lc::c1);
    290       opt->_LCsGLONASS.push_back(t_lc::c2);
    291       opt->_LCsGLONASS.push_back(t_lc::l1);
    292       opt->_LCsGLONASS.push_back(t_lc::l2);
    293       if (opt->_pseudoObsIono) {
    294         opt->_LCsGLONASS.push_back(t_lc::GIM);
    295       }
    296     }
    297     if (settings.value("PPP/lcGLONASS").toString() == "Pi") {
    298       opt->_LCsGLONASS.push_back(t_lc::c1);
    299       opt->_LCsGLONASS.push_back(t_lc::c2);
    300       if (opt->_pseudoObsIono) {
    301         opt->_LCsGLONASS.push_back(t_lc::GIM);
    302       }
    303     }
    304     if (settings.value("PPP/lcGLONASS").toString() == "P1&L1") {
    305       opt->_LCsGLONASS.push_back(t_lc::c1);
    306       opt->_LCsGLONASS.push_back(t_lc::l1);
    307       if (opt->_pseudoObsIono) {
    308         opt->_LCsGLONASS.push_back(t_lc::GIM);
    309       }
    310     }
    311     if (settings.value("PPP/lcGLONASS").toString() == "P1") {
    312         opt->_LCsGLONASS.push_back(t_lc::c1);
    313         if (opt->_pseudoObsIono) {
    314           opt->_LCsGLONASS.push_back(t_lc::GIM);
    315         }
    316     }
    317     if (settings.value("PPP/lcGLONASS").toString() == "P3&L3") {
    318       opt->_LCsGLONASS.push_back(t_lc::cIF);
    319       opt->_LCsGLONASS.push_back(t_lc::lIF);
    320     }
    321     if (settings.value("PPP/lcGLONASS").toString() == "P3") {
    322       opt->_LCsGLONASS.push_back(t_lc::cIF);
    323     }
    324     if (settings.value("PPP/lcGLONASS").toString() == "L3") {
    325       opt->_LCsGLONASS.push_back(t_lc::lIF);
    326     }
    327     // Galileo
    328     if (settings.value("PPP/lcGalileo").toString() == "Pi&Li") {
    329       opt->_LCsGalileo.push_back(t_lc::c1);
    330       opt->_LCsGalileo.push_back(t_lc::c2);
    331       opt->_LCsGalileo.push_back(t_lc::l1);
    332       opt->_LCsGalileo.push_back(t_lc::l2);
    333       if (opt->_pseudoObsIono) {
    334         opt->_LCsGalileo.push_back(t_lc::GIM);
    335       }
    336     }
    337     if (settings.value("PPP/lcGalileo").toString() == "Pi") {
    338       opt->_LCsGalileo.push_back(t_lc::c1);
    339       opt->_LCsGalileo.push_back(t_lc::c2);
    340       if (opt->_pseudoObsIono) {
    341         opt->_LCsGalileo.push_back(t_lc::GIM);
    342       }
    343     }
    344     if (settings.value("PPP/lcGalileo").toString() == "P1&L1") {
    345       opt->_LCsGalileo.push_back(t_lc::c1);
    346       opt->_LCsGalileo.push_back(t_lc::l1);
    347       if (opt->_pseudoObsIono) {
    348         opt->_LCsGalileo.push_back(t_lc::GIM);
    349       }
    350     }
    351     if (settings.value("PPP/lcGalileo").toString() == "P1") {
    352         opt->_LCsGalileo.push_back(t_lc::c1);
    353         if (opt->_pseudoObsIono) {
    354           opt->_LCsGalileo.push_back(t_lc::GIM);
    355         }
    356     }
    357     if (settings.value("PPP/lcGalileo").toString() == "P3&L3") {
    358       opt->_LCsGalileo.push_back(t_lc::cIF);
    359       opt->_LCsGalileo.push_back(t_lc::lIF);
    360     }
    361     if (settings.value("PPP/lcGalileo").toString() == "P3") {
    362       opt->_LCsGalileo.push_back(t_lc::cIF);
    363     }
    364     if (settings.value("PPP/lcGalileo").toString() == "L3") {
    365       opt->_LCsGalileo.push_back(t_lc::lIF);
    366     }
    367     // BDS
    368     if (settings.value("PPP/lcBDS").toString() == "Pi&Li") {
    369       opt->_LCsBDS.push_back(t_lc::c1);
    370       opt->_LCsBDS.push_back(t_lc::c2);
    371       opt->_LCsBDS.push_back(t_lc::l1);
    372       opt->_LCsBDS.push_back(t_lc::l2);
    373       if (opt->_pseudoObsIono) {
    374         opt->_LCsBDS.push_back(t_lc::GIM);
    375       }
    376     }
    377     if (settings.value("PPP/lcBDS").toString() == "Pi") {
    378       opt->_LCsBDS.push_back(t_lc::c1);
    379       opt->_LCsBDS.push_back(t_lc::c2);
    380       if (opt->_pseudoObsIono) {
    381         opt->_LCsBDS.push_back(t_lc::GIM);
    382       }
    383     }
    384     if (settings.value("PPP/lcBDS").toString() == "P1&L1") {
    385       opt->_LCsBDS.push_back(t_lc::c1);
    386       opt->_LCsBDS.push_back(t_lc::l1);
    387       if (opt->_pseudoObsIono) {
    388         opt->_LCsBDS.push_back(t_lc::GIM);
    389       }
    390     }
    391     if (settings.value("PPP/lcBDS").toString() == "P1") {
    392         opt->_LCsBDS.push_back(t_lc::c1);
    393         if (opt->_pseudoObsIono) {
    394           opt->_LCsBDS.push_back(t_lc::GIM);
    395         }
    396     }
    397     if (settings.value("PPP/lcBDS").toString() == "P3&L3") {
    398       opt->_LCsBDS.push_back(t_lc::cIF);
    399       opt->_LCsBDS.push_back(t_lc::lIF);
    400     }
    401     if (settings.value("PPP/lcBDS").toString() == "P3") {
    402       opt->_LCsBDS.push_back(t_lc::cIF);
    403     }
    404     if (settings.value("PPP/lcBDS").toString() == "L3") {
    405       opt->_LCsBDS.push_back(t_lc::lIF);
    406     }
    407 
    408     QString     priorStr  = QString::fromStdString(opt->_signalPriorities);
    409     QStringList priorList = priorStr.split(" ", Qt::SkipEmptyParts);
    410     QStringList hlpList;
    411     vector<char> systems = opt->systems();
    412     for (unsigned iSys= 0; iSys < systems.size(); iSys++) {
    413       char sys = systems[iSys];
    414       for (int ii = 0; ii < priorList.size(); ii++) {
    415         if (priorList[ii].indexOf(":") != -1) {
    416           hlpList = priorList[ii].split(":", Qt::SkipEmptyParts);
    417           if (hlpList.size() == 2 && hlpList[0].length() == 1 && hlpList[0][0] == sys) {
    418             hlpList = hlpList[1].split("&", Qt::SkipEmptyParts);
    419             if (hlpList.size() == 2) {
    420               for (int jj = 0; jj < hlpList[0].size(); jj++) {
    421                 char bb = hlpList[0][jj].toLatin1();
    422                 if      (sys == 'G' && opt->_frqBandsGPS.size() < 2) {
    423                   opt->_frqBandsGPS.push_back(bb);
    424                 }
    425                 else if (sys == 'R' && opt->_frqBandsGLONASS.size() < 2) {
    426                   opt->_frqBandsGLONASS.push_back(bb);
    427                 }
    428                 else if (sys == 'E' && opt->_frqBandsGalileo.size() < 2) {
    429                   opt->_frqBandsGalileo.push_back(bb);
    430                 }
    431                 else if (sys == 'C' && opt->_frqBandsBDS.size() < 2) {
    432                   opt->_frqBandsBDS.push_back(bb);
    433                 }
    434               }
    435             }
    436           }
    437         }
    438       }
    439     }
    440 #endif
    441 
     219   
     220    opt->setLCs('G', settings.value("PPP/lcGPS")    .toString().trimmed().toStdString());
     221    opt->setLCs('R', settings.value("PPP/lcGLONASS").toString().trimmed().toStdString());
     222    opt->setLCs('E', settings.value("PPP/lcGalileo").toString().trimmed().toStdString());
     223    opt->setLCs('C', settings.value("PPP/lcBDS")    .toString().trimmed().toStdString());
    442224
    443225    // Information from the coordinate file
     
    472254    opt->_seedingTime = settings.value("PPP/seedingTime").toDouble();
    473255
     256    // Ambiguity Resolution
     257    // --------------------
     258    if (settings.value("PPP/arGPS").toInt() != 0) {
     259      opt->_ar._systems.insert('G');
     260    }
     261    if (settings.value("PPP/arGalileo").toInt() != 0) {
     262      opt->_ar._systems.insert('E');
     263    }
     264    if (settings.value("PPP/arBDS").toInt() != 0) {
     265      opt->_ar._systems.insert('C');
     266    }
     267    opt->_ar._minEle    = opt->_minEle;
     268    opt->_ar._minNumEpo = settings.value("PPP/arMinNumEpo").toInt();
     269    opt->_ar._minNumSat = settings.value("PPP/arMinNumSat").toInt();
     270    opt->_ar._useYaw    = (settings.value("PPP/arUseYaw").toInt() != 0);
     271    opt->_ar._maxFrac   = settings.value("PPP/arMaxFrac").toDouble();
     272    opt->_ar._maxSig    = settings.value("PPP/arMaxSig").toDouble();
     273     
    474274    // Some default values
    475275    // -------------------
    476     opt->_aprSigClk       = 3.0e5;
    477     opt->_aprSigClkOff    = 3.0e5;
    478     opt->_aprSigAmb       = 1.0e4;
    479     opt->_aprSigIon       = 1.0e6;
    480     opt->_noiseIon        = 1.0e6;
    481     opt->_aprSigCodeBias  = 10000.0;
    482     opt->_noiseCodeBias   = 10000.0;
    483     opt->_aprSigPhaseBias = 10000.0;
    484     opt->_noisePhaseBias  = 10000.0;
     276    opt->_aprSigClk       = 1e3;
     277    opt->_aprSigAmb       = 1e3;
     278    opt->_aprSigIon       = 1e2;
     279    opt->_aprSigCodeBias  = 1e1;
    485280
    486281    _options << opt;
  • trunk/BNC/src/pppModel.cpp

    r10234 r10791  
    4040
    4141#include <cmath>
    42 
     42#include <newmatio.h>
    4343#include "pppModel.h"
    4444
     
    542542///////////////////////////////////////////////////////////////////////////
    543543double t_windUp::value(const bncTime& etime, const ColumnVector& rRec,
    544     t_prn prn, const ColumnVector& rSat, bool ssr,
    545     double yaw, const ColumnVector& vSat) {
     544                       t_prn prn, const ColumnVector& rSat, bool useYaw,
     545                       double yaw, const ColumnVector& vSat) {
    546546
    547547  if (etime.mjddec() != lastEtime[prn.toInt()]) {
     
    555555    // -------------------------------------
    556556    ColumnVector sHlp;
    557     if (!ssr) {
     557    if (!useYaw) {
    558558      sHlp = t_astro::Sun(etime.mjddec());
    559559    }
     
    571571    ColumnVector sx = crossproduct(sy, sz);
    572572
    573     if (ssr) {
    574       // Yaw angle consideration
    575       Matrix SXYZ(3, 3);
    576       SXYZ.Column(1) = sx;
    577       SXYZ.Column(2) = sy;
    578       SXYZ.Column(3) = sz;
    579       SXYZ = DotProduct(t_astro::rotZ(yaw), SXYZ);
    580       sx = SXYZ.Column(1);
    581       sy = SXYZ.Column(2);
    582       sz = SXYZ.Column(3);
    583     }
     573    //// beg test
     574    // {
     575    //   ColumnVector sun = t_astro::Sun(etime.mjddec());
     576    //   sun /= sun.NormFrobenius();
     577    //   ColumnVector syHlp = crossproduct(sz, sun);
     578    //   double yawDef = acos( DotProduct(sy, syHlp));
     579    //   cout.setf(ios::fixed);
     580    //   cout << string(etime) << ' ' << prn.toString()
     581    //        << ' ' << setw(7) << setprecision(3) << yaw    * 180.0 / M_PI
     582    //        << ' ' << setw(7) << setprecision(3) << yawDef * 180.0 / M_PI << endl;
     583    // }
     584    //// end test
     585
     586    // Yaw angle consideration (Rodrigues rotation formula)
     587    // ----------------------------------------------------
     588    if (useYaw) {
     589      double cosY = cos(yaw);
     590      double sinY = sin(yaw);
     591      sx = sx * cosY + crossproduct(sz, sx) * sinY; // + sz * DotProduct(sz, sx) * (1.0 - cosY);
     592      sy = sy * cosY + crossproduct(sz, sy) * sinY; // + sz * DotProduct(sz, sy) * (1.0 - cosY);
     593    }
     594   
    584595    // Effective Dipole of the GPS Satellite Antenna
    585596    // ---------------------------------------------
  • trunk/BNC/src/pppModel.h

    r8905 r10791  
    5858  ~t_windUp() {};
    5959  double value(const bncTime& etime, const ColumnVector& rRec, t_prn prn,
    60                const ColumnVector& rSat, bool ssr, double yaw,
     60               const ColumnVector& rSat, bool useYaw, double yaw,
    6161               const ColumnVector& vSat);
    6262 private:
  • trunk/BNC/src/pppOptions.cpp

    r10251 r10791  
    3939 * -----------------------------------------------------------------------*/
    4040
     41#include <QtCore>
     42#include <set>
    4143#include <newmatio.h>
    4244#include "pppOptions.h"
     
    6163//
    6264//////////////////////////////////////////////////////////////////////////////
    63 const std::vector<t_lc::type>& t_pppOptions::LCs(char system) const {
     65const std::vector<t_lc>& t_pppOptions::LCs(char system) const {
    6466
    6567  if      (system == 'R') {
     
    7476  else {
    7577    return _LCsGPS;
    76   }
    77 }
    78 
    79 //
    80 //////////////////////////////////////////////////////////////////////////////
    81 const std::vector<char>& t_pppOptions::frqBands(char system) const {
    82 
    83   if      (system == 'R') {
    84     return _frqBandsGLONASS;
    85   }
    86   else if (system == 'E') {
    87     return _frqBandsGalileo;
    88   }
    89   else if (system == 'C') {
    90     return  _frqBandsBDS;
    91   }
    92   else {
    93     return _frqBandsGPS;
    9478  }
    9579}
     
    119103//
    120104/////////////////////////////////////////////////////////////////////////////
    121 vector<t_lc::type> t_pppOptions::ambLCs(char system) const {
    122 
    123   const vector<t_lc::type>& allLCs = LCs(system);
    124   vector<t_lc::type>        phaseLCs;
     105vector<t_lc> t_pppOptions::ambLCs(char system) const {
     106
     107  set<t_frequency::type> frqs;
     108
     109  int numPhaseLCs = 0;
     110  const vector<t_lc>& allLCs = LCs(system);
    125111  for (unsigned ii = 0; ii < allLCs.size(); ii++) {
    126     if (t_lc::includesPhase(allLCs[ii])) {
    127       phaseLCs.push_back(allLCs[ii]);
    128     }
    129   }
    130 
    131   vector<t_lc::type> answ;
    132   if      (phaseLCs.size() == 1) {
    133     answ.push_back(phaseLCs[0]);
    134   }
    135   else if (phaseLCs.size() >  1) {
    136     answ.push_back(t_lc::l1);
    137     answ.push_back(t_lc::l2);
     112    const t_lc& LC = allLCs[ii];
     113    if (LC.includesPhase()) {
     114      numPhaseLCs += 1;
     115      frqs.insert(LC._frq1);
     116      if (LC._frq2 != t_frequency::dummy) {
     117        frqs.insert(LC._frq2);
     118      }
     119    }
     120  }
     121
     122  vector<t_lc> answ;
     123  for (auto it = frqs.begin(); it != frqs.end(); ++it) {
     124    answ.push_back(t_lc(t_lc::phase, *it));
     125    if (numPhaseLCs == 1) {
     126      break;
     127    }
    138128  }
    139129
     
    143133//
    144134/////////////////////////////////////////////////////////////////////////////
    145 vector<t_lc::type> t_pppOptions::codeLCs(char system) const {
    146 
    147   const vector<t_lc::type>& allLCs = LCs(system);
    148   vector<t_lc::type>        codeLCs;
    149   for (unsigned ii = 0; ii < allLCs.size(); ii++) {
    150     if (t_lc::includesCode(allLCs[ii])) {
    151       codeLCs.push_back(allLCs[ii]);
    152     }
    153   }
    154 
    155   vector<t_lc::type> answ;
    156   if      (codeLCs.size() == 1) {
    157     answ.push_back(codeLCs[0]);
    158   }
    159   else if (codeLCs.size() >  1) {
    160     answ.push_back(t_lc::c1);
    161     answ.push_back(t_lc::c2);
    162   }
    163 
    164   return answ;
    165 }
    166 
    167 
     135void t_pppOptions::setTrkModes(const std::string& trkStr) {
     136
     137  QStringList priorList = QString::fromStdString(trkStr).split(" ", Qt::SkipEmptyParts);
     138  for (int ii = 0; ii < priorList.size(); ii++) {
     139    if (priorList[ii].indexOf(":") != -1) {
     140      QStringList sysList = priorList[ii].split(":", Qt::SkipEmptyParts);
     141      if (sysList.size() == 2 && sysList[0].length() == 1) {
     142        char sys = sysList[0].toStdString()[0];
     143        SysTrkModes& sysTrkModes = _trkModesMap[sys];
     144        QStringList hlpList = sysList[1].split("&", Qt::SkipEmptyParts);
     145        if (hlpList.size() == 2) {
     146          string frqStr = hlpList[0].toStdString();
     147          string trkStr = hlpList[1].toStdString();
     148          for (unsigned jj = 0; jj < frqStr.length(); jj++) {
     149            char frqChar = frqStr[jj];
     150            t_frequency::type frq = t_frequency::toFreq(sys, frqChar);
     151            sysTrkModes._frqTrkModes.push_back(SysTrkModes::FrqTrkModes(frq, trkStr));
     152          }
     153        }
     154      }
     155    }
     156  }
     157
     158  //// beg test
     159  // for (const auto& [key, value] : _trkModesMap) {
     160  //   cout << "system: " << key << endl;
     161  //   for (const auto& frqTrk : value._frqTrkModes) {
     162  //     cout << "    freq: "  << t_frequency::toString(frqTrk._frq) << ' '
     163  //          << frqTrk._trkModes << endl;
     164  //   }
     165  // }
     166  //// end test
     167}
     168
     169//
     170/////////////////////////////////////////////////////////////////////////////
     171void t_pppOptions::defaultFrqs(char sys, t_frequency::type& frq1, t_frequency::type& frq2) const {
     172
     173  frq1 = t_frequency::dummy;
     174  frq2 = t_frequency::dummy;
     175
     176  const SysTrkModes* sysTrkModes = this->sysTrkModes(sys);
     177
     178  if (sysTrkModes) {
     179    if (sysTrkModes->_frqTrkModes.size() > 0) {
     180      frq1 = sysTrkModes->_frqTrkModes[0]._frq;
     181    }
     182    if (sysTrkModes->_frqTrkModes.size() > 1) {
     183      frq2 = sysTrkModes->_frqTrkModes[1]._frq;
     184    }
     185  }
     186  else {
     187    if      (sys == 'G') {
     188      frq1 = t_frequency::G1;
     189      frq2 = t_frequency::G2;
     190    }
     191    else if (sys == 'R') {
     192      frq1 = t_frequency::R1;
     193      frq2 = t_frequency::R2;
     194    }
     195    else if (sys == 'E') {
     196      frq1 = t_frequency::E1;
     197      frq2 = t_frequency::E5;
     198    }
     199    else if (sys == 'C') {
     200      frq1 = t_frequency::C1;
     201      frq2 = t_frequency::C5;
     202    }
     203  }
     204}
     205
     206//
     207/////////////////////////////////////////////////////////////////////////////
     208void t_pppOptions::setLCs(char sys, const std::string& lcStr) {
     209
     210  std::vector<t_lc>* LCs = 0;
     211  if      (sys == 'G') {
     212    LCs = &_LCsGPS;
     213  }
     214  else if (sys == 'R') {
     215    LCs = &_LCsGLONASS;
     216  }
     217  else if (sys == 'E') {
     218    LCs = &_LCsGalileo;
     219  }
     220  else if (sys == 'C') {
     221    LCs = &_LCsBDS;
     222  }
     223  else {
     224    return;
     225  }
     226
     227  t_frequency::type frq1 = t_frequency::dummy;
     228  t_frequency::type frq2 = t_frequency::dummy;
     229  defaultFrqs(sys, frq1, frq2);
     230
     231  if      (lcStr == "Pi&Li") {
     232    if (frq1 != t_frequency::dummy) LCs->push_back(t_lc(t_lc::code,  frq1));
     233    if (frq2 != t_frequency::dummy) LCs->push_back(t_lc(t_lc::code,  frq2));
     234    if (frq1 != t_frequency::dummy) LCs->push_back(t_lc(t_lc::phase, frq1));
     235    if (frq2 != t_frequency::dummy) LCs->push_back(t_lc(t_lc::phase, frq2));
     236    if (_pseudoObsIono) {
     237      LCs->push_back(t_lc(t_lc::GIM, t_frequency::dummy));
     238    }
     239  }
     240  else if (lcStr == "Pi") {
     241    if (frq1 != t_frequency::dummy) LCs->push_back(t_lc(t_lc::code, frq1));
     242    if (frq2 != t_frequency::dummy) LCs->push_back(t_lc(t_lc::code, frq2));
     243    if (_pseudoObsIono) {
     244      LCs->push_back(t_lc(t_lc::GIM, t_frequency::dummy));
     245    }
     246  }
     247  else if (lcStr == "P1&L1") {
     248    if (frq1 != t_frequency::dummy) LCs->push_back(t_lc(t_lc::code,  frq1));
     249    if (frq1 != t_frequency::dummy) LCs->push_back(t_lc(t_lc::phase, frq1));
     250    if (_pseudoObsIono) {
     251      LCs->push_back(t_lc(t_lc::GIM, t_frequency::dummy));
     252    }
     253  }
     254  else if (lcStr == "P1") {
     255    if (frq1 != t_frequency::dummy) LCs->push_back(t_lc(t_lc::code, frq1));
     256    if (_pseudoObsIono) {
     257      LCs->push_back(t_lc(t_lc::GIM, t_frequency::dummy));
     258    }
     259  }
     260  else if (lcStr == "P3&L3") {
     261    if (frq1 != t_frequency::dummy && frq2 != t_frequency::dummy) {
     262      LCs->push_back(t_lc(t_lc::codeIF,  frq1, frq2));
     263      LCs->push_back(t_lc(t_lc::phaseIF, frq1, frq2));
     264    }
     265  }
     266  else if (lcStr == "P3") {
     267    if (frq1 != t_frequency::dummy && frq2 != t_frequency::dummy) {
     268      LCs->push_back(t_lc(t_lc::codeIF, frq1, frq2));
     269    }
     270  }
     271  else if (lcStr == "L3") {
     272    if (frq1 != t_frequency::dummy && frq2 != t_frequency::dummy) {
     273      LCs->push_back(t_lc(t_lc::phaseIF, frq1, frq2));
     274    }
     275  }
     276  else {
     277    QStringListIterator it(QString(lcStr.c_str()).split("&", Qt::SkipEmptyParts));
     278    while (it.hasNext()) {
     279      string hlp = it.next().toStdString();
     280      for (unsigned ii = 1; ii < hlp.length(); ++ii) {
     281        t_frequency::type frq = t_frequency::toFreq(sys, hlp[ii]);
     282        if (frq != t_frequency::dummy) {
     283          if      (hlp[0] == 'P') {
     284            LCs->push_back(t_lc(t_lc::code, frq));
     285          }
     286          else if (hlp[0] == 'L') {
     287            LCs->push_back(t_lc(t_lc::phase, frq));
     288          }
     289        }
     290      }
     291    }
     292  }
     293}
  • trunk/BNC/src/pppOptions.h

    r10256 r10791  
    44#include <string>
    55#include <vector>
     6#include <set>
    67#include <newmat.h>
    78#include "pppInclude.h"
     
    1112class t_pppOptions {
    1213 public:
    13   enum iono_type {est,PPP_RTK};
     14  enum iono_type {est};
     15  enum e_logMode {normal, debug, all};
     16
     17  class SysTrkModes {
     18  public:
     19    class FrqTrkModes {
     20    public:
     21      FrqTrkModes(t_frequency::type frq, const std::string trkModes)
     22        : _frq(frq), _trkModes(trkModes)  {}
     23      t_frequency::type _frq;
     24      std::string       _trkModes;
     25    };
     26    std::vector<FrqTrkModes> _frqTrkModes;
     27  };
     28
     29  class ArOptions {
     30  public:
     31    std::set<char> _systems;
     32    double         _minEle    = 0.0;
     33    unsigned       _minNumEpo = 0;
     34    int            _minNumSat = 0;
     35    bool           _useYaw    = false;
     36    double         _maxFrac   = 0.0;
     37    double         _maxSig    = 0.0;
     38  };
     39 
    1440  t_pppOptions();
    1541  ~t_pppOptions();
    1642
    17   std::vector<char>              systems() const;
    18   const std::vector<t_lc::type>& LCs(char system) const;
    19   const std::vector<char>&       frqBands(char system) const;
    20   std::vector<t_lc::type>        ambLCs(char system) const;
    21   std::vector<t_lc::type>        codeLCs(char system) const;
    22   std::vector<t_lc::type>        ionoLCs(char system) const;
    23   bool useSystem(char system) const {return LCs(system).size() > 0;}
    24   bool useOrbClkCorr() const;
    25   bool estTrp() const {return _aprSigTrp > 0.0 || _noiseTrp > 0.0;}
     43  std::vector<char>        systems() const;
     44  const std::vector<t_lc>& LCs(char system) const;
     45  std::vector<t_lc>        ambLCs(char system) const;
     46  bool                     useSystem(char system) const {return LCs(system).size() > 0;}
     47  bool                     useOrbClkCorr() const;
     48  bool                     estTrp() const {return _aprSigTrp > 0.0 || _noiseTrp > 0.0;}
    2649  bool xyzAprRoverSet() const {
    2750    return (_xyzAprRover[0] != 0.0 || _xyzAprRover[1] != 0.0 || _xyzAprRover[2] != 0.0);
    2851  }
     52  void setTrkModes(const std::string& trkStr);
     53  const SysTrkModes* sysTrkModes(char sys) const {
     54    auto it = _trkModesMap.find(sys);
     55    return (it != _trkModesMap.end() ? &it->second : 0);
     56  }
     57  void setLCs(char sys, const std::string& lcStr);
     58  void defaultFrqs(char sys, t_frequency::type& frq1, t_frequency::type& frq2) const;
     59  bool ambRes() const {return _ar._systems.size() > 0;}
     60  bool arSystem(char sys) const {return _ar._systems.find(sys) != _ar._systems.end();}
    2961
    30   iono_type               _ionoModelType;
    31   bool                    _realTime;
    32   std::string             _crdFile;
    33   std::string             _corrMount;
    34   std::string             _ionoMount;
    35   bool                    _isAPC;
    36   std::string             _rinexObs;
    37   std::string             _rinexNav;
    38   std::string             _corrFile;
    39   std::string             _ionoFile;
    40   double                  _corrWaitTime;
    41   std::string             _roverName;
    42   ColumnVector            _xyzAprRover;
    43   ColumnVector            _neuEccRover;
    44   std::string             _recNameRover;
    45   std::string             _antNameRover;
    46   std::string             _antexFileName;
    47   std::string             _blqFileName;
    48   double                  _sigmaC1;
    49   double                  _sigmaL1;
    50   double                  _sigmaGIM;
    51   double                  _maxResC1;
    52   double                  _maxResL1;
    53   double                  _maxResGIM;
    54   bool                    _eleWgtCode;
    55   bool                    _eleWgtPhase;
    56   double                  _minEle;
    57   int                     _minObs;
    58   ColumnVector            _aprSigCrd;
    59   double                  _aprSigClk;
    60   double                  _aprSigClkOff;
    61   double                  _aprSigTrp;
    62   double                  _aprSigIon;
    63   double                  _aprSigAmb;
    64   double                  _aprSigCodeBias;
    65   double                  _aprSigPhaseBias;
    66   ColumnVector            _noiseCrd;
    67   double                  _noiseTrp;
    68   double                  _noiseIon;
    69   double                  _noiseCodeBias;
    70   double                  _noisePhaseBias;
    71   int                     _nmeaPort;
    72   std::string             _signalPriorities;
    73   double                  _seedingTime;
    74   std::vector<t_lc::type> _LCsGPS;
    75   std::vector<t_lc::type> _LCsGLONASS;
    76   std::vector<t_lc::type> _LCsGalileo;
    77   std::vector<t_lc::type> _LCsBDS;
    78   std::vector<char>       _frqBandsGPS;
    79   std::vector<char>       _frqBandsGLONASS;
    80   std::vector<char>       _frqBandsGalileo;
    81   std::vector<char>       _frqBandsBDS;
    82   bool                    _pseudoObsIono;
    83   bool                    _refSatRequired;
     62  iono_type                     _ionoModelType;
     63  bool                          _realTime;
     64  std::string                   _crdFile;
     65  std::string                   _corrMount;
     66  std::string                   _biasMount;
     67  std::string                   _ionoMount;
     68  bool                          _isAPC;
     69  std::string                   _rinexObs;
     70  std::string                   _rinexNav;
     71  std::string                   _corrFile;
     72  std::string                   _biasFile;
     73  std::string                   _ionoFile;
     74  double                        _corrWaitTime;
     75  std::string                   _roverName;
     76  ColumnVector                  _xyzAprRover;
     77  ColumnVector                  _neuEccRover;
     78  std::string                   _recNameRover;
     79  std::string                   _antNameRover;
     80  std::string                   _antexFileName;
     81  std::string                   _blqFileName;
     82  double                        _sigmaC1;
     83  double                        _sigmaL1;
     84  double                        _sigmaGIM;
     85  double                        _maxResC1;
     86  double                        _maxResL1;
     87  double                        _maxResGIM;
     88  bool                          _eleWgtCode;
     89  bool                          _eleWgtPhase;
     90  double                        _minEle;
     91  int                           _minObs;
     92  ColumnVector                  _aprSigCrd;
     93  double                        _aprSigClk;
     94  double                        _aprSigTrp;
     95  double                        _aprSigIon;
     96  double                        _aprSigAmb;
     97  double                        _aprSigCodeBias;
     98  ColumnVector                  _noiseCrd;
     99  double                        _noiseTrp;
     100  int                           _nmeaPort;
     101  double                        _seedingTime;
     102  std::vector<t_lc>             _LCsGPS;
     103  std::vector<t_lc>             _LCsGLONASS;
     104  std::vector<t_lc>             _LCsGalileo;
     105  std::vector<t_lc>             _LCsBDS;
     106  bool                          _pseudoObsIono;
     107  bool                          _refSatRequired;
     108  ArOptions                     _ar;
     109  e_logMode                     _logMode;
     110private: 
     111  std::map<char, SysTrkModes>   _trkModesMap;
    84112};
    85113
  • trunk/BNC/src/pppRun.cpp

    r10763 r10791  
    133133    _rnxNavFile = 0;
    134134    _corrFile   = 0;
     135    _biasFile   = 0;
    135136    _ionoFile   = 0;
    136137    _speed      = settings.value("PPP/mapSpeedSlider").toInt();
     
    274275  QMutexLocker locker(&_mutex);
    275276
     277  //// beg test
     278  // if (obsList.size() > 0) {
     279  //   const double sampling = 5.0;
     280  //   const bncTime& tt = obsList[0]._time;
     281  //   double mod = remainder(tt.gpssec(), sampling);
     282  //   if (fabs(mod) > 0.05) {
     283  //     return;
     284  //   }
     285  // }
     286  //// end test
     287
    276288  if (string(staID.data()) != _opt->_roverName) {
    277289    return;
     
    432444      return;
    433445    }
    434     if ( _opt->_ionoMount.empty() &&
    435         !_opt->_corrMount.empty() && _opt->_corrMount != vTec._staID) {
    436       return;
    437     }
    438     if (!_opt->_ionoMount.empty() && _opt->_ionoMount != vTec._staID) {
    439       return;
     446    if      (!_opt->_ionoMount.empty()) {
     447      if (_opt->_ionoMount != vTec._staID) {
     448        return;
     449      }
     450    }
     451    else if (!_opt->_corrMount.empty()) {
     452      if (_opt->_corrMount != vTec._staID) {
     453        return;
     454      }
    440455    }
    441456  }
     
    499514
    500515  if (_opt->_realTime) {
    501     if (_opt->_corrMount.empty() || _opt->_corrMount != codeBiases[0]._staID) {
     516    if (_opt->_corrMount.empty() && _opt->_biasMount.empty()) {
    502517      return;
     518    }
     519    if      (!_opt->_biasMount.empty()) {
     520      if (_opt->_biasMount != codeBiases[0]._staID) {
     521        return;
     522      }
     523    }
     524    else if (!_opt->_corrMount.empty()) {
     525      if (_opt->_corrMount != codeBiases[0]._staID) {
     526        return;
     527      }
    503528    }
    504529  }
     
    523548
    524549  if (_opt->_realTime) {
    525     if (_opt->_corrMount.empty() || _opt->_corrMount != phaseBiases[0]._staID) {
     550    if (_opt->_corrMount.empty() && _opt->_biasMount.empty()) {
    526551      return;
     552    }
     553    if      (!_opt->_biasMount.empty()) {
     554      if (_opt->_biasMount != phaseBiases[0]._staID) {
     555        return;
     556      }
     557    }
     558    else if (!_opt->_corrMount.empty()) {
     559      if (_opt->_corrMount != phaseBiases[0]._staID) {
     560        return;
     561      }
    527562    }
    528563  }
     
    563598  if (!_opt->_corrFile.empty()) {
    564599    _corrFile = new t_corrFile(QString(_opt->_corrFile.c_str()));
     600    connect(_corrFile, SIGNAL(newOrbCorrections(QList<t_orbCorr>)), this, SLOT(slotNewOrbCorrections(QList<t_orbCorr>)));
     601    connect(_corrFile, SIGNAL(newClkCorrections(QList<t_clkCorr>)), this, SLOT(slotNewClkCorrections(QList<t_clkCorr>)));
     602    if (_opt->_biasFile.empty()) {
     603      connect(_corrFile, SIGNAL(newCodeBiases(QList<t_satCodeBias>)), this, SLOT(slotNewCodeBiases(QList<t_satCodeBias>)));
     604      connect(_corrFile, SIGNAL(newPhaseBiases(QList<t_satPhaseBias>)), this, SLOT(slotNewPhaseBiases(QList<t_satPhaseBias>)));
     605    }
    565606    if (_opt->_ionoFile.empty()) {
    566607      connect(_corrFile, SIGNAL(newTec(t_vTec)), this, SLOT(slotNewTec(t_vTec)));
    567608    }
    568     connect(_corrFile, SIGNAL(newOrbCorrections(QList<t_orbCorr>)), this, SLOT(slotNewOrbCorrections(QList<t_orbCorr>)));
    569     connect(_corrFile, SIGNAL(newClkCorrections(QList<t_clkCorr>)), this, SLOT(slotNewClkCorrections(QList<t_clkCorr>)));
    570     connect(_corrFile, SIGNAL(newCodeBiases(QList<t_satCodeBias>)), this, SLOT(slotNewCodeBiases(QList<t_satCodeBias>)));
    571     connect(_corrFile, SIGNAL(newPhaseBiases(QList<t_satPhaseBias>)), this, SLOT(slotNewPhaseBiases(QList<t_satPhaseBias>)));
     609  }
     610
     611  if (!_opt->_biasFile.empty()) {
     612    _biasFile = new t_corrFile(QString(_opt->_biasFile.c_str()));
     613    connect(_biasFile, SIGNAL(newCodeBiases(QList<t_satCodeBias>)), this, SLOT(slotNewCodeBiases(QList<t_satCodeBias>)));
     614    connect(_biasFile, SIGNAL(newPhaseBiases(QList<t_satPhaseBias>)), this, SLOT(slotNewPhaseBiases(QList<t_satPhaseBias>)));
    572615  }
    573616
     
    591634    // Get Corrections
    592635    // ---------------
    593     if (_corrFile) {
    594       try {
    595         _corrFile->syncRead(epo->tt);
    596       }
    597       catch (const char* msg) {
    598         emit newMessage(QByteArray(msg), true);
    599         break;
    600       }
    601       catch (const string& msg) {
    602         emit newMessage(QByteArray(msg.c_str()), true);
    603         break;
    604       }
    605       catch (...) {
    606         emit newMessage("unknown exceptions in corrFile", true);
    607         break;
    608       }
    609     }
    610 
    611     // Get Additional VTEC Informations
    612     // --------------------------------
    613     if (_ionoFile) {
    614       try {
    615         _ionoFile->syncRead(epo->tt);
    616       }
    617       catch (const char* msg) {
    618         emit newMessage(QByteArray(msg), true);
    619         break;
    620       }
    621       catch (const string& msg) {
    622         emit newMessage(QByteArray(msg.c_str()), true);
    623         break;
    624       }
    625       catch (...) {
    626         emit newMessage("unknown exceptions in ionoFile", true);
    627         break;
     636    for (t_corrFile* file : {_corrFile, _biasFile, _ionoFile}) {
     637      if (file) {
     638        try {
     639          file->syncRead(epo->tt);
     640        }
     641        catch (const char* msg) {
     642          emit newMessage(QByteArray(msg), true);
     643          break;
     644        }
     645        catch (const string& msg) {
     646          emit newMessage(QByteArray(msg.c_str()), true);
     647          break;
     648        }
     649        catch (...) {
     650          emit newMessage("unknown exceptions in file " + file->name().toLatin1(), true);
     651          break;
     652        }
    628653      }
    629654    }
  • trunk/BNC/src/pppRun.h

    r9599 r10791  
    7171  t_rnxNavFile*          _rnxNavFile;
    7272  t_corrFile*            _corrFile;
     73  t_corrFile*            _biasFile;
    7374  t_corrFile*            _ionoFile;
    7475  int                    _speed;
  • trunk/BNC/src/pppWidgets.cpp

    r10638 r10791  
    6565  _rinexNav     = new qtFileChooser(); _rinexNav    ->setObjectName("PPP/rinexNav");     _widgets << _rinexNav;
    6666  _corrMount    = new QLineEdit();     _corrMount   ->setObjectName("PPP/corrMount");    _widgets << _corrMount;
     67  _biasMount    = new QLineEdit();     _biasMount   ->setObjectName("PPP/biasMount");    _widgets << _biasMount;
    6768  _ionoMount    = new QLineEdit();     _ionoMount   ->setObjectName("PPP/ionoMount");    _widgets << _ionoMount;
    6869  _corrFile     = new qtFileChooser(); _corrFile    ->setObjectName("PPP/corrFile");     _widgets << _corrFile;
     70  _biasFile     = new qtFileChooser(); _biasFile    ->setObjectName("PPP/biasFile");     _widgets << _biasFile;
    6971  _ionoFile     = new qtFileChooser(); _ionoFile    ->setObjectName("PPP/ionoFile");     _widgets << _ionoFile;
    7072  _crdFile      = new qtFileChooser(); _crdFile     ->setObjectName("PPP/crdFile");      _widgets << _crdFile;
     
    7274  _blqFile      = new qtFileChooser(); _blqFile     ->setObjectName("PPP/blqFile");      _widgets << _blqFile;
    7375  _logPath      = new QLineEdit();     _logPath     ->setObjectName("PPP/logPath");      _widgets << _logPath;
     76  _logMode      = new QComboBox();     _logMode     ->setObjectName("PPP/logMode");      _widgets << _logMode;
    7477  _nmeaPath     = new QLineEdit();     _nmeaPath    ->setObjectName("PPP/nmeaPath");     _widgets << _nmeaPath;
    7578  _snxtroPath   = new QLineEdit();     _snxtroPath  ->setObjectName("PPP/snxtroPath");   _widgets << _snxtroPath;
    76   _snxtroSampl  = new QComboBox();      _snxtroSampl->setObjectName("PPP/snxtroSampl");  _widgets << _snxtroSampl;
     79  _snxtroSampl  = new QComboBox();     _snxtroSampl ->setObjectName("PPP/snxtroSampl");  _widgets << _snxtroSampl;
    7780  _snxtroIntr   = new QComboBox();     _snxtroIntr  ->setObjectName("PPP/snxtroIntr");   _widgets << _snxtroIntr;
    7881  _snxtroAc     = new QLineEdit();     _snxtroAc    ->setObjectName("PPP/snxtroAc");     _widgets << _snxtroAc;
    7982  _snxtroSolId  = new QLineEdit();     _snxtroSolId ->setObjectName("PPP/snxtroSolId");  _widgets << _snxtroSolId;
    8083  _snxtroSolType= new QLineEdit();     _snxtroSolType->setObjectName("PPP/snxtroSolType");_widgets << _snxtroSolType;
    81   _snxtroCampId = new QLineEdit();     _snxtroCampId ->setObjectName("PPP/snxtroCampId");  _widgets << _snxtroCampId;
     84  _snxtroCampId = new QLineEdit();     _snxtroCampId ->setObjectName("PPP/snxtroCampId");_widgets << _snxtroCampId;
    8285  _staTable     = new QTableWidget();  _staTable    ->setObjectName("PPP/staTable");     _widgets << _staTable;
    8386  _lcGPS        = new QComboBox();     _lcGPS       ->setObjectName("PPP/lcGPS");        _widgets << _lcGPS;
     
    99102  _corrWaitTime = new QSpinBox();      _corrWaitTime->setObjectName("PPP/corrWaitTime"); _widgets << _corrWaitTime;
    100103
     104  _arGPS        = new QCheckBox();     _arGPS       ->setObjectName("PPP/arGPS");        _widgets << _arGPS;
     105  _arGalileo    = new QCheckBox();     _arGalileo   ->setObjectName("PPP/arGalileo");    _widgets << _arGalileo;
     106  _arBDS        = new QCheckBox();     _arBDS       ->setObjectName("PPP/arBDS");        _widgets << _arBDS;
     107  _arMinNumEpo  = new QSpinBox();      _arMinNumEpo ->setObjectName("PPP/arMinNumEpo");  _widgets << _arMinNumEpo;
     108  _arMinNumSat  = new QSpinBox();      _arMinNumSat ->setObjectName("PPP/arMinNumSat");  _widgets << _arMinNumSat;
     109  _arUseYaw     = new QCheckBox();     _arUseYaw    ->setObjectName("PPP/arUseYaw");     _widgets << _arUseYaw;
     110  _arMaxFrac    = new QLineEdit();     _arMaxFrac   ->setObjectName("PPP/arMaxFrac");    _widgets << _arMaxFrac;
     111  _arMaxSig     = new QLineEdit();     _arMaxSig    ->setObjectName("PPP/arMaxSig");     _widgets << _arMaxSig;
     112
    101113  _addStaButton = new QPushButton("Add Station");    _widgets << _addStaButton;
    102114  _delStaButton = new QPushButton("Delete Station"); _widgets << _delStaButton;
     
    116128  connect(_dataSource, SIGNAL(currentIndexChanged(const QString&)), this, SLOT(slotEnableWidgets()));
    117129  connect(_constraints, SIGNAL(currentIndexChanged(const QString&)), this, SLOT(slotEnableWidgets()));
     130  connect(_arGPS, SIGNAL(stateChanged(int)),  this, SLOT(slotEnableWidgets()));
     131  connect(_arGalileo, SIGNAL(stateChanged(int)),  this, SLOT(slotEnableWidgets()));
     132  connect(_arBDS, SIGNAL(stateChanged(int)),  this, SLOT(slotEnableWidgets()));
    118133  connect(_snxtroPath, SIGNAL(textChanged(const QString &)), this, SLOT(slotPPPTextChanged()));
    119134  connect(_snxtroAc, SIGNAL(textChanged(const QString &)), this, SLOT(slotPPPTextChanged()));
     
    122137  connect(_snxtroCampId, SIGNAL(textChanged(const QString &)), this, SLOT(slotPPPTextChanged()));
    123138
     139  _logMode->setEditable(false);
     140  _logMode->addItems(QString("normal,debug,all").split(","));
     141 
    124142  slotEnableWidgets();
    125143
    126   _lcGPS->setEditable(false);
    127 #ifdef USE_PPP_SSR_I
    128   _lcGPS->addItems(QString("P3,P3&L3").split(","));
    129 #else
    130   _lcGPS->addItems(QString("Pi&Li,Pi,P1&L1,P1,P3&L3,P3,L3,no").split(","));
    131 #endif
     144  _lcGPS->setEditable(true);
     145  _lcGPS->addItems(QString("Pi&Li,Pi,P1&L1,P1,P3&L3,P3,L3,no,P125&L125").split(","));
    132146
    133147  _lcGLONASS->setEditable(false);
    134 #ifdef USE_PPP_SSR_I
    135    _lcGLONASS->addItems(QString("no,P3,L3,P3&L3").split(","));
    136 #else
    137148  _lcGLONASS->addItems(QString("Pi&Li,Pi,P1&L1,P1,P3&L3,P3,L3,no").split(","));
    138 #endif
    139 
    140   _lcGalileo->setEditable(false);
    141 #ifdef USE_PPP_SSR_I
    142   _lcGalileo->addItems(QString("no,P3,L3,P3&L3").split(","));
    143 #else
    144   _lcGalileo->addItems(QString("Pi&Li,Pi,P1&L1,P1,P3&L3,P3,L3,no").split(","));
    145 #endif
    146 
    147   _lcBDS->setEditable(false);
    148  #ifdef USE_PPP_SSR_I
    149   _lcBDS->addItems(QString("no,P3,L3,P3&L3").split(","));
    150 #else
    151   _lcBDS->addItems(QString("Pi&Li,Pi,P1&L1,P1,P3&L3,P3,L3,no").split(","));
    152 #endif
    153 
    154 #ifdef USE_PPP
     149
     150  _lcGalileo->setEditable(true);
     151  _lcGalileo->addItems(QString("Pi&Li,Pi,P1&L1,P1,P3&L3,P3,L3,no,P1576&L1576").split(","));
     152
     153  _lcBDS->setEditable(true);
     154  _lcBDS->addItems(QString("Pi&Li,Pi,P1&L1,P1,P3&L3,P3,L3,no,P1576&L1576").split(","));
     155
    155156  _constraints->setEditable(false);
    156157  _constraints->addItems(QString("no,Ionosphere: pseudo-obs").split(","));
    157 #endif
     158
    158159  _snxtroSampl->setEditable(false);
    159160  _snxtroSampl->addItems(QString("1 sec,5 sec,10 sec,30 sec,60 sec,300 sec").split(","));
     
    172173  _minEle->setSuffix(" deg");
    173174
     175  _arMinNumEpo->setMinimum(5);
     176  _arMinNumEpo->setMaximum(60);
     177  _arMinNumEpo->setSingleStep(5);
     178
     179  _arMinNumSat->setMinimum(4);
     180  _arMinNumSat->setMaximum(8);
     181  _arMinNumSat->setSingleStep(1);
     182 
    174183  _corrWaitTime->setMinimum(0);
    175184  _corrWaitTime->setMaximum(20);
     
    210219  // WhatsThis, PPP (3)
    211220  // ------------------
    212 #ifdef USE_PPP
    213221  _staTable->setWhatsThis(tr("<p>Specify values for Sigma and white Noise of the Stations North, East and Height coordinate components in meters. Specify also a Sigma in meters for a priori model based Tropospheric delays and a Sigma in meters per second for the delay's Noise. You can also specify a 'NMEA Port' to output coordinates in NMEA format through an IP port of your local host. Specify a list of signal priorities for the observations that shall be used for PPP.</p>"
    214222                             "<p>'Sigma' is meant to describe the uncertainty of a single coordinate or tropospheric delay estimated for one epoch. 'Noise' is meant to describe the variation of estimates from epoch to epoch.</p><p><ul><li>A Sigma of 100.0 meters may be an appropriate choice e.g. for the initial N/E/H coordinates. However, this value may be significantly smaller (i.e. 0.01) for stations with well-known a priori coordinates.</li><li>A Noise of 100.0 meters for the estimated N/E/H coordinates may also be appropriate considering the potential movement of a rover position.</li><li>A value of 0.1 meters may be an appropriate Sigma for the a priori model based Tropospheric delay estimation.</li><li>Specify a Noise to describe the expected variation of the tropospheric effect over time. Supposing 1Hz observation data, specifying a value of 3e-6 would mean that the tropospheric effect may vary 3600 * 3e-6 = 0.01 meters per hour.</li></ul></p>"
     
    222230                             "<p>But it is recommended to specify it in more detail per individual station, e.g.:</p> <ul>  <li>'G:12&W R:12&P E:1&C E:5&Q C:26&I'</li></ul> "
    223231                             "<p> <i>[key: PPP/staTable]</i></p>"));
    224 #else
    225   _staTable->setWhatsThis(tr("<p>Specify values for Sigma and white Noise of the Stations North, East and Height coordinate components in meters. Specify also a Sigma in meters for a priori model based Tropospheric delays and a Sigma in meters per second for the delay's Noise. You can also specify a 'NMEA Port' to output coordinates in NMEA format through an IP port of your local host.<i>[key: PPP/staTable]</i></p>"));
    226 #endif
     232
    227233  // WhatsThis, PPP (4)
    228234  // ------------------
     
    240246////////////////////////////////////////////////////////////////////////////
    241247t_pppWidgets::~t_pppWidgets() {
    242   delete _dataSource;
    243   delete _rinexObs;
    244   delete _rinexNav;
    245   delete _corrMount;
    246   delete _ionoMount;
    247   delete _corrFile;
    248   delete _ionoFile;
    249   delete _crdFile;
    250   delete _antexFile;
    251   delete _blqFile;
    252   delete _logPath;
    253   delete _nmeaPath;
    254   delete _snxtroPath;
    255   delete _snxtroSampl;
    256   delete _snxtroIntr;
    257   delete _snxtroAc;
    258   delete _snxtroSolId;
    259   delete _snxtroSolType;
    260   delete _snxtroCampId;
    261   for (int iRow = _staTable->rowCount()-1; iRow >=0; iRow--) {
    262     _staTable->removeRow(iRow);
    263   }
    264   delete _staTable;
    265   delete _lcGPS;
    266   delete _lcGLONASS;
    267   delete _lcGalileo;
    268   delete _lcBDS;
    269   delete _constraints;
    270   delete _sigmaC1;
    271   delete _sigmaL1;
    272   delete _sigmaGIM;
    273   delete _maxResC1;
    274   delete _maxResL1;
    275   delete _maxResGIM;
    276   delete _minObs;
    277   delete _minEle;
    278   delete _eleWgtCode;
    279   delete _eleWgtPhase;
    280   delete _seedingTime;
    281   delete _corrWaitTime;
    282   delete _addStaButton;
    283   delete _delStaButton;
    284   delete _plotCoordinates;
    285   delete _mapWinButton;
    286   delete _audioResponse;
    287   delete _mapWinDotSize;
    288   delete _mapWinDotColor;
    289   delete _mapSpeedSlider;
    290248}
    291249
     
    296254  bncSettings settings;
    297255
    298   // ComboBoxes
    299   // ----------
    300   int ii = _dataSource->findText(settings.value(_dataSource->objectName()).toString());
    301   if (ii != -1) {
    302     _dataSource->setCurrentIndex(ii);
    303   }
    304   ii = _lcGPS->findText(settings.value(_lcGPS->objectName()).toString());
    305   if (ii != -1) {
    306     _lcGPS->setCurrentIndex(ii);
    307   }
    308   ii = _lcGLONASS->findText(settings.value(_lcGLONASS->objectName()).toString());
    309   if (ii != -1) {
    310     _lcGLONASS->setCurrentIndex(ii);
    311   }
    312   ii = _lcGalileo->findText(settings.value(_lcGalileo->objectName()).toString());
    313   if (ii != -1) {
    314     _lcGalileo->setCurrentIndex(ii);
    315   }
    316   ii = _lcBDS->findText(settings.value(_lcBDS->objectName()).toString());
    317   if (ii != -1) {
    318     _lcBDS->setCurrentIndex(ii);
    319   }
    320   ii = _constraints->findText(settings.value(_constraints->objectName()).toString());
    321   if (ii != -1) {
    322     _constraints->setCurrentIndex(ii);
    323   }
    324   ii = _snxtroIntr->findText(settings.value(_snxtroIntr->objectName()).toString());
    325   if (ii != -1) {
    326     _snxtroIntr->setCurrentIndex(ii);
    327   }
    328 
    329   // FileChoosers
    330   // ------------
    331   _rinexObs ->setFileName(settings.value(_rinexObs ->objectName()).toString());
    332   _rinexNav ->setFileName(settings.value(_rinexNav ->objectName()).toString());
    333   _corrFile ->setFileName(settings.value(_corrFile ->objectName()).toString());
    334   _ionoFile ->setFileName(settings.value(_ionoFile ->objectName()).toString());
    335   _crdFile  ->setFileName(settings.value(_crdFile  ->objectName()).toString());
    336   _antexFile->setFileName(settings.value(_antexFile->objectName()).toString());
    337   _blqFile->setFileName(settings.value(_blqFile->objectName()).toString());
    338 
    339   // LineEdits
    340   // ---------
    341   _corrMount    ->setText(settings.value(_corrMount     ->objectName()).toString());
    342   _ionoMount    ->setText(settings.value(_ionoMount     ->objectName()).toString());
    343   _logPath      ->setText(settings.value(_logPath       ->objectName()).toString());
    344   _nmeaPath     ->setText(settings.value(_nmeaPath      ->objectName()).toString());
    345   _snxtroPath   ->setText(settings.value(_snxtroPath    ->objectName()).toString());
    346   _snxtroAc     ->setText(settings.value(_snxtroAc      ->objectName()).toString());
    347   _snxtroSolId  ->setText(settings.value(_snxtroSolId   ->objectName()).toString());
    348   _snxtroSolType->setText(settings.value(_snxtroSolType ->objectName()).toString());
    349   _snxtroCampId ->setText(settings.value(_snxtroCampId  ->objectName()).toString());
    350 
    351   if (!settings.value(_sigmaC1->objectName()).toString().isEmpty()) {
    352     _sigmaC1->setText(settings.value(_sigmaC1->objectName()).toString());
    353   }
    354   else {
    355     _sigmaC1->setText("1.0");
    356   }
    357 
    358   if (!settings.value(_sigmaL1->objectName()).toString().isEmpty()) {
    359     _sigmaL1->setText(settings.value(_sigmaL1->objectName()).toString());
    360   }
    361   else {
    362     _sigmaL1->setText("0.01");
    363   }
    364 
    365   if (!settings.value(_sigmaGIM->objectName()).toString().isEmpty()) {
    366     _sigmaGIM->setText(settings.value(_sigmaGIM->objectName()).toString());
    367   }
    368   else {
    369     _sigmaGIM->setText("1.0");
    370   }
    371 
    372   if (!settings.value(_maxResC1->objectName()).toString().isEmpty()) {
    373     _maxResC1->setText(settings.value(_maxResC1->objectName()).toString());
    374   }
    375   else {
    376     _maxResC1->setText("3.0");
    377   }
    378 
    379   if (!settings.value(_maxResL1->objectName()).toString().isEmpty()) {
    380     _maxResL1->setText(settings.value(_maxResL1->objectName()).toString());
    381   }
    382   else {
    383     _maxResL1->setText("0.03");
    384   }
    385 
    386   if (!settings.value(_maxResGIM->objectName()).toString().isEmpty()) {
    387     _maxResGIM->setText(settings.value(_maxResGIM->objectName()).toString());
    388   }
    389   else {
    390     _maxResGIM->setText("3.0");
    391   }
    392 
    393 
    394   if (!settings.value(_seedingTime->objectName()).toString().isEmpty()) {
    395     _seedingTime->setText(settings.value(_seedingTime->objectName()).toString());
    396   }
    397   else {
    398     _seedingTime->setText("0");
    399   }
    400 
    401   // CheckBoxes
    402   // ----------
    403   _eleWgtCode ->setCheckState(Qt::CheckState(settings.value(_eleWgtCode ->objectName()).toInt()));
    404   _eleWgtPhase->setCheckState(Qt::CheckState(settings.value(_eleWgtPhase->objectName()).toInt()));
    405 
    406   // SpinBoxex
    407   // ---------
    408   _minObs->setValue(settings.value(_minObs->objectName()).toInt());
    409   _minEle->setValue(settings.value(_minEle->objectName()).toInt());
    410   _corrWaitTime->setValue(settings.value(_corrWaitTime->objectName()).toInt());
    411 
    412 
    413   ii = _snxtroSampl->findText(settings.value(_snxtroSampl->objectName()).toString());
    414   if (ii != -1) {
    415     _snxtroSampl->setCurrentIndex(ii);
    416   }
    417 
     256  auto setWidgetValue = [settings](QWidget* widget, QString defValue = QString()) {
     257    if      (auto* obj = qobject_cast<QLineEdit*>(widget)) {
     258      QString text = settings.value(obj->objectName()).toString();
     259      if (text.isEmpty() && !defValue.isEmpty()) {
     260        text = defValue;
     261      }
     262      obj->setText(text);
     263    }
     264    else if (auto* obj = qobject_cast<QComboBox*>(widget)) {
     265      QString text = settings.value(obj->objectName()).toString();
     266      int ii = obj->findText(text);
     267      if (ii != -1) {
     268        obj->setCurrentIndex(ii);
     269      }
     270      else if (obj->isEditable()) {
     271        obj->insertItem(0, text);
     272        obj->setCurrentIndex(0);
     273      }
     274    }
     275    else if (auto* obj = qobject_cast<qtFileChooser*>(widget)) {
     276      obj->setFileName(settings.value(obj->objectName()).toString());
     277    }
     278    else if (auto* obj = qobject_cast<QCheckBox*>(widget)) {
     279      obj->setCheckState(Qt::CheckState(settings.value(obj->objectName()).toInt()));
     280    }
     281    else if (auto* obj = qobject_cast<QSpinBox*>(widget)) {
     282      obj->setValue(settings.value(obj->objectName()).toInt());
     283    }
     284    else if (auto* obj = qobject_cast<QSlider*>(widget)) {
     285      int value = settings.value(obj->objectName()).toInt();
     286      if (value == 0) value = obj->maximum();
     287      obj->setSliderPosition(value);
     288    }
     289  };
     290 
     291  QListIterator<QWidget*> iw(_widgets);
     292  while (iw.hasNext()) {
     293    setWidgetValue(iw.next());
     294  }
     295
     296  // Set default values for some widgets
     297  // -----------------------------------
     298  setWidgetValue(_sigmaC1,     "1.0");
     299  setWidgetValue(_sigmaL1,     "0.01");
     300  setWidgetValue(_sigmaGIM,    "1.0");
     301  setWidgetValue(_maxResC1,    "3.0");
     302  setWidgetValue(_maxResL1,    "0.03");
     303  setWidgetValue(_maxResGIM,   "3.0");
     304  setWidgetValue(_seedingTime, "0");
     305   
    418306  // Table with stations
    419307  // -------------------
     
    431319    }
    432320  }
    433 
    434   // Plots and Maps
    435   // --------------
    436   _plotCoordinates ->setText(settings.value(_plotCoordinates->objectName()).toString());
    437   _audioResponse   ->setText(settings.value(_audioResponse->objectName()).toString());
    438   _mapWinDotSize   ->setText(settings.value(_mapWinDotSize->objectName()).toString());
    439 
    440   ii = _mapWinDotColor->findText(settings.value(_mapWinDotColor->objectName()).toString());
    441   if (ii != -1) {
    442     _mapWinDotColor->setCurrentIndex(ii);
    443   }
    444 
    445   int speed = settings.value(_mapSpeedSlider->objectName()).toInt();
    446   if (speed == 0) speed = _mapSpeedSlider->maximum();
    447   _mapSpeedSlider->setSliderPosition(speed);
    448321}
    449322
     
    454327  bncSettings settings;
    455328
    456   settings.setValue(_dataSource  ->objectName(), _dataSource  ->currentText());
    457   settings.setValue(_rinexObs    ->objectName(), _rinexObs    ->fileName());
    458   settings.setValue(_rinexNav    ->objectName(), _rinexNav    ->fileName());
    459   settings.setValue(_corrMount   ->objectName(), _corrMount   ->text());
    460   settings.setValue(_ionoMount   ->objectName(), _ionoMount   ->text());
    461   settings.setValue(_corrFile    ->objectName(), _corrFile    ->fileName());
    462   settings.setValue(_ionoFile    ->objectName(), _ionoFile    ->fileName());
    463   settings.setValue(_crdFile     ->objectName(), _crdFile     ->fileName());
    464   settings.setValue(_antexFile   ->objectName(), _antexFile   ->fileName());
    465   settings.setValue(_blqFile     ->objectName(), _blqFile   ->fileName());
    466   settings.setValue(_logPath     ->objectName(), _logPath     ->text());
    467   settings.setValue(_nmeaPath    ->objectName(), _nmeaPath    ->text());
    468   settings.setValue(_snxtroPath  ->objectName(), _snxtroPath  ->text());
    469   settings.setValue(_snxtroSampl ->objectName(), _snxtroSampl ->currentText());
    470   settings.setValue(_snxtroIntr  ->objectName(), _snxtroIntr  ->currentText());
    471   settings.setValue(_snxtroAc    ->objectName(), _snxtroAc    ->text());
    472   settings.setValue(_snxtroSolId  ->objectName(), _snxtroSolId   ->text());
    473   settings.setValue(_snxtroSolType->objectName(), _snxtroSolType ->text());
    474   settings.setValue(_snxtroCampId ->objectName(), _snxtroCampId  ->text());
    475   settings.setValue(_lcGPS       ->objectName(), _lcGPS       ->currentText());
    476   settings.setValue(_lcGLONASS   ->objectName(), _lcGLONASS   ->currentText());
    477   settings.setValue(_lcGalileo   ->objectName(), _lcGalileo   ->currentText());
    478   settings.setValue(_lcBDS       ->objectName(), _lcBDS       ->currentText());
    479   settings.setValue(_constraints ->objectName(), _constraints ->currentText());
    480   settings.setValue(_sigmaC1     ->objectName(), _sigmaC1     ->text());
    481   settings.setValue(_sigmaL1     ->objectName(), _sigmaL1     ->text());
    482   settings.setValue(_sigmaGIM    ->objectName(), _sigmaGIM    ->text());
    483   settings.setValue(_corrWaitTime->objectName(), _corrWaitTime->value());
    484   settings.setValue(_maxResC1    ->objectName(), _maxResC1    ->text());
    485   settings.setValue(_maxResL1    ->objectName(), _maxResL1    ->text());
    486   settings.setValue(_maxResGIM   ->objectName(), _maxResGIM   ->text());
    487   settings.setValue(_seedingTime ->objectName(), _seedingTime ->text());
    488   settings.setValue(_minObs      ->objectName(), _minObs      ->value());
    489   settings.setValue(_minEle      ->objectName(), _minEle      ->value());
    490   settings.setValue(_eleWgtCode  ->objectName(), _eleWgtCode  ->checkState());
    491   settings.setValue(_eleWgtPhase ->objectName(), _eleWgtPhase ->checkState());
     329  auto storeWidgetValue = [&settings](QWidget* widget) {
     330    if      (auto* obj = qobject_cast<QLineEdit*>(widget)) {
     331      settings.setValue(obj->objectName(), obj->text());
     332    }
     333    else if (auto* obj = qobject_cast<QComboBox*>(widget)) {
     334      settings.setValue(obj->objectName(), obj->currentText());
     335    }
     336    else if (auto* obj = qobject_cast<qtFileChooser*>(widget)) {
     337      settings.setValue(obj->objectName(), obj->fileName());
     338    }
     339    else if (auto* obj = qobject_cast<QCheckBox*>(widget)) {
     340      settings.setValue(obj->objectName(), obj->checkState());
     341    }
     342    else if (auto* obj = qobject_cast<QSpinBox*>(widget)) {
     343      settings.setValue(obj->objectName(), obj->value());
     344    }
     345    else if (auto* obj = qobject_cast<QSlider*>(widget)) {
     346      settings.setValue(obj->objectName(), obj->value());
     347    }
     348  };
     349
     350  QListIterator<QWidget*> it(_widgets);
     351  while (it.hasNext()) {
     352    storeWidgetValue(it.next());
     353  }
    492354
    493355  QStringList staList;
     
    504366  }
    505367  settings.setValue(_staTable->objectName(), staList);
    506 
    507   settings.setValue(_plotCoordinates ->objectName(), _plotCoordinates ->text());
    508   settings.setValue(_audioResponse   ->objectName(), _audioResponse   ->text());
    509   settings.setValue(_mapWinDotSize   ->objectName(), _mapWinDotSize   ->text());
    510   settings.setValue(_mapWinDotColor  ->objectName(), _mapWinDotColor  ->currentText());
    511   settings.setValue(_mapSpeedSlider  ->objectName(), _mapSpeedSlider  ->value());
    512368}
    513369
     
    534390    _rinexNav->setEnabled(false);
    535391    _corrFile->setEnabled(false);
     392    _biasFile->setEnabled(false);
    536393    _ionoFile->setEnabled(false);
    537394  }
    538395  else if (rinexFiles) {
    539396    _corrMount    ->setEnabled(false);
     397    _biasMount    ->setEnabled(false);
    540398    _ionoMount    ->setEnabled(false);
    541399    _audioResponse->setEnabled(false);
     
    543401
    544402  if ( _snxtroPath->text() != "" && !allDisabled) {
    545     _snxtroSampl->setEnabled(true);
    546     _snxtroIntr ->setEnabled(true);
    547     _snxtroAc   ->setEnabled(true);
     403    _snxtroSampl  ->setEnabled(true);
     404    _snxtroIntr   ->setEnabled(true);
     405    _snxtroAc     ->setEnabled(true);
    548406    _snxtroSolId  ->setEnabled(true);
    549     _snxtroSolType ->setEnabled(true);
    550     _snxtroCampId  ->setEnabled(true);
     407    _snxtroSolType->setEnabled(true);
     408    _snxtroCampId ->setEnabled(true);
    551409  }
    552410  else {
    553     _snxtroSampl->setEnabled(false);
    554     _snxtroIntr ->setEnabled(false);
    555     _snxtroAc   ->setEnabled(false);
     411    _snxtroSampl  ->setEnabled(false);
     412    _snxtroIntr   ->setEnabled(false);
     413    _snxtroAc     ->setEnabled(false);
    556414    _snxtroSolId  ->setEnabled(false);
    557     _snxtroSolType ->setEnabled(false);
    558     _snxtroCampId  ->setEnabled(false);
     415    _snxtroSolType->setEnabled(false);
     416    _snxtroCampId ->setEnabled(false);
    559417  }
    560418
     
    568426  }
    569427
     428  bool ar = (_arGPS->checkState()     == Qt::Checked ||
     429             _arGalileo->checkState() == Qt::Checked ||
     430             _arBDS->checkState()     == Qt::Checked);
     431  _arMinNumEpo->setEnabled(ar);
     432  _arMinNumSat->setEnabled(ar);
     433  _arUseYaw   ->setEnabled(ar);
     434  _arMaxFrac  ->setEnabled(ar);
     435  _arMaxSig   ->setEnabled(ar);
     436 
    570437  _dataSource->setEnabled(true);
    571438
     
    629496
    630497  const static QPalette paletteWhite(QColor(255, 255, 255));
    631   const static QPalette paletteGray(QColor(230, 230, 230));
     498  const static QPalette paletteGray (QColor(230, 230, 230));
    632499
    633500  // SNX TRO file sampling
     
    635502  if (sender() == 0 || sender() == _snxtroPath) {
    636503    if ( _snxtroPath->text() != "" ) {
    637       _snxtroSampl->setEnabled(true);
    638       _snxtroIntr ->setEnabled(true);
    639       _snxtroAc   ->setEnabled(true);
     504      _snxtroSampl  ->setEnabled(true);
     505      _snxtroIntr   ->setEnabled(true);
     506      _snxtroAc     ->setEnabled(true);
    640507      _snxtroSolId  ->setEnabled(true);
    641       _snxtroSolType ->setEnabled(true);
    642       _snxtroCampId  ->setEnabled(true);
    643       _snxtroSampl->setPalette(paletteWhite);
    644       _snxtroIntr ->setPalette(paletteWhite);
    645       _snxtroAc   ->setPalette(paletteWhite);
     508      _snxtroSolType->setEnabled(true);
     509      _snxtroCampId ->setEnabled(true);
     510      _snxtroSampl  ->setPalette(paletteWhite);
     511      _snxtroIntr   ->setPalette(paletteWhite);
     512      _snxtroAc     ->setPalette(paletteWhite);
    646513      _snxtroSolId  ->setPalette(paletteWhite);
    647       _snxtroSolType ->setPalette(paletteWhite);
    648       _snxtroCampId  ->setPalette(paletteWhite);
     514      _snxtroSolType->setPalette(paletteWhite);
     515      _snxtroCampId ->setPalette(paletteWhite);
    649516    }
    650517    else {
    651     _snxtroSampl->setEnabled(false);
    652     _snxtroIntr ->setEnabled(false);
    653     _snxtroAc   ->setEnabled(false);
     518    _snxtroSampl  ->setEnabled(false);
     519    _snxtroIntr   ->setEnabled(false);
     520    _snxtroAc     ->setEnabled(false);
    654521    _snxtroSolId  ->setEnabled(false);
    655     _snxtroSolType ->setEnabled(false);
    656     _snxtroCampId  ->setEnabled(false);
    657     _snxtroSampl->setPalette(paletteGray);
    658     _snxtroIntr ->setPalette(paletteGray);
    659     _snxtroAc   ->setPalette(paletteGray);
     522    _snxtroSolType->setEnabled(false);
     523    _snxtroCampId ->setEnabled(false);
     524    _snxtroSampl  ->setPalette(paletteGray);
     525    _snxtroIntr   ->setPalette(paletteGray);
     526    _snxtroAc     ->setPalette(paletteGray);
    660527    _snxtroSolId  ->setPalette(paletteGray);
    661     _snxtroSolType ->setPalette(paletteGray);
    662     _snxtroCampId  ->setPalette(paletteGray);
    663     }
    664   }
    665 
    666 
    667 }
     528    _snxtroSolType->setPalette(paletteGray);
     529    _snxtroCampId ->setPalette(paletteGray);
     530    }
     531  }
     532
     533
     534}
  • trunk/BNC/src/pppWidgets.h

    r10251 r10791  
    3838
    3939class t_pppWidgets : public QObject {
    40  Q_OBJECT
     40  Q_OBJECT
    4141
    42  public:
     42public:
    4343  t_pppWidgets();
    4444  ~t_pppWidgets();
     
    4949  qtFileChooser* _rinexNav;
    5050  QLineEdit*     _corrMount;
     51  QLineEdit*     _biasMount;
    5152  QLineEdit*     _ionoMount;
    5253  qtFileChooser* _corrFile;
     54  qtFileChooser* _biasFile;
    5355  qtFileChooser* _ionoFile;
    5456  qtFileChooser* _crdFile;
     
    5658  qtFileChooser* _blqFile;
    5759  QLineEdit*     _logPath;
     60  QComboBox*     _logMode;
    5861  QLineEdit*     _nmeaPath;
    5962  QLineEdit*     _snxtroPath;
     
    9396  QSlider*       _mapSpeedSlider;
    9497
    95  private slots:
     98  QCheckBox*     _arGPS;
     99  QCheckBox*     _arGalileo;
     100  QCheckBox*     _arBDS;
     101  QSpinBox*      _arMinNumEpo;
     102  QSpinBox*      _arMinNumSat;
     103  QCheckBox*     _arUseYaw;
     104  QLineEdit*     _arMaxFrac;
     105  QLineEdit*     _arMaxSig;
     106
     107private slots:
    96108  void slotEnableWidgets();
    97109  void slotAddStation();
     
    99111  void slotPPPTextChanged();
    100112
    101  private:
     113private:
    102114  void readOptions();
    103115  QList <QWidget*> _widgets;
  • trunk/BNC/src/rinex/corrfile.cpp

    r10599 r10791  
    4949////////////////////////////////////////////////////////////////////////////
    5050t_corrFile::t_corrFile(QString fileName) {
     51  _name = fileName;
    5152  expandEnvVar(fileName);
    5253  _stream.open(fileName.toLatin1().data());
  • trunk/BNC/src/rinex/corrfile.h

    r7169 r10791  
    4040  void syncRead(const bncTime& tt);
    4141  const QMap<QString, unsigned int>& corrIODs() const {return _corrIODs;}
     42  const QString& name() const {return _name;}
    4243
    4344 signals:
     
    4950
    5051 private:
     52  QString                     _name;
    5153  std::ifstream               _stream;
    5254  std::string                 _lastLine;
  • trunk/BNC/src/satObs.h

    r10599 r10791  
    3131    _lockTimeIndicator = -1;
    3232  }
     33  char frqChar() const {return _rnxType2ch.length() > 0 ? _rnxType2ch[0] : '?';}
     34  char trkChar() const {return _rnxType2ch.length() > 1 ? _rnxType2ch[1] : '?';}
    3335  std::string       _rnxType2ch;
    3436  double            _code;
     
    5355    _type = 0;
    5456  }
    55   t_satObs(const t_satObs& old) { // copy constructor (deep copy)
    56     _staID = old._staID;
    57     _prn   = old._prn;
    58     _time  = old._time;
    59     _type  = old._type;
    60     for (unsigned ii = 0; ii < old._obs.size(); ii++) {
    61       _obs.push_back(new t_frqObs(*old._obs[ii]));
     57  t_satObs(const t_satObs& other) { // copy constructor (deep copy)
     58    copyFields(other);
     59  }
     60  t_satObs operator=(const t_satObs& other) {
     61    if (this != &other) {
     62      copyFields(other);
    6263    }
     64    return *this;
    6365  }
    6466  /**
     
    7375   */
    7476  inline void clear(void) {
    75     for (unsigned ii = 0; ii < _obs.size(); ii++)
     77    for (unsigned ii = 0; ii < _obs.size(); ii++) {
    7678      delete _obs[ii];
     79    }
    7780    _obs.clear();
    7881    _obs.resize(0);
     
    8891  int                    _type; // MT
    8992  std::vector<t_frqObs*> _obs;
     93
     94 private:
     95  void copyFields(const t_satObs& other) {
     96    _staID = other._staID;
     97    _prn   = other._prn;
     98    _time  = other._time;
     99    _type  = other._type;
     100    for (unsigned ii = 0; ii < other._obs.size(); ii++) {
     101      _obs.push_back(new t_frqObs(*other._obs[ii]));
     102    }
     103  }
    90104};
    91105
  • trunk/BNC/src/src.pri

    r10776 r10791  
    134134  HEADERS += PPP/pppClient.h    PPP/pppObsPool.h   PPP/pppEphPool.h   \
    135135             PPP/pppStation.h   PPP/pppFilter.h    PPP/pppParlist.h   \
    136              PPP/pppSatObs.h    PPP/pppRefSat.h
     136             PPP/pppSatObs.h    PPP/pppRefSat.h    PPP/lambda.h       \
     137                         PPP/ambres.h       
    137138  SOURCES += PPP/pppClient.cpp  PPP/pppObsPool.cpp PPP/pppEphPool.cpp \
    138139             PPP/pppStation.cpp PPP/pppFilter.cpp  PPP/pppParlist.cpp \
    139              PPP/pppSatObs.cpp
    140 }
    141 else {
    142   INCLUDEPATH += PPP_SSR_I
    143   DEFINES += USE_PPP_SSR_I
    144   HEADERS += PPP_SSR_I/pppClient.h   PPP_SSR_I/pppFilter.h   PPP_SSR_I/pppUtils.h
    145   SOURCES += PPP_SSR_I/pppClient.cpp PPP_SSR_I/pppFilter.cpp PPP_SSR_I/pppUtils.cpp
     140             PPP/pppSatObs.cpp                     PPP/lambda.cpp     \
     141                         PPP/ambres.cpp
    146142}
    147143
  • trunk/BNC/src/t_prn.cpp

    r10599 r10791  
    66
    77using namespace std;
     8
     9// Set from number
     10//////////////////////////////////////////////////////////////////////////////
     11void t_prn::set(unsigned nn) {
     12  const static unsigned maxGPS     = MAXPRN_GPS;
     13  const static unsigned maxGLONASS = MAXPRN_GPS + MAXPRN_GLONASS;
     14  const static unsigned maxGALILEO = MAXPRN_GPS + MAXPRN_GLONASS + MAXPRN_GALILEO;
     15  const static unsigned maxQZSS    = MAXPRN_GPS + MAXPRN_GLONASS + MAXPRN_GALILEO + MAXPRN_QZSS;
     16  const static unsigned maxSBAS    = MAXPRN_GPS + MAXPRN_GLONASS + MAXPRN_GALILEO + MAXPRN_QZSS + MAXPRN_SBAS;
     17  const static unsigned maxBDS     = MAXPRN_GPS + MAXPRN_GLONASS + MAXPRN_GALILEO + MAXPRN_QZSS + MAXPRN_SBAS + MAXPRN_BDS;
     18  const static unsigned maxNavIC   = MAXPRN_GPS + MAXPRN_GLONASS + MAXPRN_GALILEO + MAXPRN_QZSS + MAXPRN_SBAS + MAXPRN_BDS + MAXPRN_NavIC;
     19  _system = 'G';
     20  _number = 0;
     21  _flag   = 0;
     22  if      (nn <= maxGPS) {
     23    _system = 'G';
     24    _number = nn;
     25  }
     26  else if (nn <= maxGLONASS) {
     27    _system = 'R';
     28    _number = nn - maxGPS;
     29  }
     30  else if (nn <= maxGALILEO) {
     31    _system = 'E';
     32    _number = nn - maxGLONASS;
     33  }
     34  else if (nn <= maxQZSS) {
     35    _system = 'J';
     36    _number = nn - maxGALILEO;
     37  }
     38  else if (nn <= maxSBAS) {
     39    _system = 'S';
     40    _number = nn - maxQZSS;
     41  }
     42  else if (nn <= maxBDS) {
     43    _system = 'C';
     44    _number = nn - maxSBAS;
     45  }
     46  else if (nn <= maxNavIC) {
     47    _system = 'I';
     48    _number = nn - maxBDS;
     49  }
     50}
    851
    952//
  • trunk/BNC/src/t_prn.h

    r10619 r10791  
    1616      + MAXPRN_QZSS + MAXPRN_SBAS + MAXPRN_BDS + MAXPRN_NavIC;
    1717
    18   t_prn() :
    19       _system('G'), _number(0), _flag(0) {
    20   }
    21   t_prn(char system, int number) :
    22       _system(system), _number(number), _flag(0) {
    23   }
     18  t_prn() : _system('G'), _number(0), _flag(0) {}
     19  t_prn(char system, int number) : _system(system), _number(number), _flag(0) {}
     20  t_prn(char system, int number, int flag) : _system(system), _number(number), _flag(flag) {}
     21  ~t_prn() {}
    2422
    25   t_prn(char system, int number, int flag) :
    26       _system(system), _number(number), _flag(flag) {
    27   }
    28 
    29   ~t_prn() {
     23  bool valid() const {
     24    return _number != 0;
    3025  }
    3126
     
    4136    _flag  = flag;
    4237  }
     38
     39  void set(unsigned nn);
    4340
    4441  void setFlag(int flag) {
Note: See TracChangeset for help on using the changeset viewer.