Skip to content
API Documentation
BastionGuard™
MainWindow Class Reference

#include <MainWindow.hpp>

Inheritance diagram for MainWindow:

Public Member Functions

 MainWindow ()
 ~MainWindow () override=default
void showDashboard ()
void open_settings_window ()
 MainWindow ()
void create_snapshot ()
void delete_selected ()
void mark_selected ()
void browse_selected ()
void view_snapshot_log (bool view_restore_log)
void show_settings ()
 MainWindow ()
 ~MainWindow () override
 MainWindow ()
 ~MainWindow () override

Protected Member Functions

bool on_close_request () override

Private Types

enum class  ThemeMode { Dark , Light }
enum class  WizardStep { Source , Destination , Scan , Recover }

Private Member Functions

void build_headerbar ()
void build_sidebar (ClamdConfig &clamdConfig)
void activate_sidebar_button (Gtk::Button *btn)
void minimize ()
void build_headerbar ()
bool load_theme_preference ()
void save_theme_preference (bool use_dark)
string load_language_preference ()
void save_language_preference (string lang_code)
void apply_language_env (string lang_code)
void on_language_changed ()
void restart_application ()
void load_css (bool use_dark=false)
void apply_theme (bool use_dark)
void update_theme_buttons ()
void init_sidebar ()
Gtk.Button make_nav_btn (string icon, string label, string page)
Gtk.Button make_theme_btn (string icon, string label)
void activate_nav (Gtk.Button btn, string page)
void show_snapshots_page ()
bool page_requires_expanded_window (string page)
void remember_compact_window_size ()
void resize_main_window (int width, int height)
void apply_window_mode_for_page (string page)
void set_dynamic_page (string name, ref Gtk.Widget? slot, Gtk.Widget widget)
void open_backup_flow ()
void open_delete_flow ()
void open_restore_flow ()
void open_rsync_log_page (string log_file)
void init_settings_page ()
void init_wizard_page ()
void init_about_page ()
void init_content ()
void init_snapshots_page ()
Gtk.Box make_card (bool hexpand)
Gtk.Button make_action_btn (string icon, string label, bool primary, bool danger, string css_class="")
bool init_delayed ()
bool refresh_all ()
bool on_close_request ()
void btn_restore_clicked ()
bool check_if_deletion_running ()
void restore ()
void btn_settings_clicked ()
void btn_wizard_clicked ()
void settings_changed (bool btrfs_mode_prev)
void btn_about_clicked ()
void ui_sensitive (bool enable)
void update_statusbar ()
Gtk.Image themed_icon (string icon_name, int size)
void reload_themed_icons ()
void build_headerbar ()
void build_sidebar ()
void build_dashboard ()
void build_recovery_page ()
void build_wizard ()
void build_about_page ()
void update_action_controls ()
void apply_theme (ThemeMode mode)
void apply_inline_css ()
void update_theme_buttons ()
void activate_sidebar_button (Gtk::Button *button)
void refresh_devices ()
void populate_device_lists ()
void select_source (const std::string &path, const std::string &label)
void update_source_state ()
void update_wizard_step ()
void append_log (const std::string &line)
void on_sidebar_dashboard ()
void on_sidebar_recovery ()
void on_sidebar_about ()
void on_refresh_devices ()
void on_language_changed ()
void on_open_image ()
void on_choose_destination ()
void on_use_selected_device ()
void on_dashboard_device_activated (Gtk::ListBoxRow *row)
void on_recovery_device_activated (Gtk::ListBoxRow *row)
void on_theme_dark ()
void on_theme_light ()
void on_wizard_back ()
void on_wizard_next ()
void on_scan_now ()
void on_recover_now ()
void on_launch_elevated ()
void on_scan_progress (const ScanProgress &progress)
void on_scan_completed (const ScanReport &report)
void on_recovery_completed (const RecoveryResult &result)
void populate_scan_results (const ScanReport &report)
void update_selected_results_state ()
std::vector< size_t > selected_result_indices () const
void set_all_results_selected (bool selected)
void minimize_window ()
void hide_window ()
void buildHeaderBar ()
void buildSidebar ()
Gtk::Button * makeSidebarButton (const std::string &iconPath, const std::string &label, const std::string &pageName)
void activateSidebarButton (Gtk::Button *btn)
void loadTheme (bool dark)
void applyTheme (bool dark)
void saveConfig ()
void loadConfig ()
void applyLanguage (const std::string &lang)
void showLanguageDialog ()
void onDaemonConnected ()
void onDaemonDisconnected ()
void onNewConnection (const ConnectionInfo &info)
void onDaemonAlert (const AlertInfo &alert)
void onVerdict (Verdict v, const ConnectionInfo &info)
void setStatus (const std::string &msg)
void applyProtectionEnabled (bool enabled)
void refreshSystemIntegrationStatus ()
void startDesktopActivityMonitor ()
bool pollDesktopActivity ()
void noteDesktopActivity ()
void sendDesktopActivityState (bool active, bool force=false)
bool on_close_request () override

Static Private Member Functions

static std::string result_group_label (const ScanResult &result)
static std::string result_subgroup_label (const ScanResult &result)
static std::string human_size (uint64_t bytes)
static std::string read_language ()
static void save_language (const std::string &lang_code)
static std::string read_theme ()
static void save_theme (const std::string &theme_code)
static std::string cacheKey (const std::string &app, const std::string &host, const std::string &ip)

Private Attributes

Gtk::Box mainBox {Gtk::Orientation::HORIZONTAL}
Gtk::Stack stack_
std::vector< Gtk::Button * > sidebar_buttons_
AboutPage about_page_
DonatePage donate_page_
DashboardPage dashboard_page_
ScanPage scan_page_ {*this}
LogPage log_page_
ClamdConfig clamdConfig_
SettingsWindow * settings_window_ = nullptr
BankPage * bank_page_ = nullptr
QuarantinePage quarantine_page_
PhishingPage * phishing_page_ = nullptr
VpnPage * vpn_page_ = nullptr
UpdatePage update_page_
PrivacyPage * privacy_page_
RootGuardPage * rootguard_page_ = nullptr
AntiRansomwarePage * anti_ransomware_page_ = nullptr
USBScanPage * usb_page_ = nullptr
SambaPage * samba_page_ = nullptr
IdentityLeakPage * identity_leak_page_ = nullptr
PasswordManagerPage * password_manager_page_ = nullptr
BackupPage * backup_page_ = nullptr
Gtk::Button * dashboard_button_ = nullptr
Gtk.Box hbox_root
Gtk.Box vbox_sidebar
Gtk.Stack content_stack
Gtk.? Widget settings_page_widget = null
Gtk.? Widget wizard_page_widget = null
Gtk.? Widget about_page_widget = null
Gtk.? Widget backup_page_widget = null
Gtk.? Widget restore_page_widget = null
Gtk.? Widget delete_page_widget = null
Gtk.? Widget rsync_log_page_widget = null
Gtk.Button btn_nav_snapshots
Gtk.Button btn_nav_settings
Gtk.Button btn_nav_wizard
Gtk.Button btn_nav_about
Gtk.? Button current_nav_btn = null
Gtk.? CssProvider css_provider = null
bool dark_mode = false
Gtk.? Button btn_theme_light = null
Gtk.? Button btn_theme_dark = null
Gtk.? ComboBoxText lang_combo = null
string current_lang = "en_US"
Gtk.Button btn_backup
Gtk.Button btn_restore
Gtk.Button btn_delete_snapshot
Gtk.Button btn_browse_snapshot
Gee.ArrayList< Gtk.Image > themed_img_list = new Gee.ArrayList<Gtk.Image>()
Gee.ArrayList< string > themed_img_name = new Gee.ArrayList<string>()
Gee.ArrayList< int > themed_img_size = new Gee.ArrayList<int>()
SettingsWindow? embedded_settings = null
SetupWizardWindow? embedded_wizard = null
SnapshotListBox snapshot_list_box
Gtk.Image img_shield
Gtk.Label lbl_status_title
Gtk.Label lbl_status_detail
Gtk.Label lbl_snap_count
Gtk.Label lbl_free_space
Gtk.Label lbl_device_name
uint tmr_init
int def_width = 500
int def_height = -1
int compact_window_width = 980
int compact_window_height = 520
bool window_in_expanded_mode = false
ThemeMode current_theme_ = ThemeMode::Dark
WizardStep current_step_ = WizardStep::Source
Glib::RefPtr< Gtk::CssProvider > css_provider_
Gtk::Box main_box_ {Gtk::Orientation::HORIZONTAL, 0}
Gtk::Stack page_stack_
Gtk::Box sidebar_ {Gtk::Orientation::VERTICAL, 10}
Gtk::Box dashboard_page_ {Gtk::Orientation::VERTICAL, 16}
Gtk::Box recovery_page_ {Gtk::Orientation::VERTICAL, 16}
Gtk::Box about_page_ {Gtk::Orientation::VERTICAL, 24}
Gtk::Grid cards_grid_
Gtk::Frame card_status_
Gtk::Frame card_source_
Gtk::Frame card_update_
Gtk::Label status_card_label_
Gtk::Label source_card_label_
Gtk::Label update_card_label_
Gtk::Frame devices_frame_
Gtk::ScrolledWindow devices_scroller_
Gtk::ListBox devices_list_
Gtk::Label brand_label_
Gtk::Button btn_dashboard_
Gtk::Button btn_recovery_
Gtk::Button btn_about_
Gtk::Button btn_refresh_
Gtk::Button btn_theme_dark_
Gtk::Button btn_theme_light_
Gtk::Button * recovery_button_ = nullptr
Gtk::Button * about_button_ = nullptr
Gtk::DropDown lang_combo_
bool lang_changing_ = false
Gtk::Box recovery_header_ {Gtk::Orientation::VERTICAL, 8}
Gtk::Label recovery_title_
Gtk::Label recovery_subtitle_
Gtk::Frame wizard_frame_
Gtk::Box wizard_root_ {Gtk::Orientation::VERTICAL, 12}
Gtk::Stack wizard_stack_
Gtk::Box wizard_nav_ {Gtk::Orientation::HORIZONTAL, 8}
Gtk::Button btn_wizard_back_
Gtk::Button btn_wizard_next_
Gtk::Label wizard_notice_label_
Gtk::Box source_step_box_ {Gtk::Orientation::VERTICAL, 8}
Gtk::Label source_step_label_
Gtk::Box source_button_row_ {Gtk::Orientation::HORIZONTAL, 8}
Gtk::Button btn_open_image_
Gtk::Button btn_use_selected_device_
Gtk::Button btn_launch_elevated_
Gtk::ScrolledWindow recovery_devices_scroller_
Gtk::ListBox recovery_devices_list_
Gtk::Box destination_step_box_ {Gtk::Orientation::VERTICAL, 8}
Gtk::Label destination_step_label_
Gtk::Box destination_button_row_ {Gtk::Orientation::HORIZONTAL, 8}
Gtk::Entry entry_output_
Gtk::Button btn_choose_destination_
Gtk::Box scan_step_box_ {Gtk::Orientation::VERTICAL, 8}
Gtk::Label scan_step_label_
Gtk::ProgressBar scan_progress_bar_
Gtk::Label scan_status_label_
Gtk::Label scan_timer_label_
Gtk::Button btn_scan_now_
Gtk::Box recover_step_box_ {Gtk::Orientation::VERTICAL, 8}
Gtk::Label recover_step_label_
Gtk::Frame results_frame_
Gtk::ScrolledWindow results_scroller_
Gtk::Box results_tree_box_ {Gtk::Orientation::VERTICAL, 8}
Gtk::Label results_count_label_
Gtk::Label results_selected_label_
Gtk::Box results_actions_row_ {Gtk::Orientation::HORIZONTAL, 8}
Gtk::Button btn_results_select_all_
Gtk::Button btn_results_clear_
Gtk::Button btn_recover_now_
Gtk::ScrolledWindow log_scroller_
Gtk::TextView log_view_
Glib::RefPtr< Gtk::TextBuffer > log_buffer_
Glib::RefPtr< Gtk::FileDialog > file_dialog_
Glib::RefPtr< Gtk::FileDialog > folder_dialog_
std::vector< DeviceInfo > devices_
std::string selected_source_path_
std::string selected_source_label_
std::string output_dir_
ScanReport last_report_
std::vector< bool > result_selection_
std::vector< Gtk::CheckButton * > result_check_buttons_
ScanWorker scan_worker_
RecoveryWorker recovery_worker_
ScanProgress last_scan_progress_
sigc::connection scan_timer_connection_
std::chrono::steady_clock::time_point scan_started_at_ {}
Gtk::Box m_mainBox { Gtk::Orientation::HORIZONTAL, 0 }
Gtk::Stack m_stack
UIServer m_uiServer
ConnectionsPage m_connectionsPage { m_uiServer }
AppsPage m_appsPage
NetworkPage m_networkPage
RulesPage m_rulesPage
StatsPage m_statsPage
AboutPage m_aboutPage
SettingsPage m_settingsPage
TrayIcon m_tray
std::unique_ptr< AlertDialog > m_alertDialog
std::unique_ptr< LanguageDialog > m_langDialog
std::map< std::string, ReplyAction > m_verdictCache
std::vector< Gtk::Button * > m_sidebarButtons
Gtk::Button * m_activeButton = nullptr
Gtk::Label * m_daemonLabel = nullptr
Glib::RefPtr< Gtk::CssProvider > m_cssProvider
bool m_darkMode = false
Gtk::Button * m_btnLight = nullptr
Gtk::Button * m_btnDark = nullptr
Gtk::Statusbar m_statusbar
guint m_statusCtx = 0
uint64_t m_statAllowed = 0
uint64_t m_statDenied = 0
std::string m_configFile
std::string m_language
bool m_protectionEnabled = true
std::string m_autostartBackupFile
guint m_desktopActivityTimer = 0
bool m_desktopActiveSent = true
std::chrono::steady_clock::time_point m_lastUiActivity {}

Static Private Attributes

const string THEME_CONFIG_DIR = "/etc/bastionguard-backup"
const string THEME_CONFIG_FILE = "/etc/bastionguard-backup/theme.json"
const string LANG_CONFIG_FILE = "/etc/bastionguard-backup/language.json"
static string[] LANG_CODES
static string[] LANG_NAMES

Detailed Description

Definition at line 53 of file MainWindow.hpp.

Member Enumeration Documentation

◆ ThemeMode

enum class MainWindow::ThemeMode
strongprivate
Enumerator
Dark 
Light 

Definition at line 22 of file main_window.hpp.

22{ Dark, Light };

◆ WizardStep

enum class MainWindow::WizardStep
strongprivate
Enumerator
Source 
Destination 
Scan 
Recover 

Definition at line 23 of file main_window.hpp.

23{ Source, Destination, Scan, Recover };

Constructor & Destructor Documentation

◆ MainWindow() [1/4]

MainWindow::MainWindow ( )

Definition at line 39 of file MainWindow.cpp.

39 {
40 set_title("");
41 set_resizable(true);
42 set_default_size(1000, 680);
43 set_size_request(800, 560);
44
45 std::vector<std::string> conf_paths = {
46 "/etc/clamd/clamd.conf",
47 "/etc/clamav/clamd.conf",
48 "/etc/clamd.d/clamd.conf",
49 "/etc/clamd.conf"
50 };
51
52 bool loaded = false;
53 for (const auto& path : conf_paths) {
54 if (clamdConfig_.load(path)) {
55 std::cout << _("✔ Caricato config da: ") << path << std::endl;
56 loaded = true;
57 break;
58 }
59 }
60
61 if (!loaded) {
62 std::cerr << _("❌ Errore: impossibile leggere clamd.conf in nessuno dei percorsi noti") << "\n";
63 }
64
65
66
68
69
70 stack_.get_style_context()->add_class("content");
71 stack_.set_transition_type(Gtk::StackTransitionType::SLIDE_LEFT_RIGHT);
72 stack_.set_transition_duration(220);
73 stack_.add(dashboard_page_, "dashboard");
74 stack_.add(scan_page_, "scan");
75 samba_page_ = Gtk::make_managed<SambaPage>();
76 stack_.add(*samba_page_, "samba");
77 anti_ransomware_page_ = Gtk::make_managed<AntiRansomwarePage>(*this);
78 stack_.add(*anti_ransomware_page_, "antiransomware");
79 backup_page_ = Gtk::make_managed<BackupPage>();
80 stack_.add(*backup_page_, "backup");
81 stack_.add(log_page_, "log");
82#if BASTIONGUARD_HAS_CEF
84 bank_page_ = Gtk::make_managed<BankPage>();
85 stack_.add(*bank_page_, "bank");
86 }
87#endif
88 privacy_page_ = Gtk::make_managed<PrivacyPage>();
89 stack_.add(*privacy_page_, "privacy");
90 rootguard_page_ = Gtk::make_managed<RootGuardPage>();
91 stack_.add(*rootguard_page_, "rootguard");
92 stack_.add(quarantine_page_, "quarantine");
93 usb_page_ = Gtk::make_managed<USBScanPage>();
94 stack_.add(*usb_page_, "usbscan");
95 stack_.add(update_page_, "update");
96 stack_.add(about_page_, "about");
97 stack_.add(donate_page_, "donate");
98 password_manager_page_ = Gtk::make_managed<PasswordManagerPage>();
99 stack_.add(*password_manager_page_, "passwordmanager");
100 identity_leak_page_ = Gtk::make_managed<IdentityLeakPage>(*this);
101 stack_.add(*identity_leak_page_, "identityleak");
102
103 phishing_page_ = Gtk::make_managed<PhishingPage>();
104 stack_.add(*phishing_page_, "phishing");
105 vpn_page_ = Gtk::make_managed<VpnPage>();
106 stack_.add(*vpn_page_, "vpn");
107
109 mainBox.append(stack_);
110 set_child(mainBox);
111
112
113 auto get_cvd_version = [](const std::string& path) -> std::string {
114 std::ifstream file(path, std::ios::binary);
115 if (!file.is_open()) return "";
116
117 std::string header;
118 header.resize(512);
119 file.read(&header[0], 512);
120
121 std::regex re("ClamAV-VDB:.*:([0-9]+):");
122 std::smatch match;
123 if (std::regex_search(header, match, re)) {
124 return match[1];
125 }
126 return "";
127 };
128
129 std::string db_version;
130 std::string daily = get_cvd_version("/var/lib/clamav/daily.cvd");
131 std::string main = get_cvd_version("/var/lib/clamav/main.cvd");
132 std::string bytecode = get_cvd_version("/var/lib/clamav/bytecode.cvd");
133
134 if (!daily.empty()) db_version += "daily: " + daily + " ";
135 if (!main.empty()) db_version += "main: " + main + " ";
136 if (!bytecode.empty()) db_version += "bytecode: " + bytecode + " ";
137 if (db_version.empty()) db_version = _("sconosciuta");
138
139 bool on_access_enabled = true;
140 dashboard_page_.update_from_logs("", db_version, on_access_enabled);
142}
#define _(s)
bool load(const std::string &path)
void update_from_logs(const std::string &log_path, const Glib::ustring &db_version, bool on_access_enabled)
PasswordManagerPage * password_manager_page_
BackupPage * backup_page_
USBScanPage * usb_page_
AboutPage about_page_
DonatePage donate_page_
Gtk::Button * dashboard_button_
DashboardPage dashboard_page_
PhishingPage * phishing_page_
LogPage log_page_
BankPage * bank_page_
IdentityLeakPage * identity_leak_page_
Gtk::Box mainBox
ClamdConfig clamdConfig_
PrivacyPage * privacy_page_
UpdatePage update_page_
void build_headerbar()
QuarantinePage quarantine_page_
void activate_sidebar_button(Gtk::Button *btn)
AntiRansomwarePage * anti_ransomware_page_
RootGuardPage * rootguard_page_
Gtk::Stack stack_
void build_sidebar(ClamdConfig &clamdConfig)
VpnPage * vpn_page_
ScanPage scan_page_
SambaPage * samba_page_

References _, about_page_, activate_sidebar_button(), anti_ransomware_page_, backup_page_, bank_page_, build_headerbar(), build_sidebar(), BastionGuard::Platform::cef_available(), clamdConfig_, dashboard_button_, dashboard_page_, donate_page_, identity_leak_page_, ClamdConfig::load(), log_page_, main(), mainBox, password_manager_page_, phishing_page_, privacy_page_, quarantine_page_, rootguard_page_, samba_page_, scan_page_, stack_, DashboardPage::update_from_logs(), update_page_, usb_page_, and vpn_page_.

Referenced by ClamApp::launch_main_window(), AppGtk::start_application(), and startDesktopActivityMonitor().

◆ ~MainWindow() [1/3]

MainWindow::~MainWindow ( )
overridedefault

Definition at line 292 of file MainWindow.cpp.

293{
294 if (m_desktopActivityTimer != 0) {
295 g_source_remove(m_desktopActivityTimer);
297 }
298
299 // Salva i log — vengono letti al prossimo avvio.
300 // Il file viene cancellato solo da "Pulisci" nelle rispettive pagine.
303
304 m_tray.stop();
306}
ConnectionsPage m_connectionsPage
UIServer m_uiServer
TrayIcon m_tray
guint m_desktopActivityTimer
NetworkPage m_networkPage
void saveLog() const
void stop()
Definition TrayIcon.cpp:282
void stop()
Definition UIServer.cpp:421

References m_connectionsPage, m_desktopActivityTimer, m_networkPage, m_tray, m_uiServer, ConnectionsPage::saveLog(), NetworkPage::saveLog(), TrayIcon::stop(), and UIServer::stop().

◆ MainWindow() [2/4]

Definition at line 104 of file MainWindow.vala.

104 {
105
106 log_debug("MainWindow: MainWindow()");
107
108 this.title = "BastionGuard™ Backup";
109 this.modal = true;
110 this.set_default_size(980, 520);
111 this.set_resizable(true);
112 this.close_request.connect(on_close_request);
113 this.set_icon_name("bastionguard-backup");
114 this.set_titlebar(HeaderFactory.create_main_headerbar(this, 0));
115
116 // Carica lingua da config (prima del CSS, prima di qualsiasi _())
119
120 // Carica tema da config
122 IconManager.use_dark = dark_mode; // set before first icon creation
124
125 this.set_titlebar(HeaderFactory.create_main_headerbar(this, 180));
126
127 hbox_root = new Gtk.Box(Orientation.HORIZONTAL, 0);
128 set_child(hbox_root);
129 hbox_root.hexpand = true;
130 hbox_root.vexpand = false;
131 hbox_root.halign = Gtk.Align.FILL;
132 hbox_root.valign = Gtk.Align.FILL;
133
134 init_sidebar();
135 init_content();
136 activate_nav(btn_nav_snapshots, "snapshots");
138
139 if (App.live_system()) {
140 btn_backup.sensitive = false;
141 btn_nav_settings.sensitive = false;
142 btn_nav_wizard.sensitive = false;
143 }
144
145 tmr_init = Timeout.add(100, init_delayed);
146 log_debug("MainWindow: MainWindow(): exit");
147 }
Main App
bool load_theme_preference()
void update_theme_buttons()
void activate_nav(Gtk.Button btn, string page)
bool on_close_request() override
void init_content()
bool init_delayed()
void apply_language_env(string lang_code)
Gtk.Button btn_nav_snapshots
Gtk.Box hbox_root
string load_language_preference()
void init_sidebar()
void load_css(bool use_dark=false)
string current_lang
bool live_system()
Definition Main.vala:1058
void log_debug(string message)

References activate_nav(), App, apply_language_env(), btn_nav_snapshots, HeaderFactory.create_main_headerbar(), current_lang, dark_mode, hbox_root, init_content(), init_delayed(), init_sidebar(), Main.live_system(), load_css(), load_language_preference(), load_theme_preference(), TeeJee.Logging.log_debug(), on_close_request(), tmr_init, update_theme_buttons(), and IconManager.use_dark.

◆ MainWindow() [3/4]

MainWindow::MainWindow ( )

◆ ~MainWindow() [2/3]

MainWindow::~MainWindow ( )
override

◆ MainWindow() [4/4]

MainWindow::MainWindow ( )

◆ ~MainWindow() [3/3]

MainWindow::~MainWindow ( )
override

Member Function Documentation

◆ activate_nav()

void MainWindow.activate_nav ( Gtk.Button btn,
string page )
inlineprivate

Definition at line 657 of file MainWindow.vala.

657 {
658 if (current_nav_btn != null)
659 current_nav_btn.get_style_context().remove_class("active-sidebar-button");
660 btn.get_style_context().add_class("active-sidebar-button");
661 current_nav_btn = btn;
662
663 switch (page) {
664 case "snapshots":
665 case "settings_page":
666 case "wizard":
667 case "about":
668 case "backup_flow":
669 case "restore_flow":
670 case "delete_flow":
671 case "rsync_log":
672 content_stack.set_visible_child_name(page);
674 break;
675 }
676 }
Gtk.Stack content_stack
void apply_window_mode_for_page(string page)
Gtk.? Button current_nav_btn

References apply_window_mode_for_page(), content_stack, and current_nav_btn.

Referenced by MainWindow(), make_nav_btn(), and show_snapshots_page().

◆ activate_sidebar_button() [1/2]

void MainWindow::activate_sidebar_button ( Gtk::Button * btn)
private

Definition at line 440 of file MainWindow.cpp.

441{
442 for (auto b : sidebar_buttons_)
443 b->get_style_context()->remove_class("active-sidebar-button");
444
445 if (btn)
446 btn->get_style_context()->add_class("active-sidebar-button");
447}
std::vector< Gtk::Button * > sidebar_buttons_

References sidebar_buttons_.

Referenced by MainWindow(), on_sidebar_about(), on_sidebar_dashboard(), on_sidebar_recovery(), and showDashboard().

◆ activate_sidebar_button() [2/2]

◆ activateSidebarButton()

void MainWindow::activateSidebarButton ( Gtk::Button * btn)
private

Definition at line 680 of file MainWindow.cpp.

681{
682 for (auto* b : m_sidebarButtons)
683 b->get_style_context()->remove_class("active-sidebar-button");
684
685 if (btn) {
686 btn->get_style_context()->add_class("active-sidebar-button");
687 m_activeButton = btn;
688 }
689}
Gtk::Button * m_activeButton
std::vector< Gtk::Button * > m_sidebarButtons

References m_activeButton, and m_sidebarButtons.

Referenced by makeSidebarButton().

◆ append_log()

void MainWindow::append_log ( const std::string & line)
private

Definition at line 799 of file main_window.cpp.

799 {
800 if (!log_buffer_) return;
801 auto iter = log_buffer_->end();
802 log_buffer_->insert(iter, line + "\n");
803}
Glib::RefPtr< Gtk::TextBuffer > log_buffer_

References log_buffer_.

Referenced by activate_sidebar_button(), on_choose_destination(), on_launch_elevated(), on_recover_now(), on_recovery_completed(), on_refresh_devices(), on_scan_completed(), on_scan_now(), on_use_selected_device(), and select_source().

◆ apply_inline_css()

void MainWindow::apply_inline_css ( )
private

◆ apply_language_env()

void MainWindow.apply_language_env ( string lang_code)
inlineprivate

Sets the process locale WITHOUT touching system settings. Must be called before any _() translation is evaluated. lang_code matches the .po filename: en_US, it_IT, de_DE, etc.

Definition at line 331 of file MainWindow.vala.

331 {
332 string locale_val;
333 switch (lang_code) {
334 case "ar_SA": locale_val = "ar_SA.UTF-8"; break;
335 case "de_DE": locale_val = "de_DE.UTF-8"; break;
336 case "es_ES": locale_val = "es_ES.UTF-8"; break;
337 case "fr_FR": locale_val = "fr_FR.UTF-8"; break;
338 case "it_IT": locale_val = "it_IT.UTF-8"; break;
339 case "ja_JP": locale_val = "ja_JP.UTF-8"; break;
340 case "nl_NL": locale_val = "nl_NL.UTF-8"; break;
341 case "pl_PL": locale_val = "pl_PL.UTF-8"; break;
342 case "pt_PT": locale_val = "pt_PT.UTF-8"; break;
343 case "ru_RU": locale_val = "ru_RU.UTF-8"; break;
344 default: locale_val = "en_US.UTF-8"; break;
345 }
346
347 GLib.Environment.set_variable("LANGUAGE", lang_code, true);
348 GLib.Environment.set_variable("LC_MESSAGES", locale_val, true);
349 GLib.Environment.set_variable("LANG", locale_val, true);
350
351 GLib.Intl.setlocale(GLib.LocaleCategory.MESSAGES, locale_val);
352 GLib.Intl.bindtextdomain(GETTEXT_PACKAGE, LOCALE_DIR);
353 GLib.Intl.bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
354 GLib.Intl.textdomain(GETTEXT_PACKAGE);
355
356 if (lang_code == "ar_SA") {
357 Gtk.Widget.set_default_direction(Gtk.TextDirection.RTL);
358 } else {
359 Gtk.Widget.set_default_direction(Gtk.TextDirection.LTR);
360 }
361
362 log_debug("Locale applicato (processo): " + locale_val);
363 }

References TeeJee.Logging.log_debug().

Referenced by MainWindow().

◆ apply_theme() [1/2]

void MainWindow.apply_theme ( bool use_dark)
inlineprivate

Definition at line 482 of file MainWindow.vala.

482 {
483 load_css(use_dark);
484 save_theme_preference(use_dark);
485 this.queue_draw();
486 }
void save_theme_preference(bool use_dark)

References load_css(), and save_theme_preference().

Referenced by build_headerbar(), init_sidebar(), on_theme_dark(), and on_theme_light().

◆ apply_theme() [2/2]

void MainWindow::apply_theme ( ThemeMode mode)
private

Definition at line 595 of file main_window.cpp.

