mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-11-22 10:00:33 +00:00
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:
parent
8d3a4fd463
commit
dc4f6b3ec2
12
ChangeLog
12
ChangeLog
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
///
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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; }
|
||||
///
|
||||
|
@ -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;
|
||||
///
|
||||
|
14
src/text2.C
14
src/text2.C
@ -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
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user