/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ #include #include #include #include #include #include #include "svx/svdstr.hrc" #include "svdglob.hxx" #include #include #include #include #include using namespace sdr; void SdrPolyEditView::ImpResetPolyPossibilityFlags() { eMarkedPointsSmooth=SdrPathSmoothKind::DontCare; eMarkedSegmentsKind=SdrPathSegmentKind::DontCare; bSetMarkedPointsSmoothPossible=false; bSetMarkedSegmentsKindPossible=false; } SdrPolyEditView::SdrPolyEditView(SdrModel* pModel1, OutputDevice* pOut): SdrEditView(pModel1,pOut) { ImpResetPolyPossibilityFlags(); } SdrPolyEditView::~SdrPolyEditView() { } void SdrPolyEditView::ImpCheckPolyPossibilities() { ImpResetPolyPossibilityFlags(); const size_t nMarkCount(GetMarkedObjectCount()); if(nMarkCount && !ImpIsFrameHandles()) { bool b1stSmooth(true); bool b1stSegm(true); bool bCurve(false); bool bSmoothFuz(false); bool bSegmFuz(false); basegfx::B2VectorContinuity eSmooth = basegfx::B2VectorContinuity::NONE; for(size_t nMarkNum = 0; nMarkNum < nMarkCount; ++nMarkNum) { SdrMark* pM = GetSdrMarkByIndex(nMarkNum); CheckPolyPossibilitiesHelper( pM, b1stSmooth, b1stSegm, bCurve, bSmoothFuz, bSegmFuz, eSmooth ); } } } void SdrPolyEditView::CheckPolyPossibilitiesHelper( SdrMark* pM, bool& b1stSmooth, bool& b1stSegm, bool& bCurve, bool& bSmoothFuz, bool& bSegmFuz, basegfx::B2VectorContinuity& eSmooth ) { SdrObject* pObj = pM->GetMarkedSdrObj(); SdrPathObj* pPath = dynamic_cast( pObj ); if (!pPath) return; SdrUShortCont& rPts = pM->GetMarkedPoints(); if (rPts.empty()) return; const bool bClosed(pPath->IsClosed()); bSetMarkedPointsSmoothPossible = true; if (bClosed) { bSetMarkedSegmentsKindPossible = true; } for (SdrUShortCont::const_iterator it = rPts.begin(); it != rPts.end(); ++it) { sal_uInt32 nNum(*it); sal_uInt32 nPolyNum, nPntNum; if(PolyPolygonEditor::GetRelativePolyPoint(pPath->GetPathPoly(), nNum, nPolyNum, nPntNum)) { const basegfx::B2DPolygon aLocalPolygon(pPath->GetPathPoly().getB2DPolygon(nPolyNum)); bool bCanSegment(bClosed || nPntNum < aLocalPolygon.count() - 1L); if(!bSetMarkedSegmentsKindPossible && bCanSegment) { bSetMarkedSegmentsKindPossible = true; } if(!bSmoothFuz) { if (b1stSmooth) { b1stSmooth = false; eSmooth = basegfx::tools::getContinuityInPoint(aLocalPolygon, nPntNum); } else { bSmoothFuz = (eSmooth != basegfx::tools::getContinuityInPoint(aLocalPolygon, nPntNum)); } } if(!bSegmFuz) { if(bCanSegment) { bool bCrv(aLocalPolygon.isNextControlPointUsed(nPntNum)); if(b1stSegm) { b1stSegm = false; bCurve = bCrv; } else { bSegmFuz = (bCrv != bCurve); } } } } } if(!b1stSmooth && !bSmoothFuz) { if(basegfx::B2VectorContinuity::NONE == eSmooth) { eMarkedPointsSmooth = SdrPathSmoothKind::Angular; } if(basegfx::B2VectorContinuity::C1 == eSmooth) { eMarkedPointsSmooth = SdrPathSmoothKind::Asymmetric; } if(basegfx::B2VectorContinuity::C2 == eSmooth) { eMarkedPointsSmooth = SdrPathSmoothKind::Symmetric; } } if(!b1stSegm && !bSegmFuz) { eMarkedSegmentsKind = (bCurve) ? SdrPathSegmentKind::Curve : SdrPathSegmentKind::Line; } } void SdrPolyEditView::SetMarkedPointsSmooth(SdrPathSmoothKind eKind) { basegfx::B2VectorContinuity eFlags; if(SdrPathSmoothKind::Angular == eKind) { eFlags = basegfx::B2VectorContinuity::NONE; } else if(SdrPathSmoothKind::Asymmetric == eKind) { eFlags = basegfx::B2VectorContinuity::C1; } else if(SdrPathSmoothKind::Symmetric == eKind) { eFlags = basegfx::B2VectorContinuity::C2; } else { return; } if(HasMarkedPoints()) { SortMarkedObjects(); const bool bUndo = IsUndoEnabled(); if( bUndo ) BegUndo(ImpGetResStr(STR_EditSetPointsSmooth), GetDescriptionOfMarkedPoints()); const size_t nMarkCount(GetMarkedObjectCount()); for(size_t nMarkNum(nMarkCount); nMarkNum > 0;) { --nMarkNum; SdrMark* pM = GetSdrMarkByIndex(nMarkNum); SdrPathObj* pPath = dynamic_cast< SdrPathObj* >( pM->GetMarkedSdrObj() ); if (!pPath) continue; SdrUShortCont& rPts = pM->GetMarkedPoints(); PolyPolygonEditor aEditor(pPath->GetPathPoly()); if (aEditor.SetPointsSmooth(eFlags, rPts)) { if( bUndo ) AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pPath)); pPath->SetPathPoly(aEditor.GetPolyPolygon()); } } if( bUndo ) EndUndo(); } } void SdrPolyEditView::SetMarkedSegmentsKind(SdrPathSegmentKind eKind) { if(HasMarkedPoints()) { SortMarkedObjects(); const bool bUndo = IsUndoEnabled(); if( bUndo ) BegUndo(ImpGetResStr(STR_EditSetSegmentsKind), GetDescriptionOfMarkedPoints()); const size_t nMarkCount(GetMarkedObjectCount()); for(size_t nMarkNum=nMarkCount; nMarkNum > 0;) { --nMarkNum; SdrMark* pM = GetSdrMarkByIndex(nMarkNum); SdrPathObj* pPath = dynamic_cast< SdrPathObj* >( pM->GetMarkedSdrObj() ); if (!pPath) continue; SdrUShortCont& rPts = pM->GetMarkedPoints(); PolyPolygonEditor aEditor( pPath->GetPathPoly()); if (aEditor.SetSegmentsKind(eKind, rPts)) { if( bUndo ) AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pPath)); pPath->SetPathPoly(aEditor.GetPolyPolygon()); } } if( bUndo ) EndUndo(); } } bool SdrPolyEditView::IsSetMarkedPointsSmoothPossible() const { ForcePossibilities(); return bSetMarkedPointsSmoothPossible; } SdrPathSmoothKind SdrPolyEditView::GetMarkedPointsSmooth() const { ForcePossibilities(); return eMarkedPointsSmooth; } bool SdrPolyEditView::IsSetMarkedSegmentsKindPossible() const { ForcePossibilities(); return bSetMarkedSegmentsKindPossible; } SdrPathSegmentKind SdrPolyEditView::GetMarkedSegmentsKind() const { ForcePossibilities(); return eMarkedSegmentsKind; } bool SdrPolyEditView::IsDeleteMarkedPointsPossible() const { return HasMarkedPoints(); } void SdrPolyEditView::DeleteMarkedPoints() { if (HasMarkedPoints()) { BrkAction(); SortMarkedObjects(); const size_t nMarkCount=GetMarkedObjectCount(); const bool bUndo = IsUndoEnabled(); if( bUndo ) { // Description BegUndo(ImpGetResStr(STR_EditDelete),GetDescriptionOfMarkedPoints(),SdrRepeatFunc::Delete); } for (size_t nMarkNum=nMarkCount; nMarkNum>0;) { --nMarkNum; SdrMark* pM=GetSdrMarkByIndex(nMarkNum); SdrPathObj* pPath = dynamic_cast< SdrPathObj* >( pM->GetMarkedSdrObj() ); if (!pPath) continue; SdrUShortCont& rPts = pM->GetMarkedPoints(); PolyPolygonEditor aEditor( pPath->GetPathPoly()); if (aEditor.DeletePoints(rPts)) { if( aEditor.GetPolyPolygon().count() ) { if( bUndo ) AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pPath )); pPath->SetPathPoly( aEditor.GetPolyPolygon() ); } else { if( bUndo ) AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoDeleteObject(*pPath ) ); pM->GetPageView()->GetObjList()->RemoveObject(pPath->GetOrdNum()); if( !bUndo ) { SdrObject* pObj = pPath; SdrObject::Free(pObj); } } } } if( bUndo ) EndUndo(); UnmarkAllPoints(); MarkListHasChanged(); } } void SdrPolyEditView::RipUpAtMarkedPoints() { if(HasMarkedPoints()) { SortMarkedObjects(); const size_t nMarkCount(GetMarkedObjectCount()); const bool bUndo = IsUndoEnabled(); if( bUndo ) BegUndo(ImpGetResStr(STR_EditRipUp), GetDescriptionOfMarkedPoints()); for(size_t nMarkNum = nMarkCount; nMarkNum > 0;) { --nMarkNum; SdrMark* pM = GetSdrMarkByIndex(nMarkNum); SdrPathObj* pObj = dynamic_cast( pM->GetMarkedSdrObj() ); if (!pObj) continue; SdrUShortCont& rPts = pM->GetMarkedPoints(); if( bUndo ) AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pObj)); bool bKorregFlag(false); sal_uInt32 nMax(pObj->GetHdlCount()); for(SdrUShortCont::const_reverse_iterator it = rPts.rbegin(); it != rPts.rend(); ++it) { sal_uInt32 nNewPt0Idx(0L); SdrObject* pNeuObj = pObj->RipPoint(*it, nNewPt0Idx); if(pNeuObj) { pM->GetPageView()->GetObjList()->InsertObject(pNeuObj, pObj->GetOrdNum() + 1); if( bUndo ) AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoNewObject(*pNeuObj)); MarkObj(pNeuObj, pM->GetPageView(), false, true); } if(nNewPt0Idx) { // correction necessary? DBG_ASSERT(!bKorregFlag,"Multiple index corrections at SdrPolyEditView::RipUp()."); if(!bKorregFlag) { bKorregFlag = true; SdrUShortCont aReplaceSet; for(SdrUShortCont::const_iterator it2 = rPts.begin(); it2 != rPts.end(); ++it2) { sal_uInt32 nPntNum(*it2); nPntNum += nNewPt0Idx; if(nPntNum >= nMax) { nPntNum -= nMax; } aReplaceSet.insert( (sal_uInt16)nPntNum ); } rPts.swap(aReplaceSet); it = rPts.rbegin(); } } } } UnmarkAllPoints(); if( bUndo ) EndUndo(); MarkListHasChanged(); } } bool SdrPolyEditView::IsRipUpAtMarkedPointsPossible() const { bool bRetval(false); const size_t nMarkCount(GetMarkedObjectCount()); for(size_t a = 0; a < nMarkCount; ++a) { const SdrMark* pMark = GetSdrMarkByIndex(a); const SdrPathObj* pMarkedPathObject = dynamic_cast< const SdrPathObj* >(pMark->GetMarkedSdrObj()); if (!pMarkedPathObject) continue; const SdrUShortCont& rSelectedPoints = pMark->GetMarkedPoints(); if (rSelectedPoints.empty()) continue; const basegfx::B2DPolyPolygon& rPathPolyPolygon = pMarkedPathObject->GetPathPoly(); if(1 == rPathPolyPolygon.count()) { // #i76617# Do not yet use basegfx::B2DPolygon since curve definitions // are different and methods need to be changed thoroughly with interaction rework const tools::Polygon aPathPolygon(rPathPolyPolygon.getB2DPolygon(0)); const sal_uInt16 nPointCount(aPathPolygon.GetSize()); if(nPointCount >= 3) { bRetval = pMarkedPathObject->IsClosedObj(); // #i76617# for(SdrUShortCont::const_iterator it = rSelectedPoints.begin(); !bRetval && it != rSelectedPoints.end(); ++it) { const sal_uInt16 nMarkedPointNum(*it); bRetval = (nMarkedPointNum > 0 && nMarkedPointNum < nPointCount - 1); } } } } return bRetval; } bool SdrPolyEditView::IsOpenCloseMarkedObjectsPossible() const { bool bRetval(false); const size_t nMarkCount(GetMarkedObjectCount()); for(size_t a = 0; a < nMarkCount; ++a) { const SdrMark* pMark = GetSdrMarkByIndex(a); const SdrPathObj* pMarkedPathObject = dynamic_cast< const SdrPathObj* >(pMark->GetMarkedSdrObj()); if(pMarkedPathObject) { // #i76617# Do not yet use basegfx::B2DPolygon since curve definitions // are different and methods need to be changed thoroughly with interaction rework const tools::PolyPolygon aPathPolyPolygon(pMarkedPathObject->GetPathPoly()); const sal_uInt16 nPolygonCount(aPathPolyPolygon.Count()); for(sal_uInt16 b(0); !bRetval && b < nPolygonCount; b++) { const tools::Polygon& rPathPolygon = aPathPolyPolygon[b]; const sal_uInt16 nPointCount(rPathPolygon.GetSize()); bRetval = (nPointCount >= 3); } } } return bRetval; } SdrObjClosedKind SdrPolyEditView::GetMarkedObjectsClosedState() const { bool bOpen(false); bool bClosed(false); const size_t nMarkCount(GetMarkedObjectCount()); for(size_t a = 0; !(bOpen && bClosed) && a < nMarkCount; ++a) { const SdrMark* pMark = GetSdrMarkByIndex(a); const SdrPathObj* pMarkedPathObject = dynamic_cast< const SdrPathObj* >(pMark->GetMarkedSdrObj()); if(pMarkedPathObject) { if(pMarkedPathObject->IsClosedObj()) { bClosed = true; } else { bOpen = true; } } } if(bOpen && bClosed) { return SdrObjClosedKind::DontCare; } else if(bOpen) { return SdrObjClosedKind::Open; } else { return SdrObjClosedKind::Closed; } } void SdrPolyEditView::ImpTransformMarkedPoints(PPolyTrFunc pTrFunc, const void* p1, const void* p2, const void* p3, const void* p4) { const bool bUndo = IsUndoEnabled(); const size_t nMarkCount=GetMarkedObjectCount(); for (size_t nm=0; nmGetMarkedSdrObj(); SdrPathObj* pPath=dynamic_cast( pObj ); if (!pPath) continue; const SdrUShortCont& rPts = pM->GetMarkedPoints(); if (rPts.empty()) continue; if( bUndo ) AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pObj)); basegfx::B2DPolyPolygon aXPP(pPath->GetPathPoly()); for (SdrUShortCont::const_iterator it = rPts.begin(); it != rPts.end(); ++it) { sal_uInt32 nPt = *it; sal_uInt32 nPolyNum, nPointNum; if(PolyPolygonEditor::GetRelativePolyPoint(aXPP, nPt, nPolyNum, nPointNum)) { //#i83671# used nLocalPointNum (which was the polygon point count) // instead of the point index (nPointNum). This of course leaded // to a wrong point access to the B2DPolygon. basegfx::B2DPolygon aNewXP(aXPP.getB2DPolygon(nPolyNum)); Point aPos, aC1, aC2; bool bC1(false); bool bC2(false); const basegfx::B2DPoint aB2DPos(aNewXP.getB2DPoint(nPointNum)); aPos = Point(FRound(aB2DPos.getX()), FRound(aB2DPos.getY())); if(aNewXP.isPrevControlPointUsed(nPointNum)) { const basegfx::B2DPoint aB2DC1(aNewXP.getPrevControlPoint(nPointNum)); aC1 = Point(FRound(aB2DC1.getX()), FRound(aB2DC1.getY())); bC1 = true; } if(aNewXP.isNextControlPointUsed(nPointNum)) { const basegfx::B2DPoint aB2DC2(aNewXP.getNextControlPoint(nPointNum)); aC2 = Point(FRound(aB2DC2.getX()), FRound(aB2DC2.getY())); bC2 = true; } (*pTrFunc)(aPos,&aC1,&aC2,p1,p2,p3,p4); aNewXP.setB2DPoint(nPointNum, basegfx::B2DPoint(aPos.X(), aPos.Y())); if (bC1) { aNewXP.setPrevControlPoint(nPointNum, basegfx::B2DPoint(aC1.X(), aC1.Y())); } if (bC2) { aNewXP.setNextControlPoint(nPointNum, basegfx::B2DPoint(aC2.X(), aC2.Y())); } aXPP.setB2DPolygon(nPolyNum, aNewXP); } } pPath->SetPathPoly(aXPP); } } static void ImpMove(Point& rPt, Point* pC1, Point* pC2, const void* p1, const void* /*p2*/, const void* /*p3*/, const void* /*p4*/) { MovePoint(rPt,*static_cast(p1)); if (pC1!=nullptr) MovePoint(*pC1,*static_cast(p1)); if (pC2!=nullptr) MovePoint(*pC2,*static_cast(p1)); } void SdrPolyEditView::MoveMarkedPoints(const Size& rSiz) { ForceUndirtyMrkPnt(); OUString aStr(ImpGetResStr(STR_EditMove)); BegUndo(aStr,GetDescriptionOfMarkedPoints(),SdrRepeatFunc::Move); ImpTransformMarkedPoints(ImpMove,&rSiz); EndUndo(); AdjustMarkHdl(); } static void ImpResize(Point& rPt, Point* pC1, Point* pC2, const void* p1, const void* p2, const void* p3, const void* /*p4*/) { ResizePoint(rPt,*static_cast(p1),*static_cast(p2),*static_cast(p3)); if (pC1!=nullptr) ResizePoint(*pC1,*static_cast(p1),*static_cast(p2),*static_cast(p3)); if (pC2!=nullptr) ResizePoint(*pC2,*static_cast(p1),*static_cast(p2),*static_cast(p3)); } void SdrPolyEditView::ResizeMarkedPoints(const Point& rRef, const Fraction& xFact, const Fraction& yFact) { ForceUndirtyMrkPnt(); OUString aStr(ImpGetResStr(STR_EditResize)); BegUndo(aStr,GetDescriptionOfMarkedPoints(),SdrRepeatFunc::Resize); ImpTransformMarkedPoints(ImpResize,&rRef,&xFact,&yFact); EndUndo(); AdjustMarkHdl(); } static void ImpRotate(Point& rPt, Point* pC1, Point* pC2, const void* p1, const void* /*p2*/, const void* p3, const void* p4) { RotatePoint(rPt,*static_cast(p1),*static_cast(p3),*static_cast(p4)); if (pC1!=nullptr) RotatePoint(*pC1,*static_cast(p1),*static_cast(p3),*static_cast(p4)); if (pC2!=nullptr) RotatePoint(*pC2,*static_cast(p1),*static_cast(p3),*static_cast(p4)); } void SdrPolyEditView::RotateMarkedPoints(const Point& rRef, long nAngle) { ForceUndirtyMrkPnt(); OUString aStr(ImpGetResStr(STR_EditResize)); BegUndo(aStr,GetDescriptionOfMarkedPoints(),SdrRepeatFunc::Rotate); double nSin=sin(nAngle*nPi180); double nCos=cos(nAngle*nPi180); ImpTransformMarkedPoints(ImpRotate,&rRef,&nAngle,&nSin,&nCos); EndUndo(); AdjustMarkHdl(); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ LibreOffice 核心代码仓库文档基金会
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Kaganski <mike.kaganski@collabora.com>2019-10-28 18:59:57 +0300
committerMike Kaganski <mike.kaganski@collabora.com>2019-11-09 09:53:38 +0100
commitd628258f279d003ba4e11f1f7e2e69273acd008c (patch)
tree15eb418ed03271538d1155402d41f8d1778937a6 /include/comphelper/SetFlagContextHelper.hxx
parent7e7e97fc0bd2f3d7b794b3fc064c60ef86e9b72b (diff)
tdf#80731: Only check closing parenthesis when in IDE
This reinstates the fix by Pierre Lepage, which was reverted in 351dead74b4c213b13102f81b5ae9bb47ad8ca39, and makes sure it only has effect when the compilation is started from IDE. The idea is that the IDE is used primarily for development, and that's a good opportunity to detect any error in the code. When the code is compiled from outside of the IDE (like running an extension), the error is tolerated to allow users run the legacy code having this error. Hopefully this is enough for tdf#106529. This re-uses comphelper's NoEnableJavaInteractionContext class, which is converted into general-purpose SetFlagContext class to avoid code duplication. Change-Id: Ie290019cb190b8d1d590699ec13bd63eac478d09 Reviewed-on: https://gerrit.libreoffice.org/81616 Tested-by: Jenkins Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>