diff options
author | Jim Raykowski <raykowj@gmail.com> | 2019-06-03 17:45:34 -0800 |
---|---|---|
committer | Jim Raykowski <raykowj@gmail.com> | 2019-07-11 21:33:36 +0200 |
commit | 7ae308e5cac31c64a6bf4892aac097dac3a054b7 (patch) | |
tree | dfa2586071de5c325dcc8850eff6137aa87679ab /sw | |
parent | c39ccc08f40e15f3fd66bb1d2c5c0d7131dcce75 (diff) |
tdf#123088 Multi outline drag and drop
This enhancement adds drag and drop movement for outline continous
sibling selections in writer navigator.
Change-Id: I0bbed35ceeeb8101b2b73d5c906edb5edd959a22
Reviewed-on: https://gerrit.libreoffice.org/73426
Tested-by: Jenkins
Reviewed-by: Jim Raykowski <raykowj@gmail.com>
Diffstat (limited to 'sw')
-rw-r--r-- | sw/source/uibase/inc/conttree.hxx | 3 | ||||
-rw-r--r-- | sw/source/uibase/utlui/content.cxx | 79 | ||||
-rw-r--r-- | sw/source/uibase/utlui/navipi.cxx | 1 |
3 files changed, 79 insertions, 4 deletions
diff --git a/sw/source/uibase/inc/conttree.hxx b/sw/source/uibase/inc/conttree.hxx index 2d8354607dca..8a6793a2b5ab 100644 --- a/sw/source/uibase/inc/conttree.hxx +++ b/sw/source/uibase/inc/conttree.hxx @@ -116,6 +116,9 @@ class SwContentTree final bool m_bIsKeySpace; tools::Rectangle m_aOldRectangle; + // outline root mode drag & drop + std::vector< SvTreeListEntry* > m_aDndOutlinesSelected; + /** * Before any data will be deleted, the last active entry has to be found. * After this the UserData will be deleted diff --git a/sw/source/uibase/utlui/content.cxx b/sw/source/uibase/utlui/content.cxx index 1549f6e60ff1..8eab31e8bb64 100644 --- a/sw/source/uibase/utlui/content.cxx +++ b/sw/source/uibase/utlui/content.cxx @@ -1099,11 +1099,41 @@ void SwContentTree::StartDrag( sal_Int8 nAction, const Point& rPosPixel ) } } else + { + SwWrtShell *const pShell = GetWrtShell(); + pShell->StartAllAction(); + pShell->StartUndo(SwUndoId::OUTLINE_UD); + // Only move drag entry and continuous selected siblings: + m_aDndOutlinesSelected.clear(); + SvTreeListEntry* pEntry = GetEntry(rPosPixel); + // Find first selected of continous siblings + while (pEntry && IsSelected(pEntry->PrevSibling())) + { + pEntry = pEntry->PrevSibling(); + } + // Record continous selected siblings + if (pEntry) + { + m_aDndOutlinesSelected.push_back(pEntry); + while (pEntry && IsSelected(pEntry->NextSibling())) + { + pEntry = pEntry->NextSibling(); + m_aDndOutlinesSelected.push_back(pEntry); + } + } SvTreeListBox::StartDrag( nAction, rPosPixel ); + } } void SwContentTree::DragFinished( sal_Int8 nAction ) { + SwWrtShell *const pShell = GetWrtShell(); + pShell->EndUndo(); + pShell->EndAllAction(); + m_aActiveContentArr[ContentTypeId::OUTLINE]->Invalidate(); + Display(true); + m_aDndOutlinesSelected.clear(); + // To prevent the removing of the selected entry in external drag and drop // the drag action mustn't be MOVE. SvTreeListBox::DragFinished( m_bIsInternalDrag ? nAction : DND_ACTION_COPY ); @@ -2740,7 +2770,15 @@ DragDropMode SwContentTree::NotifyStartDrag( if (State::ACTIVE == m_eState && m_nRootType == ContentTypeId::OUTLINE && GetModel()->GetAbsPos( pEntry ) > 0 && !GetWrtShell()->GetView().GetDocShell()->IsReadOnly()) + { eMode = GetDragDropMode(); + if (m_bIsRoot) + { + // Restore selection for multiple selected outlines. + for (const auto pSelected : m_aDndOutlinesSelected) + SelectListEntry(pSelected, true); + } + } else if (State::ACTIVE != m_eState && GetWrtShell()->GetView().GetDocShell()->HasName()) eMode = DragDropMode::APP_COPY; @@ -2755,6 +2793,8 @@ DragDropMode SwContentTree::NotifyStartDrag( TriState SwContentTree::NotifyMoving( SvTreeListEntry* pTarget, SvTreeListEntry* pEntry, SvTreeListEntry*& , sal_uLong& ) { + static SwOutlineNodes::size_type nStaticSourcePos = SwOutlineNodes::npos; + static SwOutlineNodes::size_type nStaticTargetPosOrOffset = SwOutlineNodes::npos; if(!m_bDocChgdInDragging) { SwOutlineNodes::size_type nTargetPos = 0; @@ -2782,12 +2822,45 @@ TriState SwContentTree::NotifyMoving( SvTreeListEntry* pTarget, OSL_ENSURE( pEntry && lcl_IsContent(pEntry),"Source == 0 or Source has no Content" ); + + if (nStaticTargetPosOrOffset != SwOutlineNodes::npos) + { + if (nTargetPos == SwOutlineNodes::npos || nSourcePos > nTargetPos) + { + // Move up + nTargetPos = nSourcePos - nStaticTargetPosOrOffset; + } + else if (nSourcePos < nTargetPos) + { + // Move down + nSourcePos = nStaticSourcePos; + nTargetPos = nStaticTargetPosOrOffset; + } + } + // Done on the first selection move + if (nTargetPos == SwOutlineNodes::npos || (nStaticTargetPosOrOffset == SwOutlineNodes::npos && nSourcePos > nTargetPos)) // only do once + { + // Up moves + // The first up move sets the up move amount for the remaining selected outlines to be moved + if (nTargetPos != SwOutlineNodes::npos) + nStaticTargetPosOrOffset = nSourcePos - nTargetPos; + else + nStaticTargetPosOrOffset = nSourcePos + 1; + } + else if (nStaticTargetPosOrOffset == SwOutlineNodes::npos && nSourcePos < nTargetPos) + { + // Down moves + // The first down move sets the source and target positions for the remaining selected outlines to be moved + nStaticSourcePos = nSourcePos; + nStaticTargetPosOrOffset = nTargetPos; + } + // Done on the last selection move + if (!IsSelected(pEntry->NextSibling())) + nStaticTargetPosOrOffset = SwOutlineNodes::npos; + GetParentWindow()->MoveOutline( nSourcePos, nTargetPos, true); - - m_aActiveContentArr[ContentTypeId::OUTLINE]->Invalidate(); - Display(true); } //TreeListBox will be reloaded from the document return TRISTATE_FALSE; diff --git a/sw/source/uibase/utlui/navipi.cxx b/sw/source/uibase/utlui/navipi.cxx index d3d1d96445c2..1eedb04e9c86 100644 --- a/sw/source/uibase/utlui/navipi.cxx +++ b/sw/source/uibase/utlui/navipi.cxx @@ -124,7 +124,6 @@ void SwNavigationPI::MoveOutline(SwOutlineNodes::size_type nSource, SwOutlineNod rSh.MoveOutlinePara( nMove ); rSh.ClearMark(); rSh.GotoOutline( nSource + nMove); - FillBox(); } } |