Render-farm and file utils for dealing with external data.
Useful to use before sending blend files to the renderfarm. * Make all Paths Relative - makes any absolute paths relative. * Report Missing Files - creates a textblock listing all missing files. * Find Missing Files - searches a directory recursively for filenames that dont exist at their current path. Added a path looper type and functions that currently loop on image, sound, font and external library paths.
This commit is contained in:
@@ -28,10 +28,7 @@
|
||||
* Contributor(s): Campbell Barton
|
||||
*
|
||||
* ***** END GPL/BL DUAL LICENSE BLOCK *****
|
||||
*
|
||||
* The old math stuff from Ton. These will slowly phase out in favour
|
||||
* of MTC calls. (or even MoTO :) )
|
||||
* */
|
||||
*/
|
||||
|
||||
/* Box Packer */
|
||||
|
||||
|
||||
59
source/blender/blenlib/BLI_bpath.h
Normal file
59
source/blender/blenlib/BLI_bpath.h
Normal file
@@ -0,0 +1,59 @@
|
||||
/**
|
||||
*
|
||||
* ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version. The Blender
|
||||
* Foundation also sells licenses for use in proprietary software under
|
||||
* the Blender License. See http://www.blender.org/BL/ for information
|
||||
* about this.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): Campbell Barton
|
||||
*
|
||||
* ***** END GPL/BL DUAL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
/* Based on ghash, difference is ghash is not a fixed size,
|
||||
* so for BPath we dont need to malloc */
|
||||
|
||||
struct BPathIterator {
|
||||
char* path;
|
||||
char* lib;
|
||||
char* name;
|
||||
void* data;
|
||||
int len;
|
||||
int type;
|
||||
};
|
||||
|
||||
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);
|
||||
|
||||
/* high level funcs */
|
||||
|
||||
/* creates a text file with missing files if there are any */
|
||||
struct Text * checkMissingFiles(void);
|
||||
void makeFilesRelative(int *tot, int *changed, int *failed, int *linked);
|
||||
void findMissingFiles(char *str);
|
||||
485
source/blender/blenlib/intern/bpath.c
Normal file
485
source/blender/blenlib/intern/bpath.c
Normal file
@@ -0,0 +1,485 @@
|
||||
/**
|
||||
*
|
||||
* ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version. The Blender
|
||||
* Foundation also sells licenses for use in proprietary software under
|
||||
* the Blender License. See http://www.blender.org/BL/ for information
|
||||
* about this.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): Campbell barton
|
||||
*
|
||||
* ***** END GPL/BL DUAL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#include "BLI_bpath.h"
|
||||
#include "BKE_global.h"
|
||||
#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 <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "BKE_main.h" /* so we can access G.main->*.first */
|
||||
#include "BKE_image.h" /* so we can check the image's type */
|
||||
|
||||
#include "blendef.h"
|
||||
#include "BKE_utildefines.h"
|
||||
|
||||
/* for writing to a textblock */
|
||||
#include "BKE_text.h"
|
||||
#include "BLI_blenlib.h"
|
||||
#include "DNA_text_types.h"
|
||||
|
||||
/* path/file handeling stuff */
|
||||
#ifndef WIN32
|
||||
#include <dirent.h>
|
||||
#else
|
||||
#include "BLI_winstuff.h"
|
||||
#endif
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <math.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define FILE_MAX 240
|
||||
|
||||
|
||||
/* TODO - BPATH_PLUGIN, BPATH_SEQ */
|
||||
enum BPathTypes {
|
||||
BPATH_IMAGE = 0,
|
||||
BPATH_SOUND,
|
||||
BPATH_FONT,
|
||||
BPATH_LIB,
|
||||
|
||||
BPATH_DONE
|
||||
};
|
||||
|
||||
|
||||
void BLI_bpathIterator_init( struct BPathIterator *bpi ) {
|
||||
bpi->type = BPATH_IMAGE;
|
||||
bpi->data = NULL;
|
||||
BLI_bpathIterator_step(bpi);
|
||||
}
|
||||
|
||||
char* BLI_bpathIterator_getPath( struct BPathIterator *bpi) {
|
||||
return bpi->path;
|
||||
}
|
||||
void BLI_bpathIterator_copyPathExpanded( struct BPathIterator *bpi, char *path_expanded) {
|
||||
char *filepath, *libpath;
|
||||
|
||||
filepath = BLI_bpathIterator_getPath(bpi);
|
||||
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 */
|
||||
BLI_convertstringcode(path_expanded, G.sce, G.scene->r.cfra);
|
||||
}
|
||||
}
|
||||
char* BLI_bpathIterator_getLib( struct BPathIterator *bpi) {
|
||||
return bpi->lib;
|
||||
}
|
||||
char* BLI_bpathIterator_getName( struct BPathIterator *bpi) {
|
||||
return bpi->name;
|
||||
}
|
||||
int BLI_bpathIterator_getType( struct BPathIterator *bpi) {
|
||||
return bpi->type;
|
||||
}
|
||||
int BLI_bpathIterator_getPathMaxLen( struct BPathIterator *bpi) {
|
||||
return bpi->len;
|
||||
}
|
||||
|
||||
/* 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) {
|
||||
if (ima==NULL)
|
||||
return NULL;
|
||||
|
||||
if (step_next)
|
||||
ima = ima->id.next;
|
||||
|
||||
while (ima) {
|
||||
if (ima->packedfile==NULL && ELEM3(ima->source, IMA_SRC_FILE, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE))
|
||||
break;
|
||||
/* image is not a image with a path, skip it */
|
||||
ima = ima->id.next;
|
||||
}
|
||||
return ima;
|
||||
}
|
||||
|
||||
static struct VFont *vf_getpath__internal(struct VFont *vf, int step_next) {
|
||||
if (vf==NULL)
|
||||
return NULL;
|
||||
|
||||
if (step_next)
|
||||
vf = vf->id.next;
|
||||
|
||||
while (vf) {
|
||||
if (vf->packedfile==NULL && BLI_streq(vf->name, "<builtin>")==0) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* font with no path, skip it */
|
||||
vf = vf->id.next;
|
||||
}
|
||||
return vf;
|
||||
}
|
||||
|
||||
static struct bSound *snd_getpath__internal(struct bSound *snd, int step_next) {
|
||||
if (snd==NULL)
|
||||
return NULL;
|
||||
|
||||
if (step_next)
|
||||
snd = snd->id.next;
|
||||
|
||||
while (snd) {
|
||||
if (snd->packedfile==NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* font with no path, skip it */
|
||||
snd = snd->id.next;
|
||||
}
|
||||
return snd;
|
||||
}
|
||||
|
||||
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) {
|
||||
/* get the path info from this datatype */
|
||||
Image *ima = (Image *)bpi->data;
|
||||
|
||||
bpi->lib = ima->id.lib ? ima->id.lib->filename : NULL;
|
||||
bpi->path = ima->name;
|
||||
bpi->name = ima->id.name+2;
|
||||
bpi->len = sizeof(ima->name);
|
||||
|
||||
/* we are done, advancing to the next item, this type worked fine */
|
||||
break;
|
||||
|
||||
} else {
|
||||
bpi->type+=1; /* advance to the next type */
|
||||
}
|
||||
|
||||
|
||||
} 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) {
|
||||
/* get the path info from this datatype */
|
||||
bSound *snd = (bSound *)bpi->data;
|
||||
|
||||
bpi->lib = snd->id.lib ? snd->id.lib->filename : NULL;
|
||||
bpi->path = snd->sample->name;
|
||||
bpi->name = snd->id.name+2;
|
||||
bpi->len = sizeof(snd->sample->name);
|
||||
|
||||
/* we are done, advancing to the next item, this type worked fine */
|
||||
break;
|
||||
} else {
|
||||
bpi->type+=1; /* advance to the next type */
|
||||
}
|
||||
|
||||
|
||||
} 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) {
|
||||
/* get the path info from this datatype */
|
||||
VFont *vf = (VFont *)bpi->data;
|
||||
|
||||
bpi->lib = vf->id.lib ? vf->id.lib->filename : NULL;
|
||||
bpi->path = vf->name;
|
||||
bpi->name = vf->id.name+2;
|
||||
bpi->len = sizeof(vf->name);
|
||||
|
||||
/* we are done, advancing to the next item, this type worked fine */
|
||||
break;
|
||||
} else {
|
||||
bpi->type+=1; /* advance to the next type */
|
||||
}
|
||||
|
||||
|
||||
} else if ((bpi->type) == BPATH_LIB) {
|
||||
|
||||
if (bpi->data) bpi->data = ((ID *)bpi->data)->next;
|
||||
else bpi->data = G.main->library.first;
|
||||
|
||||
if (bpi->data) {
|
||||
/* get the path info from this datatype */
|
||||
Library *lib = (Library *)bpi->data;
|
||||
|
||||
bpi->lib = NULL;
|
||||
bpi->path = lib->name;
|
||||
bpi->name = NULL;
|
||||
bpi->len = sizeof(lib->name);
|
||||
|
||||
/* we are done, advancing to the next item, this type worked fine */
|
||||
break;
|
||||
} else {
|
||||
bpi->type+=1; /* advance to the next type */
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int BLI_bpathIterator_isDone( struct BPathIterator *bpi) {
|
||||
return bpi->type==BPATH_DONE;
|
||||
}
|
||||
|
||||
/* include the path argument */
|
||||
static void bpathToText(Text *btxt, struct BPathIterator *bpi)
|
||||
{
|
||||
char *name;
|
||||
char path_expanded[FILE_MAXDIR*2];
|
||||
|
||||
switch(BLI_bpathIterator_getType(bpi)) {
|
||||
case BPATH_IMAGE:
|
||||
txt_insert_buf( btxt, "Image \"" );
|
||||
break;
|
||||
case BPATH_SOUND:
|
||||
txt_insert_buf( btxt, "Sound \"" );
|
||||
break;
|
||||
case BPATH_FONT:
|
||||
txt_insert_buf( btxt, "Font \"" );
|
||||
break;
|
||||
case BPATH_LIB:
|
||||
txt_insert_buf( btxt, "Library \"" );
|
||||
break;
|
||||
default:
|
||||
txt_insert_buf( btxt, "Unknown \"" );
|
||||
break;
|
||||
}
|
||||
|
||||
name = BLI_bpathIterator_getName(bpi);
|
||||
|
||||
if (name) {
|
||||
txt_insert_buf( btxt, name );
|
||||
}
|
||||
txt_insert_buf( btxt, "\" " );
|
||||
|
||||
BLI_bpathIterator_copyPathExpanded(bpi, path_expanded);
|
||||
|
||||
txt_insert_buf( btxt, path_expanded );
|
||||
txt_insert_buf( btxt, "\n" );
|
||||
txt_move_eof( btxt, 0 );
|
||||
}
|
||||
|
||||
/* high level function */
|
||||
Text *checkMissingFiles(void) {
|
||||
Text *btxt = NULL;
|
||||
struct BPathIterator bpi;
|
||||
|
||||
/* be sure there is low chance of the path being too short */
|
||||
char filepath_expanded[FILE_MAXDIR*2];
|
||||
char *filepath, *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 );
|
||||
|
||||
if (!BLI_exists(filepath_expanded)) {
|
||||
if (!btxt)
|
||||
btxt = add_empty_text( "missing_files.txt" );
|
||||
|
||||
bpathToText(btxt, &bpi);
|
||||
files_missing = 1;
|
||||
}
|
||||
BLI_bpathIterator_step(&bpi);
|
||||
}
|
||||
return btxt;
|
||||
}
|
||||
|
||||
/* dont log any errors at the moment, should probably do this */
|
||||
void makeFilesRelative(int *tot, int *changed, int *failed, int *linked) {
|
||||
struct BPathIterator bpi;
|
||||
char *filepath, *libpath;
|
||||
|
||||
/* be sure there is low chance of the path being too short */
|
||||
char filepath_relative[(FILE_MAXDIR * 2) + FILE_MAXFILE];
|
||||
|
||||
*tot = *changed = *failed = *linked = 0;
|
||||
|
||||
BLI_bpathIterator_init(&bpi);
|
||||
while (!BLI_bpathIterator_isDone(&bpi)) {
|
||||
filepath = BLI_bpathIterator_getPath(&bpi);
|
||||
libpath = BLI_bpathIterator_getLib(&bpi);
|
||||
|
||||
if(strncmp(filepath, "//", 2)==0) {
|
||||
if (libpath) { /* cant make relative if we are kibrary - TODO, LOG THIS */
|
||||
(*linked)++;
|
||||
} else { /* local data, use the blend files path */
|
||||
BLI_strncpy(filepath_relative, filepath, sizeof(filepath_relative));
|
||||
BLI_makestringcode(G.sce, filepath_relative);
|
||||
if (BLI_bpathIterator_getPathMaxLen(&bpi) < strlen(filepath_relative)) {
|
||||
(*failed)++;
|
||||
} else {
|
||||
/* safe to to check the length */
|
||||
if(strncmp(filepath_relative, "//", 2)==0) {
|
||||
(*failed)++;
|
||||
} else {
|
||||
strcpy(filepath, filepath_relative);
|
||||
(*changed)++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BLI_bpathIterator_step(&bpi);
|
||||
(*tot)++;
|
||||
}
|
||||
}
|
||||
|
||||
/* find this file recursively, use the biggest file so thumbnails dont get used by mistake
|
||||
- dir: subdir to search
|
||||
- filename: set this filename
|
||||
- filesize: filesize for the file
|
||||
*/
|
||||
#define MAX_RECUR 16
|
||||
static int findFileRecursive(char *filename_new, const char *dirname, const char *filename, int *filesize, int *recur_depth)
|
||||
{
|
||||
/* file searching stuff */
|
||||
DIR *dir;
|
||||
int file = 0;
|
||||
struct dirent *de;
|
||||
struct stat status;
|
||||
char path[FILE_MAX];
|
||||
int size;
|
||||
|
||||
printf("DIR %s\n", dirname);
|
||||
|
||||
dir = opendir(dirname);
|
||||
|
||||
if (dir==0)
|
||||
return 0;
|
||||
|
||||
if (*filesize == -1)
|
||||
*filesize = 0; /* dir opened fine */
|
||||
|
||||
while ((de = readdir(dir)) != NULL) {
|
||||
|
||||
if (strncmp(".", de->d_name, 2)==0 || strncmp("..", de->d_name, 3)==0)
|
||||
continue;
|
||||
|
||||
BLI_join_dirfile(path, dirname, de->d_name);
|
||||
|
||||
if (stat(path, &status) != 0)
|
||||
continue; /* cant stat, dont bother with this file, could print debug info here */
|
||||
|
||||
if (S_ISREG(status.st_mode)) { /* is file */
|
||||
if (strncmp(filename, de->d_name, FILE_MAX)==0) { /* name matches */
|
||||
/* open the file to read its size */
|
||||
file = open(path, O_BINARY|O_RDONLY);
|
||||
if (file >=0 ) {
|
||||
size = BLI_filesize(file);
|
||||
if (size > *filesize) { /* find the biggest file */
|
||||
*filesize = size;
|
||||
BLI_strncpy(filename_new, path, FILE_MAX);
|
||||
}
|
||||
close(file);
|
||||
}
|
||||
}
|
||||
} else if (S_ISDIR(status.st_mode)) { /* is subdir */
|
||||
if (*recur_depth <= MAX_RECUR) {
|
||||
(*recur_depth)++;
|
||||
findFileRecursive(filename_new, path, filename, filesize, recur_depth);
|
||||
(*recur_depth)--;
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir(dir);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* high level function - call from fileselector */
|
||||
void findMissingFiles(char *str) {
|
||||
struct BPathIterator bpi;
|
||||
|
||||
/* be sure there is low chance of the path being too short */
|
||||
char filepath_expanded[FILE_MAXDIR*2];
|
||||
char *filepath, *libpath;
|
||||
int filesize, recur_depth;
|
||||
|
||||
char dirname[FILE_MAX], filename[FILE_MAX], filename_new[FILE_MAX], dummyname[FILE_MAX];
|
||||
|
||||
BLI_split_dirfile(str, dirname, dummyname);
|
||||
|
||||
BLI_bpathIterator_init(&bpi);
|
||||
|
||||
while (!BLI_bpathIterator_isDone(&bpi)) {
|
||||
filepath = BLI_bpathIterator_getPath(&bpi);
|
||||
libpath = BLI_bpathIterator_getLib(&bpi);
|
||||
|
||||
if (libpath==NULL) {
|
||||
|
||||
BLI_bpathIterator_copyPathExpanded( &bpi, filepath_expanded );
|
||||
|
||||
if (!BLI_exists(filepath_expanded)) {
|
||||
/* can the dir be opened? */
|
||||
filesize = -1;
|
||||
recur_depth = 0;
|
||||
BLI_split_dirfile(filepath, dummyname, filename); /* the file to find */
|
||||
|
||||
findFileRecursive(filename_new, dirname, filename, &filesize, &recur_depth);
|
||||
if (filesize == -1) { /* could not open dir */
|
||||
printf("Could not open dir \"%s\"\n", dirname);
|
||||
return;
|
||||
}
|
||||
|
||||
if (filesize > 0) {
|
||||
|
||||
if (BLI_bpathIterator_getPathMaxLen( &bpi ) < strlen(filename_new)) {
|
||||
printf("cannot set path \"%s\" too long!", filename_new);
|
||||
} else {
|
||||
/* copy the found path into the old one */
|
||||
if (G.relbase_valid)
|
||||
BLI_makestringcode(G.sce, filename_new);
|
||||
|
||||
strcpy( BLI_bpathIterator_getPath( &bpi ), filename_new );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
BLI_bpathIterator_step(&bpi);
|
||||
}
|
||||
}
|
||||
@@ -101,6 +101,7 @@
|
||||
|
||||
#include "BLI_arithb.h"
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_bpath.h"
|
||||
#include "BLO_writefile.h"
|
||||
|
||||
#include "BSE_editipo.h"
|
||||
@@ -852,19 +853,6 @@ static void do_info_filemenu(void *arg, int event)
|
||||
case 25:
|
||||
BIF_screendump(1);
|
||||
break;
|
||||
case 10: /* pack data */
|
||||
check_packAll();
|
||||
break;
|
||||
case 11: /* unpack to current dir */
|
||||
unpackAll(PF_WRITE_LOCAL);
|
||||
G.fileflags &= ~G_AUTOPACK;
|
||||
break;
|
||||
case 12: /* unpack data */
|
||||
if (buttons_do_unpack() != RET_CANCEL) {
|
||||
/* Clear autopack bit only if user selected one of the unpack options */
|
||||
G.fileflags &= ~G_AUTOPACK;
|
||||
}
|
||||
break;
|
||||
case 13:
|
||||
exit_usiblender();
|
||||
break;
|
||||
@@ -902,6 +890,7 @@ static void do_info_filemenu(void *arg, int event)
|
||||
U.flag ^= (USER_FILECOMPRESS);
|
||||
break;
|
||||
}
|
||||
|
||||
allqueue(REDRAWINFO, 0);
|
||||
}
|
||||
|
||||
@@ -944,6 +933,81 @@ static uiBlock *info_openrecentmenu(void *arg_unused)
|
||||
return block;
|
||||
}
|
||||
|
||||
static void do_info_externalfiles(void *arg, int event)
|
||||
{
|
||||
switch (event) {
|
||||
|
||||
case 1: /* pack data */
|
||||
check_packAll();
|
||||
break;
|
||||
#if 0
|
||||
case 2: /* unpack to current dir */
|
||||
unpackAll(PF_WRITE_LOCAL);
|
||||
G.fileflags &= ~G_AUTOPACK;
|
||||
break;
|
||||
#endif
|
||||
case 3: /* unpack data */
|
||||
if (buttons_do_unpack() != RET_CANCEL) {
|
||||
/* Clear autopack bit only if user selected one of the unpack options */
|
||||
G.fileflags &= ~G_AUTOPACK;
|
||||
}
|
||||
break;
|
||||
case 10: /* make all paths relative */
|
||||
{
|
||||
int tot,changed,failed,linked;
|
||||
char str[512];
|
||||
makeFilesRelative(&tot, &changed, &failed, &linked);
|
||||
sprintf(str, "Make Relative%%t|Total files %i|Changed %i|Failed %i|Linked %i", tot, changed, failed, linked);
|
||||
pupmenu(str);
|
||||
}
|
||||
break;
|
||||
case 11: /* check images exist */
|
||||
{
|
||||
/* Its really text but only care about the name */
|
||||
ID *btxt = (ID *)checkMissingFiles();
|
||||
|
||||
if (btxt) {
|
||||
char str[128];
|
||||
sprintf(str, "Missing files listed in Text \"%s\"", btxt->name+2);
|
||||
error(str);
|
||||
} else {
|
||||
okee("No external files missing");
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 12: /* search for referenced files that are not available */
|
||||
activate_fileselect(FILE_SPECIAL, "Find Missing Files", "", findMissingFiles);
|
||||
break;
|
||||
}
|
||||
|
||||
allqueue(REDRAWINFO, 0);
|
||||
}
|
||||
|
||||
static uiBlock *info_externalfiles(void *arg_unused)
|
||||
{
|
||||
uiBlock *block;
|
||||
short yco = 20, menuwidth = 120;
|
||||
|
||||
block= uiNewBlock(&curarea->uiblocks, "info_externalfiles", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
|
||||
uiBlockSetButmFunc(block, do_info_externalfiles, NULL);
|
||||
|
||||
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Pack into Blend", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 1, "");
|
||||
#if 0
|
||||
uiDefBut(block, BUTM, 1, "Unpack Data to current dir", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 2, "Removes all packed files from the project and saves them to the current directory");
|
||||
#endif
|
||||
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Unpack into Files...", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 3, "");
|
||||
|
||||
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
|
||||
|
||||
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Make all Paths Relative", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 10, "");
|
||||
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Report Missing Files", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 11, "");
|
||||
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Find Missing Files", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 12, "");
|
||||
|
||||
uiBlockSetDirection(block, UI_RIGHT);
|
||||
uiTextBoundsBlock(block, 60);
|
||||
return block;
|
||||
}
|
||||
|
||||
static uiBlock *info_filemenu(void *arg_unused)
|
||||
{
|
||||
uiBlock *block;
|
||||
@@ -997,13 +1061,11 @@ static uiBlock *info_filemenu(void *arg_unused)
|
||||
uiDefIconTextBlockBut(block, info_file_exportmenu, NULL, ICON_RIGHTARROW_THIN, "Export", 0, yco-=20, menuwidth, 19, "");
|
||||
|
||||
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
|
||||
|
||||
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Pack Data", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 10, "");
|
||||
// uiDefBut(block, BUTM, 1, "Unpack Data to current dir", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 11, "Removes all packed files from the project and saves them to the current directory");
|
||||
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Unpack Data...", 0, yco-=20, 160, 19, NULL, 0.0, 0.0, 1, 12, "");
|
||||
|
||||
|
||||
uiDefIconTextBlockBut(block, info_externalfiles, NULL, ICON_RIGHTARROW_THIN, "External Data",0, yco-=20, 120, 19, "");
|
||||
|
||||
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
|
||||
|
||||
|
||||
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Quit Blender|Ctrl Q", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 13, "");
|
||||
|
||||
uiBlockSetDirection(block, UI_DOWN);
|
||||
|
||||
Reference in New Issue
Block a user