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

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

* empty log message *

File size: 79.3 KB
Line 
1// Part of BNC, a utility for retrieving decoding and
2// converting GNSS data streams from NTRIP broadcasters.
3//
4// Copyright (C) 2007
5// German Federal Agency for Cartography and Geodesy (BKG)
6// http://www.bkg.bund.de
7// Czech Technical University Prague, Department of Geodesy
8// http://www.fsv.cvut.cz
9//
10// Email: euref-ip@bkg.bund.de
11//
12// This program is free software; you can redistribute it and/or
13// modify it under the terms of the GNU General Public License
14// as published by the Free Software Foundation, version 2.
15//
16// This program is distributed in the hope that it will be useful,
17// but WITHOUT ANY WARRANTY; without even the implied warranty of
18// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19// GNU General Public License for more details.
20//
21// You should have received a copy of the GNU General Public License
22// along with this program; if not, write to the Free Software
23// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24
25/* -------------------------------------------------------------------------
26 * BKG NTRIP Client
27 * -------------------------------------------------------------------------
28 *
29 * Class: bncWindow
30 *
31 * Purpose: This class implements the main application window.
32 *
33 * Author: L. Mervart
34 *
35 * Created: 24-Dec-2005
36 *
37 * Changes:
38 *
39 * -----------------------------------------------------------------------*/
40
41#include <iostream>
42
43#include <unistd.h>
44#include "bncwindow.h"
45#include "bncapp.h"
46#include "bncgetthread.h"
47#include "bnctabledlg.h"
48#include "bncipport.h"
49#include "bncudpport.h"
50#include "bncserialport.h"
51#include "bnchlpdlg.h"
52#include "bnchtml.h"
53#include "bnctableitem.h"
54#include "bncsettings.h"
55#include "bncfigure.h"
56#include "bncfigurelate.h"
57#include "bncversion.h"
58
59using namespace std;
60
61// Constructor
62////////////////////////////////////////////////////////////////////////////
63bncWindow::bncWindow() {
64
65 _caster = 0;
66
67 _bncFigure = new bncFigure(this);
68 _bncFigureLate = new bncFigureLate(this);
69
70 int ww = QFontMetrics(this->font()).width('w');
71
72 static const QStringList labels = QString("account, Streams: resource loader / mountpoint,decoder,lat,long,nmea,ntrip,bytes").split(",");
73
74 setMinimumSize(85*ww, 65*ww);
75
76 setWindowTitle(tr("BKG Ntrip Client (BNC) Version " BNCVERSION));
77
78 connect((bncApp*)qApp, SIGNAL(newMessage(QByteArray,bool)),
79 this, SLOT(slotWindowMessage(QByteArray,bool)));
80
81 QPalette palette;
82 QColor lightGray(230, 230, 230);
83
84 // Create Actions
85 // --------------
86 _actHelp = new QAction(tr("&Help Contents"),this);
87 connect(_actHelp, SIGNAL(triggered()), SLOT(slotHelp()));
88
89 _actAbout = new QAction(tr("&About BNC"),this);
90 connect(_actAbout, SIGNAL(triggered()), SLOT(slotAbout()));
91
92 _actFlowchart = new QAction(tr("&Flow Chart"),this);
93 connect(_actFlowchart, SIGNAL(triggered()), SLOT(slotFlowchart()));
94
95 _actFontSel = new QAction(tr("Select &Font"),this);
96 connect(_actFontSel, SIGNAL(triggered()), SLOT(slotFontSel()));
97
98 _actSaveOpt = new QAction(tr("&Save && Reread Configuration"),this);
99 connect(_actSaveOpt, SIGNAL(triggered()), SLOT(slotSaveOptions()));
100
101 _actQuit = new QAction(tr("&Quit"),this);
102 connect(_actQuit, SIGNAL(triggered()), SLOT(close()));
103
104 _actAddMountPoints = new QAction(tr("Add &Stream"),this);
105 connect(_actAddMountPoints, SIGNAL(triggered()), SLOT(slotAddMountPoints()));
106
107 _actDeleteMountPoints = new QAction(tr("&Delete Stream"),this);
108 connect(_actDeleteMountPoints, SIGNAL(triggered()), SLOT(slotDeleteMountPoints()));
109 _actDeleteMountPoints->setEnabled(false);
110
111 _actGetData = new QAction(tr("Sta&rt"),this);
112 connect(_actGetData, SIGNAL(triggered()), SLOT(slotGetData()));
113
114 _actStop = new QAction(tr("Sto&p"),this);
115 connect(_actStop, SIGNAL(triggered()), SLOT(slotStop()));
116 _actStop->setEnabled(false);
117
118 _actwhatsthis= new QAction(tr("Help=Shift+F1"),this);
119 connect(_actwhatsthis, SIGNAL(triggered()), SLOT(slotWhatsThis()));
120
121 CreateMenu();
122 AddToolbar();
123
124 bncSettings settings;
125
126 // Proxy Options
127 // -------------
128 _proxyHostLineEdit = new QLineEdit(settings.value("proxyHost").toString());
129 _proxyPortLineEdit = new QLineEdit(settings.value("proxyPort").toString());
130
131 // General Options
132 // ---------------
133 _logFileLineEdit = new QLineEdit(settings.value("logFile").toString());
134 _rnxAppendCheckBox = new QCheckBox();
135 _rnxAppendCheckBox->setCheckState(Qt::CheckState(
136 settings.value("rnxAppend").toInt()));
137 _onTheFlyComboBox = new QComboBox();
138 _onTheFlyComboBox->setEditable(false);
139 _onTheFlyComboBox->addItems(QString("1 day,1 hour,1 min").split(","));
140 int ii = _onTheFlyComboBox->findText(settings.value("onTheFlyInterval").toString());
141 if (ii != -1) {
142 _onTheFlyComboBox->setCurrentIndex(ii);
143 }
144 _autoStartCheckBox = new QCheckBox();
145 _autoStartCheckBox->setCheckState(Qt::CheckState(
146 settings.value("autoStart").toInt()));
147
148 // RINEX Observations Options
149 // --------------------------
150 _rnxPathLineEdit = new QLineEdit(settings.value("rnxPath").toString());
151 _rnxIntrComboBox = new QComboBox();
152 _rnxIntrComboBox->setEditable(false);
153 _rnxIntrComboBox->addItems(QString("1 min,2 min,5 min,10 min,15 min,30 min,1 hour,1 day").split(","));
154 ii = _rnxIntrComboBox->findText(settings.value("rnxIntr").toString());
155 if (ii != -1) {
156 _rnxIntrComboBox->setCurrentIndex(ii);
157 }
158 _rnxSamplSpinBox = new QSpinBox();
159 _rnxSamplSpinBox->setMinimum(0);
160 _rnxSamplSpinBox->setMaximum(60);
161 _rnxSamplSpinBox->setSingleStep(5);
162 _rnxSamplSpinBox->setValue(settings.value("rnxSampl").toInt());
163 _rnxSamplSpinBox->setSuffix(" sec");
164 _rnxSkelLineEdit = new QLineEdit(settings.value("rnxSkel").toString());
165 _rnxSkelLineEdit->setMaximumWidth(5*ww);
166 _rnxScrpLineEdit = new QLineEdit(settings.value("rnxScript").toString());
167 _rnxV3CheckBox = new QCheckBox();
168 _rnxV3CheckBox->setCheckState(Qt::CheckState(settings.value("rnxV3").toInt()));
169
170 // RINEX Ephemeris Options
171 // -----------------------
172 _ephPathLineEdit = new QLineEdit(settings.value("ephPath").toString());
173 _ephIntrComboBox = new QComboBox();
174 _ephIntrComboBox->setEditable(false);
175 _ephIntrComboBox->addItems(QString("1 min,2 min,5 min,10 min,15 min,30 min,1 hour,1 day").split(","));
176 int jj = _ephIntrComboBox->findText(settings.value("ephIntr").toString());
177 if (jj != -1) {
178 _ephIntrComboBox->setCurrentIndex(jj);
179 }
180 _outEphPortLineEdit = new QLineEdit(settings.value("outEphPort").toString());
181 _ephV3CheckBox = new QCheckBox();
182 _ephV3CheckBox->setCheckState(Qt::CheckState(settings.value("ephV3").toInt()));
183
184 // Broadcast Corrections Options
185 // -----------------------------
186 _corrPathLineEdit = new QLineEdit(settings.value("corrPath").toString());
187 _corrIntrComboBox = new QComboBox();
188 _corrIntrComboBox->setEditable(false);
189 _corrIntrComboBox->addItems(QString("1 min,2 min,5 min,10 min,15 min,30 min,1 hour,1 day").split(","));
190 int mm = _corrIntrComboBox->findText(settings.value("corrIntr").toString());
191 if (mm != -1) {
192 _corrIntrComboBox->setCurrentIndex(mm);
193 }
194 _corrPortLineEdit = new QLineEdit(settings.value("corrPort").toString());
195 _corrTimeSpinBox = new QSpinBox();
196 _corrTimeSpinBox->setMinimum(1);
197 _corrTimeSpinBox->setMaximum(30);
198 _corrTimeSpinBox->setSingleStep(1);
199 _corrTimeSpinBox->setSuffix(" sec");
200 _corrTimeSpinBox->setValue(settings.value("corrTime").toInt());
201
202 // Feed Engine Options
203 // -------------------
204 _outPortLineEdit = new QLineEdit(settings.value("outPort").toString());
205 _waitTimeSpinBox = new QSpinBox();
206 _waitTimeSpinBox->setMinimum(1);
207 _waitTimeSpinBox->setMaximum(30);
208 _waitTimeSpinBox->setSingleStep(1);
209 _waitTimeSpinBox->setSuffix(" sec");
210 _waitTimeSpinBox->setValue(settings.value("waitTime").toInt());
211 _binSamplSpinBox = new QSpinBox();
212 _binSamplSpinBox->setMinimum(0);
213 _binSamplSpinBox->setMaximum(60);
214 _binSamplSpinBox->setSingleStep(5);
215 _binSamplSpinBox->setValue(settings.value("binSampl").toInt());
216 _binSamplSpinBox->setSuffix(" sec");
217 _outFileLineEdit = new QLineEdit(settings.value("outFile").toString());
218 _outUPortLineEdit = new QLineEdit(settings.value("outUPort").toString());
219
220 // Serial Output Options
221 // ---------------------
222 _serialMountPointLineEdit = new QLineEdit(settings.value("serialMountPoint").toString());
223 _serialPortNameLineEdit = new QLineEdit(settings.value("serialPortName").toString());
224 _serialBaudRateComboBox = new QComboBox();
225 _serialBaudRateComboBox->addItems(QString("110,300,600,"
226 "1200,2400,4800,9600,19200,38400,57600,115200").split(","));
227 int kk = _serialBaudRateComboBox->findText(settings.value("serialBaudRate").toString());
228 if (kk != -1) {
229 _serialBaudRateComboBox->setCurrentIndex(kk);
230 }
231 _serialFlowControlComboBox = new QComboBox();
232 _serialFlowControlComboBox->addItems(QString("OFF,XONXOFF,HARDWARE").split(","));
233 kk = _serialFlowControlComboBox->findText(settings.value("serialFlowControl").toString());
234 if (kk != -1) {
235 _serialFlowControlComboBox->setCurrentIndex(kk);
236 }
237 _serialDataBitsComboBox = new QComboBox();
238 _serialDataBitsComboBox->addItems(QString("5,6,7,8").split(","));
239 kk = _serialDataBitsComboBox->findText(settings.value("serialDataBits").toString());
240 if (kk != -1) {
241 _serialDataBitsComboBox->setCurrentIndex(kk);
242 }
243 _serialParityComboBox = new QComboBox();
244 _serialParityComboBox->addItems(QString("NONE,ODD,EVEN,SPACE").split(","));
245 kk = _serialParityComboBox->findText(settings.value("serialParity").toString());
246 if (kk != -1) {
247 _serialParityComboBox->setCurrentIndex(kk);
248 }
249 _serialStopBitsComboBox = new QComboBox();
250 _serialStopBitsComboBox->addItems(QString("1,2").split(","));
251 kk = _serialStopBitsComboBox->findText(settings.value("serialStopBits").toString());
252 if (kk != -1) {
253 _serialStopBitsComboBox->setCurrentIndex(kk);
254 }
255 _serialAutoNMEAComboBox = new QComboBox();
256 _serialAutoNMEAComboBox->addItems(QString("Auto,Manual").split(","));
257 kk = _serialAutoNMEAComboBox->findText(settings.value("serialAutoNMEA").toString());
258 if (kk != -1) {
259 _serialAutoNMEAComboBox->setCurrentIndex(kk);
260 }
261 _serialFileNMEALineEdit = new QLineEdit(settings.value("serialFileNMEA").toString());
262 _serialHeightNMEALineEdit = new QLineEdit(settings.value("serialHeightNMEA").toString());
263
264 // Outages Options
265 // ---------------
266 _obsRateComboBox = new QComboBox();
267 _obsRateComboBox->setEditable(false);
268 _obsRateComboBox->addItems(QString(",0.1 Hz,0.2 Hz,0.5 Hz,1 Hz,5 Hz").split(","));
269 kk = _obsRateComboBox->findText(settings.value("obsRate").toString());
270 if (kk != -1) {
271 _obsRateComboBox->setCurrentIndex(kk);
272 }
273 _adviseFailSpinBox = new QSpinBox();
274 _adviseFailSpinBox->setMinimum(0);
275 _adviseFailSpinBox->setMaximum(60);
276 _adviseFailSpinBox->setSingleStep(1);
277 _adviseFailSpinBox->setSuffix(" min");
278 _adviseFailSpinBox->setValue(settings.value("adviseFail").toInt());
279 _adviseRecoSpinBox = new QSpinBox();
280 _adviseRecoSpinBox->setMinimum(0);
281 _adviseRecoSpinBox->setMaximum(60);
282 _adviseRecoSpinBox->setSingleStep(1);
283 _adviseRecoSpinBox->setSuffix(" min");
284 _adviseRecoSpinBox->setValue(settings.value("adviseReco").toInt());
285 _adviseScriptLineEdit = new QLineEdit(settings.value("adviseScript").toString());
286
287 // Miscellaneous Options
288 // ---------------------
289 _miscMountLineEdit = new QLineEdit(settings.value("miscMount").toString());
290 _perfIntrComboBox = new QComboBox();
291 _perfIntrComboBox->setEditable(false);
292 _perfIntrComboBox->addItems(QString(",2 sec, 10 sec,1 min,5 min,15 min,1 hour,6 hours,1 day").split(","));
293 int ll = _perfIntrComboBox->findText(settings.value("perfIntr").toString());
294 if (ll != -1) {
295 _perfIntrComboBox->setCurrentIndex(ll);
296 }
297 _scanRTCMCheckBox = new QCheckBox();
298 _scanRTCMCheckBox->setCheckState(Qt::CheckState(
299 settings.value("scanRTCM").toInt()));
300
301 // PPP Options
302 // -----------
303 _pppMountLineEdit = new QLineEdit(settings.value("pppMount").toString());
304 _pppStaticCheckBox = new QCheckBox();
305 _pppStaticCheckBox->setCheckState(Qt::CheckState(
306 settings.value("pppStatic").toInt()));
307 _pppUsePhaseCheckBox = new QCheckBox();
308 _pppUsePhaseCheckBox->setCheckState(Qt::CheckState(
309 settings.value("pppUsePhase").toInt()));
310 _pppEstTropoCheckBox = new QCheckBox();
311 _pppEstTropoCheckBox->setCheckState(Qt::CheckState(
312 settings.value("pppEstTropo").toInt()));
313
314 // Streams
315 // -------
316 _mountPointsTable = new QTableWidget(0,8);
317
318 _mountPointsTable->horizontalHeader()->resizeSection(1,34*ww);
319 _mountPointsTable->horizontalHeader()->resizeSection(2,9*ww);
320 _mountPointsTable->horizontalHeader()->resizeSection(3,7*ww);
321 _mountPointsTable->horizontalHeader()->resizeSection(4,7*ww);
322 _mountPointsTable->horizontalHeader()->resizeSection(5,5*ww);
323 _mountPointsTable->horizontalHeader()->resizeSection(6,5*ww);
324 _mountPointsTable->horizontalHeader()->setResizeMode(QHeaderView::Interactive);
325 _mountPointsTable->horizontalHeader()->setStretchLastSection(true);
326 _mountPointsTable->setHorizontalHeaderLabels(labels);
327 _mountPointsTable->setGridStyle(Qt::NoPen);
328 _mountPointsTable->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
329 _mountPointsTable->setSelectionMode(QAbstractItemView::ExtendedSelection);
330 _mountPointsTable->setSelectionBehavior(QAbstractItemView::SelectRows);
331 _mountPointsTable->hideColumn(0);
332 connect(_mountPointsTable, SIGNAL(itemSelectionChanged()),
333 SLOT(slotSelectionChanged()));
334 populateMountPointsTable();
335
336 _log = new QTextBrowser();
337 _log->setReadOnly(true);
338
339 // WhatsThis
340 // ---------
341 _proxyHostLineEdit->setWhatsThis(tr("<p>If you are running BNC within a protected Local Area Network (LAN), you might need to use a proxy server to access the Internet. Enter your proxy server IP and port number in case one is operated in front of BNC. If you do not know the IP and port of your proxy server, check the proxy server settings in your Internet browser or ask your network administrator.</p><p>Note that IP streaming is sometimes not allowed in a LAN. In this case you need to ask your network administrator for an appropriate modification of the local security policy or for the installation of a TCP relay to the NTRIP broadcasters. If these are not possible, you might need to run BNC outside your LAN on a network that has unobstructed connection to the Internet.</p>"));
342 _proxyPortLineEdit->setWhatsThis(tr("<p>Enter your proxy server port number in case a proxy is operated in front of BNC.</p>"));
343 _waitTimeSpinBox->setWhatsThis(tr("<p>When feeding a real-time GNSS network engine waiting for synchronized input epoch by epoch, BNC drops whatever is received later than 'Wait for full epoch' seconds. A value of 3 to 5 seconds is recommended, depending on the latency of the incoming streams and the delay acceptable to your real-time GNSS network engine or products.</p>"));
344 _outFileLineEdit->setWhatsThis(tr("Specify the full path to a file where synchronized observations are saved in plain ASCII format. Beware that the size of this file can rapidly increase depending on the number of incoming streams."));
345 _outPortLineEdit->setWhatsThis(tr("BNC can produce synchronized observations in binary format on your local host through an IP port. Specify a port number here to activate this function."));
346 _outUPortLineEdit->setWhatsThis(tr("BNC can produce unsynchronized observations in binary format on your local host through an IP port. Specify a port number here to activate this function."));
347 _outEphPortLineEdit->setWhatsThis(tr("BNC can produce ephemeris data in RINEX ASCII format on your local host through an IP port. Specify a port number here to activate this function."));
348 _corrPortLineEdit->setWhatsThis(tr("BNC can produce Broadcast Ephemeris Corrections on your local host through an IP port. Specify a port number here to activate this function."));
349 _corrTimeSpinBox->setWhatsThis(tr("Concerning output through IP port, BNC drops Broadcast Ephemeris Corrections received later than 'Wait for full epoch' seconds. A value of 2 to 5 seconds is recommended, depending on the latency of the incoming correction stream(s) and the delay acceptable to your real-time application."));
350 _rnxPathLineEdit->setWhatsThis(tr("Here you specify the path to where the RINEX Observation files will be stored. If the specified directory does not exist, BNC will not create RINEX Observation files."));
351 _ephPathLineEdit->setWhatsThis(tr("Specify the path for saving Broadcast Ephemeris data as RINEX Navigation files. If the specified directory does not exist, BNC will not create RINEX Navigation files."));
352 _corrPathLineEdit->setWhatsThis(tr("Specify a directory for saving Broadcast Ephemeris Correction files. If the specified directory does not exist, BNC will not create the files."));
353 _rnxScrpLineEdit->setWhatsThis(tr("<p>Whenever a RINEX Observation file is saved, you might want to compress, copy or upload it immediately via FTP. BNC allows you to execute a script/batch file to carry out these operations. To do that specify the full path of the script/batch file here. BNC will pass the full RINEX Observation file path to the script as a command line parameter (%1 on Windows systems, $1 onUnix/Linux systems).</p>"));
354 _rnxSkelLineEdit->setWhatsThis(tr("<p>BNC allows using personal skeleton files that contain the header records you would like to include. You can derive a personal RINEX header skeleton file from the information given in an up to date sitelog.</p><p>A file in the RINEX Observations 'Directory' with a 'Skeleton extension' suffix is interpreted by BNC as a personal RINEX header skeleton file for the corresponding stream.</p>"));
355 _rnxAppendCheckBox->setWhatsThis(tr("<p>When BNC is started, new files are created by default and any existing files with the same name will be overwritten. However, users might want to append already existing files following a restart of BNC, a system crash or when BNC crashed. Tick 'Append files' to continue with existing files and keep what has been recorded so far.</p>"));
356 _autoStartCheckBox->setWhatsThis(tr("<p>Tick 'Auto start' for auto-start of BNC at startup time in window mode with preassigned processing options.</p>"));
357 _onTheFlyComboBox->setWhatsThis(tr("<p>When operating BNC online in 'no window' mode, some configuration parameters can be changed on-the-fly without interrupting the running process. For that BNC rereads parts of its configuration in pre-defined intervals.<p></p>Select '1 min', '1 hour', or '1 day' to force BNC to reread its configuration every full minute, hour, or day and let in between edited configuration options become effective on-the-fly without terminating uninvolved threads.</p><p>Note that when operating BNC in window mode, on-the-fly changeable configuration options become effective immediately through 'Save & Reread Configuration'.</p>"));
358 _rnxIntrComboBox->setWhatsThis(tr("<p>Select the length of the RINEX Observation file.</p>"));
359 _ephIntrComboBox->setWhatsThis(tr("<p>Select the length of the RINEX Navigation file.</p>"));
360 _corrIntrComboBox->setWhatsThis(tr("<p>Select the length of the Broadcast Ephemeris Correction files.</p>"));
361 _rnxSamplSpinBox->setWhatsThis(tr("<p>Select the RINEX Observation sampling interval in seconds. A value of zero '0' tells BNC to store all received epochs into RINEX.</p>"));
362 _binSamplSpinBox->setWhatsThis(tr("<p>Select the synchronized observation sampling interval in seconds. A value of zero '0' tells BNC to send/store all received epochs.</p>"));
363 _obsRateComboBox->setWhatsThis(tr("<p>BNC can collect all returns (success or failure) coming from a decoder within a certain short time span to then decide whether a stream has an outage or its content is corrupted. The procedure needs a rough estimate of the expected 'Observation rate' of the incoming streams. When a continuous problem is detected, BNC can inform its operator about this event through an advisory note.</p>"));
364 _adviseRecoSpinBox->setWhatsThis(tr("<p>Following a stream outage or a longer series of bad observations, an advisory note is generated when valid observations are received again throughout the 'Recovery threshold' time span. A value of about 5min (default) is recommended.</p><p>A value of zero '0' means that for any stream recovery, however short, BNC immediately generates an advisory note.</p>"));
365 _adviseFailSpinBox->setWhatsThis(tr("<p>An advisory note is generated when no (or only corrupted) observations are seen throughout the 'Failure threshold' time span. A value of 15 min (default) is recommended.</p><p>A value of zero '0' means that for any stream failure, however short, BNC immediately generates an advisory note.</p>"));
366 _logFileLineEdit->setWhatsThis(tr("<p>Records of BNC's activities are shown in the 'Log' tab on the bottom of this window. They can be saved into a file when a valid path is specified in the 'Logfile (full path)' field.</p><p>The logfile name will automatically be extended by a string '_YYMMDD' carrying the current date."));
367 _adviseScriptLineEdit->setWhatsThis(tr("<p>Specify the full path to a script or batch file to handle advisory notes generated in the event of corrupted streams or stream outages. The affected mountpoint and one of the comments 'Begin_Outage', 'End_Outage', 'Begin_Corrupted', or 'End_Corrupted' are passed on to the script as command line parameters.</p><p>The script may have the task to send the advisory notes by email to BNC's operator and/or to the affected stream provider. An empty option field (default) or invalid path means that you don't want to use this option.</p>"));
368 _perfIntrComboBox->setWhatsThis(tr("<p>BNC can average latencies per stream over a certain period of GPS time. The resulting mean latencies are recorded in the 'Log' tab at the end of each 'Log latency' interval together with results of a statistical evaluation (approximate number of covered epochs, data gaps).</p><p>Select a 'Log latency' interval or select the empty option field if you do not want BNC to log latencies and statistical information.</p>"));
369 _mountPointsTable->setWhatsThis(tr("<p>Streams selected for retrieval are listed in the 'Streams' section. Clicking on 'Add Stream' button will open a window that allows the user to select data streams from an NTRIP broadcaster according to their mountpoints. To remove a stream from the 'Streams' list, highlight it by clicking on it and hit the 'Delete Stream' button. You can also remove multiple streams by highlighting them using +Shift and +Ctrl.</p><p>BNC automatically allocates one of its internal decoders to a stream based on the stream's 'format' as given in the sourcetable. BNC allows users to change this selection by editing the decoder string. Double click on the 'decoder' field, enter your preferred decoder and then hit Enter. The accepted decoder strings are 'RTCM_2.x', 'RTCM_3.x', and 'RTIGS'.</p><p>In case you need to log the raw data as is, BNC allows users to by-pass its decoders and and directly save the input in daily log files. To do this specify the decoder string as 'ZERO'.</p><p>BNC can also retrieve streams from virtual reference stations (VRS). VRS streams are indicated by a 'yes' in the 'nmea' column. To initiate these streams, the approximate latitude/longitude rover position is sent to the NTRIP broadcaster. The default values can be change according to your requirement. Double click on 'lat' and 'long' fields, enter the values you wish to send and then hit Enter.</p>"));
370 _log->setWhatsThis(tr("Records of BNC's activities are shown in the 'Log' tab. The message log covers the communication status between BNC and the NTRIP broadcaster as well as any problems that occur in the communication link, stream availability, stream delay, stream conversion etc."));
371 _bncFigure->setWhatsThis(tr("The bandwidth consumtion per stream is shown in the 'Throughput' tab in bits per second (bps) or kilo bits per second (kbps)."));
372 _bncFigureLate->setWhatsThis(tr("The individual latency of observations in each incoming stream is shown in the 'Latency' tab. Streams not carrying observations (i.e. those providing only broadcast ephemeris messages) are not considered here. Note that the calculation of correct latencies requires the clock of the host computer to be properly synchronized."));
373 _ephV3CheckBox->setWhatsThis(tr("The default format for output of RINEX Navigation data containing Broadcast Ephemeris is RINEX Version 2.11. Select 'Version 3' if you want to output the ephemeris in RINEX Version 3 format."));
374 _rnxV3CheckBox->setWhatsThis(tr("The default format for RINEX Observation files is RINEX Version 2.11. Select 'Version 3' if you want to save the observations in RINEX Version 3 format."));
375 _miscMountLineEdit->setWhatsThis(tr("<p>Specify a mountpoint to apply any of the options shown below. Enter 'ALL' if you want to apply these options to all configured streams.</p><p>An empty option field (default) means that you don't want BNC to apply any of these options.</p>"));
376 _scanRTCMCheckBox->setWhatsThis(tr("<p>Tick 'Scan RTCM' to log the numbers of incomming message types as well as contained antenna coordinates, antenna heigt, and antenna descriptor.</p>"));
377 _serialMountPointLineEdit->setWhatsThis(tr("<p>Enter a 'Mountpoint' to forward the corresponding stream to a serial connected receiver.</p>"));
378 _serialPortNameLineEdit->setWhatsThis(tr("<p>Enter the serial 'Port name' selected for communication with your serial connected receiver. Valid port names are</p><pre>Windows: COM1, COM2<br>Linux: /dev/ttyS0, /dev/ttyS1<br>FreeBSD: /dev/ttyd0, /dev/ttyd1<br>Digital Unix: /dev/tty01, /dev/tty02<br>HP-UX: /dev/tty1p0, /dev/tty2p0<br>SGI/IRIX: /dev/ttyf1, /dev/ttyf2<br>SunOS/Solaris: /dev/ttya, /dev/ttyb</pre><p>Note that you must plug a serial cable in the port defined here before you start BNC.</p>"));
379 _serialBaudRateComboBox->setWhatsThis(tr("<p>Select a 'Baud rate' for the serial output link.</p><p>Note that your selection must equal the baud rate configured to the serial connected receiver. Note further that using a high baud rate is recommended.</p>"));
380 _serialParityComboBox->setWhatsThis(tr("<p>Select the 'Parity' for the serial output link.</p><p>Note that your selection must equal the parity selection configured to the serial connected receiver. Note further that parity is often set to 'NONE'.</p>"));
381 _serialDataBitsComboBox->setWhatsThis(tr("<p>Select the number of 'Data bits' for the serial output link.</p><p>Note that your selection must equal the number of data bits configured to the serial connected receiver. Note further that often 8 data bits are used.</p>"));
382 _serialStopBitsComboBox->setWhatsThis(tr("<p>Select the number of 'Stop bits' for the serial output link.</p><p>Note that your selection must equal the number of stop bits configured to the serial connected receiver. Note further that often 1 stop bit is used.</p>"));
383 _serialFlowControlComboBox->setWhatsThis(tr("<p>Select a 'Flow control' for the serial output link.</p><p>Note that your selection must equal the flow control configured to the serial connected receiver. Select 'OFF' if you don't know better.</p>"));
384 _serialAutoNMEAComboBox->setWhatsThis(tr("<p>Select 'Auto' to automatically forward NMEA-GGA messages coming from your serial connected receiver to the NTRIP broadcaster and/or save them in a file.</p><p>Select 'Manual' only when handling a VRS stream and your serial connected receiver doesn't generate NMEA-GGA messages.</p>"));
385 _serialFileNMEALineEdit->setWhatsThis(tr("<p>Specify the full path to a file where NMEA messages coming from your serial connected receiver are saved.</p>"));
386 _serialHeightNMEALineEdit->setWhatsThis(tr("<p>Specify an approximate 'Height' above mean sea level in meter for your VRS to simulate an inital NMEA-GGA message.</p><p>The setting of this option is ignored in case of streams coming from physical reference stations.</p>"));
387 _pppMountLineEdit->setWhatsThis(tr("<p>Specify a mountpoint if you want BNC to derive coordinates for the affected receiver position through a PPP solution.</p>"));
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 connect(_pppMountLineEdit, SIGNAL(textChanged(const QString &)),
754 this, SLOT(bncText(const QString &)));
755 if (_pppMountLineEdit->text().isEmpty()) {
756 palette.setColor(_pppStaticCheckBox->backgroundRole(), lightGray);
757 palette.setColor(_pppUsePhaseCheckBox->backgroundRole(), lightGray);
758 palette.setColor(_pppEstTropoCheckBox->backgroundRole(), lightGray);
759 _pppStaticCheckBox->setPalette(palette);
760 _pppUsePhaseCheckBox->setPalette(palette);
761 _pppEstTropoCheckBox->setPalette(palette);
762 _pppStaticCheckBox->setEnabled(false);
763 _pppUsePhaseCheckBox->setEnabled(false);
764 _pppEstTropoCheckBox->setEnabled(false);
765 }
766
767 // Main Layout
768 // -----------
769 QGridLayout* mLayout = new QGridLayout;
770 _aogroup->setCurrentIndex(settings.value("startTab").toInt());
771 mLayout->addWidget(_aogroup, 0,0);
772 mLayout->addWidget(_mountPointsTable, 1,0);
773 _loggroup->setCurrentIndex(settings.value("statusTab").toInt());
774 mLayout->addWidget(_loggroup, 2,0);
775
776 _canvas->setLayout(mLayout);
777
778 // Auto start
779 // ----------
780 if ( Qt::CheckState(settings.value("autoStart").toInt()) == Qt::Checked) {
781 slotGetData();
782 }
783}
784
785// Destructor
786////////////////////////////////////////////////////////////////////////////
787bncWindow::~bncWindow() {
788 delete _caster;
789}
790
791//
792////////////////////////////////////////////////////////////////////////////
793void bncWindow::populateMountPointsTable() {
794
795 for (int iRow = _mountPointsTable->rowCount()-1; iRow >=0; iRow--) {
796 _mountPointsTable->removeRow(iRow);
797 }
798
799 bncSettings settings;
800
801 QListIterator<QString> it(settings.value("mountPoints").toStringList());
802 if (!it.hasNext()) {
803 _actGetData->setEnabled(false);
804 }
805 int iRow = 0;
806 while (it.hasNext()) {
807 QStringList hlp = it.next().split(" ");
808 if (hlp.size() < 5) continue;
809 _mountPointsTable->insertRow(iRow);
810
811 QUrl url(hlp[0]);
812
813 QString fullPath = url.host() + QString(":%1").arg(url.port()) + url.path();
814 QString format(hlp[1]); QString latitude(hlp[2]); QString longitude(hlp[3]);
815 QString nmea(hlp[4]);
816 if (hlp[5] == "S") {
817 fullPath = hlp[0].replace(0,2,"");
818 }
819 QString ntripVersion = "1";
820 if (hlp.size() >= 6) {
821 ntripVersion = (hlp[5]);
822 }
823
824 QTableWidgetItem* it;
825 it = new QTableWidgetItem(url.userInfo());
826 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
827 _mountPointsTable->setItem(iRow, 0, it);
828
829 it = new QTableWidgetItem(fullPath);
830 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
831 _mountPointsTable->setItem(iRow, 1, it);
832
833 it = new QTableWidgetItem(format);
834 _mountPointsTable->setItem(iRow, 2, it);
835
836 if (nmea == "yes") {
837 it = new QTableWidgetItem(latitude);
838 _mountPointsTable->setItem(iRow, 3, it);
839 it = new QTableWidgetItem(longitude);
840 _mountPointsTable->setItem(iRow, 4, it);
841 } else {
842 it = new QTableWidgetItem(latitude);
843 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
844 _mountPointsTable->setItem(iRow, 3, it);
845 it = new QTableWidgetItem(longitude);
846 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
847 _mountPointsTable->setItem(iRow, 4, it);
848 }
849
850 it = new QTableWidgetItem(nmea);
851 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
852 _mountPointsTable->setItem(iRow, 5, it);
853
854 it = new QTableWidgetItem(ntripVersion);
855 //// it->setFlags(it->flags() & ~Qt::ItemIsEditable);
856 _mountPointsTable->setItem(iRow, 6, it);
857
858 bncTableItem* bncIt = new bncTableItem();
859 bncIt->setFlags(bncIt->flags() & ~Qt::ItemIsEditable);
860 _mountPointsTable->setItem(iRow, 7, bncIt);
861
862 iRow++;
863 }
864
865 _mountPointsTable->sortItems(1);
866}
867
868// Retrieve Table
869////////////////////////////////////////////////////////////////////////////
870void bncWindow::slotAddMountPoints() {
871
872 bncSettings settings;
873 QString proxyHost = settings.value("proxyHost").toString();
874 int proxyPort = settings.value("proxyPort").toInt();
875 if (proxyHost != _proxyHostLineEdit->text() ||
876 proxyPort != _proxyPortLineEdit->text().toInt()) {
877 int iRet = QMessageBox::question(this, "Question", "Proxy options "
878 "changed. Use the new ones?",
879 QMessageBox::Yes, QMessageBox::No,
880 QMessageBox::NoButton);
881 if (iRet == QMessageBox::Yes) {
882 settings.setValue("proxyHost", _proxyHostLineEdit->text());
883 settings.setValue("proxyPort", _proxyPortLineEdit->text());
884 settings.sync();
885 }
886 }
887
888 QMessageBox msgBox;
889 msgBox.setIcon(QMessageBox::Question);
890 msgBox.setWindowTitle("Add Stream");
891 msgBox.setText("Add stream(s) coming from:");
892
893 QPushButton* buttonNtrip = msgBox.addButton(tr("Caster"), QMessageBox::ActionRole);
894 QPushButton* buttonIP = msgBox.addButton(tr("TCP/IP port"), QMessageBox::ActionRole);
895 QPushButton* buttonUDP = msgBox.addButton(tr("UDP port"), QMessageBox::ActionRole);
896 QPushButton* buttonSerial = msgBox.addButton(tr("Serial port"), QMessageBox::ActionRole);
897 QPushButton* buttonCancel = msgBox.addButton(tr("Cancel"), QMessageBox::ActionRole);
898
899 msgBox.exec();
900
901 if (msgBox.clickedButton() == buttonNtrip) {
902 bncTableDlg* dlg = new bncTableDlg(this);
903 dlg->move(this->pos().x()+50, this->pos().y()+50);
904 connect(dlg, SIGNAL(newMountPoints(QStringList*)),
905 this, SLOT(slotNewMountPoints(QStringList*)));
906 dlg->exec();
907 delete dlg;
908 } else if (msgBox.clickedButton() == buttonIP) {
909 bncIpPort* ipp = new bncIpPort(this);
910 connect(ipp, SIGNAL(newMountPoints(QStringList*)),
911 this, SLOT(slotNewMountPoints(QStringList*)));
912 ipp->exec();
913 delete ipp;
914 } else if (msgBox.clickedButton() == buttonUDP) {
915 bncUdpPort* udp = new bncUdpPort(this);
916 connect(udp, SIGNAL(newMountPoints(QStringList*)),
917 this, SLOT(slotNewMountPoints(QStringList*)));
918 udp->exec();
919 delete udp;
920 } else if (msgBox.clickedButton() == buttonSerial) {
921 bncSerialPort* sep = new bncSerialPort(this);
922 connect(sep, SIGNAL(newMountPoints(QStringList*)),
923 this, SLOT(slotNewMountPoints(QStringList*)));
924 sep->exec();
925 delete sep;
926 } else if (msgBox.clickedButton() == buttonCancel) {
927 // Cancel
928 }
929}
930
931// Delete Selected Mount Points
932////////////////////////////////////////////////////////////////////////////
933void bncWindow::slotDeleteMountPoints() {
934
935 int nRows = _mountPointsTable->rowCount();
936 bool flg[nRows];
937 for (int iRow = 0; iRow < nRows; iRow++) {
938 if (_mountPointsTable->isItemSelected(_mountPointsTable->item(iRow,1))) {
939 flg[iRow] = true;
940 }
941 else {
942 flg[iRow] = false;
943 }
944 }
945 for (int iRow = nRows-1; iRow >= 0; iRow--) {
946 if (flg[iRow]) {
947 _mountPointsTable->removeRow(iRow);
948 }
949 }
950 _actDeleteMountPoints->setEnabled(false);
951
952 if (_mountPointsTable->rowCount() == 0) {
953 _actGetData->setEnabled(false);
954 }
955}
956
957// New Mount Points Selected
958////////////////////////////////////////////////////////////////////////////
959void bncWindow::slotNewMountPoints(QStringList* mountPoints) {
960 int iRow = 0;
961 QListIterator<QString> it(*mountPoints);
962 while (it.hasNext()) {
963 QStringList hlp = it.next().split(" ");
964 QUrl url(hlp[0]);
965 QString fullPath = url.host() + QString(":%1").arg(url.port()) + url.path();
966 QString format(hlp[1]); QString latitude(hlp[2]); QString longitude(hlp[3]);
967 QString nmea(hlp[4]);
968 if (hlp[5] == "S") {
969 fullPath = hlp[0].replace(0,2,"");
970 }
971 QString ntripVersion = "1";
972 if (hlp.size() >= 6) {
973 ntripVersion = (hlp[5]);
974 }
975
976 _mountPointsTable->insertRow(iRow);
977
978 QTableWidgetItem* it;
979 it = new QTableWidgetItem(url.userInfo());
980 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
981 _mountPointsTable->setItem(iRow, 0, it);
982
983 it = new QTableWidgetItem(fullPath);
984 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
985 _mountPointsTable->setItem(iRow, 1, it);
986
987 it = new QTableWidgetItem(format);
988 _mountPointsTable->setItem(iRow, 2, it);
989
990 if (nmea == "yes") {
991 it = new QTableWidgetItem(latitude);
992 _mountPointsTable->setItem(iRow, 3, it);
993 it = new QTableWidgetItem(longitude);
994 _mountPointsTable->setItem(iRow, 4, it);
995 } else {
996 it = new QTableWidgetItem(latitude);
997 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
998 _mountPointsTable->setItem(iRow, 3, it);
999 it = new QTableWidgetItem(longitude);
1000 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
1001 _mountPointsTable->setItem(iRow, 4, it);
1002 }
1003
1004 it = new QTableWidgetItem(nmea);
1005 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
1006 _mountPointsTable->setItem(iRow, 5, it);
1007
1008 it = new QTableWidgetItem(ntripVersion);
1009 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
1010 _mountPointsTable->setItem(iRow, 6, it);
1011
1012 bncTableItem* bncIt = new bncTableItem();
1013 _mountPointsTable->setItem(iRow, 7, bncIt);
1014
1015 iRow++;
1016 }
1017 _mountPointsTable->hideColumn(0);
1018 _mountPointsTable->sortItems(1);
1019 if (mountPoints->count() > 0 && !_actStop->isEnabled()) {
1020 _actGetData->setEnabled(true);
1021 }
1022 delete mountPoints;
1023}
1024
1025// Save Options
1026////////////////////////////////////////////////////////////////////////////
1027void bncWindow::slotSaveOptions() {
1028
1029 QStringList mountPoints;
1030 for (int iRow = 0; iRow < _mountPointsTable->rowCount(); iRow++) {
1031
1032 if (_mountPointsTable->item(iRow, 6)->text() != "S") {
1033 QUrl url( "//" + _mountPointsTable->item(iRow, 0)->text() +
1034 "@" + _mountPointsTable->item(iRow, 1)->text() );
1035
1036 mountPoints.append(url.toString() + " " +
1037 _mountPointsTable->item(iRow, 2)->text()
1038 + " " + _mountPointsTable->item(iRow, 3)->text()
1039 + " " + _mountPointsTable->item(iRow, 4)->text()
1040 + " " + _mountPointsTable->item(iRow, 5)->text()
1041 + " " + _mountPointsTable->item(iRow, 6)->text());
1042 } else {
1043 mountPoints.append(
1044 "//" + _mountPointsTable->item(iRow, 1)->text()
1045 + " " + _mountPointsTable->item(iRow, 2)->text()
1046 + " " + _mountPointsTable->item(iRow, 3)->text()
1047 + " " + _mountPointsTable->item(iRow, 4)->text()
1048 + " " + _mountPointsTable->item(iRow, 5)->text()
1049 + " " + _mountPointsTable->item(iRow, 6)->text());
1050 }
1051 }
1052
1053 bncSettings settings;
1054
1055 settings.setValue("adviseFail", _adviseFailSpinBox->value());
1056 settings.setValue("adviseReco", _adviseRecoSpinBox->value());
1057 settings.setValue("adviseScript",_adviseScriptLineEdit->text());
1058 settings.setValue("autoStart", _autoStartCheckBox->checkState());
1059 settings.setValue("binSampl", _binSamplSpinBox->value());
1060 settings.setValue("corrIntr", _corrIntrComboBox->currentText());
1061 settings.setValue("corrPath", _corrPathLineEdit->text());
1062 settings.setValue("corrPort", _corrPortLineEdit->text());
1063 settings.setValue("corrTime", _corrTimeSpinBox->value());
1064 settings.setValue("ephIntr", _ephIntrComboBox->currentText());
1065 settings.setValue("ephPath", _ephPathLineEdit->text());
1066 settings.setValue("ephV3", _ephV3CheckBox->checkState());
1067 settings.setValue("logFile", _logFileLineEdit->text());
1068 settings.setValue("miscMount", _miscMountLineEdit->text());
1069 settings.setValue("pppMount", _pppMountLineEdit->text());
1070 settings.setValue("pppStatic", _pppStaticCheckBox->checkState());
1071 settings.setValue("pppUsePhase", _pppUsePhaseCheckBox->checkState());
1072 settings.setValue("pppEstTropo", _pppEstTropoCheckBox->checkState());
1073 settings.setValue("mountPoints", mountPoints);
1074 settings.setValue("obsRate", _obsRateComboBox->currentText());
1075 settings.setValue("onTheFlyInterval", _onTheFlyComboBox->currentText());
1076 settings.setValue("outEphPort", _outEphPortLineEdit->text());
1077 settings.setValue("outFile", _outFileLineEdit->text());
1078 settings.setValue("outPort", _outPortLineEdit->text());
1079 settings.setValue("outUPort", _outUPortLineEdit->text());
1080 settings.setValue("perfIntr", _perfIntrComboBox->currentText());
1081 settings.setValue("proxyHost", _proxyHostLineEdit->text());
1082 settings.setValue("proxyPort", _proxyPortLineEdit->text());
1083 settings.setValue("rnxAppend", _rnxAppendCheckBox->checkState());
1084 settings.setValue("rnxIntr", _rnxIntrComboBox->currentText());
1085 settings.setValue("rnxPath", _rnxPathLineEdit->text());
1086 settings.setValue("rnxSampl", _rnxSamplSpinBox->value());
1087 settings.setValue("rnxScript", _rnxScrpLineEdit->text());
1088 settings.setValue("rnxSkel", _rnxSkelLineEdit->text());
1089 settings.setValue("rnxV3", _rnxV3CheckBox->checkState());
1090 settings.setValue("scanRTCM", _scanRTCMCheckBox->checkState());
1091 settings.setValue("serialFileNMEA",_serialFileNMEALineEdit->text());
1092 settings.setValue("serialHeightNMEA",_serialHeightNMEALineEdit->text());
1093 settings.setValue("serialAutoNMEA", _serialAutoNMEAComboBox->currentText());
1094 settings.setValue("serialBaudRate", _serialBaudRateComboBox->currentText());
1095 settings.setValue("serialDataBits", _serialDataBitsComboBox->currentText());
1096 settings.setValue("serialMountPoint",_serialMountPointLineEdit->text());
1097 settings.setValue("serialParity", _serialParityComboBox->currentText());
1098 settings.setValue("serialPortName", _serialPortNameLineEdit->text());
1099 settings.setValue("serialStopBits", _serialStopBitsComboBox->currentText());
1100 settings.setValue("serialFlowControl",_serialFlowControlComboBox->currentText());
1101 settings.setValue("startTab", _aogroup->currentIndex());
1102 settings.setValue("statusTab", _loggroup->currentIndex());
1103 settings.setValue("waitTime", _waitTimeSpinBox->value());
1104
1105 if (_caster) {
1106 _caster->slotReadMountPoints();
1107 }
1108 settings.sync();
1109}
1110
1111// All get slots terminated
1112////////////////////////////////////////////////////////////////////////////
1113void bncWindow::slotGetThreadsFinished() {
1114 ((bncApp*)qApp)->slotMessage("All Get Threads Terminated", true);
1115 delete _caster; _caster = 0;
1116 _actGetData->setEnabled(true);
1117 _actStop->setEnabled(false);
1118}
1119
1120// Retrieve Data
1121////////////////////////////////////////////////////////////////////////////
1122void bncWindow::slotGetData() {
1123 slotSaveOptions();
1124
1125 _actDeleteMountPoints->setEnabled(false);
1126 _actGetData->setEnabled(false);
1127 _actStop->setEnabled(true);
1128
1129 _caster = new bncCaster(_outFileLineEdit->text(),
1130 _outPortLineEdit->text().toInt());
1131
1132 ((bncApp*)qApp)->setPort(_outEphPortLineEdit->text().toInt());
1133 ((bncApp*)qApp)->setPortCorr(_corrPortLineEdit->text().toInt());
1134
1135 connect(_caster, SIGNAL(getThreadsFinished()),
1136 this, SLOT(slotGetThreadsFinished()));
1137
1138 connect (_caster, SIGNAL(mountPointsRead(QList<bncGetThread*>)),
1139 this, SLOT(slotMountPointsRead(QList<bncGetThread*>)));
1140
1141 ((bncApp*)qApp)->slotMessage("========== Start BNC v" BNCVERSION " =========", true);
1142
1143 bncSettings settings;
1144
1145 QDir rnxdir(settings.value("rnxPath").toString());
1146 if (!rnxdir.exists()) ((bncApp*)qApp)->slotMessage("Cannot find RINEX Observations directory", true);
1147
1148 QString rnx_file = settings.value("rnxScript").toString();
1149 if ( !rnx_file.isEmpty() ) {
1150 QFile rnxfile(settings.value("rnxScript").toString());
1151 if (!rnxfile.exists()) ((bncApp*)qApp)->slotMessage("Cannot find RINEX Observations script", true);
1152 }
1153
1154 QDir ephdir(settings.value("ephPath").toString());
1155 if (!ephdir.exists()) ((bncApp*)qApp)->slotMessage("Cannot find RINEX Ephemeris directory", true);
1156
1157 QDir corrdir(settings.value("corrPath").toString());
1158 if (!corrdir.exists()) ((bncApp*)qApp)->slotMessage("Cannot find Broadcast Corrections directory", true);
1159
1160 QString advise_file = settings.value("adviseScript").toString();
1161 if ( !advise_file.isEmpty() ) {
1162 QFile advisefile(settings.value("adviseScript").toString());
1163 if (!advisefile.exists()) ((bncApp*)qApp)->slotMessage("Cannot find Outages script", true);
1164 }
1165
1166 _caster->slotReadMountPoints();
1167}
1168
1169// Retrieve Data
1170////////////////////////////////////////////////////////////////////////////
1171void bncWindow::slotStop() {
1172 int iRet = QMessageBox::question(this, "Stop", "Stop retrieving data?",
1173 QMessageBox::Yes, QMessageBox::No,
1174 QMessageBox::NoButton);
1175 if (iRet == QMessageBox::Yes) {
1176 delete _caster; _caster = 0;
1177 _actGetData->setEnabled(true);
1178 _actStop->setEnabled(false);
1179 }
1180}
1181
1182// Close Application gracefully
1183////////////////////////////////////////////////////////////////////////////
1184void bncWindow::closeEvent(QCloseEvent* event) {
1185
1186 int iRet = QMessageBox::question(this, "Close", "Save Options?",
1187 QMessageBox::Yes, QMessageBox::No,
1188 QMessageBox::Cancel);
1189
1190 if (iRet == QMessageBox::Cancel) {
1191 event->ignore();
1192 return;
1193 }
1194 else if (iRet == QMessageBox::Yes) {
1195 slotSaveOptions();
1196 }
1197
1198 QMainWindow::closeEvent(event);
1199}
1200
1201// User changed the selection of mountPoints
1202////////////////////////////////////////////////////////////////////////////
1203void bncWindow::slotSelectionChanged() {
1204 if (_mountPointsTable->selectedItems().isEmpty()) {
1205 _actDeleteMountPoints->setEnabled(false);
1206 }
1207 else {
1208 _actDeleteMountPoints->setEnabled(true);
1209 }
1210}
1211
1212// Display Program Messages
1213////////////////////////////////////////////////////////////////////////////
1214void bncWindow::slotWindowMessage(const QByteArray msg, bool showOnScreen) {
1215
1216#ifdef DEBUG_RTCM2_2021
1217 const int maxBufferSize = 1000;
1218#else
1219 const int maxBufferSize = 10000;
1220#endif
1221
1222 if (! showOnScreen ) {
1223 return;
1224 }
1225
1226 QString txt = _log->toPlainText() + "\n" +
1227 QDateTime::currentDateTime().toUTC().toString("yy-MM-dd hh:mm:ss ") + msg;
1228 _log->clear();
1229 _log->append(txt.right(maxBufferSize));
1230}
1231
1232// About Message
1233////////////////////////////////////////////////////////////////////////////
1234void bncWindow::slotAbout() {
1235 new bncAboutDlg(0);
1236}
1237
1238//Flowchart
1239////////////////////////////////////////////////////////////////////////////
1240void bncWindow::slotFlowchart() {
1241 new bncFlowchartDlg(0);
1242}
1243
1244// Help Window
1245////////////////////////////////////////////////////////////////////////////
1246void bncWindow::slotHelp() {
1247 QUrl url;
1248 url.setPath(":bnchelp.html");
1249 new bncHlpDlg(0, url);
1250}
1251
1252// Select Fonts
1253////////////////////////////////////////////////////////////////////////////
1254void bncWindow::slotFontSel() {
1255 bool ok;
1256 QFont newFont = QFontDialog::getFont(&ok, this->font(), this);
1257 if (ok) {
1258 bncSettings settings;
1259 settings.setValue("font", newFont.toString());
1260 QApplication::setFont(newFont);
1261 int ww = QFontMetrics(newFont).width('w');
1262 setMinimumSize(60*ww, 80*ww);
1263 resize(60*ww, 80*ww);
1264 }
1265}
1266
1267// Whats This Help
1268void bncWindow::slotWhatsThis() {
1269 QWhatsThis::enterWhatsThisMode();
1270}
1271
1272//
1273////////////////////////////////////////////////////////////////////////////
1274void bncWindow::slotMountPointsRead(QList<bncGetThread*> threads) {
1275 _bncFigure->updateMountPoints();
1276 _bncFigureLate->updateMountPoints();
1277
1278 populateMountPointsTable();
1279 bncSettings settings;
1280 _binSamplSpinBox->setValue(settings.value("binSampl").toInt());
1281 _waitTimeSpinBox->setValue(settings.value("waitTime").toInt());
1282 QListIterator<bncGetThread*> iTh(threads);
1283 while (iTh.hasNext()) {
1284 bncGetThread* thread = iTh.next();
1285 for (int iRow = 0; iRow < _mountPointsTable->rowCount(); iRow++) {
1286 QUrl url( "//" + _mountPointsTable->item(iRow, 0)->text() +
1287 "@" + _mountPointsTable->item(iRow, 1)->text() );
1288 if (url == thread->mountPoint() &&
1289 _mountPointsTable->item(iRow, 3)->text() == thread->latitude() &&
1290 _mountPointsTable->item(iRow, 4)->text() == thread->longitude() ) {
1291 ((bncTableItem*) _mountPointsTable->item(iRow, 7))->setGetThread(thread);
1292 disconnect(thread, SIGNAL(newBytes(QByteArray, double)),
1293 _bncFigure, SLOT(slotNewData(QByteArray, double)));
1294 connect(thread, SIGNAL(newBytes(QByteArray, double)),
1295 _bncFigure, SLOT(slotNewData(QByteArray, double)));
1296 disconnect(thread, SIGNAL(newLatency(QByteArray, double)),
1297 _bncFigureLate, SLOT(slotNewLatency(QByteArray, double)));
1298 connect(thread, SIGNAL(newLatency(QByteArray, double)),
1299 _bncFigureLate, SLOT(slotNewLatency(QByteArray, double)));
1300 break;
1301 }
1302 }
1303 }
1304}
1305
1306//
1307////////////////////////////////////////////////////////////////////////////
1308void bncWindow::CreateMenu() {
1309 // Create Menus
1310 // ------------
1311 _menuFile = menuBar()->addMenu(tr("&File"));
1312 _menuFile->addAction(_actFontSel);
1313 _menuFile->addSeparator();
1314 _menuFile->addAction(_actSaveOpt);
1315 _menuFile->addSeparator();
1316 _menuFile->addAction(_actQuit);
1317
1318 _menuHlp = menuBar()->addMenu(tr("&Help"));
1319 _menuHlp->addAction(_actHelp);
1320 _menuHlp->addAction(_actFlowchart);
1321 _menuHlp->addAction(_actAbout);
1322}
1323
1324// Toolbar
1325////////////////////////////////////////////////////////////////////////////
1326void bncWindow::AddToolbar() {
1327 // Tool (Command) Bar
1328 // ------------------
1329 QToolBar* toolBar = new QToolBar;
1330 addToolBar(Qt::BottomToolBarArea, toolBar);
1331 toolBar->setMovable(false);
1332 toolBar->addAction(_actAddMountPoints);
1333 toolBar->addAction(_actDeleteMountPoints);
1334 toolBar->addAction(_actGetData);
1335 toolBar->addAction(_actStop);
1336 toolBar->addWidget(new QLabel(" "));
1337 toolBar->addAction(_actwhatsthis);
1338}
1339
1340// About
1341////////////////////////////////////////////////////////////////////////////
1342bncAboutDlg::bncAboutDlg(QWidget* parent) :
1343 QDialog(parent) {
1344
1345 QTextBrowser* tb = new QTextBrowser;
1346 QUrl url; url.setPath(":bncabout.html");
1347 tb->setSource(url);
1348 tb->setReadOnly(true);
1349
1350 int ww = QFontMetrics(font()).width('w');
1351 QPushButton* _closeButton = new QPushButton("Close");
1352 _closeButton->setMaximumWidth(10*ww);
1353 connect(_closeButton, SIGNAL(clicked()), this, SLOT(close()));
1354
1355 QGridLayout* dlgLayout = new QGridLayout();
1356 QLabel* img = new QLabel();
1357 img->setPixmap(QPixmap(":ntrip-logo.png"));
1358 dlgLayout->addWidget(img, 0,0);
1359 dlgLayout->addWidget(new QLabel("BKG Ntrip Client (BNC) Version "BNCVERSION), 0,1);
1360 dlgLayout->addWidget(tb,1,0,1,2);
1361 dlgLayout->addWidget(_closeButton,2,1,Qt::AlignRight);
1362
1363 setLayout(dlgLayout);
1364 resize(60*ww, 60*ww);
1365 setWindowTitle("About BNC");
1366 show();
1367}
1368
1369//
1370////////////////////////////////////////////////////////////////////////////
1371bncAboutDlg::~bncAboutDlg() {
1372};
1373
1374// Flowchart
1375////////////////////////////////////////////////////////////////////////////
1376bncFlowchartDlg::bncFlowchartDlg(QWidget* parent) :
1377 QDialog(parent) {
1378
1379 int ww = QFontMetrics(font()).width('w');
1380 QPushButton* _closeButton = new QPushButton("Close");
1381 _closeButton->setMaximumWidth(10*ww);
1382 connect(_closeButton, SIGNAL(clicked()), this, SLOT(close()));
1383
1384 QGridLayout* dlgLayout = new QGridLayout();
1385 QLabel* img = new QLabel();
1386 img->setPixmap(QPixmap(":bncflowchart.png"));
1387 dlgLayout->addWidget(img, 0,0);
1388 dlgLayout->addWidget(_closeButton,1,0,Qt::AlignLeft);
1389
1390 setLayout(dlgLayout);
1391 setWindowTitle("Flow Chart");
1392 show();
1393}
1394
1395//
1396////////////////////////////////////////////////////////////////////////////
1397bncFlowchartDlg::~bncFlowchartDlg() {
1398};
1399
1400// Bnc Text
1401////////////////////////////////////////////////////////////////////////////
1402void bncWindow::bncText(const QString &text){
1403
1404 bool isEmpty = text.isEmpty();
1405
1406 QPalette palette;
1407 QColor lightGray(230, 230, 230);
1408 QColor white(255, 255, 255);
1409
1410
1411 // Proxy
1412 //------
1413 if (_aogroup->currentIndex() == 0) {
1414 if (!isEmpty) {
1415 _proxyPortLineEdit->setStyleSheet("background-color: white");
1416 _proxyPortLineEdit->setEnabled(true);
1417 } else {
1418 _proxyPortLineEdit->setStyleSheet("background-color: lightGray");
1419 _proxyPortLineEdit->setEnabled(false);
1420 }
1421 }
1422
1423 // RINEX Observations
1424 // ------------------
1425 if (_aogroup->currentIndex() == 2) {
1426 if (!isEmpty) {
1427 _rnxSamplSpinBox->setStyleSheet("background-color: white");
1428 _rnxSkelLineEdit->setStyleSheet("background-color: white");
1429 _rnxScrpLineEdit->setStyleSheet("background-color: white");
1430 palette.setColor(_rnxV3CheckBox->backgroundRole(), white);
1431 _rnxV3CheckBox->setPalette(palette);
1432 _rnxIntrComboBox->setStyleSheet("background-color: white");
1433 _rnxSamplSpinBox->setEnabled(true);
1434 _rnxSkelLineEdit->setEnabled(true);
1435 _rnxScrpLineEdit->setEnabled(true);
1436 _rnxV3CheckBox->setEnabled(true);
1437 _rnxIntrComboBox->setEnabled(true);
1438 } else {
1439 _rnxSamplSpinBox->setStyleSheet("background-color: lightGray");
1440 _rnxSkelLineEdit->setStyleSheet("background-color: lightGray");
1441 _rnxScrpLineEdit->setStyleSheet("background-color: lightGray");
1442 palette.setColor(_rnxV3CheckBox->backgroundRole(), lightGray);
1443 _rnxV3CheckBox->setPalette(palette);
1444 _rnxIntrComboBox->setStyleSheet("background-color: lightGray");
1445 _rnxSamplSpinBox->setEnabled(false);
1446 _rnxSkelLineEdit->setEnabled(false);
1447 _rnxScrpLineEdit->setEnabled(false);
1448 _rnxV3CheckBox->setEnabled(false);
1449 _rnxIntrComboBox->setEnabled(false);
1450 }
1451 }
1452
1453 // RINEX Ephemeris
1454 // ---------------
1455 if (_aogroup->currentIndex() == 3) {
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(), white);
1466 _ephV3CheckBox->setPalette(palette);
1467 _ephIntrComboBox->setEnabled(false);
1468 _ephV3CheckBox->setEnabled(true);
1469 }
1470 if (!_ephPathLineEdit->text().isEmpty() && _outEphPortLineEdit->text().isEmpty()) {
1471 _ephIntrComboBox->setStyleSheet("background-color: white");
1472 palette.setColor(_ephV3CheckBox->backgroundRole(), white);
1473 _ephV3CheckBox->setPalette(palette);
1474 _ephIntrComboBox->setEnabled(true);
1475 _ephV3CheckBox->setEnabled(true);
1476 }
1477 if (_ephPathLineEdit->text().isEmpty() && _outEphPortLineEdit->text().isEmpty()) {
1478 _ephIntrComboBox->setStyleSheet("background-color: lightGray");
1479 palette.setColor(_ephV3CheckBox->backgroundRole(), lightGray);
1480 _ephV3CheckBox->setPalette(palette);
1481 _ephIntrComboBox->setEnabled(false);
1482 _ephV3CheckBox->setEnabled(false);
1483 }
1484 }
1485
1486 // Broadcast Corrections
1487 // ---------------------
1488 if (_aogroup->currentIndex() == 4) {
1489 if (!isEmpty) {
1490 if (!_corrPathLineEdit->text().isEmpty()) {
1491 _corrIntrComboBox->setStyleSheet("background-color: white");
1492 _corrPortLineEdit->setStyleSheet("background-color: white");
1493 _corrIntrComboBox->setEnabled(true);
1494 _corrPortLineEdit->setEnabled(true);
1495 }
1496 if (!_corrPortLineEdit->text().isEmpty()) {
1497 _corrTimeSpinBox->setStyleSheet("background-color: white");
1498 _corrTimeSpinBox->setEnabled(true);
1499 }
1500 } else {
1501 if (_corrPathLineEdit->text().isEmpty()) {
1502 _corrIntrComboBox->setStyleSheet("background-color: lightGray");
1503 _corrIntrComboBox->setEnabled(false);
1504 }
1505 if (_corrPortLineEdit->text().isEmpty()) {
1506 _corrTimeSpinBox->setStyleSheet("background-color: lightGray");
1507 _corrTimeSpinBox->setEnabled(false);
1508 }
1509 }
1510 }
1511
1512 // Feed Engine
1513 // -----------
1514 if (_aogroup->currentIndex() == 5) {
1515 if ( !_outPortLineEdit->text().isEmpty() || !_outFileLineEdit->text().isEmpty()) {
1516 _waitTimeSpinBox->setStyleSheet("background-color: white");
1517 _binSamplSpinBox->setStyleSheet("background-color: white");
1518 _waitTimeSpinBox->setEnabled(true);
1519 _binSamplSpinBox->setEnabled(true);
1520 } else {
1521 _waitTimeSpinBox->setStyleSheet("background-color: lightGray");
1522 _binSamplSpinBox->setStyleSheet("background-color: lightGray");
1523 _waitTimeSpinBox->setEnabled(false);
1524 _binSamplSpinBox->setEnabled(false);
1525 }
1526 }
1527
1528 // Serial Output
1529 // -------------
1530 if (_aogroup->currentIndex() == 6) {
1531 if (!isEmpty) {
1532 _serialPortNameLineEdit->setStyleSheet("background-color: white");
1533 _serialBaudRateComboBox->setStyleSheet("background-color: white");
1534 _serialParityComboBox->setStyleSheet("background-color: white");
1535 _serialDataBitsComboBox->setStyleSheet("background-color: white");
1536 _serialStopBitsComboBox->setStyleSheet("background-color: white");
1537 _serialFlowControlComboBox->setStyleSheet("background-color: white");
1538 _serialAutoNMEAComboBox->setStyleSheet("background-color: white");
1539 _serialPortNameLineEdit->setEnabled(true);
1540 _serialBaudRateComboBox->setEnabled(true);
1541 _serialParityComboBox->setEnabled(true);
1542 _serialDataBitsComboBox->setEnabled(true);
1543 _serialStopBitsComboBox->setEnabled(true);
1544 _serialFlowControlComboBox->setEnabled(true);
1545 _serialAutoNMEAComboBox->setEnabled(true);
1546 if (_serialAutoNMEAComboBox->currentText() != "Auto" ) {
1547 _serialHeightNMEALineEdit->setStyleSheet("background-color: white");
1548 _serialHeightNMEALineEdit->setEnabled(true);
1549 _serialFileNMEALineEdit->setStyleSheet("background-color: lightGray");
1550 _serialFileNMEALineEdit->setEnabled(false);
1551 } else {
1552 _serialHeightNMEALineEdit->setStyleSheet("background-color: lightGray");
1553 _serialHeightNMEALineEdit->setEnabled(false);
1554 _serialFileNMEALineEdit->setStyleSheet("background-color: white");
1555 _serialFileNMEALineEdit->setEnabled(true);
1556 }
1557 } else {
1558 _serialPortNameLineEdit->setStyleSheet("background-color: lightGray");
1559 _serialBaudRateComboBox->setStyleSheet("background-color: lightGray");
1560 _serialParityComboBox->setStyleSheet("background-color: lightGray");
1561 _serialDataBitsComboBox->setStyleSheet("background-color: lightGray");
1562 _serialStopBitsComboBox->setStyleSheet("background-color: lightGray");
1563 _serialFlowControlComboBox->setStyleSheet("background-color: lightGray");
1564 _serialAutoNMEAComboBox->setStyleSheet("background-color: lightGray");
1565 _serialFileNMEALineEdit->setStyleSheet("background-color: lightGray");
1566 _serialHeightNMEALineEdit->setStyleSheet("background-color: lightGray");
1567 _serialPortNameLineEdit->setEnabled(false);
1568 _serialBaudRateComboBox->setEnabled(false);
1569 _serialParityComboBox->setEnabled(false);
1570 _serialDataBitsComboBox->setEnabled(false);
1571 _serialStopBitsComboBox->setEnabled(false);
1572 _serialFlowControlComboBox->setEnabled(false);
1573 _serialAutoNMEAComboBox->setEnabled(false);
1574 _serialHeightNMEALineEdit->setEnabled(false);
1575 _serialFileNMEALineEdit->setEnabled(false);
1576 }
1577 }
1578
1579 // Outages
1580 // -------
1581 if (_aogroup->currentIndex() == 7) {
1582 if (!isEmpty) {
1583 _adviseScriptLineEdit->setStyleSheet("background-color: white");
1584 _adviseFailSpinBox->setStyleSheet("background-color: white");
1585 _adviseRecoSpinBox->setStyleSheet("background-color: white");
1586 _adviseFailSpinBox->setEnabled(true);
1587 _adviseRecoSpinBox->setEnabled(true);
1588 _adviseScriptLineEdit->setEnabled(true);
1589 } else {
1590 _adviseScriptLineEdit->setStyleSheet("background-color: lightGray");
1591 _adviseFailSpinBox->setStyleSheet("background-color: lightGray");
1592 _adviseRecoSpinBox->setStyleSheet("background-color: lightGray");
1593 _adviseFailSpinBox->setEnabled(false);
1594 _adviseRecoSpinBox->setEnabled(false);
1595 _adviseScriptLineEdit->setEnabled(false);
1596 }
1597 }
1598
1599 // Miscellaneous
1600 // -------------
1601 if (_aogroup->currentIndex() == 8) {
1602 if (!isEmpty) {
1603 _perfIntrComboBox->setStyleSheet("background-color: white");
1604 palette.setColor(_scanRTCMCheckBox->backgroundRole(), white);
1605 _scanRTCMCheckBox->setPalette(palette);
1606 _perfIntrComboBox->setEnabled(true);
1607 _scanRTCMCheckBox->setEnabled(true);
1608 } else {
1609 _perfIntrComboBox->setStyleSheet("background-color: lightGray");
1610 palette.setColor(_scanRTCMCheckBox->backgroundRole(), lightGray);
1611 _scanRTCMCheckBox->setPalette(palette);
1612 _perfIntrComboBox->setEnabled(false);
1613 _scanRTCMCheckBox->setEnabled(false);
1614 }
1615 }
1616
1617 // PPP Client
1618 // ----------
1619 if (_aogroup->currentIndex() == 9) {
1620 if (!isEmpty) {
1621 palette.setColor(_pppStaticCheckBox->backgroundRole(), white);
1622 palette.setColor(_pppUsePhaseCheckBox->backgroundRole(), white);
1623 palette.setColor(_pppEstTropoCheckBox->backgroundRole(), white);
1624 _pppStaticCheckBox->setPalette(palette);
1625 _pppUsePhaseCheckBox->setPalette(palette);
1626 _pppEstTropoCheckBox->setPalette(palette);
1627 _pppStaticCheckBox->setEnabled(true);
1628 _pppUsePhaseCheckBox->setEnabled(true);
1629 _pppEstTropoCheckBox->setEnabled(true);
1630 } else {
1631 palette.setColor(_pppStaticCheckBox->backgroundRole(), lightGray);
1632 palette.setColor(_pppUsePhaseCheckBox->backgroundRole(), lightGray);
1633 palette.setColor(_pppEstTropoCheckBox->backgroundRole(), lightGray);
1634 _pppStaticCheckBox->setPalette(palette);
1635 _pppUsePhaseCheckBox->setPalette(palette);
1636 _pppEstTropoCheckBox->setPalette(palette);
1637 _pppStaticCheckBox->setEnabled(false);
1638 _pppUsePhaseCheckBox->setEnabled(false);
1639 _pppEstTropoCheckBox->setEnabled(false);
1640 }
1641 }
1642}
Note: See TracBrowser for help on using the repository browser.