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

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