Skip to content
API Documentation
BastionGuard™
AppWindow Class Reference

#include <app_window.hpp>

Inheritance diagram for AppWindow:

Public Member Functions

 AppWindow ()
 ~AppWindow () override

Private Member Functions

void setup_columns ()
void add_text_column (const Glib::ustring &title, const char *property_name)
void on_choose_file ()
void on_file_chosen (const Glib::RefPtr< Gio::AsyncResult > &result)
void on_scan_clicked ()
void on_scan_completed (const ScanReport &report)
void on_save_report_clicked ()
void on_report_file_chosen (const Glib::RefPtr< Gio::AsyncResult > &result)
void on_choose_output_folder ()
void on_output_folder_chosen (const Glib::RefPtr< Gio::AsyncResult > &result)
void on_recovery_completed (const RecoveryResult &result)
void append_log (const std::string &line)

Static Private Member Functions

static std::string human_size (uint64_t bytes)
static std::string human_offset (uint64_t bytes)

Private Attributes

Gtk::Box root_ {Gtk::Orientation::VERTICAL, 8}
Gtk::Box toolbar_ {Gtk::Orientation::HORIZONTAL, 8}
Gtk::Button btn_open_
Gtk::Button btn_scan_
Gtk::Button btn_save_report_
Gtk::Button btn_recover_
Gtk::Entry entry_path_
Gtk::Label status_
Gtk::Paned paned_ {Gtk::Orientation::VERTICAL}
Gtk::ScrolledWindow results_scroller_
Gtk::ScrolledWindow logs_scroller_
Gtk::ColumnView column_view_
Gtk::TextView log_view_
Glib::RefPtr< Gtk::TextBuffer > log_buffer_
Glib::RefPtr< Gio::ListStore< ResultRow > > store_
Glib::RefPtr< Gtk::SingleSelection > selection_model_
Glib::RefPtr< Gtk::FileDialog > file_dialog_
Glib::RefPtr< Gtk::FileDialog > save_dialog_
Glib::RefPtr< Gtk::FileDialog > output_dialog_
std::string selected_path_
std::string output_dir_
ScanReport last_report_
ScanWorker worker_
RecoveryWorker recovery_worker_

Detailed Description

Definition at line 30 of file app_window.hpp.

Constructor & Destructor Documentation

◆ AppWindow()

AppWindow::AppWindow ( )

Definition at line 35 of file app_window.cpp.

36 : btn_open_(tr("Open image")),
37 btn_scan_(tr("Scan")),
38 btn_save_report_(tr("Save report")),
39 btn_recover_(tr("Recover data")),
40 status_(tr("Ready")) {
41 set_title(tr("BastionGuard Recovery Data"));
42 set_default_size(1280, 760);
43
44 set_child(root_);
45 root_.set_margin_top(12);
46 root_.set_margin_bottom(12);
47 root_.set_margin_start(12);
48 root_.set_margin_end(12);
49
50 entry_path_.set_hexpand(true);
51 entry_path_.set_editable(false);
52 btn_save_report_.set_sensitive(false);
53 btn_recover_.set_sensitive(false);
54 btn_recover_.set_sensitive(false);
55
56 toolbar_.append(btn_open_);
57 toolbar_.append(entry_path_);
58 toolbar_.append(btn_scan_);
60 toolbar_.append(btn_recover_);
61
62 root_.append(toolbar_);
63 root_.append(status_);
64
65 store_ = Gio::ListStore<ResultRow>::create();
66 selection_model_ = Gtk::SingleSelection::create(store_);
69
71 results_scroller_.set_policy(Gtk::PolicyType::AUTOMATIC, Gtk::PolicyType::AUTOMATIC);
72
73 log_buffer_ = Gtk::TextBuffer::create();
74 log_view_.set_buffer(log_buffer_);
75 log_view_.set_editable(false);
76 log_view_.set_monospace(true);
77 logs_scroller_.set_child(log_view_);
78
79 paned_.set_start_child(results_scroller_);
80 paned_.set_end_child(logs_scroller_);
81 paned_.set_position(460);
82
83 root_.append(paned_);
84
85 btn_open_.signal_clicked().connect(sigc::mem_fun(*this, &AppWindow::on_choose_file));
86 btn_scan_.signal_clicked().connect(sigc::mem_fun(*this, &AppWindow::on_scan_clicked));
87 btn_save_report_.signal_clicked().connect(sigc::mem_fun(*this, &AppWindow::on_save_report_clicked));
88 btn_recover_.signal_clicked().connect(sigc::mem_fun(*this, &AppWindow::on_choose_output_folder));
89}
Gtk::ColumnView column_view_
void on_scan_clicked()
void on_save_report_clicked()
void on_choose_output_folder()
Gtk::Paned paned_
Gtk::Button btn_save_report_
Glib::RefPtr< Gtk::TextBuffer > log_buffer_
Gtk::Button btn_open_
Gtk::ScrolledWindow results_scroller_
Gtk::Box toolbar_
Glib::RefPtr< Gtk::SingleSelection > selection_model_
void on_choose_file()
Gtk::Entry entry_path_
Gtk::Label status_
Glib::RefPtr< Gio::ListStore< ResultRow > > store_
void setup_columns()
Gtk::TextView log_view_
Gtk::Button btn_scan_
Gtk::Box root_
Gtk::ScrolledWindow logs_scroller_
Gtk::Button btn_recover_
const char * tr(const char *msgid)
Definition i18n.cpp:18

