]> git.lyx.org Git - lyx.git/blobdiff - src/Paragraph.cpp
Remove background_color_ in Insets: it takes a lot of unnecessary memory,
[lyx.git] / src / Paragraph.cpp
index 232515060eb9552a8dbb617dc194088729c88f6a..cf09a491b1e17d01a9aba6ca27fa1dfe8c31e707 100644 (file)
@@ -27,9 +27,9 @@
 #include "gettext.h"
 #include "Language.h"
 #include "LaTeXFeatures.h"
-#include "LColor.h"
-#include "LyXLength.h"
-#include "LyXFont.h"
+#include "Color.h"
+#include "Length.h"
+#include "Font.h"
 #include "LyXRC.h"
 #include "Row.h"
 #include "Messages.h"
@@ -76,7 +76,7 @@ using support::rsplit;
 /////////////////////////////////////////////////////////////////////
 
 class Encoding;
-class LyXLayout;
+class Layout;
 
 
 class Paragraph::Pimpl {
@@ -110,13 +110,13 @@ public:
        ///
        void insertChar(pos_type pos, value_type c, Change const & change);
        ///
-       void insertInset(pos_type pos, InsetBase * inset, Change const & change);
+       void insertInset(pos_type pos, Inset * inset, Change const & change);
        /// (logically) erase the char at pos; return true if it was actually erased
        bool eraseChar(pos_type pos, bool trackChanges);
        /// (logically) erase the given range; return the number of chars actually erased
        int eraseChars(pos_type start, pos_type end, bool trackChanges);
        ///
-       InsetBase * inset_owner;
+       Inset * inset_owner;
 
        /** A font entry covers a range of positions. Notice that the
            entries in the list are inserted in random order.
@@ -132,7 +132,7 @@ public:
        class FontTable  {
        public:
                ///
-               FontTable(pos_type p, LyXFont const & f)
+               FontTable(pos_type p, Font const & f)
                        : pos_(p), font_(f)
                {}
                ///
@@ -140,22 +140,22 @@ public:
                ///
                void pos(pos_type p) { pos_ = p; }
                ///
-               LyXFont const & font() const { return font_; }
+               Font const & font() const { return font_; }
                ///
-               void font(LyXFont const & f) { font_ = f;}
+               void font(Font const & f) { font_ = f;}
        private:
                /// End position of paragraph this font attribute covers
                pos_type pos_;
                /** Font. Interpretation of the font values:
-                   If a value is LyXFont::INHERIT_*, it means that the font
+                   If a value is Font::INHERIT_*, it means that the font
                    attribute is inherited from either the layout of this
                    paragraph or, in the case of nested paragraphs, from the
                    layout in the environment one level up until completely
                    resolved.
-                   The values LyXFont::IGNORE_* and LyXFont::TOGGLE are NOT
+                   The values Font::IGNORE_* and Font::TOGGLE are NOT
                    allowed in these font tables.
                */
-               LyXFont font_;
+               Font font_;
        };
        ///
        friend class matchFT;
@@ -176,32 +176,32 @@ public:
        /// Output the surrogate pair formed by \p c and \p next to \p os.
        /// \return the number of characters written.
        int latexSurrogatePair(odocstream & os, value_type c, value_type next,
-                              Encoding const &);
+                              Encoding const &);
        /// Output a space in appropriate formatting (or a surrogate pair
        /// if the next character is a combining character).
        /// \return whether a surrogate pair was output.
        bool simpleTeXBlanks(Encoding const &,
-                            odocstream &, TexRow & texrow,
+                            odocstream &, TexRow & texrow,
                             pos_type & i,
                             unsigned int & column,
-                            LyXFont const & font,
-                            LyXLayout const & style);
+                            Font const & font,
+                            Layout const & style);
        ///
        void simpleTeXSpecialChars(Buffer const &, BufferParams const &,
-                                  odocstream &,
-                                  TexRow & texrow, OutputParams const &,
-                                  LyXFont & running_font,
-                                  LyXFont & basefont,
-                                  LyXFont const & outerfont,
+                                  odocstream &,
+                                  TexRow & texrow, OutputParams const &,
+                                  Font & running_font,
+                                  Font & basefont,
+                                  Font const & outerfont,
                                   bool & open_font,
-                                  Change::Type & running_change,
-                                  LyXLayout const & style,
+                                  Change & running_change,
+                                  Layout const & style,
                                   pos_type & i,
                                   unsigned int & column, value_type const c);
 
        ///
        void validate(LaTeXFeatures & features,
-                     LyXLayout const & layout) const;
+                     Layout const & layout) const;
 
        ///
        unsigned int id_;
