]> git.lyx.org Git - lyx.git/blobdiff - src/Buffer.cpp
Support the new Indian Rupee currency symbol.
[lyx.git] / src / Buffer.cpp
index db5698129c2d293d0472c95f0cc546e47ae0e8c6..b43c4db2347bcd040404367d997ab192c837e7a9 100644 (file)
@@ -128,7 +128,7 @@ namespace {
 
 // Do not remove the comment below, so we get merge conflict in
 // independent branches. Instead add your own.
-int const LYX_FORMAT = 404; // rgh: refstyle
+int const LYX_FORMAT = 407; // uwestoehr: support for multirow offset
 
 typedef map<string, bool> DepClean;
 typedef map<docstring, pair<InsetLabel const *, Buffer::References> > RefCache;
@@ -189,7 +189,7 @@ public:
        /// is autosave needed?
        mutable bool bak_clean;
 
-       /// is this a unnamed file (New...)?
+       /// is this an unnamed file (New...)?
        bool unnamed;
 
        /// buffer is r/o
@@ -414,9 +414,8 @@ Buffer::~Buffer()
                        from_utf8(d->temppath.absFileName())));
        }
 
-       // Remove any previewed LaTeX snippets associated with this buffer.
        if (!isClone())
-               thePreviews().removeLoader(*this);
+               removePreviews();
 
        delete d;
 }
@@ -643,10 +642,11 @@ void Buffer::setReadonly(bool const flag)
 }
 
 
-void Buffer::setFileName(string const & newfile)
+void Buffer::setFileName(FileName const & fname)
 {
-       d->filename = makeAbsPath(newfile);
+       d->filename = fname;
        setReadonly(d->filename.isReadOnly());
+       saveCheckSum();
        updateTitles();
 }
 
@@ -876,6 +876,10 @@ Buffer::ReadStatus Buffer::readFile(FileName const & fn)
                return readFile(tmpFile);
        }
 
+       // FIXME: InsetInfo needs to know whether the file is under VCS 
+       // during the parse process, so this has to be done before.
+       lyxvc().file_found_hook(d->filename);
+
        if (readDocument(lex)) {
                Alert::error(_("Document format failure"),
                        bformat(_("%1$s ended unexpectedly, which means"
@@ -885,10 +889,9 @@ Buffer::ReadStatus Buffer::readFile(FileName const & fn)
        }
 
        d->file_fully_loaded = true;
-       // InsetInfo needs to know if file is under VCS
-       lyxvc().file_found_hook(fn);
        d->read_only = !fname.isWritable();
        params().compressed = fname.isZippedFile();
+       saveCheckSum();
        return ReadSuccess;
 }
 
@@ -905,6 +908,19 @@ void Buffer::setFullyLoaded(bool value)
 }
 
 
+void Buffer::updatePreviews() const
+{
+       if (graphics::Previews::status() != LyXRC::PREVIEW_OFF)
+               thePreviews().generateBufferPreviews(*this);
+}
+
+
+void Buffer::removePreviews() const
+{
+       thePreviews().removeLoader(*this);
+}
+
+
 Buffer::ReadStatus Buffer::parseLyXFormat(Lexer & lex,
        FileName const & fn, int & file_format) const
 {
@@ -1071,7 +1087,7 @@ bool Buffer::writeFile(FileName const & fname) const
        // see bug 6587
        // removeAutosaveFile();
 
-       saveCheckSum(d->filename);
+       saveCheckSum();
        message(str + _(" done."));
 
        return true;
@@ -2010,6 +2026,7 @@ void Buffer::dispatch(FuncRequest const & func, DispatchResult & dr)
 
        case LFUN_BUFFER_AUTO_SAVE:
                autoSave();
+               resetAutosaveTimers();
                break;
 
        case LFUN_BRANCH_ADD: {
@@ -2369,8 +2386,9 @@ bool Buffer::isExternallyModified(CheckMethod method) const
 }
 
 
-void Buffer::saveCheckSum(FileName const & file) const
+void Buffer::saveCheckSum() const
 {
+       FileName const & file = d->filename;
        if (file.exists()) {
                d->timestamp_ = file.lastModified();
                d->checksum_ = file.checksum();
@@ -2761,10 +2779,11 @@ void Buffer::Impl::updateMacros(DocIterator & it, DocIterator & scope)
                        }
 
                        InsetMath * im = iit->inset->asInsetMath();
-                       if (doing_export && im) 
+                       if (doing_export && im)  {
                                InsetMathHull * hull = im->asHullInset();
                                if (hull)
                                        hull->recordLocation(it);
+                       }
 
                        if (iit->inset->lyxCode() != MATHMACRO_CODE)
                                continue;
@@ -3213,13 +3232,7 @@ int AutoSaveBuffer::generateChild()
 
 FileName Buffer::getEmergencyFileName() const
 {
-       return getEmergencyFileNameFor(d->filename);
-}
-
-
-FileName Buffer::getEmergencyFileNameFor(FileName const & fn) const
-{
-       return FileName(fn.absFileName() + ".emergency");
+       return FileName(d->filename.absFileName() + ".emergency");
 }
 
 
@@ -3235,15 +3248,9 @@ FileName Buffer::getAutosaveFileName() const
        if (!isUnnamed() || fpath.empty() || !FileName(fpath).exists())
                fpath = filePath();
 
-       string const fname = d->filename.onlyFileName();
-       return getAutosaveFileNameFor(makeAbsPath(fname, fpath));
-}
-
+       string const fname = "#" + d->filename.onlyFileName() + "#";
 
-FileName Buffer::getAutosaveFileNameFor(FileName const & fn) const
-{
-       string const fname = "#" + onlyFileName(fn.absFileName()) + "#";
-       return FileName(onlyPath(fn.absFileName()) + fname);
+       return makeAbsPath(fname, fpath);
 }
 
 
@@ -3265,23 +3272,36 @@ void Buffer::moveAutosaveFile(support::FileName const & oldauto) const
 }
 
 
-// Perfect target for a thread...
-void Buffer::autoSave() const
+bool Buffer::autoSave() const 
 {
-       if (d->bak_clean || isReadonly()) {
-               // We don't save now, but we'll try again later
-               resetAutosaveTimers();
-               return;
-       }
+       Buffer const * buf = d->cloned_buffer_ ? d->cloned_buffer_ : this;
+       if (buf->d->bak_clean || isReadonly())
+               return true;
 
-       // emit message signal.
        message(_("Autosaving current document..."));
-       AutoSaveBuffer autosave(*this, getAutosaveFileName());
-       autosave.start();
-
-       d->bak_clean = true;
-
-       resetAutosaveTimers();
+       buf->d->bak_clean = true;
+       
+       FileName const fname = getAutosaveFileName();
+       if (d->cloned_buffer_) {
+               // If this buffer is cloned, we assume that
+               // we are running in a separate thread already.
+               FileName const tmp_ret = FileName::tempName("lyxauto");
+               if (!tmp_ret.empty()) {
+                       writeFile(tmp_ret);
+                       // assume successful write of tmp_ret
+                       if (tmp_ret.moveTo(fname))
+                               return true;
+               }
+               // failed to write/rename tmp_ret so try writing direct
+               return writeFile(fname);
+       } else {        
+               /// This function is deprecated as the frontend needs to take care
+               /// of cloning the buffer and autosaving it in another thread. It
+               /// is still here to allow (QT_VERSION < 0x040400).
+               AutoSaveBuffer autosave(*this, fname);
+               autosave.start();
+               return true;
+       }
 }
 
 
@@ -3602,25 +3622,25 @@ vector<string> Buffer::backends() const
 }
 
 
