]> git.lyx.org Git - lyx.git/blobdiff - src/text.C
Lars says _(_(b)) is a bug ... fix
[lyx.git] / src / text.C
index f2582dc463eb112a7a688002ec25fdaf2791ac9b..46259d4d8b7b5f20dc52bf6fc9ba559670616bea 100644 (file)
 
 #include "lyxtext.h"
 #include "lyxrow.h"
-#include "lyxtextclasslist.h"
 #include "paragraph.h"
 #include "gettext.h"
 #include "bufferparams.h"
 #include "buffer.h"
 #include "debug.h"
+#include "intl.h"
 #include "lyxrc.h"
 #include "encoding.h"
 #include "frontends/LyXView.h"
 #include "frontends/Painter.h"
 #include "frontends/font_metrics.h"
 #include "frontends/screen.h"
+#include "frontends/WorkArea.h"
 #include "bufferview_funcs.h"
 #include "BufferView.h"
 #include "language.h"
 #include "ParagraphParameters.h"
 #include "undo_funcs.h"
+#include "WordLangTuple.h"
+#include "paragraph_funcs.h"
 
 #include "insets/insetbib.h"
 #include "insets/insettext.h"
@@ -78,7 +81,7 @@ int LyXText::workWidth(BufferView * bview, Inset * inset) const
                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) {
+                       if (&(*it) == inset) {
                                par = it.getPar();
                                pos = it.getPos();
                                break;
@@ -147,12 +150,14 @@ unsigned char LyXText::transformChar(unsigned char c, Paragraph * par,
                }
 
        if (Encodings::is_arabic(next_char)) {
-               if (Encodings::is_arabic(prev_char))
+               if (Encodings::is_arabic(prev_char) &&
+                       !Encodings::is_arabic_special(prev_char))
                        return Encodings::TransformChar(c, Encodings::FORM_MEDIAL);
                else
                        return Encodings::TransformChar(c, Encodings::FORM_INITIAL);
        } else {
-               if (Encodings::is_arabic(prev_char))
+               if (Encodings::is_arabic(prev_char) &&
+                       !Encodings::is_arabic_special(prev_char))
                        return Encodings::TransformChar(c, Encodings::FORM_FINAL);
                else
                        return Encodings::TransformChar(c, Encodings::FORM_ISOLATED);
@@ -630,6 +635,8 @@ void LyXText::drawChars(DrawRowParams & p, pos_type & vpos,
                if (orig_font != getFont(p.bv->buffer(), p.row->par(), pos))
                        break;
 
+               if (arabic)
+                       c = transformChar(c, p.row->par(), pos);
                str += c;
                ++vpos;
        }
@@ -676,7 +683,7 @@ bool LyXText::draw(DrawRowParams & p, pos_type & vpos)
        if ((!hebrew && !arabic)
                || (hebrew && !Encodings::IsComposeChar_hebrew(c))
                || (arabic && !Encodings::IsComposeChar_arabic(c))) {
-               drawChars(p, vpos, true, false);
+               drawChars(p, vpos, hebrew, arabic);
        } else if (hebrew) {
                drawHebrewComposeChar(p, vpos);
        } else if (arabic) {
@@ -685,13 +692,6 @@ bool LyXText::draw(DrawRowParams & p, pos_type & vpos)
 
        drawForeignMark(p, orig_x, orig_font);
 
-#ifdef INHERIT_LANGUAGE
-#ifdef WITH_WARNINGS
-       if ((font.language() == inherit_language) ||
-               (font.language() == ignore_language))
-               lyxerr << "No this shouldn't happen!\n";
-#endif
-#endif
        return true;
 }
 
@@ -705,7 +705,7 @@ int LyXText::leftMargin(BufferView * bview, Row const * row) const
                return LYX_PAPER_MARGIN;
 
        LyXTextClass const & tclass =
-               textclasslist[bview->buffer()->params.textclass];
+               bview->buffer()->params.getLyXTextClass();
        LyXLayout_ptr const & layout = row->par()->layout();
 
        string parindent = layout->parindent;
@@ -731,8 +731,7 @@ int LyXText::leftMargin(BufferView * bview, Row const * row) const
        } else {
                // find the next level paragraph
 
-               Paragraph * newpar =
-                       row->par()->outerHook();
+               Paragraph * newpar = row->par()->outerHook();
 
                // make a corresponding row. Needed to call LeftMargin()
 
@@ -850,7 +849,7 @@ int LyXText::leftMargin(BufferView * bview, Row const * row) const
                LyXLength const len = row->par()->params().leftIndent();
                int const tw = inset_owner ?
                        inset_owner->latexTextWidth(bview) : workWidth(bview);
-               x += len.inPixels(tw, bview->text->defaultHeight());
+               x += len.inPixels(tw);
        }
 
        LyXAlignment align; // wrong type
@@ -897,7 +896,7 @@ int LyXText::rightMargin(Buffer const * buf, Row const * row) const
                (ins->needFullRow() || ins->display()))
                return LYX_PAPER_MARGIN;
 
-       LyXTextClass const & tclass = textclasslist[buf->params.textclass];
+       LyXTextClass const & tclass = buf->params.getLyXTextClass();
        LyXLayout_ptr const & layout = row->par()->layout();
 
        int x = LYX_PAPER_MARGIN
@@ -1724,12 +1723,12 @@ void LyXText::breakAgainOneRow(BufferView * bview, Row * row)
 void LyXText::breakParagraph(BufferView * bview, char keep_layout)
 {
        LyXTextClass const & tclass =
-               textclasslist[bview->buffer()->params.textclass];
+               bview->buffer()->params.getLyXTextClass();
        LyXLayout_ptr const & layout = cursor.par()->layout();
 
        // this is only allowed, if the current paragraph is not empty or caption
        // and if it has not the keepempty flag aktive
-       if ((cursor.par()->size() <= 0)
+       if (cursor.par()->empty()
           && layout->labeltype != LABEL_SENSITIVE
           && !layout->keepempty)
                return;
@@ -1754,9 +1753,9 @@ void LyXText::breakParagraph(BufferView * bview, char keep_layout)
        // breakParagraph call should return a bool if it inserts the
        // paragraph before or behind and we should react on that one
        // but we can fix this in 1.3.0 (Jug 20020509)
-       bool const isempty = (layout->keepempty && !cursor.par()->size());
-       cursor.par()->breakParagraph(bview->buffer()->params, cursor.pos(),
-                               keep_layout);
+       bool const isempty = (layout->keepempty && cursor.par()->empty());
+       ::breakParagraph(bview->buffer()->params, cursor.par(), cursor.pos(),
+                      keep_layout);
 
        // well this is the caption hack since one caption is really enough
        if (layout->labeltype == LABEL_SENSITIVE) {
@@ -1798,13 +1797,13 @@ void LyXText::breakParagraph(BufferView * bview, char keep_layout)
 
        setHeightOfRow(bview, cursor.row());
 
-       while (cursor.par()->next()->size()
+       while (!cursor.par()->next()->empty()
          && cursor.par()->next()->isNewline(0))
           cursor.par()->next()->erase(0);
 
        insertParagraph(bview, cursor.par()->next(), cursor.row());
 
-       updateCounters(bview, cursor.row()->previous());
+       updateCounters(bview);
 
        // This check is necessary. Otherwise the new empty paragraph will
        // be deleted automatically. And it is more friendly for the user!
@@ -2029,11 +2028,10 @@ void LyXText::insertChar(BufferView * bview, char c)
                // we would not get a rebreak!
                row->fill(fill(bview, row, workWidth(bview)));
        }
+
        if (c == Paragraph::META_INSET || row->fill() < 0) {
                refresh_y = y;
                refresh_row = row;
-               refresh_x = cursor.x();
-               refresh_pos = cursor.pos();
                status(bview, LyXText::NEED_MORE_REFRESH);
                breakAgainOneRow(bview, row);
                // will the cursor be in another row now?
@@ -2058,9 +2056,7 @@ void LyXText::insertChar(BufferView * bview, char c)
                        need_break_row = 0;
        } else {
                refresh_y = y;
-               refresh_x = cursor.x();
                refresh_row = row;
-               refresh_pos = cursor.pos();
 
                int const tmpheight = row->height();
                setHeightOfRow(bview, row);
@@ -2287,7 +2283,7 @@ void LyXText::cursorLeftOneWord(BufferView * bview)  const
 }
 
 
-void LyXText::cursorLeftOneWord(LyXCursor  & cur)  const
+void LyXText::cursorLeftOneWord(LyXCursor & cur) const
 {
        // treat HFills, floats and Insets as words
        cur = cursor;
@@ -2309,7 +2305,7 @@ void LyXText::cursorLeftOneWord(LyXCursor  & cur)  const
                }
        } else {                // Here, cur != 0
                while (cur.pos() > 0 &&
-                      cur.par()->isWord(cur.pos()-1))
+                      cur.par()->isWord(cur.pos() - 1))
                        cur.pos(cur.pos() - 1);
        }
 }
@@ -2327,8 +2323,8 @@ void LyXText::getWord(LyXCursor & from, LyXCursor & to,
                if (cursor.pos() == 0 || cursor.pos() == cursor.par()->size()
                    || cursor.par()->isSeparator(cursor.pos())
                    || cursor.par()->isKomma(cursor.pos())
-                   || cursor.par()->isSeparator(cursor.pos() -1)
-                   || cursor.par()->isKomma(cursor.pos() -1)) {
+                   || cursor.par()->isSeparator(cursor.pos() - 1)
+                   || cursor.par()->isKomma(cursor.pos() - 1)) {
                        to = from;
                        return;
                }
@@ -2392,19 +2388,20 @@ bool LyXText::selectWordWhenUnderCursor(BufferView * bview,
 
 // This function is only used by the spellchecker for NextWord().
 // It doesn't handle LYX_ACCENTs and probably never will.
-string const LyXText::selectNextWordToSpellcheck(BufferView * bview,
-                                                float & value) const
+WordLangTuple const
+LyXText::selectNextWordToSpellcheck(BufferView * bview, float & value) const
 {
        if (the_locking_inset) {
-               string str = the_locking_inset->selectNextWordToSpellcheck(bview, value);
-               if (!str.empty()) {
-                       value += float(cursor.y())/float(height);
-                       return str;
+               WordLangTuple word = the_locking_inset->selectNextWordToSpellcheck(bview, value);
+               if (!word.word().empty()) {
+                       value += float(cursor.y());
+                       value /= float(height);
+                       return word;
                }
-               // we have to go on checking so move cusor to the next char
+               // we have to go on checking so move cursor to the next char
                if (cursor.pos() == cursor.par()->size()) {
                        if (!cursor.par()->next())
-                               return str;
+                               return word;
                        cursor.par(cursor.par()->next());
                        cursor.pos(0);
                } else
@@ -2456,6 +2453,9 @@ string const LyXText::selectNextWordToSpellcheck(BufferView * bview,
        // Start the selection from here
        selection.cursor = cursor;
 
+       string lang_code(
+               getFont(bview->buffer(), cursor.par(), cursor.pos())
+                       .language()->code());
        // and find the end of the word (insets like optional hyphens
        // and ligature break are part of a word)
        while (cursor.pos() < cursor.par()->size()
@@ -2471,7 +2471,7 @@ string const LyXText::selectNextWordToSpellcheck(BufferView * bview,
                                str += cursor.par()->getChar(i);
                }
        }
-       return str;
+       return WordLangTuple(str, lang_code);
 }
 
 
@@ -2503,7 +2503,7 @@ void LyXText::selectSelectedWord(BufferView * bview)
 // Delete from cursor up to the end of the current or next word.
 void LyXText::deleteWordForward(BufferView * bview)
 {
-       if (!cursor.par()->size())
+       if (cursor.par()->empty())
                cursorRight(bview);
        else {
                LyXCursor tmpcursor = cursor;
@@ -2524,7 +2524,7 @@ void LyXText::deleteWordForward(BufferView * bview)
 // Delete from cursor to start of current or prior word.
 void LyXText::deleteWordBackward(BufferView * bview)
 {
-       if (!cursor.par()->size())
+       if (cursor.par()->empty())
                cursorLeft(bview);
        else {
                LyXCursor tmpcursor = cursor;
@@ -2543,7 +2543,7 @@ void LyXText::deleteWordBackward(BufferView * bview)
 // Kill to end of line.
 void LyXText::deleteLineForward(BufferView * bview)
 {
-       if (!cursor.par()->size())
+       if (cursor.par()->empty())
                // Paragraph is empty, so we just go to the right
                cursorRight(bview);
        else {
@@ -2780,7 +2780,8 @@ void LyXText::backspace(BufferView * bview)
                // different wether it is open or closed.
 
                //      Correction: Pasting is always allowed with standard-layout
-               LyXTextClass const & tclass = textclasslist[bview->buffer()->params.textclass];
+               LyXTextClass const & tclass =
+                       bview->buffer()->params.getLyXTextClass();
 
                if (cursor.par() != tmppar
                    && (cursor.par()->layout() == tmppar->layout()
@@ -2788,7 +2789,7 @@ void LyXText::backspace(BufferView * bview)
                    && cursor.par()->getAlign() == tmppar->getAlign()) {
                        removeParagraph(tmprow);
                        removeRow(tmprow);
-                       cursor.par()->pasteParagraph(bview->buffer()->params);
+                       mergeParagraph(bview->buffer()->params, cursor.par());
 
                        if (!cursor.pos() || !cursor.par()->isSeparator(cursor.pos() - 1))
                                ; //cursor.par()->insertChar(cursor.pos(), ' ');
@@ -2813,7 +2814,7 @@ void LyXText::backspace(BufferView * bview)
 
                        // This rebuilds the rows.
                        appendParagraph(bview, cursor.row());
-                       updateCounters(bview, cursor.row());
+                       updateCounters(bview);
 
                        // the row may have changed, block, hfills etc.
                        setCursor(bview, cursor.par(), cursor.pos(), false);
@@ -2893,7 +2894,7 @@ void LyXText::backspace(BufferView * bview)
                        }
 
                        // delete newlines at the beginning of paragraphs
-                       while (cursor.par()->size() &&
+                       while (!cursor.par()->empty() &&
                               cursor.par()->isNewline(cursor.pos()) &&
                               cursor.pos() == beginningOfMainBody(bview->buffer(),
                                                                   cursor.par())) {
@@ -3124,26 +3125,22 @@ void LyXText::paintRowSelection(DrawRowParams & p)
                }
                return;
        } else if (startrow != row && endrow != row) {
-               int w = p.width;
-               int h = row->height();
                if (p.y > starty && p.y < endy) {
+                       int w = p.width;
+                       int h = row->height();
                        p.pain->fillRectangle(p.xo, p.yo, w, h, LColor::selection);
                }
                return;
        }
 
-       if (!((startrow != row && !is_rtl) || (endrow != row && is_rtl))) {
-               return;
-       }
-
-       float tmpx = p.x;
-
-       p.pain->fillRectangle(p.xo, p.yo, int(p.x), row->height(), LColor::selection);
+       if ((startrow != row && !is_rtl) || (endrow != row && is_rtl))
+               p.pain->fillRectangle(p.xo, p.yo, int(p.x), row->height(), LColor::selection);
 
        Buffer const * buffer = p.bv->buffer();
        Paragraph * par = row->par();
        pos_type main_body = beginningOfMainBody(buffer, par);
        pos_type const last = rowLastPrintable(row);
+       float tmpx = p.x;
 
        for (pos_type vpos = row->pos(); vpos <= last; ++vpos)  {
                pos_type pos = vis2log(vpos);
@@ -3181,12 +3178,12 @@ void LyXText::paintRowSelection(DrawRowParams & p)
                                int(tmpx - old_tmpx + 1),
                                row->height(), LColor::selection);
                }
+       }
 
-               if ((startrow != row && is_rtl) || (endrow != row && !is_rtl)) {
-                       p.pain->fillRectangle(p.xo + int(tmpx),
-                               p.yo, int(p.bv->workWidth() - tmpx),
-                               row->height(), LColor::selection);
-               }
+       if ((startrow != row && is_rtl) || (endrow != row && !is_rtl)) {
+               p.pain->fillRectangle(p.xo + int(tmpx),
+                                     p.yo, int(p.bv->workWidth() - tmpx),
+                                     row->height(), LColor::selection);
        }
 }
 
@@ -3274,7 +3271,7 @@ int LyXText::drawLengthMarker(DrawRowParams & p, string const & prefix,
        switch (vsp.kind()) {
        case VSpace::LENGTH:
        {
-               str = prefix + " (" + vsp.asLyXCommand() + ")";
+               str = prefix + " (" + vsp.asLyXCommand() + ')';
                // adding or removing space
                bool const added = !(vsp.length().len().value() < 0.0);
                ty1 = added ? (start + arrow_size) : start;
@@ -3283,8 +3280,8 @@ int LyXText::drawLengthMarker(DrawRowParams & p, string const & prefix,
                by2 = added ? end : (end - arrow_size);
                break;
        }
-       case VSpace:: VFILL:
-               str = prefix + " (vertical fill)";
+       case VSpace::VFILL:
+               str = prefix + _(" (vertical fill)");
                ty1 = ty2 = start;
                by1 = by2 = end;
                break;
@@ -3308,9 +3305,7 @@ int LyXText::drawLengthMarker(DrawRowParams & p, string const & prefix,
 
        p.pain->rectText(leftx + 2 * arrow_size + 5,
                         start + ((end - start) / 2) + d,
-                        str, font,
-                        backgroundColor(),
-                        backgroundColor());
+                        str, font);
 
        // top arrow
        p.pain->line(leftx, ty1, midx, ty2, LColor::added_space);
@@ -3327,6 +3322,30 @@ int LyXText::drawLengthMarker(DrawRowParams & p, string const & prefix,
 }
 
 
+int LyXText::paintPageBreak(string const & label, int y, DrawRowParams & p)
+{
+       LyXFont pb_font;
+       pb_font.setColor(LColor::pagebreak).decSize();
+
+       int w = 0;
+       int a = 0;
+       int d = 0;
+       font_metrics::rectText(label, pb_font, w, a, d);
+
+       int const text_start = p.xo + ((p.width - w) / 2);
+       int const text_end = text_start + w;
+
+       p.pain->rectText(text_start, y + d, label, pb_font);
+
+       p.pain->line(p.xo, y, text_start, y,
+               LColor::pagebreak, Painter::line_onoffdash);
+       p.pain->line(text_end, y, p.xo + p.width, y,
+               LColor::pagebreak, Painter::line_onoffdash);
+
+       return 3 * defaultHeight();
+}
+
+
 void LyXText::paintFirstRow(DrawRowParams & p)
 {
        Paragraph * par = p.row->par();
@@ -3345,22 +3364,8 @@ void LyXText::paintFirstRow(DrawRowParams & p)
 
        // draw a top pagebreak
        if (parparams.pagebreakTop()) {
-               int const y = p.yo + y_top + 2*defaultHeight();
-               p.pain->line(p.xo, y, p.xo + p.width, y,
-                       LColor::pagebreak, Painter::line_onoffdash);
-
-               int w = 0;
-               int a = 0;
-               int d = 0;
-
-               LyXFont pb_font;
-               pb_font.setColor(LColor::pagebreak).decSize();
-               font_metrics::rectText(_("Page Break (top)"), pb_font, w, a, d);
-               p.pain->rectText((p.width - w)/2, y + d,
-                             _("Page Break (top)"), pb_font,
-                             backgroundColor(),
-                             backgroundColor());
-               y_top += 3 * defaultHeight();
+               y_top += paintPageBreak(_("Page Break (top)"),
+                       p.yo + y_top + 2 * defaultHeight(), p);
        }
 
        // draw the additional space if needed:
@@ -3523,22 +3528,8 @@ void LyXText::paintLastRow(DrawRowParams & p)
 
        // draw a bottom pagebreak
        if (parparams.pagebreakBottom()) {
-               LyXFont pb_font;
-               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);
-
-               int w = 0;
-               int a = 0;
-               int d = 0;
-               font_metrics::rectText(_("Page Break (bottom)"), pb_font, w, a, d);
-               p.pain->rectText((ww - w) / 2, y + d,
-                       _("Page Break (bottom)"),
-                       pb_font, backgroundColor(), backgroundColor());
-
-               y_bottom -= 3 * defaultHeight();
+               y_bottom -= paintPageBreak(_("Page Break (bottom)"),
+                       p.yo + y_bottom - 2 * defaultHeight(), p);
        }
 
        // draw the additional space if needed:
@@ -3612,6 +3603,7 @@ void LyXText::paintLastRow(DrawRowParams & p)
        }
 }
 
+
 void LyXText::paintRowText(DrawRowParams & p)
 {
        Paragraph * par = p.row->par();
@@ -3796,7 +3788,7 @@ LyXText::getColumnNearX(BufferView * bview, Row * row, int & x,
                }
 
                if (hfillExpansion(bview->buffer(), row, c)) {
-                       x += singleWidth(bview, row->par(), c);
+                       tmpx += singleWidth(bview, row->par(), c);
                        if (c >= main_body)
                                tmpx += fill_hfill;
                        else