diff options
author | Dennis Francis <dennis.francis@collabora.com> | 2020-06-02 12:12:39 +0530 |
---|---|---|
committer | Dennis Francis <dennis.francis@collabora.com> | 2020-07-07 07:47:26 +0200 |
commit | 6d8adb11ea91ca65f6f0e57e1365b326616c34f8 (patch) | |
tree | 870ac6912bcc5f1ec34b8186bcddccf71a56de72 /editeng | |
parent | 2f72fa980c2c81248c32d3b95598c23aba6ac6ed (diff) |
Introduce LOK 'special positioning' methods to EditView
This is meant for Calc. In Calc, all positions in twips are computed by
doing independent pixel-alignment for each cell's size. To allow
print-twips coordinates in LOK messages specific to EditView, this patch
introduces new methods to set/update both 'output-area' and
'visible-doc-position' in print twips coordinates, which are stored
separately.
Change-Id: Id165966c970fa26c79d583f435dccd62c7eb1f0c
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/98120
Tested-by: Jenkins
Reviewed-by: Dennis Francis <dennis.francis@collabora.com>
Diffstat (limited to 'editeng')
-rw-r--r-- | editeng/source/editeng/editview.cxx | 32 | ||||
-rw-r--r-- | editeng/source/editeng/impedit.cxx | 146 | ||||
-rw-r--r-- | editeng/source/editeng/impedit.hxx | 48 |
3 files changed, 226 insertions, 0 deletions
diff --git a/editeng/source/editeng/editview.cxx b/editeng/source/editeng/editview.cxx index 3ea3ac45f5c1..4a8b6873946d 100644 --- a/editeng/source/editeng/editview.cxx +++ b/editeng/source/editeng/editview.cxx @@ -1570,4 +1570,36 @@ void EditView::DrawSelectionXOR(OutlinerViewShell* pOtherShell) pImpEditView->RegisterOtherShell(nullptr); } +void EditView::InitLOKSpecialPositioning(MapUnit eUnit, + const tools::Rectangle& rOutputArea, + const Point& rVisDocStartPos) +{ + pImpEditView->InitLOKSpecialPositioning(eUnit, rOutputArea, rVisDocStartPos); +} + +void EditView::SetLOKSpecialOutputArea(const tools::Rectangle& rOutputArea) +{ + pImpEditView->SetLOKSpecialOutputArea(rOutputArea); +} + +tools::Rectangle EditView::GetLOKSpecialOutputArea() const +{ + return pImpEditView->GetLOKSpecialOutputArea(); +} + +void EditView::SetLOKSpecialVisArea(const tools::Rectangle& rVisArea) +{ + pImpEditView->SetLOKSpecialVisArea(rVisArea); +} + +tools::Rectangle EditView::GetLOKSpecialVisArea() const +{ + return pImpEditView->GetLOKSpecialVisArea(); +} + +bool EditView::HasLOKSpecialPositioning() const +{ + return pImpEditView->HasLOKSpecialPositioning(); +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/editeng/source/editeng/impedit.cxx b/editeng/source/editeng/impedit.cxx index 6aa35ce94eee..8da3740ba6cf 100644 --- a/editeng/source/editeng/impedit.cxx +++ b/editeng/source/editeng/impedit.cxx @@ -60,6 +60,113 @@ static void lcl_AllignToPixel( Point& rPoint, OutputDevice const * pOutDev, shor rPoint = pOutDev->PixelToLogic( rPoint ); } +LOKSpecialPositioning::LOKSpecialPositioning(const ImpEditView& rImpEditView, MapUnit eUnit, + const tools::Rectangle& rOutputArea, + const Point& rVisDocStartPos) : + mrImpEditView(rImpEditView), + maOutArea(rOutputArea), + maVisDocStartPos(rVisDocStartPos), + meUnit(eUnit) +{ +} + +void LOKSpecialPositioning::ReInit(MapUnit eUnit, const tools::Rectangle& rOutputArea, const Point& rVisDocStartPos) +{ + meUnit = eUnit; + maOutArea = rOutputArea; + maVisDocStartPos = rVisDocStartPos; +} + +void LOKSpecialPositioning::SetOutputArea(const tools::Rectangle& rOutputArea) +{ + maOutArea = rOutputArea; +} + +const tools::Rectangle& LOKSpecialPositioning::GetOutputArea() const +{ + return maOutArea; +} + +void LOKSpecialPositioning::SetVisDocStartPos(const Point& rVisDocStartPos) +{ + maVisDocStartPos = rVisDocStartPos; +} + +tools::Rectangle LOKSpecialPositioning::GetVisDocArea() const +{ + return tools::Rectangle(GetVisDocLeft(), GetVisDocTop(), GetVisDocRight(), GetVisDocBottom()); +} + +bool LOKSpecialPositioning::IsVertical() const +{ + return mrImpEditView.IsVertical(); +} + +bool LOKSpecialPositioning::IsTopToBottom() const +{ + return mrImpEditView.IsTopToBottom(); +} + +Point LOKSpecialPositioning::GetWindowPos(const Point& rDocPos, MapUnit eDocPosUnit) const +{ + const Point aDocPos = convertUnit(rDocPos, eDocPosUnit); + Point aPoint; + if ( !IsVertical() ) + { + aPoint.setX(aDocPos.X() + maOutArea.Left() - GetVisDocLeft()); + aPoint.setY(aDocPos.Y() + maOutArea.Top() - GetVisDocTop()); + } + else + { + if (IsTopToBottom()) + { + aPoint.setX(maOutArea.Right() - aDocPos.Y() + GetVisDocTop()); + aPoint.setY(aDocPos.X() + maOutArea.Top() - GetVisDocLeft()); + } + else + { + aPoint.setX(maOutArea.Left() + aDocPos.Y() - GetVisDocTop()); + aPoint.setY(maOutArea.Bottom() - aDocPos.X() + GetVisDocLeft()); + } + } + + return aPoint; +} + +tools::Rectangle LOKSpecialPositioning::GetWindowPos(const tools::Rectangle& rDocRect, MapUnit eDocRectUnit) const +{ + const tools::Rectangle aDocRect = convertUnit(rDocRect, eDocRectUnit); + Point aPos(GetWindowPos(aDocRect.TopLeft(), meUnit)); + Size aSz = aDocRect.GetSize(); + tools::Rectangle aRect; + if (!IsVertical()) + { + aRect = tools::Rectangle(aPos, aSz); + } + else + { + Point aNewPos(aPos.X() - aSz.Height(), aPos.Y()); + aRect = tools::Rectangle(aNewPos, Size(aSz.Height(), aSz.Width())); + } + return aRect; +} + +Point LOKSpecialPositioning::convertUnit(const Point& rPos, MapUnit ePosUnit) const +{ + if (ePosUnit == meUnit) + return rPos; + + return OutputDevice::LogicToLogic(rPos, MapMode(ePosUnit), MapMode(meUnit)); +} + +tools::Rectangle LOKSpecialPositioning::convertUnit(const tools::Rectangle& rRect, MapUnit eRectUnit) const +{ + if (eRectUnit == meUnit) + return rRect; + + return OutputDevice::LogicToLogic(rRect, MapMode(eRectUnit), MapMode(meUnit)); +} + // class ImpEditView @@ -2473,4 +2580,43 @@ void ImpEditView::RemoveDragAndDropListeners() bActiveDragAndDropListener = false; } +void ImpEditView::InitLOKSpecialPositioning(MapUnit eUnit, + const tools::Rectangle& rOutputArea, + const Point& rVisDocStartPos) +{ + if (!mpLOKSpecialPositioning) + mpLOKSpecialPositioning.reset(new LOKSpecialPositioning(*this, eUnit, rOutputArea, rVisDocStartPos)); + else + mpLOKSpecialPositioning->ReInit(eUnit, rOutputArea, rVisDocStartPos); +} + +void ImpEditView::SetLOKSpecialOutputArea(const tools::Rectangle& rOutputArea) +{ + assert(mpLOKSpecialPositioning); + mpLOKSpecialPositioning->SetOutputArea(rOutputArea); +} + +tools::Rectangle ImpEditView::GetLOKSpecialOutputArea() const +{ + assert(mpLOKSpecialPositioning); + return mpLOKSpecialPositioning->GetOutputArea(); +} + +void ImpEditView::SetLOKSpecialVisArea(const tools::Rectangle& rVisArea) +{ + assert(mpLOKSpecialPositioning); + mpLOKSpecialPositioning->SetVisDocStartPos(rVisArea.TopLeft()); +} + +tools::Rectangle ImpEditView::GetLOKSpecialVisArea() const +{ + assert(mpLOKSpecialPositioning); + return mpLOKSpecialPositioning->GetVisDocArea(); +} + +bool ImpEditView::HasLOKSpecialPositioning() const +{ + return bool(mpLOKSpecialPositioning); +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/editeng/source/editeng/impedit.hxx b/editeng/source/editeng/impedit.hxx index bf6196953ea6..5f67ecd9b22a 100644 --- a/editeng/source/editeng/impedit.hxx +++ b/editeng/source/editeng/impedit.hxx @@ -209,6 +209,45 @@ public: EditView* GetView() { return pView; } }; +class ImpEditView; +/// This is meant just for Calc, where all positions in logical units (twips for LOK) are computed by +/// doing independent pixel-alignment for each cell's size. LOKSpecialPositioning stores +/// both 'output-area' and 'visible-doc-position' in pure logical unit (twips for LOK). +/// This allows the cursor/selection messages to be in regular(print) twips unit like in Writer. +class LOKSpecialPositioning +{ +public: + LOKSpecialPositioning(const ImpEditView& rImpEditView, MapUnit eUnit, const tools::Rectangle& rOutputArea, + const Point& rVisDocStartPos); + + void ReInit(MapUnit eUnit, const tools::Rectangle& rOutputArea, const Point& rVisDocStartPos); + + void SetOutputArea(const tools::Rectangle& rOutputArea); + const tools::Rectangle& GetOutputArea() const; + void SetVisDocStartPos(const Point& rVisDocStartPos); + + bool IsVertical() const; + bool IsTopToBottom() const; + + long GetVisDocLeft() const { return maVisDocStartPos.X(); } + long GetVisDocTop() const { return maVisDocStartPos.Y(); } + long GetVisDocRight() const { return maVisDocStartPos.X() + (!IsVertical() ? maOutArea.GetWidth() : maOutArea.GetHeight()); } + long GetVisDocBottom() const { return maVisDocStartPos.Y() + (!IsVertical() ? maOutArea.GetHeight() : maOutArea.GetWidth()); } + tools::Rectangle GetVisDocArea() const; + + Point GetWindowPos(const Point& rDocPos, MapUnit eDocPosUnit) const; + tools::Rectangle GetWindowPos(const tools::Rectangle& rDocRect, MapUnit eDocRectUnit) const; + +private: + Point convertUnit(const Point& rPos, MapUnit ePosUnit) const; + tools::Rectangle convertUnit(const tools::Rectangle& rRect, MapUnit eRectUnit) const; + + const ImpEditView& mrImpEditView; + tools::Rectangle maOutArea; + Point maVisDocStartPos; + MapUnit meUnit; +}; + class ImpEditView : public vcl::unohelper::DragAndDropClient @@ -262,6 +301,7 @@ private: // in Draw/Impress in an OverlayObject which avoids evtl. expensive full // repaints of the EditView(s) const EditViewCallbacks* mpEditViewCallbacks; + std::unique_ptr<LOKSpecialPositioning> mpLOKSpecialPositioning; bool mbBroadcastLOKViewCursor; const EditViewCallbacks* getEditViewCallbacks() const @@ -414,6 +454,14 @@ public: // If possible invalidate more than OutputArea, for the DrawingEngine text frame void SetInvalidateMore( sal_uInt16 nPixel ) { nInvMore = nPixel; } sal_uInt16 GetInvalidateMore() const { return static_cast<sal_uInt16>(nInvMore); } + + void InitLOKSpecialPositioning(MapUnit eUnit, const tools::Rectangle& rOutputArea, + const Point& rVisDocStartPos); + void SetLOKSpecialOutputArea(const tools::Rectangle& rOutputArea); + tools::Rectangle GetLOKSpecialOutputArea() const; + void SetLOKSpecialVisArea(const tools::Rectangle& rVisArea); + tools::Rectangle GetLOKSpecialVisArea() const; + bool HasLOKSpecialPositioning() const; }; |