-Buffer::ReadStatus Buffer::extractFromVC(FileName const & fn)
+Buffer::ReadStatus Buffer::extractFromVC()
 {
-       bool const found = LyXVC::file_not_found_hook(fn);
+       bool const found = LyXVC::file_not_found_hook(d->filename);
        if (!found)
                return ReadFileNotFound;
-       if (!fn.isReadableFile())
+       if (!d->filename.isReadableFile())
                return ReadVCError;
        return ReadSuccess;
 }
 
 
-Buffer::ReadStatus Buffer::loadEmergency(FileName const & fn)
+Buffer::ReadStatus Buffer::loadEmergency()
 {
-       FileName const emergencyFile = getEmergencyFileNameFor(fn);
+       FileName const emergencyFile = getEmergencyFileName();
        if (!emergencyFile.exists() 
-                 || emergencyFile.lastModified() <= fn.lastModified())
+                 || emergencyFile.lastModified() <= d->filename.lastModified())
                return ReadFileNotFound;
 
-       docstring const file = makeDisplayPath(fn.absFileName(), 20);
+       docstring const file = makeDisplayPath(d->filename.absFileName(), 20);
        docstring const text = bformat(_("An emergency save of the document "
                "%1$s exists.\n\nRecover emergency save?"), file);
        
@@ -3634,13 +3654,12 @@ Buffer::ReadStatus Buffer::loadEmergency(FileName const & fn)
                ReadStatus const ret_llf = loadThisLyXFile(emergencyFile);
                bool const success = (ret_llf == ReadSuccess);
                if (success) {
-                       saveCheckSum(fn);
                        markDirty();
                        str = _("Document was successfully recovered.");
                } else
                        str = _("Document was NOT successfully recovered.");
                str += "\n\n" + bformat(_("Remove emergency file now?\n(%1$s)"),
-                                       makeDisplayPath(emergencyFile.absFileName()));
+                       makeDisplayPath(emergencyFile.absFileName()));
 
                int const del_emerg = 
                        Alert::prompt(_("Delete emergency file?"), str, 1, 1,
@@ -3670,15 +3689,15 @@ Buffer::ReadStatus Buffer::loadEmergency(FileName const & fn)
 }
 
 