595 {
596 current_theme_ = mode;
597
598 const std::string css_path =
599 (mode == ThemeMode::Dark)
600 ? resource("BastionGuard-dark.css")
601 : resource("BastionGuard.css");
602
603 if (!css_provider_) {
604 css_provider_ = Gtk::CssProvider::create();
605 }
606
607 try {
608 css_provider_->load_from_path(css_path);
609 } catch (const Glib::Error& ex) {
610 std::cerr << "Errore caricando CSS '" << css_path << "': " << ex.what() << std::endl;
611 return;
612 }
613
614 auto display = Gdk::Display::get_default();
615 if (display) {
616 gtk_style_context_add_provider_for_display(
617 display->gobj(),
618 GTK_STYLE_PROVIDER(css_provider_->gobj()),
619 GTK_STYLE_PROVIDER_PRIORITY_APPLICATION
620 );
621 }
622
624}
Glib::RefPtr< Gtk::CssProvider > css_provider_
ThemeMode current_theme_
std::string resource(const std::string &rel)
Definition Resource.hpp:31

References css_provider_, current_theme_, Dark, resource(), and update_theme_buttons().

◆ apply_window_mode_for_page()

void MainWindow.apply_window_mode_for_page ( string page)
inlineprivate

Definition at line 719 of file MainWindow.vala.

719 {
723
724 switch (page) {
725 case "settings_page":
726 resize_main_window(1100, 760);
727 break;
728 case "wizard":
729 resize_main_window(980, 620);
730 break;
731 case "backup_flow":
732 resize_main_window(980, 680);
733 break;
734 case "restore_flow":
735 resize_main_window(1080, 720);
736 break;
737 case "delete_flow":
738 resize_main_window(500, 500);
739 break;
740 case "rsync_log":
741 resize_main_window(800, 600);
742 break;
743 }
744 }
745 else {
748 }
749 }
int compact_window_width
void resize_main_window(int width, int height)
int compact_window_height
void remember_compact_window_size()
bool page_requires_expanded_window(string page)
bool window_in_expanded_mode

References compact_window_height, compact_window_width, page_requires_expanded_window(), remember_compact_window_size(), resize_main_window(), and window_in_expanded_mode.

Referenced by activate_nav(), and set_dynamic_page().

◆ applyLanguage()

void MainWindow::applyLanguage ( const std::string & lang)
private

Imposta la variabile d'ambiente LANGUAGE e reinizializza gettext. Deve essere chiamata PRIMA che qualsiasi stringa tradotta venga costruita. Poiché GTK/GLib non supportano il cambio di lingua a runtime senza riavvio, il metodo si limita a impostare l'ambiente: l'effetto si vedrà al prossimo avvio (il LanguageDialog avvisa l'utente di questo).

Definition at line 399 of file MainWindow.cpp.

400{
401 if (!lang.empty()) {
402 ::setenv("LANGUAGE", lang.c_str(), 1);
403 ::setenv("LANG", (lang + ".UTF-8").c_str(), 1);
404 ::setlocale(LC_ALL, (lang + ".UTF-8").c_str());
405 } else {
406 ::unsetenv("LANGUAGE");
407 ::setlocale(LC_ALL, "");
408 }
409
410 // Reinizializza gettext (il dominio e la dir devono già essere configurati in main.cpp)
411 ::textdomain("bastionguard-sc");
412}

◆ applyProtectionEnabled()

void MainWindow::applyProtectionEnabled ( bool enabled)
private

Definition at line 982 of file MainWindow.cpp.

983{
984 const std::filesystem::path cfgDir = std::filesystem::path(m_configFile).parent_path();
985 const std::filesystem::path generatedAutostart = cfgDir / "bastionguard-sc-autostart.desktop";
986 const std::string backupFile = kSystemAutostartBackupDesktop;
987
988 // Settings e systray passano da qui. About resta solo informativa, quindi
989 // l'attivazione/disattivazione non è duplicata in più pagine.
990 bool ok = !enabled || writeConfigAutostartDesktop(generatedAutostart);
991 std::string status;
992
993 if (ok) {
994 std::ostringstream script;
995 script << "set -eu; ";
996
997 if (!enabled) {
998 // Prima di rimuovere l'autostart attivo da /etc/xdg/autostart,
999 // conserva un backup nello stesso percorso di sistema con estensione .bak.
1000 script << "if [ -f " << shellQuote(kSystemAutostartDesktop) << " ]; then "
1001 << "install -m 0644 " << shellQuote(kSystemAutostartDesktop) << " " << shellQuote(backupFile) << "; fi; ";
1002 script << "if [ ! -f " << shellQuote(backupFile) << " ] && [ -f " << shellQuote(kFallbackSystemAutostartDesktop) << " ]; then "
1003 << "install -m 0644 " << shellQuote(kFallbackSystemAutostartDesktop) << " " << shellQuote(backupFile) << "; fi; ";
1004 script << "rm -f " << shellQuote(kSystemAutostartDesktop) << " " << shellQuote(kFallbackSystemAutostartDesktop) << "; ";
1005 script << "test -x " << shellQuote(kServiceCtlPath) << "; ";
1006 script << shellQuote(kServiceCtlPath) << " --system disable --now "
1007 << shellQuote(kServiceName) << "; ";
1008 } else {
1009 script << "mkdir -p " << shellQuote(std::filesystem::path(kSystemAutostartDesktop).parent_path().string()) << "; ";
1010 script << "if [ -f " << shellQuote(backupFile) << " ]; then "
1011 << "install -D -m 0644 " << shellQuote(backupFile) << " " << shellQuote(kSystemAutostartDesktop) << "; "
1012 << "else install -D -m 0644 " << shellQuote(generatedAutostart.string()) << " " << shellQuote(kSystemAutostartDesktop) << "; fi; ";
1013 script << "rm -f " << shellQuote(kFallbackSystemAutostartDesktop) << "; ";
1014 script << "test -x " << shellQuote(kServiceCtlPath) << "; ";
1015 script << shellQuote(kServiceCtlPath) << " --system enable --now "
1016 << shellQuote(kServiceName) << "; ";
1017 }
1018
1019 ok = runCommand("pkexec /bin/sh -c " + shellQuote(script.str()));
1020 }
1021
1022 if (ok) {
1023 ok = writeServiceControlPreference(enabled, backupFile);
1024 if (!ok) {
1025 status = _("Operazione di sistema completata, ma salvataggio della preferenza in ~/.config non riuscito.");
1026 }
1027 }
1028
1029 if (ok) {
1030 m_protectionEnabled = enabled;
1031 m_autostartBackupFile = backupFile;
1032 saveConfig();
1033 status = enabled
1034 ? _("Avvio persistente attivato: autostart_enabled=true e daemon_enabled=true salvati, autostart installato e bsc-daemon abilitato.")
1035 : _("Protezione disattivata: enabled=false, autostart_enabled=false e daemon_enabled=false salvati, bsc-daemon fermato/disabilitato e autostart rimosso. Backup creato in /etc/xdg/autostart.");
1036 } else if (status.empty()) {
1037 status = enabled
1038 ? _("Riattivazione non completata. Controlla PolicyKit, il gestore servizi, il backup in /etc/xdg/autostart e il salvataggio config.")
1039 : _("Disattivazione non completata. Controlla PolicyKit, il gestore servizi, il backup in /etc/xdg/autostart, bsc-daemon e il salvataggio config.");
1040 }
1041
1045 setStatus(status);
1046}
bool m_protectionEnabled
void saveConfig()
SettingsPage m_settingsPage
void setStatus(const std::string &msg)
std::string m_autostartBackupFile
std::string m_configFile
void setProtectionEnabled(bool enabled)
void setSystemIntegrationStatus(const std::string &text)
std::string shellQuote(const std::string &s)
constexpr const char * kSystemAutostartBackupDesktop
bool writeServiceControlPreference(bool enabled, const std::string &backupFile)
bool writeConfigAutostartDesktop(const std::filesystem::path &path)
CommandResult runCommand(const std::vector< std::string > &arguments) noexcept

References _, m_autostartBackupFile, m_configFile, m_protectionEnabled, m_settingsPage, SettingsPage::refreshState(), saveConfig(), SettingsPage::setProtectionEnabled(), setStatus(), and SettingsPage::setSystemIntegrationStatus().

◆ applyTheme()

void MainWindow::applyTheme ( bool dark)
private

Definition at line 449 of file MainWindow.cpp.

450{
451 m_darkMode = dark;
452 loadTheme(dark);
453 saveConfig();
454
455 if (m_btnLight && m_btnDark) {
456 if (dark) {
457 m_btnLight->get_style_context()->remove_class("theme-btn-active");
458 m_btnDark->get_style_context()->add_class("theme-btn-active");
459 } else {
460 m_btnDark->get_style_context()->remove_class("theme-btn-active");
461 m_btnLight->get_style_context()->add_class("theme-btn-active");
462 }
463 }
464}
bool m_darkMode
Gtk::Button * m_btnLight
Gtk::Button * m_btnDark
void loadTheme(bool dark)

References loadTheme(), m_btnDark, m_btnLight, m_darkMode, and saveConfig().

Referenced by buildHeaderBar().

◆ browse_selected()

void MainWindow.browse_selected ( )
inline

Definition at line 1217 of file MainWindow.vala.

1217 {
1218 var selected = snapshot_list_box.selected_snapshots();
1219 if (selected.size == 0) {
1220 TeeJee.System.xdg_open(
1221 File.new_for_path(App.repo.snapshots_path).query_exists()
1223 return;
1224 }
1225 var bak = selected[0];
1226 TeeJee.System.xdg_open(App.btrfs_mode ? bak.path : bak.path + "/localhost");
1227 }
SnapshotListBox snapshot_list_box
SnapshotRepo repo
Definition Main.vala:70
bool btrfs_mode
Definition Main.vala:52
Gee.ArrayList< Snapshot > selected_snapshots()
string snapshots_path

References App, Main.btrfs_mode, SnapshotRepo.mount_path, Main.repo, SnapshotListBox.selected_snapshots(), snapshot_list_box, and SnapshotRepo.snapshots_path.

Referenced by init_snapshots_page().

◆ btn_about_clicked()

void MainWindow.btn_about_clicked ( )
inlineprivate

Definition at line 1310 of file MainWindow.vala.

1310 {
1311 content_stack.set_visible_child_name("about");
1312 }

References content_stack.

Referenced by init_snapshots_page().

◆ btn_restore_clicked()

void MainWindow.btn_restore_clicked ( )
inlineprivate

Definition at line 1242 of file MainWindow.vala.

1242 {
1243 if (check_if_deletion_running()) return;
1244 App.mirror_system = false;
1245 restore();
1246 }
bool check_if_deletion_running()

References check_if_deletion_running(), and restore().

Referenced by init_snapshots_page().

◆ btn_settings_clicked()

void MainWindow.btn_settings_clicked ( )
inlineprivate

Definition at line 1288 of file MainWindow.vala.

1288 {
1289 content_stack.set_visible_child_name("settings_page");
1290 }

References content_stack.

Referenced by show_settings().

◆ btn_wizard_clicked()

void MainWindow.btn_wizard_clicked ( )
inlineprivate

Definition at line 1292 of file MainWindow.vala.

1292 {
1293 content_stack.set_visible_child_name("wizard");
1294 }

References content_stack.

Referenced by init_delayed(), and on_close_request().

◆ build_about_page()

void MainWindow::build_about_page ( )
private

Definition at line 1325 of file main_window.cpp.

1325 {
1326 about_page_.set_hexpand(true);
1327 about_page_.set_vexpand(true);
1328 about_page_.set_margin_top(32);
1329 about_page_.set_margin_bottom(32);
1330 about_page_.set_margin_start(48);
1331 about_page_.set_margin_end(48);
1332 about_page_.set_halign(Gtk::Align::CENTER);
1333 about_page_.set_valign(Gtk::Align::CENTER);
1334
1335 try {
1336 auto* logo_img = Gtk::make_managed<Gtk::Image>();
1337 try {
1338 auto texture = Gdk::Texture::create_from_filename(resource("logo.svg"));
1339 logo_img->set(texture);
1340 logo_img->set_pixel_size(192);
1341 } catch (...) {}
1342 logo_img->set_margin_bottom(12);
1343 about_page_.append(*logo_img);
1344 } catch (...) {}
1345
1346 auto* name_label = Gtk::make_managed<Gtk::Label>(tr("BastionGuard™ Recovery Data"));
1347 name_label->add_css_class("page-title");
1348 name_label->set_margin_bottom(4);
1349 about_page_.append(*name_label);
1350
1351 std::string version_str = "unknown";
1352 {
1353 const std::string version_path = resource("version.bs");
1354 std::ifstream vf(version_path);
1355 if (vf.is_open()) {
1356 std::getline(vf, version_str);
1357 version_str.erase(version_str.find_last_not_of(" \t\r\n") + 1);
1358 version_str.erase(0, version_str.find_first_not_of(" \t\r\n"));
1359 }
1360 }
1361
1362 auto* version_label = Gtk::make_managed<Gtk::Label>(trs("Version ") + version_str);
1363 version_label->add_css_class("small-label");
1364 version_label->set_margin_bottom(18);
1365 about_page_.append(*version_label);
1366
1367 auto* about_notebook = Gtk::make_managed<Gtk::Notebook>();
1368 about_notebook->set_hexpand(true);
1369 about_notebook->set_vexpand(true);
1370 about_notebook->set_halign(Gtk::Align::FILL);
1371 about_notebook->set_valign(Gtk::Align::FILL);
1372 about_notebook->set_size_request(680, 360);
1373
1374 auto* overview_box = Gtk::make_managed<Gtk::Box>(Gtk::Orientation::VERTICAL, 18);
1375 overview_box->set_margin_top(24);
1376 overview_box->set_margin_bottom(24);
1377 overview_box->set_margin_start(24);
1378 overview_box->set_margin_end(24);
1379
1380 auto* desc_label = Gtk::make_managed<Gtk::Label>(
1381 tr("A read-only forensic recovery tool supporting ext4, btrfs, NTFS, FAT32,exFAT, XFS and HFS+.\nScan physical disks or image files without writing a single byte to the source."));
1382 desc_label->set_wrap(true);
1383 desc_label->set_justify(Gtk::Justification::CENTER);
1384 overview_box->append(*desc_label);
1385
1386 auto* fs_label = Gtk::make_managed<Gtk::Label>(
1387 tr("Supported filesystems: ext4 • Btrfs • NTFS • FAT32 • exFAT • XFS • HFS+"));
1388 fs_label->add_css_class("subtitle");
1389 fs_label->set_wrap(true);
1390 fs_label->set_justify(Gtk::Justification::CENTER);
1391 overview_box->append(*fs_label);
1392
1393 auto* license_summary = Gtk::make_managed<Gtk::Label>(
1394 tr("Released under GNU GPLv3 or later. BastionGuard™ is a trademark of Calogero Scarnà."));
1395 license_summary->add_css_class("small-label");
1396 license_summary->set_justify(Gtk::Justification::CENTER);
1397 license_summary->set_wrap(true);
1398 overview_box->append(*license_summary);
1399
1400 auto* overview_tab = Gtk::make_managed<Gtk::Label>(tr("Overview"));
1401 about_notebook->append_page(*overview_box, *overview_tab);
1402
1403 auto* license_scroller = Gtk::make_managed<Gtk::ScrolledWindow>();
1404 license_scroller->set_policy(Gtk::PolicyType::AUTOMATIC, Gtk::PolicyType::AUTOMATIC);
1405 license_scroller->set_min_content_width(640);
1406 license_scroller->set_min_content_height(300);
1407
1408 auto* license_text = Gtk::make_managed<Gtk::TextView>();
1409 license_text->set_editable(false);
1410 license_text->set_cursor_visible(false);
1411 license_text->set_wrap_mode(Gtk::WrapMode::WORD);
1412 license_text->set_left_margin(14);
1413 license_text->set_right_margin(14);
1414 license_text->set_top_margin(14);
1415 license_text->set_bottom_margin(14);
1416
1417 auto license_buffer = Gtk::TextBuffer::create();
1418 license_buffer->set_text(load_license_text());
1419 license_text->set_buffer(license_buffer);
1420 license_scroller->set_child(*license_text);
1421
1422 auto* license_tab = Gtk::make_managed<Gtk::Label>(tr("License"));
1423 about_notebook->append_page(*license_scroller, *license_tab);
1424
1425 about_page_.append(*about_notebook);
1426}
const char * tr(const char *msgid)
Definition i18n.cpp:18
std::string trs(const char *msgid)
Definition i18n.cpp:22

References about_page_, resource(), tr(), and trs().

Referenced by build_headerbar().

◆ build_dashboard()

void MainWindow::build_dashboard ( )
private

Definition at line 391 of file main_window.cpp.

391 {
392 dashboard_page_.set_hexpand(true);
393 dashboard_page_.set_vexpand(true);
394 dashboard_page_.set_margin_top(24);
395 dashboard_page_.set_margin_bottom(24);
396 dashboard_page_.set_margin_start(24);
397 dashboard_page_.set_margin_end(24);
398
399 cards_grid_.set_column_spacing(16);
400 cards_grid_.set_row_spacing(16);
401
405
406 card_status_.add_css_class("card");
407 card_source_.add_css_class("card");
408 card_update_.add_css_class("card");
409
410 status_card_label_.set_text(tr("Core engine: Ready\nRead-only mode: Active"));
411 source_card_label_.set_text(tr("No source selected"));
412 update_card_label_.set_text(tr("Device inventory available"));
413
414 status_card_label_.set_wrap(true);
415 source_card_label_.set_wrap(true);
416 update_card_label_.set_wrap(true);
417
418 status_card_label_.set_margin_top(20);
419 status_card_label_.set_margin_bottom(20);
420 status_card_label_.set_margin_start(20);
421 status_card_label_.set_margin_end(20);
422
423 source_card_label_.set_margin_top(20);
424 source_card_label_.set_margin_bottom(20);
425 source_card_label_.set_margin_start(20);
426 source_card_label_.set_margin_end(20);
427
428 update_card_label_.set_margin_top(20);
429 update_card_label_.set_margin_bottom(20);
430 update_card_label_.set_margin_start(20);
431 update_card_label_.set_margin_end(20);
432
433 cards_grid_.attach(card_status_, 0, 0, 1, 1);
434 cards_grid_.attach(card_source_, 1, 0, 1, 1);
435 cards_grid_.attach(card_update_, 2, 0, 1, 1);
436
437 devices_frame_.set_label(tr("Available disks"));
438 devices_frame_.add_css_class("card");
439
440 devices_scroller_.set_policy(Gtk::PolicyType::AUTOMATIC, Gtk::PolicyType::AUTOMATIC);
441 devices_scroller_.set_vexpand(true);
443
444 devices_list_.add_css_class("scan-file-list");
445
447
450}
Gtk::ScrolledWindow devices_scroller_
Gtk::ListBox devices_list_
Gtk::Grid cards_grid_
Gtk::Label source_card_label_
Gtk::Frame card_source_
Gtk::Frame devices_frame_
Gtk::Frame card_update_
Gtk::Label status_card_label_
Gtk::Label update_card_label_
Gtk::Frame card_status_

References card_source_, card_status_, card_update_, cards_grid_, dashboard_page_, devices_frame_, devices_list_, devices_scroller_, source_card_label_, status_card_label_, tr(), and update_card_label_.

Referenced by build_headerbar().

◆ build_headerbar() [1/3]

void MainWindow.build_headerbar ( )
inlineprivate

Definition at line 152 of file MainWindow.vala.

152 {
153
154 var header = new Gtk.HeaderBar();
155 header.set_show_title_buttons(false);
156 header.set_decoration_layout("");
157 header.get_style_context().add_class("custom-headerbar");
158
159 var header_left = new Gtk.Box(Orientation.HORIZONTAL, 0);
160 header_left.set_size_request(180, -1);
161 header_left.get_style_context().add_class("header-left");
162 header_left.margin_start = 0;
163 header_left.margin_end = 0;
164 header_left.margin_top = 0;
165 header_left.margin_bottom = 0;
166 header.set_title_widget(new Gtk.Box(Orientation.HORIZONTAL, 0));
167 var header_root = (Gtk.Box) header.get_title_widget();
168 header_root.hexpand = true;
169 header_root.append(header_left);
170
171 var header_mid = new Gtk.Box(Orientation.HORIZONTAL, 0);
172 header_mid.hexpand = true;
173 header_mid.get_style_context().add_class("header-right");
174 header_root.append(header_mid);
175
176 var header_right = new Gtk.Box(Orientation.HORIZONTAL, 0);
177 header_right.get_style_context().add_class("header-right");
178 header_right.valign = Gtk.Align.CENTER;
179 header_right.margin_end = 6;
180
181 var btn_min = new Gtk.Button();
182 btn_min.set_child(themed_icon("window-minimize-symbolic", 16));
183 btn_min.get_style_context().add_class("header-button");
184 btn_min.clicked.connect(() => { this.minimize(); });
185 header_right.append(btn_min);
186
187 var btn_close = new Gtk.Button();
188 btn_close.set_child(themed_icon("window-close-symbolic", 16));
189 btn_close.get_style_context().add_class("header-button");
190 btn_close.clicked.connect(() => { this.close(); });
191 header_right.append(btn_close);
192
193 header_root.append(header_right);
194 this.set_titlebar(header);
195 }
void minimize()
Gtk.Image themed_icon(string icon_name, int size)

References minimize(), and themed_icon().

◆ build_headerbar() [2/3]

void MainWindow::build_headerbar ( )
private

Definition at line 145 of file MainWindow.cpp.

145 {
146 auto header = Gtk::make_managed<Gtk::HeaderBar>();
147 header->set_show_title_buttons(false);
148 header->set_decoration_layout("");
149 header->get_style_context()->add_class("custom-headerbar");
150
151
152 auto header_left = Gtk::make_managed<Gtk::Box>(Gtk::Orientation::HORIZONTAL);
153 // La larghezza è gestita dal CSS con min-width: 240px sul .header-left
154 header_left->set_hexpand(false);
155 header_left->get_style_context()->add_class("header-left");
156 header->pack_start(*header_left);
157
158
159 auto header_spacer = Gtk::make_managed<Gtk::Box>(Gtk::Orientation::HORIZONTAL);
160 header_spacer->set_hexpand(true);
161 header->pack_start(*header_spacer);
162
163
164 auto header_right = Gtk::make_managed<Gtk::Box>(Gtk::Orientation::HORIZONTAL);
165 header_right->get_style_context()->add_class("header-right");
166
167 try {
168 auto pix_min = Gdk::Pixbuf::create_from_file(resource("icon-minimize.png"), 32, 32, true);
169 auto btn_min = Gtk::make_managed<Gtk::Button>();
170 btn_min->set_child(*Gtk::make_managed<Gtk::Image>(pix_min));
171 btn_min->get_style_context()->add_class("header-button");
172 header_right->append(*btn_min);
173 btn_min->signal_clicked().connect([this]() { minimize(); });
174 } catch (...) {
175 std::cerr << _("⚠ Errore caricamento icona minimize") << "\n";
176 }
177
178 try {
179 auto pix_close = Gdk::Pixbuf::create_from_file(resource("icon-close.png"), 32, 32, true);
180 auto btn_close = Gtk::make_managed<Gtk::Button>();
181 btn_close->set_child(*Gtk::make_managed<Gtk::Image>(pix_close));
182 btn_close->get_style_context()->add_class("header-button");
183 header_right->append(*btn_close);
184
185 btn_close->signal_clicked().connect([this]() {
186 std::cout << _("[MainWindow] Pulsante close → nascondo nella tray") << "\n";
187 this->hide();
188 });
189 } catch (...) {
190 std::cerr << _("⚠ Errore caricamento icona close") << "\n";
191 }
192
193 header->pack_end(*header_right);
194 set_titlebar(*header);
195}

References _, minimize(), and resource().

Referenced by MainWindow().

◆ build_headerbar() [3/3]

◆ build_recovery_page()

void MainWindow::build_recovery_page ( )
private

Definition at line 569 of file main_window.cpp.

569 {
570 recovery_page_.set_hexpand(true);
571 recovery_page_.set_vexpand(true);
572 recovery_page_.set_margin_top(24);
573 recovery_page_.set_margin_bottom(24);
574 recovery_page_.set_margin_start(24);
575 recovery_page_.set_margin_end(24);
576
577 recovery_title_.add_css_class("page-title");
578 recovery_subtitle_.add_css_class("small-label");
579 recovery_subtitle_.set_wrap(true);
580 recovery_subtitle_.set_xalign(0.0f);
583
584 build_wizard();
585
586 log_scroller_.set_vexpand(true);
587 log_scroller_.add_css_class("BastionGuard-scroller");
588 log_scroller_.set_child(log_view_);
589
593}
Gtk::ScrolledWindow log_scroller_
Gtk::TextView log_view_
Gtk::Frame wizard_frame_
void build_wizard()
Gtk::Box recovery_page_
Gtk::Label recovery_title_
Gtk::Box recovery_header_
Gtk::Label recovery_subtitle_

References build_wizard(), log_scroller_, log_view_, recovery_header_, recovery_page_, recovery_subtitle_, recovery_title_, and wizard_frame_.

Referenced by build_headerbar().

◆ build_sidebar() [1/2]

void MainWindow::build_sidebar ( )
private

Definition at line 254 of file main_window.cpp.

254 {
255 sidebar_.set_size_request(240, -1);
256 sidebar_.add_css_class("sidebar");
257
258 auto* hdr = Gtk::make_managed<Gtk::Box>(Gtk::Orientation::VERTICAL, 8);
259 hdr->add_css_class("sidebar-header");
260
261 auto* logo_img = Gtk::make_managed<Gtk::Image>();
262 try {
263 auto texture = Gdk::Texture::create_from_filename(resource("logo-sidebar.png"));
264 logo_img->set(texture);
265 logo_img->set_pixel_size(48);
266 } catch (...) {}
267 logo_img->set_halign(Gtk::Align::START);
268 logo_img->set_margin_bottom(4);
269 hdr->append(*logo_img);
270
271 brand_label_.set_text(tr("BastionGuard™\nRecovery Data"));
272 brand_label_.set_halign(Gtk::Align::START);
273 brand_label_.add_css_class("sidebar-title");
274 hdr->append(brand_label_);
275
276 sidebar_.append(*hdr);
277
278 btn_dashboard_.add_css_class("sidebar-button");
279 btn_recovery_.add_css_class("sidebar-button");
280 btn_about_.add_css_class("sidebar-button");
281 btn_refresh_.add_css_class("sidebar-button");
282
283 btn_dashboard_.set_halign(Gtk::Align::FILL);
284 btn_recovery_.set_halign(Gtk::Align::FILL);
285 btn_about_.set_halign(Gtk::Align::FILL);
286 btn_refresh_.set_halign(Gtk::Align::FILL);
287
288 set_button_with_svg_icon(btn_dashboard_, resource("icons/icon-dashboard.svg"), tr("Dashboard"));
289 set_button_with_svg_icon(btn_recovery_, resource("icons/icon-recovery.svg"), tr("Recovery wizard"));
290 set_button_with_svg_icon(btn_refresh_, resource("icons/icon-refresh.svg"), tr("Refresh devices"));
291 set_button_with_svg_icon(btn_about_, resource("icons/icon-about.svg"), tr("About"));
292
296
299 sidebar_buttons_.push_back(&btn_about_);
300
301 sidebar_.append(btn_dashboard_);
302 sidebar_.append(btn_recovery_);
303 sidebar_.append(btn_refresh_);
304
305 auto* sep1 = Gtk::make_managed<Gtk::Separator>(Gtk::Orientation::HORIZONTAL);
306 sep1->add_css_class("sidebar-separator");
307 sidebar_.append(*sep1);
308
309 auto* theme_title = Gtk::make_managed<Gtk::Label>(tr("Theme"));
310 theme_title->set_halign(Gtk::Align::START);
311 theme_title->add_css_class("sidebar-group-label");
312 sidebar_.append(*theme_title);
313
314 auto* theme_row = Gtk::make_managed<Gtk::Box>(Gtk::Orientation::HORIZONTAL, 10);
315 theme_row->add_css_class("sidebar-theme-row");
316 theme_row->set_halign(Gtk::Align::FILL);
317 theme_row->set_hexpand(true);
318
319 btn_theme_dark_.add_css_class("theme-btn");
320 btn_theme_light_.add_css_class("theme-btn");
321
322 btn_theme_dark_.set_hexpand(true);
323 btn_theme_light_.set_hexpand(true);
324 btn_theme_dark_.set_halign(Gtk::Align::FILL);
325 btn_theme_light_.set_halign(Gtk::Align::FILL);
326
327 theme_row->append(btn_theme_dark_);
328 theme_row->append(btn_theme_light_);
329 sidebar_.append(*theme_row);
330
331 auto* sep2 = Gtk::make_managed<Gtk::Separator>(Gtk::Orientation::HORIZONTAL);
332 sep2->add_css_class("sidebar-separator");
333 sidebar_.append(*sep2);
334
335 auto* lang_title = Gtk::make_managed<Gtk::Label>(tr("Language"));
336 lang_title->set_halign(Gtk::Align::START);
337 lang_title->add_css_class("sidebar-group-label");
338 sidebar_.append(*lang_title);
339
340 lang_combo_.add_css_class("sidebar-lang-combo");
341 lang_combo_.set_hexpand(true);
342 lang_combo_.set_halign(Gtk::Align::FILL);
343 auto lang_model = Gtk::StringList::create({
344 "English",
345 "Italiano",
346 "Deutsch",
347 "Español",
348 "Français",
349 "日本語",
350 "Nederlands",
351 "Polski",
352 "Português",
353 "Русский",
354 "العربية"
355 });
356 lang_combo_.set_model(lang_model);
357
358 {
359 const std::string saved = read_language();
360
361 if (saved == "it") lang_combo_.set_selected(1);
362 else if (saved == "de") lang_combo_.set_selected(2);
363 else if (saved == "es") lang_combo_.set_selected(3);
364 else if (saved == "fr") lang_combo_.set_selected(4);
365 else if (saved == "ja") lang_combo_.set_selected(5);
366 else if (saved == "nl") lang_combo_.set_selected(6);
367 else if (saved == "pl") lang_combo_.set_selected(7);
368 else if (saved == "pt") lang_combo_.set_selected(8);
369 else if (saved == "ru") lang_combo_.set_selected(9);
370 else if (saved == "ar") lang_combo_.set_selected(10);
371 else lang_combo_.set_selected(0);
372 }
373
374 lang_combo_.property_selected().signal_changed().connect(
375 sigc::mem_fun(*this, &MainWindow::on_language_changed));
376
377 sidebar_.append(lang_combo_);
378
379 auto* spacer = Gtk::make_managed<Gtk::Box>(Gtk::Orientation::VERTICAL);
380 spacer->set_vexpand(true);
381 sidebar_.append(*spacer);
382
383 sidebar_.append(btn_about_);
384
385 auto* info = Gtk::make_managed<Gtk::Label>(tr("Read-only forensic mode"));
386 info->set_halign(Gtk::Align::START);
387 info->add_css_class("small-label");
388 sidebar_.append(*info);
389}
Gtk::DropDown lang_combo_
Gtk::Box sidebar_
Gtk::Button * recovery_button_
Gtk::Button * about_button_
Gtk::Button btn_dashboard_
Gtk::Label brand_label_
void on_language_changed()
Gtk::Button btn_theme_light_
Gtk::Button btn_about_
Gtk::Button btn_recovery_
Gtk::Button btn_theme_dark_
Gtk::Button btn_refresh_
static std::string read_language()
void set_button_with_svg_icon(Gtk::Button &button, const std::string &svg_path, const Glib::ustring &text)

References about_button_, brand_label_, btn_about_, btn_dashboard_, btn_recovery_, btn_refresh_, btn_theme_dark_, btn_theme_light_, dashboard_button_, lang_combo_, on_language_changed(), read_language(), recovery_button_, resource(), sidebar_, sidebar_buttons_, and tr().

◆ build_sidebar() [2/2]

void MainWindow::build_sidebar ( ClamdConfig & clamdConfig)
private

Definition at line 198 of file MainWindow.cpp.

198 {
199
200 // Ordine pagine per direzione animazione
201 static const std::vector<std::string> kPageOrder = {
202 "dashboard",
203 "scan","antiransomware",
204#if BASTIONGUARD_HAS_CEF
205 "bank",
206#endif
207 "privacy","rootguard","usbscan","samba",
208 "log","quarantine","identityleak","passwordmanager","backup","update",
209 "phishing",
210 "about","donate"
211 };
212
213 // Tracciamento revealer aperti — uno solo alla volta
214 // Usiamo un vettore di puntatori ai revealer attivi
215 auto open_revealers = std::make_shared<std::vector<Gtk::Revealer*>>();
216
217 auto sidebar_box = Gtk::make_managed<Gtk::Box>(Gtk::Orientation::VERTICAL, 10);
218 sidebar_box->set_size_request(240, -1);
219 sidebar_box->get_style_context()->add_class("sidebar");
220
221 // ── Header: logo + titolo ───────────────────────────────────────────
222 {
223 auto hdr = Gtk::make_managed<Gtk::Box>(Gtk::Orientation::HORIZONTAL, 8);
224 hdr->get_style_context()->add_class("sidebar-header");
225 try {
226 auto pb = Gdk::Pixbuf::create_from_file(resource("logo-sidebar.png"), 128, 128, true);
227 auto logo = Gtk::make_managed<Gtk::Image>(pb);
228 hdr->append(*logo);
229 } catch (...) {}
230 auto lbl = Gtk::make_managed<Gtk::Label>("BastionGuard™ Endpoint");
231 lbl->set_halign(Gtk::Align::START);
232 lbl->get_style_context()->add_class("sidebar-title");
233 hdr->append(*lbl);
234 sidebar_box->append(*hdr);
235 }
236
237 // ── navigate_to: animazione direzionale ────────────────────────────
238 auto navigate_to = [this, &kPageOrder](const std::string& page) {
239 const std::string cur = stack_.get_visible_child_name();
240 auto itC = std::find(kPageOrder.begin(), kPageOrder.end(), cur);
241 auto itD = std::find(kPageOrder.begin(), kPageOrder.end(), page);
242 if (itC != kPageOrder.end() && itD != kPageOrder.end()) {
243 if (itD > itC)
244 stack_.set_transition_type(Gtk::StackTransitionType::SLIDE_LEFT);
245 else if (itD < itC)
246 stack_.set_transition_type(Gtk::StackTransitionType::SLIDE_RIGHT);
247 }
248 stack_.set_visible_child(page);
249 };
250
251 // ── make_leaf: voce singola con icona ──────────────────────────────
252 auto make_leaf = [&](const std::string& icon_path,
253 const std::string& label_text,
254 const std::string& page_name,
255 bool indent = false) -> Gtk::Button*
256 {
257 auto box = Gtk::make_managed<Gtk::Box>(Gtk::Orientation::HORIZONTAL, 6);
258 if (indent) box->set_margin_start(14);
259
260 auto ib = Gtk::make_managed<Gtk::Box>(Gtk::Orientation::VERTICAL);
261 ib->set_size_request(16, 16);
262 ib->set_valign(Gtk::Align::CENTER);
263 auto pic = Gtk::make_managed<Gtk::Picture>();
264 try {
265 auto pb = Gdk::Pixbuf::create_from_file(icon_path);
266 auto sc = pb->scale_simple(16, 16, Gdk::InterpType::BILINEAR);
267 pic->set_paintable(Gdk::Texture::create_for_pixbuf(sc));
268 pic->set_content_fit(Gtk::ContentFit::FILL);
269 } catch (...) {}
270 ib->append(*pic);
271 box->append(*ib);
272
273 auto lbl = Gtk::make_managed<Gtk::Label>(_(label_text.c_str()));
274 lbl->set_halign(Gtk::Align::START);
275 lbl->get_style_context()->add_class("sidebar-group-label");
276 box->append(*lbl);
277
278 auto btn = Gtk::make_managed<Gtk::Button>();
279 btn->set_child(*box);
280 btn->get_style_context()->add_class("sidebar-button");
281 sidebar_buttons_.push_back(btn);
282
283 btn->signal_clicked().connect([this, btn, page_name, navigate_to]() {
284 for (auto b : sidebar_buttons_)
285 b->get_style_context()->remove_class("active-sidebar-button");
286 btn->get_style_context()->add_class("active-sidebar-button");
287 navigate_to(page_name);
288 });
289 return btn;
290 };
291
292 // ── make_group: gruppo espandibile, uno alla volta ─────────────────
293 auto make_group = [&](const std::string& icon_path,
294 const std::string& label_text) -> Gtk::Box*
295 {
296 auto arrow = Gtk::make_managed<Gtk::Label>("▸");
297 arrow->set_halign(Gtk::Align::END);
298 arrow->set_hexpand(true);
299 arrow->get_style_context()->add_class("sidebar-arrow");
300
301 auto box = Gtk::make_managed<Gtk::Box>(Gtk::Orientation::HORIZONTAL, 6);
302 auto ib = Gtk::make_managed<Gtk::Box>(Gtk::Orientation::VERTICAL);
303 ib->set_size_request(16, 16);
304 ib->set_valign(Gtk::Align::CENTER);
305 auto pic = Gtk::make_managed<Gtk::Picture>();
306 try {
307 auto pb = Gdk::Pixbuf::create_from_file(icon_path);
308 auto sc = pb->scale_simple(16, 16, Gdk::InterpType::BILINEAR);
309 pic->set_paintable(Gdk::Texture::create_for_pixbuf(sc));
310 pic->set_content_fit(Gtk::ContentFit::FILL);
311 } catch (...) {}
312 ib->append(*pic);
313 box->append(*ib);
314
315 auto lbl = Gtk::make_managed<Gtk::Label>(_(label_text.c_str()));
316 lbl->set_halign(Gtk::Align::START);
317 box->append(*lbl);
318 box->append(*arrow);
319
320 auto hbtn = Gtk::make_managed<Gtk::Button>();
321 hbtn->set_child(*box);
322 hbtn->get_style_context()->add_class("sidebar-group-button");
323
324 auto revealer = Gtk::make_managed<Gtk::Revealer>();
325 revealer->set_transition_type(Gtk::RevealerTransitionType::SLIDE_DOWN);
326 revealer->set_transition_duration(200);
327 revealer->set_reveal_child(false); // chiuso all'avvio
328
329 auto children = Gtk::make_managed<Gtk::Box>(Gtk::Orientation::VERTICAL, 0);
330 revealer->set_child(*children);
331
332 // Registra questo revealer nella lista
333 open_revealers->push_back(revealer);
334
335 hbtn->signal_clicked().connect([revealer, arrow, open_revealers]() {
336 bool opening = !revealer->get_reveal_child();
337 // Chiudi tutti gli altri
338 for (auto* r : *open_revealers) {
339 if (r != revealer && r->get_reveal_child()) {
340 r->set_reveal_child(false);
341 // Aggiorna la freccia del revealer che stiamo chiudendo
342 // (non abbiamo accesso diretto alla freccia degli altri,
343 // ma il CSS transition lo gestisce visivamente)
344 }
345 }
346 revealer->set_reveal_child(opening);
347 arrow->set_text(opening ? "▾" : "▸");
348 });
349
350 sidebar_box->append(*hbtn);
351 sidebar_box->append(*revealer);
352 return children;
353 };
354
355 // ═══════════════════════════════════════════════════════════════════
356 // Dashboard
357 // ═══════════════════════════════════════════════════════════════════
358 auto* db_btn = make_leaf(resource("icons/dashboard.svg"), _("Dashboard"), "dashboard");
359 dashboard_button_ = db_btn;
360 sidebar_box->append(*db_btn);
361
362 // ═══════════════════════════════════════════════════════════════════
363 // Gruppo: Protezione
364 // ═══════════════════════════════════════════════════════════════════
365 auto* grp_prot = make_group(resource("icons/scan.svg"), _("Protezione"));
366 grp_prot->append(*make_leaf(resource("icons/scan.svg"), _("Scansione in tempo reale"), "scan", true));
367 grp_prot->append(*make_leaf(resource("icons/ransomware.svg"), _("Protezione Ransomware"), "antiransomware", true));
368#if BASTIONGUARD_HAS_CEF
370 grp_prot->append(*make_leaf(resource("icons/bank.svg"), _("Banche"), "bank", true));
371 }
372#endif
373 grp_prot->append(*make_leaf(resource("icons/privacy.svg"), _("Privacy Webcam"), "privacy", true));
374 grp_prot->append(*make_leaf(resource("icons/rootguard.svg"), _("RootGuard"), "rootguard", true));
375 grp_prot->append(*make_leaf(resource("icons/usb.svg"), _("Periferiche USB"), "usbscan", true));
376 grp_prot->append(*make_leaf(resource("icons/samba.svg"), _("Samba"), "samba", true));
377
378 // ═══════════════════════════════════════════════════════════════════
379 // Gruppo: Sicurezza
380 // ═══════════════════════════════════════════════════════════════════
381 auto* grp_sec = make_group(resource("icons/log.svg"), _("Sicurezza"));
382 grp_sec->append(*make_leaf(resource("icons/log.svg"), _("Log"), "log", true));
383 grp_sec->append(*make_leaf(resource("icons/quarantine.svg"), _("Quarantena"), "quarantine", true));
384 grp_sec->append(*make_leaf(resource("icons/identity.svg"), _("Violazioni Identità"), "identityleak", true));
385 grp_sec->append(*make_leaf(resource("icons/password.svg"), _("Password Manager"), "passwordmanager", true));
386 grp_sec->append(*make_leaf(resource("icons/backup.svg"), _("Backup"), "backup", true));
387 grp_sec->append(*make_leaf(resource("icons/update.svg"), _("Aggiornamenti"), "update", true));
388
389 // ═══════════════════════════════════════════════════════════════════
390 // Phishing (voce singola)
391 // ═══════════════════════════════════════════════════════════════════
392 sidebar_box->append(*make_leaf(resource("icons/phishing.svg"), _("Phishing Search"), "phishing"));
393
394 // ═══════════════════════════════════════════════════════════════════
395 // VPN (voce singola)
396 // ═══════════════════════════════════════════════════════════════════
397 sidebar_box->append(*make_leaf(resource("icons/vpn.svg"), _("VPN WireGuard"), "vpn"));
398
399 // ═══════════════════════════════════════════════════════════════════
400 // Impostazioni (apre finestra separata)
401 // ═══════════════════════════════════════════════════════════════════
402 {
403 auto box = Gtk::make_managed<Gtk::Box>(Gtk::Orientation::HORIZONTAL, 6);
404 auto ib = Gtk::make_managed<Gtk::Box>(Gtk::Orientation::VERTICAL);
405 ib->set_size_request(16, 16);
406 ib->set_valign(Gtk::Align::CENTER);
407 auto pic = Gtk::make_managed<Gtk::Picture>();
408 try {
409 auto pb = Gdk::Pixbuf::create_from_file(resource("icons/settings.svg"));
410 auto sc = pb->scale_simple(16, 16, Gdk::InterpType::BILINEAR);
411 pic->set_paintable(Gdk::Texture::create_for_pixbuf(sc));
412 } catch (...) {}
413 ib->append(*pic);
414 box->append(*ib);
415 auto lbl = Gtk::make_managed<Gtk::Label>(_("Impostazioni"));
416 lbl->set_halign(Gtk::Align::START);
417 box->append(*lbl);
418 auto btn = Gtk::make_managed<Gtk::Button>();
419 btn->set_child(*box);
420 btn->get_style_context()->add_class("sidebar-button");
421 btn->signal_clicked().connect([this]() { open_settings_window(); });
422 sidebar_box->append(*btn);
423 }
424
425 // Spacer + separatore
426 auto spacer = Gtk::make_managed<Gtk::Box>(Gtk::Orientation::VERTICAL);
427 spacer->set_vexpand(true);
428 sidebar_box->append(*spacer);
429
430 auto sep = Gtk::make_managed<Gtk::Separator>(Gtk::Orientation::HORIZONTAL);
431 sep->get_style_context()->add_class("sidebar-separator");
432 sidebar_box->append(*sep);
433
434 sidebar_box->append(*make_leaf(resource("icons/about.svg"), _("Informazioni"), "about"));
435 sidebar_box->append(*make_leaf(resource("icons/donate.svg"), _("Donazioni"), "donate"));
436
437 mainBox.append(*sidebar_box);
438}
void open_settings_window()

