Skip to content

Commit

Permalink
Merge pull request #795 from guserav/pnp-settings-save-load
Browse files Browse the repository at this point in the history
Add save and load for PnP export

changelog: New Features/Board Editor: Add save and load for PnP export
carrotIndustries authored Jan 22, 2025
2 parents 250ee06 + 9021624 commit 40bd730
Showing 5 changed files with 105 additions and 6 deletions.
4 changes: 2 additions & 2 deletions src/imp/pnp_export.ui
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.38.2 -->
<!-- Generated with glade 3.40.0 -->
<interface>
<requires lib="gtk+" version="3.20"/>
<object class="GtkImage" id="image1">
@@ -893,7 +893,7 @@
</object>
</child>
<child type="titlebar">
<object class="GtkHeaderBar">
<object class="GtkHeaderBar" id="pnp_header">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="title" translatable="yes">Pick &amp; place export</property>
78 changes: 77 additions & 1 deletion src/imp/pnp_export_window.cpp
Original file line number Diff line number Diff line change
@@ -5,6 +5,9 @@
#include "export_pnp/export_pnp.hpp"
#include "widgets/help_button.hpp"
#include "help_texts.hpp"
#include "nlohmann/json.hpp"

#include <iostream>

namespace horizon {

@@ -27,6 +30,7 @@ PnPExportWindow::PnPExportWindow(BaseObjectType *cobject, const Glib::RefPtr<Gtk
: Gtk::Window(cobject), board(brd), settings(s), state_store(this, "imp-pnp-export"), adapter(settings.columns)
{

GET_WIDGET(pnp_header);
GET_WIDGET(export_button);
GET_WIDGET(directory_button);
GET_WIDGET(directory_entry);
@@ -48,6 +52,23 @@ PnPExportWindow::PnPExportWindow(BaseObjectType *cobject, const Glib::RefPtr<Gtk

done_revealer_controller.attach(done_revealer, done_label, done_close_button);

{
auto hamburger_button = Gtk::manage(new Gtk::MenuButton);
hamburger_button->set_image_from_icon_name("open-menu-symbolic", Gtk::ICON_SIZE_BUTTON);

hamburger_menu = Gio::Menu::create();
hamburger_button->set_menu_model(hamburger_menu);
hamburger_button->show();
pnp_header->pack_end(*hamburger_button);

auto action_group = Gio::SimpleActionGroup::create();
insert_action_group("pnp_export", action_group);
action_group->add_action("save_settings", [this] { save_to_file(); });
action_group->add_action("load_settings", [this] { load_from_file(); });
hamburger_menu->append("Save Settings", "pnp_export.save_settings");
hamburger_menu->append("Load Settings", "pnp_export.load_settings");
}

export_filechooser.attach(directory_entry, directory_button, this);
export_filechooser.set_project_dir(project_dir);
export_filechooser.bind_filename(settings.output_directory);
@@ -108,6 +129,7 @@ PnPExportWindow::PnPExportWindow(BaseObjectType *cobject, const Glib::RefPtr<Gtk
int top = 3;
for (const auto &[id, name] : pnp_column_names) {
auto entry = Gtk::manage(new Gtk::Entry);
column_name_entries[id] = entry;
entry->show();
auto box = Gtk::manage(new Gtk::Box(Gtk::ORIENTATION_HORIZONTAL, 5));
{
@@ -148,7 +170,6 @@ PnPExportWindow::PnPExportWindow(BaseObjectType *cobject, const Glib::RefPtr<Gtk
{
#define BIND_ENTRY(name_) \
do { \
Gtk::Entry *name_##_entry; \
GET_WIDGET(name_##_entry); \
bind_widget(name_##_entry, settings.name_, [this](std::string &) { \
s_signal_changed.emit(); \
@@ -279,6 +300,61 @@ void PnPExportWindow::update_export_button()
widget_set_insensitive_tooltip(*export_button, txt);
}

void PnPExportWindow::save_to_file()
{
GtkFileChooserNative *native = gtk_file_chooser_native_new("Save Settings", GTK_WINDOW(gobj()),
GTK_FILE_CHOOSER_ACTION_SAVE, "_Save", "_Cancel");
auto chooser = Glib::wrap(GTK_FILE_CHOOSER(native));
chooser->set_do_overwrite_confirmation(true);

std::string path;
auto success = run_native_filechooser_with_retry(chooser, "Error saving settings", [this, chooser, &path] {
path = append_dot_json(chooser->get_filename());
});
if (success) {
json j = settings.serialize();
save_json_to_file(path, j);
std::cout << "Saved settings to: " << path << std::endl;
}
}

void PnPExportWindow::load_from_file()
{
GtkFileChooserNative *native = gtk_file_chooser_native_new("Save Settings", GTK_WINDOW(gobj()),
GTK_FILE_CHOOSER_ACTION_OPEN, "_Open", "_Cancel");

auto chooser = Glib::wrap(GTK_FILE_CHOOSER(native));

if (gtk_native_dialog_run(GTK_NATIVE_DIALOG(native)) == GTK_RESPONSE_ACCEPT) {
std::string path = chooser->get_filename();
json j = load_json_from_file(path);
auto new_settings = PnPExportSettings(j);
mode_combo->set_active_id(PnPExportSettings::mode_lut.lookup_reverse(new_settings.mode));
nopopulate_check->set_active(new_settings.include_nopopulate);
customize_check->set_active(new_settings.customize);

settings.columns = new_settings.columns;
column_chooser->update_from_adapter();
for (const auto &[id, name] : new_settings.column_names) {
column_name_entries[id]->set_text(name);
}

#define SET_ENTRY(name_) \
do { \
name_##_entry->set_text(new_settings.name_); \
} while (0)

SET_ENTRY(filename_top);
SET_ENTRY(filename_bottom);
SET_ENTRY(filename_merged);
SET_ENTRY(position_format);
SET_ENTRY(top_side);
SET_ENTRY(bottom_side);
std::cout << "Loaded settings from: " << path << std::endl;
}
#undef SET_ENTRY
}

PnPExportWindow *PnPExportWindow::create(Gtk::Window *p, const class Board &brd, class PnPExportSettings &settings,
const std::string &project_dir)
{
11 changes: 11 additions & 0 deletions src/imp/pnp_export_window.hpp
Original file line number Diff line number Diff line change
@@ -23,13 +23,16 @@ class PnPExportWindow : public Gtk::Window, public Changeable {
void generate();
void update_preview();
void update();
void save_to_file();
void load_from_file();

private:
const class Board &board;
class PnPExportSettings &settings;

ExportFileChooser export_filechooser;

Gtk::HeaderBar *pnp_header = nullptr;
Gtk::Button *export_button = nullptr;
Gtk::Label *done_label = nullptr;
Gtk::Revealer *done_revealer = nullptr;
@@ -50,6 +53,14 @@ class PnPExportWindow : public Gtk::Window, public Changeable {
Gtk::Revealer *customize_revealer = nullptr;
Gtk::Grid *customize_grid = nullptr;

Gtk::Entry *position_format_entry = nullptr;
Gtk::Entry *top_side_entry = nullptr;
Gtk::Entry *bottom_side_entry = nullptr;

std::map<PnPColumn, Gtk::Entry *> column_name_entries;

Glib::RefPtr<Gio::Menu> hamburger_menu;

bool can_export = true;
void update_export_button();

14 changes: 12 additions & 2 deletions src/widgets/column_chooser.cpp
Original file line number Diff line number Diff line change
@@ -90,8 +90,7 @@ void ColumnChooser::incl_excl_col(bool incl)
else
adapter.exclude_column(col);

columns_available->refilter();
update_cols_included();
update_from_adapter();

if (incl) {
for (const auto &it : columns_store_included->children()) {
@@ -147,5 +146,16 @@ void ColumnChooser::update_cols_included()
}
}

void ColumnChooser::update_cols_available()
{
columns_available->refilter();
}

void ColumnChooser::update_from_adapter()
{
update_cols_available();
update_cols_included();
}


} // namespace horizon
4 changes: 3 additions & 1 deletion src/widgets/column_chooser.hpp
Original file line number Diff line number Diff line change
@@ -19,6 +19,9 @@ class ColumnChooser : public Gtk::Grid, public Changeable {
ColumnChooser(BaseObjectType *cobject, const Glib::RefPtr<Gtk::Builder> &x, IAdapter &adap);
static ColumnChooser *create(IAdapter &adap);

void update_cols_included();
void update_cols_available();
void update_from_adapter();

template <typename T> class Adapter : public IAdapter {
public:
@@ -106,6 +109,5 @@ class ColumnChooser : public Gtk::Grid, public Changeable {
void incl_excl_col(bool incl);
void up_down_col(bool up);
void update_incl_excl_sensitivity();
void update_cols_included();
};
} // namespace horizon

0 comments on commit 40bd730

Please sign in to comment.