112 m_treeView.get_style_context()->add_class(
"bsc-treeview");
113 m_treeView.set_grid_lines(Gtk::TreeView::GridLines::HORIZONTAL);
120 auto* col = Gtk::make_managed<Gtk::TreeViewColumn>(
_(
"Azione"));
121 auto* cell = Gtk::make_managed<Gtk::CellRendererCombo>();
124 cell->property_text_column() = 0;
125 cell->property_editable() =
true;
126 cell->property_has_entry() =
false;
128 cell->signal_edited().connect(
131 col->pack_start(*cell,
true);
138 auto* col = Gtk::make_managed<Gtk::TreeViewColumn>(
_(
"Durata"));
139 auto* cell = Gtk::make_managed<Gtk::CellRendererCombo>();
142 cell->property_text_column() = 0;
143 cell->property_editable() =
true;
144 cell->property_has_entry() =
false;
146 cell->signal_edited().connect(
149 col->pack_start(*cell,
true);
159 auto* col = Gtk::make_managed<Gtk::TreeViewColumn>(
_(
"Valore"));
160 auto* cell = Gtk::make_managed<Gtk::CellRendererText>();
161 cell->property_editable() =
true;
162 cell->signal_edited().connect(
164 col->pack_start(*cell,
true);
171 auto* col = Gtk::make_managed<Gtk::TreeViewColumn>(
_(
"Attiva"));
172 auto* cell = Gtk::make_managed<Gtk::CellRendererToggle>();
173 cell->property_activatable() =
true;
174 cell->signal_toggled().connect(
176 col->pack_start(*cell,
false);
182 const int minWidths[] = { 220, 90, 100, 130, 240, 80 };
183 for (
int i = 0; i < 6; ++i) {
185 c->set_min_width(minWidths[i]);
186 c->set_resizable(
true);
484 dialog.set_title(
"");
485 dialog.set_modal(
true);
486 dialog.set_resizable(
false);
487 dialog.set_default_size(540, -1);
488 dialog.get_style_context()->add_class(
"bsc-rule-dialog");
490 if (
auto* root =
dynamic_cast<Gtk::Window*
>(get_root()))
491 dialog.set_transient_for(*root);
493 auto* header = Gtk::make_managed<Gtk::HeaderBar>();
494 header->set_show_title_buttons(
false);
495 header->set_decoration_layout(
"");
496 header->get_style_context()->add_class(
"custom-headerbar");
498 auto* titleLabel = Gtk::make_managed<Gtk::Label>();
499 titleLabel->set_markup(
"<b>" + Glib::ustring(
_(
"Nuova regola")) +
"</b>");
500 titleLabel->get_style_context()->add_class(
"headerbar-title");
501 header->set_title_widget(*titleLabel);
503 auto* headerRight = Gtk::make_managed<Gtk::Box>(Gtk::Orientation::HORIZONTAL, 4);
504 headerRight->get_style_context()->add_class(
"header-right");
506 auto* closeBtn = Gtk::make_managed<Gtk::Button>(
"✕");
507 closeBtn->get_style_context()->add_class(
"header-button");
508 closeBtn->signal_clicked().connect([&dialog]() {
509 dialog.response(Gtk::ResponseType::CANCEL);
511 headerRight->append(*closeBtn);
513 header->pack_end(*headerRight);
514 dialog.set_titlebar(*header);
516 dialog.add_button(
_(
"Annulla"), Gtk::ResponseType::CANCEL);
517 dialog.add_button(
_(
"Crea"), Gtk::ResponseType::OK);
519 if (
auto* cancelBtn = dialog.get_widget_for_response(Gtk::ResponseType::CANCEL))
520 cancelBtn->get_style_context()->add_class(
"dialog-secondary");
521 if (
auto* createBtn = dialog.get_widget_for_response(Gtk::ResponseType::OK))
522 createBtn->get_style_context()->add_class(
"suggested-action");
524 auto* area = dialog.get_content_area();
525 area->set_margin_top(16);
526 area->set_margin_bottom(16);
527 area->set_margin_start(16);
528 area->set_margin_end(16);
529 area->set_spacing(12);
530 area->get_style_context()->add_class(
"bsc-rule-dialog-body");
532 auto* intro = Gtk::make_managed<Gtk::Label>(
_(
"Compila i campi per creare una nuova regola persistente."));
533 intro->set_wrap(
true);
534 intro->set_halign(Gtk::Align::START);
535 intro->get_style_context()->add_class(
"dialog-intro");
536 area->append(*intro);
538 auto* card = Gtk::make_managed<Gtk::Box>(Gtk::Orientation::VERTICAL, 0);
539 card->get_style_context()->add_class(
"card");
540 card->get_style_context()->add_class(
"rule-dialog-card");
543 auto* grid = Gtk::make_managed<Gtk::Grid>();
544 grid->set_row_spacing(10);
545 grid->set_column_spacing(12);
546 grid->set_margin_top(14);
547 grid->set_margin_bottom(14);
548 grid->set_margin_start(14);
549 grid->set_margin_end(14);
550 grid->set_column_homogeneous(
false);
553 auto attach_row = [grid](
int row,
const Glib::ustring& label, Gtk::Widget& widget) {
554 auto* lbl = Gtk::make_managed<Gtk::Label>(label);
555 lbl->set_halign(Gtk::Align::START);
556 lbl->set_valign(Gtk::Align::CENTER);
557 lbl->get_style_context()->add_class(
"dialog-label");
558 grid->attach(*lbl, 0, row, 1, 1);
560 widget.set_hexpand(
true);
561 widget.set_halign(Gtk::Align::FILL);
562 widget.get_style_context()->add_class(
"dialog-field");
563 grid->attach(widget, 1, row, 1, 1);
566 auto* nameEntry = Gtk::make_managed<Gtk::Entry>();
567 nameEntry->set_text(
_(
"Nuova regola"));
568 attach_row(0,
_(
"Nome"), *nameEntry);
570 auto* actionCombo = Gtk::make_managed<Gtk::ComboBoxText>();
571 actionCombo->append(
"allow",
"allow");
572 actionCombo->append(
"deny",
"deny");
573 actionCombo->set_active_id(
"deny");
574 attach_row(1,
_(
"Azione"), *actionCombo);
576 auto* durationCombo = Gtk::make_managed<Gtk::ComboBoxText>();
577 durationCombo->append(
"once",
"once");
578 durationCombo->append(
"always",
"always");
579 durationCombo->set_active_id(
"always");
580 attach_row(2,
_(
"Durata"), *durationCombo);
582 auto* operandCombo = Gtk::make_managed<Gtk::ComboBoxText>();
583 operandCombo->append(
"host",
"host");
584 operandCombo->append(
"ip",
"ip");
585 operandCombo->append(
"app",
"app");
586 operandCombo->append(
"port",
"port");
587 operandCombo->set_active_id(
"host");
588 attach_row(3,
_(
"Operando"), *operandCombo);
590 auto* valueEntry = Gtk::make_managed<Gtk::Entry>();
591 valueEntry->set_text(
"example.com");
592 attach_row(4,
_(
"Valore"), *valueEntry);
594 auto* enabledCheck = Gtk::make_managed<Gtk::CheckButton>(
_(
"Regola attiva"));
595 enabledCheck->set_active(
true);
596 enabledCheck->set_halign(Gtk::Align::START);
597 enabledCheck->get_style_context()->add_class(
"dialog-check");
598 grid->attach(*enabledCheck, 1, 5, 1, 1);
600 std::shared_ptr<Glib::MainLoop> loop = Glib::MainLoop::create(
false);
601 int response = Gtk::ResponseType::CANCEL;
603 dialog.signal_response().connect([&](
int id) {
606 if (loop->is_running())
613 if (response != Gtk::ResponseType::OK)
617 rule.
name = nameEntry->get_text();
618 rule.
action = actionCombo->get_active_id();
619 rule.
duration = durationCombo->get_active_id();
620 rule.
operand = operandCombo->get_active_id();
621 rule.
data = valueEntry->get_text();
622 rule.
enabled = enabledCheck->get_active();
626 std::cerr <<
"[RulesPage] Creazione regola annullata: campi mancanti\n";
633 std::cerr <<
"[RulesPage] Impossibile creare la regola\n";
bool writeFileAsRoot(const std::string &filepath, const std::string &content)
std::string jsonField(const std::string &json, const std::string &key)
void onDataEdited(const Glib::ustring &path, const Glib::ustring &new_text)
void onActionEdited(const Glib::ustring &path, const Glib::ustring &new_text)
bool replaceJsonBoolField(const std::string &filepath, const std::string &key, bool value)
void onDurationEdited(const Glib::ustring &path, const Glib::ustring &new_text)
bool replaceJsonStringField(const std::string &filepath, const std::string &key, const std::string &value)