-Buffer::ReadStatus Buffer::loadAutosave(FileName const & fn)
+Buffer::ReadStatus Buffer::loadAutosave()
 {
        // Now check if autosave file is newer.
-       FileName const autosaveFile = getAutosaveFileNameFor(fn);
+       FileName const autosaveFile = getAutosaveFileName();
        if (!autosaveFile.exists() 
-                 || autosaveFile.lastModified() <= fn.lastModified()) 
+                 || autosaveFile.lastModified() <= d->filename.lastModified()) 
                return ReadFileNotFound;
 
-       docstring const file = makeDisplayPath(fn.absFileName(), 20);
+       docstring const file = makeDisplayPath(d->filename.absFileName(), 20);
        docstring const text = bformat(_("The backup of the document %1$s " 
                "is newer.\n\nLoad the backup instead?"), file);
        int const ret = Alert::prompt(_("Load backup?"), text, 0, 2,
@@ -3691,7 +3710,6 @@ Buffer::ReadStatus Buffer::loadAutosave(FileName const & fn)
                // the file is not saved if we load the autosave file.
                if (ret_llf == ReadSuccess) {
                        markDirty();
-                       saveCheckSum(fn);
                        return ReadSuccess;
                }
                return ReadAutosaveFailure;
@@ -3707,23 +3725,23 @@ Buffer::ReadStatus Buffer::loadAutosave(FileName const & fn)
 }
 
 
-Buffer::ReadStatus Buffer::loadLyXFile(FileName const & fn)
+Buffer::ReadStatus Buffer::loadLyXFile()
 {
-       if (!fn.isReadableFile()) {
-               ReadStatus const ret_rvc = extractFromVC(fn);
+       if (!d->filename.isReadableFile()) {
+               ReadStatus const ret_rvc = extractFromVC();
                if (ret_rvc != ReadSuccess)
                        return ret_rvc;
        }
 
-       ReadStatus const ret_re = loadEmergency(fn);
+       ReadStatus const ret_re = loadEmergency();
        if (ret_re == ReadSuccess || ret_re == ReadCancel)
                return ret_re;
        
-       ReadStatus const ret_ra = loadAutosave(fn);
+       ReadStatus const ret_ra = loadAutosave();
        if (ret_ra == ReadSuccess || ret_ra == ReadCancel)
                return ret_ra;
 
-       return loadThisLyXFile(fn);
+       return loadThisLyXFile(d->filename);
 }
 
 
@@ -4095,32 +4113,62 @@ int Buffer::spellCheck(DocIterator & from, DocIterator & to,
 }
 
 
-bool Buffer::reload()
+Buffer::ReadStatus Buffer::reload()
 {
        setBusy(true);
-       // c.f. bug 6587
+       // c.f. bug http://www.lyx.org/trac/ticket/6587
        removeAutosaveFile();
        // e.g., read-only status could have changed due to version control
        d->filename.refresh();
        docstring const disp_fn = makeDisplayPath(d->filename.absFileName());
 
-       bool const success = (loadLyXFile(d->filename) == ReadSuccess);
-       if (success) {
+       ReadStatus const status = loadLyXFile();
+       if (status == ReadSuccess) {
                updateBuffer();
                changed(true);
                updateTitles();
                markClean();
-               saveCheckSum(d->filename);
                message(bformat(_("Document %1$s reloaded."), disp_fn));
        } else {
                message(bformat(_("Could not reload document %1$s."), disp_fn));
        }       
        setBusy(false);
-       thePreviews().removeLoader(*this);
-       if (graphics::Previews::status() != LyXRC::PREVIEW_OFF)
-               thePreviews().generateBufferPreviews(*this);
+       removePreviews();
+       updatePreviews();
        errors("Parse");
-       return success;
+       return status;
+}
+
+
+bool Buffer::saveAs(FileName const & fn)
+{
+       FileName const old_name = fileName();
+       FileName const old_auto = getAutosaveFileName();
+       bool const old_unnamed = isUnnamed();
+
+       setFileName(fn);
+       markDirty();
+       setUnnamed(false);
+
+       if (save()) {
+               // bring the autosave file with us, just in case.
+               moveAutosaveFile(old_auto);
+               // validate version control data and
+               // correct buffer title
+               lyxvc().file_found_hook(fileName());
+               updateTitles();
+               // the file has now been saved to the new location.
+               // we need to check that the locations of child buffers
+               // are still valid.
+               checkChildBuffers();
+               return true;
+       } else {
+               // save failed
+               // reset the old filename and unnamed state
+               setFileName(old_name);
+               setUnnamed(old_unnamed);
+               return false;
+       }
 }