]> git.lyx.org Git - lyx.git/blobdiff - src/Buffer.cpp
Store ASCII data in std::string
[lyx.git] / src / Buffer.cpp
index bf12159db8f1f76ac9b45438f851a812f94e8b7c..1eaa6ac224b201a172bbe3f063f470252d4c52d7 100644 (file)
@@ -97,6 +97,7 @@
 #include "support/gzstream.h"
 #include "support/lstrings.h"
 #include "support/lyxalgo.h"
+#include "support/mutex.h"
 #include "support/os.h"
 #include "support/Package.h"
 #include "support/PathChanger.h"
@@ -353,13 +354,20 @@ private:
 /// Creates the per buffer temporary directory
 static FileName createBufferTmpDir()
 {
-       // FIXME THREAD
-       static int count;
+       // FIXME This would be the ideal application for a TempDir class (like
+       //       TempFile but for directories) 
+       string counter;
+       {
+               static int count;
+               static Mutex mutex;
+               Mutex::Locker locker(&mutex);
+               counter = convert<string>(count++);
+       }
        // We are in our own directory.  Why bother to mangle name?
        // In fact I wrote this code to circumvent a problematic behaviour
        // (bug?) of EMX mkstemp().
        FileName tmpfl(package().temp_dir().absFileName() + "/lyx_tmpbuf" +
-               convert<string>(count++));
+               counter);
 
        if (!tmpfl.createDirectory(0777)) {
                throw ExceptionMessage(WarningException, _("Disk Error: "), bformat(
@@ -645,12 +653,19 @@ BufferParams const & Buffer::masterParams() const
        // Copy child authors to the params. We need those pointers.
        AuthorList const & child_authors = params().authors();
        AuthorList::Authors::const_iterator it = child_authors.begin();
-       for (; it != child_authors.end(); it++)
+       for (; it != child_authors.end(); ++it)
                mparams.authors().record(*it);
        return mparams;
 }
 
 
+double Buffer::fontScalingFactor() const
+{
+       return isExporting() ? 75.0 * params().html_math_img_scale
+               : 0.01 * lyxrc.dpi * lyxrc.zoom * lyxrc.preview_scale_factor * params().display_pixel_ratio;
+}
+
+
 ParagraphList & Buffer::paragraphs()
 {
        return text().paragraphs();
@@ -1285,18 +1300,24 @@ bool Buffer::save() const
        // we first write the file to a new name, then move it to its
        // proper location once that has been done successfully. that
        // way we preserve the original file if something goes wrong.
-       TempFile tempfile(fileName().onlyPath(), "tmpXXXXXX.lyx");
-       FileName savefile(tempfile.name());
+       string const justname = fileName().onlyFileNameWithoutExt();
+       boost::scoped_ptr<TempFile>
+               tempfile(new TempFile(fileName().onlyPath(),
+                  justname + "-XXXXXX.lyx"));
+       bool const symlink = fileName().isSymLink();
+       if (!symlink)
+               tempfile->setAutoRemove(false);
 
+       FileName savefile(tempfile->name());
        LYXERR(Debug::FILES, "Saving to " << savefile.absFileName());
        if (!writeFile(savefile))
                return false;
 
        // we will set this to false if we fail
        bool made_backup = true;
-       bool const symlink = fileName().isSymLink();
+
+       FileName backupName(absFileName() + '~');
        if (lyxrc.make_backup) {
-               FileName backupName(absFileName() + '~');
                if (!lyxrc.backupdir_path.empty()) {
                        string const mangledName =
                                subst(subst(backupName.absFileName(), '/', '!'), ':', '!');
@@ -1304,6 +1325,8 @@ bool Buffer::save() const
                                                      mangledName));
                }
 
+               LYXERR(Debug::FILES, "Backing up original file to " <<
+                               backupName.absFileName());
                // Except file is symlink do not copy because of #6587.
                // Hard links have bad luck.
                made_backup = symlink ?
@@ -1319,21 +1342,45 @@ bool Buffer::save() const
                }
        }
 
+       // Destroy tempfile since it keeps the file locked on windows (bug 9234)
+       // Only do this if tempfile is not in autoremove mode
+       if (!symlink)
+               tempfile.reset();
        // If we have no symlink, we can simply rename the temp file.
        // Otherwise, we need to copy it so the symlink stays intact.
