officecfg/registry/data/org/openoffice/Office/UI/WriterCommands.xcu | 24 ++++++ sw/inc/cmdid.h | 6 + sw/sdi/_basesh.sdi | 14 +++ sw/sdi/swriter.sdi | 36 ++++++++++ sw/source/uibase/dochdl/swdtflvr.cxx | 32 +++++--- sw/source/uibase/inc/swdtflvr.hxx | 16 +++- sw/source/uibase/shells/basesh.cxx | 24 +++++- sw/source/uibase/uiview/view.cxx | 4 - sw/uiconfig/swriter/menubar/menubar.xml | 2 sw/uiconfig/swriter/popupmenu/table.xml | 2 10 files changed, 137 insertions(+), 23 deletions(-)
New commits: commit 7efae60f3625a58f8a617c80f2a55a695fbaef36 Author: László Németh <nem...@numbertext.org> AuthorDate: Mon Dec 16 13:50:25 2019 +0100 Commit: László Németh <nem...@numbertext.org> CommitDate: Tue Dec 17 11:50:48 2019 +0100 tdf#64902 Writer table: Paste Special->Rows Above and Columns Before table popup and Edit menu items to insert clipboard table data in a table as new rows/columns instead of overwriting the content of the original cells of the target table. This commit introduces the new commands .uno:PasteRowsBefore and .uno:PasteColumnsBefore. See also commit 1e278d1d0cfb1d5375195aa764739f00633f21e8 (tdf#37156 Writer menu: Paste as Nested table). Change-Id: I7d13246a3ace6c5f709d607c416150f8872e4695 Reviewed-on: https://gerrit.libreoffice.org/85214 Tested-by: Jenkins Reviewed-by: László Németh <nem...@numbertext.org> diff --git a/officecfg/registry/data/org/openoffice/Office/UI/WriterCommands.xcu b/officecfg/registry/data/org/openoffice/Office/UI/WriterCommands.xcu index ac60dc4e32ca..40ca50889208 100644 --- a/officecfg/registry/data/org/openoffice/Office/UI/WriterCommands.xcu +++ b/officecfg/registry/data/org/openoffice/Office/UI/WriterCommands.xcu @@ -1528,7 +1528,29 @@ <value xml:lang="en-US">Paste as Nested Table</value> </prop> <prop oor:name="PopupLabel" oor:type="xs:string"> - <value xml:lang="en-US">As Nested Table</value> + <value xml:lang="en-US">~Nested Table</value> + </prop> + <prop oor:name="Properties" oor:type="xs:int"> + <value>1</value> + </prop> + </node> + <node oor:name=".uno:PasteRowsBefore" oor:op="replace"> + <prop oor:name="Label" oor:type="xs:string"> + <value xml:lang="en-US">Paste as Rows Above</value> + </prop> + <prop oor:name="PopupLabel" oor:type="xs:string"> + <value xml:lang="en-US">Rows ~Above</value> + </prop> + <prop oor:name="Properties" oor:type="xs:int"> + <value>1</value> + </prop> + </node> + <node oor:name=".uno:PasteColumnsBefore" oor:op="replace"> + <prop oor:name="Label" oor:type="xs:string"> + <value xml:lang="en-US">Paste as Columns Before</value> + </prop> + <prop oor:name="PopupLabel" oor:type="xs:string"> + <value xml:lang="en-US">Columns ~Before</value> </prop> <prop oor:name="Properties" oor:type="xs:int"> <value>1</value> diff --git a/sw/inc/cmdid.h b/sw/inc/cmdid.h index 6aba5e4d72d4..f382e820cf0b 100644 --- a/sw/inc/cmdid.h +++ b/sw/inc/cmdid.h @@ -281,6 +281,11 @@ // MSO content controls #define FN_INSERT_DATE_FORMFIELD (FN_INSERT2 + 25) +// clipboard table content +#define FN_PASTE_NESTED_TABLE (FN_INSERT2 + 30) /* instead of the cell-by-cell copy between source and target tables */ +#define FN_TABLE_PASTE_ROW_BEFORE (FN_INSERT2 + 31) /* paste table as new table rows */ +#define FN_TABLE_PASTE_COL_BEFORE (FN_INSERT2 + 32) /* paste table as new table columns */ + // Region: Format #define FN_AUTOFORMAT_APPLY (FN_FORMAT + 1 ) /* apply autoformat options */ #define FN_AUTOFORMAT_AUTO (FN_FORMAT + 2 ) /* apply autoformat during user input */ @@ -343,7 +348,6 @@ #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_PASTE_NESTED_TABLE (FN_FORMAT + 118) /* instead of the cell-by-cell copy between source and target tables */ #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/sdi/_basesh.sdi b/sw/sdi/_basesh.sdi index 886ae2863a9f..ef4dd4413a1a 100644 --- a/sw/sdi/_basesh.sdi +++ b/sw/sdi/_basesh.sdi @@ -122,6 +122,20 @@ interface BaseTextSelection DisableFlags="SfxDisableFlags::SwOnProtectedCursor"; ] + FN_TABLE_PASTE_ROW_BEFORE // status(final|play) + [ + ExecMethod = ExecClpbrd ; + StateMethod = StateClpbrd ; + DisableFlags="SfxDisableFlags::SwOnProtectedCursor"; + ] + + FN_TABLE_PASTE_COL_BEFORE // 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 321804cda1bf..d063a0dd5441 100644 --- a/sw/sdi/swriter.sdi +++ b/sw/sdi/swriter.sdi @@ -2699,6 +2699,42 @@ SfxVoidItem PasteNestedTable FN_PASTE_NESTED_TABLE GroupId = SfxGroupId::Edit; ] +SfxVoidItem PasteRowsBefore FN_TABLE_PASTE_ROW_BEFORE +() +[ + AutoUpdate = FALSE, + FastCall = TRUE, + ReadOnlyDoc = FALSE, + Toggle = FALSE, + Container = FALSE, + RecordAbsolute = FALSE, + RecordPerSet; + Asynchron; + + AccelConfig = FALSE, + MenuConfig = TRUE, + ToolBoxConfig = TRUE, + GroupId = SfxGroupId::Edit; +] + +SfxVoidItem PasteColumnsBefore FN_TABLE_PASTE_COL_BEFORE +() +[ + AutoUpdate = FALSE, + FastCall = TRUE, + ReadOnlyDoc = FALSE, + Toggle = FALSE, + Container = FALSE, + RecordAbsolute = FALSE, + RecordPerSet; + Asynchron; + + AccelConfig = FALSE, + MenuConfig = TRUE, + 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/uibase/dochdl/swdtflvr.cxx b/sw/source/uibase/dochdl/swdtflvr.cxx index 72ef1889f9f6..5b875cc3bdbe 100644 --- a/sw/source/uibase/dochdl/swdtflvr.cxx +++ b/sw/source/uibase/dochdl/swdtflvr.cxx @@ -1365,7 +1365,7 @@ bool SwTransferable::IsPaste( const SwWrtShell& rSh, return bIsPaste; } -bool SwTransferable::Paste(SwWrtShell& rSh, TransferableDataHelper& rData, RndStdIds nAnchorType, bool bIgnoreComments, bool bNestedTable) +bool SwTransferable::Paste(SwWrtShell& rSh, TransferableDataHelper& rData, RndStdIds nAnchorType, bool bIgnoreComments, PasteTableType ePasteTable) { SwPasteContext aPasteContext(rSh); @@ -1437,15 +1437,19 @@ 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, bNestedTable )) + nDestination, false, false, nullptr, 0, false, nAnchorType, bIgnoreComments, &aPasteContext, ePasteTable) ) { pDispatch->Execute(FN_CHAR_LEFT, SfxCallMode::SYNCHRON); pDispatch->Execute(FN_TABLE_SELECT_ALL, SfxCallMode::SYNCHRON); pDispatch->Execute(SID_COPY, SfxCallMode::SYNCHRON); for(sal_uInt32 a = 0; a < 1 + (nLevel * 2); a++) pDispatch->Execute(SID_UNDO, SfxCallMode::SYNCHRON); - if (bNestedTable) + if (ePasteTable == PasteTableType::PASTE_TABLE) pDispatch->Execute(FN_PASTE_NESTED_TABLE, SfxCallMode::SYNCHRON); + else if (ePasteTable == PasteTableType::PASTE_ROW) + pDispatch->Execute(FN_TABLE_PASTE_ROW_BEFORE, SfxCallMode::SYNCHRON); + else if (ePasteTable == PasteTableType::PASTE_COLUMN) + pDispatch->Execute(FN_TABLE_PASTE_COL_BEFORE, SfxCallMode::SYNCHRON); else pDispatch->Execute(SID_PASTE, SfxCallMode::SYNCHRON); return true; @@ -1456,22 +1460,24 @@ bool SwTransferable::Paste(SwWrtShell& rSh, TransferableDataHelper& rData, RndSt } } // insert clipboard content as new table rows/columns before the actual row/column instead of overwriting it - else if ( rSh.GetTableInsertMode() != SwTable::SEARCH_NONE && + else if ( (rSh.GetTableInsertMode() != SwTable::SEARCH_NONE || ePasteTable == PasteTableType::PASTE_ROW || ePasteTable == PasteTableType::PASTE_COLUMN) && rData.HasFormat( SotClipboardFormatId::HTML ) && rSh.GetDoc()->IsIdxInTable(rSh.GetCursor()->GetNode()) != nullptr ) { OUString aExpand; sal_Int32 nIdx; - bool bRowMode = rSh.GetTableInsertMode() == SwTable::SEARCH_ROW; + bool bRowMode = rSh.GetTableInsertMode() == SwTable::SEARCH_ROW || ePasteTable == PasteTableType::PASTE_ROW; if( rData.GetString( SotClipboardFormatId::HTML, aExpand ) && (nIdx = aExpand.indexOf("<table")) > -1 ) { + // table rows with span use also tbody + bool bShifted = aExpand.indexOf("<tbody>") > -1; // calculate count of selected rows or columns sal_Int32 nSelectedRowsOrCols = 0; const OUString sSearchRowOrCol = bRowMode ? OUString("</tr>") : OUString("<col "); while((nIdx = aExpand.indexOf(sSearchRowOrCol, nIdx)) > -1) { // skip rows/columns of nested tables, based on HTML indentation - if (nIdx > 1 && (aExpand[nIdx-1] != '\t' || aExpand[nIdx-2] != '\t' )) + if (nIdx > 2 && (aExpand[nIdx-1] != '\t' || aExpand[nIdx-2] != '\t' || (bShifted && aExpand[nIdx-3] != '\t'))) ++nSelectedRowsOrCols; ++nIdx; } @@ -1488,7 +1494,7 @@ bool SwTransferable::Paste(SwWrtShell& rSh, TransferableDataHelper& rData, RndSt pDispatch->Execute(FN_START_OF_DOCUMENT, SfxCallMode::SYNCHRON); // store cursor position in row mode - ::sw::mark::IMark* pMark = !bRowMode ? nullptr : rSh.SetBookmark( + ::sw::mark::IMark* pMark = (!bRowMode || nSelectedRowsOrCols == 0) ? nullptr : rSh.SetBookmark( vcl::KeyCode(), OUString(), IDocumentMarkAccess::MarkType::UNO_BOOKMARK ); @@ -1510,7 +1516,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, bNestedTable ); + nDestination, false, false, nullptr, 0, false, nAnchorType, bIgnoreComments, &aPasteContext ); // restore cursor position if (pMark != nullptr) @@ -1542,7 +1548,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, bNestedTable ); + nDestination, false, false, nullptr, 0, false, nAnchorType, bIgnoreComments, &aPasteContext, ePasteTable); } bool SwTransferable::PasteData( TransferableDataHelper& rData, @@ -1554,7 +1560,7 @@ bool SwTransferable::PasteData( TransferableDataHelper& rData, bool bPasteSelection, RndStdIds nAnchorType, bool bIgnoreComments, SwPasteContext* pContext, - bool bNestedTable ) + PasteTableType ePasteTable ) { SwWait aWait( *rSh.GetView().GetDocShell(), false ); std::unique_ptr<SwTrnsfrActionAndUndo, o3tl::default_delete<SwTrnsfrActionAndUndo>> pAction; @@ -1660,7 +1666,7 @@ bool SwTransferable::PasteData( TransferableDataHelper& rData, EXCHG_OUT_ACTION_INSERT_PRIVATE == nAction ) { // then internal paste - bRet = pTunneledTrans->PrivatePaste(rSh, pContext, bNestedTable); + bRet = pTunneledTrans->PrivatePaste(rSh, pContext, ePasteTable); } else if( EXCHG_INOUT_ACTION_NONE != nAction ) { @@ -3635,7 +3641,7 @@ bool lcl_checkClassification(SwDoc* pSourceDoc, SwDoc* pDestinationDoc) } -bool SwTransferable::PrivatePaste(SwWrtShell& rShell, SwPasteContext* pContext, bool bNestedTable) +bool SwTransferable::PrivatePaste(SwWrtShell& rShell, SwPasteContext* pContext, PasteTableType ePasteTable) { // first, ask for the SelectionType, then action-bracketing !!!! // (otherwise it's not pasted into a TableSelection!!!) @@ -3697,7 +3703,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(), bNestedTable); + bRet = rShell.Paste(m_pClpDocFac->GetDoc(), ePasteTable == PasteTableType::PASTE_TABLE); if( bKillPaMs ) rShell.KillPams(); diff --git a/sw/source/uibase/inc/swdtflvr.hxx b/sw/source/uibase/inc/swdtflvr.hxx index c63b1987afc4..fdb545311351 100644 --- a/sw/source/uibase/inc/swdtflvr.hxx +++ b/sw/source/uibase/inc/swdtflvr.hxx @@ -62,6 +62,14 @@ enum class TransferBufferType : sal_uInt16 namespace o3tl { template<> struct typed_flags<TransferBufferType> : is_typed_flags<TransferBufferType, 0x00ef> {}; } +// paste table into a table +enum class PasteTableType +{ + PASTE_DEFAULT, // paste table by overwriting table cells + PASTE_ROW, // paste table as rows above + PASTE_COLUMN, // paste table as columns before + PASTE_TABLE // paste table as nested table +}; class SW_DLLPUBLIC SwTransferable : public TransferableHelper { @@ -138,7 +146,8 @@ 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 bNestedTable = false ); + + bool PrivatePaste( SwWrtShell& rShell, SwPasteContext* pContext = nullptr, PasteTableType ePasteTable = PasteTableType::PASTE_DEFAULT ); void SetDataForDragAndDrop( const Point& rSttPos ); @@ -180,7 +189,8 @@ 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, bool bTableInCell = false ); + static bool Paste( SwWrtShell&, TransferableDataHelper&, RndStdIds nAnchorType = RndStdIds::FLY_AT_PARA, + bool bIgnoreComments = false, PasteTableType ePasteTable = PasteTableType::PASTE_DEFAULT ); static bool PasteData( TransferableDataHelper& rData, SwWrtShell& rSh, sal_uInt8 nAction, SotExchangeActionFlags nActionFlags, SotClipboardFormatId nFormat, @@ -190,7 +200,7 @@ public: bool bPasteSelection = false, RndStdIds nAnchorType = RndStdIds::FLY_AT_PARA, bool bIgnoreComments = false, SwPasteContext* pContext = nullptr, - bool bNestedTable = false ); + PasteTableType nPaste = PasteTableType::PASTE_DEFAULT ); 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 c9e5a8ec15bf..07ba572b15d2 100644 --- a/sw/source/uibase/shells/basesh.cxx +++ b/sw/source/uibase/shells/basesh.cxx @@ -258,7 +258,8 @@ void SwBaseShell::ExecClpbrd(SfxRequest &rReq) SwWrtShell &rSh = GetShell(); sal_uInt16 nId = rReq.GetSlot(); bool bIgnore = false; - bool bPasteNestedTable = false; + PasteTableType ePasteTable = PasteTableType::PASTE_DEFAULT; + switch( nId ) { case SID_CUT: @@ -282,7 +283,22 @@ void SwBaseShell::ExecClpbrd(SfxRequest &rReq) return; case FN_PASTE_NESTED_TABLE: - bPasteNestedTable = true; + case FN_TABLE_PASTE_ROW_BEFORE: + case FN_TABLE_PASTE_COL_BEFORE: + switch ( nId ) + { + case FN_PASTE_NESTED_TABLE: + ePasteTable = PasteTableType::PASTE_TABLE; + break; + case FN_TABLE_PASTE_ROW_BEFORE: + ePasteTable = PasteTableType::PASTE_ROW; + break; + case FN_TABLE_PASTE_COL_BEFORE: + ePasteTable = PasteTableType::PASTE_COLUMN; + break; + default: + ; + } [[fallthrough]]; case SID_PASTE: { @@ -303,7 +319,7 @@ void SwBaseShell::ExecClpbrd(SfxRequest &rReq) const SfxBoolItem* pIgnoreComments = rReq.GetArg<SfxBoolItem>(FN_PARAM_2); if (pIgnoreComments) bIgnoreComments = pIgnoreComments->GetValue(); - SwTransferable::Paste(rSh, aDataHelper, nAnchorType, bIgnoreComments, bPasteNestedTable); + SwTransferable::Paste(rSh, aDataHelper, nAnchorType, bIgnoreComments, ePasteTable); if( rSh.IsFrameSelected() || rSh.IsObjSelected() ) rSh.EnterSelFrameMode(); @@ -471,6 +487,8 @@ void SwBaseShell::StateClpbrd(SfxItemSet &rSet) break; case FN_PASTE_NESTED_TABLE: + case FN_TABLE_PASTE_ROW_BEFORE: + case FN_TABLE_PASTE_COL_BEFORE: if( !rSh.IsCursorInTable() || !GetView().IsPasteSpecialAllowed() || rSh.CursorInsideInputField() diff --git a/sw/source/uibase/uiview/view.cxx b/sw/source/uibase/uiview/view.cxx index 25d394f1f364..3a207d010ff2 100644 --- a/sw/source/uibase/uiview/view.cxx +++ b/sw/source/uibase/uiview/view.cxx @@ -594,8 +594,8 @@ void SwView::CheckReadonlyState() SID_DELETE, FN_BACKSPACE, FN_SHIFT_BACKSPACE, SID_UNDO, SID_REDO, SID_REPEAT, SID_PASTE, - SID_PASTE_UNFORMATTED, FN_PASTE_NESTED_TABLE, - SID_PASTE_SPECIAL, SID_SBA_BRW_INSERT, + SID_PASTE_UNFORMATTED, FN_PASTE_NESTED_TABLE, FN_TABLE_PASTE_ROW_BEFORE, + FN_TABLE_PASTE_COL_BEFORE, 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, FN_INSERT_HARDHYPHEN, FN_INSERT_HARD_SPACE, FN_INSERT_NNBSP, diff --git a/sw/uiconfig/swriter/menubar/menubar.xml b/sw/uiconfig/swriter/menubar/menubar.xml index 77e1ebae5f57..bdfd44675517 100644 --- a/sw/uiconfig/swriter/menubar/menubar.xml +++ b/sw/uiconfig/swriter/menubar/menubar.xml @@ -106,6 +106,8 @@ <menu:menuitem menu:id=".uno:PasteUnformatted"/> <menu:menuitem menu:id=".uno:PasteSpecial"/> <menu:menuitem menu:id=".uno:PasteNestedTable"/> + <menu:menuitem menu:id=".uno:PasteRowsBefore"/> + <menu:menuitem menu:id=".uno:PasteColumnsBefore"/> </menu:menupopup> </menu:menu> <menu:menuseparator/> diff --git a/sw/uiconfig/swriter/popupmenu/table.xml b/sw/uiconfig/swriter/popupmenu/table.xml index 4baf20af019d..2a302ef1a2cd 100644 --- a/sw/uiconfig/swriter/popupmenu/table.xml +++ b/sw/uiconfig/swriter/popupmenu/table.xml @@ -14,6 +14,8 @@ <menu:menu menu:id=".uno:PasteSpecialMenu"> <menu:menupopup> <menu:menuitem menu:id=".uno:PasteNestedTable"/> + <menu:menuitem menu:id=".uno:PasteRowsBefore"/> + <menu:menuitem menu:id=".uno:PasteColumnsBefore"/> <menu:menuitem menu:id=".uno:PasteUnformatted"/> <menu:menuitem menu:id=".uno:PasteSpecial"/> </menu:menupopup> _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits