]> git.lyx.org Git - lyx.git/blobdiff - src/text.C
bug 806 change layout to default when deleting empty keepempty paragraphs
[lyx.git] / src / text.C
index bf07d9fc9140dd7d142896f6bbb6605c49a76bdf..2f1a099dab1c6f9b21a36f3aa4221fc6f9fc6905 100644 (file)
@@ -195,10 +195,14 @@ void readParToken(Buffer const & buf, Paragraph & par, LyXLex & lex,
                par.params().read(lex);
 
        } else if (token == "\\end_layout") {
-               lyxerr << "Solitary \\end_layout in line " << lex.getLineNo() << "\n"
+               lyxerr << BOOST_CURRENT_FUNCTION
+                       << ": Solitary \\end_layout in line "
+                       << lex.getLineNo() << "\n"
                       << "Missing \\begin_layout?.\n";
        } else if (token == "\\end_inset") {
-               lyxerr << "Solitary \\end_inset in line " << lex.getLineNo() << "\n"
+               lyxerr << BOOST_CURRENT_FUNCTION
+                       << ": Solitary \\end_inset in line "
+                       << lex.getLineNo() << "\n"
                       << "Missing \\begin_inset?.\n";
        } else if (token == "\\begin_inset") {
                InsetBase * inset = readInset(lex, buf);
@@ -371,6 +375,8 @@ void readParagraph(Buffer const & buf, Paragraph & par, LyXLex & lex)
                        break;
                }
        }
+       // Initialize begin_of_body_ on load; redoParagraph maintains
+       par.setBeginOfBody();
 }
 
 
@@ -590,8 +596,12 @@ int LyXText::leftMargin(pit_type const pit, pos_type const pos) const
                   && !isFirstInSequence(pit, pars_)))
            && align == LYX_ALIGN_BLOCK
            && !par.params().noindent()
+           // display style insets are always centered, omit indentation
+           && !(!par.empty()
+                   && par.isInset(pos)
+                   && par.getInset(pos)->display())
            // in charstyles, tabulars and ert paragraphs are never indented!
