]> git.lyx.org Git - lyx.git/blobdiff - src/insets/insettext.C
clear()->erase() ; lots of using directives for cxx
[lyx.git] / src / insets / insettext.C
index d06b57abcbea289530585557b584c1693f25551a..e0b8f1f5b35ef77a7f2bdc85ec5bb3384fbc66f5 100644 (file)
 #include "lyxcursor.h"
 #include "CutAndPaste.h"
 #include "font.h"
+#include "minibuffer.h"
+#include "toolbar.h"
 
 using std::ostream;
 using std::ifstream;
+using std::endl;
 using std::min;
 using std::max;
 
 extern unsigned char getCurrentTextClass(Buffer *);
+extern LyXTextClass::size_type current_layout;
+
 
 InsetText::InsetText(Buffer * buf)
 {
@@ -75,13 +80,13 @@ InsetText::InsetText(InsetText const & ins, Buffer * buf)
     autoBreakRows = ins.autoBreakRows;
 }
 
+
 void InsetText::init(Buffer * buf, InsetText const * ins)
 {
     the_locking_inset = 0;
     buffer = buf;
     cursor_visible = false;
     cursor.x_fix = -1;
-    selection_start = selection_end = 0;
     interline_space = 1;
     no_selection = false;
     init_inset = true;
@@ -90,14 +95,13 @@ void InsetText::init(Buffer * buf, InsetText const * ins)
     autoBreakRows = false;
     xpos = 0.0;
     if (ins) {
-       if (par)
-           delete par;
-       par = ins->par->Clone();
+       SetParagraphData(ins->par);
        autoBreakRows = ins->autoBreakRows;
     }
     par->SetInsetOwner(this);
     cursor.par = par;
     cursor.pos = 0;
+    selection_start_cursor = selection_end_cursor = cursor;
 }
 
 
@@ -208,10 +212,15 @@ void InsetText::draw(Painter & pain, LyXFont const & f,
     xpos = x;
     UpdatableInset::draw(pain, f, baseline, x);
     
-    top_x = int(x);
-    top_baseline = baseline;
-    computeTextRows(pain, x);
-    computeBaselines(baseline);
+    if (init_inset || (baseline != top_baseline) || (top_x != int(x))) {
+       top_baseline = baseline;
+       if (init_inset || (top_x != int(x))) {
+           top_x = int(x);
+           computeTextRows(pain, x);
+           init_inset = false;
+       }
+       computeBaselines(baseline);
+    }
     if (the_locking_inset && (cursor.pos == inset_pos)) {
        resetPos(pain);
        inset_x = cursor.x - top_x + drawTextXOffset;
@@ -233,12 +242,12 @@ void InsetText::drawRowSelection(Painter & pain, int startpos, int endpos,
        return;
 
     int s_start, s_end;
-    if (selection_start > selection_end) {
-       s_start = selection_end;
-       s_end = selection_start;
+    if (selection_start_cursor.pos > selection_end_cursor.pos) {
+       s_start = selection_end_cursor.pos;
+       s_end = selection_start_cursor.pos;
     } else {
-       s_start = selection_start;
-       s_end = selection_end;
+       s_start = selection_start_cursor.pos;
+       s_end = selection_end_cursor.pos;
     }
     if ((s_start > endpos) || (s_end < startpos))
        return;
@@ -343,11 +352,10 @@ void InsetText::Edit(BufferView * bv, int x, int y, unsigned int button)
        return;
     }
     the_locking_inset = 0;
-    selection_start = selection_end = inset_pos = inset_x = inset_y = 0;
-//    no_selection = true;
+    inset_pos = inset_x = inset_y = 0;
     setPos(bv->painter(), x, y);
     checkAndActivateInset(bv, x, y, button);
-    selection_start = selection_end = cursor.pos;
+    selection_start_cursor = selection_end_cursor = cursor;
     current_font = real_current_font = GetFont(par, cursor.pos);
     bv->text->FinishUndo();
     UpdateLocal(bv, true);
@@ -360,15 +368,17 @@ void InsetText::InsetUnlock(BufferView * bv)
        the_locking_inset->InsetUnlock(bv);
        the_locking_inset = 0;
     }
+    HideInsetCursor(bv);
     lyxerr[Debug::INSETS] << "InsetText::InsetUnlock(" << this <<
            ")" << endl;
     if (hasSelection()) {
-       selection_start = selection_end = cursor.pos;
+       selection_start_cursor = selection_end_cursor = cursor;
        UpdateLocal(bv, false);
     }
     no_selection = false;
 }
 
+
 bool InsetText::LockInsetInInset(BufferView * bv, UpdatableInset * inset)
 {
     lyxerr[Debug::INSETS] << "InsetText::LockInsetInInset(" << inset << "): ";
@@ -399,6 +409,7 @@ bool InsetText::LockInsetInInset(BufferView * bv, UpdatableInset * inset)
     return false;
 }
 
+
 bool InsetText::UnlockInsetInInset(BufferView * bv, UpdatableInset * inset,
                                   bool lr)
 {
@@ -435,7 +446,7 @@ bool InsetText::UpdateInsetInInset(BufferView * bv, Inset * inset)
 void InsetText::InsetButtonPress(BufferView * bv, int x, int y, int button)
 {
     if (hasSelection()) {
-       selection_start = selection_end = cursor.pos;
+       selection_start_cursor = selection_end_cursor = cursor;
        UpdateLocal(bv, false);
     }
     no_selection = false;
@@ -476,7 +487,7 @@ void InsetText::InsetButtonPress(BufferView * bv, int x, int y, int button)
            UpdateLocal(bv, true);
        }
     }
-    selection_start = selection_end = cursor.pos;
+    selection_start_cursor = selection_end_cursor = cursor;
 }
 
 
