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

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