Skip to content
API Documentation
BastionGuard™
AlertWindowRealtime.cpp
Go to the documentation of this file.
1/*
2 * BastionGuard™
3 * Copyright (C) 2025–2026 Calogero Scarnà
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, version 3.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <https://www.gnu.org/licenses/>.
16 *
17 * BastionGuard™ is a trademark of Calogero Scarnà.
18 * The BastionGuard™ name and branding are not licensed under the GPL.
19 */
20
22#include "Quarantine.hpp"
23#include "Resource.hpp"
24#include <filesystem>
25#include <iostream>
26#include <fstream>
27#include <glib/gi18n.h>
28#include <glibmm/miscutils.h>
29
30
31static std::string resolve_theme_css() {
32 const std::string conf =
33 Glib::get_home_dir() + "/.config/BastionGuard/theme.conf";
34 std::ifstream tf(conf);
35 std::string theme;
36 if (tf >> theme && theme == "dark")
37 return "BastionGuard-dark.css";
38 return "BastionGuard.css";
39}
41 const std::string& file,
42 const std::string& family,
43 size_t pending)
44 : filePath(file),
45 vbox(Gtk::Orientation::VERTICAL, 15),
46 titleLabel(_("⚠️ Ransomware rilevato in tempo reale")),
48 Glib::ustring::compose(
49 _("Famiglia: %1\nFile: %2"),
50 family,
51 file
52 )
53 ),
54 quarantineButton(_("Metti in quarantena")),
55 ignoreButton(_("Ignora")),
56 ignoreAllButton(_("Ignora tutti"))
57{
58
59 set_title("");
60 set_default_size(620, 240);
61 set_resizable(false);
62 set_modal(true);
63
64 auto ctx = get_style_context();
65 ctx->add_class("app-dialog");
66 ctx->add_class("main-window");
67 ctx->add_class("app-window");
68
69 try {
70 auto css = Gtk::CssProvider::create();
71 css->load_from_path(resource(resolve_theme_css()));
72 Gtk::StyleContext::add_provider_for_display(
73 Gdk::Display::get_default(),
74 css,
75 GTK_STYLE_PROVIDER_PRIORITY_APPLICATION
76 );
77 } catch (...) {
78 std::cerr << _("Errore caricamento CSS\n");
79 }
80
81 auto *header = Gtk::make_managed<Gtk::HeaderBar>();
82 header->set_show_title_buttons(false);
83 header->set_decoration_layout("");
84 header->add_css_class("custom-headerbar");
85
86 auto *close_box = Gtk::make_managed<Gtk::Box>(Gtk::Orientation::HORIZONTAL);
87 close_box->set_margin_end(6);
88
89 try {
90 auto px = Gdk::Pixbuf::create_from_file(resource("icon-close.png"), 28, 28, true);
91 auto *btn = Gtk::make_managed<Gtk::Button>();
92 btn->set_child(*Gtk::make_managed<Gtk::Image>(px));
93 btn->add_css_class("header-button");
94
95 btn->signal_clicked().connect([this]() { hide(); });
96 close_box->append(*btn);
97 } catch (...) {
98 std::cerr << _("Icona X non trovata\n");
99 }
100
101 header->pack_end(*close_box);
102
103 auto *header_wrapper = Gtk::make_managed<Gtk::Box>(Gtk::Orientation::VERTICAL);
104 header_wrapper->append(*header);
105 set_titlebar(*header_wrapper);
106 titleLabel.set_halign(Gtk::Align::CENTER);
107 titleLabel.set_margin_bottom(5);
108 titleLabel.add_css_class("title");
109
110 std::string iconPath =
111 (family == "OK" || family == "Clean" || family == "None")
112 ? "/usr/share/BastionGuard/data/icons/true.png"
113 : "/usr/share/BastionGuard/data/icons/false.png";
114
115 auto icon = Gtk::make_managed<Gtk::Picture>();
116 icon->set_halign(Gtk::Align::CENTER);
117 icon->set_margin_bottom(10);
118
119 if (std::filesystem::exists(iconPath)) {
120 try {
121 auto pb = Gdk::Pixbuf::create_from_file(iconPath);
122 auto scaled = pb->scale_simple(68, 68, Gdk::InterpType::BILINEAR);
123 auto tex = Gdk::Texture::create_for_pixbuf(scaled);
124 icon->set_paintable(tex);
125 } catch (...) {
126 std::cerr << _("Errore caricamento icona alert\n");
127 }
128 }
129
130 messageLabel.set_wrap(true);
131 messageLabel.set_justify(Gtk::Justification::CENTER);
132 messageLabel.set_halign(Gtk::Align::CENTER);
133
134 if (pending > 0) {
135 pendingLabel.set_text(
136 Glib::ustring::compose(
137 _("🕒 %1 altri in attesa..."),
138 pending
139 )
140 );
141 pendingLabel.set_halign(Gtk::Align::CENTER);
142 }
143
144
145 quarantineButton.add_css_class("btn-danger");
146 ignoreButton.add_css_class("btn-success");
147 ignoreAllButton.add_css_class("btn-warning");
148
149 auto buttonBox =
150 Gtk::make_managed<Gtk::Box>(Gtk::Orientation::HORIZONTAL, 20);
151 buttonBox->set_halign(Gtk::Align::CENTER);
152 buttonBox->append(quarantineButton);
153 buttonBox->append(ignoreButton);
154 buttonBox->append(ignoreAllButton);
155 set_child(vbox);
156 vbox.set_margin(25);
157 vbox.set_halign(Gtk::Align::CENTER);
158 vbox.append(titleLabel);
159 vbox.append(*icon);
160 vbox.append(messageLabel);
161 if (pending > 0) vbox.append(pendingLabel);
162 vbox.append(*buttonBox);
163 quarantineButton.signal_clicked().connect([this]() {
165 hide();
166 });
167 ignoreButton.signal_clicked().connect([this]() { hide(); });
168 ignoreAllButton.signal_clicked().connect([this]() {
169 signal_ignore_all.emit();
170 hide();
171 });
172}
173
176 std::cout << Glib::ustring::compose(
177 _("[✔] File quarantena: %1"),
179 ) << "\n";
180 else
181 std::cerr << Glib::ustring::compose(
182 _("[ERROR] Quarantena fallita per: %1"),
184 ) << std::endl;
185
186}
static std::string resolve_theme_css()
#define _(s)
AlertWindowRealtime(const std::string &file, const std::string &family, size_t pending=0)
sigc::signal< void()> signal_ignore_all
static bool move(const std::string &file)
std::string resource(const std::string &rel)
Definition Resource.hpp:31