annot: update annotation object when annotation position changes

+ add tests which check annotation object position changes

Change-Id: Iad5de3d319c14ddb69d6c1994ce5949d57d76de7
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/168744
Tested-by: Jenkins
Reviewed-by: Tomaž Vajngerl <quikee@gmail.com>
This commit is contained in:
Tomaž Vajngerl 2024-06-12 23:16:36 +09:00 committed by Tomaž Vajngerl
parent c0adf5a90a
commit 752436502c
4 changed files with 85 additions and 21 deletions

View file

@ -18,6 +18,7 @@
#include <vcl/scheduler.hxx>
#include <svx/unoapi.hxx>
#include <svx/annotation/Annotation.hxx>
#include <svx/annotation/ObjectAnnotationData.hxx>
#include <svx/svdorect.hxx>
#include <svx/svdview.hxx>
@ -193,6 +194,55 @@ CPPUNIT_TEST_FIXTURE(AnnotationTest, testAnnotationInsertUndoRedo)
CPPUNIT_ASSERT_EQUAL(sal_uInt32(nID + 1), pPage->getAnnotations().at(1)->GetId());
}
CPPUNIT_TEST_FIXTURE(AnnotationTest, testAnnotationUpdate)
{
createSdDrawDoc();
auto pXImpressDocument = dynamic_cast<SdXImpressDocument*>(mxComponent.get());
sd::ViewShell* pViewShell = pXImpressDocument->GetDocShell()->GetViewShell();
SdPage* pPage = pViewShell->GetActualPage();
CPPUNIT_ASSERT_EQUAL(size_t(0), pPage->GetObjCount());
uno::Sequence<beans::PropertyValue> aArgs;
aArgs = comphelper::InitPropertySequence({
{ "Text", uno::Any(u"Comment"_ustr) },
});
dispatchCommand(mxComponent, ".uno:InsertAnnotation", aArgs);
CPPUNIT_ASSERT_EQUAL(size_t(1), pPage->GetObjCount());
SdrObject* pObject = pPage->GetObj(0);
CPPUNIT_ASSERT_EQUAL(SdrObjKind::Annotation, pObject->GetObjIdentifier());
auto& pAnnotationData = pObject->getAnnotationData();
CPPUNIT_ASSERT(pAnnotationData);
sal_Int32 nID = pAnnotationData->mxAnnotation->GetId();
CPPUNIT_ASSERT_EQUAL(tools::Long(0), pObject->GetLogicRect().Left());
CPPUNIT_ASSERT_EQUAL(tools::Long(0), pObject->GetLogicRect().Top());
pObject->Move({ 200, 200 });
CPPUNIT_ASSERT_EQUAL(tools::Long(200), pObject->GetLogicRect().Left());
CPPUNIT_ASSERT_EQUAL(tools::Long(200), pObject->GetLogicRect().Top());
CPPUNIT_ASSERT_DOUBLES_EQUAL(2.0, pAnnotationData->mxAnnotation->getPosition().X, 1E-4);
CPPUNIT_ASSERT_DOUBLES_EQUAL(2.0, pAnnotationData->mxAnnotation->getPosition().Y, 1E-4);
aArgs = comphelper::InitPropertySequence({ { "Id", uno::Any(OUString::number(nID)) },
{ "PositionX", uno::Any(sal_Int32(1440)) },
{ "PositionY", uno::Any(sal_Int32(14400)) } });
dispatchCommand(mxComponent, ".uno:EditAnnotation", aArgs);
CPPUNIT_ASSERT_DOUBLES_EQUAL(25.4, pAnnotationData->mxAnnotation->getPosition().X, 1E-4);
CPPUNIT_ASSERT_DOUBLES_EQUAL(254.0, pAnnotationData->mxAnnotation->getPosition().Y, 1E-4);
CPPUNIT_ASSERT_EQUAL(tools::Long(2540), pObject->GetLogicRect().Left());
CPPUNIT_ASSERT_EQUAL(tools::Long(25400), pObject->GetLogicRect().Top());
}
CPPUNIT_PLUGIN_IMPLEMENT();
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

View file

