]> git.lyx.org Git - lyx.git/blobdiff - src/insets/insettabular.C
(Herbert): strip the extension from the graphics filename when exporting
[lyx.git] / src / insets / insettabular.C
index e748979ca765b9bf1de1306b70ee7e0c8d5be250..b3a9435665f7321f217d0f6a4bfc2e911ac8f4ce 100644 (file)
@@ -1,6 +1,6 @@
 /* This file is part of
  * ======================================================
- * 
+ *
  *           LyX, The Document Processor
  *
  *           Copyright 2001 The LyX Team.
@@ -16,6 +16,7 @@
 
 #include "insettabular.h"
 
+#include "lyx_cb.h"
 #include "buffer.h"
 #include "commandtags.h"
 #include "lyxfunc.h"
 #include "Painter.h"
 #include "font.h"
 #include "lyxtext.h"
-#include "lyx_gui_misc.h"
 #include "LyXView.h"
 #include "insets/insettext.h"
 #include "debug.h"
-#include "WorkArea.h"
 #include "gettext.h"
 #include "language.h"
 #include "BufferView.h"
@@ -48,6 +47,8 @@
 #include <map>
 //#include <signal.h>
 
+
+using std::vector;
 using std::ostream;
 using std::ifstream;
 using std::max;
@@ -134,10 +135,11 @@ InsetTabular::InsetTabular(Buffer const & buf, int rows, int columns)
                rows = 1;
        if (columns <= 0)
                columns = 1;
-       tabular.reset(new LyXTabular(this, rows, columns));
+       tabular.reset(new LyXTabular(buf.params, this, rows, columns));
        // for now make it always display as display() inset
        // just for test!!!
        the_locking_inset = 0;
+       old_locking_inset = 0;
        locked = false;
        oldcell = -1;
        actrow = actcell = 0;
@@ -145,6 +147,8 @@ InsetTabular::InsetTabular(Buffer const & buf, int rows, int columns)
        need_update = INIT;
        in_update = false;
        in_reset_pos = false;
+       inset_x = 0;
+       inset_y = 0;
 }
 
 
@@ -152,8 +156,10 @@ InsetTabular::InsetTabular(InsetTabular const & tab, Buffer const & buf,
                                                   bool same_id)
        : UpdatableInset(tab, same_id), buffer(&buf)
 {
-       tabular.reset(new LyXTabular(this, *(tab.tabular), same_id));
+       tabular.reset(new LyXTabular(buf.params,
+                                    this, *(tab.tabular), same_id));
        the_locking_inset = 0;
+       old_locking_inset = 0;
        locked = false;
        oldcell = -1;
        actrow = actcell = 0;
@@ -161,6 +167,8 @@ InsetTabular::InsetTabular(InsetTabular const & tab, Buffer const & buf,
        need_update = INIT;
        in_update = false;
        in_reset_pos = false;
+       inset_x = 0;
+       inset_y = 0;
 }
 
 
@@ -253,13 +261,13 @@ void InsetTabular::draw(BufferView * bv, LyXFont const & font, int baseline,
                x += static_cast<float>(scroll());
 #endif
        if (!cleared && ((need_update == INIT) || (need_update == FULL) ||
-                        (top_x != int(x)) || (top_baseline != baseline)))
+                        (top_x != int(x)) || (top_baseline != baseline)))
        {
                int h = ascent(bv, font) + descent(bv, font);
                int const tx = display() || !owner() ? 0 : top_x;
                int w =  tx ? width(bv, font) : pain.paperWidth();
                int ty = baseline - ascent(bv, font);
-       
+
                if (ty < 0)
                        ty = 0;
                if ((ty + h) > pain.paperHeight())
@@ -300,7 +308,7 @@ void InsetTabular::draw(BufferView * bv, LyXFont const & font, int baseline,
                                if (hasSelection()) {
                                        drawCellSelection(pain, nx, baseline, i, j, cell);
                                }
-                               
+
                                tabular->GetCellInset(cell)->draw(bv, font, baseline, cx, cleared);
                                drawCellLines(pain, nx, baseline, i, cell);
                                nx += tabular->GetWidthOfColumn(cell);
@@ -366,22 +374,24 @@ void InsetTabular::draw(BufferView * bv, LyXFont const & font, int baseline,
                // Here we use rectangular backgroundColor patches to clean up
                // within a cell around the cell's red inset box. As follows:
                //
-               //  +---+            +---+
-               //  |   |            |   |   The rectangles are A, B and C
-               //  | A |------------| B |   below, origin top left (tx, ty), 
+               //  +--------------------+
+               //  |         C          |   The rectangles are A, B and C
+               //  | A |------------| B |   below, origin top left (tx, ty),
                //  |   |  inset box |   |   dimensions w(idth), h(eight).
                //  +---+------------+---+   x grows rightward, y downward
                //  |         D          |
                //  +--------------------+
                //
+#if 0
                // clear only if we didn't have a change
                if (bv->text->status() != LyXText::CHANGED_IN_DRAW) {
+#endif
                        // clear before the inset
                        int tx, ty, w, h;
-                       tx = nx + 1; 
+                       tx = nx + 1;
                        ty = baseline - tabular->GetAscentOfRow(i) + 1;
                        w = int(cx - nx - 1);
-                       h = tabular->GetAscentOfRow(i) + 
+                       h = tabular->GetAscentOfRow(i) +
                                tabular->GetDescentOfRow(i) - 1;
                        pain.fillRectangle(tx, ty, w, h, backgroundColor());
                        // clear behind the inset
@@ -401,7 +411,16 @@ void InsetTabular::draw(BufferView * bv, LyXFont const & font, int baseline,
                        h = tabular->GetDescentOfRow(i) -
                                the_locking_inset->descent(bv, font) - 1;
                        pain.fillRectangle(tx, ty, w, h, backgroundColor());
+                       // clear above the inset
+                       tx = nx + 1;
+                       ty = baseline - tabular->GetAscentOfRow(i) + 1;
+                       w = tabular->GetWidthOfColumn(cell) -
+                               tabular->GetAdditionalWidth(cell) - 1;
+                       h = tabular->GetAscentOfRow(i) - the_locking_inset->ascent(bv, font);
+                       pain.fillRectangle(tx, ty, w, h, backgroundColor());
+#if 0
                }
+#endif
        }
        x -= ADD_TO_TABULAR_WIDTH;
        x += width(bv, font);
@@ -418,11 +437,11 @@ void InsetTabular::draw(BufferView * bv, LyXFont const & font, int baseline,
 
 
 void InsetTabular::drawCellLines(Painter & pain, int x, int baseline,
-                                 int row, int cell) const
+                                int row, int cell) const
 {
        int x2 = x + tabular->GetWidthOfColumn(cell);
        bool on_off;
-       
+
        if (!tabular->TopAlreadyDrawed(cell)) {
                on_off = !tabular->TopLine(cell);
                pain.line(x, baseline - tabular->GetAscentOfRow(row),
@@ -464,12 +483,12 @@ void InsetTabular::drawCellSelection(Painter & pain, int x, int baseline,
        } else {
                ce = tabular->right_column_of_cell(sel_cell_end);
        }
-       
+
        int rs = tabular->row_of_cell(sel_cell_start);
        int re = tabular->row_of_cell(sel_cell_end);
        if (rs > re)
                swap(rs, re);
-       
+
        if ((column >= cs) && (column <= ce) && (row >= rs) && (row <= re)) {
                int w = tabular->GetWidthOfColumn(cell);
                int h = tabular->GetAscentOfRow(row) + tabular->GetDescentOfRow(row);
@@ -511,11 +530,13 @@ void InsetTabular::update(BufferView * bv, LyXFont const & font, bool reinit)
        case INIT:
        case FULL:
        case CELL:
-               if (calculate_dimensions_of_cells(bv, font, false))
+               if (calculate_dimensions_of_cells(bv, font, false)) {
                        need_update = INIT;
+                       resetPos(bv);
+               }
                break;
        case SELECTION:
-               need_update = INIT;
+               need_update = FULL;
                break;
        default:
                break;
@@ -533,7 +554,7 @@ string const InsetTabular::editMessage() const
 void InsetTabular::edit(BufferView * bv, int x, int y, unsigned int button)
 {
        UpdatableInset::edit(bv, x, y, button);
-       
+
        if (!bv->lockInset(this)) {
                lyxerr[Debug::INSETTEXT] << "InsetTabular::Cannot lock inset" << endl;
                return;
@@ -554,11 +575,12 @@ void InsetTabular::edit(BufferView * bv, int x, int y, unsigned int button)
 void InsetTabular::edit(BufferView * bv, bool front)
 {
        UpdatableInset::edit(bv, front);
-       
+
        if (!bv->lockInset(this)) {
                lyxerr[Debug::INSETTEXT] << "InsetTabular::Cannot lock inset" << endl;
                return;
        }
+       finishUndo();
        locked = true;
        the_locking_inset = 0;
        inset_x = 0;
@@ -569,7 +591,7 @@ void InsetTabular::edit(BufferView * bv, bool front)
                actcell = tabular->GetNumberOfCells() - 1;
        clearSelection();
        resetPos(bv);
-       finishUndo();
+       bv->fitCursor();
 }
 
 
@@ -577,6 +599,7 @@ void InsetTabular::insetUnlock(BufferView * bv)
 {
        if (the_locking_inset) {
                the_locking_inset->insetUnlock(bv);
+               updateLocal(bv, CELL, false);
                the_locking_inset = 0;
        }
        hideInsetCursor(bv);
@@ -599,11 +622,15 @@ void InsetTabular::updateLocal(BufferView * bv, UpdateCodes what,
                LyXFont font;
                calculate_dimensions_of_cells(bv, font, true);
        }
+       if (!locked && what == CELL)
+               what = FULL;
        if (need_update < what) // only set this if it has greater update
                need_update = what;
+#if 0 // maybe this should not be done!
        if ((what == INIT) && hasSelection()) {
                clearSelection();
        }
+#endif
        // Dirty Cast! (Lgb)
        if (need_update != NONE) {
                bv->updateInset(const_cast<InsetTabular *>(this), mark_dirty);
@@ -639,9 +666,7 @@ bool InsetTabular::lockInsetInInset(BufferView * bv, UpdatableInset * inset)
                        }
                        if (in->getInsetFromID(id)) {
                                actcell = i;
-                               the_locking_inset = in;
-                               locked = true;
-                               resetPos(bv);
+                               in->edit(bv);
                                return the_locking_inset->lockInsetInInset(bv, inset);
                        }
                }
@@ -664,7 +689,6 @@ bool InsetTabular::unlockInsetInInset(BufferView * bv, UpdatableInset * inset,
                return false;
        if (the_locking_inset == inset) {
                the_locking_inset->insetUnlock(bv);
-               the_locking_inset = 0;
 #ifdef WITH_WARNINGS
 #warning fix scrolling when cellinset has requested a scroll (Jug)!!!
 #endif
@@ -673,7 +697,9 @@ bool InsetTabular::unlockInsetInInset(BufferView * bv, UpdatableInset * inset,
                        scroll(bv, 0.0F);
 #endif
                updateLocal(bv, CELL, false);
-               showInsetCursor(bv, false);
+               // this has to be here otherwise we don't redraw the cell!
+               the_locking_inset = 0;
+//             showInsetCursor(bv, false);
                return true;
        }
        if (the_locking_inset->unlockInsetInInset(bv, inset, lr)) {
@@ -690,10 +716,16 @@ bool InsetTabular::unlockInsetInInset(BufferView * bv, UpdatableInset * inset,
 
 bool InsetTabular::updateInsetInInset(BufferView * bv, Inset * inset)
 {
-       if (!the_locking_inset)
+       Inset * tl_inset = inset;
+       // look if this inset is really inside myself!
+       while(tl_inset->owner() && tl_inset->owner() != this)
+               tl_inset = tl_inset->owner();
+       // if we enter here it's not ower inset
+       if (!tl_inset->owner())
                return false;
-       if (the_locking_inset != inset) {
-               if (!the_locking_inset->updateInsetInInset(bv, inset))
+       // we only have to do this if this is a subinset of our cells
+       if (tl_inset != inset) {
+               if (!static_cast<InsetText *>(tl_inset)->updateInsetInInset(bv, inset))
                        return false;
        }
        updateLocal(bv, CELL, false);
@@ -701,7 +733,7 @@ bool InsetTabular::updateInsetInInset(BufferView * bv, Inset * inset)
 }
 
 
-unsigned int InsetTabular::insetInInsetY()
+int InsetTabular::insetInInsetY() const
 {
        if (!the_locking_inset)
                return 0;
@@ -748,6 +780,12 @@ void InsetTabular::insetButtonPress(BufferView * bv, int x, int y, int button)
        int const orow = actrow;
 
        hideInsetCursor(bv);
+       if (!locked) {
+               locked = true;
+               the_locking_inset = 0;
+               inset_x = 0;
+               inset_y = 0;
+       }
        setPos(bv, x, y);
        if (actrow != orow)
                updateLocal(bv, NONE, false);
@@ -756,6 +794,7 @@ void InsetTabular::insetButtonPress(BufferView * bv, int x, int y, int button)
        if (button == 3) {
                if ((ocell != actcell) && the_locking_inset) {
                        the_locking_inset->insetUnlock(bv);
+                       updateLocal(bv, CELL, false);
                        the_locking_inset = 0;
                }
                showInsetCursor(bv);
@@ -773,18 +812,20 @@ void InsetTabular::insetButtonPress(BufferView * bv, int x, int y, int button)
                return;
        } else if (the_locking_inset) {
                the_locking_inset->insetUnlock(bv);
+               updateLocal(bv, CELL, false);
+               the_locking_inset = 0;
        }
-       the_locking_inset = 0;
        if (button == 2) {
                localDispatch(bv, LFUN_PASTESELECTION, "paragraph");
                return;
        }
        if (inset_hit && bv->theLockingInset()) {
-               if (activateCellInsetAbs(bv, x, y, button))
-                       the_locking_inset->insetButtonPress(bv,
-                                                           x - inset_x,
-                                                           y - inset_y,
-                                                           button);
+               if (!bv->lockInset(static_cast<UpdatableInset*>(tabular->GetCellInset(actcell)))) {
+                       lyxerr[Debug::INSETS] << "Cannot lock inset" << endl;
+                       return;
+               }
+               the_locking_inset->insetButtonPress(
+                       bv, x - inset_x, y - inset_y, button);
                return;
        }
        showInsetCursor(bv);
@@ -792,7 +833,7 @@ void InsetTabular::insetButtonPress(BufferView * bv, int x, int y, int button)
 
 
 bool InsetTabular::insetButtonRelease(BufferView * bv,
-                                      int x, int y, int button)
+                                     int x, int y, int button)
 {
        bool ret = false;
        if (the_locking_inset)
@@ -815,10 +856,10 @@ void InsetTabular::insetMotionNotify(BufferView * bv, int x, int y, int button)
                                                     button);
                return;
        }
+
        hideInsetCursor(bv);
 //     int const old_cell = actcell;
-       
+
        setPos(bv, x, y);
        if (!hasSelection()) {
                setSelection(actcell, actcell);
@@ -841,9 +882,9 @@ void InsetTabular::insetKeyPress(XKeyEvent * xke)
 
 UpdatableInset::RESULT
 InsetTabular::localDispatch(BufferView * bv, kb_action action,
-                            string const & arg)
+                           string const & arg)
 {
-       // We need to save the value of the_locking_inset as the call to 
+       // We need to save the value of the_locking_inset as the call to
        // the_locking_inset->LocalDispatch might unlock it.
        old_locking_inset = the_locking_inset;
        UpdatableInset::RESULT result =
@@ -920,7 +961,7 @@ InsetTabular::localDispatch(BufferView * bv, kb_action action,
                        setSelection(start, actcell);
                        break;
                }
-               
+
                int end = actcell;
                // if we are starting a selection, only select
                // the current cell at the beginning
@@ -944,11 +985,11 @@ InsetTabular::localDispatch(BufferView * bv, kb_action action,
                        setSelection(start, actcell);
                        break;
                }
+
                int end = actcell;
                // if we are starting a selection, only select
                // the current cell at the beginning
-               if (hasSelection()) { 
+               if (hasSelection()) {
                        moveLeft(bv, false);
                        end = actcell;
                }
@@ -1012,27 +1053,37 @@ InsetTabular::localDispatch(BufferView * bv, kb_action action,
                        updateLocal(bv, SELECTION, false);
                break;
        case LFUN_NEXT: {
+               UpdateCodes code = CURSOR;
+               if (hs) {
+                       clearSelection();
+                       code = SELECTION;
+               }
                int column = actcol;
                unlockInsetInInset(bv, the_locking_inset);
-               if (bv->text->first + bv->painter().paperHeight() <
+               if (bv->text->first_y + bv->painter().paperHeight() <
                    (top_baseline + tabular->GetHeightOfTabular()))
                        {
-                               bv->scrollCB(bv->text->first + bv->painter().paperHeight());
-                               updateLocal(bv, FULL, false);
+                               bv->scrollCB(bv->text->first_y + bv->painter().paperHeight());
+                               code = FULL;
                                actcell = tabular->GetCellBelow(first_visible_cell) + column;
                        } else {
                                actcell = tabular->GetFirstCellInRow(tabular->rows() - 1) + column;
                        }
                resetPos(bv);
-               updateLocal(bv, CURSOR, false);
+               updateLocal(bv, code, false);
                break;
        }
        case LFUN_PRIOR: {
+               UpdateCodes code = CURSOR;
+               if (hs) {
+                       clearSelection();
+                       code = SELECTION;
+               }
                int column = actcol;
                unlockInsetInInset(bv, the_locking_inset);
                if (top_baseline < 0) {
-                       bv->scrollCB(bv->text->first - bv->painter().paperHeight());
-                       updateLocal(bv, FULL, false);
+                       bv->scrollCB(bv->text->first_y - bv->painter().paperHeight());
+                       code = FULL;
                        if (top_baseline > 0)
                                actcell = column;
                        else
@@ -1041,7 +1092,7 @@ InsetTabular::localDispatch(BufferView * bv, kb_action action,
                        actcell = column;
                }
                resetPos(bv);
-               updateLocal(bv, CURSOR, false);
+               updateLocal(bv, code, false);
                break;
        }
        // none of these make sense for insettabular,
@@ -1051,7 +1102,7 @@ InsetTabular::localDispatch(BufferView * bv, kb_action action,
        case LFUN_NEXTSEL:
        case LFUN_WORDLEFT:
        case LFUN_WORDLEFTSEL:
-       case LFUN_WORDRIGHT: 
+       case LFUN_WORDRIGHT:
        case LFUN_WORDRIGHTSEL:
        case LFUN_DOWN_PARAGRAPH:
        case LFUN_DOWN_PARAGRAPHSEL:
@@ -1063,6 +1114,10 @@ InsetTabular::localDispatch(BufferView * bv, kb_action action,
        case LFUN_HOMESEL:
        case LFUN_END:
        case LFUN_ENDSEL:
+       case LFUN_BEGINNINGBUF:
+       case LFUN_BEGINNINGBUFSEL:
+       case LFUN_ENDBUF:
+       case LFUN_ENDBUFSEL:
                break;
        case LFUN_LAYOUT_TABULAR:
                bv->owner()->getDialogs()->showTabular(this);
@@ -1071,12 +1126,26 @@ InsetTabular::localDispatch(BufferView * bv, kb_action action,
                if (!tabularFeatures(bv, arg))
                        result = UNDISPATCHED;
                break;
+               // insert file functions
+       case LFUN_FILE_INSERT_ASCII_PARA:
+       case LFUN_FILE_INSERT_ASCII:
+       {
+               string tmpstr = getContentsOfAsciiFile(bv, arg, false);
+               if (tmpstr.empty())
+                       break;
+               if (insertAsciiString(bv, tmpstr, false))
+                       updateLocal(bv, INIT, true);
+               else
+                       result = UNDISPATCHED;
+               break;
+       }
+       // cut and paste functions
        case LFUN_CUT:
                if (!copySelection(bv))
                        break;
                setUndo(bv, Undo::DELETE,
-                       bv->text->cursor.par(),
-                       bv->text->cursor.par()->next());
+                       bv->text->cursor.par(),
+                       bv->text->cursor.par()->next());
                cutSelection();
                updateLocal(bv, INIT, true);
                break;
@@ -1089,9 +1158,9 @@ InsetTabular::localDispatch(BufferView * bv, kb_action action,
        case LFUN_PASTESELECTION:
        {
                string const clip(bv->getClipboard());
-       
-               if (clip.empty())
+                       if (clip.empty())
                        break;
+#if 0
                if (clip.find('\t') != string::npos) {
                        int cols = 1;
                        int rows = 1;
@@ -1101,7 +1170,7 @@ InsetTabular::localDispatch(BufferView * bv, kb_action action,
 
                        while (p < len &&
                              ((p = clip.find_first_of("\t\n", p)) != string::npos)) {
-                               switch(clip[p]) {
+                               switch (clip[p]) {
                                case '\t':
                                        ++cols;
                                        break;
@@ -1116,7 +1185,8 @@ InsetTabular::localDispatch(BufferView * bv, kb_action action,
                        }
                        maxCols = max(cols, maxCols);
                        delete paste_tabular;
-                       paste_tabular = new LyXTabular(this, rows, maxCols);
+                       paste_tabular = new LyXTabular(bv->buffer()->params,
+                                                      this, rows, maxCols);
                        string::size_type op = 0;
                        int cell = 0;
                        int cells = paste_tabular->GetNumberOfCells();
@@ -1125,7 +1195,7 @@ InsetTabular::localDispatch(BufferView * bv, kb_action action,
                              (p = clip.find_first_of("\t\n", p)) != string::npos) {
                                if (p >= len)
                                        break;
-                               switch(clip[p]) {
+                               switch (clip[p]) {
                                case '\t':
                                        paste_tabular->GetCellInset(cell)->setText(clip.substr(op, p-op));
                                        ++cols;
@@ -1144,7 +1214,11 @@ InsetTabular::localDispatch(BufferView * bv, kb_action action,
                        // check for the last cell if there is no trailing '\n'
                        if ((cell < cells) && (op < len))
                                paste_tabular->GetCellInset(cell)->setText(clip.substr(op, len-op));
-               } else {
+               } else
+#else
+               if (!insertAsciiString(bv, clip, true))
+#endif
+               {
                        // so that the clipboard is used and it goes on
                        // to default
                        // and executes LFUN_PASTESELECTION in insettext!
@@ -1155,18 +1229,39 @@ InsetTabular::localDispatch(BufferView * bv, kb_action action,
        case LFUN_PASTE:
                if (hasPasteBuffer()) {
                        setUndo(bv, Undo::INSERT,
-                               bv->text->cursor.par(),
-                               bv->text->cursor.par()->next());
+                               bv->text->cursor.par(),
+                               bv->text->cursor.par()->next());
                        pasteSelection(bv);
                        updateLocal(bv, INIT, true);
                        break;
                }
                // ATTENTION: the function above has to be PASTE and PASTESELECTION!!!
        default:
+               // handle font changing stuff on selection before we lock the inset
+               // in the default part!
+               result = UNDISPATCHED;
+               if (hs) {
+                       switch(action) {
+                       case LFUN_LANGUAGE:
+                       case LFUN_EMPH:
+                       case LFUN_BOLD:
+                       case LFUN_NOUN:
+                       case LFUN_CODE:
+                       case LFUN_SANS:
+                       case LFUN_ROMAN:
+                       case LFUN_DEFAULT:
+                       case LFUN_UNDERLINE:
+                       case LFUN_FONT_SIZE:
+                               if (bv->Dispatch(action, arg))
+                                       result = DISPATCHED;
+                               break;
+                       default:
+                               break;
+                       }
+               }
                // we try to activate the actual inset and put this event down to
                // the insets dispatch function.
-               result = UNDISPATCHED;
-               if (the_locking_inset)
+               if ((result == DISPATCHED) || the_locking_inset)
                        break;
                nodraw(true);
                if (activateCellInset(bv)) {
@@ -1181,6 +1276,9 @@ InsetTabular::localDispatch(BufferView * bv, kb_action action,
                                return UNDISPATCHED;
                        } else if (hs) {
                                clearSelection();
+                               // so the below CELL is not set because this is higher
+                               // priority and we get a full redraw
+                               need_update = SELECTION;
                        }
                        nodraw(false);
                        updateLocal(bv, CELL, false);
@@ -1190,7 +1288,10 @@ InsetTabular::localDispatch(BufferView * bv, kb_action action,
        }
        if (result < FINISHED) {
                if (!the_locking_inset) {
-                       showInsetCursor(bv);
+                       if (bv->fitCursor())
+                               updateLocal(bv, FULL, false);
+                       if (locked)
+                               showInsetCursor(bv);
                }
        } else
                bv->unlockInset(this);
@@ -1199,7 +1300,7 @@ InsetTabular::localDispatch(BufferView * bv, kb_action action,
 
 
 int InsetTabular::latex(Buffer const * buf, ostream & os,
-                        bool fragile, bool fp) const
+                       bool fragile, bool fp) const
 {
        return tabular->latex(buf, os, fragile, fp);
 }
@@ -1209,14 +1310,19 @@ int InsetTabular::ascii(Buffer const * buf, ostream & os, int ll) const
 {
        if (ll > 0)
                return tabular->ascii(buf, os, (int)parOwner()->params().depth(),
-                                     false,0);
+                                     false,0);
        return tabular->ascii(buf, os, 0, false,0);
 }
 
 
 int InsetTabular::linuxdoc(Buffer const * buf, ostream & os) const
 {
-       return tabular->ascii(buf,os, (int)parOwner()->params().depth(), false, 0);
+       os << "<![CDATA[";
+       int const ret = tabular->ascii(buf,os,
+                                      (int)parOwner()->params().depth(),
+                                      false, 0);
+       os << "]]>";
+       return ret;
 }
 
 
@@ -1251,15 +1357,15 @@ void InsetTabular::validate(LaTeXFeatures & features) const
 
 
 bool InsetTabular::calculate_dimensions_of_cells(BufferView * bv,
-                                                 LyXFont const & font,
-                                                 bool reinit) const
+                                                LyXFont const & font,
+                                                bool reinit) const
 {
        int cell = -1;
        int maxAsc = 0;
        int maxDesc = 0;
        InsetText * inset;
        bool changed = false;
-       
+
        // if we have a locking_inset we should have to check only this cell for
        // change so I'll try this to have a boost, but who knows ;)
        if ((need_update != INIT) &&
@@ -1320,12 +1426,12 @@ void InsetTabular::toggleInsetCursor(BufferView * bv)
                the_locking_inset->toggleInsetCursor(bv);
                return;
        }
-       
+
        LyXFont font; // = the_locking_inset->GetFont(par, cursor.pos);
-       
+
        int const asc = lyxfont::maxAscent(font);
        int const desc = lyxfont::maxDescent(font);
-       
+
        if (isCursorVisible())
                bv->hideLockedInsetCursor();
        else
@@ -1340,7 +1446,7 @@ void InsetTabular::showInsetCursor(BufferView * bv, bool show)
                return;
        if (!isCursorVisible()) {
                LyXFont font; // = GetFont(par, cursor.pos);
-       
+
                int const asc = lyxfont::maxAscent(font);
                int const desc = lyxfont::maxDescent(font);
                bv->fitLockedInsetCursor(cursor_.x(), cursor_.y(), asc, desc);
@@ -1363,21 +1469,25 @@ void InsetTabular::hideInsetCursor(BufferView * bv)
 void InsetTabular::fitInsetCursor(BufferView * bv) const
 {
        if (the_locking_inset) {
+               int old_first_y = bv->text->first_y;
                the_locking_inset->fitInsetCursor(bv);
+               if (old_first_y != bv->text->first_y)
+                       need_update = FULL;
                return;
        }
        LyXFont font;
-       
+
        int const asc = lyxfont::maxAscent(font);
        int const desc = lyxfont::maxDescent(font);
-       bv->fitLockedInsetCursor(cursor_.x(), cursor_.y(), asc, desc);
+       if (bv->fitLockedInsetCursor(cursor_.x(), cursor_.y(), asc, desc))
+               need_update = FULL;
 }
 
 
 void InsetTabular::setPos(BufferView * bv, int x, int y) const
 {
        cursor_.y(0);
-       
+
        actcell = actrow = actcol = 0;
        int ly = tabular->GetDescentOfRow(actrow);
 
@@ -1406,7 +1516,7 @@ void InsetTabular::setPos(BufferView * bv, int x, int y) const
 int InsetTabular::getCellXPos(int cell) const
 {
        int c = cell;
-       
+
        for (; !tabular->IsFirstCellInRow(c); --c)
                ;
        int lx = tabular->GetWidthOfColumn(cell);
@@ -1419,7 +1529,9 @@ int InsetTabular::getCellXPos(int cell) const
 
 void InsetTabular::resetPos(BufferView * bv) const
 {
+#ifdef WITH_WARNINGS
 #warning This should be fixed in the right manner (20011128 Jug)
+#endif
        // fast hack to fix infinite repaintings!
        if (in_reset_pos)
                return;
@@ -1636,15 +1748,15 @@ bool InsetTabular::deletable() const
 
 
 void InsetTabular::setFont(BufferView * bv, LyXFont const & font, bool tall,
-                           bool selectall)
+                          bool selectall)
 {
        if (selectall) {
                setSelection(0, tabular->GetNumberOfCells() - 1);
        }
        if (hasSelection()) {
                setUndo(bv, Undo::EDIT,
-                       bv->text->cursor.par(),
-                       bv->text->cursor.par()->next());
+                       bv->text->cursor.par(),
+                       bv->text->cursor.par()->next());
                bool frozen = undo_frozen;
                if (!frozen)
                        freezeUndo();
@@ -1671,11 +1783,11 @@ void InsetTabular::setFont(BufferView * bv, LyXFont const & font, bool tall,
 bool InsetTabular::tabularFeatures(BufferView * bv, string const & what)
 {
        LyXTabular::Feature action = LyXTabular::LAST_ACTION;
-       
+
        int i = 0;
        for (; tabularFeature[i].action != LyXTabular::LAST_ACTION; ++i) {
                string const tmp = tabularFeature[i].feature;
-               
+
                if (tmp == what.substr(0, tmp.length())) {
                        //if (!compare(tabularFeatures[i].feature.c_str(), what.c_str(),
                        //tabularFeatures[i].feature.length())) {
@@ -1693,7 +1805,7 @@ bool InsetTabular::tabularFeatures(BufferView * bv, string const & what)
 }
 
 static void checkLongtableSpecial(LyXTabular::ltType & ltt,
-                                  string const & special, bool & flag)
+                                 string const & special, bool & flag)
 {
        if (special == "dl_above") {
                ltt.topDL = flag;
@@ -1712,8 +1824,8 @@ static void checkLongtableSpecial(LyXTabular::ltType & ltt,
 
 
 void InsetTabular::tabularFeatures(BufferView * bv,
-                                   LyXTabular::Feature feature,
-                                   string const & value)
+                                  LyXTabular::Feature feature,
+                                  string const & value)
 {
        int sel_col_start;
        int sel_col_end;
@@ -1758,20 +1870,20 @@ void InsetTabular::tabularFeatures(BufferView * bv,
                sel_row_start = sel_row_end = tabular->row_of_cell(actcell);
        }
        setUndo(bv, Undo::FINISH,
-               bv->text->cursor.par(),
-               bv->text->cursor.par()->next());
+               bv->text->cursor.par(),
+               bv->text->cursor.par()->next());
 
        int row =  tabular->row_of_cell(actcell);
        int column = tabular->column_of_cell(actcell);
        bool flag = true;
        LyXTabular::ltType ltt;
-       
+
        switch (feature) {
        case LyXTabular::SET_PWIDTH:
        {
                LyXLength const vallen(value);
                LyXLength const & tmplen = tabular->GetColumnPWidth(actcell);
-               
+
                bool const update = (tmplen != vallen);
                tabular->SetColumnPWidth(actcell, vallen);
                if (update) {
@@ -1788,7 +1900,7 @@ void InsetTabular::tabularFeatures(BufferView * bv,
        {
                LyXLength const vallen(value);
                LyXLength const & tmplen = tabular->GetPWidth(actcell);
-               
+
                bool const update = (tmplen != vallen);
                tabular->SetMColumnPWidth(actcell, vallen);
                if (update) {
@@ -1808,13 +1920,13 @@ void InsetTabular::tabularFeatures(BufferView * bv,
        case LyXTabular::APPEND_ROW:
                // append the row into the tabular
                unlockInsetInInset(bv, the_locking_inset);
-               tabular->AppendRow(actcell);
+               tabular->AppendRow(bv->buffer()->params, actcell);
                updateLocal(bv, INIT, true);
                break;
        case LyXTabular::APPEND_COLUMN:
                // append the column into the tabular
                unlockInsetInInset(bv, the_locking_inset);
-               tabular->AppendColumn(actcell);
+               tabular->AppendColumn(bv->buffer()->params, actcell);
                actcell = tabular->GetCellNumber(row, column);
                updateLocal(bv, INIT, true);
                break;
@@ -1853,12 +1965,12 @@ void InsetTabular::tabularFeatures(BufferView * bv,
                updateLocal(bv, INIT, true);
                break;
        }
-       
+
        case LyXTabular::M_TOGGLE_LINE_BOTTOM:
                flag = false;
        case LyXTabular::TOGGLE_LINE_BOTTOM:
        {
-               bool lineSet = !tabular->BottomLine(actcell, flag); 
+               bool lineSet = !tabular->BottomLine(actcell, flag);
                for (int i = sel_row_start; i <= sel_row_end; ++i)
                        for (int j = sel_col_start; j <= sel_col_end; ++j)
                                tabular->SetBottomLine(
@@ -1868,7 +1980,7 @@ void InsetTabular::tabularFeatures(BufferView * bv,
                updateLocal(bv, INIT, true);
                break;
        }
-       
+
        case LyXTabular::M_TOGGLE_LINE_LEFT:
                flag = false;
        case LyXTabular::TOGGLE_LINE_LEFT:
@@ -1883,7 +1995,7 @@ void InsetTabular::tabularFeatures(BufferView * bv,
                updateLocal(bv, INIT, true);
                break;
        }
-       
+
        case LyXTabular::M_TOGGLE_LINE_RIGHT:
                flag = false;
        case LyXTabular::TOGGLE_LINE_RIGHT:
@@ -1898,7 +2010,7 @@ void InsetTabular::tabularFeatures(BufferView * bv,
                updateLocal(bv, INIT, true);
                break;
        }
-       
+
        case LyXTabular::M_ALIGN_LEFT:
        case LyXTabular::M_ALIGN_RIGHT:
        case LyXTabular::M_ALIGN_CENTER:
@@ -1931,8 +2043,8 @@ void InsetTabular::tabularFeatures(BufferView * bv,
        case LyXTabular::MULTICOLUMN:
        {
                if (sel_row_start != sel_row_end) {
-                       Alert::alert(_("Impossible Operation!"), 
-                                  _("Multicolumns can only be horizontally."), 
+                       Alert::alert(_("Impossible Operation!"),
+                                  _("Multicolumns can only be horizontally."),
                                   _("Sorry."));
                        return;
                }
@@ -1943,7 +2055,7 @@ void InsetTabular::tabularFeatures(BufferView * bv,
                                tabular->UnsetMultiColumn(actcell);
                                updateLocal(bv, INIT, true);
                        } else {
-                               tabular->SetMultiColumn(actcell, 1);
+                               tabular->SetMultiColumn(bv->buffer(), actcell, 1);
                                updateLocal(bv, CELL, true);
                        }
                        return;
@@ -1960,7 +2072,7 @@ void InsetTabular::tabularFeatures(BufferView * bv,
                        s_start = sel_cell_start;
                        s_end = sel_cell_end;
                }
-               tabular->SetMultiColumn(s_start, s_end - s_start + 1);
+               tabular->SetMultiColumn(bv->buffer(), s_start, s_end - s_start + 1);
                actcell = s_start;
                clearSelection();
                updateLocal(bv, INIT, true);
@@ -2096,49 +2208,30 @@ bool InsetTabular::insetHit(BufferView *, int x, int) const
 int InsetTabular::getMaxWidthOfCell(BufferView * bv, int cell) const
 {
        LyXLength const len = tabular->GetPWidth(cell);
-       
+
        if (len.zero())
                return -1;
-#ifdef WITH_WARNINGS
-#warning Remove use of VSpace as soon as LyXLength::inPixels exists (JMarc)
-#endif
-       return VSpace(len).inPixels(bv);
+       return len.inPixels(latexTextWidth(bv), bv->text->defaultHeight());
 }
 
 
 int InsetTabular::getMaxWidth(BufferView * bv,
-                              UpdatableInset const * inset) const
+                             UpdatableInset const * inset) const
 {
-       int cell = tabular->cur_cell;
-       if (tabular->GetCellInset(cell) != inset) {
-               cell = actcell;
-               if (tabular->GetCellInset(cell) != inset) {
-                       
-                       lyxerr[Debug::INSETTEXT] << "Actcell not equal to actual cell!\n";
-                       cell = -1;
-               }
-       }
-       
-       int const n = tabular->GetNumberOfCells();
+       int cell = tabular->GetCellFromInset(inset, actcell);
 
        if (cell == -1) {
-               for (cell = 0; cell < n; ++cell) {
-                       if (tabular->GetCellInset(cell) == inset)
-                               break;
-               }
-       }
-       
-       if (cell >= n) {
-               lyxerr << "Own inset not found, shouldn't really happen!\n";
+               lyxerr << "Own inset not found, shouldn't really happen!"
+                      << endl;
                return -1;
        }
-       
+
        int w = getMaxWidthOfCell(bv, cell);
        if (w > 0) {
                // because the inset then subtracts it's top_x and owner->x()
                w += (inset->x() - top_x);
        }
-       
+
        return w;
 }
 
@@ -2163,7 +2256,7 @@ void InsetTabular::resizeLyXText(BufferView * bv, bool force) const
 
 
 LyXText * InsetTabular::getLyXText(BufferView const * bv,
-                                   bool const recursive) const
+                                  bool const recursive) const
 {
        if (the_locking_inset)
                return the_locking_inset->getLyXText(bv, recursive);
@@ -2212,11 +2305,11 @@ FuncStatus InsetTabular::getStatus(string const & what) const
 {
        int action = LyXTabular::LAST_ACTION;
        FuncStatus status;
-       
+
        int i = 0;
        for (; tabularFeature[i].action != LyXTabular::LAST_ACTION; ++i) {
                string const tmp = tabularFeature[i].feature;
-               if (tmp == what.substr(0, tmp.length())) {                  
+               if (tmp == what.substr(0, tmp.length())) {
                        //if (!compare(tabularFeatures[i].feature.c_str(), what.c_str(),
                        //   tabularFeatures[i].feature.length())) {
                        action = tabularFeature[i].action;
@@ -2227,7 +2320,7 @@ FuncStatus InsetTabular::getStatus(string const & what) const
                status.clear();
                return status.unknown(true);
        }
-       
+
        string const argument = frontStrip(what.substr(tabularFeature[i].feature.length()));
 
        int sel_row_start;
@@ -2355,7 +2448,7 @@ FuncStatus InsetTabular::getStatus(string const & what) const
 }
 
 
-std::vector<string> const InsetTabular::getLabelList() const
+vector<string> const InsetTabular::getLabelList() const
 {
        return tabular->getLabelList();
 }
@@ -2384,7 +2477,8 @@ bool InsetTabular::copySelection(BufferView * bv)
        int const rows = sel_row_end - sel_row_start + 1;
 
        delete paste_tabular;
-       paste_tabular = new LyXTabular(this, *tabular); // rows, columns);
+       paste_tabular = new LyXTabular(bv->buffer()->params,
+                                      this, *tabular); // rows, columns);
        for (int i = 0; i < sel_row_start; ++i)
                paste_tabular->DeleteRow(0);
        while (paste_tabular->rows() > rows)
@@ -2402,7 +2496,7 @@ bool InsetTabular::copySelection(BufferView * bv)
 
        ostringstream sstr;
        paste_tabular->ascii(bv->buffer(), sstr,
-                            (int)parOwner()->params().depth(), true, '\t');
+                            (int)parOwner()->params().depth(), true, '\t');
        bv->stuffClipboard(sstr.str().c_str());
        return true;
 }
@@ -2471,7 +2565,7 @@ bool InsetTabular::cutSelection()
 }
 
 
-bool InsetTabular::isRightToLeft(BufferView *bv )
+bool InsetTabular::isRightToLeft(BufferView * bv)
 {
        return bv->getParentLanguage(this)->RightToLeft();
 }
@@ -2507,7 +2601,7 @@ void InsetTabular::getSelection(int & srow, int & erow,
 {
        int const start = hasSelection() ? sel_cell_start : actcell;
        int const end = hasSelection() ? sel_cell_end : actcell;
+
        srow = tabular->row_of_cell(start);
        erow = tabular->row_of_cell(end);
        if (srow > erow) {
@@ -2619,7 +2713,7 @@ string InsetTabular::selectNextWordInt(BufferView * bv, float & value) const
                bv->unlockInset(const_cast<InsetTabular *>(this));
                return string();
        }
-       
+
        // otherwise we have to lock the next inset and ask for it's selecttion
        UpdatableInset * inset =
                static_cast<UpdatableInset*>(tabular->GetCellInset(++actcell));
@@ -2647,7 +2741,7 @@ void InsetTabular::toggleSelection(BufferView * bv, bool kill_selection)
 
 
 bool InsetTabular::searchForward(BufferView * bv, string const & str,
-                                 bool const & cs, bool const & mw)
+                                bool cs, bool mw)
 {
        nodraw(true);
        if (the_locking_inset) {
@@ -2675,7 +2769,7 @@ bool InsetTabular::searchForward(BufferView * bv, string const & str,
 
 
 bool InsetTabular::searchBackward(BufferView * bv, string const & str,
-                               bool const & cs, bool const & mw)
+                              bool cs, bool mw)
 {
        nodraw(true);
        if (the_locking_inset) {
@@ -2706,39 +2800,119 @@ bool InsetTabular::insetAllowed(Inset::Code code) const
 {
        if (the_locking_inset)
                return the_locking_inset->insetAllowed(code);
-       return false;
+       // we return true here because if the inset is not locked someone
+       // wants to insert something in one of our insettexts and we generally
+       // allow to do so.
+       return true;
 }
 
 
 bool InsetTabular::forceDefaultParagraphs(Inset const * in) const
 {
-       int const n = tabular->GetNumberOfCells();
-       static int last = 0;
+       const int cell = tabular->GetCellFromInset(in, actcell);
 
-       // maybe some speedup
-       if ((last < n) && tabular->GetCellInset(last) == in) {
-               if (tabular->GetPWidth(last+1).zero())
-                       return true;
-               return false;
-       }
-       if ((++last < n) && tabular->GetCellInset(last) == in) {
-               if (tabular->GetPWidth(last).zero())
-                       return true;
-               return false;
-       }
+       if (cell != -1)
+               return tabular->GetPWidth(cell).zero();
 
-       for(int i=0; i < n; ++i) {
-               if (tabular->GetCellInset(i) == in) {
-                       last = i;
-                       if (tabular->GetPWidth(i).zero())
-                               return true;
-                       return false;
-               }
-       }
-       last = 0;
        // well we didn't obviously find it so maybe our owner knows more
        if (owner())
                return owner()->forceDefaultParagraphs(in);
        // if we're here there is really something strange going on!!!
        return false;
 }
+
+bool InsetTabular::insertAsciiString(BufferView * bv, string const & buf,
+                                    bool usePaste)
+{
+       if (buf.length() <= 0)
+               return true;
+       
+       int cols = 1;
+       int rows = 1;
+       int maxCols = 1;
+       string::size_type len = buf.length();
+       string::size_type p = 0;
+
+       while (p < len &&
+              ((p = buf.find_first_of("\t\n", p)) != string::npos))
+       {
+               switch (buf[p]) {
+               case '\t':
+                       ++cols;
+                       break;
+               case '\n':
+                       if ((p+1) < len)
+                               ++rows;
+                       maxCols = max(cols, maxCols);
+                       cols = 1;
+                       break;
+               }
+               ++p;
+       }
+       maxCols = max(cols, maxCols);
+       LyXTabular * loctab;
+       int cell = 0;
+       int ocol = 0;
+       int row = 0;
+       if (usePaste) {
+               delete paste_tabular;
+               paste_tabular = new LyXTabular(bv->buffer()->params,
+                                              this, rows, maxCols);
+               loctab = paste_tabular;
+               cols = 0;
+       } else {
+               loctab = tabular.get();
+               cell = actcell;
+               ocol = actcol;
+               row = actrow;
+       }
+       string::size_type op = 0;
+       int cells = loctab->GetNumberOfCells();
+       p = 0;
+       cols = ocol;
+       rows = loctab->rows();
+       int const columns = loctab->columns();
+       while ((cell < cells) && (p < len) && (row < rows) &&
+              (p = buf.find_first_of("\t\n", p)) != string::npos)
+       {
+               if (p >= len)
+                       break;
+               switch (buf[p]) {
+               case '\t':
+                       // we can only set this if we are not too far right
+                       if (cols < columns) {
+                               InsetText * ti = loctab->GetCellInset(cell);
+                               LyXFont const font = ti->getLyXText(bv)->
+                                       getFont(bv->buffer(), ti->paragraph(), 0);
+                               ti->setText(buf.substr(op, p-op), font);
+                               ++cols;
+                               ++cell;
+                       }
+                       break;
+               case '\n':
+                       // we can only set this if we are not too far right
+                       if (cols < columns) {
+                               InsetText * ti = loctab->GetCellInset(cell);
+                               LyXFont const font = ti->getLyXText(bv)->
+                                       getFont(bv->buffer(), ti->paragraph(), 0);
+                               ti->setText(buf.substr(op, p-op), font);
+                       }
+                       cols = ocol;
+                       ++row;
+                       if (row < rows)
+                               cell = loctab->GetCellNumber(row, cols);
+                       break;
+               }
+               ++p;
+               op = p;
+       }
+       // check for the last cell if there is no trailing '\n'
+       if ((cell < cells) && (op < len)) {
+               InsetText * ti = loctab->GetCellInset(cell);
+               LyXFont const font = ti->getLyXText(bv)->
+                       getFont(bv->buffer(), ti->paragraph(), 0);
+               ti->setText(buf.substr(op, len-op), font);
+       }
+
+       return true;
+}