[Libreoffice-commits] core.git: sw/inc sw/source

László Németh (via logerrit) logerrit at kemper.freedesktop.org
Tue Nov 5 08:53:16 UTC 2019


 sw/inc/crsrsh.hxx                    |    4 +
 sw/inc/fesh.hxx                      |    5 +
 sw/source/core/crsr/crsrsh.cxx       |    2 
 sw/source/core/crsr/trvltbl.cxx      |    2 
 sw/source/core/frmedt/fews.cxx       |    2 
 sw/source/uibase/dochdl/swdtflvr.cxx |   89 ++++++++++++++++++++++++++++++++++-
 sw/source/uibase/inc/wrtsh.hxx       |    6 +-
 sw/source/uibase/wrtsh/select.cxx    |    3 +
 sw/source/uibase/wrtsh/wrtsh1.cxx    |    7 ++
 9 files changed, 116 insertions(+), 4 deletions(-)

New commits:
commit 0c8b1efbad48fa9697c0b1afbe4753bbbc3c4c5c
Author:     László Németh <nemeth at numbertext.org>
AuthorDate: Fri Oct 25 15:02:26 2019 +0200
Commit:     László Németh <nemeth at numbertext.org>
CommitDate: Tue Nov 5 09:52:17 2019 +0100

    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 at numbertext.org>

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();


More information about the Libreoffice-commits mailing list