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

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

* empty log message *

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