]> git.lyx.org Git - lyx.git/blobdiff - src/text.C
John's Layout Tabular UI improvements and Martins fixes to clearing the
[lyx.git] / src / text.C
index f4da5dd0b847fee8702d772a1c9c17ff3f022c79..e546e323162056e38d1ab286eb4f915d08c041e9 100644 (file)
@@ -12,7 +12,7 @@
 
 #include "lyxtext.h"
 #include "lyxrow.h"
-#include "layout.h"
+#include "lyxtextclasslist.h"
 #include "paragraph.h"
 #include "lyx_gui_misc.h"
 #include "gettext.h"
@@ -69,17 +69,26 @@ int LyXText::workWidth(BufferView * bview) const
 int LyXText::workWidth(BufferView * bview, Inset * inset) const
 {
        Paragraph * par = 0;
-       pos_type pos = 0;
-
-       Buffer::inset_iterator it = bview->buffer()->inset_iterator_begin();
-
-       for (; it != bview->buffer()->inset_iterator_end(); ++it) {
-               if (*it == inset) {
-                       par = it.getPar();
-                       pos = it.getPos();
-                       break;
+       pos_type pos = -1;
+
+       par = inset->parOwner();
+       if (par)
+               pos = par->getPositionOfInset(inset);
+
+       if (!par || pos == -1) {
+               lyxerr << "LyXText::workWidth: something is wrong,"
+                       " fall back to the brute force method" << endl;
+               Buffer::inset_iterator it = bview->buffer()->inset_iterator_begin();
+               Buffer::inset_iterator end = bview->buffer()->inset_iterator_end();
+               for ( ; it != end; ++it) {
+                       if (*it == inset) {
+                               par = it.getPar();
+                               pos = it.getPos();
+                               break;
+                       }
                }
        }
+       
        if (!par) {
                return workWidth(bview);
        }
@@ -128,7 +137,7 @@ unsigned char LyXText::transformChar(unsigned char c, Paragraph * par,
                        pos_type pos) const
 {
        if (!Encodings::is_arabic(c))
-               if (lyxrc.font_norm_type == LyXRC::ISO_8859_6_8 && isdigit(c))
+               if (lyxrc.font_norm_type == LyXRC::ISO_8859_6_8 && IsDigit(c))
                        return c + (0xb0 - '0');
                else
                        return c;
@@ -236,10 +245,11 @@ int LyXText::singleWidth(BufferView * bview, Paragraph * par,
 // Returns the paragraph position of the last character in the specified row
 pos_type LyXText::rowLast(Row const * row) const
 {
-       if (!row->next() || row->next()->par() != row->par())
+       if (!row->next() || row->next()->par() != row->par()) {
                return row->par()->size() - 1;
-       else 
+       } else {
                return row->next()->pos() - 1;
+       }
 }
 
 
@@ -921,7 +931,7 @@ LyXText::nextBreakPoint(BufferView * bview, Row const * row, int width) const
                textclasslist.Style(bview->buffer()->params.textclass,
                                    par->getLayout());
        pos_type i = pos;
-
+       
        if (layout.margintype == MARGIN_RIGHT_ADDRESS_BOX) {
                /* special code for right address boxes, only newlines count */
                while (i < par->size()) {
@@ -949,7 +959,7 @@ LyXText::nextBreakPoint(BufferView * bview, Row const * row, int width) const
                                last_separator = i;
                                x = width; // this means break
                        } else if (c == Paragraph::META_INSET &&
-                                  par->getInset(i)) {
+                                  par->getInset(i)) {
                                
                                // check wether a Display() inset is
                                // valid here. if not, change it to
@@ -957,12 +967,14 @@ LyXText::nextBreakPoint(BufferView * bview, Row const * row, int width) const
                                if (par->getInset(i)->display() &&
                                    (layout.isCommand() ||
                                     (layout.labeltype == LABEL_MANUAL
-                                     && i < beginningOfMainBody(bview->buffer(), par)))) {
+                                     && i < beginningOfMainBody(bview->buffer(), par))))
+                               {
                                        // display istn't allowd
                                        par->getInset(i)->display(false);
                                        x += singleWidth(bview, par, i, c);
                                } else if (par->getInset(i)->display() ||
-                                        par->getInset(i)->needFullRow()) {
+                                          par->getInset(i)->needFullRow())
+                               {
                                        // So break the line here
                                        if (i == pos) {
                                                if (pos < last-1) {
@@ -976,6 +988,16 @@ LyXText::nextBreakPoint(BufferView * bview, Row const * row, int width) const
                                        x = width;  // this means break
                                } else {
                                        x += singleWidth(bview, par, i, c);
+                                       // we have to check this separately as we could have a
+                                       // lineseparator and then the algorithm below would prefer
+                                       // that which IS wrong! We should always break on an inset
+                                       // if it's too long and not on the last separator.
+                                       // Maybe the only exeption is insets used as chars but
+                                       // then we would have to have a special function inside
+                                       // the inset to tell us this. Till then we leave it as
+                                       // it is now. (Jug 20020106)
+                                       if (pos < i && x >= width && last_separator >= 0)
+                                               last_separator = i - 1;
                                }
                        } else  {
                                if (IsLineSeparatorChar(c))
@@ -993,8 +1015,12 @@ LyXText::nextBreakPoint(BufferView * bview, Row const * row, int width) const
                                        x = left_margin;
                        }
                }
+               if ((pos+1 < i) && (last_separator < 0) && (x >= width))
+                       last_separator = i - 2;
+               else if ((pos < i) && (last_separator < 0) && (x >= width))
+                       last_separator = i - 1;
                // end of paragraph is always a suitable separator
-               if (i == last && x < width)
+               else if (i == last && x < width)
                        last_separator = i;
        }
        
@@ -1125,16 +1151,19 @@ int LyXText::numberOfHfills(Buffer const * buf, Row const * row) const
 {
        pos_type const last = rowLast(row);
        pos_type first = row->pos();
+       
        if (first) { /* hfill *DO* count at the beginning 
                      * of paragraphs! */
-               while (first <= last && row->par()->isHfill(first))
+               while (first <= last && row->par()->isHfill(first)) {
                        ++first;
+               }
        }
 
        first = max(first, beginningOfMainBody(buf, row->par()));
        int n = 0;
        for (pos_type p = first; p <= last; ++p) {
                // last, because the end is ignored!
+               
                if (row->par()->isHfill(p)) {
                        ++n;
                }
@@ -1472,7 +1501,8 @@ void LyXText::setHeightOfRow(BufferView * bview, Row * row_ptr) const
                // and now the layout spaces, for example before and after
                // a section, or between the items of a itemize or enumerate
                // environment
-               if (!firstpar->params().pagebreakBottom() && row_ptr->par()->next()) {
+               if (!firstpar->params().pagebreakBottom()
+                   && row_ptr->par()->next()) {
                        Paragraph * nextpar = row_ptr->par()->next();
                        Paragraph * comparepar = row_ptr->par();
                        float usual = 0;
@@ -1775,7 +1805,7 @@ void LyXText::insertChar(BufferView * bview, char c)
                static string const number_seperators = ".,:";
 
                if (current_font.number() == LyXFont::ON) {
-                       if (!isdigit(c) && !contains(number_operators, c) &&
+                       if (!IsDigit(c) && !contains(number_operators, c) &&
                            !(contains(number_seperators, c) &&
                              cursor.pos() >= 1 &&
                              cursor.pos() < cursor.par()->size() &&
@@ -1787,7 +1817,7 @@ void LyXText::insertChar(BufferView * bview, char c)
                                      cursor.pos() - 1).number() == LyXFont::ON)
                            )
                                number(bview); // Set current_font.number to OFF
-               } else if (isdigit(c) &&
+               } else if (IsDigit(c) &&
                           real_current_font.isVisibleRightToLeft()) {
                        number(bview); // Set current_font.number to ON
 
@@ -1906,6 +1936,8 @@ void LyXText::insertChar(BufferView * bview, char c)
        // Is there a break one row above
        if ((cursor.par()->isLineSeparator(cursor.pos())
             || cursor.par()->isNewline(cursor.pos())
+                || ((cursor.pos() < cursor.par()->size()) &&
+                        cursor.par()->isInset(cursor.pos()+1))
             || cursor.row()->fill() == -1)
            && row->previous() && row->previous()->par() == row->par()) {
                pos_type z = nextBreakPoint(bview,
@@ -3159,32 +3191,64 @@ void LyXText::paintRowDepthBar(DrawRowParams & p)
 
 int LyXText::getLengthMarkerHeight(BufferView * bv, VSpace const & vsp) const
 {
+       int const arrow_size = 4;
+       int const space_size = int(vsp.inPixels(bv));
+
        if (vsp.kind() != VSpace::LENGTH) {
-               return int(vsp.inPixels(bv));
+               return space_size;
        }
-
-       int const space_size = int(vsp.inPixels(bv));
-       int const arrow_size = 10;
  
        LyXFont font;
        font.decSize();
-       int const min_size = 2 * arrow_size + 10
-               + lyxfont::maxAscent(font)
-               + lyxfont::maxDescent(font);
+       int const min_size = std::max(3 * arrow_size,
+                                     lyxfont::maxAscent(font)
+                                     + lyxfont::maxDescent(font));
 
-       return std::max(min_size, space_size);
+       if (vsp.length().len().value() < 0.0)
+               return min_size;
+       else 
+               return std::max(min_size, space_size);
 }
 
  
 int LyXText::drawLengthMarker(DrawRowParams & p, string const & prefix,
-       VSpace const & vsp, int start)
+                             VSpace const & vsp, int start)
 {
-       string const str(prefix
-               + " (" + vsp.asLyXCommand() + ")");
-       int const arrow_size = 10;
+       int const arrow_size = 4;
+       int const size = getLengthMarkerHeight(p.bv, vsp);
+       int const end = start + size;
+
+       // the label to display (if any)
+       string str;
+       // y-values for top arrow
+       int ty1, ty2;
+       // y-values for bottom arrow
+       int by1, by2;
+       switch (vsp.kind()) {
+       case VSpace::LENGTH:
+       {
+               str = prefix + " (" + vsp.asLyXCommand() + ")";
+               // adding or removing space
+               bool const added = !(vsp.length().len().value() < 0.0);
+               ty1 = added ? (start + arrow_size) : start;
+               ty2 = added ? start : (start + arrow_size);
+               by1 = added ? (end - arrow_size) : end;
+               by2 = added ? end : (end - arrow_size);
+               break;
+       }
+       case VSpace:: VFILL:
+               str = prefix + " (vertical fill)";
+               ty1 = ty2 = start;
+               by1 = by2 = end;
+               break;
+       default:
+               // nothing to draw here
+               return size;
+       }
  
-       int const size = getLengthMarkerHeight(p.bv, vsp);
+       int const leftx = p.xo + leftMargin(p.bv, p.row);
+       int const midx = leftx + arrow_size;
+       int const rightx = midx + arrow_size;
  
        // first the string
        int w = 0;
@@ -3195,32 +3259,17 @@ int LyXText::drawLengthMarker(DrawRowParams & p, string const & prefix,
        font.setColor(LColor::added_space).decSize();
        lyxfont::rectText(str, font, w, a, d);
  
-       int const end = start + size;
-
-       p.pain->rectText(p.xo + 2 * arrow_size + 5, 
-               start + ((end - start) / 2) + d,
-               str, font,
-               backgroundColor(),
-               backgroundColor());
-       // adding or removing space
-       bool const added = !(vsp.length().len().value() < 0.0);
-
-       int const leftx = p.xo;
-       int const midx = leftx + arrow_size;
-       int const rightx = midx + arrow_size;
+       p.pain->rectText(leftx + 2 * arrow_size + 5, 
+                        start + ((end - start) / 2) + d,
+                        str, font,
+                        backgroundColor(),
+                        backgroundColor());
+       
        // top arrow
-       int const ty1 = added ? (start + arrow_size) : start;
-       int const ty2 = added ? start : (start + arrow_size);
-
        p.pain->line(leftx, ty1, midx, ty2, LColor::added_space);
        p.pain->line(midx, ty2, rightx, ty1, LColor::added_space);
 
        // bottom arrow
-       int const by1 = added ? (end - arrow_size) : end;
-       int const by2 = added ? end : (end - arrow_size);
        p.pain->line(leftx, by1, midx, by2, LColor::added_space);
        p.pain->line(midx, by2, rightx, by1, LColor::added_space);
 
@@ -3267,27 +3316,9 @@ void LyXText::paintFirstRow(DrawRowParams & p)
                y_top += 3 * defaultHeight();
        }
        
-       // draw a vfill top
-       if (parparams.spaceTop().kind() == VSpace::VFILL) {
-               int const y1 = p.yo + y_top + 3 * defaultHeight();
-               int const y2 = p.yo + 2 + y_top;
-               p.pain->line(0, y1, LYX_PAPER_MARGIN, y1, LColor::added_space);
-               
-               p.pain->line(0, y2, LYX_PAPER_MARGIN, y2, LColor::added_space);
-
-               int const x = LYX_PAPER_MARGIN / 2;
-               p.pain->line(x, y2, x, y1, LColor::added_space);
-               
-               y_top += 3 * defaultHeight();
-               y_top += int(parparams.spaceTop().inPixels(p.bv));
-       } else if (parparams.spaceTop().kind() == VSpace::LENGTH) {
-               y_top += drawLengthMarker(p, _("Space above"),
-                       parparams.spaceTop(), p.yo + y_top);
-       } else {
-               y_top += int(parparams.spaceTop().inPixels(p.bv));
-       }
+       // draw the additional space if needed:
+       y_top += drawLengthMarker(p, _("Space above"),
+                                 parparams.spaceTop(), p.yo + y_top);
        
        Buffer const * buffer = p.bv->buffer();
  
@@ -3324,8 +3355,8 @@ void LyXText::paintFirstRow(DrawRowParams & p)
                y_top += asc;
  
                int const w = (inset_owner ?  inset_owner->width(p.bv, font) : ww);
-               int const xp = static_cast<int>(inset_owner ? p.x : 0);
-               p.pain->line(xp, p.yo + y_top, w, p.yo + y_top,
+               int const xp = static_cast<int>(inset_owner ? p.xo : 0);
+               p.pain->line(xp, p.yo + y_top, xp + w, p.yo + y_top,
                        LColor::topline, Painter::line_solid,
                        Painter::line_thick);
                
@@ -3437,7 +3468,7 @@ void LyXText::paintLastRow(DrawRowParams & p)
 {
        Paragraph * par = p.row->par();
        ParagraphParameters const & parparams = par->params();
-       int y_bottom = p.row->height();
+       int y_bottom = p.row->height() - 1;
        
        // think about the margins
        if (!p.row->next() && bv_owner)
@@ -3451,7 +3482,8 @@ void LyXText::paintLastRow(DrawRowParams & p)
                pb_font.setColor(LColor::pagebreak).decSize();
                int const y = p.yo + y_bottom - 2 * defaultHeight();
  
-               p.pain->line(p.xo, y, p.xo + p.width, y, LColor::pagebreak, Painter::line_onoffdash);
+               p.pain->line(p.xo, y, p.xo + p.width, y, LColor::pagebreak,
+                            Painter::line_onoffdash);
  
                int w = 0;
                int a = 0;
@@ -3464,28 +3496,12 @@ void LyXText::paintLastRow(DrawRowParams & p)
                y_bottom -= 3 * defaultHeight();
        }
        
-       // draw a vfill bottom
-       if (parparams.spaceBottom().kind() == VSpace::VFILL) {
-               int const x = LYX_PAPER_MARGIN / 2; 
-               int const x2 = LYX_PAPER_MARGIN;
-               int const y = p.yo + y_bottom - 3 * defaultHeight();
-               int const y2 = p.yo + y_bottom - 2;
-               
-               p.pain->line(0, y, x2, y, LColor::added_space);
-               p.pain->line(0, y2, x2, y2, LColor::added_space);
-               p.pain->line(x, y, x, y2, LColor::added_space);
-               y_bottom -= 3 * defaultHeight();
-               y_bottom -= int(parparams.spaceBottom().inPixels(p.bv));
-       } else if (parparams.spaceBottom().kind() == VSpace::LENGTH) {
-               int const height =  getLengthMarkerHeight(p.bv, parparams.spaceBottom());
-               y_bottom -= drawLengthMarker(p, _("Space below"),
-                               parparams.spaceBottom(),
-                               p.yo + y_bottom - height);
-       } else {
-               y_bottom -= int(parparams.spaceBottom().inPixels(p.bv));
-       }
+       // draw the additional space if needed:
+       int const height =  getLengthMarkerHeight(p.bv,
+                                                 parparams.spaceBottom());
+       y_bottom -= drawLengthMarker(p, _("Space below"),
+                                    parparams.spaceBottom(),
+                                    p.yo + y_bottom - height);
        
        Buffer const * buffer = p.bv->buffer();
  
@@ -3499,15 +3515,14 @@ void LyXText::paintLastRow(DrawRowParams & p)
                y_bottom -= asc;
  
                int const w = (inset_owner ?  inset_owner->width(p.bv, font) : ww);
-               int const xp = static_cast<int>(inset_owner ? p.x : 0);
+               int const xp = static_cast<int>(inset_owner ? p.xo : 0);
                int const y = p.yo + y_bottom; 
-               p.pain->line(xp, y, w, y, LColor::topline, Painter::line_solid,
+               p.pain->line(xp, y, xp + w, y, LColor::topline, Painter::line_solid,
                          Painter::line_thick);
  
                y_bottom -= asc;
        }
 
-       pos_type const last = rowLastPrintable(p.row);
        bool const is_rtl = p.row->par()->isRightToLeftPar(p.bv->buffer()->params);
        int const endlabel = par->getEndLabel(buffer->params);
  
@@ -3516,7 +3531,7 @@ void LyXText::paintLastRow(DrawRowParams & p)
        case END_LABEL_BOX:
        case END_LABEL_FILLED_BOX:
        {
-               LyXFont const font = getFont(buffer, par, last);
+               LyXFont const font = getLabelFont(buffer, par);
                int const size = int(0.75 * lyxfont::maxAscent(font));
                int const y = (p.yo + p.row->baseline()) - size;
                int x = is_rtl ? LYX_PAPER_MARGIN : ww - LYX_PAPER_MARGIN - size;
@@ -3525,12 +3540,10 @@ void LyXText::paintLastRow(DrawRowParams & p)
                        x += (size - p.row->fill() + 1) * (is_rtl ? -1 : 1);
  
                if (endlabel == END_LABEL_BOX) {
-                       p.pain->line(x, y, x, y + size, LColor::eolmarker);
-                       p.pain->line(x + size, y, x + size , y + size, LColor::eolmarker);
-                       p.pain->line(x, y, x + size, y, LColor::eolmarker);
-                       p.pain->line(x, y + size, x + size, y + size, LColor::eolmarker);
+                       p.pain->rectangle(x, y, size, size, LColor::eolmarker);
                } else {
-                       p.pain->fillRectangle(x, y, size, size, LColor::eolmarker);
+                       p.pain->fillRectangle(x, y, size, size,
+                                             LColor::eolmarker);
                }
                break;
        }