@@ -444,8 +444,8 @@ void Paragraph::Pimpl::insertChar(pos_type pos, value_type c, Change const & cha
        owner_->text_.insert(owner_->text_.begin() + pos, c);
 
        // Update the font table.
-       FontTable search_font(pos, LyXFont());
-       for (FontList::iterator it 
+       FontTable search_font(pos, Font());
+       for (FontList::iterator it
              = lower_bound(fontlist.begin(), fontlist.end(), search_font, matchFT());
             it != fontlist.end(); ++it)
        {
@@ -457,8 +457,8 @@ void Paragraph::Pimpl::insertChar(pos_type pos, value_type c, Change const & cha
 }
 
 
-void Paragraph::Pimpl::insertInset(pos_type pos, InsetBase * inset,
-                                   Change const & change)
+void Paragraph::Pimpl::insertInset(pos_type pos, Inset * inset,
+                                  Change const & change)
 {
        BOOST_ASSERT(inset);
        BOOST_ASSERT(pos >= 0 && pos <= size());
@@ -480,7 +480,7 @@ bool Paragraph::Pimpl::eraseChar(pos_type pos, bool trackChanges)
        if (trackChanges) {
                Change change = changes_.lookup(pos);
 
-               // set the character to DELETED if 
+               // set the character to DELETED if
                //  a) it was previously unchanged or
                //  b) it was inserted by a co-author
 
@@ -512,7 +512,7 @@ bool Paragraph::Pimpl::eraseChar(pos_type pos, bool trackChanges)
        owner_->text_.erase(owner_->text_.begin() + pos);
 
        // Erase entries in the tables.
-       FontTable search_font(pos, LyXFont());
+       FontTable search_font(pos, Font());
 
        FontList::iterator it =
                lower_bound(fontlist.begin(),
@@ -580,11 +580,11 @@ int Paragraph::Pimpl::latexSurrogatePair(odocstream & os, value_type c,
 
 
 bool Paragraph::Pimpl::simpleTeXBlanks(Encoding const & encoding,
-                                       odocstream & os, TexRow & texrow,
-                                       pos_type & i,
+                                      odocstream & os, TexRow & texrow,
+                                      pos_type & i,
                                       unsigned int & column,
-                                      LyXFont const & font,
-                                      LyXLayout const & style)
+                                      Font const & font,
+                                      Layout const & style)
 {
        if (style.pass_thru)
                return false;
@@ -608,7 +608,7 @@ bool Paragraph::Pimpl::simpleTeXBlanks(Encoding const & encoding,
            && !owner_->isFreeSpacing()
            // In typewriter mode, we want to avoid
            // ! . ? : at the end of a line
-           && !(font.family() == LyXFont::TYPEWRITER_FAMILY
+           && !(font.family() == Font::TYPEWRITER_FAMILY
                 && (getChar(i - 1) == '.'
                     || getChar(i - 1) == '?'
                     || getChar(i - 1) == ':'
@@ -661,12 +661,12 @@ void Paragraph::Pimpl::simpleTeXSpecialChars(Buffer const & buf,
                                             odocstream & os,
                                             TexRow & texrow,
                                             OutputParams const & runparams,
-                                            LyXFont & running_font,
-                                            LyXFont & basefont,
-                                            LyXFont const & outerfont,
+                                            Font & running_font,
+                                            Font & basefont,
+                                            Font const & outerfont,
                                             bool & open_font,
-                                            Change::Type & running_change,
-                                            LyXLayout const & style,
+                                            Change & running_change,
+                                            Layout const & style,
                                             pos_type & i,
                                             unsigned int & column,
                                             value_type const c)
@@ -687,14 +687,14 @@ void Paragraph::Pimpl::simpleTeXSpecialChars(Buffer const & buf,
        // and then split to handle the two modes separately.
        switch (c) {
        case Paragraph::META_INSET: {
-               InsetBase * inset = owner_->getInset(i);
+               Inset * inset = owner_->getInset(i);
 
                // FIXME: remove this check
                if (!inset)
                        break;
 
                // FIXME: move this to InsetNewline::latex
-               if (inset->lyxCode() == InsetBase::NEWLINE_CODE) {
+               if (inset->lyxCode() == Inset::NEWLINE_CODE) {
                        // newlines are handled differently here than
                        // the default in simpleTeXSpecialChars().
                        if (!style.newline_allowed) {
@@ -702,11 +702,12 @@ void Paragraph::Pimpl::simpleTeXSpecialChars(Buffer const & buf,
                        } else {
                                if (open_font) {
                                        column += running_font.latexWriteEndChanges(
-                                               os, basefont, basefont);
+                                               os, bparams, runparams,
+                                               basefont, basefont);
                                        open_font = false;
                                }
 
-                               if (running_font.family() == LyXFont::TYPEWRITER_FAMILY)
+                               if (running_font.family() == Font::TYPEWRITER_FAMILY)
                                        os << '~';
 
                                basefont = owner_->getLayoutFont(bparams, outerfont);
@@ -723,28 +724,23 @@ void Paragraph::Pimpl::simpleTeXSpecialChars(Buffer const & buf,
                        break;
                }
 
-               // output change tracking marks only if desired,
-               // if dvipost is installed,
-               // and with dvi/ps (other formats don't work)
-               LaTeXFeatures features(buf, bparams, runparams);
-               bool const output = bparams.outputChanges
-                       && runparams.flavor == OutputParams::LATEX
-                       && features.isAvailable("dvipost");
-
                if (inset->canTrackChanges()) {
-                       column += Changes::latexMarkChange(os, running_change,
-                               Change::UNCHANGED, output);
-                       running_change = Change::UNCHANGED;
+                       column += Changes::latexMarkChange(os, bparams, running_change,
+                               Change(Change::UNCHANGED));
+                       running_change = Change(Change::UNCHANGED);
                }
 
                bool close = false;
                odocstream::pos_type const len = os.tellp();
 
-               if ((inset->lyxCode() == InsetBase::GRAPHICS_CODE
-                    || inset->lyxCode() == InsetBase::MATH_CODE
-                    || inset->lyxCode() == InsetBase::URL_CODE)
+               if ((inset->lyxCode() == Inset::GRAPHICS_CODE
+                    || inset->lyxCode() == Inset::MATH_CODE
+                    || inset->lyxCode() == Inset::URL_CODE)
                    && running_font.isRightToLeft()) {
-                       os << "\\L{";
+                       if (running_font.language()->lang() == "farsi")
+                               os << "\\beginL{}";
+                       else
+                               os << "\\L{";
                        close = true;
                }
 
@@ -757,7 +753,8 @@ void Paragraph::Pimpl::simpleTeXSpecialChars(Buffer const & buf,
                // some insets cannot be inside a font change command
                if (open_font && inset->noFontChange()) {
                        column += running_font.latexWriteEndChanges(
-                                       os, basefont, basefont);
+                                       os, bparams, runparams,
+                                               basefont, basefont);
                        open_font = false;
                        basefont = owner_->getLayoutFont(bparams, outerfont);
                        running_font = basefont;
@@ -765,8 +762,12 @@ void Paragraph::Pimpl::simpleTeXSpecialChars(Buffer const & buf,
 
                int tmp = inset->latex(buf, os, runparams);
 
-               if (close)
-                       os << '}';
+               if (close) {
+                       if (running_font.language()->lang() == "farsi")
+                               os << "\\endL{}";
+                       else
+                               os << '}';
+               }
 
                if (tmp) {
                        for (int j = 0; j < tmp; ++j) {
@@ -789,10 +790,6 @@ void Paragraph::Pimpl::simpleTeXSpecialChars(Buffer const & buf,
                        column += 15;
                        break;
 
-               // The following characters could be written literally in latin1, but they
-               // would be wrongly converted on systems where char is signed, so we give
-               // the code points.
-               // This also makes us independant from the encoding of this source file.
                case '|': case '<': case '>':
                        // In T1 encoding, these characters exist
                        if (lyxrc.fontenc == "T1") {
@@ -813,7 +810,7 @@ void Paragraph::Pimpl::simpleTeXSpecialChars(Buffer const & buf,
                                break;
                        }
                        // Typewriter font also has them
-                       if (running_font.family() == LyXFont::TYPEWRITER_FAMILY) {
+                       if (running_font.family() == Font::TYPEWRITER_FAMILY) {
                                os.put(c);
                                break;
                        }
@@ -838,7 +835,7 @@ void Paragraph::Pimpl::simpleTeXSpecialChars(Buffer const & buf,
                case '-': // "--" in Typewriter mode -> "-{}-"
                        if (i <= size() - 2 &&
                            getChar(i + 1) == '-' &&
-                           running_font.family() == LyXFont::TYPEWRITER_FAMILY) {
+                           running_font.family() == Font::TYPEWRITER_FAMILY) {
                                os << "-{}";
                                column += 2;
                        } else {
@@ -890,7 +887,7 @@ void Paragraph::Pimpl::simpleTeXSpecialChars(Buffer const & buf,
                        // I assume this is hack treating typewriter as verbatim
                        // FIXME UNICODE: This can fail if c cannot be encoded
                        // in the current encoding.
-                       if (running_font.family() == LyXFont::TYPEWRITER_FAMILY) {
+                       if (running_font.family() == Font::TYPEWRITER_FAMILY) {
                                if (c != '\0') {
                                        os.put(c);
                                }
@@ -946,7 +943,7 @@ void Paragraph::Pimpl::simpleTeXSpecialChars(Buffer const & buf,
 
 
 void Paragraph::Pimpl::validate(LaTeXFeatures & features,
-                               LyXLayout const & layout) const
+                               Layout const & layout) const
 {
        BufferParams const & bparams = features.bufferParams();
 
@@ -963,7 +960,7 @@ void Paragraph::Pimpl::validate(LaTeXFeatures & features,
        FontList::const_iterator fcit = fontlist.begin();
        FontList::const_iterator fend = fontlist.end();
        for (; fcit != fend; ++fcit) {
-               if (fcit->font().noun() == LyXFont::ON) {
+               if (fcit->font().noun() == Font::ON) {
                        LYXERR(Debug::LATEX) << "font.noun: "
                                             << fcit->font().noun()
                                             << endl;
@@ -973,13 +970,13 @@ void Paragraph::Pimpl::validate(LaTeXFeatures & features,
                                             << endl;
                }
                switch (fcit->font().color()) {
-               case LColor::none:
-               case LColor::inherit:
-               case LColor::ignore:
+               case Color::none:
+               case Color::inherit:
+               case Color::ignore:
                        // probably we should put here all interface colors used for
                        // font displaying! For now I just add this ones I know of (Jug)
-               case LColor::latex:
-               case LColor::note:
+               case Color::latex:
+               case Color::note:
                        break;
                default:
                        features.require("color");
@@ -995,7 +992,7 @@ void Paragraph::Pimpl::validate(LaTeXFeatures & features,
                {
                        features.useLanguage(language);
                        LYXERR(Debug::LATEX) << "Found language "
-                                            << language->babel() << endl;
+                                            << language->lang() << endl;
                }
        }
 
@@ -1009,7 +1006,7 @@ void Paragraph::Pimpl::validate(LaTeXFeatures & features,
                if (icit->inset) {
                        icit->inset->validate(features);
                        if (layout.needprotect &&
-                           icit->inset->lyxCode() == InsetBase::FOOT_CODE)
+                           icit->inset->lyxCode() == Inset::FOOT_CODE)
                                features.require("NeedLyXFootnoteCode");
                }
        }
@@ -1117,7 +1114,7 @@ void Paragraph::write(Buffer const & buf, ostream & os,
 
        params().write(os);
 
-       LyXFont font1(LyXFont::ALL_INHERIT, bparams.language);
+       Font font1(Font::ALL_INHERIT, bparams.language);
 
        Change running_change = Change(Change::UNCHANGED);
 
@@ -1132,7 +1129,7 @@ void Paragraph::write(Buffer const & buf, ostream & os,
                        break;
 
                // Write font changes
-               LyXFont font2 = getFontSettings(bparams, i);
+               Font font2 = getFontSettings(bparams, i);
                if (font2 != font1) {
                        font2.lyxWriteChanges(font1, os);
                        column = 0;
@@ -1143,7 +1140,7 @@ void Paragraph::write(Buffer const & buf, ostream & os,
                switch (c) {
                case META_INSET:
                {
-                       InsetBase const * inset = getInset(i);
+                       Inset const * inset = getInset(i);
                        if (inset)
                                if (inset->directWrite()) {
                                        // international char, let it write
@@ -1214,7 +1211,7 @@ int Paragraph::eraseChars(pos_type start, pos_type end, bool trackChanges)
 
 
 void Paragraph::insert(pos_type start, docstring const & str,
-                       LyXFont const & font, Change const & change)
+                      Font const & font, Change const & change)
 {
        for (size_t i = 0, n = str.size(); i != n ; ++i)
                insertChar(start + i, str[i], font, change);
@@ -1222,53 +1219,53 @@ void Paragraph::insert(pos_type start, docstring const & str,
 
 
 void Paragraph::insertChar(pos_type pos, Paragraph::value_type c,
-                           bool trackChanges)
+                          bool trackChanges)
 {
        pimpl_->insertChar(pos, c, Change(trackChanges ?
-                          Change::INSERTED : Change::UNCHANGED));
+                          Change::INSERTED : Change::UNCHANGED));
 }
 
 
 void Paragraph::insertChar(pos_type pos, Paragraph::value_type c,
-                           LyXFont const & font, bool trackChanges)
+                          Font const & font, bool trackChanges)
 {
        pimpl_->insertChar(pos, c, Change(trackChanges ?
-                          Change::INSERTED : Change::UNCHANGED));
+                          Change::INSERTED : Change::UNCHANGED));
        setFont(pos, font);
 }
 
 
 void Paragraph::insertChar(pos_type pos, Paragraph::value_type c,
-                           LyXFont const & font, Change const & change)
+                          Font const & font, Change const & change)
 {
        pimpl_->insertChar(pos, c, change);
        setFont(pos, font);
 }
 
 
-void Paragraph::insertInset(pos_type pos, InsetBase * inset,
-                            Change const & change)
+void Paragraph::insertInset(pos_type pos, Inset * inset,
+                           Change const & change)
 {
        pimpl_->insertInset(pos, inset, change);
 }
 
 
-void Paragraph::insertInset(pos_type pos, InsetBase * inset,
-                            LyXFont const & font, Change const & change)
+void Paragraph::insertInset(pos_type pos, Inset * inset,
+                           Font const & font, Change const & change)
 {
        pimpl_->insertInset(pos, inset, change);
        setFont(pos, font);
 }
 
 
-bool Paragraph::insetAllowed(InsetBase_code code)
+bool Paragraph::insetAllowed(Inset_code code)
 {
        return !pimpl_->inset_owner || pimpl_->inset_owner->insetAllowed(code);
 }
 
 
 // Gets uninstantiated font setting at position.
-LyXFont const Paragraph::getFontSettings(BufferParams const & bparams,
+Font const Paragraph::getFontSettings(BufferParams const & bparams,
                                         pos_type pos) const
 {
        if (pos > size()) {
@@ -1288,7 +1285,7 @@ LyXFont const Paragraph::getFontSettings(BufferParams const & bparams,
        if (pos == size() && !empty())
                return getFontSettings(bparams, pos - 1);
 
-       return LyXFont(LyXFont::ALL_INHERIT, getParLanguage(bparams));
+       return Font(Font::ALL_INHERIT, getParLanguage(bparams));
 }
 
 
@@ -1320,36 +1317,36 @@ FontSpan Paragraph::fontSpan(pos_type pos) const
 
 
 // Gets uninstantiated font setting at position 0
-LyXFont const Paragraph::getFirstFontSettings(BufferParams const & bparams) const
+Font const Paragraph::getFirstFontSettings(BufferParams const & bparams) const
 {
        if (!empty() && !pimpl_->fontlist.empty())
                return pimpl_->fontlist[0].font();
 
-       return LyXFont(LyXFont::ALL_INHERIT, bparams.language);
+       return Font(Font::ALL_INHERIT, bparams.language);
 }
 
 
 // Gets the fully instantiated font at a given position in a paragraph
-// This is basically the same function as LyXText::GetFont() in text2.cpp.
+// This is basically the same function as Text::GetFont() in text2.cpp.
 // The difference is that this one is used for generating the LaTeX file,
 // and thus cosmetic "improvements" are disallowed: This has to deliver
 // the true picture of the buffer. (Asger)
-LyXFont const Paragraph::getFont(BufferParams const & bparams, pos_type pos,
-                                LyXFont const & outerfont) const
+Font const Paragraph::getFont(BufferParams const & bparams, pos_type pos,
+                                Font const & outerfont) const
 {
        BOOST_ASSERT(pos >= 0);
 
-       LyXLayout_ptr const & lout = layout();
+       Layout_ptr const & lout = layout();
 
        pos_type const body_pos = beginOfBody();
 
-       LyXFont layoutfont;
+       Font layoutfont;
        if (pos < body_pos)
                layoutfont = lout->labelfont;
        else
                layoutfont = lout->font;
 
-       LyXFont font = getFontSettings(bparams, pos);
+       Font font = getFontSettings(bparams, pos);
        font.realize(layoutfont);
        font.realize(outerfont);
        font.realize(bparams.getFont());
@@ -1358,10 +1355,10 @@ LyXFont const Paragraph::getFont(BufferParams const & bparams, pos_type pos,
 }
 
 
-LyXFont const Paragraph::getLabelFont
-       (BufferParams const & bparams, LyXFont const & outerfont) const
+Font const Paragraph::getLabelFont
+       (BufferParams const & bparams, Font const & outerfont) const
 {
-       LyXFont tmpfont = layout()->labelfont;
+       Font tmpfont = layout()->labelfont;
        tmpfont.setLanguage(getParLanguage(bparams));
        tmpfont.realize(outerfont);
        tmpfont.realize(bparams.getFont());
@@ -1369,10 +1366,10 @@ LyXFont const Paragraph::getLabelFont
 }
 
 
-LyXFont const Paragraph::getLayoutFont
-       (BufferParams const & bparams, LyXFont const & outerfont) const
+Font const Paragraph::getLayoutFont
+       (BufferParams const & bparams, Font const & outerfont) const
 {
-       LyXFont tmpfont = layout()->font;
+       Font tmpfont = layout()->font;
        tmpfont.setLanguage(getParLanguage(bparams));
        tmpfont.realize(outerfont);
        tmpfont.realize(bparams.getFont());
@@ -1381,8 +1378,8 @@ LyXFont const Paragraph::getLayoutFont
 
 
 /// Returns the height of the highest font in range
-LyXFont_size Paragraph::highestFontInRange
-       (pos_type startpos, pos_type endpos, LyXFont_size def_size) const
+Font_size Paragraph::highestFontInRange
+       (pos_type startpos, pos_type endpos, Font_size def_size) const
 {
        if (pimpl_->fontlist.empty())
                return def_size;
@@ -1403,12 +1400,12 @@ LyXFont_size Paragraph::highestFontInRange
                        break;
        }
 
-       LyXFont::FONT_SIZE maxsize = LyXFont::SIZE_TINY;
+       Font::FONT_SIZE maxsize = Font::SIZE_TINY;
        for (; cit != end_it; ++cit) {
-               LyXFont::FONT_SIZE size = cit->font().size();
-               if (size == LyXFont::INHERIT_SIZE)
+               Font::FONT_SIZE size = cit->font().size();
+               if (size == Font::INHERIT_SIZE)
                        size = def_size;
-               if (size > maxsize && size <= LyXFont::SIZE_HUGER)
+               if (size > maxsize && size <= Font::SIZE_HUGER)
                        maxsize = size;
        }
        return maxsize;
@@ -1456,7 +1453,7 @@ Paragraph::getUChar(BufferParams const & bparams, pos_type pos) const
 }
 
 
-void Paragraph::setFont(pos_type pos, LyXFont const & font)
+void Paragraph::setFont(pos_type pos, Font const & font)
 {
        BOOST_ASSERT(pos <= size());
 
@@ -1612,10 +1609,10 @@ docstring const Paragraph::translateIfPossible(docstring const & s,
 }
 
 
-docstring Paragraph::expandLabel(LyXLayout_ptr const & layout,
+docstring Paragraph::expandLabel(Layout_ptr const & layout,
                BufferParams const & bparams, bool process_appendix) const
 {
-       LyXTextClass const & tclass = bparams.getLyXTextClass();
+       TextClass const & tclass = bparams.getTextClass();
 
        docstring fmt;
        if (process_appendix && params().appendix())
@@ -1641,7 +1638,7 @@ docstring Paragraph::expandLabel(LyXLayout_ptr const & layout,
 }
 
 
-void Paragraph::applyLayout(LyXLayout_ptr const & new_layout)
+void Paragraph::applyLayout(Layout_ptr const & new_layout)
 {
        layout(new_layout);
        params().labelWidthString(docstring());
@@ -1692,7 +1689,7 @@ void Paragraph::setBeginOfBody()
 
 
 // returns -1 if inset not found
-int Paragraph::getPositionOfInset(InsetBase const * inset) const
+int Paragraph::getPositionOfInset(Inset const * inset) const
 {
        // Find the entry.
        InsetList::const_iterator it = insetlist.begin();
@@ -1707,8 +1704,8 @@ int Paragraph::getPositionOfInset(InsetBase const * inset) const
 InsetBibitem * Paragraph::bibitem() const
 {
        if (!insetlist.empty()) {
-               InsetBase * inset = insetlist.begin()->inset;
-               if (inset->lyxCode() == InsetBase::BIBITEM_CODE)
+               Inset * inset = insetlist.begin()->inset;
+               if (inset->lyxCode() == Inset::BIBITEM_CODE)
                        return static_cast<InsetBibitem *>(inset);
        }
        return 0;
@@ -1726,9 +1723,9 @@ namespace {
 // paragraphs inside floats need different alignment tags to avoid
 // unwanted space
 
-bool noTrivlistCentering(InsetBase::Code code)
+bool noTrivlistCentering(Inset::Code code)
 {
-       return code == InsetBase::FLOAT_CODE || code == InsetBase::WRAP_CODE;
+       return code == Inset::FLOAT_CODE || code == Inset::WRAP_CODE;
 }
 
 
@@ -1745,7 +1742,7 @@ string correction(string const & orig)
 
 
 string const corrected_env(string const & suffix, string const & env,
-       InsetBase::Code code)
+       Inset::Code code)
 {
        string output = suffix + "{";
        if (noTrivlistCentering(code))
@@ -1775,7 +1772,7 @@ void adjust_row_column(string const & str, TexRow & texrow, int & column)
 
 // This could go to ParagraphParameters if we want to
 int Paragraph::startTeXParParams(BufferParams const & bparams,
-                                 odocstream & os, TexRow & texrow, 
+                                odocstream & os, TexRow & texrow,
                                 bool moving_arg) const
 {
        int column = 0;
@@ -1839,8 +1836,8 @@ int Paragraph::startTeXParParams(BufferParams const & bparams,
 
 
 // This could go to ParagraphParameters if we want to
-int Paragraph::endTeXParParams(BufferParams const & bparams,  
-                               odocstream & os, TexRow & texrow,
+int Paragraph::endTeXParParams(BufferParams const & bparams,
+                              odocstream & os, TexRow & texrow,
                               bool moving_arg) const
 {
        int column = 0;
@@ -1901,7 +1898,7 @@ int Paragraph::endTeXParParams(BufferParams const & bparams,
 // This one spits out the text of the paragraph
 bool Paragraph::simpleTeXOnePar(Buffer const & buf,
                                BufferParams const & bparams,
-                               LyXFont const & outerfont,
+                               Font const & outerfont,
                                odocstream & os, TexRow & texrow,
                                OutputParams const & runparams) const
 {
@@ -1909,7 +1906,7 @@ bool Paragraph::simpleTeXOnePar(Buffer const & buf,
 
        bool return_value = false;
 
-       LyXLayout_ptr style;
+       Layout_ptr style;
 
        // well we have to check if we are in an inset with unlimited
        // length (all in one row) if that is true then we don't allow
@@ -1919,7 +1916,7 @@ bool Paragraph::simpleTeXOnePar(Buffer const & buf,
        bool asdefault = forceDefaultParagraphs();
 
        if (asdefault) {
-               style = bparams.getLyXTextClass().defaultLayout();
+               style = bparams.getTextClass().defaultLayout();
        } else {
                style = layout();
        }
@@ -1930,14 +1927,7 @@ bool Paragraph::simpleTeXOnePar(Buffer const & buf,
        // As long as we are in the label, this font is the base font of the
        // label. Before the first body character it is set to the base font
        // of the body.
-       LyXFont basefont;
-
-       // output change tracking marks only if desired,
-       // if dvipost is installed,
-       // and with dvi/ps (other formats don't work)
-       bool const output = bparams.outputChanges
-               && runparams.flavor == OutputParams::LATEX
-               && LaTeXFeatures::isAvailable("dvipost");
+       Font basefont;
 
        // Maybe we have to create a optional argument.
        pos_type body_pos = beginOfBody();
@@ -1954,11 +1944,11 @@ bool Paragraph::simpleTeXOnePar(Buffer const & buf,
        }
 
        // Which font is currently active?
-       LyXFont running_font(basefont);
+       Font running_font(basefont);
        // Do we have an open font change?
        bool open_font = false;
 
-       Change::Type runningChangeType = Change::UNCHANGED;
+       Change runningChange = Change(Change::UNCHANGED);
 
        texrow.start(id(), 0);
 
@@ -1979,15 +1969,16 @@ bool Paragraph::simpleTeXOnePar(Buffer const & buf,
                        if (body_pos > 0) {
                                if (open_font) {
                                        column += running_font.latexWriteEndChanges(
-                                               os, basefont, basefont);
+                                               os, bparams, runparams,
+                                               basefont, basefont);
                                        open_font = false;
                                }
                                basefont = getLayoutFont(bparams, outerfont);
                                running_font = basefont;
 
-                               column += Changes::latexMarkChange(os,
-                                               runningChangeType, Change::UNCHANGED, output);
-                               runningChangeType = Change::UNCHANGED;
+                               column += Changes::latexMarkChange(os, bparams,
+                                               runningChange, Change(Change::UNCHANGED));
+                               runningChange = Change(Change::UNCHANGED);
 
                                os << "}] ";
                                column +=3;
@@ -1998,32 +1989,40 @@ bool Paragraph::simpleTeXOnePar(Buffer const & buf,
                        }
 
                        if (!asdefault)
-                               column += startTeXParParams(bparams, os, 
+                               column += startTeXParParams(bparams, os,
                                                            texrow,
                                                            runparams.moving_arg);
                }
 
-               Change::Type changeType = pimpl_->lookupChange(i).type;
+               Change const & change = pimpl_->lookupChange(i);
+
+               if (bparams.outputChanges && runningChange != change) {
+                       if (open_font) {
+                               column += running_font.latexWriteEndChanges(
+                                               os, bparams, runparams, basefont, basefont);
+                               open_font = false;
+                       }
+                       basefont = getLayoutFont(bparams, outerfont);
+                       running_font = basefont;
+
+                       column += Changes::latexMarkChange(os, bparams, runningChange, change);
+                       runningChange = change;
+               }
 
                // do not output text which is marked deleted
                // if change tracking output is disabled
-               if (!output && changeType == Change::DELETED) {
-                       runningChangeType = changeType;
+               if (!bparams.outputChanges && change.type == Change::DELETED) {
                        continue;
                }
 
                ++column;
-               
-               column += Changes::latexMarkChange(os, runningChangeType,
-                       changeType, output);
-               runningChangeType = changeType;
 
                value_type const c = getChar(i);
 
                // Fully instantiated font
-               LyXFont const font = getFont(bparams, i, outerfont);
+               Font const font = getFont(bparams, i, outerfont);
 
-               LyXFont const last_font = running_font;
+               Font const last_font = running_font;
 
                // Do we need to close the previous font?
                if (open_font &&
@@ -2031,19 +2030,22 @@ bool Paragraph::simpleTeXOnePar(Buffer const & buf,
                     font.language() != running_font.language()))
                {
                        column += running_font.latexWriteEndChanges(
-                                       os, basefont,
+                                       os, bparams, runparams, basefont,
                                        (i == body_pos-1) ? basefont : font);
                        running_font = basefont;
                        open_font = false;
                }
 
                // Switch file encoding if necessary
-               int const count = switchEncoding(os, bparams,
-                               runparams.moving_arg, *(runparams.encoding),
-                               *(font.language()->encoding()));
-               if (count > 0) {
-                       column += count;
-                       runparams.encoding = font.language()->encoding();
+               if (runparams.encoding->package() == Encoding::inputenc &&
+                   font.language()->encoding()->package() == Encoding::inputenc) {
+                       int const count = switchEncoding(os, bparams,
+                                       runparams.moving_arg, *(runparams.encoding),
+                                       *(font.language()->encoding()));
+                       if (count > 0) {
+                               column += count;
+                               runparams.encoding = font.language()->encoding();
+                       }
                }
 
                // Do we need to change font?
@@ -2051,8 +2053,9 @@ bool Paragraph::simpleTeXOnePar(Buffer const & buf,
                     font.language() != running_font.language()) &&
                        i != body_pos - 1)
                {
-                       column += font.latexWriteStartChanges(os, basefont,
-                                                             last_font);
+                       column += font.latexWriteStartChanges(os, bparams,
+                                                             runparams, basefont,
+                                                             last_font);
                        running_font = font;
                        open_font = true;
                }
@@ -2083,7 +2086,7 @@ bool Paragraph::simpleTeXOnePar(Buffer const & buf,
                pimpl_->simpleTeXSpecialChars(buf, bparams, os,
                                        texrow, rp, running_font,
                                        basefont, outerfont, open_font,
-                                       runningChangeType, *style, i, column, c);
+                                       runningChange, *style, i, column, c);
        }
 
        // If we have an open font definition, we have to close it
@@ -2091,11 +2094,12 @@ bool Paragraph::simpleTeXOnePar(Buffer const & buf,
 #ifdef FIXED_LANGUAGE_END_DETECTION
                if (next_) {
                        running_font
-                               .latexWriteEndChanges(os, basefont,
+                               .latexWriteEndChanges(os, bparams, runparams,
+                                       basefont,
                                        next_->getFont(bparams, 0, outerfont));
                } else {
-                       running_font.latexWriteEndChanges(os, basefont,
-                                                         basefont);
+                       running_font.latexWriteEndChanges(os, bparams,
+                                       runparams, basefont, basefont);
                }
 #else
 #ifdef WITH_WARNINGS
@@ -2103,12 +2107,12 @@ bool Paragraph::simpleTeXOnePar(Buffer const & buf,
 //#warning there as we start another \selectlanguage with the next paragraph if
 //#warning we are in need of this. This should be fixed sometime (Jug)
 #endif
-               running_font.latexWriteEndChanges(os, basefont, basefont);
+               running_font.latexWriteEndChanges(os, bparams, runparams,
+                               basefont, basefont);
 #endif
        }
 
-       column += Changes::latexMarkChange(os,
-                       runningChangeType, Change::UNCHANGED, output);
+       column += Changes::latexMarkChange(os, bparams, runningChange, Change(Change::UNCHANGED));
 
        // Needed if there is an optional argument but no contents.
        if (body_pos > 0 && body_pos == size()) {
@@ -2117,7 +2121,7 @@ bool Paragraph::simpleTeXOnePar(Buffer const & buf,
        }
 
        if (!asdefault) {
-               column += endTeXParParams(bparams, os, texrow, 
+               column += endTeXParParams(bparams, os, texrow,
                                          runparams.moving_arg);
        }
 
@@ -2173,14 +2177,15 @@ bool Paragraph::emptyTag() const
 {
        for (pos_type i = 0; i < size(); ++i) {
                if (isInset(i)) {
-                       InsetBase const * inset = getInset(i);
-                       InsetBase::Code lyx_code = inset->lyxCode();
-                       if (lyx_code != InsetBase::TOC_CODE &&
-                           lyx_code != InsetBase::INCLUDE_CODE &&
-                           lyx_code != InsetBase::GRAPHICS_CODE &&
-                           lyx_code != InsetBase::ERT_CODE &&
-                           lyx_code != InsetBase::FLOAT_CODE &&
-                           lyx_code != InsetBase::TABULAR_CODE) {
+                       Inset const * inset = getInset(i);
+                       Inset::Code lyx_code = inset->lyxCode();
+                       if (lyx_code != Inset::TOC_CODE &&
+                           lyx_code != Inset::INCLUDE_CODE &&
+                           lyx_code != Inset::GRAPHICS_CODE &&
+                           lyx_code != Inset::ERT_CODE &&
+                           lyx_code != Inset::LISTINGS_CODE &&
+                           lyx_code != Inset::FLOAT_CODE &&
+                           lyx_code != Inset::TABULAR_CODE) {
                                return false;
                        }
                } else {
@@ -2197,9 +2202,9 @@ string Paragraph::getID(Buffer const & buf, OutputParams const & runparams) cons
 {
        for (pos_type i = 0; i < size(); ++i) {
                if (isInset(i)) {
-                       InsetBase const * inset = getInset(i);
-                       InsetBase::Code lyx_code = inset->lyxCode();
-                       if (lyx_code == InsetBase::LABEL_CODE) {
+                       Inset const * inset = getInset(i);
+                       Inset::Code lyx_code = inset->lyxCode();
+                       if (lyx_code == Inset::LABEL_CODE) {
                                string const id = static_cast<InsetCommand const *>(inset)->getContents();
                                return "id='" + to_utf8(sgml::cleanID(buf, runparams, from_utf8(id))) + "'";
                        }
@@ -2215,25 +2220,25 @@ pos_type Paragraph::getFirstWord(Buffer const & buf, odocstream & os, OutputPara
        pos_type i;
        for (i = 0; i < size(); ++i) {
                if (isInset(i)) {
-                       InsetBase const * inset = getInset(i);
+                       Inset const * inset = getInset(i);
                        inset->docbook(buf, os, runparams);
                } else {
                        value_type c = getChar(i);
                        if (c == ' ')
                                break;
                        os << sgml::escapeChar(c);
-               }
+               }
        }
        return i;
 }
 
 
-bool Paragraph::onlyText(Buffer const & buf, LyXFont const & outerfont, pos_type initial) const
+bool Paragraph::onlyText(Buffer const & buf, Font const & outerfont, pos_type initial) const
 {
-       LyXFont font_old;
+       Font font_old;
 
        for (pos_type i = initial; i < size(); ++i) {
-               LyXFont font = getFont(buf.params(), i, outerfont);
+               Font font = getFont(buf.params(), i, outerfont);
                if (isInset(i))
                        return false;
                if (i != initial && font != font_old)
@@ -2248,13 +2253,13 @@ bool Paragraph::onlyText(Buffer const & buf, LyXFont const & outerfont, pos_type
 void Paragraph::simpleDocBookOnePar(Buffer const & buf,
                                    odocstream & os,
                                    OutputParams const & runparams,
-                                   LyXFont const & outerfont,
+                                   Font const & outerfont,
                                    pos_type initial) const
 {
        bool emph_flag = false;
 
-       LyXLayout_ptr const & style = layout();
-       LyXFont font_old =
+       Layout_ptr const & style = layout();
+       Font font_old =
                style->labeltype == LABEL_MANUAL ? style->labelfont : style->font;
 
        if (style->pass_thru && !onlyText(buf, outerfont, initial))
@@ -2262,11 +2267,11 @@ void Paragraph::simpleDocBookOnePar(Buffer const & buf,
 
        // parsing main loop
        for (pos_type i = initial; i < size(); ++i) {
-               LyXFont font = getFont(buf.params(), i, outerfont);
+               Font font = getFont(buf.params(), i, outerfont);
 
                // handle <emphasis> tag
                if (font_old.emph() != font.emph()) {
-                       if (font.emph() == LyXFont::ON) {
+                       if (font.emph() == Font::ON) {
                                os << "<emphasis>";
                                emph_flag = true;
                        } else if (i != initial) {
@@ -2276,15 +2281,15 @@ void Paragraph::simpleDocBookOnePar(Buffer const & buf,
                }
 
                if (isInset(i)) {
-                       InsetBase const * inset = getInset(i);
+                       Inset const * inset = getInset(i);
                        inset->docbook(buf, os, runparams);
                } else {
                        value_type c = getChar(i);
 
                        if (style->pass_thru)
-                                os.put(c);
+                               os.put(c);
                        else
-                                os << sgml::escapeChar(c);
+                               os << sgml::escapeChar(c);
                }
                font_old = font;
        }
@@ -2303,7 +2308,7 @@ void Paragraph::simpleDocBookOnePar(Buffer const & buf,
 bool Paragraph::isNewline(pos_type pos) const
 {
        return isInset(pos)
-               && getInset(pos)->lyxCode() == InsetBase::NEWLINE_CODE;
+               && getInset(pos)->lyxCode() == Inset::NEWLINE_CODE;
 }
 
 
@@ -2344,7 +2349,8 @@ bool Paragraph::isRightToLeftPar(BufferParams const & bparams) const
 {
        return lyxrc.rtl_support
                && getParLanguage(bparams)->rightToLeft()
-               && ownerCode() != InsetBase::ERT_CODE;
+               && ownerCode() != Inset::ERT_CODE
+               && ownerCode() != Inset::LISTINGS_CODE;
 }
 
 
@@ -2353,7 +2359,7 @@ void Paragraph::changeLanguage(BufferParams const & bparams,
 {
        // change language including dummy font change at the end
        for (pos_type i = 0; i <= size(); ++i) {
-               LyXFont font = getFontSettings(bparams, i);
+               Font font = getFontSettings(bparams, i);
                if (font.language() == from) {
                        font.setLanguage(to);
                        setFont(i, font);
@@ -2395,7 +2401,7 @@ docstring const Paragraph::asString(Buffer const & buffer,
                os << params().labelString() << ' ';
 
        for (pos_type i = beg; i < end; ++i) {
-               value_type const c = getUChar(buffer.params(), i);
+               value_type const c = getChar(i);
                if (isPrintable(c))
                        os.put(c);
                else if (c == META_INSET)
@@ -2406,7 +2412,7 @@ docstring const Paragraph::asString(Buffer const & buffer,
 }
 
 
-void Paragraph::setInsetOwner(InsetBase * inset)
+void Paragraph::setInsetOwner(Inset * inset)
 {
        pimpl_->inset_owner = inset;
 }
@@ -2461,28 +2467,28 @@ int Paragraph::id() const
 }
 
 
-LyXLayout_ptr const & Paragraph::layout() const
+Layout_ptr const & Paragraph::layout() const
 {
        return layout_;
 }
 
 
-void Paragraph::layout(LyXLayout_ptr const & new_layout)
+void Paragraph::layout(Layout_ptr const & new_layout)
 {
        layout_ = new_layout;
 }
 
 
-InsetBase * Paragraph::inInset() const
+Inset * Paragraph::inInset() const
 {
        return pimpl_->inset_owner;
 }
 
 
-InsetBase::Code Paragraph::ownerCode() const
+Inset::Code Paragraph::ownerCode() const
 {
        return pimpl_->inset_owner
-               ? pimpl_->inset_owner->lyxCode() : InsetBase::NO_CODE;
+               ? pimpl_->inset_owner->lyxCode() : Inset::NO_CODE;
 }
 
 
@@ -2504,8 +2510,8 @@ bool Paragraph::isFreeSpacing() const
                return true;
 
        // for now we just need this, later should we need this in some
-       // other way we can always add a function to InsetBase too.
-       return ownerCode() == InsetBase::ERT_CODE;
+       // other way we can always add a function to Inset too.
+       return ownerCode() == Inset::ERT_CODE || ownerCode() == Inset::LISTINGS_CODE;
 }
 
 
@@ -2513,7 +2519,7 @@ bool Paragraph::allowEmpty() const
 {
        if (layout()->keepempty)
                return true;
-       return ownerCode() == InsetBase::ERT_CODE;
+       return ownerCode() == Inset::ERT_CODE || ownerCode() == Inset::LISTINGS_CODE;
 }
 
 
@@ -2522,9 +2528,17 @@ char_type Paragraph::transformChar(char_type c, pos_type pos) const
        if (!Encodings::is_arabic(c))
                return c;
 
-       value_type const prev_char = pos > 0 ? getChar(pos - 1) : ' ';
+       value_type prev_char = ' ';
        value_type next_char = ' ';
 
+       for (pos_type i = pos - 1; i >= 0; --i) {
+               value_type const par_char = getChar(i);
+               if (!Encodings::isComposeChar_arabic(par_char)) {
+                       prev_char = par_char;
+                       break;
+               }
+       }
+
        for (pos_type i = pos + 1, end = size(); i < end; ++i) {
                value_type const par_char = getChar(i);
                if (!Encodings::isComposeChar_arabic(par_char)) {
@@ -2585,25 +2599,70 @@ bool Paragraph::hfillExpansion(Row const & row, pos_type pos) const
 }
 
 
-bool Paragraph::checkBiblio(bool track_changes)
+int Paragraph::checkBiblio(bool track_changes)
 {
+       //FIXME From JS:
+       //This is getting more and more a mess. ...We really should clean
+       //up this bibitem issue for 1.6. See also bug 2743.
+
        // Add bibitem insets if necessary
        if (layout()->labeltype != LABEL_BIBLIO)
-               return false;
+               return 0;
 
        bool hasbibitem = !insetlist.empty()
                // Insist on it being in pos 0
                && getChar(0) == Paragraph::META_INSET
-               && insetlist.begin()->inset->lyxCode() == InsetBase::BIBITEM_CODE;
+               && insetlist.begin()->inset->lyxCode() == Inset::BIBITEM_CODE;
 
-       if (hasbibitem)
-               return false;
+       docstring oldkey;
+       docstring oldlabel;
 
-       InsetBibitem * inset(new InsetBibitem(InsetCommandParams("bibitem")));
-       insertInset(0, static_cast<InsetBase *>(inset),
-               Change(track_changes ? Change::INSERTED : Change::UNCHANGED));
+       // remove a bibitem in pos != 0
+       // restore it later in pos 0 if necessary
+       // (e.g. if a user inserts contents _before_ the item)
+       // we're assuming there's only one of these, which there
+       // should be.
+       int erasedInsetPosition = -1;
+       InsetList::iterator it = insetlist.begin();
+       InsetList::iterator end = insetlist.end();
+       for (; it != end; ++it)
+               if (it->inset->lyxCode() == Inset::BIBITEM_CODE
+                   && it->pos > 0) {
+                       InsetBibitem * olditem = static_cast<InsetBibitem *>(it->inset);
+                       oldkey = olditem->getParam("key");
+                       oldlabel = olditem->getParam("label");
+                       erasedInsetPosition = it->pos;
+                       eraseChar(erasedInsetPosition, track_changes);
+                       break;
+       }
 
-       return true;
+       //There was an InsetBibitem at the beginning, and we didn't
+       //have to erase one.
+       if (hasbibitem && erasedInsetPosition < 0)
+                       return 0;
+
+       //There was an InsetBibitem at the beginning and we did have to
+       //erase one. So we give its properties to the beginning inset.
+       if (hasbibitem) {
+               InsetBibitem * inset =
+                       static_cast<InsetBibitem *>(insetlist.begin()->inset);
+               if (!oldkey.empty())
+                       inset->setParam("key", oldkey);
+               inset->setParam("label", oldlabel);
+               return -erasedInsetPosition;
+       }
+
+       //There was no inset at the beginning, so we need to create one with
+       //the key and label of the one we erased.
+       InsetBibitem * inset(new InsetBibitem(InsetCommandParams("bibitem")));
+       // restore values of previously deleted item in this par.
+       if (!oldkey.empty())
+               inset->setParam("key", oldkey);
+       inset->setParam("label", oldlabel);
+       insertInset(0, static_cast<Inset *>(inset),
+                   Change(track_changes ? Change::INSERTED : Change::UNCHANGED));
+
+       return 1;
 }
 
 } // namespace lyx