Skip to content
API Documentation
BastionGuard™
LiveScanDialog Class Reference

#include <LiveScanDialog.hpp>

Inheritance diagram for LiveScanDialog:

Public Member Functions

 LiveScanDialog (Gtk::Window *parent, const std::string &path)
 ~LiveScanDialog () override
void append_output (const std::string &line)
void mark_finished ()
bool cancelled () const
std::string get_full_output () const

Private Member Functions

void flush_output_idle ()

Private Attributes

Gtk::Box root_
Gtk::ProgressBar progress_
Gtk::ScrolledWindow scroller_
Gtk::TextView text_view_
Gtk::Button btn_cancel_
std::atomic< bool > finished_ {false}
std::atomic< bool > cancelled_ {false}
std::atomic< bool > flush_pending_ {false}
std::mutex mtx_
std::vector< std::string > pending_lines_
std::string full_output_
BastionGuard::AliveFlag alive_

Detailed Description

Definition at line 30 of file LiveScanDialog.hpp.

Constructor & Destructor Documentation

◆ LiveScanDialog()

LiveScanDialog::LiveScanDialog ( Gtk::Window * parent,
const std::string & path )

Definition at line 40 of file LiveScanDialog.cpp.

41 : root_(Gtk::Orientation::VERTICAL, 16),
43{
44 set_title("");
45 set_default_size(620, 420);
46 set_resizable(false);
47 set_modal(true);
48 if (parent) set_transient_for(*parent);
49
50 add_css_class("app-dialog");
51 add_css_class("main-window");
52 add_css_class("app-window");
53
54 try {
55 auto css = Gtk::CssProvider::create();
56 css->load_from_path(resource(usb_live_resolve_theme_css()));
57 Gtk::StyleContext::add_provider_for_display(
58 Gdk::Display::get_default(), css,
59 GTK_STYLE_PROVIDER_PRIORITY_APPLICATION
60 );
61 } catch (...) {}
62
63 auto *header = Gtk::make_managed<Gtk::HeaderBar>();
64 header->set_show_title_buttons(false);
65 header->set_decoration_layout("");
66 header->add_css_class("custom-headerbar");
67
68 auto *close_box = Gtk::make_managed<Gtk::Box>(Gtk::Orientation::HORIZONTAL);
69 close_box->set_margin_end(6);
70
71 try {
72 auto px = Gdk::Pixbuf::create_from_file(resource("icon-close.png"), 28, 28, true);
73 auto btn = Gtk::make_managed<Gtk::Button>();
74 btn->set_child(*Gtk::make_managed<Gtk::Image>(px));
75 btn->add_css_class("header-button");
76 btn->signal_clicked().connect([this]() { hide(); });
77 close_box->append(*btn);
78 } catch (...) {}
79
80 header->pack_end(*close_box);
81
82 auto *header_wrap = Gtk::make_managed<Gtk::Box>(Gtk::Orientation::VERTICAL);
83 header_wrap->append(*header);
84 set_titlebar(*header_wrap);
85
86 root_.set_margin(20);
87
88 auto title = Gtk::make_managed<Gtk::Label>(
89 _("Scansione della periferica USB in corso")
90 );
91 title->add_css_class("title");
92 title->set_halign(Gtk::Align::CENTER);
93 root_.append(*title);
94
95 auto *icon = Gtk::make_managed<Gtk::Picture>();
96 icon->set_halign(Gtk::Align::CENTER);
97 icon->set_margin_bottom(10);
98 try {
99 auto pb = Gdk::Pixbuf::create_from_file(resource("icons/scan.png"));
100 auto scaled = pb->scale_simple(64, 64, Gdk::InterpType::BILINEAR);
101 icon->set_paintable(Gdk::Texture::create_for_pixbuf(scaled));
102 } catch (...) {}
103 root_.append(*icon);
104
105 auto device_label = Gtk::make_managed<Gtk::Label>(
106 _("Percorso analizzato:\n") + path
107 );
108 device_label->set_wrap(true);
109 device_label->set_halign(Gtk::Align::CENTER);
110 root_.append(*device_label);
111
112 progress_.set_pulse_step(0.1);
113 progress_.set_show_text(true);
114 progress_.set_text(_("Analisi in corso..."));
115 root_.append(progress_);
116
117 text_view_.set_editable(false);
118 scroller_.set_child(text_view_);
119 scroller_.set_vexpand(true);
120 scroller_.add_css_class("scroller");
121 root_.append(scroller_);
122 btn_cancel_.set_label(_("Annulla"));
123 btn_cancel_.add_css_class("btn-danger");
124 btn_cancel_.set_halign(Gtk::Align::CENTER);
125 btn_cancel_.signal_clicked().connect([this]() {
126 cancelled_.store(true);
127 btn_cancel_.set_sensitive(false);
128 progress_.set_text(_("Interruzione in corso..."));
129 });
130 root_.append(btn_cancel_);
131
132 set_child(root_);
133
134 {
135 auto alive = alive_;
136 Glib::signal_timeout().connect(
137 [this, alive]() -> bool {
138 if (!alive || !alive->load(std::memory_order_acquire)) {
139 return false; // oggetto morto: disconnette il timer
140 }
141 if (finished_) return false;
142 progress_.pulse();
143 return true;
144 },
145 120
146 );
147 }
148
149 present();
150}
#define _(s)
static std::string usb_live_resolve_theme_css()
Gtk::Button btn_cancel_
Gtk::TextView text_view_
Gtk::ProgressBar progress_
BastionGuard::AliveFlag alive_
std::atomic< bool > finished_
std::atomic< bool > cancelled_
Gtk::ScrolledWindow scroller_
AliveFlag make_alive_flag()
std::string resource(const std::string &rel)
Definition Resource.hpp:31

