Scripts menus:
authorWillian Padovani Germano <wpgermano@gmail.com>
Fri, 16 Jan 2004 23:40:14 +0000 (23:40 +0000)
committerWillian Padovani Germano <wpgermano@gmail.com>
Fri, 16 Jan 2004 23:40:14 +0000 (23:40 +0000)
-- added re-eval entry to Scripts Win -> Scripts menu
-- added it also as a button at Info Win -> File Paths, Python path
-- updated bpymenus code:
    added 'Blender' tag, for version;
    made a .Bpymenus file be written only if there's actual data to save
    made file->export menu open a scriptspace only if none is available already
-- bug fixes (bugs 866 and 879, related) for linking and sharing mesh data:
http://projects.blender.org/tracker/?func=detail&atid=125&aid=866&group_id=9
http://projects.blender.org/tracker/?func=detail&atid=125&aid=879&group_id=9

source/blender/include/blendef.h
source/blender/python/BPY_interface.c
source/blender/python/BPY_menus.c
source/blender/python/BPY_menus.h
source/blender/python/api2_2x/NMesh.c
source/blender/python/api2_2x/Object.c
source/blender/src/header_info.c
source/blender/src/header_script.c
source/blender/src/headerbuttons.c
source/blender/src/space.c

index 204e8b45c3238af3587096f91d11f99ed524ec5b..0cc2c0aefc155cf3decb78240dd1fa79894b8cd9 100644 (file)
 #define B_TEMPDIRFILESEL       337
 /* yafray: for exportdir select */
 #define B_YAFRAYDIRFILESEL     338
+#define B_PYMENUEVAL   339 /* re-eval scripts registration in menus */
 /* END Definitions for the fileselect buttons in user prefs */
 
 /* IMAGE: 350 */
index a543c929c589b0574630b70185050b6c6e5f9bdc..cb5dccd15c1c30a3242fecd5566ff345f6143bbe 100644 (file)
@@ -273,7 +273,7 @@ void init_syspath(void)
 void BPY_post_start_python(void)
 {
   syspath_append(Py_BuildValue("s", U.pythondir));
-       BPyMenu_Init(); /* get dynamic menus (registered scripts) data */
+       BPyMenu_Init(0); /* get dynamic menus (registered scripts) data */
 }
 
 /*****************************************************************************/
index 04469295e053968877066516bcdd775b48c8e96f..545b45efb9df0aac0a5b7707b0ebc869dcb3e8d5 100644 (file)
@@ -184,7 +184,7 @@ static void bpymenu_set_tooltip (BPyMenu *pymenu, char *tip)
  * try to find an existing pymenu entry with the given type and name;
  * if found, update it with new info, otherwise create a new one and fill it.
  */
-static BPyMenu *bpymenu_AddEntry (short group, char *name, char *fname, char *tooltip)
+static BPyMenu *bpymenu_AddEntry (short group, short version, char *name, char *fname, char *tooltip)
 {
        BPyMenu *menu, **iter;
 
@@ -204,6 +204,7 @@ static BPyMenu *bpymenu_AddEntry (short group, char *name, char *fname, char *to
        if (!menu) return NULL;
 
        menu->name = BLI_strdup(name);
+       menu->version = version;
        menu->filename = BLI_strdup(fname);
        menu->tooltip = NULL;
        if (tooltip) menu->tooltip = BLI_strdup(tooltip);
@@ -250,7 +251,7 @@ static void bpymenu_CreateFromFile (void)
 {
        FILE *fp;
        char line[255], w1[255], w2[255], tooltip[255], *tip;
-       int parsing;
+       int parsing, version;
        short group;
        BPyMenu *pymenu = NULL;
 
@@ -298,16 +299,16 @@ static void bpymenu_CreateFromFile (void)
                        if (line[0] == '}') break;
                        else if (line[0] == '\n') continue;
                        else if (line[0] == '\'') { /* menu entry */
-                               parsing = sscanf(line, "'%[^']' %s '%[^']'\n", w1, w2, tooltip);
+                               parsing = sscanf(line, "'%[^']' %d %s '%[^']'\n", w1, &version, w2, tooltip);
 
                                if (parsing <= 0) { /* invalid line, get rid of it */
                                        fgets(line, 255, fp); /* add error report later */
                                }
                                else if (parsing == 3) tip = tooltip; /* has tooltip */
 
-                               pymenu = bpymenu_AddEntry(group, w1, w2, tip);
+                               pymenu = bpymenu_AddEntry(group, (short)version, w1, w2, tip);
                                if (!pymenu) {
-                                       puts("BpyMenus error: couldn't create bpymenu entry.\n");
+                                       puts("BPyMenus error: couldn't create bpymenu entry.\n");
                                        fclose(fp);
                                        return;
                                }
@@ -351,7 +352,7 @@ static void bpymenu_WriteDataFile(void)
                if (!pymenu) continue;
                fprintf(fp, "\n%s {\n", BPyMenu_group_itoa(i));
                while (pymenu) {
-                       fprintf(fp, "'%s' %s", pymenu->name, pymenu->filename);
+                       fprintf(fp,"'%s' %d %s", pymenu->name, pymenu->version, pymenu->filename);
                        if (pymenu->tooltip) fprintf(fp, " '%s'\n", pymenu->tooltip);
                        else fprintf(fp, "\n");
                        smenu = pymenu->submenus;
@@ -383,7 +384,7 @@ void BPyMenu_PrintAllEntries(void)
                pymenu = BPyMenuTable[i];
                printf("\n%s {\n", BPyMenu_group_itoa(i));
                while (pymenu) {
-                       printf("'%s' %s", pymenu->name, pymenu->filename);
+                       printf("'%s' %d %s", pymenu->name, pymenu->version, pymenu->filename);
                        if (pymenu->tooltip) printf(" '%s'\n", pymenu->tooltip);
                        else printf("\n");
                        smenu = pymenu->submenus;
@@ -411,7 +412,7 @@ static void bpymenu_CreateFromDir (void)
        char *s, *fname, str[FILE_MAXFILE+FILE_MAXDIR];
        char line[100], w[100];
        char name[100], submenu[100], subarg[100], tooltip[100];
-       int res = 0;
+       int res = 0, version = 0;
 
        dir = opendir(U.pythondir);
 
@@ -470,12 +471,15 @@ static void bpymenu_CreateFromDir (void)
                 * 
                 * Name: 'script name for the menu'
                 * Group: 'group name' (defines menu)
+                * Blender: <short int> (minimal Blender version)
                 * Submenu: 'submenu name' related_1word_arg
                 * Tooltip: 'tooltip for the menu'
                 *
                 * notes:
                 * - there may be more than one submenu line, or none:
                 * 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. */ 
@@ -489,6 +493,13 @@ static void bpymenu_CreateFromDir (void)
 
                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')) {
+                       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')) {
@@ -502,7 +513,7 @@ static void bpymenu_CreateFromDir (void)
                        goto discard;
                }
 
-               pymenu = bpymenu_AddEntry(res, name, fname, NULL);
+               pymenu = bpymenu_AddEntry(res, (short)version, name, fname, NULL);
                if (!pymenu) {
                        printf("BPyMenus error: couldn't create entry for %s.\n", str);
                        fclose(fp);
@@ -537,52 +548,64 @@ discard:
  * - the BPYMENU_DATAFILE file (~/.Bpymenus) or
  * - the scripts dir, case it's newer than the datafile (then update the file).
  * then fill the bpymenu table with this data.
+ * if param usedir != 0, then the data is recreated from the dir anyway.
 */
-void BPyMenu_Init(void)
+int BPyMenu_Init(int usedir)
 {
        char fname[FILE_MAXDIR+FILE_MAXFILE];
        struct stat st;
-       time_t tdir, tfile;
+       time_t tdir, tfile = 0;
        int result = 0;
 
        result = stat(U.pythondir, &st);
 
        if (result == -1) {
-               printf ("\n# Scripts dir: %s\nError: %s\n", U.pythondir, strerror(errno));
-               printf ("# Please go to 'Info window -> File Paths tab' and set a valid "
-                                               "# path for\nthe Blender Python scripts dir.\n");
-               return;
+               printf ("\n# Scripts dir: %s\nError: %s\n", U.pythondir, strerror(errno));
+               printf ("# Please go to 'Info window -> File Paths tab' and set a valid\n"
+                                               "# path for the Blender Python scripts dir.\n");
+               return -1;
        }
 
        if (!S_ISDIR(st.st_mode)) {
                printf ("\n# Scripts dir: %s is not a directory!", U.pythondir);
-               printf ("# Please go to 'Info window -> File Paths tab' and set a valid "
+               printf ("# Please go to 'Info window -> File Paths tab' and set a valid\n"
                                                "# path for\nthe Blender Python scripts dir.\n");
-               return;
+               return -1;
        }
 
        printf("Registering scripts in Blender menus:\n");
 
        tdir = st.st_mtime;
 
-       BLI_make_file_string(NULL, fname, BLI_gethome(), BPYMENU_DATAFILE);
+       if (!usedir) { /* if we're not forced to use the dir */
+               BLI_make_file_string(NULL, fname, BLI_gethome(), BPYMENU_DATAFILE);
 
-       result = stat(fname, &st);
-       if ((result == -1) || !S_ISREG(st.st_mode)) tfile = 0;
-       else tfile = st.st_mtime;
+               result = stat(fname, &st);
+               if ((result != -1) && S_ISREG(st.st_mode)) tfile = st.st_mtime;
+       }
 
        /* comparing dates */
 
        if (tdir > tfile) { /* if so, dir is newer */
                printf("Getting menu data from dir: %s\n", U.pythondir);
                bpymenu_CreateFromDir();
-               bpymenu_WriteDataFile(); /* recreate the file */
-               return;
+
+               /* check if we got any data */
+               for (result = 0; result < PYMENU_TOTAL; result++)
+                       if (BPyMenuTable[result]) break;
+               /* if we got, recreate the file */
+               if (result < PYMENU_TOTAL) bpymenu_WriteDataFile();
+               else
+                       printf ("# Warning: Registering scripts in menus -- no info found.\n"
+                                                       "# Either your scripts dir has no .py scripts or they don't\n"
+                                                       "# have registration data.\n");
+
+               return 0;
        }
        else { /* file is newer */
                printf("Getting menu data from file: %s\n", fname);
                bpymenu_CreateFromFile();
        }
 
-       return;
+       return 0;
 }
index 8451a122f066cfa06447f46529a97c8f409eaa79..4bcb1f9034027f861e9e21a4e17e143e98b62f00 100644 (file)
@@ -61,6 +61,7 @@ typedef struct BPyMenu {
        char *name;
        char *filename;
        char *tooltip;
+       short version; /* Blender version */
        struct BPySubMenu *submenus;
        struct BPyMenu *next;
 } BPyMenu;
@@ -89,7 +90,7 @@ typedef enum {
 BPyMenu *BPyMenuTable[PYMENU_TOTAL];
 
 /* public functions: */
-void BPyMenu_Init(void);
+int BPyMenu_Init(int usedir);
 void BPyMenu_RemoveAllEntries(void);
 void BPyMenu_PrintAllEntries(void);
 char *BPyMenu_CreatePupmenuStr(BPyMenu *pym, short group);
index 14d3e47876ce7db612387b0ec30c086fc4f9dd5f..473ae7666d3f9e9662fac30a731160ea3a373eaa 100644 (file)
@@ -24,7 +24,8 @@
  *
  * This is a new part of Blender.
  *
- * Contributor(s): Willian P. Germano, Jordi Rovira i Bonet, Joseph Gilbert
+ * Contributor(s): Willian P. Germano, Jordi Rovira i Bonet, Joseph Gilbert,
+ * Bala Gi
  *
  * ***** END GPL/BL DUAL LICENSE BLOCK *****
  */
@@ -845,12 +846,6 @@ static PyObject *NMesh_update(PyObject *self, PyObject *args)
        mesh_update(mesh);
 
        nmesh_updateMaterials(nmesh);
-/**@ This is another ugly fix due to the weird material handling of blender.
-       * it makes sure that object material lists get updated (by their length)
-       * according to their data material lists, otherwise blender crashes.
-       * It just stupidly runs through all objects...BAD BAD BAD.
-       */
-       test_object_materials((ID *)mesh);
 
        if (nmesh->name && nmesh->name != Py_None)
                new_id(&(G.main->mesh), &mesh->id, PyString_AsString(nmesh->name));
@@ -1775,6 +1770,14 @@ Material **nmesh_updateMaterials(BPy_NMesh *nmesh)
                matlist = 0;
        }
        mesh->totcol = len;
+
+/**@ This is another ugly fix due to the weird material handling of blender.
+       * it makes sure that object material lists get updated (by their length)
+       * according to their data material lists, otherwise blender crashes.
+       * It just stupidly runs through all objects...BAD BAD BAD.
+       */
+       test_object_materials((ID *)mesh);
+
        return matlist;
 }
 
@@ -1950,12 +1953,6 @@ static int convert_NMeshToMesh (Mesh *mesh, BPy_NMesh *nmesh)
                }
        }
 
-       //-- balagi 01/14/2004 , fix supplied by ascotan
-       if(nmesh->materials){ 
-               mesh->mat = EXPP_newMaterialList_fromPyList (nmesh->materials); 
-       }
-       //-- balagi end
-
        return 1;
 }
 
@@ -2213,6 +2210,9 @@ Mesh *Mesh_FromPyObject (PyObject *pyobj, Object *ob)
                        new_id(&(G.main->mesh), &mesh->id, PyString_AsString(nmesh->name));
 
                mesh_update(mesh);
+
+               nmesh_updateMaterials(nmesh);
+
                return mesh;
        }
 
index 88123c002b68689ee3652ce9087a677615c3771e..90ea1924309e83afb940be1e9fe2b7700f617854 100644 (file)
@@ -27,7 +27,8 @@
  * the Python interface.
  *
  *
- * Contributor(s): Michel Selten
+ * Contributor(s): Michel Selten, Willian Germano, Jacques Guignot,
+ * Joseph Gilbert, Stephen Swaney, Bala Gi
  *
  * ***** END GPL/BL DUAL LICENSE BLOCK *****
 */
@@ -992,17 +993,13 @@ static PyObject *Object_link (BPy_Object *self, PyObject *args)
                                "Linking this object type is not supported"));
        }
        self->object->data = data;
-       
-       //-- balagi 01/14/2004
-       /*
-               if a mesh is shared the self->object material list must be setup properly !
-       */
-       if ( self->object->type == OB_MESH && id )
+
+       if ( self->object->type == OB_MESH)
        {
+               self->object->totcol = 0;
                EXPP_synchronizeMaterialLists(self->object, id);
        }
-       //-- balagi end
-       
+
        id_us_plus (id);
        if (oldid)
        {
@@ -1343,8 +1340,8 @@ static PyObject *Object_shareFrom (BPy_Object *self, PyObject *args)
                        id = (ID*) object->object->data;
                        self->object->data = object->object->data;
 
-                       //if a mesh is shared the self->object material list must be setup properly ! - balagi
                        if ( self->object->type == OB_MESH && id ){
+                               self->object->totcol = 0;
                                EXPP_synchronizeMaterialLists(self->object, id);
                        }
                        
index 1bb54d696fa3ff9ec486f1c96ba53720c2115d54..631258ccc16d76d3cd225152000d13fce823b152 100644 (file)
@@ -700,7 +700,8 @@ static void do_info_file_exportmenu(void *arg, int event)
        ScrArea *sa;
 
        if(curarea->spacetype==SPACE_INFO) {
-               sa= closest_bigger_area();
+               sa= find_biggest_area_of_type(SPACE_SCRIPT);
+               if (!sa) sa= closest_bigger_area();
                areawinset(sa->win);
        }
 
index a56cede074638d82b51a2274eb26058d202b1aed..3c97575e52801168dd88b1157b4668b5893f4c1a 100644 (file)
@@ -114,6 +114,27 @@ static uiBlock *script_scripts_submenus(void *int_menutype)
        return block;
 }
 
