BPython -- a few fixes:

-- fixed bug #1689:
http://projects.blender.org/tracker/?func=detail&atid=125&aid=1689&group_id=9

Reported by Tom Musgrove (thanks), the problem was that Window.QHandle was not passing events to windows that had id's below the current active window.  It was a stupid mistake (mine), the code was iterating from curarea instead of from the first area in the areabase list.

-- fixed bug #1568:
http://projects.blender.org/tracker/index.php?func=detail&aid=1568&group_id=9&atid=125

Stephen investigated the problem, reported by Gabriel Beloin, and left hints in the bug report, thanks :).  I also implemented what he suggested, now Effect.Get('objname') returns a list with all objname's effects and as before, Get('objname, position') returns the effect at position 'position'.  Ref doc already updated.

-- Allowed menu registration lines to appear commented out -- Python comments: '#', of course -- (suggested by Michael Reimpell) in scripts:
Some Python doc tools need the doc strings between triple double-quotes, so to avoid conflicts scripts writers can now comment out the registration code, it should work anyway.  Michael also provided a patch for this a few days ago, too (thanks), but to keep changes at a minimum because of proximity to a release I didn't use it.
This commit is contained in:
2004-10-31 04:09:19 +00:00
parent e82d208b1c
commit 13e7525152
6 changed files with 120 additions and 67 deletions

View File

@@ -597,15 +597,18 @@ static int bpymenu_CreateFromDir( char *dirname, int whichdir )
struct stat st;
struct dirent *dir_entry;
BPyMenu *pymenu;
char *s, *fname, str[FILE_MAXFILE + FILE_MAXDIR];
char *s, *fname, pathstr[FILE_MAXFILE + FILE_MAXDIR];
char line[100], w[100];
char name[100], submenu[100], subarg[100], tooltip[100];
int res = 0, version = 0;
dir = opendir( dirname );
if( !dir )
if( !dir ) {
if ( DEBUG )
printf("BPyMenus warning: could not open dir %s.\n", dirname);
return -1;
}
/* we scan the dir for filenames ending with .py and starting with the
* right 'magic number': '#!BPY'. All others are ignored. */
@@ -621,18 +624,18 @@ static int bpymenu_CreateFromDir( char *dirname, int whichdir )
if( !s || *( s + 3 ) != '\0' )
continue;
BLI_make_file_string( "/", str, dirname, fname );
BLI_make_file_string( "/", pathstr, dirname, fname );
/* paranoia: check if this is really a file and not a disguised dir */
if( ( stat( str, &st ) == -1 ) || !S_ISREG( st.st_mode ) )
if( ( stat( pathstr, &st ) == -1 ) || !S_ISREG( st.st_mode ) )
continue;
fp = fopen( str, "rb" );
fp = fopen( pathstr, "rb" );
if( !fp ) {
if( DEBUG )
printf( "BPyMenus error: couldn't open %s.\n",
str );
pathstr );
continue;
}
@@ -647,8 +650,7 @@ static int bpymenu_CreateFromDir( char *dirname, int whichdir )
/* file passed the tests, look for the three double-quotes */
while( fgets( line, 100, fp ) ) {
if( line[0] == '"' && line[1] == '"'
&& line[2] == '"' ) {
if( strstr( line, "\"\"\"" )) {
res = 1; /* found */
break;
}
@@ -658,13 +660,15 @@ static int bpymenu_CreateFromDir( char *dirname, int whichdir )
goto discard;
/* Now we're ready to get the registration info. A little more structure
* was imposed to their format, for speed. The registration
* lines must appear between the first pair of triple double-quotes and
* follow this order (the single-quotes are part of the format):
* was imposed to the format, for speed. The registration lines must
* appear between the first pair of triple double-quotes and
* follow this order (the single-quotes are part of the format,
* but as noted below, now the whole registration part can be commented
* out so external Python tools can ignore them):
*
* Name: 'script name for the menu'
* Group: 'group name' (defines menu)
* Blender: <short int> (minimal Blender version)
* Group: 'group name' (defines menu)
* Submenu: 'submenu name' related_1word_arg
* Tooltip: 'tooltip for the menu'
*
@@ -673,40 +677,42 @@ static int bpymenu_CreateFromDir( char *dirname, int whichdir )
* submenus and the tooltip are optional;
* - the Blender version is the same number reported by
* Blender.Get('version') in BPython or G.version in C;
* - only the first letter of each token is checked, both lower
* and upper cases, so that's all that matters for recognition:
* n 'script name' is enough for the name line, for example. */
* - NEW in 2.35: Michael Reimpell suggested and even provided
* a patch (read but not used to keep changes to a minimum for
* now, shame on me) to make registration code also accept
* commented out registration lines, so that BPython menu
* registration doesn't mess with Python documentation tools. */
/* first the name: */
res = fscanf( fp, "%[^']'%[^'\r\n]'\n", w, name );
if( ( res != 2 ) || ( w[0] != 'n' && w[0] != 'N' ) ) {
if( ( res != 2 ) || !strstr(w, "Name") ) {
if( DEBUG )
printf( "BPyMenus error: wrong 'name' line in %s.\n", str );
printf( "BPyMenus error: wrong 'Name' line in %s.\n", pathstr );
goto discard;
}
/* minimal Blender version: */
res = fscanf( fp, "%s %d\n", w, &version );
if( ( res != 2 ) || !strstr(w, "Blender") ) {
if( DEBUG )
printf( "BPyMenus error: wrong 'Blender' line in %s.\n", pathstr );
goto discard;
}
line[0] = '\0'; /* used as group for this part */
/* minimal Blender version: */
res = fscanf( fp, "%s %d\n", w, &version );
if( ( res != 2 ) || ( w[0] != 'b' && w[0] != 'B' ) ) {
if( DEBUG )
printf( "BPyMenus error: wrong 'blender' line in %s.\n", str );
goto discard;
}
/* the group: */
res = fscanf( fp, "%[^']'%[^'\r\n]'\n", w, line );
if( ( res != 2 ) || ( w[0] != 'g' && w[0] != 'G' ) ) {
if( ( res != 2 ) || !strstr(w, "Group" ) ) {
if( DEBUG )
printf( "BPyMenus error: wrong 'group' line in %s.\n", str );
printf( "BPyMenus error: wrong 'Group' line in %s.\n", pathstr );
goto discard;
}
res = bpymenu_group_atoi( line );
if( res < 0 ) {
if( DEBUG )
printf( "BPyMenus error: unknown 'group' %s in %s.\n", line, str );
printf( "BPyMenus error: unknown 'Group' %s in %s.\n", line, pathstr );
goto discard;
}
@@ -714,7 +720,7 @@ static int bpymenu_CreateFromDir( char *dirname, int whichdir )
whichdir, NULL );
if( !pymenu ) {
if( DEBUG )
printf( "BPyMenus error: couldn't create entry for %s.\n", str );
printf( "BPyMenus error: couldn't create entry for %s.\n", pathstr );
fclose( fp );
closedir( dir );
return -2;
@@ -724,14 +730,14 @@ static int bpymenu_CreateFromDir( char *dirname, int whichdir )
while( fgets( line, 100, fp ) ) {
res = sscanf( line, "%[^']'%[^'\r\n]'%s\n", w, submenu,
subarg );
if( ( res != 3 ) || ( w[0] != 's' && w[0] != 'S' ) )
if( ( res != 3 ) || !strstr( w, "Submenu" ) )
break;
bpymenu_AddSubEntry( pymenu, submenu, subarg );
}
/* the (optional) tooltip: */
res = sscanf( line, "%[^']'%[^'\r\n]'\n", w, tooltip );
if( ( res == 2 ) && ( w[0] == 't' || w[0] == 'T' ) ) {
if( ( res == 2 ) && (!strstr( w, "Tooltip") || !strstr( w, "Tip" ))) {
bpymenu_set_tooltip( pymenu, tooltip );
}

View File

@@ -133,41 +133,74 @@ PyObject *M_Effect_Get( PyObject * self, PyObject * args )
{
/*arguments : string object name
int : position of effect in the obj's effect list */
char *name = 0;
char *name = NULL;
Object *object_iter;
Effect *eff;
BPy_Effect *wanted_eff;
int num, i;
int num = -1, i;
if( !PyArg_ParseTuple( args, "|si", &name, &num ) )
return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
"expected string int argument" ) );
object_iter = G.main->object.first;
if( !object_iter )
return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
"Scene contains no object" ) );
if( name ) {
if( name ) { /* (name, num = -1) - try to find the given object */
while( object_iter ) {
if( strcmp( name, object_iter->id.name + 2 ) ) {
object_iter = object_iter->id.next;
continue;
if( !strcmp( name, object_iter->id.name + 2 ) ) {
eff = object_iter->effect.first; /*can be NULL: None will be returned*/
if (num >= 0) { /* return effect in given num position if available */
for( i = 0; i < num; i++ ) {
if (!eff) break;
eff = eff->next;
}
if( object_iter->effect.first != NULL ) {
eff = object_iter->effect.first;
for( i = 0; i < num; i++ )
eff = eff->next;
wanted_eff =
( BPy_Effect * )
PyObject_NEW( BPy_Effect,
&Effect_Type );
if (eff) {
wanted_eff = (BPy_Effect *)PyObject_NEW(BPy_Effect, &Effect_Type);
wanted_eff->effect = eff;
return ( PyObject * ) wanted_eff;
} else { /* didn't find any effect in the given position */
Py_INCREF(Py_None);
return Py_None;
}
}
else {/*return a list with all effects linked to the given object*/
/* this was pointed by Stephen Swaney */
PyObject *effectlist = PyList_New( 0 );
while (eff) {
BPy_Effect *found_eff = (BPy_Effect *)PyObject_NEW(BPy_Effect,
&Effect_Type);
found_eff->effect = eff;
PyList_Append( effectlist, ( PyObject * ) found_eff );
Py_DECREF((PyObject *)found_eff); /* PyList_Append incref'ed it */
eff = eff->next;
}
return effectlist;
}
}
object_iter = object_iter->id.next;
}
} else {
if (!object_iter)
return EXPP_ReturnPyObjError (PyExc_AttributeError,
"no such object");
}
else { /* () - return a list with all effects currently in Blender */
PyObject *effectlist = PyList_New( 0 );
while( object_iter ) {
if( object_iter->effect.first != NULL ) {
eff = object_iter->effect.first;
@@ -180,6 +213,7 @@ PyObject *M_Effect_Get( PyObject * self, PyObject * args )
PyList_Append( effectlist,
( PyObject * )
found_eff );
Py_DECREF((PyObject *)found_eff);
eff = eff->next;
}
}

View File

@@ -197,7 +197,7 @@ hierarchy (faster)"},
if i is nonzero, empty slots are not ignored: they are returned as None's."},
{"getMatrix", ( PyCFunction ) Object_getMatrix, METH_VARARGS,
"(str = 'worldspace') - Returns the object matrix.\n\
(str = 'localspace') - the wanted matrix: worldspace (default), localspace\n\
(str = 'worldspace') - the wanted matrix: worldspace (default), localspace\n\
or old_worldspace.\n\
\n\
'old_worldspace' was the only behavior before Blender 2.34. With it the\n\
@@ -957,7 +957,7 @@ static PyObject *Object_getMaterials( BPy_Object * self, PyObject * args )
static PyObject *Object_getMatrix( BPy_Object * self, PyObject * args )
{
PyObject *matrix;
char *space = "worldspace"; /* default to local */
char *space = "worldspace"; /* default to world */
if( !PyArg_ParseTuple( args, "|s", &space ) ) {
return ( EXPP_ReturnPyObjError( PyExc_AttributeError,

View File

@@ -971,7 +971,7 @@ static PyObject *M_Window_QAdd( PyObject * self, PyObject * args )
static PyObject *M_Window_QHandle( PyObject * self, PyObject * args )
{
short win;
ScrArea *sa = curarea;
ScrArea *sa = G.curscreen->areabase.first;
ScrArea *oldsa = NULL;
if( !PyArg_ParseTuple( args, "h", &win ) )

View File

@@ -18,7 +18,7 @@ The Blender Python API Reference
- L{Camera}
- L{Curve}
- L{Draw}
- L{Effect}
- L{Effect} (*)
- L{Image}
- L{Ipo}
- L{Lamp}
@@ -97,15 +97,16 @@ Registering scripts:
The header should be like this one (all double and single apostrophes below
are required)::
#!BPY
\"\"\"
Name: 'Script Name'
Blender: 233
Group: 'Export'
Submenu: 'All' all
Submenu: 'Selected' sel
Submenu: 'Configure (gui)' gui
Tooltip: 'Export to some format.'
\"\"\"
# \"\"\"
# Name: 'Script Name'
# Blender: 233
# Group: 'Export'
# Submenu: 'All' all
# Submenu: 'Selected' sel
# Submenu: 'Configure (gui)' gui
# Tooltip: 'Export to some format.'
# \"\"\"
where:
- B{Name} is the string that will appear in the menu;
@@ -115,6 +116,15 @@ Registering scripts:
- B{Submenu} adds optional submenus for further control;
- B{Tooltip} is the (short) tooltip string for the menu entry.
note:
- all double and single apostrophes above are required;
- B{*NEW*}: you can "comment out" the header above, by starting lines with
'#', like we did. This is not required (except for the first line, #!BPY,
of course), but this way the header won't conflict with Python tools that
you can use to generate documentation for your script code. Just
remember to keep this header above any other line with triple
double-quotes (\"\"\") in your script.
Submenu lines are not required, use them if you want to provide extra
options. To see which submenu the user chose, check the "__script__"
dictionary in your code: __script__['arg'] has the defined keyword (the word

View File

@@ -3,6 +3,8 @@
"""
The Blender.Effect submodule
B{new}: now L{Get}('objname') (without specifying second paramenter: 'position') returns a list of all effects linked to object "objname".
INTRODUCTION
The module effect allows you to access all the data of an effect.
@@ -39,16 +41,17 @@ def New (type):
@return: The created Effect.
"""
def Get (objname,position):
def Get (objname, position = None):
"""
Get an Effect from Blender.
@type objname: string
@param objname: The name of object to which is linked the effect.
@type position: string
@param position: The position of the effect in the list of effects liked to the object.
@type position: int
@param position: The position of the effect in the list of effects linked to the object.
@rtype: Blender Effect or a list of Blender Effects
@return: It depends on the 'objname,position' parameters:
- (objname,position): The Effect linked to the given object at the given position;
@return: It depends on the 'objname, position' parameters:
- (objname): A list with all Effects linked to the given object (new);
- (objname, position): The Effect linked to the given object at the given position;
- (): A list with all Effects in the current scene.
"""