References _, BastionGuard::Platform::cef_available(), dashboard_button_, mainBox, open_settings_window(), resource(), sidebar_buttons_, and stack_.

Referenced by build_headerbar(), and MainWindow().

◆ build_wizard()

void MainWindow::build_wizard ( )
private

Definition at line 452 of file main_window.cpp.

452 {
453 wizard_frame_.add_css_class("card");
454 wizard_root_.set_margin_top(14);
455 wizard_root_.set_margin_bottom(14);
456 wizard_root_.set_margin_start(14);
457 wizard_root_.set_margin_end(14);
458
459 source_step_label_.set_wrap(true);
460 source_step_label_.set_xalign(0.0f);
464 recovery_devices_scroller_.set_policy(Gtk::PolicyType::AUTOMATIC, Gtk::PolicyType::AUTOMATIC);
465 recovery_devices_scroller_.set_vexpand(true);
470
471 destination_step_label_.set_wrap(true);
472 destination_step_label_.set_xalign(0.0f);
473 entry_output_.set_hexpand(true);
474 entry_output_.set_editable(false);
479
480 wizard_notice_label_.set_wrap(true);
481 wizard_notice_label_.set_xalign(0.0f);
482 wizard_notice_label_.add_css_class("alert-danger");
483 wizard_notice_label_.set_text(tr("Avviso: non si garantisce il recupero totale dei file. La quantità e l'integrità dei dati recuperati dipendono da danni al filesystem, sovrascritture, frammentazione, cifratura, compressione e stato del dispositivo."));
484
485 scan_step_label_.set_wrap(true);
486 scan_step_label_.set_xalign(0.0f);
487 scan_progress_bar_.set_show_text(true);
488 scan_progress_bar_.set_fraction(0.0);
489 scan_progress_bar_.set_hexpand(true);
490 scan_status_label_.set_xalign(0.0f);
491 scan_status_label_.add_css_class("small-label");
492 scan_timer_label_.set_xalign(0.0f);
493 scan_timer_label_.add_css_class("small-label");
494 scan_timer_label_.set_text(tr("Elapsed: 00:00"));
500
501 recover_step_label_.set_wrap(true);
502 recover_step_label_.set_xalign(0.0f);
503
504 results_count_label_.set_halign(Gtk::Align::START);
505 results_count_label_.set_xalign(0.0f);
506 results_count_label_.add_css_class("small-label");
507 results_count_label_.set_margin_bottom(2);
508
509 results_selected_label_.set_halign(Gtk::Align::START);
510 results_selected_label_.set_xalign(0.0f);
511 results_selected_label_.add_css_class("small-label");
512 results_selected_label_.set_margin_bottom(6);
513
514 btn_results_select_all_.add_css_class("sidebar-button");
515 btn_results_clear_.add_css_class("sidebar-button");
518
519 results_tree_box_.add_css_class("scan-file-list");
520
521 results_scroller_.set_policy(Gtk::PolicyType::AUTOMATIC, Gtk::PolicyType::AUTOMATIC);
522 results_scroller_.set_vexpand(true);
524
525 results_frame_.set_label(tr("Detected items"));
526 results_frame_.add_css_class("card");
527 results_frame_.set_vexpand(true);
528
529 auto* results_inner = Gtk::make_managed<Gtk::Box>(Gtk::Orientation::VERTICAL, 6);
530 results_inner->set_margin_top(10);
531 results_inner->set_margin_bottom(10);
532 results_inner->set_margin_start(10);
533 results_inner->set_margin_end(10);
534 results_inner->append(results_count_label_);
535 results_inner->append(results_selected_label_);
536 results_inner->append(results_actions_row_);
537 results_inner->append(results_scroller_);
538 results_frame_.set_child(*results_inner);
539
540 btn_recover_now_.add_css_class("btn-primary");
541 btn_recover_now_.set_halign(Gtk::Align::END);
542
546
547 wizard_stack_.add(source_step_box_, "wizard-source", tr("Source"));
548 wizard_stack_.add(destination_step_box_, "wizard-destination", tr("Destination"));
549 wizard_stack_.add(scan_step_box_, "wizard-scan", tr("Scan"));
550 wizard_stack_.add(recover_step_box_, "wizard-recover", tr("Recover"));
551 wizard_stack_.set_visible_child(source_step_box_);
552 wizard_stack_.set_hexpand(true);
553 wizard_stack_.set_vexpand(true);
554
555 btn_wizard_back_.add_css_class("sidebar-button");
556 btn_wizard_next_.add_css_class("btn-primary");
558 auto* spacer = Gtk::make_managed<Gtk::Box>(Gtk::Orientation::HORIZONTAL);
559 spacer->set_hexpand(true);
560 wizard_nav_.append(*spacer);
562
566 wizard_frame_.set_child(wizard_root_);
567}
Gtk::Button btn_wizard_back_
Gtk::Button btn_open_image_
Gtk::Label wizard_notice_label_
Gtk::Button btn_choose_destination_
Gtk::Label results_selected_label_
Gtk::Button btn_recover_now_
Gtk::Entry entry_output_
Gtk::Button btn_launch_elevated_
Gtk::Button btn_use_selected_device_
Gtk::ListBox recovery_devices_list_
Gtk::Box destination_step_box_
Gtk::Button btn_scan_now_
Gtk::Box results_tree_box_
Gtk::Label scan_timer_label_
Gtk::Button btn_results_clear_
Gtk::Box recover_step_box_
Gtk::Box wizard_nav_
Gtk::ProgressBar scan_progress_bar_
Gtk::Stack wizard_stack_
Gtk::Box results_actions_row_
Gtk::Label results_count_label_
Gtk::Frame results_frame_
Gtk::ScrolledWindow results_scroller_
Gtk::Box source_step_box_
Gtk::Label recover_step_label_
Gtk::Label scan_status_label_
Gtk::Button btn_results_select_all_
Gtk::Label destination_step_label_
Gtk::ScrolledWindow recovery_devices_scroller_
Gtk::Box destination_button_row_
Gtk::Label source_step_label_
Gtk::Box source_button_row_
Gtk::Button btn_wizard_next_
Gtk::Box scan_step_box_
Gtk::Box wizard_root_
Gtk::Label scan_step_label_

References btn_choose_destination_, btn_launch_elevated_, btn_open_image_, btn_recover_now_, btn_results_clear_, btn_results_select_all_, btn_scan_now_, btn_use_selected_device_, btn_wizard_back_, btn_wizard_next_, destination_button_row_, destination_step_box_, destination_step_label_, entry_output_, recover_step_box_, recover_step_label_, recovery_devices_list_, recovery_devices_scroller_, results_actions_row_, results_count_label_, results_frame_, results_scroller_, results_selected_label_, results_tree_box_, scan_progress_bar_, scan_status_label_, scan_step_box_, scan_step_label_, scan_timer_label_, source_button_row_, source_step_box_, source_step_label_, tr(), wizard_frame_, wizard_nav_, wizard_notice_label_, wizard_root_, and wizard_stack_.

Referenced by build_headerbar(), and build_recovery_page().

◆ buildHeaderBar()

void MainWindow::buildHeaderBar ( )
private

Definition at line 470 of file MainWindow.cpp.

471{
472 auto header = Gtk::make_managed<Gtk::HeaderBar>();
473 header->set_show_title_buttons(false);
474 header->set_decoration_layout("");
475 header->get_style_context()->add_class("custom-headerbar");
476
477 auto headerLeft = Gtk::make_managed<Gtk::Box>(Gtk::Orientation::HORIZONTAL);
478 headerLeft->set_size_request(240, -1);
479 headerLeft->set_hexpand(false);
480 headerLeft->get_style_context()->add_class("header-left");
481 header->pack_start(*headerLeft);
482
483 auto spacer = Gtk::make_managed<Gtk::Box>(Gtk::Orientation::HORIZONTAL);
484 spacer->set_hexpand(true);
485 header->pack_start(*spacer);
486
487 auto headerRight = Gtk::make_managed<Gtk::Box>(Gtk::Orientation::HORIZONTAL, 4);
488 headerRight->set_hexpand(false);
489 headerRight->get_style_context()->add_class("header-right");
490
491 // ── Bottone selezione lingua ────────────────────────────────────────
492 auto btnLang = Gtk::make_managed<Gtk::Button>("🌐");
493 btnLang->get_style_context()->add_class("theme-btn");
494 btnLang->set_tooltip_text(_("Cambia lingua"));
495 btnLang->signal_clicked().connect(
496 sigc::mem_fun(*this, &MainWindow::showLanguageDialog));
497 headerRight->append(*btnLang);
498
499 // ── Tema ────────────────────────────────────────────────────────────
500 m_btnLight = Gtk::make_managed<Gtk::Button>("☀");
501 m_btnDark = Gtk::make_managed<Gtk::Button>("🌙");
502
503 m_btnLight->get_style_context()->add_class("theme-btn");
504 m_btnDark->get_style_context()->add_class("theme-btn");
505
506 m_btnLight->set_tooltip_text(_("Tema chiaro"));
507 m_btnDark->set_tooltip_text(_("Tema scuro"));
508
509 if (m_darkMode)
510 m_btnDark->get_style_context()->add_class("theme-btn-active");
511 else
512 m_btnLight->get_style_context()->add_class("theme-btn-active");
513
514 m_btnLight->signal_clicked().connect([this]() { applyTheme(false); });
515 m_btnDark->signal_clicked().connect([this]() { applyTheme(true); });
516
517 headerRight->append(*m_btnLight);
518 headerRight->append(*m_btnDark);
519
520 auto addWinBtn = [&](const std::string& iconRes,
521 const std::string& fallback,
522 auto cb)
523 {
524 auto btn = Gtk::make_managed<Gtk::Button>();
525 btn->get_style_context()->add_class("header-button");
526
527 try {
528 auto pix = Gdk::Pixbuf::create_from_file(resource(iconRes), 32, 32, true);
529 btn->set_child(*Gtk::make_managed<Gtk::Image>(pix));
530 } catch (...) {
531 btn->set_label(fallback);
532 }
533
534 btn->signal_clicked().connect(cb);
535 headerRight->append(*btn);
536 };
537
538 addWinBtn("icon-minimize.png", "—", [this]() { minimize(); });
539 addWinBtn("icon-close.png", "✕", [this]() { hide(); });
540
541 header->pack_end(*headerRight);
542 set_titlebar(*header);
543}
void applyTheme(bool dark)
void showLanguageDialog()

References _, applyTheme(), m_btnDark, m_btnLight, m_darkMode, minimize(), resource(), and showLanguageDialog().

◆ buildSidebar()

void MainWindow::buildSidebar ( )
private

Definition at line 549 of file MainWindow.cpp.

550{
551 auto sidebar = Gtk::make_managed<Gtk::Box>(Gtk::Orientation::VERTICAL, 10);
552 sidebar->set_size_request(240, -1);
553 sidebar->set_hexpand(false);
554 sidebar->set_vexpand(true);
555 sidebar->get_style_context()->add_class("sidebar");
556
557 // Header logo + titolo
558 {
559 auto hdr = Gtk::make_managed<Gtk::Box>(Gtk::Orientation::HORIZONTAL, 8);
560 hdr->set_hexpand(false);
561 hdr->get_style_context()->add_class("sidebar-header");
562
563 auto ico = Gtk::make_managed<Gtk::Image>();
564 try {
565 auto pix = Gdk::Pixbuf::create_from_file(
566 resource("logo-sidebar.png"), 32, 32, true);
567 ico->set(pix);
568 } catch (...) {
569 ico->set_from_icon_name("security-high-symbolic");
570 ico->set_pixel_size(28);
571 }
572
573 ico->set_hexpand(false);
574 hdr->append(*ico);
575
576 auto lbl = Gtk::make_managed<Gtk::Label>(
577 "BastionGuard™\nSecure Connection");
578 lbl->set_justify(Gtk::Justification::LEFT);
579 lbl->set_wrap(true);
580 lbl->set_max_width_chars(16);
581 lbl->set_width_chars(16);
582 lbl->get_style_context()->add_class("sidebar-title");
583 lbl->set_halign(Gtk::Align::START);
584 lbl->set_hexpand(false);
585 hdr->append(*lbl);
586
587 sidebar->append(*hdr);
588 }
589
590 sidebar->append(*makeSidebarButton(
591 resource("icons/connections.svg"), _("Connessioni"), "connections"));
592 sidebar->append(*makeSidebarButton(
593 resource("icons/apps.svg"), _("Applicazioni"), "apps"));
594 sidebar->append(*makeSidebarButton(
595 resource("icons/network.svg"), _("Monitor di rete"), "network"));
596 sidebar->append(*makeSidebarButton(
597 resource("icons/rules.svg"), _("Regole"), "rules"));
598 sidebar->append(*makeSidebarButton(
599 resource("icons/stats.svg"), _("Statistiche"), "stats"));
600 sidebar->append(*makeSidebarButton(
601 resource("icons/about.svg"), _("Impostazioni"), "settings"));
602
603 sidebar->append(*makeSidebarButton(
604 resource("icons/about.svg"), _("Informazioni"), "about"));
605
606 auto spacer = Gtk::make_managed<Gtk::Box>(Gtk::Orientation::VERTICAL);
607 spacer->set_vexpand(true);
608 sidebar->append(*spacer);
609
610 auto sep = Gtk::make_managed<Gtk::Separator>(Gtk::Orientation::HORIZONTAL);
611 sep->get_style_context()->add_class("sidebar-separator");
612 sidebar->append(*sep);
613
614 m_daemonLabel = Gtk::make_managed<Gtk::Label>(_("⚙ Daemon: in attesa..."));
615 m_daemonLabel->get_style_context()->add_class("daemon-status");
616 m_daemonLabel->set_halign(Gtk::Align::START);
617 m_daemonLabel->set_margin_top(6);
618 m_daemonLabel->set_margin_start(8);
619 m_daemonLabel->set_margin_bottom(6);
620 sidebar->append(*m_daemonLabel);
621
622 m_mainBox.append(*sidebar);
623}
Gtk::Box m_mainBox
Gtk::Button * makeSidebarButton(const std::string &iconPath, const std::string &label, const std::string &pageName)
Gtk::Label * m_daemonLabel

References _, m_daemonLabel, m_mainBox, makeSidebarButton(), and resource().

◆ cacheKey()

std::string MainWindow::cacheKey ( const std::string & app,
const std::string & host,
const std::string & ip )
staticprivate

Definition at line 808 of file MainWindow.cpp.

811{
812 return app + "|" + host + "|" + ip;
813}

Referenced by onNewConnection(), and onVerdict().

◆ check_if_deletion_running()

bool MainWindow.check_if_deletion_running ( )
inlineprivate

Definition at line 1248 of file MainWindow.vala.

1248 {
1250 ui_sensitive(true);
1251 gtk_messagebox(_("Snapshot deletion in progress..."), _("Please wait."), this, true);
1252 ui_sensitive(false);
1254 return true;
1255 }
1256 return false;
1257 }
void open_delete_flow()
void ui_sensitive(bool enable)
bool thread_delete_running
Definition Main.vala:108

References _, App, open_delete_flow(), Main.thread_delete_running, and ui_sensitive().

Referenced by btn_restore_clicked(), and create_snapshot().

◆ create_snapshot()

void MainWindow.create_snapshot ( )
inline

Definition at line 1152 of file MainWindow.vala.

1152 {
1153 if (check_if_deletion_running()) return;
1154 ui_sensitive(false);
1155 if (App.btrfs_mode && (App.check_btrfs_layout_system(this) == false)) {
1156 ui_sensitive(true); return;
1157 }
1158 if (!App.repo.available())
1159 gtk_messagebox(App.repo.status_message, App.repo.status_details, this, true);
1161 }
void open_backup_flow()
bool check_btrfs_layout_system(Gtk.Window? win=null)
Definition Main.vala:480
string status_details
string status_message

References App, SnapshotRepo.available(), Main.btrfs_mode, Main.check_btrfs_layout_system(), check_if_deletion_running(), open_backup_flow(), Main.repo, SnapshotRepo.status_details, SnapshotRepo.status_message, and ui_sensitive().

Referenced by init_snapshots_page().

◆ delete_selected()

void MainWindow.delete_selected ( )
inline

Definition at line 1163 of file MainWindow.vala.

