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