52 set_default_size(640, 300);
55 auto main_box = Gtk::make_managed<Gtk::Box>(Gtk::Orientation::HORIZONTAL, 0);
58 auto sidebar = Gtk::make_managed<Gtk::Box>(Gtk::Orientation::VERTICAL, 10);
59 sidebar->set_size_request(240, -1);
60 sidebar->get_style_context()->add_class(
"sidebar");
63 auto header = Gtk::make_managed<Gtk::Box>(Gtk::Orientation::HORIZONTAL, 8);
64 header->get_style_context()->add_class(
"sidebar-header");
67 auto pixbuf = Gdk::Pixbuf::create_from_file(
resource(
"logo-sidebar.png"), 96, 96,
true);
68 auto logo = Gtk::make_managed<Gtk::Image>(pixbuf);
69 header->append(*logo);
71 std::cerr <<
_(
"⚠ Impossibile caricare data/logo-sidebar.png") <<
"\n";
74 auto lbl = Gtk::make_managed<Gtk::Label>(
"BastionGuard");
75 lbl->set_halign(Gtk::Align::START);
76 lbl->get_style_context()->add_class(
"sidebar-title");
79 sidebar->append(*header);
82 auto spacer = Gtk::make_managed<Gtk::Box>(Gtk::Orientation::VERTICAL);
83 spacer->set_vexpand(
true);
84 sidebar->append(*spacer);
86 main_box->append(*sidebar);
87 auto content_box = Gtk::make_managed<Gtk::Box>(Gtk::Orientation::VERTICAL, 10);
88 content_box->set_margin(24);
89 content_box->set_hexpand(
true);
90 content_box->get_style_context()->add_class(
"content");
91 main_box->append(*content_box);
93 auto label = Gtk::make_managed<Gtk::Label>(
94 _(
"Seleziona un sito sicuro per i pagamenti/e-commerce:")
96 label->set_wrap(
true);
97 label->set_halign(Gtk::Align::START);
98 content_box->append(*label);
104 auto string_list = Gtk::StringList::create(
domains_);
109 auto hint = Gtk::make_managed<Gtk::Label>(
110 _(
"La lista proviene da ~/.config/BastionGuard/payments.json (chiave: \"list\").")
112 hint->set_halign(Gtk::Align::START);
113 hint->get_style_context()->add_class(
"hint");
114 content_box->append(*hint);
116 auto buttons = Gtk::make_managed<Gtk::Box>(Gtk::Orientation::HORIZONTAL, 8);
117 buttons->set_halign(Gtk::Align::END);
123 btn_open_.set_label(
_(
"Apri in Secure Browser"));
127 content_box->append(*buttons);
145 auto header = Gtk::make_managed<Gtk::HeaderBar>();
146 header->set_show_title_buttons(
false);
147 header->set_decoration_layout(
"");
148 header->get_style_context()->add_class(
"custom-headerbar");
150 auto title_label = Gtk::make_managed<Gtk::Label>(
"BastionGuard Secure Browser");
151 title_label->get_style_context()->add_class(
"header-title");
152 title_label->set_halign(Gtk::Align::CENTER);
153 title_label->set_valign(Gtk::Align::CENTER);
154 header->set_title_widget(*title_label);
156 auto header_right = Gtk::make_managed<Gtk::Box>(Gtk::Orientation::HORIZONTAL);
157 header_right->get_style_context()->add_class(
"header-right");
160 auto pix_min = Gdk::Pixbuf::create_from_file(
resource(
"icon-minimize.png"), 32, 32,
true);
161 auto btn_min = Gtk::make_managed<Gtk::Button>();
162 btn_min->set_child(*Gtk::make_managed<Gtk::Image>(pix_min));
163 btn_min->get_style_context()->add_class(
"header-button");
164 header_right->append(*btn_min);
165 btn_min->signal_clicked().connect([
this]() {
minimize(); });
167 std::cerr <<
_(
"⚠ Errore caricamento icona minimize") <<
"\n";
171 auto pix_close = Gdk::Pixbuf::create_from_file(
resource(
"icon-close.png"), 32, 32,
true);
172 auto btn_close = Gtk::make_managed<Gtk::Button>();
173 btn_close->set_child(*Gtk::make_managed<Gtk::Image>(pix_close));
174 btn_close->get_style_context()->add_class(
"header-button");
175 header_right->append(*btn_close);
176 btn_close->signal_clicked().connect([
this]() {
181 std::cerr <<
_(
"⚠ Errore caricamento icona close") <<
"\n";
184 header->pack_end(*header_right);
185 set_titlebar(*header);
200 std::vector<Glib::ustring> out;
203 if (!fs::exists(path)) {
204 std::cerr <<
"⚠ Config non trovata: " << path <<
"\n";
208 std::ifstream f(path, std::ios::binary);
210 std::cerr <<
"⚠ Impossibile aprire: " << path <<
"\n";
217 }
catch (
const std::exception& e) {
218 std::cerr <<
"⚠ Errore parsing JSON: " << e.what() <<
"\n";
222 if (!j.is_object() || !j.contains(
"list") || !j[
"list"].is_array()) {
223 std::cerr <<
"⚠ payments.json invalido: manca \"list\" (array).\n";
227 for (
const auto& v : j[
"list"]) {
228 if (!v.is_string())
continue;
229 const auto s = v.get<std::string>();
230 if (!s.empty()) out.emplace_back(s);
236 void show_warning(
const Glib::ustring& msg,
const Glib::ustring& secondary = {}) {
237 auto* dialog =
new Gtk::MessageDialog(
238 *
this, msg,
false, Gtk::MessageType::WARNING, Gtk::ButtonsType::OK,
true);
239 if (!secondary.empty()) dialog->set_secondary_text(secondary);
240 dialog->set_modal(
true);
241 dialog->signal_response().connect([dialog](
int){ dialog->hide();
delete dialog; });