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

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