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"
27 #include "LaTeXFeatures.h"
31 #include "lyx_gui_misc.h"
34 #include "insets/insettext.h"
35 #include "frontends/Dialogs.h"
39 const int ADD_TO_HEIGHT = 2;
40 const int ADD_TO_TABULAR_WIDTH = 2;
42 static LyXTabular * paste_tabular = 0;
43 bool InsetTabular::hasPasteBuffer() const
45 return (paste_tabular != 0);
55 struct tabular_features {
56 LyXTabular::Feature action;
60 //static tabular_features * tabularFeatures = 0;
62 static tabular_features tabularFeatures[] =
64 { LyXTabular::APPEND_ROW, "append-row" },
65 { LyXTabular::APPEND_COLUMN, "append-column" },
66 { LyXTabular::DELETE_ROW, "delete-row" },
67 { LyXTabular::DELETE_COLUMN, "delete-column" },
68 { LyXTabular::TOGGLE_LINE_TOP, "toggle-line-top" },
69 { LyXTabular::TOGGLE_LINE_BOTTOM, "toggle-line-bottom" },
70 { LyXTabular::TOGGLE_LINE_LEFT, "toggle-line-left" },
71 { LyXTabular::TOGGLE_LINE_RIGHT, "toggle-line-right" },
72 { LyXTabular::ALIGN_LEFT, "align-left" },
73 { LyXTabular::ALIGN_RIGHT, "align-right" },
74 { LyXTabular::ALIGN_CENTER, "align-center" },
75 { LyXTabular::VALIGN_TOP, "valign-top" },
76 { LyXTabular::VALIGN_BOTTOM, "valign-bottom" },
77 { LyXTabular::VALIGN_CENTER, "valign-center" },
78 { LyXTabular::M_TOGGLE_LINE_TOP, "m-toggle-line-top" },
79 { LyXTabular::M_TOGGLE_LINE_BOTTOM, "m-toggle-line-bottom" },
80 { LyXTabular::M_TOGGLE_LINE_LEFT, "m-toggle-line-left" },
81 { LyXTabular::M_TOGGLE_LINE_RIGHT, "m-toggle-line-right" },
82 { LyXTabular::M_ALIGN_LEFT, "m-align-left" },
83 { LyXTabular::M_ALIGN_RIGHT, "m-align-right" },
84 { LyXTabular::M_ALIGN_CENTER, "m-align-center" },
85 { LyXTabular::M_VALIGN_TOP, "m-valign-top" },
86 { LyXTabular::M_VALIGN_BOTTOM, "m-valign-bottom" },
87 { LyXTabular::M_VALIGN_CENTER, "m-valign-center" },
88 { LyXTabular::MULTICOLUMN, "multicolumn" },
89 { LyXTabular::SET_ALL_LINES, "set-all-lines" },
90 { LyXTabular::UNSET_ALL_LINES, "unset-all-lines" },
91 { LyXTabular::SET_LONGTABULAR, "set-longtabular" },
92 { LyXTabular::UNSET_LONGTABULAR, "unset-longtabular" },
93 { LyXTabular::SET_PWIDTH, "set-pwidth" },
94 { LyXTabular::SET_MPWIDTH, "set-mpwidth" },
95 { LyXTabular::SET_ROTATE_TABULAR, "set-rotate-tabular" },
96 { LyXTabular::UNSET_ROTATE_TABULAR, "unset-rotate-tabular" },
97 { LyXTabular::SET_ROTATE_CELL, "set-rotate-cell" },
98 { LyXTabular::UNSET_ROTATE_CELL, "unset-rotate-cell" },
99 { LyXTabular::SET_USEBOX, "set-usebox" },
100 { LyXTabular::SET_LTHEAD, "set-lthead" },
101 { LyXTabular::SET_LTFIRSTHEAD, "set-ltfirsthead" },
102 { LyXTabular::SET_LTFOOT, "set-ltfoot" },
103 { LyXTabular::SET_LTLASTFOOT, "set-ltlastfoot" },
104 { LyXTabular::SET_LTNEWPAGE, "set-ltnewpage" },
105 { LyXTabular::SET_SPECIAL_COLUMN, "set-special-column" },
106 { LyXTabular::SET_SPECIAL_MULTI, "set-special-multi" },
107 { LyXTabular::LAST_ACTION, "" }
112 bool cellstart(LyXParagraph::size_type p)
114 return ((p % 2) == 0);
118 InsetTabular::InsetTabular(Buffer const & buf, int rows, int columns)
125 tabular = new LyXTabular(this, rows,columns);
126 // for now make it always display as display() inset
128 the_locking_inset = 0;
129 locked = no_selection = cursor_visible = false;
134 sel_pos_start = sel_pos_end = sel_cell_start = sel_cell_end = 0;
139 InsetTabular::InsetTabular(InsetTabular const & tab, Buffer const & buf)
142 tabular = new LyXTabular(this, *(tab.tabular));
143 the_locking_inset = 0;
144 locked = no_selection = cursor_visible = false;
149 sel_pos_start = sel_pos_end = sel_cell_start = sel_cell_end = 0;
154 InsetTabular::~InsetTabular()
161 Inset * InsetTabular::Clone(Buffer const & buf) const
163 InsetTabular * t = new InsetTabular(*this, buf);
165 t->tabular = tabular->Clone(t);
170 void InsetTabular::Write(Buffer const * buf, ostream & os) const
172 os << " Tabular" << endl;
173 tabular->Write(buf, os);
177 void InsetTabular::Read(Buffer const * buf, LyXLex & lex)
179 bool old_format = (lex.GetString() == "\\LyXTable");
184 tabular = new LyXTabular(buf, this, lex);
192 token = lex.GetString();
193 while (lex.IsOK() && (token != "\\end_inset")) {
195 token = lex.GetString();
197 if (token != "\\end_inset") {
198 lex.printError("Missing \\end_inset at this point. "
204 int InsetTabular::ascent(BufferView *, LyXFont const &) const
206 return tabular->GetAscentOfRow(0);
210 int InsetTabular::descent(BufferView *, LyXFont const &) const
212 return tabular->GetHeightOfTabular() - tabular->GetAscentOfRow(0) + 1;
216 int InsetTabular::width(BufferView *, LyXFont const &) const
218 return tabular->GetWidthOfTabular() + (2 * ADD_TO_TABULAR_WIDTH);
222 void InsetTabular::draw(BufferView * bv, LyXFont const & font, int baseline,
223 float & x, bool cleared) const
225 Painter & pain = bv->painter();
230 UpdatableInset::draw(bv, font, baseline, x, cleared);
231 if (!cleared && ((need_update == INIT) || (need_update == FULL) ||
232 (top_x != int(x)) || (top_baseline != baseline))) {
233 int h = ascent(bv, font) + descent(bv, font);
234 int tx = display() || !owner() ? 0 : top_x;
235 int w = tx ? width(bv, font) : pain.paperWidth();
236 int ty = baseline - ascent(bv, font);
240 if ((ty + h) > pain.paperHeight())
241 h = pain.paperHeight();
242 if ((top_x + w) > pain.paperWidth())
243 w = pain.paperWidth();
244 pain.fillRectangle(tx, ty, w, h);
249 top_baseline = baseline;
250 if (bv->text->status == LyXText::CHANGED_IN_DRAW)
253 x += ADD_TO_TABULAR_WIDTH;
255 for(i = 0; i < tabular->rows(); ++i) {
257 dodraw = ((baseline + tabular->GetDescentOfRow(i)) > 0) &&
258 (baseline - tabular->GetAscentOfRow(i))<pain.paperHeight();
259 for(j = 0; j < tabular->columns(); ++j) {
260 if (tabular->IsPartOfMultiColumn(i, j))
262 cx = nx + tabular->GetBeginningOfTextInCell(cell);
265 DrawCellSelection(pain, nx, baseline, i, j, cell);
266 tabular->GetCellInset(cell)->draw(bv, font, baseline, cx,
268 DrawCellLines(pain, nx, baseline, i, cell);
270 nx += tabular->GetWidthOfColumn(cell);
273 baseline += tabular->GetDescentOfRow(i) +
274 tabular->GetAscentOfRow(i + 1) +
275 tabular->GetAdditionalHeight(cell);
277 } else if (need_update == CELL) {
279 for(i = 0; (cell < actcell) && (i < tabular->rows()); ++i) {
280 for(j = 0; (cell < actcell) && (j < tabular->columns()); ++j) {
281 if (tabular->IsPartOfMultiColumn(i, j))
283 nx += tabular->GetWidthOfColumn(cell);
286 if (tabular->row_of_cell(cell) > i) {
288 baseline += tabular->GetDescentOfRow(i) +
289 tabular->GetAscentOfRow(i + 1) +
290 tabular->GetAdditionalHeight(cell);
293 i = tabular->row_of_cell(actcell);
294 if (the_locking_inset == tabular->GetCellInset(cell)) {
295 LyXText::text_status st = bv->text->status;
297 cx = nx + tabular->GetBeginningOfTextInCell(cell);
298 bv->text->status = st;
299 if (need_update == CELL) {
300 // clear before the inset
303 baseline - tabular->GetAscentOfRow(i) + 1,
305 tabular->GetAscentOfRow(i) +
306 tabular->GetDescentOfRow(i) - 1);
307 // clear behind the inset
309 int(cx + the_locking_inset->width(bv,font) + 1),
310 baseline - tabular->GetAscentOfRow(i) + 1,
311 tabular->GetWidthOfColumn(cell) -
312 tabular->GetBeginningOfTextInCell(cell) -
313 the_locking_inset->width(bv,font) - 1,
314 tabular->GetAscentOfRow(i) +
315 tabular->GetDescentOfRow(i) - 1);
317 tabular->GetCellInset(cell)->draw(bv,font,baseline, cx, false);
318 } while(bv->text->status == LyXText::CHANGED_IN_DRAW);
321 x -= ADD_TO_TABULAR_WIDTH;
322 x += width(bv, font);
323 if (bv->text->status == LyXText::CHANGED_IN_DRAW)
330 void InsetTabular::DrawCellLines(Painter & pain, int x, int baseline,
331 int row, int cell) const
333 int x2 = x + tabular->GetWidthOfColumn(cell);
336 if (!tabular->TopAlreadyDrawed(cell)) {
337 on_off = !tabular->TopLine(cell);
338 pain.line(x, baseline - tabular->GetAscentOfRow(row),
339 x2, baseline - tabular->GetAscentOfRow(row),
340 on_off ? LColor::tabularonoffline : LColor::tabularline,
341 on_off ? Painter::line_onoffdash : Painter::line_solid);
343 on_off = !tabular->BottomLine(cell);
344 pain.line(x,baseline + tabular->GetDescentOfRow(row),
345 x2, baseline + tabular->GetDescentOfRow(row),
346 on_off ? LColor::tabularonoffline : LColor::tabularline,
347 on_off ? Painter::line_onoffdash : Painter::line_solid);
348 if (!tabular->LeftAlreadyDrawed(cell)) {
349 on_off = !tabular->LeftLine(cell);
350 pain.line(x, baseline - tabular->GetAscentOfRow(row),
351 x, baseline + tabular->GetDescentOfRow(row),
352 on_off ? LColor::tabularonoffline : LColor::tabularline,
353 on_off ? Painter::line_onoffdash : Painter::line_solid);
355 on_off = !tabular->RightLine(cell);
356 pain.line(x2 - tabular->GetAdditionalWidth(cell),
357 baseline - tabular->GetAscentOfRow(row),
358 x2 - tabular->GetAdditionalWidth(cell),
359 baseline + tabular->GetDescentOfRow(row),
360 on_off ? LColor::tabularonoffline : LColor::tabularline,
361 on_off ? Painter::line_onoffdash : Painter::line_solid);
365 void InsetTabular::DrawCellSelection(Painter & pain, int x, int baseline,
366 int row, int column, int cell) const
368 int cs = tabular->column_of_cell(sel_cell_start);
369 int ce = tabular->column_of_cell(sel_cell_end);
372 cs = tabular->column_of_cell(sel_cell_end);
374 ce = tabular->right_column_of_cell(sel_cell_end);
377 int rs = tabular->row_of_cell(sel_cell_start);
378 int re = tabular->row_of_cell(sel_cell_end);
379 if (rs > re) swap(rs, re);
381 if ((column >= cs) && (column <= ce) && (row >= rs) && (row <= re)) {
382 int w = tabular->GetWidthOfColumn(cell);
383 int h = tabular->GetAscentOfRow(row) + tabular->GetDescentOfRow(row);
384 pain.fillRectangle(x, baseline - tabular->GetAscentOfRow(row),
385 w, h, LColor::selection);
390 void InsetTabular::update(BufferView * bv, LyXFont const & font, bool reinit)
394 calculate_dimensions_of_cells(bv, font, true);
396 owner()->update(bv, font, true);
399 if (the_locking_inset) {
400 the_locking_inset->update(bv, font, reinit);
402 // inset_x = cursor.x() - top_x + tabular->GetBeginningOfTextInCell(actcell);
403 // inset_y = cursor.y();
405 switch(need_update) {
409 if (calculate_dimensions_of_cells(bv, font, false))
421 string const InsetTabular::EditMessage() const
423 return _("Opened Tabular Inset");
427 void InsetTabular::Edit(BufferView * bv, int x, int y, unsigned int button)
429 UpdatableInset::Edit(bv, x, y, button);
431 if (!bv->lockInset(this)) {
432 lyxerr[Debug::INSETS] << "InsetTabular::Cannot lock inset" << endl;
436 the_locking_inset = 0;
441 sel_pos_start = sel_pos_end = cursor.pos();
442 sel_cell_start = sel_cell_end = actcell;
443 bv->text->FinishUndo();
444 if (InsetHit(bv, x, y)) {
445 ActivateCellInset(bv, x, y, button);
447 UpdateLocal(bv, NONE, false);
448 // bv->getOwner()->getPopups().updateFormTabular();
452 void InsetTabular::InsetUnlock(BufferView * bv)
454 if (the_locking_inset) {
455 the_locking_inset->InsetUnlock(bv);
456 the_locking_inset = 0;
459 no_selection = false;
462 if (scroll() || hasSelection()) {
466 sel_pos_start = sel_pos_end = 0;
467 sel_cell_start = sel_cell_end = 0;
469 UpdateLocal(bv, FULL, false);
474 void InsetTabular::UpdateLocal(BufferView * bv, UpdateCodes what,
475 bool mark_dirty) const
479 bv->updateInset(const_cast<InsetTabular *>(this), mark_dirty);
480 if (locked && (what != NONE))
485 bool InsetTabular::LockInsetInInset(BufferView * bv, UpdatableInset * inset)
487 lyxerr[Debug::INSETS] << "InsetTabular::LockInsetInInset(" <<inset<< "): ";
491 if (inset == tabular->GetCellInset(actcell)) {
492 lyxerr[Debug::INSETS] << "OK" << endl;
493 the_locking_inset = tabular->GetCellInset(actcell);
495 inset_x = cursor.x() - top_x + tabular->GetBeginningOfTextInCell(actcell);
496 inset_y = cursor.y();
497 inset_pos = cursor.pos();
499 } else if (the_locking_inset && (the_locking_inset == inset)) {
500 if (cursor.pos() == inset_pos) {
501 lyxerr[Debug::INSETS] << "OK" << endl;
503 inset_x = cursor.x() - top_x + tabular->GetBeginningOfTextInCell(actcell);
504 inset_y = cursor.y();
506 lyxerr[Debug::INSETS] << "cursor.pos != inset_pos" << endl;
508 } else if (the_locking_inset) {
509 lyxerr[Debug::INSETS] << "MAYBE" << endl;
510 return the_locking_inset->LockInsetInInset(bv, inset);
512 lyxerr[Debug::INSETS] << "NOT OK" << endl;
517 bool InsetTabular::UnlockInsetInInset(BufferView * bv, UpdatableInset * inset,
520 if (!the_locking_inset)
522 if (the_locking_inset == inset) {
523 the_locking_inset->InsetUnlock(bv);
524 the_locking_inset = 0;
526 moveRight(bv, false);
527 ShowInsetCursor(bv, false);
528 UpdateLocal(bv, CELL, false);
531 if (the_locking_inset->UnlockInsetInInset(bv, inset, lr)) {
532 if (inset->LyxCode() == TABULAR_CODE &&
533 !the_locking_inset->GetFirstLockingInsetOfType(TABULAR_CODE))
535 bv->owner()->getDialogs()->updateTabular(this);
544 bool InsetTabular::UpdateInsetInInset(BufferView * bv, Inset * inset)
546 if (!the_locking_inset)
548 if (the_locking_inset != inset) {
549 if (!the_locking_inset->UpdateInsetInInset(bv, inset))
552 UpdateLocal(bv, CELL, false);
557 unsigned int InsetTabular::InsetInInsetY()
559 if (!the_locking_inset)
562 return (inset_y + the_locking_inset->InsetInInsetY());
566 UpdatableInset * InsetTabular::GetLockingInset()
568 return the_locking_inset ? the_locking_inset->GetLockingInset() : this;
572 UpdatableInset * InsetTabular::GetFirstLockingInsetOfType(Inset::Code c)
576 if (the_locking_inset)
577 return the_locking_inset->GetFirstLockingInsetOfType(c);
582 bool InsetTabular::InsertInset(BufferView * bv, Inset * inset)
584 if (the_locking_inset)
585 return the_locking_inset->InsertInset(bv, inset);
590 void InsetTabular::InsetButtonPress(BufferView * bv, int x, int y, int button)
592 if (hasSelection()) {
593 sel_pos_start = sel_pos_end = sel_cell_start = sel_cell_end = 0;
594 UpdateLocal(bv, SELECTION, false);
596 no_selection = false;
598 int const ocell = actcell;
599 int const orow = actrow;
604 UpdateLocal(bv, NONE, false);
605 sel_pos_start = sel_pos_end = cursor.pos();
606 sel_cell_start = sel_cell_end = actcell;
608 bool const inset_hit = InsetHit(bv, x, y);
610 if ((ocell == actcell) && the_locking_inset && inset_hit) {
611 cursor.pos(0); // always before the inset!
613 the_locking_inset->InsetButtonPress(bv,
614 x - inset_x, y - inset_y, button);
616 } else if (the_locking_inset) {
617 the_locking_inset->InsetUnlock(bv);
619 the_locking_inset = 0;
620 if (inset_hit && bv->theLockingInset()) {
621 if (ActivateCellInset(bv, x, y, button))
622 the_locking_inset->InsetButtonPress(bv, x - inset_x,
623 y - inset_y, button);
630 void InsetTabular::InsetButtonRelease(BufferView * bv,
631 int x, int y, int button)
634 if (the_locking_inset) {
636 if ((i=the_locking_inset->GetFirstLockingInsetOfType(TABULAR_CODE))) {
637 i->InsetButtonRelease(bv, x, y, button);
641 bv->owner()->getDialogs()->showTabular(this);
644 if (the_locking_inset) {
645 the_locking_inset->InsetButtonRelease(bv, x-inset_x, y-inset_y,button);
648 no_selection = false;
652 void InsetTabular::InsetMotionNotify(BufferView * bv, int x, int y, int button)
654 if (the_locking_inset) {
655 the_locking_inset->InsetMotionNotify(bv, x - inset_x,
656 y - inset_y, button);
661 LyXParagraph::size_type const old_pos = sel_pos_end;
662 int const old_cell = actcell;
665 sel_pos_end = cursor.pos();
666 sel_cell_end = actcell;
667 if ((sel_cell_end != old_cell) || (old_pos != sel_pos_end))
668 UpdateLocal(bv, SELECTION, false);
671 no_selection = false;
675 void InsetTabular::InsetKeyPress(XKeyEvent * xke)
677 if (the_locking_inset) {
678 the_locking_inset->InsetKeyPress(xke);
684 UpdatableInset::RESULT InsetTabular::LocalDispatch(BufferView * bv, int action,
687 UpdatableInset::RESULT
690 no_selection = false;
691 if (((result=UpdatableInset::LocalDispatch(bv, action, arg)) == DISPATCHED)
692 || (result == DISPATCHED_NOUPDATE)) {
698 if ((action < 0) && arg.empty())
701 if ((action != LFUN_DOWN) && (action != LFUN_UP) &&
702 (action != LFUN_DOWNSEL) && (action != LFUN_UPSEL))
704 if (the_locking_inset) {
705 result=the_locking_inset->LocalDispatch(bv, action, arg);
706 if (result == DISPATCHED_NOUPDATE)
708 else if (result == DISPATCHED) {
709 the_locking_inset->ToggleInsetCursor(bv);
710 UpdateLocal(bv, CELL, false);
711 the_locking_inset->ToggleInsetCursor(bv);
713 } else if (result == FINISHED) {
714 if ((action == LFUN_RIGHT) || (action == -1)) {
715 cursor.pos(inset_pos + 1);
718 sel_pos_start = sel_pos_end = cursor.pos();
719 sel_cell_start = sel_cell_end = actcell;
727 bool hs = hasSelection();
731 // --- Cursor Movements ---------------------------------------------
733 if (tabular->IsLastCellInRow(actcell) && !cellstart(cursor.pos()))
735 moveRight(bv, false);
737 if (!cellstart(cursor.pos())) {
738 sel_pos_end = cursor.pos();
739 if (tabular->right_column_of_cell(sel_cell_start) >
740 tabular->right_column_of_cell(actcell))
741 sel_cell_end = actcell+1;
743 sel_cell_end = actcell;
746 sel_pos_end = cursor.pos();
747 sel_cell_end = actcell;
749 UpdateLocal(bv, SELECTION, false);
752 result = moveRight(bv);
753 sel_pos_start = sel_pos_end = cursor.pos();
754 sel_cell_start = sel_cell_end = actcell;
756 UpdateLocal(bv, SELECTION, false);
759 if (tabular->IsFirstCellInRow(actcell) && cellstart(cursor.pos()))
763 if (cellstart(cursor.pos())) {
764 sel_pos_end = cursor.pos();
765 if (tabular->column_of_cell(sel_cell_start) >=
766 tabular->column_of_cell(actcell))
767 sel_cell_end = actcell;
769 sel_cell_end = actcell-1;
772 sel_pos_end = cursor.pos();
773 sel_cell_end = actcell;
775 UpdateLocal(bv, SELECTION, false);
778 result = moveLeft(bv);
779 sel_pos_start = sel_pos_end = cursor.pos();
780 sel_cell_start = sel_cell_end = actcell;
782 UpdateLocal(bv, SELECTION, false);
786 int const ocell = actcell;
788 sel_pos_end = cursor.pos();
789 if ((ocell == sel_cell_end) ||
790 (tabular->column_of_cell(ocell)>tabular->column_of_cell(actcell)))
791 sel_cell_end = tabular->GetCellBelow(sel_cell_end);
793 sel_cell_end = tabular->GetLastCellBelow(sel_cell_end);
794 UpdateLocal(bv, SELECTION, false);
798 result = moveDown(bv);
799 sel_pos_start = sel_pos_end = cursor.pos();
800 sel_cell_start = sel_cell_end = actcell;
802 UpdateLocal(bv, SELECTION, false);
806 int const ocell = actcell;
808 sel_pos_end = cursor.pos();
809 if ((ocell == sel_cell_end) ||
810 (tabular->column_of_cell(ocell)>tabular->column_of_cell(actcell)))
811 sel_cell_end = tabular->GetCellAbove(sel_cell_end);
813 sel_cell_end = tabular->GetLastCellAbove(sel_cell_end);
814 UpdateLocal(bv, SELECTION, false);
819 sel_pos_start = sel_pos_end = cursor.pos();
820 sel_cell_start = sel_cell_end = actcell;
822 UpdateLocal(bv, SELECTION, false);
834 if (the_locking_inset) {
835 UnlockInsetInInset(bv, the_locking_inset);
836 the_locking_inset = 0;
838 if (action == LFUN_TAB)
842 sel_pos_start = sel_pos_end = cursor.pos();
843 sel_cell_start = sel_cell_end = actcell;
845 UpdateLocal(bv, SELECTION, false);
847 case LFUN_LAYOUT_TABULAR:
849 bv->owner()->getDialogs()->showTabular(this);
852 case LFUN_TABULAR_FEATURE:
853 if (!TabularFeatures(bv, arg))
854 result = UNDISPATCHED;
857 if (!copySelection(bv))
859 bv->text->SetUndo(bv->buffer(), Undo::DELETE,
861 bv->text->cursor.par()->ParFromPos(bv->text->cursor.pos())->previous,
862 bv->text->cursor.par()->ParFromPos(bv->text->cursor.pos())->next
864 bv->text->cursor.par()->previous,
865 bv->text->cursor.par()->next
869 UpdateLocal(bv, INIT, true);
874 bv->text->FinishUndo();
878 if (!hasPasteBuffer())
880 bv->text->SetUndo(bv->buffer(), Undo::INSERT,
882 bv->text->cursor.par()->ParFromPos(bv->text->cursor.pos())->previous,
883 bv->text->cursor.par()->ParFromPos(bv->text->cursor.pos())->next
885 bv->text->cursor.par()->previous,
886 bv->text->cursor.par()->next
890 UpdateLocal(bv, INIT, true);
893 // we try to activate the actual inset and put this event down to
894 // the insets dispatch function.
895 result = UNDISPATCHED;
896 if (the_locking_inset)
898 if (ActivateCellInset(bv, 0, 0, 0, !cellstart(cursor.pos()))) {
899 result=the_locking_inset->LocalDispatch(bv, action, arg);
900 if (result == DISPATCHED_NOUPDATE)
902 else if (result == DISPATCHED) {
903 the_locking_inset->ToggleInsetCursor(bv);
904 UpdateLocal(bv, CELL, false);
905 the_locking_inset->ToggleInsetCursor(bv);
908 result = UNDISPATCHED;
913 if (result!=FINISHED) {
914 if (!the_locking_inset) {
918 bv->unlockInset(this);
923 int InsetTabular::Latex(Buffer const * buf, ostream & os,
924 bool fragile, bool fp) const
926 return tabular->Latex(buf, os, fragile, fp);
930 int InsetTabular::Ascii(Buffer const * buf, ostream & os, int) const
932 // This should be changed to a real ascii export
933 return tabular->Ascii(buf, os);
937 int InsetTabular::Linuxdoc(Buffer const *, ostream &) const
943 int InsetTabular::DocBook(Buffer const * buf, ostream & os) const
945 return tabular->DocBook(buf,os);
949 void InsetTabular::Validate(LaTeXFeatures & features) const
951 tabular->Validate(features);
955 bool InsetTabular::calculate_dimensions_of_cells(BufferView * bv,
956 LyXFont const & font,
962 bool changed = false;
964 for(int i = 0; i < tabular->rows(); ++i) {
965 maxAsc = maxDesc = 0;
966 for(int j= 0; j < tabular->columns(); ++j) {
967 if (tabular->IsPartOfMultiColumn(i,j))
970 inset = tabular->GetCellInset(cell);
972 inset->update(bv, font, false);
973 maxAsc = max(maxAsc, inset->ascent(bv, font));
974 maxDesc = max(maxDesc, inset->descent(bv, font));
975 changed = tabular->SetWidthOfCell(cell, inset->width(bv, font)) || changed;
977 changed = tabular->SetAscentOfRow(i, maxAsc + ADD_TO_HEIGHT) || changed;
978 changed = tabular->SetDescentOfRow(i, maxDesc + ADD_TO_HEIGHT) || changed;
984 void InsetTabular::GetCursorPos(BufferView *,
985 int & x, int & y) const
987 x = cursor.x() - top_x;
992 void InsetTabular::ToggleInsetCursor(BufferView * bv)
994 if (the_locking_inset) {
995 the_locking_inset->ToggleInsetCursor(bv);
999 LyXFont font; // = the_locking_inset->GetFont(par, cursor.pos);
1001 int const asc = lyxfont::maxAscent(font);
1002 int const desc = lyxfont::maxDescent(font);
1005 bv->hideLockedInsetCursor();
1007 bv->showLockedInsetCursor(cursor.x(), cursor.y(), asc, desc);
1008 cursor_visible = !cursor_visible;
1012 void InsetTabular::ShowInsetCursor(BufferView * bv, bool show)
1014 if (!cursor_visible) {
1015 LyXFont font; // = GetFont(par, cursor.pos);
1017 int const asc = lyxfont::maxAscent(font);
1018 int const desc = lyxfont::maxDescent(font);
1019 bv->fitLockedInsetCursor(cursor.x(), cursor.y(), asc, desc);
1021 bv->showLockedInsetCursor(cursor.x(), cursor.y(), asc, desc);
1022 cursor_visible = true;
1027 void InsetTabular::HideInsetCursor(BufferView * bv)
1029 if (cursor_visible) {
1030 bv->hideLockedInsetCursor();
1031 cursor_visible = false;
1033 // if (cursor_visible)
1034 // ToggleInsetCursor(bv);
1038 void InsetTabular::setPos(BufferView * bv, int x, int y) const
1043 actcell = actrow = actcol = 0;
1044 int ly = tabular->GetDescentOfRow(actrow);
1046 // first search the right row
1047 while((ly < y) && (actrow < tabular->rows())) {
1048 cursor.y(cursor.y() + tabular->GetDescentOfRow(actrow) +
1049 tabular->GetAscentOfRow(actrow + 1) +
1050 tabular->GetAdditionalHeight(tabular->GetCellNumber(actrow + 1,
1053 ly = cursor.y() + tabular->GetDescentOfRow(actrow);
1055 actcell = tabular->GetCellNumber(actrow, actcol);
1057 // now search the right column
1058 int lx = tabular->GetWidthOfColumn(actcell) -
1059 tabular->GetAdditionalWidth(actcell);
1060 #warning Jürgen, can you rewrite this to _not_ use the sequencing operator. (Lgb)
1062 for(; !tabular->IsLastCellInRow(actcell) && (lx < x);
1063 ++actcell,lx += tabular->GetWidthOfColumn(actcell) +
1064 tabular->GetAdditionalWidth(actcell - 1));
1066 // Jürgen, you should check that this is correct. (Lgb)
1067 for (; !tabular->IsLastCellInRow(actcell) && lx < x; ++actcell) {
1068 lx += tabular->GetWidthOfColumn(actcell + 1)
1069 + tabular->GetAdditionalWidth(actcell);
1075 if ((lx - (tabular->GetWidthOfColumn(actcell) / 2)) < x) {
1076 cursor.x(lx + top_x - 2);
1079 cursor.x(lx - tabular->GetWidthOfColumn(actcell) + top_x + 2);
1085 int InsetTabular::getCellXPos(int cell) const
1089 for(; !tabular->IsFirstCellInRow(c); --c)
1091 int lx = tabular->GetWidthOfColumn(cell);
1092 for(; c < cell; ++c) {
1093 lx += tabular->GetWidthOfColumn(c);
1095 return (lx - tabular->GetWidthOfColumn(cell) + top_x);
1099 void InsetTabular::resetPos(BufferView * bv) const
1103 actcol = tabular->column_of_cell(actcell);
1108 for(; (cell < actcell) && !tabular->IsLastRow(cell); ++cell) {
1109 if (tabular->IsLastCellInRow(cell)) {
1110 cursor.y(cursor.y() + tabular->GetDescentOfRow(actrow) +
1111 tabular->GetAscentOfRow(actrow + 1) +
1112 tabular->GetAdditionalHeight(cell + 1));
1116 static int const offset = ADD_TO_TABULAR_WIDTH + 2;
1117 cursor.x(getCellXPos(actcell) + offset);
1118 if (((cursor.x() - offset) > 20) &&
1119 ((cursor.x()-offset+tabular->GetWidthOfColumn(actcell)) >
1120 (bv->workWidth()-20)))
1122 scroll(bv, -tabular->GetWidthOfColumn(actcell)-20);
1123 UpdateLocal(bv, FULL, false);
1124 } else if ((cursor.x() - offset) < 20) {
1125 scroll(bv, 20 - cursor.x() + offset);
1126 UpdateLocal(bv, FULL, false);
1127 } else if (!cellstart(cursor.pos())) {
1128 LyXFont font(LyXFont::ALL_SANE);
1129 cursor.x(cursor.x() + tabular->GetCellInset(actcell)->width(bv,font) +
1130 tabular->GetBeginningOfTextInCell(actcell));
1132 if ((!the_locking_inset ||
1133 !the_locking_inset->GetFirstLockingInsetOfType(TABULAR_CODE)) &&
1134 (actcell != oldcell)) {
1135 InsetTabular * inset = const_cast<InsetTabular *>(this);
1136 bv->owner()->getDialogs()->updateTabular(inset);
1142 UpdatableInset::RESULT InsetTabular::moveRight(BufferView * bv, bool lock)
1144 if (!cellstart(cursor.pos())) {
1145 if (tabular->IsLastCell(actcell))
1150 if (ActivateCellInset(bv))
1152 } else { // before the inset
1156 return DISPATCHED_NOUPDATE;
1160 UpdatableInset::RESULT InsetTabular::moveLeft(BufferView * bv, bool lock)
1162 if (cellstart(cursor.pos()) && !actcell)
1164 if (cellstart(cursor.pos())) {
1167 } else if (lock) { // behind the inset
1169 if (ActivateCellInset(bv, 0, 0, 0, true))
1175 return DISPATCHED_NOUPDATE;
1179 UpdatableInset::RESULT InsetTabular::moveUp(BufferView * bv)
1181 int const ocell = actcell;
1182 actcell = tabular->GetCellAbove(actcell);
1183 if (actcell == ocell) // we moved out of the inset
1186 return DISPATCHED_NOUPDATE;
1190 UpdatableInset::RESULT InsetTabular::moveDown(BufferView * bv)
1192 int const ocell = actcell;
1193 actcell = tabular->GetCellBelow(actcell);
1194 if (actcell == ocell) // we moved out of the inset
1197 return DISPATCHED_NOUPDATE;
1201 bool InsetTabular::moveNextCell(BufferView * bv)
1203 if (tabular->IsLastCell(actcell))
1211 bool InsetTabular::movePrevCell(BufferView * bv)
1213 if (!actcell) // first cell
1221 bool InsetTabular::Delete()
1227 void InsetTabular::SetFont(BufferView * bv, LyXFont const & font, bool tall)
1229 if (the_locking_inset)
1230 the_locking_inset->SetFont(bv, font, tall);
1234 bool InsetTabular::TabularFeatures(BufferView * bv, string const & what)
1236 LyXTabular::Feature action = LyXTabular::LAST_ACTION;
1239 for(; tabularFeatures[i].action != LyXTabular::LAST_ACTION; ++i) {
1240 string const tmp = tabularFeatures[i].feature;
1242 if (tmp == what.substr(0, tmp.length())) {
1243 //if (!strncmp(tabularFeatures[i].feature.c_str(), what.c_str(),
1244 //tabularFeatures[i].feature.length())) {
1245 action = tabularFeatures[i].action;
1249 if (action == LyXTabular::LAST_ACTION)
1253 frontStrip(what.substr(tabularFeatures[i].feature.length()));
1254 TabularFeatures(bv, action, val);
1259 void InsetTabular::TabularFeatures(BufferView * bv,
1260 LyXTabular::Feature feature,
1261 string const & value)
1270 LyXAlignment setAlign = LYX_ALIGN_LEFT;
1271 LyXTabular::VAlignment setVAlign = LyXTabular::LYX_VALIGN_TOP;
1276 case LyXTabular::M_ALIGN_LEFT:
1277 case LyXTabular::ALIGN_LEFT:
1278 setAlign=LYX_ALIGN_LEFT;
1280 case LyXTabular::M_ALIGN_RIGHT:
1281 case LyXTabular::ALIGN_RIGHT:
1282 setAlign=LYX_ALIGN_RIGHT;
1284 case LyXTabular::M_ALIGN_CENTER:
1285 case LyXTabular::ALIGN_CENTER:
1286 setAlign=LYX_ALIGN_CENTER;
1288 case LyXTabular::M_VALIGN_TOP:
1289 case LyXTabular::VALIGN_TOP:
1290 setVAlign=LyXTabular::LYX_VALIGN_TOP;
1292 case LyXTabular::M_VALIGN_BOTTOM:
1293 case LyXTabular::VALIGN_BOTTOM:
1294 setVAlign=LyXTabular::LYX_VALIGN_BOTTOM;
1296 case LyXTabular::M_VALIGN_CENTER:
1297 case LyXTabular::VALIGN_CENTER:
1298 setVAlign=LyXTabular::LYX_VALIGN_CENTER;
1303 if (hasSelection()) {
1304 sel_col_start = tabular->column_of_cell(sel_cell_start);
1305 sel_col_end = tabular->column_of_cell(sel_cell_end);
1306 if (sel_col_start > sel_col_end) {
1307 sel_col_end = sel_col_start;
1308 sel_col_start = tabular->column_of_cell(sel_cell_end);
1310 sel_col_end = tabular->right_column_of_cell(sel_cell_end);
1313 sel_row_start = tabular->row_of_cell(sel_cell_start);
1314 sel_row_end = tabular->row_of_cell(sel_cell_end);
1315 if (sel_row_start > sel_row_end) {
1316 //int tmp = sel_row_start;
1317 //sel_row_start = sel_row_end;
1318 //sel_row_end = tmp;
1319 swap(sel_row_start, sel_row_end);
1322 sel_col_start = sel_col_end = tabular->column_of_cell(actcell);
1323 sel_row_start = sel_row_end = tabular->row_of_cell(actcell);
1325 bv->text->SetUndo(bv->buffer(), Undo::FINISH,
1327 bv->text->cursor.par()->ParFromPos(bv->text->cursor.pos())->previous,
1328 bv->text->cursor.par()->ParFromPos(bv->text->cursor.pos())->next
1330 bv->text->cursor.par()->previous,
1331 bv->text->cursor.par()->next
1335 int row = tabular->row_of_cell(actcell);
1336 int column = tabular->column_of_cell(actcell);
1340 case LyXTabular::SET_PWIDTH:
1342 bool const update = (tabular->GetColumnPWidth(actcell) != value);
1343 tabular->SetColumnPWidth(actcell,value);
1345 for (int i=0; i < tabular->rows(); ++i) {
1346 tabular->GetCellInset(tabular->GetCellNumber(i, column))->
1349 UpdateLocal(bv, INIT, true);
1353 case LyXTabular::SET_MPWIDTH:
1355 bool const update = (tabular->GetPWidth(actcell) != value);
1356 tabular->SetMColumnPWidth(actcell,value);
1358 for (int i=0; i < tabular->rows(); ++i) {
1359 tabular->GetCellInset(tabular->GetCellNumber(i, column))->
1362 UpdateLocal(bv, INIT, true);
1366 case LyXTabular::SET_SPECIAL_COLUMN:
1367 case LyXTabular::SET_SPECIAL_MULTI:
1368 tabular->SetAlignSpecial(actcell,value,feature);
1370 case LyXTabular::APPEND_ROW:
1371 // append the row into the tabular
1372 UnlockInsetInInset(bv, the_locking_inset);
1373 tabular->AppendRow(actcell);
1374 UpdateLocal(bv, INIT, true);
1376 case LyXTabular::APPEND_COLUMN:
1377 // append the column into the tabular
1378 tabular->AppendColumn(actcell);
1379 actcell = tabular->GetCellNumber(row, column);
1380 UpdateLocal(bv, INIT, true);
1382 case LyXTabular::DELETE_ROW:
1383 tabular->DeleteRow(tabular->row_of_cell(actcell));
1384 if ((row+1) > tabular->rows())
1386 actcell = tabular->GetCellNumber(row, column);
1387 UpdateLocal(bv, INIT, true);
1389 case LyXTabular::DELETE_COLUMN:
1390 tabular->DeleteColumn(tabular->column_of_cell(actcell));
1391 if ((column+1) > tabular->columns())
1393 actcell = tabular->GetCellNumber(row, column);
1394 UpdateLocal(bv, INIT, true);
1396 case LyXTabular::M_TOGGLE_LINE_TOP:
1398 case LyXTabular::TOGGLE_LINE_TOP:
1399 lineSet = !tabular->TopLine(actcell, flag);
1400 for(i=sel_row_start; i<=sel_row_end; ++i)
1401 for(j=sel_col_start; j<=sel_col_end; ++j)
1402 tabular->SetTopLine(tabular->GetCellNumber(i,j),lineSet, flag);
1403 UpdateLocal(bv, INIT, true);
1406 case LyXTabular::M_TOGGLE_LINE_BOTTOM:
1408 case LyXTabular::TOGGLE_LINE_BOTTOM:
1409 lineSet = !tabular->BottomLine(actcell, flag);
1410 for(i=sel_row_start; i<=sel_row_end; ++i)
1411 for(j=sel_col_start; j<=sel_col_end; ++j)
1412 tabular->SetBottomLine(tabular->GetCellNumber(i,j),lineSet,
1414 UpdateLocal(bv, INIT, true);
1417 case LyXTabular::M_TOGGLE_LINE_LEFT:
1419 case LyXTabular::TOGGLE_LINE_LEFT:
1420 lineSet = !tabular->LeftLine(actcell, flag);
1421 for(i=sel_row_start; i<=sel_row_end; ++i)
1422 for(j=sel_col_start; j<=sel_col_end; ++j)
1423 tabular->SetLeftLine(tabular->GetCellNumber(i,j),lineSet,
1425 UpdateLocal(bv, INIT, true);
1428 case LyXTabular::M_TOGGLE_LINE_RIGHT:
1430 case LyXTabular::TOGGLE_LINE_RIGHT:
1431 lineSet = !tabular->RightLine(actcell, flag);
1432 for(i=sel_row_start; i<=sel_row_end; ++i)
1433 for(j=sel_col_start; j<=sel_col_end; ++j)
1434 tabular->SetRightLine(tabular->GetCellNumber(i,j),lineSet,
1436 UpdateLocal(bv, INIT, true);
1438 case LyXTabular::M_ALIGN_LEFT:
1439 case LyXTabular::M_ALIGN_RIGHT:
1440 case LyXTabular::M_ALIGN_CENTER:
1442 case LyXTabular::ALIGN_LEFT:
1443 case LyXTabular::ALIGN_RIGHT:
1444 case LyXTabular::ALIGN_CENTER:
1445 for(i = sel_row_start; i <= sel_row_end; ++i)
1446 for(j = sel_col_start; j <= sel_col_end; ++j)
1447 tabular->SetAlignment(tabular->GetCellNumber(i, j), setAlign,
1450 UpdateLocal(bv, INIT, true);
1452 UpdateLocal(bv, CELL, true);
1454 case LyXTabular::M_VALIGN_TOP:
1455 case LyXTabular::M_VALIGN_BOTTOM:
1456 case LyXTabular::M_VALIGN_CENTER:
1458 case LyXTabular::VALIGN_TOP:
1459 case LyXTabular::VALIGN_BOTTOM:
1460 case LyXTabular::VALIGN_CENTER:
1461 for(i = sel_row_start; i <= sel_row_end; ++i)
1462 for(j = sel_col_start; j <= sel_col_end; ++j)
1463 tabular->SetVAlignment(tabular->GetCellNumber(i, j),
1466 UpdateLocal(bv, INIT, true);
1468 UpdateLocal(bv, CELL, true);
1470 case LyXTabular::MULTICOLUMN:
1472 if (sel_row_start != sel_row_end) {
1473 WriteAlert(_("Impossible Operation!"),
1474 _("Multicolumns can only be horizontally."),
1478 // just multicol for one Single Cell
1479 if (!hasSelection()) {
1480 // check wether we are completly in a multicol
1481 if (tabular->IsMultiColumn(actcell)) {
1482 tabular->UnsetMultiColumn(actcell);
1483 UpdateLocal(bv, INIT, true);
1485 tabular->SetMultiColumn(actcell, 1);
1486 UpdateLocal(bv, CELL, true);
1490 // we have a selection so this means we just add all this
1491 // cells to form a multicolumn cell
1495 if (sel_cell_start > sel_cell_end) {
1496 s_start = sel_cell_end;
1497 s_end = sel_cell_start;
1499 s_start = sel_cell_start;
1500 s_end = sel_cell_end;
1502 tabular->SetMultiColumn(s_start, s_end - s_start + 1);
1505 sel_cell_end = sel_cell_start;
1506 sel_pos_end = sel_pos_start;
1507 UpdateLocal(bv, INIT, true);
1510 case LyXTabular::SET_ALL_LINES:
1512 case LyXTabular::UNSET_ALL_LINES:
1513 for(i=sel_row_start; i<=sel_row_end; ++i)
1514 for(j=sel_col_start; j<=sel_col_end; ++j)
1515 tabular->SetAllLines(tabular->GetCellNumber(i,j), setLines);
1516 UpdateLocal(bv, INIT, true);
1518 case LyXTabular::SET_LONGTABULAR:
1519 tabular->SetLongTabular(true);
1520 UpdateLocal(bv, INIT, true); // because this toggles displayed
1522 case LyXTabular::UNSET_LONGTABULAR:
1523 tabular->SetLongTabular(false);
1524 UpdateLocal(bv, INIT, true); // because this toggles displayed
1526 case LyXTabular::SET_ROTATE_TABULAR:
1527 tabular->SetRotateTabular(true);
1529 case LyXTabular::UNSET_ROTATE_TABULAR:
1530 tabular->SetRotateTabular(false);
1532 case LyXTabular::SET_ROTATE_CELL:
1533 for(i=sel_row_start; i<=sel_row_end; ++i)
1534 for(j=sel_col_start; j<=sel_col_end; ++j)
1535 tabular->SetRotateCell(tabular->GetCellNumber(i,j),true);
1537 case LyXTabular::UNSET_ROTATE_CELL:
1538 for(i = sel_row_start; i <= sel_row_end; ++i)
1539 for(j = sel_col_start; j <= sel_col_end; ++j)
1540 tabular->SetRotateCell(tabular->GetCellNumber(i, j), false);
1542 case LyXTabular::SET_USEBOX:
1544 LyXTabular::BoxType val = LyXTabular::BoxType(strToInt(value));
1545 if (val == tabular->GetUsebox(actcell))
1546 val = LyXTabular::BOX_NONE;
1547 for(i = sel_row_start; i <= sel_row_end; ++i)
1548 for(j = sel_col_start; j <= sel_col_end; ++j)
1549 tabular->SetUsebox(tabular->GetCellNumber(i, j), val);
1552 case LyXTabular::SET_LTFIRSTHEAD:
1553 tabular->SetLTHead(actcell, true);
1555 case LyXTabular::SET_LTHEAD:
1556 tabular->SetLTHead(actcell, false);
1558 case LyXTabular::SET_LTFOOT:
1559 tabular->SetLTFoot(actcell, false);
1561 case LyXTabular::SET_LTLASTFOOT:
1562 tabular->SetLTFoot(actcell, true);
1564 case LyXTabular::SET_LTNEWPAGE:
1565 what = !tabular->GetLTNewPage(actcell);
1566 tabular->SetLTNewPage(actcell, what);
1568 // dummy stuff just to avoid warnings
1569 case LyXTabular::LAST_ACTION:
1575 bool InsetTabular::ActivateCellInset(BufferView * bv, int x, int y, int button,
1578 // the cursor.pos has to be before the inset so if it isn't now just
1579 // reset the curor pos first!
1580 if (!cellstart(cursor.pos())) {
1584 UpdatableInset * inset =
1585 static_cast<UpdatableInset*>(tabular->GetCellInset(actcell));
1586 LyXFont font(LyXFont::ALL_SANE);
1588 x = inset->x() + inset->width(bv, font);
1589 y = inset->descent(bv, font);
1591 inset_x = cursor.x() - top_x + tabular->GetBeginningOfTextInCell(actcell);
1592 inset_y = cursor.y();
1593 inset->Edit(bv, x - inset_x, y - inset_y, button);
1594 if (!the_locking_inset)
1596 UpdateLocal(bv, CELL, false);
1597 return (the_locking_inset != 0);
1601 bool InsetTabular::InsetHit(BufferView * bv, int x, int ) const
1603 InsetText * inset = tabular->GetCellInset(actcell);
1606 if (!cellstart(cursor.pos())) {
1607 return (((x + top_x) < cursor.x()) &&
1608 ((x + top_x) > (cursor.x() - inset->width(bv,
1609 LyXFont(LyXFont::ALL_SANE)))));
1611 int x2 = cursor.x() + tabular->GetBeginningOfTextInCell(actcell);
1612 return ((x1 > x2) &&
1613 (x1 < (x2 + inset->width(bv, LyXFont(LyXFont::ALL_SANE)))));
1618 // This returns paperWidth() if the cell-width is unlimited or the width
1619 // in pixels if we have a pwidth for this cell.
1620 int InsetTabular::GetMaxWidthOfCell(Painter &, int cell) const
1622 string const s = tabular->GetPWidth(cell);
1626 return VSpace(s).inPixels(0, 0);
1630 int InsetTabular::getMaxWidth(Painter & pain,
1631 UpdatableInset const * inset) const
1633 int const n = tabular->GetNumberOfCells();
1635 for(; cell < n; ++cell) {
1636 if (tabular->GetCellInset(cell) == inset)
1641 int w = GetMaxWidthOfCell(pain, cell);
1643 // because the inset then subtracts it's top_x and owner->x()
1644 w += (inset->x() - top_x);
1649 void InsetTabular::resizeLyXText(BufferView *) const
1655 LyXText * InsetTabular::getLyXText(BufferView * bv) const
1657 if (the_locking_inset)
1658 return the_locking_inset->getLyXText(bv);
1659 return Inset::getLyXText(bv);
1663 void InsetTabular::OpenLayoutDialog(BufferView * bv) const
1665 if (the_locking_inset) {
1666 InsetTabular * i = static_cast<InsetTabular *>
1667 (the_locking_inset->GetFirstLockingInsetOfType(TABULAR_CODE));
1669 i->OpenLayoutDialog(bv);
1673 bv->owner()->getDialogs()->showTabular(const_cast<InsetTabular *>(this));
1677 // functions returns:
1681 // 3 ... toggled off
1683 LyXFunc::func_status InsetTabular::getStatus(string const & what) const
1685 int action = LyXTabular::LAST_ACTION;
1686 LyXFunc::func_status status = LyXFunc::OK;
1689 for(; tabularFeatures[i].action != LyXTabular::LAST_ACTION; ++i) {
1690 string const tmp = tabularFeatures[i].feature;
1691 if (tmp == what.substr(0, tmp.length())) {
1692 //if (!strncmp(tabularFeatures[i].feature.c_str(), what.c_str(),
1693 // tabularFeatures[i].feature.length())) {
1694 action = tabularFeatures[i].action;
1698 if (action == LyXTabular::LAST_ACTION)
1699 return LyXFunc::Unknown;
1701 string const argument = frontStrip(what.substr(tabularFeatures[i].feature.length()));
1703 int sel_row_start, sel_row_end;
1707 if (hasSelection()) {
1708 sel_row_start = tabular->row_of_cell(sel_cell_start);
1709 sel_row_end = tabular->row_of_cell(sel_cell_end);
1710 if (sel_row_start > sel_row_end) {
1711 //int tmp = sel_row_start;
1712 //sel_row_start = sel_row_end;
1713 //sel_row_end = tmp;
1714 swap(sel_row_start, sel_row_end);
1717 sel_row_start = sel_row_end = tabular->row_of_cell(actcell);
1721 case LyXTabular::SET_PWIDTH:
1722 case LyXTabular::SET_MPWIDTH:
1723 case LyXTabular::SET_SPECIAL_COLUMN:
1724 case LyXTabular::SET_SPECIAL_MULTI:
1725 status |= LyXFunc::Disabled;
1728 case LyXTabular::APPEND_ROW:
1729 case LyXTabular::APPEND_COLUMN:
1730 case LyXTabular::DELETE_ROW:
1731 case LyXTabular::DELETE_COLUMN:
1732 case LyXTabular::SET_ALL_LINES:
1733 case LyXTabular::UNSET_ALL_LINES:
1734 status |= LyXFunc::OK;
1737 case LyXTabular::MULTICOLUMN:
1738 if (tabular->IsMultiColumn(actcell))
1739 status |= LyXFunc::ToggleOn;
1741 status |= LyXFunc::ToggleOff;
1743 case LyXTabular::M_TOGGLE_LINE_TOP:
1745 case LyXTabular::TOGGLE_LINE_TOP:
1746 if (tabular->TopLine(actcell, flag))
1747 status |= LyXFunc::ToggleOn;
1749 status |= LyXFunc::ToggleOff;
1751 case LyXTabular::M_TOGGLE_LINE_BOTTOM:
1753 case LyXTabular::TOGGLE_LINE_BOTTOM:
1754 if (tabular->BottomLine(actcell, flag))
1755 status |= LyXFunc::ToggleOn;
1757 status |= LyXFunc::ToggleOff;
1759 case LyXTabular::M_TOGGLE_LINE_LEFT:
1761 case LyXTabular::TOGGLE_LINE_LEFT:
1762 if (tabular->LeftLine(actcell, flag))
1763 status |= LyXFunc::ToggleOn;
1765 status |= LyXFunc::ToggleOff;
1767 case LyXTabular::M_TOGGLE_LINE_RIGHT:
1769 case LyXTabular::TOGGLE_LINE_RIGHT:
1770 if (tabular->RightLine(actcell, flag))
1771 status |= LyXFunc::ToggleOn;
1773 status |= LyXFunc::ToggleOff;
1775 case LyXTabular::M_ALIGN_LEFT:
1777 case LyXTabular::ALIGN_LEFT:
1778 if (tabular->GetAlignment(actcell, flag) == LYX_ALIGN_LEFT)
1779 status |= LyXFunc::ToggleOn;
1781 status |= LyXFunc::ToggleOff;
1783 case LyXTabular::M_ALIGN_RIGHT:
1785 case LyXTabular::ALIGN_RIGHT:
1786 if (tabular->GetAlignment(actcell, flag) == LYX_ALIGN_RIGHT)
1787 status |= LyXFunc::ToggleOn;
1789 status |= LyXFunc::ToggleOff;
1791 case LyXTabular::M_ALIGN_CENTER:
1793 case LyXTabular::ALIGN_CENTER:
1794 if (tabular->GetAlignment(actcell, flag) == LYX_ALIGN_CENTER)
1795 status |= LyXFunc::ToggleOn;
1797 status |= LyXFunc::ToggleOff;
1799 case LyXTabular::M_VALIGN_TOP:
1801 case LyXTabular::VALIGN_TOP:
1802 if (tabular->GetVAlignment(actcell, flag) == LyXTabular::LYX_VALIGN_TOP)
1803 status |= LyXFunc::ToggleOn;
1805 status |= LyXFunc::ToggleOff;
1807 case LyXTabular::M_VALIGN_BOTTOM:
1809 case LyXTabular::VALIGN_BOTTOM:
1810 if (tabular->GetVAlignment(actcell, flag) == LyXTabular::LYX_VALIGN_BOTTOM)
1811 status |= LyXFunc::ToggleOn;
1813 status |= LyXFunc::ToggleOff;
1815 case LyXTabular::M_VALIGN_CENTER:
1817 case LyXTabular::VALIGN_CENTER:
1818 if (tabular->GetVAlignment(actcell, flag) == LyXTabular::LYX_VALIGN_CENTER)
1819 status |= LyXFunc::ToggleOn;
1821 status |= LyXFunc::ToggleOff;
1823 case LyXTabular::SET_LONGTABULAR:
1824 if (tabular->IsLongTabular())
1825 status |= LyXFunc::ToggleOn;
1827 status |= LyXFunc::ToggleOff;
1829 case LyXTabular::UNSET_LONGTABULAR:
1830 if (!tabular->IsLongTabular())
1831 status |= LyXFunc::ToggleOn;
1833 status |= LyXFunc::ToggleOff;
1835 case LyXTabular::SET_ROTATE_TABULAR:
1836 if (tabular->GetRotateTabular())
1837 status |= LyXFunc::ToggleOn;
1839 status |= LyXFunc::ToggleOff;
1841 case LyXTabular::UNSET_ROTATE_TABULAR:
1842 if (!tabular->GetRotateTabular())
1843 status |= LyXFunc::ToggleOn;
1845 status |= LyXFunc::ToggleOff;
1847 case LyXTabular::SET_ROTATE_CELL:
1848 if (tabular->GetRotateCell(actcell))
1849 status |= LyXFunc::ToggleOn;
1851 status |= LyXFunc::ToggleOff;
1853 case LyXTabular::UNSET_ROTATE_CELL:
1854 if (!tabular->GetRotateCell(actcell))
1855 status |= LyXFunc::ToggleOn;
1857 status |= LyXFunc::ToggleOff;
1859 case LyXTabular::SET_USEBOX:
1860 if (strToInt(argument) == tabular->GetUsebox(actcell))
1861 status |= LyXFunc::ToggleOn;
1863 status |= LyXFunc::ToggleOff;
1865 case LyXTabular::SET_LTFIRSTHEAD:
1866 if (tabular->GetRowOfLTHead(actcell, dummy))
1867 status |= LyXFunc::ToggleOn;
1869 status |= LyXFunc::ToggleOff;
1871 case LyXTabular::SET_LTHEAD:
1872 if (tabular->GetRowOfLTHead(actcell, dummy))
1873 status |= LyXFunc::ToggleOn;
1875 status |= LyXFunc::ToggleOff;
1877 case LyXTabular::SET_LTFOOT:
1878 if (tabular->GetRowOfLTFoot(actcell, dummy))
1879 status |= LyXFunc::ToggleOn;
1881 status |= LyXFunc::ToggleOff;
1883 case LyXTabular::SET_LTLASTFOOT:
1884 if (tabular->GetRowOfLTFoot(actcell, dummy))
1885 status |= LyXFunc::ToggleOn;
1887 status |= LyXFunc::ToggleOff;
1889 case LyXTabular::SET_LTNEWPAGE:
1890 if (tabular->GetLTNewPage(actcell))
1891 status |= LyXFunc::ToggleOn;
1893 status |= LyXFunc::ToggleOff;
1896 status = LyXFunc::Disabled;
1903 bool InsetTabular::copySelection(BufferView * bv)
1905 if (!hasSelection())
1907 delete paste_tabular;
1909 int sel_col_start, sel_col_end;
1910 int sel_row_start, sel_row_end;
1912 sel_col_start = tabular->column_of_cell(sel_cell_start);
1913 sel_col_end = tabular->column_of_cell(sel_cell_end);
1914 if (sel_col_start > sel_col_end) {
1915 sel_col_start = sel_col_end;
1916 sel_col_end = tabular->right_column_of_cell(sel_cell_start);
1918 sel_col_end = tabular->right_column_of_cell(sel_cell_end);
1920 int columns = sel_col_end - sel_col_start + 1;
1922 sel_row_start = tabular->row_of_cell(sel_cell_start);
1923 sel_row_end = tabular->row_of_cell(sel_cell_end);
1924 if (sel_row_start > sel_row_end) {
1925 //int tmp tmp = sel_row_start;
1926 //sel_row_start = sel_row_end;
1927 //sel_row_end = tmp;
1928 swap(sel_row_start, sel_row_end);
1930 int rows = sel_row_end - sel_row_start + 1;
1932 paste_tabular = new LyXTabular(this, *tabular); // rows, columns);
1934 for(i=0; i < sel_row_start; ++i)
1935 paste_tabular->DeleteRow(0);
1936 while(paste_tabular->rows() > rows)
1937 paste_tabular->DeleteRow(rows);
1938 paste_tabular->SetTopLine(0, true, true);
1939 paste_tabular->SetBottomLine(paste_tabular->GetFirstCellInRow(rows-1),
1941 for(i=0; i < sel_col_start; ++i)
1942 paste_tabular->DeleteColumn(0);
1943 while(paste_tabular->columns() > columns)
1944 paste_tabular->DeleteColumn(columns);
1945 paste_tabular->SetLeftLine(0, true, true);
1946 paste_tabular->SetRightLine(paste_tabular->GetLastCellInRow(0),true, true);
1949 paste_tabular->Ascii(bv->buffer(), sstr);
1950 bv->stuffClipboard(sstr.str());
1955 bool InsetTabular::pasteSelection(BufferView * bv)
1959 for(int j=0, i=actcell; j<paste_tabular->GetNumberOfCells(); ++j,++i) {
1960 while (paste_tabular->row_of_cell(j) > tabular->row_of_cell(i)-actrow)
1962 if (tabular->GetNumberOfCells() <= i)
1964 while (paste_tabular->row_of_cell(j) < tabular->row_of_cell(i)-actrow)
1966 if (paste_tabular->GetNumberOfCells() <= j)
1968 *(tabular->GetCellInset(i)) = *(paste_tabular->GetCellInset(j));
1969 tabular->GetCellInset(i)->setOwner(this);
1970 tabular->GetCellInset(i)->deleteLyXText(bv);
1976 bool InsetTabular::cutSelection()
1978 if (!hasSelection())
1981 int sel_col_start, sel_col_end;
1982 int sel_row_start, sel_row_end;
1984 sel_col_start = tabular->column_of_cell(sel_cell_start);
1985 sel_col_end = tabular->column_of_cell(sel_cell_end);
1986 if (sel_col_start > sel_col_end) {
1987 sel_col_start = sel_col_end;
1988 sel_col_end = tabular->right_column_of_cell(sel_cell_start);
1990 sel_col_end = tabular->right_column_of_cell(sel_cell_end);
1992 sel_row_start = tabular->row_of_cell(sel_cell_start);
1993 sel_row_end = tabular->row_of_cell(sel_cell_end);
1994 if (sel_row_start > sel_row_end) {
1995 //int tmp = sel_row_start;
1996 //sel_row_start = sel_row_end;
1997 //sel_row_end = tmp;
1998 swap(sel_row_start, sel_row_end);
2000 if (sel_cell_start > sel_cell_end) {
2001 //int tmp = sel_cell_start;
2002 //sel_cell_start = sel_cell_end;
2003 //sel_cell_end = tmp;
2004 swap(sel_cell_start, sel_cell_end);
2006 for(int i = sel_row_start; i <= sel_row_end; ++i) {
2007 for(int j = sel_col_start; j <= sel_col_end; ++j) {
2008 tabular->GetCellInset(tabular->GetCellNumber(i, j))->clear();