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

Last change on this file since 2135 was 2135, checked in by weber, 14 years ago

* empty log message *

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