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

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

* empty log message *

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