+ fixes #0002029: VRML inline ignored

This commit is contained in:
wmayer 2015-03-30 02:23:49 +02:00
parent 995de944c8
commit dadc87eff8
3 changed files with 38 additions and 5 deletions

View File

@ -412,11 +412,16 @@ void PropertyFileIncluded::SaveDocFile (Base::Writer &writer) const
void PropertyFileIncluded::RestoreDocFile(Base::Reader &reader)
{
Base::FileInfo fi(_cValue.c_str());
if (fi.exists() && !fi.isWritable()) {
// This happens when an object is being restored and tries to reference the
// same file of another object (e.g. for copy&paste of objects inside the same document).
return;
}
Base::ofstream to(fi, std::ios::out | std::ios::binary);
if (!to) {
std::stringstream str;
str << "PropertyFileIncluded::RestoreDocFile(): "
<< "File '" << _cValue << "' in transient directory doesn't exist.";
<< "File '" << _cValue << "' in transient directory cannot be created.";
throw Base::Exception(str.str());
}

View File

@ -75,7 +75,7 @@ void VRMLObject::onChanged(const App::Property* prop)
const std::vector<std::string>& urls = Urls.getValues();
int index=0;
for (std::vector<std::string>::const_iterator it = urls.begin(); it != urls.end(); ++it, ++index) {
std::string output = getOutputFile(this->vrmlPath, *it);
std::string output = getRelativePath(this->vrmlPath, *it);
Resources.set1Value(index, output);
}
}
@ -91,7 +91,7 @@ PyObject *VRMLObject::getPyObject()
return Py::new_reference_to(PythonObject);
}
std::string VRMLObject::getOutputFile(const std::string& prefix, const std::string& resource) const
std::string VRMLObject::getRelativePath(const std::string& prefix, const std::string& resource) const
{
std::string str;
std::string intname = this->getNameInDocument();
@ -110,6 +110,20 @@ std::string VRMLObject::getOutputFile(const std::string& prefix, const std::stri
return str;
}
std::string VRMLObject::fixRelativePath(const std::string& name, const std::string& resource) const
{
// the part before the first '/' must match with object's internal name
std::string::size_type pos = resource.find('/');
if (pos != std::string::npos) {
std::string prefix = resource.substr(0, pos);
std::string suffix = resource.substr(pos);
if (prefix != name) {
return name + suffix;
}
}
return resource;
}
void VRMLObject::makeDirectories(const std::string& path, const std::string& subdir)
{
std::string::size_type pos = subdir.find('/');
@ -155,9 +169,19 @@ void VRMLObject::SaveDocFile (Base::Writer &writer) const
// store the inline files of the VRML file
if (this->index < Urls.getSize()) {
std::string url = Urls[this->index];
this->index++;
Base::FileInfo fi(url);
// it can happen that the transient directory has changed after
// saving the 'URLs' in RestoreDocFile() and then we have to
// try again with the new transient directory.
if (!fi.exists()) {
std::string path = getDocument()->TransientDir.getValue();
url = Resources[this->index];
url = path + "/" + url;
fi.setFile(url);
}
this->index++;
Base::ifstream file(fi, std::ios::in | std::ios::binary);
if (file) {
writer.Stream() << file.rdbuf();
@ -170,6 +194,9 @@ void VRMLObject::RestoreDocFile(Base::Reader &reader)
if (this->index < Resources.getSize()) {
std::string path = getDocument()->TransientDir.getValue();
std::string url = Resources[this->index];
std::string intname = this->getNameInDocument();
url = fixRelativePath(intname, url);
Resources.set1Value(this->index, url);
makeDirectories(path, url);
url = path + "/" + url;

View File

@ -60,7 +60,8 @@ public:
protected:
void onChanged(const App::Property*);
std::string getOutputFile(const std::string&, const std::string&) const;
std::string getRelativePath(const std::string&, const std::string&) const;
std::string fixRelativePath(const std::string&, const std::string&) const;
void makeDirectories(const std::string&, const std::string&);
private: