X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Fbuffer_funcs.cpp;h=66ba0dc797a6ea75700de8a74735fa8cd9bc9fab;hb=58ab972f714309aa87e7d956ceda00e18337875f;hp=1f1cd7917c1c6c8490b875be1af000d27d1e990f;hpb=47b9d13bb756a63d2933da494c92f59f4d62cdf5;p=lyx.git diff --git a/src/buffer_funcs.cpp b/src/buffer_funcs.cpp index 1f1cd7917c..66ba0dc797 100644 --- a/src/buffer_funcs.cpp +++ b/src/buffer_funcs.cpp @@ -16,15 +16,21 @@ #include "Buffer.h" #include "BufferList.h" #include "BufferParams.h" +#include "debug.h" #include "DocIterator.h" #include "Counters.h" #include "ErrorList.h" #include "Floating.h" #include "FloatList.h" #include "gettext.h" +#include "InsetIterator.h" #include "Language.h" #include "LaTeX.h" +#include "Layout.h" +#include "LyX.h" +#include "lyxlayout_ptr_fwd.h" #include "TextClass.h" +#include "TextClassList.h" #include "Paragraph.h" #include "paragraph_funcs.h" #include "ParagraphList.h" @@ -32,15 +38,14 @@ #include "ParIterator.h" #include "LyXVC.h" #include "TexRow.h" +#include "Text.h" #include "TocBackend.h" #include "VCBackend.h" #include "frontends/alert.h" #include "insets/InsetBibitem.h" -#include "insets/InsetCaption.h" #include "insets/InsetInclude.h" -#include "insets/InsetTabular.h" #include "support/filetools.h" #include "support/fs_extras.h" @@ -343,7 +348,7 @@ depth_type getDepth(DocIterator const & it) depth_type getItemDepth(ParIterator const & it) { Paragraph const & par = *it; - LYX_LABEL_TYPES const labeltype = par.layout()->labeltype; + LabelType const labeltype = par.layout()->labeltype; if (labeltype != LABEL_ENUMERATE && labeltype != LABEL_ITEMIZE) return 0; @@ -402,85 +407,12 @@ bool needEnumCounterReset(ParIterator const & it) } -void setCaptionLabels(Inset & inset, string const & type, - docstring const label, Counters & counters) -{ - Text * text = inset.getText(0); - if (!text) - return; - - ParagraphList & pars = text->paragraphs(); - if (pars.empty()) - return; - - docstring const counter = from_ascii(type); - - ParagraphList::iterator p = pars.begin(); - for (; p != pars.end(); ++p) { - InsetList::iterator it2 = p->insetlist.begin(); - InsetList::iterator end2 = p->insetlist.end(); - // Any caption within this float should have the same - // label prefix but different numbers. - for (; it2 != end2; ++it2) { - Inset & icap = *it2->inset; - // Look deeper just in case. - setCaptionLabels(icap, type, label, counters); - if (icap.lyxCode() == Inset::CAPTION_CODE) { - // We found a caption! - counters.step(counter); - int number = counters.value(counter); - InsetCaption & ic = static_cast(icap); - ic.setType(type); - ic.setCount(number); - ic.setCustomLabel(label); - } - } - } -} - - -void setCaptions(Paragraph & par, TextClass const & textclass) -{ - if (par.insetlist.empty()) - return; - - Counters & counters = textclass.counters(); - - InsetList::iterator it = par.insetlist.begin(); - InsetList::iterator end = par.insetlist.end(); - for (; it != end; ++it) { - Inset & inset = *it->inset; - if (inset.lyxCode() == Inset::FLOAT_CODE - || inset.lyxCode() == Inset::WRAP_CODE) { - docstring const name = inset.name(); - if (name.empty()) - continue; - - Floating const & fl = textclass.floats().getType(to_ascii(name)); - // FIXME UNICODE - string const & type = fl.type(); - docstring const label = from_utf8(fl.name()); - setCaptionLabels(inset, type, label, counters); - } - else if (inset.lyxCode() == Inset::TABULAR_CODE - && static_cast(inset).tabular.isLongTabular()) { - // FIXME: are "table" and "Table" the correct type and label? - setCaptionLabels(inset, "table", from_ascii("Table"), counters); - } - else if (inset.lyxCode() == Inset::LISTINGS_CODE) - setCaptionLabels(inset, "listing", from_ascii("Listing"), counters); - else if (inset.lyxCode() == Inset::INCLUDE_CODE) - // if this include inset contains lstinputlisting, and has a caption - // it will increase the 'listing' counter by one - static_cast(inset).updateCounter(counters); - } -} - // set the label of a paragraph. This includes the counters. -void setLabel(Buffer const & buf, ParIterator & it, TextClass const & textclass) +void setLabel(Buffer const & buf, ParIterator & it) { - Paragraph & par = *it; - Layout_ptr const & layout = par.layout(); + TextClass const & textclass = buf.params().getTextClass(); + Paragraph & par = it.paragraph(); + LayoutPtr const & layout = par.layout(); Counters & counters = textclass.counters(); if (par.params().startOfAppendix()) { @@ -501,13 +433,8 @@ void setLabel(Buffer const & buf, ParIterator & it, TextClass const & textclass) par.params().labelWidthString(docstring()); } - // Optimisation: setLabel() can be called for each for each - // paragraph of the document. So we make the string static to - // avoid the repeated instanciation. - static docstring itemlabel; - - // is it a layout that has an automatic label? - if (layout->labeltype == LABEL_COUNTER) { + switch(layout->labeltype) { + case LABEL_COUNTER: if (layout->toclevel <= buf.params().secnumdepth && (layout->latextype != LATEX_ENVIRONMENT || isFirstInSequence(it.pit(), it.plist()))) { @@ -516,13 +443,15 @@ void setLabel(Buffer const & buf, ParIterator & it, TextClass const & textclass) par.expandLabel(layout, buf.params())); } else par.params().labelString(docstring()); + break; - } else if (layout->labeltype == LABEL_ITEMIZE) { + case LABEL_ITEMIZE: { // At some point of time we should do something more // clever here, like: // par.params().labelString( // buf.params().user_defined_bullet(par.itemdepth).getText()); // for now, use a simple hardcoded label + docstring itemlabel; switch (par.itemdepth) { case 0: itemlabel = char_type(0x2022); @@ -538,10 +467,11 @@ void setLabel(Buffer const & buf, ParIterator & it, TextClass const & textclass) break; } par.params().labelString(itemlabel); + break; + } - } else if (layout->labeltype == LABEL_ENUMERATE) { - // FIXME - // Yes I know this is a really, really! bad solution + case LABEL_ENUMERATE: { + // FIXME: Yes I know this is a really, really! bad solution // (Lgb) docstring enumcounter = from_ascii("enum"); @@ -590,61 +520,74 @@ void setLabel(Buffer const & buf, ParIterator & it, TextClass const & textclass) par.params().labelString(counters.counterLabel( par.translateIfPossible(from_ascii(format), buf.params()))); - } else if (layout->labeltype == LABEL_BIBLIO) {// ale970302 - counters.step(from_ascii("bibitem")); - int number = counters.value(from_ascii("bibitem")); - if (par.bibitem()) - par.bibitem()->setCounter(number); + break; + } - par.params().labelString( - par.translateIfPossible(layout->labelstring(), buf.params())); - // In biblio shouldn't be following counters but... - } else if (layout->labeltype == LABEL_SENSITIVE) { - // Search for the first float or wrap inset in the iterator - size_t i = it.depth(); - Inset * in = 0; - while (i > 0) { - --i; - Inset::Code const code = it[i].inset().lyxCode(); - if (code == Inset::FLOAT_CODE || - code == Inset::WRAP_CODE) { - in = &it[i].inset(); - break; - } - } - // FIXME Can Inset::name() return an empty name for wide or - // float insets? If not we can put the definition of type - // inside the if (in) clause and use that instead of - // if (!type.empty()). - docstring type; - if (in) - type = in->name(); - - if (!type.empty()) { - Floating const & fl = textclass.floats().getType(to_ascii(type)); - // FIXME UNICODE - counters.step(from_ascii(fl.type())); - - // Doesn't work... yet. - par.params().labelString(par.translateIfPossible( - bformat(from_ascii("%1$s #:"), from_utf8(fl.name())), - buf.params())); - } else { - // par->SetLayout(0); - par.params().labelString(par.translateIfPossible( - layout->labelstring(), buf.params())); + case LABEL_SENSITIVE: { + string const & type = counters.current_float(); + docstring full_label; + if (type.empty()) + full_label = buf.B_("Senseless!!! "); + else { + docstring name = buf.B_(textclass.floats().getType(type).name()); + if (counters.hasCounter(from_utf8(type))) { + counters.step(from_utf8(type)); + full_label = bformat(from_ascii("%1$s %2$s:"), + name, + counters.theCounter(from_utf8(type))); + } else + full_label = bformat(from_ascii("%1$s #:"), name); } + par.params().labelString(full_label); + break; + } - } else if (layout->labeltype == LABEL_NO_LABEL) + case LABEL_NO_LABEL: par.params().labelString(docstring()); - else + break; + + case LABEL_MANUAL: + case LABEL_TOP_ENVIRONMENT: + case LABEL_CENTERED_TOP_ENVIRONMENT: + case LABEL_STATIC: + case LABEL_BIBLIO: par.params().labelString( - par.translateIfPossible(layout->labelstring(), buf.params())); + par.translateIfPossible(layout->labelstring(), + buf.params())); + break; + } } } // anon namespace +void updateLabels(Buffer const & buf, ParIterator & parit) +{ + BOOST_ASSERT(parit.pit() == 0); + + depth_type maxdepth = 0; + pit_type const lastpit = parit.lastpit(); + for ( ; parit.pit() <= lastpit ; ++parit.pit()) { + // reduce depth if necessary + parit->params().depth(min(parit->params().depth(), maxdepth)); + maxdepth = parit->getMaxDepthAfter(); + + // set the counter for this paragraph + setLabel(buf, parit); + + // 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->updateLabels(buf, parit); + } + } + +} + +// FIXME: buf should should be const because updateLabels() modifies +// the contents of the paragraphs. void updateLabels(Buffer const & buf, bool childonly) { Buffer const * const master = buf.getMasterBuffer(); @@ -662,39 +605,29 @@ void updateLabels(Buffer const & buf, bool childonly) textclass.counters().reset(); } - ParIterator const end = par_iterator_end(buf.inset()); - - for (ParIterator it = par_iterator_begin(buf.inset()); it != end; ++it) { - // reduce depth if necessary - if (it.pit()) { - Paragraph const & prevpar = it.plist()[it.pit() - 1]; - it->params().depth(min(it->params().depth(), - prevpar.getMaxDepthAfter())); - } else - it->params().depth(0); - - // set the counter for this paragraph - setLabel(buf, it, textclass); - - // It is better to set the captions after setLabel because - // the caption number might need the section number in the - // future. - setCaptions(*it, textclass); + Buffer & cbuf = const_cast(buf); - // Now included docs - InsetList::const_iterator iit = it->insetlist.begin(); - InsetList::const_iterator end = it->insetlist.end(); - for (; iit != end; ++iit) { - if (iit->inset->lyxCode() == Inset::INCLUDE_CODE) - static_cast(iit->inset) - ->updateLabels(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; } - Buffer & cbuf = const_cast(buf); + // do the real work + ParIterator parit = par_iterator_begin(buf.inset()); + updateLabels(buf, parit); + cbuf.tocBackend().update(); if (!childonly) cbuf.structureChanged(); + // FIXME + // the embedding signal is emitted with structureChanged signal + // this is inaccurate so these two will be separated later. + //cbuf.embeddedFiles().update(); + //cbuf.embeddingChanged(); } @@ -707,4 +640,33 @@ void checkBufferStructure(Buffer & buffer, ParIterator const & par_it) } } +textclass_type defaultTextclass() +{ + // We want to return the article class. if `first' is + // true in the returned pair, then `second' is the textclass + // number; if it is false, second is 0. In both cases, second + // is what we want. + return textclasslist.numberOfClass("article").second; +} + + +void loadChildDocuments(Buffer const & buf) +{ + bool parse_error = false; + + for (InsetIterator it = inset_iterator_begin(buf.inset()); it; ++it) { + if (it->lyxCode() != Inset::INCLUDE_CODE) + continue; + InsetInclude const & inset = static_cast(*it); + InsetCommandParams const & ip = inset.params(); + Buffer * child = loadIfNeeded(buf, ip); + if (!child) + continue; + parse_error |= !child->errorList("Parse").empty(); + loadChildDocuments(*child); + } + + if (use_gui && buf.getMasterBuffer() == &buf) + updateLabels(buf); +} } // namespace lyx