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

Last change on this file since 6822 was 6822, checked in by weber, 9 years ago

Documentation completed

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