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

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

* empty log message *

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