]> git.lyx.org Git - lyx.git/blobdiff - src/EmbeddedFiles.cpp
* gcc does not like missing characters in keywords
[lyx.git] / src / EmbeddedFiles.cpp
index 2680f4d56329aca3293e04a95c40b22f6db7ecdb..97f78d83024d69ece7a2df18bb4665a5889dc8e5 100644 (file)
@@ -20,6 +20,8 @@
 #include "debug.h"
 #include "gettext.h"
 #include "Format.h"
+#include "Lexer.h"
+#include "ErrorList.h"
 
 #include "frontends/alert.h"
 
@@ -72,7 +74,7 @@ using support::makedir;
 EmbeddedFile::EmbeddedFile(string const & file, string const & inzip_name,
        bool embed, Inset const * inset)
        : DocFileName(file, true), inzip_name_(inzip_name), embedded_(embed),
-               valid_(true), inset_list_()
+               inset_list_()
 {
        if (inset != NULL)
                inset_list_.push_back(inset);
@@ -107,7 +109,7 @@ void EmbeddedFile::saveBookmark(Buffer const * buf, int idx) const
                if (&(*it) == ptr) {
                        // this is basically BufferView::saveBookmark(0)
                        LyX::ref().session().bookmarks().save(
-                               FileName(buf->fileName()),
+                               FileName(buf->absFileName()),
                                it.bottom().pit(),
                                it.bottom().pos(),
                                it.paragraph().id(),
@@ -123,24 +125,12 @@ void EmbeddedFile::saveBookmark(Buffer const * buf, int idx) const
 
 string EmbeddedFile::availableFile(Buffer const * buf) const
 {
-       if (embedded())
-               return embeddedFile(buf);
-       else
-               return absFilename();
-}
-
-
-void EmbeddedFile::invalidate()
-{
-       // Clear inset_list_ because they will be registered again.
-       inset_list_.clear();
-       valid_ = false;
+       return embedded() ? embeddedFile(buf) : absFilename();
 }
 
 
 bool EmbeddedFile::extract(Buffer const * buf) const
 {
-
        string ext_file = absFilename();
        string emb_file = embeddedFile(buf);
 
@@ -197,7 +187,7 @@ bool EmbeddedFile::updateFromExternalFile(Buffer const * buf) const
                // other wise, ask if overwrite
                int const ret = Alert::prompt(
                        _("Update embedded file?"),
-                       bformat(_("Embeddedl file %1$s already exists, do you want to overwrite it"),
+                       bformat(_("Embedded file %1$s already exists, do you want to overwrite it"),
                                from_utf8(ext_file)), 1, 1, _("&Overwrite"), _("&Cancel"));
                if (ret != 0)
                        // if the user does not want to overwrite, we still consider it
@@ -223,28 +213,39 @@ bool EmbeddedFile::updateFromExternalFile(Buffer const * buf) const
 }
 
 
+void EmbeddedFile::updateInsets(Buffer const * buf) const
+{
+       vector<Inset const *>::const_iterator it = inset_list_.begin();
+       vector<Inset const *>::const_iterator it_end = inset_list_.end();
+       for (; it != it_end; ++it)
+               const_cast<Inset *>(*it)->updateEmbeddedFile(*buf, *this);
+}
+
+
 bool EmbeddedFiles::enabled() const
 {
        return buffer_->params().embedded;
 }
 
 
-bool EmbeddedFiles::enable(bool flag)
+void EmbeddedFiles::enable(bool flag)
 {
        if (enabled() != flag) {
                // if enable, copy all files to temppath()
                // if disable, extract all files
                if ((flag && !updateFromExternalFile()) || (!flag && !extract()))
-                       return false;
+                       return;
                // if operation is successful
                buffer_->markDirty();
                buffer_->params().embedded = flag;
+               if (flag)
+                       updateInsets();
        }
 }
 
 
-void EmbeddedFiles::registerFile(string const & filename,
-       bool embed, Inset const * inset)
+EmbeddedFile & EmbeddedFiles::registerFile(string const & filename,
+       bool embed, Inset const * inset, string const & inzipName)
 {
        // filename can be relative or absolute, translate to absolute filename
        string abs_filename = makeAbsPath(filename, buffer_->filePath()).absFilename();
@@ -257,63 +258,38 @@ void EmbeddedFiles::registerFile(string const & filename,
        // find this filename, keep the original embedding status
        if (it != file_list_.end()) {
                it->addInset(inset);
-               // if the file is embedded, the embedded file should have exist
-               // check for this to ensure that our logic is correct
-               if (it->embedded())
-                       BOOST_ASSERT(fs::exists(it->embeddedFile(buffer_)));
-               it->validate();
-               return;
+               return *it;
        }
-       // try to be more careful
+       //
        file_list_.push_back(EmbeddedFile(abs_filename, 
-               getInzipName(abs_filename), embed, inset));
-       // validate if things are OK
-       BOOST_ASSERT(fs::exists(file_list_.back().availableFile(buffer_)));
+               getInzipName(abs_filename, inzipName), embed, inset));
+       return file_list_.back();
 }
 
 
 void EmbeddedFiles::update()
 {
-       // invalidate all files, obsolete files will then not be validated by the
-       // following document scan. These files will still be kept though, because
-       // they may be added later and their embedding status will be meaningful
-       // again (thinking of cut/paste of an InsetInclude).
-       EmbeddedFileList::iterator it = file_list_.begin();
-       EmbeddedFileList::iterator it_end = file_list_.end();
-       for (; it != it_end; ++it)
-               // we do not update items that are manually inserted
-               if (it->refCount() > 0)
-                       it->invalidate();
+       file_list_.clear();
 
        for (InsetIterator it = inset_iterator_begin(buffer_->inset()); it; ++it)
                it->registerEmbeddedFiles(*buffer_, *this);
-
-       LYXERR(Debug::FILES) << "Manifest updated: " << endl
-               << *this
-               << "End Manifest" << endl;
 }
 
 
-bool EmbeddedFiles::write(DocFileName const & filename)
+bool EmbeddedFiles::writeFile(DocFileName const & filename)
 {
        // file in the temporary path has the content
        string const content = FileName(addName(buffer_->temppath(),
-               onlyFilename(filename.toFilesystemEncoding()))).toFilesystemEncoding();
+               "content.lyx")).toFilesystemEncoding();
 
-       // get a file list and write a manifest file
        vector<pair<string, string> > filenames;
-       string const manifest = FileName(
-               addName(buffer_->temppath(), "manifest.txt")).toFilesystemEncoding();
-
-       // write a manifest file
-       ofstream os(manifest.c_str());
-       os << *this;
-       os.close();
+       // add content.lyx to filenames
+       filenames.push_back(make_pair(content, "content.lyx"));
        // prepare list of embedded file
        EmbeddedFileList::iterator it = file_list_.begin();
        EmbeddedFileList::iterator it_end = file_list_.end();
        for (; it != it_end; ++it) {
-               if (it->valid() && it->embedded()) {
+               if (it->embedded()) {
                        string file = it->availableFile(buffer_);
                        if (file.empty())
                                lyxerr << "File " << it->absFilename() << " does not exist. Skip embedding it. " << endl;
@@ -321,9 +297,6 @@ bool EmbeddedFiles::write(DocFileName const & filename)
                                filenames.push_back(make_pair(file, it->inzipName()));
                }
        }
-       // add filename (.lyx) and manifest to filenames
-       filenames.push_back(make_pair(content, onlyFilename(filename.toFilesystemEncoding())));
-       filenames.push_back(make_pair(manifest, "manifest.txt"));
        // write a zip file with all these files. Write to a temp file first, to
        // avoid messing up the original file in case something goes terribly wrong.
        DocFileName zipfile(addName(buffer_->temppath(),
@@ -361,7 +334,7 @@ bool EmbeddedFiles::extract() const
        EmbeddedFileList::const_iterator it = file_list_.begin();
        EmbeddedFileList::const_iterator it_end = file_list_.end();
        for (; it != it_end; ++it)
-               if (it->valid() && it->embedded())
+               if (it->embedded())
                        if(!it->extract(buffer_))
                                return false;
        return true;
@@ -373,18 +346,20 @@ bool EmbeddedFiles::updateFromExternalFile() const
        EmbeddedFileList::const_iterator it = file_list_.begin();
        EmbeddedFileList::const_iterator it_end = file_list_.end();
        for (; it != it_end; ++it)
-               if (it->valid() && it->embedded())
+               if (it->embedded())
                        if (!it->updateFromExternalFile(buffer_))
                                return false;
        return true;
 }
 
 
-string const EmbeddedFiles::getInzipName(string const & abs_filename)
+string const EmbeddedFiles::getInzipName(string const & abs_filename, string const & name)
 {
        // register a new one, using relative file path as inzip_name
-       string inzip_name = to_utf8(makeRelPath(from_utf8(abs_filename),
-               from_utf8(buffer_->fileName())));
+       string inzip_name = name;
+       if (name.empty())
+               inzip_name = to_utf8(makeRelPath(from_utf8(abs_filename),
+                       from_utf8(buffer_->filePath())));
        // if inzip_name is an absolute path, use filename only to avoid
        // leaking of filesystem information in inzip_name
        // The second case covers cases '../path/file' and '.'
@@ -413,81 +388,14 @@ string const EmbeddedFiles::getInzipName(string const & abs_filename)
 }
 
 
-istream & operator>> (istream & is, EmbeddedFiles & files)
+void EmbeddedFiles::updateInsets() const
 {
-       files.clear();
-       string tmp;
-       getline(is, tmp);
-       // get version
-       istringstream itmp(tmp);
-       int version;
-       itmp.ignore(string("# LyX manifest version ").size());
-       itmp >> version;
-
-       if (version != 1) {
-               lyxerr << "This version of LyX can only read LyX manifest version 1" << endl;
-               return is;
-       }
-
-       getline(is, tmp);
-       if (tmp != "<manifest>") {
-               lyxerr << "Invalid manifest file, lacking <manifest>" << endl;
-               return is;
-       }
-       // manifest file may be messed up, be carefully
-       while (is.good()) {
-               getline(is, tmp);
-               if (tmp != "<file>")
-                       break;
-
-               string fname;
-               getline(is, fname);
-               string inzip_name;
-               getline(is, inzip_name);
-               getline(is, tmp);
-               istringstream itmp(tmp);
-               int embed;
-               itmp >> embed;
-
-               getline(is, tmp);
-               if (tmp != "</file>") {
-                       lyxerr << "Invalid manifest file, lacking </file>" << endl;
-                       break;
-               }
-
-               files.registerFile(fname, embed);
-       };
-       // the last line must be </manifest>
-       if (tmp != "</manifest>") {
-               lyxerr << "Invalid manifest file, lacking </manifest>" << endl;
-               return is;
-       }
-       return is;
+       EmbeddedFiles::EmbeddedFileList::const_iterator it = begin();
+       EmbeddedFiles::EmbeddedFileList::const_iterator it_end = end();
+       for (; it != it_end; ++it)
+               if (it->refCount() > 0)
+                       it->updateInsets(buffer_);
 }
 
 
-ostream & operator<< (ostream & os, EmbeddedFiles const & files)
-{
-       // store a version so that operator >> can read later versions
-       // using version information.
-       os << "# lyx manifest version 1\n";
-       os << "<manifest>\n";
-       EmbeddedFiles::EmbeddedFileList::const_iterator it = files.begin();
-       EmbeddedFiles::EmbeddedFileList::const_iterator it_end = files.end();
-       for (; it != it_end; ++it) {
-               if (!it->valid())
-                       continue;
-               // use differnt lines to make reading easier.
-               os << "<file>\n"
-                       // save the relative path
-                       << to_utf8(makeRelPath(from_utf8(it->absFilename()),
-                               from_utf8(files.buffer_->filePath()))) << '\n'
-                       << it->inzipName() << '\n'
-                       << it->embedded() << '\n'
-                       << "</file>\n";
-       }
-       os << "</manifest>\n";
-       return os;
-}
-
 }