Refactor file filters to not use preprocessor magic.
The immediate reason for refactoring this was that the GTK port broke
after 52af7256
since config.h is not included anymore, but it was
a fragile piece of code I will shed no tears for.
While we're at it, get rid of the mutable std::string &file to be
consistent with our conventions.
pull/4/head
parent
52af725606
commit
e61bac2797
|
@ -732,21 +732,20 @@ bool MenuBarIsVisible(void) {
|
||||||
|
|
||||||
/* Save/load */
|
/* Save/load */
|
||||||
|
|
||||||
bool SolveSpace::GetOpenFile(std::string &file, const std::string &defExtension,
|
bool SolveSpace::GetOpenFile(std::string *file, const std::string &defExtension,
|
||||||
const char *selPattern) {
|
const FileFilter ssFilters[]) {
|
||||||
NSOpenPanel *panel = [NSOpenPanel openPanel];
|
NSOpenPanel *panel = [NSOpenPanel openPanel];
|
||||||
NSMutableArray *filters = [[NSMutableArray alloc] init];
|
NSMutableArray *filters = [[NSMutableArray alloc] init];
|
||||||
for(NSString *filter in [[NSString stringWithUTF8String:selPattern]
|
for(const FileFilter *ssFilter = ssFilters; ssFilter->name; ssFilter++) {
|
||||||
componentsSeparatedByString:@"\n"]) {
|
for(const char *const *ssPattern = ssFilter->patterns; *ssPattern; ssPattern++) {
|
||||||
[filters addObjectsFromArray:
|
[filters addObject:[NSString stringWithUTF8String:*ssPattern]];
|
||||||
[[[filter componentsSeparatedByString:@"\t"] objectAtIndex:1]
|
}
|
||||||
componentsSeparatedByString:@","]];
|
|
||||||
}
|
}
|
||||||
[filters removeObjectIdenticalTo:@"*"];
|
[filters removeObjectIdenticalTo:@"*"];
|
||||||
[panel setAllowedFileTypes:filters];
|
[panel setAllowedFileTypes:filters];
|
||||||
|
|
||||||
if([panel runModal] == NSFileHandlingPanelOKButton) {
|
if([panel runModal] == NSFileHandlingPanelOKButton) {
|
||||||
file = [[NSFileManager defaultManager]
|
*file = [[NSFileManager defaultManager]
|
||||||
fileSystemRepresentationWithPath:[[panel URL] path]];
|
fileSystemRepresentationWithPath:[[panel URL] path]];
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
|
@ -774,8 +773,8 @@ bool SolveSpace::GetOpenFile(std::string &file, const std::string &defExtension,
|
||||||
}
|
}
|
||||||
@end
|
@end
|
||||||
|
|
||||||
bool SolveSpace::GetSaveFile(std::string &file, const std::string &defExtension,
|
bool SolveSpace::GetSaveFile(std::string *file, const std::string &defExtension,
|
||||||
const char *selPattern) {
|
const FileFilter ssFilters[]) {
|
||||||
NSSavePanel *panel = [NSSavePanel savePanel];
|
NSSavePanel *panel = [NSSavePanel savePanel];
|
||||||
|
|
||||||
SaveFormatController *controller =
|
SaveFormatController *controller =
|
||||||
|
@ -788,16 +787,19 @@ bool SolveSpace::GetSaveFile(std::string &file, const std::string &defExtension,
|
||||||
|
|
||||||
NSPopUpButton *button = [controller button];
|
NSPopUpButton *button = [controller button];
|
||||||
[button removeAllItems];
|
[button removeAllItems];
|
||||||
for(NSString *filter in [[NSString stringWithUTF8String:selPattern]
|
for(const FileFilter *ssFilter = ssFilters; ssFilter->name; ssFilter++) {
|
||||||
componentsSeparatedByString:@"\n"]) {
|
std::string desc;
|
||||||
NSArray *filterParts = [filter componentsSeparatedByString:@"\t"];
|
for(const char *const *ssPattern = ssFilter->patterns; *ssPattern; ssPattern++) {
|
||||||
NSString *filterName = [filterParts objectAtIndex:0];
|
if(desc == "") {
|
||||||
NSArray *filterExtensions = [[filterParts objectAtIndex:1]
|
desc = *ssPattern;
|
||||||
componentsSeparatedByString:@","];
|
} else {
|
||||||
[button addItemWithTitle:
|
desc += ", ";
|
||||||
[[NSString alloc] initWithFormat:@"%@ (%@)", filterName,
|
desc += *ssPattern;
|
||||||
[filterExtensions componentsJoinedByString:@", "]]];
|
}
|
||||||
[extensions addObject:[filterExtensions objectAtIndex:0]];
|
}
|
||||||
|
std::string title = std::string(ssFilter->name) + " (" + desc + ")";
|
||||||
|
[button addItemWithTitle:[NSString stringWithUTF8String:title.c_str()]];
|
||||||
|
[extensions addObject:[NSString stringWithUTF8String:ssFilter->patterns[0]]];
|
||||||
}
|
}
|
||||||
|
|
||||||
int extensionIndex = 0;
|
int extensionIndex = 0;
|
||||||
|
@ -811,7 +813,7 @@ bool SolveSpace::GetSaveFile(std::string &file, const std::string &defExtension,
|
||||||
stringByAppendingPathExtension:[extensions objectAtIndex:extensionIndex]]];
|
stringByAppendingPathExtension:[extensions objectAtIndex:extensionIndex]]];
|
||||||
|
|
||||||
if([panel runModal] == NSFileHandlingPanelOKButton) {
|
if([panel runModal] == NSFileHandlingPanelOKButton) {
|
||||||
file = [[NSFileManager defaultManager]
|
*file = [[NSFileManager defaultManager]
|
||||||
fileSystemRepresentationWithPath:[[panel URL] path]];
|
fileSystemRepresentationWithPath:[[panel URL] path]];
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -842,7 +842,7 @@ try_load_file:
|
||||||
switch(LocateImportedFileYesNoCancel(g->impFileRel, canCancel)) {
|
switch(LocateImportedFileYesNoCancel(g->impFileRel, canCancel)) {
|
||||||
case DIALOG_YES: {
|
case DIALOG_YES: {
|
||||||
std::string oldImpFile = g->impFile;
|
std::string oldImpFile = g->impFile;
|
||||||
if(!GetOpenFile(g->impFile, "", SLVS_PATTERN)) {
|
if(!GetOpenFile(&g->impFile, "", SlvsFileFilter)) {
|
||||||
if(canCancel)
|
if(canCancel)
|
||||||
return false;
|
return false;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -188,7 +188,7 @@ void Group::MenuGroup(int id) {
|
||||||
case GraphicsWindow::MNU_GROUP_IMPORT: {
|
case GraphicsWindow::MNU_GROUP_IMPORT: {
|
||||||
g.type = IMPORTED;
|
g.type = IMPORTED;
|
||||||
if(g.impFile.empty()) {
|
if(g.impFile.empty()) {
|
||||||
if(!GetOpenFile(g.impFile, "", SLVS_PATTERN)) return;
|
if(!GetOpenFile(&g.impFile, "", SlvsFileFilter)) return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assign the default name of the group based on the name of
|
// Assign the default name of the group based on the name of
|
||||||
|
|
|
@ -1058,77 +1058,53 @@ void RefreshRecentMenus(void) {
|
||||||
|
|
||||||
/* Save/load */
|
/* Save/load */
|
||||||
|
|
||||||
static std::string FiltersFromPattern(const std::string &active, const char *patterns,
|
static std::string ConvertFilters(std::string active, const FileFilter ssFilters[],
|
||||||
Gtk::FileChooser &chooser) {
|
Gtk::FileChooser *chooser) {
|
||||||
Glib::ustring uactive = active;
|
for(const FileFilter *ssFilter = ssFilters; ssFilter->name; ssFilter++) {
|
||||||
Glib::ustring upatterns = patterns;
|
|
||||||
|
|
||||||
#ifdef HAVE_GTK3
|
#ifdef HAVE_GTK3
|
||||||
Glib::RefPtr<Gtk::FileFilter> filter = Gtk::FileFilter::create();
|
Glib::RefPtr<Gtk::FileFilter> filter = Gtk::FileFilter::create();
|
||||||
#else
|
#else
|
||||||
Gtk::FileFilter *filter = new Gtk::FileFilter;
|
Gtk::FileFilter *filter = new Gtk::FileFilter;
|
||||||
#endif
|
#endif
|
||||||
Glib::ustring desc = "";
|
filter->set_name(ssFilter->name);
|
||||||
bool has_name = false, is_active = false;
|
|
||||||
int last = 0;
|
|
||||||
for(int i = 0; i <= upatterns.length(); i++) {
|
|
||||||
if(upatterns[i] == '\t' || upatterns[i] == '\n' || upatterns[i] == '\0') {
|
|
||||||
Glib::ustring frag = upatterns.substr(last, i - last);
|
|
||||||
if(!has_name) {
|
|
||||||
filter->set_name(frag);
|
|
||||||
has_name = true;
|
|
||||||
} else {
|
|
||||||
filter->add_pattern(frag);
|
|
||||||
if(uactive == "")
|
|
||||||
uactive = frag.substr(2);
|
|
||||||
if("*." + uactive == frag)
|
|
||||||
is_active = true;
|
|
||||||
if(desc == "")
|
|
||||||
desc = frag;
|
|
||||||
else
|
|
||||||
desc += ", " + frag;
|
|
||||||
}
|
|
||||||
} else continue;
|
|
||||||
|
|
||||||
if(upatterns[i] == '\n' || upatterns[i] == '\0') {
|
bool is_active = false;
|
||||||
filter->set_name(filter->get_name() + " (" + desc + ")");
|
std::string desc = "";
|
||||||
#ifdef HAVE_GTK3
|
for(const char *const *ssPattern = ssFilter->patterns; *ssPattern; ssPattern++) {
|
||||||
chooser.add_filter(filter);
|
std::string pattern = "*." + std::string(*ssPattern);
|
||||||
if(is_active)
|
filter->add_pattern(pattern);
|
||||||
chooser.set_filter(filter);
|
if(active == "")
|
||||||
|
active = pattern.substr(2);
|
||||||
filter = Gtk::FileFilter::create();
|
if("*." + active == pattern)
|
||||||
#else
|
is_active = true;
|
||||||
chooser.add_filter(*filter);
|
if(desc == "")
|
||||||
if(is_active)
|
desc = pattern;
|
||||||
chooser.set_filter(*filter);
|
else
|
||||||
|
desc += ", " + pattern;
|
||||||
filter = new Gtk::FileFilter();
|
|
||||||
#endif
|
|
||||||
has_name = false;
|
|
||||||
is_active = false;
|
|
||||||
desc = "";
|
|
||||||
}
|
}
|
||||||
|
filter->set_name(filter->get_name() + " (" + desc + ")");
|
||||||
|
|
||||||
last = i + 1;
|
chooser->add_filter(*filter);
|
||||||
|
if(is_active)
|
||||||
|
chooser->set_filter(*filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
return uactive;
|
return active;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GetOpenFile(std::string &file, const std::string &activeOrEmpty,
|
bool GetOpenFile(std::string *filename, const std::string &activeOrEmpty,
|
||||||
const char *patterns) {
|
const FileFilter filters[]) {
|
||||||
Gtk::FileChooserDialog chooser(*GW, "SolveSpace - Open File");
|
Gtk::FileChooserDialog chooser(*GW, "SolveSpace - Open File");
|
||||||
chooser.set_filename(file);
|
chooser.set_filename(*filename);
|
||||||
chooser.add_button("_Cancel", Gtk::RESPONSE_CANCEL);
|
chooser.add_button("_Cancel", Gtk::RESPONSE_CANCEL);
|
||||||
chooser.add_button("_Open", Gtk::RESPONSE_OK);
|
chooser.add_button("_Open", Gtk::RESPONSE_OK);
|
||||||
chooser.set_current_folder(CnfThawString("", "FileChooserPath"));
|
chooser.set_current_folder(CnfThawString("", "FileChooserPath"));
|
||||||
|
|
||||||
FiltersFromPattern(activeOrEmpty, patterns, chooser);
|
ConvertFilters(activeOrEmpty, filters, &chooser);
|
||||||
|
|
||||||
if(chooser.run() == Gtk::RESPONSE_OK) {
|
if(chooser.run() == Gtk::RESPONSE_OK) {
|
||||||
CnfFreezeString(chooser.get_current_folder(), "FileChooserPath");
|
CnfFreezeString(chooser.get_current_folder(), "FileChooserPath");
|
||||||
file = chooser.get_filename();
|
*filename = chooser.get_filename();
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
|
@ -1173,15 +1149,15 @@ static void ChooserFilterChanged(Gtk::FileChooserDialog *chooser)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GetSaveFile(std::string &file, const std::string &activeOrEmpty,
|
bool GetSaveFile(std::string *filename, const std::string &activeOrEmpty,
|
||||||
const char *patterns) {
|
const FileFilter filters[]) {
|
||||||
Gtk::FileChooserDialog chooser(*GW, "SolveSpace - Save File",
|
Gtk::FileChooserDialog chooser(*GW, "SolveSpace - Save File",
|
||||||
Gtk::FILE_CHOOSER_ACTION_SAVE);
|
Gtk::FILE_CHOOSER_ACTION_SAVE);
|
||||||
chooser.set_do_overwrite_confirmation(true);
|
chooser.set_do_overwrite_confirmation(true);
|
||||||
chooser.add_button("_Cancel", Gtk::RESPONSE_CANCEL);
|
chooser.add_button("_Cancel", Gtk::RESPONSE_CANCEL);
|
||||||
chooser.add_button("_Save", Gtk::RESPONSE_OK);
|
chooser.add_button("_Save", Gtk::RESPONSE_OK);
|
||||||
|
|
||||||
std::string active = FiltersFromPattern(activeOrEmpty, patterns, chooser);
|
std::string active = ConvertFilters(activeOrEmpty, filters, &chooser);
|
||||||
|
|
||||||
chooser.set_current_folder(CnfThawString("", "FileChooserPath"));
|
chooser.set_current_folder(CnfThawString("", "FileChooserPath"));
|
||||||
chooser.set_current_name(std::string("untitled.") + active);
|
chooser.set_current_name(std::string("untitled.") + active);
|
||||||
|
@ -1193,7 +1169,7 @@ bool GetSaveFile(std::string &file, const std::string &activeOrEmpty,
|
||||||
|
|
||||||
if(chooser.run() == Gtk::RESPONSE_OK) {
|
if(chooser.run() == Gtk::RESPONSE_OK) {
|
||||||
CnfFreezeString(chooser.get_current_folder(), "FileChooserPath");
|
CnfFreezeString(chooser.get_current_folder(), "FileChooserPath");
|
||||||
file = chooser.get_filename();
|
*filename = chooser.get_filename();
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -374,7 +374,7 @@ bool SolveSpaceUI::GetFilenameAndSave(bool saveAs) {
|
||||||
std::string prevSaveFile = saveFile;
|
std::string prevSaveFile = saveFile;
|
||||||
|
|
||||||
if(saveAs || saveFile.empty()) {
|
if(saveAs || saveFile.empty()) {
|
||||||
if(!GetSaveFile(saveFile, "", SLVS_PATTERN)) return false;
|
if(!GetSaveFile(&saveFile, "", SlvsFileFilter)) return false;
|
||||||
// need to get new filename directly into saveFile, since that
|
// need to get new filename directly into saveFile, since that
|
||||||
// determines impFileRel path
|
// determines impFileRel path
|
||||||
}
|
}
|
||||||
|
@ -457,7 +457,7 @@ void SolveSpaceUI::MenuFile(int id) {
|
||||||
if(!SS.OkayToStartNewFile()) break;
|
if(!SS.OkayToStartNewFile()) break;
|
||||||
|
|
||||||
std::string newFile;
|
std::string newFile;
|
||||||
if(GetOpenFile(newFile, "", SLVS_PATTERN)) {
|
if(GetOpenFile(&newFile, "", SlvsFileFilter)) {
|
||||||
SS.OpenFile(newFile);
|
SS.OpenFile(newFile);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -473,15 +473,15 @@ void SolveSpaceUI::MenuFile(int id) {
|
||||||
|
|
||||||
case GraphicsWindow::MNU_EXPORT_PNG: {
|
case GraphicsWindow::MNU_EXPORT_PNG: {
|
||||||
std::string exportFile;
|
std::string exportFile;
|
||||||
if(!GetSaveFile(exportFile, "", PNG_PATTERN)) break;
|
if(!GetSaveFile(&exportFile, "", PngFileFilter)) break;
|
||||||
SS.ExportAsPngTo(exportFile);
|
SS.ExportAsPngTo(exportFile);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case GraphicsWindow::MNU_EXPORT_VIEW: {
|
case GraphicsWindow::MNU_EXPORT_VIEW: {
|
||||||
std::string exportFile;
|
std::string exportFile;
|
||||||
if(!GetSaveFile(exportFile, CnfThawString("", "ViewExportFormat"),
|
if(!GetSaveFile(&exportFile, CnfThawString("", "ViewExportFormat"),
|
||||||
VEC_PATTERN)) break;
|
VectorFileFilter)) break;
|
||||||
CnfFreezeString(Extension(exportFile), "ViewExportFormat");
|
CnfFreezeString(Extension(exportFile), "ViewExportFormat");
|
||||||
|
|
||||||
// If the user is exporting something where it would be
|
// If the user is exporting something where it would be
|
||||||
|
@ -502,8 +502,8 @@ void SolveSpaceUI::MenuFile(int id) {
|
||||||
|
|
||||||
case GraphicsWindow::MNU_EXPORT_WIREFRAME: {
|
case GraphicsWindow::MNU_EXPORT_WIREFRAME: {
|
||||||
std::string exportFile;
|
std::string exportFile;
|
||||||
if(!GetSaveFile(exportFile, CnfThawString("", "WireframeExportFormat"),
|
if(!GetSaveFile(&exportFile, CnfThawString("", "WireframeExportFormat"),
|
||||||
V3D_PATTERN)) break;
|
Vector3dFileFilter)) break;
|
||||||
CnfFreezeString(Extension(exportFile), "WireframeExportFormat");
|
CnfFreezeString(Extension(exportFile), "WireframeExportFormat");
|
||||||
|
|
||||||
SS.ExportViewOrWireframeTo(exportFile, true);
|
SS.ExportViewOrWireframeTo(exportFile, true);
|
||||||
|
@ -512,8 +512,8 @@ void SolveSpaceUI::MenuFile(int id) {
|
||||||
|
|
||||||
case GraphicsWindow::MNU_EXPORT_SECTION: {
|
case GraphicsWindow::MNU_EXPORT_SECTION: {
|
||||||
std::string exportFile;
|
std::string exportFile;
|
||||||
if(!GetSaveFile(exportFile, CnfThawString("", "SectionExportFormat"),
|
if(!GetSaveFile(&exportFile, CnfThawString("", "SectionExportFormat"),
|
||||||
VEC_PATTERN)) break;
|
VectorFileFilter)) break;
|
||||||
CnfFreezeString(Extension(exportFile), "SectionExportFormat");
|
CnfFreezeString(Extension(exportFile), "SectionExportFormat");
|
||||||
|
|
||||||
SS.ExportSectionTo(exportFile);
|
SS.ExportSectionTo(exportFile);
|
||||||
|
@ -522,8 +522,8 @@ void SolveSpaceUI::MenuFile(int id) {
|
||||||
|
|
||||||
case GraphicsWindow::MNU_EXPORT_MESH: {
|
case GraphicsWindow::MNU_EXPORT_MESH: {
|
||||||
std::string exportFile;
|
std::string exportFile;
|
||||||
if(!GetSaveFile(exportFile, CnfThawString("", "MeshExportFormat"),
|
if(!GetSaveFile(&exportFile, CnfThawString("", "MeshExportFormat"),
|
||||||
MESH_PATTERN)) break;
|
MeshFileFilter)) break;
|
||||||
CnfFreezeString(Extension(exportFile), "MeshExportFormat");
|
CnfFreezeString(Extension(exportFile), "MeshExportFormat");
|
||||||
|
|
||||||
SS.ExportMeshTo(exportFile);
|
SS.ExportMeshTo(exportFile);
|
||||||
|
@ -532,8 +532,8 @@ void SolveSpaceUI::MenuFile(int id) {
|
||||||
|
|
||||||
case GraphicsWindow::MNU_EXPORT_SURFACES: {
|
case GraphicsWindow::MNU_EXPORT_SURFACES: {
|
||||||
std::string exportFile;
|
std::string exportFile;
|
||||||
if(!GetSaveFile(exportFile, CnfThawString("", "SurfacesExportFormat"),
|
if(!GetSaveFile(&exportFile, CnfThawString("", "SurfacesExportFormat"),
|
||||||
SRF_PATTERN)) break;
|
SurfaceFileFilter)) break;
|
||||||
CnfFreezeString(Extension(exportFile), "SurfacesExportFormat");
|
CnfFreezeString(Extension(exportFile), "SurfacesExportFormat");
|
||||||
|
|
||||||
StepFileWriter sfw = {};
|
StepFileWriter sfw = {};
|
||||||
|
@ -750,7 +750,7 @@ void SolveSpaceUI::MenuAnalyze(int id) {
|
||||||
|
|
||||||
case GraphicsWindow::MNU_STOP_TRACING: {
|
case GraphicsWindow::MNU_STOP_TRACING: {
|
||||||
std::string exportFile;
|
std::string exportFile;
|
||||||
if(GetSaveFile(exportFile, "", CSV_PATTERN)) {
|
if(GetSaveFile(&exportFile, "", CsvFileFilter)) {
|
||||||
FILE *f = ssfopen(exportFile, "wb");
|
FILE *f = ssfopen(exportFile, "wb");
|
||||||
if(f) {
|
if(f) {
|
||||||
int i;
|
int i;
|
||||||
|
|
100
src/solvespace.h
100
src/solvespace.h
|
@ -150,69 +150,61 @@ DialogChoice LocateImportedFileYesNoCancel(const std::string &filename,
|
||||||
|
|
||||||
#define AUTOSAVE_SUFFIX "~"
|
#define AUTOSAVE_SUFFIX "~"
|
||||||
|
|
||||||
#if defined(HAVE_GTK)
|
struct FileFilter {
|
||||||
// Selection pattern format to be parsed by GTK3 glue code:
|
const char *name;
|
||||||
// "PNG File\t*.png\n"
|
const char *patterns[3];
|
||||||
// "JPEG File\t*.jpg\t*.jpeg\n"
|
};
|
||||||
// "All Files\t*"
|
|
||||||
# define PAT1(desc,e1) desc "\t*." e1 "\n"
|
|
||||||
# define PAT2(desc,e1,e2) desc "\t*." e1 "\t*." e2 "\n"
|
|
||||||
# define ENDPAT "All Files\t*"
|
|
||||||
#elif defined(__APPLE__)
|
|
||||||
// Selection pattern format to be parsed by Cocoa glue code:
|
|
||||||
// "PNG File\tpng\n"
|
|
||||||
// "JPEG file\tjpg,jpeg\n"
|
|
||||||
// "All Files\t*"
|
|
||||||
# define PAT1(desc,e1) desc "\t" e1 "\n"
|
|
||||||
# define PAT2(desc,e1,e2) desc "\t" e1 "," e2 "\n"
|
|
||||||
# define ENDPAT "All Files\t*"
|
|
||||||
#else
|
|
||||||
// Selection pattern format for Win32's OPENFILENAME.lpstrFilter:
|
|
||||||
// "PNG File (*.png)\0*.png\0"
|
|
||||||
// "JPEG File (*.jpg;*.jpeg)\0*.jpg;*.jpeg\0"
|
|
||||||
// "All Files (*)\0*\0\0"
|
|
||||||
# define PAT1(desc,e1) desc " (*." e1 ")\0*." e1 "\0"
|
|
||||||
# define PAT2(desc,e1,e2) desc " (*." e1 ";*." e2 ")\0*." e1 ";*." e2 "\0"
|
|
||||||
# define ENDPAT "All Files (*)\0*\0\0"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// SolveSpace native file format
|
// SolveSpace native file format
|
||||||
#define SLVS_PATTERN PAT1("SolveSpace Models", "slvs") ENDPAT
|
const FileFilter SlvsFileFilter[] = {
|
||||||
|
{ "SolveSpace models", { "slvs" } },
|
||||||
|
{ NULL }
|
||||||
|
};
|
||||||
// PNG format bitmap
|
// PNG format bitmap
|
||||||
#define PNG_PATTERN PAT1("PNG", "png") ENDPAT
|
const FileFilter PngFileFilter[] = {
|
||||||
|
{ "PNG", { "png" } },
|
||||||
|
{ NULL }
|
||||||
|
};
|
||||||
// Triangle mesh
|
// Triangle mesh
|
||||||
#define MESH_PATTERN \
|
const FileFilter MeshFileFilter[] = {
|
||||||
PAT1("STL Mesh", "stl") \
|
{ "STL mesh", { "stl" } },
|
||||||
PAT1("Wavefront OBJ Mesh", "obj") \
|
{ "Wavefront OBJ mesh", { "obj" } },
|
||||||
PAT1("Three.js-compatible Mesh, with viewer", "html") \
|
{ "Three.js-compatible mesh, with viewer", { "html" } },
|
||||||
PAT1("Three.js-compatible Mesh, mesh only", "js") \
|
{ "Three.js-compatible mesh, mesh only", { "js" } },
|
||||||
ENDPAT
|
{ NULL }
|
||||||
|
};
|
||||||
// NURBS surfaces
|
// NURBS surfaces
|
||||||
#define SRF_PATTERN PAT2("STEP File", "step", "stp") ENDPAT
|
const FileFilter SurfaceFileFilter[] = {
|
||||||
|
{ "STEP file", { "step", "stp" } },
|
||||||
|
{ NULL }
|
||||||
|
};
|
||||||
// 2d vector (lines and curves) format
|
// 2d vector (lines and curves) format
|
||||||
#define VEC_PATTERN \
|
const FileFilter VectorFileFilter[] = {
|
||||||
PAT1("PDF File", "pdf") \
|
{ "PDF file", { "pdf" } },
|
||||||
PAT2("Encapsulated PostScript", "eps", "ps") \
|
{ "Encapsulated PostScript", { "eps", "ps" } },
|
||||||
PAT1("Scalable Vector Graphics", "svg") \
|
{ "Scalable Vector Graphics", { "svg" } },
|
||||||
PAT2("STEP File", "step", "stp") \
|
{ "STEP file", { "step", "stp" } },
|
||||||
PAT1("DXF File (AutoCAD 2007)", "dxf") \
|
{ "DXF file (AutoCAD 2007)", { "dxf" } },
|
||||||
PAT2("HPGL File", "plt", "hpgl") \
|
{ "HPGL file", { "plt", "hpgl" } },
|
||||||
PAT1("G Code", "txt") \
|
{ "G Code", { "ngc", "txt" } },
|
||||||
ENDPAT
|
{ NULL }
|
||||||
|
};
|
||||||
// 3d vector (wireframe lines and curves) format
|
// 3d vector (wireframe lines and curves) format
|
||||||
#define V3D_PATTERN \
|
const FileFilter Vector3dFileFilter[] = {
|
||||||
PAT2("STEP File", "step", "stp") \
|
{ "STEP file", { "step", "stp" } },
|
||||||
PAT1("DXF File (AutoCAD 2007)", "dxf") \
|
{ "DXF file (AutoCAD 2007)", { "dxf" } },
|
||||||
ENDPAT
|
{ NULL }
|
||||||
|
};
|
||||||
// Comma-separated value, like a spreadsheet would use
|
// Comma-separated value, like a spreadsheet would use
|
||||||
#define CSV_PATTERN \
|
const FileFilter CsvFileFilter[] = {
|
||||||
PAT1("CSV File", "csv") \
|
{ "CSV", { "csv" } },
|
||||||
ENDPAT
|
{ NULL }
|
||||||
|
};
|
||||||
|
|
||||||
bool GetSaveFile(std::string &filename, const std::string &defExtension,
|
bool GetSaveFile(std::string *filename, const std::string &defExtension,
|
||||||
const char *selPattern);
|
const FileFilter filters[]);
|
||||||
bool GetOpenFile(std::string &filename, const std::string &defExtension,
|
bool GetOpenFile(std::string *filename, const std::string &defExtension,
|
||||||
const char *selPattern);
|
const FileFilter filters[]);
|
||||||
std::vector<std::string> GetFontFiles();
|
std::vector<std::string> GetFontFiles();
|
||||||
|
|
||||||
void OpenWebsite(const char *url);
|
void OpenWebsite(const char *url);
|
||||||
|
|
|
@ -391,7 +391,7 @@ void TextWindow::ScreenBackgroundImage(int link, uint32_t v) {
|
||||||
png_info *info_ptr = NULL;
|
png_info *info_ptr = NULL;
|
||||||
|
|
||||||
std::string importFile;
|
std::string importFile;
|
||||||
if(!GetOpenFile(importFile, "", PNG_PATTERN)) goto err;
|
if(!GetOpenFile(&importFile, "", PngFileFilter)) goto err;
|
||||||
f = ssfopen(importFile, "rb");
|
f = ssfopen(importFile, "rb");
|
||||||
if(!f) goto err;
|
if(!f) goto err;
|
||||||
|
|
||||||
|
|
|
@ -987,23 +987,39 @@ LRESULT CALLBACK GraphicsWndProc(HWND hwnd, UINT msg, WPARAM wParam,
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Common dialog routines, to open or save a file.
|
// Common dialog routines, to open or save a file.
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
static size_t strlen2(const char *p) {
|
static std::string ConvertFilters(const FileFilter ssFilters[]) {
|
||||||
const char *s = p;
|
std::string filter;
|
||||||
while(*p || (!*p && *(p+1))) p++;
|
for(const FileFilter *ssFilter = ssFilters; ssFilter->name; ssFilter++) {
|
||||||
return p - s + 1;
|
std::string desc, patterns;
|
||||||
|
for(const char *const *ssPattern = ssFilter->patterns; *ssPattern; ssPattern++) {
|
||||||
|
std::string pattern = "*." + std::string(*ssPattern);
|
||||||
|
if(desc == "")
|
||||||
|
desc = pattern;
|
||||||
|
else
|
||||||
|
desc += ", " + pattern;
|
||||||
|
if(patterns == "")
|
||||||
|
patterns = pattern;
|
||||||
|
else
|
||||||
|
patterns += ";" + pattern;
|
||||||
|
}
|
||||||
|
filter += std::string(ssFilter->name) + " (" + desc + ")" + '\0';
|
||||||
|
filter += patterns + '\0';
|
||||||
|
}
|
||||||
|
filter += '\0';
|
||||||
|
return filter;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool OpenSaveFile(bool isOpen, std::string &filename,
|
static bool OpenSaveFile(bool isOpen, std::string *filename, const std::string &defExtension,
|
||||||
const std::string &defExtension, const char *selPattern) {
|
const FileFilter filters[]) {
|
||||||
// UNC paths may be as long as 32767 characters.
|
// UNC paths may be as long as 32767 characters.
|
||||||
// Unfortunately, the Get*FileName API does not provide any way to use it
|
// Unfortunately, the Get*FileName API does not provide any way to use it
|
||||||
// except with a preallocated buffer of fixed size, so we use something
|
// except with a preallocated buffer of fixed size, so we use something
|
||||||
// reasonably large.
|
// reasonably large.
|
||||||
const int len = 32768;
|
const int len = 32768;
|
||||||
wchar_t filenameC[len] = {};
|
wchar_t filenameC[len] = {};
|
||||||
wcsncpy(filenameC, Widen(filename).c_str(), len - 1);
|
wcsncpy(filenameC, Widen(*filename).c_str(), len - 1);
|
||||||
|
|
||||||
std::wstring selPatternW = Widen(std::string(selPattern, strlen2(selPattern)));
|
std::wstring selPatternW = Widen(ConvertFilters(filters));
|
||||||
std::wstring defExtensionW = Widen(defExtension);
|
std::wstring defExtensionW = Widen(defExtension);
|
||||||
|
|
||||||
OPENFILENAME ofn = {};
|
OPENFILENAME ofn = {};
|
||||||
|
@ -1030,20 +1046,20 @@ static bool OpenSaveFile(bool isOpen, std::string &filename,
|
||||||
EnableWindow(GraphicsWnd, true);
|
EnableWindow(GraphicsWnd, true);
|
||||||
SetForegroundWindow(GraphicsWnd);
|
SetForegroundWindow(GraphicsWnd);
|
||||||
|
|
||||||
if(r) filename = Narrow(filenameC);
|
if(r) *filename = Narrow(filenameC);
|
||||||
return r ? true : false;
|
return r ? true : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SolveSpace::GetOpenFile(std::string &filename,
|
bool SolveSpace::GetOpenFile(std::string *filename, const std::string &defExtension,
|
||||||
const std::string &defExtension, const char *selPattern)
|
const FileFilter filters[])
|
||||||
{
|
{
|
||||||
return OpenSaveFile(true, filename, defExtension, selPattern);
|
return OpenSaveFile(true, filename, defExtension, filters);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SolveSpace::GetSaveFile(std::string &filename,
|
bool SolveSpace::GetSaveFile(std::string *filename, const std::string &defExtension,
|
||||||
const std::string &defExtension, const char *selPattern)
|
const FileFilter filters[])
|
||||||
{
|
{
|
||||||
return OpenSaveFile(false, filename, defExtension, selPattern);
|
return OpenSaveFile(false, filename, defExtension, filters);
|
||||||
}
|
}
|
||||||
|
|
||||||
DialogChoice SolveSpace::SaveFileYesNoCancel(void)
|
DialogChoice SolveSpace::SaveFileYesNoCancel(void)
|
||||||
|
|
Loading…
Reference in New Issue