]> git.lyx.org Git - features.git/blobdiff - src/insets/insettabular.C
read the Changelog
[features.git] / src / insets / insettabular.C
index 59ac203dee2cc08bfe27df036dfdc5db34f21e7c..6e6aeac44ae78069c5e5f7bd1cb0a2a333b67e63 100644 (file)
@@ -5,7 +5,7 @@
  *
  *           Copyright 2000 The LyX Team.
  *
- *======================================================
+ * ======================================================
  */
 
 #include <config.h>
 #include "LyXView.h"
 #include "lyxfunc.h"
 #include "insets/insettext.h"
-
-extern void MenuLayoutTabular(bool, InsetTabular *);
-extern bool UpdateLayoutTabular(bool, InsetTabular *);
-extern void TabularOptClose();
+#include "frontends/Dialogs.h"
 
 const int ADD_TO_HEIGHT = 2;
 const int ADD_TO_TABULAR_WIDTH = 2;
@@ -43,6 +40,7 @@ using std::ostream;
 using std::ifstream;
 using std::max;
 using std::endl;
+using std::swap;
 
 #define cellstart(p) ((p % 2) == 0)
 
@@ -58,10 +56,13 @@ InsetTabular::InsetTabular(Buffer * buf, int rows, int columns)
     // just for test!!!
     the_locking_inset = 0;
     locked = no_selection = cursor_visible = false;
-    cursor.x_fix = -1;
+    cursor.x_fix(-1);
     oldcell = -1;
-    actcell = cursor.pos = sel_pos_start = sel_pos_end = 0;
-    init_inset = true;
+    actcell = 0;
+    cursor.pos(0);
+    sel_pos_start = sel_pos_end = sel_cell_start = sel_cell_end = 0;
+    dialogs_ = 0;
+    need_update = INIT;
 }
 
 
@@ -71,16 +72,21 @@ InsetTabular::InsetTabular(InsetTabular const & tab, Buffer * buf)
     tabular = new LyXTabular(this, *(tab.tabular));
     the_locking_inset = 0;
     locked = no_selection = cursor_visible = false;
-    cursor.x_fix = -1;
+    cursor.x_fix(-1);
     oldcell = -1;
-    actcell = cursor.pos = sel_pos_start = sel_pos_end = 0;
-    init_inset = true;
+    actcell = 0;
+    cursor.pos(0);
+    sel_pos_start = sel_pos_end = sel_cell_start = sel_cell_end = 0;
+    dialogs_ = 0;
+    need_update = INIT;
 }
 
 
 InsetTabular::~InsetTabular()
 {
     delete tabular;
+    if (dialogs_)
+       dialogs_->hideTabular(this);
 }
 
 
@@ -93,23 +99,23 @@ Inset * InsetTabular::Clone() const
 }
 
 
-void InsetTabular::Write(ostream & os) const
+void InsetTabular::Write(Buffer const * buf, ostream & os) const
 {
     os << " Tabular" << endl;
-    tabular->Write(os);
+    tabular->Write(buf, os);
 }
 
 
-void InsetTabular::Read(LyXLex & lex)
+void InsetTabular::Read(Buffer const * buf, LyXLex & lex)
 {
     bool old_format = (lex.GetString() == "\\LyXTable");
     string token;
 
     if (tabular)
        delete tabular;
-    tabular = new LyXTabular(this, lex);
+    tabular = new LyXTabular(buf, this, lex);
 
-    init_inset = true;
+    need_update = INIT;
 
     if (old_format)
        return;
@@ -127,74 +133,85 @@ void InsetTabular::Read(LyXLex & lex)
 }
 
 
-int InsetTabular::ascent(Painter & pain, LyXFont const & font) const
+int InsetTabular::ascent(BufferView *, LyXFont const &) const
 {
-    if (init_inset) {
-       calculate_width_of_cells(pain, font);
-       init_inset = false;
-    }
     return tabular->GetAscentOfRow(0);
 }
 
 
-int InsetTabular::descent(Painter & pain, LyXFont const & font) const
+int InsetTabular::descent(BufferView *, LyXFont const &) const
 {
-    if (init_inset) {
-       calculate_width_of_cells(pain, font);
-       init_inset = false;
-    }
-    return tabular->GetHeightOfTabular() - tabular->GetAscentOfRow(0);
+    return tabular->GetHeightOfTabular() - tabular->GetAscentOfRow(0) + 1;
 }
 
 
-int InsetTabular::width(Painter & pain, LyXFont const & font) const
+int InsetTabular::width(BufferView *, LyXFont const &) const
 {
-    if (init_inset) {
-       calculate_width_of_cells(pain, font);
-       init_inset = false;
-    }
     return tabular->GetWidthOfTabular() + (2 * ADD_TO_TABULAR_WIDTH);
 }
 
 
