sd: add support for shuffling slides from canvas page
added .uno:ReshufflePages which when executed will re-order the pages based on the position of their previews on the canvas page. Sorting logic: 1. Sort the previews based on their y-center 2. Form a row if the y-centers are within a tolerance limit 3. Sort the row based on their x-center (also considering RTL locale) 4. Repeat for each rows Signed-off-by: Mohit Marathe <mohit.marathe@collabora.com> Change-Id: If654e0cc14686aed2ad6cd69f2dc81249924ee2c Reviewed-on: https://gerrit.libreoffice.org/c/core/+/192940 Reviewed-by: Michael Stahl <michael.stahl@collabora.com> Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice@gmail.com> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/196798 Tested-by: Jenkins
This commit is contained in:
committed by
Michael Stahl
parent
dd9b5ec78b
commit
b162ae4be3
@@ -2215,6 +2215,14 @@
|
||||
<value>1</value>
|
||||
</prop>
|
||||
</node>
|
||||
<node oor:name=".uno:ReshufflePages" oor:op="replace">
|
||||
<prop oor:name="Label" oor:type="xs:string">
|
||||
<value xml:lang="en-US">Re-order pages</value>
|
||||
</prop>
|
||||
<prop oor:name="Properties" oor:type="xs:int">
|
||||
<value>1</value>
|
||||
</prop>
|
||||
</node>
|
||||
<node oor:name=".uno:AssignLayout?WhatLayout:long=20" oor:op="replace">
|
||||
<prop oor:name="Label" oor:type="xs:string">
|
||||
<value xml:lang="en-US">Blank Slide</value>
|
||||
|
||||
@@ -347,6 +347,7 @@
|
||||
// FREE
|
||||
#define SID_INSERTPAGE_QUICK (SID_SD_START+352)
|
||||
#define SID_INSERT_CANVAS_SLIDE (SID_SD_START+353)
|
||||
#define SID_SHUFFLE_PAGES (SID_SD_START+354)
|
||||
// FREE
|
||||
#define SID_INSERT_FLD_PAGE_TITLE (SID_SD_START+356)
|
||||
#define SID_INSERT_FLD_DATE_VAR (SID_SD_START+357)
|
||||
|
||||
@@ -1069,6 +1069,10 @@ public:
|
||||
bool bUndo = true,
|
||||
const OUString& sNewName = OUString());
|
||||
|
||||
/** Re-order the pages based on the position of their previews on canvas page.
|
||||
*/
|
||||
void ReshufflePages();
|
||||
|
||||
private:
|
||||
|
||||
void UpdatePageRelativeURLsImpl(const std::function<void(const SvxFieldItem & rFieldItem, editeng::SvxFieldItemUpdater& rFieldItemUpdater)>& rItemCallback);
|
||||
|
||||
@@ -165,6 +165,11 @@ interface DrawView
|
||||
ExecMethod = FuTemporary ;
|
||||
StateMethod = GetMenuState ;
|
||||
]
|
||||
SID_SHUFFLE_PAGES
|
||||
[
|
||||
ExecMethod = FuTemporary ;
|
||||
StateMethod = GetMenuState ;
|
||||
]
|
||||
SID_HYPERLINK_SETLINK // ole : no, status : no
|
||||
[
|
||||
ExecMethod = FuTemporary ;
|
||||
|
||||
@@ -1690,6 +1690,23 @@ SfxVoidItem InsertCanvasSlide SID_INSERT_CANVAS_SLIDE
|
||||
GroupId = SfxGroupId::Insert;
|
||||
]
|
||||
|
||||
SfxVoidItem ReshufflePages SID_SHUFFLE_PAGES
|
||||
()
|
||||
[
|
||||
AutoUpdate = FALSE,
|
||||
FastCall = FALSE,
|
||||
ReadOnlyDoc = FALSE,
|
||||
Toggle = FALSE,
|
||||
Container = FALSE,
|
||||
RecordAbsolute = FALSE,
|
||||
RecordPerSet;
|
||||
|
||||
AccelConfig = TRUE,
|
||||
MenuConfig = TRUE,
|
||||
ToolBoxConfig = TRUE,
|
||||
GroupId = SfxGroupId::Modify;
|
||||
]
|
||||
|
||||
SfxVoidItem InsertPageField SID_INSERT_FLD_PAGE
|
||||
()
|
||||
[
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
#include <vcl/settings.hxx>
|
||||
|
||||
#include <sal/log.hxx>
|
||||
@@ -1470,6 +1471,79 @@ void SdDrawDocument::SetupNewPage (
|
||||
}
|
||||
}
|
||||
|
||||
void SdDrawDocument::ReshufflePages()
|
||||
{
|
||||
SdrObjList* pObjList = mpCanvasPage.get();
|
||||
std::vector<SdrPageObj*> aPageOrder;
|
||||
|
||||
SdrObjListIter aIter(pObjList, SdrIterMode::Flat);
|
||||
for (SdrObject* pObj = aIter.Next(); pObj; pObj = aIter.Next())
|
||||
{
|
||||
if (pObj->GetObjIdentifier() == SdrObjKind::Page)
|
||||
{
|
||||
SdrPageObj* pPageObj = static_cast<SdrPageObj*>(pObj);
|
||||
aPageOrder.push_back(pPageObj);
|
||||
}
|
||||
}
|
||||
|
||||
// Sort the previews by comparing their y-center (compare x-center as a tie-breaker)
|
||||
std::sort(aPageOrder.begin(), aPageOrder.end(),
|
||||
[](const SdrPageObj* pObj1, const SdrPageObj* pObj2) {
|
||||
const ::tools::Rectangle& rect1 = pObj1->GetSnapRect();
|
||||
const ::tools::Rectangle& rect2 = pObj2->GetSnapRect();
|
||||
const ::tools::Long yCenter1 = (rect1.Top() + rect1.Bottom()) / 2;
|
||||
const ::tools::Long yCenter2 = (rect2.Top() + rect2.Bottom()) / 2;
|
||||
|
||||
if (yCenter1 != yCenter2)
|
||||
return yCenter1 < yCenter2;
|
||||
|
||||
const ::tools::Long xCenter1 = (rect1.Left() + rect1.Right()) / 2;
|
||||
const ::tools::Long xCenter2 = (rect2.Left() + rect2.Right()) / 2;
|
||||
return xCenter1 < xCenter2;
|
||||
}
|
||||
);
|
||||
|
||||
const bool bIsRTL = AllSettings::GetLayoutRTL();
|
||||
|
||||
// Form a row, and sort them based on their x-center
|
||||
for (size_t rowStart = 0; rowStart < aPageOrder.size();)
|
||||
{
|
||||
const ::tools::Rectangle& rect0 = aPageOrder[rowStart]->GetSnapRect();
|
||||
const ::tools::Long top = rect0.Top();
|
||||
const ::tools::Long bottom = rect0.Bottom();
|
||||
|
||||
size_t rowEnd = rowStart;
|
||||
while (rowEnd < aPageOrder.size())
|
||||
{
|
||||
const ::tools::Rectangle& rect = aPageOrder[rowEnd]->GetSnapRect();
|
||||
const ::tools::Long yCenter = (rect.Top() + rect.Bottom()) / 2;
|
||||
|
||||
if (yCenter < top || yCenter > bottom)
|
||||
break;
|
||||
rowEnd++;
|
||||
}
|
||||
|
||||
std::stable_sort(aPageOrder.begin() + rowStart, aPageOrder.begin() + rowEnd,
|
||||
[&bIsRTL](const SdrPageObj* pObj1, const SdrPageObj* pObj2) {
|
||||
const ::tools::Rectangle& rect1 = pObj1->GetSnapRect();
|
||||
const ::tools::Rectangle& rect2 = pObj2->GetSnapRect();
|
||||
const ::tools::Long xCenter1 = (rect1.Left() + rect1.Right()) / 2;
|
||||
const ::tools::Long xCenter2 = (rect2.Left() + rect2.Right()) / 2;
|
||||
|
||||
return bIsRTL ? (xCenter1 > xCenter2) : (xCenter1 < xCenter2);
|
||||
});
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < aPageOrder.size(); i++)
|
||||
{
|
||||
SdPage* pPage = static_cast<SdPage*>(aPageOrder[i]->GetReferencedPage());
|
||||
sal_uInt16 nCurrentPageNum = pPage->GetPageNum();
|
||||
sal_uInt16 nTargetPageNum = 2 * i + 1;
|
||||
MovePage(nCurrentPageNum, nTargetPageNum); // Standard page
|
||||
MovePage(nCurrentPageNum + 1, nTargetPageNum + 1); // Notes page
|
||||
}
|
||||
}
|
||||
|
||||
sal_uInt16 SdDrawDocument::GetOrInsertCanvasPage()
|
||||
{
|
||||
if (HasCanvasPage())
|
||||
@@ -1478,7 +1552,10 @@ sal_uInt16 SdDrawDocument::GetOrInsertCanvasPage()
|
||||
sal_uInt16 nLastPageNum = GetSdPageCount(PageKind::Standard);
|
||||
SdPage* pLastStandardPage = GetSdPage(nLastPageNum - 1, PageKind::Standard);
|
||||
|
||||
sal_uInt16 nCanvasPageNum = CreatePage(pLastStandardPage, PageKind::Standard, u"Canvas Page"_ustr, u"Canvas notes page"_ustr, AutoLayout::AUTOLAYOUT_NONE, AutoLayout::AUTOLAYOUT_NONE, false, true, pLastStandardPage->GetPageNum() + 2);
|
||||
sal_uInt16 nCanvasPageNum = CreatePage(pLastStandardPage, PageKind::Standard,
|
||||
u"Canvas Page"_ustr, u"Canvas notes page"_ustr,
|
||||
AutoLayout::AUTOLAYOUT_NONE, AutoLayout::AUTOLAYOUT_NONE,
|
||||
false, true, pLastStandardPage->GetPageNum() + 2);
|
||||
|
||||
SdPage* pCanvasPage = GetSdPage(nCanvasPageNum, PageKind::Standard);
|
||||
if (!pCanvasPage)
|
||||
|
||||
@@ -1408,6 +1408,16 @@ void DrawViewShell::FuTemporary(SfxRequest& rReq)
|
||||
}
|
||||
break;
|
||||
|
||||
case SID_SHUFFLE_PAGES:
|
||||
{
|
||||
if (!GetDoc()->HasCanvasPage())
|
||||
break;
|
||||
GetDoc()->ReshufflePages();
|
||||
Cancel();
|
||||
rReq.Done();
|
||||
}
|
||||
break;
|
||||
|
||||
case SID_DUPLICATE_PAGE:
|
||||
{
|
||||
auto slideSorter = sd::slidesorter::SlideSorterViewShell::GetSlideSorter(GetViewShellBase());
|
||||
|
||||
Reference in New Issue
Block a user