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

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

* empty log message *

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