1/****************************************************************************
2**
3** Copyright (C) 2012 Denis Shienkov <denis.shienkov@gmail.com>
4** Copyright (C) 2012 Laszlo Papp <lpapp@kde.org>
5** Contact: https://www.qt.io/licensing/
6**
7** This file is part of the QtSerialPort module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:BSD$
10** Commercial License Usage
11** Licensees holding valid commercial Qt licenses may use this file in
12** accordance with the commercial license agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and The Qt Company. For licensing terms
15** and conditions see https://www.qt.io/terms-conditions. For further
16** information use the contact form at https://www.qt.io/contact-us.
17**
18** BSD License Usage
19** Alternatively, you may use this file under the terms of the BSD license
20** as follows:
21**
22** "Redistribution and use in source and binary forms, with or without
23** modification, are permitted provided that the following conditions are
24** met:
25** * Redistributions of source code must retain the above copyright
26** notice, this list of conditions and the following disclaimer.
27** * Redistributions in binary form must reproduce the above copyright
28** notice, this list of conditions and the following disclaimer in
29** the documentation and/or other materials provided with the
30** distribution.
31** * Neither the name of The Qt Company Ltd nor the names of its
32** contributors may be used to endorse or promote products derived
33** from this software without specific prior written permission.
34**
35**
36** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
37** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
38** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
39** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
40** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
43** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
44** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
45** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
46** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
47**
48** $QT_END_LICENSE$
49**
50****************************************************************************/
51
52#include "settingsdialog.h"
53#include "ui_settingsdialog.h"
54
55#include <QIntValidator>
56#include <QLineEdit>
57#include <QSerialPortInfo>
58
59static const char blankString[] = QT_TRANSLATE_NOOP("SettingsDialog", "N/A");
60
61SettingsDialog::SettingsDialog(QWidget *parent) :
62 QDialog(parent),
63 m_ui(new Ui::SettingsDialog),
64 m_intValidator(new QIntValidator(0, 4000000, this))
65{
66 m_ui->setupUi(this);
67
68 m_ui->baudRateBox->setInsertPolicy(QComboBox::NoInsert);
69
70 connect(sender: m_ui->applyButton, signal: &QPushButton::clicked,
71 receiver: this, slot: &SettingsDialog::apply);
72 connect(sender: m_ui->serialPortInfoListBox, signal: QOverload<int>::of(ptr: &QComboBox::currentIndexChanged),
73 receiver: this, slot: &SettingsDialog::showPortInfo);
74 connect(sender: m_ui->baudRateBox, signal: QOverload<int>::of(ptr: &QComboBox::currentIndexChanged),
75 receiver: this, slot: &SettingsDialog::checkCustomBaudRatePolicy);
76 connect(sender: m_ui->serialPortInfoListBox, signal: QOverload<int>::of(ptr: &QComboBox::currentIndexChanged),
77 receiver: this, slot: &SettingsDialog::checkCustomDevicePathPolicy);
78
79 fillPortsParameters();
80 fillPortsInfo();
81
82 updateSettings();
83}
84
85SettingsDialog::~SettingsDialog()
86{
87 delete m_ui;
88}
89
90SettingsDialog::Settings SettingsDialog::settings() const
91{
92 return m_currentSettings;
93}
94
95void SettingsDialog::showPortInfo(int idx)
96{
97 if (idx == -1)
98 return;
99
100 const QStringList list = m_ui->serialPortInfoListBox->itemData(index: idx).toStringList();
101 m_ui->descriptionLabel->setText(tr(s: "Description: %1").arg(a: list.count() > 1 ? list.at(i: 1) : tr(s: blankString)));
102 m_ui->manufacturerLabel->setText(tr(s: "Manufacturer: %1").arg(a: list.count() > 2 ? list.at(i: 2) : tr(s: blankString)));
103 m_ui->serialNumberLabel->setText(tr(s: "Serial number: %1").arg(a: list.count() > 3 ? list.at(i: 3) : tr(s: blankString)));
104 m_ui->locationLabel->setText(tr(s: "Location: %1").arg(a: list.count() > 4 ? list.at(i: 4) : tr(s: blankString)));
105 m_ui->vidLabel->setText(tr(s: "Vendor Identifier: %1").arg(a: list.count() > 5 ? list.at(i: 5) : tr(s: blankString)));
106 m_ui->pidLabel->setText(tr(s: "Product Identifier: %1").arg(a: list.count() > 6 ? list.at(i: 6) : tr(s: blankString)));
107}
108
109void SettingsDialog::apply()
110{
111 updateSettings();
112 hide();
113}
114
115void SettingsDialog::checkCustomBaudRatePolicy(int idx)
116{
117 const bool isCustomBaudRate = !m_ui->baudRateBox->itemData(index: idx).isValid();
118 m_ui->baudRateBox->setEditable(isCustomBaudRate);
119 if (isCustomBaudRate) {
120 m_ui->baudRateBox->clearEditText();
121 QLineEdit *edit = m_ui->baudRateBox->lineEdit();
122 edit->setValidator(m_intValidator);
123 }
124}
125
126void SettingsDialog::checkCustomDevicePathPolicy(int idx)
127{
128 const bool isCustomPath = !m_ui->serialPortInfoListBox->itemData(index: idx).isValid();
129 m_ui->serialPortInfoListBox->setEditable(isCustomPath);
130 if (isCustomPath)
131 m_ui->serialPortInfoListBox->clearEditText();
132}
133
134void SettingsDialog::fillPortsParameters()
135{
136 m_ui->baudRateBox->addItem(QStringLiteral("9600"), auserData: QSerialPort::Baud9600);
137 m_ui->baudRateBox->addItem(QStringLiteral("19200"), auserData: QSerialPort::Baud19200);
138 m_ui->baudRateBox->addItem(QStringLiteral("38400"), auserData: QSerialPort::Baud38400);
139 m_ui->baudRateBox->addItem(QStringLiteral("115200"), auserData: QSerialPort::Baud115200);
140 m_ui->baudRateBox->addItem(atext: tr(s: "Custom"));
141
142 m_ui->dataBitsBox->addItem(QStringLiteral("5"), auserData: QSerialPort::Data5);
143 m_ui->dataBitsBox->addItem(QStringLiteral("6"), auserData: QSerialPort::Data6);
144 m_ui->dataBitsBox->addItem(QStringLiteral("7"), auserData: QSerialPort::Data7);
145 m_ui->dataBitsBox->addItem(QStringLiteral("8"), auserData: QSerialPort::Data8);
146 m_ui->dataBitsBox->setCurrentIndex(3);
147
148 m_ui->parityBox->addItem(atext: tr(s: "None"), auserData: QSerialPort::NoParity);
149 m_ui->parityBox->addItem(atext: tr(s: "Even"), auserData: QSerialPort::EvenParity);
150 m_ui->parityBox->addItem(atext: tr(s: "Odd"), auserData: QSerialPort::OddParity);
151 m_ui->parityBox->addItem(atext: tr(s: "Mark"), auserData: QSerialPort::MarkParity);
152 m_ui->parityBox->addItem(atext: tr(s: "Space"), auserData: QSerialPort::SpaceParity);
153
154 m_ui->stopBitsBox->addItem(QStringLiteral("1"), auserData: QSerialPort::OneStop);
155#ifdef Q_OS_WIN
156 m_ui->stopBitsBox->addItem(tr("1.5"), QSerialPort::OneAndHalfStop);
157#endif
158 m_ui->stopBitsBox->addItem(QStringLiteral("2"), auserData: QSerialPort::TwoStop);
159
160 m_ui->flowControlBox->addItem(atext: tr(s: "None"), auserData: QSerialPort::NoFlowControl);
161 m_ui->flowControlBox->addItem(atext: tr(s: "RTS/CTS"), auserData: QSerialPort::HardwareControl);
162 m_ui->flowControlBox->addItem(atext: tr(s: "XON/XOFF"), auserData: QSerialPort::SoftwareControl);
163}
164
165void SettingsDialog::fillPortsInfo()
166{
167 m_ui->serialPortInfoListBox->clear();
168 QString description;
169 QString manufacturer;
170 QString serialNumber;
171 const auto infos = QSerialPortInfo::availablePorts();
172 for (const QSerialPortInfo &info : infos) {
173 QStringList list;
174 description = info.description();
175 manufacturer = info.manufacturer();
176 serialNumber = info.serialNumber();
177 list << info.portName()
178 << (!description.isEmpty() ? description : blankString)
179 << (!manufacturer.isEmpty() ? manufacturer : blankString)
180 << (!serialNumber.isEmpty() ? serialNumber : blankString)
181 << info.systemLocation()
182 << (info.vendorIdentifier() ? QString::number(info.vendorIdentifier(), base: 16) : blankString)
183 << (info.productIdentifier() ? QString::number(info.productIdentifier(), base: 16) : blankString);
184
185 m_ui->serialPortInfoListBox->addItem(atext: list.first(), auserData: list);
186 }
187
188 m_ui->serialPortInfoListBox->addItem(atext: tr(s: "Custom"));
189}
190
191void SettingsDialog::updateSettings()
192{
193 m_currentSettings.name = m_ui->serialPortInfoListBox->currentText();
194
195 if (m_ui->baudRateBox->currentIndex() == 4) {
196 m_currentSettings.baudRate = m_ui->baudRateBox->currentText().toInt();
197 } else {
198 m_currentSettings.baudRate = static_cast<QSerialPort::BaudRate>(
199 m_ui->baudRateBox->itemData(index: m_ui->baudRateBox->currentIndex()).toInt());
200 }
201 m_currentSettings.stringBaudRate = QString::number(m_currentSettings.baudRate);
202
203 m_currentSettings.dataBits = static_cast<QSerialPort::DataBits>(
204 m_ui->dataBitsBox->itemData(index: m_ui->dataBitsBox->currentIndex()).toInt());
205 m_currentSettings.stringDataBits = m_ui->dataBitsBox->currentText();
206
207 m_currentSettings.parity = static_cast<QSerialPort::Parity>(
208 m_ui->parityBox->itemData(index: m_ui->parityBox->currentIndex()).toInt());
209 m_currentSettings.stringParity = m_ui->parityBox->currentText();
210
211 m_currentSettings.stopBits = static_cast<QSerialPort::StopBits>(
212 m_ui->stopBitsBox->itemData(index: m_ui->stopBitsBox->currentIndex()).toInt());
213 m_currentSettings.stringStopBits = m_ui->stopBitsBox->currentText();
214
215 m_currentSettings.flowControl = static_cast<QSerialPort::FlowControl>(
216 m_ui->flowControlBox->itemData(index: m_ui->flowControlBox->currentIndex()).toInt());
217 m_currentSettings.stringFlowControl = m_ui->flowControlBox->currentText();
218
219 m_currentSettings.localEchoEnabled = m_ui->localEchoCheckBox->isChecked();
220}
221

source code of qtserialport/examples/serialport/terminal/settingsdialog.cpp