mirror of
				https://github.com/ciphervance/supercell-wx.git
				synced 2025-10-30 23:50: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) | | ||||
| | [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) | | ||||
| | [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) | | ||||
| | [spdlog](https://github.com/gabime/spdlog) | [MIT License](https://spdx.org/licenses/MIT.html) | | ||||
| | [SQLite](https://www.sqlite.org/) | Public Domain | | ||||
|  |  | |||
|  | @ -28,6 +28,7 @@ find_package(QT NAMES Qt6 | |||
|                         OpenGL | ||||
|                         OpenGLWidgets | ||||
|                         Positioning | ||||
|                         SerialPort | ||||
|                         Svg | ||||
|                         Widgets REQUIRED) | ||||
| 
 | ||||
|  | @ -39,6 +40,7 @@ find_package(Qt${QT_VERSION_MAJOR} | |||
|                         OpenGL | ||||
|                         OpenGLWidgets | ||||
|                         Positioning | ||||
|                         SerialPort | ||||
|                         Svg | ||||
|                         Widgets | ||||
|              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/progress_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/update_dialog.hpp) | ||||
| 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/radar_site_dialog.cpp | ||||
|            source/scwx/qt/ui/settings_dialog.cpp | ||||
|            source/scwx/qt/ui/serial_port_dialog.cpp | ||||
|            source/scwx/qt/ui/update_dialog.cpp) | ||||
| set(UI_UI  source/scwx/qt/ui/about_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/radar_site_dialog.ui | ||||
|            source/scwx/qt/ui/settings_dialog.ui | ||||
|            source/scwx/qt/ui/serial_port_dialog.ui | ||||
|            source/scwx/qt/ui/update_dialog.ui) | ||||
| set(HDR_UI_SETTINGS source/scwx/qt/ui/settings/hotkey_settings_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}::Multimedia | ||||
|                                      Qt${QT_VERSION_MAJOR}::Positioning | ||||
|                                      Qt${QT_VERSION_MAJOR}::SerialPort | ||||
|                                      Qt${QT_VERSION_MAJOR}::Svg | ||||
|                                      Boost::json | ||||
|                                      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
	
	 Dan Paulat
						Dan Paulat