summaryrefslogtreecommitdiff
path: root/sw
diff options
context:
space:
mode:
authorLászló Németh <nemeth@numbertext.org>2019-10-25 15:02:26 +0200
committerLászló Németh <nemeth@numbertext.org>2019-11-05 09:52:17 +0100
commit0c8b1efbad48fa9697c0b1afbe4753bbbc3c4c5c (patch)
treead993d5bdff4265a18ab8a9c4106a1b1091646dd /sw
parent966227d9d1e6301f3c39c135d966e433f0c83771 (diff)
tdf#127759 Writer: add table row/column insert mode
using enhanced table selection. When the table rows or columns are selected by enhanced table selection, ie. clicking in front of them, next Cut operation cuts the selected rows or columns completely without leaving empty cells. Pasting them results insertion before the actual row/column instead of overwriting the actual and the next rows/columns. This greatly speeds up moving table rows and columns, like in MSO. Change-Id: I6d82ca8aad4888ab37bdb9a89d37102763fcd6c6 Reviewed-on: https://gerrit.libreoffice.org/81503 Tested-by: Jenkins Reviewed-by: László Németh <nemeth@numbertext.org>
Diffstat (limited to 'sw')
-rw-r--r--sw/inc/crsrsh.hxx4
-rw-r--r--sw/inc/fesh.hxx5
-rw-r--r--sw/source/core/crsr/crsrsh.cxx2
-rw-r--r--sw/source/core/crsr/trvltbl.cxx2
-rw-r--r--sw/source/core/frmedt/fews.cxx2
-rw-r--r--sw/source/uibase/dochdl/swdtflvr.cxx89
-rw-r--r--sw/source/uibase/inc/wrtsh.hxx6
-rw-r--r--sw/source/uibase/wrtsh/select.cxx3
-rw-r--r--sw/source/uibase/wrtsh/wrtsh1.cxx7
9 files changed, 116 insertions, 4 deletions
diff --git a/sw/inc/crsrsh.hxx b/sw/inc/crsrsh.hxx
index 0cb7ded8a2f5..23b3753dd938 100644
--- a/sw/inc/crsrsh.hxx
+++ b/sw/inc/crsrsh.hxx
@@ -203,6 +203,7 @@ private:
*/
sal_uInt16 m_nCursorMove;
CursorMoveState m_eMvState; ///< Status for Cursor-Travelling - GetCursorOfst
+ SwTable::SearchType m_eEnhancedTableSel; /// table rows or columns selected by not cell by cell
OUString m_sMarkedListId;
int m_nMarkedListLevel;
@@ -802,6 +803,9 @@ public:
void SetSelTableCells( bool bFlag ) { m_bSelTableCells = bFlag; }
bool IsSelTableCells() const { return m_bSelTableCells; }
+ void UnsetEnhancedTableSelection() { m_eEnhancedTableSel = SwTable::SEARCH_NONE; }
+ SwTable::SearchType GetEnhancedTableSelection() const { return m_eEnhancedTableSel; }
+
bool IsAutoUpdateCells() const { return m_bAutoUpdateCells; }
void SetAutoUpdateCells( bool bFlag ) { m_bAutoUpdateCells = bFlag; }
diff --git a/sw/inc/fesh.hxx b/sw/inc/fesh.hxx
index 49d168233ebe..f60f92cff44e 100644
--- a/sw/inc/fesh.hxx
+++ b/sw/inc/fesh.hxx
@@ -639,6 +639,11 @@ public:
void DeleteTable();
bool DeleteRow(bool bCompleteTable = false);
+ /// insert table rows or columns instead of overwriting the existing table cells
+ SwTable::SearchType m_eTableInsertMode;
+ SwTable::SearchType GetTableInsertMode() const { return m_eTableInsertMode; }
+ void SetTableInsertMode( SwTable::SearchType eFlag ) { m_eTableInsertMode = eFlag; }
+
bool DeleteTableSel(); ///< Current selection, may be whole table.
TableMergeErr MergeTab(); /**< Merge selected parts of table */
diff --git a/sw/source/core/crsr/crsrsh.cxx b/sw/source/core/crsr/crsrsh.cxx
index 99df80520850..f37345368f39 100644
--- a/sw/source/core/crsr/crsrsh.cxx
+++ b/sw/source/core/crsr/crsrsh.cxx
@@ -2907,6 +2907,7 @@ SwCursorShell::SwCursorShell( SwCursorShell& rShell, vcl::Window *pInitWin )
, m_nCurrentNdTyp(SwNodeType::NONE)
, m_nCursorMove( 0 )
, m_eMvState( MV_NONE )
+ , m_eEnhancedTableSel(SwTable::SEARCH_NONE)
, m_sMarkedListId()
, m_nMarkedListLevel( 0 )
, m_oldColFrame(nullptr)
@@ -2943,6 +2944,7 @@ SwCursorShell::SwCursorShell( SwDoc& rDoc, vcl::Window *pInitWin,
, m_nCurrentNdTyp(SwNodeType::NONE)
, m_nCursorMove( 0 )
, m_eMvState( MV_NONE ) // state for crsr-travelling - GetCursorOfst
+ , m_eEnhancedTableSel(SwTable::SEARCH_NONE)
, m_sMarkedListId()
, m_nMarkedListLevel( 0 )
, m_oldColFrame(nullptr)
diff --git a/sw/source/core/crsr/trvltbl.cxx b/sw/source/core/crsr/trvltbl.cxx
index 71f6cc74c1d3..cdee8e9c54d4 100644
--- a/sw/source/core/crsr/trvltbl.cxx
+++ b/sw/source/core/crsr/trvltbl.cxx
@@ -168,6 +168,8 @@ bool SwCursorShell::SelTableRowOrCol( bool bRow, bool bRowSimple )
pStt = aBoxes[0];
pEnd = aBoxes.back();
+
+ m_eEnhancedTableSel = eSearchType;
}
else
{
diff --git a/sw/source/core/frmedt/fews.cxx b/sw/source/core/frmedt/fews.cxx
index 6134d0f73f45..3c0c7d5279a2 100644
--- a/sw/source/core/frmedt/fews.cxx
+++ b/sw/source/core/frmedt/fews.cxx
@@ -707,6 +707,7 @@ SwFEShell::SwFEShell( SwDoc& rDoc, vcl::Window *pWindow, const SwViewOption *pOp
: SwEditShell( rDoc, pWindow, pOptions )
, m_bCheckForOLEInCaption(false)
, m_aPasteListeners(GetPasteMutex())
+ , m_eTableInsertMode(SwTable::SEARCH_NONE)
{
}
@@ -714,6 +715,7 @@ SwFEShell::SwFEShell( SwEditShell& rShell, vcl::Window *pWindow )
: SwEditShell( rShell, pWindow )
, m_bCheckForOLEInCaption(false)
, m_aPasteListeners(GetPasteMutex())
+ , m_eTableInsertMode(SwTable::SEARCH_NONE)
{
}
diff --git a/sw/source/uibase/dochdl/swdtflvr.cxx b/sw/source/uibase/dochdl/swdtflvr.cxx
index 6484855b5555..155efd32296b 100644
--- a/sw/source/uibase/dochdl/swdtflvr.cxx
+++ b/sw/source/uibase/dochdl/swdtflvr.cxx
@@ -852,9 +852,21 @@ void SwTransferable::DeleteSelection()
return;
// ask for type of selection before action-bracketing
const SelectionType nSelection = m_pWrtShell->GetSelectionType();
+ // cut rows or columns selected by enhanced table selection and wholly selected tables
+ bool bCutMode = ( SelectionType::TableCell & nSelection ) && ( (SelectionType::TableRow | SelectionType::TableCol) & nSelection ||
+ m_pWrtShell->HasWholeTabSelection() );
+
m_pWrtShell->StartUndo( SwUndoId::START );
- if( ( SelectionType::TableCell & nSelection ) && m_pWrtShell->HasWholeTabSelection() )
- m_pWrtShell->DeleteTable();
+ if( bCutMode )
+ {
+ if( !(SelectionType::TableCol & nSelection) )
+ m_pWrtShell->DeleteTable();
+ else
+ {
+ SfxDispatcher* pDispatch = m_pWrtShell->GetView().GetViewFrame()->GetDispatcher();
+ pDispatch->Execute(FN_TABLE_DELETE_COL, SfxCallMode::SYNCHRON);
+ }
+ }
else
{
if( ( SelectionType::Text | SelectionType::Table ) & nSelection )
@@ -870,6 +882,9 @@ int SwTransferable::PrepareForCopy( bool bIsCut )
if(!m_pWrtShell)
return 0;
+ if ( m_pWrtShell->GetTableInsertMode() != SwTable::SEARCH_NONE )
+ m_pWrtShell->SetTableInsertMode( SwTable::SEARCH_NONE );
+
OUString sGrfNm;
const SelectionType nSelection = m_pWrtShell->GetSelectionType();
if( nSelection == SelectionType::Graphic )
@@ -1001,6 +1016,9 @@ int SwTransferable::PrepareForCopy( bool bIsCut )
{
m_eBufferType = TransferBufferType::Table | m_eBufferType;
bDDELink = m_pWrtShell->HasWholeTabSelection();
+
+ if ( bIsCut && (SelectionType::TableRow | SelectionType::TableCol) & nSelection )
+ m_pWrtShell->SetTableInsertMode( (SelectionType::TableRow & nSelection) ? SwTable::SEARCH_ROW : SwTable::SEARCH_COL );
}
#if HAVE_FEATURE_DESKTOP
@@ -1421,6 +1439,73 @@ 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 &&
+ rData.HasFormat( SotClipboardFormatId::HTML ) &&
+ rSh.GetDoc()->IsIdxInTable(rSh.GetCursor()->GetNode()) != nullptr )
+ {
+ OUString aExpand;
+ sal_Int32 nIdx;
+ bool bRowMode = rSh.GetTableInsertMode() == SwTable::SEARCH_ROW;
+ if( rData.GetString( SotClipboardFormatId::HTML, aExpand ) && (nIdx = aExpand.indexOf("<table")) > -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' ))
+ ++nSelectedRowsOrCols;
+ ++nIdx;
+ }
+ // are we at the beginning of the cell?
+ bool bStartTableBoxNode =
+ // first paragraph of the cell?
+ rSh.GetCursor()->GetNode().GetIndex() == rSh.GetCursor()->GetNode().FindTableBoxStartNode()->GetIndex()+1 &&
+ // beginning of the paragraph?
+ !rSh.GetCursor()->GetPoint()->nContent.GetIndex();
+ SfxDispatcher* pDispatch = rSh.GetView().GetViewFrame()->GetDispatcher();
+
+ // go start of the cell
+ if (!bStartTableBoxNode)
+ pDispatch->Execute(FN_START_OF_DOCUMENT, SfxCallMode::SYNCHRON);
+
+ // store cursor position in row mode
+ ::sw::mark::IMark* pMark = !bRowMode ? nullptr : rSh.SetBookmark(
+ vcl::KeyCode(),
+ OUString(),
+ IDocumentMarkAccess::MarkType::UNO_BOOKMARK );
+
+ // add a new empty row/column before the actual table row/column and go there
+ const sal_uInt16 nDispatchSlot = bRowMode ? FN_TABLE_INSERT_ROW_BEFORE : FN_TABLE_INSERT_COL_BEFORE;
+ pDispatch->Execute(nDispatchSlot, SfxCallMode::SYNCHRON);
+ pDispatch->Execute(bRowMode ? FN_LINE_UP : FN_CHAR_LEFT, SfxCallMode::SYNCHRON);
+
+ // add the other new empty rows/columns after the actual table row/column
+ if ( nSelectedRowsOrCols > 1 )
+ {
+ SfxUInt16Item aCountItem( nDispatchSlot, nSelectedRowsOrCols-1 );
+ SfxBoolItem aAfter( FN_PARAM_INSERT_AFTER, true );
+ pDispatch->ExecuteList(nDispatchSlot,
+ SfxCallMode::SYNCHRON|SfxCallMode::RECORD,
+ { &aCountItem, &aAfter });
+ }
+
+ // paste rows
+ bool bResult = SwTransferable::PasteData( rData, rSh, nAction, nActionFlags, nFormat,
+ nDestination, false, false, nullptr, 0, false, nAnchorType, bIgnoreComments, &aPasteContext );
+
+ // restore cursor position
+ if (pMark != nullptr)
+ {
+ rSh.GotoMark( pMark );
+ rSh.getIDocumentMarkAccess()->deleteMark( pMark );
+ }
+
+ return bResult;
+ }
+ }
// special case for tables from draw application or 1-cell tables
if( EXCHG_OUT_ACTION_INSERT_DRAWOBJ == nAction || bSingleCellTable )
diff --git a/sw/source/uibase/inc/wrtsh.hxx b/sw/source/uibase/inc/wrtsh.hxx
index 37601b232577..6ec17d5b0e78 100644
--- a/sw/source/uibase/inc/wrtsh.hxx
+++ b/sw/source/uibase/inc/wrtsh.hxx
@@ -74,10 +74,12 @@ enum class SelectionType : sal_Int32
ExtrudedCustomShape = 0x008000, // extruded custom shape
FontWork = 0x010000, // fontwork
PostIt = 0x020000, // annotation
- All = 0x03fff3,
+ TableRow = 0x040000, // table rows are selected
+ TableCol = 0x080000, // table columns are selected
+ All = 0x0ffff3,
};
namespace o3tl {
- template<> struct typed_flags<SelectionType> : is_typed_flags<SelectionType, 0x03fff3> {};
+ template<> struct typed_flags<SelectionType> : is_typed_flags<SelectionType, 0x0ffff3> {};
}
/** Used by the UI to modify the document model.
diff --git a/sw/source/uibase/wrtsh/select.cxx b/sw/source/uibase/wrtsh/select.cxx
index ae439faeee2a..e06f3dc69777 100644
--- a/sw/source/uibase/wrtsh/select.cxx
+++ b/sw/source/uibase/wrtsh/select.cxx
@@ -359,6 +359,9 @@ long SwWrtShell::ResetSelect(const Point *,bool)
// After canceling of all selections an update of Attr-Controls
// could be necessary.
GetChgLnk().Call(nullptr);
+
+ if ( GetEnhancedTableSelection() != SwTable::SEARCH_NONE )
+ UnsetEnhancedTableSelection();
}
Invalidate();
SwTransferable::ClearSelection( *this );
diff --git a/sw/source/uibase/wrtsh/wrtsh1.cxx b/sw/source/uibase/wrtsh/wrtsh1.cxx
index 1f06646b94a6..9eb00d361b9a 100644
--- a/sw/source/uibase/wrtsh/wrtsh1.cxx
+++ b/sw/source/uibase/wrtsh/wrtsh1.cxx
@@ -1463,7 +1463,14 @@ SelectionType SwWrtShell::GetSelectionType() const
nCnt |= SelectionType::Table;
if ( IsTableMode() )
+ {
nCnt |= SelectionType::Table | SelectionType::TableCell;
+ SwTable::SearchType eTableSel = GetEnhancedTableSelection();
+ if ( eTableSel == SwTable::SEARCH_ROW )
+ nCnt |= SelectionType::TableRow;
+ else if ( eTableSel == SwTable::SEARCH_COL )
+ nCnt |= SelectionType::TableCol;
+ }
// Do not pop up numbering toolbar, if the text node has a numbering of type SVX_NUM_NUMBER_NONE.
const SwNumRule* pNumRule = GetNumRuleAtCurrCursorPos();