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

Last change on this file since 826 was 683, checked in by weber, 17 years ago

* empty log message *

File size: 14.1 KB
RevLine 
[280]1// Part of BNC, a utility for retrieving decoding and
[464]2// converting GNSS data streams from NTRIP broadcasters.
[280]3//
[464]4// Copyright (C) 2007
[280]5// German Federal Agency for Cartography and Geodesy (BKG)
6// http://www.bkg.bund.de
[464]7// Czech Technical University Prague, Department of Geodesy
[280]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.
[35]24
25/* -------------------------------------------------------------------------
[93]26 * BKG NTRIP Client
[35]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 "bnctabledlg.h"
42#include "bncgetthread.h"
43
44// Constructor
45////////////////////////////////////////////////////////////////////////////
[90]46bncTableDlg::bncTableDlg(QWidget* parent) : QDialog(parent) {
[35]47
48 setMinimumSize(600,400);
[237]49 setWindowTitle(tr("Add Mountpoints"));
[35]50
51 QVBoxLayout* mainLayout = new QVBoxLayout(this);
52
53 QSettings settings;
[88]54 _casterHostLineEdit = new QLineEdit(settings.value("casterHost").toString());
55 int ww = QFontMetrics(_casterHostLineEdit->font()).width('w');
56 _casterHostLineEdit->setMaximumWidth(18*ww);
57 _casterPortLineEdit = new QLineEdit(settings.value("casterPort").toString());
58 _casterPortLineEdit->setMaximumWidth(9*ww);
59 _casterUserLineEdit = new QLineEdit(settings.value("casterUser").toString());
60 _casterUserLineEdit->setMaximumWidth(9*ww);
61 _casterPasswordLineEdit = new QLineEdit(settings.value("casterPassword").toString());
62 _casterPasswordLineEdit->setMaximumWidth(9*ww);
63 _casterPasswordLineEdit->setEchoMode(QLineEdit::Password);
[683]64
65 // WhatsThis
66 // ---------
67 _casterUserLineEdit->setWhatsThis(tr("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. 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>."));
68 _casterPortLineEdit->setWhatsThis(tr("Enter the NTRIP broadcaster hostname or IP number and port number. <u>http://www.rtcm-ntrip.org/home</u> provides information about known NTRIP broadcaster installations. 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>."));
69 _casterHostLineEdit->setWhatsThis(tr("Enter the NTRIP broadcaster hostname or IP number and port number. <u>http://www.rtcm-ntrip.org/home</u> provides information about known NTRIP broadcaster installations. 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>."));
[682]70 _casterPasswordLineEdit->setWhatsThis(tr("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. Accounts are usually provided per NTRIP broadcaster through a registration procedure. 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>."));
[35]71
[88]72 QGridLayout* editLayout = new QGridLayout;
[105]73 editLayout->addWidget(new QLabel(tr("Caster host")), 0, 0);
74 editLayout->addWidget(_casterHostLineEdit, 0, 1);
75 editLayout->addWidget(new QLabel(tr("Caster port")), 0, 2);
76 editLayout->addWidget(_casterPortLineEdit, 0, 3);
77 editLayout->addWidget(new QLabel(tr("User")), 1, 0);
78 editLayout->addWidget(_casterUserLineEdit, 1, 1);
79 editLayout->addWidget(new QLabel(tr("Password")), 1, 2);
80 editLayout->addWidget(_casterPasswordLineEdit, 1, 3);
[88]81
[35]82 mainLayout->addLayout(editLayout);
83
84 _table = new QTableWidget(this);
[682]85 _table->setWhatsThis(tr("<p>Use the 'Get Table' button to download the sourcetable from the 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 fields 'format' and 'format-details'. 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. RTCM Version 2.x streams must contain message Type 18 and 19 while RTCM Version 3.x streams must contain GPS or SBAS message Type 1002 or 1004 and may contain GLONASS message types 1010 or 1012. See data field 'format-details' for available message types and their repetition rates in brackets.</p><p>Note that in order to produce RINEX Navigation files, RTCM Version 3.x streams containing message Type 1019 (GPS) and 1020 (GLONASS) or RTIGS streams are required.</p><p>The content of data field 'nmea' tells you whether a stream retrieval needs to be initiated by BNC by sending an NMEA-GGA message containing the user (or virtual reference station)'s coordinate.</p>"));
[195]86 connect(_table, SIGNAL(itemSelectionChanged()),
87 this, SLOT(slotSelectionChanged()));
[35]88 mainLayout->addWidget(_table);
89
[402]90 _buttonWhatsThis = new QPushButton(tr("Help=Shift+F1"), this);
[399]91 connect(_buttonWhatsThis, SIGNAL(clicked()), this, SLOT(slotWhatsThis()));
92
[195]93 _buttonGet = new QPushButton(tr("Get table"), this);
[399]94 _buttonGet->setDefault(true);
[35]95 connect(_buttonGet, SIGNAL(clicked()), this, SLOT(slotGetTable()));
[366]96
[35]97 _buttonCancel = new QPushButton(tr("Cancel"), this);
98 connect(_buttonCancel, SIGNAL(clicked()), this, SLOT(reject()));
99
100 _buttonOK = new QPushButton(tr("OK"), this);
101 connect(_buttonOK, SIGNAL(clicked()), this, SLOT(accept()));
102
103 QHBoxLayout* buttonLayout = new QHBoxLayout;
[399]104 buttonLayout->addWidget(_buttonWhatsThis);
[35]105 buttonLayout->addStretch(1);
106 buttonLayout->addWidget(_buttonGet);
107 buttonLayout->addWidget(_buttonCancel);
108 buttonLayout->addWidget(_buttonOK);
109
110 mainLayout->addLayout(buttonLayout);
111}
112
113// Destructor
114////////////////////////////////////////////////////////////////////////////
115bncTableDlg::~bncTableDlg() {
116 if (_table) {
117 for (int ir = 0; ir < _table->rowCount(); ir++) {
118 for (int ic = 0; ic < _table->columnCount(); ic++) {
119 delete _table->item(ir,ic);
120 }
121 }
122 }
123}
124
[191]125// Read Table the caster (static)
[35]126////////////////////////////////////////////////////////////////////////////
[191]127t_irc bncTableDlg::getFullTable(const QString& casterHost,
[298]128 int casterPort, QStringList& allLines,
129 bool alwaysRead) {
[35]130
[299]131 static QMutex mutex;
[298]132 static QMap<QString, QStringList> allTables;
133
[299]134 QMutexLocker locker(&mutex);
135
[298]136 if (!alwaysRead && allTables.find(casterHost) != allTables.end()) {
137 allLines = allTables.find(casterHost).value();
138 return success;
139 }
140
[191]141 allLines.clear();
142
[88]143 QUrl url;
[191]144 url.setHost(casterHost);
145 url.setPort(casterPort);
[35]146
147 // Send the Request
148 // ----------------
[136]149 const int timeOut = 10*1000;
[82]150 QString msg;
[366]151 QByteArray _latitude;
152 QByteArray _longitude;
153 QByteArray _nmea;
154 QTcpSocket* socket = bncGetThread::request(url, _latitude, _longitude, _nmea, timeOut, msg);
[88]155
[35]156 if (!socket) {
[191]157 return failure;
[35]158 }
159
160 // Read Caster Response
161 // --------------------
[473]162 bool proxyRespond = false;
[35]163 bool first = true;
164 while (true) {
165 if (socket->canReadLine()) {
166 QString line = socket->readLine();
[473]167
168 // Skip messages from proxy server
169 // -------------------------------
170 if (line.indexOf("SOURCETABLE 200 OK") == -1 &&
171 line.indexOf("200 OK") != -1 ) {
172 proxyRespond = true;
173 }
174 if (proxyRespond) {
175 if (line.trimmed().isEmpty()) {
176 proxyRespond = false;
177 }
178 continue;
179 }
180
[191]181 allLines.push_back(line);
[35]182 if (first) {
183 first = false;
184 if (line.indexOf("SOURCETABLE 200 OK") != 0) {
185 break;
186 }
187 }
188 else {
189 if (line.indexOf("ENDSOURCETABLE") == 0) {
190 break;
191 }
192 }
193 }
194 else {
195 socket->waitForReadyRead(timeOut);
196 if (socket->bytesAvailable() > 0) {
197 continue;
198 }
199 else {
200 break;
201 }
202 }
203 }
204 delete socket;
205
[298]206 allTables.insert(casterHost, allLines);
[191]207 return success;
208}
209
210// Read Table from Caster
211////////////////////////////////////////////////////////////////////////////
212void bncTableDlg::slotGetTable() {
213
[555]214 _buttonGet->setEnabled(false);
215
[196]216 _allLines.clear();
[191]217
218 if ( getFullTable(_casterHostLineEdit->text(),
219 _casterPortLineEdit->text().toInt(),
[196]220 _allLines) != success ) {
[191]221 QMessageBox::warning(0, "BNC", "Cannot retrieve table of data");
[645]222 _buttonGet->setEnabled(true);
[191]223 return;
224 }
225
226 QStringList lines;
[196]227 QStringListIterator it(_allLines);
[191]228 while (it.hasNext()) {
229 QString line = it.next();
230 if (line.indexOf("STR") == 0) {
231 lines.push_back(line);
232 }
233 }
234
[103]235 static const QStringList labels = QString("mountpoint,identifier,format,"
[371]236 "format-details,carrier,system,network,country,latitude,longitude,"
[410]237 "nmea,solution,generator,compress.,authentic.,fee,bitrate,"
[103]238 "misc").split(",");
239
[191]240 if (lines.size() > 0) {
[35]241 _table->setSelectionMode(QAbstractItemView::ExtendedSelection);
242 _table->setSelectionBehavior(QAbstractItemView::SelectRows);
243
[191]244 QStringList hlp = lines[0].split(";");
[35]245 _table->setColumnCount(hlp.size()-1);
[191]246 _table->setRowCount(lines.size());
[35]247
[191]248 QListIterator<QString> it(lines);
[35]249 int nRow = -1;
250 while (it.hasNext()) {
251 QStringList columns = it.next().split(";");
252 ++nRow;
253 for (int ic = 0; ic < columns.size()-1; ic++) {
[366]254
[410]255 if (ic+1 == 11) { if (columns[ic+1] == "0") { columns[ic+1] = "no"; } else { columns[ic+1] = "yes"; }}
[366]256
[107]257 QTableWidgetItem* it = new QTableWidgetItem(columns[ic+1]);
[115]258 it->setFlags(it->flags() & ~Qt::ItemIsEditable);
[107]259 _table->setItem(nRow, ic, it);
[35]260 }
261 }
[83]262 _table->sortItems(0);
[103]263 _table->setHorizontalHeaderLabels(labels);
[104]264 _table->setSortingEnabled(true);
[371]265
266 int ww = QFontMetrics(this->font()).width('w');
[375]267 _table->horizontalHeader()->resizeSection(0,10*ww);
[371]268 _table->horizontalHeader()->resizeSection(2,8*ww);
269 _table->horizontalHeader()->resizeSection(3,15*ww);
270 _table->horizontalHeader()->resizeSection(4,8*ww);
271 _table->horizontalHeader()->resizeSection(5,8*ww);
272 _table->horizontalHeader()->resizeSection(6,8*ww);
273 _table->horizontalHeader()->resizeSection(7,8*ww);
274 _table->horizontalHeader()->resizeSection(8,8*ww);
275 _table->horizontalHeader()->resizeSection(9,8*ww);
276 _table->horizontalHeader()->resizeSection(10,8*ww);
277 _table->horizontalHeader()->resizeSection(11,8*ww);
278 _table->horizontalHeader()->resizeSection(12,15*ww);
279 _table->horizontalHeader()->resizeSection(13,8*ww);
280 _table->horizontalHeader()->resizeSection(14,8*ww);
281 _table->horizontalHeader()->resizeSection(15,8*ww);
282 _table->horizontalHeader()->resizeSection(16,8*ww);
283 _table->horizontalHeader()->resizeSection(17,15*ww);
[35]284 }
285}
286
287// Accept slot
288////////////////////////////////////////////////////////////////////////////
289void bncTableDlg::accept() {
290
291 QSettings settings;
292 settings.setValue("casterHost", _casterHostLineEdit->text());
293 settings.setValue("casterPort", _casterPortLineEdit->text());
[88]294 settings.setValue("casterUser", _casterUserLineEdit->text());
295 settings.setValue("casterPassword", _casterPasswordLineEdit->text());
[35]296
297 QStringList* mountPoints = new QStringList;
298
299 if (_table) {
300 for (int ir = 0; ir < _table->rowCount(); ir++) {
[59]301 QTableWidgetItem* item = _table->item(ir,0);
302 QString format = _table->item(ir,2)->text();
[366]303 QString latitude = _table->item(ir,8)->text();
304 QString longitude = _table->item(ir,9)->text();
305 QString nmea = _table->item(ir,10)->text();
[59]306 format.replace(" ", "_");
[35]307 if (_table->isItemSelected(item)) {
308 QUrl url;
[444]309 url.setUserName(QUrl::toPercentEncoding(_casterUserLineEdit->text()));
310 url.setPassword(QUrl::toPercentEncoding(_casterPasswordLineEdit->text()));
[35]311 url.setHost(_casterHostLineEdit->text());
312 url.setPort(_casterPortLineEdit->text().toInt());
313 url.setPath(item->text());
[59]314
[366]315 mountPoints->push_back(url.toString() + " " + format + " " + latitude + " " + longitude + " " + nmea);
[35]316 }
317 }
318 }
319 emit newMountPoints(mountPoints);
320
321 QDialog::accept();
322}
[195]323
324// User changed the selection of mountPoints
325////////////////////////////////////////////////////////////////////////////
326void bncTableDlg::slotSelectionChanged() {
327 if (_table->selectedItems().isEmpty()) {
328 }
329}
330
[196]331// Create RINEX skeleton header
[195]332////////////////////////////////////////////////////////////////////////////
333void bncTableDlg::slotSkl() {
334
[196]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();
[195]340
[196]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
[197]354 if (!ftpDir.isEmpty()) {
355 QUrl url(ftpDir);
356 QMessageBox::warning(0, "Warning", url.host() + "\n" + url.path() +
357 "\nnot yet implemented");
358 }
[196]359 }
360 }
[197]361}
[196]362
[399]363// Whats This Help
364void bncTableDlg::slotWhatsThis() {
365QWhatsThis::enterWhatsThisMode();
366}
367
368
Note: See TracBrowser for help on using the repository browser.