@ -102,7 +102,8 @@ using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::ui;
using namespace ::com::sun::star::office;
namespace sd {
namespace sd
{
SfxItemPool* GetAnnotationPool()
{
@ -170,6 +171,24 @@ OUString getAnnotationDateTimeString( const Reference< XAnnotation >& xAnnotatio
return sRet;
}
namespace
{
SdrObject* findAnnotationObjectMatching(rtl::Reference<sdr::annotation::Annotation> const& xAnnotation)
{
SdrPage const* pPage = xAnnotation->getPage();
for (size_t i = 0; i < pPage->GetObjCount(); ++i)
{
SdrObject* pObject = pPage->GetObj(i);
if (pObject->isAnnotationObject() && pObject->getAnnotationData()->mxAnnotation == xAnnotation)
return pObject;
}
return nullptr;
}
} // end anonymous ns
AnnotationManagerImpl::AnnotationManagerImpl( ViewShellBase& rViewShellBase )
: mrBase( rViewShellBase )
, mpDoc( rViewShellBase.GetDocument() )
@ -428,11 +447,16 @@ void AnnotationManagerImpl::ExecuteEditAnnotation(SfxRequest const & rReq)
auto pSdAnnotation = static_cast<sd::Annotation*>(xAnnotation.get());
pSdAnnotation->createChangeUndo();
if (nPositionX >= 0 && nPositionY >= 0)
SdrObject* pObject = findAnnotationObjectMatching(xAnnotation);
if (pObject && nPositionX >= 0 && nPositionY >= 0)
{
double fX = convertTwipToMm100(nPositionX) / 100.0;
double fY = convertTwipToMm100(nPositionY) / 100.0;
xAnnotation->setPosition({fX, fY});
double fX = convertTwipToMm100(nPositionX);
double fY = convertTwipToMm100(nPositionY);
double deltaX = fX - (pSdAnnotation->getPosition().X * 100.0);
double deltaY = fY - (pSdAnnotation->getPosition().Y * 100.0);
pObject->Move({::tools::Long(deltaX), ::tools::Long(deltaY)});
}
if (!sText.isEmpty())
@ -939,19 +963,9 @@ IMPL_LINK_NOARG(AnnotationManagerImpl, UpdateTagsHdl, void*, void)
invalidateSlots();
}
SdrObject* AnnotationManagerImpl::findAnnotationObjectMatching(rtl::Reference<sdr::annotation::Annotation> const& xAnnotation)
{
for (size_t i = 0; i < mxCurrentPage->GetObjCount(); ++i)
{
SdrObject* pObject = mxCurrentPage->GetObj(i);
if (pObject->isAnnotationObject() && pObject->getAnnotationData()->mxAnnotation == xAnnotation)
return pObject;
}
return nullptr;
}
namespace
{
void applyAnnotationCommon(SdrObject& rObject, rtl::Reference<sdr::annotation::Annotation> const& xAnnotation)
{
rObject.setAsAnnotationObject(true);

View file

@ -108,8 +108,6 @@ public:
void ShowAnnotations(bool bShow);
SdrObject* findAnnotationObjectMatching(rtl::Reference<sdr::annotation::Annotation> const& xAnnotation);
private:
ViewShellBase& mrBase;
SdDrawDocument* mpDoc;

View file

@ -990,8 +990,8 @@ void SdrObject::RecalcBoundRect()
if ((getSdrModelFromSdrObject().isLocked()) || comphelper::IsFuzzing())
return;
auto const& rRectangle = getOutRectangle();
auto const& rRectangle = getOutRectangle();
// central new method which will calculate the BoundRect using primitive geometry
if (!rRectangle.IsEmpty())
return;
@ -1544,8 +1544,10 @@ void SdrObject::Move(const Size& rSize)
NbcMove(rSize);
if (isAnnotationObject())
{
auto& rRect = GetCurrentBoundRect();
css::geometry::RealPoint2D aNewPosition(rRect.Left() / 100.0, rRect.Top() / 100.0);
css::geometry::RealPoint2D aNewPosition(
GetLogicRect().Left() / 100.0,
GetLogicRect().Top() / 100.0);
getAnnotationData()->mxAnnotation->SetPosition(aNewPosition);
}
SetChanged();