#include "ParagraphParameters.h"
#include "ParIterator.h"
#include "PDFOptions.h"
+#include "Session.h"
#include "SpellChecker.h"
#include "sgml.h"
#include "texstream.h"
#include "mathed/InsetMathHull.h"
#include "mathed/MacroTable.h"
-#include "mathed/MathMacroTemplate.h"
+#include "mathed/InsetMathMacroTemplate.h"
#include "mathed/MathSupport.h"
#include "graphics/GraphicsCache.h"
typedef map<string, bool> DepClean;
typedef map<docstring, pair<InsetLabel const *, Buffer::References> > RefCache;
-} // namespace anon
+} // namespace
// A storehouse for the cloned buffers.
/** If we have branches that use the file suffix
feature, return the file name with suffix appended.
*/
- support::FileName exportFileName() const;
+ FileName exportFileName() const;
Buffer * owner_;
/// Container for all sort of Buffer dependant errors.
map<string, ErrorList> errorLists;
- /// timestamp and checksum used to test if the file has been externally
- /// modified. (Used to properly enable 'File->Revert to saved', bug 4114).
- time_t timestamp_;
+ /// checksum used to test if the file has been externally modified. Used to
+ /// double check whether the file had been externally modified when saving.
unsigned long checksum_;
///
/// A cache for the bibfiles (including bibfiles of loaded child
/// documents), needed for appropriate update of natbib labels.
- mutable support::FileNamePairList bibfiles_cache_;
+ mutable FileNamePairList bibfiles_cache_;
// FIXME The caching mechanism could be improved. At present, we have a
// cache for each Buffer, that caches all the bibliography info for that
mutable BiblioInfo bibinfo_;
/// whether the bibinfo cache is valid
mutable bool bibinfo_cache_valid_;
- /// whether the bibfile cache is valid
- mutable bool bibfile_cache_valid_;
/// Cache of timestamps of .bib files
map<FileName, time_t> bibfile_status_;
/// Indicates whether the bibinfo has changed since the last time
if (!cloned_buffer_ && parent_buffer && pb)
LYXERR0("Warning: a buffer should not have two parents!");
parent_buffer = pb;
- if (!cloned_buffer_ && parent_buffer) {
- parent_buffer->invalidateBibfileCache();
+ if (!cloned_buffer_ && parent_buffer)
parent_buffer->invalidateBibinfoCache();
- }
}
/// If non zero, this buffer is a clone of existing buffer \p cloned_buffer_
// Make sure the file monitor monitors the good file.
void refreshFileMonitor();
- /// has it been notified of an external modification?
- bool isExternallyModified() const { return externally_modified_; }
-
/// Notify or clear of external modification
- void fileExternallyModified(bool modified) const;
+ void fileExternallyModified(bool exists);
- /// Block notifications of external modifications
- FileMonitorBlocker blockFileMonitor() { return file_monitor_->block(10); }
+ /// has been externally modified? Can be reset by the user.
+ mutable bool externally_modified_;
private:
/// So we can force access via the accessors.
int char_count_;
int blank_count_;
- /// has been externally modified? Can be reset by the user.
- mutable bool externally_modified_;
-
FileMonitorPtr file_monitor_;
};
: owner_(owner), lyx_clean(true), bak_clean(true), unnamed(false),
internal_buffer(false), read_only(readonly_), filename(file),
file_fully_loaded(false), file_format(LYX_FORMAT), need_format_backup(false),
- ignore_parent(false), toc_backend(owner), macro_lock(false), timestamp_(0),
+ ignore_parent(false), toc_backend(owner), macro_lock(false),
checksum_(0), wa_(0), gui_(0), undo_(*owner), bibinfo_cache_valid_(false),
- bibfile_cache_valid_(false), cite_labels_valid_(false), preview_error_(false),
+ cite_labels_valid_(false), preview_error_(false),
inset(0), preview_loader_(0), cloned_buffer_(cloned_buffer),
clone_list_(0), doing_export(false),
- tracked_changes_present_(0), parent_buffer(0),
- word_count_(0), char_count_(0), blank_count_(0),
- externally_modified_(false)
+ tracked_changes_present_(0), externally_modified_(false), parent_buffer(0),
+ word_count_(0), char_count_(0), blank_count_(0)
{
refreshFileMonitor();
if (!cloned_buffer_) {
bibfiles_cache_ = cloned_buffer_->d->bibfiles_cache_;
bibinfo_ = cloned_buffer_->d->bibinfo_;
bibinfo_cache_valid_ = cloned_buffer_->d->bibinfo_cache_valid_;
- bibfile_cache_valid_ = cloned_buffer_->d->bibfile_cache_valid_;
bibfile_status_ = cloned_buffer_->d->bibfile_status_;
cite_labels_valid_ = cloned_buffer_->d->cite_labels_valid_;
unnamed = cloned_buffer_->d->unnamed;
// ourselves as a child.
d->clone_list_->erase(this);
// loop over children
- Impl::BufferPositionMap::iterator it = d->children_positions.begin();
- Impl::BufferPositionMap::iterator end = d->children_positions.end();
- for (; it != end; ++it) {
- Buffer * child = const_cast<Buffer *>(it->first);
+ for (auto const & p : d->children_positions) {
+ Buffer * child = const_cast<Buffer *>(p.first);
if (d->clone_list_->erase(child))
delete child;
}
d->position_to_children.clear();
} else {
// loop over children
- Impl::BufferPositionMap::iterator it = d->children_positions.begin();
- Impl::BufferPositionMap::iterator end = d->children_positions.end();
- for (; it != end; ++it) {
- Buffer * child = const_cast<Buffer *>(it->first);
- if (theBufferList().isLoaded(child)) {
- if (theBufferList().isOthersChild(this, child))
- child->setParent(0);
- else
- theBufferList().release(child);
+ for (auto const & p : d->children_positions) {
+ Buffer * child = const_cast<Buffer *>(p.first);
+ if (theBufferList().isLoaded(child)) {
+ if (theBufferList().isOthersChild(this, child))
+ child->setParent(0);
+ else
+ theBufferList().release(child);
}
}
if (!isClean()) {
docstring msg = _("LyX attempted to close a document that had unsaved changes!\n");
- msg += emergencyWrite();
+ try {
+ msg += emergencyWrite();
+ } catch (...) {
+ msg += " " + _("Save failed! Document is lost.");
+ }
Alert::warning(_("Attempting to close changed document!"), msg);
}
// math macro caches need to be rethought and simplified.
// I am not sure wether we should handle Buffer cloning here or in BufferList.
// Right now BufferList knows nothing about buffer clones.
- Impl::PositionScopeBufferMap::iterator it = d->position_to_children.begin();
- Impl::PositionScopeBufferMap::iterator end = d->position_to_children.end();
- for (; it != end; ++it) {
- DocIterator dit = it->first.clone(buffer_clone);
+ for (auto const & p : d->position_to_children) {
+ DocIterator dit = p.first.clone(buffer_clone);
dit.setBuffer(buffer_clone);
- Buffer * child = const_cast<Buffer *>(it->second.buffer);
+ Buffer * child = const_cast<Buffer *>(p.second.buffer);
child->cloneWithChildren(bufmap, clones);
BufferMap::iterator const bit = bufmap.find(child);
BufferParams & mparams = const_cast<Buffer *>(masterBuffer())->params();
// 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)
- mparams.authors().record(*it);
+ for (Author const & a : params().authors())
+ mparams.authors().record(a);
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;
+ : 0.01 * lyxrc.dpi * lyxrc.currentZoom * lyxrc.preview_scale_factor * params().display_pixel_ratio;
}
FileName const bname(
addName(path, onlyFileName(
changeExtension(filename,
- formats.extension(params().bufferFormat()) + ".out"))));
+ theFormats().extension(params().bufferFormat()) + ".out"))));
// Also consider the master buffer log file
FileName masterfname = fname;
errorList.push_back(ErrorItem(_("Document header error"), s));
}
+ params().shell_escape = theSession().shellescapeFiles().find(absFileName());
+
params().makeDocumentClass();
return unknown_tokens;
// inform parent buffer about local macros
if (parent()) {
Buffer const * pbuf = parent();
- UserMacroSet::const_iterator cit = usermacros.begin();
- UserMacroSet::const_iterator end = usermacros.end();
- for (; cit != end; ++cit)
- pbuf->usermacros.insert(*cit);
+ for (auto const & m : usermacros)
+ pbuf->usermacros.insert(m);
}
usermacros.clear();
updateMacros();
bool Buffer::importString(string const & format, docstring const & contents, ErrorList & errorList)
{
- Format const * fmt = formats.getFormat(format);
+ Format const * fmt = theFormats().getFormat(format);
if (!fmt)
return false;
// It is important to use the correct extension here, since some
d->file_fully_loaded = true;
d->read_only = !d->filename.isWritable();
- params().compressed = formats.isZippedFile(d->filename);
+ params().compressed = theFormats().isZippedFile(d->filename);
saveCheckSum();
return ReadSuccess;
}
command << os::python()
<< ' ' << quoteName(lyx2lyx.toFilesystemEncoding())
<< " -t " << convert<string>(LYX_FORMAT)
- << " -o " << quoteName(tmpfile.toFilesystemEncoding())
+ << " -o " << quoteName(tmpfile.toSafeFilesystemEncoding())
<< ' ' << quoteName(fn.toSafeFilesystemEncoding());
string const command_str = command.str();
// Should probably be moved to somewhere else: BufferView? GuiView?
bool Buffer::save() const
{
- FileMonitorBlocker block = d->blockFileMonitor();
docstring const file = makeDisplayPath(absFileName(), 20);
d->filename.refresh();
// if the file does not yet exist, none of the backup activity
// that follows is necessary
- if (!fileName().exists()) {
+ if (!fileName().exists()) {
if (!writeFile(fileName()))
- return false;
- markClean();
- return true;
- }
+ return false;
+ markClean();
+ return true;
+ }
// we first write the file to a new name, then move it to its
// proper location once that has been done successfully. that
return user_message;
}
- user_message += " " + _("Save failed! Bummer. Document is lost.");
+ user_message += " " + _("Save failed! Document is lost.");
// Don't try again.
markClean();
return user_message;
// Important: Keep the version formatting in sync with lyx2lyx and
// tex2lyx (bug 7951)
ofs << "#LyX " << lyx_version_major << "." << lyx_version_minor
- << " created this file. For more info see http://www.lyx.org/\n"
+ << " created this file. For more info see https://www.lyx.org/\n"
<< "\\lyxformat " << LYX_FORMAT << "\n"
<< "\\begin_document\n";
/// For each author, set 'used' to true if there is a change
/// by this author in the document; otherwise set it to 'false'.
- AuthorList::Authors::const_iterator a_it = params().authors().begin();
- AuthorList::Authors::const_iterator a_end = params().authors().end();
- for (; a_it != a_end; ++a_it)
- a_it->setUsed(false);
+ for (Author const & a : params().authors())
+ a.setUsed(false);
ParIterator const end = const_cast<Buffer *>(this)->par_iterator_end();
ParIterator it = const_cast<Buffer *>(this)->par_iterator_begin();
catch (exception const & e) {
errorList.push_back(ErrorItem(_("conversion failed"),
_(e.what())));
+ lyxerr << e.what() << endl;
failed_export = true;
}
catch (...) {
// first paragraph of the document. (Asger)
if (output_preamble && runparams.nice) {
os << "%% LyX " << lyx_version << " created this file. "
- "For more info, see http://www.lyx.org/.\n"
+ "For more info, see https://www.lyx.org/.\n"
"%% Do not edit unless you really know what "
"you are doing.\n";
}
if (!uncodable_glyphs.empty()) {
frontend::Alert::warning(
_("Uncodable character in file path"),
- support::bformat(
+ bformat(
_("The path of your document\n"
"(%1$s)\n"
"contains glyphs that are unknown "
inputpath, uncodable_glyphs));
} else {
string docdir =
- support::latex_path(original_path);
+ latex_path(original_path);
if (contains(docdir, '#')) {
docdir = subst(docdir, "#", "\\#");
os << "\\catcode`\\#=11"
// Biblatex bibliographies are loaded here
if (params().useBiblatex()) {
vector<docstring> const bibfiles =
- prepareBibFilePaths(runparams, getBibfilesCache(), true);
+ prepareBibFilePaths(runparams, getBibfiles(), true);
for (docstring const & file: bibfiles)
os << "\\addbibresource{" << file << "}\n";
}
vector<string> pll = features.getPolyglossiaExclusiveLanguages();
if (!bll.empty()) {
docstring langs;
- for (vector<string>::const_iterator it = bll.begin(); it != bll.end(); ++it) {
+ for (string const & sit : bll) {
if (!langs.empty())
langs += ", ";
- langs += _(*it);
+ langs += _(sit);
}
blangs = bll.size() > 1 ?
- support::bformat(_("The languages %1$s are only supported by Babel."), langs)
- : support::bformat(_("The language %1$s is only supported by Babel."), langs);
+ bformat(_("The languages %1$s are only supported by Babel."), langs)
+ : bformat(_("The language %1$s is only supported by Babel."), langs);
}
if (!pll.empty()) {
docstring langs;
- for (vector<string>::const_iterator it = pll.begin(); it != pll.end(); ++it) {
+ for (string const & pit : pll) {
if (!langs.empty())
langs += ", ";
- langs += _(*it);
+ langs += _(pit);
}
plangs = pll.size() > 1 ?
- support::bformat(_("The languages %1$s are only supported by Polyglossia."), langs)
- : support::bformat(_("The language %1$s is only supported by Polyglossia."), langs);
+ bformat(_("The languages %1$s are only supported by Polyglossia."), langs)
+ : bformat(_("The language %1$s is only supported by Polyglossia."), langs);
if (!blangs.empty())
- plangs += "\n";
+ plangs += "\n";
}
frontend::Alert::warning(
_("Incompatible Languages!"),
- support::bformat(
+ bformat(
_("You cannot use the following languages "
"together in one LaTeX document because "
"they require conflicting language packages:\n"
os.lastChar('\n');
// output the parent macros
- MacroSet::iterator it = parentMacros.begin();
- MacroSet::iterator end = parentMacros.end();
- for (; it != end; ++it) {
- int num_lines = (*it)->write(os.os(), true);
+ for (auto const & mac : parentMacros) {
+ int num_lines = mac->write(os.os(), true);
os.texrow().newlines(num_lines);
}
os << from_ascii(tclass.class_header());
else if (runparams.flavor == OutputParams::XML)
os << "PUBLIC \"-//OASIS//DTD DocBook XML V4.2//EN\" "
- << "\"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd\"";
+ << "\"https://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd\"";
else
os << " PUBLIC \"-//OASIS//DTD DocBook V4.2//EN\"";
os << "<!-- " << ((runparams.flavor == OutputParams::XML)? "XML" : "SGML")
<< " file was created by LyX " << lyx_version
- << "\n See http://www.lyx.org/ for more information -->\n";
+ << "\n See https://www.lyx.org/ for more information -->\n";
params().documentClass().counters().reset();
list.clear();
shared_ptr<Toc> toc = d->toc_backend.toc("label");
- Toc::const_iterator toc_it = toc->begin();
- Toc::const_iterator end = toc->end();
- for (; toc_it != end; ++toc_it) {
- if (toc_it->depth() == 0)
- list.push_back(toc_it->str());
- }
-}
-
-
-void Buffer::updateBibfilesCache(UpdateScope scope) const
-{
- // FIXME This is probably unnecssary, given where we call this.
- // If this is a child document, use the parent's cache instead.
- if (parent() && scope != UpdateChildOnly) {
- masterBuffer()->updateBibfilesCache();
- return;
- }
-
- d->bibfiles_cache_.clear();
- for (InsetIterator it = inset_iterator_begin(inset()); it; ++it) {
- if (it->lyxCode() == BIBTEX_CODE) {
- InsetBibtex const & inset = static_cast<InsetBibtex const &>(*it);
- support::FileNamePairList const bibfiles = inset.getBibFiles();
- d->bibfiles_cache_.insert(d->bibfiles_cache_.end(),
- bibfiles.begin(),
- bibfiles.end());
- } else if (it->lyxCode() == INCLUDE_CODE) {
- InsetInclude & inset = static_cast<InsetInclude &>(*it);
- Buffer const * const incbuf = inset.getChildBuffer();
- if (!incbuf)
- continue;
- support::FileNamePairList const & bibfiles =
- incbuf->getBibfilesCache(UpdateChildOnly);
- if (!bibfiles.empty()) {
- d->bibfiles_cache_.insert(d->bibfiles_cache_.end(),
- bibfiles.begin(),
- bibfiles.end());
- }
- }
+ for (auto const & tocit : *toc) {
+ if (tocit.depth() == 0)
+ list.push_back(tocit.str());
}
- d->bibfile_cache_valid_ = true;
- d->bibinfo_cache_valid_ = false;
- d->cite_labels_valid_ = false;
}
{
d->bibinfo_cache_valid_ = false;
d->cite_labels_valid_ = false;
+ removeBiblioTempFiles();
// also invalidate the cache for the parent buffer
Buffer const * const pbuf = d->parent();
if (pbuf)
}
-void Buffer::invalidateBibfileCache() const
-{
- d->bibfile_cache_valid_ = false;
- d->bibinfo_cache_valid_ = false;
- d->cite_labels_valid_ = false;
- // also invalidate the cache for the parent buffer
- Buffer const * const pbuf = d->parent();
- if (pbuf)
- pbuf->invalidateBibfileCache();
-}
-
-
-support::FileNamePairList const & Buffer::getBibfilesCache(UpdateScope scope) const
+FileNamePairList const & Buffer::getBibfiles(UpdateScope scope) const
{
// FIXME This is probably unnecessary, given where we call this.
- // If this is a child document, use the master's cache instead.
+ // If this is a child document, use the master instead.
Buffer const * const pbuf = masterBuffer();
if (pbuf != this && scope != UpdateChildOnly)
- return pbuf->getBibfilesCache();
-
- if (!d->bibfile_cache_valid_)
- this->updateBibfilesCache(scope);
-
+ return pbuf->getBibfiles();
return d->bibfiles_cache_;
}
}
+void Buffer::registerBibfiles(FileNamePairList const & bf) const {
+ Buffer const * const tmp = masterBuffer();
+ if (tmp != this)
+ return tmp->registerBibfiles(bf);
+
+ for (auto const & p : bf) {
+ FileNamePairList::const_iterator temp =
+ find(d->bibfiles_cache_.begin(), d->bibfiles_cache_.end(), p);
+ if (temp == d->bibfiles_cache_.end())
+ d->bibfiles_cache_.push_back(p);
+ }
+}
+
+
void Buffer::checkIfBibInfoCacheIsValid() const
{
// use the master's cache
return;
}
+ // if we already know the cache is invalid, no need to check
+ // the timestamps
+ if (!d->bibinfo_cache_valid_)
+ return;
+
// compare the cached timestamps with the actual ones.
- FileNamePairList const & bibfiles_cache = getBibfilesCache();
+ FileNamePairList const & bibfiles_cache = getBibfiles();
FileNamePairList::const_iterator ei = bibfiles_cache.begin();
FileNamePairList::const_iterator en = bibfiles_cache.end();
for (; ei != en; ++ ei) {
return;
d->bibinfo_.clear();
- collectBibKeys();
+ FileNameList checkedFiles;
+ collectBibKeys(checkedFiles);
d->bibinfo_cache_valid_ = true;
}
-void Buffer::collectBibKeys() const
+void Buffer::collectBibKeys(FileNameList & checkedFiles) const
{
for (InsetIterator it = inset_iterator_begin(inset()); it; ++it)
- it->collectBibKeys(it);
+ it->collectBibKeys(it, checkedFiles);
}
switch (cmd.action()) {
case LFUN_BUFFER_TOGGLE_READ_ONLY:
- flag.setOnOff(isReadonly());
+ flag.setOnOff(hasReadonlyFlag());
break;
// FIXME: There is need for a command-line import.
string const argument = to_utf8(func.argument());
// We'll set this back to false if need be.
bool dispatched = true;
- undo().beginUndoGroup();
+ // This handles undo groups automagically
+ UndoGroupHelper ugh(this);
switch (func.action()) {
case LFUN_BUFFER_TOGGLE_READ_ONLY:
dr.setMessage(log);
}
else
- setReadonly(!isReadonly());
+ setReadonly(!hasReadonlyFlag());
break;
case LFUN_BUFFER_EXPORT: {
case LFUN_BUFFER_EXPORT_CUSTOM: {
string format_name;
string command = split(argument, format_name, ' ');
- Format const * format = formats.getFormat(format_name);
+ Format const * format = theFormats().getFormat(format_name);
if (!format) {
lyxerr << "Format \"" << format_name
<< "\" not recognized!"
}
case LFUN_BRANCH_ADD: {
- docstring branch_name = func.argument();
- if (branch_name.empty()) {
+ docstring branchnames = func.argument();
+ if (branchnames.empty()) {
dispatched = false;
break;
}
BranchList & branch_list = params().branchlist();
vector<docstring> const branches =
- getVectorFromString(branch_name, branch_list.separator());
+ getVectorFromString(branchnames, branch_list.separator());
docstring msg;
- for (vector<docstring>::const_iterator it = branches.begin();
- it != branches.end(); ++it) {
- branch_name = *it;
+ for (docstring const & branch_name : branches) {
Branch * branch = branch_list.find(branch_name);
if (branch) {
LYXERR0("Branch " << branch_name << " already exists.");
}
case LFUN_BUFFER_VIEW_CACHE:
- if (!formats.view(*this, d->preview_file_,
+ if (!theFormats().view(*this, d->preview_file_,
d->preview_format_))
dr.setMessage(_("Error viewing the output file."));
break;
break;
}
dr.dispatched(dispatched);
- undo().endUndoGroup();
}
std::set<Language const *> Buffer::getLanguages() const
{
- std::set<Language const *> languages;
- getLanguages(languages);
- return languages;
+ std::set<Language const *> langs;
+ getLanguages(langs);
+ return langs;
}
-void Buffer::getLanguages(std::set<Language const *> & languages) const
+void Buffer::getLanguages(std::set<Language const *> & langs) const
{
ParConstIterator end = par_iterator_end();
// add the buffer language, even if it's not actively used
- languages.insert(language());
+ langs.insert(language());
// iterate over the paragraphs
for (ParConstIterator it = par_iterator_begin(); it != end; ++it)
- it->getLanguages(languages);
+ it->getLanguages(langs);
// also children
ListOfBuffers clist = getDescendents();
- ListOfBuffers::const_iterator cit = clist.begin();
- ListOfBuffers::const_iterator const cen = clist.end();
- for (; cit != cen; ++cit)
- (*cit)->getLanguages(languages);
+ for (auto const & cit : clist)
+ cit->getLanguages(langs);
}
void Buffer::saveCheckSum() const
{
FileName const & file = d->filename;
-
file.refresh();
- if (file.exists()) {
- d->timestamp_ = file.lastModified();
- d->checksum_ = file.checksum();
- } else {
- // in the case of save to a new file.
- d->timestamp_ = 0;
- d->checksum_ = 0;
- }
+ d->checksum_ = file.exists() ? file.checksum()
+ : 0; // in the case of save to a new file.
}
}
d->bak_clean = false;
- DepClean::iterator it = d->dep_clean.begin();
- DepClean::const_iterator const end = d->dep_clean.end();
-
- for (; it != end; ++it)
- it->second = false;
+ for (auto & depit : d->dep_clean)
+ depit.second = false;
}
// check for spaces in paths
bool found_space = false;
- FileNamePairList::const_iterator it = bibfilelist.begin();
- FileNamePairList::const_iterator en = bibfilelist.end();
- for (; it != en; ++it) {
- string utf8input = to_utf8(it->first);
+ for (auto const & bit : bibfilelist) {
+ string utf8input = to_utf8(bit.first);
string database =
prepareFileNameForLaTeX(utf8input, ".bib", runparams.nice);
FileName const try_in_file =
}
-bool Buffer::isReadonly() const
+bool Buffer::hasReadonlyFlag() const
{
return d->read_only;
}
+bool Buffer::isReadonly() const
+{
+ return hasReadonlyFlag() || notifiesExternalModification();
+}
+
+
void Buffer::setParent(Buffer const * buffer)
{
// Avoids recursive include.
void Buffer::collectChildren(ListOfBuffers & clist, bool grand_children) const
{
// loop over children
- Impl::BufferPositionMap::iterator it = d->children_positions.begin();
- Impl::BufferPositionMap::iterator end = d->children_positions.end();
- for (; it != end; ++it) {
- Buffer * child = const_cast<Buffer *>(it->first);
+ for (auto const & p : d->children_positions) {
+ Buffer * child = const_cast<Buffer *>(p.first);
// No duplicates
ListOfBuffers::const_iterator bit = find(clist.begin(), clist.end(), child);
if (bit != clist.end())
while (it.pit() <= lastpit) {
Paragraph & par = it.paragraph();
+ // FIXME Can this be done with the new-style iterators?
// iterate over the insets of the current paragraph
- InsetList const & insets = par.insetList();
- InsetList::const_iterator iit = insets.begin();
- InsetList::const_iterator end = insets.end();
- for (; iit != end; ++iit) {
- it.pos() = iit->pos;
+ for (auto const & insit : par.insetList()) {
+ it.pos() = insit.pos;
// is it a nested text inset?
- if (iit->inset->asInsetText()) {
+ if (insit.inset->asInsetText()) {
// Inset needs its own scope?
- InsetText const * itext = iit->inset->asInsetText();
+ InsetText const * itext = insit.inset->asInsetText();
bool newScope = itext->isMacroScope();
// scope which ends just behind the inset
++insetScope.pos();
// collect macros in inset
- it.push_back(CursorSlice(*iit->inset));
+ it.push_back(CursorSlice(*insit.inset));
updateMacros(it, newScope ? insetScope : scope);
it.pop_back();
continue;
}
- if (iit->inset->asInsetTabular()) {
- CursorSlice slice(*iit->inset);
+ if (insit.inset->asInsetTabular()) {
+ CursorSlice slice(*insit.inset);
size_t const numcells = slice.nargs();
for (; slice.idx() < numcells; slice.forwardIdx()) {
it.push_back(slice);
}
// is it an external file?
- if (iit->inset->lyxCode() == INCLUDE_CODE) {
+ if (insit.inset->lyxCode() == INCLUDE_CODE) {
// get buffer of external file
- InsetInclude const & inset =
- static_cast<InsetInclude const &>(*iit->inset);
+ InsetInclude const & incinset =
+ static_cast<InsetInclude const &>(*insit.inset);
macro_lock = true;
- Buffer * child = inset.getChildBuffer();
+ Buffer * child = incinset.getChildBuffer();
macro_lock = false;
if (!child)
continue;
continue;
}
- InsetMath * im = iit->inset->asInsetMath();
+ InsetMath * im = insit.inset->asInsetMath();
if (doing_export && im) {
InsetMathHull * hull = im->asHullInset();
if (hull)
hull->recordLocation(it);
}
- if (iit->inset->lyxCode() != MATHMACRO_CODE)
+ if (insit.inset->lyxCode() != MATHMACRO_CODE)
continue;
// get macro data
- MathMacroTemplate & macroTemplate =
- *iit->inset->asInsetMath()->asMacroTemplate();
+ InsetMathMacroTemplate & macroTemplate =
+ *insit.inset->asInsetMath()->asMacroTemplate();
MacroContext mc(owner_, it);
macroTemplate.updateToContext(mc);
d->macro_lock = true;
// loop over macro names
- Impl::NamePositionScopeMacroMap::iterator nameIt = d->macros.begin();
- Impl::NamePositionScopeMacroMap::iterator nameEnd = d->macros.end();
- for (; nameIt != nameEnd; ++nameIt)
- macros.insert(nameIt->first);
+ for (auto const & nameit : d->macros)
+ macros.insert(nameit.first);
// loop over children
- Impl::BufferPositionMap::iterator it = d->children_positions.begin();
- Impl::BufferPositionMap::iterator end = d->children_positions.end();
- for (; it != end; ++it)
- it->first->listMacroNames(macros);
+ for (auto const & p : d->children_positions) {
+ Buffer * child = const_cast<Buffer *>(p.first);
+ // The buffer might have been closed (see #10766).
+ if (theBufferList().isLoaded(child))
+ child->listMacroNames(macros);
+ }
// call parent
Buffer const * const pbuf = d->parent();
pbuf->listMacroNames(names);
// resolve macros
- MacroNameSet::iterator it = names.begin();
- MacroNameSet::iterator end = names.end();
- for (; it != end; ++it) {
+ for (auto const & mit : names) {
// defined?
- MacroData const * data =
- pbuf->getMacro(*it, *this, false);
+ MacroData const * data = pbuf->getMacro(mit, *this, false);
if (data) {
macros.insert(data);
- // we cannot access the original MathMacroTemplate anymore
+ // we cannot access the original InsetMathMacroTemplate anymore
// here to calls validate method. So we do its work here manually.
// FIXME: somehow make the template accessible here.
if (data->optionals() > 0)
reloadBibInfoCache();
// Check if the label 'from' appears more than once
- BiblioInfo const & keys = masterBibInfo();
- BiblioInfo::const_iterator bit = keys.begin();
- BiblioInfo::const_iterator bend = keys.end();
vector<docstring> labels;
-
- for (; bit != bend; ++bit)
- // FIXME UNICODE
- labels.push_back(bit->first);
+ for (auto const & bibit : masterBibInfo())
+ labels.push_back(bibit.first);
if (count(labels.begin(), labels.end(), from) > 1)
return;
string const paramName = "key";
- for (InsetIterator it = inset_iterator_begin(inset()); it; ++it) {
+ InsetIterator it = inset_iterator_begin(inset());
+ for (; it; ++it) {
if (it->lyxCode() != CITE_CODE)
continue;
InsetCommand * inset = it->asInsetCommand();
ots.texrow().newlines(2);
if (master)
runparams.is_child = true;
+ updateBuffer();
writeLaTeXSource(ots, string(), runparams, output);
texrow = ots.releaseTexRow();
}
return pid;
}
-} // namespace anon
+} // namespace
FileName Buffer::getEmergencyFileName() const
}
-void Buffer::moveAutosaveFile(support::FileName const & oldauto) const
+void Buffer::moveAutosaveFile(FileName const & oldauto) const
{
FileName const newauto = getAutosaveFileName();
oldauto.refresh();
bool Buffer::autoSave() const
{
Buffer const * buf = d->cloned_buffer_ ? d->cloned_buffer_ : this;
- if (buf->d->bak_clean || isReadonly())
+ if (buf->d->bak_clean || hasReadonlyFlag())
return true;
message(_("Autosaving current document..."));
{
d->doing_export = e;
ListOfBuffers clist = getDescendents();
- ListOfBuffers::const_iterator cit = clist.begin();
- ListOfBuffers::const_iterator const cen = clist.end();
- for (; cit != cen; ++cit)
- (*cit)->d->doing_export = e;
+ for (auto const & bit : clist)
+ bit->d->doing_export = e;
}
// Get shortest path to format
converters.buildGraph();
Graph::EdgePath path;
- for (vector<string>::const_iterator it = backs.begin();
- it != backs.end(); ++it) {
- Graph::EdgePath p = converters.getPath(*it, format);
+ for (string const & sit : backs) {
+ Graph::EdgePath p = converters.getPath(sit, format);
if (!p.empty() && (path.empty() || p.size() < path.size())) {
- backend_format = *it;
+ backend_format = sit;
path = p;
}
}
// file (not for previewing).
Alert::error(_("Couldn't export file"), bformat(
_("No information for exporting the format %1$s."),
- formats.prettyName(format)));
+ theFormats().prettyName(format)));
}
return ExportNoPathToFormat;
}
runparams.flavor = converters.getFlavor(path, this);
- Graph::EdgePath::const_iterator it = path.begin();
- Graph::EdgePath::const_iterator en = path.end();
- for (; it != en; ++it)
- if (theConverters().get(*it).nice()) {
+ for (auto const & edge : path)
+ if (theConverters().get(edge).nice()) {
need_nice_file = true;
break;
}
string filename = latexName(false);
filename = addName(temppath(), filename);
filename = changeExtension(filename,
- formats.extension(backend_format));
+ theFormats().extension(backend_format));
LYXERR(Debug::FILES, "filename=" << filename);
// Plain text backend
string const error_type = (format == "program")
? "Build" : params().bufferFormat();
ErrorList & error_list = d->errorLists[error_type];
- string const ext = formats.extension(format);
+ string const ext = theFormats().extension(format);
FileName const tmp_result_file(changeExtension(filename, ext));
bool const success = converters.convert(this, FileName(filename),
tmp_result_file, FileName(absFileName()), backend_format, format,
errors(error_type);
// also to the children, in case of master-buffer-view
ListOfBuffers clist = getDescendents();
- ListOfBuffers::const_iterator cit = clist.begin();
- ListOfBuffers::const_iterator const cen = clist.end();
- for (; cit != cen; ++cit) {
+ for (auto const & bit : clist) {
if (runparams.silent)
- (*cit)->d->errorLists[error_type].clear();
+ bit->d->errorLists[error_type].clear();
else if (d->cloned_buffer_) {
// Enable reverse search by copying back the
// texrow object to the cloned buffer.
// FIXME: this is not thread safe.
- (*cit)->d->cloned_buffer_->d->texrow = (*cit)->d->texrow;
- (*cit)->d->cloned_buffer_->d->errorLists[error_type] =
- (*cit)->d->errorLists[error_type];
+ bit->d->cloned_buffer_->d->texrow = bit->d->texrow;
+ bit->d->cloned_buffer_->d->errorLists[error_type] =
+ bit->d->errorLists[error_type];
} else
- (*cit)->errors(error_type, true);
+ bit->errors(error_type, true);
}
}
// FIXME: There is a possibility of concurrent access to texrow
// here from the main GUI thread that should be securized.
d->cloned_buffer_->d->texrow = d->texrow;
- string const error_type = params().bufferFormat();
- d->cloned_buffer_->d->errorLists[error_type] = d->errorLists[error_type];
+ string const err_type = params().bufferFormat();
+ d->cloned_buffer_->d->errorLists[error_type] = d->errorLists[err_type];
}
: force_overwrite == ALL_FILES;
CopyStatus status = use_force ? FORCE : SUCCESS;
- vector<ExportedFile>::const_iterator it = files.begin();
- vector<ExportedFile>::const_iterator const en = files.end();
- for (; it != en && status != CANCEL; ++it) {
- string const fmt = formats.getFormatFromFile(it->sourceName);
- string fixedName = it->exportName;
+ for (ExportedFile const & exp : files) {
+ if (status == CANCEL) {
+ message(_("Document export cancelled."));
+ return ExportCancel;
+ }
+ string const fmt = theFormats().getFormatFromFile(exp.sourceName);
+ string fixedName = exp.exportName;
if (!runparams.export_folder.empty()) {
// Relative pathnames starting with ../ will be sanitized
// if exporting to a different folder
}
FileName fixedFileName = makeAbsPath(fixedName, dest);
fixedFileName.onlyPath().createPath();
- status = copyFile(fmt, it->sourceName,
+ status = copyFile(fmt, exp.sourceName,
fixedFileName,
- it->exportName, status == FORCE,
+ exp.exportName, status == FORCE,
runparams.export_folder.empty());
}
- if (status == CANCEL) {
- message(_("Document export cancelled."));
- return ExportCancel;
- }
if (tmp_result_file.exists()) {
// Finally copy the main file
} else {
message(bformat(_("Document exported as %1$s "
"to file `%2$s'"),
- formats.prettyName(format),
+ theFormats().prettyName(format),
makeDisplayPath(result_file)));
}
} else {
// This must be a dummy converter like fax (bug 1888)
message(bformat(_("Document exported as %1$s"),
- formats.prettyName(format)));
+ theFormats().prettyName(format)));
}
return success ? ExportSuccess : ExportConverterError;
return status;
if (previewFile.exists())
- return formats.view(*this, previewFile, format) ?
+ return theFormats().view(*this, previewFile, format) ?
PreviewSuccess : PreviewError;
// Successful export but no output file?
ReadStatus const ret_llf = loadThisLyXFile(emergencyFile);
bool const success = (ret_llf == ReadSuccess);
if (success) {
- if (isReadonly()) {
+ if (hasReadonlyFlag()) {
Alert::warning(_("File is read-only"),
bformat(_("An emergency file is successfully loaded, "
"but the original file %1$s is marked read-only. "
ReadStatus const ret_llf = loadThisLyXFile(autosaveFile);
// the file is not saved if we load the autosave file.
if (ret_llf == ReadSuccess) {
- if (isReadonly()) {
+ if (hasReadonlyFlag()) {
Alert::warning(_("File is read-only"),
bformat(_("A backup file is successfully loaded, "
"but the original file %1$s is marked read-only. "
}
-void Buffer::setBuffersForInsets() const
-{
- inset().setBuffer(const_cast<Buffer &>(*this));
-}
-
-
void Buffer::updateBuffer(UpdateScope scope, UpdateType utype) const
{
LBUFERR(!text().paragraphs().empty());
Buffer const * const master = masterBuffer();
DocumentClass const & textclass = master->params().documentClass();
+ FileNamePairList old_bibfiles;
// do this only if we are the top-level Buffer
if (master == this) {
textclass.counters().reset(from_ascii("bibitem"));
reloadBibInfoCache();
+ // we will re-read this cache as we go through, but we need
+ // to know whether it's changed to know whether we need to
+ // update the bibinfo cache.
+ old_bibfiles = d->bibfiles_cache_;
+ d->bibfiles_cache_.clear();
}
// keep the buffers to be children in this set. If the call from the
// not updated during the updateBuffer call and TocModel::toc_ is invalid
// (bug 5699). The same happens if the master buffer is open in a different
// window. This test catches both possibilities.
- // See: http://marc.info/?l=lyx-devel&m=138590578911716&w=2
+ // See: https://marc.info/?l=lyx-devel&m=138590578911716&w=2
// There remains a problem here: If there is another child open in yet a third
// window, that TOC is not updated. So some more general solution is needed at
// some point.
ParIterator parit = cbuf.par_iterator_begin();
updateBuffer(parit, utype);
- /// FIXME: Perf
- /// Update the tocBackend for any buffer. The outliner uses the master's,
- /// and the navigation menu uses the child's.
- cbuf.tocBackend().update(true, utype);
-
+ // If this document has siblings, then update the TocBackend later. The
+ // reason is to ensure that later siblings are up to date when e.g. the
+ // broken or not status of references is computed. The update is called
+ // in InsetInclude::addToToc.
if (master != this)
return;
- d->bibinfo_cache_valid_ = true;
+ // if the bibfiles changed, the cache of bibinfo is invalid
+ sort(d->bibfiles_cache_.begin(), d->bibfiles_cache_.end());
+ // the old one should already be sorted
+ if (old_bibfiles != d->bibfiles_cache_) {
+ invalidateBibinfoCache();
+ reloadBibInfoCache();
+ // We relied upon the bibinfo cache when recalculating labels. But that
+ // cache was invalid, although we didn't find that out until now. So we
+ // have to do it all again.
+ // That said, the only thing we really need to do is update the citation
+ // labels. Nothing else will have changed. So we could create a new
+ // UpdateType that would signal that fact, if we needed to do so.
+ parit = cbuf.par_iterator_begin();
+ updateBuffer(parit, utype);
+ }
+ else
+ d->bibinfo_cache_valid_ = true;
d->cite_labels_valid_ = true;
+ /// FIXME: Perf
+ cbuf.tocBackend().update(true, utype);
if (scope == UpdateMaster)
cbuf.structureChanged();
}
switch (par.itemdepth) {
case 2:
enumcounter += 'i';
+ // fall through
case 1:
enumcounter += 'i';
+ // fall through
case 0:
enumcounter += 'i';
break;
break;
}
- // Increase the master counter?
- if (layout.stepmastercounter && needEnumCounterReset(it))
- counters.stepMaster(enumcounter, utype);
-
- // Maybe we have to reset the enumeration counter.
- if (!layout.resumecounter && needEnumCounterReset(it))
- counters.reset(enumcounter);
+ if (needEnumCounterReset(it)) {
+ // Increase the master counter?
+ if (layout.stepmastercounter)
+ counters.stepMaster(enumcounter, utype);
+ // Maybe we have to reset the enumeration counter.
+ if (!layout.resumecounter)
+ counters.reset(enumcounter);
+ }
counters.step(enumcounter, utype);
string const & lang = par.getParLanguage(bp)->code();
* non-const. This would however be costly in
* terms of code duplication.
*/
- const_cast<Buffer *>(this)->undo().recordUndo(CursorData(parit));
+ CursorData(parit).recordUndo();
parit->params().depth(maxdepth);
}
maxdepth = parit->getMaxDepthAfter();
// set the counter for this paragraph
d->setLabel(parit, utype);
- // update change-tracking flag
+ // update change-tracking flag
parit->addChangesToBuffer(*this);
// now the insets
- InsetList::const_iterator iit = parit->insetList().begin();
- InsetList::const_iterator end = parit->insetList().end();
- for (; iit != end; ++iit) {
- parit.pos() = iit->pos;
- iit->inset->updateBuffer(parit, utype);
+ for (auto const & insit : parit->insetList()) {
+ parit.pos() = insit.pos;
+ insit.inset->updateBuffer(parit, utype);
}
}
}
Buffer::ReadStatus Buffer::reload()
{
setBusy(true);
- // c.f. bug http://www.lyx.org/trac/ticket/6587
+ // c.f. bug https://www.lyx.org/trac/ticket/6587
removeAutosaveFile();
// e.g., read-only status could have changed due to version control
d->filename.refresh();
void Buffer::checkChildBuffers()
{
- Impl::BufferPositionMap::iterator it = d->children_positions.begin();
- Impl::BufferPositionMap::iterator const en = d->children_positions.end();
- for (; it != en; ++it) {
- DocIterator dit = it->second;
- Buffer * cbuf = const_cast<Buffer *>(it->first);
+ for (auto const & bit : d->children_positions) {
+ DocIterator dit = bit.second;
+ Buffer * cbuf = const_cast<Buffer *>(bit.first);
if (!cbuf || !theBufferList().isLoaded(cbuf))
continue;
Inset * inset = dit.nextInset();
void Buffer::Impl::refreshFileMonitor()
{
- if (file_monitor_ && file_monitor_->filename() == filename.absFileName())
- return file_monitor_->refresh();
+ if (file_monitor_ && file_monitor_->filename() == filename.absFileName()) {
+ file_monitor_->refresh();
+ return;
+ }
// The previous file monitor is invalid
// This also destroys the previous file monitor and all its connections
file_monitor_ = FileSystemWatcher::monitor(filename);
- fileExternallyModified(false);
// file_monitor_ will be destroyed with *this, so it is not going to call a
// destroyed object method.
- file_monitor_->connect([this](){ fileExternallyModified(true); });
+ file_monitor_->connect([this](bool exists) {
+ fileExternallyModified(exists);
+ });
}
-void Buffer::Impl::fileExternallyModified(bool modified) const
+void Buffer::Impl::fileExternallyModified(bool const exists)
{
- if (modified)
- lyx_clean = bak_clean = false;
- externally_modified_ = modified;
- if (wa_)
+ // ignore notifications after our own saving operations
+ if (checksum_ == filename.checksum()) {
+ LYXERR(Debug::FILES, "External modification but "
+ "checksum unchanged: " << filename);
+ return;
+ }
+ lyx_clean = bak_clean = false;
+ // If the file has been deleted, only mark the file as dirty since it is
+ // pointless to prompt for reloading. If later a file is moved into this
+ // location, then the externally modified warning will appear then.
+ if (exists)
+ externally_modified_ = true;
+ // Update external modification notification.
+ // Dirty buffers must be visible at all times.
+ if (wa_ && wa_->unhide(owner_))
wa_->updateTitles();
+ else
+ // Unable to unhide the buffer (e.g. no GUI or not current View)
+ lyx_clean = true;
}
bool Buffer::notifiesExternalModification() const
{
- return d->isExternallyModified();
+ return d->externally_modified_;
}
void Buffer::clearExternalModification() const
{
- d->fileExternallyModified(false);
+ d->externally_modified_ = false;
+ if (d->wa_)
+ d->wa_->updateTitles();
}