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

Last change on this file since 1041 was 1041, checked in by weber, 16 years ago

* empty log message *

File size: 46.5 KB
Line 
1// Part of BNC, a utility for retrieving decoding and
2// converting GNSS data streams from NTRIP broadcasters.
3//
4// Copyright (C) 2007
5// German Federal Agency for Cartography and Geodesy (BKG)
6// http://www.bkg.bund.de
7// Czech Technical University Prague, Department of Geodesy
8// http://www.fsv.cvut.cz
9//
10// Email: euref-ip@bkg.bund.de
11//
12// This program is free software; you can redistribute it and/or
13// modify it under the terms of the GNU General Public License
14// as published by the Free Software Foundation, version 2.
15//
16// This program is distributed in the hope that it will be useful,
17// but WITHOUT ANY WARRANTY; without even the implied warranty of
18// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19// GNU General Public License for more details.
20//
21// You should have received a copy of the GNU General Public License
22// along with this program; if not, write to the Free Software
23// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24
25/* -------------------------------------------------------------------------
26 * BKG NTRIP Client
27 * -------------------------------------------------------------------------
28 *
29 * Class: bncWindow
30 *
31 * Purpose: This class implements the main application window.
32 *
33 * Author: L. Mervart
34 *
35 * Created: 24-Dec-2005
36 *
37 * Changes:
38 *
39 * -----------------------------------------------------------------------*/
40
41#include <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(77*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,12*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,12*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,12*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,12*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,12*ww);
415 aLayout->setColumnMinimumWidth(1,8*ww);
416 aLayout->setColumnMinimumWidth(2,12*ww);
417 aLayout->setColumnMinimumWidth(3,40*ww);
418 aLayout->addWidget(new QLabel("Observation rate"), 0, 0);
419 aLayout->addWidget(_obsRateComboBox, 0, 1);
420 aLayout->addWidget(new QLabel("Failure threshold"), 1, 0);
421 aLayout->addWidget(_adviseFailSpinBox, 1, 1);
422 aLayout->addWidget(new QLabel("Recovery threshold"), 2, 0);
423 aLayout->addWidget(_adviseRecoSpinBox, 2, 1);
424 aLayout->addWidget(new QLabel("Pause"), 2, 2, Qt::AlignRight);
425 aLayout->addWidget(_makePauseCheckBox, 2, 3, Qt::AlignLeft);
426 aLayout->addWidget(new QLabel("Script (full path)"), 3, 0);
427 aLayout->addWidget(_adviseScriptLineEdit, 3, 1,1,10);
428 aLayout->addWidget(new QLabel("Performance log"), 4, 0);
429 aLayout->addWidget(_perfIntrComboBox, 4, 1);
430 aLayout->addWidget(new QLabel("Network monitoring, outages, handling of corrupted streams, latencies, statistics."),5,0,1,10,Qt::AlignLeft);
431 agroup->setLayout(aLayout);
432
433 QGridLayout* rLayout = new QGridLayout;
434 rLayout->setColumnMinimumWidth(0,12*ww);
435 rLayout->setColumnMinimumWidth(1,30*ww);
436 rLayout->setColumnMinimumWidth(2,30*ww);
437 rLayout->addWidget(new QLabel("Mountpoint"),0,0, Qt::AlignLeft);
438 rLayout->addWidget(_messTypesLineEdit,0,1,1,15,Qt::AlignLeft);
439 rLayout->addWidget(new QLabel("Log numbers of message types in RTCM Version 3.x stream."),1, 0, 1, 4, Qt::AlignLeft);
440 rLayout->addWidget(new QLabel(" "),2,0);
441 rLayout->addWidget(new QLabel(" "),3,0);
442 rLayout->addWidget(new QLabel(" "),4,0);
443 rLayout->addWidget(new QLabel(" "),5,0);
444 rgroup->setLayout(rLayout);
445
446 QGridLayout* oLayout = new QGridLayout;
447 oLayout->setColumnMinimumWidth(0,12*ww);
448 oLayout->setColumnMinimumWidth(1,8*ww);
449 oLayout->setColumnMinimumWidth(2,12*ww);
450 oLayout->addWidget(new QLabel("Directory"), 0, 0);
451 oLayout->addWidget(_rnxPathLineEdit, 0, 1,1,12);
452 oLayout->addWidget(new QLabel("Interval"), 1, 0);
453 oLayout->addWidget(_rnxIntrComboBox, 1, 1);
454 oLayout->addWidget(new QLabel("Sampling"), 1, 2, Qt::AlignRight);
455 oLayout->addWidget(_rnxSamplSpinBox, 1, 3, Qt::AlignLeft);
456 oLayout->addWidget(new QLabel("Skeleton extension"), 2, 0);
457 oLayout->addWidget(_rnxSkelLineEdit, 2, 1,1,1, Qt::AlignLeft);
458 oLayout->addWidget(new QLabel("Script (full path)"), 3, 0);
459 oLayout->addWidget(_rnxScrpLineEdit, 3, 1,1,12);
460 oLayout->addWidget(new QLabel("Version 3"), 4, 0);
461 oLayout->addWidget(_rnxV3CheckBox, 4, 1);
462 oLayout->addWidget(new QLabel("Saving RINEX observation files."),5,0,1,12, Qt::AlignLeft);
463 ogroup->setLayout(oLayout);
464
465 QGridLayout* cLayout = new QGridLayout;
466 cLayout->setColumnMinimumWidth(0,12*ww);
467 cLayout->addWidget(new QLabel("Directory"), 0, 0);
468 cLayout->addWidget(_corrPathLineEdit, 0, 1);
469 cLayout->addWidget(new QLabel("Interval"), 1, 0);
470 cLayout->addWidget(_corrIntrComboBox, 1, 1);
471 cLayout->addWidget(new QLabel("Port"), 2, 0);
472 cLayout->addWidget(_corrPortLineEdit, 2, 1);
473 cLayout->addWidget(new QLabel("Wait for full epoch"), 3, 0);
474 cLayout->addWidget(_corrTimeSpinBox, 3, 1);
475 cLayout->addWidget(new QLabel("Latency log"), 4, 0);
476 cLayout->addWidget(_corrLateCheckBox, 4, 1);
477 cLayout->addWidget(new QLabel("Saving Broadcast Ephemeris correction files and correction output through IP port."),5,0,1,2,Qt::AlignLeft);
478 cgroup->setLayout(cLayout);
479
480 QVBoxLayout* mLayout = new QVBoxLayout;
481 mLayout->addWidget(aogroup);
482 mLayout->addWidget(_mountPointsTable);
483 mLayout->addWidget(_log);
484
485 _canvas->setLayout(mLayout);
486}
487
488// Destructor
489////////////////////////////////////////////////////////////////////////////
490bncWindow::~bncWindow() {
491 delete _caster;
492}
493
494// Retrieve Table
495////////////////////////////////////////////////////////////////////////////
496void bncWindow::slotAddMountPoints() {
497
498 QSettings settings;
499 QString proxyHost = settings.value("proxyHost").toString();
500 int proxyPort = settings.value("proxyPort").toInt();
501 if (proxyHost != _proxyHostLineEdit->text() ||
502 proxyPort != _proxyPortLineEdit->text().toInt()) {
503 int iRet = QMessageBox::question(this, "Question", "Proxy options "
504 "changed. Use the new ones?",
505 QMessageBox::Yes, QMessageBox::No,
506 QMessageBox::NoButton);
507 if (iRet == QMessageBox::Yes) {
508 settings.setValue("proxyHost", _proxyHostLineEdit->text());
509 settings.setValue("proxyPort", _proxyPortLineEdit->text());
510 }
511 }
512
513 bncTableDlg* dlg = new bncTableDlg(this);
514 dlg->move(this->pos().x()+50, this->pos().y()+50);
515 connect(dlg, SIGNAL(newMountPoints(QStringList*)),
516 this, SLOT(slotNewMountPoints(QStringList*)));
517 dlg->exec();
518 delete dlg;
519
520}
521
522// Delete Selected Mount Points
523////////////////////////////////////////////////////////////////////////////
524void bncWindow::slotDeleteMountPoints() {
525
526 int nRows = _mountPointsTable->rowCount();
527 bool flg[nRows];
528 for (int iRow = 0; iRow < nRows; iRow++) {
529 if (_mountPointsTable->isItemSelected(_mountPointsTable->item(iRow,1))) {
530 flg[iRow] = true;
531 }
532 else {
533 flg[iRow] = false;
534 }
535 }
536 for (int iRow = nRows-1; iRow >= 0; iRow--) {
537 if (flg[iRow]) {
538 _mountPointsTable->removeRow(iRow);
539 }
540 }
541 _actDeleteMountPoints->setEnabled(false);
542
543 if (_mountPointsTable->rowCount() == 0) {
544 _actGetData->setEnabled(false);
545 }
546}
547
548// New Mount Points Selected
549////////////////////////////////////////////////////////////////////////////
550void bncWindow::slotNewMountPoints(QStringList* mountPoints) {
551 int iRow = 0;
552 QListIterator<QString> it(*mountPoints);
553 while (it.hasNext()) {
554 QStringList hlp = it.next().split(" ");
555 QUrl url(hlp[0]);
556 QString fullPath = url.host() + QString(":%1").arg(url.port()) + url.path();
557 QString format(hlp[1]); QString latitude(hlp[2]); QString longitude(hlp[3]);
558 QString nmea(hlp[4]);
559
560 _mountPointsTable->insertRow(iRow);
561
562 QTableWidgetItem* it;
563 it = new QTableWidgetItem(url.userInfo());
564 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
565 _mountPointsTable->setItem(iRow, 0, it);
566
567 it = new QTableWidgetItem(fullPath);
568 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
569 _mountPointsTable->setItem(iRow, 1, it);
570
571 it = new QTableWidgetItem(format);
572 _mountPointsTable->setItem(iRow, 2, it);
573
574 if (nmea == "yes") {
575 it = new QTableWidgetItem(latitude);
576 _mountPointsTable->setItem(iRow, 3, it);
577 it = new QTableWidgetItem(longitude);
578 _mountPointsTable->setItem(iRow, 4, it);
579 } else {
580 it = new QTableWidgetItem(latitude);
581 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
582 _mountPointsTable->setItem(iRow, 3, it);
583 it = new QTableWidgetItem(longitude);
584 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
585 _mountPointsTable->setItem(iRow, 4, it);
586 }
587
588 it = new QTableWidgetItem(nmea);
589 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
590 _mountPointsTable->setItem(iRow, 5, it);
591
592 bncTableItem* bncIt = new bncTableItem();
593 _mountPointsTable->setItem(iRow, 6, bncIt);
594
595 iRow++;
596 }
597 _mountPointsTable->hideColumn(0);
598 _mountPointsTable->sortItems(1);
599 if (mountPoints->count() > 0) {
600 _actGetData->setEnabled(true);
601 }
602 delete mountPoints;
603}
604
605// Save Options
606////////////////////////////////////////////////////////////////////////////
607void bncWindow::slotSaveOptions() {
608 QSettings settings;
609 settings.setValue("proxyHost", _proxyHostLineEdit->text());
610 settings.setValue("proxyPort", _proxyPortLineEdit->text());
611 settings.setValue("waitTime", _waitTimeSpinBox->value());
612 settings.setValue("obsRate", _obsRateComboBox->currentText());
613 settings.setValue("adviseFail", _adviseFailSpinBox->value());
614 settings.setValue("adviseReco", _adviseRecoSpinBox->value());
615 settings.setValue("makePause", _makePauseCheckBox->checkState());
616 settings.setValue("outFile", _outFileLineEdit->text());
617 settings.setValue("perfIntr", _perfIntrComboBox->currentText());
618 settings.setValue("outPort", _outPortLineEdit->text());
619 settings.setValue("outEphPort", _outEphPortLineEdit->text());
620 settings.setValue("corrPort", _corrPortLineEdit->text());
621 settings.setValue("corrTime", _corrTimeSpinBox->value());
622 settings.setValue("rnxPath", _rnxPathLineEdit->text());
623 settings.setValue("ephPath", _ephPathLineEdit->text());
624 settings.setValue("corrPath", _corrPathLineEdit->text());
625 settings.setValue("rnxScript", _rnxScrpLineEdit->text());
626 settings.setValue("rnxIntr", _rnxIntrComboBox->currentText());
627 settings.setValue("ephIntr", _ephIntrComboBox->currentText());
628 settings.setValue("corrIntr", _corrIntrComboBox->currentText());
629 settings.setValue("rnxSampl", _rnxSamplSpinBox->value());
630 settings.setValue("binSampl", _binSamplSpinBox->value());
631 settings.setValue("rnxSkel", _rnxSkelLineEdit->text());
632 settings.setValue("rnxAppend", _rnxAppendCheckBox->checkState());
633 settings.setValue("corrLate", _corrLateCheckBox->checkState());
634 settings.setValue("rnxV3", _rnxV3CheckBox->checkState());
635 settings.setValue("ephV3", _ephV3CheckBox->checkState());
636 settings.setValue("logFile", _logFileLineEdit->text());
637 settings.setValue("adviseScript",_adviseScriptLineEdit->text());
638 settings.setValue("messTypes", _messTypesLineEdit->text());
639
640QStringList mountPoints;
641
642 for (int iRow = 0; iRow < _mountPointsTable->rowCount(); iRow++) {
643 QUrl url( "//" + _mountPointsTable->item(iRow, 0)->text() +
644 "@" + _mountPointsTable->item(iRow, 1)->text() );
645
646 mountPoints.append(url.toString() + " " +
647 _mountPointsTable->item(iRow, 2)->text()
648 + " " + _mountPointsTable->item(iRow, 3)->text()
649 + " " + _mountPointsTable->item(iRow, 4)->text()
650 + " " + _mountPointsTable->item(iRow, 5)->text());
651 }
652 settings.setValue("mountPoints", mountPoints);
653}
654
655// All get slots terminated
656////////////////////////////////////////////////////////////////////////////
657void bncWindow::slotGetThreadErrors() {
658 slotMessage("All Get Threads Terminated");
659 ((bncApp*)qApp)->slotMessage("All Get Threads Terminated");
660 _actAddMountPoints->setEnabled(true);
661 _actGetData->setEnabled(true);
662}
663
664// Retrieve Data
665////////////////////////////////////////////////////////////////////////////
666void bncWindow::slotGetData() {
667 slotSaveOptions();
668
669 _actAddMountPoints->setEnabled(false);
670 _actDeleteMountPoints->setEnabled(false);
671 _actGetData->setEnabled(false);
672 _actStop->setEnabled(true);
673
674 _caster = new bncCaster(_outFileLineEdit->text(),
675 _outPortLineEdit->text().toInt());
676
677 ((bncApp*)qApp)->setPort(_outEphPortLineEdit->text().toInt());
678 ((bncApp*)qApp)->setPortCorr(_corrPortLineEdit->text().toInt());
679
680 connect(_caster, SIGNAL(getThreadErrors()),
681 this, SLOT(slotGetThreadErrors()));
682
683 connect(_caster, SIGNAL(newMessage(QByteArray)),
684 this, SLOT(slotMessage(QByteArray)));
685 connect(_caster, SIGNAL(newMessage(QByteArray)),
686 (bncApp*)qApp, SLOT(slotMessage(QByteArray)));
687 connect((bncApp*)qApp, SIGNAL(newMessage(QByteArray)),
688 this, SLOT(slotMessage(QByteArray)));
689
690 slotMessage("============ Start BNC ============");
691 ((bncApp*)qApp)->slotMessage("============ Start BNC ============");
692
693 for (int iRow = 0; iRow < _mountPointsTable->rowCount(); iRow++) {
694 QUrl url( "//" + _mountPointsTable->item(iRow, 0)->text() +
695 "@" + _mountPointsTable->item(iRow, 1)->text() );
696
697 QByteArray format = _mountPointsTable->item(iRow, 2)->text().toAscii();
698
699 QByteArray latitude = _mountPointsTable->item(iRow, 3)->text().toAscii();
700 QByteArray longitude = _mountPointsTable->item(iRow, 4)->text().toAscii();
701 QByteArray nmea = _mountPointsTable->item(iRow, 5)->text().toAscii();
702
703 bncGetThread* getThread = new bncGetThread(url, format, latitude, longitude, nmea, iRow);
704
705 connect(getThread, SIGNAL(newMessage(QByteArray)),
706 this, SLOT(slotMessage(QByteArray)));
707 connect(getThread, SIGNAL(newMessage(QByteArray)),
708 (bncApp*)qApp, SLOT(slotMessage(QByteArray)));
709
710 connect(getThread, SIGNAL(newBytes(QByteArray, double)),
711 (bncTableItem*) _mountPointsTable->item(iRow, 6),
712 SLOT(slotNewBytes(QByteArray, double)));
713
714 _caster->addGetThread(getThread);
715
716 getThread->start();
717 }
718}
719
720// Retrieve Data
721////////////////////////////////////////////////////////////////////////////
722void bncWindow::slotStop() {
723 int iRet = QMessageBox::question(this, "Stop", "Stop retrieving data?",
724 QMessageBox::Yes, QMessageBox::No,
725 QMessageBox::NoButton);
726 if (iRet == QMessageBox::Yes) {
727 delete _caster; _caster = 0;
728 _actGetData->setEnabled(true);
729 _actStop->setEnabled(false);
730 _actAddMountPoints->setEnabled(true);
731 }
732}
733
734// Close Application gracefully
735////////////////////////////////////////////////////////////////////////////
736void bncWindow::closeEvent(QCloseEvent* event) {
737
738 int iRet = QMessageBox::question(this, "Close", "Save Options?",
739 QMessageBox::Yes, QMessageBox::No,
740 QMessageBox::Cancel);
741
742 if (iRet == QMessageBox::Cancel) {
743 event->ignore();
744 return;
745 }
746 else if (iRet == QMessageBox::Yes) {
747 slotSaveOptions();
748 }
749
750 QMainWindow::closeEvent(event);
751}
752
753// User changed the selection of mountPoints
754////////////////////////////////////////////////////////////////////////////
755void bncWindow::slotSelectionChanged() {
756 if (_mountPointsTable->selectedItems().isEmpty()) {
757 _actDeleteMountPoints->setEnabled(false);
758 }
759 else {
760 _actDeleteMountPoints->setEnabled(true);
761 }
762}
763
764// Display Program Messages
765////////////////////////////////////////////////////////////////////////////
766void bncWindow::slotMessage(const QByteArray msg) {
767
768 const int maxBufferSize = 10000;
769
770 QString txt = _log->toPlainText() + "\n" +
771 QDateTime::currentDateTime().toUTC().toString("yy-MM-dd hh:mm:ss ") + msg;
772 _log->clear();
773 _log->append(txt.right(maxBufferSize));
774}
775
776// About Message
777////////////////////////////////////////////////////////////////////////////
778void bncWindow::slotAbout() {
779 new bncAboutDlg(0);
780}
781
782//Flowchart
783////////////////////////////////////////////////////////////////////////////
784void bncWindow::slotFlowchart() {
785 new bncFlowchartDlg(0);
786}
787
788// Help Window
789////////////////////////////////////////////////////////////////////////////
790void bncWindow::slotHelp() {
791 QUrl url;
792 url.setPath(":bnchelp.html");
793 new bncHlpDlg(0, url);
794}
795
796// Select Fonts
797////////////////////////////////////////////////////////////////////////////
798void bncWindow::slotFontSel() {
799 bool ok;
800 QFont newFont = QFontDialog::getFont(&ok, this->font(), this);
801 if (ok) {
802 QSettings settings;
803 settings.setValue("font", newFont.toString());
804 QApplication::setFont(newFont);
805 int ww = QFontMetrics(newFont).width('w');
806 setMinimumSize(60*ww, 80*ww);
807 resize(60*ww, 80*ww);
808 }
809}
810
811// Whats This Help
812void bncWindow::slotWhatsThis() {
813QWhatsThis::enterWhatsThisMode();
814}
815
816void bncWindow::CreateMenu() {
817 // Create Menus
818 // ------------
819 _menuFile = menuBar()->addMenu(tr("&File"));
820 _menuFile->addAction(_actFontSel);
821 _menuFile->addSeparator();
822 _menuFile->addAction(_actSaveOpt);
823 _menuFile->addSeparator();
824 _menuFile->addAction(_actQuit);
825
826 _menuHlp = menuBar()->addMenu(tr("&Help"));
827 _menuHlp->addAction(_actHelp);
828 _menuHlp->addAction(_actFlowchart);
829 _menuHlp->addAction(_actAbout);
830}
831
832void bncWindow::AddToolbar() {
833 // Tool (Command) Bar
834 // ------------------
835 QToolBar* toolBar = new QToolBar;
836 addToolBar(Qt::BottomToolBarArea, toolBar);
837 toolBar->setMovable(false);
838 toolBar->addAction(_actAddMountPoints);
839 toolBar->addAction(_actDeleteMountPoints);
840 toolBar->addAction(_actGetData);
841 toolBar->addAction(_actStop);
842 toolBar->addWidget(new QLabel(" "));
843 toolBar->addAction(_actwhatsthis);
844}
845
846bncAboutDlg::bncAboutDlg(QWidget* parent) :
847 QDialog(parent) {
848
849 QTextBrowser* tb = new QTextBrowser;
850 QUrl url; url.setPath(":bncabout.html");
851 tb->setSource(url);
852 tb->setReadOnly(true);
853
854 int ww = QFontMetrics(font()).width('w');
855 QPushButton* _closeButton = new QPushButton("Close");
856 _closeButton->setMaximumWidth(10*ww);
857 connect(_closeButton, SIGNAL(clicked()), this, SLOT(close()));
858
859 QGridLayout* dlgLayout = new QGridLayout();
860 QLabel* img = new QLabel();
861 img->setPixmap(QPixmap(":ntrip-logo.png"));
862 dlgLayout->addWidget(img, 0,0);
863 dlgLayout->addWidget(new QLabel("BKG Ntrip Client (BNC) Version 1.6"), 0,1);
864 dlgLayout->addWidget(tb,1,0,1,2);
865 dlgLayout->addWidget(_closeButton,2,1,Qt::AlignRight);
866
867 setLayout(dlgLayout);
868 resize(60*ww, 60*ww);
869 show();
870}
871
872bncAboutDlg::~bncAboutDlg() {
873};
874
875bncFlowchartDlg::bncFlowchartDlg(QWidget* parent) :
876 QDialog(parent) {
877
878 int ww = QFontMetrics(font()).width('w');
879 QPushButton* _closeButton = new QPushButton("Close");
880 _closeButton->setMaximumWidth(10*ww);
881 connect(_closeButton, SIGNAL(clicked()), this, SLOT(close()));
882
883 QGridLayout* dlgLayout = new QGridLayout();
884 QLabel* img = new QLabel();
885 img->setPixmap(QPixmap(":bncflowchart.png"));
886 dlgLayout->addWidget(img, 0,0);
887 dlgLayout->addWidget(_closeButton,1,0,Qt::AlignLeft);
888
889 setLayout(dlgLayout);
890 show();
891}
892
893bncFlowchartDlg::~bncFlowchartDlg() {
894};
895
Note: See TracBrowser for help on using the repository browser.