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

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

* empty log message *

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