]> git.lyx.org Git - features.git/commitdiff
Fixed mouse-click-bug and made cut/copy/paste work in text-insets
authorJürgen Vigna <jug@sad.it>
Mon, 27 Mar 2000 15:13:47 +0000 (15:13 +0000)
committerJürgen Vigna <jug@sad.it>
Mon, 27 Mar 2000 15:13:47 +0000 (15:13 +0000)
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@627 a592a061-630c-0410-9148-cb99ea01b6c8

ChangeLog
src/BufferView.C
src/BufferView.h
src/insets/insetcommand.C
src/insets/insettext.C
src/insets/insettext.h
src/lyxtext.h
src/text2.C

index 6c3d712bfc26a95559bda9ca8894462744ace233..5985a2b83c2f7c96d486c1416e23ba55a87433ce 100644 (file)
--- a/ChangeLog
+++ b/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
index abf7d708359deb401f3be99419a8654bc0ee8062..c412f6e2d3fe47daa0cb61c58059d776f5407aa1 100644 (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;
 }
 
index 14d74e6179004f39478d59ebb12fcdc2d27f5b9b..4f3d352723a649502d185d5cd2ae6cc273cb7ed5 100644 (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);
        ///
index ae90a45ccfb2e2ade0febd11b7856ff6d3daaa93..c0813a8b045f977d56abc160cb070900af334ca7 100644 (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;
index 9f2c430d8368ff89f8a014a43d9c9255d3e506cf..b1d4e6cf54b4c9154342bcc58bbc3a72dfb2ca7a 100644 (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,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;
 }
index f8bf929a41675d5d7c46c6f529a6cbd034dd7d0e..8cebcb733da5168009b6dd0da5822e3b0e09ebe7 100644 (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; }
     ///
index c6620eeb79fe7701ff819a6ca67c4b5ef8a1e593..e4e2bc51d181d07c6efad8fbf071a21317eba445 100644 (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;
        ///
index f69ff60516d24b28dade7b89a71e1151ed9dd4ce..e41f8756aad6c4ed922db6faf10e9994aba06e6d 100644 (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
 {