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

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

* empty log message *

File size: 79.8 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 if (_corrPortLineEdit->text().isEmpty()) {
572 _corrTimeSpinBox->setStyleSheet("background-color: lightGray");
573 _corrTimeSpinBox->setEnabled(false);
574 }
575
576 // Feed Engine
577 // -----------
578 QGridLayout* sLayout = new QGridLayout;
579 sLayout->setColumnMinimumWidth(0,14*ww);
580 _outPortLineEdit->setMaximumWidth(9*ww);
581 _waitTimeSpinBox->setMaximumWidth(9*ww);
582 _binSamplSpinBox->setMaximumWidth(9*ww);
583 _outUPortLineEdit->setMaximumWidth(9*ww);
584
585 sLayout->addWidget(new QLabel("Port"), 0, 0);
586 sLayout->addWidget(_outPortLineEdit, 0, 1);
587 sLayout->addWidget(new QLabel("Wait for full epoch"), 0, 2, Qt::AlignRight);
588 sLayout->addWidget(_waitTimeSpinBox, 0, 3, Qt::AlignLeft);
589 sLayout->addWidget(new QLabel("Sampling"), 1, 0);
590 sLayout->addWidget(_binSamplSpinBox, 1, 1, Qt::AlignLeft);
591 sLayout->addWidget(new QLabel("File (full path)"), 2, 0);
592 sLayout->addWidget(_outFileLineEdit, 2, 1, 1, 20);
593 sLayout->addWidget(new QLabel("Port (unsynchronized)"), 3, 0);
594 sLayout->addWidget(_outUPortLineEdit, 3, 1);
595 sLayout->addWidget(new QLabel("Output decoded observations in a binary format to feed a real-time GNSS network engine."),4,0,1,50);
596 sLayout->addWidget(new QLabel(" "),5,0);
597 sgroup->setLayout(sLayout);
598
599 connect(_outPortLineEdit, SIGNAL(textChanged(const QString &)),
600 this, SLOT(bncText(const QString &)));
601 connect(_outFileLineEdit, SIGNAL(textChanged(const QString &)),
602 this, SLOT(bncText(const QString &)));
603 if (_outPortLineEdit->text().isEmpty() && _outFileLineEdit->text().isEmpty()) {
604 _waitTimeSpinBox->setStyleSheet("background-color: lightGray");
605 _binSamplSpinBox->setStyleSheet("background-color: lightGray");
606 _waitTimeSpinBox->setEnabled(false);
607 _binSamplSpinBox->setEnabled(false);
608 }
609
610 // Serial Output
611 // -------------
612 QGridLayout* serLayout = new QGridLayout;
613 serLayout->setColumnMinimumWidth(0,14*ww);
614 _serialBaudRateComboBox->setMaximumWidth(9*ww);
615 _serialFlowControlComboBox->setMaximumWidth(11*ww);
616 _serialDataBitsComboBox->setMaximumWidth(5*ww);
617 _serialParityComboBox->setMaximumWidth(9*ww);
618 _serialStopBitsComboBox->setMaximumWidth(5*ww);
619 _serialAutoNMEAComboBox->setMaximumWidth(9*ww);
620 _serialHeightNMEALineEdit->setMaximumWidth(8*ww);
621
622 serLayout->addWidget(new QLabel("Mountpoint"), 0,0, Qt::AlignLeft);
623 serLayout->addWidget(_serialMountPointLineEdit, 0,1,1,2);
624 serLayout->addWidget(new QLabel("Port name"), 1,0, Qt::AlignLeft);
625 serLayout->addWidget(_serialPortNameLineEdit, 1,1,1,2);
626 serLayout->addWidget(new QLabel("Baud rate"), 2,0, Qt::AlignLeft);
627 serLayout->addWidget(_serialBaudRateComboBox, 2,1);
628 serLayout->addWidget(new QLabel("Flow control"), 2,2, Qt::AlignRight);
629 serLayout->addWidget(_serialFlowControlComboBox, 2,3);
630 serLayout->addWidget(new QLabel("Data bits"), 3,0, Qt::AlignLeft);
631 serLayout->addWidget(_serialDataBitsComboBox, 3,1);
632 serLayout->addWidget(new QLabel("Parity"), 3,2, Qt::AlignRight);
633 serLayout->addWidget(_serialParityComboBox, 3,3);
634 serLayout->addWidget(new QLabel(" Stop bits"), 3,4, Qt::AlignRight);
635 serLayout->addWidget(_serialStopBitsComboBox, 3,5);
636 serLayout->addWidget(new QLabel("NMEA"), 4,0);
637 serLayout->addWidget(_serialAutoNMEAComboBox, 4,1);
638 serLayout->addWidget(new QLabel(" File (full path)"), 4,2, Qt::AlignRight);
639 serLayout->addWidget(_serialFileNMEALineEdit, 4,3,1,15);
640 serLayout->addWidget(new QLabel("Height"), 4,20, Qt::AlignRight);
641 serLayout->addWidget(_serialHeightNMEALineEdit, 4,21,1,11);
642 serLayout->addWidget(new QLabel("Port settings to feed a serial connected receiver."),5,0,1,30);
643
644 connect(_serialMountPointLineEdit, SIGNAL(textChanged(const QString &)),
645 this, SLOT(bncText(const QString &)));
646 connect(_serialAutoNMEAComboBox, SIGNAL(currentIndexChanged(const QString &)),
647 this, SLOT(bncText(const QString)));
648 if (_serialMountPointLineEdit->text().isEmpty()) {
649 _serialPortNameLineEdit->setStyleSheet("background-color: lightGray");
650 _serialBaudRateComboBox->setStyleSheet("background-color: lightGray");
651 _serialParityComboBox->setStyleSheet("background-color: lightGray");
652 _serialDataBitsComboBox->setStyleSheet("background-color: lightGray");
653 _serialStopBitsComboBox->setStyleSheet("background-color: lightGray");
654 _serialFlowControlComboBox->setStyleSheet("background-color: lightGray");
655 _serialAutoNMEAComboBox->setStyleSheet("background-color: lightGray");
656 _serialFileNMEALineEdit->setStyleSheet("background-color: lightGray");
657 _serialHeightNMEALineEdit->setStyleSheet("background-color: lightGray");
658 _serialPortNameLineEdit->setEnabled(false);
659 _serialBaudRateComboBox->setEnabled(false);
660 _serialParityComboBox->setEnabled(false);
661 _serialDataBitsComboBox->setEnabled(false);
662 _serialStopBitsComboBox->setEnabled(false);
663 _serialFlowControlComboBox->setEnabled(false);
664 _serialAutoNMEAComboBox->setEnabled(false);
665 _serialFileNMEALineEdit->setEnabled(false);
666 _serialHeightNMEALineEdit->setEnabled(false);
667 } else {
668 if (_serialAutoNMEAComboBox->currentText() == "Auto" ) {
669 _serialHeightNMEALineEdit->setStyleSheet("background-color: lightGray");
670 _serialHeightNMEALineEdit->setEnabled(false);
671 }
672 if (_serialAutoNMEAComboBox->currentText() != "Auto" ) {
673 _serialFileNMEALineEdit->setStyleSheet("background-color: lightGray");
674 _serialFileNMEALineEdit->setEnabled(false);
675 }
676 }
677
678 sergroup->setLayout(serLayout);
679
680 // Outages
681 // -------
682 QGridLayout* aLayout = new QGridLayout;
683 aLayout->setColumnMinimumWidth(0,14*ww);
684 _obsRateComboBox->setMaximumWidth(9*ww);
685 _adviseFailSpinBox->setMaximumWidth(9*ww);
686 _adviseRecoSpinBox->setMaximumWidth(9*ww);
687
688 aLayout->addWidget(new QLabel("Observation rate"), 0, 0);
689 aLayout->addWidget(_obsRateComboBox, 0, 1);
690 aLayout->addWidget(new QLabel("Failure threshold"), 1, 0);
691 aLayout->addWidget(_adviseFailSpinBox, 1, 1);
692 aLayout->addWidget(new QLabel("Recovery threshold"), 2, 0);
693 aLayout->addWidget(_adviseRecoSpinBox, 2, 1);
694 aLayout->addWidget(new QLabel("Script (full path)"), 3, 0);
695 aLayout->addWidget(_adviseScriptLineEdit, 3, 1,1,30);
696 aLayout->addWidget(new QLabel("Failure and recovery reports, advisory notes."),5,0,1,50,Qt::AlignLeft);
697 agroup->setLayout(aLayout);
698
699 connect(_obsRateComboBox, SIGNAL(currentIndexChanged(const QString &)),
700 this, SLOT(bncText(const QString)));
701 if (_obsRateComboBox->currentText().isEmpty()) {
702 _adviseFailSpinBox->setStyleSheet("background-color: lightGray");
703 _adviseRecoSpinBox->setStyleSheet("background-color: lightGray");
704 _adviseScriptLineEdit->setStyleSheet("background-color: lightGray");
705 _adviseFailSpinBox->setEnabled(false);
706 _adviseRecoSpinBox->setEnabled(false);
707 _adviseScriptLineEdit->setEnabled(false);
708 }
709
710 // Miscellaneous
711 // -------------
712 QGridLayout* rLayout = new QGridLayout;
713 rLayout->setColumnMinimumWidth(0,14*ww);
714 _perfIntrComboBox->setMaximumWidth(9*ww);
715
716 rLayout->addWidget(new QLabel("Mountpoint"), 0, 0);
717 rLayout->addWidget(_miscMountLineEdit, 0, 1, 1,7);
718 rLayout->addWidget(new QLabel("Log latency"), 1, 0);
719 rLayout->addWidget(_perfIntrComboBox, 1, 1);
720 rLayout->addWidget(new QLabel("Scan RTCM"), 2, 0);
721 rLayout->addWidget(_scanRTCMCheckBox, 2, 1);
722 rLayout->addWidget(new QLabel("Log latencies or scan RTCM streams for numbers of message types and antenna information."),3, 0,1,30);
723 rLayout->addWidget(new QLabel(" "), 4, 0);
724 rLayout->addWidget(new QLabel(" "), 5, 0);
725 rgroup->setLayout(rLayout);
726
727 connect(_miscMountLineEdit, SIGNAL(textChanged(const QString &)),
728 this, SLOT(bncText(const QString &)));
729 if (_miscMountLineEdit->text().isEmpty()) {
730 _perfIntrComboBox->setStyleSheet("background-color: lightGray");
731 palette.setColor(_scanRTCMCheckBox->backgroundRole(), lightGray);
732 _scanRTCMCheckBox->setPalette(palette);
733 _perfIntrComboBox->setEnabled(false);
734 _scanRTCMCheckBox->setEnabled(false);
735 }
736
737 // PPP Client
738 // ----------
739 QGridLayout* pppLayout = new QGridLayout;
740 pppLayout->setColumnMinimumWidth(0,14*ww);
741 pppLayout->addWidget(new QLabel("Mountpoint"), 0, 0);
742 pppLayout->addWidget(_pppMountLineEdit, 0, 1, 1, 3);
743 pppLayout->addWidget(new QLabel("Static"), 1, 0);
744 pppLayout->addWidget(_pppStaticCheckBox, 1, 1);
745 pppLayout->addWidget(new QLabel(" Use phase obs"), 1, 2, Qt::AlignRight);
746 pppLayout->addWidget(_pppUsePhaseCheckBox, 1, 3);
747 pppLayout->addWidget(new QLabel(" Estimate tropo"), 1, 4, Qt::AlignRight);
748 pppLayout->addWidget(_pppEstTropoCheckBox, 1, 5);
749 pppLayout->addWidget(new QLabel("Derive coordinates following Precise Point Positioning (PPP) approach."),2, 0,1,30);
750 pppLayout->addWidget(new QLabel(" "), 3, 0);
751 pppLayout->addWidget(new QLabel(" "), 4, 0);
752 pppLayout->addWidget(new QLabel(" "), 5, 0);
753 pppgroup->setLayout(pppLayout);
754
755 connect(_pppMountLineEdit, SIGNAL(textChanged(const QString &)),
756 this, SLOT(bncText(const QString &)));
757 if (_pppMountLineEdit->text().isEmpty()) {
758 palette.setColor(_pppStaticCheckBox->backgroundRole(), lightGray);
759 palette.setColor(_pppUsePhaseCheckBox->backgroundRole(), lightGray);
760 palette.setColor(_pppEstTropoCheckBox->backgroundRole(), lightGray);
761 _pppStaticCheckBox->setPalette(palette);
762 _pppUsePhaseCheckBox->setPalette(palette);
763 _pppEstTropoCheckBox->setPalette(palette);
764 _pppStaticCheckBox->setEnabled(false);
765 _pppUsePhaseCheckBox->setEnabled(false);
766 _pppEstTropoCheckBox->setEnabled(false);
767 }
768
769 // Main Layout
770 // -----------
771 QGridLayout* mLayout = new QGridLayout;
772 _aogroup->setCurrentIndex(settings.value("startTab").toInt());
773 mLayout->addWidget(_aogroup, 0,0);
774 mLayout->addWidget(_mountPointsTable, 1,0);
775 _loggroup->setCurrentIndex(settings.value("statusTab").toInt());
776 mLayout->addWidget(_loggroup, 2,0);
777
778 _canvas->setLayout(mLayout);
779
780 // Auto start
781 // ----------
782 if ( Qt::CheckState(settings.value("autoStart").toInt()) == Qt::Checked) {
783 slotGetData();
784 }
785}
786
787// Destructor
788////////////////////////////////////////////////////////////////////////////
789bncWindow::~bncWindow() {
790 delete _caster;
791}
792
793//
794////////////////////////////////////////////////////////////////////////////
795void bncWindow::populateMountPointsTable() {
796
797 for (int iRow = _mountPointsTable->rowCount()-1; iRow >=0; iRow--) {
798 _mountPointsTable->removeRow(iRow);
799 }
800
801 bncSettings settings;
802
803 QListIterator<QString> it(settings.value("mountPoints").toStringList());
804 if (!it.hasNext()) {
805 _actGetData->setEnabled(false);
806 }
807 int iRow = 0;
808 while (it.hasNext()) {
809 QStringList hlp = it.next().split(" ");
810 if (hlp.size() < 5) continue;
811 _mountPointsTable->insertRow(iRow);
812
813 QUrl url(hlp[0]);
814
815 QString fullPath = url.host() + QString(":%1").arg(url.port()) + url.path();
816 QString format(hlp[1]); QString latitude(hlp[2]); QString longitude(hlp[3]);
817 QString nmea(hlp[4]);
818 if (hlp[5] == "S") {
819 fullPath = hlp[0].replace(0,2,"");
820 }
821 QString ntripVersion = "1";
822 if (hlp.size() >= 6) {
823 ntripVersion = (hlp[5]);
824 }
825
826 QTableWidgetItem* it;
827 it = new QTableWidgetItem(url.userInfo());
828 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
829 _mountPointsTable->setItem(iRow, 0, it);
830
831 it = new QTableWidgetItem(fullPath);
832 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
833 _mountPointsTable->setItem(iRow, 1, it);
834
835 it = new QTableWidgetItem(format);
836 _mountPointsTable->setItem(iRow, 2, it);
837
838 if (nmea == "yes") {
839 it = new QTableWidgetItem(latitude);
840 _mountPointsTable->setItem(iRow, 3, it);
841 it = new QTableWidgetItem(longitude);
842 _mountPointsTable->setItem(iRow, 4, it);
843 } else {
844 it = new QTableWidgetItem(latitude);
845 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
846 _mountPointsTable->setItem(iRow, 3, it);
847 it = new QTableWidgetItem(longitude);
848 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
849 _mountPointsTable->setItem(iRow, 4, it);
850 }
851
852 it = new QTableWidgetItem(nmea);
853 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
854 _mountPointsTable->setItem(iRow, 5, it);
855
856 it = new QTableWidgetItem(ntripVersion);
857 //// it->setFlags(it->flags() & ~Qt::ItemIsEditable);
858 _mountPointsTable->setItem(iRow, 6, it);
859
860 bncTableItem* bncIt = new bncTableItem();
861 bncIt->setFlags(bncIt->flags() & ~Qt::ItemIsEditable);
862 _mountPointsTable->setItem(iRow, 7, bncIt);
863
864 iRow++;
865 }
866
867 _mountPointsTable->sortItems(1);
868}
869
870// Retrieve Table
871////////////////////////////////////////////////////////////////////////////
872void bncWindow::slotAddMountPoints() {
873
874 bncSettings settings;
875 QString proxyHost = settings.value("proxyHost").toString();
876 int proxyPort = settings.value("proxyPort").toInt();
877 if (proxyHost != _proxyHostLineEdit->text() ||
878 proxyPort != _proxyPortLineEdit->text().toInt()) {
879 int iRet = QMessageBox::question(this, "Question", "Proxy options "
880 "changed. Use the new ones?",
881 QMessageBox::Yes, QMessageBox::No,
882 QMessageBox::NoButton);
883 if (iRet == QMessageBox::Yes) {
884 settings.setValue("proxyHost", _proxyHostLineEdit->text());
885 settings.setValue("proxyPort", _proxyPortLineEdit->text());
886 settings.sync();
887 }
888 }
889
890 QMessageBox msgBox;
891 msgBox.setIcon(QMessageBox::Question);
892 msgBox.setWindowTitle("Add Stream");
893 msgBox.setText("Add stream(s) coming from:");
894
895 QPushButton* buttonNtrip = msgBox.addButton(tr("Caster"), QMessageBox::ActionRole);
896 QPushButton* buttonIP = msgBox.addButton(tr("TCP/IP port"), QMessageBox::ActionRole);
897 QPushButton* buttonUDP = msgBox.addButton(tr("UDP port"), QMessageBox::ActionRole);
898 QPushButton* buttonSerial = msgBox.addButton(tr("Serial port"), QMessageBox::ActionRole);
899 QPushButton* buttonCancel = msgBox.addButton(tr("Cancel"), QMessageBox::ActionRole);
900
901 msgBox.exec();
902
903 if (msgBox.clickedButton() == buttonNtrip) {
904 bncTableDlg* dlg = new bncTableDlg(this);
905 dlg->move(this->pos().x()+50, this->pos().y()+50);
906 connect(dlg, SIGNAL(newMountPoints(QStringList*)),
907 this, SLOT(slotNewMountPoints(QStringList*)));
908 dlg->exec();
909 delete dlg;
910 } else if (msgBox.clickedButton() == buttonIP) {
911 bncIpPort* ipp = new bncIpPort(this);
912 connect(ipp, SIGNAL(newMountPoints(QStringList*)),
913 this, SLOT(slotNewMountPoints(QStringList*)));
914 ipp->exec();
915 delete ipp;
916 } else if (msgBox.clickedButton() == buttonUDP) {
917 bncUdpPort* udp = new bncUdpPort(this);
918 connect(udp, SIGNAL(newMountPoints(QStringList*)),
919 this, SLOT(slotNewMountPoints(QStringList*)));
920 udp->exec();
921 delete udp;
922 } else if (msgBox.clickedButton() == buttonSerial) {
923 bncSerialPort* sep = new bncSerialPort(this);
924 connect(sep, SIGNAL(newMountPoints(QStringList*)),
925 this, SLOT(slotNewMountPoints(QStringList*)));
926 sep->exec();
927 delete sep;
928 } else if (msgBox.clickedButton() == buttonCancel) {
929 // Cancel
930 }
931}
932
933// Delete Selected Mount Points
934////////////////////////////////////////////////////////////////////////////
935void bncWindow::slotDeleteMountPoints() {
936
937 int nRows = _mountPointsTable->rowCount();
938 bool flg[nRows];
939 for (int iRow = 0; iRow < nRows; iRow++) {
940 if (_mountPointsTable->isItemSelected(_mountPointsTable->item(iRow,1))) {
941 flg[iRow] = true;
942 }
943 else {
944 flg[iRow] = false;
945 }
946 }
947 for (int iRow = nRows-1; iRow >= 0; iRow--) {
948 if (flg[iRow]) {
949 _mountPointsTable->removeRow(iRow);
950 }
951 }
952 _actDeleteMountPoints->setEnabled(false);
953
954 if (_mountPointsTable->rowCount() == 0) {
955 _actGetData->setEnabled(false);
956 }
957}
958
959// New Mount Points Selected
960////////////////////////////////////////////////////////////////////////////
961void bncWindow::slotNewMountPoints(QStringList* mountPoints) {
962 int iRow = 0;
963 QListIterator<QString> it(*mountPoints);
964 while (it.hasNext()) {
965 QStringList hlp = it.next().split(" ");
966 QUrl url(hlp[0]);
967 QString fullPath = url.host() + QString(":%1").arg(url.port()) + url.path();
968 QString format(hlp[1]); QString latitude(hlp[2]); QString longitude(hlp[3]);
969 QString nmea(hlp[4]);
970 if (hlp[5] == "S") {
971 fullPath = hlp[0].replace(0,2,"");
972 }
973 QString ntripVersion = "1";
974 if (hlp.size() >= 6) {
975 ntripVersion = (hlp[5]);
976 }
977
978 _mountPointsTable->insertRow(iRow);
979
980 QTableWidgetItem* it;
981 it = new QTableWidgetItem(url.userInfo());
982 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
983 _mountPointsTable->setItem(iRow, 0, it);
984
985 it = new QTableWidgetItem(fullPath);
986 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
987 _mountPointsTable->setItem(iRow, 1, it);
988
989 it = new QTableWidgetItem(format);
990 _mountPointsTable->setItem(iRow, 2, it);
991
992 if (nmea == "yes") {
993 it = new QTableWidgetItem(latitude);
994 _mountPointsTable->setItem(iRow, 3, it);
995 it = new QTableWidgetItem(longitude);
996 _mountPointsTable->setItem(iRow, 4, it);
997 } else {
998 it = new QTableWidgetItem(latitude);
999 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
1000 _mountPointsTable->setItem(iRow, 3, it);
1001 it = new QTableWidgetItem(longitude);
1002 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
1003 _mountPointsTable->setItem(iRow, 4, it);
1004 }
1005
1006 it = new QTableWidgetItem(nmea);
1007 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
1008 _mountPointsTable->setItem(iRow, 5, it);
1009
1010 it = new QTableWidgetItem(ntripVersion);
1011 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
1012 _mountPointsTable->setItem(iRow, 6, it);
1013
1014 bncTableItem* bncIt = new bncTableItem();
1015 _mountPointsTable->setItem(iRow, 7, bncIt);
1016
1017 iRow++;
1018 }
1019 _mountPointsTable->hideColumn(0);
1020 _mountPointsTable->sortItems(1);
1021 if (mountPoints->count() > 0 && !_actStop->isEnabled()) {
1022 _actGetData->setEnabled(true);
1023 }
1024 delete mountPoints;
1025}
1026
1027// Save Options
1028////////////////////////////////////////////////////////////////////////////
1029void bncWindow::slotSaveOptions() {
1030
1031 QStringList mountPoints;
1032 for (int iRow = 0; iRow < _mountPointsTable->rowCount(); iRow++) {
1033
1034 if (_mountPointsTable->item(iRow, 6)->text() != "S") {
1035 QUrl url( "//" + _mountPointsTable->item(iRow, 0)->text() +
1036 "@" + _mountPointsTable->item(iRow, 1)->text() );
1037
1038 mountPoints.append(url.toString() + " " +
1039 _mountPointsTable->item(iRow, 2)->text()
1040 + " " + _mountPointsTable->item(iRow, 3)->text()
1041 + " " + _mountPointsTable->item(iRow, 4)->text()
1042 + " " + _mountPointsTable->item(iRow, 5)->text()
1043 + " " + _mountPointsTable->item(iRow, 6)->text());
1044 } else {
1045 mountPoints.append(
1046 "//" + _mountPointsTable->item(iRow, 1)->text()
1047 + " " + _mountPointsTable->item(iRow, 2)->text()
1048 + " " + _mountPointsTable->item(iRow, 3)->text()
1049 + " " + _mountPointsTable->item(iRow, 4)->text()
1050 + " " + _mountPointsTable->item(iRow, 5)->text()
1051 + " " + _mountPointsTable->item(iRow, 6)->text());
1052 }
1053 }
1054
1055 bncSettings settings;
1056
1057 settings.setValue("adviseFail", _adviseFailSpinBox->value());
1058 settings.setValue("adviseReco", _adviseRecoSpinBox->value());
1059 settings.setValue("adviseScript",_adviseScriptLineEdit->text());
1060 settings.setValue("autoStart", _autoStartCheckBox->checkState());
1061 settings.setValue("binSampl", _binSamplSpinBox->value());
1062 settings.setValue("corrIntr", _corrIntrComboBox->currentText());
1063 settings.setValue("corrPath", _corrPathLineEdit->text());
1064 settings.setValue("corrPort", _corrPortLineEdit->text());
1065 settings.setValue("corrTime", _corrTimeSpinBox->value());
1066 settings.setValue("ephIntr", _ephIntrComboBox->currentText());
1067 settings.setValue("ephPath", _ephPathLineEdit->text());
1068 settings.setValue("ephV3", _ephV3CheckBox->checkState());
1069 settings.setValue("logFile", _logFileLineEdit->text());
1070 settings.setValue("miscMount", _miscMountLineEdit->text());
1071 settings.setValue("pppMount", _pppMountLineEdit->text());
1072 settings.setValue("pppStatic", _pppStaticCheckBox->checkState());
1073 settings.setValue("pppUsePhase", _pppUsePhaseCheckBox->checkState());
1074 settings.setValue("pppEstTropo", _pppEstTropoCheckBox->checkState());
1075 settings.setValue("mountPoints", mountPoints);
1076 settings.setValue("obsRate", _obsRateComboBox->currentText());
1077 settings.setValue("onTheFlyInterval", _onTheFlyComboBox->currentText());
1078 settings.setValue("outEphPort", _outEphPortLineEdit->text());
1079 settings.setValue("outFile", _outFileLineEdit->text());
1080 settings.setValue("outPort", _outPortLineEdit->text());
1081 settings.setValue("outUPort", _outUPortLineEdit->text());
1082 settings.setValue("perfIntr", _perfIntrComboBox->currentText());
1083 settings.setValue("proxyHost", _proxyHostLineEdit->text());
1084 settings.setValue("proxyPort", _proxyPortLineEdit->text());
1085 settings.setValue("rnxAppend", _rnxAppendCheckBox->checkState());
1086 settings.setValue("rnxIntr", _rnxIntrComboBox->currentText());
1087 settings.setValue("rnxPath", _rnxPathLineEdit->text());
1088 settings.setValue("rnxSampl", _rnxSamplSpinBox->value());
1089 settings.setValue("rnxScript", _rnxScrpLineEdit->text());
1090 settings.setValue("rnxSkel", _rnxSkelLineEdit->text());
1091 settings.setValue("rnxV3", _rnxV3CheckBox->checkState());
1092 settings.setValue("scanRTCM", _scanRTCMCheckBox->checkState());
1093 settings.setValue("serialFileNMEA",_serialFileNMEALineEdit->text());
1094 settings.setValue("serialHeightNMEA",_serialHeightNMEALineEdit->text());
1095 settings.setValue("serialAutoNMEA", _serialAutoNMEAComboBox->currentText());
1096 settings.setValue("serialBaudRate", _serialBaudRateComboBox->currentText());
1097 settings.setValue("serialDataBits", _serialDataBitsComboBox->currentText());
1098 settings.setValue("serialMountPoint",_serialMountPointLineEdit->text());
1099 settings.setValue("serialParity", _serialParityComboBox->currentText());
1100 settings.setValue("serialPortName", _serialPortNameLineEdit->text());
1101 settings.setValue("serialStopBits", _serialStopBitsComboBox->currentText());
1102 settings.setValue("serialFlowControl",_serialFlowControlComboBox->currentText());
1103 settings.setValue("startTab", _aogroup->currentIndex());
1104 settings.setValue("statusTab", _loggroup->currentIndex());
1105 settings.setValue("waitTime", _waitTimeSpinBox->value());
1106
1107 if (_caster) {
1108 _caster->slotReadMountPoints();
1109 }
1110 settings.sync();
1111}
1112
1113// All get slots terminated
1114////////////////////////////////////////////////////////////////////////////
1115void bncWindow::slotGetThreadsFinished() {
1116 ((bncApp*)qApp)->slotMessage("All Get Threads Terminated", true);
1117 delete _caster; _caster = 0;
1118 _actGetData->setEnabled(true);
1119 _actStop->setEnabled(false);
1120}
1121
1122// Retrieve Data
1123////////////////////////////////////////////////////////////////////////////
1124void bncWindow::slotGetData() {
1125 slotSaveOptions();
1126
1127 _actDeleteMountPoints->setEnabled(false);
1128 _actGetData->setEnabled(false);
1129 _actStop->setEnabled(true);
1130
1131 _caster = new bncCaster(_outFileLineEdit->text(),
1132 _outPortLineEdit->text().toInt());
1133
1134 ((bncApp*)qApp)->setPort(_outEphPortLineEdit->text().toInt());
1135 ((bncApp*)qApp)->setPortCorr(_corrPortLineEdit->text().toInt());
1136
1137 connect(_caster, SIGNAL(getThreadsFinished()),
1138 this, SLOT(slotGetThreadsFinished()));
1139
1140 connect (_caster, SIGNAL(mountPointsRead(QList<bncGetThread*>)),
1141 this, SLOT(slotMountPointsRead(QList<bncGetThread*>)));
1142
1143 ((bncApp*)qApp)->slotMessage("========== Start BNC v" BNCVERSION " =========", true);
1144
1145 bncSettings settings;
1146
1147 QDir rnxdir(settings.value("rnxPath").toString());
1148 if (!rnxdir.exists()) ((bncApp*)qApp)->slotMessage("Cannot find RINEX Observations directory", true);
1149
1150 QString rnx_file = settings.value("rnxScript").toString();
1151 if ( !rnx_file.isEmpty() ) {
1152 QFile rnxfile(settings.value("rnxScript").toString());
1153 if (!rnxfile.exists()) ((bncApp*)qApp)->slotMessage("Cannot find RINEX Observations script", true);
1154 }
1155
1156 QDir ephdir(settings.value("ephPath").toString());
1157 if (!ephdir.exists()) ((bncApp*)qApp)->slotMessage("Cannot find RINEX Ephemeris directory", true);
1158
1159 QDir corrdir(settings.value("corrPath").toString());
1160 if (!corrdir.exists()) ((bncApp*)qApp)->slotMessage("Cannot find Broadcast Corrections directory", true);
1161
1162 QString advise_file = settings.value("adviseScript").toString();
1163 if ( !advise_file.isEmpty() ) {
1164 QFile advisefile(settings.value("adviseScript").toString());
1165 if (!advisefile.exists()) ((bncApp*)qApp)->slotMessage("Cannot find Outages script", true);
1166 }
1167
1168 _caster->slotReadMountPoints();
1169}
1170
1171// Retrieve Data
1172////////////////////////////////////////////////////////////////////////////
1173void bncWindow::slotStop() {
1174 int iRet = QMessageBox::question(this, "Stop", "Stop retrieving data?",
1175 QMessageBox::Yes, QMessageBox::No,
1176 QMessageBox::NoButton);
1177 if (iRet == QMessageBox::Yes) {
1178 delete _caster; _caster = 0;
1179 _actGetData->setEnabled(true);
1180 _actStop->setEnabled(false);
1181 }
1182}
1183
1184// Close Application gracefully
1185////////////////////////////////////////////////////////////////////////////
1186void bncWindow::closeEvent(QCloseEvent* event) {
1187
1188 int iRet = QMessageBox::question(this, "Close", "Save Options?",
1189 QMessageBox::Yes, QMessageBox::No,
1190 QMessageBox::Cancel);
1191
1192 if (iRet == QMessageBox::Cancel) {
1193 event->ignore();
1194 return;
1195 }
1196 else if (iRet == QMessageBox::Yes) {
1197 slotSaveOptions();
1198 }
1199
1200 QMainWindow::closeEvent(event);
1201}
1202
1203// User changed the selection of mountPoints
1204////////////////////////////////////////////////////////////////////////////
1205void bncWindow::slotSelectionChanged() {
1206 if (_mountPointsTable->selectedItems().isEmpty()) {
1207 _actDeleteMountPoints->setEnabled(false);
1208 }
1209 else {
1210 _actDeleteMountPoints->setEnabled(true);
1211 }
1212}
1213
1214// Display Program Messages
1215////////////////////////////////////////////////////////////////////////////
1216void bncWindow::slotWindowMessage(const QByteArray msg, bool showOnScreen) {
1217
1218#ifdef DEBUG_RTCM2_2021
1219 const int maxBufferSize = 1000;
1220#else
1221 const int maxBufferSize = 10000;
1222#endif
1223
1224 if (! showOnScreen ) {
1225 return;
1226 }
1227
1228 QString txt = _log->toPlainText() + "\n" +
1229 QDateTime::currentDateTime().toUTC().toString("yy-MM-dd hh:mm:ss ") + msg;
1230 _log->clear();
1231 _log->append(txt.right(maxBufferSize));
1232}
1233
1234// About Message
1235////////////////////////////////////////////////////////////////////////////
1236void bncWindow::slotAbout() {
1237 new bncAboutDlg(0);
1238}
1239
1240//Flowchart
1241////////////////////////////////////////////////////////////////////////////
1242void bncWindow::slotFlowchart() {
1243 new bncFlowchartDlg(0);
1244}
1245
1246// Help Window
1247////////////////////////////////////////////////////////////////////////////
1248void bncWindow::slotHelp() {
1249 QUrl url;
1250 url.setPath(":bnchelp.html");
1251 new bncHlpDlg(0, url);
1252}
1253
1254// Select Fonts
1255////////////////////////////////////////////////////////////////////////////
1256void bncWindow::slotFontSel() {
1257 bool ok;
1258 QFont newFont = QFontDialog::getFont(&ok, this->font(), this);
1259 if (ok) {
1260 bncSettings settings;
1261 settings.setValue("font", newFont.toString());
1262 QApplication::setFont(newFont);
1263 int ww = QFontMetrics(newFont).width('w');
1264 setMinimumSize(60*ww, 80*ww);
1265 resize(60*ww, 80*ww);
1266 }
1267}
1268
1269// Whats This Help
1270void bncWindow::slotWhatsThis() {
1271 QWhatsThis::enterWhatsThisMode();
1272}
1273
1274//
1275////////////////////////////////////////////////////////////////////////////
1276void bncWindow::slotMountPointsRead(QList<bncGetThread*> threads) {
1277 _bncFigure->updateMountPoints();
1278 _bncFigureLate->updateMountPoints();
1279
1280 populateMountPointsTable();
1281 bncSettings settings;
1282 _binSamplSpinBox->setValue(settings.value("binSampl").toInt());
1283 _waitTimeSpinBox->setValue(settings.value("waitTime").toInt());
1284 QListIterator<bncGetThread*> iTh(threads);
1285 while (iTh.hasNext()) {
1286 bncGetThread* thread = iTh.next();
1287 for (int iRow = 0; iRow < _mountPointsTable->rowCount(); iRow++) {
1288 QUrl url( "//" + _mountPointsTable->item(iRow, 0)->text() +
1289 "@" + _mountPointsTable->item(iRow, 1)->text() );
1290 if (url == thread->mountPoint() &&
1291 _mountPointsTable->item(iRow, 3)->text() == thread->latitude() &&
1292 _mountPointsTable->item(iRow, 4)->text() == thread->longitude() ) {
1293 ((bncTableItem*) _mountPointsTable->item(iRow, 7))->setGetThread(thread);
1294 disconnect(thread, SIGNAL(newBytes(QByteArray, double)),
1295 _bncFigure, SLOT(slotNewData(QByteArray, double)));
1296 connect(thread, SIGNAL(newBytes(QByteArray, double)),
1297 _bncFigure, SLOT(slotNewData(QByteArray, double)));
1298 disconnect(thread, SIGNAL(newLatency(QByteArray, double)),
1299 _bncFigureLate, SLOT(slotNewLatency(QByteArray, double)));
1300 connect(thread, SIGNAL(newLatency(QByteArray, double)),
1301 _bncFigureLate, SLOT(slotNewLatency(QByteArray, double)));
1302 break;
1303 }
1304 }
1305 }
1306}
1307
1308//
1309////////////////////////////////////////////////////////////////////////////
1310void bncWindow::CreateMenu() {
1311 // Create Menus
1312 // ------------
1313 _menuFile = menuBar()->addMenu(tr("&File"));
1314 _menuFile->addAction(_actFontSel);
1315 _menuFile->addSeparator();
1316 _menuFile->addAction(_actSaveOpt);
1317 _menuFile->addSeparator();
1318 _menuFile->addAction(_actQuit);
1319
1320 _menuHlp = menuBar()->addMenu(tr("&Help"));
1321 _menuHlp->addAction(_actHelp);
1322 _menuHlp->addAction(_actFlowchart);
1323 _menuHlp->addAction(_actAbout);
1324}
1325
1326// Toolbar
1327////////////////////////////////////////////////////////////////////////////
1328void bncWindow::AddToolbar() {
1329 // Tool (Command) Bar
1330 // ------------------
1331 QToolBar* toolBar = new QToolBar;
1332 addToolBar(Qt::BottomToolBarArea, toolBar);
1333 toolBar->setMovable(false);
1334 toolBar->addAction(_actAddMountPoints);
1335 toolBar->addAction(_actDeleteMountPoints);
1336 toolBar->addAction(_actGetData);
1337 toolBar->addAction(_actStop);
1338 toolBar->addWidget(new QLabel(" "));
1339 toolBar->addAction(_actwhatsthis);
1340}
1341
1342// About
1343////////////////////////////////////////////////////////////////////////////
1344bncAboutDlg::bncAboutDlg(QWidget* parent) :
1345 QDialog(parent) {
1346
1347 QTextBrowser* tb = new QTextBrowser;
1348 QUrl url; url.setPath(":bncabout.html");
1349 tb->setSource(url);
1350 tb->setReadOnly(true);
1351
1352 int ww = QFontMetrics(font()).width('w');
1353 QPushButton* _closeButton = new QPushButton("Close");
1354 _closeButton->setMaximumWidth(10*ww);
1355 connect(_closeButton, SIGNAL(clicked()), this, SLOT(close()));
1356
1357 QGridLayout* dlgLayout = new QGridLayout();
1358 QLabel* img = new QLabel();
1359 img->setPixmap(QPixmap(":ntrip-logo.png"));
1360 dlgLayout->addWidget(img, 0,0);
1361 dlgLayout->addWidget(new QLabel("BKG Ntrip Client (BNC) Version "BNCVERSION), 0,1);
1362 dlgLayout->addWidget(tb,1,0,1,2);
1363 dlgLayout->addWidget(_closeButton,2,1,Qt::AlignRight);
1364
1365 setLayout(dlgLayout);
1366 resize(60*ww, 60*ww);
1367 setWindowTitle("About BNC");
1368 show();
1369}
1370
1371//
1372////////////////////////////////////////////////////////////////////////////
1373bncAboutDlg::~bncAboutDlg() {
1374};
1375
1376// Flowchart
1377////////////////////////////////////////////////////////////////////////////
1378bncFlowchartDlg::bncFlowchartDlg(QWidget* parent) :
1379 QDialog(parent) {
1380
1381 int ww = QFontMetrics(font()).width('w');
1382 QPushButton* _closeButton = new QPushButton("Close");
1383 _closeButton->setMaximumWidth(10*ww);
1384 connect(_closeButton, SIGNAL(clicked()), this, SLOT(close()));
1385
1386 QGridLayout* dlgLayout = new QGridLayout();
1387 QLabel* img = new QLabel();
1388 img->setPixmap(QPixmap(":bncflowchart.png"));
1389 dlgLayout->addWidget(img, 0,0);
1390 dlgLayout->addWidget(_closeButton,1,0,Qt::AlignLeft);
1391
1392 setLayout(dlgLayout);
1393 setWindowTitle("Flow Chart");
1394 show();
1395}
1396
1397//
1398////////////////////////////////////////////////////////////////////////////
1399bncFlowchartDlg::~bncFlowchartDlg() {
1400};
1401
1402// Bnc Text
1403////////////////////////////////////////////////////////////////////////////
1404void bncWindow::bncText(const QString &text){
1405
1406 bool isEmpty = text.isEmpty();
1407
1408 QPalette palette;
1409 QColor lightGray(230, 230, 230);
1410 QColor white(255, 255, 255);
1411
1412
1413 // Proxy
1414 //------
1415 if (_aogroup->currentIndex() == 0) {
1416 if (!isEmpty) {
1417 _proxyPortLineEdit->setStyleSheet("background-color: white");
1418 _proxyPortLineEdit->setEnabled(true);
1419 } else {
1420 _proxyPortLineEdit->setStyleSheet("background-color: lightGray");
1421 _proxyPortLineEdit->setEnabled(false);
1422 }
1423 }
1424
1425 // RINEX Observations
1426 // ------------------
1427 if (_aogroup->currentIndex() == 2) {
1428 if (!isEmpty) {
1429 _rnxSamplSpinBox->setStyleSheet("background-color: white");
1430 _rnxSkelLineEdit->setStyleSheet("background-color: white");
1431 _rnxScrpLineEdit->setStyleSheet("background-color: white");
1432 palette.setColor(_rnxV3CheckBox->backgroundRole(), white);
1433 _rnxV3CheckBox->setPalette(palette);
1434 _rnxIntrComboBox->setStyleSheet("background-color: white");
1435 _rnxSamplSpinBox->setEnabled(true);
1436 _rnxSkelLineEdit->setEnabled(true);
1437 _rnxScrpLineEdit->setEnabled(true);
1438 _rnxV3CheckBox->setEnabled(true);
1439 _rnxIntrComboBox->setEnabled(true);
1440 } else {
1441 _rnxSamplSpinBox->setStyleSheet("background-color: lightGray");
1442 _rnxSkelLineEdit->setStyleSheet("background-color: lightGray");
1443 _rnxScrpLineEdit->setStyleSheet("background-color: lightGray");
1444 palette.setColor(_rnxV3CheckBox->backgroundRole(), lightGray);
1445 _rnxV3CheckBox->setPalette(palette);
1446 _rnxIntrComboBox->setStyleSheet("background-color: lightGray");
1447 _rnxSamplSpinBox->setEnabled(false);
1448 _rnxSkelLineEdit->setEnabled(false);
1449 _rnxScrpLineEdit->setEnabled(false);
1450 _rnxV3CheckBox->setEnabled(false);
1451 _rnxIntrComboBox->setEnabled(false);
1452 }
1453 }
1454
1455 // RINEX Ephemeris
1456 // ---------------
1457 if (_aogroup->currentIndex() == 3) {
1458 if (!_ephPathLineEdit->text().isEmpty() && !_outEphPortLineEdit->text().isEmpty()) {
1459 _ephIntrComboBox->setStyleSheet("background-color: white");
1460 palette.setColor(_ephV3CheckBox->backgroundRole(), white);
1461 _ephV3CheckBox->setPalette(palette);
1462 _ephIntrComboBox->setEnabled(true);
1463 _ephV3CheckBox->setEnabled(true);
1464 }
1465 if (_ephPathLineEdit->text().isEmpty() && !_outEphPortLineEdit->text().isEmpty()) {
1466 _ephIntrComboBox->setStyleSheet("background-color: lightGray");
1467 palette.setColor(_ephV3CheckBox->backgroundRole(), white);
1468 _ephV3CheckBox->setPalette(palette);
1469 _ephIntrComboBox->setEnabled(false);
1470 _ephV3CheckBox->setEnabled(true);
1471 }
1472 if (!_ephPathLineEdit->text().isEmpty() && _outEphPortLineEdit->text().isEmpty()) {
1473 _ephIntrComboBox->setStyleSheet("background-color: white");
1474 palette.setColor(_ephV3CheckBox->backgroundRole(), white);
1475 _ephV3CheckBox->setPalette(palette);
1476 _ephIntrComboBox->setEnabled(true);
1477 _ephV3CheckBox->setEnabled(true);
1478 }
1479 if (_ephPathLineEdit->text().isEmpty() && _outEphPortLineEdit->text().isEmpty()) {
1480 _ephIntrComboBox->setStyleSheet("background-color: lightGray");
1481 palette.setColor(_ephV3CheckBox->backgroundRole(), lightGray);
1482 _ephV3CheckBox->setPalette(palette);
1483 _ephIntrComboBox->setEnabled(false);
1484 _ephV3CheckBox->setEnabled(false);
1485 }
1486 }
1487
1488 // Broadcast Corrections
1489 // ---------------------
1490 if (_aogroup->currentIndex() == 4) {
1491 if (!isEmpty) {
1492 if (!_corrPathLineEdit->text().isEmpty()) {
1493 _corrIntrComboBox->setStyleSheet("background-color: white");
1494 _corrPortLineEdit->setStyleSheet("background-color: white");
1495 _corrIntrComboBox->setEnabled(true);
1496 _corrPortLineEdit->setEnabled(true);
1497 }
1498 if (!_corrPortLineEdit->text().isEmpty()) {
1499 _corrTimeSpinBox->setStyleSheet("background-color: white");
1500 _corrTimeSpinBox->setEnabled(true);
1501 }
1502 } else {
1503 if (_corrPathLineEdit->text().isEmpty()) {
1504 _corrIntrComboBox->setStyleSheet("background-color: lightGray");
1505 _corrIntrComboBox->setEnabled(false);
1506 }
1507 if (_corrPortLineEdit->text().isEmpty()) {
1508 _corrTimeSpinBox->setStyleSheet("background-color: lightGray");
1509 _corrTimeSpinBox->setEnabled(false);
1510 }
1511 }
1512 }
1513
1514 // Feed Engine
1515 // -----------
1516 if (_aogroup->currentIndex() == 5) {
1517 if ( !_outPortLineEdit->text().isEmpty() || !_outFileLineEdit->text().isEmpty()) {
1518 _waitTimeSpinBox->setStyleSheet("background-color: white");
1519 _binSamplSpinBox->setStyleSheet("background-color: white");
1520 _waitTimeSpinBox->setEnabled(true);
1521 _binSamplSpinBox->setEnabled(true);
1522 } else {
1523 _waitTimeSpinBox->setStyleSheet("background-color: lightGray");
1524 _binSamplSpinBox->setStyleSheet("background-color: lightGray");
1525 _waitTimeSpinBox->setEnabled(false);
1526 _binSamplSpinBox->setEnabled(false);
1527 }
1528 }
1529
1530 // Serial Output
1531 // -------------
1532 if (_aogroup->currentIndex() == 6) {
1533 if (!isEmpty) {
1534 _serialPortNameLineEdit->setStyleSheet("background-color: white");
1535 _serialBaudRateComboBox->setStyleSheet("background-color: white");
1536 _serialParityComboBox->setStyleSheet("background-color: white");
1537 _serialDataBitsComboBox->setStyleSheet("background-color: white");
1538 _serialStopBitsComboBox->setStyleSheet("background-color: white");
1539 _serialFlowControlComboBox->setStyleSheet("background-color: white");
1540 _serialAutoNMEAComboBox->setStyleSheet("background-color: white");
1541 _serialPortNameLineEdit->setEnabled(true);
1542 _serialBaudRateComboBox->setEnabled(true);
1543 _serialParityComboBox->setEnabled(true);
1544 _serialDataBitsComboBox->setEnabled(true);
1545 _serialStopBitsComboBox->setEnabled(true);
1546 _serialFlowControlComboBox->setEnabled(true);
1547 _serialAutoNMEAComboBox->setEnabled(true);
1548 if (_serialAutoNMEAComboBox->currentText() != "Auto" ) {
1549 _serialHeightNMEALineEdit->setStyleSheet("background-color: white");
1550 _serialHeightNMEALineEdit->setEnabled(true);
1551 _serialFileNMEALineEdit->setStyleSheet("background-color: lightGray");
1552 _serialFileNMEALineEdit->setEnabled(false);
1553 } else {
1554 _serialHeightNMEALineEdit->setStyleSheet("background-color: lightGray");
1555 _serialHeightNMEALineEdit->setEnabled(false);
1556 _serialFileNMEALineEdit->setStyleSheet("background-color: white");
1557 _serialFileNMEALineEdit->setEnabled(true);
1558 }
1559 } else {
1560 _serialPortNameLineEdit->setStyleSheet("background-color: lightGray");
1561 _serialBaudRateComboBox->setStyleSheet("background-color: lightGray");
1562 _serialParityComboBox->setStyleSheet("background-color: lightGray");
1563 _serialDataBitsComboBox->setStyleSheet("background-color: lightGray");
1564 _serialStopBitsComboBox->setStyleSheet("background-color: lightGray");
1565 _serialFlowControlComboBox->setStyleSheet("background-color: lightGray");
1566 _serialAutoNMEAComboBox->setStyleSheet("background-color: lightGray");
1567 _serialFileNMEALineEdit->setStyleSheet("background-color: lightGray");
1568 _serialHeightNMEALineEdit->setStyleSheet("background-color: lightGray");
1569 _serialPortNameLineEdit->setEnabled(false);
1570 _serialBaudRateComboBox->setEnabled(false);
1571 _serialParityComboBox->setEnabled(false);
1572 _serialDataBitsComboBox->setEnabled(false);
1573 _serialStopBitsComboBox->setEnabled(false);
1574 _serialFlowControlComboBox->setEnabled(false);
1575 _serialAutoNMEAComboBox->setEnabled(false);
1576 _serialHeightNMEALineEdit->setEnabled(false);
1577 _serialFileNMEALineEdit->setEnabled(false);
1578 }
1579 }
1580
1581 // Outages
1582 // -------
1583 if (_aogroup->currentIndex() == 7) {
1584 if (!isEmpty) {
1585 _adviseScriptLineEdit->setStyleSheet("background-color: white");
1586 _adviseFailSpinBox->setStyleSheet("background-color: white");
1587 _adviseRecoSpinBox->setStyleSheet("background-color: white");
1588 _adviseFailSpinBox->setEnabled(true);
1589 _adviseRecoSpinBox->setEnabled(true);
1590 _adviseScriptLineEdit->setEnabled(true);
1591 } else {
1592 _adviseScriptLineEdit->setStyleSheet("background-color: lightGray");
1593 _adviseFailSpinBox->setStyleSheet("background-color: lightGray");
1594 _adviseRecoSpinBox->setStyleSheet("background-color: lightGray");
1595 _adviseFailSpinBox->setEnabled(false);
1596 _adviseRecoSpinBox->setEnabled(false);
1597 _adviseScriptLineEdit->setEnabled(false);
1598 }
1599 }
1600
1601 // Miscellaneous
1602 // -------------
1603 if (_aogroup->currentIndex() == 8) {
1604 if (!isEmpty) {
1605 _perfIntrComboBox->setStyleSheet("background-color: white");
1606 palette.setColor(_scanRTCMCheckBox->backgroundRole(), white);
1607 _scanRTCMCheckBox->setPalette(palette);
1608 _perfIntrComboBox->setEnabled(true);
1609 _scanRTCMCheckBox->setEnabled(true);
1610 } else {
1611 _perfIntrComboBox->setStyleSheet("background-color: lightGray");
1612 palette.setColor(_scanRTCMCheckBox->backgroundRole(), lightGray);
1613 _scanRTCMCheckBox->setPalette(palette);
1614 _perfIntrComboBox->setEnabled(false);
1615 _scanRTCMCheckBox->setEnabled(false);
1616 }
1617 }
1618
1619 // PPP Client
1620 // ----------
1621 if (_aogroup->currentIndex() == 9) {
1622 if (!isEmpty) {
1623 palette.setColor(_pppStaticCheckBox->backgroundRole(), white);
1624 palette.setColor(_pppUsePhaseCheckBox->backgroundRole(), white);
1625 palette.setColor(_pppEstTropoCheckBox->backgroundRole(), white);
1626 _pppStaticCheckBox->setPalette(palette);
1627 _pppUsePhaseCheckBox->setPalette(palette);
1628 _pppEstTropoCheckBox->setPalette(palette);
1629 _pppStaticCheckBox->setEnabled(true);
1630 _pppUsePhaseCheckBox->setEnabled(true);
1631 _pppEstTropoCheckBox->setEnabled(true);
1632 } else {
1633 palette.setColor(_pppStaticCheckBox->backgroundRole(), lightGray);
1634 palette.setColor(_pppUsePhaseCheckBox->backgroundRole(), lightGray);
1635 palette.setColor(_pppEstTropoCheckBox->backgroundRole(), lightGray);
1636 _pppStaticCheckBox->setPalette(palette);
1637 _pppUsePhaseCheckBox->setPalette(palette);
1638 _pppEstTropoCheckBox->setPalette(palette);
1639 _pppStaticCheckBox->setEnabled(false);
1640 _pppUsePhaseCheckBox->setEnabled(false);
1641 _pppEstTropoCheckBox->setEnabled(false);
1642 }
1643 }
1644}
Note: See TracBrowser for help on using the repository browser.