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"
52 const int ADD_TO_HEIGHT = 2;
53 const int ADD_TO_TABULAR_WIDTH = 2;
55 LyXTabular * paste_tabular = 0;
58 struct tabular_features {
59 LyXTabular::Feature action;
63 //tabular_features * tabularFeatures = 0;
65 tabular_features tabularFeatures[] =
67 { LyXTabular::APPEND_ROW, "append-row" },
68 { LyXTabular::APPEND_COLUMN, "append-column" },
69 { LyXTabular::DELETE_ROW, "delete-row" },
70 { LyXTabular::DELETE_COLUMN, "delete-column" },
71 { LyXTabular::TOGGLE_LINE_TOP, "toggle-line-top" },
72 { LyXTabular::TOGGLE_LINE_BOTTOM, "toggle-line-bottom" },
73 { LyXTabular::TOGGLE_LINE_LEFT, "toggle-line-left" },
74 { LyXTabular::TOGGLE_LINE_RIGHT, "toggle-line-right" },
75 { LyXTabular::ALIGN_LEFT, "align-left" },
76 { LyXTabular::ALIGN_RIGHT, "align-right" },
77 { LyXTabular::ALIGN_CENTER, "align-center" },
78 { LyXTabular::VALIGN_TOP, "valign-top" },
79 { LyXTabular::VALIGN_BOTTOM, "valign-bottom" },
80 { LyXTabular::VALIGN_CENTER, "valign-center" },
81 { LyXTabular::M_TOGGLE_LINE_TOP, "m-toggle-line-top" },
82 { LyXTabular::M_TOGGLE_LINE_BOTTOM, "m-toggle-line-bottom" },
83 { LyXTabular::M_TOGGLE_LINE_LEFT, "m-toggle-line-left" },
84 { LyXTabular::M_TOGGLE_LINE_RIGHT, "m-toggle-line-right" },
85 { LyXTabular::M_ALIGN_LEFT, "m-align-left" },
86 { LyXTabular::M_ALIGN_RIGHT, "m-align-right" },
87 { LyXTabular::M_ALIGN_CENTER, "m-align-center" },
88 { LyXTabular::M_VALIGN_TOP, "m-valign-top" },
89 { LyXTabular::M_VALIGN_BOTTOM, "m-valign-bottom" },
90 { LyXTabular::M_VALIGN_CENTER, "m-valign-center" },
91 { LyXTabular::MULTICOLUMN, "multicolumn" },
92 { LyXTabular::SET_ALL_LINES, "set-all-lines" },
93 { LyXTabular::UNSET_ALL_LINES, "unset-all-lines" },
94 { LyXTabular::SET_LONGTABULAR, "set-longtabular" },
95 { LyXTabular::UNSET_LONGTABULAR, "unset-longtabular" },
96 { LyXTabular::SET_PWIDTH, "set-pwidth" },
97 { LyXTabular::SET_MPWIDTH, "set-mpwidth" },
98 { LyXTabular::SET_ROTATE_TABULAR, "set-rotate-tabular" },
99 { LyXTabular::UNSET_ROTATE_TABULAR, "unset-rotate-tabular" },
100 { LyXTabular::SET_ROTATE_CELL, "set-rotate-cell" },
101 { LyXTabular::UNSET_ROTATE_CELL, "unset-rotate-cell" },
102 { LyXTabular::SET_USEBOX, "set-usebox" },
103 { LyXTabular::SET_LTHEAD, "set-lthead" },
104 { LyXTabular::SET_LTFIRSTHEAD, "set-ltfirsthead" },
105 { LyXTabular::SET_LTFOOT, "set-ltfoot" },
106 { LyXTabular::SET_LTLASTFOOT, "set-ltlastfoot" },
107 { LyXTabular::SET_LTNEWPAGE, "set-ltnewpage" },
108 { LyXTabular::SET_SPECIAL_COLUMN, "set-special-column" },
109 { LyXTabular::SET_SPECIAL_MULTI, "set-special-multi" },
110 { LyXTabular::LAST_ACTION, "" }
116 bool InsetTabular::hasPasteBuffer() const
118 return (paste_tabular != 0);
122 InsetTabular::InsetTabular(Buffer const & buf, int rows, int columns)
129 //tabular = new LyXTabular(this, rows,columns);
130 tabular.reset(new LyXTabular(this, rows,columns));
131 // for now make it always display as display() inset
133 the_locking_inset = 0;
134 locked = no_selection = false;
136 cursor_visible = false;
139 actrow = actcell = 0;
146 InsetTabular::InsetTabular(InsetTabular const & tab, Buffer const & buf)
149 //tabular = new LyXTabular(this, *(tab.tabular));
150 tabular.reset(new LyXTabular(this, *(tab.tabular)));
151 the_locking_inset = 0;
152 locked = no_selection = false;
154 cursor_visible = false;
157 actrow = actcell = 0;
158 sel_cell_start = sel_cell_end = 0;
164 InsetTabular::~InsetTabular()
171 Inset * InsetTabular::Clone(Buffer const & buf) const
173 InsetTabular * t = new InsetTabular(*this, buf);
175 //t->tabular = tabular->Clone(t);
176 t->tabular.reset(tabular->Clone(t));
181 void InsetTabular::Write(Buffer const * buf, ostream & os) const
183 os << " Tabular" << endl;
184 tabular->Write(buf, os);
188 void InsetTabular::Read(Buffer const * buf, LyXLex & lex)
190 bool const old_format = (lex.GetString() == "\\LyXTable");
194 //tabular = new LyXTabular(buf, this, lex);
195 tabular.reset(new LyXTabular(buf, this, lex));
203 string token = lex.GetString();
204 while (lex.IsOK() && (token != "\\end_inset")) {
206 token = lex.GetString();
208 if (token != "\\end_inset") {
209 lex.printError("Missing \\end_inset at this point. "
215 int InsetTabular::ascent(BufferView *, LyXFont const &) const
217 return tabular->GetAscentOfRow(0);
221 int InsetTabular::descent(BufferView *, LyXFont const &) const
223 return tabular->GetHeightOfTabular() - tabular->GetAscentOfRow(0) + 1;
227 int InsetTabular::width(BufferView *, LyXFont const &) const
229 return tabular->GetWidthOfTabular() + (2 * ADD_TO_TABULAR_WIDTH);
233 void InsetTabular::draw(BufferView * bv, LyXFont const & font, int baseline,
234 float & x, bool cleared) const
239 Painter & pain = bv->painter();
244 UpdatableInset::draw(bv, font, baseline, x, cleared);
245 if (!cleared && ((need_update == INIT) || (need_update == FULL) ||
246 (top_x != int(x)) || (top_baseline != baseline))) {
247 int h = ascent(bv, font) + descent(bv, font);
248 int const tx = display() || !owner() ? 0 : top_x;
249 int w = tx ? width(bv, font) : pain.paperWidth();
250 int ty = baseline - ascent(bv, font);
254 if ((ty + h) > pain.paperHeight())
255 h = pain.paperHeight();
256 if ((top_x + w) > pain.paperWidth())
257 w = pain.paperWidth();
258 pain.fillRectangle(tx, ty, w, h);
263 top_baseline = baseline;
264 if (bv->text->status == LyXText::CHANGED_IN_DRAW)
267 x += ADD_TO_TABULAR_WIDTH;
271 first_visible_cell = -1;
272 for (i = 0; i < tabular->rows(); ++i) {
274 dodraw = ((baseline + tabular->GetDescentOfRow(i)) > 0) &&
275 (baseline - tabular->GetAscentOfRow(i))<pain.paperHeight();
276 for (j = 0; j < tabular->columns(); ++j) {
277 if (tabular->IsPartOfMultiColumn(i, j))
279 cx = nx + tabular->GetBeginningOfTextInCell(cell);
281 if (first_visible_cell < 0)
282 first_visible_cell = cell;
284 DrawCellSelection(pain, nx, baseline, i, j, cell);
285 tabular->GetCellInset(cell)->draw(bv, font, baseline, cx,
287 DrawCellLines(pain, nx, baseline, i, cell);
289 nx += tabular->GetWidthOfColumn(cell);
292 baseline += tabular->GetDescentOfRow(i) +
293 tabular->GetAscentOfRow(i + 1) +
294 tabular->GetAdditionalHeight(cell);
296 } else if (need_update == CELL) {
299 if (the_locking_inset) {
300 Inset * inset = tabular->GetCellInset(cell);
302 inset != the_locking_inset && i < tabular->rows();
305 inset != the_locking_inset
306 && j < tabular->columns();
308 if (tabular->IsPartOfMultiColumn(i, j))
310 nx += tabular->GetWidthOfColumn(cell);
312 inset = tabular->GetCellInset(cell);
314 if (tabular->row_of_cell(cell) > i) {
316 baseline += tabular->GetDescentOfRow(i) +
317 tabular->GetAscentOfRow(i + 1) +
318 tabular->GetAdditionalHeight(cell);
323 cell < actcell && i < tabular->rows(); ++i) {
324 for (j = 0; (cell < actcell) && (j < tabular->columns()); ++j) {
325 if (tabular->IsPartOfMultiColumn(i, j))
327 nx += tabular->GetWidthOfColumn(cell);
330 if (tabular->row_of_cell(cell) > i) {
332 baseline += tabular->GetDescentOfRow(i) +
333 tabular->GetAscentOfRow(i + 1) +
334 tabular->GetAdditionalHeight(cell);
338 i = tabular->row_of_cell(cell);
339 if (the_locking_inset != tabular->GetCellInset(cell)) {
340 lyxerr[Debug::INSETS] << "ERROR this shouldn't happen\n";
343 float dx = nx + tabular->GetBeginningOfTextInCell(cell);
345 //cx = dx = nx + tabular->GetBeginningOfTextInCell(cell);
346 tabular->GetCellInset(cell)->draw(bv,font,baseline, dx, false);
347 if (bv->text->status == LyXText::CHANGED_IN_DRAW)
349 // clear only if we didn't have a change
350 if (need_update == CELL) {
351 // clear before the inset
354 baseline - tabular->GetAscentOfRow(i) + 1,
356 tabular->GetAscentOfRow(i) +
357 tabular->GetDescentOfRow(i) - 1);
358 // clear behind the inset
360 int(cx + the_locking_inset->width(bv,font) + 1),
361 baseline - tabular->GetAscentOfRow(i) + 1,
362 tabular->GetWidthOfColumn(cell) -
363 tabular->GetBeginningOfTextInCell(cell) -
364 the_locking_inset->width(bv,font) -
365 tabular->GetAdditionalWidth(cell) - 1,
366 tabular->GetAscentOfRow(i) +
367 tabular->GetDescentOfRow(i) - 1);
370 x -= ADD_TO_TABULAR_WIDTH;
371 x += width(bv, font);
372 if (bv->text->status == LyXText::CHANGED_IN_DRAW)
379 void InsetTabular::DrawCellLines(Painter & pain, int x, int baseline,
380 int row, int cell) const
382 int x2 = x + tabular->GetWidthOfColumn(cell);
385 if (!tabular->TopAlreadyDrawed(cell)) {
386 on_off = !tabular->TopLine(cell);
387 pain.line(x, baseline - tabular->GetAscentOfRow(row),
388 x2, baseline - tabular->GetAscentOfRow(row),
389 on_off ? LColor::tabularonoffline : LColor::tabularline,
390 on_off ? Painter::line_onoffdash : Painter::line_solid);
392 on_off = !tabular->BottomLine(cell);
393 pain.line(x,baseline + tabular->GetDescentOfRow(row),
394 x2, baseline + tabular->GetDescentOfRow(row),
395 on_off ? LColor::tabularonoffline : LColor::tabularline,
396 on_off ? Painter::line_onoffdash : Painter::line_solid);
397 if (!tabular->LeftAlreadyDrawed(cell)) {
398 on_off = !tabular->LeftLine(cell);
399 pain.line(x, baseline - tabular->GetAscentOfRow(row),
400 x, baseline + tabular->GetDescentOfRow(row),
401 on_off ? LColor::tabularonoffline : LColor::tabularline,
402 on_off ? Painter::line_onoffdash : Painter::line_solid);
404 on_off = !tabular->RightLine(cell);
405 pain.line(x2 - tabular->GetAdditionalWidth(cell),
406 baseline - tabular->GetAscentOfRow(row),
407 x2 - tabular->GetAdditionalWidth(cell),
408 baseline + tabular->GetDescentOfRow(row),
409 on_off ? LColor::tabularonoffline : LColor::tabularline,
410 on_off ? Painter::line_onoffdash : Painter::line_solid);
414 void InsetTabular::DrawCellSelection(Painter & pain, int x, int baseline,
415 int row, int column, int cell) const
417 int cs = tabular->column_of_cell(sel_cell_start);
418 int ce = tabular->column_of_cell(sel_cell_end);
421 cs = tabular->column_of_cell(sel_cell_end);
423 ce = tabular->right_column_of_cell(sel_cell_end);
426 int rs = tabular->row_of_cell(sel_cell_start);
427 int re = tabular->row_of_cell(sel_cell_end);
428 if (rs > re) swap(rs, re);
430 if ((column >= cs) && (column <= ce) && (row >= rs) && (row <= re)) {
431 int w = tabular->GetWidthOfColumn(cell);
432 int h = tabular->GetAscentOfRow(row) + tabular->GetDescentOfRow(row);
433 pain.fillRectangle(x, baseline - tabular->GetAscentOfRow(row),
434 w, h, LColor::selection);
439 void InsetTabular::update(BufferView * bv, LyXFont const & font, bool reinit)
443 calculate_dimensions_of_cells(bv, font, true);
445 owner()->update(bv, font, true);
448 if (the_locking_inset) {
449 the_locking_inset->update(bv, font, reinit);
451 // inset_x = cursor.x() - top_x + tabular->GetBeginningOfTextInCell(actcell);
452 // inset_y = cursor.y();
454 switch (need_update) {
458 if (calculate_dimensions_of_cells(bv, font, false))
470 string const InsetTabular::EditMessage() const
472 return _("Opened Tabular Inset");
476 void InsetTabular::Edit(BufferView * bv, int x, int y, unsigned int button)
478 UpdatableInset::Edit(bv, x, y, button);
480 if (!bv->lockInset(this)) {
481 lyxerr[Debug::INSETS] << "InsetTabular::Cannot lock inset" << endl;
485 the_locking_inset = 0;
489 sel_cell_start = sel_cell_end = actcell;
490 bv->text->FinishUndo();
491 if (InsetHit(bv, x, y) && (button != 3)) {
492 ActivateCellInsetAbs(bv, x, y, button);
494 // UpdateLocal(bv, NONE, false);
495 // bv->getOwner()->getPopups().updateFormTabular();
499 void InsetTabular::InsetUnlock(BufferView * bv)
501 if (the_locking_inset) {
502 the_locking_inset->InsetUnlock(bv);
503 the_locking_inset = 0;
506 no_selection = false;
509 if (scroll() || hasSelection()) {
510 sel_cell_start = sel_cell_end = 0;
514 UpdateLocal(bv, FULL, false);
519 void InsetTabular::UpdateLocal(BufferView * bv, UpdateCodes what,
520 bool mark_dirty) const
522 if (need_update < what) // only set this if it has greater update
524 if ((what == INIT) && hasSelection())
527 if (need_update != NONE) {
528 bv->updateInset(const_cast<InsetTabular *>(this), mark_dirty);
529 if (locked) // && (what != NONE))
535 bool InsetTabular::LockInsetInInset(BufferView * bv, UpdatableInset * inset)
537 lyxerr[Debug::INSETS] << "InsetTabular::LockInsetInInset("
542 if (inset == tabular->GetCellInset(actcell)) {
543 lyxerr[Debug::INSETS] << "OK" << endl;
544 the_locking_inset = tabular->GetCellInset(actcell);
546 inset_x = cursor.x() - top_x + tabular->GetBeginningOfTextInCell(actcell);
547 inset_y = cursor.y();
549 } else if (the_locking_inset && (the_locking_inset == inset)) {
550 lyxerr[Debug::INSETS] << "OK" << endl;
552 inset_x = cursor.x() - top_x + tabular->GetBeginningOfTextInCell(actcell);
553 inset_y = cursor.y();
554 } else if (the_locking_inset) {
555 lyxerr[Debug::INSETS] << "MAYBE" << endl;
556 return the_locking_inset->LockInsetInInset(bv, inset);
558 lyxerr[Debug::INSETS] << "NOT OK" << endl;
563 bool InsetTabular::UnlockInsetInInset(BufferView * bv, UpdatableInset * inset,
566 if (!the_locking_inset)
568 if (the_locking_inset == inset) {
569 the_locking_inset->InsetUnlock(bv);
570 the_locking_inset = 0;
571 UpdateLocal(bv, CELL, false);
572 ShowInsetCursor(bv, false);
575 if (the_locking_inset->UnlockInsetInInset(bv, inset, lr)) {
576 if (inset->LyxCode() == TABULAR_CODE &&
577 !the_locking_inset->GetFirstLockingInsetOfType(TABULAR_CODE)) {
578 bv->owner()->getDialogs()->updateTabular(this);
587 bool InsetTabular::UpdateInsetInInset(BufferView * bv, Inset * inset)
589 if (!the_locking_inset)
591 if (the_locking_inset != inset) {
592 if (!the_locking_inset->UpdateInsetInInset(bv, inset))
595 UpdateLocal(bv, CELL, false);
600 unsigned int InsetTabular::InsetInInsetY()
602 if (!the_locking_inset)
605 return inset_y + the_locking_inset->InsetInInsetY();
609 UpdatableInset * InsetTabular::GetLockingInset()
611 return the_locking_inset ? the_locking_inset->GetLockingInset() : this;
615 UpdatableInset * InsetTabular::GetFirstLockingInsetOfType(Inset::Code c)
619 if (the_locking_inset)
620 return the_locking_inset->GetFirstLockingInsetOfType(c);
625 bool InsetTabular::InsertInset(BufferView * bv, Inset * inset)
627 if (the_locking_inset)
628 return the_locking_inset->InsertInset(bv, inset);
633 void InsetTabular::InsetButtonPress(BufferView * bv, int x, int y, int button)
635 if (hasSelection() && (button == 3))
638 if (hasSelection()) {
640 UpdateLocal(bv, SELECTION, false);
643 no_selection = false;
645 int const ocell = actcell;
646 int const orow = actrow;
651 UpdateLocal(bv, NONE, false);
652 sel_cell_start = sel_cell_end = actcell;
654 if ((ocell != actcell) && the_locking_inset) {
655 the_locking_inset->InsetUnlock(bv);
656 the_locking_inset = 0;
662 bool const inset_hit = InsetHit(bv, x, y);
664 if ((ocell == actcell) && the_locking_inset && inset_hit) {
666 the_locking_inset->InsetButtonPress(bv,
667 x - inset_x, y - inset_y,
670 } else if (the_locking_inset) {
671 the_locking_inset->InsetUnlock(bv);
673 the_locking_inset = 0;
675 LocalDispatch(bv, LFUN_PASTESELECTION, "paragraph");
678 if (inset_hit && bv->theLockingInset()) {
679 if (ActivateCellInsetAbs(bv, x, y, button))
680 the_locking_inset->InsetButtonPress(bv,
690 void InsetTabular::InsetButtonRelease(BufferView * bv,
691 int x, int y, int button)
694 if (the_locking_inset) {
696 if ((i=the_locking_inset->GetFirstLockingInsetOfType(TABULAR_CODE))) {
697 i->InsetButtonRelease(bv, x, y, button);
701 bv->owner()->getDialogs()->showTabular(this);
704 if (the_locking_inset) {
705 the_locking_inset->InsetButtonRelease(bv,
706 x - inset_x, y - inset_y,
710 no_selection = false;
714 void InsetTabular::InsetMotionNotify(BufferView * bv, int x, int y, int button)
716 if (the_locking_inset) {
717 the_locking_inset->InsetMotionNotify(bv,
725 int const old_cell = actcell;
728 sel_cell_end = actcell;
729 if (sel_cell_end != old_cell)
730 UpdateLocal(bv, SELECTION, false);
733 no_selection = false;
737 void InsetTabular::InsetKeyPress(XKeyEvent * xke)
739 if (the_locking_inset) {
740 the_locking_inset->InsetKeyPress(xke);
746 UpdatableInset::RESULT
747 InsetTabular::LocalDispatch(BufferView * bv,
751 // We need to save the value of the_locking_inset as the call to
752 // the_locking_inset->LocalDispatch might unlock it.
753 old_locking_inset = the_locking_inset;
754 no_selection = false;
755 UpdatableInset::RESULT result =
756 UpdatableInset::LocalDispatch(bv, action, arg);
757 if (result == DISPATCHED || result == DISPATCHED_NOUPDATE) {
762 if ((action < 0) && arg.empty())
765 bool hs = hasSelection();
768 // this one have priority over the locked InsetText!
774 if (the_locking_inset) {
775 UnlockInsetInInset(bv, the_locking_inset);
776 the_locking_inset = 0;
778 if (action == LFUN_TAB)
779 moveNextCell(bv, old_locking_inset != 0);
781 movePrevCell(bv, old_locking_inset != 0);
782 sel_cell_start = sel_cell_end = actcell;
784 UpdateLocal(bv, SELECTION, false);
788 // this to avoid compiler warnings.
793 if (the_locking_inset) {
794 result=the_locking_inset->LocalDispatch(bv, action, arg);
795 if (result == DISPATCHED_NOUPDATE) {
798 if (sc != scroll()) { // inset has been scrolled
799 the_locking_inset->ToggleInsetCursor(bv);
800 UpdateLocal(bv, FULL, false);
801 the_locking_inset->ToggleInsetCursor(bv);
804 } else if (result == DISPATCHED) {
805 the_locking_inset->ToggleInsetCursor(bv);
806 UpdateLocal(bv, CELL, false);
807 the_locking_inset->ToggleInsetCursor(bv);
809 } else if (result == FINISHED) {
816 // --- Cursor Movements ----------------------------------
818 if (tabular->IsLastCellInRow(actcell))
820 moveRight(bv, false);
821 sel_cell_end = actcell;
822 UpdateLocal(bv, SELECTION, false);
825 result = moveRight(bv);
826 sel_cell_start = sel_cell_end = actcell;
828 UpdateLocal(bv, SELECTION, false);
831 if (tabular->IsFirstCellInRow(actcell))
834 sel_cell_end = actcell;
835 UpdateLocal(bv, SELECTION, false);
838 result = moveLeft(bv);
839 sel_cell_start = sel_cell_end = actcell;
841 UpdateLocal(bv, SELECTION, false);
845 int const ocell = actcell;
847 if ((ocell == sel_cell_end) ||
848 (tabular->column_of_cell(ocell)>tabular->column_of_cell(actcell)))
849 sel_cell_end = tabular->GetCellBelow(sel_cell_end);
851 sel_cell_end = tabular->GetLastCellBelow(sel_cell_end);
852 UpdateLocal(bv, SELECTION, false);
856 result = moveDown(bv, old_locking_inset != 0);
857 sel_cell_start = sel_cell_end = actcell;
859 UpdateLocal(bv, SELECTION, false);
863 int const ocell = actcell;
865 if ((ocell == sel_cell_end) ||
866 (tabular->column_of_cell(ocell)>tabular->column_of_cell(actcell)))
867 sel_cell_end = tabular->GetCellAbove(sel_cell_end);
869 sel_cell_end = tabular->GetLastCellAbove(sel_cell_end);
870 UpdateLocal(bv, SELECTION, false);
874 result = moveUp(bv, old_locking_inset != 0);
875 sel_cell_start = sel_cell_end = actcell;
877 UpdateLocal(bv, SELECTION, false);
881 if (the_locking_inset) {
882 UnlockInsetInInset(bv, the_locking_inset);
883 the_locking_inset = 0;
885 if (bv->text->first + bv->painter().paperHeight() <
886 (top_baseline + tabular->GetHeightOfTabular()))
888 bv->scrollCB(bv->text->first + bv->painter().paperHeight());
889 UpdateLocal(bv, FULL, false);
890 actcell = tabular->GetCellBelow(first_visible_cell) + column;
892 actcell = tabular->GetFirstCellInRow(tabular->rows() - 1) + column;
895 UpdateLocal(bv, CURSOR, false);
900 if (the_locking_inset) {
901 UnlockInsetInInset(bv, the_locking_inset);
902 the_locking_inset = 0;
904 if (top_baseline < 0) {
905 bv->scrollCB(bv->text->first - bv->painter().paperHeight());
906 UpdateLocal(bv, FULL, false);
907 if (top_baseline > 0)
910 actcell = tabular->GetCellBelow(first_visible_cell) + column;
915 UpdateLocal(bv, CURSOR, false);
926 case LFUN_LAYOUT_TABULAR:
928 bv->owner()->getDialogs()->showTabular(this);
931 case LFUN_TABULAR_FEATURE:
932 if (!TabularFeatures(bv, arg))
933 result = UNDISPATCHED;
936 if (!copySelection(bv))
938 bv->text->SetUndo(bv->buffer(), Undo::DELETE,
940 bv->text->cursor.par()->ParFromPos(bv->text->cursor.pos())->previous_,
941 bv->text->cursor.par()->ParFromPos(bv->text->cursor.pos())->next_
943 bv->text->cursor.par()->previous(),
944 bv->text->cursor.par()->next()
948 UpdateLocal(bv, INIT, true);
953 bv->text->FinishUndo();
956 case LFUN_PASTESELECTION:
958 string clip(bv->workarea()->getClipboard());
962 if (clip.find('\t') != string::npos) {
966 unsigned int len = clip.length();
967 string::size_type p = 0;
970 ((p = clip.find_first_of("\t\n", p)) != string::npos)) {
978 maxCols = max(cols, maxCols);
984 maxCols = max(cols, maxCols);
985 delete paste_tabular;
986 paste_tabular = new LyXTabular(this, rows, maxCols);
987 string::size_type op = 0;
989 int cells = paste_tabular->GetNumberOfCells();
991 while((cell < cells) && (p < len) &&
992 (p = clip.find_first_of("\t\n", p)) != string::npos) {
997 paste_tabular->GetCellInset(cell)->SetText(clip.substr(op, p-op));
1002 paste_tabular->GetCellInset(cell)->SetText(clip.substr(op, p-op));
1003 while(cols++ < maxCols)
1011 // check for the last cell if there is no trailing '\n'
1012 if ((cell < cells) && (op < len))
1013 paste_tabular->GetCellInset(cell)->SetText(clip.substr(op, len-op));
1015 // so that the clipboard is used and it goes on
1017 // and executes LFUN_PASTESELECTION in insettext!
1018 delete paste_tabular;
1023 if (hasPasteBuffer()) {
1024 bv->text->SetUndo(bv->buffer(), Undo::INSERT,
1026 bv->text->cursor.par()->ParFromPos(bv->text->cursor.pos())->previous_,
1027 bv->text->cursor.par()->ParFromPos(bv->text->cursor.pos())->next_
1029 bv->text->cursor.par()->previous(),
1030 bv->text->cursor.par()->next()
1034 UpdateLocal(bv, INIT, true);
1037 // ATTENTION: the function above has to be PASTE and PASTESELECTION!!!
1039 // we try to activate the actual inset and put this event down to
1040 // the insets dispatch function.
1041 result = UNDISPATCHED;
1042 if (the_locking_inset)
1045 if (ActivateCellInset(bv)) {
1046 result = the_locking_inset->LocalDispatch(bv, action, arg);
1047 if ((result == UNDISPATCHED) || (result == FINISHED)) {
1048 UnlockInsetInInset(bv, the_locking_inset);
1050 the_locking_inset = 0;
1051 return UNDISPATCHED;
1054 the_locking_inset->ToggleInsetCursor(bv);
1055 UpdateLocal(bv, CELL, false);
1056 the_locking_inset->ToggleInsetCursor(bv);
1061 if (result!=FINISHED) {
1062 if (!the_locking_inset) {
1063 ShowInsetCursor(bv);
1066 bv->unlockInset(this);
1071 int InsetTabular::Latex(Buffer const * buf, ostream & os,
1072 bool fragile, bool fp) const
1074 return tabular->Latex(buf, os, fragile, fp);
1078 int InsetTabular::Ascii(Buffer const * buf, ostream & os, int) const
1080 // This should be changed to a real ascii export
1081 return tabular->Ascii(buf, os);
1085 int InsetTabular::Linuxdoc(Buffer const *, ostream &) const
1091 int InsetTabular::DocBook(Buffer const * buf, ostream & os) const
1093 return tabular->DocBook(buf,os);
1097 void InsetTabular::Validate(LaTeXFeatures & features) const
1099 tabular->Validate(features);
1103 bool InsetTabular::calculate_dimensions_of_cells(BufferView * bv,
1104 LyXFont const & font,
1111 bool changed = false;
1113 // if we have a locking_inset we should have to check only this cell for
1114 // change so I'll try this to have a boost, but who knows ;)
1115 if ((need_update != INIT) &&
1116 (the_locking_inset == tabular->GetCellInset(actcell))) {
1117 for(int i = 0; i < tabular->columns(); ++i) {
1118 maxAsc = max(tabular->GetCellInset(actrow, i)->ascent(bv, font),
1120 maxDesc = max(tabular->GetCellInset(actrow, i)->descent(bv, font),
1123 changed = tabular->SetWidthOfCell(actcell, the_locking_inset->width(bv, font));
1124 changed = tabular->SetAscentOfRow(actrow, maxAsc + ADD_TO_HEIGHT) || changed;
1125 changed = tabular->SetDescentOfRow(actrow, maxDesc + ADD_TO_HEIGHT) || changed;
1128 for (int i = 0; i < tabular->rows(); ++i) {
1131 for (int j= 0; j < tabular->columns(); ++j) {
1132 if (tabular->IsPartOfMultiColumn(i,j))
1135 inset = tabular->GetCellInset(cell);
1137 inset->update(bv, font, false);
1138 maxAsc = max(maxAsc, inset->ascent(bv, font));
1139 maxDesc = max(maxDesc, inset->descent(bv, font));
1140 changed = tabular->SetWidthOfCell(cell, inset->width(bv, font)) || changed;
1142 changed = tabular->SetAscentOfRow(i, maxAsc + ADD_TO_HEIGHT) || changed;
1143 changed = tabular->SetDescentOfRow(i, maxDesc + ADD_TO_HEIGHT) || changed;
1149 void InsetTabular::GetCursorPos(BufferView *,
1150 int & x, int & y) const
1152 x = cursor.x() - top_x;
1157 void InsetTabular::ToggleInsetCursor(BufferView * bv)
1159 if (the_locking_inset) {
1160 the_locking_inset->ToggleInsetCursor(bv);
1164 LyXFont font; // = the_locking_inset->GetFont(par, cursor.pos);
1166 int const asc = lyxfont::maxAscent(font);
1167 int const desc = lyxfont::maxDescent(font);
1169 if (isCursorVisible())
1170 bv->hideLockedInsetCursor();
1172 bv->showLockedInsetCursor(cursor.x(), cursor.y(), asc, desc);
1173 toggleCursorVisible();
1177 void InsetTabular::ShowInsetCursor(BufferView * bv, bool show)
1179 if (!isCursorVisible()) {
1180 LyXFont font; // = GetFont(par, cursor.pos);
1182 int const asc = lyxfont::maxAscent(font);
1183 int const desc = lyxfont::maxDescent(font);
1184 bv->fitLockedInsetCursor(cursor.x(), cursor.y(), asc, desc);
1186 bv->showLockedInsetCursor(cursor.x(), cursor.y(),
1188 setCursorVisible(true);
1193 void InsetTabular::HideInsetCursor(BufferView * bv)
1195 if (isCursorVisible()) {
1196 bv->hideLockedInsetCursor();
1197 setCursorVisible(false);
1199 // if (cursor_visible)
1200 // ToggleInsetCursor(bv);
1204 void InsetTabular::setPos(BufferView * bv, int x, int y) const
1208 actcell = actrow = actcol = 0;
1209 int ly = tabular->GetDescentOfRow(actrow);
1211 // first search the right row
1212 while((ly < y) && (actrow < tabular->rows())) {
1214 + tabular->GetDescentOfRow(actrow)
1215 + tabular->GetAscentOfRow(actrow + 1)
1217 GetAdditionalHeight(tabular->
1218 GetCellNumber(actrow + 1,
1221 ly = cursor.y() + tabular->GetDescentOfRow(actrow);
1223 actcell = tabular->GetCellNumber(actrow, actcol);
1225 // now search the right column
1226 int lx = tabular->GetWidthOfColumn(actcell) -
1227 tabular->GetAdditionalWidth(actcell);
1229 #warning Jürgen, can you rewrite this to _not_ use the sequencing operator. (Lgb)
1230 for (; !tabular->IsLastCellInRow(actcell) && (lx < x);
1231 ++actcell,lx += tabular->GetWidthOfColumn(actcell) +
1232 tabular->GetAdditionalWidth(actcell - 1));
1234 // Jürgen, you should check that this is correct. (Lgb)
1235 for (; !tabular->IsLastCellInRow(actcell) && lx < x; ++actcell) {
1236 lx += tabular->GetWidthOfColumn(actcell + 1)
1237 + tabular->GetAdditionalWidth(actcell);
1241 cursor.x(lx - tabular->GetWidthOfColumn(actcell) + top_x + 2);
1246 int InsetTabular::getCellXPos(int cell) const
1250 for (; !tabular->IsFirstCellInRow(c); --c)
1252 int lx = tabular->GetWidthOfColumn(cell);
1253 for (; c < cell; ++c) {
1254 lx += tabular->GetWidthOfColumn(c);
1256 return (lx - tabular->GetWidthOfColumn(cell) + top_x);
1260 void InsetTabular::resetPos(BufferView * bv) const
1264 actcol = tabular->column_of_cell(actcell);
1269 for (; (cell < actcell) && !tabular->IsLastRow(cell); ++cell) {
1270 if (tabular->IsLastCellInRow(cell)) {
1272 + tabular->GetDescentOfRow(actrow)
1273 + tabular->GetAscentOfRow(actrow + 1)
1274 + tabular->GetAdditionalHeight(cell + 1));
1278 static int const offset = ADD_TO_TABULAR_WIDTH + 2;
1279 int new_x = getCellXPos(actcell);
1280 int old_x = cursor.x();
1283 // cursor.x(getCellXPos(actcell) + offset);
1284 if (scroll() && (tabular->GetWidthOfTabular() < bv->workWidth()-20))
1286 else if (the_locking_inset &&
1287 (tabular->GetWidthOfColumn(actcell) > bv->workWidth()-20)) {
1288 int xx = cursor.x() - offset + bv->text->GetRealCursorX(bv);
1289 if (xx > (bv->workWidth()-20))
1290 scroll(bv, -(xx - bv->workWidth() + 60));
1298 } else if ((cursor.x() - offset) > 20 &&
1299 (cursor.x() - offset + tabular->GetWidthOfColumn(actcell))
1300 > (bv->workWidth() - 20)) {
1301 scroll(bv, -tabular->GetWidthOfColumn(actcell) - 20);
1302 UpdateLocal(bv, FULL, false);
1303 } else if ((cursor.x() - offset) < 20) {
1304 scroll(bv, 20 - cursor.x() + offset);
1305 UpdateLocal(bv, FULL, false);
1306 } else if (scroll() && top_x > 20 &&
1307 (top_x + tabular->GetWidthOfTabular()) > (bv->workWidth() - 20)) {
1308 scroll(bv, old_x - cursor.x());
1310 if ((!the_locking_inset ||
1311 !the_locking_inset->GetFirstLockingInsetOfType(TABULAR_CODE)) &&
1312 actcell != oldcell) {
1313 InsetTabular * inset = const_cast<InsetTabular *>(this);
1314 bv->owner()->getDialogs()->updateTabular(inset);
1320 UpdatableInset::RESULT InsetTabular::moveRight(BufferView * bv, bool lock)
1322 if (lock && !old_locking_inset) {
1323 if (ActivateCellInset(bv))
1326 bool moved = isRightToLeft(bv)
1327 ? movePrevCell(bv) : moveNextCell(bv);
1330 if (lock && ActivateCellInset(bv))
1334 return DISPATCHED_NOUPDATE;
1338 UpdatableInset::RESULT InsetTabular::moveLeft(BufferView * bv, bool lock)
1340 bool moved = isRightToLeft(bv) ? moveNextCell(bv) : movePrevCell(bv);
1343 if (lock) { // behind the inset
1344 if (ActivateCellInset(bv, 0, 0, 0, true))
1348 return DISPATCHED_NOUPDATE;
1352 UpdatableInset::RESULT InsetTabular::moveUp(BufferView * bv, bool lock)
1354 int const ocell = actcell;
1355 actcell = tabular->GetCellAbove(actcell);
1356 if (actcell == ocell) // we moved out of the inset
1362 if (old_locking_inset) {
1363 old_locking_inset->GetCursorPos(bv, x, y);
1364 x -= cursor.x() + tabular->GetBeginningOfTextInCell(actcell);
1366 if (ActivateCellInset(bv, x, 0))
1369 return DISPATCHED_NOUPDATE;
1373 UpdatableInset::RESULT InsetTabular::moveDown(BufferView * bv, bool lock)
1375 int const ocell = actcell;
1376 actcell = tabular->GetCellBelow(actcell);
1377 if (actcell == ocell) // we moved out of the inset
1383 if (old_locking_inset) {
1384 old_locking_inset->GetCursorPos(bv, x, y);
1385 x -= cursor.x() + tabular->GetBeginningOfTextInCell(actcell);
1387 if (ActivateCellInset(bv, x, 0))
1390 return DISPATCHED_NOUPDATE;
1394 bool InsetTabular::moveNextCell(BufferView * bv, bool lock)
1396 if (isRightToLeft(bv)) {
1397 if (tabular->IsFirstCellInRow(actcell)) {
1398 int row = tabular->row_of_cell(actcell);
1399 if (row == tabular->rows() - 1)
1401 actcell = tabular->GetLastCellInRow(row);
1402 actcell = tabular->GetCellBelow(actcell);
1409 if (tabular->IsLastCell(actcell))
1414 bool rtl = tabular->GetCellInset(actcell)->par->
1415 isRightToLeftPar(bv->buffer()->params);
1416 ActivateCellInset(bv, 0, 0, 0, !rtl);
1423 bool InsetTabular::movePrevCell(BufferView * bv, bool lock)
1425 if (isRightToLeft(bv)) {
1426 if (tabular->IsLastCellInRow(actcell)) {
1427 int row = tabular->row_of_cell(actcell);
1430 actcell = tabular->GetFirstCellInRow(row);
1431 actcell = tabular->GetCellAbove(actcell);
1433 if (tabular->IsLastCell(actcell))
1438 if (!actcell) // first cell
1443 bool rtl = tabular->GetCellInset(actcell)->par->
1444 isRightToLeftPar(bv->buffer()->params);
1445 ActivateCellInset(bv, 0, 0, 0, !rtl);
1452 bool InsetTabular::Delete()
1458 void InsetTabular::SetFont(BufferView * bv, LyXFont const & font, bool tall)
1460 if (the_locking_inset)
1461 the_locking_inset->SetFont(bv, font, tall);
1465 bool InsetTabular::TabularFeatures(BufferView * bv, string const & what)
1467 LyXTabular::Feature action = LyXTabular::LAST_ACTION;
1470 for (; tabularFeatures[i].action != LyXTabular::LAST_ACTION; ++i) {
1471 string const tmp = tabularFeatures[i].feature;
1473 if (tmp == what.substr(0, tmp.length())) {
1474 //if (!compare(tabularFeatures[i].feature.c_str(), what.c_str(),
1475 //tabularFeatures[i].feature.length())) {
1476 action = tabularFeatures[i].action;
1480 if (action == LyXTabular::LAST_ACTION)
1484 frontStrip(what.substr(tabularFeatures[i].feature.length()));
1485 TabularFeatures(bv, action, val);
1490 void InsetTabular::TabularFeatures(BufferView * bv,
1491 LyXTabular::Feature feature,
1492 string const & value)
1500 bool setLines = false;
1501 LyXAlignment setAlign = LYX_ALIGN_LEFT;
1502 LyXTabular::VAlignment setVAlign = LyXTabular::LYX_VALIGN_TOP;
1507 case LyXTabular::M_ALIGN_LEFT:
1508 case LyXTabular::ALIGN_LEFT:
1509 setAlign=LYX_ALIGN_LEFT;
1511 case LyXTabular::M_ALIGN_RIGHT:
1512 case LyXTabular::ALIGN_RIGHT:
1513 setAlign=LYX_ALIGN_RIGHT;
1515 case LyXTabular::M_ALIGN_CENTER:
1516 case LyXTabular::ALIGN_CENTER:
1517 setAlign=LYX_ALIGN_CENTER;
1519 case LyXTabular::M_VALIGN_TOP:
1520 case LyXTabular::VALIGN_TOP:
1521 setVAlign=LyXTabular::LYX_VALIGN_TOP;
1523 case LyXTabular::M_VALIGN_BOTTOM:
1524 case LyXTabular::VALIGN_BOTTOM:
1525 setVAlign=LyXTabular::LYX_VALIGN_BOTTOM;
1527 case LyXTabular::M_VALIGN_CENTER:
1528 case LyXTabular::VALIGN_CENTER:
1529 setVAlign=LyXTabular::LYX_VALIGN_CENTER;
1534 if (hasSelection()) {
1535 sel_col_start = tabular->column_of_cell(sel_cell_start);
1536 sel_col_end = tabular->column_of_cell(sel_cell_end);
1537 if (sel_col_start > sel_col_end) {
1538 sel_col_end = sel_col_start;
1539 sel_col_start = tabular->column_of_cell(sel_cell_end);
1541 sel_col_end = tabular->right_column_of_cell(sel_cell_end);
1544 sel_row_start = tabular->row_of_cell(sel_cell_start);
1545 sel_row_end = tabular->row_of_cell(sel_cell_end);
1546 if (sel_row_start > sel_row_end) {
1547 //int tmp = sel_row_start;
1548 //sel_row_start = sel_row_end;
1549 //sel_row_end = tmp;
1550 swap(sel_row_start, sel_row_end);
1553 sel_col_start = sel_col_end = tabular->column_of_cell(actcell);
1554 sel_row_start = sel_row_end = tabular->row_of_cell(actcell);
1556 bv->text->SetUndo(bv->buffer(), Undo::FINISH,
1558 bv->text->cursor.par()->ParFromPos(bv->text->cursor.pos())->previous_,
1559 bv->text->cursor.par()->ParFromPos(bv->text->cursor.pos())->next_
1561 bv->text->cursor.par()->previous(),
1562 bv->text->cursor.par()->next()
1566 int row = tabular->row_of_cell(actcell);
1567 int column = tabular->column_of_cell(actcell);
1571 case LyXTabular::SET_PWIDTH:
1573 bool const update = (tabular->GetColumnPWidth(actcell) != value);
1574 tabular->SetColumnPWidth(actcell,value);
1576 for (int i = 0; i < tabular->rows(); ++i) {
1577 tabular->GetCellInset(tabular->GetCellNumber(i, column))->
1580 UpdateLocal(bv, INIT, true);
1584 case LyXTabular::SET_MPWIDTH:
1586 bool const update = (tabular->GetPWidth(actcell) != value);
1587 tabular->SetMColumnPWidth(actcell,value);
1589 for (int i = 0; i < tabular->rows(); ++i) {
1590 tabular->GetCellInset(tabular->GetCellNumber(i, column))->
1593 UpdateLocal(bv, INIT, true);
1597 case LyXTabular::SET_SPECIAL_COLUMN:
1598 case LyXTabular::SET_SPECIAL_MULTI:
1599 tabular->SetAlignSpecial(actcell,value,feature);
1601 case LyXTabular::APPEND_ROW:
1602 // append the row into the tabular
1603 UnlockInsetInInset(bv, the_locking_inset);
1604 tabular->AppendRow(actcell);
1605 UpdateLocal(bv, INIT, true);
1607 case LyXTabular::APPEND_COLUMN:
1608 // append the column into the tabular
1609 UnlockInsetInInset(bv, the_locking_inset);
1610 tabular->AppendColumn(actcell);
1611 actcell = tabular->GetCellNumber(row, column);
1612 UpdateLocal(bv, INIT, true);
1614 case LyXTabular::DELETE_ROW:
1615 UnlockInsetInInset(bv, the_locking_inset);
1616 tabular->DeleteRow(tabular->row_of_cell(actcell));
1617 if ((row+1) > tabular->rows())
1619 actcell = tabular->GetCellNumber(row, column);
1621 UpdateLocal(bv, INIT, true);
1623 case LyXTabular::DELETE_COLUMN:
1624 UnlockInsetInInset(bv, the_locking_inset);
1625 tabular->DeleteColumn(tabular->column_of_cell(actcell));
1626 if ((column+1) > tabular->columns())
1628 actcell = tabular->GetCellNumber(row, column);
1630 UpdateLocal(bv, INIT, true);
1632 case LyXTabular::M_TOGGLE_LINE_TOP:
1634 case LyXTabular::TOGGLE_LINE_TOP:
1636 bool lineSet = !tabular->TopLine(actcell, flag);
1637 for (int i = sel_row_start; i <= sel_row_end; ++i)
1638 for (int j = sel_col_start; j <= sel_col_end; ++j)
1639 tabular->SetTopLine(
1640 tabular->GetCellNumber(i, j),
1642 UpdateLocal(bv, INIT, true);
1646 case LyXTabular::M_TOGGLE_LINE_BOTTOM:
1648 case LyXTabular::TOGGLE_LINE_BOTTOM:
1650 bool lineSet = !tabular->BottomLine(actcell, flag);
1651 for (int i = sel_row_start; i <= sel_row_end; ++i)
1652 for (int j = sel_col_start; j <= sel_col_end; ++j)
1653 tabular->SetBottomLine(
1654 tabular->GetCellNumber(i, j),
1657 UpdateLocal(bv, INIT, true);
1661 case LyXTabular::M_TOGGLE_LINE_LEFT:
1663 case LyXTabular::TOGGLE_LINE_LEFT:
1665 bool lineSet = !tabular->LeftLine(actcell, flag);
1666 for (int i = sel_row_start; i <= sel_row_end; ++i)
1667 for (int j = sel_col_start; j <= sel_col_end; ++j)
1668 tabular->SetLeftLine(
1669 tabular->GetCellNumber(i,j),
1672 UpdateLocal(bv, INIT, true);
1676 case LyXTabular::M_TOGGLE_LINE_RIGHT:
1678 case LyXTabular::TOGGLE_LINE_RIGHT:
1680 bool lineSet = !tabular->RightLine(actcell, flag);
1681 for (int i = sel_row_start; i <= sel_row_end; ++i)
1682 for (int j = sel_col_start; j <= sel_col_end; ++j)
1683 tabular->SetRightLine(
1684 tabular->GetCellNumber(i,j),
1687 UpdateLocal(bv, INIT, true);
1691 case LyXTabular::M_ALIGN_LEFT:
1692 case LyXTabular::M_ALIGN_RIGHT:
1693 case LyXTabular::M_ALIGN_CENTER:
1695 case LyXTabular::ALIGN_LEFT:
1696 case LyXTabular::ALIGN_RIGHT:
1697 case LyXTabular::ALIGN_CENTER:
1698 for (int i = sel_row_start; i <= sel_row_end; ++i)
1699 for (int j = sel_col_start; j <= sel_col_end; ++j)
1700 tabular->SetAlignment(
1701 tabular->GetCellNumber(i, j),
1704 UpdateLocal(bv, INIT, true);
1706 case LyXTabular::M_VALIGN_TOP:
1707 case LyXTabular::M_VALIGN_BOTTOM:
1708 case LyXTabular::M_VALIGN_CENTER:
1710 case LyXTabular::VALIGN_TOP:
1711 case LyXTabular::VALIGN_BOTTOM:
1712 case LyXTabular::VALIGN_CENTER:
1713 for (int i = sel_row_start; i <= sel_row_end; ++i)
1714 for (int j = sel_col_start; j <= sel_col_end; ++j)
1715 tabular->SetVAlignment(
1716 tabular->GetCellNumber(i, j),
1718 UpdateLocal(bv, INIT, true);
1720 case LyXTabular::MULTICOLUMN:
1722 if (sel_row_start != sel_row_end) {
1723 WriteAlert(_("Impossible Operation!"),
1724 _("Multicolumns can only be horizontally."),
1728 // just multicol for one Single Cell
1729 if (!hasSelection()) {
1730 // check wether we are completly in a multicol
1731 if (tabular->IsMultiColumn(actcell)) {
1732 tabular->UnsetMultiColumn(actcell);
1733 UpdateLocal(bv, INIT, true);
1735 tabular->SetMultiColumn(actcell, 1);
1736 UpdateLocal(bv, CELL, true);
1740 // we have a selection so this means we just add all this
1741 // cells to form a multicolumn cell
1745 if (sel_cell_start > sel_cell_end) {
1746 s_start = sel_cell_end;
1747 s_end = sel_cell_start;
1749 s_start = sel_cell_start;
1750 s_end = sel_cell_end;
1752 tabular->SetMultiColumn(s_start, s_end - s_start + 1);
1754 sel_cell_end = sel_cell_start;
1755 UpdateLocal(bv, INIT, true);
1758 case LyXTabular::SET_ALL_LINES:
1760 case LyXTabular::UNSET_ALL_LINES:
1761 for (int i = sel_row_start; i <= sel_row_end; ++i)
1762 for (int j = sel_col_start; j <= sel_col_end; ++j)
1763 tabular->SetAllLines(
1764 tabular->GetCellNumber(i,j), setLines);
1765 UpdateLocal(bv, INIT, true);
1767 case LyXTabular::SET_LONGTABULAR:
1768 tabular->SetLongTabular(true);
1769 UpdateLocal(bv, INIT, true); // because this toggles displayed
1771 case LyXTabular::UNSET_LONGTABULAR:
1772 tabular->SetLongTabular(false);
1773 UpdateLocal(bv, INIT, true); // because this toggles displayed
1775 case LyXTabular::SET_ROTATE_TABULAR:
1776 tabular->SetRotateTabular(true);
1778 case LyXTabular::UNSET_ROTATE_TABULAR:
1779 tabular->SetRotateTabular(false);
1781 case LyXTabular::SET_ROTATE_CELL:
1782 for (int i = sel_row_start; i <= sel_row_end; ++i)
1783 for (int j = sel_col_start; j<=sel_col_end; ++j)
1784 tabular->SetRotateCell(
1785 tabular->GetCellNumber(i, j),
1788 case LyXTabular::UNSET_ROTATE_CELL:
1789 for (int i = sel_row_start; i <= sel_row_end; ++i)
1790 for (int j = sel_col_start; j <= sel_col_end; ++j)
1791 tabular->SetRotateCell(
1792 tabular->GetCellNumber(i, j), false);
1794 case LyXTabular::SET_USEBOX:
1796 LyXTabular::BoxType val = LyXTabular::BoxType(strToInt(value));
1797 if (val == tabular->GetUsebox(actcell))
1798 val = LyXTabular::BOX_NONE;
1799 for (int i = sel_row_start; i <= sel_row_end; ++i)
1800 for (int j = sel_col_start; j <= sel_col_end; ++j)
1802 tabular->GetCellNumber(i, j), val);
1805 case LyXTabular::SET_LTFIRSTHEAD:
1806 tabular->SetLTHead(actcell, true);
1808 case LyXTabular::SET_LTHEAD:
1809 tabular->SetLTHead(actcell, false);
1811 case LyXTabular::SET_LTFOOT:
1812 tabular->SetLTFoot(actcell, false);
1814 case LyXTabular::SET_LTLASTFOOT:
1815 tabular->SetLTFoot(actcell, true);
1817 case LyXTabular::SET_LTNEWPAGE:
1819 bool what = !tabular->GetLTNewPage(actcell);
1820 tabular->SetLTNewPage(actcell, what);
1823 // dummy stuff just to avoid warnings
1824 case LyXTabular::LAST_ACTION:
1830 bool InsetTabular::ActivateCellInset(BufferView * bv, int x, int y, int button,
1833 UpdatableInset * inset =
1834 static_cast<UpdatableInset*>(tabular->GetCellInset(actcell));
1835 LyXFont font(LyXFont::ALL_SANE);
1837 x = inset->x() + inset->width(bv, font);
1838 y = inset->descent(bv, font);
1840 //inset_x = cursor.x() - top_x + tabular->GetBeginningOfTextInCell(actcell);
1841 //inset_y = cursor.y();
1842 inset->Edit(bv, x, y, button);
1843 if (!the_locking_inset)
1845 UpdateLocal(bv, CELL, false);
1846 return (the_locking_inset != 0);
1850 bool InsetTabular::ActivateCellInsetAbs(BufferView * bv, int x, int y,
1853 inset_x = cursor.x()
1854 - top_x + tabular->GetBeginningOfTextInCell(actcell);
1855 inset_y = cursor.y();
1856 return ActivateCellInset(bv, x - inset_x, y - inset_y, button);
1860 bool InsetTabular::InsetHit(BufferView *, int x, int) const
1863 > (cursor.x() + tabular->GetBeginningOfTextInCell(actcell));
1867 // This returns paperWidth() if the cell-width is unlimited or the width
1868 // in pixels if we have a pwidth for this cell.
1869 int InsetTabular::GetMaxWidthOfCell(BufferView * bv, int cell) const
1871 string const s = tabular->GetPWidth(cell);
1875 return VSpace(s).inPixels(bv);
1879 int InsetTabular::getMaxWidth(BufferView * bv,
1880 UpdatableInset const * inset) const
1882 int const n = tabular->GetNumberOfCells();
1884 for (; cell < n; ++cell) {
1885 if (tabular->GetCellInset(cell) == inset)
1890 int w = GetMaxWidthOfCell(bv, cell);
1892 // because the inset then subtracts it's top_x and owner->x()
1893 w += (inset->x() - top_x);
1898 void InsetTabular::resizeLyXText(BufferView *) const
1904 LyXText * InsetTabular::getLyXText(BufferView const * bv,
1905 bool const recursive) const
1907 if (the_locking_inset)
1908 return the_locking_inset->getLyXText(bv, recursive);
1909 return Inset::getLyXText(bv, recursive);
1913 bool InsetTabular::ShowInsetDialog(BufferView * bv) const
1915 if (!the_locking_inset || !the_locking_inset->ShowInsetDialog(bv))
1916 bv->owner()->getDialogs()
1917 ->showTabular(const_cast<InsetTabular *>(this));
1922 void InsetTabular::OpenLayoutDialog(BufferView * bv) const
1924 if (the_locking_inset) {
1925 InsetTabular * i = static_cast<InsetTabular *>
1926 (the_locking_inset->GetFirstLockingInsetOfType(TABULAR_CODE));
1928 i->OpenLayoutDialog(bv);
1932 bv->owner()->getDialogs()->showTabular(
1933 const_cast<InsetTabular *>(this));
1937 // functions returns:
1941 // 3 ... toggled off
1943 LyXFunc::func_status InsetTabular::getStatus(string const & what) const
1945 int action = LyXTabular::LAST_ACTION;
1946 LyXFunc::func_status status = LyXFunc::OK;
1949 for (; tabularFeatures[i].action != LyXTabular::LAST_ACTION; ++i) {
1950 string const tmp = tabularFeatures[i].feature;
1951 if (tmp == what.substr(0, tmp.length())) {
1952 //if (!compare(tabularFeatures[i].feature.c_str(), what.c_str(),
1953 // tabularFeatures[i].feature.length())) {
1954 action = tabularFeatures[i].action;
1958 if (action == LyXTabular::LAST_ACTION)
1959 return LyXFunc::Unknown;
1961 string const argument = frontStrip(what.substr(tabularFeatures[i].feature.length()));
1968 if (hasSelection()) {
1969 sel_row_start = tabular->row_of_cell(sel_cell_start);
1970 sel_row_end = tabular->row_of_cell(sel_cell_end);
1971 if (sel_row_start > sel_row_end) {
1972 //int tmp = sel_row_start;
1973 //sel_row_start = sel_row_end;
1974 //sel_row_end = tmp;
1975 swap(sel_row_start, sel_row_end);
1978 sel_row_start = sel_row_end = tabular->row_of_cell(actcell);
1982 case LyXTabular::SET_PWIDTH:
1983 case LyXTabular::SET_MPWIDTH:
1984 case LyXTabular::SET_SPECIAL_COLUMN:
1985 case LyXTabular::SET_SPECIAL_MULTI:
1986 status |= LyXFunc::Disabled;
1989 case LyXTabular::APPEND_ROW:
1990 case LyXTabular::APPEND_COLUMN:
1991 case LyXTabular::DELETE_ROW:
1992 case LyXTabular::DELETE_COLUMN:
1993 case LyXTabular::SET_ALL_LINES:
1994 case LyXTabular::UNSET_ALL_LINES:
1995 status |= LyXFunc::OK;
1998 case LyXTabular::MULTICOLUMN:
1999 if (tabular->IsMultiColumn(actcell))
2000 status |= LyXFunc::ToggleOn;
2002 status |= LyXFunc::ToggleOff;
2004 case LyXTabular::M_TOGGLE_LINE_TOP:
2006 case LyXTabular::TOGGLE_LINE_TOP:
2007 if (tabular->TopLine(actcell, flag))
2008 status |= LyXFunc::ToggleOn;
2010 status |= LyXFunc::ToggleOff;
2012 case LyXTabular::M_TOGGLE_LINE_BOTTOM:
2014 case LyXTabular::TOGGLE_LINE_BOTTOM:
2015 if (tabular->BottomLine(actcell, flag))
2016 status |= LyXFunc::ToggleOn;
2018 status |= LyXFunc::ToggleOff;
2020 case LyXTabular::M_TOGGLE_LINE_LEFT:
2022 case LyXTabular::TOGGLE_LINE_LEFT:
2023 if (tabular->LeftLine(actcell, flag))
2024 status |= LyXFunc::ToggleOn;
2026 status |= LyXFunc::ToggleOff;
2028 case LyXTabular::M_TOGGLE_LINE_RIGHT:
2030 case LyXTabular::TOGGLE_LINE_RIGHT:
2031 if (tabular->RightLine(actcell, flag))
2032 status |= LyXFunc::ToggleOn;
2034 status |= LyXFunc::ToggleOff;
2036 case LyXTabular::M_ALIGN_LEFT:
2038 case LyXTabular::ALIGN_LEFT:
2039 if (tabular->GetAlignment(actcell, flag) == LYX_ALIGN_LEFT)
2040 status |= LyXFunc::ToggleOn;
2042 status |= LyXFunc::ToggleOff;
2044 case LyXTabular::M_ALIGN_RIGHT:
2046 case LyXTabular::ALIGN_RIGHT:
2047 if (tabular->GetAlignment(actcell, flag) == LYX_ALIGN_RIGHT)
2048 status |= LyXFunc::ToggleOn;
2050 status |= LyXFunc::ToggleOff;
2052 case LyXTabular::M_ALIGN_CENTER:
2054 case LyXTabular::ALIGN_CENTER:
2055 if (tabular->GetAlignment(actcell, flag) == LYX_ALIGN_CENTER)
2056 status |= LyXFunc::ToggleOn;
2058 status |= LyXFunc::ToggleOff;
2060 case LyXTabular::M_VALIGN_TOP:
2062 case LyXTabular::VALIGN_TOP:
2063 if (tabular->GetVAlignment(actcell, flag) == LyXTabular::LYX_VALIGN_TOP)
2064 status |= LyXFunc::ToggleOn;
2066 status |= LyXFunc::ToggleOff;
2068 case LyXTabular::M_VALIGN_BOTTOM:
2070 case LyXTabular::VALIGN_BOTTOM:
2071 if (tabular->GetVAlignment(actcell, flag) == LyXTabular::LYX_VALIGN_BOTTOM)
2072 status |= LyXFunc::ToggleOn;
2074 status |= LyXFunc::ToggleOff;
2076 case LyXTabular::M_VALIGN_CENTER:
2078 case LyXTabular::VALIGN_CENTER:
2079 if (tabular->GetVAlignment(actcell, flag) == LyXTabular::LYX_VALIGN_CENTER)
2080 status |= LyXFunc::ToggleOn;
2082 status |= LyXFunc::ToggleOff;
2084 case LyXTabular::SET_LONGTABULAR:
2085 if (tabular->IsLongTabular())
2086 status |= LyXFunc::ToggleOn;
2088 status |= LyXFunc::ToggleOff;
2090 case LyXTabular::UNSET_LONGTABULAR:
2091 if (!tabular->IsLongTabular())
2092 status |= LyXFunc::ToggleOn;
2094 status |= LyXFunc::ToggleOff;
2096 case LyXTabular::SET_ROTATE_TABULAR:
2097 if (tabular->GetRotateTabular())
2098 status |= LyXFunc::ToggleOn;
2100 status |= LyXFunc::ToggleOff;
2102 case LyXTabular::UNSET_ROTATE_TABULAR:
2103 if (!tabular->GetRotateTabular())
2104 status |= LyXFunc::ToggleOn;
2106 status |= LyXFunc::ToggleOff;
2108 case LyXTabular::SET_ROTATE_CELL:
2109 if (tabular->GetRotateCell(actcell))
2110 status |= LyXFunc::ToggleOn;
2112 status |= LyXFunc::ToggleOff;
2114 case LyXTabular::UNSET_ROTATE_CELL:
2115 if (!tabular->GetRotateCell(actcell))
2116 status |= LyXFunc::ToggleOn;
2118 status |= LyXFunc::ToggleOff;
2120 case LyXTabular::SET_USEBOX:
2121 if (strToInt(argument) == tabular->GetUsebox(actcell))
2122 status |= LyXFunc::ToggleOn;
2124 status |= LyXFunc::ToggleOff;
2126 case LyXTabular::SET_LTFIRSTHEAD:
2127 if (tabular->GetRowOfLTHead(actcell, dummy))
2128 status |= LyXFunc::ToggleOn;
2130 status |= LyXFunc::ToggleOff;
2132 case LyXTabular::SET_LTHEAD:
2133 if (tabular->GetRowOfLTHead(actcell, dummy))
2134 status |= LyXFunc::ToggleOn;
2136 status |= LyXFunc::ToggleOff;
2138 case LyXTabular::SET_LTFOOT:
2139 if (tabular->GetRowOfLTFoot(actcell, dummy))
2140 status |= LyXFunc::ToggleOn;
2142 status |= LyXFunc::ToggleOff;
2144 case LyXTabular::SET_LTLASTFOOT:
2145 if (tabular->GetRowOfLTFoot(actcell, dummy))
2146 status |= LyXFunc::ToggleOn;
2148 status |= LyXFunc::ToggleOff;
2150 case LyXTabular::SET_LTNEWPAGE:
2151 if (tabular->GetLTNewPage(actcell))
2152 status |= LyXFunc::ToggleOn;
2154 status |= LyXFunc::ToggleOff;
2157 status = LyXFunc::Disabled;
2164 bool InsetTabular::copySelection(BufferView * bv)
2166 if (!hasSelection())
2168 //delete paste_tabular;
2170 //int sel_col_start;
2172 //int sel_row_start;
2175 int sel_col_start = tabular->column_of_cell(sel_cell_start);
2176 int sel_col_end = tabular->column_of_cell(sel_cell_end);
2177 if (sel_col_start > sel_col_end) {
2178 sel_col_start = sel_col_end;
2179 sel_col_end = tabular->right_column_of_cell(sel_cell_start);
2181 sel_col_end = tabular->right_column_of_cell(sel_cell_end);
2183 int const columns = sel_col_end - sel_col_start + 1;
2185 int sel_row_start = tabular->row_of_cell(sel_cell_start);
2186 int sel_row_end = tabular->row_of_cell(sel_cell_end);
2187 if (sel_row_start > sel_row_end) {
2188 //int tmp tmp = sel_row_start;
2189 //sel_row_start = sel_row_end;
2190 //sel_row_end = tmp;
2191 swap(sel_row_start, sel_row_end);
2193 int const rows = sel_row_end - sel_row_start + 1;
2195 delete paste_tabular;
2196 paste_tabular = new LyXTabular(this, *tabular); // rows, columns);
2198 for (int i = 0; i < sel_row_start; ++i)
2199 paste_tabular->DeleteRow(0);
2200 while(paste_tabular->rows() > rows)
2201 paste_tabular->DeleteRow(rows);
2202 paste_tabular->SetTopLine(0, true, true);
2203 paste_tabular->SetBottomLine(paste_tabular->GetFirstCellInRow(rows-1),
2205 for (int i = 0; i < sel_col_start; ++i)
2206 paste_tabular->DeleteColumn(0);
2207 while (paste_tabular->columns() > columns)
2208 paste_tabular->DeleteColumn(columns);
2209 paste_tabular->SetLeftLine(0, true, true);
2210 paste_tabular->SetRightLine(paste_tabular->GetLastCellInRow(0),
2214 paste_tabular->Ascii(bv->buffer(), sstr);
2215 bv->stuffClipboard(sstr.str().c_str());
2220 bool InsetTabular::pasteSelection(BufferView * bv)
2225 for (int r1 = 0, r2 = actrow;
2226 (r1 < paste_tabular->rows()) && (r2 < tabular->rows());
2228 for(int c1 = 0, c2 = actcol;
2229 (c1 < paste_tabular->columns()) && (c2 < tabular->columns());
2231 if (paste_tabular->IsPartOfMultiColumn(r1,c1) &&
2232 tabular->IsPartOfMultiColumn(r2,c2))
2234 if (paste_tabular->IsPartOfMultiColumn(r1,c1)) {
2238 if (tabular->IsPartOfMultiColumn(r2,c2)) {
2242 int const n1 = paste_tabular->GetCellNumber(r1, c1);
2243 int const n2 = tabular->GetCellNumber(r2, c2);
2244 *(tabular->GetCellInset(n2)) = *(paste_tabular->GetCellInset(n1));
2245 tabular->GetCellInset(n2)->setOwner(this);
2246 tabular->GetCellInset(n2)->deleteLyXText(bv);
2253 bool InsetTabular::cutSelection()
2255 if (!hasSelection())
2258 //int sel_col_start;
2260 //int sel_row_start;
2263 int sel_col_start = tabular->column_of_cell(sel_cell_start);
2264 int sel_col_end = tabular->column_of_cell(sel_cell_end);
2265 if (sel_col_start > sel_col_end) {
2266 sel_col_start = sel_col_end;
2267 sel_col_end = tabular->right_column_of_cell(sel_cell_start);
2269 sel_col_end = tabular->right_column_of_cell(sel_cell_end);
2271 int sel_row_start = tabular->row_of_cell(sel_cell_start);
2272 int sel_row_end = tabular->row_of_cell(sel_cell_end);
2273 if (sel_row_start > sel_row_end) {
2274 //int tmp = sel_row_start;
2275 //sel_row_start = sel_row_end;
2276 //sel_row_end = tmp;
2277 swap(sel_row_start, sel_row_end);
2279 if (sel_cell_start > sel_cell_end) {
2280 //int tmp = sel_cell_start;
2281 //sel_cell_start = sel_cell_end;
2282 //sel_cell_end = tmp;
2283 swap(sel_cell_start, sel_cell_end);
2285 for (int i = sel_row_start; i <= sel_row_end; ++i) {
2286 for (int j = sel_col_start; j <= sel_col_end; ++j) {
2287 tabular->GetCellInset(tabular->GetCellNumber(i, j))->clear();
2294 bool InsetTabular::isRightToLeft(BufferView *bv )
2296 return bv->getParentLanguage(this)->RightToLeft();