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

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