source: ntrip/trunk/BNC/src/bncwindow.cpp @ 8621

Last change on this file since 8621 was 8621, checked in by stuerze, 7 weeks ago

minor changes

File size: 159.0 KB
Line 
1// Part of BNC, a utility for retrieving decoding and
2// converting GNSS data streams from NTRIP broadcasters.
3//
4// Copyright (C) 2007
5// German Federal Agency for Cartography and Geodesy (BKG)
6// http://www.bkg.bund.de
7// Czech Technical University Prague, Department of Geodesy
8// http://www.fsv.cvut.cz
9//
10// Email: euref-ip@bkg.bund.de
11//
12// This program is free software; you can redistribute it and/or
13// modify it under the terms of the GNU General Public License
14// as published by the Free Software Foundation, version 2.
15//
16// This program is distributed in the hope that it will be useful,
17// but WITHOUT ANY WARRANTY; without even the implied warranty of
18// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19// GNU General Public License for more details.
20//
21// You should have received a copy of the GNU General Public License
22// along with this program; if not, write to the Free Software
23// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24
25/* -------------------------------------------------------------------------
26 * BKG NTRIP Client
27 * -------------------------------------------------------------------------
28 *
29 * Class:      bncWindow
30 *
31 * Purpose:    This class implements the main application window.
32 *
33 * Author:     L. Mervart
34 *
35 * Created:    24-Dec-2005
36 *
37 * Changes:
38 *
39 * -----------------------------------------------------------------------*/
40
41#include <iostream>
42
43#include <QAction>
44#include <QApplication>
45#include <QCheckBox>
46#include <QCloseEvent>
47#include <QComboBox>
48#include <QDialog>
49#include <QFontDialog>
50#include <QGridLayout>
51#include <QHeaderView>
52#include <QLabel>
53#include <QLineEdit>
54#include <QMenu>
55#include <QMenuBar>
56#include <QMessageBox>
57#include <QPushButton>
58#include <QRadioButton>
59#include <QSpinBox>
60#include <QTableWidgetItem>
61#include <QTextEdit>
62#include <QToolBar>
63
64#include <unistd.h>
65#include "bncwindow.h"
66#include "bnccore.h"
67#include "bncgetthread.h"
68#include "bnctabledlg.h"
69#include "bncipport.h"
70#include "bncudpport.h"
71#include "bncserialport.h"
72#include "bnchlpdlg.h"
73#include "bnchtml.h"
74#include "bnctableitem.h"
75#include "bncsettings.h"
76#include "bncfigure.h"
77#include "bncfigurelate.h"
78#include "bncfigureppp.h"
79#include "bncversion.h"
80#include "bncbytescounter.h"
81#include "bncsslconfig.h"
82#include "upload/bnccustomtrafo.h"
83#include "upload/bncephuploadcaster.h"
84#include "qtfilechooser.h"
85#include "reqcdlg.h"
86#include "bncmap.h"
87#include "rinex/reqcedit.h"
88#include "rinex/reqcanalyze.h"
89#include "orbComp/sp3Comp.h"
90#ifdef QT_WEBKIT
91#  include "map/bncmapwin.h"
92#endif
93
94using namespace std;
95
96#ifdef GNSSCENTER_PLUGIN
97Q_EXPORT_PLUGIN2(gnsscenter_bnc, t_bncFactory)
98#endif
99
100// Constructor
101////////////////////////////////////////////////////////////////////////////
102bncWindow::bncWindow() {
103
104  const static QPalette paletteWhite(QColor(255, 255, 255));
105  const static QPalette paletteGray(QColor(230, 230, 230));
106
107#ifdef GNSSCENTER_PLUGIN
108  BNC_CORE->setConfFileName("");
109#endif
110
111  _caster    = 0;
112  _casterEph = 0;
113
114  _bncFigure     = new bncFigure(this);
115  _bncFigureLate = new bncFigureLate(this);
116  _bncFigurePPP  = new bncFigurePPP(this);
117
118  connect(BNC_CORE, SIGNAL(newPosition(QByteArray, bncTime, QVector<double>)),
119          _bncFigurePPP, SLOT(slotNewPosition(QByteArray, bncTime, QVector<double>)));
120
121  connect(BNC_CORE, SIGNAL(progressRnxPPP(int)), this, SLOT(slotPostProcessingProgress(int)));
122  connect(BNC_CORE, SIGNAL(finishedRnxPPP()),    this, SLOT(slotPostProcessingFinished()));
123
124  _runningRealTime    = false;
125  _runningPPP         = false;
126  _runningEdit        = false;
127  _runningQC          = false;
128  _runningSp3Comp     = false;
129  _reqcActionComboBox = 0; // necessary for enableStartStop()
130
131  _mapWin = 0;
132
133  int ww = QFontMetrics(this->font()).width('w');
134
135  static const QStringList labels = QString("account, Streams:   resource loader / mountpoint, decoder, country, lat, long, nmea, ntrip, bytes").split(",");
136
137  setMinimumSize(100*ww, 70*ww);
138
139  setWindowTitle(tr("BKG Ntrip Client (BNC) Version " BNCVERSION));
140
141  connect(BNC_CORE, SIGNAL(newMessage(QByteArray,bool)),
142          this, SLOT(slotWindowMessage(QByteArray,bool)));
143
144  // Create Actions
145  // --------------
146  _actHelp = new QAction(tr("&Help Contents"),this);
147  connect(_actHelp, SIGNAL(triggered()), SLOT(slotHelp()));
148
149  _actAbout = new QAction(tr("&About BNC"),this);
150  connect(_actAbout, SIGNAL(triggered()), SLOT(slotAbout()));
151
152  _actFlowchart = new QAction(tr("&Flow Chart"),this);
153  connect(_actFlowchart, SIGNAL(triggered()), SLOT(slotFlowchart()));
154
155  _actFontSel = new QAction(tr("Select &Font"),this);
156  connect(_actFontSel, SIGNAL(triggered()), SLOT(slotFontSel()));
157
158  _actSaveOpt = new QAction(tr("&Reread && Save Configuration"),this);
159  connect(_actSaveOpt, SIGNAL(triggered()), SLOT(slotSaveOptions()));
160
161  _actQuit  = new QAction(tr("&Quit"),this);
162  connect(_actQuit, SIGNAL(triggered()), SLOT(close()));
163
164  _actAddMountPoints = new QAction(tr("Add &Stream"),this);
165  connect(_actAddMountPoints, SIGNAL(triggered()), SLOT(slotAddMountPoints()));
166
167  _actDeleteMountPoints = new QAction(tr("&Delete Stream"),this);
168  connect(_actDeleteMountPoints, SIGNAL(triggered()), SLOT(slotDeleteMountPoints()));
169  _actDeleteMountPoints->setEnabled(false);
170
171  _actMapMountPoints = new QAction(tr("&Map"),this);
172  connect(_actMapMountPoints, SIGNAL(triggered()), SLOT(slotMapMountPoints()));
173
174  _actStart = new QAction(tr("Sta&rt"),this);
175  connect(_actStart, SIGNAL(triggered()), SLOT(slotStart()));
176
177  _actStop = new QAction(tr("Sto&p"),this);
178  connect(_actStop, SIGNAL(triggered()), SLOT(slotStop()));
179
180  _actwhatsthis= new QAction(tr("Help?=Shift+F1"),this);
181  connect(_actwhatsthis, SIGNAL(triggered()), SLOT(slotWhatsThis()));
182
183  CreateMenu();
184  AddToolbar();
185
186  bncSettings settings;
187
188  // Network Options
189  // ---------------
190  _proxyHostLineEdit  = new QLineEdit(settings.value("proxyHost").toString());
191  _proxyPortLineEdit  = new QLineEdit(settings.value("proxyPort").toString());
192
193  connect(_proxyHostLineEdit, SIGNAL(textChanged(const QString &)),
194          this, SLOT(slotBncTextChanged()));
195
196  _sslCaCertPathLineEdit   = new QLineEdit(settings.value("sslCaCertPath").toString());
197  _sslIgnoreErrorsCheckBox = new QCheckBox();
198  _sslIgnoreErrorsCheckBox->setCheckState(Qt::CheckState(
199                                          settings.value("sslIgnoreErrors").toInt()));
200
201  // General Options
202  // ---------------
203  _logFileLineEdit    = new QLineEdit(settings.value("logFile").toString());
204  _rawOutFileLineEdit = new QLineEdit(settings.value("rawOutFile").toString());
205  _rnxAppendCheckBox  = new QCheckBox();
206  _rnxAppendCheckBox->setCheckState(Qt::CheckState(
207                                    settings.value("rnxAppend").toInt()));
208  _onTheFlyComboBox = new QComboBox();
209  _onTheFlyComboBox->setEditable(false);
210  _onTheFlyComboBox->addItems(QString("no,1 day,1 hour,5 min,1 min").split(","));
211  int ii = _onTheFlyComboBox->findText(settings.value("onTheFlyInterval").toString());
212  if (ii != -1) {
213    _onTheFlyComboBox->setCurrentIndex(ii);
214  }
215  _autoStartCheckBox  = new QCheckBox();
216  _autoStartCheckBox->setCheckState(Qt::CheckState(
217                                    settings.value("autoStart").toInt()));
218
219  // RINEX Observations Options
220  // --------------------------
221  _rnxPathLineEdit    = new QLineEdit(settings.value("rnxPath").toString());
222  _rnxIntrComboBox    = new QComboBox();
223  _rnxIntrComboBox->setEditable(false);
224  _rnxIntrComboBox->addItems(QString("1 min,2 min,5 min,10 min,15 min,30 min,1 hour,1 day").split(","));
225  ii = _rnxIntrComboBox->findText(settings.value("rnxIntr").toString());
226  if (ii != -1) {
227    _rnxIntrComboBox->setCurrentIndex(ii);
228  }
229  _rnxSamplComboBox    = new QComboBox();
230  _rnxSamplComboBox->setEditable(false);
231  _rnxSamplComboBox->addItems(QString("0.1 sec,1 sec,5 sec,10 sec,15 sec,30 sec,60 sec").split(","));
232  int ij = _rnxSamplComboBox->findText(settings.value("rnxSampl").toString());
233  if (ij != -1) {
234    _rnxSamplComboBox->setCurrentIndex(ij);
235  }
236  _rnxFileCheckBox = new QCheckBox();
237  _rnxFileCheckBox->setCheckState(Qt::CheckState(settings.value("rnxOnlyWithSKL").toInt()));
238  _rnxSkelLineEdit    = new QLineEdit(settings.value("rnxSkel").toString());
239  _rnxSkelLineEdit->setMaximumWidth(5*ww);
240  _rnxScrpLineEdit    = new QLineEdit(settings.value("rnxScript").toString());
241  _rnxV3CheckBox      = new QCheckBox();
242  _rnxV3CheckBox->setCheckState(Qt::CheckState(settings.value("rnxV3").toInt()));
243  QString hlp = settings.value("rnxV2Priority").toString();
244  if (hlp.isEmpty()) {
245    hlp = "G:12&PWCSLXYN_ G:5&IQX_ R:12&PC_ R:3&IQX_ E:16&BCX_ E:578&IQX_ J:1&SLXCZ_ J:26&SLX_ J:5&IQX_ C:IQX_ I:ABCX_ S:1&C_ S:5&IQX_";
246  }
247  _rnxV2Priority = new QLineEdit(hlp);
248
249  connect(_rnxPathLineEdit, SIGNAL(textChanged(const QString &)),
250          this, SLOT(slotBncTextChanged()));
251  connect(_rnxV3CheckBox, SIGNAL(stateChanged(int)),
252          this, SLOT(slotBncTextChanged()));
253
254  // RINEX Ephemeris Options
255  // -----------------------
256  _ephPathLineEdit    = new QLineEdit(settings.value("ephPath").toString());
257  _ephIntrComboBox    = new QComboBox();
258  _ephIntrComboBox->setEditable(false);
259  _ephIntrComboBox->addItems(QString("1 min,2 min,5 min,10 min,15 min,30 min,1 hour,1 day").split(","));
260  int jj = _ephIntrComboBox->findText(settings.value("ephIntr").toString());
261  if (jj != -1) {
262    _ephIntrComboBox->setCurrentIndex(jj);
263  }
264  _ephOutPortLineEdit    = new QLineEdit(settings.value("ephOutPort").toString());
265  _ephV3CheckBox = new QCheckBox();
266  _ephV3CheckBox->setCheckState(Qt::CheckState(settings.value("ephV3").toInt()));
267
268  connect(_ephOutPortLineEdit, SIGNAL(textChanged(const QString &)),
269          this, SLOT(slotBncTextChanged()));
270
271  connect(_ephPathLineEdit, SIGNAL(textChanged(const QString &)),
272          this, SLOT(slotBncTextChanged()));
273
274  // Broadcast Corrections Options
275  // -----------------------------
276  _corrPathLineEdit    = new QLineEdit(settings.value("corrPath").toString());
277  _corrIntrComboBox    = new QComboBox();
278  _corrIntrComboBox->setEditable(false);
279  _corrIntrComboBox->addItems(QString("1 min,2 min,5 min,10 min,15 min,30 min,1 hour,1 day").split(","));
280  int mm = _corrIntrComboBox->findText(settings.value("corrIntr").toString());
281  if (mm != -1) {
282    _corrIntrComboBox->setCurrentIndex(mm);
283  }
284  _corrPortLineEdit    = new QLineEdit(settings.value("corrPort").toString());
285
286  connect(_corrPathLineEdit, SIGNAL(textChanged(const QString &)),
287          this, SLOT(slotBncTextChanged()));
288
289  connect(_corrPortLineEdit, SIGNAL(textChanged(const QString &)),
290          this, SLOT(slotBncTextChanged()));
291
292  // Feed Engine Options
293  // -------------------
294  _outPortLineEdit    = new QLineEdit(settings.value("outPort").toString());
295  _outWaitSpinBox   = new QSpinBox();
296  _outWaitSpinBox->setMinimum(1);
297  _outWaitSpinBox->setMaximum(30);
298  _outWaitSpinBox->setSingleStep(1);
299  _outWaitSpinBox->setSuffix(" sec");
300  _outWaitSpinBox->setValue(settings.value("outWait").toInt());
301  _outSamplComboBox    = new QComboBox();
302  _outSamplComboBox->addItems(QString("0.1 sec,1 sec,5 sec,10 sec,15 sec,30 sec,60 sec").split(","));
303  int nn = _outSamplComboBox->findText(settings.value("outSampl").toString());
304    if (nn != -1) {
305      _outSamplComboBox->setCurrentIndex(nn);
306    }
307  _outFileLineEdit    = new QLineEdit(settings.value("outFile").toString());
308  _outUPortLineEdit   = new QLineEdit(settings.value("outUPort").toString());
309  _outLockTimeCheckBox = new QCheckBox();
310  _outLockTimeCheckBox->setCheckState(Qt::CheckState(settings.value("outLockTime").toInt()));
311
312  connect(_outPortLineEdit, SIGNAL(textChanged(const QString &)),
313          this, SLOT(slotBncTextChanged()));
314
315  connect(_outFileLineEdit, SIGNAL(textChanged(const QString &)),
316          this, SLOT(slotBncTextChanged()));
317
318  connect(_outLockTimeCheckBox, SIGNAL(stateChanged(int)),
319          this, SLOT(slotBncTextChanged()));
320
321  // Serial Output Options
322  // ---------------------
323  _serialMountPointLineEdit = new QLineEdit(settings.value("serialMountPoint").toString());
324  _serialPortNameLineEdit = new QLineEdit(settings.value("serialPortName").toString());
325  _serialBaudRateComboBox = new QComboBox();
326  _serialBaudRateComboBox->addItems(QString("110,300,600,"
327            "1200,2400,4800,9600,19200,38400,57600,115200").split(","));
328  int kk = _serialBaudRateComboBox->findText(settings.value("serialBaudRate").toString());
329  if (kk != -1) {
330    _serialBaudRateComboBox->setCurrentIndex(kk);
331  }
332  _serialFlowControlComboBox = new QComboBox();
333  _serialFlowControlComboBox->addItems(QString("OFF,XONXOFF,HARDWARE").split(","));
334  kk = _serialFlowControlComboBox->findText(settings.value("serialFlowControl").toString());
335  if (kk != -1) {
336    _serialFlowControlComboBox->setCurrentIndex(kk);
337  }
338  _serialDataBitsComboBox = new QComboBox();
339  _serialDataBitsComboBox->addItems(QString("5,6,7,8").split(","));
340  kk = _serialDataBitsComboBox->findText(settings.value("serialDataBits").toString());
341  if (kk != -1) {
342    _serialDataBitsComboBox->setCurrentIndex(kk);
343  }
344  _serialParityComboBox   = new QComboBox();
345  _serialParityComboBox->addItems(QString("NONE,ODD,EVEN,SPACE").split(","));
346  kk = _serialParityComboBox->findText(settings.value("serialParity").toString());
347  if (kk != -1) {
348    _serialParityComboBox->setCurrentIndex(kk);
349  }
350  _serialStopBitsComboBox = new QComboBox();
351  _serialStopBitsComboBox->addItems(QString("1,2").split(","));
352  kk = _serialStopBitsComboBox->findText(settings.value("serialStopBits").toString());
353  if (kk != -1) {
354    _serialStopBitsComboBox->setCurrentIndex(kk);
355  }
356  _serialAutoNMEAComboBox  = new QComboBox();
357  _serialAutoNMEAComboBox->addItems(QString("no,Auto,Manual GPGGA,Manual GNGGA").split(","));
358  kk = _serialAutoNMEAComboBox->findText(settings.value("serialAutoNMEA").toString());
359  if (kk != -1) {
360    _serialAutoNMEAComboBox->setCurrentIndex(kk);
361  }
362  _serialFileNMEALineEdit    = new QLineEdit(settings.value("serialFileNMEA").toString());
363  _serialHeightNMEALineEdit  = new QLineEdit(settings.value("serialHeightNMEA").toString());
364
365  _serialManualNMEASamplingSpinBox = new QSpinBox();
366  _serialManualNMEASamplingSpinBox->setMinimum(0);
367  _serialManualNMEASamplingSpinBox->setMaximum(300);
368  _serialManualNMEASamplingSpinBox->setSingleStep(10);
369  _serialManualNMEASamplingSpinBox->setValue(settings.value("serialManualNMEASampling").toInt());
370  _serialManualNMEASamplingSpinBox->setSuffix(" sec");
371
372  connect(_serialMountPointLineEdit, SIGNAL(textChanged(const QString &)),
373          this, SLOT(slotBncTextChanged()));
374
375  connect(_serialAutoNMEAComboBox, SIGNAL(currentIndexChanged(const QString &)),
376          this, SLOT(slotBncTextChanged()));
377
378  // Outages Options
379  // ---------------
380  _adviseObsRateComboBox    = new QComboBox();
381  _adviseObsRateComboBox->setEditable(false);
382  _adviseObsRateComboBox->addItems(QString(",0.1 Hz,0.2 Hz,0.5 Hz,1 Hz,5 Hz").split(","));
383  kk = _adviseObsRateComboBox->findText(settings.value("adviseObsRate").toString());
384  if (kk != -1) {
385    _adviseObsRateComboBox->setCurrentIndex(kk);
386  }
387  _adviseFailSpinBox = new QSpinBox();
388  _adviseFailSpinBox->setMinimum(0);
389  _adviseFailSpinBox->setMaximum(60);
390  _adviseFailSpinBox->setSingleStep(1);
391  _adviseFailSpinBox->setSuffix(" min");
392  _adviseFailSpinBox->setValue(settings.value("adviseFail").toInt());
393  _adviseRecoSpinBox = new QSpinBox();
394  _adviseRecoSpinBox->setMinimum(0);
395  _adviseRecoSpinBox->setMaximum(60);
396  _adviseRecoSpinBox->setSingleStep(1);
397  _adviseRecoSpinBox->setSuffix(" min");
398  _adviseRecoSpinBox->setValue(settings.value("adviseReco").toInt());
399  _adviseScriptLineEdit    = new QLineEdit(settings.value("adviseScript").toString());
400
401  connect(_adviseObsRateComboBox, SIGNAL(currentIndexChanged(const QString &)),
402          this, SLOT(slotBncTextChanged()));
403
404  // Miscellaneous Options
405  // ---------------------
406  _miscMountLineEdit  = new QLineEdit(settings.value("miscMount").toString());
407  _miscPortLineEdit   = new QLineEdit(settings.value("miscPort").toString());
408  _miscIntrComboBox   = new QComboBox();
409  _miscIntrComboBox->setEditable(false);
410  _miscIntrComboBox->addItems(QString(",2 sec,10 sec,1 min,5 min,15 min,1 hour,6 hours,1 day").split(","));
411  int ll = _miscIntrComboBox->findText(settings.value("miscIntr").toString());
412  if (ll != -1) {
413    _miscIntrComboBox->setCurrentIndex(ll);
414  }
415  _miscScanRTCMCheckBox  = new QCheckBox();
416  _miscScanRTCMCheckBox->setCheckState(Qt::CheckState(
417                                    settings.value("miscScanRTCM").toInt()));
418
419  connect(_miscMountLineEdit, SIGNAL(textChanged(const QString &)),
420          this, SLOT(slotBncTextChanged()));
421
422  // Streams
423  // -------
424  _mountPointsTable   = new QTableWidget(0,9);
425
426  _mountPointsTable->horizontalHeader()->resizeSection(1,34*ww);
427  _mountPointsTable->horizontalHeader()->resizeSection(2,9*ww);
428  _mountPointsTable->horizontalHeader()->resizeSection(3,9*ww);
429  _mountPointsTable->horizontalHeader()->resizeSection(4,7*ww);
430  _mountPointsTable->horizontalHeader()->resizeSection(5,7*ww);
431  _mountPointsTable->horizontalHeader()->resizeSection(6,5*ww);
432  _mountPointsTable->horizontalHeader()->resizeSection(7,5*ww);
433#if QT_VERSION < 0x050000
434  _mountPointsTable->horizontalHeader()->setResizeMode(QHeaderView::Interactive);
435#else
436  _mountPointsTable->horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive);
437#endif
438  _mountPointsTable->horizontalHeader()->setStretchLastSection(true);
439  _mountPointsTable->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft);
440  _mountPointsTable->setHorizontalHeaderLabels(labels);
441  _mountPointsTable->setGridStyle(Qt::NoPen);
442  _mountPointsTable->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
443  _mountPointsTable->setSelectionMode(QAbstractItemView::ExtendedSelection);
444  _mountPointsTable->setSelectionBehavior(QAbstractItemView::SelectRows);
445  _mountPointsTable->hideColumn(0);
446  _mountPointsTable->hideColumn(3);
447  connect(_mountPointsTable, SIGNAL(itemSelectionChanged()),
448          SLOT(slotSelectionChanged()));
449  populateMountPointsTable();
450
451  _log = new QTextEdit();
452  _log->setReadOnly(true);
453  QFont msFont(""); msFont.setStyleHint(QFont::TypeWriter); // default monospace font
454  _log->setFont(msFont);
455  _log->document()->setMaximumBlockCount(1000);
456
457  // Combine Corrections
458  // -------------------
459  _cmbTable = new QTableWidget(0,3);
460  _cmbTable->setHorizontalHeaderLabels(QString("Mountpoint, AC Name, Weight").split(","));
461  _cmbTable->setSelectionMode(QAbstractItemView::ExtendedSelection);
462  _cmbTable->setSelectionBehavior(QAbstractItemView::SelectRows);
463  _cmbTable->setMaximumWidth(30*ww);
464  _cmbTable->horizontalHeader()->resizeSection(0,10*ww);
465  _cmbTable->horizontalHeader()->resizeSection(1,8*ww);
466  _cmbTable->horizontalHeader()->resizeSection(2,8*ww);
467#if QT_VERSION < 0x050000
468  _cmbTable->horizontalHeader()->setResizeMode(QHeaderView::Interactive);
469#else
470  _cmbTable->horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive);
471#endif
472  _cmbTable->horizontalHeader()->setStretchLastSection(true);
473  _cmbTable->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft);
474
475  _cmbMaxresLineEdit = new QLineEdit(settings.value("cmbMaxres").toString());
476  _cmbUseGlonass     = new QCheckBox();
477  _cmbUseGlonass->setCheckState(Qt::CheckState(settings.value("cmbUseGlonass").toInt()));
478
479  _cmbSamplSpinBox = new QSpinBox;
480  _cmbSamplSpinBox->setMinimum(10);
481  _cmbSamplSpinBox->setMaximum(60);
482  _cmbSamplSpinBox->setSingleStep(10);
483  _cmbSamplSpinBox->setMaximumWidth(9*ww);
484  _cmbSamplSpinBox->setValue(settings.value("cmbSampl").toInt());
485  _cmbSamplSpinBox->setSuffix(" sec");
486
487  QPushButton* addCmbRowButton = new QPushButton("Add Row");
488  QPushButton* delCmbRowButton = new QPushButton("Delete");
489
490  connect(_cmbTable, SIGNAL(itemSelectionChanged()),
491          SLOT(slotBncTextChanged()));
492
493  _cmbMethodComboBox = new QComboBox();
494  _cmbMethodComboBox->setEditable(false);
495  _cmbMethodComboBox->addItems(QString("Filter,Single-Epoch").split(","));
496  int im = _cmbMethodComboBox->findText(settings.value("cmbMethod").toString());
497  if (im != -1) {
498    _cmbMethodComboBox->setCurrentIndex(im);
499  }
500
501  int iRow = _cmbTable->rowCount();
502  if (iRow > 0) {
503    enableWidget(true, _cmbMethodComboBox);
504    enableWidget(true, _cmbMaxresLineEdit);
505    enableWidget(true, _cmbSamplSpinBox);
506    enableWidget(true, _cmbUseGlonass);
507  }
508  else {
509    enableWidget(false, _cmbMethodComboBox);
510    enableWidget(false, _cmbMaxresLineEdit);
511    enableWidget(false, _cmbSamplSpinBox);
512    enableWidget(false, _cmbUseGlonass);
513  }
514
515  // Upload Results
516  // -------------
517  _uploadTable = new QTableWidget(0,14);
518  _uploadTable->setHorizontalHeaderLabels(QString("Host, Port, Mount, Ntrip, User, Password, System, CoM, SP3 File, RNX File, PID, SID, IOD, bytes").split(","));
519  _uploadTable->setSelectionMode(QAbstractItemView::ExtendedSelection);
520  _uploadTable->setSelectionBehavior(QAbstractItemView::SelectRows);
521  _uploadTable->horizontalHeader()->resizeSection( 0,13*ww);
522  _uploadTable->horizontalHeader()->resizeSection( 1, 5*ww);
523  _uploadTable->horizontalHeader()->resizeSection( 2, 6*ww);
524  _uploadTable->horizontalHeader()->resizeSection( 3, 6*ww);
525  _uploadTable->horizontalHeader()->resizeSection( 4, 8*ww);
526  _uploadTable->horizontalHeader()->resizeSection( 5, 8*ww);
527  _uploadTable->horizontalHeader()->resizeSection( 6,11*ww);
528  _uploadTable->horizontalHeader()->resizeSection( 7, 4*ww);
529  _uploadTable->horizontalHeader()->resizeSection( 8,15*ww);
530  _uploadTable->horizontalHeader()->resizeSection( 9,15*ww);
531  _uploadTable->horizontalHeader()->resizeSection(10, 4*ww);
532  _uploadTable->horizontalHeader()->resizeSection(11, 4*ww);
533  _uploadTable->horizontalHeader()->resizeSection(12, 4*ww);
534  _uploadTable->horizontalHeader()->resizeSection(13,12*ww);
535#if QT_VERSION < 0x050000
536  _uploadTable->horizontalHeader()->setResizeMode(QHeaderView::Interactive);
537#else
538  _uploadTable->horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive);
539#endif
540  _uploadTable->horizontalHeader()->setStretchLastSection(true);
541  _uploadTable->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft);
542
543  connect(_uploadTable, SIGNAL(itemSelectionChanged()),
544          SLOT(slotBncTextChanged()));
545
546  QPushButton* addUploadRowButton = new QPushButton("Add Row");
547  QPushButton* delUploadRowButton = new QPushButton("Del Row");
548  QPushButton* setUploadTrafoButton = new QPushButton("Custom Trafo");
549  _uploadIntrComboBox = new QComboBox;
550  _uploadIntrComboBox->setEditable(false);
551  _uploadIntrComboBox->addItems(QString("1 day,1 hour, 30 min,15 min,10 min,5 min,2 min,1 min").split(","));
552  ii = _uploadIntrComboBox->findText(settings.value("uploadIntr").toString());
553  if (ii != -1) {
554    _uploadIntrComboBox->setCurrentIndex(ii);
555  }
556
557  _uploadAntexFile      = new qtFileChooser(0, qtFileChooser::File);
558  _uploadAntexFile->setFileName(settings.value("uploadAntexFile").toString());
559
560  _uploadSamplRtcmEphCorrSpinBox = new QSpinBox;
561  _uploadSamplRtcmEphCorrSpinBox->setMinimum(0);
562  _uploadSamplRtcmEphCorrSpinBox->setMaximum(60);
563  _uploadSamplRtcmEphCorrSpinBox->setSingleStep(5);
564  _uploadSamplRtcmEphCorrSpinBox->setMaximumWidth(9*ww);
565  _uploadSamplRtcmEphCorrSpinBox->setValue(settings.value("uploadSamplRtcmEphCorr").toInt());
566  _uploadSamplRtcmEphCorrSpinBox->setSuffix(" sec");
567
568  _uploadSamplSp3SpinBox = new QSpinBox;
569  _uploadSamplSp3SpinBox->setMinimum(0);
570  _uploadSamplSp3SpinBox->setMaximum(15);
571  _uploadSamplSp3SpinBox->setSingleStep(1);
572  _uploadSamplSp3SpinBox->setMaximumWidth(9*ww);
573  _uploadSamplSp3SpinBox->setValue(settings.value("uploadSamplSp3").toInt());
574  _uploadSamplSp3SpinBox->setSuffix(" min");
575
576  _uploadSamplClkRnxSpinBox = new QSpinBox;
577  _uploadSamplClkRnxSpinBox->setMinimum(0);
578  _uploadSamplClkRnxSpinBox->setMaximum(60);
579  _uploadSamplClkRnxSpinBox->setSingleStep(5);
580  _uploadSamplClkRnxSpinBox->setMaximumWidth(9*ww);
581  _uploadSamplClkRnxSpinBox->setValue(settings.value("uploadSamplClkRnx").toInt());
582  _uploadSamplClkRnxSpinBox->setSuffix(" sec");
583
584  int iRowT = _uploadTable->rowCount();
585  if (iRowT > 0) {
586    enableWidget(true, _uploadIntrComboBox);
587    enableWidget(true, _uploadSamplRtcmEphCorrSpinBox);
588    enableWidget(true, _uploadSamplSp3SpinBox);
589    enableWidget(true, _uploadSamplClkRnxSpinBox);
590    enableWidget(true, _uploadAntexFile);
591  }
592  else {
593    enableWidget(false, _uploadIntrComboBox);
594    enableWidget(false, _uploadSamplRtcmEphCorrSpinBox);
595    enableWidget(false, _uploadSamplSp3SpinBox);
596    enableWidget(false, _uploadSamplClkRnxSpinBox);
597    enableWidget(false, _uploadAntexFile);
598  }
599
600  // Upload RTCM3 Ephemeris
601  // ----------------------
602  _uploadEphTable = new QTableWidget(0,6);
603  _uploadEphTable->setColumnCount(8);
604  _uploadEphTable->setRowCount(0);
605  _uploadEphTable->setHorizontalHeaderLabels(QString("Host, Port, Mount,  Ntrip, User, Password, System, bytes").split(","));
606  _uploadEphTable->setSelectionMode(QAbstractItemView::ExtendedSelection);
607  _uploadEphTable->setSelectionBehavior(QAbstractItemView::SelectRows);
608  _uploadEphTable->horizontalHeader()->resizeSection( 0,13*ww);
609  _uploadEphTable->horizontalHeader()->resizeSection( 1, 5*ww);
610  _uploadEphTable->horizontalHeader()->resizeSection( 2, 8*ww);
611  _uploadEphTable->horizontalHeader()->resizeSection( 3, 6*ww);
612  _uploadEphTable->horizontalHeader()->resizeSection( 4, 8*ww);
613  _uploadEphTable->horizontalHeader()->resizeSection( 3, 8*ww);
614  _uploadEphTable->horizontalHeader()->resizeSection( 5,10*ww);
615  _uploadEphTable->horizontalHeader()->resizeSection( 6,12*ww);
616#if QT_VERSION < 0x050000
617  _uploadEphTable->horizontalHeader()->setResizeMode(QHeaderView::Interactive);
618#else
619  _uploadEphTable->horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive);
620#endif
621  _uploadEphTable->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft);
622
623  connect(_uploadEphTable, SIGNAL(itemSelectionChanged()),
624          SLOT(slotBncTextChanged()));
625
626  QPushButton* addUploadEphRowButton = new QPushButton("Add Row");
627  addUploadEphRowButton->setMaximumWidth(9*ww);
628  QPushButton* delUploadEphRowButton = new QPushButton("Del Row");
629  delUploadEphRowButton->setMaximumWidth(9*ww);
630
631  _uploadSamplRtcmEphSpinBox = new QSpinBox;
632  _uploadSamplRtcmEphSpinBox->setMinimum(0);
633  _uploadSamplRtcmEphSpinBox->setMaximum(60);
634  _uploadSamplRtcmEphSpinBox->setSingleStep(5);
635  _uploadSamplRtcmEphSpinBox->setMaximumWidth(9*ww);
636  _uploadSamplRtcmEphSpinBox->setValue(settings.value("uploadSamplRtcmEph").toInt());
637  _uploadSamplRtcmEphSpinBox->setSuffix(" sec");
638
639  iRowT = _uploadEphTable->rowCount();
640  if (iRowT > 0) {
641    enableWidget(true, _uploadSamplRtcmEphSpinBox);
642  }
643  else {
644    enableWidget(false, _uploadSamplRtcmEphSpinBox);
645  }
646
647  // Canvas with Editable Fields
648  // ---------------------------
649  _canvas = new QWidget;
650  setCentralWidget(_canvas);
651
652  _aogroup = new QTabWidget();
653  _aogroup->setElideMode(Qt::ElideNone);
654  _aogroup->setUsesScrollButtons(true);
655  QWidget* pgroup = new QWidget();
656  QWidget* ggroup = new QWidget();
657  QWidget* sgroup = new QWidget();
658  QWidget* egroup = new QWidget();
659  QWidget* agroup = new QWidget();
660  QWidget* cgroup = new QWidget();
661  QWidget* ogroup = new QWidget();
662  QWidget* rgroup = new QWidget();
663  QWidget* sergroup = new QWidget();
664  QWidget* pppGroup1 = new QWidget();
665  QWidget* pppGroup2 = new QWidget();
666  QWidget* pppGroup3 = new QWidget();
667  QWidget* pppGroup4 = new QWidget();
668  QWidget* reqcgroup = new QWidget();
669  QWidget* sp3CompGroup = new QWidget();
670  QWidget* cmbgroup = new QWidget();
671  QWidget* uploadgroup = new QWidget();
672  QWidget* uploadEphgroup = new QWidget();
673  _aogroup->addTab(pgroup,tr("Network"));
674  _aogroup->addTab(ggroup,tr("General"));
675  _aogroup->addTab(ogroup,tr("RINEX Observations"));
676  _aogroup->addTab(egroup,tr("RINEX Ephemeris"));
677  _aogroup->addTab(reqcgroup,tr("RINEX Editing && QC"));
678  _aogroup->addTab(sp3CompGroup,tr("SP3 Comparison"));
679  _aogroup->addTab(cgroup,tr("Broadcast Corrections"));
680  _aogroup->addTab(sgroup,tr("Feed Engine"));
681  _aogroup->addTab(sergroup,tr("Serial Output"));
682  _aogroup->addTab(agroup,tr("Outages"));
683  _aogroup->addTab(rgroup,tr("Miscellaneous"));
684  _aogroup->addTab(pppGroup1,tr("PPP (1)"));
685  _aogroup->addTab(pppGroup2,tr("PPP (2)"));
686  _aogroup->addTab(pppGroup3,tr("PPP (3)"));
687  _aogroup->addTab(pppGroup4,tr("PPP (4)"));
688  _aogroup->addTab(cmbgroup,tr("Combine Corrections"));
689  _aogroup->addTab(uploadgroup,tr("Upload Corrections"));
690  _aogroup->addTab(uploadEphgroup,tr("Upload Ephemeris"));
691
692  // Log Tab
693  // -------
694  _loggroup = new QTabWidget();
695  _loggroup->addTab(_log,tr("Log"));
696  _loggroup->addTab(_bncFigure,tr("Throughput"));
697  _loggroup->addTab(_bncFigureLate,tr("Latency"));
698  _loggroup->addTab(_bncFigurePPP,tr("PPP Plot"));
699
700  // Netowork (Proxy and SSL) Tab
701  // ----------------------------
702  QGridLayout* pLayout = new QGridLayout;
703  pLayout->setColumnMinimumWidth(0,13*ww);
704  _proxyPortLineEdit->setMaximumWidth(9*ww);
705
706  pLayout->addWidget(new QLabel("Settings for proxy in protected networks and for SSL authorization, leave boxes blank if none.<br>"),0, 0, 1, 50);
707  pLayout->addWidget(new QLabel("Proxy host"),                               1, 0);
708  pLayout->addWidget(_proxyHostLineEdit,                                     1, 1, 1,10);
709  pLayout->addWidget(new QLabel("Proxy port"),                               2, 0);
710  pLayout->addWidget(_proxyPortLineEdit,                                     2, 1);
711  pLayout->addWidget(new QLabel("Path to SSL certificates"),                 3, 0);
712  pLayout->addWidget(_sslCaCertPathLineEdit,                                 3, 1, 1,10);
713  pLayout->addWidget(new QLabel("Default:  " + bncSslConfig::defaultPath()), 3,11, 1,20);
714  pLayout->addWidget(new QLabel("Ignore SSL authorization errors"),          4, 0);
715  pLayout->addWidget(_sslIgnoreErrorsCheckBox,                               4, 1, 1,10);
716  pLayout->addWidget(new QLabel(""),                                         5, 1);
717  pLayout->setRowStretch(6, 999);
718
719  pgroup->setLayout(pLayout);
720
721  // General Tab
722  // -----------
723  QGridLayout* gLayout = new QGridLayout;
724  gLayout->setColumnMinimumWidth(0,14*ww);
725  _onTheFlyComboBox->setMaximumWidth(9*ww);
726
727  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);
728  gLayout->addWidget(new QLabel("Logfile (full path)"),          1, 0);
729  gLayout->addWidget(_logFileLineEdit,                           1, 1, 1,20);
730  gLayout->addWidget(new QLabel("Append files"),                 2, 0);
731  gLayout->addWidget(_rnxAppendCheckBox,                         2, 1);
732  gLayout->addWidget(new QLabel("Reread configuration"),         3, 0);
733  gLayout->addWidget(_onTheFlyComboBox,                          3, 1);
734  gLayout->addWidget(new QLabel("Auto start"),                   4, 0);
735  gLayout->addWidget(_autoStartCheckBox,                         4, 1);
736  gLayout->addWidget(new QLabel("Raw output file (full path)"),  5, 0);
737  gLayout->addWidget(_rawOutFileLineEdit,                        5, 1, 1,20);
738  gLayout->addWidget(new QLabel(""),                             6, 1);
739  gLayout->setRowStretch(7, 999);
740
741  ggroup->setLayout(gLayout);
742
743  // RINEX Observations
744  // ------------------
745  QGridLayout* oLayout = new QGridLayout;
746  oLayout->setColumnMinimumWidth(0,14*ww);
747  _rnxIntrComboBox->setMaximumWidth(9*ww);
748  _rnxSamplComboBox->setMaximumWidth(9*ww);
749
750  oLayout->addWidget(new QLabel("Saving RINEX observation files.<br>"),0, 0, 1,50);
751  oLayout->addWidget(new QLabel("Directory"),                      1, 0);
752  oLayout->addWidget(_rnxPathLineEdit,                             1, 1, 1, 15);
753  oLayout->addWidget(new QLabel("Interval"),                       2, 0);
754  oLayout->addWidget(_rnxIntrComboBox,                             2, 1);
755  oLayout->addWidget(new QLabel("  Sampling"),                     2, 2, Qt::AlignRight);
756  oLayout->addWidget(_rnxSamplComboBox,                            2, 3, Qt::AlignLeft);
757  oLayout->addWidget(new QLabel("Skeleton extension"),             3, 0);
758  oLayout->addWidget(_rnxSkelLineEdit,                             3, 1, Qt::AlignLeft);
759  oLayout->addWidget(new QLabel("Skeleton mandatory"),             3, 2);
760  oLayout->addWidget(_rnxFileCheckBox,                             3, 3);
761  oLayout->addWidget(new QLabel("Script (full path)"),             4, 0);
762  oLayout->addWidget(_rnxScrpLineEdit,                             4, 1, 1, 15);
763  oLayout->addWidget(new QLabel("Version 2 signal priority"),      5, 0);
764  oLayout->addWidget(_rnxV2Priority,                               5, 1, 1, 15);
765  oLayout->addWidget(new QLabel("Version 3"),                      6, 0);
766  oLayout->addWidget(_rnxV3CheckBox,                               6, 1);
767  oLayout->addWidget(new QLabel(""),                               7, 1);
768  oLayout->setRowStretch(8, 999);
769
770  ogroup->setLayout(oLayout);
771
772  // RINEX Ephemeris
773  // ---------------
774  QGridLayout* eLayout = new QGridLayout;
775  eLayout->setColumnMinimumWidth(0,14*ww);
776  _ephIntrComboBox->setMaximumWidth(9*ww);
777  _ephOutPortLineEdit->setMaximumWidth(9*ww);
778
779  eLayout->addWidget(new QLabel("Saving RINEX navigation files and ephemeris output through IP port.<br>"),0,0,1,70);
780  eLayout->addWidget(new QLabel("Directory"),                     1, 0);
781  eLayout->addWidget(_ephPathLineEdit,                            1, 1, 1,30);
782  eLayout->addWidget(new QLabel("Interval"),                      2, 0);
783  eLayout->addWidget(_ephIntrComboBox,                            2, 1);
784  eLayout->addWidget(new QLabel("Port"),                          3, 0);
785  eLayout->addWidget(_ephOutPortLineEdit,                         3, 1);
786  eLayout->addWidget(new QLabel("Version 3"),                     4, 0);
787  eLayout->addWidget(_ephV3CheckBox,                              4, 1);
788  eLayout->setRowStretch(5, 999);
789
790  egroup->setLayout(eLayout);
791
792
793  // Broadcast Corrections
794  // ---------------------
795  QGridLayout* cLayout = new QGridLayout;
796  cLayout->setColumnMinimumWidth(0,14*ww);
797  _corrIntrComboBox->setMaximumWidth(9*ww);
798  _corrPortLineEdit->setMaximumWidth(9*ww);
799
800  cLayout->addWidget(new QLabel("Saving Broadcast Ephemeris correction files and correction output through IP port.<br>"),0,0,1,70);
801  cLayout->addWidget(new QLabel("Directory, ASCII"),              1, 0);
802  cLayout->addWidget(_corrPathLineEdit,                           1, 1, 1,30);
803  cLayout->addWidget(new QLabel("Interval"),                      2, 0);
804  cLayout->addWidget(_corrIntrComboBox,                           2, 1);
805  cLayout->addWidget(new QLabel("Port"),                          3, 0);
806  cLayout->addWidget(_corrPortLineEdit,                           3, 1);
807  cLayout->addWidget(new QLabel(""),                              4, 1);
808  cLayout->setRowStretch(7, 999);
809  cgroup->setLayout(cLayout);
810
811  // Feed Engine
812  // -----------
813  QGridLayout* sLayout = new QGridLayout;
814  sLayout->setColumnMinimumWidth(0,14*ww);
815  _outPortLineEdit->setMaximumWidth(9*ww);
816  _outWaitSpinBox->setMaximumWidth(9*ww);
817  _outSamplComboBox->setMaximumWidth(9*ww);
818  _outUPortLineEdit->setMaximumWidth(9*ww);
819
820  sLayout->addWidget(new QLabel("Output decoded observations in ASCII format to feed a real-time GNSS network engine.<br>"),0,0,1,50);
821  sLayout->addWidget(new QLabel("Port"),                            1, 0);
822  sLayout->addWidget(_outPortLineEdit,                              1, 1);
823  sLayout->addWidget(new QLabel("       Wait for full obs epoch"),  1, 2, Qt::AlignRight);
824  sLayout->addWidget(_outWaitSpinBox,                               1, 3, Qt::AlignLeft);
825  sLayout->addWidget(new QLabel("Sampling"),                        2, 0);
826  sLayout->addWidget(_outSamplComboBox,                             2, 1, Qt::AlignLeft);
827  sLayout->addWidget(new QLabel("File (full path)"),                3, 0);
828  sLayout->addWidget(_outFileLineEdit,                              3, 1, 1, 10);
829  sLayout->addWidget(new QLabel("Port (unsynchronized)"),           4, 0);
830  sLayout->addWidget(_outUPortLineEdit,                             4, 1);
831  sLayout->addWidget(new QLabel("Print lock time"),                 5, 0);
832  sLayout->addWidget(_outLockTimeCheckBox,                        5, 1);
833  sLayout->addWidget(new QLabel(""),                                6, 1);
834  sLayout->setRowStretch(7, 999);
835
836  sgroup->setLayout(sLayout);
837
838  // Serial Output
839  // -------------
840  QGridLayout* serLayout = new QGridLayout;
841  serLayout->setColumnMinimumWidth(0,12*ww);
842  _serialBaudRateComboBox->setMaximumWidth(9*ww);
843  _serialFlowControlComboBox->setMaximumWidth(11*ww);
844  _serialDataBitsComboBox->setMaximumWidth(5*ww);
845  _serialParityComboBox->setMaximumWidth(9*ww);
846  _serialStopBitsComboBox->setMaximumWidth(5*ww);
847  _serialAutoNMEAComboBox->setMaximumWidth(14*ww);
848  _serialHeightNMEALineEdit->setMaximumWidth(8*ww);
849  _serialManualNMEASamplingSpinBox->setMaximumWidth(8*ww);
850
851  serLayout->addWidget(new QLabel("Port settings to feed a serial connected receiver.<br>"),0,0,1,30);
852  serLayout->addWidget(new QLabel("Mountpoint"),                  1, 0, Qt::AlignLeft);
853  serLayout->addWidget(_serialMountPointLineEdit,                 1, 1, 1, 2);
854  serLayout->addWidget(new QLabel("Port name"),                   2, 0, Qt::AlignLeft);
855  serLayout->addWidget(_serialPortNameLineEdit,                   2, 1, 1, 2);
856  serLayout->addWidget(new QLabel("Baud rate"),                   3, 0, Qt::AlignLeft);
857  serLayout->addWidget(_serialBaudRateComboBox,                   3, 1);
858  serLayout->addWidget(new QLabel("Flow control"),                3, 2, Qt::AlignRight);
859  serLayout->addWidget(_serialFlowControlComboBox,                3, 3);
860  serLayout->addWidget(new QLabel("Data bits"),                   4, 0, Qt::AlignLeft);
861  serLayout->addWidget(_serialDataBitsComboBox,                   4, 1);
862  serLayout->addWidget(new QLabel("Parity"),                      4, 2, Qt::AlignRight);
863  serLayout->addWidget(_serialParityComboBox,                     4, 3);
864  serLayout->addWidget(new QLabel("   Stop bits"),                4, 4, Qt::AlignRight);
865  serLayout->addWidget(_serialStopBitsComboBox,                   4, 5);
866  serLayout->addWidget(new QLabel("NMEA"),                        5, 0);
867  serLayout->addWidget(_serialAutoNMEAComboBox,                   5, 1);
868  serLayout->addWidget(new QLabel("    File (full path)"),        5, 2, Qt::AlignRight);
869  serLayout->addWidget(_serialFileNMEALineEdit,                   5, 3, 1,10);
870  serLayout->addWidget(new QLabel("Height"),                      5,14, Qt::AlignRight);
871  serLayout->addWidget(_serialHeightNMEALineEdit,                 5,15, 1,11);
872  serLayout->addWidget(new QLabel("Sampling"),                    5,25, Qt::AlignRight);
873  serLayout->addWidget(_serialManualNMEASamplingSpinBox,          5,26, 1,12);
874  serLayout->addWidget(new QLabel(""),                            6, 1);
875  serLayout->setRowStretch(7, 999);
876
877  sergroup->setLayout(serLayout);
878
879  // Outages
880  // -------
881  QGridLayout* aLayout = new QGridLayout;
882  aLayout->setColumnMinimumWidth(0,14*ww);
883  _adviseObsRateComboBox->setMaximumWidth(9*ww);
884  _adviseFailSpinBox->setMaximumWidth(9*ww);
885  _adviseRecoSpinBox->setMaximumWidth(9*ww);
886
887  aLayout->addWidget(new QLabel("Failure and recovery reports, advisory notes.<br>"),0,0,1,50,Qt::AlignLeft);
888  aLayout->addWidget(new QLabel("Observation rate"),              1, 0);
889  aLayout->addWidget(_adviseObsRateComboBox,                      1, 1);
890  aLayout->addWidget(new QLabel("Failure threshold"),             2, 0);
891  aLayout->addWidget(_adviseFailSpinBox,                          2, 1);
892  aLayout->addWidget(new QLabel("Recovery threshold"),            3, 0);
893  aLayout->addWidget(_adviseRecoSpinBox,                          3, 1);
894  aLayout->addWidget(new QLabel("Script (full path)"),            4, 0);
895  aLayout->addWidget(_adviseScriptLineEdit,                       4, 1, 1,20);
896  aLayout->addWidget(new QLabel(""),                              5, 1);
897  aLayout->setRowStretch(6, 999);
898
899  agroup->setLayout(aLayout);
900
901  // Miscellaneous
902  // -------------
903  QGridLayout* rLayout = new QGridLayout;
904  rLayout->setColumnMinimumWidth(0,14*ww);
905  _miscIntrComboBox->setMaximumWidth(9*ww);
906  _miscPortLineEdit->setMaximumWidth(9*ww);
907
908  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);
909  rLayout->addWidget(new QLabel("Mountpoint"),                    1, 0);
910  rLayout->addWidget(_miscMountLineEdit,                          1, 1, 1, 7);
911  rLayout->addWidget(new QLabel("Log latency"),                   2, 0);
912  rLayout->addWidget(_miscIntrComboBox,                           2, 1);
913  rLayout->addWidget(new QLabel("Scan RTCM"),                     3, 0);
914  rLayout->addWidget(_miscScanRTCMCheckBox,                       3, 1);
915  rLayout->addWidget(new QLabel("Port"),                          4, 0);
916  rLayout->addWidget(_miscPortLineEdit,                           4, 1);
917  rLayout->addWidget(new QLabel(""),                              5, 1);
918  rLayout->setRowStretch(6, 999);
919
920  rgroup->setLayout(rLayout);
921
922  // PPP
923  // ---
924  _pppWidgets._dataSource->setMaximumWidth(15*ww);
925  _pppWidgets._corrMount->setMaximumWidth(15*ww);
926  _pppWidgets._nmeaPath->setMaximumWidth(35*ww);
927  _pppWidgets._logPath->setMaximumWidth(35*ww);
928  _pppWidgets._snxtroPath->setMaximumWidth(35*ww);
929  _pppWidgets._snxtroIntr->setMaximumWidth(10*ww);
930  _pppWidgets._snxtroAc  ->setMaximumWidth(10*ww);
931  _pppWidgets._snxtroSol ->setMaximumWidth(7*ww);
932
933  QGridLayout* pppLayout1 = new QGridLayout();
934  int ir = 0;
935  pppLayout1->addWidget(new QLabel("Precise Point Positioning - Input and Output.<br>"), ir, 0, 1, 7, Qt::AlignLeft);
936  ++ir;
937  pppLayout1->addWidget(new QLabel("Data source"),           ir, 0);
938  pppLayout1->addWidget(_pppWidgets._dataSource,             ir, 1);
939  pppLayout1->addWidget(new QLabel("   Version 3 filenames"),ir, 4);
940  pppLayout1->addWidget(_pppWidgets._v3filenames,            ir, 5, 1, 3);
941  ++ir;
942  pppLayout1->addWidget(new QLabel("Corrections stream"),    ir, 0);
943  pppLayout1->addWidget(_pppWidgets._corrMount,              ir, 1);
944  pppLayout1->addWidget(new QLabel("Corrections file"),      ir, 2);
945  pppLayout1->addWidget(_pppWidgets._corrFile,               ir, 3);
946  pppLayout1->addWidget(new QLabel("   Logfile directory"),  ir, 4);
947  pppLayout1->addWidget(_pppWidgets._logPath,                ir, 5, 1, 3);
948  ++ir;
949  pppLayout1->addWidget(new QLabel("RINEX Obs file"),        ir, 0);
950  pppLayout1->addWidget(_pppWidgets._rinexObs,               ir, 1);
951  pppLayout1->addWidget(new QLabel("RINEX Nav file"),        ir, 2);
952  pppLayout1->addWidget(_pppWidgets._rinexNav,               ir, 3);
953  pppLayout1->addWidget(new QLabel("   NMEA directory"),     ir, 4);
954  pppLayout1->addWidget(_pppWidgets._nmeaPath,               ir, 5, 1, 3);
955  ++ir;
956  pppLayout1->addWidget(new QLabel("Coordinates file"),      ir, 0);
957  pppLayout1->addWidget(_pppWidgets._crdFile,                ir, 1);
958  pppLayout1->addWidget(new QLabel("ANTEX file"),            ir, 2);
959  pppLayout1->addWidget(_pppWidgets._antexFile,              ir, 3);
960  pppLayout1->addWidget(new QLabel("   SNX TRO directory"),  ir, 4);
961  pppLayout1->addWidget(_pppWidgets._snxtroPath,             ir, 5, 1, 3);
962  ++ir;
963#ifdef USE_PPP
964  pppLayout1->addWidget(new QLabel("BLQ file"),              ir, 0);
965  pppLayout1->addWidget(_pppWidgets._blqFile,                ir, 1);
966#endif
967  pppLayout1->addWidget(new QLabel("   SNX TRO interval"),   ir, 4);
968  pppLayout1->addWidget(_pppWidgets._snxtroIntr,             ir, 5);
969  pppLayout1->addWidget(new QLabel("   SNX TRO sampling"),   ir, 6);
970  pppLayout1->addWidget(_pppWidgets._snxtroSampl,            ir, 7, Qt::AlignRight);
971  ++ir;
972  pppLayout1->addWidget(new QLabel("   SNX TRO AC"),         ir, 4);
973  pppLayout1->addWidget(_pppWidgets._snxtroAc,               ir, 5);
974  pppLayout1->addWidget(new QLabel("   SNX TRO solution"),   ir, 6);
975  pppLayout1->addWidget(_pppWidgets._snxtroSol,              ir, 7, Qt::AlignRight);
976  pppLayout1->setRowStretch(ir+1, 999);
977  pppGroup1->setLayout(pppLayout1);
978
979  QVBoxLayout* pppLayout2 = new QVBoxLayout();
980  pppLayout2->addWidget(new QLabel("Precise Point Positioning - Processed Stations.<br>"));
981  pppLayout2->addWidget(_pppWidgets._staTable, 99);
982  QHBoxLayout* pppLayout2sub = new QHBoxLayout();
983  pppLayout2sub->addWidget(_pppWidgets._addStaButton);
984  pppLayout2sub->addWidget(_pppWidgets._delStaButton);
985  pppLayout2sub->addStretch(99);
986
987  pppLayout2->addLayout(pppLayout2sub);
988
989  pppGroup2->setLayout(pppLayout2);
990
991  QGridLayout* pppLayout3 = new QGridLayout();
992  ir = 0;
993  pppLayout3->addWidget(new QLabel("Precise Point Positioning - Options.<br>"), ir, 0, 1, 2, Qt::AlignLeft);
994  ++ir;
995  pppLayout3->addWidget(new QLabel("GPS LCs"),              ir, 0, Qt::AlignLeft);
996  pppLayout3->addWidget(_pppWidgets._lcGPS,                 ir, 1);
997  pppLayout3->addItem(new QSpacerItem(8*ww, 0),             ir, 2);
998  pppLayout3->addWidget(new QLabel("Sigma C1"),             ir, 3, Qt::AlignLeft);
999  pppLayout3->addWidget(_pppWidgets._sigmaC1,               ir, 4); _pppWidgets._sigmaC1->setMaximumWidth(8*ww);
1000  pppLayout3->addItem(new QSpacerItem(8*ww, 0),             ir, 5);
1001  pppLayout3->addWidget(new QLabel("Sigma L1"),             ir, 6, Qt::AlignLeft);
1002  pppLayout3->addWidget(_pppWidgets._sigmaL1,               ir, 7); _pppWidgets._sigmaL1->setMaximumWidth(8*ww);
1003  ++ir;
1004  pppLayout3->addWidget(new QLabel("GLONASS LCs"),          ir, 0, Qt::AlignLeft);
1005  pppLayout3->addWidget(_pppWidgets._lcGLONASS,             ir, 1);
1006  pppLayout3->addWidget(new QLabel("Max Res C1"),           ir, 3, Qt::AlignLeft);
1007  pppLayout3->addWidget(_pppWidgets._maxResC1,              ir, 4); _pppWidgets._maxResC1->setMaximumWidth(8*ww);
1008  pppLayout3->addWidget(new QLabel("Max Res L1"),           ir, 6, Qt::AlignLeft);
1009  pppLayout3->addWidget(_pppWidgets._maxResL1,              ir, 7); _pppWidgets._maxResL1->setMaximumWidth(8*ww);
1010  ++ir;
1011  pppLayout3->addWidget(new QLabel("Galileo LCs"),          ir, 0, Qt::AlignLeft);
1012  pppLayout3->addWidget(_pppWidgets._lcGalileo,             ir, 1);
1013  pppLayout3->addWidget(new QLabel("Ele Wgt Code"),         ir, 3, Qt::AlignLeft);
1014  pppLayout3->addWidget(_pppWidgets._eleWgtCode,            ir, 4);
1015  pppLayout3->addWidget(new QLabel("Ele Wgt Phase"),        ir, 6, Qt::AlignLeft);
1016  pppLayout3->addWidget(_pppWidgets._eleWgtPhase,           ir, 7);
1017  ++ir;
1018  pppLayout3->addWidget(new QLabel("BDS LCs"),              ir, 0, Qt::AlignLeft);
1019  pppLayout3->addWidget(_pppWidgets._lcBDS,                 ir, 1);
1020  pppLayout3->addWidget(new QLabel("Min # of Obs"),         ir, 3, Qt::AlignLeft);
1021  pppLayout3->addWidget(_pppWidgets._minObs,                ir, 4);
1022  pppLayout3->addWidget(new QLabel("Min Elevation"),        ir, 6, Qt::AlignLeft);
1023  pppLayout3->addWidget(_pppWidgets._minEle,                ir, 7);
1024  ++ir;
1025  pppLayout3->addWidget(new QLabel("Wait for clock corr."), ir, 0, Qt::AlignLeft);
1026  pppLayout3->addWidget(_pppWidgets._corrWaitTime,          ir, 1);
1027  pppLayout3->addWidget(new QLabel("Seeding (sec)"),        ir, 3, Qt::AlignLeft);
1028  pppLayout3->addWidget(_pppWidgets._seedingTime,           ir, 4);
1029  ++ir;
1030  pppLayout3->addWidget(new QLabel(""),                     ir, 8);
1031  pppLayout3->setColumnStretch(8, 999);
1032  ++ir;
1033  pppLayout3->addWidget(new QLabel(""),                      ir, 1);
1034  pppLayout3->setRowStretch(ir, 999);
1035
1036  pppGroup3->setLayout(pppLayout3);
1037
1038  // ------------------------
1039  connect(_pppWidgets._mapWinButton, SIGNAL(clicked()), SLOT(slotMapPPP()));
1040  _pppWidgets._mapSpeedSlider->setMinimumWidth(33*ww);
1041  _pppWidgets._audioResponse->setMaximumWidth(8*ww);
1042
1043  QGridLayout* pppLayout4 = new QGridLayout();
1044  ir = 0;
1045  pppLayout4->addWidget(new QLabel("Precise Point Positioning - Plots.<br>"), ir, 0, 1, 50, Qt::AlignLeft);
1046  ++ir;
1047  pppLayout4->addWidget(new QLabel("PPP Plot"),                          ir, 0, Qt::AlignLeft);
1048  pppLayout4->addWidget(_pppWidgets._plotCoordinates,                    ir, 1, Qt::AlignLeft);
1049  pppLayout4->addWidget(new QLabel("Mountpoint"),                        ir, 2, 1, 10, Qt::AlignLeft);
1050  pppLayout4->addWidget(_pppWidgets._audioResponse,                      ir, 4, Qt::AlignLeft);
1051  pppLayout4->addWidget(new QLabel("Audio response"),                    ir, 5, Qt::AlignRight);
1052
1053  ++ir;
1054  pppLayout4->addWidget(new QLabel("Track map"),                         ir, 0, Qt::AlignLeft);
1055  pppLayout4->addWidget(_pppWidgets._mapWinButton,                       ir, 1, Qt::AlignLeft);
1056  pppLayout4->addWidget(new QLabel("OSM"),                               ir, 2, Qt::AlignLeft);
1057  pppLayout4->addWidget(_pppWidgets._useOpenStreetMap,                   ir, 3, Qt::AlignLeft);
1058  pppLayout4->addWidget(new QLabel("Google"),                            ir, 3, Qt::AlignRight);
1059  pppLayout4->addWidget(_pppWidgets._useGoogleMap,                       ir, 4, Qt::AlignLeft);
1060  ++ir;
1061  pppLayout4->addWidget(new QLabel("Dot-properties"),                    ir, 0, Qt::AlignLeft);
1062  pppLayout4->addWidget(_pppWidgets._mapWinDotSize,                      ir, 1, Qt::AlignLeft);
1063  pppLayout4->addWidget(new QLabel("Size    "),                          ir, 2, Qt::AlignLeft);
1064  pppLayout4->addWidget(_pppWidgets._mapWinDotColor,                     ir, 3, Qt::AlignLeft);
1065  pppLayout4->addWidget(new QLabel("Color"),                             ir, 4, Qt::AlignLeft);
1066  ++ir;
1067  pppLayout4->addWidget(new QLabel("Post-processing speed"),             ir, 0, Qt::AlignLeft);
1068  pppLayout4->addWidget(_pppWidgets._mapSpeedSlider,                     ir, 1, 1, 20, Qt::AlignLeft);
1069  ++ir;
1070  pppLayout4->addWidget(new QLabel(""),                                  ir, 1);
1071  pppLayout4->setRowStretch(ir, 999);
1072
1073  pppGroup4->setLayout(pppLayout4);
1074
1075  // Reqc Processing
1076  // ---------------
1077  _reqcActionComboBox = new QComboBox();
1078  _reqcActionComboBox->setEditable(false);
1079  _reqcActionComboBox->addItems(QString(",Edit/Concatenate,Analyze").split(","));
1080  int ik = _reqcActionComboBox->findText(settings.value("reqcAction").toString());
1081  if (ik != -1) {
1082    _reqcActionComboBox->setCurrentIndex(ik);
1083  }
1084  connect(_reqcActionComboBox, SIGNAL(currentIndexChanged(const QString &)),
1085          this, SLOT(slotBncTextChanged()));
1086
1087  QGridLayout* reqcLayout = new QGridLayout;
1088  _reqcActionComboBox->setMinimumWidth(15*ww);
1089  _reqcActionComboBox->setMaximumWidth(20*ww);
1090
1091  _reqcObsFileChooser = new qtFileChooser(0, qtFileChooser::Files);
1092  _reqcObsFileChooser->setFileName(settings.value("reqcObsFile").toString());
1093
1094  _reqcNavFileChooser = new qtFileChooser(0, qtFileChooser::Files);
1095  _reqcNavFileChooser->setFileName(settings.value("reqcNavFile").toString());
1096  _reqcOutObsLineEdit = new QLineEdit(settings.value("reqcOutObsFile").toString());
1097  _reqcOutNavLineEdit = new QLineEdit(settings.value("reqcOutNavFile").toString());
1098  _reqcOutLogLineEdit = new QLineEdit(settings.value("reqcOutLogFile").toString());
1099  _reqcPlotDirLineEdit = new QLineEdit(settings.value("reqcPlotDir").toString());
1100  _reqcSkyPlotSignals = new QLineEdit(settings.value("reqcSkyPlotSignals").toString());
1101
1102  connect(_reqcSkyPlotSignals, SIGNAL(textChanged(const QString &)),
1103          this, SLOT(slotBncTextChanged()));
1104
1105  _reqcLogSummaryOnly = new QCheckBox();
1106  _reqcLogSummaryOnly->setCheckState(Qt::CheckState(settings.value("reqcLogSummaryOnly").toInt()));
1107
1108  ir = 0;
1109  reqcLayout->addWidget(new QLabel("RINEX file editing, concatenation and quality check.<br>"),ir, 0, 1, 8);
1110  ++ir;
1111  reqcLayout->addWidget(new QLabel("Action"),                    ir, 0);
1112  reqcLayout->addWidget(_reqcActionComboBox,                     ir, 1);
1113  _reqcEditOptionButton = new QPushButton("Set Edit Options");
1114  _reqcEditOptionButton->setMinimumWidth(15*ww);
1115  _reqcEditOptionButton->setMaximumWidth(20*ww);
1116
1117  reqcLayout->addWidget(_reqcEditOptionButton,                   ir, 3);
1118  ++ir;
1119  reqcLayout->addWidget(new QLabel("Input files (full path)"),   ir, 0);
1120  reqcLayout->addWidget(_reqcObsFileChooser,                     ir, 1);
1121  _reqcObsFileChooser->setMaximumWidth(40*ww);
1122  reqcLayout->addWidget(new QLabel("  Obs"),                     ir, 2);
1123  reqcLayout->addWidget(_reqcNavFileChooser,                     ir, 3);
1124  _reqcNavFileChooser->setMaximumWidth(40*ww);
1125  reqcLayout->addWidget(new QLabel("  Nav"),                     ir, 4);
1126  ++ir;
1127  reqcLayout->addWidget(new QLabel("Output file (full path)"),   ir, 0);
1128  reqcLayout->addWidget(_reqcOutObsLineEdit,                     ir, 1);
1129  _reqcOutObsLineEdit->setMaximumWidth(40*ww);
1130  reqcLayout->addWidget(new QLabel("  Obs"),                     ir, 2);
1131  reqcLayout->addWidget(_reqcOutNavLineEdit,                     ir, 3);
1132  _reqcOutNavLineEdit->setMaximumWidth(40*ww);
1133  reqcLayout->addWidget(new QLabel("  Nav"),                     ir, 4);
1134  ++ir;
1135  reqcLayout->addWidget(new QLabel("Logfile"),                   ir, 0);
1136  reqcLayout->addWidget(_reqcOutLogLineEdit,                     ir, 1);
1137  _reqcOutLogLineEdit->setMaximumWidth(40*ww);
1138  reqcLayout->addWidget(new QLabel("  Summary only"),            ir, 2);
1139  reqcLayout->addWidget(_reqcLogSummaryOnly,                     ir, 3);
1140  ++ir;
1141  reqcLayout->addWidget(new QLabel("Plots for signals"),         ir, 0);
1142  reqcLayout->addWidget(_reqcSkyPlotSignals,                     ir, 1);
1143  _reqcSkyPlotSignals->setMaximumWidth(40*ww);
1144  ++ir;
1145  reqcLayout->addWidget(new QLabel("Directory for plots"),       ir, 0);
1146  reqcLayout->addWidget(_reqcPlotDirLineEdit,                    ir, 1);
1147  _reqcPlotDirLineEdit->setMaximumWidth(40*ww);
1148  ++ir;
1149  reqcLayout->setRowStretch(ir, 999);
1150
1151  reqcLayout->setColumnMinimumWidth(2, 8*ww);
1152  reqcLayout->setColumnMinimumWidth(4, 8*ww);
1153
1154  reqcgroup->setLayout(reqcLayout);
1155
1156  connect(_reqcEditOptionButton, SIGNAL(clicked()),
1157          this, SLOT(slotReqcEditOption()));
1158
1159  QGridLayout* sp3CompLayout = new QGridLayout;
1160
1161  _sp3CompFileChooser = new qtFileChooser(0, qtFileChooser::Files);
1162  _sp3CompFileChooser->setFileName(settings.value("sp3CompFile").toString());
1163  _sp3CompFileChooser->setMinimumWidth(15*ww);
1164  _sp3CompFileChooser->setMaximumWidth(40*ww);
1165
1166  _sp3CompExclude = new QLineEdit(settings.value("sp3CompExclude").toString());
1167  _sp3CompExclude->setMinimumWidth(18*ww);
1168  _sp3CompExclude->setMaximumWidth(18*ww);
1169
1170  _sp3CompLogLineEdit = new QLineEdit(settings.value("sp3CompOutLogFile").toString());
1171  _sp3CompLogLineEdit->setMinimumWidth(18*ww);
1172  _sp3CompLogLineEdit->setMaximumWidth(18*ww);
1173
1174  ir = 0;
1175  sp3CompLayout->addWidget(new QLabel("Orbit and clock comparison.<br>"),  ir, 0, 1, 40);
1176  ++ir;
1177  sp3CompLayout->addWidget(new QLabel("Input SP3 files (full path)"),  ir, 0, Qt::AlignLeft);
1178  sp3CompLayout->addWidget(_sp3CompFileChooser,                        ir, 1, 1, 20);
1179  ++ir;
1180  sp3CompLayout->addWidget(new QLabel("Exclude satellites"),           ir, 0, Qt::AlignLeft);
1181  sp3CompLayout->addWidget(_sp3CompExclude,                            ir, 1, Qt::AlignRight);
1182  ++ir;
1183  sp3CompLayout->addWidget(new QLabel("Logfile"),                      ir, 0, Qt::AlignLeft);
1184  sp3CompLayout->addWidget(_sp3CompLogLineEdit,                        ir, 1, Qt::AlignRight);
1185  ++ir;
1186  sp3CompLayout->addWidget(new QLabel(""),                             ir, 1);
1187  ++ir;
1188  sp3CompLayout->setRowStretch(ir, 999);
1189
1190  sp3CompLayout->setColumnMinimumWidth(2, 8*ww);
1191  sp3CompLayout->setColumnMinimumWidth(4, 8*ww);
1192
1193  sp3CompGroup->setLayout(sp3CompLayout);
1194
1195  connect(_sp3CompFileChooser, SIGNAL(fileNameChanged(const QString &)),
1196          this, SLOT(slotBncTextChanged()));
1197
1198  // Combine Corrections
1199  // -------------------
1200  QGridLayout* cmbLayout = new QGridLayout;
1201
1202  populateCmbTable();
1203  cmbLayout->addWidget(_cmbTable,                                            0, 0, 8, 3);
1204  cmbLayout->addWidget(new QLabel(" Combine Broadcast Correction streams.<br>"), 1, 6, 1, 10);
1205  cmbLayout->addWidget(addCmbRowButton,                                      2, 6);
1206  cmbLayout->addWidget(delCmbRowButton,                                      2, 7);
1207  cmbLayout->addWidget(new QLabel("Method"),                                 3, 6, Qt::AlignRight);
1208  cmbLayout->addWidget(_cmbMethodComboBox,                                   3, 7);
1209  cmbLayout->addWidget(new QLabel(" Maximal residuum"),                      4, 6, Qt::AlignRight);
1210  cmbLayout->addWidget(_cmbMaxresLineEdit,                                   4, 7, Qt::AlignRight);
1211  cmbLayout->addWidget(new QLabel("Sampling"),                               5, 6, Qt::AlignRight);
1212  cmbLayout->addWidget(_cmbSamplSpinBox,                                     5, 7);
1213  cmbLayout->addWidget(new QLabel("   Use GLONASS"),                         6, 6, Qt::AlignRight);
1214  cmbLayout->addWidget(_cmbUseGlonass,                                       6, 7);
1215  cmbLayout->setRowStretch(7, 999);
1216
1217  connect(addCmbRowButton, SIGNAL(clicked()), this, SLOT(slotAddCmbRow()));
1218  connect(delCmbRowButton, SIGNAL(clicked()), this, SLOT(slotDelCmbRow()));
1219
1220  cmbgroup->setLayout(cmbLayout);
1221
1222  // Upload Layout (Clocks)
1223  // ----------------------
1224  QGridLayout* uploadHlpLayout = new QGridLayout();
1225
1226  connect(addUploadRowButton, SIGNAL(clicked()), this, SLOT(slotAddUploadRow()));
1227  connect(delUploadRowButton, SIGNAL(clicked()), this, SLOT(slotDelUploadRow()));
1228  connect(setUploadTrafoButton, SIGNAL(clicked()), this, SLOT(slotSetUploadTrafo()));
1229
1230  uploadHlpLayout->addWidget(addUploadRowButton,                  0, 0);
1231  uploadHlpLayout->addWidget(delUploadRowButton,                  0, 1);
1232  uploadHlpLayout->addWidget(new QLabel("Interval"),              0, 2, Qt::AlignRight);
1233  uploadHlpLayout->addWidget(_uploadIntrComboBox,                 0, 3);
1234  uploadHlpLayout->addWidget(new QLabel("     Sampling:    Orb"), 0, 4, Qt::AlignRight);
1235  uploadHlpLayout->addWidget(_uploadSamplRtcmEphCorrSpinBox,      0, 5);
1236  uploadHlpLayout->addWidget(new QLabel("SP3"),                   0, 6, Qt::AlignRight);
1237  uploadHlpLayout->addWidget(_uploadSamplSp3SpinBox,              0, 7);
1238  uploadHlpLayout->addWidget(new QLabel("RNX"),                   0, 8, Qt::AlignRight);
1239  uploadHlpLayout->addWidget(_uploadSamplClkRnxSpinBox,           0, 9);
1240  uploadHlpLayout->addWidget(setUploadTrafoButton,                0,10);
1241  uploadHlpLayout->addWidget(new QLabel("ANTEX file"),            1, 0, Qt::AlignLeft);
1242  uploadHlpLayout->addWidget(_uploadAntexFile,                    1, 1, 1, 4);
1243
1244  QBoxLayout* uploadLayout = new QBoxLayout(QBoxLayout::TopToBottom);
1245  populateUploadTable();
1246
1247  uploadLayout->addWidget(new QLabel("Upload RTCM Version 3 Broadcast Corrections to caster.<br>"));
1248  uploadLayout->addWidget(_uploadTable);
1249  uploadLayout->addLayout(uploadHlpLayout);
1250
1251  uploadgroup->setLayout(uploadLayout);
1252
1253  // Upload Layout (Ephemeris)
1254  // -------------------------
1255  QGridLayout* uploadHlpLayoutEph = new QGridLayout();
1256
1257  connect(addUploadEphRowButton, SIGNAL(clicked()), this, SLOT(slotAddUploadEphRow()));
1258  connect(delUploadEphRowButton, SIGNAL(clicked()), this, SLOT(slotDelUploadEphRow()));
1259
1260  uploadHlpLayoutEph->addWidget(addUploadEphRowButton,               0, 0);
1261  uploadHlpLayoutEph->addWidget(delUploadEphRowButton,               0, 1);
1262  uploadHlpLayoutEph->addWidget(new QLabel("     Sampling"),         0, 2, Qt::AlignRight);
1263  uploadHlpLayoutEph->addWidget(_uploadSamplRtcmEphSpinBox,          0, 3);
1264
1265  QBoxLayout* uploadLayoutEph = new QBoxLayout(QBoxLayout::TopToBottom);
1266  populateUploadEphTable();
1267
1268  uploadLayoutEph->addWidget(new QLabel("Upload concatenated RTCMv3 Broadcast Ephemeris to caster.<br>"));
1269  uploadLayoutEph->addWidget(_uploadEphTable);
1270  uploadLayoutEph->addLayout(uploadHlpLayoutEph);
1271
1272  uploadEphgroup->setLayout(uploadLayoutEph);
1273
1274
1275  // Main Layout
1276  // -----------
1277  QGridLayout* mLayout = new QGridLayout;
1278  _aogroup->setCurrentIndex(settings.value("startTab").toInt());
1279  mLayout->addWidget(_aogroup,            0,0);
1280  mLayout->addWidget(_mountPointsTable,   1,0);
1281  _loggroup->setCurrentIndex(settings.value("statusTab").toInt());
1282  mLayout->addWidget(_loggroup,           2,0);
1283
1284  _canvas->setLayout(mLayout);
1285
1286  // WhatsThis, Network
1287  // ------------------
1288  _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.</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>"));
1289  _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>"));
1290  _sslCaCertPathLineEdit->setWhatsThis(tr("<p>Communication with an Ntrip Broadcaster over SSL requires the exchange of client and/or server certificates. Specify the path to a directory where you save certificates on your system. Don't try communication via 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: sslCaCertPath]</i></p>"));
1291  _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>"));
1292
1293  // WhatsThis, General
1294  // ------------------
1295  _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>"));
1296  _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>"));
1297  _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>"));
1298  _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>"));
1299  _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>"));
1300
1301  // WhatsThis, RINEX Observations
1302  // -----------------------------
1303  _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>"));
1304  _rnxIntrComboBox->setWhatsThis(tr("<p>Select the length of the RINEX Observation file. <i>[key: rnxIntr]</i></p>"));
1305  _rnxSamplComboBox->setWhatsThis(tr("<p>Select the RINEX Observation sampling interval in seconds. <i>[key: rnxSampl]</i></p>"));
1306  _rnxSkelLineEdit->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. In case of 'SKL'/'skl' the 4-char ID forming the base name has to be written in upper/lower cases. <i>[key: rnxSkel]</i></p>"));
1307  _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>"));
1308  _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>"));
1309  _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>'C:IQX I:ABCX' (System specific signal priorities for BDS and IRNSS) </li><li>'G:12&PWCSLXYN 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&PWCSLXYN_ G:5&IQX_ R:12&PC_ R:3&IQX_ E:16&BCX_ E:578&IQX_ J:1&SLXCZ_ J:26&SLX_ J:5&IQX_ C:IQX_ I:ABCX_ S:1&C_ S:5&IQX_'. <i>[key: rnxV2Priority]</i></p>"));
1310  _rnxV3CheckBox->setWhatsThis(tr("<p>The default format for RINEX Observation files is RINEX Version 2.</p><p>Select 'Version 3' if you want to save observations in RINEX Version 3 format. <i>[key: rnxV3]</i></p>"));
1311
1312  // WhatsThis, RINEX Ephemeris
1313  // --------------------------
1314  _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>"));
1315  _ephIntrComboBox->setWhatsThis(tr("<p>Select the length of the RINEX Navigation file. <i>[key: ephIntr]</i></p>"));
1316  _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>"));
1317  _ephV3CheckBox->setWhatsThis(tr("<p>The default format for output of RINEX Navigation data containing Broadcast Ephemeris is RINEX Version 2.</p><p>Select 'Version 3' if you want to output ephemeris in RINEX Version 3 format. <i>[key: ephV3]</i></p>"));
1318
1319  // WhatsThis, RINEX Editing & QC
1320  // -----------------------------
1321  _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>"));
1322  _reqcEditOptionButton->setWhatsThis(tr("<p>Specify options for editing RINEX Version 2 or 3 files.</p>"));
1323  _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>"));
1324  _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>"));
1325  _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>"));
1326  _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>"));
1327  _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>"));
1328  _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>"));
1329  _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>"));
1330  _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 J:1&2 E:1&7 C:1&6 S:1<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 'C:2&7 E:1&5 G:1&2 J:1&2 R:1&2 S:1&5 I:5&9'. Specifying an empty option string would be overruled by this default. <i>[key: reqcSkyPlotSignals]</i></p>"));
1331
1332  // WhatsThis, SP3 Comparison
1333  // -------------------------
1334  _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>"));
1335  _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>"));
1336  _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>"));
1337
1338  // WhatsThis, Broadcast Corrections
1339  // --------------------------------
1340  _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>"));
1341  _corrIntrComboBox->setWhatsThis(tr("<p>Select the length of Broadcast Ephemeris Correction files. <i>[key: corrIntr]</i></p>"));
1342  _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>"));
1343
1344  // WhatsThis, Feed Engine
1345  // ----------------------
1346  _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>"));
1347  _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>"));
1348  _outSamplComboBox->setWhatsThis(tr("<p>Select a synchronized observation sampling interval in seconds. <i>[key: outSampl]</i></p>"));
1349  _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>"));
1350  _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>"));
1351  _outLockTimeCheckBox->setWhatsThis(tr("<p>Print the lock time in seconds in the feed engine output.<i>[key: outLockTime]</i></p>"));
1352
1353  // WhatsThis, Serial Output
1354  // ------------------------
1355  _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>"));
1356  _serialPortNameLineEdit->setWhatsThis(tr("<p>Enter the serial 'Port name' selected for communication with your serial connected receiver. Valid port names are</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>"));
1357  _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>"));
1358  _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>"));
1359  _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>"));
1360  _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>"));
1361  _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>"));
1362  _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>"));
1363  _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>"));
1364  _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>"));
1365  _serialManualNMEASamplingSpinBox->setWhatsThis(tr("<p>Select a sampling interval in seconds for manual generation and upload of NMEA GGA sentences.</p><p>A sampling rate of '0' means, the 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: serialManualNMEASampling]</i></p>"));
1366
1367  // WhatsThis, Outages
1368  // ------------------
1369  _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>"));
1370  _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>"));
1371  _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>"));
1372  _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>"));
1373
1374  // WhatsThis, Miscellaneous
1375  // ------------------------
1376  _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>"));
1377  _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>"));
1378  _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>"));
1379  _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. <i>[key: miscPort]</i></p>"));
1380
1381  // WhatsThis, PPP (1)
1382  // ------------------
1383  _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.</p>"));
1384  _pppWidgets._rinexObs->setWhatsThis(tr("<p>Specify the RINEX Observation file.</p>"));
1385  _pppWidgets._rinexNav->setWhatsThis(tr("<p>Specify the RINEX Navigation file.</p>"));
1386  _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.</p>"));
1387  _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.</p>"));
1388  _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</li><li>Receiver APC variations</li><li>Satellite APC offsets.</li></ul> Specify the full path to an IGS 'ANTEX file' which contains APC offsets and variations.</p><p>If you don't specify an 'ANTEX file' then observations will not be corrected for APC offsets and variations.</p>"));
1389  _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 (when in real-time PPP mode), or</li><li>the 4-charater station ID of the RINEX Observations file (when in post processing PPP mode).</li></ul></li><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></p><p>Records with exclamation mark '!' in the first column or blank records will be interpreted as comment lines and ignored.</p>"));
1390  _pppWidgets._v3filenames->setWhatsThis(tr("<p>Tick 'Version 3 filenames' to let BNC create so-called extended filenames for PPP logfiles, NMEA files and SINEX Troposphere files following the RINEX Version 3 standard.</p><p>Default is an empty check box, meaning to create filenames following the RINEX Version 2 standard. The file content is not affected by this option. It only concerns the filenames.</p>"));
1391  _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.</p>"));
1392  _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.</p>"));
1393  _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.</p>"));
1394  _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'.</p>"));
1395  _pppWidgets._snxtroSampl->setWhatsThis(tr("<p>Select a 'Sampling' rate for saving troposphere parameters.</p>"));
1396  _pppWidgets._snxtroAc->setWhatsThis(tr("<p>Specify a 3-character abbreviation describing you as the generating Analysis Center (AC) in your SINEX troposphere files.</p>"));
1397  _pppWidgets._snxtroSol->setWhatsThis(tr("<p>Specify a 4-character solution ID to allow a distingtion between different solutions per AC.</p>"));
1398
1399  // WhatsThis, PPP (3)
1400  // ------------------
1401  _pppWidgets._lcGPS->setWhatsThis(tr("<p>Specify which kind of GPS observations you want to use and on which kind of ionosphere-free linear combination of GPS observations you want to base ambiguity resolutions.</p><p><ul><li>Specifying 'P3' means that you request BNC to use code data and so-called P3 ionosphere-free linear combination of code observations.</li><li>'P3&L3' means that you request BNC to use both, code and phase data and so-called P3 and L3 ionosphere-free linear combination of code and phase observations.</li></ul></p><p>Note that most geodetic receivers support the observation of GPS code and phase data. Hence specifying 'P3&L3' would be a good choice when processing data from such a receiver.</p><p>Specifying 'no' means that you don't want BNC to use GPS data. <i>[key: PPP/lcGPS]</i></p>"));
1402  _pppWidgets._lcGLONASS->setWhatsThis(tr("<p>Specify which kind of GLONASS observations you want to use and on which kind of ionosphere-free linear combination of GLONASS observations you want to base ambiguity resolutions.</p><p><ul><li>Specifying 'P3' means that you request BNC to use code data and so-called P3 ionosphere-free linear combination of code observations.</li><li>'L3' means that you request BNC to use phase data and so-called L3 ionosphere-free linear combination of phase observations.</li> <li>'P3&L3' means that you request BNC to use both, code and phase data and so-called P3 and L3 ionosphere-free linear combination of code and phase observations.</li></ul></p><p>Specifying 'no' means that you don't want BNC to use GLONASS data. <i>[key: PPP/lcGLONASS]</i></p>"));
1403  _pppWidgets._lcGalileo->setWhatsThis(tr("<p>Specify which kind of Galileo observations you want to use and on which kind of of ionosphere-free linear combination of Galileo observations you want to base ambiguity resolutions.</p><p><ul><li>Specifying 'P3' means that you request BNC to use code data and so-called P3 ionosphere-free linear combination of code observations.</li><li>'L3' means that you request BNC to use phase data and so-called L3 ionosphere-free linear combination of phase observations.</li> <li>'P3&L3' means that you request BNC to use both, code and phase data and so-called P3 and L3 ionosphere-free linear combination of code and phase observations.</li></ul></p><p>Specifying on of these options makes only sense if Galileo data are part of the processed observation stream.</p><p>Specifying 'no' means that you don't want BNC to use Galileo data. <i>[key: PPP/lcGalileo]</i></p>"));
1404  _pppWidgets._lcBDS->setWhatsThis(tr("<p>Specify which kind of BDS observations you want to use and on which kind of ionosphere-free linear combination of BDS observations you want to base ambiguity resolutions.</p><p><ul><li>Specifying 'P3' means that you request BNC to use code data and so-called P3 ionosphere-free linear combination of code observations.</li><li>'L3' means that you request BNC to use phase data and so-called L3 ionosphere-free linear combination of phase observations.</li> <li>'P3&L3' means that you request BNC to use both, code and phase data and so-called P3 and L3 ionosphere-free linear combination of code and phase observations.</li></ul></p><p>Specifying on of these options makes only sense if BDS data are part of the processed observation stream.</p><p>Specifying 'no' means that you don't want to use BDS data. <i>[key: PPP/lcBDS]</i></p>"));
1405  _pppWidgets._sigmaC1->setWhatsThis(tr("<p>Enter a Sigma for GNSS C1 code observations in meters.</p><p>The higher the sigma you enter, the less the contribution of C1 code observations to a PPP solution from combined code and phase data. 2.0 is likely to be an appropriate choice.</p><p>Default is an empty option field, meaning<br>'Sigma C1 = 2.0' <i>[key: PPP/sigmaC1]</i></p>"));
1406  _pppWidgets._sigmaL1->setWhatsThis(tr("<p>Enter a Sigma for GNSS L1 phase observations in meters.</p><p>The higher the sigma you enter, the less the contribution of 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>"));
1407  _pppWidgets._maxResC1->setWhatsThis(tr("<p>Specify a maximum for residuals from C1 code observations in a PPP solution. '3.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 Rex C1 = 3.0' <i>[key: PPP/maxResC1]</i></p>"));
1408  _pppWidgets._maxResL1->setWhatsThis(tr("<p>Specify a maximum for residuals from L1 code observations in a PPP solution. '0.03' 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 Rex L1 = 0.03' <i>[key: PPP/maxResL1]</i></p>"));
1409  _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>"));
1410  _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>"));
1411  _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>"));
1412  _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>"));
1413
1414  // WhatsThis, Combine Corrections
1415  // ------------------------------
1416  _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. 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. Finally, double click on the 'Weight' field to enter a weight to be applied for this stream in the combination.</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>"));
1417  addCmbRowButton->setWhatsThis(tr("<p>Hit 'Add Row' button to add another line to the 'Combine Corrections' table.</p>"));
1418  delCmbRowButton->setWhatsThis(tr("<p>Hit 'Delete' button to delete the highlighted line(s) from the 'Combine Corrections' table.</p>"));
1419  _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>"));
1420  _cmbMaxresLineEdit->setWhatsThis(tr("<p>BNC combines all incoming clocks according to specified weights. Individual clock estimates that differ by more than 'Maximal 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>"));
1421  _cmbSamplSpinBox->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>"));
1422  _cmbUseGlonass->setWhatsThis(tr("<p>In case the incoming orbit and clock correction stream(s) support GLONASS, you can tick 'Use GLONASS' to produce a GPS plus GLONASS combination solution.</p><p>Default is a GPS-only combination. <i>[key: cmbUseGlonass]</i></p>"));
1423
1424  // WhatsThis, Upload Corrections
1425  // -----------------------------
1426  _uploadTable->setWhatsThis(tr("<p>BNC can upload clock and orbit corrections to Broadcast Ephemeris (Broadcast Corrections) in RTCM Version 3 SSR format. You may have a situation where clocks and orbits 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', 'Mount' and 'Password' fields to enter the Ntrip Broadcaster IP port (default is 80), 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. IGS14) 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/BNC${GPSWD}.sp3<br>Note that '${GPSWD}' produces the GPS Week and Day number in the filename.</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/BNC${GPSWD}.clk<br>Note that '${GPSWD}' produces the GPS Week and Day number in the filename.</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>"));
1427  addUploadRowButton->setWhatsThis(tr("<p>Hit 'Add Row' button to add another line to the 'Upload Corrections' table.</p>"));
1428  delUploadRowButton->setWhatsThis(tr("<p>Hit 'Del Row' button to delete the highlighted line(s) from the 'Upload Corrections' table.</p>"));
1429  _uploadIntrComboBox->setWhatsThis(tr("<p>Select the length of the SP3 and Clock RINEX files. <i>[key: uploadIntr]</i></p>"));
1430  _uploadSamplRtcmEphCorrSpinBox->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>"));
1431  _uploadSamplSp3SpinBox->setWhatsThis(tr("<p>Select a SP3 orbit file sampling interval in minutes.</p><p>A value of zero '0' tells BNC to store all available samples into SP3 orbit files. <i>[key: uploadSamplSp3]</i></p>"));
1432  _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>"));
1433  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>"));
1434  _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>"));
1435
1436  // WhatsThis, Upload Ephemeris
1437  // ---------------------------
1438  _uploadEphTable->setWhatsThis(tr("<p>BNC can upload a Broadcast Ephemeris stream in RTCM Version 3 format. Specify the IP number or URL of an Ntrip Broadcaster to upload the respective stream. <i>[key: uploadEphHost]</i></p>"));
1439  addUploadEphRowButton->setWhatsThis(tr("<p>Hit 'Add Row' button to add another line to the 'Upload Ephemeris' table.</p>"));
1440  delUploadEphRowButton->setWhatsThis(tr("<p>Hit 'Del Row' button to delete the highlighted line(s) from the 'Upload Ephemeris' table.</p>"));
1441  _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>"));
1442
1443  // WhatsThis, Streams Canvas
1444  // -------------------------
1445  _mountPointsTable->setWhatsThis(tr("<p>Streams selected for retrieval are listed in the 'Streams' section. Clicking on 'Add Stream' button opens a window that allows the user to select data streams from an Ntrip Broadcaster according to their mountpoints. To remove a stream from the 'Streams' list, highlight it by clicking on it and hit the 'Delete Stream' button. You can also remove multiple streams by highlighting them using +Shift and +Ctrl.</p><p>BNC automatically allocates one of its internal decoders to a stream based on the stream's 'format' as given in the source-table. BNC allows users to change this selection by editing the decoder string. Double click on the 'decoder' field, enter your preferred decoder and then hit Enter. Accepted decoder strings are 'RTCM_2.x', 'RTCM_3.x' and 'RTNET'.</p><p>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. To do this specify the decoder string as 'ZERO'.</p><p>BNC can also retrieve streams from virtual reference stations (VRS). VRS streams are indicated by a 'yes' in the 'nmea' column. To initiate such stream, the approximate latitude/longitude rover position is sent to the Ntrip Broadcaster together with an approximation for the height. Default values for latitude and longitude can be change according to your requirement. Double click on 'lat' and 'long' fields, enter the values you wish to send and then hit Enter. <i>[key: mountPoints]</i></p>"));
1446  _actAddMountPoints->setWhatsThis(tr("<p>Add stream(s) to selection presented in the 'Streams' canvas.</p>"));
1447  _actDeleteMountPoints->setWhatsThis(tr("<p>Delete stream(s) from selection presented in the 'Streams' canvas.</p>"));
1448  _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>"));
1449  _actStart->setWhatsThis(tr("<p> Start running BNC.</p>"));
1450  _actStop->setWhatsThis(tr("<p> Stop running BNC.</p>"));
1451
1452  // WhatsThis, Log Canvas
1453  // ---------------------
1454  _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>"));
1455  _bncFigure->setWhatsThis(tr("<p>The bandwidth consumption per stream is shown in the 'Throughput' tab in bits per second (bps) or kilobits per second (kbps).</p>"));
1456  _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>"));
1457  _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>"));
1458
1459
1460  // Enable/Disable all Widgets
1461  // --------------------------
1462  slotBncTextChanged();
1463  enableStartStop();
1464
1465  // Auto start
1466  // ----------
1467  if ( Qt::CheckState(settings.value("autoStart").toInt()) == Qt::Checked) {
1468    slotStart();
1469  }
1470}
1471
1472// Destructor
1473////////////////////////////////////////////////////////////////////////////
1474bncWindow::~bncWindow() {
1475  if (_caster) {
1476    delete _caster; BNC_CORE->setCaster(0);
1477  }
1478  if (_casterEph) {
1479    delete _casterEph;
1480  }
1481  delete _bncFigureLate;
1482  delete _bncFigurePPP;
1483  delete _actHelp;
1484  delete _actAbout;
1485  delete _actFlowchart;
1486  delete _actFontSel;
1487  delete _actSaveOpt;
1488  delete _actQuit;
1489  delete _actAddMountPoints;
1490  delete _actDeleteMountPoints;
1491  delete _actMapMountPoints;
1492  delete _actStart;
1493  delete _actStop;
1494  delete _actwhatsthis;
1495  delete _proxyHostLineEdit;
1496  delete _proxyPortLineEdit;
1497  delete _sslCaCertPathLineEdit;
1498  delete _sslIgnoreErrorsCheckBox;
1499  delete _logFileLineEdit;
1500  delete _rawOutFileLineEdit;
1501  delete _rnxAppendCheckBox;
1502  delete _onTheFlyComboBox;
1503  delete _autoStartCheckBox;
1504  delete _rnxPathLineEdit;
1505  delete _rnxIntrComboBox;
1506  delete _rnxSamplComboBox;
1507  delete _rnxFileCheckBox;
1508  delete _rnxSkelLineEdit;
1509  delete _rnxScrpLineEdit;
1510  delete _rnxV3CheckBox;
1511  delete _rnxV2Priority;
1512  delete _ephPathLineEdit;
1513  delete _ephIntrComboBox;
1514  delete _ephOutPortLineEdit;
1515  delete _ephV3CheckBox;
1516  delete _corrPathLineEdit;
1517  delete _corrIntrComboBox;
1518  delete _corrPortLineEdit;
1519  delete _outPortLineEdit;
1520  delete _outWaitSpinBox;
1521  delete _outSamplComboBox;
1522  delete _outFileLineEdit;
1523  delete _outUPortLineEdit;
1524  delete _outLockTimeCheckBox;
1525  delete _serialMountPointLineEdit;
1526  delete _serialPortNameLineEdit;
1527  delete _serialBaudRateComboBox;
1528  delete _serialFlowControlComboBox;
1529  delete _serialDataBitsComboBox;
1530  delete _serialParityComboBox;
1531  delete _serialStopBitsComboBox;
1532  delete _serialAutoNMEAComboBox;
1533  delete _serialFileNMEALineEdit;
1534  delete _serialHeightNMEALineEdit;
1535  delete _serialManualNMEASamplingSpinBox;
1536  delete _adviseObsRateComboBox;
1537  delete _adviseFailSpinBox;
1538  delete _adviseRecoSpinBox;
1539  delete _adviseScriptLineEdit;
1540  delete _miscMountLineEdit;
1541  delete _miscPortLineEdit;
1542  delete _miscIntrComboBox;
1543  delete _miscScanRTCMCheckBox;
1544  _mountPointsTable->deleteLater();
1545  delete _log;
1546  delete _loggroup;
1547  _cmbTable->deleteLater();
1548  delete _cmbMaxresLineEdit;
1549  delete _cmbUseGlonass;
1550  delete _cmbSamplSpinBox;
1551  delete _cmbMethodComboBox;;
1552  _uploadEphTable->deleteLater();
1553  delete _uploadSamplRtcmEphCorrSpinBox;
1554  _uploadTable->deleteLater();
1555  delete _uploadIntrComboBox;
1556  delete _uploadAntexFile;
1557  delete _uploadSamplRtcmEphSpinBox;
1558  delete _uploadSamplSp3SpinBox;
1559  delete _uploadSamplClkRnxSpinBox;
1560  delete _reqcActionComboBox;
1561  delete _reqcObsFileChooser;
1562  delete _reqcNavFileChooser;
1563  delete _reqcOutObsLineEdit;
1564  delete _reqcOutNavLineEdit;
1565  delete _reqcOutLogLineEdit;
1566  delete _reqcPlotDirLineEdit;
1567  delete _reqcSkyPlotSignals;
1568  delete _reqcLogSummaryOnly;
1569  delete _reqcEditOptionButton;
1570  delete _sp3CompFileChooser;
1571  delete _sp3CompExclude;
1572  delete _sp3CompLogLineEdit;
1573  //delete _canvas;
1574}
1575
1576//
1577////////////////////////////////////////////////////////////////////////////
1578void bncWindow::populateMountPointsTable() {
1579
1580  for (int iRow = _mountPointsTable->rowCount()-1; iRow >=0; iRow--) {
1581    _mountPointsTable->removeRow(iRow);
1582  }
1583
1584  bncSettings settings;
1585
1586  QListIterator<QString> it(settings.value("mountPoints").toStringList());
1587  int iRow = 0;
1588  while (it.hasNext()) {
1589    QStringList hlp = it.next().split(" ");
1590    if (hlp.size() < 7) continue;
1591    _mountPointsTable->insertRow(iRow);
1592
1593    QUrl    url(hlp[0]);
1594
1595    QString fullPath = url.host() + QString(":%1").arg(url.port()) + url.path();
1596    QString format(hlp[1]); QString country(hlp[2]); QString latitude(hlp[3]); QString longitude(hlp[4]);
1597    QString nmea(hlp[5]);
1598    if (hlp[6] == "S") {
1599      fullPath = hlp[0].replace(0,2,"");
1600    }
1601    QString ntripVersion = "2";
1602    if (hlp.size() >= 7) {
1603      ntripVersion = (hlp[6]);
1604    }
1605
1606    QTableWidgetItem* it;
1607    it = new QTableWidgetItem(url.userInfo());
1608    it->setFlags(it->flags() & ~Qt::ItemIsEditable);
1609    _mountPointsTable->setItem(iRow, 0, it);
1610
1611    it = new QTableWidgetItem(fullPath);
1612    it->setFlags(it->flags() & ~Qt::ItemIsEditable);
1613    _mountPointsTable->setItem(iRow, 1, it);
1614
1615    it = new QTableWidgetItem(format);
1616    _mountPointsTable->setItem(iRow, 2, it);
1617
1618    it = new QTableWidgetItem(country);
1619    _mountPointsTable->setItem(iRow, 3, it);
1620
1621    if      (nmea == "yes") {
1622      it = new QTableWidgetItem(latitude);
1623      _mountPointsTable->setItem(iRow, 4, it);
1624      it = new QTableWidgetItem(longitude);
1625      _mountPointsTable->setItem(iRow, 5, it);
1626    } else {
1627      it = new QTableWidgetItem(latitude);
1628      it->setFlags(it->flags() & ~Qt::ItemIsEditable);
1629      _mountPointsTable->setItem(iRow, 4, it);
1630
1631      it = new QTableWidgetItem(longitude);
1632      it->setFlags(it->flags() & ~Qt::ItemIsEditable);
1633      _mountPointsTable->setItem(iRow, 5, it);
1634    }
1635
1636    it = new QTableWidgetItem(nmea);
1637    it->setFlags(it->flags() & ~Qt::ItemIsEditable);
1638    _mountPointsTable->setItem(iRow, 6, it);
1639
1640    it = new QTableWidgetItem(ntripVersion);
1641    ////    it->setFlags(it->flags() & ~Qt::ItemIsEditable);
1642    _mountPointsTable->setItem(iRow, 7, it);
1643
1644    bncTableItem* bncIt = new bncTableItem();
1645    bncIt->setFlags(bncIt->flags() & ~Qt::ItemIsEditable);
1646    _mountPointsTable->setItem(iRow, 8, bncIt);
1647
1648    iRow++;
1649  }
1650
1651  _mountPointsTable->sortItems(1);
1652
1653  enableStartStop();
1654}
1655
1656// Retrieve Table
1657////////////////////////////////////////////////////////////////////////////
1658void bncWindow::slotAddMountPoints() {
1659
1660  bncSettings settings;
1661  QString proxyHost = settings.value("proxyHost").toString();
1662  int     proxyPort = settings.value("proxyPort").toInt();
1663  if (proxyHost != _proxyHostLineEdit->text()         ||
1664      proxyPort != _proxyPortLineEdit->text().toInt()) {
1665    int iRet = QMessageBox::question(this, "Question", "Proxy options "
1666                                     "changed. Use the new ones?",
1667                                     QMessageBox::Yes, QMessageBox::No,
1668                                     QMessageBox::NoButton);
1669    if      (iRet == QMessageBox::Yes) {
1670      settings.setValue("proxyHost",   _proxyHostLineEdit->text());
1671      settings.setValue("proxyPort",   _proxyPortLineEdit->text());
1672    }
1673  }
1674
1675  settings.setValue("sslCaCertPath",   _sslCaCertPathLineEdit->text());
1676  settings.setValue("sslIgnoreErrors", _sslIgnoreErrorsCheckBox->checkState());
1677
1678  QMessageBox msgBox;
1679  msgBox.setIcon(QMessageBox::Question);
1680  msgBox.setWindowTitle("Add Stream");
1681  msgBox.setText("Add stream(s) coming from:");
1682
1683  QPushButton* buttonNtrip  = msgBox.addButton(tr("Caster"), QMessageBox::ActionRole);
1684  QPushButton* buttonIP     = msgBox.addButton(tr("TCP/IP port"), QMessageBox::ActionRole);
1685  QPushButton* buttonUDP    = msgBox.addButton(tr("UDP port"), QMessageBox::ActionRole);
1686  QPushButton* buttonSerial = msgBox.addButton(tr("Serial port"), QMessageBox::ActionRole);
1687  QPushButton* buttonCancel = msgBox.addButton(tr("Cancel"), QMessageBox::ActionRole);
1688
1689  msgBox.exec();
1690
1691  if (msgBox.clickedButton() == buttonNtrip) {
1692    bncTableDlg* dlg = new bncTableDlg(this);
1693    dlg->move(this->pos().x()+50, this->pos().y()+50);
1694    connect(dlg, SIGNAL(newMountPoints(QStringList*)),
1695          this, SLOT(slotNewMountPoints(QStringList*)));
1696    dlg->exec();
1697    delete dlg;
1698  } else if (msgBox.clickedButton() == buttonIP) {
1699    bncIpPort* ipp = new bncIpPort(this);
1700    connect(ipp, SIGNAL(newMountPoints(QStringList*)),
1701          this, SLOT(slotNewMountPoints(QStringList*)));
1702    ipp->exec();
1703    delete ipp;
1704  } else if (msgBox.clickedButton() == buttonUDP) {
1705    bncUdpPort* udp = new bncUdpPort(this);
1706    connect(udp, SIGNAL(newMountPoints(QStringList*)),
1707          this, SLOT(slotNewMountPoints(QStringList*)));
1708    udp->exec();
1709    delete udp;
1710  } else if (msgBox.clickedButton() == buttonSerial) {
1711    bncSerialPort* sep = new bncSerialPort(this);
1712    connect(sep, SIGNAL(newMountPoints(QStringList*)),
1713          this, SLOT(slotNewMountPoints(QStringList*)));
1714    sep->exec();
1715    delete sep;
1716  } else if (msgBox.clickedButton() == buttonCancel) {
1717    // Cancel
1718  }
1719
1720  enableStartStop();
1721}
1722
1723// Delete Selected Mount Points
1724////////////////////////////////////////////////////////////////////////////
1725void bncWindow::slotDeleteMountPoints() {
1726
1727  int nRows = _mountPointsTable->rowCount();
1728  bool flg[nRows];
1729  for (int iRow = 0; iRow < nRows; iRow++) {
1730    if (_mountPointsTable->isItemSelected(_mountPointsTable->item(iRow,1))) {
1731      flg[iRow] = true;
1732    }
1733    else {
1734      flg[iRow] = false;
1735    }
1736  }
1737  for (int iRow = nRows-1; iRow >= 0; iRow--) {
1738    if (flg[iRow]) {
1739      _mountPointsTable->removeRow(iRow);
1740    }
1741  }
1742  _actDeleteMountPoints->setEnabled(false);
1743
1744  enableStartStop();
1745}
1746
1747// New Mount Points Selected
1748////////////////////////////////////////////////////////////////////////////
1749void bncWindow::slotNewMountPoints(QStringList* mountPoints) {
1750  int iRow = 0;
1751  QListIterator<QString> it(*mountPoints);
1752  while (it.hasNext()) {
1753    QStringList hlp = it.next().split(" ");
1754    QUrl    url(hlp[0]);
1755    QString fullPath = url.host() + QString(":%1").arg(url.port()) + url.path();
1756    QString format(hlp[1]); QString country(hlp[2]); QString latitude(hlp[3]); QString longitude(hlp[4]);
1757    QString nmea(hlp[5]);
1758    if (hlp[6] == "S") {
1759      fullPath = hlp[0].replace(0,2,"");
1760    }
1761    QString ntripVersion = "2";
1762    if (hlp.size() >= 7) {
1763      ntripVersion = (hlp[6]);
1764    }
1765
1766    _mountPointsTable->insertRow(iRow);
1767
1768    QTableWidgetItem* it;
1769    it = new QTableWidgetItem(url.userInfo());
1770    it->setFlags(it->flags() & ~Qt::ItemIsEditable);
1771    _mountPointsTable->setItem(iRow, 0, it);
1772
1773    it = new QTableWidgetItem(fullPath);
1774    it->setFlags(it->flags() & ~Qt::ItemIsEditable);
1775    _mountPointsTable->setItem(iRow, 1, it);
1776
1777    it = new QTableWidgetItem(format);
1778    _mountPointsTable->setItem(iRow, 2, it);
1779
1780    it = new QTableWidgetItem(country);
1781    _mountPointsTable->setItem(iRow, 3, it);
1782
1783    if      (nmea == "yes") {
1784    it = new QTableWidgetItem(latitude);
1785    _mountPointsTable->setItem(iRow, 4, it);
1786    it = new QTableWidgetItem(longitude);
1787    _mountPointsTable->setItem(iRow, 5, it);
1788    } else {
1789    it = new QTableWidgetItem(latitude);
1790    it->setFlags(it->flags() & ~Qt::ItemIsEditable);
1791    _mountPointsTable->setItem(iRow, 4, it);
1792    it = new QTableWidgetItem(longitude);
1793    it->setFlags(it->flags() & ~Qt::ItemIsEditable);
1794    _mountPointsTable->setItem(iRow, 5, it);
1795    }
1796
1797    it = new QTableWidgetItem(nmea);
1798    it->setFlags(it->flags() & ~Qt::ItemIsEditable);
1799    _mountPointsTable->setItem(iRow, 6, it);
1800
1801    it = new QTableWidgetItem(ntripVersion);
1802    ////it->setFlags(it->flags() & ~Qt::ItemIsEditable);
1803    _mountPointsTable->setItem(iRow, 7, it);
1804
1805    bncTableItem* bncIt = new bncTableItem();
1806    _mountPointsTable->setItem(iRow, 8, bncIt);
1807
1808    iRow++;
1809  }
1810  _mountPointsTable->hideColumn(0);
1811  _mountPointsTable->hideColumn(3);
1812  _mountPointsTable->sortItems(1);
1813  delete mountPoints;
1814
1815  enableStartStop();
1816}
1817
1818// Save Options (serialize)
1819////////////////////////////////////////////////////////////////////////////
1820void bncWindow::slotSaveOptions() {
1821  saveOptions();
1822  bncSettings settings;
1823  settings.sync();
1824}
1825
1826// Save Options (memory only)
1827////////////////////////////////////////////////////////////////////////////
1828void bncWindow::saveOptions() {
1829
1830  QStringList mountPoints;
1831  for (int iRow = 0; iRow < _mountPointsTable->rowCount(); iRow++) {
1832
1833    if (_mountPointsTable->item(iRow, 6)->text() != "S") {
1834      QUrl url( "//" + _mountPointsTable->item(iRow, 0)->text() +
1835                "@"  + _mountPointsTable->item(iRow, 1)->text() );
1836
1837      mountPoints.append(url.toString() + " " +
1838                         _mountPointsTable->item(iRow, 2)->text()
1839                 + " " + _mountPointsTable->item(iRow, 3)->text()
1840                 + " " + _mountPointsTable->item(iRow, 4)->text()
1841                 + " " + _mountPointsTable->item(iRow, 5)->text()
1842                 + " " + _mountPointsTable->item(iRow, 6)->text()
1843                 + " " + _mountPointsTable->item(iRow, 7)->text());
1844    } else {
1845      mountPoints.append(
1846                  "//" + _mountPointsTable->item(iRow, 1)->text()
1847                 + " " + _mountPointsTable->item(iRow, 2)->text()
1848                 + " " + _mountPointsTable->item(iRow, 3)->text()
1849                 + " " + _mountPointsTable->item(iRow, 4)->text()
1850                 + " " + _mountPointsTable->item(iRow, 5)->text()
1851                 + " " + _mountPointsTable->item(iRow, 6)->text()
1852                 + " " + _mountPointsTable->item(iRow, 7)->text());
1853    }
1854  }
1855
1856  QStringList cmbStreams;
1857  for (int iRow = 0; iRow < _cmbTable->rowCount(); iRow++) {
1858    QString hlp;
1859    for (int iCol = 0; iCol < _cmbTable->columnCount(); iCol++) {
1860      if (_cmbTable->item(iRow, iCol)) {
1861        hlp += _cmbTable->item(iRow, iCol)->text() + " ";
1862      }
1863    }
1864    if (!hlp.isEmpty()) {
1865      cmbStreams << hlp;
1866    }
1867  }
1868
1869  QStringList uploadMountpointsOut;
1870  for (int iRow = 0; iRow < _uploadTable->rowCount(); iRow++) {
1871    QString hlp;
1872    for (int iCol = 0; iCol < _uploadTable->columnCount(); iCol++) {
1873      if (_uploadTable->cellWidget(iRow, iCol) &&
1874          (iCol == 3 || iCol == 4 || iCol == 5 || iCol == 6 || iCol == 7)) {
1875        if       (iCol == 3) {
1876          QComboBox* ntripversion = (QComboBox*)(_uploadTable->cellWidget(iRow, iCol));
1877          hlp += ntripversion->currentText() + ",";
1878        }
1879        else if (iCol == 4 ) {
1880          QLineEdit* user = (QLineEdit*)(_uploadTable->cellWidget(iRow, iCol));
1881          hlp += user->text() + ",";
1882        }
1883        else if (iCol == 5) {
1884          QLineEdit* passwd = (QLineEdit*)(_uploadTable->cellWidget(iRow, iCol));
1885          hlp += passwd->text() + ",";
1886        }
1887        else if (iCol == 6) {
1888          QComboBox* system = (QComboBox*)(_uploadTable->cellWidget(iRow, iCol));
1889          hlp += system->currentText() + ",";
1890        }
1891        else if (iCol == 7) {
1892          QCheckBox* com    = (QCheckBox*)(_uploadTable->cellWidget(iRow, iCol));
1893          QString state; state.setNum(com->checkState());
1894          hlp +=  state + ",";
1895        }
1896      }
1897      else if (_uploadTable->item(iRow, iCol)) {
1898        hlp += _uploadTable->item(iRow, iCol)->text() + ",";
1899      }
1900    }
1901    if (!hlp.isEmpty()) {
1902      uploadMountpointsOut << hlp;
1903    }
1904  }
1905
1906  QStringList uploadEphMountpointsOut;
1907  for (int iRow = 0; iRow < _uploadEphTable->rowCount(); iRow++) {
1908    QString hlp;
1909    for (int iCol = 0; iCol < _uploadEphTable->columnCount(); iCol++) {
1910      if (_uploadEphTable->cellWidget(iRow, iCol) &&
1911          (iCol == 3 || iCol == 4 || iCol == 5 || iCol == 6)) {
1912        if       (iCol == 3) {
1913          QComboBox* ntripversion = (QComboBox*)(_uploadEphTable->cellWidget(iRow, iCol));
1914          hlp += ntripversion->currentText() + ",";
1915        }
1916        else if (iCol == 4 ) {
1917          QLineEdit* user = (QLineEdit*)(_uploadEphTable->cellWidget(iRow, iCol));
1918          hlp += user->text() + ",";
1919        }
1920        else if (iCol == 5) {
1921          QLineEdit* passwd = (QLineEdit*)(_uploadEphTable->cellWidget(iRow, iCol));
1922          hlp += passwd->text() + ",";
1923        }
1924        else if (iCol == 6) {
1925          QComboBox* system = (QComboBox*)(_uploadEphTable->cellWidget(iRow, iCol));
1926          hlp += system->currentText() + ",";
1927        }
1928      }
1929      else if (_uploadEphTable->item(iRow, iCol)) {
1930        hlp += _uploadEphTable->item(iRow, iCol)->text() + ",";
1931      }
1932    }
1933    if (!hlp.isEmpty()) {
1934      uploadEphMountpointsOut << hlp;
1935    }
1936  }
1937
1938  bncSettings settings;
1939
1940  settings.setValue("startTab",    _aogroup->currentIndex());
1941  settings.setValue("statusTab",   _loggroup->currentIndex());
1942  settings.setValue("mountPoints", mountPoints);
1943// Network
1944  settings.setValue("proxyHost",   _proxyHostLineEdit->text());
1945  settings.setValue("proxyPort",   _proxyPortLineEdit->text());
1946  settings.setValue("sslCaCertPath",   _sslCaCertPathLineEdit->text());
1947  settings.setValue("sslIgnoreErrors",  _sslIgnoreErrorsCheckBox->checkState());
1948// General
1949  settings.setValue("logFile",     _logFileLineEdit->text());
1950  settings.setValue("rnxAppend",   _rnxAppendCheckBox->checkState());
1951  settings.setValue("onTheFlyInterval", _onTheFlyComboBox->currentText());
1952  settings.setValue("autoStart",   _autoStartCheckBox->checkState());
1953  settings.setValue("rawOutFile",  _rawOutFileLineEdit->text());
1954// RINEX Observations
1955  settings.setValue("rnxPath",      _rnxPathLineEdit->text());
1956  settings.setValue("rnxIntr",      _rnxIntrComboBox->currentText());
1957  settings.setValue("rnxSampl",     _rnxSamplComboBox->currentText());
1958  settings.setValue("rnxSkel",      _rnxSkelLineEdit->text());
1959  settings.setValue("rnxOnlyWithSKL",_rnxFileCheckBox->checkState());
1960  settings.setValue("rnxScript",    _rnxScrpLineEdit->text());
1961  settings.setValue("rnxV2Priority",_rnxV2Priority->text());
1962  settings.setValue("rnxV3",        _rnxV3CheckBox->checkState());
1963// RINEX Ephemeris
1964  settings.setValue("ephPath",       _ephPathLineEdit->text());
1965  settings.setValue("ephIntr",       _ephIntrComboBox->currentText());
1966  settings.setValue("ephOutPort",    _ephOutPortLineEdit->text());
1967  settings.setValue("ephV3",         _ephV3CheckBox->checkState());
1968// Broadcast Corrections
1969  settings.setValue("corrPath",    _corrPathLineEdit->text());
1970  settings.setValue("corrIntr",    _corrIntrComboBox->currentText());
1971  settings.setValue("corrPort",    _corrPortLineEdit->text());
1972// Feed Engine
1973  settings.setValue("outPort",     _outPortLineEdit->text());
1974  settings.setValue("outWait",     _outWaitSpinBox->value());
1975  settings.setValue("outSampl",    _outSamplComboBox->currentText());
1976  settings.setValue("outFile",     _outFileLineEdit->text());
1977  settings.setValue("outLockTime",_outLockTimeCheckBox->checkState());    settings.setValue("outUPort",    _outUPortLineEdit->text());
1978
1979// Serial Output
1980  settings.setValue("serialMountPoint",_serialMountPointLineEdit->text());
1981  settings.setValue("serialPortName",  _serialPortNameLineEdit->text());
1982  settings.setValue("serialBaudRate",  _serialBaudRateComboBox->currentText());
1983  settings.setValue("serialFlowControl",_serialFlowControlComboBox->currentText());
1984  settings.setValue("serialDataBits",  _serialDataBitsComboBox->currentText());
1985  settings.setValue("serialParity",    _serialParityComboBox->currentText());
1986  settings.setValue("serialStopBits",  _serialStopBitsComboBox->currentText());
1987  settings.setValue("serialAutoNMEA",  _serialAutoNMEAComboBox->currentText());
1988  settings.setValue("serialFileNMEA",    _serialFileNMEALineEdit->text());
1989  settings.setValue("serialHeightNMEA",  _serialHeightNMEALineEdit->text());
1990  settings.setValue("serialManualNMEASampling", _serialManualNMEASamplingSpinBox->value());
1991// Outages
1992  settings.setValue("adviseObsRate", _adviseObsRateComboBox->currentText());
1993  settings.setValue("adviseFail",    _adviseFailSpinBox->value());
1994  settings.setValue("adviseReco",    _adviseRecoSpinBox->value());
1995  settings.setValue("adviseScript",  _adviseScriptLineEdit->text());
1996// Miscellaneous
1997  settings.setValue("miscMount",   _miscMountLineEdit->text());
1998  settings.setValue("miscPort",    _miscPortLineEdit->text());
1999  settings.setValue("miscIntr",    _miscIntrComboBox->currentText());
2000  settings.setValue("miscScanRTCM", _miscScanRTCMCheckBox->checkState());
2001// Reqc
2002  settings.setValue("reqcAction",     _reqcActionComboBox->currentText());
2003  settings.setValue("reqcObsFile",    _reqcObsFileChooser->fileName());
2004  settings.setValue("reqcNavFile",    _reqcNavFileChooser->fileName());
2005  settings.setValue("reqcOutObsFile", _reqcOutObsLineEdit->text());
2006  settings.setValue("reqcOutNavFile", _reqcOutNavLineEdit->text());
2007  settings.setValue("reqcOutLogFile", _reqcOutLogLineEdit->text());
2008  settings.setValue("reqcPlotDir",    _reqcPlotDirLineEdit->text());
2009  settings.setValue("reqcSkyPlotSignals", _reqcSkyPlotSignals->text());
2010  settings.setValue("reqcLogSummaryOnly", _reqcLogSummaryOnly->checkState());
2011// SP3 Comparison
2012  settings.setValue("sp3CompFile",       _sp3CompFileChooser->fileName());
2013  settings.setValue("sp3CompExclude",    _sp3CompExclude->text());
2014  settings.setValue("sp3CompOutLogFile", _sp3CompLogLineEdit->text());
2015// Combine Corrections
2016  if (!cmbStreams.isEmpty()) {
2017    settings.setValue("cmbStreams", cmbStreams);
2018  }
2019  else {
2020    settings.setValue("cmbStreams", "");
2021  }
2022  settings.setValue("cmbMethod",     _cmbMethodComboBox->currentText());
2023  settings.setValue("cmbMaxres",     _cmbMaxresLineEdit->text());
2024  settings.setValue("cmbSampl",      _cmbSamplSpinBox->value());
2025  settings.setValue("cmbUseGlonass", _cmbUseGlonass->checkState());
2026// Upload Corrections
2027  if (!uploadMountpointsOut.isEmpty()) {
2028    settings.setValue("uploadMountpointsOut", uploadMountpointsOut);
2029  }
2030  else {
2031    settings.setValue("uploadMountpointsOut", "");
2032  }
2033  settings.setValue("uploadIntr",             _uploadIntrComboBox->currentText());
2034  settings.setValue("uploadSamplRtcmEphCorr", _uploadSamplRtcmEphCorrSpinBox->value());
2035  settings.setValue("uploadSamplSp3",         _uploadSamplSp3SpinBox->value());
2036  settings.setValue("uploadSamplClkRnx",      _uploadSamplClkRnxSpinBox->value());
2037  settings.setValue("uploadAntexFile",        _uploadAntexFile->fileName());
2038// Upload Ephemeris
2039  if (!uploadEphMountpointsOut.isEmpty()) {
2040    settings.setValue("uploadEphMountpointsOut", uploadEphMountpointsOut);
2041  }
2042  else {
2043    settings.setValue("uploadEphMountpointsOut", "");
2044  }
2045  settings.setValue("uploadSamplRtcmEph", _uploadSamplRtcmEphSpinBox->value());
2046
2047  if (_caster) {
2048    _caster->readMountPoints();
2049  }
2050
2051  _pppWidgets.saveOptions();
2052}
2053
2054// All get slots terminated
2055////////////////////////////////////////////////////////////////////////////
2056void bncWindow::slotGetThreadsFinished() {
2057  BNC_CORE->slotMessage("All Get Threads Terminated", true);
2058  delete _caster;    _caster    = 0; BNC_CORE->setCaster(0);
2059  delete _casterEph; _casterEph = 0;
2060  _runningRealTime = false;
2061}
2062
2063// Start It!
2064////////////////////////////////////////////////////////////////////////////
2065void bncWindow::slotStart() {
2066  saveOptions();
2067  if      ( _pppWidgets._dataSource->currentText() == "RINEX Files") {
2068    _runningPPP = true;
2069    enableStartStop();
2070    _caster = new bncCaster(); BNC_CORE->setCaster(_caster);
2071    BNC_CORE->startPPP();
2072    _bncFigurePPP->reset();
2073  }
2074  else if ( !_reqcActionComboBox->currentText().isEmpty() ) {
2075    if (_reqcActionComboBox->currentText() == "Analyze") {
2076      _runningQC = true;
2077      t_reqcAnalyze* reqcAnalyze = new t_reqcAnalyze(this);
2078      connect(reqcAnalyze, SIGNAL(finished()), this, SLOT(slotPostProcessingFinished()));
2079      reqcAnalyze->start();
2080    }
2081    else {
2082      _runningEdit = true;
2083      t_reqcEdit* reqcEdit = new t_reqcEdit(this);
2084      connect(reqcEdit, SIGNAL(finished()), this, SLOT(slotPostProcessingFinished()));
2085      reqcEdit->start();
2086    }
2087    enableStartStop();
2088  }
2089  else if (!_sp3CompFileChooser->fileName().isEmpty()) {
2090    _runningSp3Comp = true;
2091    t_sp3Comp* sp3Comp = new t_sp3Comp(this);
2092    connect(sp3Comp, SIGNAL(finished()), this, SLOT(slotPostProcessingFinished()));
2093    sp3Comp->start();
2094    enableStartStop();
2095  }
2096  else {
2097    startRealTime();
2098    BNC_CORE->startPPP();
2099  }
2100}
2101
2102// Start Real-Time (Retrieve Data etc.)
2103////////////////////////////////////////////////////////////////////////////
2104void bncWindow::startRealTime() {
2105
2106  _runningRealTime = true;
2107
2108  _bncFigurePPP->reset();
2109
2110  _actDeleteMountPoints->setEnabled(false);
2111
2112  enableStartStop();
2113
2114  _caster = new bncCaster();
2115
2116  BNC_CORE->setCaster(_caster);
2117  BNC_CORE->setPortEph(_ephOutPortLineEdit->text().toInt());
2118  BNC_CORE->setPortCorr(_corrPortLineEdit->text().toInt());
2119  BNC_CORE->initCombination();
2120
2121  connect(_caster, SIGNAL(getThreadsFinished()),
2122          this, SLOT(slotGetThreadsFinished()));
2123
2124  connect (_caster, SIGNAL(mountPointsRead(QList<bncGetThread*>)),
2125           this, SLOT(slotMountPointsRead(QList<bncGetThread*>)));
2126
2127  BNC_CORE->slotMessage("========== Start BNC v" BNCVERSION " (" BNC_OS ") ==========", true);
2128
2129  bncSettings settings;
2130
2131  // Active panels
2132  // -------------
2133  if (!_rnxPathLineEdit->text().isEmpty())
2134      BNC_CORE->slotMessage("Panel 'RINEX Observations' active", true);
2135  if (!_ephPathLineEdit->text().isEmpty())
2136      BNC_CORE->slotMessage("Panel 'RINEX Ephemeris' active", true);
2137  if (!_corrPathLineEdit->text().isEmpty())
2138      BNC_CORE->slotMessage("Panel 'Broadcast Corrections' active", true);
2139  if (!_outPortLineEdit->text().isEmpty())
2140      BNC_CORE->slotMessage("Panel 'Feed Engine' active", true);
2141  if (!_serialMountPointLineEdit->text().isEmpty())
2142      BNC_CORE->slotMessage("Panel 'Serial Output' active", true);
2143  if (!_adviseObsRateComboBox->currentText().isEmpty())
2144      BNC_CORE->slotMessage("Panel 'Outages' active", true);
2145  if (!_miscMountLineEdit->text().isEmpty())
2146      BNC_CORE->slotMessage("Panel 'Miscellaneous' active", true);
2147  if (_pppWidgets._dataSource->currentText() == "Real-Time Streams")
2148      BNC_CORE->slotMessage("Panel 'PPP' active", true);
2149  if (_cmbTable->rowCount() > 0)
2150      BNC_CORE->slotMessage("Panel 'Combine Corrections' active", true);
2151  if (_uploadTable->rowCount() > 0)
2152      BNC_CORE->slotMessage("Panel 'Upload Corrections' active", true);
2153  if (_uploadEphTable->rowCount() > 0)
2154      BNC_CORE->slotMessage("Panel 'UploadEphemeris' active", true);
2155
2156  QDir rnxdir(settings.value("rnxPath").toString());
2157  if (!rnxdir.exists()) BNC_CORE->slotMessage("Cannot find RINEX Observations directory", true);
2158
2159  QString rnx_file = settings.value("rnxScript").toString();
2160  if ( !rnx_file.isEmpty() ) {
2161    QFile rnxfile(settings.value("rnxScript").toString());
2162    if (!rnxfile.exists()) BNC_CORE->slotMessage("Cannot find RINEX Observations script", true);
2163  }
2164
2165  QDir ephdir(settings.value("ephPath").toString());
2166  if (!ephdir.exists()) BNC_CORE->slotMessage("Cannot find RINEX Ephemeris directory", true);
2167
2168  QDir corrdir(settings.value("corrPath").toString());
2169  if (!corrdir.exists()) BNC_CORE->slotMessage("Cannot find Broadcast Corrections directory", true);
2170
2171  QString advise_file = settings.value("adviseScript").toString();
2172  if ( !advise_file.isEmpty() ) {
2173    QFile advisefile(settings.value("adviseScript").toString());
2174    if (!advisefile.exists()) BNC_CORE->slotMessage("Cannot find Outages script", true);
2175  }
2176
2177  _caster->readMountPoints();
2178
2179  _casterEph = new bncEphUploadCaster();
2180}
2181
2182// Retrieve Data
2183////////////////////////////////////////////////////////////////////////////
2184void bncWindow::slotStop() {
2185  int iRet = QMessageBox::question(this, "Stop", "Stop retrieving/processing data?",
2186                                   QMessageBox::Yes, QMessageBox::No,
2187                                   QMessageBox::NoButton);
2188  if (iRet == QMessageBox::Yes) {
2189    BNC_CORE->stopPPP();
2190    BNC_CORE->stopCombination();
2191    delete _caster;    _caster    = 0; BNC_CORE->setCaster(0);
2192    delete _casterEph; _casterEph = 0;
2193    _runningRealTime = false;
2194    _runningPPP      = false;
2195    enableStartStop();
2196  }
2197}
2198
2199// Close Application gracefully
2200////////////////////////////////////////////////////////////////////////////
2201void bncWindow::closeEvent(QCloseEvent* event) {
2202
2203  int iRet = QMessageBox::question(this, "Close", "Save Options?",
2204                                   QMessageBox::Yes, QMessageBox::No,
2205                                   QMessageBox::Cancel);
2206
2207  if      (iRet == QMessageBox::Cancel) {
2208    event->ignore();
2209    return;
2210  }
2211  else if (iRet == QMessageBox::Yes) {
2212    slotSaveOptions();
2213  }
2214
2215  BNC_CORE->stopPPP();
2216
2217  QMainWindow::closeEvent(event);
2218}
2219
2220// User changed the selection of mountPoints
2221////////////////////////////////////////////////////////////////////////////
2222void bncWindow::slotSelectionChanged() {
2223  if (_mountPointsTable->selectedItems().isEmpty()) {
2224    _actDeleteMountPoints->setEnabled(false);
2225  }
2226  else {
2227    _actDeleteMountPoints->setEnabled(true);
2228  }
2229}
2230
2231// Display Program Messages
2232////////////////////////////////////////////////////////////////////////////
2233void bncWindow::slotWindowMessage(const QByteArray msg, bool showOnScreen) {
2234  if (showOnScreen ) {
2235    _log->append(QDateTime::currentDateTime().toUTC().toString("yy-MM-dd hh:mm:ss ") + msg);
2236  }
2237}
2238
2239// About Message
2240////////////////////////////////////////////////////////////////////////////
2241void bncWindow::slotAbout() {
2242 new bncAboutDlg(0);
2243}
2244
2245//Flowchart
2246////////////////////////////////////////////////////////////////////////////
2247void bncWindow::slotFlowchart() {
2248 new bncFlowchartDlg(0);
2249}
2250
2251// Help Window
2252////////////////////////////////////////////////////////////////////////////
2253void bncWindow::slotHelp() {
2254  QUrl url = QUrl::fromLocalFile(":/bnchelp.html");
2255  new bncHlpDlg(0, url);
2256}
2257
2258// Select Fonts
2259////////////////////////////////////////////////////////////////////////////
2260void bncWindow::slotFontSel() {
2261  bool ok;
2262  QFont newFont = QFontDialog::getFont(&ok, this->font(), this);
2263  if (ok) {
2264    bncSettings settings;
2265    settings.setValue("font", newFont.toString());
2266    QApplication::setFont(newFont);
2267    int ww = QFontMetrics(newFont).width('w');
2268    setMinimumSize(60*ww, 80*ww);
2269    resize(60*ww, 80*ww);
2270  }
2271}
2272
2273// Whats This Help
2274void bncWindow::slotWhatsThis() {
2275  QWhatsThis::enterWhatsThisMode();
2276}
2277
2278//
2279////////////////////////////////////////////////////////////////////////////
2280void bncWindow::slotMountPointsRead(QList<bncGetThread*> threads) {
2281  _threads = threads;
2282
2283  _bncFigure->updateMountPoints();
2284  _bncFigureLate->updateMountPoints();
2285
2286  populateMountPointsTable();
2287  bncSettings settings;
2288  _outSamplComboBox->findText(settings.value("outSampl").toString());
2289  _outWaitSpinBox->setValue(settings.value("outWait").toInt());
2290  QListIterator<bncGetThread*> iTh(threads);
2291  while (iTh.hasNext()) {
2292    bncGetThread* thread = iTh.next();
2293    for (int iRow = 0; iRow < _mountPointsTable->rowCount(); iRow++) {
2294      QUrl url( "//" + _mountPointsTable->item(iRow, 0)->text() +
2295                "@"  + _mountPointsTable->item(iRow, 1)->text() );
2296      if (url                                      == thread->mountPoint() &&
2297          _mountPointsTable->item(iRow, 4)->text() == thread->latitude()   &&
2298          _mountPointsTable->item(iRow, 5)->text() == thread->longitude() ) {
2299        ((bncTableItem*) _mountPointsTable->item(iRow, 8))->setGetThread(thread);
2300        disconnect(thread, SIGNAL(newBytes(QByteArray, double)),
2301                  _bncFigure, SLOT(slotNewData(QByteArray, double)));
2302        connect(thread, SIGNAL(newBytes(QByteArray, double)),
2303                _bncFigure, SLOT(slotNewData(QByteArray, double)));
2304        disconnect(thread, SIGNAL(newLatency(QByteArray, double)),
2305                   _bncFigureLate, SLOT(slotNewLatency(QByteArray, double)));
2306        connect(thread, SIGNAL(newLatency(QByteArray, double)),
2307                _bncFigureLate, SLOT(slotNewLatency(QByteArray, double)));
2308        break;
2309      }
2310    }
2311  }
2312}
2313
2314//
2315////////////////////////////////////////////////////////////////////////////
2316void bncWindow::CreateMenu() {
2317  // Create Menus
2318  // ------------
2319  _menuFile = menuBar()->addMenu(tr("&File"));
2320  _menuFile->addAction(_actFontSel);
2321  _menuFile->addSeparator();
2322  _menuFile->addAction(_actSaveOpt);
2323  _menuFile->addSeparator();
2324  _menuFile->addAction(_actQuit);
2325
2326  _menuHlp = menuBar()->addMenu(tr("&Help"));
2327  _menuHlp->addAction(_actHelp);
2328  _menuHlp->addAction(_actFlowchart);
2329  _menuHlp->addAction(_actAbout);
2330}
2331
2332// Toolbar
2333////////////////////////////////////////////////////////////////////////////
2334void bncWindow::AddToolbar() {
2335  QToolBar* toolBar = new QToolBar;
2336  addToolBar(Qt::BottomToolBarArea, toolBar);
2337  toolBar->setMovable(false);
2338  toolBar->addAction(_actAddMountPoints);
2339  toolBar->addAction(_actDeleteMountPoints);
2340  toolBar->addAction(_actMapMountPoints);
2341  toolBar->addAction(_actStart);
2342  toolBar->addAction(_actStop);
2343  toolBar->addWidget(new QLabel("                                           "));
2344  toolBar->addAction(_actwhatsthis);
2345}
2346
2347// About
2348////////////////////////////////////////////////////////////////////////////
2349bncAboutDlg::bncAboutDlg(QWidget* parent) :
2350   QDialog(parent) {
2351
2352  QTextBrowser* tb = new QTextBrowser;
2353  QUrl url = QUrl::fromLocalFile(":/bncabout.html");
2354  tb->setSource(url);
2355  tb->setReadOnly(true);
2356
2357  int ww = QFontMetrics(font()).width('w');
2358  QPushButton* _closeButton = new QPushButton("Close");
2359  _closeButton->setMaximumWidth(10*ww);
2360  connect(_closeButton, SIGNAL(clicked()), this, SLOT(close()));
2361
2362  QGridLayout* dlgLayout = new QGridLayout();
2363  QLabel* img = new QLabel();
2364  img->setPixmap(QPixmap(":ntrip-logo.png"));
2365  dlgLayout->addWidget(img, 0,0);
2366  dlgLayout->addWidget(new QLabel("BKG Ntrip Client (BNC) Version " BNCVERSION), 0,1);
2367  dlgLayout->addWidget(tb,1,0,1,2);
2368  dlgLayout->addWidget(_closeButton,2,1,Qt::AlignRight);
2369
2370  setLayout(dlgLayout);
2371  resize(60*ww, 60*ww);
2372  setWindowTitle("About BNC");
2373  show();
2374}
2375
2376//
2377////////////////////////////////////////////////////////////////////////////
2378bncAboutDlg::~bncAboutDlg() {
2379
2380};
2381
2382// Flowchart
2383////////////////////////////////////////////////////////////////////////////
2384bncFlowchartDlg::bncFlowchartDlg(QWidget* parent) :
2385   QDialog(parent) {
2386
2387  int ww = QFontMetrics(font()).width('w');
2388  QPushButton* _closeButton = new QPushButton("Close");
2389  _closeButton->setMaximumWidth(10*ww);
2390  connect(_closeButton, SIGNAL(clicked()), this, SLOT(close()));
2391
2392  QGridLayout* dlgLayout = new QGridLayout();
2393  QLabel* img = new QLabel();
2394  img->setPixmap(QPixmap(":bncflowchart.png"));
2395  dlgLayout->addWidget(img, 0,0);
2396  dlgLayout->addWidget(_closeButton,1,0,Qt::AlignLeft);
2397
2398  setLayout(dlgLayout);
2399  setWindowTitle("Flow Chart");
2400  show();
2401}
2402
2403//
2404////////////////////////////////////////////////////////////////////////////
2405bncFlowchartDlg::~bncFlowchartDlg() {
2406};
2407
2408// Enable/Disable Widget (and change its color)
2409////////////////////////////////////////////////////////////////////////////
2410void bncWindow::enableWidget(bool enable, QWidget* widget) {
2411
2412  const static QPalette paletteWhite(QColor(255, 255, 255));
2413  const static QPalette paletteGray(QColor(230, 230, 230));
2414
2415  widget->setEnabled(enable);
2416  if (enable) {
2417    widget->setPalette(paletteWhite);
2418  }
2419  else {
2420    widget->setPalette(paletteGray);
2421  }
2422}
2423
2424//  Bnc Text
2425////////////////////////////////////////////////////////////////////////////
2426void bncWindow::slotBncTextChanged(){
2427
2428  const static QPalette paletteWhite(QColor(255, 255, 255));
2429  const static QPalette paletteGray(QColor(230, 230, 230));
2430
2431  bool enable = true;
2432
2433  // Proxy
2434  //------
2435  if (sender() == 0 || sender() == _proxyHostLineEdit) {
2436    enable = !_proxyHostLineEdit->text().isEmpty();
2437    enableWidget(enable, _proxyPortLineEdit);
2438  }
2439
2440  // RINEX Observations
2441  // ------------------
2442  if (sender() == 0 || sender() == _rnxPathLineEdit) {
2443    enable = !_rnxPathLineEdit->text().isEmpty();
2444    enableWidget(enable, _rnxIntrComboBox);
2445    enableWidget(enable, _rnxSamplComboBox);
2446    enableWidget(enable, _rnxSkelLineEdit);
2447    enableWidget(enable, _rnxFileCheckBox);
2448    enableWidget(enable, _rnxScrpLineEdit);
2449    enableWidget(enable, _rnxV2Priority);
2450    enableWidget(enable, _rnxV3CheckBox);
2451
2452    bool enable1 = true;
2453    enable1 = _rnxV3CheckBox->isChecked();
2454    if (enable && enable1) {
2455      enableWidget(false, _rnxV2Priority);
2456    }
2457    if (enable && !enable1) {
2458      enableWidget(true, _rnxV2Priority);
2459    }
2460  }
2461
2462  // RINEX Observations, Signal Priority
2463  // -----------------------------------
2464  if (sender() == 0 || sender() == _rnxV3CheckBox) {
2465    if (!_rnxPathLineEdit->text().isEmpty()) {
2466      enableWidget(enable, _rnxIntrComboBox);
2467      enable = !_rnxV3CheckBox->isChecked();
2468      enableWidget(enable, _rnxV2Priority);
2469    }
2470  }
2471
2472  // RINEX Ephemeris
2473  // ---------------
2474  if (sender() == 0 || sender() == _ephPathLineEdit || sender() == _ephOutPortLineEdit) {
2475    enable = !_ephPathLineEdit->text().isEmpty() || !_ephOutPortLineEdit->text().isEmpty();
2476    enableWidget(enable, _ephIntrComboBox);
2477    enableWidget(enable, _ephV3CheckBox);
2478  }
2479
2480  // Broadcast Corrections
2481  // ---------------------
2482  if (sender() == 0 || sender() == _corrPathLineEdit || sender() == _corrPortLineEdit) {
2483    enable = !_corrPathLineEdit->text().isEmpty() || !_corrPortLineEdit->text().isEmpty();
2484    enableWidget(enable, _corrIntrComboBox);
2485  }
2486
2487  // Feed Engine
2488  // -----------
2489  if (sender() == 0 || sender() == _outPortLineEdit || sender() == _outFileLineEdit) {
2490    enable = !_outPortLineEdit->text().isEmpty() || !_outFileLineEdit->text().isEmpty();
2491    enableWidget(enable, _outWaitSpinBox);
2492    enableWidget(enable, _outSamplComboBox);
2493  }
2494
2495  // Serial Output
2496  // -------------
2497  if (sender() == 0 || sender() == _serialMountPointLineEdit ||
2498      sender() == _serialAutoNMEAComboBox) {
2499    enable = !_serialMountPointLineEdit->text().isEmpty();
2500    enableWidget(enable, _serialPortNameLineEdit);
2501    enableWidget(enable, _serialBaudRateComboBox);
2502    enableWidget(enable, _serialParityComboBox);
2503    enableWidget(enable, _serialDataBitsComboBox);
2504    enableWidget(enable, _serialStopBitsComboBox);
2505    enableWidget(enable, _serialFlowControlComboBox);
2506    enableWidget(enable, _serialAutoNMEAComboBox);
2507    bool enable2 = enable && _serialAutoNMEAComboBox->currentText() == "Auto";
2508    enableWidget(enable2, _serialFileNMEALineEdit);
2509    bool enable3 = enable && _serialAutoNMEAComboBox->currentText().contains("Manual");
2510    enableWidget(enable3, _serialHeightNMEALineEdit);
2511    enableWidget(enable3, _serialManualNMEASamplingSpinBox);
2512  }
2513
2514  // Outages
2515  // -------
2516  if (sender() == 0 || sender() == _adviseObsRateComboBox) {
2517    enable = !_adviseObsRateComboBox->currentText().isEmpty();
2518    enableWidget(enable, _adviseFailSpinBox);
2519    enableWidget(enable, _adviseRecoSpinBox);
2520    enableWidget(enable, _adviseScriptLineEdit);
2521  }
2522
2523  // Miscellaneous
2524  // -------------
2525  if (sender() == 0 || sender() == _miscMountLineEdit) {
2526    enable = !_miscMountLineEdit->text().isEmpty();
2527    enableWidget(enable, _miscIntrComboBox);
2528    enableWidget(enable, _miscScanRTCMCheckBox);
2529    enableWidget(enable, _miscPortLineEdit);
2530  }
2531
2532  // Combine Corrections
2533  // -------------------
2534  if (sender() == 0 || sender() == _cmbTable) {
2535    int iRow = _cmbTable->rowCount();
2536    if (iRow > 0) {
2537      enableWidget(true, _cmbMethodComboBox);
2538      enableWidget(true, _cmbMaxresLineEdit);
2539      enableWidget(true, _cmbSamplSpinBox);
2540      enableWidget(true, _cmbUseGlonass);
2541    }
2542    else {
2543      enableWidget(false, _cmbMethodComboBox);
2544      enableWidget(false, _cmbMaxresLineEdit);
2545      enableWidget(false, _cmbSamplSpinBox);
2546      enableWidget(false, _cmbUseGlonass);
2547    }
2548  }
2549
2550  // Upload(clk)
2551  // -----------
2552  int iRow = _uploadTable->rowCount();
2553  if (iRow > 0) {
2554    enableWidget(true, _uploadIntrComboBox);
2555    enableWidget(true, _uploadSamplRtcmEphCorrSpinBox);
2556    enableWidget(true, _uploadSamplClkRnxSpinBox);
2557    enableWidget(true, _uploadSamplSp3SpinBox);
2558    enableWidget(true, _uploadAntexFile);
2559  }
2560  else {
2561    enableWidget(false, _uploadIntrComboBox);
2562    enableWidget(false, _uploadSamplRtcmEphCorrSpinBox);
2563    enableWidget(false, _uploadSamplClkRnxSpinBox);
2564    enableWidget(false, _uploadSamplSp3SpinBox);
2565    enableWidget(false, _uploadAntexFile);
2566  }
2567
2568  // Upload(eph)
2569  // -----------
2570  iRow = _uploadEphTable->rowCount();
2571  if (iRow > 0) {
2572    enableWidget(true, _uploadSamplRtcmEphSpinBox);
2573  }
2574  else {
2575    enableWidget(false, _uploadSamplRtcmEphSpinBox);
2576  }
2577
2578  // QC
2579  // --
2580  if (sender() == 0 || sender() == _reqcActionComboBox || sender() == _reqcSkyPlotSignals) {
2581    enable = !_reqcActionComboBox->currentText().isEmpty();
2582    bool enable10   = _reqcActionComboBox->currentText() == "Edit/Concatenate";
2583//  bool enablePlot = !_reqcSkyPlotSignals->text().isEmpty();
2584    enableWidget(enable,                            _reqcObsFileChooser);
2585    enableWidget(enable,                            _reqcNavFileChooser);
2586    enableWidget(enable,                            _reqcOutLogLineEdit);
2587    enableWidget(enable &&  enable10,               _reqcEditOptionButton);
2588    enableWidget(enable &&  enable10,               _reqcOutObsLineEdit);
2589    enableWidget(enable &&  enable10,               _reqcOutNavLineEdit);
2590    enableWidget(enable && !enable10,               _reqcLogSummaryOnly);
2591    enableWidget(enable && !enable10,               _reqcSkyPlotSignals);
2592//  enableWidget(enable && !enable10 && enablePlot, _reqcPlotDirLineEdit);
2593    enableWidget(enable && !enable10,               _reqcPlotDirLineEdit);
2594  }
2595
2596  // SP3 File Comparison
2597  // -------------------
2598  if (sender() == 0 || sender() == _sp3CompFileChooser) {
2599    enable = !_sp3CompFileChooser->fileName().isEmpty();
2600    enableWidget(enable, _sp3CompLogLineEdit);
2601    enableWidget(enable, _sp3CompExclude);
2602  }
2603
2604  enableStartStop();
2605}
2606
2607//
2608////////////////////////////////////////////////////////////////////////////
2609void bncWindow::slotAddCmbRow() {
2610  int iRow = _cmbTable->rowCount();
2611  _cmbTable->insertRow(iRow);
2612  for (int iCol = 0; iCol < _cmbTable->columnCount(); iCol++) {
2613    _cmbTable->setItem(iRow, iCol, new QTableWidgetItem(""));
2614  }
2615}
2616
2617//
2618////////////////////////////////////////////////////////////////////////////
2619void bncWindow::slotDelCmbRow() {
2620
2621  const static QPalette paletteWhite(QColor(255, 255, 255));
2622  const static QPalette paletteGray(QColor(230, 230, 230));
2623
2624  int nRows = _cmbTable->rowCount();
2625  bool flg[nRows];
2626  for (int iRow = 0; iRow < nRows; iRow++) {
2627    if (_cmbTable->isItemSelected(_cmbTable->item(iRow,1))) {
2628      flg[iRow] = true;
2629    }
2630    else {
2631      flg[iRow] = false;
2632    }
2633  }
2634  for (int iRow = nRows-1; iRow >= 0; iRow--) {
2635    if (flg[iRow]) {
2636      _cmbTable->removeRow(iRow);
2637    }
2638  }
2639  nRows = _cmbTable->rowCount();
2640  if (nRows < 1) {
2641    enableWidget(false, _cmbMethodComboBox);
2642    enableWidget(false, _cmbMaxresLineEdit);
2643    enableWidget(false, _cmbSamplSpinBox);
2644    enableWidget(false, _cmbUseGlonass);
2645  }
2646}
2647
2648//
2649////////////////////////////////////////////////////////////////////////////
2650void bncWindow::populateCmbTable() {
2651
2652  for (int iRow = _cmbTable->rowCount()-1; iRow >=0; iRow--) {
2653    _cmbTable->removeRow(iRow);
2654  }
2655
2656  bncSettings settings;
2657
2658  int iRow = -1;
2659  QListIterator<QString> it(settings.value("cmbStreams").toStringList());
2660  while (it.hasNext()) {
2661    QStringList hlp = it.next().split(" ");
2662    if (hlp.size() > 2) {
2663      ++iRow;
2664      _cmbTable->insertRow(iRow);
2665    }
2666    for (int iCol = 0; iCol < hlp.size(); iCol++) {
2667      _cmbTable->setItem(iRow, iCol, new QTableWidgetItem(hlp[iCol]));
2668    }
2669  }
2670}
2671
2672//
2673////////////////////////////////////////////////////////////////////////////
2674void bncWindow::slotAddUploadRow() {
2675  int iRow = _uploadTable->rowCount();
2676  _uploadTable->insertRow(iRow);
2677  for (int iCol = 0; iCol < _uploadTable->columnCount(); iCol++) {
2678    if (iCol == 3) {
2679      QComboBox* ntripversion = new QComboBox();
2680      ntripversion->setEditable(false);
2681      ntripversion->addItems(QString("1,2,2s").split(","));
2682      ntripversion->setFrame(false);
2683      _uploadTable->setCellWidget(iRow, iCol, ntripversion);
2684
2685    }
2686    else if (iCol == 4) {
2687      QLineEdit* user = new QLineEdit();
2688      user->setFrame(false);
2689      _uploadTable->setCellWidget(iRow, iCol, user);
2690    }
2691    else if (iCol == 5) {
2692      QLineEdit* passwd = new QLineEdit();
2693      passwd->setFrame(false);
2694      passwd->setEchoMode(QLineEdit::PasswordEchoOnEdit);
2695      _uploadTable->setCellWidget(iRow, iCol, passwd);
2696    }
2697    else if (iCol == 6) {
2698      QComboBox* system = new QComboBox();
2699      system->setEditable(false);
2700      system->addItems(QString("IGS14,ETRF2000,GDA2020,SIRGAS2000,DREF91,Custom").split(","));
2701      system->setFrame(false);
2702      _uploadTable->setCellWidget(iRow, iCol, system);
2703    }
2704    else if (iCol == 7) {
2705      QCheckBox* com = new QCheckBox();
2706      _uploadTable->setCellWidget(iRow, iCol, com);
2707    }
2708    else if (iCol == 13) {
2709      bncTableItem* bncIt = new bncTableItem();
2710      bncIt->setFlags(bncIt->flags() & ~Qt::ItemIsEditable);
2711      _uploadTable->setItem(iRow, iCol, bncIt);
2712      BNC_CORE->_uploadTableItems[iRow] = bncIt;
2713    }
2714    else {
2715      _uploadTable->setItem(iRow, iCol, new QTableWidgetItem(""));
2716    }
2717  }
2718}
2719
2720//
2721////////////////////////////////////////////////////////////////////////////
2722void bncWindow::slotDelUploadRow() {
2723  BNC_CORE->_uploadTableItems.clear();
2724  int nRows = _uploadTable->rowCount();
2725  bool flg[nRows];
2726  for (int iRow = 0; iRow < nRows; iRow++) {
2727    if (_uploadTable->isItemSelected(_uploadTable->item(iRow,1))) {
2728      flg[iRow] = true;
2729    }
2730    else {
2731      flg[iRow] = false;
2732    }
2733  }
2734  for (int iRow = nRows-1; iRow >= 0; iRow--) {
2735    if (flg[iRow]) {
2736      _uploadTable->removeRow(iRow);
2737    }
2738  }
2739  for (int iRow = 0; iRow < _uploadTable->rowCount(); iRow++) {
2740    BNC_CORE->_uploadTableItems[iRow] =
2741                                (bncTableItem*) _uploadTable->item(iRow, 11);
2742  }
2743  nRows = _uploadTable->rowCount();
2744  if (nRows < 1) {
2745    enableWidget(false, _uploadIntrComboBox);
2746    enableWidget(false, _uploadSamplRtcmEphCorrSpinBox);
2747    enableWidget(false, _uploadSamplSp3SpinBox);
2748    enableWidget(false, _uploadSamplClkRnxSpinBox);
2749    enableWidget(false, _uploadAntexFile);
2750  }
2751}
2752
2753//
2754////////////////////////////////////////////////////////////////////////////
2755void bncWindow::populateUploadTable() {
2756  for (int iRow = _uploadTable->rowCount()-1; iRow >=0; iRow--) {
2757    _uploadTable->removeRow(iRow);
2758  }
2759
2760  bncSettings settings;
2761
2762  int iRow = -1;
2763  QListIterator<QString> it(settings.value("uploadMountpointsOut").toStringList());
2764
2765  while (it.hasNext()) {
2766    QStringList hlp = it.next().split(",");
2767    if (hlp.size() > 6) {
2768      ++iRow;
2769      _uploadTable->insertRow(iRow);
2770    }
2771    for (int iCol = 0; iCol < hlp.size(); iCol++) {
2772      if      (iCol == 3) {
2773        QComboBox* ntripversion = new QComboBox();
2774        ntripversion->setEditable(false);
2775        ntripversion->addItems(QString("1,2,2s").split(","));
2776        ntripversion->setFrame(false);
2777        ntripversion->setCurrentIndex(ntripversion->findText(hlp[iCol]));
2778        _uploadTable->setCellWidget(iRow, iCol, ntripversion);
2779      }
2780      else if (iCol == 4) {
2781        QLineEdit* user = new QLineEdit();
2782        user->setFrame(false);
2783        user->setText(hlp[iCol]);
2784        _uploadTable->setCellWidget(iRow, iCol, user);
2785      }
2786      else if (iCol == 5) {
2787        QLineEdit* passwd = new QLineEdit();
2788        passwd->setFrame(false);
2789        passwd->setEchoMode(QLineEdit::PasswordEchoOnEdit);
2790        passwd->setText(hlp[iCol]);
2791        _uploadTable->setCellWidget(iRow, iCol, passwd);
2792      }
2793      else if (iCol == 6) {
2794        QComboBox* system = new QComboBox();
2795        system->setEditable(false);
2796        system->addItems(QString("IGS14,ETRF2000,GDA2020,SIRGAS2000,DREF91,Custom").split(","));
2797        system->setFrame(false);
2798        system->setCurrentIndex(system->findText(hlp[iCol]));
2799        _uploadTable->setCellWidget(iRow, iCol, system);
2800      }
2801      else if (iCol == 7) {
2802        QCheckBox* com = new QCheckBox();
2803        if (hlp[iCol].toInt() == Qt::Checked) {
2804          com->setCheckState(Qt::Checked);
2805        }
2806        _uploadTable->setCellWidget(iRow, iCol, com);
2807      }
2808      else if (iCol == 13) {
2809        bncTableItem* bncIt = new bncTableItem();
2810        bncIt->setFlags(bncIt->flags() & ~Qt::ItemIsEditable);
2811        _uploadTable->setItem(iRow, iCol, bncIt);
2812        BNC_CORE->_uploadTableItems[iRow] = bncIt;
2813      }
2814      else {
2815        _uploadTable->setItem(iRow, iCol, new QTableWidgetItem(hlp[iCol]));
2816      }
2817    }
2818  }
2819}
2820
2821//
2822////////////////////////////////////////////////////////////////////////////
2823void bncWindow::slotSetUploadTrafo() {
2824  bncCustomTrafo* dlg = new bncCustomTrafo(this);
2825  dlg->exec();
2826  delete dlg;
2827}
2828
2829//
2830////////////////////////////////////////////////////////////////////////////
2831void bncWindow::slotAddUploadEphRow() {
2832  int iRow = _uploadEphTable->rowCount();
2833  _uploadEphTable->insertRow(iRow);
2834  for (int iCol = 0; iCol < _uploadEphTable->columnCount(); iCol++) {
2835    if      (iCol == 3) {
2836      QComboBox* ntripversion = new QComboBox();
2837      ntripversion->setEditable(false);
2838      ntripversion->addItems(QString("1,2,2s").split(","));
2839      ntripversion->setFrame(false);
2840      _uploadEphTable->setCellWidget(iRow, iCol, ntripversion);
2841
2842    }
2843    else if (iCol == 4) {
2844      QLineEdit* user = new QLineEdit();
2845      user->setFrame(false);
2846      _uploadEphTable->setCellWidget(iRow, iCol, user);
2847    }
2848    else if (iCol == 5) {
2849      QLineEdit* passwd = new QLineEdit();
2850      passwd->setFrame(false);
2851      passwd->setEchoMode(QLineEdit::PasswordEchoOnEdit);
2852      _uploadEphTable->setCellWidget(iRow, iCol, passwd);
2853    }
2854    else if (iCol == 6) {
2855      QComboBox* system = new QComboBox();
2856      system->setEditable(false);
2857      system->addItems(QString("ALL,GPS,GLONASS,Galileo,BDS,QZSS,SBAS").split(","));
2858      system->setFrame(false);
2859      _uploadEphTable->setCellWidget(iRow, iCol, system);
2860    }
2861    else if (iCol == 7) {
2862      bncTableItem* bncIt = new bncTableItem();
2863      bncIt->setFlags(bncIt->flags() & ~Qt::ItemIsEditable);
2864      _uploadEphTable->setItem(iRow, iCol, bncIt);
2865      BNC_CORE->_uploadTableItems[iRow] = bncIt;
2866    }
2867    else {
2868      _uploadEphTable->setItem(iRow, iCol, new QTableWidgetItem(""));
2869    }
2870  }
2871}
2872
2873//
2874////////////////////////////////////////////////////////////////////////////
2875void bncWindow::slotDelUploadEphRow() {
2876  BNC_CORE->_uploadTableItems.clear();
2877  int nRows = _uploadEphTable->rowCount();
2878  bool flg[nRows];
2879  for (int iRow = 0; iRow < nRows; iRow++) {
2880    if (_uploadEphTable->isItemSelected(_uploadEphTable->item(iRow,1))) {
2881      flg[iRow] = true;
2882    }
2883    else {
2884      flg[iRow] = false;
2885    }
2886  }
2887  for (int iRow = nRows-1; iRow >= 0; iRow--) {
2888    if (flg[iRow]) {
2889      _uploadEphTable->removeRow(iRow);
2890    }
2891  }
2892  for (int iRow = 0; iRow < _uploadTable->rowCount(); iRow++) {
2893    BNC_CORE->_uploadTableItems[iRow] =
2894                                (bncTableItem*) _uploadEphTable->item(iRow, 5);
2895  }
2896  nRows = _uploadEphTable->rowCount();
2897  if (nRows < 1) {
2898    enableWidget(false, _uploadSamplRtcmEphSpinBox);
2899  }
2900}
2901
2902//
2903////////////////////////////////////////////////////////////////////////////
2904void bncWindow::populateUploadEphTable() {
2905  for (int iRow = _uploadEphTable->rowCount()-1; iRow >=0; iRow--) {
2906    _uploadEphTable->removeRow(iRow);
2907  }
2908
2909  bncSettings settings;
2910
2911  int iRow = -1;
2912  QListIterator<QString> it(settings.value("uploadEphMountpointsOut").toStringList());
2913  while (it.hasNext()) {
2914    QStringList hlp = it.next().split(",");
2915    if (hlp.size() > 6) {
2916      ++iRow;
2917      _uploadEphTable->insertRow(iRow);
2918    }
2919    for (int iCol = 0; iCol < hlp.size(); iCol++) {
2920      if (iCol == 3) {
2921        QComboBox* ntripversion = new QComboBox();
2922        ntripversion->setEditable(false);
2923        ntripversion->addItems(QString("1,2,2s").split(","));
2924        ntripversion->setFrame(false);
2925        ntripversion->setCurrentIndex(ntripversion->findText(hlp[iCol]));
2926        _uploadEphTable->setCellWidget(iRow, iCol, ntripversion);
2927      }
2928      else if (iCol == 4) {
2929        QLineEdit* user = new QLineEdit();
2930        user->setFrame(false);
2931        _uploadEphTable->setCellWidget(iRow, iCol, user);
2932      }
2933      else if (iCol == 5) {
2934        QLineEdit* passwd = new QLineEdit();
2935        passwd->setFrame(false);
2936        passwd->setEchoMode(QLineEdit::PasswordEchoOnEdit);
2937        passwd->setText(hlp[iCol]);
2938        _uploadEphTable->setCellWidget(iRow, iCol, passwd);
2939      }
2940      else if (iCol == 6) {
2941        QComboBox* system = new QComboBox();
2942        system->setEditable(false);
2943        system->addItems(QString("ALL,GPS,GLONASS,Galileo,BDS,QZSS,SBAS").split(","));
2944        system->setFrame(false);
2945        system->setCurrentIndex(system->findText(hlp[iCol]));
2946        _uploadEphTable->setCellWidget(iRow, iCol, system);
2947      }
2948      else if (iCol == 7) {
2949        bncTableItem* bncIt = new bncTableItem();
2950        bncIt->setFlags(bncIt->flags() & ~Qt::ItemIsEditable);
2951        _uploadEphTable->setItem(iRow, iCol, bncIt);
2952        BNC_CORE->_uploadTableItems[iRow] = bncIt;
2953      }
2954      else {
2955        _uploadEphTable->setItem(iRow, iCol, new QTableWidgetItem(hlp[iCol]));
2956      }
2957    }
2958  }
2959}
2960
2961
2962// Progress Bar Change
2963////////////////////////////////////////////////////////////////////////////
2964void bncWindow::slotPostProcessingProgress(int nEpo) {
2965  _actStart->setText(QString("%1 Epochs").arg(nEpo));
2966}
2967
2968// Post-Processing Reqc Finished
2969////////////////////////////////////////////////////////////////////////////
2970void bncWindow::slotPostProcessingFinished() {
2971  delete _caster; _caster = 0; BNC_CORE->setCaster(0);
2972  _runningPPP     = false;
2973  _runningEdit    = false;
2974  _runningQC      = false;
2975  _runningSp3Comp = false;
2976  _actStart->setText(tr("Sta&rt"));
2977  enableStartStop();
2978}
2979
2980// Edit teqc-like editing options
2981////////////////////////////////////////////////////////////////////////////
2982void bncWindow::slotReqcEditOption() {
2983  saveOptions();
2984  reqcDlg* dlg = new reqcDlg(this);
2985  dlg->move(this->pos().x()+50, this->pos().y()+50);
2986  dlg->exec();
2987  delete dlg;
2988}
2989
2990// Enable/Disable Start and Stop Buttons
2991////////////////////////////////////////////////////////////////////////////
2992void bncWindow::enableStartStop() {
2993  if ( running() ) {
2994    _actStart->setEnabled(false);
2995    if (_runningRealTime || _runningPPP) {
2996      _actStop->setEnabled(true);
2997    }
2998  }
2999  else {
3000    _actStart->setEnabled(true);
3001    _actStop->setEnabled(false);
3002  }
3003}
3004
3005// Show Map
3006////////////////////////////////////////////////////////////////////////////
3007void bncWindow::slotMapMountPoints() {
3008  saveOptions();
3009  t_bncMap* bncMap = new t_bncMap(this);
3010  bncMap->setMinimumSize(800, 600);
3011  bncMap->setWindowTitle("Selected Mountpoints");
3012
3013  bncSettings settings;
3014  QListIterator<QString> it(settings.value("mountPoints").toStringList());
3015  while (it.hasNext()) {
3016    QStringList hlp = it.next().split(" ");
3017    if (hlp.size() < 5) continue;
3018    QUrl   url(hlp[0]);
3019    double latDeg = hlp[3].toDouble();
3020    double lonDeg = hlp[4].toDouble();
3021    bncMap->slotNewPoint(QFileInfo(url.path()).fileName(), latDeg, lonDeg);
3022  }
3023
3024  bncMap->show();
3025}
3026
3027// Show Map
3028////////////////////////////////////////////////////////////////////////////
3029void bncWindow::slotMapPPP() {
3030#ifdef QT_WEBKIT
3031  saveOptions();
3032  enableWidget(false, _pppWidgets._mapWinButton);
3033  enableWidget(false, _pppWidgets._useGoogleMap);
3034  enableWidget(false, _pppWidgets._useOpenStreetMap);
3035  enableWidget(false, _pppWidgets._mapWinDotSize);
3036  enableWidget(false, _pppWidgets._mapWinDotColor);
3037
3038  if (!_mapWin) {
3039    _mapWin = new bncMapWin(this);
3040    connect(_mapWin, SIGNAL(mapClosed()), this, SLOT(slotMapPPPClosed()));
3041    connect(BNC_CORE, SIGNAL(newPosition(QByteArray, bncTime, QVector<double>)),
3042            _mapWin, SLOT(slotNewPosition(QByteArray, bncTime, QVector<double>)));
3043  }
3044  _mapWin->show();
3045#else
3046  QMessageBox::information(this, "Information",
3047                           "Qt Library compiled without QtWebKit");
3048#endif
3049}
3050
3051// Show Map
3052////////////////////////////////////////////////////////////////////////////
3053void bncWindow::slotMapPPPClosed() {
3054#ifdef QT_WEBKIT
3055  enableWidget(true, _pppWidgets._mapWinButton);
3056  enableWidget(true, _pppWidgets._useGoogleMap);
3057  enableWidget(true, _pppWidgets._useOpenStreetMap);
3058  enableWidget(true, _pppWidgets._mapWinDotSize);
3059  enableWidget(true, _pppWidgets._mapWinDotColor);
3060  if (_mapWin) {
3061    QListIterator<bncGetThread*> it(_threads);
3062    while (it.hasNext()) {
3063      bncGetThread* thread = it.next();
3064      thread->disconnect(_mapWin);
3065    }
3066    _mapWin->deleteLater();
3067    _mapWin = 0;
3068  }
3069#endif
3070}
Note: See TracBrowser for help on using the repository browser.