From c25996a925885e3ab65c3b997f3e520670c2d06e Mon Sep 17 00:00:00 2001 From: lukas Date: Sat, 9 May 2020 23:08:23 +0200 Subject: [PATCH 01/10] first qt gui steps --- CMakeLists.txt | 29 ++++++++++++ src/gui/MainWindow.cpp | 38 +++++++++++++++ src/gui/MainWindow.h | 31 +++++++++++++ src/gui/mainwindow.ui | 103 +++++++++++++++++++++++++++++++++++++++++ src/maingui.cpp | 17 +++++++ 5 files changed, 218 insertions(+) create mode 100644 src/gui/MainWindow.cpp create mode 100644 src/gui/MainWindow.h create mode 100644 src/gui/mainwindow.ui create mode 100644 src/maingui.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 70dc0b8..ff32a1f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,6 +19,7 @@ SET(LIB_METHOD STATIC) #SHARED / STATIC option(BUILD_DOC "Build documentation" ON) # additional dependency for Doxygen option(PACKAGING "Allow Packaging to , or " ON) # additional dependencies for RPMbuild,dpkg or NSIS option(TESTS "Build Tests" ON) # additional dependencies for GTEST - to build tests +option(GUI "Build GUI elements" ON) # additional dependencies to QT libraries needed set(WinBuild false) # helper variables @@ -173,6 +174,34 @@ add_executable(iprefresher src/main.cpp) # LINK generated LIBS # target_link_libraries(iprefresher dynuiprefresher api ${CURL_LIBRARIES} ${LIBCONFIG++_LIBRARIES}) +if (${GUI}) + set(CMAKE_AUTOMOC ON) + set(CMAKE_INCLUDE_CURRENT_DIR ON) + + find_package(Qt5Widgets REQUIRED) + find_package(Qt5PrintSupport REQUIRED) + find_package(Qt5Sql REQUIRED) + set(QT5_LIBRARIES Qt5::Widgets Qt5::PrintSupport Qt5::Sql) + + set(UI_SOURCES + src/gui/mainwindow.ui + ) + + # + # Generate necessary headers from .ui files. (qmake lets `uic` do this job.) + # hint from [Cross-platform Qt5 project using cmake](http://stackoverflow.com/questions/21174586/cross-platform-qt5-project-using-cmake) + # + qt5_wrap_ui(UI_GENERATED_HEADERS ${UI_SOURCES}) + + add_executable(iprefresher-gui + src/maingui.cpp + src/gui/MainWindow.cpp + src/gui/MainWindow.h ${UI_GENERATED_HEADERS}) + + # LINK generated LIBS # + target_link_libraries(iprefresher-gui dynuiprefresher api ${CURL_LIBRARIES} ${LIBCONFIG++_LIBRARIES} ${QT5_LIBRARIES}) +endif () + # setting install targets IF (NOT ${WinBuild}) # INSTALL to Linux SYSTEM # diff --git a/src/gui/MainWindow.cpp b/src/gui/MainWindow.cpp new file mode 100644 index 0000000..6c1afca --- /dev/null +++ b/src/gui/MainWindow.cpp @@ -0,0 +1,38 @@ +// +// Created by lukas on 09.05.20. +// + +#include +#include "MainWindow.h" +#include "ui_mainwindow.h" + +MainWindow::MainWindow(QWidget *parent) : + QMainWindow(parent), ui(new Ui::MainWindow) { + + ui->setupUi(this); + ui->textLog-> + +// ui->labelCurrentIP->setText("currently is nothing to do"); +// ui->labelConfig->setText("blabliblub"); +// ui->textfieldname->setText("hangover"); + + connect(ui->buttonCheckConfig, SIGNAL(clicked()), this, SLOT(checkConfigBtn())); + connect(ui->buttonRefreshIP, SIGNAL(clicked()), this, SLOT(refreshIPBtn())); + + connect(this, SIGNAL(appendLogField(QString)), ui->textLog, SLOT(appendPlainText(QString))); +// connect(this, SIGNAL(setProgressBarValue(int)), ui->progressmanual, SLOT(setValue(int))); +} + +MainWindow::~MainWindow() { + delete ui; +} + +void MainWindow::checkConfigBtn() { + std::cout << "btn clicked!" << std::endl; + + appendLogField("btn clicked! \n"); +} + +void MainWindow::refreshIPBtn() { + +} \ No newline at end of file diff --git a/src/gui/MainWindow.h b/src/gui/MainWindow.h new file mode 100644 index 0000000..c954b49 --- /dev/null +++ b/src/gui/MainWindow.h @@ -0,0 +1,31 @@ +// +// Created by lukas on 09.05.20. +// + +#pragma once + + +#include + +namespace Ui { + class MainWindow; +} + +class MainWindow : public QMainWindow{ +Q_OBJECT + +public: + explicit MainWindow(QWidget *parent = 0); + ~MainWindow(); + +private: + Ui::MainWindow *ui; +private slots: +// void startdownloadBtn(); +void checkConfigBtn(); +void refreshIPBtn(); +signals: + void appendLogField(QString); +// void setInfoLabelText(QString); +// void setProgressBarValue(int); +}; \ No newline at end of file diff --git a/src/gui/mainwindow.ui b/src/gui/mainwindow.ui new file mode 100644 index 0000000..2857309 --- /dev/null +++ b/src/gui/mainwindow.ui @@ -0,0 +1,103 @@ + + + MainWindow + + + + 0 + 0 + 823 + 618 + + + + MainWindow + + + + + + 290 + 300 + 91 + 33 + + + + Refresh IP + + + + + + 40 + 60 + 161 + 17 + + + + Your current global IP: + + + + + true + + + + 40 + 410 + 691 + 191 + + + + IBeamCursor + + + + + + 40 + 380 + 64 + 17 + + + + Log: + + + + + + 270 + 140 + 91 + 33 + + + + Check Config + + + + + + 270 + 180 + 141 + 17 + + + + Config is: undefined + + + + + + + + diff --git a/src/maingui.cpp b/src/maingui.cpp new file mode 100644 index 0000000..3e10667 --- /dev/null +++ b/src/maingui.cpp @@ -0,0 +1,17 @@ +// +// Created by lukas on 09.05.20. +// + +#include +#include +#include "gui/MainWindow.h" + +int main(int argc, char *argv[]) { + std::cout << "gui here!" << std::endl; + + QApplication a(argc, argv); + MainWindow w; + w.show(); + + return QApplication::exec(); +} \ No newline at end of file From ab772aac555aed1f447e9806039d6b7b6d465f9f Mon Sep 17 00:00:00 2001 From: lukas Date: Sun, 10 May 2020 15:00:51 +0200 Subject: [PATCH 02/10] further gui developments --- CMakeLists.txt | 4 +-- src/gui/MainWindow.cpp | 71 ++++++++++++++++++++++++++++++++++-------- src/gui/MainWindow.h | 5 +-- src/gui/mainwindow.ui | 4 +-- 4 files changed, 65 insertions(+), 19 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ff32a1f..6fb4c05 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,7 +19,7 @@ SET(LIB_METHOD STATIC) #SHARED / STATIC option(BUILD_DOC "Build documentation" ON) # additional dependency for Doxygen option(PACKAGING "Allow Packaging to , or " ON) # additional dependencies for RPMbuild,dpkg or NSIS option(TESTS "Build Tests" ON) # additional dependencies for GTEST - to build tests -option(GUI "Build GUI elements" ON) # additional dependencies to QT libraries needed +option(GUI "Build GUI elements" OFF) # additional dependencies to QT libraries needed set(WinBuild false) # helper variables @@ -199,7 +199,7 @@ if (${GUI}) src/gui/MainWindow.h ${UI_GENERATED_HEADERS}) # LINK generated LIBS # - target_link_libraries(iprefresher-gui dynuiprefresher api ${CURL_LIBRARIES} ${LIBCONFIG++_LIBRARIES} ${QT5_LIBRARIES}) + target_link_libraries(iprefresher-gui -lpthread dynuiprefresher api ${CURL_LIBRARIES} ${LIBCONFIG++_LIBRARIES} ${QT5_LIBRARIES}) endif () # setting install targets diff --git a/src/gui/MainWindow.cpp b/src/gui/MainWindow.cpp index 6c1afca..7294823 100644 --- a/src/gui/MainWindow.cpp +++ b/src/gui/MainWindow.cpp @@ -1,20 +1,28 @@ -// -// Created by lukas on 09.05.20. -// - -#include +#include +#include #include "MainWindow.h" #include "ui_mainwindow.h" -MainWindow::MainWindow(QWidget *parent) : - QMainWindow(parent), ui(new Ui::MainWindow) { +#include "inc/Config.h" +#include "inc/Logger.h" +MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); - ui->textLog-> -// ui->labelCurrentIP->setText("currently is nothing to do"); -// ui->labelConfig->setText("blabliblub"); -// ui->textfieldname->setText("hangover"); + // needs to be defined out of scope -- would be termintated after this constructor. +// myThread = std::thread([this](){ +// IPAPI ipapi; +// std::string ip = ipapi.getGlobalIp(); +// Logger::message("Current global IP: " + ip); +// std::string msg = "Your current global IP: "+ip; +// ui->labelCurrentIP->setText(msg.c_str()); +// }); + + + if (Config::validateConfig()) + ui->labelConfig->setText("Config is: OK"); + else + ui->labelConfig->setText("Config is: NOT OK"); connect(ui->buttonCheckConfig, SIGNAL(clicked()), this, SLOT(checkConfigBtn())); connect(ui->buttonRefreshIP, SIGNAL(clicked()), this, SLOT(refreshIPBtn())); @@ -28,11 +36,48 @@ MainWindow::~MainWindow() { } void MainWindow::checkConfigBtn() { - std::cout << "btn clicked!" << std::endl; + Logger::message("checking config!"); + appendLogField("checking config!"); - appendLogField("btn clicked! \n"); + if (Config::validateConfig()) { + Logger::message("Config file is OK"); + appendLogField("Config file is OK"); + ui->labelConfig->setText("Config is: OK"); + } else { + Logger::error("There are errors in config file!"); + appendLogField("There are errors in config file!"); + } + appendLogField(""); } void MainWindow::refreshIPBtn() { + Logger::message("start refreshing Dynu IP."); + appendLogField(""); + appendLogField("start refreshing Dynu IP."); +new std::thread([this](){ + IPRefresher ipr; + if (Config::readConfig()) { + ipr.checkIPAdress(false); + } else { + std::cout << "incorrect credentials!" << std::endl; + } + + Logger::message("Finished refreshing Dynu IP."); + appendLogField("Finished refreshing Dynu IP."); + delete this; +}); +// myThread = std::thread([this](){ +// IPRefresher ipr; +// if (Config::readConfig()) { +// ipr.checkIPAdress(false); +// } else { +// std::cout << "incorrect credentials!" << std::endl; +// } +// +// Logger::message("Finished refreshing Dynu IP."); +// appendLogField("Finished refreshing Dynu IP."); +// ui->textLog->appendPlainText("Finished refreshing Dynu IP."); +// }); + } \ No newline at end of file diff --git a/src/gui/MainWindow.h b/src/gui/MainWindow.h index c954b49..dbdc2b8 100644 --- a/src/gui/MainWindow.h +++ b/src/gui/MainWindow.h @@ -4,7 +4,7 @@ #pragma once - +#include #include namespace Ui { @@ -15,11 +15,12 @@ class MainWindow : public QMainWindow{ Q_OBJECT public: - explicit MainWindow(QWidget *parent = 0); + explicit MainWindow(QWidget *parent = nullptr); ~MainWindow(); private: Ui::MainWindow *ui; + std::thread myThread; private slots: // void startdownloadBtn(); void checkConfigBtn(); diff --git a/src/gui/mainwindow.ui b/src/gui/mainwindow.ui index 2857309..bd9e356 100644 --- a/src/gui/mainwindow.ui +++ b/src/gui/mainwindow.ui @@ -32,7 +32,7 @@ 40 60 - 161 + 301 17 @@ -42,7 +42,7 @@ - true + false From 0eea7095e04969e2d73b88dc1b242ac4a418c7bc Mon Sep 17 00:00:00 2001 From: Lukas Heiligenbrunner Date: Sun, 10 May 2020 18:10:44 +0200 Subject: [PATCH 03/10] added better thread management cross compilation features. --- CMakeLists.txt | 23 ++++++++++------ src/gui/MainWindow.cpp | 60 ++++++++++++++++-------------------------- src/gui/MainWindow.h | 16 +++++------ src/maingui.cpp | 1 + 4 files changed, 47 insertions(+), 53 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6fb4c05..733e054 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,8 +19,8 @@ SET(LIB_METHOD STATIC) #SHARED / STATIC option(BUILD_DOC "Build documentation" ON) # additional dependency for Doxygen option(PACKAGING "Allow Packaging to , or " ON) # additional dependencies for RPMbuild,dpkg or NSIS option(TESTS "Build Tests" ON) # additional dependencies for GTEST - to build tests -option(GUI "Build GUI elements" OFF) # additional dependencies to QT libraries needed -set(WinBuild false) +option(GUI "Build GUI elements" ON) # additional dependencies to QT libraries needed +set(WinBuild true) # helper variables SET(CMAKE_CXX_STANDARD 17) @@ -99,6 +99,10 @@ if (${WinBuild}) message(STATUS "Using LIBCONFIG++ lib(s): ${LIBCONFIG++_LIBRARIES}") include_directories(${LIBCONFIG++_INCLUDE_DIRS} inc) + + if (${GUI}) + set(CMAKE_PREFIX_PATH "/usr/${TOOLCHAIN_PREFIX}/sys-root/mingw/lib/cmake") + endif () else () find_package(CURL REQUIRED) if (CURL_INCLUDE_DIRS AND CURL_LIBRARIES) @@ -130,6 +134,15 @@ else () include_directories(${LIBCONFIG_INCLUDE_DIRS}) endif () +if (${GUI}) + set(CMAKE_AUTOMOC ON) + set(CMAKE_INCLUDE_CURRENT_DIR ON) + + find_package(Qt5Widgets REQUIRED) + find_package(Qt5PrintSupport REQUIRED) + find_package(Qt5Sql REQUIRED) +endif () + message("") #read sample config @@ -175,12 +188,6 @@ add_executable(iprefresher src/main.cpp) target_link_libraries(iprefresher dynuiprefresher api ${CURL_LIBRARIES} ${LIBCONFIG++_LIBRARIES}) if (${GUI}) - set(CMAKE_AUTOMOC ON) - set(CMAKE_INCLUDE_CURRENT_DIR ON) - - find_package(Qt5Widgets REQUIRED) - find_package(Qt5PrintSupport REQUIRED) - find_package(Qt5Sql REQUIRED) set(QT5_LIBRARIES Qt5::Widgets Qt5::PrintSupport Qt5::Sql) set(UI_SOURCES diff --git a/src/gui/MainWindow.cpp b/src/gui/MainWindow.cpp index 7294823..2c758d9 100644 --- a/src/gui/MainWindow.cpp +++ b/src/gui/MainWindow.cpp @@ -1,22 +1,24 @@ -#include -#include #include "MainWindow.h" #include "ui_mainwindow.h" -#include "inc/Config.h" -#include "inc/Logger.h" +#include "api/IPAPI.h" +#include "IPRefresher.h" +#include "Config.h" +#include "Logger.h" + +#include MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); // needs to be defined out of scope -- would be termintated after this constructor. -// myThread = std::thread([this](){ -// IPAPI ipapi; -// std::string ip = ipapi.getGlobalIp(); -// Logger::message("Current global IP: " + ip); -// std::string msg = "Your current global IP: "+ip; -// ui->labelCurrentIP->setText(msg.c_str()); -// }); + new std::thread([this]() { + IPAPI ipapi; + std::string ip = ipapi.getGlobalIp(); + Logger::message("Current global IP: " + ip); + std::string msg = "Your current global IP: " + ip; + this->ui->labelCurrentIP->setText(msg.c_str()); + }); if (Config::validateConfig()) @@ -28,7 +30,6 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi connect(ui->buttonRefreshIP, SIGNAL(clicked()), this, SLOT(refreshIPBtn())); connect(this, SIGNAL(appendLogField(QString)), ui->textLog, SLOT(appendPlainText(QString))); -// connect(this, SIGNAL(setProgressBarValue(int)), ui->progressmanual, SLOT(setValue(int))); } MainWindow::~MainWindow() { @@ -54,30 +55,15 @@ void MainWindow::refreshIPBtn() { Logger::message("start refreshing Dynu IP."); appendLogField(""); appendLogField("start refreshing Dynu IP."); -new std::thread([this](){ - IPRefresher ipr; - if (Config::readConfig()) { - ipr.checkIPAdress(false); - } else { - std::cout << "incorrect credentials!" << std::endl; - } - - Logger::message("Finished refreshing Dynu IP."); - appendLogField("Finished refreshing Dynu IP."); - delete this; -}); -// myThread = std::thread([this](){ -// IPRefresher ipr; -// if (Config::readConfig()) { -// ipr.checkIPAdress(false); -// } else { -// std::cout << "incorrect credentials!" << std::endl; -// } -// -// Logger::message("Finished refreshing Dynu IP."); -// appendLogField("Finished refreshing Dynu IP."); -// ui->textLog->appendPlainText("Finished refreshing Dynu IP."); -// }); - + new std::thread([this]() { + IPRefresher ipr; + if (Config::readConfig()) { + ipr.checkIPAdress(false); + } else { + std::cout << "incorrect credentials!" << std::endl; + } + Logger::message("Finished refreshing Dynu IP."); + this->appendLogField("Finished refreshing Dynu IP."); + }); } \ No newline at end of file diff --git a/src/gui/MainWindow.h b/src/gui/MainWindow.h index dbdc2b8..288a2fc 100644 --- a/src/gui/MainWindow.h +++ b/src/gui/MainWindow.h @@ -4,29 +4,29 @@ #pragma once -#include #include namespace Ui { class MainWindow; } -class MainWindow : public QMainWindow{ +class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = nullptr); + ~MainWindow(); private: Ui::MainWindow *ui; - std::thread myThread; private slots: -// void startdownloadBtn(); -void checkConfigBtn(); -void refreshIPBtn(); + + void checkConfigBtn(); + + void refreshIPBtn(); + signals: + void appendLogField(QString); -// void setInfoLabelText(QString); -// void setProgressBarValue(int); }; \ No newline at end of file diff --git a/src/maingui.cpp b/src/maingui.cpp index 3e10667..ec9a7a0 100644 --- a/src/maingui.cpp +++ b/src/maingui.cpp @@ -8,6 +8,7 @@ int main(int argc, char *argv[]) { std::cout << "gui here!" << std::endl; + QCoreApplication::addLibraryPath("."); QApplication a(argc, argv); MainWindow w; From 3b32f60190ed9ecdc20de1e1e18840338343aa37 Mon Sep 17 00:00:00 2001 From: lukas Date: Thu, 14 May 2020 23:08:19 +0200 Subject: [PATCH 04/10] added return codes for IPrefresher refresh method. error messages in gui. --- CMakeLists.txt | 2 +- inc/IPRefresher.h | 11 +++++++++-- src/IPRefresher.cpp | 9 +++++++-- src/gui/MainWindow.cpp | 18 +++++++++++++++++- src/maingui.cpp | 4 ---- 5 files changed, 34 insertions(+), 10 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 733e054..dfe8361 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,7 +20,7 @@ option(BUILD_DOC "Build documentation" ON) # additional dependency for Doxygen option(PACKAGING "Allow Packaging to , or " ON) # additional dependencies for RPMbuild,dpkg or NSIS option(TESTS "Build Tests" ON) # additional dependencies for GTEST - to build tests option(GUI "Build GUI elements" ON) # additional dependencies to QT libraries needed -set(WinBuild true) +set(WinBuild false) # helper variables SET(CMAKE_CXX_STANDARD 17) diff --git a/inc/IPRefresher.h b/inc/IPRefresher.h index 6bc713d..70d8e0e 100644 --- a/inc/IPRefresher.h +++ b/inc/IPRefresher.h @@ -9,12 +9,19 @@ #pragma once +namespace IPRefresher_Status_Code { + const int SUCCESS = 1; + const int ERROR = -1; + const int ERROR_NO_INTERNET = -2; + const int NOREFRESH = 0; +} + class IPRefresher { public: /** * refresh ip address on Dynu server */ - void checkIPAdress(bool force); + bool checkIPAdress(bool force); /** * default constructor @@ -27,4 +34,4 @@ public: * @param loop true->loopmode on */ explicit IPRefresher(bool loop); -}; +}; \ No newline at end of file diff --git a/src/IPRefresher.cpp b/src/IPRefresher.cpp index 3dbcf0f..7238a02 100644 --- a/src/IPRefresher.cpp +++ b/src/IPRefresher.cpp @@ -11,23 +11,26 @@ #include #include -void IPRefresher::checkIPAdress(bool force) { +bool IPRefresher::checkIPAdress(bool force) { FileLogger logger; - + testspace::testi5(); IPAPI ipapi; std::string ip = ipapi.getGlobalIp(); if (ip.empty()) { //no internet connection (or other error) Logger::warning("no internet connection"); + return IPRefresher_Status_Code::ERROR_NO_INTERNET; } else if (!IpHelper::isIpValid(ip)) { // error when ip doesn't contain a : Logger::warning("an error occured when getting the global ip"); + return IPRefresher_Status_Code::ERROR; } else { std::string oldip = logger.readip(); if (oldip == ip && !force) { Logger::message("no change -- ip: " + ip); + return IPRefresher_Status_Code::NOREFRESH; } else { Logger::message("ip changed! -- from :" + oldip + "to: " + ip); @@ -43,9 +46,11 @@ void IPRefresher::checkIPAdress(bool force) { } else if (!result) { //error Logger::error("failed to write ip to dynu api!"); + return IPRefresher_Status_Code::ERROR; } logger.safeip(ip); + return result ? IPRefresher_Status_Code::SUCCESS : IPRefresher_Status_Code::ERROR; } } } diff --git a/src/gui/MainWindow.cpp b/src/gui/MainWindow.cpp index 2c758d9..3471287 100644 --- a/src/gui/MainWindow.cpp +++ b/src/gui/MainWindow.cpp @@ -58,7 +58,23 @@ void MainWindow::refreshIPBtn() { new std::thread([this]() { IPRefresher ipr; if (Config::readConfig()) { - ipr.checkIPAdress(false); + int code = ipr.checkIPAdress(false); + switch (code) { + case IPRefresher_Status_Code::SUCCESS: + appendLogField("successfully refreshed IP!"); + break; + case IPRefresher_Status_Code::NOREFRESH: + appendLogField("IP is already correct."); + break; + case IPRefresher_Status_Code::ERROR_NO_INTERNET: + appendLogField("Error: No Internet connection"); + break; + case IPRefresher_Status_Code::ERROR: + appendLogField("An error occured while refreshing."); + break; + default: + appendLogField("An unknown error code occured"); + } } else { std::cout << "incorrect credentials!" << std::endl; } diff --git a/src/maingui.cpp b/src/maingui.cpp index ec9a7a0..c144b60 100644 --- a/src/maingui.cpp +++ b/src/maingui.cpp @@ -3,13 +3,9 @@ // #include -#include #include "gui/MainWindow.h" int main(int argc, char *argv[]) { - std::cout << "gui here!" << std::endl; - QCoreApplication::addLibraryPath("."); - QApplication a(argc, argv); MainWindow w; w.show(); From b5b352f83dd1b25e0254715c0e676e8801d1f918 Mon Sep 17 00:00:00 2001 From: lukas Date: Fri, 15 May 2020 13:57:09 +0200 Subject: [PATCH 05/10] namespace for IPRefresher instead of class --- inc/IPRefresher.h | 28 ++++++++++++---------------- src/IPRefresher.cpp | 37 +++++++++++++++++++------------------ src/gui/MainWindow.cpp | 25 ++++++++++++------------- src/gui/MainWindow.h | 30 ++++++++++++++++++++++++------ src/main.cpp | 8 +++----- src/maingui.cpp | 8 ++++---- 6 files changed, 74 insertions(+), 62 deletions(-) diff --git a/inc/IPRefresher.h b/inc/IPRefresher.h index 70d8e0e..91819b1 100644 --- a/inc/IPRefresher.h +++ b/inc/IPRefresher.h @@ -9,29 +9,25 @@ #pragma once -namespace IPRefresher_Status_Code { - const int SUCCESS = 1; - const int ERROR = -1; - const int ERROR_NO_INTERNET = -2; - const int NOREFRESH = 0; -} +namespace IPRefresher { + /** + * Status return-codes for startUpService + */ + namespace Status_Code { + const int SUCCESS = 1; + const int ERROR = -1; + const int ERROR_NO_INTERNET = -2; + const int NOREFRESH = 0; + } -class IPRefresher { -public: /** * refresh ip address on Dynu server */ bool checkIPAdress(bool force); - /** - * default constructor - */ - IPRefresher() = default; - /** * start the service in loop mode * every 5 minutes the ip is checked an refreshed (needed for .service) - * @param loop true->loopmode on */ - explicit IPRefresher(bool loop); -}; \ No newline at end of file + void startUpService(int interval = 300); +} \ No newline at end of file diff --git a/src/IPRefresher.cpp b/src/IPRefresher.cpp index 7238a02..17e7ba5 100644 --- a/src/IPRefresher.cpp +++ b/src/IPRefresher.cpp @@ -11,26 +11,28 @@ #include #include +using namespace IPRefresher; + bool IPRefresher::checkIPAdress(bool force) { FileLogger logger; - testspace::testi5(); + IPAPI ipapi; std::string ip = ipapi.getGlobalIp(); if (ip.empty()) { //no internet connection (or other error) Logger::warning("no internet connection"); - return IPRefresher_Status_Code::ERROR_NO_INTERNET; + return Status_Code::ERROR_NO_INTERNET; } else if (!IpHelper::isIpValid(ip)) { // error when ip doesn't contain a : Logger::warning("an error occured when getting the global ip"); - return IPRefresher_Status_Code::ERROR; + return Status_Code::ERROR; } else { std::string oldip = logger.readip(); if (oldip == ip && !force) { Logger::message("no change -- ip: " + ip); - return IPRefresher_Status_Code::NOREFRESH; + return Status_Code::NOREFRESH; } else { Logger::message("ip changed! -- from :" + oldip + "to: " + ip); @@ -46,27 +48,26 @@ bool IPRefresher::checkIPAdress(bool force) { } else if (!result) { //error Logger::error("failed to write ip to dynu api!"); - return IPRefresher_Status_Code::ERROR; + return Status_Code::ERROR; } logger.safeip(ip); - return result ? IPRefresher_Status_Code::SUCCESS : IPRefresher_Status_Code::ERROR; + return result ? Status_Code::SUCCESS : Status_Code::ERROR; } } } -IPRefresher::IPRefresher(bool loop) { - if (loop) { - Logger::message("startup of service"); - Logger::message("Version: " + Version::VERSION); - if (Config::readConfig()) { - while (true) { - Logger::message("starting check"); - checkIPAdress(false); - std::this_thread::sleep_for(std::chrono::milliseconds(300000)); - } - } else { - std::cout << "incorrect credentials!" << std::endl; +void IPRefresher::startUpService(int interval) { + Logger::message("startup of service"); + Logger::message("Version: " + Version::VERSION); + if (Config::readConfig()) { + while (true) { + Logger::message("starting check"); + checkIPAdress(false); + std::this_thread::sleep_for(std::chrono::milliseconds(interval * 1000)); } + } else { + std::cout << "incorrect credentials!" << std::endl; } + } diff --git a/src/gui/MainWindow.cpp b/src/gui/MainWindow.cpp index 3471287..3bc8758 100644 --- a/src/gui/MainWindow.cpp +++ b/src/gui/MainWindow.cpp @@ -8,10 +8,10 @@ #include -MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { +MainWindow::MainWindow() : QMainWindow(), ui(new Ui::MainWindow) { ui->setupUi(this); - // needs to be defined out of scope -- would be termintated after this constructor. + // needs to be defined with new -- would be termintated after this constructor. new std::thread([this]() { IPAPI ipapi; std::string ip = ipapi.getGlobalIp(); @@ -20,11 +20,8 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi this->ui->labelCurrentIP->setText(msg.c_str()); }); - - if (Config::validateConfig()) - ui->labelConfig->setText("Config is: OK"); - else - ui->labelConfig->setText("Config is: NOT OK"); + // set config info label and initial check if config is valid + ui->labelConfig->setText(Config::validateConfig() ? "Config is: OK" : "Config is: NOT OK"); connect(ui->buttonCheckConfig, SIGNAL(clicked()), this, SLOT(checkConfigBtn())); connect(ui->buttonRefreshIP, SIGNAL(clicked()), this, SLOT(refreshIPBtn())); @@ -33,6 +30,9 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWi } MainWindow::~MainWindow() { + // todo check if disconnects are really necessary + disconnect(ui->buttonCheckConfig); + disconnect(ui->buttonRefreshIP); delete ui; } @@ -56,20 +56,19 @@ void MainWindow::refreshIPBtn() { appendLogField(""); appendLogField("start refreshing Dynu IP."); new std::thread([this]() { - IPRefresher ipr; if (Config::readConfig()) { - int code = ipr.checkIPAdress(false); + int code = IPRefresher::checkIPAdress(false); switch (code) { - case IPRefresher_Status_Code::SUCCESS: + case IPRefresher::Status_Code::SUCCESS: appendLogField("successfully refreshed IP!"); break; - case IPRefresher_Status_Code::NOREFRESH: + case IPRefresher::Status_Code::NOREFRESH: appendLogField("IP is already correct."); break; - case IPRefresher_Status_Code::ERROR_NO_INTERNET: + case IPRefresher::Status_Code::ERROR_NO_INTERNET: appendLogField("Error: No Internet connection"); break; - case IPRefresher_Status_Code::ERROR: + case IPRefresher::Status_Code::ERROR: appendLogField("An error occured while refreshing."); break; default: diff --git a/src/gui/MainWindow.h b/src/gui/MainWindow.h index 288a2fc..cb0ae06 100644 --- a/src/gui/MainWindow.h +++ b/src/gui/MainWindow.h @@ -1,6 +1,9 @@ -// -// Created by lukas on 09.05.20. -// +/** + * Main GUI controller - User IO handlings + * + * @author Lukas Heiligenbrunner + * @date 09.05.2020 + */ #pragma once @@ -14,19 +17,34 @@ class MainWindow : public QMainWindow { Q_OBJECT public: - explicit MainWindow(QWidget *parent = nullptr); + /** + * constructor with basic initializations + */ + explicit MainWindow(); + /** + * destruct all gui elements + */ ~MainWindow(); private: Ui::MainWindow *ui; private slots: - + /** + * executed click handler for config button + */ void checkConfigBtn(); + /** + * executed click handler for refresh btn + */ void refreshIPBtn(); signals: - + /** + * append a String line to the Log field + * + * @param QString string to be appended + */ void appendLogField(QString); }; \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 6518f92..e16b7d1 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -21,15 +21,14 @@ int main(int argc, char *argv[]) { } else if (firstarg == "-v" || firstarg == "--version") { std::cout << "Version " << Version::VERSION << std::endl; } else if (firstarg == "-f" || firstarg == "--force") { - IPRefresher ipr; if (Config::readConfig()) { - ipr.checkIPAdress(true); + IPRefresher::checkIPAdress(true); } else { std::cout << "incorrect credentials!" << std::endl; } } else if (firstarg == "-l" || firstarg == "--loop") { - IPRefresher(true); + IPRefresher::startUpService(true); } else if (firstarg == "-c" || firstarg == "--checkconfig") { if (Config::validateConfig()) { Logger::message("Config file is OK"); @@ -44,10 +43,9 @@ int main(int argc, char *argv[]) { Logger::message("wrong arguments! -h for help"); } } else { - IPRefresher ipr; Logger::message("starting check"); if (Config::readConfig()) { - ipr.checkIPAdress(false); + IPRefresher::checkIPAdress(false); } else { std::cout << "incorrect credentials!" << std::endl; } diff --git a/src/maingui.cpp b/src/maingui.cpp index c144b60..a57ba7e 100644 --- a/src/maingui.cpp +++ b/src/maingui.cpp @@ -1,13 +1,13 @@ -// -// Created by lukas on 09.05.20. -// - #include #include "gui/MainWindow.h" +/** + * application entry point + */ int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; + w.setWindowTitle("startUpService"); w.show(); return QApplication::exec(); From 3be820311197525c02fc35d93d53da22dec01bc8 Mon Sep 17 00:00:00 2001 From: lukas Date: Sat, 16 May 2020 20:30:23 +0200 Subject: [PATCH 06/10] begin of gui implementations in cmake install script --- CMakeLists.txt | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index dfe8361..d5b2cca 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -217,6 +217,11 @@ IF (NOT ${WinBuild}) install(TARGETS iprefresher DESTINATION usr/bin) # install systemd service and enable it install(FILES service/iprefresher.service DESTINATION lib/systemd/system) + + if (${GUI}) + # install binaries + install(TARGETS iprefresher-gui DESTINATION usr/bin) + endif () ELSE () # INSTALL to Windows SYSTEM # @@ -237,6 +242,17 @@ ELSE () /usr/${TOOLCHAIN_PREFIX}/sys-root/mingw/bin/libidn2-0.dll /usr/${TOOLCHAIN_PREFIX}/sys-root/mingw/bin/libconfig++-11.dll DESTINATION .) + + if (${GUI}) + # install binaries + install(TARGETS iprefresher-gui DESTINATION .) + + # install .dll dependencies + # todo check if files exist... + # TODO install right dll dependencies here + #install(FILES /usr/${TOOLCHAIN_PREFIX}/sys-root/mingw/bin/libcurl-4.dll + # DESTINATION .) + endif () ENDIF () if (${PACKAGING}) @@ -282,6 +298,7 @@ fi\n" SET(CPACK_RPM_POST_INSTALL_SCRIPT_FILE "${CMAKE_CURRENT_SOURCE_DIR}/postinst") SET(CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION "/lib/systemd/system" "/lib/systemd" "/lib" "/usr/local/bin" "/usr/local") # --> needed to not override existing folders set(CPACK_RPM_PACKAGE_REQUIRES "libcurl,libconfig") + # todo set additional gui dependencies here else (NOT ${RPMBUILD_EXECUTABLE} STREQUAL "RPMBUILD_EXECUTABLE-NOTFOUND") message(STATUS "not found rpm build tools --> not building rpm") endif (NOT ${RPMBUILD_EXECUTABLE} STREQUAL "RPMBUILD_EXECUTABLE-NOTFOUND") @@ -292,6 +309,7 @@ fi\n" SET(CPACK_GENERATOR "${CPACK_GENERATOR};DEB") # add deb generator set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA "${CMAKE_CURRENT_SOURCE_DIR}/postinst") # set post inst file set(CPACK_DEBIAN_PACKAGE_DEPENDS "libcurl4,libconfig++9v5") # add debian dependencies + # todo set additional gui dependencies here else (NOT ${DEB_EXECUTABLE} STREQUAL "DEB_EXECUTABLE-NOTFOUND") message(STATUS "not found deb build tools --> not building deb") endif (NOT ${DEB_EXECUTABLE} STREQUAL "DEB_EXECUTABLE-NOTFOUND") From 268aa3a1ad32af89341316b6f9739ab994361f12 Mon Sep 17 00:00:00 2001 From: lukas Date: Mon, 18 May 2020 17:18:41 +0200 Subject: [PATCH 07/10] hide console window - windows gui right windows gui dll dependencies linux package qt dependencies for packaging --- CMakeLists.txt | 69 ++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 53 insertions(+), 16 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d5b2cca..c3ed6a9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -205,6 +205,11 @@ if (${GUI}) src/gui/MainWindow.cpp src/gui/MainWindow.h ${UI_GENERATED_HEADERS}) + if (${WinBuild}) + # hide console window when starting ui on windows + set_target_properties(iprefresher-gui PROPERTIES LINK_FLAGS "-mwindows") + endif () + # LINK generated LIBS # target_link_libraries(iprefresher-gui -lpthread dynuiprefresher api ${CURL_LIBRARIES} ${LIBCONFIG++_LIBRARIES} ${QT5_LIBRARIES}) endif () @@ -231,27 +236,44 @@ ELSE () # install .dll dependencies # todo check if files exist... + SET(LIBBINARYPATH "/usr/${TOOLCHAIN_PREFIX}/sys-root/mingw/bin") install(FILES /usr/${TOOLCHAIN_PREFIX}/sys-root/mingw/bin/libcurl-4.dll - /usr/${TOOLCHAIN_PREFIX}/sys-root/mingw/bin/libssh2-1.dll - /usr/${TOOLCHAIN_PREFIX}/sys-root/mingw/bin/libstdc++-6.dll - /usr/${TOOLCHAIN_PREFIX}/sys-root/mingw/bin/libgcc_s_seh-1.dll - /usr/${TOOLCHAIN_PREFIX}/sys-root/mingw/bin/libcrypto-1_1-x64.dll - /usr/${TOOLCHAIN_PREFIX}/sys-root/mingw/bin/libssl-1_1-x64.dll - /usr/${TOOLCHAIN_PREFIX}/sys-root/mingw/bin/libwinpthread-1.dll - /usr/${TOOLCHAIN_PREFIX}/sys-root/mingw/bin/zlib1.dll - /usr/${TOOLCHAIN_PREFIX}/sys-root/mingw/bin/libidn2-0.dll - /usr/${TOOLCHAIN_PREFIX}/sys-root/mingw/bin/libconfig++-11.dll + ${LIBBINARYPATH}/libssh2-1.dll + ${LIBBINARYPATH}/libstdc++-6.dll + ${LIBBINARYPATH}/libgcc_s_seh-1.dll + ${LIBBINARYPATH}/libcrypto-1_1-x64.dll + ${LIBBINARYPATH}/libssl-1_1-x64.dll + ${LIBBINARYPATH}/libwinpthread-1.dll + ${LIBBINARYPATH}/zlib1.dll + ${LIBBINARYPATH}/libidn2-0.dll + ${LIBBINARYPATH}/libconfig++-11.dll DESTINATION .) if (${GUI}) # install binaries + set_target_properties(iprefresher-gui PROPERTIES SUFFIX ".exe") install(TARGETS iprefresher-gui DESTINATION .) # install .dll dependencies - # todo check if files exist... - # TODO install right dll dependencies here - #install(FILES /usr/${TOOLCHAIN_PREFIX}/sys-root/mingw/bin/libcurl-4.dll - # DESTINATION .) + install(FILES + ${LIBBINARYPATH}/Qt5Widgets.dll + ${LIBBINARYPATH}/Qt5Core.dll + ${LIBBINARYPATH}/Qt5Gui.dll + ${LIBBINARYPATH}/iconv.dll + ${LIBBINARYPATH}/libpcre2-16-0.dll + ${LIBBINARYPATH}/libpng16-16.dll + ${LIBBINARYPATH}/libharfbuzz-0.dll + ${LIBBINARYPATH}/libglib-2.0-0.dll + ${LIBBINARYPATH}/libintl-8.dll + ${LIBBINARYPATH}/libpcre-1.dll + ${LIBBINARYPATH}/libbz2-1.dll + ${LIBBINARYPATH}/libfreetype-6.dll + DESTINATION .) + + install(FILES + /usr/${TOOLCHAIN_PREFIX}/sys-root/mingw/lib/qt5/plugins/platforms/qwindows.dll + DESTINATION ./platforms + ) endif () ENDIF () @@ -296,9 +318,19 @@ fi\n" message(STATUS "found rpm build executeable --> able to build rpm") SET(CPACK_GENERATOR "${CPACK_GENERATOR};RPM") SET(CPACK_RPM_POST_INSTALL_SCRIPT_FILE "${CMAKE_CURRENT_SOURCE_DIR}/postinst") - SET(CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION "/lib/systemd/system" "/lib/systemd" "/lib" "/usr/local/bin" "/usr/local") # --> needed to not override existing folders + SET(CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION + "/lib/systemd/system" + "/lib/systemd" + "/lib" + "/usr/local/bin" + "/usr/local") # --> not override existing folders + + # dependency management tested with fedora! set(CPACK_RPM_PACKAGE_REQUIRES "libcurl,libconfig") - # todo set additional gui dependencies here + if (${GUI}) + # append rpm GUI dependencies (qt5) + set(CPACK_RPM_PACKAGE_REQUIRES "${CPACK_RPM_PACKAGE_REQUIRES},qt5-qtbase") + endif () else (NOT ${RPMBUILD_EXECUTABLE} STREQUAL "RPMBUILD_EXECUTABLE-NOTFOUND") message(STATUS "not found rpm build tools --> not building rpm") endif (NOT ${RPMBUILD_EXECUTABLE} STREQUAL "RPMBUILD_EXECUTABLE-NOTFOUND") @@ -308,8 +340,13 @@ fi\n" message(STATUS "found deb build tools --> able to build deb") SET(CPACK_GENERATOR "${CPACK_GENERATOR};DEB") # add deb generator set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA "${CMAKE_CURRENT_SOURCE_DIR}/postinst") # set post inst file + + # dependency management tested with fedora! set(CPACK_DEBIAN_PACKAGE_DEPENDS "libcurl4,libconfig++9v5") # add debian dependencies - # todo set additional gui dependencies here + if (${GUI}) + # append debian GUI dependencies (qt5) + set(CPACK_DEBIAN_PACKAGE_DEPENDS "${CPACK_DEBIAN_PACKAGE_DEPENDS},qt5-default") + endif () else (NOT ${DEB_EXECUTABLE} STREQUAL "DEB_EXECUTABLE-NOTFOUND") message(STATUS "not found deb build tools --> not building deb") endif (NOT ${DEB_EXECUTABLE} STREQUAL "DEB_EXECUTABLE-NOTFOUND") From 4344e7c1184dec5c3fc733f00d04b64584d9eecd Mon Sep 17 00:00:00 2001 From: lukas Date: Tue, 19 May 2020 16:23:00 +0200 Subject: [PATCH 08/10] added tabbed view new config page with ability to edit config file new features in config class - setting member variables new button locations in gui --- CMakeLists.txt | 3 +- inc/Config.h | 29 +++- {src => inc}/gui/MainWindow.h | 13 ++ src/Config.cpp | 17 +- src/gui/MainWindow.cpp | 69 ++++++-- src/gui/mainwindow.ui | 311 +++++++++++++++++++++++++++++----- src/maingui.cpp | 2 +- 7 files changed, 381 insertions(+), 63 deletions(-) rename {src => inc}/gui/MainWindow.h (80%) diff --git a/CMakeLists.txt b/CMakeLists.txt index c3ed6a9..dcf4afc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -203,7 +203,8 @@ if (${GUI}) add_executable(iprefresher-gui src/maingui.cpp src/gui/MainWindow.cpp - src/gui/MainWindow.h ${UI_GENERATED_HEADERS}) + inc/gui/MainWindow.h + ${UI_GENERATED_HEADERS}) if (${WinBuild}) # hide console window when starting ui on windows diff --git a/inc/Config.h b/inc/Config.h index 1529671..db806e7 100644 --- a/inc/Config.h +++ b/inc/Config.h @@ -18,6 +18,13 @@ public: */ static bool readConfig(); + /** + * save back configuration to file + * + * @return success of config write + */ + static bool saveConfig(); + /** * validate config file * @@ -63,12 +70,32 @@ public: */ static const std::string &getChatId(); + /** + * set all parameters without telegram support + * + * @param domainname Dynu Domain name + * @param dynuapikey Dynu api key + * @param domainid Dynu domain id + */ + static void setValues(const std::string &domainname, const std::string &dynuapikey, const std::string &domainid); + + /** + * set all parameters with telegram support + * + * @param domainname Dynu Domain name + * @param dynuapikey Dynu api key + * @param domainid Dynu domain id + * @param telegramApiKey Telegram api key + * @param chatId Telegram chat id + */ + static void setValues(const std::string &domainname, const std::string &dynuapikey, const std::string &domainid, + const std::string &telegramApiKey, const std::string &chatId); private: /** * private constructor --> don't allow instance of this class */ - Config(); + Config() = default; /** * helper variable for managing telegram Support diff --git a/src/gui/MainWindow.h b/inc/gui/MainWindow.h similarity index 80% rename from src/gui/MainWindow.h rename to inc/gui/MainWindow.h index cb0ae06..88879e7 100644 --- a/src/gui/MainWindow.h +++ b/inc/gui/MainWindow.h @@ -29,7 +29,14 @@ public: private: Ui::MainWindow *ui; + + /** + * all static initializations of custom gui elements + */ + void initGui(); + private slots: + /** * executed click handler for config button */ @@ -40,7 +47,13 @@ private slots: */ void refreshIPBtn(); + /** + * executed click handler for save config btn + */ + void saveConfigBtn(); + signals: + /** * append a String line to the Log field * diff --git a/src/Config.cpp b/src/Config.cpp index 32aba2a..882f5fe 100644 --- a/src/Config.cpp +++ b/src/Config.cpp @@ -64,6 +64,11 @@ bool Config::readConfig() { return !(Config::dynuapikey.empty() || Config::domainid.empty() || Config::domainname.empty()); } +bool Config::saveConfig() { + // todo save config + return false; +} + bool Config::validateConfig() { libconfig::Config cfg; try { @@ -137,4 +142,14 @@ const std::string &Config::getChatId() { return chatId; } -Config::Config() = default; +void Config::setValues(const std::string &domainname, const std::string &dynuapikey, const std::string &domainid) { + Config::domainname = domainname; + Config::dynuapikey = dynuapikey; + Config::domainid = domainid; +} + +void Config::setValues(const std::string &domainname, const std::string &dynuapikey, const std::string &domainid, const std::string &telegramApiKey, const std::string &chatId) { + setValues(domainname, dynuapikey, domainid); + Config::telegramApiKey = telegramApiKey; + Config::chatId = chatId; +} diff --git a/src/gui/MainWindow.cpp b/src/gui/MainWindow.cpp index 3bc8758..0a4c720 100644 --- a/src/gui/MainWindow.cpp +++ b/src/gui/MainWindow.cpp @@ -1,4 +1,4 @@ -#include "MainWindow.h" +#include "inc/gui/MainWindow.h" #include "ui_mainwindow.h" #include "api/IPAPI.h" @@ -11,20 +11,12 @@ MainWindow::MainWindow() : QMainWindow(), ui(new Ui::MainWindow) { ui->setupUi(this); - // needs to be defined with new -- would be termintated after this constructor. - new std::thread([this]() { - IPAPI ipapi; - std::string ip = ipapi.getGlobalIp(); - Logger::message("Current global IP: " + ip); - std::string msg = "Your current global IP: " + ip; - this->ui->labelCurrentIP->setText(msg.c_str()); - }); - - // set config info label and initial check if config is valid - ui->labelConfig->setText(Config::validateConfig() ? "Config is: OK" : "Config is: NOT OK"); + // initialize gui with start parameters + initGui(); connect(ui->buttonCheckConfig, SIGNAL(clicked()), this, SLOT(checkConfigBtn())); connect(ui->buttonRefreshIP, SIGNAL(clicked()), this, SLOT(refreshIPBtn())); + connect(ui->buttonSaveConfig, SIGNAL(clicked()), this, SLOT(saveConfigBtn())); connect(this, SIGNAL(appendLogField(QString)), ui->textLog, SLOT(appendPlainText(QString))); } @@ -33,6 +25,7 @@ MainWindow::~MainWindow() { // todo check if disconnects are really necessary disconnect(ui->buttonCheckConfig); disconnect(ui->buttonRefreshIP); + this->destroy(); delete ui; } @@ -81,4 +74,56 @@ void MainWindow::refreshIPBtn() { Logger::message("Finished refreshing Dynu IP."); this->appendLogField("Finished refreshing Dynu IP."); }); +} + +void MainWindow::saveConfigBtn() { + if (ui->telegramsupportCheckbox->isChecked()) { + Config::setValues( + ui->domainnameedit->text().toStdString(), + ui->dynuapikeyedit->text().toStdString(), + ui->domainidedit->text().toStdString(), + ui->telegramapikeyedit->text().toStdString(), + ui->chatidedit->text().toStdString()); + } else { + Config::setValues( + ui->domainnameedit->text().toStdString(), + ui->dynuapikeyedit->text().toStdString(), + ui->domainidedit->text().toStdString()); + } + Config::saveConfig(); +} + +void MainWindow::initGui() { + // needs to be defined with new -- would be termintated after the constructor call. + new std::thread([this]() { + IPAPI ipapi; + std::string ip = ipapi.getGlobalIp(); + Logger::message("Current global IP: " + ip); + std::string msg = "Your current global IP: " + ip; + this->ui->labelCurrentIP->setText(msg.c_str()); + }); + + // set config info label and initial check if config is valid + ui->labelConfig->setText(Config::validateConfig() ? "Config is: OK" : "Config is: NOT OK"); + + if (Config::readConfig()) { + ui->dynuapikeyedit->setText(Config::getDynuapikey().c_str()); + ui->domainidedit->setText(Config::getDomainid().c_str()); + ui->domainnameedit->setText(Config::getDomainname().c_str()); + + if (Config::isTelegramSupported()) { + ui->telegramsupportCheckbox->setCheckState(Qt::Checked); + ui->telegramapikeyedit->setText(Config::getTelegramApiKey().c_str()); + ui->chatidedit->setText(Config::getChatId().c_str()); + } else { + ui->telegramsupportCheckbox->setCheckState(Qt::Unchecked); + ui->telegramapikeyedit->setDisabled(true); + ui->chatidedit->setDisabled(true); + } + } else { + // todo duplicate code with above + ui->telegramsupportCheckbox->setCheckState(Qt::Unchecked); + ui->telegramapikeyedit->setDisabled(true); + ui->chatidedit->setDisabled(true); + } } \ No newline at end of file diff --git a/src/gui/mainwindow.ui b/src/gui/mainwindow.ui index bd9e356..d0fb62d 100644 --- a/src/gui/mainwindow.ui +++ b/src/gui/mainwindow.ui @@ -10,36 +10,16 @@ 618 + + ArrowCursor + MainWindow + + /*background-color: rgb(69, 196, 255); + - - - - 290 - 300 - 91 - 33 - - - - Refresh IP - - - - - - 40 - 60 - 301 - 17 - - - - Your current global IP: - - false @@ -48,7 +28,7 @@ 40 410 - 691 + 741 191 @@ -69,31 +49,268 @@ Log: - + - 270 - 140 - 91 - 33 + 40 + 20 + 741 + 351 - - Check Config - - - - - - 270 - 180 - 141 - 17 - - - - Config is: undefined + + 0 + + + Basic + + + + + 20 + 30 + 301 + 17 + + + + Your current global IP: + + + + + + 20 + 70 + 141 + 17 + + + + Config is: undefined + + + + + + 20 + 120 + 231 + 151 + + + + Actions + + + + + 30 + 50 + 91 + 33 + + + + ArrowCursor + + + Check Config + + + + + + 30 + 100 + 91 + 33 + + + + Refresh IP + + + + + + + Config + + + + + 30 + 120 + 181 + 21 + + + + Telegram Notifications + + + + + + 630 + 270 + 91 + 33 + + + + Save Config + + + + + + 30 + 20 + 101 + 17 + + + + Dynu API Key + + + + + + 460 + 20 + 111 + 17 + + + + Domain ID + + + + + + 30 + 170 + 131 + 17 + + + + Telegram API Key + + + + + + 30 + 240 + 64 + 17 + + + + Chat ID + + + + + + 30 + 40 + 211 + 31 + + + + + + + 460 + 40 + 113 + 31 + + + + + + + 30 + 260 + 113 + 31 + + + + + + + 30 + 190 + 311 + 31 + + + + + + + 280 + 40 + 161 + 31 + + + + domain.dynu.net + + + + + + 280 + 20 + 111 + 17 + + + + Domainname + + + + + + Settings + + + + + 20 + 30 + 161 + 17 + + + + Select your language: + + + + + + 20 + 60 + 94 + 31 + + + + diff --git a/src/maingui.cpp b/src/maingui.cpp index a57ba7e..21df7b6 100644 --- a/src/maingui.cpp +++ b/src/maingui.cpp @@ -7,7 +7,7 @@ int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; - w.setWindowTitle("startUpService"); + w.setWindowTitle("Dynu IP Refresher"); w.show(); return QApplication::exec(); From 85ba334c214ffabe8b1adbc293af51b757b9967a Mon Sep 17 00:00:00 2001 From: lukas Date: Tue, 26 May 2020 19:59:23 +0200 Subject: [PATCH 09/10] added options in nsis install what to install. --- CMakeLists.txt | 73 ++++++++++++++++++++++++++++++++++++++++---------- src/Config.cpp | 2 +- 2 files changed, 60 insertions(+), 15 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a8b6bb1..27a3ac6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,7 +20,7 @@ option(BUILD_DOC "Build documentation" ON) # additional dependency for Doxygen option(PACKAGING "Allow Packaging to , or " ON) # additional dependencies for RPMbuild,dpkg or NSIS option(TESTS "Build Tests" ON) # additional dependencies for GTEST - to build tests option(GUI "Build GUI elements" ON) # additional dependencies to QT libraries needed -option(WinBuild "cross compile for Windows Platform" OFF) +option(WinBuild "cross compile for Windows Platform" ON) # helper variables SET(CMAKE_CXX_STANDARD 17) @@ -220,7 +220,7 @@ if (${GUI}) # qt5_wrap_ui(UI_GENERATED_HEADERS ${UI_SOURCES}) - add_executable(iprefresher-gui + add_executable(${Application_Name}-gui src/maingui.cpp src/gui/MainWindow.cpp inc/gui/MainWindow.h @@ -228,11 +228,11 @@ if (${GUI}) if (${WinBuild}) # hide console window when starting ui on windows - set_target_properties(iprefresher-gui PROPERTIES LINK_FLAGS "-mwindows") + set_target_properties(${Application_Name}-gui PROPERTIES LINK_FLAGS "-mwindows") endif () # LINK generated LIBS # - target_link_libraries(iprefresher-gui -lpthread dynuiprefresher api ${CURL_LIBRARIES} ${LIBCONFIG++_LIBRARIES} ${QT5_LIBRARIES}) + target_link_libraries(${Application_Name}-gui -lpthread libdynuiprefresher api ${CURL_LIBRARIES} ${LIBCONFIG++_LIBRARIES} ${QT5_LIBRARIES}) endif () # setting install targets @@ -240,20 +240,32 @@ IF (NOT ${WinBuild}) # INSTALL to Linux SYSTEM # # install binaries - install(TARGETS ${Application_Name} DESTINATION usr/bin) + install( + TARGETS ${Application_Name} + DESTINATION usr/bin + COMPONENT ${Application_Name}) # install systemd service and enable it - install(FILES service/${Application_Name}.service DESTINATION lib/systemd/system) + install( + FILES service/${Application_Name}.service + DESTINATION lib/systemd/system + COMPONENT ${Application_Name}) if (${GUI}) # install binaries - install(TARGETS iprefresher-gui DESTINATION usr/bin) + install( + TARGETS ${Application_Name}-gui + DESTINATION usr/bin + COMPONENT ${Application_Name}gui) endif () ELSE () # INSTALL to Windows SYSTEM # # install binary to current folder set_target_properties(${Application_Name} PROPERTIES SUFFIX ".exe") - install(TARGETS ${Application_Name} DESTINATION .) + install( + TARGETS ${Application_Name} + DESTINATION . + COMPONENT ${Application_Name}) # install .dll dependencies # todo check if files exist... @@ -268,12 +280,16 @@ ELSE () ${LIBBINARYPATH}/zlib1.dll ${LIBBINARYPATH}/libidn2-0.dll ${LIBBINARYPATH}/libconfig++-11.dll - DESTINATION .) + DESTINATION . + COMPONENT ${Application_Name}) if (${GUI}) # install binaries - set_target_properties(iprefresher-gui PROPERTIES SUFFIX ".exe") - install(TARGETS iprefresher-gui DESTINATION .) + set_target_properties(${Application_Name}-gui PROPERTIES SUFFIX ".exe") + install( + TARGETS ${Application_Name}-gui + DESTINATION . + COMPONENT ${Application_Name}gui) # install .dll dependencies install(FILES @@ -289,12 +305,13 @@ ELSE () ${LIBBINARYPATH}/libpcre-1.dll ${LIBBINARYPATH}/libbz2-1.dll ${LIBBINARYPATH}/libfreetype-6.dll - DESTINATION .) + DESTINATION . + COMPONENT ${Application_Name}gui) install(FILES /usr/${TOOLCHAIN_PREFIX}/sys-root/mingw/lib/qt5/plugins/platforms/qwindows.dll DESTINATION ./platforms - ) + COMPONENT ${Application_Name}gui) endif () ENDIF () @@ -384,9 +401,37 @@ systemctl start ${Application_Name}.service") set(CPACK_GENERATOR NSIS) message(STATUS "Using NSIS Package build.") - set(CPACK_NSIS_testcomp_INSTALL_DIRECTORY /) + set(CPACK_NSIS_EXECUTABLES_DIRECTORY "DynuIpRefresher") set(CPACK_PACKAGE_INSTALL_DIRECTORY "DynuIpRefresher") SET(CPACK_NSIS_MODIFY_PATH ON) + set(CPACK_NSIS_MENU_LINKS + "${Application_Name}.exe" "DynuIpRefresher Console" + "${Application_Name}-gui.exe" "DynuIpRefresher GUI") + + # varnames need uppercase strings + string(TOUPPER ${Application_Name} APPLICATION_NAME_UPPER) + # Define components and their display names + set (CPACK_COMPONENTS_ALL ${Application_Name} ${Application_Name}gui) + set (CPACK_COMPONENT_${APPLICATION_NAME_UPPER}_DISPLAY_NAME "Dynu IP Refresher Console") + set (CPACK_COMPONENT_${APPLICATION_NAME_UPPER}GUI_DISPLAY_NAME "Dynu IP Refresher GUI") + + # Human readable component descriptions + set(CPACK_COMPONENT_${APPLICATION_NAME_UPPER}_DESCRIPTION "An extremely useful application that makes use of MyLib") + set(CPACK_COMPONENT_${APPLICATION_NAME_UPPER}GUI_DESCRIPTION "Static libraries used to build programs with MyLib") + + # Define dependencies between components + set(CPACK_COMPONENT_${APPLICATION_NAME_UPPER}GUI_DEPENDS ${Application_Name}) + + # Define groups + set(CPACK_COMPONENT_${APPLICATION_NAME_UPPER}_GROUP "Runtime") + set(CPACK_COMPONENT_${APPLICATION_NAME_UPPER}GUI_GROUP "Development") + + set(CPACK_COMPONENT_GROUP_DEVELOPMENT_DESCRIPTION "All of the tools you'll ever need to develop software") + + # Define NSIS installation types + set(CPACK_ALL_INSTALL_TYPES Full Developer) + set(CPACK_COMPONENT_${APPLICATION_NAME_UPPER}_INSTALL_TYPES Developer Full) + set(CPACK_COMPONENT_${APPLICATION_NAME_UPPER}GUI_INSTALL_TYPES Full) ENDIF () INCLUDE(CPack) diff --git a/src/Config.cpp b/src/Config.cpp index d68aea7..80cb95f 100644 --- a/src/Config.cpp +++ b/src/Config.cpp @@ -100,7 +100,7 @@ bool Config::validateConfig() { libconfig::Config cfg; try { Logger::message("reading config file"); - cfg.readFile(StaticData::ConfigDir.c_str()); + cfg.readFile(std::string(StaticData::ConfigDir + StaticData::ConfName).c_str()); } catch (const libconfig::FileIOException &fioex) { Logger::warning("config file doesn't exist or permission denied!"); From 4b19ecf3c3b5b7a9c7b3a44cbb5199f1d117ed56 Mon Sep 17 00:00:00 2001 From: lukas Date: Mon, 8 Jun 2020 10:54:22 +0200 Subject: [PATCH 10/10] added dockerfiles and edited readme --- Docker/Linux/Dockerfile | 19 +++++++++++++++++++ Docker/Windows/Dockerfile | 20 ++++++++++++++++++++ README.md | 20 +++++++++++++++++++- 3 files changed, 58 insertions(+), 1 deletion(-) create mode 100644 Docker/Linux/Dockerfile create mode 100644 Docker/Windows/Dockerfile diff --git a/Docker/Linux/Dockerfile b/Docker/Linux/Dockerfile new file mode 100644 index 0000000..00b37ec --- /dev/null +++ b/Docker/Linux/Dockerfile @@ -0,0 +1,19 @@ +FROM gcc:latest +MAINTAINER luki42 + +RUN \ + \ + # Install texlive + echo "instaling cmake" && \ + apt-get update && \ + apt-get install -y --no-install-recommends cmake libgtest-dev && \ + echo "installing build dependencies" && \ + apt-get install -y --no-install-recommends libcurl4-openssl-dev libconfig++-dev && \ + echo "installing packaging tools" && \ + apt-get install -y --no-install-recommends dpkg rpm && \ + # clean up + apt-get clean + +# Expose /home as workin dir +WORKDIR /home +VOLUME ["/home"] \ No newline at end of file diff --git a/Docker/Windows/Dockerfile b/Docker/Windows/Dockerfile new file mode 100644 index 0000000..c52d108 --- /dev/null +++ b/Docker/Windows/Dockerfile @@ -0,0 +1,20 @@ +FROM fedora:33 +MAINTAINER luki42 + +RUN \ + \ + # Install texlive + echo "instaling cmake" && \ + dnf install -y mingw64-gcc-c++ mingw64-curl-static mingw64-qt5-qtbase wget cmake make tar xz mingw32-nsis gtest gtest-devel && \ + wget http://repo.msys2.org/mingw/x86_64/mingw-w64-x86_64-libconfig-1.7.2-1-any.pkg.tar.xz && \ + tar -xf mingw-w64-x86_64-libconfig-1.7.2-1-any.pkg.tar.xz && \ + mv ./mingw64/bin/* /usr/x86_64-w64-mingw32/sys-root/mingw/bin && \ + mv ./mingw64/include/* /usr/x86_64-w64-mingw32/sys-root/mingw/include && \ + mv ./mingw64/lib/*.a /usr/x86_64-w64-mingw32/sys-root/mingw/lib && \ + mv ./mingw64/lib/cmake/* /usr/x86_64-w64-mingw32/sys-root/mingw/lib/cmake && \ + rm -Rv mingw-w64-x86_64-libconfig-1.7.2-1-any.pkg.tar.xz mingw64 && \ + #cleanup + dnf clean dbcache && dnf clean packages +# Expose /home as workin dir +WORKDIR /home +VOLUME ["/home"] \ No newline at end of file diff --git a/README.md b/README.md index bf7f869..5642a69 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,7 @@ # DynuIPRefresher A lightweight C++ application to setup a service for refreshing a dynamic IP to the Dynu servers. Dynu.com is a free DDns service and provides an API. +There is also a GUI for Windows Users and beginners. ## Installation Download the latest Release at [Release_Page](https://github.com/Lukas-Heiligenbrunner/DynuIPRefresher/releases). @@ -31,6 +32,17 @@ help page: [no argument] normal ip check and refresh ``` +### GUI + +You can also build the grapical user inteface if you want. +There you can manually trigger a refresh in a gui and set all the config parameters. + +Home Page: +![couldn't load image](https://i.ibb.co/syDwWQg/Screenshot-20200608-104253.png) + +Config Page: +![couldn't load image](https://i.ibb.co/89vnJXY/Screenshot-20200608-104308.png) + ## Build ## Basic Build @@ -85,6 +97,10 @@ cd into downloaded files and Generate makefiles: `make package` +### GUI Build + +please use the predefined Docker-Image here: +[DockerHub](https://hub.docker.com/repository/docker/luki42/dynuiprefresher_build) ### Windows cross build @@ -99,5 +115,7 @@ Optional dependencies * NSIS Pack tool (for creating installer) * doxygen (for generating html doc) -Some addition configuration of lib paths may be needed in CMakeList.txt. +The Simplest way to install all dependencies is the preconfigured Docker-Image: +[DockerHub](https://hub.docker.com/repository/docker/luki42/dynuiprefresher_build) + `make package` will pack it into a NSIS installer for Windows.