-void InsetTabular::draw(Painter & pain, const LyXFont & font, int baseline,
-                       float & x) const
+void InsetTabular::draw(BufferView * bv, LyXFont const & font, int baseline,
+                       float & x, bool cleared) const
 {
-    int i, j, cell=0;
+    Painter & pain = bv->painter();
+    int i, j, cell = 0;
     int nx;
     float cx;
-    bool reinit = false;
-
-    UpdatableInset::draw(pain,font,baseline,x);
-    if (init_inset || (top_x != int(x)) || (top_baseline != baseline)) {
-       int ox = top_x;
-       init_inset = false;
-       top_x = int(x);
-       top_baseline = baseline;
-       if (ox != top_x)
-           recomputeTextInsets(pain, font);
-       calculate_width_of_cells(pain, font);
-       resetPos(pain);
-       reinit = true;
+
+    UpdatableInset::draw(bv,font,baseline,x,cleared);
+    if (!cleared && ((need_update == INIT) || (need_update == FULL) ||
+                    (top_x != int(x)) || (top_baseline != baseline))) {
+       int h = ascent(bv, font) + descent(bv, font);
+       int 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())
+           h = pain.paperHeight();
+       if ((top_x + w) > pain.paperWidth())
+           w = pain.paperWidth();
+       pain.fillRectangle(tx, ty, w, h);
+       need_update = FULL;
+       cleared = true;
     }
+    top_x = int(x);
+    top_baseline = baseline;
+    bool dodraw;
     x += ADD_TO_TABULAR_WIDTH;
-    for(i=0;i<tabular->rows();++i) {
-       nx = int(x);
-        for(j=0;j<tabular->columns();++j) {
-           if (tabular->IsPartOfMultiColumn(i,j))
-               continue;
-           cx = nx + tabular->GetBeginningOfTextInCell(cell);
-           if (hasSelection())
-               DrawCellSelection(pain, nx, baseline, i, cell);
-           tabular->GetCellInset(cell)->draw(pain, font, baseline, cx);
-           DrawCellLines(pain, nx, baseline, i, cell);
-           nx += tabular->GetWidthOfColumn(cell);
-           ++cell;
+    if (cleared || (need_update == FULL) || (need_update == CELL)) {
+       for(i=0;i<tabular->rows();++i) {
+           nx = int(x);
+           dodraw = ((baseline+tabular->GetDescentOfRow(i)) > 0) &&
+                   (baseline-tabular->GetAscentOfRow(i)) < pain.paperHeight();
+           for(j=0;j<tabular->columns();++j) {
+               if (tabular->IsPartOfMultiColumn(i,j))
+                   continue;
+               cx = nx + tabular->GetBeginningOfTextInCell(cell);
+               if (hasSelection())
+                   DrawCellSelection(pain, nx, baseline, i, j, cell);
+               if (dodraw && !cleared && locked && the_locking_inset) {
+                   if (the_locking_inset == tabular->GetCellInset(cell))
+                       tabular->GetCellInset(cell)->draw(bv, font,
+                                                         baseline, cx,
+                                                         cleared);
+               } else if (dodraw) {
+                   tabular->GetCellInset(cell)->draw(bv, font, baseline, cx,
+                                                     cleared);
+                   DrawCellLines(pain, nx, baseline, i, cell);
+               }
+               nx += tabular->GetWidthOfColumn(cell);
+               ++cell;
+           }
+           baseline += tabular->GetDescentOfRow(i) +
+               tabular->GetAscentOfRow(i+1)+
+               tabular->GetAdditionalHeight(cell+1);
        }
-        baseline += tabular->GetDescentOfRow(i) + tabular->GetAscentOfRow(i+1)
-            + tabular->GetAdditionalHeight(cell+1);
     }
-    x += width(pain, font);
+    x += width(bv, font);
+    need_update = NONE;
 }
 
 
@@ -234,27 +251,22 @@ void InsetTabular::DrawCellLines(Painter & pain, int x, int baseline,
 
 
 void InsetTabular::DrawCellSelection(Painter & pain, int x, int baseline,
-                                    int row, int cell) const
+                                    int row, int column, int cell) const
 {
-    int start, end;
-    if (sel_cell_start > sel_cell_end) {
-       start = sel_cell_end;
-       end = sel_cell_start;
+    int cs = tabular->column_of_cell(sel_cell_start);
+    int ce = tabular->column_of_cell(sel_cell_end);
+    if (cs > ce) {
+       ce = cs;
+       cs = tabular->column_of_cell(sel_cell_end);
     } else {
-       start = sel_cell_start;
-       end = sel_cell_end;
+       ce = tabular->right_column_of_cell(sel_cell_end);
     }
-    int c1 = tabular->column_of_cell(cell);
-    int cs = tabular->column_of_cell(start);
-    int ce;
-    if (tabular->IsLastCellInRow(end))
-       ce = tabular->columns() - 1;
-    else
-       ce = tabular->column_of_cell(end+1) - 1; // because of multic.
-    int rs = tabular->row_of_cell(start);
-    int re = tabular->row_of_cell(end);
 
-    if ((c1 >= cs) && (c1 <= ce) && (row >= rs) && (row <= re)) {
+    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);
        pain.fillRectangle(x, baseline - tabular->GetAscentOfRow(row),
@@ -263,6 +275,33 @@ void InsetTabular::DrawCellSelection(Painter & pain, int x, int baseline,
 }
 
 
+void InsetTabular::update(BufferView * bv, LyXFont const & font, bool reinit)
+{
+    if (reinit) {
+       need_update = INIT;
+       calculate_dimensions_of_cells(bv, font, true);
+       if (owner())
+           owner()->update(bv, font, true);
+       return;
+    }
+    if (the_locking_inset)
+       the_locking_inset->update(bv, font, reinit);
+    switch(need_update) {
+    case INIT:
+    case FULL:
+    case CELL:
+       if (calculate_dimensions_of_cells(bv, font, false))
+           need_update = INIT;
+       break;
+    case SELECTION:
+       need_update = INIT;
+       break;
+    default:
+       break;
+    }
+}
+
+
 char const * InsetTabular::EditMessage() const
 {
     return _("Opened Tabular Inset");
@@ -280,45 +319,46 @@ void InsetTabular::Edit(BufferView * bv, int x, int y, unsigned int button)
     locked = true;
     the_locking_inset = 0;
     inset_pos = inset_x = inset_y = 0;
-    setPos(bv->painter(), x, y);
-    sel_pos_start = sel_pos_end = cursor.pos;
+    setPos(bv, x, y);
+    sel_pos_start = sel_pos_end = cursor.pos();
     sel_cell_start = sel_cell_end = actcell;
     bv->text->FinishUndo();
     if (InsetHit(bv, x, y)) {
        ActivateCellInset(bv, x, y, button);
     }
-    UpdateLocal(bv, true);
+    UpdateLocal(bv, NONE, false);
 //    bv->getOwner()->getPopups().updateFormTabular();
 }
 
 
 void InsetTabular::InsetUnlock(BufferView * bv)
 {
-    TabularOptClose();
     if (the_locking_inset) {
        the_locking_inset->InsetUnlock(bv);
        the_locking_inset = 0;
     }
     HideInsetCursor(bv);
     if (hasSelection()) {
-       sel_pos_start = sel_pos_end = cursor.pos;
-       sel_cell_start = sel_cell_end = actcell;
-       UpdateLocal(bv, false);
+       sel_pos_start = sel_pos_end = 0;
+       sel_cell_start = sel_cell_end = 0;
+       UpdateLocal(bv, FULL, false);
     }
     no_selection = false;
     oldcell = -1;
     locked = false;
 }
 
-void InsetTabular::UpdateLocal(BufferView * bv, bool flag)
+
+void InsetTabular::UpdateLocal(BufferView * bv, UpdateCodes what,
+                              bool mark_dirty)
 {
-    if (flag)
-       calculate_width_of_cells(bv->painter(), LyXFont(LyXFont::ALL_SANE));
-    bv->updateInset(this, flag);
-    if (flag)
-       resetPos(bv->painter());
+    need_update = what;
+    bv->updateInset(this, mark_dirty);
+    if (what != NONE)
+       resetPos(bv);
 }
 
+
 bool InsetTabular::LockInsetInInset(BufferView * bv, UpdatableInset * inset)
 {
     lyxerr[Debug::INSETS] << "InsetTabular::LockInsetInInset(" <<inset<< "): ";
@@ -328,17 +368,17 @@ bool InsetTabular::LockInsetInInset(BufferView * bv, UpdatableInset * inset)
     if (inset == tabular->GetCellInset(actcell)) {
        lyxerr[Debug::INSETS] << "OK" << endl;
        the_locking_inset = tabular->GetCellInset(actcell);
-       resetPos(bv->painter());
-       inset_x = cursor.x - top_x + tabular->GetBeginningOfTextInCell(actcell);
-       inset_y = cursor.y;
-       inset_pos = cursor.pos;
+       resetPos(bv);
+       inset_x = cursor.x() - top_x + tabular->GetBeginningOfTextInCell(actcell);
+       inset_y = cursor.y();
+       inset_pos = cursor.pos();
        return true;
     } else if (the_locking_inset && (the_locking_inset == inset)) {
-       if (cursor.pos == inset_pos) {
+       if (cursor.pos() == inset_pos) {
            lyxerr[Debug::INSETS] << "OK" << endl;
-           resetPos(bv->painter());
-           inset_x = cursor.x - top_x + tabular->GetBeginningOfTextInCell(actcell);
-           inset_y = cursor.y;
+           resetPos(bv);
+           inset_x = cursor.x() - top_x + tabular->GetBeginningOfTextInCell(actcell);
+           inset_y = cursor.y();
        } else {
            lyxerr[Debug::INSETS] << "cursor.pos != inset_pos" << endl;
        }
@@ -350,6 +390,7 @@ bool InsetTabular::LockInsetInInset(BufferView * bv, UpdatableInset * inset)
     return false;
 }
 
+
 bool InsetTabular::UnlockInsetInInset(BufferView * bv, UpdatableInset * inset,
                                   bool lr)
 {
@@ -360,13 +401,15 @@ bool InsetTabular::UnlockInsetInInset(BufferView * bv, UpdatableInset * inset,
         the_locking_inset = 0;
         if (lr)
             moveRight(bv, false);
+       UpdateLocal(bv, CELL, false);
         return true;
     }
     if (the_locking_inset->UnlockInsetInInset(bv, inset, lr)) {
        if ((inset->LyxCode() == TABULAR_CODE) &&
            !the_locking_inset->GetFirstLockingInsetOfType(TABULAR_CODE))
        {
-           UpdateLayoutTabular(true, const_cast<InsetTabular *>(this));
+           dialogs_ = bv->owner()->getDialogs();
+           dialogs_->updateTabular(const_cast<InsetTabular *>(this));
            oldcell = actcell;
        }
        return true;
@@ -374,13 +417,14 @@ bool InsetTabular::UnlockInsetInInset(BufferView * bv, UpdatableInset * inset,
     return false;
 }
 
+
 bool InsetTabular::UpdateInsetInInset(BufferView * bv, Inset * inset)
 {
     if (!the_locking_inset)
        return false;
     if (the_locking_inset != inset)
        return the_locking_inset->UpdateInsetInInset(bv, inset);
-    UpdateLocal(bv);
+    UpdateLocal(bv, CELL, false);
     return true;
 }
 
@@ -418,40 +462,18 @@ bool InsetTabular::InsertInset(BufferView * bv, Inset * inset)
 }
 
 
-void InsetTabular::InsetButtonRelease(BufferView * bv,
-                                     int x, int y, int button)
-{
-    if (button == 3) {
-       if (the_locking_inset) {
-           UpdatableInset * i;
-           if ((i=the_locking_inset->GetFirstLockingInsetOfType(TABULAR_CODE))) {
-               i->InsetButtonRelease(bv, x, y, button);
-               return;
-           }
-       }
-       MenuLayoutTabular(true, this);
-       return;
-    }
-    if (the_locking_inset) {
-        the_locking_inset->InsetButtonRelease(bv, x-inset_x, y-inset_y,button);
-        return;
-    }
-    no_selection = false;
-}
-
-
 void InsetTabular::InsetButtonPress(BufferView * bv, int x, int y, int button)
 {
     if (hasSelection()) {
        sel_pos_start = sel_pos_end = sel_cell_start = sel_cell_end = 0;
-       UpdateLocal(bv, false);
+       UpdateLocal(bv, SELECTION, false);
     }
     no_selection = false;
 
     int ocell = actcell;
 
-    setPos(bv->painter(), x, y);
-    sel_pos_start = sel_pos_end = cursor.pos;
+    setPos(bv, x, y);
+    sel_pos_start = sel_pos_end = cursor.pos();
     sel_cell_start = sel_cell_end = actcell;
 
     bool inset_hit = InsetHit(bv, x, y);
@@ -467,13 +489,33 @@ void InsetTabular::InsetButtonPress(BufferView * bv, int x, int y, int button)
        ActivateCellInset(bv, x, y, button);
        the_locking_inset->InsetButtonPress(bv, x-inset_x, y-inset_y, button);
     }
-    
+}
+
+
+void InsetTabular::InsetButtonRelease(BufferView * bv,
+                                     int x, int y, int button)
+{
+    if (button == 3) {
+       if (the_locking_inset) {
+           UpdatableInset * i;
+           if ((i=the_locking_inset->GetFirstLockingInsetOfType(TABULAR_CODE))) {
+               i->InsetButtonRelease(bv, x, y, button);
+               return;
+           }
+       }
+       dialogs_ = bv->owner()->getDialogs();
+        dialogs_->showTabular(this);
 #if 0
-    if (button == 3)
-        bview->getOwner()->getPopups().showFormTabular();
-    else if (ocell != actcell)
-        bview->getOwner()->getPopups().updateFormTabular();
+       else if (ocell != actcell)
+               bview->getOwner()->getPopups().updateTabular();
 #endif
+       return;
+    }
+    if (the_locking_inset) {
+        the_locking_inset->InsetButtonRelease(bv, x-inset_x, y-inset_y,button);
+        return;
+    }
+    no_selection = false;
 }
 
 
@@ -488,11 +530,11 @@ void InsetTabular::InsetMotionNotify(BufferView * bv, int x, int y, int button)
            // int ocell = actcell,
            int old = sel_pos_end;
 
-       setPos(bv->painter(), x, y);
-       sel_pos_end = cursor.pos;
+       setPos(bv, x, y);
+       sel_pos_end = cursor.pos();
        sel_cell_end = actcell;
        if (old != sel_pos_end)
-           UpdateLocal(bv, false);
+           UpdateLocal(bv, SELECTION, false);
 #if 0
        if (ocell != actcell)
            bview->getOwner()->getPopups().updateFormTabular();
@@ -521,32 +563,32 @@ UpdatableInset::RESULT InsetTabular::LocalDispatch(BufferView * bv, int action,
     if (((result=UpdatableInset::LocalDispatch(bv, action, arg)) == DISPATCHED)
        || (result == DISPATCHED_NOUPDATE)) {
 
-       resetPos(bv->painter());
+       resetPos(bv);
        return result;
     }
-    result=DISPATCHED;
 
     if ((action < 0) && arg.empty())
         return FINISHED;
 
     if ((action != LFUN_DOWN) && (action != LFUN_UP) &&
         (action != LFUN_DOWNSEL) && (action != LFUN_UPSEL))
-        cursor.x_fix = -1;
+        cursor.x_fix(-1);
     if (the_locking_inset) {
         result=the_locking_inset->LocalDispatch(bv, action, arg);
        if (result == DISPATCHED_NOUPDATE)
            return result;
        else if (result == DISPATCHED) {
-            bool upd = SetCellDimensions(bv->painter(), actcell, actrow);
            the_locking_inset->ToggleInsetCursor(bv);
-           UpdateLocal(bv, upd);
+           UpdateLocal(bv, CELL, false);
            the_locking_inset->ToggleInsetCursor(bv);
             return result;
         } else if (result == FINISHED) {
            if ((action == LFUN_RIGHT) || (action == -1)) {
-               cursor.pos = inset_pos + 1;
-               resetPos(bv->painter());
+               cursor.pos(inset_pos + 1);
+               resetPos(bv);
            }
+           sel_pos_start = sel_pos_end = cursor.pos();
+           sel_cell_start = sel_cell_end = actcell;
            the_locking_inset=0;
            result = DISPATCHED;
            return result;
@@ -555,72 +597,93 @@ UpdatableInset::RESULT InsetTabular::LocalDispatch(BufferView * bv, int action,
 
     bool hs = hasSelection();
     HideInsetCursor(bv);
+    result=DISPATCHED;
     switch (action) {
        // Normal chars not handled here
     case -1:
        break;
        // --- Cursor Movements ---------------------------------------------
     case LFUN_RIGHTSEL:
+       if (tabular->IsLastCellInRow(actcell) && !cellstart(cursor.pos()))
+           break;
        moveRight(bv, false);
-       sel_pos_end = cursor.pos;
-       if (!cellstart(cursor.pos)) {
-           if (sel_cell_start >= actcell)
+       sel_pos_end = cursor.pos();
+       if (!cellstart(cursor.pos())) {
+           if (tabular->right_column_of_cell(sel_cell_start) >
+               tabular->right_column_of_cell(actcell))
                sel_cell_end = actcell+1;
            else
                sel_cell_end = actcell;
        }
-       UpdateLocal(bv, false);
+       UpdateLocal(bv, SELECTION, false);
        break;
     case LFUN_RIGHT:
        result = moveRight(bv);
-       sel_pos_start = sel_pos_end = cursor.pos;
+       sel_pos_start = sel_pos_end = cursor.pos();
        sel_cell_start = sel_cell_end = actcell;
        if (hs)
-           UpdateLocal(bv, false);
+           UpdateLocal(bv, SELECTION, false);
        break;
     case LFUN_LEFTSEL:
+       if (tabular->IsFirstCellInRow(actcell) && cellstart(cursor.pos()))
+           break;
        moveLeft(bv, false);
-       sel_pos_end = cursor.pos;
-       if (cellstart(cursor.pos)) {
-           if (sel_cell_start >= actcell)
+       sel_pos_end = cursor.pos();
+       if (cellstart(cursor.pos())) {
+           if (tabular->column_of_cell(sel_cell_start) >=
+               tabular->column_of_cell(actcell))
                sel_cell_end = actcell;
            else
                sel_cell_end = actcell-1;
        }
-       UpdateLocal(bv, false);
+       UpdateLocal(bv, SELECTION, false);
        break;
     case LFUN_LEFT:
        result = moveLeft(bv);
-       sel_pos_start = sel_pos_end = cursor.pos;
+       sel_pos_start = sel_pos_end = cursor.pos();
        sel_cell_start = sel_cell_end = actcell;
        if (hs)
-           UpdateLocal(bv, false);
+           UpdateLocal(bv, SELECTION, false);
        break;
     case LFUN_DOWNSEL:
+    {
+       int ocell = actcell;
        moveDown(bv);
-       sel_pos_end = cursor.pos;
-       sel_cell_end = actcell;
-       UpdateLocal(bv, false);
-       break;
+       sel_pos_end = cursor.pos();
+       if ((ocell == sel_cell_end) ||
+           (tabular->column_of_cell(ocell)>tabular->column_of_cell(actcell)))
+           sel_cell_end = tabular->GetCellBelow(sel_cell_end);
+       else
+           sel_cell_end = tabular->GetLastCellBelow(sel_cell_end);
+       UpdateLocal(bv, SELECTION, false);
+    }
+    break;
     case LFUN_DOWN:
        result= moveDown(bv);
-       sel_pos_start = sel_pos_end = cursor.pos;
+       sel_pos_start = sel_pos_end = cursor.pos();
        sel_cell_start = sel_cell_end = actcell;
        if (hs)
-           UpdateLocal(bv, false);
+           UpdateLocal(bv, SELECTION, false);
        break;
     case LFUN_UPSEL:
+    {
+       int ocell = actcell;
        moveUp(bv);
-       sel_pos_end = cursor.pos;
-       sel_cell_end = actcell;
-       UpdateLocal(bv, false);
-       break;
+       sel_pos_end = cursor.pos();
+       if ((ocell == sel_cell_end) ||
+           (tabular->column_of_cell(ocell)>tabular->column_of_cell(actcell)))
+           sel_cell_end = tabular->GetCellAbove(sel_cell_end);
+       else
+           sel_cell_end = tabular->GetLastCellAbove(sel_cell_end);
+       UpdateLocal(bv, SELECTION, false);
+    }
+    break;
     case LFUN_UP:
        result= moveUp(bv);
-       sel_pos_start = sel_pos_end = cursor.pos;
+       sel_pos_start = sel_pos_end = cursor.pos();
        sel_cell_start = sel_cell_end = actcell;
        if (hs)
-           UpdateLocal(bv, false);
+           UpdateLocal(bv, SELECTION, false);
        break;
     case LFUN_BACKSPACE:
        break;
@@ -633,22 +696,22 @@ UpdatableInset::RESULT InsetTabular::LocalDispatch(BufferView * bv, int action,
     case LFUN_SHIFT_TAB:
     case LFUN_TAB:
        if (the_locking_inset) {
-           the_locking_inset->InsetUnlock(bv);
+           UnlockInsetInInset(bv, the_locking_inset);
+           the_locking_inset = 0;
        }
-       the_locking_inset = 0;
        if (action == LFUN_TAB)
            moveNextCell(bv);
        else
            movePrevCell(bv);
-       sel_pos_start = sel_pos_end = cursor.pos;
+       sel_pos_start = sel_pos_end = cursor.pos();
        sel_cell_start = sel_cell_end = actcell;
        if (hs)
-           UpdateLocal(bv, false);
+           UpdateLocal(bv, SELECTION, false);
        break;
     case LFUN_LAYOUT_TABLE:
     {
-       int flag = (arg == "true");
-       MenuLayoutTabular(flag, this);
+       dialogs_ = bv->owner()->getDialogs();
+        dialogs_->showTabular(this);
     }
     break;
     default:
@@ -669,24 +732,26 @@ UpdatableInset::RESULT InsetTabular::LocalDispatch(BufferView * bv, int action,
 }
 
 
-int InsetTabular::Latex(ostream & os, bool fragile, bool fp) const
+int InsetTabular::Latex(Buffer const * buf, ostream & os,
+                       bool fragile, bool fp) const
 {
-    return tabular->Latex(os, fragile, fp);
+    return tabular->Latex(buf, os, fragile, fp);
 }
 
 
-int InsetTabular::Ascii(ostream &) const
+int InsetTabular::Ascii(Buffer const *, ostream &) const
 {
     return 0;
 }
 
-int InsetTabular::Linuxdoc(ostream &) const
+
+int InsetTabular::Linuxdoc(Buffer const *, ostream &) const
 {
     return 0;
 }
 
 
-int InsetTabular::DocBook(ostream &) const
+int InsetTabular::DocBook(Buffer const *, ostream &) const
 {
     return 0;
 }
@@ -698,12 +763,14 @@ void InsetTabular::Validate(LaTeXFeatures & features) const
 }
 
 
-void InsetTabular::calculate_width_of_cells(Painter & pain,
-                                           LyXFont const & font) const
+bool InsetTabular::calculate_dimensions_of_cells(BufferView * bv,
+                                                LyXFont const & font,
+                                                bool reinit) const
 {
     int cell = -1;
     int maxAsc, maxDesc;
     InsetText * inset;
+    bool changed = false;
     
     for(int i = 0; i < tabular->rows(); ++i) {
        maxAsc = maxDesc = 0;
@@ -712,20 +779,23 @@ void InsetTabular::calculate_width_of_cells(Painter & pain,
                continue;
            ++cell;
            inset = tabular->GetCellInset(cell);
-           maxAsc = max(maxAsc, inset->ascent(pain, font));
-           maxDesc = max(maxDesc, inset->descent(pain, font));
-           tabular->SetWidthOfCell(cell, inset->width(pain, font));
+           if (!reinit)
+               inset->update(bv, font, false);
+           maxAsc = max(maxAsc, inset->ascent(bv, font));
+           maxDesc = max(maxDesc, inset->descent(bv, font));
+           changed = tabular->SetWidthOfCell(cell, inset->width(bv, font)) || changed;
        }
-       tabular->SetAscentOfRow(i, maxAsc + ADD_TO_HEIGHT);
-       tabular->SetDescentOfRow(i, maxDesc + ADD_TO_HEIGHT);
+       changed = tabular->SetAscentOfRow(i, maxAsc + ADD_TO_HEIGHT) || changed;
+       changed = tabular->SetDescentOfRow(i, maxDesc + ADD_TO_HEIGHT) || changed;
     }
+    return changed;
 }
 
 
-void InsetTabular::GetCursorPos(int & x, int & y) const
+void InsetTabular::GetCursorPos(BufferView *, int & x, int & y) const
 {
-    x = cursor.x-top_x;
-    y = cursor.y;
+    x = cursor.x() - top_x;
+    y = cursor.y();
 }
 
 
@@ -744,7 +814,7 @@ void InsetTabular::ToggleInsetCursor(BufferView * bv)
     if (cursor_visible)
         bv->hideLockedInsetCursor();
     else
-        bv->showLockedInsetCursor(cursor.x, cursor.y, asc, desc);
+        bv->showLockedInsetCursor(cursor.x(), cursor.y(), asc, desc);
     cursor_visible = !cursor_visible;
 }
 
@@ -756,8 +826,8 @@ void InsetTabular::ShowInsetCursor(BufferView * bv)
     
        int asc = lyxfont::maxAscent(font);
        int desc = lyxfont::maxDescent(font);
-       bv->fitLockedInsetCursor(cursor.x, cursor.y, asc, desc);
-       bv->showLockedInsetCursor(cursor.x, cursor.y, asc, desc);
+       bv->fitLockedInsetCursor(cursor.x(), cursor.y(), asc, desc);
+       bv->showLockedInsetCursor(cursor.x(), cursor.y(), asc, desc);
        cursor_visible = true;
     }
 }
@@ -770,19 +840,22 @@ void InsetTabular::HideInsetCursor(BufferView * bv)
 }
 
 
-void InsetTabular::setPos(Painter & pain, int x, int y) const
+void InsetTabular::setPos(BufferView * bv, int x, int y) const
 {
-    cursor.y = cursor.pos = actcell = actrow = actcol = 0;
+       cursor.y(0);
+       cursor.pos(0);
+       
+       actcell = actrow = actcol = 0;
     int ly = tabular->GetDescentOfRow(actrow);
 
     // first search the right row
     while((ly < y) && (actrow < tabular->rows())) {
-        cursor.y += tabular->GetDescentOfRow(actrow) +
+        cursor.y(cursor.y() + tabular->GetDescentOfRow(actrow) +
            tabular->GetAscentOfRow(actrow+1) +
-            tabular->GetAdditionalHeight(tabular->GetCellNumber(actrow+1,
-                                                               actcol));
+            tabular->GetAdditionalHeight(tabular->GetCellNumber(actrow + 1,
+                                                               actcol)));
         ++actrow;
-        ly = cursor.y + tabular->GetDescentOfRow(actrow);
+        ly = cursor.y() + tabular->GetDescentOfRow(actrow);
     }
     actcell = tabular->GetCellNumber(actrow, actcol);
 
@@ -791,18 +864,19 @@ void InsetTabular::setPos(Painter & pain, int x, int y) const
        tabular->GetAdditionalWidth(actcell);
     for(; !tabular->IsLastCellInRow(actcell) && (lx < x);
        ++actcell,lx += tabular->GetWidthOfColumn(actcell) +
-           tabular->GetAdditionalWidth(actcell-1));
-    cursor.pos = ((actcell+1) * 2) - 1;
-    resetPos(pain);
+           tabular->GetAdditionalWidth(actcell - 1));
+    cursor.pos(((actcell+1) * 2) - 1);
+    resetPos(bv);
     if ((lx - (tabular->GetWidthOfColumn(actcell)/2)) < x) {
-       cursor.x = lx + top_x - 2;
+       cursor.x(lx + top_x - 2);
     } else {
-       --cursor.pos;
-       cursor.x = lx - tabular->GetWidthOfColumn(actcell) + top_x + 2;
+       cursor.pos(cursor.pos() - 1);
+       cursor.x(lx - tabular->GetWidthOfColumn(actcell) + top_x + 2);
     }
-    resetPos(pain);
+    resetPos(bv);
 }
 
+
 int InsetTabular::getCellXPos(int cell) const
 {
     int c;
@@ -817,89 +891,73 @@ int InsetTabular::getCellXPos(int cell) const
            ADD_TO_TABULAR_WIDTH);
 }
 
-void InsetTabular::resetPos(Painter & pain) const
+
+void InsetTabular::resetPos(BufferView * bv) const
 {
     if (!locked)
        return;
     actcol = tabular->column_of_cell(actcell);
 
     int cell = 0;
-    actrow = cursor.y = 0;
+    actrow = 0;
+    cursor.y(0);
     for(; (cell<actcell) && !tabular->IsLastRow(cell); ++cell) {
        if (tabular->IsLastCellInRow(cell)) {
-           cursor.y += tabular->GetDescentOfRow(actrow) +
-               tabular->GetAscentOfRow(actrow+1) +
-               tabular->GetAdditionalHeight(cell+1);
+           cursor.y(cursor.y() + tabular->GetDescentOfRow(actrow) +
+               tabular->GetAscentOfRow(actrow + 1) +
+               tabular->GetAdditionalHeight(cell + 1));
            ++actrow;
        }
     }
-    cursor.x = getCellXPos(actcell) + 2;
-    if (cursor.pos % 2) {
+    cursor.x(getCellXPos(actcell) + 2);
+    if (cursor.pos() % 2) {
        LyXFont font(LyXFont::ALL_SANE);
-       cursor.x += tabular->GetCellInset(actcell)->width(pain,font) +
-               tabular->GetBeginningOfTextInCell(actcell);
+       cursor.x(cursor.x() + tabular->GetCellInset(actcell)->width(bv,font) +
+               tabular->GetBeginningOfTextInCell(actcell));
     }
     if ((!the_locking_inset ||
         !the_locking_inset->GetFirstLockingInsetOfType(TABULAR_CODE)) &&
        (actcell != oldcell)) {
-       UpdateLayoutTabular(true, const_cast<InsetTabular *>(this));
+       dialogs_ = bv->owner()->getDialogs();
+        dialogs_->updateTabular(const_cast<InsetTabular *>(this));
        oldcell = actcell;
     }
 }
 
 
-bool InsetTabular::SetCellDimensions(Painter & pain, int cell, int row)
-{
-    InsetText * inset = tabular->GetCellInset(cell);
-    LyXFont font(LyXFont::ALL_SANE);
-    int asc = inset->ascent(pain, font) + ADD_TO_HEIGHT;
-    int desc = inset->descent(pain, font) + ADD_TO_HEIGHT;
-    int maxAsc = tabular->GetAscentOfRow(row);
-    int maxDesc = tabular->GetDescentOfRow(row);
-    bool ret = tabular->SetWidthOfCell(cell, inset->width(pain, font));
-
-    if (maxAsc < asc) {
-       ret = true;
-       tabular->SetAscentOfRow(row, asc);
-    }
-    if (maxDesc < desc) {
-       ret = true;
-       tabular->SetDescentOfRow(row, desc);
-    }
-    return ret;
-}
-
-
 UpdatableInset::RESULT InsetTabular::moveRight(BufferView * bv, bool lock)
 {
-    if (cursor.pos % 2) { // behind the inset
-       ++actcell;
-       if (actcell >= tabular->GetNumberOfCells())
+    if (!cellstart(cursor.pos())) {
+       if (tabular->IsLastCell(actcell))
            return FINISHED;
-       ++cursor.pos;
+       ++actcell;
+       cursor.pos(cursor.pos() + 1);
     } else if (lock) {
        if (ActivateCellInset(bv))
            return DISPATCHED;
     } else {              // before the inset
-       ++cursor.pos;
+       cursor.pos(cursor.pos() + 1);
     }
-    resetPos(bv->painter());
+    resetPos(bv);
     return DISPATCHED_NOUPDATE;
 }
 
 
 UpdatableInset::RESULT InsetTabular::moveLeft(BufferView * bv, bool lock)
 {
-    if (!cursor.pos)
-       return FINISHED;
-    --cursor.pos;
-    if (cursor.pos % 2) { // behind the inset
+    if (!cursor.pos()) {
+       if (!actcell)
+           return FINISHED;
+       cursor.pos(2);
+    }
+    cursor.pos(cursor.pos() - 1);
+    if (!cellstart(cursor.pos())) {
        --actcell;
     } else if (lock) {       // behind the inset
        if (ActivateCellInset(bv, 0, 0, 0, true))
            return DISPATCHED;
     }
-    resetPos(bv->painter());
+    resetPos(bv);
     return DISPATCHED_NOUPDATE;
 }
 
@@ -910,7 +968,7 @@ UpdatableInset::RESULT InsetTabular::moveUp(BufferView * bv)
     actcell = tabular->GetCellAbove(actcell);
     if (actcell == ocell) // we moved out of the inset
        return FINISHED;
-    resetPos(bv->painter());
+    resetPos(bv);
     return DISPATCHED_NOUPDATE;
 }
 
@@ -921,7 +979,7 @@ UpdatableInset::RESULT InsetTabular::moveDown(BufferView * bv)
     actcell = tabular->GetCellBelow(actcell);
     if (actcell == ocell) // we moved out of the inset
        return FINISHED;
-    resetPos(bv->painter());
+    resetPos(bv);
     return DISPATCHED_NOUPDATE;
 }
 
@@ -931,10 +989,10 @@ bool InsetTabular::moveNextCell(BufferView * bv)
     if (tabular->IsLastCell(actcell))
        return false;
     ++actcell;
-    ++cursor.pos;
-    if (!cellstart(cursor.pos))
-       ++cursor.pos;
-    resetPos(bv->painter());
+    cursor.pos(cursor.pos() + 1);
+    if (!cellstart(cursor.pos()))
+       cursor.pos(cursor.pos() + 1);
+    resetPos(bv);
     return true;
 }
 
@@ -944,10 +1002,10 @@ bool InsetTabular::movePrevCell(BufferView * bv)
     if (!actcell) // first cell
        return false;
     --actcell;
-    --cursor.pos;
-    if (cellstart(cursor.pos))
-       --cursor.pos;
-    resetPos(bv->painter());
+    cursor.pos(cursor.pos() - 1);
+    if (cellstart(cursor.pos()))
+       cursor.pos(cursor.pos() - 1);
+    resetPos(bv);
     return true;
 }
 
@@ -958,17 +1016,21 @@ bool InsetTabular::Delete()
 }
 
 
-void InsetTabular::SetFont(BufferView *, LyXFont const &, bool)
+void InsetTabular::SetFont(BufferView * bv, LyXFont const & font, bool tall)
 {
+    if (the_locking_inset)
+       the_locking_inset->SetFont(bv, font, tall);
 }
 
 
 void InsetTabular::TabularFeatures(BufferView * bv, int feature, string val)
 {
     int
-       i,
-       sel_start,
-       sel_end,
+       i, j,
+       sel_col_start,
+       sel_col_end,
+       sel_row_start,
+       sel_row_end,
         setLines = 0,
         setAlign = LYX_ALIGN_LEFT,
         lineSet;
@@ -989,236 +1051,273 @@ void InsetTabular::TabularFeatures(BufferView * bv, int feature, string val)
           break;
     }
     if (hasSelection()) {
-       if (sel_cell_start > sel_cell_end) {
-           sel_start = sel_cell_end;
-           sel_end = sel_cell_start;
+       int tmp;
+       sel_col_start = tabular->column_of_cell(sel_cell_start);
+       sel_col_end = tabular->column_of_cell(sel_cell_end);
+       if (sel_col_start > sel_col_end) {
+           sel_col_end = sel_col_start;
+           sel_col_start = tabular->column_of_cell(sel_cell_end);
        } else {
-           sel_start = sel_cell_start;
-           sel_end = sel_cell_end;
+           sel_col_end = tabular->right_column_of_cell(sel_cell_end);
        }
-    } else
-       sel_start = sel_end = actcell;
+       
+       sel_row_start = tabular->row_of_cell(sel_cell_start);
+       sel_row_end = tabular->row_of_cell(sel_cell_end);
+       if (sel_row_start > sel_row_end) {
+           tmp = sel_row_start;
+           sel_row_start = sel_row_end;
+           sel_row_end = tmp;
+       }
+    } else {
+       sel_col_start = sel_col_end = tabular->column_of_cell(actcell);
+       sel_row_start = sel_row_end = tabular->row_of_cell(actcell);
+    }
+    bv->text->SetUndo(bv->buffer(), Undo::FINISH, 
+             bv->text->cursor.par()->ParFromPos(bv->text->cursor.pos())->previous,
+             bv->text->cursor.par()->ParFromPos(bv->text->cursor.pos())->next);
+
+    int row = tabular->row_of_cell(actcell);
+    int column = tabular->column_of_cell(actcell);
+
     switch (feature) {
-      case LyXTabular::SET_PWIDTH:
-      {
-         bool update = (tabular->GetPWidth(actcell) != val);
-          tabular->SetPWidth(actcell,val);
-         if (update)
-             UpdateLocal(bv, true);
-      }
-      break;
-      case LyXTabular::SET_SPECIAL_COLUMN:
-      case LyXTabular::SET_SPECIAL_MULTI:
-          tabular->SetAlignSpecial(actcell,val,feature);
-          break;
-      case LyXTabular::APPEND_ROW:
-      {
-          // append the row into the tabular
-          tabular->AppendRow(actcell);
-          UpdateLocal(bv, true);
-          break;
-      }
-      case LyXTabular::APPEND_COLUMN:
-      { 
-          // append the column into the tabular
-          tabular->AppendColumn(actcell);
-          UpdateLocal(bv, true);
-          break;
-      }
-      case LyXTabular::DELETE_ROW:
-          RemoveTabularRow();
-          UpdateLocal(bv, true);
-          break;
-      case LyXTabular::DELETE_COLUMN:
-      {
-          /* delete the column from the tabular */ 
-          tabular->DeleteColumn(actcell);
-          UpdateLocal(bv, true);
-          break;
-      }
-      case LyXTabular::TOGGLE_LINE_TOP:
-          lineSet = !tabular->TopLine(actcell);
-         for(i=sel_start; i<=sel_end; ++i)
-             tabular->SetTopLine(i,lineSet);
-          UpdateLocal(bv, true);
-          break;
+    case LyXTabular::SET_PWIDTH:
+    {
+       bool update = (tabular->GetPWidth(actcell) != val);
+       tabular->SetPWidth(actcell,val);
+       if (update) {
+           for (int i=0; i < tabular->rows(); ++i) {
+               tabular->GetCellInset(tabular->GetCellNumber(i, column))->
+                   deleteLyXText(bv);
+           }
+           UpdateLocal(bv, INIT, true);
+       }
+    }
+    break;
+    case LyXTabular::SET_SPECIAL_COLUMN:
+    case LyXTabular::SET_SPECIAL_MULTI:
+       tabular->SetAlignSpecial(actcell,val,feature);
+       break;
+    case LyXTabular::APPEND_ROW:
+       // append the row into the tabular
+       UnlockInsetInInset(bv, the_locking_inset);
+       tabular->AppendRow(actcell);
+       UpdateLocal(bv, INIT, true);
+       break;
+    case LyXTabular::APPEND_COLUMN:
+       // append the column into the tabular
+       tabular->AppendColumn(actcell);
+       actcell = tabular->GetCellNumber(row, column);
+       UpdateLocal(bv, INIT, true);
+       break;
+    case LyXTabular::DELETE_ROW:
+       tabular->DeleteRow(tabular->row_of_cell(actcell));
+       if ((row+1) > tabular->rows())
+           --row;
+       actcell = tabular->GetCellNumber(row, column);
+       UpdateLocal(bv, INIT, true);
+       break;
+    case LyXTabular::DELETE_COLUMN:
+       tabular->DeleteColumn(tabular->column_of_cell(actcell));
+       if ((column+1) > tabular->columns())
+           --column;
+       actcell = tabular->GetCellNumber(row, column);
+       UpdateLocal(bv, INIT, true);
+       break;
+    case LyXTabular::TOGGLE_LINE_TOP:
+       lineSet = !tabular->TopLine(actcell);
+       for(i=sel_row_start; i<=sel_row_end; ++i)
+           for(j=sel_col_start; j<=sel_col_end; ++j)
+               tabular->SetTopLine(tabular->GetCellNumber(i,j),lineSet);
+       UpdateLocal(bv, INIT, true);
+       break;
     
-      case LyXTabular::TOGGLE_LINE_BOTTOM:
-          lineSet = !tabular->BottomLine(actcell); 
-         for(i=sel_start; i<=sel_end; ++i)
-             tabular->SetBottomLine(i,lineSet);
-          UpdateLocal(bv, true);
-          break;
+    case LyXTabular::TOGGLE_LINE_BOTTOM:
+       lineSet = !tabular->BottomLine(actcell); 
+       for(i=sel_row_start; i<=sel_row_end; ++i)
+           for(j=sel_col_start; j<=sel_col_end; ++j)
+               tabular->SetBottomLine(tabular->GetCellNumber(i,j),lineSet);
+       UpdateLocal(bv, INIT, true);
+       break;
                
-      case LyXTabular::TOGGLE_LINE_LEFT:
-          lineSet = !tabular->LeftLine(actcell);
-         for(i=sel_start; i<=sel_end; ++i)
-             tabular->SetLeftLine(i,lineSet);
-          UpdateLocal(bv, true);
-          break;
+    case LyXTabular::TOGGLE_LINE_LEFT:
+       lineSet = !tabular->LeftLine(actcell);
+       for(i=sel_row_start; i<=sel_row_end; ++i)
+           for(j=sel_col_start; j<=sel_col_end; ++j)
+               tabular->SetLeftLine(tabular->GetCellNumber(i,j),lineSet);
+       UpdateLocal(bv, INIT, true);
+       break;
 
-      case LyXTabular::TOGGLE_LINE_RIGHT:
-          lineSet = !tabular->RightLine(actcell);
-         for(i=sel_start; i<=sel_end; ++i)
-             tabular->SetRightLine(i,lineSet);
-          UpdateLocal(bv, true);
-          break;
-      case LyXTabular::ALIGN_LEFT:
-      case LyXTabular::ALIGN_RIGHT:
-      case LyXTabular::ALIGN_CENTER:
-         for(i=sel_start; i<=sel_end; ++i)
-             tabular->SetAlignment(i,setAlign);
-          UpdateLocal(bv, true);
-          break;
-      case LyXTabular::MULTICOLUMN:
-      {
-         if (tabular->row_of_cell(sel_start) !=
-             tabular->row_of_cell(sel_end)) {
-             WriteAlert(_("Impossible Operation!"), 
-                        _("Multicolumns can only be horizontally."), 
-                        _("Sorry."));
-             return;
-         }
-         // just multicol for one Single Cell
-         if (!hasSelection()) {
-             // check wether we are completly in a multicol
-             if (tabular->IsMultiColumn(actcell)) {
-                 tabular->UnsetMultiColumn(actcell);
-                 UpdateLocal(bv, true);
-             } else {
-                 tabular->SetMultiColumn(actcell, 1);
-                 UpdateLocal(bv, false);
-             }
-             return;
-         }
-         // we have a selection so this means we just add all this
-         // cells to form a multicolumn cell
-         int
-             s_start, s_end;
-
-         if (sel_start > sel_end) {
-             s_start = sel_end;
-             s_end = sel_start;
-         } else {
-             s_start = sel_start;
-             s_end = sel_end;
-         }
-         tabular->SetMultiColumn(s_start, s_end);
-         cursor.pos = s_start;
-         sel_cell_end = sel_cell_start;
-         UpdateLocal(bv, true);
-          break;
-      }
-      case LyXTabular::SET_ALL_LINES:
-          setLines = 1;
-      case LyXTabular::UNSET_ALL_LINES:
-         for(i=sel_start; i<=sel_end; ++i)
-             tabular->SetAllLines(i, setLines);
-          UpdateLocal(bv, true);
-          break;
-      case LyXTabular::SET_LONGTABULAR:
-          tabular->SetLongTabular(true);
-         UpdateLocal(bv, true); // because this toggles displayed
-          break;
-      case LyXTabular::UNSET_LONGTABULAR:
-          tabular->SetLongTabular(false);
-         UpdateLocal(bv, true); // because this toggles displayed
-          break;
-      case LyXTabular::SET_ROTATE_TABULAR:
-          tabular->SetRotateTabular(true);
-          break;
-      case LyXTabular::UNSET_ROTATE_TABULAR:
-          tabular->SetRotateTabular(false);
-          break;
-      case LyXTabular::SET_ROTATE_CELL:
-         for(i=sel_start; i<=sel_end; ++i)
-             tabular->SetRotateCell(i,true);
-          break;
-      case LyXTabular::UNSET_ROTATE_CELL:
-         for(i=sel_start; i<=sel_end; ++i)
-             tabular->SetRotateCell(i,false);
-          break;
-      case LyXTabular::SET_LINEBREAKS:
-          what = !tabular->GetLinebreaks(actcell);
-         for(i=sel_start; i<=sel_end; ++i)
-             tabular->SetLinebreaks(i,what);
-          break;
-      case LyXTabular::SET_LTFIRSTHEAD:
-          tabular->SetLTHead(actcell,true);
-          break;
-      case LyXTabular::SET_LTHEAD:
-          tabular->SetLTHead(actcell,false);
-          break;
-      case LyXTabular::SET_LTFOOT:
-          tabular->SetLTFoot(actcell,false);
-          break;
-      case LyXTabular::SET_LTLASTFOOT:
-          tabular->SetLTFoot(actcell,true);
-          break;
-      case LyXTabular::SET_LTNEWPAGE:
-          what = !tabular->GetLTNewPage(actcell);
-          tabular->SetLTNewPage(actcell,what);
-          break;
+    case LyXTabular::TOGGLE_LINE_RIGHT:
+       lineSet = !tabular->RightLine(actcell);
+       for(i=sel_row_start; i<=sel_row_end; ++i)
+           for(j=sel_col_start; j<=sel_col_end; ++j)
+               tabular->SetRightLine(tabular->GetCellNumber(i,j),lineSet);
+       UpdateLocal(bv, INIT, true);
+       break;
+    case LyXTabular::ALIGN_LEFT:
+    case LyXTabular::ALIGN_RIGHT:
+    case LyXTabular::ALIGN_CENTER:
+       for(i=sel_row_start; i<=sel_row_end; ++i)
+           for(j=sel_col_start; j<=sel_col_end; ++j)
+               tabular->SetAlignment(tabular->GetCellNumber(i,j),setAlign);
+       if (hasSelection())
+           UpdateLocal(bv, INIT, true);
+       else
+           UpdateLocal(bv, CELL, true);
+       break;
+    case LyXTabular::MULTICOLUMN:
+    {
+       if (sel_row_start != sel_row_end) {
+           WriteAlert(_("Impossible Operation!"), 
+                      _("Multicolumns can only be horizontally."), 
+                      _("Sorry."));
+           return;
+       }
+       // just multicol for one Single Cell
+       if (!hasSelection()) {
+           // check wether we are completly in a multicol
+           if (tabular->IsMultiColumn(actcell)) {
+               tabular->UnsetMultiColumn(actcell);
+               UpdateLocal(bv, INIT, true);
+           } else {
+               tabular->SetMultiColumn(actcell, 1);
+               UpdateLocal(bv, CELL, true);
+           }
+           return;
+       }
+       // we have a selection so this means we just add all this
+       // cells to form a multicolumn cell
+       int
+           s_start, s_end;
+
+       if (sel_cell_start > sel_cell_end) {
+           s_start = sel_cell_end;
+           s_end = sel_cell_start;
+       } else {
+           s_start = sel_cell_start;
+           s_end = sel_cell_end;
+       }
+       tabular->SetMultiColumn(s_start, s_end - s_start + 1);
+       actcell = s_start;
+       cursor.pos(0);
+       sel_cell_end = sel_cell_start;
+       sel_pos_end = sel_pos_start;
+       UpdateLocal(bv, INIT, true);
+       break;
+    }
+    case LyXTabular::SET_ALL_LINES:
+       setLines = 1;
+    case LyXTabular::UNSET_ALL_LINES:
+       for(i=sel_row_start; i<=sel_row_end; ++i)
+           for(j=sel_col_start; j<=sel_col_end; ++j)
+               tabular->SetAllLines(tabular->GetCellNumber(i,j), setLines);
+       UpdateLocal(bv, INIT, true);
+       break;
+    case LyXTabular::SET_LONGTABULAR:
+       tabular->SetLongTabular(true);
+       UpdateLocal(bv, INIT, true); // because this toggles displayed
+       break;
+    case LyXTabular::UNSET_LONGTABULAR:
+       tabular->SetLongTabular(false);
+       UpdateLocal(bv, INIT, true); // because this toggles displayed
+       break;
+    case LyXTabular::SET_ROTATE_TABULAR:
+       tabular->SetRotateTabular(true);
+       break;
+    case LyXTabular::UNSET_ROTATE_TABULAR:
+       tabular->SetRotateTabular(false);
+       break;
+    case LyXTabular::SET_ROTATE_CELL:
+       for(i=sel_row_start; i<=sel_row_end; ++i)
+           for(j=sel_col_start; j<=sel_col_end; ++j)
+               tabular->SetRotateCell(tabular->GetCellNumber(i,j),true);
+       break;
+    case LyXTabular::UNSET_ROTATE_CELL:
+       for(i=sel_row_start; i<=sel_row_end; ++i)
+           for(j=sel_col_start; j<=sel_col_end; ++j)
+               tabular->SetRotateCell(tabular->GetCellNumber(i,j),false);
+       break;
+    case LyXTabular::SET_LINEBREAKS:
+       what = !tabular->GetLinebreaks(actcell);
+       for(i=sel_row_start; i<=sel_row_end; ++i)
+           for(j=sel_col_start; j<=sel_col_end; ++j)
+               tabular->SetLinebreaks(tabular->GetCellNumber(i,j),what);
+       break;
+    case LyXTabular::SET_LTFIRSTHEAD:
+       tabular->SetLTHead(actcell,true);
+       break;
+    case LyXTabular::SET_LTHEAD:
+       tabular->SetLTHead(actcell,false);
+       break;
+    case LyXTabular::SET_LTFOOT:
+       tabular->SetLTFoot(actcell,false);
+       break;
+    case LyXTabular::SET_LTLASTFOOT:
+       tabular->SetLTFoot(actcell,true);
+       break;
+    case LyXTabular::SET_LTNEWPAGE:
+       what = !tabular->GetLTNewPage(actcell);
+       tabular->SetLTNewPage(actcell,what);
+       break;
     }
 }
 
-void InsetTabular::RemoveTabularRow()
-{
-}
 
 bool InsetTabular::ActivateCellInset(BufferView * bv, int x, int y, int button,
                                     bool behind)
 {
     // the cursor.pos has to be before the inset so if it isn't now just
     // reset the curor pos first!
-    if (cursor.pos % 2) { // behind the inset
-       --cursor.pos;
-       resetPos(bv->painter());
+    if (cursor.pos() % 2) { // behind the inset
+       cursor.pos(cursor.pos() - 1);
+       resetPos(bv);
     }
     UpdatableInset * inset =
        static_cast<UpdatableInset*>(tabular->GetCellInset(actcell));
     LyXFont font(LyXFont::ALL_SANE);
     if (behind) {
-       x = inset->x() + inset->width(bv->painter(), font);
-       y = inset->descent(bv->painter(), font);
+       x = inset->x() + inset->width(bv, font);
+       y = inset->descent(bv, font);
     }
-    inset_x = cursor.x - top_x + tabular->GetBeginningOfTextInCell(actcell);
-    inset_y = cursor.y;
-    inset->Edit(bv, x-inset_x, y-inset_y, button);
+    inset_x = cursor.x() - top_x + tabular->GetBeginningOfTextInCell(actcell);
+    inset_y = cursor.y();
+    inset->Edit(bv, x - inset_x, y - inset_y, button);
     if (!the_locking_inset)
        return false;
-    UpdateLocal(bv, true);
+    UpdateLocal(bv, CELL, false);
     return true;
 }
 
+
 bool InsetTabular::InsetHit(BufferView * bv, int x, int ) const
 {
     InsetText * inset = tabular->GetCellInset(actcell);
     int x1 = x + top_x;
 
-    if (cursor.pos % 2) { // behind the inset
-       return (((x+top_x) < cursor.x) &&
-               ((x+top_x) > (cursor.x - inset->width(bv->painter(),
+    if (cursor.pos() % 2) { // behind the inset
+       return (((x + top_x) < cursor.x()) &&
+               ((x + top_x) > (cursor.x() - inset->width(bv,
                                                      LyXFont(LyXFont::ALL_SANE)))));
     } else {
-       int x2 = cursor.x + tabular->GetBeginningOfTextInCell(actcell);
+       int x2 = cursor.x() + tabular->GetBeginningOfTextInCell(actcell);
        return ((x1 > x2) &&
-               (x1 < (x2 + inset->width(bv->painter(),
-                                        LyXFont(LyXFont::ALL_SANE)))));
+               (x1 < (x2 + inset->width(bv, LyXFont(LyXFont::ALL_SANE)))));
     }
 }
 
+
 // This returns paperWidth() if the cell-width is unlimited or the width
 // in pixels if we have a pwidth for this cell.
-int InsetTabular::GetMaxWidthOfCell(Painter & pain, int cell) const
+int InsetTabular::GetMaxWidthOfCell(Painter &, int cell) const
 {
-    string w;
-       
-    if ((w=tabular->GetPWidth(cell)).empty())
-       return pain.paperWidth();
-    return VSpace(w).inPixels( 0, 0);
+    string s = tabular->GetPWidth(cell);
+
+    if (s.empty())
+       return -1;
+    return VSpace(s).inPixels( 0, 0);
 }
 
+
 int InsetTabular::getMaxWidth(Painter & pain,
                              UpdatableInset const * inset) const
 {
@@ -1229,7 +1328,7 @@ int InsetTabular::getMaxWidth(Painter & pain,
            break;
     }
     if (cell >= n)
-       return pain.paperWidth();
+       return -1;
     int w = GetMaxWidthOfCell(pain, cell);
     // this because text insets remove the xpos from the maxwidth because
     // otherwise the would not break good!!!
@@ -1238,22 +1337,30 @@ int InsetTabular::getMaxWidth(Painter & pain,
     return w;
 }
 
-void InsetTabular::recomputeTextInsets(Painter & pain, const LyXFont & font) const
+
+void InsetTabular::recomputeTextInsets(BufferView * bv,
+                                      LyXFont const & font) const
 {
     InsetText * inset;
-    int cx, cell;
+    int cell;
 
-    cx = top_x;
+//    cx = top_x;
     for(int j= 0; j < tabular->columns(); ++j) {
        for(int i = 0; i < tabular->rows(); ++i) {
            if (tabular->IsPartOfMultiColumn(i,j))
                continue;
            cell = tabular->GetCellNumber(i,j);
            inset = tabular->GetCellInset(cell);
-           inset->computeTextRows(pain);
-           tabular->SetWidthOfCell(cell, inset->width(pain, font));
+           inset->update(bv, font);
+           tabular->SetWidthOfCell(cell, inset->width(bv, font));
        }
-       cell = tabular->GetCellNumber(0, j);
-       cx += tabular->GetWidthOfColumn(cell);
+//     cell = tabular->GetCellNumber(0, j);
+//     cx += tabular->GetWidthOfColumn(cell);
     }
 }
+
+
+void InsetTabular::resizeLyXText(BufferView *) const
+{
+    need_update = FULL;
+}