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

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

* empty log message *

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