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

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

* empty log message *

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