+static void do_script_scriptsmenu(void *arg, int event)
+{
+       ScrArea *sa;
+       char dir[FILE_MAXDIR];
+       
+       if(curarea->spacetype==SPACE_INFO) {
+               sa= closest_bigger_area();
+               areawinset(sa->win);
+       }
+
+       /* these are no defines, easier this way, the codes are in the function below */
+       switch(event) {
+       case 0: /* update menus */
+               BPyMenu_RemoveAllEntries();
+               if (BPyMenu_Init(1) == -1) error("Invalid scripts dir: check console");
+               break;
+       }
+
+//     allqueue(REDRAWSCRIPT, 0);
+}
+
 /* Scripts menu */
 static uiBlock *script_scriptsmenu(void *arg_unused)
 {
@@ -124,12 +145,14 @@ static uiBlock *script_scriptsmenu(void *arg_unused)
        int i;
 
        block= uiNewBlock(&curarea->uiblocks, "script_scriptsmenu", UI_EMBOSSP, UI_HELV, curarea->headwin);
-       //uiBlockSetButmFunc(block, do_script_scriptsmenu, NULL);
+       uiBlockSetButmFunc(block, do_script_scriptsmenu, NULL);
 
        for (i = 0; i < PYMENU_TOTAL; i++) {
                uiDefIconTextBlockBut(block, script_scripts_submenus, (void *)i, ICON_RIGHTARROW_THIN, BPyMenu_group_itoa(i), 0, yco-=20, menuwidth, 19, "");
        }
 
+       uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Update Menus", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 0, "Use when you modify the scripts dir or its contents");
+
        if(curarea->headertype==HEADERTOP) {
                uiBlockSetDirection(block, UI_DOWN);
        }
index 7057dd11445cfda371852d9e651ad2d97ae80ff9..ef3d78deab906ef59758ef2ef73d6a540e5b9ebd 100644 (file)
 #include "BDR_editmball.h"
 
 #include "BPY_extern.h"
+#include "BPY_menus.h"
 
 #include "mydevice.h"
 #include "blendef.h"
@@ -1502,6 +1503,11 @@ void do_global_buttons(unsigned short event)
                activate_fileselect(FILE_SPECIAL, "SELECT RENDER PATH", U.renderdir, filesel_u_renderdir);
                break;
 
+       case B_PYMENUEVAL: /* is button from space.c *info* */
+               BPyMenu_RemoveAllEntries(); /* free old data */
+               if (BPyMenu_Init(1) == -1) /* re-eval scripts registration in menus */
+                       error("Invalid scripts dir: check console");
+               break;
        case B_PYTHONDIRFILESEL:        /* is button from space.c  *info* */
                if(curarea->spacetype==SPACE_INFO) {
                        sa= closest_bigger_area();
index f0565357ad1e25a2008777a9d8eba1bd08ae2438..4d89b93ecde00b42e893c2d77df5615052be7a25 100644 (file)
@@ -1929,7 +1929,7 @@ void drawinfospace(ScrArea *sa, void *spacedata)
        medprefbut = 193;       /* standard size for medium preferences button */
        largeprefbut = 292;     /* standard size for large preferences button */
        smfileselbut = buth;    /* standard size for fileselect button (square) */
-       
+
        edgespace = 3;          /* space from edge of end 'tab' to edge of end button */
        midspace = 5;           /* horizontal space between buttons */
 
@@ -2474,8 +2474,11 @@ void drawinfospace(ScrArea *sa, void *spacedata)
                        0, 0, 0, 0, 0, "Select the default render output location");
 
                uiDefBut(block, TEX, 0, "Python: ",
-                       (xpos+edgespace+largeprefbut+midspace),y1,(largeprefbut-smfileselbut),buth,
+                       (xpos+edgespace+largeprefbut+midspace),y1,(largeprefbut-2*smfileselbut),buth,
                        U.pythondir, 1.0, 63.0, 0, 0, "The default directory to search for Python scripts");
+               uiDefIconBut(block, BUT, B_PYMENUEVAL, ICON_SCRIPT,
+                       (xpos+edgespace+(2*largeprefbut)+midspace-2*smfileselbut),y1,smfileselbut,buth,
+                       0, 0, 0, 0, 0, "Re-evaluate scripts registration in menus");
                uiDefIconBut(block, BUT, B_PYTHONDIRFILESEL, ICON_FILESEL,
                        (xpos+edgespace+(2*largeprefbut)+midspace-smfileselbut),y1,smfileselbut,buth,
                        0, 0, 0, 0, 0, "Select the default Python script location");