#include "frontends/Dialogs.h"
#include "debug.h"
#include "lyxfunc.h"
+#include "WorkArea.h"
const int ADD_TO_HEIGHT = 2;
const int ADD_TO_TABULAR_WIDTH = 2;
using std::max;
using std::endl;
using std::swap;
+using std::max;
struct tabular_features {
Painter & pain = bv->painter();
int i, j;
int nx;
- float cx;
UpdatableInset::draw(bv, font, baseline, x, cleared);
if (!cleared && ((need_update == INIT) || (need_update == FULL) ||
x += ADD_TO_TABULAR_WIDTH;
if (cleared) {
int cell = 0;
+ float cx;
for (i = 0; i < tabular->rows(); ++i) {
nx = int(x);
dodraw = ((baseline + tabular->GetDescentOfRow(i)) > 0) &&
lyxerr[Debug::INSETS] << "ERROR this shouldn't happen\n";
return;
}
+// LyXText::text_status st = bv->text->status;
#if 0
- LyXText::text_status st = bv->text->status;
do {
- cx = nx + tabular->GetBeginningOfTextInCell(cell);
+ float cx = nx + tabular->GetBeginningOfTextInCell(cell);
bv->text->status = st;
if (need_update == CELL) {
// clear before the inset
tabular->GetCellInset(cell)->draw(bv,font,baseline, cx, false);
} while(bv->text->status == LyXText::CHANGED_IN_DRAW);
#else
- cx = nx + tabular->GetBeginningOfTextInCell(cell);
+ float dx;
+ float cx;
+ cx = dx = nx + tabular->GetBeginningOfTextInCell(cell);
+ tabular->GetCellInset(cell)->draw(bv,font,baseline, dx, false);
+ if (bv->text->status == LyXText::CHANGED_IN_DRAW)
+ return;
+ // clear only if we didn't have a change
if (need_update == CELL) {
// clear before the inset
pain.fillRectangle(
tabular->GetAscentOfRow(i) +
tabular->GetDescentOfRow(i) - 1);
}
- tabular->GetCellInset(cell)->draw(bv,font,baseline, cx, false);
- if (bv->text->status == LyXText::CHANGED_IN_DRAW)
- return;
#endif
}
x -= ADD_TO_TABULAR_WIDTH;
sel_pos_start = sel_pos_end = cursor.pos();
sel_cell_start = sel_cell_end = actcell;
bv->text->FinishUndo();
- if (InsetHit(bv, x, y)) {
+ if (InsetHit(bv, x, y) && (button != 3)) {
ActivateCellInset(bv, x, y, button);
}
// UpdateLocal(bv, NONE, false);
{
if (need_update < what) // only set this if it has greater update
need_update = what;
+ if ((what == INIT) && hasSelection())
+ clearSelection();
// Dirty Cast! (Lgb)
if (need_update != NONE) {
bv->updateInset(const_cast<InsetTabular *>(this), mark_dirty);
void InsetTabular::InsetButtonPress(BufferView * bv, int x, int y, int button)
{
- if (hasSelection() && (button != 3)) {
+ if (hasSelection() && (button == 3))
+ return;
+
+ if (hasSelection()) {
clearSelection();
UpdateLocal(bv, SELECTION, false);
}
+
no_selection = false;
int const ocell = actcell;
UpdateLocal(bv, NONE, false);
sel_pos_start = sel_pos_end = cursor.pos();
sel_cell_start = sel_cell_end = actcell;
+ if (button == 3) {
+ if ((ocell != actcell) && the_locking_inset) {
+ the_locking_inset->InsetUnlock(bv);
+ the_locking_inset = 0;
+ }
+ ShowInsetCursor(bv);
+ return;
+ }
bool const inset_hit = InsetHit(bv, x, y);
the_locking_inset->InsetUnlock(bv);
}
the_locking_inset = 0;
+ if (button == 2) {
+ LocalDispatch(bv, LFUN_PASTESELECTION, "paragraph");
+ return;
+ }
if (inset_hit && bv->theLockingInset()) {
if (ActivateCellInset(bv, x, y, button))
the_locking_inset->InsetButtonPress(bv, x - inset_x,
the_locking_inset->ToggleInsetCursor(bv);
return result;
} else if (result == FINISHED) {
+ result = DISPATCHED;
if ((action == LFUN_RIGHT) || (action == -1)) {
cursor.pos(inset_pos + 1);
resetPos(bv);
+ } else if (action == LFUN_DOWN) {
+ if (moveDown(bv) == FINISHED) {
+ bv->unlockInset(this);
+ result = FINISHED;
+ }
+ } else if (action == LFUN_UP) {
+ if (moveUp(bv) == FINISHED) {
+ bv->unlockInset(this);
+ result = FINISHED;
+ }
}
sel_pos_start = sel_pos_end = cursor.pos();
sel_cell_start = sel_cell_end = actcell;
the_locking_inset=0;
ShowInsetCursor(bv);
- result = DISPATCHED;
return result;
}
}
bv->text->FinishUndo();
copySelection(bv);
break;
- case LFUN_PASTE:
- if (!hasPasteBuffer())
+ case LFUN_PASTESELECTION:
+ {
+ string clip(bv->workarea()->getClipboard());
+
+ if (clip.empty())
break;
- bv->text->SetUndo(bv->buffer(), Undo::INSERT,
+ if (clip.find('\t') != string::npos) {
+ int cols = 1;
+ int rows = 1;
+ int maxCols = 1;
+ unsigned int len = clip.length();
+ string::size_type p = 0;
+
+ while((p < len) &&
+ ((p = clip.find_first_of("\t\n", p)) != string::npos))
+ {
+ switch(clip[p]) {
+ case '\t':
+ ++cols;
+ break;
+ case '\n':
+ if ((p+1) < len)
+ ++rows;
+ maxCols = max(cols, maxCols);
+ cols = 1;
+ break;
+ }
+ ++p;
+ }
+ maxCols = max(cols, maxCols);
+ delete paste_tabular;
+ paste_tabular = new LyXTabular(this, rows, maxCols);
+ string::size_type op = 0;
+ int cell = 0;
+ int cells = paste_tabular->GetNumberOfCells();
+ p = cols = 0;
+ while((cell < cells) && (p < len) &&
+ (p = clip.find_first_of("\t\n", p)) != string::npos)
+ {
+ if (p >= len)
+ break;
+ switch(clip[p]) {
+ case '\t':
+ paste_tabular->GetCellInset(cell)->SetText(clip.substr(op, p-op));
+ ++cols;
+ ++cell;
+ break;
+ case '\n':
+ paste_tabular->GetCellInset(cell)->SetText(clip.substr(op, p-op));
+ while(cols++ < maxCols)
+ ++cell;
+ cols = 0;
+ break;
+ }
+ ++p;
+ op = p;
+ }
+ // check for the last cell if there is no trailing '\n'
+ if ((cell < cells) && (op < len))
+ paste_tabular->GetCellInset(cell)->SetText(clip.substr(op, len-op));
+ } else {
+ // so that the clipboard is used and it goes on to default
+ // and executes LFUN_PASTESELECTION in insettext!
+ delete paste_tabular;
+ paste_tabular = 0;
+ }
+ }
+ case LFUN_PASTE:
+ if (hasPasteBuffer()) {
+ bv->text->SetUndo(bv->buffer(), Undo::INSERT,
#ifndef NEW_INSETS
- bv->text->cursor.par()->ParFromPos(bv->text->cursor.pos())->previous,
- bv->text->cursor.par()->ParFromPos(bv->text->cursor.pos())->next
+ bv->text->cursor.par()->ParFromPos(bv->text->cursor.pos())->previous,
+ bv->text->cursor.par()->ParFromPos(bv->text->cursor.pos())->next
#else
- bv->text->cursor.par()->previous,
- bv->text->cursor.par()->next
+ bv->text->cursor.par()->previous,
+ bv->text->cursor.par()->next
#endif
);
- pasteSelection(bv);
- UpdateLocal(bv, INIT, true);
- break;
+ pasteSelection(bv);
+ UpdateLocal(bv, INIT, true);
+ break;
+ }
+ // ATTENTION: the function above has to be PASTE and PASTESELECTION!!!
default:
// we try to activate the actual inset and put this event down to
// the insets dispatch function.
bool reinit) const
{
int cell = -1;
- int maxAsc, maxDesc;
+ int maxAsc = 0;
+ int maxDesc = 0;
InsetText * inset;
bool changed = false;
// change so I'll try this to have a boost, but who knows ;)
if ((need_update != INIT) &&
(the_locking_inset == tabular->GetCellInset(actcell))) {
- maxAsc = the_locking_inset->ascent(bv, font);
- maxDesc = the_locking_inset->descent(bv, font);
+ for(int i = 0; i < tabular->columns(); ++i) {
+ maxAsc = max(tabular->GetCellInset(actrow, i)->ascent(bv, font),
+ maxAsc);
+ maxDesc = max(tabular->GetCellInset(actrow, i)->descent(bv, font),
+ maxDesc);
+ }
changed = tabular->SetWidthOfCell(actcell, the_locking_inset->width(bv, font));
changed = tabular->SetAscentOfRow(actrow, maxAsc + ADD_TO_HEIGHT) || changed;
changed = tabular->SetDescentOfRow(actrow, maxDesc + ADD_TO_HEIGHT) || changed;
return changed;
}
for (int i = 0; i < tabular->rows(); ++i) {
- maxAsc = maxDesc = 0;
+ maxAsc = 0;
+ maxDesc = 0;
for (int j= 0; j < tabular->columns(); ++j) {
if (tabular->IsPartOfMultiColumn(i,j))
continue;
// now search the right column
int lx = tabular->GetWidthOfColumn(actcell) -
tabular->GetAdditionalWidth(actcell);
-#warning Jürgen, can you rewrite this to _not_ use the sequencing operator. (Lgb)
#if 0
+#warning Jürgen, can you rewrite this to _not_ use the sequencing operator. (Lgb)
for (; !tabular->IsLastCellInRow(actcell) && (lx < x);
++actcell,lx += tabular->GetWidthOfColumn(actcell) +
tabular->GetAdditionalWidth(actcell - 1));
}
static int const offset = ADD_TO_TABULAR_WIDTH + 2;
int new_x = getCellXPos(actcell);
+ int old_x = cursor.x();
new_x += offset;
cursor.x(new_x);
// cursor.x(getCellXPos(actcell) + offset);
LyXFont font(LyXFont::ALL_SANE);
cursor.x(cursor.x() + tabular->GetCellInset(actcell)->width(bv,font) +
tabular->GetBeginningOfTextInCell(actcell));
+ } else if (scroll() && (top_x > 20) &&
+ ((top_x+tabular->GetWidthOfTabular()) > (bv->workWidth()-20))) {
+ scroll(bv, old_x - cursor.x());
}
if ((!the_locking_inset ||
!the_locking_inset->GetFirstLockingInsetOfType(TABULAR_CODE)) &&
}
-LyXText * InsetTabular::getLyXText(BufferView * bv) const
+LyXText * InsetTabular::getLyXText(BufferView const * bv) const
{
if (the_locking_inset)
return the_locking_inset->getLyXText(bv);
{
if (!paste_tabular)
return false;
- for (int j=0, i=actcell; j<paste_tabular->GetNumberOfCells(); ++j,++i) {
- while (paste_tabular->row_of_cell(j) > tabular->row_of_cell(i)-actrow)
- ++i;
- if (tabular->GetNumberOfCells() <= i)
- break;
- while (paste_tabular->row_of_cell(j) < tabular->row_of_cell(i)-actrow)
- ++j;
- if (paste_tabular->GetNumberOfCells() <= j)
- break;
- *(tabular->GetCellInset(i)) = *(paste_tabular->GetCellInset(j));
- tabular->GetCellInset(i)->setOwner(this);
- tabular->GetCellInset(i)->deleteLyXText(bv);
+
+ for (int r1 = 0, r2 = actrow;
+ (r1 < paste_tabular->rows()) && (r2 < tabular->rows());
+ ++r1, ++r2)
+ {
+ for(int c1 = 0, c2 = actcol;
+ (c1 < paste_tabular->columns()) && (c2 < tabular->columns());
+ ++c1, ++c2)
+ {
+ if (paste_tabular->IsPartOfMultiColumn(r1,c1) &&
+ tabular->IsPartOfMultiColumn(r2,c2))
+ continue;
+ if (paste_tabular->IsPartOfMultiColumn(r1,c1)) {
+ --c2;
+ continue;
+ }
+ if (tabular->IsPartOfMultiColumn(r2,c2)) {
+ --c1;
+ continue;
+ }
+ int n1 = paste_tabular->GetCellNumber(r1, c1);
+ int n2 = tabular->GetCellNumber(r2, c2);
+ *(tabular->GetCellInset(n2)) = *(paste_tabular->GetCellInset(n1));
+ tabular->GetCellInset(n2)->setOwner(this);
+ tabular->GetCellInset(n2)->deleteLyXText(bv);
+ }
}
return true;
}