@@ -511,11 +522,11 @@ void InsetText::InsetMotionNotify(BufferView * bv, int x, int y, int state)
         return;
     }
     if (!no_selection) {
-       int old = selection_end;
+       LyXCursor old = selection_end_cursor;
        HideInsetCursor(bv);
        setPos(bv->painter(), x, y);
-       selection_end = cursor.pos;
-       if (old != selection_end)
+       selection_end_cursor = cursor;
+       if (old != selection_end_cursor)
            UpdateLocal(bv, false);
        ShowInsetCursor(bv);
     }
@@ -583,82 +594,82 @@ InsetText::LocalDispatch(BufferView * bv,
            bv->text->cursor.par->ParFromPos(bv->text->cursor.pos)->previous,
            bv->text->cursor.par->ParFromPos(bv->text->cursor.pos)->next);
        cutSelection();
-       cursor.pos = selection_start;
+       cursor = selection_start_cursor;
        par->InsertChar(cursor.pos,arg[0]);
        SetCharFont(cursor.pos,current_font);
        ++cursor.pos;
-       selection_start = selection_end = cursor.pos;
+       selection_start_cursor = selection_end_cursor = cursor;
        UpdateLocal(bv, true);
        break;
         // --- Cursor Movements ---------------------------------------------
     case LFUN_RIGHTSEL:
        bv->text->FinishUndo();
        moveRight(bv, false);
-       selection_end = cursor.pos;
+       selection_end_cursor = cursor;
        UpdateLocal(bv, false);
        break;
     case LFUN_RIGHT:
        bv->text->FinishUndo();
        result = moveRight(bv);
        if (hasSelection()) {
-           selection_start = selection_end = cursor.pos;
+           selection_start_cursor = selection_end_cursor = cursor;
            UpdateLocal(bv, false);
        } else {
-           selection_start = selection_end = cursor.pos;
+           selection_start_cursor = selection_end_cursor = cursor;
        }
        break;
     case LFUN_LEFTSEL:
        bv->text->FinishUndo();
        moveLeft(bv, false);
-       selection_end = cursor.pos;
+       selection_end_cursor = cursor;
        UpdateLocal(bv, false);
        break;
     case LFUN_LEFT:
        bv->text->FinishUndo();
        result= moveLeft(bv);
        if (hasSelection()) {
-               selection_start = selection_end = cursor.pos;
+               selection_start_cursor = selection_end_cursor = cursor;
                UpdateLocal(bv, false);
        } else {
-               selection_start = selection_end = cursor.pos;
+               selection_start_cursor = selection_end_cursor = cursor;
        }
        break;
     case LFUN_DOWNSEL:
        bv->text->FinishUndo();
        moveDown(bv);
