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

Last change on this file since 2110 was 2105, checked in by mervart, 15 years ago

* empty log message *

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