- if (!cursor.par()->table)
- return; /* this should never happen */
-
- int actCell = NumberOfCell(cursor.par(), cursor.pos());
- SetUndo(bview->buffer(), Undo::FINISH,
- cursor.par()->ParFromPos(cursor.pos())->previous,
- cursor.par()->ParFromPos(cursor.pos())->next);
-
- switch (feature){
- case LyXTable::SET_PWIDTH:
- cursor.par()->table->SetPWidth(actCell, val);
- break;
- case LyXTable::SET_SPECIAL_COLUMN:
- case LyXTable::SET_SPECIAL_MULTI:
- cursor.par()->table->SetAlignSpecial(actCell, val, feature);
- break;
- default:
- break;
- }
- RedoParagraph(bview);
-}
-
-
-void LyXText::TableFeatures(BufferView * bview, int feature) const
-{
- int setLines = 0;
- int setAlign = LYX_ALIGN_LEFT;
- int lineSet;
- bool what;
-
- if (!cursor.par()->table)
- return; /* this should never happen */
-
- int actCell = NumberOfCell(cursor.par(), cursor.pos());
- SetUndo(bview->buffer(), Undo::FINISH,
- cursor.par()->ParFromPos(cursor.pos())->previous,
- cursor.par()->ParFromPos(cursor.pos())->next);
-
- switch (feature){
- case LyXTable::ALIGN_LEFT:
- setAlign= LYX_ALIGN_LEFT;
- break;
- case LyXTable::ALIGN_RIGHT:
- setAlign= LYX_ALIGN_RIGHT;
- break;
- case LyXTable::ALIGN_CENTER:
- setAlign= LYX_ALIGN_CENTER;
- break;
- default:
- break;
- }
- switch (feature){
- case LyXTable::APPEND_ROW: {
- LyXParagraph::size_type pos = cursor.pos();
-
- /* move to the next row */
- int cell_org = actCell;
- int cell = cell_org;
-
- // if there is a ContRow following this row I have to add
- // the row after the ContRow's
- if ((pos < cursor.par()->Last()) &&
- cursor.par()->table->RowHasContRow(cell_org)) {
- while((pos < cursor.par()->Last()) &&
- !cursor.par()->table->IsContRow(cell)) {
- while (pos < cursor.par()->Last() &&
- !cursor.par()->IsNewline(pos))
- ++pos;
- if (pos < cursor.par()->Last())
- ++pos;
- ++cell;
- }
- while((pos < cursor.par()->Last()) &&
- cursor.par()->table->IsContRow(cell)) {
- while (pos < cursor.par()->Last() &&
- !cursor.par()->IsNewline(pos))
- ++pos;
- if (pos < cursor.par()->Last())
- ++pos;
- ++cell;
- }
- cell_org = --cell;
- if (pos < cursor.par()->Last())
- --pos;
- }
- while (pos < cursor.par()->Last() &&
- (cell == cell_org || !cursor.par()->table->IsFirstCell(cell))){
- while (pos < cursor.par()->Last() && !cursor.par()->IsNewline(pos))
- ++pos;
- if (pos < cursor.par()->Last())
- ++pos;
- ++cell;
- }
-
- /* insert the new cells */
- int number = cursor.par()->table->NumberOfCellsInRow(cell_org);
- Language const * lang = cursor.par()->getParLanguage(bview->buffer()->params);
- LyXFont font(LyXFont::ALL_INHERIT,lang);
- for (int i = 0; i < number; ++i) {
- cursor.par()->InsertChar(pos, LyXParagraph::META_NEWLINE);
- cursor.par()->SetFont(pos, font);
- }
-
- /* append the row into the table */
- cursor.par()->table->AppendRow(cell_org);
- RedoParagraph(bview);
- return;
- }
- case LyXTable::APPEND_CONT_ROW: {
- LyXParagraph::size_type pos = cursor.pos();
- /* move to the next row */
- int cell_org = actCell;
- int cell = cell_org;
-
- // if there is already a controw but not for this cell
- // the AppendContRow sets only the right values but does
- // not actually add a row
- if (cursor.par()->table->RowHasContRow(cell_org) &&
- (cursor.par()->table->CellHasContRow(cell_org)<0)) {
- cursor.par()->table->AppendContRow(cell_org);
- RedoParagraph(bview);
- return;
- }
- while (pos < cursor.par()->Last() &&
- (cell == cell_org
- || !cursor.par()->table->IsFirstCell(cell))){
- while (pos < cursor.par()->Last() && !cursor.par()->IsNewline(pos))
- ++pos;
- if (pos < cursor.par()->Last())
- ++pos;
- ++cell;
- }
-
- /* insert the new cells */
- int number = cursor.par()->table->NumberOfCellsInRow(cell_org);
- Language const * lang = cursor.par()->getParLanguage(bview->buffer()->params);
- LyXFont font(LyXFont::ALL_INHERIT,lang);
- for (int i = 0; i < number; ++i) {
- cursor.par()->InsertChar(pos, LyXParagraph::META_NEWLINE);
- cursor.par()->SetFont(pos, font);
- }
-
- /* append the row into the table */
- cursor.par()->table->AppendContRow(cell_org);
- RedoParagraph(bview);
- return;
- }
- case LyXTable::APPEND_COLUMN: {
- LyXParagraph::size_type pos = 0;
- int cell_org = actCell;
- int cell = 0;
- Language const * lang = cursor.par()->getParLanguage(bview->buffer()->params);
- LyXFont font(LyXFont::ALL_INHERIT,lang);
- do{
- if (pos && (cursor.par()->IsNewline(pos-1))){
- if (cursor.par()->table->AppendCellAfterCell(cell_org, cell)) {
- cursor.par()->InsertChar(pos, LyXParagraph::META_NEWLINE);
- cursor.par()->SetFont(pos, font);
- if (pos <= cursor.pos())
- cursor.pos(cursor.pos() + 1);
- ++pos;
- }
- ++cell;
- }
- ++pos;
- } while (pos <= cursor.par()->Last());
- /* remember that the very last cell doesn't end with a newline.
- This saves one byte memory per table ;-) */
- if (cursor.par()->table->AppendCellAfterCell(cell_org, cell)) {
- LyXParagraph::size_type last = cursor.par()->Last();
- cursor.par()->InsertChar(last, LyXParagraph::META_NEWLINE);
- cursor.par()->SetFont(last, font);
- }
-
- /* append the column into the table */
- cursor.par()->table->AppendColumn(cell_org);
-
- RedoParagraph(bview);
- return;
- }
- case LyXTable::DELETE_ROW:
- if (bview->the_locking_inset)
- bview->unlockInset(bview->the_locking_inset);
- RemoveTableRow(cursor);
- RedoParagraph(bview);
- return;
-
- case LyXTable::DELETE_COLUMN: {
- LyXParagraph::size_type pos = 0;
- int cell_org = actCell;
- int cell = 0;
- if (bview->the_locking_inset)
- bview->unlockInset(bview->the_locking_inset);
- do {
- if (!pos || (cursor.par()->IsNewline(pos-1))){
- if (cursor.par()->table->DeleteCellIfColumnIsDeleted(cell, cell_org)){
- // delete one cell
- while (pos < cursor.par()->Last() && !cursor.par()->IsNewline(pos))
- cursor.par()->Erase(pos);
- if (pos < cursor.par()->Last())
- cursor.par()->Erase(pos);
- else
- cursor.par()->Erase(pos - 1); // the missing newline at the end of a table
- --pos; // because of pos++ below
- }
- ++cell;
- }
- ++pos;
- } while (pos <= cursor.par()->Last());
-
- /* delete the column from the table */
- cursor.par()->table->DeleteColumn(cell_org);
-
- /* set the cursor to the beginning of the table, where else? */
- cursor.pos(0);
- RedoParagraph(bview);
- return;
- }
- case LyXTable::TOGGLE_LINE_TOP:
- lineSet = !cursor.par()->table->TopLine(actCell);
- if (!selection){
- cursor.par()->table->SetTopLine(actCell, lineSet);
- } else {
- LyXParagraph::size_type i;
- int n = -1, m = -2;
- for (i = sel_start_cursor.pos(); i <= sel_end_cursor.pos(); ++i){
- if ((n = NumberOfCell(sel_start_cursor.par(), i)) != m) {
- cursor.par()->table->SetTopLine(n, lineSet);
- m = n;
- }
- }
- }
- RedoParagraph(bview);
- return;
-
- case LyXTable::TOGGLE_LINE_BOTTOM:
- lineSet = !cursor.par()->table->BottomLine(actCell);
- if (!selection){
- cursor.par()->table->SetBottomLine(actCell, lineSet);
- } else {
- LyXParagraph::size_type i;
- int n = -1, m = -2;
- for (i = sel_start_cursor.pos(); i <= sel_end_cursor.pos(); ++i) {
- if ((n = NumberOfCell(sel_start_cursor.par(), i)) != m) {
- cursor.par()->table->SetBottomLine(n, lineSet);
- m = n;
- }
- }
- }
- RedoParagraph(bview);
- return;
-
- case LyXTable::TOGGLE_LINE_LEFT:
- lineSet = !cursor.par()->table->LeftLine(actCell);
- if (!selection){
- cursor.par()->table->SetLeftLine(actCell, lineSet);
- } else {
- LyXParagraph::size_type i;
- int n = -1, m = -2;
- for (i = sel_start_cursor.pos(); i <= sel_end_cursor.pos(); ++i){
- if ((n= NumberOfCell(sel_start_cursor.par(), i)) != m) {
- cursor.par()->table->SetLeftLine(n, lineSet);
- m = n;
- }
- }
- }
- RedoParagraph(bview);
- return;
-
- case LyXTable::TOGGLE_LINE_RIGHT:
- lineSet = !cursor.par()->table->RightLine(actCell);
- if (!selection){
- cursor.par()->table->SetRightLine(actCell, lineSet);
- } else {
- int n = -1, m = -2;
- LyXParagraph::size_type i = sel_start_cursor.pos();
- for (; i <= sel_end_cursor.pos(); ++i) {
- if ((n= NumberOfCell(sel_start_cursor.par(), i)) != m) {
- cursor.par()->table->SetRightLine(n, lineSet);
- m = n;
- }
- }
- }
- RedoParagraph(bview);
- return;
-
- case LyXTable::ALIGN_LEFT:
- case LyXTable::ALIGN_RIGHT:
- case LyXTable::ALIGN_CENTER:
- if (!selection){
- cursor.par()->table->SetAlignment(actCell, setAlign);
- } else {
- int n = -1, m = -2;
- LyXParagraph::size_type i = sel_start_cursor.pos();
- for (; i <= sel_end_cursor.pos(); ++i) {
- if ((n= NumberOfCell(sel_start_cursor.par(), i)) != m) {
- cursor.par()->table->SetAlignment(n, setAlign);
- m = n;
- }
- }
- }
- RedoParagraph(bview);
- return;
-
- case LyXTable::DELETE_TABLE:
- SetCursorIntern(bview, cursor.par(), 0);
- delete cursor.par()->table;
- cursor.par()->table = 0;
- // temporary: Should put table in simple_cut_buffer (with before and after
- // dummy-paragraph !!
- // not necessar anymore with UNDO :)
- for (LyXParagraph::size_type i =
- cursor.par()->size() - 1; i >= 0; --i)
- cursor.par()->Erase(i);
- RedoParagraph(bview);
- return;
-
- case LyXTable::MULTICOLUMN: {
- int number = 0;
- // check wether we are completly in a multicol
- int multicol = cursor.par()->table->IsMultiColumn(actCell);
- if (multicol && selection && sel_start_cursor.row() == sel_end_cursor.row()) {
- multicol = NumberOfCell(sel_start_cursor.par(), sel_start_cursor.pos())
- == NumberOfCell(sel_end_cursor.par(), sel_end_cursor.pos());
- }
-
- if (multicol){
- int newlines = cursor.par()->table->UnsetMultiColumn(actCell);
- LyXParagraph::size_type pos = cursor.pos();
- while (pos < cursor.par()->Last() && !cursor.par()->IsNewline(pos))
- ++pos;
- for (; newlines; --newlines)
- cursor.par()->InsertChar(pos, LyXParagraph::META_NEWLINE);
- RedoParagraph(bview);
- return;
- }
- else {
- // selection must be in one row (or no selection)
- if (!selection){
- cursor.par()->table->SetMultiColumn(NumberOfCell(cursor.par(),
- cursor.pos()),
- 1);
- RedoParagraph(bview);
- return;
- }
- else {
- if (sel_start_cursor.row() == sel_end_cursor.row()){
- LyXParagraph::size_type i;
- number = 1;
- for (i = sel_start_cursor.pos();
- i < sel_end_cursor.pos(); ++i){
- if (sel_start_cursor.par()->IsNewline(i)){
- sel_start_cursor.par()->Erase(i);
- // check for double-blanks
- if ((i && !sel_start_cursor.par()->IsLineSeparator(i-1))
- &&
- (i < sel_start_cursor.par()->Last()
- && !sel_start_cursor.par()->IsLineSeparator(i)))
- sel_start_cursor.par()->InsertChar(i, ' ');
- else {
- sel_end_cursor.pos(sel_end_cursor.pos() - 1);
- --i;
- }
- ++number;
- }
- }
- cursor.par()->table->
- SetMultiColumn(NumberOfCell(sel_start_cursor.par(),
- sel_start_cursor.pos()),
- number);
- cursor.pos(sel_start_cursor.pos());
- RedoParagraph(bview);
- return;
- }
- else {
- WriteAlert(_("Impossible Operation!"),
- _("Multicolumns can only be horizontally."),
- _("Sorry."));
- }
- }
- }
- break;
- }
- case LyXTable::SET_ALL_LINES:
- setLines = 1;
- case LyXTable::UNSET_ALL_LINES:
- if (!selection){
- cursor.par()->table->SetAllLines(NumberOfCell(cursor.par(),
- cursor.pos()),
- setLines);
- } else {
- LyXParagraph::size_type i;
- int n = -1, m = -2;
- for (i = sel_start_cursor.pos(); i <= sel_end_cursor.pos(); ++i) {
- if ((n= NumberOfCell(sel_start_cursor.par(), i)) != m) {
- cursor.par()->table->SetAllLines(n, setLines);
- m = n;
- }
- }
- }
- RedoParagraph(bview);
- return;
- case LyXTable::SET_LONGTABLE:
- cursor.par()->table->SetLongTable(true);
- return;
- case LyXTable::UNSET_LONGTABLE:
- cursor.par()->table->SetLongTable(false);
- return;
- case LyXTable::SET_ROTATE_TABLE:
- cursor.par()->table->SetRotateTable(true);
- return;
- case LyXTable::UNSET_ROTATE_TABLE:
- cursor.par()->table->SetRotateTable(false);
- return;
- case LyXTable::SET_ROTATE_CELL:
- if (!selection){
- cursor.par()->table->SetRotateCell(actCell, true);
- } else {
- LyXParagraph::size_type i;
- int n = -1, m = -2;
- for (i = sel_start_cursor.pos(); i <= sel_end_cursor.pos(); ++i){
- if ((n = NumberOfCell(sel_start_cursor.par(), i)) != m) {
- cursor.par()->table->SetRotateCell(n, true);
- m = n;
- }
- }
- }
- return;
- case LyXTable::UNSET_ROTATE_CELL:
- if (!selection){
- cursor.par()->table->SetRotateCell(actCell, false);
- } else {
- int n = -1, m = -2;
- LyXParagraph::size_type i = sel_start_cursor.pos();
- for (; i <= sel_end_cursor.pos(); ++i) {
- if ((n= NumberOfCell(sel_start_cursor.par(), i)) != m) {
- cursor.par()->table->SetRotateCell(n, false);
- m = n;
- }
- }
- }
- return;
- case LyXTable::SET_LINEBREAKS:
- what = !cursor.par()->table->Linebreaks(cursor.par()->table->FirstVirtualCell(actCell));
- if (!selection){
- cursor.par()->table->SetLinebreaks(actCell, what);
- } else {
- LyXParagraph::size_type i;
- int n = -1, m = -2;
- for (i = sel_start_cursor.pos(); i <= sel_end_cursor.pos(); ++i) {
- if ((n = NumberOfCell(sel_start_cursor.par(), i)) != m) {
- cursor.par()->table->SetLinebreaks(n, what);
- m = n;
- }
- }
- }
- return;
- case LyXTable::SET_LTFIRSTHEAD:
- cursor.par()->table->SetLTHead(actCell, true);
- return;
- case LyXTable::SET_LTHEAD:
- cursor.par()->table->SetLTHead(actCell, false);
- return;
- case LyXTable::SET_LTFOOT:
- cursor.par()->table->SetLTFoot(actCell, false);
- return;
- case LyXTable::SET_LTLASTFOOT:
- cursor.par()->table->SetLTFoot(actCell, true);
- return;
- case LyXTable::SET_LTNEWPAGE:
- what = !cursor.par()->table->LTNewPage(actCell);
- cursor.par()->table->SetLTNewPage(actCell, what);
- return;
- }
-}
-
-
-void LyXText::InsertCharInTable(BufferView * bview, char c)
-{
- Row * row = 0;
- Row * tmprow = 0;
- long y;
- bool jumped_over_space;
-
- /* first check, if there will be two blanks together or a blank at
- * the beginning of a paragraph.
- * I decided to handle blanks like normal characters, the main
- * difference are the special checks when calculating the row.fill
- * (blank does not count at the end of a row) and the check here */
-
- LyXFont realtmpfont = real_current_font;
- LyXFont rawtmpfont = current_font; /* store the current font.
- * This is because of the use
- * of cursor movements. The moving
- * cursor would refresh the
- * current font */
-
- // Get the font that is used to calculate the baselineskip
- LyXParagraph::size_type const lastpos =
- cursor.par()->Last();
- LyXFont rawparfont = cursor.par()->GetFontSettings(bview->buffer()->params,
- lastpos - 1);
-
- jumped_over_space = false;
- if (IsLineSeparatorChar(c)) {
- if ((cursor.pos() > 0 &&
- cursor.par()->IsLineSeparator(cursor.pos() - 1))
- || (cursor.pos() > 0 && cursor.par()->IsNewline(cursor.pos() - 1))
- || (cursor.pos() == 0 &&
- !(cursor.par()->Previous()
- && cursor.par()->Previous()->footnoteflag
- == LyXParagraph::OPEN_FOOTNOTE)))
- return;
- } else if (IsNewlineChar(c)) {
- if (!IsEmptyTableCell()) {
- TableFeatures(bview, LyXTable::APPEND_CONT_ROW);
- CursorDown(bview);
- }
- return;
- }
-
- row = cursor.row();
- y = cursor.y() - row->baseline();
- if (c != LyXParagraph::META_INSET) /* in this case LyXText::InsertInset
- * already inserted the character */
- cursor.par()->InsertChar(cursor.pos(), c);
- SetCharFont(bview->buffer(), cursor.par(), cursor.pos(), rawtmpfont);
-
- if (!jumped_over_space) {
- /* refresh the positions */
- tmprow = row;
- while (tmprow->next() && tmprow->next()->par() == row->par()) {
- tmprow = tmprow->next();
- tmprow->pos(tmprow->pos() + 1);
- }
- }
-
- cursor.pos(cursor.pos() + 1);
-
- CheckParagraphInTable(bview, cursor.par(), cursor.pos());
-
- current_font = rawtmpfont;
- real_current_font = realtmpfont;
-
- /* check, whether the last character's font has changed. */
- if (cursor.pos() && cursor.pos() == cursor.par()->Last()
- && rawparfont != rawtmpfont)
- RedoHeightOfParagraph(bview, cursor);
-}
-
-
-void LyXText::CheckParagraphInTable(BufferView * bview, LyXParagraph * par,
- LyXParagraph::size_type pos)
-{
-
- if (par->GetChar(pos) == LyXParagraph::META_INSET &&
- par->GetInset(pos) && par->GetInset(pos)->display()){
- par->GetInset(pos)->display(false);
- }
-
- long y;
- Row * row = GetRow(par, pos, y);
-
- int tmpheight = row->height();
- SetHeightOfRow(bview, row);
-
- LyXParagraph::size_type tmp_pos = pos;
- /* update the table information */
- while (tmp_pos && !par->IsNewline(tmp_pos - 1))
- --tmp_pos;
- if (par->table->SetWidthOfCell(NumberOfCell(par, pos),
- WidthOfCell(bview, par, tmp_pos))) {
- LyXCursor tmpcursor = cursor;
- SetCursorIntern(bview, par, pos, false);
- /* make a complete redraw */
- RedoDrawingOfParagraph(bview, cursor);
- cursor = tmpcursor;
- }
- else {
- /* redraw only the row */
- LyXCursor tmpcursor = cursor;
- SetCursorIntern(bview, par, pos);
- //CHECK See comment on top of text.C
- refresh_y = y;
- refresh_x = cursor.x();
- refresh_row = row;
- refresh_pos = cursor.pos();
- cursor = tmpcursor;
-
- if (tmpheight == row->height())
- status = LyXText::NEED_VERY_LITTLE_REFRESH;
- else
- status = LyXText::NEED_MORE_REFRESH;
- }
- SetCursorIntern(bview, cursor.par(), cursor.pos(), false,
- cursor.boundary());
-}
-
-
-void LyXText::BackspaceInTable(BufferView * bview)
-{
- Row * tmprow, * row;
- long y;
-
- LyXFont rawtmpfont = current_font;
- LyXFont realtmpfont = real_current_font;
-
- // Get the font that is used to calculate the baselineskip
- int const lastpos = cursor.par()->Last();
- LyXFont rawparfont = cursor.par()->GetFontSettings(bview->buffer()->params,
- lastpos - 1);
-
- if (cursor.pos() == 0) {
- /* no pasting of table paragraphs */
-
- CursorLeft(bview);
- } else {
- /* this is the code for a normal backspace, not pasting
- * any paragraphs */
- SetUndo(bview->buffer(), Undo::DELETE,
- cursor.par()->ParFromPos(cursor.pos())->previous,
- cursor.par()->ParFromPos(cursor.pos())->next);
-
- CursorLeftIntern(bview);
-
- /* some insets are undeletable here */
- if (cursor.par()->GetChar(cursor.pos()) == LyXParagraph::META_INSET) {
- if (!cursor.par()->GetInset(cursor.pos())->Deletable())
- return;
- }
-
- row = cursor.row();
- y = cursor.y() - row->baseline();
-
- /* some special code when deleting a newline. */
- if (cursor.par()->IsNewline(cursor.pos())) {
- /* nothing :-) */
- return;
- } else {
- cursor.par()->Erase(cursor.pos());
-
- /* refresh the positions */
- tmprow = row;
- while (tmprow->next()
- && tmprow->next()->par() == row->par()) {
- tmprow = tmprow->next();
- tmprow->pos(tmprow->pos() - 1);
- }
- }
-
- CheckParagraphInTable(bview, cursor.par(), cursor.pos());
-
- /* check, wether the last characters font has changed. */
- if (cursor.pos() && cursor.pos() == cursor.par()->Last()
- && rawparfont != rawtmpfont)
- RedoHeightOfParagraph(bview, cursor);
-
- /* restore the current font
- * That is what a user expects! */
- current_font = rawtmpfont;
- real_current_font = realtmpfont;
- }
- SetCursorIntern(bview, cursor.par(), cursor.pos(), true,
- cursor.boundary());
- if (IsBoundary(bview->buffer(), cursor.par(), cursor.pos()) != cursor.boundary())
- SetCursor(bview, cursor.par(), cursor.pos(), false, !cursor.boundary());
-}
-
-/* table stuff -- end*/
-
-
-// Just a macro to make some thing easier.
-void LyXText::RedoParagraph(BufferView * bview) const
-{
- ClearSelection();
- RedoParagraphs(bview, cursor, cursor.par()->Next());