From 6ad50db01b46446f5d0f088eae0c01b8fa6c62b3 Mon Sep 17 00:00:00 2001 From: Sebastian Hoogen Date: Sun, 14 Sep 2014 10:50:45 +0200 Subject: [PATCH] fixes #1744 Use unicode in Unit system --- src/Base/QuantityPyImp.cpp | 75 ++++++++++++++++++++++++++------------ src/Base/UnitPyImp.cpp | 34 ++++++++++++----- src/Base/UnitsApiPy.cpp | 48 ++++++++++++++---------- src/Mod/Draft/DraftGui.py | 2 +- 4 files changed, 105 insertions(+), 54 deletions(-) diff --git a/src/Base/QuantityPyImp.cpp b/src/Base/QuantityPyImp.cpp index 329e3797f969..783801e58509 100644 --- a/src/Base/QuantityPyImp.cpp +++ b/src/Base/QuantityPyImp.cpp @@ -37,7 +37,7 @@ std::string QuantityPy::representation(void) const { std::stringstream ret; ret << getQuantityPtr()->getValue() << " "; - ret << getQuantityPtr()->getUnit().getString().toLatin1().constData(); + ret << getQuantityPtr()->getUnit().getString().toUtf8().constData(); return ret.str(); } @@ -83,20 +83,29 @@ int QuantityPy::PyInit(PyObject* args, PyObject* kwd) return 0; } PyErr_Clear(); // set by PyArg_ParseTuple() - const char* string; - if (PyArg_ParseTuple(args,"s", &string)) { - try { - *self = Quantity::parse(QString::fromLatin1(string)); - }catch(const Base::Exception& e) { - PyErr_SetString(PyExc_ValueError, e.what()); - return-1; - } - - return 0; - } - - PyErr_SetString(PyExc_TypeError, "Either three floats, tuple or Vector expected"); - return -1; + if (PyArg_ParseTuple(args,"O", &object)) { + if (PyString_Check(object) || PyUnicode_Check(object)) { + QString qstr; + if (PyUnicode_Check(object)) { + PyObject * utf8str = PyUnicode_AsUTF8String(object); + qstr = QString::fromUtf8(PyString_AsString(utf8str)); + Py_DECREF(utf8str); + } + else { + qstr = QString::fromUtf8(PyString_AsString(object)); + } + try { + *self = Quantity::parse(qstr); + } + catch(const Base::Exception& e) { + PyErr_SetString(PyExc_ValueError, e.what()); + return -1; + } + return 0; + } // Not string or unicode + } // zero or more than one object + PyErr_SetString(PyExc_TypeError, "Either quantity, float and Base unit, float and 8 integers or unicode or utf-8 string expected"); + return -1; } PyObject* QuantityPy::getUserPreferred(PyObject *args) @@ -107,9 +116,9 @@ PyObject* QuantityPy::getUserPreferred(PyObject *args) QString uss = getQuantityPtr()->getUserString(factor,uus); - res[0] = Py::String(uss.toLatin1()); + res[0] = Py::String(uss.toUtf8(),"utf-8"); res[1] = Py::Float(factor); - res[2] = Py::String(uus.toLatin1()); + res[2] = Py::String(uus.toUtf8(),"utf-8"); return Py::new_reference_to(res); } @@ -169,14 +178,32 @@ PyObject* QuantityPy::getValueAs(PyObject *args) if (!quant.isValid()) { PyErr_Clear(); - const char* string; - if (PyArg_ParseTuple(args,"s", &string)) { - quant = Quantity::parse(QString::fromLatin1(string)); - } - } + PyObject *object; + if (PyArg_ParseTuple(args,"O", &object)) { + if (PyString_Check(object) || PyUnicode_Check(object)) { + QString qstr; + if (PyUnicode_Check(object)) { + PyObject * utf8str = PyUnicode_AsUTF8String(object); + qstr = QString::fromUtf8(PyString_AsString(utf8str)); + Py_DECREF(utf8str); + } + else { + qstr = QString::fromUtf8(PyString_AsString(object)); + } + try { + quant = Quantity::parse(qstr); + } + catch(const Base::Exception& e) { + PyErr_SetString(PyExc_ValueError, e.what()); + return 0; + } + return 0; + } // Not string or unicode + } // zero or more than one object + } // !isValid if (!quant.isValid()) { - PyErr_SetString(PyExc_TypeError, "Either quantity, string, float or unit expected"); + PyErr_SetString(PyExc_TypeError, "Either quantity, float and Base unit, float and 8 integers or unicode or utf-8 string expected"); return 0; } @@ -559,7 +586,7 @@ void QuantityPy::setUnit(Py::Object arg) Py::String QuantityPy::getUserString(void) const { - return Py::String(getQuantityPtr()->getUserString().toLatin1()); + return Py::String(getQuantityPtr()->getUserString().toUtf8(),"utf-8"); } PyObject *QuantityPy::getCustomAttributes(const char* /*attr*/) const diff --git a/src/Base/UnitPyImp.cpp b/src/Base/UnitPyImp.cpp index 5ee00576f57d..51ceed60b3fa 100644 --- a/src/Base/UnitPyImp.cpp +++ b/src/Base/UnitPyImp.cpp @@ -16,7 +16,7 @@ std::string UnitPy::representation(void) const const UnitSignature & Sig = getUnitPtr()->getSignature(); std::stringstream ret; ret << "Unit: "; - ret << getUnitPtr()->getString().toLatin1().constData() << " ("; + ret << getUnitPtr()->getString().toUtf8().constData() << " ("; ret << Sig.Length << ","; ret << Sig.Mass << ","; ret << Sig.Time << ","; @@ -25,7 +25,7 @@ std::string UnitPy::representation(void) const ret << Sig.AmountOfSubstance << ","; ret << Sig.LuminoseIntensity << ","; ret << Sig.Angle << ")"; - std::string type = getUnitPtr()->getTypeString().toLatin1().constData(); + std::string type = getUnitPtr()->getTypeString().toUtf8().constData(); if(! type.empty()) ret << " [" << type << "]"; @@ -72,13 +72,27 @@ int UnitPy::PyInit(PyObject* args, PyObject* kwd) return 0; } PyErr_Clear(); // set by PyArg_ParseTuple() - const char* string; - if (PyArg_ParseTuple(args,"s", &string)) { - - *self = Quantity::parse(QString::fromLatin1(string)).getUnit(); - return 0; - } - + if (PyArg_ParseTuple(args,"O", &object)) { + if (PyString_Check(object) || PyUnicode_Check(object)) { + QString qstr; + if (PyUnicode_Check(object)) { + PyObject * utf8str = PyUnicode_AsUTF8String(object); + qstr = QString::fromUtf8(PyString_AsString(utf8str)); + Py_DECREF(utf8str); + } + else { + qstr = QString::fromUtf8(PyString_AsString(object)); + } + try { + *self = Quantity::parse(qstr).getUnit(); + } + catch(const Base::Exception& e) { + PyErr_SetString(PyExc_ValueError, e.what()); + return -1; + } + return 0; + } // Not string or unicode + } // zero or more than one object PyErr_SetString(PyExc_TypeError, "Either string, (float,8 ints), Unit() or Quantity()"); return -1; } @@ -178,7 +192,7 @@ PyObject* UnitPy::richCompare(PyObject *v, PyObject *w, int op) Py::String UnitPy::getType(void) const { - return Py::String(getUnitPtr()->getTypeString().toLatin1()); + return Py::String(getUnitPtr()->getTypeString().toUtf8(),"utf-8"); } diff --git a/src/Base/UnitsApiPy.cpp b/src/Base/UnitsApiPy.cpp index 5d1a8b5b92c2..273b0add5486 100644 --- a/src/Base/UnitsApiPy.cpp +++ b/src/Base/UnitsApiPy.cpp @@ -128,23 +128,33 @@ PyMethodDef UnitsApi::Methods[] = { PyObject* UnitsApi::sParseQuantity(PyObject * /*self*/, PyObject *args,PyObject * /*kwd*/) { - char *pstr; - if (!PyArg_ParseTuple(args, "s", &pstr)) // convert args: Python->C - return NULL; // NULL triggers exception - - Quantity rtn; - try { - rtn = Quantity::parse(QString::fromLatin1(pstr)); - } - catch (const Base::Exception&) { - PyErr_Format(PyExc_IOError, "invalid unit expression \n"); - return 0L; - } - catch (const std::exception&) { - PyErr_Format(PyExc_IOError, "invalid unit expression \n"); - return 0L; - } - - return new QuantityPy(new Quantity(rtn)); - + PyObject * object; + if (PyArg_ParseTuple(args,"O", &object)) { + if (PyString_Check(object) || PyUnicode_Check(object)) { + QString qstr; + if (PyUnicode_Check(object)) { + PyObject * utf8str = PyUnicode_AsUTF8String(object); + qstr = QString::fromUtf8(PyString_AsString(utf8str)); + Py_DECREF(utf8str); + } + else { + qstr = QString::fromUtf8(PyString_AsString(object)); + } + Quantity rtn; + try { + rtn = Quantity::parse(qstr); + } + catch (const Base::Exception&) { + PyErr_Format(PyExc_IOError, "invalid unit expression \n"); + return 0L; + } + catch (const std::exception&) { + PyErr_Format(PyExc_IOError, "invalid unit expression \n"); + return 0L; + } + return new QuantityPy(new Quantity(rtn)); + } //string or unicode + } //if one object + PyErr_Format(PyExc_IOError, "invalid unit expression \n"); + return 0L; } diff --git a/src/Mod/Draft/DraftGui.py b/src/Mod/Draft/DraftGui.py index d470d1f2c27f..526a1b09198e 100644 --- a/src/Mod/Draft/DraftGui.py +++ b/src/Mod/Draft/DraftGui.py @@ -142,7 +142,7 @@ def displayExternal(internValue,decimals=4,dim='Length',showUnit=True): qty = FreeCAD.Units.Quantity(internValue,FreeCAD.Units.Angle) pref=qty.getUserPreferred() conversion = pref[1] - uom = pref[2].decode('latin-1') + uom = pref[2] else: conversion = 1.0 uom = "??"