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

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

* empty log message *

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