From dc4f6b3ec240ede0d7a9df7b52ee385a083bf19e Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=BCrgen=20Vigna?= Date: Mon, 27 Mar 2000 15:13:47 +0000 Subject: [PATCH] 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 --- ChangeLog | 12 ++++ src/BufferView.C | 44 +++++++------ src/BufferView.h | 2 +- src/insets/insetcommand.C | 8 +-- src/insets/insettext.C | 128 ++++++++++++++++++++++++++++++++++---- src/insets/insettext.h | 3 + src/lyxtext.h | 1 + src/text2.C | 14 +++++ 8 files changed, 178 insertions(+), 34 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6c3d712bfc..5985a2b83c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2000-03-27 Juergen Vigna + + * 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 * config/gettext.m4 (AM_WITH_NLS): fix a gettext bug where -lintl diff --git a/src/BufferView.C b/src/BufferView.C index abf7d70835..c412f6e2d3 100644 --- a/src/BufferView.C +++ b/src/BufferView.C @@ -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; } diff --git a/src/BufferView.h b/src/BufferView.h index 14d74e6179..4f3d352723 100644 --- a/src/BufferView.h +++ b/src/BufferView.h @@ -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); /// diff --git a/src/insets/insetcommand.C b/src/insets/insetcommand.C index ae90a45ccf..c0813a8b04 100644 --- a/src/insets/insetcommand.C +++ b/src/insets/insetcommand.C @@ -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; diff --git a/src/insets/insettext.C b/src/insets/insettext.C index 9f2c430d83..b1d4e6cf54 100644 --- a/src/insets/insettext.C +++ b/src/insets/insettext.C @@ -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,30 @@ 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()) { + selection_start = selection_end = actpos; + 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()) { @@ -570,6 +588,12 @@ InsetText::LocalDispatch(BufferView * bv, 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; } diff --git a/src/insets/insettext.h b/src/insets/insettext.h index f8bf929a41..8cebcb733d 100644 --- a/src/insets/insettext.h +++ b/src/insets/insettext.h @@ -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; } /// diff --git a/src/lyxtext.h b/src/lyxtext.h index c6620eeb79..e4e2bc51d1 100644 --- a/src/lyxtext.h +++ b/src/lyxtext.h @@ -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; /// diff --git a/src/text2.C b/src/text2.C index f69ff60516..e41f8756aa 100644 --- a/src/text2.C +++ b/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 { -- 2.39.2