CommConfigurationWindow.cc 10.2 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"
43
#include "MAVLinkSimulationLink.h"
44 45 46 47
#ifdef XBEELINK
#include "XbeeLink.h"
#include "XbeeConfigurationWindow.h"
#endif // XBEELINK
48 49
#ifdef OPAL_RT
#include "OpalLink.h"
50
#include "OpalLinkConfigurationWindow.h"
51
#endif
pixhawk's avatar
pixhawk committed
52 53
#include "MAVLinkProtocol.h"
#include "MAVLinkSettingsWidget.h"
54
#include "QGCUDPLinkConfiguration.h"
55
#include "LinkManager.h"
oberion's avatar
oberion committed
56
#include "MainWindow.h"
pixhawk's avatar
pixhawk committed
57

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

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

65 66 67 68 69
    // Center the window on the screen.
    QRect position = frameGeometry();
    position.moveCenter(QDesktopWidget().availableGeometry().center());
    move(position.topLeft());

70 71 72 73 74 75 76 77 78 79 80 81
    // Initialize basic ui state

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

    // Connect UI element visibility to checkbox
    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)));

82
    // add link types
83 84 85 86
    ui.linkType->addItem(tr("Serial"), QGC_LINK_SERIAL);
    ui.linkType->addItem(tr("UDP"), QGC_LINK_UDP);
    ui.linkType->addItem(tr("Simulation"), QGC_LINK_SIMULATION);
    ui.linkType->addItem(tr("Opal-RT Link"), QGC_LINK_OPAL);
87 88 89
#ifdef XBEELINK
	ui.linkType->addItem(tr("Xbee API"),QGC_LINK_XBEE);
#endif // XBEELINK
90
    ui.linkType->setEditable(false);
91 92

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

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

115

pixhawk's avatar
pixhawk committed
116 117 118 119
    // Fill in the current data
    if(this->link->isConnected()) ui.connectButton->setChecked(true);
    //connect(this->link, SIGNAL(connected(bool)), ui.connectButton, SLOT(setChecked(bool)));

120
    if(this->link->isConnected()) {
pixhawk's avatar
pixhawk committed
121 122 123
        ui.connectionStatusLabel->setText(tr("Connected"));

        // TODO Deactivate all settings to force user to manually disconnect first
124
    } else {
pixhawk's avatar
pixhawk committed
125 126 127 128 129 130
        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
131
    SerialLink* serial = dynamic_cast<SerialLink*>(link);
132
    if(serial != 0) {
pixhawk's avatar
pixhawk committed
133
        QWidget* conf = new SerialConfigurationWindow(serial, this);
lm's avatar
lm committed
134
        ui.linkScrollArea->setWidget(conf);
135
        ui.linkGroupBox->setTitle(tr("Serial Link"));
136
        ui.linkType->setCurrentIndex(0);
pixhawk's avatar
pixhawk committed
137
    }
138
    UDPLink* udp = dynamic_cast<UDPLink*>(link);
139
    if (udp != 0) {
140
        QWidget* conf = new QGCUDPLinkConfiguration(udp, this);
lm's avatar
lm committed
141
        ui.linkScrollArea->setWidget(conf);
142
        ui.linkGroupBox->setTitle(tr("UDP Link"));
143
        ui.linkType->setCurrentIndex(1);
pixhawk's avatar
pixhawk committed
144
    }
145
    MAVLinkSimulationLink* sim = dynamic_cast<MAVLinkSimulationLink*>(link);
146
    if (sim != 0) {
147
        ui.linkType->setCurrentIndex(2);
148 149
        ui.linkGroupBox->setTitle(tr("MAVLink Simulation Link"));
    }
150
#ifdef OPAL_RT
151
    OpalLink* opal = dynamic_cast<OpalLink*>(link);
152
    if (opal != 0) {
153 154 155 156
        QWidget* conf = new OpalLinkConfigurationWindow(opal, this);
        QBoxLayout* layout = new QBoxLayout(QBoxLayout::LeftToRight, ui.linkGroupBox);
        layout->addWidget(conf);
        ui.linkGroupBox->setLayout(layout);
157
        ui.linkType->setCurrentIndex(3);
158 159 160
        ui.linkGroupBox->setTitle(tr("Opal-RT Link"));
    }
#endif
161 162 163 164 165 166 167
#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"));
oberion's avatar
oberion committed
168
		ui.linkType->setCurrentIndex(4);
oberion's avatar
oberion committed
169 170
		connect(xbee,SIGNAL(tryConnectBegin(bool)),ui.actionConnect,SLOT(setDisabled(bool)));
		connect(xbee,SIGNAL(tryConnectEnd(bool)),ui.actionConnect,SLOT(setEnabled(bool)));
171 172
	}
#endif // XBEELINK
173 174
    if (serial == 0 && udp == 0 && sim == 0
#ifdef OPAL_RT
175
            && opal == 0
176
#endif
177 178 179
#ifdef XBEELINK
			&& xbee == 0
#endif // XBEELINK
180
       ) {
pixhawk's avatar
pixhawk committed
181 182 183
        qDebug() << "Link is NOT a known link, can't open configuration window";
    }

