Skip to content
API Documentation
BastionGuard™
PasswordImportDialog Class Reference

#include <PasswordImportDialog.hpp>

Public Types

using BulkItem = std::pair<PasswordEntry, std::string>

Public Member Functions

 PasswordImportDialog (Gtk::Window &parent)
 ~PasswordImportDialog ()
void present ()
void hide ()
sigc::signal< void(std::vector< BulkItem >)> signal_import_confirmed ()

Private Member Functions

void buildUi ()
void styleImportButton ()
void onChooseFile ()
void loadFile (const std::string &path)
void populatePreview ()
void onImportClicked ()
void onProgressTick ()
void onImportDone ()

Private Attributes

Gtk::Window & parent_
Gtk::Dialog * dialog_ = nullptr
Gtk::Box mainBox_
Gtk::Label hintLabel_
Gtk::Button chooseFileBtn_
Gtk::Label fileLabel_
Gtk::Label formatLabel_
Gtk::Label countLabel_
Gtk::ListBox previewList_
Gtk::ScrolledWindow previewScrolled_
Gtk::Box progressBox_
Gtk::ProgressBar progressBar_
Gtk::Label progressLabel_
Gtk::Button importBtn_
std::vector< ImportedCredential > parsed_
std::vector< BulkItem > pendingItems_
sigc::signal< void(std::vector< BulkItem >)> signalImportConfirmed_
std::thread importThread_
std::atomic< bool > importing_ { false }
std::atomic< int > progressDone_ { 0 }
std::atomic< int > progressTotal_ { 0 }
Glib::Dispatcher dispProgress_
Glib::Dispatcher dispDone_

Detailed Description

Definition at line 31 of file PasswordImportDialog.hpp.

Member Typedef Documentation

◆ BulkItem

using PasswordImportDialog::BulkItem = std::pair<PasswordEntry, std::string>

Definition at line 39 of file PasswordImportDialog.hpp.

Constructor & Destructor Documentation

◆ PasswordImportDialog()

PasswordImportDialog::PasswordImportDialog ( Gtk::Window & parent)
explicit

Definition at line 28 of file PasswordImportDialog.cpp.

29: parent_(parent),
30 mainBox_(Gtk::Orientation::VERTICAL, 10),
31 hintLabel_(_("Seleziona un file CSV esportato da Chrome, Edge, Firefox o Safari.")),
32 chooseFileBtn_(_("📂 Scegli file CSV…")),
33 progressBox_(Gtk::Orientation::VERTICAL, 4),
34 importBtn_(_("⬆ Importa credenziali"))
35{
36 dialog_ = new Gtk::Dialog(_("Importa credenziali da browser"), parent, true);
37 dialog_->set_default_size(720, 560);
38
39 dispProgress_.connect(sigc::mem_fun(*this, &PasswordImportDialog::onProgressTick));
40 dispDone_.connect(sigc::mem_fun(*this, &PasswordImportDialog::onImportDone));
41
42 buildUi();
43}
#define _(s)

References _, buildUi(), chooseFileBtn_, dialog_, dispDone_, dispProgress_, hintLabel_, importBtn_, mainBox_, onImportDone(), onProgressTick(), parent_, and progressBox_.

Referenced by PasswordManagerPage::onImportClicked().

◆ ~PasswordImportDialog()

PasswordImportDialog::~PasswordImportDialog ( )

Definition at line 45 of file PasswordImportDialog.cpp.

45 {
46 if (importThread_.joinable()) importThread_.join();
47 delete dialog_;
48}

References dialog_, and importThread_.

Member Function Documentation

◆ buildUi()

void PasswordImportDialog::buildUi ( )
private

Definition at line 53 of file PasswordImportDialog.cpp.