References _, alive_, btn_cancel_, cancelled_, finished_, progress_, resource(), root_, scroller_, text_view_, and usb_live_resolve_theme_css().

◆ ~LiveScanDialog()

LiveScanDialog::~LiveScanDialog ( )
override

Definition at line 154 of file LiveScanDialog.cpp.

155{
156 // Segnala ai lambda in volo (signal_idle non ancora eseguito,
157 // timeout pulse pending) che l'oggetto sta per sparire.
158 if (alive_) alive_->store(false, std::memory_order_release);
159}

References alive_.

Member Function Documentation

◆ append_output()

void LiveScanDialog::append_output ( const std::string & line)

Definition at line 162 of file LiveScanDialog.cpp.

163{
164 {
165 std::lock_guard<std::mutex> lock(mtx_);
166 pending_lines_.push_back(line + "\n");
167 }
168
169 if (!flush_pending_.exchange(true)) {
170 auto alive = alive_;
171 Glib::signal_idle().connect_once([this, alive]() {
172 BastionGuard::if_alive(alive, [this]() {
174 });
175 });
176 }
177}
std::vector< std::string > pending_lines_
std::atomic< bool > flush_pending_
void if_alive(const AliveFlag &alive, Fn &&fn)

References alive_, flush_output_idle(), flush_pending_, BastionGuard::if_alive(), mtx_, and pending_lines_.

◆ cancelled()

bool LiveScanDialog::cancelled ( ) const
inline

Definition at line 37 of file LiveScanDialog.hpp.

37{ return cancelled_.load(); }

References cancelled_.

◆ flush_output_idle()

void LiveScanDialog::flush_output_idle ( )
private

Definition at line 180 of file LiveScanDialog.cpp.