1163 {
1164 if (!App.repo.available()) {
1165 gtk_messagebox(App.repo.status_message, _("Select another device"), this, false);
1166 return;
1167 }
1168 if (!App.repo.has_snapshots()) {
1169 gtk_messagebox(_("No snapshots on device"), _("Select another device"), this, false);
1170 return;
1171 }
1172 foreach (var bak in snapshot_list_box.selected_snapshots()) {
1173 if (bak.live) {
1174 gtk_messagebox(_("Cannot Delete Live Snapshot"),
1175 _("Snapshot '%s' is in use").printf(bak.date_formatted), this, false);
1176 return;
1177 }
1178 }
1179 var dlg = new Gtk.MessageDialog(this, Gtk.DialogFlags.MODAL,
1180 Gtk.MessageType.QUESTION, Gtk.ButtonsType.YES_NO,
1181 _("Are you sure you want to delete this snapshot?"));
1182 var resp = gtk_dialog_run(dlg); dlg.destroy();
1183 if (resp != Gtk.ResponseType.YES) return;
1185 foreach (var item in snapshot_list_box.selected_snapshots()) {
1186 bool dup = false;
1187 foreach (var bak in App.delete_list) {
1188 if (bak.name == item.name) { dup = true; break; }
1189 }
1190 if (!dup) App.delete_list.add(item);
1191 }
1192 }
1193 ui_sensitive(false);
1195 }
Gee.ArrayList< Snapshot > delete_list
Definition Main.vala:133
int gtk_dialog_run(Gtk.Dialog dlg)

References _, App, SnapshotRepo.available(), Main.delete_list, TeeJee.GtkHelper.gtk_dialog_run(), SnapshotRepo.has_snapshots(), open_delete_flow(), Main.repo, SnapshotListBox.selected_snapshots(), snapshot_list_box, SnapshotRepo.status_message, Main.thread_delete_running, and ui_sensitive().

Referenced by init_snapshots_page().

◆ hide_window()

void MainWindow::hide_window ( )
private

Definition at line 1321 of file main_window.cpp.

1321 {
1322 set_visible(false);
1323}

Referenced by on_language_changed().

◆ human_size()

std::string MainWindow::human_size ( uint64_t bytes)
staticprivate

Definition at line 1560 of file main_window.cpp.

1560 {
1561 const char* units[] = {"B", "KiB", "MiB", "GiB", "TiB"};
1562 double value = static_cast<double>(bytes);
1563 int unit_index = 0;
1564
1565 while (value >= 1024.0 && unit_index < 4) {
1566 value /= 1024.0;
1567 ++unit_index;
1568 }
1569
1570 std::ostringstream oss;
1571 oss << std::fixed << std::setprecision(2) << value << ' ' << units[unit_index];
1572 return oss.str();
1573}

Referenced by on_dashboard_device_activated(), on_language_changed(), on_use_selected_device(), populate_device_lists(), and populate_scan_results().

◆ init_about_page()

void MainWindow.init_about_page ( )
inlineprivate

Definition at line 820 of file MainWindow.vala.

820 {
821 var page = new Gtk.Box(Orientation.VERTICAL, 0);
822 page.hexpand = true;
823 page.vexpand = true;
824 page.halign = Gtk.Align.FILL;
825 page.valign = Gtk.Align.FILL;
826
827 var title = new Gtk.Label(_("Informazioni su BastionGuard Backup"));
828 title.xalign = 0;
829 title.get_style_context().add_class("page-title");
830 title.margin_start = 20;
831 title.margin_top = 20;
832 title.margin_bottom = 12;
833 page.append(title);
834
835 var card = make_card(true);
836 card.margin_start = 14;
837 card.margin_end = 14;
838 card.margin_bottom = 16;
839 page.append(card);
840
841 var body = new Gtk.Box(Orientation.VERTICAL, 10);
842 body.margin_start = 12;
843 body.margin_end = 12;
844 body.margin_top = 12;
845 body.margin_bottom = 12;
846 card.append(body);
847
848 body.append(IconManager.lookup_image("bastionguard-backup", 96));
849
850 var lbl_title = new Gtk.Label("BastionGuard™ Backup");
851 lbl_title.xalign = 0.5f;
852 lbl_title.wrap = true;
853 lbl_title.get_style_context().add_class("title");
854 body.append(lbl_title);
855
856 var lbl_version = new Gtk.Label(AppVersion);
857 lbl_version.xalign = 0.5f;
858 body.append(lbl_version);
859
860 var lbl_desc = new Gtk.Label("Fork di Timeshift con shell UI a pagina singola e sidebar persistente.");
861 lbl_desc.xalign = 0.5f;
862 lbl_desc.wrap = true;
863 lbl_desc.set_justify(Gtk.Justification.CENTER);
864 body.append(lbl_desc);
865
866 var link = new Gtk.LinkButton.with_label("https://bastionguard.eu", "bastionguard.eu");
867 link.set_halign(Gtk.Align.CENTER);
868 link.activate_link.connect(() => {
869 TeeJee.System.xdg_open("https://bastionguard.eu");
870 return true;
871 });
872 body.append(link);
873
874 var lbl_copy = new Gtk.Label("© 2025–2026 BastionGuard™. All Rights Reserved.");
875 lbl_copy.xalign = 0.5f;
876 lbl_copy.wrap = true;
877 lbl_copy.set_justify(Gtk.Justification.CENTER);
878 body.append(lbl_copy);
879
880 var lbl_tm = new Gtk.Label("BastionGuard was filed by Calogero Scarnà with the Italian Patent and Trademark Office (UIBM) on 16/12/2025 – Application No. 302025000196519.
881The BastionGuard™ name and branding are not licensed under the GPLv3.");
882 lbl_tm.xalign = 0.5f;
883 lbl_tm.wrap = true;
884 lbl_tm.set_justify(Gtk.Justification.CENTER);
885 body.append(lbl_tm);
886
887 var lbl_license = new Gtk.Label(_("BastionGuard Backup is a fork of Timeshift by Tony George.
888This program is free software licensed under GNU GPL v2 or later."));
889 lbl_license.xalign = 0.5f;
890 lbl_license.wrap = true;
891 lbl_license.set_justify(Gtk.Justification.CENTER);
892 body.append(lbl_license);
893
894 var filler = new Gtk.Box(Orientation.VERTICAL, 0);
895 filler.vexpand = true;
896 page.append(filler);
897
898 about_page_widget = page;
899 content_stack.add_named(about_page_widget, "about");
900 }
Gtk.Box make_card(bool hexpand)
Gtk.? Widget about_page_widget

References _, about_page_widget, content_stack, IconManager.lookup_image(), and make_card().

Referenced by init_content().

◆ init_content()

void MainWindow.init_content ( )
inlineprivate

Definition at line 906 of file MainWindow.vala.

906 {
907 var vbox_content = new Gtk.Box(Orientation.VERTICAL, 0);
908 vbox_content.hexpand = true;
909 vbox_content.vexpand = false;
910 vbox_content.halign = Gtk.Align.FILL;
911 vbox_content.valign = Gtk.Align.FILL;
912 hbox_root.append(vbox_content);
913
914 content_stack = new Gtk.Stack();
915 content_stack.hexpand = true;
916 content_stack.vexpand = false;
917 content_stack.set_hhomogeneous(false);
918 content_stack.set_vhomogeneous(false);
919 content_stack.halign = Gtk.Align.FILL;
920 content_stack.valign = Gtk.Align.FILL;
921 content_stack.transition_type = Gtk.StackTransitionType.CROSSFADE;
922 content_stack.transition_duration = 160;
923 vbox_content.append(content_stack);
924
929 }
void init_snapshots_page()
void init_settings_page()
void init_wizard_page()
void init_about_page()

References content_stack, hbox_root, init_about_page(), init_settings_page(), init_snapshots_page(), and init_wizard_page().

Referenced by MainWindow().

◆ init_delayed()

bool MainWindow.init_delayed ( )
inlineprivate

Definition at line 1103 of file MainWindow.vala.

1103 {
1104 if (tmr_init > 0) { Source.remove(tmr_init); tmr_init = 0; }
1105 if ((App.repo == null) || !App.repo.available()) {
1106 if (App.backup_parent_uuid.length > 0)
1107 App.repo = new SnapshotRepo.from_uuid(App.backup_parent_uuid, this, App.btrfs_mode);
1108 }
1109 refresh_all();
1111 return false;
1112 }
bool refresh_all()
void btn_wizard_clicked()
bool first_run
Definition Main.vala:47
string backup_parent_uuid
Definition Main.vala:50

References App, SnapshotRepo.available(), Main.backup_parent_uuid, btn_wizard_clicked(), Main.btrfs_mode, Main.first_run, SnapshotRepo.from_uuid(), refresh_all(), Main.repo, and tmr_init.

Referenced by MainWindow().

◆ init_settings_page()

void MainWindow.init_settings_page ( )
inlineprivate

Definition at line 801 of file MainWindow.vala.

801 {
803 embedded_settings.request_close.connect(() => {
805 });
807 content_stack.add_named(settings_page_widget, "settings_page");
808 }
void show_snapshots_page()
SettingsWindow? embedded_settings
Gtk.? Widget settings_page_widget
Gtk.Widget detach_root_widget()
signal void request_close()
SettingsWindow(ClamdConfig &config)

References content_stack, SettingsWindow.detach_root_widget(), embedded_settings, SettingsWindow.request_close(), settings_page_widget, SettingsWindow.SettingsWindow(), and show_snapshots_page().

Referenced by init_content().

◆ init_sidebar()

void MainWindow.init_sidebar ( )
inlineprivate

Definition at line 508 of file MainWindow.vala.

508 {
509
510 vbox_sidebar = new Gtk.Box(Orientation.VERTICAL, 0);
511 vbox_sidebar.set_size_request(180, -1);
512 vbox_sidebar.get_style_context().add_class("sidebar");
513 vbox_sidebar.hexpand = false;
514 vbox_sidebar.vexpand = true;
515 vbox_sidebar.halign = Gtk.Align.FILL;
516 vbox_sidebar.valign = Gtk.Align.FILL;
517 hbox_root.append(vbox_sidebar);
518
519 var header_box = new Gtk.Box(Orientation.HORIZONTAL, 8);
520 header_box.get_style_context().add_class("sidebar-header");
521 vbox_sidebar.append(header_box);
522
523 var logo = IconManager.lookup_image("bastionguard-backup", 32);
524 header_box.append(logo);
525
526 var title_lbl = new Gtk.Label("BastionGuard™\nBackup");
527 title_lbl.xalign = 0;
528 title_lbl.get_style_context().add_class("sidebar-title");
529 header_box.append(title_lbl);
530
531 vbox_sidebar.append(new Gtk.Box(Orientation.VERTICAL, 0));
532
533 btn_nav_snapshots = make_nav_btn("document-save-symbolic", _("Snapshot"), "snapshots");
534 btn_nav_settings = make_nav_btn("preferences-system-symbolic", _("Impostazioni"), "settings_page");
535 btn_nav_wizard = make_nav_btn("emblem-default-symbolic", _("Procedura guidata"), "wizard");
536
537 var spacer = new Gtk.Box(Orientation.VERTICAL, 0);
538 spacer.vexpand = true;
539 vbox_sidebar.append(spacer);
540
541 // Theme section
542 var theme_sep = new Gtk.Separator(Orientation.HORIZONTAL);
543 theme_sep.margin_top = 6;
544 theme_sep.margin_bottom = 6;
545 theme_sep.margin_start = 8;
546 theme_sep.margin_end = 8;
547 vbox_sidebar.append(theme_sep);
548
549 var theme_title = new Gtk.Label(_("Theme"));
550 theme_title.xalign = 0;
551 theme_title.margin_start = 18;
552 theme_title.margin_end = 18;
553 theme_title.margin_top = 4;
554 theme_title.margin_bottom = 6;
555 vbox_sidebar.append(theme_title);
556
557 var theme_box = new Gtk.Box(Orientation.HORIZONTAL, 6);
558 theme_box.margin_start = 10;
559 theme_box.margin_end = 10;
560 theme_box.margin_bottom = 8;
561 vbox_sidebar.append(theme_box);
562
563 btn_theme_light = make_theme_btn("weather-clear-symbolic", _("Chiaro"));
564 btn_theme_light.clicked.connect(() => { apply_theme(false); });
565 theme_box.append(btn_theme_light);
566
567 btn_theme_dark = make_theme_btn("weather-clear-night-symbolic", _("Scuro"));
568 btn_theme_dark.clicked.connect(() => { apply_theme(true); });
569 theme_box.append(btn_theme_dark);
570
571 // ── Language selector ──────────────────────────────────────────
572 var lang_sep = new Gtk.Separator(Orientation.HORIZONTAL);
573 lang_sep.margin_top = 6;
574 lang_sep.margin_bottom = 6;
575 lang_sep.margin_start = 8;
576 lang_sep.margin_end = 8;
577 vbox_sidebar.append(lang_sep);
578
579 var lang_title = new Gtk.Label(_("Language"));
580 lang_title.xalign = 0;
581 lang_title.margin_start = 18;
582 lang_title.margin_end = 18;
583 lang_title.margin_top = 2;
584 lang_title.margin_bottom = 4;
585 vbox_sidebar.append(lang_title);
586
587 lang_combo = new Gtk.ComboBoxText();
588 lang_combo.margin_start = 10;
589 lang_combo.margin_end = 10;
590 lang_combo.margin_bottom = 8;
591 lang_combo.get_style_context().add_class("sidebar-combo");
592
593 int active_idx = 0;
594 for (int i = 0; i < LANG_CODES.length; i++) {
595 lang_combo.append_text(LANG_NAMES[i]);
596 if (LANG_CODES[i] == current_lang) active_idx = i;
597 }
598 lang_combo.set_active(active_idx);
599 lang_combo.changed.connect(on_language_changed);
600 vbox_sidebar.append(lang_combo);
601 // ──────────────────────────────────────────────────────────────
602
603 var sep = new Gtk.Separator(Orientation.HORIZONTAL);
604 sep.margin_top = 6;
605 sep.margin_bottom = 6;
606 sep.margin_start = 8;
607 sep.margin_end = 8;
608 vbox_sidebar.append(sep);
609
610 btn_nav_about = make_nav_btn("help-about-symbolic", _("Informazioni"), "about");
611
613 }
Gtk.Button btn_nav_wizard
Gtk.? Button btn_theme_dark
Gtk.? Button btn_theme_light
Gtk.Box vbox_sidebar
Gtk.Button make_nav_btn(string icon, string label, string page)
static string[] LANG_NAMES
static string[] LANG_CODES
Gtk.Button btn_nav_about
Gtk.Button btn_nav_settings
Gtk.Button make_theme_btn(string icon, string label)
void apply_theme(bool use_dark)
Gtk.? ComboBoxText lang_combo

References _, apply_theme(), btn_nav_about, btn_nav_settings, btn_nav_snapshots, btn_nav_wizard, btn_theme_dark, btn_theme_light, current_lang, hbox_root, LANG_CODES, lang_combo, LANG_NAMES, IconManager.lookup_image(), make_nav_btn(), make_theme_btn(), on_language_changed(), update_theme_buttons(), and vbox_sidebar.

Referenced by MainWindow().

◆ init_snapshots_page()

void MainWindow.init_snapshots_page ( )
inlineprivate

Definition at line 931 of file MainWindow.vala.

931 {
932
933 var vbox = new Gtk.Box(Orientation.VERTICAL, 0);
934 content_stack.add_named(vbox, "snapshots");
935 vbox.hexpand = true;
936 vbox.vexpand = false;
937 vbox.halign = Gtk.Align.FILL;
938 vbox.valign = Gtk.Align.FILL;
939
940 var page_title = new Gtk.Label(_("Snapshots"));
941 page_title.xalign = 0;
942 page_title.get_style_context().add_class("page-title");
943 page_title.margin_start = 14;
944 page_title.margin_top = 8;
945 page_title.margin_bottom = 6;
946 vbox.append(page_title);
947
948 var cards_box = new Gtk.Box(Orientation.HORIZONTAL, 0);
949 cards_box.margin_start = 14;
950 cards_box.margin_end = 14;
951 cards_box.margin_bottom = 6;
952 vbox.append(cards_box);
953
954 var card_status = make_card(true);
955 cards_box.append(card_status);
956
957 var status_inner = new Gtk.Box(Orientation.HORIZONTAL, 12);
958 card_status.append(status_inner);
959
960 img_shield = new Gtk.Image();
961 img_shield.set_from_pixbuf(IconManager.lookup(
962 IconManager.SHIELD_HIGH, 48));
963 status_inner.append(img_shield);
964
965 var status_text = new Gtk.Box(Orientation.VERTICAL, 2);
966 status_inner.append(status_text);
967
968 lbl_status_title = new Gtk.Label("—");
969 lbl_status_title.xalign = 0;
970 lbl_status_title.get_style_context().add_class("title");
971 lbl_status_title.wrap = true;
972 status_text.append(lbl_status_title);
973
974 lbl_status_detail = new Gtk.Label("");
975 lbl_status_detail.xalign = 0;
976 lbl_status_detail.wrap = true;
977 status_text.append(lbl_status_detail);
978
979 var card_snaps = make_card(false);
980 card_snaps.set_size_request(150, -1);
981 cards_box.append(card_snaps);
982
983 var snaps_hdr = new Gtk.Label(_("Snapshots"));
984 snaps_hdr.xalign = 0;
985 card_snaps.append(snaps_hdr);
986
987 lbl_snap_count = new Gtk.Label("0");
988 lbl_snap_count.xalign = 0;
989 lbl_snap_count.get_style_context().add_class("title");
990 card_snaps.append(lbl_snap_count);
991
992 var card_space = make_card(false);
993 card_space.set_size_request(170, -1);
994 cards_box.append(card_space);
995
996 var space_hdr = new Gtk.Label(_("Free space"));
997 space_hdr.xalign = 0;
998 card_space.append(space_hdr);
999
1000 lbl_free_space = new Gtk.Label("—");
1001 lbl_free_space.xalign = 0;
1002 lbl_free_space.get_style_context().add_class("title");
1003 card_space.append(lbl_free_space);
1004
1005 lbl_device_name = new Gtk.Label("");
1006 lbl_device_name.xalign = 0;
1007 card_space.append(lbl_device_name);
1008
1009 var action_bar = new Gtk.Box(Orientation.HORIZONTAL, 4);
1010 action_bar.margin_start = 14;
1011 action_bar.margin_end = 14;
1012 action_bar.margin_bottom = 6;
1013 vbox.append(action_bar);
1014
1015 btn_backup = make_action_btn("document-save-symbolic", _("Create"), false, false, "btn-success");
1016 action_bar.append(btn_backup);
1017 btn_backup.clicked.connect(create_snapshot);
1018
1019 btn_restore = make_action_btn("document-open-recent-symbolic", _("Restore"), false, false, "btn-primary");
1020 action_bar.append(btn_restore);
1021 btn_restore.clicked.connect(btn_restore_clicked);
1022
1023 btn_browse_snapshot = make_action_btn("folder-symbolic", _("Browse"), false, false, "btn-info");
1024 action_bar.append(btn_browse_snapshot);
1025 btn_browse_snapshot.clicked.connect(browse_selected);
1026
1027 btn_delete_snapshot = make_action_btn("edit-delete-symbolic", _("Delete"), false, false, "btn-danger");
1028 action_bar.append(btn_delete_snapshot);
1029 btn_delete_snapshot.clicked.connect(delete_selected);
1030
1031 var sep2 = new Gtk.Box(Orientation.HORIZONTAL, 0);
1032 sep2.hexpand = true;
1033 action_bar.append(sep2);
1034
1035 var btn_menu = make_action_btn("open-menu-symbolic", "", false, false);
1036 btn_menu.set_tooltip_text(_("More options"));
1037 action_bar.append(btn_menu);
1038 btn_menu.clicked.connect(() => { btn_about_clicked(); });
1039
1040 var list_card = new Gtk.Box(Orientation.VERTICAL, 0);
1041 list_card.get_style_context().add_class("card");
1042 list_card.margin_start = 14;
1043 list_card.margin_end = 14;
1044 list_card.margin_bottom = 6;
1045 list_card.hexpand = true;
1046 list_card.vexpand = false;
1047 list_card.halign = Gtk.Align.FILL;
1048 list_card.valign = Gtk.Align.FILL;
1049
1051 snapshot_list_box.vexpand = false;
1052 snapshot_list_box.hexpand = true;
1053 snapshot_list_box.halign = Gtk.Align.FILL;
1054 snapshot_list_box.valign = Gtk.Align.FILL;
1055 list_card.append(snapshot_list_box);
1056 vbox.append(list_card);
1057
1062 }
Gtk.Button btn_restore
Gtk.Label lbl_device_name
Gtk.Label lbl_free_space
void btn_restore_clicked()
Gtk.Button btn_delete_snapshot
void create_snapshot()
Gtk.Label lbl_status_detail
void browse_selected()
Gtk.Label lbl_snap_count
void view_snapshot_log(bool view_restore_log)
Gtk.Button make_action_btn(string icon, string label, bool primary, bool danger, string css_class="")
Gtk.Button btn_browse_snapshot
void mark_selected()
void btn_about_clicked()
Gtk.Label lbl_status_title
Gtk.Button btn_backup
Gtk.Image img_shield
void delete_selected()
signal void browse_selected()
SnapshotListBox(Gtk.Window _parent_window)
signal void view_snapshot_log(bool show_restore_log)
signal void mark_selected()
signal void delete_selected()

References _, browse_selected(), SnapshotListBox.browse_selected(), btn_about_clicked(), btn_backup, btn_browse_snapshot, btn_delete_snapshot, btn_restore, btn_restore_clicked(), content_stack, create_snapshot(), delete_selected(), SnapshotListBox.delete_selected(), img_shield, lbl_device_name, lbl_free_space, lbl_snap_count, lbl_status_detail, lbl_status_title, IconManager.lookup(), make_action_btn(), make_card(), mark_selected(), SnapshotListBox.mark_selected(), IconManager.SHIELD_HIGH, snapshot_list_box, SnapshotListBox.SnapshotListBox(), view_snapshot_log(), and SnapshotListBox.view_snapshot_log().

Referenced by init_content().

◆ init_wizard_page()

void MainWindow.init_wizard_page ( )
inlineprivate

◆ load_css()

void MainWindow.load_css ( bool use_dark = false)
inlineprivate

Definition at line 432 of file MainWindow.vala.

432 {
433
434 string css_name = use_dark ? "BastionGuard-dark.css" : "BastionGuard.css";
435 string css_res = ResourceHelper.resource_prefix() + "/css/" + css_name;
436 string? path = ResourceHelper.resolve_css(css_name);
437
438 if (css_provider != null) {
439 Gtk.StyleContext.remove_provider_for_display(
440 Gdk.Display.get_default(),
442 );
443 css_provider = null;
444 }
445
446 css_provider = new Gtk.CssProvider();
447 try {
448 if (ResourceHelper.resource_exists("css/" + css_name)) {
449 css_provider.load_from_resource(css_res);
450 log_debug("CSS caricato da resource: " + css_res);
451 } else if (path != null && FileUtils.test(path, FileTest.EXISTS)) {
452 css_provider.load_from_path(path);
453 log_debug("CSS caricato da path: " + path);
454 } else {
455 log_debug(css_name + " non trovato, uso stile di default");
456 return;
457 }
458 Gtk.StyleContext.add_provider_for_display(
459 Gdk.Display.get_default(),
461 Gtk.STYLE_PROVIDER_PRIORITY_USER
462 );
463
464 var gtk_settings = Gtk.Settings.get_default();
465 if (gtk_settings != null) {
466 gtk_settings.gtk_application_prefer_dark_theme = use_dark;
467 }
468
469 dark_mode = use_dark;
470 // Tell IconManager which theme is active so future lookups use the right icons
471 IconManager.use_dark = use_dark;
472 // Reload already-rendered themed icons to the correct colour variant
475 return;
476 }
477 catch (Error e) {
478 log_error("CSS error: " + e.message);
479 }
480 }
Gtk.? CssProvider css_provider
void reload_themed_icons()
void log_error(string message, bool highlight=false, bool is_warning=false)

References css_provider, dark_mode, Error, TeeJee.Logging.log_debug(), TeeJee.Logging.log_error(), reload_themed_icons(), ResourceHelper.resolve_css(), ResourceHelper.resource_exists(), ResourceHelper.resource_prefix(), update_theme_buttons(), and IconManager.use_dark.

Referenced by apply_theme(), and MainWindow().

◆ load_language_preference()

string MainWindow.load_language_preference ( )
inlineprivate

Reads the saved language code from language.json. Returns "en_US" if the file is absent or invalid (first run).

Definition at line 266 of file MainWindow.vala.

266 {
267 try {
268 if (!FileUtils.test(LANG_CONFIG_FILE, FileTest.EXISTS)) {
269 log_debug("Language config non trovato, uso English (en_US)");
270 return "en_US";
271 }
272
273 string content;
274 FileUtils.get_contents(LANG_CONFIG_FILE, out content);
275
276 var parser = new Json.Parser();
277 parser.load_from_data(content, -1);
278
279 Json.Node root = parser.get_root();
280 if (root == null || root.get_node_type() != Json.NodeType.OBJECT) {
281 log_error("Language config non valido, uso en_US");
282 return "en_US";
283 }
284
285 Json.Object obj = root.get_object();
286 if (!obj.has_member("language")) {
287 log_debug("Chiave 'language' mancante, uso en_US");
288 return "en_US";
289 }
290
291 string lang = obj.get_string_member("language");
292
293 // Validate against supported codes
294 foreach (var code in LANG_CODES) {
295 if (lang == code) {
296 log_debug("Lingua letta da config: " + lang);
297 return lang;
298 }
299 }
300
301 log_debug("Lingua non supportata '%s', uso en_US".printf(lang));
302 return "en_US";
303 }
304 catch (Error e) {
305 log_error("Errore lettura language config: " + e.message);
306 return "en_US";
307 }
308 }
const string LANG_CONFIG_FILE

References Error, LANG_CODES, LANG_CONFIG_FILE, TeeJee.Logging.log_debug(), and TeeJee.Logging.log_error().

Referenced by MainWindow().

◆ load_theme_preference()

bool MainWindow.load_theme_preference ( )
inlineprivate

Definition at line 200 of file MainWindow.vala.

200 {
201 try {
202 if (!FileUtils.test(THEME_CONFIG_FILE, FileTest.EXISTS)) {
203 return false;
204 }
205
206 string content;
207 FileUtils.get_contents(THEME_CONFIG_FILE, out content);
208
209 var parser = new Json.Parser();
210 parser.load_from_data(content, -1);
211
212 Json.Node root = parser.get_root();
213 if (root == null || root.get_node_type() != Json.NodeType.OBJECT) {
214 log_error("Theme config non valido, uso light");
215 return false;
216 }
217
218 Json.Object obj = root.get_object();
219 if (!obj.has_member("theme")) {
220 log_debug("Chiave 'theme' mancante, uso light");
221 return false;
222 }
223
224 string theme = obj.get_string_member("theme");
225 if (theme == "dark") {
226 log_debug("Tema letto da config: dark");
227 return true;
228 }
229
230 log_debug("Tema letto da config: light");
231 return false;
232 }
233 catch (Error e) {
234 log_error("Errore lettura theme config: " + e.message);
235 return false;
236 }
237 }
const string THEME_CONFIG_FILE

References Error, TeeJee.Logging.log_debug(), TeeJee.Logging.log_error(), and THEME_CONFIG_FILE.

Referenced by MainWindow().

◆ loadConfig()

void MainWindow::loadConfig ( )
private

Definition at line 330 of file MainWindow.cpp.

331{
332 m_darkMode = false;
333 m_language.clear();
334 m_protectionEnabled = true;
336
337 std::ifstream f(m_configFile);
338 if (f.is_open()) {
339 std::string line;
340 while (std::getline(f, line)) {
341 if (line.find("dark_mode=true") != std::string::npos)
342 m_darkMode = true;
343
344 // ── Lingua ──────────────────────────────────────────────────────
345 const std::string langKey = "language=";
346 auto pos = line.find(langKey);
347 if (pos != std::string::npos)
348 m_language = line.substr(pos + langKey.size());
349
350 if (line.find("protection_enabled=false") != std::string::npos)
351 m_protectionEnabled = false;
352
353 const std::string backupKey = "autostart_backup=";
354 pos = line.find(backupKey);
355 if (pos != std::string::npos)
356 m_autostartBackupFile = line.substr(pos + backupKey.size());
357 }
358 }
359
360 // service-control.ini è la sorgente esplicita per autostart e daemon.
361 // Se esiste, sincronizza lo stato UI anche dopo modifiche fatte da Settings.
362 const std::filesystem::path serviceControlFile =
363 std::filesystem::path(m_configFile).parent_path() / "service-control.ini";
364 std::ifstream sc(serviceControlFile);
365 bool sawServiceControlState = false;
366 bool serviceControlEnabled = true;
367 std::string line;
368 while (std::getline(sc, line)) {
369 if (line == "enabled=true" || line == "autostart_enabled=true" || line == "daemon_enabled=true") {
370 sawServiceControlState = true;
371 }
372 if (line == "enabled=false" || line == "autostart_enabled=false" || line == "daemon_enabled=false") {
373 sawServiceControlState = true;
374 serviceControlEnabled = false;
375 }
376
377 const std::string backupPathKey = "backup_path=";
378 auto backupPathPos = line.find(backupPathKey);
379 if (backupPathPos == 0) {
380 m_autostartBackupFile = line.substr(backupPathKey.size());
381 }
382 }
383 if (sawServiceControlState) {
384 m_protectionEnabled = serviceControlEnabled;
385 }
386}
std::string m_language

References m_autostartBackupFile, m_configFile, m_darkMode, m_language, and m_protectionEnabled.

◆ loadTheme()

void MainWindow::loadTheme ( bool dark)
private

Definition at line 435 of file MainWindow.cpp.

436{
437 const std::string cssFile = dark ? resource("BSC-dark.css") : resource("BSC.css");
438 try {
439 m_cssProvider->load_from_path(cssFile);
440 Gtk::StyleContext::add_provider_for_display(
441 get_display(),
443 GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
444 } catch (const Glib::Error& e) {
445 std::cerr << "⚠ CSS: " << e.what() << "\n";
446 }
447}
Glib::RefPtr< Gtk::CssProvider > m_cssProvider

References m_cssProvider, and resource().

Referenced by applyTheme().

◆ make_action_btn()

Gtk.Button MainWindow.make_action_btn ( string icon,
string label,
bool primary,
bool danger,
string css_class = "" )
inlineprivate

Definition at line 1078 of file MainWindow.vala.

1078 {
1079 var btn = new Gtk.Button();
1080 btn.get_style_context().add_class("action-btn");
1081 if (css_class.length > 0) {
1082 btn.get_style_context().add_class(css_class);
1083 } else {
1084 if (primary) btn.get_style_context().add_class("btn-success");
1085 if (danger) btn.get_style_context().add_class("btn-danger");
1086 }
1087 btn.get_style_context().remove_class("button");
1088
1089 if (label.length == 0) {
1090 btn.set_child(themed_icon(icon, 16));
1091 } else {
1092 var box = new Gtk.Box(Orientation.HORIZONTAL, 6);
1093 box.append(themed_icon(icon, 16));
1094 box.append(new Gtk.Label(label));
1095 btn.set_child(box);
1096 }
1097 return btn;
1098 }

References themed_icon().

Referenced by init_snapshots_page().

◆ make_card()

Gtk.Box MainWindow.make_card ( bool hexpand)
inlineprivate

Definition at line 1067 of file MainWindow.vala.

1067 {
1068 var card = new Gtk.Box(Orientation.VERTICAL, 4);
1069 card.get_style_context().add_class("card");
1070 card.hexpand = hexpand;
1071 card.margin_start = 4;
1072 card.margin_end = 4;
1073 card.margin_top = 4;
1074 card.margin_bottom = 4;
1075 return card;
1076 }

Referenced by init_about_page(), and init_snapshots_page().

◆ make_nav_btn()

Gtk.Button MainWindow.make_nav_btn ( string icon,
string label,
string page )
inlineprivate

Definition at line 615 of file MainWindow.vala.

615 {
616 var btn = new Gtk.Button();
617 btn.get_style_context().add_class("sidebar-button");
618 btn.hexpand = true;
619
620 var box = new Gtk.Box(Orientation.HORIZONTAL, 12);
621 box.margin_start = 6;
622
623 var img = themed_icon(icon, 18);
624 box.append(img);
625
626 var lbl = new Gtk.Label(label);
627 lbl.xalign = 0;
628 box.append(lbl);
629
630 btn.set_child(box);
631 vbox_sidebar.append(btn);
632
633 btn.clicked.connect(() => { activate_nav(btn, page); });
634 return btn;
635 }

References activate_nav(), themed_icon(), and vbox_sidebar.

Referenced by init_sidebar().

◆ make_theme_btn()

Gtk.Button MainWindow.make_theme_btn ( string icon,
string label )
inlineprivate

Definition at line 637 of file MainWindow.vala.

637 {
638 var btn = new Gtk.Button();
639 btn.get_style_context().add_class("sidebar-button");
640 btn.hexpand = true;
641
642 var box = new Gtk.Box(Orientation.HORIZONTAL, 8);
643 box.margin_start = 6;
644 box.margin_end = 6;
645
646 var img = themed_icon(icon, 18);
647 box.append(img);
648
649 var lbl = new Gtk.Label(label);
650 lbl.xalign = 0.5f;
651 box.append(lbl);
652
653 btn.set_child(box);
654 return btn;
655 }

References themed_icon().

Referenced by init_sidebar().

◆ makeSidebarButton()

Gtk::Button * MainWindow::makeSidebarButton ( const std::string & iconPath,
const std::string & label,
const std::string & pageName )
private

Definition at line 625 of file MainWindow.cpp.

628{
629 auto box = Gtk::make_managed<Gtk::Box>(Gtk::Orientation::HORIZONTAL, 6);
630
631 auto pic = Gtk::make_managed<Gtk::Picture>();
632 try {
633 auto pb = Gdk::Pixbuf::create_from_file(iconPath);
634 auto scaled = pb->scale_simple(16, 16, Gdk::InterpType::BILINEAR);
635 auto tex = Gdk::Texture::create_for_pixbuf(scaled);
636 pic->set_paintable(tex);
637 pic->set_content_fit(Gtk::ContentFit::FILL);
638 } catch (...) {}
639
640 auto iconBox = Gtk::make_managed<Gtk::Box>(Gtk::Orientation::VERTICAL);
641 iconBox->set_size_request(16, 16);
642 iconBox->set_hexpand(false);
643 iconBox->set_valign(Gtk::Align::CENTER);
644 iconBox->append(*pic);
645 box->append(*iconBox);
646
647 auto lbl = Gtk::make_managed<Gtk::Label>(label);
648 lbl->set_halign(Gtk::Align::START);
649 lbl->set_hexpand(false);
650 box->append(*lbl);
651
652 auto btn = Gtk::make_managed<Gtk::Button>();
653 btn->set_child(*box);
654 btn->set_hexpand(true);
655 btn->get_style_context()->add_class("sidebar-button");
656 m_sidebarButtons.push_back(btn);
657
658 btn->signal_clicked().connect([this, btn, pageName]() {
659 // Determina direzione animazione in base all'ordine delle pagine
660 static const std::vector<std::string> pageOrder = {
661 "connections", "apps", "network", "rules", "stats", "settings", "about"
662 };
663 const std::string currentPage = m_stack.get_visible_child_name();
664 auto itCur = std::find(pageOrder.begin(), pageOrder.end(), currentPage);
665 auto itDst = std::find(pageOrder.begin(), pageOrder.end(), pageName);
666 if (itCur != pageOrder.end() && itDst != pageOrder.end()) {
667 if (itDst > itCur)
668 m_stack.set_transition_type(Gtk::StackTransitionType::SLIDE_LEFT);
669 else if (itDst < itCur)
670 m_stack.set_transition_type(Gtk::StackTransitionType::SLIDE_RIGHT);
671 // stessa pagina: nessun cambio di tipo
672 }
674 m_stack.set_visible_child(pageName);
675 });
676
677 return btn;
678}
Gtk::Stack m_stack
void activateSidebarButton(Gtk::Button *btn)

References activateSidebarButton(), m_sidebarButtons, and m_stack.

Referenced by buildSidebar().

◆ mark_selected()

void MainWindow.mark_selected ( )
inline

Definition at line 1197 of file MainWindow.vala.

1197 {
1198 var selected = snapshot_list_box.selected_snapshots();
1199 if (selected.size == 0) {
1200 gtk_messagebox(_("No Snapshots Selected"), _("Select the snapshots to mark"), this, false);
1201 return;
1202 }
1203 bool marked = false;
1204 foreach (var bak in selected) {
1205 bak.mark_for_deletion();
1206 marked = marked || bak.marked_for_deletion;
1207 }
1209 gtk_messagebox(
1210 marked ? _("Marked for deletion") : _("Unmarked"),
1211 marked ? _("Snapshots will be removed at next scheduled run")
1212 : _("Snapshots will not be removed"),
1213 this, false);
1215 }
bool load_snapshots()

References _, App, SnapshotRepo.load_snapshots(), SnapshotListBox.refresh(), Main.repo, SnapshotListBox.selected_snapshots(), and snapshot_list_box.

Referenced by init_snapshots_page().

◆ minimize()

void MainWindow::minimize ( )
private

Definition at line 451 of file MainWindow.cpp.

451 {
452 #if GTKMM_CHECK_VERSION(4,10,0)
453 this->hide();
454 #endif
455}

Referenced by build_headerbar(), buildHeaderBar(), and minimize_window().

◆ minimize_window()

void MainWindow::minimize_window ( )
private

Definition at line 1313 of file main_window.cpp.

1313 {
1314 #if GTKMM_CHECK_VERSION(4,10,0)
1315 minimize();
1316 #else
1317 set_visible(false);
1318 #endif
1319}

References minimize().

Referenced by on_language_changed().

◆ noteDesktopActivity()

void MainWindow::noteDesktopActivity ( )
private

Definition at line 762 of file MainWindow.cpp.

763{
764 m_lastUiActivity = std::chrono::steady_clock::now();
766}
std::chrono::steady_clock::time_point m_lastUiActivity
void sendDesktopActivityState(bool active, bool force=false)

References m_lastUiActivity, and sendDesktopActivityState().

Referenced by startDesktopActivityMonitor().

◆ on_choose_destination()

void MainWindow::on_choose_destination ( )
private

Definition at line 844 of file main_window.cpp.

844 {
845 folder_dialog_ = Gtk::FileDialog::create();
846 folder_dialog_->set_title(tr("Select destination folder"));
847
848 folder_dialog_->select_folder(*this, [this](const Glib::RefPtr<Gio::AsyncResult>& result) {
849 try {
850 if (!folder_dialog_) return;
851 auto folder = folder_dialog_->select_folder_finish(result);
852 if (!folder) return;
853
854 output_dir_ = folder->get_path();
855 entry_output_.set_text(output_dir_);
856 append_log(trs("Recovery destination: ") + output_dir_);
859 folder_dialog_.reset();
860 } catch (const Glib::Error&) {
861 folder_dialog_.reset();
862 }
863 });
864}
void append_log(const std::string &line)
Glib::RefPtr< Gtk::FileDialog > folder_dialog_
void update_wizard_step()
std::string output_dir_
void update_source_state()

References append_log(), entry_output_, folder_dialog_, output_dir_, tr(), trs(), update_source_state(), and update_wizard_step().

Referenced by on_language_changed().

◆ on_close_request() [1/3]

bool MainWindow.on_close_request ( )
inlineprivate

Definition at line 1122 of file MainWindow.vala.

1122 {
1123 this.close_request.disconnect(on_close_request);
1124 if (App.task.status == AppStatus.RUNNING) {
1125 log_error(_("Main window closed by user"));
1126 App.task.stop();
1127 }
1129 App.delete_list.clear();
1130 if (App.delete_file_task != null)
1132 }
1133 if (!App.live_system()) {
1134 if (!App.repo.available() || !App.repo.has_space()) {
1135 var dlg = new CustomMessageDialog(
1136 App.repo.status_message, _("Select another device?"),
1137 Gtk.MessageType.ERROR, this, Gtk.ButtonsType.YES_NO);
1138 var resp = gtk_dialog_run(dlg);
1139 dlg.destroy();
1140 if (resp == Gtk.ResponseType.YES) {
1141 this.close_request.connect(on_close_request);
1143 return true;
1144 }
1145 return false;
1146 }
1147 }
1148 App.exit_app(0);
1149 return false;
1150 }
AppStatus
void stop(AppStatus status_to_update=AppStatus.CANCELLED)
AppStatus status
CustomMessageDialog(string _msg_title, string _msg_body, Gtk.MessageType _msg_type, Window? parent, Gtk.ButtonsType _buttons_type)
RsyncTask task
Definition Main.vala:160
void exit_app(int exit_code=0)
Definition Main.vala:4574
DeleteFileTask delete_file_task
Definition Main.vala:161
bool has_space(uint64 needed=0)

References _, App, SnapshotRepo.available(), btn_wizard_clicked(), CustomMessageDialog.CustomMessageDialog(), Main.delete_file_task, Main.delete_list, Main.exit_app(), TeeJee.GtkHelper.gtk_dialog_run(), SnapshotRepo.has_space(), Main.live_system(), TeeJee.Logging.log_error(), on_close_request(), Main.repo, AsyncTask.status, SnapshotRepo.status_message, AsyncTask.stop(), Main.task, and Main.thread_delete_running.

◆ on_close_request() [2/3]

bool MainWindow::on_close_request ( )
overrideprotected

Definition at line 458 of file MainWindow.cpp.

458 {
459 std::cout << _("[MainWindow] Nascondo finestra nella tray invece di chiudere") << "\n";
460 this->hide();
461 return true;
462}

References _.

Referenced by MainWindow(), and on_close_request().

◆ on_close_request() [3/3]

bool MainWindow::on_close_request ( )
overrideprivate

◆ on_dashboard_device_activated()

void MainWindow::on_dashboard_device_activated ( Gtk::ListBoxRow * row)
private

Definition at line 881 of file main_window.cpp.

881 {
882 if (!row) return;
883
884 const int idx = row->get_index();
885 if (idx < 0 || static_cast<size_t>(idx) >= devices_.size()) return;
886
887 const auto& d = devices_[static_cast<size_t>(idx)];
888 select_source(d.path, d.path + " • " + human_size(d.size_bytes));
892}
void on_sidebar_recovery()
WizardStep current_step_
static std::string human_size(uint64_t bytes)
void select_source(const std::string &path, const std::string &label)
std::vector< DeviceInfo > devices_

References current_step_, devices_, human_size(), on_sidebar_recovery(), select_source(), Source, and update_wizard_step().

Referenced by on_language_changed().

◆ on_language_changed() [1/2]

void MainWindow.on_language_changed ( )
inlineprivate

Definition at line 365 of file MainWindow.vala.

365 {
366 if (lang_combo == null) return;
367
368 int idx = lang_combo.get_active();
369 if (idx < 0 || idx >= LANG_CODES.length) return;
370
371 string new_lang = LANG_CODES[idx];
372 if (new_lang == current_lang) return;
373
374 save_language_preference(new_lang);
375 current_lang = new_lang;
376
377 // gettext caches translations at first use — the only reliable way
378 // to switch language at runtime is to re-exec the current process.
379 var dlg = new Gtk.MessageDialog(
380 this,
381 Gtk.DialogFlags.MODAL,
382 Gtk.MessageType.QUESTION,
383 Gtk.ButtonsType.YES_NO,
384 _("Language saved. The application must restart to apply the new language.\n\nRestart now?")
385 );
386 var resp = gtk_dialog_run(dlg);
387 dlg.destroy();
388
389 if (resp == Gtk.ResponseType.YES) {
391 }
392 }
void save_language_preference(string lang_code)
void restart_application()

References _, current_lang, TeeJee.GtkHelper.gtk_dialog_run(), LANG_CODES, lang_combo, restart_application(), and save_language_preference().

Referenced by build_sidebar(), and init_sidebar().

◆ on_language_changed() [2/2]

◆ on_launch_elevated()

void MainWindow::on_launch_elevated ( )
private

Definition at line 1015 of file main_window.cpp.

1015 {
1016 std::string error;
1017
1019 append_log(trs("Already running with elevated privileges."));
1020 return;
1021 }
1022
1024 append_log(trs("Failed to launch pkexec: ") + error);
1025 return;
1026 }
1027
1028 append_log(trs("Requested pkexec relaunch."));
1029}
static bool is_running_as_root()
static bool launch_pkexec_relaunch(std::string &error, const std::string &extra_args="")

References append_log(), PrivilegeUtils::is_running_as_root(), PrivilegeUtils::launch_pkexec_relaunch(), and trs().

Referenced by on_language_changed().

◆ on_open_image()

void MainWindow::on_open_image ( )
private

Definition at line 822 of file main_window.cpp.

822 {
823 file_dialog_ = Gtk::FileDialog::create();
824 file_dialog_->set_title(tr("Select image file"));
825
826 file_dialog_->open(*this, [this](const Glib::RefPtr<Gio::AsyncResult>& result) {
827 try {
828 if (!file_dialog_) return;
829 auto file = file_dialog_->open_finish(result);
830 if (!file) return;
831
832 const auto path = file->get_path();
833 select_source(path, path);
835 file_dialog_.reset();
836 } catch (const Glib::Error&) {
837 file_dialog_.reset();
838 }
839
841 });
842}
Glib::RefPtr< Gtk::FileDialog > file_dialog_

References file_dialog_, on_sidebar_recovery(), select_source(), tr(), and update_wizard_step().

Referenced by on_language_changed().

◆ on_recover_now()

void MainWindow::on_recover_now ( )
private

Definition at line 984 of file main_window.cpp.

984 {
985 if (last_report_.results.empty()) {
986 append_log(trs("No scan report available."));
987 return;
988 }
989
990 if (output_dir_.empty()) {
991 append_log(trs("No output directory selected."));
992 return;
993 }
994
996 append_log(trs("A recovery task is already running."));
997 return;
998 }
999
1000 const auto selected = selected_result_indices();
1001 if (selected.empty()) {
1002 append_log(trs("No recoverable items selected."));
1003 return;
1004 }
1005
1006 append_log(trs("Starting recovery to: ") + output_dir_);
1007 append_log(trs("Selected items for recovery: ") + std::to_string(selected.size()));
1008 btn_recover_now_.set_sensitive(false);
1009
1010 recovery_worker_.start(last_report_, output_dir_, selected, [this](const RecoveryResult& result) {
1011 Glib::signal_idle().connect_once([this, result]() { on_recovery_completed(result); });
1012 });
1013}
ScanReport last_report_
RecoveryWorker recovery_worker_
std::vector< size_t > selected_result_indices() const
void on_recovery_completed(const RecoveryResult &result)
void start(const ScanReport &report, const std::string &output_dir, const std::vector< size_t > &selected_result_indices, CompletionCallback cb)
bool running() const
std::vector< ScanResult > results
Definition models.hpp:40

