Fixed mouse-click-bug and made cut/copy/paste work in text-insets

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@627 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Jürgen Vigna 2000-03-27 15:13:47 +00:00
parent 8d3a4fd463
commit dc4f6b3ec2
8 changed files with 178 additions and 34 deletions

View File

@ -1,3 +1,15 @@
2000-03-27 Juergen Vigna <jug@sad.it>
* src/insets/insettext.C: added Cut/Copy/Paste inside insets,
also some modifications with operations on selected text.
* src/BufferView.C (checkInsetHit): Now hopefully fixed all the
problems with clicking on insets (last famous words ;)
* src/insets/insetcommand.C (draw):
(width): Changed to have a bit of space before and after the inset so
that the blinking cursor can be seen (otherwise it was hidden)
2000-03-22 Jean-Marc Lasgouttes <Jean-Marc.Lasgouttes@inria.fr>
* config/gettext.m4 (AM_WITH_NLS): fix a gettext bug where -lintl

View File

@ -643,7 +643,7 @@ void BufferView::workAreaButtonPress(int xpos, int ypos, unsigned int button)
if (buffer_ == 0 || !screen) return;
Inset * inset_hit = checkInsetHit(xpos, ypos);
Inset * inset_hit = checkInsetHit(xpos, ypos, button);
// ok ok, this is a hack.
if (button == 4 || button == 5) {
@ -749,7 +749,8 @@ void BufferView::workAreaButtonPress(int xpos, int ypos, unsigned int button)
return;
}
text->SetCursorFromCoordinates(xpos, ypos + screen_first);
if (!inset_hit) // otherwise it was already set in checkInsetHit(...)
text->SetCursorFromCoordinates(xpos, ypos + screen_first);
text->FinishUndo();
text->sel_cursor = text->cursor;
text->cursor.x_fix = text->cursor.x;
@ -817,7 +818,7 @@ void BufferView::workAreaButtonRelease(int x, int y, unsigned int button)
// If we hit an inset, we have the inset coordinates in these
// and inset_hit points to the inset. If we do not hit an
// inset, inset_hit is 0, and inset_x == x, inset_y == y.
Inset * inset_hit = checkInsetHit(x, y);
Inset * inset_hit = checkInsetHit(x, y, button);
if (the_locking_inset) {
// We are in inset locking mode.
@ -967,18 +968,21 @@ void BufferView::workAreaButtonRelease(int x, int y, unsigned int button)
* If hit, the coordinates are changed relative to the inset.
* Otherwise coordinates are not changed, and false is returned.
*/
Inset * BufferView::checkInsetHit(int & x, int & y)
Inset * BufferView::checkInsetHit(int & x, int & y, unsigned int button)
{
if (!screen)
return 0;
int y_tmp = y + screen->first;
LyXCursor & old_cursor = text->cursor;
text->SetCursorFromCoordinates(x,y);
LyXCursor & cursor = text->cursor;
bool is_rtl = text->real_current_font.isVisibleRightToLeft();
LyXCursor cursor;
text->SetCursorFromCoordinates(cursor, x, y_tmp);
#if 1
bool move_cursor = true;
#else
bool move_cursor = ((cursor.par != text->cursor.par) ||
(cursor.pos != text->cursor.pos)) && (button < 2);
#endif
if (cursor.pos < cursor.par->Last()
&& cursor.par->GetChar(cursor.pos) == LyXParagraph::META_INSET
@ -988,7 +992,9 @@ Inset * BufferView::checkInsetHit(int & x, int & y)
// Check whether the inset really was hit
Inset * tmpinset = cursor.par->GetInset(cursor.pos);
LyXFont font = text->GetFont(cursor.par, cursor.pos);
bool is_rtl = font.isVisibleRightToLeft();
int start_x, end_x;
if (is_rtl) {
start_x = cursor.x - tmpinset->width(painter(), font);
end_x = cursor.x;
@ -1000,9 +1006,11 @@ Inset * BufferView::checkInsetHit(int & x, int & y)
if (x > start_x && x < end_x
&& y_tmp > cursor.y - tmpinset->ascent(painter(), font)
&& y_tmp < cursor.y + tmpinset->descent(painter(), font)) {
if (move_cursor)
text->SetCursorFromCoordinates(x, y_tmp);
x = x - start_x;
// The origin of an inset is on the baseline
y = y_tmp - (cursor.y);
y = y_tmp - (text->cursor.y);
return tmpinset;
}
}
@ -1011,11 +1019,12 @@ Inset * BufferView::checkInsetHit(int & x, int & y)
(cursor.par->GetChar(cursor.pos-1) == LyXParagraph::META_INSET) &&
(cursor.par->GetInset(cursor.pos - 1)) &&
(cursor.par->GetInset(cursor.pos - 1)->Editable())) {
text->CursorLeft();
Inset * tmpinset = cursor.par->GetInset(cursor.pos);
LyXFont font = text->GetFont(cursor.par, cursor.pos);
Inset * tmpinset = cursor.par->GetInset(cursor.pos-1);
LyXFont font = text->GetFont(cursor.par, cursor.pos-1);
bool is_rtl = font.isVisibleRightToLeft();
int start_x, end_x;
if (is_rtl) {
if (!is_rtl) {
start_x = cursor.x - tmpinset->width(painter(), font);
end_x = cursor.x;
} else {
@ -1025,15 +1034,14 @@ Inset * BufferView::checkInsetHit(int & x, int & y)
if (x > start_x && x < end_x
&& y_tmp > cursor.y - tmpinset->ascent(painter(), font)
&& y_tmp < cursor.y + tmpinset->descent(painter(), font)) {
if (move_cursor)
text->SetCursorFromCoordinates(x, y_tmp);
x = x - start_x;
// The origin of an inset is on the baseline
y = y_tmp - (cursor.y);
y = y_tmp - (text->cursor.y);
return tmpinset;
} else {
text->CursorRight();
}
}
text->SetCursor(old_cursor.par, old_cursor.pos);
return 0;
}

View File

@ -204,7 +204,7 @@ private:
///
void create_view();
///
Inset * checkInsetHit(int & x, int & y);
Inset * checkInsetHit(int & x, int & y, unsigned int button);
///
int scrollUp(long time);
///

View File

@ -99,7 +99,7 @@ int InsetCommand::width(Painter & pain, LyXFont const &) const
LColor::commandbg, LColor::commandframe,
false, width, ascent, descent);
}
return width;
return width+4;
#else
LyXFont f = font;
f.decSize();
@ -121,14 +121,14 @@ void InsetCommand::draw(Painter & pain, LyXFont const &,
string s = getScreenLabel();
if (Editable()) {
pain.buttonText(int(x), baseline, s, font, true, width);
pain.buttonText(int(x)+2, baseline, s, font, true, width);
} else {
pain.rectText(int(x), baseline, s, font,
pain.rectText(int(x)+2, baseline, s, font,
LColor::commandbg, LColor::commandframe,
true, width);
}
x += width;
x += width + 4;
#else
x += 3;

View File

@ -193,7 +193,6 @@ void InsetText::draw(Painter & pain, LyXFont const & f,
computeTextRows(pain, x);
UpdatableInset::draw(pain, f, baseline, x);
bool do_reset_pos = (x != top_x) || (baseline != top_baseline);
top_x = int(x);
top_baseline = baseline;
computeBaselines(baseline);
@ -203,11 +202,6 @@ void InsetText::draw(Painter & pain, LyXFont const & f,
drawRowText(pain, rows[r].pos, rows[r + 1].pos, rows[r].baseline, x);
}
x += insetWidth;
if (!the_locking_inset && do_reset_pos) {
// HideInsetCursor(bv);
// resetPos(bv);
// ShowInsetCursor(bv);
}
}
@ -488,12 +482,13 @@ InsetText::LocalDispatch(BufferView * bv,
switch (action) {
// Normal chars
case -1:
cutSelection();
actpos = selection_start;
par->InsertChar(actpos,arg[0]);
par->SetFont(actpos,real_current_font);
UpdateLocal(bv, true);
++actpos;
selection_start = selection_end = actpos;
resetPos(bv);
UpdateLocal(bv, true);
break;
// --- Cursor Movements ---------------------------------------------
case LFUN_RIGHTSEL:
@ -562,7 +557,12 @@ InsetText::LocalDispatch(BufferView * bv,
}
moveLeft(bv);
case LFUN_DELETE:
if (Delete()) { // we need update
bool ret;
if (hasSelection())
ret = cutSelection();
else
ret = Delete();
if (ret) { // we need update
selection_start = selection_end = actpos;
UpdateLocal(bv, true);
} else if (hasSelection()) {
@ -570,6 +570,30 @@ InsetText::LocalDispatch(BufferView * bv,
UpdateLocal(bv, false);
}
break;
case LFUN_CUT:
if (cutSelection()) { // we need update
actpos = selection_end = selection_start;
UpdateLocal(bv, true);
} else if (hasSelection()) {
selection_start = selection_end = actpos;
UpdateLocal(bv, false);
}
break;
case LFUN_COPY:
if (copySelection()) { // we need update
selection_start = selection_end = actpos;
UpdateLocal(bv, true);
} else if (hasSelection()) {
selection_start = selection_end = actpos;
UpdateLocal(bv, false);
}
break;
case LFUN_PASTE:
if (pasteSelection()) {
selection_start = selection_end = actpos;
UpdateLocal(bv, true);
}
break;
case LFUN_HOME:
for(; actpos > rows[actrow].pos; --actpos)
cx -= SingleWidth(bv->getPainter(), par, actpos);
@ -935,6 +959,9 @@ bool InsetText::moveDown(BufferView * bv, bool activate_inset)
void InsetText::resetPos(BufferView * bv)
{
if (!rows.size())
return;
int old_pos = actpos;
cy = top_baseline;
@ -959,7 +986,7 @@ bool InsetText::Delete()
/* some insets are undeletable here */
if (par->GetChar(actpos)==LyXParagraph::META_INSET) {
/* force complete redo when erasing display insets */
/* this is a cruel mathod but save..... Matthias */
/* this is a cruel method but save..... Matthias */
if (par->GetInset(actpos)->Deletable() &&
par->GetInset(actpos)->display()) {
par->Erase(actpos);
@ -1245,6 +1272,85 @@ void InsetText::computeBaselines(int baseline) const
void InsetText::UpdateLocal(BufferView *bv, bool flag)
{
init_inset = flag;
HideInsetCursor(bv);
if (flag) {
computeTextRows(bv->painter(), xpos);
computeBaselines(top_baseline);
resetPos(bv);
}
bv->updateInset(this, flag);
ShowInsetCursor(bv);
}
// this is for the simple cut and paste mechanism
// this then should be a global stuff so that cut'n'paste can work in and
// and outside text-insets
static LyXParagraph * simple_cut_buffer = 0;
// static char simple_cut_buffer_textclass = 0;
// for now here this should be in another Cut&Paste Class!
//
static void DeleteSimpleCutBuffer()
{
if (!simple_cut_buffer)
return;
LyXParagraph * tmppar;
while (simple_cut_buffer) {
tmppar = simple_cut_buffer;
simple_cut_buffer = simple_cut_buffer->next;
delete tmppar;
}
simple_cut_buffer = 0;
}
bool InsetText::cutSelection()
{
if (!hasSelection())
return false;
DeleteSimpleCutBuffer();
// only within one paragraph
simple_cut_buffer = new LyXParagraph;
LyXParagraph::size_type i = selection_start;
for (; i < selection_end; ++i) {
par->CopyIntoMinibuffer(selection_start);
par->Erase(selection_start);
simple_cut_buffer->InsertFromMinibuffer(simple_cut_buffer->Last());
}
return true;
}
bool InsetText::copySelection()
{
if (!hasSelection())
return false;
DeleteSimpleCutBuffer();
// only within one paragraph
simple_cut_buffer = new LyXParagraph;
LyXParagraph::size_type i = selection_start;
for (; i < selection_end; ++i) {
par->CopyIntoMinibuffer(i);
simple_cut_buffer->InsertFromMinibuffer(simple_cut_buffer->Last());
}
return true;
}
bool InsetText::pasteSelection()
{
if (!simple_cut_buffer)
return false;
LyXParagraph * tmppar = simple_cut_buffer->Clone();
while (simple_cut_buffer->size()) {
simple_cut_buffer->CutIntoMinibuffer(0);
simple_cut_buffer->Erase(0);
par->InsertFromMinibuffer(actpos);
++actpos;
}
delete simple_cut_buffer;
simple_cut_buffer = tmppar;
return true;
}

View File

@ -161,6 +161,9 @@ private:
bool moveUp(BufferView *, bool activate_inset = true);
bool moveDown(BufferView *, bool activate_inset = true);
bool Delete();
bool cutSelection();
bool copySelection();
bool pasteSelection();
///
bool hasSelection() const { return selection_start != selection_end; }
///

View File

@ -245,6 +245,7 @@ public:
bool setfont = true) const;
///
void SetCursorFromCoordinates(int x, long y) const;
void SetCursorFromCoordinates(LyXCursor &, int x, long y) const;
///
void CursorUp() const;
///

View File

@ -3159,6 +3159,20 @@ void LyXText::SetCursorFromCoordinates(int x, long y) const
DeleteEmptyParagraphMechanism(old_cursor);
}
void LyXText::SetCursorFromCoordinates(LyXCursor & cur, int x, long y) const
{
/* get the row first */
Row * row = GetRowNearY(y);
int column = GetColumnNearX(row, x);
cur.par = row->par;
cur.pos = row->pos + column;
cur.x = x;
cur.y = y + row->baseline;
cur.row = row;
}
void LyXText::CursorLeft() const
{