53 {
54 auto* content = dialog_->get_content_area();
55 content->set_spacing(0);
56 content->set_margin(0);
57
58 mainBox_.set_margin(16);
59 mainBox_.set_spacing(10);
60
61 hintLabel_.set_xalign(0.0f);
62 hintLabel_.set_wrap(true);
63 mainBox_.append(hintLabel_);
64
65 auto* fileRow = Gtk::make_managed<Gtk::Box>(Gtk::Orientation::HORIZONTAL, 8);
66 fileLabel_.set_xalign(0.0f);
67 fileLabel_.set_hexpand(true);
68 fileLabel_.set_ellipsize(Pango::EllipsizeMode::MIDDLE);
69 fileRow->append(chooseFileBtn_);
70 fileRow->append(fileLabel_);
71 mainBox_.append(*fileRow);
72
73 auto* infoRow = Gtk::make_managed<Gtk::Box>(Gtk::Orientation::HORIZONTAL, 16);
74 formatLabel_.set_xalign(0.0f);
75 countLabel_.set_xalign(0.0f);
76 infoRow->append(formatLabel_);
77 infoRow->append(countLabel_);
78 mainBox_.append(*infoRow);
79
80 mainBox_.append(*Gtk::make_managed<Gtk::Separator>(Gtk::Orientation::HORIZONTAL));
81
82 auto* previewLabel = Gtk::make_managed<Gtk::Label>(
83 _("Anteprima (prime 50 righe — tutte verranno importate):"));
84 previewLabel->set_xalign(0.0f);
85 previewLabel->get_style_context()->add_class("heading");
86 mainBox_.append(*previewLabel);
87
88 previewList_.set_selection_mode(Gtk::SelectionMode::NONE);
90 previewScrolled_.set_vexpand(true);
91 previewScrolled_.set_min_content_height(240);
93 progressLabel_.set_xalign(0.0f);
94 progressBar_.set_show_text(false);
95 progressBar_.set_fraction(0.0);
98 progressBox_.set_visible(false);
99 mainBox_.append(progressBox_);
100
101 content->append(mainBox_);
102
103 dialog_->add_button(_("Chiudi"), Gtk::ResponseType::CANCEL);
104
105 importBtn_.set_sensitive(false);
107 content->append(importBtn_);
108
109 chooseFileBtn_.signal_clicked().connect(
110 sigc::mem_fun(*this, &PasswordImportDialog::onChooseFile));
111 importBtn_.signal_clicked().connect(
112 sigc::mem_fun(*this, &PasswordImportDialog::onImportClicked));
113
114 dialog_->signal_response().connect([this](int r) {
115 if ((r == Gtk::ResponseType::CANCEL || r == Gtk::ResponseType::DELETE_EVENT)
116 && !importing_)
117 dialog_->hide();
118 });
119}
std::atomic< bool > importing_
Gtk::ScrolledWindow previewScrolled_

References _, chooseFileBtn_, countLabel_, dialog_, fileLabel_, formatLabel_, hintLabel_, importBtn_, importing_, mainBox_, onChooseFile(), onImportClicked(), previewList_, previewScrolled_, progressBar_, progressBox_, progressLabel_, and styleImportButton().

Referenced by PasswordImportDialog().

◆ hide()

void PasswordImportDialog::hide ( )

Definition at line 51 of file PasswordImportDialog.cpp.

51{ dialog_->hide(); }

References dialog_.

◆ loadFile()

void PasswordImportDialog::loadFile ( const std::string & path)
private

Definition at line 168 of file PasswordImportDialog.cpp.

168 {
169 std::string errorMsg;
171
172 const auto slash = path.rfind('/');
173 fileLabel_.set_text(slash != std::string::npos ? path.substr(slash + 1) : path);
174
175 if (!errorMsg.empty() || parsed_.empty()) {
176 const std::string msg = errorMsg.empty() ? "Nessuna credenziale trovata." : errorMsg;
177 formatLabel_.set_markup(
178 std::string("<span foreground='red'>⚠ ") +
179 Glib::Markup::escape_text(msg) + "</span>");
180 countLabel_.set_text("");
181 importBtn_.set_sensitive(false);
182 while (auto* child = previewList_.get_first_child())
183 previewList_.remove(*child);
184 return;
185 }
186
187 std::ifstream probe(path);
188 std::string firstLine;
189 std::getline(probe, firstLine);
190 if (!firstLine.empty() && firstLine.back() == '\r') firstLine.pop_back();
191
192 const auto fmt = PasswordImporter::detectFormat(firstLine);
193 std::string fmtName;
194 switch (fmt) {
195 case BrowserFormat::Chrome: fmtName = "Chrome"; break;
196 case BrowserFormat::Edge: fmtName = "Edge"; break;
197 case BrowserFormat::Firefox: fmtName = "Firefox"; break;
198 case BrowserFormat::Safari: fmtName = "Safari"; break;
199 default: fmtName = "?"; break;
200 }
201
202 formatLabel_.set_markup(
203 std::string("<b>") + std::string(_("Browser: ")) + "</b>" + fmtName);
204 countLabel_.set_markup(
205 std::string("<b>") + std::string(_("Credenziali trovate: ")) + "</b>" +
206 std::to_string(parsed_.size()));
207
208 importBtn_.set_sensitive(true);
210}
std::vector< ImportedCredential > parsed_
static BrowserFormat detectFormat(const std::string &headerLine)
static std::vector< ImportedCredential > importFromFile(const std::string &path, std::string &errorMsg)

