diff --git a/Gtkmm3/gtk138_cfgconverter/.vscode/settings.json b/Gtkmm3/gtk138_cfgconverter/.vscode/settings.json new file mode 100644 index 0000000..da712a3 --- /dev/null +++ b/Gtkmm3/gtk138_cfgconverter/.vscode/settings.json @@ -0,0 +1,6 @@ +{ + "C_Cpp.default.configurationProvider": "ms-vscode.cmake-tools", + "files.associations": { + "iostream": "cpp" + } +} \ No newline at end of file diff --git a/Gtkmm3/gtk138_cfgconverter/CMakeLists.txt b/Gtkmm3/gtk138_cfgconverter/CMakeLists.txt new file mode 100644 index 0000000..39336d6 --- /dev/null +++ b/Gtkmm3/gtk138_cfgconverter/CMakeLists.txt @@ -0,0 +1,72 @@ +set(CMAKE_CXX_STANDARD 17) +cmake_minimum_required(VERSION 3.0.0) +project(gtk138_cfgconvert VERSION 1.0.0) + +list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/../../GCR_CMake/macros) +include(GlibCompileResourcesSupport) + +include(CTest) +enable_testing() + +set(CPACK_PROJECT_NAME ${PROJECT_NAME}) +set(CPACK_PROJECT_VERSION ${PROJECT_VERSION}) + +include(CPack) +include_directories(.) +include_directories(..) + +#Find PkgConfig to use gtkmm3 +find_package (PkgConfig REQUIRED) +pkg_check_modules (GTKMM3 REQUIRED gtkmm-3.0) +include_directories (${GTKMM3_INCLUDE_DIRS}) +link_directories (${GTKMM3_LIBRARY_DIRS}) + +#Find Gettext +find_package (Gettext REQUIRED) +set(PO_DIR ${CMAKE_BINARY_DIR}/po/zh_CN/LC_MESSAGES) + +#Source files +set(SOURCE_FILE src/main.cc src/CfgConvert.cc ../cfgfile2/cfgfile.cc) + +#Compile Resource + +# set(RESOURCE_LIST +# text_menu.xml) + +# compile_gresources(RESOURCE_FILE +# XML_OUT +# TYPE EMBED_C +# RESOURCES ${RESOURCE_LIST} +# PREFIX "/org/gtk/daleclack" +# SOURCE_DIR ${PROJECT_SOURCE_DIR}/res) + +# Add a custom target to the makefile. Now make builds our resource file. +# It depends on the output RESOURCE_FILE. + +# add_custom_target(resource ALL DEPENDS ${RESOURCE_FILE}) + +#For win32 platform,use rc resource and .ico icon +if(WIN32) + SET(CMAKE_RC_COMPILER x86_64-w64-mingw32-windres) + set(app_WINRC ../icon.rc) + set_property(SOURCE ../icon.rc APPEND PROPERTY + OBJECT_DEPENDS ${PROJECT_SOURCE_DIR}/../icon.ico + ) + add_executable(${PROJECT_NAME} WIN32 ${app_WINRC} ${SOURCE_FILE}) + add_custom_command( TARGET ${PROJECT_NAME} + COMMAND echo * > ${CMAKE_BINARY_DIR}/.gitignore + COMMAND echo **/* > ${CMAKE_BINARY_DIR}/.hgignore) +else() + add_executable(${PROJECT_NAME} ${SOURCE_FILE}) + add_custom_command( TARGET ${PROJECT_NAME} + COMMAND echo \"*\" > ${CMAKE_BINARY_DIR}/.gitignore + COMMAND echo \"**/*\" > ${CMAKE_BINARY_DIR}/.hgignore) +endif(WIN32) + +#Add command to generate .gitignore and .mo files +# add_custom_command( TARGET ${PROJECT_NAME} +# COMMAND mkdir -p ${PO_DIR} +# COMMAND ${GETTEXT_MSGFMT_EXECUTABLE} ${CMAKE_SOURCE_DIR}/po/zh_CN.po -o ${PO_DIR}/${PROJECT_NAME}.mo) + +SET (CMAKE_EXTRA_CXX_FLAGS ${GTKMM3_CFLAGS_OTHER}) +target_link_libraries (${PROJECT_NAME} ${GTKMM3_LIBRARIES} -lpthread) diff --git a/Gtkmm3/gtk138_cfgconverter/src/CfgConvert.cc b/Gtkmm3/gtk138_cfgconverter/src/CfgConvert.cc new file mode 100644 index 0000000..a7877c1 --- /dev/null +++ b/Gtkmm3/gtk138_cfgconverter/src/CfgConvert.cc @@ -0,0 +1,124 @@ +#include "CfgConvert.hh" +#include +#include "../json_nlohmann/json.hpp" + +using json = nlohmann::json; + +CfgConvert::CfgConvert() + : main_box(Gtk::ORIENTATION_HORIZONTAL, 5), + btn_box(Gtk::ORIENTATION_VERTICAL, 5), + btnopen("Open cfg file"), + btnsave("Save json file") +{ + // Initalize window + set_default_size(800, 450); + set_title("Simple Config File Converter"); + set_icon_name("org.gtk.daleclack"); + + // Create List Store + m_liststore = Gtk::ListStore::create(n_columns); + cfg_view.append_column("Key", n_columns.key); + cfg_view.append_column("Value", n_columns.value); + cfg_view.set_model(m_liststore); + + // Pack Buttons + btn_box.pack_start(btnopen, Gtk::PACK_SHRINK); + btn_box.pack_start(btnsave, Gtk::PACK_SHRINK); + btn_box.set_valign(Gtk::ALIGN_CENTER); + btnopen.signal_clicked().connect(sigc::mem_fun(*this, &CfgConvert::btnopen_clicked)); + btnsave.signal_clicked().connect(sigc::mem_fun(*this, &CfgConvert::btnsave_clicked)); + + // Pack Widgets + main_box.pack_start(cfg_view); + main_box.pack_start(btn_box, Gtk::PACK_SHRINK); + add(main_box); + show_all_children(); +} + +void CfgConvert::btnsave_clicked() +{ + // Create dialog + dialog = Gtk::FileChooserNative::create("Open Config File", *this, + Gtk::FILE_CHOOSER_ACTION_SAVE, "OK", "Cancel"); + // Create filters + auto filter_any = Gtk::FileFilter::create(); + filter_any->add_pattern("*"); + filter_any->set_name("Any Config File"); + + dialog->add_filter(filter_any); + + // Link Signal and show the dialog + dialog->signal_response().connect(sigc::mem_fun(*this, &CfgConvert::dialog_response)); + dialog->show(); +} + +void CfgConvert::btnopen_clicked() +{ + // Create dialog + dialog = Gtk::FileChooserNative::create("Open Config File", *this, + Gtk::FILE_CHOOSER_ACTION_OPEN, "OK", "Cancel"); + // Create filters + auto filter_any = Gtk::FileFilter::create(); + filter_any->add_pattern("*"); + filter_any->set_name("Any Config File"); + + dialog->add_filter(filter_any); + + // Link Signal and show the dialog + dialog->signal_response().connect(sigc::mem_fun(*this, &CfgConvert::dialog_response)); + dialog->show(); +} + +void CfgConvert::dialog_response(int response) +{ + if (response == Gtk::RESPONSE_ACCEPT) + { + // Use action to execute the save and open action + auto action = dialog->get_action(); + + // Get Filename + auto file = dialog->get_file(); + auto path = file->get_path(); + std::fstream outfile; + json data; + switch (action) + { + case Gtk::FILE_CHOOSER_ACTION_OPEN: + // Read data to std::map and show + if (readCfgFile(path, config_data)) + { + treeview_init(); + } + break; + case Gtk::FILE_CHOOSER_ACTION_SAVE: + // Save data to json file + data = json(config_data); + outfile.open(path, std::ios_base::out); + if (outfile.is_open()) + { + outfile << data; + } + outfile.close(); + break; + default: + std::cout << "Error!" << std::endl; + } + file.reset(); + } + dialog.reset(); +} + +void CfgConvert::treeview_init() +{ + // Clear the data + m_liststore->clear(); + + // Append data + auto mite = config_data.begin(); + for (; mite != config_data.end(); mite++) + { + auto row = *(m_liststore->append()); + row[n_columns.key] = mite->first; + row[n_columns.value] = mite->second; + } +} diff --git a/Gtkmm3/gtk138_cfgconverter/src/CfgConvert.hh b/Gtkmm3/gtk138_cfgconverter/src/CfgConvert.hh new file mode 100644 index 0000000..b4735a8 --- /dev/null +++ b/Gtkmm3/gtk138_cfgconverter/src/CfgConvert.hh @@ -0,0 +1,44 @@ +#pragma once + +#include +#include "../cfgfile2/cfgfile.hh" + +class CfgConvert : public Gtk::ApplicationWindow +{ +public: + CfgConvert(); + +private: + // Config data + conf_map config_data; + + // Open or save dialog + Glib::RefPtr dialog; + void dialog_response(int response_id); + + // Child widgets + Gtk::Box main_box, btn_box; + Gtk::Button btnopen, btnsave; + + // Treeview + class ModelColumns : public Gtk::TreeModelColumnRecord + { + public: + ModelColumns() + { + add(key); + add(value); + } + Gtk::TreeModelColumn key; + Gtk::TreeModelColumn value; + }; + + ModelColumns n_columns; + Gtk::TreeView cfg_view; + Glib::RefPtr m_liststore; + void treeview_init(); + + // Signal Handlers + void btnopen_clicked(); + void btnsave_clicked(); +}; \ No newline at end of file diff --git a/Gtkmm3/gtk138_cfgconverter/src/main.cc b/Gtkmm3/gtk138_cfgconverter/src/main.cc new file mode 100644 index 0000000..54a4586 --- /dev/null +++ b/Gtkmm3/gtk138_cfgconverter/src/main.cc @@ -0,0 +1,8 @@ +#include "CfgConvert.hh" + +int main(int argc, char **argv){ + // Create a application + auto app = Gtk::Application::create(argc, argv, "org.gtk.daleclack"); + CfgConvert cfgwin; + return app->run(cfgwin); +}