Fix of output file dialog extension template for OSX:
When opening a "Save" file dialog with a default output file name, OSX file dialog strips the provided extension and replaces it with the default extension. This causes issues with a custom file output template, where a non-default file extension is specified. This commit changes the function to generate file dialog templates so that if a default extension is provided, it is emitted as first into the extension template. Fixes Post Processing passes wrong name #7190
This commit is contained in:
parent
3f0bdb5816
commit
e7cc12b2c9
@ -12,6 +12,7 @@
|
|||||||
#include <exception>
|
#include <exception>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <regex>
|
#include <regex>
|
||||||
|
#include <string_view>
|
||||||
#include <boost/algorithm/string/predicate.hpp>
|
#include <boost/algorithm/string/predicate.hpp>
|
||||||
#include <boost/algorithm/string.hpp>
|
#include <boost/algorithm/string.hpp>
|
||||||
#include <boost/format.hpp>
|
#include <boost/format.hpp>
|
||||||
@ -97,6 +98,8 @@
|
|||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
using namespace std::literals;
|
||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
namespace GUI {
|
namespace GUI {
|
||||||
|
|
||||||
@ -471,39 +474,86 @@ static bool run_updater_win()
|
|||||||
}
|
}
|
||||||
#endif //_WIN32
|
#endif //_WIN32
|
||||||
|
|
||||||
|
struct FileWildcards {
|
||||||
|
std::string_view title;
|
||||||
|
std::vector<std::string_view> file_extensions;
|
||||||
|
};
|
||||||
|
|
||||||
|
static const FileWildcards file_wildcards_by_type[FT_SIZE] = {
|
||||||
|
/* FT_STL */ { "STL files"sv, { ".stl"sv } },
|
||||||
|
/* FT_OBJ */ { "OBJ files"sv, { ".obj"sv } },
|
||||||
|
/* FT_AMF */ { "AMF files"sv, { ".amf"sv, ".zip.amf"sv, ".xml"sv } },
|
||||||
|
/* FT_3MF */ { "3MF files"sv, { ".3mf"sv } },
|
||||||
|
/* FT_GCODE */ { "G-code files"sv, { ".gcode"sv, ".gco"sv, ".g"sv, ".ngc"sv } },
|
||||||
|
/* FT_MODEL */ { "Known files"sv, { ".stl"sv, ".obj"sv, ".3mf"sv, ".amf"sv, ".zip.amf"sv, ".xml"sv } },
|
||||||
|
/* FT_PROJECT */ { "Project files"sv, { ".3mf"sv, ".amf"sv, ".zip.amf"sv } },
|
||||||
|
/* FT_GALLERY */ { "Known files"sv, { ".stl"sv, ".obj"sv } },
|
||||||
|
|
||||||
|
/* FT_INI */ { "INI files"sv, { ".ini"sv } },
|
||||||
|
/* FT_SVG */ { "SVG files"sv, { ".svg"sv } },
|
||||||
|
|
||||||
|
/* FT_TEX */ { "Texture"sv, { ".png"sv, ".svg"sv } },
|
||||||
|
|
||||||
|
/* FT_SL1 */ { "Masked SLA files"sv, { ".sl1"sv, ".sl1s"sv } },
|
||||||
|
};
|
||||||
|
|
||||||
|
// This function produces a Win32 file dialog file template mask to be consumed by wxWidgets on all platforms.
|
||||||
|
// The function accepts a custom extension parameter. If the parameter is provided, the custom extension
|
||||||
|
// will be added as a fist to the list. This is important for a "file save" dialog on OSX, which strips
|
||||||
|
// an extension from the provided initial file name and substitutes it with the default extension (the first one in the template).
|
||||||
wxString file_wildcards(FileType file_type, const std::string &custom_extension)
|
wxString file_wildcards(FileType file_type, const std::string &custom_extension)
|
||||||
{
|
{
|
||||||
static const std::string defaults[FT_SIZE] = {
|
const FileWildcards data = file_wildcards_by_type[file_type];
|
||||||
/* FT_STL */ "STL files (*.stl)|*.stl;*.STL",
|
std::string title;
|
||||||
/* FT_OBJ */ "OBJ files (*.obj)|*.obj;*.OBJ",
|
std::string mask;
|
||||||
/* FT_AMF */ "AMF files (*.amf)|*.zip.amf;*.amf;*.AMF;*.xml;*.XML",
|
std::string custom_ext_lower;
|
||||||
/* FT_3MF */ "3MF files (*.3mf)|*.3mf;*.3MF;",
|
|
||||||
/* FT_GCODE */ "G-code files (*.gcode, *.gco, *.g, *.ngc)|*.gcode;*.GCODE;*.gco;*.GCO;*.g;*.G;*.ngc;*.NGC",
|
|
||||||
/* FT_MODEL */ "Known files (*.stl, *.obj, *.amf, *.xml, *.3mf, *.prusa)|*.stl;*.STL;*.obj;*.OBJ;*.amf;*.AMF;*.xml;*.XML;*.3mf;*.3MF",
|
|
||||||
/* FT_PROJECT */ "Project files (*.3mf, *.amf)|*.3mf;*.3MF;*.amf;*.AMF",
|
|
||||||
/* FT_GALLERY */ "Known files (*.stl, *.obj)|*.stl;*.STL;*.obj;*.OBJ",
|
|
||||||
|
|
||||||
/* FT_INI */ "INI files (*.ini)|*.ini;*.INI",
|
|
||||||
/* FT_SVG */ "SVG files (*.svg)|*.svg;*.SVG",
|
|
||||||
|
|
||||||
/* FT_TEX */ "Texture (*.png, *.svg)|*.png;*.PNG;*.svg;*.SVG",
|
|
||||||
|
|
||||||
/* FT_SL1 */ "Masked SLA files (*.sl1, *.sl1s)|*.sl1;*.SL1;*.sl1s;*.SL1S",
|
|
||||||
// Workaround for OSX file picker, for some reason it always saves with the 1st extension.
|
|
||||||
/* FT_SL1S */ "Masked SLA files (*.sl1s, *.sl1)|*.sl1s;*.SL1S;*.sl1;*.SL1",
|
|
||||||
};
|
|
||||||
|
|
||||||
std::string out = defaults[file_type];
|
|
||||||
if (! custom_extension.empty()) {
|
if (! custom_extension.empty()) {
|
||||||
// Find the custom extension in the template.
|
// Generate an extension into the title mask and into the list of extensions.
|
||||||
if (out.find(std::string("*") + custom_extension + ",") == std::string::npos && out.find(std::string("*") + custom_extension + ")") == std::string::npos) {
|
custom_ext_lower = custom_extension;
|
||||||
// The custom extension was not found in the template.
|
boost::to_lower(custom_ext_lower);
|
||||||
// Append the custom extension to the wildcards, so that the file dialog would not add the default extension to it.
|
std::string custom_ext_upper = custom_extension;
|
||||||
boost::replace_first(out, ")|", std::string(", *") + custom_extension + ")|");
|
boost::to_upper(custom_ext_upper);
|
||||||
out += std::string(";*") + custom_extension;
|
if (custom_ext_lower == custom_extension) {
|
||||||
|
// Add a lower case version.
|
||||||
|
title = std::string("*") + custom_ext_lower;
|
||||||
|
mask = title;
|
||||||
|
// Add an upper case version.
|
||||||
|
mask += ";*";
|
||||||
|
mask += custom_ext_upper;
|
||||||
|
} else if (custom_ext_upper == custom_extension) {
|
||||||
|
// Add an upper case version.
|
||||||
|
title = std::string("*") + custom_ext_upper;
|
||||||
|
mask = title;
|
||||||
|
// Add a lower case version.
|
||||||
|
mask += ";*";
|
||||||
|
mask += custom_ext_lower;
|
||||||
|
} else {
|
||||||
|
// Add the mixed case version only.
|
||||||
|
title = std::string("*") + custom_extension;
|
||||||
|
mask = title;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return from_u8(out);
|
|
||||||
|
for (const std::string_view ext : data.file_extensions)
|
||||||
|
// Only add an extension if it was not added first as the custom extension.
|
||||||
|
if (ext != custom_ext_lower) {
|
||||||
|
if (title.empty()) {
|
||||||
|
title = "*";
|
||||||
|
title += ext;
|
||||||
|
mask = title;
|
||||||
|
} else {
|
||||||
|
title += ", *";
|
||||||
|
title += ext;
|
||||||
|
mask += ";*";
|
||||||
|
mask += ext;
|
||||||
|
}
|
||||||
|
mask += ";*";
|
||||||
|
std::string ext_upper{ ext };
|
||||||
|
boost::to_upper(ext_upper);
|
||||||
|
mask += ext_upper;
|
||||||
|
}
|
||||||
|
return GUI::format("%s (%s)|%s", data.title, title, mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string libslic3r_translate_callback(const char *s) { return wxGetTranslation(wxString(s, wxConvUTF8)).utf8_str().data(); }
|
static std::string libslic3r_translate_callback(const char *s) { return wxGetTranslation(wxString(s, wxConvUTF8)).utf8_str().data(); }
|
||||||
|
@ -66,13 +66,11 @@ enum FileType
|
|||||||
FT_TEX,
|
FT_TEX,
|
||||||
|
|
||||||
FT_SL1,
|
FT_SL1,
|
||||||
// Workaround for OSX file picker, for some reason it always saves with the 1st extension.
|
|
||||||
FT_SL1S,
|
|
||||||
|
|
||||||
FT_SIZE,
|
FT_SIZE,
|
||||||
};
|
};
|
||||||
|
|
||||||
extern wxString file_wildcards(FileType file_type, const std::string &custom_extension = std::string());
|
extern wxString file_wildcards(FileType file_type, const std::string &custom_extension = std::string{});
|
||||||
|
|
||||||
enum ConfigMenuIDs {
|
enum ConfigMenuIDs {
|
||||||
ConfigMenuWizard,
|
ConfigMenuWizard,
|
||||||
|
@ -5721,7 +5721,7 @@ void Plater::export_gcode(bool prefer_removable)
|
|||||||
wxFileDialog dlg(this, (printer_technology() == ptFFF) ? _L("Save G-code file as:") : _L("Save SL1 / SL1S file as:"),
|
wxFileDialog dlg(this, (printer_technology() == ptFFF) ? _L("Save G-code file as:") : _L("Save SL1 / SL1S file as:"),
|
||||||
start_dir,
|
start_dir,
|
||||||
from_path(default_output_file.filename()),
|
from_path(default_output_file.filename()),
|
||||||
GUI::file_wildcards((printer_technology() == ptFFF) ? FT_GCODE : boost::iequals(ext, ".sl1s") ? FT_SL1S : FT_SL1, ext),
|
GUI::file_wildcards((printer_technology() == ptFFF) ? FT_GCODE : FT_SL1, ext),
|
||||||
wxFD_SAVE | wxFD_OVERWRITE_PROMPT
|
wxFD_SAVE | wxFD_OVERWRITE_PROMPT
|
||||||
);
|
);
|
||||||
if (dlg.ShowModal() == wxID_OK) {
|
if (dlg.ShowModal() == wxID_OK) {
|
||||||
|
Loading…
Reference in New Issue
Block a user