References _, Chrome, countLabel_, PasswordImporter::detectFormat(), Edge, fileLabel_, Firefox, formatLabel_, importBtn_, PasswordImporter::importFromFile(), parsed_, populatePreview(), previewList_, and Safari.

Referenced by onChooseFile().

◆ onChooseFile()

void PasswordImportDialog::onChooseFile ( )
private

Definition at line 136 of file PasswordImportDialog.cpp.

136 {
137 auto* fc = new Gtk::FileChooserDialog(
138 _("Seleziona file CSV"), Gtk::FileChooser::Action::OPEN);
139 fc->set_transient_for(*dialog_);
140 fc->set_modal(true);
141
142 auto filter = Gtk::FileFilter::create();
143 filter->set_name(_("File CSV (*.csv)"));
144 filter->add_pattern("*.csv");
145 filter->add_pattern("*.CSV");
146 fc->add_filter(filter);
147
148 auto filterAll = Gtk::FileFilter::create();
149 filterAll->set_name(_("Tutti i file"));
150 filterAll->add_pattern("*");
151 fc->add_filter(filterAll);
152
153 fc->add_button(_("Annulla"), Gtk::ResponseType::CANCEL);
154 fc->add_button(_("Apri"), Gtk::ResponseType::OK);
155
156 fc->signal_response().connect([this, fc](int r) {
157 if (r == Gtk::ResponseType::OK) {
158 const auto file = fc->get_file();
159 if (file) loadFile(file->get_path());
160 }
161 fc->hide();
162 delete fc;
163 });
164 fc->present();
165}
void loadFile(const std::string &path)

References _, dialog_, and loadFile().

Referenced by buildUi().

◆ onImportClicked()

void PasswordImportDialog::onImportClicked ( )
private

Definition at line 278 of file PasswordImportDialog.cpp.

278 {
279 if (parsed_.empty() || importing_) return;
280
281 importing_ = true;
282 progressDone_ = 0;
283 progressTotal_ = static_cast<int>(parsed_.size());
284
285 progressBar_.set_fraction(0.0);
286 progressLabel_.set_text(
287 std::string(_("Preparazione: ")) +
288 std::to_string(progressTotal_) +
289 std::string(_(" credenziali…")));
290 progressBox_.set_visible(true);
291 importBtn_.set_sensitive(false);
292 chooseFileBtn_.set_sensitive(false);
293 dialog_->set_response_sensitive(Gtk::ResponseType::CANCEL, false);
294 auto creds = parsed_;
295
296 importThread_ = std::thread([this, creds]() mutable {
297 pendingItems_.clear();
298 pendingItems_.reserve(creds.size());
299
300 for (auto& c : creds) {
301 PasswordEntry e = PasswordImporter::toPasswordEntry(c);
302 pendingItems_.emplace_back(std::move(e), std::move(c.password));
304 dispProgress_.emit();
305 }
306
307 dispDone_.emit();
308 });
309}
std::atomic< int > progressDone_
std::vector< BulkItem > pendingItems_
std::atomic< int > progressTotal_
static PasswordEntry toPasswordEntry(const ImportedCredential &cred)

References _, chooseFileBtn_, dialog_, dispDone_, dispProgress_, importBtn_, importing_, importThread_, parsed_, pendingItems_, progressBar_, progressBox_, progressDone_, progressLabel_, progressTotal_, and PasswordImporter::toPasswordEntry().

Referenced by buildUi().

◆ onImportDone()

void PasswordImportDialog::onImportDone ( )
private

Definition at line 322 of file PasswordImportDialog.cpp.

322 {
323 if (importThread_.joinable()) importThread_.join();
324
325 progressBar_.set_fraction(1.0);
326 progressLabel_.set_text(_("Salvataggio nel vault…"));
327 importing_ = false;
328 signalImportConfirmed_.emit(std::move(pendingItems_));
329}
sigc::signal< void(std::vector< BulkItem >)> signalImportConfirmed_

References _, importing_, importThread_, pendingItems_, progressBar_, progressLabel_, and signalImportConfirmed_.

Referenced by PasswordImportDialog().

◆ onProgressTick()

void PasswordImportDialog::onProgressTick ( )
private

Definition at line 311 of file PasswordImportDialog.cpp.

311 {
312 const int done = progressDone_.load();
313 const int total = progressTotal_.load();
314 if (total > 0) {
315 progressBar_.set_fraction(static_cast<double>(done) / total);
316 progressLabel_.set_text(
317 std::string(_("Preparazione: ")) + std::to_string(done) +
318 " / " + std::to_string(total));
319 }
320}

