diff --git a/include/f1x/openauto/autoapp/Configuration/IRecentAddressesList.hpp b/include/f1x/openauto/autoapp/Configuration/IRecentAddressesList.hpp new file mode 100644 index 0000000..88213de --- /dev/null +++ b/include/f1x/openauto/autoapp/Configuration/IRecentAddressesList.hpp @@ -0,0 +1,46 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* 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. + +* openauto is distributed in the hope that it will be useful, +* 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 +* along with openauto. If not, see . +*/ + +#pragma once + +#include +#include + +namespace f1x +{ +namespace openauto +{ +namespace autoapp +{ +namespace configuration +{ + +class IRecentAddressesList +{ +public: + typedef std::deque RecentAddresses; + + virtual void read() = 0; + virtual void insertAddress(const std::string& address) = 0; + virtual RecentAddresses getList() const = 0; +}; + +} +} +} +} diff --git a/include/f1x/openauto/autoapp/Configuration/RecentAddressesList.hpp b/include/f1x/openauto/autoapp/Configuration/RecentAddressesList.hpp new file mode 100644 index 0000000..3c12591 --- /dev/null +++ b/include/f1x/openauto/autoapp/Configuration/RecentAddressesList.hpp @@ -0,0 +1,57 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* 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. + +* openauto is distributed in the hope that it will be useful, +* 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 +* along with openauto. If not, see . +*/ + +#pragma once + +#include +#include + +namespace f1x +{ +namespace openauto +{ +namespace autoapp +{ +namespace configuration +{ + +class RecentAddressesList: public IRecentAddressesList +{ +public: + RecentAddressesList(size_t maxListSize); + + void read() override; + void insertAddress(const std::string& address) override; + RecentAddresses getList() const override; + +private: + void load(); + void save(); + + size_t maxListSize_; + RecentAddresses list_; + + static const std::string cConfigFileName; + static const std::string cRecentEntiresCount; + static const std::string cRecentEntryPrefix; +}; + +} +} +} +} diff --git a/include/f1x/openauto/autoapp/UI/ConnectDialog.hpp b/include/f1x/openauto/autoapp/UI/ConnectDialog.hpp index fe654ca..5395bef 100644 --- a/include/f1x/openauto/autoapp/UI/ConnectDialog.hpp +++ b/include/f1x/openauto/autoapp/UI/ConnectDialog.hpp @@ -1,8 +1,10 @@ #pragma once #include +#include #include #include +#include namespace Ui { class ConnectDialog; @@ -22,25 +24,31 @@ class ConnectDialog : public QDialog Q_OBJECT public: - explicit ConnectDialog(boost::asio::io_service& ioService, aasdk::tcp::ITCPWrapper& tcpWrapper, QWidget *parent = nullptr); + explicit ConnectDialog(boost::asio::io_service& ioService, aasdk::tcp::ITCPWrapper& tcpWrapper, openauto::autoapp::configuration::IRecentAddressesList& recentAddressesList, QWidget *parent = nullptr); ~ConnectDialog() override; signals: void connectToDevice(const QString& ipAddress); - void connectionSucceed(aasdk::tcp::ITCPEndpoint::SocketPointer socket); + void connectionSucceed(aasdk::tcp::ITCPEndpoint::SocketPointer socket, std::string ipAddress); void connectionFailed(const QString& message); private slots: void onConnectButtonClicked(); void onConnectionFailed(const QString& message); - void onConnectionSucceed(); + void onConnectionSucceed(aasdk::tcp::ITCPEndpoint::SocketPointer socket, std::string ipAddress); void setControlsEnabledStatus(bool status); - void connectHandler(const boost::system::error_code& ec, aasdk::tcp::ITCPEndpoint::SocketPointer socket); + void connectHandler(const boost::system::error_code& ec, std::string ipAddress, aasdk::tcp::ITCPEndpoint::SocketPointer socket); private: + void insertIpAddress(std::string ipAddress); + void loadRecentList(); + boost::asio::io_service& ioService_; aasdk::tcp::ITCPWrapper& tcpWrapper_; + openauto::autoapp::configuration::IRecentAddressesList& recentAddressesList_; Ui::ConnectDialog *ui_; + QStringListModel recentAddressesModel_; + QStringList recentAddressesModelList_; }; } diff --git a/src/autoapp/Configuration/RecentAddressesList.cpp b/src/autoapp/Configuration/RecentAddressesList.cpp new file mode 100644 index 0000000..7d8af3e --- /dev/null +++ b/src/autoapp/Configuration/RecentAddressesList.cpp @@ -0,0 +1,106 @@ +/* +* This file is part of openauto project. +* Copyright (C) 2018 f1x.studio (Michal Szwaj) +* +* openauto is free software: you can redistribute it and/or modify +* 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. + +* openauto is distributed in the hope that it will be useful, +* 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 +* along with openauto. If not, see . +*/ + +#include +#include +#include + +namespace f1x +{ +namespace openauto +{ +namespace autoapp +{ +namespace configuration +{ + +const std::string RecentAddressesList::cConfigFileName = "openauto_wifi_recent.ini"; +const std::string RecentAddressesList::cRecentEntiresCount = "Recent.EntiresCount"; +const std::string RecentAddressesList::cRecentEntryPrefix = "Recent.Entry_"; + +RecentAddressesList::RecentAddressesList(size_t maxListSize) + : maxListSize_(maxListSize) +{ + +} + +void RecentAddressesList::read() +{ + this->load(); +} + +void RecentAddressesList::insertAddress(const std::string& address) +{ + list_.push_front(address); + this->save(); +} + +RecentAddressesList::RecentAddresses RecentAddressesList::getList() const +{ + return list_; +} + +void RecentAddressesList::load() +{ + boost::property_tree::ptree iniConfig; + + try + { + boost::property_tree::ini_parser::read_ini(cConfigFileName, iniConfig); + + const auto listSize = std::min(maxListSize_, iniConfig.get(cRecentEntiresCount, 0)); + + for(size_t i = 0; i < listSize; ++i) + { + const auto key = cRecentEntryPrefix + std::to_string(i); + const auto address = iniConfig.get(key, RecentAddresses::value_type()); + + if(!address.empty()) + { + list_.push_back(address); + } + } + } + catch(const boost::property_tree::ini_parser_error& e) + { + OPENAUTO_LOG(warning) << "[RecentAddressesList] failed to read configuration file: " << cConfigFileName + << ", error: " << e.what() + << ". Empty list will be used."; + } +} + +void RecentAddressesList::save() +{ + boost::property_tree::ptree iniConfig; + + const auto entiresCount = std::min(maxListSize_, list_.size()); + iniConfig.put(cRecentEntiresCount, entiresCount); + + for(size_t i = 0; i < entiresCount; ++i) + { + const auto key = cRecentEntryPrefix + std::to_string(i); + iniConfig.put(key, list_.at(i)); + } + + boost::property_tree::ini_parser::write_ini(cConfigFileName, iniConfig); +} + +} +} +} +} diff --git a/src/autoapp/UI/ConnectDialog.cpp b/src/autoapp/UI/ConnectDialog.cpp index 69a2e02..1a510cd 100644 --- a/src/autoapp/UI/ConnectDialog.cpp +++ b/src/autoapp/UI/ConnectDialog.cpp @@ -11,10 +11,11 @@ namespace autoapp namespace ui { -ConnectDialog::ConnectDialog(boost::asio::io_service& ioService, aasdk::tcp::ITCPWrapper& tcpWrapper, QWidget *parent) +ConnectDialog::ConnectDialog(boost::asio::io_service& ioService, aasdk::tcp::ITCPWrapper& tcpWrapper, openauto::autoapp::configuration::IRecentAddressesList& recentAddressesList, QWidget *parent) : QDialog(parent) , ioService_(ioService) , tcpWrapper_(tcpWrapper) + , recentAddressesList_(recentAddressesList) , ui_(new Ui::ConnectDialog) { qRegisterMetaType("aasdk::tcp::ITCPEndpoint::SocketPointer"); @@ -24,6 +25,9 @@ ConnectDialog::ConnectDialog(boost::asio::io_service& ioService, aasdk::tcp::ITC connect(ui_->pushButtonConnect, &QPushButton::clicked, this, &ConnectDialog::onConnectButtonClicked); connect(this, &ConnectDialog::connectionSucceed, this, &ConnectDialog::onConnectionSucceed); connect(this, &ConnectDialog::connectionFailed, this, &ConnectDialog::onConnectionFailed); + + recentAddressesModel_.setStringList(recentAddressesModelList_); + ui_->listViewRecent->setModel(&recentAddressesModel_); } ConnectDialog::~ConnectDialog() @@ -40,7 +44,7 @@ void ConnectDialog::onConnectButtonClicked() try { - tcpWrapper_.asyncConnect(*socket, ipAddress, 5277, std::bind(&ConnectDialog::connectHandler, this, std::placeholders::_1, socket)); + tcpWrapper_.asyncConnect(*socket, ipAddress, 5277, std::bind(&ConnectDialog::connectHandler, this, std::placeholders::_1, ipAddress, socket)); } catch(const boost::system::system_error& se) { @@ -48,11 +52,11 @@ void ConnectDialog::onConnectButtonClicked() } } -void ConnectDialog::connectHandler(const boost::system::error_code& ec, aasdk::tcp::ITCPEndpoint::SocketPointer socket) +void ConnectDialog::connectHandler(const boost::system::error_code& ec, std::string ipAddress, aasdk::tcp::ITCPEndpoint::SocketPointer socket) { if(!ec) { - emit connectionSucceed(std::move(socket)); + emit connectionSucceed(std::move(socket), ipAddress); this->close(); } else @@ -61,8 +65,9 @@ void ConnectDialog::connectHandler(const boost::system::error_code& ec, aasdk::t } } -void ConnectDialog::onConnectionSucceed() +void ConnectDialog::onConnectionSucceed(aasdk::tcp::ITCPEndpoint::SocketPointer, std::string ipAddress) { + this->insertIpAddress(ipAddress); this->setControlsEnabledStatus(true); } @@ -83,6 +88,23 @@ void ConnectDialog::setControlsEnabledStatus(bool status) ui_->listViewRecent->setEnabled(status); } +void ConnectDialog::loadRecentList() +{ + recentAddressesModelList_.clear(); + const auto& configList = recentAddressesList_.getList(); + + for(const auto& element : configList) + { + recentAddressesModelList_.append(QString::fromStdString(element)); + } +} + +void ConnectDialog::insertIpAddress(std::string ipAddress) +{ + recentAddressesList_.insertAddress(ipAddress); + this->loadRecentList(); +} + } } }