42 set_default_size(1000, 680);
43 set_size_request(800, 560);
45 std::vector<std::string> conf_paths = {
46 "/etc/clamd/clamd.conf",
47 "/etc/clamav/clamd.conf",
48 "/etc/clamd.d/clamd.conf",
53 for (
const auto& path : conf_paths) {
55 std::cout <<
_(
"✔ Caricato config da: ") << path << std::endl;
62 std::cerr <<
_(
"❌ Errore: impossibile leggere clamd.conf in nessuno dei percorsi noti") <<
"\n";
70 stack_.get_style_context()->add_class(
"content");
71 stack_.set_transition_type(Gtk::StackTransitionType::SLIDE_LEFT_RIGHT);
72 stack_.set_transition_duration(220);
82#if BASTIONGUARD_HAS_CEF
93 usb_page_ = Gtk::make_managed<USBScanPage>();
105 vpn_page_ = Gtk::make_managed<VpnPage>();
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 "";
119 file.read(&header[0], 512);
121 std::regex re(
"ClamAV-VDB:.*:([0-9]+):");
123 if (std::regex_search(header, match, re)) {
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");
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");
139 bool on_access_enabled =
true;
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");
152 auto header_left = Gtk::make_managed<Gtk::Box>(Gtk::Orientation::HORIZONTAL);
154 header_left->set_hexpand(
false);
155 header_left->get_style_context()->add_class(
"header-left");
156 header->pack_start(*header_left);
159 auto header_spacer = Gtk::make_managed<Gtk::Box>(Gtk::Orientation::HORIZONTAL);
160 header_spacer->set_hexpand(
true);
161 header->pack_start(*header_spacer);
164 auto header_right = Gtk::make_managed<Gtk::Box>(Gtk::Orientation::HORIZONTAL);
165 header_right->get_style_context()->add_class(
"header-right");
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(); });
175 std::cerr <<
_(
"⚠ Errore caricamento icona minimize") <<
"\n";
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);
185 btn_close->signal_clicked().connect([
this]() {
186 std::cout <<
_(
"[MainWindow] Pulsante close → nascondo nella tray") <<
"\n";
190 std::cerr <<
_(
"⚠ Errore caricamento icona close") <<
"\n";
193 header->pack_end(*header_right);
194 set_titlebar(*header);
201 static const std::vector<std::string> kPageOrder = {
203 "scan",
"antiransomware",
204#if BASTIONGUARD_HAS_CEF
207 "privacy",
"rootguard",
"usbscan",
"samba",
208 "log",
"quarantine",
"identityleak",
"passwordmanager",
"backup",
"update",
215 auto open_revealers = std::make_shared<std::vector<Gtk::Revealer*>>();
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");
223 auto hdr = Gtk::make_managed<Gtk::Box>(Gtk::Orientation::HORIZONTAL, 8);
224 hdr->get_style_context()->add_class(
"sidebar-header");
226 auto pb = Gdk::Pixbuf::create_from_file(
resource(
"logo-sidebar.png"), 128, 128,
true);
227 auto logo = Gtk::make_managed<Gtk::Image>(pb);
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");
234 sidebar_box->append(*hdr);
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()) {
244 stack_.set_transition_type(Gtk::StackTransitionType::SLIDE_LEFT);
246 stack_.set_transition_type(Gtk::StackTransitionType::SLIDE_RIGHT);
248 stack_.set_visible_child(page);
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*
257 auto box = Gtk::make_managed<Gtk::Box>(Gtk::Orientation::HORIZONTAL, 6);
258 if (indent) box->set_margin_start(14);
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>();
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);
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");
278 auto btn = Gtk::make_managed<Gtk::Button>();
279 btn->set_child(*box);
280 btn->get_style_context()->add_class(
"sidebar-button");
283 btn->signal_clicked().connect([
this, btn, page_name, navigate_to]() {
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);
293 auto make_group = [&](
const std::string& icon_path,
294 const std::string& label_text) -> Gtk::Box*
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");
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>();
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);
315 auto lbl = Gtk::make_managed<Gtk::Label>(
_(label_text.c_str()));
316 lbl->set_halign(Gtk::Align::START);
320 auto hbtn = Gtk::make_managed<Gtk::Button>();
321 hbtn->set_child(*box);
322 hbtn->get_style_context()->add_class(
"sidebar-group-button");
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);
329 auto children = Gtk::make_managed<Gtk::Box>(Gtk::Orientation::VERTICAL, 0);
330 revealer->set_child(*children);
333 open_revealers->push_back(revealer);
335 hbtn->signal_clicked().connect([revealer, arrow, open_revealers]() {
336 bool opening = !revealer->get_reveal_child();
338 for (
auto* r : *open_revealers) {
339 if (r != revealer && r->get_reveal_child()) {
340 r->set_reveal_child(
false);
346 revealer->set_reveal_child(opening);
347 arrow->set_text(opening ?
"▾" :
"▸");
350 sidebar_box->append(*hbtn);
351 sidebar_box->append(*revealer);
358 auto* db_btn = make_leaf(
resource(
"icons/dashboard.svg"),
_(
"Dashboard"),
"dashboard");
360 sidebar_box->append(*db_btn);
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));
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));
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));
392 sidebar_box->append(*make_leaf(
resource(
"icons/phishing.svg"),
_(
"Phishing Search"),
"phishing"));
397 sidebar_box->append(*make_leaf(
resource(
"icons/vpn.svg"),
_(
"VPN WireGuard"),
"vpn"));
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>();
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));
415 auto lbl = Gtk::make_managed<Gtk::Label>(
_(
"Impostazioni"));
416 lbl->set_halign(Gtk::Align::START);
418 auto btn = Gtk::make_managed<Gtk::Button>();
419 btn->set_child(*box);
420 btn->get_style_context()->add_class(
"sidebar-button");
422 sidebar_box->append(*btn);
426 auto spacer = Gtk::make_managed<Gtk::Box>(Gtk::Orientation::VERTICAL);
427 spacer->set_vexpand(
true);
428 sidebar_box->append(*spacer);
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);
434 sidebar_box->append(*make_leaf(
resource(
"icons/about.svg"),
_(
"Informazioni"),
"about"));
435 sidebar_box->append(*make_leaf(
resource(
"icons/donate.svg"),
_(
"Donazioni"),
"donate"));