Massive refactoring
This commit is contained in:
parent
4814d9002d
commit
9d054d4119
10
App.cpp
Normal file
10
App.cpp
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
//
|
||||||
|
// Created by selim on 01.10.22.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "App.h"
|
||||||
|
|
||||||
|
App &App::instance() {
|
||||||
|
static App app("pro.aliencat.autocat");
|
||||||
|
return app;
|
||||||
|
}
|
||||||
17
App.h
Normal file
17
App.h
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
//
|
||||||
|
// Created by selim on 01.10.22.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef AUTOCAT_GNOME_APP_H
|
||||||
|
#define AUTOCAT_GNOME_APP_H
|
||||||
|
|
||||||
|
#include "gtkpp/Application.h"
|
||||||
|
|
||||||
|
class App: public gtkpp::Application {
|
||||||
|
public:
|
||||||
|
using gtkpp::Application::Application;
|
||||||
|
static App& instance();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //AUTOCAT_GNOME_APP_H
|
||||||
@ -17,12 +17,12 @@ if(APPLE)
|
|||||||
set(OPENSSL_LIBRARIES /usr/local/opt/openssl/lib)
|
set(OPENSSL_LIBRARIES /usr/local/opt/openssl/lib)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
#list(APPEND CMAKE_MODULE_PATH /usr/local/lib/cmake/concurrencpp-0.1.4)
|
|
||||||
|
|
||||||
find_package(PkgConfig REQUIRED)
|
find_package(PkgConfig REQUIRED)
|
||||||
find_package(nlohmann_json REQUIRED)
|
find_package(nlohmann_json REQUIRED)
|
||||||
find_package(concurrencpp REQUIRED)
|
find_package(concurrencpp REQUIRED)
|
||||||
find_package(Threads REQUIRED)
|
find_package(Threads REQUIRED)
|
||||||
|
find_package(SQLite3 REQUIRED)
|
||||||
|
find_package(fmt REQUIRED)
|
||||||
|
|
||||||
pkg_check_modules(GTK REQUIRED gtk4)
|
pkg_check_modules(GTK REQUIRED gtk4)
|
||||||
pkg_check_modules(GLIB REQUIRED glib-2.0)
|
pkg_check_modules(GLIB REQUIRED glib-2.0)
|
||||||
@ -30,8 +30,6 @@ pkg_check_modules(LIBSOUP REQUIRED libsoup-2.4)
|
|||||||
pkg_check_modules(LIBADWAITA REQUIRED libadwaita-1)
|
pkg_check_modules(LIBADWAITA REQUIRED libadwaita-1)
|
||||||
pkg_check_modules(LIBSIGCPP REQUIRED sigc++-3.0)
|
pkg_check_modules(LIBSIGCPP REQUIRED sigc++-3.0)
|
||||||
|
|
||||||
#ExternalProject_Add(concurrencpp GIT_REPOSITORY https://github.com/David-Haim/concurrencpp)
|
|
||||||
|
|
||||||
include_directories(${GTK_INCLUDE_DIRS}
|
include_directories(${GTK_INCLUDE_DIRS}
|
||||||
${GLIB_INCLUDE_DIRS}
|
${GLIB_INCLUDE_DIRS}
|
||||||
${LIBSOUP_INCLUDE_DIRS}
|
${LIBSOUP_INCLUDE_DIRS}
|
||||||
@ -77,7 +75,17 @@ add_executable(autocat_gnome main.cpp
|
|||||||
gtkpp/MessageDialog.cpp
|
gtkpp/MessageDialog.cpp
|
||||||
gtkpp/MessageDialog.h
|
gtkpp/MessageDialog.h
|
||||||
gtkpp/Leaflet.cpp
|
gtkpp/Leaflet.cpp
|
||||||
gtkpp/Leaflet.h gtkpp/Dialog.cpp gtkpp/Dialog.h gui/AddNumberDialog.cpp gui/AddNumberDialog.h gui/custom/PlateView.h gui/custom/PlateView.c)
|
gtkpp/Leaflet.h
|
||||||
|
gtkpp/Dialog.cpp
|
||||||
|
gtkpp/Dialog.h
|
||||||
|
gui/AddNumberDialog.cpp
|
||||||
|
gui/AddNumberDialog.h
|
||||||
|
gui/custom/PlateView.h
|
||||||
|
gui/custom/PlateView.c
|
||||||
|
App.cpp
|
||||||
|
App.h
|
||||||
|
models/Vehicle.cpp
|
||||||
|
models/Vehicle.h services/Storage.cpp services/Storage.h models/Engine.cpp models/Engine.h services/IDBEntity.h models/JsonOptional.h services/IDBEntity.cpp gtkpp/ScrolledWindow.cpp gtkpp/ScrolledWindow.h gtkpp/ListView.cpp gtkpp/ListView.h gtkpp/SelectionModel.cpp gtkpp/SelectionModel.h gtkpp/ListItemFactory.cpp gtkpp/ListItemFactory.h models/VehiclesListFactory.cpp models/VehiclesListFactory.h gtkpp/Separator.cpp gtkpp/Separator.h)
|
||||||
|
|
||||||
target_link_libraries(autocat_gnome ${GTK_LIBRARIES}
|
target_link_libraries(autocat_gnome ${GTK_LIBRARIES}
|
||||||
${GLIB_LIBRARIES}
|
${GLIB_LIBRARIES}
|
||||||
@ -86,9 +94,11 @@ target_link_libraries(autocat_gnome ${GTK_LIBRARIES}
|
|||||||
${LIBSIGCPP_LIBRARIES}
|
${LIBSIGCPP_LIBRARIES}
|
||||||
nlohmann_json::nlohmann_json
|
nlohmann_json::nlohmann_json
|
||||||
concurrencpp::concurrencpp
|
concurrencpp::concurrencpp
|
||||||
Threads::Threads)
|
Threads::Threads
|
||||||
|
SQLite::SQLite3
|
||||||
|
fmt::fmt)
|
||||||
|
|
||||||
set(XML gui/MainWindow.xml gui/AddNumberDialog.xml)
|
set(XML gui/MainWindow.xml)
|
||||||
|
|
||||||
list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake/Modules")
|
list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake/Modules")
|
||||||
include(GlibCompileResourcesSupport)
|
include(GlibCompileResourcesSupport)
|
||||||
|
|||||||
@ -13,7 +13,7 @@ namespace gtkpp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Application::Application(const std::string &id) {
|
Application::Application(const std::string &id) {
|
||||||
_app = adw_application_new(id.c_str(), G_APPLICATION_FLAGS_NONE);
|
_app = adw_application_new(id.c_str(), G_APPLICATION_DEFAULT_FLAGS);
|
||||||
g_signal_connect(_app, "activate", G_CALLBACK(activateCallback), this);
|
g_signal_connect(_app, "activate", G_CALLBACK(activateCallback), this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -4,14 +4,22 @@
|
|||||||
|
|
||||||
#include "Box.h"
|
#include "Box.h"
|
||||||
|
|
||||||
gtkpp::Box::Box(GtkOrientation orientation, int spacing) : Widget() {
|
namespace gtkpp {
|
||||||
|
|
||||||
|
Box::Box(GtkWidget *widget): Widget() {
|
||||||
|
_widget = widget;
|
||||||
|
}
|
||||||
|
|
||||||
|
Box::Box(GtkOrientation orientation, int spacing) : Widget() {
|
||||||
_widget = gtk_box_new(orientation, spacing);
|
_widget = gtk_box_new(orientation, spacing);
|
||||||
}
|
}
|
||||||
|
|
||||||
void gtkpp::Box::append(const gtkpp::Widget& widget) {
|
void Box::append(const gtkpp::Widget& widget) {
|
||||||
gtk_box_append(GTK_BOX(_widget), widget.gobj());
|
gtk_box_append(GTK_BOX(_widget), widget.gobj());
|
||||||
}
|
}
|
||||||
|
|
||||||
void gtkpp::Box::append(GtkWidget *widget) {
|
void Box::append(GtkWidget *widget) {
|
||||||
gtk_box_append(GTK_BOX(_widget), widget);
|
gtk_box_append(GTK_BOX(_widget), widget);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,8 +11,9 @@
|
|||||||
|
|
||||||
namespace gtkpp {
|
namespace gtkpp {
|
||||||
|
|
||||||
class Box: public Widget{
|
class Box: public Widget {
|
||||||
public:
|
public:
|
||||||
|
Box(GtkWidget* widget);
|
||||||
Box(GtkOrientation orientation, int spacing);
|
Box(GtkOrientation orientation, int spacing);
|
||||||
void append(const Widget& widget);
|
void append(const Widget& widget);
|
||||||
void append(GtkWidget* widget);
|
void append(GtkWidget* widget);
|
||||||
|
|||||||
@ -15,4 +15,8 @@ namespace gtkpp {
|
|||||||
gtk_button_set_label(GTK_BUTTON(_widget), title.c_str());
|
gtk_button_set_label(GTK_BUTTON(_widget), title.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Button::setIconName(const std::string &name) {
|
||||||
|
gtk_button_set_icon_name(GTK_BUTTON(_widget), name.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,6 +15,7 @@ namespace gtkpp {
|
|||||||
using Widget::Widget;
|
using Widget::Widget;
|
||||||
Button();
|
Button();
|
||||||
void setTitle(const std::string& title);
|
void setTitle(const std::string& title);
|
||||||
|
void setIconName(const std::string& name);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,3 +3,58 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#include "Dialog.h"
|
#include "Dialog.h"
|
||||||
|
|
||||||
|
namespace gtkpp {
|
||||||
|
|
||||||
|
void responseCallback(GtkDialog*, GtkResponseType responseId, void* data) {
|
||||||
|
auto dialog = reinterpret_cast<Dialog*>(data);
|
||||||
|
dialog->_response = responseId;
|
||||||
|
dialog->_signalResponse.emit(responseId);
|
||||||
|
}
|
||||||
|
|
||||||
|
Dialog::Dialog(Window* parent) {
|
||||||
|
|
||||||
|
auto flags = static_cast<GtkDialogFlags>(GTK_DIALOG_DESTROY_WITH_PARENT
|
||||||
|
| GTK_DIALOG_MODAL
|
||||||
|
| GTK_DIALOG_USE_HEADER_BAR);
|
||||||
|
|
||||||
|
auto dialog = gtk_dialog_new_with_buttons("Add plate number",
|
||||||
|
parent->gobj(),
|
||||||
|
flags,
|
||||||
|
"OK", GTK_RESPONSE_OK,
|
||||||
|
"Cancel", GTK_RESPONSE_CANCEL,
|
||||||
|
nullptr);
|
||||||
|
_window = GTK_WINDOW(dialog);
|
||||||
|
gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
|
||||||
|
_responseHandlerId = g_signal_connect (dialog, "response", G_CALLBACK(responseCallback), this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Dialog::onResponse(const std::function<void(GtkResponseType)> &callback) {
|
||||||
|
_signalResponse.connect(callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
cc::result<GtkResponseType> Dialog::responseAsync() {
|
||||||
|
auto promise = std::make_shared<cc::result_promise<GtkResponseType>>();
|
||||||
|
auto result = promise->get_result();
|
||||||
|
|
||||||
|
_signalResponse.connect([promise](GtkResponseType response){
|
||||||
|
promise->set_result(response);
|
||||||
|
});
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
Dialog::~Dialog() {
|
||||||
|
g_signal_handler_disconnect(_window, _responseHandlerId);
|
||||||
|
}
|
||||||
|
|
||||||
|
GtkResponseType Dialog::currentResponse() const {
|
||||||
|
return _response;
|
||||||
|
}
|
||||||
|
|
||||||
|
Box Dialog::contentWidget() const {
|
||||||
|
auto contentArea = gtk_dialog_get_content_area (GTK_DIALOG(_window));
|
||||||
|
return {contentArea};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@ -6,12 +6,30 @@
|
|||||||
#define AUTOCAT_GNOME_DIALOG_H
|
#define AUTOCAT_GNOME_DIALOG_H
|
||||||
|
|
||||||
#include "Window.h"
|
#include "Window.h"
|
||||||
|
#include "Box.h"
|
||||||
|
#include <sigc++/sigc++.h>
|
||||||
|
#include <concurrencpp/concurrencpp.h>
|
||||||
|
|
||||||
|
namespace cc = concurrencpp;
|
||||||
|
|
||||||
namespace gtkpp {
|
namespace gtkpp {
|
||||||
|
|
||||||
class Dialog: public Window {
|
class Dialog: public Window {
|
||||||
|
private:
|
||||||
|
GtkResponseType _response = GTK_RESPONSE_NONE;
|
||||||
|
gulong _responseHandlerId;
|
||||||
|
sigc::signal<void(GtkResponseType)> _signalResponse;
|
||||||
|
friend void responseCallback(GtkDialog*, GtkResponseType responseId, void* data);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using Window::Window;
|
void onResponse(const std::function<void(GtkResponseType)>& callback);
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit Dialog(Window* parent);
|
||||||
|
~Dialog();
|
||||||
|
cc::result<GtkResponseType> responseAsync();
|
||||||
|
GtkResponseType currentResponse() const;
|
||||||
|
Box contentWidget() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -13,7 +13,11 @@ namespace gtkpp {
|
|||||||
|
|
||||||
Entry::Entry() : Widget() {
|
Entry::Entry() : Widget() {
|
||||||
_widget = gtk_entry_new();
|
_widget = gtk_entry_new();
|
||||||
g_signal_connect(_widget, "changed", G_CALLBACK(changedCallback), this);
|
_changedHandlerId = g_signal_connect(_widget, "changed", G_CALLBACK(changedCallback), this);
|
||||||
|
}
|
||||||
|
|
||||||
|
Entry::~Entry() {
|
||||||
|
g_signal_handler_disconnect(_widget, _changedHandlerId);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Entry::setPlaceholder(const std::string &placeholder) {
|
void Entry::setPlaceholder(const std::string &placeholder) {
|
||||||
|
|||||||
@ -13,6 +13,7 @@ namespace gtkpp {
|
|||||||
|
|
||||||
class Entry: public Widget {
|
class Entry: public Widget {
|
||||||
private:
|
private:
|
||||||
|
gulong _changedHandlerId;
|
||||||
sigc::signal<void()> _signalChanged;
|
sigc::signal<void()> _signalChanged;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -20,6 +21,7 @@ namespace gtkpp {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
Entry();
|
Entry();
|
||||||
|
~Entry();
|
||||||
void setPlaceholder(const std::string& placeholder);
|
void setPlaceholder(const std::string& placeholder);
|
||||||
void setPurpose(GtkInputPurpose purpose);
|
void setPurpose(GtkInputPurpose purpose);
|
||||||
void setVisibility(bool visibility);
|
void setVisibility(bool visibility);
|
||||||
|
|||||||
@ -18,4 +18,12 @@ namespace gtkpp {
|
|||||||
void HeaderBar::setTitle(const std::string& title) {
|
void HeaderBar::setTitle(const std::string& title) {
|
||||||
adw_header_bar_set_title_widget(ADW_HEADER_BAR(_widget), gtk_label_new(title.c_str()));
|
adw_header_bar_set_title_widget(ADW_HEADER_BAR(_widget), gtk_label_new(title.c_str()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HeaderBar::showEndButtons(bool show) {
|
||||||
|
adw_header_bar_set_show_end_title_buttons(ADW_HEADER_BAR(_widget), show);
|
||||||
|
}
|
||||||
|
|
||||||
|
void HeaderBar::packStart(const Widget &widget) {
|
||||||
|
adw_header_bar_pack_start(ADW_HEADER_BAR(_widget), widget.gobj());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -15,6 +15,8 @@ namespace gtkpp {
|
|||||||
HeaderBar();
|
HeaderBar();
|
||||||
explicit HeaderBar(const std::string& title);
|
explicit HeaderBar(const std::string& title);
|
||||||
void setTitle(const std::string& title);
|
void setTitle(const std::string& title);
|
||||||
|
void showEndButtons(bool show);
|
||||||
|
void packStart(const Widget& widget);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,8 +11,8 @@ namespace gtkpp {
|
|||||||
_widget = adw_leaflet_new();
|
_widget = adw_leaflet_new();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Leaflet::append(Widget *widget) {
|
void Leaflet::append(const Widget& widget) {
|
||||||
adw_leaflet_append(ADW_LEAFLET(_widget), widget->gobj());
|
adw_leaflet_append(ADW_LEAFLET(_widget), widget.gobj());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,7 +12,7 @@ namespace gtkpp {
|
|||||||
class Leaflet: public Widget {
|
class Leaflet: public Widget {
|
||||||
public:
|
public:
|
||||||
Leaflet();
|
Leaflet();
|
||||||
void append(Widget* widget);
|
void append(const Widget& widget);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
27
gtkpp/ListItemFactory.cpp
Normal file
27
gtkpp/ListItemFactory.cpp
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
//
|
||||||
|
// Created by selim on 13.11.22.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "ListItemFactory.h"
|
||||||
|
|
||||||
|
namespace gtkpp {
|
||||||
|
|
||||||
|
void setupListItemCallback(GtkListItemFactory* factory, GtkListItem* list_item, void* data) {
|
||||||
|
auto self = reinterpret_cast<ListItemFactory*>(data);
|
||||||
|
self->setup();
|
||||||
|
}
|
||||||
|
|
||||||
|
ListItemFactory::ListItemFactory() {
|
||||||
|
_factory = gtk_signal_list_item_factory_new();
|
||||||
|
g_signal_connect(_factory, "setup", G_CALLBACK(setupListItemCallback), this);
|
||||||
|
}
|
||||||
|
|
||||||
|
GtkListItemFactory *ListItemFactory::gobj() const {
|
||||||
|
return _factory;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ListItemFactory::setup() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
26
gtkpp/ListItemFactory.h
Normal file
26
gtkpp/ListItemFactory.h
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
//
|
||||||
|
// Created by selim on 13.11.22.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef AUTOCAT_GNOME_LISTITEMFACTORY_H
|
||||||
|
#define AUTOCAT_GNOME_LISTITEMFACTORY_H
|
||||||
|
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
|
namespace gtkpp {
|
||||||
|
|
||||||
|
class ListItemFactory {
|
||||||
|
private:
|
||||||
|
GtkListItemFactory* _factory;
|
||||||
|
|
||||||
|
public:
|
||||||
|
ListItemFactory();
|
||||||
|
[[nodiscard]] GtkListItemFactory* gobj() const;
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual void setup();
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //AUTOCAT_GNOME_LISTITEMFACTORY_H
|
||||||
13
gtkpp/ListView.cpp
Normal file
13
gtkpp/ListView.cpp
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
//
|
||||||
|
// Created by selim on 13.11.22.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "ListView.h"
|
||||||
|
|
||||||
|
namespace gtkpp {
|
||||||
|
|
||||||
|
ListView::ListView(SelectionModel selectionModel, ListItemFactory factory) {
|
||||||
|
_widget = gtk_list_view_new(selectionModel.gobj(), factory.gobj());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
21
gtkpp/ListView.h
Normal file
21
gtkpp/ListView.h
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
//
|
||||||
|
// Created by selim on 13.11.22.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef AUTOCAT_GNOME_LISTVIEW_H
|
||||||
|
#define AUTOCAT_GNOME_LISTVIEW_H
|
||||||
|
|
||||||
|
#include "Widget.h"
|
||||||
|
#include "SelectionModel.h"
|
||||||
|
#include "ListItemFactory.h"
|
||||||
|
|
||||||
|
namespace gtkpp {
|
||||||
|
|
||||||
|
class ListView: public Widget {
|
||||||
|
public:
|
||||||
|
ListView(SelectionModel selectionModel, ListItemFactory factory);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //AUTOCAT_GNOME_LISTVIEW_H
|
||||||
15
gtkpp/ScrolledWindow.cpp
Normal file
15
gtkpp/ScrolledWindow.cpp
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
//
|
||||||
|
// Created by selim on 13.11.22.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "ScrolledWindow.h"
|
||||||
|
|
||||||
|
#include <gtk/gtkscrolledwindow.h>
|
||||||
|
|
||||||
|
namespace gtkpp {
|
||||||
|
|
||||||
|
ScrolledWindow::ScrolledWindow() {
|
||||||
|
_widget = gtk_scrolled_window_new();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
19
gtkpp/ScrolledWindow.h
Normal file
19
gtkpp/ScrolledWindow.h
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
//
|
||||||
|
// Created by selim on 13.11.22.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef AUTOCAT_GNOME_SCROLLEDWINDOW_H
|
||||||
|
#define AUTOCAT_GNOME_SCROLLEDWINDOW_H
|
||||||
|
|
||||||
|
#include "Widget.h"
|
||||||
|
|
||||||
|
namespace gtkpp {
|
||||||
|
|
||||||
|
class ScrolledWindow: public Widget {
|
||||||
|
public:
|
||||||
|
ScrolledWindow();
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //AUTOCAT_GNOME_SCROLLEDWINDOW_H
|
||||||
26
gtkpp/SelectionModel.cpp
Normal file
26
gtkpp/SelectionModel.cpp
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
//
|
||||||
|
// Created by selim on 13.11.22.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "SelectionModel.h"
|
||||||
|
|
||||||
|
namespace gtkpp {
|
||||||
|
|
||||||
|
SelectionModel::SelectionModel(gtkpp::Selection selection) {
|
||||||
|
|
||||||
|
char *array[] = { "one", "two", "three", "four", NULL };
|
||||||
|
GtkStringList *sl = gtk_string_list_new ((const char * const *) array);
|
||||||
|
|
||||||
|
switch (selection) {
|
||||||
|
case None:
|
||||||
|
_model = GTK_SELECTION_MODEL(gtk_no_selection_new(G_LIST_MODEL(sl)));
|
||||||
|
case Single:
|
||||||
|
_model = GTK_SELECTION_MODEL(gtk_single_selection_new(G_LIST_MODEL(sl)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GtkSelectionModel *SelectionModel::gobj() const {
|
||||||
|
return _model;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
29
gtkpp/SelectionModel.h
Normal file
29
gtkpp/SelectionModel.h
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
//
|
||||||
|
// Created by selim on 13.11.22.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef AUTOCAT_GNOME_SELECTIONMODEL_H
|
||||||
|
#define AUTOCAT_GNOME_SELECTIONMODEL_H
|
||||||
|
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
#include <gio/glistmodel.h>
|
||||||
|
|
||||||
|
namespace gtkpp {
|
||||||
|
|
||||||
|
enum Selection {
|
||||||
|
None,
|
||||||
|
Single
|
||||||
|
};
|
||||||
|
|
||||||
|
class SelectionModel {
|
||||||
|
private:
|
||||||
|
GtkSelectionModel* _model;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit SelectionModel(Selection selection);
|
||||||
|
[[nodiscard]] GtkSelectionModel* gobj() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //AUTOCAT_GNOME_SELECTIONMODEL_H
|
||||||
9
gtkpp/Separator.cpp
Normal file
9
gtkpp/Separator.cpp
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
//
|
||||||
|
// Created by selim on 15.11.22.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "Separator.h"
|
||||||
|
|
||||||
|
gtkpp::Separator::Separator(GtkOrientation orientation) {
|
||||||
|
_widget = gtk_separator_new(orientation);
|
||||||
|
}
|
||||||
19
gtkpp/Separator.h
Normal file
19
gtkpp/Separator.h
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
//
|
||||||
|
// Created by selim on 15.11.22.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef AUTOCAT_GNOME_SEPARATOR_H
|
||||||
|
#define AUTOCAT_GNOME_SEPARATOR_H
|
||||||
|
|
||||||
|
#include "Widget.h"
|
||||||
|
|
||||||
|
namespace gtkpp {
|
||||||
|
|
||||||
|
class Separator: public Widget {
|
||||||
|
public:
|
||||||
|
explicit Separator(GtkOrientation orientation);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //AUTOCAT_GNOME_SEPARATOR_H
|
||||||
@ -19,6 +19,11 @@ namespace gtkpp {
|
|||||||
_widget = nullptr;
|
_widget = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Widget::Widget(GtkWidget *widget) {
|
||||||
|
_widget = widget;
|
||||||
|
g_signal_connect(_widget, "clicked", G_CALLBACK(clickedCallback), this);
|
||||||
|
}
|
||||||
|
|
||||||
Widget::Widget(GtkBuilder *builder, const char *id) {
|
Widget::Widget(GtkBuilder *builder, const char *id) {
|
||||||
_widget = GTK_WIDGET(gtk_builder_get_object(builder, id));
|
_widget = GTK_WIDGET(gtk_builder_get_object(builder, id));
|
||||||
g_signal_connect(_widget, "clicked", G_CALLBACK(clickedCallback), this);
|
g_signal_connect(_widget, "clicked", G_CALLBACK(clickedCallback), this);
|
||||||
@ -43,6 +48,10 @@ namespace gtkpp {
|
|||||||
gtk_widget_set_vexpand(_widget, expand);
|
gtk_widget_set_vexpand(_widget, expand);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Widget::setHExpand(bool expand) {
|
||||||
|
gtk_widget_set_hexpand(_widget, expand);
|
||||||
|
}
|
||||||
|
|
||||||
void Widget::setHorizontalMargins(int margin) {
|
void Widget::setHorizontalMargins(int margin) {
|
||||||
gtk_widget_set_margin_start(_widget, margin);
|
gtk_widget_set_margin_start(_widget, margin);
|
||||||
gtk_widget_set_margin_end(_widget, margin);
|
gtk_widget_set_margin_end(_widget, margin);
|
||||||
@ -61,4 +70,12 @@ namespace gtkpp {
|
|||||||
g_signal_connect(_widget, "clicked", G_CALLBACK(clickedCallback), this);
|
g_signal_connect(_widget, "clicked", G_CALLBACK(clickedCallback), this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Widget::show() {
|
||||||
|
gtk_widget_show(_widget);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Widget::hide() {
|
||||||
|
gtk_widget_hide(_widget);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -28,6 +28,7 @@ namespace gtkpp {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
Widget();
|
Widget();
|
||||||
|
explicit Widget(GtkWidget* widget);
|
||||||
Widget(GtkBuilder* builder, const char* id);
|
Widget(GtkBuilder* builder, const char* id);
|
||||||
[[nodiscard]] GtkWidget* gobj() const;
|
[[nodiscard]] GtkWidget* gobj() const;
|
||||||
void setMargins(int margin);
|
void setMargins(int margin);
|
||||||
@ -35,7 +36,10 @@ namespace gtkpp {
|
|||||||
void setHorizontalMargins(int margin);
|
void setHorizontalMargins(int margin);
|
||||||
void setVAlign(GtkAlign align);
|
void setVAlign(GtkAlign align);
|
||||||
void setVExpand(bool expand);
|
void setVExpand(bool expand);
|
||||||
|
void setHExpand(bool expand);
|
||||||
void setEnabled(bool enabled);
|
void setEnabled(bool enabled);
|
||||||
|
void show();
|
||||||
|
void hide();
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,6 +3,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#include "Window.h"
|
#include "Window.h"
|
||||||
|
#include "../App.h"
|
||||||
|
|
||||||
namespace gtkpp {
|
namespace gtkpp {
|
||||||
|
|
||||||
@ -15,23 +16,28 @@ namespace gtkpp {
|
|||||||
_builder = nullptr;
|
_builder = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
Window::Window(std::shared_ptr<Application> app, bool isAppWindow) {
|
Window::Window(bool isAppWindow): _isAppWindow(isAppWindow) {
|
||||||
if(isAppWindow) {
|
if(isAppWindow) {
|
||||||
_window = GTK_WINDOW(adw_application_window_new(GTK_APPLICATION(app->gobj())));
|
auto app = GTK_APPLICATION(App::instance().gobj());
|
||||||
|
_window = GTK_WINDOW(adw_application_window_new(app));
|
||||||
} else {
|
} else {
|
||||||
_window = GTK_WINDOW(adw_window_new());
|
_window = GTK_WINDOW(adw_window_new());
|
||||||
}
|
}
|
||||||
|
|
||||||
_app = app;
|
|
||||||
_builder = nullptr;
|
_builder = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
Window::Window(std::shared_ptr<Application> app, const char* resourceName, const char* id) {
|
Window::Window(const char* resourceName, const char* id) {
|
||||||
_app = app;
|
|
||||||
_builder = gtk_builder_new_from_resource(resourceName);
|
_builder = gtk_builder_new_from_resource(resourceName);
|
||||||
_window = GTK_WINDOW(gtk_builder_get_object(_builder, id));
|
_window = GTK_WINDOW(gtk_builder_get_object(_builder, id));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Window::~Window() {
|
||||||
|
if(_window) {
|
||||||
|
destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Window::show() {
|
void Window::show() {
|
||||||
gtk_window_present(GTK_WINDOW(_window));
|
gtk_window_present(GTK_WINDOW(_window));
|
||||||
}
|
}
|
||||||
@ -48,12 +54,32 @@ namespace gtkpp {
|
|||||||
gtk_window_set_default_size(GTK_WINDOW(_window), width, height);
|
gtk_window_set_default_size(GTK_WINDOW(_window), width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<Application> Window::application() const {
|
|
||||||
return _app.lock();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Window::hide() {
|
void Window::hide() {
|
||||||
gtk_window_close(GTK_WINDOW(_window));
|
gtk_window_close(GTK_WINDOW(_window));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Window::destroy() {
|
||||||
|
gtk_window_destroy(GTK_WINDOW(_window));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Window::setTransientFor(const Window* window) {
|
||||||
|
gtk_window_set_transient_for(_window, window->gobj());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Window::setModal() {
|
||||||
|
gtk_window_set_modal(_window, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Window::setContent(const Widget& widget) {
|
||||||
|
if(_isAppWindow) {
|
||||||
|
adw_application_window_set_content(ADW_APPLICATION_WINDOW(_window), widget.gobj());
|
||||||
|
} else {
|
||||||
|
adw_window_set_content(ADW_WINDOW(_window), widget.gobj());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Window::setResizable(bool resizable) {
|
||||||
|
gtk_window_set_resizable(_window, resizable);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,6 +6,8 @@
|
|||||||
#define AUTOCAT_GNOME_WINDOW_H
|
#define AUTOCAT_GNOME_WINDOW_H
|
||||||
|
|
||||||
#include "Application.h"
|
#include "Application.h"
|
||||||
|
#include "Widget.h"
|
||||||
|
|
||||||
#include <adwaita.h>
|
#include <adwaita.h>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
@ -15,21 +17,26 @@ namespace gtkpp {
|
|||||||
protected:
|
protected:
|
||||||
GtkBuilder* _builder;
|
GtkBuilder* _builder;
|
||||||
GtkWindow* _window;
|
GtkWindow* _window;
|
||||||
std::weak_ptr<Application> _app;
|
bool _isAppWindow;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend bool operator==(const Window& wnd1, const Window& wnd2);
|
friend bool operator==(const Window& wnd1, const Window& wnd2);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Window();
|
Window();
|
||||||
Window(std::shared_ptr<Application> app, bool isAppWindow);
|
explicit Window(bool isAppWindow);
|
||||||
Window(std::shared_ptr<Application> app, const char* resourceName, const char* id);
|
Window(const char* resourceName, const char* id);
|
||||||
|
virtual ~Window();
|
||||||
void show();
|
void show();
|
||||||
void hide();
|
void hide();
|
||||||
|
void destroy();
|
||||||
void setTitle(const std::string& title);
|
void setTitle(const std::string& title);
|
||||||
void setDefaultSize(int width, int height);
|
void setDefaultSize(int width, int height);
|
||||||
|
void setTransientFor(const Window* window);
|
||||||
|
void setModal();
|
||||||
[[nodiscard]] GtkWindow* gobj() const;
|
[[nodiscard]] GtkWindow* gobj() const;
|
||||||
[[nodiscard]] std::shared_ptr<Application> application() const;
|
void setContent(const Widget& widget);
|
||||||
|
void setResizable(bool resizable);
|
||||||
};
|
};
|
||||||
|
|
||||||
using WindowPtr = std::shared_ptr<Window>;
|
using WindowPtr = std::shared_ptr<Window>;
|
||||||
|
|||||||
@ -3,21 +3,33 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#include "AddNumberDialog.h"
|
#include "AddNumberDialog.h"
|
||||||
|
#include "../services/Api.h"
|
||||||
|
#include "../services/Storage.h"
|
||||||
|
|
||||||
AddNumberDialog::AddNumberDialog(GtkWindow* parent): gtkpp::Window() {
|
#include <iostream>
|
||||||
auto flags = static_cast<GtkDialogFlags>(GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_MODAL);
|
#include <algorithm>
|
||||||
auto dialog = gtk_dialog_new_with_buttons("Add plate number",
|
#include <cctype>
|
||||||
parent,
|
|
||||||
flags,
|
|
||||||
"OK", GTK_RESPONSE_ACCEPT,
|
|
||||||
"Cancel", GTK_RESPONSE_REJECT,
|
|
||||||
nullptr);
|
|
||||||
_window = GTK_WINDOW(dialog);
|
|
||||||
|
|
||||||
//auto contentArea = gtk_dialog_get_content_area (GTK_DIALOG(dialog));
|
AddNumberDialog::AddNumberDialog(gtkpp::Window* parent): gtkpp::Dialog(parent) {
|
||||||
|
auto content = contentWidget();
|
||||||
g_signal_connect_swapped (dialog,
|
_entry.setMargins(16);
|
||||||
"response",
|
_entry.setPlaceholder("Plate number");
|
||||||
G_CALLBACK(gtk_window_destroy),
|
content.append(_entry);
|
||||||
dialog);
|
content.append(_spinner);
|
||||||
|
_spinner.setMargins(16);
|
||||||
|
_spinner.hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string AddNumberDialog::text() const {
|
||||||
|
return _entry.text();
|
||||||
|
}
|
||||||
|
|
||||||
|
cc::result<void> AddNumberDialog::checkNumber() {
|
||||||
|
_spinner.show();
|
||||||
|
_spinner.start();
|
||||||
|
std::string text = _entry.text();
|
||||||
|
std::transform(text.begin(), text.end(), text.begin(), [](unsigned char c){ return std::toupper(c); });
|
||||||
|
auto vehicle = co_await Api::check(text);
|
||||||
|
Storage::instance().insert(&vehicle);
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@ -5,11 +5,24 @@
|
|||||||
#ifndef AUTOCAT_GNOME_ADDNUMBERDIALOG_H
|
#ifndef AUTOCAT_GNOME_ADDNUMBERDIALOG_H
|
||||||
#define AUTOCAT_GNOME_ADDNUMBERDIALOG_H
|
#define AUTOCAT_GNOME_ADDNUMBERDIALOG_H
|
||||||
|
|
||||||
#include "../gtkpp/Window.h"
|
#include "../gtkpp/Dialog.h"
|
||||||
|
#include "../gtkpp/Entry.h"
|
||||||
|
#include "../gtkpp/Spinner.h"
|
||||||
|
|
||||||
|
#include <concurrencpp/concurrencpp.h>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace cc = concurrencpp;
|
||||||
|
|
||||||
|
class AddNumberDialog: public gtkpp::Dialog {
|
||||||
|
private:
|
||||||
|
gtkpp::Entry _entry;
|
||||||
|
gtkpp::Spinner _spinner;
|
||||||
|
|
||||||
class AddNumberDialog: public gtkpp::Window {
|
|
||||||
public:
|
public:
|
||||||
explicit AddNumberDialog(GtkWindow* parent);
|
explicit AddNumberDialog(gtkpp::Window* parent);
|
||||||
|
std::string text() const;
|
||||||
|
cc::result<void> checkNumber();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -1,32 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<interface>
|
|
||||||
<object class="GtkDialog" id="add_number_dialog">
|
|
||||||
<!--
|
|
||||||
<child type="action">
|
|
||||||
<object class="GtkButton" id="button_cancel"/>
|
|
||||||
</child>
|
|
||||||
<child type="action">
|
|
||||||
<object class="GtkButton" id="button_ok">
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
<action-widgets>
|
|
||||||
<action-widget response="cancel">button_cancel</action-widget>
|
|
||||||
<action-widget response="ok" default="true">button_ok</action-widget>
|
|
||||||
</action-widgets>
|
|
||||||
-->
|
|
||||||
<child internal-child="content_area">
|
|
||||||
<object class="GtkBox" id="vbox1">
|
|
||||||
<child internal-child="action_area">
|
|
||||||
<object class="GtkBox" id="hbuttonbox1">
|
|
||||||
<child>
|
|
||||||
<object class="GtkButton" id="ok_button">
|
|
||||||
<property name="label" translatable="yes">_Ok</property>
|
|
||||||
<property name="use-underline">True</property>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
</object>
|
|
||||||
</child>
|
|
||||||
</object>
|
|
||||||
</interface>
|
|
||||||
@ -5,15 +5,14 @@
|
|||||||
#include "LoginWindow.h"
|
#include "LoginWindow.h"
|
||||||
#include "MainWindow.h"
|
#include "MainWindow.h"
|
||||||
#include "../services/Api.h"
|
#include "../services/Api.h"
|
||||||
#include "../coro/GLibMainContextExecutor.h"
|
|
||||||
|
|
||||||
#include "../gtkpp/HeaderBar.h"
|
#include "../gtkpp/HeaderBar.h"
|
||||||
#include "../gtkpp/MessageDialog.h"
|
#include "../gtkpp/MessageDialog.h"
|
||||||
|
#include "../App.h"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
LoginWindow::LoginWindow(std::shared_ptr<gtkpp::Application> app): gtkpp::Window(std::move(app), false) {
|
LoginWindow::LoginWindow(): gtkpp::Window(false) {
|
||||||
|
|
||||||
setDefaultSize(640, 480);
|
setDefaultSize(640, 480);
|
||||||
|
|
||||||
@ -44,7 +43,7 @@ LoginWindow::LoginWindow(std::shared_ptr<gtkpp::Application> app): gtkpp::Window
|
|||||||
rootBox.append(gtkpp::HeaderBar("Login"));
|
rootBox.append(gtkpp::HeaderBar("Login"));
|
||||||
rootBox.append(contentBox);
|
rootBox.append(contentBox);
|
||||||
|
|
||||||
adw_window_set_content(ADW_WINDOW(_window), rootBox.gobj());
|
setContent(rootBox);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoginWindow::loginClicked() {
|
void LoginWindow::loginClicked() {
|
||||||
@ -56,13 +55,11 @@ void LoginWindow::loginClicked() {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
User user = co_await Api::login(email, password);
|
User user = co_await Api::login(email, password);
|
||||||
if(auto app = this->application()) {
|
auto mainWindow = std::make_shared<MainWindow>();
|
||||||
auto mainWindow = std::make_shared<MainWindow>(app);
|
|
||||||
mainWindow->show();
|
mainWindow->show();
|
||||||
app->addWindow(mainWindow);
|
App::instance().addWindow(mainWindow);
|
||||||
app->removeWindow(this);
|
App::instance().removeWindow(this);
|
||||||
hide();
|
hide();
|
||||||
}
|
|
||||||
} catch (std::exception& ex) {
|
} catch (std::exception& ex) {
|
||||||
enableControls(true);
|
enableControls(true);
|
||||||
_spinner.stop();
|
_spinner.stop();
|
||||||
|
|||||||
@ -11,7 +11,6 @@
|
|||||||
#include "../gtkpp/Entry.h"
|
#include "../gtkpp/Entry.h"
|
||||||
#include "../gtkpp/Button.h"
|
#include "../gtkpp/Button.h"
|
||||||
#include "../gtkpp/Spinner.h"
|
#include "../gtkpp/Spinner.h"
|
||||||
#include "../gtkpp/Application.h"
|
|
||||||
|
|
||||||
class LoginWindow: public gtkpp::Window {
|
class LoginWindow: public gtkpp::Window {
|
||||||
private:
|
private:
|
||||||
@ -21,7 +20,7 @@ private:
|
|||||||
gtkpp::Spinner _spinner;
|
gtkpp::Spinner _spinner;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit LoginWindow(std::shared_ptr<gtkpp::Application> app);
|
LoginWindow();
|
||||||
|
|
||||||
void loginClicked();
|
void loginClicked();
|
||||||
void validateFields();
|
void validateFields();
|
||||||
|
|||||||
@ -4,17 +4,57 @@
|
|||||||
|
|
||||||
#include "MainWindow.h"
|
#include "MainWindow.h"
|
||||||
#include "AddNumberDialog.h"
|
#include "AddNumberDialog.h"
|
||||||
|
#include "../gtkpp/MessageDialog.h"
|
||||||
|
#include "../coro/Coro.h"
|
||||||
|
#include "../services/Storage.h"
|
||||||
#include "../gtkpp/HeaderBar.h"
|
#include "../gtkpp/HeaderBar.h"
|
||||||
|
#include "../gtkpp/Separator.h"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
MainWindow::MainWindow(std::shared_ptr<gtkpp::Application> app):
|
MainWindow::MainWindow(): gtkpp::Window(true) {
|
||||||
gtkpp::Window(std::move(app), "/gui/MainWindow.xml", "adw_main_window"),
|
|
||||||
_addNumberButton(_builder, "add_number_button") {
|
|
||||||
|
|
||||||
|
setDefaultSize(640, 480);
|
||||||
|
setResizable(true);
|
||||||
|
|
||||||
|
_addNumberButton.setIconName("list-add-symbolic");
|
||||||
_addNumberButton.onClick([this] {
|
_addNumberButton.onClick([this] {
|
||||||
std::cout << "Add clicked" << std::endl;
|
showCheckDialog();
|
||||||
auto dialog = std::make_unique<AddNumberDialog>(gobj());
|
|
||||||
dialog->show();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
gtkpp::HeaderBar leftHeader("Vehicles");
|
||||||
|
leftHeader.showEndButtons(false);
|
||||||
|
leftHeader.packStart(_addNumberButton);
|
||||||
|
|
||||||
|
gtkpp::Box leftPanel(GTK_ORIENTATION_VERTICAL, 0);
|
||||||
|
leftPanel.append(leftHeader);
|
||||||
|
|
||||||
|
gtkpp::HeaderBar rightHeader;
|
||||||
|
gtkpp::Box rightPanel(GTK_ORIENTATION_VERTICAL, 0);
|
||||||
|
rightPanel.append(rightHeader);
|
||||||
|
rightPanel.setHExpand(true);
|
||||||
|
|
||||||
|
_leaflet.append(leftPanel);
|
||||||
|
_leaflet.append(gtkpp::Separator(GTK_ORIENTATION_VERTICAL));
|
||||||
|
_leaflet.append(rightPanel);
|
||||||
|
_leaflet.setVExpand(true);
|
||||||
|
|
||||||
|
setContent(_leaflet);
|
||||||
|
|
||||||
|
auto vehicles = Storage::instance().select<Vehicle>();
|
||||||
|
std::cout << "" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::showCheckDialog() {
|
||||||
|
AddNumberDialog dialog(this);
|
||||||
|
dialog.show();
|
||||||
|
GtkResponseType response = co_await dialog.responseAsync();
|
||||||
|
|
||||||
|
if(response == GTK_RESPONSE_OK) {
|
||||||
|
try {
|
||||||
|
co_await dialog.checkNumber();
|
||||||
|
} catch(std::exception& ex) {
|
||||||
|
gtkpp::MessageDialog::showError(this, ex.what());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,7 +15,8 @@ private:
|
|||||||
gtkpp::Button _addNumberButton;
|
gtkpp::Button _addNumberButton;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit MainWindow(std::shared_ptr<gtkpp::Application> app);
|
explicit MainWindow();
|
||||||
|
void showCheckDialog();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
17
main.cpp
17
main.cpp
@ -3,16 +3,17 @@
|
|||||||
#include "services/Settings.h"
|
#include "services/Settings.h"
|
||||||
#include "gtkpp/Application.h"
|
#include "gtkpp/Application.h"
|
||||||
#include "gtkpp/Window.h"
|
#include "gtkpp/Window.h"
|
||||||
|
#include "App.h"
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
std::shared_ptr<gtkpp::Window> createMainWindow(std::shared_ptr<gtkpp::Application> app) {
|
std::shared_ptr<gtkpp::Window> createMainWindow() {
|
||||||
auto settings = Settings::instance();
|
auto settings = Settings::instance();
|
||||||
if(settings.user().token.empty()) {
|
if(settings.user().token.empty()) {
|
||||||
return std::make_shared<LoginWindow>(app);
|
return std::make_shared<LoginWindow>();
|
||||||
} else {
|
} else {
|
||||||
return std::make_shared<MainWindow>(app);
|
return std::make_shared<MainWindow>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -20,13 +21,13 @@ int main(int argc, char* argv[]) {
|
|||||||
|
|
||||||
g_resources_register(g_resource_load("resources.gresource", nullptr));
|
g_resources_register(g_resource_load("resources.gresource", nullptr));
|
||||||
|
|
||||||
auto app = std::make_shared<gtkpp::Application>("pro.aliencat.autocat");
|
auto app = App::instance(); //std::make_shared<gtkpp::Application>("pro.aliencat.autocat");
|
||||||
|
|
||||||
app->onActivate([&](){
|
app.onActivate([&](){
|
||||||
auto window = createMainWindow(app);
|
auto window = createMainWindow();
|
||||||
app->addWindow(window);
|
app.addWindow(window);
|
||||||
window->show();
|
window->show();
|
||||||
});
|
});
|
||||||
|
|
||||||
return app->run(argc, argv);
|
return app.run(argc, argv);
|
||||||
}
|
}
|
||||||
|
|||||||
5
models/Engine.cpp
Normal file
5
models/Engine.cpp
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
//
|
||||||
|
// Created by selim on 06.11.22.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "Engine.h"
|
||||||
21
models/Engine.h
Normal file
21
models/Engine.h
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
//
|
||||||
|
// Created by selim on 06.11.22.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef AUTOCAT_GNOME_ENGINE_H
|
||||||
|
#define AUTOCAT_GNOME_ENGINE_H
|
||||||
|
|
||||||
|
#include <nlohmann/json.hpp>
|
||||||
|
|
||||||
|
class Engine {
|
||||||
|
public:
|
||||||
|
std::string number;
|
||||||
|
int volume;
|
||||||
|
float powerHp;
|
||||||
|
float powerKw;
|
||||||
|
std::string fuelType;
|
||||||
|
|
||||||
|
NLOHMANN_DEFINE_TYPE_INTRUSIVE(Engine, number, volume, powerHp, powerKw, fuelType)
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //AUTOCAT_GNOME_ENGINE_H
|
||||||
75
models/JsonOptional.h
Normal file
75
models/JsonOptional.h
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
//
|
||||||
|
// Created by selim on 06.11.22.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef AUTOCAT_GNOME_JSONOPTIONAL_H
|
||||||
|
#define AUTOCAT_GNOME_JSONOPTIONAL_H
|
||||||
|
|
||||||
|
#include <nlohmann/json.hpp>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
namespace nlohmann {
|
||||||
|
|
||||||
|
template<class J, class T>
|
||||||
|
void optional_to_json(J& j, const char* name, const std::optional<T>& value)
|
||||||
|
{
|
||||||
|
if (value)
|
||||||
|
{
|
||||||
|
j[name] = *value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class J, class T>
|
||||||
|
void optional_from_json(const J& j, const char* name, std::optional<T>& value)
|
||||||
|
{
|
||||||
|
const auto it = j.find(name);
|
||||||
|
if (it != j.end())
|
||||||
|
{
|
||||||
|
if(j.at(name).is_null()) {
|
||||||
|
value = std::nullopt;
|
||||||
|
} else {
|
||||||
|
value = it->template get<T>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
value = std::nullopt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename>
|
||||||
|
constexpr bool is_optional = false;
|
||||||
|
template <typename T>
|
||||||
|
constexpr bool is_optional<std::optional<T>> = true;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void extended_to_json(const char *key, nlohmann::json &j, const T &value) {
|
||||||
|
if constexpr (is_optional<T>)
|
||||||
|
optional_to_json(j, key, value);
|
||||||
|
else
|
||||||
|
j[key] = value;
|
||||||
|
}
|
||||||
|
template <typename T>
|
||||||
|
void extended_from_json(const char *key, const nlohmann::json &j, T &value) {
|
||||||
|
//std::cout << "parsing key " << key << std::endl;
|
||||||
|
if constexpr (is_optional<T>) {
|
||||||
|
optional_from_json(j, key, value);
|
||||||
|
} else {
|
||||||
|
j.at(key).get_to(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define EXTEND_JSON_TO(v1) extended_to_json(#v1, nlohmann_json_j, nlohmann_json_t.v1);
|
||||||
|
#define EXTEND_JSON_FROM(v1) extended_from_json(#v1, nlohmann_json_j, nlohmann_json_t.v1);
|
||||||
|
|
||||||
|
#define NLOHMANN_JSONIFY_ALL_THINGS(Type, ...) \
|
||||||
|
friend void to_json(nlohmann::json &nlohmann_json_j, const Type &nlohmann_json_t) { \
|
||||||
|
NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(EXTEND_JSON_TO, __VA_ARGS__)) \
|
||||||
|
} \
|
||||||
|
friend void from_json(const nlohmann::json &nlohmann_json_j, Type &nlohmann_json_t) { \
|
||||||
|
NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(EXTEND_JSON_FROM, __VA_ARGS__)) \
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //AUTOCAT_GNOME_JSONOPTIONAL_H
|
||||||
91
models/Vehicle.cpp
Normal file
91
models/Vehicle.cpp
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
//
|
||||||
|
// Created by selim on 03.10.22.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <fmt/core.h>
|
||||||
|
#include "Vehicle.h"
|
||||||
|
|
||||||
|
std::string Vehicle::createTableQuery() {
|
||||||
|
return R"(
|
||||||
|
CREATE TABLE IF NOT EXISTS vehicles(
|
||||||
|
number TEXT NOT NULL PRIMARY KEY,
|
||||||
|
currentNumber TEXT,
|
||||||
|
color TEXT,
|
||||||
|
category TEXT,
|
||||||
|
year INT,
|
||||||
|
addedDate REAL,
|
||||||
|
updatedDate REAL,
|
||||||
|
vin1 TEXT,
|
||||||
|
vin2 TEXT,
|
||||||
|
sts TEXT,
|
||||||
|
pts TEXT,
|
||||||
|
addedBy TEXT,
|
||||||
|
engineNumber TEXT,
|
||||||
|
engineVolume INT,
|
||||||
|
enginePowerHp REAL,
|
||||||
|
enginePowerKw REAL,
|
||||||
|
engineFuelType TEXT
|
||||||
|
);
|
||||||
|
)";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Vehicle::insertQuery() {
|
||||||
|
return fmt::format(R"(
|
||||||
|
INSERT INTO vehicles(number,
|
||||||
|
currentNumber,
|
||||||
|
color,
|
||||||
|
category,
|
||||||
|
year,
|
||||||
|
addedDate,
|
||||||
|
updatedDate,
|
||||||
|
vin1, vin2,
|
||||||
|
sts, pts,
|
||||||
|
addedBy,
|
||||||
|
engineNumber,
|
||||||
|
engineVolume,
|
||||||
|
enginePowerHp,
|
||||||
|
enginePowerKw,
|
||||||
|
engineFuelType)
|
||||||
|
VALUES('{}', '{}', '{}', '{}', '{}', '{}', '{}', '{}', '{}', '{}', '{}', '{}', '{}', '{}', '{}', '{}', '{}')
|
||||||
|
)",
|
||||||
|
number,
|
||||||
|
currentNumber,
|
||||||
|
color.value_or("NULL"),
|
||||||
|
category,
|
||||||
|
year,
|
||||||
|
addedDate,
|
||||||
|
updatedDate,
|
||||||
|
vin1,
|
||||||
|
vin2.value_or("NULL"),
|
||||||
|
sts, pts,
|
||||||
|
addedBy,
|
||||||
|
engine.number,
|
||||||
|
engine.volume,
|
||||||
|
engine.powerHp,
|
||||||
|
engine.powerKw,
|
||||||
|
engine.fuelType);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Vehicle::selectQuery() {
|
||||||
|
return "SELECT * FROM vehicles";
|
||||||
|
}
|
||||||
|
|
||||||
|
Vehicle::Vehicle(sqlite3_stmt *stmt) {
|
||||||
|
number = readString(stmt, 0);
|
||||||
|
currentNumber = readString(stmt, 1);
|
||||||
|
color = readStringOptional(stmt, 2);
|
||||||
|
category = readString(stmt, 3);
|
||||||
|
year = readInt(stmt, 4);
|
||||||
|
addedDate = readDouble(stmt, 5);
|
||||||
|
updatedDate = readDouble(stmt, 6);
|
||||||
|
vin1 = readString(stmt, 7);
|
||||||
|
vin2 = readStringOptional(stmt, 8);
|
||||||
|
sts = readString(stmt, 9);
|
||||||
|
pts = readString(stmt, 10);
|
||||||
|
addedBy = readString(stmt, 11);
|
||||||
|
engine.number = readString(stmt, 12);
|
||||||
|
engine.volume = readInt(stmt, 13);
|
||||||
|
engine.powerHp = readDouble(stmt, 14);
|
||||||
|
engine.powerKw = readDouble(stmt, 15);
|
||||||
|
engine.fuelType = readString(stmt, 16);
|
||||||
|
}
|
||||||
42
models/Vehicle.h
Normal file
42
models/Vehicle.h
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
//
|
||||||
|
// Created by selim on 03.10.22.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef AUTOCAT_GNOME_VEHICLE_H
|
||||||
|
#define AUTOCAT_GNOME_VEHICLE_H
|
||||||
|
|
||||||
|
#include "../services/IDBEntity.h"
|
||||||
|
#include "Engine.h"
|
||||||
|
#include "JsonOptional.h"
|
||||||
|
|
||||||
|
#include <optional>
|
||||||
|
#include <sqlite3.h>
|
||||||
|
|
||||||
|
class Vehicle: public IDBEntity {
|
||||||
|
public:
|
||||||
|
std::string number;
|
||||||
|
std::string currentNumber;
|
||||||
|
std::optional<std::string> color;
|
||||||
|
std::string category;
|
||||||
|
int year;
|
||||||
|
double addedDate;
|
||||||
|
double updatedDate;
|
||||||
|
std::string vin1;
|
||||||
|
std::optional<std::string> vin2;
|
||||||
|
std::string sts;
|
||||||
|
std::string pts;
|
||||||
|
std::string addedBy;
|
||||||
|
Engine engine;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Vehicle() = default;
|
||||||
|
explicit Vehicle(sqlite3_stmt* stmt);
|
||||||
|
static std::string createTableQuery();
|
||||||
|
static std::string selectQuery();
|
||||||
|
std::string insertQuery() override;
|
||||||
|
|
||||||
|
NLOHMANN_JSONIFY_ALL_THINGS(Vehicle, number, currentNumber, color, category, year, addedDate, updatedDate, vin1, vin2, sts, pts, addedBy, engine)
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //AUTOCAT_GNOME_VEHICLE_H
|
||||||
9
models/VehiclesListFactory.cpp
Normal file
9
models/VehiclesListFactory.cpp
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
//
|
||||||
|
// Created by selim on 13.11.22.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "VehiclesListFactory.h"
|
||||||
|
|
||||||
|
VehiclesListFactory::VehiclesListFactory() {
|
||||||
|
|
||||||
|
}
|
||||||
16
models/VehiclesListFactory.h
Normal file
16
models/VehiclesListFactory.h
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
//
|
||||||
|
// Created by selim on 13.11.22.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef AUTOCAT_GNOME_VEHICLESLISTFACTORY_H
|
||||||
|
#define AUTOCAT_GNOME_VEHICLESLISTFACTORY_H
|
||||||
|
|
||||||
|
#include "../gtkpp/ListItemFactory.h"
|
||||||
|
|
||||||
|
class VehiclesListFactory: gtkpp::ListItemFactory {
|
||||||
|
public:
|
||||||
|
VehiclesListFactory();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //AUTOCAT_GNOME_VEHICLESLISTFACTORY_H
|
||||||
@ -6,7 +6,7 @@
|
|||||||
#include "Settings.h"
|
#include "Settings.h"
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
const std::string Api::_baseUrl = "https://vps.aliencat.pro:8443/";
|
const std::string Api::_baseUrl = "http://127.0.0.1:3000/"; //"https://vps.aliencat.pro:8443/";
|
||||||
SoupSession* Api::_session = soup_session_new();
|
SoupSession* Api::_session = soup_session_new();
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
@ -36,6 +36,12 @@ cc::result<T> Api::post(const std::string &method, const nlohmann::json& params)
|
|||||||
std::string url = _baseUrl + method;
|
std::string url = _baseUrl + method;
|
||||||
auto msg = soup_message_new(SOUP_METHOD_POST, url.c_str());
|
auto msg = soup_message_new(SOUP_METHOD_POST, url.c_str());
|
||||||
|
|
||||||
|
auto token = Settings::instance().user().token;
|
||||||
|
if(!token.empty()) {
|
||||||
|
auto authHeader = "Bearer " + token;
|
||||||
|
soup_message_headers_append(msg->request_headers, "Authorization", authHeader.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
auto promise = new cc::result_promise<T>();
|
auto promise = new cc::result_promise<T>();
|
||||||
auto result = promise->get_result();
|
auto result = promise->get_result();
|
||||||
|
|
||||||
@ -67,3 +73,12 @@ cc::result<User> Api::login(std::string email, std::string password) {
|
|||||||
|
|
||||||
co_return user;
|
co_return user;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cc::result<Vehicle> Api::check(const std::string& number, bool force) {
|
||||||
|
nlohmann::json params = {
|
||||||
|
{ "number", number },
|
||||||
|
{ "forceUpdate", force }
|
||||||
|
};
|
||||||
|
|
||||||
|
return post<Vehicle>("vehicles/check", params);
|
||||||
|
}
|
||||||
|
|||||||
@ -11,6 +11,7 @@
|
|||||||
#include <concurrencpp/concurrencpp.h>
|
#include <concurrencpp/concurrencpp.h>
|
||||||
|
|
||||||
#include "../models/User.h"
|
#include "../models/User.h"
|
||||||
|
#include "../models/Vehicle.h"
|
||||||
#include "../coro/Coro.h"
|
#include "../coro/Coro.h"
|
||||||
|
|
||||||
namespace cc = concurrencpp;
|
namespace cc = concurrencpp;
|
||||||
@ -26,6 +27,7 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
static cc::result<User> login(std::string email, std::string password);
|
static cc::result<User> login(std::string email, std::string password);
|
||||||
|
static cc::result<Vehicle> check(const std::string& number, bool force = false);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
41
services/IDBEntity.cpp
Normal file
41
services/IDBEntity.cpp
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
//
|
||||||
|
// Created by selim on 09.11.22.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "IDBEntity.h"
|
||||||
|
|
||||||
|
std::string IDBEntity::readString(sqlite3_stmt *stmt, int column) {
|
||||||
|
return { reinterpret_cast<const char*>(sqlite3_column_text(stmt, column)) };
|
||||||
|
}
|
||||||
|
|
||||||
|
int IDBEntity::readInt(sqlite3_stmt *stmt, int column) {
|
||||||
|
return sqlite3_column_int(stmt, column);
|
||||||
|
}
|
||||||
|
|
||||||
|
double IDBEntity::readDouble(sqlite3_stmt *stmt, int column) {
|
||||||
|
return sqlite3_column_double(stmt, column);
|
||||||
|
}
|
||||||
|
|
||||||
|
StringOptional IDBEntity::readStringOptional(sqlite3_stmt *stmt, int column) {
|
||||||
|
if(sqlite3_column_type(stmt, column) == SQLITE_NULL) {
|
||||||
|
return std::nullopt;
|
||||||
|
} else {
|
||||||
|
return readString(stmt, column);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
IntOptional IDBEntity::readIntOptional(sqlite3_stmt *stmt, int column) {
|
||||||
|
if(sqlite3_column_type(stmt, column) == SQLITE_NULL) {
|
||||||
|
return std::nullopt;
|
||||||
|
} else {
|
||||||
|
return readInt(stmt, column);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DoubleOptional IDBEntity::readDoubleOptional(sqlite3_stmt *stmt, int column) {
|
||||||
|
if(sqlite3_column_type(stmt, column) == SQLITE_NULL) {
|
||||||
|
return std::nullopt;
|
||||||
|
} else {
|
||||||
|
return readDouble(stmt, column);
|
||||||
|
}
|
||||||
|
}
|
||||||
31
services/IDBEntity.h
Normal file
31
services/IDBEntity.h
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
//
|
||||||
|
// Created by selim on 06.11.22.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef AUTOCAT_GNOME_IDBENTITY_H
|
||||||
|
#define AUTOCAT_GNOME_IDBENTITY_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <optional>
|
||||||
|
#include <variant>
|
||||||
|
#include <vector>
|
||||||
|
#include <sqlite3.h>
|
||||||
|
|
||||||
|
using StringOptional = std::optional<std::string>;
|
||||||
|
using IntOptional = std::optional<int>;
|
||||||
|
using DoubleOptional = std::optional<double>;
|
||||||
|
|
||||||
|
struct IDBEntity {
|
||||||
|
public:
|
||||||
|
virtual std::string insertQuery() = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
static std::string readString(sqlite3_stmt* stmt, int column);
|
||||||
|
static int readInt(sqlite3_stmt* stmt, int column);
|
||||||
|
static double readDouble(sqlite3_stmt* stmt, int column);
|
||||||
|
static StringOptional readStringOptional(sqlite3_stmt* stmt, int column);
|
||||||
|
static IntOptional readIntOptional(sqlite3_stmt* stmt, int column);
|
||||||
|
static DoubleOptional readDoubleOptional(sqlite3_stmt* stmt, int column);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //AUTOCAT_GNOME_IDBENTITY_H
|
||||||
@ -9,17 +9,15 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
namespace fs = std::filesystem;
|
fs::path Settings::getDataPath() {
|
||||||
|
|
||||||
fs::path getDataPath() {
|
|
||||||
auto dataDir = std::getenv("XDG_DATA_HOME");
|
auto dataDir = std::getenv("XDG_DATA_HOME");
|
||||||
if(dataDir) {
|
if(dataDir) {
|
||||||
return fs::path(dataDir);
|
return fs::path(dataDir) / "autocat";
|
||||||
}
|
}
|
||||||
|
|
||||||
auto home = std::getenv("HOME");
|
auto home = std::getenv("HOME");
|
||||||
if(home) {
|
if(home) {
|
||||||
return fs::path(home) / ".local" / "share";
|
return fs::path(home) / ".local" / "share" / "autocat";
|
||||||
}
|
}
|
||||||
|
|
||||||
throw std::runtime_error("Failed to find data home directory");
|
throw std::runtime_error("Failed to find data home directory");
|
||||||
@ -46,7 +44,7 @@ Settings Settings::instance() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Settings::Settings() {
|
Settings::Settings() {
|
||||||
_dataPath = getDataPath() / "autocat";
|
_dataPath = getDataPath();
|
||||||
if(!fs::exists(_dataPath)) {
|
if(!fs::exists(_dataPath)) {
|
||||||
fs::create_directories(_dataPath);
|
fs::create_directories(_dataPath);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,6 +8,8 @@
|
|||||||
#include "../models/User.h"
|
#include "../models/User.h"
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
|
||||||
|
namespace fs = std::filesystem;
|
||||||
|
|
||||||
class Settings {
|
class Settings {
|
||||||
private:
|
private:
|
||||||
std::filesystem::path _dataPath;
|
std::filesystem::path _dataPath;
|
||||||
@ -15,6 +17,7 @@ private:
|
|||||||
public:
|
public:
|
||||||
static Settings instance();
|
static Settings instance();
|
||||||
Settings();
|
Settings();
|
||||||
|
static fs::path getDataPath();
|
||||||
|
|
||||||
[[nodiscard]] User user() const;
|
[[nodiscard]] User user() const;
|
||||||
void setUser(const User& user);
|
void setUser(const User& user);
|
||||||
|
|||||||
42
services/Storage.cpp
Normal file
42
services/Storage.cpp
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
//
|
||||||
|
// Created by selim on 25.10.22.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "Storage.h"
|
||||||
|
#include "Settings.h"
|
||||||
|
|
||||||
|
#include <fmt/core.h>
|
||||||
|
|
||||||
|
Storage Storage::instance() {
|
||||||
|
static Storage instance;
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
Storage::Storage(): _sqlite(nullptr) {
|
||||||
|
auto path = Settings::getDataPath() / "vehicles.sqlite";
|
||||||
|
int result = sqlite3_open(path.c_str(), &_sqlite);
|
||||||
|
if(result != SQLITE_OK) {
|
||||||
|
throw std::runtime_error(sqlite3_errmsg(_sqlite));
|
||||||
|
}
|
||||||
|
|
||||||
|
executeQuery(Vehicle::createTableQuery());
|
||||||
|
}
|
||||||
|
|
||||||
|
Storage::~Storage() {
|
||||||
|
if(_sqlite) {
|
||||||
|
sqlite3_close(_sqlite);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Storage::executeQuery(const std::string& query) {
|
||||||
|
char* error = nullptr;
|
||||||
|
sqlite3_exec(_sqlite, query.c_str(), nullptr, nullptr, &error);
|
||||||
|
if(error) {
|
||||||
|
throw std::runtime_error(error);
|
||||||
|
// TODO: error buffer should be deallocated with sqlite3_free()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Storage::insert(IDBEntity *entity) {
|
||||||
|
executeQuery(entity->insertQuery());
|
||||||
|
}
|
||||||
64
services/Storage.h
Normal file
64
services/Storage.h
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
//
|
||||||
|
// Created by selim on 25.10.22.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef AUTOCAT_GNOME_STORAGE_H
|
||||||
|
#define AUTOCAT_GNOME_STORAGE_H
|
||||||
|
|
||||||
|
#include "../models/Vehicle.h"
|
||||||
|
#include "IDBEntity.h"
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
|
#include <sqlite3.h>
|
||||||
|
|
||||||
|
class Storage {
|
||||||
|
private:
|
||||||
|
sqlite3* _sqlite;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void executeQuery(const std::string& query);
|
||||||
|
|
||||||
|
public:
|
||||||
|
Storage();
|
||||||
|
~Storage();
|
||||||
|
static Storage instance();
|
||||||
|
void insert(IDBEntity* entity);
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
std::vector<T> select() {
|
||||||
|
auto sql = T::selectQuery();
|
||||||
|
sqlite3_stmt* stmt = nullptr;
|
||||||
|
std::vector<T> rows;
|
||||||
|
|
||||||
|
int result = sqlite3_prepare_v2(_sqlite, sql.c_str(), sql.size(), &stmt, nullptr);
|
||||||
|
if(result != SQLITE_OK) {
|
||||||
|
throw std::runtime_error(sqlite3_errmsg(_sqlite));
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
result = sqlite3_step(stmt);
|
||||||
|
switch(result) {
|
||||||
|
case SQLITE_BUSY:
|
||||||
|
// TODO: Rollback transaction
|
||||||
|
break;
|
||||||
|
case SQLITE_ERROR:
|
||||||
|
throw std::runtime_error(sqlite3_errmsg(_sqlite));
|
||||||
|
case SQLITE_ROW:
|
||||||
|
rows.emplace_back(stmt);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while (result == SQLITE_ROW);
|
||||||
|
|
||||||
|
result = sqlite3_finalize(stmt);
|
||||||
|
if(result != SQLITE_OK) {
|
||||||
|
throw std::runtime_error(sqlite3_errmsg(_sqlite));
|
||||||
|
}
|
||||||
|
|
||||||
|
return rows;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //AUTOCAT_GNOME_STORAGE_H
|
||||||
Loading…
Reference in New Issue
Block a user