-           && (par.ownerCode() != InsetBase::TEXT_CODE
+           && ((par.ownerCode() != InsetBase::TEXT_CODE || isMainText())
                    && par.ownerCode() != InsetBase::ERT_CODE
                    && par.ownerCode() != InsetBase::CHARSTYLE_CODE)
            && (par.layout() != tclass.defaultLayout()
@@ -773,7 +783,7 @@ void LyXText::setRowWidth(pit_type const pit, Row & row) const
        pos_type const end = row.endpos();
 
        Paragraph const & par = pars_[pit];
-       string labelsep = par.layout()->labelsep;
+       string const & labelsep = par.layout()->labelsep;
        int w = leftMargin(pit, row.pos());
 
        pos_type const body_pos = par.beginOfBody();
@@ -911,12 +921,13 @@ void LyXText::setHeightOfRow(pit_type const pit, Row & row)
                                maxasc += bufparams.getDefSkip().inPixels(*bv());
                }
 
-               if (pars_[pit].params().startOfAppendix())
+               if (par.params().startOfAppendix())
                        maxasc += int(3 * dh);
 
                // This is special code for the chapter, since the label of this
                // layout is printed in an extra row
-               if (layout->counter == "chapter" && bufparams.secnumdepth >= 0) {
+               if (layout->counter == "chapter"
+                   && !par.params().labelString().empty()) {
                        labeladdon = int(font_metrics::maxHeight(labelfont)
                                     * layout->spacing.getValue()
                                     * spacing(par));
@@ -999,7 +1010,7 @@ void LyXText::setHeightOfRow(pit_type const pit, Row & row)
        if (bv_owner->text() == this) {
                if (pit == 0 && row.pos() == 0)
                        maxasc += 20;
-               if (pit == pars_.size() - 1 && row.endpos() == par.size())
+               if (pit + 1 == pars_.size() && row.endpos() == par.size())
                        maxdesc += 20;
        }
 
@@ -1182,7 +1193,8 @@ void LyXText::insertChar(LCursor & cur, char c)
 
        current_font = rawtmpfont;
        real_current_font = realtmpfont;
-       setCursor(cur, cur.pit(), cur.pos() + 1, false, cur.boundary());
+       //setCursor(cur, cur.pit(), cur.pos() + 1, false, cur.boundary());
+       setCursor(cur, cur.pit(), cur.pos() + 1, false, true);
        charInserted();
 }
 
@@ -1571,6 +1583,17 @@ void LyXText::backspace(LCursor & cur)
                        // handle the actual deletion of the paragraph.
 
                        if (cur.pit() != 0) {
+                                // For KeepEmpty layouts we need to get
+                                // rid of the keepEmpty setting first.
+                                // And the only way to do this is to
+                                // reset the layout to something
+                                // else: f.ex. the default layout.
+                                if (par.allowEmpty()) {
+                                        Buffer & buf = cur.buffer();
+                                        BufferParams const & bparams = buf.params();
+                                        par.layout(bparams.getLyXTextClass().defaultLayout());
+                                }
+                                
                                cursorLeft(cur);
                                return;
                        }
@@ -1648,11 +1671,29 @@ Row const & LyXText::firstRow() const
 }
 
 
-void LyXText::redoParagraph(pit_type const pit)
+bool LyXText::redoParagraph(pit_type const pit)
 {
        // remove rows of paragraph, keep track of height changes
        Paragraph & par = pars_[pit];
 
+       // Add bibitem insets if necessary
+       if (par.layout()->labeltype == LABEL_BIBLIO) {
+               bool hasbibitem(false);
+               if (!par.insetlist.empty()
+                       // Insist on it being in pos 0
+                       && par.getChar(0) == Paragraph::META_INSET) {
+                       InsetBase * inset = par.insetlist.begin()->inset;
+                       if (inset->lyxCode() == InsetBase::BIBITEM_CODE)
+                               hasbibitem = true;
+               }
+               if (!hasbibitem) {
+                       InsetBibitem * inset(new
+                               InsetBibitem(InsetCommandParams("bibitem")));
+                       par.insertInset(0, static_cast<InsetBase *>(inset));
+                       bv()->cursor().posRight();
+               }
+       }
+
        // redo insets
        InsetList::iterator ii = par.insetlist.begin();
        InsetList::iterator iend = par.insetlist.end();
@@ -1682,8 +1723,13 @@ void LyXText::redoParagraph(pit_type const pit)
 
        dim.asc += par.rows()[0].ascent();
        dim.des -= par.rows()[0].ascent();
+
+       bool const same = dim == par.dim();
+
        par.dim() = dim;
        //lyxerr << "redoParagraph: " << par.rows().size() << " rows\n";
+
+       return !same;
 }
 
 
@@ -1694,6 +1740,8 @@ void LyXText::metrics(MetricsInfo & mi, Dimension & dim)
                maxwidth_ = mi.base.textwidth;
        //lyxerr << "LyXText::metrics: width: " << mi.base.textwidth
        //      << " maxWidth: " << maxwidth_ << "\nfont: " << mi.base.font << endl;
+       // save the caller's font locally:
+       font_ = mi.base.font;
 
        unsigned int h = 0;
        unsigned int w = 0;
@@ -1757,7 +1805,7 @@ void LyXText::drawSelection(PainterInfo & pi, int x , int) const
                x2 = 0;
        } else {
                y1 = bv_funcs::getPos(beg).y_ - row1.ascent();
-               int const startx = cursorX(beg.top());
+               int const startx = cursorX(beg.top(), begin.boundary());
                x1 = isRTL(par1) ? startx : 0;
                x2 = isRTL(par1) ? 0 + dim_.wid : startx;
        }
@@ -1769,7 +1817,7 @@ void LyXText::drawSelection(PainterInfo & pi, int x , int) const
                X2 = 0;
        } else {
                y2 = bv_funcs::getPos(end).y_ + row2.descent();
-               int const endx = cursorX(end.top());
+               int const endx = cursorX(end.top(), end.boundary());
                X1 = isRTL(par2) ? 0 : endx;
                X2 = isRTL(par2) ? endx : 0 + dim_.wid;
        }
@@ -1800,7 +1848,10 @@ void LyXText::drawSelection(PainterInfo & pi, int x, int) const
        if (!ptr_cmp(cur.text(), this))
                return;
 
-       lyxerr << "draw selection at " << x << endl;
+       lyxerr[Debug::DEBUG]
+                << BOOST_CURRENT_FUNCTION
+                << "draw selection at " << x
+                << endl;
 
        // is there a better way of getting these two iterators?
        DocIterator beg = cur;
@@ -1829,9 +1880,9 @@ void LyXText::drawSelection(PainterInfo & pi, int x, int) const
                x2 = dim_.wid;
        } else {
                Row const & row1 = par1.getRow(beg.pos());
-               y1 = bv_funcs::getPos(beg).y_ - row1.ascent();
+               y1 = bv_funcs::getPos(beg, beg.boundary()).y_ - row1.ascent();
                y2 = y1 + row1.height();
-               int const startx = cursorX(beg.top());
+               int const startx = cursorX(beg.top(), beg.boundary());
                x1 = !isRTL(par1) ? startx : 0;
                x2 = !isRTL(par1) ? 0 + dim_.wid : startx;
        }
@@ -1844,9 +1895,9 @@ void LyXText::drawSelection(PainterInfo & pi, int x, int) const
                X2 = dim_.wid;
        } else {
                Row const & row2 = par2.getRow(end.pos());
-               Y1 = bv_funcs::getPos(end).y_ - row2.ascent();
+               Y1 = bv_funcs::getPos(end, end.boundary()).y_ - row2.ascent();
                Y2 = Y1 + row2.height();
-               int const endx = cursorX(end.top());
+               int const endx = cursorX(end.top(), end.boundary());
                X1 = !isRTL(par2) ? 0 : endx;
                X2 = !isRTL(par2) ? endx : 0 + dim_.wid;
        }
