Internationalize all messages without substitutions.
parent
4fda1e4361
commit
984f74d271
1241
res/locales/en_US.po
1241
res/locales/en_US.po
File diff suppressed because it is too large
Load Diff
1088
res/locales/ua_UA.po
1088
res/locales/ua_UA.po
File diff suppressed because it is too large
Load Diff
1053
res/messages.pot
1053
res/messages.pot
File diff suppressed because it is too large
Load Diff
|
@ -212,21 +212,20 @@ if(HAVE_GETTEXT)
|
||||||
set(output_pot ${CMAKE_CURRENT_SOURCE_DIR}/../res/messages.pot)
|
set(output_pot ${CMAKE_CURRENT_SOURCE_DIR}/../res/messages.pot)
|
||||||
set(templ_po ${CMAKE_CURRENT_BINARY_DIR}/messages.po)
|
set(templ_po ${CMAKE_CURRENT_BINARY_DIR}/messages.po)
|
||||||
set(output_po ${CMAKE_CURRENT_SOURCE_DIR}/../res/locales/en_US.po)
|
set(output_po ${CMAKE_CURRENT_SOURCE_DIR}/../res/locales/en_US.po)
|
||||||
set(inputs)
|
set(inputs ${solvespace_core_SOURCES})
|
||||||
foreach(input ${solvespace_core_SOURCES})
|
|
||||||
list(APPEND inputs ${CMAKE_CURRENT_SOURCE_DIR}/${input})
|
|
||||||
endforeach()
|
|
||||||
|
|
||||||
add_custom_command(
|
add_custom_command(
|
||||||
OUTPUT ${output_pot}
|
OUTPUT ${output_pot}
|
||||||
COMMAND ${XGETTEXT}
|
COMMAND ${XGETTEXT}
|
||||||
--keyword --keyword=_ --keyword=N_
|
--keyword --keyword=_ --keyword=N_ --keyword=C_:2,1c --keyword=CN_:2,1c
|
||||||
--force-po --width=100 --sort-by-file
|
--force-po --width=100 --sort-by-file
|
||||||
--package-name=SolveSpace --package-version=3.0
|
--package-name=SolveSpace
|
||||||
|
--package-version=${solvespace_VERSION_MAJOR}.${solvespace_VERSION_MINOR}
|
||||||
"--copyright-holder=the PACKAGE authors"
|
"--copyright-holder=the PACKAGE authors"
|
||||||
--msgid-bugs-address=whitequark@whitequark.org
|
--msgid-bugs-address=whitequark@whitequark.org
|
||||||
--from-code=utf-8 --output=${output_pot} ${inputs}
|
--from-code=utf-8 --output=${output_pot} ${inputs}
|
||||||
DEPENDS ${inputs}
|
DEPENDS ${inputs}
|
||||||
|
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
COMMENT "Extracting translations"
|
COMMENT "Extracting translations"
|
||||||
VERBATIM)
|
VERBATIM)
|
||||||
add_custom_command(
|
add_custom_command(
|
||||||
|
@ -240,7 +239,7 @@ if(HAVE_GETTEXT)
|
||||||
DEPENDS ${output_pot}
|
DEPENDS ${output_pot}
|
||||||
COMMENT "Updating English translations"
|
COMMENT "Updating English translations"
|
||||||
VERBATIM)
|
VERBATIM)
|
||||||
add_custom_target(solvespace-translations ALL
|
add_custom_target(solvespace-translations
|
||||||
DEPENDS ${output_pot} ${output_po})
|
DEPENDS ${output_pot} ${output_po})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
|
@ -239,8 +239,8 @@ void GraphicsWindow::PasteClipboard(Vector trans, double theta, double scale) {
|
||||||
|
|
||||||
void GraphicsWindow::MenuClipboard(Command id) {
|
void GraphicsWindow::MenuClipboard(Command id) {
|
||||||
if(id != Command::DELETE && !SS.GW.LockedInWorkplane()) {
|
if(id != Command::DELETE && !SS.GW.LockedInWorkplane()) {
|
||||||
Error("Cut, paste, and copy work only in a workplane.\n\n"
|
Error(_("Cut, paste, and copy work only in a workplane.\n\n"
|
||||||
"Activate one with Sketch -> In Workplane.");
|
"Activate one with Sketch -> In Workplane."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -256,7 +256,7 @@ void GraphicsWindow::MenuClipboard(Command id) {
|
||||||
|
|
||||||
case Command::PASTE_TRANSFORM: {
|
case Command::PASTE_TRANSFORM: {
|
||||||
if(SS.clipboard.r.n == 0) {
|
if(SS.clipboard.r.n == 0) {
|
||||||
Error("Clipboard is empty; nothing to paste.");
|
Error(_("Clipboard is empty; nothing to paste."));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -303,7 +303,7 @@ bool TextWindow::EditControlDoneForPaste(const char *s) {
|
||||||
if(v > 0) {
|
if(v > 0) {
|
||||||
shown.paste.times = v;
|
shown.paste.times = v;
|
||||||
} else {
|
} else {
|
||||||
Error("Number of copies to paste must be at least one.");
|
Error(_("Number of copies to paste must be at least one."));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -319,7 +319,7 @@ bool TextWindow::EditControlDoneForPaste(const char *s) {
|
||||||
if(fabs(v) > 1e-6) {
|
if(fabs(v) > 1e-6) {
|
||||||
shown.paste.scale = v;
|
shown.paste.scale = v;
|
||||||
} else {
|
} else {
|
||||||
Error("Scale cannot be zero.");
|
Error(_("Scale cannot be zero."));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -357,7 +357,7 @@ void TextWindow::ScreenPasteTransformed(int link, uint32_t v) {
|
||||||
Entity *e = SK.GetEntity(SS.GW.gs.point[0]);
|
Entity *e = SK.GetEntity(SS.GW.gs.point[0]);
|
||||||
SS.TW.shown.paste.origin = e->PointGetNum();
|
SS.TW.shown.paste.origin = e->PointGetNum();
|
||||||
} else {
|
} else {
|
||||||
Error("Select one point to define origin of rotation.");
|
Error(_("Select one point to define origin of rotation."));
|
||||||
}
|
}
|
||||||
SS.GW.ClearSelection();
|
SS.GW.ClearSelection();
|
||||||
break;
|
break;
|
||||||
|
@ -369,7 +369,7 @@ void TextWindow::ScreenPasteTransformed(int link, uint32_t v) {
|
||||||
SS.TW.shown.paste.trans =
|
SS.TW.shown.paste.trans =
|
||||||
(pb->PointGetNum()).Minus(pa->PointGetNum());
|
(pb->PointGetNum()).Minus(pa->PointGetNum());
|
||||||
} else {
|
} else {
|
||||||
Error("Select two points to define translation vector.");
|
Error(_("Select two points to define translation vector."));
|
||||||
}
|
}
|
||||||
SS.GW.ClearSelection();
|
SS.GW.ClearSelection();
|
||||||
break;
|
break;
|
||||||
|
@ -379,16 +379,16 @@ void TextWindow::ScreenPasteTransformed(int link, uint32_t v) {
|
||||||
SS.TW.shown.paste.trans.Magnitude() < LENGTH_EPS &&
|
SS.TW.shown.paste.trans.Magnitude() < LENGTH_EPS &&
|
||||||
SS.TW.shown.paste.times != 1)
|
SS.TW.shown.paste.times != 1)
|
||||||
{
|
{
|
||||||
Message("Transformation is identity. So all copies will be "
|
Message(_("Transformation is identity. So all copies will be "
|
||||||
"exactly on top of each other.");
|
"exactly on top of each other."));
|
||||||
}
|
}
|
||||||
if(SS.TW.shown.paste.times*SS.clipboard.r.n > 100) {
|
if(SS.TW.shown.paste.times*SS.clipboard.r.n > 100) {
|
||||||
Error("Too many items to paste; split this into smaller "
|
Error(_("Too many items to paste; split this into smaller "
|
||||||
"pastes.");
|
"pastes."));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(!SS.GW.LockedInWorkplane()) {
|
if(!SS.GW.LockedInWorkplane()) {
|
||||||
Error("No workplane active.");
|
Error(_("No workplane active."));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
Entity *wrkpl = SK.GetEntity(SS.GW.ActiveWorkplane());
|
Entity *wrkpl = SK.GetEntity(SS.GW.ActiveWorkplane());
|
||||||
|
|
|
@ -325,7 +325,7 @@ bool TextWindow::EditControlDoneForConfiguration(const char *s) {
|
||||||
if(sscanf(s, "%lf, %lf, %lf", &x, &y, &z)==3) {
|
if(sscanf(s, "%lf, %lf, %lf", &x, &y, &z)==3) {
|
||||||
SS.lightDir[edit.i] = Vector::From(x, y, z);
|
SS.lightDir[edit.i] = Vector::From(x, y, z);
|
||||||
} else {
|
} else {
|
||||||
Error("Bad format: specify coordinates as x, y, z");
|
Error(_("Bad format: specify coordinates as x, y, z"));
|
||||||
}
|
}
|
||||||
InvalidateGraphics();
|
InvalidateGraphics();
|
||||||
break;
|
break;
|
||||||
|
@ -336,7 +336,7 @@ bool TextWindow::EditControlDoneForConfiguration(const char *s) {
|
||||||
rgb = rgb.ClampWithin(0, 1);
|
rgb = rgb.ClampWithin(0, 1);
|
||||||
SS.modelColor[edit.i] = RGBf(rgb.x, rgb.y, rgb.z);
|
SS.modelColor[edit.i] = RGBf(rgb.x, rgb.y, rgb.z);
|
||||||
} else {
|
} else {
|
||||||
Error("Bad format: specify color as r, g, b");
|
Error(_("Bad format: specify color as r, g, b"));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -361,8 +361,8 @@ bool TextWindow::EditControlDoneForConfiguration(const char *s) {
|
||||||
case Edit::CAMERA_TANGENT: {
|
case Edit::CAMERA_TANGENT: {
|
||||||
SS.cameraTangent = (min(2.0, max(0.0, atof(s))))/1000.0;
|
SS.cameraTangent = (min(2.0, max(0.0, atof(s))))/1000.0;
|
||||||
if(!SS.usePerspectiveProj) {
|
if(!SS.usePerspectiveProj) {
|
||||||
Message("The perspective factor will have no effect until you "
|
Message(_("The perspective factor will have no effect until you "
|
||||||
"enable View -> Use Perspective Projection.");
|
"enable View -> Use Perspective Projection."));
|
||||||
}
|
}
|
||||||
InvalidateGraphics();
|
InvalidateGraphics();
|
||||||
break;
|
break;
|
||||||
|
@ -375,7 +375,7 @@ bool TextWindow::EditControlDoneForConfiguration(const char *s) {
|
||||||
case Edit::DIGITS_AFTER_DECIMAL: {
|
case Edit::DIGITS_AFTER_DECIMAL: {
|
||||||
int v = atoi(s);
|
int v = atoi(s);
|
||||||
if(v < 0 || v > 8) {
|
if(v < 0 || v > 8) {
|
||||||
Error("Specify between 0 and 8 digits after the decimal.");
|
Error(_("Specify between 0 and 8 digits after the decimal."));
|
||||||
} else {
|
} else {
|
||||||
SS.SetUnitDigitsAfterDecimal(v);
|
SS.SetUnitDigitsAfterDecimal(v);
|
||||||
}
|
}
|
||||||
|
@ -387,7 +387,7 @@ bool TextWindow::EditControlDoneForConfiguration(const char *s) {
|
||||||
if(e) {
|
if(e) {
|
||||||
double ev = e->Eval();
|
double ev = e->Eval();
|
||||||
if(fabs(ev) < 0.001 || isnan(ev)) {
|
if(fabs(ev) < 0.001 || isnan(ev)) {
|
||||||
Error("Export scale must not be zero!");
|
Error(_("Export scale must not be zero!"));
|
||||||
} else {
|
} else {
|
||||||
SS.exportScale = (float)ev;
|
SS.exportScale = (float)ev;
|
||||||
}
|
}
|
||||||
|
@ -399,7 +399,7 @@ bool TextWindow::EditControlDoneForConfiguration(const char *s) {
|
||||||
if(e) {
|
if(e) {
|
||||||
double ev = SS.ExprToMm(e);
|
double ev = SS.ExprToMm(e);
|
||||||
if(isnan(ev) || ev < 0) {
|
if(isnan(ev) || ev < 0) {
|
||||||
Error("Cutter radius offset must not be negative!");
|
Error(_("Cutter radius offset must not be negative!"));
|
||||||
} else {
|
} else {
|
||||||
SS.exportOffset = (float)ev;
|
SS.exportOffset = (float)ev;
|
||||||
}
|
}
|
||||||
|
@ -453,10 +453,10 @@ bool TextWindow::EditControlDoneForConfiguration(const char *s) {
|
||||||
SS.autosaveInterval = interval;
|
SS.autosaveInterval = interval;
|
||||||
SetAutosaveTimerFor(interval);
|
SetAutosaveTimerFor(interval);
|
||||||
} else {
|
} else {
|
||||||
Error("Bad value: autosave interval should be positive");
|
Error(_("Bad value: autosave interval should be positive"));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Error("Bad format: specify interval in integral minutes");
|
Error(_("Bad format: specify interval in integral minutes"));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,47 +7,47 @@
|
||||||
#include "solvespace.h"
|
#include "solvespace.h"
|
||||||
|
|
||||||
std::string Constraint::DescriptionString() const {
|
std::string Constraint::DescriptionString() const {
|
||||||
const char *s;
|
std::string s;
|
||||||
switch(type) {
|
switch(type) {
|
||||||
case Type::POINTS_COINCIDENT: s = "pts-coincident"; break;
|
case Type::POINTS_COINCIDENT: s = C_("constr-name", "pts-coincident"); break;
|
||||||
case Type::PT_PT_DISTANCE: s = "pt-pt-distance"; break;
|
case Type::PT_PT_DISTANCE: s = C_("constr-name", "pt-pt-distance"); break;
|
||||||
case Type::PT_LINE_DISTANCE: s = "pt-line-distance"; break;
|
case Type::PT_LINE_DISTANCE: s = C_("constr-name", "pt-line-distance"); break;
|
||||||
case Type::PT_PLANE_DISTANCE: s = "pt-plane-distance"; break;
|
case Type::PT_PLANE_DISTANCE: s = C_("constr-name", "pt-plane-distance"); break;
|
||||||
case Type::PT_FACE_DISTANCE: s = "pt-face-distance"; break;
|
case Type::PT_FACE_DISTANCE: s = C_("constr-name", "pt-face-distance"); break;
|
||||||
case Type::PROJ_PT_DISTANCE: s = "proj-pt-pt-distance"; break;
|
case Type::PROJ_PT_DISTANCE: s = C_("constr-name", "proj-pt-pt-distance"); break;
|
||||||
case Type::PT_IN_PLANE: s = "pt-in-plane"; break;
|
case Type::PT_IN_PLANE: s = C_("constr-name", "pt-in-plane"); break;
|
||||||
case Type::PT_ON_LINE: s = "pt-on-line"; break;
|
case Type::PT_ON_LINE: s = C_("constr-name", "pt-on-line"); break;
|
||||||
case Type::PT_ON_FACE: s = "pt-on-face"; break;
|
case Type::PT_ON_FACE: s = C_("constr-name", "pt-on-face"); break;
|
||||||
case Type::EQUAL_LENGTH_LINES: s = "eq-length"; break;
|
case Type::EQUAL_LENGTH_LINES: s = C_("constr-name", "eq-length"); break;
|
||||||
case Type::EQ_LEN_PT_LINE_D: s = "eq-length-and-pt-ln-dist"; break;
|
case Type::EQ_LEN_PT_LINE_D: s = C_("constr-name", "eq-length-and-pt-ln-dist"); break;
|
||||||
case Type::EQ_PT_LN_DISTANCES: s = "eq-pt-line-distances"; break;
|
case Type::EQ_PT_LN_DISTANCES: s = C_("constr-name", "eq-pt-line-distances"); break;
|
||||||
case Type::LENGTH_RATIO: s = "length-ratio"; break;
|
case Type::LENGTH_RATIO: s = C_("constr-name", "length-ratio"); break;
|
||||||
case Type::LENGTH_DIFFERENCE: s = "length-difference"; break;
|
case Type::LENGTH_DIFFERENCE: s = C_("constr-name", "length-difference"); break;
|
||||||
case Type::SYMMETRIC: s = "symmetric"; break;
|
case Type::SYMMETRIC: s = C_("constr-name", "symmetric"); break;
|
||||||
case Type::SYMMETRIC_HORIZ: s = "symmetric-h"; break;
|
case Type::SYMMETRIC_HORIZ: s = C_("constr-name", "symmetric-h"); break;
|
||||||
case Type::SYMMETRIC_VERT: s = "symmetric-v"; break;
|
case Type::SYMMETRIC_VERT: s = C_("constr-name", "symmetric-v"); break;
|
||||||
case Type::SYMMETRIC_LINE: s = "symmetric-line"; break;
|
case Type::SYMMETRIC_LINE: s = C_("constr-name", "symmetric-line"); break;
|
||||||
case Type::AT_MIDPOINT: s = "at-midpoint"; break;
|
case Type::AT_MIDPOINT: s = C_("constr-name", "at-midpoint"); break;
|
||||||
case Type::HORIZONTAL: s = "horizontal"; break;
|
case Type::HORIZONTAL: s = C_("constr-name", "horizontal"); break;
|
||||||
case Type::VERTICAL: s = "vertical"; break;
|
case Type::VERTICAL: s = C_("constr-name", "vertical"); break;
|
||||||
case Type::DIAMETER: s = "diameter"; break;
|
case Type::DIAMETER: s = C_("constr-name", "diameter"); break;
|
||||||
case Type::PT_ON_CIRCLE: s = "pt-on-circle"; break;
|
case Type::PT_ON_CIRCLE: s = C_("constr-name", "pt-on-circle"); break;
|
||||||
case Type::SAME_ORIENTATION: s = "same-orientation"; break;
|
case Type::SAME_ORIENTATION: s = C_("constr-name", "same-orientation"); break;
|
||||||
case Type::ANGLE: s = "angle"; break;
|
case Type::ANGLE: s = C_("constr-name", "angle"); break;
|
||||||
case Type::PARALLEL: s = "parallel"; break;
|
case Type::PARALLEL: s = C_("constr-name", "parallel"); break;
|
||||||
case Type::ARC_LINE_TANGENT: s = "arc-line-tangent"; break;
|
case Type::ARC_LINE_TANGENT: s = C_("constr-name", "arc-line-tangent"); break;
|
||||||
case Type::CUBIC_LINE_TANGENT: s = "cubic-line-tangent"; break;
|
case Type::CUBIC_LINE_TANGENT: s = C_("constr-name", "cubic-line-tangent"); break;
|
||||||
case Type::CURVE_CURVE_TANGENT: s = "curve-curve-tangent"; break;
|
case Type::CURVE_CURVE_TANGENT: s = C_("constr-name", "curve-curve-tangent"); break;
|
||||||
case Type::PERPENDICULAR: s = "perpendicular"; break;
|
case Type::PERPENDICULAR: s = C_("constr-name", "perpendicular"); break;
|
||||||
case Type::EQUAL_RADIUS: s = "eq-radius"; break;
|
case Type::EQUAL_RADIUS: s = C_("constr-name", "eq-radius"); break;
|
||||||
case Type::EQUAL_ANGLE: s = "eq-angle"; break;
|
case Type::EQUAL_ANGLE: s = C_("constr-name", "eq-angle"); break;
|
||||||
case Type::EQUAL_LINE_ARC_LEN: s = "eq-line-len-arc-len"; break;
|
case Type::EQUAL_LINE_ARC_LEN: s = C_("constr-name", "eq-line-len-arc-len"); break;
|
||||||
case Type::WHERE_DRAGGED: s = "lock-where-dragged"; break;
|
case Type::WHERE_DRAGGED: s = C_("constr-name", "lock-where-dragged"); break;
|
||||||
case Type::COMMENT: s = "comment"; break;
|
case Type::COMMENT: s = C_("constr-name", "comment"); break;
|
||||||
default: s = "???"; break;
|
default: s = "???"; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ssprintf("c%03x-%s", h.v, s);
|
return ssprintf("c%03x-%s", h.v, s.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef LIBRARY
|
#ifndef LIBRARY
|
||||||
|
@ -156,8 +156,7 @@ void Constraint::MenuConstrain(Command id) {
|
||||||
c.type = Type::DIAMETER;
|
c.type = Type::DIAMETER;
|
||||||
c.entityA = gs.entity[0];
|
c.entityA = gs.entity[0];
|
||||||
} else {
|
} else {
|
||||||
Error(
|
Error(_("Bad selection for distance / diameter constraint. This "
|
||||||
"Bad selection for distance / diameter constraint. This "
|
|
||||||
"constraint can apply to:\n\n"
|
"constraint can apply to:\n\n"
|
||||||
" * two points (distance between points)\n"
|
" * two points (distance between points)\n"
|
||||||
" * a line segment (length)\n"
|
" * a line segment (length)\n"
|
||||||
|
@ -165,7 +164,7 @@ void Constraint::MenuConstrain(Command id) {
|
||||||
" * a workplane and a point (minimum distance)\n"
|
" * a workplane and a point (minimum distance)\n"
|
||||||
" * a line segment and a point (minimum distance)\n"
|
" * a line segment and a point (minimum distance)\n"
|
||||||
" * a plane face and a point (minimum distance)\n"
|
" * a plane face and a point (minimum distance)\n"
|
||||||
" * a circle or an arc (diameter)\n");
|
" * a circle or an arc (diameter)\n"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(c.type == Type::PT_PT_DISTANCE || c.type == Type::PROJ_PT_DISTANCE) {
|
if(c.type == Type::PT_PT_DISTANCE || c.type == Type::PROJ_PT_DISTANCE) {
|
||||||
|
@ -210,13 +209,13 @@ void Constraint::MenuConstrain(Command id) {
|
||||||
c.ptA = gs.point[0];
|
c.ptA = gs.point[0];
|
||||||
c.entityA = gs.face[0];
|
c.entityA = gs.face[0];
|
||||||
} else {
|
} else {
|
||||||
Error("Bad selection for on point / curve / plane constraint. "
|
Error(_("Bad selection for on point / curve / plane constraint. "
|
||||||
"This constraint can apply to:\n\n"
|
"This constraint can apply to:\n\n"
|
||||||
" * two points (points coincident)\n"
|
" * two points (points coincident)\n"
|
||||||
" * a point and a workplane (point in plane)\n"
|
" * a point and a workplane (point in plane)\n"
|
||||||
" * a point and a line segment (point on line)\n"
|
" * a point and a line segment (point on line)\n"
|
||||||
" * a point and a circle or arc (point on curve)\n"
|
" * a point and a circle or arc (point on curve)\n"
|
||||||
" * a point and a plane face (point on face)\n");
|
" * a point and a plane face (point on face)\n"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
AddConstraint(&c);
|
AddConstraint(&c);
|
||||||
|
@ -272,7 +271,7 @@ void Constraint::MenuConstrain(Command id) {
|
||||||
c.entityB = gs.entity[1];
|
c.entityB = gs.entity[1];
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Error("Bad selection for equal length / radius constraint. "
|
Error(_("Bad selection for equal length / radius constraint. "
|
||||||
"This constraint can apply to:\n\n"
|
"This constraint can apply to:\n\n"
|
||||||
" * two line segments (equal length)\n"
|
" * two line segments (equal length)\n"
|
||||||
" * two line segments and two points "
|
" * two line segments and two points "
|
||||||
|
@ -287,7 +286,7 @@ void Constraint::MenuConstrain(Command id) {
|
||||||
"(equal angle between A,B and B,C)\n"
|
"(equal angle between A,B and B,C)\n"
|
||||||
" * two circles or arcs (equal radius)\n"
|
" * two circles or arcs (equal radius)\n"
|
||||||
" * a line segment and an arc "
|
" * a line segment and an arc "
|
||||||
"(line segment length equals arc length)\n");
|
"(line segment length equals arc length)\n"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(c.type == Type::EQUAL_ANGLE) {
|
if(c.type == Type::EQUAL_ANGLE) {
|
||||||
|
@ -311,9 +310,9 @@ void Constraint::MenuConstrain(Command id) {
|
||||||
c.entityA = gs.entity[0];
|
c.entityA = gs.entity[0];
|
||||||
c.entityB = gs.entity[1];
|
c.entityB = gs.entity[1];
|
||||||
} else {
|
} else {
|
||||||
Error("Bad selection for length ratio constraint. This "
|
Error(_("Bad selection for length ratio constraint. This "
|
||||||
"constraint can apply to:\n\n"
|
"constraint can apply to:\n\n"
|
||||||
" * two line segments\n");
|
" * two line segments\n"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -328,9 +327,9 @@ void Constraint::MenuConstrain(Command id) {
|
||||||
c.entityA = gs.entity[0];
|
c.entityA = gs.entity[0];
|
||||||
c.entityB = gs.entity[1];
|
c.entityB = gs.entity[1];
|
||||||
} else {
|
} else {
|
||||||
Error("Bad selection for length difference constraint. This "
|
Error(_("Bad selection for length difference constraint. This "
|
||||||
"constraint can apply to:\n\n"
|
"constraint can apply to:\n\n"
|
||||||
" * two line segments\n");
|
" * two line segments\n"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -354,12 +353,12 @@ void Constraint::MenuConstrain(Command id) {
|
||||||
c.entityA = gs.entity[i];
|
c.entityA = gs.entity[i];
|
||||||
c.entityB = gs.entity[1-i];
|
c.entityB = gs.entity[1-i];
|
||||||
} else {
|
} else {
|
||||||
Error("Bad selection for at midpoint constraint. This "
|
Error(_("Bad selection for at midpoint constraint. This "
|
||||||
"constraint can apply to:\n\n"
|
"constraint can apply to:\n\n"
|
||||||
" * a line segment and a point "
|
" * a line segment and a point "
|
||||||
"(point at midpoint)\n"
|
"(point at midpoint)\n"
|
||||||
" * a line segment and a workplane "
|
" * a line segment and a workplane "
|
||||||
"(line's midpoint on plane)\n");
|
"(line's midpoint on plane)\n"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
AddConstraint(&c);
|
AddConstraint(&c);
|
||||||
|
@ -412,22 +411,22 @@ void Constraint::MenuConstrain(Command id) {
|
||||||
c.entityA = gs.entity[0];
|
c.entityA = gs.entity[0];
|
||||||
c.type = Type::SYMMETRIC_LINE;
|
c.type = Type::SYMMETRIC_LINE;
|
||||||
} else {
|
} else {
|
||||||
Error("Bad selection for symmetric constraint. This constraint "
|
Error(_("Bad selection for symmetric constraint. This constraint "
|
||||||
"can apply to:\n\n"
|
"can apply to:\n\n"
|
||||||
" * two points or a line segment "
|
" * two points or a line segment "
|
||||||
"(symmetric about workplane's coordinate axis)\n"
|
"(symmetric about workplane's coordinate axis)\n"
|
||||||
" * line segment, and two points or a line segment "
|
" * line segment, and two points or a line segment "
|
||||||
"(symmetric about line segment)\n"
|
"(symmetric about line segment)\n"
|
||||||
" * workplane, and two points or a line segment "
|
" * workplane, and two points or a line segment "
|
||||||
"(symmetric about workplane)\n");
|
"(symmetric about workplane)\n"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(c.entityA.v == Entity::NO_ENTITY.v) {
|
if(c.entityA.v == Entity::NO_ENTITY.v) {
|
||||||
// Horizontal / vertical symmetry, implicit symmetry plane
|
// Horizontal / vertical symmetry, implicit symmetry plane
|
||||||
// normal to the workplane
|
// normal to the workplane
|
||||||
if(c.workplane.v == Entity::FREE_IN_3D.v) {
|
if(c.workplane.v == Entity::FREE_IN_3D.v) {
|
||||||
Error("A workplane must be active when constraining "
|
Error(_("A workplane must be active when constraining "
|
||||||
"symmetric without an explicit symmetry plane.");
|
"symmetric without an explicit symmetry plane."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Vector pa = SK.GetEntity(c.ptA)->PointGetNum();
|
Vector pa = SK.GetEntity(c.ptA)->PointGetNum();
|
||||||
|
@ -456,8 +455,8 @@ void Constraint::MenuConstrain(Command id) {
|
||||||
case Command::HORIZONTAL: {
|
case Command::HORIZONTAL: {
|
||||||
hEntity ha, hb;
|
hEntity ha, hb;
|
||||||
if(c.workplane.v == Entity::FREE_IN_3D.v) {
|
if(c.workplane.v == Entity::FREE_IN_3D.v) {
|
||||||
Error("Activate a workplane (with Sketch -> In Workplane) before "
|
Error(_("Activate a workplane (with Sketch -> In Workplane) before "
|
||||||
"applying a horizontal or vertical constraint.");
|
"applying a horizontal or vertical constraint."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(gs.lineSegments == 1 && gs.n == 1) {
|
if(gs.lineSegments == 1 && gs.n == 1) {
|
||||||
|
@ -469,10 +468,10 @@ void Constraint::MenuConstrain(Command id) {
|
||||||
ha = c.ptA = gs.point[0];
|
ha = c.ptA = gs.point[0];
|
||||||
hb = c.ptB = gs.point[1];
|
hb = c.ptB = gs.point[1];
|
||||||
} else {
|
} else {
|
||||||
Error("Bad selection for horizontal / vertical constraint. "
|
Error(_("Bad selection for horizontal / vertical constraint. "
|
||||||
"This constraint can apply to:\n\n"
|
"This constraint can apply to:\n\n"
|
||||||
" * two points\n"
|
" * two points\n"
|
||||||
" * a line segment\n");
|
" * a line segment\n"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(id == Command::HORIZONTAL) {
|
if(id == Command::HORIZONTAL) {
|
||||||
|
@ -490,9 +489,9 @@ void Constraint::MenuConstrain(Command id) {
|
||||||
c.entityA = gs.anyNormal[0];
|
c.entityA = gs.anyNormal[0];
|
||||||
c.entityB = gs.anyNormal[1];
|
c.entityB = gs.anyNormal[1];
|
||||||
} else {
|
} else {
|
||||||
Error("Bad selection for same orientation constraint. This "
|
Error(_("Bad selection for same orientation constraint. This "
|
||||||
"constraint can apply to:\n\n"
|
"constraint can apply to:\n\n"
|
||||||
" * two normals\n");
|
" * two normals\n"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
SS.UndoRemember();
|
SS.UndoRemember();
|
||||||
|
@ -542,7 +541,7 @@ void Constraint::MenuConstrain(Command id) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Error("Must select an angle constraint.");
|
Error(_("Must select an angle constraint."));
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case Command::REFERENCE:
|
case Command::REFERENCE:
|
||||||
|
@ -554,7 +553,7 @@ void Constraint::MenuConstrain(Command id) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Error("Must select a constraint with associated label.");
|
Error(_("Must select a constraint with associated label."));
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case Command::ANGLE:
|
case Command::ANGLE:
|
||||||
|
@ -565,11 +564,11 @@ void Constraint::MenuConstrain(Command id) {
|
||||||
c.entityB = gs.vector[1];
|
c.entityB = gs.vector[1];
|
||||||
c.valA = 0;
|
c.valA = 0;
|
||||||
} else {
|
} else {
|
||||||
Error("Bad selection for angle constraint. This constraint "
|
Error(_("Bad selection for angle constraint. This constraint "
|
||||||
"can apply to:\n\n"
|
"can apply to:\n\n"
|
||||||
" * two line segments\n"
|
" * two line segments\n"
|
||||||
" * a line segment and a normal\n"
|
" * a line segment and a normal\n"
|
||||||
" * two normals\n");
|
" * two normals\n"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -622,9 +621,9 @@ void Constraint::MenuConstrain(Command id) {
|
||||||
} else if(l0.Equals(a2) || l1.Equals(a2)) {
|
} else if(l0.Equals(a2) || l1.Equals(a2)) {
|
||||||
c.other = true;
|
c.other = true;
|
||||||
} else {
|
} else {
|
||||||
Error("The tangent arc and line segment must share an "
|
Error(_("The tangent arc and line segment must share an "
|
||||||
"endpoint. Constrain them with Constrain -> "
|
"endpoint. Constrain them with Constrain -> "
|
||||||
"On Point before constraining tangent.");
|
"On Point before constraining tangent."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
c.type = Type::ARC_LINE_TANGENT;
|
c.type = Type::ARC_LINE_TANGENT;
|
||||||
|
@ -646,9 +645,9 @@ void Constraint::MenuConstrain(Command id) {
|
||||||
} else if(l0.Equals(af) || l1.Equals(af)) {
|
} else if(l0.Equals(af) || l1.Equals(af)) {
|
||||||
c.other = true;
|
c.other = true;
|
||||||
} else {
|
} else {
|
||||||
Error("The tangent cubic and line segment must share an "
|
Error(_("The tangent cubic and line segment must share an "
|
||||||
"endpoint. Constrain them with Constrain -> "
|
"endpoint. Constrain them with Constrain -> "
|
||||||
"On Point before constraining tangent.");
|
"On Point before constraining tangent."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
c.type = Type::CUBIC_LINE_TANGENT;
|
c.type = Type::CUBIC_LINE_TANGENT;
|
||||||
|
@ -656,7 +655,7 @@ void Constraint::MenuConstrain(Command id) {
|
||||||
c.entityB = line->h;
|
c.entityB = line->h;
|
||||||
} else if(gs.cubics + gs.arcs == 2 && gs.n == 2) {
|
} else if(gs.cubics + gs.arcs == 2 && gs.n == 2) {
|
||||||
if(!SS.GW.LockedInWorkplane()) {
|
if(!SS.GW.LockedInWorkplane()) {
|
||||||
Error("Curve-curve tangency must apply in workplane.");
|
Error(_("Curve-curve tangency must apply in workplane."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Entity *eA = SK.GetEntity(gs.entity[0]),
|
Entity *eA = SK.GetEntity(gs.entity[0]),
|
||||||
|
@ -674,22 +673,22 @@ void Constraint::MenuConstrain(Command id) {
|
||||||
} else if(af.Equals(bf)) {
|
} else if(af.Equals(bf)) {
|
||||||
c.other = true; c.other2 = true;
|
c.other = true; c.other2 = true;
|
||||||
} else {
|
} else {
|
||||||
Error("The curves must share an endpoint. Constrain them "
|
Error(_("The curves must share an endpoint. Constrain them "
|
||||||
"with Constrain -> On Point before constraining "
|
"with Constrain -> On Point before constraining "
|
||||||
"tangent.");
|
"tangent."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
c.type = Type::CURVE_CURVE_TANGENT;
|
c.type = Type::CURVE_CURVE_TANGENT;
|
||||||
c.entityA = eA->h;
|
c.entityA = eA->h;
|
||||||
c.entityB = eB->h;
|
c.entityB = eB->h;
|
||||||
} else {
|
} else {
|
||||||
Error("Bad selection for parallel / tangent constraint. This "
|
Error(_("Bad selection for parallel / tangent constraint. This "
|
||||||
"constraint can apply to:\n\n"
|
"constraint can apply to:\n\n"
|
||||||
" * two line segments (parallel)\n"
|
" * two line segments (parallel)\n"
|
||||||
" * a line segment and a normal (parallel)\n"
|
" * a line segment and a normal (parallel)\n"
|
||||||
" * two normals (parallel)\n"
|
" * two normals (parallel)\n"
|
||||||
" * two line segments, arcs, or beziers, that share "
|
" * two line segments, arcs, or beziers, that share "
|
||||||
"an endpoint (tangent)\n");
|
"an endpoint (tangent)\n"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
AddConstraint(&c);
|
AddConstraint(&c);
|
||||||
|
@ -701,11 +700,11 @@ void Constraint::MenuConstrain(Command id) {
|
||||||
c.entityA = gs.vector[0];
|
c.entityA = gs.vector[0];
|
||||||
c.entityB = gs.vector[1];
|
c.entityB = gs.vector[1];
|
||||||
} else {
|
} else {
|
||||||
Error("Bad selection for perpendicular constraint. This "
|
Error(_("Bad selection for perpendicular constraint. This "
|
||||||
"constraint can apply to:\n\n"
|
"constraint can apply to:\n\n"
|
||||||
" * two line segments\n"
|
" * two line segments\n"
|
||||||
" * a line segment and a normal\n"
|
" * a line segment and a normal\n"
|
||||||
" * two normals\n");
|
" * two normals\n"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
AddConstraint(&c);
|
AddConstraint(&c);
|
||||||
|
@ -716,9 +715,9 @@ void Constraint::MenuConstrain(Command id) {
|
||||||
c.type = Type::WHERE_DRAGGED;
|
c.type = Type::WHERE_DRAGGED;
|
||||||
c.ptA = gs.point[0];
|
c.ptA = gs.point[0];
|
||||||
} else {
|
} else {
|
||||||
Error("Bad selection for lock point where dragged constraint. "
|
Error(_("Bad selection for lock point where dragged constraint. "
|
||||||
"This constraint can apply to:\n\n"
|
"This constraint can apply to:\n\n"
|
||||||
" * a point\n");
|
" * a point\n"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
AddConstraint(&c);
|
AddConstraint(&c);
|
||||||
|
@ -727,7 +726,7 @@ void Constraint::MenuConstrain(Command id) {
|
||||||
case Command::COMMENT:
|
case Command::COMMENT:
|
||||||
SS.GW.pending.operation = GraphicsWindow::Pending::COMMAND;
|
SS.GW.pending.operation = GraphicsWindow::Pending::COMMAND;
|
||||||
SS.GW.pending.command = Command::COMMENT;
|
SS.GW.pending.command = Command::COMMENT;
|
||||||
SS.GW.pending.description = "click center of comment text";
|
SS.GW.pending.description = _("click center of comment text");
|
||||||
SS.ScheduleShowTW();
|
SS.ScheduleShowTW();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -15,8 +15,8 @@ void SolveSpaceUI::ExportSectionTo(const std::string &filename) {
|
||||||
Group *g = SK.GetGroup(SS.GW.activeGroup);
|
Group *g = SK.GetGroup(SS.GW.activeGroup);
|
||||||
g->GenerateDisplayItems();
|
g->GenerateDisplayItems();
|
||||||
if(g->displayMesh.IsEmpty()) {
|
if(g->displayMesh.IsEmpty()) {
|
||||||
Error("No solid model present; draw one with extrudes and revolves, "
|
Error(_("No solid model present; draw one with extrudes and revolves, "
|
||||||
"or use Export 2d View to export bare lines and curves.");
|
"or use Export 2d View to export bare lines and curves."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,12 +57,12 @@ void SolveSpaceUI::ExportSectionTo(const std::string &filename) {
|
||||||
u = ut.WithMagnitude(1);
|
u = ut.WithMagnitude(1);
|
||||||
v = (n.Cross(u)).WithMagnitude(1);
|
v = (n.Cross(u)).WithMagnitude(1);
|
||||||
} else {
|
} else {
|
||||||
Error("Bad selection for export section. Please select:\n\n"
|
Error(_("Bad selection for export section. Please select:\n\n"
|
||||||
" * nothing, with an active workplane "
|
" * nothing, with an active workplane "
|
||||||
"(workplane is section plane)\n"
|
"(workplane is section plane)\n"
|
||||||
" * a face (section plane through face)\n"
|
" * a face (section plane through face)\n"
|
||||||
" * a point and two line segments "
|
" * a point and two line segments "
|
||||||
"(plane through point and parallel to lines)\n");
|
"(plane through point and parallel to lines)\n"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
SS.GW.ClearSelection();
|
SS.GW.ClearSelection();
|
||||||
|
@ -802,7 +802,7 @@ void SolveSpaceUI::ExportMeshTo(const std::string &filename) {
|
||||||
|
|
||||||
SMesh *m = &(SK.GetGroup(SS.GW.activeGroup)->displayMesh);
|
SMesh *m = &(SK.GetGroup(SS.GW.activeGroup)->displayMesh);
|
||||||
if(m->IsEmpty()) {
|
if(m->IsEmpty()) {
|
||||||
Error("Active group mesh is empty; nothing to export.");
|
Error(_("Active group mesh is empty; nothing to export."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -327,9 +327,9 @@ public:
|
||||||
entity->setWidthMm(Style::WidthMm(hs.v));
|
entity->setWidthMm(Style::WidthMm(hs.v));
|
||||||
|
|
||||||
if(s->stippleType == StipplePattern::FREEHAND) {
|
if(s->stippleType == StipplePattern::FREEHAND) {
|
||||||
messages.insert("freehand lines were replaced with continuous lines");
|
messages.insert(_("freehand lines were replaced with continuous lines"));
|
||||||
} else if(s->stippleType == StipplePattern::ZIGZAG) {
|
} else if(s->stippleType == StipplePattern::ZIGZAG) {
|
||||||
messages.insert("zigzag lines were replaced with continuous lines");
|
messages.insert(_("zigzag lines were replaced with continuous lines"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -580,8 +580,8 @@ void DxfFileWriter::FinishAndCloseFile() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!interface.messages.empty()) {
|
if(!interface.messages.empty()) {
|
||||||
std::string text = "Some aspects of the drawing have no DXF equivalent and "
|
std::string text = _("Some aspects of the drawing have no DXF equivalent and "
|
||||||
"were not exported:\n";
|
"were not exported:\n");
|
||||||
for(const std::string &message : interface.messages) {
|
for(const std::string &message : interface.messages) {
|
||||||
text += " * " + message + "\n";
|
text += " * " + message + "\n";
|
||||||
}
|
}
|
||||||
|
@ -797,8 +797,8 @@ void PdfFileWriter::StartFile() {
|
||||||
if((ptMax.x - ptMin.x) > 200*25.4 ||
|
if((ptMax.x - ptMin.x) > 200*25.4 ||
|
||||||
(ptMax.y - ptMin.y) > 200*25.4)
|
(ptMax.y - ptMin.y) > 200*25.4)
|
||||||
{
|
{
|
||||||
Message("PDF page size exceeds 200 by 200 inches; many viewers may "
|
Message(_("PDF page size exceeds 200 by 200 inches; many viewers may "
|
||||||
"reject this file.");
|
"reject this file."));
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(f,
|
fprintf(f,
|
||||||
|
|
|
@ -40,7 +40,7 @@ hGroup SolveSpaceUI::CreateDefaultDrawingGroup() {
|
||||||
|
|
||||||
// And an empty group, for the first stuff the user draws.
|
// And an empty group, for the first stuff the user draws.
|
||||||
g.visible = true;
|
g.visible = true;
|
||||||
g.name = "sketch-in-plane";
|
g.name = C_("group-name", "sketch-in-plane");
|
||||||
g.type = Group::Type::DRAWING_WORKPLANE;
|
g.type = Group::Type::DRAWING_WORKPLANE;
|
||||||
g.subtype = Group::Subtype::WORKPLANE_BY_POINT_ORTHO;
|
g.subtype = Group::Subtype::WORKPLANE_BY_POINT_ORTHO;
|
||||||
g.order = 1;
|
g.order = 1;
|
||||||
|
@ -58,7 +58,7 @@ void SolveSpaceUI::NewFile() {
|
||||||
// Our initial group, that contains the references.
|
// Our initial group, that contains the references.
|
||||||
Group g = {};
|
Group g = {};
|
||||||
g.visible = true;
|
g.visible = true;
|
||||||
g.name = "#references";
|
g.name = C_("group-name", "#references");
|
||||||
g.type = Group::Type::DRAWING_3D;
|
g.type = Group::Type::DRAWING_3D;
|
||||||
g.order = 0;
|
g.order = 0;
|
||||||
g.h = Group::HGROUP_REFERENCES;
|
g.h = Group::HGROUP_REFERENCES;
|
||||||
|
@ -505,8 +505,8 @@ bool SolveSpaceUI::LoadFromFile(const std::string &filename, bool canCancel) {
|
||||||
fclose(fh);
|
fclose(fh);
|
||||||
|
|
||||||
if(fileLoadError) {
|
if(fileLoadError) {
|
||||||
Error("Unrecognized data in file. This file may be corrupt, or "
|
Error(_("Unrecognized data in file. This file may be corrupt, or "
|
||||||
"from a new version of the program.");
|
"from a newer version of the program."));
|
||||||
// At least leave the program in a non-crashing state.
|
// At least leave the program in a non-crashing state.
|
||||||
if(SK.group.n == 0) {
|
if(SK.group.n == 0) {
|
||||||
NewFile();
|
NewFile();
|
||||||
|
|
|
@ -489,8 +489,7 @@ void GraphicsWindow::MenuView(Command id) {
|
||||||
case Command::SHOW_GRID:
|
case Command::SHOW_GRID:
|
||||||
SS.GW.showSnapGrid = !SS.GW.showSnapGrid;
|
SS.GW.showSnapGrid = !SS.GW.showSnapGrid;
|
||||||
if(SS.GW.showSnapGrid && !SS.GW.LockedInWorkplane()) {
|
if(SS.GW.showSnapGrid && !SS.GW.LockedInWorkplane()) {
|
||||||
Message("No workplane is active, so the grid will not "
|
Message(_("No workplane is active, so the grid will not appear."));
|
||||||
"appear.");
|
|
||||||
}
|
}
|
||||||
SS.GW.EnsureValidActives();
|
SS.GW.EnsureValidActives();
|
||||||
InvalidateGraphics();
|
InvalidateGraphics();
|
||||||
|
@ -499,11 +498,11 @@ void GraphicsWindow::MenuView(Command id) {
|
||||||
case Command::PERSPECTIVE_PROJ:
|
case Command::PERSPECTIVE_PROJ:
|
||||||
SS.usePerspectiveProj = !SS.usePerspectiveProj;
|
SS.usePerspectiveProj = !SS.usePerspectiveProj;
|
||||||
if(SS.cameraTangent < 1e-6) {
|
if(SS.cameraTangent < 1e-6) {
|
||||||
Error("The perspective factor is set to zero, so the view will "
|
Error(_("The perspective factor is set to zero, so the view will "
|
||||||
"always be a parallel projection.\n\n"
|
"always be a parallel projection.\n\n"
|
||||||
"For a perspective projection, modify the perspective "
|
"For a perspective projection, modify the perspective "
|
||||||
"factor in the configuration screen. A value around 0.3 "
|
"factor in the configuration screen. A value around 0.3 "
|
||||||
"is typical.");
|
"is typical."));
|
||||||
}
|
}
|
||||||
SS.GW.EnsureValidActives();
|
SS.GW.EnsureValidActives();
|
||||||
InvalidateGraphics();
|
InvalidateGraphics();
|
||||||
|
@ -580,8 +579,8 @@ void GraphicsWindow::MenuView(Command id) {
|
||||||
SS.GW.AnimateOnto(quat0, pt.ScaledBy(-1));
|
SS.GW.AnimateOnto(quat0, pt.ScaledBy(-1));
|
||||||
SS.GW.ClearSelection();
|
SS.GW.ClearSelection();
|
||||||
} else {
|
} else {
|
||||||
Error("Select a point; this point will become the center "
|
Error(_("Select a point; this point will become the center "
|
||||||
"of the view on screen.");
|
"of the view on screen."));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -862,8 +861,7 @@ void GraphicsWindow::MenuEdit(Command id) {
|
||||||
}
|
}
|
||||||
} while(didSomething);
|
} while(didSomething);
|
||||||
if(newlySelected == 0) {
|
if(newlySelected == 0) {
|
||||||
Error("No additional entities share endpoints with the "
|
Error(_("No additional entities share endpoints with the selected entities."));
|
||||||
"selected entities.");
|
|
||||||
}
|
}
|
||||||
InvalidateGraphics();
|
InvalidateGraphics();
|
||||||
SS.ScheduleShowTW();
|
SS.ScheduleShowTW();
|
||||||
|
@ -883,9 +881,9 @@ void GraphicsWindow::MenuEdit(Command id) {
|
||||||
hGroup hg = e ? e->group : SS.GW.activeGroup;
|
hGroup hg = e ? e->group : SS.GW.activeGroup;
|
||||||
Group *g = SK.GetGroup(hg);
|
Group *g = SK.GetGroup(hg);
|
||||||
if(g->type != Group::Type::LINKED) {
|
if(g->type != Group::Type::LINKED) {
|
||||||
Error("To use this command, select a point or other "
|
Error(_("To use this command, select a point or other "
|
||||||
"entity from an linked part, or make a link "
|
"entity from an linked part, or make a link "
|
||||||
"group the active group.");
|
"group the active group."));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -907,16 +905,16 @@ void GraphicsWindow::MenuEdit(Command id) {
|
||||||
|
|
||||||
case Command::SNAP_TO_GRID: {
|
case Command::SNAP_TO_GRID: {
|
||||||
if(!SS.GW.LockedInWorkplane()) {
|
if(!SS.GW.LockedInWorkplane()) {
|
||||||
Error("No workplane is active. Activate a workplane "
|
Error(_("No workplane is active. Activate a workplane "
|
||||||
"(with Sketch -> In Workplane) to define the plane "
|
"(with Sketch -> In Workplane) to define the plane "
|
||||||
"for the snap grid.");
|
"for the snap grid."));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
SS.GW.GroupSelection();
|
SS.GW.GroupSelection();
|
||||||
if(SS.GW.gs.points == 0 && SS.GW.gs.constraintLabels == 0) {
|
if(SS.GW.gs.points == 0 && SS.GW.gs.constraintLabels == 0) {
|
||||||
Error("Can't snap these items to grid; select points, "
|
Error(_("Can't snap these items to grid; select points, "
|
||||||
"text comments, or constraints with a label. "
|
"text comments, or constraints with a label. "
|
||||||
"To snap a line, select its endpoints.");
|
"To snap a line, select its endpoints."));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
SS.UndoRemember();
|
SS.UndoRemember();
|
||||||
|
@ -979,15 +977,15 @@ void GraphicsWindow::MenuRequest(Command id) {
|
||||||
} else if(g->type == Group::Type::DRAWING_WORKPLANE) {
|
} else if(g->type == Group::Type::DRAWING_WORKPLANE) {
|
||||||
// The group's default workplane
|
// The group's default workplane
|
||||||
g->activeWorkplane = g->h.entity(0);
|
g->activeWorkplane = g->h.entity(0);
|
||||||
Message("No workplane selected. Activating default workplane "
|
Message(_("No workplane selected. Activating default workplane "
|
||||||
"for this group.");
|
"for this group."));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!SS.GW.LockedInWorkplane()) {
|
if(!SS.GW.LockedInWorkplane()) {
|
||||||
Error("No workplane is selected, and the active group does "
|
Error(_("No workplane is selected, and the active group does "
|
||||||
"not have a default workplane. Try selecting a "
|
"not have a default workplane. Try selecting a "
|
||||||
"workplane, or activating a sketch-in-new-workplane "
|
"workplane, or activating a sketch-in-new-workplane "
|
||||||
"group.");
|
"group."));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// Align the view with the selected workplane
|
// Align the view with the selected workplane
|
||||||
|
@ -1008,9 +1006,9 @@ void GraphicsWindow::MenuRequest(Command id) {
|
||||||
if(SS.GW.gs.n == 1 && SS.GW.gs.points == 1) {
|
if(SS.GW.gs.n == 1 && SS.GW.gs.points == 1) {
|
||||||
SS.GW.MakeTangentArc();
|
SS.GW.MakeTangentArc();
|
||||||
} else if(SS.GW.gs.n != 0) {
|
} else if(SS.GW.gs.n != 0) {
|
||||||
Error("Bad selection for tangent arc at point. Select a "
|
Error(_("Bad selection for tangent arc at point. Select a "
|
||||||
"single point, or select nothing to set up arc "
|
"single point, or select nothing to set up arc "
|
||||||
"parameters.");
|
"parameters."));
|
||||||
} else {
|
} else {
|
||||||
SS.TW.GoToScreen(TextWindow::Screen::TANGENT_ARC);
|
SS.TW.GoToScreen(TextWindow::Screen::TANGENT_ARC);
|
||||||
SS.GW.ForceTextWindowShown();
|
SS.GW.ForceTextWindowShown();
|
||||||
|
@ -1019,15 +1017,16 @@ void GraphicsWindow::MenuRequest(Command id) {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Command::ARC: s = "click point on arc (draws anti-clockwise)"; goto c;
|
case Command::ARC: s = _("click point on arc (draws anti-clockwise)"); goto c;
|
||||||
case Command::DATUM_POINT: s = "click to place datum point"; goto c;
|
case Command::DATUM_POINT: s = _("click to place datum point"); goto c;
|
||||||
case Command::LINE_SEGMENT: s = "click first point of line segment"; goto c;
|
case Command::LINE_SEGMENT: s = _("click first point of line segment"); goto c;
|
||||||
case Command::CONSTR_SEGMENT: s = "click first point of construction line segment"; goto c;
|
case Command::CONSTR_SEGMENT:
|
||||||
case Command::CUBIC: s = "click first point of cubic segment"; goto c;
|
s = _("click first point of construction line segment"); goto c;
|
||||||
case Command::CIRCLE: s = "click center of circle"; goto c;
|
case Command::CUBIC: s = _("click first point of cubic segment"); goto c;
|
||||||
case Command::WORKPLANE: s = "click origin of workplane"; goto c;
|
case Command::CIRCLE: s = _("click center of circle"); goto c;
|
||||||
case Command::RECTANGLE: s = "click one corner of rectangle"; goto c;
|
case Command::WORKPLANE: s = _("click origin of workplane"); goto c;
|
||||||
case Command::TTF_TEXT: s = "click top left of text"; goto c;
|
case Command::RECTANGLE: s = _("click one corner of rectangle"); goto c;
|
||||||
|
case Command::TTF_TEXT: s = _("click top left of text"); goto c;
|
||||||
c:
|
c:
|
||||||
SS.GW.pending.operation = GraphicsWindow::Pending::COMMAND;
|
SS.GW.pending.operation = GraphicsWindow::Pending::COMMAND;
|
||||||
SS.GW.pending.command = id;
|
SS.GW.pending.command = id;
|
||||||
|
@ -1040,8 +1039,8 @@ c:
|
||||||
SS.UndoRemember();
|
SS.UndoRemember();
|
||||||
SS.GW.GroupSelection();
|
SS.GW.GroupSelection();
|
||||||
if(SS.GW.gs.entities == 0) {
|
if(SS.GW.gs.entities == 0) {
|
||||||
Error("No entities are selected. Select entities before "
|
Error(_("No entities are selected. Select entities before "
|
||||||
"trying to toggle their construction state.");
|
"trying to toggle their construction state."));
|
||||||
}
|
}
|
||||||
int i;
|
int i;
|
||||||
for(i = 0; i < SS.GW.gs.entities; i++) {
|
for(i = 0; i < SS.GW.gs.entities; i++) {
|
||||||
|
|
|
@ -86,12 +86,12 @@ void Group::MenuGroup(Command id) {
|
||||||
switch(id) {
|
switch(id) {
|
||||||
case Command::GROUP_3D:
|
case Command::GROUP_3D:
|
||||||
g.type = Type::DRAWING_3D;
|
g.type = Type::DRAWING_3D;
|
||||||
g.name = "sketch-in-3d";
|
g.name = C_("group-name", "sketch-in-3d");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Command::GROUP_WRKPL:
|
case Command::GROUP_WRKPL:
|
||||||
g.type = Type::DRAWING_WORKPLANE;
|
g.type = Type::DRAWING_WORKPLANE;
|
||||||
g.name = "sketch-in-plane";
|
g.name = C_("group-name", "sketch-in-plane");
|
||||||
if(gs.points == 1 && gs.n == 1) {
|
if(gs.points == 1 && gs.n == 1) {
|
||||||
g.subtype = Subtype::WORKPLANE_BY_POINT_ORTHO;
|
g.subtype = Subtype::WORKPLANE_BY_POINT_ORTHO;
|
||||||
|
|
||||||
|
@ -142,28 +142,28 @@ void Group::MenuGroup(Command id) {
|
||||||
} else ssassert(false, "Unexpected workplane subtype");
|
} else ssassert(false, "Unexpected workplane subtype");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Error("Bad selection for new sketch in workplane. This "
|
Error(_("Bad selection for new sketch in workplane. This "
|
||||||
"group can be created with:\n\n"
|
"group can be created with:\n\n"
|
||||||
" * a point (through the point, orthogonal to coordinate axes)\n"
|
" * a point (through the point, orthogonal to coordinate axes)\n"
|
||||||
" * a point and two line segments (through the point, "
|
" * a point and two line segments (through the point, "
|
||||||
"parallel to the lines)\n"
|
"parallel to the lines)\n"
|
||||||
" * a workplane (copy of the workplane)\n");
|
" * a workplane (copy of the workplane)\n"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Command::GROUP_EXTRUDE:
|
case Command::GROUP_EXTRUDE:
|
||||||
if(!SS.GW.LockedInWorkplane()) {
|
if(!SS.GW.LockedInWorkplane()) {
|
||||||
Error("Activate a workplane (Sketch -> In Workplane) before "
|
Error(_("Activate a workplane (Sketch -> In Workplane) before "
|
||||||
"extruding. The sketch will be extruded normal to the "
|
"extruding. The sketch will be extruded normal to the "
|
||||||
"workplane.");
|
"workplane."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
g.type = Type::EXTRUDE;
|
g.type = Type::EXTRUDE;
|
||||||
g.opA = SS.GW.activeGroup;
|
g.opA = SS.GW.activeGroup;
|
||||||
g.predef.entityB = SS.GW.ActiveWorkplane();
|
g.predef.entityB = SS.GW.ActiveWorkplane();
|
||||||
g.subtype = Subtype::ONE_SIDED;
|
g.subtype = Subtype::ONE_SIDED;
|
||||||
g.name = "extrude";
|
g.name = C_("group-name", "extrude");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Command::GROUP_LATHE:
|
case Command::GROUP_LATHE:
|
||||||
|
@ -175,17 +175,17 @@ void Group::MenuGroup(Command id) {
|
||||||
g.predef.entityB = gs.entity[0];
|
g.predef.entityB = gs.entity[0];
|
||||||
// since a line segment is a vector
|
// since a line segment is a vector
|
||||||
} else {
|
} else {
|
||||||
Error("Bad selection for new lathe group. This group can "
|
Error(_("Bad selection for new lathe group. This group can "
|
||||||
"be created with:\n\n"
|
"be created with:\n\n"
|
||||||
" * a point and a line segment or normal "
|
" * a point and a line segment or normal "
|
||||||
"(revolved about an axis parallel to line / "
|
"(revolved about an axis parallel to line / "
|
||||||
"normal, through point)\n"
|
"normal, through point)\n"
|
||||||
" * a line segment (revolved about line segment)\n");
|
" * a line segment (revolved about line segment)\n"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
g.type = Type::LATHE;
|
g.type = Type::LATHE;
|
||||||
g.opA = SS.GW.activeGroup;
|
g.opA = SS.GW.activeGroup;
|
||||||
g.name = "lathe";
|
g.name = C_("group-name", "lathe");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Command::GROUP_ROT: {
|
case Command::GROUP_ROT: {
|
||||||
|
@ -198,20 +198,20 @@ void Group::MenuGroup(Command id) {
|
||||||
g.predef.origin = gs.point[0];
|
g.predef.origin = gs.point[0];
|
||||||
g.predef.entityB = gs.vector[0];
|
g.predef.entityB = gs.vector[0];
|
||||||
} else {
|
} else {
|
||||||
Error("Bad selection for new rotation. This group can "
|
Error(_("Bad selection for new rotation. This group can "
|
||||||
"be created with:\n\n"
|
"be created with:\n\n"
|
||||||
" * a point, while locked in workplane (rotate "
|
" * a point, while locked in workplane (rotate "
|
||||||
"in plane, about that point)\n"
|
"in plane, about that point)\n"
|
||||||
" * a point and a line or a normal (rotate about "
|
" * a point and a line or a normal (rotate about "
|
||||||
"an axis through the point, and parallel to "
|
"an axis through the point, and parallel to "
|
||||||
"line / normal)\n");
|
"line / normal)\n"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
g.type = Type::ROTATE;
|
g.type = Type::ROTATE;
|
||||||
g.opA = SS.GW.activeGroup;
|
g.opA = SS.GW.activeGroup;
|
||||||
g.valA = 3;
|
g.valA = 3;
|
||||||
g.subtype = Subtype::ONE_SIDED;
|
g.subtype = Subtype::ONE_SIDED;
|
||||||
g.name = "rotate";
|
g.name = C_("group-name", "rotate");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -222,7 +222,7 @@ void Group::MenuGroup(Command id) {
|
||||||
g.subtype = Subtype::ONE_SIDED;
|
g.subtype = Subtype::ONE_SIDED;
|
||||||
g.predef.entityB = SS.GW.ActiveWorkplane();
|
g.predef.entityB = SS.GW.ActiveWorkplane();
|
||||||
g.activeWorkplane = SS.GW.ActiveWorkplane();
|
g.activeWorkplane = SS.GW.ActiveWorkplane();
|
||||||
g.name = "translate";
|
g.name = C_("group-name", "translate");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Command::GROUP_LINK: {
|
case Command::GROUP_LINK: {
|
||||||
|
@ -254,7 +254,7 @@ void Group::MenuGroup(Command id) {
|
||||||
if(groupName.length() > 0) {
|
if(groupName.length() > 0) {
|
||||||
g.name = groupName;
|
g.name = groupName;
|
||||||
} else {
|
} else {
|
||||||
g.name = "link";
|
g.name = C_("group-name", "link");
|
||||||
}
|
}
|
||||||
|
|
||||||
g.meshCombine = CombineAs::ASSEMBLE;
|
g.meshCombine = CombineAs::ASSEMBLE;
|
||||||
|
@ -336,7 +336,7 @@ void Group::TransformImportedBy(Vector t, Quaternion q) {
|
||||||
|
|
||||||
std::string Group::DescriptionString() {
|
std::string Group::DescriptionString() {
|
||||||
if(name.empty()) {
|
if(name.empty()) {
|
||||||
return ssprintf("g%03x-(unnamed)", h.v);
|
return ssprintf("g%03x-%s", h.v, _("(unnamed)"));
|
||||||
} else {
|
} else {
|
||||||
return ssprintf("g%03x-%s", h.v, name.c_str());
|
return ssprintf("g%03x-%s", h.v, name.c_str());
|
||||||
}
|
}
|
||||||
|
|
|
@ -604,7 +604,8 @@ void Group::DrawPolyError(Canvas *canvas) {
|
||||||
// Report this error only in sketch-in-workplane groups; otherwise
|
// Report this error only in sketch-in-workplane groups; otherwise
|
||||||
// it's just a nuisance.
|
// it's just a nuisance.
|
||||||
if(type == Type::DRAWING_WORKPLANE) {
|
if(type == Type::DRAWING_WORKPLANE) {
|
||||||
canvas->DrawVectorText("not closed contour, or not all same style!", textHeight,
|
canvas->DrawVectorText(_("not closed contour, or not all same style!"),
|
||||||
|
textHeight,
|
||||||
polyError.notClosedAt.b, camera.projRight, camera.projUp,
|
polyError.notClosedAt.b, camera.projRight, camera.projUp,
|
||||||
hcsError);
|
hcsError);
|
||||||
canvas->DrawLine(polyError.notClosedAt.a, polyError.notClosedAt.b, hcsUnclosed);
|
canvas->DrawLine(polyError.notClosedAt.a, polyError.notClosedAt.b, hcsUnclosed);
|
||||||
|
@ -616,11 +617,11 @@ void Group::DrawPolyError(Canvas *canvas) {
|
||||||
if(type == Type::DRAWING_WORKPLANE) {
|
if(type == Type::DRAWING_WORKPLANE) {
|
||||||
const char *msg;
|
const char *msg;
|
||||||
if(polyError.how == PolyError::NOT_COPLANAR) {
|
if(polyError.how == PolyError::NOT_COPLANAR) {
|
||||||
msg = "points not all coplanar!";
|
msg = _("points not all coplanar!");
|
||||||
} else if(polyError.how == PolyError::SELF_INTERSECTING) {
|
} else if(polyError.how == PolyError::SELF_INTERSECTING) {
|
||||||
msg = "contour is self-intersecting!";
|
msg = _("contour is self-intersecting!");
|
||||||
} else {
|
} else {
|
||||||
msg = "zero-length edge!";
|
msg = _("zero-length edge!");
|
||||||
}
|
}
|
||||||
canvas->DrawVectorText(msg, textHeight,
|
canvas->DrawVectorText(msg, textHeight,
|
||||||
polyError.errorPointAt, camera.projRight, camera.projUp,
|
polyError.errorPointAt, camera.projRight, camera.projUp,
|
||||||
|
|
|
@ -234,8 +234,7 @@ void GraphicsWindow::ParametricCurve::ConstrainPointIfCoincident(hEntity hpt) {
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void GraphicsWindow::MakeTangentArc() {
|
void GraphicsWindow::MakeTangentArc() {
|
||||||
if(!LockedInWorkplane()) {
|
if(!LockedInWorkplane()) {
|
||||||
Error("Must be sketching in workplane to create tangent "
|
Error(_("Must be sketching in workplane to create tangent arc."));
|
||||||
"arc.");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -282,9 +281,9 @@ void GraphicsWindow::MakeTangentArc() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(c != 2) {
|
if(c != 2) {
|
||||||
Error("To create a tangent arc, select a point where two "
|
Error(_("To create a tangent arc, select a point where two "
|
||||||
"non-construction lines or circles in this group and "
|
"non-construction lines or circles in this group and "
|
||||||
"workplane join.");
|
"workplane join."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -369,9 +368,9 @@ void GraphicsWindow::MakeTangentArc() {
|
||||||
t[0] > 0.99 || t[1] > 0.99 ||
|
t[0] > 0.99 || t[1] > 0.99 ||
|
||||||
isnan(t[0]) || isnan(t[1]))
|
isnan(t[0]) || isnan(t[1]))
|
||||||
{
|
{
|
||||||
Error("Couldn't round this corner. Try a smaller radius, or try "
|
Error(_("Couldn't round this corner. Try a smaller radius, or try "
|
||||||
"creating the desired geometry by hand with tangency "
|
"creating the desired geometry by hand with tangency "
|
||||||
"constraints.");
|
"constraints."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -573,7 +572,7 @@ hEntity GraphicsWindow::SplitEntity(hEntity he, Vector pinter) {
|
||||||
} else if(e->type == Entity::Type::CUBIC || e->type == Entity::Type::CUBIC_PERIODIC) {
|
} else if(e->type == Entity::Type::CUBIC || e->type == Entity::Type::CUBIC_PERIODIC) {
|
||||||
ret = SplitCubic(he, pinter);
|
ret = SplitCubic(he, pinter);
|
||||||
} else {
|
} else {
|
||||||
Error("Couldn't split this entity; lines, circles, or cubics only.");
|
Error(_("Couldn't split this entity; lines, circles, or cubics only."));
|
||||||
return Entity::NO_ENTITY;
|
return Entity::NO_ENTITY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -599,7 +598,7 @@ hEntity GraphicsWindow::SplitEntity(hEntity he, Vector pinter) {
|
||||||
|
|
||||||
void GraphicsWindow::SplitLinesOrCurves() {
|
void GraphicsWindow::SplitLinesOrCurves() {
|
||||||
if(!LockedInWorkplane()) {
|
if(!LockedInWorkplane()) {
|
||||||
Error("Must be sketching in workplane to split.");
|
Error(_("Must be sketching in workplane to split."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -609,8 +608,8 @@ void GraphicsWindow::SplitLinesOrCurves() {
|
||||||
gs.cubics +
|
gs.cubics +
|
||||||
gs.periodicCubics) == 2))
|
gs.periodicCubics) == 2))
|
||||||
{
|
{
|
||||||
Error("Select two entities that intersect each other (e.g. two lines "
|
Error(_("Select two entities that intersect each other (e.g. two lines "
|
||||||
"or two circles or a circle and a line).");
|
"or two circles or a circle and a line)."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -653,7 +652,7 @@ void GraphicsWindow::SplitLinesOrCurves() {
|
||||||
Constraint::ConstrainCoincident(hia, hib);
|
Constraint::ConstrainCoincident(hia, hib);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Error("Can't split; no intersection found.");
|
Error(_("Can't split; no intersection found."));
|
||||||
}
|
}
|
||||||
|
|
||||||
// All done, clean up and regenerate.
|
// All done, clean up and regenerate.
|
||||||
|
|
|
@ -775,7 +775,7 @@ void GraphicsWindow::MouseRightUp(double x, double y) {
|
||||||
SS.MarkGroupDirtyByEntity(gs.entity[0]);
|
SS.MarkGroupDirtyByEntity(gs.entity[0]);
|
||||||
ClearSelection();
|
ClearSelection();
|
||||||
} else {
|
} else {
|
||||||
Error("Cannot add spline point: maximum number of points reached.");
|
Error(_("Cannot add spline point: maximum number of points reached."));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -945,14 +945,14 @@ void GraphicsWindow::MouseLeftDown(double mx, double my) {
|
||||||
pending.operation = Pending::DRAGGING_NEW_LINE_POINT;
|
pending.operation = Pending::DRAGGING_NEW_LINE_POINT;
|
||||||
pending.request = hr;
|
pending.request = hr;
|
||||||
pending.point = hr.entity(2);
|
pending.point = hr.entity(2);
|
||||||
pending.description = "click next point of line, or press Esc";
|
pending.description = _("click next point of line, or press Esc");
|
||||||
SK.GetEntity(pending.point)->PointForceTo(v);
|
SK.GetEntity(pending.point)->PointForceTo(v);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Command::RECTANGLE: {
|
case Command::RECTANGLE: {
|
||||||
if(!SS.GW.LockedInWorkplane()) {
|
if(!SS.GW.LockedInWorkplane()) {
|
||||||
Error("Can't draw rectangle in 3d; first, activate a workplane "
|
Error(_("Can't draw rectangle in 3d; first, activate a workplane "
|
||||||
"with Sketch -> In Workplane.");
|
"with Sketch -> In Workplane."));
|
||||||
ClearSuper();
|
ClearSuper();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -978,7 +978,7 @@ void GraphicsWindow::MouseLeftDown(double mx, double my) {
|
||||||
|
|
||||||
pending.operation = Pending::DRAGGING_NEW_POINT;
|
pending.operation = Pending::DRAGGING_NEW_POINT;
|
||||||
pending.point = lns[1].entity(2);
|
pending.point = lns[1].entity(2);
|
||||||
pending.description = "click to place other corner of rectangle";
|
pending.description = _("click to place other corner of rectangle");
|
||||||
hr = lns[0];
|
hr = lns[0];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -998,13 +998,13 @@ void GraphicsWindow::MouseLeftDown(double mx, double my) {
|
||||||
|
|
||||||
pending.operation = Pending::DRAGGING_NEW_RADIUS;
|
pending.operation = Pending::DRAGGING_NEW_RADIUS;
|
||||||
pending.circle = hr.entity(0);
|
pending.circle = hr.entity(0);
|
||||||
pending.description = "click to set radius";
|
pending.description = _("click to set radius");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Command::ARC: {
|
case Command::ARC: {
|
||||||
if(!SS.GW.LockedInWorkplane()) {
|
if(!SS.GW.LockedInWorkplane()) {
|
||||||
Error("Can't draw arc in 3d; first, activate a workplane "
|
Error(_("Can't draw arc in 3d; first, activate a workplane "
|
||||||
"with Sketch -> In Workplane.");
|
"with Sketch -> In Workplane."));
|
||||||
ClearPending();
|
ClearPending();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1021,7 +1021,7 @@ void GraphicsWindow::MouseLeftDown(double mx, double my) {
|
||||||
|
|
||||||
pending.operation = Pending::DRAGGING_NEW_ARC_POINT;
|
pending.operation = Pending::DRAGGING_NEW_ARC_POINT;
|
||||||
pending.point = hr.entity(3);
|
pending.point = hr.entity(3);
|
||||||
pending.description = "click to place point";
|
pending.description = _("click to place point");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Command::CUBIC:
|
case Command::CUBIC:
|
||||||
|
@ -1036,13 +1036,13 @@ void GraphicsWindow::MouseLeftDown(double mx, double my) {
|
||||||
|
|
||||||
pending.operation = Pending::DRAGGING_NEW_CUBIC_POINT;
|
pending.operation = Pending::DRAGGING_NEW_CUBIC_POINT;
|
||||||
pending.point = hr.entity(4);
|
pending.point = hr.entity(4);
|
||||||
pending.description = "click next point of cubic, or press Esc";
|
pending.description = _("click next point of cubic, or press Esc");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Command::WORKPLANE:
|
case Command::WORKPLANE:
|
||||||
if(LockedInWorkplane()) {
|
if(LockedInWorkplane()) {
|
||||||
Error("Sketching in a workplane already; sketch in 3d before "
|
Error(_("Sketching in a workplane already; sketch in 3d before "
|
||||||
"creating new workplane.");
|
"creating new workplane."));
|
||||||
ClearSuper();
|
ClearSuper();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1057,8 +1057,8 @@ void GraphicsWindow::MouseLeftDown(double mx, double my) {
|
||||||
|
|
||||||
case Command::TTF_TEXT: {
|
case Command::TTF_TEXT: {
|
||||||
if(!SS.GW.LockedInWorkplane()) {
|
if(!SS.GW.LockedInWorkplane()) {
|
||||||
Error("Can't draw text in 3d; first, activate a workplane "
|
Error(_("Can't draw text in 3d; first, activate a workplane "
|
||||||
"with Sketch -> In Workplane.");
|
"with Sketch -> In Workplane."));
|
||||||
ClearSuper();
|
ClearSuper();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1072,7 +1072,7 @@ void GraphicsWindow::MouseLeftDown(double mx, double my) {
|
||||||
|
|
||||||
pending.operation = Pending::DRAGGING_NEW_POINT;
|
pending.operation = Pending::DRAGGING_NEW_POINT;
|
||||||
pending.point = hr.entity(2);
|
pending.point = hr.entity(2);
|
||||||
pending.description = "click to place bottom left of text";
|
pending.description = _("click to place bottom left of text");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1083,7 +1083,7 @@ void GraphicsWindow::MouseLeftDown(double mx, double my) {
|
||||||
c.workplane = SS.GW.ActiveWorkplane();
|
c.workplane = SS.GW.ActiveWorkplane();
|
||||||
c.type = Constraint::Type::COMMENT;
|
c.type = Constraint::Type::COMMENT;
|
||||||
c.disp.offset = v;
|
c.disp.offset = v;
|
||||||
c.comment = "NEW COMMENT -- DOUBLE-CLICK TO EDIT";
|
c.comment = _("NEW COMMENT -- DOUBLE-CLICK TO EDIT");
|
||||||
hc = Constraint::AddConstraint(&c);
|
hc = Constraint::AddConstraint(&c);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1196,7 +1196,7 @@ void GraphicsWindow::MouseLeftDown(double mx, double my) {
|
||||||
pending.operation = Pending::DRAGGING_NEW_LINE_POINT;
|
pending.operation = Pending::DRAGGING_NEW_LINE_POINT;
|
||||||
pending.request = hr;
|
pending.request = hr;
|
||||||
pending.point = hr.entity(2);
|
pending.point = hr.entity(2);
|
||||||
pending.description = "click next point of line, or press Esc";
|
pending.description = _("click next point of line, or press Esc");
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1254,6 +1254,25 @@ unsigned PluralExpr::Eval(const std::string &s, unsigned n) {
|
||||||
return t.value;
|
return t.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Gettext message keys
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
class TranslationKey {
|
||||||
|
public:
|
||||||
|
bool hasContext;
|
||||||
|
std::string context;
|
||||||
|
std::string ident;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TranslationKeyLess {
|
||||||
|
bool operator()(const TranslationKey &a, const TranslationKey &b) const {
|
||||||
|
return a.hasContext < b.hasContext ||
|
||||||
|
(a.hasContext == b.hasContext && a.context < b.context) ||
|
||||||
|
(a.hasContext == b.hasContext && a.context == b.context && a.ident < b.ident);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Gettext .po file parsing
|
// Gettext .po file parsing
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -1265,7 +1284,7 @@ public:
|
||||||
unsigned pluralCount;
|
unsigned pluralCount;
|
||||||
std::string pluralExpr;
|
std::string pluralExpr;
|
||||||
|
|
||||||
std::map<std::string, std::vector<std::string>> messages;
|
std::map<TranslationKey, std::vector<std::string>, TranslationKeyLess> messages;
|
||||||
|
|
||||||
void SkipSpace();
|
void SkipSpace();
|
||||||
std::string ReadString();
|
std::string ReadString();
|
||||||
|
@ -1342,11 +1361,18 @@ void GettextParser::Parse() {
|
||||||
|
|
||||||
SkipSpace();
|
SkipSpace();
|
||||||
while(!reader.AtEnd()) {
|
while(!reader.AtEnd()) {
|
||||||
|
TranslationKey key = {};
|
||||||
|
|
||||||
|
if(reader.TryString("msgctxt")) {
|
||||||
|
key.hasContext = true;
|
||||||
|
key.context = ReadString();
|
||||||
|
}
|
||||||
|
|
||||||
reader.ExpectString("msgid");
|
reader.ExpectString("msgid");
|
||||||
std::string msgid = ReadString();
|
key.ident = ReadString();
|
||||||
|
|
||||||
if(reader.TryString("msgid_plural")) {
|
if(reader.TryString("msgid_plural")) {
|
||||||
std::string _msgid_plural = ReadString();
|
ReadString(); // we don't need it
|
||||||
// We don't need it.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string> msgstrs;
|
std::vector<std::string> msgstrs;
|
||||||
|
@ -1364,7 +1390,7 @@ void GettextParser::Parse() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(msgid == "") {
|
if(key.ident == "") {
|
||||||
ssassert(msgstrs.size() == 1,
|
ssassert(msgstrs.size() == 1,
|
||||||
"Expected exactly one header msgstr");
|
"Expected exactly one header msgstr");
|
||||||
ParseHeader(msgstrs[0]);
|
ParseHeader(msgstrs[0]);
|
||||||
|
@ -1372,7 +1398,7 @@ void GettextParser::Parse() {
|
||||||
ssassert(msgstrs.size() == 1 ||
|
ssassert(msgstrs.size() == 1 ||
|
||||||
msgstrs.size() == pluralCount,
|
msgstrs.size() == pluralCount,
|
||||||
"Expected msgstr count to match plural form count");
|
"Expected msgstr count to match plural form count");
|
||||||
messages.emplace(msgid, msgstrs);
|
messages.emplace(key, msgstrs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1386,12 +1412,12 @@ public:
|
||||||
unsigned pluralCount;
|
unsigned pluralCount;
|
||||||
std::string pluralExpr;
|
std::string pluralExpr;
|
||||||
|
|
||||||
std::map<std::string, std::vector<std::string>> messages;
|
std::map<TranslationKey, std::vector<std::string>, TranslationKeyLess> messages;
|
||||||
|
|
||||||
static Translation From(const std::string &poData);
|
static Translation From(const std::string &poData);
|
||||||
|
|
||||||
const std::string &Translate(const char *msgid);
|
const std::string &Translate(const TranslationKey &key);
|
||||||
const std::string &TranslatePlural(const char *msgid, unsigned n);
|
const std::string &TranslatePlural(const TranslationKey &key, unsigned n);
|
||||||
};
|
};
|
||||||
|
|
||||||
Translation Translation::From(const std::string &poData) {
|
Translation Translation::From(const std::string &poData) {
|
||||||
|
@ -1406,28 +1432,28 @@ Translation Translation::From(const std::string &poData) {
|
||||||
return trans;
|
return trans;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string &Translation::Translate(const char *msgid) {
|
const std::string &Translation::Translate(const TranslationKey &key) {
|
||||||
auto it = messages.find(msgid);
|
auto it = messages.find(key);
|
||||||
if(it == messages.end()) {
|
if(it == messages.end()) {
|
||||||
dbp("Missing translation for '%s'", msgid);
|
dbp("Missing translation for %s'%s'", key.context.c_str(), key.ident.c_str());
|
||||||
messages[msgid].emplace_back(msgid);
|
messages[key].emplace_back(key.ident);
|
||||||
it = messages.find(msgid);
|
it = messages.find(key);
|
||||||
}
|
}
|
||||||
if(it->second.size() != 1) {
|
if(it->second.size() != 1) {
|
||||||
dbp("Incorrect use of translated message '%s'", msgid);
|
dbp("Incorrect use of translated message %s'%s'", key.context.c_str(), key.ident.c_str());
|
||||||
ssassert(false, "Using a message with a plural form without a number");
|
ssassert(false, "Using a message with a plural form without a number");
|
||||||
}
|
}
|
||||||
return it->second[0];
|
return it->second[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string &Translation::TranslatePlural(const char *msgid, unsigned n) {
|
const std::string &Translation::TranslatePlural(const TranslationKey &key, unsigned n) {
|
||||||
auto it = messages.find(msgid);
|
auto it = messages.find(key);
|
||||||
if(it == messages.end()) {
|
if(it == messages.end()) {
|
||||||
dbp("Missing translation for '%s'", msgid);
|
dbp("Missing translation for %s'%s'", key.context.c_str(), key.ident.c_str());
|
||||||
for(unsigned i = 0; i < pluralCount; i++) {
|
for(unsigned i = 0; i < pluralCount; i++) {
|
||||||
messages[msgid].emplace_back(msgid);
|
messages[key].emplace_back(key.ident);
|
||||||
}
|
}
|
||||||
it = messages.find(msgid);
|
it = messages.find(key);
|
||||||
}
|
}
|
||||||
unsigned pluralForm = PluralExpr::Eval(pluralExpr, n);
|
unsigned pluralForm = PluralExpr::Eval(pluralExpr, n);
|
||||||
return it->second[pluralForm];
|
return it->second[pluralForm];
|
||||||
|
@ -1501,11 +1527,31 @@ bool SetLocale(uint16_t lcid) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string &Translate(const char *msgid) {
|
const std::string &Translate(const char *msgid) {
|
||||||
return currentTranslation->Translate(msgid);
|
TranslationKey key = {};
|
||||||
|
key.ident = msgid;
|
||||||
|
return currentTranslation->Translate(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string &Translate(const char *msgctxt, const char *msgid) {
|
||||||
|
TranslationKey key = {};
|
||||||
|
key.hasContext = true;
|
||||||
|
key.context = msgctxt;
|
||||||
|
key.ident = msgid;
|
||||||
|
return currentTranslation->Translate(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string &TranslatePlural(const char *msgid, unsigned n) {
|
const std::string &TranslatePlural(const char *msgid, unsigned n) {
|
||||||
return currentTranslation->TranslatePlural(msgid, n);
|
TranslationKey key = {};
|
||||||
|
key.ident = msgid;
|
||||||
|
return currentTranslation->TranslatePlural(key, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string &TranslatePlural(const char *msgctxt, const char *msgid, unsigned n) {
|
||||||
|
TranslationKey key = {};
|
||||||
|
key.hasContext = true;
|
||||||
|
key.context = msgctxt;
|
||||||
|
key.ident = msgid;
|
||||||
|
return currentTranslation->TranslatePlural(key, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -476,10 +476,10 @@ void SolveSpaceUI::MenuFile(Command id) {
|
||||||
(FilenameHasExtension(exportFile, ".txt") ||
|
(FilenameHasExtension(exportFile, ".txt") ||
|
||||||
fabs(SS.exportOffset) > LENGTH_EPS))
|
fabs(SS.exportOffset) > LENGTH_EPS))
|
||||||
{
|
{
|
||||||
Message("Constraints are currently shown, and will be exported "
|
Message(_("Constraints are currently shown, and will be exported "
|
||||||
"in the toolpath. This is probably not what you want; "
|
"in the toolpath. This is probably not what you want; "
|
||||||
"hide them by clicking the link at the top of the "
|
"hide them by clicking the link at the top of the "
|
||||||
"text window.");
|
"text window."));
|
||||||
}
|
}
|
||||||
|
|
||||||
SS.ExportViewOrWireframeTo(exportFile, /*exportWireframe*/false);
|
SS.ExportViewOrWireframeTo(exportFile, /*exportWireframe*/false);
|
||||||
|
@ -583,11 +583,11 @@ void SolveSpaceUI::MenuAnalyze(Command id) {
|
||||||
SS.ScheduleShowTW();
|
SS.ScheduleShowTW();
|
||||||
SS.GW.ClearSelection();
|
SS.GW.ClearSelection();
|
||||||
} else {
|
} else {
|
||||||
Error("Constraint must have a label, and must not be "
|
Error(_("Constraint must have a label, and must not be "
|
||||||
"a reference dimension.");
|
"a reference dimension."));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Error("Bad selection for step dimension; select a constraint.");
|
Error(_("Bad selection for step dimension; select a constraint."));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -611,7 +611,7 @@ void SolveSpaceUI::MenuAnalyze(Command id) {
|
||||||
Error("%d edges interfere with other triangles, bad.",
|
Error("%d edges interfere with other triangles, bad.",
|
||||||
SS.nakedEdges.l.n);
|
SS.nakedEdges.l.n);
|
||||||
} else {
|
} else {
|
||||||
Message("The assembly does not interfere, good.");
|
Message(_("The assembly does not interfere, good."));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -688,9 +688,9 @@ void SolveSpaceUI::MenuAnalyze(Command id) {
|
||||||
case Command::AREA: {
|
case Command::AREA: {
|
||||||
Group *g = SK.GetGroup(SS.GW.activeGroup);
|
Group *g = SK.GetGroup(SS.GW.activeGroup);
|
||||||
if(g->polyError.how != PolyError::GOOD) {
|
if(g->polyError.how != PolyError::GOOD) {
|
||||||
Error("This group does not contain a correctly-formed "
|
Error(_("This group does not contain a correctly-formed "
|
||||||
"2d closed area. It is open, not coplanar, or self-"
|
"2d closed area. It is open, not coplanar, or self-"
|
||||||
"intersecting.");
|
"intersecting."));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
SEdgeList sel = {};
|
SEdgeList sel = {};
|
||||||
|
@ -731,7 +731,7 @@ void SolveSpaceUI::MenuAnalyze(Command id) {
|
||||||
perimeter / scale,
|
perimeter / scale,
|
||||||
SS.UnitName());
|
SS.UnitName());
|
||||||
} else {
|
} else {
|
||||||
Error("Bad selection for perimeter; select line segments, arcs, and curves.");
|
Error(_("Bad selection for perimeter; select line segments, arcs, and curves."));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -747,7 +747,7 @@ void SolveSpaceUI::MenuAnalyze(Command id) {
|
||||||
SS.traced.point = gs.point[0];
|
SS.traced.point = gs.point[0];
|
||||||
SS.GW.ClearSelection();
|
SS.GW.ClearSelection();
|
||||||
} else {
|
} else {
|
||||||
Error("Bad selection for trace; select a single point.");
|
Error(_("Bad selection for trace; select a single point."));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -158,8 +158,8 @@ void Style::AssignSelectionToStyle(uint32_t v) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if(showError) {
|
if(showError) {
|
||||||
Error("Can't assign style to an entity that's derived from another "
|
Error(_("Can't assign style to an entity that's derived from another "
|
||||||
"entity; try assigning a style to this entity's parent.");
|
"entity; try assigning a style to this entity's parent."));
|
||||||
}
|
}
|
||||||
|
|
||||||
SS.GW.ClearSelection();
|
SS.GW.ClearSelection();
|
||||||
|
@ -695,13 +695,13 @@ bool TextWindow::EditControlDoneForStyles(const char *str) {
|
||||||
SS.backgroundColor = RGBf(rgb.x, rgb.y, rgb.z);
|
SS.backgroundColor = RGBf(rgb.x, rgb.y, rgb.z);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Error("Bad format: specify color as r, g, b");
|
Error(_("Bad format: specify color as r, g, b"));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Edit::STYLE_NAME:
|
case Edit::STYLE_NAME:
|
||||||
if(!*str) {
|
if(!*str) {
|
||||||
Error("Style name cannot be empty");
|
Error(_("Style name cannot be empty"));
|
||||||
} else {
|
} else {
|
||||||
SS.UndoRemember();
|
SS.UndoRemember();
|
||||||
s = Style::Get(edit.style);
|
s = Style::Get(edit.style);
|
||||||
|
@ -714,7 +714,7 @@ bool TextWindow::EditControlDoneForStyles(const char *str) {
|
||||||
if(e) {
|
if(e) {
|
||||||
double ev = e->Eval();
|
double ev = e->Eval();
|
||||||
if(ev < 0.001 || isnan(ev)) {
|
if(ev < 0.001 || isnan(ev)) {
|
||||||
Error("Scale must not be zero or negative!");
|
Error(_("Scale must not be zero or negative!"));
|
||||||
} else {
|
} else {
|
||||||
SS.bgImage.scale = ev / SS.MmPerUnit();
|
SS.bgImage.scale = ev / SS.MmPerUnit();
|
||||||
}
|
}
|
||||||
|
|
|
@ -654,11 +654,11 @@ void TextWindow::EditControlDone(const char *s) {
|
||||||
|
|
||||||
double ev = e->Eval();
|
double ev = e->Eval();
|
||||||
if((int)ev < 1) {
|
if((int)ev < 1) {
|
||||||
Error("Can't repeat fewer than 1 time.");
|
Error(_("Can't repeat fewer than 1 time."));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if((int)ev > 999) {
|
if((int)ev > 999) {
|
||||||
Error("Can't repeat more than 999 times.");
|
Error(_("Can't repeat more than 999 times."));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -687,7 +687,7 @@ void TextWindow::EditControlDone(const char *s) {
|
||||||
}
|
}
|
||||||
case Edit::GROUP_NAME: {
|
case Edit::GROUP_NAME: {
|
||||||
if(!*s) {
|
if(!*s) {
|
||||||
Error("Group name cannot be empty");
|
Error(_("Group name cannot be empty"));
|
||||||
} else {
|
} else {
|
||||||
SS.UndoRemember();
|
SS.UndoRemember();
|
||||||
|
|
||||||
|
@ -701,7 +701,7 @@ void TextWindow::EditControlDone(const char *s) {
|
||||||
if(e) {
|
if(e) {
|
||||||
double ev = e->Eval();
|
double ev = e->Eval();
|
||||||
if(fabs(ev) < 1e-6) {
|
if(fabs(ev) < 1e-6) {
|
||||||
Error("Scale cannot be zero.");
|
Error(_("Scale cannot be zero."));
|
||||||
} else {
|
} else {
|
||||||
Group *g = SK.GetGroup(edit.group);
|
Group *g = SK.GetGroup(edit.group);
|
||||||
g->scale = ev;
|
g->scale = ev;
|
||||||
|
@ -722,7 +722,7 @@ void TextWindow::EditControlDone(const char *s) {
|
||||||
SS.MarkGroupDirty(g->h);
|
SS.MarkGroupDirty(g->h);
|
||||||
SS.GW.ClearSuper();
|
SS.GW.ClearSuper();
|
||||||
} else {
|
} else {
|
||||||
Error("Bad format: specify color as r, g, b");
|
Error(_("Bad format: specify color as r, g, b"));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -731,7 +731,7 @@ void TextWindow::EditControlDone(const char *s) {
|
||||||
if(e) {
|
if(e) {
|
||||||
double alpha = e->Eval();
|
double alpha = e->Eval();
|
||||||
if(alpha < 0 || alpha > 1) {
|
if(alpha < 0 || alpha > 1) {
|
||||||
Error("Opacity must be between zero and one.");
|
Error(_("Opacity must be between zero and one."));
|
||||||
} else {
|
} else {
|
||||||
Group *g = SK.GetGroup(edit.group);
|
Group *g = SK.GetGroup(edit.group);
|
||||||
g->color.alpha = (int)(255.1f * alpha);
|
g->color.alpha = (int)(255.1f * alpha);
|
||||||
|
@ -770,7 +770,7 @@ void TextWindow::EditControlDone(const char *s) {
|
||||||
Expr *e = Expr::From(s, /*popUpError=*/true);
|
Expr *e = Expr::From(s, /*popUpError=*/true);
|
||||||
if(!e) break;
|
if(!e) break;
|
||||||
if(e->Eval() < LENGTH_EPS) {
|
if(e->Eval() < LENGTH_EPS) {
|
||||||
Error("Radius cannot be zero or negative.");
|
Error(_("Radius cannot be zero or negative."));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
SS.tangentArcRadius = SS.ExprToMm(e);
|
SS.tangentArcRadius = SS.ExprToMm(e);
|
||||||
|
|
25
src/ui.h
25
src/ui.h
|
@ -32,10 +32,31 @@ bool SetLocale(const std::string &name);
|
||||||
bool SetLocale(uint16_t lcid);
|
bool SetLocale(uint16_t lcid);
|
||||||
|
|
||||||
const std::string &Translate(const char *msgid);
|
const std::string &Translate(const char *msgid);
|
||||||
|
const std::string &Translate(const char *msgctxt, const char *msgid);
|
||||||
const std::string &TranslatePlural(const char *msgid, unsigned n);
|
const std::string &TranslatePlural(const char *msgid, unsigned n);
|
||||||
|
const std::string &TranslatePlural(const char *msgctxt, const char *msgid, unsigned n);
|
||||||
|
|
||||||
inline const char *N_(const char *msgid) { return msgid; }
|
inline const char *N_(const char *msgid) {
|
||||||
inline const char *_(const char *msgid) { return Translate(msgid).c_str(); }
|
return msgid;
|
||||||
|
}
|
||||||
|
inline const char *CN_(const char *msgctxt, const char *msgid) {
|
||||||
|
return msgid;
|
||||||
|
}
|
||||||
|
#if defined(LIBRARY)
|
||||||
|
inline const char *_(const char *msgid) {
|
||||||
|
return msgid;
|
||||||
|
}
|
||||||
|
inline const char *C_(const char *msgctxt, const char *msgid) {
|
||||||
|
return msgid;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
inline const char *_(const char *msgid) {
|
||||||
|
return Translate(msgid).c_str();
|
||||||
|
}
|
||||||
|
inline const char *C_(const char *msgctxt, const char *msgid) {
|
||||||
|
return Translate(msgctxt, msgid).c_str();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// This table describes the top-level menus in the graphics winodw.
|
// This table describes the top-level menus in the graphics winodw.
|
||||||
enum class Command : uint32_t {
|
enum class Command : uint32_t {
|
||||||
|
|
|
@ -75,7 +75,7 @@ bool TextWindow::EditControlDoneForView(const char *s) {
|
||||||
if(v > LENGTH_EPS) {
|
if(v > LENGTH_EPS) {
|
||||||
SS.GW.scale = v;
|
SS.GW.scale = v;
|
||||||
} else {
|
} else {
|
||||||
Error("Scale cannot be zero or negative.");
|
Error(_("Scale cannot be zero or negative."));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -87,7 +87,7 @@ bool TextWindow::EditControlDoneForView(const char *s) {
|
||||||
pt = pt.ScaledBy(SS.MmPerUnit());
|
pt = pt.ScaledBy(SS.MmPerUnit());
|
||||||
SS.GW.offset = pt.ScaledBy(-1);
|
SS.GW.offset = pt.ScaledBy(-1);
|
||||||
} else {
|
} else {
|
||||||
Error("Bad format: specify x, y, z");
|
Error(_("Bad format: specify x, y, z"));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -96,7 +96,7 @@ bool TextWindow::EditControlDoneForView(const char *s) {
|
||||||
case Edit::VIEW_PROJ_UP: {
|
case Edit::VIEW_PROJ_UP: {
|
||||||
Vector pt;
|
Vector pt;
|
||||||
if(sscanf(s, "%lf, %lf, %lf", &pt.x, &pt.y, &pt.z) != 3) {
|
if(sscanf(s, "%lf, %lf, %lf", &pt.x, &pt.y, &pt.z) != 3) {
|
||||||
Error("Bad format: specify x, y, z");
|
Error(_("Bad format: specify x, y, z"));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(edit.meaning == Edit::VIEW_PROJ_RIGHT) {
|
if(edit.meaning == Edit::VIEW_PROJ_RIGHT) {
|
||||||
|
|
Loading…
Reference in New Issue