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

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