2010-03-21 14:44:00 +01:00
|
|
|
/**
|
|
|
|
******************************************************************************
|
|
|
|
*
|
|
|
|
* @file connectionmanager.cpp
|
|
|
|
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
|
|
|
|
* Parts by Nokia Corporation (qt-info@nokia.com) Copyright (C) 2009.
|
2010-07-16 18:59:25 +02:00
|
|
|
* @addtogroup GCSPlugins GCS Plugins
|
2010-03-21 14:44:00 +01:00
|
|
|
* @{
|
2010-07-16 18:59:25 +02:00
|
|
|
* @addtogroup CorePlugin Core Plugin
|
|
|
|
* @{
|
|
|
|
* @brief The Core GCS plugin
|
2010-03-21 14:44:00 +01:00
|
|
|
*****************************************************************************/
|
|
|
|
/*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* 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.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful, 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 along
|
|
|
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
|
|
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "connectionmanager.h"
|
|
|
|
|
|
|
|
#include <aggregation/aggregate.h>
|
|
|
|
#include <coreplugin/iconnection.h>
|
|
|
|
#include <extensionsystem/pluginmanager.h>
|
|
|
|
|
|
|
|
#include <utils/styledbar.h>
|
|
|
|
|
|
|
|
#include "fancytabwidget.h"
|
|
|
|
#include "fancyactionbar.h"
|
|
|
|
#include "mainwindow.h"
|
2010-04-10 18:14:29 +02:00
|
|
|
#include "qextserialport/src/qextserialenumerator.h"
|
|
|
|
#include "qextserialport/src/qextserialport.h"
|
2010-03-21 14:44:00 +01:00
|
|
|
|
|
|
|
#include <QDebug>
|
|
|
|
#include <QLabel>
|
|
|
|
#include <QHBoxLayout>
|
|
|
|
#include <QComboBox>
|
|
|
|
|
|
|
|
namespace Core {
|
|
|
|
|
|
|
|
|
|
|
|
ConnectionManager::ConnectionManager(Internal::MainWindow *mainWindow, Internal::FancyTabWidget *modeStack)
|
|
|
|
: m_availableDevList(0),
|
|
|
|
m_connectBtn(0),
|
2010-04-11 23:08:46 +02:00
|
|
|
m_ioDev(NULL)
|
2010-03-21 14:44:00 +01:00
|
|
|
{
|
2010-11-14 16:25:14 +01:00
|
|
|
Q_UNUSED(mainWindow);
|
|
|
|
|
2010-03-21 14:44:00 +01:00
|
|
|
QVBoxLayout *top = new QVBoxLayout;
|
|
|
|
top->setSpacing(0);
|
|
|
|
top->setMargin(0);
|
|
|
|
|
|
|
|
QHBoxLayout *layout = new QHBoxLayout;
|
|
|
|
layout->setSpacing(0);
|
|
|
|
layout->setContentsMargins(5,0,5,0);
|
|
|
|
layout->addWidget(new QLabel("Connections: "));
|
|
|
|
|
|
|
|
m_availableDevList = new QComboBox;
|
|
|
|
//m_availableDevList->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
|
|
|
m_availableDevList->setMinimumWidth(100);
|
|
|
|
m_availableDevList->setMaximumWidth(150);
|
|
|
|
m_availableDevList->setContextMenuPolicy(Qt::CustomContextMenu);
|
|
|
|
layout->addWidget(m_availableDevList);
|
|
|
|
|
|
|
|
m_connectBtn = new QPushButton("Connect");
|
|
|
|
m_connectBtn->setEnabled(false);
|
|
|
|
layout->addWidget(m_connectBtn);
|
|
|
|
|
|
|
|
Utils::StyledBar *bar = new Utils::StyledBar;
|
|
|
|
bar->setLayout(layout);
|
|
|
|
|
|
|
|
top->addWidget(bar);
|
|
|
|
setLayout(top);
|
|
|
|
|
|
|
|
modeStack->insertCornerWidget(modeStack->cornerWidgetCount()-1, this);
|
|
|
|
|
|
|
|
QObject::connect(m_connectBtn, SIGNAL(pressed()),
|
|
|
|
this, SLOT(onConnectPressed()));
|
|
|
|
}
|
|
|
|
|
|
|
|
ConnectionManager::~ConnectionManager()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void ConnectionManager::init()
|
|
|
|
{
|
|
|
|
//register to the plugin manager so we can receive
|
|
|
|
//new connection object from plugins
|
|
|
|
QObject::connect(ExtensionSystem::PluginManager::instance(), SIGNAL(objectAdded(QObject*)),
|
|
|
|
this, SLOT(objectAdded(QObject*)));
|
|
|
|
QObject::connect(ExtensionSystem::PluginManager::instance(), SIGNAL(aboutToRemoveObject(QObject*)),
|
|
|
|
this, SLOT(aboutToRemoveObject(QObject*)));
|
|
|
|
}
|
|
|
|
|
2010-03-21 21:53:28 +01:00
|
|
|
/**
|
|
|
|
* Slot called when a plugin added an object to the core pool
|
|
|
|
*/
|
2010-03-21 14:44:00 +01:00
|
|
|
void ConnectionManager::objectAdded(QObject *obj)
|
|
|
|
{
|
|
|
|
//Check if a plugin added a connection object to the pool
|
|
|
|
IConnection *connection = Aggregation::query<IConnection>(obj);
|
|
|
|
if (!connection)
|
|
|
|
return;
|
|
|
|
|
|
|
|
//qDebug() << "Connection object registered:" << connection->connectionName();
|
|
|
|
//qDebug() << connection->availableDevices();
|
|
|
|
|
|
|
|
//register devices and populate CB
|
|
|
|
devChanged(connection);
|
|
|
|
|
2011-01-12 08:43:02 +01:00
|
|
|
// Keep track of the registration to be able to tell plugins
|
|
|
|
// to do things
|
|
|
|
m_connectionsList.append(connection);
|
|
|
|
|
2010-03-21 14:44:00 +01:00
|
|
|
QObject::connect(connection, SIGNAL(availableDevChanged(IConnection *)),
|
|
|
|
this, SLOT(devChanged(IConnection*)));
|
|
|
|
}
|
|
|
|
|
|
|
|
void ConnectionManager::aboutToRemoveObject(QObject *obj)
|
|
|
|
{
|
2011-01-12 08:43:02 +01:00
|
|
|
//Check if a plugin added a connection object to the pool
|
|
|
|
IConnection *connection = Aggregation::query<IConnection>(obj);
|
|
|
|
if (!connection)
|
|
|
|
return;
|
|
|
|
if (m_connectionsList.contains(connection))
|
|
|
|
m_connectionsList.removeAt(m_connectionsList.indexOf(connection));
|
2010-03-21 14:44:00 +01:00
|
|
|
}
|
|
|
|
|
2010-11-01 14:34:27 +01:00
|
|
|
/**
|
|
|
|
* Method called by plugins who want to force a disconnection. Used
|
|
|
|
* by Uploader gadget for instance.
|
|
|
|
*/
|
|
|
|
bool ConnectionManager::disconnectDevice()
|
|
|
|
{
|
|
|
|
// Check if we are currently connected or not
|
|
|
|
if(!m_ioDev)
|
|
|
|
return false; // We were not connected
|
2010-11-14 16:25:14 +01:00
|
|
|
|
|
|
|
//signal interested plugins that we are disconnecting the device
|
|
|
|
emit deviceDisconnected();
|
|
|
|
if(m_connectionDevice.connection)
|
2010-11-01 14:34:27 +01:00
|
|
|
{
|
2010-11-14 16:25:14 +01:00
|
|
|
m_connectionDevice.connection->closeDevice(m_connectionDevice.devName);
|
|
|
|
m_ioDev = NULL;
|
|
|
|
m_connectionDevice.connection = NULL;
|
2010-11-01 14:34:27 +01:00
|
|
|
}
|
2010-11-14 16:25:14 +01:00
|
|
|
|
|
|
|
m_connectBtn->setText("Connect");
|
|
|
|
m_availableDevList->setEnabled(true);
|
|
|
|
return true;
|
2010-11-01 14:34:27 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-03-21 21:53:28 +01:00
|
|
|
/**
|
|
|
|
* Slot called when the user pressed the connect/disconnect button
|
|
|
|
*/
|
2010-03-21 14:44:00 +01:00
|
|
|
void ConnectionManager::onConnectPressed()
|
|
|
|
{
|
2010-04-11 23:08:46 +02:00
|
|
|
//check if we are trying to connect a new device
|
|
|
|
//or if we are disconnecting it
|
|
|
|
if(!m_ioDev)
|
2010-03-21 14:44:00 +01:00
|
|
|
{
|
|
|
|
m_connectionDevice = findDevice(m_availableDevList->currentText());
|
|
|
|
|
|
|
|
if(m_connectionDevice.connection)
|
|
|
|
{
|
2010-04-11 23:08:46 +02:00
|
|
|
m_ioDev = m_connectionDevice.connection->openDevice(m_connectionDevice.devName);
|
|
|
|
|
|
|
|
if(m_ioDev)
|
2010-03-21 14:44:00 +01:00
|
|
|
{
|
2010-04-11 23:08:46 +02:00
|
|
|
m_ioDev->open(QIODevice::ReadWrite);
|
2010-10-22 13:17:48 +02:00
|
|
|
|
|
|
|
// check if opening the device worked
|
|
|
|
if (!m_ioDev->isOpen())
|
|
|
|
{
|
|
|
|
qDebug() << "could not connect to " << m_connectionDevice.devName;
|
|
|
|
// TODO: inform the user that something went wrong
|
|
|
|
m_ioDev = NULL;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2010-04-11 23:08:46 +02:00
|
|
|
//signal interested plugins that the user wants to connect to the device
|
|
|
|
emit deviceConnected(m_ioDev);
|
2010-08-07 21:14:34 +02:00
|
|
|
m_connectBtn->setText("Disconnect");
|
|
|
|
m_availableDevList->setEnabled(false);
|
2010-03-21 14:44:00 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
m_connectionDevice.connection = NULL;
|
2010-07-10 03:24:32 +02:00
|
|
|
m_ioDev = NULL;
|
2010-03-21 14:44:00 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2010-08-07 21:14:34 +02:00
|
|
|
else
|
|
|
|
{
|
2010-07-10 03:24:32 +02:00
|
|
|
//only do this if we are disconnecting
|
|
|
|
//signal interested plugins that user is disconnecting his device
|
|
|
|
emit deviceDisconnected();
|
2010-08-07 21:14:34 +02:00
|
|
|
if(m_connectionDevice.connection)
|
|
|
|
{
|
2010-07-10 03:24:32 +02:00
|
|
|
m_connectionDevice.connection->closeDevice(m_connectionDevice.devName);
|
|
|
|
m_ioDev = NULL;
|
|
|
|
m_connectionDevice.connection = NULL;
|
|
|
|
}
|
2010-03-21 14:44:00 +01:00
|
|
|
|
2010-08-07 21:14:34 +02:00
|
|
|
m_connectBtn->setText("Connect");
|
|
|
|
m_availableDevList->setEnabled(true);
|
2010-04-11 23:08:46 +02:00
|
|
|
}
|
2010-03-21 14:44:00 +01:00
|
|
|
}
|
|
|
|
|
2010-03-21 21:53:28 +01:00
|
|
|
/**
|
|
|
|
* Find a device by its displayed (visible on screen) name
|
|
|
|
*/
|
2010-03-21 14:44:00 +01:00
|
|
|
devListItem ConnectionManager::findDevice(const QString &displayedName)
|
|
|
|
{
|
|
|
|
foreach(devListItem d, m_devList)
|
|
|
|
{
|
|
|
|
if(d.displayedName == displayedName)
|
|
|
|
{
|
|
|
|
return d;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
qDebug() << "findDevice: cannot find " << displayedName << " in device list";
|
|
|
|
devListItem d;
|
|
|
|
d.connection = NULL;
|
|
|
|
return d;
|
|
|
|
}
|
|
|
|
|
2010-03-21 21:53:28 +01:00
|
|
|
/**
|
|
|
|
* Unregister all devices from one connection plugin
|
|
|
|
* \param[in] connection Connection type that you want to forget about :)
|
|
|
|
*/
|
2010-03-21 14:44:00 +01:00
|
|
|
void ConnectionManager::unregisterAll(IConnection *connection)
|
|
|
|
{
|
|
|
|
for(QLinkedList<devListItem>::iterator iter = m_devList.begin();
|
2010-04-11 23:32:08 +02:00
|
|
|
iter != m_devList.end(); )
|
2010-03-21 14:44:00 +01:00
|
|
|
{
|
|
|
|
if(iter->connection == connection)
|
|
|
|
{
|
|
|
|
iter = m_devList.erase(iter);
|
|
|
|
}
|
2010-04-11 23:32:08 +02:00
|
|
|
else
|
|
|
|
{
|
|
|
|
++iter;
|
|
|
|
}
|
2010-03-21 14:44:00 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-01-12 01:05:51 +01:00
|
|
|
/**
|
|
|
|
* Tells every connection plugin to stop polling for devices if they
|
|
|
|
* are doing that.
|
2011-01-12 08:43:02 +01:00
|
|
|
*
|
2011-01-12 01:05:51 +01:00
|
|
|
*/
|
|
|
|
void ConnectionManager::suspendPolling()
|
|
|
|
{
|
2011-01-12 08:43:02 +01:00
|
|
|
foreach (IConnection* cnx, m_connectionsList) {
|
2011-01-12 01:05:51 +01:00
|
|
|
cnx->suspendPolling();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Tells every connection plugin to resume polling for devices if they
|
|
|
|
* are doing that.
|
|
|
|
*/
|
|
|
|
void ConnectionManager::resumePolling()
|
|
|
|
{
|
2011-01-12 08:43:02 +01:00
|
|
|
foreach (IConnection* cnx, m_connectionsList) {
|
2011-01-12 01:05:51 +01:00
|
|
|
cnx->resumePolling();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-03-21 21:53:28 +01:00
|
|
|
/**
|
2010-04-11 23:32:08 +02:00
|
|
|
* Register a device from a specific connection plugin
|
2010-03-21 21:53:28 +01:00
|
|
|
*/
|
2010-03-21 14:44:00 +01:00
|
|
|
void ConnectionManager::registerDevice(IConnection *conn, const QString &devN, const QString &disp)
|
|
|
|
{
|
|
|
|
devListItem d;
|
|
|
|
d.connection = conn;
|
|
|
|
d.devName = devN;
|
|
|
|
d.displayedName = disp;
|
|
|
|
|
|
|
|
m_devList.append(d);
|
|
|
|
}
|
|
|
|
|
2010-03-21 21:53:28 +01:00
|
|
|
/**
|
|
|
|
* A device plugin notified us that its device list has changed
|
|
|
|
* (eg: user plug/unplug a usb device)
|
|
|
|
* \param[in] connection Connection type which signaled the update
|
|
|
|
*/
|
2010-03-21 14:44:00 +01:00
|
|
|
void ConnectionManager::devChanged(IConnection *connection)
|
|
|
|
{
|
2011-01-12 01:05:51 +01:00
|
|
|
|
2010-04-11 23:32:08 +02:00
|
|
|
//clear device list combobox
|
2010-03-21 14:44:00 +01:00
|
|
|
m_availableDevList->clear();
|
2010-04-11 23:32:08 +02:00
|
|
|
|
|
|
|
//remove registered devices of this IConnection from the list
|
2010-03-21 14:44:00 +01:00
|
|
|
unregisterAll(connection);
|
|
|
|
|
|
|
|
//and add them back in the list
|
2010-04-11 23:32:08 +02:00
|
|
|
QStringList availableDev = connection->availableDevices();
|
|
|
|
foreach(QString dev, availableDev)
|
2010-03-21 14:44:00 +01:00
|
|
|
{
|
|
|
|
QString cbName = connection->shortName() + ": " + dev;
|
|
|
|
registerDevice(connection, dev, cbName);
|
|
|
|
}
|
|
|
|
|
2010-04-11 23:32:08 +02:00
|
|
|
//add all the list again to the combobox
|
2010-03-21 14:44:00 +01:00
|
|
|
foreach(devListItem d, m_devList)
|
|
|
|
{
|
|
|
|
m_availableDevList->addItem(d.displayedName);
|
|
|
|
}
|
|
|
|
|
|
|
|
//disable connection button if the list is empty
|
|
|
|
if(m_availableDevList->count() > 0)
|
|
|
|
m_connectBtn->setEnabled(true);
|
|
|
|
else
|
|
|
|
m_connectBtn->setEnabled(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
} //namespace Core
|