References btn_open_, btn_recover_, btn_save_report_, btn_scan_, column_view_, entry_path_, log_buffer_, log_view_, logs_scroller_, on_choose_file(), on_choose_output_folder(), on_save_report_clicked(), on_scan_clicked(), paned_, results_scroller_, root_, selection_model_, setup_columns(), status_, store_, toolbar_, and tr().

◆ ~AppWindow()

Member Function Documentation

◆ add_text_column()

void AppWindow::add_text_column ( const Glib::ustring & title,
const char * property_name )
private

Definition at line 102 of file app_window.cpp.

102 {
103 auto factory = Gtk::SignalListItemFactory::create();
104
105 factory->signal_setup().connect([](const Glib::RefPtr<Gtk::ListItem>& item) {
106 auto* label = Gtk::make_managed<Gtk::Label>();
107 label->set_xalign(0.0f);
108 label->set_selectable(true);
109 label->set_wrap(true);
110 item->set_child(*label);
111 });
112
113 factory->signal_bind().connect([property_name](const Glib::RefPtr<Gtk::ListItem>& item) {
114 auto base = item->get_item();
115 auto row = std::dynamic_pointer_cast<ResultRow>(base);
116 auto* label = dynamic_cast<Gtk::Label*>(item->get_child());
117
118 if (!row || !label) {
119 return;
120 }
121
122 Glib::ustring text;
123
124 if (std::strcmp(property_name, "offset") == 0) {
125 text = row->offset.get_value();
126 } else if (std::strcmp(property_name, "size") == 0) {
127 text = row->size.get_value();
128 } else if (std::strcmp(property_name, "type") == 0) {
129 text = row->type.get_value();
130 } else if (std::strcmp(property_name, "source") == 0) {
131 text = row->source.get_value();
132 } else if (std::strcmp(property_name, "detail") == 0) {
133 text = row->detail.get_value();
134 } else if (std::strcmp(property_name, "confidence") == 0) {
135 text = row->confidence.get_value();
136 }
137
138 label->set_text(text);
139 });
140
141 auto column = Gtk::ColumnViewColumn::create(title, factory);
142 column->set_resizable(true);
143 column_view_.append_column(column);
144}

References column_view_.

Referenced by setup_columns(), and ~AppWindow().

◆ append_log()

void AppWindow::append_log ( const std::string & line)
private

◆ human_offset()

std::string AppWindow::human_offset ( uint64_t bytes)
staticprivate

Definition at line 290 of file app_window.cpp.

290 {
291 std::ostringstream oss;
292 oss << bytes << " (0x" << std::hex << std::uppercase << bytes << ')';
293 return oss.str();
294}

Referenced by on_scan_completed(), and ~AppWindow().

◆ human_size()

std::string AppWindow::human_size ( uint64_t bytes)
staticprivate

Definition at line 277 of file app_window.cpp.

