From feb440c2cd72ef87c79d1bbf1524802d4e82fa88 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 25 Apr 2008 16:09:16 +0000 Subject: [PATCH] added sequencer paths to bpath iterator, This needed to use get/set filename callbacks internally because the sequencer stores dir/file separately. This means when moving large projects with many images/videos/sounds is possible with 'File, External Data, Find Missing Files'. - needed so we can put peach animatic, glrenders & testrenders on the dvd. also datatoc.c - brecht's fixes from apricot. --- release/datafiles/datatoc.c | 6 +- source/blender/blenlib/BLI_bpath.h | 32 +++- source/blender/blenlib/intern/bpath.c | 226 ++++++++++++++++++++---- source/blender/include/BSE_sequence.h | 1 + source/blender/python/api2_2x/Blender.c | 10 +- source/blender/src/buttons_scene.c | 5 +- 6 files changed, 220 insertions(+), 60 deletions(-) diff --git a/release/datafiles/datatoc.c b/release/datafiles/datatoc.c index 75f789b378a..2e24a0f92ef 100644 --- a/release/datafiles/datatoc.c +++ b/release/datafiles/datatoc.c @@ -62,7 +62,7 @@ int main(int argc, char**argv) { if (argv[1][i]=='.') argv[1][i]='_'; sprintf(sizest, "%d", (int)size); - printf ("Input filesize is %d, Output size should be %d\n", size, ((int)size)*4 + strlen("/* DataToC output of file <> */\n\n") + strlen("char datatoc_[]= {\"") + strlen ("\"};\n") + (strlen(argv[1])*3) + strlen(sizest) + strlen("int datatoc__size= ;\n") +(((int)(size/256)+1)*5)); + printf ("Input filesize is %ld, Output size should be %ld\n", size, ((int)size)*4 + strlen("/* DataToC output of file <> */\n\n") + strlen("char datatoc_[]= {\"") + strlen ("\"};\n") + (strlen(argv[1])*3) + strlen(sizest) + strlen("int datatoc__size= ;\n") +(((int)(size/256)+1)*5)); fpout= fopen(cname, "w"); if (!fpout) { @@ -93,8 +93,8 @@ int main(int argc, char**argv) { /* fprintf (fpout, "\\x%02x", getc(fpin)); */ fprintf (fpout, "%3d,", getc(fpin)); } - - fprintf (fpout, "\n};\n\n"); + /* null terminate for the case it is a string */ + fprintf (fpout, "\n 0};\n\n"); fclose(fpin); fclose(fpout); diff --git a/source/blender/blenlib/BLI_bpath.h b/source/blender/blenlib/BLI_bpath.h index 40bb66a2278..0f2f9346c83 100644 --- a/source/blender/blenlib/BLI_bpath.h +++ b/source/blender/blenlib/BLI_bpath.h @@ -29,6 +29,12 @@ /* Based on ghash, difference is ghash is not a fixed size, * so for BPath we dont need to malloc */ +struct BPathIteratorSeqData { + int totseq; + int seq; + struct Sequence **seqar; /* Sequence */ +}; + struct BPathIterator { char* path; char* lib; @@ -36,17 +42,25 @@ struct BPathIterator { void* data; int len; int type; + + void (*setpath_callback)(struct BPathIterator *, char *); + void (*getpath_callback)(struct BPathIterator *, char *); + + /* only for seq data */ + struct BPathIteratorSeqData seqdata; }; -void BLI_bpathIterator_init (struct BPathIterator *bpi); -char* BLI_bpathIterator_getPath (struct BPathIterator *bpi); -char* BLI_bpathIterator_getLib (struct BPathIterator *bpi); -char* BLI_bpathIterator_getName (struct BPathIterator *bpi); -int BLI_bpathIterator_getType (struct BPathIterator *bpi); -int BLI_bpathIterator_getPathMaxLen(struct BPathIterator *bpi); -void BLI_bpathIterator_step (struct BPathIterator *bpi); -int BLI_bpathIterator_isDone (struct BPathIterator *bpi); -void BLI_bpathIterator_copyPathExpanded( struct BPathIterator *bpi, char *path_expanded); +void BLI_bpathIterator_init (struct BPathIterator *bpi); +void BLI_bpathIterator_free (struct BPathIterator *bpi); +char* BLI_bpathIterator_getLib (struct BPathIterator *bpi); +char* BLI_bpathIterator_getName (struct BPathIterator *bpi); +int BLI_bpathIterator_getType (struct BPathIterator *bpi); +int BLI_bpathIterator_getPathMaxLen (struct BPathIterator *bpi); +void BLI_bpathIterator_step (struct BPathIterator *bpi); +int BLI_bpathIterator_isDone (struct BPathIterator *bpi); +void BLI_bpathIterator_getPath (struct BPathIterator *bpi, char *path); +void BLI_bpathIterator_getPathExpanded (struct BPathIterator *bpi, char *path_expanded); +void BLI_bpathIterator_setPath (struct BPathIterator *bpi, char *path); /* high level funcs */ diff --git a/source/blender/blenlib/intern/bpath.c b/source/blender/blenlib/intern/bpath.c index 92531eb07c4..dfa5226ebfa 100644 --- a/source/blender/blenlib/intern/bpath.c +++ b/source/blender/blenlib/intern/bpath.c @@ -28,11 +28,13 @@ #include "BLI_bpath.h" #include "BKE_global.h" +#include "BIF_screen.h" /* only for wait cursor */ #include "DNA_ID.h" /* Library */ #include "DNA_vfont_types.h" #include "DNA_image_types.h" #include "DNA_sound_types.h" #include "DNA_scene_types.h" /* to get the current frame */ +#include "DNA_sequence_types.h" #include #include @@ -41,6 +43,10 @@ #include "blendef.h" #include "BKE_utildefines.h" +#include "MEM_guardedalloc.h" + +/* for sequence */ +#include "BSE_sequence.h" /* for writing to a textblock */ #include "BKE_text.h" @@ -67,35 +73,60 @@ #define FILE_MAX 240 - /* TODO - BPATH_PLUGIN, BPATH_SEQ */ enum BPathTypes { BPATH_IMAGE = 0, BPATH_SOUND, BPATH_FONT, BPATH_LIB, + BPATH_SEQ, BPATH_DONE }; - void BLI_bpathIterator_init( struct BPathIterator *bpi ) { bpi->type = BPATH_IMAGE; bpi->data = NULL; + + bpi->getpath_callback = NULL; + bpi->setpath_callback = NULL; + + /* Sequencer spesific */ + bpi->seqdata.totseq = 0; + bpi->seqdata.seq = 0; + bpi->seqdata.seqar = NULL; + BLI_bpathIterator_step(bpi); } -char* BLI_bpathIterator_getPath( struct BPathIterator *bpi) { - return bpi->path; +void BLI_bpathIterator_free( struct BPathIterator *bpi ) { + if (bpi->seqdata.seqar) + MEM_freeN((void *)bpi->seqdata.seqar); + bpi->seqdata.seqar = NULL; } -void BLI_bpathIterator_copyPathExpanded( struct BPathIterator *bpi, char *path_expanded) { - char *filepath, *libpath; + +void BLI_bpathIterator_getPath( struct BPathIterator *bpi, char *path) { + if (bpi->getpath_callback) { + bpi->getpath_callback( bpi, path ); + } else { + strcpy(path, bpi->path); /* warning, we assume 'path' are long enough */ + } +} + +void BLI_bpathIterator_setPath( struct BPathIterator *bpi, char *path) { + if (bpi->setpath_callback) { + bpi->setpath_callback( bpi, path ); + } else { + strcpy(bpi->path, path); /* warning, we assume 'path' are long enough */ + } +} + +void BLI_bpathIterator_getPathExpanded( struct BPathIterator *bpi, char *path_expanded) { + char *libpath; - filepath = BLI_bpathIterator_getPath(bpi); + BLI_bpathIterator_getPath(bpi, path_expanded); libpath = BLI_bpathIterator_getLib(bpi); - BLI_strncpy(path_expanded, filepath, FILE_MAXDIR*2); - if (libpath) { /* check the files location relative to its library path */ BLI_convertstringcode(path_expanded, libpath, G.scene->r.cfra); } else { /* local data, use the blend files path */ @@ -116,7 +147,7 @@ int BLI_bpathIterator_getPathMaxLen( struct BPathIterator *bpi) { } /* gets the first or the next image that has a path - not a viewer node or generated image */ -static struct Image *ima_getpath__internal(struct Image *ima, int step_next) { +static struct Image *ima_stepdata__internal(struct Image *ima, int step_next) { if (ima==NULL) return NULL; @@ -132,7 +163,7 @@ static struct Image *ima_getpath__internal(struct Image *ima, int step_next) { return ima; } -static struct VFont *vf_getpath__internal(struct VFont *vf, int step_next) { +static struct VFont *vf_stepdata__internal(struct VFont *vf, int step_next) { if (vf==NULL) return NULL; @@ -150,7 +181,7 @@ static struct VFont *vf_getpath__internal(struct VFont *vf, int step_next) { return vf; } -static struct bSound *snd_getpath__internal(struct bSound *snd, int step_next) { +static struct bSound *snd_stepdata__internal(struct bSound *snd, int step_next) { if (snd==NULL) return NULL; @@ -168,13 +199,105 @@ static struct bSound *snd_getpath__internal(struct bSound *snd, int step_next) { return snd; } +static struct Sequence *seq_stepdata__internal(struct BPathIterator *bpi, int step_next) { + Sequence *seq; + + if (G.scene->ed==NULL) { + return NULL; + } + + if (bpi->seqdata.seqar == NULL) { + /* allocate the sequencer array */ + build_seqar( &(((Editing *)G.scene->ed)->seqbase), &bpi->seqdata.seqar, &bpi->seqdata.totseq); + bpi->seqdata.seq = 0; + } + + if (step_next) { + bpi->seqdata.seq++; + } + + if (bpi->seqdata.seq >= bpi->seqdata.totseq) { + seq = NULL; + } else { + seq = bpi->seqdata.seqar[bpi->seqdata.seq]; + while (!SEQ_HAS_PATH(seq)) { + bpi->seqdata.seq++; + if (bpi->seqdata.seq >= bpi->seqdata.totseq) { + seq = NULL; + break; + } + seq = bpi->seqdata.seqar[bpi->seqdata.seq]; + } + } + return seq ; +} + +void seq_getpath(struct BPathIterator *bpi, char *path) { + Sequence *seq = (Sequence *)bpi->data; + + + path[0] = '\0'; /* incase we cant get the path */ + if (seq==NULL) return; + if (SEQ_HAS_PATH(seq)) { + if (seq->type == SEQ_IMAGE || seq->type == SEQ_MOVIE) { + BLI_strncpy(path, seq->strip->dir, FILE_MAX); + BLI_add_slash(path); /* incase its missing */ + if (seq->strip->stripdata) { /* should always be true! */ + /* Using the first image is weak for image sequences */ + strcat(path, seq->strip->stripdata->name); + } + } else { + /* simple case */ + BLI_strncpy(seq->strip->dir, path, sizeof(seq->strip->dir)); + } + } +} + +void seq_setpath(struct BPathIterator *bpi, char *path) { + Sequence *seq = (Sequence *)bpi->data; + if (seq==NULL) return; + + if (SEQ_HAS_PATH(seq)) { + if (seq->type == SEQ_IMAGE || seq->type == SEQ_MOVIE) { + char file[FILE_MAX]; + BLI_split_dirfile(path, seq->strip->dir, file); + BLI_add_slash(seq->strip->dir); /* incase its missing */ + + /* now append the filename */ + if (seq->strip->stripdata) { /* should always be true! */ + BLI_strncpy(seq->strip->stripdata->name, file, sizeof(seq->strip->stripdata->name)); + } + + } else { + /* simple case */ + BLI_strncpy(seq->strip->dir, path, sizeof(seq->strip->dir)); + } + } +} + +static void bpi_type_step__internal( struct BPathIterator *bpi) { + bpi->type++; /* advance to the next type */ + bpi->data = NULL; + + switch (bpi->type) { + case BPATH_SEQ: + bpi->getpath_callback = seq_getpath; + bpi->setpath_callback = seq_setpath; + break; + default: + bpi->getpath_callback = NULL; + bpi->setpath_callback = NULL; + break; + } +} + void BLI_bpathIterator_step( struct BPathIterator *bpi) { while (bpi->type != BPATH_DONE) { if ((bpi->type) == BPATH_IMAGE) { /*if (bpi->data) bpi->data = ((ID *)bpi->data)->next;*/ - if (bpi->data) bpi->data = ima_getpath__internal( (Image *)bpi->data, 1 ); /* must skip images that have no path */ - else bpi->data = ima_getpath__internal(G.main->image.first, 0); + if (bpi->data) bpi->data = ima_stepdata__internal( (Image *)bpi->data, 1 ); /* must skip images that have no path */ + else bpi->data = ima_stepdata__internal(G.main->image.first, 0); if (bpi->data) { /* get the path info from this datatype */ @@ -189,13 +312,13 @@ void BLI_bpathIterator_step( struct BPathIterator *bpi) { break; } else { - bpi->type+=1; /* advance to the next type */ + bpi_type_step__internal(bpi); } } else if ((bpi->type) == BPATH_SOUND) { - if (bpi->data) bpi->data = snd_getpath__internal( (bSound *)bpi->data, 1 ); /* must skip images that have no path */ - else bpi->data = snd_getpath__internal(G.main->sound.first, 0); + if (bpi->data) bpi->data = snd_stepdata__internal( (bSound *)bpi->data, 1 ); /* must skip images that have no path */ + else bpi->data = snd_stepdata__internal(G.main->sound.first, 0); if (bpi->data) { /* get the path info from this datatype */ @@ -209,14 +332,14 @@ void BLI_bpathIterator_step( struct BPathIterator *bpi) { /* we are done, advancing to the next item, this type worked fine */ break; } else { - bpi->type+=1; /* advance to the next type */ + bpi_type_step__internal(bpi); } } else if ((bpi->type) == BPATH_FONT) { - if (bpi->data) bpi->data = vf_getpath__internal( (VFont *)bpi->data, 1 ); - else bpi->data = vf_getpath__internal( G.main->vfont.first, 0 ); + if (bpi->data) bpi->data = vf_stepdata__internal( (VFont *)bpi->data, 1 ); + else bpi->data = vf_stepdata__internal( G.main->vfont.first, 0 ); if (bpi->data) { /* get the path info from this datatype */ @@ -230,12 +353,10 @@ void BLI_bpathIterator_step( struct BPathIterator *bpi) { /* we are done, advancing to the next item, this type worked fine */ break; } else { - bpi->type+=1; /* advance to the next type */ + bpi_type_step__internal(bpi); } - } else if ((bpi->type) == BPATH_LIB) { - if (bpi->data) bpi->data = ((ID *)bpi->data)->next; else bpi->data = G.main->library.first; @@ -251,7 +372,19 @@ void BLI_bpathIterator_step( struct BPathIterator *bpi) { /* we are done, advancing to the next item, this type worked fine */ break; } else { - bpi->type+=1; /* advance to the next type */ + bpi_type_step__internal(bpi); + } + } else if ((bpi->type) == BPATH_SEQ) { + if (bpi->data) bpi->data = seq_stepdata__internal( bpi, 1 ); + else bpi->data = seq_stepdata__internal( bpi, 0 ); + if (bpi->data) { + Sequence *seq = (Sequence *)bpi->data; + bpi->lib = NULL; + bpi->name = seq->name+2; + bpi->len = sizeof(seq->strip->stripdata->name); + break; + } else { + bpi_type_step__internal(bpi); } } } @@ -280,6 +413,9 @@ static void bpathToText(Text *btxt, struct BPathIterator *bpi) case BPATH_LIB: txt_insert_buf( btxt, "Library \"" ); break; + case BPATH_SEQ: + txt_insert_buf( btxt, "Sequence \"" ); + break; default: txt_insert_buf( btxt, "Unknown \"" ); break; @@ -292,7 +428,7 @@ static void bpathToText(Text *btxt, struct BPathIterator *bpi) } txt_insert_buf( btxt, "\" " ); - BLI_bpathIterator_copyPathExpanded(bpi, path_expanded); + BLI_bpathIterator_getPathExpanded(bpi, path_expanded); txt_insert_buf( btxt, path_expanded ); txt_insert_buf( btxt, "\n" ); @@ -306,15 +442,14 @@ void checkMissingFiles( char *txtname ) { /* be sure there is low chance of the path being too short */ char filepath_expanded[FILE_MAXDIR*2]; - char *filepath, *libpath; + char *libpath; int files_missing = 0; BLI_bpathIterator_init(&bpi); while (!BLI_bpathIterator_isDone(&bpi)) { - filepath = BLI_bpathIterator_getPath(&bpi); libpath = BLI_bpathIterator_getLib(&bpi); - BLI_bpathIterator_copyPathExpanded( &bpi, filepath_expanded ); + BLI_bpathIterator_getPathExpanded( &bpi, filepath_expanded ); if (!BLI_exists(filepath_expanded)) { if (!btxt) { @@ -328,12 +463,13 @@ void checkMissingFiles( char *txtname ) { } BLI_bpathIterator_step(&bpi); } + BLI_bpathIterator_free(&bpi); } /* dont log any errors at the moment, should probably do this */ void makeFilesRelative(char *txtname, int *tot, int *changed, int *failed, int *linked) { struct BPathIterator bpi; - char *filepath, *libpath; + char filepath[FILE_MAX], *libpath; /* be sure there is low chance of the path being too short */ char filepath_relative[(FILE_MAXDIR * 2) + FILE_MAXFILE]; @@ -344,7 +480,7 @@ void makeFilesRelative(char *txtname, int *tot, int *changed, int *failed, int * BLI_bpathIterator_init(&bpi); while (!BLI_bpathIterator_isDone(&bpi)) { - filepath = BLI_bpathIterator_getPath(&bpi); + BLI_bpathIterator_getPath(&bpi, filepath); libpath = BLI_bpathIterator_getLib(&bpi); if(strncmp(filepath, "//", 2)) { @@ -368,7 +504,7 @@ void makeFilesRelative(char *txtname, int *tot, int *changed, int *failed, int * (*failed)++; } else { if(strncmp(filepath_relative, "//", 2)==0) { - strcpy(filepath, filepath_relative); + BLI_bpathIterator_setPath(&bpi, filepath_relative); (*changed)++; } else { if (!btxt) { @@ -386,13 +522,14 @@ void makeFilesRelative(char *txtname, int *tot, int *changed, int *failed, int * BLI_bpathIterator_step(&bpi); (*tot)++; } + BLI_bpathIterator_free(&bpi); } /* dont log any errors at the moment, should probably do this - * Verry similar to makeFilesRelative - keep in sync! */ void makeFilesAbsolute(char *txtname, int *tot, int *changed, int *failed, int *linked) { struct BPathIterator bpi; - char *filepath, *libpath; + char filepath[FILE_MAX], *libpath; /* be sure there is low chance of the path being too short */ char filepath_absolute[(FILE_MAXDIR * 2) + FILE_MAXFILE]; @@ -403,14 +540,14 @@ void makeFilesAbsolute(char *txtname, int *tot, int *changed, int *failed, int * BLI_bpathIterator_init(&bpi); while (!BLI_bpathIterator_isDone(&bpi)) { - filepath = BLI_bpathIterator_getPath(&bpi); + BLI_bpathIterator_getPath(&bpi, filepath); libpath = BLI_bpathIterator_getLib(&bpi); if(strncmp(filepath, "//", 2)==0) { if (libpath) { /* cant make absolute if we are library - TODO, LOG THIS */ (*linked)++; } else { /* get the expanded path and check it is relative or too long */ - BLI_bpathIterator_copyPathExpanded( &bpi, filepath_absolute ); + BLI_bpathIterator_getPathExpanded( &bpi, filepath_absolute ); BLI_cleanup_file(G.sce, filepath_absolute); /* fix any /foo/../foo/ */ /* to be safe, check the length */ if (BLI_bpathIterator_getPathMaxLen(&bpi) <= strlen(filepath_absolute)) { @@ -424,7 +561,7 @@ void makeFilesAbsolute(char *txtname, int *tot, int *changed, int *failed, int * (*failed)++; } else { if(strncmp(filepath_absolute, "//", 2)) { - strcpy(filepath, filepath_absolute); + BLI_bpathIterator_setPath(&bpi, filepath_absolute); (*changed)++; } else { if (!btxt) { @@ -442,6 +579,7 @@ void makeFilesAbsolute(char *txtname, int *tot, int *changed, int *failed, int * BLI_bpathIterator_step(&bpi); (*tot)++; } + BLI_bpathIterator_free(&bpi); } @@ -505,22 +643,29 @@ void findMissingFiles(char *str) { /* be sure there is low chance of the path being too short */ char filepath_expanded[FILE_MAXDIR*2]; - char *filepath, *libpath; + char filepath[FILE_MAX], *libpath; int filesize, recur_depth; char dirname[FILE_MAX], filename[FILE_MAX], filename_new[FILE_MAX], dummyname[FILE_MAX]; + waitcursor( 1 ); + BLI_split_dirfile(str, dirname, dummyname); BLI_bpathIterator_init(&bpi); while (!BLI_bpathIterator_isDone(&bpi)) { - filepath = BLI_bpathIterator_getPath(&bpi); + BLI_bpathIterator_getPath(&bpi, filepath); libpath = BLI_bpathIterator_getLib(&bpi); + /* Check if esc was pressed because searching files can be slow */ + if (blender_test_break()) { + break; + } + if (libpath==NULL) { - BLI_bpathIterator_copyPathExpanded( &bpi, filepath_expanded ); + BLI_bpathIterator_getPathExpanded( &bpi, filepath_expanded ); if (!BLI_exists(filepath_expanded)) { /* can the dir be opened? */ @@ -543,11 +688,14 @@ void findMissingFiles(char *str) { if (G.relbase_valid) BLI_makestringcode(G.sce, filename_new); - strcpy( BLI_bpathIterator_getPath( &bpi ), filename_new ); + BLI_bpathIterator_setPath( &bpi, filename_new ); } } } } BLI_bpathIterator_step(&bpi); } + BLI_bpathIterator_free(&bpi); + + waitcursor( 0 ); } diff --git a/source/blender/include/BSE_sequence.h b/source/blender/include/BSE_sequence.h index 70ba4ad8fbd..15a9218b735 100644 --- a/source/blender/include/BSE_sequence.h +++ b/source/blender/include/BSE_sequence.h @@ -92,6 +92,7 @@ void update_changed_seq_and_deps(struct Sequence *seq, int len_change, int ibuf_ struct RenderResult; void do_render_seq(struct RenderResult *rr, int cfra); +#define SEQ_HAS_PATH(seq) (seq->type==SEQ_MOVIE || seq->type==SEQ_HD_SOUND || seq->type==SEQ_RAM_SOUND || seq->type==SEQ_IMAGE) #endif diff --git a/source/blender/python/api2_2x/Blender.c b/source/blender/python/api2_2x/Blender.c index 6d9c448c16f..fe5ae25ccb1 100644 --- a/source/blender/python/api2_2x/Blender.c +++ b/source/blender/python/api2_2x/Blender.c @@ -927,7 +927,7 @@ static PyObject *Blender_CountPackedFiles( PyObject * self ) static PyObject *Blender_GetPaths( PyObject * self, PyObject *args, PyObject *keywds ) { struct BPathIterator bpi; - PyObject *list = PyList_New(0), *st; + PyObject *list = PyList_New(0), *st; /* stupidly big string to be safe */ /* be sure there is low chance of the path being too short */ char filepath_expanded[FILE_MAXDIR*2]; @@ -944,18 +944,18 @@ static PyObject *Blender_GetPaths( PyObject * self, PyObject *args, PyObject *ke /* build the list */ if (absolute) { - BLI_bpathIterator_copyPathExpanded( &bpi, filepath_expanded ); - st = PyString_FromString(filepath_expanded); + BLI_bpathIterator_getPathExpanded( &bpi, filepath_expanded ); } else { - st = PyString_FromString(BLI_bpathIterator_getPath(&bpi)); + BLI_bpathIterator_getPathExpanded( &bpi, filepath_expanded ); } + st = PyString_FromString(filepath_expanded); PyList_Append(list, st); Py_DECREF(st); BLI_bpathIterator_step(&bpi); } - + BLI_bpathIterator_free(&bpi); return list; } diff --git a/source/blender/src/buttons_scene.c b/source/blender/src/buttons_scene.c index a955f7a89e4..77a46168e1f 100644 --- a/source/blender/src/buttons_scene.c +++ b/source/blender/src/buttons_scene.c @@ -747,10 +747,7 @@ static void seq_panel_input() if(uiNewPanel(curarea, block, "Input", "Sequencer", 10, 230, 318, 204) == 0) return; - if (last_seq->type == SEQ_MOVIE - || last_seq->type == SEQ_IMAGE - || last_seq->type == SEQ_HD_SOUND - || last_seq->type == SEQ_RAM_SOUND) { + if (SEQ_HAS_PATH(last_seq)) { uiDefBut(block, TEX, B_SEQ_BUT_RELOAD_FILE, "Dir: ", 10,140,240,19, last_seq->strip->dir,