]> git.lyx.org Git - lyx.git/blobdiff - src/text.C
cleanup after svn hang-up, #undef CursorShape. Should be compilable ganin now.
[lyx.git] / src / text.C
index 0493c1416c32836f9cd7835ece7c838bc9fd3a89..22b5741227c6da281414ebfb7aad1872b6ca4f4f 100644 (file)
@@ -88,6 +88,7 @@ using lyx::support::split;
 using lyx::support::uppercase;
 
 using lyx::cap::cutSelection;
+using lyx::cap::pasteParagraphList;
 
 using std::auto_ptr;
 using std::advance;
@@ -191,7 +192,7 @@ void readParToken(Buffer const & buf, Paragraph & par, LyXLex & lex,
                if (!hasLayout) {
                        errorList.push_back(ErrorItem(_("Unknown layout"),
                        bformat(_("Layout '%1$s' does not exist in textclass '%2$s'\nTrying to use the default instead.\n"),
-                               layoutname, tclass.name()), par.id(), 0, par.size()));
+                       lyx::from_utf8(layoutname), lyx::from_utf8(tclass.name())), par.id(), 0, par.size()));
                        layoutname = tclass.defaultLayoutName();
                }
 
@@ -220,7 +221,7 @@ void readParToken(Buffer const & buf, Paragraph & par, LyXLex & lex,
                        par.insertInset(par.size(), inset, font, change);
                else {
                        lex.eatLine();
-                       string line = lex.getString();
+                       docstring line = lyx::from_utf8(lex.getString());
                        errorList.push_back(ErrorItem(_("Unknown Inset"), line,
                                            par.id(), 0, par.size()));
                }
@@ -362,7 +363,8 @@ void readParToken(Buffer const & buf, Paragraph & par, LyXLex & lex,
        } else {
                lex.eatLine();
                errorList.push_back(ErrorItem(_("Unknown token"),
-                       bformat(_("Unknown token: %1$s %2$s\n"), token, lex.getString()),
+                       bformat(_("Unknown token: %1$s %2$s\n"), lyx::from_utf8(token),
+                       lyx::from_utf8(lex.getString())),
                        par.id(), 0, par.size()));
        }
 }
@@ -501,8 +503,8 @@ int LyXText::leftMargin(pit_type const pit, pos_type const pos) const
        if (isMainText())
                l_margin += changebarMargin();
 
