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

Last change on this file since 1035 was 1035, 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,3);
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,4,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);
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->setColumnMinimumWidth(3,40*ww);
451 oLayout->addWidget(new QLabel("Directory"), 0, 0);
452 oLayout->addWidget(_rnxPathLineEdit, 0, 1,1,3);
453 oLayout->addWidget(new QLabel("Interval"), 1, 0);
454 oLayout->addWidget(_rnxIntrComboBox, 1, 1);
455 oLayout->addWidget(new QLabel("Sampling"), 1, 2, Qt::AlignRight);
456 oLayout->addWidget(_rnxSamplSpinBox, 1, 3, Qt::AlignLeft);
457 oLayout->addWidget(new QLabel("Skeleton extension"), 2, 0);
458 oLayout->addWidget(_rnxSkelLineEdit, 2, 1);
459 oLayout->addWidget(new QLabel("Script (full path)"), 3, 0);
460 oLayout->addWidget(_rnxScrpLineEdit, 3, 1, 1, 3);
461 oLayout->addWidget(new QLabel("Version 3"), 4, 0);
462 oLayout->addWidget(_rnxV3CheckBox, 4, 1);
463 oLayout->addWidget(new QLabel("Saving RINEX observation files."),5,0,1,4, Qt::AlignLeft);
464 ogroup->setLayout(oLayout);
465
466 QGridLayout* cLayout = new QGridLayout;
467 cLayout->setColumnMinimumWidth(0,12*ww);
468 cLayout->addWidget(new QLabel("Directory"), 0, 0);
469 cLayout->addWidget(_corrPathLineEdit, 0, 1);
470 cLayout->addWidget(new QLabel("Interval"), 1, 0);
471 cLayout->addWidget(_corrIntrComboBox, 1, 1);
472 cLayout->addWidget(new QLabel("Port"), 2, 0);
473 cLayout->addWidget(_corrPortLineEdit, 2, 1);
474 cLayout->addWidget(new QLabel("Wait for full epoch"), 3, 0);
475 cLayout->addWidget(_corrTimeSpinBox, 3, 1);
476 cLayout->addWidget(new QLabel("Latency log"), 4, 0);
477 cLayout->addWidget(_corrLateCheckBox, 4, 1);
478 cLayout->addWidget(new QLabel("Saving Broadcast Ephemeris correction files and correction output through IP port."),5,0,1,2,Qt::AlignLeft);
479 cgroup->setLayout(cLayout);
480
481 QVBoxLayout* mLayout = new QVBoxLayout;
482 mLayout->addWidget(aogroup);
483 mLayout->addWidget(_mountPointsTable);
484 mLayout->addWidget(_log);
485
486 _canvas->setLayout(mLayout);
487}
488
489// Destructor
490////////////////////////////////////////////////////////////////////////////
491bncWindow::~bncWindow() {
492 delete _caster;
493}
494
495// Retrieve Table
496////////////////////////////////////////////////////////////////////////////
497void bncWindow::slotAddMountPoints() {
498
499 QSettings settings;
500 QString proxyHost = settings.value("proxyHost").toString();
501 int proxyPort = settings.value("proxyPort").toInt();
502 if (proxyHost != _proxyHostLineEdit->text() ||
503 proxyPort != _proxyPortLineEdit->text().toInt()) {
504 int iRet = QMessageBox::question(this, "Question", "Proxy options "
505 "changed. Use the new ones?",
506 QMessageBox::Yes, QMessageBox::No,
507 QMessageBox::NoButton);
508 if (iRet == QMessageBox::Yes) {
509 settings.setValue("proxyHost", _proxyHostLineEdit->text());
510 settings.setValue("proxyPort", _proxyPortLineEdit->text());
511 }
512 }
513
514 bncTableDlg* dlg = new bncTableDlg(this);
515 dlg->move(this->pos().x()+50, this->pos().y()+50);
516 connect(dlg, SIGNAL(newMountPoints(QStringList*)),
517 this, SLOT(slotNewMountPoints(QStringList*)));
518 dlg->exec();
519 delete dlg;
520
521}
522
523// Delete Selected Mount Points
524////////////////////////////////////////////////////////////////////////////
525void bncWindow::slotDeleteMountPoints() {
526
527 int nRows = _mountPointsTable->rowCount();
528 bool flg[nRows];
529 for (int iRow = 0; iRow < nRows; iRow++) {
530 if (_mountPointsTable->isItemSelected(_mountPointsTable->item(iRow,1))) {
531 flg[iRow] = true;
532 }
533 else {
534 flg[iRow] = false;
535 }
536 }
537 for (int iRow = nRows-1; iRow >= 0; iRow--) {
538 if (flg[iRow]) {
539 _mountPointsTable->removeRow(iRow);
540 }
541 }
542 _actDeleteMountPoints->setEnabled(false);
543
544 if (_mountPointsTable->rowCount() == 0) {
545 _actGetData->setEnabled(false);
546 }
547}
548
549// New Mount Points Selected
550////////////////////////////////////////////////////////////////////////////
551void bncWindow::slotNewMountPoints(QStringList* mountPoints) {
552 int iRow = 0;
553 QListIterator<QString> it(*mountPoints);
554 while (it.hasNext()) {
555 QStringList hlp = it.next().split(" ");
556 QUrl url(hlp[0]);
557 QString fullPath = url.host() + QString(":%1").arg(url.port()) + url.path();
558 QString format(hlp[1]); QString latitude(hlp[2]); QString longitude(hlp[3]);
559 QString nmea(hlp[4]);
560
561 _mountPointsTable->insertRow(iRow);
562
563 QTableWidgetItem* it;
564 it = new QTableWidgetItem(url.userInfo());
565 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
566 _mountPointsTable->setItem(iRow, 0, it);
567
568 it = new QTableWidgetItem(fullPath);
569 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
570 _mountPointsTable->setItem(iRow, 1, it);
571
572 it = new QTableWidgetItem(format);
573 _mountPointsTable->setItem(iRow, 2, it);
574
575 if (nmea == "yes") {
576 it = new QTableWidgetItem(latitude);
577 _mountPointsTable->setItem(iRow, 3, it);
578 it = new QTableWidgetItem(longitude);
579 _mountPointsTable->setItem(iRow, 4, it);
580 } else {
581 it = new QTableWidgetItem(latitude);
582 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
583 _mountPointsTable->setItem(iRow, 3, it);
584 it = new QTableWidgetItem(longitude);
585 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
586 _mountPointsTable->setItem(iRow, 4, it);
587 }
588
589 it = new QTableWidgetItem(nmea);
590 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
591 _mountPointsTable->setItem(iRow, 5, it);
592
593 bncTableItem* bncIt = new bncTableItem();
594 _mountPointsTable->setItem(iRow, 6, bncIt);
595
596 iRow++;
597 }
598 _mountPointsTable->hideColumn(0);
599 _mountPointsTable->sortItems(1);
600 if (mountPoints->count() > 0) {
601 _actGetData->setEnabled(true);
602 }
603 delete mountPoints;
604}
605
606// Save Options
607////////////////////////////////////////////////////////////////////////////
608void bncWindow::slotSaveOptions() {
609 QSettings settings;
610 settings.setValue("proxyHost", _proxyHostLineEdit->text());
611 settings.setValue("proxyPort", _proxyPortLineEdit->text());
612 settings.setValue("waitTime", _waitTimeSpinBox->value());
613 settings.setValue("obsRate", _obsRateComboBox->currentText());
614 settings.setValue("adviseFail", _adviseFailSpinBox->value());
615 settings.setValue("adviseReco", _adviseRecoSpinBox->value());
616 settings.setValue("makePause", _makePauseCheckBox->checkState());
617 settings.setValue("outFile", _outFileLineEdit->text());
618 settings.setValue("perfIntr", _perfIntrComboBox->currentText());
619 settings.setValue("outPort", _outPortLineEdit->text());
620 settings.setValue("outEphPort", _outEphPortLineEdit->text());
621 settings.setValue("corrPort", _corrPortLineEdit->text());
622 settings.setValue("corrTime", _corrTimeSpinBox->value());
623 settings.setValue("rnxPath", _rnxPathLineEdit->text());
624 settings.setValue("ephPath", _ephPathLineEdit->text());
625 settings.setValue("corrPath", _corrPathLineEdit->text());
626 settings.setValue("rnxScript", _rnxScrpLineEdit->text());
627 settings.setValue("rnxIntr", _rnxIntrComboBox->currentText());
628 settings.setValue("ephIntr", _ephIntrComboBox->currentText());
629 settings.setValue("corrIntr", _corrIntrComboBox->currentText());
630 settings.setValue("rnxSampl", _rnxSamplSpinBox->value());
631 settings.setValue("binSampl", _binSamplSpinBox->value());
632 settings.setValue("rnxSkel", _rnxSkelLineEdit->text());
633 settings.setValue("rnxAppend", _rnxAppendCheckBox->checkState());
634 settings.setValue("corrLate", _corrLateCheckBox->checkState());
635 settings.setValue("rnxV3", _rnxV3CheckBox->checkState());
636 settings.setValue("ephV3", _ephV3CheckBox->checkState());
637 settings.setValue("logFile", _logFileLineEdit->text());
638 settings.setValue("adviseScript",_adviseScriptLineEdit->text());
639 settings.setValue("messTypes", _messTypesLineEdit->text());
640
641QStringList mountPoints;
642
643 for (int iRow = 0; iRow < _mountPointsTable->rowCount(); iRow++) {
644 QUrl url( "//" + _mountPointsTable->item(iRow, 0)->text() +
645 "@" + _mountPointsTable->item(iRow, 1)->text() );
646
647 mountPoints.append(url.toString() + " " +
648 _mountPointsTable->item(iRow, 2)->text()
649 + " " + _mountPointsTable->item(iRow, 3)->text()
650 + " " + _mountPointsTable->item(iRow, 4)->text()
651 + " " + _mountPointsTable->item(iRow, 5)->text());
652 }
653 settings.setValue("mountPoints", mountPoints);
654}
655
656// All get slots terminated
657////////////////////////////////////////////////////////////////////////////
658void bncWindow::slotGetThreadErrors() {
659 slotMessage("All Get Threads Terminated");
660 ((bncApp*)qApp)->slotMessage("All Get Threads Terminated");
661 _actAddMountPoints->setEnabled(true);
662 _actGetData->setEnabled(true);
663}
664
665// Retrieve Data
666////////////////////////////////////////////////////////////////////////////
667void bncWindow::slotGetData() {
668 slotSaveOptions();
669
670 _actAddMountPoints->setEnabled(false);
671 _actDeleteMountPoints->setEnabled(false);
672 _actGetData->setEnabled(false);
673 _actStop->setEnabled(true);
674
675 _caster = new bncCaster(_outFileLineEdit->text(),
676 _outPortLineEdit->text().toInt());
677
678 ((bncApp*)qApp)->setPort(_outEphPortLineEdit->text().toInt());
679 ((bncApp*)qApp)->setPortCorr(_corrPortLineEdit->text().toInt());
680
681 connect(_caster, SIGNAL(getThreadErrors()),
682 this, SLOT(slotGetThreadErrors()));
683
684 connect(_caster, SIGNAL(newMessage(QByteArray)),
685 this, SLOT(slotMessage(QByteArray)));
686 connect(_caster, SIGNAL(newMessage(QByteArray)),
687 (bncApp*)qApp, SLOT(slotMessage(QByteArray)));
688 connect((bncApp*)qApp, SIGNAL(newMessage(QByteArray)),
689 this, SLOT(slotMessage(QByteArray)));
690
691 slotMessage("============ Start BNC ============");
692 ((bncApp*)qApp)->slotMessage("============ Start BNC ============");
693
694 for (int iRow = 0; iRow < _mountPointsTable->rowCount(); iRow++) {
695 QUrl url( "//" + _mountPointsTable->item(iRow, 0)->text() +
696 "@" + _mountPointsTable->item(iRow, 1)->text() );
697
698 QByteArray format = _mountPointsTable->item(iRow, 2)->text().toAscii();
699
700 QByteArray latitude = _mountPointsTable->item(iRow, 3)->text().toAscii();
701 QByteArray longitude = _mountPointsTable->item(iRow, 4)->text().toAscii();
702 QByteArray nmea = _mountPointsTable->item(iRow, 5)->text().toAscii();
703
704 bncGetThread* getThread = new bncGetThread(url, format, latitude, longitude, nmea, iRow);
705
706 connect(getThread, SIGNAL(newMessage(QByteArray)),
707 this, SLOT(slotMessage(QByteArray)));
708 connect(getThread, SIGNAL(newMessage(QByteArray)),
709 (bncApp*)qApp, SLOT(slotMessage(QByteArray)));
710
711 connect(getThread, SIGNAL(newBytes(QByteArray, double)),
712 (bncTableItem*) _mountPointsTable->item(iRow, 6),
713 SLOT(slotNewBytes(QByteArray, double)));
714
715 _caster->addGetThread(getThread);
716
717 getThread->start();
718 }
719}
720
721// Retrieve Data
722////////////////////////////////////////////////////////////////////////////
723void bncWindow::slotStop() {
724 int iRet = QMessageBox::question(this, "Stop", "Stop retrieving data?",
725 QMessageBox::Yes, QMessageBox::No,
726 QMessageBox::NoButton);
727 if (iRet == QMessageBox::Yes) {
728 delete _caster; _caster = 0;
729 _actGetData->setEnabled(true);
730 _actStop->setEnabled(false);
731 _actAddMountPoints->setEnabled(true);
732 }
733}
734
735// Close Application gracefully
736////////////////////////////////////////////////////////////////////////////
737void bncWindow::closeEvent(QCloseEvent* event) {
738
739 int iRet = QMessageBox::question(this, "Close", "Save Options?",
740 QMessageBox::Yes, QMessageBox::No,
741 QMessageBox::Cancel);
742
743 if (iRet == QMessageBox::Cancel) {
744 event->ignore();
745 return;
746 }
747 else if (iRet == QMessageBox::Yes) {
748 slotSaveOptions();
749 }
750
751 QMainWindow::closeEvent(event);
752}
753
754// User changed the selection of mountPoints
755////////////////////////////////////////////////////////////////////////////
756void bncWindow::slotSelectionChanged() {
757 if (_mountPointsTable->selectedItems().isEmpty()) {
758 _actDeleteMountPoints->setEnabled(false);
759 }
760 else {
761 _actDeleteMountPoints->setEnabled(true);
762 }
763}
764
765// Display Program Messages
766////////////////////////////////////////////////////////////////////////////
767void bncWindow::slotMessage(const QByteArray msg) {
768
769 const int maxBufferSize = 10000;
770
771 QString txt = _log->toPlainText() + "\n" +
772 QDateTime::currentDateTime().toUTC().toString("yy-MM-dd hh:mm:ss ") + msg;
773 _log->clear();
774 _log->append(txt.right(maxBufferSize));
775}
776
777// About Message
778////////////////////////////////////////////////////////////////////////////
779void bncWindow::slotAbout() {
780 new bncAboutDlg(0);
781}
782
783//Flowchart
784////////////////////////////////////////////////////////////////////////////
785void bncWindow::slotFlowchart() {
786 new bncFlowchartDlg(0);
787}
788
789// Help Window
790////////////////////////////////////////////////////////////////////////////
791void bncWindow::slotHelp() {
792 QUrl url;
793 url.setPath(":bnchelp.html");
794 new bncHlpDlg(0, url);
795}
796
797// Select Fonts
798////////////////////////////////////////////////////////////////////////////
799void bncWindow::slotFontSel() {
800 bool ok;
801 QFont newFont = QFontDialog::getFont(&ok, this->font(), this);
802 if (ok) {
803 QSettings settings;
804 settings.setValue("font", newFont.toString());
805 QApplication::setFont(newFont);
806 int ww = QFontMetrics(newFont).width('w');
807 setMinimumSize(60*ww, 80*ww);
808 resize(60*ww, 80*ww);
809 }
810}
811
812// Whats This Help
813void bncWindow::slotWhatsThis() {
814QWhatsThis::enterWhatsThisMode();
815}
816
817void bncWindow::CreateMenu() {
818 // Create Menus
819 // ------------
820 _menuFile = menuBar()->addMenu(tr("&File"));
821 _menuFile->addAction(_actFontSel);
822 _menuFile->addSeparator();
823 _menuFile->addAction(_actSaveOpt);
824 _menuFile->addSeparator();
825 _menuFile->addAction(_actQuit);
826
827 _menuHlp = menuBar()->addMenu(tr("&Help"));
828 _menuHlp->addAction(_actHelp);
829 _menuHlp->addAction(_actFlowchart);
830 _menuHlp->addAction(_actAbout);
831}
832
833void bncWindow::AddToolbar() {
834 // Tool (Command) Bar
835 // ------------------
836 QToolBar* toolBar = new QToolBar;
837 addToolBar(Qt::BottomToolBarArea, toolBar);
838 toolBar->setMovable(false);
839 toolBar->addAction(_actAddMountPoints);
840 toolBar->addAction(_actDeleteMountPoints);
841 toolBar->addAction(_actGetData);
842 toolBar->addAction(_actStop);
843 toolBar->addWidget(new QLabel(" "));
844 toolBar->addAction(_actwhatsthis);
845}
846
847bncAboutDlg::bncAboutDlg(QWidget* parent) :
848 QDialog(parent) {
849
850 QTextBrowser* tb = new QTextBrowser;
851 QUrl url; url.setPath(":bncabout.html");
852 tb->setSource(url);
853 tb->setReadOnly(true);
854
855 int ww = QFontMetrics(font()).width('w');
856 QPushButton* _closeButton = new QPushButton("Close");
857 _closeButton->setMaximumWidth(10*ww);
858 connect(_closeButton, SIGNAL(clicked()), this, SLOT(close()));
859
860 QGridLayout* dlgLayout = new QGridLayout();
861 QLabel* img = new QLabel();
862 img->setPixmap(QPixmap(":ntrip-logo.png"));
863 dlgLayout->addWidget(img, 0,0);
864 dlgLayout->addWidget(new QLabel("BKG NTRIP Client (BNC) Version 1.6"), 0,1);
865 dlgLayout->addWidget(tb,1,0,1,2);
866 dlgLayout->addWidget(_closeButton,2,1,Qt::AlignRight);
867
868 setLayout(dlgLayout);
869 resize(60*ww, 60*ww);
870 show();
871}
872
873bncAboutDlg::~bncAboutDlg() {
874};
875
876bncFlowchartDlg::bncFlowchartDlg(QWidget* parent) :
877 QDialog(parent) {
878
879 int ww = QFontMetrics(font()).width('w');
880 QPushButton* _closeButton = new QPushButton("Close");
881 _closeButton->setMaximumWidth(10*ww);
882 connect(_closeButton, SIGNAL(clicked()), this, SLOT(close()));
883
884 QGridLayout* dlgLayout = new QGridLayout();
885 QLabel* img = new QLabel();
886 img->setPixmap(QPixmap(":bncflowchart.png"));
887 dlgLayout->addWidget(img, 0,0);
888 dlgLayout->addWidget(_closeButton,1,0,Qt::AlignLeft);
889
890 setLayout(dlgLayout);
891 show();
892}
893
894bncFlowchartDlg::~bncFlowchartDlg() {
895};
896
Note: See TracBrowser for help on using the repository browser.