277 {
278 const char* units[] = {"B", "KiB", "MiB", "GiB", "TiB"};
279 double value = static_cast<double>(bytes);
280 int idx = 0;
281 while (value >= 1024.0 && idx < 4) {
282 value /= 1024.0;
283 ++idx;
284 }
285 std::ostringstream oss;
286 oss << std::fixed << std::setprecision(2) << value << ' ' << units[idx];
287 return oss.str();
288}

Referenced by on_scan_completed(), and ~AppWindow().

◆ on_choose_file()

void AppWindow::on_choose_file ( )
private

Definition at line 146 of file app_window.cpp.

146 {
147 file_dialog_ = Gtk::FileDialog::create();
148 file_dialog_->set_title(tr("Select disk image"));
149 file_dialog_->open(*this, sigc::mem_fun(*this, &AppWindow::on_file_chosen));
150}
Glib::RefPtr< Gtk::FileDialog > file_dialog_
void on_file_chosen(const Glib::RefPtr< Gio::AsyncResult > &result)

References file_dialog_, on_file_chosen(), and tr().

Referenced by AppWindow(), and ~AppWindow().

◆ on_choose_output_folder()

void AppWindow::on_choose_output_folder ( )
private

Definition at line 296 of file app_window.cpp.

296 {
297 if (last_report_.input_path.empty()) {
298 append_log(trs("No scan report available."));
299 return;
300 }
302 append_log(trs("A recovery task is already running."));
303 return;
304 }
305
306 output_dialog_ = Gtk::FileDialog::create();
307 output_dialog_->set_title(tr("Select destination folder"));
308 output_dialog_->select_folder(*this, sigc::mem_fun(*this, &AppWindow::on_output_folder_chosen));
309}
void on_output_folder_chosen(const Glib::RefPtr< Gio::AsyncResult > &result)
RecoveryWorker recovery_worker_
void append_log(const std::string &line)
Glib::RefPtr< Gtk::FileDialog > output_dialog_
ScanReport last_report_
bool running() const
std::string trs(const char *msgid)
Definition i18n.cpp:22
std::string input_path
Definition models.hpp:38

References append_log(), ScanReport::input_path, last_report_, on_output_folder_chosen(), output_dialog_, recovery_worker_, RecoveryWorker::running(), tr(), and trs().

Referenced by AppWindow(), and ~AppWindow().

◆ on_file_chosen()

void AppWindow::on_file_chosen ( const Glib::RefPtr< Gio::AsyncResult > & result)
private

Definition at line 152 of file app_window.cpp.

152 {
153 try {
154 if (!file_dialog_) {
155 append_log(trs("Internal error: file dialog unavailable."));
156 return;
157 }
158 auto file = file_dialog_->open_finish(result);
159 if (file) {
160 selected_path_ = file->get_path();
161 entry_path_.set_text(selected_path_);
162 append_log(trs("Selected file:") + " " + selected_path_);
163 status_.set_text(tr("File ready for scan"));
164 }
165 } catch (const Glib::Error& ex) {
166 append_log(trs("File selection cancelled or failed:") + " " + ex.what());
167 }
168 file_dialog_.reset();
169}
std::string selected_path_

References append_log(), entry_path_, file_dialog_, selected_path_, status_, tr(), and trs().

Referenced by on_choose_file(), and ~AppWindow().

◆ on_output_folder_chosen()

void AppWindow::on_output_folder_chosen ( const Glib::RefPtr< Gio::AsyncResult > & result)
private

Definition at line 311 of file app_window.cpp.

311 {
312 try {
313 if (!output_dialog_) {
314 append_log(trs("Internal error: output dialog unavailable."));
315 return;
316 }
317 auto file = output_dialog_->select_folder_finish(result);
318 if (!file) {
319 output_dialog_.reset();
320 return;
321 }
322 output_dir_ = file->get_path();
323 append_log(trs("Recovery destination:") + std::string(" ") + output_dir_);
324 status_.set_text(tr("Recovery in progress..."));
325 btn_open_.set_sensitive(false);
326 btn_scan_.set_sensitive(false);
327 btn_save_report_.set_sensitive(false);
328 btn_recover_.set_sensitive(false);
329
330 recovery_worker_.start(last_report_, output_dir_, [this](const RecoveryResult& rr) {
331 Glib::signal_idle().connect_once([this, rr]() {
333 });
334 });
335 } catch (const Glib::Error& ex) {
336 append_log(trs("Destination selection cancelled or failed:") + std::string(" ") + ex.what());
337 }
338 output_dialog_.reset();
339}
void on_recovery_completed(const RecoveryResult &result)
std::string output_dir_
void start(const ScanReport &report, const std::string &output_dir, const std::vector< size_t > &selected_result_indices, CompletionCallback cb)

