From 8c1cfab84d565ecf9176af7b80bad02ea04a8d52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A1szl=C3=B3=20N=C3=A9meth?= Date: Wed, 11 Dec 2019 15:38:05 +0100 Subject: [PATCH] tdf#37156 popup menu: paste nested table Paste table data in Writer tables overwrites the content of the existing cells, when the cursor is there in an empty cell or at the beginning of the first paragraph of a table cell. Using the new Paste Special option "Paste in Cell", based on the new .uno:PasteTableInCell command, clipboard content (including native tables or tables copied from Calc or other spreadsheets) are inserted as nested tables in empty cells and at cell starting cursor positions. Change-Id: I32807200883651e492ae280efce7bf9806f22283 --- .../openoffice/Office/UI/WriterCommands.xcu | 11 +++++++++++ sw/inc/cmdid.h | 1 + sw/inc/fesh.hxx | 2 +- sw/sdi/_basesh.sdi | 7 +++++++ sw/sdi/swriter.sdi | 18 ++++++++++++++++++ sw/source/core/frmedt/fecopy.cxx | 4 +++- sw/source/uibase/dochdl/swdtflvr.cxx | 17 +++++++++-------- sw/source/uibase/inc/swdtflvr.hxx | 7 ++++--- sw/source/uibase/shells/basesh.cxx | 6 +++++- sw/source/uibase/uiview/view.cxx | 2 +- sw/uiconfig/swriter/popupmenu/table.xml | 1 + 11 files changed, 61 insertions(+), 15 deletions(-) diff --git a/officecfg/registry/data/org/openoffice/Office/UI/WriterCommands.xcu b/officecfg/registry/data/org/openoffice/Office/UI/WriterCommands.xcu index ce664af0e1bd..3ace951b51e2 100644 --- a/officecfg/registry/data/org/openoffice/Office/UI/WriterCommands.xcu +++ b/officecfg/registry/data/org/openoffice/Office/UI/WriterCommands.xcu @@ -1523,6 +1523,17 @@ 1 + + + Paste in Cell + + + Paste in Cell + + + 1 + + Delete Rows diff --git a/sw/inc/cmdid.h b/sw/inc/cmdid.h index 6b49d5a91e51..b0c6f8addf9a 100644 --- a/sw/inc/cmdid.h +++ b/sw/inc/cmdid.h @@ -343,6 +343,7 @@ #define FN_TABLE_SELECT_ALL (FN_FORMAT + 115) /* */ #define FN_TABLE_INSERT_COL_AFTER (FN_FORMAT + 116) /* */ #define FN_TABLE_SET_READ_ONLY_CELLS (FN_FORMAT + 117) /* protect table cells */ +#define FN_TABLE_PASTE_IN_CELL (FN_FORMAT + 118) /* paste nested table */ #define FN_TABLE_UNSET_READ_ONLY_CELLS (FN_FORMAT + 119) /* undo table cell protection */ #define FN_TABLE_HEADLINE_REPEAT (FN_FORMAT + 120) /* also used in SwXTextTable*/ #define FN_TABLE_ADJUST_CELLS (FN_FORMAT + 121) /* */ diff --git a/sw/inc/fesh.hxx b/sw/inc/fesh.hxx index f60f92cff44e..e1a03186c37c 100644 --- a/sw/inc/fesh.hxx +++ b/sw/inc/fesh.hxx @@ -252,7 +252,7 @@ public: /// Copy and Paste methods for internal clipboard. void Copy( SwDoc* pClpDoc, const OUString* pNewClpText = nullptr ); - bool Paste( SwDoc* pClpDoc ); + bool Paste( SwDoc* pClpDoc, bool bInCell = false ); /// Paste some pages into another doc - used in mailmerge. void PastePages( SwFEShell& rToFill, sal_uInt16 nStartPage, sal_uInt16 nEndPage); diff --git a/sw/sdi/_basesh.sdi b/sw/sdi/_basesh.sdi index 472198cdc922..39c4153349ac 100644 --- a/sw/sdi/_basesh.sdi +++ b/sw/sdi/_basesh.sdi @@ -115,6 +115,13 @@ interface BaseTextSelection DisableFlags="SfxDisableFlags::SwOnProtectedCursor"; ] + FN_TABLE_PASTE_IN_CELL // status(final|play) + [ + ExecMethod = ExecClpbrd ; + StateMethod = StateClpbrd ; + DisableFlags="SfxDisableFlags::SwOnProtectedCursor"; + ] + FN_REPAGINATE // status(final|play) [ ExecMethod = Execute ; diff --git a/sw/sdi/swriter.sdi b/sw/sdi/swriter.sdi index 78dfda33e744..73c32a67c7b2 100644 --- a/sw/sdi/swriter.sdi +++ b/sw/sdi/swriter.sdi @@ -2681,6 +2681,24 @@ SfxVoidItem InsertColumnsAfter FN_TABLE_INSERT_COL_AFTER GroupId = SfxGroupId::Table; ] +SfxVoidItem PasteTableInCell FN_TABLE_PASTE_IN_CELL +() +[ + AutoUpdate = FALSE, + FastCall = TRUE, + ReadOnlyDoc = FALSE, + Toggle = FALSE, + Container = FALSE, + RecordAbsolute = FALSE, + RecordPerSet; + Asynchron; + + AccelConfig = FALSE, + MenuConfig = FALSE, + ToolBoxConfig = TRUE, + GroupId = SfxGroupId::Edit; +] + SfxUInt16Item InsertSection FN_INSERT_REGION (SfxUInt16Item Columns SID_ATTR_COLUMNS,SfxStringItem RegionName FN_PARAM_REGION_NAME,SfxStringItem RegionCondition FN_PARAM_REGION_CONDITION,SfxBoolItem RegionHidden FN_PARAM_REGION_HIDDEN,SfxBoolItem RegionProtect FN_PARAM_REGION_PROTECT,SfxStringItem LinkName FN_PARAM_1,SfxStringItem FilterName FN_PARAM_2,SfxStringItem SubRegion FN_PARAM_3) [ diff --git a/sw/source/core/frmedt/fecopy.cxx b/sw/source/core/frmedt/fecopy.cxx index 8dadded1e2a6..461a41589829 100644 --- a/sw/source/core/frmedt/fecopy.cxx +++ b/sw/source/core/frmedt/fecopy.cxx @@ -672,7 +672,7 @@ namespace { } } -bool SwFEShell::Paste( SwDoc* pClpDoc ) +bool SwFEShell::Paste( SwDoc* pClpDoc, bool bInCell ) { SET_CURR_SHELL( this ); OSL_ENSURE( pClpDoc, "no clipboard document" ); @@ -818,6 +818,8 @@ bool SwFEShell::Paste( SwDoc* pClpDoc ) SwTableNode *const pDestNd(GetDoc()->IsIdxInTable(rPaM.GetPoint()->nNode)); if (pSrcNd && nullptr != pDestNd && + // not a forced nested table insertion + !bInCell && // are we at the beginning of the cell? (if not, we will insert a nested table) // first paragraph of the cell? rPaM.GetNode().GetIndex() == rPaM.GetNode().FindTableBoxStartNode()->GetIndex()+1 && diff --git a/sw/source/uibase/dochdl/swdtflvr.cxx b/sw/source/uibase/dochdl/swdtflvr.cxx index ffdbd98b4538..928fe5d2d623 100644 --- a/sw/source/uibase/dochdl/swdtflvr.cxx +++ b/sw/source/uibase/dochdl/swdtflvr.cxx @@ -1360,7 +1360,7 @@ bool SwTransferable::IsPaste( const SwWrtShell& rSh, return bIsPaste; } -bool SwTransferable::Paste(SwWrtShell& rSh, TransferableDataHelper& rData, RndStdIds nAnchorType, bool bIgnoreComments) +bool SwTransferable::Paste(SwWrtShell& rSh, TransferableDataHelper& rData, RndStdIds nAnchorType, bool bIgnoreComments, bool bInCell) { SwPasteContext aPasteContext(rSh); @@ -1432,7 +1432,7 @@ bool SwTransferable::Paste(SwWrtShell& rSh, TransferableDataHelper& rData, RndSt nLevel++; } while (rSh.GetDoc()->IsIdxInTable(rSh.GetCursor()->GetNode()) != nullptr); if ( SwTransferable::PasteData( rData, rSh, EXCHG_OUT_ACTION_INSERT_STRING, nActionFlags, SotClipboardFormatId::HTML, - nDestination, false, false, nullptr, 0, false, nAnchorType, bIgnoreComments, &aPasteContext )) + nDestination, false, false, nullptr, 0, false, nAnchorType, bIgnoreComments, &aPasteContext, bInCell )) { pDispatch->Execute(FN_CHAR_LEFT, SfxCallMode::SYNCHRON); pDispatch->Execute(FN_TABLE_SELECT_ALL, SfxCallMode::SYNCHRON); @@ -1502,7 +1502,7 @@ bool SwTransferable::Paste(SwWrtShell& rSh, TransferableDataHelper& rData, RndSt // paste rows bool bResult = SwTransferable::PasteData( rData, rSh, nAction, nActionFlags, nFormat, - nDestination, false, false, nullptr, 0, false, nAnchorType, bIgnoreComments, &aPasteContext ); + nDestination, false, false, nullptr, 0, false, nAnchorType, bIgnoreComments, &aPasteContext, bInCell ); // restore cursor position if (pMark != nullptr) @@ -1534,7 +1534,7 @@ bool SwTransferable::Paste(SwWrtShell& rSh, TransferableDataHelper& rData, RndSt return EXCHG_INOUT_ACTION_NONE != nAction && SwTransferable::PasteData( rData, rSh, nAction, nActionFlags, nFormat, - nDestination, false, false, nullptr, 0, false, nAnchorType, bIgnoreComments, &aPasteContext ); + nDestination, false, false, nullptr, 0, false, nAnchorType, bIgnoreComments, &aPasteContext, bInCell ); } bool SwTransferable::PasteData( TransferableDataHelper& rData, @@ -1545,7 +1545,8 @@ bool SwTransferable::PasteData( TransferableDataHelper& rData, const Point* pPt, sal_Int8 nDropAction, bool bPasteSelection, RndStdIds nAnchorType, bool bIgnoreComments, - SwPasteContext* pContext ) + SwPasteContext* pContext, + bool bInCell ) { SwWait aWait( *rSh.GetView().GetDocShell(), false ); std::unique_ptr> pAction; @@ -1651,7 +1652,7 @@ bool SwTransferable::PasteData( TransferableDataHelper& rData, EXCHG_OUT_ACTION_INSERT_PRIVATE == nAction ) { // then internal paste - bRet = pTunneledTrans->PrivatePaste(rSh, pContext); + bRet = pTunneledTrans->PrivatePaste(rSh, pContext, bInCell); } else if( EXCHG_INOUT_ACTION_NONE != nAction ) { @@ -3621,7 +3622,7 @@ bool lcl_checkClassification(SwDoc* pSourceDoc, SwDoc* pDestinationDoc) } -bool SwTransferable::PrivatePaste(SwWrtShell& rShell, SwPasteContext* pContext) +bool SwTransferable::PrivatePaste(SwWrtShell& rShell, SwPasteContext* pContext, bool bInCell) { // first, ask for the SelectionType, then action-bracketing !!!! // (otherwise it's not pasted into a TableSelection!!!) @@ -3683,7 +3684,7 @@ bool SwTransferable::PrivatePaste(SwWrtShell& rShell, SwPasteContext* pContext) bool bRet = true; // m_pWrtShell is nullptr when the source document is closed already. if (!m_pWrtShell || lcl_checkClassification(m_pWrtShell->GetDoc(), rShell.GetDoc())) - bRet = rShell.Paste(m_pClpDocFac->GetDoc()); + bRet = rShell.Paste(m_pClpDocFac->GetDoc(), bInCell); if( bKillPaMs ) rShell.KillPams(); diff --git a/sw/source/uibase/inc/swdtflvr.hxx b/sw/source/uibase/inc/swdtflvr.hxx index 680e808767b8..39065b2dd0d1 100644 --- a/sw/source/uibase/inc/swdtflvr.hxx +++ b/sw/source/uibase/inc/swdtflvr.hxx @@ -138,7 +138,7 @@ class SW_DLLPUBLIC SwTransferable : public TransferableHelper bool PrivateDrop( SwWrtShell& rSh, const Point& rDragPt, bool bMove, bool bIsXSelection ); - bool PrivatePaste( SwWrtShell& rShell, SwPasteContext* pContext = nullptr ); + bool PrivatePaste( SwWrtShell& rShell, SwPasteContext* pContext = nullptr, bool bInCell = false ); void SetDataForDragAndDrop( const Point& rSttPos ); @@ -180,7 +180,7 @@ public: // paste - methods and helper methods for the paste static bool IsPaste( const SwWrtShell&, const TransferableDataHelper& ); - static bool Paste( SwWrtShell&, TransferableDataHelper&, RndStdIds nAnchorType = RndStdIds::FLY_AT_PARA, bool bIgnoreComments = false ); + static bool Paste( SwWrtShell&, TransferableDataHelper&, RndStdIds nAnchorType = RndStdIds::FLY_AT_PARA, bool bIgnoreComments = false, bool bTableInCell = false ); static bool PasteData( TransferableDataHelper& rData, SwWrtShell& rSh, sal_uInt8 nAction, SotExchangeActionFlags nActionFlags, SotClipboardFormatId nFormat, @@ -189,7 +189,8 @@ public: const Point* pDDPos = nullptr, sal_Int8 nDropAction = 0, bool bPasteSelection = false, RndStdIds nAnchorType = RndStdIds::FLY_AT_PARA, bool bIgnoreComments = false, - SwPasteContext* pContext = nullptr ); + SwPasteContext* pContext = nullptr, + bool bInCell = false ); static bool IsPasteSpecial( const SwWrtShell& rWrtShell, const TransferableDataHelper& ); diff --git a/sw/source/uibase/shells/basesh.cxx b/sw/source/uibase/shells/basesh.cxx index e65149b15995..d4b2a33b9d1a 100644 --- a/sw/source/uibase/shells/basesh.cxx +++ b/sw/source/uibase/shells/basesh.cxx @@ -258,6 +258,7 @@ void SwBaseShell::ExecClpbrd(SfxRequest &rReq) SwWrtShell &rSh = GetShell(); sal_uInt16 nId = rReq.GetSlot(); bool bIgnore = false; + bool bPasteInCell = false; switch( nId ) { case SID_CUT: @@ -280,6 +281,9 @@ void SwBaseShell::ExecClpbrd(SfxRequest &rReq) } return; + case FN_TABLE_PASTE_IN_CELL: + bPasteInCell = true; + [[fallthrough]]; case SID_PASTE: { TransferableDataHelper aDataHelper( @@ -299,7 +303,7 @@ void SwBaseShell::ExecClpbrd(SfxRequest &rReq) const SfxBoolItem* pIgnoreComments = rReq.GetArg(FN_PARAM_2); if (pIgnoreComments) bIgnoreComments = pIgnoreComments->GetValue(); - SwTransferable::Paste(rSh, aDataHelper, nAnchorType, bIgnoreComments); + SwTransferable::Paste(rSh, aDataHelper, nAnchorType, bIgnoreComments, bPasteInCell); if( rSh.IsFrameSelected() || rSh.IsObjSelected() ) rSh.EnterSelFrameMode(); diff --git a/sw/source/uibase/uiview/view.cxx b/sw/source/uibase/uiview/view.cxx index ec013052dc75..791a5ca781c7 100644 --- a/sw/source/uibase/uiview/view.cxx +++ b/sw/source/uibase/uiview/view.cxx @@ -594,7 +594,7 @@ void SwView::CheckReadonlyState() SID_DELETE, FN_BACKSPACE, FN_SHIFT_BACKSPACE, SID_UNDO, SID_REDO, SID_REPEAT, SID_PASTE, - SID_PASTE_UNFORMATTED, + SID_PASTE_UNFORMATTED, FN_TABLE_PASTE_IN_CELL, SID_PASTE_SPECIAL, SID_SBA_BRW_INSERT, SID_BACKGROUND_COLOR, FN_INSERT_BOOKMARK, SID_CHARMAP_CONTROL, SID_CHARMAP, SID_EMOJI_CONTROL, FN_INSERT_SOFT_HYPHEN, diff --git a/sw/uiconfig/swriter/popupmenu/table.xml b/sw/uiconfig/swriter/popupmenu/table.xml index 09470cab6d34..ddcc425b3b96 100644 --- a/sw/uiconfig/swriter/popupmenu/table.xml +++ b/sw/uiconfig/swriter/popupmenu/table.xml @@ -14,6 +14,7 @@ + -- 2.17.1