Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTamito Kajiyama <rd6t-kjym@asahi-net.or.jp>2013-02-16 22:38:03 +0400
committerTamito Kajiyama <rd6t-kjym@asahi-net.or.jp>2013-02-16 22:38:03 +0400
commit92436c94d3adbbfc285bd7b3041db36e66dae5d5 (patch)
tree2083c8ad4fa810a781e9631161aa88b12008453d /source/blender/python
parent90ed5ea4ea278b4aadf9187e4e2b92ef3221001b (diff)
parentfda8927d01ba719963154a56b45952ee541a869d (diff)
Merged changes in the trunk up to revision 54594.
Diffstat (limited to 'source/blender/python')
-rw-r--r--source/blender/python/bmesh/bmesh_py_ops_call.c5
-rw-r--r--source/blender/python/bmesh/bmesh_py_types.c54
-rw-r--r--source/blender/python/intern/bpy_app_translations.c107
3 files changed, 140 insertions, 26 deletions
diff --git a/source/blender/python/bmesh/bmesh_py_ops_call.c b/source/blender/python/bmesh/bmesh_py_ops_call.c
index d4c8033589a..fad3e4a35cd 100644
--- a/source/blender/python/bmesh/bmesh_py_ops_call.c
+++ b/source/blender/python/bmesh/bmesh_py_ops_call.c
@@ -48,11 +48,13 @@
static int bpy_bm_op_as_py_error(BMesh *bm)
{
if (BMO_error_occurred(bm)) {
+ /* note: we could have multiple errors */
const char *errmsg;
if (BMO_error_get(bm, &errmsg, NULL)) {
PyErr_Format(PyExc_RuntimeError,
"bmesh operator: %.200s",
errmsg);
+ BMO_error_clear(bm);
return -1;
}
}
@@ -692,6 +694,9 @@ PyObject *BPy_BMO_call(BPy_BMeshOpFunc *self, PyObject *args, PyObject *kw)
{
BPY_BM_CHECK_OBJ(py_bm);
bm = py_bm->bm;
+
+ /* could complain about entering with exceptions... */
+ BMO_error_clear(bm);
}
else {
PyErr_SetString(PyExc_TypeError,
diff --git a/source/blender/python/bmesh/bmesh_py_types.c b/source/blender/python/bmesh/bmesh_py_types.c
index 0abff03da46..b95db945eb1 100644
--- a/source/blender/python/bmesh/bmesh_py_types.c
+++ b/source/blender/python/bmesh/bmesh_py_types.c
@@ -50,6 +50,8 @@
#include "bmesh_py_types_customdata.h"
#include "bmesh_py_types_meshdata.h"
+static void bm_dealloc_editmode_warn(BPy_BMesh *self);
+
/* Common Flags
* ************ */
@@ -847,6 +849,8 @@ static PyObject *bpy_bmesh_free(BPy_BMesh *self)
if (self->bm) {
BMesh *bm = self->bm;
+ bm_dealloc_editmode_warn(self);
+
if ((self->flag & BPY_BMFLAG_IS_WRAPPED) == 0) {
BM_mesh_free(bm);
}
@@ -2828,6 +2832,8 @@ static void bpy_bmesh_dealloc(BPy_BMesh *self)
/* have have been freed by bmesh */
if (bm) {
+ bm_dealloc_editmode_warn(self);
+
BM_data_layer_free(bm, &bm->vdata, CD_BM_ELEM_PYPTR);
BM_data_layer_free(bm, &bm->edata, CD_BM_ELEM_PYPTR);
BM_data_layer_free(bm, &bm->pdata, CD_BM_ELEM_PYPTR);
@@ -3638,3 +3644,51 @@ char *BPy_BMElem_StringFromHType(const char htype)
static char ret[32];
return BPy_BMElem_StringFromHType_ex(htype, ret);
}
+
+
+/* -------------------------------------------------------------------- */
+/* keep at bottom */
+/* BAD INCLUDES */
+
+#include "BKE_global.h"
+#include "BKE_main.h"
+#include "BKE_tessmesh.h"
+#include "DNA_scene_types.h"
+#include "DNA_object_types.h"
+#include "DNA_mesh_types.h"
+#include "MEM_guardedalloc.h"
+
+/* there are cases where this warning isnt needed, otherwise it could be made into an error */
+static void bm_dealloc_warn(const char *mesh_name)
+{
+ PySys_WriteStdout("Modified BMesh '%.200s' from a wrapped editmesh is freed without a call "
+ "to bmesh.update_edit_mesh(mesh, destructive=True), this is will likely cause a crash\n",
+ mesh_name);
+}
+
+/* this function is called on free, it should stay quite fast */
+static void bm_dealloc_editmode_warn(BPy_BMesh *self)
+{
+ if (self->flag & BPY_BMFLAG_IS_WRAPPED) {
+ /* likely editmesh */
+ BMesh *bm = self->bm;
+ Scene *scene;
+ for (scene = G.main->scene.first; scene; scene = scene->id.next) {
+ Base *base = scene->basact;
+ if (base && base->object->type == OB_MESH) {
+ Mesh *me = base->object->data;
+ BMEditMesh *em = me->edit_btmesh;
+ if (em && em->bm == bm) {
+ /* not foolproof, scripter may have added/removed verts */
+ if (((em->vert_index && (MEM_allocN_len(em->vert_index) / sizeof(*em->vert_index)) != bm->totvert)) ||
+ ((em->edge_index && (MEM_allocN_len(em->edge_index) / sizeof(*em->edge_index)) != bm->totedge)) ||
+ ((em->face_index && (MEM_allocN_len(em->face_index) / sizeof(*em->face_index)) != bm->totface)))
+ {
+ bm_dealloc_warn(me->id.name + 2);
+ break;
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/source/blender/python/intern/bpy_app_translations.c b/source/blender/python/intern/bpy_app_translations.c
index b6d2f624229..7c89972b486 100644
--- a/source/blender/python/intern/bpy_app_translations.c
+++ b/source/blender/python/intern/bpy_app_translations.c
@@ -74,7 +74,7 @@ typedef struct GHashKey {
static GHashKey *_ghashutil_keyalloc(const void *msgctxt, const void *msgid)
{
GHashKey *key = MEM_mallocN(sizeof(GHashKey), "Py i18n GHashKey");
- key->msgctxt = BLI_strdup(msgctxt ? msgctxt : BLF_I18NCONTEXT_DEFAULT_BPY_INTERN);
+ key->msgctxt = BLI_strdup(msgctxt ? msgctxt : BLF_I18NCONTEXT_DEFAULT_BPY);
key->msgid = BLI_strdup(msgid);
return key;
}
@@ -195,7 +195,7 @@ static void _build_translations_cache(PyObject *py_messages, const char *locale)
else {
PyObject *tmp = PyTuple_GET_ITEM(pykey, 0);
if (tmp == Py_None) {
- msgctxt = BLF_I18NCONTEXT_DEFAULT;
+ msgctxt = BLF_I18NCONTEXT_DEFAULT_BPY;
}
else if (PyUnicode_Check(tmp)) {
msgctxt = _PyUnicode_AsString(tmp);
@@ -288,9 +288,7 @@ const char *BPY_app_translations_py_pgettext(const char *msgctxt, const char *ms
_ghashutil_keyfree((void *)key);
- if (tmp)
- return tmp;
- return msgid;
+ return tmp ? tmp : msgid;
#undef STATIC_LOCALE_SIZE
}
@@ -435,8 +433,8 @@ static PyObject *app_translations_contexts_make(void)
PyDoc_STRVAR(app_translations_contexts_doc,
"A named tuple containing all pre-defined translation contexts.\n"
- "WARNING: do not use the \"" BLF_I18NCONTEXT_DEFAULT_BPY_INTERN "\" context, it is internally assimilated as the "
- "default one!\n"
+ "WARNING: Never use a (new) context starting with \"" BLF_I18NCONTEXT_DEFAULT_BPY "\", it would be internally "
+ "assimilated as the default one!\n"
);
PyDoc_STRVAR(app_translations_contexts_C_to_py_doc,
@@ -495,6 +493,39 @@ PyGetSetDef app_translations_getseters[] = {
{NULL}
};
+/* pgettext helper. */
+static PyObject *_py_pgettext(PyObject *args, PyObject *kw, const char *(*_pgettext)(const char *, const char *))
+{
+ static const char *kwlist[] = {"msgid", "msgctxt", NULL};
+
+#ifdef WITH_INTERNATIONAL
+ char *msgid, *msgctxt = NULL;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kw,
+ "s|z:bpy.app.translations.pgettext",
+ (char **)kwlist, &msgid, &msgctxt))
+ {
+ return NULL;
+ }
+
+ return PyUnicode_FromString((*_pgettext)(msgctxt ? msgctxt : BLF_I18NCONTEXT_DEFAULT, msgid));
+#else
+ PyObject *msgid, *msgctxt;
+ (void)_pgettext;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kw,
+ "O|O:bpy.app.translations.pgettext",
+ (char **)kwlist, &msgid, &msgctxt))
+ {
+ return NULL;
+ }
+
+ Py_INCREF(msgid);
+
+ return msgid;
+#endif
+}
+
PyDoc_STRVAR(app_translations_pgettext_doc,
".. method:: pgettext(msgid, msgctxt)\n"
"\n"
@@ -502,7 +533,8 @@ PyDoc_STRVAR(app_translations_pgettext_doc,
" NOTE: The (msgid, msgctxt) parameter orders has been switched compared to gettext function, to allow\n"
" single-parameter calls (context then defaults to BLF_I18NCONTEXT_DEFAULT).\n"
" NOTE: You should really rarely need to use this function in regular addon code, as all translation should be\n"
-" handled by Blender internal code.\n"
+" handled by Blender internal code. The only exception are string containing formatting (like \"File: %r\"),\n"
+" but you should rather use pgettext_iface/_tip in those cases!\n"
" Note: Does nothing when Blender is built without internationalization support (hence always returns msgid).\n"
"\n"
" :arg msgid: The string to translate.\n"
@@ -515,26 +547,45 @@ PyDoc_STRVAR(app_translations_pgettext_doc,
);
static PyObject *app_translations_pgettext(BlenderAppTranslations *UNUSED(self), PyObject *args, PyObject *kw)
{
- /* Note we could optimize this a bit when WITH_INTERNATIONAL is not defined, but don't think "code complexity" would
- * be worth it, as this func should not often be used!
- */
- /* XXX This code fails with scons when WITH_INTERNATIONAL is not defined, at link time, stating that BLF_pgettext
- * is undefined... So using #ifdef after all, rather than removing scons from blender trunk!
- */
- static const char *kwlist[] = {"msgid", "msgctxt", NULL};
- char *msgid, *msgctxt = NULL;
+ return _py_pgettext(args, kw, BLF_pgettext);
+}
- if (!PyArg_ParseTupleAndKeywords(args, kw, "s|z:bpy.app.translations.pgettext", (char **)kwlist,
- &msgid, &msgctxt))
- {
- return NULL;
- }
+PyDoc_STRVAR(app_translations_pgettext_iface_doc,
+".. method:: pgettext_iface(msgid, msgctxt)\n"
+"\n"
+" Try to translate the given msgid (with optional msgctxt), if labels' translation is enabled.\n"
+" NOTE: See pgettext notes.\n"
+"\n"
+" :arg msgid: The string to translate.\n"
+" :type msgid: string\n"
+" :arg msgctxt: The translation context.\n"
+" :type msgctxt: string or None\n"
+" :default msgctxt: BLF_I18NCONTEXT_DEFAULT value.\n"
+" :return: The translated string (or msgid if no translation was found).\n"
+"\n"
+);
+static PyObject *app_translations_pgettext_iface(BlenderAppTranslations *UNUSED(self), PyObject *args, PyObject *kw)
+{
+ return _py_pgettext(args, kw, BLF_translate_do_iface);
+}
-#ifdef WITH_INTERNATIONAL
- return PyUnicode_FromString(BLF_pgettext(msgctxt ? msgctxt : BLF_I18NCONTEXT_DEFAULT, msgid));
-#else
- return PyUnicode_FromString(msgid);
-#endif
+PyDoc_STRVAR(app_translations_pgettext_tip_doc,
+".. method:: pgettext(msgid, msgctxt)\n"
+"\n"
+" Try to translate the given msgid (with optional msgctxt), if tooltips' translation is enabled.\n"
+" NOTE: See pgettext notes.\n"
+"\n"
+" :arg msgid: The string to translate.\n"
+" :type msgid: string\n"
+" :arg msgctxt: The translation context.\n"
+" :type msgctxt: string or None\n"
+" :default msgctxt: BLF_I18NCONTEXT_DEFAULT value.\n"
+" :return: The translated string (or msgid if no translation was found).\n"
+"\n"
+);
+static PyObject *app_translations_pgettext_tip(BlenderAppTranslations *UNUSED(self), PyObject *args, PyObject *kw)
+{
+ return _py_pgettext(args, kw, BLF_translate_do_tooltip);
}
PyDoc_STRVAR(app_translations_locale_explode_doc,
@@ -575,6 +626,10 @@ PyMethodDef app_translations_methods[] = {
app_translations_py_messages_unregister_doc},
{(char *)"pgettext", (PyCFunction)app_translations_pgettext, METH_VARARGS | METH_KEYWORDS | METH_STATIC,
app_translations_pgettext_doc},
+ {(char *)"pgettext_iface", (PyCFunction)app_translations_pgettext_iface, METH_VARARGS | METH_KEYWORDS | METH_STATIC,
+ app_translations_pgettext_iface_doc},
+ {(char *)"pgettext_tip", (PyCFunction)app_translations_pgettext_tip, METH_VARARGS | METH_KEYWORDS | METH_STATIC,
+ app_translations_pgettext_tip_doc},
{(char *)"locale_explode", (PyCFunction)app_translations_locale_explode, METH_VARARGS | METH_KEYWORDS | METH_STATIC,
app_translations_locale_explode_doc},
{NULL}