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

Last change on this file since 7170 was 7170, checked in by stuerze, 9 years ago

Check box for the optional choice of RINEX V3 observation file names is added

File size: 142.6 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 "bnccore.h"
46#include "bncgetthread.h"
47#include "bnctabledlg.h"
48#include "bncipport.h"
49#include "bncudpport.h"
50#include "bncserialport.h"
51#include "bnchlpdlg.h"
52#include "bnchtml.h"
53#include "bnctableitem.h"
54#include "bncsettings.h"
55#include "bncfigure.h"
56#include "bncfigurelate.h"
57#include "bncfigureppp.h"
58#include "bncversion.h"
59#include "bncbytescounter.h"
60#include "bncsslconfig.h"
61#include "upload/bnccustomtrafo.h"
62#include "upload/bncephuploadcaster.h"
63#include "qtfilechooser.h"
64#include "reqcdlg.h"
65#include "bncmap.h"
66#include "rinex/reqcedit.h"
67#include "rinex/reqcanalyze.h"
68#include "orbComp/sp3Comp.h"
69#ifdef QT_WEBKIT
70# include "map/bncmapwin.h"
71#endif
72
73using namespace std;
74
75#ifdef GNSSCENTER_PLUGIN
76Q_EXPORT_PLUGIN2(gnsscenter_bnc, t_bncFactory)
77#endif
78
79// Constructor
80////////////////////////////////////////////////////////////////////////////
81bncWindow::bncWindow() {
82
83 const static QPalette paletteWhite(QColor(255, 255, 255));
84 const static QPalette paletteGray(QColor(230, 230, 230));
85
86#ifdef GNSSCENTER_PLUGIN
87 BNC_CORE->setConfFileName("");
88#endif
89
90 _caster = 0;
91 _casterEph = 0;
92
93 _bncFigure = new bncFigure(this);
94 _bncFigureLate = new bncFigureLate(this);
95 _bncFigurePPP = new bncFigurePPP(this);
96
97 connect(BNC_CORE, SIGNAL(newPosition(QByteArray, bncTime, QVector<double>)),
98 _bncFigurePPP, SLOT(slotNewPosition(QByteArray, bncTime, QVector<double>)));
99
100 connect(BNC_CORE, SIGNAL(progressRnxPPP(int)), this, SLOT(slotPostProcessingProgress(int)));
101 connect(BNC_CORE, SIGNAL(finishedRnxPPP()), this, SLOT(slotPostProcessingFinished()));
102
103 _runningRealTime = false;
104 _runningPPP = false;
105 _runningEdit = false;
106 _runningQC = false;
107 _runningSp3Comp = false;
108 _reqcActionComboBox = 0; // necessary for enableStartStop()
109
110 _mapWin = 0;
111
112 int ww = QFontMetrics(this->font()).width('w');
113
114 static const QStringList labels = QString("account, Streams: resource loader / mountpoint, decoder, lat, long, nmea, ntrip, bytes").split(",");
115
116 setMinimumSize(100*ww, 70*ww);
117
118 setWindowTitle(tr("BKG Ntrip Client (BNC) Version " BNCVERSION));
119
120 connect(BNC_CORE, SIGNAL(newMessage(QByteArray,bool)),
121 this, SLOT(slotWindowMessage(QByteArray,bool)));
122
123 // Create Actions
124 // --------------
125 _actHelp = new QAction(tr("&Help Contents"),this);
126 connect(_actHelp, SIGNAL(triggered()), SLOT(slotHelp()));
127
128 _actAbout = new QAction(tr("&About BNC"),this);
129 connect(_actAbout, SIGNAL(triggered()), SLOT(slotAbout()));
130
131 _actFlowchart = new QAction(tr("&Flow Chart"),this);
132 connect(_actFlowchart, SIGNAL(triggered()), SLOT(slotFlowchart()));
133
134 _actFontSel = new QAction(tr("Select &Font"),this);
135 connect(_actFontSel, SIGNAL(triggered()), SLOT(slotFontSel()));
136
137 _actSaveOpt = new QAction(tr("&Reread && Save Configuration"),this);
138 connect(_actSaveOpt, SIGNAL(triggered()), SLOT(slotSaveOptions()));
139
140 _actQuit = new QAction(tr("&Quit"),this);
141 connect(_actQuit, SIGNAL(triggered()), SLOT(close()));
142
143 _actAddMountPoints = new QAction(tr("Add &Stream"),this);
144 connect(_actAddMountPoints, SIGNAL(triggered()), SLOT(slotAddMountPoints()));
145
146 _actDeleteMountPoints = new QAction(tr("&Delete Stream"),this);
147 connect(_actDeleteMountPoints, SIGNAL(triggered()), SLOT(slotDeleteMountPoints()));
148 _actDeleteMountPoints->setEnabled(false);
149
150 _actMapMountPoints = new QAction(tr("&Map"),this);
151 connect(_actMapMountPoints, SIGNAL(triggered()), SLOT(slotMapMountPoints()));
152
153 _actStart = new QAction(tr("Sta&rt"),this);
154 connect(_actStart, SIGNAL(triggered()), SLOT(slotStart()));
155
156 _actStop = new QAction(tr("Sto&p"),this);
157 connect(_actStop, SIGNAL(triggered()), SLOT(slotStop()));
158
159 _actwhatsthis= new QAction(tr("Help ?=Shift+F1"),this);
160 connect(_actwhatsthis, SIGNAL(triggered()), SLOT(slotWhatsThis()));
161
162 CreateMenu();
163 AddToolbar();
164
165 bncSettings settings;
166
167 // Network Options
168 // ---------------
169 _proxyHostLineEdit = new QLineEdit(settings.value("proxyHost").toString());
170 _proxyPortLineEdit = new QLineEdit(settings.value("proxyPort").toString());
171
172 connect(_proxyHostLineEdit, SIGNAL(textChanged(const QString &)),
173 this, SLOT(slotBncTextChanged()));
174
175 _sslCaCertPathLineEdit = new QLineEdit(settings.value("sslCaCertPath").toString());
176 _ignoreSslErrorsCheckBox = new QCheckBox();
177 _ignoreSslErrorsCheckBox->setCheckState(Qt::CheckState(
178 settings.value("ignoreSslErrors").toInt()));
179
180 // General Options
181 // ---------------
182 _logFileLineEdit = new QLineEdit(settings.value("logFile").toString());
183 _rawOutFileLineEdit = new QLineEdit(settings.value("rawOutFile").toString());
184 _rnxAppendCheckBox = new QCheckBox();
185 _rnxAppendCheckBox->setCheckState(Qt::CheckState(
186 settings.value("rnxAppend").toInt()));
187 _onTheFlyComboBox = new QComboBox();
188 _onTheFlyComboBox->setEditable(false);
189 _onTheFlyComboBox->addItems(QString("1 day,1 hour,5 min,1 min").split(","));
190 int ii = _onTheFlyComboBox->findText(settings.value("onTheFlyInterval").toString());
191 if (ii != -1) {
192 _onTheFlyComboBox->setCurrentIndex(ii);
193 }
194 _autoStartCheckBox = new QCheckBox();
195 _autoStartCheckBox->setCheckState(Qt::CheckState(
196 settings.value("autoStart").toInt()));
197
198 // RINEX Observations Options
199 // --------------------------
200 _rnxPathLineEdit = new QLineEdit(settings.value("rnxPath").toString());
201 _rnxIntrComboBox = new QComboBox();
202 _rnxIntrComboBox->setEditable(false);
203 _rnxIntrComboBox->addItems(QString("1 min,2 min,5 min,10 min,15 min,30 min,1 hour,1 day").split(","));
204 ii = _rnxIntrComboBox->findText(settings.value("rnxIntr").toString());
205 if (ii != -1) {
206 _rnxIntrComboBox->setCurrentIndex(ii);
207 }
208 _rnxSamplSpinBox = new QSpinBox();
209 _rnxSamplSpinBox->setMinimum(0);
210 _rnxSamplSpinBox->setMaximum(60);
211 _rnxSamplSpinBox->setSingleStep(5);
212 _rnxSamplSpinBox->setValue(settings.value("rnxSampl").toInt());
213 _rnxFileCheckBox = new QCheckBox();
214 _rnxFileCheckBox->setCheckState(Qt::CheckState(settings.value("rnxOnlyWithSKL").toInt()));
215 _rnxV3filenameCheckBox = new QCheckBox();
216 _rnxV3filenameCheckBox->setCheckState(Qt::CheckState(settings.value("rnxV3filenames").toInt()));
217 _rnxSamplSpinBox->setSuffix(" sec");
218 _rnxSkelLineEdit = new QLineEdit(settings.value("rnxSkel").toString());
219 _rnxSkelLineEdit->setMaximumWidth(5*ww);
220 _rnxScrpLineEdit = new QLineEdit(settings.value("rnxScript").toString());
221 _rnxV3CheckBox = new QCheckBox();
222 _rnxV3CheckBox->setCheckState(Qt::CheckState(settings.value("rnxV3").toInt()));
223 QString hlp = settings.value("rnxV2Priority").toString();
224 if (hlp.isEmpty()) {
225 hlp = "CWPX_?";
226 }
227 _rnxV2Priority = new QLineEdit(hlp);
228
229 connect(_rnxPathLineEdit, SIGNAL(textChanged(const QString &)),
230 this, SLOT(slotBncTextChanged()));
231 connect(_rnxV3CheckBox, SIGNAL(stateChanged(int)),
232 this, SLOT(slotBncTextChanged()));
233
234 // RINEX Ephemeris Options
235 // -----------------------
236 _ephPathLineEdit = new QLineEdit(settings.value("ephPath").toString());
237 _ephIntrComboBox = new QComboBox();
238 _ephIntrComboBox->setEditable(false);
239 _ephIntrComboBox->addItems(QString("1 min,2 min,5 min,10 min,15 min,30 min,1 hour,1 day").split(","));
240 int jj = _ephIntrComboBox->findText(settings.value("ephIntr").toString());
241 if (jj != -1) {
242 _ephIntrComboBox->setCurrentIndex(jj);
243 }
244 _outEphPortLineEdit = new QLineEdit(settings.value("outEphPort").toString());
245 _ephV3CheckBox = new QCheckBox();
246 _ephV3CheckBox->setCheckState(Qt::CheckState(settings.value("ephV3").toInt()));
247
248 connect(_outEphPortLineEdit, SIGNAL(textChanged(const QString &)),
249 this, SLOT(slotBncTextChanged()));
250
251 connect(_ephPathLineEdit, SIGNAL(textChanged(const QString &)),
252 this, SLOT(slotBncTextChanged()));
253
254 // Broadcast Corrections Options
255 // -----------------------------
256 _corrPathLineEdit = new QLineEdit(settings.value("corrPath").toString());
257 _corrIntrComboBox = new QComboBox();
258 _corrIntrComboBox->setEditable(false);
259 _corrIntrComboBox->addItems(QString("1 min,2 min,5 min,10 min,15 min,30 min,1 hour,1 day").split(","));
260 int mm = _corrIntrComboBox->findText(settings.value("corrIntr").toString());
261 if (mm != -1) {
262 _corrIntrComboBox->setCurrentIndex(mm);
263 }
264 _corrPortLineEdit = new QLineEdit(settings.value("corrPort").toString());
265
266 connect(_corrPathLineEdit, SIGNAL(textChanged(const QString &)),
267 this, SLOT(slotBncTextChanged()));
268
269 connect(_corrPortLineEdit, SIGNAL(textChanged(const QString &)),
270 this, SLOT(slotBncTextChanged()));
271
272 // Feed Engine Options
273 // -------------------
274 _outPortLineEdit = new QLineEdit(settings.value("outPort").toString());
275 _waitTimeSpinBox = new QSpinBox();
276 _waitTimeSpinBox->setMinimum(1);
277 _waitTimeSpinBox->setMaximum(30);
278 _waitTimeSpinBox->setSingleStep(1);
279 _waitTimeSpinBox->setSuffix(" sec");
280 _waitTimeSpinBox->setValue(settings.value("waitTime").toInt());
281 _binSamplSpinBox = new QSpinBox();
282 _binSamplSpinBox->setMinimum(0);
283 _binSamplSpinBox->setMaximum(60);
284 _binSamplSpinBox->setSingleStep(5);
285 _binSamplSpinBox->setValue(settings.value("binSampl").toInt());
286 _binSamplSpinBox->setSuffix(" sec");
287 _outFileLineEdit = new QLineEdit(settings.value("outFile").toString());
288 _outUPortLineEdit = new QLineEdit(settings.value("outUPort").toString());
289
290 connect(_outPortLineEdit, SIGNAL(textChanged(const QString &)),
291 this, SLOT(slotBncTextChanged()));
292
293 connect(_outFileLineEdit, SIGNAL(textChanged(const QString &)),
294 this, SLOT(slotBncTextChanged()));
295
296 // Serial Output Options
297 // ---------------------
298 _serialMountPointLineEdit = new QLineEdit(settings.value("serialMountPoint").toString());
299 _serialPortNameLineEdit = new QLineEdit(settings.value("serialPortName").toString());
300 _serialBaudRateComboBox = new QComboBox();
301 _serialBaudRateComboBox->addItems(QString("110,300,600,"
302 "1200,2400,4800,9600,19200,38400,57600,115200").split(","));
303 int kk = _serialBaudRateComboBox->findText(settings.value("serialBaudRate").toString());
304 if (kk != -1) {
305 _serialBaudRateComboBox->setCurrentIndex(kk);
306 }
307 _serialFlowControlComboBox = new QComboBox();
308 _serialFlowControlComboBox->addItems(QString("OFF,XONXOFF,HARDWARE").split(","));
309 kk = _serialFlowControlComboBox->findText(settings.value("serialFlowControl").toString());
310 if (kk != -1) {
311 _serialFlowControlComboBox->setCurrentIndex(kk);
312 }
313 _serialDataBitsComboBox = new QComboBox();
314 _serialDataBitsComboBox->addItems(QString("5,6,7,8").split(","));
315 kk = _serialDataBitsComboBox->findText(settings.value("serialDataBits").toString());
316 if (kk != -1) {
317 _serialDataBitsComboBox->setCurrentIndex(kk);
318 }
319 _serialParityComboBox = new QComboBox();
320 _serialParityComboBox->addItems(QString("NONE,ODD,EVEN,SPACE").split(","));
321 kk = _serialParityComboBox->findText(settings.value("serialParity").toString());
322 if (kk != -1) {
323 _serialParityComboBox->setCurrentIndex(kk);
324 }
325 _serialStopBitsComboBox = new QComboBox();
326 _serialStopBitsComboBox->addItems(QString("1,2").split(","));
327 kk = _serialStopBitsComboBox->findText(settings.value("serialStopBits").toString());
328 if (kk != -1) {
329 _serialStopBitsComboBox->setCurrentIndex(kk);
330 }
331 _serialAutoNMEAComboBox = new QComboBox();
332 _serialAutoNMEAComboBox->addItems(QString("no,Auto,Manual GPGGA,Manual GNGGA").split(","));
333 kk = _serialAutoNMEAComboBox->findText(settings.value("serialAutoNMEA").toString());
334 if (kk != -1) {
335 _serialAutoNMEAComboBox->setCurrentIndex(kk);
336 }
337 _serialFileNMEALineEdit = new QLineEdit(settings.value("serialFileNMEA").toString());
338 _serialHeightNMEALineEdit = new QLineEdit(settings.value("serialHeightNMEA").toString());
339
340 _serialManualNMEASamplingSpinBox = new QSpinBox();
341 _serialManualNMEASamplingSpinBox->setMinimum(0);
342 _serialManualNMEASamplingSpinBox->setMaximum(300);
343 _serialManualNMEASamplingSpinBox->setSingleStep(10);
344 _serialManualNMEASamplingSpinBox->setValue(settings.value("serialManualNMEASampling").toInt());
345 _serialManualNMEASamplingSpinBox->setSuffix(" sec");
346
347 connect(_serialMountPointLineEdit, SIGNAL(textChanged(const QString &)),
348 this, SLOT(slotBncTextChanged()));
349
350 connect(_serialAutoNMEAComboBox, SIGNAL(currentIndexChanged(const QString &)),
351 this, SLOT(slotBncTextChanged()));
352
353 // Outages Options
354 // ---------------
355 _obsRateComboBox = new QComboBox();
356 _obsRateComboBox->setEditable(false);
357 _obsRateComboBox->addItems(QString(",0.1 Hz,0.2 Hz,0.5 Hz,1 Hz,5 Hz").split(","));
358 kk = _obsRateComboBox->findText(settings.value("obsRate").toString());
359 if (kk != -1) {
360 _obsRateComboBox->setCurrentIndex(kk);
361 }
362 _adviseFailSpinBox = new QSpinBox();
363 _adviseFailSpinBox->setMinimum(0);
364 _adviseFailSpinBox->setMaximum(60);
365 _adviseFailSpinBox->setSingleStep(1);
366 _adviseFailSpinBox->setSuffix(" min");
367 _adviseFailSpinBox->setValue(settings.value("adviseFail").toInt());
368 _adviseRecoSpinBox = new QSpinBox();
369 _adviseRecoSpinBox->setMinimum(0);
370 _adviseRecoSpinBox->setMaximum(60);
371 _adviseRecoSpinBox->setSingleStep(1);
372 _adviseRecoSpinBox->setSuffix(" min");
373 _adviseRecoSpinBox->setValue(settings.value("adviseReco").toInt());
374 _adviseScriptLineEdit = new QLineEdit(settings.value("adviseScript").toString());
375
376 connect(_obsRateComboBox, SIGNAL(currentIndexChanged(const QString &)),
377 this, SLOT(slotBncTextChanged()));
378
379 // Miscellaneous Options
380 // ---------------------
381 _miscMountLineEdit = new QLineEdit(settings.value("miscMount").toString());
382 _miscPortLineEdit = new QLineEdit(settings.value("miscPort").toString());
383 _perfIntrComboBox = new QComboBox();
384 _perfIntrComboBox->setEditable(false);
385 _perfIntrComboBox->addItems(QString(",2 sec, 10 sec,1 min,5 min,15 min,1 hour,6 hours,1 day").split(","));
386 int ll = _perfIntrComboBox->findText(settings.value("perfIntr").toString());
387 if (ll != -1) {
388 _perfIntrComboBox->setCurrentIndex(ll);
389 }
390 _scanRTCMCheckBox = new QCheckBox();
391 _scanRTCMCheckBox->setCheckState(Qt::CheckState(
392 settings.value("scanRTCM").toInt()));
393
394 connect(_miscMountLineEdit, SIGNAL(textChanged(const QString &)),
395 this, SLOT(slotBncTextChanged()));
396
397 // Streams
398 // -------
399 _mountPointsTable = new QTableWidget(0,8);
400
401 _mountPointsTable->horizontalHeader()->resizeSection(1,34*ww);
402 _mountPointsTable->horizontalHeader()->resizeSection(2,9*ww);
403 _mountPointsTable->horizontalHeader()->resizeSection(3,7*ww);
404 _mountPointsTable->horizontalHeader()->resizeSection(4,7*ww);
405 _mountPointsTable->horizontalHeader()->resizeSection(5,5*ww);
406 _mountPointsTable->horizontalHeader()->resizeSection(6,5*ww);
407 _mountPointsTable->horizontalHeader()->setResizeMode(QHeaderView::Interactive);
408 _mountPointsTable->horizontalHeader()->setStretchLastSection(true);
409 _mountPointsTable->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft);
410 _mountPointsTable->setHorizontalHeaderLabels(labels);
411 _mountPointsTable->setGridStyle(Qt::NoPen);
412 _mountPointsTable->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
413 _mountPointsTable->setSelectionMode(QAbstractItemView::ExtendedSelection);
414 _mountPointsTable->setSelectionBehavior(QAbstractItemView::SelectRows);
415 _mountPointsTable->hideColumn(0);
416 connect(_mountPointsTable, SIGNAL(itemSelectionChanged()),
417 SLOT(slotSelectionChanged()));
418 populateMountPointsTable();
419
420 _log = new QTextEdit();
421 _log->setReadOnly(true);
422 QFont msFont(""); msFont.setStyleHint(QFont::TypeWriter); // default monospace font
423 _log->setFont(msFont);
424 _log->document()->setMaximumBlockCount(1000);
425
426 // Combine Corrections
427 // -------------------
428 _cmbTable = new QTableWidget(0,3);
429 _cmbTable->setHorizontalHeaderLabels(QString("Mountpoint, AC Name, Weight").split(","));
430 _cmbTable->setSelectionMode(QAbstractItemView::ExtendedSelection);
431 _cmbTable->setSelectionBehavior(QAbstractItemView::SelectRows);
432 _cmbTable->setMaximumWidth(30*ww);
433 _cmbTable->horizontalHeader()->resizeSection(0,10*ww);
434 _cmbTable->horizontalHeader()->resizeSection(1,8*ww);
435 _cmbTable->horizontalHeader()->resizeSection(2,8*ww);
436 _cmbTable->horizontalHeader()->setResizeMode(QHeaderView::Interactive);
437 _cmbTable->horizontalHeader()->setStretchLastSection(true);
438 _cmbTable->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft);
439
440 _cmbMaxresLineEdit = new QLineEdit(settings.value("cmbMaxres").toString());
441 _cmbUseGlonass = new QCheckBox();
442 _cmbUseGlonass->setCheckState(Qt::CheckState(settings.value("cmbUseGlonass").toInt()));
443
444 _cmbSamplSpinBox = new QSpinBox;
445 _cmbSamplSpinBox->setMinimum(10);
446 _cmbSamplSpinBox->setMaximum(60);
447 _cmbSamplSpinBox->setSingleStep(10);
448 _cmbSamplSpinBox->setMaximumWidth(9*ww);
449 _cmbSamplSpinBox->setValue(settings.value("cmbSampl").toInt());
450 _cmbSamplSpinBox->setSuffix(" sec");
451
452 QPushButton* addCmbRowButton = new QPushButton("Add Row");
453 QPushButton* delCmbRowButton = new QPushButton("Delete");
454
455 connect(_cmbTable, SIGNAL(itemSelectionChanged()),
456 SLOT(slotBncTextChanged()));
457
458 _cmbMethodComboBox = new QComboBox();
459 _cmbMethodComboBox->setEditable(false);
460 _cmbMethodComboBox->addItems(QString("Filter,Single-Epoch").split(","));
461 int im = _cmbMethodComboBox->findText(settings.value("cmbMethod").toString());
462 if (im != -1) {
463 _cmbMethodComboBox->setCurrentIndex(im);
464 }
465
466 int iRow = _cmbTable->rowCount();
467 if (iRow > 0) {
468 enableWidget(true, _cmbMethodComboBox);
469 enableWidget(true, _cmbMaxresLineEdit);
470 enableWidget(true, _cmbSamplSpinBox);
471 enableWidget(true, _cmbUseGlonass);
472 }
473 else {
474 enableWidget(false, _cmbMethodComboBox);
475 enableWidget(false, _cmbMaxresLineEdit);
476 enableWidget(false, _cmbSamplSpinBox);
477 enableWidget(false, _cmbUseGlonass);
478 }
479
480 // Upload Results
481 // -------------
482 _uploadTable = new QTableWidget(0,12);
483 _uploadTable->setHorizontalHeaderLabels(QString("Host, Port, Mount, Password, System, CoM, SP3 File, RNX File, PID, SID, IOD, bytes").split(","));
484 _uploadTable->setSelectionMode(QAbstractItemView::ExtendedSelection);
485 _uploadTable->setSelectionBehavior(QAbstractItemView::SelectRows);
486 _uploadTable->horizontalHeader()->resizeSection( 0,13*ww);
487 _uploadTable->horizontalHeader()->resizeSection( 1, 5*ww);
488 _uploadTable->horizontalHeader()->resizeSection( 2, 6*ww);
489 _uploadTable->horizontalHeader()->resizeSection( 3, 8*ww);
490 _uploadTable->horizontalHeader()->resizeSection( 4,11*ww);
491 _uploadTable->horizontalHeader()->resizeSection( 5, 4*ww);
492 _uploadTable->horizontalHeader()->resizeSection( 6,15*ww);
493 _uploadTable->horizontalHeader()->resizeSection( 7,15*ww);
494 _uploadTable->horizontalHeader()->resizeSection( 8, 4*ww);
495 _uploadTable->horizontalHeader()->resizeSection( 9, 4*ww);
496 _uploadTable->horizontalHeader()->resizeSection(10, 4*ww);
497 _uploadTable->horizontalHeader()->resizeSection(11,12*ww);
498 _uploadTable->horizontalHeader()->setResizeMode(QHeaderView::Interactive);
499 _uploadTable->horizontalHeader()->setStretchLastSection(true);
500 _uploadTable->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft);
501
502 connect(_uploadTable, SIGNAL(itemSelectionChanged()),
503 SLOT(slotBncTextChanged()));
504
505 QPushButton* addUploadRowButton = new QPushButton("Add Row");
506 QPushButton* delUploadRowButton = new QPushButton("Del Row");
507 QPushButton* setUploadTrafoButton = new QPushButton("Custom Trafo");
508 _uploadIntrComboBox = new QComboBox;
509 _uploadIntrComboBox->setEditable(false);
510 _uploadIntrComboBox->addItems(QString("1 day,1 hour, 30 min,15 min,10 min,5 min,2 min,1 min").split(","));
511 ii = _uploadIntrComboBox->findText(settings.value("uploadIntr").toString());
512 if (ii != -1) {
513 _uploadIntrComboBox->setCurrentIndex(ii);
514 }
515
516 _uploadAntexFile = new qtFileChooser(0, qtFileChooser::File);
517 _uploadAntexFile->setFileName(settings.value("uploadAntexFile").toString());
518
519 _uploadSamplRtcmEphCorrSpinBox = new QSpinBox;
520 _uploadSamplRtcmEphCorrSpinBox->setMinimum(0);
521 _uploadSamplRtcmEphCorrSpinBox->setMaximum(60);
522 _uploadSamplRtcmEphCorrSpinBox->setSingleStep(5);
523 _uploadSamplRtcmEphCorrSpinBox->setMaximumWidth(9*ww);
524 _uploadSamplRtcmEphCorrSpinBox->setValue(settings.value("uploadSamplRtcmEphCorr").toInt());
525 _uploadSamplRtcmEphCorrSpinBox->setSuffix(" sec");
526
527 _uploadSamplSp3SpinBox = new QSpinBox;
528 _uploadSamplSp3SpinBox->setMinimum(0);
529 _uploadSamplSp3SpinBox->setMaximum(15);
530 _uploadSamplSp3SpinBox->setSingleStep(1);
531 _uploadSamplSp3SpinBox->setMaximumWidth(9*ww);
532 _uploadSamplSp3SpinBox->setValue(settings.value("uploadSamplSp3").toInt());
533 _uploadSamplSp3SpinBox->setSuffix(" min");
534
535 _uploadSamplClkRnxSpinBox = new QSpinBox;
536 _uploadSamplClkRnxSpinBox->setMinimum(0);
537 _uploadSamplClkRnxSpinBox->setMaximum(60);
538 _uploadSamplClkRnxSpinBox->setSingleStep(5);
539 _uploadSamplClkRnxSpinBox->setMaximumWidth(9*ww);
540 _uploadSamplClkRnxSpinBox->setValue(settings.value("uploadSamplClkRnx").toInt());
541 _uploadSamplClkRnxSpinBox->setSuffix(" sec");
542
543 int iRowT = _uploadTable->rowCount();
544 if (iRowT > 0) {
545 enableWidget(true, _uploadIntrComboBox);
546 enableWidget(true, _uploadSamplRtcmEphCorrSpinBox);
547 enableWidget(true, _uploadSamplSp3SpinBox);
548 enableWidget(true, _uploadSamplClkRnxSpinBox);
549 enableWidget(true, _uploadAntexFile);
550 }
551 else {
552 enableWidget(false, _uploadIntrComboBox);
553 enableWidget(false, _uploadSamplRtcmEphCorrSpinBox);
554 enableWidget(false, _uploadSamplSp3SpinBox);
555 enableWidget(false, _uploadSamplClkRnxSpinBox);
556 enableWidget(false, _uploadAntexFile);
557 }
558
559 // Upload RTCM3 Ephemeris
560 // ----------------------
561 _uploadEphHostLineEdit = new QLineEdit(settings.value("uploadEphHost").toString());
562 _uploadEphPortLineEdit = new QLineEdit(settings.value("uploadEphPort").toString());
563 _uploadEphPasswordLineEdit = new QLineEdit(settings.value("uploadEphPassword").toString());
564 _uploadEphPasswordLineEdit->setEchoMode(QLineEdit::PasswordEchoOnEdit);
565 _uploadEphMountpointLineEdit = new QLineEdit(settings.value("uploadEphMountpoint").toString());
566 _uploadEphSampleSpinBox = new QSpinBox;
567 _uploadEphSampleSpinBox->setMinimum(5);
568 _uploadEphSampleSpinBox->setMaximum(60);
569 _uploadEphSampleSpinBox->setSingleStep(5);
570 _uploadEphSampleSpinBox->setMaximumWidth(9*ww);
571 _uploadEphSampleSpinBox->setValue(settings.value("uploadEphSample").toInt());
572 _uploadEphSampleSpinBox->setSuffix(" sec");
573 _uploadEphBytesCounter = new bncBytesCounter;
574
575 // Canvas with Editable Fields
576 // ---------------------------
577 _canvas = new QWidget;
578 setCentralWidget(_canvas);
579
580 _aogroup = new QTabWidget();
581 _aogroup->setElideMode(Qt::ElideNone);
582 _aogroup->setUsesScrollButtons(true);
583 QWidget* pgroup = new QWidget();
584 QWidget* ggroup = new QWidget();
585 QWidget* sgroup = new QWidget();
586 QWidget* egroup = new QWidget();
587 QWidget* agroup = new QWidget();
588 QWidget* cgroup = new QWidget();
589 QWidget* ogroup = new QWidget();
590 QWidget* rgroup = new QWidget();
591 QWidget* sergroup = new QWidget();
592 QWidget* pppGroup1 = new QWidget();
593 QWidget* pppGroup2 = new QWidget();
594 QWidget* pppGroup3 = new QWidget();
595 QWidget* pppGroup4 = new QWidget();
596 QWidget* reqcgroup = new QWidget();
597 QWidget* sp3CompGroup = new QWidget();
598 QWidget* cmbgroup = new QWidget();
599 QWidget* uploadgroup = new QWidget();
600 QWidget* uploadEphgroup = new QWidget();
601 _aogroup->addTab(pgroup,tr("Network"));
602 _aogroup->addTab(ggroup,tr("General"));
603 _aogroup->addTab(ogroup,tr("RINEX Observations"));
604 _aogroup->addTab(egroup,tr("RINEX Ephemeris"));
605 _aogroup->addTab(reqcgroup,tr("RINEX Editing && QC"));
606 _aogroup->addTab(sp3CompGroup,tr("SP3 Comparison"));
607 _aogroup->addTab(cgroup,tr("Broadcast Corrections"));
608 _aogroup->addTab(sgroup,tr("Feed Engine"));
609 _aogroup->addTab(sergroup,tr("Serial Output"));
610 _aogroup->addTab(agroup,tr("Outages"));
611 _aogroup->addTab(rgroup,tr("Miscellaneous"));
612 _aogroup->addTab(pppGroup1,tr("PPP (1)"));
613 _aogroup->addTab(pppGroup2,tr("PPP (2)"));
614 _aogroup->addTab(pppGroup3,tr("PPP (3)"));
615 _aogroup->addTab(pppGroup4,tr("PPP (4)"));
616
617#ifdef USE_COMBINATION
618 _aogroup->addTab(cmbgroup,tr("Combine Corrections"));
619#endif
620 _aogroup->addTab(uploadgroup,tr("Upload Corrections"));
621 _aogroup->addTab(uploadEphgroup,tr("Upload Ephemeris"));
622
623 // Log Tab
624 // -------
625 _loggroup = new QTabWidget();
626 _loggroup->addTab(_log,tr("Log"));
627 _loggroup->addTab(_bncFigure,tr("Throughput"));
628 _loggroup->addTab(_bncFigureLate,tr("Latency"));
629 _loggroup->addTab(_bncFigurePPP,tr("PPP Plot"));
630
631 // Netowork (Proxy and SSL) Tab
632 // ----------------------------
633 QGridLayout* pLayout = new QGridLayout;
634 pLayout->setColumnMinimumWidth(0,13*ww);
635 _proxyPortLineEdit->setMaximumWidth(9*ww);
636
637 pLayout->addWidget(new QLabel("Settings for proxy in protected networks and for SSL authorization, leave boxes blank if none.<br>"),0, 0, 1, 50);
638 pLayout->addWidget(new QLabel("Proxy host"), 1, 0);
639 pLayout->addWidget(_proxyHostLineEdit, 1, 1, 1,10);
640 pLayout->addWidget(new QLabel("Proxy port"), 2, 0);
641 pLayout->addWidget(_proxyPortLineEdit, 2, 1);
642 pLayout->addWidget(new QLabel("Path to SSL certificates"), 3, 0);
643 pLayout->addWidget(_sslCaCertPathLineEdit, 3, 1, 1,10);
644 pLayout->addWidget(new QLabel("Default: " + bncSslConfig::defaultPath()), 3,11, 1,20);
645 pLayout->addWidget(new QLabel("Ignore SSL authorization errors"), 4, 0);
646 pLayout->addWidget(_ignoreSslErrorsCheckBox, 4, 1, 1,10);
647 pLayout->addWidget(new QLabel(""), 5, 1);
648 pLayout->setRowStretch(6, 999);
649
650 pgroup->setLayout(pLayout);
651
652 // General Tab
653 // -----------
654 QGridLayout* gLayout = new QGridLayout;
655 gLayout->setColumnMinimumWidth(0,14*ww);
656 _onTheFlyComboBox->setMaximumWidth(9*ww);
657
658 gLayout->addWidget(new QLabel("General settings for logfile, file handling, configuration on-the-fly, auto-start, and raw file output.<br>"),0, 0, 1, 50);
659 gLayout->addWidget(new QLabel("Logfile (full path)"), 1, 0);
660 gLayout->addWidget(_logFileLineEdit, 1, 1, 1,20);
661 gLayout->addWidget(new QLabel("Append files"), 2, 0);
662 gLayout->addWidget(_rnxAppendCheckBox, 2, 1);
663 gLayout->addWidget(new QLabel("Reread configuration"), 3, 0);
664 gLayout->addWidget(_onTheFlyComboBox, 3, 1);
665 gLayout->addWidget(new QLabel("Auto start"), 4, 0);
666 gLayout->addWidget(_autoStartCheckBox, 4, 1);
667 gLayout->addWidget(new QLabel("Raw output file (full path)"), 5, 0);
668 gLayout->addWidget(_rawOutFileLineEdit, 5, 1, 1,20);
669 gLayout->addWidget(new QLabel(""), 6, 1);
670 gLayout->setRowStretch(7, 999);
671
672 ggroup->setLayout(gLayout);
673
674 // RINEX Observations
675 // ------------------
676 QGridLayout* oLayout = new QGridLayout;
677 oLayout->setColumnMinimumWidth(0,14*ww);
678 _rnxIntrComboBox->setMaximumWidth(9*ww);
679 _rnxSamplSpinBox->setMaximumWidth(9*ww);
680
681 _rnxV2Priority->setMaximumWidth(9*ww);
682
683 oLayout->addWidget(new QLabel("Saving RINEX observation files.<br>"),0, 0, 1,50);
684 oLayout->addWidget(new QLabel("Directory"), 1, 0);
685 oLayout->addWidget(_rnxPathLineEdit, 1, 1, 1, 15);
686 oLayout->addWidget(new QLabel("Interval"), 2, 0);
687 oLayout->addWidget(_rnxIntrComboBox, 2, 1);
688 oLayout->addWidget(new QLabel(" Sampling"), 2, 2, Qt::AlignRight);
689 oLayout->addWidget(_rnxSamplSpinBox, 2, 3, Qt::AlignLeft);
690 oLayout->addWidget(new QLabel("Skeleton extension"), 3, 0);
691 oLayout->addWidget(_rnxSkelLineEdit, 3, 1, Qt::AlignLeft);
692 oLayout->addWidget(new QLabel("Skeleton mandatory"), 3, 2);
693 oLayout->addWidget(_rnxFileCheckBox, 3, 3);
694 oLayout->addWidget(new QLabel("Script (full path)"), 4, 0);
695 oLayout->addWidget(_rnxScrpLineEdit, 4, 1, 1, 15);
696 oLayout->addWidget(new QLabel("Version 2"), 5, 0);
697 oLayout->addWidget(_rnxV2Priority, 5, 1);
698 oLayout->addWidget(new QLabel("Signal priority"), 5, 2);
699 oLayout->addWidget(new QLabel("Version 3"), 6, 0);
700 oLayout->addWidget(_rnxV3CheckBox, 6, 1);
701 oLayout->addWidget(new QLabel("Version 3 file names"), 6, 2);
702 oLayout->addWidget(_rnxV3filenameCheckBox, 6, 3);
703 oLayout->addWidget(new QLabel(""), 7, 1);
704 oLayout->setRowStretch(8, 999);
705
706 ogroup->setLayout(oLayout);
707
708 // RINEX Ephemeris
709 // ---------------
710 QGridLayout* eLayout = new QGridLayout;
711 eLayout->setColumnMinimumWidth(0,14*ww);
712 _ephIntrComboBox->setMaximumWidth(9*ww);
713 _outEphPortLineEdit->setMaximumWidth(9*ww);
714
715 eLayout->addWidget(new QLabel("Saving RINEX navigation files and ephemeris output through IP port.<br>"),0,0,1,70);
716 eLayout->addWidget(new QLabel("Directory"), 1, 0);
717 eLayout->addWidget(_ephPathLineEdit, 1, 1, 1,30);
718 eLayout->addWidget(new QLabel("Interval"), 2, 0);
719 eLayout->addWidget(_ephIntrComboBox, 2, 1);
720 eLayout->addWidget(new QLabel("Port"), 3, 0);
721 eLayout->addWidget(_outEphPortLineEdit, 3, 1);
722 eLayout->addWidget(new QLabel("Version 3"), 4, 0);
723 eLayout->addWidget(_ephV3CheckBox, 4, 1);
724 eLayout->setRowStretch(5, 999);
725
726 egroup->setLayout(eLayout);
727
728
729 // Broadcast Corrections
730 // ---------------------
731 QGridLayout* cLayout = new QGridLayout;
732 cLayout->setColumnMinimumWidth(0,14*ww);
733 _corrIntrComboBox->setMaximumWidth(9*ww);
734 _corrPortLineEdit->setMaximumWidth(9*ww);
735
736 cLayout->addWidget(new QLabel("Saving Broadcast Ephemeris correction files and correction output through IP port.<br>"),0,0,1,70);
737 cLayout->addWidget(new QLabel("Directory, ASCII"), 1, 0);
738 cLayout->addWidget(_corrPathLineEdit, 1, 1, 1,30);
739 cLayout->addWidget(new QLabel("Interval"), 2, 0);
740 cLayout->addWidget(_corrIntrComboBox, 2, 1);
741 cLayout->addWidget(new QLabel("Port"), 3, 0);
742 cLayout->addWidget(_corrPortLineEdit, 3, 1);
743 cLayout->addWidget(new QLabel(""), 4, 1);
744 cLayout->setRowStretch(7, 999);
745 cgroup->setLayout(cLayout);
746
747 // Feed Engine
748 // -----------
749 QGridLayout* sLayout = new QGridLayout;
750 sLayout->setColumnMinimumWidth(0,14*ww);
751 _outPortLineEdit->setMaximumWidth(9*ww);
752 _waitTimeSpinBox->setMaximumWidth(9*ww);
753 _binSamplSpinBox->setMaximumWidth(9*ww);
754 _outUPortLineEdit->setMaximumWidth(9*ww);
755
756 sLayout->addWidget(new QLabel("Output decoded observations in ASCII format to feed a real-time GNSS network engine.<br>"),0,0,1,50);
757 sLayout->addWidget(new QLabel("Port"), 1, 0);
758 sLayout->addWidget(_outPortLineEdit, 1, 1);
759 sLayout->addWidget(new QLabel(" Wait for full obs epoch"), 1, 2, Qt::AlignRight);
760 sLayout->addWidget(_waitTimeSpinBox, 1, 3, Qt::AlignLeft);
761 sLayout->addWidget(new QLabel("Sampling"), 2, 0);
762 sLayout->addWidget(_binSamplSpinBox, 2, 1, Qt::AlignLeft);
763 sLayout->addWidget(new QLabel("File (full path)"), 3, 0);
764 sLayout->addWidget(_outFileLineEdit, 3, 1, 1, 10);
765 sLayout->addWidget(new QLabel("Port (unsynchronized)"), 4, 0);
766 sLayout->addWidget(_outUPortLineEdit, 4, 1);
767 sLayout->addWidget(new QLabel(""), 5, 1);
768 sLayout->setRowStretch(6, 999);
769
770 sgroup->setLayout(sLayout);
771
772 // Serial Output
773 // -------------
774 QGridLayout* serLayout = new QGridLayout;
775 serLayout->setColumnMinimumWidth(0,12*ww);
776 _serialBaudRateComboBox->setMaximumWidth(9*ww);
777 _serialFlowControlComboBox->setMaximumWidth(11*ww);
778 _serialDataBitsComboBox->setMaximumWidth(5*ww);
779 _serialParityComboBox->setMaximumWidth(9*ww);
780 _serialStopBitsComboBox->setMaximumWidth(5*ww);
781 _serialAutoNMEAComboBox->setMaximumWidth(14*ww);
782 _serialHeightNMEALineEdit->setMaximumWidth(8*ww);
783 _serialManualNMEASamplingSpinBox->setMaximumWidth(8*ww);
784
785 serLayout->addWidget(new QLabel("Port settings to feed a serial connected receiver.<br>"),0,0,1,30);
786 serLayout->addWidget(new QLabel("Mountpoint"), 1, 0, Qt::AlignLeft);
787 serLayout->addWidget(_serialMountPointLineEdit, 1, 1, 1, 2);
788 serLayout->addWidget(new QLabel("Port name"), 2, 0, Qt::AlignLeft);
789 serLayout->addWidget(_serialPortNameLineEdit, 2, 1, 1, 2);
790 serLayout->addWidget(new QLabel("Baud rate"), 3, 0, Qt::AlignLeft);
791 serLayout->addWidget(_serialBaudRateComboBox, 3, 1);
792 serLayout->addWidget(new QLabel("Flow control"), 3, 2, Qt::AlignRight);
793 serLayout->addWidget(_serialFlowControlComboBox, 3, 3);
794 serLayout->addWidget(new QLabel("Data bits"), 4, 0, Qt::AlignLeft);
795 serLayout->addWidget(_serialDataBitsComboBox, 4, 1);
796 serLayout->addWidget(new QLabel("Parity"), 4, 2, Qt::AlignRight);
797 serLayout->addWidget(_serialParityComboBox, 4, 3);
798 serLayout->addWidget(new QLabel(" Stop bits"), 4, 4, Qt::AlignRight);
799 serLayout->addWidget(_serialStopBitsComboBox, 4, 5);
800 serLayout->addWidget(new QLabel("NMEA"), 5, 0);
801 serLayout->addWidget(_serialAutoNMEAComboBox, 5, 1);
802 serLayout->addWidget(new QLabel(" File (full path)"), 5, 2, Qt::AlignRight);
803 serLayout->addWidget(_serialFileNMEALineEdit, 5, 3, 1,10);
804 serLayout->addWidget(new QLabel("Height"), 5,14, Qt::AlignRight);
805 serLayout->addWidget(_serialHeightNMEALineEdit, 5,15, 1,11);
806 serLayout->addWidget(new QLabel("Sampling"), 5,25, Qt::AlignRight);
807 serLayout->addWidget(_serialManualNMEASamplingSpinBox, 5,26, 1,12);
808 serLayout->addWidget(new QLabel(""), 6, 1);
809 serLayout->setRowStretch(7, 999);
810
811 sergroup->setLayout(serLayout);
812
813 // Outages
814 // -------
815 QGridLayout* aLayout = new QGridLayout;
816 aLayout->setColumnMinimumWidth(0,14*ww);
817 _obsRateComboBox->setMaximumWidth(9*ww);
818 _adviseFailSpinBox->setMaximumWidth(9*ww);
819 _adviseRecoSpinBox->setMaximumWidth(9*ww);
820
821 aLayout->addWidget(new QLabel("Failure and recovery reports, advisory notes.<br>"),0,0,1,50,Qt::AlignLeft);
822 aLayout->addWidget(new QLabel("Observation rate"), 1, 0);
823 aLayout->addWidget(_obsRateComboBox, 1, 1);
824 aLayout->addWidget(new QLabel("Failure threshold"), 2, 0);
825 aLayout->addWidget(_adviseFailSpinBox, 2, 1);
826 aLayout->addWidget(new QLabel("Recovery threshold"), 3, 0);
827 aLayout->addWidget(_adviseRecoSpinBox, 3, 1);
828 aLayout->addWidget(new QLabel("Script (full path)"), 4, 0);
829 aLayout->addWidget(_adviseScriptLineEdit, 4, 1, 1,20);
830 aLayout->addWidget(new QLabel(""), 5, 1);
831 aLayout->setRowStretch(6, 999);
832
833 agroup->setLayout(aLayout);
834
835 // Miscellaneous
836 // -------------
837 QGridLayout* rLayout = new QGridLayout;
838 rLayout->setColumnMinimumWidth(0,14*ww);
839 _perfIntrComboBox->setMaximumWidth(9*ww);
840 _miscPortLineEdit->setMaximumWidth(9*ww);
841
842 rLayout->addWidget(new QLabel("Log latencies or scan RTCM streams for message types and antenna information or output raw data through TCP/IP port.<br>"),0, 0,1,50);
843 rLayout->addWidget(new QLabel("Mountpoint"), 1, 0);
844 rLayout->addWidget(_miscMountLineEdit, 1, 1, 1, 7);
845 rLayout->addWidget(new QLabel("Log latency"), 2, 0);
846 rLayout->addWidget(_perfIntrComboBox, 2, 1);
847 rLayout->addWidget(new QLabel("Scan RTCM"), 3, 0);
848 rLayout->addWidget(_scanRTCMCheckBox, 3, 1);
849 rLayout->addWidget(new QLabel("Port"), 4, 0);
850 rLayout->addWidget(_miscPortLineEdit, 4, 1);
851 rLayout->addWidget(new QLabel(""), 5, 1);
852 rLayout->setRowStretch(6, 999);
853
854 rgroup->setLayout(rLayout);
855
856 // PPP
857 // ---
858 _pppWidgets._dataSource->setMaximumWidth(20*ww);
859 _pppWidgets._corrMount->setMaximumWidth(20*ww);
860
861 QGridLayout* pppLayout1 = new QGridLayout();
862 int ir = 0;
863 pppLayout1->addWidget(new QLabel("Precise Point Positioning - Input and Output."), ir, 0, 1, 7, Qt::AlignLeft);
864 ++ir;
865 pppLayout1->addWidget(new QLabel("Data source"), ir, 0);
866 pppLayout1->addWidget(_pppWidgets._dataSource, ir, 1);
867 pppLayout1->addItem(new QSpacerItem(4*ww, 0), ir, 2);
868 pppLayout1->addWidget(new QLabel(" RINEX Obs file"), ir, 3);
869 pppLayout1->addWidget(_pppWidgets._rinexObs, ir, 4);
870 ++ir;
871 pppLayout1->addWidget(new QLabel(" RINEX Nav file"), ir, 3);
872 pppLayout1->addWidget(_pppWidgets._rinexNav, ir, 4);
873 ++ir;
874 pppLayout1->addWidget(new QLabel("Corrections stream"), ir, 0);
875 pppLayout1->addWidget(_pppWidgets._corrMount, ir, 1);
876 pppLayout1->addWidget(new QLabel(" Correction file"), ir, 3);
877 pppLayout1->addWidget(_pppWidgets._corrFile, ir, 4);
878 ++ir;
879 pppLayout1->addWidget(new QLabel("Coordinates"), ir, 0);
880 pppLayout1->addWidget(_pppWidgets._crdFile, ir, 1);
881 pppLayout1->addWidget(new QLabel(" Logfile"), ir, 3);
882 pppLayout1->addWidget(_pppWidgets._logFile, ir, 4);
883 ++ir;
884 pppLayout1->addWidget(new QLabel("ANTEX file"), ir, 0);
885 pppLayout1->addWidget(_pppWidgets._antexFile, ir, 1);
886
887 pppLayout1->addWidget(new QLabel(" NMEA file"), ir, 3);
888 pppLayout1->addWidget(_pppWidgets._nmeaFile, ir, 4);
889 ++ir;
890 pppLayout1->addWidget(new QLabel(" SNX TRO file"), ir, 3);
891 pppLayout1->addWidget(_pppWidgets._snxtroFile, ir, 4);
892 pppLayout1->addWidget(new QLabel(" Sampling"), ir, 5);
893 pppLayout1->addWidget(_pppWidgets._snxtroSampl, ir, 6);
894 ++ir;
895 pppLayout1->setRowStretch(ir, 999);
896
897 pppGroup1->setLayout(pppLayout1);
898
899
900 _pppWidgets._dataSource->setWhatsThis(tr("<p>Select 'Real-time Streams' for real-time PPP from RTCM streams or 'RINEX Files' for post processing PPP from RINEX files.</p><p><ul><li>Real-time PPP requires that you pull an RTCM stream carrying GNSS observations plus a stream providing corrections to Broadcast Ephemeris. If the observations stream does not contain Broadcast Ephemeris then you must in addition pull a Broadcast Ephemeris stream like 'RTCM3EPH' from NTRIP broadcaster www.igs-ip.net.</li><li>Post processing PPP requires RINEX observation files, RINEX navigation files and a file with corrections to Broadcast Ephemeris in plain ASCII format as saved beforehand using BNC.</li></ul></p><p>Note that BNC allows to carry out PPP solutions simultaneously for several stations.</p>"));
901
902 _pppWidgets._corrMount->setWhatsThis(tr("<p>Specify a 'mountpoint' from the 'Streams' canvas below which provides corrections to Broadcast Ephemeris.</p><p>If you don't specify a corrections stream through this option, BNC will fall back to Single Point Positioning (SPP, positioning from observations and broadcast ephemeris only only) instead of doing PPP.</p>"));
903
904 _pppWidgets._crdFile->setWhatsThis(tr("<p>Enter the full path to an ASCII file which specifies the streams or files of those stations you want to process. Specifying a 'Coordinates' file is optional. If it exists, it should contain one record per station with the following parameters separated by blank characters:<p><ul><li>Specify the station either through<ul><li>the 'Mountpoint' of the station's RTCM stream (when in real-time PPP mode), or</li><li>the 4-charater station ID of the RINEX observations file (when in post processing PPP mode).</li></ul></li><li>Approximate X,Y,Z coordinate components of station's Antenna Reference Point [m] (ARP, specify '0.0 0.0 0.0' if unknown).</li><li>Nort, East and Up component of antenna excentricity [m] (specify '0.0 0.0 0.0' if unknown).</li><li>20 Characters describing the antenna type and radome following the IGS 'ANTEX file' standard (leave blank if unknown).</li></ul></p><p>Records with exclamation mark '!' in the first column or blank records will be interpreted as comment lines and ignored.</p>"));
905
906 _pppWidgets._antexFile->setWhatsThis(tr("<p>Observations in RTCM streams or RINEX files should be referred to the receiver's and to the satellite's Antenna Phase Center (APC) and therefore be corrected for<ul><li>Receiver APC offsets</li><li>Receiver APC variations</li><li>Satellite APC offsets.</li></ul> Specify the full path to an IGS 'ANTEX file' which contains APC offsets and variations.</p><p>If you don't specify an 'ANTEX file' then observations will not be corrected for APC offsets and variations.</p>"));
907
908 _pppWidgets._rinexObs->setWhatsThis(tr("<p>Specify the RINEX observations file.</p>"));
909
910 _pppWidgets._rinexNav->setWhatsThis(tr("<p>Specify the RINEX navigation file.</p>"));
911
912 _pppWidgets._corrFile->setWhatsThis(tr("<p>Specify the Broadcast Ephemeris Corrections file as saved beforehand using BNC.</p><p>If you don't specify corrections through this option, BNC will fall back to Single Point Positioning (SPP, positioning from RINEX Obs and RINEX Nav files only) instead of doing PPP.</p>"));
913
914 _pppWidgets._logFile->setWhatsThis(tr("<p>Specify the path to daily PPP logfiles using e.g. the following syntax (example):</p><p> ./PPP_${STATION}_${DATE}.log</p><p>BNC will produce one daily PPP logfile per station. Variable ${STATION} stands for the affected station and ${DATE} stands for the date.</p>"));
915
916 _pppWidgets._nmeaFile->setWhatsThis(tr("<p>Specify the path to daily NMEA files using e.g. the following syntax (example):</p><p> ./PPP_${STATION}_${DATE}.nmea</p><p>BNC will produce one daily NMEA file per station, mainly to save NMEA GGA sentences from the PPP solution. Variable ${STATION} stands for the affected station and ${DATE} stands for the date.</p>"));
917
918 _pppWidgets._snxtroFile->setWhatsThis(tr("<p>Specify the path to daily SINEX Troposphere files using e.g. the following syntax (example):</p><p> ./PPP_${STATION}${DOY}.${YY}.zpd</p><p>BNC will produce one daily troposphere file per station to save troposphere parameters from the PPP solution in SINEX Troposphere format. Variable ${STATION} stands for the affected station, ${DOY} stands for the Day Of Year, and ${YY} for the year.</p>"));
919
920 _pppWidgets._snxtroSampl->setWhatsThis(tr("<p>Select a 'Sampling' rate for saving troposphere paramers.</p>"));
921
922 _pppWidgets._sigmaC1->setWhatsThis(tr("<p>Enter a sigma for your GNSS C1 code observations in meters.</p><p>The higher the sigma you enter, the less the contribution of C1 code observations to a PPP solution based on a combination of code and phase data. 2.0 is likely to be an appropriate choice.</p><p>Default is an empty option field, meaning<br>'Sigma C1 = 2.0'</p>"));
923
924 _pppWidgets._sigmaL1->setWhatsThis(tr("<p>Enter a sigma for your GNSS L1 phase observations in meters.</p><p>The higher the sigma you enter, the less the contribution of L1 phase observations to a PPP solutions based on a combination of code and phase data. 0.01 is likely to be an appropriate choice.</p><p>Default is an empty option field, meaning<br>'Sigma L1 = 0.01'</p>"));
925
926 _pppWidgets._maxResC1->setWhatsThis(tr("<p>Specify a maximum for residuals from C1 code observations in a PPP solution. '3.0' meters may be an appropriate choise for that.</p><p>If the maximum is exceeded, contributions from the corresponding observation will be ignored in the PPP solution.</p><p>Default is an empty option field, meaning<br>'Max Rex C1 = 3.0'</p>"));
927
928 _pppWidgets._maxResL1->setWhatsThis(tr("<p>Specify a maximum for residuals from L1 code observations in a PPP solution. '0.03' meters may be an appropriate choise for that.</p><p>If the maximum is exceeded, contributions from the corresponding observation will be ignored in the PPP solution.</p><p>Default is an empty option field, meaning<br>'Max Rex L1 = 0.03'</p>"));
929
930 _pppWidgets._eleWgtCode->setWhatsThis(tr("<p>Tic 'Ele Wgt Code' to use satellite Elevation depending Weights for Code observations in the PPP solution.</p>"));
931
932 _pppWidgets._eleWgtPhase->setWhatsThis(tr("<p>Tic 'Ele Wgt Phase' to use satellite Elevation depending Weights for Phase observations in the PPP solution.</p>"));
933
934 _pppWidgets._minObs->setWhatsThis(tr("<p>Select a Minimum Number of Observations per epoch for a PPP solution.</p><p>BNC will only process epochs with observation numbers reaching or exceeding this minimum.</p>"));
935
936 _pppWidgets._minEle->setWhatsThis(tr("<p>Select a Minimum satellite Elevation for observations.</p><p>BNC will ignore an observation if the associated Satellite Elevation does not reach or exceed this minimum.</p><p>Selecting '10 deg' may be an appropriate choise in order to avoid too noisy observations."));
937
938 _pppWidgets._lcGPS->setWhatsThis(tr("<p>Specify which kind of GPS observations you want to use and on which kind of ionosphere-free linear combination of GPS observations you want to base ambiguity resolutions.</p><p><ul><li>Specifying 'P3' means that you request BNC to use code data and the so-called P3 ionosphere-free linear combination of code observations.</li><li>'L3' means that you request BNC to use phase data and the so-called L3 ionosphere-free linear combination of phase observations.</li> <li>'P3&L3' means that you request BNC to use both, code and phase data and the so-called P3 and L3 ionosphere-free linear combination of code and phase observations.</li></ul></p><p>Note that most geodetic receivers support the observation of GPS code and phase data. Hence specifying 'P3&L3' would be a good choice when processing data from such a receiver.</p><p>Specifying 'no' means that you don't want BNC to use GPS data.</p>"));
939
940 _pppWidgets._lcGLONASS->setWhatsThis(tr("<p>Specify which kind of GLONASS observations you want to use and on which kind of ionosphere-free linear combination of GLONASS observations you want to base ambiguity resolutions.</p><p><ul><li>Specifying 'P3' means that you request BNC to use code data and the so-called P3 ionosphere-free linear combination of code observations.</li><li>'L3' means that you request BNC to use phase data and the so-called L3 ionosphere-free linear combination of phase observations.</li> <li>'P3&L3' means that you request BNC to use both, code and phase data and the so-called P3 and L3 ionosphere-free linear combination of code and phase observations.</li></ul></p><p>Specifying 'no' means that you don't want BNC to use GLONASS data.</p>"));
941
942 _pppWidgets._lcGalileo->setWhatsThis(tr("<p>Specify which kind of Galileo observations you want to use and on which kind of of ionosphere-free linear combination of Galileo observations you want to base ambiguity resolutions.</p><p><ul><li>Specifying 'P3' means that you request BNC to use code data and the so-called P3 ionosphere-free linear combination of code observations.</li><li>'L3' means that you request BNC to use phase data and the so-called L3 ionosphere-free linear combination of phase observations.</li> <li>'P3&L3' means that you request BNC to use both, code and phase data and the so-called P3 and L3 ionosphere-free linear combination of code and phase observations.</li></ul></p><p>Specifying on of these options makes only sense if Galileo data are part ot the processed observation stream.</p><p>Specifying 'no' means that you don't want BNC to use Galileo data.</p>"));
943
944 _pppWidgets._lcBDS->setWhatsThis(tr("<p>Specify which kind of BDS observations you want to use and on which kind of ionosphere-free linear combination of BDS observations you want to base ambiguity resolutions.</p><p><ul><li>Specifying 'P3' means that you request BNC to use code data and the so-called P3 ionosphere-free linear combination of code observations.</li><li>'L3' means that you request BNC to use phase data and the so-called L3 ionosphere-free linear combination of phase observations.</li> <li>'P3&L3' means that you request BNC to use both, code and phase data and the so-called P3 and L3 ionosphere-free linear combination of code and phase observations.</li></ul></p><p>Specifying on of these options makes only sense if BDS data are part ot the processed observation stream.</p><p>Specifying 'no' means that you don't want to use BDS data.</p>"));
945
946 QVBoxLayout* pppLayout2 = new QVBoxLayout();
947 pppLayout2->addWidget(new QLabel("Precise Point Positioning - Processed Stations.<br>"));
948 pppLayout2->addWidget(_pppWidgets._staTable, 99);
949 QHBoxLayout* pppLayout2sub = new QHBoxLayout();
950 pppLayout2sub->addWidget(_pppWidgets._addStaButton);
951 pppLayout2sub->addWidget(_pppWidgets._delStaButton);
952 pppLayout2sub->addStretch(99);
953
954 pppLayout2->addLayout(pppLayout2sub);
955
956 pppGroup2->setLayout(pppLayout2);
957
958 QGridLayout* pppLayout3 = new QGridLayout();
959 ir = 0;
960 pppLayout3->addWidget(new QLabel("Precise Point Positioning - Options.<br>"), ir, 0, 1, 2, Qt::AlignLeft);
961 ++ir;
962 pppLayout3->addWidget(new QLabel("GPS LCs"), ir, 0, Qt::AlignLeft);
963 pppLayout3->addWidget(_pppWidgets._lcGPS, ir, 1);
964 pppLayout3->addItem(new QSpacerItem(8*ww, 0), ir, 2);
965 pppLayout3->addWidget(new QLabel("Sigma C1"), ir, 3, Qt::AlignLeft);
966 pppLayout3->addWidget(_pppWidgets._sigmaC1, ir, 4); _pppWidgets._sigmaC1->setMaximumWidth(8*ww);
967 pppLayout3->addItem(new QSpacerItem(8*ww, 0), ir, 5);
968 pppLayout3->addWidget(new QLabel("Sigma L1"), ir, 6, Qt::AlignLeft);
969 pppLayout3->addWidget(_pppWidgets._sigmaL1, ir, 7); _pppWidgets._sigmaL1->setMaximumWidth(8*ww);
970 ++ir;
971 pppLayout3->addWidget(new QLabel("GLONASS LCs"), ir, 0, Qt::AlignLeft);
972 pppLayout3->addWidget(_pppWidgets._lcGLONASS, ir, 1);
973 pppLayout3->addWidget(new QLabel("Max Res C1"), ir, 3, Qt::AlignLeft);
974 pppLayout3->addWidget(_pppWidgets._maxResC1, ir, 4); _pppWidgets._maxResC1->setMaximumWidth(8*ww);
975 pppLayout3->addWidget(new QLabel("Max Res L1"), ir, 6, Qt::AlignLeft);
976 pppLayout3->addWidget(_pppWidgets._maxResL1, ir, 7); _pppWidgets._maxResL1->setMaximumWidth(8*ww);
977 ++ir;
978 pppLayout3->addWidget(new QLabel("Galileo LCs"), ir, 0, Qt::AlignLeft);
979 pppLayout3->addWidget(_pppWidgets._lcGalileo, ir, 1);
980 pppLayout3->addWidget(new QLabel("Ele Wgt Code"), ir, 3, Qt::AlignLeft);
981 pppLayout3->addWidget(_pppWidgets._eleWgtCode, ir, 4);
982 pppLayout3->addWidget(new QLabel("Ele Wgt Phase"), ir, 6, Qt::AlignLeft);
983 pppLayout3->addWidget(_pppWidgets._eleWgtPhase, ir, 7);
984 ++ir;
985 pppLayout3->addWidget(new QLabel("BDS LCs"), ir, 0, Qt::AlignLeft);
986 pppLayout3->addWidget(_pppWidgets._lcBDS, ir, 1);
987 pppLayout3->addWidget(new QLabel("Min # of Obs"), ir, 3, Qt::AlignLeft);
988 pppLayout3->addWidget(_pppWidgets._minObs, ir, 4);
989 pppLayout3->addWidget(new QLabel("Min Elevation"), ir, 6, Qt::AlignLeft);
990 pppLayout3->addWidget(_pppWidgets._minEle, ir, 7);
991 ++ir;
992 pppLayout3->addWidget(new QLabel("Wait for clock corr."), ir, 0, Qt::AlignLeft);
993 pppLayout3->addWidget(_pppWidgets._corrWaitTime, ir, 1);
994 pppLayout3->addWidget(new QLabel("Seeding (sec)"), ir, 3, Qt::AlignLeft);
995 pppLayout3->addWidget(_pppWidgets._seedingTime, ir, 4);
996 ++ir;
997 pppLayout3->addWidget(new QLabel(""), ir, 8);
998 pppLayout3->setColumnStretch(8, 999);
999 ++ir;
1000 pppLayout3->addWidget(new QLabel(""), ir, 1);
1001 pppLayout3->setRowStretch(ir, 999);
1002
1003 pppGroup3->setLayout(pppLayout3);
1004
1005 // ------------------------
1006 connect(_pppWidgets._mapWinButton, SIGNAL(clicked()), SLOT(slotMapPPP()));
1007 _pppWidgets._mapSpeedSlider->setMinimumWidth(33*ww);
1008 _pppWidgets._audioResponse->setMaximumWidth(8*ww);
1009
1010 QGridLayout* pppLayout4 = new QGridLayout();
1011 ir = 0;
1012 pppLayout4->addWidget(new QLabel("Precise Point Positioning - Plots.<br>"), ir, 0, 1, 50, Qt::AlignLeft);
1013 ++ir;
1014 pppLayout4->addWidget(new QLabel("PPP Plot"), ir, 0, Qt::AlignLeft);
1015 pppLayout4->addWidget(_pppWidgets._plotCoordinates, ir, 1, Qt::AlignLeft);
1016 pppLayout4->addWidget(new QLabel("Mountpoint"), ir, 2, 1, 10, Qt::AlignLeft);
1017 pppLayout4->addWidget(_pppWidgets._audioResponse, ir, 4, Qt::AlignLeft);
1018 pppLayout4->addWidget(new QLabel("Audio response"), ir, 5, Qt::AlignRight);
1019
1020 ++ir;
1021 pppLayout4->addWidget(new QLabel("Track map"), ir, 0, Qt::AlignLeft);
1022 pppLayout4->addWidget(_pppWidgets._mapWinButton, ir, 1, Qt::AlignLeft);
1023 pppLayout4->addWidget(new QLabel("OSM"), ir, 2, Qt::AlignLeft);
1024 pppLayout4->addWidget(_pppWidgets._useOpenStreetMap, ir, 3, Qt::AlignLeft);
1025 pppLayout4->addWidget(new QLabel("Google"), ir, 3, Qt::AlignRight);
1026 pppLayout4->addWidget(_pppWidgets._useGoogleMap, ir, 4, Qt::AlignLeft);
1027 ++ir;
1028 pppLayout4->addWidget(new QLabel("Dot-properties"), ir, 0, Qt::AlignLeft);
1029 pppLayout4->addWidget(_pppWidgets._mapWinDotSize, ir, 1, Qt::AlignLeft);
1030 pppLayout4->addWidget(new QLabel("Size "), ir, 2, Qt::AlignLeft);
1031 pppLayout4->addWidget(_pppWidgets._mapWinDotColor, ir, 3, Qt::AlignLeft);
1032 pppLayout4->addWidget(new QLabel("Color"), ir, 4, Qt::AlignLeft);
1033 ++ir;
1034 pppLayout4->addWidget(new QLabel("Post-processing speed"), ir, 0, Qt::AlignLeft);
1035 pppLayout4->addWidget(_pppWidgets._mapSpeedSlider, ir, 1, 1, 20, Qt::AlignLeft);
1036 ++ir;
1037 pppLayout4->addWidget(new QLabel(""), ir, 1);
1038 pppLayout4->setRowStretch(ir, 999);
1039
1040 pppGroup4->setLayout(pppLayout4);
1041
1042 // Reqc Processing
1043 // ---------------
1044 _reqcActionComboBox = new QComboBox();
1045 _reqcActionComboBox->setEditable(false);
1046 _reqcActionComboBox->addItems(QString(",Edit/Concatenate,Analyze").split(","));
1047 int ik = _reqcActionComboBox->findText(settings.value("reqcAction").toString());
1048 if (ik != -1) {
1049 _reqcActionComboBox->setCurrentIndex(ik);
1050 }
1051 connect(_reqcActionComboBox, SIGNAL(currentIndexChanged(const QString &)),
1052 this, SLOT(slotBncTextChanged()));
1053
1054 QGridLayout* reqcLayout = new QGridLayout;
1055 _reqcActionComboBox->setMinimumWidth(15*ww);
1056 _reqcActionComboBox->setMaximumWidth(20*ww);
1057
1058 _reqcObsFileChooser = new qtFileChooser(0, qtFileChooser::Files);
1059 _reqcObsFileChooser->setFileName(settings.value("reqcObsFile").toString());
1060 _reqcObsFileChooser->setWhatsThis(tr("<p>Specify the full path to an input observation file in RINEX v2 or v3 format.</p><p>Note that when in 'Analyze' mode, specifying at least one RINEX observation file is mandatory.</p>"));
1061
1062 _reqcNavFileChooser = new qtFileChooser(0, qtFileChooser::Files);
1063 _reqcNavFileChooser->setFileName(settings.value("reqcNavFile").toString());
1064 _reqcNavFileChooser->setWhatsThis(tr("<p>Specify the full path to an input navigation file in RINEX v2 or v3 format.</p><p>Note that when in 'Analyze' mode, specifying at least one RINEX navigation file is mandatory.</p>"));
1065
1066 _reqcOutObsLineEdit = new QLineEdit(settings.value("reqcOutObsFile").toString());
1067 _reqcOutObsLineEdit->setWhatsThis(tr("<p>Specify the full path to a RINEX observation output file.</p><p>Default is an empty option field, meaning that no RINEX observation output file will be produced.</p>"));
1068
1069 _reqcOutNavLineEdit = new QLineEdit(settings.value("reqcOutNavFile").toString());
1070 _reqcOutNavLineEdit->setWhatsThis(tr("<p>Specify the full path to a RINEX navigation output file.</p><p>Default is an empty option field, meaning that no RINEX navigation output file will be produced.</p>"));
1071
1072 _reqcOutLogLineEdit = new QLineEdit(settings.value("reqcOutLogFile").toString());
1073 _reqcOutLogLineEdit->setWhatsThis(tr("<p>Specify the full path to a logfile.</p><p>Default is an empty option field, meaning that no 'RINEX Editing & QC' logfile will be produced.</p>"));
1074
1075 _reqcPlotDirLineEdit = new QLineEdit(settings.value("reqcPlotDir").toString());
1076 _reqcPlotDirLineEdit->setWhatsThis(tr("<p>Specify a directory for saving plots in PNG format.</p><p>Default is an empty option field, meaning that plots will not be saved on disk.</p>"));
1077
1078 _reqcSkyPlotSignals = new QLineEdit(settings.value("reqcSkyPlotSignals").toString());
1079 _reqcSkyPlotSignals->setWhatsThis(tr("<p>BNC can produce plots for multipath, signal-to-noise ratio, satellite availability, satellite elevation, and PDOP values. The 'Plots for signals' option lets you exactly specify the observation signals to be used for that and also enables the plot production. You can specify the navigation system, the frequency, and the tracking mode or channel as defined in RINEX Version 3. Specifications for fequency and tracking mode or channel must be seperated by ampersand character '&'. Specifications for each navigation systems must be seperated by blank character ' '.</p><p>Examples for 'Plots for signals' option:<ul><li> G:1&2 R:1&2 J:1&2 E:1&7 C:1&6 S:1<br>(Plots will be based on GPS observations on 1st and 2nd frequency, GLONASS observations on 1st and 2nd frequency, QZSS observations on 1st and 2nd frequency, Galileo observations on 1st and 7th frequency, BeiDou observations on 1st and 6th frequency, SBAS observations on 1st frequency.)</li><li>G:1C&5X<br>(Plots will be based on GPS observations on 1st frequency in C tracking mode and GPS observations on 5th frequency in X tracking mode.)</li><li>C:6I&7I<br>(Plots will be based on BeiDou observations on 6th frequency in I tracking mode and BeiDou observations on 7th frequency in I tracking mode.)<li></ul></p><p>Default is 'C:2&7 E:1&5 G:1&2 J:1&2 R:1&2 S:1&5'. Specifying an empty option string would be overruled by this default.</p>"));
1080
1081 connect(_reqcSkyPlotSignals, SIGNAL(textChanged(const QString &)),
1082 this, SLOT(slotBncTextChanged()));
1083
1084 _reqcLogSummaryOnly = new QCheckBox();
1085 _reqcLogSummaryOnly->setCheckState(Qt::CheckState(settings.value("reqcLogSummaryOnly").toInt()));
1086 _reqcLogSummaryOnly->setWhatsThis(tr("<p>By default BNC produces a detailed 'Logfile' providing all information resulting from editing or analyzing RINEX data. If that is too much information, you can limit the logfile contents to a short summary.</p><p>Tick 'Summary only' to suppress a full logfile output and instead produce a logfile containing only summary information.</p>"));
1087
1088 ir = 0;
1089 reqcLayout->addWidget(new QLabel("RINEX file editing, concatenation and quality check.<br>"),ir, 0, 1, 8);
1090 ++ir;
1091 reqcLayout->addWidget(new QLabel("Action"), ir, 0);
1092 reqcLayout->addWidget(_reqcActionComboBox, ir, 1);
1093 _reqcEditOptionButton = new QPushButton("Set Edit Options");
1094 _reqcEditOptionButton->setMinimumWidth(15*ww);
1095 _reqcEditOptionButton->setMaximumWidth(20*ww);
1096
1097 reqcLayout->addWidget(_reqcEditOptionButton, ir, 3);
1098 ++ir;
1099 reqcLayout->addWidget(new QLabel("Input files (full path)"), ir, 0);
1100 reqcLayout->addWidget(_reqcObsFileChooser, ir, 1);
1101 _reqcObsFileChooser->setMaximumWidth(40*ww);
1102 reqcLayout->addWidget(new QLabel(" Obs"), ir, 2);
1103 reqcLayout->addWidget(_reqcNavFileChooser, ir, 3);
1104 _reqcNavFileChooser->setMaximumWidth(40*ww);
1105 reqcLayout->addWidget(new QLabel(" Nav"), ir, 4);
1106 ++ir;
1107 reqcLayout->addWidget(new QLabel("Output files (full path)"), ir, 0);
1108 reqcLayout->addWidget(_reqcOutObsLineEdit, ir, 1);
1109 _reqcOutObsLineEdit->setMaximumWidth(40*ww);
1110 reqcLayout->addWidget(new QLabel(" Obs"), ir, 2);
1111 reqcLayout->addWidget(_reqcOutNavLineEdit, ir, 3);
1112 _reqcOutNavLineEdit->setMaximumWidth(40*ww);
1113 reqcLayout->addWidget(new QLabel(" Nav"), ir, 4);
1114 ++ir;
1115 reqcLayout->addWidget(new QLabel("Logfile"), ir, 0);
1116 reqcLayout->addWidget(_reqcOutLogLineEdit, ir, 1);
1117 _reqcOutLogLineEdit->setMaximumWidth(40*ww);
1118 reqcLayout->addWidget(new QLabel(" Summary only"), ir, 2);
1119 reqcLayout->addWidget(_reqcLogSummaryOnly, ir, 3);
1120 ++ir;
1121 reqcLayout->addWidget(new QLabel("Plots for signals"), ir, 0);
1122 reqcLayout->addWidget(_reqcSkyPlotSignals, ir, 1);
1123 _reqcSkyPlotSignals->setMaximumWidth(40*ww);
1124 ++ir;
1125 reqcLayout->addWidget(new QLabel("Directory for plots"), ir, 0);
1126 reqcLayout->addWidget(_reqcPlotDirLineEdit, ir, 1);
1127 _reqcPlotDirLineEdit->setMaximumWidth(40*ww);
1128 ++ir;
1129 reqcLayout->setRowStretch(ir, 999);
1130
1131 reqcLayout->setColumnMinimumWidth(2, 8*ww);
1132 reqcLayout->setColumnMinimumWidth(4, 8*ww);
1133
1134 reqcgroup->setLayout(reqcLayout);
1135
1136 connect(_reqcEditOptionButton, SIGNAL(clicked()),
1137 this, SLOT(slotReqcEditOption()));
1138
1139 QGridLayout* sp3CompLayout = new QGridLayout;
1140
1141 _sp3CompFileChooser = new qtFileChooser(0, qtFileChooser::Files);
1142 _sp3CompFileChooser->setFileName(settings.value("sp3CompFile").toString());
1143 _sp3CompFileChooser->setWhatsThis(tr("<p>BNC can compare two SP3 files containing GNSS satellite orbit and clock information.</p></p>Specify the full path to two files with orbits and clocks in SP3 format, separate them by comma.</p>"));
1144 _sp3CompFileChooser->setMinimumWidth(15*ww);
1145 _sp3CompFileChooser->setMaximumWidth(40*ww);
1146
1147 _sp3CompExclude = new QLineEdit(settings.value("sp3CompExclude").toString());
1148 _sp3CompExclude->setMinimumWidth(18*ww);
1149 _sp3CompExclude->setMaximumWidth(18*ww);
1150 _sp3CompExclude->setWhatsThis(tr("<p>Specify satellites to exclude them from orbit and clock comparision. Example:<p>G04,G31,R</p><p>This excludes GPS satellites RPN 4 and 31 as well as all GLONASS satellites from the comparision.</p><p>Default is an empty option field, meaning that no satellite is excluded from the comparison.</p>"));
1151
1152 _sp3CompLogLineEdit = new QLineEdit(settings.value("sp3CompOutLogFile").toString());
1153 _sp3CompLogLineEdit->setWhatsThis(tr("<p>Specify the full path to a logfile to save comparison results.</p><p>Specifying a logfile is mandatory. Comparing SP3 files and not saving the results on disk would be meaningless.</p>"));
1154 _sp3CompLogLineEdit->setMinimumWidth(18*ww);
1155 _sp3CompLogLineEdit->setMaximumWidth(18*ww);
1156
1157 ir = 0;
1158 sp3CompLayout->addWidget(new QLabel("Orbit and clock comparison.<br>"), ir, 0, 1, 40);
1159 ++ir;
1160 sp3CompLayout->addWidget(new QLabel("Input SP3 files (full path)"), ir, 0, Qt::AlignLeft);
1161 sp3CompLayout->addWidget(_sp3CompFileChooser, ir, 1, 1, 20);
1162 ++ir;
1163 sp3CompLayout->addWidget(new QLabel("Exclude satellites"), ir, 0, Qt::AlignLeft);
1164 sp3CompLayout->addWidget(_sp3CompExclude, ir, 1, Qt::AlignRight);
1165 ++ir;
1166 sp3CompLayout->addWidget(new QLabel("Logfile"), ir, 0, Qt::AlignLeft);
1167 sp3CompLayout->addWidget(_sp3CompLogLineEdit, ir, 1, Qt::AlignRight);
1168 ++ir;
1169 sp3CompLayout->addWidget(new QLabel(""), ir, 1);
1170 ++ir;
1171 sp3CompLayout->setRowStretch(ir, 999);
1172
1173 sp3CompLayout->setColumnMinimumWidth(2, 8*ww);
1174 sp3CompLayout->setColumnMinimumWidth(4, 8*ww);
1175
1176 sp3CompGroup->setLayout(sp3CompLayout);
1177
1178 connect(_sp3CompFileChooser, SIGNAL(fileNameChanged(const QString &)),
1179 this, SLOT(slotBncTextChanged()));
1180
1181 // Combine Corrections
1182 // -------------------
1183 QGridLayout* cmbLayout = new QGridLayout;
1184
1185 populateCmbTable();
1186 cmbLayout->addWidget(_cmbTable, 0, 0, 8, 3);
1187 cmbLayout->addWidget(new QLabel(" Combine Broadcast Correction streams.<br>"), 1, 6, 1, 10);
1188 cmbLayout->addWidget(addCmbRowButton, 2, 6);
1189 cmbLayout->addWidget(delCmbRowButton, 2, 7);
1190 cmbLayout->addWidget(new QLabel("Method"), 3, 6, Qt::AlignRight);
1191 cmbLayout->addWidget(_cmbMethodComboBox, 3, 7);
1192 cmbLayout->addWidget(new QLabel(" Maximal residuum"), 4, 6, Qt::AlignRight);
1193 cmbLayout->addWidget(_cmbMaxresLineEdit, 4, 7, Qt::AlignRight);
1194 cmbLayout->addWidget(new QLabel("Sampling"), 5, 6, Qt::AlignRight);
1195 cmbLayout->addWidget(_cmbSamplSpinBox, 5, 7);
1196 cmbLayout->addWidget(new QLabel(" Use GLONASS"), 6, 6, Qt::AlignRight);
1197 cmbLayout->addWidget(_cmbUseGlonass, 6, 7);
1198 cmbLayout->setRowStretch(7, 999);
1199
1200 connect(addCmbRowButton, SIGNAL(clicked()), this, SLOT(slotAddCmbRow()));
1201 connect(delCmbRowButton, SIGNAL(clicked()), this, SLOT(slotDelCmbRow()));
1202
1203 cmbgroup->setLayout(cmbLayout);
1204
1205 // Upload Layout (Clocks)
1206 // ----------------------
1207 QGridLayout* uploadHlpLayout = new QGridLayout();
1208
1209 connect(addUploadRowButton, SIGNAL(clicked()), this, SLOT(slotAddUploadRow()));
1210 connect(delUploadRowButton, SIGNAL(clicked()), this, SLOT(slotDelUploadRow()));
1211 connect(setUploadTrafoButton, SIGNAL(clicked()), this, SLOT(slotSetUploadTrafo()));
1212
1213 uploadHlpLayout->addWidget(addUploadRowButton, 0, 0);
1214 uploadHlpLayout->addWidget(delUploadRowButton, 0, 1);
1215 uploadHlpLayout->addWidget(new QLabel("Interval"), 0, 2, Qt::AlignRight);
1216 uploadHlpLayout->addWidget(_uploadIntrComboBox, 0, 3);
1217 uploadHlpLayout->addWidget(new QLabel(" Sampling: Orb"), 0, 4, Qt::AlignRight);
1218 uploadHlpLayout->addWidget(_uploadSamplRtcmEphCorrSpinBox, 0, 5);
1219 uploadHlpLayout->addWidget(new QLabel("SP3"), 0, 6, Qt::AlignRight);
1220 uploadHlpLayout->addWidget(_uploadSamplSp3SpinBox, 0, 7);
1221 uploadHlpLayout->addWidget(new QLabel("RNX"), 0, 8, Qt::AlignRight);
1222 uploadHlpLayout->addWidget(_uploadSamplClkRnxSpinBox, 0, 9);
1223 uploadHlpLayout->addWidget(setUploadTrafoButton, 0,10);
1224 uploadHlpLayout->addWidget(new QLabel("ANTEX file"), 1, 0, Qt::AlignLeft);
1225 uploadHlpLayout->addWidget(_uploadAntexFile, 1, 1, 1, 4);
1226
1227 QBoxLayout* uploadLayout = new QBoxLayout(QBoxLayout::TopToBottom);
1228 populateUploadTable();
1229
1230 uploadLayout->addWidget(new QLabel("Upload RTCM Version 3 Broadcast Corrections to caster.<br>"));
1231 uploadLayout->addWidget(_uploadTable);
1232 uploadLayout->addLayout(uploadHlpLayout);
1233
1234 uploadgroup->setLayout(uploadLayout);
1235
1236 // Upload Layout (Ephemeris)
1237 // -------------------------
1238 QGridLayout* uploadLayoutEph = new QGridLayout;
1239
1240 uploadLayoutEph->setColumnMinimumWidth(0, 9*ww);
1241 _uploadEphPortLineEdit->setMaximumWidth(9*ww);
1242 _uploadEphPasswordLineEdit->setMaximumWidth(9*ww);
1243 _uploadEphMountpointLineEdit->setMaximumWidth(12*ww);
1244
1245 uploadLayoutEph->addWidget(new QLabel("Upload concatenated RTCMv3 Broadcast Ephemeris to caster.<br>"), 0, 0, 1, 50);
1246 uploadLayoutEph->addWidget(new QLabel("Host"), 1, 0);
1247 uploadLayoutEph->addWidget(_uploadEphHostLineEdit, 1, 1, 1, 3);
1248 uploadLayoutEph->addWidget(new QLabel(" Port"), 1, 4, Qt::AlignRight);
1249 uploadLayoutEph->addWidget(_uploadEphPortLineEdit, 1, 5, 1, 1);
1250 uploadLayoutEph->addWidget(new QLabel("Mountpoint "), 2, 0);
1251 uploadLayoutEph->addWidget(_uploadEphMountpointLineEdit, 2, 1);
1252 uploadLayoutEph->addWidget(new QLabel(" Password"), 2, 2, Qt::AlignRight);
1253 uploadLayoutEph->addWidget(_uploadEphPasswordLineEdit, 2, 3);
1254 uploadLayoutEph->addWidget(new QLabel("Sampling"), 3, 0);
1255 uploadLayoutEph->addWidget(_uploadEphSampleSpinBox, 3, 1);
1256 uploadLayoutEph->addWidget(new QLabel("Uploaded"), 4, 0);
1257 uploadLayoutEph->addWidget(_uploadEphBytesCounter, 4, 1);
1258 uploadLayoutEph->setRowStretch(5, 999);
1259
1260 uploadEphgroup->setLayout(uploadLayoutEph);
1261
1262 connect(_uploadEphHostLineEdit, SIGNAL(textChanged(const QString &)),
1263 this, SLOT(slotBncTextChanged()));
1264
1265 // Main Layout
1266 // -----------
1267 QGridLayout* mLayout = new QGridLayout;
1268 _aogroup->setCurrentIndex(settings.value("startTab").toInt());
1269 mLayout->addWidget(_aogroup, 0,0);
1270 mLayout->addWidget(_mountPointsTable, 1,0);
1271 _loggroup->setCurrentIndex(settings.value("statusTab").toInt());
1272 mLayout->addWidget(_loggroup, 2,0);
1273
1274 _canvas->setLayout(mLayout);
1275
1276 // WhatsThis
1277 // ---------
1278 _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>"));
1279 _proxyPortLineEdit->setWhatsThis(tr("<p>Enter your proxy server port number in case a proxy is operated in front of BNC.</p>"));
1280 _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>"));
1281 _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>"));
1282 _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 obs 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>"));
1283 _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."));
1284 _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."));
1285 _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."));
1286 _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."));
1287 _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."));
1288 _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."));
1289 _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."));
1290 _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."));
1291 _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>"));
1292 _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>"));
1293 _rnxFileCheckBox->setWhatsThis(tr("<p>Tick check box 'Skeleton mandatory' in case you want that RINEX files are only produced if skeleton files are available for BNC. If no skeleton file is available for a particular source then no RINEX observation file will be produced from the affected stream.</p><p>Note that a skeleton file contains RINEX header information such as receiver and antenna types. In case of stream conversion to RINEX Version 3 a skeleton file should also contain information on potentially available observation types. A missing skeleton file will therefore enforce BNC to only save a default set of RINEX 3 observation types."));
1294 _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>"));
1295 _autoStartCheckBox->setWhatsThis(tr("<p>Tick 'Auto start' for auto-start of BNC at startup time in window mode with preassigned processing options.</p>"));
1296 _rawOutFileLineEdit->setWhatsThis(tr("<p>Save all data coming in through various streams in the received order and format in one file.</p>"));
1297 _onTheFlyComboBox->setWhatsThis(tr("<p>When operating BNC online in 'no window' mode, some configuration parameters can be changed on-the-fly without interrupting the running process. For that BNC rereads parts of its configuration in pre-defined intervals.<p></p>Select '1 min', '5 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>"));
1298 _rnxIntrComboBox->setWhatsThis(tr("<p>Select the length of the RINEX Observation file.</p>"));
1299 _ephIntrComboBox->setWhatsThis(tr("<p>Select the length of the RINEX Navigation file.</p>"));
1300 _corrIntrComboBox->setWhatsThis(tr("<p>Select the length of the Broadcast Ephemeris Correction files.</p>"));
1301 _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>"));
1302 _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>"));
1303 _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><p>Default is an empty option field, meaning that you don't want BNC to report on stream failures or recoveries when exceeding a threshold time span.</p>"));
1304 _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>"));
1305 _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>"));
1306 _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."));
1307 _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.</p><p>An empty option field (default) or invalid path means that you don't want to use this option.</p>"));
1308 _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>"));
1309 _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', 'RTCM_3.x' and 'RTNET'.</p><p>In case you need to log the raw data as is, BNC allows users to by-pass its decoders and directly save the input in daily log files. To do this specify the decoder string as 'ZERO'.</p><p>BNC can also retrieve streams from virtual reference stations (VRS). VRS streams are indicated by a 'yes' in the 'nmea' column. To initiate these streams, the approximate latitude/longitude rover position is sent to the NTRIP broadcaster together with an approximation for the height. The default values for latitude and longitude can be change according to your requirement. Double click on 'lat' and 'long' fields, enter the values you wish to send and then hit Enter.</p>"));
1310 _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."));
1311 _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)."));
1312 _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."));
1313 _ephV3CheckBox->setWhatsThis(tr("The default format for output of RINEX Navigation data containing Broadcast Ephemeris is RINEX Version 2. Select 'Version 3' if you want to output the ephemeris in RINEX Version 3 format."));
1314 _rnxV3CheckBox->setWhatsThis(tr("The default format for RINEX Observation files is RINEX Version 2. Select 'Version 3' if you want to save the observations in RINEX Version 3 format."));
1315 _rnxV2Priority->setWhatsThis(tr("<p>Specify a priority list of characters defining signal attributes as defined in RINEX Version 3. Priorities will be used to map observations with RINEX Version 3 attributes from incoming streams to Version 2. The underscore character '_' stands for undefined attributes. A question mark '?' can be used as wildcard which represents any one character.</p><p>Default is priority list 'CWPX_?'.</p>"));
1316 _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>"));
1317 _miscPortLineEdit->setWhatsThis(tr("BNC can output an incoming stream through a TCP/IP port of your local host. Specify a port number here to activate this function."));
1318 _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><p>In case of RTCM Version 3 MSM streams, BNC will also log contained RINEX Version 3 observation types.</p>."));
1319 _serialMountPointLineEdit->setWhatsThis(tr("<p>Enter a 'Mountpoint' to forward the corresponding stream to a serial connected receiver.</p><p>Depending on the stream contents the receiver may use it for Differential GNSS, Precise Point Positioning or any other purpose supported by the firmware.</p>"));
1320 _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>"));
1321 _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>"));
1322 _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>"));
1323 _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>"));
1324 _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>"));
1325 _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>"));
1326 _serialAutoNMEAComboBox->setWhatsThis(tr("<p>The 'NMEA' option supports the so-called 'Virtural Reference Station' (VRS) concept which requires the receiver to send approximate position information to the NTRIP Broadcaster. Select 'no' if you don't want BNC to forward or upload any NMEA message to the NTRIP broadcaster in support of VRS.</p><p>Select 'Auto' to automatically forward NMEA messages of type GGA from your serial connected receiver to the NTRIP broadcaster and/or save them in a file.</p><p>Select 'Manual GPGGA' or 'Manual GNGGA' if you want BNC to produce and upload GPGGA or GNGGA NMEA messages to the NTRIP broadcaster because your serial connected receiver doesn't generate these messages. A Talker ID 'GP' preceding the GGA string stands for GPS solutions while a Talker ID 'GN' stands for multi constellation solutions.</p><p>Note that selecting 'Auto' or 'Manual' works only for VRS streams which show up under the 'Streams' canvas on BNC's main window with 'nmea' stream attribute set to 'yes'. This attribute is either extracted from the NTRIP broadcaster's sourcetable or introduced by the user through editing the BNC configuration file.</p>"));
1327 _serialFileNMEALineEdit->setWhatsThis(tr("<p>Specify the full path to a file where NMEA messages coming from your serial connected receiver are saved.</p><p>Default is an empty option field, meaning that NMEA messages will not be saved on disk.</p>"));
1328 _serialHeightNMEALineEdit->setWhatsThis(tr("<p>Specify an approximate 'Height' above mean sea level in meters for the reference station introduced through 'Mountpoint'. Together with the latitude and longitude from the NTRIP broadcaster sourcetable the height information is used to build GGA messages to be sent to the NTRIP broadcaster.</p><p>For adjusting latitude and longitude values of a VRS stream given in the 'Streams' canvas you can double click the latitude/longitude data fields, specify appropriate values and then hit Enter.</p><p>This option is only relevant when option 'NMEA' is set to 'Manual GPGGA' or 'Manual GNGGA' respectively.</p>"));
1329 _serialManualNMEASamplingSpinBox->setWhatsThis(tr("<p>Select the sampling interval in seconds for manual generation and upload of NMEA GGA sentences.</p><p>A sampling rate of '0' means, the a GGA sentence will be send only once to initialize the requested VRS stream. Note that some VRS systems need GGA sentences at regular intervals.</p>"));
1330 _reqcActionComboBox->setWhatsThis(tr("<p>BNC allows to 'Edit or Concatenate' RINEX v2 or v3 files or to perform a quality check and 'Analyze' the data following UNAVCO's famous 'teqc' program.</p>"));
1331 _reqcEditOptionButton->setWhatsThis(tr("<p>Specify options for editing RINEX v2 or v3 files.</p>"));
1332 _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."));
1333
1334 _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 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 stream for getting hold of the orbit information.</p><p>The combination process requires Broadcast Ephemeris. Besides the orbit and clock corrections stream(s) BNC should therefore pull a stream carrying Broadcast Ephemeris in the form of RTCM Version 3 messages.</p><p>It is possible to specify only one Broadcast Ephemeris corrections stream in the combination table. Instead of combining corrections BNC will then merge them with Broadcast Ephemeris to save results in SP3 and/or Clock RINEX format."));
1335
1336 _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>"));
1337 _cmbSamplSpinBox->setWhatsThis(tr("<p>Specify a combination sampling interval for the Clocks. The clock corrections will be produced following that interval. A value of 10 sec may be an appropriate choice.</p>"));
1338 _cmbUseGlonass->setWhatsThis(tr("<p>In case the incoming orbit and clock correction stream(s) support GLONASS, you can tick 'Use GLONASS' to produce a GPS plus GLONASS combination solution.</p><p>Default is a GPS-only combination."));
1339 _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>"));
1340 _uploadTable->setWhatsThis(tr("<p>BNC can upload clock and orbit corrections to broadcast ephemeris (Broadcast Corrections) in RTCM Version 3 SSR format. You may have a situation where clocks and orbits come from an external Real-time Network Engine (1) or a situation where clock and orbit corrections are combined within BNC (2).</p><p>(1) BNC identifies a stream as coming from a Real-time Network Engine if its format is specified as 'RTNET' and hence its decoder string in the 'Streams' canvas is 'RTNET'. It encodes and uploads that stream to the specified NTRIP broadcaster</p><p>(2) BNC understands that it is expected to encode and upload combined Broadcast Ephemeris corrections if you specify correction streams in the 'Combine Corrections' stream table.</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', 'Mount' and 'Password' fields to enter the NTRIP broadcaster IP port (default is 80), the mountpoint and the stream upload password. An empty 'Host' option field means that you don't want to upload corrections.</p><p>Select a target coordinate reference system (e.g. IGS08) for outgoing clock and orbit corrections.</p><p>By default orbit and clock corrections refer to Antenna Phase Center (APC). Tick 'CoM' to refer uploaded corrections to Center of Mass instead of APC.</p><p>Specify a path for saving the generated Broadcast Corrections plus Broadcast Ephemeris as SP3 orbit files. If the specified directory does not exist, BNC will not create SP3 orbit files. The following is a path example for a Linux system:<br>/home/user/BNC${GPSWD}.sp3<br>Note that '${GPSWD}' produces the GPS Week and Day number in the file name.</p><p>When saving SP3 file contents and/or referring correctors to the satellite's Center of Mass (CoM), an offset has to be applied because correctors originally refer to the satellite's Antenna Phase Center (APC). Antenna offsets are available from the IGS 'ANTEX file' which can be introduced through specifying its path. If you don't specify an 'ANTEX file' path, the SP3 file contents and the orbit and clock correctors will be referred to satellite APCs and not to CoM.</p><p>Specify a path for saving the generated Broadcast Correction clocks plus Broadcast Ephemeris clocks as Clock RINEX files. If the specified directory does not exist, BNC will not create Clock RINEX files. The following is a path example for a Linux system:<br>/home/user/BNC${GPSWD}.clk<br>Note that '${GPSWD}' produces the GPS Week and Day number in the file name.</p><p>Specify finally an SSR Provider ID number, an SSR Solution ID number and an Issue of Data SSR number.</p><p>In case the 'Combine Corrections' table contains only one Broadcast Corrections stream, BNC will merge that stream with Broadcast Ephemeris to save results in files specified here through SP3 and/or Clock RINEX file path. In such a case you should define only the SP3 and Clock RINEX file path and no further options in the 'Upload Corrections' table.</p>"));
1341
1342 addCmbRowButton->setWhatsThis(tr("Hit 'Add Row' button to add another line to the mountpoints table."));
1343 delCmbRowButton->setWhatsThis(tr("Hit 'Delete' button to delete the highlighted line from the mountpoints table."));
1344 addUploadRowButton->setWhatsThis(tr("Hit 'Add Row' button to add another line to the stream upload table."));
1345 delUploadRowButton->setWhatsThis(tr("Hit 'Del Row' button to delete the highlighted line from the stream upload table."));
1346 _uploadIntrComboBox->setWhatsThis(tr("Select the length of the SP3 and Clock RINEX files."));
1347 _uploadSamplRtcmEphCorrSpinBox->setWhatsThis(tr("Select the stream's orbit correction sampling interval in seconds. A value of zero '0' tells BNC to upload all available orbit and clock correction samples together in combined messages."));
1348 _uploadSamplClkRnxSpinBox->setWhatsThis(tr("Select the Clock RINEX file sampling interval in seconds. A value of zero '0' tells BNC to store all available samples into Clock RINEX files."));
1349 _uploadSamplSp3SpinBox->setWhatsThis(tr("Select the SP3 orbit file sampling interval in minutes. A value of zero '0' tells BNC to store all available samples into SP3 orbit files."));
1350 setUploadTrafoButton->setWhatsThis(tr("Hit 'Custom Trafo' to specify your own 14 parameter Helmert Transformation instead of selecting a predefined transformation through 'System' button."));
1351 _uploadAntexFile->setWhatsThis(tr("<p>When producing SP3 files or referring orbit and clock corrections to the satellite's Center of Mass (CoM) instead of Antenna Phase Center (APC), an offset has to be applied which is available from the IGS 'ANTEX file'. You must therefore specify the 'ANTEX file' path if you want to save the stream contents in SP3 format and/or refer correctors to CoM.</p><p>If you don't specify an 'ANTEX file' path, the SP3 file contents as well as the orbit and clock correctors will be referred to satellite APCs.</p>"));
1352 _uploadEphHostLineEdit->setWhatsThis(tr("BNC can upload a Broadcast Ephemeris stream in RTCM Version 3 format. Specify the host IP of an NTRIP Broadcaster to upload the stream. An empty option field means that you don't want to upload Broadcast Ephemeris."));
1353 _uploadEphPortLineEdit->setWhatsThis(tr("Specify the IP port of an NTRIP Broadcaster to upload the stream. Default is port 80."));
1354 _uploadEphMountpointLineEdit->setWhatsThis(tr("Specify the mounpoint for stream upload to an NTRIP Broadcaster."));
1355 _uploadEphPasswordLineEdit->setWhatsThis(tr("Specify the stream upload password protecting the mounpoint on an NTRIP Broadcaster."));
1356 _uploadEphSampleSpinBox->setWhatsThis(tr("Select the Broadcast Ephemeris sampling interval in seconds. Defaut is '5' meaning that a complete set of Broadcast Ephemeris is uploaded every 5 seconds."));
1357 _uploadEphBytesCounter->setWhatsThis(tr("BNC shows the amount of data uploaded through this stream."));
1358 _actDeleteMountPoints->setWhatsThis(tr("<p>Delete stream(s) from selection presented in the 'Streams' canvas.</p>"));
1359 _actAddMountPoints->setWhatsThis(tr("<p>Add stream(s) to selection presented in the 'Streams' canvas.</p>"));
1360 _actMapMountPoints->setWhatsThis(tr("<p> Draw distribution map of stream selection presented in the 'Streams' canvas. Use the mouse to zoom in or out.</p><p>Left button: Draw rectangle to zoom in.<br>Right button: Zoom out.<br>Middle button: Zoom back.</p>"));
1361 _actStart->setWhatsThis(tr("<p> Start running BNC.</p>"));
1362 _actStop->setWhatsThis(tr("<p> Stop running BNC.</p>"));
1363
1364 // Enable/Disable all Widgets
1365 // --------------------------
1366 slotBncTextChanged();
1367 enableStartStop();
1368
1369 // Auto start
1370 // ----------
1371 if ( Qt::CheckState(settings.value("autoStart").toInt()) == Qt::Checked) {
1372 slotStart();
1373 }
1374}
1375
1376// Destructor
1377////////////////////////////////////////////////////////////////////////////
1378bncWindow::~bncWindow() {
1379 delete _caster; BNC_CORE->setCaster(0);
1380 delete _casterEph;
1381}
1382
1383//
1384////////////////////////////////////////////////////////////////////////////
1385void bncWindow::populateMountPointsTable() {
1386
1387 for (int iRow = _mountPointsTable->rowCount()-1; iRow >=0; iRow--) {
1388 _mountPointsTable->removeRow(iRow);
1389 }
1390
1391 bncSettings settings;
1392
1393 QListIterator<QString> it(settings.value("mountPoints").toStringList());
1394 int iRow = 0;
1395 while (it.hasNext()) {
1396 QStringList hlp = it.next().split(" ");
1397 if (hlp.size() < 5) continue;
1398 _mountPointsTable->insertRow(iRow);
1399
1400 QUrl url(hlp[0]);
1401
1402 QString fullPath = url.host() + QString(":%1").arg(url.port()) + url.path();
1403 QString format(hlp[1]); QString latitude(hlp[2]); QString longitude(hlp[3]);
1404 QString nmea(hlp[4]);
1405 if (hlp[5] == "S") {
1406 fullPath = hlp[0].replace(0,2,"");
1407 }
1408 QString ntripVersion = "2";
1409 if (hlp.size() >= 6) {
1410 ntripVersion = (hlp[5]);
1411 }
1412
1413 QTableWidgetItem* it;
1414 it = new QTableWidgetItem(url.userInfo());
1415 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
1416 _mountPointsTable->setItem(iRow, 0, it);
1417
1418 it = new QTableWidgetItem(fullPath);
1419 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
1420 _mountPointsTable->setItem(iRow, 1, it);
1421
1422 it = new QTableWidgetItem(format);
1423 _mountPointsTable->setItem(iRow, 2, it);
1424
1425 if (nmea == "yes") {
1426 it = new QTableWidgetItem(latitude);
1427 _mountPointsTable->setItem(iRow, 3, it);
1428 it = new QTableWidgetItem(longitude);
1429 _mountPointsTable->setItem(iRow, 4, it);
1430 } else {
1431 it = new QTableWidgetItem(latitude);
1432 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
1433 _mountPointsTable->setItem(iRow, 3, it);
1434 it = new QTableWidgetItem(longitude);
1435 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
1436 _mountPointsTable->setItem(iRow, 4, it);
1437 }
1438
1439 it = new QTableWidgetItem(nmea);
1440 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
1441 _mountPointsTable->setItem(iRow, 5, it);
1442
1443 it = new QTableWidgetItem(ntripVersion);
1444 //// it->setFlags(it->flags() & ~Qt::ItemIsEditable);
1445 _mountPointsTable->setItem(iRow, 6, it);
1446
1447 bncTableItem* bncIt = new bncTableItem();
1448 bncIt->setFlags(bncIt->flags() & ~Qt::ItemIsEditable);
1449 _mountPointsTable->setItem(iRow, 7, bncIt);
1450
1451 iRow++;
1452 }
1453
1454 _mountPointsTable->sortItems(1);
1455
1456 enableStartStop();
1457}
1458
1459// Retrieve Table
1460////////////////////////////////////////////////////////////////////////////
1461void bncWindow::slotAddMountPoints() {
1462
1463 bncSettings settings;
1464 QString proxyHost = settings.value("proxyHost").toString();
1465 int proxyPort = settings.value("proxyPort").toInt();
1466 if (proxyHost != _proxyHostLineEdit->text() ||
1467 proxyPort != _proxyPortLineEdit->text().toInt()) {
1468 int iRet = QMessageBox::question(this, "Question", "Proxy options "
1469 "changed. Use the new ones?",
1470 QMessageBox::Yes, QMessageBox::No,
1471 QMessageBox::NoButton);
1472 if (iRet == QMessageBox::Yes) {
1473 settings.setValue("proxyHost", _proxyHostLineEdit->text());
1474 settings.setValue("proxyPort", _proxyPortLineEdit->text());
1475 }
1476 }
1477
1478 settings.setValue("sslCaCertPath", _sslCaCertPathLineEdit->text());
1479 settings.setValue("ignoreSslErrors", _ignoreSslErrorsCheckBox->checkState());
1480
1481 QMessageBox msgBox;
1482 msgBox.setIcon(QMessageBox::Question);
1483 msgBox.setWindowTitle("Add Stream");
1484 msgBox.setText("Add stream(s) coming from:");
1485
1486 QPushButton* buttonNtrip = msgBox.addButton(tr("Caster"), QMessageBox::ActionRole);
1487 QPushButton* buttonIP = msgBox.addButton(tr("TCP/IP port"), QMessageBox::ActionRole);
1488 QPushButton* buttonUDP = msgBox.addButton(tr("UDP port"), QMessageBox::ActionRole);
1489 QPushButton* buttonSerial = msgBox.addButton(tr("Serial port"), QMessageBox::ActionRole);
1490 QPushButton* buttonCancel = msgBox.addButton(tr("Cancel"), QMessageBox::ActionRole);
1491
1492 msgBox.exec();
1493
1494 if (msgBox.clickedButton() == buttonNtrip) {
1495 bncTableDlg* dlg = new bncTableDlg(this);
1496 dlg->move(this->pos().x()+50, this->pos().y()+50);
1497 connect(dlg, SIGNAL(newMountPoints(QStringList*)),
1498 this, SLOT(slotNewMountPoints(QStringList*)));
1499 dlg->exec();
1500 delete dlg;
1501 } else if (msgBox.clickedButton() == buttonIP) {
1502 bncIpPort* ipp = new bncIpPort(this);
1503 connect(ipp, SIGNAL(newMountPoints(QStringList*)),
1504 this, SLOT(slotNewMountPoints(QStringList*)));
1505 ipp->exec();
1506 delete ipp;
1507 } else if (msgBox.clickedButton() == buttonUDP) {
1508 bncUdpPort* udp = new bncUdpPort(this);
1509 connect(udp, SIGNAL(newMountPoints(QStringList*)),
1510 this, SLOT(slotNewMountPoints(QStringList*)));
1511 udp->exec();
1512 delete udp;
1513 } else if (msgBox.clickedButton() == buttonSerial) {
1514 bncSerialPort* sep = new bncSerialPort(this);
1515 connect(sep, SIGNAL(newMountPoints(QStringList*)),
1516 this, SLOT(slotNewMountPoints(QStringList*)));
1517 sep->exec();
1518 delete sep;
1519 } else if (msgBox.clickedButton() == buttonCancel) {
1520 // Cancel
1521 }
1522
1523 enableStartStop();
1524}
1525
1526// Delete Selected Mount Points
1527////////////////////////////////////////////////////////////////////////////
1528void bncWindow::slotDeleteMountPoints() {
1529
1530 int nRows = _mountPointsTable->rowCount();
1531 bool flg[nRows];
1532 for (int iRow = 0; iRow < nRows; iRow++) {
1533 if (_mountPointsTable->isItemSelected(_mountPointsTable->item(iRow,1))) {
1534 flg[iRow] = true;
1535 }
1536 else {
1537 flg[iRow] = false;
1538 }
1539 }
1540 for (int iRow = nRows-1; iRow >= 0; iRow--) {
1541 if (flg[iRow]) {
1542 _mountPointsTable->removeRow(iRow);
1543 }
1544 }
1545 _actDeleteMountPoints->setEnabled(false);
1546
1547 enableStartStop();
1548}
1549
1550// New Mount Points Selected
1551////////////////////////////////////////////////////////////////////////////
1552void bncWindow::slotNewMountPoints(QStringList* mountPoints) {
1553 int iRow = 0;
1554 QListIterator<QString> it(*mountPoints);
1555 while (it.hasNext()) {
1556 QStringList hlp = it.next().split(" ");
1557 QUrl url(hlp[0]);
1558 QString fullPath = url.host() + QString(":%1").arg(url.port()) + url.path();
1559 QString format(hlp[1]); QString latitude(hlp[2]); QString longitude(hlp[3]);
1560 QString nmea(hlp[4]);
1561 if (hlp[5] == "S") {
1562 fullPath = hlp[0].replace(0,2,"");
1563 }
1564 QString ntripVersion = "2";
1565 if (hlp.size() >= 6) {
1566 ntripVersion = (hlp[5]);
1567 }
1568
1569 _mountPointsTable->insertRow(iRow);
1570
1571 QTableWidgetItem* it;
1572 it = new QTableWidgetItem(url.userInfo());
1573 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
1574 _mountPointsTable->setItem(iRow, 0, it);
1575
1576 it = new QTableWidgetItem(fullPath);
1577 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
1578 _mountPointsTable->setItem(iRow, 1, it);
1579
1580 it = new QTableWidgetItem(format);
1581 _mountPointsTable->setItem(iRow, 2, it);
1582
1583 if (nmea == "yes") {
1584 it = new QTableWidgetItem(latitude);
1585 _mountPointsTable->setItem(iRow, 3, it);
1586 it = new QTableWidgetItem(longitude);
1587 _mountPointsTable->setItem(iRow, 4, it);
1588 } else {
1589 it = new QTableWidgetItem(latitude);
1590 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
1591 _mountPointsTable->setItem(iRow, 3, it);
1592 it = new QTableWidgetItem(longitude);
1593 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
1594 _mountPointsTable->setItem(iRow, 4, it);
1595 }
1596
1597 it = new QTableWidgetItem(nmea);
1598 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
1599 _mountPointsTable->setItem(iRow, 5, it);
1600
1601 it = new QTableWidgetItem(ntripVersion);
1602 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
1603 _mountPointsTable->setItem(iRow, 6, it);
1604
1605 bncTableItem* bncIt = new bncTableItem();
1606 _mountPointsTable->setItem(iRow, 7, bncIt);
1607
1608 iRow++;
1609 }
1610 _mountPointsTable->hideColumn(0);
1611 _mountPointsTable->sortItems(1);
1612 delete mountPoints;
1613
1614 enableStartStop();
1615}
1616
1617// Save Options (serialize)
1618////////////////////////////////////////////////////////////////////////////
1619void bncWindow::slotSaveOptions() {
1620 saveOptions();
1621 bncSettings settings;
1622 settings.sync();
1623}
1624
1625// Save Options (memory only)
1626////////////////////////////////////////////////////////////////////////////
1627void bncWindow::saveOptions() {
1628
1629 QStringList mountPoints;
1630 for (int iRow = 0; iRow < _mountPointsTable->rowCount(); iRow++) {
1631
1632 if (_mountPointsTable->item(iRow, 6)->text() != "S") {
1633 QUrl url( "//" + _mountPointsTable->item(iRow, 0)->text() +
1634 "@" + _mountPointsTable->item(iRow, 1)->text() );
1635
1636 mountPoints.append(url.toString() + " " +
1637 _mountPointsTable->item(iRow, 2)->text()
1638 + " " + _mountPointsTable->item(iRow, 3)->text()
1639 + " " + _mountPointsTable->item(iRow, 4)->text()
1640 + " " + _mountPointsTable->item(iRow, 5)->text()
1641 + " " + _mountPointsTable->item(iRow, 6)->text());
1642 } else {
1643 mountPoints.append(
1644 "//" + _mountPointsTable->item(iRow, 1)->text()
1645 + " " + _mountPointsTable->item(iRow, 2)->text()
1646 + " " + _mountPointsTable->item(iRow, 3)->text()
1647 + " " + _mountPointsTable->item(iRow, 4)->text()
1648 + " " + _mountPointsTable->item(iRow, 5)->text()
1649 + " " + _mountPointsTable->item(iRow, 6)->text());
1650 }
1651 }
1652
1653 QStringList combineStreams;
1654 for (int iRow = 0; iRow < _cmbTable->rowCount(); iRow++) {
1655 QString hlp;
1656 for (int iCol = 0; iCol < _cmbTable->columnCount(); iCol++) {
1657 if (_cmbTable->item(iRow, iCol)) {
1658 hlp += _cmbTable->item(iRow, iCol)->text() + " ";
1659 }
1660 }
1661 if (!hlp.isEmpty()) {
1662 combineStreams << hlp;
1663 }
1664 }
1665
1666 QStringList uploadMountpointsOut;
1667 for (int iRow = 0; iRow < _uploadTable->rowCount(); iRow++) {
1668 QString hlp;
1669 for (int iCol = 0; iCol < _uploadTable->columnCount(); iCol++) {
1670 if (_uploadTable->cellWidget(iRow, iCol) &&
1671 (iCol == 3 || iCol == 4 || iCol == 5)) {
1672 if (iCol == 3) {
1673 QLineEdit* passwd = (QLineEdit*)(_uploadTable->cellWidget(iRow, iCol));
1674 hlp += passwd->text() + ",";
1675 }
1676 else if (iCol == 4) {
1677 QComboBox* system = (QComboBox*)(_uploadTable->cellWidget(iRow, iCol));
1678 hlp += system->currentText() + ",";
1679 }
1680 else if (iCol == 5) {
1681 QCheckBox* com = (QCheckBox*)(_uploadTable->cellWidget(iRow, iCol));
1682 QString state; state.setNum(com->checkState());
1683 hlp += state + ",";
1684 }
1685 }
1686 else if (_uploadTable->item(iRow, iCol)) {
1687 hlp += _uploadTable->item(iRow, iCol)->text() + ",";
1688 }
1689 }
1690 if (!hlp.isEmpty()) {
1691 uploadMountpointsOut << hlp;
1692 }
1693 }
1694
1695 bncSettings settings;
1696
1697 settings.setValue("startTab", _aogroup->currentIndex());
1698 settings.setValue("statusTab", _loggroup->currentIndex());
1699 settings.setValue("mountPoints", mountPoints);
1700// Network
1701 settings.setValue("proxyHost", _proxyHostLineEdit->text());
1702 settings.setValue("proxyPort", _proxyPortLineEdit->text());
1703 settings.setValue("sslCaCertPath", _sslCaCertPathLineEdit->text());
1704 settings.setValue("ignoreSslErrors", _ignoreSslErrorsCheckBox->checkState());
1705// General
1706 settings.setValue("logFile", _logFileLineEdit->text());
1707 settings.setValue("rnxAppend", _rnxAppendCheckBox->checkState());
1708 settings.setValue("onTheFlyInterval", _onTheFlyComboBox->currentText());
1709 settings.setValue("autoStart", _autoStartCheckBox->checkState());
1710 settings.setValue("rawOutFile", _rawOutFileLineEdit->text());
1711// RINEX Observations
1712 settings.setValue("rnxPath", _rnxPathLineEdit->text());
1713 settings.setValue("rnxIntr", _rnxIntrComboBox->currentText());
1714 settings.setValue("rnxSampl", _rnxSamplSpinBox->value());
1715 settings.setValue("rnxSkel", _rnxSkelLineEdit->text());
1716 settings.setValue("rnxOnlyWithSKL",_rnxFileCheckBox->checkState());
1717 settings.setValue("rnxV3filenames",_rnxV3filenameCheckBox->checkState());
1718 settings.setValue("rnxScript", _rnxScrpLineEdit->text());
1719 settings.setValue("rnxV3", _rnxV3CheckBox->checkState());
1720 settings.setValue("rnxV2Priority",_rnxV2Priority->text());
1721// RINEX Ephemeris
1722 settings.setValue("ephPath", _ephPathLineEdit->text());
1723 settings.setValue("ephIntr", _ephIntrComboBox->currentText());
1724 settings.setValue("outEphPort", _outEphPortLineEdit->text());
1725 settings.setValue("ephV3", _ephV3CheckBox->checkState());
1726// Broadcast Corrections
1727 settings.setValue("corrPath", _corrPathLineEdit->text());
1728 settings.setValue("corrIntr", _corrIntrComboBox->currentText());
1729 settings.setValue("corrPort", _corrPortLineEdit->text());
1730// Feed Engine
1731 settings.setValue("outPort", _outPortLineEdit->text());
1732 settings.setValue("waitTime", _waitTimeSpinBox->value());
1733 settings.setValue("binSampl", _binSamplSpinBox->value());
1734 settings.setValue("outFile", _outFileLineEdit->text());
1735 settings.setValue("outUPort", _outUPortLineEdit->text());
1736// Serial Output
1737 settings.setValue("serialMountPoint",_serialMountPointLineEdit->text());
1738 settings.setValue("serialPortName", _serialPortNameLineEdit->text());
1739 settings.setValue("serialBaudRate", _serialBaudRateComboBox->currentText());
1740 settings.setValue("serialFlowControl",_serialFlowControlComboBox->currentText());
1741 settings.setValue("serialDataBits", _serialDataBitsComboBox->currentText());
1742 settings.setValue("serialParity", _serialParityComboBox->currentText());
1743 settings.setValue("serialStopBits", _serialStopBitsComboBox->currentText());
1744 settings.setValue("serialAutoNMEA", _serialAutoNMEAComboBox->currentText());
1745 settings.setValue("serialFileNMEA", _serialFileNMEALineEdit->text());
1746 settings.setValue("serialHeightNMEA", _serialHeightNMEALineEdit->text());
1747 settings.setValue("serialManualNMEASampling", _serialManualNMEASamplingSpinBox->value());
1748// Outages
1749 settings.setValue("obsRate", _obsRateComboBox->currentText());
1750 settings.setValue("adviseFail", _adviseFailSpinBox->value());
1751 settings.setValue("adviseReco", _adviseRecoSpinBox->value());
1752 settings.setValue("adviseScript",_adviseScriptLineEdit->text());
1753// Miscellaneous
1754 settings.setValue("miscMount", _miscMountLineEdit->text());
1755 settings.setValue("miscPort", _miscPortLineEdit->text());
1756 settings.setValue("perfIntr", _perfIntrComboBox->currentText());
1757 settings.setValue("scanRTCM", _scanRTCMCheckBox->checkState());
1758// Reqc
1759 settings.setValue("reqcAction", _reqcActionComboBox->currentText());
1760 settings.setValue("reqcObsFile", _reqcObsFileChooser->fileName());
1761 settings.setValue("reqcNavFile", _reqcNavFileChooser->fileName());
1762 settings.setValue("reqcOutObsFile", _reqcOutObsLineEdit->text());
1763 settings.setValue("reqcOutNavFile", _reqcOutNavLineEdit->text());
1764 settings.setValue("reqcOutLogFile", _reqcOutLogLineEdit->text());
1765 settings.setValue("reqcPlotDir", _reqcPlotDirLineEdit->text());
1766 settings.setValue("reqcSkyPlotSignals", _reqcSkyPlotSignals->text());
1767 settings.setValue("reqcLogSummaryOnly", _reqcLogSummaryOnly->checkState());
1768// SP3 Comparison
1769 settings.setValue("sp3CompFile", _sp3CompFileChooser->fileName());
1770 settings.setValue("sp3CompExclude", _sp3CompExclude->text());
1771 settings.setValue("sp3CompOutLogFile", _sp3CompLogLineEdit->text());
1772// Combine Corrections
1773 if (!combineStreams.isEmpty()) {
1774 settings.setValue("combineStreams", combineStreams);
1775 }
1776 else {
1777 settings.setValue("combineStreams", "");
1778 }
1779 settings.setValue("cmbMethod", _cmbMethodComboBox->currentText());
1780 settings.setValue("cmbMaxres", _cmbMaxresLineEdit->text());
1781 settings.setValue("cmbSampl", _cmbSamplSpinBox->value());
1782 settings.setValue("cmbUseGlonass", _cmbUseGlonass->checkState());
1783// Upload Corrections
1784 if (!uploadMountpointsOut.isEmpty()) {
1785 settings.setValue("uploadMountpointsOut", uploadMountpointsOut);
1786 }
1787 else {
1788 settings.setValue("uploadMountpointsOut", "");
1789 }
1790 settings.setValue("uploadIntr", _uploadIntrComboBox->currentText());
1791 settings.setValue("uploadSamplRtcmEphCorr", _uploadSamplRtcmEphCorrSpinBox->value());
1792 settings.setValue("uploadSamplSp3", _uploadSamplSp3SpinBox->value());
1793 settings.setValue("uploadSamplClkRnx", _uploadSamplClkRnxSpinBox->value());
1794 settings.setValue("uploadAntexFile", _uploadAntexFile->fileName());
1795// Upload Ephemeris
1796 settings.setValue("uploadEphHost", _uploadEphHostLineEdit->text());
1797 settings.setValue("uploadEphPort", _uploadEphPortLineEdit->text());
1798 settings.setValue("uploadEphMountpoint",_uploadEphMountpointLineEdit->text());
1799 settings.setValue("uploadEphPassword", _uploadEphPasswordLineEdit->text());
1800 settings.setValue("uploadEphSample", _uploadEphSampleSpinBox->value());
1801
1802 if (_caster) {
1803 _caster->readMountPoints();
1804 }
1805
1806 _pppWidgets.saveOptions();
1807}
1808
1809// All get slots terminated
1810////////////////////////////////////////////////////////////////////////////
1811void bncWindow::slotGetThreadsFinished() {
1812 BNC_CORE->slotMessage("All Get Threads Terminated", true);
1813 delete _caster; _caster = 0; BNC_CORE->setCaster(0);
1814 delete _casterEph; _casterEph = 0;
1815 _runningRealTime = false;
1816}
1817
1818// Start It!
1819////////////////////////////////////////////////////////////////////////////
1820void bncWindow::slotStart() {
1821 saveOptions();
1822 if ( _pppWidgets._dataSource->currentText() == "RINEX Files") {
1823 _runningPPP = true;
1824 enableStartStop();
1825 _caster = new bncCaster(); BNC_CORE->setCaster(_caster);
1826 BNC_CORE->startPPP();
1827 _bncFigurePPP->reset();
1828 }
1829 else if ( !_reqcActionComboBox->currentText().isEmpty() ) {
1830 if (_reqcActionComboBox->currentText() == "Analyze") {
1831 _runningQC = true;
1832 t_reqcAnalyze* reqcAnalyze = new t_reqcAnalyze(this);
1833 connect(reqcAnalyze, SIGNAL(finished()), this, SLOT(slotPostProcessingFinished()));
1834 reqcAnalyze->start();
1835 }
1836 else {
1837 _runningEdit = true;
1838 t_reqcEdit* reqcEdit = new t_reqcEdit(this);
1839 connect(reqcEdit, SIGNAL(finished()), this, SLOT(slotPostProcessingFinished()));
1840 reqcEdit->start();
1841 }
1842 enableStartStop();
1843 }
1844 else if (!_sp3CompFileChooser->fileName().isEmpty()) {
1845 _runningSp3Comp = true;
1846 t_sp3Comp* sp3Comp = new t_sp3Comp(this);
1847 connect(sp3Comp, SIGNAL(finished()), this, SLOT(slotPostProcessingFinished()));
1848 sp3Comp->start();
1849 enableStartStop();
1850 }
1851 else {
1852 startRealTime();
1853 BNC_CORE->startPPP();
1854 }
1855}
1856
1857// Start Real-Time (Retrieve Data etc.)
1858////////////////////////////////////////////////////////////////////////////
1859void bncWindow::startRealTime() {
1860
1861 _runningRealTime = true;
1862
1863 _bncFigurePPP->reset();
1864
1865 _actDeleteMountPoints->setEnabled(false);
1866
1867 enableStartStop();
1868
1869 _caster = new bncCaster();
1870
1871 BNC_CORE->setCaster(_caster);
1872 BNC_CORE->setPortEph(_outEphPortLineEdit->text().toInt());
1873 BNC_CORE->setPortCorr(_corrPortLineEdit->text().toInt());
1874 BNC_CORE->initCombination();
1875
1876 connect(_caster, SIGNAL(getThreadsFinished()),
1877 this, SLOT(slotGetThreadsFinished()));
1878
1879 connect (_caster, SIGNAL(mountPointsRead(QList<bncGetThread*>)),
1880 this, SLOT(slotMountPointsRead(QList<bncGetThread*>)));
1881
1882 BNC_CORE->slotMessage("========== Start BNC v" BNCVERSION " ("BNC_OS") ==========", true);
1883
1884 bncSettings settings;
1885
1886 // Active panels
1887 // -------------
1888 if (!_rnxPathLineEdit->text().isEmpty())
1889 BNC_CORE->slotMessage("Panel 'RINEX Observations' active", true);
1890 if (!_ephPathLineEdit->text().isEmpty())
1891 BNC_CORE->slotMessage("Panel 'RINEX Ephemeris' active", true);
1892 if (!_corrPathLineEdit->text().isEmpty())
1893 BNC_CORE->slotMessage("Panel 'Broadcast Corrections' active", true);
1894 if (!_outPortLineEdit->text().isEmpty())
1895 BNC_CORE->slotMessage("Panel 'Feed Engine' active", true);
1896 if (!_serialMountPointLineEdit->text().isEmpty())
1897 BNC_CORE->slotMessage("Panel 'Serial Output' active", true);
1898 if (!_obsRateComboBox->currentText().isEmpty())
1899 BNC_CORE->slotMessage("Panel 'Outages' active", true);
1900 if (!_miscMountLineEdit->text().isEmpty())
1901 BNC_CORE->slotMessage("Panel 'Miscellaneous' active", true);
1902 if (_pppWidgets._dataSource->currentText() == "Real-Time Streams")
1903 BNC_CORE->slotMessage("Panel 'PPP' active", true);
1904 if (_cmbTable->rowCount() > 0)
1905 BNC_CORE->slotMessage("Panel 'Combine Corrections' active", true);
1906 if (_uploadTable->rowCount() > 0)
1907 BNC_CORE->slotMessage("Panel 'Upload Corrections' active", true);
1908 if (!_uploadEphHostLineEdit->text().isEmpty())
1909 BNC_CORE->slotMessage("Panel 'UploadEphemeris' active", true);
1910
1911 QDir rnxdir(settings.value("rnxPath").toString());
1912 if (!rnxdir.exists()) BNC_CORE->slotMessage("Cannot find RINEX Observations directory", true);
1913
1914 QString rnx_file = settings.value("rnxScript").toString();
1915 if ( !rnx_file.isEmpty() ) {
1916 QFile rnxfile(settings.value("rnxScript").toString());
1917 if (!rnxfile.exists()) BNC_CORE->slotMessage("Cannot find RINEX Observations script", true);
1918 }
1919
1920 QDir ephdir(settings.value("ephPath").toString());
1921 if (!ephdir.exists()) BNC_CORE->slotMessage("Cannot find RINEX Ephemeris directory", true);
1922
1923 QDir corrdir(settings.value("corrPath").toString());
1924 if (!corrdir.exists()) BNC_CORE->slotMessage("Cannot find Broadcast Corrections directory", true);
1925
1926 QString advise_file = settings.value("adviseScript").toString();
1927 if ( !advise_file.isEmpty() ) {
1928 QFile advisefile(settings.value("adviseScript").toString());
1929 if (!advisefile.exists()) BNC_CORE->slotMessage("Cannot find Outages script", true);
1930 }
1931
1932 _caster->readMountPoints();
1933
1934 _casterEph = new bncEphUploadCaster();
1935 connect(_casterEph, SIGNAL(newBytes(QByteArray,double)),
1936 _uploadEphBytesCounter, SLOT(slotNewBytes(QByteArray,double)));
1937}
1938
1939// Retrieve Data
1940////////////////////////////////////////////////////////////////////////////
1941void bncWindow::slotStop() {
1942 int iRet = QMessageBox::question(this, "Stop", "Stop retrieving/processing data?",
1943 QMessageBox::Yes, QMessageBox::No,
1944 QMessageBox::NoButton);
1945 if (iRet == QMessageBox::Yes) {
1946 BNC_CORE->stopPPP();
1947 BNC_CORE->stopCombination();
1948 delete _caster; _caster = 0; BNC_CORE->setCaster(0);
1949 delete _casterEph; _casterEph = 0;
1950 _runningRealTime = false;
1951 _runningPPP = false;
1952 enableStartStop();
1953 }
1954}
1955
1956// Close Application gracefully
1957////////////////////////////////////////////////////////////////////////////
1958void bncWindow::closeEvent(QCloseEvent* event) {
1959
1960 int iRet = QMessageBox::question(this, "Close", "Save Options?",
1961 QMessageBox::Yes, QMessageBox::No,
1962 QMessageBox::Cancel);
1963
1964 if (iRet == QMessageBox::Cancel) {
1965 event->ignore();
1966 return;
1967 }
1968 else if (iRet == QMessageBox::Yes) {
1969 slotSaveOptions();
1970 }
1971
1972 BNC_CORE->stopPPP();
1973
1974 QMainWindow::closeEvent(event);
1975}
1976
1977// User changed the selection of mountPoints
1978////////////////////////////////////////////////////////////////////////////
1979void bncWindow::slotSelectionChanged() {
1980 if (_mountPointsTable->selectedItems().isEmpty()) {
1981 _actDeleteMountPoints->setEnabled(false);
1982 }
1983 else {
1984 _actDeleteMountPoints->setEnabled(true);
1985 }
1986}
1987
1988// Display Program Messages
1989////////////////////////////////////////////////////////////////////////////
1990void bncWindow::slotWindowMessage(const QByteArray msg, bool showOnScreen) {
1991 if (showOnScreen ) {
1992 _log->append(QDateTime::currentDateTime().toUTC().toString("yy-MM-dd hh:mm:ss ") + msg);
1993 }
1994}
1995
1996// About Message
1997////////////////////////////////////////////////////////////////////////////
1998void bncWindow::slotAbout() {
1999 new bncAboutDlg(0);
2000}
2001
2002//Flowchart
2003////////////////////////////////////////////////////////////////////////////
2004void bncWindow::slotFlowchart() {
2005 new bncFlowchartDlg(0);
2006}
2007
2008// Help Window
2009////////////////////////////////////////////////////////////////////////////
2010void bncWindow::slotHelp() {
2011 QUrl url;
2012 url.setPath(":bnchelp.html");
2013 new bncHlpDlg(0, url);
2014}
2015
2016// Select Fonts
2017////////////////////////////////////////////////////////////////////////////
2018void bncWindow::slotFontSel() {
2019 bool ok;
2020 QFont newFont = QFontDialog::getFont(&ok, this->font(), this);
2021 if (ok) {
2022 bncSettings settings;
2023 settings.setValue("font", newFont.toString());
2024 QApplication::setFont(newFont);
2025 int ww = QFontMetrics(newFont).width('w');
2026 setMinimumSize(60*ww, 80*ww);
2027 resize(60*ww, 80*ww);
2028 }
2029}
2030
2031// Whats This Help
2032void bncWindow::slotWhatsThis() {
2033 QWhatsThis::enterWhatsThisMode();
2034}
2035
2036//
2037////////////////////////////////////////////////////////////////////////////
2038void bncWindow::slotMountPointsRead(QList<bncGetThread*> threads) {
2039 _threads = threads;
2040
2041 _bncFigure->updateMountPoints();
2042 _bncFigureLate->updateMountPoints();
2043
2044 populateMountPointsTable();
2045 bncSettings settings;
2046 _binSamplSpinBox->setValue(settings.value("binSampl").toInt());
2047 _waitTimeSpinBox->setValue(settings.value("waitTime").toInt());
2048 QListIterator<bncGetThread*> iTh(threads);
2049 while (iTh.hasNext()) {
2050 bncGetThread* thread = iTh.next();
2051 for (int iRow = 0; iRow < _mountPointsTable->rowCount(); iRow++) {
2052 QUrl url( "//" + _mountPointsTable->item(iRow, 0)->text() +
2053 "@" + _mountPointsTable->item(iRow, 1)->text() );
2054 if (url == thread->mountPoint() &&
2055 _mountPointsTable->item(iRow, 3)->text() == thread->latitude() &&
2056 _mountPointsTable->item(iRow, 4)->text() == thread->longitude() ) {
2057 ((bncTableItem*) _mountPointsTable->item(iRow, 7))->setGetThread(thread);
2058 disconnect(thread, SIGNAL(newBytes(QByteArray, double)),
2059 _bncFigure, SLOT(slotNewData(QByteArray, double)));
2060 connect(thread, SIGNAL(newBytes(QByteArray, double)),
2061 _bncFigure, SLOT(slotNewData(QByteArray, double)));
2062 disconnect(thread, SIGNAL(newLatency(QByteArray, double)),
2063 _bncFigureLate, SLOT(slotNewLatency(QByteArray, double)));
2064 connect(thread, SIGNAL(newLatency(QByteArray, double)),
2065 _bncFigureLate, SLOT(slotNewLatency(QByteArray, double)));
2066 break;
2067 }
2068 }
2069 }
2070}
2071
2072//
2073////////////////////////////////////////////////////////////////////////////
2074void bncWindow::CreateMenu() {
2075 // Create Menus
2076 // ------------
2077 _menuFile = menuBar()->addMenu(tr("&File"));
2078 _menuFile->addAction(_actFontSel);
2079 _menuFile->addSeparator();
2080 _menuFile->addAction(_actSaveOpt);
2081 _menuFile->addSeparator();
2082 _menuFile->addAction(_actQuit);
2083
2084 _menuHlp = menuBar()->addMenu(tr("&Help"));
2085 _menuHlp->addAction(_actHelp);
2086 _menuHlp->addAction(_actFlowchart);
2087 _menuHlp->addAction(_actAbout);
2088}
2089
2090// Toolbar
2091////////////////////////////////////////////////////////////////////////////
2092void bncWindow::AddToolbar() {
2093 QToolBar* toolBar = new QToolBar;
2094 addToolBar(Qt::BottomToolBarArea, toolBar);
2095 toolBar->setMovable(false);
2096 toolBar->addAction(_actAddMountPoints);
2097 toolBar->addAction(_actDeleteMountPoints);
2098 toolBar->addAction(_actMapMountPoints);
2099 toolBar->addAction(_actStart);
2100 toolBar->addAction(_actStop);
2101 toolBar->addWidget(new QLabel(" "));
2102 toolBar->addAction(_actwhatsthis);
2103}
2104
2105// About
2106////////////////////////////////////////////////////////////////////////////
2107bncAboutDlg::bncAboutDlg(QWidget* parent) :
2108 QDialog(parent) {
2109
2110 QTextBrowser* tb = new QTextBrowser;
2111 QUrl url; url.setPath(":bncabout.html");
2112 tb->setSource(url);
2113 tb->setReadOnly(true);
2114
2115 int ww = QFontMetrics(font()).width('w');
2116 QPushButton* _closeButton = new QPushButton("Close");
2117 _closeButton->setMaximumWidth(10*ww);
2118 connect(_closeButton, SIGNAL(clicked()), this, SLOT(close()));
2119
2120 QGridLayout* dlgLayout = new QGridLayout();
2121 QLabel* img = new QLabel();
2122 img->setPixmap(QPixmap(":ntrip-logo.png"));
2123 dlgLayout->addWidget(img, 0,0);
2124 dlgLayout->addWidget(new QLabel("BKG Ntrip Client (BNC) Version "BNCVERSION), 0,1);
2125 dlgLayout->addWidget(tb,1,0,1,2);
2126 dlgLayout->addWidget(_closeButton,2,1,Qt::AlignRight);
2127
2128 setLayout(dlgLayout);
2129 resize(60*ww, 60*ww);
2130 setWindowTitle("About BNC");
2131 show();
2132}
2133
2134//
2135////////////////////////////////////////////////////////////////////////////
2136bncAboutDlg::~bncAboutDlg() {
2137};
2138
2139// Flowchart
2140////////////////////////////////////////////////////////////////////////////
2141bncFlowchartDlg::bncFlowchartDlg(QWidget* parent) :
2142 QDialog(parent) {
2143
2144 int ww = QFontMetrics(font()).width('w');
2145 QPushButton* _closeButton = new QPushButton("Close");
2146 _closeButton->setMaximumWidth(10*ww);
2147 connect(_closeButton, SIGNAL(clicked()), this, SLOT(close()));
2148
2149 QGridLayout* dlgLayout = new QGridLayout();
2150 QLabel* img = new QLabel();
2151 img->setPixmap(QPixmap(":bncflowchart.png"));
2152 dlgLayout->addWidget(img, 0,0);
2153 dlgLayout->addWidget(_closeButton,1,0,Qt::AlignLeft);
2154
2155 setLayout(dlgLayout);
2156 setWindowTitle("Flow Chart");
2157 show();
2158}
2159
2160//
2161////////////////////////////////////////////////////////////////////////////
2162bncFlowchartDlg::~bncFlowchartDlg() {
2163};
2164
2165// Enable/Disable Widget (and change its color)
2166////////////////////////////////////////////////////////////////////////////
2167void bncWindow::enableWidget(bool enable, QWidget* widget) {
2168
2169 const static QPalette paletteWhite(QColor(255, 255, 255));
2170 const static QPalette paletteGray(QColor(230, 230, 230));
2171
2172 widget->setEnabled(enable);
2173 if (enable) {
2174 widget->setPalette(paletteWhite);
2175 }
2176 else {
2177 widget->setPalette(paletteGray);
2178 }
2179}
2180
2181// Bnc Text
2182////////////////////////////////////////////////////////////////////////////
2183void bncWindow::slotBncTextChanged(){
2184
2185 const static QPalette paletteWhite(QColor(255, 255, 255));
2186 const static QPalette paletteGray(QColor(230, 230, 230));
2187
2188 bool enable = true;
2189
2190 // Proxy
2191 //------
2192 if (sender() == 0 || sender() == _proxyHostLineEdit) {
2193 enable = !_proxyHostLineEdit->text().isEmpty();
2194 enableWidget(enable, _proxyPortLineEdit);
2195 }
2196
2197 // RINEX Observations
2198 // ------------------
2199 if (sender() == 0 || sender() == _rnxPathLineEdit) {
2200 enable = !_rnxPathLineEdit->text().isEmpty();
2201 enableWidget(enable, _rnxIntrComboBox);
2202 enableWidget(enable, _rnxSamplSpinBox);
2203 enableWidget(enable, _rnxSkelLineEdit);
2204 enableWidget(enable, _rnxFileCheckBox);
2205 enableWidget(enable, _rnxScrpLineEdit);
2206 enableWidget(enable, _rnxV2Priority);
2207 enableWidget(enable, _rnxV3CheckBox);
2208
2209 bool enable1 = true;
2210 enable1 = _rnxV3CheckBox->isChecked();
2211 if (enable && enable1) {
2212 enableWidget(false, _rnxV2Priority);
2213 }
2214 if (enable && !enable1) {
2215 enableWidget(true, _rnxV2Priority);
2216 }
2217 }
2218
2219 // RINEX Observations, Signal Priority
2220 // -----------------------------------
2221 if (sender() == 0 || sender() == _rnxV3CheckBox) {
2222 if (!_rnxPathLineEdit->text().isEmpty()) {
2223 enableWidget(enable, _rnxIntrComboBox);
2224 enable = !_rnxV3CheckBox->isChecked();
2225 enableWidget(enable, _rnxV2Priority);
2226 }
2227 }
2228
2229 // RINEX Ephemeris
2230 // ---------------
2231 if (sender() == 0 || sender() == _ephPathLineEdit || sender() == _outEphPortLineEdit) {
2232 enable = !_ephPathLineEdit->text().isEmpty() || !_outEphPortLineEdit->text().isEmpty();
2233 enableWidget(enable, _ephIntrComboBox);
2234 enableWidget(enable, _ephV3CheckBox);
2235 }
2236
2237 // Broadcast Corrections
2238 // ---------------------
2239 if (sender() == 0 || sender() == _corrPathLineEdit || sender() == _corrPortLineEdit) {
2240 enable = !_corrPathLineEdit->text().isEmpty() || !_corrPortLineEdit->text().isEmpty();
2241 enableWidget(enable, _corrIntrComboBox);
2242 }
2243
2244 // Feed Engine
2245 // -----------
2246 if (sender() == 0 || sender() == _outPortLineEdit || sender() == _outFileLineEdit) {
2247 enable = !_outPortLineEdit->text().isEmpty() || !_outFileLineEdit->text().isEmpty();
2248 enableWidget(enable, _waitTimeSpinBox);
2249 enableWidget(enable, _binSamplSpinBox);
2250 }
2251
2252 // Serial Output
2253 // -------------
2254 if (sender() == 0 || sender() == _serialMountPointLineEdit ||
2255 sender() == _serialAutoNMEAComboBox) {
2256 enable = !_serialMountPointLineEdit->text().isEmpty();
2257 enableWidget(enable, _serialPortNameLineEdit);
2258 enableWidget(enable, _serialBaudRateComboBox);
2259 enableWidget(enable, _serialParityComboBox);
2260 enableWidget(enable, _serialDataBitsComboBox);
2261 enableWidget(enable, _serialStopBitsComboBox);
2262 enableWidget(enable, _serialFlowControlComboBox);
2263 enableWidget(enable, _serialAutoNMEAComboBox);
2264 bool enable2 = enable && _serialAutoNMEAComboBox->currentText() == "Auto";
2265 enableWidget(enable2, _serialFileNMEALineEdit);
2266 bool enable3 = enable && _serialAutoNMEAComboBox->currentText().contains("Manual");
2267 enableWidget(enable3, _serialHeightNMEALineEdit);
2268 enableWidget(enable3, _serialManualNMEASamplingSpinBox);
2269 }
2270
2271 // Outages
2272 // -------
2273 if (sender() == 0 || sender() == _obsRateComboBox) {
2274 enable = !_obsRateComboBox->currentText().isEmpty();
2275 enableWidget(enable, _adviseFailSpinBox);
2276 enableWidget(enable, _adviseRecoSpinBox);
2277 enableWidget(enable, _adviseScriptLineEdit);
2278 }
2279
2280 // Miscellaneous
2281 // -------------
2282 if (sender() == 0 || sender() == _miscMountLineEdit) {
2283 enable = !_miscMountLineEdit->text().isEmpty();
2284 enableWidget(enable, _perfIntrComboBox);
2285 enableWidget(enable, _scanRTCMCheckBox);
2286 enableWidget(enable, _miscPortLineEdit);
2287 }
2288
2289 // Enable/disable Broadcast Ephemerides
2290 // ------------------------------------
2291 if (sender() == 0 || sender() == _uploadEphHostLineEdit) {
2292 enable = !_uploadEphHostLineEdit->text().isEmpty();
2293 enableWidget(enable, _uploadEphPortLineEdit);
2294 enableWidget(enable, _uploadEphMountpointLineEdit);
2295 enableWidget(enable, _uploadEphPasswordLineEdit);
2296 enableWidget(enable, _uploadEphSampleSpinBox);
2297 }
2298
2299 // Combine Corrections
2300 // -------------------
2301 if (sender() == 0 || sender() == _cmbTable) {
2302 int iRow = _cmbTable->rowCount();
2303 if (iRow > 0) {
2304 enableWidget(true, _cmbMethodComboBox);
2305 enableWidget(true, _cmbMaxresLineEdit);
2306 enableWidget(true, _cmbSamplSpinBox);
2307 enableWidget(true, _cmbUseGlonass);
2308 }
2309 else {
2310 enableWidget(false, _cmbMethodComboBox);
2311 enableWidget(false, _cmbMaxresLineEdit);
2312 enableWidget(false, _cmbSamplSpinBox);
2313 enableWidget(false, _cmbUseGlonass);
2314 }
2315 }
2316
2317 // Upload(clk)
2318 // -----------
2319 int iRow = _uploadTable->rowCount();
2320 if (iRow > 0) {
2321 enableWidget(true, _uploadIntrComboBox);
2322 enableWidget(true, _uploadSamplRtcmEphCorrSpinBox);
2323 enableWidget(true, _uploadSamplClkRnxSpinBox);
2324 enableWidget(true, _uploadSamplSp3SpinBox);
2325 enableWidget(true, _uploadAntexFile);
2326 }
2327 else {
2328 enableWidget(false, _uploadIntrComboBox);
2329 enableWidget(false, _uploadSamplRtcmEphCorrSpinBox);
2330 enableWidget(false, _uploadSamplClkRnxSpinBox);
2331 enableWidget(false, _uploadSamplSp3SpinBox);
2332 enableWidget(false, _uploadAntexFile);
2333 }
2334
2335 // QC
2336 // --
2337 if (sender() == 0 || sender() == _reqcActionComboBox || sender() == _reqcSkyPlotSignals) {
2338 enable = !_reqcActionComboBox->currentText().isEmpty();
2339 bool enable10 = _reqcActionComboBox->currentText() == "Edit/Concatenate";
2340// bool enablePlot = !_reqcSkyPlotSignals->text().isEmpty();
2341 enableWidget(enable, _reqcObsFileChooser);
2342 enableWidget(enable, _reqcNavFileChooser);
2343 enableWidget(enable, _reqcOutLogLineEdit);
2344 enableWidget(enable && enable10, _reqcEditOptionButton);
2345 enableWidget(enable && enable10, _reqcOutObsLineEdit);
2346 enableWidget(enable && enable10, _reqcOutNavLineEdit);
2347 enableWidget(enable && !enable10, _reqcLogSummaryOnly);
2348 enableWidget(enable && !enable10, _reqcSkyPlotSignals);
2349// enableWidget(enable && !enable10 && enablePlot, _reqcPlotDirLineEdit);
2350 enableWidget(enable && !enable10, _reqcPlotDirLineEdit);
2351 }
2352
2353 // SP3 File Comparison
2354 // -------------------
2355 if (sender() == 0 || sender() == _sp3CompFileChooser) {
2356 enable = !_sp3CompFileChooser->fileName().isEmpty();
2357 enableWidget(enable, _sp3CompLogLineEdit);
2358 enableWidget(enable, _sp3CompExclude);
2359 }
2360
2361 enableStartStop();
2362}
2363
2364//
2365////////////////////////////////////////////////////////////////////////////
2366void bncWindow::slotAddCmbRow() {
2367 int iRow = _cmbTable->rowCount();
2368 _cmbTable->insertRow(iRow);
2369 for (int iCol = 0; iCol < _cmbTable->columnCount(); iCol++) {
2370 _cmbTable->setItem(iRow, iCol, new QTableWidgetItem(""));
2371 }
2372}
2373
2374//
2375////////////////////////////////////////////////////////////////////////////
2376void bncWindow::slotDelCmbRow() {
2377
2378 const static QPalette paletteWhite(QColor(255, 255, 255));
2379 const static QPalette paletteGray(QColor(230, 230, 230));
2380
2381 int nRows = _cmbTable->rowCount();
2382 bool flg[nRows];
2383 for (int iRow = 0; iRow < nRows; iRow++) {
2384 if (_cmbTable->isItemSelected(_cmbTable->item(iRow,1))) {
2385 flg[iRow] = true;
2386 }
2387 else {
2388 flg[iRow] = false;
2389 }
2390 }
2391 for (int iRow = nRows-1; iRow >= 0; iRow--) {
2392 if (flg[iRow]) {
2393 _cmbTable->removeRow(iRow);
2394 }
2395 }
2396 nRows = _cmbTable->rowCount();
2397 if (nRows < 1) {
2398 enableWidget(false, _cmbMethodComboBox);
2399 enableWidget(false, _cmbMaxresLineEdit);
2400 enableWidget(false, _cmbSamplSpinBox);
2401 enableWidget(false, _cmbUseGlonass);
2402 }
2403}
2404
2405//
2406////////////////////////////////////////////////////////////////////////////
2407void bncWindow::populateCmbTable() {
2408
2409 for (int iRow = _cmbTable->rowCount()-1; iRow >=0; iRow--) {
2410 _cmbTable->removeRow(iRow);
2411 }
2412
2413 bncSettings settings;
2414
2415 int iRow = -1;
2416 QListIterator<QString> it(settings.value("combineStreams").toStringList());
2417 while (it.hasNext()) {
2418 QStringList hlp = it.next().split(" ");
2419 if (hlp.size() > 2) {
2420 ++iRow;
2421 _cmbTable->insertRow(iRow);
2422 }
2423 for (int iCol = 0; iCol < hlp.size(); iCol++) {
2424 _cmbTable->setItem(iRow, iCol, new QTableWidgetItem(hlp[iCol]));
2425 }
2426 }
2427}
2428
2429//
2430////////////////////////////////////////////////////////////////////////////
2431void bncWindow::slotAddUploadRow() {
2432 int iRow = _uploadTable->rowCount();
2433 _uploadTable->insertRow(iRow);
2434 for (int iCol = 0; iCol < _uploadTable->columnCount(); iCol++) {
2435 if (iCol == 3) {
2436 QLineEdit* passwd = new QLineEdit();
2437 passwd->setFrame(false);
2438 passwd->setEchoMode(QLineEdit::PasswordEchoOnEdit);
2439 _uploadTable->setCellWidget(iRow, iCol, passwd);
2440 }
2441 else if (iCol == 4) {
2442 QComboBox* system = new QComboBox();
2443 system->setEditable(false);
2444 system->addItems(QString(",IGS08,ETRF2000,NAD83,GDA94,SIRGAS95,SIRGAS2000,DREF91,Custom").split(","));
2445 system->setFrame(false);
2446 _uploadTable->setCellWidget(iRow, iCol, system);
2447 }
2448 else if (iCol == 5) {
2449 QCheckBox* com = new QCheckBox();
2450 _uploadTable->setCellWidget(iRow, iCol, com);
2451 }
2452 else if (iCol == 11) {
2453 bncTableItem* bncIt = new bncTableItem();
2454 bncIt->setFlags(bncIt->flags() & ~Qt::ItemIsEditable);
2455 _uploadTable->setItem(iRow, iCol, bncIt);
2456 BNC_CORE->_uploadTableItems[iRow] = bncIt;
2457 }
2458 else {
2459 _uploadTable->setItem(iRow, iCol, new QTableWidgetItem(""));
2460 }
2461 }
2462}
2463
2464//
2465////////////////////////////////////////////////////////////////////////////
2466void bncWindow::slotDelUploadRow() {
2467 BNC_CORE->_uploadTableItems.clear();
2468 int nRows = _uploadTable->rowCount();
2469 bool flg[nRows];
2470 for (int iRow = 0; iRow < nRows; iRow++) {
2471 if (_uploadTable->isItemSelected(_uploadTable->item(iRow,1))) {
2472 flg[iRow] = true;
2473 }
2474 else {
2475 flg[iRow] = false;
2476 }
2477 }
2478 for (int iRow = nRows-1; iRow >= 0; iRow--) {
2479 if (flg[iRow]) {
2480 _uploadTable->removeRow(iRow);
2481 }
2482 }
2483 for (int iRow = 0; iRow < _uploadTable->rowCount(); iRow++) {
2484 BNC_CORE->_uploadTableItems[iRow] =
2485 (bncTableItem*) _uploadTable->item(iRow, 11);
2486 }
2487 nRows = _uploadTable->rowCount();
2488 if (nRows < 1) {
2489 enableWidget(false, _uploadIntrComboBox);
2490 enableWidget(false, _uploadSamplRtcmEphCorrSpinBox);
2491 enableWidget(false, _uploadSamplSp3SpinBox);
2492 enableWidget(false, _uploadSamplClkRnxSpinBox);
2493 enableWidget(false, _uploadAntexFile);
2494 }
2495}
2496
2497//
2498////////////////////////////////////////////////////////////////////////////
2499void bncWindow::populateUploadTable() {
2500 for (int iRow = _uploadTable->rowCount()-1; iRow >=0; iRow--) {
2501 _uploadTable->removeRow(iRow);
2502 }
2503
2504 bncSettings settings;
2505
2506 int iRow = -1;
2507 QListIterator<QString> it(settings.value("uploadMountpointsOut").toStringList());
2508 while (it.hasNext()) {
2509 QStringList hlp = it.next().split(",");
2510 if (hlp.size() > 6) {
2511 ++iRow;
2512 _uploadTable->insertRow(iRow);
2513 }
2514 for (int iCol = 0; iCol < hlp.size(); iCol++) {
2515 if (iCol == 3) {
2516 QLineEdit* passwd = new QLineEdit();
2517 passwd->setFrame(false);
2518 passwd->setEchoMode(QLineEdit::PasswordEchoOnEdit);
2519 passwd->setText(hlp[iCol]);
2520 _uploadTable->setCellWidget(iRow, iCol, passwd);
2521 }
2522 else if (iCol == 4) {
2523 QComboBox* system = new QComboBox();
2524 system->setEditable(false);
2525 system->addItems(QString(",IGS08,ETRF2000,NAD83,GDA94,SIRGAS95,SIRGAS2000,DREF91,Custom").split(","));
2526 system->setFrame(false);
2527 system->setCurrentIndex(system->findText(hlp[iCol]));
2528 _uploadTable->setCellWidget(iRow, iCol, system);
2529 }
2530 else if (iCol == 5) {
2531 QCheckBox* com = new QCheckBox();
2532 if (hlp[iCol].toInt() == Qt::Checked) {
2533 com->setCheckState(Qt::Checked);
2534 }
2535 _uploadTable->setCellWidget(iRow, iCol, com);
2536 }
2537 else if (iCol == 11) {
2538 bncTableItem* bncIt = new bncTableItem();
2539 bncIt->setFlags(bncIt->flags() & ~Qt::ItemIsEditable);
2540 _uploadTable->setItem(iRow, iCol, bncIt);
2541 BNC_CORE->_uploadTableItems[iRow] = bncIt;
2542 }
2543 else {
2544 _uploadTable->setItem(iRow, iCol, new QTableWidgetItem(hlp[iCol]));
2545 }
2546 }
2547 }
2548}
2549
2550//
2551////////////////////////////////////////////////////////////////////////////
2552void bncWindow::slotSetUploadTrafo() {
2553 bncCustomTrafo* dlg = new bncCustomTrafo(this);
2554 dlg->exec();
2555 delete dlg;
2556}
2557
2558// Progress Bar Change
2559////////////////////////////////////////////////////////////////////////////
2560void bncWindow::slotPostProcessingProgress(int nEpo) {
2561 _actStart->setText(QString("%1 Epochs").arg(nEpo));
2562}
2563
2564// Post-Processing Reqc Finished
2565////////////////////////////////////////////////////////////////////////////
2566void bncWindow::slotPostProcessingFinished() {
2567 delete _caster; _caster = 0; BNC_CORE->setCaster(0);
2568 _runningPPP = false;
2569 _runningEdit = false;
2570 _runningQC = false;
2571 _runningSp3Comp = false;
2572 _actStart->setText(tr("Sta&rt"));
2573 enableStartStop();
2574}
2575
2576// Edit teqc-like editing options
2577////////////////////////////////////////////////////////////////////////////
2578void bncWindow::slotReqcEditOption() {
2579 saveOptions();
2580 reqcDlg* dlg = new reqcDlg(this);
2581 dlg->move(this->pos().x()+50, this->pos().y()+50);
2582 dlg->exec();
2583 delete dlg;
2584}
2585
2586// Enable/Disable Start and Stop Buttons
2587////////////////////////////////////////////////////////////////////////////
2588void bncWindow::enableStartStop() {
2589 if ( running() ) {
2590 _actStart->setEnabled(false);
2591 if (_runningRealTime || _runningPPP) {
2592 _actStop->setEnabled(true);
2593 }
2594 }
2595 else {
2596 _actStart->setEnabled(true);
2597 _actStop->setEnabled(false);
2598 }
2599}
2600
2601// Show Map
2602////////////////////////////////////////////////////////////////////////////
2603void bncWindow::slotMapMountPoints() {
2604 saveOptions();
2605 t_bncMap* bncMap = new t_bncMap(this);
2606 bncMap->setMinimumSize(800, 600);
2607 bncMap->setWindowTitle("Selected Mountpoints");
2608
2609 bncSettings settings;
2610 QListIterator<QString> it(settings.value("mountPoints").toStringList());
2611 while (it.hasNext()) {
2612 QStringList hlp = it.next().split(" ");
2613 if (hlp.size() < 5) continue;
2614 QUrl url(hlp[0]);
2615 double latDeg = hlp[2].toDouble();
2616 double lonDeg = hlp[3].toDouble();
2617 bncMap->slotNewPoint(QFileInfo(url.path()).fileName(), latDeg, lonDeg);
2618 }
2619
2620 bncMap->show();
2621}
2622
2623// Show Map
2624////////////////////////////////////////////////////////////////////////////
2625void bncWindow::slotMapPPP() {
2626#ifdef QT_WEBKIT
2627 saveOptions();
2628 enableWidget(false, _pppWidgets._mapWinButton);
2629 enableWidget(false, _pppWidgets._useGoogleMap);
2630 enableWidget(false, _pppWidgets._useOpenStreetMap);
2631 enableWidget(false, _pppWidgets._mapWinDotSize);
2632 enableWidget(false, _pppWidgets._mapWinDotColor);
2633
2634 if (!_mapWin) {
2635 _mapWin = new bncMapWin(this);
2636 connect(_mapWin, SIGNAL(mapClosed()), this, SLOT(slotMapPPPClosed()));
2637 connect(BNC_CORE, SIGNAL(newPosition(QByteArray, bncTime, QVector<double>)),
2638 _mapWin, SLOT(slotNewPosition(QByteArray, bncTime, QVector<double>)));
2639 }
2640 _mapWin->show();
2641#else
2642 QMessageBox::information(this, "Information",
2643 "Qt Library compiled without QtWebKit");
2644#endif
2645}
2646
2647// Show Map
2648////////////////////////////////////////////////////////////////////////////
2649void bncWindow::slotMapPPPClosed() {
2650#ifdef QT_WEBKIT
2651 enableWidget(true, _pppWidgets._mapWinButton);
2652 enableWidget(true, _pppWidgets._useGoogleMap);
2653 enableWidget(true, _pppWidgets._useOpenStreetMap);
2654 enableWidget(true, _pppWidgets._mapWinDotSize);
2655 enableWidget(true, _pppWidgets._mapWinDotColor);
2656 if (_mapWin) {
2657 QListIterator<bncGetThread*> it(_threads);
2658 while (it.hasNext()) {
2659 bncGetThread* thread = it.next();
2660 thread->disconnect(_mapWin);
2661 }
2662 _mapWin->deleteLater();
2663 _mapWin = 0;
2664 }
2665#endif
2666}
Note: See TracBrowser for help on using the repository browser.