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

Last change on this file since 562 was 562, checked in by mervart, 17 years ago

* empty log message *

File size: 31.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 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.4"));
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 Version 2.11. 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>Navigation messages can be converted to RINEX files. Enter a path for saving the files in a directory.</p>"));
155 _rnxV3CheckBox = new QCheckBox();
156 _rnxV3CheckBox->setCheckState(Qt::CheckState(settings.value("rnxV3").toInt()));
157 _ephV3CheckBox = new QCheckBox();
158 _ephV3CheckBox->setCheckState(Qt::CheckState(settings.value("ephV3").toInt()));
159 _rnxScrpLineEdit = new QLineEdit(settings.value("rnxScript").toString());
160 _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."));
161 _rnxSkelLineEdit = new QLineEdit(settings.value("rnxSkel").toString());
162 _rnxSkelLineEdit->setMaximumWidth(5*ww);
163 _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>"));
164 _rnxAppendCheckBox = new QCheckBox();
165 _rnxAppendCheckBox->setCheckState(Qt::CheckState(
166 settings.value("rnxAppend").toInt()));
167 _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>"));
168 _rnxIntrComboBox = new QComboBox();
169 _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>"));
170 _rnxIntrComboBox->setMaximumWidth(9*ww);
171 _rnxIntrComboBox->setEditable(false);
172 _rnxIntrComboBox->addItems(QString("1 min,2 min,5 min,10 min,15 min,30 min,1 hour,1 day").split(","));
173 int ii = _rnxIntrComboBox->findText(settings.value("rnxIntr").toString());
174 if (ii != -1) {
175 _rnxIntrComboBox->setCurrentIndex(ii);
176 }
177 _ephIntrComboBox = new QComboBox();
178 _ephIntrComboBox->setWhatsThis(tr("<p>Select an interval for the ephemeris file generation."));
179 _ephIntrComboBox->setMaximumWidth(9*ww);
180 _ephIntrComboBox->setEditable(false);
181 _ephIntrComboBox->addItems(QString("15 min,30 min,1 hour,1 day").split(","));
182 int jj = _ephIntrComboBox->findText(settings.value("ephIntr").toString());
183 if (jj != -1) {
184 _ephIntrComboBox->setCurrentIndex(jj);
185 }
186 _rnxSamplSpinBox = new QSpinBox();
187 _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>"));
188 _rnxSamplSpinBox->setMinimum(0);
189 _rnxSamplSpinBox->setMaximum(60);
190 _rnxSamplSpinBox->setSingleStep(5);
191 _rnxSamplSpinBox->setMaximumWidth(9*ww);
192 _rnxSamplSpinBox->setValue(settings.value("rnxSampl").toInt());
193 _rnxSamplSpinBox->setSuffix(" sec");
194 _logFileLineEdit = new QLineEdit(settings.value("logFile").toString());
195 _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>"));
196 _mountPointsTable = new QTableWidget(0,7);
197 _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', 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>"));
198
199 _mountPointsTable->horizontalHeader()->resizeSection(1,25*ww);
200 _mountPointsTable->horizontalHeader()->resizeSection(2,9*ww);
201 _mountPointsTable->horizontalHeader()->resizeSection(3,7*ww);
202 _mountPointsTable->horizontalHeader()->resizeSection(4,7*ww);
203 _mountPointsTable->horizontalHeader()->resizeSection(5,5*ww);
204 _mountPointsTable->horizontalHeader()->setResizeMode(QHeaderView::Interactive);
205 _mountPointsTable->horizontalHeader()->setStretchLastSection(true);
206 _mountPointsTable->setHorizontalHeaderLabels(labels);
207 _mountPointsTable->setGridStyle(Qt::NoPen);
208 _mountPointsTable->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
209 _mountPointsTable->setSelectionMode(QAbstractItemView::ExtendedSelection);
210 _mountPointsTable->setSelectionBehavior(QAbstractItemView::SelectRows);
211 QListIterator<QString> it(settings.value("mountPoints").toStringList());
212 if (!it.hasNext()) {
213 _actGetData->setEnabled(false);
214 }
215 int iRow = 0;
216 while (it.hasNext()) {
217 QStringList hlp = it.next().split(" ");
218 if (hlp.size() < 5) continue;
219 _mountPointsTable->insertRow(iRow);
220
221 QUrl url(hlp[0]);
222
223 QString fullPath = url.host() + QString(":%1").arg(url.port()) + url.path();
224 QString format(hlp[1]); QString latitude(hlp[2]); QString longitude(hlp[3]);
225 QString nmea(hlp[4]);
226
227 QTableWidgetItem* it;
228 it = new QTableWidgetItem(url.userInfo());
229 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
230 _mountPointsTable->setItem(iRow, 0, it);
231
232 it = new QTableWidgetItem(fullPath);
233 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
234 _mountPointsTable->setItem(iRow, 1, it);
235
236 it = new QTableWidgetItem(format);
237 _mountPointsTable->setItem(iRow, 2, it);
238
239 if (nmea == "yes") {
240 it = new QTableWidgetItem(latitude);
241 _mountPointsTable->setItem(iRow, 3, it);
242 it = new QTableWidgetItem(longitude);
243 _mountPointsTable->setItem(iRow, 4, it);
244 } else {
245 it = new QTableWidgetItem(latitude);
246 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
247 _mountPointsTable->setItem(iRow, 3, it);
248 it = new QTableWidgetItem(longitude);
249 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
250 _mountPointsTable->setItem(iRow, 4, it);
251 }
252
253 it = new QTableWidgetItem(nmea);
254 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
255 _mountPointsTable->setItem(iRow, 5, it);
256
257 bncTableItem* bncIt = new bncTableItem();
258 bncIt->setFlags(bncIt->flags() & ~Qt::ItemIsEditable);
259 _mountPointsTable->setItem(iRow, 6, bncIt);
260
261 iRow++;
262 }
263 _mountPointsTable->hideColumn(0);
264 _mountPointsTable->sortItems(1);
265
266 connect(_mountPointsTable, SIGNAL(itemSelectionChanged()),
267 SLOT(slotSelectionChanged()));
268
269 _log = new QTextBrowser();
270 _log->setReadOnly(true);
271
272 _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."));
273
274 layout->addWidget(new QLabel("Proxy host"), 0, 0, 1, 2);
275 layout->addWidget(_proxyHostLineEdit, 0, 2);
276 layout->addWidget(new QLabel("Proxy port"), 0, 3);
277 layout->addWidget(_proxyPortLineEdit, 0, 4);
278
279 layout->addWidget(new QLabel("Wait for full epoch"), 1, 0, 1, 2);
280 layout->addWidget(_waitTimeSpinBox, 1, 2);
281
282 layout->addWidget(new QLabel("ASCII output file (full path)"), 2, 0, 1, 2);
283 layout->addWidget(_outFileLineEdit, 2, 2, 1, 3);
284
285 layout->addWidget(new QLabel("Port for binary output"), 3, 0, 1, 2);
286 layout->addWidget(_outPortLineEdit, 3, 2);
287
288 layout->addWidget(new QLabel("RINEX directory"), 4, 0, 1, 2);
289 layout->addWidget(_rnxPathLineEdit, 4, 2);
290
291 layout->addWidget(new QLabel("RINEX v3"), 4, 3, 1, 2);
292 layout->addWidget(_rnxV3CheckBox, 4, 4);
293
294 layout->addWidget(new QLabel("RINEX script (full path)"), 5, 0, 1, 2);
295 layout->addWidget(_rnxScrpLineEdit, 5, 2, 1, 3);
296
297 layout->addWidget(new QLabel("File interval"), 6, 0, 1, 2);
298
299 QBoxLayout* bl = new QBoxLayout(QBoxLayout::LeftToRight);
300 bl->addWidget(_rnxIntrComboBox);
301 bl->addWidget(new QLabel("RINEX"));
302 bl->addWidget(_ephIntrComboBox);
303 bl->addWidget(new QLabel("EPH"));
304 layout->addLayout(bl, 6, 2, 1, 1);
305
306 layout->addWidget(new QLabel("Sampling"), 6, 3);
307 layout->addWidget(_rnxSamplSpinBox, 6, 4);
308
309 layout->addWidget(new QLabel("RINEX skeleton extension"), 7, 0, 1, 2);
310 layout->addWidget(_rnxSkelLineEdit, 7, 2);
311
312 layout->addWidget(new QLabel("Append files"), 7, 3);
313 layout->addWidget(_rnxAppendCheckBox, 7, 4);
314
315 layout->addWidget(new QLabel("Ephemeris directory"), 8, 0, 1, 2);
316 layout->addWidget(_ephPathLineEdit, 8, 2);
317
318 layout->addWidget(new QLabel("RINEX v3"), 8, 3, 1, 2);
319 layout->addWidget(_ephV3CheckBox, 8, 4);
320
321 layout->addWidget(new QLabel("Mountpoints"), 9, 0, 1, 2);
322
323 layout->addWidget(_mountPointsTable, 10, 0, 1, 5);
324
325 layout->addWidget(new QLabel("Log (full path)"), 11, 0, 1, 2);
326 layout->addWidget(_logFileLineEdit, 11, 2, 1, 3);
327 layout->addWidget(_log, 12, 0, 1, 5);
328}
329
330// Destructor
331////////////////////////////////////////////////////////////////////////////
332bncWindow::~bncWindow() {
333}
334
335// Retrieve Table
336////////////////////////////////////////////////////////////////////////////
337void bncWindow::slotAddMountPoints() {
338
339 QSettings settings;
340 QString proxyHost = settings.value("proxyHost").toString();
341 int proxyPort = settings.value("proxyPort").toInt();
342 if (proxyHost != _proxyHostLineEdit->text() ||
343 proxyPort != _proxyPortLineEdit->text().toInt()) {
344 int iRet = QMessageBox::question(this, "Question", "Proxy options "
345 "changed. Use the new ones?",
346 QMessageBox::Yes, QMessageBox::No,
347 QMessageBox::NoButton);
348 if (iRet == QMessageBox::Yes) {
349 settings.setValue("proxyHost", _proxyHostLineEdit->text());
350 settings.setValue("proxyPort", _proxyPortLineEdit->text());
351 }
352 }
353
354 bncTableDlg* dlg = new bncTableDlg(this);
355 dlg->move(this->pos().x()+50, this->pos().y()+50);
356 connect(dlg, SIGNAL(newMountPoints(QStringList*)),
357 this, SLOT(slotNewMountPoints(QStringList*)));
358 dlg->exec();
359 delete dlg;
360
361}
362
363// Delete Selected Mount Points
364////////////////////////////////////////////////////////////////////////////
365void bncWindow::slotDeleteMountPoints() {
366
367 int nRows = _mountPointsTable->rowCount();
368 bool flg[nRows];
369 for (int iRow = 0; iRow < nRows; iRow++) {
370 if (_mountPointsTable->isItemSelected(_mountPointsTable->item(iRow,1))) {
371 flg[iRow] = true;
372 }
373 else {
374 flg[iRow] = false;
375 }
376 }
377 for (int iRow = nRows-1; iRow >= 0; iRow--) {
378 if (flg[iRow]) {
379 _mountPointsTable->removeRow(iRow);
380 }
381 }
382 _actDeleteMountPoints->setEnabled(false);
383
384 if (_mountPointsTable->rowCount() == 0) {
385 _actGetData->setEnabled(false);
386 }
387}
388
389// New Mount Points Selected
390////////////////////////////////////////////////////////////////////////////
391void bncWindow::slotNewMountPoints(QStringList* mountPoints) {
392 int iRow = 0;
393 QListIterator<QString> it(*mountPoints);
394 while (it.hasNext()) {
395 QStringList hlp = it.next().split(" ");
396 QUrl url(hlp[0]);
397 QString fullPath = url.host() + QString(":%1").arg(url.port()) + url.path();
398 QString format(hlp[1]); QString latitude(hlp[2]); QString longitude(hlp[3]);
399 QString nmea(hlp[4]);
400
401 _mountPointsTable->insertRow(iRow);
402
403 QTableWidgetItem* it;
404 it = new QTableWidgetItem(url.userInfo());
405 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
406 _mountPointsTable->setItem(iRow, 0, it);
407
408 it = new QTableWidgetItem(fullPath);
409 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
410 _mountPointsTable->setItem(iRow, 1, it);
411
412 it = new QTableWidgetItem(format);
413 _mountPointsTable->setItem(iRow, 2, it);
414
415 if (nmea == "yes") {
416 it = new QTableWidgetItem(latitude);
417 _mountPointsTable->setItem(iRow, 3, it);
418 it = new QTableWidgetItem(longitude);
419 _mountPointsTable->setItem(iRow, 4, it);
420 } else {
421 it = new QTableWidgetItem(latitude);
422 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
423 _mountPointsTable->setItem(iRow, 3, it);
424 it = new QTableWidgetItem(longitude);
425 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
426 _mountPointsTable->setItem(iRow, 4, it);
427 }
428
429 it = new QTableWidgetItem(nmea);
430 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
431 _mountPointsTable->setItem(iRow, 5, it);
432
433 bncTableItem* bncIt = new bncTableItem();
434 _mountPointsTable->setItem(iRow, 6, bncIt);
435
436 iRow++;
437 }
438 _mountPointsTable->hideColumn(0);
439 _mountPointsTable->sortItems(1);
440 if (mountPoints->count() > 0) {
441 _actGetData->setEnabled(true);
442 }
443 delete mountPoints;
444}
445
446// Save Options
447////////////////////////////////////////////////////////////////////////////
448void bncWindow::slotSaveOptions() {
449 QSettings settings;
450 settings.setValue("proxyHost", _proxyHostLineEdit->text());
451 settings.setValue("proxyPort", _proxyPortLineEdit->text());
452 settings.setValue("waitTime", _waitTimeSpinBox->value());
453 settings.setValue("outFile", _outFileLineEdit->text());
454 settings.setValue("outPort", _outPortLineEdit->text());
455 settings.setValue("rnxPath", _rnxPathLineEdit->text());
456 settings.setValue("ephPath", _ephPathLineEdit->text());
457 settings.setValue("rnxScript", _rnxScrpLineEdit->text());
458 settings.setValue("rnxIntr", _rnxIntrComboBox->currentText());
459 settings.setValue("ephIntr", _ephIntrComboBox->currentText());
460 settings.setValue("rnxSampl", _rnxSamplSpinBox->value());
461 settings.setValue("rnxSkel", _rnxSkelLineEdit->text());
462 settings.setValue("rnxAppend", _rnxAppendCheckBox->checkState());
463 settings.setValue("rnxV3", _rnxV3CheckBox->checkState());
464 settings.setValue("ephV3", _ephV3CheckBox->checkState());
465 settings.setValue("logFile", _logFileLineEdit->text());
466
467QStringList mountPoints;
468
469 for (int iRow = 0; iRow < _mountPointsTable->rowCount(); iRow++) {
470 QUrl url( "//" + _mountPointsTable->item(iRow, 0)->text() +
471 "@" + _mountPointsTable->item(iRow, 1)->text() );
472
473 mountPoints.append(url.toString() + " " +
474 _mountPointsTable->item(iRow, 2)->text()
475 + " " + _mountPointsTable->item(iRow, 3)->text()
476 + " " + _mountPointsTable->item(iRow, 4)->text()
477 + " " + _mountPointsTable->item(iRow, 5)->text());
478 }
479 settings.setValue("mountPoints", mountPoints);
480}
481
482// All get slots terminated
483////////////////////////////////////////////////////////////////////////////
484void bncWindow::slotGetThreadErrors() {
485 slotMessage("All Get Threads Terminated");
486 ((bncApp*)qApp)->slotMessage("All Get Threads Terminated");
487 _actAddMountPoints->setEnabled(true);
488 _actGetData->setEnabled(true);
489}
490
491// Retrieve Data
492////////////////////////////////////////////////////////////////////////////
493void bncWindow::slotGetData() {
494 slotSaveOptions();
495
496 _actAddMountPoints->setEnabled(false);
497 _actDeleteMountPoints->setEnabled(false);
498 _actGetData->setEnabled(false);
499 _actStop->setEnabled(true);
500
501 _caster = new bncCaster(_outFileLineEdit->text(),
502 _outPortLineEdit->text().toInt());
503
504 connect(_caster, SIGNAL(getThreadErrors()),
505 this, SLOT(slotGetThreadErrors()));
506
507 connect(_caster, SIGNAL(newMessage(const QByteArray&)),
508 this, SLOT(slotMessage(const QByteArray&)));
509 connect(_caster, SIGNAL(newMessage(const QByteArray&)),
510 (bncApp*)qApp, SLOT(slotMessage(const QByteArray&)));
511
512 slotMessage("============ Start BNC ============");
513 ((bncApp*)qApp)->slotMessage("============ Start BNC ============");
514
515 for (int iRow = 0; iRow < _mountPointsTable->rowCount(); iRow++) {
516 QUrl url( "//" + _mountPointsTable->item(iRow, 0)->text() +
517 "@" + _mountPointsTable->item(iRow, 1)->text() );
518
519 QByteArray format = _mountPointsTable->item(iRow, 2)->text().toAscii();
520
521 QByteArray latitude = _mountPointsTable->item(iRow, 3)->text().toAscii();
522 QByteArray longitude = _mountPointsTable->item(iRow, 4)->text().toAscii();
523 QByteArray nmea = _mountPointsTable->item(iRow, 5)->text().toAscii();
524
525 bncGetThread* getThread = new bncGetThread(url, format, latitude, longitude, nmea, iRow);
526
527 connect(getThread, SIGNAL(newMessage(const QByteArray&)),
528 this, SLOT(slotMessage(const QByteArray&)));
529 connect(getThread, SIGNAL(newMessage(const QByteArray&)),
530 (bncApp*)qApp, SLOT(slotMessage(const QByteArray&)));
531
532 connect(getThread, SIGNAL(newBytes(const QByteArray, double)),
533 (bncTableItem*) _mountPointsTable->item(iRow, 6),
534 SLOT(slotNewBytes(const QByteArray, double)));
535
536 _caster->addGetThread(getThread);
537
538 getThread->start();
539 }
540}
541
542// Retrieve Data
543////////////////////////////////////////////////////////////////////////////
544void bncWindow::slotStop() {
545 int iRet = QMessageBox::question(this, "Stop", "Stop retrieving data?",
546 QMessageBox::Yes, QMessageBox::No,
547 QMessageBox::NoButton);
548 if (iRet == QMessageBox::Yes) {
549 delete _caster; _caster = 0;
550 _actGetData->setEnabled(true);
551 _actStop->setEnabled(false);
552 _actAddMountPoints->setEnabled(true);
553 }
554}
555
556// Close Application gracefully
557////////////////////////////////////////////////////////////////////////////
558void bncWindow::closeEvent(QCloseEvent* event) {
559
560 int iRet = QMessageBox::question(this, "Close", "Save Options?",
561 QMessageBox::Yes, QMessageBox::No,
562 QMessageBox::Cancel);
563
564 if (iRet == QMessageBox::Cancel) {
565 event->ignore();
566 return;
567 }
568 else if (iRet == QMessageBox::Yes) {
569 slotSaveOptions();
570 }
571
572 return QMainWindow::closeEvent(event);
573}
574
575// User changed the selection of mountPoints
576////////////////////////////////////////////////////////////////////////////
577void bncWindow::slotSelectionChanged() {
578 if (_mountPointsTable->selectedItems().isEmpty()) {
579 _actDeleteMountPoints->setEnabled(false);
580 }
581 else {
582 _actDeleteMountPoints->setEnabled(true);
583 }
584}
585
586// Display Program Messages
587////////////////////////////////////////////////////////////////////////////
588void bncWindow::slotMessage(const QByteArray msg) {
589
590 const int maxBufferSize = 10000;
591
592 QString txt = _log->toPlainText() + "\n" +
593 QDate::currentDate().toString("yy-MM-dd ") +
594 QTime::currentTime().toString("hh:mm:ss ") + msg;
595 _log->clear();
596 _log->append(txt.right(maxBufferSize));
597}
598
599// About Message
600////////////////////////////////////////////////////////////////////////////
601void bncWindow::slotAbout() {
602
603 QTextBrowser* tb = new QTextBrowser;
604 QUrl url; url.setPath(":bncabout.html");
605 tb->setSource(url);
606 tb->setReadOnly(true);
607
608 QDialog dlg(this);
609
610 QGridLayout* dlgLayout = new QGridLayout();
611 QLabel* img = new QLabel();
612 img->setPixmap(QPixmap(":ntrip-logo.png"));
613 dlgLayout->addWidget(img, 0,0);
614 dlgLayout->addWidget(new QLabel("BKG NTRIP Client (BNC), Version 1.4"), 0,1);
615 dlgLayout->addWidget(tb,1,0,1,2);
616
617 dlg.setLayout(dlgLayout);
618 int ww = QFontMetrics(font()).width('w');
619 dlg.resize(60*ww, 60*ww);
620 dlg.exec();
621}
622
623// Help Window
624////////////////////////////////////////////////////////////////////////////
625void bncWindow::slotHelp() {
626 QUrl url;
627 url.setPath(":bnchelp.html");
628 new bncHlpDlg(this, url);
629}
630
631// Select Fonts
632////////////////////////////////////////////////////////////////////////////
633void bncWindow::slotFontSel() {
634 bool ok;
635 QFont newFont = QFontDialog::getFont(&ok, this->font(), this);
636 if (ok) {
637 QSettings settings;
638 settings.setValue("font", newFont.toString());
639 QApplication::setFont(newFont);
640 int ww = QFontMetrics(newFont).width('w');
641 setMinimumSize(60*ww, 80*ww);
642 resize(60*ww, 80*ww);
643 }
644}
645
646// Whats This Help
647void bncWindow::slotWhatsThis() {
648QWhatsThis::enterWhatsThisMode();
649}
650
651
Note: See TracBrowser for help on using the repository browser.