]> git.lyx.org Git - lyx.git/blobdiff - src/text.C
bug 183
[lyx.git] / src / text.C
index 3ff2676f674c226e2328ae22d3af720f9291db10..1c2e34e2ec89046956189b539bd69e2b56402bd7 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()) {
@@ -945,24 +955,25 @@ LyXText::nextBreakPoint(BufferView * bview, Row const * row, int width) const
                while (doitonetime || ((x < width) && (i < last))) {
                        doitonetime = false;
                        char const c = par->getChar(i);
+                       Inset * in = 0;
+                       if (c == Paragraph::META_INSET)
+                               in = par->getInset(i);
                        if (IsNewlineChar(c)) {
                                last_separator = i;
                                x = width; // this means break
-                       } else if (c == Paragraph::META_INSET &&
-                                  par->getInset(i)) {
-                               
+                       } else if (in && !in->isChar()) {
                                // check wether a Display() inset is
                                // valid here. if not, change it to
                                // non-display
-                               if (par->getInset(i)->display() &&
+                               if (in->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);
+                                       in->display(false);
                                        x += singleWidth(bview, par, i, c);
-                               } else if (par->getInset(i)->display() ||
-                                        par->getInset(i)->needFullRow()) {
+                               } else if (in->display() || in->needFullRow()) {
                                        // So break the line here
                                        if (i == pos) {
                                                if (pos < last-1) {
@@ -976,9 +987,19 @@ 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))
+                               if (IsLineSeparatorChar(c, in))
                                        last_separator = i;
                                x += singleWidth(bview, par, i, c);
                        }
@@ -993,8 +1014,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 +1150,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;
                }
@@ -1519,6 +1547,8 @@ void LyXText::setHeightOfRow(BufferView * bview, Row * row_ptr) const
        float x = 0;
        if (layout.margintype != MARGIN_RIGHT_ADDRESS_BOX) {
                float dummy;
+               // this IS needed
+               row_ptr->width(maxwidth);
                prepareToPrint(bview, row_ptr, x, dummy, dummy, dummy, false);
        }
        row_ptr->width(int(maxwidth + x));
@@ -1776,7 +1806,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() &&
@@ -1788,7 +1818,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
 
@@ -1907,6 +1937,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,
@@ -2048,7 +2080,7 @@ void LyXText::prepareToPrint(BufferView * bview,
        fill_separator = 0;
        fill_label_hfill = 0;
 
-        bool const is_rtl =
+       bool const is_rtl =
                row->par()->isRightToLeftPar(bview->buffer()->params);
        if (is_rtl) {
                x = (workWidth(bview) > 0)
@@ -2075,7 +2107,10 @@ void LyXText::prepareToPrint(BufferView * bview,
        if (nh) {
                if (w > 0)
                        fill_hfill = w / nh;
-       } else  {
+       // we don't have to look at the alignment if it is ALIGN_LEFT and
+       // if the row is already larger then the permitted width as then
+       // we force the LEFT_ALIGN'edness!
+       } else if (static_cast<int>(row->width()) < workWidth(bview)) {
                // is it block, flushleft or flushright? 
                // set x how you need it
                int align;
@@ -2318,9 +2353,7 @@ string const LyXText::selectNextWordToSpellcheck(BufferView * bview,
                        value += float(cursor.y())/float(height);
                        return str;
                }
-#warning Dekel please have a look on this one RTL? (Jug)
-#warning DEKEL!
-               // we have to go on checking so move cusor to the right
+               // we have to go on checking so move cusor to the next char
                if (cursor.pos() == cursor.par()->size()) {
                        if (!cursor.par()->next())
                                return str;
@@ -3160,12 +3193,12 @@ 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 = 4;
  
        LyXFont font;
        font.decSize();
@@ -3173,7 +3206,10 @@ int LyXText::getLengthMarkerHeight(BufferView * bv, VSpace const & vsp) const
                                      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);
 }
 
  
@@ -3321,8 +3357,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);
                
@@ -3481,15 +3517,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);
  
@@ -3498,7 +3533,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;
@@ -3507,12 +3542,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;
        }