SerialConfigurationWindow.cc 8.04 KB
Newer Older
pixhawk's avatar
pixhawk committed
1 2
/*=====================================================================

3
QGroundControl Open Source Ground Control Station
pixhawk's avatar
pixhawk committed
4

5
(c) 2009, 2010 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
pixhawk's avatar
pixhawk committed
6

7
This file is part of the QGROUNDCONTROL project
pixhawk's avatar
pixhawk committed
8

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.

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
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 SerialConfigurationWindow
pixhawk's avatar
pixhawk committed
27 28 29 30 31
 *   @author Lorenz Meier <mavteam@student.ethz.ch>
 *
 */

#include <QDir>
32
#include <QSettings>
pixhawk's avatar
pixhawk committed
33
#include <QFileInfoList>
34
#include <QDebug>
dogmaphobic's avatar
dogmaphobic committed
35 36 37 38

#ifdef __android__
#include "qserialportinfo.h"
#else
39
#include <QSerialPortInfo>
dogmaphobic's avatar
dogmaphobic committed
40
#endif
pixhawk's avatar
pixhawk committed
41

42 43
#include <SerialConfigurationWindow.h>
#include <SerialLink.h>
Bryant's avatar
Bryant committed
44

45 46 47
#ifndef USE_ANCIENT_RATES
#define USE_ANCIENT_RATES 0
#endif
pixhawk's avatar
pixhawk committed
48

49 50 51 52 53 54
SerialConfigurationWindow::SerialConfigurationWindow(SerialConfiguration *config, QWidget *parent, Qt::WindowFlags flags)
    : QWidget(parent, flags)
{
    _ui.setupUi(this);
    Q_ASSERT(config != NULL);
    _config = config;
pixhawk's avatar
pixhawk committed
55

56 57 58 59
    // Scan for serial ports. Let the user know if none were found for debugging purposes
    if (!setupPortList()) {
        qDebug() << "No serial ports found.";
    }
60

61 62
    // Set up baud rates
    _ui.baudRate->clear();
63

64 65
    // Keep track of all desired baud rates by OS. These are iterated through
    // later and added to _ui.baudRate.
66
    QStringList supportedBaudRates = SerialConfiguration::supportedBaudRates();
pixhawk's avatar
pixhawk committed
67

68 69
    // Now actually add all of our supported baud rates to the ui.
    for (int i = 0; i < supportedBaudRates.size(); ++i) {
70
        _ui.baudRate->addItem(supportedBaudRates.at(i), supportedBaudRates.at(i).toInt());
71
    }
pixhawk's avatar
pixhawk committed
72

73
    // Connect the individual user interface inputs
74 75 76 77 78 79 80 81 82 83 84 85 86 87
    connect(_ui.portName,           static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
            this,  &SerialConfigurationWindow::setPortName);
    connect(_ui.baudRate,           static_cast<void (QComboBox::*)(int)>(&QComboBox::activated),
            this,            &SerialConfigurationWindow::setBaudRate);
    connect(_ui.dataBitsSpinBox, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged),
            this,         &SerialConfigurationWindow::setDataBits);
    connect(_ui.stopBitsSpinBox,    static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged),
            this,         &SerialConfigurationWindow::setStopBits);

    connect(_ui.flowControlCheckBox,&QCheckBox::toggled, this,             &SerialConfigurationWindow::enableFlowControl);
    connect(_ui.parNone,            &QRadioButton::toggled, this,             &SerialConfigurationWindow::setParityNone);
    connect(_ui.parOdd,             &QRadioButton::toggled, this,             &SerialConfigurationWindow::setParityOdd);
    connect(_ui.parEven,            &QRadioButton::toggled, this,             &SerialConfigurationWindow::setParityEven);
    connect(_ui.advCheckBox,        &QCheckBox::clicked, _ui.advGroupBox,  &QWidget::setVisible);
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108

    _ui.advCheckBox->setCheckable(true);
    _ui.advCheckBox->setChecked(false);
    _ui.advGroupBox->setVisible(false);

    switch(_config->parity()) {
    case QSerialPort::NoParity:
        _ui.parNone->setChecked(true);
        break;
    case QSerialPort::OddParity:
        _ui.parOdd->setChecked(true);
        break;
    case QSerialPort::EvenParity:
        _ui.parEven->setChecked(true);
        break;
    default:
        // Enforce default: no parity in link
        setParityNone(true);
        _ui.parNone->setChecked(true);
        break;
    }
pixhawk's avatar
pixhawk committed
109

110 111 112 113 114 115 116 117 118 119
    int idx = 0;
    _ui.flowControlCheckBox->setChecked(_config->flowControl() == QSerialPort::HardwareControl);
    idx = _ui.baudRate->findText(QString("%1").arg(_config->baud()));
    if(idx < 0) idx = _ui.baudRate->findText("57600");
    if(idx < 0) idx = 0;
    _ui.baudRate->setCurrentIndex(idx);
    _ui.dataBitsSpinBox->setValue(_config->dataBits());
    _ui.stopBitsSpinBox->setValue(_config->stopBits());
    _portCheckTimer = new QTimer(this);
    _portCheckTimer->setInterval(1000);
120
    connect(_portCheckTimer, &QTimer::timeout, this, &SerialConfigurationWindow::setupPortList);
pixhawk's avatar
pixhawk committed
121

122 123
    // Display the widget
    setWindowTitle(tr("Serial Communication Settings"));
