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

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

* empty log message *

File size: 32.6 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 int ww = QFontMetrics(this->font()).width('w');
57
58 static const QStringList labels = QString("account,mountpoint,decoder,lat,long,nmea,bytes").split(",");
59
60 setMinimumSize(77*ww, 65*ww);
61
62 setWindowTitle(tr("BKG Ntrip Client (BNC) Version 1.5"));
63
64 // Create Actions
65 // --------------
66 _actHelp = new QAction(tr("&Help Contents"),this);
67 connect(_actHelp, SIGNAL(triggered()), SLOT(slotHelp()));
68
69 _actAbout = new QAction(tr("&About BNC"),this);
70 connect(_actAbout, SIGNAL(triggered()), SLOT(slotAbout()));
71
72 _actFontSel = new QAction(tr("Select &Font"),this);
73 connect(_actFontSel, SIGNAL(triggered()), SLOT(slotFontSel()));
74
75 _actSaveOpt = new QAction(tr("&Save Options"),this);
76 connect(_actSaveOpt, SIGNAL(triggered()), SLOT(slotSaveOptions()));
77
78 _actQuit = new QAction(tr("&Quit"),this);
79 connect(_actQuit, SIGNAL(triggered()), SLOT(close()));
80
81 _actAddMountPoints = new QAction(tr("Add &Mountpoints"),this);
82 connect(_actAddMountPoints, SIGNAL(triggered()), SLOT(slotAddMountPoints()));
83
84 _actDeleteMountPoints = new QAction(tr("&Delete Mountpoints"),this);
85 connect(_actDeleteMountPoints, SIGNAL(triggered()), SLOT(slotDeleteMountPoints()));
86 _actDeleteMountPoints->setEnabled(false);
87
88 _actGetData = new QAction(tr("Sta&rt"),this);
89 connect(_actGetData, SIGNAL(triggered()), SLOT(slotGetData()));
90
91 _actStop = new QAction(tr("Sto&p"),this);
92 connect(_actStop, SIGNAL(triggered()), SLOT(slotStop()));
93 _actStop->setEnabled(false);
94
95 _actwhatsthis= new QAction(tr("Help=Shift+F1"),this);
96 connect(_actwhatsthis, SIGNAL(triggered()), SLOT(slotWhatsThis()));
97
98 // Create Menus
99 // ------------
100 _menuFile = menuBar()->addMenu(tr("&File"));
101 _menuFile->addAction(_actFontSel);
102 _menuFile->addSeparator();
103 _menuFile->addAction(_actSaveOpt);
104 _menuFile->addSeparator();
105 _menuFile->addAction(_actQuit);
106
107 _menuHlp = menuBar()->addMenu(tr("&Help"));
108 _menuHlp->addAction(_actHelp);
109 _menuHlp->addAction(_actAbout);
110
111 // Tool (Command) Bar
112 // ------------------
113 QToolBar* toolBar = new QToolBar;
114 addToolBar(Qt::BottomToolBarArea, toolBar);
115 toolBar->setMovable(false);
116 toolBar->addAction(_actAddMountPoints);
117 toolBar->addAction(_actDeleteMountPoints);
118 toolBar->addAction(_actGetData);
119 toolBar->addAction(_actStop);
120 toolBar->addWidget(new QLabel(" "));
121 toolBar->addAction(_actwhatsthis);
122
123 // Canvas with Editable Fields
124 // ---------------------------
125 _canvas = new QWidget;
126 setCentralWidget(_canvas);
127
128 QGridLayout* layout = new QGridLayout;
129 _canvas->setLayout(layout);
130
131 QSettings settings;
132 _proxyHostLineEdit = new QLineEdit(settings.value("proxyHost").toString());
133 _proxyHostLineEdit->setMaximumWidth(12*ww);
134 _proxyHostLineEdit->setWhatsThis(tr("<p>You may want to run BNC in a Local Area Network (LAN). LANs are often protected by a proxy server. Enter your proxy server host IP name or number and port number in case one is operated in front of BNC. If you don't know the IP and port of your proxy server, check out the proxy server settings of your Internet browser or ask your network administrator.</p><p>Note that IP streaming may generally be denied in a LAN. In such a case you need to ask your network administrator for an appropriate modification of his security policy or for the installation of a TCP relay to involved NTRIP broadcasters. If that doesn't work out, run BNC outside your LAN on a host that is connected to the Internet through an Internet Service Provider (ISP).</p><p>Default values for 'Proxy host' and 'Proxy port' are empty option fields, assuming that no proxy server is operated in front of BNC.</p>"));
135 _proxyPortLineEdit = new QLineEdit(settings.value("proxyPort").toString());
136 _proxyPortLineEdit->setMaximumWidth(9*ww);
137 _proxyPortLineEdit->setWhatsThis(tr("<p>You may want to run BNC in a Local Area Network (LAN). LANs are often protected by a proxy server. Enter your proxy server host IP name or number and port number in case one is operated in front of BNC. If you don't know the IP and port of your proxy server, check out the proxy server settings of your Internet browser or ask your network administrator.</p><p>Note that IP streaming may generally be denied in a LAN. In such a case you need to ask your network administrator for an appropriate modification of his security policy or for the installation of a TCP relay to involved NTRIP broadcasters. If that doesn't work out, run BNC outside your LAN on a host that is connected to the Internet through an Internet Service Provider (ISP).</p><p>Default values for 'Proxy host' and 'Proxy port' are empty option fields, assuming that no proxy server is operated in front of BNC.</p>"));
138 _waitTimeSpinBox = new QSpinBox();
139 _waitTimeSpinBox->setMinimum(1);
140 _waitTimeSpinBox->setMaximum(30);
141 _waitTimeSpinBox->setSingleStep(1);
142 _waitTimeSpinBox->setSuffix(" sec");
143 _waitTimeSpinBox->setMaximumWidth(9*ww);
144 _waitTimeSpinBox->setValue(settings.value("waitTime").toInt());
145 _waitTimeSpinBox->setWhatsThis(tr("<p>BNC lets you output synchronized observations epoch by epoch. When feeding a real-time GNSS engine waiting for input, BNC ignores whatever is received later than 'Wait for full epoch' seconds. A value of 3 to 5 seconds could be an appropriate choice for that, depending on the latency of the incoming streams and the delay you can accept for your real-time GNSS product.</p><p>Note that 'Wait for full epoch' only concerns the ASCII output and the binary output and does not influence the RINEX file contents. Observations received later than 'Wait for full epoch' seconds will still be included in the RINEX files.</p>"));
146 _outFileLineEdit = new QLineEdit(settings.value("outFile").toString());
147 _outFileLineEdit->setWhatsThis(tr("<p>Enter the full path for a file to save synchronized observations in a plain ASCII format.</p><p>Note that the size of this file rapidly increases, mainly depending on the number of incoming streams. Thus, this output option is primarily meant for test and evaluation purposes. Devault value for 'ASCII output file' is an empty option field, meaning that no ASCII output file is created.</p>"));
148 _outPortLineEdit = new QLineEdit(settings.value("outPort").toString());
149 _outPortLineEdit->setMaximumWidth(9*ww);
150 _outPortLineEdit->setWhatsThis(tr("<p>BNC makes synchronized observations available in a binary format on your local host (IP 127.0.0.1) through an IP port. Enter an IP port number to activate this function.</p><p>Default is an empty option field, meaning that no binary output is generated.</p>"));
151 _rnxPathLineEdit = new QLineEdit(settings.value("rnxPath").toString());
152 _rnxPathLineEdit->setWhatsThis(tr("<p>Observations can be converted to RINEX. Enter a path for saving the RINEX files in a directory. If this directory does not exist, BNC will not create RINEX files.</p><p>Default value for 'RINEX directory' is an empty option field, meaning that streams are not converted to RINEX.</p>"));
153 _ephPathLineEdit = new QLineEdit(settings.value("ephPath").toString());
154 _ephPathLineEdit->setWhatsThis(tr("<p>Ephemeris data from RTCM Version 3.x streams can be converted to RINEX. Enter a path for saving the RINEX Navigation files in a directory. If this directory does not exist, BNC will not create RINEX Navigation files.</p><p>Default value for 'Ephemeris directory' is an empty option field, meaning that no RINEX Navigation files will be created.</p>"));
155
156 _rnxV3CheckBox = new QCheckBox();
157 _rnxV3CheckBox->setCheckState(Qt::CheckState(settings.value("rnxV3").toInt()));
158 _ephV3CheckBox = new QCheckBox();
159 _ephV3CheckBox->setCheckState(Qt::CheckState(settings.value("ephV3").toInt()));
160 _rnxScrpLineEdit = new QLineEdit(settings.value("rnxScript").toString());
161 _rnxScrpLineEdit->setWhatsThis(tr("<p>Whenever a RINEX file is saved, you may like to compress, copy or upload it immediately via FTP. For that you enter the full path of a script or batch file which is then called to carry out these operations. The full RINEX file path will be passed to the script as a command line parameter (%1 on Windows systems, $1 on Unix/Linux systems).</p><p>The triggering event for calling the script or batch file is the end of the 'RINEX file interval'. If that is superposed by a stream outage, the triggering event is the stream reconnect.</p><p>Default value for 'RINEX script' is an empty option field, meaning that no script or batch file shall be called."));
162 _rnxSkelLineEdit = new QLineEdit(settings.value("rnxSkel").toString());
163 _rnxSkelLineEdit->setMaximumWidth(5*ww);
164 _rnxSkelLineEdit->setWhatsThis(tr("<p>Whenever BNC starts generating RINEX 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, it may happen that public RINEX header skeleton files are not available, its contents is not up to date, or you need to have additional/optional records in the RINEX header.</p><p>For that BNC allows to introduce personal skeleton files that contain the header records you would like to see. You may 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 extension 'RINEX skeleton extension' is interpreted by BNC as a personal RINEX header skeleton file for the affected stream.</p><p>Default value for 'RINEX skeleton extension' is 'SKL', meaning that BNC will include the contents of probably existing files with this extension into the affected RINEX file headers.</p>"));
165 _rnxAppendCheckBox = new QCheckBox();
166 _rnxAppendCheckBox->setCheckState(Qt::CheckState(
167 settings.value("rnxAppend").toInt()));
168 _rnxAppendCheckBox->setWhatsThis(tr("<p>When starting BNC, new RINEX files are created by default. Probably existing files will be overwritten. However, it may be desirable to append observations to already existing RINEX files following a restart of BNC after an intentional 'Stop', a system crash or a crash of BNC. Hit 'Append files' to continue with already existing files and thus save what has been recorded so far.</p><p>Note that option 'Append files' also concerns the 'ASCII output file' and the 'Log' file.</p>"));
169 _rnxIntrComboBox = new QComboBox();
170 _rnxIntrComboBox->setWhatsThis(tr("<p>Select an interval for the RINEX file generation.</p><p>Default for 'RINEX file interval' is '15 min', meaning that a new RINEX file is generated every 15 minutes.</p>"));
171 _rnxIntrComboBox->setMaximumWidth(9*ww);
172 _rnxIntrComboBox->setEditable(false);
173 _rnxIntrComboBox->addItems(QString("1 min,2 min,5 min,10 min,15 min,30 min,1 hour,1 day").split(","));
174 int ii = _rnxIntrComboBox->findText(settings.value("rnxIntr").toString());
175 if (ii != -1) {
176 _rnxIntrComboBox->setCurrentIndex(ii);
177 }
178 _ephIntrComboBox = new QComboBox();
179 _ephIntrComboBox->setWhatsThis(tr("<p>Select an interval for the ephemeris file generation.</p><p>Default for 'Ephemeris file interval' is '1 day', meaning that a new Ephemeris file is generated every day.</p>"));
180 _ephIntrComboBox->setMaximumWidth(9*ww);
181 _ephIntrComboBox->setEditable(false);
182 _ephIntrComboBox->addItems(QString("15 min,1 hour,1 day").split(","));
183 int jj = _ephIntrComboBox->findText(settings.value("ephIntr").toString());
184 if (jj != -1) {
185 _ephIntrComboBox->setCurrentIndex(jj);
186 }
187 _rnxSamplSpinBox = new QSpinBox();
188 _rnxSamplSpinBox->setWhatsThis(tr("<p>Select the RINEX sample interval in seconds. Zero '0' stands for converting all incoming epochs to RINEX.</p><p>Default for RINEX 'Sampling' is '0'.</p>"));
189 _rnxSamplSpinBox->setMinimum(0);
190 _rnxSamplSpinBox->setMaximum(60);
191 _rnxSamplSpinBox->setSingleStep(5);
192 _rnxSamplSpinBox->setMaximumWidth(9*ww);
193 _rnxSamplSpinBox->setValue(settings.value("rnxSampl").toInt());
194 _rnxSamplSpinBox->setSuffix(" sec");
195 _logFileLineEdit = new QLineEdit(settings.value("logFile").toString());
196 _logFileLineEdit->setWhatsThis(tr("<p>BNC's run-time comments as shown in the 'Log' section can be saved in a file through entering the full path for a 'Log' file.</p><p>Default value for 'Log' is an empty option field, meaning that BNC's run-time comments are not saved in a file.</p>"));
197 _mountPointsTable = new QTableWidget(0,7);
198 _mountPointsTable->setWhatsThis(tr("<p>Streams selected for retrieval are listed in the 'Mountpoints' section. Button 'Add Mountpoints' opens a window that allows to select data streams from an NTRIP broadcaster by their mountpoints. To delete a stream, select it by mouse click and hit 'Delete Mountpoints'. For adding or deleting several streams simultaneously, highlight them using +Shift and +Ctrl.</p><p>BNC automatically selects one out of several internal decoders for a stream based on its 'format' and 'format-details' as given in the source-table. It may happen that you need to overrule the automated decoder selection. Therefore BNC allows to edit the decoder string (first double-click, then edit field 'decoder', then hit Enter). Decoder strings allowed to be introduced for stream decoding and conversion are 'RTCM_2.x', 'RTCM_3.x', and 'RTIGS'.</p><p> BNC allows to by-pass its stream decoding and conversion algorithms, leave whatever is received untouched and save it in daily named files. To activate this functionality you need to enter the decoder string 'ZERO'. <p>BNC allows to receive streams from virtual reference stations. For accessing these streams, an approximate rover position is required to be send in NMEA format to the NTRIP broadcaster. Whether or not a stream retrieval needs be initiated by BNC through sending an NMEA-GGA string is indicated in column 'nmea'. For those streams showing 'yes' in column 'nmea', an individual user-specific data stream is generated, usually by a network RTK software. This stream is tailored exactly to the latitude and longitude shown in the 'lat' and 'long' columns. You may change these values (first double-click, then edit fields 'lat' and/or 'long', then hit Enter) according to your needs. The position has to be introduced in northern latitude degrees (example for northern hemisphere: 52.436, example for southern hemisphere: -24.567) and eastern longitude degrees (example: 358.872 or -1.128). Editing the 'lat' and 'long' values is only possible for streams that show a 'yes' in column 'nmea'. The position must point to a location within the service area of the affected RTK network.</p>"));
199
200 _mountPointsTable->horizontalHeader()->resizeSection(1,25*ww);
201 _mountPointsTable->horizontalHeader()->resizeSection(2,9*ww);
202 _mountPointsTable->horizontalHeader()->resizeSection(3,7*ww);
203 _mountPointsTable->horizontalHeader()->resizeSection(4,7*ww);
204 _mountPointsTable->horizontalHeader()->resizeSection(5,5*ww);
205 _mountPointsTable->horizontalHeader()->setResizeMode(QHeaderView::Interactive);
206 _mountPointsTable->horizontalHeader()->setStretchLastSection(true);
207 _mountPointsTable->setHorizontalHeaderLabels(labels);
208 _mountPointsTable->setGridStyle(Qt::NoPen);
209 _mountPointsTable->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
210 _mountPointsTable->setSelectionMode(QAbstractItemView::ExtendedSelection);
211 _mountPointsTable->setSelectionBehavior(QAbstractItemView::SelectRows);
212 QListIterator<QString> it(settings.value("mountPoints").toStringList());
213 if (!it.hasNext()) {
214 _actGetData->setEnabled(false);
215 }
216 int iRow = 0;
217 while (it.hasNext()) {
218 QStringList hlp = it.next().split(" ");
219 if (hlp.size() < 5) continue;
220 _mountPointsTable->insertRow(iRow);
221
222 QUrl url(hlp[0]);
223
224 QString fullPath = url.host() + QString(":%1").arg(url.port()) + url.path();
225 QString format(hlp[1]); QString latitude(hlp[2]); QString longitude(hlp[3]);
226 QString nmea(hlp[4]);
227
228 QTableWidgetItem* it;
229 it = new QTableWidgetItem(url.userInfo());
230 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
231 _mountPointsTable->setItem(iRow, 0, it);
232
233 it = new QTableWidgetItem(fullPath);
234 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
235 _mountPointsTable->setItem(iRow, 1, it);
236
237 it = new QTableWidgetItem(format);
238 _mountPointsTable->setItem(iRow, 2, it);
239
240 if (nmea == "yes") {
241 it = new QTableWidgetItem(latitude);
242 _mountPointsTable->setItem(iRow, 3, it);
243 it = new QTableWidgetItem(longitude);
244 _mountPointsTable->setItem(iRow, 4, it);
245 } else {
246 it = new QTableWidgetItem(latitude);
247 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
248 _mountPointsTable->setItem(iRow, 3, it);
249 it = new QTableWidgetItem(longitude);
250 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
251 _mountPointsTable->setItem(iRow, 4, it);
252 }
253
254 it = new QTableWidgetItem(nmea);
255 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
256 _mountPointsTable->setItem(iRow, 5, it);
257
258 bncTableItem* bncIt = new bncTableItem();
259 bncIt->setFlags(bncIt->flags() & ~Qt::ItemIsEditable);
260 _mountPointsTable->setItem(iRow, 6, bncIt);
261
262 iRow++;
263 }
264 _mountPointsTable->hideColumn(0);
265 _mountPointsTable->sortItems(1);
266
267 connect(_mountPointsTable, SIGNAL(itemSelectionChanged()),
268 SLOT(slotSelectionChanged()));
269
270 _log = new QTextBrowser();
271 _log->setReadOnly(true);
272
273 _log->setWhatsThis(tr("BNC comments its activities in the 'Log' section. Information is given concerning reconnections to the NTRIP broadcaster(s) following outages, stream delays, stream conversion etc."));
274
275 layout->addWidget(new QLabel("Proxy host"), 0, 0, 1, 2);
276 layout->addWidget(_proxyHostLineEdit, 0, 2);
277 layout->addWidget(new QLabel("Proxy port"), 0, 3);
278 layout->addWidget(_proxyPortLineEdit, 0, 4);
279
280 layout->addWidget(new QLabel("Wait for full epoch"), 1, 0, 1, 2);
281 layout->addWidget(_waitTimeSpinBox, 1, 2);
282
283 layout->addWidget(new QLabel("ASCII output file (full path)"), 2, 0, 1, 2);
284 layout->addWidget(_outFileLineEdit, 2, 2, 1, 3);
285
286 layout->addWidget(new QLabel("Port for binary output"), 3, 0, 1, 2);
287 layout->addWidget(_outPortLineEdit, 3, 2);
288
289 layout->addWidget(new QLabel("RINEX directory"), 4, 0, 1, 2);
290 layout->addWidget(_rnxPathLineEdit, 4, 2);
291
292 layout->addWidget(new QLabel("RINEX v3"), 4, 3, 1, 2);
293 layout->addWidget(_rnxV3CheckBox, 4, 4);
294 _rnxV3CheckBox->setWhatsThis(tr("<p>Select the RINEX Observation file output format.</p><p>Default is RINEX Version 2.11 format. Output in RINEX Version 3 (RINEX v3) format is optional.</p>"));
295
296 layout->addWidget(new QLabel("RINEX script (full path)"), 5, 0, 1, 2);
297 layout->addWidget(_rnxScrpLineEdit, 5, 2, 1, 3);
298
299 layout->addWidget(new QLabel("File interval"), 6, 0, 1, 2);
300
301 QBoxLayout* bl = new QBoxLayout(QBoxLayout::LeftToRight);
302 bl->addWidget(_rnxIntrComboBox);
303 bl->addWidget(new QLabel("RINEX"));
304 bl->addWidget(_ephIntrComboBox);
305 bl->addWidget(new QLabel("Ephemeris"));
306 layout->addLayout(bl, 6, 2, 1, 1);
307
308 layout->addWidget(new QLabel("Sampling"), 6, 3);
309 layout->addWidget(_rnxSamplSpinBox, 6, 4);
310
311 layout->addWidget(new QLabel("RINEX skeleton extension"), 7, 0, 1, 2);
312 layout->addWidget(_rnxSkelLineEdit, 7, 2);
313
314 layout->addWidget(new QLabel("Append files"), 7, 3);
315 layout->addWidget(_rnxAppendCheckBox, 7, 4);
316
317 layout->addWidget(new QLabel("Ephemeris directory"), 8, 0, 1, 2);
318 layout->addWidget(_ephPathLineEdit, 8, 2);
319
320 layout->addWidget(new QLabel("RINEX v3"), 8, 3, 1, 2);
321 layout->addWidget(_ephV3CheckBox, 8, 4);
322 _ephV3CheckBox->setWhatsThis(tr("<p>Select the RINEX Ephemeris file output format.</p><p>Default is RINEX Version 2.11 format. Output in RINEX Version 3 (RINEX v3) format is optional.</p>"));
323
324 layout->addWidget(new QLabel("Mountpoints"), 9, 0, 1, 2);
325
326 layout->addWidget(_mountPointsTable, 10, 0, 1, 5);
327
328 layout->addWidget(new QLabel("Log (full path)"), 11, 0, 1, 2);
329 layout->addWidget(_logFileLineEdit, 11, 2, 1, 3);
330 layout->addWidget(_log, 12, 0, 1, 5);
331}
332
333// Destructor
334////////////////////////////////////////////////////////////////////////////
335bncWindow::~bncWindow() {
336}
337
338// Retrieve Table
339////////////////////////////////////////////////////////////////////////////
340void bncWindow::slotAddMountPoints() {
341
342 QSettings settings;
343 QString proxyHost = settings.value("proxyHost").toString();
344 int proxyPort = settings.value("proxyPort").toInt();
345 if (proxyHost != _proxyHostLineEdit->text() ||
346 proxyPort != _proxyPortLineEdit->text().toInt()) {
347 int iRet = QMessageBox::question(this, "Question", "Proxy options "
348 "changed. Use the new ones?",
349 QMessageBox::Yes, QMessageBox::No,
350 QMessageBox::NoButton);
351 if (iRet == QMessageBox::Yes) {
352 settings.setValue("proxyHost", _proxyHostLineEdit->text());
353 settings.setValue("proxyPort", _proxyPortLineEdit->text());
354 }
355 }
356
357 bncTableDlg* dlg = new bncTableDlg(this);
358 dlg->move(this->pos().x()+50, this->pos().y()+50);
359 connect(dlg, SIGNAL(newMountPoints(QStringList*)),
360 this, SLOT(slotNewMountPoints(QStringList*)));
361 dlg->exec();
362 delete dlg;
363
364}
365
366// Delete Selected Mount Points
367////////////////////////////////////////////////////////////////////////////
368void bncWindow::slotDeleteMountPoints() {
369
370 int nRows = _mountPointsTable->rowCount();
371 bool flg[nRows];
372 for (int iRow = 0; iRow < nRows; iRow++) {
373 if (_mountPointsTable->isItemSelected(_mountPointsTable->item(iRow,1))) {
374 flg[iRow] = true;
375 }
376 else {
377 flg[iRow] = false;
378 }
379 }
380 for (int iRow = nRows-1; iRow >= 0; iRow--) {
381 if (flg[iRow]) {
382 _mountPointsTable->removeRow(iRow);
383 }
384 }
385 _actDeleteMountPoints->setEnabled(false);
386
387 if (_mountPointsTable->rowCount() == 0) {
388 _actGetData->setEnabled(false);
389 }
390}
391
392// New Mount Points Selected
393////////////////////////////////////////////////////////////////////////////
394void bncWindow::slotNewMountPoints(QStringList* mountPoints) {
395 int iRow = 0;
396 QListIterator<QString> it(*mountPoints);
397 while (it.hasNext()) {
398 QStringList hlp = it.next().split(" ");
399 QUrl url(hlp[0]);
400 QString fullPath = url.host() + QString(":%1").arg(url.port()) + url.path();
401 QString format(hlp[1]); QString latitude(hlp[2]); QString longitude(hlp[3]);
402 QString nmea(hlp[4]);
403
404 _mountPointsTable->insertRow(iRow);
405
406 QTableWidgetItem* it;
407 it = new QTableWidgetItem(url.userInfo());
408 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
409 _mountPointsTable->setItem(iRow, 0, it);
410
411 it = new QTableWidgetItem(fullPath);
412 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
413 _mountPointsTable->setItem(iRow, 1, it);
414
415 it = new QTableWidgetItem(format);
416 _mountPointsTable->setItem(iRow, 2, it);
417
418 if (nmea == "yes") {
419 it = new QTableWidgetItem(latitude);
420 _mountPointsTable->setItem(iRow, 3, it);
421 it = new QTableWidgetItem(longitude);
422 _mountPointsTable->setItem(iRow, 4, it);
423 } else {
424 it = new QTableWidgetItem(latitude);
425 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
426 _mountPointsTable->setItem(iRow, 3, it);
427 it = new QTableWidgetItem(longitude);
428 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
429 _mountPointsTable->setItem(iRow, 4, it);
430 }
431
432 it = new QTableWidgetItem(nmea);
433 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
434 _mountPointsTable->setItem(iRow, 5, it);
435
436 bncTableItem* bncIt = new bncTableItem();
437 _mountPointsTable->setItem(iRow, 6, bncIt);
438
439 iRow++;
440 }
441 _mountPointsTable->hideColumn(0);
442 _mountPointsTable->sortItems(1);
443 if (mountPoints->count() > 0) {
444 _actGetData->setEnabled(true);
445 }
446 delete mountPoints;
447}
448
449// Save Options
450////////////////////////////////////////////////////////////////////////////
451void bncWindow::slotSaveOptions() {
452 QSettings settings;
453 settings.setValue("proxyHost", _proxyHostLineEdit->text());
454 settings.setValue("proxyPort", _proxyPortLineEdit->text());
455 settings.setValue("waitTime", _waitTimeSpinBox->value());
456 settings.setValue("outFile", _outFileLineEdit->text());
457 settings.setValue("outPort", _outPortLineEdit->text());
458 settings.setValue("rnxPath", _rnxPathLineEdit->text());
459 settings.setValue("ephPath", _ephPathLineEdit->text());
460 settings.setValue("rnxScript", _rnxScrpLineEdit->text());
461 settings.setValue("rnxIntr", _rnxIntrComboBox->currentText());
462 settings.setValue("ephIntr", _ephIntrComboBox->currentText());
463 settings.setValue("rnxSampl", _rnxSamplSpinBox->value());
464 settings.setValue("rnxSkel", _rnxSkelLineEdit->text());
465 settings.setValue("rnxAppend", _rnxAppendCheckBox->checkState());
466 settings.setValue("rnxV3", _rnxV3CheckBox->checkState());
467 settings.setValue("ephV3", _ephV3CheckBox->checkState());
468 settings.setValue("logFile", _logFileLineEdit->text());
469
470QStringList mountPoints;
471
472 for (int iRow = 0; iRow < _mountPointsTable->rowCount(); iRow++) {
473 QUrl url( "//" + _mountPointsTable->item(iRow, 0)->text() +
474 "@" + _mountPointsTable->item(iRow, 1)->text() );
475
476 mountPoints.append(url.toString() + " " +
477 _mountPointsTable->item(iRow, 2)->text()
478 + " " + _mountPointsTable->item(iRow, 3)->text()
479 + " " + _mountPointsTable->item(iRow, 4)->text()
480 + " " + _mountPointsTable->item(iRow, 5)->text());
481 }
482 settings.setValue("mountPoints", mountPoints);
483}
484
485// All get slots terminated
486////////////////////////////////////////////////////////////////////////////
487void bncWindow::slotGetThreadErrors() {
488 slotMessage("All Get Threads Terminated");
489 ((bncApp*)qApp)->slotMessage("All Get Threads Terminated");
490 _actAddMountPoints->setEnabled(true);
491 _actGetData->setEnabled(true);
492}
493
494// Retrieve Data
495////////////////////////////////////////////////////////////////////////////
496void bncWindow::slotGetData() {
497 slotSaveOptions();
498
499 _actAddMountPoints->setEnabled(false);
500 _actDeleteMountPoints->setEnabled(false);
501 _actGetData->setEnabled(false);
502 _actStop->setEnabled(true);
503
504 _caster = new bncCaster(_outFileLineEdit->text(),
505 _outPortLineEdit->text().toInt());
506
507 connect(_caster, SIGNAL(getThreadErrors()),
508 this, SLOT(slotGetThreadErrors()));
509
510 connect(_caster, SIGNAL(newMessage(const QByteArray&)),
511 this, SLOT(slotMessage(const QByteArray&)));
512 connect(_caster, SIGNAL(newMessage(const QByteArray&)),
513 (bncApp*)qApp, SLOT(slotMessage(const QByteArray&)));
514
515 slotMessage("============ Start BNC ============");
516 ((bncApp*)qApp)->slotMessage("============ Start BNC ============");
517
518 for (int iRow = 0; iRow < _mountPointsTable->rowCount(); iRow++) {
519 QUrl url( "//" + _mountPointsTable->item(iRow, 0)->text() +
520 "@" + _mountPointsTable->item(iRow, 1)->text() );
521
522 QByteArray format = _mountPointsTable->item(iRow, 2)->text().toAscii();
523
524 QByteArray latitude = _mountPointsTable->item(iRow, 3)->text().toAscii();
525 QByteArray longitude = _mountPointsTable->item(iRow, 4)->text().toAscii();
526 QByteArray nmea = _mountPointsTable->item(iRow, 5)->text().toAscii();
527
528 bncGetThread* getThread = new bncGetThread(url, format, latitude, longitude, nmea, iRow);
529
530 connect(getThread, SIGNAL(newMessage(const QByteArray&)),
531 this, SLOT(slotMessage(const QByteArray&)));
532 connect(getThread, SIGNAL(newMessage(const QByteArray&)),
533 (bncApp*)qApp, SLOT(slotMessage(const QByteArray&)));
534
535 connect(getThread, SIGNAL(newBytes(const QByteArray, double)),
536 (bncTableItem*) _mountPointsTable->item(iRow, 6),
537 SLOT(slotNewBytes(const QByteArray, double)));
538
539 _caster->addGetThread(getThread);
540
541 getThread->start();
542 }
543}
544
545// Retrieve Data
546////////////////////////////////////////////////////////////////////////////
547void bncWindow::slotStop() {
548 int iRet = QMessageBox::question(this, "Stop", "Stop retrieving data?",
549 QMessageBox::Yes, QMessageBox::No,
550 QMessageBox::NoButton);
551 if (iRet == QMessageBox::Yes) {
552 delete _caster; _caster = 0;
553 _actGetData->setEnabled(true);
554 _actStop->setEnabled(false);
555 _actAddMountPoints->setEnabled(true);
556 }
557}
558
559// Close Application gracefully
560////////////////////////////////////////////////////////////////////////////
561void bncWindow::closeEvent(QCloseEvent* event) {
562
563 int iRet = QMessageBox::question(this, "Close", "Save Options?",
564 QMessageBox::Yes, QMessageBox::No,
565 QMessageBox::Cancel);
566
567 if (iRet == QMessageBox::Cancel) {
568 event->ignore();
569 return;
570 }
571 else if (iRet == QMessageBox::Yes) {
572 slotSaveOptions();
573 }
574
575 return QMainWindow::closeEvent(event);
576}
577
578// User changed the selection of mountPoints
579////////////////////////////////////////////////////////////////////////////
580void bncWindow::slotSelectionChanged() {
581 if (_mountPointsTable->selectedItems().isEmpty()) {
582 _actDeleteMountPoints->setEnabled(false);
583 }
584 else {
585 _actDeleteMountPoints->setEnabled(true);
586 }
587}
588
589// Display Program Messages
590////////////////////////////////////////////////////////////////////////////
591void bncWindow::slotMessage(const QByteArray msg) {
592
593 const int maxBufferSize = 10000;
594
595 QString txt = _log->toPlainText() + "\n" +
596 QDateTime::currentDateTime().toUTC().toString("yy-MM-dd hh:mm:ss ") + msg;
597 _log->clear();
598 _log->append(txt.right(maxBufferSize));
599}
600
601// About Message
602////////////////////////////////////////////////////////////////////////////
603void bncWindow::slotAbout() {
604
605 QTextBrowser* tb = new QTextBrowser;
606 QUrl url; url.setPath(":bncabout.html");
607 tb->setSource(url);
608 tb->setReadOnly(true);
609
610 QDialog dlg(this);
611
612 QGridLayout* dlgLayout = new QGridLayout();
613 QLabel* img = new QLabel();
614 img->setPixmap(QPixmap(":ntrip-logo.png"));
615 dlgLayout->addWidget(img, 0,0);
616 dlgLayout->addWidget(new QLabel("BKG NTRIP Client (BNC) Version 1.5"), 0,1);
617 dlgLayout->addWidget(tb,1,0,1,2);
618
619 dlg.setLayout(dlgLayout);
620 int ww = QFontMetrics(font()).width('w');
621 dlg.resize(60*ww, 60*ww);
622 dlg.exec();
623}
624
625// Help Window
626////////////////////////////////////////////////////////////////////////////
627void bncWindow::slotHelp() {
628 QUrl url;
629 url.setPath(":bnchelp.html");
630 new bncHlpDlg(this, url);
631}
632
633// Select Fonts
634////////////////////////////////////////////////////////////////////////////
635void bncWindow::slotFontSel() {
636 bool ok;
637 QFont newFont = QFontDialog::getFont(&ok, this->font(), this);
638 if (ok) {
639 QSettings settings;
640 settings.setValue("font", newFont.toString());
641 QApplication::setFont(newFont);
642 int ww = QFontMetrics(newFont).width('w');
643 setMinimumSize(60*ww, 80*ww);
644 resize(60*ww, 80*ww);
645 }
646}
647
648// Whats This Help
649void bncWindow::slotWhatsThis() {
650QWhatsThis::enterWhatsThisMode();
651}
652
653
Note: See TracBrowser for help on using the repository browser.