-       if (!symlink)
-               tempfile.setAutoRemove(false);
-       if (made_backup &&
-           (symlink ? savefile.copyTo(fileName(), true) : savefile.moveTo(fileName()))) {
+       if (made_backup && symlink ? savefile.copyTo(fileName(), true) :
+                                          savefile.moveTo(fileName()))
+       {
+               // saveCheckSum() was already called by writeFile(), but the
+               // time stamp is invalidated by copying/moving
+               saveCheckSum();
                markClean();
                return true;
        }
-       // else
-       Alert::error(_("Write failure"),
-                    bformat(_("Cannot move saved file to:\n  %1$s.\n"
-                              "But the file has successfully been saved as:\n  %2$s."),
-                            from_utf8(fileName().absFileName()),
-                from_utf8(savefile.absFileName())));
+       // else we saved the file, but failed to move it to the right location.
+
+       if (lyxrc.make_backup && made_backup && !symlink) {
+               // the original file was moved to filename.lyx~, so it will look
+               // to the user as if it was deleted. (see bug #9234.) we could try
+               // to restore it, but that would basically mean trying to do again
+               // what we just failed to do. better to leave things as they are.
+               Alert::error(_("Write failure"),
+                            bformat(_("The file has successfully been saved as:\n  %1$s.\n"
+                          "But LyX could not move it to:\n  %2$s.\n"
+                                                        "Your original file has been backed up to:\n  %3$s"),
+                                    from_utf8(savefile.absFileName()),
+             from_utf8(fileName().absFileName()),
+                        from_utf8(backupName.absFileName())));
+       } else {
+               // either we did not try to make a backup, or else we tried and failed,
+               // or else the original file was a symlink, in which case it was copied,
+               // not moved. so the original file is intact.
+               Alert::error(_("Write failure"),
+                            bformat(_("Cannot move saved file to:\n  %1$s.\n"
+                                      "But the file has successfully been saved as:\n  %2$s."),
+                                    from_utf8(fileName().absFileName()),
+                        from_utf8(savefile.absFileName())));
+       }
        return false;
 }
 
@@ -1538,13 +1585,12 @@ bool Buffer::makeLaTeXFile(FileName const & fname,
                writeLaTeXSource(os, original_path, runparams, output);
        }
        catch (EncodingException const & e) {
-               odocstringstream ods;
-               ods.put(e.failed_char);
+               docstring const failed(1, e.failed_char);
                ostringstream oss;
                oss << "0x" << hex << e.failed_char << dec;
                docstring msg = bformat(_("Could not find LaTeX command for character '%1$s'"
                                          " (code point %2$s)"),
-                                         ods.str(), from_utf8(oss.str()));
+                                         failed, from_utf8(oss.str()));
                errorList.push_back(ErrorItem(msg, _("Some characters of your document are probably not "
                                "representable in the chosen encoding.\n"
                                "Changing the document encoding to utf8 could help."),
@@ -3496,7 +3542,7 @@ void Buffer::changeRefsIfUnique(docstring const & from, docstring const & to)
 }
 
 
-void Buffer::getSourceCode(odocstream & os, string const format,
+void Buffer::getSourceCode(odocstream & os, string const format,
                           pit_type par_begin, pit_type par_end,
                           OutputWhat output, bool master) const
 {
@@ -3735,9 +3781,9 @@ int AutoSaveBuffer::generateChild()
        tempfile.setAutoRemove(false);
        FileName const tmp_ret = tempfile.name();
        if (!tmp_ret.empty()) {
-               buffer_.writeFile(tmp_ret);
-               // assume successful write of tmp_ret
-               if (!tmp_ret.moveTo(fname_))
+               if (!buffer_.writeFile(tmp_ret))
+                       failed = true;
+               else if (!tmp_ret.moveTo(fname_))
                        failed = true;
        } else
                failed = true;
@@ -3942,7 +3988,7 @@ Buffer::ExportStatus Buffer::doExport(string const & target, bool put_in_tempdir
                Graph::EdgePath::const_iterator it = path.begin();
                Graph::EdgePath::const_iterator en = path.end();
                for (; it != en; ++it)
-                       if (theConverters().get(*it).nice) {
+                       if (theConverters().get(*it).nice()) {
                                need_nice_file = true;
                                break;
                        }
@@ -4137,6 +4183,7 @@ Buffer::ExportStatus Buffer::preview(string const & format) const
        return preview(format, update_unincluded);
 }
 
+
 Buffer::ExportStatus Buffer::preview(string const & format, bool includeall) const
 {
        MarkAsExporting exporting(this);