-       selection_end = cursor.pos;
+       selection_end_cursor = cursor;
        UpdateLocal(bv, false);
        break;
     case LFUN_DOWN:
        bv->text->FinishUndo();
        result = moveDown(bv);
        if (hasSelection()) {
-           selection_start = selection_end = cursor.pos;
+           selection_start_cursor = selection_end_cursor = cursor;
            UpdateLocal(bv, false);
        } else {
-           selection_start = selection_end = cursor.pos;
+           selection_start_cursor = selection_end_cursor = cursor;
        }
        break;
     case LFUN_UPSEL:
        bv->text->FinishUndo();
        moveUp(bv);
-       selection_end = cursor.pos;
+       selection_end_cursor = cursor;
        UpdateLocal(bv, false);
        break;
     case LFUN_UP:
        bv->text->FinishUndo();
        result = moveUp(bv);
        if (hasSelection()) {
-           selection_start = selection_end = cursor.pos;
+           selection_start_cursor = selection_end_cursor = cursor;
            UpdateLocal(bv, false);
        } else {
-           selection_start = selection_end = cursor.pos;
+           selection_start_cursor = selection_end_cursor = cursor;
        }
        break;
     case LFUN_BACKSPACE:
-       if (!cursor.pos) { // || par->IsNewline(cursor.pos-1)) {
+       if (!cursor.pos) {
            if (hasSelection()) {
-               selection_start = selection_end = cursor.pos;
+               selection_start_cursor = selection_end_cursor = cursor;
                UpdateLocal(bv, false);
            }
            break;
@@ -671,17 +682,17 @@ InsetText::LocalDispatch(BufferView * bv,
            bv->text->cursor.par->ParFromPos(bv->text->cursor.pos)->next);
        bool ret = true;
        if (hasSelection()) {
-           LyXParagraph::size_type i = selection_start;
-           for (; i < selection_end; ++i) {
-               par->Erase(selection_start);
+           LyXParagraph::size_type i = selection_start_cursor.pos;
+           for (; i < selection_end_cursor.pos; ++i) {
+               par->Erase(selection_start_cursor.pos);
            }
        } else
            ret = Delete();
        if (ret) { // we need update
-           selection_start = selection_end = cursor.pos;
+           selection_start_cursor = selection_end_cursor = cursor;
            UpdateLocal(bv, true);
        } else if (hasSelection()) {
-           selection_start = selection_end = cursor.pos;
+           selection_start_cursor = selection_end_cursor = cursor;
            UpdateLocal(bv, false);
        }
     }
@@ -694,10 +705,10 @@ InsetText::LocalDispatch(BufferView * bv,
 
        if (cutSelection()) {
            // we need update
-           cursor.pos = selection_end = selection_start;
+           cursor = selection_end_cursor = selection_start_cursor;
            UpdateLocal(bv, true);
        } else if (hasSelection()) {
-           selection_start = selection_end = cursor.pos;
+           selection_start_cursor = selection_end_cursor = cursor;
            UpdateLocal(bv, false);
        }
        resetPos(bv->painter());
@@ -706,10 +717,10 @@ InsetText::LocalDispatch(BufferView * bv,
        bv->text->FinishUndo();
        if (copySelection()) {
            // we need update
-           selection_start = selection_end = cursor.pos;
+           selection_start_cursor = selection_end_cursor = cursor;
            UpdateLocal(bv, true);
        } else if (hasSelection()) {
-           selection_start = selection_end = cursor.pos;
+           selection_start_cursor = selection_end_cursor = cursor;
            UpdateLocal(bv, false);
        }
        break;
@@ -719,7 +730,7 @@ InsetText::LocalDispatch(BufferView * bv,
          bv->text->cursor.par->ParFromPos(bv->text->cursor.pos)->previous,
          bv->text->cursor.par->ParFromPos(bv->text->cursor.pos)->next);
        if (pasteSelection()) {
-           selection_start = selection_end = cursor.pos;
+           selection_start_cursor = selection_end_cursor = cursor;
            UpdateLocal(bv, true);
        }
     }
@@ -731,10 +742,10 @@ InsetText::LocalDispatch(BufferView * bv,
            cursor.x -= SingleWidth(bv->painter(), par, cursor.pos);
        cursor.x -= SingleWidth(bv->painter(), par, cursor.pos);
        if (hasSelection()) {
-           selection_start = selection_end = cursor.pos;
+           selection_start_cursor = selection_end_cursor = cursor;
            UpdateLocal(bv, false);
        } else {
-           selection_start = selection_end = cursor.pos;
+           selection_start_cursor = selection_end_cursor = cursor;
        }
        resetPos(bv->painter());
        break;
@@ -747,10 +758,10 @@ InsetText::LocalDispatch(BufferView * bv,
        for(; cursor.pos < checkpos; ++cursor.pos)
            cursor.x += SingleWidth(bv->painter(), par, cursor.pos);
        if (hasSelection()) {
-           selection_start = selection_end = cursor.pos;
+           selection_start_cursor = selection_end_cursor = cursor;
            UpdateLocal(bv, false);
        } else {
-           selection_start = selection_end = cursor.pos;
+           selection_start_cursor = selection_end_cursor = cursor;
        }
     }
     resetPos(bv->painter());
@@ -772,9 +783,42 @@ InsetText::LocalDispatch(BufferView * bv,
        SetCharFont(cursor.pos,current_font);
        UpdateLocal(bv, true);
        ++cursor.pos;
-       selection_start = selection_end = cursor.pos;
+       selection_start_cursor = selection_end_cursor = cursor;
        resetPos(bv->painter());
        break;
+    case LFUN_LAYOUT:
+    {
+       // Derive layout number from given argument (string)
+       // and current buffer's textclass (number). */    
+       LyXTextClassList::ClassList::size_type tclass =
+           buffer->params.textclass;
+       std::pair <bool, LyXTextClass::size_type> layout = 
+           textclasslist.NumberOfLayout(tclass, arg);
+
+       // If the entry is obsolete, use the new one instead.
+       if (layout.first) {
+           string obs = textclasslist.Style(tclass,layout.second).
+               obsoleted_by();
+           if (!obs.empty()) 
+               layout = textclasslist.NumberOfLayout(tclass, obs);
+       }
+
+       // see if we found the layout number:
+       if (!layout.first) {
+           string msg = string(N_("Layout ")) + arg + N_(" not known");
+
+           bv->owner()->getMiniBuffer()->Set(msg);
+           break;
+       }
+
+       if (current_layout != layout.second) {
+           bv->text->SetLayout(cursor, selection_start_cursor,
+                               selection_end_cursor, layout.second);
+           bv->owner()->getToolbar()->combox->select(cursor.par->GetLayout()+1);
+           UpdateLocal(bv, true);
+       }
+    }
+    break;
     default:
        result = UNDISPATCHED;
        break;
@@ -787,11 +831,11 @@ InsetText::LocalDispatch(BufferView * bv,
 }
 
 
-int InsetText::Latex(ostream & os, bool /*fragile*/, bool) const
+int InsetText::Latex(ostream & os, bool /*fragile*/, bool /*fp*/) const
 {
-       TexRow texrow;
-       int ret = par->SimpleTeXOnePar(os, texrow);
-       return ret;
+    TexRow texrow;
+    buffer->latexParagraphs(os, par, 0, texrow);
+    return texrow.rows();
 }
 
 
@@ -917,12 +961,14 @@ LyXFont InsetText::GetFont(LyXParagraph * par, int pos) const
     return tmpfont;
 }
 
+
 // the font for drawing may be different from the real font
 LyXFont InsetText::GetDrawFont(LyXParagraph * par, int pos) const
 {
     return GetFont(par, pos);
 }
 
+
 int InsetText::BeginningOfMainBody(LyXParagraph * par) const
 {
     if (textclasslist.Style(buffer->params.textclass,
@@ -1007,7 +1053,8 @@ void InsetText::setPos(Painter & pain, int x, int y) const
     cursor.y = top_baseline;
     y += cursor.y;
     for(unsigned int i = 1;
-       ((cursor.y + rows[i - 1].desc) < y) && (i < rows.size() - 1); ++i) {
+       (long(cursor.y + rows[i - 1].desc) < y)
+               && (i < rows.size() - 1); ++i) {
        cursor.y = rows[i].baseline;
        cursor.pos = rows[i].pos;
        actrow = i;
@@ -1035,6 +1082,8 @@ void InsetText::setPos(Painter & pain, int x, int y) const
 
 void InsetText::resetPos(Painter & pain) const
 {
+    cursor.par = par;
+
     if (!rows.size())
        return;
 
@@ -1042,7 +1091,8 @@ void InsetText::resetPos(Painter & pain) const
 
     cursor.y = top_baseline;
     actrow = 0;
-    for(unsigned int i = 0; (i < (rows.size()-1)) && (rows[i].pos <= cursor.pos);
+    for(unsigned int i = 0;
+       (i < (rows.size()-1)) && (rows[i].pos <= cursor.pos);
        ++i) {
        cursor.y = rows[i].baseline;
        actrow = i;
@@ -1135,9 +1185,9 @@ bool InsetText::InsertInset(BufferView * bv, Inset * inset)
     par->InsertChar(cursor.pos, LyXParagraph::META_INSET);
     par->InsertInset(cursor.pos, inset);
     if (hasSelection()) {
-       selection_start = selection_end = cursor.pos;
+       selection_start_cursor = selection_end_cursor = cursor;
     } else {
-       selection_start = selection_end = cursor.pos;
+       selection_start_cursor = selection_end_cursor = cursor;
     }
     UpdateLocal(bv, true);
     static_cast<UpdatableInset*>(inset)->Edit(bv, 0, 0, 0);
@@ -1175,12 +1225,12 @@ void InsetText::SetFont(BufferView * bv, LyXFont const & font, bool toggleall)
     }
     
     int s_start, s_end;
-    if (selection_start > selection_end) {
-       s_start = selection_end;
-       s_end = selection_start;
+    if (selection_start_cursor.pos > selection_end_cursor.pos) {
+       s_start = selection_end_cursor.pos;
+       s_end = selection_start_cursor.pos;
     } else {
-       s_start = selection_start;
-       s_end = selection_end;
+       s_start = selection_start_cursor.pos;
+       s_end = selection_end_cursor.pos;
     }
     LyXFont newfont;
     while(s_start < s_end) {
@@ -1287,7 +1337,7 @@ void InsetText::computeTextRows(Painter & pain, float x) const
            }
            rows.back().asc = wordAscent;
            rows.back().desc = wordDescent;
-           row.pos = ++p; // +1;
+           row.pos = ++p;
            rows.push_back(row);
            SingleHeight(pain, par, p, oasc, odesc);
            insetWidth = max(insetWidth, owidth);
@@ -1297,39 +1347,42 @@ void InsetText::computeTextRows(Painter & pain, float x) const
            nwp = p;
            continue;
        }
-       Inset const * inset = 0;
+       Inset * inset = 0;
        if (((p + 1) < par->Last()) &&
            (par->GetChar(p + 1)==LyXParagraph::META_INSET))
            inset = par->GetInset(p + 1);
-       if (inset && inset->display()) {
-           if (!is_first_word_in_row && (width >= maxWidth)) {
-               // we have to split also the row above
+       if (inset) {
+               inset->setOwner(const_cast<InsetText*>(this)); // is this safe?
+           if (inset->display()) {
+               if (!is_first_word_in_row && (width >= maxWidth)) {
+                   // we have to split also the row above
+                   rows.back().asc = oasc;
+                   rows.back().desc = odesc;
+                   row.pos = nwp;
+                   rows.push_back(row);
+                   oasc = wordAscent;
+                   odesc = wordDescent;
+                   insetWidth = max(insetWidth, owidth);
+                   width = lastWordWidth;
+                   lastWordWidth = 0;
+               } else {
+                   oasc = max(oasc, wordAscent);
+                   odesc = max(odesc, wordDescent);
+               }
                rows.back().asc = oasc;
                rows.back().desc = odesc;
-               row.pos = nwp;
+               row.pos = ++p;
                rows.push_back(row);
-               oasc = wordAscent;
-               odesc = wordDescent;
-               insetWidth = max(insetWidth, owidth);
-               width = lastWordWidth;
-               lastWordWidth = 0;
-           } else {
-                   oasc = max(oasc, wordAscent);
-                   odesc = max(odesc, wordDescent);
+               SingleHeight(pain, par, p, asc, desc);
+               rows.back().asc = asc;
+               rows.back().desc = desc;
+               row.pos = nwp = p + 1;
+               rows.push_back(row);
+               oasc = odesc = width = lastWordWidth = 0;
+               is_first_word_in_row = true;
+               wordAscent = wordDescent = 0;
+               continue;
            }
-           rows.back().asc = oasc;
-           rows.back().desc = odesc;
-           row.pos = ++p;
-           rows.push_back(row);
-           SingleHeight(pain, par, p, asc, desc);
-           rows.back().asc = asc;
-           rows.back().desc = desc;
-           row.pos = nwp = p + 1;
-           rows.push_back(row);
-           oasc = odesc = width = lastWordWidth = 0;
-           is_first_word_in_row = true;
-           wordAscent = wordDescent = 0;
-           continue;
        } else if (par->IsSeparator(p)) {
            if (width >= maxWidth) {
                if (is_first_word_in_row) {
@@ -1400,9 +1453,9 @@ void InsetText::computeBaselines(int baseline) const
     }
 }
 
-void InsetText::UpdateLocal(BufferView *bv, bool flag)
+
+void InsetText::UpdateLocal(BufferView * bv, bool flag)
 {
-#if 1
     if (flag) {
        computeTextRows(bv->painter(), xpos);
        computeBaselines(top_baseline);
@@ -1410,12 +1463,10 @@ void InsetText::UpdateLocal(BufferView *bv, bool flag)
     bv->updateInset(this, flag);
     if (flag)
        resetPos(bv->painter());
-#else
-    init_inset = flag;
-    bv->updateInset(this, flag);
-#endif
+    bv->owner()->getToolbar()->combox->select(cursor.par->GetLayout()+1);
 }
 
+
 bool InsetText::cutSelection()
 {
     if (!hasSelection())
@@ -1423,12 +1474,20 @@ bool InsetText::cutSelection()
 
     CutAndPaste cap;
 
-    LyXParagraph *endpar = par;
+    LyXParagraph * endpar = par;
+    int start, end;
+    if (selection_start_cursor.pos > selection_end_cursor.pos) {
+           start = selection_end_cursor.pos;
+           end = selection_start_cursor.pos;
+    } else {
+           start = selection_start_cursor.pos;
+           end = selection_end_cursor.pos;
+    }
 
-    return cap.cutSelection(par, &endpar, selection_start, selection_end,
-                           buffer->params.textclass);
+    return cap.cutSelection(par, &endpar, start, end,buffer->params.textclass);
 }
 
+
 bool InsetText::copySelection()
 {
     if (!hasSelection())
@@ -1436,10 +1495,18 @@ bool InsetText::copySelection()
 
     CutAndPaste cap;
 
-    return cap.copySelection(par, par, selection_start, selection_end,
-                            buffer->params.textclass);
+    int start, end;
+    if (selection_start_cursor.pos > selection_end_cursor.pos) {
+           start = selection_end_cursor.pos;
+           end = selection_start_cursor.pos;
+    } else {
+           start = selection_start_cursor.pos;
+           end = selection_end_cursor.pos;
+    }
+    return cap.copySelection(par, par, start, end, buffer->params.textclass);
 }
 
+
 bool InsetText::pasteSelection()
 {
     CutAndPaste cap;
@@ -1457,6 +1524,7 @@ bool InsetText::pasteSelection()
                              buffer->params.textclass);
 }
 
+
 bool InsetText::checkAndActivateInset(BufferView * bv, int x, int y,
                                      int button)
 {
@@ -1479,8 +1547,18 @@ bool InsetText::checkAndActivateInset(BufferView * bv, int x, int y,
     return false;
 }
 
+
 int InsetText::getMaxTextWidth(Painter & pain, UpdatableInset const * inset,
                               int x) const
 {
     return getMaxWidth(pain, inset) - x;
 }
+
+void InsetText::SetParagraphData(LyXParagraph *p)
+{
+    if (par)
+       delete par;
+    par = p->Clone();
+    par->SetInsetOwner(this);
+    init_inset = true;
+}