]> git.lyx.org Git - lyx.git/blob - src/insets/insettabular.C
Small fixes + literate patch
[lyx.git] / src / insets / insettabular.C
1 /* This file is part of
2  * ======================================================
3  * 
4  *           LyX, The Document Processor
5  *
6  *           Copyright 2000 The LyX Team.
7  *
8  *======================================================
9  */
10
11 #include <config.h>
12
13 #include <fstream>
14 #include <algorithm>
15
16 #include <cstdlib>
17
18 #ifdef __GNUG__
19 #pragma implementation
20 #endif
21
22 #include "insettabular.h"
23
24 #include "buffer.h"
25 #include "commandtags.h"
26 #include "LaTeXFeatures.h"
27 #include "Painter.h"
28 #include "font.h"
29 #include "lyxtext.h"
30 #include "lyx_gui_misc.h"
31 #include "LyXView.h"
32 #include "lyxfunc.h"
33 #include "insets/insettext.h"
34 #include "frontends/Dialogs.h"
35
36 extern void MenuLayoutTabular(bool, InsetTabular *);
37 extern bool UpdateLayoutTabular(bool, InsetTabular *);
38 extern void TabularOptClose();
39
40 const int ADD_TO_HEIGHT = 2;
41 const int ADD_TO_TABULAR_WIDTH = 2;
42
43 using std::ostream;
44 using std::ifstream;
45 using std::max;
46 using std::endl;
47
48 #define cellstart(p) ((p % 2) == 0)
49
50 #define USE_NEW_LAYOUT 1
51
52 InsetTabular::InsetTabular(Buffer * buf, int rows, int columns)
53 {
54     if (rows <= 0)
55         rows = 1;
56     if (columns <= 0)
57         columns = 1;
58     buffer = buf; // set this first!!!
59     tabular = new LyXTabular(this, rows,columns);
60     // for now make it always display as display() inset
61     // just for test!!!
62     the_locking_inset = 0;
63     locked = no_selection = cursor_visible = false;
64     cursor.x_fix(-1);
65     oldcell = -1;
66     actcell = 0;
67     cursor.pos(0);
68     sel_pos_start = sel_pos_end = sel_cell_start = sel_cell_end = 0;
69     dialogs_ = 0;
70     need_update = INIT;
71 }
72
73
74 InsetTabular::InsetTabular(InsetTabular const & tab, Buffer * buf)
75 {
76     buffer = buf; // set this first
77     tabular = new LyXTabular(this, *(tab.tabular));
78     the_locking_inset = 0;
79     locked = no_selection = cursor_visible = false;
80     cursor.x_fix(-1);
81     oldcell = -1;
82     actcell = 0;
83     cursor.pos(0);
84     sel_pos_start = sel_pos_end = sel_cell_start = sel_cell_end = 0;
85     dialogs_ = 0;
86     need_update = INIT;
87 }
88
89
90 InsetTabular::~InsetTabular()
91 {
92     delete tabular;
93 #ifdef USE_NEW_LAYOUT
94     if (buffer->getUser())
95         buffer->getUser()->owner()->getDialogs()->hideTabular(this);
96     else if (dialogs_)
97         dialogs_->hideTabular(this);
98 #endif
99 }
100
101
102 Inset * InsetTabular::Clone() const
103 {
104     InsetTabular * t = new InsetTabular(*this, buffer);
105     delete t->tabular;
106     t->tabular = tabular->Clone(t);
107     return t;
108 }
109
110
111 void InsetTabular::Write(Buffer const * buf, ostream & os) const
112 {
113     os << " Tabular" << endl;
114     tabular->Write(buf, os);
115 }
116
117
118 void InsetTabular::Read(Buffer const * buf, LyXLex & lex)
119 {
120     bool old_format = (lex.GetString() == "\\LyXTable");
121     string token;
122
123     if (tabular)
124         delete tabular;
125     tabular = new LyXTabular(buf, this, lex);
126
127     need_update = INIT;
128
129     if (old_format)
130         return;
131
132     lex.nextToken();
133     token = lex.GetString();
134     while (lex.IsOK() && (token != "\\end_inset")) {
135         lex.nextToken();
136         token = lex.GetString();
137     }
138     if (token != "\\end_inset") {
139         lex.printError("Missing \\end_inset at this point. "
140                        "Read: `$$Token'");
141     }
142 }
143
144
145 int InsetTabular::ascent(BufferView *, LyXFont const &) const
146 {
147     return tabular->GetAscentOfRow(0);
148 }
149
150
151 int InsetTabular::descent(BufferView *, LyXFont const &) const
152 {
153     return tabular->GetHeightOfTabular() - tabular->GetAscentOfRow(0);
154 }
155
156
157 int InsetTabular::width(BufferView *, LyXFont const &) const
158 {
159     return tabular->GetWidthOfTabular() + (2 * ADD_TO_TABULAR_WIDTH);
160 }
161
162
163 void InsetTabular::draw(BufferView * bv, LyXFont const & font, int baseline,
164                         float & x, bool cleared) const
165 {
166     Painter & pain = bv->painter();
167     int i, j, cell=0;
168     int nx;
169     float cx;
170
171     UpdatableInset::draw(bv,font,baseline,x,cleared);
172     if (!cleared && ((need_update == INIT) || (need_update == FULL) ||
173                      (top_x != int(x)) || (top_baseline != baseline))) {
174 #if 1
175         int h = ascent(bv, font) + descent(bv, font);
176         int tx = display()? 0:top_x;
177         int w =  tx? width(bv, font):pain.paperWidth();
178         int ty = baseline - ascent(bv, font);
179         
180         if (ty < 0)
181             ty = 0;
182         if ((ty + h) > pain.paperHeight())
183             h = pain.paperHeight();
184         if ((top_x + w) > pain.paperWidth())
185             w = pain.paperWidth();
186         pain.fillRectangle(tx, ty, w, h);
187         need_update = FULL;
188         cleared = true;
189 #else
190         need_update = FULL;
191         resetPos(pain);
192         if (locked) { // repaint this way as the background was not cleared
193                 if (the_locking_inset)
194                         the_locking_inset->update(bv, font, true);
195                 locked = false;
196                 bv->updateInset(const_cast<InsetTabular*>(this), false);
197                 locked = true;
198                 return;
199         }
200 #endif
201     }
202     top_x = int(x);
203     top_baseline = baseline;
204     bool dodraw;
205     x += ADD_TO_TABULAR_WIDTH;
206     if (cleared || (need_update == FULL) || (need_update == CELL)) {
207         for(i=0;i<tabular->rows();++i) {
208             nx = int(x);
209             dodraw = ((baseline+tabular->GetDescentOfRow(i)) > 0) &&
210                     (baseline-tabular->GetAscentOfRow(i)) < pain.paperHeight();
211             for(j=0;j<tabular->columns();++j) {
212                 if (tabular->IsPartOfMultiColumn(i,j))
213                     continue;
214                 cx = nx + tabular->GetBeginningOfTextInCell(cell);
215                 if (hasSelection())
216                     DrawCellSelection(pain, nx, baseline, i, j, cell);
217                 if (dodraw && !cleared && locked && the_locking_inset) {
218                     if (the_locking_inset == tabular->GetCellInset(cell))
219                         tabular->GetCellInset(cell)->draw(bv, font,
220                                                           baseline, cx,
221                                                           cleared);
222                 } else if (dodraw) {
223                     tabular->GetCellInset(cell)->draw(bv, font, baseline, cx,
224                                                       cleared);
225                     DrawCellLines(pain, nx, baseline, i, cell);
226                 }
227                 nx += tabular->GetWidthOfColumn(cell);
228                 ++cell;
229             }
230             baseline += tabular->GetDescentOfRow(i) +
231                 tabular->GetAscentOfRow(i+1)+
232                 tabular->GetAdditionalHeight(cell+1);
233         }
234     }
235     x += width(bv, font);
236     need_update = NONE;
237 }
238
239
240 void InsetTabular::DrawCellLines(Painter & pain, int x, int baseline,
241                                  int row, int cell) const
242 {
243     int  x2 = x + tabular->GetWidthOfColumn(cell);
244     bool on_off;
245
246     if (!tabular->TopAlreadyDrawed(cell)) {
247         on_off = !tabular->TopLine(cell);
248         pain.line(x, baseline - tabular->GetAscentOfRow(row),
249                   x2, baseline -  tabular->GetAscentOfRow(row),
250                   on_off ? LColor::tabularonoffline:LColor::tabularline,
251                   on_off ? Painter::line_onoffdash:Painter::line_solid);
252     }
253     on_off = !tabular->BottomLine(cell);
254     pain.line(x,baseline +  tabular->GetDescentOfRow(row),
255               x2, baseline +  tabular->GetDescentOfRow(row),
256               on_off ? LColor::tabularonoffline:LColor::tabularline,
257               on_off ? Painter::line_onoffdash:Painter::line_solid);
258     if (!tabular->LeftAlreadyDrawed(cell)) {
259         on_off = !tabular->LeftLine(cell);
260         pain.line(x, baseline -  tabular->GetAscentOfRow(row),
261                   x, baseline +  tabular->GetDescentOfRow(row),
262                   on_off ? LColor::tabularonoffline:LColor::tabularline,
263                   on_off ? Painter::line_onoffdash:Painter::line_solid);
264     }
265     on_off = !tabular->RightLine(cell);
266     pain.line(x2 - tabular->GetAdditionalWidth(cell),
267               baseline -  tabular->GetAscentOfRow(row),
268               x2 - tabular->GetAdditionalWidth(cell),
269               baseline +  tabular->GetDescentOfRow(row),
270               on_off ? LColor::tabularonoffline:LColor::tabularline,
271               on_off ? Painter::line_onoffdash:Painter::line_solid);
272 }
273
274
275 void InsetTabular::DrawCellSelection(Painter & pain, int x, int baseline,
276                                      int row, int column, int cell) const
277 {
278     int tmp;
279
280     int cs = tabular->column_of_cell(sel_cell_start);
281     int ce = tabular->column_of_cell(sel_cell_end);
282     if (cs > ce) {
283         ce = cs;
284         cs = tabular->column_of_cell(sel_cell_end);
285     } else {
286         ce = tabular->right_column_of_cell(sel_cell_end);
287     }
288
289     int rs = tabular->row_of_cell(sel_cell_start);
290     int re = tabular->row_of_cell(sel_cell_end);
291     if (rs > re) {
292         tmp = rs;
293         rs = re;
294         re = tmp;
295     }
296
297     if ((column >= cs) && (column <= ce) && (row >= rs) && (row <= re)) {
298         int w = tabular->GetWidthOfColumn(cell);
299         int h = tabular->GetAscentOfRow(row) + tabular->GetDescentOfRow(row);
300         pain.fillRectangle(x, baseline - tabular->GetAscentOfRow(row),
301                            w, h, LColor::selection);
302     }
303 }
304
305
306 void InsetTabular::update(BufferView * bv, LyXFont const & font, bool reinit)
307 {
308     if (reinit) {
309         need_update = INIT;
310         calculate_dimensions_of_cells(bv, font, true);
311         if (owner())
312             owner()->update(bv, font, true);
313         return;
314     }
315     if (the_locking_inset)
316         the_locking_inset->update(bv, font, reinit);
317     switch(need_update) {
318     case INIT:
319     case FULL:
320     case CELL:
321         if (calculate_dimensions_of_cells(bv, font, false))
322             need_update = INIT;
323         break;
324     case SELECTION:
325         need_update = INIT;
326         break;
327     default:
328         break;
329     }
330 }
331
332
333 char const * InsetTabular::EditMessage() const
334 {
335     return _("Opened Tabular Inset");
336 }
337
338
339 void InsetTabular::Edit(BufferView * bv, int x, int y, unsigned int button)
340 {
341     UpdatableInset::Edit(bv, x, y, button);
342
343     if (!bv->lockInset(this)) {
344         lyxerr[Debug::INSETS] << "InsetTabular::Cannot lock inset" << endl;
345         return;
346     }
347     locked = true;
348     the_locking_inset = 0;
349     inset_pos = inset_x = inset_y = 0;
350     setPos(bv, x, y);
351     sel_pos_start = sel_pos_end = cursor.pos();
352     sel_cell_start = sel_cell_end = actcell;
353     bv->text->FinishUndo();
354     if (InsetHit(bv, x, y)) {
355         ActivateCellInset(bv, x, y, button);
356     }
357     UpdateLocal(bv, NONE, false);
358 //    bv->getOwner()->getPopups().updateFormTabular();
359 }
360
361
362 void InsetTabular::InsetUnlock(BufferView * bv)
363 {
364     TabularOptClose();
365     if (the_locking_inset) {
366         the_locking_inset->InsetUnlock(bv);
367         the_locking_inset = 0;
368     }
369     HideInsetCursor(bv);
370     if (hasSelection()) {
371         sel_pos_start = sel_pos_end = 0;
372         sel_cell_start = sel_cell_end = 0;
373         UpdateLocal(bv, FULL, false);
374     }
375     no_selection = false;
376     oldcell = -1;
377     locked = false;
378 }
379
380 void InsetTabular::UpdateLocal(BufferView * bv, UpdateCodes what,
381                                bool mark_dirty)
382 {
383     need_update = what;
384     bv->updateInset(this, mark_dirty);
385     if (what != NONE)
386         resetPos(bv);
387 }
388
389 bool InsetTabular::LockInsetInInset(BufferView * bv, UpdatableInset * inset)
390 {
391     lyxerr[Debug::INSETS] << "InsetTabular::LockInsetInInset(" <<inset<< "): ";
392     if (!inset)
393         return false;
394     oldcell = -1;
395     if (inset == tabular->GetCellInset(actcell)) {
396         lyxerr[Debug::INSETS] << "OK" << endl;
397         the_locking_inset = tabular->GetCellInset(actcell);
398         resetPos(bv);
399         inset_x = cursor.x() - top_x + tabular->GetBeginningOfTextInCell(actcell);
400         inset_y = cursor.y();
401         inset_pos = cursor.pos();
402         return true;
403     } else if (the_locking_inset && (the_locking_inset == inset)) {
404         if (cursor.pos() == inset_pos) {
405             lyxerr[Debug::INSETS] << "OK" << endl;
406             resetPos(bv);
407             inset_x = cursor.x() - top_x + tabular->GetBeginningOfTextInCell(actcell);
408             inset_y = cursor.y();
409         } else {
410             lyxerr[Debug::INSETS] << "cursor.pos != inset_pos" << endl;
411         }
412     } else if (the_locking_inset) {
413         lyxerr[Debug::INSETS] << "MAYBE" << endl;
414         return the_locking_inset->LockInsetInInset(bv, inset);
415     }
416     lyxerr[Debug::INSETS] << "NOT OK" << endl;
417     return false;
418 }
419
420 bool InsetTabular::UnlockInsetInInset(BufferView * bv, UpdatableInset * inset,
421                                    bool lr)
422 {
423     if (!the_locking_inset)
424         return false;
425     if (the_locking_inset == inset) {
426         the_locking_inset->InsetUnlock(bv);
427         the_locking_inset = 0;
428         if (lr)
429             moveRight(bv, false);
430         UpdateLocal(bv, CELL, false);
431         return true;
432     }
433     if (the_locking_inset->UnlockInsetInInset(bv, inset, lr)) {
434         if ((inset->LyxCode() == TABULAR_CODE) &&
435             !the_locking_inset->GetFirstLockingInsetOfType(TABULAR_CODE))
436         {
437 #ifdef USE_NEW_LAYOUT
438             dialogs_ = bv->owner()->getDialogs();
439             dialogs_->updateTabular(const_cast<InsetTabular *>(this));
440 #else
441             UpdateLayoutTabular(true, const_cast<InsetTabular *>(this));
442 #endif
443             oldcell = actcell;
444         }
445         return true;
446     }
447     return false;
448 }
449
450 bool InsetTabular::UpdateInsetInInset(BufferView * bv, Inset * inset)
451 {
452     if (!the_locking_inset)
453         return false;
454     if (the_locking_inset != inset)
455         return the_locking_inset->UpdateInsetInInset(bv, inset);
456     UpdateLocal(bv, CELL, false);
457     return true;
458 }
459
460
461 int InsetTabular::InsetInInsetY()
462 {
463     if (!the_locking_inset)
464         return 0;
465
466     return (inset_y + the_locking_inset->InsetInInsetY());
467 }
468
469
470 UpdatableInset * InsetTabular::GetLockingInset()
471 {
472     return the_locking_inset ? the_locking_inset->GetLockingInset() : this;
473 }
474
475
476 UpdatableInset * InsetTabular::GetFirstLockingInsetOfType(Inset::Code c)
477 {
478     if (c == LyxCode())
479         return this;
480     if (the_locking_inset)
481         return the_locking_inset->GetFirstLockingInsetOfType(c);
482     return 0;
483 }
484
485
486 bool InsetTabular::InsertInset(BufferView * bv, Inset * inset)
487 {
488     if (the_locking_inset)
489         return the_locking_inset->InsertInset(bv, inset);
490     return false;
491 }
492
493
494 void InsetTabular::InsetButtonPress(BufferView * bv, int x, int y, int button)
495 {
496     if (hasSelection()) {
497         sel_pos_start = sel_pos_end = sel_cell_start = sel_cell_end = 0;
498         UpdateLocal(bv, SELECTION, false);
499     }
500     no_selection = false;
501
502     int ocell = actcell;
503
504     setPos(bv, x, y);
505     sel_pos_start = sel_pos_end = cursor.pos();
506     sel_cell_start = sel_cell_end = actcell;
507
508     bool inset_hit = InsetHit(bv, x, y);
509
510     if ((ocell == actcell) && the_locking_inset && inset_hit) {
511         the_locking_inset->InsetButtonPress(bv, x-inset_x, y-inset_y, button);
512         return;
513     } else if (the_locking_inset) {
514         the_locking_inset->InsetUnlock(bv);
515     }
516     the_locking_inset = 0;
517     if (inset_hit && bv->the_locking_inset) {
518         ActivateCellInset(bv, x, y, button);
519         the_locking_inset->InsetButtonPress(bv, x-inset_x, y-inset_y, button);
520     }
521 }
522
523
524 void InsetTabular::InsetButtonRelease(BufferView * bv,
525                                       int x, int y, int button)
526 {
527     if (button == 3) {
528         if (the_locking_inset) {
529             UpdatableInset * i;
530             if ((i=the_locking_inset->GetFirstLockingInsetOfType(TABULAR_CODE))) {
531                 i->InsetButtonRelease(bv, x, y, button);
532                 return;
533             }
534         }
535 #ifdef USE_NEW_LAYOUT
536         dialogs_ = bv->owner()->getDialogs();
537         dialogs_->showTabular(this);
538 #if 0
539         else if (ocell != actcell)
540                 bview->getOwner()->getPopups().updateTabular();
541 #endif
542 #else
543         MenuLayoutTabular(true, this);
544 #endif
545         return;
546     }
547     if (the_locking_inset) {
548         the_locking_inset->InsetButtonRelease(bv, x-inset_x, y-inset_y,button);
549         return;
550     }
551     no_selection = false;
552 }
553
554
555 void InsetTabular::InsetMotionNotify(BufferView * bv, int x, int y, int button)
556 {
557     if (the_locking_inset) {
558         the_locking_inset->InsetMotionNotify(bv, x - inset_x,
559                                              y - inset_y, button);
560         return;
561     }
562     if (!no_selection) {
563             // int ocell = actcell,
564             int old = sel_pos_end;
565
566         setPos(bv, x, y);
567         sel_pos_end = cursor.pos();
568         sel_cell_end = actcell;
569         if (old != sel_pos_end)
570             UpdateLocal(bv, SELECTION, false);
571 #if 0
572         if (ocell != actcell)
573             bview->getOwner()->getPopups().updateFormTabular();
574 #endif
575     }
576     no_selection = false;
577 }
578
579
580 void InsetTabular::InsetKeyPress(XKeyEvent * xke)
581 {
582     if (the_locking_inset) {
583         the_locking_inset->InsetKeyPress(xke);
584         return;
585     }
586 }
587
588
589 UpdatableInset::RESULT InsetTabular::LocalDispatch(BufferView * bv, int action,
590                                                    string const & arg)
591 {
592     UpdatableInset::RESULT 
593         result;
594
595     no_selection = false;
596     if (((result=UpdatableInset::LocalDispatch(bv, action, arg)) == DISPATCHED)
597         || (result == DISPATCHED_NOUPDATE)) {
598
599         resetPos(bv);
600         return result;
601     }
602     result=DISPATCHED;
603
604     if ((action < 0) && arg.empty())
605         return FINISHED;
606
607     if ((action != LFUN_DOWN) && (action != LFUN_UP) &&
608         (action != LFUN_DOWNSEL) && (action != LFUN_UPSEL))
609         cursor.x_fix(-1);
610     if (the_locking_inset) {
611         result=the_locking_inset->LocalDispatch(bv, action, arg);
612         if (result == DISPATCHED_NOUPDATE)
613             return result;
614         else if (result == DISPATCHED) {
615             the_locking_inset->ToggleInsetCursor(bv);
616             UpdateLocal(bv, CELL, false);
617             the_locking_inset->ToggleInsetCursor(bv);
618             return result;
619         } else if (result == FINISHED) {
620             if ((action == LFUN_RIGHT) || (action == -1)) {
621                 cursor.pos(inset_pos + 1);
622                 resetPos(bv);
623             }
624             sel_pos_start = sel_pos_end = cursor.pos();
625             sel_cell_start = sel_cell_end = actcell;
626             the_locking_inset=0;
627             result = DISPATCHED;
628             return result;
629         }
630     }
631
632     bool hs = hasSelection();
633     HideInsetCursor(bv);
634     switch (action) {
635         // Normal chars not handled here
636     case -1:
637         break;
638         // --- Cursor Movements ---------------------------------------------
639     case LFUN_RIGHTSEL:
640         if (tabular->IsLastCellInRow(actcell) && !cellstart(cursor.pos()))
641             break;
642         moveRight(bv, false);
643         sel_pos_end = cursor.pos();
644         if (!cellstart(cursor.pos())) {
645             if (tabular->right_column_of_cell(sel_cell_start) >
646                 tabular->right_column_of_cell(actcell))
647                 sel_cell_end = actcell+1;
648             else
649                 sel_cell_end = actcell;
650         }
651         UpdateLocal(bv, SELECTION, false);
652         break;
653     case LFUN_RIGHT:
654         result = moveRight(bv);
655         sel_pos_start = sel_pos_end = cursor.pos();
656         sel_cell_start = sel_cell_end = actcell;
657         if (hs)
658             UpdateLocal(bv, CURSOR, false);
659         break;
660     case LFUN_LEFTSEL:
661         if (tabular->IsFirstCellInRow(actcell) && cellstart(cursor.pos()))
662             break;
663         moveLeft(bv, false);
664         sel_pos_end = cursor.pos();
665         if (cellstart(cursor.pos())) {
666             if (tabular->column_of_cell(sel_cell_start) >=
667                 tabular->column_of_cell(actcell))
668                 sel_cell_end = actcell;
669             else
670                 sel_cell_end = actcell-1;
671         }
672         UpdateLocal(bv, SELECTION, false);
673         break;
674     case LFUN_LEFT:
675         result = moveLeft(bv);
676         sel_pos_start = sel_pos_end = cursor.pos();
677         sel_cell_start = sel_cell_end = actcell;
678         if (hs)
679             UpdateLocal(bv, CURSOR, false);
680         break;
681     case LFUN_DOWNSEL:
682     {
683         int ocell = actcell;
684         moveDown(bv);
685         sel_pos_end = cursor.pos();
686         if ((ocell == sel_cell_end) ||
687             (tabular->column_of_cell(ocell)>tabular->column_of_cell(actcell)))
688             sel_cell_end = tabular->GetCellBelow(sel_cell_end);
689         else
690             sel_cell_end = tabular->GetLastCellBelow(sel_cell_end);
691         UpdateLocal(bv, SELECTION, false);
692     }
693     break;
694     case LFUN_DOWN:
695         result= moveDown(bv);
696         sel_pos_start = sel_pos_end = cursor.pos();
697         sel_cell_start = sel_cell_end = actcell;
698         if (hs)
699             UpdateLocal(bv, CURSOR, false);
700         break;
701     case LFUN_UPSEL:
702     {
703         int ocell = actcell;
704         moveUp(bv);
705         sel_pos_end = cursor.pos();
706         if ((ocell == sel_cell_end) ||
707             (tabular->column_of_cell(ocell)>tabular->column_of_cell(actcell)))
708             sel_cell_end = tabular->GetCellAbove(sel_cell_end);
709         else
710             sel_cell_end = tabular->GetLastCellAbove(sel_cell_end);
711         UpdateLocal(bv, SELECTION, false);
712     }
713     break;
714     case LFUN_UP:
715         result= moveUp(bv);
716         sel_pos_start = sel_pos_end = cursor.pos();
717         sel_cell_start = sel_cell_end = actcell;
718         if (hs)
719             UpdateLocal(bv, CURSOR, false);
720         break;
721     case LFUN_BACKSPACE:
722         break;
723     case LFUN_DELETE:
724         break;
725     case LFUN_HOME:
726         break;
727     case LFUN_END:
728         break;
729     case LFUN_SHIFT_TAB:
730     case LFUN_TAB:
731         if (the_locking_inset) {
732             the_locking_inset->InsetUnlock(bv);
733         }
734         the_locking_inset = 0;
735         if (action == LFUN_TAB)
736             moveNextCell(bv);
737         else
738             movePrevCell(bv);
739         sel_pos_start = sel_pos_end = cursor.pos();
740         sel_cell_start = sel_cell_end = actcell;
741         if (hs)
742             UpdateLocal(bv, CURSOR, false);
743         break;
744     case LFUN_LAYOUT_TABLE:
745     {
746 #ifdef USE_NEW_LAYOUT
747         dialogs_ = bv->owner()->getDialogs();
748         dialogs_->showTabular(this);
749 #else
750         int flag = (arg == "true");
751         MenuLayoutTabular(flag, this);
752 #endif
753     }
754     break;
755     default:
756         result = UNDISPATCHED;
757         break;
758     }
759     if (result!=FINISHED) {
760         if (!the_locking_inset) {
761 #if 0       
762             if (ocell != actcell)
763                 bview->getOwner()->getPopups().updateFormTabular();
764 #endif
765             ShowInsetCursor(bv);
766         }
767     } else
768         bv->unlockInset(this);
769     return result;
770 }
771
772
773 int InsetTabular::Latex(Buffer const * buf, ostream & os, bool fragile, bool fp) const
774 {
775     return tabular->Latex(buf, os, fragile, fp);
776 }
777
778
779 int InsetTabular::Ascii(Buffer const *, ostream &) const
780 {
781     return 0;
782 }
783
784 int InsetTabular::Linuxdoc(Buffer const *, ostream &) const
785 {
786     return 0;
787 }
788
789
790 int InsetTabular::DocBook(Buffer const *, ostream &) const
791 {
792     return 0;
793 }
794
795
796 void InsetTabular::Validate(LaTeXFeatures & features) const
797 {
798     tabular->Validate(features);
799 }
800
801
802 bool InsetTabular::calculate_dimensions_of_cells(BufferView * bv,
803                                                  LyXFont const & font,
804                                                  bool reinit) const
805 {
806     int cell = -1;
807     int maxAsc, maxDesc;
808     InsetText * inset;
809     bool changed = false;
810     
811     for(int i = 0; i < tabular->rows(); ++i) {
812         maxAsc = maxDesc = 0;
813         for(int j= 0; j < tabular->columns(); ++j) {
814             if (tabular->IsPartOfMultiColumn(i,j))
815                 continue;
816             ++cell;
817             inset = tabular->GetCellInset(cell);
818             if (!reinit)
819                 inset->update(bv, font, false);
820             maxAsc = max(maxAsc, inset->ascent(bv, font));
821             maxDesc = max(maxDesc, inset->descent(bv, font));
822             changed = tabular->SetWidthOfCell(cell, inset->width(bv, font)) || changed;
823         }
824         changed = tabular->SetAscentOfRow(i, maxAsc + ADD_TO_HEIGHT) || changed;
825         changed = tabular->SetDescentOfRow(i, maxDesc + ADD_TO_HEIGHT) || changed;
826     }
827     return changed;
828 }
829
830
831 void InsetTabular::GetCursorPos(BufferView *, int & x, int & y) const
832 {
833     x = cursor.x() - top_x;
834     y = cursor.y();
835 }
836
837
838 void InsetTabular::ToggleInsetCursor(BufferView * bv)
839 {
840     if (the_locking_inset) {
841         the_locking_inset->ToggleInsetCursor(bv);
842         return;
843     }
844
845     LyXFont font; // = the_locking_inset->GetFont(par, cursor.pos);
846
847     int asc = lyxfont::maxAscent(font);
848     int desc = lyxfont::maxDescent(font);
849   
850     if (cursor_visible)
851         bv->hideLockedInsetCursor();
852     else
853         bv->showLockedInsetCursor(cursor.x(), cursor.y(), asc, desc);
854     cursor_visible = !cursor_visible;
855 }
856
857
858 void InsetTabular::ShowInsetCursor(BufferView * bv)
859 {
860     if (!cursor_visible) {
861         LyXFont font; // = GetFont(par, cursor.pos);
862     
863         int asc = lyxfont::maxAscent(font);
864         int desc = lyxfont::maxDescent(font);
865         bv->fitLockedInsetCursor(cursor.x(), cursor.y(), asc, desc);
866         bv->showLockedInsetCursor(cursor.x(), cursor.y(), asc, desc);
867         cursor_visible = true;
868     }
869 }
870
871
872 void InsetTabular::HideInsetCursor(BufferView * bv)
873 {
874     if (cursor_visible)
875         ToggleInsetCursor(bv);
876 }
877
878
879 void InsetTabular::setPos(BufferView * bv, int x, int y) const
880 {
881         cursor.y(0);
882         cursor.pos(0);
883         
884         actcell = actrow = actcol = 0;
885     int ly = tabular->GetDescentOfRow(actrow);
886
887     // first search the right row
888     while((ly < y) && (actrow < tabular->rows())) {
889         cursor.y(cursor.y() + tabular->GetDescentOfRow(actrow) +
890             tabular->GetAscentOfRow(actrow+1) +
891             tabular->GetAdditionalHeight(tabular->GetCellNumber(actrow + 1,
892                                                                 actcol)));
893         ++actrow;
894         ly = cursor.y() + tabular->GetDescentOfRow(actrow);
895     }
896     actcell = tabular->GetCellNumber(actrow, actcol);
897
898     // now search the right column
899     int lx = tabular->GetWidthOfColumn(actcell) -
900         tabular->GetAdditionalWidth(actcell);
901     for(; !tabular->IsLastCellInRow(actcell) && (lx < x);
902         ++actcell,lx += tabular->GetWidthOfColumn(actcell) +
903             tabular->GetAdditionalWidth(actcell - 1));
904     cursor.pos(((actcell+1) * 2) - 1);
905     resetPos(bv);
906     if ((lx - (tabular->GetWidthOfColumn(actcell)/2)) < x) {
907         cursor.x(lx + top_x - 2);
908     } else {
909         cursor.pos(cursor.pos() - 1);
910         cursor.x(lx - tabular->GetWidthOfColumn(actcell) + top_x + 2);
911     }
912     resetPos(bv);
913 }
914
915 int InsetTabular::getCellXPos(int cell) const
916 {
917     int c;
918
919     for(c=cell;!tabular->IsFirstCellInRow(c);--c)
920         ;
921     int lx = tabular->GetWidthOfColumn(cell);
922     for(; (c < cell); ++c) {
923         lx += tabular->GetWidthOfColumn(c);
924     }
925     return (lx - tabular->GetWidthOfColumn(cell) + top_x +
926             ADD_TO_TABULAR_WIDTH);
927 }
928
929 void InsetTabular::resetPos(BufferView * bv) const
930 {
931     if (!locked)
932         return;
933     actcol = tabular->column_of_cell(actcell);
934
935     int cell = 0;
936     actrow = 0;
937     cursor.y(0);
938     for(; (cell<actcell) && !tabular->IsLastRow(cell); ++cell) {
939         if (tabular->IsLastCellInRow(cell)) {
940             cursor.y(cursor.y() + tabular->GetDescentOfRow(actrow) +
941                 tabular->GetAscentOfRow(actrow + 1) +
942                 tabular->GetAdditionalHeight(cell + 1));
943             ++actrow;
944         }
945     }
946     cursor.x(getCellXPos(actcell) + 2);
947     if (cursor.pos() % 2) {
948         LyXFont font(LyXFont::ALL_SANE);
949         cursor.x(cursor.x() + tabular->GetCellInset(actcell)->width(bv,font) +
950                 tabular->GetBeginningOfTextInCell(actcell));
951     }
952     if ((!the_locking_inset ||
953          !the_locking_inset->GetFirstLockingInsetOfType(TABULAR_CODE)) &&
954         (actcell != oldcell)) {
955 #ifdef USE_NEW_LAYOUT
956         dialogs_ = bv->owner()->getDialogs();
957         dialogs_->updateTabular(const_cast<InsetTabular *>(this));
958 #else
959         UpdateLayoutTabular(true, const_cast<InsetTabular *>(this));
960 #endif
961         oldcell = actcell;
962     }
963 }
964
965
966 UpdatableInset::RESULT InsetTabular::moveRight(BufferView * bv, bool lock)
967 {
968     if (!cellstart(cursor.pos())) {
969         if (tabular->IsLastCell(actcell))
970             return FINISHED;
971         ++actcell;
972         cursor.pos(cursor.pos() + 1);
973     } else if (lock) {
974         if (ActivateCellInset(bv))
975             return DISPATCHED;
976     } else {              // before the inset
977         cursor.pos(cursor.pos() + 1);
978     }
979     resetPos(bv);
980     return DISPATCHED_NOUPDATE;
981 }
982
983
984 UpdatableInset::RESULT InsetTabular::moveLeft(BufferView * bv, bool lock)
985 {
986     if (!cursor.pos()) {
987         if (!actcell)
988             return FINISHED;
989         cursor.pos(2);
990     }
991     cursor.pos(cursor.pos() - 1);
992     if (!cellstart(cursor.pos())) {
993         --actcell;
994     } else if (lock) {       // behind the inset
995         if (ActivateCellInset(bv, 0, 0, 0, true))
996             return DISPATCHED;
997     }
998     resetPos(bv);
999     return DISPATCHED_NOUPDATE;
1000 }
1001
1002
1003 UpdatableInset::RESULT InsetTabular::moveUp(BufferView * bv)
1004 {
1005     int ocell = actcell;
1006     actcell = tabular->GetCellAbove(actcell);
1007     if (actcell == ocell) // we moved out of the inset
1008         return FINISHED;
1009     resetPos(bv);
1010     return DISPATCHED_NOUPDATE;
1011 }
1012
1013
1014 UpdatableInset::RESULT InsetTabular::moveDown(BufferView * bv)
1015 {
1016     int ocell = actcell;
1017     actcell = tabular->GetCellBelow(actcell);
1018     if (actcell == ocell) // we moved out of the inset
1019         return FINISHED;
1020     resetPos(bv);
1021     return DISPATCHED_NOUPDATE;
1022 }
1023
1024
1025 bool InsetTabular::moveNextCell(BufferView * bv)
1026 {
1027     if (tabular->IsLastCell(actcell))
1028         return false;
1029     ++actcell;
1030     cursor.pos(cursor.pos() + 1);
1031     if (!cellstart(cursor.pos()))
1032         cursor.pos(cursor.pos() + 1);
1033     resetPos(bv);
1034     return true;
1035 }
1036
1037
1038 bool InsetTabular::movePrevCell(BufferView * bv)
1039 {
1040     if (!actcell) // first cell
1041         return false;
1042     --actcell;
1043     cursor.pos(cursor.pos() - 1);
1044     if (cellstart(cursor.pos()))
1045         cursor.pos(cursor.pos() - 1);
1046     resetPos(bv);
1047     return true;
1048 }
1049
1050
1051 bool InsetTabular::Delete()
1052 {
1053     return true;
1054 }
1055
1056
1057 void InsetTabular::SetFont(BufferView * bv, LyXFont const & font, bool tall)
1058 {
1059     if (the_locking_inset)
1060         the_locking_inset->SetFont(bv, font, tall);
1061 }
1062
1063
1064 void InsetTabular::TabularFeatures(BufferView * bv, int feature, string val)
1065 {
1066     int
1067         i, j,
1068         sel_col_start,
1069         sel_col_end,
1070         sel_row_start,
1071         sel_row_end,
1072         setLines = 0,
1073         setAlign = LYX_ALIGN_LEFT,
1074         lineSet;
1075     bool
1076         what;
1077
1078     switch (feature) {
1079       case LyXTabular::ALIGN_LEFT:
1080           setAlign=LYX_ALIGN_LEFT;
1081           break;
1082       case LyXTabular::ALIGN_RIGHT:
1083           setAlign=LYX_ALIGN_RIGHT;
1084           break;
1085       case LyXTabular::ALIGN_CENTER:
1086           setAlign=LYX_ALIGN_CENTER;
1087           break;
1088       default:
1089           break;
1090     }
1091     if (hasSelection()) {
1092         int tmp;
1093         sel_col_start = tabular->column_of_cell(sel_cell_start);
1094         sel_col_end = tabular->column_of_cell(sel_cell_end);
1095         if (sel_col_start > sel_col_end) {
1096             sel_col_end = sel_col_start;
1097             sel_col_start = tabular->column_of_cell(sel_cell_end);
1098         } else {
1099             sel_col_end = tabular->right_column_of_cell(sel_cell_end);
1100         }
1101         
1102         sel_row_start = tabular->row_of_cell(sel_cell_start);
1103         sel_row_end = tabular->row_of_cell(sel_cell_end);
1104         if (sel_row_start > sel_row_end) {
1105             tmp = sel_row_start;
1106             sel_row_start = sel_row_end;
1107             sel_row_end = tmp;
1108         }
1109     } else {
1110         sel_col_start = sel_col_end = tabular->column_of_cell(actcell);
1111         sel_row_start = sel_row_end = tabular->row_of_cell(actcell);
1112     }
1113     bv->text->SetUndo(bv->buffer(), Undo::FINISH, 
1114               bv->text->cursor.par()->ParFromPos(bv->text->cursor.pos())->previous,
1115               bv->text->cursor.par()->ParFromPos(bv->text->cursor.pos())->next);
1116
1117     int row = tabular->row_of_cell(actcell);
1118     int column = tabular->column_of_cell(actcell);
1119
1120     switch (feature) {
1121     case LyXTabular::SET_PWIDTH:
1122     {
1123         bool update = (tabular->GetPWidth(actcell) != val);
1124         tabular->SetPWidth(actcell,val);
1125         if (update) {
1126             for (int i=0; i < tabular->rows(); ++i) {
1127                 tabular->GetCellInset(tabular->GetCellNumber(i, column))->
1128                     deleteLyXText(bv);
1129             }
1130             UpdateLocal(bv, INIT, true);
1131         }
1132     }
1133     break;
1134     case LyXTabular::SET_SPECIAL_COLUMN:
1135     case LyXTabular::SET_SPECIAL_MULTI:
1136         tabular->SetAlignSpecial(actcell,val,feature);
1137         break;
1138     case LyXTabular::APPEND_ROW:
1139         // append the row into the tabular
1140         UnlockInsetInInset(bv, the_locking_inset);
1141         tabular->AppendRow(actcell);
1142         UpdateLocal(bv, INIT, true);
1143         break;
1144     case LyXTabular::APPEND_COLUMN:
1145         // append the column into the tabular
1146         tabular->AppendColumn(actcell);
1147         actcell = tabular->GetCellNumber(row, column);
1148         UpdateLocal(bv, INIT, true);
1149         break;
1150     case LyXTabular::DELETE_ROW:
1151         tabular->DeleteRow(tabular->row_of_cell(actcell));
1152         if ((row+1) > tabular->rows())
1153             --row;
1154         actcell = tabular->GetCellNumber(row, column);
1155         UpdateLocal(bv, INIT, true);
1156         break;
1157     case LyXTabular::DELETE_COLUMN:
1158         tabular->DeleteColumn(tabular->column_of_cell(actcell));
1159         if ((column+1) > tabular->columns())
1160             --column;
1161         actcell = tabular->GetCellNumber(row, column);
1162         UpdateLocal(bv, INIT, true);
1163         break;
1164     case LyXTabular::TOGGLE_LINE_TOP:
1165         lineSet = !tabular->TopLine(actcell);
1166         for(i=sel_row_start; i<=sel_row_end; ++i)
1167             for(j=sel_col_start; j<=sel_col_end; ++j)
1168                 tabular->SetTopLine(tabular->GetCellNumber(i,j),lineSet);
1169         UpdateLocal(bv, INIT, true);
1170         break;
1171     
1172     case LyXTabular::TOGGLE_LINE_BOTTOM:
1173         lineSet = !tabular->BottomLine(actcell); 
1174         for(i=sel_row_start; i<=sel_row_end; ++i)
1175             for(j=sel_col_start; j<=sel_col_end; ++j)
1176                 tabular->SetBottomLine(tabular->GetCellNumber(i,j),lineSet);
1177         UpdateLocal(bv, INIT, true);
1178         break;
1179                 
1180     case LyXTabular::TOGGLE_LINE_LEFT:
1181         lineSet = !tabular->LeftLine(actcell);
1182         for(i=sel_row_start; i<=sel_row_end; ++i)
1183             for(j=sel_col_start; j<=sel_col_end; ++j)
1184                 tabular->SetLeftLine(tabular->GetCellNumber(i,j),lineSet);
1185         UpdateLocal(bv, INIT, true);
1186         break;
1187
1188     case LyXTabular::TOGGLE_LINE_RIGHT:
1189         lineSet = !tabular->RightLine(actcell);
1190         for(i=sel_row_start; i<=sel_row_end; ++i)
1191             for(j=sel_col_start; j<=sel_col_end; ++j)
1192                 tabular->SetRightLine(tabular->GetCellNumber(i,j),lineSet);
1193         UpdateLocal(bv, INIT, true);
1194         break;
1195     case LyXTabular::ALIGN_LEFT:
1196     case LyXTabular::ALIGN_RIGHT:
1197     case LyXTabular::ALIGN_CENTER:
1198         for(i=sel_row_start; i<=sel_row_end; ++i)
1199             for(j=sel_col_start; j<=sel_col_end; ++j)
1200                 tabular->SetAlignment(tabular->GetCellNumber(i,j),setAlign);
1201         if (hasSelection())
1202             UpdateLocal(bv, INIT, true);
1203         else
1204             UpdateLocal(bv, CELL, true);
1205         break;
1206     case LyXTabular::MULTICOLUMN:
1207     {
1208         if (sel_row_start != sel_row_end) {
1209             WriteAlert(_("Impossible Operation!"), 
1210                        _("Multicolumns can only be horizontally."), 
1211                        _("Sorry."));
1212             return;
1213         }
1214         // just multicol for one Single Cell
1215         if (!hasSelection()) {
1216             // check wether we are completly in a multicol
1217             if (tabular->IsMultiColumn(actcell)) {
1218                 tabular->UnsetMultiColumn(actcell);
1219                 UpdateLocal(bv, INIT, true);
1220             } else {
1221                 tabular->SetMultiColumn(actcell, 1);
1222                 UpdateLocal(bv, CELL, true);
1223             }
1224             return;
1225         }
1226         // we have a selection so this means we just add all this
1227         // cells to form a multicolumn cell
1228         int
1229             s_start, s_end;
1230
1231         if (sel_cell_start > sel_cell_end) {
1232             s_start = sel_cell_end;
1233             s_end = sel_cell_start;
1234         } else {
1235             s_start = sel_cell_start;
1236             s_end = sel_cell_end;
1237         }
1238         tabular->SetMultiColumn(s_start, s_end - s_start + 1);
1239         actcell = s_start;
1240         cursor.pos(0);
1241         sel_cell_end = sel_cell_start;
1242         sel_pos_end = sel_pos_start;
1243         UpdateLocal(bv, INIT, true);
1244         break;
1245     }
1246     case LyXTabular::SET_ALL_LINES:
1247         setLines = 1;
1248     case LyXTabular::UNSET_ALL_LINES:
1249         for(i=sel_row_start; i<=sel_row_end; ++i)
1250             for(j=sel_col_start; j<=sel_col_end; ++j)
1251                 tabular->SetAllLines(tabular->GetCellNumber(i,j), setLines);
1252         UpdateLocal(bv, INIT, true);
1253         break;
1254     case LyXTabular::SET_LONGTABULAR:
1255         tabular->SetLongTabular(true);
1256         UpdateLocal(bv, INIT, true); // because this toggles displayed
1257         break;
1258     case LyXTabular::UNSET_LONGTABULAR:
1259         tabular->SetLongTabular(false);
1260         UpdateLocal(bv, INIT, true); // because this toggles displayed
1261         break;
1262     case LyXTabular::SET_ROTATE_TABULAR:
1263         tabular->SetRotateTabular(true);
1264         break;
1265     case LyXTabular::UNSET_ROTATE_TABULAR:
1266         tabular->SetRotateTabular(false);
1267         break;
1268     case LyXTabular::SET_ROTATE_CELL:
1269         for(i=sel_row_start; i<=sel_row_end; ++i)
1270             for(j=sel_col_start; j<=sel_col_end; ++j)
1271                 tabular->SetRotateCell(tabular->GetCellNumber(i,j),true);
1272         break;
1273     case LyXTabular::UNSET_ROTATE_CELL:
1274         for(i=sel_row_start; i<=sel_row_end; ++i)
1275             for(j=sel_col_start; j<=sel_col_end; ++j)
1276                 tabular->SetRotateCell(tabular->GetCellNumber(i,j),false);
1277         break;
1278     case LyXTabular::SET_LINEBREAKS:
1279         what = !tabular->GetLinebreaks(actcell);
1280         for(i=sel_row_start; i<=sel_row_end; ++i)
1281             for(j=sel_col_start; j<=sel_col_end; ++j)
1282                 tabular->SetLinebreaks(tabular->GetCellNumber(i,j),what);
1283         break;
1284     case LyXTabular::SET_LTFIRSTHEAD:
1285         tabular->SetLTHead(actcell,true);
1286         break;
1287     case LyXTabular::SET_LTHEAD:
1288         tabular->SetLTHead(actcell,false);
1289         break;
1290     case LyXTabular::SET_LTFOOT:
1291         tabular->SetLTFoot(actcell,false);
1292         break;
1293     case LyXTabular::SET_LTLASTFOOT:
1294         tabular->SetLTFoot(actcell,true);
1295         break;
1296     case LyXTabular::SET_LTNEWPAGE:
1297         what = !tabular->GetLTNewPage(actcell);
1298         tabular->SetLTNewPage(actcell,what);
1299         break;
1300     }
1301 }
1302
1303 bool InsetTabular::ActivateCellInset(BufferView * bv, int x, int y, int button,
1304                                      bool behind)
1305 {
1306     // the cursor.pos has to be before the inset so if it isn't now just
1307     // reset the curor pos first!
1308     if (cursor.pos() % 2) { // behind the inset
1309         cursor.pos(cursor.pos() - 1);
1310         resetPos(bv);
1311     }
1312     UpdatableInset * inset =
1313         static_cast<UpdatableInset*>(tabular->GetCellInset(actcell));
1314     LyXFont font(LyXFont::ALL_SANE);
1315     if (behind) {
1316         x = inset->x() + inset->width(bv, font);
1317         y = inset->descent(bv, font);
1318     }
1319     inset_x = cursor.x() - top_x + tabular->GetBeginningOfTextInCell(actcell);
1320     inset_y = cursor.y();
1321     inset->Edit(bv, x - inset_x, y - inset_y, button);
1322     if (!the_locking_inset)
1323         return false;
1324     UpdateLocal(bv, CELL, false);
1325     return true;
1326 }
1327
1328 bool InsetTabular::InsetHit(BufferView * bv, int x, int ) const
1329 {
1330     InsetText * inset = tabular->GetCellInset(actcell);
1331     int x1 = x + top_x;
1332
1333     if (cursor.pos() % 2) { // behind the inset
1334         return (((x + top_x) < cursor.x()) &&
1335                 ((x + top_x) > (cursor.x() - inset->width(bv,
1336                                                       LyXFont(LyXFont::ALL_SANE)))));
1337     } else {
1338         int x2 = cursor.x() + tabular->GetBeginningOfTextInCell(actcell);
1339         return ((x1 > x2) &&
1340                 (x1 < (x2 + inset->width(bv, LyXFont(LyXFont::ALL_SANE)))));
1341     }
1342 }
1343
1344 // This returns paperWidth() if the cell-width is unlimited or the width
1345 // in pixels if we have a pwidth for this cell.
1346 int InsetTabular::GetMaxWidthOfCell(Painter &, int cell) const
1347 {
1348     string s = tabular->GetPWidth(cell);
1349
1350     if (s.empty())
1351         return -1;
1352     return VSpace(s).inPixels( 0, 0);
1353 }
1354
1355 int InsetTabular::getMaxWidth(Painter & pain,
1356                               UpdatableInset const * inset) const
1357 {
1358     int cell;
1359     int n = tabular->GetNumberOfCells();
1360     for(cell=0; cell < n; ++cell) {
1361         if (tabular->GetCellInset(cell) == inset)
1362             break;
1363     }
1364     if (cell >= n)
1365         return -1;
1366     int w = GetMaxWidthOfCell(pain, cell);
1367     // this because text insets remove the xpos from the maxwidth because
1368     // otherwise the would not break good!!!
1369 //    w += getCellXPos(cell) + tabular->GetBeginningOfTextInCell(cell);
1370 //    w += inset->x();
1371     return w;
1372 }
1373
1374 void InsetTabular::recomputeTextInsets(BufferView * bv, const LyXFont & font) const
1375 {
1376     InsetText * inset;
1377     int cell;
1378
1379 //    cx = top_x;
1380     for(int j= 0; j < tabular->columns(); ++j) {
1381         for(int i = 0; i < tabular->rows(); ++i) {
1382             if (tabular->IsPartOfMultiColumn(i,j))
1383                 continue;
1384             cell = tabular->GetCellNumber(i,j);
1385             inset = tabular->GetCellInset(cell);
1386             inset->update(bv, font);
1387             tabular->SetWidthOfCell(cell, inset->width(bv, font));
1388         }
1389 //      cell = tabular->GetCellNumber(0, j);
1390 //      cx += tabular->GetWidthOfColumn(cell);
1391     }
1392 }