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 *);
37 const int ADD_TO_HEIGHT = 2;
38 const int ADD_TO_TABULAR_WIDTH = 2;
46 InsetTabular::InsetTabular(Buffer * buf, int rows, int columns)
52 buffer = buf; // set this first!!!
53 tabular = new LyXTabular(this, rows,columns);
54 // for now make it always display as display() inset
56 the_locking_inset = 0;
57 cursor_visible = false;
59 actcell = cursor.pos = sel_pos_start = sel_pos_end = 0;
65 InsetTabular::InsetTabular(InsetTabular const & tab, Buffer * buf)
67 buffer = buf; // set this first
68 tabular = new LyXTabular(this, *(tab.tabular));
69 the_locking_inset = 0;
70 cursor_visible = false;
72 actcell = cursor.pos = sel_pos_start = sel_pos_end = 0;
78 InsetTabular::~InsetTabular()
84 Inset * InsetTabular::Clone() const
86 InsetTabular * t = new InsetTabular(*this, buffer);
91 void InsetTabular::Write(ostream & os) const
93 os << " Tabular" << endl;
98 void InsetTabular::Read(LyXLex & lex)
100 // bool old_format = (lex.GetString() == "\\LyXTable");
105 tabular = new LyXTabular(this, lex);
108 token = lex.GetString();
109 while (lex.IsOK() && (token != "\\end_inset")) {
111 token = lex.GetString();
113 if (token != "\\end_inset") {
114 lex.printError("Missing \\end_inset at this point. "
121 int InsetTabular::ascent(Painter & pain, LyXFont const & font) const
124 calculate_width_of_cells(pain, font);
127 return tabular->GetAscentOfRow(0);
131 int InsetTabular::descent(Painter & pain, LyXFont const & font) const
134 calculate_width_of_cells(pain, font);
137 return tabular->GetHeightOfTabular() - tabular->GetAscentOfRow(0);
141 int InsetTabular::width(Painter & pain, LyXFont const & font) const
144 calculate_width_of_cells(pain, font);
147 return tabular->GetWidthOfTabular() + (2 * ADD_TO_TABULAR_WIDTH);
151 void InsetTabular::draw(Painter & pain, const LyXFont & font, int baseline,
159 UpdatableInset::draw(pain,font,baseline,x);
160 if (init_inset || (top_x != int(x)) || (top_baseline != baseline)) {
164 top_baseline = baseline;
166 recomputeTextInsets(pain, font);
167 calculate_width_of_cells(pain, font);
171 for(i=0;i<tabular->rows();++i) {
173 for(j=0;j<tabular->columns();++j) {
174 if (tabular->IsPartOfMultiColumn(i,j))
176 cx = nx + tabular->GetBeginningOfTextInCell(cell);
177 tabular->GetCellInset(cell)->draw(pain, font, baseline, cx);
178 DrawCellLines(pain, nx, baseline, i, cell);
179 nx += tabular->GetWidthOfColumn(cell);
182 baseline += tabular->GetDescentOfRow(i) + tabular->GetAscentOfRow(i+1)
183 + tabular->GetAdditionalHeight(cell+1);
185 x += width(pain, font);
189 void InsetTabular::DrawCellLines(Painter & pain, int x, int baseline,
190 int row, int cell) const
192 int x2 = x + tabular->GetWidthOfColumn(cell);
195 if (!tabular->TopAlreadyDrawed(cell)) {
196 on_off = !tabular->TopLine(cell);
197 pain.line(x, baseline - tabular->GetAscentOfRow(row),
198 x2, baseline - tabular->GetAscentOfRow(row),
199 on_off ? LColor::tabularonoffline:LColor::tabularline,
200 on_off ? Painter::line_onoffdash:Painter::line_solid);
202 on_off = !tabular->BottomLine(cell);
203 pain.line(x,baseline + tabular->GetDescentOfRow(row),
204 x2, baseline + tabular->GetDescentOfRow(row),
205 on_off ? LColor::tabularonoffline:LColor::tabularline,
206 on_off ? Painter::line_onoffdash:Painter::line_solid);
207 if (!tabular->LeftAlreadyDrawed(cell)) {
208 on_off = !tabular->LeftLine(cell);
209 pain.line(x, baseline - tabular->GetAscentOfRow(row),
210 x, baseline + tabular->GetDescentOfRow(row),
211 on_off ? LColor::tabularonoffline:LColor::tabularline,
212 on_off ? Painter::line_onoffdash:Painter::line_solid);
214 on_off = !tabular->RightLine(cell);
215 pain.line(x2 - tabular->GetAdditionalWidth(cell),
216 baseline - tabular->GetAscentOfRow(row),
217 x2 - tabular->GetAdditionalWidth(cell),
218 baseline + tabular->GetDescentOfRow(row),
219 on_off ? LColor::tabularonoffline:LColor::tabularline,
220 on_off ? Painter::line_onoffdash:Painter::line_solid);
224 char const * InsetTabular::EditMessage() const
226 return _("Opened Tabular Inset");
230 void InsetTabular::Edit(BufferView * bv, int x, int y, unsigned int button)
232 UpdatableInset::Edit(bv, x, y, button);
234 if (!bv->lockInset(this)) {
235 lyxerr[Debug::INSETS] << "InsetTabular::Cannot lock inset" << endl;
238 the_locking_inset = 0;
239 sel_pos_start = sel_pos_end = inset_pos = inset_x = inset_y = 0;
240 setPos(bv->painter(), x, y);
241 sel_pos_start = sel_pos_end = cursor.pos;
242 bv->text->FinishUndo();
243 if (InsetHit(bv, x, y)) {
244 ActivateCellInset(bv, x, y, button);
246 UpdateLocal(bv, true);
247 // bv->getOwner()->getPopups().updateFormTabular();
251 void InsetTabular::InsetUnlock(BufferView * bv)
253 if (the_locking_inset) {
254 the_locking_inset->InsetUnlock(bv);
255 the_locking_inset = 0;
258 if (hasCharSelection()) {
259 sel_pos_start = sel_pos_end = cursor.pos;
260 UpdateLocal(bv, false);
262 sel_pos_start = sel_pos_end = cursor.pos;
263 no_selection = false;
266 void InsetTabular::UpdateLocal(BufferView * bv, bool flag)
269 calculate_width_of_cells(bv->painter(), LyXFont(LyXFont::ALL_SANE));
270 bv->updateInset(this, flag);
272 resetPos(bv->painter());
275 bool InsetTabular::LockInsetInInset(BufferView * bv, UpdatableInset * inset)
277 lyxerr[Debug::INSETS] << "InsetTabular::LockInsetInInset(" <<inset<< "): ";
280 if (inset == tabular->GetCellInset(actcell)) {
281 lyxerr[Debug::INSETS] << "OK" << endl;
282 the_locking_inset = tabular->GetCellInset(actcell);
283 resetPos(bv->painter());
284 inset_x = cursor.x - top_x + tabular->GetBeginningOfTextInCell(actcell);
286 inset_pos = cursor.pos;
288 } else if (the_locking_inset && (the_locking_inset == inset)) {
289 if (cursor.pos == inset_pos) {
290 lyxerr[Debug::INSETS] << "OK" << endl;
291 resetPos(bv->painter());
292 inset_x = cursor.x - top_x + tabular->GetBeginningOfTextInCell(actcell);
295 lyxerr[Debug::INSETS] << "cursor.pos != inset_pos" << endl;
297 } else if (the_locking_inset) {
298 lyxerr[Debug::INSETS] << "MAYBE" << endl;
299 return the_locking_inset->LockInsetInInset(bv, inset);
301 lyxerr[Debug::INSETS] << "NOT OK" << endl;
305 bool InsetTabular::UnlockInsetInInset(BufferView * bv, UpdatableInset * inset,
308 if (!the_locking_inset)
310 if (the_locking_inset == inset) {
311 the_locking_inset->InsetUnlock(bv);
312 the_locking_inset = 0;
314 moveRight(bv, false);
317 return the_locking_inset->UnlockInsetInInset(bv, inset, lr);
320 bool InsetTabular::UpdateInsetInInset(BufferView * bv, Inset * inset)
322 if (!the_locking_inset)
324 if (the_locking_inset != inset)
325 return the_locking_inset->UpdateInsetInInset(bv, inset);
331 int InsetTabular::InsetInInsetY()
333 if (!the_locking_inset)
336 return (inset_y + the_locking_inset->InsetInInsetY());
340 UpdatableInset * InsetTabular::GetLockingInset()
342 return the_locking_inset ? the_locking_inset->GetLockingInset() : this;
346 UpdatableInset * InsetTabular::GetFirstLockingInsetOfType(Inset::Code c)
350 if (the_locking_inset)
351 return the_locking_inset->GetFirstLockingInsetOfType(c);
356 bool InsetTabular::InsertInset(BufferView * bv, Inset * inset)
358 if (the_locking_inset)
359 return the_locking_inset->InsertInset(bv, inset);
364 void InsetTabular::InsetButtonRelease(BufferView * bv,
365 int x, int y, int button)
368 if (the_locking_inset) {
370 if ((i=the_locking_inset->GetFirstLockingInsetOfType(TABULAR_CODE))) {
371 i->InsetButtonRelease(bv, x, y, button);
375 MenuLayoutTabular(true, this);
378 if (the_locking_inset) {
379 the_locking_inset->InsetButtonRelease(bv, x-inset_x, y-inset_y,button);
382 no_selection = false;
386 void InsetTabular::InsetButtonPress(BufferView * bv, int x, int y, int button)
388 if (hasCharSelection()) {
389 sel_pos_start = sel_pos_end = 0;
390 UpdateLocal(bv, false);
392 no_selection = false;
394 int oldcell = actcell;
396 setPos(bv->painter(), x, y);
398 bool inset_hit = InsetHit(bv, x, y);
400 if ((oldcell == actcell) && the_locking_inset && inset_hit) {
401 the_locking_inset->InsetButtonPress(bv, x-inset_x, y-inset_y, button);
403 } else if (the_locking_inset) {
404 the_locking_inset->InsetUnlock(bv);
406 the_locking_inset = 0;
407 sel_pos_start = sel_pos_end = cursor.pos;
408 sel_cell_start = sel_cell_end = actcell;
409 if (inset_hit && bv->the_locking_inset) {
410 ActivateCellInset(bv, x, y, button);
411 the_locking_inset->InsetButtonPress(bv, x-inset_x, y-inset_y, button);
416 bview->getOwner()->getPopups().showFormTabular();
417 else if (oldcell != actcell)
418 bview->getOwner()->getPopups().updateFormTabular();
423 void InsetTabular::InsetMotionNotify(BufferView * bv, int x, int y, int button)
425 if (the_locking_inset) {
426 the_locking_inset->InsetMotionNotify(bv, x - inset_x,
427 y - inset_y, button);
431 // int oldcell = actcell,
432 int old = sel_pos_end;
434 setPos(bv->painter(), x, y);
435 sel_pos_end = cursor.pos;
436 sel_cell_end = actcell;
437 if (old != sel_pos_end)
438 UpdateLocal(bv, false);
440 if (oldcell != actcell)
441 bview->getOwner()->getPopups().updateFormTabular();
444 no_selection = false;
448 void InsetTabular::InsetKeyPress(XKeyEvent * xke)
450 if (the_locking_inset) {
451 the_locking_inset->InsetKeyPress(xke);
457 UpdatableInset::RESULT InsetTabular::LocalDispatch(BufferView * bv, int action,
460 UpdatableInset::RESULT
463 no_selection = false;
464 if (((result=UpdatableInset::LocalDispatch(bv, action, arg)) == DISPATCHED)
465 || (result == DISPATCHED_NOUPDATE)) {
467 resetPos(bv->painter());
472 if ((action < 0) && arg.empty())
475 if ((action != LFUN_DOWN) && (action != LFUN_UP) &&
476 (action != LFUN_DOWNSEL) && (action != LFUN_UPSEL))
478 if (the_locking_inset) {
479 result=the_locking_inset->LocalDispatch(bv, action, arg);
480 if (result == DISPATCHED_NOUPDATE)
482 else if (result == DISPATCHED) {
483 bool upd = SetCellDimensions(bv->painter(), actcell, actrow);
484 the_locking_inset->ToggleInsetCursor(bv);
485 UpdateLocal(bv, upd);
486 the_locking_inset->ToggleInsetCursor(bv);
488 } else if (result == FINISHED) {
489 if ((action == LFUN_RIGHT) || (action == -1)) {
490 cursor.pos = inset_pos + 1;
491 resetPos(bv->painter());
501 // Normal chars not handled here
504 // --- Cursor Movements ---------------------------------------------
506 moveRight(bv, false);
507 sel_pos_end = cursor.pos;
508 UpdateLocal(bv, false);
511 result = moveRight(bv);
512 if (hasCharSelection()) {
513 sel_pos_start = sel_pos_end = cursor.pos;
514 UpdateLocal(bv, false);
516 sel_pos_start = sel_pos_end = cursor.pos;
520 sel_pos_end = cursor.pos;
521 UpdateLocal(bv, false);
524 result = moveLeft(bv);
525 if (hasCharSelection()) {
526 sel_pos_start = sel_pos_end = cursor.pos;
527 UpdateLocal(bv, false);
529 sel_pos_start = sel_pos_end = cursor.pos;
533 sel_pos_end = cursor.pos;
534 UpdateLocal(bv, false);
538 if (hasCharSelection()) {
539 sel_pos_start = sel_pos_end = cursor.pos;
540 UpdateLocal(bv, false);
542 sel_pos_start = sel_pos_end = cursor.pos;
546 sel_pos_end = cursor.pos;
547 UpdateLocal(bv, false);
551 if (hasCharSelection()) {
552 sel_pos_start = sel_pos_end = cursor.pos;
553 UpdateLocal(bv, false);
555 sel_pos_start = sel_pos_end = cursor.pos;
566 if (hasCharSelection()) {
567 sel_pos_start = sel_pos_end = cursor.pos;
568 UpdateLocal(bv, false);
570 sel_pos_start = sel_pos_end = cursor.pos;
573 case LFUN_LAYOUT_TABLE:
575 int flag = (arg == "true");
576 MenuLayoutTabular(flag, this);
580 result = UNDISPATCHED;
583 if (result!=FINISHED) {
584 if (!the_locking_inset) {
586 if (oldcell != actcell)
587 bview->getOwner()->getPopups().updateFormTabular();
592 bv->unlockInset(this);
597 int InsetTabular::Latex(ostream & os, bool fragile, bool fp) const
599 return tabular->Latex(os, fragile, fp);
603 int InsetTabular::Ascii(ostream &) const
608 int InsetTabular::Linuxdoc(ostream &) const
614 int InsetTabular::DocBook(ostream &) const
620 void InsetTabular::Validate(LaTeXFeatures & features) const
622 if (tabular->IsLongTabular())
623 features.longtable = true;
627 void InsetTabular::calculate_width_of_cells(Painter & pain,
628 LyXFont const & font) const
634 for(int i = 0; i < tabular->rows(); ++i) {
635 maxAsc = maxDesc = 0;
636 for(int j= 0; j < tabular->columns(); ++j) {
637 if (tabular->IsPartOfMultiColumn(i,j))
640 inset = tabular->GetCellInset(cell);
641 maxAsc = max(maxAsc, inset->ascent(pain, font));
642 maxDesc = max(maxDesc, inset->descent(pain, font));
643 tabular->SetWidthOfCell(cell, inset->width(pain, font));
645 tabular->SetAscentOfRow(i, maxAsc + ADD_TO_HEIGHT);
646 tabular->SetDescentOfRow(i, maxDesc + ADD_TO_HEIGHT);
651 void InsetTabular::GetCursorPos(int & x, int & y) const
658 void InsetTabular::ToggleInsetCursor(BufferView * bv)
660 if (the_locking_inset) {
661 the_locking_inset->ToggleInsetCursor(bv);
665 LyXFont font; // = the_locking_inset->GetFont(par, cursor.pos);
667 int asc = lyxfont::maxAscent(font);
668 int desc = lyxfont::maxDescent(font);
671 bv->hideLockedInsetCursor();
673 bv->showLockedInsetCursor(cursor.x, cursor.y, asc, desc);
674 cursor_visible = !cursor_visible;
678 void InsetTabular::ShowInsetCursor(BufferView * bv)
680 if (!cursor_visible) {
681 LyXFont font; // = GetFont(par, cursor.pos);
683 int asc = lyxfont::maxAscent(font);
684 int desc = lyxfont::maxDescent(font);
685 bv->fitLockedInsetCursor(cursor.x, cursor.y, asc, desc);
686 bv->showLockedInsetCursor(cursor.x, cursor.y, asc, desc);
687 cursor_visible = true;
692 void InsetTabular::HideInsetCursor(BufferView * bv)
695 ToggleInsetCursor(bv);
699 void InsetTabular::setPos(Painter & pain, int x, int y) const
701 cursor.y = cursor.pos = actcell = actrow = actcol = 0;
702 int ly = tabular->GetDescentOfRow(actrow);
704 // first search the right row
705 while((ly < y) && (actrow < tabular->rows())) {
706 cursor.y += tabular->GetDescentOfRow(actrow) +
707 tabular->GetAscentOfRow(actrow+1) +
708 tabular->GetAdditionalHeight(tabular->GetCellNumber(actrow+1,
711 ly = cursor.y + tabular->GetDescentOfRow(actrow);
713 actcell = tabular->GetCellNumber(actrow, actcol);
715 // now search the right column
716 int lx = tabular->GetWidthOfColumn(actcell) -
717 tabular->GetAdditionalWidth(actcell);
718 for(; !tabular->IsLastCellInRow(actcell) && (lx < x);
719 ++actcell,lx += tabular->GetWidthOfColumn(actcell) +
720 tabular->GetAdditionalWidth(actcell-1));
721 cursor.pos = ((actcell+1) * 2) - 1;
723 if ((lx - (tabular->GetWidthOfColumn(actcell)/2)) < x) {
724 cursor.x = lx + top_x - 2;
727 cursor.x = lx - tabular->GetWidthOfColumn(actcell) + top_x + 2;
732 int InsetTabular::getCellXPos(int cell) const
736 for(c=cell;!tabular->IsFirstCellInRow(c);--c)
738 int lx = tabular->GetWidthOfColumn(cell);
739 for(; (c < cell); ++c) {
740 lx += tabular->GetWidthOfColumn(c);
742 return (lx - tabular->GetWidthOfColumn(cell) + top_x);
745 void InsetTabular::resetPos(Painter & pain) const
747 actcol = tabular->column_of_cell(actcell);
750 actrow = cursor.y = 0;
751 for(; (cell<actcell) && !tabular->IsLastRow(cell); ++cell) {
752 if (tabular->IsLastCellInRow(cell)) {
753 cursor.y += tabular->GetDescentOfRow(actrow) +
754 tabular->GetAscentOfRow(actrow+1) +
755 tabular->GetAdditionalHeight(cell+1);
759 cursor.x = getCellXPos(actcell) + 2;
760 if (cursor.pos % 2) {
761 LyXFont font(LyXFont::ALL_SANE);
762 cursor.x += tabular->GetCellInset(actcell)->width(pain,font) +
763 tabular->GetBeginningOfTextInCell(actcell);
768 bool InsetTabular::SetCellDimensions(Painter & pain, int cell, int row)
770 InsetText * inset = tabular->GetCellInset(cell);
771 LyXFont font(LyXFont::ALL_SANE);
772 int asc = inset->ascent(pain, font) + ADD_TO_HEIGHT;
773 int desc = inset->descent(pain, font) + ADD_TO_HEIGHT;
774 int maxAsc = tabular->GetAscentOfRow(row);
775 int maxDesc = tabular->GetDescentOfRow(row);
776 bool ret = tabular->SetWidthOfCell(cell, inset->width(pain, font));
780 tabular->SetAscentOfRow(row, asc);
782 if (maxDesc < desc) {
784 tabular->SetDescentOfRow(row, desc);
790 UpdatableInset::RESULT InsetTabular::moveRight(BufferView * bv, bool lock)
792 if (cursor.pos % 2) { // behind the inset
794 if (actcell >= tabular->GetNumberOfCells())
798 if (ActivateCellInset(bv))
800 } else { // before the inset
803 resetPos(bv->painter());
804 return DISPATCHED_NOUPDATE;
808 UpdatableInset::RESULT InsetTabular::moveLeft(BufferView * bv, bool lock)
813 if (cursor.pos % 2) { // behind the inset
815 } else if (lock) { // behind the inset
816 if (ActivateCellInset(bv, 0, 0, 0, true))
819 resetPos(bv->painter());
820 return DISPATCHED_NOUPDATE;
824 UpdatableInset::RESULT InsetTabular::moveUp()
826 return DISPATCHED_NOUPDATE;
830 UpdatableInset::RESULT InsetTabular::moveDown()
832 return DISPATCHED_NOUPDATE;
836 bool InsetTabular::moveNextCell()
842 bool InsetTabular::movePrevCell()
848 bool InsetTabular::Delete()
854 void InsetTabular::SetFont(BufferView *, LyXFont const &, bool)
859 void InsetTabular::TabularFeatures(BufferView * bv, int feature, string val)
866 setAlign = LYX_ALIGN_LEFT,
872 case LyXTabular::ALIGN_LEFT:
873 setAlign=LYX_ALIGN_LEFT;
875 case LyXTabular::ALIGN_RIGHT:
876 setAlign=LYX_ALIGN_RIGHT;
878 case LyXTabular::ALIGN_CENTER:
879 setAlign=LYX_ALIGN_CENTER;
884 if (hasCellSelection()) {
885 if (sel_cell_start > sel_cell_end) {
886 sel_pos_start = sel_cell_end;
887 sel_pos_end = sel_cell_start;
889 sel_pos_start = sel_cell_start;
890 sel_pos_end = sel_cell_end;
893 sel_pos_start = sel_pos_end = actcell;
895 case LyXTabular::SET_PWIDTH:
897 bool update = tabular->GetPWidth(actcell).empty();
898 tabular->SetPWidth(actcell,val);
899 if (tabular->GetPWidth(actcell).empty() != update)
900 UpdateLocal(bv, true);
903 case LyXTabular::SET_SPECIAL_COLUMN:
904 case LyXTabular::SET_SPECIAL_MULTI:
905 tabular->SetAlignSpecial(actcell,val,feature);
907 case LyXTabular::APPEND_ROW:
909 // append the row into the tabular
910 tabular->AppendRow(actcell);
911 UpdateLocal(bv, true);
914 case LyXTabular::APPEND_COLUMN:
916 // append the column into the tabular
917 tabular->AppendColumn(actcell);
918 UpdateLocal(bv, true);
921 case LyXTabular::DELETE_ROW:
923 UpdateLocal(bv, true);
925 case LyXTabular::DELETE_COLUMN:
927 /* delete the column from the tabular */
928 tabular->DeleteColumn(actcell);
929 UpdateLocal(bv, true);
932 case LyXTabular::TOGGLE_LINE_TOP:
933 lineSet = !tabular->TopLine(actcell);
934 for(i=sel_pos_start; i<=sel_pos_end; ++i)
935 tabular->SetTopLine(i,lineSet);
936 UpdateLocal(bv, true);
939 case LyXTabular::TOGGLE_LINE_BOTTOM:
940 lineSet = !tabular->BottomLine(actcell);
941 for(i=sel_pos_start; i<=sel_pos_end; ++i)
942 tabular->SetBottomLine(i,lineSet);
943 UpdateLocal(bv, true);
946 case LyXTabular::TOGGLE_LINE_LEFT:
947 lineSet = !tabular->LeftLine(actcell);
948 for(i=sel_pos_start; i<=sel_pos_end; ++i)
949 tabular->SetLeftLine(i,lineSet);
950 UpdateLocal(bv, true);
953 case LyXTabular::TOGGLE_LINE_RIGHT:
954 lineSet = !tabular->RightLine(actcell);
955 for(i=sel_pos_start; i<=sel_pos_end; ++i)
956 tabular->SetRightLine(i,lineSet);
957 UpdateLocal(bv, true);
959 case LyXTabular::ALIGN_LEFT:
960 case LyXTabular::ALIGN_RIGHT:
961 case LyXTabular::ALIGN_CENTER:
962 for(i=sel_pos_start; i<=sel_pos_end; ++i)
963 tabular->SetAlignment(i,setAlign);
964 UpdateLocal(bv, true);
966 case LyXTabular::MULTICOLUMN:
968 if (tabular->row_of_cell(sel_pos_start) !=
969 tabular->row_of_cell(sel_pos_end)) {
970 WriteAlert(_("Impossible Operation!"),
971 _("Multicolumns can only be horizontally."),
975 // just multicol for one Single Cell
976 if (!hasCellSelection()) {
977 // check wether we are completly in a multicol
978 if (tabular->IsMultiColumn(actcell)) {
979 tabular->UnsetMultiColumn(actcell);
980 UpdateLocal(bv, true);
982 tabular->SetMultiColumn(actcell, 1);
983 UpdateLocal(bv, false);
987 // we have a selection so this means we just add all this
988 // cells to form a multicolumn cell
992 if (sel_pos_start > sel_pos_end) {
993 s_start = sel_pos_end;
994 s_end = sel_pos_start;
996 s_start = sel_pos_start;
999 tabular->SetMultiColumn(s_start, s_end);
1000 cursor.pos = s_start;
1001 sel_cell_end = sel_cell_start;
1002 UpdateLocal(bv, true);
1005 case LyXTabular::SET_ALL_LINES:
1007 case LyXTabular::UNSET_ALL_LINES:
1008 for(i=sel_pos_start; i<=sel_pos_end; ++i)
1009 tabular->SetAllLines(i, setLines);
1010 UpdateLocal(bv, true);
1012 case LyXTabular::SET_LONGTABULAR:
1013 tabular->SetLongTabular(true);
1014 UpdateLocal(bv, true); // because this toggles displayed
1016 case LyXTabular::UNSET_LONGTABULAR:
1017 tabular->SetLongTabular(false);
1018 UpdateLocal(bv, true); // because this toggles displayed
1020 case LyXTabular::SET_ROTATE_TABULAR:
1021 tabular->SetRotateTabular(true);
1023 case LyXTabular::UNSET_ROTATE_TABULAR:
1024 tabular->SetRotateTabular(false);
1026 case LyXTabular::SET_ROTATE_CELL:
1027 for(i=sel_pos_start; i<=sel_pos_end; ++i)
1028 tabular->SetRotateCell(i,true);
1030 case LyXTabular::UNSET_ROTATE_CELL:
1031 for(i=sel_pos_start; i<=sel_pos_end; ++i)
1032 tabular->SetRotateCell(i,false);
1034 case LyXTabular::SET_LINEBREAKS:
1035 what = !tabular->GetLinebreaks(actcell);
1036 for(i=sel_pos_start; i<=sel_pos_end; ++i)
1037 tabular->SetLinebreaks(i,what);
1039 case LyXTabular::SET_LTFIRSTHEAD:
1040 tabular->SetLTHead(actcell,true);
1042 case LyXTabular::SET_LTHEAD:
1043 tabular->SetLTHead(actcell,false);
1045 case LyXTabular::SET_LTFOOT:
1046 tabular->SetLTFoot(actcell,false);
1048 case LyXTabular::SET_LTLASTFOOT:
1049 tabular->SetLTFoot(actcell,true);
1051 case LyXTabular::SET_LTNEWPAGE:
1052 what = !tabular->GetLTNewPage(actcell);
1053 tabular->SetLTNewPage(actcell,what);
1058 void InsetTabular::RemoveTabularRow()
1062 bool InsetTabular::ActivateCellInset(BufferView * bv, int x, int y, int button,
1065 // the cursor.pos has to be before the inset so if it isn't now just
1066 // reset the curor pos first!
1067 if (cursor.pos % 2) { // behind the inset
1069 resetPos(bv->painter());
1071 UpdatableInset * inset =
1072 static_cast<UpdatableInset*>(tabular->GetCellInset(actcell));
1073 LyXFont font(LyXFont::ALL_SANE);
1075 x = inset->x() + inset->width(bv->painter(), font);
1076 y = inset->descent(bv->painter(), font);
1078 inset_x = cursor.x - top_x + tabular->GetBeginningOfTextInCell(actcell);
1080 inset->Edit(bv, x-inset_x, y-inset_y, button);
1081 if (!the_locking_inset)
1083 UpdateLocal(bv, true);
1087 bool InsetTabular::InsetHit(BufferView * bv, int x, int ) const
1089 InsetText * inset = tabular->GetCellInset(actcell);
1092 if (cursor.pos % 2) { // behind the inset
1093 return (((x+top_x) < cursor.x) &&
1094 ((x+top_x) > (cursor.x - inset->width(bv->painter(),
1095 LyXFont(LyXFont::ALL_SANE)))));
1097 int x2 = cursor.x + tabular->GetBeginningOfTextInCell(actcell);
1098 return ((x1 > x2) &&
1099 (x1 < (x2 + inset->width(bv->painter(),
1100 LyXFont(LyXFont::ALL_SANE)))));
1104 // This returns paperWidth() if the cell-width is unlimited or the width
1105 // in pixels if we have a pwidth for this cell.
1106 int InsetTabular::GetMaxWidthOfCell(Painter & pain, int cell) const
1110 if ((w=tabular->GetPWidth(cell)).empty())
1111 return pain.paperWidth();
1112 return VSpace(w).inPixels( 0, 0);
1115 int InsetTabular::getMaxWidth(Painter & pain,
1116 UpdatableInset const * inset) const
1119 int n = tabular->GetNumberOfCells();
1120 for(cell=0; cell < n; ++cell) {
1121 if (tabular->GetCellInset(cell) == inset)
1125 return pain.paperWidth();
1126 int w = GetMaxWidthOfCell(pain, cell);
1127 // this because text insets remove the xpos from the maxwidth because
1128 // otherwise the would not break good!!!
1129 // w += getCellXPos(cell) + tabular->GetBeginningOfTextInCell(cell);
1134 void InsetTabular::recomputeTextInsets(Painter & pain, const LyXFont & font) const
1140 for(int j= 0; j < tabular->columns(); ++j) {
1141 for(int i = 0; i < tabular->rows(); ++i) {
1142 if (tabular->IsPartOfMultiColumn(i,j))
1144 cell = tabular->GetCellNumber(i,j);
1145 inset = tabular->GetCellInset(cell);
1146 inset->computeTextRows(pain);
1147 tabular->SetWidthOfCell(cell, inset->width(pain, font));
1149 cell = tabular->GetCellNumber(0, j);
1150 cx += tabular->GetWidthOfColumn(cell);