Jean-Marc Lasgouttes a écrit :
"Abdelrazak" == Abdelrazak Younes <[EMAIL PROTECTED]> writes:
Abdelrazak> bool needEnumCounterReset(ParagraphList & pars, size_t const pos)
Abdelrazak> Maybe I am missing something but this is simpler. Please
Abdelrazak> correct me if I am wrong.
I agree that using dociterators all over makes a code a bit longer,
but a big advantage is that we pass just one object to the function
instead of a (ParagraphList,pos) [and of course your pos should be a
pit, so your are preparing us for more confusion]. We have fixed
*many* bugs in the core where people used a parlist index with the
wrong parlist.
IMHO, this is because the code is not object oriented. In this context
docIterator is an advantage.
When/if we move to a truly object oriented way of dealing with insets I
believe that most of the its use will disappear. Beside updating _all_
the counters of the document (including inside insets!) because of one
new paragraph seems wrong to me.
I am not going to fight about keeping this function as
it is, I do not really care. What would be more useful though is to
see a profile so that we see what the problem actually is. Rewriting
everything just in case it helps will not give us the solution.
This is something I don't understand, sorry. IMHO, rewriting is a sane
thing to do in any case if you want more people to understand the code.
There are really too much code of that sort in lyx. Please find attached
a patch that improve the situation dramatically. The LABEL_ENUMERATE
case optimization is not yet enabled but is almost ready. Passing
(Buffer const & buf) is not nice from an OO point of view but this can
be solved later.
I hope I did not waste my time.
Abdel.
Index: buffer_funcs.C
===================================================================
--- buffer_funcs.C (revision 13538)
+++ buffer_funcs.C (working copy)
@@ -329,23 +329,119 @@
}
-bool needEnumCounterReset(ParIterator const & it)
+bool needEnumCounterReset(size_t const pit, ParagraphList const & pars)
{
- Paragraph const & par = *it;
- BOOST_ASSERT(par.layout()->labeltype == LABEL_ENUMERATE);
- lyx::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;
+ // Do we really want this. I would say this is OK to call this function
with
+ // labeltype != LABEL_ENUMERATE
+ BOOST_ASSERT(pars[pit].layout()->labeltype == LABEL_ENUMERATE);
+
+ // start of nested inset: reset
+ if (pit == 0)
+ return true;
+
+ // previous par has a lower deph: reset
+ size_t i = pit - 1;
+ lyx::depth_type const current_depth = pars[pit].getDepth();
+ if (pars[i].getDepth() < current_depth)
+ return true;
+
+ // reset if one of previous pars with same depth is not a
LABEL_ENUMERATE
+ // In principle the case (pars[i].getDepth() < pars[pit].getDepth())
+ // should not occur.
+ for (; i >= 0; --i) {
+ if (pars[i].getDepth() <= current_depth)
+ return pars[i].layout()->labeltype != LABEL_ENUMERATE;
}
- // start of nested inset: reset
- return true;
+
+ // In principle, this is dead code.
+ return false;
}
+void setItemLabel(Paragraph & par)
+{
+ BOOST_ASSERT(par.layout()->labeltype == LABEL_ITEMIZE);
+
+ // At some point of time we should do something more
+ // clever here, like:
+ // par.params().labelString(
+ // bufparams.user_defined_bullet(par.itemdepth).getText());
+ // for now, use a simple hardcoded label
+ string itemlabel;
+ switch (par.itemdepth) {
+ case 0:
+ itemlabel = "*";
+ break;
+ case 1:
+ itemlabel = "-";
+ break;
+ case 2:
+ itemlabel = "@";
+ break;
+ case 3:
+ itemlabel = "·";
+ break;
+ }
+
+ par.params().labelString(itemlabel);
+}
+void setEnumLabel(size_t pit, ParagraphList & pars,
+ Buffer const & buf)
+{
+ Paragraph & par = pars[pit];
+ Counters & counters = buf.params().getLyXTextClass().counters();
+
+ // FIXME
+ // Yes I know this is a really, really! bad solution
+ // (Lgb)
+ string enumcounter = "enum";
+
+ switch (par.itemdepth) {
+ case 2:
+ enumcounter += 'i';
+ case 1:
+ enumcounter += 'i';
+ case 0:
+ enumcounter += 'i';
+ break;
+ case 3:
+ enumcounter += "iv";
+ break;
+ default:
+ // not a valid enumdepth...
+ break;
+ }
+
+ // Maybe we have to reset the enumeration counter.
+ if (needEnumCounterReset(pit, pars))
+ counters.reset(enumcounter);
+
+ counters.step(enumcounter);
+
+ string format;
+
+ switch (par.itemdepth) {
+ case 0:
+ format = N_("\\arabic{enumi}.");
+ break;
+ case 1:
+ format = N_("(\\alph{enumii})");
+ break;
+ case 2:
+ format = N_("\\roman{enumiii}.");
+ break;
+ case 3:
+ format = N_("\\Alph{enumiv}.");
+ break;
+ default:
+ // not a valid enumdepth...
+ break;
+ }
+
+ par.params().labelString(counters.counterLabel(buf.B_(format)));
+}
+
+
// set the counter of a paragraph. This includes the labels
void setCounter(Buffer const & buf, ParIterator & it)
{
@@ -379,6 +475,10 @@
par.setLabelWidthString(string());
}
+ // is it a layout that has no label at all (ex: standard layout)?
+ if (layout->labeltype == LABEL_NO_LABEL)
+ return;
+
// is it a layout that has an automatic label?
if (layout->labeltype == LABEL_COUNTER) {
if (layout->toclevel <= buf.params().secnumdepth
@@ -390,77 +490,13 @@
par.params().labelString(label);
}
} else if (layout->labeltype == LABEL_ITEMIZE) {
- // At some point of time we should do something more
- // clever here, like:
- // par.params().labelString(
- // bufparams.user_defined_bullet(par.itemdepth).getText());
- // for now, use a simple hardcoded label
- string itemlabel;
- switch (par.itemdepth) {
- case 0:
- itemlabel = "*";
- break;
- case 1:
- itemlabel = "-";
- break;
- case 2:
- itemlabel = "@";
- break;
- case 3:
- itemlabel = "·";
- break;
- }
- par.params().labelString(itemlabel);
+ setItemLabel(par);
+
} else if (layout->labeltype == LABEL_ENUMERATE) {
- // FIXME
- // Yes I know this is a really, really! bad solution
- // (Lgb)
- string enumcounter = "enum";
+
+ setEnumLabel(it.pit(), it.plist(), buf);
- switch (par.itemdepth) {
- case 2:
- enumcounter += 'i';
- case 1:
- enumcounter += 'i';
- case 0:
- enumcounter += 'i';
- break;
- case 3:
- enumcounter += "iv";
- break;
- default:
- // not a valid enumdepth...
- break;
- }
-
- // Maybe we have to reset the enumeration counter.
- if (needEnumCounterReset(it))
- counters.reset(enumcounter);
-
- counters.step(enumcounter);
-
- string format;
-
- switch (par.itemdepth) {
- case 0:
- format = N_("\\arabic{enumi}.");
- break;
- case 1:
- format = N_("(\\alph{enumii})");
- break;
- case 2:
- format = N_("\\roman{enumiii}.");
- break;
- case 3:
- format = N_("\\Alph{enumiv}.");
- break;
- default:
- // not a valid enumdepth...
- break;
- }
-
- par.params().labelString(counters.counterLabel(buf.B_(format)));
} else if (layout->labeltype == LABEL_BIBLIO) {// ale970302
counters.step("bibitem");
int number = counters.value("bibitem");
@@ -508,7 +544,9 @@
// start over
buf.params().getLyXTextClass().counters().reset();
- for (ParIterator it = par_iterator_begin(buf.inset()); it; ++it) {
+ ParIterator 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];
@@ -522,7 +560,28 @@
}
}
+bool needUpdateCounters(size_t const pit, ParagraphList & pars,
+ Buffer const & buf)
+{
+ Paragraph & current_par = pars[pit];
+ switch (current_par.layout()->labeltype) {
+ case LABEL_NO_LABEL:
+ return false;
+
+ case LABEL_ITEMIZE:
+ setItemLabel(current_par);
+ return false;
+
+// case LABEL_ENUMERATE:
+// setEnumLabel(pit, pars, buf);
+// return false;
+
+ default:
+ return true;
+ }
+}
+
string expandLabel(Buffer const & buf,
LyXLayout_ptr const & layout, bool appendix)
{
Index: buffer_funcs.h
===================================================================
--- buffer_funcs.h (revision 13538)
+++ buffer_funcs.h (working copy)
@@ -13,6 +13,7 @@
#define BUFFER_FUNCS_H
#include "lyxlayout_ptr_fwd.h"
+#include "ParagraphList_fwd.h"
#include <string>
@@ -48,6 +49,14 @@
std::string expandLabel(Buffer const & buf, LyXLayout_ptr const & layout,
bool appendix);
+/// updates current counter and/or label if possible.
+/**
+\retval true if a full updateCounters is required.
+\retval false if a full updateCounters is required.
+*/
+bool needUpdateCounters(size_t const pit, ParagraphList & pars,
+ Buffer const & buf);
+
/// updates all counters
void updateCounters(Buffer const &);
Index: text.C
===================================================================
--- text.C (revision 13538)
+++ text.C (working copy)
@@ -1087,7 +1087,8 @@
while (!pars_[next_par].empty() && pars_[next_par].isNewline(0))
pars_[next_par].erase(0);
- updateCounters(cur.buffer());
+ if (needUpdateCounters(next_par, pars_, cur.buffer()))
+ updateCounters(cur.buffer());
// Mark "carriage return" as inserted if change tracking:
if (cur.buffer().params().tracking_changes) {