-        string leftm = tclass.leftmargin();
-        docstring dleft(leftm.begin(), leftm.end());
+       string leftm = tclass.leftmargin();
+       docstring dleft(leftm.begin(), leftm.end());
        l_margin += font_metrics::signedWidth(dleft, params.getFont());
 
        if (par.getDepth() != 0) {
@@ -531,64 +533,64 @@ int LyXText::leftMargin(pit_type const pit, pos_type const pos) const
        LyXFont const labelfont = getLabelFont(par);
        switch (layout->margintype) {
        case MARGIN_DYNAMIC:
-                if (!layout->leftmargin.empty()) {
-                        string leftm = layout->leftmargin;
-                        docstring dleft(leftm.begin(), leftm.end());
-                        l_margin += font_metrics::signedWidth(dleft,
-                                                              params.getFont());
-                }
-                if (!par.getLabelstring().empty()) {
-                        string labin = layout->labelindent;
-                        docstring dlabin(labin.begin(), labin.end());
+               if (!layout->leftmargin.empty()) {
+                       string leftm = layout->leftmargin;
+                       docstring dleft(leftm.begin(), leftm.end());
+                       l_margin += font_metrics::signedWidth(dleft,
+                                                             params.getFont());
+               }
+               if (!par.getLabelstring().empty()) {
+                       string labin = layout->labelindent;
+                       docstring dlabin(labin.begin(), labin.end());
                        l_margin += font_metrics::signedWidth(dlabin,
                                                  labelfont);
-                        string labstr = par.getLabelstring();
-                        docstring dlabstr(labstr.begin(), labstr.end());
+                       string labstr = par.getLabelstring();
+                       docstring dlabstr(labstr.begin(), labstr.end());
                        l_margin += font_metrics::width(dlabstr,
                                            labelfont);
-                        string labsep = layout->labelsep;
-                        docstring dlabsep(labsep.begin(), labsep.end());
+                       string labsep = layout->labelsep;
+                       docstring dlabsep(labsep.begin(), labsep.end());
                        l_margin += font_metrics::width(dlabsep, labelfont);
                }
                break;
 
        case MARGIN_MANUAL: {
-                string labin = layout->labelindent;
-                docstring dlabin(labin.begin(), labin.end());
+               string labin = layout->labelindent;
+               docstring dlabin(labin.begin(), labin.end());
                l_margin += font_metrics::signedWidth(dlabin, labelfont);
                // The width of an empty par, even with manual label, should be 0
                if (!par.empty() && pos >= par.beginOfBody()) {
                        if (!par.getLabelWidthString().empty()) {
-                                string labstr = par.getLabelWidthString();
-                                docstring dlabstr(labstr.begin(), labstr.end());
+                               string labstr = par.getLabelWidthString();
+                               docstring dlabstr(labstr.begin(), labstr.end());
                                l_margin += font_metrics::width(dlabstr,
                                               labelfont);
-                                string labsep = layout->labelsep;
-                                docstring dlabsep(labsep.begin(), labsep.end());
+                               string labsep = layout->labelsep;
+                               docstring dlabsep(labsep.begin(), labsep.end());
                                l_margin += font_metrics::width(dlabsep, labelfont);
                        }
                }
                break;
-        }
-            
+       }
+
        case MARGIN_STATIC: {
-                string leftm = layout->leftmargin;
-                docstring dleft(leftm.begin(), leftm.end());
+               string leftm = layout->leftmargin;
+               docstring dleft(leftm.begin(), leftm.end());
                l_margin += font_metrics::signedWidth(dleft, params.getFont()) * 4
                        / (par.getDepth() + 4);
                break;
-        }
+       }
 
        case MARGIN_FIRST_DYNAMIC:
                if (layout->labeltype == LABEL_MANUAL) {
                        if (pos >= par.beginOfBody()) {
-                                string leftm = layout->leftmargin;
-                                docstring dleft(leftm.begin(), leftm.end());
+                               string leftm = layout->leftmargin;
+                               docstring dleft(leftm.begin(), leftm.end());
                                l_margin += font_metrics::signedWidth(dleft,
                                                          labelfont);
                        } else {
-                                string labin = layout->labelindent;
-                                docstring dlabin(labin.begin(), labin.end());
+                               string labin = layout->labelindent;
+                               docstring dlabin(labin.begin(), labin.end());
                                l_margin += font_metrics::signedWidth(dlabin,
                                                          labelfont);
                        }
@@ -598,23 +600,23 @@ int LyXText::leftMargin(pit_type const pit, pos_type const pos) const
                           || (layout->labeltype == LABEL_STATIC
                               && layout->latextype == LATEX_ENVIRONMENT
                               && !isFirstInSequence(pit, pars_))) {
-                        string leftm = layout->leftmargin;
-                        docstring dleft(leftm.begin(), leftm.end());
+                       string leftm = layout->leftmargin;
+                       docstring dleft(leftm.begin(), leftm.end());
                        l_margin += font_metrics::signedWidth(dleft,
                                                  labelfont);
                } else if (layout->labeltype != LABEL_TOP_ENVIRONMENT
                           && layout->labeltype != LABEL_BIBLIO
                           && layout->labeltype !=
                           LABEL_CENTERED_TOP_ENVIRONMENT) {
-                        string labin = layout->labelindent;
-                        docstring dlabin(labin.begin(), labin.end());
+                       string labin = layout->labelindent;
+                       docstring dlabin(labin.begin(), labin.end());
                        l_margin += font_metrics::signedWidth(dlabin,
                                                  labelfont);
-                        string labsep = layout->labelsep;
-                        docstring dlabsep(labsep.begin(), labsep.end());
+                       string labsep = layout->labelsep;
+                       docstring dlabsep(labsep.begin(), labsep.end());
                        l_margin += font_metrics::width(dlabsep, labelfont);
-                        string labstr = par.getLabelstring();
-                        docstring dlabstr(labstr.begin(), labstr.end());
+                       string labstr = par.getLabelstring();
+                       docstring dlabstr(labstr.begin(), labstr.end());
                        l_margin += font_metrics::width(dlabstr, labelfont);
                }
                break;
@@ -672,7 +674,7 @@ int LyXText::leftMargin(pit_type const pit, pos_type const pos) const
                || bv()->buffer()->params().paragraph_separation ==
                   BufferParams::PARSEP_INDENT))
        {
-                docstring din(parindent.begin(), parindent.end());
+               docstring din(parindent.begin(), parindent.end());
                l_margin += font_metrics::signedWidth(din, params.getFont());
        }
 