@@ -1871,6 +1922,7 @@ void LyXText::drawSelection(PainterInfo & pi, int x, int) const
                              Y1 - y2, LColor::selection);
 }
 
+
 bool LyXText::isLastRow(pit_type pit, Row const & row) const
 {
        return row.endpos() >= pars_[pit].size()
@@ -2006,16 +2058,20 @@ int LyXText::descent() const
 }
 
 
-int LyXText::cursorX(CursorSlice const & cur) const
+int LyXText::cursorX(CursorSlice const & sl, bool boundary) const
 {
-       pit_type const pit = cur.pit();
+       pit_type const pit = sl.pit();
        Paragraph const & par = pars_[pit];
        if (par.rows().empty())
                return 0;
 
-       Row const & row = par.getRow(cur.pos());
+       pos_type pos = sl.pos();
+       //// Correct position in front of big insets
+       //if (pos && boundary)
+       //      --pos;
+
+       Row const & row = par.getRow(pos);
 
-       pos_type pos = cur.pos();
        pos_type cursor_vpos = 0;
 
        RowMetrics const m = computeRowMetrics(pit, row);
@@ -2065,20 +2121,28 @@ int LyXText::cursorX(CursorSlice const & cur) const
                } else
                        x += singleWidth(par, pos);
        }
+       
+       // see correction above
+       //if (pos && boundary)
+       //      x += singleWidth(par, pos + 1);
+
        return int(x);
 }
 
 
-int LyXText::cursorY(CursorSlice const & cur) const
+int LyXText::cursorY(CursorSlice const & sl, bool boundary) const
 {
-       Paragraph const & par = getPar(cur.pit());
+       //lyxerr << "LyXText::cursorY: boundary: " << boundary << std::endl;
+       Paragraph const & par = getPar(sl.pit());
        int h = 0;
        h -= pars_[0].rows()[0].ascent();
-       for (pit_type pit = 0; pit < cur.pit(); ++pit)
+       for (pit_type pit = 0; pit < sl.pit(); ++pit)
                h += pars_[pit].height();
-       for (size_t rit = 0, rend = par.pos2row(cur.pos()); rit != rend; ++rit)
+       //size_t const rend = par.pos2row(sl.pos() - boundary ? 1 : 0);
+       size_t const rend = par.pos2row(sl.pos());
+       for (size_t rit = 0; rit != rend; ++rit)
                h += par.rows()[rit].height();
-       h += par.rows()[par.pos2row(cur.pos())].ascent();
+       h += par.rows()[rend].ascent();
        return h;
 }
 
@@ -2215,6 +2279,7 @@ string LyXText::getPossibleLabel(LCursor & cur) const
 
 pos_type LyXText::x2pos(pit_type pit, int row, int x) const
 {
+       BOOST_ASSERT(row < int(pars_[pit].rows().size()));
        bool bound = false;
        Row const & r = pars_[pit].rows()[row];
        return r.pos() + getColumnNearX(pit, r, x, bound);
@@ -2236,8 +2301,12 @@ void LyXText::setCursorFromCoordinates(LCursor & cur, int const x, int const y)
 {
        pit_type pit = getPitNearY(y);
        int yy = theCoords.get(this, pit).y_ - pars_[pit].ascent();
-       lyxerr << "setCursorFromCoordinates: x: " << x << " y: " << y
-               << " pit: " << pit << " yy: " << yy << endl;
+       lyxerr[Debug::DEBUG]
+                << BOOST_CURRENT_FUNCTION
+                << ": x: " << x
+                << " y: " << y
+               << " pit: " << pit
+                << " yy: " << yy << endl;
 
        Paragraph const & par = pars_[pit];
        int r = 0;
@@ -2251,11 +2320,21 @@ void LyXText::setCursorFromCoordinates(LCursor & cur, int const x, int const y)
 
        Row const & row = par.rows()[r];
 
-       lyxerr << "setCursorFromCoordinates:  row " << r
-              << " from pos: " << row.pos() << endl;
+       lyxerr[Debug::DEBUG]
+                << BOOST_CURRENT_FUNCTION
+                << ": row " << r
+                << " from pos: " << row.pos()
+                << endl;
 
        bool bound = false;
        int xx = x;
        pos_type const pos = row.pos() + getColumnNearX(pit, row, xx, bound);
+
+        lyxerr[Debug::DEBUG]
+                << BOOST_CURRENT_FUNCTION
+                << ": setting cursor pit: " << pit
+                << " pos: " << pos
+                << endl;
+        
        setCursor(cur, pit, pos, true, bound);
 }