source: ntrip/trunk/BNC/bncwindow.cpp@ 1931

Last change on this file since 1931 was 1931, checked in by mervart, 14 years ago

* empty log message *

File size: 76.4 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 "bncapp.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
56using namespace std;
57
58// Constructor
59////////////////////////////////////////////////////////////////////////////
60FWidget::FWidget(QWidget *parent) : QWidget(parent) {
61 bncSettings settings;
62 QListIterator<QString> it(settings.value("mountPoints").toStringList());
63 while (it.hasNext()) {
64 QStringList hlp = it.next().split(" ");
65 QUrl url(hlp[0]);
66 QByteArray staID = url.path().mid(1).toAscii();
67 _bytes[staID] = new sumAndMean();
68 }
69 _counter = 0;
70 slotNextAnimationFrame();
71}
72
73// Destructor
74////////////////////////////////////////////////////////////////////////////
75FWidget::~FWidget() {
76}
77
78//
79////////////////////////////////////////////////////////////////////////////
80void FWidget::slotNewData(const QByteArray staID, double nbyte) {
81 QMutexLocker locker(&_mutex);
82 QMap<QByteArray, sumAndMean*>::const_iterator it = _bytes.find(staID);
83 if (it != _bytes.end()) {
84 it.value()->_sum += nbyte;
85 }
86}
87
88//
89////////////////////////////////////////////////////////////////////////////
90void FWidget::slotNextAnimationFrame() {
91 QMutexLocker locker(&_mutex);
92 if (++_counter == 10) {
93 QMapIterator<QByteArray, sumAndMean*> it(_bytes);
94 while (it.hasNext()) {
95 it.next();
96 it.value()->_mean = it.value()->_sum / _counter;
97 it.value()->_sum = 0.0;
98 }
99 _counter = 0;
100 }
101 update();
102 QTimer::singleShot(1000, this, SLOT(slotNextAnimationFrame()));
103}
104
105//
106////////////////////////////////////////////////////////////////////////////
107void FWidget::paintEvent(QPaintEvent *) {
108 QRectF rectangle(0, 0, 640, 180);
109 QBrush rBrush(Qt::white,Qt::SolidPattern);
110 QPainter painter(this);
111 painter.fillRect(rectangle,rBrush);
112 painter.drawRect(rectangle);
113 QLine line(50, 140, 630, 140);
114 painter.drawLine(line);
115 line.setLine(50, 140, 50, 10);
116 painter.drawLine(line);
117 QPoint textP(40, 140);
118 painter.drawText(textP, tr("0"));
119 textP.setX(20);
120 textP.setY(25);
121 painter.drawText(textP, tr("3000"));
122 int anker=0;
123 textP.setY(160);
124 painter.drawText(textP, tr(QTime::currentTime().toString().toAscii()));
125 textP.setX(300);
126
127 QMapIterator<QByteArray, sumAndMean*> it(_bytes);
128 while (it.hasNext()) {
129 it.next();
130 QByteArray staID = it.key();
131 double vv = it.value()->_mean;
132 QRectF vrect((100+anker*40), (140-vv), (30), (vv));
133 QBrush xBrush(Qt::green,Qt::SolidPattern);
134 textP.setX(100+anker*40);
135 painter.fillRect(vrect,xBrush);
136 painter.drawRect(vrect);
137 painter.drawText(textP, staID);
138 anker++;
139 }
140}
141
142// Constructor
143////////////////////////////////////////////////////////////////////////////
144bncWindow::bncWindow() {
145
146 _caster = 0;
147
148 _Figure1 = new FWidget(this);
149
150 int ww = QFontMetrics(this->font()).width('w');
151
152 static const QStringList labels = QString("account, Streams: resource loader / mountpoint,decoder,lat,long,nmea,ntrip,bytes").split(",");
153
154 setMinimumSize(85*ww, 65*ww);
155
156 setWindowTitle(tr("BKG Ntrip Client (BNC) Version 1.7"));
157
158 connect((bncApp*)qApp, SIGNAL(newMessage(QByteArray,bool)),
159 this, SLOT(slotWindowMessage(QByteArray,bool)));
160
161 QPalette palette;
162 QColor lightGray(230, 230, 230);
163
164 // Create Actions
165 // --------------
166 _actHelp = new QAction(tr("&Help Contents"),this);
167 connect(_actHelp, SIGNAL(triggered()), SLOT(slotHelp()));
168
169 _actAbout = new QAction(tr("&About BNC"),this);
170 connect(_actAbout, SIGNAL(triggered()), SLOT(slotAbout()));
171
172 _actFlowchart = new QAction(tr("&Flow Chart"),this);
173 connect(_actFlowchart, SIGNAL(triggered()), SLOT(slotFlowchart()));
174
175 _actFontSel = new QAction(tr("Select &Font"),this);
176 connect(_actFontSel, SIGNAL(triggered()), SLOT(slotFontSel()));
177
178 _actSaveOpt = new QAction(tr("&Save && Reread Configuration"),this);
179 connect(_actSaveOpt, SIGNAL(triggered()), SLOT(slotSaveOptions()));
180
181 _actQuit = new QAction(tr("&Quit"),this);
182 connect(_actQuit, SIGNAL(triggered()), SLOT(close()));
183
184 _actAddMountPoints = new QAction(tr("Add &Stream"),this);
185 connect(_actAddMountPoints, SIGNAL(triggered()), SLOT(slotAddMountPoints()));
186
187 _actDeleteMountPoints = new QAction(tr("&Delete Stream"),this);
188 connect(_actDeleteMountPoints, SIGNAL(triggered()), SLOT(slotDeleteMountPoints()));
189 _actDeleteMountPoints->setEnabled(false);
190
191 _actGetData = new QAction(tr("Sta&rt"),this);
192 connect(_actGetData, SIGNAL(triggered()), SLOT(slotGetData()));
193
194 _actStop = new QAction(tr("Sto&p"),this);
195 connect(_actStop, SIGNAL(triggered()), SLOT(slotStop()));
196 _actStop->setEnabled(false);
197
198 _actwhatsthis= new QAction(tr("Help=Shift+F1"),this);
199 connect(_actwhatsthis, SIGNAL(triggered()), SLOT(slotWhatsThis()));
200
201 CreateMenu();
202 AddToolbar();
203
204 bncSettings settings;
205
206 // Proxy Options
207 // -------------
208 _proxyHostLineEdit = new QLineEdit(settings.value("proxyHost").toString());
209 _proxyPortLineEdit = new QLineEdit(settings.value("proxyPort").toString());
210
211 // General Options
212 // ---------------
213 _logFileLineEdit = new QLineEdit(settings.value("logFile").toString());
214 _rnxAppendCheckBox = new QCheckBox();
215 _rnxAppendCheckBox->setCheckState(Qt::CheckState(
216 settings.value("rnxAppend").toInt()));
217 _onTheFlyComboBox = new QComboBox();
218 _onTheFlyComboBox->setEditable(false);
219 _onTheFlyComboBox->addItems(QString("1 day,1 hour,1 min").split(","));
220 int ii = _onTheFlyComboBox->findText(settings.value("onTheFlyInterval").toString());
221 if (ii != -1) {
222 _onTheFlyComboBox->setCurrentIndex(ii);
223 }
224 _autoStartCheckBox = new QCheckBox();
225 _autoStartCheckBox->setCheckState(Qt::CheckState(
226 settings.value("autoStart").toInt()));
227
228 // RINEX Observations Options
229 // --------------------------
230 _rnxPathLineEdit = new QLineEdit(settings.value("rnxPath").toString());
231 _rnxIntrComboBox = new QComboBox();
232 _rnxIntrComboBox->setEditable(false);
233 _rnxIntrComboBox->addItems(QString("1 min,2 min,5 min,10 min,15 min,30 min,1 hour,1 day").split(","));
234 ii = _rnxIntrComboBox->findText(settings.value("rnxIntr").toString());
235 if (ii != -1) {
236 _rnxIntrComboBox->setCurrentIndex(ii);
237 }
238 _rnxSamplSpinBox = new QSpinBox();
239 _rnxSamplSpinBox->setMinimum(0);
240 _rnxSamplSpinBox->setMaximum(60);
241 _rnxSamplSpinBox->setSingleStep(5);
242 _rnxSamplSpinBox->setValue(settings.value("rnxSampl").toInt());
243 _rnxSamplSpinBox->setSuffix(" sec");
244 _rnxSkelLineEdit = new QLineEdit(settings.value("rnxSkel").toString());
245 _rnxSkelLineEdit->setMaximumWidth(5*ww);
246 _rnxScrpLineEdit = new QLineEdit(settings.value("rnxScript").toString());
247 _rnxV3CheckBox = new QCheckBox();
248 _rnxV3CheckBox->setCheckState(Qt::CheckState(settings.value("rnxV3").toInt()));
249
250 // RINEX Ephemeris Options
251 // -----------------------
252 _ephPathLineEdit = new QLineEdit(settings.value("ephPath").toString());
253 _ephIntrComboBox = new QComboBox();
254 _ephIntrComboBox->setEditable(false);
255 _ephIntrComboBox->addItems(QString("1 min,2 min,5 min,10 min,15 min,30 min,1 hour,1 day").split(","));
256 int jj = _ephIntrComboBox->findText(settings.value("ephIntr").toString());
257 if (jj != -1) {
258 _ephIntrComboBox->setCurrentIndex(jj);
259 }
260 _outEphPortLineEdit = new QLineEdit(settings.value("outEphPort").toString());
261 _ephV3CheckBox = new QCheckBox();
262 _ephV3CheckBox->setCheckState(Qt::CheckState(settings.value("ephV3").toInt()));
263
264 // Broadcast Corrections Options
265 // -----------------------------
266 _corrPathLineEdit = new QLineEdit(settings.value("corrPath").toString());
267 _corrIntrComboBox = new QComboBox();
268 _corrIntrComboBox->setEditable(false);
269 _corrIntrComboBox->addItems(QString("1 min,2 min,5 min,10 min,15 min,30 min,1 hour,1 day").split(","));
270 int mm = _corrIntrComboBox->findText(settings.value("corrIntr").toString());
271 if (mm != -1) {
272 _corrIntrComboBox->setCurrentIndex(mm);
273 }
274 _corrPortLineEdit = new QLineEdit(settings.value("corrPort").toString());
275 _corrTimeSpinBox = new QSpinBox();
276 _corrTimeSpinBox->setMinimum(1);
277 _corrTimeSpinBox->setMaximum(30);
278 _corrTimeSpinBox->setSingleStep(1);
279 _corrTimeSpinBox->setSuffix(" sec");
280 _corrTimeSpinBox->setValue(settings.value("corrTime").toInt());
281
282 // Feed Engine Options
283 // -------------------
284 _outPortLineEdit = new QLineEdit(settings.value("outPort").toString());
285 _waitTimeSpinBox = new QSpinBox();
286 _waitTimeSpinBox->setMinimum(1);
287 _waitTimeSpinBox->setMaximum(30);
288 _waitTimeSpinBox->setSingleStep(1);
289 _waitTimeSpinBox->setSuffix(" sec");
290 _waitTimeSpinBox->setValue(settings.value("waitTime").toInt());
291 _binSamplSpinBox = new QSpinBox();
292 _binSamplSpinBox->setMinimum(0);
293 _binSamplSpinBox->setMaximum(60);
294 _binSamplSpinBox->setSingleStep(5);
295 _binSamplSpinBox->setValue(settings.value("binSampl").toInt());
296 _binSamplSpinBox->setSuffix(" sec");
297 _outFileLineEdit = new QLineEdit(settings.value("outFile").toString());
298 _outUPortLineEdit = new QLineEdit(settings.value("outUPort").toString());
299
300 // Serial Output Options
301 // ---------------------
302 _serialMountPointLineEdit = new QLineEdit(settings.value("serialMountPoint").toString());
303 _serialPortNameLineEdit = new QLineEdit(settings.value("serialPortName").toString());
304 _serialBaudRateComboBox = new QComboBox();
305 _serialBaudRateComboBox->addItems(QString("110,300,600,"
306 "1200,2400,4800,9600,19200,38400,57600,115200").split(","));
307 int kk = _serialBaudRateComboBox->findText(settings.value("serialBaudRate").toString());
308 if (kk != -1) {
309 _serialBaudRateComboBox->setCurrentIndex(kk);
310 }
311 _serialFlowControlComboBox = new QComboBox();
312 _serialFlowControlComboBox->addItems(QString("OFF,XONXOFF,HARDWARE").split(","));
313 kk = _serialFlowControlComboBox->findText(settings.value("serialFlowControl").toString());
314 if (kk != -1) {
315 _serialFlowControlComboBox->setCurrentIndex(kk);
316 }
317 _serialDataBitsComboBox = new QComboBox();
318 _serialDataBitsComboBox->addItems(QString("5,6,7,8").split(","));
319 kk = _serialDataBitsComboBox->findText(settings.value("serialDataBits").toString());
320 if (kk != -1) {
321 _serialDataBitsComboBox->setCurrentIndex(kk);
322 }
323 _serialParityComboBox = new QComboBox();
324 _serialParityComboBox->addItems(QString("NONE,ODD,EVEN,SPACE").split(","));
325 kk = _serialParityComboBox->findText(settings.value("serialParity").toString());
326 if (kk != -1) {
327 _serialParityComboBox->setCurrentIndex(kk);
328 }
329 _serialStopBitsComboBox = new QComboBox();
330 _serialStopBitsComboBox->addItems(QString("1,2").split(","));
331 kk = _serialStopBitsComboBox->findText(settings.value("serialStopBits").toString());
332 if (kk != -1) {
333 _serialStopBitsComboBox->setCurrentIndex(kk);
334 }
335 _serialAutoNMEAComboBox = new QComboBox();
336 _serialAutoNMEAComboBox->addItems(QString("Auto,Manual").split(","));
337 kk = _serialAutoNMEAComboBox->findText(settings.value("serialAutoNMEA").toString());
338 if (kk != -1) {
339 _serialAutoNMEAComboBox->setCurrentIndex(kk);
340 }
341 _serialFileNMEALineEdit = new QLineEdit(settings.value("serialFileNMEA").toString());
342 _serialHeightNMEALineEdit = new QLineEdit(settings.value("serialHeightNMEA").toString());
343
344 // Outages Options
345 // ---------------
346 _obsRateComboBox = new QComboBox();
347 _obsRateComboBox->setEditable(false);
348 _obsRateComboBox->addItems(QString(",0.1 Hz,0.2 Hz,0.5 Hz,1 Hz,5 Hz").split(","));
349 kk = _obsRateComboBox->findText(settings.value("obsRate").toString());
350 if (kk != -1) {
351 _obsRateComboBox->setCurrentIndex(kk);
352 }
353 _adviseFailSpinBox = new QSpinBox();
354 _adviseFailSpinBox->setMinimum(0);
355 _adviseFailSpinBox->setMaximum(60);
356 _adviseFailSpinBox->setSingleStep(1);
357 _adviseFailSpinBox->setSuffix(" min");
358 _adviseFailSpinBox->setValue(settings.value("adviseFail").toInt());
359 _adviseRecoSpinBox = new QSpinBox();
360 _adviseRecoSpinBox->setMinimum(0);
361 _adviseRecoSpinBox->setMaximum(60);
362 _adviseRecoSpinBox->setSingleStep(1);
363 _adviseRecoSpinBox->setSuffix(" min");
364 _adviseRecoSpinBox->setValue(settings.value("adviseReco").toInt());
365 _adviseScriptLineEdit = new QLineEdit(settings.value("adviseScript").toString());
366
367 // Miscellaneous Options
368 // ---------------------
369 _miscMountLineEdit = new QLineEdit(settings.value("miscMount").toString());
370 _perfIntrComboBox = new QComboBox();
371 _perfIntrComboBox->setEditable(false);
372 _perfIntrComboBox->addItems(QString(",2 sec, 10 sec,1 min,5 min,15 min,1 hour,6 hours,1 day").split(","));
373 int ll = _perfIntrComboBox->findText(settings.value("perfIntr").toString());
374 if (ll != -1) {
375 _perfIntrComboBox->setCurrentIndex(ll);
376 }
377 _scanRTCMCheckBox = new QCheckBox();
378 _scanRTCMCheckBox->setCheckState(Qt::CheckState(
379 settings.value("scanRTCM").toInt()));
380
381 // Streams
382 // -------
383 _mountPointsTable = new QTableWidget(0,8);
384
385 _mountPointsTable->horizontalHeader()->resizeSection(1,34*ww);
386 _mountPointsTable->horizontalHeader()->resizeSection(2,9*ww);
387 _mountPointsTable->horizontalHeader()->resizeSection(3,7*ww);
388 _mountPointsTable->horizontalHeader()->resizeSection(4,7*ww);
389 _mountPointsTable->horizontalHeader()->resizeSection(5,5*ww);
390 _mountPointsTable->horizontalHeader()->resizeSection(6,5*ww);
391 _mountPointsTable->horizontalHeader()->setResizeMode(QHeaderView::Interactive);
392 _mountPointsTable->horizontalHeader()->setStretchLastSection(true);
393 _mountPointsTable->setHorizontalHeaderLabels(labels);
394 _mountPointsTable->setGridStyle(Qt::NoPen);
395 _mountPointsTable->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
396 _mountPointsTable->setSelectionMode(QAbstractItemView::ExtendedSelection);
397 _mountPointsTable->setSelectionBehavior(QAbstractItemView::SelectRows);
398 _mountPointsTable->hideColumn(0);
399 connect(_mountPointsTable, SIGNAL(itemSelectionChanged()),
400 SLOT(slotSelectionChanged()));
401 populateMountPointsTable();
402
403 _log = new QTextBrowser();
404 _log->setReadOnly(true);
405
406 // WhatsThis
407 // ---------
408 _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>"));
409 _proxyPortLineEdit->setWhatsThis(tr("<p>Enter your proxy server port number in case a proxy is operated in front of BNC.</p>"));
410 _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 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>"));
411 _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."));
412 _outPortLineEdit->setWhatsThis(tr("BNC can produce synchronized observations in binary format on your local host through an IP port. Specify a port number here to activate this function."));
413 _outUPortLineEdit->setWhatsThis(tr("BNC can produce unsynchronized observations in binary format on your local host through an IP port. Specify a port number here to activate this function."));
414 _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."));
415 _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."));
416 _corrTimeSpinBox->setWhatsThis(tr("Concerning output through IP port, BNC drops Broadcast Ephemeris Corrections received later than 'Wait for full epoch' seconds. A value of 2 to 5 seconds is recommended, depending on the latency of the incoming correction stream(s) and the delay acceptable to your real-time application."));
417 _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."));
418 _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."));
419 _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."));
420 _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>"));
421 _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>"));
422 _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>"));
423 _autoStartCheckBox->setWhatsThis(tr("<p>Tick 'Auto start' for auto-start of BNC at startup time in window mode with preassigned processing options.</p>"));
424 _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', '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>"));
425 _rnxIntrComboBox->setWhatsThis(tr("<p>Select the length of the RINEX Observation file.</p>"));
426 _ephIntrComboBox->setWhatsThis(tr("<p>Select the length of the RINEX Navigation file.</p>"));
427 _corrIntrComboBox->setWhatsThis(tr("<p>Select the length of the Broadcast Ephemeris Correction files.</p>"));
428 _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>"));
429 _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>"));
430 _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>"));
431 _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>"));
432 _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>"));
433 _logFileLineEdit->setWhatsThis(tr("<p>Records of BNC's activities are shown in the 'Logs' section 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."));
434 _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>"));
435 _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 'Logs' section 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>"));
436 _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 'RTIGS'.</p><p>In case you need to log the raw data as is, BNC allows users to by-pass its decoders and 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>"));
437 _log->setWhatsThis(tr("Records of BNC's activities are shown in the 'Logs' section. 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."));
438 _ephV3CheckBox->setWhatsThis(tr("The default format for output of RINEX Navigation data containing Broadcast Ephemeris is RINEX Version 2.11. Select 'Version 3' if you want to output the ephemeris in RINEX Version 3 format."));
439 _rnxV3CheckBox->setWhatsThis(tr("The default format for RINEX Observation files is RINEX Version 2.11. Select 'Version 3' if you want to save the observations in RINEX Version 3 format."));
440 _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>"));
441 _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>"));
442 _serialMountPointLineEdit->setWhatsThis(tr("<p>Enter a 'Mountpoint' to forward the corresponding stream to a serial connected receiver.</p>"));
443 _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>"));
444 _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>"));
445 _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>"));
446 _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>"));
447 _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>"));
448 _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>"));
449 _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>"));
450 _serialFileNMEALineEdit->setWhatsThis(tr("<p>Specify the full path to a file where NMEA messages coming from your serial connected receiver are saved.</p>"));
451 _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>"));
452
453 // Canvas with Editable Fields
454 // ---------------------------
455 _canvas = new QWidget;
456 setCentralWidget(_canvas);
457
458 _aogroup = new QTabWidget();
459 QWidget* pgroup = new QWidget();
460 QWidget* ggroup = new QWidget();
461 QWidget* sgroup = new QWidget();
462 QWidget* egroup = new QWidget();
463 QWidget* agroup = new QWidget();
464 QWidget* cgroup = new QWidget();
465 QWidget* ogroup = new QWidget();
466 QWidget* rgroup = new QWidget();
467 QWidget* sergroup = new QWidget();
468 _aogroup->addTab(pgroup,tr("Proxy"));
469 _aogroup->addTab(ggroup,tr("General"));
470 _aogroup->addTab(ogroup,tr("RINEX Observations"));
471 _aogroup->addTab(egroup,tr("RINEX Ephemeris"));
472 _aogroup->addTab(cgroup,tr("Broadcast Corrections"));
473 _aogroup->addTab(sgroup,tr("Feed Engine"));
474 _aogroup->addTab(sergroup,tr("Serial Output"));
475 _aogroup->addTab(agroup,tr("Outages"));
476 _aogroup->addTab(rgroup,tr("Miscellaneous"));
477
478 _loggroup = new QTabWidget();
479 QWidget* log1group = new QWidget();
480 QWidget* log2group = new QWidget();
481 _loggroup->addTab(log1group,tr("Log"));
482 _loggroup->addTab(log2group,tr("Status"));
483
484 // log Tab
485 // -------
486 QGridLayout* log1Layout = new QGridLayout;
487 log1Layout->addWidget(_log, 0,0);
488 log1group->setLayout(log1Layout);
489
490 // Status Tab
491 // ----------
492 QGridLayout* log2Layout = new QGridLayout;
493 log2Layout->addWidget(_Figure1, 0,0);
494 log2group->setLayout(log2Layout);
495
496 // Proxy Tab
497 // ---------
498 QGridLayout* pLayout = new QGridLayout;
499 pLayout->setColumnMinimumWidth(0,13*ww);
500 _proxyPortLineEdit->setMaximumWidth(9*ww);
501
502 pLayout->addWidget(new QLabel("Proxy host"), 0, 0);
503 pLayout->addWidget(_proxyHostLineEdit, 0, 1, 1,10);
504 pLayout->addWidget(new QLabel("Proxy port"), 1, 0);
505 pLayout->addWidget(_proxyPortLineEdit, 1, 1);
506 pLayout->addWidget(new QLabel("Settings for the proxy in protected networks, leave boxes blank if none."),2, 0, 1, 50, Qt::AlignLeft);
507 pLayout->addWidget(new QLabel(" "),3,0);
508 pLayout->addWidget(new QLabel(" "),4,0);
509 pLayout->addWidget(new QLabel(" "),5,0);
510 pgroup->setLayout(pLayout);
511
512
513 connect(_proxyHostLineEdit, SIGNAL(textChanged(const QString &)),
514 this, SLOT(bncText(const QString &)));
515 if (_proxyHostLineEdit->text().isEmpty()) {
516 _proxyPortLineEdit->setStyleSheet("background-color: lightGray");
517 _proxyPortLineEdit->setEnabled(false);
518 }
519
520 // General Tab
521 // -----------
522 QGridLayout* gLayout = new QGridLayout;
523 gLayout->setColumnMinimumWidth(0,14*ww);
524 _onTheFlyComboBox->setMaximumWidth(9*ww);
525
526 gLayout->addWidget(new QLabel("Logfile (full path)"), 0, 0);
527 gLayout->addWidget(_logFileLineEdit, 0, 1, 1,30); // 1
528 gLayout->addWidget(new QLabel("Append files"), 1, 0);
529 gLayout->addWidget(_rnxAppendCheckBox, 1, 1);
530 gLayout->addWidget(new QLabel("Reread configuration"), 2, 0);
531 gLayout->addWidget(_onTheFlyComboBox, 2, 1);
532 gLayout->addWidget(new QLabel("Auto start"), 3, 0);
533 gLayout->addWidget(_autoStartCheckBox, 3, 1);
534 gLayout->addWidget(new QLabel("General settings for logfile, file handling, configuration on-the-fly, and auto-start."),4, 0, 1, 50, Qt::AlignLeft); // 2
535 gLayout->addWidget(new QLabel(" "),5,0);
536 ggroup->setLayout(gLayout);
537
538 // RINEX Observations
539 // ------------------
540 QGridLayout* oLayout = new QGridLayout;
541 oLayout->setColumnMinimumWidth(0,14*ww);
542 _rnxIntrComboBox->setMaximumWidth(9*ww);
543 _rnxSamplSpinBox->setMaximumWidth(9*ww);
544
545 oLayout->addWidget(new QLabel("Directory"), 0, 0);
546 oLayout->addWidget(_rnxPathLineEdit, 0, 1,1,24);
547 oLayout->addWidget(new QLabel("Interval"), 1, 0);
548 oLayout->addWidget(_rnxIntrComboBox, 1, 1);
549 oLayout->addWidget(new QLabel(" Sampling"), 1, 2, Qt::AlignRight);
550 oLayout->addWidget(_rnxSamplSpinBox, 1, 3, Qt::AlignLeft);
551 oLayout->addWidget(new QLabel("Skeleton extension"), 2, 0);
552 oLayout->addWidget(_rnxSkelLineEdit, 2, 1,1,1, Qt::AlignLeft);
553 oLayout->addWidget(new QLabel("Script (full path)"), 3, 0);
554 oLayout->addWidget(_rnxScrpLineEdit, 3, 1,1,24);
555 oLayout->addWidget(new QLabel("Version 3"), 4, 0);
556 oLayout->addWidget(_rnxV3CheckBox, 4, 1);
557 oLayout->addWidget(new QLabel("Saving RINEX observation files."),5,0,1,50, Qt::AlignLeft);
558 ogroup->setLayout(oLayout);
559
560 connect(_rnxPathLineEdit, SIGNAL(textChanged(const QString &)),
561 this, SLOT(bncText(const QString &)));
562 if (_rnxPathLineEdit->text().isEmpty()) {
563 _rnxIntrComboBox->setStyleSheet("background-color: lightGray");
564 _rnxSamplSpinBox->setStyleSheet("background-color: lightGray");
565 _rnxSkelLineEdit->setStyleSheet("background-color: lightGray");
566 _rnxScrpLineEdit->setStyleSheet("background-color: lightGray");
567 palette.setColor(_rnxV3CheckBox->backgroundRole(), lightGray);
568 _rnxV3CheckBox->setPalette(palette);
569 _rnxIntrComboBox->setEnabled(false);
570 _rnxSamplSpinBox->setEnabled(false);
571 _rnxSkelLineEdit->setEnabled(false);
572 _rnxScrpLineEdit->setEnabled(false);
573 _rnxV3CheckBox->setEnabled(false);
574 }
575
576 // RINEX Ephemeris
577 // ---------------
578 QGridLayout* eLayout = new QGridLayout;
579 eLayout->setColumnMinimumWidth(0,14*ww);
580 _ephIntrComboBox->setMaximumWidth(9*ww);
581 _outEphPortLineEdit->setMaximumWidth(9*ww);
582
583 eLayout->addWidget(new QLabel("Directory"), 0, 0);
584 eLayout->addWidget(_ephPathLineEdit, 0, 1, 1,30);
585 eLayout->addWidget(new QLabel("Interval"), 1, 0);
586 eLayout->addWidget(_ephIntrComboBox, 1, 1);
587 eLayout->addWidget(new QLabel("Port"), 2, 0);
588 eLayout->addWidget(_outEphPortLineEdit, 2, 1);
589 eLayout->addWidget(new QLabel("Version 3"), 3, 0);
590 eLayout->addWidget(_ephV3CheckBox, 3, 1);
591 eLayout->addWidget(new QLabel("Saving RINEX ephemeris files and ephemeris output through IP port."),4,0,1,50,Qt::AlignLeft);
592 eLayout->addWidget(new QLabel(" "),5,0);
593 egroup->setLayout(eLayout);
594
595 connect(_ephPathLineEdit, SIGNAL(textChanged(const QString &)),
596 this, SLOT(bncText(const QString &)));
597 connect(_outEphPortLineEdit, SIGNAL(textChanged(const QString &)),
598 this, SLOT(bncText(const QString &)));
599
600 if (_ephPathLineEdit->text().isEmpty() && _outEphPortLineEdit->text().isEmpty()) {
601 _ephIntrComboBox->setStyleSheet("background-color: lightGray");
602 palette.setColor(_ephV3CheckBox->backgroundRole(), lightGray);
603 _ephV3CheckBox->setPalette(palette);
604 _ephIntrComboBox->setEnabled(false);
605 _ephV3CheckBox->setEnabled(false);
606 }
607 if (_ephPathLineEdit->text().isEmpty() && !_outEphPortLineEdit->text().isEmpty()) {
608 _ephIntrComboBox->setStyleSheet("background-color: lightGray");
609 _ephIntrComboBox->setEnabled(false);
610 }
611
612 // Broadcast Corrections
613 // ---------------------
614 QGridLayout* cLayout = new QGridLayout;
615 cLayout->setColumnMinimumWidth(0,14*ww);
616 _corrIntrComboBox->setMaximumWidth(9*ww);
617 _corrPortLineEdit->setMaximumWidth(9*ww);
618 _corrTimeSpinBox->setMaximumWidth(9*ww);
619
620 cLayout->addWidget(new QLabel("Directory"), 0, 0);
621 cLayout->addWidget(_corrPathLineEdit, 0, 1,1,20);
622 cLayout->addWidget(new QLabel("Interval"), 1, 0);
623 cLayout->addWidget(_corrIntrComboBox, 1, 1);
624 cLayout->addWidget(new QLabel("Port"), 2, 0);
625 cLayout->addWidget(_corrPortLineEdit, 2, 1);
626 cLayout->addWidget(new QLabel(" Wait for full epoch"), 2, 2, Qt::AlignRight);
627 cLayout->addWidget(_corrTimeSpinBox, 2, 3, Qt::AlignLeft);
628 cLayout->addWidget(new QLabel("Saving Broadcast Ephemeris correction files and correction output through IP port."),3,0,1,50);
629 cLayout->addWidget(new QLabel(" "),4,0);
630 cLayout->addWidget(new QLabel(" "),5,0);
631 cgroup->setLayout(cLayout);
632
633 connect(_corrPathLineEdit, SIGNAL(textChanged(const QString &)),
634 this, SLOT(bncText(const QString &)));
635 connect(_corrPortLineEdit, SIGNAL(textChanged(const QString &)),
636 this, SLOT(bncText(const QString &)));
637 if (_corrPathLineEdit->text().isEmpty()) {
638 _corrIntrComboBox->setStyleSheet("background-color: lightGray");
639 _corrIntrComboBox->setEnabled(false);
640 }
641 if (_corrPortLineEdit->text().isEmpty()) {
642 _corrTimeSpinBox->setStyleSheet("background-color: lightGray");
643 _corrTimeSpinBox->setEnabled(false);
644 }
645
646 // Feed Engine
647 // -----------
648 QGridLayout* sLayout = new QGridLayout;
649 sLayout->setColumnMinimumWidth(0,14*ww);
650 _outPortLineEdit->setMaximumWidth(9*ww);
651 _waitTimeSpinBox->setMaximumWidth(9*ww);
652 _binSamplSpinBox->setMaximumWidth(9*ww);
653 _outUPortLineEdit->setMaximumWidth(9*ww);
654
655 sLayout->addWidget(new QLabel("Port"), 0, 0);
656 sLayout->addWidget(_outPortLineEdit, 0, 1);
657 sLayout->addWidget(new QLabel("Wait for full epoch"), 0, 2, Qt::AlignRight);
658 sLayout->addWidget(_waitTimeSpinBox, 0, 3, Qt::AlignLeft);
659 sLayout->addWidget(new QLabel("Sampling"), 1, 0);
660 sLayout->addWidget(_binSamplSpinBox, 1, 1, Qt::AlignLeft);
661 sLayout->addWidget(new QLabel("File (full path)"), 2, 0);
662 sLayout->addWidget(_outFileLineEdit, 2, 1, 1, 20);
663 sLayout->addWidget(new QLabel("Port (unsynchronized)"), 3, 0);
664 sLayout->addWidget(_outUPortLineEdit, 3, 1);
665 sLayout->addWidget(new QLabel("Output decoded observations in a binary format to feed a real-time GNSS network engine."),4,0,1,50);
666 sLayout->addWidget(new QLabel(" "),5,0);
667 sgroup->setLayout(sLayout);
668
669 connect(_outPortLineEdit, SIGNAL(textChanged(const QString &)),
670 this, SLOT(bncText(const QString &)));
671 connect(_outFileLineEdit, SIGNAL(textChanged(const QString &)),
672 this, SLOT(bncText(const QString &)));
673 if (_outPortLineEdit->text().isEmpty() && _outFileLineEdit->text().isEmpty()) {
674 _waitTimeSpinBox->setStyleSheet("background-color: lightGray");
675 _binSamplSpinBox->setStyleSheet("background-color: lightGray");
676 _waitTimeSpinBox->setEnabled(false);
677 _binSamplSpinBox->setEnabled(false);
678 }
679
680 // Serial Output
681 // -------------
682 QGridLayout* serLayout = new QGridLayout;
683 serLayout->setColumnMinimumWidth(0,14*ww);
684 _serialBaudRateComboBox->setMaximumWidth(9*ww);
685 _serialFlowControlComboBox->setMaximumWidth(11*ww);
686 _serialDataBitsComboBox->setMaximumWidth(5*ww);
687 _serialParityComboBox->setMaximumWidth(9*ww);
688 _serialStopBitsComboBox->setMaximumWidth(5*ww);
689 _serialAutoNMEAComboBox->setMaximumWidth(9*ww);
690 _serialHeightNMEALineEdit->setMaximumWidth(8*ww);
691
692 serLayout->addWidget(new QLabel("Mountpoint"), 0,0, Qt::AlignLeft);
693 serLayout->addWidget(_serialMountPointLineEdit, 0,1,1,2);
694 serLayout->addWidget(new QLabel("Port name"), 1,0, Qt::AlignLeft);
695 serLayout->addWidget(_serialPortNameLineEdit, 1,1,1,2);
696 serLayout->addWidget(new QLabel("Baud rate"), 2,0, Qt::AlignLeft);
697 serLayout->addWidget(_serialBaudRateComboBox, 2,1);
698 serLayout->addWidget(new QLabel("Flow control"), 2,2, Qt::AlignRight);
699 serLayout->addWidget(_serialFlowControlComboBox, 2,3);
700 serLayout->addWidget(new QLabel("Data bits"), 3,0, Qt::AlignLeft);
701 serLayout->addWidget(_serialDataBitsComboBox, 3,1);
702 serLayout->addWidget(new QLabel("Parity"), 3,2, Qt::AlignRight);
703 serLayout->addWidget(_serialParityComboBox, 3,3);
704 serLayout->addWidget(new QLabel(" Stop bits"), 3,4, Qt::AlignRight);
705 serLayout->addWidget(_serialStopBitsComboBox, 3,5);
706 serLayout->addWidget(new QLabel("NMEA"), 4,0);
707 serLayout->addWidget(_serialAutoNMEAComboBox, 4,1);
708 serLayout->addWidget(new QLabel(" File (full path)"), 4,2, Qt::AlignRight);
709 serLayout->addWidget(_serialFileNMEALineEdit, 4,3,1,15);
710 serLayout->addWidget(new QLabel("Height"), 4,20, Qt::AlignRight);
711 serLayout->addWidget(_serialHeightNMEALineEdit, 4,21,1,11);
712 serLayout->addWidget(new QLabel("Port settings to feed a serial connected receiver."),5,0,1,30);
713
714 connect(_serialMountPointLineEdit, SIGNAL(textChanged(const QString &)),
715 this, SLOT(bncText(const QString &)));
716 connect(_serialAutoNMEAComboBox, SIGNAL(currentIndexChanged(const QString &)),
717 this, SLOT(bncText(const QString)));
718 if (_serialMountPointLineEdit->text().isEmpty()) {
719 _serialPortNameLineEdit->setStyleSheet("background-color: lightGray");
720 _serialBaudRateComboBox->setStyleSheet("background-color: lightGray");
721 _serialParityComboBox->setStyleSheet("background-color: lightGray");
722 _serialDataBitsComboBox->setStyleSheet("background-color: lightGray");
723 _serialStopBitsComboBox->setStyleSheet("background-color: lightGray");
724 _serialFlowControlComboBox->setStyleSheet("background-color: lightGray");
725 _serialAutoNMEAComboBox->setStyleSheet("background-color: lightGray");
726 _serialFileNMEALineEdit->setStyleSheet("background-color: lightGray");
727 _serialHeightNMEALineEdit->setStyleSheet("background-color: lightGray");
728 _serialPortNameLineEdit->setEnabled(false);
729 _serialBaudRateComboBox->setEnabled(false);
730 _serialParityComboBox->setEnabled(false);
731 _serialDataBitsComboBox->setEnabled(false);
732 _serialStopBitsComboBox->setEnabled(false);
733 _serialFlowControlComboBox->setEnabled(false);
734 _serialAutoNMEAComboBox->setEnabled(false);
735 _serialFileNMEALineEdit->setEnabled(false);
736 _serialHeightNMEALineEdit->setEnabled(false);
737 } else {
738 if (_serialAutoNMEAComboBox->currentText() == "Auto" ) {
739 _serialHeightNMEALineEdit->setStyleSheet("background-color: lightGray");
740 _serialHeightNMEALineEdit->setEnabled(false);
741 }
742 if (_serialAutoNMEAComboBox->currentText() != "Auto" ) {
743 _serialFileNMEALineEdit->setStyleSheet("background-color: lightGray");
744 _serialFileNMEALineEdit->setEnabled(false);
745 }
746 }
747
748 sergroup->setLayout(serLayout);
749
750 // Outages
751 // -------
752 QGridLayout* aLayout = new QGridLayout;
753 aLayout->setColumnMinimumWidth(0,14*ww);
754 _obsRateComboBox->setMaximumWidth(9*ww);
755 _adviseFailSpinBox->setMaximumWidth(9*ww);
756 _adviseRecoSpinBox->setMaximumWidth(9*ww);
757
758 aLayout->addWidget(new QLabel("Observation rate"), 0, 0);
759 aLayout->addWidget(_obsRateComboBox, 0, 1);
760 aLayout->addWidget(new QLabel("Failure threshold"), 1, 0);
761 aLayout->addWidget(_adviseFailSpinBox, 1, 1);
762 aLayout->addWidget(new QLabel("Recovery threshold"), 2, 0);
763 aLayout->addWidget(_adviseRecoSpinBox, 2, 1);
764 aLayout->addWidget(new QLabel("Script (full path)"), 3, 0);
765 aLayout->addWidget(_adviseScriptLineEdit, 3, 1,1,30);
766 aLayout->addWidget(new QLabel("Failure and recovery reports, advisory notes."),5,0,1,50,Qt::AlignLeft);
767 agroup->setLayout(aLayout);
768
769 connect(_obsRateComboBox, SIGNAL(currentIndexChanged(const QString &)),
770 this, SLOT(bncText(const QString)));
771 if (_obsRateComboBox->currentText().isEmpty()) {
772 _adviseFailSpinBox->setStyleSheet("background-color: lightGray");
773 _adviseRecoSpinBox->setStyleSheet("background-color: lightGray");
774 _adviseScriptLineEdit->setStyleSheet("background-color: lightGray");
775 _adviseFailSpinBox->setEnabled(false);
776 _adviseRecoSpinBox->setEnabled(false);
777 _adviseScriptLineEdit->setEnabled(false);
778 }
779
780 // Miscellaneous
781 // -------------
782 QGridLayout* rLayout = new QGridLayout;
783 rLayout->setColumnMinimumWidth(0,14*ww);
784 _perfIntrComboBox->setMaximumWidth(9*ww);
785
786 rLayout->addWidget(new QLabel("Mountpoint"), 0, 0);
787 rLayout->addWidget(_miscMountLineEdit, 0, 1, 1,7);
788 rLayout->addWidget(new QLabel("Log latency"), 1, 0);
789 rLayout->addWidget(_perfIntrComboBox, 1, 1);
790 rLayout->addWidget(new QLabel("Scan RTCM"), 2, 0);
791 rLayout->addWidget(_scanRTCMCheckBox, 2, 1);
792 rLayout->addWidget(new QLabel("Log latencies or scan RTCM streams for numbers of message types and antenna information."),3, 0,1,30);
793 rLayout->addWidget(new QLabel(" "), 4, 0);
794 rLayout->addWidget(new QLabel(" "), 5, 0);
795 rgroup->setLayout(rLayout);
796
797 connect(_miscMountLineEdit, SIGNAL(textChanged(const QString &)),
798 this, SLOT(bncText(const QString &)));
799 if (_miscMountLineEdit->text().isEmpty()) {
800 _perfIntrComboBox->setStyleSheet("background-color: lightGray");
801 palette.setColor(_scanRTCMCheckBox->backgroundRole(), lightGray);
802 _scanRTCMCheckBox->setPalette(palette);
803 _perfIntrComboBox->setEnabled(false);
804 _scanRTCMCheckBox->setEnabled(false);
805 }
806
807 // Main Layout
808 // -----------
809
810 QGridLayout* mLayout = new QGridLayout;
811 _aogroup->setCurrentIndex(settings.value("startTab").toInt());
812 mLayout->addWidget(_aogroup, 0,0);
813 mLayout->addWidget(_mountPointsTable, 1,0);
814 mLayout->addWidget(_loggroup, 2,0);
815
816 _canvas->setLayout(mLayout);
817
818 // Auto start
819 // ----------
820 if ( Qt::CheckState(settings.value("autoStart").toInt()) == Qt::Checked) {
821 slotGetData();
822 }
823}
824
825// Destructor
826////////////////////////////////////////////////////////////////////////////
827bncWindow::~bncWindow() {
828 delete _caster;
829}
830
831//
832////////////////////////////////////////////////////////////////////////////
833void bncWindow::populateMountPointsTable() {
834
835 for (int iRow = _mountPointsTable->rowCount()-1; iRow >=0; iRow--) {
836 _mountPointsTable->removeRow(iRow);
837 }
838
839 bncSettings settings;
840
841 QListIterator<QString> it(settings.value("mountPoints").toStringList());
842 if (!it.hasNext()) {
843 _actGetData->setEnabled(false);
844 }
845 int iRow = 0;
846 while (it.hasNext()) {
847 QStringList hlp = it.next().split(" ");
848 if (hlp.size() < 5) continue;
849 _mountPointsTable->insertRow(iRow);
850
851 QUrl url(hlp[0]);
852
853 QString fullPath = url.host() + QString(":%1").arg(url.port()) + url.path();
854 QString format(hlp[1]); QString latitude(hlp[2]); QString longitude(hlp[3]);
855 QString nmea(hlp[4]);
856 if (hlp[5] == "S") {
857 fullPath = hlp[0].replace(0,2,"");
858 }
859 QString ntripVersion = "1";
860 if (hlp.size() >= 6) {
861 ntripVersion = (hlp[5]);
862 }
863
864 QTableWidgetItem* it;
865 it = new QTableWidgetItem(url.userInfo());
866 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
867 _mountPointsTable->setItem(iRow, 0, it);
868
869 it = new QTableWidgetItem(fullPath);
870 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
871 _mountPointsTable->setItem(iRow, 1, it);
872
873 it = new QTableWidgetItem(format);
874 _mountPointsTable->setItem(iRow, 2, it);
875
876 if (nmea == "yes") {
877 it = new QTableWidgetItem(latitude);
878 _mountPointsTable->setItem(iRow, 3, it);
879 it = new QTableWidgetItem(longitude);
880 _mountPointsTable->setItem(iRow, 4, it);
881 } else {
882 it = new QTableWidgetItem(latitude);
883 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
884 _mountPointsTable->setItem(iRow, 3, it);
885 it = new QTableWidgetItem(longitude);
886 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
887 _mountPointsTable->setItem(iRow, 4, it);
888 }
889
890 it = new QTableWidgetItem(nmea);
891 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
892 _mountPointsTable->setItem(iRow, 5, it);
893
894 it = new QTableWidgetItem(ntripVersion);
895 //// it->setFlags(it->flags() & ~Qt::ItemIsEditable);
896 _mountPointsTable->setItem(iRow, 6, it);
897
898 bncTableItem* bncIt = new bncTableItem();
899 bncIt->setFlags(bncIt->flags() & ~Qt::ItemIsEditable);
900 _mountPointsTable->setItem(iRow, 7, bncIt);
901
902 iRow++;
903 }
904
905 _mountPointsTable->sortItems(1);
906}
907
908// Retrieve Table
909////////////////////////////////////////////////////////////////////////////
910void bncWindow::slotAddMountPoints() {
911
912 bncSettings settings;
913 QString proxyHost = settings.value("proxyHost").toString();
914 int proxyPort = settings.value("proxyPort").toInt();
915 if (proxyHost != _proxyHostLineEdit->text() ||
916 proxyPort != _proxyPortLineEdit->text().toInt()) {
917 int iRet = QMessageBox::question(this, "Question", "Proxy options "
918 "changed. Use the new ones?",
919 QMessageBox::Yes, QMessageBox::No,
920 QMessageBox::NoButton);
921 if (iRet == QMessageBox::Yes) {
922 settings.setValue("proxyHost", _proxyHostLineEdit->text());
923 settings.setValue("proxyPort", _proxyPortLineEdit->text());
924 settings.sync();
925 }
926 }
927
928 QMessageBox msgBox;
929 msgBox.setIcon(QMessageBox::Question);
930 msgBox.setWindowTitle("Add Stream");
931 msgBox.setText("Add stream(s) coming from:");
932
933 QPushButton* buttonNtrip = msgBox.addButton(tr("Caster"), QMessageBox::ActionRole);
934 QPushButton* buttonIP = msgBox.addButton(tr("TCP/IP port"), QMessageBox::ActionRole);
935 QPushButton* buttonUDP = msgBox.addButton(tr("UDP port"), QMessageBox::ActionRole);
936 QPushButton* buttonSerial = msgBox.addButton(tr("Serial port"), QMessageBox::ActionRole);
937 QPushButton* buttonCancel = msgBox.addButton(tr("Cancel"), QMessageBox::ActionRole);
938
939 msgBox.exec();
940
941 if (msgBox.clickedButton() == buttonNtrip) {
942 bncTableDlg* dlg = new bncTableDlg(this);
943 dlg->move(this->pos().x()+50, this->pos().y()+50);
944 connect(dlg, SIGNAL(newMountPoints(QStringList*)),
945 this, SLOT(slotNewMountPoints(QStringList*)));
946 dlg->exec();
947 delete dlg;
948 } else if (msgBox.clickedButton() == buttonIP) {
949 bncIpPort* ipp = new bncIpPort(this);
950 connect(ipp, SIGNAL(newMountPoints(QStringList*)),
951 this, SLOT(slotNewMountPoints(QStringList*)));
952 ipp->exec();
953 delete ipp;
954 } else if (msgBox.clickedButton() == buttonUDP) {
955 bncUdpPort* udp = new bncUdpPort(this);
956 connect(udp, SIGNAL(newMountPoints(QStringList*)),
957 this, SLOT(slotNewMountPoints(QStringList*)));
958 udp->exec();
959 delete udp;
960 } else if (msgBox.clickedButton() == buttonSerial) {
961 bncSerialPort* sep = new bncSerialPort(this);
962 connect(sep, SIGNAL(newMountPoints(QStringList*)),
963 this, SLOT(slotNewMountPoints(QStringList*)));
964 sep->exec();
965 delete sep;
966 } else if (msgBox.clickedButton() == buttonCancel) {
967 // Cancel
968 }
969}
970
971// Delete Selected Mount Points
972////////////////////////////////////////////////////////////////////////////
973void bncWindow::slotDeleteMountPoints() {
974
975 int nRows = _mountPointsTable->rowCount();
976 bool flg[nRows];
977 for (int iRow = 0; iRow < nRows; iRow++) {
978 if (_mountPointsTable->isItemSelected(_mountPointsTable->item(iRow,1))) {
979 flg[iRow] = true;
980 }
981 else {
982 flg[iRow] = false;
983 }
984 }
985 for (int iRow = nRows-1; iRow >= 0; iRow--) {
986 if (flg[iRow]) {
987 _mountPointsTable->removeRow(iRow);
988 }
989 }
990 _actDeleteMountPoints->setEnabled(false);
991
992 if (_mountPointsTable->rowCount() == 0) {
993 _actGetData->setEnabled(false);
994 }
995}
996
997// New Mount Points Selected
998////////////////////////////////////////////////////////////////////////////
999void bncWindow::slotNewMountPoints(QStringList* mountPoints) {
1000 int iRow = 0;
1001 QListIterator<QString> it(*mountPoints);
1002 while (it.hasNext()) {
1003 QStringList hlp = it.next().split(" ");
1004 QUrl url(hlp[0]);
1005 QString fullPath = url.host() + QString(":%1").arg(url.port()) + url.path();
1006 QString format(hlp[1]); QString latitude(hlp[2]); QString longitude(hlp[3]);
1007 QString nmea(hlp[4]);
1008 if (hlp[5] == "S") {
1009 fullPath = hlp[0].replace(0,2,"");
1010 }
1011 QString ntripVersion = "1";
1012 if (hlp.size() >= 6) {
1013 ntripVersion = (hlp[5]);
1014 }
1015
1016 _mountPointsTable->insertRow(iRow);
1017
1018 QTableWidgetItem* it;
1019 it = new QTableWidgetItem(url.userInfo());
1020 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
1021 _mountPointsTable->setItem(iRow, 0, it);
1022
1023 it = new QTableWidgetItem(fullPath);
1024 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
1025 _mountPointsTable->setItem(iRow, 1, it);
1026
1027 it = new QTableWidgetItem(format);
1028 _mountPointsTable->setItem(iRow, 2, it);
1029
1030 if (nmea == "yes") {
1031 it = new QTableWidgetItem(latitude);
1032 _mountPointsTable->setItem(iRow, 3, it);
1033 it = new QTableWidgetItem(longitude);
1034 _mountPointsTable->setItem(iRow, 4, it);
1035 } else {
1036 it = new QTableWidgetItem(latitude);
1037 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
1038 _mountPointsTable->setItem(iRow, 3, it);
1039 it = new QTableWidgetItem(longitude);
1040 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
1041 _mountPointsTable->setItem(iRow, 4, it);
1042 }
1043
1044 it = new QTableWidgetItem(nmea);
1045 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
1046 _mountPointsTable->setItem(iRow, 5, it);
1047
1048 it = new QTableWidgetItem(ntripVersion);
1049 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
1050 _mountPointsTable->setItem(iRow, 6, it);
1051
1052 bncTableItem* bncIt = new bncTableItem();
1053 _mountPointsTable->setItem(iRow, 7, bncIt);
1054
1055 iRow++;
1056 }
1057 _mountPointsTable->hideColumn(0);
1058 _mountPointsTable->sortItems(1);
1059 if (mountPoints->count() > 0 && !_actStop->isEnabled()) {
1060 _actGetData->setEnabled(true);
1061 }
1062 delete mountPoints;
1063}
1064
1065// Save Options
1066////////////////////////////////////////////////////////////////////////////
1067void bncWindow::slotSaveOptions() {
1068
1069 QStringList mountPoints;
1070 for (int iRow = 0; iRow < _mountPointsTable->rowCount(); iRow++) {
1071
1072 if (_mountPointsTable->item(iRow, 6)->text() != "S") {
1073 QUrl url( "//" + _mountPointsTable->item(iRow, 0)->text() +
1074 "@" + _mountPointsTable->item(iRow, 1)->text() );
1075
1076 mountPoints.append(url.toString() + " " +
1077 _mountPointsTable->item(iRow, 2)->text()
1078 + " " + _mountPointsTable->item(iRow, 3)->text()
1079 + " " + _mountPointsTable->item(iRow, 4)->text()
1080 + " " + _mountPointsTable->item(iRow, 5)->text()
1081 + " " + _mountPointsTable->item(iRow, 6)->text());
1082 } else {
1083 mountPoints.append(
1084 "//" + _mountPointsTable->item(iRow, 1)->text()
1085 + " " + _mountPointsTable->item(iRow, 2)->text()
1086 + " " + _mountPointsTable->item(iRow, 3)->text()
1087 + " " + _mountPointsTable->item(iRow, 4)->text()
1088 + " " + _mountPointsTable->item(iRow, 5)->text()
1089 + " " + _mountPointsTable->item(iRow, 6)->text());
1090 }
1091 }
1092
1093 bncSettings settings;
1094
1095 settings.setValue("adviseFail", _adviseFailSpinBox->value());
1096 settings.setValue("adviseReco", _adviseRecoSpinBox->value());
1097 settings.setValue("adviseScript",_adviseScriptLineEdit->text());
1098 settings.setValue("autoStart", _autoStartCheckBox->checkState());
1099 settings.setValue("binSampl", _binSamplSpinBox->value());
1100 settings.setValue("corrIntr", _corrIntrComboBox->currentText());
1101 settings.setValue("corrPath", _corrPathLineEdit->text());
1102 settings.setValue("corrPort", _corrPortLineEdit->text());
1103 settings.setValue("corrTime", _corrTimeSpinBox->value());
1104 settings.setValue("ephIntr", _ephIntrComboBox->currentText());
1105 settings.setValue("ephPath", _ephPathLineEdit->text());
1106 settings.setValue("ephV3", _ephV3CheckBox->checkState());
1107 settings.setValue("logFile", _logFileLineEdit->text());
1108 settings.setValue("miscMount", _miscMountLineEdit->text());
1109 settings.setValue("mountPoints", mountPoints);
1110 settings.setValue("obsRate", _obsRateComboBox->currentText());
1111 settings.setValue("onTheFlyInterval", _onTheFlyComboBox->currentText());
1112 settings.setValue("outEphPort", _outEphPortLineEdit->text());
1113 settings.setValue("outFile", _outFileLineEdit->text());
1114 settings.setValue("outPort", _outPortLineEdit->text());
1115 settings.setValue("outUPort", _outUPortLineEdit->text());
1116 settings.setValue("perfIntr", _perfIntrComboBox->currentText());
1117 settings.setValue("proxyHost", _proxyHostLineEdit->text());
1118 settings.setValue("proxyPort", _proxyPortLineEdit->text());
1119 settings.setValue("rnxAppend", _rnxAppendCheckBox->checkState());
1120 settings.setValue("rnxIntr", _rnxIntrComboBox->currentText());
1121 settings.setValue("rnxPath", _rnxPathLineEdit->text());
1122 settings.setValue("rnxSampl", _rnxSamplSpinBox->value());
1123 settings.setValue("rnxScript", _rnxScrpLineEdit->text());
1124 settings.setValue("rnxSkel", _rnxSkelLineEdit->text());
1125 settings.setValue("rnxV3", _rnxV3CheckBox->checkState());
1126 settings.setValue("scanRTCM", _scanRTCMCheckBox->checkState());
1127 settings.setValue("serialFileNMEA",_serialFileNMEALineEdit->text());
1128 settings.setValue("serialHeightNMEA",_serialHeightNMEALineEdit->text());
1129 settings.setValue("serialAutoNMEA", _serialAutoNMEAComboBox->currentText());
1130 settings.setValue("serialBaudRate", _serialBaudRateComboBox->currentText());
1131 settings.setValue("serialDataBits", _serialDataBitsComboBox->currentText());
1132 settings.setValue("serialMountPoint",_serialMountPointLineEdit->text());
1133 settings.setValue("serialParity", _serialParityComboBox->currentText());
1134 settings.setValue("serialPortName", _serialPortNameLineEdit->text());
1135 settings.setValue("serialStopBits", _serialStopBitsComboBox->currentText());
1136 settings.setValue("serialFlowControl",_serialFlowControlComboBox->currentText());
1137 settings.setValue("startTab", _aogroup->currentIndex());
1138 settings.setValue("waitTime", _waitTimeSpinBox->value());
1139
1140 if (_caster) {
1141 _caster->slotReadMountPoints();
1142 }
1143 settings.sync();
1144}
1145
1146// All get slots terminated
1147////////////////////////////////////////////////////////////////////////////
1148void bncWindow::slotGetThreadsFinished() {
1149 ((bncApp*)qApp)->slotMessage("All Get Threads Terminated", true);
1150 delete _caster; _caster = 0;
1151 _actGetData->setEnabled(true);
1152 _actStop->setEnabled(false);
1153}
1154
1155// Retrieve Data
1156////////////////////////////////////////////////////////////////////////////
1157void bncWindow::slotGetData() {
1158 slotSaveOptions();
1159
1160 _actDeleteMountPoints->setEnabled(false);
1161 _actGetData->setEnabled(false);
1162 _actStop->setEnabled(true);
1163
1164 _caster = new bncCaster(_outFileLineEdit->text(),
1165 _outPortLineEdit->text().toInt());
1166
1167 ((bncApp*)qApp)->setPort(_outEphPortLineEdit->text().toInt());
1168 ((bncApp*)qApp)->setPortCorr(_corrPortLineEdit->text().toInt());
1169
1170 connect(_caster, SIGNAL(getThreadsFinished()),
1171 this, SLOT(slotGetThreadsFinished()));
1172
1173 connect (_caster, SIGNAL(mountPointsRead(QList<bncGetThread*>)),
1174 this, SLOT(slotMountPointsRead(QList<bncGetThread*>)));
1175
1176 ((bncApp*)qApp)->slotMessage("============ Start BNC ============", true);
1177
1178 bncSettings settings;
1179
1180 QDir rnxdir(settings.value("rnxPath").toString());
1181 if (!rnxdir.exists()) ((bncApp*)qApp)->slotMessage("Cannot find RINEX Observations directory", true);
1182
1183 QString rnx_file = settings.value("rnxScript").toString();
1184 if ( !rnx_file.isEmpty() ) {
1185 QFile rnxfile(settings.value("rnxScript").toString());
1186 if (!rnxfile.exists()) ((bncApp*)qApp)->slotMessage("Cannot find RINEX Observations script", true);
1187 }
1188
1189 QDir ephdir(settings.value("ephPath").toString());
1190 if (!ephdir.exists()) ((bncApp*)qApp)->slotMessage("Cannot find RINEX Ephemeris directory", true);
1191
1192 QDir corrdir(settings.value("corrPath").toString());
1193 if (!corrdir.exists()) ((bncApp*)qApp)->slotMessage("Cannot find Broadcast Corrections directory", true);
1194
1195 QString advise_file = settings.value("adviseScript").toString();
1196 if ( !advise_file.isEmpty() ) {
1197 QFile advisefile(settings.value("adviseScript").toString());
1198 if (!advisefile.exists()) ((bncApp*)qApp)->slotMessage("Cannot find Outages script", true);
1199 }
1200
1201 _caster->slotReadMountPoints();
1202}
1203
1204// Retrieve Data
1205////////////////////////////////////////////////////////////////////////////
1206void bncWindow::slotStop() {
1207 int iRet = QMessageBox::question(this, "Stop", "Stop retrieving data?",
1208 QMessageBox::Yes, QMessageBox::No,
1209 QMessageBox::NoButton);
1210 if (iRet == QMessageBox::Yes) {
1211 delete _caster; _caster = 0;
1212 _actGetData->setEnabled(true);
1213 _actStop->setEnabled(false);
1214 }
1215}
1216
1217// Close Application gracefully
1218////////////////////////////////////////////////////////////////////////////
1219void bncWindow::closeEvent(QCloseEvent* event) {
1220
1221 int iRet = QMessageBox::question(this, "Close", "Save Options?",
1222 QMessageBox::Yes, QMessageBox::No,
1223 QMessageBox::Cancel);
1224
1225 if (iRet == QMessageBox::Cancel) {
1226 event->ignore();
1227 return;
1228 }
1229 else if (iRet == QMessageBox::Yes) {
1230 slotSaveOptions();
1231 }
1232
1233 QMainWindow::closeEvent(event);
1234}
1235
1236// User changed the selection of mountPoints
1237////////////////////////////////////////////////////////////////////////////
1238void bncWindow::slotSelectionChanged() {
1239 if (_mountPointsTable->selectedItems().isEmpty()) {
1240 _actDeleteMountPoints->setEnabled(false);
1241 }
1242 else {
1243 _actDeleteMountPoints->setEnabled(true);
1244 }
1245}
1246
1247// Display Program Messages
1248////////////////////////////////////////////////////////////////////////////
1249void bncWindow::slotWindowMessage(const QByteArray msg, bool showOnScreen) {
1250
1251#ifdef DEBUG_RTCM2_2021
1252 const int maxBufferSize = 1000;
1253#else
1254 const int maxBufferSize = 10000;
1255#endif
1256
1257 if (! showOnScreen ) {
1258 return;
1259 }
1260
1261 QString txt = _log->toPlainText() + "\n" +
1262 QDateTime::currentDateTime().toUTC().toString("yy-MM-dd hh:mm:ss ") + msg;
1263 _log->clear();
1264 _log->append(txt.right(maxBufferSize));
1265}
1266
1267// About Message
1268////////////////////////////////////////////////////////////////////////////
1269void bncWindow::slotAbout() {
1270 new bncAboutDlg(0);
1271}
1272
1273//Flowchart
1274////////////////////////////////////////////////////////////////////////////
1275void bncWindow::slotFlowchart() {
1276 new bncFlowchartDlg(0);
1277}
1278
1279// Help Window
1280////////////////////////////////////////////////////////////////////////////
1281void bncWindow::slotHelp() {
1282 QUrl url;
1283 url.setPath(":bnchelp.html");
1284 new bncHlpDlg(0, url);
1285}
1286
1287// Select Fonts
1288////////////////////////////////////////////////////////////////////////////
1289void bncWindow::slotFontSel() {
1290 bool ok;
1291 QFont newFont = QFontDialog::getFont(&ok, this->font(), this);
1292 if (ok) {
1293 bncSettings settings;
1294 settings.setValue("font", newFont.toString());
1295 QApplication::setFont(newFont);
1296 int ww = QFontMetrics(newFont).width('w');
1297 setMinimumSize(60*ww, 80*ww);
1298 resize(60*ww, 80*ww);
1299 }
1300}
1301
1302// Whats This Help
1303void bncWindow::slotWhatsThis() {
1304 QWhatsThis::enterWhatsThisMode();
1305}
1306
1307//
1308////////////////////////////////////////////////////////////////////////////
1309void bncWindow::slotMountPointsRead(QList<bncGetThread*> threads) {
1310 populateMountPointsTable();
1311 bncSettings settings;
1312 _binSamplSpinBox->setValue(settings.value("binSampl").toInt());
1313 _waitTimeSpinBox->setValue(settings.value("waitTime").toInt());
1314 QListIterator<bncGetThread*> iTh(threads);
1315 while (iTh.hasNext()) {
1316 bncGetThread* thread = iTh.next();
1317 for (int iRow = 0; iRow < _mountPointsTable->rowCount(); iRow++) {
1318 QUrl url( "//" + _mountPointsTable->item(iRow, 0)->text() +
1319 "@" + _mountPointsTable->item(iRow, 1)->text() );
1320 if (url == thread->mountPoint() &&
1321 _mountPointsTable->item(iRow, 3)->text() == thread->latitude() &&
1322 _mountPointsTable->item(iRow, 4)->text() == thread->longitude() ) {
1323 ((bncTableItem*) _mountPointsTable->item(iRow, 7))->setGetThread(thread);
1324 connect(thread, SIGNAL(newBytes(QByteArray, double)),
1325 _Figure1, SLOT(slotNewData(QByteArray, double)));
1326
1327 break;
1328 }
1329 }
1330 }
1331}
1332
1333//
1334////////////////////////////////////////////////////////////////////////////
1335void bncWindow::CreateMenu() {
1336 // Create Menus
1337 // ------------
1338 _menuFile = menuBar()->addMenu(tr("&File"));
1339 _menuFile->addAction(_actFontSel);
1340 _menuFile->addSeparator();
1341 _menuFile->addAction(_actSaveOpt);
1342 _menuFile->addSeparator();
1343 _menuFile->addAction(_actQuit);
1344
1345 _menuHlp = menuBar()->addMenu(tr("&Help"));
1346 _menuHlp->addAction(_actHelp);
1347 _menuHlp->addAction(_actFlowchart);
1348 _menuHlp->addAction(_actAbout);
1349}
1350
1351// Toolbar
1352////////////////////////////////////////////////////////////////////////////
1353void bncWindow::AddToolbar() {
1354 // Tool (Command) Bar
1355 // ------------------
1356 QToolBar* toolBar = new QToolBar;
1357 addToolBar(Qt::BottomToolBarArea, toolBar);
1358 toolBar->setMovable(false);
1359 toolBar->addAction(_actAddMountPoints);
1360 toolBar->addAction(_actDeleteMountPoints);
1361 toolBar->addAction(_actGetData);
1362 toolBar->addAction(_actStop);
1363 toolBar->addWidget(new QLabel(" "));
1364 toolBar->addAction(_actwhatsthis);
1365}
1366
1367// About
1368////////////////////////////////////////////////////////////////////////////
1369bncAboutDlg::bncAboutDlg(QWidget* parent) :
1370 QDialog(parent) {
1371
1372 QTextBrowser* tb = new QTextBrowser;
1373 QUrl url; url.setPath(":bncabout.html");
1374 tb->setSource(url);
1375 tb->setReadOnly(true);
1376
1377 int ww = QFontMetrics(font()).width('w');
1378 QPushButton* _closeButton = new QPushButton("Close");
1379 _closeButton->setMaximumWidth(10*ww);
1380 connect(_closeButton, SIGNAL(clicked()), this, SLOT(close()));
1381
1382 QGridLayout* dlgLayout = new QGridLayout();
1383 QLabel* img = new QLabel();
1384 img->setPixmap(QPixmap(":ntrip-logo.png"));
1385 dlgLayout->addWidget(img, 0,0);
1386 dlgLayout->addWidget(new QLabel("BKG Ntrip Client (BNC) Version 1.7"), 0,1);
1387 dlgLayout->addWidget(tb,1,0,1,2);
1388 dlgLayout->addWidget(_closeButton,2,1,Qt::AlignRight);
1389
1390 setLayout(dlgLayout);
1391 resize(60*ww, 60*ww);
1392 setWindowTitle("About BNC");
1393 show();
1394}
1395
1396//
1397////////////////////////////////////////////////////////////////////////////
1398bncAboutDlg::~bncAboutDlg() {
1399};
1400
1401// Flowchart
1402////////////////////////////////////////////////////////////////////////////
1403bncFlowchartDlg::bncFlowchartDlg(QWidget* parent) :
1404 QDialog(parent) {
1405
1406 int ww = QFontMetrics(font()).width('w');
1407 QPushButton* _closeButton = new QPushButton("Close");
1408 _closeButton->setMaximumWidth(10*ww);
1409 connect(_closeButton, SIGNAL(clicked()), this, SLOT(close()));
1410
1411 QGridLayout* dlgLayout = new QGridLayout();
1412 QLabel* img = new QLabel();
1413 img->setPixmap(QPixmap(":bncflowchart.png"));
1414 dlgLayout->addWidget(img, 0,0);
1415 dlgLayout->addWidget(_closeButton,1,0,Qt::AlignLeft);
1416
1417 setLayout(dlgLayout);
1418 setWindowTitle("Flow Chart");
1419 show();
1420}
1421
1422//
1423////////////////////////////////////////////////////////////////////////////
1424bncFlowchartDlg::~bncFlowchartDlg() {
1425};
1426
1427// Bnc Text
1428////////////////////////////////////////////////////////////////////////////
1429void bncWindow::bncText(const QString &text){
1430
1431 bool isEmpty = text.isEmpty();
1432
1433 QPalette palette;
1434 QColor lightGray(230, 230, 230);
1435 QColor white(255, 255, 255);
1436
1437
1438 // Proxy
1439 //------
1440 if (_aogroup->currentIndex() == 0) {
1441 if (!isEmpty) {
1442 _proxyPortLineEdit->setStyleSheet("background-color: white");
1443 _proxyPortLineEdit->setEnabled(true);
1444 } else {
1445 _proxyPortLineEdit->setStyleSheet("background-color: lightGray");
1446 _proxyPortLineEdit->setEnabled(false);
1447 }
1448 }
1449
1450 // RINEX Observations
1451 // ------------------
1452 if (_aogroup->currentIndex() == 2) {
1453 if (!isEmpty) {
1454 _rnxSamplSpinBox->setStyleSheet("background-color: white");
1455 _rnxSkelLineEdit->setStyleSheet("background-color: white");
1456 _rnxScrpLineEdit->setStyleSheet("background-color: white");
1457 palette.setColor(_rnxV3CheckBox->backgroundRole(), white);
1458 _rnxV3CheckBox->setPalette(palette);
1459 _rnxIntrComboBox->setStyleSheet("background-color: white");
1460 _rnxSamplSpinBox->setEnabled(true);
1461 _rnxSkelLineEdit->setEnabled(true);
1462 _rnxScrpLineEdit->setEnabled(true);
1463 _rnxV3CheckBox->setEnabled(true);
1464 _rnxIntrComboBox->setEnabled(true);
1465 } else {
1466 _rnxSamplSpinBox->setStyleSheet("background-color: lightGray");
1467 _rnxSkelLineEdit->setStyleSheet("background-color: lightGray");
1468 _rnxScrpLineEdit->setStyleSheet("background-color: lightGray");
1469 palette.setColor(_rnxV3CheckBox->backgroundRole(), lightGray);
1470 _rnxV3CheckBox->setPalette(palette);
1471 _rnxIntrComboBox->setStyleSheet("background-color: lightGray");
1472 _rnxSamplSpinBox->setEnabled(false);
1473 _rnxSkelLineEdit->setEnabled(false);
1474 _rnxScrpLineEdit->setEnabled(false);
1475 _rnxV3CheckBox->setEnabled(false);
1476 _rnxIntrComboBox->setEnabled(false);
1477 }
1478 }
1479
1480 // RINEX Ephemeris
1481 // ---------------
1482 if (_aogroup->currentIndex() == 3) {
1483 if (!_ephPathLineEdit->text().isEmpty() && !_outEphPortLineEdit->text().isEmpty()) {
1484 _ephIntrComboBox->setStyleSheet("background-color: white");
1485 palette.setColor(_ephV3CheckBox->backgroundRole(), white);
1486 _ephV3CheckBox->setPalette(palette);
1487 _ephIntrComboBox->setEnabled(true);
1488 _ephV3CheckBox->setEnabled(true);
1489 }
1490 if (_ephPathLineEdit->text().isEmpty() && !_outEphPortLineEdit->text().isEmpty()) {
1491 _ephIntrComboBox->setStyleSheet("background-color: lightGray");
1492 palette.setColor(_ephV3CheckBox->backgroundRole(), white);
1493 _ephV3CheckBox->setPalette(palette);
1494 _ephIntrComboBox->setEnabled(false);
1495 _ephV3CheckBox->setEnabled(true);
1496 }
1497 if (!_ephPathLineEdit->text().isEmpty() && _outEphPortLineEdit->text().isEmpty()) {
1498 _ephIntrComboBox->setStyleSheet("background-color: white");
1499 palette.setColor(_ephV3CheckBox->backgroundRole(), white);
1500 _ephV3CheckBox->setPalette(palette);
1501 _ephIntrComboBox->setEnabled(true);
1502 _ephV3CheckBox->setEnabled(true);
1503 }
1504 if (_ephPathLineEdit->text().isEmpty() && _outEphPortLineEdit->text().isEmpty()) {
1505 _ephIntrComboBox->setStyleSheet("background-color: lightGray");
1506 palette.setColor(_ephV3CheckBox->backgroundRole(), lightGray);
1507 _ephV3CheckBox->setPalette(palette);
1508 _ephIntrComboBox->setEnabled(false);
1509 _ephV3CheckBox->setEnabled(false);
1510 }
1511 }
1512
1513 // Broadcast Corrections
1514 // ---------------------
1515 if (_aogroup->currentIndex() == 4) {
1516 if (!isEmpty) {
1517 if (!_corrPathLineEdit->text().isEmpty()) {
1518 _corrIntrComboBox->setStyleSheet("background-color: white");
1519 _corrPortLineEdit->setStyleSheet("background-color: white");
1520 _corrIntrComboBox->setEnabled(true);
1521 _corrPortLineEdit->setEnabled(true);
1522 }
1523 if (!_corrPortLineEdit->text().isEmpty()) {
1524 _corrTimeSpinBox->setStyleSheet("background-color: white");
1525 _corrTimeSpinBox->setEnabled(true);
1526 }
1527 } else {
1528 if (_corrPathLineEdit->text().isEmpty()) {
1529 _corrIntrComboBox->setStyleSheet("background-color: lightGray");
1530 _corrIntrComboBox->setEnabled(false);
1531 }
1532 if (_corrPortLineEdit->text().isEmpty()) {
1533 _corrTimeSpinBox->setStyleSheet("background-color: lightGray");
1534 _corrTimeSpinBox->setEnabled(false);
1535 }
1536 }
1537 }
1538
1539 // Feed Engine
1540 // -----------
1541 if (_aogroup->currentIndex() == 5) {
1542 if ( !_outPortLineEdit->text().isEmpty() || !_outFileLineEdit->text().isEmpty()) {
1543 _waitTimeSpinBox->setStyleSheet("background-color: white");
1544 _binSamplSpinBox->setStyleSheet("background-color: white");
1545 _waitTimeSpinBox->setEnabled(true);
1546 _binSamplSpinBox->setEnabled(true);
1547 } else {
1548 _waitTimeSpinBox->setStyleSheet("background-color: lightGray");
1549 _binSamplSpinBox->setStyleSheet("background-color: lightGray");
1550 _waitTimeSpinBox->setEnabled(false);
1551 _binSamplSpinBox->setEnabled(false);
1552 }
1553 }
1554
1555 // Serial Output
1556 // -------------
1557 if (_aogroup->currentIndex() == 6) {
1558 if (!isEmpty) {
1559 _serialPortNameLineEdit->setStyleSheet("background-color: white");
1560 _serialBaudRateComboBox->setStyleSheet("background-color: white");
1561 _serialParityComboBox->setStyleSheet("background-color: white");
1562 _serialDataBitsComboBox->setStyleSheet("background-color: white");
1563 _serialStopBitsComboBox->setStyleSheet("background-color: white");
1564 _serialFlowControlComboBox->setStyleSheet("background-color: white");
1565 _serialAutoNMEAComboBox->setStyleSheet("background-color: white");
1566 _serialPortNameLineEdit->setEnabled(true);
1567 _serialBaudRateComboBox->setEnabled(true);
1568 _serialParityComboBox->setEnabled(true);
1569 _serialDataBitsComboBox->setEnabled(true);
1570 _serialStopBitsComboBox->setEnabled(true);
1571 _serialFlowControlComboBox->setEnabled(true);
1572 _serialAutoNMEAComboBox->setEnabled(true);
1573 if (_serialAutoNMEAComboBox->currentText() != "Auto" ) {
1574 _serialHeightNMEALineEdit->setStyleSheet("background-color: white");
1575 _serialHeightNMEALineEdit->setEnabled(true);
1576 _serialFileNMEALineEdit->setStyleSheet("background-color: lightGray");
1577 _serialFileNMEALineEdit->setEnabled(false);
1578 } else {
1579 _serialHeightNMEALineEdit->setStyleSheet("background-color: lightGray");
1580 _serialHeightNMEALineEdit->setEnabled(false);
1581 _serialFileNMEALineEdit->setStyleSheet("background-color: white");
1582 _serialFileNMEALineEdit->setEnabled(true);
1583 }
1584 } else {
1585 _serialPortNameLineEdit->setStyleSheet("background-color: lightGray");
1586 _serialBaudRateComboBox->setStyleSheet("background-color: lightGray");
1587 _serialParityComboBox->setStyleSheet("background-color: lightGray");
1588 _serialDataBitsComboBox->setStyleSheet("background-color: lightGray");
1589 _serialStopBitsComboBox->setStyleSheet("background-color: lightGray");
1590 _serialFlowControlComboBox->setStyleSheet("background-color: lightGray");
1591 _serialAutoNMEAComboBox->setStyleSheet("background-color: lightGray");
1592 _serialFileNMEALineEdit->setStyleSheet("background-color: lightGray");
1593 _serialHeightNMEALineEdit->setStyleSheet("background-color: lightGray");
1594 _serialPortNameLineEdit->setEnabled(false);
1595 _serialBaudRateComboBox->setEnabled(false);
1596 _serialParityComboBox->setEnabled(false);
1597 _serialDataBitsComboBox->setEnabled(false);
1598 _serialStopBitsComboBox->setEnabled(false);
1599 _serialFlowControlComboBox->setEnabled(false);
1600 _serialAutoNMEAComboBox->setEnabled(false);
1601 _serialHeightNMEALineEdit->setEnabled(false);
1602 _serialFileNMEALineEdit->setEnabled(false);
1603 }
1604 }
1605
1606 // Outages
1607 // -------
1608 if (_aogroup->currentIndex() == 7) {
1609 if (!isEmpty) {
1610 _adviseScriptLineEdit->setStyleSheet("background-color: white");
1611 _adviseFailSpinBox->setStyleSheet("background-color: white");
1612 _adviseRecoSpinBox->setStyleSheet("background-color: white");
1613 _adviseFailSpinBox->setEnabled(true);
1614 _adviseRecoSpinBox->setEnabled(true);
1615 _adviseScriptLineEdit->setEnabled(true);
1616 } else {
1617 _adviseScriptLineEdit->setStyleSheet("background-color: lightGray");
1618 _adviseFailSpinBox->setStyleSheet("background-color: lightGray");
1619 _adviseRecoSpinBox->setStyleSheet("background-color: lightGray");
1620 _adviseFailSpinBox->setEnabled(false);
1621 _adviseRecoSpinBox->setEnabled(false);
1622 _adviseScriptLineEdit->setEnabled(false);
1623 }
1624 }
1625
1626 // Miscellaneous
1627 // -------------
1628 if (_aogroup->currentIndex() == 8) {
1629 if (!isEmpty) {
1630 _perfIntrComboBox->setStyleSheet("background-color: white");
1631 palette.setColor(_scanRTCMCheckBox->backgroundRole(), white);
1632 _scanRTCMCheckBox->setPalette(palette);
1633 _perfIntrComboBox->setEnabled(true);
1634 _scanRTCMCheckBox->setEnabled(true);
1635 } else {
1636 _perfIntrComboBox->setStyleSheet("background-color: lightGray");
1637 palette.setColor(_scanRTCMCheckBox->backgroundRole(), lightGray);
1638 _scanRTCMCheckBox->setPalette(palette);
1639 _perfIntrComboBox->setEnabled(false);
1640 _scanRTCMCheckBox->setEnabled(false);
1641 }
1642 }
1643}
1644
Note: See TracBrowser for help on using the repository browser.