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

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

* empty log message *

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