CommConfigurationWindow.cc 11.9 KB
Newer Older
pixhawk's avatar
pixhawk committed
1 2
/*=====================================================================

lm's avatar
lm committed
3
QGroundControl Open Source Ground Control Station
pixhawk's avatar
pixhawk committed
4

lm's avatar
lm committed
5
(c) 2009, 2010 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
pixhawk's avatar
pixhawk committed
6

lm's avatar
lm committed
7
This file is part of the QGROUNDCONTROL project
pixhawk's avatar
pixhawk committed
8

lm's avatar
lm committed
9
    QGROUNDCONTROL is free software: you can redistribute it and/or modify
pixhawk's avatar
pixhawk committed
10 11 12 13
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

lm's avatar
lm committed
14
    QGROUNDCONTROL is distributed in the hope that it will be useful,
pixhawk's avatar
pixhawk committed
15 16 17 18 19
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
lm's avatar
lm committed
20
    along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
pixhawk's avatar
pixhawk committed
21 22 23 24 25

======================================================================*/

/**
 * @file
lm's avatar
lm committed
26
 *   @brief Implementation of CommConfigurationWindow
pixhawk's avatar
pixhawk committed
27 28 29 30 31 32 33 34 35 36 37 38 39 40
 *
 *   @author Lorenz Meier <mavteam@student.ethz.ch>
 *
 */

#include <QDebug>

#include <QDir>
#include <QFileInfoList>
#include <QBoxLayout>
#include <QWidget>

#include "CommConfigurationWindow.h"
#include "SerialConfigurationWindow.h"
41
#include "SerialLink.h"
pixhawk's avatar
pixhawk committed
42
#include "UDPLink.h"
Don Gagne's avatar
Don Gagne committed
43
#include "TCPLink.h"
44
#include "MAVLinkSimulationLink.h"
45
#ifdef QGC_XBEE_ENABLED
46 47
#include "XbeeLink.h"
#include "XbeeConfigurationWindow.h"
48
#endif // QGC_XBEE_ENABLED
49
#ifdef QGC_RTLAB_ENABLED
50
#include "OpalLink.h"
51
#include "OpalLinkConfigurationWindow.h"
52
#endif
pixhawk's avatar
pixhawk committed
53 54
#include "MAVLinkProtocol.h"
#include "MAVLinkSettingsWidget.h"
55
#include "QGCUDPLinkConfiguration.h"
Don Gagne's avatar
Don Gagne committed
56
#include "QGCTCPLinkConfiguration.h"
57
#include "LinkManager.h"
oberion's avatar
oberion committed
58
#include "MainWindow.h"
pixhawk's avatar
pixhawk committed
59

