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