]> git.lyx.org Git - lyx.git/blobdiff - src/paragraph.C
hopefully fix tex2lyx linking.
[lyx.git] / src / paragraph.C
index 20e7817237b51125ad6622e85d90f6a9be724984..c0c53c3e524220eed2aefacf3aef80680facef39 100644 (file)
@@ -44,8 +44,8 @@
 #include "support/lstrings.h"
 #include "support/textutils.h"
 #include "support/convert.h"
+#include "support/unicode.h"
 
-#include <boost/tuple/tuple.hpp>
 #include <boost/bind.hpp>
 
 #include <algorithm>
 #include <stack>
 #include <sstream>
 
-using lyx::pos_type;
 
-using lyx::support::subst;
+namespace lyx {
+
+using support::subst;
 
 using std::distance;
 using std::endl;
@@ -152,13 +153,12 @@ void Paragraph::write(Buffer const & buf, ostream & os,
        LyXFont font1(LyXFont::ALL_INHERIT, bparams.language);
 
        Change running_change = Change(Change::UNCHANGED);
-       lyx::time_type const curtime(lyx::current_time());
 
        int column = 0;
        for (pos_type i = 0; i <= size(); ++i) {
 
                Change change = pimpl_->lookupChange(i);
-               Changes::lyxMarkChange(os, column, curtime, running_change, change);
+               Changes::lyxMarkChange(os, column, running_change, change);
                running_change = change;
 
                if (i == size())
@@ -212,9 +212,11 @@ void Paragraph::write(Buffer const & buf, ostream & os,
                        }
                        // this check is to amend a bug. LyX sometimes
                        // inserts '\0' this could cause problems.
-                       if (c != '\0')
-                               os << c;
-                       else
+                       if (c != '\0') {
+                               std::vector<char> tmp = ucs4_to_utf8(c);
+                               tmp.push_back('\0');
+                               os << &tmp[0];
+                       } else
                                lyxerr << "ERROR (Paragraph::writeFile):"
                                        " NULL char in structure." << endl;
                        ++column;
@@ -232,55 +234,60 @@ void Paragraph::validate(LaTeXFeatures & features) const
 }
 
 
-void Paragraph::eraseIntern(lyx::pos_type pos)
+bool Paragraph::eraseChar(pos_type pos, bool trackChanges)
 {
-       pimpl_->eraseIntern(pos);
+       return pimpl_->eraseChar(pos, trackChanges);
 }
 
 
-bool Paragraph::erase(pos_type pos)
+int Paragraph::eraseChars(pos_type start, pos_type end, bool trackChanges)
 {
-       return pimpl_->erase(pos);
+       return pimpl_->eraseChars(start, end, trackChanges);
 }
 
 
-int Paragraph::erase(pos_type start, pos_type end)
+void Paragraph::insert(pos_type start, docstring const & str,
+                       LyXFont const & font, Change const & change)
 {
-       return pimpl_->erase(start, end);
+       for (size_t i = 0, n = str.size(); i != n ; ++i)
+               insertChar(start + i, str[i], font, change);
 }
 
 
-void Paragraph::insert(pos_type start, string const & str,
-                      LyXFont const & font)
+void Paragraph::insertChar(pos_type pos, Paragraph::value_type c,
+                           bool trackChanges)
 {
-       for (size_t i = 0, n = str.size(); i != n ; ++i)
-               insertChar(start + i, str[i], font);
+       pimpl_->insertChar(pos, c, Change(trackChanges ?
+                          Change::INSERTED : Change::UNCHANGED));
 }
 
 
 void Paragraph::insertChar(pos_type pos, Paragraph::value_type c,
-                          Change change)
+                           LyXFont const & font, bool trackChanges)
 {
-       pimpl_->insertChar(pos, c, change);
+       pimpl_->insertChar(pos, c, Change(trackChanges ?
+                          Change::INSERTED : Change::UNCHANGED));
+       setFont(pos, font);
 }
 
 
 void Paragraph::insertChar(pos_type pos, Paragraph::value_type c,
-                          LyXFont const & font, Change change)
+                           LyXFont const & font, Change const & change)
 {
        pimpl_->insertChar(pos, c, change);
        setFont(pos, font);
 }
 
 