pixhawk's avatar
pixhawk committed
124 125
}

126 127
SerialConfigurationWindow::~SerialConfigurationWindow()
{
pixhawk's avatar
pixhawk committed
128 129 130 131 132

}

void SerialConfigurationWindow::showEvent(QShowEvent* event)
{
133
    Q_UNUSED(event);
134
    _portCheckTimer->start();
pixhawk's avatar
pixhawk committed
135 136 137 138
}

void SerialConfigurationWindow::hideEvent(QHideEvent* event)
{
139
    Q_UNUSED(event);
140
    _portCheckTimer->stop();
pixhawk's avatar
pixhawk committed
141 142
}

143
bool SerialConfigurationWindow::setupPortList()
pixhawk's avatar
pixhawk committed
144
{
145 146 147 148
    bool changed = false;
    // Iterate found ports
    QList<QSerialPortInfo> portList = QSerialPortInfo::availablePorts();
    foreach (const QSerialPortInfo &info, portList)
149
    {
150 151 152
        QString name = info.portName();
        // Append newly found port to the list
        if (_ui.portName->findText(name) < 0)
153
        {
154 155 156
            // We show the user the "short name" but store the full port name
            _ui.portName->addItem(name, QVariant(info.systemLocation()));
            changed = true;
pixhawk's avatar
pixhawk committed
157 158
        }
    }
159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176
    // See if configured port (if any) is present
    if(changed) {
        int idx = _ui.portName->count() - 1;
        if(!_config->portName().isEmpty()) {
            idx = _ui.portName->findData(QVariant(_config->portName()));
            if(idx < 0) {
                idx = 0;
            }
        }
        _ui.portName->setCurrentIndex(idx);
        if(_ui.portName->count() > 0) {
            _ui.portName->setEditText(_ui.portName->itemText(idx));
        }
        if(_config->portName().isEmpty()) {
            setPortName(idx);
        }
    }
    return (_ui.portName->count() > 0);
pixhawk's avatar
pixhawk committed
177 178 179 180
}

void SerialConfigurationWindow::enableFlowControl(bool flow)
{
181
    _config->setFlowControl(flow ? QSerialPort::HardwareControl : QSerialPort::NoFlowControl);
dogmaphobic's avatar
dogmaphobic committed
182 183
    //-- If this was dynamic, it's now edited and persistent
    _config->setDynamic(false);
pixhawk's avatar
pixhawk committed
184 185
}

lm's avatar
lm committed
186
void SerialConfigurationWindow::setParityNone(bool accept)
pixhawk's avatar
pixhawk committed
187
{
dogmaphobic's avatar
dogmaphobic committed
188 189 190 191 192
    if (accept) {
        _config->setParity(QSerialPort::NoParity);
        //-- If this was dynamic, it's now edited and persistent
        _config->setDynamic(false);
    }
pixhawk's avatar
pixhawk committed
193 194
}

lm's avatar
lm committed
195
void SerialConfigurationWindow::setParityOdd(bool accept)
pixhawk's avatar
pixhawk committed
196
{
dogmaphobic's avatar
dogmaphobic committed
197 198 199 200 201
    if (accept) {
        _config->setParity(QSerialPort::OddParity);
        //-- If this was dynamic, it's now edited and persistent
        _config->setDynamic(false);
    }
pixhawk's avatar
pixhawk committed
202 203
}

lm's avatar
lm committed
204
void SerialConfigurationWindow::setParityEven(bool accept)
pixhawk's avatar
pixhawk committed
205
{
dogmaphobic's avatar
dogmaphobic committed
206 207 208 209 210
    if (accept) {
        _config->setParity(QSerialPort::EvenParity);
        //-- If this was dynamic, it's now edited and persistent
        _config->setDynamic(false);
    }
pixhawk's avatar
pixhawk committed
211 212
}

213
void SerialConfigurationWindow::setPortName(int index)
pixhawk's avatar
pixhawk committed
214
{
215 216 217 218
    // Get the full port name and store it in the config
    QString pname = _ui.portName->itemData(index).toString();
    if (_config->portName() != pname) {
        _config->setPortName(pname);
dogmaphobic's avatar
dogmaphobic committed
219 220
        //-- If this was dynamic, it's now edited and persistent
        _config->setDynamic(false);
pixhawk's avatar
pixhawk committed
221 222 223
    }
}

224
void SerialConfigurationWindow::setBaudRate(int index)
Bryant's avatar
Bryant committed
225
{
226 227
    int baud = _ui.baudRate->itemData(index).toInt();
    _config->setBaud(baud);
dogmaphobic's avatar
dogmaphobic committed
228 229
    //-- If this was dynamic, it's now edited and persistent
    _config->setDynamic(false);
Bryant's avatar
Bryant committed
230 231
}

232
void SerialConfigurationWindow::setDataBits(int bits)
Bryant's avatar
Bryant committed
233
{
234
    _config->setDataBits(bits);
dogmaphobic's avatar
dogmaphobic committed
235 236
    //-- If this was dynamic, it's now edited and persistent
    _config->setDynamic(false);
Bryant's avatar
Bryant committed
237 238
}

239
void SerialConfigurationWindow::setStopBits(int bits)
Bryant's avatar
Bryant committed
240
{
241
    _config->setStopBits(bits);
dogmaphobic's avatar
dogmaphobic committed
242 243
    //-- If this was dynamic, it's now edited and persistent
    _config->setDynamic(false);
Bryant's avatar
Bryant committed
244
}