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 {
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::DELETE_TABULAR, "delete-tabular" },
89 { LyXTabular::MULTICOLUMN, "multicolumn" },
90 { LyXTabular::SET_ALL_LINES, "set-all-lines" },
91 { LyXTabular::UNSET_ALL_LINES, "unset-all-lines" },
92 { LyXTabular::SET_LONGTABULAR, "set-longtabular" },
93 { LyXTabular::UNSET_LONGTABULAR, "unset-longtabular" },
94 { LyXTabular::SET_PWIDTH, "set-pwidth" },
95 { LyXTabular::SET_MPWIDTH, "set-mpwidth" },
96 { LyXTabular::SET_ROTATE_TABULAR, "set-rotate-tabular" },
97 { LyXTabular::UNSET_ROTATE_TABULAR, "unset-rotate-tabular" },
98 { LyXTabular::SET_ROTATE_CELL, "set-rotate-cell" },
99 { LyXTabular::UNSET_ROTATE_CELL, "unset-rotate-cell" },
100 { LyXTabular::SET_USEBOX, "set-usebox" },
101 { LyXTabular::SET_LTHEAD, "set-lthead" },
102 { LyXTabular::SET_LTFIRSTHEAD, "set-ltfirsthead" },
103 { LyXTabular::SET_LTFOOT, "set-ltfoot" },
104 { LyXTabular::SET_LTLASTFOOT, "set-ltlastfoot" },
105 { LyXTabular::SET_LTNEWPAGE, "set-ltnewpage" },
106 { LyXTabular::SET_SPECIAL_COLUMN, "set-special-column" },
107 { LyXTabular::SET_SPECIAL_MULTI, "set-special-multi" },
108 { LyXTabular::LAST_ACTION, "" }
113 bool cellstart(LyXParagraph::size_type p)
115 return ((p % 2) == 0);
119 InsetTabular::InsetTabular(Buffer * buf, int rows, int columns)
126 tabular = new LyXTabular(this, rows,columns);
127 // for now make it always display as display() inset
129 the_locking_inset = 0;
130 locked = no_selection = cursor_visible = false;
135 sel_pos_start = sel_pos_end = sel_cell_start = sel_cell_end = 0;
141 InsetTabular::InsetTabular(InsetTabular const & tab, Buffer * buf)
144 tabular = new LyXTabular(this, *(tab.tabular));
145 the_locking_inset = 0;
146 locked = no_selection = cursor_visible = false;
151 sel_pos_start = sel_pos_end = sel_cell_start = sel_cell_end = 0;
157 InsetTabular::~InsetTabular()
161 dialogs_->hideTabular(this);
165 Inset * InsetTabular::Clone() const
167 InsetTabular * t = new InsetTabular(*this, buffer);
169 t->tabular = tabular->Clone(t);
174 void InsetTabular::Write(Buffer const * buf, ostream & os) const
176 os << " Tabular" << endl;
177 tabular->Write(buf, os);
181 void InsetTabular::Read(Buffer const * buf, LyXLex & lex)
183 bool old_format = (lex.GetString() == "\\LyXTable");
188 tabular = new LyXTabular(buf, this, lex);
196 token = lex.GetString();
197 while (lex.IsOK() && (token != "\\end_inset")) {
199 token = lex.GetString();
201 if (token != "\\end_inset") {
202 lex.printError("Missing \\end_inset at this point. "
208 int InsetTabular::ascent(BufferView *, LyXFont const &) const
210 return tabular->GetAscentOfRow(0);
214 int InsetTabular::descent(BufferView *, LyXFont const &) const
216 return tabular->GetHeightOfTabular() - tabular->GetAscentOfRow(0) + 1;
220 int InsetTabular::width(BufferView *, LyXFont const &) const
222 return tabular->GetWidthOfTabular() + (2 * ADD_TO_TABULAR_WIDTH);
226 void InsetTabular::draw(BufferView * bv, LyXFont const & font, int baseline,
227 float & x, bool cleared) const
229 Painter & pain = bv->painter();
234 UpdatableInset::draw(bv,font,baseline,x,cleared);
235 if (!cleared && ((need_update == INIT) || (need_update == FULL) ||
236 (top_x != int(x)) || (top_baseline != baseline))) {
237 int h = ascent(bv, font) + descent(bv, font);
238 int tx = display()||!owner()? 0:top_x;
239 int w = tx? width(bv, font):pain.paperWidth();
240 int ty = baseline - ascent(bv, font);
244 if ((ty + h) > pain.paperHeight())
245 h = pain.paperHeight();
246 if ((top_x + w) > pain.paperWidth())
247 w = pain.paperWidth();
248 pain.fillRectangle(tx, ty, w, h);
253 top_baseline = baseline;
254 if (bv->text->status == LyXText::CHANGED_IN_DRAW)
257 x += ADD_TO_TABULAR_WIDTH;
258 if (cleared || (need_update == FULL) || (need_update == CELL)) {
259 for(i=0;i<tabular->rows();++i) {
261 dodraw = ((baseline+tabular->GetDescentOfRow(i)) > 0) &&
262 (baseline-tabular->GetAscentOfRow(i)) < pain.paperHeight();
263 for(j=0;j<tabular->columns();++j) {
264 if (tabular->IsPartOfMultiColumn(i,j))
266 cx = nx + tabular->GetBeginningOfTextInCell(cell);
268 DrawCellSelection(pain, nx, baseline, i, j, cell);
269 if (dodraw && !cleared && locked && the_locking_inset) {
270 if (the_locking_inset == tabular->GetCellInset(cell)) {
271 LyXText::text_status st = bv->text->status;
273 bv->text->status = st;
274 if (need_update == CELL) {
275 // clear before the inset
278 baseline - tabular->GetAscentOfRow(i)+1,
280 tabular->GetAscentOfRow(i) +
281 tabular->GetDescentOfRow(i) - 1);
282 // clear behind the inset
284 cx + the_locking_inset->width(bv,font) + 1,
285 baseline - tabular->GetAscentOfRow(i)+1,
286 tabular->GetWidthOfColumn(cell) -
287 tabular->GetBeginningOfTextInCell(cell) -
288 the_locking_inset->width(bv,font) - 1,
289 tabular->GetAscentOfRow(i) +
290 tabular->GetDescentOfRow(i) - 1);
292 tabular->GetCellInset(cell)->draw(
293 bv, font, baseline, cx, false);
294 } while(bv->text->status == LyXText::CHANGED_IN_DRAW);
297 tabular->GetCellInset(cell)->draw(bv, font, baseline, cx,
299 DrawCellLines(pain, nx, baseline, i, cell);
301 nx += tabular->GetWidthOfColumn(cell);
304 baseline += tabular->GetDescentOfRow(i) +
305 tabular->GetAscentOfRow(i+1)+
306 tabular->GetAdditionalHeight(cell+1);
309 x -= ADD_TO_TABULAR_WIDTH;
310 x += width(bv, font);
311 if (bv->text->status == LyXText::CHANGED_IN_DRAW)
318 void InsetTabular::DrawCellLines(Painter & pain, int x, int baseline,
319 int row, int cell) const
321 int x2 = x + tabular->GetWidthOfColumn(cell);
324 if (!tabular->TopAlreadyDrawed(cell)) {
325 on_off = !tabular->TopLine(cell);
326 pain.line(x, baseline - tabular->GetAscentOfRow(row),
327 x2, baseline - tabular->GetAscentOfRow(row),
328 on_off ? LColor::tabularonoffline:LColor::tabularline,
329 on_off ? Painter::line_onoffdash:Painter::line_solid);
331 on_off = !tabular->BottomLine(cell);
332 pain.line(x,baseline + tabular->GetDescentOfRow(row),
333 x2, baseline + tabular->GetDescentOfRow(row),
334 on_off ? LColor::tabularonoffline:LColor::tabularline,
335 on_off ? Painter::line_onoffdash:Painter::line_solid);
336 if (!tabular->LeftAlreadyDrawed(cell)) {
337 on_off = !tabular->LeftLine(cell);
338 pain.line(x, baseline - tabular->GetAscentOfRow(row),
339 x, baseline + tabular->GetDescentOfRow(row),
340 on_off ? LColor::tabularonoffline:LColor::tabularline,
341 on_off ? Painter::line_onoffdash:Painter::line_solid);
343 on_off = !tabular->RightLine(cell);
344 pain.line(x2 - tabular->GetAdditionalWidth(cell),
345 baseline - tabular->GetAscentOfRow(row),
346 x2 - tabular->GetAdditionalWidth(cell),
347 baseline + tabular->GetDescentOfRow(row),
348 on_off ? LColor::tabularonoffline:LColor::tabularline,
349 on_off ? Painter::line_onoffdash:Painter::line_solid);
353 void InsetTabular::DrawCellSelection(Painter & pain, int x, int baseline,
354 int row, int column, int cell) const
356 int cs = tabular->column_of_cell(sel_cell_start);
357 int ce = tabular->column_of_cell(sel_cell_end);
360 cs = tabular->column_of_cell(sel_cell_end);
362 ce = tabular->right_column_of_cell(sel_cell_end);
365 int rs = tabular->row_of_cell(sel_cell_start);
366 int re = tabular->row_of_cell(sel_cell_end);
367 if (rs > re) swap(rs, re);
369 if ((column >= cs) && (column <= ce) && (row >= rs) && (row <= re)) {
370 int w = tabular->GetWidthOfColumn(cell);
371 int h = tabular->GetAscentOfRow(row) + tabular->GetDescentOfRow(row);
372 pain.fillRectangle(x, baseline - tabular->GetAscentOfRow(row),
373 w, h, LColor::selection);
378 void InsetTabular::update(BufferView * bv, LyXFont const & font, bool reinit)
382 calculate_dimensions_of_cells(bv, font, true);
384 owner()->update(bv, font, true);
387 if (the_locking_inset)
388 the_locking_inset->update(bv, font, reinit);
389 switch(need_update) {
393 if (calculate_dimensions_of_cells(bv, font, false))
405 string const InsetTabular::EditMessage() const
407 return _("Opened Tabular Inset");
411 void InsetTabular::Edit(BufferView * bv, int x, int y, unsigned int button)
413 UpdatableInset::Edit(bv, x, y, button);
415 if (!bv->lockInset(this)) {
416 lyxerr[Debug::INSETS] << "InsetTabular::Cannot lock inset" << endl;
420 the_locking_inset = 0;
421 inset_pos = inset_x = inset_y = 0;
423 sel_pos_start = sel_pos_end = cursor.pos();
424 sel_cell_start = sel_cell_end = actcell;
425 bv->text->FinishUndo();
426 if (InsetHit(bv, x, y)) {
427 ActivateCellInset(bv, x, y, button);
429 UpdateLocal(bv, NONE, false);
430 // bv->getOwner()->getPopups().updateFormTabular();
434 void InsetTabular::InsetUnlock(BufferView * bv)
436 if (the_locking_inset) {
437 the_locking_inset->InsetUnlock(bv);
438 the_locking_inset = 0;
441 no_selection = false;
444 if (scroll() || hasSelection()) {
446 scroll(bv, (float)0.0);
448 sel_pos_start = sel_pos_end = 0;
449 sel_cell_start = sel_cell_end = 0;
451 UpdateLocal(bv, FULL, false);
456 void InsetTabular::UpdateLocal(BufferView * bv, UpdateCodes what,
457 bool mark_dirty) const
460 bv->updateInset(const_cast<InsetTabular *>(this), mark_dirty);
461 if (locked && (what != NONE))
466 bool InsetTabular::LockInsetInInset(BufferView * bv, UpdatableInset * inset)
468 lyxerr[Debug::INSETS] << "InsetTabular::LockInsetInInset(" <<inset<< "): ";
472 if (inset == tabular->GetCellInset(actcell)) {
473 lyxerr[Debug::INSETS] << "OK" << endl;
474 the_locking_inset = tabular->GetCellInset(actcell);
476 inset_x = cursor.x() - top_x + tabular->GetBeginningOfTextInCell(actcell);
477 inset_y = cursor.y();
478 inset_pos = cursor.pos();
480 } else if (the_locking_inset && (the_locking_inset == inset)) {
481 if (cursor.pos() == inset_pos) {
482 lyxerr[Debug::INSETS] << "OK" << endl;
484 inset_x = cursor.x() - top_x + tabular->GetBeginningOfTextInCell(actcell);
485 inset_y = cursor.y();
487 lyxerr[Debug::INSETS] << "cursor.pos != inset_pos" << endl;
489 } else if (the_locking_inset) {
490 lyxerr[Debug::INSETS] << "MAYBE" << endl;
491 return the_locking_inset->LockInsetInInset(bv, inset);
493 lyxerr[Debug::INSETS] << "NOT OK" << endl;
498 bool InsetTabular::UnlockInsetInInset(BufferView * bv, UpdatableInset * inset,
501 if (!the_locking_inset)
503 if (the_locking_inset == inset) {
504 the_locking_inset->InsetUnlock(bv);
505 the_locking_inset = 0;
507 moveRight(bv, false);
508 UpdateLocal(bv, CELL, false);
511 if (the_locking_inset->UnlockInsetInInset(bv, inset, lr)) {
512 if ((inset->LyxCode() == TABULAR_CODE) &&
513 !the_locking_inset->GetFirstLockingInsetOfType(TABULAR_CODE))
515 dialogs_ = bv->owner()->getDialogs();
516 dialogs_->updateTabular(const_cast<InsetTabular *>(this));
525 bool InsetTabular::UpdateInsetInInset(BufferView * bv, Inset * inset)
527 if (!the_locking_inset)
529 if (the_locking_inset != inset)
530 return the_locking_inset->UpdateInsetInInset(bv, inset);
531 UpdateLocal(bv, CELL, false);
536 int InsetTabular::InsetInInsetY()
538 if (!the_locking_inset)
541 return (inset_y + the_locking_inset->InsetInInsetY());
545 UpdatableInset * InsetTabular::GetLockingInset()
547 return the_locking_inset ? the_locking_inset->GetLockingInset() : this;
551 UpdatableInset * InsetTabular::GetFirstLockingInsetOfType(Inset::Code c)
555 if (the_locking_inset)
556 return the_locking_inset->GetFirstLockingInsetOfType(c);
561 bool InsetTabular::InsertInset(BufferView * bv, Inset * inset)
563 if (the_locking_inset)
564 return the_locking_inset->InsertInset(bv, inset);
569 void InsetTabular::InsetButtonPress(BufferView * bv, int x, int y, int button)
571 if (hasSelection()) {
572 sel_pos_start = sel_pos_end = sel_cell_start = sel_cell_end = 0;
573 UpdateLocal(bv, SELECTION, false);
575 no_selection = false;
583 UpdateLocal(bv, NONE, false);
584 sel_pos_start = sel_pos_end = cursor.pos();
585 sel_cell_start = sel_cell_end = actcell;
587 bool inset_hit = InsetHit(bv, x, y);
589 if ((ocell == actcell) && the_locking_inset && inset_hit) {
590 the_locking_inset->InsetButtonPress(bv, x-inset_x, y-inset_y, button);
592 } else if (the_locking_inset) {
593 the_locking_inset->InsetUnlock(bv);
595 the_locking_inset = 0;
596 if (inset_hit && bv->the_locking_inset) {
597 if (ActivateCellInset(bv, x, y, button))
598 the_locking_inset->InsetButtonPress(bv, x-inset_x,
606 void InsetTabular::InsetButtonRelease(BufferView * bv,
607 int x, int y, int button)
610 if (the_locking_inset) {
612 if ((i=the_locking_inset->GetFirstLockingInsetOfType(TABULAR_CODE))) {
613 i->InsetButtonRelease(bv, x, y, button);
617 dialogs_ = bv->owner()->getDialogs();
618 dialogs_->showTabular(this);
621 if (the_locking_inset) {
622 the_locking_inset->InsetButtonRelease(bv, x-inset_x, y-inset_y,button);
625 no_selection = false;
629 void InsetTabular::InsetMotionNotify(BufferView * bv, int x, int y, int button)
631 if (the_locking_inset) {
632 the_locking_inset->InsetMotionNotify(bv, x - inset_x,
633 y - inset_y, button);
638 int old_pos = sel_pos_end;
639 int old_cell = actcell;
642 sel_pos_end = cursor.pos();
643 sel_cell_end = actcell;
644 if ((sel_cell_end != old_cell) || (old_pos != sel_pos_end))
645 UpdateLocal(bv, SELECTION, false);
648 no_selection = false;
652 void InsetTabular::InsetKeyPress(XKeyEvent * xke)
654 if (the_locking_inset) {
655 the_locking_inset->InsetKeyPress(xke);
661 UpdatableInset::RESULT InsetTabular::LocalDispatch(BufferView * bv, int action,
664 UpdatableInset::RESULT
667 no_selection = false;
668 if (((result=UpdatableInset::LocalDispatch(bv, action, arg)) == DISPATCHED)
669 || (result == DISPATCHED_NOUPDATE)) {
675 if ((action < 0) && arg.empty())
678 if ((action != LFUN_DOWN) && (action != LFUN_UP) &&
679 (action != LFUN_DOWNSEL) && (action != LFUN_UPSEL))
681 if (the_locking_inset) {
682 result=the_locking_inset->LocalDispatch(bv, action, arg);
683 if (result == DISPATCHED_NOUPDATE)
685 else if (result == DISPATCHED) {
686 the_locking_inset->ToggleInsetCursor(bv);
687 UpdateLocal(bv, CELL, false);
688 the_locking_inset->ToggleInsetCursor(bv);
690 } else if (result == FINISHED) {
691 if ((action == LFUN_RIGHT) || (action == -1)) {
692 cursor.pos(inset_pos + 1);
695 sel_pos_start = sel_pos_end = cursor.pos();
696 sel_cell_start = sel_cell_end = actcell;
703 bool hs = hasSelection();
707 // Normal chars not handled here
710 // --- Cursor Movements ---------------------------------------------
712 if (tabular->IsLastCellInRow(actcell) && !cellstart(cursor.pos()))
714 moveRight(bv, false);
715 sel_pos_end = cursor.pos();
716 if (!cellstart(cursor.pos())) {
717 if (tabular->right_column_of_cell(sel_cell_start) >
718 tabular->right_column_of_cell(actcell))
719 sel_cell_end = actcell+1;
721 sel_cell_end = actcell;
723 UpdateLocal(bv, SELECTION, false);
726 result = moveRight(bv);
727 sel_pos_start = sel_pos_end = cursor.pos();
728 sel_cell_start = sel_cell_end = actcell;
730 UpdateLocal(bv, SELECTION, false);
733 if (tabular->IsFirstCellInRow(actcell) && cellstart(cursor.pos()))
736 sel_pos_end = cursor.pos();
737 if (cellstart(cursor.pos())) {
738 if (tabular->column_of_cell(sel_cell_start) >=
739 tabular->column_of_cell(actcell))
740 sel_cell_end = actcell;
742 sel_cell_end = actcell-1;
744 UpdateLocal(bv, SELECTION, false);
747 result = moveLeft(bv);
748 sel_pos_start = sel_pos_end = cursor.pos();
749 sel_cell_start = sel_cell_end = actcell;
751 UpdateLocal(bv, SELECTION, false);
757 sel_pos_end = cursor.pos();
758 if ((ocell == sel_cell_end) ||
759 (tabular->column_of_cell(ocell)>tabular->column_of_cell(actcell)))
760 sel_cell_end = tabular->GetCellBelow(sel_cell_end);
762 sel_cell_end = tabular->GetLastCellBelow(sel_cell_end);
763 UpdateLocal(bv, SELECTION, false);
767 result= moveDown(bv);
768 sel_pos_start = sel_pos_end = cursor.pos();
769 sel_cell_start = sel_cell_end = actcell;
771 UpdateLocal(bv, SELECTION, false);
777 sel_pos_end = cursor.pos();
778 if ((ocell == sel_cell_end) ||
779 (tabular->column_of_cell(ocell)>tabular->column_of_cell(actcell)))
780 sel_cell_end = tabular->GetCellAbove(sel_cell_end);
782 sel_cell_end = tabular->GetLastCellAbove(sel_cell_end);
783 UpdateLocal(bv, SELECTION, false);
788 sel_pos_start = sel_pos_end = cursor.pos();
789 sel_cell_start = sel_cell_end = actcell;
791 UpdateLocal(bv, SELECTION, false);
803 if (the_locking_inset) {
804 UnlockInsetInInset(bv, the_locking_inset);
805 the_locking_inset = 0;
807 if (action == LFUN_TAB)
811 sel_pos_start = sel_pos_end = cursor.pos();
812 sel_cell_start = sel_cell_end = actcell;
814 UpdateLocal(bv, SELECTION, false);
816 case LFUN_LAYOUT_TABLE:
818 dialogs_ = bv->owner()->getDialogs();
819 dialogs_->showTabular(this);
822 case LFUN_TABULAR_FEATURE:
823 if (!TabularFeatures(bv, arg))
824 result = UNDISPATCHED;
827 if (!copySelection())
829 bv->text->SetUndo(bv->buffer(), Undo::DELETE,
831 bv->text->cursor.par()->ParFromPos(bv->text->cursor.pos())->previous,
832 bv->text->cursor.par()->ParFromPos(bv->text->cursor.pos())->next
834 bv->text->cursor.par()->previous,
835 bv->text->cursor.par()->next
839 UpdateLocal(bv, INIT, true);
844 bv->text->FinishUndo();
848 if (!hasPasteBuffer())
850 bv->text->SetUndo(bv->buffer(), Undo::INSERT,
852 bv->text->cursor.par()->ParFromPos(bv->text->cursor.pos())->previous,
853 bv->text->cursor.par()->ParFromPos(bv->text->cursor.pos())->next
855 bv->text->cursor.par()->previous,
856 bv->text->cursor.par()->next
860 UpdateLocal(bv, INIT, true);
863 result = UNDISPATCHED;
866 if (result!=FINISHED) {
867 if (!the_locking_inset) {
869 if (ocell != actcell)
870 bview->getOwner()->getPopups().updateFormTabular();
875 bv->unlockInset(this);
880 int InsetTabular::Latex(Buffer const * buf, ostream & os,
881 bool fragile, bool fp) const
883 return tabular->Latex(buf, os, fragile, fp);
887 int InsetTabular::Ascii(Buffer const * buf, ostream & os) const
889 // This should be changed to a real ascii export
890 return tabular->Latex(buf, os, false, false);
894 int InsetTabular::Linuxdoc(Buffer const *, ostream &) const
900 int InsetTabular::DocBook(Buffer const *, ostream &) const
906 void InsetTabular::Validate(LaTeXFeatures & features) const
908 tabular->Validate(features);
912 bool InsetTabular::calculate_dimensions_of_cells(BufferView * bv,
913 LyXFont const & font,
919 bool changed = false;
921 for(int i = 0; i < tabular->rows(); ++i) {
922 maxAsc = maxDesc = 0;
923 for(int j= 0; j < tabular->columns(); ++j) {
924 if (tabular->IsPartOfMultiColumn(i,j))
927 inset = tabular->GetCellInset(cell);
929 inset->update(bv, font, false);
930 maxAsc = max(maxAsc, inset->ascent(bv, font));
931 maxDesc = max(maxDesc, inset->descent(bv, font));
932 changed = tabular->SetWidthOfCell(cell, inset->width(bv, font)) || changed;
934 changed = tabular->SetAscentOfRow(i, maxAsc + ADD_TO_HEIGHT) || changed;
935 changed = tabular->SetDescentOfRow(i, maxDesc + ADD_TO_HEIGHT) || changed;
941 void InsetTabular::GetCursorPos(BufferView *, int & x, int & y) const
943 x = cursor.x() - top_x;
948 void InsetTabular::ToggleInsetCursor(BufferView * bv)
950 if (the_locking_inset) {
951 the_locking_inset->ToggleInsetCursor(bv);
955 LyXFont font; // = the_locking_inset->GetFont(par, cursor.pos);
957 int asc = lyxfont::maxAscent(font);
958 int desc = lyxfont::maxDescent(font);
961 bv->hideLockedInsetCursor();
963 bv->showLockedInsetCursor(cursor.x(), cursor.y(), asc, desc);
964 cursor_visible = !cursor_visible;
968 void InsetTabular::ShowInsetCursor(BufferView * bv)
970 if (!cursor_visible) {
971 LyXFont font; // = GetFont(par, cursor.pos);
973 int asc = lyxfont::maxAscent(font);
974 int desc = lyxfont::maxDescent(font);
975 bv->fitLockedInsetCursor(cursor.x(), cursor.y(), asc, desc);
976 bv->showLockedInsetCursor(cursor.x(), cursor.y(), asc, desc);
977 cursor_visible = true;
982 void InsetTabular::HideInsetCursor(BufferView * bv)
984 if (cursor_visible) {
985 bv->hideLockedInsetCursor();
986 cursor_visible = false;
988 // if (cursor_visible)
989 // ToggleInsetCursor(bv);
993 void InsetTabular::setPos(BufferView * bv, int x, int y) const
998 actcell = actrow = actcol = 0;
999 int ly = tabular->GetDescentOfRow(actrow);
1001 // first search the right row
1002 while((ly < y) && (actrow < tabular->rows())) {
1003 cursor.y(cursor.y() + tabular->GetDescentOfRow(actrow) +
1004 tabular->GetAscentOfRow(actrow+1) +
1005 tabular->GetAdditionalHeight(tabular->GetCellNumber(actrow + 1,
1008 ly = cursor.y() + tabular->GetDescentOfRow(actrow);
1010 actcell = tabular->GetCellNumber(actrow, actcol);
1012 // now search the right column
1013 int lx = tabular->GetWidthOfColumn(actcell) -
1014 tabular->GetAdditionalWidth(actcell);
1015 for(; !tabular->IsLastCellInRow(actcell) && (lx < x);
1016 ++actcell,lx += tabular->GetWidthOfColumn(actcell) +
1017 tabular->GetAdditionalWidth(actcell - 1));
1020 if ((lx - (tabular->GetWidthOfColumn(actcell)/2)) < x) {
1021 cursor.x(lx + top_x - 2);
1024 cursor.x(lx - tabular->GetWidthOfColumn(actcell) + top_x + 2);
1030 int InsetTabular::getCellXPos(int cell) const
1034 for(c=cell;!tabular->IsFirstCellInRow(c);--c)
1036 int lx = tabular->GetWidthOfColumn(cell);
1037 for(; (c < cell); ++c) {
1038 lx += tabular->GetWidthOfColumn(c);
1040 return (lx - tabular->GetWidthOfColumn(cell) + top_x);
1044 void InsetTabular::resetPos(BufferView * bv) const
1048 actcol = tabular->column_of_cell(actcell);
1053 for(; (cell<actcell) && !tabular->IsLastRow(cell); ++cell) {
1054 if (tabular->IsLastCellInRow(cell)) {
1055 cursor.y(cursor.y() + tabular->GetDescentOfRow(actrow) +
1056 tabular->GetAscentOfRow(actrow + 1) +
1057 tabular->GetAdditionalHeight(cell + 1));
1061 static int offset = ADD_TO_TABULAR_WIDTH + 2;
1062 cursor.x(getCellXPos(actcell) + offset);
1063 if (((cursor.x() - offset) > 20) &&
1064 ((cursor.x()-offset+tabular->GetWidthOfColumn(actcell)) >
1065 (bv->workWidth()-20)))
1067 scroll(bv, -tabular->GetWidthOfColumn(actcell)-20);
1068 UpdateLocal(bv, FULL, false);
1069 } else if ((cursor.x() - offset) < 20) {
1070 scroll(bv, 20 - cursor.x() + offset);
1071 UpdateLocal(bv, FULL, false);
1072 } else if (!cellstart(cursor.pos())) {
1073 LyXFont font(LyXFont::ALL_SANE);
1074 cursor.x(cursor.x() + tabular->GetCellInset(actcell)->width(bv,font) +
1075 tabular->GetBeginningOfTextInCell(actcell));
1077 if ((!the_locking_inset ||
1078 !the_locking_inset->GetFirstLockingInsetOfType(TABULAR_CODE)) &&
1079 (actcell != oldcell)) {
1080 dialogs_ = bv->owner()->getDialogs();
1081 dialogs_->updateTabular(const_cast<InsetTabular *>(this));
1087 UpdatableInset::RESULT InsetTabular::moveRight(BufferView * bv, bool lock)
1089 if (!cellstart(cursor.pos())) {
1090 if (tabular->IsLastCell(actcell))
1093 cursor.pos((cursor.pos() + 1) % 2);
1095 if (ActivateCellInset(bv))
1097 } else { // before the inset
1098 cursor.pos((cursor.pos() + 1) % 2);
1101 return DISPATCHED_NOUPDATE;
1105 UpdatableInset::RESULT InsetTabular::moveLeft(BufferView * bv, bool lock)
1107 if (!cursor.pos()) {
1112 cursor.pos((cursor.pos() - 1) % 2);
1113 if (!cellstart(cursor.pos())) {
1115 } else if (lock) { // behind the inset
1116 if (ActivateCellInset(bv, 0, 0, 0, true))
1120 return DISPATCHED_NOUPDATE;
1124 UpdatableInset::RESULT InsetTabular::moveUp(BufferView * bv)
1126 int ocell = actcell;
1127 actcell = tabular->GetCellAbove(actcell);
1128 if (actcell == ocell) // we moved out of the inset
1131 return DISPATCHED_NOUPDATE;
1135 UpdatableInset::RESULT InsetTabular::moveDown(BufferView * bv)
1137 int ocell = actcell;
1138 actcell = tabular->GetCellBelow(actcell);
1139 if (actcell == ocell) // we moved out of the inset
1142 return DISPATCHED_NOUPDATE;
1146 bool InsetTabular::moveNextCell(BufferView * bv)
1148 if (tabular->IsLastCell(actcell))
1151 cursor.pos((cursor.pos() + 1) % 2);
1152 if (!cellstart(cursor.pos()))
1153 cursor.pos((cursor.pos() + 1) % 2);
1159 bool InsetTabular::movePrevCell(BufferView * bv)
1161 if (!actcell) // first cell
1164 cursor.pos((cursor.pos() - 1) % 2);
1165 if (cellstart(cursor.pos()))
1166 cursor.pos((cursor.pos() - 1) % 2);
1172 bool InsetTabular::Delete()
1178 void InsetTabular::SetFont(BufferView * bv, LyXFont const & font, bool tall)
1180 if (the_locking_inset)
1181 the_locking_inset->SetFont(bv, font, tall);
1185 bool InsetTabular::TabularFeatures(BufferView * bv, string what)
1187 int action = LyXTabular::LAST_ACTION;
1191 for(i=0; tabularFeatures[i].action != LyXTabular::LAST_ACTION; ++i) {
1192 if (!strncmp(tabularFeatures[i].feature.c_str(), what.c_str(),
1193 tabularFeatures[i].feature.length())) {
1194 action = tabularFeatures[i].action;
1198 if (action == LyXTabular::LAST_ACTION)
1201 val = frontStrip(what.substr(tabularFeatures[i].feature.length()));
1202 TabularFeatures(bv, action, val);
1207 void InsetTabular::TabularFeatures(BufferView * bv, int feature, string value)
1216 setAlign = LYX_ALIGN_LEFT,
1221 case LyXTabular::M_ALIGN_LEFT:
1222 case LyXTabular::ALIGN_LEFT:
1223 setAlign=LYX_ALIGN_LEFT;
1225 case LyXTabular::M_ALIGN_RIGHT:
1226 case LyXTabular::ALIGN_RIGHT:
1227 setAlign=LYX_ALIGN_RIGHT;
1229 case LyXTabular::M_ALIGN_CENTER:
1230 case LyXTabular::ALIGN_CENTER:
1231 setAlign=LYX_ALIGN_CENTER;
1233 case LyXTabular::M_VALIGN_TOP:
1234 case LyXTabular::VALIGN_TOP:
1235 setAlign=LyXTabular::LYX_VALIGN_TOP;
1237 case LyXTabular::M_VALIGN_BOTTOM:
1238 case LyXTabular::VALIGN_BOTTOM:
1239 setAlign=LyXTabular::LYX_VALIGN_BOTTOM;
1241 case LyXTabular::M_VALIGN_CENTER:
1242 case LyXTabular::VALIGN_CENTER:
1243 setAlign=LyXTabular::LYX_VALIGN_CENTER;
1248 if (hasSelection()) {
1250 sel_col_start = tabular->column_of_cell(sel_cell_start);
1251 sel_col_end = tabular->column_of_cell(sel_cell_end);
1252 if (sel_col_start > sel_col_end) {
1253 sel_col_end = sel_col_start;
1254 sel_col_start = tabular->column_of_cell(sel_cell_end);
1256 sel_col_end = tabular->right_column_of_cell(sel_cell_end);
1259 sel_row_start = tabular->row_of_cell(sel_cell_start);
1260 sel_row_end = tabular->row_of_cell(sel_cell_end);
1261 if (sel_row_start > sel_row_end) {
1262 tmp = sel_row_start;
1263 sel_row_start = sel_row_end;
1267 sel_col_start = sel_col_end = tabular->column_of_cell(actcell);
1268 sel_row_start = sel_row_end = tabular->row_of_cell(actcell);
1270 bv->text->SetUndo(bv->buffer(), Undo::FINISH,
1272 bv->text->cursor.par()->ParFromPos(bv->text->cursor.pos())->previous,
1273 bv->text->cursor.par()->ParFromPos(bv->text->cursor.pos())->next
1275 bv->text->cursor.par()->previous,
1276 bv->text->cursor.par()->next
1280 int row = tabular->row_of_cell(actcell);
1281 int column = tabular->column_of_cell(actcell);
1285 case LyXTabular::SET_PWIDTH:
1287 bool update = (tabular->GetColumnPWidth(actcell) != value);
1288 tabular->SetColumnPWidth(actcell,value);
1290 for (int i=0; i < tabular->rows(); ++i) {
1291 tabular->GetCellInset(tabular->GetCellNumber(i, column))->
1294 UpdateLocal(bv, INIT, true);
1298 case LyXTabular::SET_MPWIDTH:
1300 bool update = (tabular->GetPWidth(actcell) != value);
1301 tabular->SetMColumnPWidth(actcell,value);
1303 for (int i=0; i < tabular->rows(); ++i) {
1304 tabular->GetCellInset(tabular->GetCellNumber(i, column))->
1307 UpdateLocal(bv, INIT, true);
1311 case LyXTabular::SET_SPECIAL_COLUMN:
1312 case LyXTabular::SET_SPECIAL_MULTI:
1313 tabular->SetAlignSpecial(actcell,value,feature);
1315 case LyXTabular::APPEND_ROW:
1316 // append the row into the tabular
1317 UnlockInsetInInset(bv, the_locking_inset);
1318 tabular->AppendRow(actcell);
1319 UpdateLocal(bv, INIT, true);
1321 case LyXTabular::APPEND_COLUMN:
1322 // append the column into the tabular
1323 tabular->AppendColumn(actcell);
1324 actcell = tabular->GetCellNumber(row, column);
1325 UpdateLocal(bv, INIT, true);
1327 case LyXTabular::DELETE_ROW:
1328 tabular->DeleteRow(tabular->row_of_cell(actcell));
1329 if ((row+1) > tabular->rows())
1331 actcell = tabular->GetCellNumber(row, column);
1332 UpdateLocal(bv, INIT, true);
1334 case LyXTabular::DELETE_COLUMN:
1335 tabular->DeleteColumn(tabular->column_of_cell(actcell));
1336 if ((column+1) > tabular->columns())
1338 actcell = tabular->GetCellNumber(row, column);
1339 UpdateLocal(bv, INIT, true);
1341 case LyXTabular::M_TOGGLE_LINE_TOP:
1343 case LyXTabular::TOGGLE_LINE_TOP:
1344 lineSet = !tabular->TopLine(actcell, flag);
1345 for(i=sel_row_start; i<=sel_row_end; ++i)
1346 for(j=sel_col_start; j<=sel_col_end; ++j)
1347 tabular->SetTopLine(tabular->GetCellNumber(i,j),lineSet, flag);
1348 UpdateLocal(bv, INIT, true);
1351 case LyXTabular::M_TOGGLE_LINE_BOTTOM:
1353 case LyXTabular::TOGGLE_LINE_BOTTOM:
1354 lineSet = !tabular->BottomLine(actcell, flag);
1355 for(i=sel_row_start; i<=sel_row_end; ++i)
1356 for(j=sel_col_start; j<=sel_col_end; ++j)
1357 tabular->SetBottomLine(tabular->GetCellNumber(i,j),lineSet,
1359 UpdateLocal(bv, INIT, true);
1362 case LyXTabular::M_TOGGLE_LINE_LEFT:
1364 case LyXTabular::TOGGLE_LINE_LEFT:
1365 lineSet = !tabular->LeftLine(actcell, flag);
1366 for(i=sel_row_start; i<=sel_row_end; ++i)
1367 for(j=sel_col_start; j<=sel_col_end; ++j)
1368 tabular->SetLeftLine(tabular->GetCellNumber(i,j),lineSet,
1370 UpdateLocal(bv, INIT, true);
1373 case LyXTabular::M_TOGGLE_LINE_RIGHT:
1375 case LyXTabular::TOGGLE_LINE_RIGHT:
1376 lineSet = !tabular->RightLine(actcell, flag);
1377 for(i=sel_row_start; i<=sel_row_end; ++i)
1378 for(j=sel_col_start; j<=sel_col_end; ++j)
1379 tabular->SetRightLine(tabular->GetCellNumber(i,j),lineSet,
1381 UpdateLocal(bv, INIT, true);
1383 case LyXTabular::M_ALIGN_LEFT:
1384 case LyXTabular::M_ALIGN_RIGHT:
1385 case LyXTabular::M_ALIGN_CENTER:
1387 case LyXTabular::ALIGN_LEFT:
1388 case LyXTabular::ALIGN_RIGHT:
1389 case LyXTabular::ALIGN_CENTER:
1390 for(i=sel_row_start; i<=sel_row_end; ++i)
1391 for(j=sel_col_start; j<=sel_col_end; ++j)
1392 tabular->SetAlignment(tabular->GetCellNumber(i,j),setAlign,
1395 UpdateLocal(bv, INIT, true);
1397 UpdateLocal(bv, CELL, true);
1399 case LyXTabular::M_VALIGN_TOP:
1400 case LyXTabular::M_VALIGN_BOTTOM:
1401 case LyXTabular::M_VALIGN_CENTER:
1403 case LyXTabular::VALIGN_TOP:
1404 case LyXTabular::VALIGN_BOTTOM:
1405 case LyXTabular::VALIGN_CENTER:
1406 for(i=sel_row_start; i<=sel_row_end; ++i)
1407 for(j=sel_col_start; j<=sel_col_end; ++j)
1408 tabular->SetVAlignment(tabular->GetCellNumber(i,j), setAlign,
1411 UpdateLocal(bv, INIT, true);
1413 UpdateLocal(bv, CELL, true);
1415 case LyXTabular::MULTICOLUMN:
1417 if (sel_row_start != sel_row_end) {
1418 WriteAlert(_("Impossible Operation!"),
1419 _("Multicolumns can only be horizontally."),
1423 // just multicol for one Single Cell
1424 if (!hasSelection()) {
1425 // check wether we are completly in a multicol
1426 if (tabular->IsMultiColumn(actcell)) {
1427 tabular->UnsetMultiColumn(actcell);
1428 UpdateLocal(bv, INIT, true);
1430 tabular->SetMultiColumn(actcell, 1);
1431 UpdateLocal(bv, CELL, true);
1435 // we have a selection so this means we just add all this
1436 // cells to form a multicolumn cell
1440 if (sel_cell_start > sel_cell_end) {
1441 s_start = sel_cell_end;
1442 s_end = sel_cell_start;
1444 s_start = sel_cell_start;
1445 s_end = sel_cell_end;
1447 tabular->SetMultiColumn(s_start, s_end - s_start + 1);
1450 sel_cell_end = sel_cell_start;
1451 sel_pos_end = sel_pos_start;
1452 UpdateLocal(bv, INIT, true);
1455 case LyXTabular::SET_ALL_LINES:
1457 case LyXTabular::UNSET_ALL_LINES:
1458 for(i=sel_row_start; i<=sel_row_end; ++i)
1459 for(j=sel_col_start; j<=sel_col_end; ++j)
1460 tabular->SetAllLines(tabular->GetCellNumber(i,j), setLines);
1461 UpdateLocal(bv, INIT, true);
1463 case LyXTabular::SET_LONGTABULAR:
1464 tabular->SetLongTabular(true);
1465 UpdateLocal(bv, INIT, true); // because this toggles displayed
1467 case LyXTabular::UNSET_LONGTABULAR:
1468 tabular->SetLongTabular(false);
1469 UpdateLocal(bv, INIT, true); // because this toggles displayed
1471 case LyXTabular::SET_ROTATE_TABULAR:
1472 tabular->SetRotateTabular(true);
1474 case LyXTabular::UNSET_ROTATE_TABULAR:
1475 tabular->SetRotateTabular(false);
1477 case LyXTabular::SET_ROTATE_CELL:
1478 for(i=sel_row_start; i<=sel_row_end; ++i)
1479 for(j=sel_col_start; j<=sel_col_end; ++j)
1480 tabular->SetRotateCell(tabular->GetCellNumber(i,j),true);
1482 case LyXTabular::UNSET_ROTATE_CELL:
1483 for(i=sel_row_start; i<=sel_row_end; ++i)
1484 for(j=sel_col_start; j<=sel_col_end; ++j)
1485 tabular->SetRotateCell(tabular->GetCellNumber(i,j),false);
1487 case LyXTabular::SET_USEBOX:
1489 LyXTabular::BoxType val = static_cast<LyXTabular::BoxType>
1491 if (val == tabular->GetUsebox(actcell))
1492 val = LyXTabular::BOX_NONE;
1493 for(i=sel_row_start; i<=sel_row_end; ++i)
1494 for(j=sel_col_start; j<=sel_col_end; ++j)
1495 tabular->SetUsebox(tabular->GetCellNumber(i,j),val);
1498 case LyXTabular::SET_LTFIRSTHEAD:
1499 tabular->SetLTHead(actcell,true);
1501 case LyXTabular::SET_LTHEAD:
1502 tabular->SetLTHead(actcell,false);
1504 case LyXTabular::SET_LTFOOT:
1505 tabular->SetLTFoot(actcell,false);
1507 case LyXTabular::SET_LTLASTFOOT:
1508 tabular->SetLTFoot(actcell,true);
1510 case LyXTabular::SET_LTNEWPAGE:
1511 what = !tabular->GetLTNewPage(actcell);
1512 tabular->SetLTNewPage(actcell,what);
1518 bool InsetTabular::ActivateCellInset(BufferView * bv, int x, int y, int button,
1521 // the cursor.pos has to be before the inset so if it isn't now just
1522 // reset the curor pos first!
1523 if (!cellstart(cursor.pos())) {
1524 cursor.pos((cursor.pos() - 1) % 2);
1527 UpdatableInset * inset =
1528 static_cast<UpdatableInset*>(tabular->GetCellInset(actcell));
1529 LyXFont font(LyXFont::ALL_SANE);
1531 x = inset->x() + inset->width(bv, font);
1532 y = inset->descent(bv, font);
1534 inset_x = cursor.x() - top_x + tabular->GetBeginningOfTextInCell(actcell);
1535 inset_y = cursor.y();
1536 inset->Edit(bv, x - inset_x, y - inset_y, button);
1537 if (!the_locking_inset)
1539 UpdateLocal(bv, CELL, false);
1540 return (the_locking_inset != 0);
1544 bool InsetTabular::InsetHit(BufferView * bv, int x, int ) const
1546 InsetText * inset = tabular->GetCellInset(actcell);
1549 if (!cellstart(cursor.pos())) {
1550 return (((x + top_x) < cursor.x()) &&
1551 ((x + top_x) > (cursor.x() - inset->width(bv,
1552 LyXFont(LyXFont::ALL_SANE)))));
1554 int x2 = cursor.x() + tabular->GetBeginningOfTextInCell(actcell);
1555 return ((x1 > x2) &&
1556 (x1 < (x2 + inset->width(bv, LyXFont(LyXFont::ALL_SANE)))));
1561 // This returns paperWidth() if the cell-width is unlimited or the width
1562 // in pixels if we have a pwidth for this cell.
1563 int InsetTabular::GetMaxWidthOfCell(Painter &, int cell) const
1565 string s = tabular->GetPWidth(cell);
1569 return VSpace(s).inPixels( 0, 0);
1573 int InsetTabular::getMaxWidth(Painter & pain,
1574 UpdatableInset const * inset) const
1577 int n = tabular->GetNumberOfCells();
1578 for(cell=0; cell < n; ++cell) {
1579 if (tabular->GetCellInset(cell) == inset)
1584 int w = GetMaxWidthOfCell(pain, cell);
1586 // because the inset then subtracts it's top_x and owner->x()
1587 w += (inset->x() - top_x);
1592 void InsetTabular::resizeLyXText(BufferView *) const
1597 LyXText * InsetTabular::getLyXText(BufferView * bv) const
1599 if (the_locking_inset)
1600 return the_locking_inset->getLyXText(bv);
1601 return Inset::getLyXText(bv);
1605 void InsetTabular::OpenLayoutDialog(BufferView * bv) const
1607 if (the_locking_inset) {
1608 InsetTabular * i = static_cast<InsetTabular *>
1609 (the_locking_inset->GetFirstLockingInsetOfType(TABULAR_CODE));
1611 i->OpenLayoutDialog(bv);
1615 dialogs_ = bv->owner()->getDialogs();
1616 dialogs_->showTabular(const_cast<InsetTabular *>(this));
1620 // functions returns:
1624 // 3 ... toggled off
1626 LyXFunc::func_status InsetTabular::getStatus(string what) const
1628 int action = LyXTabular::LAST_ACTION;
1631 LyXFunc::func_status status = LyXFunc::OK;
1633 for(i=0; tabularFeatures[i].action != LyXTabular::LAST_ACTION; ++i) {
1634 if (!strncmp(tabularFeatures[i].feature.c_str(), what.c_str(),
1635 tabularFeatures[i].feature.length())) {
1636 action = tabularFeatures[i].action;
1640 if (action == LyXTabular::LAST_ACTION)
1641 return LyXFunc::Unknown;
1643 argument = frontStrip(what.substr(tabularFeatures[i].feature.length()));
1645 int sel_row_start, sel_row_end;
1649 if (hasSelection()) {
1651 sel_row_start = tabular->row_of_cell(sel_cell_start);
1652 sel_row_end = tabular->row_of_cell(sel_cell_end);
1653 if (sel_row_start > sel_row_end) {
1654 tmp = sel_row_start;
1655 sel_row_start = sel_row_end;
1659 sel_row_start = sel_row_end = tabular->row_of_cell(actcell);
1663 case LyXTabular::SET_PWIDTH:
1664 case LyXTabular::SET_MPWIDTH:
1665 case LyXTabular::SET_SPECIAL_COLUMN:
1666 case LyXTabular::SET_SPECIAL_MULTI:
1667 status |= LyXFunc::Disabled;
1670 case LyXTabular::APPEND_ROW:
1671 case LyXTabular::APPEND_COLUMN:
1672 case LyXTabular::DELETE_ROW:
1673 case LyXTabular::DELETE_COLUMN:
1674 case LyXTabular::SET_ALL_LINES:
1675 case LyXTabular::UNSET_ALL_LINES:
1676 status |= LyXFunc::OK;
1679 case LyXTabular::MULTICOLUMN:
1680 if (tabular->IsMultiColumn(actcell))
1681 status |= LyXFunc::ToggleOn;
1683 status |= LyXFunc::ToggleOff;
1685 case LyXTabular::M_TOGGLE_LINE_TOP:
1687 case LyXTabular::TOGGLE_LINE_TOP:
1688 if (tabular->TopLine(actcell, flag))
1689 status |= LyXFunc::ToggleOn;
1691 status |= LyXFunc::ToggleOff;
1693 case LyXTabular::M_TOGGLE_LINE_BOTTOM:
1695 case LyXTabular::TOGGLE_LINE_BOTTOM:
1696 if (tabular->BottomLine(actcell, flag))
1697 status |= LyXFunc::ToggleOn;
1699 status |= LyXFunc::ToggleOff;
1701 case LyXTabular::M_TOGGLE_LINE_LEFT:
1703 case LyXTabular::TOGGLE_LINE_LEFT:
1704 if (tabular->LeftLine(actcell, flag))
1705 status |= LyXFunc::ToggleOn;
1707 status |= LyXFunc::ToggleOff;
1709 case LyXTabular::M_TOGGLE_LINE_RIGHT:
1711 case LyXTabular::TOGGLE_LINE_RIGHT:
1712 if (tabular->RightLine(actcell, flag))
1713 status |= LyXFunc::ToggleOn;
1715 status |= LyXFunc::ToggleOff;
1717 case LyXTabular::M_ALIGN_LEFT:
1719 case LyXTabular::ALIGN_LEFT:
1720 if (tabular->GetAlignment(actcell, flag) == LYX_ALIGN_LEFT)
1721 status |= LyXFunc::ToggleOn;
1723 status |= LyXFunc::ToggleOff;
1725 case LyXTabular::M_ALIGN_RIGHT:
1727 case LyXTabular::ALIGN_RIGHT:
1728 if (tabular->GetAlignment(actcell, flag) == LYX_ALIGN_RIGHT)
1729 status |= LyXFunc::ToggleOn;
1731 status |= LyXFunc::ToggleOff;
1733 case LyXTabular::M_ALIGN_CENTER:
1735 case LyXTabular::ALIGN_CENTER:
1736 if (tabular->GetAlignment(actcell, flag) == LYX_ALIGN_CENTER)
1737 status |= LyXFunc::ToggleOn;
1739 status |= LyXFunc::ToggleOff;
1741 case LyXTabular::M_VALIGN_TOP:
1743 case LyXTabular::VALIGN_TOP:
1744 if (tabular->GetVAlignment(actcell, flag) == LyXTabular::LYX_VALIGN_TOP)
1745 status |= LyXFunc::ToggleOn;
1747 status |= LyXFunc::ToggleOff;
1749 case LyXTabular::M_VALIGN_BOTTOM:
1751 case LyXTabular::VALIGN_BOTTOM:
1752 if (tabular->GetVAlignment(actcell, flag) == LyXTabular::LYX_VALIGN_BOTTOM)
1753 status |= LyXFunc::ToggleOn;
1755 status |= LyXFunc::ToggleOff;
1757 case LyXTabular::M_VALIGN_CENTER:
1759 case LyXTabular::VALIGN_CENTER:
1760 if (tabular->GetVAlignment(actcell, flag) == LyXTabular::LYX_VALIGN_CENTER)
1761 status |= LyXFunc::ToggleOn;
1763 status |= LyXFunc::ToggleOff;
1765 case LyXTabular::SET_LONGTABULAR:
1766 if (tabular->IsLongTabular())
1767 status |= LyXFunc::ToggleOn;
1769 status |= LyXFunc::ToggleOff;
1771 case LyXTabular::UNSET_LONGTABULAR:
1772 if (!tabular->IsLongTabular())
1773 status |= LyXFunc::ToggleOn;
1775 status |= LyXFunc::ToggleOff;
1777 case LyXTabular::SET_ROTATE_TABULAR:
1778 if (tabular->GetRotateTabular())
1779 status |= LyXFunc::ToggleOn;
1781 status |= LyXFunc::ToggleOff;
1783 case LyXTabular::UNSET_ROTATE_TABULAR:
1784 if (!tabular->GetRotateTabular())
1785 status |= LyXFunc::ToggleOn;
1787 status |= LyXFunc::ToggleOff;
1789 case LyXTabular::SET_ROTATE_CELL:
1790 if (tabular->GetRotateCell(actcell))
1791 status |= LyXFunc::ToggleOn;
1793 status |= LyXFunc::ToggleOff;
1795 case LyXTabular::UNSET_ROTATE_CELL:
1796 if (!tabular->GetRotateCell(actcell))
1797 status |= LyXFunc::ToggleOn;
1799 status |= LyXFunc::ToggleOff;
1801 case LyXTabular::SET_USEBOX:
1802 if (strToInt(argument) == tabular->GetUsebox(actcell))
1803 status |= LyXFunc::ToggleOn;
1805 status |= LyXFunc::ToggleOff;
1807 case LyXTabular::SET_LTFIRSTHEAD:
1808 if (tabular->GetRowOfLTHead(actcell, dummy))
1809 status |= LyXFunc::ToggleOn;
1811 status |= LyXFunc::ToggleOff;
1813 case LyXTabular::SET_LTHEAD:
1814 if (tabular->GetRowOfLTHead(actcell, dummy))
1815 status |= LyXFunc::ToggleOn;
1817 status |= LyXFunc::ToggleOff;
1819 case LyXTabular::SET_LTFOOT:
1820 if (tabular->GetRowOfLTFoot(actcell, dummy))
1821 status |= LyXFunc::ToggleOn;
1823 status |= LyXFunc::ToggleOff;
1825 case LyXTabular::SET_LTLASTFOOT:
1826 if (tabular->GetRowOfLTFoot(actcell, dummy))
1827 status |= LyXFunc::ToggleOn;
1829 status |= LyXFunc::ToggleOff;
1831 case LyXTabular::SET_LTNEWPAGE:
1832 if (tabular->GetLTNewPage(actcell))
1833 status |= LyXFunc::ToggleOn;
1835 status |= LyXFunc::ToggleOff;
1838 status = LyXFunc::Disabled;
1845 bool InsetTabular::copySelection()
1847 if (!hasSelection())
1849 delete paste_tabular;
1851 int sel_col_start, sel_col_end;
1852 int sel_row_start, sel_row_end;
1854 sel_col_start = tabular->column_of_cell(sel_cell_start);
1855 sel_col_end = tabular->column_of_cell(sel_cell_end);
1856 if (sel_col_start > sel_col_end) {
1857 sel_col_start = sel_col_end;
1858 sel_col_end = tabular->right_column_of_cell(sel_cell_start);
1860 sel_col_end = tabular->right_column_of_cell(sel_cell_end);
1862 int columns = sel_col_end - sel_col_start + 1;
1864 sel_row_start = tabular->row_of_cell(sel_cell_start);
1865 sel_row_end = tabular->row_of_cell(sel_cell_end);
1866 if (sel_row_start > sel_row_end) {
1868 tmp = sel_row_start;
1869 sel_row_start = sel_row_end;
1872 int rows = sel_row_end - sel_row_start + 1;
1874 paste_tabular = new LyXTabular(this, rows, columns);
1876 if (sel_cell_start > sel_cell_end) {
1877 int tmp = sel_cell_start;
1878 sel_cell_start = sel_cell_end;
1881 for(int i=sel_cell_start, j=0; i <= sel_cell_end; ++i, ++j) {
1882 while(paste_tabular->row_of_cell(j) <
1883 (tabular->row_of_cell(i)-sel_row_start)) {
1886 while(paste_tabular->row_of_cell(j) >
1887 (tabular->row_of_cell(i)-sel_row_start)) {
1890 *(paste_tabular->GetCellInset(j)) = *(tabular->GetCellInset(i));
1896 bool InsetTabular::pasteSelection(BufferView * bv)
1900 for(int j=0, i=actcell; j<paste_tabular->GetNumberOfCells(); ++j,++i) {
1901 while (paste_tabular->row_of_cell(j) > tabular->row_of_cell(i)-actrow)
1903 if (tabular->GetNumberOfCells() <= i)
1905 while (paste_tabular->row_of_cell(j) < tabular->row_of_cell(i)-actrow)
1907 if (paste_tabular->GetNumberOfCells() <= j)
1909 *(tabular->GetCellInset(i)) = *(paste_tabular->GetCellInset(j));
1910 tabular->GetCellInset(i)->setOwner(this);
1911 tabular->GetCellInset(i)->deleteLyXText(bv);
1917 bool InsetTabular::cutSelection()
1919 if (!hasSelection())
1922 int sel_col_start, sel_col_end;
1923 int sel_row_start, sel_row_end;
1925 sel_col_start = tabular->column_of_cell(sel_cell_start);
1926 sel_col_end = tabular->column_of_cell(sel_cell_end);
1927 if (sel_col_start > sel_col_end) {
1928 sel_col_start = sel_col_end;
1929 sel_col_end = tabular->right_column_of_cell(sel_cell_start);
1931 sel_col_end = tabular->right_column_of_cell(sel_cell_end);
1933 sel_row_start = tabular->row_of_cell(sel_cell_start);
1934 sel_row_end = tabular->row_of_cell(sel_cell_end);
1935 if (sel_row_start > sel_row_end) {
1937 tmp = sel_row_start;
1938 sel_row_start = sel_row_end;
1941 if (sel_cell_start > sel_cell_end) {
1942 int tmp = sel_cell_start;
1943 sel_cell_start = sel_cell_end;
1947 for(i=sel_row_start; i <= sel_row_end; ++i) {
1948 for(j=sel_col_start; j <= sel_col_end; ++j) {
1949 tabular->GetCellInset(tabular->GetCellNumber(i, j))->clear();