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

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