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

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