References append_log(), btn_recover_now_, last_report_, on_recovery_completed(), output_dir_, recovery_worker_, ScanReport::results, RecoveryWorker::running(), selected_result_indices(), RecoveryWorker::start(), and trs().

Referenced by on_language_changed().

◆ on_recovery_completed()

void MainWindow::on_recovery_completed ( const RecoveryResult & result)
private

Definition at line 1299 of file main_window.cpp.

1299 {
1300 for (const auto& line : result.logs) append_log(line);
1301
1302 if (result.ok) {
1303 append_log(trs("Recovery completed."));
1304 append_log(trs("Exported images: ") + std::to_string(result.summary.exported_images.size()));
1305 append_log(trs("Recovered files: ") + std::to_string(result.summary.recovered_files.size()));
1306 } else {
1307 append_log(trs("Recovery failed: ") + result.error);
1308 }
1309
1311}
void update_selected_results_state()
RecoverySummary summary
std::vector< std::string > logs
std::vector< std::string > exported_images
std::vector< std::string > recovered_files

References append_log(), RecoveryResult::error, RecoverySummary::exported_images, RecoveryResult::logs, RecoveryResult::ok, RecoverySummary::recovered_files, RecoveryResult::summary, trs(), and update_selected_results_state().

Referenced by on_language_changed(), and on_recover_now().

◆ on_recovery_device_activated()

void MainWindow::on_recovery_device_activated ( Gtk::ListBoxRow * row)
private

Definition at line 894 of file main_window.cpp.

894 {
895 if (!row) return;
896 recovery_devices_list_.select_row(*row);
898}
void on_use_selected_device()

References on_use_selected_device(), and recovery_devices_list_.

Referenced by on_language_changed().

◆ on_refresh_devices()

void MainWindow::on_refresh_devices ( )
private

Definition at line 817 of file main_window.cpp.

817 {
819 append_log(trs("Device list refreshed."));
820}
void refresh_devices()

References append_log(), refresh_devices(), and trs().

Referenced by activate_sidebar_button().

◆ on_scan_completed()

void MainWindow::on_scan_completed ( const ScanReport & report)
private

Definition at line 1053 of file main_window.cpp.

1053 {
1054 if (scan_timer_connection_.connected())
1055 scan_timer_connection_.disconnect();
1056
1057 scan_progress_bar_.set_fraction(1.0);
1058 scan_progress_bar_.set_text("100%");
1059 scan_status_label_.set_text(trs("Completed • Scan finished"));
1060
1061 scan_timer_label_.set_text(
1062 tr("Elapsed: ") + format_elapsed(std::chrono::steady_clock::now() - scan_started_at_)
1063 );
1064
1065 last_report_ = report;
1066
1067 for (const auto& line : report.logs)
1068 append_log(line);
1069
1070 std::ostringstream ss;
1071 ss << trs("Scan completed. Results: ") << report.results.size();
1072 append_log(ss.str());
1073
1074 populate_scan_results(report);
1075
1076 btn_scan_now_.set_label(trs("Repeat scan"));
1078
1079 if (!report.results.empty())
1081
1083}
void populate_scan_results(const ScanReport &report)
sigc::connection scan_timer_connection_
std::chrono::steady_clock::time_point scan_started_at_
void update_action_controls()
std::string format_elapsed(std::chrono::steady_clock::duration elapsed)
std::vector< std::string > logs
Definition models.hpp:41

References append_log(), btn_scan_now_, current_step_, last_report_, ScanReport::logs, populate_scan_results(), Recover, ScanReport::results, scan_progress_bar_, scan_started_at_, scan_status_label_, scan_timer_connection_, scan_timer_label_, tr(), trs(), update_action_controls(), and update_wizard_step().

Referenced by on_language_changed(), and on_scan_now().

◆ on_scan_now()

void MainWindow::on_scan_now ( )
private

Definition at line 940 of file main_window.cpp.

940 {
941 if (selected_source_path_.empty()) {
942 append_log(trs("No source selected."));
943 return;
944 }
945
946 if (scan_worker_.running()) {
947 append_log(trs("A scan is already running."));
948 return;
949 }
950
952 append_log(trs("Source access denied. Relaunch with pkexec or adjust permissions."));
953 return;
954 }
955
956 append_log(trs("Starting read-only scan on: ") + selected_source_path_);
957 btn_scan_now_.set_sensitive(false);
959 scan_started_at_ = std::chrono::steady_clock::now();
960 scan_progress_bar_.set_fraction(0.0);
961 scan_progress_bar_.set_text("0%");
962 scan_status_label_.set_text(tr("Preparing scan..."));
963 scan_timer_label_.set_text(tr("Elapsed: ") + std::string("00:00"));
964
965 if (scan_timer_connection_.connected()) scan_timer_connection_.disconnect();
966
967 scan_timer_connection_ = Glib::signal_timeout().connect([this]() {
968 scan_timer_label_.set_text(
969 tr("Elapsed: ") + format_elapsed(std::chrono::steady_clock::now() - scan_started_at_));
970 return scan_worker_.running();
971 }, 250);
972
975 [this](const ScanReport& report) {
976 Glib::signal_idle().connect_once([this, report]() { on_scan_completed(report); });
977 },
978 [this](const ScanProgress& progress) {
979 Glib::signal_idle().connect_once([this, progress]() { on_scan_progress(progress); });
980 }
981 );
982}
void on_scan_completed(const ScanReport &report)
ScanWorker scan_worker_
void on_scan_progress(const ScanProgress &progress)
ScanProgress last_scan_progress_
std::string selected_source_path_
static bool can_read_source(const std::string &path)
void start(const std::string &path, CompletionCallback cb, ProgressCallback progress_cb={})
bool running() const

References append_log(), btn_scan_now_, PrivilegeUtils::can_read_source(), PrivilegeUtils::is_running_as_root(), last_scan_progress_, on_scan_completed(), on_scan_progress(), ScanWorker::running(), scan_progress_bar_, scan_started_at_, scan_status_label_, scan_timer_connection_, scan_timer_label_, scan_worker_, selected_source_path_, ScanWorker::start(), tr(), and trs().

Referenced by on_language_changed().

◆ on_scan_progress()

void MainWindow::on_scan_progress ( const ScanProgress & progress)
private

Definition at line 1031 of file main_window.cpp.

1031 {
1032 last_scan_progress_ = progress;
1033
1034 double fraction = progress.fraction;
1035 if (fraction < 0.0) fraction = 0.0;
1036 if (fraction > 1.0) fraction = 1.0;
1037
1038 scan_progress_bar_.set_fraction(fraction);
1039
1040 std::ostringstream pct;
1041 pct << static_cast<int>(fraction * 100.0) << '%';
1042 scan_progress_bar_.set_text(pct.str());
1043
1044 std::string status = progress.stage;
1045 if (!progress.detail.empty()) {
1046 if (!status.empty()) status += " • ";
1047 status += progress.detail;
1048 }
1049
1050 scan_status_label_.set_text(status.empty() ? tr("Scanning...") : status);
1051}
std::string stage
Definition models.hpp:30
std::string detail
Definition models.hpp:31
double fraction
Definition models.hpp:34

References ScanProgress::detail, ScanProgress::fraction, last_scan_progress_, scan_progress_bar_, scan_status_label_, ScanProgress::stage, and tr().

Referenced by on_language_changed(), and on_scan_now().

◆ on_sidebar_about()

void MainWindow::on_sidebar_about ( )
private

Definition at line 1435 of file main_window.cpp.

1435 {
1436 page_stack_.set_transition_type(Gtk::StackTransitionType::SLIDE_LEFT);
1437 page_stack_.set_visible_child(about_page_);
1439}
Gtk::Stack page_stack_

References about_button_, about_page_, activate_sidebar_button(), and page_stack_.

Referenced by activate_sidebar_button().

◆ on_sidebar_dashboard()

void MainWindow::on_sidebar_dashboard ( )
private

Definition at line 805 of file main_window.cpp.

805 {
806 page_stack_.set_transition_type(Gtk::StackTransitionType::SLIDE_RIGHT);
807 page_stack_.set_visible_child(dashboard_page_);
809}

References activate_sidebar_button(), dashboard_button_, dashboard_page_, and page_stack_.

Referenced by activate_sidebar_button().

◆ on_sidebar_recovery()

void MainWindow::on_sidebar_recovery ( )
private

Definition at line 811 of file main_window.cpp.

811 {
812 page_stack_.set_transition_type(Gtk::StackTransitionType::SLIDE_LEFT);
813 page_stack_.set_visible_child(recovery_page_);
815}

References activate_sidebar_button(), page_stack_, recovery_button_, and recovery_page_.

Referenced by activate_sidebar_button(), on_dashboard_device_activated(), and on_open_image().

◆ on_theme_dark()

void MainWindow::on_theme_dark ( )
private

Definition at line 900 of file main_window.cpp.

900 {
902 save_theme("dark");
904}
static void save_theme(const std::string &theme_code)

References apply_theme(), current_theme_, Dark, and save_theme().

Referenced by on_language_changed().

◆ on_theme_light()

void MainWindow::on_theme_light ( )
private

Definition at line 906 of file main_window.cpp.

References apply_theme(), current_theme_, Light, and save_theme().

Referenced by on_language_changed().

◆ on_use_selected_device()

void MainWindow::on_use_selected_device ( )
private

Definition at line 866 of file main_window.cpp.

866 {
867 auto* row = recovery_devices_list_.get_selected_row();
868 if (!row) {
869 append_log(trs("No device selected."));
870 return;
871 }
872
873 const int idx = row->get_index();
874 if (idx < 0 || static_cast<size_t>(idx) >= devices_.size()) return;
875
876 const auto& d = devices_[static_cast<size_t>(idx)];
877 select_source(d.path, d.path + " • " + human_size(d.size_bytes));
879}

References append_log(), devices_, human_size(), recovery_devices_list_, select_source(), trs(), and update_wizard_step().

Referenced by on_language_changed(), and on_recovery_device_activated().

◆ on_wizard_back()

void MainWindow::on_wizard_back ( )
private

◆ on_wizard_next()

void MainWindow::on_wizard_next ( )
private

Definition at line 922 of file main_window.cpp.

922 {
923 switch (current_step_) {
926 break;
929 break;
930 case WizardStep::Scan:
931 if (!last_report_.results.empty())
933 break;
935 break;
936 }
938}

References current_step_, Destination, last_report_, output_dir_, Recover, ScanReport::results, Scan, selected_source_path_, Source, and update_wizard_step().

Referenced by on_language_changed().

◆ onDaemonAlert()

void MainWindow::onDaemonAlert ( const AlertInfo & alert)
private

Definition at line 875 of file MainWindow.cpp.

876{
877 std::string text = alert.text.empty() ? _("Alert dal daemon") : alert.text;
878
879 // Mapping dei codici `what` e `type` come definiti in ipc/UIServer.cpp:
880 // what: 0 generic, 2 firewall, 3 connection
881 // type: 0 error, 1 warning, 2 info
882 constexpr int kWhatConnection = 3;
883 constexpr int kTypeWarning = 1;
884
885 const bool is_connection_alert = alert.what == kWhatConnection && alert.has_connection;
886
887 if (is_connection_alert) {
888 m_connectionsPage.onNewConnection(alert.connection, /*pending=*/false);
890 std::string esito;
891 if (alert.type == kTypeWarning) {
892 ++m_statDenied;
893 esito = _("❌ Negato");
895 } else {
897 esito = _("✅ Consentito");
899 }
903 setStatus(text);
904 m_tray.set_tooltip("BastionGuard™ SC — " + text);
905 return;
906 }
907
908 setStatus(text);
909 m_tray.set_tooltip("BastionGuard™ SC — " + text);
910
911 // NON chiamare present() qui: gli alert informativi passano tramite il
912 // tray, non forzano l'apertura della main window. L'utente apre lei
913 // attivamente cliccando sull'icona del tray.
914}
void noteConnection(const ConnectionInfo &info, const std::string &verdict)
Definition AppsPage.cpp:109
void setLastVerdict(const std::string &verdict)
void onNewConnection(const ConnectionInfo &info, bool pending=true)
uint64_t m_statAllowed
uint64_t m_statDenied
AppsPage m_appsPage
StatsPage m_statsPage
void noteConnection(const ConnectionInfo &info)
void updateStats(uint64_t allowed, uint64_t denied, uint64_t total)
Definition StatsPage.cpp:50
void set_tooltip(const std::string &text)
Definition TrayIcon.cpp:368
ConnectionInfo connection
Definition UIServer.hpp:68
bool has_connection
Definition UIServer.hpp:69
std::string text
Definition UIServer.hpp:64

References _, AlertInfo::connection, AlertInfo::has_connection, m_appsPage, m_connectionsPage, m_networkPage, m_statAllowed, m_statDenied, m_statsPage, m_tray, AppsPage::noteConnection(), NetworkPage::noteConnection(), ConnectionsPage::onNewConnection(), ConnectionsPage::saveLog(), TrayIcon::set_tooltip(), ConnectionsPage::setLastVerdict(), setStatus(), AlertInfo::text, AlertInfo::type, StatsPage::updateStats(), and AlertInfo::what.

◆ onDaemonConnected()

void MainWindow::onDaemonConnected ( )
private

Definition at line 779 of file MainWindow.cpp.

