summaryrefslogtreecommitdiff
path: root/sw
diff options
context:
space:
mode:
Diffstat (limited to 'sw')
-rw-r--r--sw/inc/cmdid.h1
-rw-r--r--sw/inc/fesh.hxx6
-rw-r--r--sw/inc/view.hxx1
-rw-r--r--sw/sdi/_basesh.sdi7
-rw-r--r--sw/sdi/swriter.sdi18
-rw-r--r--sw/source/core/frmedt/fecopy.cxx4
-rw-r--r--sw/source/uibase/dochdl/swdtflvr.cxx32
-rw-r--r--sw/source/uibase/inc/swdtflvr.hxx8
-rw-r--r--sw/source/uibase/shells/basesh.cxx17
-rw-r--r--sw/source/uibase/uiview/view.cxx16
-rw-r--r--sw/uiconfig/swriter/menubar/menubar.xml1
-rw-r--r--sw/uiconfig/swriter/popupmenu/table.xml1
12 files changed, 96 insertions, 16 deletions
diff --git a/sw/inc/cmdid.h b/sw/inc/cmdid.h
index 6b49d5a91e51..6aba5e4d72d4 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_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/inc/fesh.hxx b/sw/inc/fesh.hxx
index f60f92cff44e..b928420ea824 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 bNestedTable = false );
/// Paste some pages into another doc - used in mailmerge.
void PastePages( SwFEShell& rToFill, sal_uInt16 nStartPage, sal_uInt16 nEndPage);
@@ -643,6 +643,10 @@ public:
SwTable::SearchType m_eTableInsertMode;
SwTable::SearchType GetTableInsertMode() const { return m_eTableInsertMode; }
void SetTableInsertMode( SwTable::SearchType eFlag ) { m_eTableInsertMode = eFlag; }
+ /// table copied to the clipboard by the last private copy
+ bool bTableCopied;
+ bool GetTableCopied() { return bTableCopied; }
+ void SetTableCopied( bool bCopied ) { bTableCopied = bCopied; }
bool DeleteTableSel(); ///< Current selection, may be whole table.
diff --git a/sw/inc/view.hxx b/sw/inc/view.hxx
index 13f73dc09123..1ce11c33bda6 100644
--- a/sw/inc/view.hxx
+++ b/sw/inc/view.hxx
@@ -589,6 +589,7 @@ public:
// Status changes now notified from the clipboard.
bool IsPasteAllowed();
bool IsPasteSpecialAllowed();
+ bool IsPasteSpreadsheet(bool bHasOwnTableCopied);
// Enable mail merge - mail merge field dialog enabled
void EnableMailMerge();
diff --git a/sw/sdi/_basesh.sdi b/sw/sdi/_basesh.sdi
index 472198cdc922..886ae2863a9f 100644
--- a/sw/sdi/_basesh.sdi
+++ b/sw/sdi/_basesh.sdi
@@ -115,6 +115,13 @@ interface BaseTextSelection
DisableFlags="SfxDisableFlags::SwOnProtectedCursor";
]
+ FN_PASTE_NESTED_TABLE // 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..321804cda1bf 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 PasteNestedTable FN_PASTE_NESTED_TABLE
+()
+[
+ 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/core/frmedt/fecopy.cxx b/sw/source/core/frmedt/fecopy.cxx
index 8dadded1e2a6..ed91aa86b851 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 bNestedTable )
{
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
+ !bNestedTable &&
// 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 bb140e9742af..72ef1889f9f6 100644
--- a/sw/source/uibase/dochdl/swdtflvr.cxx
+++ b/sw/source/uibase/dochdl/swdtflvr.cxx
@@ -893,6 +893,9 @@ int SwTransferable::PrepareForCopy( bool bIsCut )
if ( m_pWrtShell->GetTableInsertMode() != SwTable::SEARCH_NONE )
m_pWrtShell->SetTableInsertMode( SwTable::SEARCH_NONE );
+ if ( m_pWrtShell->GetTableCopied() )
+ m_pWrtShell->SetTableCopied( false );
+
OUString sGrfNm;
const SelectionType nSelection = m_pWrtShell->GetSelectionType();
if( nSelection == SelectionType::Graphic )
@@ -1025,6 +1028,8 @@ int SwTransferable::PrepareForCopy( bool bIsCut )
m_eBufferType = TransferBufferType::Table | m_eBufferType;
bDDELink = m_pWrtShell->HasWholeTabSelection();
+ m_pWrtShell->SetTableCopied(true);
+
if ( bIsCut && (SelectionType::TableRow | SelectionType::TableCol) & nSelection )
m_pWrtShell->SetTableInsertMode( (SelectionType::TableRow & nSelection) ? SwTable::SEARCH_ROW : SwTable::SEARCH_COL );
}
@@ -1360,7 +1365,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 bNestedTable)
{
SwPasteContext aPasteContext(rSh);
@@ -1432,14 +1437,17 @@ 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, bNestedTable ))
{
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);
- pDispatch->Execute(SID_PASTE, SfxCallMode::SYNCHRON);
+ if (bNestedTable)
+ pDispatch->Execute(FN_PASTE_NESTED_TABLE, SfxCallMode::SYNCHRON);
+ else
+ pDispatch->Execute(SID_PASTE, SfxCallMode::SYNCHRON);
return true;
} else {
for(sal_uInt32 a = 0; a < (nLevel * 2); a++)
@@ -1502,7 +1510,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, bNestedTable );
// restore cursor position
if (pMark != nullptr)
@@ -1534,7 +1542,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, bNestedTable );
}
bool SwTransferable::PasteData( TransferableDataHelper& rData,
@@ -1545,7 +1553,8 @@ bool SwTransferable::PasteData( TransferableDataHelper& rData,
const Point* pPt, sal_Int8 nDropAction,
bool bPasteSelection, RndStdIds nAnchorType,
bool bIgnoreComments,
- SwPasteContext* pContext )
+ SwPasteContext* pContext,
+ bool bNestedTable )
{
SwWait aWait( *rSh.GetView().GetDocShell(), false );
std::unique_ptr<SwTrnsfrActionAndUndo, o3tl::default_delete<SwTrnsfrActionAndUndo>> pAction;
@@ -1651,7 +1660,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, bNestedTable);
}
else if( EXCHG_INOUT_ACTION_NONE != nAction )
{
@@ -3197,6 +3206,11 @@ bool SwTransferable::IsPasteSpecial( const SwWrtShell& rWrtShell,
return aClipboardFormatItem.Count() > 0;
}
+bool SwTransferable::IsPasteOwnFormat( const TransferableDataHelper& rData )
+{
+ return ( GetSwTransferable( rData ) != nullptr );
+}
+
bool SwTransferable::PasteFormat( SwWrtShell& rSh,
TransferableDataHelper& rData,
SotClipboardFormatId nFormat )
@@ -3621,7 +3635,7 @@ bool lcl_checkClassification(SwDoc* pSourceDoc, SwDoc* pDestinationDoc)
}
-bool SwTransferable::PrivatePaste(SwWrtShell& rShell, SwPasteContext* pContext)
+bool SwTransferable::PrivatePaste(SwWrtShell& rShell, SwPasteContext* pContext, bool bNestedTable)
{
// first, ask for the SelectionType, then action-bracketing !!!!
// (otherwise it's not pasted into a TableSelection!!!)
@@ -3683,7 +3697,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(), bNestedTable);
if( bKillPaMs )
rShell.KillPams();
diff --git a/sw/source/uibase/inc/swdtflvr.hxx b/sw/source/uibase/inc/swdtflvr.hxx
index 680e808767b8..c63b1987afc4 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 bNestedTable = 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,10 +189,12 @@ 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 bNestedTable = false );
static bool IsPasteSpecial( const SwWrtShell& rWrtShell,
const TransferableDataHelper& );
+ static bool IsPasteOwnFormat( const TransferableDataHelper& );
static bool PasteUnformatted( SwWrtShell& rSh, TransferableDataHelper& );
/**
* @brief PrePasteSpecial Prepares the given dialog without actually running it
diff --git a/sw/source/uibase/shells/basesh.cxx b/sw/source/uibase/shells/basesh.cxx
index ff9598c84b37..c9e5a8ec15bf 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 bPasteNestedTable = false;
switch( nId )
{
case SID_CUT:
@@ -280,6 +281,9 @@ void SwBaseShell::ExecClpbrd(SfxRequest &rReq)
}
return;
+ case FN_PASTE_NESTED_TABLE:
+ bPasteNestedTable = true;
+ [[fallthrough]];
case SID_PASTE:
{
TransferableDataHelper aDataHelper(
@@ -299,7 +303,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);
+ SwTransferable::Paste(rSh, aDataHelper, nAnchorType, bIgnoreComments, bPasteNestedTable);
if( rSh.IsFrameSelected() || rSh.IsObjSelected() )
rSh.EnterSelFrameMode();
@@ -466,6 +470,17 @@ void SwBaseShell::StateClpbrd(SfxItemSet &rSet)
rSet.DisableItem( nWhich );
break;
+ case FN_PASTE_NESTED_TABLE:
+ if( !rSh.IsCursorInTable()
+ || !GetView().IsPasteSpecialAllowed()
+ || rSh.CursorInsideInputField()
+ // disable if not a native Writer table and not a spreadsheet format
+ || !GetView().IsPasteSpreadsheet(rSh.GetTableCopied()) )
+ {
+ rSet.DisableItem( nWhich );
+ }
+ break;
+
case SID_PASTE:
if( !GetView().IsPasteAllowed() )
{
diff --git a/sw/source/uibase/uiview/view.cxx b/sw/source/uibase/uiview/view.cxx
index 58c7d77349b3..25d394f1f364 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_PASTE_NESTED_TABLE,
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,
@@ -1848,6 +1848,20 @@ bool SwView::IsPasteSpecialAllowed()
return m_bPasteSpecialState;
}
+bool SwView::IsPasteSpreadsheet(bool bHasOwnTableCopied)
+{
+ TransferableDataHelper aDataHelper(
+ TransferableDataHelper::CreateFromSystemClipboard(
+ &GetEditWin()) );
+ if( aDataHelper.GetXTransferable().is() )
+ {
+ if (bHasOwnTableCopied && SwTransferable::IsPasteOwnFormat( aDataHelper ))
+ return true;
+ return aDataHelper.HasFormat( SotClipboardFormatId::SYLK ) || aDataHelper.HasFormat( SotClipboardFormatId::SYLK_BIGCAPS );
+ }
+ return false;
+}
+
void SwView::NotifyDBChanged()
{
GetViewImpl()->GetUNOObject_Impl()->NotifyDBChanged();
diff --git a/sw/uiconfig/swriter/menubar/menubar.xml b/sw/uiconfig/swriter/menubar/menubar.xml
index bd57b91564da..77e1ebae5f57 100644
--- a/sw/uiconfig/swriter/menubar/menubar.xml
+++ b/sw/uiconfig/swriter/menubar/menubar.xml
@@ -105,6 +105,7 @@
<menu:menupopup>
<menu:menuitem menu:id=".uno:PasteUnformatted"/>
<menu:menuitem menu:id=".uno:PasteSpecial"/>
+ <menu:menuitem menu:id=".uno:PasteNestedTable"/>
</menu:menupopup>
</menu:menu>
<menu:menuseparator/>
diff --git a/sw/uiconfig/swriter/popupmenu/table.xml b/sw/uiconfig/swriter/popupmenu/table.xml
index 09470cab6d34..4baf20af019d 100644
--- a/sw/uiconfig/swriter/popupmenu/table.xml
+++ b/sw/uiconfig/swriter/popupmenu/table.xml
@@ -13,6 +13,7 @@
<menu:menuitem menu:id=".uno:Paste"/>
<menu:menu menu:id=".uno:PasteSpecialMenu">
<menu:menupopup>
+ <menu:menuitem menu:id=".uno:PasteNestedTable"/>
<menu:menuitem menu:id=".uno:PasteUnformatted"/>
<menu:menuitem menu:id=".uno:PasteSpecial"/>
</menu:menupopup>