Remap Relative paths save option.
If you have a blend file and want to save in a new directory enabling this will save with the paths corrected relative to the new directory.
This commit is contained in:
@@ -146,6 +146,7 @@ typedef struct Global {
|
|||||||
#define G_FILE_GLSL_NO_EXTRA_TEX (1 << 21) /* deprecated */
|
#define G_FILE_GLSL_NO_EXTRA_TEX (1 << 21) /* deprecated */
|
||||||
#define G_FILE_IGNORE_DEPRECATION_WARNINGS (1 << 22) /* deprecated */
|
#define G_FILE_IGNORE_DEPRECATION_WARNINGS (1 << 22) /* deprecated */
|
||||||
#define G_FILE_RECOVER (1 << 23)
|
#define G_FILE_RECOVER (1 << 23)
|
||||||
|
#define G_FILE_RELATIVE_REMAP (1 << 24)
|
||||||
|
|
||||||
/* G.windowstate */
|
/* G.windowstate */
|
||||||
#define G_WINDOWSTATE_USERDEF 0
|
#define G_WINDOWSTATE_USERDEF 0
|
||||||
|
|||||||
@@ -47,11 +47,13 @@ struct BPathIterator {
|
|||||||
void (*setpath_callback)(struct BPathIterator *, char *);
|
void (*setpath_callback)(struct BPathIterator *, char *);
|
||||||
void (*getpath_callback)(struct BPathIterator *, char *);
|
void (*getpath_callback)(struct BPathIterator *, char *);
|
||||||
|
|
||||||
|
char* base_path; /* base path, the directry the blend file is in - normally G.sce */
|
||||||
|
|
||||||
/* only for seq data */
|
/* only for seq data */
|
||||||
struct BPathIteratorSeqData seqdata;
|
struct BPathIteratorSeqData seqdata;
|
||||||
};
|
};
|
||||||
|
|
||||||
void BLI_bpathIterator_init (struct BPathIterator *bpi);
|
void BLI_bpathIterator_init (struct BPathIterator *bpi, char *base_path);
|
||||||
void BLI_bpathIterator_free (struct BPathIterator *bpi);
|
void BLI_bpathIterator_free (struct BPathIterator *bpi);
|
||||||
char* BLI_bpathIterator_getLib (struct BPathIterator *bpi);
|
char* BLI_bpathIterator_getLib (struct BPathIterator *bpi);
|
||||||
char* BLI_bpathIterator_getName (struct BPathIterator *bpi);
|
char* BLI_bpathIterator_getName (struct BPathIterator *bpi);
|
||||||
@@ -66,7 +68,7 @@ void BLI_bpathIterator_setPath (struct BPathIterator *bpi, char *path);
|
|||||||
/* high level funcs */
|
/* high level funcs */
|
||||||
|
|
||||||
/* creates a text file with missing files if there are any */
|
/* creates a text file with missing files if there are any */
|
||||||
void checkMissingFiles(char *txtname );
|
void checkMissingFiles(char *basepath, ReportList *reports);
|
||||||
void makeFilesRelative(char *txtname, int *tot, int *changed, int *failed, int *linked);
|
void makeFilesRelative(char *basepath, ReportList *reports);
|
||||||
void makeFilesAbsolute(char *txtname, int *tot, int *changed, int *failed, int *linked);
|
void makeFilesAbsolute(char *basepath, ReportList *reports);
|
||||||
void findMissingFiles(char *str);
|
void findMissingFiles(char *basepath, char *str);
|
||||||
|
|||||||
@@ -52,7 +52,7 @@
|
|||||||
#include "DNA_sound_types.h"
|
#include "DNA_sound_types.h"
|
||||||
#include "DNA_scene_types.h" /* to get the current frame */
|
#include "DNA_scene_types.h" /* to get the current frame */
|
||||||
#include "DNA_sequence_types.h"
|
#include "DNA_sequence_types.h"
|
||||||
#include "DNA_text_types.h"
|
#include "DNA_windowmanager_types.h"
|
||||||
|
|
||||||
#include "BLI_blenlib.h"
|
#include "BLI_blenlib.h"
|
||||||
#include "BLI_bpath.h"
|
#include "BLI_bpath.h"
|
||||||
@@ -61,7 +61,6 @@
|
|||||||
#include "BKE_image.h" /* so we can check the image's type */
|
#include "BKE_image.h" /* so we can check the image's type */
|
||||||
#include "BKE_main.h" /* so we can access G.main->*.first */
|
#include "BKE_main.h" /* so we can access G.main->*.first */
|
||||||
#include "BKE_sequencer.h"
|
#include "BKE_sequencer.h"
|
||||||
#include "BKE_text.h" /* for writing to a textblock */
|
|
||||||
#include "BKE_utildefines.h"
|
#include "BKE_utildefines.h"
|
||||||
|
|
||||||
//XXX #include "BIF_screen.h" /* only for wait cursor */
|
//XXX #include "BIF_screen.h" /* only for wait cursor */
|
||||||
@@ -86,19 +85,21 @@ enum BPathTypes {
|
|||||||
BPATH_DONE
|
BPATH_DONE
|
||||||
};
|
};
|
||||||
|
|
||||||
void BLI_bpathIterator_init( struct BPathIterator *bpi ) {
|
void BLI_bpathIterator_init( struct BPathIterator *bpi, char *base_path ) {
|
||||||
bpi->type = BPATH_IMAGE;
|
bpi->type = BPATH_IMAGE;
|
||||||
bpi->data = NULL;
|
bpi->data = NULL;
|
||||||
|
|
||||||
bpi->getpath_callback = NULL;
|
bpi->getpath_callback = NULL;
|
||||||
bpi->setpath_callback = NULL;
|
bpi->setpath_callback = NULL;
|
||||||
|
|
||||||
/* Sequencer spesific */
|
/* Sequencer specific */
|
||||||
bpi->seqdata.totseq = 0;
|
bpi->seqdata.totseq = 0;
|
||||||
bpi->seqdata.seq = 0;
|
bpi->seqdata.seq = 0;
|
||||||
bpi->seqdata.seqar = NULL;
|
bpi->seqdata.seqar = NULL;
|
||||||
bpi->seqdata.scene = NULL;
|
bpi->seqdata.scene = NULL;
|
||||||
|
|
||||||
|
bpi->base_path= base_path ? base_path : G.sce;
|
||||||
|
|
||||||
BLI_bpathIterator_step(bpi);
|
BLI_bpathIterator_step(bpi);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -134,7 +135,7 @@ void BLI_bpathIterator_getPathExpanded( struct BPathIterator *bpi, char *path_ex
|
|||||||
if (libpath) { /* check the files location relative to its library path */
|
if (libpath) { /* check the files location relative to its library path */
|
||||||
BLI_convertstringcode(path_expanded, libpath);
|
BLI_convertstringcode(path_expanded, libpath);
|
||||||
} else { /* local data, use the blend files path */
|
} else { /* local data, use the blend files path */
|
||||||
BLI_convertstringcode(path_expanded, G.sce);
|
BLI_convertstringcode(path_expanded, bpi->base_path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
char* BLI_bpathIterator_getLib( struct BPathIterator *bpi) {
|
char* BLI_bpathIterator_getLib( struct BPathIterator *bpi) {
|
||||||
@@ -413,186 +414,157 @@ int BLI_bpathIterator_isDone( struct BPathIterator *bpi) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* include the path argument */
|
/* include the path argument */
|
||||||
static void bpathToText(Text *btxt, struct BPathIterator *bpi)
|
static void bpath_as_report(struct BPathIterator *bpi, const char *message, ReportList *reports)
|
||||||
{
|
{
|
||||||
|
char *prefix;
|
||||||
char *name;
|
char *name;
|
||||||
char path_expanded[FILE_MAXDIR*2];
|
char path_expanded[FILE_MAXDIR*2];
|
||||||
|
|
||||||
|
if(reports==NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
switch(BLI_bpathIterator_getType(bpi)) {
|
switch(BLI_bpathIterator_getType(bpi)) {
|
||||||
case BPATH_IMAGE:
|
case BPATH_IMAGE:
|
||||||
txt_insert_buf( btxt, "Image \"" );
|
prefix= "Image";
|
||||||
break;
|
break;
|
||||||
case BPATH_SOUND:
|
case BPATH_SOUND:
|
||||||
txt_insert_buf( btxt, "Sound \"" );
|
prefix= "Sound";
|
||||||
break;
|
break;
|
||||||
case BPATH_FONT:
|
case BPATH_FONT:
|
||||||
txt_insert_buf( btxt, "Font \"" );
|
prefix= "Font";
|
||||||
break;
|
break;
|
||||||
case BPATH_LIB:
|
case BPATH_LIB:
|
||||||
txt_insert_buf( btxt, "Library \"" );
|
prefix= "Library";
|
||||||
break;
|
break;
|
||||||
case BPATH_SEQ:
|
case BPATH_SEQ:
|
||||||
txt_insert_buf( btxt, "Sequence \"" );
|
prefix= "Sequence";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
txt_insert_buf( btxt, "Unknown \"" );
|
prefix= "Unknown";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
name = BLI_bpathIterator_getName(bpi);
|
name = BLI_bpathIterator_getName(bpi);
|
||||||
|
|
||||||
if (name) {
|
|
||||||
txt_insert_buf( btxt, name );
|
|
||||||
}
|
|
||||||
txt_insert_buf( btxt, "\" " );
|
|
||||||
|
|
||||||
BLI_bpathIterator_getPathExpanded(bpi, path_expanded);
|
BLI_bpathIterator_getPathExpanded(bpi, path_expanded);
|
||||||
|
|
||||||
txt_insert_buf( btxt, path_expanded );
|
if(reports) {
|
||||||
txt_insert_buf( btxt, "\n" );
|
if (name) BKE_reportf("%s \"%s\", \"%s\": %s", prefix, name, path_expanded, message);
|
||||||
txt_move_eof( btxt, 0 );
|
else BKE_reportf("%s \"%s\": %s", prefix, path_expanded, message);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* high level function */
|
/* high level function */
|
||||||
void checkMissingFiles( char *txtname ) {
|
void checkMissingFiles(char *basepath, ReportList *reports) {
|
||||||
Text *btxt = NULL;
|
|
||||||
struct BPathIterator bpi;
|
struct BPathIterator bpi;
|
||||||
|
|
||||||
/* be sure there is low chance of the path being too short */
|
/* be sure there is low chance of the path being too short */
|
||||||
char filepath_expanded[FILE_MAXDIR*2];
|
char filepath_expanded[FILE_MAXDIR*2];
|
||||||
|
|
||||||
BLI_bpathIterator_init(&bpi);
|
BLI_bpathIterator_init(&bpi, basepath);
|
||||||
while (!BLI_bpathIterator_isDone(&bpi)) {
|
while (!BLI_bpathIterator_isDone(&bpi)) {
|
||||||
BLI_bpathIterator_getPathExpanded( &bpi, filepath_expanded );
|
BLI_bpathIterator_getPathExpanded( &bpi, filepath_expanded );
|
||||||
|
|
||||||
if (!BLI_exists(filepath_expanded)) {
|
if (!BLI_exists(filepath_expanded))
|
||||||
if (!btxt) {
|
bpath_as_report(&bpi, "file not found", reports);
|
||||||
btxt = add_empty_text( "missing_files.log" );
|
|
||||||
if (txtname) {
|
|
||||||
BLI_strncpy(txtname, btxt->id.name+2, 24);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bpathToText(btxt, &bpi);
|
|
||||||
}
|
|
||||||
BLI_bpathIterator_step(&bpi);
|
BLI_bpathIterator_step(&bpi);
|
||||||
}
|
}
|
||||||
BLI_bpathIterator_free(&bpi);
|
BLI_bpathIterator_free(&bpi);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* dont log any errors at the moment, should probably do this */
|
/* dont log any errors at the moment, should probably do this */
|
||||||
void makeFilesRelative(char *txtname, int *tot, int *changed, int *failed, int *linked) {
|
void makeFilesRelative(char *basepath, ReportList *reports) {
|
||||||
|
int tot= 0, changed= 0, failed= 0, linked= 0;
|
||||||
struct BPathIterator bpi;
|
struct BPathIterator bpi;
|
||||||
char filepath[FILE_MAX], *libpath;
|
char filepath[FILE_MAX], *libpath;
|
||||||
|
|
||||||
/* be sure there is low chance of the path being too short */
|
/* be sure there is low chance of the path being too short */
|
||||||
char filepath_relative[(FILE_MAXDIR * 2) + FILE_MAXFILE];
|
char filepath_relative[(FILE_MAXDIR * 2) + FILE_MAXFILE];
|
||||||
|
|
||||||
Text *btxt = NULL;
|
BLI_bpathIterator_init(&bpi, basepath);
|
||||||
|
|
||||||
*tot = *changed = *failed = *linked = 0;
|
|
||||||
|
|
||||||
BLI_bpathIterator_init(&bpi);
|
|
||||||
while (!BLI_bpathIterator_isDone(&bpi)) {
|
while (!BLI_bpathIterator_isDone(&bpi)) {
|
||||||
BLI_bpathIterator_getPath(&bpi, filepath);
|
BLI_bpathIterator_getPath(&bpi, filepath);
|
||||||
libpath = BLI_bpathIterator_getLib(&bpi);
|
libpath = BLI_bpathIterator_getLib(&bpi);
|
||||||
|
|
||||||
if(strncmp(filepath, "//", 2)) {
|
if(strncmp(filepath, "//", 2)) {
|
||||||
if (libpath) { /* cant make relative if we are library - TODO, LOG THIS */
|
if (libpath) { /* cant make relative if we are library - TODO, LOG THIS */
|
||||||
(*linked)++;
|
linked++;
|
||||||
} else { /* local data, use the blend files path */
|
} else { /* local data, use the blend files path */
|
||||||
BLI_strncpy(filepath_relative, filepath, sizeof(filepath_relative));
|
BLI_strncpy(filepath_relative, filepath, sizeof(filepath_relative));
|
||||||
/* Important BLI_cleanup_dir runs before the path is made relative
|
/* Important BLI_cleanup_dir runs before the path is made relative
|
||||||
* because it wont work for paths that start with "//../" */
|
* because it wont work for paths that start with "//../" */
|
||||||
BLI_cleanup_file(G.sce, filepath_relative); /* fix any /foo/../foo/ */
|
BLI_cleanup_file(bpi.base_path, filepath_relative); /* fix any /foo/../foo/ */
|
||||||
BLI_makestringcode(G.sce, filepath_relative);
|
BLI_makestringcode(bpi.base_path, filepath_relative);
|
||||||
/* be safe and check the length */
|
/* be safe and check the length */
|
||||||
if (BLI_bpathIterator_getPathMaxLen(&bpi) <= strlen(filepath_relative)) {
|
if (BLI_bpathIterator_getPathMaxLen(&bpi) <= strlen(filepath_relative)) {
|
||||||
if (!btxt) {
|
bpath_as_report(&bpi, "couldn't make path relative (too long)", reports);
|
||||||
btxt = add_empty_text( "missing_no_rel.log" );
|
failed++;
|
||||||
if (txtname) {
|
|
||||||
BLI_strncpy(txtname, btxt->id.name+2, 24);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bpathToText(btxt, &bpi);
|
|
||||||
(*failed)++;
|
|
||||||
} else {
|
} else {
|
||||||
if(strncmp(filepath_relative, "//", 2)==0) {
|
if(strncmp(filepath_relative, "//", 2)==0) {
|
||||||
BLI_bpathIterator_setPath(&bpi, filepath_relative);
|
BLI_bpathIterator_setPath(&bpi, filepath_relative);
|
||||||
(*changed)++;
|
changed++;
|
||||||
} else {
|
} else {
|
||||||
if (!btxt) {
|
bpath_as_report(&bpi, "couldn't make path relative", reports);
|
||||||
btxt = add_empty_text( "missing_no_rel.log" );
|
failed++;
|
||||||
if (txtname) {
|
|
||||||
BLI_strncpy(txtname, btxt->id.name+2, 24);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bpathToText(btxt, &bpi);
|
|
||||||
(*failed)++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BLI_bpathIterator_step(&bpi);
|
BLI_bpathIterator_step(&bpi);
|
||||||
(*tot)++;
|
tot++;
|
||||||
}
|
}
|
||||||
BLI_bpathIterator_free(&bpi);
|
BLI_bpathIterator_free(&bpi);
|
||||||
|
|
||||||
|
if(reports)
|
||||||
|
BKE_reportf(reports, failed ? RPT_ERROR : RPT_INFO, "Total files %i|Changed %i|Failed %i|Linked %i", tot, changed, failed, linked);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* dont log any errors at the moment, should probably do this -
|
/* dont log any errors at the moment, should probably do this -
|
||||||
* Verry similar to makeFilesRelative - keep in sync! */
|
* Verry similar to makeFilesRelative - keep in sync! */
|
||||||
void makeFilesAbsolute(char *txtname, int *tot, int *changed, int *failed, int *linked) {
|
void makeFilesAbsolute(char *basepath, ReportList *reports)
|
||||||
|
{
|
||||||
|
int tot= 0, changed= 0, failed= 0, linked= 0;
|
||||||
|
|
||||||
struct BPathIterator bpi;
|
struct BPathIterator bpi;
|
||||||
char filepath[FILE_MAX], *libpath;
|
char filepath[FILE_MAX], *libpath;
|
||||||
|
|
||||||
/* be sure there is low chance of the path being too short */
|
/* be sure there is low chance of the path being too short */
|
||||||
char filepath_absolute[(FILE_MAXDIR * 2) + FILE_MAXFILE];
|
char filepath_absolute[(FILE_MAXDIR * 2) + FILE_MAXFILE];
|
||||||
|
|
||||||
Text *btxt = NULL;
|
BLI_bpathIterator_init(&bpi, basepath);
|
||||||
|
|
||||||
*tot = *changed = *failed = *linked = 0;
|
|
||||||
|
|
||||||
BLI_bpathIterator_init(&bpi);
|
|
||||||
while (!BLI_bpathIterator_isDone(&bpi)) {
|
while (!BLI_bpathIterator_isDone(&bpi)) {
|
||||||
BLI_bpathIterator_getPath(&bpi, filepath);
|
BLI_bpathIterator_getPath(&bpi, filepath);
|
||||||
libpath = BLI_bpathIterator_getLib(&bpi);
|
libpath = BLI_bpathIterator_getLib(&bpi);
|
||||||
|
|
||||||
if(strncmp(filepath, "//", 2)==0) {
|
if(strncmp(filepath, "//", 2)==0) {
|
||||||
if (libpath) { /* cant make absolute if we are library - TODO, LOG THIS */
|
if (libpath) { /* cant make absolute if we are library - TODO, LOG THIS */
|
||||||
(*linked)++;
|
linked++;
|
||||||
} else { /* get the expanded path and check it is relative or too long */
|
} else { /* get the expanded path and check it is relative or too long */
|
||||||
BLI_bpathIterator_getPathExpanded( &bpi, filepath_absolute );
|
BLI_bpathIterator_getPathExpanded( &bpi, filepath_absolute );
|
||||||
BLI_cleanup_file(G.sce, filepath_absolute); /* fix any /foo/../foo/ */
|
BLI_cleanup_file(bpi.base_path, filepath_absolute); /* fix any /foo/../foo/ */
|
||||||
/* to be safe, check the length */
|
/* to be safe, check the length */
|
||||||
if (BLI_bpathIterator_getPathMaxLen(&bpi) <= strlen(filepath_absolute)) {
|
if (BLI_bpathIterator_getPathMaxLen(&bpi) <= strlen(filepath_absolute)) {
|
||||||
if (!btxt) {
|
bpath_as_report(&bpi, "couldn't make absolute (too long)", reports);
|
||||||
btxt = add_empty_text( "missing_no_abs.log" );
|
failed++;
|
||||||
if (txtname) {
|
|
||||||
BLI_strncpy(txtname, btxt->id.name+2, 24);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bpathToText(btxt, &bpi);
|
|
||||||
(*failed)++;
|
|
||||||
} else {
|
} else {
|
||||||
if(strncmp(filepath_absolute, "//", 2)) {
|
if(strncmp(filepath_absolute, "//", 2)) {
|
||||||
BLI_bpathIterator_setPath(&bpi, filepath_absolute);
|
BLI_bpathIterator_setPath(&bpi, filepath_absolute);
|
||||||
(*changed)++;
|
changed++;
|
||||||
} else {
|
} else {
|
||||||
if (!btxt) {
|
bpath_as_report(&bpi, "couldn't make absolute", reports);
|
||||||
btxt = add_empty_text( "missing_no_abs.log" );
|
failed++;
|
||||||
if (txtname) {
|
|
||||||
BLI_strncpy(txtname, btxt->id.name+2, 24);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bpathToText(btxt, &bpi);
|
|
||||||
(*failed)++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BLI_bpathIterator_step(&bpi);
|
BLI_bpathIterator_step(&bpi);
|
||||||
(*tot)++;
|
tot++;
|
||||||
}
|
}
|
||||||
BLI_bpathIterator_free(&bpi);
|
BLI_bpathIterator_free(&bpi);
|
||||||
|
|
||||||
|
if(reports)
|
||||||
|
BKE_reportf(reports, failed ? RPT_ERROR : RPT_INFO, "Total files %i|Changed %i|Failed %i|Linked %i", tot, changed, failed, linked);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -651,7 +623,7 @@ static int findFileRecursive(char *filename_new, const char *dirname, const char
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* high level function - call from fileselector */
|
/* high level function - call from fileselector */
|
||||||
void findMissingFiles(char *str) {
|
void findMissingFiles(char *basepath, char *str) {
|
||||||
struct BPathIterator bpi;
|
struct BPathIterator bpi;
|
||||||
|
|
||||||
/* be sure there is low chance of the path being too short */
|
/* be sure there is low chance of the path being too short */
|
||||||
@@ -665,7 +637,7 @@ void findMissingFiles(char *str) {
|
|||||||
|
|
||||||
BLI_split_dirfile_basic(str, dirname, NULL);
|
BLI_split_dirfile_basic(str, dirname, NULL);
|
||||||
|
|
||||||
BLI_bpathIterator_init(&bpi);
|
BLI_bpathIterator_init(&bpi, basepath);
|
||||||
|
|
||||||
while (!BLI_bpathIterator_isDone(&bpi)) {
|
while (!BLI_bpathIterator_isDone(&bpi)) {
|
||||||
BLI_bpathIterator_getPath(&bpi, filepath);
|
BLI_bpathIterator_getPath(&bpi, filepath);
|
||||||
@@ -699,7 +671,7 @@ void findMissingFiles(char *str) {
|
|||||||
} else {
|
} else {
|
||||||
/* copy the found path into the old one */
|
/* copy the found path into the old one */
|
||||||
if (G.relbase_valid)
|
if (G.relbase_valid)
|
||||||
BLI_makestringcode(G.sce, filename_new);
|
BLI_makestringcode(bpi.base_path, filename_new);
|
||||||
|
|
||||||
BLI_bpathIterator_setPath( &bpi, filename_new );
|
BLI_bpathIterator_setPath( &bpi, filename_new );
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -145,6 +145,7 @@ Any case: direct data is ALWAYS after the lib block
|
|||||||
#include "MEM_guardedalloc.h" // MEM_freeN
|
#include "MEM_guardedalloc.h" // MEM_freeN
|
||||||
#include "BLI_blenlib.h"
|
#include "BLI_blenlib.h"
|
||||||
#include "BLI_linklist.h"
|
#include "BLI_linklist.h"
|
||||||
|
#include "BLI_bpath.h"
|
||||||
|
|
||||||
#include "BKE_action.h"
|
#include "BKE_action.h"
|
||||||
#include "BKE_blender.h"
|
#include "BKE_blender.h"
|
||||||
@@ -2458,9 +2459,28 @@ int BLO_write_file(Main *mainvar, char *dir, int write_flags, ReportList *report
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(write_flags & G_FILE_RELATIVE_REMAP) {
|
||||||
|
char dir1[FILE_MAXDIR+FILE_MAXFILE];
|
||||||
|
char dir2[FILE_MAXDIR+FILE_MAXFILE];
|
||||||
|
BLI_split_dirfile_basic(dir, dir1, NULL);
|
||||||
|
BLI_split_dirfile_basic(mainvar->name, dir2, NULL);
|
||||||
|
|
||||||
|
/* just incase there is some subtle difference */
|
||||||
|
BLI_cleanup_dir(dir1);
|
||||||
|
BLI_cleanup_dir(dir2);
|
||||||
|
|
||||||
|
if(strcmp(dir1, dir2)==0)
|
||||||
|
write_flags &= ~G_FILE_RELATIVE_REMAP;
|
||||||
|
else
|
||||||
|
makeFilesAbsolute(G.sce, reports);
|
||||||
|
}
|
||||||
|
|
||||||
BLI_make_file_string(G.sce, userfilename, BLI_gethome(), ".B25.blend");
|
BLI_make_file_string(G.sce, userfilename, BLI_gethome(), ".B25.blend");
|
||||||
write_user_block= BLI_streq(dir, userfilename);
|
write_user_block= BLI_streq(dir, userfilename);
|
||||||
|
|
||||||
|
if(write_flags & G_FILE_RELATIVE_REMAP)
|
||||||
|
makeFilesRelative(dir, NULL); /* note, making relative to something OTHER then G.sce */
|
||||||
|
|
||||||
err= write_file_handle(mainvar, file, NULL,NULL, write_user_block, write_flags);
|
err= write_file_handle(mainvar, file, NULL,NULL, write_user_block, write_flags);
|
||||||
close(file);
|
close(file);
|
||||||
|
|
||||||
|
|||||||
@@ -196,21 +196,12 @@ void FILE_OT_unpack_all(wmOperatorType *ot)
|
|||||||
|
|
||||||
static int make_paths_relative_exec(bContext *C, wmOperator *op)
|
static int make_paths_relative_exec(bContext *C, wmOperator *op)
|
||||||
{
|
{
|
||||||
char txtname[24]; /* text block name */
|
|
||||||
int tot, changed, failed, linked;
|
|
||||||
|
|
||||||
if(!G.relbase_valid) {
|
if(!G.relbase_valid) {
|
||||||
BKE_report(op->reports, RPT_WARNING, "Can't set relative paths with an unsaved blend file.");
|
BKE_report(op->reports, RPT_WARNING, "Can't set relative paths with an unsaved blend file.");
|
||||||
return OPERATOR_CANCELLED;
|
return OPERATOR_CANCELLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
txtname[0] = '\0';
|
makeFilesRelative(G.sce, op->reports);
|
||||||
makeFilesRelative(txtname, &tot, &changed, &failed, &linked);
|
|
||||||
|
|
||||||
if(failed)
|
|
||||||
BKE_reportf(op->reports, RPT_ERROR, "Total files %i|Changed %i|Failed %i, See Text \"%s\"|Linked %i", tot, changed, failed, txtname, linked);
|
|
||||||
else
|
|
||||||
BKE_reportf(op->reports, RPT_INFO, "Total files %i|Changed %i|Failed %i|Linked %i", tot, changed, failed, linked);
|
|
||||||
|
|
||||||
return OPERATOR_FINISHED;
|
return OPERATOR_FINISHED;
|
||||||
}
|
}
|
||||||
@@ -232,22 +223,12 @@ void FILE_OT_make_paths_relative(wmOperatorType *ot)
|
|||||||
|
|
||||||
static int make_paths_absolute_exec(bContext *C, wmOperator *op)
|
static int make_paths_absolute_exec(bContext *C, wmOperator *op)
|
||||||
{
|
{
|
||||||
char txtname[24]; /* text block name */
|
|
||||||
int tot, changed, failed, linked;
|
|
||||||
|
|
||||||
if(!G.relbase_valid) {
|
if(!G.relbase_valid) {
|
||||||
BKE_report(op->reports, RPT_WARNING, "Can't set absolute paths with an unsaved blend file.");
|
BKE_report(op->reports, RPT_WARNING, "Can't set absolute paths with an unsaved blend file.");
|
||||||
return OPERATOR_CANCELLED;
|
return OPERATOR_CANCELLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
txtname[0] = '\0';
|
makeFilesAbsolute(G.sce, op->reports);
|
||||||
makeFilesAbsolute(txtname, &tot, &changed, &failed, &linked);
|
|
||||||
|
|
||||||
if(failed)
|
|
||||||
BKE_reportf(op->reports, RPT_ERROR, "Total files %i|Changed %i|Failed %i, See Text \"%s\"|Linked %i", tot, changed, failed, txtname, linked);
|
|
||||||
else
|
|
||||||
BKE_reportf(op->reports, RPT_INFO, "Total files %i|Changed %i|Failed %i|Linked %i", tot, changed, failed, linked);
|
|
||||||
|
|
||||||
return OPERATOR_FINISHED;
|
return OPERATOR_FINISHED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -273,12 +254,7 @@ static int report_missing_files_exec(bContext *C, wmOperator *op)
|
|||||||
txtname[0] = '\0';
|
txtname[0] = '\0';
|
||||||
|
|
||||||
/* run the missing file check */
|
/* run the missing file check */
|
||||||
checkMissingFiles(txtname);
|
checkMissingFiles(G.sce, op->reports);
|
||||||
|
|
||||||
if(txtname[0] == '\0')
|
|
||||||
BKE_report(op->reports, RPT_INFO, "No external files missing.");
|
|
||||||
else
|
|
||||||
BKE_reportf(op->reports, RPT_ERROR, "Missing files listed in Text \"%s\"", txtname);
|
|
||||||
|
|
||||||
return OPERATOR_FINISHED;
|
return OPERATOR_FINISHED;
|
||||||
}
|
}
|
||||||
@@ -303,7 +279,7 @@ static int find_missing_files_exec(bContext *C, wmOperator *op)
|
|||||||
char *path;
|
char *path;
|
||||||
|
|
||||||
path= RNA_string_get_alloc(op->ptr, "path", NULL, 0);
|
path= RNA_string_get_alloc(op->ptr, "path", NULL, 0);
|
||||||
findMissingFiles(path);
|
findMissingFiles(path, G.sce);
|
||||||
MEM_freeN(path);
|
MEM_freeN(path);
|
||||||
|
|
||||||
return OPERATOR_FINISHED;
|
return OPERATOR_FINISHED;
|
||||||
|
|||||||
@@ -1535,10 +1535,10 @@ static int wm_save_as_mainfile_exec(bContext *C, wmOperator *op)
|
|||||||
fileflags= G.fileflags;
|
fileflags= G.fileflags;
|
||||||
|
|
||||||
/* set compression flag */
|
/* set compression flag */
|
||||||
if(RNA_boolean_get(op->ptr, "compress"))
|
if(RNA_boolean_get(op->ptr, "compress")) fileflags |= G_FILE_COMPRESS;
|
||||||
fileflags |= G_FILE_COMPRESS;
|
else fileflags &= ~G_FILE_COMPRESS;
|
||||||
else
|
if(RNA_boolean_get(op->ptr, "relative_remap")) fileflags |= G_FILE_RELATIVE_REMAP;
|
||||||
fileflags &= ~G_FILE_COMPRESS;
|
else fileflags &= ~G_FILE_RELATIVE_REMAP;
|
||||||
|
|
||||||
WM_write_file(C, path, fileflags, op->reports);
|
WM_write_file(C, path, fileflags, op->reports);
|
||||||
|
|
||||||
@@ -1559,6 +1559,7 @@ static void WM_OT_save_as_mainfile(wmOperatorType *ot)
|
|||||||
|
|
||||||
WM_operator_properties_filesel(ot, FOLDERFILE|BLENDERFILE, FILE_BLENDER);
|
WM_operator_properties_filesel(ot, FOLDERFILE|BLENDERFILE, FILE_BLENDER);
|
||||||
RNA_def_boolean(ot->srna, "compress", 0, "Compress", "Write compressed .blend file.");
|
RNA_def_boolean(ot->srna, "compress", 0, "Compress", "Write compressed .blend file.");
|
||||||
|
RNA_def_boolean(ot->srna, "relative_remap", 0, "Remap Relative", "Remap relative paths when saving in a different directory.");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* *************** save file directly ******** */
|
/* *************** save file directly ******** */
|
||||||
@@ -1597,6 +1598,7 @@ static void WM_OT_save_mainfile(wmOperatorType *ot)
|
|||||||
|
|
||||||
WM_operator_properties_filesel(ot, FOLDERFILE|BLENDERFILE, FILE_BLENDER);
|
WM_operator_properties_filesel(ot, FOLDERFILE|BLENDERFILE, FILE_BLENDER);
|
||||||
RNA_def_boolean(ot->srna, "compress", 0, "Compress", "Write compressed .blend file.");
|
RNA_def_boolean(ot->srna, "compress", 0, "Compress", "Write compressed .blend file.");
|
||||||
|
RNA_def_boolean(ot->srna, "relative_remap", 0, "Remap Relative", "Remap relative paths when saving in a different directory.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user