780{
781 setStatus(_("✅ Daemon connesso"));
782 if (m_daemonLabel)
783 m_daemonLabel->set_text(_("⚙ Daemon: connesso"));
784 m_tray.set_tooltip("BastionGuard™ SC — Daemon connesso");
785
786 // Allineamento immediato: il daemon parte "idle" per sicurezza finché
787 // la UI non conferma che il desktop è attivo.
790}
bool m_desktopActiveSent
bool pollDesktopActivity()

References _, m_daemonLabel, m_desktopActiveSent, m_tray, pollDesktopActivity(), sendDesktopActivityState(), TrayIcon::set_tooltip(), and setStatus().

◆ onDaemonDisconnected()

void MainWindow::onDaemonDisconnected ( )
private

Definition at line 792 of file MainWindow.cpp.

793{
794 setStatus(_("⚠ Daemon disconnesso — in attesa..."));
795 if (m_daemonLabel)
796 m_daemonLabel->set_text(_("⚙ Daemon: in attesa..."));
797 m_tray.set_tooltip("BastionGuard™ SC — Daemon disconnesso");
798}

References _, m_daemonLabel, m_tray, TrayIcon::set_tooltip(), and setStatus().

◆ onNewConnection()

void MainWindow::onNewConnection ( const ConnectionInfo & info)
private

Definition at line 815 of file MainWindow.cpp.

816{
817 // ── Controlla la cache dei verdetti "always" ─────────────────────────
818 // Se questa combinazione app+host+ip è già stata decisa con ALLOW_ALWAYS
819 // o DENY_ALWAYS, rispondi immediatamente senza mostrare il popup.
820 const std::string key = cacheKey(!info.app_path.empty() ? info.app_path : info.app_comm, info.dest_host, info.dest_ip);
821 auto it = m_verdictCache.find(key);
822 if (it != m_verdictCache.end()) {
823 const bool allowed = (it->second == ReplyAction::ALLOW_ALWAYS);
824 const std::string esito = allowed
825 ? std::string{"✅ "} + _("Consentito (sempre)")
826 : std::string{"❌ "} + _("Negato (sempre)");
827
828 m_uiServer.sendReply(it->second);
829 m_connectionsPage.onNewConnection(info, /*pending=*/false);
831
832 // Anche i verdetti ricavati da cache devono aggiornare le
833 // viste aggregate e la mappa, altrimenti dopo il primo "allow
834 // always" una app scompare dai grafici.
835 m_appsPage.noteConnection(info, esito);
837
838 if (allowed) ++m_statAllowed; else ++m_statDenied;
841 setStatus(esito + " — " + displayNameForStatus(info));
842 return;
843 }
844
845 // ── Nessuna regola in cache: mostra il popup ─────────────────────────
846 m_connectionsPage.onNewConnection(info, /*pending=*/true);
848
849 if (m_alertDialog && m_alertDialog->is_visible())
850 return;
851
852 m_alertDialog = std::make_unique<AlertDialog>(
853 info.app_comm, info.app_path, info.app_args, info.dest_host, info.dest_ip, info.dest_port);
854
855 // IMPORTANTE: NON rendere l'AlertDialog transient_for della main window.
856 // Se lo fosse:
857 // - su X11/Wayland, presentarlo presenterebbe anche la main window
858 // - la main window in tray verrebbe forzata visibile
859 // Qui vogliamo che l'alert sia una finestra completamente indipendente:
860 // il tray resta nel tray, il dialog appare sopra al desktop.
861
862 m_alertDialog->signal_verdict.connect(
863 [this, info](Verdict v) {
864 onVerdict(v, info);
865 });
866
867 // IMPORTANTE: NON chiamare present() sulla main window.
868 // Prima c'era `if (!is_visible()) present()` che apriva la finestra
869 // principale ogni volta che arrivava un alert — comportamento sbagliato:
870 // l'utente viene disturbato abbastanza dal popup, la main window deve
871 // restare discreta nel tray.
872 m_alertDialog->present();
873}
Verdict
static std::string cacheKey(const std::string &app, const std::string &host, const std::string &ip)
void onVerdict(Verdict v, const ConnectionInfo &info)
std::map< std::string, ReplyAction > m_verdictCache
std::unique_ptr< AlertDialog > m_alertDialog
void sendReply(ReplyAction action)
Definition UIServer.cpp:422
std::string displayNameForStatus(const ConnectionInfo &info)
std::string dest_host
Definition UIServer.hpp:37
uint32_t dest_port
Definition UIServer.hpp:39
std::string app_path
Definition UIServer.hpp:27
std::vector< std::string > app_args
Definition UIServer.hpp:30
std::string dest_ip
Definition UIServer.hpp:38
std::string app_comm
Definition UIServer.hpp:28

References _, ALLOW_ALWAYS, ConnectionInfo::app_args, ConnectionInfo::app_comm, ConnectionInfo::app_path, cacheKey(), ConnectionInfo::dest_host, ConnectionInfo::dest_ip, ConnectionInfo::dest_port, m_alertDialog, m_appsPage, m_connectionsPage, m_networkPage, m_statAllowed, m_statDenied, m_statsPage, m_uiServer, m_verdictCache, AppsPage::noteConnection(), NetworkPage::noteConnection(), ConnectionsPage::onNewConnection(), onVerdict(), ConnectionsPage::saveLog(), UIServer::sendReply(), ConnectionsPage::setLastVerdict(), setStatus(), and StatsPage::updateStats().

◆ onVerdict()

void MainWindow::onVerdict ( Verdict v,
const ConnectionInfo & info )
private

Definition at line 916 of file MainWindow.cpp.

917{
919 std::string esito;
920
921 switch (v) {
924 esito = std::string{"✅ "} + _("Consentito (una volta)");
926 break;
927
930 esito = std::string{"✅ "} + _("Consentito (sempre)");
932 break;
933
935 action = ReplyAction::DENY_ONCE;
936 esito = std::string{"❌ "} + _("Negato (una volta)");
937 ++m_statDenied;
938 break;
939
942 esito = std::string{"❌ "} + _("Negato (sempre)");
943 ++m_statDenied;
944 break;
945 }
946
947 m_uiServer.sendReply(action);
948
949 // Memorizza in cache solo le regole "always"
951 m_verdictCache[cacheKey(!info.app_path.empty() ? info.app_path : info.app_comm, info.dest_host, info.dest_ip)] = action;
952
953 // Aggiorna la riga nella pagina Connessioni e salva il log
956
957 // Aggiorna vista per-applicazione
958 m_appsPage.noteConnection(info, esito);
959
960 // Aggiorna Monitor di rete (geo lookup async)
962
967
968 setStatus(esito + " — " + displayNameForStatus(info));
969}
ReplyAction
Definition UIServer.hpp:42

References _, ALLOW_ALWAYS, ALLOW_ONCE, ConnectionInfo::app_comm, ConnectionInfo::app_path, cacheKey(), DENY_ALWAYS, DENY_ONCE, ConnectionInfo::dest_host, ConnectionInfo::dest_ip, m_appsPage, m_connectionsPage, m_networkPage, m_statAllowed, m_statDenied, m_statsPage, m_uiServer, m_verdictCache, AppsPage::noteConnection(), NetworkPage::noteConnection(), ConnectionsPage::saveLog(), UIServer::sendReply(), ConnectionsPage::setLastVerdict(), setStatus(), and StatsPage::updateStats().

Referenced by onNewConnection().

◆ open_backup_flow()

void MainWindow.open_backup_flow ( )
inlineprivate

Definition at line 762 of file MainWindow.vala.

762 {
763 var embedded = new BackupWindow(true);
764 embedded.request_close.connect(() => {
765 refresh_all();
766 ui_sensitive(true);
768 });
769 set_dynamic_page("backup_flow", ref backup_page_widget, embedded.detach_root_widget());
770 }
BackupWindow(bool embedded=false)
Gtk.? Widget backup_page_widget
void set_dynamic_page(string name, ref Gtk.Widget? slot, Gtk.Widget widget)

References backup_page_widget, BackupWindow.BackupWindow(), refresh_all(), set_dynamic_page(), show_snapshots_page(), and ui_sensitive().

Referenced by create_snapshot().

◆ open_delete_flow()

void MainWindow.open_delete_flow ( )
inlineprivate

Definition at line 772 of file MainWindow.vala.

772 {
773 var embedded = new DeleteWindow(true);
774 embedded.request_close.connect(() => {
775 refresh_all();
776 ui_sensitive(true);
778 });
779 set_dynamic_page("delete_flow", ref delete_page_widget, embedded.detach_root_widget());
780 }
DeleteWindow(bool embedded=false)
Gtk.? Widget delete_page_widget

References delete_page_widget, DeleteWindow.DeleteWindow(), refresh_all(), set_dynamic_page(), show_snapshots_page(), and ui_sensitive().

Referenced by check_if_deletion_running(), and delete_selected().

◆ open_restore_flow()

void MainWindow.open_restore_flow ( )
inlineprivate

Definition at line 782 of file MainWindow.vala.

782 {
783 var embedded = new RestoreWindow(true);
784 embedded.request_close.connect(() => {
785 App.dry_run = false;
787 refresh_all();
789 });
790 set_dynamic_page("restore_flow", ref restore_page_widget, embedded.detach_root_widget());
791 }
Gtk.? Widget restore_page_widget
RestoreWindow(bool embedded=false)

References App, SnapshotRepo.load_snapshots(), refresh_all(), Main.repo, restore_page_widget, RestoreWindow.RestoreWindow(), set_dynamic_page(), and show_snapshots_page().

Referenced by restore().

◆ open_rsync_log_page()

void MainWindow.open_rsync_log_page ( string log_file)
inlineprivate

Definition at line 793 of file MainWindow.vala.

793 {
794 var embedded = new RsyncLogWindow(log_file, true);
795 embedded.request_close.connect(() => {
797 });
798 set_dynamic_page("rsync_log", ref rsync_log_page_widget, embedded.detach_root_widget());
799 }
Gtk.? Widget rsync_log_page_widget
RsyncLogWindow(string _rsync_log_file, bool embedded=false)

References rsync_log_page_widget, RsyncLogWindow.RsyncLogWindow(), set_dynamic_page(), and show_snapshots_page().

Referenced by view_snapshot_log().

◆ open_settings_window()

void MainWindow::open_settings_window ( )

Definition at line 493 of file MainWindow.cpp.

494{
495 if (settings_window_) {
496 settings_window_->present();
497 return;
498 }
499
501 settings_window_->set_transient_for(*this);
502 settings_window_->set_modal(true);
503
504 settings_window_->signal_close_request().connect(
505 [this]() -> bool {
506 settings_window_->hide();
507 return true;
508 },
509 false
510 );
511
512 settings_window_->present();
513}
SettingsWindow * settings_window_

References clamdConfig_, settings_window_, and SettingsWindow::SettingsWindow().

Referenced by build_sidebar(), and ClamApp::launch_main_window().

◆ page_requires_expanded_window()

bool MainWindow.page_requires_expanded_window ( string page)
inlineprivate

Definition at line 683 of file MainWindow.vala.

683 {
684 switch (page) {
685 case "settings_page":
686 case "wizard":
687 case "backup_flow":
688 case "restore_flow":
689 case "delete_flow":
690 case "rsync_log":
691 return true;
692 default:
693 return false;
694 }
695 }

Referenced by apply_window_mode_for_page().

◆ pollDesktopActivity()

bool MainWindow::pollDesktopActivity ( )
private

Definition at line 751 of file MainWindow.cpp.

752{
753 const auto screensaver_active = queryScreensaverActive();
754
755 // Se il DE non espone lo stato screen saver/lock, restiamo attivi:
756 // meglio non spegnere il monitoraggio mentre l’utente sta lavorando.
757 const bool desktop_active = screensaver_active ? !*screensaver_active : true;
758 sendDesktopActivityState(desktop_active);
759 return true;
760}
std::optional< bool > queryScreensaverActive()

References sendDesktopActivityState().

Referenced by onDaemonConnected(), and startDesktopActivityMonitor().

◆ populate_device_lists()

void MainWindow::populate_device_lists ( )
private

Definition at line 650 of file main_window.cpp.

650 {
651 while (auto* child = devices_list_.get_first_child()) devices_list_.remove(*child);
652 while (auto* child = recovery_devices_list_.get_first_child()) recovery_devices_list_.remove(*child);
653
654 int selected_index = -1;
655
656 for (size_t i = 0; i < devices_.size(); ++i) {
657 const auto& d = devices_[i];
658
659 auto make_row = [&](bool include_path_first) -> Gtk::ListBoxRow* {
660 auto* row_box = Gtk::make_managed<Gtk::Box>(Gtk::Orientation::VERTICAL, 4);
661 row_box->set_margin_top(10);
662 row_box->set_margin_bottom(10);
663 row_box->set_margin_start(12);
664 row_box->set_margin_end(12);
665
666 std::ostringstream title;
667 if (include_path_first)
668 title << d.path << " • " << human_size(d.size_bytes);
669 else
670 title << d.name << " • " << human_size(d.size_bytes);
671
672 std::ostringstream subtitle;
673 subtitle << (d.model.empty() ? tr("Disk") : d.model) << " • "
674 << (d.transport.empty() ? tr("Block") : d.transport);
675
676 if (d.removable) subtitle << trs(" • removable");
678 subtitle << trs(" • needs elevation");
679
680 auto* lbl1 = Gtk::make_managed<Gtk::Label>(title.str());
681 auto* lbl2 = Gtk::make_managed<Gtk::Label>(subtitle.str());
682 lbl1->set_halign(Gtk::Align::START);
683 lbl2->set_halign(Gtk::Align::START);
684 lbl1->set_xalign(0.0f);
685 lbl2->set_xalign(0.0f);
686 lbl1->add_css_class("subtitle");
687 lbl2->add_css_class("small-label");
688 row_box->append(*lbl1);
689 row_box->append(*lbl2);
690
691 auto* row = Gtk::make_managed<Gtk::ListBoxRow>();
692 row->set_child(*row_box);
693 return row;
694 };
695
696 devices_list_.append(*make_row(true));
697 recovery_devices_list_.append(*make_row(true));
698
699 if (!selected_source_path_.empty() && d.path == selected_source_path_) {
700 selected_index = static_cast<int>(i);
701 }
702 }
703
704 devices_list_.unselect_all();
705 recovery_devices_list_.unselect_all();
706
707 if (selected_index >= 0) {
708 if (auto* row = devices_list_.get_row_at_index(selected_index))
709 devices_list_.select_row(*row);
710 if (auto* row = recovery_devices_list_.get_row_at_index(selected_index))
711 recovery_devices_list_.select_row(*row);
712 }
713}

References PrivilegeUtils::can_read_source(), devices_, devices_list_, human_size(), PrivilegeUtils::is_running_as_root(), recovery_devices_list_, selected_source_path_, tr(), and trs().

Referenced by activate_sidebar_button(), and refresh_devices().

◆ populate_scan_results()

void MainWindow::populate_scan_results ( const ScanReport & report)
private

Definition at line 1109 of file main_window.cpp.

1109 {
1110 while (auto* child = results_tree_box_.get_first_child())
1111 results_tree_box_.remove(*child);
1112
1113 result_selection_.assign(report.results.size(), false);
1114 result_check_buttons_.assign(report.results.size(), nullptr);
1115
1116 std::map<std::string, std::vector<size_t>> subgroups;
1117 size_t count = 0;
1118
1119 for (size_t report_index = 0; report_index < report.results.size(); ++report_index) {
1120 const auto& r = report.results[report_index];
1121 if (r.kind == ResultKind::Info || r.kind == ResultKind::Warning || r.kind == ResultKind::Error)
1122 continue;
1123 ++count;
1124 result_selection_[report_index] = true;
1125 subgroups[result_subgroup_label(r)].push_back(report_index);
1126 }
1127
1128 const std::string scan_root_name = !selected_source_label_.empty()
1130 : (!report.input_path.empty() ? report.input_path : std::string(trs("Scanned source")));
1131
1132 auto* root_expander = Gtk::make_managed<Gtk::Expander>();
1133 root_expander->set_label(scan_root_name + " (" + std::to_string(count) + ")");
1134 root_expander->set_expanded(true);
1135
1136 auto* root_box = Gtk::make_managed<Gtk::Box>(Gtk::Orientation::VERTICAL, 6);
1137 root_box->set_margin_top(6);
1138 root_box->set_margin_bottom(6);
1139 root_box->set_margin_start(6);
1140 root_box->set_margin_end(6);
1141
1142 if (count == 0) {
1143 auto* empty = Gtk::make_managed<Gtk::Label>(trs("No recoverable items found in this scan result."));
1144 empty->set_halign(Gtk::Align::START);
1145 empty->set_xalign(0.0f);
1146 empty->add_css_class("small-label");
1147 root_box->append(*empty);
1148 }
1149
1150 for (const auto& subgroup_entry : subgroups) {
1151 const auto& subgroup_name = subgroup_entry.first;
1152 const auto& indices = subgroup_entry.second;
1153
1154 auto* sub_expander = Gtk::make_managed<Gtk::Expander>();
1155 sub_expander->set_label(subgroup_name + " (" + std::to_string(indices.size()) + ")");
1156 sub_expander->set_expanded(true);
1157
1158 auto* subgroup_box = Gtk::make_managed<Gtk::Box>(Gtk::Orientation::VERTICAL, 4);
1159 subgroup_box->set_margin_top(4);
1160 subgroup_box->set_margin_bottom(4);
1161 subgroup_box->set_margin_start(8);
1162 subgroup_box->set_margin_end(4);
1163
1164 for (size_t report_index : indices) {
1165 const auto& r = report.results[report_index];
1166
1167 auto* row_layout = Gtk::make_managed<Gtk::Box>(Gtk::Orientation::HORIZONTAL, 10);
1168 row_layout->set_margin_top(6);
1169 row_layout->set_margin_bottom(6);
1170 row_layout->set_margin_start(10);
1171 row_layout->set_margin_end(10);
1172
1173 auto* check = Gtk::make_managed<Gtk::CheckButton>();
1174 check->set_active(true);
1175 check->set_valign(Gtk::Align::START);
1176 check->signal_toggled().connect([this, report_index, check]() {
1177 if (report_index < result_selection_.size()) {
1178 result_selection_[report_index] = check->get_active();
1180 }
1181 });
1182 if (report_index < result_check_buttons_.size()) result_check_buttons_[report_index] = check;
1183 row_layout->append(*check);
1184
1185 auto* row_box = Gtk::make_managed<Gtk::Box>(Gtk::Orientation::VERTICAL, 3);
1186 row_box->set_hexpand(true);
1187
1188 std::ostringstream title;
1189 title << r.type;
1190 if (r.size_bytes > 0)
1191 title << " • " << human_size(r.size_bytes);
1192
1193 std::ostringstream sub;
1194 sub << trs("Offset: ") << r.offset_bytes
1195 << " (0x" << std::hex << std::uppercase << r.offset_bytes << std::dec << ")";
1196 if (r.confidence > 0.0) {
1197 std::ostringstream conf;
1198 conf << std::fixed << std::setprecision(0) << (r.confidence * 100.0) << "%";
1199 sub << trs(" • Confidence: ") << conf.str();
1200 }
1201 if (!r.source.empty())
1202 sub << " • " << r.source;
1203
1204 auto* lbl_title = Gtk::make_managed<Gtk::Label>(title.str());
1205 lbl_title->set_halign(Gtk::Align::START);
1206 lbl_title->set_xalign(0.0f);
1207 lbl_title->add_css_class("subtitle");
1208
1209 auto* lbl_sub = Gtk::make_managed<Gtk::Label>(sub.str());
1210 lbl_sub->set_halign(Gtk::Align::START);
1211 lbl_sub->set_xalign(0.0f);
1212 lbl_sub->add_css_class("small-label");
1213 lbl_sub->set_ellipsize(Pango::EllipsizeMode::END);
1214
1215 row_box->append(*lbl_title);
1216 row_box->append(*lbl_sub);
1217
1218 if (!r.detail.empty()) {
1219 auto* lbl_detail = Gtk::make_managed<Gtk::Label>(r.detail);
1220 lbl_detail->set_halign(Gtk::Align::START);
1221 lbl_detail->set_xalign(0.0f);
1222 lbl_detail->add_css_class("small-label");
1223 lbl_detail->set_wrap(true);
1224 lbl_detail->set_wrap_mode(Pango::WrapMode::WORD_CHAR);
1225 row_box->append(*lbl_detail);
1226 }
1227
1228 row_layout->append(*row_box);
1229 subgroup_box->append(*row_layout);
1230 }
1231
1232 sub_expander->set_child(*subgroup_box);
1233 root_box->append(*sub_expander);
1234 }
1235
1236 root_expander->set_child(*root_box);
1237 results_tree_box_.append(*root_expander);
1238
1239 std::ostringstream cnt;
1240 if (count == 0) {
1241 cnt << trs("No recoverable items found.");
1242 } else if (count == 1) {
1243 cnt << count << trs(" recoverable item detected in this scan.");
1244 } else {
1245 cnt << count << trs(" recoverable items detected in this scan.");
1246 }
1247 results_count_label_.set_text(cnt.str());
1248
1249 std::ostringstream rec_msg;
1250 rec_msg << trs("Destination: ")
1251 << (output_dir_.empty() ? std::string(trs("not selected")) : output_dir_)
1252 << "\n"
1253 << trs("Scan result: ") << scan_root_name
1254 << "\n"
1255 << trs("This tree belongs to the current scan result. Select all items or only the entries you want to recover, then click \"Start recovery\".");
1256
1257 recover_step_label_.set_text(rec_msg.str());
1259}
std::string selected_source_label_
static std::string result_subgroup_label(const ScanResult &result)
std::vector< Gtk::CheckButton * > result_check_buttons_
std::vector< bool > result_selection_
std::string input_path
Definition models.hpp:38

References Error, human_size(), Info, ScanReport::input_path, output_dir_, recover_step_label_, result_check_buttons_, result_selection_, result_subgroup_label(), ScanReport::results, results_count_label_, results_tree_box_, selected_source_label_, trs(), update_selected_results_state(), and Warning.

Referenced by on_language_changed(), and on_scan_completed().

◆ read_language()

std::string MainWindow::read_language ( )
staticprivate

Definition at line 1441 of file main_window.cpp.

1441 {
1442 const std::string path =
1443 Glib::get_home_dir() + "/.config/bastionguard-recovery-data/lang.conf";
1444
1445 std::ifstream f(path);
1446 if (!f.is_open()) return "en";
1447
1448 std::string val;
1449 f >> val;
1450
1451 static const std::unordered_set<std::string> supported = {
1452 "en", "it", "de", "es", "fr", "ja", "nl", "pl", "pt", "ru", "ar"
1453 };
1454
1455 return supported.count(val) ? val : "en";
1456}

Referenced by build_sidebar(), and on_language_changed().

◆ read_theme()

std::string MainWindow::read_theme ( )
staticprivate

Definition at line 1467 of file main_window.cpp.

1467 {
1468 const std::string path =
1469 Glib::get_home_dir() + "/.config/bastionguard-recovery-data/theme.conf";
1470
1471 std::ifstream f(path);
1472 if (!f.is_open()) return "dark";
1473
1474 std::string val;
1475 f >> val;
1476
1477 if (val == "dark" || val == "light")
1478 return val;
1479
1480 return "dark";
1481}

Referenced by on_language_changed().

◆ refresh_all()

bool MainWindow.refresh_all ( )
inlineprivate

Definition at line 1114 of file MainWindow.vala.

1114 {
1115 ui_sensitive(false);
1118 ui_sensitive(true);
1119 return false;
1120 }
void update_statusbar()

References SnapshotListBox.refresh(), snapshot_list_box, ui_sensitive(), and update_statusbar().

Referenced by init_delayed(), open_backup_flow(), open_delete_flow(), open_restore_flow(), and settings_changed().

◆ refresh_devices()

void MainWindow::refresh_devices ( )
private

Definition at line 641 of file main_window.cpp.

641 {
644
645 std::ostringstream ss;
646 ss << trs("Detected devices: ") << devices_.size();
647 update_card_label_.set_text(ss.str());
648}
static std::vector< DeviceInfo > enumerate_linux_block_devices(bool include_health_probe=false)
void populate_device_lists()

References devices_, DeviceEnumerator::enumerate_linux_block_devices(), populate_device_lists(), trs(), and update_card_label_.

Referenced by activate_sidebar_button(), and on_refresh_devices().

◆ refreshSystemIntegrationStatus()

void MainWindow::refreshSystemIntegrationStatus ( )
private

Definition at line 1048 of file MainWindow.cpp.

1049{
1050 const bool serviceEnabled = runCommand(
1051 shellQuote(kServiceCtlPath) + " --system is-enabled " +
1052 shellQuote(kServiceName) + " >/dev/null 2>&1");
1053 const bool autostartPresent = std::filesystem::exists(kSystemAutostartDesktop) ||
1054 std::filesystem::exists(kFallbackSystemAutostartDesktop);
1055 std::string text;
1056 if (m_protectionEnabled) {
1057 text = _("Protezione attiva nelle impostazioni utente.");
1058 } else {
1059 text = _("Protezione disattivata nelle impostazioni utente.");
1060 }
1061 text += std::string(" ") + (serviceEnabled ? _("Servizio di sistema abilitato.") : _("Servizio di sistema disabilitato."));
1062 text += std::string(" ") + (autostartPresent ? _("Avvio automatico presente.") : _("Avvio automatico assente."));
1063 if (!m_autostartBackupFile.empty() && std::filesystem::exists(m_autostartBackupFile)) {
1064 text += std::string(" ") + _("Backup autostart disponibile.");
1065 }
1069}

References _, m_autostartBackupFile, m_protectionEnabled, m_settingsPage, SettingsPage::refreshState(), SettingsPage::setProtectionEnabled(), and SettingsPage::setSystemIntegrationStatus().

◆ reload_themed_icons()

void MainWindow.reload_themed_icons ( )
inlineprivate

Definition at line 1387 of file MainWindow.vala.

1387 {
1390 for (int i = 0; i < themed_img_list.size; i++) {
1391 var img = themed_img_list[i];
1392 var name = themed_img_name[i];
1393 var sz = themed_img_size[i];
1394 var pix = IconManager.lookup(name, sz);
1395 if (pix != null) {
1396 img.set_from_pixbuf(pix);
1397 } else {
1398 img.set_from_icon_name(name);
1399 }
1400 }
1401 }
Gee.ArrayList< Gtk.Image > themed_img_list
Gee.ArrayList< int > themed_img_size
Gee.ArrayList< string > themed_img_name

References embedded_settings, embedded_wizard, IconManager.lookup(), SettingsWindow.reload_themed_icons(), SetupWizardWindow.reload_themed_icons(), themed_img_list, themed_img_name, and themed_img_size.

Referenced by load_css().

◆ remember_compact_window_size()

void MainWindow.remember_compact_window_size ( )
inlineprivate

Definition at line 697 of file MainWindow.vala.

697 {
699 return;
700
701 int current_width = this.get_width();
702 int current_height = this.get_height();
703
704 if (current_width > 0)
705 compact_window_width = current_width;
706 if (current_height > 0)
707 compact_window_height = current_height;
708 }

References compact_window_height, compact_window_width, and window_in_expanded_mode.

Referenced by apply_window_mode_for_page().

◆ resize_main_window()

void MainWindow.resize_main_window ( int width,
int height )
inlineprivate

Definition at line 710 of file MainWindow.vala.

710 {
711 this.set_default_size(width, height);
712 this.set_size_request(width, height);
713 Idle.add(() => {
714 this.set_size_request(-1, -1);
715 return false;
716 });
717 }

References Idle.

Referenced by apply_window_mode_for_page().

◆ restart_application()

void MainWindow.restart_application ( )
inlineprivate

Spawns a fresh instance of the application and exits the current one. The new process reads language.json at startup and loads the correct locale before any _() call — this is the only reliable way to switch gettext locale.

Definition at line 399 of file MainWindow.vala.

399 {
400 string exe_path = "";
401 try {
402 exe_path = GLib.FileUtils.read_link("/proc/self/exe");
403 } catch (Error e) {
404 log_error("restart: cannot read /proc/self/exe: " + e.message);
405 App.exit_app(0);
406 return;
407 }
408
409 string[] argv = { exe_path };
410
411 try {
412 GLib.Process.spawn_async(
413 null,
414 argv,
415 null,
416 GLib.SpawnFlags.SEARCH_PATH | GLib.SpawnFlags.DO_NOT_REAP_CHILD,
417 null,
418 null
419 );
420 } catch (Error e) {
421 log_error("restart: spawn failed: " + e.message);
422 App.exit_app(0);
423 return;
424 }
425
426 App.exit_app(0);
427 }

References App, Error, Main.exit_app(), and TeeJee.Logging.log_error().

Referenced by on_language_changed().

◆ restore()

void MainWindow.restore ( )
inlineprivate

Definition at line 1259 of file MainWindow.vala.

1259 {
1260 if (!App.mirror_system) {
1261 var selected = snapshot_list_box.selected_snapshots();
1262 if (selected.size == 0) {
1263 gtk_messagebox(_("No snapshots selected"), _("Select the snapshot to restore"), this, false);
1264 return;
1265 }
1266 if (selected.size > 1) {
1267 gtk_messagebox(_("Multiple snapshots selected"), _("Select a single snapshot"), this, false);
1268 return;
1269 }
1270 Snapshot snap = selected[0];
1271 if ((snap != null) && snap.marked_for_deletion) {
1272 gtk_messagebox(_("Invalid snapshot"),
1273 _("Selected snapshot is marked for deletion"), this, false);
1274 return;
1275 }
1276 App.snapshot_to_restore = snap;
1277 } else {
1278 App.snapshot_to_restore = null;
1279 }
1282 }
void open_restore_flow()
bool mirror_system
Definition Main.vala:85
void init_mount_list()
Definition Main.vala:2075
bool marked_for_deletion
Definition Snapshot.vala:51

References _, App, Main.init_mount_list(), Snapshot.marked_for_deletion, Main.mirror_system, open_restore_flow(), SnapshotListBox.selected_snapshots(), and snapshot_list_box.

Referenced by btn_restore_clicked().

◆ result_group_label()

std::string MainWindow::result_group_label ( const ScanResult & result)
staticprivate

