X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Fbuffer_funcs.cpp;h=17aab767c2c91c04b3a86a78533a7c5d97cd87da;hb=cca78e3c8ae27431323746abd64f9d7db017099d;hp=3f031df6be218591a54ca2497ad039525d9e13e4;hpb=b89cc942eb458284f40f4d4e7db58890c3288979;p=lyx.git diff --git a/src/buffer_funcs.cpp b/src/buffer_funcs.cpp index 3f031df6be..17aab767c2 100644 --- a/src/buffer_funcs.cpp +++ b/src/buffer_funcs.cpp @@ -22,14 +22,11 @@ #include "Floating.h" #include "FloatList.h" #include "InsetList.h" -#include "InsetIterator.h" #include "Language.h" #include "LaTeX.h" #include "Layout.h" -#include "LayoutPtr.h" #include "LyX.h" #include "TextClass.h" -#include "TextClassList.h" #include "Paragraph.h" #include "paragraph_funcs.h" #include "ParagraphList.h" @@ -44,12 +41,13 @@ #include "insets/InsetBibitem.h" #include "insets/InsetInclude.h" +#include "support/lassert.h" #include "support/convert.h" #include "support/debug.h" #include "support/filetools.h" #include "support/gettext.h" #include "support/lstrings.h" -#include "support/lyxlib.h" +#include "support/textutils.h" using namespace std; using namespace lyx::support; @@ -62,7 +60,7 @@ namespace Alert = frontend::Alert; Buffer * checkAndLoadLyXFile(FileName const & filename) { // File already open? - Buffer * checkBuffer = theBufferList().getBuffer(filename.absFilename()); + Buffer * checkBuffer = theBufferList().getBuffer(filename); if (checkBuffer) { if (checkBuffer->isClean()) return checkBuffer; @@ -80,8 +78,18 @@ Buffer * checkAndLoadLyXFile(FileName const & filename) return checkAndLoadLyXFile(filename); } - if (filename.isReadableFile()) { + if (filename.exists()) { + if (!filename.isReadableFile()) { + docstring text = bformat(_("The file %1$s exists but is not " + "readable by the current user."), + from_utf8(filename.absFilename())); + Alert::error(_("File not readable!"), text); + return 0; + } Buffer * b = theBufferList().newBuffer(filename.absFilename()); + if (!b) + // Buffer creation is not possible. + return 0; if (!b->loadLyXFile(filename)) { theBufferList().release(b); return 0; @@ -106,7 +114,9 @@ Buffer * newFile(string const & filename, string const & templatename, { // get a free buffer Buffer * b = theBufferList().newBuffer(filename); - BOOST_ASSERT(b); + if (!b) + // Buffer creation is not possible. + return 0; FileName tname; // use defaults.lyx as a default template if it exists. @@ -143,16 +153,15 @@ Buffer * newUnnamedFile(string const & templatename, FileName const & path) { static int newfile_number; - string document_path = path.absFilename(); - string filename = addName(document_path, + FileName filename(path, "newfile" + convert(++newfile_number) + ".lyx"); while (theBufferList().exists(filename) - || FileName(filename).isReadableFile()) { + || filename.isReadableFile()) { ++newfile_number; - filename = addName(document_path, + filename.set(path, "newfile" + convert(newfile_number) + ".lyx"); } - return newFile(filename, templatename, false); + return newFile(filename.absFilename(), templatename, false); } @@ -178,6 +187,36 @@ int countWords(DocIterator const & from, DocIterator const & to) } +int countChars(DocIterator const & from, DocIterator const & to, bool with_blanks) +{ + int chars = 0; + int blanks = 0; + for (DocIterator dit = from ; dit != to ; dit.forwardPos()) { + + if (!dit.inTexted()) continue; + Paragraph const & par = dit.paragraph(); + pos_type const pos = dit.pos(); + + if (pos != dit.lastpos() && !par.isDeleted(pos)) { + if (Inset const * ins = par.getInset(pos)) { + if (ins->isLetter()) + ++chars; + else if (with_blanks && ins->isSpace()) + ++blanks; + } else { + char_type const c = par.getChar(pos); + if (isPrintableNonspace(c)) + ++chars; + else if (isSpace(c) && with_blanks) + ++blanks; + } + } + } + + return chars + blanks; +} + + namespace { depth_type getDepth(DocIterator const & it) @@ -193,7 +232,7 @@ depth_type getDepth(DocIterator const & it) depth_type getItemDepth(ParIterator const & it) { Paragraph const & par = *it; - LabelType const labeltype = par.layout()->labeltype; + LabelType const labeltype = par.layout().labeltype; if (labeltype != LABEL_ENUMERATE && labeltype != LABEL_ITEMIZE) return 0; @@ -217,13 +256,13 @@ depth_type getItemDepth(ParIterator const & it) // that is not more deeply nested. Paragraph & prev_par = *prev_it; depth_type const prev_depth = getDepth(prev_it); - if (labeltype == prev_par.layout()->labeltype) { + if (labeltype == prev_par.layout().labeltype) { if (prev_depth < min_depth) return prev_par.itemdepth + 1; if (prev_depth == min_depth) return prev_par.itemdepth; } - min_depth = std::min(min_depth, prev_depth); + min_depth = min(min_depth, prev_depth); // small optimization: if we are at depth 0, we won't // find anything else if (prev_depth == 0) @@ -235,14 +274,14 @@ depth_type getItemDepth(ParIterator const & it) bool needEnumCounterReset(ParIterator const & it) { Paragraph const & par = *it; - BOOST_ASSERT(par.layout()->labeltype == LABEL_ENUMERATE); + LASSERT(par.layout().labeltype == LABEL_ENUMERATE, /**/); depth_type const cur_depth = par.getDepth(); ParIterator prev_it = it; while (prev_it.pit()) { --prev_it.top().pit(); Paragraph const & prev_par = *prev_it; if (prev_par.getDepth() <= cur_depth) - return prev_par.layout()->labeltype != LABEL_ENUMERATE; + return prev_par.layout().labeltype != LABEL_ENUMERATE; } // start of nested inset: reset return true; @@ -252,9 +291,10 @@ bool needEnumCounterReset(ParIterator const & it) // set the label of a paragraph. This includes the counters. void setLabel(Buffer const & buf, ParIterator & it) { - TextClass const & textclass = buf.params().getTextClass(); + BufferParams const & bp = buf.masterBuffer()->params(); + DocumentClass const & textclass = bp.documentClass(); Paragraph & par = it.paragraph(); - LayoutPtr const & layout = par.layout(); + Layout const & layout = par.layout(); Counters & counters = textclass.counters(); if (par.params().startOfAppendix()) { @@ -268,21 +308,21 @@ void setLabel(Buffer const & buf, ParIterator & it) // Compute the item depth of the paragraph par.itemdepth = getItemDepth(it); - if (layout->margintype == MARGIN_MANUAL) { + if (layout.margintype == MARGIN_MANUAL) { if (par.params().labelWidthString().empty()) - par.params().labelWidthString(par.translateIfPossible(layout->labelstring(), buf.params())); + par.params().labelWidthString(par.translateIfPossible(layout.labelstring(), bp)); } else { par.params().labelWidthString(docstring()); } - switch(layout->labeltype) { + switch(layout.labeltype) { case LABEL_COUNTER: - if (layout->toclevel <= buf.params().secnumdepth - && (layout->latextype != LATEX_ENVIRONMENT + if (layout.toclevel <= bp.secnumdepth + && (layout.latextype != LATEX_ENVIRONMENT || isFirstInSequence(it.pit(), it.plist()))) { - counters.step(layout->counter); + counters.step(layout.counter); par.params().labelString( - par.expandLabel(layout, buf.params())); + par.expandLabel(layout, bp)); } else par.params().labelString(docstring()); break; @@ -291,7 +331,7 @@ void setLabel(Buffer const & buf, ParIterator & it) // At some point of time we should do something more // clever here, like: // par.params().labelString( - // buf.params().user_defined_bullet(par.itemdepth).getText()); + // bp.user_defined_bullet(par.itemdepth).getText()); // for now, use a simple hardcoded label docstring itemlabel; switch (par.itemdepth) { @@ -360,7 +400,7 @@ void setLabel(Buffer const & buf, ParIterator & it) } par.params().labelString(counters.counterLabel( - par.translateIfPossible(from_ascii(format), buf.params()))); + par.translateIfPossible(from_ascii(format), bp))); break; } @@ -394,8 +434,7 @@ void setLabel(Buffer const & buf, ParIterator & it) case LABEL_STATIC: case LABEL_BIBLIO: par.params().labelString( - par.translateIfPossible(layout->labelstring(), - buf.params())); + par.translateIfPossible(layout.labelstring(), bp)); break; } } @@ -404,7 +443,13 @@ void setLabel(Buffer const & buf, ParIterator & it) void updateLabels(Buffer const & buf, ParIterator & parit) { - BOOST_ASSERT(parit.pit() == 0); + LASSERT(parit.pit() == 0, /**/); + + // set the position of the text in the buffer to be able + // to resolve macros in it. This has nothing to do with + // labels, but by putting it here we avoid implementing + // a whole bunch of traversal routines just for this call. + parit.text()->setMacrocontextPosition(parit); depth_type maxdepth = 0; pit_type const lastpit = parit.lastpit(); @@ -421,10 +466,9 @@ void updateLabels(Buffer const & buf, ParIterator & parit) InsetList::const_iterator end = parit->insetList().end(); for (; iit != end; ++iit) { parit.pos() = iit->pos; - iit->inset->updateLabels(buf, parit); + iit->inset->updateLabels(parit); } } - } @@ -434,7 +478,7 @@ void updateLabels(Buffer const & buf, bool childonly) { Buffer const * const master = buf.masterBuffer(); // Use the master text class also for child documents - TextClass const & textclass = master->params().getTextClass(); + DocumentClass const & textclass = master->params().documentClass(); if (!childonly) { // If this is a child document start with the master @@ -445,37 +489,27 @@ void updateLabels(Buffer const & buf, bool childonly) // start over the counters textclass.counters().reset(); + buf.clearReferenceCache(); + buf.inset().setBuffer(const_cast(buf)); + buf.updateMacros(); } Buffer & cbuf = const_cast(buf); - if (buf.text().empty()) { - // FIXME: we don't call continue with updateLabels() - // here because it crashes on newly created documents. - // But the TocBackend needs to be initialised - // nonetheless so we update the tocBackend manually. - cbuf.tocBackend().update(); - return; - } + BOOST_ASSERT(!buf.text().paragraphs().empty()); // do the real work ParIterator parit = par_iterator_begin(buf.inset()); updateLabels(buf, parit); + if (master != &buf) + // TocBackend update will be done later. + return; + cbuf.tocBackend().update(); if (!childonly) cbuf.structureChanged(); } -void checkBufferStructure(Buffer & buffer, ParIterator const & par_it) -{ - if (par_it->layout()->toclevel != Layout::NOT_IN_TOC) { - Buffer const * master = buffer.masterBuffer(); - master->tocBackend().updateItem(par_it); - master->structureChanged(); - } -} - - } // namespace lyx