/*===================================================================== QGroundControl Open Source Ground Control Station (c) 2009, 2015 QGROUNDCONTROL PROJECT This file is part of the QGROUNDCONTROL project QGROUNDCONTROL 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. QGROUNDCONTROL 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 QGROUNDCONTROL. If not, see . ======================================================================*/ /** * @file * @brief Implementation of QGCLinkConfiguration * @author Gus Grubba */ #include "SettingsDialog.h" #include "QGCLinkConfiguration.h" #include "ui_QGCLinkConfiguration.h" #include "QGCCommConfiguration.h" #include "QGCMessageBox.h" QGCLinkConfiguration::QGCLinkConfiguration(QWidget *parent) : QWidget(parent), _ui(new Ui::QGCLinkConfiguration) { // Stop automatic link updates while this UI is up qgcApp()->toolbox()->linkManager()->suspendConfigurationUpdates(true); _ui->setupUi(this); _viewModel = new LinkViewModel; _ui->linkView->setModel(_viewModel); _ui->connectLinkButton->setEnabled(false); _ui->delLinkButton->setEnabled(false); _ui->editLinkButton->setEnabled(false); } QGCLinkConfiguration::~QGCLinkConfiguration() { if(_viewModel) delete _viewModel; if(_ui) delete _ui; // Resume automatic link updates qgcApp()->toolbox()->linkManager()->suspendConfigurationUpdates(false); } void QGCLinkConfiguration::on_delLinkButton_clicked() { QModelIndex index = _ui->linkView->currentIndex(); if(index.row() >= 0) { LinkConfiguration* config = _viewModel->getConfiguration(index.row()); if(config) { // Ask user if they are sure QMessageBox::StandardButton button = QGCMessageBox::question( tr("Delete Link Configuration"), tr("Are you sure you want to delete %1?\nDeleting a configuration will also disconnect it if connected.").arg(config->name()), QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Cancel); if (button == QMessageBox::Yes) { // Get link attached to this configuration (if any) LinkInterface* iface = config->getLink(); if(iface) { // Disconnect it (if connected) qgcApp()->toolbox()->linkManager()->disconnectLink(iface); } _viewModel->beginChange(); // Remove configuration qgcApp()->toolbox()->linkManager()->removeLinkConfiguration(config); // Save list qgcApp()->toolbox()->linkManager()->saveLinkConfigurationList(); _viewModel->endChange(); } } } _updateButtons(); } void QGCLinkConfiguration::on_linkView_clicked(const QModelIndex&) { _updateButtons(); } void QGCLinkConfiguration::on_connectLinkButton_clicked() { QModelIndex index = _ui->linkView->currentIndex(); if(index.row() >= 0) { LinkConfiguration* config = _viewModel->getConfiguration(index.row()); if(config) { LinkInterface* link = config->getLink(); if(link) { // Disconnect Link if (link->isConnected()) { qgcApp()->toolbox()->linkManager()->disconnectLink(link); } } else { LinkInterface* link = qgcApp()->toolbox()->linkManager()->createConnectedLink(config); if(link) { // Now go hunting for the parent so we can shut this down QWidget* pQw = parentWidget(); while(pQw) { SettingsDialog* pDlg = dynamic_cast(pQw); if(pDlg) { pDlg->accept(); break; } pQw = pQw->parentWidget(); } } } } } _updateButtons(); } void QGCLinkConfiguration::on_editLinkButton_clicked() { QModelIndex index = _ui->linkView->currentIndex(); _editLink(index.row()); } void QGCLinkConfiguration::_fixUnnamed(LinkConfiguration* config) { Q_ASSERT(config != NULL); //-- Check for "Unnamed" if (config->name() == tr("Unnamed")) { switch(config->type()) { #ifndef __ios__ case LinkConfiguration::TypeSerial: { QString tname = dynamic_cast(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(config)->localPort())); break; case LinkConfiguration::TypeTcp: { TCPConfiguration* tconfig = dynamic_cast(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(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 } } } void QGCLinkConfiguration::on_addLinkButton_clicked() { QGCCommConfiguration* commDialog = new QGCCommConfiguration(this); if(commDialog->exec() == QDialog::Accepted) { // Save changes (if any) LinkConfiguration* config = commDialog->getConfig(); if(config) { _fixUnnamed(config); _viewModel->beginChange(); qgcApp()->toolbox()->linkManager()->addLinkConfiguration(commDialog->getConfig()); qgcApp()->toolbox()->linkManager()->saveLinkConfigurationList(); _viewModel->endChange(); } } _updateButtons(); } void QGCLinkConfiguration::on_linkView_doubleClicked(const QModelIndex &index) { _editLink(index.row()); } void QGCLinkConfiguration::_editLink(int row) { if(row >= 0) { LinkConfiguration* config = _viewModel->getConfiguration(row); if(config) { LinkConfiguration* tmpConfig = LinkConfiguration::duplicateSettings(config); QGCCommConfiguration* commDialog = new QGCCommConfiguration(this, tmpConfig); if(commDialog->exec() == QDialog::Accepted) { // Save changes (if any) if(commDialog->getConfig()) { _fixUnnamed(tmpConfig); _viewModel->beginChange(); config->copyFrom(tmpConfig); // Save it qgcApp()->toolbox()->linkManager()->saveLinkConfigurationList(); _viewModel->endChange(); // Tell link about changes (if any) config->updateSettings(); } } // Discard temporary duplicate if(commDialog->getConfig()) delete commDialog->getConfig(); } } _updateButtons(); } void QGCLinkConfiguration::_updateButtons() { LinkConfiguration* config = NULL; QModelIndex index = _ui->linkView->currentIndex(); bool enabled = (index.row() >= 0); bool deleteEnabled = true; if(enabled) { config = _viewModel->getConfiguration(index.row()); if(config) { // Can't delete a dynamic link if(config->isDynamic()) { deleteEnabled = false; } LinkInterface* link = config->getLink(); if(link) { _ui->connectLinkButton->setText("Disconnect"); } else { _ui->connectLinkButton->setText("Connect"); } } } _ui->connectLinkButton->setEnabled(enabled); _ui->delLinkButton->setEnabled(config != NULL && deleteEnabled); _ui->editLinkButton->setEnabled(config != NULL); } LinkViewModel::LinkViewModel(QObject *parent) : QAbstractListModel(parent) { Q_UNUSED(parent); } int LinkViewModel::rowCount( const QModelIndex & parent) const { Q_UNUSED(parent); QList cfgList = qgcApp()->toolbox()->linkManager()->getLinkConfigurationList(); int count = cfgList.count(); return count; } QVariant LinkViewModel::data( const QModelIndex & index, int role) const { QList cfgList = qgcApp()->toolbox()->linkManager()->getLinkConfigurationList(); if (role == Qt::DisplayRole && index.row() < cfgList.count()) { QString name(cfgList.at(index.row())->name()); return name; } return QVariant(); } LinkConfiguration* LinkViewModel::getConfiguration(int row) { QList cfgList = qgcApp()->toolbox()->linkManager()->getLinkConfigurationList(); if(row < cfgList.count()) { return cfgList.at(row); } return NULL; }