Implement proper pasting from multiple table cells to non-table (#4447)

This commit is contained in:
Juergen Spitzmueller 2020-06-29 15:13:45 +02:00
parent 2cee820f71
commit 5cb89a8f81
3 changed files with 51 additions and 13 deletions

View File

@ -1087,14 +1087,14 @@ void copySelectionToTemp(Cursor & cur)
void copySelection(Cursor const & cur, docstring const & plaintext)
{
// In tablemode, because copy and paste actually use special table stack
// we do not attempt to get selected paragraphs under cursor. Instead, a
// paragraph with the plain text version is generated so that table cells
// can be pasted as pure text somewhere else.
// In tablemode, because copy and paste actually use a special table stack,
// we need to go through the cells and collect the paragraphs.
// In math matrices, we generate a plain text version.
if (cur.selBegin().idx() != cur.selEnd().idx()) {
ParagraphList pars;
Paragraph par;
BufferParams const & bp = cur.buffer()->params();
if (cur.inMathed()) {
Paragraph par;
par.setLayout(bp.documentClass().plainLayout());
// Replace (column-separating) tabs by space (#4449)
docstring const clean_text = subst(plaintext, '\t', ' ');
@ -1103,6 +1103,26 @@ void copySelection(Cursor const & cur, docstring const & plaintext)
par.insert(0, clean_text, Font(sane_font, par.getParLanguage(bp)),
Change(Change::UNCHANGED));
pars.push_back(par);
} else {
// Get paragraphs from all cells
InsetTabular * table = cur.inset().asInsetTabular();
LASSERT(table, return);
ParagraphList tplist = table->asParList(cur.selBegin().idx(), cur.selEnd().idx());
for (auto & cpar : tplist) {
cpar.setLayout(bp.documentClass().plainLayout());
pars.push_back(cpar);
// since the pars are merged later, we separate them by blank
Paragraph epar;
epar.insert(0, from_ascii(" "), Font(sane_font, epar.getParLanguage(bp)),
Change(Change::UNCHANGED));
pars.push_back(epar);
}
// remove last empty par
pars.pop_back();
// merge all paragraphs to one
while (pars.size() > 1)
mergeParagraph(bp, pars, 0);
}
theCuts.push(make_pair(pars, bp.documentClassPtr()));
} else {
copySelectionToStack(cur, theCuts);

View File

@ -7206,6 +7206,22 @@ docstring InsetTabular::asString(idx_type stidx, idx_type enidx,
}
ParagraphList InsetTabular::asParList(idx_type stidx, idx_type enidx)
{
LASSERT(stidx <= enidx, return ParagraphList());
ParagraphList retval;
col_type const col1 = tabular.cellColumn(stidx);
col_type const col2 = tabular.cellColumn(enidx);
row_type const row1 = tabular.cellRow(stidx);
row_type const row2 = tabular.cellRow(enidx);
for (col_type col = col1; col <= col2; col++)
for (row_type row = row1; row <= row2; row++)
for (auto par : tabular.cellInset(row, col)->paragraphs())
retval.push_back(par);
return retval;
}
void InsetTabular::getSelection(Cursor & cur,
row_type & rs, row_type & re, col_type & cs, col_type & ce) const
{

View File

@ -1075,6 +1075,8 @@ public:
/// writes the cells between stidx and enidx as a string, optionally
/// descending into the insets
docstring asString(idx_type stidx, idx_type enidx, bool intoInsets = true);
///
ParagraphList asParList(idx_type stidx, idx_type enidx);
/// Returns whether the cell in the specified row and column is selected.
bool isCellSelected(Cursor & cur, row_type row, col_type col) const;