References append_log(), btn_open_, btn_recover_, btn_save_report_, btn_scan_, last_report_, on_recovery_completed(), output_dialog_, output_dir_, recovery_worker_, RecoveryWorker::start(), status_, tr(), and trs().

Referenced by on_choose_output_folder(), and ~AppWindow().

◆ on_recovery_completed()

void AppWindow::on_recovery_completed ( const RecoveryResult & result)
private

Definition at line 341 of file app_window.cpp.

341 {
342 for (const auto& line : result.logs) {
343 append_log(line);
344 }
345 if (result.ok) {
346 append_log(trs("Exported images:") + std::string(" ") + std::to_string(result.summary.exported_images.size()));
347 append_log(trs("Recovered files:") + std::string(" ") + std::to_string(result.summary.recovered_files.size()));
348 status_.set_text(tr("Recovery completed"));
349 } else {
350 append_log(trs("Recovery failed:") + std::string(" ") + result.error);
351 status_.set_text(tr("Recovery failed"));
352 }
353 btn_open_.set_sensitive(true);
354 btn_scan_.set_sensitive(true);
355 btn_save_report_.set_sensitive(true);
356 btn_recover_.set_sensitive(true);
357}
RecoverySummary summary
std::vector< std::string > logs
std::vector< std::string > exported_images
std::vector< std::string > recovered_files

References append_log(), btn_open_, btn_recover_, btn_save_report_, btn_scan_, RecoveryResult::error, RecoverySummary::exported_images, RecoveryResult::logs, RecoveryResult::ok, RecoverySummary::recovered_files, status_, RecoveryResult::summary, tr(), and trs().

Referenced by on_output_folder_chosen(), and ~AppWindow().

◆ on_report_file_chosen()

void AppWindow::on_report_file_chosen ( const Glib::RefPtr< Gio::AsyncResult > & result)
private

Definition at line 237 of file app_window.cpp.

237 {
238 try {
239 if (!save_dialog_) {
240 append_log(trs("Internal error: save dialog unavailable."));
241 return;
242 }
243
244 auto file = save_dialog_->save_finish(result);
245 if (!file) {
246 save_dialog_.reset();
247 return;
248 }
249
250 const std::string path = file->get_path();
251 std::string err;
252 bool ok = false;
253 if (path.size() >= 5 && path.substr(path.size() - 5) == ".json") {
255 } else {
257 }
258
259 if (ok) {
260 append_log(trs("Report saved:") + " " + path);
261 status_.set_text(tr("Report saved"));
262 } else {
263 append_log(trs("Failed to save report:") + " " + err);
264 status_.set_text(tr("Report save failed"));
265 }
266 } catch (const Glib::Error& ex) {
267 append_log(trs("Report save cancelled or failed:") + " " + ex.what());
268 }
269 save_dialog_.reset();
270}
Glib::RefPtr< Gtk::FileDialog > save_dialog_
static bool save_json(const ScanReport &report, const std::string &path, std::string &error_out)
static bool save_text(const ScanReport &report, const std::string &path, std::string &error_out)

References append_log(), last_report_, save_dialog_, ReportExporter::save_json(), ReportExporter::save_text(), status_, tr(), and trs().

Referenced by on_save_report_clicked(), and ~AppWindow().

◆ on_save_report_clicked()

void AppWindow::on_save_report_clicked ( )
private

Definition at line 226 of file app_window.cpp.