60
CommConfigurationWindow::CommConfigurationWindow(LinkInterface* link, ProtocolInterface* protocol, QWidget *parent) : QDialog(parent)
pixhawk's avatar
pixhawk committed
61 62 63 64 65 66
{
    this->link = link;

    // Setup the user interface according to link type
    ui.setupUi(this);

67 68 69 70 71
    // Initialize basic ui state

    // Do not allow changes here unless advanced is checked
    ui.connectionType->setEnabled(false);
    ui.protocolGroupBox->setVisible(false);
72
    ui.protocolTypeGroupBox->setVisible(false);
73 74

    // Connect UI element visibility to checkbox
75 76 77 78 79 80 81 82
    //connect(ui.advancedOptionsCheckBox, SIGNAL(clicked(bool)), ui.connectionType, SLOT(setEnabled(bool)));
    //connect(ui.advancedOptionsCheckBox, SIGNAL(clicked(bool)), ui.linkType, SLOT(setEnabled(bool)));
    //connect(ui.advancedOptionsCheckBox, SIGNAL(clicked(bool)), ui.protocolGroupBox, SLOT(setVisible(bool)));
    ui.advancedOptionsCheckBox->setVisible(false);
    //connect(ui.advCheckBox,SIGNAL(clicked(bool)),ui.advancedOptionsCheckBox,SLOT(setChecked(bool)));
    connect(ui.advCheckBox,SIGNAL(clicked(bool)),ui.protocolTypeGroupBox,SLOT(setVisible(bool)));
    connect(ui.advCheckBox, SIGNAL(clicked(bool)), ui.connectionType, SLOT(setEnabled(bool)));
    connect(ui.advCheckBox, SIGNAL(clicked(bool)), ui.protocolGroupBox, SLOT(setVisible(bool)));
83

84
    // add link types
85 86
    ui.linkType->addItem(tr("Serial"), QGC_LINK_SERIAL);
    ui.linkType->addItem(tr("UDP"), QGC_LINK_UDP);
Don Gagne's avatar
Don Gagne committed
87
    ui.linkType->addItem(tr("TCP"), QGC_LINK_TCP);
88 89 90 91 92
    if(dynamic_cast<MAVLinkSimulationLink*>(link)) {
        //Only show simulation option if already setup elsewhere as a simulation
        ui.linkType->addItem(tr("Simulation"), QGC_LINK_SIMULATION);
    }

93
#ifdef QGC_RTLAB_ENABLED
94
    ui.linkType->addItem(tr("Opal-RT Link"), QGC_LINK_OPAL);
95
#endif
96
#ifdef QGC_XBEE_ENABLED
97
	ui.linkType->addItem(tr("Xbee API"),QGC_LINK_XBEE);
98
#endif // QGC_XBEE_ENABLED
99
    ui.linkType->setEditable(false);
100 101

    ui.connectionType->addItem("MAVLink", QGC_PROTOCOL_MAVLINK);
102

pixhawk's avatar
pixhawk committed
103 104 105
    // Create action to open this menu
    // Create configuration action for this link
    // Connect the current UAS
106
    action = new QAction(QIcon(":/files/images/devices/network-wireless.svg"), "", this);
107
    LinkManager::instance()->add(link);
oberion's avatar
oberion committed
108
	action->setData(link->getId());
109 110
    action->setEnabled(true);
    action->setVisible(true);
pixhawk's avatar
pixhawk committed
111 112 113 114 115 116 117 118 119 120 121 122 123
    setLinkName(link->getName());
    connect(action, SIGNAL(triggered()), this, SLOT(show()));

    // Make sure that a change in the link name will be reflected in the UI
    connect(link, SIGNAL(nameChanged(QString)), this, SLOT(setLinkName(QString)));

    // Setup user actions and link notifications
    connect(ui.connectButton, SIGNAL(clicked()), this, SLOT(setConnection()));
    connect(ui.closeButton, SIGNAL(clicked()), this->window(), SLOT(close()));
    connect(ui.deleteButton, SIGNAL(clicked()), this, SLOT(remove()));

    connect(this->link, SIGNAL(connected(bool)), this, SLOT(connectionState(bool)));

124

pixhawk's avatar
pixhawk committed
125 126 127 128
    // Fill in the current data
    if(this->link->isConnected()) ui.connectButton->setChecked(true);
    //connect(this->link, SIGNAL(connected(bool)), ui.connectButton, SLOT(setChecked(bool)));

129
    if(this->link->isConnected()) {
pixhawk's avatar
pixhawk committed
130 131 132
        ui.connectionStatusLabel->setText(tr("Connected"));

        // TODO Deactivate all settings to force user to manually disconnect first
133
    } else {
pixhawk's avatar
pixhawk committed
134 135 136 137 138 139
        ui.connectionStatusLabel->setText(tr("Disconnected"));
    }

    // TODO Move these calls to each link so that dynamic casts vanish

    // Open details pane for serial link if necessary
140
    SerialLink* serial = dynamic_cast<SerialLink*>(link);
141
    if(serial != 0) {
pixhawk's avatar
pixhawk committed
142
        QWidget* conf = new SerialConfigurationWindow(serial, this);
lm's avatar
lm committed
143
        ui.linkScrollArea->setWidget(conf);
144
        ui.linkGroupBox->setTitle(tr("Serial Link"));
145
        ui.linkType->setCurrentIndex(ui.linkType->findData(QGC_LINK_SERIAL));
pixhawk's avatar
pixhawk committed
146
    }
147
    UDPLink* udp = dynamic_cast<UDPLink*>(link);
148
    if (udp != 0) {
149
        QWidget* conf = new QGCUDPLinkConfiguration(udp, this);
lm's avatar
lm committed
150
        ui.linkScrollArea->setWidget(conf);
151
        ui.linkGroupBox->setTitle(tr("UDP Link"));
152
        ui.linkType->setCurrentIndex(ui.linkType->findData(QGC_LINK_UDP));
pixhawk's avatar
pixhawk committed
153
    }
Don Gagne's avatar
Don Gagne committed
154 155
    TCPLink* tcp = dynamic_cast<TCPLink*>(link);
    if (tcp != 0) {
Don Gagne's avatar
Don Gagne committed
156 157
        QWidget* conf = new QGCTCPLinkConfiguration(tcp, this);
        ui.linkScrollArea->setWidget(conf);
Don Gagne's avatar
Don Gagne committed
158 159 160
        ui.linkGroupBox->setTitle(tr("TCP Link"));
        ui.linkType->setCurrentIndex(ui.linkType->findData(QGC_LINK_TCP));
    }
161
    MAVLinkSimulationLink* sim = dynamic_cast<MAVLinkSimulationLink*>(link);
162
    if (sim != 0) {
163 164
        ui.linkType->setCurrentIndex(ui.linkType->findData(QGC_LINK_SIMULATION));
        ui.linkType->setEnabled(false); //Don't allow the user to change to a non-simulation
165 166
        ui.linkGroupBox->setTitle(tr("MAVLink Simulation Link"));
    }
167
#ifdef QGC_RTLAB_ENABLED
168
    OpalLink* opal = dynamic_cast<OpalLink*>(link);
169
    if (opal != 0) {
170 171 172 173
        QWidget* conf = new OpalLinkConfigurationWindow(opal, this);
        QBoxLayout* layout = new QBoxLayout(QBoxLayout::LeftToRight, ui.linkGroupBox);
        layout->addWidget(conf);
        ui.linkGroupBox->setLayout(layout);
174
        ui.linkType->setCurrentIndex(ui.linkType->findData(QGC_LINK_OPAL));
175 176 177
        ui.linkGroupBox->setTitle(tr("Opal-RT Link"));
    }
#endif
178
#ifdef QGC_XBEE_ENABLED
179 180 181 182 183 184
	XbeeLink* xbee = dynamic_cast<XbeeLink*>(link); // new Konrad
	if(xbee != 0)
	{
		QWidget* conf = new XbeeConfigurationWindow(xbee,this); 
		ui.linkScrollArea->setWidget(conf);
		ui.linkGroupBox->setTitle(tr("Xbee Link"));
185
        ui.linkType->setCurrentIndex(ui.linkType->findData(QGC_LINK_XBEE));
oberion's avatar
oberion committed
186 187
		connect(xbee,SIGNAL(tryConnectBegin(bool)),ui.actionConnect,SLOT(setDisabled(bool)));
		connect(xbee,SIGNAL(tryConnectEnd(bool)),ui.actionConnect,SLOT(setEnabled(bool)));
188
	}
189
#endif // QGC_XBEE_ENABLED
Don Gagne's avatar
Don Gagne committed
190
    if (serial == 0 && udp == 0 && sim == 0 && tcp == 0
191
#ifdef QGC_RTLAB_ENABLED
192
            && opal == 0
193
#endif
194
#ifdef QGC_XBEE_ENABLED
195
			&& xbee == 0
196
#endif // QGC_XBEE_ENABLED
197
       ) {
pixhawk's avatar
pixhawk committed
198 199 200
        qDebug() << "Link is NOT a known link, can't open configuration window";
    }

201
    connect(ui.linkType,SIGNAL(currentIndexChanged(int)),this,SLOT(linkCurrentIndexChanged(int)));
202

pixhawk's avatar
pixhawk committed
203 204
    // Open details pane for MAVLink if necessary
    MAVLinkProtocol* mavlink = dynamic_cast<MAVLinkProtocol*>(protocol);
205
    if (mavlink != 0) {
pixhawk's avatar
pixhawk committed
206
        QWidget* conf = new MAVLinkSettingsWidget(mavlink, this);
lm's avatar
lm committed
207
        ui.protocolScrollArea->setWidget(conf);
208
        ui.protocolGroupBox->setTitle(protocol->getName()+" (Global Settings)");
209
    } else {
pixhawk's avatar
pixhawk committed
210 211 212 213 214 215 216 217 218 219 220
        qDebug() << "Protocol is NOT MAVLink, can't open configuration window";
    }

    // Open details for UDP link if necessary
    // TODO

    // Display the widget
    this->window()->setWindowTitle(tr("Settings for ") + this->link->getName());
    this->hide();
}

221 222
CommConfigurationWindow::~CommConfigurationWindow()
{
pixhawk's avatar
pixhawk committed
223 224 225 226 227 228 229 230

}

QAction* CommConfigurationWindow::getAction()
{
    return action;
}

231 232 233 234 235 236
void CommConfigurationWindow::linkCurrentIndexChanged(int currentIndex)
{
    setLinkType(static_cast<qgc_link_t>(ui.linkType->itemData(currentIndex).toInt()));
}

void CommConfigurationWindow::setLinkType(qgc_link_t linktype)
pixhawk's avatar
pixhawk committed
237
{
oberion's avatar
oberion committed
238 239 240 241 242 243 244 245 246 247
	if(link->isConnected())
	{
		// close old configuration window
		this->window()->close();
	}
	else
	{
		// delete old configuration window
		this->remove();
	}
oberion's avatar
oberion committed
248

oberion's avatar
oberion committed
249
	LinkInterface *tmpLink(NULL);
250 251
	switch(linktype)
	{
252
#ifdef QGC_XBEE_ENABLED
253
        case QGC_LINK_XBEE:
254 255
			{
				XbeeLink *xbee = new XbeeLink();
oberion's avatar
oberion committed
256 257
				tmpLink = xbee;
				MainWindow::instance()->addLink(tmpLink);
258 259
				break;
			}
260
#endif // QGC_XBEE_ENABLED
261
        case QGC_LINK_UDP:
262 263 264 265 266 267
			{
				UDPLink *udp = new UDPLink();
				tmpLink = udp;
				MainWindow::instance()->addLink(tmpLink);
				break;
			}
oberion's avatar
oberion committed
268
			
Don Gagne's avatar
Don Gagne committed
269
        case QGC_LINK_TCP:
Don Gagne's avatar
Don Gagne committed
270
            {
Don Gagne's avatar
Don Gagne committed
271 272 273 274
            TCPLink *tcp = new TCPLink();
            tmpLink = tcp;
            MainWindow::instance()->addLink(tmpLink);
            break;
Don Gagne's avatar
Don Gagne committed
275
            }
Don Gagne's avatar
Don Gagne committed
276

277
#ifdef QGC_RTLAB_ENABLED
278
        case QGC_LINK_OPAL:
279 280 281 282 283 284
			{
				OpalLink* opal = new OpalLink();
				tmpLink = opal;
				MainWindow::instance()->addLink(tmpLink);
				break;
			}
285
#endif // QGC_RTLAB_ENABLED
286
		default:
oberion's avatar
oberion committed
287
			{
288
			}
289
        case QGC_LINK_SERIAL:
290 291 292 293
			{
				SerialLink *serial = new SerialLink();
				tmpLink = serial;
				MainWindow::instance()->addLink(tmpLink);
oberion's avatar
oberion committed
294 295
				break;
			}
296
	}
oberion's avatar
oberion committed
297
	// trigger new window
oberion's avatar
oberion committed
298 299 300 301

	const int32_t& linkIndex(LinkManager::instance()->getLinks().indexOf(tmpLink));
	const int32_t& linkID(LinkManager::instance()->getLinks()[linkIndex]->getId());

oberion's avatar
oberion committed
302 303 304
	QList<QAction*> actions = MainWindow::instance()->listLinkMenuActions();
	foreach (QAction* act, actions) 
	{
oberion's avatar
oberion committed
305
        if (act->data().toInt() == linkID) 
lm's avatar
lm committed
306
        {
oberion's avatar
oberion committed
307 308 309 310
            act->trigger();
            break;
        }
    }
pixhawk's avatar
pixhawk committed
311 312
}

313 314 315 316 317
void CommConfigurationWindow::setProtocol(int protocol)
{
    qDebug() << "Changing to protocol" << protocol;
}

pixhawk's avatar
pixhawk committed
318 319
void CommConfigurationWindow::setConnection()
{
320
    if(!link->isConnected()) {
pixhawk's avatar
pixhawk committed
321
        link->connect();
322 323 324 325
        QGC::SLEEP::msleep(100);
        if (link->isConnected())
            // Auto-close window on connect
            this->window()->close();
326
    } else {
pixhawk's avatar
pixhawk committed
327 328 329 330 331 332
        link->disconnect();
    }
}

void CommConfigurationWindow::setLinkName(QString name)
{
333 334 335
    action->setText(tr("%1 Settings").arg(name));
    action->setStatusTip(tr("Adjust setting for link %1").arg(name));
    this->window()->setWindowTitle(tr("Settings for %1").arg(name));
pixhawk's avatar
pixhawk committed
336 337 338 339
}

void CommConfigurationWindow::remove()
{
340 341 342
    if(action) delete action; //delete action first since it has a pointer to link
    action=NULL;

343
    if(link) {
344 345 346 347
        LinkManager::instance()->removeLink(link); //remove link from LinkManager list
        link->disconnect(); //disconnect port, and also calls terminate() to stop the thread
        if (link->isRunning()) link->terminate(); // terminate() the serial thread just in case it is still running
        link->wait(); // wait() until thread is stoped before deleting
348
        link->deleteLater();
349 350 351
    }
    link=NULL;

pixhawk's avatar
pixhawk committed
352
    this->window()->close();
353
    this->deleteLater();
pixhawk's avatar
pixhawk committed
354 355 356 357 358
}

void CommConfigurationWindow::connectionState(bool connect)
{
    ui.connectButton->setChecked(connect);
359
    if(connect) {
pixhawk's avatar
pixhawk committed
360 361
        ui.connectionStatusLabel->setText(tr("Connected"));
        ui.connectButton->setText(tr("Disconnect"));
362
    } else {
pixhawk's avatar
pixhawk committed
363 364 365 366
        ui.connectionStatusLabel->setText(tr("Disconnected"));
        ui.connectButton->setText(tr("Connect"));
    }
}