source: ntrip/trunk/BNC/bnctabledlg.cpp@ 1460

Last change on this file since 1460 was 1460, checked in by weber, 15 years ago

* empty log message *

File size: 20.5 KB
Line 
1// Part of BNC, a utility for retrieving decoding and
2// converting GNSS data streams from NTRIP broadcasters.
3//
4// Copyright (C) 2007
5// German Federal Agency for Cartography and Geodesy (BKG)
6// http://www.bkg.bund.de
7// Czech Technical University Prague, Department of Geodesy
8// http://www.fsv.cvut.cz
9//
10// Email: euref-ip@bkg.bund.de
11//
12// This program is free software; you can redistribute it and/or
13// modify it under the terms of the GNU General Public License
14// as published by the Free Software Foundation, version 2.
15//
16// This program is distributed in the hope that it will be useful,
17// but WITHOUT ANY WARRANTY; without even the implied warranty of
18// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19// GNU General Public License for more details.
20//
21// You should have received a copy of the GNU General Public License
22// along with this program; if not, write to the Free Software
23// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24
25/* -------------------------------------------------------------------------
26 * BKG NTRIP Client
27 * -------------------------------------------------------------------------
28 *
29 * Class: bncTableDlg
30 *
31 * Purpose: Displays the source table, allows mountpoints selection
32 *
33 * Author: L. Mervart
34 *
35 * Created: 24-Dec-2005
36 *
37 * Changes:
38 *
39 * -----------------------------------------------------------------------*/
40
41#include <iostream>
42
43#include "bnctabledlg.h"
44#include "bncgetthread.h"
45#include "bncnetqueryv2.h"
46
47using namespace std;
48
49// Constructor
50////////////////////////////////////////////////////////////////////////////
51bncTableDlg::bncTableDlg(QWidget* parent) : QDialog(parent) {
52
53 setMinimumSize(600,400);
54 setWindowTitle(tr("Add Streams"));
55
56 QVBoxLayout* mainLayout = new QVBoxLayout(this);
57
58 QSettings settings;
59 _casterHostLineEdit = new QComboBox();
60 _casterHostLineEdit->setDuplicatesEnabled(false);
61 _casterHostLineEdit->setEditable(true);
62 int ww = QFontMetrics(_casterHostLineEdit->font()).width('w');
63 _casterHostLineEdit->setMaximumWidth(20*ww);
64 QStringList casterHostList = settings.value("casterHostList").toStringList();
65 _casterHostLineEdit->addItem(settings.value("casterHost").toString());
66 for (int ii = 0; ii < casterHostList.count(); ii++) {
67 QString item = casterHostList[ii];
68 if (_casterHostLineEdit->findText(item, Qt::MatchFixedString) < 0) {
69 _casterHostLineEdit->addItem(item);
70 }
71 }
72 _casterPortLineEdit = new QLineEdit(settings.value("casterPort").toString());
73 _casterPortLineEdit->setMaximumWidth(9*ww);
74 _casterUserLineEdit = new QLineEdit(settings.value("casterUser").toString());
75 _casterUserLineEdit->setMaximumWidth(9*ww);
76 _casterPasswordLineEdit = new QLineEdit(settings.value("casterPassword").toString());
77 _casterPasswordLineEdit->setMaximumWidth(9*ww);
78 _casterPasswordLineEdit->setEchoMode(QLineEdit::Password);
79
80 _ntripVersionComboBox = new QComboBox();
81 _ntripVersionComboBox->addItems(QString("1,2,R").split(","));
82 int kk = _ntripVersionComboBox->findText(settings.value("ntripVersion").toString());
83 if (kk != -1) {
84 _ntripVersionComboBox->setCurrentIndex(kk);
85 }
86 _ntripVersionComboBox->setMaximumWidth(5*ww);
87
88 _buttonCasterTable = new QPushButton(tr("Show"), this);
89 connect(_buttonCasterTable, SIGNAL(clicked()), this, SLOT(slotCasterTable()));
90 _buttonCasterTable->setMaximumWidth(5*ww);
91
92 // WhatsThis
93 // ---------
94 _casterUserLineEdit->setWhatsThis(tr("<p>Access to some streams on NTRIP broadcasters may be restricted. You'll need to enter a valid 'User ID' and 'Password' for access to these protected streams.</p><p>Accounts are usually provided per NTRIP broadcaster through a registration process. Register through <u>http://igs.bkg.bund.de/index_ntrip_reg.htm</u> for access to protected streams on <u>www.euref-ip.net</u> and <u>www.igs-ip.net</u>.</p>"));
95 _casterHostLineEdit->setWhatsThis(tr("<p>Enter the NTRIP broadcaster hostname or IP number.</p><p>Note that EUREF and IGS operate NTRIP broadcasters at <u>http://www.euref-ip.net/home</u> and <u>http://www.igs-ip.net/home</u>.</p>"));
96 _casterPortLineEdit->setWhatsThis(tr("Enter the NTRIP broadcaster port number."));
97 _casterPasswordLineEdit->setWhatsThis(tr("Access to some streams on NTRIP broadcasters may be restricted. You'll need to enter a valid 'Password' for access to these protected streams."));
98
99 QGridLayout* editLayout = new QGridLayout;
100 editLayout->addWidget(new QLabel(tr("Caster host")), 0, 0);
101 editLayout->addWidget(_casterHostLineEdit, 0, 1);
102 editLayout->addWidget(new QLabel(tr(" Caster port")), 0, 2, Qt::AlignRight);
103 editLayout->addWidget(_casterPortLineEdit, 0, 3);
104 editLayout->addWidget(new QLabel(tr("Caster table")), 0, 4, Qt::AlignRight);
105 editLayout->addWidget(_buttonCasterTable, 0, 5);
106 editLayout->addWidget(new QLabel(tr("User")), 1, 0, Qt::AlignRight);
107 editLayout->addWidget(_casterUserLineEdit, 1, 1);
108 editLayout->addWidget(new QLabel(tr("Password")), 1, 2, Qt::AlignRight);
109 editLayout->addWidget(_casterPasswordLineEdit, 1, 3);
110 editLayout->addWidget(new QLabel(tr(" NTRIP Version")),1, 4, Qt::AlignRight);
111 editLayout->addWidget(_ntripVersionComboBox, 1, 5);
112
113 mainLayout->addLayout(editLayout);
114
115 _buttonCasterTable->setWhatsThis(tr("<p>Hit 'Show' for a table of known NTRIP broadcaster installations as maintained at www.rtcm-ntrip.org/home.</p><p>A window opens which allows to select a broadcaster for stream retrieval.</p>"));
116 _ntripVersionComboBox->setWhatsThis(tr("<p>Select the NTRIP transport protocol version you want to use. Implemented options are:<br>&nbsp; 1:&nbsp; NTRIP version 1, TCP/IP<br>&nbsp; 2:&nbsp; NTRIP version 2, TCP/IP<br>&nbsp; R:&nbsp; NTRIP Version 2, RTSP/RTP<br>Select option '1' if you are not sure whether the NTRIP broadcaster supports NTRIP version 2.</p>"));
117
118 _table = new QTableWidget(this);
119 _table->setWhatsThis(tr("<p>Use the 'Get Table' button to download the sourcetable from the selected NTRIP broadcaster. Select the desired streams line by line, using +Shift and +Ctrl when necessary. Hit 'OK' to return to the main window.</p><p>Pay attention to data field 'format'. Keep in mind that BNC can only decode and convert streams that come in RTCM Version 2.x, RTCM Version 3.x, or RTIGS format. See data field 'format-details' for available message types and their repetition rates in brackets.</p><p>The content of data field 'nmea' tells you whether a stream comes from a virtual reference station (VRS).</p>"));
120 connect(_table, SIGNAL(itemSelectionChanged()),
121 this, SLOT(slotSelectionChanged()));
122 mainLayout->addWidget(_table);
123
124 _buttonWhatsThis = new QPushButton(tr("Help=Shift+F1"), this);
125 connect(_buttonWhatsThis, SIGNAL(clicked()), this, SLOT(slotWhatsThis()));
126
127 _buttonGet = new QPushButton(tr("Get table"), this);
128 _buttonGet->setDefault(true);
129 connect(_buttonGet, SIGNAL(clicked()), this, SLOT(slotGetTable()));
130
131 _buttonCancel = new QPushButton(tr("Cancel"), this);
132 connect(_buttonCancel, SIGNAL(clicked()), this, SLOT(reject()));
133
134 _buttonOK = new QPushButton(tr("OK"), this);
135 connect(_buttonOK, SIGNAL(clicked()), this, SLOT(accept()));
136
137 QHBoxLayout* buttonLayout = new QHBoxLayout;
138 buttonLayout->addWidget(_buttonWhatsThis);
139 buttonLayout->addStretch(1);
140 buttonLayout->addWidget(_buttonGet);
141 buttonLayout->addWidget(_buttonCancel);
142 buttonLayout->addWidget(_buttonOK);
143
144 mainLayout->addLayout(buttonLayout);
145}
146
147// Destructor
148////////////////////////////////////////////////////////////////////////////
149bncTableDlg::~bncTableDlg() {
150 if (_table) {
151 for (int ir = 0; ir < _table->rowCount(); ir++) {
152 for (int ic = 0; ic < _table->columnCount(); ic++) {
153 delete _table->item(ir,ic);
154 }
155 }
156 }
157}
158
159// Read Table the caster (static)
160////////////////////////////////////////////////////////////////////////////
161t_irc bncTableDlg::getFullTable(const QString& casterHost,
162 int casterPort, QStringList& allLines,
163 bool alwaysRead) {
164
165 static QMutex mutex;
166 static QMap<QString, QStringList> allTables;
167
168 QMutexLocker locker(&mutex);
169
170 if (!alwaysRead && allTables.find(casterHost) != allTables.end()) {
171 allLines = allTables.find(casterHost).value();
172 return success;
173 }
174
175 allLines.clear();
176
177 QUrl url;
178 url.setHost(casterHost);
179 url.setPort(casterPort);
180 url.setScheme("http");
181 url.setPath("/");
182
183 bncNetQueryV2 query;
184 QByteArray outData;
185 query.waitForRequestResult(url, outData);
186 if (query.status() == bncNetQuery::finished) {
187 QTextStream in(outData);
188 QString line = in.readLine();
189 while ( !line.isNull() ) {
190 allLines.append(line);
191 line = in.readLine();
192 }
193 allTables.insert(casterHost, allLines);
194 return success;
195 }
196 else {
197 return failure;
198 }
199}
200
201// Read Table from Caster
202////////////////////////////////////////////////////////////////////////////
203void bncTableDlg::slotGetTable() {
204
205 _buttonGet->setEnabled(false);
206 _buttonCasterTable->setEnabled(false);
207
208 _allLines.clear();
209
210 if ( getFullTable(_casterHostLineEdit->currentText(),
211 _casterPortLineEdit->text().toInt(),
212 _allLines) != success ) {
213 QMessageBox::warning(0, "BNC", "Cannot retrieve table of data");
214 _buttonGet->setEnabled(true);
215 return;
216 }
217
218 QStringList lines;
219 QStringListIterator it(_allLines);
220 while (it.hasNext()) {
221 QString line = it.next();
222 if (line.indexOf("STR") == 0) {
223 lines.push_back(line);
224 }
225 }
226
227 static const QStringList labels = QString("mountpoint,identifier,format,"
228 "format-details,carrier,system,network,country,latitude,longitude,"
229 "nmea,solution,generator,compress.,authentic.,fee,bitrate,"
230 "misc").split(",");
231
232 if (lines.size() > 0) {
233 _table->setSelectionMode(QAbstractItemView::ExtendedSelection);
234 _table->setSelectionBehavior(QAbstractItemView::SelectRows);
235
236 QStringList hlp = lines[0].split(";");
237 _table->setColumnCount(hlp.size()-1);
238 _table->setRowCount(lines.size());
239
240 QListIterator<QString> it(lines);
241 int nRow = -1;
242 while (it.hasNext()) {
243 QStringList columns = it.next().split(";");
244 ++nRow;
245 for (int ic = 0; ic < columns.size()-1; ic++) {
246
247 if (ic+1 == 11) { if (columns[ic+1] == "0") { columns[ic+1] = "no"; } else { columns[ic+1] = "yes"; }}
248
249 QTableWidgetItem* it = new QTableWidgetItem(columns[ic+1]);
250 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
251 _table->setItem(nRow, ic, it);
252 }
253 }
254 _table->sortItems(0);
255 _table->setHorizontalHeaderLabels(labels);
256 _table->setSortingEnabled(true);
257
258 int ww = QFontMetrics(this->font()).width('w');
259 _table->horizontalHeader()->resizeSection(0,10*ww);
260 _table->horizontalHeader()->resizeSection(2,8*ww);
261 _table->horizontalHeader()->resizeSection(3,15*ww);
262 _table->horizontalHeader()->resizeSection(4,8*ww);
263 _table->horizontalHeader()->resizeSection(5,8*ww);
264 _table->horizontalHeader()->resizeSection(6,8*ww);
265 _table->horizontalHeader()->resizeSection(7,8*ww);
266 _table->horizontalHeader()->resizeSection(8,8*ww);
267 _table->horizontalHeader()->resizeSection(9,8*ww);
268 _table->horizontalHeader()->resizeSection(10,8*ww);
269 _table->horizontalHeader()->resizeSection(11,8*ww);
270 _table->horizontalHeader()->resizeSection(12,15*ww);
271 _table->horizontalHeader()->resizeSection(13,8*ww);
272 _table->horizontalHeader()->resizeSection(14,8*ww);
273 _table->horizontalHeader()->resizeSection(15,8*ww);
274 _table->horizontalHeader()->resizeSection(16,8*ww);
275 _table->horizontalHeader()->resizeSection(17,15*ww);
276 }
277}
278
279// Accept slot
280////////////////////////////////////////////////////////////////////////////
281void bncTableDlg::accept() {
282
283 QSettings settings;
284 settings.setValue("casterHost", _casterHostLineEdit->currentText());
285 QStringList casterHostList;
286 for (int ii = 0; ii < _casterHostLineEdit->count(); ii++) {
287 casterHostList.push_back(_casterHostLineEdit->itemText(ii));
288 }
289 settings.setValue("casterHostList", casterHostList);
290 settings.setValue("casterPort", _casterPortLineEdit->text());
291 settings.setValue("ntripVersion", _ntripVersionComboBox->currentText());
292 settings.setValue("casterUser", _casterUserLineEdit->text());
293 settings.setValue("casterPassword", _casterPasswordLineEdit->text());
294
295 QStringList* mountPoints = new QStringList;
296
297 if (_table) {
298 for (int ir = 0; ir < _table->rowCount(); ir++) {
299 QTableWidgetItem* item = _table->item(ir,0);
300 QString format = _table->item(ir,2)->text();
301 QString latitude = _table->item(ir,8)->text();
302 QString longitude = _table->item(ir,9)->text();
303 QString nmea = _table->item(ir,10)->text();
304 QString ntripVersion = _ntripVersionComboBox->currentText();
305 format.replace(" ", "_");
306 if (_table->isItemSelected(item)) {
307 QUrl url;
308 url.setUserName(QUrl::toPercentEncoding(_casterUserLineEdit->text()));
309 url.setPassword(QUrl::toPercentEncoding(_casterPasswordLineEdit->text()));
310 url.setHost(_casterHostLineEdit->currentText());
311 url.setPort(_casterPortLineEdit->text().toInt());
312 url.setPath(item->text());
313
314 mountPoints->push_back(url.toString() + " " + format + " " + latitude
315 + " " + longitude + " " + nmea + " " + ntripVersion);
316 }
317 }
318 }
319 emit newMountPoints(mountPoints);
320
321 QDialog::accept();
322}
323
324// User changed the selection of mountPoints
325////////////////////////////////////////////////////////////////////////////
326void bncTableDlg::slotSelectionChanged() {
327 if (_table->selectedItems().isEmpty()) {
328 }
329}
330
331// Create RINEX skeleton header
332////////////////////////////////////////////////////////////////////////////
333void bncTableDlg::slotSkl() {
334
335 int nRows = _table->rowCount();
336 for (int iRow = 0; iRow < nRows; iRow++) {
337 if (_table->isItemSelected(_table->item(iRow,1))) {
338 QString staID = _table->item(iRow,0)->text();
339 QString net = _table->item(iRow,6)->text();
340
341 QString ftpDir;
342 QStringListIterator it(_allLines);
343 while (it.hasNext()) {
344 QString line = it.next();
345 if (line.indexOf("NET") == 0) {
346 QStringList tags = line.split(';');
347 if (tags.at(1) == net) {
348 ftpDir = tags.at(6);
349 break;
350 }
351 }
352 }
353
354 if (!ftpDir.isEmpty()) {
355 QUrl url(ftpDir);
356 QMessageBox::warning(0, "Warning", url.host() + "\n" + url.path() +
357 "\nnot yet implemented");
358 }
359 }
360 }
361}
362
363// Whats This Help
364void bncTableDlg::slotWhatsThis() {
365QWhatsThis::enterWhatsThisMode();
366}
367
368// Slot caster table
369////////////////////////////////////////////////////////////////////////////
370void bncTableDlg::slotCasterTable() {
371
372 _buttonCasterTable->setEnabled(false);
373 bncCasterTableDlg* dlg = new bncCasterTableDlg(this);
374 dlg->move(this->pos().x()+50, this->pos().y()+50);
375 connect(dlg, SIGNAL(newCaster(QString*, QString*)),
376 this, SLOT(slotNewCaster(QString*, QString*)));
377 dlg->exec();
378 delete dlg;
379 _buttonCasterTable->setEnabled(true);
380
381}
382
383// Caster table
384////////////////////////////////////////////////////////////////////////////
385bncCasterTableDlg::bncCasterTableDlg(QWidget* parent) :
386 QDialog(parent) {
387
388 static const QStringList labels = QString("host,port,caster,operator,nmea,country,lat,long,link").split(",");
389
390 QStringList lines;
391 lines.clear();
392 _casterTable = new QTableWidget(this);
393
394 QUrl url;
395 url.setHost("www.rtcm-ntrip.org");
396 url.setPort(2101);
397 url.setScheme("http");
398 url.setPath("/");
399
400 bncNetQueryV2 query;
401 QByteArray outData;
402 query.waitForRequestResult(url, outData);
403 if (query.status() == bncNetQuery::finished) {
404 QTextStream in(outData);
405 QString line = in.readLine();
406 while ( !line.isNull() ) {
407 line = in.readLine();
408 if (line.indexOf("CAS") == 0) {
409 lines.append(line);
410 }
411 }
412 }
413 if (lines.size() > 0) {
414 _casterTable->setSelectionMode(QAbstractItemView::ExtendedSelection);
415 _casterTable->setSelectionBehavior(QAbstractItemView::SelectRows);
416
417 QStringList hlp = lines[0].split(";");
418 _casterTable->setColumnCount(hlp.size()-1);
419 _casterTable->setRowCount(lines.size());
420
421 QListIterator<QString> it(lines);
422 int nRow = -1;
423 while (it.hasNext()) {
424 QStringList columns = it.next().split(";");
425 ++nRow;
426 for (int ic = 0; ic < columns.size()-1; ic++) {
427 if (ic+1 == 5) { if (columns[ic+1] == "0") { columns[ic+1] = "no"; } else { columns[ic+1] = "yes"; }}
428 QTableWidgetItem* it = new QTableWidgetItem(columns[ic+1]);
429 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
430 _casterTable->setItem(nRow, ic, it);
431 }
432 }
433 }
434 _casterTable->sortItems(0);
435 _casterTable->setHorizontalHeaderLabels(labels);
436 _casterTable->setSortingEnabled(true);
437
438 int ww = QFontMetrics(this->font()).width('w');
439 _casterTable->horizontalHeader()->resizeSection(0,15*ww);
440 _casterTable->horizontalHeader()->resizeSection(1,5*ww);
441 _casterTable->horizontalHeader()->resizeSection(2,15*ww);
442 _casterTable->horizontalHeader()->resizeSection(3,15*ww);
443 _casterTable->horizontalHeader()->resizeSection(4,5*ww);
444 _casterTable->horizontalHeader()->resizeSection(5,7*ww);
445 _casterTable->horizontalHeader()->resizeSection(6,7*ww);
446 _casterTable->horizontalHeader()->resizeSection(7,7*ww);
447 _casterTable->horizontalHeader()->resizeSection(8,15*ww);
448
449 ww = QFontMetrics(font()).width('w');
450
451 QPushButton* _closeButton = new QPushButton("Cancel");
452 connect(_closeButton, SIGNAL(clicked()), this, SLOT(close()));
453 _closeButton->setMinimumWidth(8*ww);
454 _closeButton->setMaximumWidth(8*ww);
455
456 QPushButton* _okButton = new QPushButton(tr("OK"), this);
457 connect(_okButton, SIGNAL(clicked()), this, SLOT(slotAcceptCasterTable()));
458 _okButton->setMinimumWidth(8*ww);
459 _okButton->setMaximumWidth(8*ww);
460
461 QPushButton* _whatsThisCasterTableButton = new QPushButton(tr("Help=Shift+F1"), this);
462 connect(_whatsThisCasterTableButton, SIGNAL(clicked()), this, SLOT(slotWhatsThisCasterTable()));
463 _whatsThisCasterTableButton->setMinimumWidth(12*ww);
464 _whatsThisCasterTableButton->setMaximumWidth(12*ww);
465
466 _casterTable->setWhatsThis(tr("<p>Select an NTRIP broadcaster and hit 'OK'.</p><p>See http://www.rtcm-ntrip.org/home for further details on known NTRIP broadcaster installations.</u>."));
467
468 QGridLayout* dlgLayout = new QGridLayout();
469 dlgLayout->addWidget(new QLabel(" List of NTRIP Broadcasters from www.rtcm-ntrip.org"), 0,0,1,3,Qt::AlignLeft);
470 dlgLayout->addWidget(_casterTable, 1, 0, 1, 3);
471 dlgLayout->addWidget(_whatsThisCasterTableButton, 2, 0);
472 dlgLayout->addWidget(_closeButton, 2, 1, Qt::AlignRight);
473 dlgLayout->addWidget(_okButton, 2, 2);
474
475 setMinimumSize(600,400);
476 setWindowTitle(tr("Select Broadcaster"));
477 setLayout(dlgLayout);
478 resize(68*ww, 60*ww);
479 show();
480}
481
482// Caster table what's this
483////////////////////////////////////////////////////////////////////////////
484void bncCasterTableDlg:: slotWhatsThisCasterTable() {
485QWhatsThis::enterWhatsThisMode();
486}
487
488// Caster table destructor
489////////////////////////////////////////////////////////////////////////////
490bncCasterTableDlg::~bncCasterTableDlg() {
491 if (_casterTable) {
492 for (int ir = 0; ir < _casterTable->rowCount(); ir++) {
493 for (int ic = 0; ic < _casterTable->columnCount(); ic++) {
494 delete _casterTable->item(ir,ic);
495 }
496 }
497 }
498}
499
500// Accept caster table
501////////////////////////////////////////////////////////////////////////////
502void bncCasterTableDlg::slotAcceptCasterTable() {
503
504 QSettings settings;
505 QString* newCasterHost = new QString;
506 QString* newCasterPort = new QString;
507
508 if (_casterTable) {
509 for (int ir = 0; ir < _casterTable->rowCount(); ir++) {
510 QTableWidgetItem* item = _casterTable->item(ir,0);
511 for (int ic = 0; ic < _casterTable->columnCount(); ic++) {
512 if (_casterTable->isItemSelected(item)) {
513 if (ic == 0) {
514 newCasterHost->push_back(_casterTable->item(ir,0)->text());
515 }
516 if (ic == 1) {
517 newCasterPort->push_back(_casterTable->item(ir,1)->text());
518 }
519 }
520 }
521 }
522 }
523 emit newCaster(newCasterHost, newCasterPort);
524QDialog::accept();
525}
526
527// New caster selected
528////////////////////////////////////////////////////////////////////////////
529void bncTableDlg::slotNewCaster(QString* newCasterHost, QString* newCasterPort) {
530
531 const QString* newHost = new QString(*newCasterHost);
532 const QString* newPort = new QString(*newCasterPort);
533
534 _casterHostLineEdit->setItemText(0,newHost->toAscii().data());
535 _casterPortLineEdit->clear();
536 _casterPortLineEdit->insert(newPort->toAscii().data());
537}
538
Note: See TracBrowser for help on using the repository browser.