-void Paragraph::insertInset(pos_type pos, InsetBase * inset, Change change)
+void Paragraph::insertInset(pos_type pos, InsetBase * inset,
+                            Change const & change)
 {
        pimpl_->insertInset(pos, inset, change);
 }
 
 
 void Paragraph::insertInset(pos_type pos, InsetBase * inset,
-                           LyXFont const & font, Change change)
+                            LyXFont const & font, Change const & change)
 {
        pimpl_->insertInset(pos, inset, change);
        setFont(pos, font);
@@ -318,10 +325,10 @@ LyXFont const Paragraph::getFontSettings(BufferParams const & bparams,
 }
 
 
-FontSpan Paragraph::fontSpan(lyx::pos_type pos) const
+FontSpan Paragraph::fontSpan(pos_type pos) const
 {
        BOOST_ASSERT(pos <= size());
-       lyx::pos_type start = 0;
+       pos_type start = 0;
 
        Pimpl::FontList::const_iterator cit = pimpl_->fontlist.begin();
        Pimpl::FontList::const_iterator end = pimpl_->fontlist.end();
@@ -560,8 +567,8 @@ int Paragraph::stripLeadingSpaces()
 
        int i = 0;
        while (!empty() && (isNewline(0) || isLineSeparator(0))
-               && (lookupChange(0).type != Change::DELETED)) {
-               erase(0);
+               && !isDeleted(0)) {
+               eraseChar(0, false); // no change tracking here
                ++i;
        }
 
@@ -575,13 +582,13 @@ bool Paragraph::hasSameLayout(Paragraph const & par) const
 }
 
 
-Paragraph::depth_type Paragraph::getDepth() const
+depth_type Paragraph::getDepth() const
 {
        return params().depth();
 }
 
 
-Paragraph::depth_type Paragraph::getMaxDepthAfter() const
+depth_type Paragraph::getMaxDepthAfter() const
 {
        if (layout()->isEnvironment())
                return params().depth() + 1;
@@ -596,14 +603,14 @@ char Paragraph::getAlign() const
 }
 
 
-string const & Paragraph::getLabelstring() const
+docstring const & Paragraph::getLabelstring() const
 {
        return params().labelString();
 }
 
 
 // the next two functions are for the manual labels
-string const Paragraph::getLabelWidthString() const
+docstring const Paragraph::getLabelWidthString() const
 {
        if (!params().labelWidthString().empty())
                return params().labelWidthString();
@@ -612,7 +619,7 @@ string const Paragraph::getLabelWidthString() const
 }
 
 
-void Paragraph::setLabelWidthString(string const & s)
+void Paragraph::setLabelWidthString(docstring const & s)
 {
        params().labelWidthString(s);
 }
@@ -621,7 +628,7 @@ void Paragraph::setLabelWidthString(string const & s)
 void Paragraph::applyLayout(LyXLayout_ptr const & new_layout)
 {
        layout(new_layout);
-       params().labelWidthString(string());
+       params().labelWidthString(docstring());
        params().align(LYX_ALIGN_LAYOUT);
        params().spacing(Spacing(Spacing::Default));
 }
@@ -647,8 +654,8 @@ void Paragraph::setBeginOfBody()
        pos_type end = size();
        if (i < end && !isNewline(i)) {
                ++i;
-               char previous_char = 0;
-               char temp = 0;
+               char_type previous_char = 0;
+               char_type temp = 0;
                if (i < end) {
                        previous_char = text_[i];
                        if (!isNewline(i)) {
@@ -737,7 +744,7 @@ string const corrected_env(string const & suffix, string const & env,
 
 // This could go to ParagraphParameters if we want to
 int Paragraph::startTeXParParams(BufferParams const & bparams,
-                                ostream & os, bool moving_arg) const
+                                odocstream & os, bool moving_arg) const
 {
        int column = 0;
 
@@ -774,7 +781,7 @@ int Paragraph::startTeXParParams(BufferParams const & bparams,
                        output = corrected_env("\\begin", "flushleft", ownerCode());
                else
                        output = corrected_env("\\begin", "flushright", ownerCode());
-               os << output;
+               os << from_ascii(output);
                column += output.size();
                break;
        } case LYX_ALIGN_RIGHT: {
@@ -783,13 +790,13 @@ int Paragraph::startTeXParParams(BufferParams const & bparams,
                        output = corrected_env("\\begin", "flushright", ownerCode());
                else
                        output = corrected_env("\\begin", "flushleft", ownerCode());
-               os << output;
+               os << from_ascii(output);
                column += output.size();
                break;
        } case LYX_ALIGN_CENTER: {
                string output;
                output = corrected_env("\\begin", "center", ownerCode());
-               os << output;
+               os << from_ascii(output);
                column += output.size();
                break;
        }
@@ -801,7 +808,7 @@ int Paragraph::startTeXParParams(BufferParams const & bparams,
 
 // This could go to ParagraphParameters if we want to
 int Paragraph::endTeXParParams(BufferParams const & bparams,
-                              ostream & os, bool moving_arg) const
+                              odocstream & os, bool moving_arg) const
 {
        int column = 0;
 
@@ -833,7 +840,7 @@ int Paragraph::endTeXParParams(BufferParams const & bparams,
                        output = corrected_env("\\par\\end", "flushleft", ownerCode());
                else
                        output = corrected_env("\\par\\end", "flushright", ownerCode());
-               os << output;
+               os << from_ascii(output);
                column += output.size();
                break;
        } case LYX_ALIGN_RIGHT: {
@@ -842,13 +849,13 @@ int Paragraph::endTeXParParams(BufferParams const & bparams,
                        output = corrected_env("\\par\\end", "flushright", ownerCode());
                else
                        output = corrected_env("\\par\\end", "flushleft", ownerCode());
-               os << output;
+               os << from_ascii(output);
                column += output.size();
                break;
        } case LYX_ALIGN_CENTER: {
                string output;
                output = corrected_env("\\par\\end", "center", ownerCode());
-               os << output;
+               os << from_ascii(output);
                column += output.size();
                break;
        }
@@ -862,7 +869,7 @@ int Paragraph::endTeXParParams(BufferParams const & bparams,
 bool Paragraph::simpleTeXOnePar(Buffer const & buf,
                                BufferParams const & bparams,
                                LyXFont const & outerfont,
-                               ostream & os, TexRow & texrow,
+                               odocstream & os, TexRow & texrow,
                                OutputParams const & runparams) const
 {
        lyxerr[Debug::LATEX] << "SimpleTeXOnePar...     " << this << endl;
@@ -890,7 +897,7 @@ bool Paragraph::simpleTeXOnePar(Buffer const & buf,
        // output change tracking marks only if desired,
        // if dvipost is installed,
        // and with dvi/ps (other formats don't work)
-       bool const output = bparams.output_changes
+       bool const output = bparams.outputChanges
                && runparams.flavor == OutputParams::LATEX
                && features.isAvailable("dvipost");
 
@@ -913,7 +920,7 @@ bool Paragraph::simpleTeXOnePar(Buffer const & buf,
        // Do we have an open font change?
        bool open_font = false;
 
-       Change::Type running_change = Change::UNCHANGED;
+       Change::Type runningChangeType = Change::UNCHANGED;
 
        texrow.start(id(), 0);
 
@@ -1001,15 +1008,15 @@ bool Paragraph::simpleTeXOnePar(Buffer const & buf,
                        open_font = true;
                }
 
-               Change::Type change = pimpl_->lookupChange(i).type;
+               Change::Type changeType = pimpl_->lookupChange(i).type;
 
-               column += Changes::latexMarkChange(os, running_change,
-                       change, output);
-               running_change = change;
+               column += Changes::latexMarkChange(os, runningChangeType,
+                       changeType, output);
+               runningChangeType = changeType;
 
                // do not output text which is marked deleted
                // if change tracking output is not desired
-               if (output || running_change != Change::DELETED) {
+               if (output || runningChangeType != Change::DELETED) {
                        OutputParams rp = runparams;
                        rp.free_spacing = style->free_spacing;
                        rp.local_font = &font;
@@ -1018,13 +1025,13 @@ bool Paragraph::simpleTeXOnePar(Buffer const & buf,
                                                os, texrow, rp,
                                                font, running_font,
                                                basefont, outerfont, open_font,
-                                               running_change,
+                                               runningChangeType,
                                                *style, i, column, c);
                }
        }
 
        column += Changes::latexMarkChange(os,
-                       running_change, Change::UNCHANGED, output);
+                       runningChangeType, Change::UNCHANGED, output);
 
        // If we have an open font definition, we have to close it
        if (open_font) {
@@ -1118,201 +1125,6 @@ void reset(PAR_TAG & p1, PAR_TAG const & p2)
 } // anon
 
 
-// Handle internal paragraph parsing -- layout already processed.
-void Paragraph::simpleLinuxDocOnePar(Buffer const & buf,
-                                    ostream & os,
-                                    LyXFont const & outerfont,
-                                    OutputParams const & runparams,
-                                    lyx::depth_type /*depth*/) const
-{
-       LyXLayout_ptr const & style = layout();
-
-       string::size_type char_line_count = 5;     // Heuristic choice ;-)
-
-       // gets paragraph main font
-       LyXFont font_old;
-       bool desc_on;
-       if (style->labeltype == LABEL_MANUAL) {
-               font_old = style->labelfont;
-               desc_on = true;
-       } else {
-               font_old = style->font;
-               desc_on = false;
-       }
-
-       LyXFont::FONT_FAMILY family_type = LyXFont::ROMAN_FAMILY;
-       LyXFont::FONT_SERIES series_type = LyXFont::MEDIUM_SERIES;
-       LyXFont::FONT_SHAPE  shape_type  = LyXFont::UP_SHAPE;
-       bool is_em = false;
-
-       stack<PAR_TAG> tag_state;
-       // parsing main loop
-       for (pos_type i = 0; i < size(); ++i) {
-
-               PAR_TAG tag_close = PAR_NONE;
-               list < PAR_TAG > tag_open;
-
-               LyXFont const font = getFont(buf.params(), i, outerfont);
-
-               if (font_old.family() != font.family()) {
-                       switch (family_type) {
-                       case LyXFont::SANS_FAMILY:
-                               tag_close |= SF;
-                               break;
-                       case LyXFont::TYPEWRITER_FAMILY:
-                               tag_close |= TT;
-                               break;
-                       default:
-                               break;
-                       }
-
-                       family_type = font.family();
-
-                       switch (family_type) {
-                       case LyXFont::SANS_FAMILY:
-                               tag_open.push_back(SF);
-                               break;
-                       case LyXFont::TYPEWRITER_FAMILY:
-                               tag_open.push_back(TT);
-                               break;
-                       default:
-                               break;
-                       }
-               }
-
-               if (font_old.series() != font.series()) {
-                       switch (series_type) {
-                       case LyXFont::BOLD_SERIES:
-                               tag_close |= BF;
-                               break;
-                       default:
-                               break;
-                       }
-
-                       series_type = font.series();
-
-                       switch (series_type) {
-                       case LyXFont::BOLD_SERIES:
-                               tag_open.push_back(BF);
-                               break;
-                       default:
-                               break;
-                       }
-
-               }
-
-               if (font_old.shape() != font.shape()) {
-                       switch (shape_type) {
-                       case LyXFont::ITALIC_SHAPE:
-                               tag_close |= IT;
-                               break;
-                       case LyXFont::SLANTED_SHAPE:
-                               tag_close |= SL;
-                               break;
-                       default:
-                               break;
-                       }
-
-                       shape_type = font.shape();
-
-                       switch (shape_type) {
-                       case LyXFont::ITALIC_SHAPE:
-                               tag_open.push_back(IT);
-                               break;
-                       case LyXFont::SLANTED_SHAPE:
-                               tag_open.push_back(SL);
-                               break;
-                       default:
-                               break;
-                       }
-               }
-               // handle <em> tag
-               if (font_old.emph() != font.emph()) {
-                       if (font.emph() == LyXFont::ON) {
-                               tag_open.push_back(EM);
-                               is_em = true;
-                       }
-                       else if (is_em) {
-                               tag_close |= EM;
-                               is_em = false;
-                       }
-               }
-
-               list < PAR_TAG > temp;
-               while (!tag_state.empty() && tag_close) {
-                       PAR_TAG k =  tag_state.top();
-                       tag_state.pop();
-                       os << "</" << tag_name(k) << '>';
-                       if (tag_close & k)
-                               reset(tag_close,k);
-                       else
-                               temp.push_back(k);
-               }
-
-               for(list< PAR_TAG >::const_iterator j = temp.begin();
-                   j != temp.end(); ++j) {
-                       tag_state.push(*j);
-                       os << '<' << tag_name(*j) << '>';
-               }
-
-               for(list< PAR_TAG >::const_iterator j = tag_open.begin();
-                   j != tag_open.end(); ++j) {
-                       tag_state.push(*j);
-                       os << '<' << tag_name(*j) << '>';
-               }
-
-               value_type c = getChar(i);
-
-
-               if (c == Paragraph::META_INSET) {
-                       getInset(i)->linuxdoc(buf, os, runparams);
-                       font_old = font;
-                       continue;
-               }
-
-               if (style->latexparam() == "CDATA") {
-                       // "TeX"-Mode on == > SGML-Mode on.
-                       if (c != '\0')
-                               os << c;
-                       ++char_line_count;
-               } else {
-                       bool ws;
-                       string str;
-                       boost::tie(ws, str) = sgml::escapeChar(c);
-                       if (ws && !isFreeSpacing()) {
-                               // in freespacing mode, spaces are
-                               // non-breaking characters
-                               if (desc_on) { // if char is ' ' then...
-                                       ++char_line_count;
-                                       sgmlLineBreak(os, char_line_count, 6);
-                                       os << "</tag>";
-                                       desc_on = false;
-                               } else  {
-                                       sgmlLineBreak(os, char_line_count, 1);
-                                       os << c;
-                               }
-                       } else {
-                               os << str;
-                               char_line_count += str.length();
-                       }
-               }
-               font_old = font;
-       }
-
-       while (!tag_state.empty()) {
-               os << "</" << tag_name(tag_state.top()) << '>';
-               tag_state.pop();
-       }
-
-       // resets description flag correctly
-       if (desc_on) {
-               // <tag> not closed...
-               sgmlLineBreak(os, char_line_count, 6);
-               os << "</tag>";
-       }
-}
-
-
 bool Paragraph::emptyTag() const
 {
        for (pos_type i = 0; i < size(); ++i) {
@@ -1345,7 +1157,7 @@ string Paragraph::getID(Buffer const & buf, OutputParams const & runparams) cons
                        InsetBase::Code lyx_code = inset->lyxCode();
                        if (lyx_code == InsetBase::LABEL_CODE) {
                                string const id = static_cast<InsetCommand const *>(inset)->getContents();
-                               return "id=\"" + sgml::cleanID(buf, runparams, id) + "\"";
+                               return "id='" + to_utf8(sgml::cleanID(buf, runparams, from_utf8(id))) + "'";
                        }
                }
 
@@ -1354,7 +1166,7 @@ string Paragraph::getID(Buffer const & buf, OutputParams const & runparams) cons
 }
 
 
-pos_type Paragraph::getFirstWord(Buffer const & buf, ostream & os, OutputParams const & runparams) const
+pos_type Paragraph::getFirstWord(Buffer const & buf, odocstream & os, OutputParams const & runparams) const
 {
        pos_type i;
        for (i = 0; i < size(); ++i) {
@@ -1365,12 +1177,8 @@ pos_type Paragraph::getFirstWord(Buffer const & buf, ostream & os, OutputParams
                        value_type c = getChar(i);
                        if (c == ' ')
                                break;
-                       bool ws;
-                       string str;
-                       boost::tie(ws, str) = sgml::escapeChar(c);
-
-                       os << str;
-               }
+                       os << sgml::escapeChar(c);
+               }
        }
        return i;
 }
@@ -1394,7 +1202,7 @@ bool Paragraph::onlyText(Buffer const & buf, LyXFont const & outerfont, pos_type
 
 
 void Paragraph::simpleDocBookOnePar(Buffer const & buf,
-                                   ostream & os,
+                                   odocstream & os,
                                    OutputParams const & runparams,
                                    LyXFont const & outerfont,
                                    pos_type initial) const
@@ -1428,14 +1236,11 @@ void Paragraph::simpleDocBookOnePar(Buffer const & buf,
                        inset->docbook(buf, os, runparams);
                } else {
                        value_type c = getChar(i);
-                       bool ws;
-                       string str;
-                       boost::tie(ws, str) = sgml::escapeChar(c);
 
                        if (style->pass_thru)
-                               os << c;
+                                os.put(c);
                        else
-                               os << str;
+                                os << sgml::escapeChar(c);
                }
                font_old = font;
        }
@@ -1502,7 +1307,8 @@ bool Paragraph::isRightToLeftPar(BufferParams const & bparams) const
 void Paragraph::changeLanguage(BufferParams const & bparams,
                               Language const * from, Language const * to)
 {
-       for (pos_type i = 0; i < size(); ++i) {
+       // change language including dummy font change at the end
+       for (pos_type i = 0; i <= size(); ++i) {
                LyXFont font = getFontSettings(bparams, i);
                if (font.language() == from) {
                        font.setLanguage(to);
@@ -1529,14 +1335,14 @@ bool Paragraph::isMultiLingual(BufferParams const & bparams) const
 
 // Convert the paragraph to a string.
 // Used for building the table of contents
-string const Paragraph::asString(Buffer const & buffer, bool label) const
+docstring const Paragraph::asString(Buffer const & buffer, bool label) const
 {
        OutputParams runparams;
        return asString(buffer, runparams, label);
 }
 
 
-string const Paragraph::asString(Buffer const & buffer,
+docstring const Paragraph::asString(Buffer const & buffer,
                                 OutputParams const & runparams,
                                 bool label) const
 {
@@ -1560,13 +1366,13 @@ string const Paragraph::asString(Buffer const & buffer,
        return s;
 #else
        // This should really be done by the caller and not here.
-       string ret = asString(buffer, runparams, 0, size(), label);
+       docstring ret = asString(buffer, runparams, 0, size(), label);
        return subst(ret, '\n', ' ');
 #endif
 }
 
 
-string const Paragraph::asString(Buffer const & buffer,
+docstring const Paragraph::asString(Buffer const & buffer,
                                 pos_type beg, pos_type end, bool label) const
 {
 
@@ -1575,11 +1381,11 @@ string const Paragraph::asString(Buffer const & buffer,
 }
 
 
-string const Paragraph::asString(Buffer const & buffer,
+docstring const Paragraph::asString(Buffer const & buffer,
                                 OutputParams const & runparams,
                                 pos_type beg, pos_type end, bool label) const
 {
-       ostringstream os;
+       lyx::odocstringstream os;
 
        if (beg == 0 && label && !params().labelString().empty())
                os << params().labelString() << ' ';
@@ -1587,7 +1393,7 @@ string const Paragraph::asString(Buffer const & buffer,
        for (pos_type i = beg; i < end; ++i) {
                value_type const c = getUChar(buffer.params(), i);
                if (isPrintable(c))
-                       os << c;
+                       os.put(c);
                else if (c == META_INSET)
                        getInset(i)->textString(buffer, os, runparams);
        }
@@ -1602,31 +1408,7 @@ void Paragraph::setInsetOwner(InsetBase * inset)
 }
 
 
-void Paragraph::setContentsFromPar(Paragraph const & par)
-{
-       pimpl_->setContentsFromPar(par);
-}
-
-
-void Paragraph::trackChanges(Change::Type type)
-{
-       pimpl_->trackChanges(type);
-}
-
-
-void Paragraph::untrackChanges()
-{
-       pimpl_->untrackChanges();
-}
-
-
-void Paragraph::cleanChanges(ChangeTracking ct)
-{
-       pimpl_->cleanChanges(ct);
-}
-
-
-Change const Paragraph::lookupChange(lyx::pos_type pos) const
+Change const Paragraph::lookupChange(pos_type pos) const
 {
        BOOST_ASSERT(pos <= size());
        return pimpl_->lookupChange(pos);
@@ -1639,39 +1421,27 @@ bool Paragraph::isChanged(pos_type start, pos_type end) const
 }
 
 
-bool Paragraph::isChangeEdited(pos_type start, pos_type end) const
+void Paragraph::setChange(Change const & change)
 {
-       return pimpl_->isChangeEdited(start, end);
+       pimpl_->setChange(change);
 }
 
 
-void Paragraph::setChangeType(lyx::pos_type pos, Change::Type type)
-{
-       pimpl_->setChangeType(pos, type);
-}
-
-
-void Paragraph::setChange(lyx::pos_type pos, Change change)
+void Paragraph::setChange(pos_type pos, Change const & change)
 {
        pimpl_->setChange(pos, change);
 }
 
 
-void Paragraph::markErased(bool erased)
-{
-       pimpl_->markErased(erased);
-}
-
-
-void Paragraph::acceptChange(pos_type start, pos_type end)
+void Paragraph::acceptChanges(pos_type start, pos_type end)
 {
-       return pimpl_->acceptChange(start, end);
+       return pimpl_->acceptChanges(start, end);
 }
 
 
-void Paragraph::rejectChange(pos_type start, pos_type end)
+void Paragraph::rejectChanges(pos_type start, pos_type end)
 {
-       return pimpl_->rejectChange(start, end);
+       return pimpl_->rejectChanges(start, end);
 }
 
 
@@ -1712,12 +1482,6 @@ void Paragraph::clearContents()
 }
 
 
-void Paragraph::setChar(pos_type pos, value_type c)
-{
-       text_[pos] = c;
-}
-
-
 ParagraphParameters & Paragraph::params()
 {
        return pimpl_->params;
@@ -1801,10 +1565,11 @@ size_t Paragraph::pos2row(pos_type pos) const
 }
 
 
-unsigned char Paragraph::transformChar(unsigned char c, pos_type pos) const
+char_type Paragraph::transformChar(char_type c, pos_type pos) const
 {
        if (!Encodings::is_arabic(c))
                if (lyxrc.font_norm_type == LyXRC::ISO_8859_6_8 && isDigit(c))
+                       // FIXME UNICODE What does this do?
                        return c + (0xb0 - '0');
                else
                        return c;
@@ -1844,3 +1609,38 @@ void Paragraph::dump() const
                rows_[i].dump();
        }
 }
+
+
+bool Paragraph::hfillExpansion(Row const & row, pos_type pos) const
+{
+       if (!isHfill(pos))
+               return false;
+
+       // at the end of a row it does not count
+       // unless another hfill exists on the line
+       if (pos >= row.endpos()) {
+               for (pos_type i = row.pos(); i < pos && !isHfill(i); ++i)
+                       return false;
+       }
+
+       // at the beginning of a row it does not count, if it is not
+       // the first row of a paragaph
+       if (row.pos() == 0)
+               return true;
+
+       // in some labels it does not count
+       if (layout()->margintype != MARGIN_MANUAL && pos < beginOfBody())
+               return false;
+
+       // if there is anything between the first char of the row and
+       // the specified position that is not a newline and not a hfill,
+       // the hfill will count, otherwise not
+       pos_type i = row.pos();
+       while (i < pos && (isNewline(i) || isHfill(i)))
+               ++i;
+
+       return i != pos;
+}
+
+
+} // namespace lyx