]> git.lyx.org Git - lyx.git/blobdiff - src/text.C
More 'standard conformant blurb' nonsense.
[lyx.git] / src / text.C
index cd2cd571f76939f79817865463c4ee065fe14e03..aac263891554fdde9793cfdf40a301d491e3d0ac 100644 (file)
@@ -82,61 +82,29 @@ BufferView * LyXText::bv() const
 
 void LyXText::updateRowPositions()
 {
-       RowList::iterator rit = rows().begin();
-       RowList::iterator rend = rows().end();
-       for (int y = 0; rit != rend ; ++rit) {
-               rit->y(y);
-               y += rit->height();
+       ParagraphList::iterator pit = ownerParagraphs().begin();
+       ParagraphList::iterator end = ownerParagraphs().end();
+       for (int y = 0; pit != end; ++pit) {
+               RowList::iterator rit = pit->rows.begin();
+               RowList::iterator rend = pit->rows.end();
+               for ( ; rit != rend ; rit = ++rit) {
+                       rit->y(y);
+                       y += rit->height();
+               }
        }
 }
 
 
 int LyXText::top_y() const
 {
-       if (anchor_row_ == rowlist_.end())
-               return 0;
-
-       return anchor_row_->y() + anchor_row_offset_;
+       return anchor_y_;
 }
 
 
 void LyXText::top_y(int newy)
 {
-       if (rows().empty())
-               return;
-
-       if (isInInset()) {
-               anchor_row_ = rows().begin();
-               anchor_row_offset_ = newy;
-               return;
-       }
-
-       lyxerr[Debug::GUI] << "setting top y = " << newy << endl;
-
-       int y = newy;
-       RowList::iterator rit = getRowNearY(y);
-
-       if (rit == anchor_row_ && anchor_row_offset_ == newy - y) {
-               lyxerr[Debug::GUI] << "top_y to same value, skipping update" << endl;
-               return;
-       }
-
-       anchor_row_ = rit;
-       anchor_row_offset_ = newy - y;
-       lyxerr[Debug::GUI] << "changing reference to row: " << &*anchor_row_
-              << " offset: " << anchor_row_offset_ << endl;
-}
-
-
-void LyXText::anchor_row(RowList::iterator rit)
-{
-       int old_y = top_y();
-       anchor_row_offset_ = 0;
-       anchor_row_ = rit;
-       anchor_row_offset_ = old_y - top_y();
-       lyxerr[Debug::GUI] << "anchor_row(): changing reference to row: "
-                          << &*anchor_row_ << " offset: "
-                          << anchor_row_offset_ << endl;
+       anchor_y_ = newy;
+       lyxerr[Debug::GUI] << "changing reference to offset: " << anchor_y_ << endl;
 }
 
 
@@ -255,26 +223,12 @@ int LyXText::singleWidth(ParagraphList::iterator pit,
 
        if (c == Paragraph::META_INSET) {
                InsetOld * tmpinset = pit->getInset(pos);
-               if (tmpinset) {
-                       if (tmpinset->lyxCode() == InsetOld::HFILL_CODE) {
-                               // Because of the representation as vertical lines
-                               return 3;
-                       }
-#if 0
-#warning enabling this fixes the 'insets of width 0 on load' problem
-                       // this IS needed otherwise on initialitation we don't get the fill
-                       // of the row right (ONLY on initialization if we read a file!)
-                       // should be changed! (Jug 20011204)
-                       //tmpinset->update(bv());
-                       Dimension dim;
-                       MetricsInfo mi(bv(), font, workWidth());
-                       tmpinset->metrics(mi, dim);
-                       return dim.wid;
-#else
-                       return tmpinset->width();
-#endif
+               Assert(tmpinset);
+               if (tmpinset->lyxCode() == InsetOld::HFILL_CODE) {
+                       // Because of the representation as vertical lines
+                       return 3;
                }
-               return 0;
+               return tmpinset->width();
        }
 
        if (IsSeparatorChar(c))
@@ -317,7 +271,7 @@ bool LyXText::bidi_InRange(lyx::pos_type pos) const
 }
 
 
-void LyXText::computeBidiTables(ParagraphList::iterator row_par,
+void LyXText::computeBidiTables(ParagraphList::iterator pit,
    Buffer const * buf, RowList::iterator row) const
 {
        bidi_same_direction = true;
@@ -326,7 +280,7 @@ void LyXText::computeBidiTables(ParagraphList::iterator row_par,
                return;
        }
 
-       InsetOld * inset = row_par->inInset();
+       InsetOld * inset = pit->inInset();
        if (inset && inset->owner() &&
            inset->owner()->lyxCode() == InsetOld::ERT_CODE) {
                bidi_start = -1;
@@ -334,7 +288,7 @@ void LyXText::computeBidiTables(ParagraphList::iterator row_par,
        }
 
        bidi_start = row->pos();
-       bidi_end = lastPrintablePos(*this, row_par, row);
+       bidi_end = lastPrintablePos(*pit, row);
 
        if (bidi_start > bidi_end) {
                bidi_start = -1;
@@ -356,25 +310,25 @@ void LyXText::computeBidiTables(ParagraphList::iterator row_par,
 
        pos_type stack[2];
        bool const rtl_par =
-               row_par->isRightToLeftPar(buf->params);
+               pit->isRightToLeftPar(buf->params);
        int level = 0;
        bool rtl = false;
        bool rtl0 = false;
-       pos_type const body_pos = row_par->beginningOfBody();
+       pos_type const body_pos = pit->beginningOfBody();
 
        for (pos_type lpos = bidi_start; lpos <= bidi_end; ++lpos) {
-               bool is_space = row_par->isLineSeparator(lpos);
+               bool is_space = pit->isLineSeparator(lpos);
                pos_type const pos =
                        (is_space && lpos + 1 <= bidi_end &&
-                        !row_par->isLineSeparator(lpos + 1) &&
-                        !row_par->isNewline(lpos + 1))
+                        !pit->isLineSeparator(lpos + 1) &&
+                        !pit->isNewline(lpos + 1))
                        ? lpos + 1 : lpos;
-               LyXFont font = row_par->getFontSettings(buf->params, pos);
+               LyXFont font = pit->getFontSettings(buf->params, pos);
                if (pos != lpos && 0 < lpos && rtl0 && font.isRightToLeft() &&
                    font.number() == LyXFont::ON &&
-                   row_par->getFontSettings(buf->params, lpos - 1).number()
+                   pit->getFontSettings(buf->params, lpos - 1).number()
                    == LyXFont::ON) {
-                       font = row_par->getFontSettings(buf->params, lpos);
+                       font = pit->getFontSettings(buf->params, lpos);
                        is_space = false;
                }
 
@@ -480,7 +434,7 @@ bool LyXText::isBoundary(Buffer const * buf, Paragraph const & par,
 
 
 int LyXText::leftMargin(ParagraphList::iterator pit, Row const & row) const
-{
+{      
        InsetOld * ins;
 
        if (row.pos() < pit->size())
@@ -605,18 +559,12 @@ int LyXText::leftMargin(ParagraphList::iterator pit, Row const & row) const
                // are *NOT* allowed in the LaTeX realisation of this layout.
 
                // find the first row of this paragraph
-               RowList::iterator tmprit = rowlist_.begin();
-               while (tmprit != rowlist_.end()
-                      && getPar(tmprit) != pit)
-                       ++tmprit;
-
-               int minfill = tmprit->fill();
-               while (boost::next(tmprit) != rowlist_.end() &&
-                      getPar(boost::next(tmprit)) == pit) {
-                       ++tmprit;
-                       if (tmprit->fill() < minfill)
-                               minfill = tmprit->fill();
-               }
+               RowList::iterator rit = pit->rows.begin();
+               RowList::iterator end = pit->rows.end();
+               int minfill = rit->fill();
+               for ( ; rit != end; ++rit)
+                       if (rit->fill() < minfill)
+                               minfill = rit->fill();
 
                x += font_metrics::signedWidth(layout->leftmargin,
                        tclass.defaultfont());
@@ -875,15 +823,15 @@ pos_type LyXText::rowBreakPoint(ParagraphList::iterator pit,
 
 
 // returns the minimum space a row needs on the screen in pixel
-int LyXText::fill(RowList::iterator row, int paper_width) const
+int LyXText::fill(ParagraphList::iterator pit,
+       RowList::iterator row, int paper_width) const
 {
        if (paper_width < 0)
                return 0;
 
        int w;
        // get the pure distance
-       ParagraphList::iterator pit = getPar(row);
-       pos_type const last = lastPrintablePos(*this, pit, row);
+       pos_type const last = lastPrintablePos(*pit, row);
 
        LyXLayout_ptr const & layout = pit->layout();
 
@@ -1009,10 +957,8 @@ LColor::color LyXText::backgroundColor() const
 }
 
 
-void LyXText::setHeightOfRow(RowList::iterator rit)
+void LyXText::setHeightOfRow(ParagraphList::iterator pit, RowList::iterator rit)
 {
-       Assert(rit != rows().end());
-
        // get the maximum ascent and the maximum descent
        double layoutasc = 0;
        double layoutdesc = 0;
@@ -1021,8 +967,6 @@ void LyXText::setHeightOfRow(RowList::iterator rit)
        // ok, let us initialize the maxasc and maxdesc value.
        // Only the fontsize count. The other properties
        // are taken from the layoutfont. Nicer on the screen :)
-       ParagraphList::iterator pit = getPar(rit);
-
        LyXLayout_ptr const & layout = pit->layout();
 
        // as max get the first character of this row then it can increase but not
@@ -1048,7 +992,7 @@ void LyXText::setHeightOfRow(RowList::iterator rit)
        int maxdesc = int(font_metrics::maxDescent(font) *
                          layout->spacing.getValue() * spacing_val);
 
-       pos_type const pos_end = lastPos(*this, pit, rit);
+       pos_type const pos_end = lastPos(*pit, rit);
        int labeladdon = 0;
        int maxwidth = 0;
 
@@ -1224,12 +1168,11 @@ void LyXText::setHeightOfRow(RowList::iterator rit)
                                prev->getLabelWidthString() == pit->getLabelWidthString())
                        {
                                layoutasc = (layout->itemsep * defaultRowHeight());
-                       } else if (rit != rows().begin()) {
+                       } else if (rit != firstRow()) {
                                tmptop = layout->topsep;
 
-                               if (boost::prior(pit)->getDepth() >= pit->getDepth()) {
-                                       tmptop -= getPar(boost::prior(rit))->layout()->bottomsep;
-                               }
+                               //if (boost::prior(pit)->getDepth() >= pit->getDepth())
+                               //      tmptop -= getPar(previousRow(rit))->layout()->bottomsep;
 
                                if (tmptop > 0)
                                        layoutasc = (tmptop * defaultRowHeight());
@@ -1254,12 +1197,10 @@ void LyXText::setHeightOfRow(RowList::iterator rit)
        }
 
        // is it a bottom line?
-       RowList::iterator next_rit = boost::next(rit);
-       if (next_rit == rows().end() || getPar(next_rit) != pit) {
+       if (boost::next(rit) == pit->rows.end()) {
                // the bottom margin
                ParagraphList::iterator nextpit = boost::next(pit);
-               if (nextpit == ownerParagraphs().end() &&
-                   !isInInset())
+               if (nextpit == ownerParagraphs().end() && !isInInset())
                        maxdesc += PAPER_MARGIN;
 
                // add the vertical spaces, that the user added
@@ -1331,11 +1272,14 @@ void LyXText::setHeightOfRow(RowList::iterator rit)
        rit->width(int(maxwidth + x));
        if (inset_owner) {
                width = max(0, workWidth());
-               RowList::iterator it = rows().begin();
-               RowList::iterator end = rows().end();
-               for (; it != end; ++it)
-                       if (it->width() > width)
-                               width = it->width();
+               RowList::iterator rit = firstRow();
+               RowList::iterator end = endRow();
+               ParagraphList::iterator it = ownerParagraphs().begin();
+               while (rit != end) {
+                       if (rit->width() > width)
+                               width = rit->width();
+                       nextRow(it, rit);
+               }
        }
 }
 
@@ -1380,6 +1324,12 @@ void LyXText::breakParagraph(ParagraphList & paragraphs, char keep_layout)
        ::breakParagraph(bv()->buffer()->params, paragraphs, cursor.par(),
                         cursor.pos(), keep_layout);
 
+#warning Trouble Point! (Lgb)
+       // When ::breakParagraph is called from within an inset we must
+       // ensure that the correct ParagraphList is used. Today that is not
+       // the case and the Buffer::paragraphs is used. Not good. (Lgb)
+       ParagraphList::iterator next_par = boost::next(cursor.par());
+
        // well this is the caption hack since one caption is really enough
        if (layout->labeltype == LABEL_SENSITIVE) {
                if (!cursor.pos())
@@ -1387,7 +1337,7 @@ void LyXText::breakParagraph(ParagraphList & paragraphs, char keep_layout)
                        cursor.par()->applyLayout(tclass.defaultLayout());
                else
                        // set to standard-layout
-                       boost::next(cursor.par())->applyLayout(tclass.defaultLayout());
+                       next_par->applyLayout(tclass.defaultLayout());
        }
 
        // if the cursor is at the beginning of a row without prior newline,
@@ -1400,19 +1350,12 @@ void LyXText::breakParagraph(ParagraphList & paragraphs, char keep_layout)
                cursorLeft(bv());
        }
 
-       removeParagraph(cursorRow());
-
-#warning Trouble Point! (Lgb)
-       // When ::breakParagraph is called from within an inset we must
-       // ensure that the correct ParagraphList is used. Today that is not
-       // the case and the Buffer::paragraphs is used. Not good. (Lgb)
-       ParagraphList::iterator next_par = boost::next(cursor.par());
-
        while (!next_par->empty() && next_par->isNewline(0))
                next_par->erase(0);
 
-       insertParagraph(next_par, boost::next(cursorRow()));
        updateCounters();
+       redoParagraph(cursor.par());
+       redoParagraph(next_par);
 
        // This check is necessary. Otherwise the new empty paragraph will
        // be deleted automatically. And it is more friendly for the user!
@@ -1420,8 +1363,6 @@ void LyXText::breakParagraph(ParagraphList & paragraphs, char keep_layout)
                setCursor(next_par, 0);
        else
                setCursor(cursor.par(), 0);
-
-       redoParagraph(cursor.par());
 }
 
 
@@ -1580,7 +1521,7 @@ void LyXText::prepareToPrint(ParagraphList::iterator pit,
        if (layout->margintype == MARGIN_MANUAL
            && layout->labeltype == LABEL_MANUAL) {
                /// We might have real hfills in the label part
-               int nlh = numberOfLabelHfills(*this, pit, rit);
+               int nlh = numberOfLabelHfills(*pit, rit);
 
                // A manual label par (e.g. List) has an auto-hfill
                // between the label text and the body of the
@@ -1596,7 +1537,7 @@ void LyXText::prepareToPrint(ParagraphList::iterator pit,
        }
 
        // are there any hfills in the row?
-       int const nh = numberOfHfills(*this, pit, rit);
+       int const nh = numberOfHfills(*pit, rit);
 
        if (nh) {
                if (w > 0)
@@ -1633,16 +1574,14 @@ void LyXText::prepareToPrint(ParagraphList::iterator pit,
                switch (align) {
            case LYX_ALIGN_BLOCK:
            {
-                       int const ns = numberOfSeparators(*this, pit, rit);
+                       int const ns = numberOfSeparators(*pit, rit);
                        RowList::iterator next_row = boost::next(rit);
-                       ParagraphList::iterator next_pit;
-
-                       if (ns && next_row != rowlist_.end() &&
-                           (next_pit = getPar(next_row)) == pit &&
-                           !(next_pit->isNewline(next_row->pos() - 1))
-                           && !(next_pit->isInset(next_row->pos()) &&
-                                next_pit->getInset(next_row->pos()) &&
-                                next_pit->getInset(next_row->pos())->display())
+                       if (ns
+                               && next_row != pit->rows.end()
+                               && !pit->isNewline(next_row->pos() - 1)
+                         && !(pit->isInset(next_row->pos())
+                                    && pit->getInset(next_row->pos())
+                                    && pit->getInset(next_row->pos())->display())
                                ) {
                                fill_separator = w / ns;
                        } else if (is_rtl) {
@@ -1664,7 +1603,7 @@ void LyXText::prepareToPrint(ParagraphList::iterator pit,
        computeBidiTables(pit, bv()->buffer(), rit);
        if (is_rtl) {
                pos_type body_pos = pit->beginningOfBody();
-               pos_type last = lastPos(*this, pit, rit);
+               pos_type last = lastPos(*pit, rit);
 
                if (body_pos > 0 &&
                    (body_pos - 1 > last ||
@@ -2076,7 +2015,7 @@ void LyXText::backspace()
                                cursorLeft(bv());
 
                                // the layout things can change the height of a row !
-                               setHeightOfRow(cursorRow());
+                               setHeightOfRow(cursor.par(), cursorRow());
                                return;
                        }
                }
@@ -2088,8 +2027,6 @@ void LyXText::backspace()
                }
 
                ParagraphList::iterator tmppit = cursor.par();
-               RowList::iterator tmprow = cursorRow();
-
                // We used to do cursorLeftIntern() here, but it is
                // not a good idea since it triggers the auto-delete
                // mechanism. So we do a cursorLeftIntern()-lite,
@@ -2112,8 +2049,6 @@ void LyXText::backspace()
                    && (cursor.par()->layout() == tmppit->layout()
                        || tmppit->layout() == tclass.defaultLayout())
                    && cursor.par()->getAlign() == tmppit->getAlign()) {
-                       removeParagraph(tmprow);
-                       removeRow(tmprow);
                        mergeParagraph(bv()->buffer()->params,
                                bv()->buffer()->paragraphs, cursor.par());
 
@@ -2161,23 +2096,15 @@ RowList::iterator LyXText::getRow(LyXCursor const & cur) const
 RowList::iterator
 LyXText::getRow(ParagraphList::iterator pit, pos_type pos) const
 {
-       if (rows().empty())
-               return rowlist_.end();
-
-       // find the first row of the specified paragraph
-       RowList::iterator rit = rowlist_.begin();
-       RowList::iterator end = rowlist_.end();
-       while (boost::next(rit) != end && getPar(rit) != pit) {
+       RowList::iterator rit = pit->rows.begin();
+       RowList::iterator end = pit->rows.end();
+
+#warning Why is this next thing needed? (Andre)
+       while (rit != end
+                    && rit->pos() < pos
+                    && boost::next(rit) != end
+                    && boost::next(rit)->pos() <= pos)
                ++rit;
-       }
-
-       // now find the wanted row
-       while (rit->pos() < pos
-              && boost::next(rit) != end
-              && getPar(boost::next(rit)) == pit
-              && boost::next(rit)->pos() <= pos) {
-               ++rit;
-       }
 
        return rit;
 }
@@ -2189,21 +2116,22 @@ LyXText::getRow(ParagraphList::iterator pit, pos_type pos, int & y) const
 {
        y = 0;
 
-       if (rows().empty())
-               return rowlist_.end();
+       if (noRows())
+               return firstRow();
 
-       // find the first row of the specified paragraph
-       RowList::iterator rit = rowlist_.begin();
-       RowList::iterator end = rowlist_.end();
-       while (boost::next(rit) != end && getPar(rit) != pit) {
-               y += rit->height();
-               ++rit;
+       ParagraphList::iterator it = ownerParagraphs().begin();
+       for ( ; it != pit; ++it) {
+               RowList::iterator beg = it->rows.begin();
+               RowList::iterator end = it->rows.end();
+               for (RowList::iterator rit = beg; rit != end; ++rit)
+                       y += rit->height();
        }
 
-       // now find the wanted row
-       while (rit->pos() < pos
+       RowList::iterator rit = pit->rows.begin();
+       RowList::iterator end = pit->rows.end();
+       while (rit != end
+              && rit->pos() < pos
               && boost::next(rit) != end
-              && getPar(boost::next(rit)) == pit
               && boost::next(rit)->pos() <= pos) {
                y += rit->height();
                ++rit;
@@ -2221,44 +2149,20 @@ RowList::iterator LyXText::cursorIRow() const
 }
 
 
-RowList::iterator LyXText::getRowNearY(int & y) const
+RowList::iterator LyXText::getRowNearY(int & y,
+       ParagraphList::iterator & pit) const
 {
-       RowList::iterator rit = anchor_row_;
-       RowList::iterator const beg = rows().begin();
-       RowList::iterator const end = rows().end();
-
-       if (rows().empty()) {
-               y = 0;
-               return end;
-       }
-       if (rit == end)
-               rit = beg;
-
-       int tmpy = rit->y();
-
-       if (tmpy <= y) {
-               while (rit != end && tmpy <= y) {
-                       tmpy += rit->height();
-                       ++rit;
-               }
-               if (rit != beg) {
-                       --rit;
-                       tmpy -= rit->height();
-               }
-       } else {
-               while (rit != beg && tmpy > y) {
-                       --rit;
-                       tmpy -= rit->height();
-               }
-       }
-       if (tmpy < 0 || rit == end) {
-               tmpy = 0;
-               rit = beg;
-       }
+       //lyxerr << "getRowNearY: y " << y << endl;
+       pit = ownerParagraphs().begin();
+       RowList::iterator rit = firstRow();
+       RowList::iterator rend = endRow();
 
-       // return the rel y
-       y = tmpy;
+       for (; rit != rend; nextRow(pit, rit))
+               if (rit->y() > y)
+                       break;
 
+       previousRow(pit, rit);
+       y = rit->y();
        return rit;
 }
 
@@ -2269,66 +2173,52 @@ int LyXText::getDepth() const
 }
 
 
-#warning Expensive. Remove before 1.4!
-// computes a ParagraphList::iterator from RowList::iterator by
-// counting zeros in the sequence of pos values.
-
-ParagraphList::iterator LyXText::getPar(RowList::iterator row) const
+RowList::iterator LyXText::firstRow() const
 {
-       if (row == rows().end()) {
-               lyxerr << "getPar() pit at end " << endl;
-               Assert(false);
-       }
+       return ownerParagraphs().front().rows.begin();
+}
 
-       if (row == rows().begin()) {
-               return ownerParagraphs().begin();
-       }
 
-       ParagraphList::iterator pit = ownerParagraphs().begin();
-       RowList::iterator rit = rows().begin();
-       RowList::iterator rend = rows().end();
-       for (++rit ; rit != rend; ++rit) {
-               if (rit->pos() == 0) {
-                       ++pit;
-                       if (pit == ownerParagraphs().end()) {
-                               lyxerr << "unexpected in LyXText::getPar()" << endl;
-                               Assert(false);
-                       }
-               }
-               if (rit == row) {
-                       return pit;
-               }
-       }
-
-       lyxerr << "LyXText::getPar: row not found " << endl;
-       Assert(false);
-       return ownerParagraphs().end(); // shut up compiler
+RowList::iterator LyXText::lastRow() const
+{
+       return boost::prior(endRow());
 }
 
 
-RowList::iterator LyXText::beginRow(ParagraphList::iterator pit) const
+RowList::iterator LyXText::endRow() const
 {
-       int n = std::distance(ownerParagraphs().begin(), pit);
+       return ownerParagraphs().back().rows.end();
+}
 
-       RowList::iterator rit = rows().begin();
-       RowList::iterator end = rows().end();
-       for ( ; rit != end; ++rit)
-               if (rit->pos() == 0 && n-- == 0)
-                       return rit;
 
-       return rit;
+void LyXText::nextRow(ParagraphList::iterator & pit,
+       RowList::iterator & rit) const
+{
+       ++rit;
+       if (rit == pit->rows.end()) {
+               ++pit;
+               if (pit == ownerParagraphs().end())
+                       --pit;
+               else
+                       rit = pit->rows.begin();
+       }
 }
 
 
-RowList::iterator LyXText::endRow(ParagraphList::iterator pit) const
+void LyXText::previousRow(ParagraphList::iterator & pit,
+       RowList::iterator & rit) const
 {
-       return beginRow(boost::next(pit));
+       if (rit != pit->rows.begin())
+               --rit;
+       else {
+               Assert(pit != ownerParagraphs().begin());
+               --pit;
+               rit = boost::prior(pit->rows.end());
+       }
 }
 
 
-RowList::iterator LyXText::endRow(RowList::iterator rit) const
+bool LyXText::noRows() const
 {
-       for (++rit; rit != rows().end() && rit->pos(); ++rit)
-               ;
-       return rit;
+       return ownerParagraphs().begin()->rows.empty();
 }