mirror of
https://github.com/ciphervance/supercell-wx.git
synced 2025-10-30 21:40:05 +00:00
Initial serial port dialog work
This commit is contained in:
parent
523c26ed47
commit
230c96e450
5 changed files with 333 additions and 1 deletions
|
|
@ -34,7 +34,7 @@ Supercell Wx uses code from the following dependencies:
|
||||||
| [MapLibre Native](https://maplibre.org/projects/maplibre-native/) | [BSD 2-Clause "Simplified" License](https://spdx.org/licenses/BSD-2-Clause.html) |
|
| [MapLibre Native](https://maplibre.org/projects/maplibre-native/) | [BSD 2-Clause "Simplified" License](https://spdx.org/licenses/BSD-2-Clause.html) |
|
||||||
| [nunicode](https://bitbucket.org/alekseyt/nunicode/src/master/) | [MIT License](https://spdx.org/licenses/MIT.html) | Modified for MapLibre Native |
|
| [nunicode](https://bitbucket.org/alekseyt/nunicode/src/master/) | [MIT License](https://spdx.org/licenses/MIT.html) | Modified for MapLibre Native |
|
||||||
| [OpenSSL](https://www.openssl.org/) | [OpenSSL License](https://spdx.org/licenses/OpenSSL.html) |
|
| [OpenSSL](https://www.openssl.org/) | [OpenSSL License](https://spdx.org/licenses/OpenSSL.html) |
|
||||||
| [Qt](https://www.qt.io/) | [GNU Lesser General Public License v3.0 only](https://spdx.org/licenses/LGPL-3.0-only.html) | Qt Core, Qt GUI, Qt Multimedia, Qt Network, Qt OpenGL, Qt Positioning, Qt SQL, Qt SVG, Qt Widgets<br/>Additional Licenses: https://doc.qt.io/qt-6/licenses-used-in-qt.html |
|
| [Qt](https://www.qt.io/) | [GNU Lesser General Public License v3.0 only](https://spdx.org/licenses/LGPL-3.0-only.html) | Qt Core, Qt GUI, Qt Multimedia, Qt Network, Qt OpenGL, Qt Positioning, Qt Serial Port, Qt SQL, Qt SVG, Qt Widgets<br/>Additional Licenses: https://doc.qt.io/qt-6/licenses-used-in-qt.html |
|
||||||
| [re2](https://github.com/google/re2) | [BSD 3-Clause "New" or "Revised" License](https://spdx.org/licenses/BSD-3-Clause.html) |
|
| [re2](https://github.com/google/re2) | [BSD 3-Clause "New" or "Revised" License](https://spdx.org/licenses/BSD-3-Clause.html) |
|
||||||
| [spdlog](https://github.com/gabime/spdlog) | [MIT License](https://spdx.org/licenses/MIT.html) |
|
| [spdlog](https://github.com/gabime/spdlog) | [MIT License](https://spdx.org/licenses/MIT.html) |
|
||||||
| [SQLite](https://www.sqlite.org/) | Public Domain |
|
| [SQLite](https://www.sqlite.org/) | Public Domain |
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ find_package(QT NAMES Qt6
|
||||||
OpenGL
|
OpenGL
|
||||||
OpenGLWidgets
|
OpenGLWidgets
|
||||||
Positioning
|
Positioning
|
||||||
|
SerialPort
|
||||||
Svg
|
Svg
|
||||||
Widgets REQUIRED)
|
Widgets REQUIRED)
|
||||||
|
|
||||||
|
|
@ -39,6 +40,7 @@ find_package(Qt${QT_VERSION_MAJOR}
|
||||||
OpenGL
|
OpenGL
|
||||||
OpenGLWidgets
|
OpenGLWidgets
|
||||||
Positioning
|
Positioning
|
||||||
|
SerialPort
|
||||||
Svg
|
Svg
|
||||||
Widgets
|
Widgets
|
||||||
REQUIRED)
|
REQUIRED)
|
||||||
|
|
@ -248,6 +250,7 @@ set(HDR_UI source/scwx/qt/ui/about_dialog.hpp
|
||||||
source/scwx/qt/ui/placefile_settings_widget.hpp
|
source/scwx/qt/ui/placefile_settings_widget.hpp
|
||||||
source/scwx/qt/ui/progress_dialog.hpp
|
source/scwx/qt/ui/progress_dialog.hpp
|
||||||
source/scwx/qt/ui/radar_site_dialog.hpp
|
source/scwx/qt/ui/radar_site_dialog.hpp
|
||||||
|
source/scwx/qt/ui/serial_port_dialog.hpp
|
||||||
source/scwx/qt/ui/settings_dialog.hpp
|
source/scwx/qt/ui/settings_dialog.hpp
|
||||||
source/scwx/qt/ui/update_dialog.hpp)
|
source/scwx/qt/ui/update_dialog.hpp)
|
||||||
set(SRC_UI source/scwx/qt/ui/about_dialog.cpp
|
set(SRC_UI source/scwx/qt/ui/about_dialog.cpp
|
||||||
|
|
@ -272,6 +275,7 @@ set(SRC_UI source/scwx/qt/ui/about_dialog.cpp
|
||||||
source/scwx/qt/ui/progress_dialog.cpp
|
source/scwx/qt/ui/progress_dialog.cpp
|
||||||
source/scwx/qt/ui/radar_site_dialog.cpp
|
source/scwx/qt/ui/radar_site_dialog.cpp
|
||||||
source/scwx/qt/ui/settings_dialog.cpp
|
source/scwx/qt/ui/settings_dialog.cpp
|
||||||
|
source/scwx/qt/ui/serial_port_dialog.cpp
|
||||||
source/scwx/qt/ui/update_dialog.cpp)
|
source/scwx/qt/ui/update_dialog.cpp)
|
||||||
set(UI_UI source/scwx/qt/ui/about_dialog.ui
|
set(UI_UI source/scwx/qt/ui/about_dialog.ui
|
||||||
source/scwx/qt/ui/alert_dialog.ui
|
source/scwx/qt/ui/alert_dialog.ui
|
||||||
|
|
@ -287,6 +291,7 @@ set(UI_UI source/scwx/qt/ui/about_dialog.ui
|
||||||
source/scwx/qt/ui/progress_dialog.ui
|
source/scwx/qt/ui/progress_dialog.ui
|
||||||
source/scwx/qt/ui/radar_site_dialog.ui
|
source/scwx/qt/ui/radar_site_dialog.ui
|
||||||
source/scwx/qt/ui/settings_dialog.ui
|
source/scwx/qt/ui/settings_dialog.ui
|
||||||
|
source/scwx/qt/ui/serial_port_dialog.ui
|
||||||
source/scwx/qt/ui/update_dialog.ui)
|
source/scwx/qt/ui/update_dialog.ui)
|
||||||
set(HDR_UI_SETTINGS source/scwx/qt/ui/settings/hotkey_settings_widget.hpp
|
set(HDR_UI_SETTINGS source/scwx/qt/ui/settings/hotkey_settings_widget.hpp
|
||||||
source/scwx/qt/ui/settings/settings_page_widget.hpp
|
source/scwx/qt/ui/settings/settings_page_widget.hpp
|
||||||
|
|
@ -597,6 +602,7 @@ target_link_libraries(scwx-qt PUBLIC Qt${QT_VERSION_MAJOR}::Widgets
|
||||||
Qt${QT_VERSION_MAJOR}::OpenGLWidgets
|
Qt${QT_VERSION_MAJOR}::OpenGLWidgets
|
||||||
Qt${QT_VERSION_MAJOR}::Multimedia
|
Qt${QT_VERSION_MAJOR}::Multimedia
|
||||||
Qt${QT_VERSION_MAJOR}::Positioning
|
Qt${QT_VERSION_MAJOR}::Positioning
|
||||||
|
Qt${QT_VERSION_MAJOR}::SerialPort
|
||||||
Qt${QT_VERSION_MAJOR}::Svg
|
Qt${QT_VERSION_MAJOR}::Svg
|
||||||
Boost::json
|
Boost::json
|
||||||
Boost::timer
|
Boost::timer
|
||||||
|
|
|
||||||
199
scwx-qt/source/scwx/qt/ui/serial_port_dialog.cpp
Normal file
199
scwx-qt/source/scwx/qt/ui/serial_port_dialog.cpp
Normal file
|
|
@ -0,0 +1,199 @@
|
||||||
|
#define __STDC_WANT_LIB_EXT1__ 1
|
||||||
|
|
||||||
|
#include "serial_port_dialog.hpp"
|
||||||
|
#include "ui_serial_port_dialog.h"
|
||||||
|
|
||||||
|
#include <scwx/util/logger.hpp>
|
||||||
|
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <QSerialPortInfo>
|
||||||
|
#include <QSortFilterProxyModel>
|
||||||
|
#include <QStandardItemModel>
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
|
# include <Windows.h>
|
||||||
|
# include <cstdlib>
|
||||||
|
# include <tchar.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace scwx
|
||||||
|
{
|
||||||
|
namespace qt
|
||||||
|
{
|
||||||
|
namespace ui
|
||||||
|
{
|
||||||
|
|
||||||
|
static const std::string logPrefix_ = "scwx::qt::ui::serial_port_dialog";
|
||||||
|
static const auto logger_ = scwx::util::Logger::Create(logPrefix_);
|
||||||
|
|
||||||
|
class SerialPortDialog::Impl
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit Impl(SerialPortDialog* self) :
|
||||||
|
self_ {self}, model_ {new QStandardItemModel(self)}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
~Impl() = default;
|
||||||
|
|
||||||
|
void LogSerialPortInfo(const QSerialPortInfo& info);
|
||||||
|
void ReadComPortSettings();
|
||||||
|
void RefreshSerialDevices();
|
||||||
|
|
||||||
|
SerialPortDialog* self_;
|
||||||
|
QStandardItemModel* model_;
|
||||||
|
|
||||||
|
std::string selectedSerialPort_ {"?"};
|
||||||
|
};
|
||||||
|
|
||||||
|
SerialPortDialog::SerialPortDialog(QWidget* parent) :
|
||||||
|
QDialog(parent),
|
||||||
|
p {std::make_unique<Impl>(this)},
|
||||||
|
ui(new Ui::SerialPortDialog)
|
||||||
|
{
|
||||||
|
ui->setupUi(this);
|
||||||
|
|
||||||
|
connect(ui->refreshButton,
|
||||||
|
&QAbstractButton::clicked,
|
||||||
|
this,
|
||||||
|
[this]() { p->RefreshSerialDevices(); });
|
||||||
|
}
|
||||||
|
|
||||||
|
SerialPortDialog::~SerialPortDialog()
|
||||||
|
{
|
||||||
|
delete ui;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string SerialPortDialog::serial_port()
|
||||||
|
{
|
||||||
|
return p->selectedSerialPort_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SerialPortDialog::Impl::LogSerialPortInfo(const QSerialPortInfo& info)
|
||||||
|
{
|
||||||
|
logger_->debug("Serial Port: {}", info.portName().toStdString());
|
||||||
|
logger_->debug(" Description: {}", info.description().toStdString());
|
||||||
|
logger_->debug(" System Loc: {}", info.systemLocation().toStdString());
|
||||||
|
logger_->debug(" Manufacturer: {}", info.manufacturer().toStdString());
|
||||||
|
logger_->debug(" Vendor ID: {}", info.vendorIdentifier());
|
||||||
|
logger_->debug(" Product ID: {}", info.productIdentifier());
|
||||||
|
logger_->debug(" Serial No: {}", info.serialNumber().toStdString());
|
||||||
|
}
|
||||||
|
|
||||||
|
void SerialPortDialog::Impl::RefreshSerialDevices()
|
||||||
|
{
|
||||||
|
QList<QSerialPortInfo> availablePorts = QSerialPortInfo::availablePorts();
|
||||||
|
|
||||||
|
for (auto& port : availablePorts)
|
||||||
|
{
|
||||||
|
LogSerialPortInfo(port);
|
||||||
|
}
|
||||||
|
|
||||||
|
ReadComPortSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SerialPortDialog::Impl::ReadComPortSettings()
|
||||||
|
{
|
||||||
|
#if defined(_WIN32)
|
||||||
|
const LPCTSTR lpSubKey =
|
||||||
|
TEXT("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Ports");
|
||||||
|
DWORD ulOptions = 0;
|
||||||
|
REGSAM samDesired = KEY_READ;
|
||||||
|
HKEY hkResult;
|
||||||
|
LSTATUS status;
|
||||||
|
|
||||||
|
// Open Port Settings Key
|
||||||
|
status = RegOpenKeyEx(
|
||||||
|
HKEY_LOCAL_MACHINE, lpSubKey, ulOptions, samDesired, &hkResult);
|
||||||
|
|
||||||
|
if (status == ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
DWORD dwIndex = 0;
|
||||||
|
TCHAR valueName[MAX_PATH];
|
||||||
|
LPDWORD lpReserved = nullptr;
|
||||||
|
DWORD type;
|
||||||
|
TCHAR valueData[64];
|
||||||
|
char buffer[MAX_PATH]; // Buffer for string conversion
|
||||||
|
|
||||||
|
// Number of characters, not including terminating null
|
||||||
|
static constexpr DWORD maxValueNameSize =
|
||||||
|
sizeof(valueName) / sizeof(TCHAR) - 1;
|
||||||
|
DWORD valueNameSize = maxValueNameSize;
|
||||||
|
|
||||||
|
// Number of bytes
|
||||||
|
DWORD valueDataSize = sizeof(valueData);
|
||||||
|
|
||||||
|
static constexpr std::size_t bufferSize = sizeof(buffer);
|
||||||
|
|
||||||
|
// Enumerate each port value
|
||||||
|
while ((status = RegEnumValue(hkResult,
|
||||||
|
dwIndex,
|
||||||
|
valueName,
|
||||||
|
&valueNameSize,
|
||||||
|
lpReserved,
|
||||||
|
&type,
|
||||||
|
(LPBYTE) &valueData,
|
||||||
|
&valueDataSize)) == ERROR_SUCCESS ||
|
||||||
|
status == ERROR_MORE_DATA)
|
||||||
|
{
|
||||||
|
// Validate port value
|
||||||
|
if (status == ERROR_SUCCESS && //
|
||||||
|
type == REG_SZ && //
|
||||||
|
valueNameSize >= 5 && // COM#:
|
||||||
|
valueNameSize < sizeof(buffer) - 1 && // Strip off :
|
||||||
|
valueDataSize > sizeof(TCHAR) && // Null character
|
||||||
|
_tcsncmp(valueName, TEXT("COM"), 3) == 0)
|
||||||
|
{
|
||||||
|
errno_t error;
|
||||||
|
std::size_t returnValue;
|
||||||
|
|
||||||
|
// Get port name
|
||||||
|
if ((error = wcstombs_s(&returnValue,
|
||||||
|
buffer,
|
||||||
|
sizeof(buffer),
|
||||||
|
valueName,
|
||||||
|
valueNameSize - 1)) != 0)
|
||||||
|
{
|
||||||
|
logger_->error(
|
||||||
|
"Error converting registry value name to string: {}",
|
||||||
|
returnValue);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string portName = buffer;
|
||||||
|
|
||||||
|
// Get port data
|
||||||
|
if ((error = wcstombs_s(&returnValue,
|
||||||
|
buffer,
|
||||||
|
sizeof(buffer),
|
||||||
|
valueData,
|
||||||
|
sizeof(buffer) - 1)) != 0)
|
||||||
|
{
|
||||||
|
logger_->error(
|
||||||
|
"Error converting registry value data to string: {}",
|
||||||
|
returnValue);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string portData = buffer;
|
||||||
|
|
||||||
|
logger_->debug("Port {} has data \"{}\"", portName, portData);
|
||||||
|
}
|
||||||
|
|
||||||
|
valueNameSize = maxValueNameSize;
|
||||||
|
valueDataSize = sizeof(valueData);
|
||||||
|
++dwIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
RegCloseKey(hkResult);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
logger_->warn("Could not open COM port settings registry key: {}",
|
||||||
|
status);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace ui
|
||||||
|
} // namespace qt
|
||||||
|
} // namespace scwx
|
||||||
35
scwx-qt/source/scwx/qt/ui/serial_port_dialog.hpp
Normal file
35
scwx-qt/source/scwx/qt/ui/serial_port_dialog.hpp
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
|
||||||
|
namespace Ui
|
||||||
|
{
|
||||||
|
class SerialPortDialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace scwx
|
||||||
|
{
|
||||||
|
namespace qt
|
||||||
|
{
|
||||||
|
namespace ui
|
||||||
|
{
|
||||||
|
class SerialPortDialog : public QDialog
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_DISABLE_COPY_MOVE(SerialPortDialog)
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit SerialPortDialog(QWidget* parent = nullptr);
|
||||||
|
~SerialPortDialog();
|
||||||
|
|
||||||
|
std::string serial_port();
|
||||||
|
|
||||||
|
private:
|
||||||
|
class Impl;
|
||||||
|
std::unique_ptr<Impl> p;
|
||||||
|
Ui::SerialPortDialog* ui;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ui
|
||||||
|
} // namespace qt
|
||||||
|
} // namespace scwx
|
||||||
92
scwx-qt/source/scwx/qt/ui/serial_port_dialog.ui
Normal file
92
scwx-qt/source/scwx/qt/ui/serial_port_dialog.ui
Normal file
|
|
@ -0,0 +1,92 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>SerialPortDialog</class>
|
||||||
|
<widget class="QDialog" name="SerialPortDialog">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>400</width>
|
||||||
|
<height>300</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Select Serial Port</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QTreeView" name="serialPortView"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QWidget" name="widget" native="true">
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="refreshButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>&Refresh</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Orientation::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="standardButtons">
|
||||||
|
<set>QDialogButtonBox::StandardButton::Cancel|QDialogButtonBox::StandardButton::Ok</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>accepted()</signal>
|
||||||
|
<receiver>SerialPortDialog</receiver>
|
||||||
|
<slot>accept()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>248</x>
|
||||||
|
<y>254</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>157</x>
|
||||||
|
<y>274</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>rejected()</signal>
|
||||||
|
<receiver>SerialPortDialog</receiver>
|
||||||
|
<slot>reject()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>316</x>
|
||||||
|
<y>260</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>286</x>
|
||||||
|
<y>274</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
</connections>
|
||||||
|
</ui>
|
||||||
Loading…
Add table
Add a link
Reference in a new issue