On 04/22/2011 02:17 PM, Richard Heck wrote:
On 04/22/2011 01:46 PM, Edwin Leuven wrote:
Richard Heck<rgh...@comcast.net>  wrote:
Same crash with a footnote there. So it looks
as if for some reason insets inside cells are not
getting their macro context set properly.
which is done in lines 3453-3473 of insettabular.cpp:


if (tabular.getAlignment(cell) == LYX_ALIGN_DECIMAL) {
    // make a copy which we will split in 2
InsetTableCell head = InsetTableCell(*tabular.cellInset(cell).get());
    head.getText(0)->setMacrocontextPosition(
        tabular.cellInset(cell)->getText(0)->macrocontextPosition());
    head.setBuffer(tabular.buffer());
    // split in 2 and calculate width of each part
    bool hassep = false;
    InsetTableCell tail =
        splitCell(head, tabular.column_info[c].decimal_point, hassep);
    tail.getText(0)->setMacrocontextPosition(
        head.getText(0)->macrocontextPosition());
    tail.setBuffer(head.buffer());
    Dimension dim1;
    head.metrics(m, dim1);
    decimal_hoffset = dim1.width();
    if (hassep) {
        tail.metrics(m, dim1);
        decimal_width = dim1.width();
    }
}

I think I know what's happening here. Suppose I insert a footnote. The trip through the updateBuffer() routine that follows will set the macro context for that inset. But head and tail are COPIES of (part of) that inset, so one of them contains a COPY of that footnote, and its macro context has *not* been set. When we call head.metrics() and tail.metrics(), for the one that contains the footnote, we end up here:

TextMetrics.cpp:383

    DocIterator parPos = text_->macrocontextPosition();

Since text_ here is the text of the COPY footnote, this is unset.

    if (!parPos.empty())
        parPos.pit() = pit;
    else {

So we go to this branch.

        LYXERR(Debug::INFO, "MacroContext not initialised!"
<< " Going through the buffer again and hope"
<< " the context is better then.");
        // FIXME audit updateBuffer calls
        // This should not be here, but it is not clear yet where else it
        // should be.
        bv_->buffer().updateBuffer();

Now the point is that this call does nothing to resolve the situation: The COPY we are in isn't actually in the Buffer, so updateBuffer() never reaches it.

        parPos = text_->macrocontextPosition();

So this is still unset, and....

        LASSERT(!parPos.empty(), /**/);

we assert.

We might somehow need to call updateBuffer() on these new insets.

Richard

Reply via email to