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

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