1 /* This file is part of
2 * ======================================================
4 * LyX, The Document Processor
6 * Copyright 2000 The LyX Team.
8 *======================================================
19 #pragma implementation
22 #include "insettabular.h"
25 #include "commandtags.h"
26 #include "LaTeXFeatures.h"
30 #include "lyx_gui_misc.h"
33 #include "insets/insettext.h"
35 extern void MenuLayoutTabular(bool, InsetTabular *);
36 extern bool UpdateLayoutTabular(bool, InsetTabular *);
37 extern void TabularOptClose();
39 const int ADD_TO_HEIGHT = 2;
40 const int ADD_TO_TABULAR_WIDTH = 2;
47 #define cellstart(p) ((p % 2) == 0)
49 InsetTabular::InsetTabular(Buffer * buf, int rows, int columns)
55 buffer = buf; // set this first!!!
56 tabular = new LyXTabular(this, rows,columns);
57 // for now make it always display as display() inset
59 the_locking_inset = 0;
60 locked = no_selection = cursor_visible = false;
63 actcell = cursor.pos = sel_pos_start = sel_pos_end = 0;
68 InsetTabular::InsetTabular(InsetTabular const & tab, Buffer * buf)
70 buffer = buf; // set this first
71 tabular = new LyXTabular(this, *(tab.tabular));
72 the_locking_inset = 0;
73 locked = no_selection = cursor_visible = false;
76 actcell = cursor.pos = sel_pos_start = sel_pos_end = 0;
81 InsetTabular::~InsetTabular()
87 Inset * InsetTabular::Clone() const
89 InsetTabular * t = new InsetTabular(*this, buffer);
91 t->tabular = tabular->Clone(t);
96 void InsetTabular::Write(ostream & os) const
98 os << " Tabular" << endl;
103 void InsetTabular::Read(LyXLex & lex)
105 bool old_format = (lex.GetString() == "\\LyXTable");
110 tabular = new LyXTabular(this, lex);
118 token = lex.GetString();
119 while (lex.IsOK() && (token != "\\end_inset")) {
121 token = lex.GetString();
123 if (token != "\\end_inset") {
124 lex.printError("Missing \\end_inset at this point. "
130 int InsetTabular::ascent(Painter & pain, LyXFont const & font) const
133 calculate_width_of_cells(pain, font);
136 return tabular->GetAscentOfRow(0);
140 int InsetTabular::descent(Painter & pain, LyXFont const & font) const
143 calculate_width_of_cells(pain, font);
146 return tabular->GetHeightOfTabular() - tabular->GetAscentOfRow(0);
150 int InsetTabular::width(Painter & pain, LyXFont const & font) const
153 calculate_width_of_cells(pain, font);
156 return tabular->GetWidthOfTabular() + (2 * ADD_TO_TABULAR_WIDTH);
160 void InsetTabular::draw(Painter & pain, const LyXFont & font, int baseline,
168 UpdatableInset::draw(pain,font,baseline,x);
169 if (init_inset || (top_x != int(x)) || (top_baseline != baseline)) {
173 top_baseline = baseline;
175 recomputeTextInsets(pain, font);
176 calculate_width_of_cells(pain, font);
180 x += ADD_TO_TABULAR_WIDTH;
181 for(i=0;i<tabular->rows();++i) {
183 for(j=0;j<tabular->columns();++j) {
184 if (tabular->IsPartOfMultiColumn(i,j))
186 cx = nx + tabular->GetBeginningOfTextInCell(cell);
188 DrawCellSelection(pain, nx, baseline, i, cell);
189 tabular->GetCellInset(cell)->draw(pain, font, baseline, cx);
190 DrawCellLines(pain, nx, baseline, i, cell);
191 nx += tabular->GetWidthOfColumn(cell);
194 baseline += tabular->GetDescentOfRow(i) + tabular->GetAscentOfRow(i+1)
195 + tabular->GetAdditionalHeight(cell+1);
197 x += width(pain, font);
201 void InsetTabular::DrawCellLines(Painter & pain, int x, int baseline,
202 int row, int cell) const
204 int x2 = x + tabular->GetWidthOfColumn(cell);
207 if (!tabular->TopAlreadyDrawed(cell)) {
208 on_off = !tabular->TopLine(cell);
209 pain.line(x, baseline - tabular->GetAscentOfRow(row),
210 x2, baseline - tabular->GetAscentOfRow(row),
211 on_off ? LColor::tabularonoffline:LColor::tabularline,
212 on_off ? Painter::line_onoffdash:Painter::line_solid);
214 on_off = !tabular->BottomLine(cell);
215 pain.line(x,baseline + tabular->GetDescentOfRow(row),
216 x2, baseline + tabular->GetDescentOfRow(row),
217 on_off ? LColor::tabularonoffline:LColor::tabularline,
218 on_off ? Painter::line_onoffdash:Painter::line_solid);
219 if (!tabular->LeftAlreadyDrawed(cell)) {
220 on_off = !tabular->LeftLine(cell);
221 pain.line(x, baseline - tabular->GetAscentOfRow(row),
222 x, baseline + tabular->GetDescentOfRow(row),
223 on_off ? LColor::tabularonoffline:LColor::tabularline,
224 on_off ? Painter::line_onoffdash:Painter::line_solid);
226 on_off = !tabular->RightLine(cell);
227 pain.line(x2 - tabular->GetAdditionalWidth(cell),
228 baseline - tabular->GetAscentOfRow(row),
229 x2 - tabular->GetAdditionalWidth(cell),
230 baseline + tabular->GetDescentOfRow(row),
231 on_off ? LColor::tabularonoffline:LColor::tabularline,
232 on_off ? Painter::line_onoffdash:Painter::line_solid);
236 void InsetTabular::DrawCellSelection(Painter & pain, int x, int baseline,
237 int row, int cell) const
240 if (sel_cell_start > sel_cell_end) {
241 start = sel_cell_end;
242 end = sel_cell_start;
244 start = sel_cell_start;
247 int c1 = tabular->column_of_cell(cell);
248 int cs = tabular->column_of_cell(start);
250 if (tabular->IsLastCellInRow(end))
251 ce = tabular->columns() - 1;
253 ce = tabular->column_of_cell(end+1) - 1; // because of multic.
254 int rs = tabular->row_of_cell(start);
255 int re = tabular->row_of_cell(end);
257 if ((c1 >= cs) && (c1 <= ce) && (row >= rs) && (row <= re)) {
258 int w = tabular->GetWidthOfColumn(cell);
259 int h = tabular->GetAscentOfRow(row) + tabular->GetDescentOfRow(row);
260 pain.fillRectangle(x, baseline - tabular->GetAscentOfRow(row),
261 w, h, LColor::selection);
266 char const * InsetTabular::EditMessage() const
268 return _("Opened Tabular Inset");
272 void InsetTabular::Edit(BufferView * bv, int x, int y, unsigned int button)
274 UpdatableInset::Edit(bv, x, y, button);
276 if (!bv->lockInset(this)) {
277 lyxerr[Debug::INSETS] << "InsetTabular::Cannot lock inset" << endl;
281 the_locking_inset = 0;
282 inset_pos = inset_x = inset_y = 0;
283 setPos(bv->painter(), x, y);
284 sel_pos_start = sel_pos_end = cursor.pos;
285 sel_cell_start = sel_cell_end = actcell;
286 bv->text->FinishUndo();
287 if (InsetHit(bv, x, y)) {
288 ActivateCellInset(bv, x, y, button);
290 UpdateLocal(bv, true);
291 // bv->getOwner()->getPopups().updateFormTabular();
295 void InsetTabular::InsetUnlock(BufferView * bv)
298 if (the_locking_inset) {
299 the_locking_inset->InsetUnlock(bv);
300 the_locking_inset = 0;
303 if (hasSelection()) {
304 sel_pos_start = sel_pos_end = cursor.pos;
305 sel_cell_start = sel_cell_end = actcell;
306 UpdateLocal(bv, false);
308 no_selection = false;
313 void InsetTabular::UpdateLocal(BufferView * bv, bool flag)
316 calculate_width_of_cells(bv->painter(), LyXFont(LyXFont::ALL_SANE));
317 bv->updateInset(this, flag);
319 resetPos(bv->painter());
322 bool InsetTabular::LockInsetInInset(BufferView * bv, UpdatableInset * inset)
324 lyxerr[Debug::INSETS] << "InsetTabular::LockInsetInInset(" <<inset<< "): ";
328 if (inset == tabular->GetCellInset(actcell)) {
329 lyxerr[Debug::INSETS] << "OK" << endl;
330 the_locking_inset = tabular->GetCellInset(actcell);
331 resetPos(bv->painter());
332 inset_x = cursor.x - top_x + tabular->GetBeginningOfTextInCell(actcell);
334 inset_pos = cursor.pos;
336 } else if (the_locking_inset && (the_locking_inset == inset)) {
337 if (cursor.pos == inset_pos) {
338 lyxerr[Debug::INSETS] << "OK" << endl;
339 resetPos(bv->painter());
340 inset_x = cursor.x - top_x + tabular->GetBeginningOfTextInCell(actcell);
343 lyxerr[Debug::INSETS] << "cursor.pos != inset_pos" << endl;
345 } else if (the_locking_inset) {
346 lyxerr[Debug::INSETS] << "MAYBE" << endl;
347 return the_locking_inset->LockInsetInInset(bv, inset);
349 lyxerr[Debug::INSETS] << "NOT OK" << endl;
353 bool InsetTabular::UnlockInsetInInset(BufferView * bv, UpdatableInset * inset,
356 if (!the_locking_inset)
358 if (the_locking_inset == inset) {
359 the_locking_inset->InsetUnlock(bv);
360 the_locking_inset = 0;
362 moveRight(bv, false);
365 if (the_locking_inset->UnlockInsetInInset(bv, inset, lr)) {
366 if ((inset->LyxCode() == TABULAR_CODE) &&
367 !the_locking_inset->GetFirstLockingInsetOfType(TABULAR_CODE))
369 UpdateLayoutTabular(true, const_cast<InsetTabular *>(this));
377 bool InsetTabular::UpdateInsetInInset(BufferView * bv, Inset * inset)
379 if (!the_locking_inset)
381 if (the_locking_inset != inset)
382 return the_locking_inset->UpdateInsetInInset(bv, inset);
388 int InsetTabular::InsetInInsetY()
390 if (!the_locking_inset)
393 return (inset_y + the_locking_inset->InsetInInsetY());
397 UpdatableInset * InsetTabular::GetLockingInset()
399 return the_locking_inset ? the_locking_inset->GetLockingInset() : this;
403 UpdatableInset * InsetTabular::GetFirstLockingInsetOfType(Inset::Code c)
407 if (the_locking_inset)
408 return the_locking_inset->GetFirstLockingInsetOfType(c);
413 bool InsetTabular::InsertInset(BufferView * bv, Inset * inset)
415 if (the_locking_inset)
416 return the_locking_inset->InsertInset(bv, inset);
421 void InsetTabular::InsetButtonRelease(BufferView * bv,
422 int x, int y, int button)
425 if (the_locking_inset) {
427 if ((i=the_locking_inset->GetFirstLockingInsetOfType(TABULAR_CODE))) {
428 i->InsetButtonRelease(bv, x, y, button);
432 MenuLayoutTabular(true, this);
435 if (the_locking_inset) {
436 the_locking_inset->InsetButtonRelease(bv, x-inset_x, y-inset_y,button);
439 no_selection = false;
443 void InsetTabular::InsetButtonPress(BufferView * bv, int x, int y, int button)
445 if (hasSelection()) {
446 sel_pos_start = sel_pos_end = sel_cell_start = sel_cell_end = 0;
447 UpdateLocal(bv, false);
449 no_selection = false;
453 setPos(bv->painter(), x, y);
454 sel_pos_start = sel_pos_end = cursor.pos;
455 sel_cell_start = sel_cell_end = actcell;
457 bool inset_hit = InsetHit(bv, x, y);
459 if ((ocell == actcell) && the_locking_inset && inset_hit) {
460 the_locking_inset->InsetButtonPress(bv, x-inset_x, y-inset_y, button);
462 } else if (the_locking_inset) {
463 the_locking_inset->InsetUnlock(bv);
465 the_locking_inset = 0;
466 if (inset_hit && bv->the_locking_inset) {
467 ActivateCellInset(bv, x, y, button);
468 the_locking_inset->InsetButtonPress(bv, x-inset_x, y-inset_y, button);
473 bview->getOwner()->getPopups().showFormTabular();
474 else if (ocell != actcell)
475 bview->getOwner()->getPopups().updateFormTabular();
480 void InsetTabular::InsetMotionNotify(BufferView * bv, int x, int y, int button)
482 if (the_locking_inset) {
483 the_locking_inset->InsetMotionNotify(bv, x - inset_x,
484 y - inset_y, button);
488 // int ocell = actcell,
489 int old = sel_pos_end;
491 setPos(bv->painter(), x, y);
492 sel_pos_end = cursor.pos;
493 sel_cell_end = actcell;
494 if (old != sel_pos_end)
495 UpdateLocal(bv, false);
497 if (ocell != actcell)
498 bview->getOwner()->getPopups().updateFormTabular();
501 no_selection = false;
505 void InsetTabular::InsetKeyPress(XKeyEvent * xke)
507 if (the_locking_inset) {
508 the_locking_inset->InsetKeyPress(xke);
514 UpdatableInset::RESULT InsetTabular::LocalDispatch(BufferView * bv, int action,
517 UpdatableInset::RESULT
520 no_selection = false;
521 if (((result=UpdatableInset::LocalDispatch(bv, action, arg)) == DISPATCHED)
522 || (result == DISPATCHED_NOUPDATE)) {
524 resetPos(bv->painter());
529 if ((action < 0) && arg.empty())
532 if ((action != LFUN_DOWN) && (action != LFUN_UP) &&
533 (action != LFUN_DOWNSEL) && (action != LFUN_UPSEL))
535 if (the_locking_inset) {
536 result=the_locking_inset->LocalDispatch(bv, action, arg);
537 if (result == DISPATCHED_NOUPDATE)
539 else if (result == DISPATCHED) {
540 bool upd = SetCellDimensions(bv->painter(), actcell, actrow);
541 the_locking_inset->ToggleInsetCursor(bv);
542 UpdateLocal(bv, upd);
543 the_locking_inset->ToggleInsetCursor(bv);
545 } else if (result == FINISHED) {
546 if ((action == LFUN_RIGHT) || (action == -1)) {
547 cursor.pos = inset_pos + 1;
548 resetPos(bv->painter());
556 bool hs = hasSelection();
559 // Normal chars not handled here
562 // --- Cursor Movements ---------------------------------------------
564 moveRight(bv, false);
565 sel_pos_end = cursor.pos;
566 if (!cellstart(cursor.pos)) {
567 if (sel_cell_start >= actcell)
568 sel_cell_end = actcell+1;
570 sel_cell_end = actcell;
572 UpdateLocal(bv, false);
575 result = moveRight(bv);
576 sel_pos_start = sel_pos_end = cursor.pos;
577 sel_cell_start = sel_cell_end = actcell;
579 UpdateLocal(bv, false);
583 sel_pos_end = cursor.pos;
584 if (cellstart(cursor.pos)) {
585 if (sel_cell_start >= actcell)
586 sel_cell_end = actcell;
588 sel_cell_end = actcell-1;
590 UpdateLocal(bv, false);
593 result = moveLeft(bv);
594 sel_pos_start = sel_pos_end = cursor.pos;
595 sel_cell_start = sel_cell_end = actcell;
597 UpdateLocal(bv, false);
601 sel_pos_end = cursor.pos;
602 sel_cell_end = actcell;
603 UpdateLocal(bv, false);
606 result= moveDown(bv);
607 sel_pos_start = sel_pos_end = cursor.pos;
608 sel_cell_start = sel_cell_end = actcell;
610 UpdateLocal(bv, false);
614 sel_pos_end = cursor.pos;
615 sel_cell_end = actcell;
616 UpdateLocal(bv, false);
620 sel_pos_start = sel_pos_end = cursor.pos;
621 sel_cell_start = sel_cell_end = actcell;
623 UpdateLocal(bv, false);
635 if (the_locking_inset) {
636 the_locking_inset->InsetUnlock(bv);
638 the_locking_inset = 0;
639 if (action == LFUN_TAB)
643 sel_pos_start = sel_pos_end = cursor.pos;
644 sel_cell_start = sel_cell_end = actcell;
646 UpdateLocal(bv, false);
648 case LFUN_LAYOUT_TABLE:
650 int flag = (arg == "true");
651 MenuLayoutTabular(flag, this);
655 result = UNDISPATCHED;
658 if (result!=FINISHED) {
659 if (!the_locking_inset) {
661 if (ocell != actcell)
662 bview->getOwner()->getPopups().updateFormTabular();
667 bv->unlockInset(this);
672 int InsetTabular::Latex(ostream & os, bool fragile, bool fp) const
674 return tabular->Latex(os, fragile, fp);
678 int InsetTabular::Ascii(ostream &) const
683 int InsetTabular::Linuxdoc(ostream &) const
689 int InsetTabular::DocBook(ostream &) const
695 void InsetTabular::Validate(LaTeXFeatures & features) const
697 tabular->Validate(features);
701 void InsetTabular::calculate_width_of_cells(Painter & pain,
702 LyXFont const & font) const
708 for(int i = 0; i < tabular->rows(); ++i) {
709 maxAsc = maxDesc = 0;
710 for(int j= 0; j < tabular->columns(); ++j) {
711 if (tabular->IsPartOfMultiColumn(i,j))
714 inset = tabular->GetCellInset(cell);
715 maxAsc = max(maxAsc, inset->ascent(pain, font));
716 maxDesc = max(maxDesc, inset->descent(pain, font));
717 tabular->SetWidthOfCell(cell, inset->width(pain, font));
719 tabular->SetAscentOfRow(i, maxAsc + ADD_TO_HEIGHT);
720 tabular->SetDescentOfRow(i, maxDesc + ADD_TO_HEIGHT);
725 void InsetTabular::GetCursorPos(int & x, int & y) const
732 void InsetTabular::ToggleInsetCursor(BufferView * bv)
734 if (the_locking_inset) {
735 the_locking_inset->ToggleInsetCursor(bv);
739 LyXFont font; // = the_locking_inset->GetFont(par, cursor.pos);
741 int asc = lyxfont::maxAscent(font);
742 int desc = lyxfont::maxDescent(font);
745 bv->hideLockedInsetCursor();
747 bv->showLockedInsetCursor(cursor.x, cursor.y, asc, desc);
748 cursor_visible = !cursor_visible;
752 void InsetTabular::ShowInsetCursor(BufferView * bv)
754 if (!cursor_visible) {
755 LyXFont font; // = GetFont(par, cursor.pos);
757 int asc = lyxfont::maxAscent(font);
758 int desc = lyxfont::maxDescent(font);
759 bv->fitLockedInsetCursor(cursor.x, cursor.y, asc, desc);
760 bv->showLockedInsetCursor(cursor.x, cursor.y, asc, desc);
761 cursor_visible = true;
766 void InsetTabular::HideInsetCursor(BufferView * bv)
769 ToggleInsetCursor(bv);
773 void InsetTabular::setPos(Painter & pain, int x, int y) const
775 cursor.y = cursor.pos = actcell = actrow = actcol = 0;
776 int ly = tabular->GetDescentOfRow(actrow);
778 // first search the right row
779 while((ly < y) && (actrow < tabular->rows())) {
780 cursor.y += tabular->GetDescentOfRow(actrow) +
781 tabular->GetAscentOfRow(actrow+1) +
782 tabular->GetAdditionalHeight(tabular->GetCellNumber(actrow+1,
785 ly = cursor.y + tabular->GetDescentOfRow(actrow);
787 actcell = tabular->GetCellNumber(actrow, actcol);
789 // now search the right column
790 int lx = tabular->GetWidthOfColumn(actcell) -
791 tabular->GetAdditionalWidth(actcell);
792 for(; !tabular->IsLastCellInRow(actcell) && (lx < x);
793 ++actcell,lx += tabular->GetWidthOfColumn(actcell) +
794 tabular->GetAdditionalWidth(actcell-1));
795 cursor.pos = ((actcell+1) * 2) - 1;
797 if ((lx - (tabular->GetWidthOfColumn(actcell)/2)) < x) {
798 cursor.x = lx + top_x - 2;
801 cursor.x = lx - tabular->GetWidthOfColumn(actcell) + top_x + 2;
806 int InsetTabular::getCellXPos(int cell) const
810 for(c=cell;!tabular->IsFirstCellInRow(c);--c)
812 int lx = tabular->GetWidthOfColumn(cell);
813 for(; (c < cell); ++c) {
814 lx += tabular->GetWidthOfColumn(c);
816 return (lx - tabular->GetWidthOfColumn(cell) + top_x +
817 ADD_TO_TABULAR_WIDTH);
820 void InsetTabular::resetPos(Painter & pain) const
824 actcol = tabular->column_of_cell(actcell);
827 actrow = cursor.y = 0;
828 for(; (cell<actcell) && !tabular->IsLastRow(cell); ++cell) {
829 if (tabular->IsLastCellInRow(cell)) {
830 cursor.y += tabular->GetDescentOfRow(actrow) +
831 tabular->GetAscentOfRow(actrow+1) +
832 tabular->GetAdditionalHeight(cell+1);
836 cursor.x = getCellXPos(actcell) + 2;
837 if (cursor.pos % 2) {
838 LyXFont font(LyXFont::ALL_SANE);
839 cursor.x += tabular->GetCellInset(actcell)->width(pain,font) +
840 tabular->GetBeginningOfTextInCell(actcell);
842 if ((!the_locking_inset ||
843 !the_locking_inset->GetFirstLockingInsetOfType(TABULAR_CODE)) &&
844 (actcell != oldcell)) {
845 UpdateLayoutTabular(true, const_cast<InsetTabular *>(this));
851 bool InsetTabular::SetCellDimensions(Painter & pain, int cell, int row)
853 InsetText * inset = tabular->GetCellInset(cell);
854 LyXFont font(LyXFont::ALL_SANE);
855 int asc = inset->ascent(pain, font) + ADD_TO_HEIGHT;
856 int desc = inset->descent(pain, font) + ADD_TO_HEIGHT;
857 int maxAsc = tabular->GetAscentOfRow(row);
858 int maxDesc = tabular->GetDescentOfRow(row);
859 bool ret = tabular->SetWidthOfCell(cell, inset->width(pain, font));
863 tabular->SetAscentOfRow(row, asc);
865 if (maxDesc < desc) {
867 tabular->SetDescentOfRow(row, desc);
873 UpdatableInset::RESULT InsetTabular::moveRight(BufferView * bv, bool lock)
875 if (cursor.pos % 2) { // behind the inset
877 if (actcell >= tabular->GetNumberOfCells())
881 if (ActivateCellInset(bv))
883 } else { // before the inset
886 resetPos(bv->painter());
887 return DISPATCHED_NOUPDATE;
891 UpdatableInset::RESULT InsetTabular::moveLeft(BufferView * bv, bool lock)
896 if (cursor.pos % 2) { // behind the inset
898 } else if (lock) { // behind the inset
899 if (ActivateCellInset(bv, 0, 0, 0, true))
902 resetPos(bv->painter());
903 return DISPATCHED_NOUPDATE;
907 UpdatableInset::RESULT InsetTabular::moveUp(BufferView * bv)
910 actcell = tabular->GetCellAbove(actcell);
911 if (actcell == ocell) // we moved out of the inset
913 resetPos(bv->painter());
914 return DISPATCHED_NOUPDATE;
918 UpdatableInset::RESULT InsetTabular::moveDown(BufferView * bv)
921 actcell = tabular->GetCellBelow(actcell);
922 if (actcell == ocell) // we moved out of the inset
924 resetPos(bv->painter());
925 return DISPATCHED_NOUPDATE;
929 bool InsetTabular::moveNextCell(BufferView * bv)
931 if (tabular->IsLastCell(actcell))
935 if (!cellstart(cursor.pos))
937 resetPos(bv->painter());
942 bool InsetTabular::movePrevCell(BufferView * bv)
944 if (!actcell) // first cell
948 if (cellstart(cursor.pos))
950 resetPos(bv->painter());
955 bool InsetTabular::Delete()
961 void InsetTabular::SetFont(BufferView *, LyXFont const &, bool)
966 void InsetTabular::TabularFeatures(BufferView * bv, int feature, string val)
973 setAlign = LYX_ALIGN_LEFT,
979 case LyXTabular::ALIGN_LEFT:
980 setAlign=LYX_ALIGN_LEFT;
982 case LyXTabular::ALIGN_RIGHT:
983 setAlign=LYX_ALIGN_RIGHT;
985 case LyXTabular::ALIGN_CENTER:
986 setAlign=LYX_ALIGN_CENTER;
991 if (hasSelection()) {
992 if (sel_cell_start > sel_cell_end) {
993 sel_start = sel_cell_end;
994 sel_end = sel_cell_start;
996 sel_start = sel_cell_start;
997 sel_end = sel_cell_end;
1000 sel_start = sel_end = actcell;
1002 case LyXTabular::SET_PWIDTH:
1004 bool update = (tabular->GetPWidth(actcell) != val);
1005 tabular->SetPWidth(actcell,val);
1007 UpdateLocal(bv, true);
1010 case LyXTabular::SET_SPECIAL_COLUMN:
1011 case LyXTabular::SET_SPECIAL_MULTI:
1012 tabular->SetAlignSpecial(actcell,val,feature);
1014 case LyXTabular::APPEND_ROW:
1016 // append the row into the tabular
1017 tabular->AppendRow(actcell);
1018 UpdateLocal(bv, true);
1021 case LyXTabular::APPEND_COLUMN:
1023 // append the column into the tabular
1024 tabular->AppendColumn(actcell);
1025 UpdateLocal(bv, true);
1028 case LyXTabular::DELETE_ROW:
1030 UpdateLocal(bv, true);
1032 case LyXTabular::DELETE_COLUMN:
1034 /* delete the column from the tabular */
1035 tabular->DeleteColumn(actcell);
1036 UpdateLocal(bv, true);
1039 case LyXTabular::TOGGLE_LINE_TOP:
1040 lineSet = !tabular->TopLine(actcell);
1041 for(i=sel_start; i<=sel_end; ++i)
1042 tabular->SetTopLine(i,lineSet);
1043 UpdateLocal(bv, true);
1046 case LyXTabular::TOGGLE_LINE_BOTTOM:
1047 lineSet = !tabular->BottomLine(actcell);
1048 for(i=sel_start; i<=sel_end; ++i)
1049 tabular->SetBottomLine(i,lineSet);
1050 UpdateLocal(bv, true);
1053 case LyXTabular::TOGGLE_LINE_LEFT:
1054 lineSet = !tabular->LeftLine(actcell);
1055 for(i=sel_start; i<=sel_end; ++i)
1056 tabular->SetLeftLine(i,lineSet);
1057 UpdateLocal(bv, true);
1060 case LyXTabular::TOGGLE_LINE_RIGHT:
1061 lineSet = !tabular->RightLine(actcell);
1062 for(i=sel_start; i<=sel_end; ++i)
1063 tabular->SetRightLine(i,lineSet);
1064 UpdateLocal(bv, true);
1066 case LyXTabular::ALIGN_LEFT:
1067 case LyXTabular::ALIGN_RIGHT:
1068 case LyXTabular::ALIGN_CENTER:
1069 for(i=sel_start; i<=sel_end; ++i)
1070 tabular->SetAlignment(i,setAlign);
1071 UpdateLocal(bv, true);
1073 case LyXTabular::MULTICOLUMN:
1075 if (tabular->row_of_cell(sel_start) !=
1076 tabular->row_of_cell(sel_end)) {
1077 WriteAlert(_("Impossible Operation!"),
1078 _("Multicolumns can only be horizontally."),
1082 // just multicol for one Single Cell
1083 if (!hasSelection()) {
1084 // check wether we are completly in a multicol
1085 if (tabular->IsMultiColumn(actcell)) {
1086 tabular->UnsetMultiColumn(actcell);
1087 UpdateLocal(bv, true);
1089 tabular->SetMultiColumn(actcell, 1);
1090 UpdateLocal(bv, false);
1094 // we have a selection so this means we just add all this
1095 // cells to form a multicolumn cell
1099 if (sel_start > sel_end) {
1103 s_start = sel_start;
1106 tabular->SetMultiColumn(s_start, s_end);
1107 cursor.pos = s_start;
1108 sel_cell_end = sel_cell_start;
1109 UpdateLocal(bv, true);
1112 case LyXTabular::SET_ALL_LINES:
1114 case LyXTabular::UNSET_ALL_LINES:
1115 for(i=sel_start; i<=sel_end; ++i)
1116 tabular->SetAllLines(i, setLines);
1117 UpdateLocal(bv, true);
1119 case LyXTabular::SET_LONGTABULAR:
1120 tabular->SetLongTabular(true);
1121 UpdateLocal(bv, true); // because this toggles displayed
1123 case LyXTabular::UNSET_LONGTABULAR:
1124 tabular->SetLongTabular(false);
1125 UpdateLocal(bv, true); // because this toggles displayed
1127 case LyXTabular::SET_ROTATE_TABULAR:
1128 tabular->SetRotateTabular(true);
1130 case LyXTabular::UNSET_ROTATE_TABULAR:
1131 tabular->SetRotateTabular(false);
1133 case LyXTabular::SET_ROTATE_CELL:
1134 for(i=sel_start; i<=sel_end; ++i)
1135 tabular->SetRotateCell(i,true);
1137 case LyXTabular::UNSET_ROTATE_CELL:
1138 for(i=sel_start; i<=sel_end; ++i)
1139 tabular->SetRotateCell(i,false);
1141 case LyXTabular::SET_LINEBREAKS:
1142 what = !tabular->GetLinebreaks(actcell);
1143 for(i=sel_start; i<=sel_end; ++i)
1144 tabular->SetLinebreaks(i,what);
1146 case LyXTabular::SET_LTFIRSTHEAD:
1147 tabular->SetLTHead(actcell,true);
1149 case LyXTabular::SET_LTHEAD:
1150 tabular->SetLTHead(actcell,false);
1152 case LyXTabular::SET_LTFOOT:
1153 tabular->SetLTFoot(actcell,false);
1155 case LyXTabular::SET_LTLASTFOOT:
1156 tabular->SetLTFoot(actcell,true);
1158 case LyXTabular::SET_LTNEWPAGE:
1159 what = !tabular->GetLTNewPage(actcell);
1160 tabular->SetLTNewPage(actcell,what);
1165 void InsetTabular::RemoveTabularRow()
1169 bool InsetTabular::ActivateCellInset(BufferView * bv, int x, int y, int button,
1172 // the cursor.pos has to be before the inset so if it isn't now just
1173 // reset the curor pos first!
1174 if (cursor.pos % 2) { // behind the inset
1176 resetPos(bv->painter());
1178 UpdatableInset * inset =
1179 static_cast<UpdatableInset*>(tabular->GetCellInset(actcell));
1180 LyXFont font(LyXFont::ALL_SANE);
1182 x = inset->x() + inset->width(bv->painter(), font);
1183 y = inset->descent(bv->painter(), font);
1185 inset_x = cursor.x - top_x + tabular->GetBeginningOfTextInCell(actcell);
1187 inset->Edit(bv, x-inset_x, y-inset_y, button);
1188 if (!the_locking_inset)
1190 UpdateLocal(bv, true);
1194 bool InsetTabular::InsetHit(BufferView * bv, int x, int ) const
1196 InsetText * inset = tabular->GetCellInset(actcell);
1199 if (cursor.pos % 2) { // behind the inset
1200 return (((x+top_x) < cursor.x) &&
1201 ((x+top_x) > (cursor.x - inset->width(bv->painter(),
1202 LyXFont(LyXFont::ALL_SANE)))));
1204 int x2 = cursor.x + tabular->GetBeginningOfTextInCell(actcell);
1205 return ((x1 > x2) &&
1206 (x1 < (x2 + inset->width(bv->painter(),
1207 LyXFont(LyXFont::ALL_SANE)))));
1211 // This returns paperWidth() if the cell-width is unlimited or the width
1212 // in pixels if we have a pwidth for this cell.
1213 int InsetTabular::GetMaxWidthOfCell(Painter & pain, int cell) const
1217 if ((w=tabular->GetPWidth(cell)).empty())
1218 return pain.paperWidth();
1219 return VSpace(w).inPixels( 0, 0);
1222 int InsetTabular::getMaxWidth(Painter & pain,
1223 UpdatableInset const * inset) const
1226 int n = tabular->GetNumberOfCells();
1227 for(cell=0; cell < n; ++cell) {
1228 if (tabular->GetCellInset(cell) == inset)
1232 return pain.paperWidth();
1233 int w = GetMaxWidthOfCell(pain, cell);
1234 // this because text insets remove the xpos from the maxwidth because
1235 // otherwise the would not break good!!!
1236 // w += getCellXPos(cell) + tabular->GetBeginningOfTextInCell(cell);
1241 void InsetTabular::recomputeTextInsets(Painter & pain, const LyXFont & font) const
1247 for(int j= 0; j < tabular->columns(); ++j) {
1248 for(int i = 0; i < tabular->rows(); ++i) {
1249 if (tabular->IsPartOfMultiColumn(i,j))
1251 cell = tabular->GetCellNumber(i,j);
1252 inset = tabular->GetCellInset(cell);
1253 inset->computeTextRows(pain);
1254 tabular->SetWidthOfCell(cell, inset->width(pain, font));
1256 cell = tabular->GetCellNumber(0, j);
1257 cx += tabular->GetWidthOfColumn(cell);