References _, progressBar_, progressDone_, progressLabel_, and progressTotal_.

Referenced by PasswordImportDialog().

◆ populatePreview()

void PasswordImportDialog::populatePreview ( )
private

Definition at line 213 of file PasswordImportDialog.cpp.

213 {
214 while (auto* child = previewList_.get_first_child())
215 previewList_.remove(*child);
216
217 // Header
218 {
219 auto* row = Gtk::make_managed<Gtk::ListBoxRow>();
220 auto* box = Gtk::make_managed<Gtk::Box>(Gtk::Orientation::HORIZONTAL, 0);
221 box->set_margin(6);
222 auto makeHdr = [](const std::string& t, int chars) {
223 auto* l = Gtk::make_managed<Gtk::Label>();
224 l->set_markup("<b>" + Glib::Markup::escape_text(t) + "</b>");
225 l->set_xalign(0.0f);
226 l->set_width_chars(chars);
227 l->set_max_width_chars(chars);
228 l->set_ellipsize(Pango::EllipsizeMode::END);
229 return l;
230 };
231 box->append(*makeHdr(_("Nome / Sito"), 26));
232 box->append(*makeHdr(_("Username"), 22));
233 box->append(*makeHdr(_("URL"), 28));
234 row->set_child(*box);
235 row->set_activatable(false);
236 previewList_.append(*row);
237 }
238
239 const size_t limit = std::min(parsed_.size(), size_t(50));
240 for (size_t i = 0; i < limit; ++i) {
241 const auto& c = parsed_[i];
242 auto* row = Gtk::make_managed<Gtk::ListBoxRow>();
243 auto* box = Gtk::make_managed<Gtk::Box>(Gtk::Orientation::HORIZONTAL, 0);
244 box->set_margin_top(3); box->set_margin_bottom(3);
245 box->set_margin_start(6); box->set_margin_end(6);
246 auto makeCell = [](const std::string& t, int chars) {
247 auto* l = Gtk::make_managed<Gtk::Label>(t);
248 l->set_xalign(0.0f);
249 l->set_width_chars(chars);
250 l->set_max_width_chars(chars);
251 l->set_ellipsize(Pango::EllipsizeMode::END);
252 return l;
253 };
254 const std::string name = c.name.empty()
255 ? PasswordImporter::domainFromUrl(c.url) : c.name;
256 box->append(*makeCell(name, 26));
257 box->append(*makeCell(c.username, 22));
258 box->append(*makeCell(c.url, 28));
259 row->set_child(*box);
260 row->set_activatable(false);
261 previewList_.append(*row);
262 }
263
264 if (parsed_.size() > limit) {
265 auto* row = Gtk::make_managed<Gtk::ListBoxRow>();
266 auto* lbl = Gtk::make_managed<Gtk::Label>(
267 std::string("… ") + std::to_string(parsed_.size() - limit) +
268 std::string(_(" altre (tutte verranno importate)")));
269 lbl->set_margin(6);
270 lbl->get_style_context()->add_class("dim-label");
271 row->set_child(*lbl);
272 row->set_activatable(false);
273 previewList_.append(*row);
274 }
275}
static std::string domainFromUrl(const std::string &url)

References _, PasswordImporter::domainFromUrl(), parsed_, and previewList_.

Referenced by loadFile().

◆ present()

void PasswordImportDialog::present ( )

Definition at line 50 of file PasswordImportDialog.cpp.

50{ dialog_->present(); }

References dialog_.

◆ signal_import_confirmed()

sigc::signal< void(std::vector< PasswordImportDialog::BulkItem >)> PasswordImportDialog::signal_import_confirmed ( )

Definition at line 332 of file PasswordImportDialog.cpp.

332 {
334}

References signalImportConfirmed_.

◆ styleImportButton()

void PasswordImportDialog::styleImportButton ( )
private

Definition at line 121 of file PasswordImportDialog.cpp.

