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

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

* empty log message *

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