#include "MainWindow.hpp" #include #include #include #include #include #include #include namespace fs = std::filesystem; MainWindow::MainWindow() : m_MainLayout(Gtk::ORIENTATION_VERTICAL, 0), m_VBoxBackup(Gtk::ORIENTATION_VERTICAL, 15), m_LabelBackupInstruction("Select what to backup:"), m_CheckThemesBackup("GTK Themes (~/.themes)"), m_CheckIconsBackup("Icons (~/.icons)"), m_CheckDconfBackup("GNOME Settings (dconf dump)"), m_ButtonBackup("Start Backup"), m_VBoxRestore(Gtk::ORIENTATION_VERTICAL, 15), m_LabelRestoreInstruction("Select what to restore:"), m_CheckThemesRestore("GTK Themes"), m_CheckIconsRestore("Icons"), m_CheckDconfRestore("GNOME Settings"), m_ButtonRestore("Start Restore") { // --- Force Dark Theme --- auto settings = Gtk::Settings::get_default(); if (settings) { settings->property_gtk_application_prefer_dark_theme() = true; } set_default_size(550, 450); set_border_width(0); // Removing window border to let layout handle it // --- HeaderBar Setup (Modern GNOME look) --- m_HeaderBar.set_title("Gnome-Vault"); m_HeaderBar.set_subtitle("System State Manager"); m_HeaderBar.set_show_close_button(true); set_titlebar(m_HeaderBar); // Allow markup in the instruction labels m_LabelBackupInstruction.set_use_markup(true); m_LabelBackupInstruction.set_halign(Gtk::ALIGN_START); m_LabelRestoreInstruction.set_use_markup(true); m_LabelRestoreInstruction.set_halign(Gtk::ALIGN_START); // --- Backup Page Setup --- m_VBoxBackup.set_border_width(20); m_VBoxBackup.pack_start(m_LabelBackupInstruction, Gtk::PACK_SHRINK); m_VBoxBackup.pack_start(m_CheckThemesBackup, Gtk::PACK_SHRINK); m_VBoxBackup.pack_start(m_CheckIconsBackup, Gtk::PACK_SHRINK); m_VBoxBackup.pack_start(m_CheckDconfBackup, Gtk::PACK_SHRINK); m_CheckThemesBackup.set_active(true); // Make the button chunkier m_ButtonBackup.set_size_request(-1, 45); m_ButtonBackup.signal_clicked().connect(sigc::mem_fun(*this, &MainWindow::on_button_backup_clicked)); m_VBoxBackup.pack_end(m_ButtonBackup, Gtk::PACK_SHRINK); // --- Restore Page Setup --- m_VBoxRestore.set_border_width(20); m_VBoxRestore.pack_start(m_LabelRestoreInstruction, Gtk::PACK_SHRINK); m_VBoxRestore.pack_start(m_CheckThemesRestore, Gtk::PACK_SHRINK); m_VBoxRestore.pack_start(m_CheckIconsRestore, Gtk::PACK_SHRINK); m_VBoxRestore.pack_start(m_CheckDconfRestore, Gtk::PACK_SHRINK); m_ButtonRestore.set_size_request(-1, 45); m_ButtonRestore.signal_clicked().connect(sigc::mem_fun(*this, &MainWindow::on_button_restore_clicked)); m_VBoxRestore.pack_end(m_ButtonRestore, Gtk::PACK_SHRINK); // --- Notebook (Tabs) Setup --- m_Notebook.append_page(m_VBoxBackup, "Backup"); m_Notebook.append_page(m_VBoxRestore, "Restore"); // --- Status Label Setup --- m_StatusLabel.set_text("Ready."); m_StatusLabel.set_halign(Gtk::ALIGN_START); m_StatusLabel.set_margin_top(10); m_StatusLabel.set_margin_bottom(10); m_StatusLabel.set_margin_start(10); // --- Main Layout Assembly --- m_MainLayout.pack_start(m_Notebook, Gtk::PACK_EXPAND_WIDGET); m_MainLayout.pack_end(m_StatusLabel, Gtk::PACK_SHRINK); add(m_MainLayout); show_all_children(); } MainWindow::~MainWindow() {} bool MainWindow::create_tar_archive(const std::string& source_dir, const std::string& out_filename) { struct archive *a; struct archive *disk; struct archive_entry *entry; char buff[8192]; int len; int fd; a = archive_write_new(); archive_write_add_filter_gzip(a); archive_write_set_format_pax_restricted(a); archive_write_open_filename(a, out_filename.c_str()); disk = archive_read_disk_new(); archive_read_disk_set_standard_lookup(disk); for (const auto& dirEntry : fs::recursive_directory_iterator(source_dir)) { std::string path = dirEntry.path().string(); entry = archive_entry_new(); archive_entry_copy_pathname(entry, path.c_str()); archive_read_disk_entry_from_file(disk, entry, -1, nullptr); archive_write_header(a, entry); if (fs::is_regular_file(dirEntry)) { fd = ::open(path.c_str(), O_RDONLY); if (fd >= 0) { len = ::read(fd, buff, sizeof(buff)); while (len > 0) { archive_write_data(a, buff, len); len = ::read(fd, buff, sizeof(buff)); } ::close(fd); } } archive_entry_free(entry); } archive_read_free(disk); archive_write_close(a); archive_write_free(a); return true; } void MainWindow::on_button_backup_clicked() { m_StatusLabel.set_text("Initializing Backup Sequence..."); // Keep the cout for the terminal debugger std::cout << ">>> Initializing Backup Sequence..." << std::endl; std::string home_dir = getenv("HOME"); if (m_CheckThemesBackup.get_active()) { std::string target = home_dir + "/.themes"; std::string out = home_dir + "/gnome_themes_backup.tar.gz"; if (fs::exists(target)) { m_StatusLabel.set_text("Packing Themes into archive..."); create_tar_archive(target, out); m_StatusLabel.set_text("Success: Packed ~/.themes into gnome_themes_backup.tar.gz"); } else { m_StatusLabel.set_text("Warning: ~/.themes doesn't exist. Skipped."); } } if (m_CheckIconsBackup.get_active()) std::cout << " [x] Queuing Icons (TODO)..." << std::endl; if (m_CheckDconfBackup.get_active()) std::cout << " [x] Queuing Dconf (TODO)..." << std::endl; } void MainWindow::on_button_restore_clicked() { m_StatusLabel.set_text("Initializing Restore Sequence..."); std::cout << ">>> Initializing Restore Sequence..." << std::endl; if (m_CheckThemesRestore.get_active()) std::cout << " [x] Preparing to overwrite Themes..." << std::endl; if (m_CheckIconsRestore.get_active()) std::cout << " [x] Preparing to overwrite Icons..." << std::endl; if (m_CheckDconfRestore.get_active()) std::cout << " [x] Preparing to inject Dconf..." << std::endl; }