oberion's avatar
oberion committed
184 185 186
#ifdef XBEELINK
	connect(ui.linkType,SIGNAL(currentIndexChanged(int)),this,SLOT(setLinkType(int)));
#endif // XBEELINK
187

pixhawk's avatar
pixhawk committed
188 189
    // Open details pane for MAVLink if necessary
    MAVLinkProtocol* mavlink = dynamic_cast<MAVLinkProtocol*>(protocol);
190
    if (mavlink != 0) {
pixhawk's avatar
pixhawk committed
191
        QWidget* conf = new MAVLinkSettingsWidget(mavlink, this);
lm's avatar
lm committed
192
        ui.protocolScrollArea->setWidget(conf);
193
        ui.protocolGroupBox->setTitle(protocol->getName()+" (Global Settings)");
194
    } else {
pixhawk's avatar
pixhawk committed
195 196 197 198 199 200 201 202 203 204 205
        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();
}

206 207
CommConfigurationWindow::~CommConfigurationWindow()
{
pixhawk's avatar
pixhawk committed
208 209 210 211 212 213 214 215 216 217

}

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

void CommConfigurationWindow::setLinkType(int linktype)
{
oberion's avatar
oberion committed
218 219 220 221 222 223 224 225 226 227
	if(link->isConnected())
	{
		// close old configuration window
		this->window()->close();
	}
	else
	{
		// delete old configuration window
		this->remove();
	}
oberion's avatar
oberion committed
228

oberion's avatar
oberion committed
229
	LinkInterface *tmpLink(NULL);
230 231
	switch(linktype)
	{
232
#ifdef XBEELINK
233 234 235
		case 4:
			{
				XbeeLink *xbee = new XbeeLink();
oberion's avatar
oberion committed
236 237
				tmpLink = xbee;
				MainWindow::instance()->addLink(tmpLink);
238 239
				break;
			}
240
#endif // XBEELINK
oberion's avatar
oberion committed
241
		case 1:
242 243 244 245 246 247
			{
				UDPLink *udp = new UDPLink();
				tmpLink = udp;
				MainWindow::instance()->addLink(tmpLink);
				break;
			}
oberion's avatar
oberion committed
248
			
249 250 251 252 253 254 255 256 257
#ifdef OPAL_RT
		case 3:
			{
				OpalLink* opal = new OpalLink();
				tmpLink = opal;
				MainWindow::instance()->addLink(tmpLink);
				break;
			}
#endif // OPAL_RT
258
		default:
oberion's avatar
oberion committed
259
			{
260 261 262 263 264 265
			}
		case 0:
			{
				SerialLink *serial = new SerialLink();
				tmpLink = serial;
				MainWindow::instance()->addLink(tmpLink);
oberion's avatar
oberion committed
266 267
				break;
			}
268
	}
oberion's avatar
oberion committed
269
	// trigger new window
oberion's avatar
oberion committed
270 271 272 273

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

oberion's avatar
oberion committed
274 275 276
	QList<QAction*> actions = MainWindow::instance()->listLinkMenuActions();
	foreach (QAction* act, actions) 
	{
oberion's avatar
oberion committed
277
        if (act->data().toInt() == linkID) 
lm's avatar
lm committed
278
        {
oberion's avatar
oberion committed
279 280 281 282
            act->trigger();
            break;
        }
    }
pixhawk's avatar
pixhawk committed
283 284
}

285 286 287 288 289
void CommConfigurationWindow::setProtocol(int protocol)
{
    qDebug() << "Changing to protocol" << protocol;
}

pixhawk's avatar
pixhawk committed
290 291
void CommConfigurationWindow::setConnection()
{
292
    if(!link->isConnected()) {
pixhawk's avatar
pixhawk committed
293
        link->connect();
294 295 296 297
        QGC::SLEEP::msleep(100);
        if (link->isConnected())
            // Auto-close window on connect
            this->window()->close();
298
    } else {
pixhawk's avatar
pixhawk committed
299 300 301 302 303 304
        link->disconnect();
    }
}

void CommConfigurationWindow::setLinkName(QString name)
{
305 306 307
    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
308 309 310 311
}

void CommConfigurationWindow::remove()
{
312 313 314
    if(action) delete action; //delete action first since it has a pointer to link
    action=NULL;

315
    if(link) {
316 317 318 319
        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
320
        link->deleteLater();
321 322 323
    }
    link=NULL;

pixhawk's avatar
pixhawk committed
324
    this->window()->close();
325
    this->deleteLater();
pixhawk's avatar
pixhawk committed
326 327 328 329 330
}

void CommConfigurationWindow::connectionState(bool connect)
{
    ui.connectButton->setChecked(connect);
331
    if(connect) {
pixhawk's avatar
pixhawk committed
332 333
        ui.connectionStatusLabel->setText(tr("Connected"));
        ui.connectButton->setText(tr("Disconnect"));
334
    } else {
pixhawk's avatar
pixhawk committed
335 336 337 338
        ui.connectionStatusLabel->setText(tr("Disconnected"));
        ui.connectButton->setText(tr("Connect"));
    }
}