181{
182 flush_pending_.store(false);
183
184 std::vector<std::string> lines;
185 {
186 std::lock_guard<std::mutex> lock(mtx_);
187 lines.swap(pending_lines_);
188 }
189
190 if (lines.empty())
191 return;
192
193 auto buf = text_view_.get_buffer();
194 Gtk::TextIter it = buf->end();
195
196 for (auto& l : lines) {
197 buf->insert(it, l);
198 it = buf->end();
199 full_output_ += l;
200 }
201
202 if (auto adj = scroller_.get_vadjustment())
203 adj->set_value(adj->get_upper());
204}
std::string full_output_

References flush_pending_, full_output_, mtx_, pending_lines_, scroller_, and text_view_.

Referenced by append_output(), and mark_finished().

◆ get_full_output()

std::string LiveScanDialog::get_full_output ( ) const

Definition at line 225 of file LiveScanDialog.cpp.

226{
227 std::lock_guard<std::mutex> lock(mtx_);
228 return full_output_;
229}

References full_output_, and mtx_.

◆ mark_finished()

void LiveScanDialog::mark_finished ( )

Definition at line 207 of file LiveScanDialog.cpp.

208{
209 finished_.store(true);
210
211 // Forza ultimo flush
212 flush_pending_.store(true);
213
214 auto alive = alive_;
215 Glib::signal_idle().connect_once([this, alive]() {
216 BastionGuard::if_alive(alive, [this]() {
218 progress_.set_fraction(1.0);
219 progress_.set_text(_("Completato"));
220 });
221 });
222}

References _, alive_, finished_, flush_output_idle(), flush_pending_, BastionGuard::if_alive(), and progress_.

Member Data Documentation

◆ alive_

BastionGuard::AliveFlag LiveScanDialog::alive_
private

Definition at line 60 of file LiveScanDialog.hpp.

Referenced by append_output(), LiveScanDialog(), mark_finished(), and ~LiveScanDialog().

◆ btn_cancel_

Gtk::Button LiveScanDialog::btn_cancel_
private

Definition at line 47 of file LiveScanDialog.hpp.

Referenced by LiveScanDialog().

◆ cancelled_

std::atomic<bool> LiveScanDialog::cancelled_ {false}
private

Definition at line 50 of file LiveScanDialog.hpp.

Referenced by cancelled(), and LiveScanDialog().

◆ finished_

std::atomic<bool> LiveScanDialog::finished_ {false}
private

Definition at line 49 of file LiveScanDialog.hpp.

Referenced by LiveScanDialog(), and mark_finished().

◆ flush_pending_

std::atomic<bool> LiveScanDialog::flush_pending_ {false}
private

Definition at line 51 of file LiveScanDialog.hpp.

Referenced by append_output(), flush_output_idle(), and mark_finished().

◆ full_output_

std::string LiveScanDialog::full_output_
private

Definition at line 55 of file LiveScanDialog.hpp.

Referenced by flush_output_idle(), and get_full_output().

◆ mtx_

std::mutex LiveScanDialog::mtx_
mutableprivate

Definition at line 53 of file LiveScanDialog.hpp.

Referenced by append_output(), flush_output_idle(), and get_full_output().

◆ pending_lines_

std::vector<std::string> LiveScanDialog::pending_lines_
private

Definition at line 54 of file LiveScanDialog.hpp.

Referenced by append_output(), and flush_output_idle().

◆ progress_

Gtk::ProgressBar LiveScanDialog::progress_
private

Definition at line 44 of file LiveScanDialog.hpp.

Referenced by LiveScanDialog(), and mark_finished().

◆ root_

Gtk::Box LiveScanDialog::root_
private

Definition at line 43 of file LiveScanDialog.hpp.

Referenced by LiveScanDialog().

◆ scroller_

Gtk::ScrolledWindow LiveScanDialog::scroller_
private

Definition at line 45 of file LiveScanDialog.hpp.

Referenced by flush_output_idle(), and LiveScanDialog().

◆ text_view_

Gtk::TextView LiveScanDialog::text_view_
private

Definition at line 46 of file LiveScanDialog.hpp.

Referenced by flush_output_idle(), and LiveScanDialog().


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