@@ -682,16 +684,19 @@ int LyXText::leftMargin(pit_type const pit, pos_type const pos) const
 
 int LyXText::rightMargin(Paragraph const & par) const
 {
+       // FIXME: the correct way is to only call rightMargin() only
+       // within the main LyXText. The following test is thus bogus.
+       LyXText const & text = bv()->buffer()->text();
        // We do not want rightmargins on inner texts.
-       if (bv()->text() != this)
+       if (&text != this)
                return 0;
 
        BufferParams const & params = bv()->buffer()->params();
        LyXTextClass const & tclass = params.getLyXTextClass();
-        string trmarg = tclass.rightmargin();
-        docstring dtrmarg(trmarg.begin(), trmarg.end());
-        string lrmarg = par.layout()->rightmargin;
-        docstring dlrmarg(lrmarg.begin(), lrmarg.end());
+       string trmarg = tclass.rightmargin();
+       docstring dtrmarg(trmarg.begin(), trmarg.end());
+       string lrmarg = par.layout()->rightmargin;
+       docstring dlrmarg(lrmarg.begin(), lrmarg.end());
        int const r_margin =
                ::rightMargin()
                + font_metrics::signedWidth(dtrmarg,
@@ -777,8 +782,8 @@ void LyXText::rowBreakPoint(pit_type const pit, Row & row) const
 
                // add the auto-hfill from label end to the body
                if (body_pos && i == body_pos) {
-                        string lsep = layout->labelsep;
-                        docstring dlsep(lsep.begin(), lsep.end());
+                       string lsep = layout->labelsep;
+                       docstring dlsep(lsep.begin(), lsep.end());
                        int add = font_metrics::width(dlsep, getLabelFont(par));
                        if (par.isLineSeparator(i - 1))
                                add -= singleWidth(par, i - 1);
@@ -853,7 +858,7 @@ void LyXText::setRowWidth(pit_type const pit, Row & row) const
 
        Paragraph const & par = pars_[pit];
        string const & labelsep = par.layout()->labelsep;
-        docstring dlsep(labelsep.begin(), labelsep.end());
+       docstring dlsep(labelsep.begin(), labelsep.end());
        int w = leftMargin(pit, row.pos());
 
        pos_type const body_pos = par.beginOfBody();
@@ -906,7 +911,7 @@ int LyXText::labelFill(Paragraph const & par, Row const & row) const
        if (label.empty())
                return 0;
 
-        docstring dlab(label.begin(), label.end());
+       docstring dlab(label.begin(), label.end());
        return max(0, font_metrics::width(dlab, getLabelFont(par)) - w);
 }
 
@@ -1077,8 +1082,12 @@ void LyXText::setHeightOfRow(pit_type const pit, Row & row)
        maxasc  += int(layoutasc  * 2 / (2 + pars_[pit].getDepth()));
        maxdesc += int(layoutdesc * 2 / (2 + pars_[pit].getDepth()));
 
+       // FIXME: the correct way is to do the following is to move the 
+       // following code in another method specially tailored for the 
+       // main LyXText. The following test is thus bogus.
+       LyXText const & text = bv_owner->buffer()->text();
        // Top and bottom margin of the document (only at top-level)
-       if (bv_owner->text() == this) {
+       if (&text == this) {
                if (pit == 0 && row.pos() == 0)
                        maxasc += 20;
                if (pit + 1 == pit_type(pars_.size()) &&
@@ -1193,9 +1202,9 @@ void LyXText::insertChar(LCursor & cur, char_type c)
                par.isFreeSpacing();
 
        if (lyxrc.auto_number) {
-               static string const number_operators = "+-/*";
-               static string const number_unary_operators = "+-";
-               static string const number_seperators = ".,:";
+               static docstring const number_operators = lyx::from_ascii("+-/*");
+               static docstring const number_unary_operators = lyx::from_ascii("+-");
+               static docstring const number_seperators = lyx::from_ascii(".,:");
 
                if (current_font.number() == LyXFont::ON) {
                        if (!isDigit(c) && !contains(number_operators, c) &&
@@ -1240,7 +1249,7 @@ void LyXText::insertChar(LCursor & cur, char_type c)
                        static bool sent_space_message = false;
                        if (!sent_space_message) {
                                cur.message(_("You cannot insert a space at the "
-                                       "beginning of a paragraph. Please read the Tutorial."));
+                                                          "beginning of a paragraph. Please read the Tutorial."));
                                sent_space_message = true;
                        }
                        return;
@@ -1252,7 +1261,7 @@ void LyXText::insertChar(LCursor & cur, char_type c)
                        static bool sent_space_message = false;
                        if (!sent_space_message) {
                                cur.message(_("You cannot type two spaces this way. "
-                                       "Please read the Tutorial."));
+                                                          "Please read the Tutorial."));
                                sent_space_message = true;
                        }
                        return;
@@ -1382,8 +1391,8 @@ LyXText::computeRowMetrics(pit_type const pit, Row const & row) const
                if (body_pos > 0
                    && (body_pos > end || !par.isLineSeparator(body_pos - 1)))
                {
-                        string lsep = layout->labelsep;
-                        docstring dlsep(lsep.begin(), lsep.end());
+                       string lsep = layout->labelsep;
+                       docstring dlsep(lsep.begin(), lsep.end());
                        result.x += font_metrics::width(dlsep, getLabelFont(par));
                        if (body_pos <= end)
                                result.x += result.label_hfill;
@@ -1671,7 +1680,9 @@ bool LyXText::erase(LCursor & cur)
                } else {
                        setCursorIntern(scur, scur.pit(), scur.pos(), false, scur.boundary());
                }
-       }
+       } else
+               needsUpdate = dissolveInset(cur);
+
        return needsUpdate;
 }
 
@@ -1757,6 +1768,9 @@ bool LyXText::backspace(LCursor & cur)
        BOOST_ASSERT(this == cur.text());
        bool needsUpdate = false;
        if (cur.pos() == 0) {
+               if (cur.pit() == 0)
+                       return dissolveInset(cur);
+
                // The cursor is at the beginning of a paragraph, so
                // the the backspace will collapse two paragraphs into
                // one.
@@ -1797,6 +1811,40 @@ bool LyXText::backspace(LCursor & cur)
 }
 
 
+bool LyXText::dissolveInset(LCursor & cur) {
+       BOOST_ASSERT(this == cur.text());
+
+       if (isMainText() || cur.inset().nargs() != 1)
+               return false;
+
+       recordUndoInset(cur);
+       cur.selHandle(false);
+       // save position
+       lyx::pos_type spos = cur.pos();
+       lyx::pit_type spit = cur.pit();
+       ParagraphList plist;
+       if (cur.lastpit() != 0 || cur.lastpos() != 0)
+               plist = paragraphs();
+       cur.popLeft();
+       // store cursor offset
+       if (spit == 0)
+               spos += cur.pos();
+       spit += cur.pit();
+       cur.paragraph().erase(cur.pos());
+       if (!plist.empty()) {
+               Buffer & b = cur.buffer();
+               pasteParagraphList(cur, plist, b.params().textclass,
+                                  b.errorList("Paste"));
+               // restore position
+               cur.pit() = std::min(cur.lastpit(), spit);
+               cur.pos() = std::min(cur.lastpos(), spos);
+       }
+       cur.clearSelection();
+       cur.resetAnchor();
+       return true;
+}
+
+
 Row const & LyXText::firstRow() const
 {
        return *paragraphs().front().rows().begin();
@@ -2253,8 +2301,8 @@ int LyXText::cursorX(CursorSlice const & sl, bool boundary) const
        for (pos_type vpos = row_pos; vpos < cursor_vpos; ++vpos) {
                pos_type pos = bidi.vis2log(vpos);
                if (body_pos > 0 && pos == body_pos - 1) {
-                        string lsep = par.layout()->labelsep;
-                        docstring dlsep(lsep.begin(), lsep.end());
+                       string lsep = par.layout()->labelsep;
+                       docstring dlsep(lsep.begin(), lsep.end());
                        x += m.label_hfill
                                + font_metrics::width(dlsep,
                                                      getLabelFont(par));
@@ -2334,11 +2382,11 @@ string LyXText::currentState(LCursor & cur)
        if (show_change) {
                Change change = par.lookupChange(cur.pos());
                Author const & a = buf.params().authors().get(change.author);
-               os << _("Change: ") << a.name();
+               os << lyx::to_utf8(_("Change: ")) << a.name();
                if (!a.email().empty())
                        os << " (" << a.email() << ")";
                if (change.changetime)
-                       os << _(" at ") << ctime(&change.changetime);
+                       os << lyx::to_utf8(_(" at ")) << ctime(&change.changetime);
                os << " : ";
        }
 
@@ -2348,34 +2396,34 @@ string LyXText::currentState(LCursor & cur)
        LyXFont font = real_current_font;
        font.reduce(buf.params().getFont());
 
-       // avoid _(...) re-entrance problem
+       // avoid lyx::to_utf8(_(...)) re-entrance problem
        string const s = font.stateText(&buf.params());
-       os << bformat(_("Font: %1$s"), s);
+       os << lyx::to_utf8(bformat(_("Font: %1$s"), lyx::from_utf8(s)));
 
-       // os << bformat(_("Font: %1$s"), font.stateText(&buf.params));
+       // os << lyx::to_utf8(bformat(_("Font: %1$s"), font.stateText(&buf.params)));
 
        // The paragraph depth
        int depth = cur.paragraph().getDepth();
        if (depth > 0)
-               os << bformat(_(", Depth: %1$d"), depth);
+               os << lyx::to_utf8(bformat(_(", Depth: %1$d"), depth));
 
        // The paragraph spacing, but only if different from
        // buffer spacing.
        Spacing const & spacing = par.params().spacing();
        if (!spacing.isDefault()) {
-               os << _(", Spacing: ");
+               os << lyx::to_utf8(_(", Spacing: "));
                switch (spacing.getSpace()) {
                case Spacing::Single:
-                       os << _("Single");
+                       os << lyx::to_utf8(_("Single"));
                        break;
                case Spacing::Onehalf:
-                       os << _("OneHalf");
+                       os << lyx::to_utf8(_("OneHalf"));
                        break;
                case Spacing::Double:
-                       os << _("Double");
+                       os << lyx::to_utf8(_("Double"));
                        break;
                case Spacing::Other:
-                       os << _("Other (") << spacing.getValueAsString() << ')';
+                       os << lyx::to_utf8(_("Other (")) << spacing.getValueAsString() << ')';
                        break;
                case Spacing::Default:
                        // should never happen, do nothing
@@ -2384,11 +2432,11 @@ string LyXText::currentState(LCursor & cur)
        }
 
 #ifdef DEVEL_VERSION
-       os << _(", Inset: ") << &cur.inset();
-       os << _(", Paragraph: ") << cur.pit();
-       os << _(", Id: ") << par.id();
-       os << _(", Position: ") << cur.pos();
-       os << _(", Boundary: ") << cur.boundary();
+       os << lyx::to_utf8(_(", Inset: ")) << &cur.inset();
+       os << lyx::to_utf8(_(", Paragraph: ")) << cur.pit();
+       os << lyx::to_utf8(_(", Id: ")) << par.id();
+       os << lyx::to_utf8(_(", Position: ")) << cur.pos();
+       os << lyx::to_utf8(_(", Boundary: ")) << cur.boundary();
 //     Row & row = cur.textRow();
 //     os << bformat(_(", Row b:%1$d e:%2$d"), row.pos(), row.endpos());
 #endif
@@ -2490,6 +2538,7 @@ pos_type LyXText::x2pos(pit_type pit, int row, int x) const
 // sets cursor only within this LyXText
 bool LyXText::setCursorFromCoordinates(LCursor & cur, int const x, int const y)
 {
+       BOOST_ASSERT(this == cur.text());
        pit_type pit = getPitNearY(y);
        int yy = theCoords.get(this, pit).y_ - pars_[pit].ascent();
        lyxerr[Debug::DEBUG]