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

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

* empty log message *

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