]> git.lyx.org Git - lyx.git/commitdiff
Fix crash when there are text insets in a table cell with decimal alignment. This...
authorRichard Heck <rgheck@comcast.net>
Mon, 25 Apr 2011 12:56:09 +0000 (12:56 +0000)
committerRichard Heck <rgheck@comcast.net>
Mon, 25 Apr 2011 12:56:09 +0000 (12:56 +0000)
http://marc.info/?t=115869271700002&r=1&w=2&n=5
http://marc.info/?t=130349942500005&r=1&w=2&n=17
This is the simpler and more conservative of the two solutions proposed. It is possible,
however, that we need the more complicated one, which is in x2a.patch here:
http://marc.info/?l=lyx-devel&m=130359169107401&q=p4
Both patches contain work by me and Edwin.

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@38496 a592a061-630c-0410-9148-cb99ea01b6c8

src/insets/InsetTabular.cpp
src/insets/InsetText.cpp
src/insets/InsetText.h

index a899706f380f611719f8b5a62c2a34e62d445656..fe33dbeef013b866feceacfd29467787ee9b5c41 100644 (file)
@@ -2484,14 +2484,17 @@ void Tabular::TeXRow(otexstream & os, row_type row,
                        && cellInfo(cell).decimal_width != 0) {
                        // copy cell and split in 2
                        InsetTableCell head = InsetTableCell(*cellInset(cell).get());
-                       head.getText(0)->setMacrocontextPosition(
-                               cellInset(cell)->getText(0)->macrocontextPosition());
                        head.setBuffer(buffer());
+                       DocIterator dit = cellInset(cell)->getText(0)->macrocontextPosition();
+                       dit.pop_back();
+                       dit.push_back(CursorSlice(head));
+                       head.setMacrocontextPositionRecursive(dit);
                        bool hassep = false;
                        InsetTableCell tail = splitCell(head, column_info[c].decimal_point, hassep);
-                       tail.getText(0)->setMacrocontextPosition(
-                               head.getText(0)->macrocontextPosition());
                        tail.setBuffer(head.buffer());
+                       dit.pop_back();
+                       dit.push_back(CursorSlice(tail));
+                       tail.setMacrocontextPositionRecursive(dit);
                        head.latex(os, newrp);
                        os << '&';
                        tail.latex(os, newrp);
@@ -3465,30 +3468,36 @@ void InsetTabular::metrics(MetricsInfo & mi, Dimension & dim) const
                                mi.base.bv->textMetrics(tabular.cellInset(cell)->getText(0));
 
                        // determine horizontal offset because of decimal align (if necessary)
-                       int decimal_hoffset = 0;
                        int decimal_width = 0;
                        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) {
+                               InsetTableCell tail = InsetTableCell(*tabular.cellInset(cell).get());
+                               tail.setBuffer(tabular.buffer());
+                               // we need to set macrocontext position everywhere
+                               // otherwise we crash with nested insets (e.g. footnotes)
+                               // after decimal point
+                               DocIterator dit = tabular.cellInset(cell)->getText(0)->macrocontextPosition();
+                               dit.pop_back();
+                               dit.push_back(CursorSlice(tail));
+                               tail.setMacrocontextPositionRecursive(dit);
+
+                               // remove text leading decimal point
+                               docstring const align_d = tabular.column_info[c].decimal_point;
+                               dit = doc_iterator_begin(&tail.buffer(), &tail);
+                               for (; dit; dit.forwardChar())
+                                       if (dit.inTexted() && dit.depth()==1
+                                               && dit.paragraph().find(align_d, false, false, dit.pos()))
+                                               break;
+
+                               pit_type const psize = tail.paragraphs().front().size();
+                               if (dit) {
+                                       tail.paragraphs().front().eraseChars(0,
+                                               dit.pos() < psize ? dit.pos() + 1 : psize, false);
+                                       Dimension dim1;
                                        tail.metrics(m, dim1);
                                        decimal_width = dim1.width();
                                }
                        }
-                       tabular.cell_info[r][c].decimal_hoffset = decimal_hoffset;
+                       tabular.cell_info[r][c].decimal_hoffset = tm.width() - decimal_width;
                        tabular.cell_info[r][c].decimal_width = decimal_width;
 
                        // with LYX_VALIGN_BOTTOM the descent is relative to the last par
index 96d5a34d5a73419f8265deb7b4d22b5632d8333a..77131a055b4a2e27c8913ded9c8777acddffdb7b 100644 (file)
@@ -99,6 +99,26 @@ void InsetText::setBuffer(Buffer & buf)
 }
 
 
+void InsetText::setMacrocontextPositionRecursive(DocIterator const & pos)
+{
+       text_.setMacrocontextPosition(pos);
+
+       ParagraphList::const_iterator pit = paragraphs().begin();
+       ParagraphList::const_iterator pend = paragraphs().end();
+       for (; pit != pend; ++pit) {
+               InsetList::const_iterator iit = pit->insetList().begin();
+               InsetList::const_iterator end = pit->insetList().end();
+               for (; iit != end; ++iit) {
+                       if (InsetText * txt = iit->inset->asInsetText()) {
+                               DocIterator ppos(pos);
+                               ppos.push_back(CursorSlice(*txt));
+                               iit->inset->asInsetText()->setMacrocontextPositionRecursive(ppos);
+                       }
+               }
+       }
+}
+
+
 void InsetText::clear()
 {
        ParagraphList & pars = paragraphs();
index 1f643c029fcc9a606ad35e576508e46bf05ceaea..704194c5d0212dee50e403e438e0ffdfe49eee35 100644 (file)
@@ -164,6 +164,8 @@ public:
        /// Update the counters of this inset and of its contents
        virtual void updateBuffer(ParIterator const &, UpdateType);
        /// 
+       void setMacrocontextPositionRecursive(DocIterator const & pos);
+       ///
        void toString(odocstream &) const;
        ///
        void forToc(docstring &, size_t) const;