]> git.lyx.org Git - lyx.git/blobdiff - src/insets/insettabular.C
* src/LyXAction.C: mark goto-clear-bookmark as working without buffer
[lyx.git] / src / insets / insettabular.C
index 849bf95079b7966784bcc9eb737913a072acdc6f..202ac6fa44bb8495781e2a56dd4919f2a87029ff 100644 (file)
@@ -174,12 +174,6 @@ string const featureAsString(LyXTabular::Feature feature)
 }
 
 
-bool InsetTabular::hasPasteBuffer() const
-{
-       return (paste_tabular.get() != 0);
-}
-
-
 InsetTabular::InsetTabular(Buffer const & buf, row_type rows,
                           col_type columns)
        : tabular(buf.params(), max(rows, row_type(1)),
@@ -498,6 +492,8 @@ void InsetTabular::doDispatch(LCursor & cur, FuncRequest & cmd)
                if (cmd.button() == mouse_button::button1 
                    || (cmd.button() == mouse_button::button3 
                        && (&bvcur.selBegin().inset() != this || !tablemode(bvcur)))) {
+                       if (!bvcur.selection() && !cur.bv().mouseSetCursor(cur))
+                               cur.noUpdate();
                        cur.selection() = false;
                        setCursorFromCoordinates(cur, cmd.x, cmd.y);
                        cur.bv().mouseSetCursor(cur);
@@ -505,7 +501,17 @@ void InsetTabular::doDispatch(LCursor & cur, FuncRequest & cmd)
                }
 
                if (cmd.button() == mouse_button::button2) {
-                       cmd = FuncRequest(LFUN_PRIMARY_SELECTION_PASTE, "paragraph");
+                       if (bvcur.selection()) {
+                               // See comment in LyXText::dispatch why we
+                               // do this
+                               // FIXME This does not use paste_tabular,
+                               // another reason why paste_tabular should go.
+                               cap::copySelectionToStack(bvcur);
+                               cmd = FuncRequest(LFUN_PASTE, "0");
+                       } else {
+                               cmd = FuncRequest(LFUN_PRIMARY_SELECTION_PASTE,
+                                                 "paragraph");
+                       }
                        doDispatch(cur, cmd);
                }
                break;
@@ -515,6 +521,10 @@ void InsetTabular::doDispatch(LCursor & cur, FuncRequest & cmd)
                if (cmd.button() == mouse_button::button1) {
                        // only accept motions to places not deeper nested than the real anchor
                        if (bvcur.anchor_.hasPart(cur)) {
+                               // only update if selection changes
+                               if (bvcur.idx() == cur.idx() &&
+                                       !(bvcur.anchor_.idx() == cur.idx() && bvcur.pos() != cur.pos()))
+                                       cur.noUpdate();
                                setCursorFromCoordinates(cur, cmd.x, cmd.y);
                                bvcur.setCursor(cur);
                                bvcur.selection() = true;
@@ -525,7 +535,10 @@ void InsetTabular::doDispatch(LCursor & cur, FuncRequest & cmd)
 
        case LFUN_MOUSE_RELEASE:
                //lyxerr << "# InsetTabular::MouseRelease\n" << bvcur << endl;
-               if (cmd.button() == mouse_button::button3)
+               if (cmd.button() == mouse_button::button1) {
+                       if (bvcur.selection())
+                               theSelection().haveSelection(true);
+               } else if (cmd.button() == mouse_button::button3)
                        InsetTabularMailer(*this).showDialog(&cur.bv());
                break;
 
@@ -544,6 +557,8 @@ void InsetTabular::doDispatch(LCursor & cur, FuncRequest & cmd)
                cell(cur.idx())->dispatch(cur, cmd);
                if (!cur.result().dispatched()) {
                        isRightToLeft(cur) ? movePrevCell(cur) : moveNextCell(cur);
+                       if (cmd.action == LFUN_CHAR_FORWARD_SELECT)
+                               theSelection().haveSelection(cur.selection());
                        if (sl == cur.top())
                                cmd = FuncRequest(LFUN_FINISHED_RIGHT);
                        else
@@ -556,6 +571,8 @@ void InsetTabular::doDispatch(LCursor & cur, FuncRequest & cmd)
                cell(cur.idx())->dispatch(cur, cmd);
                if (!cur.result().dispatched()) {
                        isRightToLeft(cur) ? moveNextCell(cur) : movePrevCell(cur);
+                       if (cmd.action == LFUN_CHAR_BACKWARD_SELECT)
+                               theSelection().haveSelection(cur.selection());
                        if (sl == cur.top())
                                cmd = FuncRequest(LFUN_FINISHED_LEFT);
                        else
@@ -574,8 +591,11 @@ void InsetTabular::doDispatch(LCursor & cur, FuncRequest & cmd)
                        if (tabular.row_of_cell(cur.idx()) != tabular.rows() - 1) {
                                cur.idx() = tabular.getCellBelow(cur.idx());
                                cur.pit() = 0;
-                               cur.pos() = cell(cur.idx())->getText(0)->x2pos(
-                                       cur.bv(), cur.pit(), 0, cur.targetX());
+                               TextMetrics const & tm =
+                                       cur.bv().textMetrics(cell(cur.idx())->getText(0));
+                               cur.pos() = tm.x2pos(cur.pit(), 0, cur.targetX());
+                               if (cmd.action == LFUN_DOWN_SELECT)
+                                       theSelection().haveSelection(cur.selection());
                        }
                if (sl == cur.top()) {
                        // we trick it to go to the RIGHT after leaving the
@@ -597,11 +617,12 @@ void InsetTabular::doDispatch(LCursor & cur, FuncRequest & cmd)
                                cur.idx() = tabular.getCellAbove(cur.idx());
                                cur.pit() = cur.lastpit();
                                LyXText const * text = cell(cur.idx())->getText(0);
-                               cur.pos() = text->x2pos(
-                                       cur.bv(),
-                                       cur.pit(),
-                                       text->paragraphs().back().rows().size()-1,
-                                       cur.targetX());
+                               TextMetrics const & tm = cur.bv().textMetrics(text);
+                               ParagraphMetrics const & pm =
+                                       tm.parMetrics(cur.lastpit());
+                               cur.pos() = tm.x2pos(cur.pit(), pm.rows().size()-1, cur.targetX());
+                               if (cmd.action == LFUN_UP_SELECT)
+                                       theSelection().haveSelection(cur.selection());
                        }
                if (sl == cur.top()) {
                        cmd = FuncRequest(LFUN_FINISHED_UP);
@@ -658,12 +679,12 @@ void InsetTabular::doDispatch(LCursor & cur, FuncRequest & cmd)
                break;
 
        // insert file functions
-       case LFUN_FILE_INSERT_ASCII_PARA:
-       case LFUN_FILE_INSERT_ASCII: {
+       case LFUN_FILE_INSERT_PLAINTEXT_PARA:
+       case LFUN_FILE_INSERT_PLAINTEXT: {
                // FIXME UNICODE
-               string const tmpstr = getContentsOfAsciiFile(&cur.bv(), to_utf8(cmd.argument()), false);
+               string const tmpstr = getContentsOfPlaintextFile(&cur.bv(), to_utf8(cmd.argument()), false);
                // FIXME: We don't know the encoding of the file
-               if (!tmpstr.empty() && !insertAsciiString(cur.bv(), from_utf8(tmpstr), false))
+               if (!tmpstr.empty() && !insertPlaintextString(cur.bv(), from_utf8(tmpstr), false))
                        cur.undispatched();
                break;
        }
@@ -702,32 +723,28 @@ void InsetTabular::doDispatch(LCursor & cur, FuncRequest & cmd)
        case LFUN_CLIPBOARD_PASTE:
        case LFUN_PRIMARY_SELECTION_PASTE: {
                docstring const clip = (cmd.action == LFUN_CLIPBOARD_PASTE) ?
-                       theClipboard().get() :
+                       theClipboard().getAsText() :
                        theSelection().get();
                if (clip.empty())
                        break;
-               // pass to InsertAsciiString, but
+               // pass to InsertPlaintextString, but
                // only if we have multi-cell content
                if (clip.find_first_of(from_ascii("\t\n")) != docstring::npos) {
-                       if (insertAsciiString(cur.bv(), clip, false)) {
+                       if (insertPlaintextString(cur.bv(), clip, false)) {
                                // content has been replaced,
                                // so cursor might be invalid
                                cur.pos() = cur.lastpos();
                                bvcur.setCursor(cur);
                                break;
                        }
-               } else {
-                       // so that the clipboard is used and it goes on
-                       // to default
-                       // and executes LFUN_PRIMARY_SELECTION_PASTE in insettext!
-                       paste_tabular.reset();
-                       dirtyTabularStack(false);
                }
-               // fall through
+               // Let the cell handle normal text
+               cell(cur.idx())->dispatch(cur, cmd);
+               break;
        }
 
        case LFUN_PASTE:
-               if (hasPasteBuffer() && tabularStackDirty()) {
+               if (tabularStackDirty() && theClipboard().isInternal()) {
                        recordUndoInset(cur, Undo::INSERT);
                        pasteSelection(cur);
                        break;
@@ -1037,10 +1054,11 @@ bool InsetTabular::getStatus(LCursor & cur, FuncRequest const & cmd,
        }
 
        case LFUN_PASTE:
-               if (tabularStackDirty()) {
+               if (tabularStackDirty() && theClipboard().isInternal()) {
                        status.enabled(true);
                        return true;
-               }
+               } else
+                       return cell(cur.idx())->getStatus(cur, cmd, status);
 
        case LFUN_INSET_MODIFY:
                if (translate(cmd.getArg(0)) == TABULAR_CODE) {
@@ -1253,8 +1271,6 @@ void InsetTabular::resetPos(LCursor & cur) const
        }
 
        cur.updateFlags(Update::Force | Update::FitCursor);
-
-       InsetTabularMailer(*this).updateDialog(&bv);
 }
 
 
@@ -1434,7 +1450,7 @@ void InsetTabular::tabularFeatures(LCursor & cur,
 
        case LyXTabular::SET_SPECIAL_COLUMN:
        case LyXTabular::SET_SPECIAL_MULTI:
-               tabular.setAlignSpecial(cur.idx(),value,feature);
+               tabular.setAlignSpecial(cur.idx(), from_utf8(value), feature);
                break;
 
        case LyXTabular::APPEND_ROW:
@@ -1742,8 +1758,6 @@ void InsetTabular::tabularFeatures(LCursor & cur,
        case LyXTabular::LAST_ACTION:
                break;
        }
-
-       InsetTabularMailer(*this).updateDialog(&bv);
 }
 
 
@@ -1796,11 +1810,14 @@ bool InsetTabular::copySelection(LCursor & cur)
        odocstringstream os;
        OutputParams const runparams;
        paste_tabular->plaintext(cur.buffer(), os, runparams, 0, true, '\t');
-       theClipboard().put(os.str());
+       // Needed for the "Edit->Paste recent" menu and the system clipboard.
+       cap::copySelection(cur, os.str());
+
        // mark tabular stack dirty
        // FIXME: this is a workaround for bug 1919. Should be removed for 1.5,
        // when we (hopefully) have a one-for-all paste mechanism.
-       cap::dirtyTabularStack(true);
+       // This must be called after cap::copySelection.
+       dirtyTabularStack(true);
 
        return true;
 }
@@ -1868,6 +1885,7 @@ void InsetTabular::cutSelection(LCursor & cur)
        if (cur.pos() > cur.lastpos())
                cur.pos() = cur.lastpos();
        cur.clearSelection();
+       theSelection().haveSelection(false);
 }
 
 
@@ -1935,7 +1953,7 @@ bool InsetTabular::forceDefaultParagraphs(idx_type cell) const
 }
 
 
-bool InsetTabular::insertAsciiString(BufferView & bv, docstring const & buf,
+bool InsetTabular::insertPlaintextString(BufferView & bv, docstring const & buf,
                                     bool usePaste)
 {
        if (buf.length() <= 0)