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

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