226 {
227 if (last_report_.input_path.empty()) {
228 append_log(trs("No scan report available."));
229 return;
230 }
231
232 save_dialog_ = Gtk::FileDialog::create();
233 save_dialog_->set_title(tr("Save report"));
234 save_dialog_->save(*this, sigc::mem_fun(*this, &AppWindow::on_report_file_chosen));
235}
void on_report_file_chosen(const Glib::RefPtr< Gio::AsyncResult > &result)

References append_log(), ScanReport::input_path, last_report_, on_report_file_chosen(), save_dialog_, tr(), and trs().

Referenced by AppWindow(), and ~AppWindow().

◆ on_scan_clicked()

void AppWindow::on_scan_clicked ( )
private

Definition at line 171 of file app_window.cpp.

171 {
172 if (selected_path_.empty()) {
173 append_log(trs("No file selected."));
174 status_.set_text(tr("Select a file first"));
175 return;
176 }
177 if (worker_.running()) {
178 append_log(trs("A scan is already running."));
179 return;
180 }
181
182 while (store_->get_n_items() > 0) {
183 store_->remove(store_->get_n_items() - 1);
184 }
185 last_report_ = {};
186 log_buffer_->set_text("");
187 append_log(trs("Starting read-only scan..."));
188 status_.set_text(tr("Scanning in progress..."));
189 btn_open_.set_sensitive(false);
190 btn_scan_.set_sensitive(false);
191 btn_save_report_.set_sensitive(false);
192 btn_recover_.set_sensitive(false);
193
194 worker_.start(selected_path_, [this](const ScanReport& report) {
195 Glib::signal_idle().connect_once([this, report]() {
196 on_scan_completed(report);
197 });
198 });
199}
ScanWorker worker_
void on_scan_completed(const ScanReport &report)
void start(const std::string &path, CompletionCallback cb, ProgressCallback progress_cb={})
bool running() const

References append_log(), btn_open_, btn_recover_, btn_save_report_, btn_scan_, last_report_, log_buffer_, on_scan_completed(), ScanWorker::running(), selected_path_, ScanWorker::start(), status_, store_, tr(), trs(), and worker_.

Referenced by AppWindow(), and ~AppWindow().

◆ on_scan_completed()

void AppWindow::on_scan_completed ( const ScanReport & report)
private

Definition at line 201 of file app_window.cpp.

201 {
202 last_report_ = report;
203
204 for (const auto& line : report.logs) {
205 append_log(line);
206 }
207
208 for (const auto& r : report.results) {
209 std::ostringstream conf;
210 conf << std::fixed << std::setprecision(2) << (r.confidence * 100.0) << "%";
211 store_->append(ResultRow::create(human_offset(r.offset_bytes),
212 human_size(r.size_bytes),
213 r.type,
214 r.source,
215 r.detail,
216 conf.str()));
217 }
218
219 status_.set_text(tr("Scan completed"));
220 btn_open_.set_sensitive(true);
221 btn_scan_.set_sensitive(true);
222 btn_save_report_.set_sensitive(true);
223 btn_recover_.set_sensitive(true);
224}
static std::string human_offset(uint64_t bytes)
static std::string human_size(uint64_t bytes)
static Glib::RefPtr< ResultRow > create(const Glib::ustring &offset, const Glib::ustring &size, const Glib::ustring &type, const Glib::ustring &source, const Glib::ustring &detail, const Glib::ustring &confidence)
std::vector< ScanResult > results
Definition models.hpp:40
std::vector< std::string > logs
Definition models.hpp:41

References append_log(), btn_open_, btn_recover_, btn_save_report_, btn_scan_, ResultRow::create(), human_offset(), human_size(), last_report_, ScanReport::logs, ScanReport::results, status_, store_, and tr().

Referenced by on_scan_clicked(), and ~AppWindow().

◆ setup_columns()

void AppWindow::setup_columns ( )
private

Definition at line 93 of file app_window.cpp.

93 {
94 add_text_column(tr("Offset"), "offset");
95 add_text_column(tr("Size"), "size");
96 add_text_column(tr("Type"), "type");
97 add_text_column(tr("Source"), "source");
98 add_text_column(tr("Detail"), "detail");
99 add_text_column(tr("Confidence"), "confidence");
100}
void add_text_column(const Glib::ustring &title, const char *property_name)

References add_text_column(), and tr().

Referenced by AppWindow(), and ~AppWindow().

