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

Last change on this file since 1049 was 1044, checked in by zdenek, 16 years ago

Zdenek Lukes: a) added logic for RTCM 2.3 messages 20/21 decoding

b) added logic for cycle slip flags (slip counters or lock time indicators) handling

File size: 46.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 <unistd.h>
42#include "bncwindow.h"
43#include "bncapp.h"
44#include "bncgetthread.h"
45#include "bnctabledlg.h"
46#include "bnchlpdlg.h"
47#include "bnchtml.h"
48#include "bnctableitem.h"
49
50using namespace std;
51
52// Constructor
53////////////////////////////////////////////////////////////////////////////
54bncWindow::bncWindow() {
55
56 _caster = 0;
57
58 int ww = QFontMetrics(this->font()).width('w');
59
60 static const QStringList labels = QString("account,mountpoint,decoder,lat,long,nmea,bytes").split(",");
61
62 setMinimumSize(80*ww, 65*ww);
63
64 setWindowTitle(tr("BKG Ntrip Client (BNC) Version 1.6"));
65
66 // Create Actions
67 // --------------
68 _actHelp = new QAction(tr("&Help Contents"),this);
69 connect(_actHelp, SIGNAL(triggered()), SLOT(slotHelp()));
70
71 _actAbout = new QAction(tr("&About BNC"),this);
72 connect(_actAbout, SIGNAL(triggered()), SLOT(slotAbout()));
73
74 _actFlowchart = new QAction(tr("&Flow Chart"),this);
75 connect(_actFlowchart, SIGNAL(triggered()), SLOT(slotFlowchart()));
76
77 _actFontSel = new QAction(tr("Select &Font"),this);
78 connect(_actFontSel, SIGNAL(triggered()), SLOT(slotFontSel()));
79
80 _actSaveOpt = new QAction(tr("&Save Options"),this);
81 connect(_actSaveOpt, SIGNAL(triggered()), SLOT(slotSaveOptions()));
82
83 _actQuit = new QAction(tr("&Quit"),this);
84 connect(_actQuit, SIGNAL(triggered()), SLOT(close()));
85
86 _actAddMountPoints = new QAction(tr("Add &Mountpoints"),this);
87 connect(_actAddMountPoints, SIGNAL(triggered()), SLOT(slotAddMountPoints()));
88
89 _actDeleteMountPoints = new QAction(tr("&Delete Mountpoints"),this);
90 connect(_actDeleteMountPoints, SIGNAL(triggered()), SLOT(slotDeleteMountPoints()));
91 _actDeleteMountPoints->setEnabled(false);
92
93 _actGetData = new QAction(tr("Sta&rt"),this);
94 connect(_actGetData, SIGNAL(triggered()), SLOT(slotGetData()));
95
96 _actStop = new QAction(tr("Sto&p"),this);
97 connect(_actStop, SIGNAL(triggered()), SLOT(slotStop()));
98 _actStop->setEnabled(false);
99
100 _actwhatsthis= new QAction(tr("Help=Shift+F1"),this);
101 connect(_actwhatsthis, SIGNAL(triggered()), SLOT(slotWhatsThis()));
102
103 CreateMenu();
104 AddToolbar();
105
106 QSettings settings;
107 _proxyHostLineEdit = new QLineEdit(settings.value("proxyHost").toString());
108 _proxyPortLineEdit = new QLineEdit(settings.value("proxyPort").toString());
109 _proxyPortLineEdit->setMaximumWidth(9*ww);
110 _messTypesLineEdit = new QLineEdit(settings.value("messTypes").toString());
111 _messTypesLineEdit->setMaximumWidth(20*ww);
112 _waitTimeSpinBox = new QSpinBox();
113 _waitTimeSpinBox->setMinimum(1);
114 _waitTimeSpinBox->setMaximum(30);
115 _waitTimeSpinBox->setSingleStep(1);
116 _waitTimeSpinBox->setSuffix(" sec");
117 _waitTimeSpinBox->setMaximumWidth(9*ww);
118 _waitTimeSpinBox->setValue(settings.value("waitTime").toInt());
119 _outFileLineEdit = new QLineEdit(settings.value("outFile").toString());
120 _outPortLineEdit = new QLineEdit(settings.value("outPort").toString());
121 _outPortLineEdit->setMaximumWidth(9*ww);
122 _outEphPortLineEdit = new QLineEdit(settings.value("outEphPort").toString());
123 _outEphPortLineEdit->setMaximumWidth(9*ww);
124 _corrPortLineEdit = new QLineEdit(settings.value("corrPort").toString());
125 _corrPortLineEdit->setMaximumWidth(9*ww);
126 _rnxPathLineEdit = new QLineEdit(settings.value("rnxPath").toString());
127 _ephPathLineEdit = new QLineEdit(settings.value("ephPath").toString());
128 _corrPathLineEdit = new QLineEdit(settings.value("corrPath").toString());
129 _corrLateCheckBox = new QCheckBox();
130 _corrLateCheckBox->setCheckState(Qt::CheckState(
131 settings.value("corrLate").toInt()));
132
133 _rnxV3CheckBox = new QCheckBox();
134 _rnxV3CheckBox->setCheckState(Qt::CheckState(settings.value("rnxV3").toInt()));
135 _ephV3CheckBox = new QCheckBox();
136 _ephV3CheckBox->setCheckState(Qt::CheckState(settings.value("ephV3").toInt()));
137 _rnxScrpLineEdit = new QLineEdit(settings.value("rnxScript").toString());
138 _rnxSkelLineEdit = new QLineEdit(settings.value("rnxSkel").toString());
139 _rnxSkelLineEdit->setMaximumWidth(5*ww);
140 _rnxAppendCheckBox = new QCheckBox();
141 _rnxAppendCheckBox->setCheckState(Qt::CheckState(
142 settings.value("rnxAppend").toInt()));
143 _rnxIntrComboBox = new QComboBox();
144 _rnxIntrComboBox->setMaximumWidth(9*ww);
145 _rnxIntrComboBox->setEditable(false);
146 _rnxIntrComboBox->addItems(QString("1 min,2 min,5 min,10 min,15 min,30 min,1 hour,1 day").split(","));
147 int ii = _rnxIntrComboBox->findText(settings.value("rnxIntr").toString());
148 if (ii != -1) {
149 _rnxIntrComboBox->setCurrentIndex(ii);
150 }
151 _ephIntrComboBox = new QComboBox();
152 _ephIntrComboBox->setMaximumWidth(9*ww);
153 _ephIntrComboBox->setEditable(false);
154 _ephIntrComboBox->addItems(QString("1 min,2 min,5 min,10 min,15 min,30 min,1 hour,1 day").split(","));
155 int jj = _ephIntrComboBox->findText(settings.value("ephIntr").toString());
156 if (jj != -1) {
157 _ephIntrComboBox->setCurrentIndex(jj);
158 }
159 _corrIntrComboBox = new QComboBox();
160 _corrIntrComboBox->setMaximumWidth(9*ww);
161 _corrIntrComboBox->setEditable(false);
162 _corrIntrComboBox->addItems(QString("1 min,2 min,5 min,10 min,15 min,30 min,1 hour,1 day").split(","));
163 int mm = _corrIntrComboBox->findText(settings.value("corrIntr").toString());
164 if (mm != -1) {
165 _corrIntrComboBox->setCurrentIndex(mm);
166 }
167 _corrTimeSpinBox = new QSpinBox();
168 _corrTimeSpinBox->setMinimum(1);
169 _corrTimeSpinBox->setMaximum(30);
170 _corrTimeSpinBox->setSingleStep(1);
171 _corrTimeSpinBox->setSuffix(" sec");
172 _corrTimeSpinBox->setMaximumWidth(9*ww);
173 _corrTimeSpinBox->setValue(settings.value("corrTime").toInt());
174 _rnxSamplSpinBox = new QSpinBox();
175 _rnxSamplSpinBox->setMinimum(0);
176 _rnxSamplSpinBox->setMaximum(60);
177 _rnxSamplSpinBox->setSingleStep(5);
178 _rnxSamplSpinBox->setMaximumWidth(9*ww);
179 _rnxSamplSpinBox->setValue(settings.value("rnxSampl").toInt());
180 _rnxSamplSpinBox->setSuffix(" sec");
181
182 _binSamplSpinBox = new QSpinBox();
183 _binSamplSpinBox->setMinimum(0);
184 _binSamplSpinBox->setMaximum(60);
185 _binSamplSpinBox->setSingleStep(5);
186 _binSamplSpinBox->setMaximumWidth(9*ww);
187 _binSamplSpinBox->setValue(settings.value("binSampl").toInt());
188 _binSamplSpinBox->setSuffix(" sec");
189
190 _obsRateComboBox = new QComboBox();
191 _obsRateComboBox->setMaximumWidth(9*ww);
192 _obsRateComboBox->setEditable(false);
193 _obsRateComboBox->addItems(QString(",0.1 Hz,0.2 Hz,0.5 Hz,1 Hz,5 Hz").split(","));
194 int kk = _obsRateComboBox->findText(settings.value("obsRate").toString());
195 if (kk != -1) {
196 _obsRateComboBox->setCurrentIndex(kk);
197 }
198 _makePauseCheckBox = new QCheckBox();
199 _makePauseCheckBox->setCheckState(Qt::CheckState(
200 settings.value("makePause").toInt()));
201 _adviseRecoSpinBox = new QSpinBox();
202 _adviseRecoSpinBox->setMinimum(0);
203 _adviseRecoSpinBox->setMaximum(60);
204 _adviseRecoSpinBox->setSingleStep(1);
205 _adviseRecoSpinBox->setSuffix(" min");
206 _adviseRecoSpinBox->setMaximumWidth(9*ww);
207 _adviseRecoSpinBox->setValue(settings.value("adviseReco").toInt());
208 _adviseFailSpinBox = new QSpinBox();
209 _adviseFailSpinBox->setMinimum(0);
210 _adviseFailSpinBox->setMaximum(60);
211 _adviseFailSpinBox->setSingleStep(1);
212 _adviseFailSpinBox->setSuffix(" min");
213 _adviseFailSpinBox->setMaximumWidth(9*ww);
214 _adviseFailSpinBox->setValue(settings.value("adviseFail").toInt());
215 _logFileLineEdit = new QLineEdit(settings.value("logFile").toString());
216 _adviseScriptLineEdit = new QLineEdit(settings.value("adviseScript").toString());
217
218 _perfIntrComboBox = new QComboBox();
219 _perfIntrComboBox->setMaximumWidth(9*ww);
220 _perfIntrComboBox->setEditable(false);
221 _perfIntrComboBox->addItems(QString(",1 min,5 min,15 min,1 hour,6 hours,1 day").split(","));
222 int ll = _perfIntrComboBox->findText(settings.value("perfIntr").toString());
223 if (ll != -1) {
224 _perfIntrComboBox->setCurrentIndex(ll);
225 }
226
227 _mountPointsTable = new QTableWidget(0,7);
228
229 _mountPointsTable->horizontalHeader()->resizeSection(1,34*ww);
230 _mountPointsTable->horizontalHeader()->resizeSection(2,9*ww);
231 _mountPointsTable->horizontalHeader()->resizeSection(3,7*ww);
232 _mountPointsTable->horizontalHeader()->resizeSection(4,7*ww);
233 _mountPointsTable->horizontalHeader()->resizeSection(5,5*ww);
234 _mountPointsTable->horizontalHeader()->setResizeMode(QHeaderView::Interactive);
235 _mountPointsTable->horizontalHeader()->setStretchLastSection(true);
236 _mountPointsTable->setHorizontalHeaderLabels(labels);
237 _mountPointsTable->setGridStyle(Qt::NoPen);
238 _mountPointsTable->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
239 _mountPointsTable->setSelectionMode(QAbstractItemView::ExtendedSelection);
240 _mountPointsTable->setSelectionBehavior(QAbstractItemView::SelectRows);
241 QListIterator<QString> it(settings.value("mountPoints").toStringList());
242 if (!it.hasNext()) {
243 _actGetData->setEnabled(false);
244 }
245 int iRow = 0;
246 while (it.hasNext()) {
247 QStringList hlp = it.next().split(" ");
248 if (hlp.size() < 5) continue;
249 _mountPointsTable->insertRow(iRow);
250
251 QUrl url(hlp[0]);
252
253 QString fullPath = url.host() + QString(":%1").arg(url.port()) + url.path();
254 QString format(hlp[1]); QString latitude(hlp[2]); QString longitude(hlp[3]);
255 QString nmea(hlp[4]);
256
257 QTableWidgetItem* it;
258 it = new QTableWidgetItem(url.userInfo());
259 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
260 _mountPointsTable->setItem(iRow, 0, it);
261
262 it = new QTableWidgetItem(fullPath);
263 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
264 _mountPointsTable->setItem(iRow, 1, it);
265
266 it = new QTableWidgetItem(format);
267 _mountPointsTable->setItem(iRow, 2, it);
268
269 if (nmea == "yes") {
270 it = new QTableWidgetItem(latitude);
271 _mountPointsTable->setItem(iRow, 3, it);
272 it = new QTableWidgetItem(longitude);
273 _mountPointsTable->setItem(iRow, 4, it);
274 } else {
275 it = new QTableWidgetItem(latitude);
276 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
277 _mountPointsTable->setItem(iRow, 3, it);
278 it = new QTableWidgetItem(longitude);
279 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
280 _mountPointsTable->setItem(iRow, 4, it);
281 }
282
283 it = new QTableWidgetItem(nmea);
284 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
285 _mountPointsTable->setItem(iRow, 5, it);
286
287 bncTableItem* bncIt = new bncTableItem();
288 bncIt->setFlags(bncIt->flags() & ~Qt::ItemIsEditable);
289 _mountPointsTable->setItem(iRow, 6, bncIt);
290
291 iRow++;
292 }
293 _mountPointsTable->hideColumn(0);
294 _mountPointsTable->sortItems(1);
295
296 connect(_mountPointsTable, SIGNAL(itemSelectionChanged()),
297 SLOT(slotSelectionChanged()));
298
299 _log = new QTextBrowser();
300 _log->setReadOnly(true);
301
302 // WhatsThis
303 // ---------
304 _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>"));
305 _proxyPortLineEdit->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>"));
306 _waitTimeSpinBox->setWhatsThis(tr("<p>When feeding a real-time GNSS engine waiting for 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 engine or products.</p><p>Note that 'Wait for full epoch' does not effect the RINEX Observation file content. Observations received later than 'Wait for full epoch' seconds will still be included in the RINEX Observation files.</p>"));
307 _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."));
308 _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."));
309 _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."));
310 _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."));
311 _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."));
312 _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."));
313 _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."));
314 _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."));
315 _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><p>The triggering event for calling the script or batch file is the end of a RINEX Observation file 'Interval'. If that is overridden by a stream outage, the triggering event is the stream reconnection.</p>"));
316 _rnxSkelLineEdit->setWhatsThis(tr("<p>Whenever BNC starts generating RINEX Observation files (and then once every day at midnight), it first tries to retrieve information needed for RINEX headers from so-called public RINEX header skeleton files which are derived from sitelogs. However, sometimes public RINEX header skeleton files are not available, its contents is not up to date, or you need to put additional/optional records in the RINEX header.</p><p>For that 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. A file in the RINEX 'Directory' with the RINEX 'Skeleton extension' is interpreted by BNC as a personal RINEX header skeleton file for the corresponding stream.</p>"));
317 _corrLateCheckBox->setWhatsThis(tr("<p>Log latency of Broadcast Ephemeris Corrections.</p>"));
318 _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>"));
319 _rnxIntrComboBox->setWhatsThis(tr("<p>Select the length of the RINEX Observation file.</p>"));
320 _ephIntrComboBox->setWhatsThis(tr("<p>Select the length of the RINEX Navigation file.</p>"));
321 _corrIntrComboBox->setWhatsThis(tr("<p>Select the length of the Broadcast Ephemeris Correction files.</p>"));
322 _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>"));
323 _binSamplSpinBox->setWhatsThis(tr("<p>Select the Observation sampling interval in seconds. A value of zero '0' tells BNC to send/store all received epochs.</p>"));
324 _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><p>An empty option field (default) means that you don't want an explicit information from BNC about stream outages and incoming streams that can not be decoded and that the special procedure for handling of corrupted streams is bypassed.</p>"));
325 _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><p>Note that for using this function you need to specify the 'Observation rate'.</p>"));
326 _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><p>Note that for using this function you need to specify the 'Observation rate'.</p>"));
327 _makePauseCheckBox->setWhatsThis(tr("<p>In case of a continuously corrupted stream, the decoding process can be paused and decodings are then attempted again at decreasing rate till the stream hopefully recovers. Tick 'Pause' to activate this function.</p><p>Do not tick 'Pause' (default) in order to prevent BNC from making any decoding pause. Be aware that this may incur an unnecessary workload.</p><p>Note that this function is only effective if an 'Observation rate' is specified.</p>"));
328 _logFileLineEdit->setWhatsThis(tr("Records of BNC's activities are shown in the Log section 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."));
329 _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 can be configured to send an 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><p> Note that for using this function you need to specify the 'Observation rate'.</p>"));
330 _perfIntrComboBox->setWhatsThis(tr("<p>BNC can average all observation latencies per stream over a certain period of GPS time. The resulting mean latencies of observations are recorded in the Log file/section at the end of each 'Performance log' interval together with results of a statistical evaluation (approximate number of covered epochs, data gaps).</p><p>Select a 'Performance log' interval or select the empty option field if you do not want BNC to log latencies and statistical information.</p>"));
331 _mountPointsTable->setWhatsThis(tr("<p>Streams selected for retrieval are listed in the 'Mountpoints' section. Clicking on 'Add Mountpoints' 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 'Mountpoints' list, highlight it by clicking on it and hit the 'Delete Mountpoints' button. You can also remove multiple mountpoints 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' and 'format-details' as given in the sourcetable. However, there might be cases where you need to override the automatic selection due to incorrect sourcetable for example. BNC allows users to manually select the required decoder 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). To initiate these streams, an approximate rover position needs to be sent in NMEA GGA message to the NTRIP broadcaster. In return, a user-specific data stream is generated, typically by a Network-RTK software. This stream is customized to the exact latitude and longitude as shown in the 'lat' and 'long' columns under 'Mountpoints'. These VRS streams are indicated by a 'yes' in the 'nmea' column under 'Mountpoints' as well as in the sourcetable. The default 'lat' and 'long' values are taken from the sourcetable. However, in most cases you would probably want to change this according to your requirement. Double click on 'lat' and 'long' fields, enter the values you wish to send and then hit Enter. The format is in positive north latitude degrees (e.g. for northern hemisphere: 52.436, for southern hemisphere: -24.567) and eastern longitude degrees (e.g.: 358.872 or -1.128). Only mountpoints with a 'yes' in its 'nmea' column can be edited. The position should preferably be a point within the coverage of the network.</p>"));
332 _log->setWhatsThis(tr("Records of BNC's activities are shown in the Log section. 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."));
333 _ephV3CheckBox->setWhatsThis(tr("The default format for RINEX Navigation files containing Broadcast Ephemeris is RINEX Version 2.11. Select 'Version 3' if you want to save the ephemeris in RINEX Version 3 format."));
334 _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."));
335 _messTypesLineEdit->setWhatsThis(tr("<p>Specify the mountpoint of an RTCM Version 3.x stream to log the numbers of incoming message types.</p><p>An empty option field (default) means that you don't want BNC to print the message type numbers carried in a specific stream.</p>"));
336
337 // Canvas with Editable Fields
338 // ---------------------------
339 _canvas = new QWidget;
340 setCentralWidget(_canvas);
341
342 QTabWidget* aogroup = new QTabWidget();
343 QWidget* pgroup = new QWidget();
344 QWidget* ggroup = new QWidget();
345 QWidget* sgroup = new QWidget();
346 QWidget* egroup = new QWidget();
347 QWidget* agroup = new QWidget();
348 QWidget* cgroup = new QWidget();
349 QWidget* ogroup = new QWidget();
350 QWidget* rgroup = new QWidget();
351 aogroup->addTab(pgroup,tr("Proxy"));
352 aogroup->addTab(ggroup,tr("General"));
353 aogroup->addTab(ogroup,tr("RINEX Observations"));
354 aogroup->addTab(egroup,tr("RINEX Ephemeris"));
355 aogroup->addTab(sgroup,tr("Synchronized Observations"));
356 aogroup->addTab(cgroup,tr("Ephemeris Corrections"));
357 aogroup->addTab(agroup,tr("Monitor"));
358 aogroup->addTab(rgroup,tr("RTCM Message Types"));
359
360 QGridLayout* pLayout = new QGridLayout;
361 pLayout->setColumnMinimumWidth(0,14*ww);
362 pLayout->addWidget(new QLabel("Proxy host"),0,0, Qt::AlignLeft);
363 pLayout->addWidget(_proxyHostLineEdit,0, 1);
364 pLayout->addWidget(new QLabel("Proxy port"),1,0, Qt::AlignLeft);
365 pLayout->addWidget(_proxyPortLineEdit,1,1);
366 pLayout->addWidget(new QLabel("Settings for the proxy in protected networks, leave the boxes blank if none."),2, 0, 1, 2, Qt::AlignLeft);
367 pLayout->addWidget(new QLabel(" "),3,0);
368 pLayout->addWidget(new QLabel(" "),4,0);
369 pLayout->addWidget(new QLabel(" "),5,0);
370 pgroup->setLayout(pLayout);
371
372 QGridLayout* gLayout = new QGridLayout;
373 gLayout->setColumnMinimumWidth(0,14*ww);
374 gLayout->addWidget(new QLabel("Logfile (full path)"), 0,0);
375 gLayout->addWidget(_logFileLineEdit, 0,1);
376 gLayout->addWidget(new QLabel("Append files") ,1,0 );
377 gLayout->addWidget(_rnxAppendCheckBox, 1,1 );
378 gLayout->addWidget(new QLabel("General settings for logfile and file handling."),2, 0, 1, 2, Qt::AlignLeft);
379 gLayout->addWidget(new QLabel(" "),3,0);
380 gLayout->addWidget(new QLabel(" "),4,0);
381 gLayout->addWidget(new QLabel(" "),5,0);
382 ggroup->setLayout(gLayout);
383
384 QGridLayout* sLayout = new QGridLayout;
385 sLayout->setColumnMinimumWidth(0,14*ww);
386 sLayout->addWidget(new QLabel("Port"), 0, 0);
387 sLayout->addWidget(_outPortLineEdit, 0, 1);
388 sLayout->addWidget(new QLabel("Wait for full epoch"), 1, 0);
389 sLayout->addWidget(_waitTimeSpinBox, 1, 1);
390 sLayout->addWidget(new QLabel("File (full path)"), 2, 0);
391 sLayout->addWidget(_outFileLineEdit, 2, 1);
392 sLayout->addWidget(new QLabel("Sampling"), 3, 0, Qt::AlignLeft);
393 sLayout->addWidget(_binSamplSpinBox, 3, 1, Qt::AlignLeft);
394 sLayout->addWidget(new QLabel("Output synchronized observations epoch by epoch."),4,0,1,2,Qt::AlignLeft);
395 sLayout->addWidget(new QLabel(" "),5,0);
396 sLayout->addWidget(new QLabel(" "),6,0);
397 sgroup->setLayout(sLayout);
398
399 QGridLayout* eLayout = new QGridLayout;
400 eLayout->setColumnMinimumWidth(0,14*ww);
401 eLayout->addWidget(new QLabel("Directory"), 0, 0);
402 eLayout->addWidget(_ephPathLineEdit, 0, 1);
403 eLayout->addWidget(new QLabel("Interval"), 1, 0);
404 eLayout->addWidget(_ephIntrComboBox, 1, 1);
405 eLayout->addWidget(new QLabel("Port"), 2, 0);
406 eLayout->addWidget(_outEphPortLineEdit, 2, 1);
407 eLayout->addWidget(new QLabel("Version 3"), 3, 0);
408 eLayout->addWidget(_ephV3CheckBox, 3, 1);
409 eLayout->addWidget(new QLabel("Saving RINEX ephemeris files and ephemeris output through IP port."),4,0,1,2,Qt::AlignLeft);
410 eLayout->addWidget(new QLabel(" "),5,0);
411 egroup->setLayout(eLayout);
412
413 QGridLayout* aLayout = new QGridLayout;
414 aLayout->setColumnMinimumWidth(0,14*ww);
415 aLayout->addWidget(new QLabel("Observation rate"), 0, 0);
416 aLayout->addWidget(_obsRateComboBox, 0, 1);
417 aLayout->addWidget(new QLabel("Failure threshold"), 1, 0);
418 aLayout->addWidget(_adviseFailSpinBox, 1, 1);
419 aLayout->addWidget(new QLabel("Recovery threshold"), 2, 0);
420 aLayout->addWidget(_adviseRecoSpinBox, 2, 1);
421 aLayout->addWidget(new QLabel("Pause"), 2, 2, Qt::AlignRight);
422 aLayout->addWidget(_makePauseCheckBox, 2, 3, Qt::AlignLeft);
423 aLayout->addWidget(new QLabel("Script (full path)"), 3, 0);
424 aLayout->addWidget(_adviseScriptLineEdit, 3, 1,1,10);
425 aLayout->addWidget(new QLabel("Performance log"), 4, 0);
426 aLayout->addWidget(_perfIntrComboBox, 4, 1);
427 aLayout->addWidget(new QLabel("Network monitoring, outages, handling of corrupted streams, latencies, statistics."),5,0,1,10,Qt::AlignLeft);
428 agroup->setLayout(aLayout);
429
430 QGridLayout* rLayout = new QGridLayout;
431 rLayout->setColumnMinimumWidth(0,14*ww);
432 rLayout->addWidget(new QLabel("Mountpoint"),0,0, Qt::AlignLeft);
433 rLayout->addWidget(_messTypesLineEdit,0,1,1,15,Qt::AlignLeft);
434 rLayout->addWidget(new QLabel("Log numbers of message types in RTCM Version 3.x stream."),1, 0, 1, 4, Qt::AlignLeft);
435 rLayout->addWidget(new QLabel(" "),2,0);
436 rLayout->addWidget(new QLabel(" "),3,0);
437 rLayout->addWidget(new QLabel(" "),4,0);
438 rLayout->addWidget(new QLabel(" "),5,0);
439 rgroup->setLayout(rLayout);
440
441 QGridLayout* oLayout = new QGridLayout;
442 oLayout->setColumnMinimumWidth(0,14*ww);
443 oLayout->addWidget(new QLabel("Directory"), 0, 0);
444 oLayout->addWidget(_rnxPathLineEdit, 0, 1,1,12);
445 oLayout->addWidget(new QLabel("Interval"), 1, 0);
446 oLayout->addWidget(_rnxIntrComboBox, 1, 1);
447 oLayout->addWidget(new QLabel("Sampling"), 1, 2, Qt::AlignRight);
448 oLayout->addWidget(_rnxSamplSpinBox, 1, 3, Qt::AlignLeft);
449 oLayout->addWidget(new QLabel("Skeleton extension"), 2, 0);
450 oLayout->addWidget(_rnxSkelLineEdit, 2, 1,1,1, Qt::AlignLeft);
451 oLayout->addWidget(new QLabel("Script (full path)"), 3, 0);
452 oLayout->addWidget(_rnxScrpLineEdit, 3, 1,1,12);
453 oLayout->addWidget(new QLabel("Version 3"), 4, 0);
454 oLayout->addWidget(_rnxV3CheckBox, 4, 1);
455 oLayout->addWidget(new QLabel("Saving RINEX observation files."),5,0,1,12, Qt::AlignLeft);
456 ogroup->setLayout(oLayout);
457
458 QGridLayout* cLayout = new QGridLayout;
459 cLayout->setColumnMinimumWidth(0,14*ww);
460 cLayout->addWidget(new QLabel("Directory"), 0, 0);
461 cLayout->addWidget(_corrPathLineEdit, 0, 1);
462 cLayout->addWidget(new QLabel("Interval"), 1, 0);
463 cLayout->addWidget(_corrIntrComboBox, 1, 1);
464 cLayout->addWidget(new QLabel("Port"), 2, 0);
465 cLayout->addWidget(_corrPortLineEdit, 2, 1);
466 cLayout->addWidget(new QLabel("Wait for full epoch"), 3, 0);
467 cLayout->addWidget(_corrTimeSpinBox, 3, 1);
468 cLayout->addWidget(new QLabel("Latency log"), 4, 0);
469 cLayout->addWidget(_corrLateCheckBox, 4, 1);
470 cLayout->addWidget(new QLabel("Saving Broadcast Ephemeris correction files and correction output through IP port."),5,0,1,2,Qt::AlignLeft);
471 cgroup->setLayout(cLayout);
472
473 QVBoxLayout* mLayout = new QVBoxLayout;
474 mLayout->addWidget(aogroup);
475 mLayout->addWidget(_mountPointsTable);
476 mLayout->addWidget(_log);
477
478 _canvas->setLayout(mLayout);
479}
480
481// Destructor
482////////////////////////////////////////////////////////////////////////////
483bncWindow::~bncWindow() {
484 delete _caster;
485}
486
487// Retrieve Table
488////////////////////////////////////////////////////////////////////////////
489void bncWindow::slotAddMountPoints() {
490
491 QSettings settings;
492 QString proxyHost = settings.value("proxyHost").toString();
493 int proxyPort = settings.value("proxyPort").toInt();
494 if (proxyHost != _proxyHostLineEdit->text() ||
495 proxyPort != _proxyPortLineEdit->text().toInt()) {
496 int iRet = QMessageBox::question(this, "Question", "Proxy options "
497 "changed. Use the new ones?",
498 QMessageBox::Yes, QMessageBox::No,
499 QMessageBox::NoButton);
500 if (iRet == QMessageBox::Yes) {
501 settings.setValue("proxyHost", _proxyHostLineEdit->text());
502 settings.setValue("proxyPort", _proxyPortLineEdit->text());
503 }
504 }
505
506 bncTableDlg* dlg = new bncTableDlg(this);
507 dlg->move(this->pos().x()+50, this->pos().y()+50);
508 connect(dlg, SIGNAL(newMountPoints(QStringList*)),
509 this, SLOT(slotNewMountPoints(QStringList*)));
510 dlg->exec();
511 delete dlg;
512
513}
514
515// Delete Selected Mount Points
516////////////////////////////////////////////////////////////////////////////
517void bncWindow::slotDeleteMountPoints() {
518
519 int nRows = _mountPointsTable->rowCount();
520 bool flg[nRows];
521 for (int iRow = 0; iRow < nRows; iRow++) {
522 if (_mountPointsTable->isItemSelected(_mountPointsTable->item(iRow,1))) {
523 flg[iRow] = true;
524 }
525 else {
526 flg[iRow] = false;
527 }
528 }
529 for (int iRow = nRows-1; iRow >= 0; iRow--) {
530 if (flg[iRow]) {
531 _mountPointsTable->removeRow(iRow);
532 }
533 }
534 _actDeleteMountPoints->setEnabled(false);
535
536 if (_mountPointsTable->rowCount() == 0) {
537 _actGetData->setEnabled(false);
538 }
539}
540
541// New Mount Points Selected
542////////////////////////////////////////////////////////////////////////////
543void bncWindow::slotNewMountPoints(QStringList* mountPoints) {
544 int iRow = 0;
545 QListIterator<QString> it(*mountPoints);
546 while (it.hasNext()) {
547 QStringList hlp = it.next().split(" ");
548 QUrl url(hlp[0]);
549 QString fullPath = url.host() + QString(":%1").arg(url.port()) + url.path();
550 QString format(hlp[1]); QString latitude(hlp[2]); QString longitude(hlp[3]);
551 QString nmea(hlp[4]);
552
553 _mountPointsTable->insertRow(iRow);
554
555 QTableWidgetItem* it;
556 it = new QTableWidgetItem(url.userInfo());
557 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
558 _mountPointsTable->setItem(iRow, 0, it);
559
560 it = new QTableWidgetItem(fullPath);
561 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
562 _mountPointsTable->setItem(iRow, 1, it);
563
564 it = new QTableWidgetItem(format);
565 _mountPointsTable->setItem(iRow, 2, it);
566
567 if (nmea == "yes") {
568 it = new QTableWidgetItem(latitude);
569 _mountPointsTable->setItem(iRow, 3, it);
570 it = new QTableWidgetItem(longitude);
571 _mountPointsTable->setItem(iRow, 4, it);
572 } else {
573 it = new QTableWidgetItem(latitude);
574 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
575 _mountPointsTable->setItem(iRow, 3, it);
576 it = new QTableWidgetItem(longitude);
577 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
578 _mountPointsTable->setItem(iRow, 4, it);
579 }
580
581 it = new QTableWidgetItem(nmea);
582 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
583 _mountPointsTable->setItem(iRow, 5, it);
584
585 bncTableItem* bncIt = new bncTableItem();
586 _mountPointsTable->setItem(iRow, 6, bncIt);
587
588 iRow++;
589 }
590 _mountPointsTable->hideColumn(0);
591 _mountPointsTable->sortItems(1);
592 if (mountPoints->count() > 0) {
593 _actGetData->setEnabled(true);
594 }
595 delete mountPoints;
596}
597
598// Save Options
599////////////////////////////////////////////////////////////////////////////
600void bncWindow::slotSaveOptions() {
601 QSettings settings;
602 settings.setValue("proxyHost", _proxyHostLineEdit->text());
603 settings.setValue("proxyPort", _proxyPortLineEdit->text());
604 settings.setValue("waitTime", _waitTimeSpinBox->value());
605 settings.setValue("obsRate", _obsRateComboBox->currentText());
606 settings.setValue("adviseFail", _adviseFailSpinBox->value());
607 settings.setValue("adviseReco", _adviseRecoSpinBox->value());
608 settings.setValue("makePause", _makePauseCheckBox->checkState());
609 settings.setValue("outFile", _outFileLineEdit->text());
610 settings.setValue("perfIntr", _perfIntrComboBox->currentText());
611 settings.setValue("outPort", _outPortLineEdit->text());
612 settings.setValue("outEphPort", _outEphPortLineEdit->text());
613 settings.setValue("corrPort", _corrPortLineEdit->text());
614 settings.setValue("corrTime", _corrTimeSpinBox->value());
615 settings.setValue("rnxPath", _rnxPathLineEdit->text());
616 settings.setValue("ephPath", _ephPathLineEdit->text());
617 settings.setValue("corrPath", _corrPathLineEdit->text());
618 settings.setValue("rnxScript", _rnxScrpLineEdit->text());
619 settings.setValue("rnxIntr", _rnxIntrComboBox->currentText());
620 settings.setValue("ephIntr", _ephIntrComboBox->currentText());
621 settings.setValue("corrIntr", _corrIntrComboBox->currentText());
622 settings.setValue("rnxSampl", _rnxSamplSpinBox->value());
623 settings.setValue("binSampl", _binSamplSpinBox->value());
624 settings.setValue("rnxSkel", _rnxSkelLineEdit->text());
625 settings.setValue("rnxAppend", _rnxAppendCheckBox->checkState());
626 settings.setValue("corrLate", _corrLateCheckBox->checkState());
627 settings.setValue("rnxV3", _rnxV3CheckBox->checkState());
628 settings.setValue("ephV3", _ephV3CheckBox->checkState());
629 settings.setValue("logFile", _logFileLineEdit->text());
630 settings.setValue("adviseScript",_adviseScriptLineEdit->text());
631 settings.setValue("messTypes", _messTypesLineEdit->text());
632
633QStringList mountPoints;
634
635 for (int iRow = 0; iRow < _mountPointsTable->rowCount(); iRow++) {
636 QUrl url( "//" + _mountPointsTable->item(iRow, 0)->text() +
637 "@" + _mountPointsTable->item(iRow, 1)->text() );
638
639 mountPoints.append(url.toString() + " " +
640 _mountPointsTable->item(iRow, 2)->text()
641 + " " + _mountPointsTable->item(iRow, 3)->text()
642 + " " + _mountPointsTable->item(iRow, 4)->text()
643 + " " + _mountPointsTable->item(iRow, 5)->text());
644 }
645 settings.setValue("mountPoints", mountPoints);
646}
647
648// All get slots terminated
649////////////////////////////////////////////////////////////////////////////
650void bncWindow::slotGetThreadErrors() {
651 slotMessage("All Get Threads Terminated");
652 ((bncApp*)qApp)->slotMessage("All Get Threads Terminated");
653 _actAddMountPoints->setEnabled(true);
654 _actGetData->setEnabled(true);
655}
656
657// Retrieve Data
658////////////////////////////////////////////////////////////////////////////
659void bncWindow::slotGetData() {
660 slotSaveOptions();
661
662 _actAddMountPoints->setEnabled(false);
663 _actDeleteMountPoints->setEnabled(false);
664 _actGetData->setEnabled(false);
665 _actStop->setEnabled(true);
666
667 _caster = new bncCaster(_outFileLineEdit->text(),
668 _outPortLineEdit->text().toInt());
669
670 ((bncApp*)qApp)->setPort(_outEphPortLineEdit->text().toInt());
671 ((bncApp*)qApp)->setPortCorr(_corrPortLineEdit->text().toInt());
672
673 connect(_caster, SIGNAL(getThreadErrors()),
674 this, SLOT(slotGetThreadErrors()));
675
676 connect(_caster, SIGNAL(newMessage(QByteArray)),
677 this, SLOT(slotMessage(QByteArray)));
678 connect(_caster, SIGNAL(newMessage(QByteArray)),
679 (bncApp*)qApp, SLOT(slotMessage(QByteArray)));
680 connect((bncApp*)qApp, SIGNAL(newMessage(QByteArray)),
681 this, SLOT(slotMessage(QByteArray)));
682
683 slotMessage("============ Start BNC ============");
684 ((bncApp*)qApp)->slotMessage("============ Start BNC ============");
685
686 for (int iRow = 0; iRow < _mountPointsTable->rowCount(); iRow++) {
687 QUrl url( "//" + _mountPointsTable->item(iRow, 0)->text() +
688 "@" + _mountPointsTable->item(iRow, 1)->text() );
689
690 QByteArray format = _mountPointsTable->item(iRow, 2)->text().toAscii();
691
692 QByteArray latitude = _mountPointsTable->item(iRow, 3)->text().toAscii();
693 QByteArray longitude = _mountPointsTable->item(iRow, 4)->text().toAscii();
694 QByteArray nmea = _mountPointsTable->item(iRow, 5)->text().toAscii();
695
696 bncGetThread* getThread = new bncGetThread(url, format, latitude, longitude, nmea, iRow);
697
698 connect(getThread, SIGNAL(newMessage(QByteArray)),
699 this, SLOT(slotMessage(QByteArray)));
700 connect(getThread, SIGNAL(newMessage(QByteArray)),
701 (bncApp*)qApp, SLOT(slotMessage(QByteArray)));
702
703 connect(getThread, SIGNAL(newBytes(QByteArray, double)),
704 (bncTableItem*) _mountPointsTable->item(iRow, 6),
705 SLOT(slotNewBytes(QByteArray, double)));
706
707 connect(((bncApp*)qApp), SIGNAL(newEphGPS(gpsephemeris)),
708 getThread, SLOT(slotNewEphGPS(gpsephemeris)));
709
710 _caster->addGetThread(getThread);
711
712 getThread->start();
713 }
714}
715
716// Retrieve Data
717////////////////////////////////////////////////////////////////////////////
718void bncWindow::slotStop() {
719 int iRet = QMessageBox::question(this, "Stop", "Stop retrieving data?",
720 QMessageBox::Yes, QMessageBox::No,
721 QMessageBox::NoButton);
722 if (iRet == QMessageBox::Yes) {
723 delete _caster; _caster = 0;
724 _actGetData->setEnabled(true);
725 _actStop->setEnabled(false);
726 _actAddMountPoints->setEnabled(true);
727 }
728}
729
730// Close Application gracefully
731////////////////////////////////////////////////////////////////////////////
732void bncWindow::closeEvent(QCloseEvent* event) {
733
734 int iRet = QMessageBox::question(this, "Close", "Save Options?",
735 QMessageBox::Yes, QMessageBox::No,
736 QMessageBox::Cancel);
737
738 if (iRet == QMessageBox::Cancel) {
739 event->ignore();
740 return;
741 }
742 else if (iRet == QMessageBox::Yes) {
743 slotSaveOptions();
744 }
745
746 QMainWindow::closeEvent(event);
747}
748
749// User changed the selection of mountPoints
750////////////////////////////////////////////////////////////////////////////
751void bncWindow::slotSelectionChanged() {
752 if (_mountPointsTable->selectedItems().isEmpty()) {
753 _actDeleteMountPoints->setEnabled(false);
754 }
755 else {
756 _actDeleteMountPoints->setEnabled(true);
757 }
758}
759
760// Display Program Messages
761////////////////////////////////////////////////////////////////////////////
762void bncWindow::slotMessage(const QByteArray msg) {
763
764 const int maxBufferSize = 10000;
765
766 QString txt = _log->toPlainText() + "\n" +
767 QDateTime::currentDateTime().toUTC().toString("yy-MM-dd hh:mm:ss ") + msg;
768 _log->clear();
769 _log->append(txt.right(maxBufferSize));
770}
771
772// About Message
773////////////////////////////////////////////////////////////////////////////
774void bncWindow::slotAbout() {
775 new bncAboutDlg(0);
776}
777
778//Flowchart
779////////////////////////////////////////////////////////////////////////////
780void bncWindow::slotFlowchart() {
781 new bncFlowchartDlg(0);
782}
783
784// Help Window
785////////////////////////////////////////////////////////////////////////////
786void bncWindow::slotHelp() {
787 QUrl url;
788 url.setPath(":bnchelp.html");
789 new bncHlpDlg(0, url);
790}
791
792// Select Fonts
793////////////////////////////////////////////////////////////////////////////
794void bncWindow::slotFontSel() {
795 bool ok;
796 QFont newFont = QFontDialog::getFont(&ok, this->font(), this);
797 if (ok) {
798 QSettings settings;
799 settings.setValue("font", newFont.toString());
800 QApplication::setFont(newFont);
801 int ww = QFontMetrics(newFont).width('w');
802 setMinimumSize(60*ww, 80*ww);
803 resize(60*ww, 80*ww);
804 }
805}
806
807// Whats This Help
808void bncWindow::slotWhatsThis() {
809QWhatsThis::enterWhatsThisMode();
810}
811
812void bncWindow::CreateMenu() {
813 // Create Menus
814 // ------------
815 _menuFile = menuBar()->addMenu(tr("&File"));
816 _menuFile->addAction(_actFontSel);
817 _menuFile->addSeparator();
818 _menuFile->addAction(_actSaveOpt);
819 _menuFile->addSeparator();
820 _menuFile->addAction(_actQuit);
821
822 _menuHlp = menuBar()->addMenu(tr("&Help"));
823 _menuHlp->addAction(_actHelp);
824 _menuHlp->addAction(_actFlowchart);
825 _menuHlp->addAction(_actAbout);
826}
827
828void bncWindow::AddToolbar() {
829 // Tool (Command) Bar
830 // ------------------
831 QToolBar* toolBar = new QToolBar;
832 addToolBar(Qt::BottomToolBarArea, toolBar);
833 toolBar->setMovable(false);
834 toolBar->addAction(_actAddMountPoints);
835 toolBar->addAction(_actDeleteMountPoints);
836 toolBar->addAction(_actGetData);
837 toolBar->addAction(_actStop);
838 toolBar->addWidget(new QLabel(" "));
839 toolBar->addAction(_actwhatsthis);
840}
841
842bncAboutDlg::bncAboutDlg(QWidget* parent) :
843 QDialog(parent) {
844
845 QTextBrowser* tb = new QTextBrowser;
846 QUrl url; url.setPath(":bncabout.html");
847 tb->setSource(url);
848 tb->setReadOnly(true);
849
850 int ww = QFontMetrics(font()).width('w');
851 QPushButton* _closeButton = new QPushButton("Close");
852 _closeButton->setMaximumWidth(10*ww);
853 connect(_closeButton, SIGNAL(clicked()), this, SLOT(close()));
854
855 QGridLayout* dlgLayout = new QGridLayout();
856 QLabel* img = new QLabel();
857 img->setPixmap(QPixmap(":ntrip-logo.png"));
858 dlgLayout->addWidget(img, 0,0);
859 dlgLayout->addWidget(new QLabel("BKG Ntrip Client (BNC) Version 1.6"), 0,1);
860 dlgLayout->addWidget(tb,1,0,1,2);
861 dlgLayout->addWidget(_closeButton,2,1,Qt::AlignRight);
862
863 setLayout(dlgLayout);
864 resize(60*ww, 60*ww);
865 show();
866}
867
868bncAboutDlg::~bncAboutDlg() {
869};
870
871bncFlowchartDlg::bncFlowchartDlg(QWidget* parent) :
872 QDialog(parent) {
873
874 int ww = QFontMetrics(font()).width('w');
875 QPushButton* _closeButton = new QPushButton("Close");
876 _closeButton->setMaximumWidth(10*ww);
877 connect(_closeButton, SIGNAL(clicked()), this, SLOT(close()));
878
879 QGridLayout* dlgLayout = new QGridLayout();
880 QLabel* img = new QLabel();
881 img->setPixmap(QPixmap(":bncflowchart.png"));
882 dlgLayout->addWidget(img, 0,0);
883 dlgLayout->addWidget(_closeButton,1,0,Qt::AlignLeft);
884
885 setLayout(dlgLayout);
886 show();
887}
888
889bncFlowchartDlg::~bncFlowchartDlg() {
890};
891
Note: See TracBrowser for help on using the repository browser.