Commit a8dabf1f authored by dogmaphobic's avatar dogmaphobic

Serial Link Settings completed (QML)

parent ab167a25
...@@ -45,6 +45,7 @@ LinkConfiguration::LinkConfiguration(const QString& name) ...@@ -45,6 +45,7 @@ LinkConfiguration::LinkConfiguration(const QString& name)
: _link(NULL) : _link(NULL)
, _name(name) , _name(name)
, _dynamic(false) , _dynamic(false)
, _autoConnect(false)
{ {
_name = name; _name = name;
if (_name.isEmpty()) { if (_name.isEmpty()) {
...@@ -57,6 +58,7 @@ LinkConfiguration::LinkConfiguration(LinkConfiguration* copy) ...@@ -57,6 +58,7 @@ LinkConfiguration::LinkConfiguration(LinkConfiguration* copy)
_link = copy->link(); _link = copy->link();
_name = copy->name(); _name = copy->name();
_dynamic = copy->isDynamic(); _dynamic = copy->isDynamic();
_autoConnect= copy->isAutoConnect();
Q_ASSERT(!_name.isEmpty()); Q_ASSERT(!_name.isEmpty());
} }
...@@ -66,6 +68,7 @@ void LinkConfiguration::copyFrom(LinkConfiguration* source) ...@@ -66,6 +68,7 @@ void LinkConfiguration::copyFrom(LinkConfiguration* source)
_link = source->link(); _link = source->link();
_name = source->name(); _name = source->name();
_dynamic = source->isDynamic(); _dynamic = source->isDynamic();
_autoConnect= source->isAutoConnect();
} }
/*! /*!
......
...@@ -40,9 +40,11 @@ public: ...@@ -40,9 +40,11 @@ public:
LinkConfiguration(LinkConfiguration* copy); LinkConfiguration(LinkConfiguration* copy);
virtual ~LinkConfiguration() {} virtual ~LinkConfiguration() {}
Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged) Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
Q_PROPERTY(LinkInterface* link READ link WRITE setLink NOTIFY linkChanged) Q_PROPERTY(LinkInterface* link READ link WRITE setLink NOTIFY linkChanged)
Q_PROPERTY(LinkType linkType READ type CONSTANT) Q_PROPERTY(LinkType linkType READ type CONSTANT)
Q_PROPERTY(bool dynamic READ isDynamic WRITE setDynamic NOTIFY dynamicChanged)
Q_PROPERTY(bool autoConnect READ isAutoConnect WRITE setAutoConnect NOTIFY autoConnectChanged)
// Property accessors // Property accessors
...@@ -77,10 +79,22 @@ public: ...@@ -77,10 +79,22 @@ public:
*/ */
bool isDynamic() { return _dynamic; } bool isDynamic() { return _dynamic; }
/*!
*
* Is this an Auto Connect configuration?
* @return True if this is an Auto Connect configuration (connects automatically at boot time).
*/
bool isAutoConnect() { return _autoConnect; }
/*! /*!
* Set if this is this a dynamic configuration. (decided at runtime) * Set if this is this a dynamic configuration. (decided at runtime)
*/ */
void setDynamic(bool dynamic = true) { _dynamic = dynamic; } void setDynamic(bool dynamic = true) { _dynamic = dynamic; emit dynamicChanged(); }
/*!
* Set if this is this an Auto Connect configuration.
*/
void setAutoConnect(bool autoc = true) { _autoConnect = autoc; emit autoConnectChanged(); }
/// Virtual Methods /// Virtual Methods
...@@ -152,14 +166,17 @@ public: ...@@ -152,14 +166,17 @@ public:
static LinkConfiguration* duplicateSettings(LinkConfiguration *source); static LinkConfiguration* duplicateSettings(LinkConfiguration *source);
signals: signals:
void nameChanged(const QString& name); void nameChanged (const QString& name);
void linkChanged(LinkInterface* link); void linkChanged (LinkInterface* link);
void dynamicChanged ();
void autoConnectChanged ();
protected: protected:
LinkInterface* _link; ///< Link currently using this configuration (if any) LinkInterface* _link; ///< Link currently using this configuration (if any)
private: private:
QString _name; QString _name;
bool _dynamic; ///< A connection added automatically and not persistent (unless it's edited). bool _dynamic; ///< A connection added automatically and not persistent (unless it's edited).
bool _autoConnect; ///< This connection is started automatically at boot
}; };
#endif // LINKCONFIGURATION_H #endif // LINKCONFIGURATION_H
...@@ -286,17 +286,17 @@ void LinkManager::saveLinkConfigurationList() ...@@ -286,17 +286,17 @@ void LinkManager::saveLinkConfigurationList()
{ {
QSettings settings; QSettings settings;
settings.remove(LinkConfiguration::settingsRoot()); settings.remove(LinkConfiguration::settingsRoot());
int trueCount = 0;
for (int i=0; i<_linkConfigurations.count(); i++) { for (int i = 0; i < _linkConfigurations.count(); i++) {
LinkConfiguration* linkConfig = _linkConfigurations.value<LinkConfiguration*>(i); LinkConfiguration* linkConfig = _linkConfigurations.value<LinkConfiguration*>(i);
if (linkConfig) { if (linkConfig) {
if(!linkConfig->isDynamic()) if(!linkConfig->isDynamic())
{ {
QString root = LinkConfiguration::settingsRoot(); QString root = LinkConfiguration::settingsRoot();
root += QString("/Link%1").arg(i); root += QString("/Link%1").arg(trueCount++);
settings.setValue(root + "/name", linkConfig->name()); settings.setValue(root + "/name", linkConfig->name());
settings.setValue(root + "/type", linkConfig->type()); settings.setValue(root + "/type", linkConfig->type());
settings.setValue(root + "/auto", linkConfig->isAutoConnect());
// Have the instance save its own values // Have the instance save its own values
linkConfig->saveSettings(settings, root); linkConfig->saveSettings(settings, root);
} }
...@@ -304,17 +304,16 @@ void LinkManager::saveLinkConfigurationList() ...@@ -304,17 +304,16 @@ void LinkManager::saveLinkConfigurationList()
qWarning() << "Internal error"; qWarning() << "Internal error";
} }
} }
QString root(LinkConfiguration::settingsRoot()); QString root(LinkConfiguration::settingsRoot());
settings.setValue(root + "/count", _linkConfigurations.count()); settings.setValue(root + "/count", trueCount);
emit linkConfigurationChanged(); emit linkConfigurationsChanged();
} }
void LinkManager::loadLinkConfigurationList() void LinkManager::loadLinkConfigurationList()
{ {
bool linksChanged = false; bool linksChanged = false;
bool mockPresent = false;
QSettings settings; QSettings settings;
// Is the group even there? // Is the group even there?
if(settings.contains(LinkConfiguration::settingsRoot() + "/count")) { if(settings.contains(LinkConfiguration::settingsRoot() + "/count")) {
// Find out how many configurations we have // Find out how many configurations we have
...@@ -324,12 +323,13 @@ void LinkManager::loadLinkConfigurationList() ...@@ -324,12 +323,13 @@ void LinkManager::loadLinkConfigurationList()
root += QString("/Link%1").arg(i); root += QString("/Link%1").arg(i);
if(settings.contains(root + "/type")) { if(settings.contains(root + "/type")) {
int type = settings.value(root + "/type").toInt(); int type = settings.value(root + "/type").toInt();
if(type < LinkConfiguration::TypeLast) { if((LinkConfiguration::LinkType)type < LinkConfiguration::TypeLast) {
if(settings.contains(root + "/name")) { if(settings.contains(root + "/name")) {
QString name = settings.value(root + "/name").toString(); QString name = settings.value(root + "/name").toString();
if(!name.isEmpty()) { if(!name.isEmpty()) {
LinkConfiguration* pLink = NULL; LinkConfiguration* pLink = NULL;
switch(type) { bool autoConnect = settings.value(root + "/auto").toBool();
switch((LinkConfiguration::LinkType)type) {
#ifndef __ios__ #ifndef __ios__
case LinkConfiguration::TypeSerial: case LinkConfiguration::TypeSerial:
pLink = (LinkConfiguration*)new SerialConfiguration(name); pLink = (LinkConfiguration*)new SerialConfiguration(name);
...@@ -347,42 +347,48 @@ void LinkManager::loadLinkConfigurationList() ...@@ -347,42 +347,48 @@ void LinkManager::loadLinkConfigurationList()
#ifdef QT_DEBUG #ifdef QT_DEBUG
case LinkConfiguration::TypeMock: case LinkConfiguration::TypeMock:
pLink = (LinkConfiguration*)new MockConfiguration(name); pLink = (LinkConfiguration*)new MockConfiguration(name);
mockPresent = true;
break; break;
#endif #endif
default:
case LinkConfiguration::TypeLast:
break;
} }
if(pLink) { if(pLink) {
// Have the instance load its own values //-- Have the instance load its own values
pLink->setAutoConnect(autoConnect);
pLink->loadSettings(settings, root); pLink->loadSettings(settings, root);
_linkConfigurations.append(pLink); _linkConfigurations.append(pLink);
linksChanged = true; linksChanged = true;
} }
} else { } else {
qWarning() << "Link Configuration " << root << " has an empty name." ; qWarning() << "Link Configuration" << root << "has an empty name." ;
} }
} else { } else {
qWarning() << "Link Configuration " << root << " has no name." ; qWarning() << "Link Configuration" << root << "has no name." ;
} }
} else { } else {
qWarning() << "Link Configuration " << root << " an invalid type: " << type; qWarning() << "Link Configuration" << root << "an invalid type: " << type;
} }
} else { } else {
qWarning() << "Link Configuration " << root << " has no type." ; qWarning() << "Link Configuration" << root << "has no type." ;
} }
} }
} }
// Debug buids always add MockLink automatically (if one is not already there)
// Debug buids always add MockLink automatically
#ifdef QT_DEBUG #ifdef QT_DEBUG
MockConfiguration* pMock = new MockConfiguration("Mock Link PX4"); if(!mockPresent)
pMock->setDynamic(true); {
_linkConfigurations.append(pMock); MockConfiguration* pMock = new MockConfiguration("Mock Link PX4");
linksChanged = true; pMock->setDynamic(true);
_linkConfigurations.append(pMock);
linksChanged = true;
}
#endif #endif
if(linksChanged) { if(linksChanged) {
emit linkConfigurationChanged(); emit linkConfigurationsChanged();
} }
// Enable automatic Serial PX4/3DR Radio hunting // Enable automatic Serial PX4/3DR Radio hunting
_configurationsLoaded = true; _configurationsLoaded = true;
} }
...@@ -417,7 +423,6 @@ void LinkManager::_updateAutoConnectLinks(void) ...@@ -417,7 +423,6 @@ void LinkManager::_updateAutoConnectLinks(void)
bool foundUDP = false; bool foundUDP = false;
for (int i=0; i<_links.count(); i++) { for (int i=0; i<_links.count(); i++) {
LinkConfiguration* linkConfig = _links.value<LinkInterface*>(i)->getLinkConfiguration(); LinkConfiguration* linkConfig = _links.value<LinkInterface*>(i)->getLinkConfiguration();
if (linkConfig->type() == LinkConfiguration::TypeUdp && linkConfig->name() == _defaultUPDLinkName) { if (linkConfig->type() == LinkConfiguration::TypeUdp && linkConfig->name() == _defaultUPDLinkName) {
foundUDP = true; foundUDP = true;
break; break;
...@@ -428,7 +433,9 @@ void LinkManager::_updateAutoConnectLinks(void) ...@@ -428,7 +433,9 @@ void LinkManager::_updateAutoConnectLinks(void)
UDPConfiguration* udpConfig = new UDPConfiguration(_defaultUPDLinkName); UDPConfiguration* udpConfig = new UDPConfiguration(_defaultUPDLinkName);
udpConfig->setLocalPort(QGC_UDP_LOCAL_PORT); udpConfig->setLocalPort(QGC_UDP_LOCAL_PORT);
udpConfig->setDynamic(true); udpConfig->setDynamic(true);
_linkConfigurations.append(udpConfig);
createConnectedLink(udpConfig); createConnectedLink(udpConfig);
emit linkConfigurationsChanged();
} }
#ifndef __ios__ #ifndef __ios__
...@@ -503,9 +510,7 @@ void LinkManager::_updateAutoConnectLinks(void) ...@@ -503,9 +510,7 @@ void LinkManager::_updateAutoConnectLinks(void)
pSerialConfig->setBaud(boardType == QGCSerialPortInfo::BoardType3drRadio ? 57600 : 115200); pSerialConfig->setBaud(boardType == QGCSerialPortInfo::BoardType3drRadio ? 57600 : 115200);
pSerialConfig->setDynamic(true); pSerialConfig->setDynamic(true);
pSerialConfig->setPortName(portInfo.systemLocation()); pSerialConfig->setPortName(portInfo.systemLocation());
_autoconnectConfigurations.append(pSerialConfig); _autoconnectConfigurations.append(pSerialConfig);
createConnectedLink(pSerialConfig); createConnectedLink(pSerialConfig);
} }
} }
...@@ -516,7 +521,6 @@ void LinkManager::_updateAutoConnectLinks(void) ...@@ -516,7 +521,6 @@ void LinkManager::_updateAutoConnectLinks(void)
QList<LinkConfiguration*> _confToDelete; QList<LinkConfiguration*> _confToDelete;
for (int i=0; i<_autoconnectConfigurations.count(); i++) { for (int i=0; i<_autoconnectConfigurations.count(); i++) {
SerialConfiguration* linkConfig = _autoconnectConfigurations.value<SerialConfiguration*>(i); SerialConfiguration* linkConfig = _autoconnectConfigurations.value<SerialConfiguration*>(i);
if (linkConfig) { if (linkConfig) {
if (!currentPorts.contains(linkConfig->portName())) { if (!currentPorts.contains(linkConfig->portName())) {
// We don't remove links which are still connected even though at this point the cable may // We don't remove links which are still connected even though at this point the cable may
...@@ -682,19 +686,36 @@ QStringList LinkManager::linkTypeStrings(void) const ...@@ -682,19 +686,36 @@ QStringList LinkManager::linkTypeStrings(void) const
return list; return list;
} }
QStringList LinkManager::serialPortStrings(void) void LinkManager::_updateSerialPorts()
{ {
_commPortList.clear();
_commPortDisplayList.clear();
#ifndef __ios__ #ifndef __ios__
if(!_commPortList.size()) QList<QSerialPortInfo> portList = QSerialPortInfo::availablePorts();
foreach (const QSerialPortInfo &info, portList)
{ {
QList<QSerialPortInfo> portList = QSerialPortInfo::availablePorts(); QString port = info.systemLocation().trimmed();
foreach (const QSerialPortInfo &info, portList) _commPortList += port;
{ _commPortDisplayList += SerialConfiguration::cleanPortDisplayname(port);
QString name = info.portName();
_commPortList += name;
}
} }
#endif #endif
}
QStringList LinkManager::serialPortStrings(void)
{
if(!_commPortDisplayList.size())
{
_updateSerialPorts();
}
return _commPortDisplayList;
}
QStringList LinkManager::serialPorts(void)
{
if(!_commPortList.size())
{
_updateSerialPorts();
}
return _commPortList; return _commPortList;
} }
...@@ -707,3 +728,107 @@ QStringList LinkManager::serialBaudRates(void) ...@@ -707,3 +728,107 @@ QStringList LinkManager::serialBaudRates(void)
return SerialConfiguration::supportedBaudRates(); return SerialConfiguration::supportedBaudRates();
#endif #endif
} }
bool LinkManager::endConfigurationEditing(LinkConfiguration* config, LinkConfiguration* editedConfig)
{
Q_ASSERT(config != NULL);
Q_ASSERT(editedConfig != NULL);
_fixUnnamed(editedConfig);
config->copyFrom(editedConfig);
saveLinkConfigurationList();
// Tell link about changes (if any)
config->updateSettings();
// Discard temporary duplicate
delete editedConfig;
return true;
}
bool LinkManager::endCreateConfiguration(LinkConfiguration* config)
{
Q_ASSERT(config != NULL);
_fixUnnamed(config);
_linkConfigurations.append(config);
saveLinkConfigurationList();
return true;
}
LinkConfiguration* LinkManager::createConfiguration(int type, const QString& name)
{
if((LinkConfiguration::LinkType)type == LinkConfiguration::TypeSerial)
_updateSerialPorts();
return LinkConfiguration::createSettings(type, name);
}
LinkConfiguration* LinkManager::startConfigurationEditing(LinkConfiguration* config)
{
Q_ASSERT(config != NULL);
if(config->type() == LinkConfiguration::TypeSerial)
_updateSerialPorts();
return LinkConfiguration::duplicateSettings(config);
}
void LinkManager::_fixUnnamed(LinkConfiguration* config)
{
Q_ASSERT(config != NULL);
//-- Check for "Unnamed"
if (config->name() == "Unnamed") {
switch(config->type()) {
#ifndef __ios__
case LinkConfiguration::TypeSerial: {
QString tname = dynamic_cast<SerialConfiguration*>(config)->portName();
#ifdef Q_OS_WIN32
tname.replace("\\\\.\\", "");
#else
tname.replace("/dev/cu.", "");
tname.replace("/dev/", "");
#endif
config->setName(QString("Serial Device on %1").arg(tname));
break;
}
#endif
case LinkConfiguration::TypeUdp:
config->setName(
QString("UDP Link on Port %1").arg(dynamic_cast<UDPConfiguration*>(config)->localPort()));
break;
case LinkConfiguration::TypeTcp: {
TCPConfiguration* tconfig = dynamic_cast<TCPConfiguration*>(config);
if(tconfig) {
config->setName(
QString("TCP Link %1:%2").arg(tconfig->address().toString()).arg((int)tconfig->port()));
}
}
break;
case LinkConfiguration::TypeLogReplay: {
LogReplayLinkConfiguration* tconfig = dynamic_cast<LogReplayLinkConfiguration*>(config);
if(tconfig) {
config->setName(QString("Log Replay %1").arg(tconfig->logFilenameShort()));
}
}
break;
#ifdef QT_DEBUG
case LinkConfiguration::TypeMock:
config->setName(
QString("Mock Link"));
break;
#endif
case LinkConfiguration::TypeLast:
default:
break;
}
}
}
void LinkManager::removeConfiguration(LinkConfiguration* config)
{
Q_ASSERT(config != NULL);
LinkInterface* iface = config->link();
if(iface) {
disconnectLink(iface);
}
// Remove configuration
_linkConfigurations.removeOne(config);
delete config;
// Save list
saveLinkConfigurationList();
}
...@@ -80,15 +80,25 @@ public: ...@@ -80,15 +80,25 @@ public:
Q_PROPERTY(bool autoconnectPX4Flow READ autoconnectPX4Flow WRITE setAutoconnectPX4Flow NOTIFY autoconnectPX4FlowChanged) Q_PROPERTY(bool autoconnectPX4Flow READ autoconnectPX4Flow WRITE setAutoconnectPX4Flow NOTIFY autoconnectPX4FlowChanged)
/// LinkInterface Accessor /// LinkInterface Accessor
Q_PROPERTY(QmlObjectListModel* links READ links CONSTANT) Q_PROPERTY(QmlObjectListModel* links READ links CONSTANT)
/// LinkConfiguration Accessor /// LinkConfiguration Accessor
Q_PROPERTY(QmlObjectListModel* linkConfigurations READ linkConfigurations CONSTANT) Q_PROPERTY(QmlObjectListModel* linkConfigurations READ linkConfigurations NOTIFY linkConfigurationsChanged)
/// List of comm type strings /// List of comm type strings
Q_PROPERTY(QStringList linkTypeStrings READ linkTypeStrings CONSTANT) Q_PROPERTY(QStringList linkTypeStrings READ linkTypeStrings CONSTANT)
/// List of supported baud rates for serial links /// List of supported baud rates for serial links
Q_PROPERTY(QStringList serialBaudRates READ serialBaudRates CONSTANT) Q_PROPERTY(QStringList serialBaudRates READ serialBaudRates CONSTANT)
/// List of comm ports display names
Q_PROPERTY(QStringList serialPortStrings READ serialPortStrings NOTIFY commPortStringsChanged)
/// List of comm ports /// List of comm ports
Q_PROPERTY(QStringList serialPortStrings READ serialPortStrings NOTIFY commPortStringsChanged) Q_PROPERTY(QStringList serialPorts READ serialPorts NOTIFY commPortsChanged)
// Create/Edit Link Configuration
Q_INVOKABLE LinkConfiguration* createConfiguration (int type, const QString& name);
Q_INVOKABLE LinkConfiguration* startConfigurationEditing (LinkConfiguration* config);
Q_INVOKABLE void cancelConfigurationEditing (LinkConfiguration* config) { delete config; }
Q_INVOKABLE bool endConfigurationEditing (LinkConfiguration* config, LinkConfiguration* editedConfig);
Q_INVOKABLE bool endCreateConfiguration (LinkConfiguration* config);
Q_INVOKABLE void removeConfiguration (LinkConfiguration* config);
// Property accessors // Property accessors
...@@ -104,6 +114,7 @@ public: ...@@ -104,6 +114,7 @@ public:
QStringList linkTypeStrings (void) const; QStringList linkTypeStrings (void) const;
QStringList serialBaudRates (void); QStringList serialBaudRates (void);
QStringList serialPortStrings (void); QStringList serialPortStrings (void);
QStringList serialPorts (void);
void setAutoconnectUDP (bool autoconnect); void setAutoconnectUDP (bool autoconnect);
void setAutoconnectPixhawk (bool autoconnect); void setAutoconnectPixhawk (bool autoconnect);
...@@ -186,8 +197,9 @@ signals: ...@@ -186,8 +197,9 @@ signals:
// No longer hearing from any vehicles on this link. // No longer hearing from any vehicles on this link.
void linkInactive(LinkInterface* link); void linkInactive(LinkInterface* link);
void linkConfigurationChanged();
void commPortStringsChanged(); void commPortStringsChanged();
void commPortsChanged();
void linkConfigurationsChanged();
private slots: private slots:
void _linkConnected(void); void _linkConnected(void);
...@@ -197,6 +209,8 @@ private slots: ...@@ -197,6 +209,8 @@ private slots:
private: private:
bool _connectionsSuspendedMsg(void); bool _connectionsSuspendedMsg(void);
void _updateAutoConnectLinks(void); void _updateAutoConnectLinks(void);
void _updateSerialPorts();
void _fixUnnamed(LinkConfiguration* config);
#ifndef __ios__ #ifndef __ios__
SerialConfiguration* _autoconnectConfigurationsContainsPort(const QString& portName); SerialConfiguration* _autoconnectConfigurationsContainsPort(const QString& portName);
...@@ -218,6 +232,7 @@ private: ...@@ -218,6 +232,7 @@ private:
QStringList _autoconnectWaitList; QStringList _autoconnectWaitList;
QStringList _commPortList; QStringList _commPortList;
QStringList _commPortDisplayList;
bool _autoconnectUDP; bool _autoconnectUDP;
bool _autoconnectPixhawk; bool _autoconnectPixhawk;
......
...@@ -395,12 +395,13 @@ SerialConfiguration::SerialConfiguration(const QString& name) : LinkConfiguratio ...@@ -395,12 +395,13 @@ SerialConfiguration::SerialConfiguration(const QString& name) : LinkConfiguratio
SerialConfiguration::SerialConfiguration(SerialConfiguration* copy) : LinkConfiguration(copy) SerialConfiguration::SerialConfiguration(SerialConfiguration* copy) : LinkConfiguration(copy)
{ {
_baud = copy->baud(); _baud = copy->baud();
_flowControl= copy->flowControl(); _flowControl = copy->flowControl();
_parity = copy->parity(); _parity = copy->parity();
_dataBits = copy->dataBits(); _dataBits = copy->dataBits();
_stopBits = copy->stopBits(); _stopBits = copy->stopBits();
_portName = copy->portName(); _portName = copy->portName();
_portDisplayName = copy->portDisplayName();
} }
void SerialConfiguration::copyFrom(LinkConfiguration *source) void SerialConfiguration::copyFrom(LinkConfiguration *source)
...@@ -408,12 +409,13 @@ void SerialConfiguration::copyFrom(LinkConfiguration *source) ...@@ -408,12 +409,13 @@ void SerialConfiguration::copyFrom(LinkConfiguration *source)
LinkConfiguration::copyFrom(source); LinkConfiguration::copyFrom(source);
SerialConfiguration* ssource = dynamic_cast<SerialConfiguration*>(source); SerialConfiguration* ssource = dynamic_cast<SerialConfiguration*>(source);
Q_ASSERT(ssource != NULL); Q_ASSERT(ssource != NULL);
_baud = ssource->baud(); _baud = ssource->baud();
_flowControl= ssource->flowControl(); _flowControl = ssource->flowControl();
_parity = ssource->parity(); _parity = ssource->parity();
_dataBits = ssource->dataBits(); _dataBits = ssource->dataBits();
_stopBits = ssource->stopBits(); _stopBits = ssource->stopBits();
_portName = ssource->portName(); _portName = ssource->portName();
_portDisplayName = ssource->portDisplayName();
} }
void SerialConfiguration::updateSettings() void SerialConfiguration::updateSettings()
...@@ -457,30 +459,45 @@ void SerialConfiguration::setPortName(const QString& portName) ...@@ -457,30 +459,45 @@ void SerialConfiguration::setPortName(const QString& portName)
QString pname = portName.trimmed(); QString pname = portName.trimmed();
if (!pname.isEmpty() && pname != _portName) { if (!pname.isEmpty() && pname != _portName) {
_portName = pname; _portName = pname;
_portDisplayName = cleanPortDisplayname(pname);
} }
} }
QString SerialConfiguration::cleanPortDisplayname(const QString name)
{
QString pname = name.trimmed();
#ifdef Q_OS_WIN32
pname.replace("\\\\.\\", "");
#else
pname.replace("/dev/cu.", "");
pname.replace("/dev/", "");
#endif
return pname;
}
void SerialConfiguration::saveSettings(QSettings& settings, const QString& root) void SerialConfiguration::saveSettings(QSettings& settings, const QString& root)
{ {
settings.beginGroup(root); settings.beginGroup(root);
settings.setValue("baud", _baud); settings.setValue("baud", _baud);
settings.setValue("dataBits", _dataBits); settings.setValue("dataBits", _dataBits);
settings.setValue("flowControl", _flowControl); settings.setValue("flowControl", _flowControl);
settings.setValue("stopBits", _stopBits); settings.setValue("stopBits", _stopBits);
settings.setValue("parity", _parity); settings.setValue("parity", _parity);
settings.setValue("portName", _portName); settings.setValue("portName", _portName);
settings.setValue("portDisplayName",_portDisplayName);
settings.endGroup(); settings.endGroup();
} }
void SerialConfiguration::loadSettings(QSettings& settings, const QString& root) void SerialConfiguration::loadSettings(QSettings& settings, const QString& root)
{ {
settings.beginGroup(root); settings.beginGroup(root);
if(settings.contains("baud")) _baud = settings.value("baud").toInt(); if(settings.contains("baud")) _baud = settings.value("baud").toInt();
if(settings.contains("dataBits")) _dataBits = settings.value("dataBits").toInt(); if(settings.contains("dataBits")) _dataBits = settings.value("dataBits").toInt();
if(settings.contains("flowControl")) _flowControl = settings.value("flowControl").toInt(); if(settings.contains("flowControl")) _flowControl = settings.value("flowControl").toInt();
if(settings.contains("stopBits")) _stopBits = settings.value("stopBits").toInt(); if(settings.contains("stopBits")) _stopBits = settings.value("stopBits").toInt();
if(settings.contains("parity")) _parity = settings.value("parity").toInt(); if(settings.contains("parity")) _parity = settings.value("parity").toInt();
if(settings.contains("portName")) _portName = settings.value("portName").toString(); if(settings.contains("portName")) _portName = settings.value("portName").toString();
if(settings.contains("portDisplayName"))_portDisplayName= settings.value("portDisplayName").toString();
settings.endGroup(); settings.endGroup();
} }
......
...@@ -66,22 +66,32 @@ public: ...@@ -66,22 +66,32 @@ public:
SerialConfiguration(const QString& name); SerialConfiguration(const QString& name);
SerialConfiguration(SerialConfiguration* copy); SerialConfiguration(SerialConfiguration* copy);
Q_PROPERTY(int baud READ baud WRITE setBaud NOTIFY baudChanged)
Q_PROPERTY(int dataBits READ dataBits WRITE setDataBits NOTIFY dataBitsChanged)
Q_PROPERTY(int flowControl READ flowControl WRITE setFlowControl NOTIFY flowControlChanged)
Q_PROPERTY(int stopBits READ stopBits WRITE setStopBits NOTIFY stopBitsChanged)
Q_PROPERTY(int parity READ parity WRITE setParity NOTIFY parityChanged)
Q_PROPERTY(QString portName READ portName WRITE setPortName NOTIFY portNameChanged)
Q_PROPERTY(QString portDisplayName READ portDisplayName NOTIFY portDisplayNameChanged)
int baud() { return _baud; } int baud() { return _baud; }
int dataBits() { return _dataBits; } int dataBits() { return _dataBits; }
int flowControl() { return _flowControl; } ///< QSerialPort Enums int flowControl() { return _flowControl; } ///< QSerialPort Enums
int stopBits() { return _stopBits; } int stopBits() { return _stopBits; }
int parity() { return _parity; } ///< QSerialPort Enums int parity() { return _parity; } ///< QSerialPort Enums
const QString portName() { return _portName; } const QString portName () { return _portName; }
const QString portDisplayName () { return _portDisplayName; }
void setBaud (int baud); void setBaud (int baud);
void setDataBits (int databits); void setDataBits (int databits);
void setFlowControl (int flowControl); ///< QSerialPort Enums void setFlowControl (int flowControl); ///< QSerialPort Enums
void setStopBits (int stopBits); void setStopBits (int stopBits);
void setParity (int parity); ///< QSerialPort Enums void setParity (int parity); ///< QSerialPort Enums
void setPortName (const QString& portName); void setPortName (const QString& portName);
static QStringList supportedBaudRates(); static QStringList supportedBaudRates();
static QString cleanPortDisplayname(const QString name);
/// From LinkConfiguration /// From LinkConfiguration
LinkType type() { return LinkConfiguration::TypeSerial; } LinkType type() { return LinkConfiguration::TypeSerial; }
...@@ -90,6 +100,15 @@ public: ...@@ -90,6 +100,15 @@ public:
void saveSettings(QSettings& settings, const QString& root); void saveSettings(QSettings& settings, const QString& root);
void updateSettings(); void updateSettings();
signals:
void baudChanged ();
void dataBitsChanged ();
void flowControlChanged ();
void stopBitsChanged ();
void parityChanged ();
void portNameChanged ();
void portDisplayNameChanged ();
private: private:
static void _initBaudRates(); static void _initBaudRates();
...@@ -100,9 +119,9 @@ private: ...@@ -100,9 +119,9 @@ private:
int _stopBits; int _stopBits;
int _parity; int _parity;
QString _portName; QString _portName;
QString _portDisplayName;
}; };
/** /**
* @brief The SerialLink class provides cross-platform access to serial links. * @brief The SerialLink class provides cross-platform access to serial links.
* It takes care of the link management and provides a common API to higher * It takes care of the link management and provides a common API to higher
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
import QtQuick 2.5 import QtQuick 2.5
import QtQuick.Controls 1.4 import QtQuick.Controls 1.4
import QtQuick.Dialogs 1.1
import QGroundControl 1.0 import QGroundControl 1.0
import QGroundControl.Controls 1.0 import QGroundControl.Controls 1.0
...@@ -92,7 +93,7 @@ Rectangle { ...@@ -92,7 +93,7 @@ Rectangle {
text: object.name text: object.name
width: _linkRoot.width * 0.5 width: _linkRoot.width * 0.5
exclusiveGroup: linkGroup exclusiveGroup: linkGroup
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: settingsColumn.horizontalCenter
onClicked: { onClicked: {
checked = true checked = true
_currentSelection = object _currentSelection = object
...@@ -111,8 +112,26 @@ Rectangle { ...@@ -111,8 +112,26 @@ Rectangle {
QGCButton { QGCButton {
width: ScreenTools.defaultFontPixelWidth * 10 width: ScreenTools.defaultFontPixelWidth * 10
text: "Delete" text: "Delete"
enabled: _currentSelection && !_currentSelection.link enabled: _currentSelection && !_currentSelection.dynamic
onClicked: { onClicked: {
if(_currentSelection)
deleteDialog.visible = true
}
MessageDialog {
id: deleteDialog
visible: false
icon: StandardIcon.Warning
standardButtons: StandardButton.Yes | StandardButton.No
title: "Remove Link Configuration"
text: _currentSelection ? "Remove " + _currentSelection.name + ". Is this really what you want?" : ""
onYes: {
if(_currentSelection)
QGroundControl.linkManager.removeConfiguration(_currentSelection)
deleteDialog.visible = false
}
onNo: {
deleteDialog.visible = false
}
} }
} }
QGCButton { QGCButton {
...@@ -154,6 +173,7 @@ Rectangle { ...@@ -154,6 +173,7 @@ Rectangle {
anchors.fill: parent anchors.fill: parent
visible: false visible: false
property var linkConfig: null property var linkConfig: null
property var editConfig: null
} }
//--------------------------------------------- //---------------------------------------------
...@@ -163,6 +183,24 @@ Rectangle { ...@@ -163,6 +183,24 @@ Rectangle {
Rectangle { Rectangle {
color: __qgcPal.window color: __qgcPal.window
anchors.fill: parent anchors.fill: parent
Component.onCompleted: {
// If editing, create copy for editing
if(linkConfig) {
editConfig = QGroundControl.linkManager.startConfigurationEditing(linkConfig)
} else {
// Create new link configuration
if(ScreenTools.isiOS)
editConfig = QGroundControl.linkManager.createConfiguration(LinkConfiguration.TypeUdp, "Unnamed")
else
editConfig = QGroundControl.linkManager.createConfiguration(LinkConfiguration.TypeSerial, "Unnamed")
}
}
Component.onDestruction: {
if(editConfig) {
QGroundControl.linkManager.cancelConfigurationEditing(editConfig)
editConfig = null
}
}
Flickable { Flickable {
clip: true clip: true
anchors.top: parent.top anchors.top: parent.top
...@@ -199,7 +237,8 @@ Rectangle { ...@@ -199,7 +237,8 @@ Rectangle {
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
} }
QGCTextField { QGCTextField {
text: linkConfig ? linkConfig.name : "Untitled" id: nameField
text: editConfig ? editConfig.name : ""
width: _secondColumn width: _secondColumn
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
} }
...@@ -220,8 +259,17 @@ Rectangle { ...@@ -220,8 +259,17 @@ Rectangle {
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
Component.onCompleted: { Component.onCompleted: {
if(linkConfig != null) { if(linkConfig != null) {
if(linkConfig.linkType === LinkConfiguration.TypeSerial) var index = linkConfig.linkType
if(index === LinkConfiguration.TypeSerial)
linkSettingLoader.sourceComponent = serialLinkSettings linkSettingLoader.sourceComponent = serialLinkSettings
if(index === LinkConfiguration.TypeUdp)
linkSettingLoader.sourceComponent = udpLinkSettings
if(index === LinkConfiguration.TypeTcp)
linkSettingLoader.sourceComponent = tcpLinkSettings
if(index === LinkConfiguration.TypeMock)
linkSettingLoader.sourceComponent = mockLinkSettings
if(index === LinkConfiguration.TypeLogReplay)
linkSettingLoader.sourceComponent = logLinkSettings
linkSettingLoader.visible = true linkSettingLoader.visible = true
} }
} }
...@@ -235,7 +283,14 @@ Rectangle { ...@@ -235,7 +283,14 @@ Rectangle {
model: QGroundControl.linkManager.linkTypeStrings model: QGroundControl.linkManager.linkTypeStrings
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
onActivated: { onActivated: {
if (index != -1) { if (index != -1 && index !== editConfig.linkType) {
// Save current name
var name = editConfig.name
// Discard link configuration (old type)
QGroundControl.linkManager.cancelConfigurationEditing(editConfig)
// Create new link configuration
editConfig = QGroundControl.linkManager.createConfiguration(index, name)
// Load appropriate configuration panel
linkSettingLoader.sourceComponent = null linkSettingLoader.sourceComponent = null
if(index === LinkConfiguration.TypeSerial) if(index === LinkConfiguration.TypeSerial)
linkSettingLoader.sourceComponent = serialLinkSettings linkSettingLoader.sourceComponent = serialLinkSettings
...@@ -252,12 +307,40 @@ Rectangle { ...@@ -252,12 +307,40 @@ Rectangle {
Component.onCompleted: { Component.onCompleted: {
if(linkConfig == null) { if(linkConfig == null) {
linkTypeCombo.currentIndex = 0 linkTypeCombo.currentIndex = 0
linkSettingLoader.sourceComponent = serialLinkSettings var index = editConfig.linkType
if(index === LinkConfiguration.TypeSerial)
linkSettingLoader.sourceComponent = serialLinkSettings
if(index === LinkConfiguration.TypeUdp)
linkSettingLoader.sourceComponent = udpLinkSettings
if(index === LinkConfiguration.TypeTcp)
linkSettingLoader.sourceComponent = tcpLinkSettings
if(index === LinkConfiguration.TypeMock)
linkSettingLoader.sourceComponent = mockLinkSettings
if(index === LinkConfiguration.TypeLogReplay)
linkSettingLoader.sourceComponent = logLinkSettings
linkSettingLoader.visible = true linkSettingLoader.visible = true
} }
} }
} }
} }
Item {
height: ScreenTools.defaultFontPixelHeight * 0.5
width: parent.width
}
//-- Auto Connect
QGCCheckBox {
text: "Automatically Connect on Start"
checked: false
onCheckedChanged: {
if(editConfig) {
editConfig.autoConnect = checked
}
}
Component.onCompleted: {
if(editConfig)
checked = editConfig.autoConnect
}
}
Item { Item {
height: ScreenTools.defaultFontPixelHeight height: ScreenTools.defaultFontPixelHeight
width: parent.width width: parent.width
...@@ -266,7 +349,7 @@ Rectangle { ...@@ -266,7 +349,7 @@ Rectangle {
id: linkSettingLoader id: linkSettingLoader
width: parent.width width: parent.width
visible: false visible: false
property var config: linkConfig property var subEditConfig: editConfig
} }
} }
} }
...@@ -280,6 +363,16 @@ Rectangle { ...@@ -280,6 +363,16 @@ Rectangle {
width: ScreenTools.defaultFontPixelWidth * 10 width: ScreenTools.defaultFontPixelWidth * 10
text: "OK" text: "OK"
onClicked: { onClicked: {
// Save editting
editConfig.name = nameField.text
if(linkConfig) {
QGroundControl.linkManager.endConfigurationEditing(linkConfig, editConfig)
} else {
// If it was edited, it's no longer "dynamic"
editConfig.dynamic = false
QGroundControl.linkManager.endCreateConfiguration(editConfig)
}
editConfig = null
_linkRoot.closeCommSettings() _linkRoot.closeCommSettings()
} }
} }
...@@ -287,6 +380,8 @@ Rectangle { ...@@ -287,6 +380,8 @@ Rectangle {
width: ScreenTools.defaultFontPixelWidth * 10 width: ScreenTools.defaultFontPixelWidth * 10
text: "Cancel" text: "Cancel"
onClicked: { onClicked: {
QGroundControl.linkManager.cancelConfigurationEditing(editConfig)
editConfig = null
_linkRoot.closeCommSettings() _linkRoot.closeCommSettings()
} }
} }
...@@ -327,10 +422,21 @@ Rectangle { ...@@ -327,10 +422,21 @@ Rectangle {
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
onActivated: { onActivated: {
if (index != -1) { if (index != -1) {
subEditConfig.portName = QGroundControl.linkManager.serialPorts[index]
} }
} }
Component.onCompleted: { Component.onCompleted: {
if(config != null) { if(subEditConfig != null) {
if(subEditConfig.portDisplayName === "")
subEditConfig.portName = QGroundControl.linkManager.serialPorts[0]
var index = commPortCombo.find(subEditConfig.portDisplayName)
if (index === -1) {
console.warn("Serial Port not present", subEditConfig.portName)
} else {
commPortCombo.currentIndex = index
}
} else {
commPortCombo.currentIndex = 0
} }
} }
} }
...@@ -349,15 +455,16 @@ Rectangle { ...@@ -349,15 +455,16 @@ Rectangle {
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
onActivated: { onActivated: {
if (index != -1) { if (index != -1) {
subEditConfig.baud = parseInt(QGroundControl.linkManager.serialBaudRates[index])
} }
} }
Component.onCompleted: { Component.onCompleted: {
var baud = "57600" var baud = "57600"
if(config != null) { if(subEditConfig != null) {
// Get baud from config baud = subEditConfig.baud.toString()
} }
var index = baudCombo.find(baud) var index = baudCombo.find(baud)
if (index == -1) { if (index === -1) {
console.warn("Baud rate name not in combo box", baud) console.warn("Baud rate name not in combo box", baud)
} else { } else {
baudCombo.currentIndex = index baudCombo.currentIndex = index
...@@ -365,6 +472,128 @@ Rectangle { ...@@ -365,6 +472,128 @@ Rectangle {
} }
} }
} }
Item {
height: ScreenTools.defaultFontPixelHeight / 2
width: parent.width
}
//-----------------------------------------------------------------
//-- Advanced Serial Settings
QGCCheckBox {
id: showAdvanced
text: "Show Advanced Serial Settings"
}
Item {
height: ScreenTools.defaultFontPixelHeight / 2
width: parent.width
}
//-- Flow Control
QGCCheckBox {
text: "Enable Flow Control"
checked: subEditConfig ? subEditConfig.flowControl !== 0 : false
visible: showAdvanced.checked
onCheckedChanged: {
if(subEditConfig) {
subEditConfig.flowControl = checked ? 1 : 0
}
}
}
//-- Parity
Row {
spacing: ScreenTools.defaultFontPixelWidth
visible: showAdvanced.checked
QGCLabel {
text: "Parity:"
width: _firstColumn
anchors.verticalCenter: parent.verticalCenter
}
QGCComboBox {
id: parityCombo
width: _firstColumn
model: ["None", "Even", "Odd"]
anchors.verticalCenter: parent.verticalCenter
onActivated: {
if (index != -1) {
// Hard coded values from qserialport.h
if(index == 0)
subEditConfig.parity = 0
else if(index == 1)
subEditConfig.parity = 2
else
subEditConfig.parity = 3
}
}
Component.onCompleted: {
var index = 0
if(subEditConfig != null) {
index = subEditConfig.parity
}
if(index > 1) {
index = index - 2
}
parityCombo.currentIndex = index
}
}
}
//-- Data Bits
Row {
spacing: ScreenTools.defaultFontPixelWidth
visible: showAdvanced.checked
QGCLabel {
text: "Data Bits:"
width: _firstColumn
anchors.verticalCenter: parent.verticalCenter
}
QGCComboBox {
id: dataCombo
width: _firstColumn
model: ["5", "6", "7", "8"]
anchors.verticalCenter: parent.verticalCenter
onActivated: {
if (index != -1) {
subEditConfig.dataBits = index + 5
}
}
Component.onCompleted: {
var index = 3
if(subEditConfig != null) {
index = subEditConfig.parity - 5
if(index < 0)
index = 3
}
dataCombo.currentIndex = index
}
}
}
//-- Stop Bits
Row {
spacing: ScreenTools.defaultFontPixelWidth
visible: showAdvanced.checked
QGCLabel {
text: "Stop Bits:"
width: _firstColumn
anchors.verticalCenter: parent.verticalCenter
}
QGCComboBox {
id: stopCombo
width: _firstColumn
model: ["1", "2"]
anchors.verticalCenter: parent.verticalCenter
onActivated: {
if (index != -1) {
subEditConfig.stopBits = index + 1
}
}
Component.onCompleted: {
var index = 0
if(subEditConfig != null) {
index = subEditConfig.stopBits - 1
if(index < 0)
index = 0
}
stopCombo.currentIndex = index
}
}
}
} }
} }
//--------------------------------------------- //---------------------------------------------
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment