Added a NULL check that was needed.
[blender.git] / source / blender / src / filesel.c
index 760e200ee269f619d00b8dd73a5845ef851317ca..1bdca25a88d0fc149074c0db16140b15d0cc5ac8 100644 (file)
 #include "BKE_material.h"
 #include "BKE_utildefines.h"
 
+#include "BIF_editview.h"
+#include "BIF_filelist.h"
 #include "BIF_gl.h"
 #include "BIF_interface.h"
-#include "BIF_toolbox.h"
+#include "BIF_language.h"
 #include "BIF_mywindow.h"
-#include "BIF_editview.h"
+#include "BIF_resources.h"
 #include "BIF_space.h"
 #include "BIF_screen.h"
-#include "BIF_resources.h"
-#include "BIF_language.h"
+#include "BIF_toolbox.h"
+#include "BIF_usiblender.h"
 
 #include "BLO_readfile.h"
 
 
 #include "BIF_fsmenu.h"  /* include ourselves */
 
-#if defined WITH_ICONV
-       #include "iconv.h"
+#ifdef INTERNATIONAL
+#include "FTF_Api.h"
 #endif
 
 #if defined WIN32 || defined __BeOS
-int fnmatch(const char *pattern, const char *string, int flags)
+static int fnmatch(const char *pattern, const char *string, int flags)
 {
        return 0;
 }
@@ -148,6 +150,8 @@ int fnmatch(const char *pattern, const char *string, int flags)
 #define B_FS_CANCEL    6
 #define B_FS_LIBNAME   7
 
+/* max length of library group name within filesel */
+#define GROUP_MAX 32
 
 static int is_a_library(SpaceFile *sfile, char *dir, char *group);
 static void do_library_append(SpaceFile *sfile);
@@ -167,155 +171,6 @@ static float pixels_to_ofs;
 static char otherdir[FILE_MAX];
 static ScrArea *otherarea;
 
-/* FSMENU HANDLING */
-
-       /* FSMenuEntry's without paths indicate seperators */
-typedef struct _FSMenuEntry FSMenuEntry;
-struct _FSMenuEntry {
-       FSMenuEntry *next;
-
-       char *path;
-};
-
-static FSMenuEntry *fsmenu= 0;
-
-int fsmenu_get_nentries(void)
-{
-       FSMenuEntry *fsme;
-       int count= 0;
-
-       for (fsme= fsmenu; fsme; fsme= fsme->next) 
-               count++;
-
-       return count;
-}
-int fsmenu_is_entry_a_seperator(int idx)
-{
-       FSMenuEntry *fsme;
-
-       for (fsme= fsmenu; fsme && idx; fsme= fsme->next)
-               idx--;
-
-       return (fsme && !fsme->path)?1:0;
-}
-char *fsmenu_get_entry(int idx)
-{
-       FSMenuEntry *fsme;
-
-       for (fsme= fsmenu; fsme && idx; fsme= fsme->next)
-               idx--;
-
-       return fsme?fsme->path:NULL;
-}
-char *fsmenu_build_menu(void)
-{
-       DynStr *ds= BLI_dynstr_new();
-       FSMenuEntry *fsme;
-       char *menustr;
-
-       for (fsme= fsmenu; fsme; fsme= fsme->next) {
-               if (!fsme->path) {
-                               /* clean consecutive seperators and ignore trailing ones */
-                       if (fsme->next) {
-                               if (fsme->next->path) {
-                                       BLI_dynstr_append(ds, "%l|");
-                               } else {
-                                       FSMenuEntry *next= fsme->next;
-                                       fsme->next= next->next;
-                                       MEM_freeN(next);
-                               }
-                       }
-               } else {
-                       BLI_dynstr_append(ds, fsme->path);
-                       if (fsme->next) BLI_dynstr_append(ds, "|");
-               }
-       }
-
-       menustr= BLI_dynstr_get_cstring(ds);
-       BLI_dynstr_free(ds);
-       return menustr;
-}
-static FSMenuEntry *fsmenu_get_last_separator(void) 
-{
-       FSMenuEntry *fsme, *lsep=NULL;
-
-       for (fsme= fsmenu; fsme; fsme= fsme->next)
-               if (!fsme->path)
-                       lsep= fsme;
-
-       return lsep;
-}
-void fsmenu_insert_entry(char *path, int sorted)
-{
-       FSMenuEntry *prev= fsmenu_get_last_separator();
-       FSMenuEntry *fsme= prev?prev->next:fsmenu;
-
-       for (; fsme; prev= fsme, fsme= fsme->next) {
-               if (fsme->path) {
-                       if (BLI_streq(path, fsme->path)) {
-                               return;
-                       } else if (sorted && strcmp(path, fsme->path)<0) {
-                               break;
-                       }
-               }
-       }
-       
-       fsme= MEM_mallocN(sizeof(*fsme), "fsme");
-       fsme->path= BLI_strdup(path);
-
-       if (prev) {
-               fsme->next= prev->next;
-               prev->next= fsme;
-       } else {
-               fsme->next= fsmenu;
-               fsmenu= fsme;
-       }
-}
-void fsmenu_append_seperator(void)
-{
-       if (fsmenu) {
-               FSMenuEntry *fsme= fsmenu;
-
-               while (fsme->next) fsme= fsme->next;
-
-               fsme->next= MEM_mallocN(sizeof(*fsme), "fsme");
-               fsme->next->next= NULL;
-               fsme->next->path= NULL;
-       }
-}
-void fsmenu_remove_entry(int idx)
-{
-       FSMenuEntry *prev= NULL, *fsme= fsmenu;
-
-       for (fsme= fsmenu; fsme && idx; prev= fsme, fsme= fsme->next)
-               if (fsme->path)
-                       idx--;
-
-       if (fsme) {
-               if (prev) {
-                       prev->next= fsme->next;
-               } else {
-                       fsmenu= fsme->next;
-               }
-
-               MEM_freeN(fsme->path);
-               MEM_freeN(fsme);
-       }
-}
-void fsmenu_free(void)
-{
-       FSMenuEntry *fsme= fsmenu;
-
-       while (fsme) {
-               FSMenuEntry *n= fsme->next;
-
-               if (fsme->path) MEM_freeN(fsme->path);
-               MEM_freeN(fsme);
-
-               fsme= n;
-       }
-}
-
 /* ******************* SORT ******************* */
 
 static int compare_name(const void *a1, const void *a2)
@@ -508,7 +363,7 @@ void test_flags_file(SpaceFile *sfile)
                                        }
                                }
                        }
-               } else if (sfile->type==FILE_SPECIAL){
+               } else if (sfile->type==FILE_SPECIAL || sfile->type==FILE_LOADFONT){
                        if(BLI_testextensie(file->relname, ".py")) {
                                file->flags |= PYSCRIPTFILE;                    
                        } else if( BLI_testextensie(file->relname, ".ttf")
@@ -532,6 +387,9 @@ void test_flags_file(SpaceFile *sfile)
                                        ||      BLI_testextensie(file->relname, ".rgb")
                                        ||      BLI_testextensie(file->relname, ".bmp")
                                        ||      BLI_testextensie(file->relname, ".png")
+#ifdef WITH_DDS
+                                       ||      BLI_testextensie(file->relname, ".dds")
+#endif
                                        ||      BLI_testextensie(file->relname, ".iff")
                                        ||      BLI_testextensie(file->relname, ".lbm")
                                        ||      BLI_testextensie(file->relname, ".gif")
@@ -563,6 +421,9 @@ void test_flags_file(SpaceFile *sfile)
                                        ||      BLI_testextensie(file->relname, ".rgb")
                                        ||      BLI_testextensie(file->relname, ".bmp")
                                        ||      BLI_testextensie(file->relname, ".png")
+#ifdef WITH_DDS
+                                       ||      BLI_testextensie(file->relname, ".dds")
+#endif
                                        ||      BLI_testextensie(file->relname, ".iff")
                                        ||      BLI_testextensie(file->relname, ".lbm")
                                        ||  BLI_testextensie(file->relname, ".cin")
@@ -893,31 +754,6 @@ static void linerect(int id, int x, int y)
 
 }
 
-#ifdef WITH_ICONV
-static void string_to_utf8(char *original, char *utf_8) 
-{
-       size_t inbytesleft=strlen(original);
-       size_t outbytesleft=512;
-       size_t rv=0;
-       iconv_t cd;
-       
-       cd=iconv_open("UTF-8", "gb2312");
-       if (cd == (iconv_t)(-1)) {
-               printf("iconv_open Error");
-               *utf_8='\0';
-               return ;
-       }
-       rv=iconv(cd, &original, &inbytesleft, &utf_8, &outbytesleft);
-       if (rv == (size_t) -1) {
-               printf("iconv Error\n");
-               return ;
-       }
-       *utf_8 = '\0';
-       iconv_close(cd);
-}
-#endif
-
-
 static void print_line(SpaceFile *sfile, struct direntry *files, int x, int y)
 {
        int boxcol=0;
@@ -967,15 +803,26 @@ static void print_line(SpaceFile *sfile, struct direntry *files, int x, int y)
                glRasterPos2i(x,  y);
 #ifdef WITH_ICONV
                {
-                       char utf_8[512];
-                       string_to_utf8(files->relname, utf_8);
-                       BIF_RasterPos((float)x, (float)y);      /* texture fonts */
-                       BIF_DrawString(G.font, utf_8, (U.transopts & USER_TR_MENUS));
-               }
+                       struct LANGMenuEntry *lme;
+                       lme = find_language(U.language);
+
+                       if ((lme !=NULL) && (!strcmp(lme->code, "ja_JP") || 
+                               !strcmp(lme->code, "zh_CN")))
+                       {
+                               BIF_RasterPos((float)x, (float)y);
+#ifdef WIN32
+                               BIF_DrawString(G.font, files->relname, ((U.transopts & USER_TR_MENUS) | CONVERT_TO_UTF8));
 #else
-               BMF_DrawString(G.font, files->relname);
+                               BIF_DrawString(G.font, files->relname, (U.transopts & USER_TR_MENUS));
 #endif
-               
+                       } else {
+                               BMF_DrawString(G.font, files->relname);
+                       }
+               }
+#else
+                       BMF_DrawString(G.font, files->relname);
+#endif /* WITH_ICONV */
+
                x += sfile->maxnamelen + 100;
 
                glRasterPos2i(x - BMF_GetStringWidth(G.font, files->size),  y);
@@ -1135,10 +982,10 @@ static char *library_string(void)
        int nr=0, tot= BLI_countlist(&G.main->library);
        
        if(tot==0) return NULL;
-       str= MEM_callocN(tot*(FILE_MAX), "filesel lib menu");
+       str= MEM_callocN(tot*(FILE_MAXDIR+FILE_MAX), "filesel lib menu");
        
        for(tot=0, lib= G.main->library.first; lib; lib= lib->id.next, nr++) {
-               tot+= sprintf(str+tot, "%s %%x%d|", lib->name+2, nr);
+               tot+= sprintf(str+tot, "%s %%x%d|", lib->name, nr);
        }
        return str;
 }
