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

Last change on this file was 10955, checked in by stuerze, 3 weeks ago

Possibility to select how satellite attitude is modelled when converting Antenna Phase Center (APC) corrections to
Center-of-Mass (CoM) positions required for SP3 output

File size: 193.0 KB
Line 
1// Part of BNC, a utility for retrieving decoding and
2// converting GNSS data streams from NTRIP broadcasters.
3//
4// Copyright (C) 2007
5// German Federal Agency for Cartography and Geodesy (BKG)
6// http://www.bkg.bund.de
7// Czech Technical University Prague, Department of Geodesy
8// http://www.fsv.cvut.cz
9//
10// Email: euref-ip@bkg.bund.de
11//
12// This program is free software; you can redistribute it and/or
13// modify it under the terms of the GNU General Public License
14// as published by the Free Software Foundation, version 2.
15//
16// This program is distributed in the hope that it will be useful,
17// but WITHOUT ANY WARRANTY; without even the implied warranty of
18// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19// GNU General Public License for more details.
20//
21// You should have received a copy of the GNU General Public License
22// along with this program; if not, write to the Free Software
23// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24
25/* -------------------------------------------------------------------------
26 * BKG NTRIP Client
27 * -------------------------------------------------------------------------
28 *
29 * Class: bncWindow
30 *
31 * Purpose: This class implements the main application window.
32 *
33 * Author: L. Mervart
34 *
35 * Created: 24-Dec-2005
36 *
37 * Changes:
38 *
39 * -----------------------------------------------------------------------*/
40#ifndef WIN32
41#include <unistd.h>
42#else
43#include <windows.h>
44#endif
45#include <iostream>
46#include <QAction>
47#include <QApplication>
48#include <QCheckBox>
49#include <QCloseEvent>
50#include <QComboBox>
51#include <QDialog>
52#include <QFontDialog>
53#include <QGridLayout>
54#include <QHeaderView>
55#include <QLabel>
56#include <QLineEdit>
57#include <QMenu>
58#include <QMenuBar>
59#include <QMessageBox>
60#include <QPushButton>
61#include <QRadioButton>
62#include <QSpinBox>
63#include <QTableWidgetItem>
64#include <QTextEdit>
65#include <QToolBar>
66
67#include "bncwindow.h"
68#include "bnccore.h"
69#include "bncgetthread.h"
70#include "bnctabledlg.h"
71#include "bncipport.h"
72#include "bncudpport.h"
73#include "bncserialport.h"
74#include "bnchlpdlg.h"
75#include "bnchtml.h"
76#include "bnctableitem.h"
77#include "bncsettings.h"
78#include "bncfigure.h"
79#include "bncfigurelate.h"
80#include "bncfigureppp.h"
81#include "bncversion.h"
82#include "bncbytescounter.h"
83#include "bncsslconfig.h"
84#include "upload/bnccustomtrafo.h"
85#include "upload/bncephuploadcaster.h"
86#include "qtfilechooser.h"
87#include "reqcdlg.h"
88#include "bncmap.h"
89#include "rinex/reqcedit.h"
90#include "rinex/reqcanalyze.h"
91#include "orbComp/sp3Comp.h"
92#ifdef QT_WEBENGINE
93# include "map/bncmapwin.h"
94#endif
95
96using namespace std;
97
98// Constructor
99////////////////////////////////////////////////////////////////////////////
100bncWindow::bncWindow() {
101
102 const static QPalette paletteWhite(QColor(255, 255, 255));
103 const static QPalette paletteGray(QColor(230, 230, 230));
104
105 _caster = 0;
106 _casterEph = 0;
107
108 _bncFigure = new bncFigure(this);
109 _bncFigureLate = new bncFigureLate(this);
110 _bncFigurePPP = new bncFigurePPP(this);
111
112 connect(BNC_CORE, SIGNAL(newPosition(QByteArray, bncTime, QVector<double>)),
113 _bncFigurePPP, SLOT(slotNewPosition(QByteArray, bncTime, QVector<double>)));
114
115 connect(BNC_CORE, SIGNAL(progressRnxPPP(int)), this, SLOT(slotPostProcessingProgress(int)));
116 connect(BNC_CORE, SIGNAL(finishedRnxPPP()), this, SLOT(slotPostProcessingFinished()));
117
118 _runningRealTime = false;
119 _runningPPP = false;
120 _runningEdit = false;
121 _runningQC = false;
122 _runningSp3Comp = false;
123 _reqcActionComboBox = 0; // necessary for enableStartStop()
124
125 _mapWin = 0;
126
127 int ww = QFontMetrics(this->font()).horizontalAdvance('w');
128
129 static const QStringList labels = QString("account, Streams: resource loader / mountpoint, decoder, country, lat, long, nmea, ntrip, bytes").split(",");
130
131 setMinimumSize(100 * ww, 70 * ww);
132
133 setWindowTitle(tr("BKG Ntrip Client (BNC) Version " BNCVERSION));
134
135 connect(BNC_CORE, SIGNAL(newMessage(QByteArray, bool)),
136 this, SLOT(slotWindowMessage(QByteArray, bool)));
137
138 // Create Actions
139 // --------------
140 _actHelp = new QAction(tr("&Help Contents"), this);
141 connect(_actHelp, SIGNAL(triggered()), SLOT(slotHelp()));
142
143 _actAbout = new QAction(tr("&About BNC"), this);
144 connect(_actAbout, SIGNAL(triggered()), SLOT(slotAbout()));
145
146 _actFlowchart = new QAction(tr("&Flow Chart"), this);
147 connect(_actFlowchart, SIGNAL(triggered()), SLOT(slotFlowchart()));
148
149 _actFontSel = new QAction(tr("Select &Font"), this);
150 connect(_actFontSel, SIGNAL(triggered()), SLOT(slotFontSel()));
151
152 _actSaveOpt = new QAction(tr("&Reread && Save Configuration"), this);
153 connect(_actSaveOpt, SIGNAL(triggered()), SLOT(slotSaveOptions()));
154
155 _actQuit = new QAction(tr("&Quit"), this);
156 connect(_actQuit, SIGNAL(triggered()), SLOT(close()));
157
158 _actAddMountPoints = new QAction(tr("Add &Stream"), this);
159 connect(_actAddMountPoints, SIGNAL(triggered()), SLOT(slotAddMountPoints()));
160
161 _actDeleteMountPoints = new QAction(tr("&Delete Stream"), this);
162 connect(_actDeleteMountPoints, SIGNAL(triggered()), SLOT(slotDeleteMountPoints()));
163 _actDeleteMountPoints->setEnabled(false);
164
165 _actMapMountPoints = new QAction(tr("&Map"), this);
166 connect(_actMapMountPoints, SIGNAL(triggered()), SLOT(slotMapMountPoints()));
167
168 _actStart = new QAction(tr("Sta&rt"), this);
169 connect(_actStart, SIGNAL(triggered()), SLOT(slotStart()));
170
171 _actStop = new QAction(tr("Sto&p"), this);
172 connect(_actStop, SIGNAL(triggered()), SLOT(slotStop()));
173 connect(_actStop, SIGNAL(triggered()), SLOT(slotMapPPPClosed()));
174
175 _actwhatsthis = new QAction(tr("Help?=Shift+F1"), this);
176 connect(_actwhatsthis, SIGNAL(triggered()), SLOT(slotWhatsThis()));
177
178 CreateMenu();
179 AddToolbar();
180
181 bncSettings settings;
182
183 // Network Options
184 // ---------------
185 _proxyHostLineEdit = new QLineEdit(settings.value("proxyHost").toString());
186 _proxyPortLineEdit = new QLineEdit(settings.value("proxyPort").toString());
187
188 connect(_proxyHostLineEdit, SIGNAL(textChanged(const QString&)),
189 this, SLOT(slotBncTextChanged()));
190
191 _sslCaCertPathLineEdit = new QLineEdit(settings.value("sslCaCertPath").toString());
192 _sslClientCertPathLineEdit = new QLineEdit(settings.value("sslClientCertPath").toString());
193 _sslIgnoreErrorsCheckBox = new QCheckBox();
194 _sslIgnoreErrorsCheckBox->setCheckState(Qt::CheckState(
195 settings.value("sslIgnoreErrors").toInt()));
196
197 // General Options
198 // ---------------
199 _logFileLineEdit = new QLineEdit(settings.value("logFile").toString());
200 _rawOutFileLineEdit = new QLineEdit(settings.value("rawOutFile").toString());
201 _rnxAppendCheckBox = new QCheckBox();
202 _rnxAppendCheckBox->setCheckState(Qt::CheckState(
203 settings.value("rnxAppend").toInt()));
204 _onTheFlyComboBox = new QComboBox();
205 _onTheFlyComboBox->setEditable(false);
206 _onTheFlyComboBox->addItems(QString("no,1 day,1 hour,5 min,1 min").split(","));
207 int go = _onTheFlyComboBox->findText(settings.value("onTheFlyInterval").toString());
208 if (go != -1) {
209 _onTheFlyComboBox->setCurrentIndex(go);
210 }
211 _autoStartCheckBox = new QCheckBox();
212 _autoStartCheckBox->setCheckState(Qt::CheckState(
213 settings.value("autoStart").toInt()));
214
215 // RINEX Observations Options
216 // --------------------------
217 _rnxPathLineEdit = new QLineEdit(settings.value("rnxPath").toString());
218 _rnxIntrComboBox = new QComboBox();
219 _rnxIntrComboBox->setEditable(false);
220 _rnxIntrComboBox->addItems(QString("1 min,2 min,5 min,10 min,15 min,30 min,1 hour,1 day").split(","));
221 int ii = _rnxIntrComboBox->findText(settings.value("rnxIntr").toString());
222 if (ii != -1) {
223 _rnxIntrComboBox->setCurrentIndex(ii);
224 }
225 _rnxSamplComboBox = new QComboBox();
226 _rnxSamplComboBox->setEditable(false);
227 _rnxSamplComboBox->addItems(QString("0.1 sec,1 sec,5 sec,10 sec,15 sec,30 sec,60 sec").split(","));
228 int ij = _rnxSamplComboBox->findText(settings.value("rnxSampl").toString());
229 if (ij != -1) {
230 _rnxSamplComboBox->setCurrentIndex(ij);
231 }
232 _rnxFileCheckBox = new QCheckBox();
233 _rnxFileCheckBox->setCheckState(Qt::CheckState(settings.value("rnxOnlyWithSKL").toInt()));
234 _rnxSkelExtComboBox = new QComboBox();
235 _rnxSkelExtComboBox->setEditable(false);
236 _rnxSkelExtComboBox->addItems(QString("skl,SKL").split(","));
237 int ik = _rnxSkelExtComboBox->findText(settings.value("rnxSkel").toString());
238 if (ik != -1) {
239 _rnxSkelExtComboBox->setCurrentIndex(ik);
240 }
241 _rnxSkelPathLineEdit = new QLineEdit(settings.value("rnxSkelPath").toString());
242 _rnxScrpLineEdit = new QLineEdit(settings.value("rnxScript").toString());
243 _rnxVersComboBox = new QComboBox();
244 _rnxVersComboBox->setEditable(false);
245 _rnxVersComboBox->addItems(QString("4,3,2").split(","));
246 _rnxVersComboBox->setMaximumWidth(7 * ww);
247 int il = _rnxVersComboBox->findText(settings.value("rnxVersion").toString());
248 if (il != -1) {
249 _rnxVersComboBox->setCurrentIndex(il);
250 }
251 QString hlp = settings.value("rnxV2Priority").toString();
252 if (hlp.isEmpty()) {
253 hlp = "G:12&PWCSLX G:5&IQX R:12&PC R:3&IQX R:46&ABX E:16&BCXZ E:578&IQX J:1&SLXCZ J:26&SLX J:5&IQX C:267&IQX C:18&DPX I:ABCX S:1&C S:5&IQX";
254 }
255 _rnxV2Priority = new QLineEdit(hlp);
256
257 connect(_rnxPathLineEdit, SIGNAL(textChanged(const QString&)), this, SLOT(slotBncTextChanged()));
258 connect(_rnxSkelPathLineEdit, SIGNAL(textChanged(const QString&)), this, SLOT(slotBncTextChanged()));
259 connect(_rnxVersComboBox, SIGNAL(currentIndexChanged(const QString&)), this, SLOT(slotBncTextChanged()));
260
261 // RINEX Ephemeris Options
262 // -----------------------
263 _ephPathLineEdit = new QLineEdit(settings.value("ephPath").toString());
264 _ephIntrComboBox = new QComboBox();
265 _ephIntrComboBox->setEditable(false);
266 _ephIntrComboBox->addItems(QString("1 min,2 min,5 min,10 min,15 min,30 min,1 hour,1 day").split(","));
267 int ji = _ephIntrComboBox->findText(settings.value("ephIntr").toString());
268 if (ji != -1) {
269 _ephIntrComboBox->setCurrentIndex(ji);
270 }
271 _ephOutPortLineEdit = new QLineEdit(settings.value("ephOutPort").toString());
272 _ephVersComboBox = new QComboBox();
273 _ephVersComboBox->setEditable(false);
274 _ephVersComboBox->addItems(QString("4,3,2").split(","));
275 _ephVersComboBox->setMaximumWidth(7 * ww);
276 int jk = _ephVersComboBox->findText(settings.value("ephVersion").toString());
277 if (jk != -1) {
278 _ephVersComboBox->setCurrentIndex(jk);
279 }
280 //_ephFilePerStation = new QCheckBox();
281 //_ephFilePerStation->setCheckState(Qt::CheckState(settings.value("ephFilePerStation").toInt()));
282
283 connect(_ephOutPortLineEdit, SIGNAL(textChanged(const QString&)),
284 this, SLOT(slotBncTextChanged()));
285
286 connect(_ephPathLineEdit, SIGNAL(textChanged(const QString&)),
287 this, SLOT(slotBncTextChanged()));
288
289 // Broadcast Corrections Options
290 // -----------------------------
291 _corrPathLineEdit = new QLineEdit(settings.value("corrPath").toString());
292 _corrIntrComboBox = new QComboBox();
293 _corrIntrComboBox->setEditable(false);
294 _corrIntrComboBox->addItems(QString("1 min,2 min,5 min,10 min,15 min,30 min,1 hour,1 day").split(","));
295 int bi = _corrIntrComboBox->findText(settings.value("corrIntr").toString());
296 if (bi != -1) {
297 _corrIntrComboBox->setCurrentIndex(bi);
298 }
299 _corrPortLineEdit = new QLineEdit(settings.value("corrPort").toString());
300
301 connect(_corrPathLineEdit, SIGNAL(textChanged(const QString&)),
302 this, SLOT(slotBncTextChanged()));
303
304 connect(_corrPortLineEdit, SIGNAL(textChanged(const QString&)),
305 this, SLOT(slotBncTextChanged()));
306
307 // Feed Engine Options
308 // -------------------
309 _outPortLineEdit = new QLineEdit(settings.value("outPort").toString());
310 _outWaitSpinBox = new QSpinBox();
311 _outWaitSpinBox->setMinimum(0);
312 _outWaitSpinBox->setMaximum(30);
313 _outWaitSpinBox->setSingleStep(1);
314 _outWaitSpinBox->setSuffix(" sec");
315 _outWaitSpinBox->setValue(settings.value("outWait").toInt());
316 _outSamplComboBox = new QComboBox();
317 _outSamplComboBox->addItems(QString("0.1 sec,1 sec,5 sec,10 sec,15 sec,30 sec,60 sec").split(","));
318 int nn = _outSamplComboBox->findText(settings.value("outSampl").toString());
319 if (nn != -1) {
320 _outSamplComboBox->setCurrentIndex(nn);
321 }
322 _outFileLineEdit = new QLineEdit(settings.value("outFile").toString());
323 _outUPortLineEdit = new QLineEdit(settings.value("outUPort").toString());
324 _outLockTimeCheckBox = new QCheckBox();
325 _outLockTimeCheckBox->setCheckState(Qt::CheckState(settings.value("outLockTime").toInt()));
326
327 connect(_outPortLineEdit, SIGNAL(textChanged(const QString&)),
328 this, SLOT(slotBncTextChanged()));
329
330 connect(_outFileLineEdit, SIGNAL(textChanged(const QString&)),
331 this, SLOT(slotBncTextChanged()));
332
333 connect(_outLockTimeCheckBox, SIGNAL(stateChanged(int)),
334 this, SLOT(slotBncTextChanged()));
335
336 // Serial Output Options
337 // ---------------------
338 _serialMountPointLineEdit = new QLineEdit(settings.value("serialMountPoint").toString());
339 _serialPortNameLineEdit = new QLineEdit(settings.value("serialPortName").toString());
340 _serialBaudRateComboBox = new QComboBox();
341 _serialBaudRateComboBox->addItems(QString("110,300,600,"
342 "1200,2400,4800,9600,19200,38400,57600,115200").split(","));
343 int kk = _serialBaudRateComboBox->findText(settings.value("serialBaudRate").toString());
344 if (kk != -1) {
345 _serialBaudRateComboBox->setCurrentIndex(kk);
346 }
347 _serialFlowControlComboBox = new QComboBox();
348 _serialFlowControlComboBox->addItems(QString("OFF,XONXOFF,HARDWARE").split(","));
349 kk = _serialFlowControlComboBox->findText(settings.value("serialFlowControl").toString());
350 if (kk != -1) {
351 _serialFlowControlComboBox->setCurrentIndex(kk);
352 }
353 _serialDataBitsComboBox = new QComboBox();
354 _serialDataBitsComboBox->addItems(QString("5,6,7,8").split(","));
355 kk = _serialDataBitsComboBox->findText(settings.value("serialDataBits").toString());
356 if (kk != -1) {
357 _serialDataBitsComboBox->setCurrentIndex(kk);
358 }
359 _serialParityComboBox = new QComboBox();
360 _serialParityComboBox->addItems(QString("NONE,ODD,EVEN,SPACE").split(","));
361 kk = _serialParityComboBox->findText(settings.value("serialParity").toString());
362 if (kk != -1) {
363 _serialParityComboBox->setCurrentIndex(kk);
364 }
365 _serialStopBitsComboBox = new QComboBox();
366 _serialStopBitsComboBox->addItems(QString("1,2").split(","));
367 kk = _serialStopBitsComboBox->findText(settings.value("serialStopBits").toString());
368 if (kk != -1) {
369 _serialStopBitsComboBox->setCurrentIndex(kk);
370 }
371 _serialAutoNMEAComboBox = new QComboBox();
372 _serialAutoNMEAComboBox->addItems(QString("no,Auto,Manual GPGGA,Manual GNGGA").split(","));
373 kk = _serialAutoNMEAComboBox->findText(settings.value("serialAutoNMEA").toString());
374 if (kk != -1) {
375 _serialAutoNMEAComboBox->setCurrentIndex(kk);
376 }
377 _serialFileNMEALineEdit = new QLineEdit(settings.value("serialFileNMEA").toString());
378 _serialHeightNMEALineEdit = new QLineEdit(settings.value("serialHeightNMEA").toString());
379
380 _serialNMEASamplingSpinBox = new QSpinBox();
381 _serialNMEASamplingSpinBox->setMinimum(0);
382 _serialNMEASamplingSpinBox->setMaximum(300);
383 _serialNMEASamplingSpinBox->setSingleStep(10);
384 _serialNMEASamplingSpinBox->setValue(settings.value("serialNMEASampling").toInt());
385 _serialNMEASamplingSpinBox->setSuffix(" sec");
386
387 connect(_serialMountPointLineEdit, SIGNAL(textChanged(const QString&)),
388 this, SLOT(slotBncTextChanged()));
389
390 connect(_serialAutoNMEAComboBox, SIGNAL(currentIndexChanged(const QString&)),
391 this, SLOT(slotBncTextChanged()));
392
393 // Outages Options
394 // ---------------
395 _adviseObsRateComboBox = new QComboBox();
396 _adviseObsRateComboBox->setEditable(false);
397 _adviseObsRateComboBox->addItems(QString(",0.1 Hz,0.2 Hz,0.5 Hz,1 Hz,5 Hz").split(","));
398 kk = _adviseObsRateComboBox->findText(settings.value("adviseObsRate").toString());
399 if (kk != -1) {
400 _adviseObsRateComboBox->setCurrentIndex(kk);
401 }
402 _adviseFailSpinBox = new QSpinBox();
403 _adviseFailSpinBox->setMinimum(0);
404 _adviseFailSpinBox->setMaximum(60);
405 _adviseFailSpinBox->setSingleStep(1);
406 _adviseFailSpinBox->setSuffix(" min");
407 _adviseFailSpinBox->setValue(settings.value("adviseFail").toInt());
408 _adviseRecoSpinBox = new QSpinBox();
409 _adviseRecoSpinBox->setMinimum(0);
410 _adviseRecoSpinBox->setMaximum(60);
411 _adviseRecoSpinBox->setSingleStep(1);
412 _adviseRecoSpinBox->setSuffix(" min");
413 _adviseRecoSpinBox->setValue(settings.value("adviseReco").toInt());
414 _adviseScriptLineEdit = new QLineEdit(settings.value("adviseScript").toString());
415
416 connect(_adviseObsRateComboBox, SIGNAL(currentIndexChanged(const QString&)),
417 this, SLOT(slotBncTextChanged()));
418
419 // Miscellaneous Options
420 // ---------------------
421 _miscMountLineEdit = new QLineEdit(settings.value("miscMount").toString());
422 _miscPortLineEdit = new QLineEdit(settings.value("miscPort").toString());
423 _miscIntrComboBox = new QComboBox();
424 _miscIntrComboBox->setEditable(false);
425 _miscIntrComboBox->addItems(QString(",2 sec,10 sec,1 min,5 min,15 min,1 hour,6 hours,1 day").split(","));
426 int ll = _miscIntrComboBox->findText(settings.value("miscIntr").toString());
427 if (ll != -1) {
428 _miscIntrComboBox->setCurrentIndex(ll);
429 }
430 _miscScanRTCMCheckBox = new QCheckBox();
431 _miscScanRTCMCheckBox->setCheckState(Qt::CheckState(
432 settings.value("miscScanRTCM").toInt()));
433
434 connect(_miscMountLineEdit, SIGNAL(textChanged(const QString&)),
435 this, SLOT(slotBncTextChanged()));
436
437 // Streams
438 // -------
439 _mountPointsTable = new QTableWidget(0, 9);
440
441 _mountPointsTable->horizontalHeader()->resizeSection(1, 34 * ww);
442 _mountPointsTable->horizontalHeader()->resizeSection(2, 9 * ww);
443 _mountPointsTable->horizontalHeader()->resizeSection(3, 9 * ww);
444 _mountPointsTable->horizontalHeader()->resizeSection(4, 7 * ww);
445 _mountPointsTable->horizontalHeader()->resizeSection(5, 7 * ww);
446 _mountPointsTable->horizontalHeader()->resizeSection(6, 5 * ww);
447 _mountPointsTable->horizontalHeader()->resizeSection(7, 5 * ww);
448#if QT_VERSION < 0x050000
449 _mountPointsTable->horizontalHeader()->setResizeMode(QHeaderView::Interactive);
450#else
451 _mountPointsTable->horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive);
452#endif
453 _mountPointsTable->horizontalHeader()->setStretchLastSection(true);
454 _mountPointsTable->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft);
455 _mountPointsTable->setHorizontalHeaderLabels(labels);
456 _mountPointsTable->setGridStyle(Qt::NoPen);
457 _mountPointsTable->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
458 _mountPointsTable->setSelectionMode(QAbstractItemView::ExtendedSelection);
459 _mountPointsTable->setSelectionBehavior(QAbstractItemView::SelectRows);
460 _mountPointsTable->hideColumn(0);
461 _mountPointsTable->hideColumn(3);
462 connect(_mountPointsTable, SIGNAL(itemSelectionChanged()),
463 SLOT(slotSelectionChanged()));
464 populateMountPointsTable();
465
466 _log = new QTextEdit();
467 _log->setReadOnly(true);
468 QFont msFont(""); msFont.setStyleHint(QFont::TypeWriter); // default monospace font
469 _log->setFont(msFont);
470 _log->document()->setMaximumBlockCount(1000);
471
472 // Combine Corrections
473 // -------------------
474 _cmbTable = new QTableWidget(0, 5);
475 _cmbTable->setHorizontalHeaderLabels(QString("Mountpoint, AC Name, Weight Factor, Exclude Satellites, Attitude").split(","));
476 _cmbTable->setSelectionMode(QAbstractItemView::ExtendedSelection);
477 _cmbTable->setSelectionBehavior(QAbstractItemView::SelectRows);
478 _cmbTable->setMaximumWidth(50 * ww);
479 _cmbTable->horizontalHeader()->resizeSection(0, 10 * ww);
480 _cmbTable->horizontalHeader()->resizeSection(1, 6 * ww);
481 _cmbTable->horizontalHeader()->resizeSection(2, 9 * ww);
482 _cmbTable->horizontalHeader()->resizeSection(3, 9 * ww);
483 _cmbTable->horizontalHeader()->resizeSection(4, 8 * ww);
484#if QT_VERSION < 0x050000
485 _cmbTable->horizontalHeader()->setResizeMode(QHeaderView::Interactive);
486#else
487 _cmbTable->horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive);
488#endif
489 _cmbTable->horizontalHeader()->setStretchLastSection(true);
490 _cmbTable->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft);
491
492 _cmbMaxresLineEdit = new QLineEdit(settings.value("cmbMaxres").toString());
493 _cmbMaxdisplacementLineEdit = new QLineEdit(settings.value("cmbMaxdisplacement").toString());
494
495 _cmbSamplComboBox = new QComboBox();
496 _cmbSamplComboBox->setEditable(false);
497 _cmbSamplComboBox->addItems(QString("1 sec,2 sec,5 sec,10 sec,15 sec,30 sec,60 sec").split(","));
498 int kl = _cmbSamplComboBox->findText(settings.value("cmbSampl").toString());
499 if (kl != -1) {
500 _cmbSamplComboBox->setCurrentIndex(kl);
501 }
502
503 _cmbLogPath = new QLineEdit(settings.value("cmbLogpath").toString());
504
505 QPushButton* addCmbRowButton = new QPushButton("Add Row");
506 QPushButton* delCmbRowButton = new QPushButton("Delete");
507
508 connect(_cmbTable, SIGNAL(itemSelectionChanged()), SLOT(slotBncTextChanged()));
509
510 _cmbMethodComboBox = new QComboBox();
511 _cmbMethodComboBox->setEditable(false);
512 _cmbMethodComboBox->addItems(QString("Kalman Filter,Single-Epoch").split(","));
513 int cm = _cmbMethodComboBox->findText(settings.value("cmbMethod").toString());
514 if (cm != -1) {
515 _cmbMethodComboBox->setCurrentIndex(cm);
516 }
517
518 int iRow = _cmbTable->rowCount();
519 if (iRow > 0) {
520 enableWidget(true, _cmbMethodComboBox);
521 enableWidget(true, _cmbMaxresLineEdit);
522 enableWidget(true, _cmbMaxdisplacementLineEdit);
523 enableWidget(true, _cmbSamplComboBox);
524 enableWidget(true, _cmbLogPath);
525 }
526 else {
527 enableWidget(false, _cmbMethodComboBox);
528 enableWidget(false, _cmbMaxresLineEdit);
529 enableWidget(false, _cmbMaxdisplacementLineEdit);
530 enableWidget(false, _cmbSamplComboBox);
531 enableWidget(false, _cmbLogPath);
532 }
533 _cmbGpsCheckBox = new QCheckBox();
534 _cmbGpsCheckBox->setCheckState(Qt::CheckState(settings.value("cmbGps").toInt()));
535 _cmbGloCheckBox = new QCheckBox();
536 _cmbGloCheckBox->setCheckState(Qt::CheckState(settings.value("cmbGlo").toInt()));
537 _cmbGalCheckBox = new QCheckBox();
538 _cmbGalCheckBox->setCheckState(Qt::CheckState(settings.value("cmbGal").toInt()));
539 _cmbBdsCheckBox = new QCheckBox();
540 _cmbBdsCheckBox->setCheckState(Qt::CheckState(settings.value("cmbBds").toInt()));
541 _cmbQzssCheckBox = new QCheckBox();
542 _cmbQzssCheckBox->setCheckState(Qt::CheckState(settings.value("cmbQzss").toInt()));
543 _cmbSbasCheckBox = new QCheckBox();
544 _cmbSbasCheckBox->setCheckState(Qt::CheckState(settings.value("cmbSbas").toInt()));
545 _cmbNavicCheckBox = new QCheckBox();
546 _cmbNavicCheckBox->setCheckState(Qt::CheckState(settings.value("cmbNavic").toInt()));
547
548 connect(_cmbGpsCheckBox, SIGNAL(stateChanged(int)), this, SLOT(slotBncTextChanged()));
549 connect(_cmbGloCheckBox, SIGNAL(stateChanged(int)), this, SLOT(slotBncTextChanged()));
550 connect(_cmbGalCheckBox, SIGNAL(stateChanged(int)), this, SLOT(slotBncTextChanged()));
551 connect(_cmbBdsCheckBox, SIGNAL(stateChanged(int)), this, SLOT(slotBncTextChanged()));
552 connect(_cmbQzssCheckBox, SIGNAL(stateChanged(int)), this, SLOT(slotBncTextChanged()));
553 connect(_cmbSbasCheckBox, SIGNAL(stateChanged(int)), this, SLOT(slotBncTextChanged()));
554 connect(_cmbNavicCheckBox, SIGNAL(stateChanged(int)), this, SLOT(slotBncTextChanged()));
555
556 _cmbBsxFile = new qtFileChooser(0, qtFileChooser::File);
557 _cmbBsxFile->setFileName(settings.value("cmbBsxFile").toString());
558
559 // Upload Results
560 // -------------
561 _uploadTable = new QTableWidget(0, 16);
562 _uploadTable->setHorizontalHeaderLabels(QString("Host, Port, Mountpoint, Ntrip, User, Password, System, Format, CoM, SP3 File, RNX File, BSX File, PID, SID, IOD, Bytes").split(","));
563 _uploadTable->setSelectionMode(QAbstractItemView::ExtendedSelection);
564 _uploadTable->setSelectionBehavior(QAbstractItemView::SelectRows);
565 _uploadTable->horizontalHeader()->resizeSection(0, 13 * ww);
566 _uploadTable->horizontalHeader()->resizeSection(1, 5 * ww);
567 _uploadTable->horizontalHeader()->resizeSection(2, 10 * ww);
568 _uploadTable->horizontalHeader()->resizeSection(3, 6 * ww);
569 _uploadTable->horizontalHeader()->resizeSection(4, 8 * ww);
570 _uploadTable->horizontalHeader()->resizeSection(5, 8 * ww);
571 _uploadTable->horizontalHeader()->resizeSection(6, 11 * ww);
572 _uploadTable->horizontalHeader()->resizeSection(7, 11 * ww);
573 _uploadTable->horizontalHeader()->resizeSection(8, 4 * ww);
574 _uploadTable->horizontalHeader()->resizeSection(9, 15 * ww);
575 _uploadTable->horizontalHeader()->resizeSection(10, 15 * ww);
576 _uploadTable->horizontalHeader()->resizeSection(11, 15 * ww);
577 _uploadTable->horizontalHeader()->resizeSection(12, 4 * ww);
578 _uploadTable->horizontalHeader()->resizeSection(13, 4 * ww);
579 _uploadTable->horizontalHeader()->resizeSection(14, 4 * ww);
580 _uploadTable->horizontalHeader()->resizeSection(15, 12 * ww);
581#if QT_VERSION < 0x050000
582 _uploadTable->horizontalHeader()->setResizeMode(QHeaderView::Interactive);
583#else
584 _uploadTable->horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive);
585#endif
586 _uploadTable->horizontalHeader()->setStretchLastSection(true);
587 _uploadTable->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft);
588
589 connect(_uploadTable, SIGNAL(itemSelectionChanged()),
590 SLOT(slotBncTextChanged()));
591
592 QPushButton* addUploadRowButton = new QPushButton("Add Row");
593 QPushButton* delUploadRowButton = new QPushButton("Del Row");
594 QPushButton* setUploadTrafoButton = new QPushButton("Custom Trafo");
595 _uploadIntrComboBox = new QComboBox;
596 _uploadIntrComboBox->setEditable(false);
597 _uploadIntrComboBox->addItems(QString("1 day,1 hour, 30 min,15 min,10 min,5 min,2 min,1 min").split(","));
598 ii = _uploadIntrComboBox->findText(settings.value("uploadIntr").toString());
599 if (ii != -1) {
600 _uploadIntrComboBox->setCurrentIndex(ii);
601 }
602
603 _uploadAntexFile = new qtFileChooser(0, qtFileChooser::File);
604 _uploadAntexFile->setFileName(settings.value("uploadAntexFile").toString());
605
606 _uploadSamplRtcmEphCorrComboBox = new QComboBox();
607 _uploadSamplRtcmEphCorrComboBox->setEditable(false);
608 _uploadSamplRtcmEphCorrComboBox->addItems(QString("0 sec,1 sec,2 sec,5 sec,10 sec,15 sec,30 sec,60 sec").split(","));
609 int pp = _uploadSamplRtcmEphCorrComboBox->findText(settings.value("uploadSamplRtcmEphCorr").toString());
610 if (pp != -1) {
611 _uploadSamplRtcmEphCorrComboBox->setCurrentIndex(pp);
612 }
613
614 _uploadSamplSp3ComboBox = new QComboBox();
615 _uploadSamplSp3ComboBox->setEditable(false);
616 _uploadSamplSp3ComboBox->addItems(QString("0 sec,30 sec,60 sec,300 sec,900 sec").split(","));
617 int oo = _uploadSamplSp3ComboBox->findText(settings.value("uploadSamplSp3").toString());
618 if (oo != -1) {
619 _uploadSamplSp3ComboBox->setCurrentIndex(oo);
620 }
621
622 _uploadSamplClkRnxSpinBox = new QSpinBox;
623 _uploadSamplClkRnxSpinBox->setMinimum(0);
624 _uploadSamplClkRnxSpinBox->setMaximum(60);
625 _uploadSamplClkRnxSpinBox->setSingleStep(5);
626 _uploadSamplClkRnxSpinBox->setMaximumWidth(9 * ww);
627 _uploadSamplClkRnxSpinBox->setValue(settings.value("uploadSamplClkRnx").toInt());
628 _uploadSamplClkRnxSpinBox->setSuffix(" sec");
629
630 _uploadSamplBiaSnxSpinBox = new QSpinBox;
631 _uploadSamplBiaSnxSpinBox->setMinimum(0);
632 _uploadSamplBiaSnxSpinBox->setMaximum(60);
633 _uploadSamplBiaSnxSpinBox->setSingleStep(5);
634 _uploadSamplBiaSnxSpinBox->setMaximumWidth(9 * ww);
635 _uploadSamplBiaSnxSpinBox->setValue(settings.value("uploadSamplBiaSnx").toInt());
636 _uploadSamplBiaSnxSpinBox->setSuffix(" sec");
637
638 int iRowT = _uploadTable->rowCount();
639 if (iRowT > 0) {
640 enableWidget(true, _uploadIntrComboBox);
641 enableWidget(true, _uploadSamplRtcmEphCorrComboBox);
642 enableWidget(true, _uploadSamplSp3ComboBox);
643 enableWidget(true, _uploadSamplClkRnxSpinBox);
644 enableWidget(true, _uploadSamplBiaSnxSpinBox);
645 enableWidget(true, _uploadAntexFile);
646 }
647 else {
648 enableWidget(false, _uploadIntrComboBox);
649 enableWidget(false, _uploadSamplRtcmEphCorrComboBox);
650 enableWidget(false, _uploadSamplSp3ComboBox);
651 enableWidget(false, _uploadSamplClkRnxSpinBox);
652 enableWidget(true, _uploadSamplBiaSnxSpinBox);
653 enableWidget(false, _uploadAntexFile);
654 }
655
656 // Upload RTCM3 Ephemeris
657 // ----------------------
658 _uploadEphTable = new QTableWidget(0, 7);
659 _uploadEphTable->setColumnCount(8);
660 _uploadEphTable->setRowCount(0);
661 _uploadEphTable->setHorizontalHeaderLabels(QString("Host, Port, Mountpoint, Ntrip, User, Password, System, Bytes").split(","));
662 _uploadEphTable->setSelectionMode(QAbstractItemView::ExtendedSelection);
663 _uploadEphTable->setSelectionBehavior(QAbstractItemView::SelectRows);
664 _uploadEphTable->horizontalHeader()->resizeSection(0, 13 * ww);
665 _uploadEphTable->horizontalHeader()->resizeSection(1, 5 * ww);
666 _uploadEphTable->horizontalHeader()->resizeSection(2, 8 * ww);
667 _uploadEphTable->horizontalHeader()->resizeSection(3, 6 * ww);
668 _uploadEphTable->horizontalHeader()->resizeSection(4, 8 * ww);
669 _uploadEphTable->horizontalHeader()->resizeSection(5, 8 * ww);
670 _uploadEphTable->horizontalHeader()->resizeSection(6, 10 * ww);
671 _uploadEphTable->horizontalHeader()->resizeSection(7, 12 * ww);
672#if QT_VERSION < 0x050000
673 _uploadEphTable->horizontalHeader()->setResizeMode(QHeaderView::Interactive);
674#else
675 _uploadEphTable->horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive);
676#endif
677 _uploadEphTable->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft);
678
679 connect(_uploadEphTable, SIGNAL(itemSelectionChanged()),
680 SLOT(slotBncTextChanged()));
681
682 QPushButton* addUploadEphRowButton = new QPushButton("Add Row");
683 addUploadEphRowButton->setMaximumWidth(9 * ww);
684 QPushButton* delUploadEphRowButton = new QPushButton("Del Row");
685 delUploadEphRowButton->setMaximumWidth(9 * ww);
686
687 _uploadSamplRtcmEphSpinBox = new QSpinBox;
688 _uploadSamplRtcmEphSpinBox->setMinimum(0);
689 _uploadSamplRtcmEphSpinBox->setMaximum(60);
690 _uploadSamplRtcmEphSpinBox->setSingleStep(5);
691 _uploadSamplRtcmEphSpinBox->setMaximumWidth(9 * ww);
692 _uploadSamplRtcmEphSpinBox->setValue(settings.value("uploadSamplRtcmEph").toInt());
693 _uploadSamplRtcmEphSpinBox->setSuffix(" sec");
694
695 iRowT = _uploadEphTable->rowCount();
696 if (iRowT > 0) {
697 enableWidget(true, _uploadSamplRtcmEphSpinBox);
698 }
699 else {
700 enableWidget(false, _uploadSamplRtcmEphSpinBox);
701 }
702
703 // Upload Raw data
704 // ----------------------
705 _uploadRawTable = new QTableWidget(0, 7);
706 _uploadRawTable->setColumnCount(8);
707 _uploadRawTable->setRowCount(0);
708 _uploadRawTable->setHorizontalHeaderLabels(QString("Source Mountpoint, Host, Port, Upload Mountpoint, Ntrip, User, Password, Bytes").split(","));
709 _uploadRawTable->setSelectionMode(QAbstractItemView::ExtendedSelection);
710 _uploadRawTable->setSelectionBehavior(QAbstractItemView::SelectRows);
711 _uploadRawTable->horizontalHeader()->resizeSection(0, 13 * ww);
712 _uploadRawTable->horizontalHeader()->resizeSection(1, 13 * ww);
713 _uploadRawTable->horizontalHeader()->resizeSection(2, 5 * ww);
714 _uploadRawTable->horizontalHeader()->resizeSection(3, 13 * ww);
715 _uploadRawTable->horizontalHeader()->resizeSection(4, 6 * ww);
716 _uploadRawTable->horizontalHeader()->resizeSection(5, 8 * ww);
717 _uploadRawTable->horizontalHeader()->resizeSection(6, 8 * ww);
718 _uploadRawTable->horizontalHeader()->resizeSection(7, 10 * ww);
719 _uploadRawTable->horizontalHeader()->resizeSection(8, 12 * ww);
720#if QT_VERSION < 0x050000
721 _uploadRawTable->horizontalHeader()->setResizeMode(QHeaderView::Interactive);
722#else
723 _uploadRawTable->horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive);
724#endif
725 _uploadRawTable->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft);
726
727 connect(_uploadRawTable, SIGNAL(itemSelectionChanged()), SLOT(slotBncTextChanged()));
728
729 QPushButton* addUploadRawRowButton = new QPushButton("Add Row");
730 addUploadRawRowButton->setMaximumWidth(9 * ww);
731 QPushButton* delUploadRawRowButton = new QPushButton("Del Row");
732 delUploadRawRowButton->setMaximumWidth(9 * ww);
733
734 // Canvas with Editable Fields
735 // ---------------------------
736 _canvas = new QWidget;
737 setCentralWidget(_canvas);
738
739 _aogroup = new QTabWidget();
740 _aogroup->setElideMode(Qt::ElideNone);
741 _aogroup->setUsesScrollButtons(true);
742 QWidget* pgroup = new QWidget();
743 QWidget* ggroup = new QWidget();
744 QWidget* sgroup = new QWidget();
745 QWidget* egroup = new QWidget();
746 QWidget* agroup = new QWidget();
747 QWidget* cgroup = new QWidget();
748 QWidget* ogroup = new QWidget();
749 QWidget* rgroup = new QWidget();
750 QWidget* sergroup = new QWidget();
751 QWidget* pppGroup1 = new QWidget();
752 QWidget* pppGroup2 = new QWidget();
753 QWidget* pppGroup3 = new QWidget();
754 QWidget* pppGroup4 = new QWidget();
755 QWidget* reqcgroup = new QWidget();
756 QWidget* sp3CompGroup = new QWidget();
757 QWidget* cmbgroup = new QWidget();
758 QWidget* uploadgroup = new QWidget();
759 QWidget* uploadEphgroup = new QWidget();
760 QWidget* uploadRawgroup = new QWidget();
761 _aogroup->addTab(pgroup, tr("Network"));
762 _aogroup->addTab(ggroup, tr("General"));
763 _aogroup->addTab(ogroup, tr("RINEX Observations"));
764 _aogroup->addTab(egroup, tr("RINEX Ephemeris"));
765 _aogroup->addTab(reqcgroup, tr("RINEX Editing && QC"));
766 _aogroup->addTab(sp3CompGroup, tr("SP3 Comparison"));
767 _aogroup->addTab(cgroup, tr("Broadcast Corrections"));
768 _aogroup->addTab(sgroup, tr("Feed Engine"));
769 _aogroup->addTab(sergroup, tr("Serial Output"));
770 _aogroup->addTab(agroup, tr("Outages"));
771 _aogroup->addTab(rgroup, tr("Miscellaneous"));
772 _aogroup->addTab(pppGroup1, tr("PPP (1)"));
773 _aogroup->addTab(pppGroup2, tr("PPP (2)"));
774 _aogroup->addTab(pppGroup3, tr("PPP (3)"));
775 _aogroup->addTab(pppGroup4, tr("PPP (4)"));
776 _aogroup->addTab(cmbgroup, tr("Combine Corrections"));
777 _aogroup->addTab(uploadgroup, tr("Upload Corrections"));
778 _aogroup->addTab(uploadEphgroup, tr("Upload Ephemeris"));
779 _aogroup->addTab(uploadRawgroup, tr("Upload Raw Data"));
780
781 // Log Tab
782 // -------
783 _loggroup = new QTabWidget();
784 _loggroup->addTab(_log, tr("Log"));
785 _loggroup->addTab(_bncFigure, tr("Throughput"));
786 _loggroup->addTab(_bncFigureLate, tr("Latency"));
787 _loggroup->addTab(_bncFigurePPP, tr("PPP Plot"));
788
789 // Netowork (Proxy and SSL) Tab
790 // ----------------------------
791 QGridLayout* pLayout = new QGridLayout;
792 pLayout->setColumnMinimumWidth(0, 13 * ww);
793 _proxyPortLineEdit->setMaximumWidth(9 * ww);
794
795 pLayout->addWidget(new QLabel("Settings for proxy in protected networks and for SSL authorization, leave boxes blank if none.<br>"), 0, 0, 1, 50);
796 pLayout->addWidget(new QLabel("Proxy host"), 1, 0);
797 pLayout->addWidget(_proxyHostLineEdit, 1, 1, 1, 10);
798 pLayout->addWidget(new QLabel("Proxy port"), 2, 0);
799 pLayout->addWidget(_proxyPortLineEdit, 2, 1);
800 pLayout->addWidget(new QLabel("Path to SSL certificates"), 3, 0);
801 pLayout->addWidget(_sslCaCertPathLineEdit, 3, 1, 1, 10);
802 pLayout->addWidget(new QLabel("Default: " + bncSslConfig::defaultPath()), 3, 11, 1, 20);
803 pLayout->addWidget(new QLabel("Path to SSL client certificates"), 4, 0);
804 pLayout->addWidget(_sslClientCertPathLineEdit, 4, 1, 1, 10);
805 pLayout->addWidget(new QLabel("Ignore SSL authorization errors"), 5, 0);
806 pLayout->addWidget(_sslIgnoreErrorsCheckBox, 5, 1, 1, 10);
807 pLayout->addWidget(new QLabel(""), 6, 1);
808 pLayout->setRowStretch(6, 999);
809
810 pgroup->setLayout(pLayout);
811
812 // General Tab
813 // -----------
814 QGridLayout* gLayout = new QGridLayout;
815 gLayout->setColumnMinimumWidth(0, 14 * ww);
816 _onTheFlyComboBox->setMaximumWidth(9 * ww);
817
818 gLayout->addWidget(new QLabel("General settings for logfile, file handling, configuration on-the-fly, auto-start, and raw file output.<br>"), 0, 0, 1, 50);
819 gLayout->addWidget(new QLabel("Logfile (full path)"), 1, 0);
820 gLayout->addWidget(_logFileLineEdit, 1, 1, 1, 20);
821 gLayout->addWidget(new QLabel("Append files"), 2, 0);
822 gLayout->addWidget(_rnxAppendCheckBox, 2, 1);
823 gLayout->addWidget(new QLabel("Reread configuration"), 3, 0);
824 gLayout->addWidget(_onTheFlyComboBox, 3, 1);
825 gLayout->addWidget(new QLabel("Auto start"), 4, 0);
826 gLayout->addWidget(_autoStartCheckBox, 4, 1);
827 gLayout->addWidget(new QLabel("Raw output file (full path)"), 5, 0);
828 gLayout->addWidget(_rawOutFileLineEdit, 5, 1, 1, 20);
829 gLayout->addWidget(new QLabel(""), 6, 1);
830 gLayout->setRowStretch(7, 999);
831
832 ggroup->setLayout(gLayout);
833
834 // RINEX Observations
835 // ------------------
836 QGridLayout* oLayout = new QGridLayout;
837 oLayout->setColumnMinimumWidth(0, 14 * ww);
838 _rnxIntrComboBox->setMaximumWidth(9 * ww);
839 _rnxSamplComboBox->setMaximumWidth(9 * ww);
840 _rnxSkelExtComboBox->setMaximumWidth(9 * ww);
841
842 oLayout->addWidget(new QLabel("Saving RINEX observation files.<br>"), 0, 0, 1, 50);
843 oLayout->addWidget(new QLabel("Directory"), 1, 0);
844 oLayout->addWidget(_rnxPathLineEdit, 1, 1, 1, 15);
845 oLayout->addWidget(new QLabel("Interval"), 2, 0);
846 oLayout->addWidget(_rnxIntrComboBox, 2, 1);
847 oLayout->addWidget(new QLabel(" Sampling"), 2, 2, Qt::AlignRight);
848 oLayout->addWidget(_rnxSamplComboBox, 2, 3, Qt::AlignRight);
849 oLayout->addWidget(new QLabel("Skeleton extension"), 3, 0);
850 oLayout->addWidget(_rnxSkelExtComboBox, 3, 1, Qt::AlignLeft);
851 oLayout->addWidget(new QLabel("Skeleton mandatory"), 3, 2, Qt::AlignRight);
852 oLayout->addWidget(_rnxFileCheckBox, 3, 3);
853 oLayout->addWidget(new QLabel("Skeleton Directory"), 4, 0);
854 oLayout->addWidget(_rnxSkelPathLineEdit, 4, 1, 1, 15);
855 oLayout->addWidget(new QLabel("Script (full path)"), 5, 0);
856 oLayout->addWidget(_rnxScrpLineEdit, 5, 1, 1, 15);
857 oLayout->addWidget(new QLabel("Version"), 6, 0);
858 oLayout->addWidget(_rnxVersComboBox, 6, 1);
859 oLayout->addWidget(new QLabel("Signal priority"), 6, 2, Qt::AlignRight);
860 oLayout->addWidget(_rnxV2Priority, 6, 3, 1, 13);
861 oLayout->addWidget(new QLabel(""), 7, 1);
862 oLayout->setRowStretch(8, 999);
863
864 ogroup->setLayout(oLayout);
865
866 // RINEX Ephemeris
867 // ---------------
868 QGridLayout* eLayout = new QGridLayout;
869 eLayout->setColumnMinimumWidth(0, 14 * ww);
870 _ephIntrComboBox->setMaximumWidth(9 * ww);
871 _ephOutPortLineEdit->setMaximumWidth(9 * ww);
872
873 eLayout->addWidget(new QLabel("Saving RINEX navigation files and ephemeris output through IP port.<br>"), 0, 0, 1, 70);
874 eLayout->addWidget(new QLabel("Directory"), 1, 0);
875 eLayout->addWidget(_ephPathLineEdit, 1, 1, 1, 30);
876 eLayout->addWidget(new QLabel("Interval"), 2, 0);
877 eLayout->addWidget(_ephIntrComboBox, 2, 1);
878 eLayout->addWidget(new QLabel("Port"), 3, 0);
879 eLayout->addWidget(_ephOutPortLineEdit, 3, 1);
880 eLayout->addWidget(new QLabel("Version"), 4, 0);
881 eLayout->addWidget(_ephVersComboBox, 4, 1);
882 eLayout->setRowStretch(5, 999);
883 //eLayout->addWidget(new QLabel("File per Station"), 5, 0);
884 //eLayout->addWidget(_ephFilePerStation, 5, 1);
885 //eLayout->setRowStretch(6, 999);
886
887 egroup->setLayout(eLayout);
888
889
890 // Broadcast Corrections
891 // ---------------------
892 QGridLayout* cLayout = new QGridLayout;
893 cLayout->setColumnMinimumWidth(0, 14 * ww);
894 _corrIntrComboBox->setMaximumWidth(9 * ww);
895 _corrPortLineEdit->setMaximumWidth(9 * ww);
896
897 cLayout->addWidget(new QLabel("Saving Broadcast Ephemeris correction files and correction output through IP port.<br>"), 0, 0, 1, 70);
898 cLayout->addWidget(new QLabel("Directory, ASCII"), 1, 0);
899 cLayout->addWidget(_corrPathLineEdit, 1, 1, 1, 30);
900 cLayout->addWidget(new QLabel("Interval"), 2, 0);
901 cLayout->addWidget(_corrIntrComboBox, 2, 1);
902 cLayout->addWidget(new QLabel("Port"), 3, 0);
903 cLayout->addWidget(_corrPortLineEdit, 3, 1);
904 cLayout->addWidget(new QLabel(""), 4, 1);
905 cLayout->setRowStretch(7, 999);
906 cgroup->setLayout(cLayout);
907
908 // Feed Engine
909 // -----------
910 QGridLayout* sLayout = new QGridLayout;
911 sLayout->setColumnMinimumWidth(0, 14 * ww);
912 _outPortLineEdit->setMaximumWidth(9 * ww);
913 _outWaitSpinBox->setMaximumWidth(9 * ww);
914 _outSamplComboBox->setMaximumWidth(9 * ww);
915 _outUPortLineEdit->setMaximumWidth(9 * ww);
916
917 sLayout->addWidget(new QLabel("Output decoded observations in ASCII format to feed a real-time GNSS network engine.<br>"), 0, 0, 1, 50);
918 sLayout->addWidget(new QLabel("Port"), 1, 0);
919 sLayout->addWidget(_outPortLineEdit, 1, 1);
920 sLayout->addWidget(new QLabel(" Wait for full obs epoch"), 1, 2, Qt::AlignRight);
921 sLayout->addWidget(_outWaitSpinBox, 1, 3, Qt::AlignLeft);
922 sLayout->addWidget(new QLabel("Sampling"), 2, 0);
923 sLayout->addWidget(_outSamplComboBox, 2, 1, Qt::AlignLeft);
924 sLayout->addWidget(new QLabel("File (full path)"), 3, 0);
925 sLayout->addWidget(_outFileLineEdit, 3, 1, 1, 10);
926 sLayout->addWidget(new QLabel("Port (unsynchronized)"), 4, 0);
927 sLayout->addWidget(_outUPortLineEdit, 4, 1);
928 sLayout->addWidget(new QLabel("Print lock time"), 5, 0);
929 sLayout->addWidget(_outLockTimeCheckBox, 5, 1);
930 sLayout->addWidget(new QLabel(""), 6, 1);
931 sLayout->setRowStretch(7, 999);
932
933 sgroup->setLayout(sLayout);
934
935 // Serial Output
936 // -------------
937 QGridLayout* serLayout = new QGridLayout;
938 serLayout->setColumnMinimumWidth(0, 12 * ww);
939 _serialBaudRateComboBox->setMaximumWidth(9 * ww);
940 _serialFlowControlComboBox->setMaximumWidth(11 * ww);
941 _serialDataBitsComboBox->setMaximumWidth(5 * ww);
942 _serialParityComboBox->setMaximumWidth(9 * ww);
943 _serialStopBitsComboBox->setMaximumWidth(5 * ww);
944 _serialAutoNMEAComboBox->setMaximumWidth(14 * ww);
945 _serialHeightNMEALineEdit->setMaximumWidth(8 * ww);
946 _serialNMEASamplingSpinBox->setMaximumWidth(8 * ww);
947
948 serLayout->addWidget(new QLabel("Port settings to feed a serial connected receiver.<br>"), 0, 0, 1, 30);
949 serLayout->addWidget(new QLabel("Mountpoint"), 1, 0, Qt::AlignLeft);
950 serLayout->addWidget(_serialMountPointLineEdit, 1, 1, 1, 2);
951 serLayout->addWidget(new QLabel("Port name"), 2, 0, Qt::AlignLeft);
952 serLayout->addWidget(_serialPortNameLineEdit, 2, 1, 1, 2);
953 serLayout->addWidget(new QLabel("Baud rate"), 3, 0, Qt::AlignLeft);
954 serLayout->addWidget(_serialBaudRateComboBox, 3, 1);
955 serLayout->addWidget(new QLabel("Flow control"), 3, 2, Qt::AlignRight);
956 serLayout->addWidget(_serialFlowControlComboBox, 3, 3);
957 serLayout->addWidget(new QLabel("Data bits"), 4, 0, Qt::AlignLeft);
958 serLayout->addWidget(_serialDataBitsComboBox, 4, 1);
959 serLayout->addWidget(new QLabel("Parity"), 4, 2, Qt::AlignRight);
960 serLayout->addWidget(_serialParityComboBox, 4, 3);
961 serLayout->addWidget(new QLabel(" Stop bits"), 4, 4, Qt::AlignRight);
962 serLayout->addWidget(_serialStopBitsComboBox, 4, 5);
963 serLayout->addWidget(new QLabel("NMEA"), 5, 0);
964 serLayout->addWidget(_serialAutoNMEAComboBox, 5, 1);
965 serLayout->addWidget(new QLabel(" File (full path)"), 5, 2, Qt::AlignRight);
966 serLayout->addWidget(_serialFileNMEALineEdit, 5, 3, 1, 10);
967 serLayout->addWidget(new QLabel("Height"), 5, 14, Qt::AlignRight);
968 serLayout->addWidget(_serialHeightNMEALineEdit, 5, 15, 1, 11);
969 serLayout->addWidget(new QLabel("Sampling"), 5, 25, Qt::AlignRight);
970 serLayout->addWidget(_serialNMEASamplingSpinBox, 5, 26, 1, 12);
971 serLayout->addWidget(new QLabel(""), 6, 1);
972 serLayout->setRowStretch(7, 999);
973
974 sergroup->setLayout(serLayout);
975
976 // Outages
977 // -------
978 QGridLayout* aLayout = new QGridLayout;
979 aLayout->setColumnMinimumWidth(0, 14 * ww);
980 _adviseObsRateComboBox->setMaximumWidth(9 * ww);
981 _adviseFailSpinBox->setMaximumWidth(9 * ww);
982 _adviseRecoSpinBox->setMaximumWidth(9 * ww);
983
984 aLayout->addWidget(new QLabel("Failure and recovery reports, advisory notes.<br>"), 0, 0, 1, 50, Qt::AlignLeft);
985 aLayout->addWidget(new QLabel("Observation rate"), 1, 0);
986 aLayout->addWidget(_adviseObsRateComboBox, 1, 1);
987 aLayout->addWidget(new QLabel("Failure threshold"), 2, 0);
988 aLayout->addWidget(_adviseFailSpinBox, 2, 1);
989 aLayout->addWidget(new QLabel("Recovery threshold"), 3, 0);
990 aLayout->addWidget(_adviseRecoSpinBox, 3, 1);
991 aLayout->addWidget(new QLabel("Script (full path)"), 4, 0);
992 aLayout->addWidget(_adviseScriptLineEdit, 4, 1, 1, 20);
993 aLayout->addWidget(new QLabel(""), 5, 1);
994 aLayout->setRowStretch(6, 999);
995
996 agroup->setLayout(aLayout);
997
998 // Miscellaneous
999 // -------------
1000 QGridLayout* rLayout = new QGridLayout;
1001 rLayout->setColumnMinimumWidth(0, 14 * ww);
1002 _miscIntrComboBox->setMaximumWidth(9 * ww);
1003 _miscPortLineEdit->setMaximumWidth(9 * ww);
1004
1005 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);
1006 rLayout->addWidget(new QLabel("Mountpoint"), 1, 0);
1007 rLayout->addWidget(_miscMountLineEdit, 1, 1, 1, 7);
1008 rLayout->addWidget(new QLabel("Log latency"), 2, 0);
1009 rLayout->addWidget(_miscIntrComboBox, 2, 1);
1010 rLayout->addWidget(new QLabel("Scan RTCM"), 3, 0);
1011 rLayout->addWidget(_miscScanRTCMCheckBox, 3, 1);
1012 rLayout->addWidget(new QLabel("Port"), 4, 0);
1013 rLayout->addWidget(_miscPortLineEdit, 4, 1);
1014 rLayout->addWidget(new QLabel(""), 5, 1);
1015 rLayout->setRowStretch(6, 999);
1016
1017 rgroup->setLayout(rLayout);
1018
1019 // PPP
1020 // ---
1021 _pppWidgets._dataSource->setMaximumWidth(15 * ww);
1022 _pppWidgets._corrMount->setMaximumWidth(15 * ww);
1023 _pppWidgets._biasMount->setMaximumWidth(15 * ww);
1024 _pppWidgets._nmeaPath->setMaximumWidth(35 * ww);
1025 _pppWidgets._logPath->setMaximumWidth(15 * ww);
1026 _pppWidgets._snxtroPath->setMaximumWidth(35 * ww);
1027 _pppWidgets._snxtroIntr->setMaximumWidth(7 * ww);
1028 _pppWidgets._snxtroAc->setMaximumWidth(7 * ww);
1029 _pppWidgets._snxtroSolId->setMaximumWidth(7 * ww);
1030 _pppWidgets._snxtroSolType->setMaximumWidth(7 * ww);
1031 _pppWidgets._snxtroCampId->setMaximumWidth(7 * ww);
1032 _pppWidgets._ionoMount->setMaximumWidth(15 * ww);
1033
1034
1035 QGridLayout* pppLayout1 = new QGridLayout();
1036 int ir = 0;
1037 pppLayout1->addWidget(new QLabel("Precise Point Positioning - Input and Output.<br>"), ir, 0, 1, 7, Qt::AlignLeft);
1038 ++ir;
1039 pppLayout1->addWidget(new QLabel("Data source"), ir, 0);
1040 pppLayout1->addWidget(_pppWidgets._dataSource, ir, 1);
1041 pppLayout1->addWidget(new QLabel(" Logfile directory"), ir, 4);
1042 pppLayout1->addWidget(_pppWidgets._logPath, ir, 5, 1, 2);
1043 pppLayout1->addWidget(_pppWidgets._logMode, ir, 7);
1044 ++ir;
1045 pppLayout1->addWidget(new QLabel("Corrections stream"), ir, 0);
1046 pppLayout1->addWidget(_pppWidgets._corrMount, ir, 1);
1047 pppLayout1->addWidget(new QLabel("Corrections file"), ir, 2);
1048 pppLayout1->addWidget(_pppWidgets._corrFile, ir, 3);
1049 pppLayout1->addWidget(new QLabel(" NMEA directory"), ir, 4);
1050 pppLayout1->addWidget(_pppWidgets._nmeaPath, ir, 5, 1, 3);
1051 ++ir;
1052 pppLayout1->addWidget(new QLabel("Biases stream"), ir, 0);
1053 pppLayout1->addWidget(_pppWidgets._biasMount, ir, 1);
1054 pppLayout1->addWidget(new QLabel("Biases file"), ir, 2);
1055 pppLayout1->addWidget(_pppWidgets._biasFile, ir, 3);
1056 pppLayout1->addWidget(new QLabel(" SNX TRO directory"), ir, 4);
1057 pppLayout1->addWidget(_pppWidgets._snxtroPath, ir, 5, 1, 3);
1058 ++ir;
1059 pppLayout1->addWidget(new QLabel("Ionosphere stream"), ir, 0);
1060 pppLayout1->addWidget(_pppWidgets._ionoMount, ir, 1);
1061 pppLayout1->addWidget(new QLabel("Ionosphere file"), ir, 2);
1062 pppLayout1->addWidget(_pppWidgets._ionoFile, ir, 3);
1063 pppLayout1->addWidget(new QLabel(" SNX TRO interval"), ir, 4);
1064 pppLayout1->addWidget(_pppWidgets._snxtroIntr, ir, 5);
1065 pppLayout1->addWidget(new QLabel(" SNX TRO sampling"), ir, 6);
1066 pppLayout1->addWidget(_pppWidgets._snxtroSampl, ir, 7, Qt::AlignRight);
1067 ++ir;
1068 pppLayout1->addWidget(new QLabel("RINEX Obs file"), ir, 0);
1069 pppLayout1->addWidget(_pppWidgets._rinexObs, ir, 1);
1070 pppLayout1->addWidget(new QLabel("RINEX Nav file"), ir, 2);
1071 pppLayout1->addWidget(_pppWidgets._rinexNav, ir, 3);
1072 pppLayout1->addWidget(new QLabel(" SNX TRO AC"), ir, 4);
1073 pppLayout1->addWidget(_pppWidgets._snxtroAc, ir, 5);
1074 pppLayout1->addWidget(new QLabel(" SNX TRO solution ID"), ir, 6);
1075 pppLayout1->addWidget(_pppWidgets._snxtroSolId, ir, 7, Qt::AlignRight);
1076 ++ir;
1077 pppLayout1->addWidget(new QLabel("ANTEX file"), ir, 0);
1078 pppLayout1->addWidget(_pppWidgets._antexFile, ir, 1);
1079 pppLayout1->addWidget(new QLabel("Coordinates file"), ir, 2);
1080 pppLayout1->addWidget(_pppWidgets._crdFile, ir, 3);
1081 pppLayout1->addWidget(new QLabel(" SNX TRO campaign ID"), ir, 4);
1082 pppLayout1->addWidget(_pppWidgets._snxtroCampId, ir, 5);
1083 pppLayout1->addWidget(new QLabel(" SNX TRO solution type"), ir, 6);
1084 pppLayout1->addWidget(_pppWidgets._snxtroSolType, ir, 7, Qt::AlignRight);
1085 ++ir;
1086 pppLayout1->addWidget(new QLabel("BLQ file"), ir, 0);
1087 pppLayout1->addWidget(_pppWidgets._blqFile, ir, 1);
1088
1089 pppLayout1->setRowStretch(ir + 1, 999);
1090 pppGroup1->setLayout(pppLayout1);
1091
1092 QGridLayout* pppLayout2 = new QGridLayout();
1093 ir = 0;
1094 pppLayout2->addWidget(new QLabel("Precise Point Positioning - Options.<br>"), ir, 0, 1, 2, Qt::AlignLeft);
1095 ++ir;
1096 pppLayout2->addWidget(new QLabel("GPS LCs"), ir, 0, Qt::AlignLeft);
1097 pppLayout2->addWidget(_pppWidgets._lcGPS, ir, 1);
1098 pppLayout2->addItem(new QSpacerItem(8 * ww, 0), ir, 2);
1099 pppLayout2->addWidget(new QLabel("Sigma C1"), ir, 3, Qt::AlignLeft);
1100 pppLayout2->addWidget(_pppWidgets._sigmaC1, ir, 4); _pppWidgets._sigmaC1->setMaximumWidth(8 * ww);
1101 pppLayout2->addItem(new QSpacerItem(8 * ww, 0), ir, 5);
1102 pppLayout2->addWidget(new QLabel("Sigma L1"), ir, 6, Qt::AlignLeft);
1103 pppLayout2->addWidget(_pppWidgets._sigmaL1, ir, 7); _pppWidgets._sigmaL1->setMaximumWidth(8 * ww);
1104 ++ir;
1105 pppLayout2->addWidget(new QLabel("GLONASS LCs"), ir, 0, Qt::AlignLeft);
1106 pppLayout2->addWidget(_pppWidgets._lcGLONASS, ir, 1);
1107 pppLayout2->addWidget(new QLabel("Max Res C1"), ir, 3, Qt::AlignLeft);
1108 pppLayout2->addWidget(_pppWidgets._maxResC1, ir, 4); _pppWidgets._maxResC1->setMaximumWidth(8 * ww);
1109 pppLayout2->addWidget(new QLabel("Max Res L1"), ir, 6, Qt::AlignLeft);
1110 pppLayout2->addWidget(_pppWidgets._maxResL1, ir, 7); _pppWidgets._maxResL1->setMaximumWidth(8 * ww);
1111 ++ir;
1112 pppLayout2->addWidget(new QLabel("Galileo LCs"), ir, 0, Qt::AlignLeft);
1113 pppLayout2->addWidget(_pppWidgets._lcGalileo, ir, 1);
1114 pppLayout2->addWidget(new QLabel("Ele Wgt Code"), ir, 3, Qt::AlignLeft);
1115 pppLayout2->addWidget(_pppWidgets._eleWgtCode, ir, 4);
1116 pppLayout2->addWidget(new QLabel("Ele Wgt Phase"), ir, 6, Qt::AlignLeft);
1117 pppLayout2->addWidget(_pppWidgets._eleWgtPhase, ir, 7);
1118 ++ir;
1119 pppLayout2->addWidget(new QLabel("BDS LCs"), ir, 0, Qt::AlignLeft);
1120 pppLayout2->addWidget(_pppWidgets._lcBDS, ir, 1);
1121 pppLayout2->addWidget(new QLabel("Min # of Obs"), ir, 3, Qt::AlignLeft);
1122 pppLayout2->addWidget(_pppWidgets._minObs, ir, 4);
1123 pppLayout2->addWidget(new QLabel("Min Elevation"), ir, 6, Qt::AlignLeft);
1124 pppLayout2->addWidget(_pppWidgets._minEle, ir, 7); _pppWidgets._minEle->setMaximumWidth(8 * ww);
1125 ++ir;
1126 pppLayout2->addWidget(new QLabel("Constraints"), ir, 0, Qt::AlignLeft);
1127 pppLayout2->addWidget(_pppWidgets._constraints, ir, 1);
1128 pppLayout2->addWidget(new QLabel("Sigma GIM"), ir, 3, Qt::AlignLeft);
1129 pppLayout2->addWidget(_pppWidgets._sigmaGIM, ir, 4); _pppWidgets._sigmaGIM->setMaximumWidth(8 * ww);
1130 pppLayout2->addItem(new QSpacerItem(8 * ww, 0), ir, 5);
1131 pppLayout2->addWidget(new QLabel("Wait for clock corr."), ir, 6, Qt::AlignLeft);
1132 pppLayout2->addWidget(_pppWidgets._corrWaitTime, ir, 7);
1133 ++ir;
1134 pppLayout2->addItem(new QSpacerItem(8 * ww, 0), ir, 2);
1135 pppLayout2->addWidget(new QLabel("Seeding (sec)"), ir, 6, Qt::AlignLeft);
1136 pppLayout2->addWidget(_pppWidgets._seedingTime, ir, 7); _pppWidgets._seedingTime->setMaximumWidth(8 * ww);
1137 ++ir;
1138 QFrame* hLine = new QFrame();
1139 hLine->setFrameShape(QFrame::HLine);
1140 hLine->setFrameShadow(QFrame::Sunken);
1141 pppLayout2->addWidget(hLine, ir, 0, 2, 8);
1142 ++ir;
1143 ++ir;
1144 pppLayout2->addWidget(new QLabel("Amb. Res."), ir, 0);
1145 QHBoxLayout* pL1 = new QHBoxLayout();
1146 pL1->setSpacing(0);
1147 pL1->setContentsMargins(0,0,0,0);
1148 pL1->addWidget(new QLabel("GPS"));
1149 pL1->addWidget(_pppWidgets._arGPS);
1150 QHBoxLayout* pL2 = new QHBoxLayout();
1151 pL2->setSpacing(0);
1152 pL2->setContentsMargins(0,0,0,0);
1153 pL2->addWidget(new QLabel("Gal"));
1154 pL2->addWidget(_pppWidgets._arGalileo);
1155 QHBoxLayout* pL3 = new QHBoxLayout();
1156 pL3->setSpacing(0);
1157 pL3->setContentsMargins(0,0,0,0);
1158 pL3->addWidget(new QLabel("BDS"));
1159 pL3->addWidget(_pppWidgets._arBDS);
1160 QHBoxLayout* arLayout = new QHBoxLayout();
1161 arLayout->addLayout(pL1);
1162 arLayout->addLayout(pL2);
1163 arLayout->addLayout(pL3);
1164 pppLayout2->addLayout(arLayout, ir, 1);
1165 ++ir;
1166 _pppWidgets._arMinNumEpo->setMaximumWidth(8 * ww);
1167 _pppWidgets._arMinNumSat->setMaximumWidth(8 * ww);
1168 _pppWidgets._arMaxFrac->setMaximumWidth(8 * ww);
1169 _pppWidgets._arMaxSig->setMaximumWidth(8 * ww);
1170 QHBoxLayout* pAR = new QHBoxLayout();
1171 pAR->addWidget(new QLabel("Min # Epo"));
1172 pAR->addWidget(_pppWidgets._arMinNumEpo);
1173 pAR->addStretch();
1174 pAR->addWidget(new QLabel("Min # Sat"));
1175 pAR->addWidget(_pppWidgets._arMinNumSat);
1176 pAR->addStretch();
1177 pAR->addWidget(new QLabel("Max Frac"));
1178 pAR->addWidget(_pppWidgets._arMaxFrac);
1179 pAR->addStretch();
1180 pAR->addWidget(new QLabel("Max Sig"));
1181 pAR->addWidget(_pppWidgets._arMaxSig);
1182 pAR->addStretch();
1183 pAR->addWidget(new QLabel("Use Yaw"));
1184 pAR->addWidget(_pppWidgets._arUseYaw);
1185 pppLayout2->addLayout(pAR, ir, 0, 1, 8);
1186 ++ir;
1187 pppLayout2->addWidget(new QLabel(""), ir, 8);
1188 pppLayout2->setColumnStretch(8, 999);
1189
1190 pppGroup2->setLayout(pppLayout2);
1191
1192 QVBoxLayout* pppLayout3 = new QVBoxLayout();
1193 pppLayout3->addWidget(new QLabel("Precise Point Positioning - Processed Stations.<br>"));
1194 pppLayout3->addWidget(_pppWidgets._staTable, 99);
1195 QHBoxLayout* pppLayout3sub = new QHBoxLayout();
1196 pppLayout3sub->addWidget(_pppWidgets._addStaButton);
1197 pppLayout3sub->addWidget(_pppWidgets._delStaButton);
1198 pppLayout3sub->addStretch(99);
1199
1200 pppLayout3->addLayout(pppLayout3sub);
1201
1202 pppGroup3->setLayout(pppLayout3);
1203
1204 // ------------------------
1205 connect(_pppWidgets._mapWinButton, SIGNAL(clicked()), SLOT(slotMapPPP()));
1206 _pppWidgets._mapSpeedSlider->setMinimumWidth(33 * ww);
1207 _pppWidgets._audioResponse->setMaximumWidth(8 * ww);
1208
1209 QGridLayout* pppLayout4 = new QGridLayout();
1210 ir = 0;
1211 pppLayout4->addWidget(new QLabel("Precise Point Positioning - Plots.<br>"), ir, 0, 1, 50, Qt::AlignLeft);
1212 ++ir;
1213 pppLayout4->addWidget(new QLabel("PPP Plot"), ir, 0, Qt::AlignLeft);
1214 pppLayout4->addWidget(_pppWidgets._plotCoordinates, ir, 1, Qt::AlignLeft);
1215 pppLayout4->addWidget(new QLabel("Mountpoint"), ir, 2, 1, 10, Qt::AlignLeft);
1216 pppLayout4->addWidget(_pppWidgets._audioResponse, ir, 4, Qt::AlignLeft);
1217 pppLayout4->addWidget(new QLabel("Audio response"), ir, 5, Qt::AlignRight);
1218 ++ir;
1219 pppLayout4->addWidget(new QLabel("Track map"), ir, 0, Qt::AlignLeft);
1220 pppLayout4->addWidget(_pppWidgets._mapWinButton, ir, 1, Qt::AlignLeft);
1221 ++ir;
1222 pppLayout4->addWidget(new QLabel("Dot-properties"), ir, 0, Qt::AlignLeft);
1223 pppLayout4->addWidget(_pppWidgets._mapWinDotSize, ir, 1, Qt::AlignLeft);
1224 pppLayout4->addWidget(new QLabel("Size "), ir, 2, Qt::AlignLeft);
1225 pppLayout4->addWidget(_pppWidgets._mapWinDotColor, ir, 3, Qt::AlignLeft);
1226 pppLayout4->addWidget(new QLabel("Color"), ir, 4, Qt::AlignLeft);
1227 ++ir;
1228 pppLayout4->addWidget(new QLabel("Post-processing speed"), ir, 0, Qt::AlignLeft);
1229 pppLayout4->addWidget(_pppWidgets._mapSpeedSlider, ir, 1, 1, 20, Qt::AlignLeft);
1230 ++ir;
1231 pppLayout4->addWidget(new QLabel(""), ir, 1);
1232 pppLayout4->setRowStretch(ir, 999);
1233
1234 pppGroup4->setLayout(pppLayout4);
1235
1236 // Reqc Processing
1237 // ---------------
1238 _reqcActionComboBox = new QComboBox();
1239 _reqcActionComboBox->setEditable(false);
1240 _reqcActionComboBox->addItems(QString(",Edit/Concatenate,Analyze").split(","));
1241 int ip = _reqcActionComboBox->findText(settings.value("reqcAction").toString());
1242 if (ip != -1) {
1243 _reqcActionComboBox->setCurrentIndex(ip);
1244 }
1245 connect(_reqcActionComboBox, SIGNAL(currentIndexChanged(const QString&)),
1246 this, SLOT(slotBncTextChanged()));
1247
1248 QGridLayout* reqcLayout = new QGridLayout;
1249 _reqcActionComboBox->setMinimumWidth(15 * ww);
1250 _reqcActionComboBox->setMaximumWidth(20 * ww);
1251
1252 _reqcObsFileChooser = new qtFileChooser(0, qtFileChooser::Files);
1253 _reqcObsFileChooser->setFileName(settings.value("reqcObsFile").toString());
1254
1255 _reqcNavFileChooser = new qtFileChooser(0, qtFileChooser::Files);
1256 _reqcNavFileChooser->setFileName(settings.value("reqcNavFile").toString());
1257 _reqcOutObsLineEdit = new QLineEdit(settings.value("reqcOutObsFile").toString());
1258 _reqcOutNavLineEdit = new QLineEdit(settings.value("reqcOutNavFile").toString());
1259 _reqcOutLogLineEdit = new QLineEdit(settings.value("reqcOutLogFile").toString());
1260 _reqcPlotDirLineEdit = new QLineEdit(settings.value("reqcPlotDir").toString());
1261 _reqcSkyPlotSignals = new QLineEdit(settings.value("reqcSkyPlotSignals").toString());
1262
1263 connect(_reqcSkyPlotSignals, SIGNAL(textChanged(const QString&)),
1264 this, SLOT(slotBncTextChanged()));
1265
1266 _reqcLogSummaryOnly = new QCheckBox();
1267 _reqcLogSummaryOnly->setCheckState(Qt::CheckState(settings.value("reqcLogSummaryOnly").toInt()));
1268
1269 _reqcMinEle = new QSpinBox();
1270 _reqcMinEle->setMinimum(0);
1271 _reqcMinEle->setMaximum(90);
1272 _reqcMinEle->setSingleStep(1);
1273 _reqcMinEle->setSuffix(" deg");
1274 _reqcMinEle->setValue(settings.value("reqcMinEle").toInt());
1275
1276 ir = 0;
1277 reqcLayout->addWidget(new QLabel("RINEX file editing, concatenation and quality check.<br>"), ir, 0, 1, 8);
1278 ++ir;
1279 reqcLayout->addWidget(new QLabel("Action"), ir, 0);
1280 reqcLayout->addWidget(_reqcActionComboBox, ir, 1);
1281 _reqcEditOptionButton = new QPushButton("Set Edit Options");
1282 _reqcEditOptionButton->setMinimumWidth(15 * ww);
1283 _reqcEditOptionButton->setMaximumWidth(20 * ww);
1284
1285 reqcLayout->addWidget(_reqcEditOptionButton, ir, 3);
1286 ++ir;
1287 reqcLayout->addWidget(new QLabel("Input files (full path)"), ir, 0);
1288 reqcLayout->addWidget(_reqcObsFileChooser, ir, 1);
1289 _reqcObsFileChooser->setMaximumWidth(40 * ww);
1290 reqcLayout->addWidget(new QLabel(" Obs"), ir, 2);
1291 reqcLayout->addWidget(_reqcNavFileChooser, ir, 3);
1292 _reqcNavFileChooser->setMaximumWidth(40 * ww);
1293 reqcLayout->addWidget(new QLabel(" Nav"), ir, 4);
1294 ++ir;
1295 reqcLayout->addWidget(new QLabel("Output file (full path)"), ir, 0);
1296 reqcLayout->addWidget(_reqcOutObsLineEdit, ir, 1);
1297 _reqcOutObsLineEdit->setMaximumWidth(40 * ww);
1298 reqcLayout->addWidget(new QLabel(" Obs"), ir, 2);
1299 reqcLayout->addWidget(_reqcOutNavLineEdit, ir, 3);
1300 _reqcOutNavLineEdit->setMaximumWidth(40 * ww);
1301 reqcLayout->addWidget(new QLabel(" Nav"), ir, 4);
1302 ++ir;
1303 reqcLayout->addWidget(new QLabel("Minimum Elevation"), ir, 0);
1304 reqcLayout->addWidget(_reqcMinEle, ir, 1);
1305 ++ir;
1306 reqcLayout->addWidget(new QLabel("Logfile"), ir, 0);
1307 reqcLayout->addWidget(_reqcOutLogLineEdit, ir, 1);
1308 _reqcOutLogLineEdit->setMaximumWidth(40 * ww);
1309 reqcLayout->addWidget(new QLabel(" Summary only"), ir, 2);
1310 reqcLayout->addWidget(_reqcLogSummaryOnly, ir, 3);
1311 ++ir;
1312 reqcLayout->addWidget(new QLabel("Plots for signals"), ir, 0);
1313 reqcLayout->addWidget(_reqcSkyPlotSignals, ir, 1);
1314 _reqcSkyPlotSignals->setMaximumWidth(40 * ww);
1315 ++ir;
1316 reqcLayout->addWidget(new QLabel("Directory for plots"), ir, 0);
1317 reqcLayout->addWidget(_reqcPlotDirLineEdit, ir, 1);
1318 _reqcPlotDirLineEdit->setMaximumWidth(40 * ww);
1319 ++ir;
1320 reqcLayout->setRowStretch(ir, 999);
1321
1322 reqcLayout->setColumnMinimumWidth(2, 8 * ww);
1323 reqcLayout->setColumnMinimumWidth(4, 8 * ww);
1324
1325 reqcgroup->setLayout(reqcLayout);
1326
1327 connect(_reqcEditOptionButton, SIGNAL(clicked()),
1328 this, SLOT(slotReqcEditOption()));
1329
1330 QGridLayout* sp3CompLayout = new QGridLayout;
1331
1332 _sp3CompFileChooser = new qtFileChooser(0, qtFileChooser::Files);
1333 _sp3CompFileChooser->setFileName(settings.value("sp3CompFile").toString());
1334 _sp3CompFileChooser->setMinimumWidth(15 * ww);
1335 _sp3CompFileChooser->setMaximumWidth(40 * ww);
1336
1337 _sp3CompExclude = new QLineEdit(settings.value("sp3CompExclude").toString());
1338 _sp3CompExclude->setMinimumWidth(18 * ww);
1339 _sp3CompExclude->setMaximumWidth(18 * ww);
1340
1341 _sp3CompLogLineEdit = new QLineEdit(settings.value("sp3CompOutLogFile").toString());
1342 _sp3CompLogLineEdit->setMinimumWidth(18 * ww);
1343 _sp3CompLogLineEdit->setMaximumWidth(18 * ww);
1344
1345 _sp3CompSummaryOnly = new QCheckBox();
1346 _sp3CompSummaryOnly->setCheckState(Qt::CheckState(settings.value("sp3CompSummaryOnly").toInt()));
1347
1348 ir = 0;
1349 sp3CompLayout->addWidget(new QLabel("Orbit and clock comparison.<br>"), ir, 0, 1, 40);
1350 ++ir;
1351 sp3CompLayout->addWidget(new QLabel("Input SP3 files (full path)"), ir, 0, Qt::AlignLeft);
1352 sp3CompLayout->addWidget(_sp3CompFileChooser, ir, 1, 1, 20);
1353 ++ir;
1354 sp3CompLayout->addWidget(new QLabel("Exclude satellites"), ir, 0, Qt::AlignLeft);
1355 sp3CompLayout->addWidget(_sp3CompExclude, ir, 1, Qt::AlignRight);
1356 ++ir;
1357 sp3CompLayout->addWidget(new QLabel("Logfile"), ir, 0, Qt::AlignLeft);
1358 sp3CompLayout->addWidget(_sp3CompLogLineEdit, ir, 1, Qt::AlignRight);
1359 ++ir;
1360 sp3CompLayout->addWidget(new QLabel("Summary only"), ir, 0);
1361 sp3CompLayout->addWidget(_sp3CompSummaryOnly, ir, 1);
1362 ++ir;
1363 sp3CompLayout->addWidget(new QLabel(""), ir, 1);
1364 ++ir;
1365 sp3CompLayout->setRowStretch(ir, 999);
1366
1367 sp3CompLayout->setColumnMinimumWidth(2, 8 * ww);
1368 sp3CompLayout->setColumnMinimumWidth(4, 8 * ww);
1369
1370 sp3CompGroup->setLayout(sp3CompLayout);
1371
1372 connect(_sp3CompFileChooser, SIGNAL(fileNameChanged(const QString&)),
1373 this, SLOT(slotBncTextChanged()));
1374
1375 // Combine Corrections
1376 // -------------------
1377 QGridLayout* cmbLayout = new QGridLayout;
1378
1379 populateCmbTable();
1380 cmbLayout->addWidget(_cmbTable, 0, 0, 8, 10);
1381 cmbLayout->addWidget(new QLabel(" Combine Broadcast Correction streams"), 0, 10, 1, 10);
1382 cmbLayout->addWidget(addCmbRowButton, 1, 10);
1383 cmbLayout->addWidget(delCmbRowButton, 1, 11);
1384 cmbLayout->addWidget(new QLabel("Method"), 2, 10, Qt::AlignLeft);
1385 cmbLayout->addWidget(_cmbMethodComboBox, 2, 11);
1386 cmbLayout->addWidget(new QLabel("BSX File"), 3, 10, Qt::AlignLeft);
1387 cmbLayout->addWidget(_cmbBsxFile, 3, 11, Qt::AlignRight);
1388 cmbLayout->addWidget(new QLabel("Max Clk Residual"), 4, 10, Qt::AlignLeft);
1389 cmbLayout->addWidget(_cmbMaxresLineEdit, 4, 11, Qt::AlignRight);
1390 cmbLayout->addWidget(new QLabel("Max Orb Displacement"), 5, 10, Qt::AlignLeft);
1391 cmbLayout->addWidget(_cmbMaxdisplacementLineEdit, 5, 11, Qt::AlignRight);
1392 cmbLayout->addWidget(new QLabel("Logfile directory"), 6, 10, Qt::AlignLeft);
1393 cmbLayout->addWidget(_cmbLogPath, 6, 11, Qt::AlignRight);
1394 cmbLayout->addWidget(new QLabel("Sampling"), 7, 10, Qt::AlignLeft);
1395 cmbLayout->addWidget(_cmbSamplComboBox, 7, 11, Qt::AlignRight);
1396
1397
1398 cmbLayout->addWidget(new QLabel("GNSS"), 0, 14, Qt::AlignLeft);
1399 cmbLayout->addWidget(new QLabel("GPS (C1W/C2W)"), 1, 14);
1400 cmbLayout->addWidget(_cmbGpsCheckBox, 1, 15);
1401
1402 cmbLayout->addWidget(new QLabel("GLONASS (C1P/C2P)"), 2, 14);
1403 cmbLayout->addWidget(_cmbGloCheckBox, 2, 15);
1404
1405 cmbLayout->addWidget(new QLabel("Galileo (C1C/C5Q)"), 3, 14);
1406 cmbLayout->addWidget(_cmbGalCheckBox, 3, 15);
1407
1408 cmbLayout->addWidget(new QLabel("Beidou (C2I/C6I)"), 4, 14);
1409 cmbLayout->addWidget(_cmbBdsCheckBox, 4, 15);
1410
1411 cmbLayout->addWidget(new QLabel("QZSS (C1C/C2L)"), 5, 14);
1412 cmbLayout->addWidget(_cmbQzssCheckBox, 5, 15);
1413
1414 cmbLayout->addWidget(new QLabel("SBAS (C1C/C5Q)"), 6, 14);
1415 cmbLayout->addWidget(_cmbSbasCheckBox, 6, 15);
1416
1417 cmbLayout->addWidget(new QLabel("NavIC"), 7, 14);
1418 cmbLayout->addWidget(_cmbNavicCheckBox, 7, 15);
1419 cmbLayout->setRowStretch(9, 999);
1420
1421 connect(addCmbRowButton, SIGNAL(clicked()), this, SLOT(slotAddCmbRow()));
1422 connect(delCmbRowButton, SIGNAL(clicked()), this, SLOT(slotDelCmbRow()));
1423
1424 cmbgroup->setLayout(cmbLayout);
1425
1426 // Upload Layout (Clocks)
1427 // ----------------------
1428 QGridLayout* uploadHlpLayout = new QGridLayout();
1429
1430 connect(addUploadRowButton, SIGNAL(clicked()), this, SLOT(slotAddUploadRow()));
1431 connect(delUploadRowButton, SIGNAL(clicked()), this, SLOT(slotDelUploadRow()));
1432 connect(setUploadTrafoButton, SIGNAL(clicked()), this, SLOT(slotSetUploadTrafo()));
1433
1434 uploadHlpLayout->addWidget(addUploadRowButton, 0, 0);
1435 uploadHlpLayout->addWidget(delUploadRowButton, 0, 1);
1436 uploadHlpLayout->addWidget(new QLabel("Interval"), 0, 2, Qt::AlignRight);
1437 uploadHlpLayout->addWidget(_uploadIntrComboBox, 0, 3);
1438 uploadHlpLayout->addWidget(new QLabel(" Sampling: Orb"), 0, 4, Qt::AlignRight);
1439 uploadHlpLayout->addWidget(_uploadSamplRtcmEphCorrComboBox, 0, 5);
1440 uploadHlpLayout->addWidget(new QLabel("SP3"), 0, 6, Qt::AlignRight);
1441 uploadHlpLayout->addWidget(_uploadSamplSp3ComboBox, 0, 7);
1442 uploadHlpLayout->addWidget(new QLabel("RNX"), 0, 8, Qt::AlignRight);
1443 uploadHlpLayout->addWidget(_uploadSamplClkRnxSpinBox, 0, 9);
1444 uploadHlpLayout->addWidget(new QLabel("BSX"), 0, 10, Qt::AlignRight);
1445 uploadHlpLayout->addWidget(_uploadSamplBiaSnxSpinBox, 0, 11);
1446 uploadHlpLayout->addWidget(setUploadTrafoButton, 0, 12);
1447 uploadHlpLayout->addWidget(new QLabel("ANTEX file"), 1, 0, Qt::AlignLeft);
1448 uploadHlpLayout->addWidget(_uploadAntexFile, 1, 1, 1, 4);
1449
1450 QBoxLayout* uploadLayout = new QBoxLayout(QBoxLayout::TopToBottom);
1451 populateUploadTable();
1452
1453 uploadLayout->addWidget(new QLabel("Upload RTCM Version 3 Broadcast Corrections to Broadcaster.<br>"));
1454 uploadLayout->addWidget(_uploadTable);
1455 uploadLayout->addLayout(uploadHlpLayout);
1456
1457 uploadgroup->setLayout(uploadLayout);
1458
1459 // Upload Layout (Ephemeris)
1460 // -------------------------
1461 QGridLayout* uploadHlpLayoutEph = new QGridLayout();
1462
1463 connect(addUploadEphRowButton, SIGNAL(clicked()), this, SLOT(slotAddUploadEphRow()));
1464 connect(delUploadEphRowButton, SIGNAL(clicked()), this, SLOT(slotDelUploadEphRow()));
1465
1466 uploadHlpLayoutEph->addWidget(addUploadEphRowButton, 0, 0);
1467 uploadHlpLayoutEph->addWidget(delUploadEphRowButton, 0, 1);
1468 uploadHlpLayoutEph->addWidget(new QLabel(" Sampling"), 0, 2, Qt::AlignRight);
1469 uploadHlpLayoutEph->addWidget(_uploadSamplRtcmEphSpinBox, 0, 3);
1470
1471 QBoxLayout* uploadLayoutEph = new QBoxLayout(QBoxLayout::TopToBottom);
1472 populateUploadEphTable();
1473
1474 uploadLayoutEph->addWidget(new QLabel("Upload RTCM Version 3 Broadcast Ephemeris to Broadcaster.<br>"));
1475 uploadLayoutEph->addWidget(_uploadEphTable);
1476 uploadLayoutEph->addLayout(uploadHlpLayoutEph);
1477
1478 uploadEphgroup->setLayout(uploadLayoutEph);
1479
1480
1481 // Upload Layout (Raw Data)
1482 // -------------------------
1483 QGridLayout* uploadHlpLayoutRaw = new QGridLayout();
1484
1485 connect(addUploadRawRowButton, SIGNAL(clicked()), this, SLOT(slotAddUploadRawRow()));
1486 connect(delUploadRawRowButton, SIGNAL(clicked()), this, SLOT(slotDelUploadRawRow()));
1487
1488 uploadHlpLayoutRaw->addWidget(addUploadRawRowButton, 0, 0);
1489 uploadHlpLayoutRaw->addWidget(delUploadRawRowButton, 0, 1);
1490
1491 QBoxLayout* uploadLayoutRaw = new QBoxLayout(QBoxLayout::TopToBottom);
1492 populateUploadRawTable();
1493
1494 uploadLayoutRaw->addWidget(new QLabel("Upload Raw Data to Broadcaster (Ntrip Server Functionality).<br>"));
1495 uploadLayoutRaw->addWidget(_uploadRawTable);
1496 uploadLayoutRaw->addLayout(uploadHlpLayoutRaw);
1497
1498 uploadRawgroup->setLayout(uploadLayoutRaw);
1499
1500 // Main Layout
1501 // -----------
1502 QGridLayout* mLayout = new QGridLayout;
1503 _aogroup->setCurrentIndex(settings.value("startTab").toInt());
1504 mLayout->addWidget(_aogroup, 0, 0);
1505 mLayout->addWidget(_mountPointsTable, 1, 0);
1506 _loggroup->setCurrentIndex(settings.value("statusTab").toInt());
1507 mLayout->addWidget(_loggroup, 2, 0);
1508
1509 _canvas->setLayout(mLayout);
1510
1511 // WhatsThis, Network
1512 // ------------------
1513 _proxyHostLineEdit->setWhatsThis(tr("<p>If you are running BNC within a protected Local Area Network (LAN), you may 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. Without any entry, BNC will try to use the system proxies. </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 this is not possible, you may need to run BNC outside your LAN on a network that has unobstructed connection to the Internet. <i>[key: proxyHost]</i></p>"));
1514 _proxyPortLineEdit->setWhatsThis(tr("<p>Enter your proxy server port number in case a proxy is operated in front of BNC. <i>[key: proxyPort]</i></p>"));
1515 _sslCaCertPathLineEdit->setWhatsThis(tr("<p>Communication with an Ntrip Broadcaster over SSL requires the exchange of server certificates. Specify the path to a directory where you save CA certificates on your system. </p><p>BNC creates from *.crt and *.pem files a CA certificate database, which is used by the socket during the handshake phase to validate the peer's certificate. </p><p>Note that SSL communication is usually done over port 443. <i>[key: sslCaCertPath]</i></p>"));
1516 _sslClientCertPathLineEdit->setWhatsThis(tr("<p>Two-sided communication with an Ntrip Broadcaster over SSL requires in addition the exchange of client certificates. Specify the full path to the client certificates on your system.</p><p></p><p>The file naming convention for client certificates in BNC is as follows: &lt;hostname&gt;.&lt;port&gt;.crt for the certificate and &lt;hostname&gt;.&lt;port&gt;.key for the private key, where &lt;hostname&gt; is without https://. </p><p> If available, the client or personal authentication certificate is presented to the peer during the SSL handshake process. Password protected key files are not supported. </p><p>Don't try communication via two sided SSL if you are not sure whether this is supported by the involved Ntrip Broadcaster. </p><p>Note that SSL communication is usually done over port 443. <i>[key: sslClientCertPath]</i></p>"));
1517 _sslIgnoreErrorsCheckBox->setWhatsThis(tr("<p>SSL communication may involve queries coming from the Ntrip Broadcaster. Tick 'Ignore SSL authorization errors' if you don't want to be bothered with this. <i>[key: sslIgnoreErrors]</i></p>"));
1518
1519 // WhatsThis, General
1520 // ------------------
1521 _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 for that 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. <i>[key: logFile]</i></p>"));
1522 _rnxAppendCheckBox->setWhatsThis(tr("<p>When BNC is started, new files are created by default and file content already available under the same name will be overwritten. However, users might want to append already existing files following a regular restart or a crash of BNC or its platform.</p><p>Tick 'Append files' to continue with existing files and keep what has been recorded so far. <i>[key: rnxAppend]</i></p>"));
1523 _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. The default entry is 'no' that means the reread function is switched of. <p></p>Select '1 min', '5 min', '1 hour', or '1 day' to force BNC to reread its configuration every full minute, five minutes, 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 via button 'Save & Reread Configuration'. <i>[key: onTheFlyInterval]</i></p>"));
1524 _autoStartCheckBox->setWhatsThis(tr("<p>Tick 'Auto start' for auto-start of BNC at startup time in window mode with preassigned processing options. <i>[key: autoStart]</i></p>"));
1525 _rawOutFileLineEdit->setWhatsThis(tr("<p>Save all data coming in through various streams in the received order and format in one file.</p><p>This option is primarily meant for debugging purposes. <i>[key: rawOutFile]</i></p>"));
1526
1527 // WhatsThis, RINEX Observations
1528 // -----------------------------
1529 _rnxPathLineEdit->setWhatsThis(tr("<p>Here you specify the path to where the RINEX Observation files will be stored.</p><p>If the specified directory does not exist, BNC will not create RINEX Observation files. <i>[key: rnxPath]</i></p>"));
1530 _rnxIntrComboBox->setWhatsThis(tr("<p>Select the length of the RINEX Observation file. <i>[key: rnxIntr]</i></p>"));
1531 _rnxSamplComboBox->setWhatsThis(tr("<p>Select the RINEX Observation sampling interval in seconds. <i>[key: rnxSampl]</i></p>"));
1532 _rnxSkelExtComboBox->setWhatsThis(tr("<p>BNC allows using personal RINEX skeleton files that contain the RINEX header records you would like to include. You can derive a skeleton file from information given in an up to date sitelog.</p><p>A file in the RINEX Observations 'Directory' with a 'Skeleton extension' skl or SKL is interpreted by BNC as a personal RINEX header skeleton file for the corresponding stream. <i>[key: rnxSkel]</i></p>"));
1533 _rnxSkelPathLineEdit->setWhatsThis(tr("<p>Here you specify the path to where local skeleton files are located.</p><p> If no directory is specified, the path is assumed to where the RINEX Observation files will stored. <i>[key: rnxSkelPath]</i></p>"));
1534 _rnxFileCheckBox->setWhatsThis(tr("<p>Tick check box 'Skeleton mandatory' in case you want that RINEX files are only produced if skeleton files are available for BNC. If no skeleton file is available for a particular source then no RINEX Observation file will be produced from the affected stream.</p><p>Note that a skeleton file contains RINEX header information such as receiver and antenna types. In case of stream conversion to RINEX Version 3, a skeleton file should also contain information on potentially available observation types. A missing skeleton file will therefore enforce BNC to only save a default set of RINEX 3 observation types. <i>[key: rnxOnlyWithSKL]</i></p>"));
1535 _rnxScrpLineEdit->setWhatsThis(tr("<p>Whenever a RINEX Observation file is finally saved, you may want to compress, copy or upload it immediately, for example via FTP. BNC allows you to execute a script/batch file to carry out such operation.</p><p>Specify the full path of a script or batch file. BNC will pass the full RINEX Observation file path to the script as command line parameter (%1 on Windows systems, $1 on Unix/Linux/Mac systems). <i>[key: rnxScript]</i></p>"));
1536 _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>Signal priorities can be specified as equal for all systems, as system specific or as system and freq. specific. For example: </li><ul><li>'CWPX_?' (General signal priorities valid for all GNSS) </li><li>'I:ABCX' (System specific signal priorities for NavIC) </li><li>'G:12&PWCSLX G:5&IQX R:12&PC R:3&IQX' (System and frequency specific signal priorities) </li></ul>Default is the following priority list 'G:12&PWCSLX G:5&IQX R:12&PC R:3&IQX R:46&ABX E:16&BCXZ E:578&IQX J:1&SLXCZ J:26&SLX J:5&IQX C:267&IQX C:18&DPX I:ABCX S:1&C S:5&IQX'. <i>[key: rnxV2Priority]</i></p>"));
1537 _rnxVersComboBox->setWhatsThis(tr("<p>Select the format for RINEX Observation files. <i>[key: rnxVersion]</i></p>"));
1538
1539 // WhatsThis, RINEX Ephemeris
1540 // --------------------------
1541 _ephPathLineEdit->setWhatsThis(tr("<p>Specify the path for saving Broadcast Ephemeris data as RINEX Navigation files.</p><p>If the specified directory does not exist, BNC will not create RINEX Navigation files. <i>[key: ephPath]</i></p>"));
1542 _ephIntrComboBox->setWhatsThis(tr("<p>Select the length of the RINEX Navigation file. <i>[key: ephIntr]</i></p>"));
1543 _ephOutPortLineEdit->setWhatsThis(tr("<p>BNC can produce ephemeris data in RINEX Navigation ASCII format on your local host through an IP port.</p><p>Specify a port number here to activate this function. <i>[key: ephOutPort]</i></p>"));
1544 _ephVersComboBox->setWhatsThis(tr("<p>Select the format for RINEX Navigation files. <i>[key: ephVersion]</i></p>"));
1545 //_ephFilePerStation->setWhatsThis(tr("<p>By default, all received Broadcast Ephemeris data will be stored within one File. Thick 'File per Stations' to get separate files per station/mountpoint. <i>[key: ephFilePerStation]</i></p>"));
1546
1547 // WhatsThis, RINEX Editing & QC
1548 // -----------------------------
1549 _reqcActionComboBox->setWhatsThis(tr("<p>BNC allows to 'Edit or Concatenate' RINEX Version 2 or 3 files or to perform a Quality Check (QC) and 'Analyze' data following UNAVCO's famous 'teqc' program. <i>[key: reqcAction]</i></p>"));
1550 _reqcEditOptionButton->setWhatsThis(tr("<p>Specify options for editing RINEX Version 2 or 3 files.</p>"));
1551 _reqcObsFileChooser->setWhatsThis(tr("<p>Specify the full path to input observation files in RINEX Version 2 or 3 format.</p><p>Note that when in 'Analyze' mode, specifying at least one RINEX observation file is mandatory. <i>[key: reqcObsFile]</i></p>"));
1552 _reqcNavFileChooser->setWhatsThis(tr("<p>Specify the full path to input navigation files in RINEX Version 2 or 3 format.</p><p>Note that when in 'Analyze' mode, specifying at least one RINEX navigation file is mandatory. <i>[key: reqcNavFile]</i></p>"));
1553 _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. <i>[key: reqcOutObsFile]</i></p>"));
1554 _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. <i>[key: reqcOutNavFile]</i></p>"));
1555 _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. <i>[key: reqcOutLogFile]</i></p>"));
1556 _reqcMinEle->setWhatsThis(tr("<p>Select a Minimum satellite Elevation.</p><p>BNC will ignore an observation if the associated satellite Elevation does not reach or exceed this minimum. This requires a RINEX Navigation input file to compute satellite elevations.</p><p>Default is '0 deg' meaning that no elevation mask is applied. <i>[key: reqcMinEle]</i></p>"));
1557 _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 content to a short summary.</p><p>Tick 'Summary only' to suppress full logfile output and instead produce a logfile containing only summary information. <i>[key: reqcLogSummaryOnly]</i></p>"));
1558 _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. <i>[key: reqcPlotDir]</i></p>"));
1559 _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 observation signals to be used for that and also enables the plot generation. You can specify the navigation system, the frequency, and the tracking mode or channel as defined in RINEX Version 3. Specifications for frequency and tracking mode or channel must be separated by ampersand character '&'. Specifications for navigation systems must be separated by blank character ' '.</p><p>Examples for 'Plots for signals' option:<ul><li> G:1&2&5 R:1&2&3 E:1&7 C:2&6 J:1&2 I:5&9 S:1&5 <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 'G:1&2 R:1&2 E:1&5 C:2&6 J:1&2 I:5&9 S:1&5'. Specifying an empty option string would be overruled by this default. <i>[key: reqcSkyPlotSignals]</i></p>"));
1560
1561 // WhatsThis, SP3 Comparison
1562 // -------------------------
1563 _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. <i>[key: sp3CompFile]</i></p>"));
1564 _sp3CompExclude->setWhatsThis(tr("<p>Specify satellites to exclude them from orbit and clock comparison. Example:<p>G04,G31,R</p><p>This excludes GPS satellites PRN 4 and 31 as well as all GLONASS satellites from the comparison.</p><p>Default is an empty option field, meaning that no satellite is excluded from the comparison. <i>[key: sp3CompExclude]</i></p>"));
1565 _sp3CompLogLineEdit->setWhatsThis(tr("<p>Specify the full path to a logfile saving comparison results.</p><p>Specifying a logfile is mandatory. Comparing SP3 files and not saving comparison results on disk would be useless. <i>[key: sp3CompOutLogFile]</i></p>"));
1566 _sp3CompSummaryOnly->setWhatsThis(tr("<p>By default BNC produces a detailed 'Logfile' providing all information resulting from comparing SP3 files. If that is too much information, you can limit the logfile content to a short summary.</p><p>Tick 'Summary only' to suppress full logfile output and instead produce a logfile containing only summary information. <i>[key: sp3CompSummaryOnly]</i></p>"));
1567
1568 // WhatsThis, Broadcast Corrections
1569 // --------------------------------
1570 _corrPathLineEdit->setWhatsThis(tr("<p>Specify a directory for saving Broadcast Ephemeris Correction files.</p><p>If the specified directory does not exist, BNC will not create the files. <i>[key: corrPath]</i></p>"));
1571 _corrIntrComboBox->setWhatsThis(tr("<p>Select the length of Broadcast Ephemeris Correction files. <i>[key: corrIntr]</i></p>"));
1572 _corrPortLineEdit->setWhatsThis(tr("<p>BNC can produce Broadcast Ephemeris Corrections on your local host through an IP port.</p><p>Specify a port number here to activate this function. <i>[key: corrPort]</i></p>"));
1573
1574 // WhatsThis, Feed Engine
1575 // ----------------------
1576 _outPortLineEdit->setWhatsThis(tr("<p>BNC can produce synchronized observations in a plain ASCII format on your local host via IP port.</p><p>Specify a port number to activate this function. <i>[key: outPort]</i></p>"));
1577 _outWaitSpinBox->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.</p><p>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 product. <i>[key: outWait]</i></p>"));
1578 _outSamplComboBox->setWhatsThis(tr("<p>Select a synchronized observation sampling interval in seconds. <i>[key: outSampl]</i></p>"));
1579 _outFileLineEdit->setWhatsThis(tr("<p>Specify the full path to a file where synchronized observations are saved in plain ASCII format.</p><p>Beware that the size of this file can rapidly increase depending on the number of incoming streams. <i>[key: outFile]</i></p>"));
1580 _outUPortLineEdit->setWhatsThis(tr("<p>BNC can produce unsynchronized observations in a plain ASCII format on your local host via IP port.</p><p>Specify a port number to activate this function. <i>[key: outUPort]</i></p>"));
1581 _outLockTimeCheckBox->setWhatsThis(tr("<p>Print the lock time in seconds in the feed engine output.<i>[key: outLockTime]</i></p>"));
1582
1583 // WhatsThis, Serial Output
1584 // ------------------------
1585 _serialMountPointLineEdit->setWhatsThis(tr("<p>Enter a 'Mountpoint' to forward the corresponding stream to a serial connected receiver.</p><p>Depending on the stream content, the receiver may use it for example for Differential GNSS, Precise Point Positioning or any other purpose supported by its firmware. <i>[key: serialMountPoint]</i></p>"));
1586 _serialPortNameLineEdit->setWhatsThis(tr("<p>Enter the serial 'Port name' selected for communication with your serial connected receiver. Valid port names are e.g.</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 before you start BNC, you must plug a serial cable in the port defined here. <i>[key: serialPortName]</i></p>"));
1587 _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. Using a high baud rate is recommended. <i>[key: serialBaudRate]</i></p>"));
1588 _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. <i>[key: serialFlowControl]</i></p>"));
1589 _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. <i>[key: serialDataBits]</i></p>"));
1590 _serialParityComboBox->setWhatsThis(tr("<p>Select a 'Parity' for the serial output link.</p><p>Note that your selection must equal the parity selection configured to the serial connected receiver. The parity is often set to 'NONE'. <i>[key: serialParity]</i></p>"));
1591 _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. <i>[key: serialStopBits]</i></p>"));
1592 _serialAutoNMEAComboBox->setWhatsThis(tr("<p>The 'NMEA' option supports the so-called 'Virtual 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 source-table or introduced by the user via editing the BNC configuration file. <i>[key: serialAutoNMEA]</i></p>"));
1593 _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. <i>[key: serialFileNMEA]</i></p>"));
1594 _serialHeightNMEALineEdit->setWhatsThis(tr("<p>Specify an approximate 'Height' above mean sea level in meters for the reference station introduced by option 'Mountpoint'. Together with the latitude and longitude from the source-table, 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. <i>[key: serialHeightNMEA]</i></p>"));
1595 _serialNMEASamplingSpinBox->setWhatsThis(tr("<p>Select a sampling interval in seconds for manual or receiver generated NMEA GGA sentences and their upload.</p><p>A sampling rate of '0' means, 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. <i>[key: serialNMEASampling]</i></p>"));
1596
1597 // WhatsThis, Outages
1598 // ------------------
1599 _adviseObsRateComboBox->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. <i>[key: adviseObsRate]</i></p>"));
1600 _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. <i>[key: adviseFail]</i></p>"));
1601 _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. <i>[key: adviseReco]</i></p>"));
1602 _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 a comment '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. <i>[key: adviseScript]</i></p>"));
1603
1604 // WhatsThis, Miscellaneous
1605 // ------------------------
1606 _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. <i>[key: miscMount]</i></p>"));
1607 _miscIntrComboBox->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. <i>[key: miscIntr]</i></p>"));
1608 _miscScanRTCMCheckBox->setWhatsThis(tr("<p>Tick 'Scan RTCM' to log the numbers of incoming message types as well as contained antenna coordinates, antenna height, and antenna descriptor.</p><p>In case of RTCM Version 3 MSM streams, BNC will also log contained RINEX Version 3 observation types. <i>[key: miscScanRTCM]</i></p>"));
1609 _miscPortLineEdit->setWhatsThis(tr("<p>BNC can output an incoming stream through an IP port of your local host.</p><p>Specify a port number to activate this function. In this case, the stream content remains untouched; BNC does not decode or reformat the data for this output.</p><p> If the decoder string is not an accepted one ('RTCM_2.x', 'RTCM_3.x' and 'RTNET'), please change the decoder string to <ul>"
1610 "<li> 'ZERO' (forward the raw data) or </li>"
1611 "<li> 'ZERO2FILE' (forward and store the raw data)</li> </ul> in addition. <i>[key: miscPort]</i></p>"));
1612
1613 // WhatsThis, PPP (1)
1614 // ------------------
1615 _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 a 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 <u>products.igs-ip.net</u>.<br></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. <i>[key: PPP/dataSource]</i></p>"));
1616 _pppWidgets._rinexObs->setWhatsThis(tr("<p>Specify the RINEX Observation file. <i>[key: PPP/rinexObs]</i></p>"));
1617 _pppWidgets._rinexNav->setWhatsThis(tr("<p>Specify the RINEX Navigation file. <i>[key: PPP/rinexNav]</i></p>"));
1618 _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 via this option, BNC will fall back to Single Point Positioning (SPP, positioning from observations and Broadcast Ephemeris only) instead of doing PPP. <i>[key: PPP/corrMount]</i></p>"));
1619 _pppWidgets._biasMount->setWhatsThis(tr("<p>Specify a 'mountpoint' from the 'Streams' canvas below which provides satellite biases in SSR format.</p><p>If you don't specify a corrections stream via this option, BNC will use satellite biases from the Corrections stream 'mountpoint', if available. <i>[key: PPP/biasMount]</i></p>"));
1620 _pppWidgets._ionoMount->setWhatsThis(tr("<p>Specify a 'mountpoint' from the 'Streams' canvas below which provides VTEC informations in SSR format.</p><p>If you don't specify a corrections stream via this option, BNC will use VTEC informations from the Corrections stream 'mountpoint', if available. <i>[key: PPP/ionoMount]</i></p>"));
1621 _pppWidgets._corrFile->setWhatsThis(tr("<p>Specify the Broadcast Ephemeris Corrections file as saved beforehand using BNC.</p><p>If you don't specify corrections by this option, BNC will fall back to Single Point Positioning (SPP, positioning from RINEX Obs and RINEX Nav files only) instead of doing PPP. <i>[key: PPP/corrFile]</i></p>"));
1622 _pppWidgets._biasFile->setWhatsThis(tr("<p>Specify the satellite bias file as saved beforehand using BNC.</p><p>If you don't specify corrections by this option, BNC will use satellite biases from the Corrections file, if available. <i>[key: PPP/biasFile]</i></p>"));
1623 _pppWidgets._ionoFile->setWhatsThis(tr("<p>Specify the VTEC file as saved beforehand using BNC.</p><p>If you don't specify corrections by this option, BNC will use VTEC informations from the Corrections file, if available. <i>[key: PPP/ionoFile]</i></p>"));
1624 _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 and variations</li><li>Satellite APC offsets and variations.</li></ul> Specify the full path to an IGS 'ANTEX file' which contains APC offsets and variations for satellites and receiver.</p> <i>[key: PPP/antexFile]</i></p>"));
1625 _pppWidgets._crdFile->setWhatsThis(tr("<p>Enter the full path to an ASCII file which specifies the streams or files of those stations you want to process. Specifying a 'Coordinates file' is optional. If it exists, it should contain one record per station with the following parameters separated by blank character:</p><ul><li>Specify the station either by:<ul><li>the 'Mountpoint' of the station's RTCM stream (in real-time PPP mode), or</li><li>the 9-char station ID of the RINEX Version 3 or 4 Observations file (in post processing PPP mode), or </li><li>the 4-char station ID of the RINEX Version 2 Observations file (in post processing PPP mode).</li></ul><li>Approximate X,Y,Z coordinate of station's Antenna Reference Point [m] (ARP, specify '0.0 0.0 0.0' if unknown).</li><li>North, East and Up component of antenna eccentricity [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><li>Receiver type following the naming conventions for IGS equipment.</li></ul>Records with exclamation mark '!' in the first column or blank records will be interpreted as comment lines and ignored.. <i>[key: PPP/crdFile]</i></p>"));
1626 _pppWidgets._blqFile->setWhatsThis(tr("<p>Specify the full path to a 'BLQ file' containing the ocean loading coefficients for different stations. These coefficients can be obtained from the ocean loading service under request trough the web site http://holt.oso.chalmers.se/loading/. <i>[key: PPP/blqFile]</i></p>"));
1627 _pppWidgets._logPath->setWhatsThis(tr("<p>Specify a directory for saving daily PPP log files. If the specified directory does not exist, BNC will not create such files.</p><p>Default is an empty option field, meaning that no PPP logfiles shall be produced. <i>[key: PPP/logPath]</i></p>"));
1628 _pppWidgets._logMode->setWhatsThis(tr("<p>This option controls the details of the PPP client processing output. The 'normal' mode produces a log file, related to the estimated parameters and observation residuals. If the user selects 'debug' additional information (particularly about used SSR corrections) is printed. The option value 'all' triggers a very detailed log including the information about the constituents of the observation model.</p><p>Default is the 'normal' mode. <i>[key: PPP/logMode]</i></p>"));
1629 _pppWidgets._nmeaPath->setWhatsThis(tr("<p>Specify a directory for saving coordinates in daily NMEA files. If the specified directory does not exist, BNC will not create such files.</p><p>Default is an empty option field, meaning that no NMEA file shall be produced. <i>[key: PPP/nmeaPath]</i></p>"));
1630 _pppWidgets._snxtroPath->setWhatsThis(tr("<p>Specify a directory for saving SINEX Troposphere files. If the specified directory does not exist, BNC will not create such files.</p><p>Default is an empty option field, meaning that no SINEX Troposphere files shall be produced. <i>[key: PPP/snxtroPath]</i></p>"));
1631 _pppWidgets._snxtroIntr->setWhatsThis(tr("<p>Select a length for SINEX Troposphere files.</p><p>Default 'SNX TRO interval' for saving SINEX Troposphere files on disk is '1 hour'. <i>[key: PPP/snxtroIntr]</i></p>"));
1632 _pppWidgets._snxtroSampl->setWhatsThis(tr("<p>Select a 'Sampling' rate for saving troposphere parameters. <i>[key: PPP/snxtroSampl]</i></p>"));
1633 _pppWidgets._snxtroAc->setWhatsThis(tr("<p>Specify a 3-character abbreviation describing you as the generating Analysis Center (AC) in your SINEX troposphere files. <i>[key: PPP/snxtroAc]</i></p>"));
1634 _pppWidgets._snxtroSolId->setWhatsThis(tr("<p>Specify a 1-character solution ID to allow a distinction between different solutions per AC. <i>[key: PPP/snxtroSolId]</i></p>"));
1635 _pppWidgets._snxtroSolType->setWhatsThis(tr("<p>Specify a 3-character solution type, e.g. real-time (RTS), unknown (UNK), .. <i>[key: PPP/snxtroSolType]</i></p>"));
1636 _pppWidgets._snxtroCampId->setWhatsThis(tr("<p>Specify a 3-character campaign ID, e.g. operational (OPS), demonstration (DEM), testing (TST), .. <i>[key: PPP/snxtroCampId]</i></p>"));
1637
1638 // WhatsThis, PPP (2)
1639 // ------------------
1640 _pppWidgets._lcGPS->setWhatsThis(tr("<p>Specify which kind of GPS observations you want to use and on which kind of linear combination the GPS ambiguity resolutions shall be based:</p><p><ul>"
1641 "<li> This option is editable. Hence, you can specify your own frequencies for code (P) and phase (L) observations, e.g. P125&L125, which means that band 1,2 and 5 of code and phase observations are used. The tracking mode for each frequency can be specified per station using the Signal Priorities in PPP(3). </li> "
1642 "<li>'Pi&Li' means that uncombined code and phase data of two frequencies shall be used. Band and attribute can be specified per station using the Signal Priorities in PPP(3). </li>"
1643 "<li>'Pi' means that uncombined code data of two frequencies shall be used. Band and attribute can be specified per station using the Signal Priorities in PPP(3). </li>"
1644 "<li>'P1&L1' means that uncombined code and phase data of one frequency shall be used. Band and attribute can be specified per station using the Signal Priorities in PPP(3). </li>"
1645 "<li>'P1' means that uncombined code data of one frequency shall be used.</li>"
1646 "<li>'P3&L3' means that the inonosphere-free linear combination of code and phase data shall be used. Band and attribute can be specified per station using the Signal Priorities in PPP(3). </li>"
1647 "<li>'P3' means that the inonosphere-free linear combination of code data shall be used. Band and attribute can be specified per station using the Signal Priorities in PPP(3). </li>"
1648 "<li>'L3' means that the inonosphere-free linear combination of phase data shall be used. Band and attribute can be specified per station using the Signal Priorities in PPP(3). </li> "
1649 "<li>'P125&L125' means that band 1,2 and 5 of code and phase observations are used. The tracking mode for each frequency can be specified using the Signal Priorities in PPP(3). </li> "
1650 "<li>'no' means that you don't want BNC to use GPS data.</li></ul></p><p><i>[key: PPP/lcGPS]</i></p>"));
1651 _pppWidgets._lcGLONASS->setWhatsThis(tr("<p>Specify which kind of GLONASS observations you want to use and on which kind of linear combination the GLONASS ambiguity resolutions shall be based:</p><p><ul>"
1652 "<li>'Pi&Li' means that uncombined code and phase data of two frequencies shall be used.</li>"
1653 "<li>'Pi' means that uncombined code data of two frequencies shall be used.</li>"
1654 "<li>'P1&L1' means that uncombined code and phase data of one frequency shall be used.</li>"
1655 "<li>'P1' means that uncombined code data of one frequency shall be used.</li>"
1656 "<li>'P3&L3' means that the inonosphere-free linear combination of code and phase data shall be used.</li>"
1657 "<li>'P3' means that the inonosphere-free linear combination of code data shall be used.</li>"
1658 "<li>'L3' means that the inonosphere-free linear combination of phase data shall be used.</li> "
1659 "<li>'no' means that you don't want BNC to use GLONASS data.</li></ul></p><p><i>[key: PPP/lcGLONASS]</i></p>"));
1660 _pppWidgets._lcGalileo->setWhatsThis(tr("<p>Specify which kind of Galileo observations you want to use and on which kind of linear combination the Galileo ambiguity resolutions shall be based:</p><p><ul>"
1661 "<li> This option is editable. Hence, you can specify your own frequencies for code (P) and phase (L) observations, e.g. P1576&L1576, which means that band 1,5,7 and 6 of code and phase observations are used. The tracking mode for each frequency can be specified per station using the Signal Priorities in PPP(3). </li> "
1662 "<li>'Pi&Li' means that uncombined code and phase data of two frequencies shall be used.</li>"
1663 "<li>'Pi' means that uncombined code data of two frequencies shall be used.</li>"
1664 "<li>'P1&L1' means that uncombined code and phase data of one frequency shall be used.</li>"
1665 "<li>'P1' means that uncombined code data of one frequency shall be used.</li>"
1666 "<li>'P3&L3' means that the inonosphere-free linear combination of code and phase data shall be used.</li>"
1667 "<li>'P3' means that the inonosphere-free linear combination of code data shall be used.</li>"
1668 "<li>'L3' means that the inonosphere-free linear combination of phase data shall be used.</li>"
1669 "<li>'P1576&L1576' means that band 1,5,7 and 6 of code and phase observations are used. The tracking mode for each frequency can be specified using the Signal Priorities in PPP(3). </li> "
1670 "<li>'no' means that you don't want BNC to use Galileo data.</li></ul></p><p><i>[key: PPP/lcGalileo]</i></p>"));
1671 _pppWidgets._lcBDS->setWhatsThis(tr("<p>Specify which kind of BDS observations you want to use and on which kind of linear combination the BDS ambiguity resolutions shall be based:</p><p><ul>"
1672 "<li> This option is editable. Hence, you can specify your own frequencies for code (P) and phase (L) observations, e.g. P1576&L1576, which means that band 1,5,7 and 6 of code and phase observations are used. The tracking mode for each frequency can be specified per station using the Signal Priorities in PPP(3). </li> "
1673 "<li>'Pi&Li' means that uncombined code and phase data of two frequencies shall be used.</li>"
1674 "<li>'Pi' means that uncombined code data of two frequencies shall be used.</li>"
1675 "<li>'P1&L1' means that uncombined code and phase data of one frequency shall be used.</li>"
1676 "<li>'P1' means that uncombined code data of one frequency shall be used.</li>"
1677 "<li>'P3&L3' means that the inonosphere-free linear combination of code and phase data shall be used.</li>"
1678 "<li>'P3' means that the inonosphere-free linear combination of code data shall be used.</li>"
1679 "<li>'L3' means that the inonosphere-free linear combination of phase data shall be used.</li> "
1680 "<li>'P1576&L1576' means that band 1,5,7 and 6 of code and phase observations are used. The tracking mode for each frequency can be specified using the Signal Priorities in PPP(3). </li> "
1681 "<li>'no' means that you don't want BNC to use BDS data.</li></ul></p><p><i>[key: PPP/lcBDS]</i></p>"));
1682 _pppWidgets._constraints->setWhatsThis(tr("<p>Specify, whether ionospheric constraints in form of pseudo-observations shall be added. Please note, this is only valid, if no ionosphere-free linear-combination is used and only helpful as soon as the ionosphere information is more accurate than the code data accuracy. <i>[key: PPP/constraints]</i></p>"));
1683 _pppWidgets._sigmaC1->setWhatsThis(tr("<p>Enter a Sigma for GPS C1 code observations in meters.</p><p>The higher the sigma you enter, the less the contribution of GPS C1 code observations to a PPP solution from combined code and phase data. 1.0 is likely to be an appropriate choice.</p><p>Default is an empty option field, meaning<br>'Sigma C1 = 1.0' <i>[key: PPP/sigmaC1]</i></p>"));
1684 _pppWidgets._sigmaL1->setWhatsThis(tr("<p>Enter a Sigma for GPS L1 phase observations in meters.</p><p>The higher the sigma you enter, the less the contribution of GPS L1 phase observations to a PPP solutions from combined code and phase data. 0.01 is likely to be an appropriate choice.</p><p>Default is an empty option field, meaning<br>'Sigma L1 = 0.01' <i>[key: PPP/sigmaL1]</i></p>"));
1685 _pppWidgets._sigmaGIM->setWhatsThis(tr("<p>Enter a Sigma for GIM pseudo observations in meters.</p><p>The higher the sigma you enter, the less the contribution of GIM pseudo observations to a PPP solution. 5.0 is likely to be an appropriate choice.</p><p>Default is an empty option field, meaning<br>'Sigma GIM = 1.0' <i>[key: PPP/sigmaGIM]</i></p>"));
1686 _pppWidgets._maxResC1->setWhatsThis(tr("<p>Specify a maximum for residuals from GPS C1 code observations in a PPP solution. '2.0' meters may be an appropriate choice for that.</p><p>If the maximum is exceeded, contributions from the corresponding observation will be ignored in the PPP solution.</p><p>Default is an empty option field, meaning<br>'Max Res C1 = 3.0' <i>[key: PPP/maxResC1]</i></p>"));
1687 _pppWidgets._maxResL1->setWhatsThis(tr("<p>Specify a maximum for residuals from GPS L1 phase observations in a PPP solution. '0.02' meters may be an appropriate choice for that.</p><p>If the maximum is exceeded, contributions from the corresponding observation will be ignored in the PPP solution.</p><p>Default is an empty option field, meaning<br>'Max Res L1 = 0.03' <i>[key: PPP/maxResL1]</i></p>"));
1688 _pppWidgets._eleWgtCode->setWhatsThis(tr("<p>Tic 'Ele Wgt Code' to use satellite Elevation depending Weights for Code observations in the PPP solution. <i>[key: PPP/eleWgtCode]</i></p>"));
1689 _pppWidgets._eleWgtPhase->setWhatsThis(tr("<p>Tic 'Ele Wgt Phase' to use satellite Elevation depending Weights for Phase observations in the PPP solution. <i>[key: PPP/eleWgtPhase]</i></p>"));
1690 _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. <i>[key: PPP/minObs]</i></p>"));
1691 _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 choice in order to avoid too noisy observations. <i>[key: PPP/minEle]</i></p>"));
1692
1693 _pppWidgets._arGPS->setWhatsThis(tr("<p>Specify whether for GPS the ambiguities should be resolved to their integer values. <i>[key: PPP/arGPS]</i></p>"));
1694 _pppWidgets._arGalileo->setWhatsThis(tr("<p>Specify whether for Galileo the ambiguities should be resolved to their integer values. <i>[key: PPP/arGalileo]</i></p>"));
1695 _pppWidgets._arBDS->setWhatsThis(tr("<p>Specify whether for BDS the ambiguities should be resolved to their integer values. <i>[key: PPP/arBDS]</i></p>"));
1696 _pppWidgets._arMinNumEpo->setWhatsThis(tr("<p>Specify the number of epochs for which the unknown ambiguity parameter has to be observed at least, to be included into the search. A recommended value is 30. <i>[key: PPP/arMinNumEpo]</i></p>"));
1697 _pppWidgets._arMinNumSat->setWhatsThis(tr("<p>The ambiguity search is performed if at least the specified number of satellites per constellation is being tracked. A recommended value is 5. <i>[key: PPP/arMinNumSat]</i></p>"));
1698 _pppWidgets._arUseYaw->setWhatsThis(tr("<p>If set, the information about the satellite attitude (yaw angle) is taken from the corresponding SSR stream (phase bias message). Otherwise a standard satellite attitude model is used. <i>[key: PPP/arUseYaw]</i></p>"));
1699 _pppWidgets._arMaxFrac->setWhatsThis(tr("<p>If greater than zero, the ambiguity is constrained only if the absolute value of the fractional part of its BIE value is lower or equal than the specified value. A recommended value is 0.01. <i>[key: PPP/arMaxFrac]</i></p>"));
1700 _pppWidgets._arMaxSig->setWhatsThis(tr("<p>If greater than zero, the ambiguity is constrained only if the BIE sigma (uncertainty of the BIE result) is lower or equal than the specified value. A recommended value is 0.001. <i>[key: PPP/arMaxSig]</i></p>"));
1701
1702 // WhatsThis, Combine Corrections
1703 // ------------------------------
1704 _cmbTable->setWhatsThis(tr("<p>BNC allows to process several orbit and clock correction streams in real-time to produce, encode, upload and save a combination of correctors coming from different providers. </p><p>To add a line to the 'Combine Corrections' table hit the 'Add Row' button, double click on the 'Mountpoint' field to specify a Broadcast Ephemeris Correction 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. Double click on the 'Weight Factor' field to enter a weight factor to be applied for this stream in the combination. A Factor greater than 1 will enlarge the sigma of the clock pseudo-observations and with it down-weight its contribution. Finally, double click on the 'Exclude Satellites' field and specify satellites, to exclude them for an individual AC. An entry 'G04,G31,R' means to excludes GPS satellites PRN 4 and 31 as well as all GLONASS satellites from one individual AC. Default is an empty option field, meaning that no satellite is excluded from this individual AC.</p><p>Use the 'Attitude' field to select how satellite attitude is modelled when converting Antenna Phase Center (APC) corrections to Center-of-Mass (CoM) positions for SP3 output. 'Computed' (default) applies BNC's kinematic attitude model, including GPS noon/midnight turn manoeuvres, GLONASS yaw-fixed mode, and Galileo/BDS orbit-normal mode switching. 'Nominal' uses a simplified continuous Sun-pointing model without manoeuvre modelling. 'SSR' uses the yaw angle transmitted in the SSR phase bias message; select this option only if you trust the yaw values provided by the AC. If no yaw angle is available for a particular satellite in a given epoch, BNC falls back to 'Computed'. Note that the attitude model affects APC-referenced streams only; for CoM-referenced streams the AC has already applied attitude before encoding.</p><p>Note that the orbit information in the resulting 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 orbit and clock correction streams 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 Correction stream in the 'Combine Corrections' table. Instead of combining corrections BNC will then add the corrections to the Broadcast Ephemeris with the possibility to save final orbit and clock results in SP3 and/or Clock RINEX format. <i>[key: cmbStreams]</i></p>"));
1705 addCmbRowButton->setWhatsThis(tr("<p>Hit 'Add Row' button to add another line to the 'Combine Corrections' table.</p>"));
1706 delCmbRowButton->setWhatsThis(tr("<p>Hit 'Delete' button to delete the highlighted line(s) from the 'Combine Corrections' table.</p>"));
1707 _cmbMethodComboBox->setWhatsThis(tr("<p>Select a clock combination approach. Options are 'Single-Epoch' and Kalman 'Filter'.</p><p>It is suggested to use the Kalman filter approach for the purpose of Precise Point Positioning. <i>[key: cmbMethod]</i></p>"));
1708 _cmbMaxresLineEdit->setWhatsThis(tr("<p>BNC combines all incoming clocks according to specified weights. Individual clock estimates that differ by more than 'Maximal Clk 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'. <i>[key: cmbMaxres]</i></p>"));
1709 _cmbMaxdisplacementLineEdit->setWhatsThis(tr("<p>BNC builds mean values for all incoming orbit corrections per satellite. Individual orbit corrections that differ by more than 'Maximal Orb Displacement' meters from the average of all orbit corrections per satellite will be ignored.<p></p>It is suggested to specify a value of about 0.5 m.</p><p>Default is a value of '2.0'. <i>[key: cmbMaxdisplacement]</i></p>"));
1710 _cmbSamplComboBox->setWhatsThis(tr("<p>Select a combination Sampling interval for the clocks. Clock corrections will be produced following that interval.</p><p>A value of 10 sec may be an appropriate choice. <i>[key: cmbSampl]</i></p>"));
1711 _cmbLogPath->setWhatsThis(tr("<p>Specify a directory for saving daily Combination logfiles. If the specified directory does not exist, BNC will not create such files.</p><p>Default is an empty option field, meaning that no Combination logfiles shall be produced. <i>[key: cmbLogpath]</i></p>"));
1712 _cmbGpsCheckBox->setWhatsThis(tr("<p>GPS clock corrections shall be combined. GPS Broadcast ephemeris and corrections are required. <i>[key: cmbGps]</i></p>"));
1713 _cmbGloCheckBox->setWhatsThis(tr("<p>GLONASS clock corrections shall be combined; GLONASS Broadcast ephemeris and corrections are required. <i>[key: cmbGlo]</i></p>"));
1714 _cmbGalCheckBox->setWhatsThis(tr("<p>Galileo clock corrections shall be combined; Galileo Broadcast ephemeris and corrections are required. <i>[key: cmbGal]</i></p>"));
1715 _cmbBdsCheckBox->setWhatsThis(tr("<p>Beidou clock corrections shall be combined; BDS Broadcast ephemeris and corrections are required. <i>[key: cmbBds]</i></p>"));
1716 _cmbQzssCheckBox->setWhatsThis(tr("<p>QZSS clock corrections shall be combined; QZSS Broadcast ephemeris and corrections are required. <i>[key: cmbQzss]</i></p>"));
1717 _cmbSbasCheckBox->setWhatsThis(tr("<p>SBAS clock corrections shall be combined; SBAS Broadcast ephemeris and corrections are required. <i>[key: cmbSbas]</i></p>"));
1718 _cmbNavicCheckBox->setWhatsThis(tr("<p>NavIC clock corrections shall be combined; NavIC Broadcast ephemeris and corrections are required. <i>[key: cmbNavic]</i></p>"));
1719 _cmbBsxFile->setWhatsThis(tr("<p> Specify a Bias SINEX File that will be used to add satellite code biases to the combined clocks. <i>[key: cmbBsxFile]</i></p>"));
1720
1721 // WhatsThis, Upload Corrections
1722 // -----------------------------
1723 _uploadTable->setWhatsThis(tr("<p>BNC can upload clock and orbit corrections to Broadcast Ephemeris (Broadcast Corrections) as well as Code Biases in different SSR formats. You may have a situation where clocks, orbits and code biases 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 Host and Port</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' table.</p><p>To fill the 'Upload Corrections' table, hit the 'Add Row' button, double click on the 'Host' field to enter the IP or URL of an Ntrip Broadcaster and hit Enter. Select the Ntrip Version that shall be used for data upload. Then double click on the 'Port', 'Mountpoint' and 'Password' fields to enter the Ntrip Broadcaster IP port, the mountpoint and the stream upload password. If Ntrip Version 2 is chosen, click to the 'User' field to enter a stream upload user name. An empty 'Host' option field means that you don't want to upload corrections.</p><p>Select a target coordinate reference System (e.g. IGS20) for outgoing clock and orbit corrections.</p><p>Select a target SSR format (e.g. IGS-SSR) 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 generated Broadcast Corrections plus Broadcast Ephemeris as SP3 orbit files. If the specified directory does not exist, BNC will not create such files. The following is a path example for a Linux system: /home/user/BKG0MGXRTS${V3PROD}.SP3.</p><p>Specify a path for saving 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: /home/user/BKG0MGXRTS${V3PROD}.CLK.</p><p>Specify a path for saving generated Code Biases as SINEX Bias files. If the specified directory does not exist, BNC will not create SINEX Bias files. The following is a path example for a Linux system: /home/user/BKG0MGXRTS${V3PROD}.BIA.</p><p>Note that '${V3PROD}' produces the time stamp in the filename, which is related to the RINEX version 3 filename concept.</p><p>Finally, specify a SSR Provider ID (issued by RTCM), SSR Solution ID, and SSR Issue of Data number.</p><p>In case the 'Combine Corrections' table contains only one Broadcast Correction stream, BNC will add that stream content to the Broadcast Ephemeris to save results in files specified via SP3 and/or Clock RINEX file path. You should then define only the SP3 and Clock RINEX file path and no further option in the 'Upload Corrections' table. <i>[key: uploadMountpointsOut]</i></p>"));
1724 addUploadRowButton->setWhatsThis(tr("<p>Hit 'Add Row' button to add another line to the 'Upload Corrections' table.</p>"));
1725 delUploadRowButton->setWhatsThis(tr("<p>Hit 'Del Row' button to delete the highlighted line(s) from the 'Upload Corrections' table.</p>"));
1726 _uploadIntrComboBox->setWhatsThis(tr("<p>Select the length of the SP3, Clock RINEX and Bias SINEX files. <i>[key: uploadIntr]</i></p>"));
1727 _uploadSamplRtcmEphCorrComboBox->setWhatsThis(tr("<p>Select a stream's orbit correction sampling interval in seconds.</p><p>A value of zero '0' tells BNC to upload all available orbit and clock correction samples together in combined messages. <i>[key: uploadSamplRtcmEphCorr]</i></p>"));
1728 _uploadSamplSp3ComboBox->setWhatsThis(tr("<p>Select a SP3 orbit file sampling interval in seconds.</p><p>A value of zero '0' tells BNC to store all available samples into SP3 orbit files. <i>[key: uploadSamplSp3]</i></p>"));
1729 _uploadSamplClkRnxSpinBox->setWhatsThis(tr("<p>Select a Clock RINEX file sampling interval in seconds.</p><p>A value of zero '0' tells BNC to store all available samples into Clock RINEX files. <i>[key: uploadSamplClkRnx]</i></p>"));
1730 _uploadSamplBiaSnxSpinBox->setWhatsThis(tr("<p>Select a Bias SINEX file sampling interval in seconds.</p><p>A value of zero '0' tells BNC to store all available samples into Bias SINEX files. <i>[key: uploadSamplBiaSnx]</i></p>"));
1731 setUploadTrafoButton->setWhatsThis(tr("<p>Hit 'Custom Trafo' to specify your own 14 parameter Helmert Transformation instead of selecting a predefined transformation via option 'System'.</p>"));
1732 _uploadAntexFile->setWhatsThis(tr("<p>When producing SP3 files or referring orbit and clock corrections to the satellite's Center of Mass (CoM) instead Antenna Phase Center (APC), an offset has to be applied which is available from the IGS 'ANTEX file'. You must therefore specify an 'ANTEX file' path if you want to save the stream content in SP3 format and/or refer correctors to CoM.</p><p>If you don't specify an 'ANTEX file' path, the SP3 file content as well as the orbit and clock correctors will be referred to satellite APCs. <i>[key: uploadAntexFile]</i></p>"));
1733
1734 // WhatsThis, Upload Ephemeris
1735 // ---------------------------
1736 _uploadEphTable->setWhatsThis(tr("<p>BNC can upload Broadcast Ephemeris streams in RTCM Version 3 format. </p><p>To fill the 'Upload Ephemeris' table, hit the 'Add Row' button, double click on the 'Host' field to enter the IP or URL of an Ntrip Broadcaster and hit Enter. Select the Ntrip Version that shall be used for data upload. Then double click on the 'Port', 'Mountpoint' and 'Password' fields to enter the Ntrip Broadcaster IP port, the mountpoint and the stream upload password. If Ntrip Version 2 is chosen, click to the 'User' field to enter a stream upload user name. Specify the satellite system(s) that shall be part of the uploaded stream (e.g. G for GPS or GRE for GPS+GLONASS+Galileo, or ALL). <i>[key: uploadEphMountpointsOut]</i></p>"));
1737 addUploadEphRowButton->setWhatsThis(tr("<p>Hit 'Add Row' button to add another line to the 'Upload Ephemeris' table.</p>"));
1738 delUploadEphRowButton->setWhatsThis(tr("<p>Hit 'Del Row' button to delete the highlighted line(s) from the 'Upload Ephemeris' table.</p>"));
1739 _uploadSamplRtcmEphSpinBox->setWhatsThis(tr("<p>Select the Broadcast Ephemeris sampling interval in seconds.</p><p>Default is '5', meaning that a complete set of Broadcast Ephemeris is uploaded every 5 seconds. <i>[key: uploadSamplRtcmEph]</i></p>"));
1740
1741 // WhatsThis, Upload Raw Data
1742 // ---------------------------
1743 _uploadRawTable->setWhatsThis(tr("<p>BNC can upload Raw Data streams in any format like a NtripServer. </p><p>To fill the 'Upload Raw Data' table, hit the 'Add Row' button and double click on the 'Source Mountpoint' field to enter the Source of data from the 'Streams' section below, which shall be forwarded without decoding and hit Enter. Double click on the 'Host' field to enter the IP or URL of an Ntrip Broadcaster and hit Enter. Select the Ntrip Version that shall be used for data upload. Then double click on the 'Port', 'Upload Mountpoint' and 'Password' fields to enter the Ntrip Broadcaster IP port, the stream upload mountpoint and password. If Ntrip Version 2 is chosen, click to the 'User' field to enter a stream upload user name. </p><p> If the decoder string is not an accepted one ('RTCM_2.x', 'RTCM_3.x' and 'RTNET'), please change the decoder string to <ul>"
1744 "<li> 'ZERO' (forward the raw data) or </li>"
1745 "<li> 'ZERO2FILE' (forward and store the raw data)</li> </ul> in addition <i>[key: uploadRawMountpointsOut]</i></p>"));
1746 addUploadEphRowButton->setWhatsThis(tr("<p>Hit 'Add Row' button to add another line to the 'Upload Raw Data' table.</p>"));
1747 delUploadEphRowButton->setWhatsThis(tr("<p>Hit 'Del Row' button to delete the highlighted line(s) from the 'Upload Raw Data' table.</p>"));
1748
1749
1750 // WhatsThis, Streams Canvas
1751 // -------------------------
1752 _mountPointsTable->setWhatsThis(tr("<p>Streams selected for retrieval are listed in the 'Streams' section. "
1753 "Clicking on 'Add Stream' button opens a window that allows the user to select data streams from an Ntrip Broadcaster "
1754 "according to their mountpoints. To remove a stream from the 'Streams' list, highlight it by clicking on it "
1755 "and hit the 'Delete Stream' button. You can also remove multiple streams by highlighting them using +Shift and +Ctrl.</p><p>"
1756 "BNC automatically allocates one of its internal decoders to a stream based on the stream's 'format' as given in the source-table. "
1757 "BNC allows users to change this selection by editing the decoder string. "
1758 "Double click on the 'decoder' field, enter your preferred decoder and then hit Enter. "
1759 "Accepted decoder strings are 'RTCM_2.x', 'RTCM_3.x' and 'RTNET'.</p><p>"
1760 "In case you need to log raw data as is, BNC allows to by-pass its decoders and directly save the input in daily log files. "
1761 "To do this, specify the decoder string as 'ZERO2FILE'.</p><p>"
1762 "BNC allows as well to forward streams related to the specified 'Mountpoint' on top of the 'Miscellaneous Panel' "
1763 "through a TCP/IP port of your local host. "
1764 "In this case, the stream content remains untouched; BNC does not decode or reformat the data for this output. "
1765 "If the decoder string is not an accepted one, please change the decoder string to 'ZERO' (forward the raw data only) or 'ZERO2FILE' (forward and store the raw data) in addition.</p><p>"
1766 "BNC can also retrieve streams from virtual reference stations (VRS). VRS streams are indicated by a 'yes' in the 'nmea' column. "
1767 "To initiate such stream, the approximate latitude/longitude rover position is sent to the Ntrip Broadcaster "
1768 "together with an approximation for the height. Default values for latitude and longitude can be change according to your requirement. "
1769 "Double click on 'lat' and 'long' fields, enter the values you wish to send and then hit Enter. <i>[key: mountPoints]</i></p>"));
1770 _actAddMountPoints->setWhatsThis(tr("<p>Add stream(s) to selection presented in the 'Streams' canvas.</p>"));
1771 _actDeleteMountPoints->setWhatsThis(tr("<p>Delete stream(s) from selection presented in the 'Streams' canvas.</p>"));
1772 _actMapMountPoints->setWhatsThis(tr("<p> Draw distribution map of stream selection presented in the 'Streams' canvas. Use 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>"));
1773 _actStart->setWhatsThis(tr("<p> Start running BNC.</p>"));
1774 _actStop->setWhatsThis(tr("<p> Stop running BNC.</p>"));
1775
1776 // WhatsThis, Log Canvas
1777 // ---------------------
1778 _log->setWhatsThis(tr("<p>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 problems that occur in the communication link, stream availability, stream delay, stream conversion etc.</p>"));
1779 _bncFigure->setWhatsThis(tr("<p>The bandwith consumption per stream is shown in the 'Throughput' tab in bits per second (bps) or kilobits per second (kbps).</p>"));
1780 _bncFigureLate->setWhatsThis(tr("<p>The individual latency of observations of incoming streams is shown in the 'Latency' tab. Streams not carrying observations (e.g. those providing only Broadcast Ephemeris) remain unconsidered.</p><p>Note that the calculation of correct latencies requires the clock of the host computer to be properly synchronized.</p>"));
1781 _bncFigurePPP->setWhatsThis(tr("<p>PPP time series of North (red), East (green) and Up (blue) displacements are shown in the 'PPP Plot' tab when the corresponding option is selected.</p><p>Values are referred to an XYZ a priori coordinate. The sliding PPP time series window covers the period of the latest 5 minutes.</p>"));
1782
1783
1784 // Enable/Disable all Widgets
1785 // --------------------------
1786 slotBncTextChanged();
1787 enableStartStop();
1788
1789 // Auto start
1790 // ----------
1791 if (Qt::CheckState(settings.value("autoStart").toInt()) == Qt::Checked) {
1792 slotStart();
1793 }
1794}
1795
1796// Destructor
1797////////////////////////////////////////////////////////////////////////////
1798bncWindow::~bncWindow() {
1799 if (_caster) {
1800 delete _caster; BNC_CORE->setCaster(0);
1801 }
1802 if (_casterEph) {
1803 delete _casterEph;
1804 }
1805 delete _bncFigureLate;
1806 delete _bncFigurePPP;
1807 delete _actHelp;
1808 delete _actAbout;
1809 delete _actFlowchart;
1810 delete _actFontSel;
1811 delete _actSaveOpt;
1812 delete _actQuit;
1813 delete _actAddMountPoints;
1814 delete _actDeleteMountPoints;
1815 delete _actMapMountPoints;
1816 delete _actStart;
1817 delete _actStop;
1818 delete _actwhatsthis;
1819 delete _proxyHostLineEdit;
1820 delete _proxyPortLineEdit;
1821 delete _sslCaCertPathLineEdit;
1822 delete _sslClientCertPathLineEdit;
1823 delete _sslIgnoreErrorsCheckBox;
1824 delete _logFileLineEdit;
1825 delete _rawOutFileLineEdit;
1826 delete _rnxAppendCheckBox;
1827 delete _onTheFlyComboBox;
1828 delete _autoStartCheckBox;
1829 delete _rnxPathLineEdit;
1830 delete _rnxIntrComboBox;
1831 delete _rnxSamplComboBox;
1832 delete _rnxSkelExtComboBox;
1833 delete _rnxSkelPathLineEdit;
1834 delete _rnxFileCheckBox;
1835 delete _rnxScrpLineEdit;
1836 delete _rnxVersComboBox;
1837 delete _rnxV2Priority;
1838 delete _ephPathLineEdit;
1839 //delete _ephFilePerStation;
1840 delete _ephIntrComboBox;
1841 delete _ephOutPortLineEdit;
1842 delete _ephVersComboBox;
1843 delete _corrPathLineEdit;
1844 delete _corrIntrComboBox;
1845 delete _corrPortLineEdit;
1846 delete _outPortLineEdit;
1847 delete _outWaitSpinBox;
1848 delete _outSamplComboBox;
1849 delete _outFileLineEdit;
1850 delete _outUPortLineEdit;
1851 delete _outLockTimeCheckBox;
1852 delete _serialMountPointLineEdit;
1853 delete _serialPortNameLineEdit;
1854 delete _serialBaudRateComboBox;
1855 delete _serialFlowControlComboBox;
1856 delete _serialDataBitsComboBox;
1857 delete _serialParityComboBox;
1858 delete _serialStopBitsComboBox;
1859 delete _serialAutoNMEAComboBox;
1860 delete _serialFileNMEALineEdit;
1861 delete _serialHeightNMEALineEdit;
1862 delete _serialNMEASamplingSpinBox;
1863 delete _adviseObsRateComboBox;
1864 delete _adviseFailSpinBox;
1865 delete _adviseRecoSpinBox;
1866 delete _adviseScriptLineEdit;
1867 delete _miscMountLineEdit;
1868 delete _miscPortLineEdit;
1869 delete _miscIntrComboBox;
1870 delete _miscScanRTCMCheckBox;
1871 _mountPointsTable->deleteLater();
1872 delete _log;
1873 delete _loggroup;
1874 _cmbTable->deleteLater();
1875 delete _cmbMaxresLineEdit;
1876 delete _cmbMaxdisplacementLineEdit;
1877 delete _cmbSamplComboBox;
1878 delete _cmbLogPath;
1879 delete _cmbMethodComboBox;
1880 delete _cmbGpsCheckBox;
1881 delete _cmbGloCheckBox;
1882 delete _cmbGalCheckBox;
1883 delete _cmbBdsCheckBox;
1884 delete _cmbQzssCheckBox;
1885 delete _cmbSbasCheckBox;
1886 delete _cmbNavicCheckBox;
1887 delete _cmbBsxFile;
1888 delete _uploadSamplRtcmEphCorrComboBox;
1889 _uploadEphTable->deleteLater();
1890 _uploadRawTable->deleteLater();
1891 _uploadTable->deleteLater();
1892 delete _uploadIntrComboBox;
1893 delete _uploadAntexFile;
1894 delete _uploadSamplRtcmEphSpinBox;
1895 delete _uploadSamplSp3ComboBox;
1896 delete _uploadSamplClkRnxSpinBox;
1897 delete _uploadSamplBiaSnxSpinBox;
1898 delete _reqcActionComboBox;
1899 delete _reqcObsFileChooser;
1900 delete _reqcNavFileChooser;
1901 delete _reqcOutObsLineEdit;
1902 delete _reqcOutNavLineEdit;
1903 delete _reqcOutLogLineEdit;
1904 delete _reqcPlotDirLineEdit;
1905 delete _reqcSkyPlotSignals;
1906 delete _reqcLogSummaryOnly;
1907 delete _reqcMinEle;
1908 delete _reqcEditOptionButton;
1909 delete _sp3CompFileChooser;
1910 delete _sp3CompExclude;
1911 delete _sp3CompLogLineEdit;
1912 delete _sp3CompSummaryOnly;
1913 //delete _canvas;
1914}
1915
1916//
1917////////////////////////////////////////////////////////////////////////////
1918void bncWindow::populateMountPointsTable() {
1919
1920 for (int iRow = _mountPointsTable->rowCount() - 1; iRow >= 0; iRow--) {
1921 _mountPointsTable->removeRow(iRow);
1922 }
1923
1924 bncSettings settings;
1925
1926 QListIterator<QString> it(settings.value("mountPoints").toStringList());
1927 int iRow = 0;
1928 while (it.hasNext()) {
1929 QStringList hlp = it.next().split(" ");
1930 if (hlp.size() < 7) continue;
1931 _mountPointsTable->insertRow(iRow);
1932
1933 QUrl url(hlp[0]);
1934
1935 QString format(hlp[1]);
1936 QString country(hlp[2]);
1937 QString latitude(hlp[3]);
1938 QString longitude(hlp[4]);
1939 QString nmea(hlp[5]);
1940 QString ntripVersion(hlp[6]);
1941
1942 QString fullPath;
1943 if (ntripVersion == 'S') {
1944 // url.userInfo() contains the case sensitive portName
1945 // the portName shall be part of the mountpointString
1946 // to inform the user about the source of the stream
1947 if (url.host().contains(url.userInfo().toLower())) {
1948 fullPath = url.host() + url.path();
1949 }
1950 else {
1951 fullPath = url.userInfo() + "-" + url.host() + url.path();
1952 }
1953 } else {
1954 fullPath = url.host() + QString(":%1").arg(url.port()) + url.path();
1955 }
1956
1957 QTableWidgetItem* it;
1958 it = new QTableWidgetItem(url.userInfo());
1959 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
1960 _mountPointsTable->setItem(iRow, 0, it);
1961
1962 it = new QTableWidgetItem(fullPath);
1963 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
1964 _mountPointsTable->setItem(iRow, 1, it);
1965
1966 it = new QTableWidgetItem(format);
1967 _mountPointsTable->setItem(iRow, 2, it);
1968
1969 it = new QTableWidgetItem(country);
1970 _mountPointsTable->setItem(iRow, 3, it);
1971
1972 if (nmea == "yes") {
1973 it = new QTableWidgetItem(latitude);
1974 _mountPointsTable->setItem(iRow, 4, it);
1975 it = new QTableWidgetItem(longitude);
1976 _mountPointsTable->setItem(iRow, 5, it);
1977 }
1978 else {
1979 it = new QTableWidgetItem(latitude);
1980 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
1981 _mountPointsTable->setItem(iRow, 4, it);
1982
1983 it = new QTableWidgetItem(longitude);
1984 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
1985 _mountPointsTable->setItem(iRow, 5, it);
1986 }
1987
1988 it = new QTableWidgetItem(nmea);
1989 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
1990 _mountPointsTable->setItem(iRow, 6, it);
1991
1992 it = new QTableWidgetItem(ntripVersion);
1993 //// it->setFlags(it->flags() & ~Qt::ItemIsEditable);
1994 _mountPointsTable->setItem(iRow, 7, it);
1995
1996 bncTableItem* bncIt = new bncTableItem();
1997 bncIt->setFlags(bncIt->flags() & ~Qt::ItemIsEditable);
1998 _mountPointsTable->setItem(iRow, 8, bncIt);
1999
2000 iRow++;
2001 }
2002
2003 _mountPointsTable->sortItems(1);
2004
2005 enableStartStop();
2006}
2007
2008// Retrieve Table
2009////////////////////////////////////////////////////////////////////////////
2010void bncWindow::slotAddMountPoints() {
2011
2012 bncSettings settings;
2013 QString proxyHost = settings.value("proxyHost").toString();
2014 int proxyPort = settings.value("proxyPort").toInt();
2015 if (proxyHost != _proxyHostLineEdit->text() ||
2016 proxyPort != _proxyPortLineEdit->text().toInt()) {
2017 int iRet = QMessageBox::question(this, "Question", "Proxy options "
2018 "changed. Use the new ones?",
2019 QMessageBox::Yes, QMessageBox::No,
2020 QMessageBox::NoButton);
2021 if (iRet == QMessageBox::Yes) {
2022 settings.setValue("proxyHost", _proxyHostLineEdit->text());
2023 settings.setValue("proxyPort", _proxyPortLineEdit->text());
2024 }
2025 }
2026
2027 settings.setValue("sslCaCertPath", _sslCaCertPathLineEdit->text());
2028 settings.setValue("sslClientCertPath", _sslClientCertPathLineEdit->text());
2029 settings.setValue("sslIgnoreErrors", _sslIgnoreErrorsCheckBox->checkState());
2030
2031 QMessageBox msgBox;
2032 msgBox.setIcon(QMessageBox::Question);
2033 msgBox.setWindowTitle("Add Stream");
2034 msgBox.setText("Add stream(s) coming from:");
2035
2036 QPushButton* buttonNtrip = msgBox.addButton(tr("Caster"), QMessageBox::ActionRole);
2037 QPushButton* buttonIP = msgBox.addButton(tr("TCP/IP port"), QMessageBox::ActionRole);
2038 QPushButton* buttonUDP = msgBox.addButton(tr("UDP port"), QMessageBox::ActionRole);
2039 QPushButton* buttonSerial = msgBox.addButton(tr("Serial port"), QMessageBox::ActionRole);
2040 QPushButton* buttonCancel = msgBox.addButton(tr("Cancel"), QMessageBox::ActionRole);
2041
2042 msgBox.exec();
2043
2044 if (msgBox.clickedButton() == buttonNtrip) {
2045 bncTableDlg* dlg = new bncTableDlg(this);
2046 dlg->move(this->pos().x() + 50, this->pos().y() + 50);
2047 connect(dlg, SIGNAL(newMountPoints(QStringList*)),
2048 this, SLOT(slotNewMountPoints(QStringList*)));
2049 dlg->exec();
2050 delete dlg;
2051 }
2052 else if (msgBox.clickedButton() == buttonIP) {
2053 bncIpPort* ipp = new bncIpPort(this);
2054 connect(ipp, SIGNAL(newMountPoints(QStringList*)),
2055 this, SLOT(slotNewMountPoints(QStringList*)));
2056 ipp->exec();
2057 delete ipp;
2058 }
2059 else if (msgBox.clickedButton() == buttonUDP) {
2060 bncUdpPort* udp = new bncUdpPort(this);
2061 connect(udp, SIGNAL(newMountPoints(QStringList*)),
2062 this, SLOT(slotNewMountPoints(QStringList*)));
2063 udp->exec();
2064 delete udp;
2065 }
2066 else if (msgBox.clickedButton() == buttonSerial) {
2067 bncSerialPort* sep = new bncSerialPort(this);
2068 connect(sep, SIGNAL(newMountPoints(QStringList*)),
2069 this, SLOT(slotNewMountPoints(QStringList*)));
2070 sep->exec();
2071 delete sep;
2072 }
2073 else if (msgBox.clickedButton() == buttonCancel) {
2074 // Cancel
2075 }
2076
2077 enableStartStop();
2078}
2079
2080// Delete Selected Mount Points
2081////////////////////////////////////////////////////////////////////////////
2082void bncWindow::slotDeleteMountPoints() {
2083
2084 int nRows = _mountPointsTable->rowCount();
2085 std::vector <bool> flg(nRows);
2086 for (int iRow = 0; iRow < nRows; iRow++) {
2087 if (_mountPointsTable->item(iRow, 1)->isSelected()) {
2088 flg[iRow] = true;
2089 }
2090 else {
2091 flg[iRow] = false;
2092 }
2093 }
2094 for (int iRow = nRows - 1; iRow >= 0; iRow--) {
2095 if (flg[iRow]) {
2096 _mountPointsTable->removeRow(iRow);
2097 }
2098 }
2099 _actDeleteMountPoints->setEnabled(false);
2100
2101 enableStartStop();
2102}
2103
2104// New Mount Points Selected
2105////////////////////////////////////////////////////////////////////////////
2106void bncWindow::slotNewMountPoints(QStringList* mountPoints) {
2107 int iRow = 0;
2108 QListIterator<QString> it(*mountPoints);
2109 while (it.hasNext()) {
2110 QStringList hlp = it.next().split(" ");
2111
2112 QUrl url(hlp[0]);
2113
2114 QString format(hlp[1]);
2115 QString country(hlp[2]);
2116 QString latitude(hlp[3]);
2117 QString longitude(hlp[4]);
2118 QString nmea(hlp[5]);
2119 QString ntripVersion(hlp[6]);
2120
2121 QString fullPath;
2122 if (ntripVersion == 'S') {
2123 // url.userInfo() contains the case sensitive portName
2124 // the portName shall be part of the mountpointString
2125 // to inform the user about the source of the stream
2126 if (url.host().contains(url.userInfo().toLower())) {
2127 fullPath = url.host() + url.path();
2128 }
2129 else {
2130 fullPath = url.userInfo() + "-" + url.host() + url.path();
2131 }
2132 } else {
2133 fullPath = url.host() + QString(":%1").arg(url.port()) + url.path();
2134 }
2135
2136 _mountPointsTable->insertRow(iRow);
2137
2138 QTableWidgetItem* it;
2139 it = new QTableWidgetItem(url.userInfo());
2140 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
2141 _mountPointsTable->setItem(iRow, 0, it);
2142
2143 it = new QTableWidgetItem(fullPath);
2144 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
2145 _mountPointsTable->setItem(iRow, 1, it);
2146
2147 it = new QTableWidgetItem(format);
2148 _mountPointsTable->setItem(iRow, 2, it);
2149
2150 it = new QTableWidgetItem(country);
2151 _mountPointsTable->setItem(iRow, 3, it);
2152
2153 if (nmea == "yes") {
2154 it = new QTableWidgetItem(latitude);
2155 _mountPointsTable->setItem(iRow, 4, it);
2156 it = new QTableWidgetItem(longitude);
2157 _mountPointsTable->setItem(iRow, 5, it);
2158 }
2159 else {
2160 it = new QTableWidgetItem(latitude);
2161 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
2162 _mountPointsTable->setItem(iRow, 4, it);
2163 it = new QTableWidgetItem(longitude);
2164 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
2165 _mountPointsTable->setItem(iRow, 5, it);
2166 }
2167
2168 it = new QTableWidgetItem(nmea);
2169 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
2170 _mountPointsTable->setItem(iRow, 6, it);
2171
2172 it = new QTableWidgetItem(ntripVersion);
2173 //// it->setFlags(it->flags() & ~Qt::ItemIsEditable);
2174 _mountPointsTable->setItem(iRow, 7, it);
2175
2176 bncTableItem* bncIt = new bncTableItem();
2177 _mountPointsTable->setItem(iRow, 8, bncIt);
2178
2179 iRow++;
2180 }
2181 _mountPointsTable->hideColumn(0);
2182 _mountPointsTable->hideColumn(3);
2183 _mountPointsTable->sortItems(1);
2184 delete mountPoints;
2185
2186 enableStartStop();
2187}
2188
2189// Save Options (serialize)
2190////////////////////////////////////////////////////////////////////////////
2191void bncWindow::slotSaveOptions() {
2192 saveOptions();
2193 bncSettings settings;
2194 settings.sync();
2195}
2196
2197// Save Options (memory only)
2198////////////////////////////////////////////////////////////////////////////
2199void bncWindow::saveOptions() {
2200
2201 QStringList mountPoints;
2202 for (int iRow = 0; iRow < _mountPointsTable->rowCount(); iRow++) {
2203
2204 QUrl url("//"
2205 + _mountPointsTable->item(iRow, 0)->text() + "@"
2206 + _mountPointsTable->item(iRow, 1)->text());
2207
2208 mountPoints.append(url.toString()
2209 + " " + _mountPointsTable->item(iRow, 2)->text()
2210 + " " + _mountPointsTable->item(iRow, 3)->text()
2211 + " " + _mountPointsTable->item(iRow, 4)->text()
2212 + " " + _mountPointsTable->item(iRow, 5)->text()
2213 + " " + _mountPointsTable->item(iRow, 6)->text()
2214 + " " + _mountPointsTable->item(iRow, 7)->text());
2215 }
2216
2217 QStringList cmbStreams;
2218 for (int iRow = 0; iRow < _cmbTable->rowCount(); iRow++) {
2219 QString hlp;
2220 for (int iCol = 0; iCol < _cmbTable->columnCount(); iCol++) {
2221 if (iCol == 4) {
2222 QComboBox* attCombo = qobject_cast<QComboBox*>(_cmbTable->cellWidget(iRow, iCol));
2223 hlp += (attCombo ? attCombo->currentText() : "Computed") + " ";
2224 }
2225 else if (_cmbTable->item(iRow, iCol)) {
2226 hlp += _cmbTable->item(iRow, iCol)->text() + " ";
2227 }
2228 }
2229 if (!hlp.isEmpty()) {
2230 cmbStreams << hlp;
2231 }
2232 }
2233
2234 QStringList uploadMountpointsOut;
2235 for (int iRow = 0; iRow < _uploadTable->rowCount(); iRow++) {
2236 QString hlp;
2237 for (int iCol = 0; iCol < _uploadTable->columnCount(); iCol++) {
2238 if (_uploadTable->cellWidget(iRow, iCol) &&
2239 (iCol == 3 || iCol == 4 || iCol == 5 || iCol == 6 || iCol == 7 || iCol == 8)) {
2240 if (iCol == 3) {
2241 QComboBox* ntripversion = (QComboBox*)(_uploadTable->cellWidget(iRow, iCol));
2242 hlp += ntripversion->currentText() + ",";
2243 }
2244 else if (iCol == 4) {
2245 QLineEdit* user = (QLineEdit*)(_uploadTable->cellWidget(iRow, iCol));
2246 hlp += user->text() + ",";
2247 }
2248 else if (iCol == 5) {
2249 QLineEdit* passwd = (QLineEdit*)(_uploadTable->cellWidget(iRow, iCol));
2250 hlp += passwd->text() + ",";
2251 }
2252 else if (iCol == 6) {
2253 QComboBox* system = (QComboBox*)(_uploadTable->cellWidget(iRow, iCol));
2254 hlp += system->currentText() + ",";
2255 }
2256 else if (iCol == 7) {
2257 QComboBox* format = (QComboBox*)(_uploadTable->cellWidget(iRow, iCol));
2258 hlp += format->currentText() + ",";
2259 }
2260 else if (iCol == 8) {
2261 QCheckBox* com = (QCheckBox*)(_uploadTable->cellWidget(iRow, iCol));
2262 QString state; state.setNum(com->checkState());
2263 hlp += state + ",";
2264 }
2265 }
2266 else if (_uploadTable->item(iRow, iCol)) {
2267 hlp += _uploadTable->item(iRow, iCol)->text() + ",";
2268 }
2269 }
2270 if (!hlp.isEmpty()) {
2271 uploadMountpointsOut << hlp;
2272 }
2273 }
2274
2275 QStringList uploadEphMountpointsOut;
2276 for (int iRow = 0; iRow < _uploadEphTable->rowCount(); iRow++) {
2277 QString hlp;
2278 for (int iCol = 0; iCol < _uploadEphTable->columnCount(); iCol++) {
2279 if (_uploadEphTable->cellWidget(iRow, iCol) &&
2280 (iCol == 3 || iCol == 4 || iCol == 5 || iCol == 6)) {
2281 if (iCol == 3) {
2282 QComboBox* ntripversion = (QComboBox*)(_uploadEphTable->cellWidget(iRow, iCol));
2283 hlp += ntripversion->currentText() + ",";
2284 }
2285 else if (iCol == 4) {
2286 QLineEdit* user = (QLineEdit*)(_uploadEphTable->cellWidget(iRow, iCol));
2287 hlp += user->text() + ",";
2288 }
2289 else if (iCol == 5) {
2290 QLineEdit* passwd = (QLineEdit*)(_uploadEphTable->cellWidget(iRow, iCol));
2291 hlp += passwd->text() + ",";
2292 }
2293 else if (iCol == 6) {
2294 QLineEdit* system = (QLineEdit*)(_uploadEphTable->cellWidget(iRow, iCol));
2295 hlp += system->text() + ",";
2296 }
2297 }
2298 else if (_uploadEphTable->item(iRow, iCol)) {
2299 hlp += _uploadEphTable->item(iRow, iCol)->text() + ",";
2300 }
2301 }
2302 if (!hlp.isEmpty()) {
2303 uploadEphMountpointsOut << hlp;
2304 }
2305 }
2306
2307 QStringList uploadRawMountpointsOut;
2308 for (int iRow = 0; iRow < _uploadRawTable->rowCount(); iRow++) {
2309 QString hlp;
2310 for (int iCol = 0; iCol < _uploadRawTable->columnCount(); iCol++) {
2311 if (_uploadRawTable->cellWidget(iRow, iCol) &&
2312 (iCol == 4 || iCol == 5 || iCol == 6)) {
2313 if (iCol == 4) {
2314 QComboBox* ntripversion = (QComboBox*)(_uploadRawTable->cellWidget(iRow, iCol));
2315 hlp += ntripversion->currentText() + ",";
2316 }
2317 else if (iCol == 5) {
2318 QLineEdit* user = (QLineEdit*)(_uploadRawTable->cellWidget(iRow, iCol));
2319 hlp += user->text() + ",";
2320 }
2321 else if (iCol == 6) {
2322 QLineEdit* passwd = (QLineEdit*)(_uploadRawTable->cellWidget(iRow, iCol));
2323 hlp += passwd->text() + ",";
2324 }
2325 }
2326 else if (_uploadRawTable->item(iRow, iCol)) {
2327 hlp += _uploadRawTable->item(iRow, iCol)->text() + ",";
2328 }
2329 }
2330 if (!hlp.isEmpty()) {
2331 uploadRawMountpointsOut << hlp;
2332 }
2333 }
2334
2335 bncSettings settings;
2336
2337 settings.setValue("startTab", _aogroup->currentIndex());
2338 settings.setValue("statusTab", _loggroup->currentIndex());
2339 settings.setValue("mountPoints", mountPoints);
2340 // Network
2341 settings.setValue("proxyHost", _proxyHostLineEdit->text());
2342 settings.setValue("proxyPort", _proxyPortLineEdit->text());
2343 settings.setValue("sslCaCertPath", _sslCaCertPathLineEdit->text());
2344 settings.setValue("sslClientCertPath", _sslClientCertPathLineEdit->text());
2345 settings.setValue("sslIgnoreErrors", _sslIgnoreErrorsCheckBox->checkState());
2346 // General
2347 settings.setValue("logFile", _logFileLineEdit->text());
2348 settings.setValue("rnxAppend", _rnxAppendCheckBox->checkState());
2349 settings.setValue("onTheFlyInterval", _onTheFlyComboBox->currentText());
2350 settings.setValue("autoStart", _autoStartCheckBox->checkState());
2351 settings.setValue("rawOutFile", _rawOutFileLineEdit->text());
2352 // RINEX Observations
2353 settings.setValue("rnxPath", _rnxPathLineEdit->text());
2354 settings.setValue("rnxIntr", _rnxIntrComboBox->currentText());
2355 settings.setValue("rnxSampl", _rnxSamplComboBox->currentText());
2356 settings.setValue("rnxSkel", _rnxSkelExtComboBox->currentText());
2357 settings.setValue("rnxSkelPath", _rnxSkelPathLineEdit->text());
2358 settings.setValue("rnxOnlyWithSKL", _rnxFileCheckBox->checkState());
2359 settings.setValue("rnxScript", _rnxScrpLineEdit->text());
2360 settings.setValue("rnxV2Priority", _rnxV2Priority->text());
2361 settings.setValue("rnxVersion", _rnxVersComboBox->currentText());
2362 // RINEX Ephemeris
2363 settings.setValue("ephPath", _ephPathLineEdit->text());
2364 settings.setValue("ephIntr", _ephIntrComboBox->currentText());
2365 settings.setValue("ephOutPort", _ephOutPortLineEdit->text());
2366 settings.setValue("ephVersion", _ephVersComboBox->currentText());
2367 //settings.setValue("ephFilePerStation", _ephFilePerStation->checkState());
2368 // Broadcast Corrections
2369 settings.setValue("corrPath", _corrPathLineEdit->text());
2370 settings.setValue("corrIntr", _corrIntrComboBox->currentText());
2371 settings.setValue("corrPort", _corrPortLineEdit->text());
2372 // Feed Engine
2373 settings.setValue("outPort", _outPortLineEdit->text());
2374 settings.setValue("outWait", _outWaitSpinBox->value());
2375 settings.setValue("outSampl", _outSamplComboBox->currentText());
2376 settings.setValue("outFile", _outFileLineEdit->text());
2377 settings.setValue("outLockTime", _outLockTimeCheckBox->checkState());
2378 settings.setValue("outUPort", _outUPortLineEdit->text());
2379 // Serial Output
2380 settings.setValue("serialMountPoint", _serialMountPointLineEdit->text());
2381 settings.setValue("serialPortName", _serialPortNameLineEdit->text());
2382 settings.setValue("serialBaudRate", _serialBaudRateComboBox->currentText());
2383 settings.setValue("serialFlowControl", _serialFlowControlComboBox->currentText());
2384 settings.setValue("serialDataBits", _serialDataBitsComboBox->currentText());
2385 settings.setValue("serialParity", _serialParityComboBox->currentText());
2386 settings.setValue("serialStopBits", _serialStopBitsComboBox->currentText());
2387 settings.setValue("serialAutoNMEA", _serialAutoNMEAComboBox->currentText());
2388 settings.setValue("serialFileNMEA", _serialFileNMEALineEdit->text());
2389 settings.setValue("serialHeightNMEA", _serialHeightNMEALineEdit->text());
2390 settings.setValue("serialNMEASampling", _serialNMEASamplingSpinBox->value());
2391 // Outages
2392 settings.setValue("adviseObsRate", _adviseObsRateComboBox->currentText());
2393 settings.setValue("adviseFail", _adviseFailSpinBox->value());
2394 settings.setValue("adviseReco", _adviseRecoSpinBox->value());
2395 settings.setValue("adviseScript", _adviseScriptLineEdit->text());
2396 // Miscellaneous
2397 settings.setValue("miscMount", _miscMountLineEdit->text());
2398 settings.setValue("miscPort", _miscPortLineEdit->text());
2399 settings.setValue("miscIntr", _miscIntrComboBox->currentText());
2400 settings.setValue("miscScanRTCM", _miscScanRTCMCheckBox->checkState());
2401 // Reqc
2402 settings.setValue("reqcAction", _reqcActionComboBox->currentText());
2403 settings.setValue("reqcObsFile", _reqcObsFileChooser->fileName());
2404 settings.setValue("reqcNavFile", _reqcNavFileChooser->fileName());
2405 settings.setValue("reqcOutObsFile", _reqcOutObsLineEdit->text());
2406 settings.setValue("reqcOutNavFile", _reqcOutNavLineEdit->text());
2407 settings.setValue("reqcOutLogFile", _reqcOutLogLineEdit->text());
2408 settings.setValue("reqcPlotDir", _reqcPlotDirLineEdit->text());
2409 settings.setValue("reqcSkyPlotSignals", _reqcSkyPlotSignals->text());
2410 settings.setValue("reqcLogSummaryOnly", _reqcLogSummaryOnly->checkState());
2411 settings.setValue("reqcMinEle", _reqcMinEle->value());
2412 // SP3 Comparison
2413 settings.setValue("sp3CompFile", _sp3CompFileChooser->fileName());
2414 settings.setValue("sp3CompExclude", _sp3CompExclude->text());
2415 settings.setValue("sp3CompOutLogFile", _sp3CompLogLineEdit->text());
2416 settings.setValue("sp3CompSummaryOnly", _sp3CompSummaryOnly->checkState());
2417 // Combine Corrections
2418 if (!cmbStreams.isEmpty()) {
2419 settings.setValue("cmbStreams", cmbStreams);
2420 }
2421 else {
2422 settings.setValue("cmbStreams", "");
2423 }
2424 settings.setValue("cmbMethod", _cmbMethodComboBox->currentText());
2425 settings.setValue("cmbMaxres", _cmbMaxresLineEdit->text());
2426 settings.setValue("cmbMaxdisplacement", _cmbMaxdisplacementLineEdit->text());
2427 settings.setValue("cmbSampl", _cmbSamplComboBox->currentText());
2428 settings.setValue("cmbLogpath", _cmbLogPath->text());
2429 settings.setValue("cmbGps", _cmbGpsCheckBox->checkState());
2430 settings.setValue("cmbGlo", _cmbGloCheckBox->checkState());
2431 settings.setValue("cmbGal", _cmbGalCheckBox->checkState());
2432 settings.setValue("cmbBds", _cmbBdsCheckBox->checkState());
2433 settings.setValue("cmbQzss", _cmbQzssCheckBox->checkState());
2434 settings.setValue("cmbSbas", _cmbSbasCheckBox->checkState());
2435 settings.setValue("cmbNavic", _cmbNavicCheckBox->checkState());
2436 settings.setValue("cmbBsxFile", _cmbBsxFile->fileName());
2437
2438 // Upload Corrections
2439 if (!uploadMountpointsOut.isEmpty()) {
2440 settings.setValue("uploadMountpointsOut", uploadMountpointsOut);
2441 }
2442 else {
2443 settings.setValue("uploadMountpointsOut", "");
2444 }
2445 settings.setValue("uploadIntr", _uploadIntrComboBox->currentText());
2446 settings.setValue("uploadSamplRtcmEphCorr", _uploadSamplRtcmEphCorrComboBox->currentText());
2447 settings.setValue("uploadSamplSp3", _uploadSamplSp3ComboBox->currentText());
2448 settings.setValue("uploadSamplClkRnx", _uploadSamplClkRnxSpinBox->value());
2449 settings.setValue("uploadSamplBiaSnx", _uploadSamplBiaSnxSpinBox->value());
2450 settings.setValue("uploadAntexFile", _uploadAntexFile->fileName());
2451 // Upload Ephemeris
2452 if (!uploadEphMountpointsOut.isEmpty()) {
2453 settings.setValue("uploadEphMountpointsOut", uploadEphMountpointsOut);
2454 }
2455 else {
2456 settings.setValue("uploadEphMountpointsOut", "");
2457 }
2458 settings.setValue("uploadSamplRtcmEph", _uploadSamplRtcmEphSpinBox->value());
2459 // Upload Raw Data
2460 if (!uploadRawMountpointsOut.isEmpty()) {
2461 settings.setValue("uploadRawMountpointsOut", uploadRawMountpointsOut);
2462 }
2463 else {
2464 settings.setValue("uploadRawMountpointsOut", "");
2465 }
2466 if (_caster) {
2467 _caster->readMountPoints();
2468 }
2469
2470 _pppWidgets.saveOptions();
2471}
2472
2473// All get slots terminated
2474////////////////////////////////////////////////////////////////////////////
2475void bncWindow::slotGetThreadsFinished() {
2476 BNC_CORE->slotMessage("All Get Threads Terminated", true);
2477 delete _caster; _caster = 0; BNC_CORE->setCaster(0);
2478 delete _casterEph; _casterEph = 0;
2479 _runningRealTime = false;
2480 enableStartStop();
2481}
2482
2483// Start It!
2484////////////////////////////////////////////////////////////////////////////
2485void bncWindow::slotStart() {
2486 saveOptions();
2487 if (_pppWidgets._dataSource->currentText() == "RINEX Files") {
2488 _runningPPP = true;
2489 enableStartStop();
2490 _caster = new bncCaster(); BNC_CORE->setCaster(_caster);
2491 BNC_CORE->startPPP();
2492 _bncFigurePPP->reset();
2493 }
2494 else if (!_reqcActionComboBox->currentText().isEmpty()) {
2495 if (_reqcActionComboBox->currentText() == "Analyze") {
2496 _runningQC = true;
2497 t_reqcAnalyze* reqcAnalyze = new t_reqcAnalyze(this);
2498 connect(reqcAnalyze, SIGNAL(finished()), this, SLOT(slotPostProcessingFinished()));
2499 reqcAnalyze->start();
2500 }
2501 else {
2502 _runningEdit = true;
2503 t_reqcEdit* reqcEdit = new t_reqcEdit(this);
2504 connect(reqcEdit, SIGNAL(finished()), this, SLOT(slotPostProcessingFinished()));
2505 reqcEdit->start();
2506 }
2507 enableStartStop();
2508 }
2509 else if (!_sp3CompFileChooser->fileName().isEmpty()) {
2510 _runningSp3Comp = true;
2511 t_sp3Comp* sp3Comp = new t_sp3Comp(this);
2512 connect(sp3Comp, SIGNAL(finished()), this, SLOT(slotPostProcessingFinished()));
2513 sp3Comp->start();
2514 enableStartStop();
2515 }
2516 else {
2517 startRealTime();
2518 BNC_CORE->startPPP();
2519 }
2520}
2521
2522// Start Real-Time (Retrieve Data etc.)
2523////////////////////////////////////////////////////////////////////////////
2524void bncWindow::startRealTime() {
2525
2526 _runningRealTime = true;
2527
2528 _bncFigurePPP->reset();
2529
2530 _actDeleteMountPoints->setEnabled(false);
2531
2532 enableStartStop();
2533
2534 _caster = new bncCaster();
2535
2536 BNC_CORE->setCaster(_caster);
2537 BNC_CORE->setPortEph(_ephOutPortLineEdit->text().toInt());
2538 BNC_CORE->setPortCorr(_corrPortLineEdit->text().toInt());
2539 BNC_CORE->initCombination();
2540
2541 connect(_caster, SIGNAL(getThreadsFinished()), this, SLOT(slotGetThreadsFinished()));
2542
2543 connect(_caster, SIGNAL(mountPointsRead(QList<bncGetThread*>)), this, SLOT(slotMountPointsRead(QList<bncGetThread*>)));
2544
2545 BNC_CORE->slotMessage("========== Start BNC v" BNCVERSION " (" BNC_OS ") ==========", true);
2546
2547 bncSettings settings;
2548
2549 // Active panels
2550 // -------------
2551 if (!_rnxPathLineEdit->text().isEmpty())
2552 BNC_CORE->slotMessage("Panel 'RINEX Observations' active", true);
2553 if (!_ephPathLineEdit->text().isEmpty())
2554 BNC_CORE->slotMessage("Panel 'RINEX Ephemeris' active", true);
2555 if (!_corrPathLineEdit->text().isEmpty())
2556 BNC_CORE->slotMessage("Panel 'Broadcast Corrections' active", true);
2557 if (!_outPortLineEdit->text().isEmpty())
2558 BNC_CORE->slotMessage("Panel 'Feed Engine' active", true);
2559 if (!_serialMountPointLineEdit->text().isEmpty())
2560 BNC_CORE->slotMessage("Panel 'Serial Output' active", true);
2561 if (!_adviseObsRateComboBox->currentText().isEmpty())
2562 BNC_CORE->slotMessage("Panel 'Outages' active", true);
2563 if (!_miscMountLineEdit->text().isEmpty())
2564 BNC_CORE->slotMessage("Panel 'Miscellaneous' active", true);
2565 if (_pppWidgets._dataSource->currentText() == "Real-Time Streams")
2566 BNC_CORE->slotMessage("Panel 'PPP' active", true);
2567 if (_cmbTable->rowCount() > 0)
2568 BNC_CORE->slotMessage("Panel 'Combine Corrections' active", true);
2569 if (_uploadTable->rowCount() > 0)
2570 BNC_CORE->slotMessage("Panel 'Upload Corrections' active", true);
2571 if (_uploadEphTable->rowCount() > 0)
2572 BNC_CORE->slotMessage("Panel 'UploadEphemeris' active", true);
2573
2574 QDir rnxdir(settings.value("rnxPath").toString());
2575 if (!rnxdir.exists()) BNC_CORE->slotMessage("Cannot find RINEX Observations directory", true);
2576
2577 QString rnx_file = settings.value("rnxScript").toString();
2578 if (!rnx_file.isEmpty()) {
2579 QFile rnxfile(settings.value("rnxScript").toString());
2580 if (!rnxfile.exists()) BNC_CORE->slotMessage("Cannot find RINEX Observations script", true);
2581 }
2582
2583 QDir ephdir(settings.value("ephPath").toString());
2584 if (!ephdir.exists()) BNC_CORE->slotMessage("Cannot find RINEX Ephemeris directory", true);
2585
2586 QDir corrdir(settings.value("corrPath").toString());
2587 if (!corrdir.exists()) BNC_CORE->slotMessage("Cannot find Broadcast Corrections directory", true);
2588
2589 QString advise_file = settings.value("adviseScript").toString();
2590 if (!advise_file.isEmpty()) {
2591 QFile advisefile(settings.value("adviseScript").toString());
2592 if (!advisefile.exists()) BNC_CORE->slotMessage("Cannot find Outages script", true);
2593 }
2594
2595 _caster->readMountPoints();
2596
2597 _casterEph = new bncEphUploadCaster();
2598}
2599
2600// Retrieve Data
2601////////////////////////////////////////////////////////////////////////////
2602void bncWindow::slotStop() {
2603 int iRet = QMessageBox::question(this, "Stop", "Stop retrieving/processing data?",
2604 QMessageBox::Yes, QMessageBox::No,
2605 QMessageBox::NoButton);
2606 if (iRet == QMessageBox::Yes) {
2607 BNC_CORE->stopPPP();
2608 BNC_CORE->stopCombination();
2609 delete _caster; _caster = 0; BNC_CORE->setCaster(0);
2610 delete _casterEph; _casterEph = 0;
2611 _runningRealTime = false;
2612 _runningPPP = false;
2613 enableStartStop();
2614 }
2615}
2616
2617// Close Application gracefully
2618////////////////////////////////////////////////////////////////////////////
2619void bncWindow::closeEvent(QCloseEvent* event) {
2620
2621 int iRet = QMessageBox::question(this, "Close", "Save Options?",
2622 QMessageBox::Yes, QMessageBox::No,
2623 QMessageBox::Cancel);
2624
2625 if (iRet == QMessageBox::Cancel) {
2626 event->ignore();
2627 return;
2628 }
2629 else if (iRet == QMessageBox::Yes) {
2630 slotSaveOptions();
2631 }
2632
2633 BNC_CORE->stopPPP();
2634
2635 QMainWindow::closeEvent(event);
2636}
2637
2638// User changed the selection of mountPoints
2639////////////////////////////////////////////////////////////////////////////
2640void bncWindow::slotSelectionChanged() {
2641 if (_mountPointsTable->selectedItems().isEmpty()) {
2642 _actDeleteMountPoints->setEnabled(false);
2643 }
2644 else {
2645 _actDeleteMountPoints->setEnabled(true);
2646 }
2647}
2648
2649// Display Program Messages
2650////////////////////////////////////////////////////////////////////////////
2651void bncWindow::slotWindowMessage(const QByteArray msg, bool showOnScreen) {
2652 if (showOnScreen) {
2653 _log->append(QDateTime::currentDateTime().toUTC().toString("yy-MM-dd hh:mm:ss ") + msg);
2654 }
2655}
2656
2657// About Message
2658////////////////////////////////////////////////////////////////////////////
2659void bncWindow::slotAbout() {
2660 new bncAboutDlg(0);
2661}
2662
2663//Flowchart
2664////////////////////////////////////////////////////////////////////////////
2665void bncWindow::slotFlowchart() {
2666 new bncFlowchartDlg(0);
2667}
2668
2669// Help Window
2670////////////////////////////////////////////////////////////////////////////
2671void bncWindow::slotHelp() {
2672 QUrl url = QUrl::fromLocalFile(":/bnchelp.html");
2673 new bncHlpDlg(0, url);
2674}
2675
2676// Select Fonts
2677////////////////////////////////////////////////////////////////////////////
2678void bncWindow::slotFontSel() {
2679 bool ok;
2680 QFont newFont = QFontDialog::getFont(&ok, this->font(), this);
2681 if (ok) {
2682 bncSettings settings;
2683 settings.setValue("font", newFont.toString());
2684 QApplication::setFont(newFont);
2685 int ww = QFontMetrics(newFont).horizontalAdvance('w');
2686 setMinimumSize(60 * ww, 80 * ww);
2687 resize(60 * ww, 80 * ww);
2688 }
2689}
2690
2691// Whats This Help
2692void bncWindow::slotWhatsThis() {
2693 QWhatsThis::enterWhatsThisMode();
2694}
2695
2696//
2697////////////////////////////////////////////////////////////////////////////
2698void bncWindow::slotMountPointsRead(QList<bncGetThread*> threads) {
2699 _threads = threads;
2700
2701 _bncFigure->updateMountPoints();
2702 _bncFigureLate->updateMountPoints();
2703
2704 populateMountPointsTable();
2705 bncSettings settings;
2706 _outSamplComboBox->findText(settings.value("outSampl").toString());
2707 _outWaitSpinBox->setValue(settings.value("outWait").toInt());
2708 QListIterator<bncGetThread*> iTh(threads);
2709 while (iTh.hasNext()) {
2710 bncGetThread* thread = iTh.next();
2711 for (int iRow = 0; iRow < _mountPointsTable->rowCount(); iRow++) {
2712 QUrl url("//" + _mountPointsTable->item(iRow, 0)->text() +
2713 "@" + _mountPointsTable->item(iRow, 1)->text());
2714 if (url == thread->mountPoint() &&
2715 _mountPointsTable->item(iRow, 4)->text() == thread->latitude() &&
2716 _mountPointsTable->item(iRow, 5)->text() == thread->longitude()) {
2717 ((bncTableItem*)_mountPointsTable->item(iRow, 8))->setGetThread(thread);
2718 disconnect(thread, SIGNAL(newBytes(QByteArray, double)), _bncFigure, SLOT(slotNewData(QByteArray, double)));
2719 connect(thread, SIGNAL(newBytes(QByteArray, double)), _bncFigure, SLOT(slotNewData(QByteArray, double)));
2720 disconnect(thread, SIGNAL(newLatency(QByteArray, double)), _bncFigureLate, SLOT(slotNewLatency(QByteArray, double)));
2721 connect(thread, SIGNAL(newLatency(QByteArray, double)), _bncFigureLate, SLOT(slotNewLatency(QByteArray, double)));
2722 break;
2723 }
2724 }
2725 }
2726}
2727
2728//
2729////////////////////////////////////////////////////////////////////////////
2730void bncWindow::CreateMenu() {
2731 // Create Menus
2732 // ------------
2733 _menuFile = menuBar()->addMenu(tr("&File"));
2734 _menuFile->addAction(_actFontSel);
2735 _menuFile->addSeparator();
2736 _menuFile->addAction(_actSaveOpt);
2737 _menuFile->addSeparator();
2738 _menuFile->addAction(_actQuit);
2739
2740 _menuHlp = menuBar()->addMenu(tr("&Help"));
2741 _menuHlp->addAction(_actHelp);
2742 _menuHlp->addAction(_actFlowchart);
2743 _menuHlp->addAction(_actAbout);
2744}
2745
2746// Toolbar
2747////////////////////////////////////////////////////////////////////////////
2748void bncWindow::AddToolbar() {
2749 QToolBar* toolBar = new QToolBar;
2750 addToolBar(Qt::BottomToolBarArea, toolBar);
2751 toolBar->setMovable(false);
2752 toolBar->addAction(_actAddMountPoints);
2753 toolBar->addAction(_actDeleteMountPoints);
2754 toolBar->addAction(_actMapMountPoints);
2755 toolBar->addAction(_actStart);
2756 toolBar->addAction(_actStop);
2757 toolBar->addWidget(new QLabel(" "));
2758 toolBar->addAction(_actwhatsthis);
2759}
2760
2761// About
2762////////////////////////////////////////////////////////////////////////////
2763bncAboutDlg::bncAboutDlg(QWidget* parent) :
2764 QDialog(parent) {
2765
2766 QTextBrowser* tb = new QTextBrowser;
2767 QUrl url = QUrl::fromLocalFile(":/bncabout.html");
2768 tb->setSource(url);
2769 tb->setReadOnly(true);
2770
2771 int ww = QFontMetrics(font()).horizontalAdvance('w');
2772 QPushButton* _closeButton = new QPushButton("Close");
2773 _closeButton->setMaximumWidth(10 * ww);
2774 connect(_closeButton, SIGNAL(clicked()), this, SLOT(close()));
2775
2776 QGridLayout* dlgLayout = new QGridLayout();
2777 QLabel* img = new QLabel();
2778 img->setPixmap(QPixmap(":ntrip-logo.png"));
2779 dlgLayout->addWidget(img, 0, 0);
2780 dlgLayout->addWidget(new QLabel("BKG Ntrip Client (BNC) Version " BNCVERSION), 0, 1);
2781 dlgLayout->addWidget(tb, 1, 0, 1, 2);
2782 dlgLayout->addWidget(_closeButton, 2, 1, Qt::AlignRight);
2783
2784 setLayout(dlgLayout);
2785 resize(60 * ww, 60 * ww);
2786 setWindowTitle("About BNC");
2787 show();
2788}
2789
2790//
2791////////////////////////////////////////////////////////////////////////////
2792bncAboutDlg::~bncAboutDlg() {
2793
2794};
2795
2796// Flowchart
2797////////////////////////////////////////////////////////////////////////////
2798bncFlowchartDlg::bncFlowchartDlg(QWidget* parent) :
2799 QDialog(parent) {
2800
2801 int ww = QFontMetrics(font()).horizontalAdvance('w');
2802 QPushButton* _closeButton = new QPushButton("Close");
2803 _closeButton->setMaximumWidth(10 * ww);
2804 connect(_closeButton, SIGNAL(clicked()), this, SLOT(close()));
2805
2806 QGridLayout* dlgLayout = new QGridLayout();
2807 QLabel* img = new QLabel();
2808 img->setPixmap(QPixmap(":bncflowchart.png"));
2809 dlgLayout->addWidget(img, 0, 0);
2810 dlgLayout->addWidget(_closeButton, 1, 0, Qt::AlignLeft);
2811
2812 setLayout(dlgLayout);
2813 setWindowTitle("Flow Chart");
2814 show();
2815}
2816
2817//
2818////////////////////////////////////////////////////////////////////////////
2819bncFlowchartDlg::~bncFlowchartDlg() {
2820};
2821
2822// Enable/Disable Widget (and change its color)
2823////////////////////////////////////////////////////////////////////////////
2824void bncWindow::enableWidget(bool enable, QWidget* widget) {
2825
2826 const static QPalette paletteWhite(QColor(255, 255, 255));
2827 const static QPalette paletteGray(QColor(230, 230, 230));
2828
2829 widget->setEnabled(enable);
2830 if (enable) {
2831 widget->setPalette(paletteWhite);
2832 }
2833 else {
2834 widget->setPalette(paletteGray);
2835 }
2836}
2837
2838// Bnc Text
2839////////////////////////////////////////////////////////////////////////////
2840void bncWindow::slotBncTextChanged() {
2841
2842 const static QPalette paletteWhite(QColor(255, 255, 255));
2843 const static QPalette paletteGray(QColor(230, 230, 230));
2844
2845 bool enable = true;
2846
2847 // Proxy
2848 //------
2849 if (sender() == 0 || sender() == _proxyHostLineEdit) {
2850 enable = !_proxyHostLineEdit->text().isEmpty();
2851 enableWidget(enable, _proxyPortLineEdit);
2852 }
2853
2854 // RINEX Observations
2855 // ------------------
2856 if (sender() == 0 || sender() == _rnxPathLineEdit) {
2857 enable = !_rnxPathLineEdit->text().isEmpty();
2858 enableWidget(enable, _rnxIntrComboBox);
2859 enableWidget(enable, _rnxSamplComboBox);
2860 enableWidget(enable, _rnxSkelExtComboBox);
2861 enableWidget(enable, _rnxSkelPathLineEdit);
2862 enableWidget(enable, _rnxFileCheckBox);
2863 enableWidget(enable, _rnxScrpLineEdit);
2864 enableWidget(enable, _rnxV2Priority);
2865 enableWidget(enable, _rnxVersComboBox);
2866
2867 bool enable1 = true;
2868 enable1 = _rnxVersComboBox->currentText() == "2";
2869 if (enable && enable1) {
2870 enableWidget(true, _rnxV2Priority);
2871 }
2872 if (enable && !enable1) {
2873 enableWidget(false, _rnxV2Priority);
2874 }
2875 }
2876
2877 // RINEX Observations, Signal Priority
2878 // -----------------------------------
2879 if (sender() == 0 || sender() == _rnxVersComboBox) {
2880 if (!_rnxPathLineEdit->text().isEmpty()) {
2881 enableWidget(enable, _rnxIntrComboBox);
2882 enable = _rnxVersComboBox->currentText() == "2";
2883 enableWidget(enable, _rnxV2Priority);
2884 }
2885 }
2886
2887 // RINEX Ephemeris
2888 // ---------------
2889 if (sender() == 0 || sender() == _ephPathLineEdit || sender() == _ephOutPortLineEdit) {
2890 enable = !_ephPathLineEdit->text().isEmpty() || !_ephOutPortLineEdit->text().isEmpty();
2891 enableWidget(enable, _ephIntrComboBox);
2892 enableWidget(enable, _ephVersComboBox);
2893 //enableWidget(enable, _ephVersComboBox);
2894 //enableWidget(enable, _ephFilePerStation);
2895 }
2896
2897 // Broadcast Corrections
2898 // ---------------------
2899 if (sender() == 0 || sender() == _corrPathLineEdit || sender() == _corrPortLineEdit) {
2900 enable = !_corrPathLineEdit->text().isEmpty() || !_corrPortLineEdit->text().isEmpty();
2901 enableWidget(enable, _corrIntrComboBox);
2902 }
2903
2904 // Feed Engine
2905 // -----------
2906 if (sender() == 0 || sender() == _outPortLineEdit || sender() == _outFileLineEdit) {
2907 enable = !_outPortLineEdit->text().isEmpty() || !_outFileLineEdit->text().isEmpty();
2908 enableWidget(enable, _outWaitSpinBox);
2909 enableWidget(enable, _outSamplComboBox);
2910 }
2911
2912 // Serial Output
2913 // -------------
2914 if (sender() == 0 ||
2915 sender() == _serialMountPointLineEdit ||
2916 sender() == _serialAutoNMEAComboBox) {
2917 enable = !_serialMountPointLineEdit->text().isEmpty();
2918 enableWidget(enable, _serialPortNameLineEdit);
2919 enableWidget(enable, _serialBaudRateComboBox);
2920 enableWidget(enable, _serialParityComboBox);
2921 enableWidget(enable, _serialDataBitsComboBox);
2922 enableWidget(enable, _serialStopBitsComboBox);
2923 enableWidget(enable, _serialFlowControlComboBox);
2924 enableWidget(enable, _serialAutoNMEAComboBox);
2925 if (enable && _serialAutoNMEAComboBox->currentText() == "Auto") {
2926 enableWidget(true, _serialFileNMEALineEdit);
2927 enableWidget(false, _serialHeightNMEALineEdit);
2928 enableWidget(true, _serialNMEASamplingSpinBox);
2929 }
2930 else if (enable && _serialAutoNMEAComboBox->currentText().contains("Manual")) {
2931 enableWidget(false, _serialFileNMEALineEdit);
2932 enableWidget(true, _serialHeightNMEALineEdit);
2933 enableWidget(true, _serialNMEASamplingSpinBox);
2934 }
2935 else {
2936 enableWidget(false, _serialFileNMEALineEdit);
2937 enableWidget(false, _serialHeightNMEALineEdit);
2938 enableWidget(false, _serialNMEASamplingSpinBox);
2939 }
2940 }
2941
2942 // Outages
2943 // -------
2944 if (sender() == 0 || sender() == _adviseObsRateComboBox) {
2945 enable = !_adviseObsRateComboBox->currentText().isEmpty();
2946 enableWidget(enable, _adviseFailSpinBox);
2947 enableWidget(enable, _adviseRecoSpinBox);
2948 enableWidget(enable, _adviseScriptLineEdit);
2949 }
2950
2951 // Miscellaneous
2952 // -------------
2953 if (sender() == 0 || sender() == _miscMountLineEdit) {
2954 enable = !_miscMountLineEdit->text().isEmpty();
2955 enableWidget(enable, _miscIntrComboBox);
2956 enableWidget(enable, _miscScanRTCMCheckBox);
2957 enableWidget(enable, _miscPortLineEdit);
2958 }
2959
2960 // Combine Corrections
2961 // -------------------
2962 if (sender() == 0 || sender() == _cmbTable) {
2963 int iRow = _cmbTable->rowCount();
2964 if (iRow > 0) {
2965 enableWidget(true, _cmbMethodComboBox);
2966 enableWidget(true, _cmbMaxresLineEdit);
2967 enableWidget(true, _cmbMaxdisplacementLineEdit);
2968 enableWidget(true, _cmbSamplComboBox);
2969 enableWidget(true, _cmbLogPath);
2970 enableWidget(true, _cmbGpsCheckBox);
2971 enableWidget(true, _cmbGloCheckBox);
2972 enableWidget(true, _cmbGalCheckBox);
2973 enableWidget(true, _cmbBdsCheckBox);
2974 enableWidget(true, _cmbQzssCheckBox);
2975 enableWidget(true, _cmbSbasCheckBox);
2976 enableWidget(true, _cmbNavicCheckBox);
2977 enableWidget(true, _cmbBsxFile);
2978 }
2979 else {
2980 enableWidget(false, _cmbMethodComboBox);
2981 enableWidget(false, _cmbMaxresLineEdit);
2982 enableWidget(false, _cmbMaxdisplacementLineEdit);
2983 enableWidget(false, _cmbSamplComboBox);
2984 enableWidget(false, _cmbLogPath);
2985 enableWidget(false, _cmbGpsCheckBox);
2986 enableWidget(false, _cmbGloCheckBox);
2987 enableWidget(false, _cmbGalCheckBox);
2988 enableWidget(false, _cmbBdsCheckBox);
2989 enableWidget(false, _cmbQzssCheckBox);
2990 enableWidget(false, _cmbSbasCheckBox);
2991 enableWidget(false, _cmbNavicCheckBox);
2992 enableWidget(false, _cmbBsxFile);
2993 }
2994 }
2995
2996 // Upload(clk)
2997 // -----------
2998 int iRow = _uploadTable->rowCount();
2999 if (iRow > 0) {
3000 enableWidget(true, _uploadIntrComboBox);
3001 enableWidget(true, _uploadSamplRtcmEphCorrComboBox);
3002 enableWidget(true, _uploadSamplClkRnxSpinBox);
3003 enableWidget(true, _uploadSamplBiaSnxSpinBox);
3004 enableWidget(true, _uploadSamplSp3ComboBox);
3005 enableWidget(true, _uploadAntexFile);
3006 }
3007 else {
3008 enableWidget(false, _uploadIntrComboBox);
3009 enableWidget(false, _uploadSamplRtcmEphCorrComboBox);
3010 enableWidget(false, _uploadSamplClkRnxSpinBox);
3011 enableWidget(false, _uploadSamplBiaSnxSpinBox);
3012 enableWidget(false, _uploadSamplSp3ComboBox);
3013 enableWidget(false, _uploadAntexFile);
3014 }
3015
3016 // Upload(eph)
3017 // -----------
3018 iRow = _uploadEphTable->rowCount();
3019 if (iRow > 0) {
3020 enableWidget(true, _uploadSamplRtcmEphSpinBox);
3021 }
3022 else {
3023 enableWidget(false, _uploadSamplRtcmEphSpinBox);
3024 }
3025
3026 // QC
3027 // --
3028 if (sender() == 0 || sender() == _reqcActionComboBox || sender() == _reqcSkyPlotSignals) {
3029 enable = !_reqcActionComboBox->currentText().isEmpty();
3030 bool enable10 = _reqcActionComboBox->currentText() == "Edit/Concatenate";
3031 // bool enablePlot = !_reqcSkyPlotSignals->text().isEmpty();
3032 enableWidget(enable, _reqcObsFileChooser);
3033 enableWidget(enable, _reqcNavFileChooser);
3034 enableWidget(enable, _reqcOutLogLineEdit);
3035 enableWidget(enable, _reqcMinEle);
3036 enableWidget(enable && enable10, _reqcEditOptionButton);
3037 enableWidget(enable && enable10, _reqcOutObsLineEdit);
3038 enableWidget(enable && enable10, _reqcOutNavLineEdit);
3039 enableWidget(enable && !enable10, _reqcLogSummaryOnly);
3040 enableWidget(enable && !enable10, _reqcSkyPlotSignals);
3041 // enableWidget(enable && !enable10 && enablePlot, _reqcPlotDirLineEdit);
3042 enableWidget(enable && !enable10, _reqcPlotDirLineEdit);
3043 }
3044
3045 // SP3 File Comparison
3046 // -------------------
3047 if (sender() == 0 || sender() == _sp3CompFileChooser) {
3048 enable = !_sp3CompFileChooser->fileName().isEmpty();
3049 enableWidget(enable, _sp3CompLogLineEdit);
3050 enableWidget(enable, _sp3CompExclude);
3051 enableWidget(enable, _sp3CompSummaryOnly);
3052 }
3053
3054 enableStartStop();
3055}
3056
3057//
3058////////////////////////////////////////////////////////////////////////////
3059void bncWindow::slotAddCmbRow() {
3060 int iRow = _cmbTable->rowCount();
3061 _cmbTable->insertRow(iRow);
3062 for (int iCol = 0; iCol < _cmbTable->columnCount(); iCol++) {
3063 if (iCol == 4) {
3064 QComboBox* attCombo = new QComboBox();
3065 attCombo->setEditable(false);
3066 attCombo->addItems(QString("Computed,SSR,Nominal").split(","));
3067 attCombo->setFrame(false);
3068 _cmbTable->setCellWidget(iRow, iCol, attCombo);
3069 }
3070 else {
3071 _cmbTable->setItem(iRow, iCol, new QTableWidgetItem(""));
3072 }
3073 }
3074}
3075
3076//
3077////////////////////////////////////////////////////////////////////////////
3078void bncWindow::slotDelCmbRow() {
3079
3080 const static QPalette paletteWhite(QColor(255, 255, 255));
3081 const static QPalette paletteGray(QColor(230, 230, 230));
3082
3083 int nRows = _cmbTable->rowCount();
3084 std::vector <bool> flg(nRows);
3085 for (int iRow = 0; iRow < nRows; iRow++) {
3086 if (_cmbTable->item(iRow, 1)->isSelected()) {
3087 flg[iRow] = true;
3088 }
3089 else {
3090 flg[iRow] = false;
3091 }
3092 }
3093 for (int iRow = nRows - 1; iRow >= 0; iRow--) {
3094 if (flg[iRow]) {
3095 _cmbTable->removeRow(iRow);
3096 }
3097 }
3098 nRows = _cmbTable->rowCount();
3099 if (nRows < 1) {
3100 enableWidget(false, _cmbMethodComboBox);
3101 enableWidget(false, _cmbMaxresLineEdit);
3102 enableWidget(false, _cmbMaxdisplacementLineEdit);
3103 enableWidget(false, _cmbSamplComboBox);
3104 enableWidget(false, _cmbLogPath);
3105 }
3106}
3107
3108//
3109////////////////////////////////////////////////////////////////////////////
3110void bncWindow::populateCmbTable() {
3111
3112 for (int iRow = _cmbTable->rowCount() - 1; iRow >= 0; iRow--) {
3113 _cmbTable->removeRow(iRow);
3114 }
3115
3116 bncSettings settings;
3117
3118 int iRow = -1;
3119 QListIterator<QString> it(settings.value("cmbStreams").toStringList());
3120 while (it.hasNext()) {
3121 QStringList hlp = it.next().split(" ");
3122 if (hlp.size() > 2) {
3123 ++iRow;
3124 _cmbTable->insertRow(iRow);
3125 }
3126 for (int iCol = 0; iCol < hlp.size() && iCol < _cmbTable->columnCount(); iCol++) {
3127 if (iCol == 4) {
3128 QComboBox* attCombo = new QComboBox();
3129 attCombo->setEditable(false);
3130 attCombo->addItems(QString("Computed,SSR,Nominal").split(","));
3131 attCombo->setFrame(false);
3132 int idx = attCombo->findText(hlp[iCol]);
3133 if (idx != -1) attCombo->setCurrentIndex(idx);
3134 _cmbTable->setCellWidget(iRow, iCol, attCombo);
3135 }
3136 else {
3137 _cmbTable->setItem(iRow, iCol, new QTableWidgetItem(hlp[iCol]));
3138 }
3139 }
3140 // Ensure the Attitude combo exists even for old configs without column 4
3141 if (hlp.size() <= 4 && _cmbTable->columnCount() > 4 && iRow >= 0
3142 && !_cmbTable->cellWidget(iRow, 4)) {
3143 QComboBox* attCombo = new QComboBox();
3144 attCombo->setEditable(false);
3145 attCombo->addItems(QString("Computed,SSR,Nominal").split(","));
3146 attCombo->setFrame(false);
3147 _cmbTable->setCellWidget(iRow, 4, attCombo);
3148 }
3149 }
3150}
3151
3152//
3153////////////////////////////////////////////////////////////////////////////
3154void bncWindow::slotAddUploadRow() {
3155 int iRow = _uploadTable->rowCount();
3156 _uploadTable->insertRow(iRow);
3157 for (int iCol = 0; iCol < _uploadTable->columnCount(); iCol++) {
3158 if (iCol == 3) {
3159 QComboBox* ntripversion = new QComboBox();
3160 ntripversion->setEditable(false);
3161 ntripversion->addItems(QString("2s,2,1").split(","));
3162 ntripversion->setFrame(false);
3163 _uploadTable->setCellWidget(iRow, iCol, ntripversion);
3164
3165 }
3166 else if (iCol == 4) {
3167 QLineEdit* user = new QLineEdit();
3168 user->setFrame(false);
3169 _uploadTable->setCellWidget(iRow, iCol, user);
3170 }
3171 else if (iCol == 5) {
3172 QLineEdit* passwd = new QLineEdit();
3173 passwd->setFrame(false);
3174 passwd->setEchoMode(QLineEdit::PasswordEchoOnEdit);
3175 _uploadTable->setCellWidget(iRow, iCol, passwd);
3176 }
3177 else if (iCol == 6) {
3178 QComboBox* system = new QComboBox();
3179 system->setEditable(false);
3180 system->addItems(QString("IGS20,ETRF2000,GDA2020,SIRGAS2000,DREF91,Custom").split(","));
3181 system->setFrame(false);
3182 _uploadTable->setCellWidget(iRow, iCol, system);
3183 }
3184 else if (iCol == 7) {
3185 QComboBox* format = new QComboBox();
3186 format->setEditable(false);
3187 //format->addItems(QString("IGS-SSR,RTCM-SSR,RTCM-NEW-SSR").split(","));
3188 format->addItems(QString("IGS-SSR,RTCM-SSR").split(","));
3189 format->setFrame(false);
3190 _uploadTable->setCellWidget(iRow, iCol, format);
3191 }
3192 else if (iCol == 8) {
3193 QCheckBox* com = new QCheckBox();
3194 _uploadTable->setCellWidget(iRow, iCol, com);
3195 }
3196 else if (iCol == 15) {
3197 bncTableItem* bncIt = new bncTableItem();
3198 bncIt->setFlags(bncIt->flags() & ~Qt::ItemIsEditable);
3199 _uploadTable->setItem(iRow, iCol, bncIt);
3200 BNC_CORE->_uploadTableItems[iRow] = bncIt;
3201 }
3202 else {
3203 _uploadTable->setItem(iRow, iCol, new QTableWidgetItem(""));
3204 }
3205 }
3206}
3207
3208//
3209////////////////////////////////////////////////////////////////////////////
3210void bncWindow::slotDelUploadRow() {
3211 BNC_CORE->_uploadTableItems.clear();
3212 int nRows = _uploadTable->rowCount();
3213 std::vector <bool> flg(nRows);
3214 for (int iRow = 0; iRow < nRows; iRow++) {
3215 if (_uploadTable->item(iRow, 1)->isSelected()) {
3216 flg[iRow] = true;
3217 }
3218 else {
3219 flg[iRow] = false;
3220 }
3221 }
3222 for (int iRow = nRows - 1; iRow >= 0; iRow--) {
3223 if (flg[iRow]) {
3224 _uploadTable->removeRow(iRow);
3225 }
3226 }
3227 for (int iRow = 0; iRow < _uploadTable->rowCount(); iRow++) {
3228 BNC_CORE->_uploadTableItems[iRow] =
3229 (bncTableItem*)_uploadTable->item(iRow, 14);
3230 }
3231 nRows = _uploadTable->rowCount();
3232 if (nRows < 1) {
3233 enableWidget(false, _uploadIntrComboBox);
3234 enableWidget(false, _uploadSamplRtcmEphCorrComboBox);
3235 enableWidget(false, _uploadSamplSp3ComboBox);
3236 enableWidget(false, _uploadSamplClkRnxSpinBox);
3237 enableWidget(false, _uploadAntexFile);
3238 }
3239}
3240
3241//
3242////////////////////////////////////////////////////////////////////////////
3243void bncWindow::populateUploadTable() {
3244 for (int iRow = _uploadTable->rowCount() - 1; iRow >= 0; iRow--) {
3245 _uploadTable->removeRow(iRow);
3246 }
3247
3248 bncSettings settings;
3249
3250 int iRow = -1;
3251 QListIterator<QString> it(settings.value("uploadMountpointsOut").toStringList());
3252
3253 while (it.hasNext()) {
3254 QStringList hlp = it.next().split(",");
3255 if (hlp.size() > 6) {
3256 ++iRow;
3257 _uploadTable->insertRow(iRow);
3258 }
3259 for (int iCol = 0; iCol < hlp.size(); iCol++) {
3260 if (iCol == 3) {
3261 QComboBox* ntripversion = new QComboBox();
3262 ntripversion->setEditable(false);
3263 ntripversion->addItems(QString("1,2,2s").split(","));
3264 ntripversion->setFrame(false);
3265 ntripversion->setCurrentIndex(ntripversion->findText(hlp[iCol]));
3266 _uploadTable->setCellWidget(iRow, iCol, ntripversion);
3267 }
3268 else if (iCol == 4) {
3269 QLineEdit* user = new QLineEdit();
3270 user->setFrame(false);
3271 user->setText(hlp[iCol]);
3272 _uploadTable->setCellWidget(iRow, iCol, user);
3273 }
3274 else if (iCol == 5) {
3275 QLineEdit* passwd = new QLineEdit();
3276 passwd->setFrame(false);
3277 passwd->setEchoMode(QLineEdit::PasswordEchoOnEdit);
3278 passwd->setText(hlp[iCol]);
3279 _uploadTable->setCellWidget(iRow, iCol, passwd);
3280 }
3281 else if (iCol == 6) {
3282 QComboBox* system = new QComboBox();
3283 system->setEditable(false);
3284 system->addItems(QString("IGS20,ETRF2000,GDA2020,SIRGAS2000,DREF91,Custom").split(","));
3285 system->setFrame(false);
3286 system->setCurrentIndex(system->findText(hlp[iCol]));
3287 _uploadTable->setCellWidget(iRow, iCol, system);
3288 }
3289 else if (iCol == 7) {
3290 QComboBox* format = new QComboBox();
3291 format->setEditable(false);
3292 //format->addItems(QString("IGS-SSR,RTCM-SSR,RTCM-NEW-SSR").split(","));
3293 format->addItems(QString("IGS-SSR,RTCM-SSR").split(","));
3294 format->setFrame(false);
3295 format->setCurrentIndex(format->findText(hlp[iCol]));
3296 _uploadTable->setCellWidget(iRow, iCol, format);
3297 }
3298 else if (iCol == 8) {
3299 QCheckBox* com = new QCheckBox();
3300 if (hlp[iCol].toInt() == Qt::Checked) {
3301 com->setCheckState(Qt::Checked);
3302 }
3303 _uploadTable->setCellWidget(iRow, iCol, com);
3304 }
3305 else if (iCol == 15) {
3306 bncTableItem* bncIt = new bncTableItem();
3307 bncIt->setFlags(bncIt->flags() & ~Qt::ItemIsEditable);
3308 _uploadTable->setItem(iRow, iCol, bncIt);
3309 BNC_CORE->_uploadTableItems[iRow] = bncIt;
3310 }
3311 else {
3312 _uploadTable->setItem(iRow, iCol, new QTableWidgetItem(hlp[iCol]));
3313 }
3314 }
3315 }
3316}
3317
3318//
3319////////////////////////////////////////////////////////////////////////////
3320void bncWindow::slotSetUploadTrafo() {
3321 bncCustomTrafo* dlg = new bncCustomTrafo(this);
3322 dlg->exec();
3323 delete dlg;
3324}
3325
3326//
3327////////////////////////////////////////////////////////////////////////////
3328void bncWindow::slotAddUploadEphRow() {
3329 int iRow = _uploadEphTable->rowCount();
3330 _uploadEphTable->insertRow(iRow);
3331 for (int iCol = 0; iCol < _uploadEphTable->columnCount(); iCol++) {
3332 if (iCol == 3) {
3333 QComboBox* ntripversion = new QComboBox();
3334 ntripversion->setEditable(false);
3335 ntripversion->addItems(QString("2s,2,1").split(","));
3336 ntripversion->setFrame(false);
3337 _uploadEphTable->setCellWidget(iRow, iCol, ntripversion);
3338
3339 }
3340 else if (iCol == 4) {
3341 QLineEdit* user = new QLineEdit();
3342 user->setFrame(false);
3343 _uploadEphTable->setCellWidget(iRow, iCol, user);
3344 }
3345 else if (iCol == 5) {
3346 QLineEdit* passwd = new QLineEdit();
3347 passwd->setFrame(false);
3348 passwd->setEchoMode(QLineEdit::PasswordEchoOnEdit);
3349 _uploadEphTable->setCellWidget(iRow, iCol, passwd);
3350 }
3351 else if (iCol == 6) {
3352 QLineEdit* system = new QLineEdit("GREC");
3353 system->setFrame(false);
3354 _uploadEphTable->setCellWidget(iRow, iCol, system);
3355 }
3356 else if (iCol == 7) {
3357 bncTableItem* bncIt = new bncTableItem();
3358 bncIt->setFlags(bncIt->flags() & ~Qt::ItemIsEditable);
3359 _uploadEphTable->setItem(iRow, iCol, bncIt);
3360 BNC_CORE->_uploadEphTableItems[iRow] = bncIt;
3361 }
3362 else {
3363 _uploadEphTable->setItem(iRow, iCol, new QTableWidgetItem(""));
3364 }
3365 }
3366}
3367
3368//
3369////////////////////////////////////////////////////////////////////////////
3370void bncWindow::slotDelUploadEphRow() {
3371 BNC_CORE->_uploadEphTableItems.clear();
3372 int nRows = _uploadEphTable->rowCount();
3373 std::vector <bool> flg(nRows);
3374 for (int iRow = 0; iRow < nRows; iRow++) {
3375 if (_uploadEphTable->item(iRow, 1)->isSelected()) {
3376 flg[iRow] = true;
3377 }
3378 else {
3379 flg[iRow] = false;
3380 }
3381 }
3382 for (int iRow = nRows - 1; iRow >= 0; iRow--) {
3383 if (flg[iRow]) {
3384 _uploadEphTable->removeRow(iRow);
3385 }
3386 }
3387 for (int iRow = 0; iRow < _uploadTable->rowCount(); iRow++) {
3388 BNC_CORE->_uploadEphTableItems[iRow] =
3389 (bncTableItem*)_uploadEphTable->item(iRow, 7);
3390 }
3391 nRows = _uploadEphTable->rowCount();
3392 if (nRows < 1) {
3393 enableWidget(false, _uploadSamplRtcmEphSpinBox);
3394 }
3395}
3396
3397//
3398////////////////////////////////////////////////////////////////////////////
3399void bncWindow::populateUploadEphTable() {
3400 for (int iRow = _uploadEphTable->rowCount() - 1; iRow >= 0; iRow--) {
3401 _uploadEphTable->removeRow(iRow);
3402 }
3403
3404 bncSettings settings;
3405
3406 int iRow = -1;
3407 QListIterator<QString> it(settings.value("uploadEphMountpointsOut").toStringList());
3408 while (it.hasNext()) {
3409 QStringList hlp = it.next().split(",");
3410 if (hlp.size() > 6) {
3411 ++iRow;
3412 _uploadEphTable->insertRow(iRow);
3413 }
3414 for (int iCol = 0; iCol < hlp.size(); iCol++) {
3415 if (iCol == 3) {
3416 QComboBox* ntripversion = new QComboBox();
3417 ntripversion->setEditable(false);
3418 ntripversion->addItems(QString("1,2,2s").split(","));
3419 ntripversion->setFrame(false);
3420 ntripversion->setCurrentIndex(ntripversion->findText(hlp[iCol]));
3421 _uploadEphTable->setCellWidget(iRow, iCol, ntripversion);
3422 }
3423 else if (iCol == 4) {
3424 QLineEdit* user = new QLineEdit();
3425 user->setFrame(false);
3426 user->setText(hlp[iCol]);
3427 _uploadEphTable->setCellWidget(iRow, iCol, user);
3428 }
3429 else if (iCol == 5) {
3430 QLineEdit* passwd = new QLineEdit();
3431 passwd->setFrame(false);
3432 passwd->setEchoMode(QLineEdit::PasswordEchoOnEdit);
3433 passwd->setText(hlp[iCol]);
3434 _uploadEphTable->setCellWidget(iRow, iCol, passwd);
3435 }
3436 else if (iCol == 6) {
3437 QLineEdit* system = new QLineEdit();
3438 system->setFrame(false);
3439 system->setText(hlp[iCol]);
3440 _uploadEphTable->setCellWidget(iRow, iCol, system);
3441 }
3442 else if (iCol == 7) {
3443 bncTableItem* bncIt = new bncTableItem();
3444 bncIt->setFlags(bncIt->flags() & ~Qt::ItemIsEditable);
3445 _uploadEphTable->setItem(iRow, iCol, bncIt);
3446 BNC_CORE->_uploadEphTableItems[iRow] = bncIt;
3447 }
3448 else {
3449 _uploadEphTable->setItem(iRow, iCol, new QTableWidgetItem(hlp[iCol]));
3450 }
3451 }
3452 }
3453}
3454
3455//
3456////////////////////////////////////////////////////////////////////////////
3457void bncWindow::slotAddUploadRawRow() {
3458 int iRow = _uploadRawTable->rowCount();
3459 _uploadRawTable->insertRow(iRow);
3460 for (int iCol = 0; iCol < _uploadRawTable->columnCount(); iCol++) {
3461 if (iCol == 4) {
3462 QComboBox* ntripversion = new QComboBox();
3463 ntripversion->setEditable(false);
3464 ntripversion->addItems(QString("2s,2,1").split(","));
3465 ntripversion->setFrame(false);
3466 _uploadRawTable->setCellWidget(iRow, iCol, ntripversion);
3467
3468 }
3469 else if (iCol == 5) {
3470 QLineEdit* user = new QLineEdit();
3471 user->setFrame(false);
3472 _uploadRawTable->setCellWidget(iRow, iCol, user);
3473 }
3474 else if (iCol == 6) {
3475 QLineEdit* passwd = new QLineEdit();
3476 passwd->setFrame(false);
3477 passwd->setEchoMode(QLineEdit::PasswordEchoOnEdit);
3478 _uploadRawTable->setCellWidget(iRow, iCol, passwd);
3479 }
3480 else if (iCol == 7) {
3481 bncTableItem* bncIt = new bncTableItem();
3482 bncIt->setFlags(bncIt->flags() & ~Qt::ItemIsEditable);
3483 _uploadRawTable->setItem(iRow, iCol, bncIt);
3484 BNC_CORE->_uploadRawTableItems[iRow] = bncIt;
3485 }
3486 else {
3487 _uploadRawTable->setItem(iRow, iCol, new QTableWidgetItem(""));
3488 }
3489 }
3490}
3491
3492//
3493////////////////////////////////////////////////////////////////////////////
3494void bncWindow::slotDelUploadRawRow() {
3495 BNC_CORE->_uploadRawTableItems.clear();
3496 int nRows = _uploadRawTable->rowCount();
3497 std::vector <bool> flg(nRows);
3498 for (int iRow = 0; iRow < nRows; iRow++) {
3499 if (_uploadRawTable->item(iRow, 1)->isSelected()) {
3500 flg[iRow] = true;
3501 }
3502 else {
3503 flg[iRow] = false;
3504 }
3505 }
3506 for (int iRow = nRows - 1; iRow >= 0; iRow--) {
3507 if (flg[iRow]) {
3508 _uploadRawTable->removeRow(iRow);
3509 }
3510 }
3511 for (int iRow = 0; iRow < _uploadRawTable->rowCount(); iRow++) {
3512 BNC_CORE->_uploadRawTableItems[iRow] =
3513 (bncTableItem*)_uploadRawTable->item(iRow, 7);
3514 }
3515}
3516
3517//
3518////////////////////////////////////////////////////////////////////////////
3519void bncWindow::populateUploadRawTable() {
3520 for (int iRow = _uploadRawTable->rowCount() - 1; iRow >= 0; iRow--) {
3521 _uploadRawTable->removeRow(iRow);
3522 }
3523
3524 bncSettings settings;
3525
3526 int iRow = -1;
3527 QListIterator<QString> it(settings.value("uploadRawMountpointsOut").toStringList());
3528 while (it.hasNext()) {
3529 QStringList hlp = it.next().split(",");
3530 if (hlp.size() > 6) {
3531 ++iRow;
3532 _uploadRawTable->insertRow(iRow);
3533 }
3534 for (int iCol = 0; iCol < hlp.size(); iCol++) {
3535 if (iCol == 4) {
3536 QComboBox* ntripversion = new QComboBox();
3537 ntripversion->setEditable(false);
3538 ntripversion->addItems(QString("1,2,2s").split(","));
3539 ntripversion->setFrame(false);
3540 ntripversion->setCurrentIndex(ntripversion->findText(hlp[iCol]));
3541 _uploadRawTable->setCellWidget(iRow, iCol, ntripversion);
3542 }
3543 else if (iCol == 5) {
3544 QLineEdit* user = new QLineEdit();
3545 user->setFrame(false);
3546 user->setText(hlp[iCol]);
3547 _uploadRawTable->setCellWidget(iRow, iCol, user);
3548 }
3549 else if (iCol == 6) {
3550 QLineEdit* passwd = new QLineEdit();
3551 passwd->setFrame(false);
3552 passwd->setEchoMode(QLineEdit::PasswordEchoOnEdit);
3553 passwd->setText(hlp[iCol]);
3554 _uploadRawTable->setCellWidget(iRow, iCol, passwd);
3555 }
3556 else if (iCol == 7) {
3557 bncTableItem* bncIt = new bncTableItem();
3558 bncIt->setFlags(bncIt->flags() & ~Qt::ItemIsEditable);
3559 _uploadRawTable->setItem(iRow, iCol, bncIt);
3560 BNC_CORE->_uploadRawTableItems[iRow] = bncIt;
3561 }
3562 else {
3563 _uploadRawTable->setItem(iRow, iCol, new QTableWidgetItem(hlp[iCol]));
3564 }
3565 }
3566 }
3567}
3568
3569// Progress Bar Change
3570////////////////////////////////////////////////////////////////////////////
3571void bncWindow::slotPostProcessingProgress(int nEpo) {
3572 _actStart->setText(QString("%1 Epochs").arg(nEpo));
3573}
3574
3575// Post-Processing Reqc Finished
3576////////////////////////////////////////////////////////////////////////////
3577void bncWindow::slotPostProcessingFinished() {
3578 delete _caster; _caster = 0; BNC_CORE->setCaster(0);
3579 _runningPPP = false;
3580 _runningEdit = false;
3581 _runningQC = false;
3582 _runningSp3Comp = false;
3583 _actStart->setText(tr("Sta&rt"));
3584 enableStartStop();
3585}
3586
3587// Edit teqc-like editing options
3588////////////////////////////////////////////////////////////////////////////
3589void bncWindow::slotReqcEditOption() {
3590 saveOptions();
3591 reqcDlg* dlg = new reqcDlg(this);
3592 dlg->move(this->pos().x() + 50, this->pos().y() + 50);
3593 dlg->exec();
3594 delete dlg;
3595}
3596
3597// Enable/Disable Start and Stop Buttons
3598////////////////////////////////////////////////////////////////////////////
3599void bncWindow::enableStartStop() {
3600
3601 if (running()) {
3602 _actStart->setEnabled(false);
3603 if (_runningRealTime || _runningPPP) {
3604 _actStop->setEnabled(true);
3605 }
3606 }
3607 else {
3608 _actStart->setEnabled(true);
3609 _actStop->setEnabled(false);
3610 }
3611}
3612
3613// Show Map
3614////////////////////////////////////////////////////////////////////////////
3615void bncWindow::slotMapMountPoints() {
3616 saveOptions();
3617 t_bncMap* bncMap = new t_bncMap(this);
3618 bncMap->setMinimumSize(800, 600);
3619 bncMap->setWindowTitle("Selected Mountpoints");
3620
3621 bncSettings settings;
3622 QListIterator<QString> it(settings.value("mountPoints").toStringList());
3623 while (it.hasNext()) {
3624 QStringList hlp = it.next().split(" ");
3625 if (hlp.size() < 5) continue;
3626 QUrl url(hlp[0]);
3627 double latDeg = hlp[3].toDouble();
3628 double lonDeg = hlp[4].toDouble();
3629 bncMap->slotNewPoint(QFileInfo(url.path()).fileName(), latDeg, lonDeg);
3630 }
3631
3632 bncMap->show();
3633}
3634
3635// Show Map
3636////////////////////////////////////////////////////////////////////////////
3637void bncWindow::slotMapPPP() {
3638#ifdef QT_WEBENGINE
3639 saveOptions();
3640 enableWidget(false, _pppWidgets._mapWinButton);
3641 enableWidget(false, _pppWidgets._mapWinDotSize);
3642 enableWidget(false, _pppWidgets._mapWinDotColor);
3643
3644 if (!_mapWin) {
3645 _mapWin = new bncMapWin(this);
3646 connect(_mapWin, SIGNAL(mapClosed()), this, SLOT(slotMapPPPClosed()));
3647 connect(BNC_CORE, SIGNAL(newPosition(QByteArray, bncTime, QVector<double>)),
3648 _mapWin, SLOT(slotNewPosition(QByteArray, bncTime, QVector<double>)));
3649 }
3650 _mapWin->show();
3651#else
3652 QMessageBox::information(this, "Information",
3653 "Qt Library compiled without QT_WEBENGINE");
3654#endif
3655}
3656
3657// Show Map
3658////////////////////////////////////////////////////////////////////////////
3659void bncWindow::slotMapPPPClosed() {
3660#ifdef QT_WEBENGINE
3661 enableWidget(true, _pppWidgets._mapWinButton);
3662 enableWidget(true, _pppWidgets._mapWinDotSize);
3663 enableWidget(true, _pppWidgets._mapWinDotColor);
3664 if (_mapWin) {
3665 QListIterator<bncGetThread*> it(_threads);
3666 while (it.hasNext()) {
3667 bncGetThread* thread = it.next();
3668 thread->disconnect(_mapWin);
3669 }
3670 _mapWin->deleteLater();
3671 _mapWin = 0;
3672 }
3673#endif
3674}
Note: See TracBrowser for help on using the repository browser.