Definition at line 1085 of file main_window.cpp.

1085 {
1086 if (result.type.find("NTFS") != std::string::npos) return "NTFS";
1087 if (result.type.find("ext4") != std::string::npos || result.type.find("EXT4") != std::string::npos) return "ext4";
1088 if (result.type.find("Btrfs") != std::string::npos || result.type.find("BTRFS") != std::string::npos) return "Btrfs";
1089 if (result.type.find("exFAT") != std::string::npos) return "exFAT";
1090 if (result.type.find("FAT32") != std::string::npos) return "FAT32";
1091 if (result.kind == ResultKind::Partition || result.kind == ResultKind::LostPartitionCandidate) return "Partitions";
1092 return "Other detected items";
1093}
@ Partition
Definition models.hpp:8
@ LostPartitionCandidate
Definition models.hpp:9
std::string type
Definition models.hpp:23
ResultKind kind
Definition models.hpp:20

References ScanResult::kind, LostPartitionCandidate, Partition, and ScanResult::type.

Referenced by on_language_changed().

◆ result_subgroup_label()

std::string MainWindow::result_subgroup_label ( const ScanResult & result)
staticprivate

Definition at line 1095 of file main_window.cpp.

1095 {
1096 switch (result.kind) {
1097 case ResultKind::Partition: return "Partitions";
1098 case ResultKind::LostPartitionCandidate: return "Lost partitions";
1099 case ResultKind::FilesystemCandidate: return "Filesystem candidates";
1101 case ResultKind::NtfsVolume: return "Volumes";
1102 case ResultKind::NtfsMetadata: return "Metadata";
1103 default: break;
1104 }
1105 if (result.type.find("$MFT") != std::string::npos) return "Metadata";
1106 return "Items";
1107}
@ NtfsMetadata
Definition models.hpp:13
@ FilesystemCandidate
Definition models.hpp:10
@ FilesystemVolume
Definition models.hpp:11

References FilesystemCandidate, FilesystemVolume, ScanResult::kind, LostPartitionCandidate, NtfsMetadata, NtfsVolume, Partition, and ScanResult::type.

Referenced by on_language_changed(), and populate_scan_results().

◆ save_language()

void MainWindow::save_language ( const std::string & lang_code)
staticprivate

Definition at line 1458 of file main_window.cpp.

1458 {
1459 const std::string dir =
1460 Glib::get_home_dir() + "/.config/bastionguard-recovery-data";
1461
1462 std::filesystem::create_directories(dir);
1463 std::ofstream f(dir + "/lang.conf");
1464 if (f.is_open()) f << lang_code << "\n";
1465}

Referenced by on_language_changed().

◆ save_language_preference()

void MainWindow.save_language_preference ( string lang_code)
inlineprivate

Definition at line 310 of file MainWindow.vala.

310 {
311 try {
312 if (!FileUtils.test(THEME_CONFIG_DIR, FileTest.IS_DIR)) {
313 DirUtils.create_with_parents(THEME_CONFIG_DIR, 0755);
314 }
315
316 string json = "{\n\t\"language\": \"%s\"\n}\n".printf(lang_code);
317 FileUtils.set_contents(LANG_CONFIG_FILE, json);
318
319 log_debug("Lingua salvata in " + LANG_CONFIG_FILE + ": " + lang_code);
320 }
321 catch (Error e) {
322 log_error("Errore salvataggio language config: " + e.message);
323 }
324 }
nlohmann::json json
Definition Backend.cpp:2908
const string THEME_CONFIG_DIR

References Error, LANG_CONFIG_FILE, TeeJee.Logging.log_debug(), TeeJee.Logging.log_error(), and THEME_CONFIG_DIR.

Referenced by on_language_changed().

◆ save_theme()

void MainWindow::save_theme ( const std::string & theme_code)
staticprivate

Definition at line 1483 of file main_window.cpp.

1483 {
1484 const std::string dir =
1485 Glib::get_home_dir() + "/.config/bastionguard-recovery-data";
1486
1487 std::filesystem::create_directories(dir);
1488 std::ofstream f(dir + "/theme.conf");
1489 if (f.is_open()) f << theme_code << "\n";
1490}

Referenced by on_language_changed(), on_theme_dark(), and on_theme_light().

◆ save_theme_preference()

void MainWindow.save_theme_preference ( bool use_dark)
inlineprivate

Definition at line 239 of file MainWindow.vala.

239 {
240 try {
241 // Crea la directory se manca
242 if (!FileUtils.test(THEME_CONFIG_DIR, FileTest.IS_DIR)) {
243 DirUtils.create_with_parents(THEME_CONFIG_DIR, 0755);
244 }
245
246 string theme = use_dark ? "dark" : "light";
247 string json = "{\n\t\"theme\": \"%s\"\n}\n".printf(theme);
248
249 FileUtils.set_contents(THEME_CONFIG_FILE, json);
250
251 log_debug("Theme salvato in " + THEME_CONFIG_FILE + ": " + theme);
252 }
253 catch (Error e) {
254 log_error("Errore salvataggio theme config: " + e.message);
255 }
256 }

References Error, TeeJee.Logging.log_debug(), TeeJee.Logging.log_error(), THEME_CONFIG_DIR, and THEME_CONFIG_FILE.

Referenced by apply_theme().

◆ saveConfig()

void MainWindow::saveConfig ( )
private

Definition at line 312 of file MainWindow.cpp.

313{
314 try {
315 std::filesystem::create_directories(
316 std::filesystem::path(m_configFile).parent_path());
317 std::ofstream f(m_configFile);
318 f << "[General]\n";
319 f << "dark_mode=" << (m_darkMode ? "true" : "false") << "\n";
320 if (!m_language.empty())
321 f << "language=" << m_language << "\n";
322 f << "protection_enabled=" << (m_protectionEnabled ? "true" : "false") << "\n";
323 if (!m_autostartBackupFile.empty())
324 f << "autostart_backup=" << m_autostartBackupFile << "\n";
325 } catch (const std::exception& e) {
326 std::cerr << "⚠ Impossibile salvare config: " << e.what() << "\n";
327 }
328}

References m_autostartBackupFile, m_configFile, m_darkMode, m_language, and m_protectionEnabled.

Referenced by applyProtectionEnabled(), and applyTheme().

◆ select_source()

void MainWindow::select_source ( const std::string & path,
const std::string & label )
private

Definition at line 715 of file main_window.cpp.

715 {
718 last_report_ = {};
719
720 int selected_index = -1;
721 for (size_t i = 0; i < devices_.size(); ++i) {
722 if (devices_[i].path == path) {
723 selected_index = static_cast<int>(i);
724 break;
725 }
726 }
727
728 devices_list_.unselect_all();
729 recovery_devices_list_.unselect_all();
730
731 if (selected_index >= 0) {
732 if (auto* dashboard_row = devices_list_.get_row_at_index(selected_index))
733 devices_list_.select_row(*dashboard_row);
734
735 if (auto* wizard_row = recovery_devices_list_.get_row_at_index(selected_index))
736 recovery_devices_list_.select_row(*wizard_row);
737 }
738
740 append_log(trs("Selected source: ") + label);
741}

References append_log(), devices_, devices_list_, last_report_, recovery_devices_list_, selected_source_label_, selected_source_path_, trs(), and update_source_state().

Referenced by activate_sidebar_button(), on_dashboard_device_activated(), on_open_image(), and on_use_selected_device().

◆ selected_result_indices()

std::vector< size_t > MainWindow::selected_result_indices ( ) const
private

Definition at line 1275 of file main_window.cpp.

1275 {
1276 std::vector<size_t> out;
1277 for (size_t i = 0; i < result_selection_.size(); ++i) {
1278 if (result_selection_[i]) {
1279 const auto& r = last_report_.results[i];
1280 if (r.kind == ResultKind::Info || r.kind == ResultKind::Warning || r.kind == ResultKind::Error) continue;
1281 out.push_back(i);
1282 }
1283 }
1284 return out;
1285}

References Error, Info, last_report_, result_selection_, ScanReport::results, and Warning.

Referenced by on_language_changed(), on_recover_now(), and update_selected_results_state().

◆ sendDesktopActivityState()

void MainWindow::sendDesktopActivityState ( bool active,
bool force = false )
private

Definition at line 768 of file MainWindow.cpp.

769{
770 if (!force && active == m_desktopActiveSent) return;
771 m_desktopActiveSent = active;
772
773 m_uiServer.queueNotification(active ? kNotifDesktopActive : kNotifDesktopIdle, "{}");
774 if (!active) {
775 setStatus(_("⏸ Desktop inattivo: monitoraggio connessioni sospeso"));
776 }
777}
void queueNotification(int type, const std::string &data={})
Definition UIServer.cpp:423

References _, m_desktopActiveSent, m_uiServer, UIServer::queueNotification(), and setStatus().

Referenced by noteDesktopActivity(), onDaemonConnected(), and pollDesktopActivity().

◆ set_all_results_selected()

void MainWindow::set_all_results_selected ( bool selected)
private

Definition at line 1287 of file main_window.cpp.

1287 {
1288 for (size_t i = 0; i < last_report_.results.size(); ++i) {
1289 const auto& r = last_report_.results[i];
1290 if (r.kind == ResultKind::Info || r.kind == ResultKind::Warning || r.kind == ResultKind::Error) continue;
1291 if (i < result_selection_.size()) result_selection_[i] = selected;
1292 if (i < result_check_buttons_.size() && result_check_buttons_[i]) {
1293 result_check_buttons_[i]->set_active(selected);
1294 }
1295 }
1297}

References Error, Info, last_report_, result_check_buttons_, result_selection_, ScanReport::results, update_selected_results_state(), and Warning.

Referenced by on_language_changed().

◆ set_dynamic_page()

void MainWindow.set_dynamic_page ( string name,
ref Gtk.Widget? slot,
Gtk.Widget widget )
inlineprivate

Definition at line 751 of file MainWindow.vala.

751 {
752 if (slot != null) {
753 content_stack.remove(slot);
754 slot = null;
755 }
756 slot = widget;
757 content_stack.add_named(slot, name);
758 content_stack.set_visible_child_name(name);
760 }

References apply_window_mode_for_page(), and content_stack.

Referenced by open_backup_flow(), open_delete_flow(), open_restore_flow(), and open_rsync_log_page().

◆ setStatus()

void MainWindow::setStatus ( const std::string & msg)
private

◆ settings_changed()

void MainWindow.settings_changed ( bool btrfs_mode_prev)
inlineprivate

Definition at line 1296 of file MainWindow.vala.

1296 {
1297 if (btrfs_mode_prev != App.btrfs_mode) {
1298 if ((App.repo != null) && (App.repo.device != null) && (App.repo.device.uuid.length > 0))
1299 App.repo = new SnapshotRepo.from_uuid(App.repo.device.uuid, this, App.btrfs_mode);
1300 else if ((App.sys_root != null) && (App.sys_root.fstype == "btrfs"))
1301 App.repo = new SnapshotRepo.from_uuid(App.sys_root.uuid, this, App.btrfs_mode);
1302 else
1303 App.repo = new SnapshotRepo.from_null();
1304 }
1307 refresh_all();
1308 }
string uuid
Definition Device.vala:50
string fstype
Definition Device.vala:65
Device sys_root
Definition Main.vala:75
void save_app_config()
Definition Main.vala:3338

References App, Main.btrfs_mode, SnapshotRepo.device, SnapshotRepo.from_null(), SnapshotRepo.from_uuid(), Device.fstype, SnapshotRepo.load_snapshots(), refresh_all(), Main.repo, Main.save_app_config(), Main.sys_root, and Device.uuid.

◆ show_settings()

void MainWindow.show_settings ( )
inline

Definition at line 1285 of file MainWindow.vala.

1285 {
1287 }
void btn_settings_clicked()

References btn_settings_clicked().

◆ show_snapshots_page()

void MainWindow.show_snapshots_page ( )
inlineprivate

◆ showDashboard()

void MainWindow::showDashboard ( )

Definition at line 465 of file MainWindow.cpp.

465 {
466 try {
467 stack_.set_visible_child("dashboard");
469
470 // grab_focus su un widget non ancora realized/mapped emette
471 // un g_critical fatale (con G_DEBUG=fatal-criticals). Posticipalo
472 // a quando la finestra è effettivamente mostrata.
473 if (dashboard_page_.get_realized() && dashboard_page_.get_mapped()) {
474 dashboard_page_.grab_focus();
475 } else {
476 Glib::signal_idle().connect_once([this]() {
477 try {
478 if (dashboard_page_.get_realized() && dashboard_page_.get_mapped()) {
479 dashboard_page_.grab_focus();
480 }
481 } catch (...) {}
482 });
483 }
484
485 std::cout << _("[MainWindow] Ritorno alla Dashboard") << std::endl;
486 } catch (const std::exception& e) {
487 std::cerr << _("⚠ Errore durante il ritorno alla Dashboard: ") << e.what() << std::endl;
488 } catch (...) {
489 std::cerr << _("⚠ Errore sconosciuto durante il ritorno alla Dashboard") << std::endl;
490 }
491}

References _, activate_sidebar_button(), dashboard_button_, dashboard_page_, and stack_.

Referenced by ClamApp::launch_main_window().

◆ showLanguageDialog()

void MainWindow::showLanguageDialog ( )
private

Definition at line 414 of file MainWindow.cpp.

415{
416 m_langDialog = std::make_unique<LanguageDialog>(m_configFile, m_language);
417 m_langDialog->set_transient_for(*this);
418 m_langDialog->set_modal(true);
419 m_langDialog->signal_hide().connect([this]() {
420 // Se la lingua è cambiata aggiorna il membro (la UI si aggiorna al prossimo avvio)
421 const std::string chosen = m_langDialog->selectedLanguage();
422 if (chosen != m_language) {
423 m_language = chosen;
424 // Il file è già stato scritto da LanguageDialog::onApply()
425 setStatus(_("Lingua aggiornata — riavvia per applicare la modifica."));
426 }
427 });
428 m_langDialog->present();
429}
std::unique_ptr< LanguageDialog > m_langDialog

References _, m_configFile, m_langDialog, m_language, and setStatus().

Referenced by buildHeaderBar().

◆ startDesktopActivityMonitor()

void MainWindow::startDesktopActivityMonitor ( )
private

Definition at line 696 of file MainWindow.cpp.

697{
698 m_lastUiActivity = std::chrono::steady_clock::now();
699
700 auto install_activity_controller = [this](GtkEventController* controller) {
701 gtk_event_controller_set_propagation_phase(controller, GTK_PHASE_CAPTURE);
702 gtk_widget_add_controller(GTK_WIDGET(gobj()), controller);
703 };
704
705 auto* motion = gtk_event_controller_motion_new();
706 g_signal_connect(
707 motion,
708 "motion",
709 G_CALLBACK(+[](GtkEventControllerMotion*, double, double, gpointer data) {
710 static_cast<MainWindow*>(data)->noteDesktopActivity();
711 }),
712 this);
713 install_activity_controller(GTK_EVENT_CONTROLLER(motion));
714
715 auto* click = gtk_gesture_click_new();
716 g_signal_connect(
717 click,
718 "pressed",
719 G_CALLBACK(+[](GtkGestureClick*, int, double, double, gpointer data) {
720 static_cast<MainWindow*>(data)->noteDesktopActivity();
721 }),
722 this);
723 install_activity_controller(GTK_EVENT_CONTROLLER(click));
724
725 auto* key = gtk_event_controller_key_new();
726 g_signal_connect(
727 key,
728 "key-pressed",
729 G_CALLBACK(+[](GtkEventControllerKey*, guint, guint, GdkModifierType, gpointer data) -> gboolean {
730 static_cast<MainWindow*>(data)->noteDesktopActivity();
731 return GDK_EVENT_PROPAGATE;
732 }),
733 this);
734 install_activity_controller(GTK_EVENT_CONTROLLER(key));
735
736 // Il polling non usa “inattività della finestra BSC” perché la UI può
737 // restare nel tray mentre l’utente lavora su altre app. Usiamo invece lo
738 // stato del desktop/screen saver quando il DE lo espone via D-Bus.
739 m_desktopActivityTimer = g_timeout_add_seconds(
740 5,
741 +[](gpointer data) -> gboolean {
742 return static_cast<MainWindow*>(data)->pollDesktopActivity()
743 ? G_SOURCE_CONTINUE
744 : G_SOURCE_REMOVE;
745 },
746 this);
747
749}
void noteDesktopActivity()

References m_desktopActivityTimer, m_lastUiActivity, MainWindow(), noteDesktopActivity(), and pollDesktopActivity().

◆ themed_icon()

Gtk.Image MainWindow.themed_icon ( string icon_name,
int size )
inlineprivate

Definition at line 1379 of file MainWindow.vala.

1379 {
1380 var img = IconManager.lookup_image(icon_name, size);
1381 themed_img_list.add(img);
1382 themed_img_name.add(icon_name);
1383 themed_img_size.add(size);
1384 return img;
1385 }

References IconManager.lookup_image(), themed_img_list, themed_img_name, and themed_img_size.

Referenced by build_headerbar(), make_action_btn(), make_nav_btn(), and make_theme_btn().

◆ ui_sensitive()

void MainWindow.ui_sensitive ( bool enable)
inlineprivate

Definition at line 1314 of file MainWindow.vala.

1314 {
1315 vbox_sidebar.sensitive = enable;
1316 snapshot_list_box.sensitive = enable;
1317 gtk_set_busy(!enable, this);
1318 }
void gtk_set_busy(bool busy, Gtk.Window win)

References TeeJee.GtkHelper.gtk_set_busy().

Referenced by check_if_deletion_running(), create_snapshot(), delete_selected(), open_backup_flow(), open_delete_flow(), and refresh_all().

◆ update_action_controls()

◆ update_selected_results_state()

void MainWindow::update_selected_results_state ( )
private

Definition at line 1261 of file main_window.cpp.

1261 {
1262 const auto selected = selected_result_indices().size();
1263 size_t total = 0;
1264 for (const auto& r : last_report_.results) {
1265 if (r.kind == ResultKind::Info || r.kind == ResultKind::Warning || r.kind == ResultKind::Error) continue;
1266 ++total;
1267 }
1268 std::ostringstream ss;
1269 ss << trs("Selected items: ") << selected;
1270 if (total > 0) ss << " / " << total;
1271 results_selected_label_.set_text(ss.str());
1272 btn_recover_now_.set_sensitive(!selected_source_path_.empty() && !output_dir_.empty() && !last_report_.results.empty() && selected > 0 && !recovery_worker_.running());
1273}

References btn_recover_now_, Error, Info, last_report_, output_dir_, recovery_worker_, ScanReport::results, results_selected_label_, RecoveryWorker::running(), selected_result_indices(), selected_source_path_, trs(), and Warning.

Referenced by on_language_changed(), on_recovery_completed(), populate_scan_results(), set_all_results_selected(), and update_action_controls().

◆ update_source_state()

void MainWindow::update_source_state ( )
private

Definition at line 743 of file main_window.cpp.

743 {
744 if (selected_source_path_.empty()) {
745 source_card_label_.set_text(tr("No source selected"));
746 scan_step_label_.set_text(tr("Run a read-only scan before exporting recovered data. Non si garantisce il recupero totale dei file."));
747 recover_step_label_.set_text(tr("Export detected volumes, filesystem-level recoveries, and carved files. Non si garantisce il recupero totale dei file."));
749 return;
750 }
751
752 std::ostringstream ss;
753 ss << trs("Source selected:\n") << selected_source_label_ << "\nPath: " << selected_source_path_;
754
756 ss << trs("\nAccess: needs elevation");
757 else
758 ss << trs("\nAccess: ready");
759
760 source_card_label_.set_text(ss.str());
761
762 std::ostringstream scan_msg;
763 scan_msg << trs("Current source:\n") << selected_source_label_
764 << trs("\n\nRun a read-only scan before continuing.");
765 scan_step_label_.set_text(scan_msg.str());
766
767 std::ostringstream rec_msg;
768 rec_msg << trs("Destination: ")
769 << (output_dir_.empty() ? std::string(trs("not selected")) : output_dir_)
770 << trs("\nSource: ") << selected_source_label_
771 << trs("\n\nBrowse the recovery tree, keep all items selected or choose only the branches you want, then click \"Start recovery\".");
772 recover_step_label_.set_text(rec_msg.str());
774}

References PrivilegeUtils::can_read_source(), PrivilegeUtils::is_running_as_root(), output_dir_, recover_step_label_, scan_step_label_, selected_source_label_, selected_source_path_, source_card_label_, tr(), trs(), and update_action_controls().

Referenced by activate_sidebar_button(), on_choose_destination(), and select_source().

◆ update_statusbar()

void MainWindow.update_statusbar ( )
inlineprivate

Definition at line 1320 of file MainWindow.vala.

1320 {
1322 string message = App.repo.status_message;
1323 string details = App.repo.status_details;
1324 int status_code = App.repo.status_code;
1325
1326 switch (status_code) {
1327 case SnapshotLocationStatus.HAS_SNAPSHOTS_HAS_SPACE:
1328 img_shield.set_from_pixbuf(IconManager.lookup(
1329 IconManager.SHIELD_HIGH, 48));
1330 break;
1331 case SnapshotLocationStatus.NO_SNAPSHOTS_HAS_SPACE:
1332 case SnapshotLocationStatus.HAS_SNAPSHOTS_NO_SPACE:
1333 img_shield.set_from_pixbuf(IconManager.lookup(
1334 IconManager.SHIELD_MED, 48));
1335 break;
1336 default:
1337 img_shield.set_from_pixbuf(IconManager.lookup(
1338 IconManager.SHIELD_LOW, 48));
1339 break;
1340 }
1341
1342 lbl_status_title.set_text(message);
1343
1344 // Evita duplicazione con le card laterali
1345 switch (status_code) {
1346 case SnapshotLocationStatus.HAS_SNAPSHOTS_HAS_SPACE:
1347 lbl_status_detail.set_text(_("Repository available and ready"));
1348 break;
1349
1350 case SnapshotLocationStatus.NO_SNAPSHOTS_HAS_SPACE:
1351 lbl_status_detail.set_text(_("No snapshots yet"));
1352 break;
1353
1354 case SnapshotLocationStatus.HAS_SNAPSHOTS_NO_SPACE:
1355 lbl_status_detail.set_text(_("Low free space on backup device"));
1356 break;
1357
1358 default:
1359 lbl_status_detail.set_text(details);
1360 break;
1361 }
1362
1363 lbl_snap_count.set_text("%d".printf(App.repo.snapshots.size));
1364
1365 if ((App.repo != null) && (App.repo.device != null)) {
1368 } else {
1369 lbl_free_space.set_text("—");
1370 lbl_device_name.set_text("");
1371 }
1372 }
SnapshotLocationStatus
uint64 free_bytes
Definition Device.vala:120
string device
Definition Device.vala:44
Gee.ArrayList< Snapshot?> snapshots
SnapshotLocationStatus status_code
string format_file_size(uint64 size, bool binary_units=false, string unit="", bool show_units=true, int decimals=1)

References _, App, SnapshotRepo.check_status(), Device.device, SnapshotRepo.device, TeeJee.FileSystem.format_file_size(), Device.free_bytes, img_shield, lbl_device_name, lbl_free_space, lbl_snap_count, lbl_status_detail, lbl_status_title, IconManager.lookup(), Main.repo, IconManager.SHIELD_HIGH, IconManager.SHIELD_LOW, IconManager.SHIELD_MED, SnapshotRepo.snapshots, SnapshotRepo.status_code, SnapshotRepo.status_details, and SnapshotRepo.status_message.

Referenced by refresh_all().

◆ update_theme_buttons() [1/2]

void MainWindow.update_theme_buttons ( )
inlineprivate

Definition at line 488 of file MainWindow.vala.

488 {
489 if (btn_theme_light == null || btn_theme_dark == null)
490 return;
491
492 var light_btn = btn_theme_light;
493 var dark_btn = btn_theme_dark;
494
495 if (dark_mode) {
496 dark_btn.get_style_context().add_class("active-sidebar-button");
497 light_btn.get_style_context().remove_class("active-sidebar-button");
498 }
499 else {
500 light_btn.get_style_context().add_class("active-sidebar-button");
501 dark_btn.get_style_context().remove_class("active-sidebar-button");
502 }
503 }

References btn_theme_dark, btn_theme_light, and dark_mode.

Referenced by apply_theme(), init_sidebar(), load_css(), and MainWindow().

◆ update_theme_buttons() [2/2]

◆ update_wizard_step()

void MainWindow::update_wizard_step ( )
private

◆ view_snapshot_log()

void MainWindow.view_snapshot_log ( bool view_restore_log)
inline

Definition at line 1229 of file MainWindow.vala.

1229 {
1230 var selected = snapshot_list_box.selected_snapshots();
1231 if (selected.size == 0) {
1232 gtk_messagebox(_("Select Snapshot"), _("Please select a snapshot"), this, false);
1233 return;
1234 }
1235 var bak = selected[0];
1236 string log_file = view_restore_log ? bak.rsync_restore_log_file : bak.rsync_log_file;
1237 if (file_exists(log_file) || file_exists(log_file + "-changes")) {
1238 open_rsync_log_page(log_file);
1239 }
1240 }
void open_rsync_log_page(string log_file)
bool file_exists(string file_path)

References _, TeeJee.FileSystem.file_exists(), open_rsync_log_page(), SnapshotListBox.selected_snapshots(), and snapshot_list_box.

Referenced by init_snapshots_page().

Member Data Documentation

◆ about_button_

Gtk::Button* MainWindow::about_button_ = nullptr
private

Definition at line 116 of file main_window.hpp.

Referenced by build_sidebar(), and on_sidebar_about().

◆ about_page_ [1/2]

AboutPage MainWindow::about_page_
private

Definition at line 68 of file MainWindow.hpp.

Referenced by build_about_page(), MainWindow(), and on_sidebar_about().

◆ about_page_ [2/2]

Gtk::Box MainWindow::about_page_ {Gtk::Orientation::VERTICAL, 24}
private

Definition at line 92 of file main_window.hpp.

◆ about_page_widget

Gtk.? Widget MainWindow.about_page_widget = null
private

Definition at line 33 of file MainWindow.vala.

Referenced by init_about_page().

◆ anti_ransomware_page_

AntiRansomwarePage* MainWindow::anti_ransomware_page_ = nullptr
private

Definition at line 84 of file MainWindow.hpp.

Referenced by MainWindow().

◆ backup_page_

BackupPage* MainWindow::backup_page_ = nullptr
private

Definition at line 89 of file MainWindow.hpp.

Referenced by MainWindow().

◆ backup_page_widget

Gtk.? Widget MainWindow.backup_page_widget = null
private

Definition at line 34 of file MainWindow.vala.

Referenced by open_backup_flow().

◆ bank_page_

BankPage* MainWindow::bank_page_ = nullptr
private

Definition at line 76 of file MainWindow.hpp.

Referenced by MainWindow().

◆ brand_label_

Gtk::Label MainWindow::brand_label_
private

Definition at line 107 of file main_window.hpp.

Referenced by build_sidebar().

◆ btn_about_

Gtk::Button MainWindow::btn_about_
private

Definition at line 110 of file main_window.hpp.

Referenced by build_sidebar().

◆ btn_backup

Gtk.Button MainWindow.btn_backup
private

Definition at line 71 of file MainWindow.vala.

Referenced by init_snapshots_page().

◆ btn_browse_snapshot

Gtk.Button MainWindow.btn_browse_snapshot
private

Definition at line 74 of file MainWindow.vala.

Referenced by init_snapshots_page().

◆ btn_choose_destination_

Gtk::Button MainWindow::btn_choose_destination_
private

Definition at line 147 of file main_window.hpp.

Referenced by build_wizard().

◆ btn_dashboard_

Gtk::Button MainWindow::btn_dashboard_
private

Definition at line 108 of file main_window.hpp.

Referenced by build_sidebar().

◆ btn_delete_snapshot

Gtk.Button MainWindow.btn_delete_snapshot
private

Definition at line 73 of file MainWindow.vala.

Referenced by init_snapshots_page().

◆ btn_launch_elevated_

Gtk::Button MainWindow::btn_launch_elevated_
private

Definition at line 139 of file main_window.hpp.

Referenced by build_wizard().

◆ btn_nav_about

Gtk.Button MainWindow.btn_nav_about
private

Definition at line 43 of file MainWindow.vala.

Referenced by init_sidebar().

◆ btn_nav_settings

Gtk.Button MainWindow.btn_nav_settings
private

Definition at line 41 of file MainWindow.vala.

Referenced by init_sidebar().

◆ btn_nav_snapshots

Gtk.Button MainWindow.btn_nav_snapshots
private

Definition at line 40 of file MainWindow.vala.

Referenced by init_sidebar(), MainWindow(), and show_snapshots_page().

◆ btn_nav_wizard

Gtk.Button MainWindow.btn_nav_wizard
private

Definition at line 42 of file MainWindow.vala.

Referenced by init_sidebar().

◆ btn_open_image_

Gtk::Button MainWindow::btn_open_image_
private

Definition at line 137 of file main_window.hpp.

Referenced by build_wizard().

◆ btn_recover_now_

Gtk::Button MainWindow::btn_recover_now_
private

Definition at line 166 of file main_window.hpp.

Referenced by build_wizard(), on_recover_now(), and update_selected_results_state().

◆ btn_recovery_

Gtk::Button MainWindow::btn_recovery_
private

Definition at line 109 of file main_window.hpp.

Referenced by build_sidebar().

◆ btn_refresh_

Gtk::Button MainWindow::btn_refresh_
private

Definition at line 111 of file main_window.hpp.

Referenced by build_sidebar().

◆ btn_restore

Gtk.Button MainWindow.btn_restore
private

Definition at line 72 of file MainWindow.vala.

Referenced by init_snapshots_page().

◆ btn_results_clear_

Gtk::Button MainWindow::btn_results_clear_
private

Definition at line 165 of file main_window.hpp.

Referenced by build_wizard(), and update_action_controls().

◆ btn_results_select_all_

Gtk::Button MainWindow::btn_results_select_all_
private

Definition at line 164 of file main_window.hpp.

Referenced by build_wizard(), and update_action_controls().

◆ btn_scan_now_

