CommConfigurationWindow.cc 11.6 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 46 47 48
#ifdef XBEELINK
#include "XbeeLink.h"
#include "XbeeConfigurationWindow.h"
#endif // XBEELINK
49 50
#ifdef OPAL_RT
#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"
56
#include "LinkManager.h"
oberion's avatar
oberion committed
57
#include "MainWindow.h"
pixhawk's avatar
pixhawk committed
58

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

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

66 67 68 69 70
    // Initialize basic ui state

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

    // Connect UI element visibility to checkbox
74 75 76 77 78 79 80 81
    //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)));
82

83
    // add link types
84 85
    ui.linkType->addItem(tr("Serial"), QGC_LINK_SERIAL);
    ui.linkType->addItem(tr("UDP"), QGC_LINK_UDP);
Don Gagne's avatar
Don Gagne committed
86
    ui.linkType->addItem(tr("TCP"), QGC_LINK_TCP);
87 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);
    }

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

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

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

123

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

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

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

198
    connect(ui.linkType,SIGNAL(currentIndexChanged(int)),this,SLOT(linkCurrentIndexChanged(int)));
199

pixhawk's avatar
pixhawk committed
200 201
    // Open details pane for MAVLink if necessary
    MAVLinkProtocol* mavlink = dynamic_cast<MAVLinkProtocol*>(protocol);
202
    if (mavlink != 0) {
pixhawk's avatar
pixhawk committed
203
        QWidget* conf = new MAVLinkSettingsWidget(mavlink, this);
lm's avatar
lm committed
204
        ui.protocolScrollArea->setWidget(conf);
205
        ui.protocolGroupBox->setTitle(protocol->getName()+" (Global Settings)");
206
    } else {
pixhawk's avatar
pixhawk committed
207 208 209 210 211 212 213 214 215 216 217
        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();
}

218 219
CommConfigurationWindow::~CommConfigurationWindow()
{
pixhawk's avatar
pixhawk committed
220 221 222 223 224 225 226 227

}

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

228 229 230 231 232 233
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
234
{
oberion's avatar
oberion committed
235 236 237 238 239 240 241 242 243 244
	if(link->isConnected())
	{
		// close old configuration window
		this->window()->close();
	}
	else
	{
		// delete old configuration window
		this->remove();
	}
oberion's avatar
oberion committed
245

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

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

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

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

310 311 312 313 314
void CommConfigurationWindow::setProtocol(int protocol)
{
    qDebug() << "Changing to protocol" << protocol;
}

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

void CommConfigurationWindow::setLinkName(QString name)
{
330 331 332
    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
333 334 335 336
}

void CommConfigurationWindow::remove()
{
337 338 339
    if(action) delete action; //delete action first since it has a pointer to link
    action=NULL;

340
    if(link) {
341 342 343 344
        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
345
        link->deleteLater();
346 347 348
    }
    link=NULL;

pixhawk's avatar
pixhawk committed
349
    this->window()->close();
350
    this->deleteLater();
pixhawk's avatar
pixhawk committed
351 352 353 354 355
}

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