diff options
author | Jim Raykowski <raykowj@gmail.com> | 2022-07-31 20:45:06 -0800 |
---|---|---|
committer | Jim Raykowski <raykowj@gmail.com> | 2022-08-01 16:31:22 +0200 |
commit | f181399656a0d4273c4cb0579bd0917448c54ddc (patch) | |
tree | b40d268b8c76a94a1f818b1ca34e274cf407ff0d | |
parent | 60f9ca81e84f1bede4928c6f680325692cc8bc49 (diff) |
tdf#116411 fix Navigate By Page Next does not move the expected next
page into view
Uses newly introduced GetFirstLastVisPageNumbers function which does
not include pages having only visible bottom or top margins. This
solves the issue of pages with bottom margin remnants in the view
causing Page Next to not move the expected page into view.
Change-Id: Iec05f132b39e1db92be5d13c7d4cc41072dddac0
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/132373
Tested-by: Jenkins
Reviewed-by: Jim Raykowski <raykowj@gmail.com>
-rw-r--r-- | sw/inc/viewsh.hxx | 10 | ||||
-rw-r--r-- | sw/source/core/inc/viewimp.hxx | 2 | ||||
-rw-r--r-- | sw/source/core/view/viewimp.cxx | 24 | ||||
-rw-r--r-- | sw/source/core/view/viewsh.cxx | 38 | ||||
-rw-r--r-- | sw/source/uibase/uiview/viewmdi.cxx | 26 |
5 files changed, 90 insertions, 10 deletions
diff --git a/sw/inc/viewsh.hxx b/sw/inc/viewsh.hxx index 54ad92ee5ae0..06cdc6ccfd2c 100644 --- a/sw/inc/viewsh.hxx +++ b/sw/inc/viewsh.hxx @@ -79,6 +79,14 @@ typedef std::shared_ptr<SwRootFrame> SwRootFramePtr; typedef struct _xmlTextWriter* xmlTextWriterPtr; +struct SwVisiblePageNumbers +{ + sal_uInt16 nFirstPhy, nLastPhy; + sal_uInt16 nFirstVirt, nLastVirt; + OUString sFirstCustomPhy, sLastCustomPhy; + OUString sFirstCustomVirt, sLastCustomVirt; +}; + class SW_DLLPUBLIC SwViewShell : public sw::Ring<SwViewShell> { friend void SetOutDev( SwViewShell *pSh, OutputDevice *pOut ); @@ -573,6 +581,8 @@ public: bool isOutputToWindow() const; void OnGraphicArrived(const SwRect&); + void GetFirstLastVisPageNumbers(SwVisiblePageNumbers& rVisiblePageNumbers); + virtual void dumpAsXml(xmlTextWriterPtr pWriter) const; }; diff --git a/sw/source/core/inc/viewimp.hxx b/sw/source/core/inc/viewimp.hxx index fdd0ed330592..1c0732917245 100644 --- a/sw/source/core/inc/viewimp.hxx +++ b/sw/source/core/inc/viewimp.hxx @@ -147,6 +147,8 @@ public: SwPageFrame *GetFirstVisPage(OutputDevice const * pRenderContext); void SetFirstVisPageInvalid() { m_bFirstPageInvalid = true; } + const SwPageFrame* GetLastVisPage(const OutputDevice* pRenderContext) const; + bool AddPaintRect( const SwRect &rRect ); bool HasPaintRegion() { return static_cast<bool>(m_pPaintRegion); } std::unique_ptr<SwRegionRects> TakePaintRegion() { return std::move(m_pPaintRegion); } diff --git a/sw/source/core/view/viewimp.cxx b/sw/source/core/view/viewimp.cxx index f44850d70f82..4fc1c8318f48 100644 --- a/sw/source/core/view/viewimp.cxx +++ b/sw/source/core/view/viewimp.cxx @@ -316,6 +316,30 @@ const SwPageFrame *SwViewShellImp::GetFirstVisPage(OutputDevice const * pRenderC return m_pFirstVisiblePage; } +const SwPageFrame* SwViewShellImp::GetLastVisPage(const OutputDevice* pRenderContext) const +{ + const SwViewOption* pSwViewOption = m_pShell->GetViewOptions(); + const bool bBookMode = pSwViewOption->IsViewLayoutBookMode(); + const SwPageFrame* pPage = GetFirstVisPage(pRenderContext); + const SwPageFrame* pLastVisPage = pPage; + SwRect aPageRect = pPage->GetBoundRect(pRenderContext); + while (pPage && (pPage->IsEmptyPage() || aPageRect.Overlaps(m_pShell->VisArea()))) + { + pLastVisPage = pPage; + pPage = static_cast<const SwPageFrame*>(pPage->GetNext()); + if (pPage) + { + aPageRect = pPage->GetBoundRect(pRenderContext); + if (bBookMode && pPage->IsEmptyPage()) + { + const SwPageFrame& rFormatPage = pPage->GetFormatPage(); + aPageRect.SSize(rFormatPage.GetBoundRect(pRenderContext).SSize()); + } + } + } + return pLastVisPage; +} + // create page preview layout void SwViewShellImp::InitPagePreviewLayout() { diff --git a/sw/source/core/view/viewsh.cxx b/sw/source/core/view/viewsh.cxx index ac49662e9854..ddc7ca386318 100644 --- a/sw/source/core/view/viewsh.cxx +++ b/sw/source/core/view/viewsh.cxx @@ -2771,6 +2771,44 @@ SwPostItMgr* SwViewShell::GetPostItMgr() return nullptr; } +void SwViewShell::GetFirstLastVisPageNumbers(SwVisiblePageNumbers& rVisiblePageNumbers) +{ + SwView* pView = GetDoc()->GetDocShell() ? GetDoc()->GetDocShell()->GetView() : nullptr; + if (!pView) + return; + SwRect rViewVisArea(pView->GetVisArea()); + vcl::RenderContext* pRenderContext = GetOut(); + const SwPageFrame* pPageFrame = Imp()->GetFirstVisPage(pRenderContext); + SwRect rPageRect = pPageFrame->getFrameArea(); + rPageRect.AddBottom(-pPageFrame->GetBottomMargin()); + while (!rPageRect.Overlaps(rViewVisArea) && pPageFrame->GetNext()) + { + pPageFrame = static_cast<const SwPageFrame*>(pPageFrame->GetNext()); + rPageRect = pPageFrame->getFrameArea(); + if (rPageRect.Top() > 0) + rPageRect.AddBottom(-pPageFrame->GetBottomMargin()); + } + rVisiblePageNumbers.nFirstPhy = pPageFrame->GetPhyPageNum(); + rVisiblePageNumbers.nFirstVirt = pPageFrame->GetVirtPageNum(); + const SvxNumberType& rFirstVisNum = pPageFrame->GetPageDesc()->GetNumType(); + rVisiblePageNumbers.sFirstCustomPhy = rFirstVisNum.GetNumStr(rVisiblePageNumbers.nFirstPhy); + rVisiblePageNumbers.sFirstCustomVirt = rFirstVisNum.GetNumStr(rVisiblePageNumbers.nFirstVirt); + pPageFrame = Imp()->GetLastVisPage(pRenderContext); + rPageRect = pPageFrame->getFrameArea(); + rPageRect.AddTop(pPageFrame->GetTopMargin()); + while (!rPageRect.Overlaps(rViewVisArea) && pPageFrame->GetPrev()) + { + pPageFrame = static_cast<const SwPageFrame*>(pPageFrame->GetPrev()); + rPageRect = pPageFrame->getFrameArea(); + rPageRect.AddTop(pPageFrame->GetTopMargin()); + } + rVisiblePageNumbers.nLastPhy = pPageFrame->GetPhyPageNum(); + rVisiblePageNumbers.nLastVirt = pPageFrame->GetVirtPageNum(); + const SvxNumberType& rLastVisNum = pPageFrame->GetPageDesc()->GetNumType(); + rVisiblePageNumbers.sLastCustomPhy = rLastVisNum.GetNumStr(rVisiblePageNumbers.nLastPhy); + rVisiblePageNumbers.sLastCustomVirt = rLastVisNum.GetNumStr(rVisiblePageNumbers.nLastVirt); +} + /* * Document Interface Access */ diff --git a/sw/source/uibase/uiview/viewmdi.cxx b/sw/source/uibase/uiview/viewmdi.cxx index abbc7438700a..fee7f5ce5d91 100644 --- a/sw/source/uibase/uiview/viewmdi.cxx +++ b/sw/source/uibase/uiview/viewmdi.cxx @@ -347,24 +347,30 @@ IMPL_LINK( SwView, MoveNavigationHdl, void*, p, void ) { case NID_PGE: { - if (USHRT_MAX == rSh.GetNextPrevPageNum(bNext)) + tools::Long nYPos; + SwVisiblePageNumbers aVisiblePageNumbers; + rSh.GetFirstLastVisPageNumbers(aVisiblePageNumbers); + if ((bNext && aVisiblePageNumbers.nLastPhy + 1 > rSh.GetPageCnt()) || + (!bNext && aVisiblePageNumbers.nFirstPhy == 1)) { - const Point aPt(GetVisArea().Left(), - rSh.GetPagePos(bNext ? 1 : rSh.GetPageCnt()).Y()); - Point aAlPt(AlignToPixel(aPt) ); - // If there is a difference, has been truncated --> then add one pixel, - // so that no residue of the previous page is visible. - if(aPt.Y() != aAlPt.Y()) - aAlPt.AdjustY(3 * GetEditWin().PixelToLogic(Size(0, 1)).Height()); - SetVisArea(aAlPt); + nYPos = rSh.GetPagePos(bNext ? 1 : rSh.GetPageCnt()).Y(); SvxSearchDialogWrapper::SetSearchLabel(bNext ? SearchLabel::EndWrapped : SearchLabel::StartWrapped); } else { - bNext ? PhyPageDown() : PhyPageUp(); + auto nPage = bNext ? aVisiblePageNumbers.nLastPhy + 1 : + aVisiblePageNumbers.nFirstPhy - 1; + nYPos = rSh.GetPagePos(nPage).Y(); SvxSearchDialogWrapper::SetSearchLabel(SearchLabel::Empty); } + const Point aPt(GetVisArea().Left(), nYPos); + Point aAlPt(AlignToPixel(aPt)); + // If there is a difference, has been truncated --> then add one pixel, + // so that no residue of the previous page is visible. + if(aPt.Y() != aAlPt.Y()) + aAlPt.AdjustY(3 * GetEditWin().PixelToLogic(Size(0, 1)).Height()); + SetVisArea(aAlPt); } break; case NID_TBL : |