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

Last change on this file since 5955 was 5955, checked in by mervart, 10 years ago
File size: 118.9 KB
Line 
1// Part of BNC, a utility for retrieving decoding and
2// converting GNSS data streams from NTRIP broadcasters.
3//
4// Copyright (C) 2007
5// German Federal Agency for Cartography and Geodesy (BKG)
6// http://www.bkg.bund.de
7// Czech Technical University Prague, Department of Geodesy
8// http://www.fsv.cvut.cz
9//
10// Email: euref-ip@bkg.bund.de
11//
12// This program is free software; you can redistribute it and/or
13// modify it under the terms of the GNU General Public License
14// as published by the Free Software Foundation, version 2.
15//
16// This program is distributed in the hope that it will be useful,
17// but WITHOUT ANY WARRANTY; without even the implied warranty of
18// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19// GNU General Public License for more details.
20//
21// You should have received a copy of the GNU General Public License
22// along with this program; if not, write to the Free Software
23// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24
25/* -------------------------------------------------------------------------
26 * BKG NTRIP Client
27 * -------------------------------------------------------------------------
28 *
29 * Class: bncWindow
30 *
31 * Purpose: This class implements the main application window.
32 *
33 * Author: L. Mervart
34 *
35 * Created: 24-Dec-2005
36 *
37 * Changes:
38 *
39 * -----------------------------------------------------------------------*/
40
41#include <iostream>
42
43#include <unistd.h>
44#include "bncwindow.h"
45#include "bnccore.h"
46#include "bncgetthread.h"
47#include "bnctabledlg.h"
48#include "bncipport.h"
49#include "bncudpport.h"
50#include "bncserialport.h"
51#include "bnchlpdlg.h"
52#include "bnchtml.h"
53#include "bnctableitem.h"
54#include "bncsettings.h"
55#include "bncfigure.h"
56#include "bncfigurelate.h"
57#include "bncfigureppp.h"
58#include "bncversion.h"
59#include "bncbytescounter.h"
60#include "bncsslconfig.h"
61#include "upload/bnccustomtrafo.h"
62#include "upload/bncephuploadcaster.h"
63#include "qtfilechooser.h"
64#include "reqcdlg.h"
65#include "bncmap.h"
66#include "rinex/reqcedit.h"
67#include "rinex/reqcanalyze.h"
68#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);
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 ++ir;
874 pppLayout3->addWidget(new QLabel("Galileo LCs"), ir, 0, Qt::AlignLeft);
875 pppLayout3->addWidget(_pppWidgets._lcGalileo, ir, 1);
876 ++ir;
877 pppLayout3->addWidget(new QLabel("Wait for corrections"), ir, 0, Qt::AlignLeft);
878 pppLayout3->addWidget(_pppWidgets._corrWaitTime, ir, 1);
879 ++ir;
880 pppLayout3->addWidget(new QLabel(""), ir, 0);
881
882 pppGroup3->setLayout(pppLayout3);
883
884 // ------------------------
885 QVBoxLayout* pppLayout4 = new QVBoxLayout;
886 pppLayout4->addWidget(new QLabel("<b>Precise Point Positioning (Plots)</b>"));
887 pppLayout4->addSpacing(ww);
888
889 QHBoxLayout* pppLayout4Hlp1 = new QHBoxLayout;
890 pppLayout4Hlp1->addWidget(new QLabel("PPP Station "));
891 _pppWidgets._plotCoordinates->setMaximumWidth(8*ww);
892 pppLayout4Hlp1->addWidget(_pppWidgets._plotCoordinates);
893 pppLayout4Hlp1->addWidget(new QLabel("Nort-East-Up Time Series"));
894 pppLayout4Hlp1->addStretch();
895 pppLayout4->addLayout(pppLayout4Hlp1);
896 pppLayout4->addSpacing(ww);
897
898 QHBoxLayout* pppLayout4Hlp2 = new QHBoxLayout;
899 pppLayout4Hlp2->addWidget(new QLabel("Track Plot "));
900 connect(_pppWidgets._mapWinButton, SIGNAL(clicked()), SLOT(slotMapPPP()));
901 pppLayout4Hlp2->addWidget(_pppWidgets._mapWinButton);
902
903 pppLayout4Hlp2->addSpacing(1*ww);
904
905 pppLayout4Hlp2->addWidget(new QLabel("Google"));
906 pppLayout4Hlp2->addWidget(_pppWidgets._useGoogleMap);
907
908 pppLayout4Hlp2->addWidget(new QLabel("OSM"));
909 pppLayout4Hlp2->addWidget(_pppWidgets._useOpenStreetMap);
910
911 pppLayout4Hlp2->addSpacing(3*ww);
912
913 _pppWidgets._mapWinDotSize->setMaximumWidth(5*ww);
914 pppLayout4Hlp2->addWidget(_pppWidgets._mapWinDotSize);
915
916 pppLayout4Hlp2->addSpacing(3*ww);
917
918 pppLayout4Hlp2->addWidget(_pppWidgets._mapWinDotColor);
919
920 pppLayout4Hlp2->addSpacing(3*ww);
921
922 pppLayout4Hlp2->addWidget(new QLabel("Speed"));
923 pppLayout4Hlp2->addWidget(_pppWidgets._mapSpeedSlider);
924
925 pppLayout4Hlp2->addStretch();
926 pppLayout4->addLayout(pppLayout4Hlp2);
927
928 pppLayout4->addStretch();
929 pppGroup4->setLayout(pppLayout4);
930
931 // Reqc Processing
932 // ---------------
933 _reqcActionComboBox = new QComboBox();
934 _reqcActionComboBox->setEditable(false);
935 _reqcActionComboBox->addItems(QString(",Edit/Concatenate,Analyze").split(","));
936 int ik = _reqcActionComboBox->findText(settings.value("reqcAction").toString());
937 if (ik != -1) {
938 _reqcActionComboBox->setCurrentIndex(ik);
939 }
940 connect(_reqcActionComboBox, SIGNAL(currentIndexChanged(const QString &)),
941 this, SLOT(slotBncTextChanged()));
942
943 QGridLayout* reqcLayout = new QGridLayout;
944 _reqcActionComboBox->setMinimumWidth(15*ww);
945 _reqcActionComboBox->setMaximumWidth(15*ww);
946
947 _reqcObsFileChooser = new qtFileChooser(0, qtFileChooser::Files);
948 _reqcObsFileChooser->setFileName(settings.value("reqcObsFile").toString());
949 _reqcObsFileChooser->setWhatsThis(tr("Specify the full path to an observation file in RINEX v2 or v3 format."));
950 _reqcObsFileChooser->setMinimumWidth(15*ww);
951 _reqcObsFileChooser->setMaximumWidth(15*ww);
952
953 _reqcNavFileChooser = new qtFileChooser(0, qtFileChooser::Files);
954 _reqcNavFileChooser->setFileName(settings.value("reqcNavFile").toString());
955 _reqcNavFileChooser->setWhatsThis(tr("Specify the full path to a RINEX v2 or v3 navigation file."));
956 _reqcNavFileChooser->setMinimumWidth(15*ww);
957 _reqcNavFileChooser->setMaximumWidth(15*ww);
958
959 _reqcOutObsLineEdit = new QLineEdit(settings.value("reqcOutObsFile").toString());
960 _reqcOutObsLineEdit->setWhatsThis(tr("Specify the full path to a RINEX observation output file."));
961 _reqcOutObsLineEdit->setMinimumWidth(15*ww);
962 _reqcOutObsLineEdit->setMaximumWidth(15*ww);
963
964 _reqcOutNavLineEdit = new QLineEdit(settings.value("reqcOutNavFile").toString());
965 _reqcOutNavLineEdit->setWhatsThis(tr("Specify the full path to a RINEX navigation output file."));
966 _reqcOutNavLineEdit->setMinimumWidth(15*ww);
967 _reqcOutNavLineEdit->setMaximumWidth(15*ww);
968
969 _reqcOutLogLineEdit = new QLineEdit(settings.value("reqcOutLogFile").toString());
970 _reqcOutLogLineEdit->setWhatsThis(tr("Specify the full path to a logfile."));
971 _reqcOutLogLineEdit->setMinimumWidth(15*ww);
972 _reqcOutLogLineEdit->setMaximumWidth(15*ww);
973
974 _reqcPlotDirLineEdit = new QLineEdit(settings.value("reqcPlotDir").toString());
975 _reqcPlotDirLineEdit->setWhatsThis(tr("Specify the directory name for saving plots."));
976 _reqcPlotDirLineEdit->setMinimumWidth(15*ww);
977 _reqcPlotDirLineEdit->setMaximumWidth(15*ww);
978
979 _reqcSkyPlotSystems = new QComboBox();
980 _reqcSkyPlotSystems->setEditable(false);
981 _reqcSkyPlotSystems->addItems(QString("ALL,GPS,GLONASS,Galileo").split(","));
982 ik = _reqcSkyPlotSystems->findText(settings.value("reqcSkyPlotSystems").toString());
983 if (ik != -1) {
984 _reqcSkyPlotSystems->setCurrentIndex(ik);
985 }
986
987 ir = 0;
988 reqcLayout->addWidget(new QLabel("RINEX file editing, concatenation and quality check."),ir, 0, 1, 20);
989 ++ir;
990 reqcLayout->addWidget(new QLabel("Action"), ir, 0, Qt::AlignLeft);
991 reqcLayout->addWidget(_reqcActionComboBox, ir, 1, Qt::AlignLeft);
992 _reqcEditOptionButton = new QPushButton("Set Edit Options");
993 reqcLayout->addWidget(_reqcEditOptionButton, ir, 3, Qt::AlignRight);
994 ++ir;
995 reqcLayout->addWidget(new QLabel("Input files (full path)"), ir, 0, Qt::AlignLeft);
996 reqcLayout->addWidget(_reqcObsFileChooser, ir, 1, Qt::AlignRight);
997 reqcLayout->addWidget(new QLabel("Obs"), ir, 2, Qt::AlignLeft);
998 reqcLayout->addWidget(_reqcNavFileChooser, ir, 3, Qt::AlignRight);
999 reqcLayout->addWidget(new QLabel("Nav"), ir, 4, Qt::AlignLeft);
1000 ++ir;
1001 reqcLayout->addWidget(new QLabel("Output files (full path)"), ir, 0, Qt::AlignLeft);
1002 reqcLayout->addWidget(_reqcOutObsLineEdit, ir, 1, Qt::AlignRight);
1003 reqcLayout->addWidget(new QLabel("Obs"), ir, 2, Qt::AlignLeft);
1004 reqcLayout->addWidget(_reqcOutNavLineEdit, ir, 3, Qt::AlignRight);
1005 reqcLayout->addWidget(new QLabel("Nav"), ir, 4, Qt::AlignLeft);
1006 ++ir;
1007 reqcLayout->addWidget(_reqcOutLogLineEdit, ir, 1, Qt::AlignRight);
1008 reqcLayout->addWidget(new QLabel("Log"), ir, 2, Qt::AlignLeft);
1009 ++ir;
1010 reqcLayout->addWidget(new QLabel("Directory for plots"), ir, 0, Qt::AlignLeft);
1011 reqcLayout->addWidget(_reqcPlotDirLineEdit, ir, 1, Qt::AlignRight);
1012 ++ir;
1013 reqcLayout->addWidget(new QLabel("Sky plots for"), ir, 0, Qt::AlignLeft);
1014 reqcLayout->addWidget(_reqcSkyPlotSystems, ir, 1, Qt::AlignRight);
1015 ++ir;
1016 reqcLayout->addWidget(new QLabel(""), ir, 1);
1017 reqcLayout->setRowStretch(ir, 999);
1018
1019 reqcLayout->setColumnMinimumWidth(2, 8*ww);
1020 reqcLayout->setColumnMinimumWidth(4, 8*ww);
1021
1022 reqcgroup->setLayout(reqcLayout);
1023
1024 connect(_reqcEditOptionButton, SIGNAL(clicked()),
1025 this, SLOT(slotReqcEditOption()));
1026
1027 // Combine Corrections
1028 // -------------------
1029 QGridLayout* cmbLayout = new QGridLayout;
1030
1031 populateCmbTable();
1032 cmbLayout->addWidget(_cmbTable, 0, 0, 6, 3);
1033 cmbLayout->addWidget(new QLabel(" "), 0, 5);
1034 cmbLayout->addWidget(new QLabel("Combine Broadcast Correction streams."), 0, 6, 1, 50);
1035 cmbLayout->addWidget(new QLabel(" "), 1, 5);
1036 cmbLayout->addWidget(addCmbRowButton, 1, 6);
1037 cmbLayout->addWidget(delCmbRowButton, 1, 7);
1038 cmbLayout->addWidget(new QLabel(" "), 2, 5);
1039 cmbLayout->addWidget(new QLabel("Method"), 2, 6, Qt::AlignRight);
1040 cmbLayout->addWidget(_cmbMethodComboBox, 2, 7, Qt::AlignRight);
1041 cmbLayout->addWidget(new QLabel(" "), 3, 5);
1042 cmbLayout->addWidget(new QLabel("Maximal Residuum"), 3, 6, Qt::AlignRight);
1043 cmbLayout->addWidget(_cmbMaxresLineEdit, 3, 7, Qt::AlignRight);
1044 cmbLayout->addWidget(new QLabel(" "), 4, 5);
1045 cmbLayout->addWidget(new QLabel("Sampling"), 4, 6, Qt::AlignRight);
1046 cmbLayout->addWidget(_cmbSamplSpinBox, 4, 7, Qt::AlignRight);
1047 cmbLayout->addWidget(new QLabel(" "), 5, 0);
1048
1049 connect(addCmbRowButton, SIGNAL(clicked()), this, SLOT(slotAddCmbRow()));
1050 connect(delCmbRowButton, SIGNAL(clicked()), this, SLOT(slotDelCmbRow()));
1051
1052 cmbgroup->setLayout(cmbLayout);
1053
1054 // Upload Layout (Clocks)
1055 // ----------------------
1056 QGridLayout* uploadHlpLayout = new QGridLayout();
1057
1058 connect(addUploadRowButton, SIGNAL(clicked()), this, SLOT(slotAddUploadRow()));
1059 connect(delUploadRowButton, SIGNAL(clicked()), this, SLOT(slotDelUploadRow()));
1060 connect(setUploadTrafoButton, SIGNAL(clicked()), this, SLOT(slotSetUploadTrafo()));
1061
1062 uploadHlpLayout->addWidget(addUploadRowButton, 0, 0);
1063 uploadHlpLayout->addWidget(delUploadRowButton, 0, 1);
1064 uploadHlpLayout->addWidget(new QLabel("Interval"), 0, 2, Qt::AlignRight);
1065 uploadHlpLayout->addWidget(_uploadIntrComboBox, 0, 3);
1066 uploadHlpLayout->addWidget(new QLabel(" Sampling: Orb"), 0, 4, Qt::AlignRight);
1067 uploadHlpLayout->addWidget(_uploadSamplRtcmEphCorrSpinBox, 0, 5);
1068 uploadHlpLayout->addWidget(new QLabel("SP3"), 0, 6, Qt::AlignRight);
1069 uploadHlpLayout->addWidget(_uploadSamplSp3SpinBox, 0, 7);
1070 uploadHlpLayout->addWidget(new QLabel("RNX"), 0, 8, Qt::AlignRight);
1071 uploadHlpLayout->addWidget(_uploadSamplClkRnxSpinBox, 0, 9);
1072 uploadHlpLayout->addWidget(setUploadTrafoButton, 0,10);
1073
1074 QBoxLayout* uploadLayout = new QBoxLayout(QBoxLayout::TopToBottom);
1075 populateUploadTable();
1076
1077 uploadLayout->addWidget(new QLabel("Upload RTCMv3 Broadcast Corrections to caster."));
1078 uploadLayout->addWidget(_uploadTable);
1079 uploadLayout->addLayout(uploadHlpLayout);
1080
1081 uploadgroup->setLayout(uploadLayout);
1082
1083 // Upload Layout (Ephemeris)
1084 // -------------------------
1085 QGridLayout* uploadLayoutEph = new QGridLayout;
1086
1087 uploadLayoutEph->setColumnMinimumWidth(0, 9*ww);
1088 _uploadEphPortLineEdit->setMaximumWidth(9*ww);
1089 _uploadEphPasswordLineEdit->setMaximumWidth(9*ww);
1090 _uploadEphMountpointLineEdit->setMaximumWidth(12*ww);
1091
1092 uploadLayoutEph->addWidget(new QLabel("Upload concatenated RTCMv3 Broadcast Ephemeris to caster."), 0, 0, 1, 50);
1093 uploadLayoutEph->addWidget(new QLabel("Host"), 1, 0);
1094 uploadLayoutEph->addWidget(_uploadEphHostLineEdit, 1, 1, 1, 3);
1095 uploadLayoutEph->addWidget(new QLabel(" Port"), 1, 4, Qt::AlignRight);
1096 uploadLayoutEph->addWidget(_uploadEphPortLineEdit, 1, 5, 1, 1);
1097 uploadLayoutEph->addWidget(new QLabel("Mountpoint "), 2, 0);
1098 uploadLayoutEph->addWidget(_uploadEphMountpointLineEdit, 2, 1);
1099 uploadLayoutEph->addWidget(new QLabel(" Password"), 2, 2, Qt::AlignRight);
1100 uploadLayoutEph->addWidget(_uploadEphPasswordLineEdit, 2, 3);
1101 uploadLayoutEph->addWidget(new QLabel("Sampling"), 3, 0);
1102 uploadLayoutEph->addWidget(_uploadEphSampleSpinBox, 3, 1);
1103 uploadLayoutEph->addWidget(new QLabel("Uploaded"), 4, 0);
1104 uploadLayoutEph->addWidget(_uploadEphBytesCounter, 4, 1);
1105 uploadLayoutEph->addWidget(new QLabel(" "), 5, 0);
1106 uploadLayoutEph->addWidget(new QLabel(" "), 6, 0);
1107
1108 uploadEphgroup->setLayout(uploadLayoutEph);
1109
1110 connect(_uploadEphHostLineEdit, SIGNAL(textChanged(const QString &)),
1111 this, SLOT(slotBncTextChanged()));
1112
1113 // Main Layout
1114 // -----------
1115 QGridLayout* mLayout = new QGridLayout;
1116 _aogroup->setCurrentIndex(settings.value("startTab").toInt());
1117 mLayout->addWidget(_aogroup, 0,0);
1118 mLayout->addWidget(_mountPointsTable, 1,0);
1119 _loggroup->setCurrentIndex(settings.value("statusTab").toInt());
1120 mLayout->addWidget(_loggroup, 2,0);
1121
1122 _canvas->setLayout(mLayout);
1123
1124 // WhatsThis
1125 // ---------
1126 _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>"));
1127 _proxyPortLineEdit->setWhatsThis(tr("<p>Enter your proxy server port number in case a proxy is operated in front of BNC.</p>"));
1128 _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>"));
1129 _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>"));
1130 _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>"));
1131 _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."));
1132 _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."));
1133 _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."));
1134 _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."));
1135 _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."));
1136 _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>"));
1137 _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."));
1138 _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."));
1139 _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."));
1140 _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>"));
1141 _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>"));
1142 _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>"));
1143 _autoStartCheckBox->setWhatsThis(tr("<p>Tick 'Auto start' for auto-start of BNC at startup time in window mode with preassigned processing options.</p>"));
1144 _rawOutFileLineEdit->setWhatsThis(tr("<p>Save all data coming in through various streams in the received order and format in one file.</p>"));
1145 _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>"));
1146 _rnxIntrComboBox->setWhatsThis(tr("<p>Select the length of the RINEX Observation file.</p>"));
1147 _ephIntrComboBox->setWhatsThis(tr("<p>Select the length of the RINEX Navigation file.</p>"));
1148 _corrIntrComboBox->setWhatsThis(tr("<p>Select the length of the Broadcast Ephemeris Correction files.</p>"));
1149 _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>"));
1150 _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>"));
1151 _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>"));
1152 _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>"));
1153 _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>"));
1154 _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."));
1155 _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>"));
1156 _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>"));
1157 _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>"));
1158 _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."));
1159 _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)."));
1160 _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."));
1161 _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."));
1162 _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."));
1163 _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>"));
1164 _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."));
1165 _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>."));
1166 _serialMountPointLineEdit->setWhatsThis(tr("<p>Enter a 'Mountpoint' to forward the corresponding stream to a serial connected receiver.</p>"));
1167 _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>"));
1168 _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>"));
1169 _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>"));
1170 _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>"));
1171 _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>"));
1172 _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>"));
1173 _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>"));
1174 _serialFileNMEALineEdit->setWhatsThis(tr("<p>Specify the full path to a file where NMEA messages coming from your serial connected receiver are saved.</p>"));
1175 _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>"));
1176 _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>"));
1177 _reqcEditOptionButton->setWhatsThis(tr("<p>Specify options for editing RINEX v2 or v3 files.</p>"));
1178 _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."));
1179 _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."));
1180 _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>"));
1181 _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>"));
1182 _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>"));
1183 _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>"));
1184 addCmbRowButton->setWhatsThis(tr("Hit 'Add Row' button to add another line to the mountpoints table."));
1185 delCmbRowButton->setWhatsThis(tr("Hit 'Delete' button to delete the highlighted line from the mountpoints table."));
1186 addUploadRowButton->setWhatsThis(tr("Hit 'Add Row' button to add another line to the stream upload table."));
1187 delUploadRowButton->setWhatsThis(tr("Hit 'Del Row' button to delete the highlighted line from the stream upload table."));
1188 _uploadIntrComboBox->setWhatsThis(tr("Select the length of the SP3 and Clock RINEX files."));
1189 _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."));
1190 _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."));
1191 _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."));
1192 setUploadTrafoButton->setWhatsThis(tr("Hit 'Custom Trafo' to specify your own 14 parameter Helmert Transformation instead of selecting a predefined transformation through 'System' button."));
1193 _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."));
1194 _uploadEphPortLineEdit->setWhatsThis(tr("Specify the IP port of an NTRIP Broadcaster to upload the stream. Default is port 80."));
1195 _uploadEphMountpointLineEdit->setWhatsThis(tr("Specify the mounpoint for stream upload to an NTRIP Broadcaster."));
1196 _uploadEphPasswordLineEdit->setWhatsThis(tr("Specify the stream upload password protecting the mounpoint on an NTRIP Broadcaster."));
1197 _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."));
1198 _uploadEphBytesCounter->setWhatsThis(tr("BNC shows the amount of data uploaded through this stream."));
1199 _actDeleteMountPoints->setWhatsThis(tr("<p>Delete stream(s) from selection presented in the 'Streams' canvas.</p>"));
1200 _actAddMountPoints->setWhatsThis(tr("<p>Add stream(s) to selection presented in the 'Streams' canvas.</p>"));
1201 _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>"));
1202 _actStart->setWhatsThis(tr("<p> Start running BNC.</p>"));
1203 _actStop->setWhatsThis(tr("<p> Stop running BNC.</p>"));
1204// Weber
1205
1206 // Enable/Disable all Widgets
1207 // --------------------------
1208 slotBncTextChanged();
1209 enableStartStop();
1210
1211 // Auto start
1212 // ----------
1213 if ( Qt::CheckState(settings.value("autoStart").toInt()) == Qt::Checked) {
1214 slotStart();
1215 }
1216}
1217
1218// Destructor
1219////////////////////////////////////////////////////////////////////////////
1220bncWindow::~bncWindow() {
1221 delete _caster; BNC_CORE->setCaster(0);
1222 delete _casterEph;
1223}
1224
1225//
1226////////////////////////////////////////////////////////////////////////////
1227void bncWindow::populateMountPointsTable() {
1228
1229 for (int iRow = _mountPointsTable->rowCount()-1; iRow >=0; iRow--) {
1230 _mountPointsTable->removeRow(iRow);
1231 }
1232
1233 bncSettings settings;
1234
1235 QListIterator<QString> it(settings.value("mountPoints").toStringList());
1236 int iRow = 0;
1237 while (it.hasNext()) {
1238 QStringList hlp = it.next().split(" ");
1239 if (hlp.size() < 5) continue;
1240 _mountPointsTable->insertRow(iRow);
1241
1242 QUrl url(hlp[0]);
1243
1244 QString fullPath = url.host() + QString(":%1").arg(url.port()) + url.path();
1245 QString format(hlp[1]); QString latitude(hlp[2]); QString longitude(hlp[3]);
1246 QString nmea(hlp[4]);
1247 if (hlp[5] == "S") {
1248 fullPath = hlp[0].replace(0,2,"");
1249 }
1250 QString ntripVersion = "2";
1251 if (hlp.size() >= 6) {
1252 ntripVersion = (hlp[5]);
1253 }
1254
1255 QTableWidgetItem* it;
1256 it = new QTableWidgetItem(url.userInfo());
1257 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
1258 _mountPointsTable->setItem(iRow, 0, it);
1259
1260 it = new QTableWidgetItem(fullPath);
1261 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
1262 _mountPointsTable->setItem(iRow, 1, it);
1263
1264 it = new QTableWidgetItem(format);
1265 _mountPointsTable->setItem(iRow, 2, it);
1266
1267 if (nmea == "yes") {
1268 it = new QTableWidgetItem(latitude);
1269 _mountPointsTable->setItem(iRow, 3, it);
1270 it = new QTableWidgetItem(longitude);
1271 _mountPointsTable->setItem(iRow, 4, it);
1272 } else {
1273 it = new QTableWidgetItem(latitude);
1274 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
1275 _mountPointsTable->setItem(iRow, 3, it);
1276 it = new QTableWidgetItem(longitude);
1277 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
1278 _mountPointsTable->setItem(iRow, 4, it);
1279 }
1280
1281 it = new QTableWidgetItem(nmea);
1282 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
1283 _mountPointsTable->setItem(iRow, 5, it);
1284
1285 it = new QTableWidgetItem(ntripVersion);
1286 //// it->setFlags(it->flags() & ~Qt::ItemIsEditable);
1287 _mountPointsTable->setItem(iRow, 6, it);
1288
1289 bncTableItem* bncIt = new bncTableItem();
1290 bncIt->setFlags(bncIt->flags() & ~Qt::ItemIsEditable);
1291 _mountPointsTable->setItem(iRow, 7, bncIt);
1292
1293 iRow++;
1294 }
1295
1296 _mountPointsTable->sortItems(1);
1297
1298 enableStartStop();
1299}
1300
1301// Retrieve Table
1302////////////////////////////////////////////////////////////////////////////
1303void bncWindow::slotAddMountPoints() {
1304
1305 bncSettings settings;
1306 QString proxyHost = settings.value("proxyHost").toString();
1307 int proxyPort = settings.value("proxyPort").toInt();
1308 if (proxyHost != _proxyHostLineEdit->text() ||
1309 proxyPort != _proxyPortLineEdit->text().toInt()) {
1310 int iRet = QMessageBox::question(this, "Question", "Proxy options "
1311 "changed. Use the new ones?",
1312 QMessageBox::Yes, QMessageBox::No,
1313 QMessageBox::NoButton);
1314 if (iRet == QMessageBox::Yes) {
1315 settings.setValue("proxyHost", _proxyHostLineEdit->text());
1316 settings.setValue("proxyPort", _proxyPortLineEdit->text());
1317 }
1318 }
1319
1320 settings.setValue("sslCaCertPath", _sslCaCertPathLineEdit->text());
1321 settings.setValue("ignoreSslErrors", _ignoreSslErrorsCheckBox->checkState());
1322
1323 QMessageBox msgBox;
1324 msgBox.setIcon(QMessageBox::Question);
1325 msgBox.setWindowTitle("Add Stream");
1326 msgBox.setText("Add stream(s) coming from:");
1327
1328 QPushButton* buttonNtrip = msgBox.addButton(tr("Caster"), QMessageBox::ActionRole);
1329 QPushButton* buttonIP = msgBox.addButton(tr("TCP/IP port"), QMessageBox::ActionRole);
1330 QPushButton* buttonUDP = msgBox.addButton(tr("UDP port"), QMessageBox::ActionRole);
1331 QPushButton* buttonSerial = msgBox.addButton(tr("Serial port"), QMessageBox::ActionRole);
1332 QPushButton* buttonCancel = msgBox.addButton(tr("Cancel"), QMessageBox::ActionRole);
1333
1334 msgBox.exec();
1335
1336 if (msgBox.clickedButton() == buttonNtrip) {
1337 bncTableDlg* dlg = new bncTableDlg(this);
1338 dlg->move(this->pos().x()+50, this->pos().y()+50);
1339 connect(dlg, SIGNAL(newMountPoints(QStringList*)),
1340 this, SLOT(slotNewMountPoints(QStringList*)));
1341 dlg->exec();
1342 delete dlg;
1343 } else if (msgBox.clickedButton() == buttonIP) {
1344 bncIpPort* ipp = new bncIpPort(this);
1345 connect(ipp, SIGNAL(newMountPoints(QStringList*)),
1346 this, SLOT(slotNewMountPoints(QStringList*)));
1347 ipp->exec();
1348 delete ipp;
1349 } else if (msgBox.clickedButton() == buttonUDP) {
1350 bncUdpPort* udp = new bncUdpPort(this);
1351 connect(udp, SIGNAL(newMountPoints(QStringList*)),
1352 this, SLOT(slotNewMountPoints(QStringList*)));
1353 udp->exec();
1354 delete udp;
1355 } else if (msgBox.clickedButton() == buttonSerial) {
1356 bncSerialPort* sep = new bncSerialPort(this);
1357 connect(sep, SIGNAL(newMountPoints(QStringList*)),
1358 this, SLOT(slotNewMountPoints(QStringList*)));
1359 sep->exec();
1360 delete sep;
1361 } else if (msgBox.clickedButton() == buttonCancel) {
1362 // Cancel
1363 }
1364
1365 enableStartStop();
1366}
1367
1368// Delete Selected Mount Points
1369////////////////////////////////////////////////////////////////////////////
1370void bncWindow::slotDeleteMountPoints() {
1371
1372 int nRows = _mountPointsTable->rowCount();
1373 bool flg[nRows];
1374 for (int iRow = 0; iRow < nRows; iRow++) {
1375 if (_mountPointsTable->isItemSelected(_mountPointsTable->item(iRow,1))) {
1376 flg[iRow] = true;
1377 }
1378 else {
1379 flg[iRow] = false;
1380 }
1381 }
1382 for (int iRow = nRows-1; iRow >= 0; iRow--) {
1383 if (flg[iRow]) {
1384 _mountPointsTable->removeRow(iRow);
1385 }
1386 }
1387 _actDeleteMountPoints->setEnabled(false);
1388
1389 enableStartStop();
1390}
1391
1392// New Mount Points Selected
1393////////////////////////////////////////////////////////////////////////////
1394void bncWindow::slotNewMountPoints(QStringList* mountPoints) {
1395 int iRow = 0;
1396 QListIterator<QString> it(*mountPoints);
1397 while (it.hasNext()) {
1398 QStringList hlp = it.next().split(" ");
1399 QUrl url(hlp[0]);
1400 QString fullPath = url.host() + QString(":%1").arg(url.port()) + url.path();
1401 QString format(hlp[1]); QString latitude(hlp[2]); QString longitude(hlp[3]);
1402 QString nmea(hlp[4]);
1403 if (hlp[5] == "S") {
1404 fullPath = hlp[0].replace(0,2,"");
1405 }
1406 QString ntripVersion = "2";
1407 if (hlp.size() >= 6) {
1408 ntripVersion = (hlp[5]);
1409 }
1410
1411 _mountPointsTable->insertRow(iRow);
1412
1413 QTableWidgetItem* it;
1414 it = new QTableWidgetItem(url.userInfo());
1415 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
1416 _mountPointsTable->setItem(iRow, 0, it);
1417
1418 it = new QTableWidgetItem(fullPath);
1419 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
1420 _mountPointsTable->setItem(iRow, 1, it);
1421
1422 it = new QTableWidgetItem(format);
1423 _mountPointsTable->setItem(iRow, 2, it);
1424
1425 if (nmea == "yes") {
1426 it = new QTableWidgetItem(latitude);
1427 _mountPointsTable->setItem(iRow, 3, it);
1428 it = new QTableWidgetItem(longitude);
1429 _mountPointsTable->setItem(iRow, 4, it);
1430 } else {
1431 it = new QTableWidgetItem(latitude);
1432 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
1433 _mountPointsTable->setItem(iRow, 3, it);
1434 it = new QTableWidgetItem(longitude);
1435 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
1436 _mountPointsTable->setItem(iRow, 4, it);
1437 }
1438
1439 it = new QTableWidgetItem(nmea);
1440 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
1441 _mountPointsTable->setItem(iRow, 5, it);
1442
1443 it = new QTableWidgetItem(ntripVersion);
1444 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
1445 _mountPointsTable->setItem(iRow, 6, it);
1446
1447 bncTableItem* bncIt = new bncTableItem();
1448 _mountPointsTable->setItem(iRow, 7, bncIt);
1449
1450 iRow++;
1451 }
1452 _mountPointsTable->hideColumn(0);
1453 _mountPointsTable->sortItems(1);
1454 delete mountPoints;
1455
1456 enableStartStop();
1457}
1458
1459// Save Options (serialize)
1460////////////////////////////////////////////////////////////////////////////
1461void bncWindow::slotSaveOptions() {
1462 saveOptions();
1463 bncSettings settings;
1464 settings.sync();
1465}
1466
1467// Save Options (memory only)
1468////////////////////////////////////////////////////////////////////////////
1469void bncWindow::saveOptions() {
1470
1471 QStringList mountPoints;
1472 for (int iRow = 0; iRow < _mountPointsTable->rowCount(); iRow++) {
1473
1474 if (_mountPointsTable->item(iRow, 6)->text() != "S") {
1475 QUrl url( "//" + _mountPointsTable->item(iRow, 0)->text() +
1476 "@" + _mountPointsTable->item(iRow, 1)->text() );
1477
1478 mountPoints.append(url.toString() + " " +
1479 _mountPointsTable->item(iRow, 2)->text()
1480 + " " + _mountPointsTable->item(iRow, 3)->text()
1481 + " " + _mountPointsTable->item(iRow, 4)->text()
1482 + " " + _mountPointsTable->item(iRow, 5)->text()
1483 + " " + _mountPointsTable->item(iRow, 6)->text());
1484 } else {
1485 mountPoints.append(
1486 "//" + _mountPointsTable->item(iRow, 1)->text()
1487 + " " + _mountPointsTable->item(iRow, 2)->text()
1488 + " " + _mountPointsTable->item(iRow, 3)->text()
1489 + " " + _mountPointsTable->item(iRow, 4)->text()
1490 + " " + _mountPointsTable->item(iRow, 5)->text()
1491 + " " + _mountPointsTable->item(iRow, 6)->text());
1492 }
1493 }
1494
1495 QStringList combineStreams;
1496 for (int iRow = 0; iRow < _cmbTable->rowCount(); iRow++) {
1497 QString hlp;
1498 for (int iCol = 0; iCol < _cmbTable->columnCount(); iCol++) {
1499 if (_cmbTable->item(iRow, iCol)) {
1500 hlp += _cmbTable->item(iRow, iCol)->text() + " ";
1501 }
1502 }
1503 if (!hlp.isEmpty()) {
1504 combineStreams << hlp;
1505 }
1506 }
1507
1508 QStringList uploadMountpointsOut;
1509 for (int iRow = 0; iRow < _uploadTable->rowCount(); iRow++) {
1510 QString hlp;
1511 for (int iCol = 0; iCol < _uploadTable->columnCount(); iCol++) {
1512 if (_uploadTable->cellWidget(iRow, iCol) &&
1513 (iCol == 3 || iCol == 4 || iCol == 5)) {
1514 if (iCol == 3) {
1515 QLineEdit* passwd = (QLineEdit*)(_uploadTable->cellWidget(iRow, iCol));
1516 hlp += passwd->text() + ",";
1517 }
1518 else if (iCol == 4) {
1519 QComboBox* system = (QComboBox*)(_uploadTable->cellWidget(iRow, iCol));
1520 hlp += system->currentText() + ",";
1521 }
1522 else if (iCol == 5) {
1523 QCheckBox* com = (QCheckBox*)(_uploadTable->cellWidget(iRow, iCol));
1524 QString state; state.setNum(com->checkState());
1525 hlp += state + ",";
1526 }
1527 }
1528 else if (_uploadTable->item(iRow, iCol)) {
1529 hlp += _uploadTable->item(iRow, iCol)->text() + ",";
1530 }
1531 }
1532 if (!hlp.isEmpty()) {
1533 uploadMountpointsOut << hlp;
1534 }
1535 }
1536
1537 bncSettings settings;
1538
1539 settings.setValue("startTab", _aogroup->currentIndex());
1540 settings.setValue("statusTab", _loggroup->currentIndex());
1541 settings.setValue("mountPoints", mountPoints);
1542// Network
1543 settings.setValue("proxyHost", _proxyHostLineEdit->text());
1544 settings.setValue("proxyPort", _proxyPortLineEdit->text());
1545 settings.setValue("sslCaCertPath", _sslCaCertPathLineEdit->text());
1546 settings.setValue("ignoreSslErrors", _ignoreSslErrorsCheckBox->checkState());
1547// General
1548 settings.setValue("logFile", _logFileLineEdit->text());
1549 settings.setValue("rnxAppend", _rnxAppendCheckBox->checkState());
1550 settings.setValue("onTheFlyInterval", _onTheFlyComboBox->currentText());
1551 settings.setValue("autoStart", _autoStartCheckBox->checkState());
1552 settings.setValue("rawOutFile", _rawOutFileLineEdit->text());
1553// RINEX Observations
1554 settings.setValue("rnxPath", _rnxPathLineEdit->text());
1555 settings.setValue("rnxIntr", _rnxIntrComboBox->currentText());
1556 settings.setValue("rnxSampl", _rnxSamplSpinBox->value());
1557 settings.setValue("rnxSkel", _rnxSkelLineEdit->text());
1558 settings.setValue("rnxScript", _rnxScrpLineEdit->text());
1559 settings.setValue("rnxV3", _rnxV3CheckBox->checkState());
1560// RINEX Ephemeris
1561 settings.setValue("ephPath", _ephPathLineEdit->text());
1562 settings.setValue("ephIntr", _ephIntrComboBox->currentText());
1563 settings.setValue("outEphPort", _outEphPortLineEdit->text());
1564 settings.setValue("ephV3", _ephV3CheckBox->checkState());
1565// Broadcast Corrections
1566 settings.setValue("corrPath", _corrPathLineEdit->text());
1567 settings.setValue("corrIntr", _corrIntrComboBox->currentText());
1568 settings.setValue("corrPort", _corrPortLineEdit->text());
1569 settings.setValue("corrTime", _corrTimeSpinBox->value());
1570// Feed Engine
1571 settings.setValue("outPort", _outPortLineEdit->text());
1572 settings.setValue("waitTime", _waitTimeSpinBox->value());
1573 settings.setValue("binSampl", _binSamplSpinBox->value());
1574 settings.setValue("outFile", _outFileLineEdit->text());
1575 settings.setValue("outUPort", _outUPortLineEdit->text());
1576// Serial Output
1577 settings.setValue("serialMountPoint",_serialMountPointLineEdit->text());
1578 settings.setValue("serialPortName", _serialPortNameLineEdit->text());
1579 settings.setValue("serialBaudRate", _serialBaudRateComboBox->currentText());
1580 settings.setValue("serialFlowControl",_serialFlowControlComboBox->currentText());
1581 settings.setValue("serialDataBits", _serialDataBitsComboBox->currentText());
1582 settings.setValue("serialParity", _serialParityComboBox->currentText());
1583 settings.setValue("serialStopBits", _serialStopBitsComboBox->currentText());
1584 settings.setValue("serialAutoNMEA", _serialAutoNMEAComboBox->currentText());
1585 settings.setValue("serialFileNMEA",_serialFileNMEALineEdit->text());
1586 settings.setValue("serialHeightNMEA",_serialHeightNMEALineEdit->text());
1587// Outages
1588 settings.setValue("obsRate", _obsRateComboBox->currentText());
1589 settings.setValue("adviseFail", _adviseFailSpinBox->value());
1590 settings.setValue("adviseReco", _adviseRecoSpinBox->value());
1591 settings.setValue("adviseScript",_adviseScriptLineEdit->text());
1592// Miscellaneous
1593 settings.setValue("miscMount", _miscMountLineEdit->text());
1594 settings.setValue("miscPort", _miscPortLineEdit->text());
1595 settings.setValue("perfIntr", _perfIntrComboBox->currentText());
1596 settings.setValue("scanRTCM", _scanRTCMCheckBox->checkState());
1597// Reqc
1598 settings.setValue("reqcAction", _reqcActionComboBox->currentText());
1599 settings.setValue("reqcObsFile", _reqcObsFileChooser->fileName());
1600 settings.setValue("reqcNavFile", _reqcNavFileChooser->fileName());
1601 settings.setValue("reqcOutObsFile", _reqcOutObsLineEdit->text());
1602 settings.setValue("reqcOutNavFile", _reqcOutNavLineEdit->text());
1603 settings.setValue("reqcOutLogFile", _reqcOutLogLineEdit->text());
1604 settings.setValue("reqcPlotDir", _reqcPlotDirLineEdit->text());
1605 settings.setValue("reqcSkyPlotSystems", _reqcSkyPlotSystems->currentText());
1606// Combine Corrections
1607 if (!combineStreams.isEmpty()) {
1608 settings.setValue("combineStreams", combineStreams);
1609 }
1610 else {
1611 settings.setValue("combineStreams", "");
1612 }
1613 settings.setValue("cmbMethod", _cmbMethodComboBox->currentText());
1614 settings.setValue("cmbMaxres", _cmbMaxresLineEdit->text());
1615 settings.setValue("cmbSampl", _cmbSamplSpinBox->value());
1616// Upload Corrections
1617 if (!uploadMountpointsOut.isEmpty()) {
1618 settings.setValue("uploadMountpointsOut", uploadMountpointsOut);
1619 }
1620 else {
1621 settings.setValue("uploadMountpointsOut", "");
1622 }
1623 settings.setValue("uploadIntr", _uploadIntrComboBox->currentText());
1624 settings.setValue("uploadSamplRtcmEphCorr", _uploadSamplRtcmEphCorrSpinBox->value());
1625 settings.setValue("uploadSamplSp3", _uploadSamplSp3SpinBox->value());
1626 settings.setValue("uploadSamplClkRnx", _uploadSamplClkRnxSpinBox->value());
1627// Upload Ephemeris
1628 settings.setValue("uploadEphHost", _uploadEphHostLineEdit->text());
1629 settings.setValue("uploadEphPort", _uploadEphPortLineEdit->text());
1630 settings.setValue("uploadEphMountpoint",_uploadEphMountpointLineEdit->text());
1631 settings.setValue("uploadEphPassword", _uploadEphPasswordLineEdit->text());
1632 settings.setValue("uploadEphSample", _uploadEphSampleSpinBox->value());
1633
1634 if (_caster) {
1635 _caster->readMountPoints();
1636 }
1637
1638 _pppWidgets.saveOptions();
1639}
1640
1641// All get slots terminated
1642////////////////////////////////////////////////////////////////////////////
1643void bncWindow::slotGetThreadsFinished() {
1644 BNC_CORE->slotMessage("All Get Threads Terminated", true);
1645 delete _caster; _caster = 0; BNC_CORE->setCaster(0);
1646 delete _casterEph; _casterEph = 0;
1647 _runningRealTime = false;
1648}
1649
1650// Start It!
1651////////////////////////////////////////////////////////////////////////////
1652void bncWindow::slotStart() {
1653 saveOptions();
1654 if ( _pppWidgets._dataSource->currentText() == "RINEX Files") {
1655 BNC_CORE->startPPP();
1656 }
1657 else if ( !_reqcActionComboBox->currentText().isEmpty() ) {
1658 startPostProcessingReqc();
1659 }
1660 else {
1661 startRealTime();
1662 BNC_CORE->startPPP();
1663 }
1664}
1665
1666// Start Real-Time (Retrieve Data etc.)
1667////////////////////////////////////////////////////////////////////////////
1668void bncWindow::startRealTime() {
1669
1670 _runningRealTime = true;
1671
1672 _bncFigurePPP->reset();
1673
1674 _actDeleteMountPoints->setEnabled(false);
1675
1676 enableStartStop();
1677
1678 _caster = new bncCaster();
1679
1680 BNC_CORE->setCaster(_caster);
1681 BNC_CORE->setPort(_outEphPortLineEdit->text().toInt());
1682 BNC_CORE->setPortCorr(_corrPortLineEdit->text().toInt());
1683 BNC_CORE->initCombination();
1684
1685 connect(_caster, SIGNAL(getThreadsFinished()),
1686 this, SLOT(slotGetThreadsFinished()));
1687
1688 connect (_caster, SIGNAL(mountPointsRead(QList<bncGetThread*>)),
1689 this, SLOT(slotMountPointsRead(QList<bncGetThread*>)));
1690
1691 BNC_CORE->slotMessage("========== Start BNC v" BNCVERSION " =========", true);
1692
1693 bncSettings settings;
1694
1695 QDir rnxdir(settings.value("rnxPath").toString());
1696 if (!rnxdir.exists()) BNC_CORE->slotMessage("Cannot find RINEX Observations directory", true);
1697
1698 QString rnx_file = settings.value("rnxScript").toString();
1699 if ( !rnx_file.isEmpty() ) {
1700 QFile rnxfile(settings.value("rnxScript").toString());
1701 if (!rnxfile.exists()) BNC_CORE->slotMessage("Cannot find RINEX Observations script", true);
1702 }
1703
1704 QDir ephdir(settings.value("ephPath").toString());
1705 if (!ephdir.exists()) BNC_CORE->slotMessage("Cannot find RINEX Ephemeris directory", true);
1706
1707 QDir corrdir(settings.value("corrPath").toString());
1708 if (!corrdir.exists()) BNC_CORE->slotMessage("Cannot find Broadcast Corrections directory", true);
1709
1710 QString advise_file = settings.value("adviseScript").toString();
1711 if ( !advise_file.isEmpty() ) {
1712 QFile advisefile(settings.value("adviseScript").toString());
1713 if (!advisefile.exists()) BNC_CORE->slotMessage("Cannot find Outages script", true);
1714 }
1715
1716 QString ant_file = settings.value("pppAntex").toString();
1717 if ( !ant_file.isEmpty() ) {
1718 QFile anxfile(settings.value("pppAntex").toString());
1719 if (!anxfile.exists()) BNC_CORE->slotMessage("Cannot find IGS ANTEX file", true);
1720 }
1721
1722 _caster->readMountPoints();
1723
1724 _casterEph = new bncEphUploadCaster();
1725 connect(_casterEph, SIGNAL(newBytes(QByteArray,double)),
1726 _uploadEphBytesCounter, SLOT(slotNewBytes(QByteArray,double)));
1727}
1728
1729// Retrieve Data
1730////////////////////////////////////////////////////////////////////////////
1731void bncWindow::slotStop() {
1732 int iRet = QMessageBox::question(this, "Stop", "Stop retrieving data?",
1733 QMessageBox::Yes, QMessageBox::No,
1734 QMessageBox::NoButton);
1735 if (iRet == QMessageBox::Yes) {
1736 BNC_CORE->stopPPP();
1737 BNC_CORE->stopCombination();
1738 delete _caster; _caster = 0; BNC_CORE->setCaster(0);
1739 delete _casterEph; _casterEph = 0;
1740 _runningRealTime = false;
1741 enableStartStop();
1742 }
1743}
1744
1745// Close Application gracefully
1746////////////////////////////////////////////////////////////////////////////
1747void bncWindow::closeEvent(QCloseEvent* event) {
1748
1749 int iRet = QMessageBox::question(this, "Close", "Save Options?",
1750 QMessageBox::Yes, QMessageBox::No,
1751 QMessageBox::Cancel);
1752
1753 if (iRet == QMessageBox::Cancel) {
1754 event->ignore();
1755 return;
1756 }
1757 else if (iRet == QMessageBox::Yes) {
1758 slotSaveOptions();
1759 }
1760
1761 BNC_CORE->stopPPP();
1762
1763 QMainWindow::closeEvent(event);
1764}
1765
1766// User changed the selection of mountPoints
1767////////////////////////////////////////////////////////////////////////////
1768void bncWindow::slotSelectionChanged() {
1769 if (_mountPointsTable->selectedItems().isEmpty()) {
1770 _actDeleteMountPoints->setEnabled(false);
1771 }
1772 else {
1773 _actDeleteMountPoints->setEnabled(true);
1774 }
1775}
1776
1777// Display Program Messages
1778////////////////////////////////////////////////////////////////////////////
1779void bncWindow::slotWindowMessage(const QByteArray msg, bool showOnScreen) {
1780 if (showOnScreen ) {
1781 _log->append(QDateTime::currentDateTime().toUTC().toString("yy-MM-dd hh:mm:ss ") + msg + '\n');
1782 }
1783}
1784
1785// About Message
1786////////////////////////////////////////////////////////////////////////////
1787void bncWindow::slotAbout() {
1788 new bncAboutDlg(0);
1789}
1790
1791//Flowchart
1792////////////////////////////////////////////////////////////////////////////
1793void bncWindow::slotFlowchart() {
1794 new bncFlowchartDlg(0);
1795}
1796
1797// Help Window
1798////////////////////////////////////////////////////////////////////////////
1799void bncWindow::slotHelp() {
1800 QUrl url;
1801 url.setPath(":bnchelp.html");
1802 new bncHlpDlg(0, url);
1803}
1804
1805// Select Fonts
1806////////////////////////////////////////////////////////////////////////////
1807void bncWindow::slotFontSel() {
1808 bool ok;
1809 QFont newFont = QFontDialog::getFont(&ok, this->font(), this);
1810 if (ok) {
1811 bncSettings settings;
1812 settings.setValue("font", newFont.toString());
1813 QApplication::setFont(newFont);
1814 int ww = QFontMetrics(newFont).width('w');
1815 setMinimumSize(60*ww, 80*ww);
1816 resize(60*ww, 80*ww);
1817 }
1818}
1819
1820// Whats This Help
1821void bncWindow::slotWhatsThis() {
1822 QWhatsThis::enterWhatsThisMode();
1823}
1824
1825//
1826////////////////////////////////////////////////////////////////////////////
1827void bncWindow::slotMountPointsRead(QList<bncGetThread*> threads) {
1828 _threads = threads;
1829
1830 _bncFigure->updateMountPoints();
1831 _bncFigureLate->updateMountPoints();
1832
1833 populateMountPointsTable();
1834 bncSettings settings;
1835 _binSamplSpinBox->setValue(settings.value("binSampl").toInt());
1836 _waitTimeSpinBox->setValue(settings.value("waitTime").toInt());
1837 QListIterator<bncGetThread*> iTh(threads);
1838 while (iTh.hasNext()) {
1839 bncGetThread* thread = iTh.next();
1840 for (int iRow = 0; iRow < _mountPointsTable->rowCount(); iRow++) {
1841 QUrl url( "//" + _mountPointsTable->item(iRow, 0)->text() +
1842 "@" + _mountPointsTable->item(iRow, 1)->text() );
1843 if (url == thread->mountPoint() &&
1844 _mountPointsTable->item(iRow, 3)->text() == thread->latitude() &&
1845 _mountPointsTable->item(iRow, 4)->text() == thread->longitude() ) {
1846 ((bncTableItem*) _mountPointsTable->item(iRow, 7))->setGetThread(thread);
1847 disconnect(thread, SIGNAL(newBytes(QByteArray, double)),
1848 _bncFigure, SLOT(slotNewData(QByteArray, double)));
1849 connect(thread, SIGNAL(newBytes(QByteArray, double)),
1850 _bncFigure, SLOT(slotNewData(QByteArray, double)));
1851 disconnect(thread, SIGNAL(newLatency(QByteArray, double)),
1852 _bncFigureLate, SLOT(slotNewLatency(QByteArray, double)));
1853 connect(thread, SIGNAL(newLatency(QByteArray, double)),
1854 _bncFigureLate, SLOT(slotNewLatency(QByteArray, double)));
1855 break;
1856 }
1857 }
1858 }
1859}
1860
1861//
1862////////////////////////////////////////////////////////////////////////////
1863void bncWindow::CreateMenu() {
1864 // Create Menus
1865 // ------------
1866 _menuFile = menuBar()->addMenu(tr("&File"));
1867 _menuFile->addAction(_actFontSel);
1868 _menuFile->addSeparator();
1869 _menuFile->addAction(_actSaveOpt);
1870 _menuFile->addSeparator();
1871 _menuFile->addAction(_actQuit);
1872
1873 _menuHlp = menuBar()->addMenu(tr("&Help"));
1874 _menuHlp->addAction(_actHelp);
1875 _menuHlp->addAction(_actFlowchart);
1876 _menuHlp->addAction(_actAbout);
1877}
1878
1879// Toolbar
1880////////////////////////////////////////////////////////////////////////////
1881void bncWindow::AddToolbar() {
1882 QToolBar* toolBar = new QToolBar;
1883 addToolBar(Qt::BottomToolBarArea, toolBar);
1884 toolBar->setMovable(false);
1885 toolBar->addAction(_actAddMountPoints);
1886 toolBar->addAction(_actDeleteMountPoints);
1887 toolBar->addAction(_actMapMountPoints);
1888 toolBar->addAction(_actStart);
1889 toolBar->addAction(_actStop);
1890 toolBar->addWidget(new QLabel(" "));
1891 toolBar->addAction(_actwhatsthis);
1892}
1893
1894// About
1895////////////////////////////////////////////////////////////////////////////
1896bncAboutDlg::bncAboutDlg(QWidget* parent) :
1897 QDialog(parent) {
1898
1899 QTextBrowser* tb = new QTextBrowser;
1900 QUrl url; url.setPath(":bncabout.html");
1901 tb->setSource(url);
1902 tb->setReadOnly(true);
1903
1904 int ww = QFontMetrics(font()).width('w');
1905 QPushButton* _closeButton = new QPushButton("Close");
1906 _closeButton->setMaximumWidth(10*ww);
1907 connect(_closeButton, SIGNAL(clicked()), this, SLOT(close()));
1908
1909 QGridLayout* dlgLayout = new QGridLayout();
1910 QLabel* img = new QLabel();
1911 img->setPixmap(QPixmap(":ntrip-logo.png"));
1912 dlgLayout->addWidget(img, 0,0);
1913 dlgLayout->addWidget(new QLabel("BKG Ntrip Client (BNC) Version "BNCVERSION), 0,1);
1914 dlgLayout->addWidget(tb,1,0,1,2);
1915 dlgLayout->addWidget(_closeButton,2,1,Qt::AlignRight);
1916
1917 setLayout(dlgLayout);
1918 resize(60*ww, 60*ww);
1919 setWindowTitle("About BNC");
1920 show();
1921}
1922
1923//
1924////////////////////////////////////////////////////////////////////////////
1925bncAboutDlg::~bncAboutDlg() {
1926};
1927
1928// Flowchart
1929////////////////////////////////////////////////////////////////////////////
1930bncFlowchartDlg::bncFlowchartDlg(QWidget* parent) :
1931 QDialog(parent) {
1932
1933 int ww = QFontMetrics(font()).width('w');
1934 QPushButton* _closeButton = new QPushButton("Close");
1935 _closeButton->setMaximumWidth(10*ww);
1936 connect(_closeButton, SIGNAL(clicked()), this, SLOT(close()));
1937
1938 QGridLayout* dlgLayout = new QGridLayout();
1939 QLabel* img = new QLabel();
1940 img->setPixmap(QPixmap(":bncflowchart.png"));
1941 dlgLayout->addWidget(img, 0,0);
1942 dlgLayout->addWidget(_closeButton,1,0,Qt::AlignLeft);
1943
1944 setLayout(dlgLayout);
1945 setWindowTitle("Flow Chart");
1946 show();
1947}
1948
1949//
1950////////////////////////////////////////////////////////////////////////////
1951bncFlowchartDlg::~bncFlowchartDlg() {
1952};
1953
1954// Enable/Disable Widget (and change its color)
1955////////////////////////////////////////////////////////////////////////////
1956void bncWindow::enableWidget(bool enable, QWidget* widget) {
1957 const static QPalette paletteWhite(QColor(255, 255, 255));
1958 const static QPalette paletteGray(QColor(230, 230, 230));
1959
1960 widget->setEnabled(enable);
1961 if (enable) {
1962 widget->setPalette(paletteWhite);
1963 }
1964 else {
1965 widget->setPalette(paletteGray);
1966 }
1967}
1968
1969// Bnc Text
1970////////////////////////////////////////////////////////////////////////////
1971void bncWindow::slotBncTextChanged(){
1972
1973 bool enable = true;
1974
1975 // Proxy
1976 //------
1977 if (sender() == 0 || sender() == _proxyHostLineEdit) {
1978 enable = !_proxyHostLineEdit->text().isEmpty();
1979 enableWidget(enable, _proxyPortLineEdit);
1980 }
1981
1982 // RINEX Observations
1983 // ------------------
1984 if (sender() == 0 || sender() == _rnxPathLineEdit) {
1985 enable = !_rnxPathLineEdit->text().isEmpty();
1986 enableWidget(enable, _rnxSamplSpinBox);
1987 enableWidget(enable, _rnxSkelLineEdit);
1988 enableWidget(enable, _rnxScrpLineEdit);
1989 enableWidget(enable, _rnxV3CheckBox);
1990 enableWidget(enable, _rnxIntrComboBox);
1991 }
1992
1993 // RINEX Ephemeris
1994 // ---------------
1995 if (sender() == 0 || sender() == _ephPathLineEdit || sender() == _outEphPortLineEdit) {
1996 enable = !_ephPathLineEdit->text().isEmpty() || !_outEphPortLineEdit->text().isEmpty();
1997 enableWidget(enable, _ephIntrComboBox);
1998 enableWidget(enable, _ephV3CheckBox);
1999 }
2000
2001 // Broadcast Corrections
2002 // ---------------------
2003 if (sender() == 0 || sender() == _corrPathLineEdit || sender() == _corrPortLineEdit) {
2004 enable = !_corrPathLineEdit->text().isEmpty() || !_corrPortLineEdit->text().isEmpty();
2005 enableWidget(enable, _corrIntrComboBox);
2006 }
2007
2008 // Feed Engine
2009 // -----------
2010 if (sender() == 0 || sender() == _outPortLineEdit || sender() == _outFileLineEdit) {
2011 enable = !_outPortLineEdit->text().isEmpty() || !_outFileLineEdit->text().isEmpty();
2012 enableWidget(enable, _waitTimeSpinBox);
2013 enableWidget(enable, _binSamplSpinBox);
2014 }
2015
2016 // Serial Output
2017 // -------------
2018 if (sender() == 0 || sender() == _serialMountPointLineEdit ||
2019 sender() == _serialAutoNMEAComboBox) {
2020 enable = !_serialMountPointLineEdit->text().isEmpty();
2021 enableWidget(enable, _serialPortNameLineEdit);
2022 enableWidget(enable, _serialBaudRateComboBox);
2023 enableWidget(enable, _serialParityComboBox);
2024 enableWidget(enable, _serialDataBitsComboBox);
2025 enableWidget(enable, _serialStopBitsComboBox);
2026 enableWidget(enable, _serialFlowControlComboBox);
2027 enableWidget(enable, _serialAutoNMEAComboBox);
2028
2029 bool enable2 = enable && _serialAutoNMEAComboBox->currentText() != "Auto";
2030 enableWidget(enable2, _serialFileNMEALineEdit);
2031 }
2032
2033 // Outages
2034 // -------
2035 if (sender() == 0 || sender() == _obsRateComboBox) {
2036 enable = !_obsRateComboBox->currentText().isEmpty();
2037 enableWidget(enable, _adviseFailSpinBox);
2038 enableWidget(enable, _adviseRecoSpinBox);
2039 enableWidget(enable, _adviseScriptLineEdit);
2040 }
2041
2042 // Miscellaneous
2043 // -------------
2044 if (sender() == 0 || sender() == _miscMountLineEdit) {
2045 enable = !_miscMountLineEdit->text().isEmpty();
2046 enableWidget(enable, _perfIntrComboBox);
2047 enableWidget(enable, _scanRTCMCheckBox);
2048 enableWidget(enable, _miscPortLineEdit);
2049 }
2050
2051 // Enable/disable Broadcast Ephemerides
2052 // ------------------------------------
2053 if (sender() == 0 || sender() == _uploadEphHostLineEdit) {
2054 if (!_uploadEphHostLineEdit->text().isEmpty()) {
2055 _uploadEphPortLineEdit->setStyleSheet("background-color: white");
2056 _uploadEphMountpointLineEdit->setStyleSheet("background-color: white");
2057 _uploadEphPasswordLineEdit->setStyleSheet("background-color: white");
2058 _uploadEphSampleSpinBox->setStyleSheet("background-color: white");
2059 _uploadEphPortLineEdit->setEnabled(true);
2060 _uploadEphMountpointLineEdit->setEnabled(true);
2061 _uploadEphPasswordLineEdit->setEnabled(true);
2062 _uploadEphSampleSpinBox->setEnabled(true);
2063 }
2064 else {
2065 _uploadEphPortLineEdit->setStyleSheet("background-color: lightGray");
2066 _uploadEphMountpointLineEdit->setStyleSheet("background-color: lightGray");
2067 _uploadEphPasswordLineEdit->setStyleSheet("background-color: lightGray");
2068 _uploadEphSampleSpinBox->setStyleSheet("background-color: lightGray");
2069 _uploadEphPortLineEdit->setEnabled(false);
2070 _uploadEphMountpointLineEdit->setEnabled(false);
2071 _uploadEphPasswordLineEdit->setEnabled(false);
2072 _uploadEphSampleSpinBox->setEnabled(false);
2073 }
2074 }
2075
2076 // Combine Corrections
2077 // -------------------
2078 if (sender() == 0 || sender() == _cmbTable) {
2079 int iRow = _cmbTable->rowCount();
2080 if (iRow > 0) {
2081 enableWidget(true, _cmbMethodComboBox);
2082 _cmbMaxresLineEdit->setStyleSheet("background-color: white");
2083 _cmbMaxresLineEdit->setEnabled(true);
2084 _cmbSamplSpinBox->setEnabled(true);
2085 }
2086 else {
2087 enableWidget(false, _cmbMethodComboBox);
2088 _cmbMaxresLineEdit->setStyleSheet("background-color: lightGray");
2089 _cmbMaxresLineEdit->setEnabled(false);
2090 _cmbSamplSpinBox->setEnabled(false);
2091 }
2092 }
2093
2094 // Upload(clk)
2095 // -----------
2096 int iRow = _uploadTable->rowCount();
2097 if (iRow > 0) {
2098 enableWidget(true, _uploadIntrComboBox);
2099 enableWidget(true, _uploadSamplRtcmEphCorrSpinBox);
2100 enableWidget(true, _uploadSamplClkRnxSpinBox);
2101 enableWidget(true, _uploadSamplSp3SpinBox);
2102 }
2103 else {
2104 enableWidget(false, _uploadIntrComboBox);
2105 enableWidget(false, _uploadSamplRtcmEphCorrSpinBox);
2106 enableWidget(false, _uploadSamplClkRnxSpinBox);
2107 enableWidget(false, _uploadSamplSp3SpinBox);
2108 }
2109
2110 // QC
2111 // --
2112 if (sender() == 0 || sender() == _reqcActionComboBox) {
2113 enable = !_reqcActionComboBox->currentText().isEmpty();
2114 bool enable10 = _reqcActionComboBox->currentText() == "Edit/Concatenate";
2115 enableWidget(enable && enable10, _reqcEditOptionButton);
2116 enableWidget(enable, _reqcObsFileChooser);
2117 enableWidget(enable, _reqcNavFileChooser);
2118 enableWidget(enable && enable10, _reqcOutObsLineEdit);
2119 enableWidget(enable && enable10, _reqcOutNavLineEdit);
2120 enableWidget(enable, _reqcOutLogLineEdit);
2121 enableWidget(enable && !enable10, _reqcPlotDirLineEdit);
2122 enableWidget(enable && !enable10, _reqcSkyPlotSystems);
2123 }
2124
2125 enableStartStop();
2126}
2127
2128//
2129////////////////////////////////////////////////////////////////////////////
2130void bncWindow::slotAddCmbRow() {
2131 int iRow = _cmbTable->rowCount();
2132 _cmbTable->insertRow(iRow);
2133 for (int iCol = 0; iCol < _cmbTable->columnCount(); iCol++) {
2134 _cmbTable->setItem(iRow, iCol, new QTableWidgetItem(""));
2135 }
2136}
2137
2138//
2139////////////////////////////////////////////////////////////////////////////
2140void bncWindow::slotDelCmbRow() {
2141 int nRows = _cmbTable->rowCount();
2142 bool flg[nRows];
2143 for (int iRow = 0; iRow < nRows; iRow++) {
2144 if (_cmbTable->isItemSelected(_cmbTable->item(iRow,1))) {
2145 flg[iRow] = true;
2146 }
2147 else {
2148 flg[iRow] = false;
2149 }
2150 }
2151 for (int iRow = nRows-1; iRow >= 0; iRow--) {
2152 if (flg[iRow]) {
2153 _cmbTable->removeRow(iRow);
2154 }
2155 }
2156 nRows = _cmbTable->rowCount();
2157 if (nRows < 1) {
2158 enableWidget(false, _cmbMethodComboBox);
2159 _cmbMaxresLineEdit->setStyleSheet("background-color: lightGray");
2160 _cmbMaxresLineEdit->setEnabled(false);
2161 _cmbSamplSpinBox->setEnabled(false);
2162 }
2163}
2164
2165//
2166////////////////////////////////////////////////////////////////////////////
2167void bncWindow::populateCmbTable() {
2168
2169 for (int iRow = _cmbTable->rowCount()-1; iRow >=0; iRow--) {
2170 _cmbTable->removeRow(iRow);
2171 }
2172
2173 bncSettings settings;
2174
2175 int iRow = -1;
2176 QListIterator<QString> it(settings.value("combineStreams").toStringList());
2177 while (it.hasNext()) {
2178 QStringList hlp = it.next().split(" ");
2179 if (hlp.size() > 2) {
2180 ++iRow;
2181 _cmbTable->insertRow(iRow);
2182 }
2183 for (int iCol = 0; iCol < hlp.size(); iCol++) {
2184 _cmbTable->setItem(iRow, iCol, new QTableWidgetItem(hlp[iCol]));
2185 }
2186 }
2187}
2188
2189//
2190////////////////////////////////////////////////////////////////////////////
2191void bncWindow::slotAddUploadRow() {
2192 int iRow = _uploadTable->rowCount();
2193 _uploadTable->insertRow(iRow);
2194 for (int iCol = 0; iCol < _uploadTable->columnCount(); iCol++) {
2195 if (iCol == 3) {
2196 QLineEdit* passwd = new QLineEdit();
2197 passwd->setFrame(false);
2198 passwd->setEchoMode(QLineEdit::PasswordEchoOnEdit);
2199 _uploadTable->setCellWidget(iRow, iCol, passwd);
2200 }
2201 else if (iCol == 4) {
2202 QComboBox* system = new QComboBox();
2203 system->setEditable(false);
2204 system->addItems(QString(",IGS08,ETRF2000,NAD83,GDA94,SIRGAS95,SIRGAS2000,DREF91,Custom").split(","));
2205 system->setFrame(false);
2206 _uploadTable->setCellWidget(iRow, iCol, system);
2207 }
2208 else if (iCol == 5) {
2209 QCheckBox* com = new QCheckBox();
2210 _uploadTable->setCellWidget(iRow, iCol, com);
2211 }
2212 else if (iCol == 11) {
2213 bncTableItem* bncIt = new bncTableItem();
2214 bncIt->setFlags(bncIt->flags() & ~Qt::ItemIsEditable);
2215 _uploadTable->setItem(iRow, iCol, bncIt);
2216 BNC_CORE->_uploadTableItems[iRow] = bncIt;
2217 }
2218 else {
2219 _uploadTable->setItem(iRow, iCol, new QTableWidgetItem(""));
2220 }
2221 }
2222}
2223
2224//
2225////////////////////////////////////////////////////////////////////////////
2226void bncWindow::slotDelUploadRow() {
2227 BNC_CORE->_uploadTableItems.clear();
2228 int nRows = _uploadTable->rowCount();
2229 bool flg[nRows];
2230 for (int iRow = 0; iRow < nRows; iRow++) {
2231 if (_uploadTable->isItemSelected(_uploadTable->item(iRow,1))) {
2232 flg[iRow] = true;
2233 }
2234 else {
2235 flg[iRow] = false;
2236 }
2237 }
2238 for (int iRow = nRows-1; iRow >= 0; iRow--) {
2239 if (flg[iRow]) {
2240 _uploadTable->removeRow(iRow);
2241 }
2242 }
2243 for (int iRow = 0; iRow < _uploadTable->rowCount(); iRow++) {
2244 BNC_CORE->_uploadTableItems[iRow] =
2245 (bncTableItem*) _uploadTable->item(iRow, 11);
2246 }
2247 nRows = _uploadTable->rowCount();
2248 if (nRows < 1) {
2249 enableWidget(false, _uploadIntrComboBox);
2250 enableWidget(false, _uploadSamplRtcmEphCorrSpinBox);
2251 enableWidget(false, _uploadSamplSp3SpinBox);
2252 enableWidget(false, _uploadSamplClkRnxSpinBox);
2253 }
2254}
2255
2256//
2257////////////////////////////////////////////////////////////////////////////
2258void bncWindow::populateUploadTable() {
2259 for (int iRow = _uploadTable->rowCount()-1; iRow >=0; iRow--) {
2260 _uploadTable->removeRow(iRow);
2261 }
2262
2263 bncSettings settings;
2264
2265 int iRow = -1;
2266 QListIterator<QString> it(settings.value("uploadMountpointsOut").toStringList());
2267 while (it.hasNext()) {
2268 QStringList hlp = it.next().split(",");
2269 if (hlp.size() > 6) {
2270 ++iRow;
2271 _uploadTable->insertRow(iRow);
2272 }
2273 for (int iCol = 0; iCol < hlp.size(); iCol++) {
2274 if (iCol == 3) {
2275 QLineEdit* passwd = new QLineEdit();
2276 passwd->setFrame(false);
2277 passwd->setEchoMode(QLineEdit::PasswordEchoOnEdit);
2278 passwd->setText(hlp[iCol]);
2279 _uploadTable->setCellWidget(iRow, iCol, passwd);
2280 }
2281 else if (iCol == 4) {
2282 QComboBox* system = new QComboBox();
2283 system->setEditable(false);
2284 system->addItems(QString(",IGS08,ETRF2000,NAD83,GDA94,SIRGAS95,SIRGAS2000,DREF91,Custom").split(","));
2285 system->setFrame(false);
2286 system->setCurrentIndex(system->findText(hlp[iCol]));
2287 _uploadTable->setCellWidget(iRow, iCol, system);
2288 }
2289 else if (iCol == 5) {
2290 QCheckBox* com = new QCheckBox();
2291 if (hlp[iCol].toInt() == Qt::Checked) {
2292 com->setCheckState(Qt::Checked);
2293 }
2294 _uploadTable->setCellWidget(iRow, iCol, com);
2295 }
2296 else if (iCol == 11) {
2297 bncTableItem* bncIt = new bncTableItem();
2298 bncIt->setFlags(bncIt->flags() & ~Qt::ItemIsEditable);
2299 _uploadTable->setItem(iRow, iCol, bncIt);
2300 BNC_CORE->_uploadTableItems[iRow] = bncIt;
2301 }
2302 else {
2303 _uploadTable->setItem(iRow, iCol, new QTableWidgetItem(hlp[iCol]));
2304 }
2305 }
2306 }
2307}
2308
2309//
2310////////////////////////////////////////////////////////////////////////////
2311void bncWindow::slotSetUploadTrafo() {
2312 bncCustomTrafo* dlg = new bncCustomTrafo(this);
2313 dlg->exec();
2314 delete dlg;
2315}
2316
2317// Progress Bar Change
2318////////////////////////////////////////////////////////////////////////////
2319void bncWindow::slotPostProgress(int nEpo) {
2320 if (_actStart) {
2321 _actStart->setText(QString("%1 Epochs").arg(nEpo));
2322 }
2323}
2324
2325// Start Post-Processing Reqc
2326////////////////////////////////////////////////////////////////////////////
2327void bncWindow::startPostProcessingReqc() {
2328 _runningPostProcessingReqc = true;
2329 enableStartStop();
2330 if (_reqcActionComboBox->currentText() == "Analyze") {
2331 t_reqcAnalyze* reqcAnalyze = new t_reqcAnalyze(this);
2332 connect(reqcAnalyze, SIGNAL(finished()),
2333 this, SLOT(slotFinishedPostProcessingReqc()));
2334 reqcAnalyze->start();
2335 }
2336 else {
2337 t_reqcEdit* reqcEdit = new t_reqcEdit(this);
2338 connect(reqcEdit, SIGNAL(finished()),
2339 this, SLOT(slotFinishedPostProcessingReqc()));
2340 reqcEdit->start();
2341 }
2342}
2343
2344// Post-Processing Reqc Finished
2345////////////////////////////////////////////////////////////////////////////
2346void bncWindow::slotFinishedPostProcessingReqc() {
2347 _runningPostProcessingReqc = false;
2348 if (_reqcActionComboBox->currentText() != "Analyze") {
2349 QMessageBox::information(this, "Information",
2350 "RINEX Processing Thread Finished");
2351 }
2352 enableStartStop();
2353}
2354
2355//
2356////////////////////////////////////////////////////////////////////////////
2357void bncWindow::slotFinishedRnxPPP() {
2358 if (_actStart) {
2359 _actStart->setText(tr("Sta&rt"));
2360 }
2361}
2362
2363// Edit teqc-like editing options
2364////////////////////////////////////////////////////////////////////////////
2365void bncWindow::slotReqcEditOption() {
2366 reqcDlg* dlg = new reqcDlg(this);
2367 dlg->move(this->pos().x()+50, this->pos().y()+50);
2368 dlg->exec();
2369 delete dlg;
2370}
2371
2372// Enable/Disable Start and Stop Buttons
2373////////////////////////////////////////////////////////////////////////////
2374void bncWindow::enableStartStop() {
2375
2376 if ( _reqcActionComboBox && !_reqcActionComboBox->currentText().isEmpty() ) {
2377 if (_runningPostProcessingReqc) {
2378 _actStart->setEnabled(false);
2379 }
2380 else {
2381 _actStart->setEnabled(true);
2382 }
2383 _actStop->setEnabled(false);
2384 }
2385 else {
2386 if (_runningRealTime) {
2387 _actStart->setEnabled(false);
2388 _actStop->setEnabled(true);
2389 }
2390 else {
2391 _actStop->setEnabled(false);
2392 if (_mountPointsTable->rowCount() == 0) {
2393 _actStart->setEnabled(false);
2394 }
2395 else {
2396 _actStart->setEnabled(true);
2397 }
2398 }
2399 }
2400}
2401
2402// Show Map
2403////////////////////////////////////////////////////////////////////////////
2404void bncWindow::slotMapMountPoints() {
2405 saveOptions();
2406 t_bncMap* bncMap = new t_bncMap(this);
2407 bncMap->setMinimumSize(800, 600);
2408 bncMap->setWindowTitle("Selected Mountpoints");
2409
2410 bncSettings settings;
2411 QListIterator<QString> it(settings.value("mountPoints").toStringList());
2412 while (it.hasNext()) {
2413 QStringList hlp = it.next().split(" ");
2414 if (hlp.size() < 5) continue;
2415 QUrl url(hlp[0]);
2416 double latDeg = hlp[2].toDouble();
2417 double lonDeg = hlp[3].toDouble();
2418 bncMap->slotNewPoint(QFileInfo(url.path()).fileName(), latDeg, lonDeg);
2419 }
2420
2421 bncMap->show();
2422}
2423
2424// Show Map
2425////////////////////////////////////////////////////////////////////////////
2426void bncWindow::slotMapPPP() {
2427#ifdef QT_WEBKIT
2428 saveOptions();
2429 enableWidget(false, _pppWidgets._mapWinButton);
2430 enableWidget(false, _pppWidgets._useGoogleMap);
2431 enableWidget(false, _pppWidgets._useOpenStreetMap);
2432 enableWidget(false, _pppWidgets._mapWinDotSize);
2433 enableWidget(false, _pppWidgets._mapWinDotColor);
2434
2435 if (!_mapWin) {
2436 _mapWin = new bncMapWin(this);
2437 connect(_mapWin, SIGNAL(mapClosed()), this, SLOT(slotMapPPPClosed()));
2438 connect(BNC_CORE, SIGNAL(newPosition(QByteArray, bncTime, QVector<double>)),
2439 _mapWin, SLOT(slotNewPosition(QByteArray, bncTime, QVector<double>)));
2440 }
2441 _mapWin->show();
2442#else
2443 QMessageBox::information(this, "Information",
2444 "Qt Library compiled without QtWebKit");
2445#endif
2446}
2447
2448// Show Map
2449////////////////////////////////////////////////////////////////////////////
2450void bncWindow::slotMapPPPClosed() {
2451#ifdef QT_WEBKIT
2452 enableWidget(true, _pppWidgets._mapWinButton);
2453 enableWidget(true, _pppWidgets._useGoogleMap);
2454 enableWidget(true, _pppWidgets._useOpenStreetMap);
2455 enableWidget(true, _pppWidgets._mapWinDotSize);
2456 enableWidget(true, _pppWidgets._mapWinDotColor);
2457 if (_mapWin) {
2458 QListIterator<bncGetThread*> it(_threads);
2459 while (it.hasNext()) {
2460 bncGetThread* thread = it.next();
2461 thread->disconnect(_mapWin);
2462 }
2463 _mapWin->deleteLater();
2464 _mapWin = 0;
2465 }
2466#endif
2467}
Note: See TracBrowser for help on using the repository browser.