Customizable association of .3mf, .stl and .gcode files on Windows

This commit is contained in:
enricoturri1966 2020-11-26 10:09:34 +01:00
parent 7da1622e76
commit e2b4de455b
7 changed files with 292 additions and 111 deletions

View file

@ -68,6 +68,15 @@ void AppConfig::set_defaults()
if (get("export_sources_full_pathnames").empty())
set("export_sources_full_pathnames", "0");
#if ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN
#ifdef _WIN32
if (get("associate_3mf").empty())
set("associate_3mf", "0");
if (get("associate_stl").empty())
set("associate_stl", "0");
#endif // _WIN32
#endif // ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN
// remove old 'use_legacy_opengl' parameter from this config, if present
if (!get("use_legacy_opengl").empty())
erase("", "use_legacy_opengl");
@ -109,6 +118,14 @@ void AppConfig::set_defaults()
if (get("use_inches").empty())
set("use_inches", "0");
}
#if ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN
else {
#ifdef _WIN32
if (get("associate_gcode").empty())
set("associate_gcode", "0");
#endif // _WIN32
}
#endif // ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN
if (get("seq_top_layer_only").empty())
set("seq_top_layer_only", "1");

View file

@ -80,6 +80,7 @@
#define ENABLE_SHOW_WIPE_MOVES (1 && ENABLE_2_3_0_BETA1)
#define ENABLE_DRAG_AND_DROP_FIX (1 && ENABLE_2_3_0_BETA1)
#define ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN (1 && ENABLE_2_3_0_BETA1)
#endif // _prusaslicer_technologies_h_

View file