Gtk::Button MainWindow::btn_scan_now_
private

◆ btn_theme_dark

Gtk.? Button MainWindow.btn_theme_dark = null
private

Definition at line 50 of file MainWindow.vala.

Referenced by init_sidebar(), and update_theme_buttons().

◆ btn_theme_dark_

Gtk::Button MainWindow::btn_theme_dark_
private

Definition at line 112 of file main_window.hpp.

Referenced by build_sidebar().

◆ btn_theme_light

Gtk.? Button MainWindow.btn_theme_light = null
private

Definition at line 49 of file MainWindow.vala.

Referenced by init_sidebar(), and update_theme_buttons().

◆ btn_theme_light_

Gtk::Button MainWindow::btn_theme_light_
private

Definition at line 113 of file main_window.hpp.

Referenced by build_sidebar().

◆ btn_use_selected_device_

Gtk::Button MainWindow::btn_use_selected_device_
private

Definition at line 138 of file main_window.hpp.

Referenced by build_wizard().

◆ btn_wizard_back_

Gtk::Button MainWindow::btn_wizard_back_
private

Definition at line 130 of file main_window.hpp.

Referenced by build_wizard(), and update_wizard_step().

◆ btn_wizard_next_

Gtk::Button MainWindow::btn_wizard_next_
private

Definition at line 131 of file main_window.hpp.

Referenced by build_wizard(), and update_wizard_step().

◆ card_source_

Gtk::Frame MainWindow::card_source_
private

Definition at line 97 of file main_window.hpp.

Referenced by build_dashboard().

◆ card_status_

Gtk::Frame MainWindow::card_status_
private

Definition at line 96 of file main_window.hpp.

Referenced by build_dashboard().

◆ card_update_

Gtk::Frame MainWindow::card_update_
private

Definition at line 98 of file main_window.hpp.

Referenced by build_dashboard().

◆ cards_grid_

Gtk::Grid MainWindow::cards_grid_
private

Definition at line 95 of file main_window.hpp.

Referenced by build_dashboard().

◆ clamdConfig_

ClamdConfig MainWindow::clamdConfig_
private

Definition at line 73 of file MainWindow.hpp.

Referenced by MainWindow(), and open_settings_window().

◆ compact_window_height

int MainWindow.compact_window_height = 520
private

Definition at line 101 of file MainWindow.vala.

Referenced by apply_window_mode_for_page(), and remember_compact_window_size().

◆ compact_window_width

int MainWindow.compact_window_width = 980
private

Definition at line 100 of file MainWindow.vala.

Referenced by apply_window_mode_for_page(), and remember_compact_window_size().

◆ content_stack

◆ css_provider

Gtk.? CssProvider MainWindow.css_provider = null
private

Definition at line 47 of file MainWindow.vala.

Referenced by load_css().

◆ css_provider_

Glib::RefPtr<Gtk::CssProvider> MainWindow::css_provider_
private

Definition at line 84 of file main_window.hpp.

Referenced by apply_theme().

◆ current_lang

string MainWindow.current_lang = "en_US"
private

Definition at line 58 of file MainWindow.vala.

Referenced by init_sidebar(), MainWindow(), and on_language_changed().

◆ current_nav_btn

Gtk.? Button MainWindow.current_nav_btn = null
private

Definition at line 44 of file MainWindow.vala.

Referenced by activate_nav().

◆ current_step_

◆ current_theme_

ThemeMode MainWindow::current_theme_ = ThemeMode::Dark
private

Definition at line 81 of file main_window.hpp.

Referenced by apply_theme(), on_theme_dark(), and on_theme_light().

◆ dark_mode

bool MainWindow.dark_mode = false
private

Definition at line 48 of file MainWindow.vala.

Referenced by load_css(), MainWindow(), and update_theme_buttons().

◆ dashboard_button_

Gtk::Button * MainWindow::dashboard_button_ = nullptr
private

◆ dashboard_page_ [1/2]

DashboardPage MainWindow::dashboard_page_
private

Definition at line 70 of file MainWindow.hpp.

Referenced by build_dashboard(), MainWindow(), on_sidebar_dashboard(), and showDashboard().

◆ dashboard_page_ [2/2]

Gtk::Box MainWindow::dashboard_page_ {Gtk::Orientation::VERTICAL, 16}
private

Definition at line 90 of file main_window.hpp.

◆ def_height

int MainWindow.def_height = -1
private

Definition at line 99 of file MainWindow.vala.

◆ def_width

int MainWindow.def_width = 500
private

Definition at line 98 of file MainWindow.vala.

◆ delete_page_widget

Gtk.? Widget MainWindow.delete_page_widget = null
private

Definition at line 36 of file MainWindow.vala.

Referenced by open_delete_flow().

◆ destination_button_row_

Gtk::Box MainWindow::destination_button_row_ {Gtk::Orientation::HORIZONTAL, 8}
private

Definition at line 145 of file main_window.hpp.

Referenced by build_wizard().

◆ destination_step_box_

Gtk::Box MainWindow::destination_step_box_ {Gtk::Orientation::VERTICAL, 8}
private

Definition at line 143 of file main_window.hpp.

Referenced by build_wizard(), and update_wizard_step().

◆ destination_step_label_

Gtk::Label MainWindow::destination_step_label_
private

Definition at line 144 of file main_window.hpp.

Referenced by build_wizard().

◆ devices_

std::vector<DeviceInfo> MainWindow::devices_
private

◆ devices_frame_

Gtk::Frame MainWindow::devices_frame_
private

Definition at line 103 of file main_window.hpp.

Referenced by build_dashboard().

◆ devices_list_

Gtk::ListBox MainWindow::devices_list_
private

Definition at line 105 of file main_window.hpp.

Referenced by build_dashboard(), populate_device_lists(), and select_source().

◆ devices_scroller_

Gtk::ScrolledWindow MainWindow::devices_scroller_
private

Definition at line 104 of file main_window.hpp.

Referenced by build_dashboard().

◆ donate_page_

DonatePage MainWindow::donate_page_
private

Definition at line 69 of file MainWindow.hpp.

Referenced by MainWindow().

◆ embedded_settings

SettingsWindow? MainWindow.embedded_settings = null
private

Definition at line 82 of file MainWindow.vala.

Referenced by init_settings_page(), and reload_themed_icons().

◆ embedded_wizard

SetupWizardWindow? MainWindow.embedded_wizard = null
private

Definition at line 83 of file MainWindow.vala.

Referenced by init_wizard_page(), and reload_themed_icons().

◆ entry_output_

Gtk::Entry MainWindow::entry_output_
private

Definition at line 146 of file main_window.hpp.

Referenced by build_wizard(), and on_choose_destination().

◆ file_dialog_

Glib::RefPtr<Gtk::FileDialog> MainWindow::file_dialog_
private

Definition at line 172 of file main_window.hpp.

Referenced by on_open_image().

◆ folder_dialog_

Glib::RefPtr<Gtk::FileDialog> MainWindow::folder_dialog_
private

Definition at line 173 of file main_window.hpp.

Referenced by on_choose_destination().

◆ hbox_root

Gtk.Box MainWindow.hbox_root
private

Definition at line 28 of file MainWindow.vala.

Referenced by init_content(), init_sidebar(), and MainWindow().

◆ identity_leak_page_

IdentityLeakPage* MainWindow::identity_leak_page_ = nullptr
private

Definition at line 87 of file MainWindow.hpp.

Referenced by MainWindow().

◆ img_shield

Gtk.Image MainWindow.img_shield
private

Definition at line 89 of file MainWindow.vala.

Referenced by init_snapshots_page(), and update_statusbar().

◆ lang_changing_

bool MainWindow::lang_changing_ = false
private

Definition at line 120 of file main_window.hpp.

◆ LANG_CODES

string [] MainWindow.LANG_CODES
staticprivate
Initial value:
= {
"en_US", "ar_SA", "de_DE", "es_ES", "fr_FR",
"it_IT", "ja_JP", "nl_NL", "pl_PL", "pt_PT", "ru_RU"
}

Definition at line 61 of file MainWindow.vala.

Referenced by init_sidebar(), load_language_preference(), and on_language_changed().

◆ lang_combo

Gtk.? ComboBoxText MainWindow.lang_combo = null
private

Definition at line 57 of file MainWindow.vala.

Referenced by init_sidebar(), and on_language_changed().

◆ lang_combo_

Gtk::DropDown MainWindow::lang_combo_
private

Definition at line 119 of file main_window.hpp.

Referenced by build_sidebar().

◆ LANG_CONFIG_FILE

const string MainWindow.LANG_CONFIG_FILE = "/etc/bastionguard-backup/language.json"
staticprivate

Definition at line 54 of file MainWindow.vala.

Referenced by load_language_preference(), and save_language_preference().

◆ LANG_NAMES

string [] MainWindow.LANG_NAMES
staticprivate
Initial value:
= {
"English", "\u0627\u0644\u0639\u0631\u0628\u064a\u0629", "Deutsch", "Espa\u00f1ol", "Fran\u00e7ais",
"Italiano", "\u65e5\u672c\u8a9e", "Nederlands", "Polski", "Portugu\u00eas", "\u0420\u0443\u0441\u0441\u043a\u0438\u0439"
}

Definition at line 65 of file MainWindow.vala.

Referenced by init_sidebar().

◆ last_report_

◆ last_scan_progress_

ScanProgress MainWindow::last_scan_progress_
private

Definition at line 186 of file main_window.hpp.

Referenced by on_scan_now(), and on_scan_progress().

◆ lbl_device_name

Gtk.Label MainWindow.lbl_device_name
private

Definition at line 94 of file MainWindow.vala.

Referenced by init_snapshots_page(), and update_statusbar().

◆ lbl_free_space

Gtk.Label MainWindow.lbl_free_space
private

Definition at line 93 of file MainWindow.vala.

Referenced by init_snapshots_page(), and update_statusbar().

◆ lbl_snap_count

Gtk.Label MainWindow.lbl_snap_count
private

Definition at line 92 of file MainWindow.vala.

Referenced by init_snapshots_page(), and update_statusbar().

◆ lbl_status_detail

Gtk.Label MainWindow.lbl_status_detail
private

Definition at line 91 of file MainWindow.vala.

Referenced by init_snapshots_page(), and update_statusbar().

◆ lbl_status_title

Gtk.Label MainWindow.lbl_status_title
private

Definition at line 90 of file MainWindow.vala.

Referenced by init_snapshots_page(), and update_statusbar().

◆ log_buffer_

Glib::RefPtr<Gtk::TextBuffer> MainWindow::log_buffer_
private

Definition at line 170 of file main_window.hpp.

Referenced by append_log().

◆ log_page_

LogPage MainWindow::log_page_
private

Definition at line 72 of file MainWindow.hpp.

Referenced by MainWindow().

◆ log_scroller_

Gtk::ScrolledWindow MainWindow::log_scroller_
private

Definition at line 168 of file main_window.hpp.

Referenced by build_recovery_page().

◆ log_view_

Gtk::TextView MainWindow::log_view_
private

Definition at line 169 of file main_window.hpp.

Referenced by build_recovery_page().

◆ m_aboutPage

AboutPage MainWindow::m_aboutPage
private

Definition at line 48 of file MainWindow.hpp.

◆ m_activeButton

Gtk::Button* MainWindow::m_activeButton = nullptr
private

Definition at line 69 of file MainWindow.hpp.

Referenced by activateSidebarButton().

◆ m_alertDialog

std::unique_ptr<AlertDialog> MainWindow::m_alertDialog
private

Definition at line 55 of file MainWindow.hpp.

Referenced by onNewConnection().

◆ m_appsPage

AppsPage MainWindow::m_appsPage
private

Definition at line 44 of file MainWindow.hpp.

Referenced by onDaemonAlert(), onNewConnection(), and onVerdict().

◆ m_autostartBackupFile

std::string MainWindow::m_autostartBackupFile
private

◆ m_btnDark

Gtk::Button* MainWindow::m_btnDark = nullptr
private

Definition at line 76 of file MainWindow.hpp.

Referenced by applyTheme(), and buildHeaderBar().

◆ m_btnLight

Gtk::Button* MainWindow::m_btnLight = nullptr
private

Definition at line 75 of file MainWindow.hpp.

Referenced by applyTheme(), and buildHeaderBar().

◆ m_configFile

std::string MainWindow::m_configFile
private

Definition at line 87 of file MainWindow.hpp.

Referenced by applyProtectionEnabled(), loadConfig(), saveConfig(), and showLanguageDialog().

◆ m_connectionsPage

ConnectionsPage MainWindow::m_connectionsPage { m_uiServer }
private

Definition at line 43 of file MainWindow.hpp.

Referenced by onDaemonAlert(), onNewConnection(), onVerdict(), and ~MainWindow().

◆ m_cssProvider

Glib::RefPtr<Gtk::CssProvider> MainWindow::m_cssProvider
private

Definition at line 73 of file MainWindow.hpp.

Referenced by loadTheme().

◆ m_daemonLabel

Gtk::Label* MainWindow::m_daemonLabel = nullptr
private

Definition at line 70 of file MainWindow.hpp.

Referenced by buildSidebar(), onDaemonConnected(), and onDaemonDisconnected().

◆ m_darkMode

bool MainWindow::m_darkMode = false
private

Definition at line 74 of file MainWindow.hpp.

Referenced by applyTheme(), buildHeaderBar(), loadConfig(), and saveConfig().

◆ m_desktopActiveSent

bool MainWindow::m_desktopActiveSent = true
private

Definition at line 96 of file MainWindow.hpp.

Referenced by onDaemonConnected(), and sendDesktopActivityState().

◆ m_desktopActivityTimer

guint MainWindow::m_desktopActivityTimer = 0
private

Definition at line 95 of file MainWindow.hpp.

Referenced by startDesktopActivityMonitor(), and ~MainWindow().

◆ m_langDialog

std::unique_ptr<LanguageDialog> MainWindow::m_langDialog
private

Definition at line 58 of file MainWindow.hpp.

Referenced by showLanguageDialog().

◆ m_language

std::string MainWindow::m_language
private

Definition at line 88 of file MainWindow.hpp.

Referenced by loadConfig(), saveConfig(), and showLanguageDialog().

◆ m_lastUiActivity

std::chrono::steady_clock::time_point MainWindow::m_lastUiActivity {}
private

Definition at line 97 of file MainWindow.hpp.

Referenced by noteDesktopActivity(), and startDesktopActivityMonitor().

◆ m_mainBox

Gtk::Box MainWindow::m_mainBox { Gtk::Orientation::HORIZONTAL, 0 }
private

Definition at line 36 of file MainWindow.hpp.

Referenced by buildSidebar().

◆ m_networkPage

NetworkPage MainWindow::m_networkPage
private

Definition at line 45 of file MainWindow.hpp.

Referenced by onDaemonAlert(), onNewConnection(), onVerdict(), and ~MainWindow().

◆ m_protectionEnabled

bool MainWindow::m_protectionEnabled = true
private

◆ m_rulesPage

RulesPage MainWindow::m_rulesPage
private

Definition at line 46 of file MainWindow.hpp.

◆ m_settingsPage

SettingsPage MainWindow::m_settingsPage
private

Definition at line 49 of file MainWindow.hpp.

Referenced by applyProtectionEnabled(), and refreshSystemIntegrationStatus().

◆ m_sidebarButtons

std::vector<Gtk::Button*> MainWindow::m_sidebarButtons
private

Definition at line 68 of file MainWindow.hpp.

Referenced by activateSidebarButton(), and makeSidebarButton().

◆ m_stack

Gtk::Stack MainWindow::m_stack
private

Definition at line 37 of file MainWindow.hpp.

Referenced by makeSidebarButton().

◆ m_statAllowed

uint64_t MainWindow::m_statAllowed = 0
private

Definition at line 83 of file MainWindow.hpp.

Referenced by onDaemonAlert(), onNewConnection(), and onVerdict().

◆ m_statDenied

uint64_t MainWindow::m_statDenied = 0
private

Definition at line 84 of file MainWindow.hpp.

Referenced by onDaemonAlert(), onNewConnection(), and onVerdict().

◆ m_statsPage

StatsPage MainWindow::m_statsPage
private

Definition at line 47 of file MainWindow.hpp.

Referenced by onDaemonAlert(), onNewConnection(), and onVerdict().

◆ m_statusbar

Gtk::Statusbar MainWindow::m_statusbar
private

Definition at line 79 of file MainWindow.hpp.

Referenced by setStatus().

◆ m_statusCtx

guint MainWindow::m_statusCtx = 0
private

Definition at line 80 of file MainWindow.hpp.

Referenced by setStatus().

◆ m_tray

TrayIcon MainWindow::m_tray
private

Definition at line 52 of file MainWindow.hpp.

Referenced by onDaemonAlert(), onDaemonConnected(), onDaemonDisconnected(), and ~MainWindow().

◆ m_uiServer

UIServer MainWindow::m_uiServer
private

Definition at line 40 of file MainWindow.hpp.

Referenced by onNewConnection(), onVerdict(), sendDesktopActivityState(), and ~MainWindow().

◆ m_verdictCache

std::map<std::string, ReplyAction> MainWindow::m_verdictCache
private

Definition at line 62 of file MainWindow.hpp.

Referenced by onNewConnection(), and onVerdict().

◆ main_box_

Gtk::Box MainWindow::main_box_ {Gtk::Orientation::HORIZONTAL, 0}
private

Definition at line 86 of file main_window.hpp.

◆ mainBox

Gtk::Box MainWindow::mainBox {Gtk::Orientation::HORIZONTAL}
private

Definition at line 64 of file MainWindow.hpp.

Referenced by build_sidebar(), and MainWindow().

◆ output_dir_

◆ page_stack_

Gtk::Stack MainWindow::page_stack_
private

Definition at line 87 of file main_window.hpp.

Referenced by on_sidebar_about(), on_sidebar_dashboard(), and on_sidebar_recovery().

◆ password_manager_page_

PasswordManagerPage* MainWindow::password_manager_page_ = nullptr
private

Definition at line 88 of file MainWindow.hpp.

Referenced by MainWindow().

◆ phishing_page_

PhishingPage* MainWindow::phishing_page_ = nullptr
private

Definition at line 79 of file MainWindow.hpp.

Referenced by MainWindow().

◆ privacy_page_

PrivacyPage* MainWindow::privacy_page_
private

Definition at line 82 of file MainWindow.hpp.

Referenced by MainWindow().

◆ quarantine_page_

QuarantinePage MainWindow::quarantine_page_
private

Definition at line 78 of file MainWindow.hpp.

Referenced by MainWindow().

◆ recover_step_box_

Gtk::Box MainWindow::recover_step_box_ {Gtk::Orientation::VERTICAL, 8}
private

Definition at line 156 of file main_window.hpp.

Referenced by build_wizard(), and update_wizard_step().

◆ recover_step_label_

Gtk::Label MainWindow::recover_step_label_
private

Definition at line 157 of file main_window.hpp.

Referenced by build_wizard(), populate_scan_results(), and update_source_state().

◆ recovery_button_

Gtk::Button* MainWindow::recovery_button_ = nullptr
private

Definition at line 115 of file main_window.hpp.

Referenced by build_sidebar(), and on_sidebar_recovery().

◆ recovery_devices_list_

Gtk::ListBox MainWindow::recovery_devices_list_
private

◆ recovery_devices_scroller_

Gtk::ScrolledWindow MainWindow::recovery_devices_scroller_
private

Definition at line 140 of file main_window.hpp.

Referenced by build_wizard().

◆ recovery_header_

Gtk::Box MainWindow::recovery_header_ {Gtk::Orientation::VERTICAL, 8}
private

Definition at line 122 of file main_window.hpp.

Referenced by build_recovery_page().

◆ recovery_page_

Gtk::Box MainWindow::recovery_page_ {Gtk::Orientation::VERTICAL, 16}
private

Definition at line 91 of file main_window.hpp.

Referenced by build_recovery_page(), and on_sidebar_recovery().

◆ recovery_subtitle_

Gtk::Label MainWindow::recovery_subtitle_
private

Definition at line 124 of file main_window.hpp.

Referenced by build_recovery_page().

◆ recovery_title_

Gtk::Label MainWindow::recovery_title_
private

Definition at line 123 of file main_window.hpp.

Referenced by build_recovery_page().

◆ recovery_worker_

RecoveryWorker MainWindow::recovery_worker_
private

Definition at line 184 of file main_window.hpp.

Referenced by on_recover_now(), and update_selected_results_state().

◆ restore_page_widget

Gtk.? Widget MainWindow.restore_page_widget = null
private

Definition at line 35 of file MainWindow.vala.

Referenced by open_restore_flow().

◆ result_check_buttons_

std::vector<Gtk::CheckButton*> MainWindow::result_check_buttons_
private

Definition at line 181 of file main_window.hpp.

Referenced by populate_scan_results(), and set_all_results_selected().

◆ result_selection_

std::vector<bool> MainWindow::result_selection_
private

◆ results_actions_row_

Gtk::Box MainWindow::results_actions_row_ {Gtk::Orientation::HORIZONTAL, 8}
private

Definition at line 163 of file main_window.hpp.

Referenced by build_wizard().

◆ results_count_label_

Gtk::Label MainWindow::results_count_label_
private

Definition at line 161 of file main_window.hpp.

Referenced by build_wizard(), and populate_scan_results().

◆ results_frame_

Gtk::Frame MainWindow::results_frame_
private

Definition at line 158 of file main_window.hpp.

Referenced by build_wizard().

◆ results_scroller_

Gtk::ScrolledWindow MainWindow::results_scroller_
private

Definition at line 159 of file main_window.hpp.

Referenced by build_wizard().

◆ results_selected_label_

Gtk::Label MainWindow::results_selected_label_
private

Definition at line 162 of file main_window.hpp.

Referenced by build_wizard(), and update_selected_results_state().

◆ results_tree_box_

Gtk::Box MainWindow::results_tree_box_ {Gtk::Orientation::VERTICAL, 8}
private

Definition at line 160 of file main_window.hpp.

Referenced by build_wizard(), and populate_scan_results().

◆ rootguard_page_

RootGuardPage* MainWindow::rootguard_page_ = nullptr
private

Definition at line 83 of file MainWindow.hpp.

Referenced by MainWindow().

◆ rsync_log_page_widget

Gtk.? Widget MainWindow.rsync_log_page_widget = null
private

Definition at line 37 of file MainWindow.vala.

Referenced by open_rsync_log_page().

◆ samba_page_

SambaPage* MainWindow::samba_page_ = nullptr
private

Definition at line 86 of file MainWindow.hpp.

Referenced by MainWindow().

◆ scan_page_

ScanPage MainWindow::scan_page_ {*this}
private

Definition at line 71 of file MainWindow.hpp.

Referenced by MainWindow().

◆ scan_progress_bar_

Gtk::ProgressBar MainWindow::scan_progress_bar_
private

Definition at line 151 of file main_window.hpp.

Referenced by build_wizard(), on_scan_completed(), on_scan_now(), and on_scan_progress().

◆ scan_started_at_

std::chrono::steady_clock::time_point MainWindow::scan_started_at_ {}
private

Definition at line 188 of file main_window.hpp.

Referenced by on_scan_completed(), and on_scan_now().

◆ scan_status_label_

Gtk::Label MainWindow::scan_status_label_
private

Definition at line 152 of file main_window.hpp.

Referenced by build_wizard(), on_scan_completed(), on_scan_now(), and on_scan_progress().

◆ scan_step_box_

Gtk::Box MainWindow::scan_step_box_ {Gtk::Orientation::VERTICAL, 8}
private

Definition at line 149 of file main_window.hpp.

Referenced by build_wizard(), and update_wizard_step().

◆ scan_step_label_

Gtk::Label MainWindow::scan_step_label_
private

Definition at line 150 of file main_window.hpp.

Referenced by build_wizard(), and update_source_state().

◆ scan_timer_connection_

sigc::connection MainWindow::scan_timer_connection_
private

Definition at line 187 of file main_window.hpp.

Referenced by on_scan_completed(), and on_scan_now().

◆ scan_timer_label_

Gtk::Label MainWindow::scan_timer_label_
private

Definition at line 153 of file main_window.hpp.

Referenced by build_wizard(), on_scan_completed(), and on_scan_now().

◆ scan_worker_

ScanWorker MainWindow::scan_worker_
private

Definition at line 183 of file main_window.hpp.

Referenced by on_scan_now(), and update_action_controls().

◆ selected_source_label_

std::string MainWindow::selected_source_label_
private

Definition at line 177 of file main_window.hpp.

Referenced by populate_scan_results(), select_source(), and update_source_state().

◆ selected_source_path_

◆ settings_page_widget

Gtk.? Widget MainWindow.settings_page_widget = null
private

Definition at line 31 of file MainWindow.vala.

Referenced by init_settings_page().

◆ settings_window_

SettingsWindow* MainWindow::settings_window_ = nullptr
private

Definition at line 74 of file MainWindow.hpp.

Referenced by open_settings_window().

◆ sidebar_

Gtk::Box MainWindow::sidebar_ {Gtk::Orientation::VERTICAL, 10}
private

Definition at line 89 of file main_window.hpp.

Referenced by build_sidebar().

◆ sidebar_buttons_

std::vector< Gtk::Button * > MainWindow::sidebar_buttons_
private

Definition at line 66 of file MainWindow.hpp.

Referenced by activate_sidebar_button(), build_sidebar(), and build_sidebar().

◆ snapshot_list_box

SnapshotListBox MainWindow.snapshot_list_box
private

◆ source_button_row_

Gtk::Box MainWindow::source_button_row_ {Gtk::Orientation::HORIZONTAL, 8}
private

Definition at line 136 of file main_window.hpp.

Referenced by build_wizard().

◆ source_card_label_

Gtk::Label MainWindow::source_card_label_
private

Definition at line 100 of file main_window.hpp.

Referenced by build_dashboard(), and update_source_state().

◆ source_step_box_

Gtk::Box MainWindow::source_step_box_ {Gtk::Orientation::VERTICAL, 8}
private

Definition at line 134 of file main_window.hpp.

Referenced by build_wizard(), and update_wizard_step().

◆ source_step_label_

Gtk::Label MainWindow::source_step_label_
private

Definition at line 135 of file main_window.hpp.

Referenced by build_wizard().

◆ stack_

Gtk::Stack MainWindow::stack_
private

Definition at line 65 of file MainWindow.hpp.

Referenced by build_sidebar(), MainWindow(), and showDashboard().

◆ status_card_label_

Gtk::Label MainWindow::status_card_label_
private

Definition at line 99 of file main_window.hpp.

Referenced by build_dashboard().

◆ THEME_CONFIG_DIR

const string MainWindow.THEME_CONFIG_DIR = "/etc/bastionguard-backup"
staticprivate

Definition at line 52 of file MainWindow.vala.

Referenced by save_language_preference(), and save_theme_preference().

◆ THEME_CONFIG_FILE

const string MainWindow.THEME_CONFIG_FILE = "/etc/bastionguard-backup/theme.json"
staticprivate

Definition at line 53 of file MainWindow.vala.

Referenced by load_theme_preference(), and save_theme_preference().

◆ themed_img_list

Gee.ArrayList<Gtk.Image> MainWindow.themed_img_list = new Gee.ArrayList<Gtk.Image>()
private

Definition at line 77 of file MainWindow.vala.

Referenced by reload_themed_icons(), and themed_icon().

◆ themed_img_name

Gee.ArrayList<string> MainWindow.themed_img_name = new Gee.ArrayList<string>()
private

Definition at line 78 of file MainWindow.vala.

Referenced by reload_themed_icons(), and themed_icon().

◆ themed_img_size

Gee.ArrayList<int> MainWindow.themed_img_size = new Gee.ArrayList<int>()
private

Definition at line 79 of file MainWindow.vala.

Referenced by reload_themed_icons(), and themed_icon().

◆ tmr_init

uint MainWindow.tmr_init
private

Definition at line 97 of file MainWindow.vala.

Referenced by init_delayed(), and MainWindow().

◆ update_card_label_

Gtk::Label MainWindow::update_card_label_
private

Definition at line 101 of file main_window.hpp.

Referenced by build_dashboard(), and refresh_devices().

◆ update_page_

UpdatePage MainWindow::update_page_
private

Definition at line 81 of file MainWindow.hpp.

Referenced by MainWindow().

◆ usb_page_

USBScanPage* MainWindow::usb_page_ = nullptr
private

Definition at line 85 of file MainWindow.hpp.

Referenced by MainWindow().

◆ vbox_sidebar

Gtk.Box MainWindow.vbox_sidebar
private

Definition at line 29 of file MainWindow.vala.

Referenced by init_sidebar(), and make_nav_btn().

◆ vpn_page_

VpnPage* MainWindow::vpn_page_ = nullptr
private

Definition at line 80 of file MainWindow.hpp.

Referenced by MainWindow().

◆ window_in_expanded_mode

bool MainWindow.window_in_expanded_mode = false
private

Definition at line 102 of file MainWindow.vala.

Referenced by apply_window_mode_for_page(), and remember_compact_window_size().

◆ wizard_frame_

Gtk::Frame MainWindow::wizard_frame_
private

Definition at line 126 of file main_window.hpp.

Referenced by build_recovery_page(), and build_wizard().

◆ wizard_nav_

Gtk::Box MainWindow::wizard_nav_ {Gtk::Orientation::HORIZONTAL, 8}
private

Definition at line 129 of file main_window.hpp.

Referenced by build_wizard().

◆ wizard_notice_label_

Gtk::Label MainWindow::wizard_notice_label_
private

Definition at line 132 of file main_window.hpp.

Referenced by build_wizard().

◆ wizard_page_widget

Gtk.? Widget MainWindow.wizard_page_widget = null
private

Definition at line 32 of file MainWindow.vala.

Referenced by init_wizard_page().

◆ wizard_root_

Gtk::Box MainWindow::wizard_root_ {Gtk::Orientation::VERTICAL, 12}
private

Definition at line 127 of file main_window.hpp.

Referenced by build_wizard().

◆ wizard_stack_

Gtk::Stack MainWindow::wizard_stack_
private

Definition at line 128 of file main_window.hpp.

Referenced by build_wizard(), and update_wizard_step().


The documentation for this class was generated from the following files: