Internationalize platform-specific code.
parent
aeebc3c395
commit
c12672be66
|
@ -7,7 +7,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: SolveSpace 3.0\n"
|
||||
"Report-Msgid-Bugs-To: whitequark@whitequark.org\n"
|
||||
"POT-Creation-Date: 2017-01-07 06:44+0000\n"
|
||||
"POT-Creation-Date: 2017-01-11 03:01+0000\n"
|
||||
"PO-Revision-Date: 2017-01-05 10:30+0000\n"
|
||||
"Last-Translator: Automatically generated\n"
|
||||
"Language-Team: none\n"
|
||||
|
@ -1398,6 +1398,191 @@ msgstr "click to place bottom left of text"
|
|||
msgid "NEW COMMENT -- DOUBLE-CLICK TO EDIT"
|
||||
msgstr "NEW COMMENT -- DOUBLE-CLICK TO EDIT"
|
||||
|
||||
#: platform/cocoamain.mm:481 platform/gtkmain.cpp:582 platform/w32main.cpp:448
|
||||
#: platform/w32main.cpp:1373
|
||||
msgctxt "title"
|
||||
msgid "(new sketch)"
|
||||
msgstr "(new sketch)"
|
||||
|
||||
#: platform/cocoamain.mm:710 platform/gtkmain.cpp:896 platform/w32main.cpp:1292
|
||||
msgid "(no recent files)"
|
||||
msgstr "(no recent files)"
|
||||
|
||||
#: platform/cocoamain.mm:828 platform/gtkmain.cpp:1010
|
||||
msgid "untitled"
|
||||
msgstr "untitled"
|
||||
|
||||
#: platform/cocoamain.mm:859
|
||||
msgid "Do you want to save the changes you made to the new sketch?"
|
||||
msgstr "Do you want to save the changes you made to the new sketch?"
|
||||
|
||||
#: platform/cocoamain.mm:861
|
||||
msgid "Your changes will be lost if you don't save them."
|
||||
msgstr "Your changes will be lost if you don't save them."
|
||||
|
||||
#: platform/cocoamain.mm:862
|
||||
msgctxt "button"
|
||||
msgid "Save"
|
||||
msgstr "Save"
|
||||
|
||||
#: platform/cocoamain.mm:863 platform/cocoamain.mm:904
|
||||
msgctxt "button"
|
||||
msgid "Cancel"
|
||||
msgstr "Cancel"
|
||||
|
||||
#: platform/cocoamain.mm:864
|
||||
msgctxt "button"
|
||||
msgid "Don't Save"
|
||||
msgstr "Don't Save"
|
||||
|
||||
#: platform/cocoamain.mm:879
|
||||
msgid "An autosave file is availible for this project."
|
||||
msgstr "An autosave file is availible for this project."
|
||||
|
||||
#: platform/cocoamain.mm:881
|
||||
msgid "Do you want to load the autosave file instead?"
|
||||
msgstr "Do you want to load the autosave file instead?"
|
||||
|
||||
#: platform/cocoamain.mm:882
|
||||
msgctxt "button"
|
||||
msgid "Load"
|
||||
msgstr "Load"
|
||||
|
||||
#: platform/cocoamain.mm:883
|
||||
msgctxt "button"
|
||||
msgid "Don't Load"
|
||||
msgstr "Don't Load"
|
||||
|
||||
#: platform/cocoamain.mm:899
|
||||
msgid ""
|
||||
"Do you want to locate it manually?\n"
|
||||
"If you select “No”, any geometry that depends on the missing file will be "
|
||||
"removed."
|
||||
msgstr ""
|
||||
"Do you want to locate it manually?\n"
|
||||
"If you select “No”, any geometry that depends on the missing file will be "
|
||||
"removed."
|
||||
|
||||
#: platform/cocoamain.mm:902
|
||||
msgctxt "button"
|
||||
msgid "Yes"
|
||||
msgstr "Yes"
|
||||
|
||||
#: platform/cocoamain.mm:905
|
||||
msgctxt "button"
|
||||
msgid "No"
|
||||
msgstr "No"
|
||||
|
||||
#: platform/cocoamain.mm:1125 platform/w32main.cpp:180
|
||||
msgctxt "button"
|
||||
msgid "OK"
|
||||
msgstr "OK"
|
||||
|
||||
#: platform/cocoamain.mm:1208 platform/gtkmain.cpp:1377
|
||||
#: platform/w32main.cpp:1395 platform/w32main.cpp:1435
|
||||
msgctxt "title"
|
||||
msgid "Property Browser"
|
||||
msgstr "Property Browser"
|
||||
|
||||
#: platform/gtkmain.cpp:952
|
||||
msgctxt "title"
|
||||
msgid "Open File"
|
||||
msgstr "Open File"
|
||||
|
||||
#: platform/gtkmain.cpp:954
|
||||
msgid "_Cancel"
|
||||
msgstr "_Cancel"
|
||||
|
||||
#: platform/gtkmain.cpp:955
|
||||
msgid "_Open"
|
||||
msgstr "_Open"
|
||||
|
||||
#: platform/gtkmain.cpp:1000
|
||||
msgctxt "title"
|
||||
msgid "Save File"
|
||||
msgstr "Save File"
|
||||
|
||||
#: platform/gtkmain.cpp:1003 platform/gtkmain.cpp:1040
|
||||
#: platform/gtkmain.cpp:1088
|
||||
msgctxt "button"
|
||||
msgid "_Cancel"
|
||||
msgstr "_Cancel"
|
||||
|
||||
#: platform/gtkmain.cpp:1004 platform/gtkmain.cpp:1038
|
||||
msgctxt "button"
|
||||
msgid "_Save"
|
||||
msgstr "_Save"
|
||||
|
||||
#: platform/gtkmain.cpp:1033 platform/w32main.cpp:1153
|
||||
msgid ""
|
||||
"The file has changed since it was last saved.\n"
|
||||
"\n"
|
||||
"Do you want to save the changes?"
|
||||
msgstr ""
|
||||
"The file has changed since it was last saved.\n"
|
||||
"\n"
|
||||
"Do you want to save the changes?"
|
||||
|
||||
#: platform/gtkmain.cpp:1037 platform/w32main.cpp:1155
|
||||
msgctxt "title"
|
||||
msgid "Modified File"
|
||||
msgstr "Modified File"
|
||||
|
||||
#: platform/gtkmain.cpp:1039
|
||||
msgctxt "button"
|
||||
msgid "Do_n't Save"
|
||||
msgstr "Do_n't Save"
|
||||
|
||||
#: platform/gtkmain.cpp:1057 platform/w32main.cpp:1179
|
||||
msgid ""
|
||||
"An autosave file is availible for this project.\n"
|
||||
"\n"
|
||||
"Do you want to load the autosave file instead?"
|
||||
msgstr ""
|
||||
"An autosave file is availible for this project.\n"
|
||||
"\n"
|
||||
"Do you want to load the autosave file instead?"
|
||||
|
||||
#: platform/gtkmain.cpp:1061 platform/w32main.cpp:1181
|
||||
msgctxt "title"
|
||||
msgid "Autosave Available"
|
||||
msgstr "Autosave Available"
|
||||
|
||||
#: platform/gtkmain.cpp:1062
|
||||
msgctxt "button"
|
||||
msgid "_Load autosave"
|
||||
msgstr "_Load autosave"
|
||||
|
||||
#: platform/gtkmain.cpp:1063
|
||||
msgctxt "button"
|
||||
msgid "Do_n't Load"
|
||||
msgstr "Do_n't Load"
|
||||
|
||||
#: platform/gtkmain.cpp:1084 platform/w32main.cpp:1209
|
||||
msgctxt "title"
|
||||
msgid "Missing File"
|
||||
msgstr "Missing File"
|
||||
|
||||
#: platform/gtkmain.cpp:1085
|
||||
msgctxt "button"
|
||||
msgid "_Yes"
|
||||
msgstr "_Yes"
|
||||
|
||||
#: platform/gtkmain.cpp:1086
|
||||
msgctxt "button"
|
||||
msgid "_No"
|
||||
msgstr "_No"
|
||||
|
||||
#: platform/gtkmain.cpp:1300 platform/w32main.cpp:176
|
||||
msgctxt "title"
|
||||
msgid "Error"
|
||||
msgstr "Error"
|
||||
|
||||
#: platform/gtkmain.cpp:1300 platform/w32main.cpp:176
|
||||
msgctxt "title"
|
||||
msgid "Message"
|
||||
msgstr "Message"
|
||||
|
||||
#: style.cpp:161
|
||||
msgid ""
|
||||
"Can't assign style to an entity that's derived from another entity; try "
|
||||
|
@ -1558,6 +1743,66 @@ msgstr "Nearest isometric view"
|
|||
msgid "Align view to active workplane"
|
||||
msgstr "Align view to active workplane"
|
||||
|
||||
#: ui.h:69
|
||||
msgid "SolveSpace models"
|
||||
msgstr "SolveSpace models"
|
||||
|
||||
#: ui.h:74
|
||||
msgid "PNG file"
|
||||
msgstr "PNG file"
|
||||
|
||||
#: ui.h:79
|
||||
msgid "STL mesh"
|
||||
msgstr "STL mesh"
|
||||
|
||||
#: ui.h:80
|
||||
msgid "Wavefront OBJ mesh"
|
||||
msgstr "Wavefront OBJ mesh"
|
||||
|
||||
#: ui.h:81
|
||||
msgid "Three.js-compatible mesh, with viewer"
|
||||
msgstr "Three.js-compatible mesh, with viewer"
|
||||
|
||||
#: ui.h:82
|
||||
msgid "Three.js-compatible mesh, mesh only"
|
||||
msgstr "Three.js-compatible mesh, mesh only"
|
||||
|
||||
#: ui.h:87 ui.h:95 ui.h:103
|
||||
msgid "STEP file"
|
||||
msgstr "STEP file"
|
||||
|
||||
#: ui.h:92
|
||||
msgid "PDF file"
|
||||
msgstr "PDF file"
|
||||
|
||||
#: ui.h:93
|
||||
msgid "Encapsulated PostScript"
|
||||
msgstr "Encapsulated PostScript"
|
||||
|
||||
#: ui.h:94
|
||||
msgid "Scalable Vector Graphics"
|
||||
msgstr "Scalable Vector Graphics"
|
||||
|
||||
#: ui.h:96 ui.h:104
|
||||
msgid "DXF file (AutoCAD 2007)"
|
||||
msgstr "DXF file (AutoCAD 2007)"
|
||||
|
||||
#: ui.h:97
|
||||
msgid "HPGL file"
|
||||
msgstr "HPGL file"
|
||||
|
||||
#: ui.h:98
|
||||
msgid "G Code"
|
||||
msgstr "G Code"
|
||||
|
||||
#: ui.h:109
|
||||
msgid "AutoCAD DXF and DWG files"
|
||||
msgstr "AutoCAD DXF and DWG files"
|
||||
|
||||
#: ui.h:114
|
||||
msgid "Comma-separated values"
|
||||
msgstr "Comma-separated values"
|
||||
|
||||
#: view.cpp:78
|
||||
msgid "Scale cannot be zero or negative."
|
||||
msgstr "Scale cannot be zero or negative."
|
||||
|
|
236
res/messages.pot
236
res/messages.pot
|
@ -8,7 +8,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: SolveSpace 3.0\n"
|
||||
"Report-Msgid-Bugs-To: whitequark@whitequark.org\n"
|
||||
"POT-Creation-Date: 2017-01-07 06:44+0000\n"
|
||||
"POT-Creation-Date: 2017-01-11 03:01+0000\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
|
@ -1212,6 +1212,180 @@ msgstr ""
|
|||
msgid "NEW COMMENT -- DOUBLE-CLICK TO EDIT"
|
||||
msgstr ""
|
||||
|
||||
#: platform/cocoamain.mm:481 platform/gtkmain.cpp:582 platform/w32main.cpp:448
|
||||
#: platform/w32main.cpp:1373
|
||||
msgctxt "title"
|
||||
msgid "(new sketch)"
|
||||
msgstr ""
|
||||
|
||||
#: platform/cocoamain.mm:710 platform/gtkmain.cpp:896 platform/w32main.cpp:1292
|
||||
msgid "(no recent files)"
|
||||
msgstr ""
|
||||
|
||||
#: platform/cocoamain.mm:828 platform/gtkmain.cpp:1010
|
||||
msgid "untitled"
|
||||
msgstr ""
|
||||
|
||||
#: platform/cocoamain.mm:859
|
||||
msgid "Do you want to save the changes you made to the new sketch?"
|
||||
msgstr ""
|
||||
|
||||
#: platform/cocoamain.mm:861
|
||||
msgid "Your changes will be lost if you don't save them."
|
||||
msgstr ""
|
||||
|
||||
#: platform/cocoamain.mm:862
|
||||
msgctxt "button"
|
||||
msgid "Save"
|
||||
msgstr ""
|
||||
|
||||
#: platform/cocoamain.mm:863 platform/cocoamain.mm:904
|
||||
msgctxt "button"
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
|
||||
#: platform/cocoamain.mm:864
|
||||
msgctxt "button"
|
||||
msgid "Don't Save"
|
||||
msgstr ""
|
||||
|
||||
#: platform/cocoamain.mm:879
|
||||
msgid "An autosave file is availible for this project."
|
||||
msgstr ""
|
||||
|
||||
#: platform/cocoamain.mm:881
|
||||
msgid "Do you want to load the autosave file instead?"
|
||||
msgstr ""
|
||||
|
||||
#: platform/cocoamain.mm:882
|
||||
msgctxt "button"
|
||||
msgid "Load"
|
||||
msgstr ""
|
||||
|
||||
#: platform/cocoamain.mm:883
|
||||
msgctxt "button"
|
||||
msgid "Don't Load"
|
||||
msgstr ""
|
||||
|
||||
#: platform/cocoamain.mm:899
|
||||
msgid ""
|
||||
"Do you want to locate it manually?\n"
|
||||
"If you select “No”, any geometry that depends on the missing file will be removed."
|
||||
msgstr ""
|
||||
|
||||
#: platform/cocoamain.mm:902
|
||||
msgctxt "button"
|
||||
msgid "Yes"
|
||||
msgstr ""
|
||||
|
||||
#: platform/cocoamain.mm:905
|
||||
msgctxt "button"
|
||||
msgid "No"
|
||||
msgstr ""
|
||||
|
||||
#: platform/cocoamain.mm:1125 platform/w32main.cpp:180
|
||||
msgctxt "button"
|
||||
msgid "OK"
|
||||
msgstr ""
|
||||
|
||||
#: platform/cocoamain.mm:1208 platform/gtkmain.cpp:1377 platform/w32main.cpp:1395
|
||||
#: platform/w32main.cpp:1435
|
||||
msgctxt "title"
|
||||
msgid "Property Browser"
|
||||
msgstr ""
|
||||
|
||||
#: platform/gtkmain.cpp:952
|
||||
msgctxt "title"
|
||||
msgid "Open File"
|
||||
msgstr ""
|
||||
|
||||
#: platform/gtkmain.cpp:954
|
||||
msgid "_Cancel"
|
||||
msgstr ""
|
||||
|
||||
#: platform/gtkmain.cpp:955
|
||||
msgid "_Open"
|
||||
msgstr ""
|
||||
|
||||
#: platform/gtkmain.cpp:1000
|
||||
msgctxt "title"
|
||||
msgid "Save File"
|
||||
msgstr ""
|
||||
|
||||
#: platform/gtkmain.cpp:1003 platform/gtkmain.cpp:1040 platform/gtkmain.cpp:1088
|
||||
msgctxt "button"
|
||||
msgid "_Cancel"
|
||||
msgstr ""
|
||||
|
||||
#: platform/gtkmain.cpp:1004 platform/gtkmain.cpp:1038
|
||||
msgctxt "button"
|
||||
msgid "_Save"
|
||||
msgstr ""
|
||||
|
||||
#: platform/gtkmain.cpp:1033 platform/w32main.cpp:1153
|
||||
msgid ""
|
||||
"The file has changed since it was last saved.\n"
|
||||
"\n"
|
||||
"Do you want to save the changes?"
|
||||
msgstr ""
|
||||
|
||||
#: platform/gtkmain.cpp:1037 platform/w32main.cpp:1155
|
||||
msgctxt "title"
|
||||
msgid "Modified File"
|
||||
msgstr ""
|
||||
|
||||
#: platform/gtkmain.cpp:1039
|
||||
msgctxt "button"
|
||||
msgid "Do_n't Save"
|
||||
msgstr ""
|
||||
|
||||
#: platform/gtkmain.cpp:1057 platform/w32main.cpp:1179
|
||||
msgid ""
|
||||
"An autosave file is availible for this project.\n"
|
||||
"\n"
|
||||
"Do you want to load the autosave file instead?"
|
||||
msgstr ""
|
||||
|
||||
#: platform/gtkmain.cpp:1061 platform/w32main.cpp:1181
|
||||
msgctxt "title"
|
||||
msgid "Autosave Available"
|
||||
msgstr ""
|
||||
|
||||
#: platform/gtkmain.cpp:1062
|
||||
msgctxt "button"
|
||||
msgid "_Load autosave"
|
||||
msgstr ""
|
||||
|
||||
#: platform/gtkmain.cpp:1063
|
||||
msgctxt "button"
|
||||
msgid "Do_n't Load"
|
||||
msgstr ""
|
||||
|
||||
#: platform/gtkmain.cpp:1084 platform/w32main.cpp:1209
|
||||
msgctxt "title"
|
||||
msgid "Missing File"
|
||||
msgstr ""
|
||||
|
||||
#: platform/gtkmain.cpp:1085
|
||||
msgctxt "button"
|
||||
msgid "_Yes"
|
||||
msgstr ""
|
||||
|
||||
#: platform/gtkmain.cpp:1086
|
||||
msgctxt "button"
|
||||
msgid "_No"
|
||||
msgstr ""
|
||||
|
||||
#: platform/gtkmain.cpp:1300 platform/w32main.cpp:176
|
||||
msgctxt "title"
|
||||
msgid "Error"
|
||||
msgstr ""
|
||||
|
||||
#: platform/gtkmain.cpp:1300 platform/w32main.cpp:176
|
||||
msgctxt "title"
|
||||
msgid "Message"
|
||||
msgstr ""
|
||||
|
||||
#: style.cpp:161
|
||||
msgid ""
|
||||
"Can't assign style to an entity that's derived from another entity; try assigning a style to this "
|
||||
|
@ -1370,6 +1544,66 @@ msgstr ""
|
|||
msgid "Align view to active workplane"
|
||||
msgstr ""
|
||||
|
||||
#: ui.h:69
|
||||
msgid "SolveSpace models"
|
||||
msgstr ""
|
||||
|
||||
#: ui.h:74
|
||||
msgid "PNG file"
|
||||
msgstr ""
|
||||
|
||||
#: ui.h:79
|
||||
msgid "STL mesh"
|
||||
msgstr ""
|
||||
|
||||
#: ui.h:80
|
||||
msgid "Wavefront OBJ mesh"
|
||||
msgstr ""
|
||||
|
||||
#: ui.h:81
|
||||
msgid "Three.js-compatible mesh, with viewer"
|
||||
msgstr ""
|
||||
|
||||
#: ui.h:82
|
||||
msgid "Three.js-compatible mesh, mesh only"
|
||||
msgstr ""
|
||||
|
||||
#: ui.h:87 ui.h:95 ui.h:103
|
||||
msgid "STEP file"
|
||||
msgstr ""
|
||||
|
||||
#: ui.h:92
|
||||
msgid "PDF file"
|
||||
msgstr ""
|
||||
|
||||
#: ui.h:93
|
||||
msgid "Encapsulated PostScript"
|
||||
msgstr ""
|
||||
|
||||
#: ui.h:94
|
||||
msgid "Scalable Vector Graphics"
|
||||
msgstr ""
|
||||
|
||||
#: ui.h:96 ui.h:104
|
||||
msgid "DXF file (AutoCAD 2007)"
|
||||
msgstr ""
|
||||
|
||||
#: ui.h:97
|
||||
msgid "HPGL file"
|
||||
msgstr ""
|
||||
|
||||
#: ui.h:98
|
||||
msgid "G Code"
|
||||
msgstr ""
|
||||
|
||||
#: ui.h:109
|
||||
msgid "AutoCAD DXF and DWG files"
|
||||
msgstr ""
|
||||
|
||||
#: ui.h:114
|
||||
msgid "Comma-separated values"
|
||||
msgstr ""
|
||||
|
||||
#: view.cpp:78
|
||||
msgid "Scale cannot be zero or negative."
|
||||
msgstr ""
|
||||
|
|
|
@ -125,10 +125,14 @@ else()
|
|||
endforeach()
|
||||
endif()
|
||||
|
||||
set(every_platform_SOURCES
|
||||
platform/w32main.cpp
|
||||
platform/gtkmain.cpp
|
||||
platform/cocoamain.mm)
|
||||
|
||||
# solvespace library
|
||||
|
||||
set(solvespace_core_HEADERS
|
||||
config.h
|
||||
dsc.h
|
||||
expr.h
|
||||
polygon.h
|
||||
|
@ -212,11 +216,15 @@ if(HAVE_GETTEXT)
|
|||
set(output_pot ${CMAKE_CURRENT_SOURCE_DIR}/../res/messages.pot)
|
||||
set(templ_po ${CMAKE_CURRENT_BINARY_DIR}/messages.po)
|
||||
set(output_po ${CMAKE_CURRENT_SOURCE_DIR}/../res/locales/en_US.po)
|
||||
set(inputs ${solvespace_core_SOURCES})
|
||||
set(inputs
|
||||
${solvespace_core_SOURCES}
|
||||
${solvespace_core_HEADERS}
|
||||
${every_platform_SOURCES})
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${output_pot}
|
||||
COMMAND ${XGETTEXT}
|
||||
--language=C++
|
||||
--keyword --keyword=_ --keyword=N_ --keyword=C_:2,1c --keyword=CN_:2,1c
|
||||
--force-po --width=100 --sort-by-file
|
||||
--package-name=SolveSpace
|
||||
|
|
|
@ -13,16 +13,22 @@
|
|||
|
||||
using SolveSpace::dbp;
|
||||
|
||||
/* Utility functions */
|
||||
|
||||
static NSString* Wrap(const std::string &s) {
|
||||
return [NSString stringWithUTF8String:s.c_str()];
|
||||
}
|
||||
|
||||
/* Settings */
|
||||
|
||||
namespace SolveSpace {
|
||||
void CnfFreezeInt(uint32_t val, const std::string &key) {
|
||||
[[NSUserDefaults standardUserDefaults]
|
||||
setInteger:val forKey:[NSString stringWithUTF8String:key.c_str()]];
|
||||
setInteger:val forKey:Wrap(key)];
|
||||
}
|
||||
|
||||
uint32_t CnfThawInt(uint32_t val, const std::string &key) {
|
||||
NSString *nsKey = [NSString stringWithUTF8String:key.c_str()];
|
||||
NSString *nsKey = Wrap(key);
|
||||
if([[NSUserDefaults standardUserDefaults] objectForKey:nsKey])
|
||||
return [[NSUserDefaults standardUserDefaults] integerForKey:nsKey];
|
||||
return val;
|
||||
|
@ -30,11 +36,11 @@ uint32_t CnfThawInt(uint32_t val, const std::string &key) {
|
|||
|
||||
void CnfFreezeFloat(float val, const std::string &key) {
|
||||
[[NSUserDefaults standardUserDefaults]
|
||||
setFloat:val forKey:[NSString stringWithUTF8String:key.c_str()]];
|
||||
setFloat:val forKey:Wrap(key)];
|
||||
}
|
||||
|
||||
float CnfThawFloat(float val, const std::string &key) {
|
||||
NSString *nsKey = [NSString stringWithUTF8String:key.c_str()];
|
||||
NSString *nsKey = Wrap(key);
|
||||
if([[NSUserDefaults standardUserDefaults] objectForKey:nsKey])
|
||||
return [[NSUserDefaults standardUserDefaults] floatForKey:nsKey];
|
||||
return val;
|
||||
|
@ -42,12 +48,12 @@ float CnfThawFloat(float val, const std::string &key) {
|
|||
|
||||
void CnfFreezeString(const std::string &val, const std::string &key) {
|
||||
[[NSUserDefaults standardUserDefaults]
|
||||
setObject:[NSString stringWithUTF8String:val.c_str()]
|
||||
forKey:[NSString stringWithUTF8String:key.c_str()]];
|
||||
setObject:Wrap(val)
|
||||
forKey:Wrap(key)];
|
||||
}
|
||||
|
||||
std::string CnfThawString(const std::string &val, const std::string &key) {
|
||||
NSString *nsKey = [NSString stringWithUTF8String:key.c_str()];
|
||||
NSString *nsKey = Wrap(key);
|
||||
if([[NSUserDefaults standardUserDefaults] objectForKey:nsKey]) {
|
||||
NSString *nsNewVal = [[NSUserDefaults standardUserDefaults] stringForKey:nsKey];
|
||||
return [nsNewVal UTF8String];
|
||||
|
@ -459,45 +465,45 @@ void GetGraphicsWindowSize(int *w, int *h) {
|
|||
*h = (int)size.height;
|
||||
}
|
||||
|
||||
void InvalidateGraphics(void) {
|
||||
void InvalidateGraphics() {
|
||||
[GWView setNeedsDisplay:YES];
|
||||
}
|
||||
|
||||
void PaintGraphics(void) {
|
||||
void PaintGraphics() {
|
||||
[GWView setNeedsDisplay:YES];
|
||||
CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, YES);
|
||||
}
|
||||
|
||||
void SetCurrentFilename(const std::string &filename) {
|
||||
if(!filename.empty()) {
|
||||
[GW setTitleWithRepresentedFilename:[NSString stringWithUTF8String:filename.c_str()]];
|
||||
[GW setTitleWithRepresentedFilename:Wrap(filename)];
|
||||
} else {
|
||||
[GW setTitle:@"(new sketch)"];
|
||||
[GW setTitle:Wrap(C_("title", "(new sketch)"))];
|
||||
[GW setRepresentedFilename:@""];
|
||||
}
|
||||
}
|
||||
|
||||
void ToggleFullScreen(void) {
|
||||
void ToggleFullScreen() {
|
||||
[GW toggleFullScreen:nil];
|
||||
}
|
||||
|
||||
bool FullScreenIsActive(void) {
|
||||
bool FullScreenIsActive() {
|
||||
return [GWDelegate isFullscreen];
|
||||
}
|
||||
|
||||
void ShowGraphicsEditControl(int x, int y, int fontHeight, int minWidthChars,
|
||||
const std::string &str) {
|
||||
[GWView startEditing:[NSString stringWithUTF8String:str.c_str()]
|
||||
[GWView startEditing:Wrap(str)
|
||||
at:(NSPoint){(CGFloat)x, (CGFloat)y}
|
||||
withHeight:fontHeight
|
||||
withMinWidthInChars:minWidthChars];
|
||||
}
|
||||
|
||||
void HideGraphicsEditControl(void) {
|
||||
void HideGraphicsEditControl() {
|
||||
[GWView stopEditing];
|
||||
}
|
||||
|
||||
bool GraphicsEditControlIsVisible(void) {
|
||||
bool GraphicsEditControlIsVisible() {
|
||||
return [GWView isEditing];
|
||||
}
|
||||
}
|
||||
|
@ -547,13 +553,13 @@ void AddContextMenuItem(const char *label, ContextCommand cmd) {
|
|||
}
|
||||
}
|
||||
|
||||
void CreateContextSubmenu(void) {
|
||||
void CreateContextSubmenu() {
|
||||
ssassert(!contextSubmenu, "Unexpected nested submenu");
|
||||
|
||||
contextSubmenu = [[NSMenu alloc] initWithTitle:@""];
|
||||
}
|
||||
|
||||
ContextCommand ShowContextMenu(void) {
|
||||
ContextCommand ShowContextMenu() {
|
||||
if(!contextMenu)
|
||||
return ContextCommand::CANCELLED;
|
||||
|
||||
|
@ -629,7 +635,7 @@ void InitMainMenu(NSMenu *mainMenu) {
|
|||
current_level = entry->level;
|
||||
|
||||
if(entry->label) {
|
||||
label = [NSString stringWithUTF8String:Translate(entry->label).c_str()];
|
||||
label = Wrap(Translate(entry->label));
|
||||
/* OS X does not support mnemonics */
|
||||
label = [label stringByReplacingOccurrencesOfString:@"&" withString:@""];
|
||||
|
||||
|
@ -668,7 +674,7 @@ void InitMainMenu(NSMenu *mainMenu) {
|
|||
for(auto locale : Locales()) {
|
||||
NSMenuItem *localeMenuItem =
|
||||
[localeMenu addItemWithTitle:
|
||||
[NSString stringWithUTF8String:locale.displayName.c_str()]
|
||||
Wrap(locale.displayName)
|
||||
action:NULL keyEquivalent:@""];
|
||||
[localeMenuItem setTag:(NSInteger)i++];
|
||||
[localeMenuItem setTarget:[MainMenuResponder class]];
|
||||
|
@ -701,7 +707,7 @@ static void RefreshRecentMenu(SolveSpace::Command cmd, SolveSpace::Command base)
|
|||
|
||||
if(std::string(RecentFile[0]).empty()) {
|
||||
NSMenuItem *placeholder = [[NSMenuItem alloc]
|
||||
initWithTitle:@"(no recent files)" action:nil keyEquivalent:@""];
|
||||
initWithTitle:Wrap(_("(no recent files)")) action:nil keyEquivalent:@""];
|
||||
[placeholder setEnabled:NO];
|
||||
[menu addItem:placeholder];
|
||||
} else {
|
||||
|
@ -710,7 +716,7 @@ static void RefreshRecentMenu(SolveSpace::Command cmd, SolveSpace::Command base)
|
|||
break;
|
||||
|
||||
NSMenuItem *item = [[NSMenuItem alloc]
|
||||
initWithTitle:[[NSString stringWithUTF8String:RecentFile[i].c_str()]
|
||||
initWithTitle:[Wrap(RecentFile[i])
|
||||
stringByAbbreviatingWithTildeInPath]
|
||||
action:nil keyEquivalent:@""];
|
||||
[item setTag:((uint32_t)base + i)];
|
||||
|
@ -721,16 +727,16 @@ static void RefreshRecentMenu(SolveSpace::Command cmd, SolveSpace::Command base)
|
|||
}
|
||||
}
|
||||
|
||||
void RefreshRecentMenus(void) {
|
||||
void RefreshRecentMenus() {
|
||||
RefreshRecentMenu(Command::OPEN_RECENT, Command::RECENT_OPEN);
|
||||
RefreshRecentMenu(Command::GROUP_RECENT, Command::RECENT_LINK);
|
||||
}
|
||||
|
||||
void ToggleMenuBar(void) {
|
||||
void ToggleMenuBar() {
|
||||
[NSMenu setMenuBarVisible:![NSMenu menuBarVisible]];
|
||||
}
|
||||
|
||||
bool MenuBarIsVisible(void) {
|
||||
bool MenuBarIsVisible() {
|
||||
return [NSMenu menuBarVisible];
|
||||
}
|
||||
}
|
||||
|
@ -801,8 +807,8 @@ bool SolveSpace::GetSaveFile(std::string *file, const std::string &defExtension,
|
|||
desc += *ssPattern;
|
||||
}
|
||||
}
|
||||
std::string title = std::string(ssFilter->name) + " (" + desc + ")";
|
||||
[button addItemWithTitle:[NSString stringWithUTF8String:title.c_str()]];
|
||||
std::string title = Translate(ssFilter->name) + " (" + desc + ")";
|
||||
[button addItemWithTitle:Wrap(title)];
|
||||
[extensions addObject:[NSString stringWithUTF8String:ssFilter->patterns[0]]];
|
||||
}
|
||||
[panel setAllowedFileTypes:extensions];
|
||||
|
@ -810,8 +816,7 @@ bool SolveSpace::GetSaveFile(std::string *file, const std::string &defExtension,
|
|||
|
||||
int extensionIndex = 0;
|
||||
if(defExtension != "") {
|
||||
extensionIndex = [extensions indexOfObject:
|
||||
[NSString stringWithUTF8String:defExtension.c_str()]];
|
||||
extensionIndex = [extensions indexOfObject:Wrap(defExtension)];
|
||||
if(extensionIndex == -1) {
|
||||
extensionIndex = 0;
|
||||
}
|
||||
|
@ -819,14 +824,15 @@ bool SolveSpace::GetSaveFile(std::string *file, const std::string &defExtension,
|
|||
[button selectItemAtIndex:extensionIndex];
|
||||
|
||||
if(file->empty()) {
|
||||
[panel setNameFieldStringValue:[@"untitled"
|
||||
[panel setNameFieldStringValue:
|
||||
[Wrap(_("untitled"))
|
||||
stringByAppendingPathExtension:[extensions objectAtIndex:extensionIndex]]];
|
||||
} else {
|
||||
[panel setDirectoryURL:
|
||||
[NSURL fileURLWithPath:[NSString stringWithUTF8String:Dirname(*file).c_str()]
|
||||
[NSURL fileURLWithPath:Wrap(Dirname(*file))
|
||||
isDirectory:NO]];
|
||||
[panel setNameFieldStringValue:
|
||||
[[NSString stringWithUTF8String:Basename(*file, /*stripExtension=*/true).c_str()]
|
||||
[Wrap(Basename(*file, /*stripExtension=*/true))
|
||||
stringByAppendingPathExtension:[extensions objectAtIndex:extensionIndex]]];
|
||||
}
|
||||
|
||||
|
@ -839,22 +845,23 @@ bool SolveSpace::GetSaveFile(std::string *file, const std::string &defExtension,
|
|||
}
|
||||
}
|
||||
|
||||
SolveSpace::DialogChoice SolveSpace::SaveFileYesNoCancel(void) {
|
||||
SolveSpace::DialogChoice SolveSpace::SaveFileYesNoCancel() {
|
||||
NSAlert *alert = [[NSAlert alloc] init];
|
||||
if(!std::string(SolveSpace::SS.saveFile).empty()) {
|
||||
[alert setMessageText:
|
||||
[[@"Do you want to save the changes you made to the sketch “"
|
||||
stringByAppendingString:
|
||||
[[NSString stringWithUTF8String:SolveSpace::SS.saveFile.c_str()]
|
||||
[Wrap(SolveSpace::SS.saveFile)
|
||||
stringByAbbreviatingWithTildeInPath]]
|
||||
stringByAppendingString:@"”?"]];
|
||||
} else {
|
||||
[alert setMessageText:@"Do you want to save the changes you made to the new sketch?"];
|
||||
[alert setMessageText:
|
||||
Wrap(_("Do you want to save the changes you made to the new sketch?"))];
|
||||
}
|
||||
[alert setInformativeText:@"Your changes will be lost if you don't save them."];
|
||||
[alert addButtonWithTitle:@"Save"];
|
||||
[alert addButtonWithTitle:@"Cancel"];
|
||||
[alert addButtonWithTitle:@"Don't Save"];
|
||||
[alert setInformativeText:Wrap(_("Your changes will be lost if you don't save them."))];
|
||||
[alert addButtonWithTitle:Wrap(C_("button", "Save"))];
|
||||
[alert addButtonWithTitle:Wrap(C_("button", "Cancel"))];
|
||||
[alert addButtonWithTitle:Wrap(C_("button", "Don't Save"))];
|
||||
switch([alert runModal]) {
|
||||
case NSAlertFirstButtonReturn:
|
||||
return DIALOG_YES;
|
||||
|
@ -866,14 +873,14 @@ SolveSpace::DialogChoice SolveSpace::SaveFileYesNoCancel(void) {
|
|||
}
|
||||
}
|
||||
|
||||
SolveSpace::DialogChoice SolveSpace::LoadAutosaveYesNo(void) {
|
||||
SolveSpace::DialogChoice SolveSpace::LoadAutosaveYesNo() {
|
||||
NSAlert *alert = [[NSAlert alloc] init];
|
||||
[alert setMessageText:
|
||||
@"An autosave file is availible for this project."];
|
||||
Wrap(_("An autosave file is availible for this project."))];
|
||||
[alert setInformativeText:
|
||||
@"Do you want to load the autosave file instead?"];
|
||||
[alert addButtonWithTitle:@"Load"];
|
||||
[alert addButtonWithTitle:@"Don't Load"];
|
||||
Wrap(_("Do you want to load the autosave file instead?"))];
|
||||
[alert addButtonWithTitle:Wrap(C_("button", "Load"))];
|
||||
[alert addButtonWithTitle:Wrap(C_("button", "Don't Load"))];
|
||||
switch([alert runModal]) {
|
||||
case NSAlertFirstButtonReturn:
|
||||
return DIALOG_YES;
|
||||
|
@ -886,16 +893,16 @@ SolveSpace::DialogChoice SolveSpace::LoadAutosaveYesNo(void) {
|
|||
SolveSpace::DialogChoice SolveSpace::LocateImportedFileYesNoCancel(
|
||||
const std::string &filename, bool canCancel) {
|
||||
NSAlert *alert = [[NSAlert alloc] init];
|
||||
[alert setMessageText:[NSString stringWithUTF8String:
|
||||
("The linked file " + filename + " is not present.").c_str()]];
|
||||
[alert setMessageText:
|
||||
Wrap("The linked file “" + filename + "” is not present.")];
|
||||
[alert setInformativeText:
|
||||
@"Do you want to locate it manually?\n"
|
||||
"If you select \"No\", any geometry that depends on "
|
||||
"the missing file will be removed."];
|
||||
[alert addButtonWithTitle:@"Yes"];
|
||||
Wrap(_("Do you want to locate it manually?\n"
|
||||
"If you select “No”, any geometry that depends on "
|
||||
"the missing file will be removed."))];
|
||||
[alert addButtonWithTitle:Wrap(C_("button", "Yes"))];
|
||||
if(canCancel)
|
||||
[alert addButtonWithTitle:@"Cancel"];
|
||||
[alert addButtonWithTitle:@"No"];
|
||||
[alert addButtonWithTitle:Wrap(C_("button", "Cancel"))];
|
||||
[alert addButtonWithTitle:Wrap(C_("button", "No"))];
|
||||
switch([alert runModal]) {
|
||||
case NSAlertFirstButtonReturn:
|
||||
return DIALOG_YES;
|
||||
|
@ -1039,7 +1046,6 @@ void InitTextWindow() {
|
|||
NSUtilityWindowMask)];
|
||||
[[TW standardWindowButton:NSWindowMiniaturizeButton] setHidden:YES];
|
||||
[[TW standardWindowButton:NSWindowZoomButton] setHidden:YES];
|
||||
[TW setTitle:@"Property Browser"];
|
||||
[TW setFrameAutosaveName:@"TextWindow"];
|
||||
[TW setFloatingPanel:YES];
|
||||
[TW setBecomesKeyOnlyIfNeeded:YES];
|
||||
|
@ -1082,7 +1088,7 @@ double GetScreenDpi() {
|
|||
return (displayPixelSize.width / displayPhysicalSize.width) * 25.4f;
|
||||
}
|
||||
|
||||
void InvalidateText(void) {
|
||||
void InvalidateText() {
|
||||
NSSize size = [TWView convertSizeToBacking:[TWView frame].size];
|
||||
size.height = (SS.TW.top[SS.TW.rows - 1] + 1) * TextWindow::LINE_HEIGHT / 2;
|
||||
[TWView setFrameSize:[TWView convertSizeFromBacking:size]];
|
||||
|
@ -1098,15 +1104,15 @@ void SetMousePointerToHand(bool is_hand) {
|
|||
}
|
||||
|
||||
void ShowTextEditControl(int x, int y, const std::string &str) {
|
||||
return [TWView startEditing:[NSString stringWithUTF8String:str.c_str()]
|
||||
return [TWView startEditing:Wrap(str)
|
||||
at:(NSPoint){(CGFloat)x, (CGFloat)y}];
|
||||
}
|
||||
|
||||
void HideTextEditControl(void) {
|
||||
void HideTextEditControl() {
|
||||
return [TWView stopEditing];
|
||||
}
|
||||
|
||||
bool TextEditControlIsVisible(void) {
|
||||
bool TextEditControlIsVisible() {
|
||||
return [TWView isEditing];
|
||||
}
|
||||
};
|
||||
|
@ -1116,10 +1122,10 @@ bool TextEditControlIsVisible(void) {
|
|||
void SolveSpace::DoMessageBox(const char *str, int rows, int cols, bool error) {
|
||||
NSAlert *alert = [[NSAlert alloc] init];
|
||||
[alert setAlertStyle:(error ? NSWarningAlertStyle : NSInformationalAlertStyle)];
|
||||
[alert addButtonWithTitle:@"OK"];
|
||||
[alert addButtonWithTitle:Wrap(C_("button", "OK"))];
|
||||
|
||||
/* do some additional formatting of the message these are
|
||||
heuristics, but they are made failsafe and lead to nice results. */
|
||||
/* do some additional formatting of the message;
|
||||
these are heuristics, but they are made failsafe and lead to nice results. */
|
||||
NSString *input = [NSString stringWithUTF8String:str];
|
||||
NSRange dot = [input rangeOfCharacterFromSet:
|
||||
[NSCharacterSet characterSetWithCharactersInString:@".:"]];
|
||||
|
@ -1195,10 +1201,14 @@ std::vector<std::string> SolveSpace::GetFontFiles() {
|
|||
@end
|
||||
|
||||
void SolveSpace::RefreshLocale() {
|
||||
SS.UpdateWindowTitle();
|
||||
SolveSpace::InitMainMenu([NSApp mainMenu]);
|
||||
RefreshRecentMenus();
|
||||
|
||||
[TW setTitle:Wrap(C_("title", "Property Browser"))];
|
||||
}
|
||||
|
||||
void SolveSpace::ExitNow(void) {
|
||||
void SolveSpace::ExitNow() {
|
||||
[NSApp stop:nil];
|
||||
}
|
||||
|
||||
|
|
|
@ -10,8 +10,6 @@
|
|||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <json-c/json_object.h>
|
||||
#include <json-c/json_util.h>
|
||||
|
||||
|
@ -53,6 +51,11 @@
|
|||
#endif
|
||||
|
||||
namespace SolveSpace {
|
||||
/* Utility functions */
|
||||
std::string Title(const std::string &s) {
|
||||
return "SolveSpace - " + s;
|
||||
}
|
||||
|
||||
/* Settings */
|
||||
|
||||
/* Why not just use GSettings? Two reasons. It doesn't allow to easily see
|
||||
|
@ -576,11 +579,7 @@ void PaintGraphics(void) {
|
|||
}
|
||||
|
||||
void SetCurrentFilename(const std::string &filename) {
|
||||
if(!filename.empty()) {
|
||||
GW->set_title("SolveSpace - " + filename);
|
||||
} else {
|
||||
GW->set_title("SolveSpace - (not yet saved)");
|
||||
}
|
||||
GW->set_title(Title(filename.empty() ? C_("title", "(new sketch)") : filename.c_str()));
|
||||
}
|
||||
|
||||
void ToggleFullScreen(void) {
|
||||
|
@ -893,13 +892,13 @@ static void RefreshRecentMenu(Command cmd, Command base) {
|
|||
Gtk::Menu *menu = new Gtk::Menu;
|
||||
recent->set_submenu(*menu);
|
||||
|
||||
if(std::string(RecentFile[0]).empty()) {
|
||||
Gtk::MenuItem *placeholder = new Gtk::MenuItem("(no recent files)");
|
||||
if(RecentFile[0].empty()) {
|
||||
Gtk::MenuItem *placeholder = new Gtk::MenuItem(_("(no recent files)"));
|
||||
placeholder->set_sensitive(false);
|
||||
menu->append(*placeholder);
|
||||
} else {
|
||||
for(size_t i = 0; i < MAX_RECENT; i++) {
|
||||
if(std::string(RecentFile[i]).empty())
|
||||
if(RecentFile[i].empty())
|
||||
break;
|
||||
|
||||
RecentMenuItem *item = new RecentMenuItem(RecentFile[i], (uint32_t)base + i);
|
||||
|
@ -921,7 +920,7 @@ static std::string ConvertFilters(std::string active, const FileFilter ssFilters
|
|||
Gtk::FileChooser *chooser) {
|
||||
for(const FileFilter *ssFilter = ssFilters; ssFilter->name; ssFilter++) {
|
||||
Glib::RefPtr<Gtk::FileFilter> filter = Gtk::FileFilter::create();
|
||||
filter->set_name(ssFilter->name);
|
||||
filter->set_name(Translate(ssFilter->name));
|
||||
|
||||
bool is_active = false;
|
||||
std::string desc = "";
|
||||
|
@ -950,10 +949,10 @@ static std::string ConvertFilters(std::string active, const FileFilter ssFilters
|
|||
|
||||
bool GetOpenFile(std::string *filename, const std::string &activeOrEmpty,
|
||||
const FileFilter filters[]) {
|
||||
Gtk::FileChooserDialog chooser(*GW, "SolveSpace - Open File");
|
||||
Gtk::FileChooserDialog chooser(*GW, Title(C_("title", "Open File")));
|
||||
chooser.set_filename(*filename);
|
||||
chooser.add_button("_Cancel", Gtk::RESPONSE_CANCEL);
|
||||
chooser.add_button("_Open", Gtk::RESPONSE_OK);
|
||||
chooser.add_button(_("_Cancel"), Gtk::RESPONSE_CANCEL);
|
||||
chooser.add_button(_("_Open"), Gtk::RESPONSE_OK);
|
||||
chooser.set_current_folder(CnfThawString("", "FileChooserPath"));
|
||||
|
||||
ConvertFilters(activeOrEmpty, filters, &chooser);
|
||||
|
@ -998,17 +997,17 @@ static void ChooserFilterChanged(Gtk::FileChooserDialog *chooser)
|
|||
|
||||
bool GetSaveFile(std::string *filename, const std::string &defExtension,
|
||||
const FileFilter filters[]) {
|
||||
Gtk::FileChooserDialog chooser(*GW, "SolveSpace - Save File",
|
||||
Gtk::FileChooserDialog chooser(*GW, Title(C_("title", "Save File")),
|
||||
Gtk::FILE_CHOOSER_ACTION_SAVE);
|
||||
chooser.set_do_overwrite_confirmation(true);
|
||||
chooser.add_button("_Cancel", Gtk::RESPONSE_CANCEL);
|
||||
chooser.add_button("_Save", Gtk::RESPONSE_OK);
|
||||
chooser.add_button(C_("button", "_Cancel"), Gtk::RESPONSE_CANCEL);
|
||||
chooser.add_button(C_("button", "_Save"), Gtk::RESPONSE_OK);
|
||||
|
||||
std::string activeExtension = ConvertFilters(defExtension, filters, &chooser);
|
||||
|
||||
if(filename->empty()) {
|
||||
chooser.set_current_folder(CnfThawString("", "FileChooserPath"));
|
||||
chooser.set_current_name("untitled." + activeExtension);
|
||||
chooser.set_current_name(std::string(_("untitled")) + "." + activeExtension);
|
||||
} else {
|
||||
chooser.set_current_folder(Dirname(*filename));
|
||||
chooser.set_current_name(Basename(*filename, /*stripExtension=*/true) +
|
||||
|
@ -1031,14 +1030,14 @@ bool GetSaveFile(std::string *filename, const std::string &defExtension,
|
|||
|
||||
DialogChoice SaveFileYesNoCancel(void) {
|
||||
Glib::ustring message =
|
||||
"The file has changed since it was last saved.\n"
|
||||
"Do you want to save the changes?";
|
||||
_("The file has changed since it was last saved.\n\n"
|
||||
"Do you want to save the changes?");
|
||||
Gtk::MessageDialog dialog(*GW, message, /*use_markup*/ true, Gtk::MESSAGE_QUESTION,
|
||||
Gtk::BUTTONS_NONE, /*is_modal*/ true);
|
||||
dialog.set_title("SolveSpace - Modified File");
|
||||
dialog.add_button("_Save", Gtk::RESPONSE_YES);
|
||||
dialog.add_button("Do_n't Save", Gtk::RESPONSE_NO);
|
||||
dialog.add_button("_Cancel", Gtk::RESPONSE_CANCEL);
|
||||
dialog.set_title(Title(C_("title", "Modified File")));
|
||||
dialog.add_button(C_("button", "_Save"), Gtk::RESPONSE_YES);
|
||||
dialog.add_button(C_("button", "Do_n't Save"), Gtk::RESPONSE_NO);
|
||||
dialog.add_button(C_("button", "_Cancel"), Gtk::RESPONSE_CANCEL);
|
||||
|
||||
switch(dialog.run()) {
|
||||
case Gtk::RESPONSE_YES:
|
||||
|
@ -1055,13 +1054,13 @@ DialogChoice SaveFileYesNoCancel(void) {
|
|||
|
||||
DialogChoice LoadAutosaveYesNo(void) {
|
||||
Glib::ustring message =
|
||||
"An autosave file is availible for this project.\n"
|
||||
"Do you want to load the autosave file instead?";
|
||||
_("An autosave file is availible for this project.\n\n"
|
||||
"Do you want to load the autosave file instead?");
|
||||
Gtk::MessageDialog dialog(*GW, message, /*use_markup*/ true, Gtk::MESSAGE_QUESTION,
|
||||
Gtk::BUTTONS_NONE, /*is_modal*/ true);
|
||||
dialog.set_title("SolveSpace - Autosave Available");
|
||||
dialog.add_button("_Load autosave", Gtk::RESPONSE_YES);
|
||||
dialog.add_button("Do_n't Load", Gtk::RESPONSE_NO);
|
||||
dialog.set_title(Title(C_("title", "Autosave Available")));
|
||||
dialog.add_button(C_("button", "_Load autosave"), Gtk::RESPONSE_YES);
|
||||
dialog.add_button(C_("button", "Do_n't Load"), Gtk::RESPONSE_NO);
|
||||
|
||||
switch(dialog.run()) {
|
||||
case Gtk::RESPONSE_YES:
|
||||
|
@ -1076,17 +1075,17 @@ DialogChoice LoadAutosaveYesNo(void) {
|
|||
DialogChoice LocateImportedFileYesNoCancel(const std::string &filename,
|
||||
bool canCancel) {
|
||||
Glib::ustring message =
|
||||
"The linked file " + filename + " is not present.\n"
|
||||
"Do you want to locate it manually?\n"
|
||||
"The linked file " + filename + " is not present.\n\n"
|
||||
"Do you want to locate it manually?\n\n"
|
||||
"If you select \"No\", any geometry that depends on "
|
||||
"the missing file will be removed.";
|
||||
Gtk::MessageDialog dialog(*GW, message, /*use_markup*/ true, Gtk::MESSAGE_QUESTION,
|
||||
Gtk::BUTTONS_NONE, /*is_modal*/ true);
|
||||
dialog.set_title("SolveSpace - Missing File");
|
||||
dialog.add_button("_Yes", Gtk::RESPONSE_YES);
|
||||
dialog.add_button("_No", Gtk::RESPONSE_NO);
|
||||
dialog.set_title(Title(C_("title", "Missing File")));
|
||||
dialog.add_button(C_("button", "_Yes"), Gtk::RESPONSE_YES);
|
||||
dialog.add_button(C_("button", "_No"), Gtk::RESPONSE_NO);
|
||||
if(canCancel)
|
||||
dialog.add_button("_Cancel", Gtk::RESPONSE_CANCEL);
|
||||
dialog.add_button(C_("button", "_Cancel"), Gtk::RESPONSE_CANCEL);
|
||||
|
||||
switch(dialog.run()) {
|
||||
case Gtk::RESPONSE_YES:
|
||||
|
@ -1167,7 +1166,6 @@ public:
|
|||
set_type_hint(Gdk::WINDOW_TYPE_HINT_UTILITY);
|
||||
set_skip_taskbar_hint(true);
|
||||
set_skip_pager_hint(true);
|
||||
set_title("SolveSpace - Property Browser");
|
||||
set_default_size(420, 300);
|
||||
|
||||
_box.pack_start(_overlay, true, true);
|
||||
|
@ -1298,7 +1296,8 @@ void DoMessageBox(const char *message, int rows, int cols, bool error) {
|
|||
Gtk::MessageDialog dialog(*GW, message, /*use_markup*/ true,
|
||||
error ? Gtk::MESSAGE_ERROR : Gtk::MESSAGE_INFO, Gtk::BUTTONS_OK,
|
||||
/*is_modal*/ true);
|
||||
dialog.set_title(error ? "SolveSpace - Error" : "SolveSpace - Message");
|
||||
dialog.set_title(error ?
|
||||
Title(C_("title", "Error")) : Title(C_("title", "Message")));
|
||||
dialog.run();
|
||||
}
|
||||
|
||||
|
@ -1365,13 +1364,17 @@ static GdkFilterReturn GdkSpnavFilter(GdkXEvent *gxevent, GdkEvent *, gpointer)
|
|||
/* Application lifecycle */
|
||||
|
||||
void RefreshLocale() {
|
||||
SS.UpdateWindowTitle();
|
||||
for(auto menu : GW->get_menubar().get_children()) {
|
||||
GW->get_menubar().remove(*menu);
|
||||
}
|
||||
InitMainMenu(&GW->get_menubar());
|
||||
RefreshRecentMenus();
|
||||
GW->get_menubar().show_all();
|
||||
GW->get_menubar().accelerate(*GW);
|
||||
GW->get_menubar().accelerate(*TW);
|
||||
|
||||
TW->set_title(Title(C_("title", "Property Browser")));
|
||||
}
|
||||
|
||||
void ExitNow() {
|
||||
|
@ -1390,7 +1393,7 @@ int main(int argc, char** argv) {
|
|||
We set it back to C after all. */
|
||||
setlocale(LC_ALL, "");
|
||||
if(!Glib::get_charset()) {
|
||||
std::cerr << "Sorry, only UTF-8 locales are supported." << std::endl;
|
||||
dbp("Sorry, only UTF-8 locales are supported.");
|
||||
return 1;
|
||||
}
|
||||
setlocale(LC_ALL, "C");
|
||||
|
@ -1441,8 +1444,7 @@ int main(int argc, char** argv) {
|
|||
|
||||
if(argc >= 2) {
|
||||
if(argc > 2) {
|
||||
std::cerr << "Only the first file passed on command line will be opened."
|
||||
<< std::endl;
|
||||
dbp("Only the first file passed on command line will be opened.");
|
||||
}
|
||||
|
||||
/* Make sure the argument is valid UTF-8. */
|
||||
|
|
|
@ -72,6 +72,13 @@ HFONT FixedFont;
|
|||
SiHdl SpaceNavigator = SI_NO_HANDLE;
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Utility routines
|
||||
//-----------------------------------------------------------------------------
|
||||
std::wstring Title(const std::string &s) {
|
||||
return Widen("SolveSpace - " + s);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Routines to display message boxes on screen. Do our own, instead of using
|
||||
// MessageBox, because that is not consistent from version to version and
|
||||
|
@ -161,16 +168,16 @@ void SolveSpace::DoMessageBox(const char *str, int rows, int cols, bool error)
|
|||
MessageString = str;
|
||||
RECT r;
|
||||
GetWindowRect(GraphicsWnd, &r);
|
||||
const char *title = error ? "SolveSpace - Error" : "SolveSpace - Message";
|
||||
int width = cols*SS.TW.CHAR_WIDTH + 20,
|
||||
height = rows*SS.TW.LINE_HEIGHT + 60;
|
||||
MessageWidth = width;
|
||||
MessageHeight = height;
|
||||
MessageWnd = CreateWindowClient(0, L"MessageWnd", Widen(title).c_str(),
|
||||
MessageWnd = CreateWindowClient(0, L"MessageWnd",
|
||||
(error ? Title(C_("title", "Error")) : Title(C_("title", "Message"))).c_str(),
|
||||
WS_OVERLAPPED | WS_SYSMENU,
|
||||
r.left + 100, r.top + 100, width, height, NULL, NULL, Instance, NULL);
|
||||
|
||||
OkButton = CreateWindowExW(0, WC_BUTTON, L"OK",
|
||||
OkButton = CreateWindowExW(0, WC_BUTTON, Widen(C_("button", "OK")).c_str(),
|
||||
WS_CHILD | WS_TABSTOP | WS_CLIPSIBLINGS | WS_VISIBLE | BS_DEFPUSHBUTTON,
|
||||
(width - 70)/2, rows*SS.TW.LINE_HEIGHT + 20,
|
||||
70, 25, MessageWnd, NULL, Instance, NULL);
|
||||
|
@ -437,11 +444,8 @@ static void ThawWindowPos(HWND hwnd, const std::string &name)
|
|||
}
|
||||
|
||||
void SolveSpace::SetCurrentFilename(const std::string &filename) {
|
||||
if(!filename.empty()) {
|
||||
SetWindowTextW(GraphicsWnd, Widen("SolveSpace - " + filename).c_str());
|
||||
} else {
|
||||
SetWindowTextW(GraphicsWnd, L"SolveSpace - (not yet saved)");
|
||||
}
|
||||
SetWindowTextW(GraphicsWnd,
|
||||
Title(filename.empty() ? C_("title", "(new sketch)") : filename).c_str());
|
||||
}
|
||||
|
||||
void SolveSpace::SetMousePointerToHand(bool yes) {
|
||||
|
@ -1146,8 +1150,9 @@ DialogChoice SolveSpace::SaveFileYesNoCancel()
|
|||
EnableWindow(TextWnd, false);
|
||||
|
||||
int r = MessageBoxW(GraphicsWnd,
|
||||
L"The file has changed since it was last saved.\n\n"
|
||||
L"Do you want to save the changes?", L"SolveSpace",
|
||||
Widen(_("The file has changed since it was last saved.\n\n"
|
||||
"Do you want to save the changes?")).c_str(),
|
||||
Title(C_("title", "Modified File")).c_str(),
|
||||
MB_YESNOCANCEL | MB_ICONWARNING);
|
||||
|
||||
EnableWindow(TextWnd, true);
|
||||
|
@ -1171,8 +1176,9 @@ DialogChoice SolveSpace::LoadAutosaveYesNo()
|
|||
EnableWindow(TextWnd, false);
|
||||
|
||||
int r = MessageBoxW(GraphicsWnd,
|
||||
L"An autosave file is availible for this project.\n\n"
|
||||
L"Do you want to load the autosave file instead?", L"SolveSpace",
|
||||
Widen(_("An autosave file is availible for this project.\n\n"
|
||||
"Do you want to load the autosave file instead?")).c_str(),
|
||||
Title(C_("title", "Autosave Available")).c_str(),
|
||||
MB_YESNO | MB_ICONWARNING);
|
||||
|
||||
EnableWindow(TextWnd, true);
|
||||
|
@ -1199,7 +1205,8 @@ DialogChoice SolveSpace::LocateImportedFileYesNoCancel(const std::string &filena
|
|||
"If you select \"No\", any geometry that depends on "
|
||||
"the missing file will be removed.";
|
||||
|
||||
int r = MessageBoxW(GraphicsWnd, Widen(message).c_str(), L"SolveSpace",
|
||||
int r = MessageBoxW(GraphicsWnd, Widen(message).c_str(),
|
||||
Title(C_("title", "Missing File")).c_str(),
|
||||
(canCancel ? MB_YESNOCANCEL : MB_YESNO) | MB_ICONWARNING);
|
||||
|
||||
EnableWindow(TextWnd, true);
|
||||
|
@ -1282,7 +1289,7 @@ static void DoRecent(HMENU m, Command base)
|
|||
c++;
|
||||
}
|
||||
}
|
||||
if(c == 0) AppendMenuW(m, MF_STRING | MF_GRAYED, 0, L"(no recent files)");
|
||||
if(c == 0) AppendMenuW(m, MF_STRING | MF_GRAYED, 0, Widen(_("(no recent files)")).c_str());
|
||||
}
|
||||
void SolveSpace::RefreshRecentMenus()
|
||||
{
|
||||
|
@ -1363,7 +1370,7 @@ static void CreateMainWindows()
|
|||
ssassert(RegisterClassEx(&wc), "Cannot register window class");
|
||||
|
||||
GraphicsWnd = CreateWindowExW(0, L"GraphicsWnd",
|
||||
L"SolveSpace (not yet saved)",
|
||||
Title(C_("title", "(new sketch)")).c_str(),
|
||||
WS_OVERLAPPED | WS_THICKFRAME | WS_CLIPCHILDREN | WS_MAXIMIZEBOX |
|
||||
WS_MINIMIZEBOX | WS_SYSMENU | WS_SIZEBOX | WS_CLIPSIBLINGS,
|
||||
50, 50, 900, 600, NULL, NULL, Instance, NULL);
|
||||
|
@ -1384,8 +1391,9 @@ static void CreateMainWindows()
|
|||
|
||||
// We get the desired Alt+Tab behaviour by specifying that the text
|
||||
// window is a child of the graphics window.
|
||||
TextWnd = CreateWindowExW(0,
|
||||
L"TextWnd", L"SolveSpace - Property Browser", WS_THICKFRAME | WS_CLIPCHILDREN,
|
||||
TextWnd = CreateWindowExW(0, L"TextWnd",
|
||||
Title(C_("title", "Property Browser")).c_str(),
|
||||
WS_THICKFRAME | WS_CLIPCHILDREN,
|
||||
650, 500, 420, 300, GraphicsWnd, (HMENU)NULL, Instance, NULL);
|
||||
ssassert(TextWnd != NULL, "Cannot create window");
|
||||
|
||||
|
@ -1415,11 +1423,16 @@ static void CreateMainWindows()
|
|||
}
|
||||
|
||||
void SolveSpace::RefreshLocale() {
|
||||
SS.UpdateWindowTitle();
|
||||
|
||||
HMENU oldMenu = GetMenu(GraphicsWnd);
|
||||
SetMenu(GraphicsWnd, CreateGraphicsWindowMenus());
|
||||
if(oldMenu != NULL) {
|
||||
DestroyMenu(oldMenu);
|
||||
}
|
||||
RefreshRecentMenus();
|
||||
|
||||
SetWindowTextW(TextWnd, Title(C_("title", "Property Browser")).c_str());
|
||||
}
|
||||
|
||||
#ifdef HAVE_SPACEWARE
|
||||
|
|
|
@ -169,67 +169,13 @@ DialogChoice LocateImportedFileYesNoCancel(const std::string &filename,
|
|||
|
||||
#define AUTOSAVE_SUFFIX "~"
|
||||
|
||||
struct FileFilter {
|
||||
const char *name;
|
||||
const char *patterns[3];
|
||||
};
|
||||
|
||||
// SolveSpace native file format
|
||||
const FileFilter SlvsFileFilter[] = {
|
||||
{ "SolveSpace models", { "slvs" } },
|
||||
{ NULL, {} }
|
||||
};
|
||||
// PNG format bitmap
|
||||
const FileFilter PngFileFilter[] = {
|
||||
{ "PNG file", { "png" } },
|
||||
{ NULL, {} }
|
||||
};
|
||||
// Triangle mesh
|
||||
const FileFilter MeshFileFilter[] = {
|
||||
{ "STL mesh", { "stl" } },
|
||||
{ "Wavefront OBJ mesh", { "obj" } },
|
||||
{ "Three.js-compatible mesh, with viewer", { "html" } },
|
||||
{ "Three.js-compatible mesh, mesh only", { "js" } },
|
||||
{ NULL, {} }
|
||||
};
|
||||
// NURBS surfaces
|
||||
const FileFilter SurfaceFileFilter[] = {
|
||||
{ "STEP file", { "step", "stp" } },
|
||||
{ NULL, {} }
|
||||
};
|
||||
// 2d vector (lines and curves) format
|
||||
const FileFilter VectorFileFilter[] = {
|
||||
{ "PDF file", { "pdf" } },
|
||||
{ "Encapsulated PostScript", { "eps", "ps" } },
|
||||
{ "Scalable Vector Graphics", { "svg" } },
|
||||
{ "STEP file", { "step", "stp" } },
|
||||
{ "DXF file (AutoCAD 2007)", { "dxf" } },
|
||||
{ "HPGL file", { "plt", "hpgl" } },
|
||||
{ "G Code", { "ngc", "txt" } },
|
||||
{ NULL, {} }
|
||||
};
|
||||
// 3d vector (wireframe lines and curves) format
|
||||
const FileFilter Vector3dFileFilter[] = {
|
||||
{ "STEP file", { "step", "stp" } },
|
||||
{ "DXF file (AutoCAD 2007)", { "dxf" } },
|
||||
{ NULL, {} }
|
||||
};
|
||||
// All Importable formats
|
||||
const FileFilter ImportableFileFilter[] = {
|
||||
{ "AutoCAD DXF and DWG files", { "dxf", "dwg" } },
|
||||
{ NULL, {} }
|
||||
};
|
||||
// Comma-separated value, like a spreadsheet would use
|
||||
const FileFilter CsvFileFilter[] = {
|
||||
{ "CSV", { "csv" } },
|
||||
{ NULL, {} }
|
||||
};
|
||||
|
||||
enum class Unit : uint32_t {
|
||||
MM = 0,
|
||||
INCHES
|
||||
};
|
||||
|
||||
struct FileFilter;
|
||||
|
||||
bool GetSaveFile(std::string *filename, const std::string &defExtension,
|
||||
const FileFilter filters[]);
|
||||
bool GetOpenFile(std::string *filename, const std::string &defExtension,
|
||||
|
|
57
src/ui.h
57
src/ui.h
|
@ -58,6 +58,63 @@ inline const char *C_(const char *msgctxt, const char *msgid) {
|
|||
}
|
||||
#endif
|
||||
|
||||
// Filters for the file formats that we support.
|
||||
struct FileFilter {
|
||||
const char *name;
|
||||
const char *patterns[3];
|
||||
};
|
||||
|
||||
// SolveSpace native file format
|
||||
const FileFilter SlvsFileFilter[] = {
|
||||
{ N_("SolveSpace models"), { "slvs" } },
|
||||
{ NULL, {} }
|
||||
};
|
||||
// PNG format bitmap
|
||||
const FileFilter PngFileFilter[] = {
|
||||
{ N_("PNG file"), { "png" } },
|
||||
{ NULL, {} }
|
||||
};
|
||||
// Triangle mesh
|
||||
const FileFilter MeshFileFilter[] = {
|
||||
{ N_("STL mesh"), { "stl" } },
|
||||
{ N_("Wavefront OBJ mesh"), { "obj" } },
|
||||
{ N_("Three.js-compatible mesh, with viewer"), { "html" } },
|
||||
{ N_("Three.js-compatible mesh, mesh only"), { "js" } },
|
||||
{ NULL, {} }
|
||||
};
|
||||
// NURBS surfaces
|
||||
const FileFilter SurfaceFileFilter[] = {
|
||||
{ N_("STEP file"), { "step", "stp" } },
|
||||
{ NULL, {} }
|
||||
};
|
||||
// 2d vector (lines and curves) format
|
||||
const FileFilter VectorFileFilter[] = {
|
||||
{ N_("PDF file"), { "pdf" } },
|
||||
{ N_("Encapsulated PostScript"), { "eps", "ps" } },
|
||||
{ N_("Scalable Vector Graphics"), { "svg" } },
|
||||
{ N_("STEP file"), { "step", "stp" } },
|
||||
{ N_("DXF file (AutoCAD 2007)"), { "dxf" } },
|
||||
{ N_("HPGL file"), { "plt", "hpgl" } },
|
||||
{ N_("G Code"), { "ngc", "txt" } },
|
||||
{ NULL, {} }
|
||||
};
|
||||
// 3d vector (wireframe lines and curves) format
|
||||
const FileFilter Vector3dFileFilter[] = {
|
||||
{ N_("STEP file"), { "step", "stp" } },
|
||||
{ N_("DXF file (AutoCAD 2007)"), { "dxf" } },
|
||||
{ NULL, {} }
|
||||
};
|
||||
// All Importable formats
|
||||
const FileFilter ImportableFileFilter[] = {
|
||||
{ N_("AutoCAD DXF and DWG files"), { "dxf", "dwg" } },
|
||||
{ NULL, {} }
|
||||
};
|
||||
// Comma-separated value, like a spreadsheet would use
|
||||
const FileFilter CsvFileFilter[] = {
|
||||
{ N_("Comma-separated values"), { "csv" } },
|
||||
{ NULL, {} }
|
||||
};
|
||||
|
||||
// This table describes the top-level menus in the graphics winodw.
|
||||
enum class Command : uint32_t {
|
||||
NONE = 0,
|
||||
|
|
Loading…
Reference in New Issue