@ -238,7 +238,7 @@ PrinterPicker::PrinterPicker(wxWindow *parent, const VendorProfile &vendor, wxSt
: from_u8(model.name);
if (i == 1) {
auto *alt_label = new wxStaticText(variants_panel, wxID_ANY, _(L("Alternate nozzles:")));
auto *alt_label = new wxStaticText(variants_panel, wxID_ANY, _L("Alternate nozzles:"));
alt_label->SetFont(font_alt_nozzle);
variants_sizer->Add(alt_label, 0, wxBOTTOM, 3);
is_variants = true;
@ -302,9 +302,9 @@ PrinterPicker::PrinterPicker(wxWindow *parent, const VendorProfile &vendor, wxSt
if (/*titles.size() > 1*/is_variants) {
// It only makes sense to add the All / None buttons if there's multiple printers
auto *sel_all_std = new wxButton(this, wxID_ANY, titles.size() > 1 ? _(L("All standard")) : _(L("Standard")));
auto *sel_all = new wxButton(this, wxID_ANY, _(L("All")));
auto *sel_none = new wxButton(this, wxID_ANY, _(L("None")));
auto *sel_all_std = new wxButton(this, wxID_ANY, titles.size() > 1 ? _L("All standard") : _L("Standard"));
auto *sel_all = new wxButton(this, wxID_ANY, _L("All"));
auto *sel_none = new wxButton(this, wxID_ANY, _L("None"));
sel_all_std->Bind(wxEVT_BUTTON, [this](const wxCommandEvent &event) { this->select_all(true, false); });
sel_all->Bind(wxEVT_BUTTON, [this](const wxCommandEvent &event) { this->select_all(true, true); });
sel_none->Bind(wxEVT_BUTTON, [this](const wxCommandEvent &event) { this->select_all(false); });
@ -444,14 +444,14 @@ PageWelcome::PageWelcome(ConfigWizard *parent)
#else
_utf8(L("Welcome to the %s Configuration Wizard"))
#endif
) % SLIC3R_APP_NAME).str()), _(L("Welcome")))
) % SLIC3R_APP_NAME).str()), _L("Welcome"))
, welcome_text(append_text(from_u8((boost::format(
_utf8(L("Hello, welcome to %s! This %s helps you with the initial configuration; just a few settings and you will be ready to print.")))
% SLIC3R_APP_NAME
% _utf8(ConfigWizard::name())).str())
))
, cbox_reset(append(
new wxCheckBox(this, wxID_ANY, _(L("Remove user profiles (a snapshot will be taken beforehand)")))
new wxCheckBox(this, wxID_ANY, _L("Remove user profiles (a snapshot will be taken beforehand)"))
))
{
welcome_text->Hide();
@ -582,10 +582,10 @@ PageMaterials::PageMaterials(ConfigWizard *parent, Materials *materials, wxStrin
grid->AddGrowableCol(3, 1);
grid->AddGrowableRow(1, 1);
grid->Add(new wxStaticText(this, wxID_ANY, _(L("Printer:"))));
grid->Add(new wxStaticText(this, wxID_ANY, _L("Printer:")));
grid->Add(new wxStaticText(this, wxID_ANY, list1name));
grid->Add(new wxStaticText(this, wxID_ANY, _(L("Vendor:"))));
grid->Add(new wxStaticText(this, wxID_ANY, _(L("Profile:"))));
grid->Add(new wxStaticText(this, wxID_ANY, _L("Vendor:")));
grid->Add(new wxStaticText(this, wxID_ANY, _L("Profile:")));
grid->Add(list_printer, 0, wxEXPAND);
grid->Add(list_type, 0, wxEXPAND);
@ -593,8 +593,8 @@ PageMaterials::PageMaterials(ConfigWizard *parent, Materials *materials, wxStrin
grid->Add(list_profile, 1, wxEXPAND);
auto *btn_sizer = new wxBoxSizer(wxHORIZONTAL);
auto *sel_all = new wxButton(this, wxID_ANY, _(L("All")));
auto *sel_none = new wxButton(this, wxID_ANY, _(L("None")));
auto *sel_all = new wxButton(this, wxID_ANY, _L("All"));
auto *sel_none = new wxButton(this, wxID_ANY, _L("None"));
btn_sizer->Add(sel_all, 0, wxRIGHT, em / 2);
btn_sizer->Add(sel_none);
@ -657,7 +657,7 @@ void PageMaterials::reload_presets()
{
clear();
list_printer->append(_(L("(All)")), &EMPTY);
list_printer->append(_L("(All)"), &EMPTY);
//list_printer->SetLabelMarkup("<b>bald</b>");
for (const Preset* printer : materials->printers) {
list_printer->append(printer->name, &printer->name);
@ -686,10 +686,10 @@ void PageMaterials::set_compatible_printers_html_window(const std::vector<std::s
const auto bgr_clr_str = wxString::Format(wxT("#%02X%02X%02X"), bgr_clr.Red(), bgr_clr.Green(), bgr_clr.Blue());
const auto text_clr = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT);
const auto text_clr_str = wxString::Format(wxT("#%02X%02X%02X"), text_clr.Red(), text_clr.Green(), text_clr.Blue());
wxString first_line = _(L("Filaments marked with <b>*</b> are <b>not</b> compatible with some installed printers."));
wxString first_line = _L("Filaments marked with <b>*</b> are <b>not</b> compatible with some installed printers.");
wxString text;
if (all_printers) {
wxString second_line = _(L("All installed printers are compatible with the selected filament."));
wxString second_line = _L("All installed printers are compatible with the selected filament.");
text = wxString::Format(
"<html>"
"<style>"
@ -709,7 +709,7 @@ void PageMaterials::set_compatible_printers_html_window(const std::vector<std::s
, second_line
);
} else {
wxString second_line = _(L("Only the following installed printers are compatible with the selected filament:"));
wxString second_line = _L("Only the following installed printers are compatible with the selected filament:");
text = wxString::Format(
"<html>"
"<style>"
@ -807,7 +807,7 @@ void PageMaterials::update_lists(int sel_printer, int sel_type, int sel_vendor)
if (sel_printers_count != sel_printer_count_prev || (sel_printers_count == 1 && sel_printer_item_prev != sel_printer && sel_printer != -1)) {
// Refresh type list
list_type->Clear();
list_type->append(_(L("(All)")), &EMPTY);
list_type->append(_L("(All)"), &EMPTY);
if (sel_printers_count > 0) {
// If all is selected with other printers
// unselect "all" or all printers depending on last value
@ -868,7 +868,7 @@ void PageMaterials::update_lists(int sel_printer, int sel_type, int sel_vendor)
// but the number of vendors is going to be very small this shouldn't be a problem.
list_vendor->Clear();
list_vendor->append(_(L("(All)")), &EMPTY);
list_vendor->append(_L("(All)"), &EMPTY);
if (sel_printers_count != 0 && sel_type != wxNOT_FOUND) {
const std::string& type = list_type->get_data(sel_type);
// find printer preset
@ -1005,7 +1005,7 @@ void PageMaterials::sort_list_data(StringList* list, bool add_All_item, bool mat
list->Clear();
if (add_All_item)
list->append(_(L("(All)")), &EMPTY);
list->append(_L("(All)"), &EMPTY);
for (const auto& item : prusa_profiles)
list->append(item, &const_cast<std::string&>(item.get()));
for (const auto& item : other_profiles)
@ -1095,11 +1095,11 @@ void PageMaterials::on_activate()
const char *PageCustom::default_profile_name = "My Settings";
PageCustom::PageCustom(ConfigWizard *parent)
: ConfigWizardPage(parent, _(L("Custom Printer Setup")), _(L("Custom Printer")))
: ConfigWizardPage(parent, _L("Custom Printer Setup"), _L("Custom Printer"))
{
cb_custom = new wxCheckBox(this, wxID_ANY, _(L("Define a custom printer profile")));
cb_custom = new wxCheckBox(this, wxID_ANY, _L("Define a custom printer profile"));
tc_profile_name = new wxTextCtrl(this, wxID_ANY, default_profile_name);
auto *label = new wxStaticText(this, wxID_ANY, _(L("Custom profile name:")));
auto *label = new wxStaticText(this, wxID_ANY, _L("Custom profile name:"));
tc_profile_name->Enable(false);
tc_profile_name->Bind(wxEVT_KILL_FOCUS, [this](wxFocusEvent &evt) {
@ -1124,7 +1124,7 @@ PageCustom::PageCustom(ConfigWizard *parent)
}
PageUpdate::PageUpdate(ConfigWizard *parent)
: ConfigWizardPage(parent, _(L("Automatic updates")), _(L("Updates")))
: ConfigWizardPage(parent, _L("Automatic updates"), _L("Updates"))
, version_check(true)
, preset_update(true)
{
@ -1132,60 +1132,76 @@ PageUpdate::PageUpdate(ConfigWizard *parent)
auto boldfont = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
boldfont.SetWeight(wxFONTWEIGHT_BOLD);
auto *box_slic3r = new wxCheckBox(this, wxID_ANY, _(L("Check for application updates")));
auto *box_slic3r = new wxCheckBox(this, wxID_ANY, _L("Check for application updates"));
box_slic3r->SetValue(app_config->get("version_check") == "1");
append(box_slic3r);
append_text(wxString::Format(_(L(
append_text(wxString::Format(_L(
"If enabled, %s checks for new application versions online. When a new version becomes available, "
"a notification is displayed at the next application startup (never during program usage). "
"This is only a notification mechanisms, no automatic installation is done.")), SLIC3R_APP_NAME));
"This is only a notification mechanisms, no automatic installation is done."), SLIC3R_APP_NAME));
append_spacer(VERTICAL_SPACING);
auto *box_presets = new wxCheckBox(this, wxID_ANY, _(L("Update built-in Presets automatically")));
auto *box_presets = new wxCheckBox(this, wxID_ANY, _L("Update built-in Presets automatically"));
box_presets->SetValue(app_config->get("preset_update") == "1");
append(box_presets);
append_text(wxString::Format(_(L(
append_text(wxString::Format(_L(
"If enabled, %s downloads updates of built-in system presets in the background."
"These updates are downloaded into a separate temporary location."
"When a new preset version becomes available it is offered at application startup.")), SLIC3R_APP_NAME));
const auto text_bold = _(L("Updates are never applied without user's consent and never overwrite user's customized settings."));
"When a new preset version becomes available it is offered at application startup."), SLIC3R_APP_NAME));
const auto text_bold = _L("Updates are never applied without user's consent and never overwrite user's customized settings.");
auto *label_bold = new wxStaticText(this, wxID_ANY, text_bold);
label_bold->SetFont(boldfont);
label_bold->Wrap(WRAP_WIDTH);
append(label_bold);
append_text(_(L("Additionally a backup snapshot of the whole configuration is created before an update is applied.")));
append_text(_L("Additionally a backup snapshot of the whole configuration is created before an update is applied."));
box_slic3r->Bind(wxEVT_CHECKBOX, [this](wxCommandEvent &event) { this->version_check = event.IsChecked(); });
box_presets->Bind(wxEVT_CHECKBOX, [this](wxCommandEvent &event) { this->preset_update = event.IsChecked(); });
}
PageReloadFromDisk::PageReloadFromDisk(ConfigWizard* parent)
: ConfigWizardPage(parent, _(L("Reload from disk")), _(L("Reload from disk")))
: ConfigWizardPage(parent, _L("Reload from disk"), _L("Reload from disk"))
, full_pathnames(false)
{
auto* box_pathnames = new wxCheckBox(this, wxID_ANY, _(L("Export full pathnames of models and parts sources into 3mf and amf files")));
auto* box_pathnames = new wxCheckBox(this, wxID_ANY, _L("Export full pathnames of models and parts sources into 3mf and amf files"));
box_pathnames->SetValue(wxGetApp().app_config->get("export_sources_full_pathnames") == "1");
append(box_pathnames);
append_text(_(L(
append_text(_L(
"If enabled, allows the Reload from disk command to automatically find and load the files when invoked.\n"
"If not enabled, the Reload from disk command will ask to select each file using an open file dialog."
)));
));
box_pathnames->Bind(wxEVT_CHECKBOX, [this](wxCommandEvent& event) { this->full_pathnames = event.IsChecked(); });
}
PageMode::PageMode(ConfigWizard *parent)
: ConfigWizardPage(parent, _(L("View mode")), _(L("View mode")))
#if ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN
#ifdef _WIN32
PageFilesAssociation::PageFilesAssociation(ConfigWizard* parent)
: ConfigWizardPage(parent, _L("Files association"), _L("Files association"))
{
append_text(_(L("PrusaSlicer's user interfaces comes in three variants:\nSimple, Advanced, and Expert.\n"
cb_3mf = new wxCheckBox(this, wxID_ANY, _L("Associate .3mf files to PrusaSlicer"));
cb_stl = new wxCheckBox(this, wxID_ANY, _L("Associate .stl files to PrusaSlicer"));
// cb_gcode = new wxCheckBox(this, wxID_ANY, _L("Associate .gcode files to PrusaSlicer G-code Viewer"));
append(cb_3mf);
append(cb_stl);
// append(cb_gcode);
}
#endif // _WIN32
#endif // ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN
PageMode::PageMode(ConfigWizard *parent)
: ConfigWizardPage(parent, _L("View mode"), _L("View mode"))
{
append_text(_L("PrusaSlicer's user interfaces comes in three variants:\nSimple, Advanced, and Expert.\n"
"The Simple mode shows only the most frequently used settings relevant for regular 3D printing. "
"The other two offer progressively more sophisticated fine-tuning, "
"they are suitable for advanced and expert users, respectively.")));
"they are suitable for advanced and expert users, respectively."));
radio_simple = new wxRadioButton(this, wxID_ANY, _(L("Simple mode")));
radio_advanced = new wxRadioButton(this, wxID_ANY, _(L("Advanced mode")));
radio_expert = new wxRadioButton(this, wxID_ANY, _(L("Expert mode")));
radio_simple = new wxRadioButton(this, wxID_ANY, _L("Simple mode"));
radio_advanced = new wxRadioButton(this, wxID_ANY, _L("Advanced mode"));
radio_expert = new wxRadioButton(this, wxID_ANY, _L("Expert mode"));
append(radio_simple);
append(radio_advanced);
@ -1226,11 +1242,11 @@ void PageMode::serialize_mode(AppConfig *app_config) const
}
PageVendors::PageVendors(ConfigWizard *parent)
: ConfigWizardPage(parent, _(L("Other Vendors")), _(L("Other Vendors")))
: ConfigWizardPage(parent, _L("Other Vendors"), _L("Other Vendors"))
{
const AppConfig &appconfig = this->wizard_p()->appconfig_new;
append_text(wxString::Format(_(L("Pick another vendor supported by %s")), SLIC3R_APP_NAME) + ":");
append_text(wxString::Format(_L("Pick another vendor supported by %s"), SLIC3R_APP_NAME) + ":");
auto boldfont = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
boldfont.SetWeight(wxFONTWEIGHT_BOLD);
@ -1261,11 +1277,11 @@ PageVendors::PageVendors(ConfigWizard *parent)
}
PageFirmware::PageFirmware(ConfigWizard *parent)
: ConfigWizardPage(parent, _(L("Firmware Type")), _(L("Firmware")), 1)
: ConfigWizardPage(parent, _L("Firmware Type"), _L("Firmware"), 1)
, gcode_opt(*print_config_def.get("gcode_flavor"))
, gcode_picker(nullptr)
{
append_text(_(L("Choose the type of firmware used by your printer.")));
append_text(_L("Choose the type of firmware used by your printer."));
append_text(_(gcode_opt.tooltip));
wxArrayString choices;
@ -1299,10 +1315,10 @@ void PageFirmware::apply_custom_config(DynamicPrintConfig &config)
}
PageBedShape::PageBedShape(ConfigWizard *parent)
: ConfigWizardPage(parent, _(L("Bed Shape and Size")), _(L("Bed Shape")), 1)
: ConfigWizardPage(parent, _L("Bed Shape and Size"), _L("Bed Shape"), 1)
, shape_panel(new BedShapePanel(this))
{
append_text(_(L("Set the shape of your printer's bed.")));
append_text(_L("Set the shape of your printer's bed."));
shape_panel->build_panel(*wizard_p()->custom_config->option<ConfigOptionPoints>("bed_shape"),
*wizard_p()->custom_config->option<ConfigOptionString>("bed_custom_texture"),
@ -1322,7 +1338,7 @@ void PageBedShape::apply_custom_config(DynamicPrintConfig &config)
}
PageDiameters::PageDiameters(ConfigWizard *parent)
: ConfigWizardPage(parent, _(L("Filament and Nozzle Diameters")), _(L("Print Diameters")), 1)
: ConfigWizardPage(parent, _L("Filament and Nozzle Diameters"), _L("Print Diameters"), 1)
, spin_nozzle(new wxSpinCtrlDouble(this, wxID_ANY))
, spin_filam(new wxSpinCtrlDouble(this, wxID_ANY))
{
@ -1336,11 +1352,11 @@ PageDiameters::PageDiameters(ConfigWizard *parent)
auto *default_filam = print_config_def.get("filament_diameter")->get_default_value<ConfigOptionFloats>();
spin_filam->SetValue(default_filam != nullptr && default_filam->size() > 0 ? default_filam->get_at(0) : 3.0);
append_text(_(L("Enter the diameter of your printer's hot end nozzle.")));
append_text(_L("Enter the diameter of your printer's hot end nozzle."));
auto *sizer_nozzle = new wxFlexGridSizer(3, 5, 5);
auto *text_nozzle = new wxStaticText(this, wxID_ANY, _(L("Nozzle Diameter:")));
auto *unit_nozzle = new wxStaticText(this, wxID_ANY, _(L("mm")));
auto *text_nozzle = new wxStaticText(this, wxID_ANY, _L("Nozzle Diameter:"));
auto *unit_nozzle = new wxStaticText(this, wxID_ANY, _L("mm"));
sizer_nozzle->AddGrowableCol(0, 1);
sizer_nozzle->Add(text_nozzle, 0, wxALIGN_CENTRE_VERTICAL);
sizer_nozzle->Add(spin_nozzle);
@ -1349,12 +1365,12 @@ PageDiameters::PageDiameters(ConfigWizard *parent)
append_spacer(VERTICAL_SPACING);
append_text(_(L("Enter the diameter of your filament.")));
append_text(_(L("Good precision is required, so use a caliper and do multiple measurements along the filament, then compute the average.")));
append_text(_L("Enter the diameter of your filament."));
append_text(_L("Good precision is required, so use a caliper and do multiple measurements along the filament, then compute the average."));
auto *sizer_filam = new wxFlexGridSizer(3, 5, 5);
auto *text_filam = new wxStaticText(this, wxID_ANY, _(L("Filament Diameter:")));
auto *unit_filam = new wxStaticText(this, wxID_ANY, _(L("mm")));
auto *text_filam = new wxStaticText(this, wxID_ANY, _L("Filament Diameter:"));
auto *unit_filam = new wxStaticText(this, wxID_ANY, _L("mm"));
sizer_filam->AddGrowableCol(0, 1);
sizer_filam->Add(text_filam, 0, wxALIGN_CENTRE_VERTICAL);
sizer_filam->Add(spin_filam);
@ -1387,7 +1403,7 @@ void PageDiameters::apply_custom_config(DynamicPrintConfig &config)
}
PageTemperatures::PageTemperatures(ConfigWizard *parent)
: ConfigWizardPage(parent, _(L("Nozzle and Bed Temperatures")), _(L("Temperatures")), 1)
: ConfigWizardPage(parent, _L("Nozzle and Bed Temperatures"), _L("Temperatures"), 1)
, spin_extr(new wxSpinCtrlDouble(this, wxID_ANY))
, spin_bed(new wxSpinCtrlDouble(this, wxID_ANY))
{
@ -1403,12 +1419,12 @@ PageTemperatures::PageTemperatures(ConfigWizard *parent)
auto *default_bed = def_bed.get_default_value<ConfigOptionInts>();
spin_bed->SetValue(default_bed != nullptr && default_bed->size() > 0 ? default_bed->get_at(0) : 0);
append_text(_(L("Enter the temperature needed for extruding your filament.")));
append_text(_(L("A rule of thumb is 160 to 230 °C for PLA, and 215 to 250 °C for ABS.")));
append_text(_L("Enter the temperature needed for extruding your filament."));
append_text(_L("A rule of thumb is 160 to 230 °C for PLA, and 215 to 250 °C for ABS."));
auto *sizer_extr = new wxFlexGridSizer(3, 5, 5);
auto *text_extr = new wxStaticText(this, wxID_ANY, _(L("Extrusion Temperature:")));
auto *unit_extr = new wxStaticText(this, wxID_ANY, _(L("°C")));
auto *text_extr = new wxStaticText(this, wxID_ANY, _L("Extrusion Temperature:"));
auto *unit_extr = new wxStaticText(this, wxID_ANY, _L("°C"));
sizer_extr->AddGrowableCol(0, 1);
sizer_extr->Add(text_extr, 0, wxALIGN_CENTRE_VERTICAL);
sizer_extr->Add(spin_extr);
@ -1417,12 +1433,12 @@ PageTemperatures::PageTemperatures(ConfigWizard *parent)
append_spacer(VERTICAL_SPACING);
append_text(_(L("Enter the bed temperature needed for getting your filament to stick to your heated bed.")));
append_text(_(L("A rule of thumb is 60 °C for PLA and 110 °C for ABS. Leave zero if you have no heated bed.")));
append_text(_L("Enter the bed temperature needed for getting your filament to stick to your heated bed."));
append_text(_L("A rule of thumb is 60 °C for PLA and 110 °C for ABS. Leave zero if you have no heated bed."));
auto *sizer_bed = new wxFlexGridSizer(3, 5, 5);
auto *text_bed = new wxStaticText(this, wxID_ANY, _(L("Bed Temperature:")));
auto *unit_bed = new wxStaticText(this, wxID_ANY, _(L("°C")));
auto *text_bed = new wxStaticText(this, wxID_ANY, _L("Bed Temperature:"));
auto *unit_bed = new wxStaticText(this, wxID_ANY, _L("°C"));
sizer_bed->AddGrowableCol(0, 1);
sizer_bed->Add(text_bed, 0, wxALIGN_CENTRE_VERTICAL);
sizer_bed->Add(spin_bed);
@ -1780,6 +1796,11 @@ void ConfigWizard::priv::load_pages()
index->add_page(page_update);
index->add_page(page_reload_from_disk);
#if ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN
#ifdef _WIN32
index->add_page(page_files_association);
#endif // _WIN32
#endif // ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN
index->add_page(page_mode);
index->go_to(former_active); // Will restore the active item/page if possible
@ -1876,7 +1897,7 @@ void ConfigWizard::priv::load_vendors()
void ConfigWizard::priv::add_page(ConfigWizardPage *page)
{
const int proportion = (page->shortname == _(L("Filaments"))) || (page->shortname == _(L("SLA Materials"))) ? 1 : 0;
const int proportion = (page->shortname == _L("Filaments")) || (page->shortname == _L("SLA Materials")) ? 1 : 0;
hscroll_sizer->Add(page, proportion, wxEXPAND);
all_pages.push_back(page);
}
@ -1930,12 +1951,12 @@ void ConfigWizard::priv::create_3rdparty_pages()
PagePrinters* pageSLA = nullptr;
if (is_fff_technology) {
pageFFF = new PagePrinters(q, vendor->name + " " +_(L("FFF Technology Printers")), vendor->name+" FFF", *vendor, 1, T_FFF);
pageFFF = new PagePrinters(q, vendor->name + " " +_L("FFF Technology Printers"), vendor->name+" FFF", *vendor, 1, T_FFF);
add_page(pageFFF);
}
if (is_sla_technology) {
pageSLA = new PagePrinters(q, vendor->name + " " + _(L("SLA Technology Printers")), vendor->name+" MSLA", *vendor, 1, T_SLA);
pageSLA = new PagePrinters(q, vendor->name + " " + _L("SLA Technology Printers"), vendor->name+" MSLA", *vendor, 1, T_SLA);
add_page(pageSLA);
}
@ -2241,7 +2262,7 @@ bool ConfigWizard::priv::check_and_install_missing_materials(Technology technolo
const auto ask_and_select_default_materials = [this](const wxString &message, const std::set<const VendorProfile::PrinterModel*> &printer_models, Technology technology)
{
wxMessageDialog msg(q, message, _(L("Notice")), wxYES_NO);
wxMessageDialog msg(q, message, _L("Notice"), wxYES_NO);
if (msg.ShowModal() == wxID_YES)
select_default_materials_for_printer_models(technology, printer_models);
};
@ -2372,6 +2393,26 @@ void ConfigWizard::priv::apply_config(AppConfig *app_config, PresetBundle *prese
app_config->set("preset_update", page_update->preset_update ? "1" : "0");
app_config->set("export_sources_full_pathnames", page_reload_from_disk->full_pathnames ? "1" : "0");
#if ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN
#ifdef _WIN32
app_config->set("associate_3mf", page_files_association->associate_3mf() ? "1" : "0");
app_config->set("associate_stl", page_files_association->associate_stl() ? "1" : "0");
// app_config->set("associate_gcode", page_files_association->associate_gcode() ? "1" : "0");
if (wxGetApp().is_editor()) {
if (page_files_association->associate_3mf())
wxGetApp().associate_3mf_files();
if (page_files_association->associate_stl())
wxGetApp().associate_stl_files();
}
// else {
// if (page_files_association->associate_gcode())
// wxGetApp().associate_gcode_files();
// }
#endif // _WIN32
#endif // ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN
page_mode->serialize_mode(app_config);
std::string preferred_model;
@ -2491,13 +2532,13 @@ ConfigWizard::ConfigWizard(wxWindow *parent)
topsizer->AddSpacer(INDEX_MARGIN);
topsizer->Add(p->hscroll, 1, wxEXPAND);
p->btn_sel_all = new wxButton(this, wxID_ANY, _(L("Select all standard printers")));
p->btn_sel_all = new wxButton(this, wxID_ANY, _L("Select all standard printers"));
p->btnsizer->Add(p->btn_sel_all);
p->btn_prev = new wxButton(this, wxID_ANY, _(L("< &Back")));
p->btn_next = new wxButton(this, wxID_ANY, _(L("&Next >")));
p->btn_finish = new wxButton(this, wxID_APPLY, _(L("&Finish")));
p->btn_cancel = new wxButton(this, wxID_CANCEL, _(L("Cancel"))); // Note: The label needs to be present, otherwise we get accelerator bugs on Mac
p->btn_prev = new wxButton(this, wxID_ANY, _L("< &Back"));
p->btn_next = new wxButton(this, wxID_ANY, _L("&Next >"));
p->btn_finish = new wxButton(this, wxID_APPLY, _L("&Finish"));
p->btn_cancel = new wxButton(this, wxID_CANCEL, _L("Cancel")); // Note: The label needs to be present, otherwise we get accelerator bugs on Mac
p->btnsizer->AddStretchSpacer();
p->btnsizer->Add(p->btn_prev, 0, wxLEFT, BTN_SPACING);
p->btnsizer->Add(p->btn_next, 0, wxLEFT, BTN_SPACING);
@ -2510,10 +2551,10 @@ ConfigWizard::ConfigWizard(wxWindow *parent)
p->add_page(p->page_welcome = new PageWelcome(this));
p->page_fff = new PagePrinters(this, _(L("Prusa FFF Technology Printers")), "Prusa FFF", *vendor_prusa, 0, T_FFF);
p->page_fff = new PagePrinters(this, _L("Prusa FFF Technology Printers"), "Prusa FFF", *vendor_prusa, 0, T_FFF);
p->add_page(p->page_fff);
p->page_msla = new PagePrinters(this, _(L("Prusa MSLA Technology Printers")), "Prusa MSLA", *vendor_prusa, 0, T_SLA);
p->page_msla = new PagePrinters(this, _L("Prusa MSLA Technology Printers"), "Prusa MSLA", *vendor_prusa, 0, T_SLA);
p->add_page(p->page_msla);
// Pages for 3rd party vendors
@ -2528,13 +2569,18 @@ ConfigWizard::ConfigWizard(wxWindow *parent)
p->update_materials(T_ANY);
p->add_page(p->page_filaments = new PageMaterials(this, &p->filaments,
_(L("Filament Profiles Selection")), _(L("Filaments")), _(L("Type:")) ));
_L("Filament Profiles Selection"), _L("Filaments"), _L("Type:") ));
p->add_page(p->page_sla_materials = new PageMaterials(this, &p->sla_materials,
_(L("SLA Material Profiles Selection")) + " ", _(L("SLA Materials")), _(L("Type:")) ));
_L("SLA Material Profiles Selection") + " ", _L("SLA Materials"), _L("Type:") ));
p->add_page(p->page_update = new PageUpdate(this));
p->add_page(p->page_reload_from_disk = new PageReloadFromDisk(this));
#if ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN
#ifdef _WIN32
p->add_page(p->page_files_association = new PageFilesAssociation(this));
#endif // _WIN32
#endif // ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN
p->add_page(p->page_mode = new PageMode(this));
p->add_page(p->page_firmware = new PageFirmware(this));
p->add_page(p->page_bed = new PageBedShape(this));

View file

@ -392,6 +392,25 @@ struct PageReloadFromDisk : ConfigWizardPage
PageReloadFromDisk(ConfigWizard* parent);
};
#if ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN
#ifdef _WIN32
struct PageFilesAssociation : ConfigWizardPage
{
private:
wxCheckBox* cb_3mf{ nullptr };
wxCheckBox* cb_stl{ nullptr };
// wxCheckBox* cb_gcode;
public:
PageFilesAssociation(ConfigWizard* parent);
bool associate_3mf() const { return cb_3mf->IsChecked(); }
bool associate_stl() const { return cb_stl->IsChecked(); }
// bool associate_gcode() const { return cb_gcode->IsChecked(); }
};
#endif // _WIN32
#endif // ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN
struct PageMode: ConfigWizardPage
{
wxRadioButton *radio_simple;
@ -550,6 +569,11 @@ struct ConfigWizard::priv
PageCustom *page_custom = nullptr;
PageUpdate *page_update = nullptr;
PageReloadFromDisk *page_reload_from_disk = nullptr;
#if ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN
#ifdef _WIN32
PageFilesAssociation* page_files_association = nullptr;
#endif // _WIN32
#endif // ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN
PageMode *page_mode = nullptr;
PageVendors *page_vendors = nullptr;
Pages3rdparty pages_3rdparty;

View file

@ -804,7 +804,14 @@ bool GUI_App::on_init_inner()
if (is_editor()) {
#ifdef __WXMSW__
associate_3mf_files();
#if ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN
if (app_config->get("associate_3mf") == "1")
#endif // ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN
associate_3mf_files();
#if ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN
if (app_config->get("associate_stl") == "1")
associate_stl_files();
#endif // ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN
#endif // __WXMSW__
preset_updater = new PresetUpdater();
@ -820,7 +827,10 @@ bool GUI_App::on_init_inner()
}
else {
#ifdef __WXMSW__
associate_gcode_files();
#if ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN
if (app_config->get("associate_gcode") == "1")
#endif // ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN
associate_gcode_files();
#endif // __WXMSW__
}
@ -1577,6 +1587,20 @@ void GUI_App::add_config_menu(wxMenuBar *menu)
app_layout_changed = dlg.settings_layout_changed();
if (dlg.seq_top_layer_only_changed())
this->plater_->refresh_print();
#if ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN
#ifdef _WIN32
if (is_editor()) {
if (app_config->get("associate_3mf") == "1")
associate_3mf_files();
if (app_config->get("associate_stl") == "1")
associate_stl_files();
}
else {
if (app_config->get("associate_gcode") == "1")
associate_gcode_files();
}
#endif // _WIN32
#endif // ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN
}
if (app_layout_changed) {
// hide full main_sizer for mainFrame
@ -2112,6 +2136,32 @@ void GUI_App::associate_3mf_files()
::SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, nullptr, nullptr);
}
#if ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN
void GUI_App::associate_stl_files()
{
wchar_t app_path[MAX_PATH];
::GetModuleFileNameW(nullptr, app_path, sizeof(app_path));
std::wstring prog_path = L"\"" + std::wstring(app_path) + L"\"";
std::wstring prog_id = L"Prusa.Slicer.1";
std::wstring prog_desc = L"PrusaSlicer";
std::wstring prog_command = prog_path + L" \"%1\"";
std::wstring reg_base = L"Software\\Classes";
std::wstring reg_extension = reg_base + L"\\.stl";
std::wstring reg_prog_id = reg_base + L"\\" + prog_id;
std::wstring reg_prog_id_command = reg_prog_id + L"\\Shell\\Open\\Command";
bool is_new = false;
is_new |= set_into_win_registry(HKEY_CURRENT_USER, reg_extension.c_str(), prog_id.c_str());
is_new |= set_into_win_registry(HKEY_CURRENT_USER, reg_prog_id.c_str(), prog_desc.c_str());
is_new |= set_into_win_registry(HKEY_CURRENT_USER, reg_prog_id_command.c_str(), prog_command.c_str());
if (is_new)
// notify Windows only when any of the values gets changed
::SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, nullptr, nullptr);
}
#endif // ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN
void GUI_App::associate_gcode_files()
{
wchar_t app_path[MAX_PATH];

View file

@ -274,6 +274,14 @@ public:
bool is_gl_version_greater_or_equal_to(unsigned int major, unsigned int minor) const { return m_opengl_mgr.get_gl_info().is_version_greater_or_equal_to(major, minor); }
bool is_glsl_version_greater_or_equal_to(unsigned int major, unsigned int minor) const { return m_opengl_mgr.get_gl_info().is_glsl_version_greater_or_equal_to(major, minor); }
#if ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN
#ifdef __WXMSW__
void associate_3mf_files();
void associate_stl_files();
void associate_gcode_files();
#endif // __WXMSW__
#endif // ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN
private:
bool on_init_inner();
void init_app_config();
@ -285,11 +293,14 @@ private:
bool config_wizard_startup();
void check_updates(const bool verbose);
#if !ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN
#ifdef __WXMSW__
void associate_3mf_files();
void associate_gcode_files();
#endif // __WXMSW__
#endif // !ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN
};
DECLARE_APP(GUI_App)
} // GUI

View file

@ -85,6 +85,25 @@ void PreferencesDialog::build()
option = Option(def, "export_sources_full_pathnames");
m_optgroup_general->append_single_option_line(option);
#if ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN
#ifdef _WIN32
// Please keep in sync with ConfigWizard
def.label = L("Associate .3mf files to PrusaSlicer");
def.type = coBool;
def.tooltip = L("If enabled, sets PrusaSlicer as default application to open .3mf files.");
def.set_default_value(new ConfigOptionBool(app_config->get("associate_3mf") == "1"));
option = Option(def, "associate_3mf");
m_optgroup_general->append_single_option_line(option);
def.label = L("Associate .stl files to PrusaSlicer");
def.type = coBool;
def.tooltip = L("If enabled, sets PrusaSlicer as default application to open .stl files.");
def.set_default_value(new ConfigOptionBool(app_config->get("associate_stl") == "1"));
option = Option(def, "associate_stl");
m_optgroup_general->append_single_option_line(option);
#endif // _WIN32
#endif // ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN
// Please keep in sync with ConfigWizard
def.label = L("Update built-in Presets automatically");
def.type = coBool;
@ -126,7 +145,44 @@ void PreferencesDialog::build()
def.set_default_value(new ConfigOptionBool{ app_config->has("single_instance") ? app_config->get("single_instance") == "1" : false });
option = Option(def, "single_instance");
m_optgroup_general->append_single_option_line(option);
/* // ysFIXME THis part is temporary commented
// The using of inches is implemented just for object's size and position
def.label = L("Use inches instead of millimeters");
def.type = coBool;
def.tooltip = L("Use inches instead of millimeters for the object's size");
def.set_default_value(new ConfigOptionBool{ app_config->get("use_inches") == "1" });
option = Option(def, "use_inches");
m_optgroup_general->append_single_option_line(option);
*/
def.label = L("Ask for unsaved changes when closing application");
def.type = coBool;
def.tooltip = L("When closing the application, always ask for unsaved changes");
def.set_default_value(new ConfigOptionBool{ app_config->get("default_action_on_close_application") == "none" });
option = Option(def, "default_action_on_close_application");
m_optgroup_general->append_single_option_line(option);
def.label = L("Ask for unsaved changes when selecting new preset");
def.type = coBool;
def.tooltip = L("Always ask for unsaved changes when selecting new preset");
def.set_default_value(new ConfigOptionBool{ app_config->get("default_action_on_select_preset") == "none" });
option = Option(def, "default_action_on_select_preset");
m_optgroup_general->append_single_option_line(option);
}
#if ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN
#ifdef _WIN32
else {
def.label = L("Associate .gcode files to PrusaSlicer G-code Viewer");
def.type = coBool;
def.tooltip = L("If enabled, sets PrusaSlicer G-code Viewer as default application to open .gcode files.");
def.set_default_value(new ConfigOptionBool(app_config->get("associate_gcode") == "1"));
option = Option(def, "associate_gcode");
m_optgroup_general->append_single_option_line(option);
}
#endif // _WIN32
#endif // ENABLE_CUSTOMIZABLE_FILES_ASSOCIATION_ON_WIN
#if __APPLE__
def.label = L("Use Retina resolution for the 3D scene");
@ -137,30 +193,6 @@ void PreferencesDialog::build()
option = Option (def, "use_retina_opengl");
m_optgroup_general->append_single_option_line(option);
#endif
/* // ysFIXME THis part is temporary commented
// The using of inches is implemented just for object's size and position
def.label = L("Use inches instead of millimeters");
def.type = coBool;
def.tooltip = L("Use inches instead of millimeters for the object's size");
def.set_default_value(new ConfigOptionBool{ app_config->get("use_inches") == "1" });
option = Option(def, "use_inches");
m_optgroup_general->append_single_option_line(option);
*/
def.label = L("Ask for unsaved changes when closing application");
def.type = coBool;
def.tooltip = L("When closing the application, always ask for unsaved changes");
def.set_default_value(new ConfigOptionBool{ app_config->get("default_action_on_close_application") == "none" });
option = Option(def, "default_action_on_close_application");
m_optgroup_general->append_single_option_line(option);
def.label = L("Ask for unsaved changes when selecting new preset");
def.type = coBool;
def.tooltip = L("Always ask for unsaved changes when selecting new preset");
def.set_default_value(new ConfigOptionBool{ app_config->get("default_action_on_select_preset") == "none" });
option = Option(def, "default_action_on_select_preset");
m_optgroup_general->append_single_option_line(option);
// Show/Hide splash screen
def.label = L("Show splash screen");
@ -229,6 +261,14 @@ void PreferencesDialog::build()
def.set_default_value(new ConfigOptionBool{ app_config->get("use_custom_toolbar_size") == "1" });
option = Option(def, "use_custom_toolbar_size");
m_optgroup_gui->append_single_option_line(option);
def.label = L("Suppress to open hyperlink in browser");
def.type = coBool;
def.tooltip = L("If enabled, the descriptions of configuration parameters in settings tabs woldn't work as hyperlinks. "
"If disabled, the descriptions of configuration parameters in settings tabs will work as hyperlinks.");
def.set_default_value(new ConfigOptionBool{ app_config->get("suppress_hyperlinks") == "1" });
option = Option(def, "suppress_hyperlinks");
m_optgroup_gui->append_single_option_line(option);
}
def.label = L("Sequential slider applied only to top layer");
@ -239,14 +279,6 @@ void PreferencesDialog::build()
option = Option(def, "seq_top_layer_only");
m_optgroup_gui->append_single_option_line(option);
def.label = L("Suppress to open hyperlink in browser");
def.type = coBool;
def.tooltip = L("If enabled, the descriptions of configuration parameters in settings tabs woldn't work as hyperlinks. "
"If disabled, the descriptions of configuration parameters in settings tabs will work as hyperlinks.");
def.set_default_value(new ConfigOptionBool{ app_config->get("suppress_hyperlinks") == "1" });
option = Option(def, "suppress_hyperlinks");
m_optgroup_gui->append_single_option_line(option);
m_optgroup_gui->activate();
if (is_editor) {