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

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

* empty log message *

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