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

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