source: ntrip/trunk/BNC/bncwindow.cpp@ 3753

Last change on this file since 3753 was 3750, checked in by habrich, 13 years ago

design edited

File size: 120.4 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 <unistd.h>
44#include "bncwindow.h"
45#include "bncapp.h"
46#include "bncgetthread.h"
47#include "bnctabledlg.h"
48#include "bncipport.h"
49#include "bncudpport.h"
50#include "bncserialport.h"
51#include "bnchlpdlg.h"
52#include "bnchtml.h"
53#include "bnctableitem.h"
54#include "bncsettings.h"
55#include "bncfigure.h"
56#include "bncfigurelate.h"
57#include "bncfigureppp.h"
58#include "bncversion.h"
59#include "bncbytescounter.h"
60#include "bncsslconfig.h"
61#include "upload/bnccustomtrafo.h"
62#include "upload/bncephuploadcaster.h"
63#include "qtfilechooser.h"
64#include "teqcdlg.h"
65#ifdef USE_POSTPROCESSING
66# include "rinex/bncpostprocess.h"
67#endif
68
69using namespace std;
70
71// Constructor
72////////////////////////////////////////////////////////////////////////////
73bncWindow::bncWindow() {
74
75 _caster = 0;
76 _casterEph = 0;
77
78 _bncFigure = new bncFigure(this);
79 _bncFigureLate = new bncFigureLate(this);
80 _bncFigurePPP = new bncFigurePPP(this);
81 _postProcessingRunningPPP = false;
82 _postProcessingRunningTeqc = false;
83
84 int ww = QFontMetrics(this->font()).width('w');
85
86 static const QStringList labels = QString("account, Streams: resource loader / mountpoint, decoder, lat, long, nmea, ntrip, bytes").split(",");
87
88 setMinimumSize(85*ww, 65*ww);
89
90 setWindowTitle(tr("BKG Ntrip Client (BNC) Version " BNCVERSION));
91
92 connect((bncApp*)qApp, SIGNAL(newMessage(QByteArray,bool)),
93 this, SLOT(slotWindowMessage(QByteArray,bool)));
94
95 // Create Actions
96 // --------------
97 _actHelp = new QAction(tr("&Help Contents"),this);
98 connect(_actHelp, SIGNAL(triggered()), SLOT(slotHelp()));
99
100 _actAbout = new QAction(tr("&About BNC"),this);
101 connect(_actAbout, SIGNAL(triggered()), SLOT(slotAbout()));
102
103 _actFlowchart = new QAction(tr("&Flow Chart"),this);
104 connect(_actFlowchart, SIGNAL(triggered()), SLOT(slotFlowchart()));
105
106 _actFontSel = new QAction(tr("Select &Font"),this);
107 connect(_actFontSel, SIGNAL(triggered()), SLOT(slotFontSel()));
108
109 _actSaveOpt = new QAction(tr("&Save && Reread Configuration"),this);
110 connect(_actSaveOpt, SIGNAL(triggered()), SLOT(slotSaveOptions()));
111
112 _actQuit = new QAction(tr("&Quit"),this);
113 connect(_actQuit, SIGNAL(triggered()), SLOT(close()));
114
115 _actAddMountPoints = new QAction(tr("Add &Stream"),this);
116 connect(_actAddMountPoints, SIGNAL(triggered()), SLOT(slotAddMountPoints()));
117
118 _actDeleteMountPoints = new QAction(tr("&Delete Stream"),this);
119 connect(_actDeleteMountPoints, SIGNAL(triggered()), SLOT(slotDeleteMountPoints()));
120 _actDeleteMountPoints->setEnabled(false);
121
122 _actGetData = new QAction(tr("Sta&rt"),this);
123 connect(_actGetData, SIGNAL(triggered()), SLOT(slotGetData()));
124
125 _actPostProcessing = new QAction(tr("Start PPP/Teqc"),this);
126 connect(_actPostProcessing, SIGNAL(triggered()), SLOT(slotStartPostProcessing()));
127
128 _actStop = new QAction(tr("Sto&p"),this);
129 connect(_actStop, SIGNAL(triggered()), SLOT(slotStop()));
130 _actStop->setEnabled(false);
131
132 _actwhatsthis= new QAction(tr("Help ?=Shift+F1"),this);
133 connect(_actwhatsthis, SIGNAL(triggered()), SLOT(slotWhatsThis()));
134
135 CreateMenu();
136 AddToolbar();
137
138 bncSettings settings;
139
140 // Netowrk Options
141 // ---------------
142 _proxyHostLineEdit = new QLineEdit(settings.value("proxyHost").toString());
143 _proxyPortLineEdit = new QLineEdit(settings.value("proxyPort").toString());
144
145 connect(_proxyHostLineEdit, SIGNAL(textChanged(const QString &)),
146 this, SLOT(slotBncTextChanged()));
147
148 _sslCaCertPathLineEdit = new QLineEdit(settings.value("sslCaCertPath").toString());
149 _ignoreSslErrorsCheckBox = new QCheckBox();
150 _ignoreSslErrorsCheckBox->setCheckState(Qt::CheckState(
151 settings.value("ignoreSslErrors").toInt()));
152
153 // General Options
154 // ---------------
155 _logFileLineEdit = new QLineEdit(settings.value("logFile").toString());
156 _rawOutFileLineEdit = new QLineEdit(settings.value("rawOutFile").toString());
157 _rnxAppendCheckBox = new QCheckBox();
158 _rnxAppendCheckBox->setCheckState(Qt::CheckState(
159 settings.value("rnxAppend").toInt()));
160 _onTheFlyComboBox = new QComboBox();
161 _onTheFlyComboBox->setEditable(false);
162 _onTheFlyComboBox->addItems(QString("1 day,1 hour,1 min").split(","));
163 int ii = _onTheFlyComboBox->findText(settings.value("onTheFlyInterval").toString());
164 if (ii != -1) {
165 _onTheFlyComboBox->setCurrentIndex(ii);
166 }
167 _autoStartCheckBox = new QCheckBox();
168 _autoStartCheckBox->setCheckState(Qt::CheckState(
169 settings.value("autoStart").toInt()));
170
171 // RINEX Observations Options
172 // --------------------------
173 _rnxPathLineEdit = new QLineEdit(settings.value("rnxPath").toString());
174 _rnxIntrComboBox = new QComboBox();
175 _rnxIntrComboBox->setEditable(false);
176 _rnxIntrComboBox->addItems(QString("1 min,2 min,5 min,10 min,15 min,30 min,1 hour,1 day").split(","));
177 ii = _rnxIntrComboBox->findText(settings.value("rnxIntr").toString());
178 if (ii != -1) {
179 _rnxIntrComboBox->setCurrentIndex(ii);
180 }
181 _rnxSamplSpinBox = new QSpinBox();
182 _rnxSamplSpinBox->setMinimum(0);
183 _rnxSamplSpinBox->setMaximum(60);
184 _rnxSamplSpinBox->setSingleStep(5);
185 _rnxSamplSpinBox->setValue(settings.value("rnxSampl").toInt());
186 _rnxSamplSpinBox->setSuffix(" sec");
187 _rnxSkelLineEdit = new QLineEdit(settings.value("rnxSkel").toString());
188 _rnxSkelLineEdit->setMaximumWidth(5*ww);
189 _rnxScrpLineEdit = new QLineEdit(settings.value("rnxScript").toString());
190 _rnxV3CheckBox = new QCheckBox();
191 _rnxV3CheckBox->setCheckState(Qt::CheckState(settings.value("rnxV3").toInt()));
192
193 connect(_rnxPathLineEdit, SIGNAL(textChanged(const QString &)),
194 this, SLOT(slotBncTextChanged()));
195
196 // RINEX Ephemeris Options
197 // -----------------------
198 _ephPathLineEdit = new QLineEdit(settings.value("ephPath").toString());
199 _ephIntrComboBox = new QComboBox();
200 _ephIntrComboBox->setEditable(false);
201 _ephIntrComboBox->addItems(QString("1 min,2 min,5 min,10 min,15 min,30 min,1 hour,1 day").split(","));
202 int jj = _ephIntrComboBox->findText(settings.value("ephIntr").toString());
203 if (jj != -1) {
204 _ephIntrComboBox->setCurrentIndex(jj);
205 }
206 _outEphPortLineEdit = new QLineEdit(settings.value("outEphPort").toString());
207 _ephV3CheckBox = new QCheckBox();
208 _ephV3CheckBox->setCheckState(Qt::CheckState(settings.value("ephV3").toInt()));
209
210 connect(_outEphPortLineEdit, SIGNAL(textChanged(const QString &)),
211 this, SLOT(slotBncTextChanged()));
212
213 connect(_ephPathLineEdit, SIGNAL(textChanged(const QString &)),
214 this, SLOT(slotBncTextChanged()));
215
216 // Broadcast Corrections Options
217 // -----------------------------
218 _corrPathLineEdit = new QLineEdit(settings.value("corrPath").toString());
219 _corrIntrComboBox = new QComboBox();
220 _corrIntrComboBox->setEditable(false);
221 _corrIntrComboBox->addItems(QString("1 min,2 min,5 min,10 min,15 min,30 min,1 hour,1 day").split(","));
222 int mm = _corrIntrComboBox->findText(settings.value("corrIntr").toString());
223 if (mm != -1) {
224 _corrIntrComboBox->setCurrentIndex(mm);
225 }
226 _corrPortLineEdit = new QLineEdit(settings.value("corrPort").toString());
227 _corrTimeSpinBox = new QSpinBox();
228 _corrTimeSpinBox->setMinimum(0);
229 _corrTimeSpinBox->setMaximum(60);
230 _corrTimeSpinBox->setSingleStep(1);
231 _corrTimeSpinBox->setSuffix(" sec");
232 _corrTimeSpinBox->setValue(settings.value("corrTime").toInt());
233
234 connect(_corrPathLineEdit, SIGNAL(textChanged(const QString &)),
235 this, SLOT(slotBncTextChanged()));
236
237 connect(_corrPortLineEdit, SIGNAL(textChanged(const QString &)),
238 this, SLOT(slotBncTextChanged()));
239
240 // Feed Engine Options
241 // -------------------
242 _outPortLineEdit = new QLineEdit(settings.value("outPort").toString());
243 _waitTimeSpinBox = new QSpinBox();
244 _waitTimeSpinBox->setMinimum(1);
245 _waitTimeSpinBox->setMaximum(30);
246 _waitTimeSpinBox->setSingleStep(1);
247 _waitTimeSpinBox->setSuffix(" sec");
248 _waitTimeSpinBox->setValue(settings.value("waitTime").toInt());
249 _binSamplSpinBox = new QSpinBox();
250 _binSamplSpinBox->setMinimum(0);
251 _binSamplSpinBox->setMaximum(60);
252 _binSamplSpinBox->setSingleStep(5);
253 _binSamplSpinBox->setValue(settings.value("binSampl").toInt());
254 _binSamplSpinBox->setSuffix(" sec");
255 _outFileLineEdit = new QLineEdit(settings.value("outFile").toString());
256 _outUPortLineEdit = new QLineEdit(settings.value("outUPort").toString());
257
258 connect(_outPortLineEdit, SIGNAL(textChanged(const QString &)),
259 this, SLOT(slotBncTextChanged()));
260
261 connect(_outFileLineEdit, SIGNAL(textChanged(const QString &)),
262 this, SLOT(slotBncTextChanged()));
263
264 // Serial Output Options
265 // ---------------------
266 _serialMountPointLineEdit = new QLineEdit(settings.value("serialMountPoint").toString());
267 _serialPortNameLineEdit = new QLineEdit(settings.value("serialPortName").toString());
268 _serialBaudRateComboBox = new QComboBox();
269 _serialBaudRateComboBox->addItems(QString("110,300,600,"
270 "1200,2400,4800,9600,19200,38400,57600,115200").split(","));
271 int kk = _serialBaudRateComboBox->findText(settings.value("serialBaudRate").toString());
272 if (kk != -1) {
273 _serialBaudRateComboBox->setCurrentIndex(kk);
274 }
275 _serialFlowControlComboBox = new QComboBox();
276 _serialFlowControlComboBox->addItems(QString("OFF,XONXOFF,HARDWARE").split(","));
277 kk = _serialFlowControlComboBox->findText(settings.value("serialFlowControl").toString());
278 if (kk != -1) {
279 _serialFlowControlComboBox->setCurrentIndex(kk);
280 }
281 _serialDataBitsComboBox = new QComboBox();
282 _serialDataBitsComboBox->addItems(QString("5,6,7,8").split(","));
283 kk = _serialDataBitsComboBox->findText(settings.value("serialDataBits").toString());
284 if (kk != -1) {
285 _serialDataBitsComboBox->setCurrentIndex(kk);
286 }
287 _serialParityComboBox = new QComboBox();
288 _serialParityComboBox->addItems(QString("NONE,ODD,EVEN,SPACE").split(","));
289 kk = _serialParityComboBox->findText(settings.value("serialParity").toString());
290 if (kk != -1) {
291 _serialParityComboBox->setCurrentIndex(kk);
292 }
293 _serialStopBitsComboBox = new QComboBox();
294 _serialStopBitsComboBox->addItems(QString("1,2").split(","));
295 kk = _serialStopBitsComboBox->findText(settings.value("serialStopBits").toString());
296 if (kk != -1) {
297 _serialStopBitsComboBox->setCurrentIndex(kk);
298 }
299 _serialAutoNMEAComboBox = new QComboBox();
300 _serialAutoNMEAComboBox->addItems(QString("Auto,Manual").split(","));
301 kk = _serialAutoNMEAComboBox->findText(settings.value("serialAutoNMEA").toString());
302 if (kk != -1) {
303 _serialAutoNMEAComboBox->setCurrentIndex(kk);
304 }
305 _serialFileNMEALineEdit = new QLineEdit(settings.value("serialFileNMEA").toString());
306 _serialHeightNMEALineEdit = new QLineEdit(settings.value("serialHeightNMEA").toString());
307
308 connect(_serialMountPointLineEdit, SIGNAL(textChanged(const QString &)),
309 this, SLOT(slotBncTextChanged()));
310
311 connect(_serialAutoNMEAComboBox, SIGNAL(currentIndexChanged(const QString &)),
312 this, SLOT(slotBncTextChanged()));
313
314 // Outages Options
315 // ---------------
316 _obsRateComboBox = new QComboBox();
317 _obsRateComboBox->setEditable(false);
318 _obsRateComboBox->addItems(QString(",0.1 Hz,0.2 Hz,0.5 Hz,1 Hz,5 Hz").split(","));
319 kk = _obsRateComboBox->findText(settings.value("obsRate").toString());
320 if (kk != -1) {
321 _obsRateComboBox->setCurrentIndex(kk);
322 }
323 _adviseFailSpinBox = new QSpinBox();
324 _adviseFailSpinBox->setMinimum(0);
325 _adviseFailSpinBox->setMaximum(60);
326 _adviseFailSpinBox->setSingleStep(1);
327 _adviseFailSpinBox->setSuffix(" min");
328 _adviseFailSpinBox->setValue(settings.value("adviseFail").toInt());
329 _adviseRecoSpinBox = new QSpinBox();
330 _adviseRecoSpinBox->setMinimum(0);
331 _adviseRecoSpinBox->setMaximum(60);
332 _adviseRecoSpinBox->setSingleStep(1);
333 _adviseRecoSpinBox->setSuffix(" min");
334 _adviseRecoSpinBox->setValue(settings.value("adviseReco").toInt());
335 _adviseScriptLineEdit = new QLineEdit(settings.value("adviseScript").toString());
336
337 connect(_obsRateComboBox, SIGNAL(currentIndexChanged(const QString &)),
338 this, SLOT(slotBncTextChanged()));
339
340 // Miscellaneous Options
341 // ---------------------
342 _miscMountLineEdit = new QLineEdit(settings.value("miscMount").toString());
343 _perfIntrComboBox = new QComboBox();
344 _perfIntrComboBox->setEditable(false);
345 _perfIntrComboBox->addItems(QString(",2 sec, 10 sec,1 min,5 min,15 min,1 hour,6 hours,1 day").split(","));
346 int ll = _perfIntrComboBox->findText(settings.value("perfIntr").toString());
347 if (ll != -1) {
348 _perfIntrComboBox->setCurrentIndex(ll);
349 }
350 _scanRTCMCheckBox = new QCheckBox();
351 _scanRTCMCheckBox->setCheckState(Qt::CheckState(
352 settings.value("scanRTCM").toInt()));
353
354 connect(_miscMountLineEdit, SIGNAL(textChanged(const QString &)),
355 this, SLOT(slotBncTextChanged()));
356
357 // PPP Options
358 // -----------
359 _pppMountLineEdit = new QLineEdit(settings.value("pppMount").toString());
360 _pppMountLineEdit->setMaximumWidth(8*ww);
361 _pppCorrMountLineEdit = new QLineEdit(settings.value("pppCorrMount").toString());
362 _pppCorrMountLineEdit->setMaximumWidth(8*ww);
363 _pppNMEALineEdit = new QLineEdit(settings.value("nmeaFile").toString());
364 _pppNMEAPortLineEdit = new QLineEdit(settings.value("nmeaPort").toString());
365 _pppSigCLineEdit = new QLineEdit(settings.value("pppSigmaCode").toString());
366 _pppSigPLineEdit = new QLineEdit(settings.value("pppSigmaPhase").toString());
367 _pppSigCrd0 = new QLineEdit(settings.value("pppSigCrd0").toString());
368 _pppSigCrdP = new QLineEdit(settings.value("pppSigCrdP").toString());
369 _pppSigTrp0 = new QLineEdit(settings.value("pppSigTrp0").toString());
370 _pppSigTrpP = new QLineEdit(settings.value("pppSigTrpP").toString());
371 _pppAverageLineEdit = new QLineEdit(settings.value("pppAverage").toString());
372 _pppQuickStartLineEdit = new QLineEdit(settings.value("pppQuickStart").toString());
373 _pppMaxSolGapLineEdit = new QLineEdit(settings.value("pppMaxSolGap").toString());
374 _pppRefCrdXLineEdit = new QLineEdit(settings.value("pppRefCrdX").toString());
375 _pppRefCrdYLineEdit = new QLineEdit(settings.value("pppRefCrdY").toString());
376 _pppRefCrdZLineEdit = new QLineEdit(settings.value("pppRefCrdZ").toString());
377 _pppRefdNLineEdit = new QLineEdit(settings.value("pppRefdN").toString());
378 _pppRefdELineEdit = new QLineEdit(settings.value("pppRefdE").toString());
379 _pppRefdULineEdit = new QLineEdit(settings.value("pppRefdU").toString());
380 _pppSync = new QLineEdit(settings.value("pppSync").toString());
381 _pppAntexFileChooser = new qtFileChooser;
382 _pppAntexFileChooser->setMinimumWidth(12*ww);
383 _pppAntennaLineEdit = new QLineEdit(settings.value("pppAntenna").toString());
384 _pppAntennaLineEdit->setMinimumWidth(14*ww);
385 _pppAntexFileChooser->setFileName(settings.value("pppAntex").toString());
386
387
388 _pppSPPComboBox = new QComboBox();
389 _pppSPPComboBox->setEditable(false);
390 _pppSPPComboBox->addItems(QString("PPP,SPP,RNX").split(","));
391 int ik = _pppSPPComboBox->findText(settings.value("pppSPP").toString());
392 if (ik != -1) {
393 _pppSPPComboBox->setCurrentIndex(ik);
394 }
395 _pppUsePhaseCheckBox = new QCheckBox();
396 _pppUsePhaseCheckBox->setCheckState(Qt::CheckState(
397 settings.value("pppUsePhase").toInt()));
398 _pppEstTropoCheckBox = new QCheckBox();
399 _pppEstTropoCheckBox->setCheckState(Qt::CheckState(
400 settings.value("pppEstTropo").toInt()));
401 _pppGLONASSCheckBox = new QCheckBox();
402 _pppGLONASSCheckBox->setCheckState(Qt::CheckState(
403 settings.value("pppGLONASS").toInt()));
404 _pppGalileoCheckBox = new QCheckBox();
405 _pppGalileoCheckBox->setCheckState(Qt::CheckState(
406 settings.value("pppGalileo").toInt()));
407
408 _pppPlotCoordinates = new QCheckBox();
409 _pppPlotCoordinates->setCheckState(Qt::CheckState(
410 settings.value("pppPlotCoordinates").toInt()));
411
412 _pppApplySatAntCheckBox = new QCheckBox();
413 _pppApplySatAntCheckBox->setCheckState(Qt::CheckState(
414 settings.value("pppApplySatAnt").toInt()));
415
416 connect(_pppMountLineEdit, SIGNAL(textChanged(const QString &)),
417 this, SLOT(slotBncTextChanged()));
418
419 connect(_pppCorrMountLineEdit, SIGNAL(textChanged(const QString &)),
420 this, SLOT(slotBncTextChanged()));
421
422 connect(_pppUsePhaseCheckBox, SIGNAL(stateChanged(int)),
423 this, SLOT(slotBncTextChanged()));
424
425 connect(_pppRefCrdXLineEdit, SIGNAL(textChanged(const QString &)),
426 this, SLOT(slotBncTextChanged()));
427 connect(_pppRefCrdYLineEdit, SIGNAL(textChanged(const QString &)),
428 this, SLOT(slotBncTextChanged()));
429 connect(_pppRefCrdZLineEdit, SIGNAL(textChanged(const QString &)),
430 this, SLOT(slotBncTextChanged()));
431 connect(_pppRefdNLineEdit, SIGNAL(textChanged(const QString &)),
432 this, SLOT(slotBncTextChanged()));
433 connect(_pppRefdELineEdit, SIGNAL(textChanged(const QString &)),
434 this, SLOT(slotBncTextChanged()));
435 connect(_pppRefdULineEdit, SIGNAL(textChanged(const QString &)),
436 this, SLOT(slotBncTextChanged()));
437
438 connect(_pppEstTropoCheckBox, SIGNAL(stateChanged(int)),
439 this, SLOT(slotBncTextChanged()));
440
441 connect(_pppSync, SIGNAL(textChanged(const QString &)),
442 this, SLOT(slotBncTextChanged()));
443
444 connect(_pppSPPComboBox, SIGNAL(currentIndexChanged(const QString &)),
445 this, SLOT(slotBncTextChanged()));
446
447 connect(_pppAntexFileChooser, SIGNAL(fileNameChanged(const QString &)),
448 this, SLOT(slotBncTextChanged()));
449
450 connect(_pppQuickStartLineEdit, SIGNAL(textChanged(const QString &)),
451 this, SLOT(slotBncTextChanged()));
452
453 // Streams
454 // -------
455 _mountPointsTable = new QTableWidget(0,8);
456
457 _mountPointsTable->horizontalHeader()->resizeSection(1,34*ww);
458 _mountPointsTable->horizontalHeader()->resizeSection(2,9*ww);
459 _mountPointsTable->horizontalHeader()->resizeSection(3,7*ww);
460 _mountPointsTable->horizontalHeader()->resizeSection(4,7*ww);
461 _mountPointsTable->horizontalHeader()->resizeSection(5,5*ww);
462 _mountPointsTable->horizontalHeader()->resizeSection(6,5*ww);
463 _mountPointsTable->horizontalHeader()->setResizeMode(QHeaderView::Interactive);
464 _mountPointsTable->horizontalHeader()->setStretchLastSection(true);
465 _mountPointsTable->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft);
466 _mountPointsTable->setHorizontalHeaderLabels(labels);
467 _mountPointsTable->setGridStyle(Qt::NoPen);
468 _mountPointsTable->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
469 _mountPointsTable->setSelectionMode(QAbstractItemView::ExtendedSelection);
470 _mountPointsTable->setSelectionBehavior(QAbstractItemView::SelectRows);
471 _mountPointsTable->hideColumn(0);
472 connect(_mountPointsTable, SIGNAL(itemSelectionChanged()),
473 SLOT(slotSelectionChanged()));
474 populateMountPointsTable();
475
476 _log = new QTextBrowser();
477 _log->setReadOnly(true);
478
479 // Combination
480 // -----------
481 _cmbTable = new QTableWidget(0,3);
482 _cmbTable->setHorizontalHeaderLabels(QString("Mountpoint, AC Name, Weight").split(","));
483 _cmbTable->setSelectionMode(QAbstractItemView::ExtendedSelection);
484 _cmbTable->setSelectionBehavior(QAbstractItemView::SelectRows);
485 _cmbTable->setMaximumWidth(30*ww);
486 _cmbTable->horizontalHeader()->resizeSection(0,10*ww);
487 _cmbTable->horizontalHeader()->resizeSection(1,8*ww);
488 _cmbTable->horizontalHeader()->resizeSection(2,8*ww);
489 _cmbTable->horizontalHeader()->setResizeMode(QHeaderView::Interactive);
490 _cmbTable->horizontalHeader()->setStretchLastSection(true);
491 _cmbTable->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft);
492
493 _cmbMaxresLineEdit = new QLineEdit(settings.value("cmbMaxres").toString());
494
495 QPushButton* addCmbRowButton = new QPushButton("Add Row");
496 QPushButton* delCmbRowButton = new QPushButton("Delete");
497
498 connect(_cmbTable, SIGNAL(itemSelectionChanged()),
499 SLOT(slotBncTextChanged()));
500
501 _cmbMethodComboBox = new QComboBox();
502 _cmbMethodComboBox->setEditable(false);
503 _cmbMethodComboBox->addItems(QString("Filter,Single-Epoch").split(","));
504 int im = _cmbMethodComboBox->findText(settings.value("cmbMethod").toString());
505 if (im != -1) {
506 _cmbMethodComboBox->setCurrentIndex(im);
507 }
508
509 // Upload Results
510 // -------------
511 _uploadTable = new QTableWidget(0,9);
512 _uploadTable->setHorizontalHeaderLabels(QString("Host, Port, Mount, Password, System, CoM, SP3 File, RNX File, bytes").split(","));
513 _uploadTable->setSelectionMode(QAbstractItemView::ExtendedSelection);
514 _uploadTable->setSelectionBehavior(QAbstractItemView::SelectRows);
515 _uploadTable->horizontalHeader()->resizeSection(0,13*ww);
516 _uploadTable->horizontalHeader()->resizeSection(1,5*ww);
517 _uploadTable->horizontalHeader()->resizeSection(2,6*ww);
518 _uploadTable->horizontalHeader()->resizeSection(3,8*ww);
519 _uploadTable->horizontalHeader()->resizeSection(4,11*ww);
520 _uploadTable->horizontalHeader()->resizeSection(5,4*ww);
521 _uploadTable->horizontalHeader()->resizeSection(6,15*ww);
522 _uploadTable->horizontalHeader()->resizeSection(7,15*ww);
523 _uploadTable->horizontalHeader()->resizeSection(8,10*ww);
524 _uploadTable->horizontalHeader()->setResizeMode(QHeaderView::Interactive);
525 _uploadTable->horizontalHeader()->setStretchLastSection(true);
526 _uploadTable->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft);
527
528 connect(_uploadTable, SIGNAL(itemSelectionChanged()),
529 SLOT(slotBncTextChanged()));
530
531 QPushButton* addUploadRowButton = new QPushButton("Add Row");
532 QPushButton* delUploadRowButton = new QPushButton("Del Row");
533 QPushButton* setUploadTrafoButton = new QPushButton("Custom Trafo");
534 _uploadIntrComboBox = new QComboBox;
535 _uploadIntrComboBox->setEditable(false);
536 _uploadIntrComboBox->addItems(QString("1 day,1 hour, 30 min,15 min,10 min,5 min,2 min,1 min").split(","));
537 ii = _uploadIntrComboBox->findText(settings.value("uploadIntr").toString());
538 if (ii != -1) {
539 _uploadIntrComboBox->setCurrentIndex(ii);
540 }
541 _uploadSamplSpinBox = new QSpinBox;
542 _uploadSamplSpinBox->setMinimum(5);
543 _uploadSamplSpinBox->setMaximum(60);
544 _uploadSamplSpinBox->setSingleStep(5);
545 _uploadSamplSpinBox->setMaximumWidth(9*ww);
546 _uploadSamplSpinBox->setValue(settings.value("uploadSampl").toInt());
547 _uploadSamplSpinBox->setSuffix(" sec");
548
549 _uploadSamplOrbSpinBox = new QSpinBox;
550 _uploadSamplOrbSpinBox->setMinimum(0);
551 _uploadSamplOrbSpinBox->setMaximum(60);
552 _uploadSamplOrbSpinBox->setSingleStep(5);
553 _uploadSamplOrbSpinBox->setMaximumWidth(9*ww);
554 _uploadSamplOrbSpinBox->setValue(settings.value("uploadSamplOrb").toInt());
555 _uploadSamplOrbSpinBox->setSuffix(" sec");
556
557 // Upload RTCM3 Ephemeris
558 // ----------------------
559 _uploadEphHostLineEdit = new QLineEdit(settings.value("uploadEphHost").toString());
560 _uploadEphPortLineEdit = new QLineEdit(settings.value("uploadEphPort").toString());
561 _uploadEphPasswordLineEdit = new QLineEdit(settings.value("uploadEphPassword").toString());
562 _uploadEphPasswordLineEdit->setEchoMode(QLineEdit::PasswordEchoOnEdit);
563 _uploadEphMountpointLineEdit = new QLineEdit(settings.value("uploadEphMountpoint").toString());
564 _uploadEphSampleSpinBox = new QSpinBox;
565 _uploadEphSampleSpinBox->setMinimum(5);
566 _uploadEphSampleSpinBox->setMaximum(60);
567 _uploadEphSampleSpinBox->setSingleStep(5);
568 _uploadEphSampleSpinBox->setMaximumWidth(9*ww);
569 _uploadEphSampleSpinBox->setValue(settings.value("uploadEphSample").toInt());
570 _uploadEphSampleSpinBox->setSuffix(" sec");
571 _uploadEphBytesCounter = new bncBytesCounter;
572
573 // Canvas with Editable Fields
574 // ---------------------------
575 _canvas = new QWidget;
576 setCentralWidget(_canvas);
577
578 _aogroup = new QTabWidget();
579 QWidget* pgroup = new QWidget();
580 QWidget* ggroup = new QWidget();
581 QWidget* sgroup = new QWidget();
582 QWidget* egroup = new QWidget();
583 QWidget* agroup = new QWidget();
584 QWidget* cgroup = new QWidget();
585 QWidget* ogroup = new QWidget();
586 QWidget* rgroup = new QWidget();
587 QWidget* sergroup = new QWidget();
588 QWidget* pppgroup = new QWidget();
589 QWidget* ppp2group = new QWidget();
590 QWidget* teqcgroup = new QWidget();
591 QWidget* cmbgroup = new QWidget();
592 QWidget* uploadgroup = new QWidget();
593 QWidget* uploadEphgroup = new QWidget();
594 _aogroup->addTab(pgroup,tr("Network"));
595 _aogroup->addTab(ggroup,tr("General"));
596 _aogroup->addTab(ogroup,tr("RINEX Observations"));
597 _aogroup->addTab(egroup,tr("RINEX Ephemeris"));
598 _aogroup->addTab(cgroup,tr("Broadcast Corrections"));
599 _aogroup->addTab(sgroup,tr("Feed Engine"));
600 _aogroup->addTab(sergroup,tr("Serial Output"));
601 _aogroup->addTab(agroup,tr("Outages"));
602 _aogroup->addTab(rgroup,tr("Miscellaneous"));
603 _aogroup->addTab(pppgroup,tr("PPP (1)")); _tabIndexPPP1 = _aogroup->count() - 1;
604 _aogroup->addTab(ppp2group,tr("PPP (2)")); _tabIndexPPP2 = _aogroup->count() - 1;
605 _aogroup->addTab(teqcgroup,tr("Teqc")); _tabIndexTeqc = _aogroup->count() - 1;
606#ifdef USE_COMBINATION
607 _aogroup->addTab(cmbgroup,tr("Combination"));
608#endif
609 _aogroup->addTab(uploadgroup,tr("Upload (clk)"));
610 _aogroup->addTab(uploadEphgroup,tr("Upload (eph)"));
611
612 connect(_aogroup, SIGNAL(currentChanged(int)),
613 this, SLOT(slotEnablePostProcessing()));
614
615 // Log Tab
616 // -------
617 _loggroup = new QTabWidget();
618 _loggroup->addTab(_log,tr("Log"));
619 _loggroup->addTab(_bncFigure,tr("Throughput"));
620 _loggroup->addTab(_bncFigureLate,tr("Latency"));
621 _loggroup->addTab(_bncFigurePPP,tr("PPP Plot"));
622
623 // Netowork (Proxy and SSL) Tab
624 // ----------------------------
625 QGridLayout* pLayout = new QGridLayout;
626 pLayout->setColumnMinimumWidth(0,13*ww);
627 _proxyPortLineEdit->setMaximumWidth(9*ww);
628
629 pLayout->addWidget(new QLabel("Proxy host"), 0, 0);
630 pLayout->addWidget(_proxyHostLineEdit, 0, 1, 1,10);
631 pLayout->addWidget(new QLabel("Proxy port"), 1, 0);
632 pLayout->addWidget(_proxyPortLineEdit, 1, 1);
633 pLayout->addWidget(new QLabel("Settings for proxy in protected networks, leave boxes blank if none."),2, 0, 1, 50, Qt::AlignLeft);
634 pLayout->addWidget(new QLabel(" "),3,0);
635 pLayout->addWidget(new QLabel(" "),4,0);
636 pLayout->addWidget(new QLabel("Path to SSL Certificates"), 5, 0);
637 pLayout->addWidget(_sslCaCertPathLineEdit, 5, 1, 1,10);
638 pLayout->addWidget(new QLabel("default: " + bncSslConfig::defaultPath()), 5, 12, 1,20);
639 pLayout->addWidget(new QLabel("Ignore SSL Authorization Errors"), 6,0);
640 pLayout->addWidget(_ignoreSslErrorsCheckBox, 6, 1, 1,10);
641 pLayout->addWidget(new QLabel("Settings for SSL Authorization."),7, 0, 1, 50, Qt::AlignLeft);
642 pgroup->setLayout(pLayout);
643
644 // General Tab
645 // -----------
646 QGridLayout* gLayout = new QGridLayout;
647 gLayout->setColumnMinimumWidth(0,14*ww);
648 _onTheFlyComboBox->setMaximumWidth(9*ww);
649
650 gLayout->addWidget(new QLabel("Logfile (full path)"), 0, 0);
651 gLayout->addWidget(_logFileLineEdit, 0, 1, 1,30); // 1
652 gLayout->addWidget(new QLabel("Append files"), 1, 0);
653 gLayout->addWidget(_rnxAppendCheckBox, 1, 1);
654 gLayout->addWidget(new QLabel("Reread configuration"), 2, 0);
655 gLayout->addWidget(_onTheFlyComboBox, 2, 1);
656 gLayout->addWidget(new QLabel("Auto start"), 3, 0);
657 gLayout->addWidget(_autoStartCheckBox, 3, 1);
658 gLayout->addWidget(new QLabel("Raw output file (full path)"), 4, 0);
659 gLayout->addWidget(_rawOutFileLineEdit, 4, 1, 1,30);
660 gLayout->addWidget(new QLabel("General settings for logfile, file handling, configuration on-the-fly, and auto-start."),5, 0, 1, 50, Qt::AlignLeft);
661 ggroup->setLayout(gLayout);
662
663 // RINEX Observations
664 // ------------------
665 QGridLayout* oLayout = new QGridLayout;
666 oLayout->setColumnMinimumWidth(0,14*ww);
667 _rnxIntrComboBox->setMaximumWidth(9*ww);
668 _rnxSamplSpinBox->setMaximumWidth(9*ww);
669
670 oLayout->addWidget(new QLabel("Directory"), 0, 0);
671 oLayout->addWidget(_rnxPathLineEdit, 0, 1,1,24);
672 oLayout->addWidget(new QLabel("Interval"), 1, 0);
673 oLayout->addWidget(_rnxIntrComboBox, 1, 1);
674 oLayout->addWidget(new QLabel(" Sampling"), 1, 2, Qt::AlignRight);
675 oLayout->addWidget(_rnxSamplSpinBox, 1, 3, Qt::AlignLeft);
676 oLayout->addWidget(new QLabel("Skeleton extension"), 2, 0);
677 oLayout->addWidget(_rnxSkelLineEdit, 2, 1,1,1, Qt::AlignLeft);
678 oLayout->addWidget(new QLabel("Script (full path)"), 3, 0);
679 oLayout->addWidget(_rnxScrpLineEdit, 3, 1,1,24);
680 oLayout->addWidget(new QLabel("Version 3"), 4, 0);
681 oLayout->addWidget(_rnxV3CheckBox, 4, 1);
682 oLayout->addWidget(new QLabel("Saving RINEX observation files."),5,0,1,50, Qt::AlignLeft);
683 ogroup->setLayout(oLayout);
684
685 // RINEX Ephemeris
686 // ---------------
687 QGridLayout* eLayout = new QGridLayout;
688 eLayout->setColumnMinimumWidth(0,14*ww);
689 _ephIntrComboBox->setMaximumWidth(9*ww);
690 _outEphPortLineEdit->setMaximumWidth(9*ww);
691
692 eLayout->addWidget(new QLabel("Directory"), 0, 0);
693 eLayout->addWidget(_ephPathLineEdit, 0, 1, 1,30);
694 eLayout->addWidget(new QLabel("Interval"), 1, 0);
695 eLayout->addWidget(_ephIntrComboBox, 1, 1);
696 eLayout->addWidget(new QLabel("Port"), 2, 0);
697 eLayout->addWidget(_outEphPortLineEdit, 2, 1);
698 eLayout->addWidget(new QLabel("Version 3"), 3, 0);
699 eLayout->addWidget(_ephV3CheckBox, 3, 1);
700 eLayout->addWidget(new QLabel("Saving RINEX ephemeris files and ephemeris output through IP port."),4,0,1,50,Qt::AlignLeft);
701 eLayout->addWidget(new QLabel(" "),5,0);
702 egroup->setLayout(eLayout);
703
704
705 // Broadcast Corrections
706 // ---------------------
707 QGridLayout* cLayout = new QGridLayout;
708 cLayout->setColumnMinimumWidth(0,14*ww);
709 _corrIntrComboBox->setMaximumWidth(9*ww);
710 _corrPortLineEdit->setMaximumWidth(9*ww);
711 _corrTimeSpinBox->setMaximumWidth(9*ww);
712
713 cLayout->addWidget(new QLabel("Directory, ASCII"), 0, 0);
714 cLayout->addWidget(_corrPathLineEdit, 0, 1,1,20);
715 cLayout->addWidget(new QLabel("Interval"), 1, 0);
716 cLayout->addWidget(_corrIntrComboBox, 1, 1);
717 cLayout->addWidget(new QLabel("Port"), 2, 0);
718 cLayout->addWidget(_corrPortLineEdit, 2, 1);
719 cLayout->addWidget(new QLabel(" Wait for full epoch"), 2, 2, Qt::AlignRight);
720 cLayout->addWidget(_corrTimeSpinBox, 2, 3, Qt::AlignLeft);
721 cLayout->addWidget(new QLabel("Saving Broadcast Ephemeris correction files and correction output through IP port."),3,0,1,50);
722 cLayout->addWidget(new QLabel(" "),4,0);
723 cLayout->addWidget(new QLabel(" "),5,0);
724 cgroup->setLayout(cLayout);
725
726 // Feed Engine
727 // -----------
728 QGridLayout* sLayout = new QGridLayout;
729 sLayout->setColumnMinimumWidth(0,14*ww);
730 _outPortLineEdit->setMaximumWidth(9*ww);
731 _waitTimeSpinBox->setMaximumWidth(9*ww);
732 _binSamplSpinBox->setMaximumWidth(9*ww);
733 _outUPortLineEdit->setMaximumWidth(9*ww);
734
735 sLayout->addWidget(new QLabel("Port"), 0, 0);
736 sLayout->addWidget(_outPortLineEdit, 0, 1);
737 sLayout->addWidget(new QLabel("Wait for full epoch"), 0, 2, Qt::AlignRight);
738 sLayout->addWidget(_waitTimeSpinBox, 0, 3, Qt::AlignLeft);
739 sLayout->addWidget(new QLabel("Sampling"), 1, 0);
740 sLayout->addWidget(_binSamplSpinBox, 1, 1, Qt::AlignLeft);
741 sLayout->addWidget(new QLabel("File (full path)"), 2, 0);
742 sLayout->addWidget(_outFileLineEdit, 2, 1, 1, 20);
743 sLayout->addWidget(new QLabel("Port (unsynchronized)"), 3, 0);
744 sLayout->addWidget(_outUPortLineEdit, 3, 1);
745 sLayout->addWidget(new QLabel("Output decoded observations in a binary format to feed a real-time GNSS network engine."),4,0,1,50);
746 sLayout->addWidget(new QLabel(" "),5,0);
747 sgroup->setLayout(sLayout);
748
749 // Serial Output
750 // -------------
751 QGridLayout* serLayout = new QGridLayout;
752 serLayout->setColumnMinimumWidth(0,14*ww);
753 _serialBaudRateComboBox->setMaximumWidth(9*ww);
754 _serialFlowControlComboBox->setMaximumWidth(11*ww);
755 _serialDataBitsComboBox->setMaximumWidth(5*ww);
756 _serialParityComboBox->setMaximumWidth(9*ww);
757 _serialStopBitsComboBox->setMaximumWidth(5*ww);
758 _serialAutoNMEAComboBox->setMaximumWidth(9*ww);
759 _serialHeightNMEALineEdit->setMaximumWidth(8*ww);
760
761 serLayout->addWidget(new QLabel("Mountpoint"), 0,0, Qt::AlignLeft);
762 serLayout->addWidget(_serialMountPointLineEdit, 0,1,1,2);
763 serLayout->addWidget(new QLabel("Port name"), 1,0, Qt::AlignLeft);
764 serLayout->addWidget(_serialPortNameLineEdit, 1,1,1,2);
765 serLayout->addWidget(new QLabel("Baud rate"), 2,0, Qt::AlignLeft);
766 serLayout->addWidget(_serialBaudRateComboBox, 2,1);
767 serLayout->addWidget(new QLabel("Flow control"), 2,2, Qt::AlignRight);
768 serLayout->addWidget(_serialFlowControlComboBox, 2,3);
769 serLayout->addWidget(new QLabel("Data bits"), 3,0, Qt::AlignLeft);
770 serLayout->addWidget(_serialDataBitsComboBox, 3,1);
771 serLayout->addWidget(new QLabel("Parity"), 3,2, Qt::AlignRight);
772 serLayout->addWidget(_serialParityComboBox, 3,3);
773 serLayout->addWidget(new QLabel(" Stop bits"), 3,4, Qt::AlignRight);
774 serLayout->addWidget(_serialStopBitsComboBox, 3,5);
775 serLayout->addWidget(new QLabel("NMEA"), 4,0);
776 serLayout->addWidget(_serialAutoNMEAComboBox, 4,1);
777 serLayout->addWidget(new QLabel(" File (full path)"), 4,2, Qt::AlignRight);
778 serLayout->addWidget(_serialFileNMEALineEdit, 4,3,1,15);
779 serLayout->addWidget(new QLabel("Height"), 4,20, Qt::AlignRight);
780 serLayout->addWidget(_serialHeightNMEALineEdit, 4,21,1,11);
781 serLayout->addWidget(new QLabel("Port settings to feed a serial connected receiver."),5,0,1,30);
782
783 sergroup->setLayout(serLayout);
784
785 // Outages
786 // -------
787 QGridLayout* aLayout = new QGridLayout;
788 aLayout->setColumnMinimumWidth(0,14*ww);
789 _obsRateComboBox->setMaximumWidth(9*ww);
790 _adviseFailSpinBox->setMaximumWidth(9*ww);
791 _adviseRecoSpinBox->setMaximumWidth(9*ww);
792
793 aLayout->addWidget(new QLabel("Observation rate"), 0, 0);
794 aLayout->addWidget(_obsRateComboBox, 0, 1);
795 aLayout->addWidget(new QLabel("Failure threshold"), 1, 0);
796 aLayout->addWidget(_adviseFailSpinBox, 1, 1);
797 aLayout->addWidget(new QLabel("Recovery threshold"), 2, 0);
798 aLayout->addWidget(_adviseRecoSpinBox, 2, 1);
799 aLayout->addWidget(new QLabel("Script (full path)"), 3, 0);
800 aLayout->addWidget(_adviseScriptLineEdit, 3, 1,1,30);
801 aLayout->addWidget(new QLabel("Failure and recovery reports, advisory notes."),4,0,1,50,Qt::AlignLeft);
802 aLayout->addWidget(new QLabel(" "), 5, 0);
803 agroup->setLayout(aLayout);
804
805 // Miscellaneous
806 // -------------
807 QGridLayout* rLayout = new QGridLayout;
808 rLayout->setColumnMinimumWidth(0,14*ww);
809 _perfIntrComboBox->setMaximumWidth(9*ww);
810
811 rLayout->addWidget(new QLabel("Mountpoint"), 0, 0);
812 rLayout->addWidget(_miscMountLineEdit, 0, 1, 1,7);
813 rLayout->addWidget(new QLabel("Log latency"), 1, 0);
814 rLayout->addWidget(_perfIntrComboBox, 1, 1);
815 rLayout->addWidget(new QLabel("Scan RTCM"), 2, 0);
816 rLayout->addWidget(_scanRTCMCheckBox, 2, 1);
817 rLayout->addWidget(new QLabel("Log latencies or scan RTCM streams for numbers of message types and antenna information."),3, 0,1,30);
818 rLayout->addWidget(new QLabel(" "), 4, 0);
819 rLayout->addWidget(new QLabel(" "), 5, 0);
820 rgroup->setLayout(rLayout);
821
822 // PPP Client
823 // ----------
824 QGridLayout* pppLayout = new QGridLayout;
825 _pppSigCLineEdit->setMaximumWidth(6*ww);
826 _pppSigPLineEdit->setMaximumWidth(6*ww);
827 _pppSigCrd0->setMaximumWidth(6*ww);
828 _pppSigCrdP->setMaximumWidth(6*ww);
829 _pppSigTrp0->setMaximumWidth(6*ww);
830 _pppSigTrpP->setMaximumWidth(6*ww);
831 _pppAverageLineEdit->setMaximumWidth(6*ww);
832 _pppQuickStartLineEdit->setMaximumWidth(6*ww);
833 _pppMaxSolGapLineEdit->setMaximumWidth(6*ww);
834 _pppRefCrdXLineEdit->setMaximumWidth(10*ww);
835 _pppRefCrdYLineEdit->setMaximumWidth(10*ww);
836 _pppRefCrdZLineEdit->setMaximumWidth(10*ww);
837 _pppRefdNLineEdit->setMaximumWidth(5*ww);
838 _pppRefdELineEdit->setMaximumWidth(5*ww);
839 _pppRefdULineEdit->setMaximumWidth(5*ww);
840 _pppSync->setMaximumWidth(6*ww);
841 _pppSPPComboBox->setMaximumWidth(15*ww);
842 _pppNMEAPortLineEdit->setMaximumWidth(6*ww);
843
844 _postObsFileChooser = new qtFileChooser;
845 _postObsFileChooser->setFileName(settings.value("postObsFile").toString());
846 _postObsFileChooser->setWhatsThis(tr("Full Path to RINEX Observation File"));
847
848 _postNavFileChooser = new qtFileChooser;
849 _postNavFileChooser->setFileName(settings.value("postNavFile").toString());
850 _postNavFileChooser->setWhatsThis(tr("Full Path to RINEX Navigation File"));
851
852 _postCorrFileChooser = new qtFileChooser;
853 _postCorrFileChooser->setFileName(settings.value("postCorrFile").toString());
854 _postCorrFileChooser->setWhatsThis(tr("Full Path to DGPS Correction File"));
855
856 _postOutLineEdit = new QLineEdit(settings.value("postOutFile").toString());
857 _postOutLineEdit->setWhatsThis(tr("Full Path to DGPS Correction File"));
858
859 int ir = 0;
860 pppLayout->addWidget(new QLabel("<b>Precise Point Positioning (Panel 1)</b>"), ir, 0, 1, 8);
861 ++ir;
862 pppLayout->addWidget(new QLabel("Obs Mountpoint"), ir, 0);
863 pppLayout->addWidget(_pppMountLineEdit, ir, 1);
864 pppLayout->addWidget(_pppSPPComboBox, ir, 2);
865 pppLayout->addWidget(new QLabel(" X "), ir, 3, Qt::AlignRight);
866 pppLayout->addWidget(_pppRefCrdXLineEdit, ir, 4);
867 pppLayout->addWidget(new QLabel(" Y "), ir, 5, Qt::AlignRight);
868 pppLayout->addWidget(_pppRefCrdYLineEdit, ir, 6);
869 pppLayout->addWidget(new QLabel(" Z "), ir, 7, Qt::AlignRight);
870 pppLayout->addWidget(_pppRefCrdZLineEdit, ir, 8);
871 ++ir;
872 pppLayout->addWidget(new QLabel("Corr Mountpoint "), ir, 0);
873 pppLayout->addWidget(_pppCorrMountLineEdit, ir, 1);
874 pppLayout->addWidget(new QLabel(" dN "), ir, 3, Qt::AlignRight);
875 pppLayout->addWidget(_pppRefdNLineEdit, ir, 4);
876 pppLayout->addWidget(new QLabel(" dE "), ir, 5, Qt::AlignRight);
877 pppLayout->addWidget(_pppRefdELineEdit, ir, 6);
878 pppLayout->addWidget(new QLabel(" dU "), ir, 7, Qt::AlignRight);
879 pppLayout->addWidget(_pppRefdULineEdit, ir, 8);
880 ++ir;
881 pppLayout->addWidget(new QLabel("Output"), ir, 0);
882 pppLayout->addWidget(new QLabel("NMEA File"), ir, 1, Qt::AlignRight);
883 pppLayout->addWidget(_pppNMEALineEdit, ir, 2, 1, 2);
884 pppLayout->addWidget(new QLabel("NMEA Port"), ir, 5, Qt::AlignRight);
885 pppLayout->addWidget(_pppNMEAPortLineEdit, ir, 6);
886 pppLayout->addWidget(new QLabel("PPP Plot"), ir, 7, Qt::AlignRight);
887 pppLayout->addWidget(_pppPlotCoordinates, ir, 8);
888 ++ir;
889 pppLayout->addWidget(new QLabel("<b>Post-Processing </b>"));
890 {
891 QHBoxLayout* hlpLayout = new QHBoxLayout;
892 hlpLayout->addWidget(new QLabel("Obs"));
893 hlpLayout->addWidget(_postObsFileChooser);
894 hlpLayout->addWidget(new QLabel(" Nav"));
895 hlpLayout->addWidget(_postNavFileChooser);
896 hlpLayout->addWidget(new QLabel(" Corr"));
897 hlpLayout->addWidget(_postCorrFileChooser);
898 pppLayout->addLayout(hlpLayout, ir, 1, 1, 8);
899 }
900 ++ir;
901 pppLayout->addWidget(new QLabel("Output"), ir, 1);
902 pppLayout->addWidget(_postOutLineEdit, ir, 2, 1, 2);
903
904 pppgroup->setLayout(pppLayout);
905
906 // PPP Client (second panel)
907 // -------------------------
908 QGridLayout* ppp2Layout = new QGridLayout;
909 ir = 0;
910 ppp2Layout->addWidget(new QLabel("<b>Precise Point Positioning (Panel 2)</b>"), ir, 0, 1, 8);
911 ++ir;
912 ppp2Layout->addWidget(new QLabel("Antennas"), ir, 0);
913 {
914 QHBoxLayout* hlpLayout = new QHBoxLayout;
915 hlpLayout->addWidget(_pppAntexFileChooser);
916 hlpLayout->addWidget(new QLabel("ANTEX File"));
917 hlpLayout->addWidget(_pppAntennaLineEdit);
918 hlpLayout->addWidget(new QLabel("Antenna Name"));
919 hlpLayout->addWidget(_pppApplySatAntCheckBox);
920 hlpLayout->addWidget(new QLabel("Apply Sat. Ant. Offsets"));
921 ppp2Layout->addLayout(hlpLayout, ir, 1, 1, 8);
922 }
923 ++ir;
924 ppp2Layout->addWidget(new QLabel("Sigmas"), ir, 0);
925 ppp2Layout->addWidget(_pppSigCLineEdit, ir, 1, Qt::AlignRight);
926 ppp2Layout->addWidget(new QLabel("Code"), ir, 2);
927 ppp2Layout->addWidget(_pppSigPLineEdit, ir, 3);
928 ppp2Layout->addWidget(new QLabel("Phase"), ir, 4);
929 ppp2Layout->addWidget(_pppSigTrp0, ir, 5, Qt::AlignRight);
930 ppp2Layout->addWidget(new QLabel("Tropo Init "), ir, 6);
931 ppp2Layout->addWidget(_pppSigTrpP, ir, 7);
932 ppp2Layout->addWidget(new QLabel("Tropo White Noise"), ir, 8);
933 ++ir;
934 ppp2Layout->addWidget(new QLabel("Options"), ir, 0, 1, 5);
935 ppp2Layout->addWidget(_pppUsePhaseCheckBox, ir, 1, Qt::AlignRight);
936 ppp2Layout->addWidget(new QLabel("Use phase obs"), ir, 2);
937 ppp2Layout->addWidget(_pppEstTropoCheckBox, ir, 3, Qt::AlignRight);
938 ppp2Layout->addWidget(new QLabel("Estimate tropo"), ir, 4);
939 ppp2Layout->addWidget(_pppGLONASSCheckBox, ir, 5, Qt::AlignRight);
940 ppp2Layout->addWidget(new QLabel("Use GLONASS"), ir, 6);
941 ppp2Layout->addWidget(_pppGalileoCheckBox, ir, 7, Qt::AlignRight);
942 ppp2Layout->addWidget(new QLabel("Use Galileo "), ir, 8);
943 ++ir;
944 ppp2Layout->addWidget(new QLabel("Options cont'd"), ir, 0);
945 ppp2Layout->addWidget(_pppSigCrd0, ir, 1, Qt::AlignRight);
946 ppp2Layout->addWidget(new QLabel("Sigma XYZ Init "), ir, 2);
947 ppp2Layout->addWidget(_pppSigCrdP, ir, 3, Qt::AlignRight);
948 ppp2Layout->addWidget(new QLabel("Sigma XYZ Noise "), ir, 4);
949 ppp2Layout->addWidget(_pppQuickStartLineEdit, ir, 5, Qt::AlignRight);
950 ppp2Layout->addWidget(new QLabel("Quick-Start (sec) "), ir, 6);
951 ppp2Layout->addWidget(_pppMaxSolGapLineEdit, ir, 7, Qt::AlignRight);
952 ppp2Layout->addWidget(new QLabel("Max Sol. Gap (sec)"), ir, 8);
953 ++ir;
954 ppp2Layout->addWidget(new QLabel("Options cont'd"), ir, 0);
955 ppp2Layout->addWidget(_pppSync, ir, 1);
956 ppp2Layout->addWidget(new QLabel("Sync Corr (sec) "), ir, 2);
957 ppp2Layout->addWidget(_pppAverageLineEdit, ir, 3, Qt::AlignRight);
958 ppp2Layout->addWidget(new QLabel("Averaging (min)") , ir, 4);
959
960 ppp2group->setLayout(ppp2Layout);
961
962 // Teqc Processing
963 // ---------------
964 _teqcActionComboBox = new QComboBox();
965 _teqcActionComboBox->setEditable(false);
966 _teqcActionComboBox->addItems(QString("Edit, Analyze").split(","));
967 ik = _teqcActionComboBox->findText(settings.value("teqcAction").toString());
968 if (ik != -1) {
969 _teqcActionComboBox->setCurrentIndex(ik);
970 }
971 connect(_teqcActionComboBox, SIGNAL(currentIndexChanged(const QString &)),
972 this, SLOT(slotBncTextChanged()));
973
974 QGridLayout* teqcLayout = new QGridLayout;
975 teqcLayout->setColumnMinimumWidth(0,14*ww);
976 _teqcActionComboBox->setMaximumWidth(10*ww);
977
978 _teqcObsFileChooser = new qtFileChooser;
979 _teqcObsFileChooser->setFileName(settings.value("teqcObsFile").toString());
980 _teqcObsFileChooser->setWhatsThis(tr("Specify the full path to an observation file in RINEX v2 or v3 format."));
981
982 _teqcNavFileChooser = new qtFileChooser;
983 _teqcNavFileChooser->setFileName(settings.value("teqcNavFile").toString());
984 _teqcNavFileChooser->setWhatsThis(tr("Specify the full path to a RINEX v2 or v3 navigation file."));
985
986 _teqcOutLineEdit = new QLineEdit(settings.value("teqcOutFile").toString());
987 _teqcOutLineEdit->setWhatsThis(tr("Specify the full path to an output file."));
988
989 ir = 0;
990 teqcLayout->addWidget(new QLabel("Action"), ir, 0);
991 teqcLayout->addWidget(_teqcActionComboBox, ir, 1);
992 _teqcEditOptionButton = new QPushButton("Set Edit Options");
993 teqcLayout->addWidget(_teqcEditOptionButton, ir, 2);
994 ++ir;
995 teqcLayout->addWidget(new QLabel("Input files (full path)"), ir, 0);
996 teqcLayout->addWidget(_teqcObsFileChooser, ir, 1);
997 teqcLayout->addWidget(new QLabel("Obs "), ir, 2);
998 teqcLayout->addWidget(_teqcNavFileChooser, ir, 3);
999 teqcLayout->addWidget(new QLabel("Nav "), ir, 4);
1000 ++ir;
1001 teqcLayout->addWidget(new QLabel("Output file (full path)"), ir, 0);
1002 teqcLayout->addWidget(_teqcOutLineEdit, ir, 1, 1, 2);
1003 teqcLayout->addWidget(new QLabel("Teqc-processing, input, output, options."), 3, 0, 1, 5);
1004
1005 teqcgroup->setLayout(teqcLayout);
1006
1007 connect(_teqcEditOptionButton, SIGNAL(clicked()),
1008 this, SLOT(slotTeqcEditOption()));
1009
1010 // Combination
1011 // -----------
1012 QGridLayout* cmbLayout = new QGridLayout;
1013
1014 populateCmbTable();
1015 cmbLayout->addWidget(_cmbTable,0,0,6,3);
1016
1017 cmbLayout->addWidget(addCmbRowButton,1,3);
1018 connect(addCmbRowButton, SIGNAL(clicked()), this, SLOT(slotAddCmbRow()));
1019 cmbLayout->addWidget(delCmbRowButton,2,3);
1020 cmbLayout->addWidget(new QLabel("Method"), 3, 3);
1021 cmbLayout->addWidget(_cmbMethodComboBox, 3, 4, Qt::AlignRight);
1022 cmbLayout->addWidget(new QLabel("Maximal Residuum"), 4, 3);
1023 cmbLayout->addWidget(_cmbMaxresLineEdit, 4, 4, Qt::AlignRight);
1024 connect(delCmbRowButton, SIGNAL(clicked()), this, SLOT(slotDelCmbRow()));
1025
1026 cmbLayout->addWidget(new QLabel(" Combine Broadcast Ephemeris corrections streams."),5,3,1,3);
1027
1028 cmbgroup->setLayout(cmbLayout);
1029
1030 // Upload Layout (Clocks)
1031 // ----------------------
1032 QGridLayout* uploadHlpLayout = new QGridLayout();
1033
1034 uploadHlpLayout->addWidget(new QLabel("Upload RTNet or Combination Results"),0,0);
1035
1036 uploadHlpLayout->addWidget(addUploadRowButton,0,1);
1037 connect(addUploadRowButton, SIGNAL(clicked()), this, SLOT(slotAddUploadRow()));
1038
1039 uploadHlpLayout->addWidget(delUploadRowButton,0,2);
1040 connect(delUploadRowButton, SIGNAL(clicked()), this, SLOT(slotDelUploadRow()));
1041
1042 uploadHlpLayout->addWidget(setUploadTrafoButton,1,1);
1043 connect(setUploadTrafoButton, SIGNAL(clicked()), this, SLOT(slotSetUploadTrafo()));
1044
1045 uploadHlpLayout->addWidget(new QLabel("Interval"),0,3, Qt::AlignRight);
1046 uploadHlpLayout->addWidget(_uploadIntrComboBox,0,4);
1047
1048 uploadHlpLayout->addWidget(new QLabel("Sampling"),1,3, Qt::AlignRight);
1049 uploadHlpLayout->addWidget(_uploadSamplSpinBox,1,4);
1050
1051 uploadHlpLayout->addWidget(new QLabel("Sampling (Orb)"),1,5, Qt::AlignRight);
1052 uploadHlpLayout->addWidget(_uploadSamplOrbSpinBox,1,6);
1053
1054 QBoxLayout* uploadLayout = new QBoxLayout(QBoxLayout::TopToBottom);
1055 populateUploadTable();
1056 uploadLayout->addWidget(_uploadTable);
1057 uploadLayout->addLayout(uploadHlpLayout);
1058
1059 uploadgroup->setLayout(uploadLayout);
1060
1061 // Upload Layout (Ephemeris)
1062 // -------------------------
1063 QGridLayout* uploadLayoutEph = new QGridLayout;
1064
1065 uploadLayoutEph->setColumnMinimumWidth(0, 9*ww);
1066 _uploadEphPortLineEdit->setMaximumWidth(9*ww);
1067 _uploadEphPasswordLineEdit->setMaximumWidth(9*ww);
1068 _uploadEphMountpointLineEdit->setMaximumWidth(12*ww);
1069
1070 uploadLayoutEph->addWidget(new QLabel("Host"), 0, 0);
1071 uploadLayoutEph->addWidget(_uploadEphHostLineEdit, 0, 1, 1, 3);
1072 uploadLayoutEph->addWidget(new QLabel(" Port"), 0, 4, Qt::AlignRight);
1073 uploadLayoutEph->addWidget(_uploadEphPortLineEdit, 0, 5, 1, 1);
1074 uploadLayoutEph->addWidget(new QLabel("Mountpoint "), 1, 0);
1075 uploadLayoutEph->addWidget(_uploadEphMountpointLineEdit, 1, 1);
1076 uploadLayoutEph->addWidget(new QLabel(" Password"), 1, 2, Qt::AlignRight);
1077 uploadLayoutEph->addWidget(_uploadEphPasswordLineEdit, 1, 3);
1078 uploadLayoutEph->addWidget(new QLabel("Sampling"), 2, 0);
1079 uploadLayoutEph->addWidget(_uploadEphSampleSpinBox, 2, 1);
1080 uploadLayoutEph->addWidget(new QLabel("Upload concatenated RTCMv3 Broadcast Ephemeris to caster."), 3, 0, 1, 5);
1081 uploadLayoutEph->addWidget(_uploadEphBytesCounter, 3, 5);
1082
1083 uploadEphgroup->setLayout(uploadLayoutEph);
1084
1085 connect(_uploadEphHostLineEdit, SIGNAL(textChanged(const QString &)),
1086 this, SLOT(slotBncTextChanged()));
1087
1088 // Main Layout
1089 // -----------
1090 QGridLayout* mLayout = new QGridLayout;
1091 _aogroup->setCurrentIndex(settings.value("startTab").toInt());
1092 mLayout->addWidget(_aogroup, 0,0);
1093 mLayout->addWidget(_mountPointsTable, 1,0);
1094 _loggroup->setCurrentIndex(settings.value("statusTab").toInt());
1095 mLayout->addWidget(_loggroup, 2,0);
1096
1097 _canvas->setLayout(mLayout);
1098
1099 // WhatsThis
1100 // ---------
1101 _proxyHostLineEdit->setWhatsThis(tr("<p>If you are running BNC within a protected Local Area Network (LAN), you might 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 these are not possible, you might need to run BNC outside your LAN on a network that has unobstructed connection to the Internet.</p>"));
1102 _proxyPortLineEdit->setWhatsThis(tr("<p>Enter your proxy server port number in case a proxy is operated in front of BNC.</p>"));
1103 _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 wheter this is supported by the involved NTRIP broadcaster. Note that SSL communication is usually done over port 443.</p>"));
1104 _ignoreSslErrorsCheckBox->setWhatsThis(tr("<p>SSL communication may involve queries coming from the NTRIP broadcaster. Tick 'Ignore SSL authorization erros' if you don't want to be bothered with this.</p>"));
1105 _waitTimeSpinBox->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 epoch' seconds. 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 products.</p>"));
1106 _outFileLineEdit->setWhatsThis(tr("Specify the full path to a file where synchronized observations are saved in plain ASCII format. Beware that the size of this file can rapidly increase depending on the number of incoming streams."));
1107 _outPortLineEdit->setWhatsThis(tr("BNC can produce synchronized observations in a plain ASCII format on your local host through an IP port. Specify a port number here to activate this function."));
1108 _outUPortLineEdit->setWhatsThis(tr("BNC can produce unsynchronized observations in a plain ASCII format on your local host through an IP port. Specify a port number here to activate this function."));
1109 _outEphPortLineEdit->setWhatsThis(tr("BNC can produce ephemeris data in RINEX ASCII format on your local host through an IP port. Specify a port number here to activate this function."));
1110 _corrPortLineEdit->setWhatsThis(tr("BNC can produce Broadcast Ephemeris Corrections on your local host through an IP port. Specify a port number here to activate this function."));
1111 _corrTimeSpinBox->setWhatsThis(tr("<p>Concerning output through IP port, BNC drops Broadcast Ephemeris Corrections received later than 'Wait for full epoch' seconds. A value of 2 to 5 seconds is recommended, depending on the latency of the incoming correction stream(s) and the delay acceptable to your real-time application.</p><p>Specifying a value of '0' means that BNC immediately outputs all incoming Broadcast Epemeris Corrections and does not drop any of them for latency reasons.</p>"));
1112 _rnxPathLineEdit->setWhatsThis(tr("Here you specify the path to where the RINEX Observation files will be stored. If the specified directory does not exist, BNC will not create RINEX Observation files."));
1113 _ephPathLineEdit->setWhatsThis(tr("Specify the path for saving Broadcast Ephemeris data as RINEX Navigation files. If the specified directory does not exist, BNC will not create RINEX Navigation files."));
1114 _corrPathLineEdit->setWhatsThis(tr("Specify a directory for saving Broadcast Ephemeris Correction files. If the specified directory does not exist, BNC will not create the files."));
1115 _rnxScrpLineEdit->setWhatsThis(tr("<p>Whenever a RINEX Observation file is saved, you might want to compress, copy or upload it immediately via FTP. BNC allows you to execute a script/batch file to carry out these operations. To do that specify the full path of the script/batch file here. BNC will pass the full RINEX Observation file path to the script as a command line parameter (%1 on Windows systems, $1 onUnix/Linux systems).</p>"));
1116 _rnxSkelLineEdit->setWhatsThis(tr("<p>BNC allows using personal skeleton files that contain the header records you would like to include. You can derive a personal RINEX header skeleton file from the information given in an up to date sitelog.</p><p>A file in the RINEX Observations 'Directory' with a 'Skeleton extension' suffix is interpreted by BNC as a personal RINEX header skeleton file for the corresponding stream.</p>"));
1117 _rnxAppendCheckBox->setWhatsThis(tr("<p>When BNC is started, new files are created by default and any existing files with the same name will be overwritten. However, users might want to append already existing files following a restart of BNC, a system crash or when BNC crashed. Tick 'Append files' to continue with existing files and keep what has been recorded so far.</p>"));
1118 _autoStartCheckBox->setWhatsThis(tr("<p>Tick 'Auto start' for auto-start of BNC at startup time in window mode with preassigned processing options.</p>"));
1119 _rawOutFileLineEdit->setWhatsThis(tr("<p>Save all data coming in through various streams in the received order and format in one file.</p>"));
1120
1121 _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.<p></p>Select '1 min', '1 hour', or '1 day' to force BNC to reread its configuration every full minute, 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 through 'Save & Reread Configuration'.</p>"));
1122 _rnxIntrComboBox->setWhatsThis(tr("<p>Select the length of the RINEX Observation file.</p>"));
1123 _ephIntrComboBox->setWhatsThis(tr("<p>Select the length of the RINEX Navigation file.</p>"));
1124 _corrIntrComboBox->setWhatsThis(tr("<p>Select the length of the Broadcast Ephemeris Correction files.</p>"));
1125 _rnxSamplSpinBox->setWhatsThis(tr("<p>Select the RINEX Observation sampling interval in seconds. A value of zero '0' tells BNC to store all received epochs into RINEX.</p>"));
1126 _binSamplSpinBox->setWhatsThis(tr("<p>Select the synchronized observation sampling interval in seconds. A value of zero '0' tells BNC to send/store all received epochs.</p>"));
1127 _obsRateComboBox->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>"));
1128 _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.</p>"));
1129 _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.</p>"));
1130 _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 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."));
1131 _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 one of the comments '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. An empty option field (default) or invalid path means that you don't want to use this option.</p>"));
1132 _perfIntrComboBox->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.</p>"));
1133 _mountPointsTable->setWhatsThis(tr("<p>Streams selected for retrieval are listed in the 'Streams' section. Clicking on 'Add Stream' button will open 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 sourcetable. 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. The accepted decoder strings are 'RTCM_2.x' and 'RTCM_3.x'.</p><p>In case you need to log the raw data as is, BNC allows users to by-pass its decoders and 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 these streams, the approximate latitude/longitude rover position is sent to the NTRIP broadcaster. The default values 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.</p>"));
1134 _log->setWhatsThis(tr("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 any problems that occur in the communication link, stream availability, stream delay, stream conversion etc."));
1135 _bncFigure->setWhatsThis(tr("The bandwidth consumtion per stream is shown in the 'Throughput' tab in bits per second (bps) or kilo bits per second (kbps)."));
1136 _bncFigureLate->setWhatsThis(tr("The individual latency of observations in each incoming stream is shown in the 'Latency' tab. Streams not carrying observations (i.e. those providing only broadcast ephemeris messages) are not considered here. Note that the calculation of correct latencies requires the clock of the host computer to be properly synchronized."));
1137 _ephV3CheckBox->setWhatsThis(tr("The default format for output of RINEX Navigation data containing Broadcast Ephemeris is RINEX Version 2.11. Select 'Version 3' if you want to output the ephemeris in RINEX Version 3 format."));
1138 _rnxV3CheckBox->setWhatsThis(tr("The default format for RINEX Observation files is RINEX Version 2.11. Select 'Version 3' if you want to save the observations in RINEX Version 3 format."));
1139 _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.</p>"));
1140 _scanRTCMCheckBox->setWhatsThis(tr("<p>Tick 'Scan RTCM' to log the numbers of incomming message types as well as contained antenna coordinates, antenna heigt, and antenna descriptor.</p>"));
1141 _serialMountPointLineEdit->setWhatsThis(tr("<p>Enter a 'Mountpoint' to forward the corresponding stream to a serial connected receiver.</p>"));
1142 _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 you must plug a serial cable in the port defined here before you start BNC.</p>"));
1143 _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. Note further that using a high baud rate is recommended.</p>"));
1144 _serialParityComboBox->setWhatsThis(tr("<p>Select the 'Parity' for the serial output link.</p><p>Note that your selection must equal the parity selection configured to the serial connected receiver. Note further that parity is often set to 'NONE'.</p>"));
1145 _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.</p>"));
1146 _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.</p>"));
1147 _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.</p>"));
1148 _serialAutoNMEAComboBox->setWhatsThis(tr("<p>Select 'Auto' to automatically forward NMEA-GGA messages coming from your serial connected receiver to the NTRIP broadcaster and/or save them in a file.</p><p>Select 'Manual' only when handling a VRS stream and your serial connected receiver doesn't generate NMEA-GGA messages.</p>"));
1149 _serialFileNMEALineEdit->setWhatsThis(tr("<p>Specify the full path to a file where NMEA messages coming from your serial connected receiver are saved.</p>"));
1150 _serialHeightNMEALineEdit->setWhatsThis(tr("<p>Specify an approximate 'Height' above mean sea level in meter for your VRS to simulate an inital NMEA-GGA message.</p><p>The setting of this option is ignored in case of streams coming from physical reference stations.</p>"));
1151 _pppMountLineEdit->setWhatsThis(tr("<p>Specify an observations stream by its mountpoint from the 'Streams' list compiled below if you want BNC to estimate coordinates for the affected receiver position through a PPP solution. Example: 'FFMJ1'</p><p>Note that PPP in BNC requires to also pull a stream carrying RTCM Version 3 satellite orbit and clock corrections to Broadcast Ephemeris referring to the satellites' Antenna Phase Centers (APC). Stream CLK11 on NTRIP broadcaster products.igs-ip.net is an example.</p><p>Pulling in addition a third stream carrying Broadcast Ephemeris messages in high repetition rate is suggested if such messages are comeing from the receiver in low repetition rate or don't come at all from there.</p>"));
1152 _pppCorrMountLineEdit->setWhatsThis(tr("<p>You must specify an orbit/clock corrections stream by its mountpoint from the 'Streams' list compiled below. Example: 'CLK10'</p>"));
1153 _pppSPPComboBox->setWhatsThis(tr("<p>Choose between plain Single Point Positioning (SPP) and Precise Point Positioning (PPP).</p>"));
1154 _teqcActionComboBox->setWhatsThis(tr("<p>Select an editing action.</p>"));
1155 _pppUsePhaseCheckBox->setWhatsThis(tr("<p>By default BNC applies a PPP solution using an ionosphere free P3 linear combination of code observations.</p><p>Tick 'Use phase obs' for an ionosphere free L3 linear combination of phase observations.</p>"));
1156 _pppEstTropoCheckBox->setWhatsThis(tr("<p>By default BNC does not introduce troposphere parameters when estimating coordinates.</p><p>Tick 'Estimate tropo' to introduce troposphere parameters when estimating coordinates.</p>"));
1157 _pppGLONASSCheckBox->setWhatsThis(tr("<p>By default BNC does not use GLONASS observations in PPP mode.</p><p>Tick 'Use GLONASS' for adding GLONASS observations to GPS and Galileo (optional) in a PPP solution.</p>"));
1158 _pppGalileoCheckBox->setWhatsThis(tr("<p>By default BNC does not use Galileo observations in PPP mode.</p><p>Tick 'Use Galileo' for adding Galileo observations to GPS and GLONASS (optional) in a PPP solution.</p>"));
1159 _pppPlotCoordinates->setWhatsThis(tr("<p>BNC will plot PPP results in the 'PPP Plot' tab as North (red), East (green) and Up (blue) displacements when this option is selected. Values will be either referred to an XYZ reference coordinate (if specified) or referred to the first estimated coordinate. The sliding PPP time series window will cover the period of the latest 5 minutes.</p><p>Note that a PPP time series makes only sense for a stationary operated receiver."));
1160 _pppNMEALineEdit->setWhatsThis(tr("<p>Specify the full path to a file where PPP results are saved as NMEA messages.</p>"));
1161 _pppNMEAPortLineEdit->setWhatsThis(tr("<p>Specify an IP port number to output PPP results as NMEA messages through an IP port.</p>"));
1162 _pppSigCLineEdit->setWhatsThis(tr("<p>Enter a sigma for your code observations in meters.</p><p>The higher the sigma you enter, the less the contribution of code observations to a PPP solution based on a combination of code and phase data. 5.0 (default) is likely to be an appropriate choice.</p>"));
1163 _pppQuickStartLineEdit->setWhatsThis(tr("<p>Enter the lenght of a startup period in seconds for which you want to fix the PPP solution to a known XYZ coordinate as introduced above and adjust a sigma 'XYZ Ini' according to the coordinate's precision. Fixing the coordinate is done in BNC through setting the 'Sigma XYZ Noise' you define below temporarily to zero.</p><p>This so-called Quick-Start option allows the PPP solution to rapidly converge. It requires that the antenna remains unmoved on the know position throughout the startup period.</p><p>A value of 120 is likely to be an appropriate choice for 'Quick-Start'. Default is an empty option field, meaning that you don't want BNC to operate in Quick-Start mode.</p>"));
1164 _pppMaxSolGapLineEdit->setWhatsThis(tr("<p>Specify a 'Maximum Solution Gap' in seconds. Should the time span between two consecutive solutions exceed this limit, the algorithm returns into the Quick-Start mode and fixes the introduced reference coordinate for the specified Quick-Start period. A value of '120' seconds could be an appropriate choice.</p><p>This option makes only sense for a stationary operated receiver where solution convergence can be enforced because a good approximation for the rover position is known. Default is an empty option field, meaning that you don't want BNC to return into the Quick-Start mode after failures caused i.e. by longer lasting outages.</p>"));
1165 _pppSigPLineEdit->setWhatsThis(tr("<p>Enter a sigma for your phase observations in meters.</p><p>The higher the sigma you enter, the less the contribution of phase observations to a PPP solutions based on a combination of code and phase data. 0.02 (default) is likely to be an appropriate choice.</p>"));
1166 _pppAverageLineEdit->setWhatsThis(tr("<p>Enter the length of a sliding time window in minutes. BNC will continuously output moving average positions computed from those individual positions obtained most recently throughout this period.</p><p>An empty option field (default) means that you don't want BNC to output moving average positions.</p>"));
1167 _pppSigCrd0->setWhatsThis(tr("<p>Enter a sigma in meters for the initial XYZ coordinate componentes. A value of 100.0 (default) may be an appropriate choice. However, this value may be significantly smaller (i.e. 0.01) when starting for example from a station with known XZY position in Quick-Start mode."));
1168 _pppSigCrdP->setWhatsThis(tr("<p>Enter a sigma in meters for the white noise of estimated XYZ coordinate components. A value of 100.0 (default) may be appropriate considering the potential movement of a rover position.</p>"));
1169 _pppSigTrp0->setWhatsThis(tr("<p>Enter a sigma in meters for the a-priory model based tropospheric delay estimation. A value of 0.1 (default) may be an appropriate choice.</p>"));
1170 _pppSigTrpP->setWhatsThis(tr("<p>Enter a sigma in meters per second to describe the expected variation of the tropospheric effect.</p><p>Supposing 1Hz observation data, a value of 1e-6 (default) would mean that the tropospheric effect may vary for 3600 * 1e-6 = 0.018 meters per hour.</p>"));
1171 _pppRefCrdXLineEdit->setWhatsThis(tr("<p>Enter reference coordinate X of the receiver's position.</p>"));
1172 _pppRefCrdYLineEdit->setWhatsThis(tr("<p>Enter reference coordinate Y of the receiver's position.</p>"));
1173 _pppRefCrdZLineEdit->setWhatsThis(tr("<p>Enter reference coordinate Z of the receiver's position.</p>"));
1174 _pppRefdNLineEdit->setWhatsThis(tr("<p>Enter north antenna excentricity.</p>"));
1175 _pppRefdELineEdit->setWhatsThis(tr("<p>Enter east antenna excentricity.</p>"));
1176 _pppRefdULineEdit->setWhatsThis(tr("<p>Enter up antenna excentricity.</p>"));
1177 _bncFigurePPP->setWhatsThis(tr("PPP time series of North (red), East (green) and Up (blue) coordinate components are shown in the 'PPP Plot' tab when the corresponting option is selected above. Values are either referred to an XYZ reference coordinate (if specified) or referred to the first estimated set of coordinate compoments. The sliding PPP time series window covers the period of the latest 5 minutes."));
1178 _pppSync->setWhatsThis(tr(
1179 "<p> Zero value (or empty field, default) means that BNC processes each epoch of data "
1180 "immediately after its arrival using satellite clock corrections available at "
1181 "that time.</p><p> Non-zero value 'Sync Corr' (i.e. 5) means that the epochs of data "
1182 "are buffered and the processing of each epoch is postponed till the satellite clock "
1183 "corrections not older than 'Sync Corr' seconds are available.<p>"));
1184 _pppAntexFileChooser->setWhatsThis(tr("<p>IGS provides a file containing absolute phase center corrections for GNSS satellite and receiver antennas in ANTEX format. Entering the full path to such an ANTEX file is required for correcting observations for antenna phase center offsets and variations. It allows you to specify the name of your receiver's antenna (as contained in the ANTEX file) to apply such corrections.</p><p>Default is an empty option field meaning that you don't want to correct observations for antenna phase center offsets and variations.</p>"));
1185 _pppAntennaLineEdit->setWhatsThis(tr("<p>Specify the receiver's antenna name as defined in your ANTEX file. Observations will be corrected for the antenna phase center's offset which may result in a reduction of a few centimeters at max. Corrections for phase center variations are not yet applied by BNC. The specified name must consist of 20 characters. Add trailing blanks if the antenna name has less then 20 characters.</p><p>Default is an empty option field meaning that you don't want to correct observations for antenna phase center offsets.</p>"));
1186 _pppApplySatAntCheckBox->setWhatsThis(tr("<p>This option is not yet working.</p><p>Satellite orbit and clock corrections refer to the satellite's antenna phase centers and hence observations are actually <u>not</u> to be corrected for satellite antenna phase center offsets. However, you may like to tick 'Apply Offsets' to force BNC to correct observations for satellite antenna phase center offsets.</p><p>Default is to <u>not</u> correct observations for satellite antenna phase center offsets."));
1187 _cmbTable->setWhatsThis(tr("<p>BNC allows to process several orbit and clock corrections streams in real-time to produce, encode, upload and save a combination of correctors coming from various providers. Hit the 'Add Row' button, double click on the 'Mountpoint' field to enter a Broadcast Ephemeris corrections 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 the weight to be applied for this stream in the combination.</p><p>Note that an appropriate 'Wait for full epoch' value needs to be specified for the combination under the 'Broadcast Corrections' tab. A value of 15 seconds would make sense there if the update rate of incoming clock corrections is i.e. 10 seconds.</p><p>Note further that the orbit information in the final 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 streams to get hold of the orbit information.</p><p>The combination process requires Broadcast Ephemeris. Besides the orbit and clock corrections stream(s) BNC must therefore pull a stream carrying Broadcast Ephemeris in the form of RTCM Version 3 messages.</p>"));
1188 _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'.</p>"));
1189 _cmbMethodComboBox->setWhatsThis(tr("<p>Select a clock combination approach. Options are 'Single-Epoch' and Kalman 'Filter'. It is suggested to use the Kalman filter approach for the purpose of Precise Point Positioning.</p>"));
1190 _uploadTable->setWhatsThis(tr("<p>BNC can upload clock and orbit corrections to broadcast ephemeris (Broadcast Corrections) in RTCM Version 3 SSR format. The clock and orbit corrections may either come from a Real-time Network Engine or from a combination of incoming orbit/clock streams.</p><p>Hit the 'Add Row' button, double click on the 'Host' field to enter the IP or URL of an NTRIP broadcaster and hit Enter. Then double click on the 'Port' field to enter the NTRIP broadcaster IP port.</p>"));
1191
1192 addCmbRowButton->setWhatsThis(tr("Hit 'Add Row' button to add another line to the mountpoints table."));
1193 delCmbRowButton->setWhatsThis(tr("Hit 'Delete' button to delete the highlighted line from the mountpoints table."));
1194
1195 // Enable/Disable all Widgets
1196 // --------------------------
1197 slotBncTextChanged();
1198
1199 // Auto start
1200 // ----------
1201 if ( Qt::CheckState(settings.value("autoStart").toInt()) == Qt::Checked) {
1202 slotGetData();
1203 }
1204}
1205
1206// Destructor
1207////////////////////////////////////////////////////////////////////////////
1208bncWindow::~bncWindow() {
1209 delete _caster;
1210 delete _casterEph;
1211}
1212
1213//
1214////////////////////////////////////////////////////////////////////////////
1215void bncWindow::populateMountPointsTable() {
1216
1217 for (int iRow = _mountPointsTable->rowCount()-1; iRow >=0; iRow--) {
1218 _mountPointsTable->removeRow(iRow);
1219 }
1220
1221 bncSettings settings;
1222
1223 QListIterator<QString> it(settings.value("mountPoints").toStringList());
1224 if (!it.hasNext()) {
1225 _actGetData->setEnabled(false);
1226 }
1227 int iRow = 0;
1228 while (it.hasNext()) {
1229 QStringList hlp = it.next().split(" ");
1230 if (hlp.size() < 5) continue;
1231 _mountPointsTable->insertRow(iRow);
1232
1233 QUrl url(hlp[0]);
1234
1235 QString fullPath = url.host() + QString(":%1").arg(url.port()) + url.path();
1236 QString format(hlp[1]); QString latitude(hlp[2]); QString longitude(hlp[3]);
1237 QString nmea(hlp[4]);
1238 if (hlp[5] == "S") {
1239 fullPath = hlp[0].replace(0,2,"");
1240 }
1241 QString ntripVersion = "2";
1242 if (hlp.size() >= 6) {
1243 ntripVersion = (hlp[5]);
1244 }
1245
1246 QTableWidgetItem* it;
1247 it = new QTableWidgetItem(url.userInfo());
1248 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
1249 _mountPointsTable->setItem(iRow, 0, it);
1250
1251 it = new QTableWidgetItem(fullPath);
1252 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
1253 _mountPointsTable->setItem(iRow, 1, it);
1254
1255 it = new QTableWidgetItem(format);
1256 _mountPointsTable->setItem(iRow, 2, it);
1257
1258 if (nmea == "yes") {
1259 it = new QTableWidgetItem(latitude);
1260 _mountPointsTable->setItem(iRow, 3, it);
1261 it = new QTableWidgetItem(longitude);
1262 _mountPointsTable->setItem(iRow, 4, it);
1263 } else {
1264 it = new QTableWidgetItem(latitude);
1265 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
1266 _mountPointsTable->setItem(iRow, 3, it);
1267 it = new QTableWidgetItem(longitude);
1268 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
1269 _mountPointsTable->setItem(iRow, 4, it);
1270 }
1271
1272 it = new QTableWidgetItem(nmea);
1273 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
1274 _mountPointsTable->setItem(iRow, 5, it);
1275
1276 it = new QTableWidgetItem(ntripVersion);
1277 //// it->setFlags(it->flags() & ~Qt::ItemIsEditable);
1278 _mountPointsTable->setItem(iRow, 6, it);
1279
1280 bncTableItem* bncIt = new bncTableItem();
1281 bncIt->setFlags(bncIt->flags() & ~Qt::ItemIsEditable);
1282 _mountPointsTable->setItem(iRow, 7, bncIt);
1283
1284 iRow++;
1285 }
1286
1287 _mountPointsTable->sortItems(1);
1288}
1289
1290// Retrieve Table
1291////////////////////////////////////////////////////////////////////////////
1292void bncWindow::slotAddMountPoints() {
1293
1294 bncSettings settings;
1295 QString proxyHost = settings.value("proxyHost").toString();
1296 int proxyPort = settings.value("proxyPort").toInt();
1297 if (proxyHost != _proxyHostLineEdit->text() ||
1298 proxyPort != _proxyPortLineEdit->text().toInt()) {
1299 int iRet = QMessageBox::question(this, "Question", "Proxy options "
1300 "changed. Use the new ones?",
1301 QMessageBox::Yes, QMessageBox::No,
1302 QMessageBox::NoButton);
1303 if (iRet == QMessageBox::Yes) {
1304 settings.setValue("proxyHost", _proxyHostLineEdit->text());
1305 settings.setValue("proxyPort", _proxyPortLineEdit->text());
1306 settings.sync();
1307 }
1308 }
1309
1310 settings.setValue("sslCaCertPath", _sslCaCertPathLineEdit->text());
1311 settings.setValue("ignoreSslErrors", _ignoreSslErrorsCheckBox->checkState());
1312 settings.sync();
1313
1314 QMessageBox msgBox;
1315 msgBox.setIcon(QMessageBox::Question);
1316 msgBox.setWindowTitle("Add Stream");
1317 msgBox.setText("Add stream(s) coming from:");
1318
1319 QPushButton* buttonNtrip = msgBox.addButton(tr("Caster"), QMessageBox::ActionRole);
1320 QPushButton* buttonIP = msgBox.addButton(tr("TCP/IP port"), QMessageBox::ActionRole);
1321 QPushButton* buttonUDP = msgBox.addButton(tr("UDP port"), QMessageBox::ActionRole);
1322 QPushButton* buttonSerial = msgBox.addButton(tr("Serial port"), QMessageBox::ActionRole);
1323 QPushButton* buttonCancel = msgBox.addButton(tr("Cancel"), QMessageBox::ActionRole);
1324
1325 msgBox.exec();
1326
1327 if (msgBox.clickedButton() == buttonNtrip) {
1328 bncTableDlg* dlg = new bncTableDlg(this);
1329 dlg->move(this->pos().x()+50, this->pos().y()+50);
1330 connect(dlg, SIGNAL(newMountPoints(QStringList*)),
1331 this, SLOT(slotNewMountPoints(QStringList*)));
1332 dlg->exec();
1333 delete dlg;
1334 } else if (msgBox.clickedButton() == buttonIP) {
1335 bncIpPort* ipp = new bncIpPort(this);
1336 connect(ipp, SIGNAL(newMountPoints(QStringList*)),
1337 this, SLOT(slotNewMountPoints(QStringList*)));
1338 ipp->exec();
1339 delete ipp;
1340 } else if (msgBox.clickedButton() == buttonUDP) {
1341 bncUdpPort* udp = new bncUdpPort(this);
1342 connect(udp, SIGNAL(newMountPoints(QStringList*)),
1343 this, SLOT(slotNewMountPoints(QStringList*)));
1344 udp->exec();
1345 delete udp;
1346 } else if (msgBox.clickedButton() == buttonSerial) {
1347 bncSerialPort* sep = new bncSerialPort(this);
1348 connect(sep, SIGNAL(newMountPoints(QStringList*)),
1349 this, SLOT(slotNewMountPoints(QStringList*)));
1350 sep->exec();
1351 delete sep;
1352 } else if (msgBox.clickedButton() == buttonCancel) {
1353 // Cancel
1354 }
1355}
1356
1357// Delete Selected Mount Points
1358////////////////////////////////////////////////////////////////////////////
1359void bncWindow::slotDeleteMountPoints() {
1360
1361 int nRows = _mountPointsTable->rowCount();
1362 bool flg[nRows];
1363 for (int iRow = 0; iRow < nRows; iRow++) {
1364 if (_mountPointsTable->isItemSelected(_mountPointsTable->item(iRow,1))) {
1365 flg[iRow] = true;
1366 }
1367 else {
1368 flg[iRow] = false;
1369 }
1370 }
1371 for (int iRow = nRows-1; iRow >= 0; iRow--) {
1372 if (flg[iRow]) {
1373 _mountPointsTable->removeRow(iRow);
1374 }
1375 }
1376 _actDeleteMountPoints->setEnabled(false);
1377
1378 if (_mountPointsTable->rowCount() == 0) {
1379 _actGetData->setEnabled(false);
1380 }
1381}
1382
1383// New Mount Points Selected
1384////////////////////////////////////////////////////////////////////////////
1385void bncWindow::slotNewMountPoints(QStringList* mountPoints) {
1386 int iRow = 0;
1387 QListIterator<QString> it(*mountPoints);
1388 while (it.hasNext()) {
1389 QStringList hlp = it.next().split(" ");
1390 QUrl url(hlp[0]);
1391 QString fullPath = url.host() + QString(":%1").arg(url.port()) + url.path();
1392 QString format(hlp[1]); QString latitude(hlp[2]); QString longitude(hlp[3]);
1393 QString nmea(hlp[4]);
1394 if (hlp[5] == "S") {
1395 fullPath = hlp[0].replace(0,2,"");
1396 }
1397 QString ntripVersion = "2";
1398 if (hlp.size() >= 6) {
1399 ntripVersion = (hlp[5]);
1400 }
1401
1402 _mountPointsTable->insertRow(iRow);
1403
1404 QTableWidgetItem* it;
1405 it = new QTableWidgetItem(url.userInfo());
1406 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
1407 _mountPointsTable->setItem(iRow, 0, it);
1408
1409 it = new QTableWidgetItem(fullPath);
1410 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
1411 _mountPointsTable->setItem(iRow, 1, it);
1412
1413 it = new QTableWidgetItem(format);
1414 _mountPointsTable->setItem(iRow, 2, it);
1415
1416 if (nmea == "yes") {
1417 it = new QTableWidgetItem(latitude);
1418 _mountPointsTable->setItem(iRow, 3, it);
1419 it = new QTableWidgetItem(longitude);
1420 _mountPointsTable->setItem(iRow, 4, it);
1421 } else {
1422 it = new QTableWidgetItem(latitude);
1423 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
1424 _mountPointsTable->setItem(iRow, 3, it);
1425 it = new QTableWidgetItem(longitude);
1426 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
1427 _mountPointsTable->setItem(iRow, 4, it);
1428 }
1429
1430 it = new QTableWidgetItem(nmea);
1431 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
1432 _mountPointsTable->setItem(iRow, 5, it);
1433
1434 it = new QTableWidgetItem(ntripVersion);
1435 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
1436 _mountPointsTable->setItem(iRow, 6, it);
1437
1438 bncTableItem* bncIt = new bncTableItem();
1439 _mountPointsTable->setItem(iRow, 7, bncIt);
1440
1441 iRow++;
1442 }
1443 _mountPointsTable->hideColumn(0);
1444 _mountPointsTable->sortItems(1);
1445 if (mountPoints->count() > 0 && !_actStop->isEnabled()) {
1446 _actGetData->setEnabled(true);
1447 }
1448 delete mountPoints;
1449}
1450
1451// Save Options
1452////////////////////////////////////////////////////////////////////////////
1453void bncWindow::slotSaveOptions() {
1454
1455 QStringList mountPoints;
1456 for (int iRow = 0; iRow < _mountPointsTable->rowCount(); iRow++) {
1457
1458 if (_mountPointsTable->item(iRow, 6)->text() != "S") {
1459 QUrl url( "//" + _mountPointsTable->item(iRow, 0)->text() +
1460 "@" + _mountPointsTable->item(iRow, 1)->text() );
1461
1462 mountPoints.append(url.toString() + " " +
1463 _mountPointsTable->item(iRow, 2)->text()
1464 + " " + _mountPointsTable->item(iRow, 3)->text()
1465 + " " + _mountPointsTable->item(iRow, 4)->text()
1466 + " " + _mountPointsTable->item(iRow, 5)->text()
1467 + " " + _mountPointsTable->item(iRow, 6)->text());
1468 } else {
1469 mountPoints.append(
1470 "//" + _mountPointsTable->item(iRow, 1)->text()
1471 + " " + _mountPointsTable->item(iRow, 2)->text()
1472 + " " + _mountPointsTable->item(iRow, 3)->text()
1473 + " " + _mountPointsTable->item(iRow, 4)->text()
1474 + " " + _mountPointsTable->item(iRow, 5)->text()
1475 + " " + _mountPointsTable->item(iRow, 6)->text());
1476 }
1477 }
1478
1479 QStringList combineStreams;
1480 for (int iRow = 0; iRow < _cmbTable->rowCount(); iRow++) {
1481 QString hlp;
1482 for (int iCol = 0; iCol < _cmbTable->columnCount(); iCol++) {
1483 if (_cmbTable->item(iRow, iCol)) {
1484 hlp += _cmbTable->item(iRow, iCol)->text() + " ";
1485 }
1486 }
1487 if (!hlp.isEmpty()) {
1488 combineStreams << hlp;
1489 }
1490 }
1491
1492 QStringList uploadMountpointsOut;
1493 for (int iRow = 0; iRow < _uploadTable->rowCount(); iRow++) {
1494 QString hlp;
1495 for (int iCol = 0; iCol < _uploadTable->columnCount(); iCol++) {
1496 if (_uploadTable->cellWidget(iRow, iCol) &&
1497 (iCol == 3 || iCol == 4 || iCol == 5)) {
1498 if (iCol == 3) {
1499 QLineEdit* passwd = (QLineEdit*)(_uploadTable->cellWidget(iRow, iCol));
1500 hlp += passwd->text() + ",";
1501 }
1502 else if (iCol == 4) {
1503 QComboBox* system = (QComboBox*)(_uploadTable->cellWidget(iRow, iCol));
1504 hlp += system->currentText() + ",";
1505 }
1506 else if (iCol == 5) {
1507 QCheckBox* com = (QCheckBox*)(_uploadTable->cellWidget(iRow, iCol));
1508 QString state; state.setNum(com->checkState());
1509 hlp += state + ",";
1510 }
1511 }
1512 else if (_uploadTable->item(iRow, iCol)) {
1513 hlp += _uploadTable->item(iRow, iCol)->text() + ",";
1514 }
1515 }
1516 if (!hlp.isEmpty()) {
1517 uploadMountpointsOut << hlp;
1518 }
1519 }
1520
1521 bncSettings settings;
1522
1523 settings.setValue("adviseFail", _adviseFailSpinBox->value());
1524 settings.setValue("adviseReco", _adviseRecoSpinBox->value());
1525 settings.setValue("adviseScript",_adviseScriptLineEdit->text());
1526 settings.setValue("autoStart", _autoStartCheckBox->checkState());
1527 settings.setValue("binSampl", _binSamplSpinBox->value());
1528 settings.setValue("corrIntr", _corrIntrComboBox->currentText());
1529 settings.setValue("corrPath", _corrPathLineEdit->text());
1530 settings.setValue("corrPort", _corrPortLineEdit->text());
1531 settings.setValue("corrTime", _corrTimeSpinBox->value());
1532 settings.setValue("ephIntr", _ephIntrComboBox->currentText());
1533 settings.setValue("ephPath", _ephPathLineEdit->text());
1534 settings.setValue("ephV3", _ephV3CheckBox->checkState());
1535 settings.setValue("logFile", _logFileLineEdit->text());
1536 settings.setValue("rawOutFile", _rawOutFileLineEdit->text());
1537 settings.setValue("miscMount", _miscMountLineEdit->text());
1538 settings.setValue("pppMount", _pppMountLineEdit->text());
1539 settings.setValue("pppCorrMount",_pppCorrMountLineEdit->text());
1540 settings.setValue("pppSPP", _pppSPPComboBox->currentText());
1541 settings.setValue("nmeaFile", _pppNMEALineEdit->text());
1542 settings.setValue("nmeaPort", _pppNMEAPortLineEdit->text());
1543 settings.setValue("pppSigmaCode",_pppSigCLineEdit->text());
1544 settings.setValue("pppSigmaPhase",_pppSigPLineEdit->text());
1545 settings.setValue("pppSigCrd0",_pppSigCrd0->text());
1546 settings.setValue("pppSigCrdP",_pppSigCrdP->text());
1547 settings.setValue("pppSigTrp0",_pppSigTrp0->text());
1548 settings.setValue("pppSigTrpP",_pppSigTrpP->text());
1549 settings.setValue("pppAverage", _pppAverageLineEdit->text());
1550 settings.setValue("pppQuickStart", _pppQuickStartLineEdit->text());
1551 settings.setValue("pppMaxSolGap", _pppMaxSolGapLineEdit->text());
1552 settings.setValue("pppRefCrdX", _pppRefCrdXLineEdit->text());
1553 settings.setValue("pppRefCrdY", _pppRefCrdYLineEdit->text());
1554 settings.setValue("pppRefCrdZ", _pppRefCrdZLineEdit->text());
1555 settings.setValue("pppRefdN", _pppRefdNLineEdit->text());
1556 settings.setValue("pppRefdE", _pppRefdELineEdit->text());
1557 settings.setValue("pppRefdU", _pppRefdULineEdit->text());
1558 settings.setValue("pppSync", _pppSync->text());
1559 settings.setValue("pppUsePhase", _pppUsePhaseCheckBox->checkState());
1560 settings.setValue("pppPlotCoordinates", _pppPlotCoordinates->checkState());
1561 settings.setValue("pppEstTropo", _pppEstTropoCheckBox->checkState());
1562 settings.setValue("pppGLONASS", _pppGLONASSCheckBox->checkState());
1563 settings.setValue("pppGalileo", _pppGalileoCheckBox->checkState());
1564 settings.setValue("pppAntenna", _pppAntennaLineEdit->text());
1565 settings.setValue("pppAntex", _pppAntexFileChooser->fileName());
1566 settings.setValue("pppApplySatAnt", _pppApplySatAntCheckBox->checkState());
1567 settings.setValue("mountPoints", mountPoints);
1568 settings.setValue("obsRate", _obsRateComboBox->currentText());
1569 settings.setValue("onTheFlyInterval", _onTheFlyComboBox->currentText());
1570 settings.setValue("outEphPort", _outEphPortLineEdit->text());
1571 settings.setValue("outFile", _outFileLineEdit->text());
1572 settings.setValue("outPort", _outPortLineEdit->text());
1573 settings.setValue("outUPort", _outUPortLineEdit->text());
1574 settings.setValue("perfIntr", _perfIntrComboBox->currentText());
1575 settings.setValue("proxyHost", _proxyHostLineEdit->text());
1576 settings.setValue("proxyPort", _proxyPortLineEdit->text());
1577 settings.setValue("sslCaCertPath", _sslCaCertPathLineEdit->text());
1578 settings.setValue("ignoreSslErrors", _ignoreSslErrorsCheckBox->checkState());
1579 settings.setValue("rnxAppend", _rnxAppendCheckBox->checkState());
1580 settings.setValue("rnxIntr", _rnxIntrComboBox->currentText());
1581 settings.setValue("rnxPath", _rnxPathLineEdit->text());
1582 settings.setValue("rnxSampl", _rnxSamplSpinBox->value());
1583 settings.setValue("rnxScript", _rnxScrpLineEdit->text());
1584 settings.setValue("rnxSkel", _rnxSkelLineEdit->text());
1585 settings.setValue("rnxV3", _rnxV3CheckBox->checkState());
1586 settings.setValue("scanRTCM", _scanRTCMCheckBox->checkState());
1587 settings.setValue("serialFileNMEA",_serialFileNMEALineEdit->text());
1588 settings.setValue("serialHeightNMEA",_serialHeightNMEALineEdit->text());
1589 settings.setValue("serialAutoNMEA", _serialAutoNMEAComboBox->currentText());
1590 settings.setValue("serialBaudRate", _serialBaudRateComboBox->currentText());
1591 settings.setValue("serialDataBits", _serialDataBitsComboBox->currentText());
1592 settings.setValue("serialMountPoint",_serialMountPointLineEdit->text());
1593 settings.setValue("serialParity", _serialParityComboBox->currentText());
1594 settings.setValue("serialPortName", _serialPortNameLineEdit->text());
1595 settings.setValue("serialStopBits", _serialStopBitsComboBox->currentText());
1596 settings.setValue("serialFlowControl",_serialFlowControlComboBox->currentText());
1597 settings.setValue("startTab", _aogroup->currentIndex());
1598 settings.setValue("statusTab", _loggroup->currentIndex());
1599 settings.setValue("waitTime", _waitTimeSpinBox->value());
1600 if (!combineStreams.isEmpty()) {
1601 settings.setValue("combineStreams", combineStreams);
1602 }
1603 else {
1604 settings.setValue("combineStreams", "");
1605 }
1606 settings.setValue("cmbMaxres", _cmbMaxresLineEdit->text());
1607 settings.setValue("cmbMethod", _cmbMethodComboBox->currentText());
1608
1609 if (!uploadMountpointsOut.isEmpty()) {
1610 settings.setValue("uploadMountpointsOut", uploadMountpointsOut);
1611 }
1612 else {
1613 settings.setValue("uploadMountpointsOut", "");
1614 }
1615 settings.setValue("uploadIntr", _uploadIntrComboBox->currentText());
1616 settings.setValue("uploadSampl", _uploadSamplSpinBox->value());
1617 settings.setValue("uploadSamplOrb", _uploadSamplOrbSpinBox->value());
1618
1619 settings.setValue("uploadEphHost", _uploadEphHostLineEdit->text());
1620 settings.setValue("uploadEphPort", _uploadEphPortLineEdit->text());
1621 settings.setValue("uploadEphPassword", _uploadEphPasswordLineEdit->text());
1622 settings.setValue("uploadEphMountpoint",_uploadEphMountpointLineEdit->text());
1623 settings.setValue("uploadEphSample", _uploadEphSampleSpinBox->value());
1624
1625 settings.setValue("postObsFile", _postObsFileChooser->fileName());
1626 settings.setValue("postNavFile", _postNavFileChooser->fileName());
1627 settings.setValue("postCorrFile", _postCorrFileChooser->fileName());
1628 settings.setValue("postOutFile", _postOutLineEdit->text());
1629
1630 settings.setValue("teqcObsFile", _teqcObsFileChooser->fileName());
1631 settings.setValue("teqcNavFile", _teqcNavFileChooser->fileName());
1632 settings.setValue("teqcOutFile", _teqcOutLineEdit->text());
1633
1634 if (_caster) {
1635 _caster->slotReadMountPoints();
1636 }
1637 settings.sync();
1638}
1639
1640// All get slots terminated
1641////////////////////////////////////////////////////////////////////////////
1642void bncWindow::slotGetThreadsFinished() {
1643 ((bncApp*)qApp)->slotMessage("All Get Threads Terminated", true);
1644 delete _caster; _caster = 0;
1645 delete _casterEph; _casterEph = 0;
1646 _actGetData->setEnabled(true);
1647 _actStop->setEnabled(false);
1648}
1649
1650// Retrieve Data
1651////////////////////////////////////////////////////////////////////////////
1652void bncWindow::slotGetData() {
1653 slotSaveOptions();
1654
1655 _bncFigurePPP->reset();
1656
1657 _actDeleteMountPoints->setEnabled(false);
1658 _actGetData->setEnabled(false);
1659 _actStop->setEnabled(true);
1660
1661 _caster = new bncCaster(_outFileLineEdit->text(),
1662 _outPortLineEdit->text().toInt());
1663
1664 ((bncApp*)qApp)->setPort(_outEphPortLineEdit->text().toInt());
1665 ((bncApp*)qApp)->setPortCorr(_corrPortLineEdit->text().toInt());
1666 ((bncApp*)qApp)->initCombination();
1667
1668 connect(_caster, SIGNAL(getThreadsFinished()),
1669 this, SLOT(slotGetThreadsFinished()));
1670
1671 connect (_caster, SIGNAL(mountPointsRead(QList<bncGetThread*>)),
1672 this, SLOT(slotMountPointsRead(QList<bncGetThread*>)));
1673
1674 ((bncApp*)qApp)->slotMessage("========== Start BNC v" BNCVERSION " =========", true);
1675
1676 bncSettings settings;
1677
1678 QDir rnxdir(settings.value("rnxPath").toString());
1679 if (!rnxdir.exists()) ((bncApp*)qApp)->slotMessage("Cannot find RINEX Observations directory", true);
1680
1681 QString rnx_file = settings.value("rnxScript").toString();
1682 if ( !rnx_file.isEmpty() ) {
1683 QFile rnxfile(settings.value("rnxScript").toString());
1684 if (!rnxfile.exists()) ((bncApp*)qApp)->slotMessage("Cannot find RINEX Observations script", true);
1685 }
1686
1687 QDir ephdir(settings.value("ephPath").toString());
1688 if (!ephdir.exists()) ((bncApp*)qApp)->slotMessage("Cannot find RINEX Ephemeris directory", true);
1689
1690 QDir corrdir(settings.value("corrPath").toString());
1691 if (!corrdir.exists()) ((bncApp*)qApp)->slotMessage("Cannot find Broadcast Corrections directory", true);
1692
1693 QString advise_file = settings.value("adviseScript").toString();
1694 if ( !advise_file.isEmpty() ) {
1695 QFile advisefile(settings.value("adviseScript").toString());
1696 if (!advisefile.exists()) ((bncApp*)qApp)->slotMessage("Cannot find Outages script", true);
1697 }
1698
1699 QString ant_file = settings.value("pppAntex").toString();
1700 if ( !ant_file.isEmpty() ) {
1701 QFile anxfile(settings.value("pppAntex").toString());
1702 if (!anxfile.exists()) ((bncApp*)qApp)->slotMessage("Cannot find IGS ANTEX file", true);
1703 }
1704
1705 _caster->slotReadMountPoints();
1706
1707 _casterEph = new bncEphUploadCaster();
1708 connect(_casterEph, SIGNAL(newBytes(QByteArray,double)),
1709 _uploadEphBytesCounter, SLOT(slotNewBytes(QByteArray,double)));
1710}
1711
1712// Retrieve Data
1713////////////////////////////////////////////////////////////////////////////
1714void bncWindow::slotStop() {
1715 int iRet = QMessageBox::question(this, "Stop", "Stop retrieving data?",
1716 QMessageBox::Yes, QMessageBox::No,
1717 QMessageBox::NoButton);
1718 if (iRet == QMessageBox::Yes) {
1719 ((bncApp*)qApp)->stopCombination();
1720 delete _caster; _caster = 0;
1721 delete _casterEph; _casterEph = 0;
1722 _actGetData->setEnabled(true);
1723 _actStop->setEnabled(false);
1724 }
1725}
1726
1727// Close Application gracefully
1728////////////////////////////////////////////////////////////////////////////
1729void bncWindow::closeEvent(QCloseEvent* event) {
1730
1731 int iRet = QMessageBox::question(this, "Close", "Save Options?",
1732 QMessageBox::Yes, QMessageBox::No,
1733 QMessageBox::Cancel);
1734
1735 if (iRet == QMessageBox::Cancel) {
1736 event->ignore();
1737 return;
1738 }
1739 else if (iRet == QMessageBox::Yes) {
1740 slotSaveOptions();
1741 }
1742
1743 QMainWindow::closeEvent(event);
1744}
1745
1746// User changed the selection of mountPoints
1747////////////////////////////////////////////////////////////////////////////
1748void bncWindow::slotSelectionChanged() {
1749 if (_mountPointsTable->selectedItems().isEmpty()) {
1750 _actDeleteMountPoints->setEnabled(false);
1751 }
1752 else {
1753 _actDeleteMountPoints->setEnabled(true);
1754 }
1755}
1756
1757// Display Program Messages
1758////////////////////////////////////////////////////////////////////////////
1759void bncWindow::slotWindowMessage(const QByteArray msg, bool showOnScreen) {
1760
1761#ifdef DEBUG_RTCM2_2021
1762 const int maxBufferSize = 1000;
1763#else
1764 const int maxBufferSize = 10000;
1765#endif
1766
1767 if (! showOnScreen ) {
1768 return;
1769 }
1770
1771 QString txt = _log->toPlainText() + "\n" +
1772 QDateTime::currentDateTime().toUTC().toString("yy-MM-dd hh:mm:ss ") + msg;
1773 _log->clear();
1774 _log->append(txt.right(maxBufferSize));
1775}
1776
1777// About Message
1778////////////////////////////////////////////////////////////////////////////
1779void bncWindow::slotAbout() {
1780 new bncAboutDlg(0);
1781}
1782
1783//Flowchart
1784////////////////////////////////////////////////////////////////////////////
1785void bncWindow::slotFlowchart() {
1786 new bncFlowchartDlg(0);
1787}
1788
1789// Help Window
1790////////////////////////////////////////////////////////////////////////////
1791void bncWindow::slotHelp() {
1792 QUrl url;
1793 url.setPath(":bnchelp.html");
1794 new bncHlpDlg(0, url);
1795}
1796
1797// Select Fonts
1798////////////////////////////////////////////////////////////////////////////
1799void bncWindow::slotFontSel() {
1800 bool ok;
1801 QFont newFont = QFontDialog::getFont(&ok, this->font(), this);
1802 if (ok) {
1803 bncSettings settings;
1804 settings.setValue("font", newFont.toString());
1805 QApplication::setFont(newFont);
1806 int ww = QFontMetrics(newFont).width('w');
1807 setMinimumSize(60*ww, 80*ww);
1808 resize(60*ww, 80*ww);
1809 }
1810}
1811
1812// Whats This Help
1813void bncWindow::slotWhatsThis() {
1814 QWhatsThis::enterWhatsThisMode();
1815}
1816
1817//
1818////////////////////////////////////////////////////////////////////////////
1819void bncWindow::slotMountPointsRead(QList<bncGetThread*> threads) {
1820 _bncFigure->updateMountPoints();
1821 _bncFigureLate->updateMountPoints();
1822
1823 populateMountPointsTable();
1824 bncSettings settings;
1825 _binSamplSpinBox->setValue(settings.value("binSampl").toInt());
1826 _waitTimeSpinBox->setValue(settings.value("waitTime").toInt());
1827 QListIterator<bncGetThread*> iTh(threads);
1828 while (iTh.hasNext()) {
1829 bncGetThread* thread = iTh.next();
1830 for (int iRow = 0; iRow < _mountPointsTable->rowCount(); iRow++) {
1831 QUrl url( "//" + _mountPointsTable->item(iRow, 0)->text() +
1832 "@" + _mountPointsTable->item(iRow, 1)->text() );
1833 if (url == thread->mountPoint() &&
1834 _mountPointsTable->item(iRow, 3)->text() == thread->latitude() &&
1835 _mountPointsTable->item(iRow, 4)->text() == thread->longitude() ) {
1836 ((bncTableItem*) _mountPointsTable->item(iRow, 7))->setGetThread(thread);
1837 disconnect(thread, SIGNAL(newBytes(QByteArray, double)),
1838 _bncFigure, SLOT(slotNewData(QByteArray, double)));
1839 connect(thread, SIGNAL(newBytes(QByteArray, double)),
1840 _bncFigure, SLOT(slotNewData(QByteArray, double)));
1841 disconnect(thread, SIGNAL(newLatency(QByteArray, double)),
1842 _bncFigureLate, SLOT(slotNewLatency(QByteArray, double)));
1843 connect(thread, SIGNAL(newLatency(QByteArray, double)),
1844 _bncFigureLate, SLOT(slotNewLatency(QByteArray, double)));
1845 if ( Qt::CheckState(settings.value("pppPlotCoordinates").toInt()) == Qt::Checked) {
1846 disconnect(thread,
1847 SIGNAL(newPosition(bncTime, double, double, double)),
1848 _bncFigurePPP,
1849 SLOT(slotNewPosition(bncTime, double, double, double)));
1850 connect(thread, SIGNAL(newPosition(bncTime, double, double, double)),
1851 _bncFigurePPP,
1852 SLOT(slotNewPosition(bncTime, double, double, double)));
1853 }
1854 break;
1855 }
1856 }
1857 }
1858}
1859
1860//
1861////////////////////////////////////////////////////////////////////////////
1862void bncWindow::CreateMenu() {
1863 // Create Menus
1864 // ------------
1865 _menuFile = menuBar()->addMenu(tr("&File"));
1866 _menuFile->addAction(_actFontSel);
1867 _menuFile->addSeparator();
1868 _menuFile->addAction(_actSaveOpt);
1869 _menuFile->addSeparator();
1870 _menuFile->addAction(_actQuit);
1871
1872 _menuHlp = menuBar()->addMenu(tr("&Help"));
1873 _menuHlp->addAction(_actHelp);
1874 _menuHlp->addAction(_actFlowchart);
1875 _menuHlp->addAction(_actAbout);
1876}
1877
1878// Toolbar
1879////////////////////////////////////////////////////////////////////////////
1880void bncWindow::AddToolbar() {
1881 QToolBar* toolBar = new QToolBar;
1882 addToolBar(Qt::BottomToolBarArea, toolBar);
1883 toolBar->setMovable(false);
1884 toolBar->addAction(_actAddMountPoints);
1885 toolBar->addAction(_actDeleteMountPoints);
1886 toolBar->addAction(_actGetData);
1887 toolBar->addAction(_actStop);
1888 toolBar->addAction(_actPostProcessing);
1889 toolBar->addWidget(new QLabel(" "));
1890 toolBar->addAction(_actwhatsthis);
1891}
1892
1893// About
1894////////////////////////////////////////////////////////////////////////////
1895bncAboutDlg::bncAboutDlg(QWidget* parent) :
1896 QDialog(parent) {
1897
1898 QTextBrowser* tb = new QTextBrowser;
1899 QUrl url; url.setPath(":bncabout.html");
1900 tb->setSource(url);
1901 tb->setReadOnly(true);
1902
1903 int ww = QFontMetrics(font()).width('w');
1904 QPushButton* _closeButton = new QPushButton("Close");
1905 _closeButton->setMaximumWidth(10*ww);
1906 connect(_closeButton, SIGNAL(clicked()), this, SLOT(close()));
1907
1908 QGridLayout* dlgLayout = new QGridLayout();
1909 QLabel* img = new QLabel();
1910 img->setPixmap(QPixmap(":ntrip-logo.png"));
1911 dlgLayout->addWidget(img, 0,0);
1912 dlgLayout->addWidget(new QLabel("BKG Ntrip Client (BNC) Version "BNCVERSION), 0,1);
1913 dlgLayout->addWidget(tb,1,0,1,2);
1914 dlgLayout->addWidget(_closeButton,2,1,Qt::AlignRight);
1915
1916 setLayout(dlgLayout);
1917 resize(60*ww, 60*ww);
1918 setWindowTitle("About BNC");
1919 show();
1920}
1921
1922//
1923////////////////////////////////////////////////////////////////////////////
1924bncAboutDlg::~bncAboutDlg() {
1925};
1926
1927// Flowchart
1928////////////////////////////////////////////////////////////////////////////
1929bncFlowchartDlg::bncFlowchartDlg(QWidget* parent) :
1930 QDialog(parent) {
1931
1932 int ww = QFontMetrics(font()).width('w');
1933 QPushButton* _closeButton = new QPushButton("Close");
1934 _closeButton->setMaximumWidth(10*ww);
1935 connect(_closeButton, SIGNAL(clicked()), this, SLOT(close()));
1936
1937 QGridLayout* dlgLayout = new QGridLayout();
1938 QLabel* img = new QLabel();
1939 img->setPixmap(QPixmap(":bncflowchart.png"));
1940 dlgLayout->addWidget(img, 0,0);
1941 dlgLayout->addWidget(_closeButton,1,0,Qt::AlignLeft);
1942
1943 setLayout(dlgLayout);
1944 setWindowTitle("Flow Chart");
1945 show();
1946}
1947
1948//
1949////////////////////////////////////////////////////////////////////////////
1950bncFlowchartDlg::~bncFlowchartDlg() {
1951};
1952
1953// Enable/Disable Widget (and change its color)
1954////////////////////////////////////////////////////////////////////////////
1955void bncWindow::enableWidget(bool enable, QWidget* widget) {
1956 const static QPalette paletteWhite(QColor(255, 255, 255));
1957 const static QPalette paletteGray(QColor(230, 230, 230));
1958
1959 widget->setEnabled(enable);
1960 if (enable) {
1961 widget->setPalette(paletteWhite);
1962 }
1963 else {
1964 widget->setPalette(paletteGray);
1965 }
1966}
1967
1968// Bnc Text
1969////////////////////////////////////////////////////////////////////////////
1970void bncWindow::slotBncTextChanged(){
1971
1972 bool enable = true;
1973
1974 // Proxy
1975 //------
1976 if (sender() == 0 || sender() == _proxyHostLineEdit) {
1977 enable = !_proxyHostLineEdit->text().isEmpty();
1978 enableWidget(enable, _proxyPortLineEdit);
1979 }
1980
1981 // RINEX Observations
1982 // ------------------
1983 if (sender() == 0 || sender() == _rnxPathLineEdit) {
1984 enable = !_rnxPathLineEdit->text().isEmpty();
1985 enableWidget(enable, _rnxSamplSpinBox);
1986 enableWidget(enable, _rnxSkelLineEdit);
1987 enableWidget(enable, _rnxScrpLineEdit);
1988 enableWidget(enable, _rnxV3CheckBox);
1989 enableWidget(enable, _rnxIntrComboBox);
1990 }
1991
1992 // RINEX Ephemeris
1993 // ---------------
1994 if (sender() == 0 || sender() == _ephPathLineEdit || sender() == _outEphPortLineEdit) {
1995 enable = !_ephPathLineEdit->text().isEmpty() || !_outEphPortLineEdit->text().isEmpty();
1996 enableWidget(enable, _ephIntrComboBox);
1997 enableWidget(enable, _ephV3CheckBox);
1998 }
1999
2000 // Broadcast Corrections
2001 // ---------------------
2002 if (sender() == 0 || sender() == _corrPathLineEdit || sender() == _corrPortLineEdit) {
2003 enable = !_corrPathLineEdit->text().isEmpty() || !_corrPortLineEdit->text().isEmpty();
2004 enableWidget(enable, _corrIntrComboBox);
2005 }
2006
2007 // Feed Engine
2008 // -----------
2009 if (sender() == 0 || sender() == _outPortLineEdit || sender() == _outFileLineEdit) {
2010 enable = !_outPortLineEdit->text().isEmpty() || !_outFileLineEdit->text().isEmpty();
2011 enableWidget(enable, _waitTimeSpinBox);
2012 enableWidget(enable, _binSamplSpinBox);
2013 }
2014
2015 // Serial Output
2016 // -------------
2017 if (sender() == 0 || sender() == _serialMountPointLineEdit ||
2018 sender() == _serialAutoNMEAComboBox) {
2019 enable = !_serialMountPointLineEdit->text().isEmpty();
2020 enableWidget(enable, _serialPortNameLineEdit);
2021 enableWidget(enable, _serialBaudRateComboBox);
2022 enableWidget(enable, _serialParityComboBox);
2023 enableWidget(enable, _serialDataBitsComboBox);
2024 enableWidget(enable, _serialStopBitsComboBox);
2025 enableWidget(enable, _serialFlowControlComboBox);
2026 enableWidget(enable, _serialAutoNMEAComboBox);
2027
2028 bool enable2 = enable && _serialAutoNMEAComboBox->currentText() != "Auto";
2029 enableWidget(enable2, _serialFileNMEALineEdit);
2030 }
2031
2032 // Outages
2033 // -------
2034 if (sender() == 0 || sender() == _obsRateComboBox) {
2035 enable = !_obsRateComboBox->currentText().isEmpty();
2036 enableWidget(enable, _adviseFailSpinBox);
2037 enableWidget(enable, _adviseRecoSpinBox);
2038 enableWidget(enable, _adviseScriptLineEdit);
2039 }
2040
2041 // Miscellaneous
2042 // -------------
2043 if (sender() == 0 || sender() == _miscMountLineEdit) {
2044 enable = !_miscMountLineEdit->text().isEmpty();
2045 enableWidget(enable, _perfIntrComboBox);
2046 enableWidget(enable, _scanRTCMCheckBox);
2047 }
2048
2049 // PPP Client
2050 // ----------
2051 if (sender() == 0
2052 || sender() == _pppMountLineEdit
2053 || sender() == _pppCorrMountLineEdit
2054 || sender() == _pppRefCrdXLineEdit
2055 || sender() == _pppRefCrdYLineEdit
2056 || sender() == _pppRefCrdZLineEdit
2057 || sender() == _pppRefdNLineEdit
2058 || sender() == _pppRefdELineEdit
2059 || sender() == _pppRefdULineEdit
2060 || sender() == _pppSync
2061 || sender() == _pppSPPComboBox
2062 || sender() == _pppQuickStartLineEdit
2063 || sender() == _pppEstTropoCheckBox
2064 || sender() == _pppUsePhaseCheckBox
2065 || sender() == _pppAntexFileChooser ) {
2066
2067 enable = (!_pppMountLineEdit->text().isEmpty() && !_pppCorrMountLineEdit->text().isEmpty()) ||
2068 (!_pppMountLineEdit->text().isEmpty() && _pppSPPComboBox->currentText() == "SPP") ||
2069 (_pppSPPComboBox->currentText() == "RNX");
2070
2071 enableWidget(enable, _pppNMEALineEdit);
2072 enableWidget(enable, _pppNMEAPortLineEdit);
2073 enableWidget(enable, _pppRefCrdXLineEdit);
2074 enableWidget(enable, _pppRefCrdYLineEdit);
2075 enableWidget(enable, _pppRefCrdZLineEdit);
2076 enableWidget(enable, _pppRefdNLineEdit);
2077 enableWidget(enable, _pppRefdELineEdit);
2078 enableWidget(enable, _pppRefdULineEdit);
2079 enableWidget(enable, _pppUsePhaseCheckBox);
2080 enableWidget(enable, _pppPlotCoordinates);
2081 enableWidget(enable, _pppEstTropoCheckBox);
2082 enableWidget(enable, _pppGLONASSCheckBox);
2083 enableWidget(enable, _pppGalileoCheckBox);
2084 enableWidget(enable, _pppAntexFileChooser);
2085 enableWidget(enable, _pppSigCLineEdit);
2086 enableWidget(enable, _pppSigCrd0);
2087 enableWidget(enable, _pppSigCrdP);
2088
2089 bool enable2 = enable && !_pppRefCrdXLineEdit->text().isEmpty() &&
2090 !_pppRefCrdYLineEdit->text().isEmpty() &&
2091 !_pppRefCrdZLineEdit->text().isEmpty();
2092
2093 enableWidget(enable2, _pppAverageLineEdit);
2094 enableWidget(enable2, _pppQuickStartLineEdit);
2095
2096 bool enable3 = enable2 && !_pppQuickStartLineEdit->text().isEmpty();
2097 enableWidget(enable3, _pppMaxSolGapLineEdit);
2098
2099 bool enable4 = enable && !_pppAntexFileChooser->fileName().isEmpty();
2100 enableWidget(enable4, _pppAntennaLineEdit);
2101 enableWidget(enable4, _pppApplySatAntCheckBox);
2102
2103 bool enable5 = enable && _pppEstTropoCheckBox->isChecked() && !_pppMountLineEdit->text().isEmpty();
2104 enableWidget(enable5, _pppSigTrp0);
2105 enableWidget(enable5, _pppSigTrpP);
2106
2107 bool enable6 = enable && _pppUsePhaseCheckBox->isChecked();
2108 enableWidget(enable6, _pppSigPLineEdit);
2109
2110 bool enable7 = enable && _pppSPPComboBox->currentText() == "PPP";
2111 enableWidget(enable7, _pppSync);
2112
2113 bool enable8 = _pppSPPComboBox->currentText() == "PPP";
2114 enableWidget(enable8, _pppCorrMountLineEdit);
2115
2116 bool enable9 = _pppSPPComboBox->currentText() == "RNX";
2117 enableWidget(enable9, _postObsFileChooser);
2118 enableWidget(enable9, _postNavFileChooser);
2119 enableWidget(enable9, _postCorrFileChooser);
2120 enableWidget(enable9, _postOutLineEdit);
2121 enableWidget(!enable9, _pppMountLineEdit);
2122 }
2123
2124 if (sender() == 0 || sender() == _teqcActionComboBox) {
2125 bool enable10 = _teqcActionComboBox->currentText() == "Edit";
2126 enableWidget(enable10, _teqcEditOptionButton);
2127 enableWidget(!enable10, _teqcNavFileChooser);
2128 enableWidget(!enable10, _teqcOutLineEdit);
2129 }
2130
2131 slotEnablePostProcessing();
2132}
2133
2134// Enable/Disable Post-Processing Action
2135////////////////////////////////////////////////////////////////////////////
2136void bncWindow::slotEnablePostProcessing() {
2137 if (_actPostProcessing) {
2138 if (_postProcessingRunningPPP || _postProcessingRunningTeqc) {
2139 _actPostProcessing->setEnabled(false);
2140 }
2141 else {
2142 if (_aogroup->currentIndex() == _tabIndexPPP1 ||
2143 _aogroup->currentIndex() == _tabIndexPPP2) {
2144 _actPostProcessing->setText("Start PPP");
2145 bool enable = _pppSPPComboBox->currentText() == "RNX";
2146 _actPostProcessing->setEnabled(enable);
2147 }
2148 else if (_aogroup->currentIndex() == _tabIndexTeqc) {
2149 _actPostProcessing->setText("Start Teqc");
2150 _actPostProcessing->setEnabled(true);
2151 }
2152 else {
2153 _actPostProcessing->setText("Start PPP/Teqc");
2154 _actPostProcessing->setEnabled(false);
2155 }
2156 }
2157 }
2158}
2159
2160//
2161////////////////////////////////////////////////////////////////////////////
2162void bncWindow::slotAddCmbRow() {
2163 int iRow = _cmbTable->rowCount();
2164 _cmbTable->insertRow(iRow);
2165 for (int iCol = 0; iCol < _cmbTable->columnCount(); iCol++) {
2166 _cmbTable->setItem(iRow, iCol, new QTableWidgetItem(""));
2167 }
2168}
2169
2170//
2171////////////////////////////////////////////////////////////////////////////
2172void bncWindow::slotDelCmbRow() {
2173 int nRows = _cmbTable->rowCount();
2174 bool flg[nRows];
2175 for (int iRow = 0; iRow < nRows; iRow++) {
2176 if (_cmbTable->isItemSelected(_cmbTable->item(iRow,1))) {
2177 flg[iRow] = true;
2178 }
2179 else {
2180 flg[iRow] = false;
2181 }
2182 }
2183 for (int iRow = nRows-1; iRow >= 0; iRow--) {
2184 if (flg[iRow]) {
2185 _cmbTable->removeRow(iRow);
2186 }
2187 }
2188}
2189
2190//
2191////////////////////////////////////////////////////////////////////////////
2192void bncWindow::populateCmbTable() {
2193
2194 for (int iRow = _cmbTable->rowCount()-1; iRow >=0; iRow--) {
2195 _cmbTable->removeRow(iRow);
2196 }
2197
2198 bncSettings settings;
2199
2200 int iRow = -1;
2201 QListIterator<QString> it(settings.value("combineStreams").toStringList());
2202 while (it.hasNext()) {
2203 QStringList hlp = it.next().split(" ");
2204 if (hlp.size() > 2) {
2205 ++iRow;
2206 _cmbTable->insertRow(iRow);
2207 }
2208 for (int iCol = 0; iCol < hlp.size(); iCol++) {
2209 _cmbTable->setItem(iRow, iCol, new QTableWidgetItem(hlp[iCol]));
2210 }
2211 }
2212}
2213
2214//
2215////////////////////////////////////////////////////////////////////////////
2216void bncWindow::slotAddUploadRow() {
2217 int iRow = _uploadTable->rowCount();
2218 _uploadTable->insertRow(iRow);
2219 for (int iCol = 0; iCol < _uploadTable->columnCount(); iCol++) {
2220 if (iCol == 3) {
2221 QLineEdit* passwd = new QLineEdit();
2222 passwd->setFrame(false);
2223 passwd->setEchoMode(QLineEdit::PasswordEchoOnEdit);
2224 _uploadTable->setCellWidget(iRow, iCol, passwd);
2225 }
2226 else if (iCol == 4) {
2227 QComboBox* system = new QComboBox();
2228 system->setEditable(false);
2229 system->addItems(QString("IGS05,ETRF2000,NAD83,GDA94,SIRGAS95,SIRGAS2000,Custom").split(","));
2230 system->setFrame(false);
2231 _uploadTable->setCellWidget(iRow, iCol, system);
2232 }
2233 else if (iCol == 5) {
2234 QCheckBox* com = new QCheckBox();
2235 _uploadTable->setCellWidget(iRow, iCol, com);
2236 }
2237 else if (iCol == 8) {
2238 bncTableItem* bncIt = new bncTableItem();
2239 bncIt->setFlags(bncIt->flags() & ~Qt::ItemIsEditable);
2240 _uploadTable->setItem(iRow, iCol, bncIt);
2241 ((bncApp*)qApp)->_uploadTableItems[iRow] = bncIt;
2242 }
2243 else {
2244 _uploadTable->setItem(iRow, iCol, new QTableWidgetItem(""));
2245 }
2246 }
2247}
2248
2249//
2250////////////////////////////////////////////////////////////////////////////
2251void bncWindow::slotDelUploadRow() {
2252 ((bncApp*)qApp)->_uploadTableItems.clear();
2253 int nRows = _uploadTable->rowCount();
2254 bool flg[nRows];
2255 for (int iRow = 0; iRow < nRows; iRow++) {
2256 if (_uploadTable->isItemSelected(_uploadTable->item(iRow,1))) {
2257 flg[iRow] = true;
2258 }
2259 else {
2260 flg[iRow] = false;
2261 }
2262 }
2263 for (int iRow = nRows-1; iRow >= 0; iRow--) {
2264 if (flg[iRow]) {
2265 _uploadTable->removeRow(iRow);
2266 }
2267 }
2268 for (int iRow = 0; iRow < _uploadTable->rowCount(); iRow++) {
2269 ((bncApp*)qApp)->_uploadTableItems[iRow] =
2270 (bncTableItem*) _uploadTable->item(iRow, 8);
2271 }
2272}
2273
2274//
2275////////////////////////////////////////////////////////////////////////////
2276void bncWindow::populateUploadTable() {
2277 for (int iRow = _uploadTable->rowCount()-1; iRow >=0; iRow--) {
2278 _uploadTable->removeRow(iRow);
2279 }
2280
2281 bncSettings settings;
2282
2283 int iRow = -1;
2284 QListIterator<QString> it(settings.value("uploadMountpointsOut").toStringList());
2285 while (it.hasNext()) {
2286 QStringList hlp = it.next().split(",");
2287 if (hlp.size() > 6) {
2288 ++iRow;
2289 _uploadTable->insertRow(iRow);
2290 }
2291 for (int iCol = 0; iCol < hlp.size(); iCol++) {
2292 if (iCol == 3) {
2293 QLineEdit* passwd = new QLineEdit();
2294 passwd->setFrame(false);
2295 passwd->setEchoMode(QLineEdit::PasswordEchoOnEdit);
2296 passwd->setText(hlp[iCol]);
2297 _uploadTable->setCellWidget(iRow, iCol, passwd);
2298 }
2299 else if (iCol == 4) {
2300 QComboBox* system = new QComboBox();
2301 system->setEditable(false);
2302 system->addItems(QString("IGS05,ETRF2000,NAD83,GDA94,SIRGAS95,SIRGAS2000,Custom").split(","));
2303 system->setFrame(false);
2304 system->setCurrentIndex(system->findText(hlp[iCol]));
2305 _uploadTable->setCellWidget(iRow, iCol, system);
2306 }
2307 else if (iCol == 5) {
2308 QCheckBox* com = new QCheckBox();
2309 if (hlp[iCol].toInt() == Qt::Checked) {
2310 com->setCheckState(Qt::Checked);
2311 }
2312 _uploadTable->setCellWidget(iRow, iCol, com);
2313 }
2314 else if (iCol == 8) {
2315 bncTableItem* bncIt = new bncTableItem();
2316 bncIt->setFlags(bncIt->flags() & ~Qt::ItemIsEditable);
2317 _uploadTable->setItem(iRow, iCol, bncIt);
2318 ((bncApp*)qApp)->_uploadTableItems[iRow] = bncIt;
2319 }
2320 else {
2321 _uploadTable->setItem(iRow, iCol, new QTableWidgetItem(hlp[iCol]));
2322 }
2323 }
2324 }
2325}
2326
2327//
2328////////////////////////////////////////////////////////////////////////////
2329void bncWindow::slotSetUploadTrafo() {
2330 bncCustomTrafo* dlg = new bncCustomTrafo(this);
2331 dlg->exec();
2332 delete dlg;
2333}
2334
2335// Start Post-Processing PPP or Teqc (slot)
2336////////////////////////////////////////////////////////////////////////////
2337void bncWindow::slotStartPostProcessing() {
2338 if (_aogroup->currentIndex() == _tabIndexPPP1 ||
2339 _aogroup->currentIndex() == _tabIndexPPP2) {
2340 startPostProcessingPPP();
2341 }
2342 else if (_aogroup->currentIndex() == _tabIndexTeqc) {
2343 startPostProcessingTeqc();
2344 }
2345}
2346
2347// Start Post-Processing PPP
2348////////////////////////////////////////////////////////////////////////////
2349void bncWindow::startPostProcessingPPP() {
2350#ifdef USE_POSTPROCESSING
2351 _postProcessingRunningPPP = true;
2352 slotEnablePostProcessing();
2353 _actPostProcessing->setText("0 Epochs");
2354
2355 slotSaveOptions();
2356
2357 t_postProcessing* postProcessing = new t_postProcessing(this);
2358 connect(postProcessing, SIGNAL(finished()), this, SLOT(slotFinishedPostProcessingPPP()));
2359 connect(postProcessing, SIGNAL(progress(int)), this, SLOT(slotPostProgress(int)));
2360
2361 postProcessing->start();
2362#else
2363 QMessageBox::information(this, "Information",
2364 "Post-Processing Not Permitted");
2365#endif
2366}
2367
2368// Post-Processing PPP Finished
2369////////////////////////////////////////////////////////////////////////////
2370void bncWindow::slotFinishedPostProcessingPPP() {
2371 _postProcessingRunningPPP = false;
2372 QMessageBox::information(this, "Information",
2373 "Post-Processing Thread Finished");
2374 slotEnablePostProcessing();
2375}
2376
2377// Progress Bar Change
2378////////////////////////////////////////////////////////////////////////////
2379void bncWindow::slotPostProgress(int nEpo) {
2380 if (_actPostProcessing) {
2381 _actPostProcessing->setText(QString("%1 Epochs").arg(nEpo));
2382 }
2383}
2384
2385// Start Post-Processing Teqc
2386////////////////////////////////////////////////////////////////////////////
2387void bncWindow::startPostProcessingTeqc() {
2388 _postProcessingRunningTeqc = false; // TODO
2389 QMessageBox::information(this, "Information",
2390 "Teqc-Processing Not Yet Implemented");
2391 slotEnablePostProcessing();
2392}
2393
2394// Post-Processing Teqc Finished
2395////////////////////////////////////////////////////////////////////////////
2396void bncWindow::slotFinishedPostProcessingTeqc() {
2397 _postProcessingRunningTeqc = false;
2398 QMessageBox::information(this, "Information",
2399 "Teqc-Processing Thread Finished");
2400 slotEnablePostProcessing();
2401}
2402
2403// Edit teqc-like editing options
2404////////////////////////////////////////////////////////////////////////////
2405void bncWindow::slotTeqcEditOption() {
2406 teqcDlg* dlg = new teqcDlg(this);
2407 dlg->move(this->pos().x()+50, this->pos().y()+50);
2408 dlg->exec();
2409 delete dlg;
2410}
Note: See TracBrowser for help on using the repository browser.