summaryrefslogtreecommitdiff
path: root/sw
diff options
context:
space:
mode:
authorJim Raykowski <raykowj@gmail.com>2019-06-03 17:45:34 -0800
committerJim Raykowski <raykowj@gmail.com>2019-07-11 21:33:36 +0200
commit7ae308e5cac31c64a6bf4892aac097dac3a054b7 (patch)
treedfa2586071de5c325dcc8850eff6137aa87679ab /sw
parentc39ccc08f40e15f3fd66bb1d2c5c0d7131dcce75 (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.hxx3
-rw-r--r--sw/source/uibase/utlui/content.cxx79
-rw-r--r--sw/source/uibase/utlui/navipi.cxx1
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();
}
}