mirror of
				https://github.com/ciphervance/supercell-wx.git
				synced 2025-10-31 02:10: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
	
	 Dan Paulat
						Dan Paulat