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

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

* empty log message *

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