121 {
122 importBtn_.get_style_context()->add_class("suggested-action");
123 auto provider = Gtk::CssProvider::create();
124 provider->load_from_data(
125 "button.suggested-action {"
126 " background: linear-gradient(to bottom, #33d17a, #26a269);"
127 " color: white; font-weight: bold;"
128 " padding: 8px 24px; border-radius: 6px;"
129 " border: 1px solid #1e8449;"
130 "}");
131 importBtn_.get_style_context()->add_provider(
132 provider, GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
133}

References importBtn_.

Referenced by buildUi().

Member Data Documentation

◆ chooseFileBtn_

Gtk::Button PasswordImportDialog::chooseFileBtn_
private

Definition at line 48 of file PasswordImportDialog.hpp.

Referenced by buildUi(), onImportClicked(), and PasswordImportDialog().

◆ countLabel_

Gtk::Label PasswordImportDialog::countLabel_
private

Definition at line 51 of file PasswordImportDialog.hpp.

Referenced by buildUi(), and loadFile().

◆ dialog_

Gtk::Dialog* PasswordImportDialog::dialog_ = nullptr
private

◆ dispDone_

Glib::Dispatcher PasswordImportDialog::dispDone_
private

Definition at line 69 of file PasswordImportDialog.hpp.

Referenced by onImportClicked(), and PasswordImportDialog().

◆ dispProgress_

Glib::Dispatcher PasswordImportDialog::dispProgress_
private

Definition at line 68 of file PasswordImportDialog.hpp.

Referenced by onImportClicked(), and PasswordImportDialog().

◆ fileLabel_

Gtk::Label PasswordImportDialog::fileLabel_
private

Definition at line 49 of file PasswordImportDialog.hpp.

Referenced by buildUi(), and loadFile().

◆ formatLabel_

Gtk::Label PasswordImportDialog::formatLabel_
private

Definition at line 50 of file PasswordImportDialog.hpp.

Referenced by buildUi(), and loadFile().

◆ hintLabel_

Gtk::Label PasswordImportDialog::hintLabel_
private

Definition at line 47 of file PasswordImportDialog.hpp.

Referenced by buildUi(), and PasswordImportDialog().

◆ importBtn_

Gtk::Button PasswordImportDialog::importBtn_
private

◆ importing_

std::atomic<bool> PasswordImportDialog::importing_ { false }
private

Definition at line 65 of file PasswordImportDialog.hpp.

Referenced by buildUi(), onImportClicked(), and onImportDone().

◆ importThread_

std::thread PasswordImportDialog::importThread_
private

Definition at line 64 of file PasswordImportDialog.hpp.

Referenced by onImportClicked(), onImportDone(), and ~PasswordImportDialog().

◆ mainBox_

Gtk::Box PasswordImportDialog::mainBox_
private

Definition at line 46 of file PasswordImportDialog.hpp.

Referenced by buildUi(), and PasswordImportDialog().

◆ parent_

Gtk::Window& PasswordImportDialog::parent_
private

Definition at line 43 of file PasswordImportDialog.hpp.

Referenced by PasswordImportDialog().

◆ parsed_

std::vector<ImportedCredential> PasswordImportDialog::parsed_
private

Definition at line 59 of file PasswordImportDialog.hpp.

Referenced by loadFile(), onImportClicked(), and populatePreview().

◆ pendingItems_

std::vector<BulkItem> PasswordImportDialog::pendingItems_
private

Definition at line 60 of file PasswordImportDialog.hpp.

Referenced by onImportClicked(), and onImportDone().

◆ previewList_

Gtk::ListBox PasswordImportDialog::previewList_
private

Definition at line 52 of file PasswordImportDialog.hpp.

Referenced by buildUi(), loadFile(), and populatePreview().

◆ previewScrolled_

Gtk::ScrolledWindow PasswordImportDialog::previewScrolled_
private

Definition at line 53 of file PasswordImportDialog.hpp.

Referenced by buildUi().

◆ progressBar_

Gtk::ProgressBar PasswordImportDialog::progressBar_
private

Definition at line 55 of file PasswordImportDialog.hpp.

Referenced by buildUi(), onImportClicked(), onImportDone(), and onProgressTick().

◆ progressBox_

Gtk::Box PasswordImportDialog::progressBox_
private

Definition at line 54 of file PasswordImportDialog.hpp.

Referenced by buildUi(), onImportClicked(), and PasswordImportDialog().

◆ progressDone_

std::atomic<int> PasswordImportDialog::progressDone_ { 0 }
private

Definition at line 66 of file PasswordImportDialog.hpp.

Referenced by onImportClicked(), and onProgressTick().

◆ progressLabel_

Gtk::Label PasswordImportDialog::progressLabel_
private

Definition at line 56 of file PasswordImportDialog.hpp.

Referenced by buildUi(), onImportClicked(), onImportDone(), and onProgressTick().

◆ progressTotal_

std::atomic<int> PasswordImportDialog::progressTotal_ { 0 }
private

Definition at line 67 of file PasswordImportDialog.hpp.

Referenced by onImportClicked(), and onProgressTick().

◆ signalImportConfirmed_

sigc::signal<void(std::vector<BulkItem>)> PasswordImportDialog::signalImportConfirmed_
private

Definition at line 62 of file PasswordImportDialog.hpp.

Referenced by onImportDone(), and signal_import_confirmed().


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