Member Data Documentation

◆ btn_open_

Gtk::Button AppWindow::btn_open_
private

◆ btn_recover_

Gtk::Button AppWindow::btn_recover_
private

◆ btn_save_report_

Gtk::Button AppWindow::btn_save_report_
private

◆ btn_scan_

Gtk::Button AppWindow::btn_scan_
private

◆ column_view_

Gtk::ColumnView AppWindow::column_view_
private

Definition at line 63 of file app_window.hpp.

Referenced by add_text_column(), and AppWindow().

◆ entry_path_

Gtk::Entry AppWindow::entry_path_
private

Definition at line 58 of file app_window.hpp.

Referenced by AppWindow(), and on_file_chosen().

◆ file_dialog_

Glib::RefPtr<Gtk::FileDialog> AppWindow::file_dialog_
private

Definition at line 68 of file app_window.hpp.

Referenced by on_choose_file(), and on_file_chosen().

◆ last_report_

◆ log_buffer_

Glib::RefPtr<Gtk::TextBuffer> AppWindow::log_buffer_
private

Definition at line 65 of file app_window.hpp.

Referenced by append_log(), AppWindow(), and on_scan_clicked().

◆ log_view_

Gtk::TextView AppWindow::log_view_
private

Definition at line 64 of file app_window.hpp.

Referenced by AppWindow().

◆ logs_scroller_

Gtk::ScrolledWindow AppWindow::logs_scroller_
private

Definition at line 62 of file app_window.hpp.

Referenced by AppWindow().

◆ output_dialog_

Glib::RefPtr<Gtk::FileDialog> AppWindow::output_dialog_
private

Definition at line 70 of file app_window.hpp.

Referenced by on_choose_output_folder(), and on_output_folder_chosen().

◆ output_dir_

std::string AppWindow::output_dir_
private

Definition at line 72 of file app_window.hpp.

Referenced by on_output_folder_chosen().

◆ paned_

Gtk::Paned AppWindow::paned_ {Gtk::Orientation::VERTICAL}
private

Definition at line 60 of file app_window.hpp.

Referenced by AppWindow().

◆ recovery_worker_

RecoveryWorker AppWindow::recovery_worker_
private

Definition at line 75 of file app_window.hpp.

Referenced by on_choose_output_folder(), and on_output_folder_chosen().

◆ results_scroller_

Gtk::ScrolledWindow AppWindow::results_scroller_
private

Definition at line 61 of file app_window.hpp.

Referenced by AppWindow().

◆ root_

Gtk::Box AppWindow::root_ {Gtk::Orientation::VERTICAL, 8}
private

Definition at line 52 of file app_window.hpp.

Referenced by AppWindow().

◆ save_dialog_

Glib::RefPtr<Gtk::FileDialog> AppWindow::save_dialog_
private

Definition at line 69 of file app_window.hpp.

Referenced by on_report_file_chosen(), and on_save_report_clicked().

◆ selected_path_

std::string AppWindow::selected_path_
private

Definition at line 71 of file app_window.hpp.

Referenced by on_file_chosen(), and on_scan_clicked().

◆ selection_model_

Glib::RefPtr<Gtk::SingleSelection> AppWindow::selection_model_
private

Definition at line 67 of file app_window.hpp.

Referenced by AppWindow().

◆ status_

Gtk::Label AppWindow::status_
private

◆ store_

Glib::RefPtr<Gio::ListStore<ResultRow> > AppWindow::store_
private

Definition at line 66 of file app_window.hpp.

Referenced by AppWindow(), on_scan_clicked(), and on_scan_completed().

◆ toolbar_

Gtk::Box AppWindow::toolbar_ {Gtk::Orientation::HORIZONTAL, 8}
private

Definition at line 53 of file app_window.hpp.

Referenced by AppWindow().

◆ worker_

ScanWorker AppWindow::worker_
private

Definition at line 74 of file app_window.hpp.

Referenced by on_scan_clicked().


The documentation for this class was generated from the following files:
  • BastionGuard/thirdparty/bastionguard-recovery-data/src/app_window.hpp
  • BastionGuard/thirdparty/bastionguard-recovery-data/src/app_window.cpp