@@ -1309,7 +1156,7 @@ static void activate_fileselect_(int type, char *title, char *file, short *menup
                                                                                 void *arg1, void *arg2)
 {
        SpaceFile *sfile;
-       char group[24], name[FILE_MAX], temp[FILE_MAX];
+       char group[GROUP_MAX], name[FILE_MAX], temp[FILE_MAX];
        
        if(curarea==0) return;
        if(curarea->win==0) return;
@@ -1342,8 +1189,10 @@ static void activate_fileselect_(int type, char *title, char *file, short *menup
        /* sfile->act is used for databrowse: double names of library objects */
        sfile->act= -1;
 
-       if(BLI_convertstringcode(name, G.sce, G.scene->r.cfra)) sfile->flag |= FILE_STRINGCODE;
-       else sfile->flag &= ~FILE_STRINGCODE;
+       if(G.relbase_valid && BLI_convertstringcode(name, G.sce, G.scene->r.cfra))
+               sfile->flag |= FILE_STRINGCODE;
+       else
+               sfile->flag &= ~FILE_STRINGCODE;
 
        if (U.uiflag & USER_HIDE_DOT)
                sfile->flag |= FILE_HIDE_DOT;
@@ -1377,7 +1226,7 @@ static void activate_fileselect_(int type, char *title, char *file, short *menup
                        sfile->libfiledata= NULL;
                }
        }
-       else {  /* FILE_BLENDER */
+       else {  /* FILE_BLENDER or FILE_LOADFONT */
                split_sfile(sfile, name);       /* test filelist too */
                BLI_cleanup_dir(G.sce, sfile->dir);
 
@@ -1404,41 +1253,6 @@ void activate_fileselect_args(int type, char *title, char *file, void (*func)(ch
        activate_fileselect_(type, title, file, NULL, NULL, NULL, NULL, func, arg1, arg2);
 }
 
-
-void activate_imageselect(int type, char *title, char *file, void (*func)(char *))
-{
-       SpaceImaSel *simasel;
-       char dir[FILE_MAX], name[FILE_MAX];
-       
-       if(curarea==NULL) return;
-       if(curarea->win==0) return;
-       
-       newspace(curarea, SPACE_IMASEL);
-       
-       /* sometimes double, when area is already SPACE_FILE with a different file name */
-       addqueue(curarea->headwin, CHANGED, 1);
-       addqueue(curarea->win, CHANGED, 1);
-
-       name[2]= 0;
-       BLI_strncpy(name, file, sizeof(name));
-
-       simasel= curarea->spacedata.first;
-       simasel->returnfunc= func;
-
-       if(BLI_convertstringcode(name, G.sce, G.scene->r.cfra)) simasel->mode |= IMS_STRINGCODE;
-       else simasel->mode &= ~IMS_STRINGCODE;
-       
-       BLI_split_dirfile(name, dir, simasel->file);
-       BLI_cleanup_dir(G.sce, simasel->dir);
-       if(strcmp(dir, simasel->dir)!=0) simasel->fase= 0;
-
-       BLI_strncpy(simasel->dir, dir, sizeof(simasel->dir));
-       BLI_strncpy(simasel->title, title, sizeof(simasel->title));
-       
-       /* filetoname= 1; */
-}
-
-
 void activate_databrowse(ID *id, int idcode, int fromcode, int retval, short *menup, void (*func)(unsigned short))
 {
        ListBase *lb;
@@ -1608,7 +1422,7 @@ static void filesel_execute(SpaceFile *sfile)
                allqueue(REDRAWALL, 1);
        }
        else if(filesel_has_func(sfile)) {
-               fsmenu_insert_entry(sfile->dir, 1);
+               fsmenu_insert_entry(sfile->dir, 1, 0);
        
                if(sfile->type==FILE_MAIN) { /* DATABROWSE */
                        if (sfile->menup) {     /* with value pointing to ID block index */
@@ -1665,16 +1479,9 @@ static void filesel_execute(SpaceFile *sfile)
                        strcat(name, sfile->file);
                        
                        if(sfile->flag & FILE_STRINGCODE) {
-                               if (!G.relbase_valid) {
-                                       /* skip save */
-                                       if(strncmp(sfile->title, "Save", 4)) {
-                                               okee("You have to save the .blend file before using relative paths! Using absolute path instead.");
-                                               sfile->flag &= ~FILE_STRINGCODE;
-                                       }
-                               }
-                               else {
+                               /* still weak, but we don't want saving files to make relative paths */
+                               if(strncmp(sfile->title, "Save", 4))
                                        BLI_makestringcode(G.sce, name);
-                               }
                        }
                        if(sfile->returnfunc)
                                sfile->returnfunc(name);
@@ -2029,14 +1836,23 @@ void winqreadfilespace(ScrArea *sa, void *spacedata, BWinEvent *evt)
                                                strcat(sfile->dir, sfile->filelist[act].relname);
                                                strcat(sfile->dir,"/");
                                                BLI_cleanup_dir(G.sce, sfile->dir);
-                                               freefilelist(sfile);
+                                               freefilelist(sfile);                                            
                                                sfile->ofs= 0;
                                                do_draw= 1;
                                        }
                                        else {
                                                if( strcmp(sfile->file, sfile->filelist[act].relname)) {
+                                                       char tmpstr[240];
                                                        do_draw= 1;
                                                        BLI_strncpy(sfile->file, sfile->filelist[act].relname, sizeof(sfile->file));
+                                                       if (sfile->f_fp) {
+                                                               sprintf (tmpstr, "%s%s", sfile->dir, sfile->file);
+                                                               /* printf ("%s\n", tmpstr); */
+                                                               #ifdef INTERNATIONAL
+                                                               if (!FTF_GetNewFont ((const unsigned char *)tmpstr, 0, U.fontsize))
+                                                                       error ("No font file");
+                                                               #endif
+                                                       }
                                                }
                                                if(event==MIDDLEMOUSE && sfile->type) filesel_execute(sfile);
                                        }
@@ -2319,10 +2135,10 @@ void winqreadfilespace(ScrArea *sa, void *spacedata, BWinEvent *evt)
 
 static int groupname_to_code(char *group)
 {
-       char buf[32];
+       char buf[GROUP_MAX];
        char *lslash;
        
-       BLI_strncpy(buf, group, 31);
+       BLI_strncpy(buf, group, GROUP_MAX);
        lslash= BLI_last_slash(buf);
        if (lslash)
                lslash[0]= '\0';
@@ -2342,7 +2158,7 @@ static int is_a_library(SpaceFile *sfile, char *dir, char *group)
        len= strlen(dir);
        if(len<7) return 0;
        if( dir[len-1] != '/' && dir[len-1] != '\\') return 0;
-               
+       
        group[0]= 0;
        dir[len-1]= 0;
 
@@ -2352,14 +2168,19 @@ static int is_a_library(SpaceFile *sfile, char *dir, char *group)
        if(fd==0) return 0;
        *fd= 0;
        if(BLO_has_bfile_extension(fd+1)) {
-               *fd= '/';
+               /* the last part of the dir is a .blend file, no group follows */
+               *fd= '/'; /* put back the removed slash separating the dir and the .blend file name */
        }
-       else {
-               strcpy(group, fd+1);
-                       
+       else {          
+               char *gp = fd+1; // in case we have a .blend file, gp points to the group
+
                /* Find the last slash */
                fd= (strrchr(dir, '/')>strrchr(dir, '\\'))?strrchr(dir, '/'):strrchr(dir, '\\');
                if (!fd || !BLO_has_bfile_extension(fd+1)) return 0;
+
+               /* now we know that we are in a blend file and it is safe to 
+                  assume that gp actually points to a group */
+               BLI_strncpy(group, gp, GROUP_MAX);
        }
        return 1;
 }
@@ -2367,7 +2188,7 @@ static int is_a_library(SpaceFile *sfile, char *dir, char *group)
 static void do_library_append(SpaceFile *sfile)
 {
        Library *lib;
-       char dir[FILE_MAX], group[32];
+       char dir[FILE_MAX], group[GROUP_MAX];
        
        if ( is_a_library(sfile, dir, group)==0 ) {
                error("Not a library");
@@ -2381,8 +2202,12 @@ static void do_library_append(SpaceFile *sfile)
                Object *ob;
                int idcode = groupname_to_code(group);
                
+               if((sfile->flag & FILE_LINK)==0)
+                       /* tag everything, all untagged data can be made local */
+                       flag_all_listbases_ids(LIB_APPEND_TAG, 1);
+               
                BLO_library_append(sfile, dir, idcode);
-
+               
                /* DISPLISTS? */
                ob= G.main->object.first;
                while(ob) {
@@ -2399,14 +2224,18 @@ static void do_library_append(SpaceFile *sfile)
                        lib= lib->id.next;
                }
                
-               if(lib) {
-                       if((sfile->flag & FILE_LINK)==0) 
-                               all_local(lib);
+               /* make local */
+               if(lib && (sfile->flag & FILE_LINK)==0) {
+                       all_local(lib, 1);
+                       /* important we unset, otherwise these object wont
+                        * link into other scenes from this blend file */
+                       flag_all_listbases_ids(LIB_APPEND_TAG, 0);
                }
                
+               DAG_scene_sort(G.scene);
+               
                /* in sfile->dir is the whole lib name */
                BLI_strncpy(G.lib, sfile->dir, sizeof(G.lib) );
-               
        }
 }
 
@@ -2415,7 +2244,7 @@ static void library_to_filelist(SpaceFile *sfile)
        LinkNode *l, *names;
        int ok, i, nnames, idcode;
        char filename[FILE_MAX];
-       char dir[FILE_MAX], group[24];
+       char dir[FILE_MAX], group[GROUP_MAX];
        
        /* name test */
        ok= is_a_library(sfile, dir, group);
@@ -2497,7 +2326,7 @@ static void filesel_select_objects(SpaceFile *sfile)
                        
                        ob= (Object *)sfile->filelist[a].poin;
                        
-                       if(ob) {
+                       if(ob && (ob->flag & OB_RESTRICT_VIEW)==0) {
                                if(sfile->filelist[a].flags & ACTIVE) ob->flag |= SELECT;
                                else ob->flag &= ~SELECT;
                        }
@@ -2539,7 +2368,7 @@ static void active_file_object(SpaceFile *sfile)
                        
                        ob= (Object *)sfile->filelist[sfile->act].poin;
                        
-                       if(ob) {
+                       if(ob && (ob->flag & OB_RESTRICT_VIEW)==0) {
                                set_active_object(ob);
                                if(BASACT && BASACT->object==ob) {
                                        BASACT->flag |= SELECT;